⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swconvrt.cpp

📁 windows ce 3.00 嵌入式操作系统源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	}
	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 + -