📄 swconvrt.cpp
字号:
/*
Copyright (c) 1995-2000 Microsoft Corporation. All rights reserved.
*/
#include "precomp.h"
#define NUMINTENSITYGROUPS (31 + 15 + 7 + 1) // (=54) Green, Red, Blue, black
#define NUMRECENTENTRIES 16
class LRU
{
unsigned long *m_aiUniq;
short *m_aiNewer;
short *m_aiOlder;
short m_nLRU;
short m_nMRU;
short m_nListSize;
public:
LRU();
Init( short listSize );
short Find( unsigned long iUniq ); // -1 == not found
short Add( unsigned long iUniq ); // returns index chosen
void Fill( unsigned long value );
void Free();
// ~LRU();
};
class MaskInfo
{
public:
unsigned long m_aMask[3]; // entry #0:r, #1:g, #2:b
unsigned char m_anShift[3]; // To align top bit with bit#31
unsigned short m_iType;
void InitMaskInfo(
XLATEOBJ *pxo,
unsigned long ColorSource, // XO_DESTPALETTE etc
unsigned short ColorType );
};
// static unsigned long (ColorConverter::*m_afpConvertFunction[])(unsigned long);
class MaskColorConverter : public ColorConverter
{
protected:
MaskInfo m_Src; // Source bitmasks
MaskInfo m_Dst; // Dest bitmasks
public:
unsigned long RGBToFromBGR( unsigned long rgbSrc );
unsigned long MaskedSrcToRGB( unsigned long maskedSrc );
unsigned long MaskedSrcToBGR( unsigned long maskedSrc );
unsigned long RGBSrcToMaskedDst( unsigned long rgbSrc );
unsigned long BGRSrcToMaskedDst( unsigned long bgrSrc );
unsigned long MaskedSrcToMaskedDst( unsigned long maskedSrc );
void Init( XLATEOBJ *pxo );
};
class GroupColorConverter : public ColorConverter
{
unsigned long m_aRecentResult[NUMRECENTENTRIES];
LRU m_LRURecent;
short m_piDstNext[256]; // Chain of entries of similar intensity
short m_aiIntensityHead[NUMINTENSITYGROUPS+1]; // last == -1
unsigned short m_nLowestGroup; // Index of first valid entry in m_aiIntensityHead[]
unsigned short m_nHighestGroup;// Index of first -1 in m_aiIntensityHead[]
unsigned long m_pPalette[256];// Destination palette
unsigned short m_nPaletteSize; // Destination palette size ( <= 256 )
MaskInfo m_Src; // Source bitmasks
public:
unsigned long RGBToFromBGR( unsigned long rgbSrc );
unsigned long MaskedSrcToRGB( unsigned long maskedSrc );
unsigned long MaskedSrcToPaletteDst( unsigned long maskedSrc );
int InitLRU();
void FreeLRU();
void Init( XLATEOBJ *pxo );
};
class MonoColorConverter : public ColorConverter
{
unsigned long m_BackgroundColor;
public:
unsigned long AnyToMono( unsigned long srcValue );
void Init( unsigned long color )
{
m_BackgroundColor = color;
}
};
class LookupColorConverter : public ColorConverter
{
MaskInfo m_Dst; // Dest bitmasks
unsigned long m_aLookup[256];
public:
unsigned long RGBSrcToMaskedDst( unsigned long rgbSrc );
void Init( XLATEOBJ *pxo );
unsigned long * LookupTable() { return m_aLookup; }
};
#define MASK_LRU_SIZE 10
#define GROUP_LRU_SIZE 2
#define MONO_LRU_SIZE 10
#define LOOKUP_LRU_SIZE 4
LRU gMaskedLRU;
LRU gGroupLRU;
LRU gMonoLRU;
LRU gLookupLRU;
MaskColorConverter gMaskedConverter[MASK_LRU_SIZE];
GroupColorConverter gGroupConverter[GROUP_LRU_SIZE];
MonoColorConverter gMonoConverter[MONO_LRU_SIZE];
LookupColorConverter gLookupConverter[LOOKUP_LRU_SIZE];
// If AllocConverters fails, this returns 0. No free's are done as the driver is going
// to exit anyway.
int AllocConverters()
{
int i;
if( !gMaskedLRU.Init(MASK_LRU_SIZE) ||
!gGroupLRU.Init(GROUP_LRU_SIZE) ||
!gMonoLRU.Init(MONO_LRU_SIZE) ||
!gLookupLRU.Init(LOOKUP_LRU_SIZE) )
return 0;
for( i=0; i<GROUP_LRU_SIZE; i++ )
if( !gGroupConverter[i].InitLRU() )
return 0;
return 1;
}
void FreeConverters()
{
int i;
gMaskedLRU.Free();
gGroupLRU.Free();
gMonoLRU.Free();
gLookupLRU.Free();
for( i=0; i<GROUP_LRU_SIZE; i++ )
gGroupConverter[i].FreeLRU();
}
int GroupColorConverter::InitLRU()
{
return m_LRURecent.Init(NUMRECENTENTRIES);
}
void GroupColorConverter::FreeLRU()
{
m_LRURecent.Free();
}
LRU::LRU()
{
m_aiUniq = (unsigned long *)NULL;
m_aiNewer = (short *)NULL;
m_aiOlder = (short *)NULL;
}
int LRU::Init( short listSize )
{
int i;
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("LRU::LRU( list size = %d )\r\n"),listSize ));
m_aiUniq = (unsigned long *)malloc( listSize * sizeof(unsigned long) );
m_aiNewer = (short *)malloc( listSize * sizeof(unsigned short) );
m_aiOlder = (short *)malloc( listSize * sizeof(unsigned short) );
if( !m_aiUniq || !m_aiNewer || !m_aiOlder )
return 0; // see AllocConverters
m_nListSize = listSize;
for( i=0; i<m_nListSize; i++ )
{
m_aiUniq[i] = 0;
m_aiNewer[i] = i-1; // Note that m_aiNewer[m_nMRU] is "undefined"
m_aiOlder[i] = i+1; // Note that m_aiOlder[m_nLRU] is "undefined"
}
m_nMRU = 0;
m_nLRU = m_nListSize-1;
return 1;
}
short LRU::Find( unsigned long iUniq ) // -1 == not found
{
int i;
for( i=0; i<m_nListSize; i++ )
{
if( m_aiUniq[i] == iUniq )
{
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("LRU 0x%08x Find 0x%08x: found at location %d\r\n"),
this, iUniq, i ));
// Now we pop this to the most recently used:
if( i == m_nLRU )
{
m_nLRU = m_aiNewer[i];
m_aiNewer[m_nMRU] = i;
m_aiOlder[i] = m_nMRU;
m_nMRU = i;
}
else if ( i != m_nMRU )
{
m_aiNewer[m_aiOlder[i]] = m_aiNewer[i];
m_aiOlder[m_aiNewer[i]] = m_aiOlder[i];
m_aiNewer[m_nMRU] = i;
m_aiOlder[i] = m_nMRU;
m_nMRU = i;
}
return i;
}
}
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("LRU 0x%08x Find 0x%08x: Not found!\r\n"),
this, iUniq ));
return -1;
}
short LRU::Add( unsigned long iUniq ) // returns index chosen
{
m_aiNewer[m_nMRU] = m_nLRU;
m_aiOlder[m_nLRU] = m_nMRU;
m_nMRU = m_nLRU;
m_nLRU = m_aiNewer[m_nLRU];
m_aiUniq[m_nMRU] = iUniq;
return m_nMRU;
}
void LRU::Fill( unsigned long value )
{
int i;
for( i=0; i<m_nListSize; i++ )
m_aiUniq[i] = value;
}
// Not needed so long as DrvDisablePDEV gets called when this driver gets unloaded.
//LRU::~LRU()
//{
// Free();
//}
void LRU::Free()
{
if( m_aiUniq )
{
free( (void *)m_aiUniq );
m_aiUniq = (unsigned long *)NULL;
}
if( m_aiNewer )
{
free( (void *)m_aiNewer );
m_aiNewer = (short *)NULL;
}
if( m_aiOlder )
{
free( (void *)m_aiOlder );
m_aiOlder = (short *)NULL;
}
}
//typedef struct _XLATEOBJ {
// ULONG iUniq;
// FLONG flXlate;
// USHORT iSrcType;
// USHORT iDstType;
// ULONG cEntries;
// ULONG *pulXlate;
//} XLATEOBJ;
unsigned long SwapRedBlue( unsigned long srcValue )
{
unsigned long dstValue = srcValue;
((unsigned char *)(&dstValue))[0] = ((unsigned char *)(&srcValue))[2];
((unsigned char *)(&dstValue))[2] = ((unsigned char *)(&srcValue))[0];
return dstValue;
}
//#define XO_TRIVIAL 1
//#define XO_TABLE 2
//#define XO_TO_MONO 4
//
//#define PAL_INDEXED 1
//#define PAL_BITFIELDS 2
//#define PAL_RGB 4
//#define PAL_BGR 8
//
//#define XO_SRCPALETTE 1
//#define XO_DESTPALETTE 2
//#define XO_DESTDCPALETTE 3
void MaskInfo::InitMaskInfo(
XLATEOBJ *pxo,
unsigned long colorSource, // XO_DESTPALETTE etc
unsigned short colorType ) // PAL_INDEXED etc
{
unsigned long mask;
int topBit;
m_iType = colorType;
if( m_iType == PAL_BITFIELDS )
{
unsigned char component;
XLATEOBJ_cGetPalette( pxo, colorSource, 3, m_aMask );
for( component=0; component<3; component++ )
{
mask = m_aMask[component];
for( topBit=0; mask; topBit++ )
mask>>=1;
m_anShift[component] = 32-topBit;
}
}
}
#define FNTYPE (unsigned long (ColorConverter::*)(unsigned long))
unsigned long (ColorConverter::* const m_afpConvertFunction[])(unsigned long) =
// unsigned long (ColorConverter::*ColorConverter::m_afpConvertFunction[])(unsigned long) =
{
// (unsigned long (ColorConverter::*)(unsigned long)) NULL, // Indexed -> indexed
// (unsigned long (ColorConverter::*)(unsigned long)) NULL, // Indexed -> bitfield
// (unsigned long (ColorConverter::*)(unsigned long)) NULL, // Indexed -> rgb
// (unsigned long (ColorConverter::*)(unsigned long)) NULL, // Indexed -> bgr
FNTYPE GroupColorConverter::MaskedSrcToPaletteDst, // bitfield -> indexed
FNTYPE MaskColorConverter::MaskedSrcToMaskedDst, // bitfield -> bitfield
FNTYPE MaskColorConverter::MaskedSrcToRGB, // bitfield -> rgb
FNTYPE MaskColorConverter::MaskedSrcToBGR, // bitfield -> bgr
FNTYPE GroupColorConverter::MaskedSrcToPaletteDst, // rgb -> indexed
FNTYPE MaskColorConverter::RGBSrcToMaskedDst, // rgb -> bitfield
FNTYPE NULL, // rgb -> rgb
FNTYPE MaskColorConverter::RGBToFromBGR, // rgb -> bgr
FNTYPE GroupColorConverter::MaskedSrcToPaletteDst, // bgr -> indexed
FNTYPE MaskColorConverter::BGRSrcToMaskedDst, // bgr -> bitfield
FNTYPE MaskColorConverter::RGBToFromBGR, // bgr -> rgb
FNTYPE NULL // bgr -> bgr
};
static unsigned char log2nOver2[] = { 0, 1, 2, 2, 3 };
unsigned long RGBError(
unsigned long v1,
unsigned long v2 )
{
unsigned char *p1 = (unsigned char *)&v1;
unsigned char *p2 = (unsigned char *)&v2;
long accum = *p1++ - *p2++;
accum *= accum;
long diff = *p1++ - *p2++;
accum += diff * diff;
diff = *p1++ - *p2++;
return accum + diff * diff;
}
short RGBToGroup( unsigned long rgbValue )
{
// From 0x00bbggrr format
return (short)(
((rgbValue>>(24-3))&7)+ // 3 bits blue
((rgbValue>>(16-5))&31)+ // 5 bits green
((rgbValue>>(8-4))&15)); // 4 bits red
}
void ColorConverter::InitConverter(
XLATEOBJ *pxo,
ColorConverter **ppConvertObj,
unsigned long (ColorConverter::**ppConvertFn)(unsigned long),
unsigned long **ppLookup )
{
// m_iUniq = pxo->iUniq;
*ppConvertObj = (ColorConverter *)NULL;
*ppLookup = (unsigned long *)NULL;
*ppConvertFn = NULL;
short converterIndex;
if( pxo->flXlate == XO_TRIVIAL )
{
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("XO_TRIVIAL\r\n")));
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -