Leaked source code of windows server 2003
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.

237 lines
8.4 KiB

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