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.
 
 
 
 
 
 

2223 lines
48 KiB

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
bmpcvt.cpp
Abstract:
Bitmap conversion object
Environment:
Windows Whistler
Revision History:
08/23/99
Created it.
--*/
#include "xlpdev.h"
#include "xldebug.h"
#include "pclxle.h"
#include "xlbmpcvt.h"
BPP
NumToBPP(
ULONG ulBPP)
/*++
Routine Description:
Converts Bits per pixel to BPP enum.
Arguments:
Bits per pixel.
Return Value:
BPP enum
Note:
BPP enum is defined in xlbmpcvt.h.
--*/
{
BPP Bpp;
switch (ulBPP)
{
case 1:
Bpp = e1bpp;
break;
case 4:
Bpp = e4bpp;
break;
case 8:
Bpp = e8bpp;
break;
case 16:
Bpp = e16bpp;
break;
case 24:
Bpp = e24bpp;
break;
case 32:
Bpp = e32bpp;
break;
}
return Bpp;
}
ULONG
UlBPPtoNum(
BPP Bpp)
/*++
Routine Description:
Converts BPP enum to bits per pixel.
Arguments:
BPP enum
Return Value:
Bits per pixel.
Note:
BPP enum is defined in xlbmpcvt.h.
--*/
{
ULONG ulRet;
switch (Bpp)
{
case e1bpp:
ulRet = 1;
break;
case e4bpp:
ulRet = 4;
break;
case e8bpp:
ulRet = 8;
break;
case e16bpp:
ulRet = 16;
break;
case e24bpp:
ulRet = 24;
break;
case e32bpp:
ulRet = 32;
break;
}
return ulRet;
}
//
// Constructor/Destructor
//
BMPConv::
BMPConv( VOID ):
/*++
Routine Description:
BMPConv constructor
Arguments:
Return Value:
Note:
Initializes values. There is no memory allocation.
--*/
m_flags(0),
m_dwOutputBuffSize(0),
m_dwRLEOutputBuffSize(0),
m_dwDRCOutputBuffSize(0),
m_OddPixelStart(eOddPixelZero),
m_FirstBit(eBitZero),
m_pxlo(NULL),
m_pubOutputBuff(NULL),
m_pubRLEOutputBuff(NULL),
m_pubDRCOutputBuff(NULL),
m_pubDRCPrevOutputBuff(NULL),
m_CMode(eNoCompression)
{
#if DBG
SetDbgLevel(DBG_WARNING);
#endif
XL_VERBOSE(("BMPConv: Ctor\n"));
}
BMPConv::
~BMPConv( VOID )
/*++
Routine Description:
BMPConv destructor
Arguments:
Return Value:
Note:
m_pubOutputBuff and m_pubRLEOutputBuff are allocaed ConvertBMP.
ConvertBMP is scaline base bitmap conversion function.
--*/
{
XL_VERBOSE(("BMPConv: Dtor\n"));
//
// DRCPrevOutputBuff and OutputBuff are contiguous.
if (m_pubOutputBuff)
MemFree(m_pubOutputBuff);
if (m_pubRLEOutputBuff)
MemFree(m_pubRLEOutputBuff);
if (m_pubDRCOutputBuff)
MemFree(m_pubDRCOutputBuff);
}
//
// Public functions
//
#if DBG
VOID
BMPConv::
SetDbgLevel(
DWORD dwLevel)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
m_dbglevel = dwLevel;
}
#endif
BOOL
BMPConv::
BSetInputBPP(
BPP InputBPP)
/*++
Routine Description:
Sets source bitmap BPP in BMPConv.
Arguments:
Source bitmap BPP enum (bits per pixel)
Return Value:
TRUE if succeeded.
Note:
--*/
{
XL_VERBOSE(("BMPConv: BSetInputBPP\n"));
m_flags |= BMPCONV_SET_INPUTBPP;
m_InputBPP = InputBPP;
return TRUE;
}
BOOL
BMPConv::
BSetOutputBPP(
BPP OutputBPP)
/*++
Routine Description:
Sets destination bimtap BPP in BMPConv.
Arguments:
Destination bitmap BPP enum
Return Value:
TRUE if succeeded.
Note:
--*/
{
XL_VERBOSE(("BMPConv: BSetOutputBPP\n"));
m_OutputBPP = OutputBPP;
return TRUE;
}
BOOL
BMPConv::
BSetOutputBMPFormat(
OutputFormat BitmapFormat)
/*++
Routine Description:
Sets output bitmap format (GrayScale/Palette/RGB/CMYK).
Arguments:
OutputFormat enum.
Return Value:
TRUE if succeeded.
Note:
--*/
{
XL_VERBOSE(("BMPConv: BSetOutputBMPFormat\n"));
m_OutputFormat = BitmapFormat;
return TRUE;
}
BOOL
BMPConv::
BSetCompressionType(
CompressMode CMode)
/*++
Routine Description:
Set compression type.
Arguments:
CompressMode {eNoCompression, eRLECompression, eDeltaRowCompression}
Return Value:
TRUE if it succeeded.
Note:
--*/
{
XL_VERBOSE(("BMPConv: BSetCompressionType.\n"));
m_CMode = CMode;
return TRUE;
}
CompressMode
BMPConv::
GetCompressionType(VOID)
/*++
Routine Description:
CompressMode
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("BMPConv: BGetRLEStatus\n"));
return m_CMode;
}
BOOL
BMPConv::
BSetXLATEOBJ(
XLATEOBJ *pxlo)
/*++
Routine Description:
Sets XLATEOBJ in BMPConv.
Arguments:
A pointer to XLATEOBJ.
Return Value:
Note:
--*/
{
XL_VERBOSE(("BMPConv: BSetXLATEOBJ\n"));
//
// XL_ERRor check
//
if (NULL == pxlo)
{
XL_ERR(("BMPConv::BSetXLATEOBJ: an invalid parameter.\n"));
return FALSE;
}
m_pxlo = pxlo;
m_flags |= DwCheckXlateObj(pxlo, m_InputBPP);
return TRUE;
}
PBYTE
BMPConv::
PubConvertBMP(
PBYTE pubSrc,
DWORD dwcbSrcSize)
/*++
Routine Description:
Scaline base bitmap conversion function.
Arguments:
pubSrc - a pointer to the source bitmap.
dwcbSrcSize - the size of the source bitmap.
Return Value:
A pointer to the destination bitmap.
Note:
The pointer to the destination bitmap is stored in BMPConv.
It is going to be freed in the BMPConv destructor.
--*/
{
DWORD dwcbDstSize, dwInputBPP;
LONG lWidth, lHeight;
PBYTE pubRet = NULL;
XL_VERBOSE(("BMPConv: BConvertBMP\n"));
//
// Calculate the number of pixels and the size of dest buffer
// Output data has to be DWORD aligned on PCL-XL.
//
dwInputBPP = UlBPPtoNum(m_InputBPP);
m_dwWidth = ((dwcbSrcSize << 3 ) + dwInputBPP - 1) / dwInputBPP;
dwcbDstSize = ((UlBPPtoNum(m_OutputBPP) * m_dwWidth + 31 ) >> 5 ) << 2;
//
// Allocate destination buffer
//
if (NULL == m_pubOutputBuff || NULL == m_pubDRCPrevOutputBuff)
{
//
// Allocate main and previous output buffer for DRC.
//
m_pubOutputBuff = (PBYTE)MemAlloc(dwcbDstSize * 2);
if (NULL == m_pubOutputBuff)
{
XL_ERR(("BMPConv::PubConvertBMP: m_pubOutputBuff[0x%x] allocation failed..\n", dwcbDstSize));
return NULL;
}
m_dwOutputBuffSize = dwcbDstSize;
//
// Zero init seed row.
// PCL XL exception about DRC.
// 1) the seed row is initialized to zeroes and contains the number
// of bytes defined by SourceWidth in the BeginImage operator.
//
m_pubDRCPrevOutputBuff = m_pubOutputBuff + dwcbDstSize;
m_dwDRCPrevOutputBuffSize = dwcbDstSize;
memset(m_pubDRCPrevOutputBuff, 0, m_dwDRCPrevOutputBuffSize);
}
//
// Allocate RLE destination buffer if RLE is on.
//
if (m_CMode == eRLECompression && NULL == m_pubRLEOutputBuff)
{
m_pubRLEOutputBuff = (PBYTE)MemAlloc(dwcbDstSize * 3);
m_dwRLEOutputBuffSize = dwcbDstSize * 3;
if (NULL == m_pubRLEOutputBuff)
{
XL_ERR(("BMPConv::PubConvertBMP: m_pubOutputBuff[0x%x] allocation failed..\n", dwcbDstSize));
MemFree(m_pubOutputBuff);
m_pubOutputBuff = NULL;
m_dwOutputBuffSize = 0;
m_pubDRCPrevOutputBuff = NULL;
m_dwDRCPrevOutputBuffSize = 0;
return NULL;
}
}
//
// Allocate DRC destination buffer if DRC is on.
//
if (m_CMode == eDeltaRowCompression && NULL == m_pubDRCOutputBuff)
{
m_pubDRCOutputBuff = (PBYTE)MemAlloc(dwcbDstSize * 3);
m_dwDRCOutputBuffSize = dwcbDstSize * 3;
if (NULL == m_pubDRCOutputBuff)
{
XL_ERR(("BMPConv::PubConvertBMP: m_pubOutputBuff[0x%x] allocation failed..\n", dwcbDstSize));
MemFree(m_pubOutputBuff);
m_pubOutputBuff = NULL;
m_pubDRCPrevOutputBuff = NULL;
MemFree(m_pubRLEOutputBuff);
m_pubRLEOutputBuff = NULL;
return NULL;
}
}
//
// Converrt source bitmap to destination.
// Source and Destination format is set by SetXXX functions.
//
if (BConversionProc(pubSrc, (dwcbSrcSize * 8 + dwInputBPP - 1) / dwInputBPP))
{
if (m_CMode == eRLECompression)
{
if (BCompressRLE())
pubRet = m_pubRLEOutputBuff;
else
pubRet = NULL;
}
else
if (m_CMode == eDeltaRowCompression)
{
if (BCompressDRC())
pubRet = m_pubDRCOutputBuff;
else
pubRet = NULL;
//
// Update seed row for DRC.
//
CopyMemory(m_pubDRCPrevOutputBuff, m_pubOutputBuff, m_dwDRCPrevOutputBuffSize);
}
else
pubRet = m_pubOutputBuff;
}
else
pubRet = NULL;
return pubRet;
}
BOOL
BMPConv::
BCompressRLE(
VOID)
/*++
Routine Description:
RLE compression function
Arguments:
Return Value:
TRUE if it succeeded.
Note:
--*/
{
DWORD dwSrcSize, dwDstSize, dwCount, dwErr, dwInputBPP, dwWidth;
PBYTE pubSrcBuff, pubDstBuff, pubLiteralNum;
BYTE ubCurrentData;
BOOL bLiteral;
XL_VERBOSE(("BMPConv: BCompressRLE\n"));
if ( NULL == m_pubRLEOutputBuff ||
NULL == m_pubOutputBuff )
return FALSE;
//
//
// PCL XL Run Length Encoding Compression Method (eRLECompression)
// The PCL XL RLE compression method employs control bytes followed by data
// bytes. Each
// control byte in the compressed data sequence is a signed, two's
// complement byte.
// If bit 7 of the control byte is zero (0 <= control byte <= 127) the bytes
// following are literal.
// Literal bytes are simply uncompressed data bytes. The number of literal
// bytes following a control
// byte is one plus the value of the control byte. Thus, a control byte of 0
// means 1 literal byte
// follows; a control byte of 6 means 7 literal bytes follow; and so on.
// If bit 7 of the control byte is 1 (-127 <= control byte <= -1), the byte
// following the control byte
// will occur two or more times as decompressed data. A byte following a
// control byte in this range
// is called a repeat byte. The control byte39s absolute value plus one is
// the number of times the byte
// following will occur in the decompressed sequence of bytes. For example,
// a control byte of -5
// means the subsequent byte will occur 6 times as decompressed data.
// A control byte of -128 is ignored and is not included in the decompressed
// data. The byte
// following a control byte of 128 is treated as the next control byte.
// It is more efficient to code two consecutive identical bytes as a
// repeated byte, unless these bytes
// are preceded and followed by literal bytes. Three-byte repeats should
// always be encoded using a
// repeat control byte.
//
// Literal byte <= 127
// Repeated byte <= 128
//
bLiteral = FALSE;
dwCount = 1;
dwSrcSize = m_dwOutputBuffSize;
pubSrcBuff = m_pubOutputBuff;
pubDstBuff = m_pubRLEOutputBuff;
m_dwRLEOutputDataSize = 0;
while (dwSrcSize > 0 && m_dwRLEOutputDataSize + 2 < m_dwRLEOutputBuffSize)
{
ubCurrentData = *pubSrcBuff++;
while (dwSrcSize > dwCount &&
ubCurrentData == *pubSrcBuff &&
dwCount < 128 )
{
dwCount++;
pubSrcBuff++;
}
if (dwCount > 1)
{
bLiteral = FALSE;
*pubDstBuff++ = 1-(char)dwCount;
*pubDstBuff++ = ubCurrentData;
m_dwRLEOutputDataSize += 2;
}
else
{
if (bLiteral)
{
(*pubLiteralNum) ++;
*pubDstBuff++ = ubCurrentData;
m_dwRLEOutputDataSize ++;
if (*pubLiteralNum == 127)
{
bLiteral = FALSE;
}
}
else
{
bLiteral = TRUE;
pubLiteralNum = pubDstBuff;
*pubDstBuff++ = 0;
*pubDstBuff++ = ubCurrentData;
m_dwRLEOutputDataSize += 2;
}
}
dwSrcSize -= dwCount;
dwCount = 1;
}
if (dwSrcSize == 0)
return TRUE;
else
return FALSE;
}
BOOL
BMPConv::
BCompressDRC(
VOID)
/*++
Routine Description:
This function is called to compress a scan line of data using
delta row compression.
Arguments:
Return Value:
Number of compressed bytes or -1 if too large for buffer
Note:
A return value of 0 is valid since it implies the two lines
are identical.
--*/
{
BYTE *pbI;
BYTE *pbO; /* Record output location */
BYTE *pbOEnd; /* As far as we will go in the output buffer */
BYTE *pbIEnd;
BYTE *pbStart;
BYTE *pb;
int iDelta;
int iOffset; // index of current data stream
int iSize; /* Number of bytes in the run */
int iSrcSize;
//
// The control byte has the following format:
// Number of delta bytes: Bits 5-7 indicate the number of consecutive
// replacement bytes that follow the commands byte. The actual number
// of of replacement bytes is always one more than the value
// (000 = 1, 111 = 8). If more than 8 delta bytes are needed,
// additional command byte/delta bytes are added.
// [ (Command Byte) (1-8 Delta Bytes) ]
// [ (Command Byte) (1-8 Delta Bytes) ] . . .
// Offset: Bits 0-4 show where to position the replacement byte string.
// This is the offset: it specifies a byte placement, counting from left
// to right from the current byte position. The current byte is the
// first unaltered byte that follows the last replacement bytes; at the
// beginning of a row, the current byte immediately follows the left
// raster margin. Bits 0-4 allow a maximum value of 31, but larger
// offsets are possible. A value of 0 to 30 indicates the delta bytes
// are offset from the 1st to the 31st bytes.
// A value of 31 indicates that an additional offset byte follows the
// command byte.
//
// To summarize, bits 0-4 have the following meaning:
// 0 to 30: the offset is 0 to 30.
// 31: the offset is 31 or greater. If the offset is 31, an additional
// offset byte follows the command byte. The offset in the command bytes
// is added to the offset bytes. If the offset byte is 0, the offset is
// 31; if the offset byte is 255 additional offset bytes follow.
// The last offset byte will have a value less than 255. All the offset
// bytes are added to the offset in the command byte to get the offset
// value. For example, if there are two offset bytes, and the last
// byte contains 175, the total offset would be: 31+255+175=461.
//
/*
* Limit the amount of data we will generate. For performance
* reasons we will ignore the effects of an offset value
* greater than 30 since it implies we were able to already skip
* that many bytes. However, for safety sake we will reduce the
* max allowable size by 2 bytes.
*/
XL_VERBOSE(("BMPConv: BCompressDRC\n"));
m_dwDRCOutputDataSize = 0;
if ( NULL == m_pubDRCOutputBuff ||
NULL == m_pubDRCPrevOutputBuff ||
NULL == m_pubOutputBuff )
return FALSE;
pbI = m_pubOutputBuff; /* Working copy */
iSrcSize = (UlBPPtoNum(m_OutputBPP) * m_dwWidth + 7) >> 3;
pbIEnd = m_pubOutputBuff + iSrcSize;
pbO = m_pubDRCOutputBuff; /* Working copy */
pbOEnd = m_pubDRCOutputBuff + m_dwDRCOutputBuffSize - 2;
//
// m_pubDRCPrevOutputBuff is continuously followed by m_putOutputBuff.
// Both has m_dwOutputBuffSize size of memory.
//
iDelta = (int)(m_pubDRCPrevOutputBuff - m_pubOutputBuff);
pbStart = m_pubOutputBuff;
//
// PCL XL exception.
// 2) the delta row is preceded by a 2-byte byte count which
// indicates the number of bytes to follow for the delta row.
// The byte count is expected to be in LSB MSB order.
//
*((PWORD)pbO) = 0x0000;
pbO += 2;
//
// this is the main loop for compressing the data
//
while (pbI < pbIEnd)
{
// fast skip for matching dwords
//
if (!((ULONG_PTR)pbI & 3))
{
while (pbI <= (pbIEnd-4) && *(DWORD *)pbI == *(DWORD *)&pbI[iDelta])
pbI += 4;
if (pbI >= pbIEnd)
break;
}
// test for non-matching bytes and output the necessary compression string
//
if (*pbI != pbI[iDelta])
{
// determine the run length
pb = pbI;
do {
pb++;
} while (pb < pbIEnd && *pb != pb[iDelta]);
iSize = (int)(pb - pbI);
// Lets make sure we have room in the buffer before
// we continue this, this compression algorithm adds
// 1 byte for every 8 bytes of data worst case.
//
if (((iSize * 9 + 7) >> 3) > (pbOEnd - pbO)) // gives tighter code
return FALSE;
iOffset = (int)(pbI - pbStart);
if (iOffset > 30)
{
if (iSize < 8)
*pbO++ = ((iSize-1) << 5) + 31;
else
*pbO++ = (7 << 5) + 31;
iOffset -= 31;
while (iOffset >= 255)
{
iOffset -= 255;
*pbO++ = 255;
}
*pbO++ = (BYTE)iOffset;
if (iSize > 8)
goto FastEightByteRun;
}
else if (iSize > 8)
{
*pbO++ = (7 << 5) + iOffset;
FastEightByteRun:
while (1)
{
CopyMemory(pbO,pbI,8);
pbI += 8;
pbO += 8;
if ((iSize -= 8) <= 8)
break;
*pbO++ = (7 << 5);
}
*pbO++ = (iSize-1) << 5;
}
else
*pbO++ = ((iSize-1) << 5) + iOffset;
CopyMemory (pbO,pbI,iSize);
pbI += iSize;
pbO += iSize;
pbStart = pbI;
}
pbI++;
}
//
// PCL XL exception.
// 2) the delta row is preceded by a 2-byte byte count which
// indicates the number of bytes to follow for the delta row.
// The byte count is expected to be in LSB MSB order.
//
m_dwDRCOutputDataSize = (DWORD)(pbO - m_pubDRCOutputBuff);
(*(PWORD)m_pubDRCOutputBuff) = (WORD)m_dwDRCOutputDataSize - 2;
return TRUE;
}
DWORD
BMPConv::
DwGetDstSize(VOID)
/*++
Routine Description:
Returns the size of destination bitmap.
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("BMPConv: DwGetDstSize\n"));
if (m_CMode == eDeltaRowCompression)
return m_dwDRCOutputDataSize;
else
if (m_CMode == eRLECompression)
return m_dwRLEOutputDataSize;
else
return m_dwOutputBuffSize;
}
//
// Scanline basis DIB conversion functions
//
BOOL
BMPConv::
BCopy(
PBYTE pubSrc,
DWORD dwSrcPixelNum)
/*++
Routine Description:
DIB conversion function. Simple copy for 1BPP, 4,8BPP palette image.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return TRUE if succeeded, otherwise FALSE.
--*/
{
DWORD dwByteIndex, dwBitIndex, dwSrcBytes, dwSrcRemainderBits;
XL_VERBOSE(("BMPConv: BCopy\n"));
if (m_InputBPP == e8bpp || m_FirstBit == eBitZero)
{
dwSrcBytes = (dwSrcPixelNum * (DWORD)UlBPPtoNum(m_InputBPP) + 7) >> 3;
CopyMemory(m_pubOutputBuff, pubSrc, dwSrcBytes);
}
else
{
//
// m_InputBPP is either 1 or 4, m_FirstBit is in [1,7].
//
ASSERT((m_InputBPP == e1bpp) || (m_InputBPP == e4bpp));
ASSERT(m_FirstBit != eBitZero);
dwSrcBytes = (dwSrcPixelNum * (DWORD)UlBPPtoNum(m_InputBPP)) >> 3;
dwSrcRemainderBits = (dwSrcPixelNum * (DWORD)UlBPPtoNum(m_InputBPP)) % 8;
//
// Now dwSrcBytes is the number of full bytes we need to copy from the source,
// dwSrcRemainderBits is the number of remaining bits after dwSrcBytes number
// of bytes in the source we need to copy.
//
// We first copy the full bytes from source.
//
for (dwByteIndex = 0; dwByteIndex < dwSrcBytes; dwByteIndex++)
{
//
// Compose the destination byte from two adjacent source bytes.
//
m_pubOutputBuff[dwByteIndex] = (BYTE)(pubSrc[dwByteIndex] << ((DWORD)m_FirstBit)) |
(BYTE)(pubSrc[dwByteIndex+1] >> (8 - (DWORD)m_FirstBit));
}
if (dwSrcRemainderBits)
{
//
// Now copy the remaining source bits. There are 2 cases:
//
// (1) the remaining source bits are in 1 byte;
// (2) the remaining source bits run across 2 bytes;
//
if (((DWORD)m_FirstBit + dwSrcRemainderBits - 1) < 8)
m_pubOutputBuff[dwByteIndex] = (BYTE)(pubSrc[dwByteIndex] << ((DWORD)m_FirstBit));
else
m_pubOutputBuff[dwByteIndex] = (BYTE)(pubSrc[dwByteIndex] << ((DWORD)m_FirstBit)) |
(BYTE)(pubSrc[dwByteIndex+1] >> (8 - (DWORD)m_FirstBit));
}
}
return TRUE;
}
BOOL
BMPConv::
B4BPPtoCMYK(
PBYTE pubSrc,
DWORD dwSrcPixelNum)
/*++
Routine Description:
DIB conversion function. 4BPP to CMYK.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return TRUE if succeeded, otherwise FALSE.
--*/
{
PDWORD pdwColorTable;
PBYTE pubDst;
DWORD dwConvSize;
ULONG ulIndex;
XL_VERBOSE(("BMPConv: B4BPPtoCMYK\n"));
pdwColorTable = GET_COLOR_TABLE(m_pxlo);
if (pdwColorTable == NULL)
return FALSE;
dwConvSize = (DWORD)m_OddPixelStart;
dwSrcPixelNum += dwConvSize;
pubDst = m_pubOutputBuff;
while (dwConvSize < dwSrcPixelNum)
{
ulIndex = (dwConvSize++ & 1) ?
pdwColorTable[*pubSrc++ & 0x0F] :
pdwColorTable[*pubSrc >> 4];
pubDst[0] = CYAN(ulIndex);
pubDst[1] = MAGENTA(ulIndex);
pubDst[2] = YELLOW(ulIndex);
pubDst[3] = BLACK(ulIndex);
pubDst += 4;
}
return TRUE;
}
BOOL
BMPConv::
B4BPPtoRGB(
PBYTE pubSrc,
DWORD dwSrcPixelNum)
/*++
Routine Description:
DIB conversion function. 4BPP to RGB.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return TRUE if succeeded, otherwise FALSE.
--*/
{
PDWORD pdwColorTable;
DWORD dwConvSize;
ULONG ulIndex;
PBYTE pubDst;
XL_VERBOSE(("BMPConv: B4BPPtoRGB\n"));
pdwColorTable = GET_COLOR_TABLE(m_pxlo);
if (pdwColorTable == NULL)
return FALSE;
dwConvSize = m_OddPixelStart;
dwSrcPixelNum += dwConvSize;
pubDst = m_pubOutputBuff;
while (dwConvSize < dwSrcPixelNum)
{
ulIndex = (dwConvSize++ & 1) ?
pdwColorTable[*pubSrc++ & 0x0F] :
pdwColorTable[*pubSrc >> 4];
pubDst[0] = RED(ulIndex);
pubDst[1] = GREEN(ulIndex);
pubDst[2] = BLUE(ulIndex);
pubDst += 3;
}
return TRUE;
}
BOOL
BMPConv::
B4BPPtoGray(
PBYTE pubSrc,
DWORD dwSrcPixelNum)
/*++
Routine Description:
DIB conversion function. 4BPP to Gray.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return TRUE if succeeded, otherwise FALSE.
--*/
{
PDWORD pdwColorTable;
ULONG ulIndex;
DWORD dwConvSize;
PBYTE pubDst;
XL_VERBOSE(("BMPConv: B4BPPtoGray\n"));
pdwColorTable = GET_COLOR_TABLE(m_pxlo);
if (pdwColorTable == NULL)
return FALSE;
dwConvSize = m_OddPixelStart;
dwSrcPixelNum += dwConvSize;
pubDst = m_pubOutputBuff;
while (dwConvSize < dwSrcPixelNum)
{
ulIndex = (dwConvSize++ & 1) ?
pdwColorTable[*pubSrc++ & 0x0F] :
pdwColorTable[*pubSrc >> 4];
*pubDst++ = DWORD2GRAY(ulIndex);
}
return TRUE;
}
BOOL
BMPConv::
B8BPPtoGray(
IN PBYTE pubSrc,
IN DWORD dwSrcPixelNum
)
/*++
Routine Description:
DIB conversion function - 8BPP to grayscale.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return TRUE if succeeded, otherwise FALSE.
--*/
{
PDWORD pdwColorTable;
DWORD dwColor;
PBYTE pubDst;
XL_VERBOSE(("BMPConv: B8BPPtoGray\n"));
pdwColorTable = GET_COLOR_TABLE(m_pxlo);
if (pdwColorTable == NULL)
return FALSE;
pubDst = m_pubOutputBuff;
while (dwSrcPixelNum--)
{
dwColor = pdwColorTable[*pubSrc++];
*pubDst++ = DWORD2GRAY(dwColor);
}
return TRUE;
}
BOOL
BMPConv::
B8BPPtoRGB(
IN PBYTE pubSrc,
IN DWORD dwSrcPixelNum)
/*++
Routine Description:
DIB conversion function. 8BPP to RGB.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return the size of translated destination bitmap
--*/
{
PDWORD pdwColorTable;
ULONG ulIndex;
PBYTE pubDst;
XL_VERBOSE(("BMPConv: B8BPPtoRGB\n"));
pdwColorTable = GET_COLOR_TABLE(m_pxlo);
if (pdwColorTable == NULL)
return FALSE;
pubDst = m_pubOutputBuff;
while (dwSrcPixelNum--)
{
ulIndex = pdwColorTable[*pubSrc++];
pubDst[0] = RED(ulIndex);
pubDst[1] = GREEN(ulIndex);
pubDst[2] = BLUE(ulIndex);
pubDst += 3;
}
return TRUE;
}
BOOL
BMPConv::
B8BPPtoCMYK(
IN PBYTE pubSrc,
IN DWORD dwSrcPixelNum)
/*++
Routine Description:
DIB conversion function. 8BPP to CMYK.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return the size of translated destination bitmap
--*/
{
PDWORD pdwColorTable;
ULONG ulIndex;
PBYTE pubDst;
XL_VERBOSE(("BMPConv: B8BPPtoCMYK\n"));
pdwColorTable = GET_COLOR_TABLE(m_pxlo);
if (pdwColorTable == NULL)
return FALSE;
pubDst = m_pubOutputBuff;
while (dwSrcPixelNum--)
{
ulIndex = pdwColorTable[*pubSrc++];
pubDst[0] = CYAN(ulIndex);
pubDst[1] = MAGENTA(ulIndex);
pubDst[2] = YELLOW(ulIndex);
pubDst[3] = BLACK(ulIndex);
pubDst += 4;
}
return TRUE;
}
BOOL
BMPConv::
B16BPPtoGray(
IN PBYTE pubSrc,
IN DWORD dwSrcPixelNum)
/*++
Routine Description:
DIB conversion function. 16BPP to 8 bits gray.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return TRUE if succeeded, otherwise FALSE.
--*/
{
DWORD dwColor;
PBYTE pubDst = m_pubOutputBuff;
XL_VERBOSE(("BMPConv: B16BPPtoGray\n"));
while (dwSrcPixelNum--)
{
dwColor = XLATEOBJ_iXlate(m_pxlo, *((PWORD) pubSrc));
pubSrc += 2;
*pubDst++ = DWORD2GRAY(dwColor);
}
return TRUE;
}
BOOL
BMPConv::
B16BPPtoRGB(
IN PBYTE pubSrc,
IN DWORD dwSrcPixelNum)
/*++
Routine Description:
DIB conversion function. 16BPP to RGB.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return TRUE if succeeded, otherwise FALSE.
--*/
{
DWORD dwColor;
PBYTE pubDst = m_pubOutputBuff;
XL_VERBOSE(("BMPConv: B16BPPtoRGB\n"));
while (dwSrcPixelNum--)
{
dwColor = XLATEOBJ_iXlate(m_pxlo, *((PWORD) pubSrc));
pubSrc += 2;
pubDst[0] = RED(dwColor);
pubDst[1] = GREEN(dwColor);
pubDst[2] = BLUE(dwColor);
pubDst += 3;
}
return TRUE;
}
BOOL
BMPConv::
B24BPPtoGray(
IN PBYTE pubSrc,
IN DWORD dwSrcPixelNum)
/*++
Routine Description:
DIB conversion function. 24BPP to 8 bits gray.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return TRUE if succeeded, otherwise FALSE.
--*/
{
DWORD dwColor;
PBYTE pubDst = m_pubOutputBuff;
XL_VERBOSE(("BMPConv: B24BPPtoGray\n"));
if (! (m_flags & BMPCONV_CHECKXLATEOBJ))
{
//
// No special conversion is necessary.
// Pure 24BPP RGB image.
//
while (dwSrcPixelNum--)
{
*pubDst++ = RGB2GRAY(pubSrc[0], pubSrc[1], pubSrc[2]);
pubSrc += 3;
}
}
else if (m_flags & BMPCONV_BGR)
{
while (dwSrcPixelNum--)
{
*pubDst++ = RGB2GRAY(pubSrc[2], pubSrc[1], pubSrc[0]);
pubSrc += 3;
}
}
else
{
ASSERT(m_flags & BMPCONV_XLATE);
while (dwSrcPixelNum--)
{
dwColor = ((DWORD) pubSrc[0] ) |
((DWORD) pubSrc[1] << 8) |
((DWORD) pubSrc[2] << 16);
pubSrc += 3;
dwColor = XLATEOBJ_iXlate(m_pxlo, dwColor);
*pubDst++ = DWORD2GRAY(dwColor);
}
}
return TRUE;
}
BOOL
BMPConv::
B24BPPtoRGB(
IN PBYTE pubSrc,
IN DWORD dwSrcPixelNum)
/*++
Routine Description:
DIB conversion function. 24BPP to RGB.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return TRUE if succeeded, otherwise FALSE.
--*/
{
DWORD dwColor;
PBYTE pubDst = m_pubOutputBuff;
XL_VERBOSE(("BMPConv: B24BPPtoRGB\n"));
if (! (m_flags & BMPCONV_CHECKXLATEOBJ))
{
//
// No special conversion is necessary.
// Pure 24BPP RGB image.
//
CopyMemory(m_pubOutputBuff, pubSrc, dwSrcPixelNum * 3);
}
else if (m_flags & BMPCONV_BGR)
{
while (dwSrcPixelNum--)
{
pubDst[0] = pubSrc[2];
pubDst[1] = pubSrc[1];
pubDst[2] = pubSrc[0];
pubSrc += 3;
pubDst += 3;
}
}
else if (m_flags & BMPCONV_XLATE)
{
while (dwSrcPixelNum--)
{
dwColor = ((DWORD) pubSrc[0] ) |
((DWORD) pubSrc[1] << 8) |
((DWORD) pubSrc[2] << 16);
pubSrc += 3;
dwColor = XLATEOBJ_iXlate(m_pxlo, dwColor);
pubDst[0] = RED(dwColor);
pubDst[1] = GREEN(dwColor);
pubDst[2] = BLUE(dwColor);
pubDst += 3;
}
}
return TRUE;
}
BOOL
BMPConv::
B32BPPtoGray(
IN PBYTE pubSrc,
IN DWORD dwSrcPixelNum)
/*++
Routine Description:
DIB conversion function. 32BPP to 8 bits Gray.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return TRUE if succeeded, otherwise FALSE.
--*/
{
DWORD dwColor;
BYTE ubCyan, ubMagenta, ubYellow, ubBlack;
PBYTE pubDst = m_pubOutputBuff;
XL_VERBOSE(("BMPConv: B24BPPtoGray\n"));
if (! (m_flags & BMPCONV_CHECKXLATEOBJ))
{
//
// No special conversion is necessary.
// Source bitmap is a pure 32BPP CMYK image.
//
while (dwSrcPixelNum--)
{
ubCyan = *pubSrc++;
ubMagenta = *pubSrc++;
ubYellow = *pubSrc++;
ubBlack = *pubSrc++;
*pubDst++ = RGB2GRAY(255 - min(255, (ubCyan + ubBlack)),
255 - min(255, (ubMagenta + ubBlack)),
255 - min(255, (ubYellow + ubBlack)));
}
}
else if (m_flags & BMPCONV_32BPP_RGB)
{
while (dwSrcPixelNum--)
{
*pubDst++ = RGB2GRAY(pubSrc[0], pubSrc[1], pubSrc[2]);
pubSrc += 4;
}
}
else if (m_flags & BMPCONV_32BPP_BGR)
{
while (dwSrcPixelNum--)
{
*pubDst++ = RGB2GRAY(pubSrc[0], pubSrc[1], pubSrc[2]);
pubSrc += 4;
}
}
else
{
ASSERT(m_flags & BMPCONV_XLATE);
while (dwSrcPixelNum--)
{
dwColor = XLATEOBJ_iXlate(m_pxlo, *((PDWORD) pubSrc));
pubSrc += 4;
*pubDst++ = DWORD2GRAY(dwColor);
}
}
return TRUE;
}
BOOL
BMPConv::
B32BPPtoRGB(
IN PBYTE pubSrc,
IN DWORD dwSrcPixelNum)
/*++
Routine Description:
DIB conversion function. 32BPP to RGB.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return TRUE if succeeded, otherwise FALSE.
--*/
{
DWORD dwColor;
BYTE ubCyan, ubMagenta, ubYellow, ubBlack;
PBYTE pubDst = m_pubOutputBuff;
XL_VERBOSE(("BMPConv: B32BPPtoRGB\n"));
if (! (m_flags & BMPCONV_CHECKXLATEOBJ))
{
//
// No special conversion is necessary.
// Source bitmap is a pure 32BPP CMYK image.
//
while (dwSrcPixelNum--)
{
ubCyan = pubSrc[0];
ubMagenta = pubSrc[1];
ubYellow = pubSrc[2];
ubBlack = pubSrc[3];
pubSrc += 4;
ubCyan += ubBlack;
ubMagenta += ubBlack;
ubYellow += ubBlack;
pubDst[0] = 255 - min(255, ubCyan);
pubDst[1] = 255 - min(255, ubMagenta);
pubDst[2] = 255 - min(255, ubYellow);
pubDst += 3;
}
}
else if (m_flags & BMPCONV_32BPP_RGB)
{
while (dwSrcPixelNum--)
{
pubDst[0] = pubSrc[0];
pubDst[1] = pubSrc[1];
pubDst[2] = pubSrc[2];
pubSrc += 4;
pubDst += 3;
}
}
else if (m_flags & BMPCONV_32BPP_BGR)
{
while (dwSrcPixelNum--)
{
pubDst[0] = pubSrc[2];
pubDst[1] = pubSrc[1];
pubDst[2] = pubSrc[0];
pubSrc += 4;
pubDst += 3;
}
}
else
{
ASSERT(m_flags & BMPCONV_XLATE);
while (dwSrcPixelNum--)
{
dwColor = XLATEOBJ_iXlate(m_pxlo, *((PDWORD) pubSrc));
pubSrc += 4;
pubDst[0] = RED(dwColor);
pubDst[1] = GREEN(dwColor);
pubDst[2] = BLUE(dwColor);
pubDst += 3;
}
}
return TRUE;
}
BOOL
BMPConv::
B32BPPtoCMYK(
IN PBYTE pubSrc,
IN DWORD dwSrcPixelNum)
/*++
Routine Description:
DIB conversion function. 32BPP to CMYK.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return TRUE if succeeded, otherwise FALSE.
--*/
{
DWORD dwColor;
PBYTE pubDst = m_pubOutputBuff;
XL_VERBOSE(("BMPConv: B32BPPtoCMYK\n"));
if (! (m_flags & BMPCONV_CHECKXLATEOBJ))
{
//
// No special conversion is necessary.
// Source bitmap is a pure 32BPP CMYK image.
//
CopyMemory(m_pubOutputBuff, pubSrc, dwSrcPixelNum * 4);
}
else
{
ASSERT(m_flags & BMPCONV_XLATE);
while (dwSrcPixelNum--)
{
dwColor = XLATEOBJ_iXlate(m_pxlo, *((PDWORD) pubSrc));
pubSrc += 4;
pubDst[0] = 255 - RED(dwColor);
pubDst[1] = 255 - GREEN(dwColor);
pubDst[2] = 255 - BLUE(dwColor);
pubDst[3] = 0;
pubDst += 4;
}
}
return TRUE;
}
BOOL
BMPConv::
BArbtoGray(
PBYTE pubSrc,
DWORD dwSrcPixelNum)
/*++
Routine Description:
DIB conversion function. Arbitray bitmap to 8 bits Gray scale.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return TRUE if succeeded, otherwise FALSE.
--*/
{
DWORD dwColor;
PDWORD pdwSrc;
PBYTE pubDst = m_pubOutputBuff;
XL_VERBOSE(("BMPConv: BArbtoGray\n"));
pdwSrc = (PDWORD) pubSrc;
while (dwSrcPixelNum--)
{
dwColor = XLATEOBJ_iXlate(m_pxlo, *pdwSrc++);
*pubDst++ = DWORD2GRAY(dwColor);
}
return TRUE;
}
BOOL
BMPConv::
BArbtoRGB(
PBYTE pubSrc,
DWORD dwSrcPixelNum)
/*++
Routine Description:
DIB conversion function. Arbitraty bitmap to RGB.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return TRUE if succeeded, otherwise FALSE.
--*/
{
DWORD dwColor;
PDWORD pdwSrc;
PBYTE pubDst = m_pubOutputBuff;
XL_VERBOSE(("BMPConv: BArbtoRGB\n"));
pdwSrc = (PDWORD) pubSrc;
while (dwSrcPixelNum--)
{
dwColor = XLATEOBJ_iXlate(m_pxlo, *pdwSrc++);
pubDst[0] = RED(dwColor);
pubDst[1] = GREEN(dwColor);
pubDst[2] = BLUE(dwColor);
pubDst += 3;
}
return TRUE;
}
#ifdef WINNT_40
BOOL
BMPConv::
B24BPPToImageMask(
PBYTE pubSrc,
DWORD dwSrcPixelNum)
/*++
Routine Description:
DIB conversion function. 24 bpp bitmaps with only one non-white color to image mask.
Can happen on NT4, where GDI does not optimize for that case.
Arguments:
pubSrc - Source DIB buffer
dwSrcPixelNum - the number of source pixel
Return Value:
Return TRUE if succeeded, otherwise FALSE.
--*/
{
DWORD dwColor;
PDWORD pdwSrc;
BYTE ubDest = 0;
DWORD dwIndex = 0;
DWORD dwTransp = (m_flags & BMPCONV_SRC_COPY) ? RGB_WHITE : RGB_BLACK;
PBYTE pubDst = m_pubOutputBuff;
XL_VERBOSE(("BMPConv: B24BPPToImageMask\n"));
while (dwSrcPixelNum--)
{
if (! (m_flags & BMPCONV_CHECKXLATEOBJ))
{
//
// No special conversion is necessary, 24BPP RGB image.
//
dwColor = ((DWORD) pubSrc[0] ) |
((DWORD) pubSrc[1] << 8) |
((DWORD) pubSrc[2] << 16);
}
else if (m_flags & BMPCONV_BGR)
{
//
// convert 24BPP BGR to RGB.
//
dwColor = ((DWORD) pubSrc[2] ) |
((DWORD) pubSrc[1] << 8) |
((DWORD) pubSrc[0] << 16);
}
else if (m_flags & BMPCONV_XLATE)
{
dwColor = ((DWORD) pubSrc[0] ) |
((DWORD) pubSrc[1] << 8) |
((DWORD) pubSrc[2] << 16);
dwColor = XLATEOBJ_iXlate(m_pxlo, dwColor);
}
ubDest = ubDest << 1;
dwIndex++;
pubSrc += 3;
if (dwColor != dwTransp)
ubDest |= 0x01;
if (dwIndex == 8) // one byte completed ?
{
*pubDst++ = ubDest;
dwIndex = 0;
ubDest = 0;
}
}
if (dwIndex != 0) // flush leftover bits
*pubDst = ubDest;
return TRUE;
}
#endif
BOOL
BMPConv::
BConversionProc(
PBYTE pubSrc,
DWORD dwSrcPixelNum)
/*++
Routine Description:
Return a pointer to the appropriate DIB conversion function
Arguments:
pBMPAttrrib - Points to a BMPATTRUTE structure
Return Value:
Pointer to a DIB conversion function
--*/
{
//PVOID pfnDibConv[7][4] = {
// Gray Scale, Palette, RGB, CMYK
//-----------------------------------------------------------------------
//{BCopy, BCopy, NULL, NULL}, // 1bpp
//{B4BPPtoGray, BCopy, B4BPPtoRGB, B4BPPtoCMYK}, // 4bpp
//{B8BPPtoGray, BCopy, B8BPPtoRGB, B8BPPtoCMYK}, // 8bpp
//{B16BPPtoGray, NULL, B16BPPtoRGB, NULL}, // 16bpp
//{B24BPPtoGray, NULL, B24BPPtoRGB, NULL}, // 24bpp
//{B32BPPtoGray, NULL, B32BPPtoRGB, B32BPPtoCMYK},// 32bpp
//{BArbtoGray, NULL, BArbtoRGB, NULL} // Arbitrary
//};
XL_VERBOSE(("BMPConv: BConversionProc\n"));
//
// special case for NT4: GDI passes all bitmaps as 24 bpp, even 1 bpp bitmaps
// that can be better treated through image masks
//
#if 0 // #ifdef WINNT_40
if (m_flags & BMPCONV_2COLOR_24BPP)
{
return B24BPPToImageMask;
}
#endif
BOOL bRet = FALSE;
//
// Zero init for DWORD alignment
//
ZeroMemory(m_pubOutputBuff, m_dwOutputBuffSize);
switch (m_InputBPP)
{
case e1bpp:
switch(m_OutputFormat)
{
case eOutputGray:
case eOutputPal:
BCopy(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
case eOutputRGB:
case eOutputCMYK:
break;
}
break;
case e4bpp:
switch(m_OutputFormat)
{
case eOutputGray:
B4BPPtoGray(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
case eOutputPal:
BCopy(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
case eOutputRGB:
B4BPPtoRGB(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
case eOutputCMYK:
B4BPPtoCMYK(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
}
break;
case e8bpp:
switch(m_OutputFormat)
{
case eOutputGray:
B8BPPtoGray(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
case eOutputPal:
BCopy(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
case eOutputRGB:
B8BPPtoRGB(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
case eOutputCMYK:
B8BPPtoCMYK(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
}
break;
case e16bpp:
switch(m_OutputFormat)
{
case eOutputGray:
B16BPPtoGray(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
case eOutputPal:
BCopy(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
break;
case eOutputRGB:
B16BPPtoRGB(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
case eOutputCMYK:
XL_ERR(("BMPConv::BConversionProc: 16 to CMYK is not supported yet.\n"));
break;
}
break;
case e24bpp:
switch(m_OutputFormat)
{
case eOutputGray:
B24BPPtoGray(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
case eOutputPal:
break;
case eOutputRGB:
B24BPPtoRGB(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
case eOutputCMYK:
break;
}
break;
case e32bpp:
switch(m_OutputFormat)
{
case eOutputGray:
B32BPPtoGray(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
case eOutputPal:
break;
case eOutputRGB:
B32BPPtoRGB(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
case eOutputCMYK:
B32BPPtoCMYK(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
}
break;
default:
switch(m_OutputFormat)
{
case eOutputGray:
BArbtoGray(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
case eOutputPal:
break;
case eOutputRGB:
BArbtoRGB(pubSrc, dwSrcPixelNum);
bRet = TRUE;
break;
case eOutputCMYK:
XL_ERR(("BMPConv::BConversionProc: Arb to CMYK is not supported yet.\n"));
break;
}
}
return bRet;
}
DWORD
BMPConv::
DwCheckXlateObj(
IN XLATEOBJ *pxlo,
IN BPP InputBPP)
/*++
Routine Description:
Determines the type of converison.
*Palette
*RGB
*BGR
*CMYK
*Call XLATEOBJ_XXX function.
Arguments:
Return Value:
Note:
--*/
{
DWORD dwRet;
DWORD Dst[4];
XL_VERBOSE(("BMPConv: DwCheckXlateObj\n"));
//
// Init dwRet
//
dwRet = 0;
switch (InputBPP)
{
case e16bpp:
dwRet = BMPCONV_XLATE;
break;
case e24bpp:
if (pxlo->iSrcType == PAL_RGB)
dwRet = 0;
else
if (pxlo->iSrcType == PAL_BGR)
dwRet = BMPCONV_BGR;
{
Dst[0] = XLATEOBJ_iXlate(pxlo, 0x000000FF);
Dst[1] = XLATEOBJ_iXlate(pxlo, 0x0000FF00);
Dst[2] = XLATEOBJ_iXlate(pxlo, 0x00FF0000);
if ((Dst[0] == 0x000000FF) &&
(Dst[1] == 0x0000FF00) &&
(Dst[2] == 0x00FF0000) )
{
dwRet = 0;
}
else if ((Dst[0] == 0x00FF0000) &&
(Dst[1] == 0x0000FF00) &&
(Dst[2] == 0x000000FF) )
{
dwRet = BMPCONV_BGR;
}
}
break;
case e32bpp:
if (pxlo->flXlate & XO_FROM_CMYK)
dwRet = 0;
else
{
//
// Translate all 4 bytes from the DWORD
//
Dst[0] = XLATEOBJ_iXlate(pxlo, 0x000000FF);
Dst[1] = XLATEOBJ_iXlate(pxlo, 0x0000FF00);
Dst[2] = XLATEOBJ_iXlate(pxlo, 0x00FF0000);
Dst[3] = XLATEOBJ_iXlate(pxlo, 0xFF000000);
if ((Dst[0] == 0x000000FF) &&
(Dst[1] == 0x0000FF00) &&
(Dst[2] == 0x00FF0000) &&
(Dst[3] == 0x00000000))
{
//
// If translate result is same (4th byte will be zero) then
// we done with it except if 32bpp then we have to skip one
// source byte for every 3 bytes
//
dwRet = BMPCONV_32BPP_RGB;
}
else if ((Dst[0] == 0x00FF0000) &&
(Dst[1] == 0x0000FF00) &&
(Dst[2] == 0x000000FF) &&
(Dst[3] == 0x00000000))
{
//
// Simply swap the R and B component
//
dwRet = BMPCONV_32BPP_BGR;
}
}
}
return dwRet;
}