📄 swconvrt.cpp
字号:
} else if( pxo->flXlate == XO_TABLE ) { DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("XO_TABLE\r\n"))); *ppLookup = pxo->pulXlate; } else if( pxo->flXlate == XO_TO_MONO ) { DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("XO_TO_MONO\r\n"))); // we could optionally create a lookup table if the source is PAL_INDEXED // for faster access unsigned long backgroundColor = pxo->pulXlate[0]; if( ( converterIndex = gMonoLRU.Find( backgroundColor ) ) == -1 ) { converterIndex = gMonoLRU.Add( backgroundColor ); } gMonoConverter[converterIndex].Init(backgroundColor); *ppConvertObj = &gMonoConverter[converterIndex]; *ppConvertFn = FNTYPE MonoColorConverter::AnyToMono; } else if( pxo->iSrcType == PAL_INDEXED ) { DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("PAL_INDEXED->\r\n"))); if( ( converterIndex = gLookupLRU.Find( pxo->iUniq ) ) == -1 ) { // there is no cached converter for this iUniq converterIndex = gLookupLRU.Add( pxo->iUniq ); gLookupConverter[converterIndex].Init( pxo ); } *ppLookup = gLookupConverter[converterIndex].LookupTable(); } else if( pxo->iDstType == PAL_INDEXED ) { DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("->PAL_INDEXED\r\n"))); if( ( converterIndex = gGroupLRU.Find( pxo->iUniq ) ) == -1 ) { // there is no cached converter for this iUniq converterIndex = gGroupLRU.Add( pxo->iUniq ); gGroupConverter[converterIndex].Init( pxo ); } *ppConvertObj = &gGroupConverter[converterIndex]; *ppConvertFn = FNTYPE GroupColorConverter::MaskedSrcToPaletteDst; } else { // It is masked,rgb, or bgr --> masked,rgb, or bgr // Look up the converter function based on the src & dst color types DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("mask/rgb <-> mask/rgb\r\n"))); *ppConvertFn = m_afpConvertFunction[ log2nOver2[pxo->iSrcType/2]*4+log2nOver2[pxo->iDstType/2] - 4]; if( ( pxo->iSrcType | pxo->iDstType ) & PAL_BITFIELDS ) { // for bitfields (i.e. masked), there is some storage required... if( ( converterIndex = gMaskedLRU.Find( pxo->iUniq ) ) == -1 ) { // there is no cached converter for this iUniq converterIndex = gMaskedLRU.Add( pxo->iUniq ); gMaskedConverter[converterIndex].Init( pxo ); } *ppConvertObj = &gMaskedConverter[converterIndex]; } }}void MaskColorConverter::Init( XLATEOBJ *pxo ){ DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("Mask Init\r\n"))); m_Src.InitMaskInfo( pxo, XO_SRCPALETTE, pxo->iSrcType ); m_Dst.InitMaskInfo( pxo, XO_DESTPALETTE, pxo->iDstType );}void GroupColorConverter::Init( XLATEOBJ *pxo ){ // Create an intensity-grouped table short group; short lastHead; short i; DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("Group Init\r\n"))); m_Src.InitMaskInfo( pxo, XO_SRCPALETTE, pxo->iSrcType ); // Read in destination palette unsigned short m_nPaletteSize = (unsigned short)XLATEOBJ_cGetPalette(pxo,XO_DESTPALETTE,0,(unsigned long *)NULL); if( m_nPaletteSize > 256 ) m_nPaletteSize = 256; XLATEOBJ_cGetPalette(pxo,XO_DESTPALETTE,m_nPaletteSize,m_pPalette); m_nHighestGroup = 0; m_nLowestGroup = 0x0100; // Create chains of entries for each intensity group for( group=0; group<=NUMINTENSITYGROUPS; group++ ) m_aiIntensityHead[group] = -1; for( i=0; i<m_nPaletteSize; i++ ) { group = RGBToGroup( m_pPalette[i] ); m_piDstNext[i] = m_aiIntensityHead[group]; m_aiIntensityHead[group] = i; if( group > m_nHighestGroup ) m_nHighestGroup = group; if( group < m_nLowestGroup ) m_nLowestGroup = group; } lastHead = m_aiIntensityHead[m_nHighestGroup]; m_nHighestGroup++; m_aiIntensityHead[m_nHighestGroup] = -1; for( group=m_nHighestGroup-2; group>=m_nLowestGroup; group-- ) { if( ( i = m_aiIntensityHead[group] ) == -1 ) m_aiIntensityHead[group] = lastHead; else { // Connect last entry in chain to first entry in next chain while( m_piDstNext[i] != -1 ) i = m_piDstNext[i]; m_piDstNext[i] = lastHead; lastHead = m_aiIntensityHead[group]; } } // Invalidate the recent entry cache m_LRURecent.Fill(0xffffffff);}void LookupColorConverter::Init( XLATEOBJ *pxo ){ unsigned short srcInd; unsigned long dstPalette[256]; // Used for palette -> palette, or palette -> masked // First, read in the source palette unsigned short srcPaletteSize = (unsigned short)XLATEOBJ_cGetPalette(pxo,XO_SRCPALETTE,0,(unsigned long *)NULL); if( srcPaletteSize > 256 ) srcPaletteSize = 256; XLATEOBJ_cGetPalette(pxo,XO_SRCPALETTE,srcPaletteSize,m_aLookup); if( pxo->iDstType == PAL_INDEXED ) { // Read in the dest palette DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("PAL_INDEXED->PAL_INDEXED\r\n"))); unsigned short dstPaletteSize = (unsigned short)XLATEOBJ_cGetPalette(pxo,XO_DESTPALETTE,0,(unsigned long *)NULL); if( dstPaletteSize > 256 ) dstPaletteSize = 256; XLATEOBJ_cGetPalette(pxo,XO_DESTPALETTE,dstPaletteSize,dstPalette); // Create a closest-match lookup table unsigned long *srcPtr; srcPtr = m_aLookup; for( srcInd=0; srcInd<srcPaletteSize; srcInd++ ) { *srcPtr = DrvRealizeColor( PAL_INDEXED, dstPaletteSize, dstPalette, *srcPtr ); srcPtr++; } } else { m_Dst.InitMaskInfo( pxo, XO_DESTPALETTE, pxo->iDstType ); DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("PAL_INDEXED->mask/rgb\r\n"))); // Populate a lookup table with an appropriately munged palette for( srcInd=0; srcInd < srcPaletteSize; srcInd++ ) { if( pxo->iDstType == PAL_BITFIELDS ) m_aLookup[srcInd] = RGBSrcToMaskedDst( m_aLookup[srcInd] ); if( pxo->iDstType == PAL_BGR ) m_aLookup[srcInd] = SwapRedBlue( m_aLookup[srcInd] ); } }}unsigned long GroupColorConverter::MaskedSrcToPaletteDst( unsigned long maskedSrc ){ short lruIndex; unsigned long dstValue; unsigned long srcRGB; short possibleDst; short lowGroup, highGroup; unsigned long error; unsigned long smallestError; if( ( lruIndex = m_LRURecent.Find(maskedSrc) ) == -1 ) { if( m_Src.m_iType == PAL_RGB ) srcRGB = maskedSrc; else if( m_Src.m_iType == PAL_BGR ) srcRGB = RGBToFromBGR( maskedSrc ); else srcRGB = MaskedSrcToRGB( maskedSrc ); // We need to find the closest lookup // Determine range of intensity groups to check highGroup = lowGroup = RGBToGroup( srcRGB ); lowGroup = (lowGroup<m_nLowestGroup+4)?m_nLowestGroup:lowGroup-4; highGroup = (highGroup>m_nHighestGroup-5)?m_nHighestGroup:highGroup+5; if( m_aiIntensityHead[lowGroup] == m_aiIntensityHead[highGroup] ) { // No palette entries in range (i.e. inept palette) - scan all entries lowGroup = m_nLowestGroup; highGroup = m_nHighestGroup; } smallestError=0x10000000; for( possibleDst = m_aiIntensityHead[lowGroup]; possibleDst != m_aiIntensityHead[highGroup]; possibleDst = m_piDstNext[possibleDst] ) { error = RGBError( srcRGB, m_pPalette[possibleDst] ); if( error < smallestError ) { smallestError = error; dstValue = (unsigned long)possibleDst; } } // add this conversion to the LRU lruIndex = m_LRURecent.Add(maskedSrc); m_aRecentResult[lruIndex] = dstValue; } else { // we've recently done the same conversion so we can look it up dstValue = m_aRecentResult[lruIndex]; } return dstValue;} unsigned long MaskColorConverter::RGBToFromBGR( unsigned long rgbSrc ){ return SwapRedBlue( rgbSrc );}unsigned long GroupColorConverter::RGBToFromBGR( unsigned long rgbSrc ){ return SwapRedBlue( rgbSrc );}unsigned long MaskColorConverter::MaskedSrcToRGB( unsigned long srcValue ){ return ( ( ( srcValue & m_Src.m_aMask[0] ) << m_Src.m_anShift[0] ) >> 24 ) | ( ( ( srcValue & m_Src.m_aMask[1] ) << m_Src.m_anShift[1] ) >> 16 ) | ( ( ( srcValue & m_Src.m_aMask[2] ) << m_Src.m_anShift[2] ) >> 8 );}unsigned long GroupColorConverter::MaskedSrcToRGB( unsigned long srcValue ){ return ( ( ( srcValue & m_Src.m_aMask[0] ) << m_Src.m_anShift[0] ) >> 24 ) | ( ( ( srcValue & m_Src.m_aMask[1] ) << m_Src.m_anShift[1] ) >> 16 ) | ( ( ( srcValue & m_Src.m_aMask[2] ) << m_Src.m_anShift[2] ) >> 8 );}unsigned long MaskColorConverter::MaskedSrcToBGR( unsigned long srcValue ){ return ( ( ( srcValue & m_Src.m_aMask[0] ) << m_Src.m_anShift[0] ) >> 8 ) | ( ( ( srcValue & m_Src.m_aMask[1] ) << m_Src.m_anShift[1] ) >> 16 ) | ( ( ( srcValue & m_Src.m_aMask[2] ) << m_Src.m_anShift[2] ) >> 24 );}unsigned long MaskColorConverter::RGBSrcToMaskedDst( unsigned long srcValue ){ return ((( srcValue << 24 ) >> m_Dst.m_anShift[0] ) & m_Dst.m_aMask[0] ) | ((( srcValue << 16 ) >> m_Dst.m_anShift[1] ) & m_Dst.m_aMask[1] ) | ((( srcValue << 8 ) >> m_Dst.m_anShift[2] ) & m_Dst.m_aMask[2] );}unsigned long LookupColorConverter::RGBSrcToMaskedDst( unsigned long srcValue ){ return ((( srcValue << 24 ) >> m_Dst.m_anShift[0] ) & m_Dst.m_aMask[0] ) | ((( srcValue << 16 ) >> m_Dst.m_anShift[1] ) & m_Dst.m_aMask[1] ) | ((( srcValue << 8 ) >> m_Dst.m_anShift[2] ) & m_Dst.m_aMask[2] );}unsigned long MaskColorConverter::BGRSrcToMaskedDst( unsigned long srcValue ){ return ((( srcValue << 8 ) >> m_Dst.m_anShift[0] ) & m_Dst.m_aMask[0] ) | ((( srcValue << 16 ) >> m_Dst.m_anShift[1] ) & m_Dst.m_aMask[1] ) | ((( srcValue << 24 ) >> m_Dst.m_anShift[2] ) & m_Dst.m_aMask[2] );}unsigned long MaskColorConverter::MaskedSrcToMaskedDst( unsigned long maskedSrc ){ return ( ( ( ( maskedSrc & m_Src.m_aMask[0] ) << m_Src.m_anShift[0] ) >> m_Dst.m_anShift[0] ) & m_Dst.m_aMask[0] ) | ( ( ( ( maskedSrc & m_Src.m_aMask[1] ) << m_Src.m_anShift[1] ) >> m_Dst.m_anShift[1] ) & m_Dst.m_aMask[1] ) | ( ( ( ( maskedSrc & m_Src.m_aMask[2] ) << m_Src.m_anShift[2] ) >> m_Dst.m_anShift[2] ) & m_Dst.m_aMask[2] );}unsigned long MonoColorConverter::AnyToMono( unsigned long srcValue ){ return ( srcValue == m_BackgroundColor ) ? 1 : 0;}ULONG APIENTRY DrvRealizeColor( USHORT iDstType, ULONG cEntries, ULONG *pPalette, ULONG rgbColor){ unsigned short palInd; unsigned long *palPtr; unsigned long dstValue; unsigned long smallestError; unsigned long error; unsigned long mask; char shiftRight; char shiftLeft; switch( iDstType ) { case PAL_INDEXED: smallestError = 0x7fffffff; // Set large value palPtr = pPalette; for( palInd=0; palInd < cEntries; palInd++ ) { error = RGBError( rgbColor, *palPtr++ ); if( error > smallestError ) continue; smallestError = error; dstValue = palInd; if( error == 0 ) // perfect match, no need to keep looking break; } return dstValue; case PAL_BITFIELDS: dstValue = 0; for( shiftLeft=24; (shiftLeft>=0)&&(cEntries--); shiftLeft-=8 ) { mask = *pPalette; for( shiftRight=32; mask; shiftRight-- ) mask>>=1; dstValue |= ( ( rgbColor << shiftLeft ) >> shiftRight ) & *pPalette++; } return dstValue; case PAL_BGR: return SwapRedBlue( rgbColor ); case PAL_RGB: return rgbColor; } return 0; // actually an illegal type was encountered}ULONG APIENTRY DrvUnrealizeColor( USHORT iSrcType, ULONG cEntries, ULONG *pPalette, ULONG iRealizedColor){ unsigned long dstValue; unsigned long mask; char shiftRight; char shiftLeft; switch( iSrcType ) { case PAL_INDEXED: return pPalette[iRealizedColor]; case PAL_BITFIELDS: dstValue = 0; for( shiftRight=24; (shiftRight>=0)&&(cEntries--); shiftRight-=8 ) { mask = *pPalette; for( shiftLeft=32; mask; shiftLeft-- ) mask>>=1; dstValue |= ( ( iRealizedColor & *pPalette++ ) << shiftLeft ) >> shiftRight; } return dstValue; case PAL_BGR: return SwapRedBlue(iRealizedColor); case PAL_RGB: return iRealizedColor; } return 0; // actually an illegal type was encountered}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -