dxt.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #define HL_NAME(n) fmt_##n
  2. #include <hl.h>
  3. static const int BIT5[] = { 0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140, 148, 156, 165, 173, 181, 189, 197, 206, 214, 222, 230, 239, 247, 255 };
  4. static const int BIT6[] = { 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138, 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255 };
  5. #define MK_COLOR(r,g,b,a) (((a)<<24) | ((b)<<16) | ((g)<<8) | (r))
  6. #define DXT_COLOR1(c,a) MK_COLOR( \
  7. BIT5[(c & 0xFC00) >> 11], \
  8. BIT6[(c & 0x07E0) >> 5], \
  9. BIT5[(c & 0x001F)], \
  10. a)
  11. #define DXT_COLOR2(c0,c1,a) MK_COLOR( \
  12. (BIT5[(c0 & 0xFC00) >> 11] + BIT5[(c1 & 0xFC00) >> 11]) / 2, \
  13. (BIT6[(c0 & 0x07E0) >> 5] + BIT6[(c1 & 0x07E0) >> 5]) / 2, \
  14. (BIT5[c0 & 0x001F] + BIT5[c1 & 0x001F]) / 2, \
  15. a)
  16. #define DXT_COLOR3(c0,c1,a) MK_COLOR( \
  17. (2 * BIT5[(c0 & 0xFC00) >> 11] + BIT5[(c1 & 0xFC00) >> 11]) / 3, \
  18. (2 * BIT6[(c0 & 0x07E0) >> 5] + BIT6[(c1 & 0x07E0) >> 5]) / 3, \
  19. (2 * BIT5[c0 & 0x001F] + BIT5[c1 & 0x001F]) / 3, \
  20. a)
  21. static int dxtAlpha(int a0, int a1, int t) {
  22. if (a0 > a1) switch (t) {
  23. case 0: return a0;
  24. case 1: return a1;
  25. case 2: return (6 * a0 + a1) / 7;
  26. case 3: return (5 * a0 + 2 * a1) / 7;
  27. case 4: return (4 * a0 + 3 * a1) / 7;
  28. case 5: return (3 * a0 + 4 * a1) / 7;
  29. case 6: return (2 * a0 + 5 * a1) / 7;
  30. case 7: return (a0 + 6 * a1) / 7;
  31. }
  32. else switch (t) {
  33. case 0: return a0;
  34. case 1: return a1;
  35. case 2: return (4 * a0 + a1) / 5;
  36. case 3: return (3 * a0 + 2 * a1) / 5;
  37. case 4: return (2 * a0 + 3 * a1) / 5;
  38. case 5: return (a0 + 4 * a1) / 5;
  39. case 6: return 0;
  40. case 7: return 255;
  41. }
  42. return 0;
  43. }
  44. static int dxtColor(int c0, int c1, int a, int t) {
  45. switch (t) {
  46. case 0: return DXT_COLOR1(c0, a);
  47. case 1: return DXT_COLOR1(c1, a);
  48. case 2: return (c0 > c1) ? DXT_COLOR3(c0, c1, a) : DXT_COLOR2(c0, c1, a);
  49. case 3: return (c0 > c1) ? DXT_COLOR3(c1, c0, a) : 0;
  50. }
  51. return 0;
  52. }
  53. HL_PRIM bool HL_NAME(dxt_decode)( vbyte *data, int *out, int width, int height, int format ) {
  54. int x,y,k;
  55. int index = 0;
  56. int write = 0;
  57. int alpha[16];
  58. switch( format ) {
  59. case 1:
  60. for(y=0;y<height>>2;y++) {
  61. for(x=0;x<width>>2;x++) {
  62. int c0 = data[index] | (data[index + 1] << 8); index += 2;
  63. int c1 = data[index] | (data[index + 1] << 8); index += 2;
  64. for(k=0;k<4;k++) {
  65. unsigned char c = data[index++];
  66. int t0 = c & 0x03;
  67. int t1 = (c & 0x0C) >> 2;
  68. int t2 = (c & 0x30) >> 4;
  69. int t3 = (c & 0xC0) >> 6;
  70. int w = write + k * width;
  71. out[w++] = dxtColor(c0, c1, 0xFF, t0);
  72. out[w++] = dxtColor(c0, c1, 0xFF, t1);
  73. out[w++] = dxtColor(c0, c1, 0xFF, t2);
  74. out[w++] = dxtColor(c0, c1, 0xFF, t3);
  75. }
  76. write += 4;
  77. }
  78. write += 3 * width;
  79. }
  80. return true;
  81. case 2:
  82. for(y=0;y<height>>2;y++) {
  83. for(x=0;x<width>>2;x++) {
  84. int ap = 0;
  85. for(k=0;k<4;k++) {
  86. int a0 = data[index++];
  87. int a1 = data[index++];
  88. alpha[ap++] = 17 * ((a0 & 0xF0) >> 4);
  89. alpha[ap++] = 17 * (a0 & 0x0F);
  90. alpha[ap++] = 17 * ((a1 & 0xF0) >> 4);
  91. alpha[ap++] = 17 * (a1 & 0x0F);
  92. }
  93. ap = 0;
  94. int c0 = data[index] | (data[index + 1] << 8); index += 2;
  95. int c1 = data[index] | (data[index + 1] << 8); index += 2;
  96. for (int k = 0; k<4; k++) {
  97. int c = data[index++];
  98. int t0 = c & 0x03;
  99. int t1 = (c & 0x0C) >> 2;
  100. int t2 = (c & 0x30) >> 4;
  101. int t3 = (c & 0xC0) >> 6;
  102. int w = write + k * width;
  103. out[w++] = dxtColor(c0, c1, alpha[ap++], t0);
  104. out[w++] = dxtColor(c0, c1, alpha[ap++], t1);
  105. out[w++] = dxtColor(c0, c1, alpha[ap++], t2);
  106. out[w++] = dxtColor(c0, c1, alpha[ap++], t3);
  107. }
  108. write += 4;
  109. }
  110. write += 3 * width;
  111. }
  112. return true;
  113. case 3:
  114. for(y=0;y<height>>2;y++) {
  115. for(x=0;x<width>>2;x++) {
  116. int a0 = data[index++];
  117. int a1 = data[index++];
  118. int b0 = data[index] | (data[index + 1] << 8) | (data[index + 2] << 16); index += 3;
  119. int b1 = data[index] | (data[index + 1] << 8) | (data[index + 2] << 16); index += 3;
  120. alpha[0] = b0 & 0x07;
  121. alpha[1] = (b0 >> 3) & 0x07;
  122. alpha[2] = (b0 >> 6) & 0x07;
  123. alpha[3] = (b0 >> 9) & 0x07;
  124. alpha[4] = (b0 >> 12) & 0x07;
  125. alpha[5] = (b0 >> 15) & 0x07;
  126. alpha[6] = (b0 >> 18) & 0x07;
  127. alpha[7] = (b0 >> 21) & 0x07;
  128. alpha[8] = b1 & 0x07;
  129. alpha[9] = (b1 >> 3) & 0x07;
  130. alpha[10] = (b1 >> 6) & 0x07;
  131. alpha[11] = (b1 >> 9) & 0x07;
  132. alpha[12] = (b1 >> 12) & 0x07;
  133. alpha[13] = (b1 >> 15) & 0x07;
  134. alpha[14] = (b1 >> 18) & 0x07;
  135. alpha[15] = (b1 >> 21) & 0x07;
  136. int c0 = data[index] | (data[index + 1] << 8); index += 2;
  137. int c1 = data[index] | (data[index + 1] << 8); index += 2;
  138. int ap = 0;
  139. for (int k = 0; k<4; k++) {
  140. int c = data[index++];
  141. int t0 = c & 0x03;
  142. int t1 = (c & 0x0C) >> 2;
  143. int t2 = (c & 0x30) >> 4;
  144. int t3 = (c & 0xC0) >> 6;
  145. int w = write + k * width;
  146. out[w++] = dxtColor(c0, c1, dxtAlpha(a0, a1, alpha[ap++]), t0);
  147. out[w++] = dxtColor(c0, c1, dxtAlpha(a0, a1, alpha[ap++]), t1);
  148. out[w++] = dxtColor(c0, c1, dxtAlpha(a0, a1, alpha[ap++]), t2);
  149. out[w++] = dxtColor(c0, c1, dxtAlpha(a0, a1, alpha[ap++]), t3);
  150. }
  151. write += 4;
  152. }
  153. write += 3 * width;
  154. }
  155. return true;
  156. default:
  157. return false;
  158. }
  159. }
  160. DEFINE_PRIM(_BOOL, dxt_decode, _BYTES _BYTES _I32 _I32 _I32);