Decompress.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074
  1. //
  2. // Copyright (c) 2008-2017 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #include "../Precompiled.h"
  23. #include "../Resource/Decompress.h"
  24. // DXT decompression based on the Squish library, modified for Atomic
  25. namespace Atomic
  26. {
  27. /* -----------------------------------------------------------------------------
  28. Copyright (c) 2006 Simon Brown [email protected]
  29. Permission is hereby granted, free of charge, to any person obtaining
  30. a copy of this software and associated documentation files (the
  31. "Software"), to deal in the Software without restriction, including
  32. without limitation the rights to use, copy, modify, merge, publish,
  33. distribute, sublicense, and/or sell copies of the Software, and to
  34. permit persons to whom the Software is furnished to do so, subject to
  35. the following conditions:
  36. The above copyright notice and this permission notice shall be included
  37. in all copies or substantial portions of the Software.
  38. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  39. OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  40. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  41. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  42. CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  43. TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  44. SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  45. -------------------------------------------------------------------------- */
  46. static int Unpack565(unsigned char const* packed, unsigned char* colour)
  47. {
  48. // build the packed value
  49. int value = (int)packed[0] | ((int)packed[1] << 8);
  50. // get the components in the stored range
  51. unsigned char red = (unsigned char)((value >> 11) & 0x1f);
  52. unsigned char green = (unsigned char)((value >> 5) & 0x3f);
  53. unsigned char blue = (unsigned char)(value & 0x1f);
  54. // scale up to 8 bits
  55. colour[0] = (red << 3) | (red >> 2);
  56. colour[1] = (green << 2) | (green >> 4);
  57. colour[2] = (blue << 3) | (blue >> 2);
  58. colour[3] = 255;
  59. // return the value
  60. return value;
  61. }
  62. static void DecompressColourDXT(unsigned char* rgba, void const* block, bool isDxt1)
  63. {
  64. // get the block bytes
  65. unsigned char const* bytes = reinterpret_cast< unsigned char const* >( block );
  66. // unpack the endpoints
  67. unsigned char codes[16];
  68. int a = Unpack565(bytes, codes);
  69. int b = Unpack565(bytes + 2, codes + 4);
  70. // generate the midpoints
  71. for (int i = 0; i < 3; ++i)
  72. {
  73. int c = codes[i];
  74. int d = codes[4 + i];
  75. if (isDxt1 && a <= b)
  76. {
  77. codes[8 + i] = (unsigned char)((c + d) / 2);
  78. codes[12 + i] = 0;
  79. }
  80. else
  81. {
  82. codes[8 + i] = (unsigned char)((2 * c + d) / 3);
  83. codes[12 + i] = (unsigned char)((c + 2 * d) / 3);
  84. }
  85. }
  86. // fill in alpha for the intermediate values
  87. codes[8 + 3] = 255;
  88. codes[12 + 3] = (unsigned char)((isDxt1 && a <= b) ? 0 : 255);
  89. // unpack the indices
  90. unsigned char indices[16];
  91. for (int i = 0; i < 4; ++i)
  92. {
  93. unsigned char* ind = indices + 4 * i;
  94. unsigned char packed = bytes[4 + i];
  95. ind[0] = (unsigned char)(packed & 0x3);
  96. ind[1] = (unsigned char)((packed >> 2) & 0x3);
  97. ind[2] = (unsigned char)((packed >> 4) & 0x3);
  98. ind[3] = (unsigned char)((packed >> 6) & 0x3);
  99. }
  100. // store out the colours
  101. for (int i = 0; i < 16; ++i)
  102. {
  103. unsigned char offset = (unsigned char)(4 * indices[i]);
  104. for (int j = 0; j < 4; ++j)
  105. rgba[4 * i + j] = codes[offset + j];
  106. }
  107. }
  108. static void DecompressAlphaDXT3(unsigned char* rgba, void const* block)
  109. {
  110. unsigned char const* bytes = reinterpret_cast< unsigned char const* >( block );
  111. // unpack the alpha values pairwise
  112. for (int i = 0; i < 8; ++i)
  113. {
  114. // quantise down to 4 bits
  115. unsigned char quant = bytes[i];
  116. // unpack the values
  117. unsigned char lo = (unsigned char)(quant & 0x0f);
  118. unsigned char hi = (unsigned char)(quant & 0xf0);
  119. // convert back up to bytes
  120. rgba[8 * i + 3] = lo | (lo << 4);
  121. rgba[8 * i + 7] = hi | (hi >> 4);
  122. }
  123. }
  124. static void DecompressAlphaDXT5(unsigned char* rgba, void const* block)
  125. {
  126. // get the two alpha values
  127. unsigned char const* bytes = reinterpret_cast< unsigned char const* >( block );
  128. int alpha0 = bytes[0];
  129. int alpha1 = bytes[1];
  130. // compare the values to build the codebook
  131. unsigned char codes[8];
  132. codes[0] = (unsigned char)alpha0;
  133. codes[1] = (unsigned char)alpha1;
  134. if (alpha0 <= alpha1)
  135. {
  136. // use 5-alpha codebook
  137. for (int i = 1; i < 5; ++i)
  138. codes[1 + i] = (unsigned char)(((5 - i) * alpha0 + i * alpha1) / 5);
  139. codes[6] = 0;
  140. codes[7] = 255;
  141. }
  142. else
  143. {
  144. // use 7-alpha codebook
  145. for (int i = 1; i < 7; ++i)
  146. codes[1 + i] = (unsigned char)(((7 - i) * alpha0 + i * alpha1) / 7);
  147. }
  148. // decode the indices
  149. unsigned char indices[16];
  150. unsigned char const* src = bytes + 2;
  151. unsigned char* dest = indices;
  152. for (int i = 0; i < 2; ++i)
  153. {
  154. // grab 3 bytes
  155. int value = 0;
  156. for (int j = 0; j < 3; ++j)
  157. {
  158. int byte = *src++;
  159. value |= (byte << 8 * j);
  160. }
  161. // unpack 8 3-bit values from it
  162. for (int j = 0; j < 8; ++j)
  163. {
  164. int index = (value >> 3 * j) & 0x7;
  165. *dest++ = (unsigned char)index;
  166. }
  167. }
  168. // write out the indexed codebook values
  169. for (int i = 0; i < 16; ++i)
  170. rgba[4 * i + 3] = codes[indices[i]];
  171. }
  172. static void DecompressDXT(unsigned char* rgba, const void* block, CompressedFormat format)
  173. {
  174. // get the block locations
  175. void const* colourBlock = block;
  176. void const* alphaBock = block;
  177. if (format == CF_DXT3 || format == CF_DXT5)
  178. colourBlock = reinterpret_cast< unsigned char const* >( block ) + 8;
  179. // decompress colour
  180. DecompressColourDXT(rgba, colourBlock, format == CF_DXT1);
  181. // decompress alpha separately if necessary
  182. if (format == CF_DXT3)
  183. DecompressAlphaDXT3(rgba, alphaBock);
  184. else if (format == CF_DXT5)
  185. DecompressAlphaDXT5(rgba, alphaBock);
  186. }
  187. void DecompressImageDXT(unsigned char* rgba, const void* blocks, int width, int height, int depth, CompressedFormat format)
  188. {
  189. // initialise the block input
  190. unsigned char const* sourceBlock = reinterpret_cast< unsigned char const* >( blocks );
  191. int bytesPerBlock = format == CF_DXT1 ? 8 : 16;
  192. // loop over blocks
  193. for (int z = 0; z < depth; ++z)
  194. {
  195. int sz = width * height * 4 * z;
  196. for (int y = 0; y < height; y += 4)
  197. {
  198. for (int x = 0; x < width; x += 4)
  199. {
  200. // decompress the block
  201. unsigned char targetRgba[4 * 16];
  202. DecompressDXT(targetRgba, sourceBlock, format);
  203. // write the decompressed pixels to the correct image locations
  204. unsigned char const* sourcePixel = targetRgba;
  205. for (int py = 0; py < 4; ++py)
  206. {
  207. for (int px = 0; px < 4; ++px)
  208. {
  209. // get the target location
  210. int sx = x + px;
  211. int sy = y + py;
  212. if (sx < width && sy < height)
  213. {
  214. unsigned char* targetPixel = rgba + sz + 4 * (width * sy + sx);
  215. // copy the rgba value
  216. for (int i = 0; i < 4; ++i)
  217. *targetPixel++ = *sourcePixel++;
  218. }
  219. else
  220. {
  221. // skip this pixel as its outside the image
  222. sourcePixel += 4;
  223. }
  224. }
  225. }
  226. // advance
  227. sourceBlock += bytesPerBlock;
  228. }
  229. }
  230. }
  231. }
  232. // ETC and PVRTC decompression based on the Oolong Engine, modified for Atomic
  233. /*
  234. Oolong Engine for the iPhone / iPod touch
  235. Copyright (c) 2007-2008 Wolfgang Engel http://code.google.com/p/oolongengine/
  236. This software is provided 'as-is', without any express or implied warranty
  237. In no event will the authors be held liable for any damages arising from the
  238. use of this software. Permission is granted to anyone to use this software for
  239. any purpose, including commercial applications, and to alter it and
  240. redistribute it freely, subject to the following restrictions:
  241. 1. The origin of this software must not be misrepresented; you must not claim
  242. that you wrote the original software. If you use this software in a product, an
  243. acknowledgment in the product documentation would be appreciated but is not
  244. required.
  245. 2. Altered source versions must be plainly marked as such, and must not be
  246. misrepresented as being the original software.
  247. 3. This notice may not be removed or altered from any source distribution.
  248. */
  249. #define _CLAMP_(X, Xmin, Xmax) ( (X)<(Xmax) ? ( (X)<(Xmin)?(Xmin):(X) ) : (Xmax) )
  250. unsigned ETC_FLIP = 0x01000000;
  251. unsigned ETC_DIFF = 0x02000000;
  252. const int mod[8][4] = {{2, 8, -2, -8},
  253. {5, 17, -5, -17},
  254. {9, 29, -9, -29},
  255. {13, 42, -13, -42},
  256. {18, 60, -18, -60},
  257. {24, 80, -24, -80},
  258. {33, 106, -33, -106},
  259. {47, 183, -47, -183}};
  260. // lsb: hgfedcba ponmlkji msb: hgfedcba ponmlkji due to endianness
  261. static unsigned long ModifyPixel(int red, int green, int blue, int x, int y, unsigned long modBlock, int modTable)
  262. {
  263. int index = x * 4 + y, pixelMod;
  264. unsigned long mostSig = modBlock << 1;
  265. if (index < 8) //hgfedcba
  266. pixelMod = mod[modTable][((modBlock >> (index + 24)) & 0x1) + ((mostSig >> (index + 8)) & 0x2)];
  267. else // ponmlkj
  268. pixelMod = mod[modTable][((modBlock >> (index + 8)) & 0x1) + ((mostSig >> (index - 8)) & 0x2)];
  269. red = _CLAMP_(red + pixelMod, 0, 255);
  270. green = _CLAMP_(green + pixelMod, 0, 255);
  271. blue = _CLAMP_(blue + pixelMod, 0, 255);
  272. return ((blue << 16) + (green << 8) + red) | 0xff000000;
  273. }
  274. static void DecompressETC(unsigned char* pDestData, const void* pSrcData)
  275. {
  276. unsigned long blockTop, blockBot, * input = (unsigned long*)pSrcData, * output;
  277. unsigned char red1, green1, blue1, red2, green2, blue2;
  278. bool bFlip, bDiff;
  279. int modtable1, modtable2;
  280. blockTop = *(input++);
  281. blockBot = *(input++);
  282. output = (unsigned long*)pDestData;
  283. // check flipbit
  284. bFlip = (blockTop & ETC_FLIP) != 0;
  285. bDiff = (blockTop & ETC_DIFF) != 0;
  286. if (bDiff)
  287. { // differential mode 5 colour bits + 3 difference bits
  288. // get base colour for subblock 1
  289. blue1 = (unsigned char)((blockTop & 0xf80000) >> 16);
  290. green1 = (unsigned char)((blockTop & 0xf800) >> 8);
  291. red1 = (unsigned char)(blockTop & 0xf8);
  292. // get differential colour for subblock 2
  293. signed char blues = (signed char)(blue1 >> 3) + ((signed char)((blockTop & 0x70000) >> 11) >> 5);
  294. signed char greens = (signed char)(green1 >> 3) + ((signed char)((blockTop & 0x700) >> 3) >> 5);
  295. signed char reds = (signed char)(red1 >> 3) + ((signed char)((blockTop & 0x7) << 5) >> 5);
  296. blue2 = (unsigned char)blues;
  297. green2 = (unsigned char)greens;
  298. red2 = (unsigned char)reds;
  299. red1 = red1 + (red1 >> 5); // copy bits to lower sig
  300. green1 = green1 + (green1 >> 5); // copy bits to lower sig
  301. blue1 = blue1 + (blue1 >> 5); // copy bits to lower sig
  302. red2 = (red2 << 3) + (red2 >> 2); // copy bits to lower sig
  303. green2 = (green2 << 3) + (green2 >> 2); // copy bits to lower sig
  304. blue2 = (blue2 << 3) + (blue2 >> 2); // copy bits to lower sig
  305. }
  306. else
  307. { // individual mode 4 + 4 colour bits
  308. // get base colour for subblock 1
  309. blue1 = (unsigned char)((blockTop & 0xf00000) >> 16);
  310. blue1 = blue1 + (blue1 >> 4); // copy bits to lower sig
  311. green1 = (unsigned char)((blockTop & 0xf000) >> 8);
  312. green1 = green1 + (green1 >> 4); // copy bits to lower sig
  313. red1 = (unsigned char)(blockTop & 0xf0);
  314. red1 = red1 + (red1 >> 4); // copy bits to lower sig
  315. // get base colour for subblock 2
  316. blue2 = (unsigned char)((blockTop & 0xf0000) >> 12);
  317. blue2 = blue2 + (blue2 >> 4); // copy bits to lower sig
  318. green2 = (unsigned char)((blockTop & 0xf00) >> 4);
  319. green2 = green2 + (green2 >> 4); // copy bits to lower sig
  320. red2 = (unsigned char)((blockTop & 0xf) << 4);
  321. red2 = red2 + (red2 >> 4); // copy bits to lower sig
  322. }
  323. // get the modtables for each subblock
  324. modtable1 = (int)((blockTop >> 29) & 0x7);
  325. modtable2 = (int)((blockTop >> 26) & 0x7);
  326. if (!bFlip)
  327. { // 2 2x4 blocks side by side
  328. for (int j = 0; j < 4; j++) // vertical
  329. {
  330. for (int k = 0; k < 2; k++) // horizontal
  331. {
  332. *(output + j * 4 + k) = ModifyPixel(red1, green1, blue1, k, j, blockBot, modtable1);
  333. *(output + j * 4 + k + 2) = ModifyPixel(red2, green2, blue2, k + 2, j, blockBot, modtable2);
  334. }
  335. }
  336. }
  337. else
  338. { // 2 4x2 blocks on top of each other
  339. for (int j = 0; j < 2; j++)
  340. {
  341. for (int k = 0; k < 4; k++)
  342. {
  343. *(output + j * 4 + k) = ModifyPixel(red1, green1, blue1, k, j, blockBot, modtable1);
  344. *(output + (j + 2) * 4 + k) = ModifyPixel(red2, green2, blue2, k, j + 2, blockBot, modtable2);
  345. }
  346. }
  347. }
  348. }
  349. void DecompressImageETC(unsigned char* rgba, const void* blocks, int width, int height)
  350. {
  351. // initialise the block input
  352. unsigned char const* sourceBlock = reinterpret_cast< unsigned char const* >( blocks );
  353. int bytesPerBlock = 8;
  354. // loop over blocks
  355. for (int y = 0; y < height; y += 4)
  356. {
  357. for (int x = 0; x < width; x += 4)
  358. {
  359. // decompress the block
  360. unsigned char targetRgba[4 * 16];
  361. DecompressETC(targetRgba, sourceBlock);
  362. // write the decompressed pixels to the correct image locations
  363. unsigned char const* sourcePixel = targetRgba;
  364. for (int py = 0; py < 4; ++py)
  365. {
  366. for (int px = 0; px < 4; ++px)
  367. {
  368. // get the target location
  369. int sx = x + px;
  370. int sy = y + py;
  371. if (sx < width && sy < height)
  372. {
  373. unsigned char* targetPixel = rgba + 4 * (width * sy + sx);
  374. // copy the rgba value
  375. for (int i = 0; i < 4; ++i)
  376. *targetPixel++ = *sourcePixel++;
  377. }
  378. else
  379. {
  380. // skip this pixel as its outside the image
  381. sourcePixel += 4;
  382. }
  383. }
  384. }
  385. // advance
  386. sourceBlock += bytesPerBlock;
  387. }
  388. }
  389. }
  390. #define PT_INDEX (2) /*The Punch-through index*/
  391. #define BLK_Y_SIZE (4) /*always 4 for all 2D block types*/
  392. #define BLK_X_MAX (8) /*Max X dimension for blocks*/
  393. #define BLK_X_2BPP (8) /*dimensions for the two formats*/
  394. #define BLK_X_4BPP (4)
  395. #define _MIN(X, Y) (((X)<(Y))? (X):(Y))
  396. #define _MAX(X, Y) (((X)>(Y))? (X):(Y))
  397. #define WRAP_COORD(Val, Size) ((Val) & ((Size)-1))
  398. #define CLAMP(X, lower, upper) (_MIN(_MAX((X),(lower)), (upper)))
  399. #define LIMIT_COORD(Val, Size, AssumeImageTiles) ((AssumeImageTiles)? WRAP_COORD((Val), (Size)): CLAMP((Val), 0, (Size)-1))
  400. typedef struct
  401. {
  402. // Uses 64 bits pre block
  403. unsigned PackedData[2];
  404. } AMTC_BLOCK_STRUCT;
  405. static void Unpack5554Colour(const AMTC_BLOCK_STRUCT* pBlock, int ABColours[2][4])
  406. {
  407. unsigned RawBits[2];
  408. int i;
  409. // Extract A and B
  410. RawBits[0] = pBlock->PackedData[1] & (0xFFFE); /*15 bits (shifted up by one)*/
  411. RawBits[1] = pBlock->PackedData[1] >> 16; /*16 bits*/
  412. // Step through both colours
  413. for (i = 0; i < 2; i++)
  414. {
  415. // If completely opaque
  416. if (RawBits[i] & (1 << 15))
  417. {
  418. // Extract R and G (both 5 bit)
  419. ABColours[i][0] = (RawBits[i] >> 10) & 0x1F;
  420. ABColours[i][1] = (RawBits[i] >> 5) & 0x1F;
  421. // The precision of Blue depends on A or B. If A then we need to
  422. // replicate the top bit to get 5 bits in total
  423. ABColours[i][2] = RawBits[i] & 0x1F;
  424. if (i == 0)
  425. {
  426. ABColours[0][2] |= ABColours[0][2] >> 4;
  427. }
  428. // Set 4bit alpha fully on...
  429. ABColours[i][3] = 0xF;
  430. }
  431. // Else if colour has variable translucency
  432. else
  433. {
  434. // Extract R and G (both 4 bit).
  435. // (Leave a space on the end for the replication of bits
  436. ABColours[i][0] = (RawBits[i] >> (8 - 1)) & 0x1E;
  437. ABColours[i][1] = (RawBits[i] >> (4 - 1)) & 0x1E;
  438. // Replicate bits to truly expand to 5 bits
  439. ABColours[i][0] |= ABColours[i][0] >> 4;
  440. ABColours[i][1] |= ABColours[i][1] >> 4;
  441. // Grab the 3(+padding) or 4 bits of blue and add an extra padding bit
  442. ABColours[i][2] = (RawBits[i] & 0xF) << 1;
  443. // Expand from 3 to 5 bits if this is from colour A, or 4 to 5 bits if from
  444. // colour B
  445. if (i == 0)
  446. {
  447. ABColours[0][2] |= ABColours[0][2] >> 3;
  448. }
  449. else
  450. {
  451. ABColours[0][2] |= ABColours[0][2] >> 4;
  452. }
  453. // Set the alpha bits to be 3 + a zero on the end
  454. ABColours[i][3] = (RawBits[i] >> 11) & 0xE;
  455. }
  456. }
  457. }
  458. static void UnpackModulations(const AMTC_BLOCK_STRUCT* pBlock, const int Do2bitMode, int ModulationVals[8][16],
  459. int ModulationModes[8][16], int StartX, int StartY)
  460. {
  461. int BlockModMode;
  462. unsigned ModulationBits;
  463. int x, y;
  464. BlockModMode = pBlock->PackedData[1] & 1;
  465. ModulationBits = pBlock->PackedData[0];
  466. // If it's in an interpolated mode
  467. if (Do2bitMode && BlockModMode)
  468. {
  469. // Run through all the pixels in the block. Note we can now treat all the
  470. // "stored" values as if they have 2bits (even when they didn't!)
  471. for (y = 0; y < BLK_Y_SIZE; y++)
  472. {
  473. for (x = 0; x < BLK_X_2BPP; x++)
  474. {
  475. ModulationModes[y + StartY][x + StartX] = BlockModMode;
  476. // If this is a stored value...
  477. if (((x ^ y) & 1) == 0)
  478. {
  479. ModulationVals[y + StartY][x + StartX] = ModulationBits & 3;
  480. ModulationBits >>= 2;
  481. }
  482. }
  483. }
  484. }
  485. // Else if direct encoded 2bit mode - i.e. 1 mode bit per pixel
  486. else if (Do2bitMode)
  487. {
  488. for (y = 0; y < BLK_Y_SIZE; y++)
  489. {
  490. for (x = 0; x < BLK_X_2BPP; x++)
  491. {
  492. ModulationModes[y + StartY][x + StartX] = BlockModMode;
  493. // Double the bits so 0=> 00, and 1=>11
  494. if (ModulationBits & 1)
  495. {
  496. ModulationVals[y + StartY][x + StartX] = 0x3;
  497. }
  498. else
  499. {
  500. ModulationVals[y + StartY][x + StartX] = 0x0;
  501. }
  502. ModulationBits >>= 1;
  503. }
  504. }
  505. }
  506. // Else its the 4bpp mode so each value has 2 bits
  507. else
  508. {
  509. for (y = 0; y < BLK_Y_SIZE; y++)
  510. {
  511. for (x = 0; x < BLK_X_4BPP; x++)
  512. {
  513. ModulationModes[y + StartY][x + StartX] = BlockModMode;
  514. ModulationVals[y + StartY][x + StartX] = ModulationBits & 3;
  515. ModulationBits >>= 2;
  516. }
  517. }
  518. }
  519. }
  520. static void InterpolateColours(const int ColourP[4], const int ColourQ[4], const int ColourR[4], const int ColourS[4],
  521. const int Do2bitMode, const int x, const int y, int Result[4])
  522. {
  523. int u, v, uscale;
  524. int k;
  525. int tmp1, tmp2;
  526. int P[4], Q[4], R[4], S[4];
  527. // Copy the colours
  528. for (k = 0; k < 4; k++)
  529. {
  530. P[k] = ColourP[k];
  531. Q[k] = ColourQ[k];
  532. R[k] = ColourR[k];
  533. S[k] = ColourS[k];
  534. }
  535. // Put the x and y values into the right range
  536. v = (y & 0x3) | ((~y & 0x2) << 1);
  537. if (Do2bitMode)
  538. {
  539. u = (x & 0x7) | ((~x & 0x4) << 1);
  540. }
  541. else
  542. {
  543. u = (x & 0x3) | ((~x & 0x2) << 1);
  544. }
  545. // Get the u and v scale amounts
  546. v = v - BLK_Y_SIZE / 2;
  547. if (Do2bitMode)
  548. {
  549. u = u - BLK_X_2BPP / 2;
  550. uscale = 8;
  551. }
  552. else
  553. {
  554. u = u - BLK_X_4BPP / 2;
  555. uscale = 4;
  556. }
  557. for (k = 0; k < 4; k++)
  558. {
  559. tmp1 = P[k] * uscale + u * (Q[k] - P[k]);
  560. tmp2 = R[k] * uscale + u * (S[k] - R[k]);
  561. tmp1 = tmp1 * 4 + v * (tmp2 - tmp1);
  562. Result[k] = tmp1;
  563. }
  564. // Lop off the appropriate number of bits to get us to 8 bit precision
  565. if (Do2bitMode)
  566. {
  567. // Do RGB
  568. for (k = 0; k < 3; k++)
  569. {
  570. Result[k] >>= 2;
  571. }
  572. Result[3] >>= 1;
  573. }
  574. else
  575. {
  576. // Do RGB (A is ok)
  577. for (k = 0; k < 3; k++)
  578. {
  579. Result[k] >>= 1;
  580. }
  581. }
  582. // Convert from 5554 to 8888
  583. //
  584. // do RGB 5.3 => 8
  585. for (k = 0; k < 3; k++)
  586. {
  587. Result[k] += Result[k] >> 5;
  588. }
  589. Result[3] += Result[3] >> 4;
  590. }
  591. static void GetModulationValue(int x, int y, const int Do2bitMode, const int ModulationVals[8][16],
  592. const int ModulationModes[8][16], int* Mod, int* DoPT)
  593. {
  594. static const int RepVals0[4] = {0, 3, 5, 8};
  595. static const int RepVals1[4] = {0, 4, 4, 8};
  596. int ModVal;
  597. // Map X and Y into the local 2x2 block
  598. y = (y & 0x3) | ((~y & 0x2) << 1);
  599. if (Do2bitMode)
  600. {
  601. x = (x & 0x7) | ((~x & 0x4) << 1);
  602. }
  603. else
  604. {
  605. x = (x & 0x3) | ((~x & 0x2) << 1);
  606. }
  607. // Assume no PT for now
  608. *DoPT = 0;
  609. // Extract the modulation value. If a simple encoding
  610. if (ModulationModes[y][x] == 0)
  611. {
  612. ModVal = RepVals0[ModulationVals[y][x]];
  613. }
  614. else if (Do2bitMode)
  615. {
  616. // If this is a stored value
  617. if (((x ^ y) & 1) == 0)
  618. {
  619. ModVal = RepVals0[ModulationVals[y][x]];
  620. }
  621. // Else average from the neighbours
  622. //
  623. // If H&V interpolation...
  624. else if (ModulationModes[y][x] == 1)
  625. {
  626. ModVal = (RepVals0[ModulationVals[y - 1][x]] +
  627. RepVals0[ModulationVals[y + 1][x]] +
  628. RepVals0[ModulationVals[y][x - 1]] +
  629. RepVals0[ModulationVals[y][x + 1]] + 2) / 4;
  630. }
  631. // Else if H-Only
  632. else if (ModulationModes[y][x] == 2)
  633. {
  634. ModVal = (RepVals0[ModulationVals[y][x - 1]] +
  635. RepVals0[ModulationVals[y][x + 1]] + 1) / 2;
  636. }
  637. // Else it's V-Only
  638. else
  639. {
  640. ModVal = (RepVals0[ModulationVals[y - 1][x]] +
  641. RepVals0[ModulationVals[y + 1][x]] + 1) / 2;
  642. }
  643. }
  644. // Else it's 4BPP and PT encoding
  645. else
  646. {
  647. ModVal = RepVals1[ModulationVals[y][x]];
  648. *DoPT = ModulationVals[y][x] == PT_INDEX;
  649. }
  650. *Mod = ModVal;
  651. }
  652. static unsigned TwiddleUV(unsigned YSize, unsigned XSize, unsigned YPos, unsigned XPos)
  653. {
  654. unsigned Twiddled;
  655. unsigned MinDimension;
  656. unsigned MaxValue;
  657. unsigned SrcBitPos;
  658. unsigned DstBitPos;
  659. int ShiftCount;
  660. if (YSize < XSize)
  661. {
  662. MinDimension = YSize;
  663. MaxValue = XPos;
  664. }
  665. else
  666. {
  667. MinDimension = XSize;
  668. MaxValue = YPos;
  669. }
  670. // Step through all the bits in the "minimum" dimension
  671. SrcBitPos = 1;
  672. DstBitPos = 1;
  673. Twiddled = 0;
  674. ShiftCount = 0;
  675. while (SrcBitPos < MinDimension)
  676. {
  677. if (YPos & SrcBitPos)
  678. {
  679. Twiddled |= DstBitPos;
  680. }
  681. if (XPos & SrcBitPos)
  682. {
  683. Twiddled |= (DstBitPos << 1);
  684. }
  685. SrcBitPos <<= 1;
  686. DstBitPos <<= 2;
  687. ShiftCount += 1;
  688. }
  689. // Prepend any unused bits
  690. MaxValue >>= ShiftCount;
  691. Twiddled |= (MaxValue << (2 * ShiftCount));
  692. return Twiddled;
  693. }
  694. void DecompressImagePVRTC(unsigned char* dest, const void* blocks, int width, int height, CompressedFormat format)
  695. {
  696. AMTC_BLOCK_STRUCT* pCompressedData = (AMTC_BLOCK_STRUCT*)blocks;
  697. int AssumeImageTiles = 1;
  698. int Do2bitMode = format == CF_PVRTC_RGB_2BPP || format == CF_PVRTC_RGBA_2BPP;
  699. int x, y;
  700. int i, j;
  701. int BlkX, BlkY;
  702. int BlkXp1, BlkYp1;
  703. int XBlockSize;
  704. int BlkXDim, BlkYDim;
  705. int StartX, StartY;
  706. int ModulationVals[8][16];
  707. int ModulationModes[8][16];
  708. int Mod, DoPT;
  709. unsigned uPosition;
  710. // Local neighbourhood of blocks
  711. AMTC_BLOCK_STRUCT* pBlocks[2][2];
  712. AMTC_BLOCK_STRUCT* pPrevious[2][2] = {{NULL, NULL},
  713. {NULL, NULL}};
  714. // Low precision colours extracted from the blocks
  715. struct
  716. {
  717. int Reps[2][4];
  718. } Colours5554[2][2];
  719. // Interpolated A and B colours for the pixel
  720. int ASig[4], BSig[4];
  721. int Result[4];
  722. if (Do2bitMode)
  723. {
  724. XBlockSize = BLK_X_2BPP;
  725. }
  726. else
  727. {
  728. XBlockSize = BLK_X_4BPP;
  729. }
  730. // For MBX don't allow the sizes to get too small
  731. BlkXDim = _MAX(2, width / XBlockSize);
  732. BlkYDim = _MAX(2, height / BLK_Y_SIZE);
  733. // Step through the pixels of the image decompressing each one in turn
  734. //
  735. // Note that this is a hideously inefficient way to do this!
  736. for (y = 0; y < height; y++)
  737. {
  738. for (x = 0; x < width; x++)
  739. {
  740. // Map this pixel to the top left neighbourhood of blocks
  741. BlkX = (x - XBlockSize / 2);
  742. BlkY = (y - BLK_Y_SIZE / 2);
  743. BlkX = LIMIT_COORD(BlkX, width, AssumeImageTiles);
  744. BlkY = LIMIT_COORD(BlkY, height, AssumeImageTiles);
  745. BlkX /= XBlockSize;
  746. BlkY /= BLK_Y_SIZE;
  747. // Compute the positions of the other 3 blocks
  748. BlkXp1 = LIMIT_COORD(BlkX + 1, BlkXDim, AssumeImageTiles);
  749. BlkYp1 = LIMIT_COORD(BlkY + 1, BlkYDim, AssumeImageTiles);
  750. // Map to block memory locations
  751. pBlocks[0][0] = pCompressedData + TwiddleUV((unsigned)BlkYDim, (unsigned)BlkXDim, (unsigned)BlkY, (unsigned)BlkX);
  752. pBlocks[0][1] = pCompressedData + TwiddleUV((unsigned)BlkYDim, (unsigned)BlkXDim, (unsigned)BlkY, (unsigned)BlkXp1);
  753. pBlocks[1][0] = pCompressedData + TwiddleUV((unsigned)BlkYDim, (unsigned)BlkXDim, (unsigned)BlkYp1, (unsigned)BlkX);
  754. pBlocks[1][1] = pCompressedData + TwiddleUV((unsigned)BlkYDim, (unsigned)BlkXDim, (unsigned)BlkYp1, (unsigned)BlkXp1);
  755. // Extract the colours and the modulation information IF the previous values
  756. // have changed.
  757. if (memcmp(pPrevious, pBlocks, 4 * sizeof(void*)) != 0)
  758. {
  759. StartY = 0;
  760. for (i = 0; i < 2; i++)
  761. {
  762. StartX = 0;
  763. for (j = 0; j < 2; j++)
  764. {
  765. Unpack5554Colour(pBlocks[i][j], Colours5554[i][j].Reps);
  766. UnpackModulations(pBlocks[i][j],
  767. Do2bitMode,
  768. ModulationVals,
  769. ModulationModes,
  770. StartX, StartY);
  771. StartX += XBlockSize;
  772. }
  773. StartY += BLK_Y_SIZE;
  774. }
  775. // Make a copy of the new pointers
  776. memcpy(pPrevious, pBlocks, 4 * sizeof(void*));
  777. }
  778. // Decompress the pixel. First compute the interpolated A and B signals
  779. InterpolateColours(Colours5554[0][0].Reps[0],
  780. Colours5554[0][1].Reps[0],
  781. Colours5554[1][0].Reps[0],
  782. Colours5554[1][1].Reps[0],
  783. Do2bitMode, x, y,
  784. ASig);
  785. InterpolateColours(Colours5554[0][0].Reps[1],
  786. Colours5554[0][1].Reps[1],
  787. Colours5554[1][0].Reps[1],
  788. Colours5554[1][1].Reps[1],
  789. Do2bitMode, x, y,
  790. BSig);
  791. GetModulationValue(x, y, Do2bitMode, (const int (*)[16])ModulationVals, (const int (*)[16])ModulationModes,
  792. &Mod, &DoPT);
  793. // Compute the modulated colour
  794. for (i = 0; i < 4; i++)
  795. {
  796. Result[i] = ASig[i] * 8 + Mod * (BSig[i] - ASig[i]);
  797. Result[i] >>= 3;
  798. }
  799. if (DoPT)
  800. {
  801. Result[3] = 0;
  802. }
  803. // Store the result in the output image
  804. uPosition = (unsigned)((x + y * width) << 2);
  805. dest[uPosition + 0] = (unsigned char)Result[0];
  806. dest[uPosition + 1] = (unsigned char)Result[1];
  807. dest[uPosition + 2] = (unsigned char)Result[2];
  808. dest[uPosition + 3] = (unsigned char)Result[3];
  809. }
  810. }
  811. }
  812. void FlipBlockVertical(unsigned char* dest, unsigned char* src, CompressedFormat format)
  813. {
  814. switch (format)
  815. {
  816. case CF_RGBA:
  817. for (unsigned i = 0; i < 4; ++i)
  818. dest[i] = src[i];
  819. break;
  820. case CF_DXT1:
  821. for (unsigned i = 0; i < 4; ++i)
  822. {
  823. dest[i] = src[i];
  824. dest[i + 4] = src[7 - i];
  825. }
  826. break;
  827. case CF_DXT3:
  828. for (unsigned i = 0; i < 8; i += 2)
  829. {
  830. dest[i] = src[6 - i];
  831. dest[i + 1] = src[6 - i + 1];
  832. }
  833. for (unsigned i = 0; i < 4; ++i)
  834. {
  835. dest[i + 8] = src[i + 8];
  836. dest[i + 12] = src[15 - i];
  837. }
  838. break;
  839. case CF_DXT5:
  840. dest[0] = src[0];
  841. dest[1] = src[1];
  842. {
  843. unsigned a1 = src[2] | ((unsigned)src[3] << 8) | ((unsigned)src[4] << 16);
  844. unsigned a2 = src[5] | ((unsigned)src[6] << 8) | ((unsigned)src[7] << 16);
  845. unsigned b1 = ((a1 & 0x000fff) << 12) | (a1 & 0xfff000) >> 12;
  846. unsigned b2 = ((a2 & 0x000fff) << 12) | (a2 & 0xfff000) >> 12;
  847. dest[2] = (unsigned char)(b2 & 0xff);
  848. dest[3] = (unsigned char)((b2 >> 8) & 0xff);
  849. dest[4] = (unsigned char)((b2 >> 16) & 0xff);
  850. dest[5] = (unsigned char)(b1 & 0xff);
  851. dest[6] = (unsigned char)((b1 >> 8) & 0xff);
  852. dest[7] = (unsigned char)((b1 >> 16) & 0xff);
  853. }
  854. for (unsigned i = 0; i < 4; ++i)
  855. {
  856. dest[i + 8] = src[i + 8];
  857. dest[i + 12] = src[15 - i];
  858. }
  859. break;
  860. default:
  861. /// ETC1 & PVRTC not yet implemented
  862. break;
  863. }
  864. }
  865. static unsigned char FlipDXT1Horizontal(unsigned char src)
  866. {
  867. return (unsigned char)(((src & 0x3) << 6) | ((src & 0xc) << 2) | ((src & 0x30) >> 2) | ((src & 0xc0) >> 6));
  868. }
  869. static unsigned FlipDXT5AlphaHorizontal(unsigned src)
  870. {
  871. // Works on 2 lines at a time
  872. return ((src & 0x7) << 9) | ((src & 0x38) << 3) | ((src & 0x1c0) >> 3) | ((src & 0xe00) >> 9) |
  873. ((src & 0x7000) << 9) | ((src & 0x38000) << 3) | ((src & 0x1c0000) >> 3) | ((src & 0xe00000) >> 9);
  874. }
  875. void FlipBlockHorizontal(unsigned char* dest, unsigned char* src, CompressedFormat format)
  876. {
  877. switch (format)
  878. {
  879. case CF_DXT1:
  880. for (unsigned i = 0; i < 4; ++i)
  881. {
  882. dest[i] = src[i];
  883. dest[i + 4] = FlipDXT1Horizontal(src[i + 4]);
  884. }
  885. break;
  886. case CF_DXT3:
  887. for (unsigned i = 0; i < 8; i += 2)
  888. {
  889. dest[i] = (unsigned char)(((src[i + 1] & 0xf0) >> 4) | ((src[i + 1] & 0xf) << 4));
  890. dest[i + 1] = (unsigned char)(((src[i] & 0xf0) >> 4) | ((src[i] & 0xf) << 4));
  891. }
  892. for (unsigned i = 0; i < 4; ++i)
  893. {
  894. dest[i + 8] = src[i + 8];
  895. dest[i + 12] = FlipDXT1Horizontal(src[i + 12]);
  896. }
  897. break;
  898. case CF_DXT5:
  899. dest[0] = src[0];
  900. dest[1] = src[1];
  901. {
  902. unsigned a1 = src[2] | ((unsigned)src[3] << 8) | ((unsigned)src[4] << 16);
  903. unsigned a2 = src[5] | ((unsigned)src[6] << 8) | ((unsigned)src[7] << 16);
  904. unsigned b1 = FlipDXT5AlphaHorizontal(a1);
  905. unsigned b2 = FlipDXT5AlphaHorizontal(a2);
  906. dest[2] = (unsigned char)(b1 & 0xff);
  907. dest[3] = (unsigned char)((b1 >> 8) & 0xff);
  908. dest[4] = (unsigned char)((b1 >> 16) & 0xff);
  909. dest[5] = (unsigned char)(b2 & 0xff);
  910. dest[6] = (unsigned char)((b2 >> 8) & 0xff);
  911. dest[7] = (unsigned char)((b2 >> 16) & 0xff);
  912. }
  913. for (unsigned i = 0; i < 4; ++i)
  914. {
  915. dest[i + 8] = src[i + 8];
  916. dest[i + 12] = FlipDXT1Horizontal(src[i + 12]);
  917. }
  918. break;
  919. default:
  920. /// ETC1 & PVRTC not yet implemented
  921. break;
  922. }
  923. }
  924. }