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

///////////////////////////////////////////////////////////////////////////////
// Copyright (C) Microsoft Corporation, 1998.
//
// texmap.cpp
//
// Direct3D Reference Rasterizer - Texture Map Access Methods
//
///////////////////////////////////////////////////////////////////////////////
#include "pch.cpp"
#pragma hdrstop
inline UINT8 CLAMP_BYTE(double f)
{
if (f > 255.0) return 255;
if (f < 0.0) return 0;
return (BYTE) f;
}
//-----------------------------------------------------------------------------
// TexelFromBlock - decompress a color block and obtain texel color
//-----------------------------------------------------------------------------
UINT32 TexelFromBlock(RRSurfaceType surfType, char *pblockSrc,
int x, int y)
{
UINT32 index = ((y & 0x3)<<2) + (x & 0x3);
DDRGBA colorDst[DXT_BLOCK_PIXELS];
switch(surfType)
{
case RR_STYPE_DXT1:
DecodeBlockRGB((DXTBlockRGB *)pblockSrc, (DXT_COLOR *)colorDst);
break;
case RR_STYPE_DXT2:
case RR_STYPE_DXT3:
DecodeBlockAlpha4((DXTBlockAlpha4 *)pblockSrc,
(DXT_COLOR *)colorDst);
break;
case RR_STYPE_DXT4:
case RR_STYPE_DXT5:
DecodeBlockAlpha3((DXTBlockAlpha3 *)pblockSrc,
(DXT_COLOR *)colorDst);
break;
}
return RGBA_MAKE(colorDst[index].red,
colorDst[index].green,
colorDst[index].blue,
colorDst[index].alpha);
}
//-----------------------------------------------------------------------------
//
// ReadTexelColor - Reads texel from texture map at given LOD; converts to
// RRColor format, applying palette if necessary; also performs colorkey by
// zero-ing out alpha
//
//-----------------------------------------------------------------------------
void
RRTexture::ReadColor(
INT32 iX, INT32 iY, INT32 iLOD,
RRColor& Texel, BOOL &bColorKeyMatched )
{
if ( (iLOD > m_cLOD) && !(m_uFlags & RR_TEXTURE_ENVMAP) )
{
return;
}
if ( NULL == m_pTextureBits[iLOD] ) { return; }
char* pSurfaceBits =
PixelAddress( iX, iY, m_pTextureBits[iLOD], m_iPitch[iLOD], m_SurfType );
switch ( m_SurfType )
{
default:
Texel.ConvertFrom( m_SurfType, pSurfaceBits );
break;
case RR_STYPE_PALETTE8:
{
UINT8 uIndex = *((UINT8*)pSurfaceBits);
UINT32 uTexel = *( (UINT32*)(m_pPalette) + uIndex );
Texel = RGBA_MAKE(
(uTexel>> 0) & 0xff,
(uTexel>> 8) & 0xff,
(uTexel>>16) & 0xff,
(uTexel>>24) & 0xff);
if ( !( m_uFlags & RR_TEXTURE_ALPHAINPALETTE ) ) Texel.A = 1.f;
}
break;
case RR_STYPE_PALETTE4:
{
UINT8 uIndex = *((INT8*)pSurfaceBits);
if ((iX & 1) == 0) { uIndex &= 0xf; }
else { uIndex >>= 4; }
UINT32 uTexel = *( (UINT32*)(m_pPalette) + uIndex );
Texel = RGBA_MAKE(
(uTexel>> 0) & 0xff,
(uTexel>> 8) & 0xff,
(uTexel>>16) & 0xff,
(uTexel>>24) & 0xff);
if ( !( m_uFlags & RR_TEXTURE_ALPHAINPALETTE ) ) Texel.A = 1.f;
}
break;
case RR_STYPE_UYVY:
case RR_STYPE_YUY2:
// Converts a given YUV (8bits each) to RGB scaled between 0 and 255
// These are using the YCrCb to RGB algorithms given on page 30
// in "VIDEO DEMYSTIFIED" by Keith Jack
// ISBN#: 1-878707-09-4
// IN PC graphics, even though they call it YUV, it is really YCrCb
// formats that are used by most framegrabbers etc. Hence the pixel
// data we will obtain in these YUV surfaces will most likely be this
// and not the original YUV which is actually used in PAL broadcast
// only (NTSC uses YIQ). So really, U should be called Cb (Blue color
// difference) and V should be called Cr (Red color difference)
//
// These equations are meant to handle the following ranges
// (from the same book):
// Y (16 to 235), U and V (16 to 240, 128 = zero)
// -----------
// Y U V
// -----------
// White : 180 128 128
// Black : 16 128 128
// Red : 65 100 212
// Green : 112 72 58
// Blue : 35 212 114
// Yellow : 162 44 142
// Cyan : 131 156 44
// Magenta: 84 184 198
// -----------
// It is assumed that the gamma corrected RGB range is (0 - 255)
//
// UYVY: U0Y0 V0Y1 U2Y2 V2Y3 (low byte always has current Y)
// If iX is even, hight-byte has current U (Cb)
// If iX is odd, hight-byte has previous V (Cr)
//
// YUY2: Y0U0 Y1V0 Y2U2 Y3V2 (high byte always has current Y)
// (UYVY bytes flipped)
//
// In this algorithm, we use U and V values from two neighboring
// pixels
{
UINT8 Y, U, V;
UINT16 u16Curr = *((UINT16*)pSurfaceBits);
UINT16 u16ForU = 0; // Extract U from this
UINT16 u16ForV = 0; // Extract V from this
// By default we assume YUY2. Change it later if it is UYVY
int uvShift = 8;
int yShift = 0;
if (m_SurfType == RR_STYPE_UYVY)
{
uvShift = 0;
yShift = 8;
}
if ((iX & 1) == 0)
{
// Current U available
u16ForU = u16Curr;
// Obtain V from the next pixel
if ( (iX < (m_iWidth >> iLOD)) || (m_uFlags & RR_TEXTURE_ENVMAP) )
{
u16ForV = *((UINT16*)PixelAddress( iX+1, iY,
m_pTextureBits[iLOD],
m_iPitch[iLOD],
m_SurfType ));
}
else
{
// This case should not be hit because the texture
// width is even (actually, a power of two)
_ASSERTa(0, "iX exceeds width", u16ForV = u16Curr;)
}
}
else
{
// Current V available
u16ForV = u16Curr;
// Obtain U from the previous pixel
if (iX > 0)
{
u16ForU = *((UINT16*)PixelAddress( iX-1, iY,
m_pTextureBits[iLOD],
m_iPitch[iLOD],
m_SurfType ));
}
else
{
// This case should not be hit because the texture
// width is even (actually, a power of two)
_ASSERTa(0, "iX is negative", u16ForU = u16Curr;)
}
}
Y = (u16Curr >> yShift) & 0xff;
U = (u16ForU >> uvShift) & 0xff;
V = (u16ForV >> uvShift) & 0xff;
Texel = RGB_MAKE(
CLAMP_BYTE(1.164*(Y-16) + 1.596*(V-128)),
CLAMP_BYTE(1.164*(Y-16) - 0.813*(V-128) - 0.391*(U-128)),
CLAMP_BYTE(1.164*(Y-16) + 2.018*(U-128))
);
Texel.A = 1.f;
}
break;
// S3 compressed formats:
// We have the address to the block, now extract the actual color
case RR_STYPE_DXT1:
case RR_STYPE_DXT2:
case RR_STYPE_DXT3:
case RR_STYPE_DXT4:
case RR_STYPE_DXT5:
Texel = TexelFromBlock(m_SurfType, pSurfaceBits, iX, iY);
break;
}
// colorkey (only supported for legacy behavior)
if ( m_bDoColorKeyKill || m_bDoColorKeyZero )
{
DWORD dwBits;
switch ( m_SurfType )
{
default:
case RR_STYPE_NULL:
return; // don't colorkey unknown or null surfaces
case RR_STYPE_PALETTE4:
{
UINT8 uIndex = *((INT8*)pSurfaceBits);
if ((iX & 1) == 0) { uIndex &= 0xf; }
else { uIndex >>= 4; }
dwBits = (DWORD)uIndex;
}
break;
case RR_STYPE_L8:
case RR_STYPE_PALETTE8:
case RR_STYPE_B2G3R3:
case RR_STYPE_L4A4:
{
UINT8 uBits = *((UINT8*)pSurfaceBits);
dwBits = (DWORD)uBits;
}
break;
case RR_STYPE_B5G6R5:
case RR_STYPE_B5G5R5:
case RR_STYPE_B5G5R5A1:
case RR_STYPE_B4G4R4A4:
case RR_STYPE_L8A8:
case RR_STYPE_B2G3R3A8:
{
UINT16 uBits = *((UINT16*)pSurfaceBits);
dwBits = (DWORD)uBits;
}
break;
case RR_STYPE_B8G8R8:
{
UINT32 uBits = 0;
uBits |= ( *((UINT8*)pSurfaceBits+0) ) << 0;
uBits |= ( *((UINT8*)pSurfaceBits+1) ) << 8;
uBits |= ( *((UINT8*)pSurfaceBits+2) ) << 16;
dwBits = (DWORD)uBits;
}
break;
case RR_STYPE_B8G8R8A8:
case RR_STYPE_B8G8R8X8:
{
UINT32 uBits = *((UINT32*)pSurfaceBits);
dwBits = (DWORD)uBits;
}
break;
}
if ( dwBits == m_dwColorKey )
{
bColorKeyMatched = TRUE;
if (m_bDoColorKeyZero)
{
Texel.A = 0.F;
Texel.R = 0.F;
Texel.G = 0.F;
Texel.B = 0.F;
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
// end