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.

302 lines
10 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) Microsoft Corporation, 1998.
  3. //
  4. // texmap.cpp
  5. //
  6. // Direct3D Reference Rasterizer - Texture Map Access Methods
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #include "pch.cpp"
  10. #pragma hdrstop
  11. inline UINT8 CLAMP_BYTE(double f)
  12. {
  13. if (f > 255.0) return 255;
  14. if (f < 0.0) return 0;
  15. return (BYTE) f;
  16. }
  17. //-----------------------------------------------------------------------------
  18. // TexelFromBlock - decompress a color block and obtain texel color
  19. //-----------------------------------------------------------------------------
  20. UINT32 TexelFromBlock(RRSurfaceType surfType, char *pblockSrc,
  21. int x, int y)
  22. {
  23. UINT32 index = ((y & 0x3)<<2) + (x & 0x3);
  24. DDRGBA colorDst[DXT_BLOCK_PIXELS];
  25. switch(surfType)
  26. {
  27. case RR_STYPE_DXT1:
  28. DecodeBlockRGB((DXTBlockRGB *)pblockSrc, (DXT_COLOR *)colorDst);
  29. break;
  30. case RR_STYPE_DXT2:
  31. case RR_STYPE_DXT3:
  32. DecodeBlockAlpha4((DXTBlockAlpha4 *)pblockSrc,
  33. (DXT_COLOR *)colorDst);
  34. break;
  35. case RR_STYPE_DXT4:
  36. case RR_STYPE_DXT5:
  37. DecodeBlockAlpha3((DXTBlockAlpha3 *)pblockSrc,
  38. (DXT_COLOR *)colorDst);
  39. break;
  40. }
  41. return RGBA_MAKE(colorDst[index].red,
  42. colorDst[index].green,
  43. colorDst[index].blue,
  44. colorDst[index].alpha);
  45. }
  46. //-----------------------------------------------------------------------------
  47. //
  48. // ReadTexelColor - Reads texel from texture map at given LOD; converts to
  49. // RRColor format, applying palette if necessary; also performs colorkey by
  50. // zero-ing out alpha
  51. //
  52. //-----------------------------------------------------------------------------
  53. void
  54. RRTexture::ReadColor(
  55. INT32 iX, INT32 iY, INT32 iLOD,
  56. RRColor& Texel, BOOL &bColorKeyMatched )
  57. {
  58. if ( (iLOD > m_cLOD) && !(m_uFlags & RR_TEXTURE_ENVMAP) )
  59. {
  60. return;
  61. }
  62. if ( NULL == m_pTextureBits[iLOD] ) { return; }
  63. char* pSurfaceBits =
  64. PixelAddress( iX, iY, m_pTextureBits[iLOD], m_iPitch[iLOD], m_SurfType );
  65. switch ( m_SurfType )
  66. {
  67. default:
  68. Texel.ConvertFrom( m_SurfType, pSurfaceBits );
  69. break;
  70. case RR_STYPE_PALETTE8:
  71. {
  72. UINT8 uIndex = *((UINT8*)pSurfaceBits);
  73. UINT32 uTexel = *( (UINT32*)(m_pPalette) + uIndex );
  74. Texel = RGBA_MAKE(
  75. (uTexel>> 0) & 0xff,
  76. (uTexel>> 8) & 0xff,
  77. (uTexel>>16) & 0xff,
  78. (uTexel>>24) & 0xff);
  79. if ( !( m_uFlags & RR_TEXTURE_ALPHAINPALETTE ) ) Texel.A = 1.f;
  80. }
  81. break;
  82. case RR_STYPE_PALETTE4:
  83. {
  84. UINT8 uIndex = *((INT8*)pSurfaceBits);
  85. if ((iX & 1) == 0) { uIndex &= 0xf; }
  86. else { uIndex >>= 4; }
  87. UINT32 uTexel = *( (UINT32*)(m_pPalette) + uIndex );
  88. Texel = RGBA_MAKE(
  89. (uTexel>> 0) & 0xff,
  90. (uTexel>> 8) & 0xff,
  91. (uTexel>>16) & 0xff,
  92. (uTexel>>24) & 0xff);
  93. if ( !( m_uFlags & RR_TEXTURE_ALPHAINPALETTE ) ) Texel.A = 1.f;
  94. }
  95. break;
  96. case RR_STYPE_UYVY:
  97. case RR_STYPE_YUY2:
  98. // Converts a given YUV (8bits each) to RGB scaled between 0 and 255
  99. // These are using the YCrCb to RGB algorithms given on page 30
  100. // in "VIDEO DEMYSTIFIED" by Keith Jack
  101. // ISBN#: 1-878707-09-4
  102. // IN PC graphics, even though they call it YUV, it is really YCrCb
  103. // formats that are used by most framegrabbers etc. Hence the pixel
  104. // data we will obtain in these YUV surfaces will most likely be this
  105. // and not the original YUV which is actually used in PAL broadcast
  106. // only (NTSC uses YIQ). So really, U should be called Cb (Blue color
  107. // difference) and V should be called Cr (Red color difference)
  108. //
  109. // These equations are meant to handle the following ranges
  110. // (from the same book):
  111. // Y (16 to 235), U and V (16 to 240, 128 = zero)
  112. // -----------
  113. // Y U V
  114. // -----------
  115. // White : 180 128 128
  116. // Black : 16 128 128
  117. // Red : 65 100 212
  118. // Green : 112 72 58
  119. // Blue : 35 212 114
  120. // Yellow : 162 44 142
  121. // Cyan : 131 156 44
  122. // Magenta: 84 184 198
  123. // -----------
  124. // It is assumed that the gamma corrected RGB range is (0 - 255)
  125. //
  126. // UYVY: U0Y0 V0Y1 U2Y2 V2Y3 (low byte always has current Y)
  127. // If iX is even, hight-byte has current U (Cb)
  128. // If iX is odd, hight-byte has previous V (Cr)
  129. //
  130. // YUY2: Y0U0 Y1V0 Y2U2 Y3V2 (high byte always has current Y)
  131. // (UYVY bytes flipped)
  132. //
  133. // In this algorithm, we use U and V values from two neighboring
  134. // pixels
  135. {
  136. UINT8 Y, U, V;
  137. UINT16 u16Curr = *((UINT16*)pSurfaceBits);
  138. UINT16 u16ForU = 0; // Extract U from this
  139. UINT16 u16ForV = 0; // Extract V from this
  140. // By default we assume YUY2. Change it later if it is UYVY
  141. int uvShift = 8;
  142. int yShift = 0;
  143. if (m_SurfType == RR_STYPE_UYVY)
  144. {
  145. uvShift = 0;
  146. yShift = 8;
  147. }
  148. if ((iX & 1) == 0)
  149. {
  150. // Current U available
  151. u16ForU = u16Curr;
  152. // Obtain V from the next pixel
  153. if ( (iX < (m_iWidth >> iLOD)) || (m_uFlags & RR_TEXTURE_ENVMAP) )
  154. {
  155. u16ForV = *((UINT16*)PixelAddress( iX+1, iY,
  156. m_pTextureBits[iLOD],
  157. m_iPitch[iLOD],
  158. m_SurfType ));
  159. }
  160. else
  161. {
  162. // This case should not be hit because the texture
  163. // width is even (actually, a power of two)
  164. _ASSERTa(0, "iX exceeds width", u16ForV = u16Curr;)
  165. }
  166. }
  167. else
  168. {
  169. // Current V available
  170. u16ForV = u16Curr;
  171. // Obtain U from the previous pixel
  172. if (iX > 0)
  173. {
  174. u16ForU = *((UINT16*)PixelAddress( iX-1, iY,
  175. m_pTextureBits[iLOD],
  176. m_iPitch[iLOD],
  177. m_SurfType ));
  178. }
  179. else
  180. {
  181. // This case should not be hit because the texture
  182. // width is even (actually, a power of two)
  183. _ASSERTa(0, "iX is negative", u16ForU = u16Curr;)
  184. }
  185. }
  186. Y = (u16Curr >> yShift) & 0xff;
  187. U = (u16ForU >> uvShift) & 0xff;
  188. V = (u16ForV >> uvShift) & 0xff;
  189. Texel = RGB_MAKE(
  190. CLAMP_BYTE(1.164*(Y-16) + 1.596*(V-128)),
  191. CLAMP_BYTE(1.164*(Y-16) - 0.813*(V-128) - 0.391*(U-128)),
  192. CLAMP_BYTE(1.164*(Y-16) + 2.018*(U-128))
  193. );
  194. Texel.A = 1.f;
  195. }
  196. break;
  197. // S3 compressed formats:
  198. // We have the address to the block, now extract the actual color
  199. case RR_STYPE_DXT1:
  200. case RR_STYPE_DXT2:
  201. case RR_STYPE_DXT3:
  202. case RR_STYPE_DXT4:
  203. case RR_STYPE_DXT5:
  204. Texel = TexelFromBlock(m_SurfType, pSurfaceBits, iX, iY);
  205. break;
  206. }
  207. // colorkey (only supported for legacy behavior)
  208. if ( m_bDoColorKeyKill || m_bDoColorKeyZero )
  209. {
  210. DWORD dwBits;
  211. switch ( m_SurfType )
  212. {
  213. default:
  214. case RR_STYPE_NULL:
  215. return; // don't colorkey unknown or null surfaces
  216. case RR_STYPE_PALETTE4:
  217. {
  218. UINT8 uIndex = *((INT8*)pSurfaceBits);
  219. if ((iX & 1) == 0) { uIndex &= 0xf; }
  220. else { uIndex >>= 4; }
  221. dwBits = (DWORD)uIndex;
  222. }
  223. break;
  224. case RR_STYPE_L8:
  225. case RR_STYPE_PALETTE8:
  226. case RR_STYPE_B2G3R3:
  227. case RR_STYPE_L4A4:
  228. {
  229. UINT8 uBits = *((UINT8*)pSurfaceBits);
  230. dwBits = (DWORD)uBits;
  231. }
  232. break;
  233. case RR_STYPE_B5G6R5:
  234. case RR_STYPE_B5G5R5:
  235. case RR_STYPE_B5G5R5A1:
  236. case RR_STYPE_B4G4R4A4:
  237. case RR_STYPE_L8A8:
  238. case RR_STYPE_B2G3R3A8:
  239. {
  240. UINT16 uBits = *((UINT16*)pSurfaceBits);
  241. dwBits = (DWORD)uBits;
  242. }
  243. break;
  244. case RR_STYPE_B8G8R8:
  245. {
  246. UINT32 uBits = 0;
  247. uBits |= ( *((UINT8*)pSurfaceBits+0) ) << 0;
  248. uBits |= ( *((UINT8*)pSurfaceBits+1) ) << 8;
  249. uBits |= ( *((UINT8*)pSurfaceBits+2) ) << 16;
  250. dwBits = (DWORD)uBits;
  251. }
  252. break;
  253. case RR_STYPE_B8G8R8A8:
  254. case RR_STYPE_B8G8R8X8:
  255. {
  256. UINT32 uBits = *((UINT32*)pSurfaceBits);
  257. dwBits = (DWORD)uBits;
  258. }
  259. break;
  260. }
  261. if ( dwBits == m_dwColorKey )
  262. {
  263. bColorKeyMatched = TRUE;
  264. if (m_bDoColorKeyZero)
  265. {
  266. Texel.A = 0.F;
  267. Texel.R = 0.F;
  268. Texel.G = 0.F;
  269. Texel.B = 0.F;
  270. }
  271. }
  272. }
  273. }
  274. ///////////////////////////////////////////////////////////////////////////////
  275. // end