Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

254 lines
7.3 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) Microsoft Corporation, 1998.
  3. //
  4. // dxtn.cpp
  5. //
  6. // Direct3D Reference Rasterizer - DXTn texture compression functions
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #include "pch.cpp"
  10. // Primary color components (use DirextX byte ordering)
  11. #undef RED
  12. #define RED 0
  13. #undef GRN
  14. #define GRN 1
  15. #undef BLU
  16. #define BLU 2
  17. #undef ALFA
  18. #define ALFA 3
  19. typedef struct
  20. {
  21. float rgba[4];
  22. } FCOLOR; // internal color format
  23. //
  24. // Processing all primaries is such a common idiom
  25. // that we define a macro for this action.
  26. // Any self-respecting C compiler should easily optimize
  27. // this by unrolling the loop!
  28. //
  29. #define ForAllPrimaries for( primary = 0; primary < NUM_PRIMARIES; ++primary)
  30. // Similarly, processing all pixels in a block is a common idiom.
  31. #define ForAllPixels for(pixel=0; pixel < DXT_BLOCK_PIXELS; ++pixel)
  32. #define NUM_PRIMARIES 3
  33. #define NUM_COMPONENTS 4
  34. //
  35. // Quantization constants for RGB565
  36. //
  37. #define PRIMARY_BITS 8
  38. #define RED_BITS 5
  39. #define GRN_BITS 6
  40. #define BLU_BITS 5
  41. #define RED_SHIFT (PRIMARY_BITS-RED_BITS)
  42. #define GRN_SHIFT (PRIMARY_BITS-GRN_BITS)
  43. #define BLU_SHIFT (PRIMARY_BITS-BLU_BITS)
  44. #if 0
  45. #define RED_MASK 0xf8
  46. #define GRN_MASK 0xfc
  47. #define BLU_MASK 0xf8
  48. #endif
  49. // Weighting for each primary based on NTSC luminance
  50. static float wtPrimary[NUM_PRIMARIES] =
  51. {
  52. 0.0820f, // blue
  53. 0.6094f, // green
  54. 0.3086f // red
  55. };
  56. //-----------------------------------------------------------------------------
  57. //
  58. // unpack a fixed point color
  59. //
  60. //-----------------------------------------------------------------------------
  61. static void RGBToColor (RGB565 *prgb, DXT_COLOR *pcolor)
  62. {
  63. WORD rgb;
  64. DXT_COLOR color;
  65. rgb = *((WORD *)prgb);
  66. // pick off bits in groups of 5, 6, and 5
  67. color.rgba[BLU] = (unsigned char) rgb;
  68. rgb >>= BLU_BITS;
  69. color.rgba[GRN] = (unsigned char) rgb;
  70. rgb >>= GRN_BITS;
  71. color.rgba[RED] = (unsigned char) rgb;
  72. // shift primaries into the appropriate LSBs
  73. color.rgba[BLU] <<= BLU_SHIFT;
  74. color.rgba[GRN] <<= GRN_SHIFT;
  75. color.rgba[RED] <<= RED_SHIFT;
  76. // replicate primaries MSBs into LSBs
  77. color.rgba[BLU] |= color.rgba[BLU] >> BLU_BITS;
  78. color.rgba[GRN] |= color.rgba[GRN] >> GRN_BITS;
  79. color.rgba[RED] |= color.rgba[RED] >> RED_BITS;
  80. *pcolor = color;
  81. }
  82. //-----------------------------------------------------------------------------
  83. //
  84. // DecodeBlockRGB - decompress a color block
  85. //
  86. //-----------------------------------------------------------------------------
  87. void DecodeBlockRGB (DXTBlockRGB *pblockSrc, DXT_COLOR colorDst[DXT_BLOCK_PIXELS])
  88. {
  89. int lev;
  90. DXT_COLOR clut[4];
  91. PIXBM pixbm;
  92. int pixel;
  93. int primary;
  94. // if source block is invalid, ...
  95. if (pblockSrc == NULL)
  96. return;
  97. // determine the number of color levels in the block
  98. lev = (pblockSrc->rgb0 <= pblockSrc->rgb1) ? 2 : 3;
  99. // Fill extrema values into pixel code lookup table.
  100. RGBToColor(&pblockSrc->rgb0, &clut[0]);
  101. RGBToColor(&pblockSrc->rgb1, &clut[1]);
  102. clut[0].rgba[ALFA] =
  103. clut[1].rgba[ALFA] =
  104. clut[2].rgba[ALFA] = 255;
  105. if (lev == 3)
  106. { // No transparency info present, all color info.
  107. ForAllPrimaries
  108. {
  109. WORD temp0 = clut[0].rgba[primary]; // jvanaken fixed overflow bug
  110. WORD temp1 = clut[1].rgba[primary];
  111. clut[2].rgba[primary] = (BYTE)((2*temp0 + temp1 + 1)/3);
  112. clut[3].rgba[primary] = (BYTE)((temp0 + 2*temp1 + 1)/3);
  113. }
  114. clut[3].rgba[ALFA] = 255;
  115. }
  116. else
  117. { // transparency info.
  118. ForAllPrimaries
  119. {
  120. WORD temp0 = clut[0].rgba[primary]; // jvanaken fixed overflow bug
  121. WORD temp1 = clut[1].rgba[primary];
  122. clut[2].rgba[primary] = (BYTE)((temp0 + temp1)/2);
  123. clut[3].rgba[primary] = 0; // jvanaken added this
  124. }
  125. clut[3].rgba[ALFA] = 0;
  126. }
  127. // munge a local copy
  128. pixbm = pblockSrc->pixbm;
  129. // Look up the actual pixel color in the table.
  130. ForAllPixels
  131. {
  132. // lookup color from pixel bitmap
  133. ForAllPrimaries
  134. colorDst[pixel].rgba[primary] = clut[pixbm & 3].rgba[primary];
  135. colorDst[pixel].rgba[ALFA] = clut[pixbm & 3].rgba[ALFA];
  136. // prepare to extract next index
  137. pixbm >>= 2;
  138. }
  139. }
  140. //-----------------------------------------------------------------------------
  141. // DecodeBlockAlpha4 - decompress a block with alpha at 4 BPP
  142. //-----------------------------------------------------------------------------
  143. void DecodeBlockAlpha4(DXTBlockAlpha4 *pblockSrc, DXT_COLOR colorDst[DXT_BLOCK_PIXELS])
  144. {
  145. int row, col;
  146. WORD alpha;
  147. DecodeBlockRGB(&pblockSrc->rgb, colorDst);
  148. for (row = 0; row < 4; ++row)
  149. {
  150. alpha = pblockSrc->alphabm[row];
  151. for (col = 0; col < 4; ++col)
  152. {
  153. colorDst[4 * row + col].rgba[ALFA] =
  154. ((alpha & 0xf) << 4)
  155. | (alpha & 0xf);
  156. alpha >>= 4;
  157. }
  158. }
  159. }
  160. //-----------------------------------------------------------------------------
  161. //
  162. // DecodeBlockAlpha3 - decompress a block with alpha at 3 BPP
  163. //
  164. //-----------------------------------------------------------------------------
  165. void DecodeBlockAlpha3(DXTBlockAlpha3 *pblockSrc, DXT_COLOR colorDst[DXT_BLOCK_PIXELS])
  166. {
  167. int pixel;
  168. int alpha[8]; // alpha lookup table
  169. DWORD dwBM = 0; // alpha bitmap in DWORD cache
  170. DecodeBlockRGB(&pblockSrc->rgb, colorDst);
  171. alpha[0] = pblockSrc->alpha0;
  172. alpha[1] = pblockSrc->alpha1;
  173. if (alpha[0] > alpha[1]) // 8 alpha ramp
  174. { // interpolate intermediate colors
  175. alpha[2] = (6 * alpha[0] + 1 * alpha[1]) / 7;
  176. alpha[3] = (5 * alpha[0] + 2 * alpha[1]) / 7;
  177. alpha[4] = (4 * alpha[0] + 3 * alpha[1]) / 7;
  178. alpha[5] = (3 * alpha[0] + 4 * alpha[1]) / 7;
  179. alpha[6] = (2 * alpha[0] + 5 * alpha[1]) / 7;
  180. alpha[7] = (1 * alpha[0] + 6 * alpha[1]) / 7;
  181. }
  182. else // else 6 alpha ramp with 0 and 255
  183. { // interpolate intermediate colors
  184. alpha[2] = (4 * alpha[0] + 1 * alpha[1]) / 5;
  185. alpha[3] = (3 * alpha[0] + 2 * alpha[1]) / 5;
  186. alpha[4] = (2 * alpha[0] + 3 * alpha[1]) / 5;
  187. alpha[5] = (1 * alpha[0] + 4 * alpha[1]) / 5;
  188. alpha[6] = 0;
  189. alpha[7] = 255;
  190. }
  191. ForAllPixels
  192. { // reload bitmap dword cache every 8 pixels
  193. if ((pixel & 7) == 0)
  194. {
  195. if (pixel == 0)
  196. { // pack 3 bytes into dword
  197. dwBM = pblockSrc->alphabm[2];
  198. dwBM <<= 8;
  199. dwBM |= pblockSrc->alphabm[1];
  200. dwBM <<= 8;
  201. dwBM |= pblockSrc->alphabm[0];
  202. }
  203. else // pixel == 8
  204. { // pack 3 bytes into dword
  205. dwBM = pblockSrc->alphabm[5];
  206. dwBM <<= 8;
  207. dwBM |= pblockSrc->alphabm[4];
  208. dwBM <<= 8;
  209. dwBM |= pblockSrc->alphabm[3];
  210. }
  211. }
  212. // unpack bitmap dword 3 bits at a time
  213. colorDst[pixel].rgba[ALFA] = (BYTE)alpha[(dwBM & 7)];
  214. dwBM >>= 3;
  215. }
  216. }
  217. ///////////////////////////////////////////////////////////////////////////////
  218. // end