GraphicData.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  1. /**
  2. * 魔力宝贝图档解析脚本 - CGTool
  3. *
  4. * @Author HonorLee (dev@honorlee.me)
  5. * @Version 1.0 (2023-11-20)
  6. * @License GPL-3.0
  7. *
  8. * GraphicData.cs 图档解析类
  9. */
  10. using System;
  11. using System.Collections;
  12. using System.Collections.Generic;
  13. using System.IO;
  14. using System.Linq;
  15. using Unity.Burst;
  16. using Unity.Collections;
  17. using Unity.Jobs;
  18. using UnityEngine;
  19. namespace CrossgateToolkit
  20. {
  21. //图档数据详情
  22. public class GraphicDetail
  23. {
  24. //索引
  25. public uint Index;
  26. //编号
  27. public uint Serial;
  28. //图档宽度
  29. public uint Width;
  30. //图档高度
  31. public uint Height;
  32. //图档偏移X
  33. public int OffsetX;
  34. //图档偏移Y
  35. public int OffsetY;
  36. //Palet调色板Index
  37. public int Palet;
  38. //图档Sprite
  39. public Sprite Sprite;
  40. //图档主色调,用于小地图绘制
  41. public Color32 PrimaryColor;
  42. }
  43. // 图档数据
  44. public static class GraphicData
  45. {
  46. // // 图档缓存 Serial -> Palet -> GraphicDetail
  47. // public static Dictionary<uint,Dictionary<int,GraphicDetail>> _cache = new Dictionary<uint, Dictionary<int, GraphicDetail>>();
  48. //
  49. // // 图档索引缓存 Index -> Palet -> GraphicDetail
  50. // public static Dictionary<uint,Dictionary<int,GraphicDetail>> _indexCache = new Dictionary<uint, Dictionary<int, GraphicDetail>>();
  51. public static Dictionary<GraphicInfoData,Dictionary<int,GraphicDetail>> _cache = new Dictionary<GraphicInfoData, Dictionary<int, GraphicDetail>>();
  52. // 获取图档
  53. public static GraphicDetail GetGraphicDetail(GraphicInfoData graphicInfoData, int palet = 0,int subPalet = 0)
  54. {
  55. GraphicDetail graphicDetail = null;
  56. if (_cache.ContainsKey(graphicInfoData))
  57. {
  58. if (_cache[graphicInfoData].ContainsKey(palet))
  59. {
  60. graphicDetail = _cache[graphicInfoData][palet];
  61. }
  62. else
  63. {
  64. graphicDetail = _loadGraphicDetail(graphicInfoData, palet, subPalet);
  65. _cache[graphicInfoData].Add(palet, graphicDetail);
  66. }
  67. }
  68. else
  69. {
  70. graphicDetail = _loadGraphicDetail(graphicInfoData, palet, subPalet);
  71. _cache.Add(graphicInfoData, new Dictionary<int, GraphicDetail>());
  72. _cache[graphicInfoData].Add(palet, graphicDetail);
  73. }
  74. return graphicDetail;
  75. }
  76. // 解析图档
  77. private static GraphicDetail _loadGraphicDetail(GraphicInfoData graphicInfoData,int palet = 0,int subPalet = 0)
  78. {
  79. GraphicDetail graphicDetail = new GraphicDetail();
  80. //获取图像数据
  81. List<Color32> pixels = UnpackGraphic(graphicInfoData, palet, subPalet);
  82. if(pixels==null) return null;
  83. graphicDetail.PrimaryColor = pixels.Last();
  84. pixels.RemoveAt(pixels.Count - 1);
  85. //直接通过Texture2D做偏移,并转为Sprite的偏移量
  86. Vector2 offset = new Vector2(0f, 1f);
  87. offset.x += -(graphicInfoData.OffsetX * 1f) / graphicInfoData.Width;
  88. offset.y -= (-graphicInfoData.OffsetY * 1f) / graphicInfoData.Height;
  89. //创建Texture2D对象
  90. Texture2D texture2D;
  91. Sprite sprite;
  92. // RGBA4444 减少内存占用
  93. texture2D = new Texture2D((int) graphicInfoData.Width, (int) graphicInfoData.Height,
  94. TextureFormat.RGBA4444, false, false);
  95. // 固定点过滤
  96. texture2D.filterMode = FilterMode.Point;
  97. texture2D.SetPixels32(pixels.ToArray());
  98. // texture2D.LoadRawTextureData(rawTextureData);
  99. texture2D.Apply();
  100. sprite = Sprite.Create(texture2D, new Rect(0, 0, texture2D.width, texture2D.height), offset, 1,1,SpriteMeshType.FullRect);
  101. //写入数据
  102. graphicDetail.Index = graphicInfoData.Index;
  103. graphicDetail.Serial = graphicInfoData.Serial;
  104. graphicDetail.Width = graphicInfoData.Width;
  105. graphicDetail.Height = graphicInfoData.Height;
  106. graphicDetail.OffsetX = graphicInfoData.OffsetX;
  107. graphicDetail.OffsetY = graphicInfoData.OffsetY;
  108. graphicDetail.Palet = palet;
  109. graphicDetail.Sprite = sprite;
  110. return graphicDetail;
  111. }
  112. #region 地图合批
  113. // 合批数据
  114. private class BatchData
  115. {
  116. public int BatchOffsetX;
  117. public int BatchOffsetY;
  118. public GraphicDetail GraphicDetail;
  119. }
  120. // 图档合批
  121. private class TextureData
  122. {
  123. public int MaxHeight;
  124. public int MaxWidth;
  125. public List<BatchData> BatchDatas = new List<BatchData>();
  126. public List<GraphicInfoData> GraphicInfoDatas = new List<GraphicInfoData>();
  127. }
  128. //预备地图缓存
  129. [Obsolete("该方法已废弃,请使用BakeGraphics方法")]
  130. public static Dictionary<uint, GraphicDetail> BakeAsGround(List<GraphicInfoData> groundInfos,int palet=0)
  131. {
  132. Dictionary<uint, GraphicDetail> graphicDataDic = new Dictionary<uint, GraphicDetail>();
  133. // _mapSpriteMap[MapID].Add(PaletIndex, graphicDataDic);
  134. List<BatchData> batchDatas = new List<BatchData>();
  135. Texture2D texture2D = null;
  136. for (var i = 0; i < groundInfos.Count; i++)
  137. {
  138. //每1344个图像合并一次,即不超过2048*2048尺寸
  139. if (i % 1344 == 0)
  140. {
  141. //合并
  142. if (i != 0) Combine(texture2D, batchDatas);
  143. //清空
  144. batchDatas.Clear();
  145. int height = 2048;
  146. if (i + 1344 > groundInfos.Count-1)
  147. {
  148. height = Mathf.CeilToInt((groundInfos.Count - i) / 32f) * 48;
  149. }
  150. texture2D = new Texture2D(2048, height, TextureFormat.RGBA4444, false, true);
  151. texture2D.filterMode = FilterMode.Point;
  152. //默认填充全透明
  153. Color32[] colors = Enumerable.Repeat(new Color32(0, 0, 0, 0), 2048 * height).ToArray();
  154. texture2D.SetPixels32(colors);
  155. }
  156. GraphicInfoData graphicInfoData = groundInfos[i];
  157. GraphicDetail graphicData = GetGraphicDetail(graphicInfoData, palet);
  158. int x = i % 32 * 64;
  159. int y = i / 32 * 48;
  160. if(graphicData!=null && graphicData.Sprite!=null)
  161. {
  162. Color32[] pixels = graphicData.Sprite.texture.GetPixels32();
  163. texture2D.SetPixels32(x, y, (int) graphicInfoData.Width, (int) graphicInfoData.Height,
  164. pixels.ToArray());
  165. }
  166. BatchData batchData = new BatchData();
  167. batchData.BatchOffsetX = x;
  168. batchData.BatchOffsetY = y;
  169. batchData.GraphicDetail = graphicData;
  170. batchDatas.Add(batchData);
  171. }
  172. //最后一次合并
  173. if (batchDatas.Count > 0)
  174. {
  175. Combine(texture2D, batchDatas);
  176. batchDatas.Clear();
  177. }
  178. void Combine(Texture2D texture2D,List<BatchData> batchDatas)
  179. {
  180. texture2D.Apply();
  181. for (var i = 0; i < batchDatas.Count; i++)
  182. {
  183. GraphicDetail graphicDataPiece = batchDatas[i].GraphicDetail;
  184. //直接通过Texture2D做偏移,并转为Sprite的偏移量
  185. Vector2 offset = new Vector2(0f, 1f);
  186. offset.x += -(graphicDataPiece.OffsetX * 1f) / graphicDataPiece.Width;
  187. offset.y -= (-graphicDataPiece.OffsetY * 1f) / graphicDataPiece.Height;
  188. int X = i % 32 * 64;
  189. int Y = i / 32 * 48;
  190. Sprite sprite = Sprite.Create(texture2D,
  191. new Rect(X, Y, (int)graphicDataPiece.Width, (int)graphicDataPiece.Height), offset, 1, 1,
  192. SpriteMeshType.FullRect);
  193. GraphicDetail graphicData = new GraphicDetail()
  194. {
  195. Index = graphicDataPiece.Index,
  196. Serial = graphicDataPiece.Serial,
  197. Width = graphicDataPiece.Width,
  198. Height = graphicDataPiece.Height,
  199. OffsetX = graphicDataPiece.OffsetX,
  200. OffsetY = graphicDataPiece.OffsetY,
  201. Palet = graphicDataPiece.Palet,
  202. Sprite = sprite,
  203. PrimaryColor = graphicDataPiece.PrimaryColor
  204. };
  205. graphicDataDic.Add(graphicData.Serial, graphicData);
  206. }
  207. }
  208. return graphicDataDic;
  209. }
  210. /// <summary>
  211. /// 合批图档
  212. /// 通过指定图档序列,对图档进行合批处理,并返回合批后的图档数据
  213. /// </summary>
  214. /// <param name="graphicInfoDatas">图档索引数据序列</param>
  215. /// <param name="palet">调色板序号</param>
  216. /// <param name="maxTextureSize">单个Texture最大尺寸,地面数据建议2048,物件数据建议4096</param>
  217. /// <param name="padding">图档间隔,可以有效避免图档渲染时出现多余的黑边或像素黏连</param>
  218. /// <returns>合批后的图档数据,Key(unit)为图档数据编号,Value为图档数据</returns>
  219. public static Dictionary<uint, GraphicDetail> BakeGraphics(List<GraphicInfoData> graphicInfoDatas,int palet = 0, int maxTextureSize = 2048,int padding = 0)
  220. {
  221. // 单个Texture最大尺寸
  222. int maxWidth = maxTextureSize;
  223. int maxHeight = maxTextureSize;
  224. List<TextureData> textureDatas = new List<TextureData>();
  225. Dictionary<uint, GraphicDetail> graphicDataDic = new Dictionary<uint, GraphicDetail>();
  226. // 根据objectInfos的内,GraphicInfoData的Width,Height进行排序,优先排序Width,使图档从小到大排列
  227. graphicInfoDatas = graphicInfoDatas.OrderBy(obj => obj.Width).ThenBy(obj => obj.Height).ToList();
  228. int offsetX = 0; // X轴偏移量
  229. int offsetY = 0; // Y轴偏移量
  230. int maxRowHeight = 0; // 当前行最大高度
  231. TextureData textureData = new TextureData();
  232. for (var i = 0; i < graphicInfoDatas.Count; i++)
  233. {
  234. GraphicInfoData graphicInfoData = graphicInfoDatas[i];
  235. // 如果宽度超过4096,则换行
  236. if((graphicInfoData.Width + offsetX) > maxWidth)
  237. {
  238. offsetX = 0;
  239. offsetY = offsetY + maxRowHeight + padding;
  240. maxRowHeight = 0;
  241. }
  242. // 如果高度超过2048,则生成新的Texture2D
  243. if ((graphicInfoData.Height + offsetY) > maxHeight)
  244. {
  245. offsetX = 0;
  246. offsetY = 0;
  247. maxRowHeight = 0;
  248. textureDatas.Add(textureData);
  249. textureData = new TextureData();
  250. }
  251. BatchData batchData = new BatchData();
  252. batchData.BatchOffsetX = offsetX;
  253. batchData.BatchOffsetY = offsetY;
  254. batchData.GraphicDetail = GetGraphicDetail(graphicInfoData, palet);
  255. // graphicDatas.Add(graphicData);
  256. textureData.BatchDatas.Add(batchData);
  257. textureData.GraphicInfoDatas.Add(graphicInfoData);
  258. maxRowHeight = Mathf.Max(maxRowHeight, (int) graphicInfoData.Height);
  259. textureData.MaxHeight = Mathf.Max(textureData.MaxHeight, offsetY + maxRowHeight);
  260. textureData.MaxWidth = Mathf.Max(textureData.MaxWidth, offsetX + (int) graphicInfoData.Width);
  261. offsetX += (int) graphicInfoData.Width + padding;
  262. }
  263. //最后一次合并
  264. if (textureData.BatchDatas.Count > 0) textureDatas.Add(textureData);
  265. //合并Texture2D
  266. for (var i = 0; i < textureDatas.Count; i++)
  267. {
  268. TextureData textureDataPiece = textureDatas[i];
  269. // Debug.Log($"合并第{i}个Texture2D,最大高度:{textureDataPiece.MaxHeight},图像数量:{textureDataPiece.GraphicDatas.Count}");
  270. Color32[] colors = Enumerable.Repeat(new Color32(0,0,0,0), textureDataPiece.MaxWidth * textureDataPiece.MaxHeight).ToArray();
  271. Texture2D texture2DPiece = new Texture2D(textureDataPiece.MaxWidth, textureDataPiece.MaxHeight, TextureFormat.RGBA4444, false, false);
  272. texture2DPiece.filterMode = FilterMode.Point;
  273. texture2DPiece.SetPixels32(colors);
  274. for (var n = 0; n < textureDataPiece.BatchDatas.Count; n++)
  275. {
  276. BatchData batchData = textureDataPiece.BatchDatas[n];
  277. GraphicInfoData graphicInfoData = textureDataPiece.GraphicInfoDatas[n];
  278. if (batchData.GraphicDetail!=null)
  279. {
  280. Color32[] pixels = batchData.GraphicDetail.Sprite.texture.GetPixels32();
  281. texture2DPiece.SetPixels32(batchData.BatchOffsetX, batchData.BatchOffsetY, (int) graphicInfoData.Width, (int) graphicInfoData.Height,
  282. pixels.ToArray());
  283. }
  284. }
  285. texture2DPiece.Apply();
  286. Combine(texture2DPiece, textureDataPiece.BatchDatas);
  287. }
  288. void Combine(Texture2D texture2D,List<BatchData> batchDatas)
  289. {
  290. for (var i = 0; i < batchDatas.Count; i++)
  291. {
  292. BatchData batchData = batchDatas[i];
  293. //直接通过Texture2D做偏移,并转为Sprite的偏移量
  294. Vector2 offset = new Vector2(0f, 1f);
  295. offset.x += -(batchData.GraphicDetail.OffsetX * 1f) / batchData.GraphicDetail.Width;
  296. offset.y -= (-batchData.GraphicDetail.OffsetY * 1f) / batchData.GraphicDetail.Height;
  297. Sprite sprite = Sprite.Create(texture2D, new Rect(batchData.BatchOffsetX, batchData.BatchOffsetY, (int)batchData.GraphicDetail.Width, (int)batchData.GraphicDetail.Height),offset, 1, 1, SpriteMeshType.FullRect);
  298. GraphicDetail graphicDetail = new GraphicDetail()
  299. {
  300. Index = batchData.GraphicDetail.Index,
  301. Serial = batchData.GraphicDetail.Serial,
  302. Width = batchData.GraphicDetail.Width,
  303. Height = batchData.GraphicDetail.Height,
  304. OffsetX = batchData.GraphicDetail.OffsetX,
  305. OffsetY = batchData.GraphicDetail.OffsetY,
  306. Palet = batchData.GraphicDetail.Palet,
  307. Sprite = sprite,
  308. PrimaryColor = batchData.GraphicDetail.PrimaryColor
  309. };
  310. // graphicDataPiece.Sprite = sprite;
  311. graphicDataDic.Add(graphicDetail.Serial, graphicDetail);
  312. }
  313. }
  314. return graphicDataDic;
  315. }
  316. #endregion
  317. //解压图像数据
  318. private static List<Color32> UnpackGraphic(GraphicInfoData graphicInfoData,int PaletIndex=0,int SubPaletIndex=0){
  319. List<Color32> pixels = new List<Color32>();
  320. //获取调色板
  321. List<Color32> palet;
  322. //调整流指针
  323. BinaryReader fileReader = graphicInfoData.GraphicReader;
  324. fileReader.BaseStream.Position = graphicInfoData.Addr;
  325. //读入目标字节集
  326. byte[] Content = fileReader.ReadBytes((int) graphicInfoData.Length);
  327. //读取缓存字节集
  328. BinaryReader contentReader = new BinaryReader(new MemoryStream(Content));
  329. //16字节头信息
  330. byte[] RD = contentReader.ReadBytes(2);
  331. int Version = contentReader.ReadByte();
  332. int Unknow = contentReader.ReadByte();
  333. uint Width = contentReader.ReadUInt32();
  334. uint Height = contentReader.ReadUInt32();
  335. uint DataLen = contentReader.ReadUInt32();
  336. uint innerPaletLen = 0;
  337. // 低版本头部长度为16,高版本为20
  338. int headLen = 16;
  339. if (Version > 1)
  340. {
  341. headLen = 20;
  342. innerPaletLen = contentReader.ReadUInt32();
  343. }
  344. //数据长度
  345. int contentLen = (int)(DataLen - headLen);
  346. int pixelLen = (int) (graphicInfoData.Width * graphicInfoData.Height);
  347. int[] paletIndex;
  348. if (graphicInfoData.UnpackedPaletIndex == null)
  349. {
  350. //解压数据
  351. byte[] contentBytes = contentReader.ReadBytes((int) contentLen);
  352. NativeArray<byte> bytes = new NativeArray<byte>((int) contentBytes.Length, Allocator.TempJob);
  353. bytes.CopyFrom(contentBytes);
  354. long decompressLen = pixelLen + innerPaletLen;
  355. NativeArray<int> colorIndexs =
  356. new NativeArray<int>((int)decompressLen, Allocator.TempJob);
  357. DecompressJob decompressJob = new DecompressJob()
  358. {
  359. bytes = bytes,
  360. compressd = Version != 0,
  361. colorIndexs = colorIndexs
  362. };
  363. // decompressJob.Execute();
  364. decompressJob.Schedule().Complete();
  365. bytes.Dispose();
  366. paletIndex = colorIndexs.ToArray();
  367. graphicInfoData.UnpackedPaletIndex = paletIndex;
  368. colorIndexs.Dispose();
  369. }
  370. else
  371. {
  372. paletIndex = graphicInfoData.UnpackedPaletIndex;
  373. }
  374. if (SubPaletIndex > 0)
  375. {
  376. palet = Palet.GetPalet(SubPaletIndex);
  377. if (palet == null)
  378. {
  379. GraphicInfoData subPaletInfoData = GraphicInfo.GetGraphicInfoData((uint)SubPaletIndex);
  380. Graphic.GetGraphicDetail((uint)SubPaletIndex);
  381. palet = subPaletInfoData.InnerPalet;
  382. Palet.AddPalet(SubPaletIndex, palet);
  383. }
  384. }
  385. else
  386. {
  387. if (innerPaletLen > 0)
  388. {
  389. int[] innerPaletIndex = paletIndex.Skip(pixelLen).Take((int) innerPaletLen).ToArray();
  390. palet = AnalysisInnerPalet(innerPaletIndex).ToList();
  391. paletIndex = paletIndex.Take(pixelLen).ToArray();
  392. graphicInfoData.InnerPalet = palet;
  393. }
  394. else
  395. {
  396. palet = Palet.GetPalet(PaletIndex);
  397. }
  398. }
  399. //释放连接
  400. contentReader.Dispose();
  401. contentReader.Close();
  402. //主色调色值
  403. int r = 0;
  404. int g = 0;
  405. int b = 0;
  406. foreach (int index in paletIndex)
  407. {
  408. Color32 color32;
  409. if (index == 999 || (index > palet.Count - 1))
  410. {
  411. color32 = Color.clear;
  412. }
  413. else
  414. {
  415. color32 = palet[index];
  416. }
  417. pixels.Add(color32);
  418. r += color32.r;
  419. g += color32.g;
  420. b += color32.b;
  421. }
  422. //主色调计算及提亮
  423. r = r / pixels.Count * 3;
  424. g = g / pixels.Count * 3;
  425. b = b / pixels.Count * 3;
  426. if (r > 255) r = 255;
  427. if (g > 255) g = 255;
  428. if (b > 255) b = 255;
  429. int len = (int) (graphicInfoData.Width * graphicInfoData.Height);
  430. if (pixels.Count != len)
  431. {
  432. if (pixels.Count > len)
  433. {
  434. pixels = pixels.GetRange(0, len);
  435. }
  436. else
  437. {
  438. Color32[] temc = new Color32[len - pixels.Count];
  439. ArrayList.Repeat(Color.clear, len - pixels.Count).CopyTo(temc);
  440. pixels.AddRange(temc);
  441. }
  442. }
  443. //主色调加入最后
  444. pixels.Add(new Color32((byte) r, (byte) g, (byte) b, 255));
  445. return pixels;
  446. }
  447. //分析高版本内部调色板
  448. private static Color32[] AnalysisInnerPalet(int[] bytes)
  449. {
  450. int colorLen = bytes.Length / 3;
  451. Color32[] palet = new Color32[colorLen + 1];
  452. for (var i = 0; i < colorLen; i++)
  453. {
  454. int[] paletBytes = bytes.Skip(i * 3).Take(3).ToArray();
  455. Color32 color32 = new Color32();
  456. color32.r = (byte)paletBytes[2];
  457. color32.g = (byte)paletBytes[1];
  458. color32.b = (byte)paletBytes[0];
  459. color32.a = 0xFF;
  460. palet[i] = color32;
  461. }
  462. palet[colorLen] = Color.clear;
  463. return palet;
  464. }
  465. #region 测试解压
  466. private static int[] TestDecompress(byte[] bytes)
  467. {
  468. List<int> colorIndexs = new List<int>();
  469. int _index = -1;
  470. int next()
  471. {
  472. _index++;
  473. if (_index > bytes.Length - 1) return -1;
  474. return bytes[_index];
  475. }
  476. while (_index < (bytes.Length - 1))
  477. {
  478. int head = next();
  479. if (head == -1) break;
  480. int repeat = 0;
  481. if (head < 0x10)
  482. {
  483. repeat = head;
  484. for (var i = 0; i < repeat; i++)
  485. {
  486. colorIndexs.Add(next());
  487. }
  488. }
  489. else if (head < 0x20)
  490. {
  491. repeat = head % 0x10 * 0x100 + next();
  492. for (var i = 0; i < repeat; i++)
  493. {
  494. colorIndexs.Add(next());
  495. }
  496. }
  497. else if (head < 0x80)
  498. {
  499. repeat = head % 0x20 * 0x10000 + next() * 0x100 + next();
  500. for (var i = 0; i < repeat; i++)
  501. {
  502. colorIndexs.Add(next());
  503. }
  504. }
  505. else if (head < 0x90)
  506. {
  507. repeat = head % 0x80;
  508. int index = next();
  509. for (var i = 0; i < repeat; i++)
  510. {
  511. colorIndexs.Add(index);
  512. }
  513. }
  514. else if (head < 0xa0)
  515. {
  516. int index = next();
  517. repeat = head % 0x90 * 0x100 + next();
  518. for (var i = 0; i < repeat; i++)
  519. {
  520. colorIndexs.Add(index);
  521. }
  522. }
  523. else if (head < 0xc0)
  524. {
  525. int index = next();
  526. repeat = head % 0xa0 * 0x10000 + next() * 0x100 + next();
  527. for (var i = 0; i < repeat; i++)
  528. {
  529. colorIndexs.Add(index);
  530. }
  531. }
  532. else if (head < 0xd0)
  533. {
  534. repeat = head % 0xc0;
  535. for (var i = 0; i < repeat; i++)
  536. {
  537. colorIndexs.Add(999);
  538. }
  539. }
  540. else if (head < 0xe0)
  541. {
  542. repeat = head % 0xd0 * 0x100 + next();
  543. for (var i = 0; i < repeat; i++)
  544. {
  545. colorIndexs.Add(999);
  546. }
  547. }
  548. else if (head < 0xff)
  549. {
  550. repeat = head % 0xe0 * 0x10000 + next() * 0x100 + next();
  551. for (var i = 0; i < repeat; i++)
  552. {
  553. colorIndexs.Add(999);
  554. }
  555. }
  556. }
  557. return colorIndexs.ToArray();
  558. }
  559. #endregion 测试解压
  560. }
  561. //解压缩交给IJob处理
  562. [BurstCompile]
  563. public struct DecompressJob : IJob
  564. {
  565. [ReadOnly]
  566. public NativeArray<byte> bytes;
  567. public bool compressd;
  568. public NativeArray<int> colorIndexs;
  569. private int _maxIndex;
  570. private int _index;
  571. private int _colorIndex;
  572. private int NextByte()
  573. {
  574. _index++;
  575. if (_index > _maxIndex) return -1;
  576. return bytes[_index];
  577. }
  578. private void AddColorIndex(int index)
  579. {
  580. if (_colorIndex > colorIndexs.Length - 1) return;
  581. colorIndexs[_colorIndex] = index;
  582. _colorIndex++;
  583. }
  584. [BurstCompile]
  585. public void Execute()
  586. {
  587. _maxIndex = bytes.Length - 1;
  588. _index = -1;
  589. _colorIndex = 0;
  590. if (!compressd)
  591. {
  592. while (_index<=_maxIndex)
  593. {
  594. int pindex = NextByte();
  595. if(pindex==-1) break;
  596. AddColorIndex(pindex);
  597. }
  598. }
  599. else
  600. //压缩型数据解压
  601. {
  602. // int count = 0;
  603. while (_index<=_maxIndex)
  604. {
  605. // count++;
  606. int head = NextByte();
  607. if(head==-1) break;
  608. int repeat = 0;
  609. if (head < 0x10)
  610. {
  611. repeat = head;
  612. for (var i = 0; i < repeat; i++)
  613. {
  614. AddColorIndex(NextByte());
  615. }
  616. }
  617. else if (head < 0x20)
  618. {
  619. repeat = head % 0x10 * 0x100 + NextByte();
  620. for (var i = 0; i < repeat; i++)
  621. {
  622. AddColorIndex(NextByte());
  623. }
  624. }
  625. else if (head < 0x80)
  626. {
  627. repeat = head % 0x20 * 0x10000 + NextByte() * 0x100 + NextByte();
  628. for (var i = 0; i < repeat; i++)
  629. {
  630. AddColorIndex(NextByte());
  631. }
  632. }
  633. else if (head < 0x90)
  634. {
  635. repeat = head % 0x80;
  636. int index = NextByte();
  637. for (var i = 0; i < repeat; i++)
  638. {
  639. AddColorIndex(index);
  640. }
  641. }
  642. else if (head < 0xa0)
  643. {
  644. int index = NextByte();
  645. repeat = head % 0x90 * 0x100 + NextByte();
  646. for (var i = 0; i < repeat; i++)
  647. {
  648. AddColorIndex(index);
  649. }
  650. }
  651. else if (head < 0xc0)
  652. {
  653. int index = NextByte();
  654. repeat = head % 0xa0 * 0x10000 + NextByte() * 0x100 + NextByte();
  655. for (var i = 0; i < repeat; i++)
  656. {
  657. AddColorIndex(index);
  658. }
  659. }
  660. else if (head < 0xd0)
  661. {
  662. repeat = head % 0xc0;
  663. for (var i = 0; i < repeat; i++)
  664. {
  665. AddColorIndex(999);
  666. }
  667. }
  668. else if (head < 0xe0)
  669. {
  670. repeat = head % 0xd0 * 0x100 + NextByte();
  671. for (var i = 0; i < repeat; i++)
  672. {
  673. AddColorIndex(999);
  674. }
  675. }
  676. else
  677. {
  678. repeat = head % 0xe0 * 0x10000 + NextByte() * 0x100 + NextByte();
  679. for (var i = 0; i < repeat; i++)
  680. {
  681. AddColorIndex(999);
  682. }
  683. }
  684. }
  685. }
  686. }
  687. }
  688. }