etc2.c 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285
  1. /*
  2. ESENTHEL CHANGED: char -> signed char
  3. Copyright (c) 2015 Harm Hanemaaijer <[email protected]>
  4. Permission to use, copy, modify, and/or distribute this software for any
  5. purpose with or without fee is hereby granted, provided that the above
  6. copyright notice and this permission notice appear in all copies.
  7. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  10. ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  12. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  13. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  14. #include <stdlib.h>
  15. #include <stdint.h>
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include "texgenpack.h"
  19. #include "decode.h"
  20. #include "packing.h"*/
  21. #define alpha_byte_offset 3
  22. #ifndef TGP_SHARED_FUNCTIONS // needed for Android compilation
  23. #define TGP_SHARED_FUNCTIONS
  24. static unsigned int pack_rgba (int r, int g, int b, int a) {return (unsigned int)r | ((unsigned int)g << 8) | ((unsigned int)b << 16) | ((unsigned int)a << 24);}
  25. #endif
  26. static unsigned int pack_rgb_alpha_0xff(int r, int g, int b ) {return pack_rgba(r, g, b, 0xFF);}
  27. typedef U64 uint64_t;
  28. // Define an array to speed up clamping of values to the ranges 0 to 255.
  29. static unsigned char clamp_table[255 + 256 + 256] = {
  30. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  31. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  32. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  33. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  34. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  35. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  36. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  37. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  38. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  39. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  40. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  41. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  42. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  43. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  44. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  45. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  46. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
  47. 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
  48. 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
  49. 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
  50. 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
  51. 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
  52. 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
  53. 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
  54. 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
  55. 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160,
  56. 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176,
  57. 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192,
  58. 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208,
  59. 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224,
  60. 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240,
  61. 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 255,
  62. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  63. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  64. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  65. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  66. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  67. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  68. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  69. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  70. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  71. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  72. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  73. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  74. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  75. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  76. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  77. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 };
  78. static int complement3bitshifted_table[8] = {
  79. 0, 8, 16, 24, -32, -24, -16, -8
  80. };
  81. static int modifier_table[8][4] = {
  82. { 2, 8, -2, -8 },
  83. { 5, 17, -5, -17 },
  84. { 9, 29, -9, -29 },
  85. { 13, 42, -13, -42 },
  86. { 18, 60, -18, -60 },
  87. { 24, 80, -24, -80 },
  88. { 33, 106, -33, -106 },
  89. { 47, 183, -47, -183 }
  90. };
  91. static unsigned char clamp(int x) {
  92. return clamp_table[x + 255];
  93. }
  94. static int clamp_slow(int x) {
  95. if (x < 0)
  96. return 0;
  97. if (x > 255)
  98. return 255;
  99. return x;
  100. }
  101. static int clamp2047(int x) {
  102. if (x < 0)
  103. return 0;
  104. if (x > 2047)
  105. return 2047;
  106. return x;
  107. }
  108. static int clamp1023_signed(int x) {
  109. if (x < - 1023)
  110. return - 1023;
  111. if (x > 1023)
  112. return 1023;
  113. return x;
  114. }
  115. // This function calculates the 3-bit complement value in the range -4 to 3 of a three bit
  116. // representation. The result is arithmetically shifted 3 places to the left before returning.
  117. static int complement3bitshifted(int x) {
  118. return complement3bitshifted_table[x];
  119. }
  120. static int complement3bitshifted_slow(int x) {
  121. if (x & 4)
  122. return ((x & 3) - 4) << 3; // Note: shift is arithmetic.
  123. return x << 3;
  124. }
  125. static int complement3bit(int x) {
  126. if (x & 4)
  127. return ((x & 3) - 4);
  128. return x;
  129. }
  130. // Define some macros to speed up ETC1 decoding.
  131. #define do_flipbit0_pixel0to7(val) \
  132. { \
  133. int i = val; \
  134. int pixel_index = ((pixel_index_word & (1 << i)) >> i) \
  135. | ((pixel_index_word & (0x10000 << i)) >> (16 + i - 1)); \
  136. int r, g, b; \
  137. int modifier = modifier_table[table_codeword1][pixel_index]; \
  138. r = clamp(base_color_subblock1_R + modifier); \
  139. g = clamp(base_color_subblock1_G + modifier); \
  140. b = clamp(base_color_subblock1_B + modifier); \
  141. image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] = pack_rgb_alpha_0xff(r, g, b); \
  142. }
  143. #define do_flipbit0_pixel8to15(val) \
  144. { \
  145. int i = val; \
  146. int pixel_index = ((pixel_index_word & (1 << i)) >> i) \
  147. | ((pixel_index_word & (0x10000 << i)) >> (16 + i - 1)); \
  148. int r, g, b; \
  149. int modifier = modifier_table[table_codeword2][pixel_index]; \
  150. r = clamp(base_color_subblock2_R + modifier); \
  151. g = clamp(base_color_subblock2_G + modifier); \
  152. b = clamp(base_color_subblock2_B + modifier); \
  153. image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] = pack_rgb_alpha_0xff(r, g, b); \
  154. }
  155. #define do_flipbit1_pixelbit1notset(val) \
  156. { \
  157. int i = val; \
  158. int pixel_index = ((pixel_index_word & (1 << i)) >> i) \
  159. | ((pixel_index_word & (0x10000 << i)) >> (16 + i - 1)); \
  160. int r, g, b; \
  161. int modifier = modifier_table[table_codeword1][pixel_index]; \
  162. r = clamp(base_color_subblock1_R + modifier); \
  163. g = clamp(base_color_subblock1_G + modifier); \
  164. b = clamp(base_color_subblock1_B + modifier); \
  165. image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] = pack_rgb_alpha_0xff(r, g, b); \
  166. }
  167. #define do_flipbit1_pixelbit1set(val) \
  168. { \
  169. int i = val; \
  170. int pixel_index = ((pixel_index_word & (1 << i)) >> i) \
  171. | ((pixel_index_word & (0x10000 << i)) >> (16 + i - 1)); \
  172. int r, g, b; \
  173. int modifier = modifier_table[table_codeword2][pixel_index]; \
  174. r = clamp(base_color_subblock2_R + modifier); \
  175. g = clamp(base_color_subblock2_G + modifier); \
  176. b = clamp(base_color_subblock2_B + modifier); \
  177. image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] = pack_rgb_alpha_0xff(r, g, b); \
  178. }
  179. // Draw a 4x4 pixel block using the ETC1 texture compression data in bitstring. Return 1 is it is a valid block, 0 if
  180. // not (overflow or underflow occurred in differential mode).
  181. int draw_block4x4_etc1(const unsigned char *bitstring, unsigned int *image_buffer) {
  182. int differential_mode = bitstring[3] & 2;
  183. int flipbit = bitstring[3] & 1;
  184. int base_color_subblock1_R;
  185. int base_color_subblock1_G;
  186. int base_color_subblock1_B;
  187. int base_color_subblock2_R;
  188. int base_color_subblock2_G;
  189. int base_color_subblock2_B;
  190. if (differential_mode) {
  191. base_color_subblock1_R = (bitstring[0] & 0xF8);
  192. base_color_subblock1_R |= ((base_color_subblock1_R & 224) >> 5);
  193. base_color_subblock1_G = (bitstring[1] & 0xF8);
  194. base_color_subblock1_G |= (base_color_subblock1_G & 224) >> 5;
  195. base_color_subblock1_B = (bitstring[2] & 0xF8);
  196. base_color_subblock1_B |= (base_color_subblock1_B & 224) >> 5;
  197. base_color_subblock2_R = (bitstring[0] & 0xF8); // 5 highest order bits.
  198. base_color_subblock2_R += complement3bitshifted(bitstring[0] & 7); // Add difference.
  199. if (base_color_subblock2_R & 0xFF07) // Check for overflow.
  200. return 0;
  201. base_color_subblock2_R |= (base_color_subblock2_R & 224) >> 5; // Replicate.
  202. base_color_subblock2_G = (bitstring[1] & 0xF8);
  203. base_color_subblock2_G += complement3bitshifted(bitstring[1] & 7);
  204. if (base_color_subblock2_G & 0xFF07)
  205. return 0;
  206. base_color_subblock2_G |= (base_color_subblock2_G & 224) >> 5;
  207. base_color_subblock2_B = (bitstring[2] & 0xF8);
  208. base_color_subblock2_B += complement3bitshifted(bitstring[2] & 7);
  209. if (base_color_subblock2_B & 0xFF07)
  210. return 0;
  211. base_color_subblock2_B |= (base_color_subblock2_B & 224) >> 5;
  212. }
  213. else {
  214. base_color_subblock1_R = (bitstring[0] & 0xF0);
  215. base_color_subblock1_R |= base_color_subblock1_R >> 4;
  216. base_color_subblock1_G = (bitstring[1] & 0xF0);
  217. base_color_subblock1_G |= base_color_subblock1_G >> 4;
  218. base_color_subblock1_B = (bitstring[2] & 0xF0);
  219. base_color_subblock1_B |= base_color_subblock1_B >> 4;
  220. base_color_subblock2_R = (bitstring[0] & 0x0F);
  221. base_color_subblock2_R |= base_color_subblock2_R << 4;
  222. base_color_subblock2_G = (bitstring[1] & 0x0F);
  223. base_color_subblock2_G |= base_color_subblock2_G << 4;
  224. base_color_subblock2_B = (bitstring[2] & 0x0F);
  225. base_color_subblock2_B |= base_color_subblock2_B << 4;
  226. }
  227. int table_codeword1 = (bitstring[3] & 224) >> 5;
  228. int table_codeword2 = (bitstring[3] & 28) >> 2;
  229. unsigned int pixel_index_word = ((unsigned int)bitstring[4] << 24) | ((unsigned int)bitstring[5] << 16) |
  230. ((unsigned int)bitstring[6] << 8) | bitstring[7];
  231. #if 1
  232. if (flipbit == 0) {
  233. do_flipbit0_pixel0to7(0);
  234. do_flipbit0_pixel0to7(1);
  235. do_flipbit0_pixel0to7(2);
  236. do_flipbit0_pixel0to7(3);
  237. do_flipbit0_pixel0to7(4);
  238. do_flipbit0_pixel0to7(5);
  239. do_flipbit0_pixel0to7(6);
  240. do_flipbit0_pixel0to7(7);
  241. do_flipbit0_pixel8to15(8);
  242. do_flipbit0_pixel8to15(9);
  243. do_flipbit0_pixel8to15(10);
  244. do_flipbit0_pixel8to15(11);
  245. do_flipbit0_pixel8to15(12);
  246. do_flipbit0_pixel8to15(13);
  247. do_flipbit0_pixel8to15(14);
  248. do_flipbit0_pixel8to15(15);
  249. return 1;
  250. }
  251. else {
  252. do_flipbit1_pixelbit1notset(0);
  253. do_flipbit1_pixelbit1notset(1);
  254. do_flipbit1_pixelbit1set(2);
  255. do_flipbit1_pixelbit1set(3);
  256. do_flipbit1_pixelbit1notset(4);
  257. do_flipbit1_pixelbit1notset(5);
  258. do_flipbit1_pixelbit1set(6);
  259. do_flipbit1_pixelbit1set(7);
  260. do_flipbit1_pixelbit1notset(8);
  261. do_flipbit1_pixelbit1notset(9);
  262. do_flipbit1_pixelbit1set(10);
  263. do_flipbit1_pixelbit1set(11);
  264. do_flipbit1_pixelbit1notset(12);
  265. do_flipbit1_pixelbit1notset(13);
  266. do_flipbit1_pixelbit1set(14);
  267. do_flipbit1_pixelbit1set(15);
  268. return 1;
  269. }
  270. #else
  271. // Slow unoptimized version.
  272. for (int i = 0; i < 16; i++) {
  273. int pixel_index = ((pixel_index_word & (1 << i)) >> i) // Least significant bit.
  274. | ((pixel_index_word & (0x10000 << i)) >> (16 + i - 1)); // Most significant bit.
  275. int r, g, b;
  276. if (flipbit == 0) {
  277. // Two 2x4 blocks side-by-side.
  278. if (i < 8) {
  279. // Subblock 1.
  280. int modifier = modifier_table[table_codeword1][pixel_index];
  281. r = clamp(base_color_subblock1_R + modifier);
  282. g = clamp(base_color_subblock1_G + modifier);
  283. b = clamp(base_color_subblock1_B + modifier);
  284. }
  285. else {
  286. // Subblock 2.
  287. int modifier = modifier_table[table_codeword2][pixel_index];
  288. r = clamp(base_color_subblock2_R + modifier);
  289. g = clamp(base_color_subblock2_G + modifier);
  290. b = clamp(base_color_subblock2_B + modifier);
  291. }
  292. }
  293. else {
  294. // Two 4x2 blocks on top of each other.
  295. if ((i & 2) == 0) {
  296. // Subblock 1.
  297. int modifier = modifier_table[table_codeword1][pixel_index];
  298. r = clamp(base_color_subblock1_R + modifier);
  299. g = clamp(base_color_subblock1_G + modifier);
  300. b = clamp(base_color_subblock1_B + modifier);
  301. }
  302. else {
  303. // Subblock 2.
  304. int modifier = modifier_table[table_codeword2][pixel_index];
  305. r = clamp(base_color_subblock2_R + modifier);
  306. g = clamp(base_color_subblock2_G + modifier);
  307. b = clamp(base_color_subblock2_B + modifier);
  308. }
  309. }
  310. image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] = pack_rgb_alpha_0xff(r, g, b);
  311. }
  312. return 1;
  313. #endif
  314. }
  315. static int etc2_distance_table[8] = { 3, 6, 11, 16, 23, 32, 41, 64 };
  316. static void draw_block4x4_rgb8_etc2_T_or_H_mode(const unsigned char *bitstring, unsigned int *image_buffer, int mode) {
  317. int base_color1_R, base_color1_G, base_color1_B;
  318. int base_color2_R, base_color2_G, base_color2_B;
  319. int paint_color_R[4], paint_color_G[4], paint_color_B[4];
  320. int distance;
  321. if (mode == 0) {
  322. // T mode.
  323. base_color1_R = ((bitstring[0] & 0x18) >> 1) | (bitstring[0] & 0x3);
  324. base_color1_R |= base_color1_R << 4;
  325. base_color1_G = bitstring[1] & 0xF0;
  326. base_color1_G |= base_color1_G >> 4;
  327. base_color1_B = bitstring[1] & 0x0F;
  328. base_color1_B |= base_color1_B << 4;
  329. base_color2_R = bitstring[2] & 0xF0;
  330. base_color2_R |= base_color2_R >> 4;
  331. base_color2_G = bitstring[2] & 0x0F;
  332. base_color2_G |= base_color2_G << 4;
  333. base_color2_B = bitstring[3] & 0xF0;
  334. base_color2_B |= base_color2_B >> 4;
  335. // index = (da << 1) | db
  336. distance = etc2_distance_table[((bitstring[3] & 0x0C) >> 1) | (bitstring[3] & 0x1)];
  337. paint_color_R[0] = base_color1_R;
  338. paint_color_G[0] = base_color1_G;
  339. paint_color_B[0] = base_color1_B;
  340. paint_color_R[2] = base_color2_R;
  341. paint_color_G[2] = base_color2_G;
  342. paint_color_B[2] = base_color2_B;
  343. paint_color_R[1] = clamp(base_color2_R + distance);
  344. paint_color_G[1] = clamp(base_color2_G + distance);
  345. paint_color_B[1] = clamp(base_color2_B + distance);
  346. paint_color_R[3] = clamp(base_color2_R - distance);
  347. paint_color_G[3] = clamp(base_color2_G - distance);
  348. paint_color_B[3] = clamp(base_color2_B - distance);
  349. }
  350. else {
  351. // H mode.
  352. base_color1_R = (bitstring[0] & 0x78) >> 3;
  353. base_color1_R |= base_color1_R << 4;
  354. base_color1_G = ((bitstring[0] & 0x07) << 1) | ((bitstring[1] & 0x10) >> 4);
  355. base_color1_G |= base_color1_G << 4;
  356. base_color1_B = (bitstring[1] & 0x08) | ((bitstring[1] & 0x03) << 1) | ((bitstring[2] & 0x80) >> 7);
  357. base_color1_B |= base_color1_B << 4;
  358. base_color2_R = (bitstring[2] & 0x78) >> 3;
  359. base_color2_R |= base_color2_R << 4;
  360. base_color2_G = ((bitstring[2] & 0x07) << 1) | ((bitstring[3] & 0x80) >> 7);
  361. base_color2_G |= base_color2_G << 4;
  362. base_color2_B = (bitstring[3] & 0x78) >> 3;
  363. base_color2_B |= base_color2_B << 4;
  364. // da is most significant bit, db is middle bit, least significant bit is
  365. // (base_color1 value >= base_color2 value).
  366. int base_color1_value = (base_color1_R << 16) + (base_color1_G << 8) + base_color1_B;
  367. int base_color2_value = (base_color2_R << 16) + (base_color2_G << 8) + base_color2_B;
  368. int bit;
  369. if (base_color1_value >= base_color2_value)
  370. bit = 1;
  371. else
  372. bit = 0;
  373. distance = etc2_distance_table[(bitstring[3] & 0x04) | ((bitstring[3] & 0x01) << 1) | bit];
  374. paint_color_R[0] = clamp(base_color1_R + distance);
  375. paint_color_G[0] = clamp(base_color1_G + distance);
  376. paint_color_B[0] = clamp(base_color1_B + distance);
  377. paint_color_R[1] = clamp(base_color1_R - distance);
  378. paint_color_G[1] = clamp(base_color1_G - distance);
  379. paint_color_B[1] = clamp(base_color1_B - distance);
  380. paint_color_R[2] = clamp(base_color2_R + distance);
  381. paint_color_G[2] = clamp(base_color2_G + distance);
  382. paint_color_B[2] = clamp(base_color2_B + distance);
  383. paint_color_R[3] = clamp(base_color2_R - distance);
  384. paint_color_G[3] = clamp(base_color2_G - distance);
  385. paint_color_B[3] = clamp(base_color2_B - distance);
  386. }
  387. unsigned int pixel_index_word = ((unsigned int)bitstring[4] << 24) | ((unsigned int)bitstring[5] << 16) |
  388. ((unsigned int)bitstring[6] << 8) | bitstring[7];
  389. for (int i = 0; i < 16; i++) {
  390. int pixel_index = ((pixel_index_word & (1 << i)) >> i) // Least significant bit.
  391. | ((pixel_index_word & (0x10000 << i)) >> (16 + i - 1)); // Most significant bit.
  392. int r = paint_color_R[pixel_index];
  393. int g = paint_color_G[pixel_index];
  394. int b = paint_color_B[pixel_index];
  395. image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] = pack_rgb_alpha_0xff(r, g, b);
  396. }
  397. }
  398. static void draw_block4x4_rgb8_etc2_planar_mode(const unsigned char *bitstring, unsigned int *image_buffer) {
  399. // Each color O, H and V is in 6-7-6 format.
  400. int RO = (bitstring[0] & 0x7E) >> 1;
  401. int GO = ((bitstring[0] & 0x1) << 6) | ((bitstring[1] & 0x7E) >> 1);
  402. int BO = ((bitstring[1] & 0x1) << 5) | (bitstring[2] & 0x18) | ((bitstring[2] & 0x03) << 1) |
  403. ((bitstring[3] & 0x80) >> 7);
  404. int RH = ((bitstring[3] & 0x7C) >> 1) | (bitstring[3] & 0x1);
  405. int GH = (bitstring[4] & 0xFE) >> 1;
  406. int BH = ((bitstring[4] & 0x1) << 5) | ((bitstring[5] & 0xF8) >> 3);
  407. int RV = ((bitstring[5] & 0x7) << 3) | ((bitstring[6] & 0xE0) >> 5);
  408. int GV = ((bitstring[6] & 0x1F) << 2) | ((bitstring[7] & 0xC0) >> 6);
  409. int BV = bitstring[7] & 0x3F;
  410. RO = (RO << 2) | ((RO & 0x30) >> 4); // Replicate bits.
  411. GO = (GO << 1) | ((GO & 0x40) >> 6);
  412. BO = (BO << 2) | ((BO & 0x30) >> 4);
  413. RH = (RH << 2) | ((RH & 0x30) >> 4);
  414. GH = (GH << 1) | ((GH & 0x40) >> 6);
  415. BH = (BH << 2) | ((BH & 0x30) >> 4);
  416. RV = (RV << 2) | ((RV & 0x30) >> 4);
  417. GV = (GV << 1) | ((GV & 0x40) >> 6);
  418. BV = (BV << 2) | ((BV & 0x30) >> 4);
  419. for (int y = 0; y < 4; y++)
  420. for (int x = 0; x < 4; x++) {
  421. int r = clamp((x * (RH - RO) + y * (RV - RO) + 4 * RO + 2) >> 2);
  422. int g = clamp((x * (GH - GO) + y * (GV - GO) + 4 * GO + 2) >> 2);
  423. int b = clamp((x * (BH - BO) + y * (BV - BO) + 4 * BO + 2) >> 2);
  424. image_buffer[y * 4 + x] = pack_rgb_alpha_0xff(r, g, b);
  425. }
  426. }
  427. // Draw a 4x4 pixel block using the ETC2 texture compression data in bitstring (format COMPRESSED_RGB8_ETC2).
  428. int draw_block4x4_etc2_rgb8(const unsigned char *bitstring, unsigned int *image_buffer) {
  429. // Figure out the mode.
  430. if ((bitstring[3] & 2) == 0) {
  431. // Individual mode.
  432. return draw_block4x4_etc1(bitstring, image_buffer);
  433. }
  434. #if 0
  435. int R = (bitstring[0] & 0xF8) >> 3;;
  436. R += complement3bit(bitstring[0] & 7);
  437. int G = (bitstring[1] & 0xF8) >> 3;
  438. G += complement3bit(bitstring[1] & 7);
  439. int B = (bitstring[2] & 0xF8) >> 3;
  440. B += complement3bit(bitstring[2] & 7);
  441. if (R < 0 || R > 31) {
  442. // T mode.
  443. draw_block4x4_rgb8_etc2_T_or_H_mode(bitstring, image_buffer, 0);
  444. return 1;
  445. }
  446. else
  447. if (G < 0 || G > 31) {
  448. // H mode.
  449. draw_block4x4_rgb8_etc2_T_or_H_mode(bitstring, image_buffer, 1);
  450. return 1;
  451. }
  452. else
  453. if (B < 0 || B > 31) {
  454. // Planar mode.
  455. draw_block4x4_rgb8_etc2_planar_mode(bitstring, image_buffer);
  456. return 1;
  457. }
  458. else {
  459. // Differential mode.
  460. return draw_block4x4_etc1(bitstring, image_buffer);
  461. }
  462. #else
  463. int R = (bitstring[0] & 0xF8);
  464. R += complement3bitshifted(bitstring[0] & 7);
  465. int G = (bitstring[1] & 0xF8);
  466. G += complement3bitshifted(bitstring[1] & 7);
  467. int B = (bitstring[2] & 0xF8);
  468. B += complement3bitshifted(bitstring[2] & 7);
  469. if (R & 0xFF07) {
  470. // T mode.
  471. draw_block4x4_rgb8_etc2_T_or_H_mode(bitstring, image_buffer, 0);
  472. return 1;
  473. }
  474. else
  475. if (G & 0xFF07) {
  476. // H mode.
  477. draw_block4x4_rgb8_etc2_T_or_H_mode(bitstring, image_buffer, 1);
  478. return 1;
  479. }
  480. else
  481. if (B & 0xFF07) {
  482. // Planar mode.
  483. draw_block4x4_rgb8_etc2_planar_mode(bitstring, image_buffer);
  484. return 1;
  485. }
  486. else {
  487. // Differential mode.
  488. return draw_block4x4_etc1(bitstring, image_buffer);
  489. }
  490. #endif
  491. }
  492. /*
  493. // Determine the mode of the ETC1 RGB8 block.
  494. // Return one of the following values:
  495. // 0 Individual mode
  496. // 1 Differential mode
  497. int block4x4_etc1_get_mode(const unsigned char *bitstring) {
  498. // Figure out the mode.
  499. if ((bitstring[3] & 2) == 0)
  500. // Individual mode.
  501. return 0;
  502. else
  503. return 1;
  504. }
  505. // Determine the mode of the ETC2 RGB8 block.
  506. // Return one of the following values:
  507. // 0 Individual mode
  508. // 1 Differential mode
  509. // 2 T mode
  510. // 3 H mode
  511. // 4 Planar mode
  512. int block4x4_etc2_rgb8_get_mode(const unsigned char *bitstring) {
  513. // Figure out the mode.
  514. if ((bitstring[3] & 2) == 0)
  515. // Individual mode.
  516. return 0;
  517. #if 0
  518. int R = (bitstring[0] & 0xF8) >> 3;;
  519. R += complement3bit(bitstring[0] & 7);
  520. int G = (bitstring[1] & 0xF8) >> 3;
  521. G += complement3bit(bitstring[1] & 7);
  522. int B = (bitstring[2] & 0xF8) >> 3;
  523. B += complement3bit(bitstring[2] & 7);
  524. if (R < 0 || R > 31)
  525. // T mode.
  526. return 2;
  527. else
  528. if (G < 0 || G > 31)
  529. // H mode.
  530. return 3;
  531. else
  532. if (B < 0 || B > 31)
  533. // Planar mode.
  534. return 4;
  535. else
  536. // Differential mode.
  537. return 1;
  538. #else
  539. int R = (bitstring[0] & 0xF8);
  540. R += complement3bitshifted(bitstring[0] & 7);
  541. int G = (bitstring[1] & 0xF8);
  542. G += complement3bitshifted(bitstring[1] & 7);
  543. int B = (bitstring[2] & 0xF8);
  544. B += complement3bitshifted(bitstring[2] & 7);
  545. if (R & 0xFF07)
  546. // T mode.
  547. return 2;
  548. else
  549. if (G & 0xFF07)
  550. // H mode.
  551. return 3;
  552. else
  553. if (B & 0xFF07)
  554. // Planar mode.
  555. return 4;
  556. else
  557. // Differential mode.
  558. return 1;
  559. #endif
  560. }
  561. */
  562. static signed char eac_modifier_table[16][8] = {
  563. { -3, -6, -9, -15, 2, 5, 8, 14 },
  564. { -3, -7, -10, -13, 2, 6, 9, 12 },
  565. { -2, -5, -8, -13, 1, 4, 7, 12 },
  566. { -2, -4, -6, -13, 1, 3, 5, 12 },
  567. { -3, -6, -8, -12, 2, 5, 7, 11 },
  568. { -3, -7, -9, -11, 2, 6, 8, 10 },
  569. { -4, -7, -8, -11, 3, 6, 7, 10 },
  570. { -3, -5, -8, -11, 2, 4, 7, 10 },
  571. { -2, -6, -8, -10, 1, 5, 7, 9 },
  572. { -2, -5, -8, -10, 1, 4, 7, 9 },
  573. { -2, -4, -8, -10, 1, 3, 7, 9 },
  574. { -2, -5, -7, -10, 1, 4, 6, 9 },
  575. { -3, -4, -7, -10, 2, 3, 6, 9 },
  576. { -1, -2, -3, -10, 0, 1, 2, 9 },
  577. { -4, -6, -8, -9, 3, 5, 7, 8 },
  578. { -3, -5, -7, -9, 2, 4, 6, 8 }
  579. };
  580. #if 0
  581. // This table is currently not used.
  582. static short int modifier_times_multiplier_table[30][16] = {
  583. { 0, -15, -30, -45, -60, -75, -90, -105, -120, -135, -150, -165, -180, -195, -210, -225 },
  584. { 0, -14, -28, -42, -56, -70, -84, -98, -112, -126, -140, -154, -168, -182, -196, -210 },
  585. { 0, -13, -26, -39, -52, -65, -78, -91, -104, -117, -130, -143, -156, -169, -182, -195 },
  586. { 0, -12, -24, -36, -48, -60, -72, -84, -96, -108, -120, -132, -144, -156, -168, -180 },
  587. { 0, -11, -22, -33, -44, -55, -66, -77, -88, -99, -110, -121, -132, -143, -154, -165 },
  588. { 0, -10, -20, -30, -40, -50, -60, -70, -80, -90, -100, -110, -120, -130, -140, -150 },
  589. { 0, -9, -18, -27, -36, -45, -54, -63, -72, -81, -90, -99, -108, -117, -126, -135 },
  590. { 0, -8, -16, -24, -32, -40, -48, -56, -64, -72, -80, -88, -96, -104, -112, -120 },
  591. { 0, -7, -14, -21, -28, -35, -42, -49, -56, -63, -70, -77, -84, -91, -98, -105 },
  592. { 0, -6, -12, -18, -24, -30, -36, -42, -48, -54, -60, -66, -72, -78, -84, -90 },
  593. { 0, -5, -10, -15, -20, -25, -30, -35, -40, -45, -50, -55, -60, -65, -70, -75 },
  594. { 0, -4, -8, -12, -16, -20, -24, -28, -32, -36, -40, -44, -48, -52, -56, -60 },
  595. { 0, -3, -6, -9, -12, -15, -18, -21, -24, -27, -30, -33, -36, -39, -42, -45 },
  596. { 0, -2, -4, -6, -8, -10, -12, -14, -16, -18, -20, -22, -24, -26, -28, -30 },
  597. { 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15 },
  598. { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  599. { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
  600. { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 },
  601. { 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45 },
  602. { 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60 },
  603. { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75 },
  604. { 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90 },
  605. { 0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105 },
  606. { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 },
  607. { 0, 9, 18, 27, 36, 45, 54, 63, 72, 81, 90, 99, 108, 117, 126, 135 },
  608. { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150 },
  609. { 0, 11, 22, 33, 44, 55, 66, 77, 88, 99, 110, 121, 132, 143, 154, 165 },
  610. { 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168, 180 },
  611. { 0, 13, 26, 39, 52, 65, 78, 91, 104, 117, 130, 143, 156, 169, 182, 195 },
  612. { 0, 14, 28, 42, 56, 70, 84, 98, 112, 126, 140, 154, 168, 182, 196, 210 },
  613. };
  614. static int modifier_times_multiplier_lookup(int modifier, int multiplier) {
  615. return modifier_times_multiplier_table[modifier + 15][multiplier];
  616. }
  617. #endif
  618. static int modifier_times_multiplier(int modifier, int multiplier) {
  619. return modifier * multiplier;
  620. }
  621. #define do_eac_pixel(val) \
  622. { \
  623. int i = val; \
  624. int modifier = modifier_table[(pixels >> (45 - i * 3)) & 7]; \
  625. *((unsigned char *)&image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] + alpha_byte_offset) = \
  626. clamp(base_codeword + modifier_times_multiplier(modifier, multiplier)); \
  627. }
  628. // Draw a 4x4 pixel block using 128-bit ETC2 EAC compression data.
  629. // This might slow on 32-bit architectures.
  630. int draw_block4x4_etc2_eac(const unsigned char *bitstring, unsigned int *image_buffer) {
  631. int r = draw_block4x4_etc2_rgb8(&bitstring[8], image_buffer);
  632. // Decode the alpha part.
  633. int base_codeword = bitstring[0];
  634. signed char *modifier_table = eac_modifier_table[(bitstring[1] & 0x0F)];
  635. int multiplier = (bitstring[1] & 0xF0) >> 4;
  636. uint64_t pixels = ((uint64_t)bitstring[2] << 40) | ((uint64_t)bitstring[3] << 32) | ((uint64_t)bitstring[4] << 24)
  637. | ((uint64_t)bitstring[5] << 16) | ((uint64_t)bitstring[6] << 8) | bitstring[7];
  638. #if 1
  639. do_eac_pixel(0);
  640. do_eac_pixel(1);
  641. do_eac_pixel(2);
  642. do_eac_pixel(3);
  643. do_eac_pixel(4);
  644. do_eac_pixel(5);
  645. do_eac_pixel(6);
  646. do_eac_pixel(7);
  647. do_eac_pixel(8);
  648. do_eac_pixel(9);
  649. do_eac_pixel(10);
  650. do_eac_pixel(11);
  651. do_eac_pixel(12);
  652. do_eac_pixel(13);
  653. do_eac_pixel(14);
  654. do_eac_pixel(15);
  655. #else
  656. for (int i = 0; i < 16; i++) {
  657. int modifier = modifier_table[(pixels >> (45 - i * 3)) & 7];
  658. *((unsigned char *)&image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] + alpha_byte_offset) =
  659. clamp(base_codeword + modifier_times_multiplier(modifier, multiplier));
  660. }
  661. #endif
  662. return 1;
  663. }
  664. /*int block4x4_etc2_eac_get_mode(const unsigned char *bitstring) {
  665. return block4x4_etc2_rgb8_get_mode(&bitstring[8]);
  666. }*/
  667. static int punchthrough_modifier_table[8][4] = {
  668. { 0, 8, 0, -8 },
  669. { 0, 17, 0, -17 },
  670. { 0, 29, 0, -29 },
  671. { 0, 42, 0, -42 },
  672. { 0, 60, 0, -60 },
  673. { 0, 80, 0, -80 },
  674. { 0, 106, 0, -106 },
  675. { 0, 183, 0, -183 }
  676. };
  677. static unsigned int punchthrough_mask_table[4] = {
  678. 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF };
  679. #define do_flipbit0_pixel0to7_punchthrough(val) \
  680. { \
  681. int i = val; \
  682. int pixel_index = ((pixel_index_word & (1 << i)) >> i) \
  683. | ((pixel_index_word & (0x10000 << i)) >> (16 + i - 1)); \
  684. unsigned int a = 0xFF000000; \
  685. int r, g, b; \
  686. int modifier = punchthrough_modifier_table[table_codeword1][pixel_index]; \
  687. r = clamp(base_color_subblock1_R + modifier); \
  688. g = clamp(base_color_subblock1_G + modifier); \
  689. b = clamp(base_color_subblock1_B + modifier); \
  690. unsigned int mask = punchthrough_mask_table[pixel_index]; \
  691. image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] = (pack_rgb_alpha_0xff(r, g, b)) & mask; \
  692. }
  693. #define do_flipbit0_pixel8to15_punchthrough(val) \
  694. { \
  695. int i = val; \
  696. int pixel_index = ((pixel_index_word & (1 << i)) >> i) \
  697. | ((pixel_index_word & (0x10000 << i)) >> (16 + i - 1)); \
  698. int r, g, b; \
  699. int modifier = punchthrough_modifier_table[table_codeword2][pixel_index]; \
  700. r = clamp(base_color_subblock2_R + modifier); \
  701. g = clamp(base_color_subblock2_G + modifier); \
  702. b = clamp(base_color_subblock2_B + modifier); \
  703. unsigned int mask = punchthrough_mask_table[pixel_index]; \
  704. image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] = (pack_rgb_alpha_0xff(r, g, b)) & mask; \
  705. }
  706. #define do_flipbit1_pixelbit1notset_punchthrough(val) \
  707. { \
  708. int i = val; \
  709. int pixel_index = ((pixel_index_word & (1 << i)) >> i) \
  710. | ((pixel_index_word & (0x10000 << i)) >> (16 + i - 1)); \
  711. int r, g, b; \
  712. int modifier = punchthrough_modifier_table[table_codeword1][pixel_index]; \
  713. r = clamp(base_color_subblock1_R + modifier); \
  714. g = clamp(base_color_subblock1_G + modifier); \
  715. b = clamp(base_color_subblock1_B + modifier); \
  716. unsigned int mask = punchthrough_mask_table[pixel_index]; \
  717. image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] = (pack_rgb_alpha_0xff(r, g, b)) & mask; \
  718. }
  719. #define do_flipbit1_pixelbit1set_punchthrough(val) \
  720. { \
  721. int i = val; \
  722. int pixel_index = ((pixel_index_word & (1 << i)) >> i) \
  723. | ((pixel_index_word & (0x10000 << i)) >> (16 + i - 1)); \
  724. int r, g, b; \
  725. int modifier = punchthrough_modifier_table[table_codeword2][pixel_index]; \
  726. r = clamp(base_color_subblock2_R + modifier); \
  727. g = clamp(base_color_subblock2_G + modifier); \
  728. b = clamp(base_color_subblock2_B + modifier); \
  729. unsigned int mask = punchthrough_mask_table[pixel_index]; \
  730. image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] = (pack_rgb_alpha_0xff(r, g, b)) & mask; \
  731. }
  732. void draw_block4x4_etc2_punchthrough_differential(const unsigned char *bitstring, unsigned int *image_buffer) {
  733. int flipbit = bitstring[3] & 1;
  734. int base_color_subblock1_R;
  735. int base_color_subblock1_G;
  736. int base_color_subblock1_B;
  737. int base_color_subblock2_R;
  738. int base_color_subblock2_G;
  739. int base_color_subblock2_B;
  740. base_color_subblock1_R = (bitstring[0] & 0xF8);
  741. base_color_subblock1_R |= ((base_color_subblock1_R & 224) >> 5);
  742. base_color_subblock1_G = (bitstring[1] & 0xF8);
  743. base_color_subblock1_G |= (base_color_subblock1_G & 224) >> 5;
  744. base_color_subblock1_B = (bitstring[2] & 0xF8);
  745. base_color_subblock1_B |= (base_color_subblock1_B & 224) >> 5;
  746. base_color_subblock2_R = (bitstring[0] & 0xF8); // 5 highest order bits.
  747. base_color_subblock2_R += complement3bitshifted(bitstring[0] & 7); // Add difference.
  748. base_color_subblock2_R |= (base_color_subblock2_R & 224) >> 5; // Replicate.
  749. base_color_subblock2_G = (bitstring[1] & 0xF8);
  750. base_color_subblock2_G += complement3bitshifted(bitstring[1] & 7);
  751. base_color_subblock2_G |= (base_color_subblock2_G & 224) >> 5;
  752. base_color_subblock2_B = (bitstring[2] & 0xF8);
  753. base_color_subblock2_B += complement3bitshifted(bitstring[2] & 7);
  754. base_color_subblock2_B |= (base_color_subblock2_B & 224) >> 5;
  755. int table_codeword1 = (bitstring[3] & 224) >> 5;
  756. int table_codeword2 = (bitstring[3] & 28) >> 2;
  757. unsigned int pixel_index_word = ((unsigned int)bitstring[4] << 24) | ((unsigned int)bitstring[5] << 16) |
  758. ((unsigned int)bitstring[6] << 8) | bitstring[7];
  759. if (flipbit == 0) {
  760. do_flipbit0_pixel0to7_punchthrough(0);
  761. do_flipbit0_pixel0to7_punchthrough(1);
  762. do_flipbit0_pixel0to7_punchthrough(2);
  763. do_flipbit0_pixel0to7_punchthrough(3);
  764. do_flipbit0_pixel0to7_punchthrough(4);
  765. do_flipbit0_pixel0to7_punchthrough(5);
  766. do_flipbit0_pixel0to7_punchthrough(6);
  767. do_flipbit0_pixel0to7_punchthrough(7);
  768. do_flipbit0_pixel8to15_punchthrough(8);
  769. do_flipbit0_pixel8to15_punchthrough(9);
  770. do_flipbit0_pixel8to15_punchthrough(10);
  771. do_flipbit0_pixel8to15_punchthrough(11);
  772. do_flipbit0_pixel8to15_punchthrough(12);
  773. do_flipbit0_pixel8to15_punchthrough(13);
  774. do_flipbit0_pixel8to15_punchthrough(14);
  775. do_flipbit0_pixel8to15_punchthrough(15);
  776. return;
  777. }
  778. else {
  779. do_flipbit1_pixelbit1notset_punchthrough(0);
  780. do_flipbit1_pixelbit1notset_punchthrough(1);
  781. do_flipbit1_pixelbit1set_punchthrough(2);
  782. do_flipbit1_pixelbit1set_punchthrough(3);
  783. do_flipbit1_pixelbit1notset_punchthrough(4);
  784. do_flipbit1_pixelbit1notset_punchthrough(5);
  785. do_flipbit1_pixelbit1set_punchthrough(6);
  786. do_flipbit1_pixelbit1set_punchthrough(7);
  787. do_flipbit1_pixelbit1notset_punchthrough(8);
  788. do_flipbit1_pixelbit1notset_punchthrough(9);
  789. do_flipbit1_pixelbit1set_punchthrough(10);
  790. do_flipbit1_pixelbit1set_punchthrough(11);
  791. do_flipbit1_pixelbit1notset_punchthrough(12);
  792. do_flipbit1_pixelbit1notset_punchthrough(13);
  793. do_flipbit1_pixelbit1set_punchthrough(14);
  794. do_flipbit1_pixelbit1set_punchthrough(15);
  795. return;
  796. }
  797. }
  798. void draw_block4x4_etc2_punchthrough_T_or_H_mode(const unsigned char *bitstring, unsigned int *image_buffer, int mode) {
  799. int base_color1_R, base_color1_G, base_color1_B;
  800. int base_color2_R, base_color2_G, base_color2_B;
  801. int paint_color_R[4], paint_color_G[4], paint_color_B[4];
  802. int distance;
  803. if (mode == 0) {
  804. // T mode.
  805. base_color1_R = ((bitstring[0] & 0x18) >> 1) | (bitstring[0] & 0x3);
  806. base_color1_R |= base_color1_R << 4;
  807. base_color1_G = bitstring[1] & 0xF0;
  808. base_color1_G |= base_color1_G >> 4;
  809. base_color1_B = bitstring[1] & 0x0F;
  810. base_color1_B |= base_color1_B << 4;
  811. base_color2_R = bitstring[2] & 0xF0;
  812. base_color2_R |= base_color2_R >> 4;
  813. base_color2_G = bitstring[2] & 0x0F;
  814. base_color2_G |= base_color2_G << 4;
  815. base_color2_B = bitstring[3] & 0xF0;
  816. base_color2_B |= base_color2_B >> 4;
  817. // index = (da << 1) | db
  818. distance = etc2_distance_table[((bitstring[3] & 0x0C) >> 1) | (bitstring[3] & 0x1)];
  819. paint_color_R[0] = base_color1_R;
  820. paint_color_G[0] = base_color1_G;
  821. paint_color_B[0] = base_color1_B;
  822. paint_color_R[2] = base_color2_R;
  823. paint_color_G[2] = base_color2_G;
  824. paint_color_B[2] = base_color2_B;
  825. paint_color_R[1] = clamp(base_color2_R + distance);
  826. paint_color_G[1] = clamp(base_color2_G + distance);
  827. paint_color_B[1] = clamp(base_color2_B + distance);
  828. paint_color_R[3] = clamp(base_color2_R - distance);
  829. paint_color_G[3] = clamp(base_color2_G - distance);
  830. paint_color_B[3] = clamp(base_color2_B - distance);
  831. }
  832. else {
  833. // H mode.
  834. base_color1_R = (bitstring[0] & 0x78) >> 3;
  835. base_color1_R |= base_color1_R << 4;
  836. base_color1_G = ((bitstring[0] & 0x07) << 1) | ((bitstring[1] & 0x10) >> 4);
  837. base_color1_G |= base_color1_G << 4;
  838. base_color1_B = (bitstring[1] & 0x08) | ((bitstring[1] & 0x03) << 1) | ((bitstring[2] & 0x80) >> 7);
  839. base_color1_B |= base_color1_B << 4;
  840. base_color2_R = (bitstring[2] & 0x78) >> 3;
  841. base_color2_R |= base_color2_R << 4;
  842. base_color2_G = ((bitstring[2] & 0x07) << 1) | ((bitstring[3] & 0x80) >> 7);
  843. base_color2_G |= base_color2_G << 4;
  844. base_color2_B = (bitstring[3] & 0x78) >> 3;
  845. base_color2_B |= base_color2_B << 4;
  846. // da is most significant bit, db is middle bit, least significant bit is
  847. // (base_color1 value >= base_color2 value).
  848. int base_color1_value = (base_color1_R << 16) + (base_color1_G << 8) + base_color1_B;
  849. int base_color2_value = (base_color2_R << 16) + (base_color2_G << 8) + base_color2_B;
  850. int bit;
  851. if (base_color1_value >= base_color2_value)
  852. bit = 1;
  853. else
  854. bit = 0;
  855. distance = etc2_distance_table[(bitstring[3] & 0x04) | ((bitstring[3] & 0x01) << 1) | bit];
  856. paint_color_R[0] = clamp(base_color1_R + distance);
  857. paint_color_G[0] = clamp(base_color1_G + distance);
  858. paint_color_B[0] = clamp(base_color1_B + distance);
  859. paint_color_R[1] = clamp(base_color1_R - distance);
  860. paint_color_G[1] = clamp(base_color1_G - distance);
  861. paint_color_B[1] = clamp(base_color1_B - distance);
  862. paint_color_R[2] = clamp(base_color2_R + distance);
  863. paint_color_G[2] = clamp(base_color2_G + distance);
  864. paint_color_B[2] = clamp(base_color2_B + distance);
  865. paint_color_R[3] = clamp(base_color2_R - distance);
  866. paint_color_G[3] = clamp(base_color2_G - distance);
  867. paint_color_B[3] = clamp(base_color2_B - distance);
  868. }
  869. unsigned int pixel_index_word = ((unsigned int)bitstring[4] << 24) | ((unsigned int)bitstring[5] << 16) |
  870. ((unsigned int)bitstring[6] << 8) | bitstring[7];
  871. for (int i = 0; i < 16; i++) {
  872. int pixel_index = ((pixel_index_word & (1 << i)) >> i) // Least significant bit.
  873. | ((pixel_index_word & (0x10000 << i)) >> (16 + i - 1)); // Most significant bit.
  874. int r = paint_color_R[pixel_index];
  875. int g = paint_color_G[pixel_index];
  876. int b = paint_color_B[pixel_index];
  877. unsigned int mask = punchthrough_mask_table[pixel_index];
  878. image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] = (pack_rgb_alpha_0xff(r, g, b)) & mask;
  879. }
  880. }
  881. /*int block4x4_etc2_punchthrough_get_mode(const unsigned char *bitstring) {
  882. // Figure out the mode.
  883. int opaque = bitstring[3] & 2;
  884. int R = (bitstring[0] & 0xF8);
  885. R += complement3bitshifted(bitstring[0] & 7);
  886. int G = (bitstring[1] & 0xF8);
  887. G += complement3bitshifted(bitstring[1] & 7);
  888. int B = (bitstring[2] & 0xF8);
  889. B += complement3bitshifted(bitstring[2] & 7);
  890. if (R & 0xFF07)
  891. // T mode.
  892. return 2;
  893. else if (G & 0xFF07)
  894. // H mode.
  895. return 3;
  896. else if (B & 0xFF07)
  897. // Planar mode.
  898. return 4;
  899. else
  900. // Differential mode.
  901. return 1;
  902. }*/
  903. // Draw a 4x4 pixel block using 64-bit ETC2 PUNCHTHROUGH ALPHA compression data.
  904. int draw_block4x4_etc2_punchthrough(const unsigned char *bitstring, unsigned int *image_buffer) {
  905. int R = (bitstring[0] & 0xF8);
  906. R += complement3bitshifted(bitstring[0] & 7);
  907. int G = (bitstring[1] & 0xF8);
  908. G += complement3bitshifted(bitstring[1] & 7);
  909. int B = (bitstring[2] & 0xF8);
  910. B += complement3bitshifted(bitstring[2] & 7);
  911. int opaque = bitstring[3] & 2;
  912. if (R & 0xFF07) {
  913. // T mode.
  914. if (opaque) {
  915. draw_block4x4_rgb8_etc2_T_or_H_mode(bitstring, image_buffer, 0);
  916. return 1;
  917. }
  918. // T mode with punchthrough alpha.
  919. draw_block4x4_etc2_punchthrough_T_or_H_mode(bitstring, image_buffer, 0);
  920. return 1;
  921. }
  922. else
  923. if (G & 0xFF07) {
  924. // H mode.
  925. if (opaque) {
  926. draw_block4x4_rgb8_etc2_T_or_H_mode(bitstring, image_buffer, 1);
  927. return 1;
  928. }
  929. // H mode with punchthrough alpha.
  930. draw_block4x4_etc2_punchthrough_T_or_H_mode(bitstring, image_buffer, 1);
  931. return 1;
  932. }
  933. else
  934. if (B & 0xFF07) {
  935. // Planar mode.
  936. draw_block4x4_rgb8_etc2_planar_mode(bitstring, image_buffer);
  937. return 1;
  938. }
  939. else {
  940. // Differential mode.
  941. if (opaque)
  942. return draw_block4x4_etc1(bitstring, image_buffer);
  943. // Differential mode with punchthrough alpha.
  944. draw_block4x4_etc2_punchthrough_differential(bitstring, image_buffer);
  945. return 1;
  946. }
  947. }
  948. /*
  949. // Decode an 11-bit integer and store it in the first 16-bits in memory of each pixel in image_buffer if offset is zero,
  950. // in the last 16 bits in memory if offset is 1.
  951. void decode_block4x4_11bits(uint64_t qword, unsigned int *image_buffer, int offset) {
  952. int base_codeword_times_8_plus_4 = ((qword & 0xFF00000000000000) >> (56 - 3)) | 0x4;
  953. int modifier_index = (qword & 0x000F000000000000) >> 48;
  954. signed char *modifier_table = eac_modifier_table[modifier_index];
  955. int multiplier_times_8 = (qword & 0x00F0000000000000) >> (52 - 3);
  956. if (multiplier_times_8 == 0)
  957. for (int i = 0; i < 16; i++) {
  958. int pixel_index = (qword & (0x0000E00000000000 >> (i * 3))) >> (45 - i * 3);
  959. int modifier = modifier_table[pixel_index];
  960. unsigned int value = clamp2047(base_codeword_times_8_plus_4 + modifier);
  961. *((unsigned short *)&image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] + offset) =
  962. (value << 5) | (value >> 6); // Replicate bits to 16-bit.
  963. }
  964. else
  965. for (int i = 0; i < 16; i++) {
  966. int pixel_index = (qword & (0x0000E00000000000 >> (i * 3))) >> (45 - i * 3);
  967. int modifier = modifier_table[pixel_index];
  968. unsigned int value = clamp2047(base_codeword_times_8_plus_4 + modifier * multiplier_times_8);
  969. *((unsigned short *)&image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] + offset) =
  970. (value << 5) | (value >> 6); // Replicate bits to 16-bit.
  971. }
  972. }
  973. // Draw a 4x4 pixel block using 64-bit ETC2 R11_EAC compression data.
  974. int draw_block4x4_r11_eac(const unsigned char *bitstring, unsigned int *image_buffer, int offset) {
  975. memset(image_buffer, 0, 64);
  976. uint64_t qword = ((uint64_t)bitstring[0] << 56) | ((uint64_t)bitstring[1] << 48) | ((uint64_t)bitstring[2] << 40) |
  977. ((uint64_t)bitstring[3] << 32) | ((uint64_t)bitstring[4] << 24) |
  978. ((uint64_t)bitstring[5] << 16) | ((uint64_t)bitstring[6] << 8) | bitstring[7];
  979. decode_block4x4_11bits(qword, image_buffer, 0);
  980. return 1;
  981. }
  982. // Draw a 4x4 pixel block using 128-bit ETC2 RG11_EAC compression data.
  983. int draw_block4x4_rg11_eac(const unsigned char *bitstring, unsigned int *image_buffer, int flags) {
  984. uint64_t red_qword = ((uint64_t)bitstring[0] << 56) | ((uint64_t)bitstring[1] << 48) | ((uint64_t)bitstring[2] << 40) |
  985. ((uint64_t)bitstring[3] << 32) | ((uint64_t)bitstring[4] << 24) |
  986. ((uint64_t)bitstring[5] << 16) | ((uint64_t)bitstring[6] << 8) | bitstring[7];
  987. decode_block4x4_11bits(red_qword, image_buffer, 0);
  988. uint64_t green_qword = ((uint64_t)bitstring[8] << 56) | ((uint64_t)bitstring[9] << 48) | ((uint64_t)bitstring[10] << 40) |
  989. ((uint64_t)bitstring[11] << 32) | ((uint64_t)bitstring[12] << 24) |
  990. ((uint64_t)bitstring[13] << 16) | ((uint64_t)bitstring[14] << 8) | bitstring[15];
  991. decode_block4x4_11bits(green_qword, image_buffer, 1);
  992. return 1;
  993. }
  994. static unsigned int replicate_11bits_signed_to_16bits(int value) {
  995. if (value >= 0)
  996. return (value << 5) | (value >> 5);
  997. value = - value;
  998. value = (value << 5) | (value >> 5);
  999. return - value;
  1000. }
  1001. // Decode an 11-bit signed integer and store it in the first 16-bits in memory of each pixel in image_buffer if offset is
  1002. // zero, in the last 16 bits in memory if offset is 1.
  1003. int decode_block4x4_11bits_signed(uint64_t qword, unsigned int *image_buffer, int offset, int flags) {
  1004. int base_codeword = (signed char)((qword & 0xFF00000000000000) >> 56); // Signed 8 bits.
  1005. if (base_codeword == - 128) // && (flags & ENCODE_BIT)
  1006. // Not allowed in encoding. Decoder should handle it but we don't do that yet.
  1007. return 0;
  1008. int base_codeword_times_8 = base_codeword << 3; // Arithmetic shift.
  1009. int modifier_index = (qword & 0x000F000000000000) >> 48;
  1010. signed char *modifier_table = eac_modifier_table[modifier_index];
  1011. int multiplier_times_8 = (qword & 0x00F0000000000000) >> (52 - 3);
  1012. if (multiplier_times_8 == 0)
  1013. for (int i = 0; i < 16; i++) {
  1014. int pixel_index = (qword & (0x0000E00000000000 >> (i * 3))) >> (45 - i * 3);
  1015. int modifier = modifier_table[pixel_index];
  1016. int value = clamp1023_signed(base_codeword_times_8 + modifier);
  1017. unsigned int bits = replicate_11bits_signed_to_16bits(value);
  1018. *((unsigned short *)&image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] + offset) = bits;
  1019. }
  1020. else
  1021. for (int i = 0; i < 16; i++) {
  1022. int pixel_index = (qword & (0x0000E00000000000 >> (i * 3))) >> (45 - i * 3);
  1023. int modifier = modifier_table[pixel_index];
  1024. int value = clamp1023_signed(base_codeword_times_8 + modifier * multiplier_times_8);
  1025. unsigned int bits = replicate_11bits_signed_to_16bits(value);
  1026. *((unsigned short *)&image_buffer[(i & 3) * 4 + ((i & 12) >> 2)] + offset) = bits;
  1027. }
  1028. return 1;
  1029. }
  1030. // Draw a 4x4 pixel block using 64-bit ETC2 SIGNED_R11_EAC compression data.
  1031. int draw_block4x4_signed_r11_eac(const unsigned char *bitstring, unsigned int *image_buffer, int flags) {
  1032. memset(image_buffer, 0, 64);
  1033. uint64_t qword = ((uint64_t)bitstring[0] << 56) | ((uint64_t)bitstring[1] << 48) | ((uint64_t)bitstring[2] << 40) |
  1034. ((uint64_t)bitstring[3] << 32) | ((uint64_t)bitstring[4] << 24) |
  1035. ((uint64_t)bitstring[5] << 16) | ((uint64_t)bitstring[6] << 8) | bitstring[7];
  1036. return decode_block4x4_11bits_signed(qword, image_buffer, 0, flags);
  1037. }
  1038. // Draw a 4x4 pixel block using 128-bit ETC2 SIGNED_RG11_EAC compression data.
  1039. int draw_block4x4_signed_rg11_eac(const unsigned char *bitstring, unsigned int *image_buffer, int flags) {
  1040. uint64_t red_qword = ((uint64_t)bitstring[0] << 56) | ((uint64_t)bitstring[1] << 48) | ((uint64_t)bitstring[2] << 40) |
  1041. ((uint64_t)bitstring[3] << 32) | ((uint64_t)bitstring[4] << 24) |
  1042. ((uint64_t)bitstring[5] << 16) | ((uint64_t)bitstring[6] << 8) | bitstring[7];
  1043. int r = decode_block4x4_11bits_signed(red_qword, image_buffer, 0, flags);
  1044. if (r == 0)
  1045. return 0;
  1046. uint64_t green_qword = ((uint64_t)bitstring[8] << 56) | ((uint64_t)bitstring[9] << 48) | ((uint64_t)bitstring[10] << 40) |
  1047. ((uint64_t)bitstring[11] << 32) | ((uint64_t)bitstring[12] << 24) |
  1048. ((uint64_t)bitstring[13] << 16) | ((uint64_t)bitstring[14] << 8) | bitstring[15];
  1049. decode_block4x4_11bits_signed(green_qword, image_buffer, 1, flags);
  1050. return 1;
  1051. }
  1052. // Manual optimization function for the alpha components of ETC2 PUNCHTHROUGH mode.
  1053. void optimize_block_alpha_etc2_punchthrough(unsigned char *bitstring, unsigned char *alpha_values) {
  1054. if (bitstring[3] & 2)
  1055. // Opaque mode. Don't bother optimizing this bitstring.
  1056. return;
  1057. int R = (bitstring[0] & 0xF8);
  1058. R += complement3bitshifted(bitstring[0] & 7);
  1059. int G = (bitstring[1] & 0xF8);
  1060. G += complement3bitshifted(bitstring[1] & 7);
  1061. int B = (bitstring[2] & 0xF8);
  1062. B += complement3bitshifted(bitstring[2] & 7);
  1063. if (!(R & 0xFF07) && !(G & 0xFF07) && (B & 0xFF07))
  1064. // Planar mode. Always opaque.
  1065. return;
  1066. // We have differential, T or H mode with pixels that can be non-opaque.
  1067. unsigned int pixel_index_word = ((unsigned int)bitstring[4] << 24) | ((unsigned int)bitstring[5] << 16) |
  1068. ((unsigned int)bitstring[6] << 8) | bitstring[7];
  1069. for (int i = 0; i < 16; i++) {
  1070. int pixel_index = ((pixel_index_word & (1 << i)) >> i) // Least significant bit.
  1071. | ((pixel_index_word & (0x10000 << i)) >> (16 + i - 1)); // Most significant bit.
  1072. int row_major_index = (i & 3) * 4 + ((i & 12) >> 2);
  1073. if (alpha_values[row_major_index] < 128 && pixel_index != 2)
  1074. // Force pixel index 2 (transparent, alpha is 0).
  1075. pixel_index = 2;
  1076. if (alpha_values[row_major_index] >= 128 && pixel_index == 2)
  1077. // Force pixel index 1 (opaque). pixel index 0 or 3 would also be ok.
  1078. pixel_index = 1;
  1079. // Set the pixel index. First clear the two pixel index bits.
  1080. pixel_index_word &= ~((1 << i) | (0x10000 << i));
  1081. // Set the two bits.
  1082. pixel_index_word |= ((pixel_index & 1) << i) | ((pixel_index & 2) << (16 + i - 1));
  1083. }
  1084. bitstring[4] = pixel_index_word >> 24; // Only the lower 8 bits are assigned.
  1085. bitstring[5] = pixel_index_word >> 16;
  1086. bitstring[6] = pixel_index_word >> 8;
  1087. bitstring[7] = pixel_index_word;
  1088. }
  1089. void optimize_block_alpha_etc2_eac(unsigned char *bitstring, unsigned char *alpha_values, int flags) {
  1090. // Optimize the alpha values if they are either 0x00 or 0xFF.
  1091. int base_codeword = 225;
  1092. // Select modifier table entry 0: { -3, -6, -9, -15, 2, 5, 8, 14 }
  1093. int modifier_table = 0;
  1094. // Select multiplier 15, so that:
  1095. // pixel value 3 = 225 + 15 * - 15 = 0
  1096. // pixel value 4 = 225 + 2 * 15 = 255
  1097. int multiplier = 15;
  1098. bitstring[0] = base_codeword;
  1099. bitstring[1] = modifier_table | (multiplier << 4);
  1100. uint64_t pixels = 0;
  1101. for (int i = 0; i < 16; i++) {
  1102. int j = (i & 3) * 4 + ((i & 12) >> 2);
  1103. uint64_t pixel_index;
  1104. if (alpha_values[j] == 0)
  1105. pixel_index = 0x3;
  1106. else
  1107. pixel_index = 0x4;
  1108. pixels |= pixel_index << (45 - i * 3);
  1109. }
  1110. bitstring[2] = (uint8_t)(pixels >> 40);
  1111. bitstring[3] = (uint8_t)(pixels >> 32);
  1112. bitstring[4] = (uint8_t)(pixels >> 24);
  1113. bitstring[5] = (uint8_t)(pixels >> 16);
  1114. bitstring[6] = (uint8_t)(pixels >> 8);
  1115. bitstring[7] = (uint8_t)pixels;
  1116. }
  1117. // set_mode functions: Try to modify the bitstring so that it conforms to a single mode if a single
  1118. // mode is defined in flags.
  1119. static void etc2_set_mode_THP(unsigned char *bitstring, int flags) {
  1120. if ((flags & ETC2_MODE_ALLOWED_ALL) == ETC2_MODE_ALLOWED_T) {
  1121. // bitstring[0] bits 0, 1, 3, 4 are used.
  1122. // Bits 2, 5, 6, 7 can be modified.
  1123. // Modify bits 2, 5, 6, 7 so that R < 0 or R > 31.
  1124. int R_bits_5_to_7_clear = (bitstring[0] & 0x18) >> 3;
  1125. int R_compl_bit_2_clear = complement3bit(bitstring[0] & 0x3);
  1126. if (R_bits_5_to_7_clear + 0x1C + R_compl_bit_2_clear > 31) {
  1127. // Set bits 5, 6, 7 and clear bit 2.
  1128. bitstring[0] &= ~0x04;
  1129. bitstring[0] |= 0xE0;
  1130. }
  1131. else {
  1132. int R_compl_bit_2_set = complement3bit((bitstring[0] & 0x3) | 0x4);
  1133. if (R_bits_5_to_7_clear + R_compl_bit_2_set < 0) {
  1134. // Clear bits 5, 6, 7 and set bit 2.
  1135. bitstring[0] &= ~0xE0;
  1136. bitstring[0] |= 0x04;
  1137. }
  1138. else
  1139. printf("set_mode: Can't modify ETC2_PUNCHTHROUGH mode to mode T.\n");
  1140. }
  1141. // printf("set_mode: bitstring[0] = 0x%02X\n", bitstring[0]);
  1142. }
  1143. else if ((flags & ETC2_MODE_ALLOWED_ALL) == ETC2_MODE_ALLOWED_H) {
  1144. int G_bits_5_to_7_clear = (bitstring[1] & 0x18) >> 3;
  1145. int G_compl_bit_2_clear = complement3bit(bitstring[1] & 0x3);
  1146. if (G_bits_5_to_7_clear + 0x1C + G_compl_bit_2_clear > 31) {
  1147. // Set bits 5, 6, 7 and clear bit 2.
  1148. bitstring[1] &= ~0x04;
  1149. bitstring[1] |= 0xE0;
  1150. }
  1151. else {
  1152. int G_compl_bit_2_set = complement3bit((bitstring[1] & 0x3) | 0x4);
  1153. if (G_bits_5_to_7_clear + G_compl_bit_2_set < 0) {
  1154. // Clear bits 5, 6, 7 and set bit 2.
  1155. bitstring[1] &= ~0xE0;
  1156. bitstring[1] |= 0x04;
  1157. }
  1158. else
  1159. printf("set_mode: Can't modify ETC2_PUNCHTHROUGH mode to mode H.\n");
  1160. }
  1161. }
  1162. else if ((flags & ETC2_MODE_ALLOWED_ALL) == ETC2_MODE_ALLOWED_PLANAR) {
  1163. int B_bits_5_to_7_clear = (bitstring[2] & 0x18) >> 3;
  1164. int B_compl_bit_2_clear = complement3bit(bitstring[2] & 0x3);
  1165. if (B_bits_5_to_7_clear + 0x1C + B_compl_bit_2_clear > 31) {
  1166. // Set bits 5, 6, 7 and clear bit 2.
  1167. bitstring[2] &= ~0x04;
  1168. bitstring[2] |= 0xE0;
  1169. }
  1170. else {
  1171. int B_compl_bit_2_set = complement3bit((bitstring[2] & 0x3) | 0x4);
  1172. if (B_bits_5_to_7_clear + B_compl_bit_2_set < 0) {
  1173. // Clear bits 5, 6, 7 and set bit 2.
  1174. bitstring[2] &= ~0xE0;
  1175. bitstring[2] |= 0x04;
  1176. }
  1177. else
  1178. printf("set_mode: Can't modify ETC2_PUNCHTHROUGH mode to mode P.\n");
  1179. }
  1180. // printf("set_mode: bitstring[2] = 0x%02X\n", bitstring[2]);
  1181. }
  1182. }
  1183. void block4x4_etc1_set_mode(unsigned char *bitstring, int flags) {
  1184. if ((flags & ETC2_MODE_ALLOWED_ALL) == ETC_MODE_ALLOWED_INDIVIDUAL)
  1185. bitstring[3] &= ~0x2;
  1186. else
  1187. bitstring[3] |= 0x2;
  1188. }
  1189. void block4x4_etc2_rgb8_set_mode(unsigned char *bitstring, int flags) {
  1190. if ((flags & ETC2_MODE_ALLOWED_ALL) == ETC_MODE_ALLOWED_INDIVIDUAL)
  1191. bitstring[3] &= ~0x2;
  1192. else {
  1193. bitstring[3] |= 0x2;
  1194. etc2_set_mode_THP(bitstring, flags);
  1195. }
  1196. }
  1197. void block4x4_etc2_eac_set_mode(unsigned char *bitstring, int flags) {
  1198. block4x4_etc2_rgb8_set_mode(&bitstring[8], flags);
  1199. }
  1200. void block4x4_etc2_punchthrough_set_mode(unsigned char *bitstring, int flags) {
  1201. if (flags & MODES_ALLOWED_NON_OPAQUE_ONLY)
  1202. bitstring[3] &= ~0x2;
  1203. if (flags & MODES_ALLOWED_OPAQUE_ONLY)
  1204. bitstring[3] |= 0x2;
  1205. etc2_set_mode_THP(bitstring, flags);
  1206. }
  1207. */