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
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;
|
|
}
|
|
|