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.
1481 lines
40 KiB
1481 lines
40 KiB
/*++
|
|
|
|
Copyright (c) 1996 - 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
raster.c
|
|
|
|
Abstract:
|
|
|
|
Functions to scan a bitmap for white regions.
|
|
|
|
Environment:
|
|
|
|
Windows NT Unidrv driver
|
|
|
|
Revision History:
|
|
|
|
12/15/96 -alvins-
|
|
Created (mostly stolen from Lindsayh)
|
|
|
|
--*/
|
|
|
|
|
|
#include "raster.h"
|
|
#include "rmrender.h"
|
|
|
|
/*
|
|
* The following union allows machine independent conversion from
|
|
* DWORDS to BYTES.
|
|
*/
|
|
|
|
typedef union
|
|
{
|
|
DWORD dw; /* Data as a DWORD */
|
|
BYTE b[ DWBYTES ]; /* Data as bytes */
|
|
} UBDW;
|
|
|
|
|
|
/*
|
|
* Following array is used to test the leftover bits from scanning. The
|
|
* rational is that only some of the bits in the last word are part
|
|
* of the bitmap, so only they must be tested. It is initialised at
|
|
* DLL initialisation time.
|
|
* NOTE: There are 33 entries in this array: This is intentional!
|
|
* Depending upon circumstances, either the 0 or 32nd entry will be
|
|
* used for a dword that is all ones.
|
|
*
|
|
**** THIS ARRAY IS NOW DYNAMICALLY ALLOCATED IN bSkipInit(). ************
|
|
*/
|
|
|
|
|
|
#define TABLE_SIZE ((DWBITS + 1) * sizeof( DWORD ))
|
|
|
|
/*
|
|
* RGB_WHITE is the bit pattern found in a white entry for an RGB format
|
|
* 4 bits per pel bitmap. This is the only special case required when
|
|
* scanning the source bitmap for white. In all other cases (monochrome
|
|
* and CMY), white is represented by a 0 nibble.
|
|
*/
|
|
|
|
#define RGB_WHITE 0x77777777
|
|
|
|
/*
|
|
* Also want to know about the 8 bit per pel white index.
|
|
*/
|
|
|
|
#define BPP8_WHITE 0xffffffff
|
|
|
|
/*
|
|
* Define BPP values for clarify
|
|
*/
|
|
#define BPP1 1
|
|
#define BPP4 4
|
|
#define BPP8 8
|
|
#define BPP24 24
|
|
|
|
|
|
//*****************************************************
|
|
BOOL
|
|
bSkipInit(
|
|
PDEV *pPDev
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
The job here is to initialise the table that is used to mask off
|
|
the unused bits in a scanline. All scanlines are DWORD aligned,
|
|
and we take advantage of that fact when looking for white space.
|
|
However, the last DWORD may not be completely used, so we have
|
|
a masking table used to check only those bits of interest.
|
|
The table depends upon byte ordering within words, and this is
|
|
machine dependent, so we generate the table. This provides
|
|
machine independence, since the machine that is going to use
|
|
the table generates it! This function is called when the DLL
|
|
is loaded, so we are not called often.
|
|
The union 'u' provides the mapping between BYTES and DWORDS,
|
|
and so is the key to this function. The union is initialised
|
|
using the BYTE array, but it stored in memory using the DWORD.
|
|
|
|
|
|
Arguments:
|
|
|
|
pPDev Pointer to PDEV structure
|
|
|
|
Return Value:
|
|
|
|
TRUE for success and FALSE for failure
|
|
|
|
--*/
|
|
{
|
|
|
|
register int iIndex;
|
|
register DWORD *pdw;
|
|
|
|
UBDW u; /* The magic union */
|
|
PRASTERPDEV pRPDev = pPDev->pRasterPDEV;
|
|
|
|
u.dw = 0;
|
|
|
|
if( !(pRPDev->pdwBitMask = (DWORD *)MemAlloc( TABLE_SIZE )) )
|
|
return FALSE;
|
|
|
|
|
|
pdw = pRPDev->pdwBitMask;
|
|
|
|
for( iIndex = 0; iIndex < DWBITS; ++iIndex )
|
|
{
|
|
*pdw++ = u.dw;
|
|
|
|
/* The left most bit in the scan line is the MSB of the byte */
|
|
u.b[ iIndex / BBITS ] |= 1 << (BBITS - 1 - (iIndex & (BBITS - 1)));
|
|
}
|
|
|
|
/* ALL bits are involved in the last one */
|
|
*pdw = (DWORD)~0;
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//*******************************************************
|
|
BOOL
|
|
bIsBandWhite(
|
|
DWORD *pdwBitsIn,
|
|
RENDER *pRData,
|
|
int iWhiteIndex
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Scan a band of the bitmap, and return TRUE if it is
|
|
all WHITE, else FALSE. This is used to decide whether a
|
|
band should be sent to the printer. This routine also
|
|
masks off the unused bits at the end of each scan line.
|
|
|
|
Arguments:
|
|
|
|
pdwBitsIn Pointer to area to scan for white
|
|
pRData Pointer to RENDER structure
|
|
iWhiteIndex White value to compare against, only
|
|
included here for functional compatibility
|
|
|
|
Return Value:
|
|
|
|
TRUE if entire bitmap is white, else FALSE
|
|
|
|
--*/
|
|
{
|
|
|
|
register DWORD *pdwBits;
|
|
register DWORD *pdwLim;
|
|
|
|
int iLines; /* Number of scan lines to check */
|
|
|
|
DWORD dwMask; /* Mask to zap the trailing bits */
|
|
BOOL bRet;
|
|
|
|
//Always TRUE for Txtonly as we don't want to send any graphics.
|
|
if(pRData->PrinterType == PT_TTY)
|
|
return TRUE;
|
|
|
|
|
|
/*
|
|
* As a speed optimisation, scan the bits in DWORD size clumps.
|
|
* This substantially reduces the number of iterations and memory
|
|
* references required. There will usually be some trailing
|
|
* bits; these are handled individually - if we get that far.
|
|
*/
|
|
|
|
/* Mask to clear last few bits of scanline, if not full DWORD */
|
|
dwMask = *(pRData->pdwBitMask + (pRData->cBLine % DWBITS));
|
|
if( dwMask == 0 )
|
|
dwMask = (DWORD)~0; /* Size is DWORD multiple */
|
|
|
|
iLines = pRData->iTransHigh;
|
|
|
|
bRet = TRUE;
|
|
|
|
while( --iLines >= 0 )
|
|
{
|
|
|
|
/* Calculate the starting address for this scan */
|
|
pdwBits = pdwBitsIn;
|
|
|
|
/* pDWLim is the DWORD past the data of interest - not used */
|
|
pdwLim = pdwBits + pRData->cDWLine;
|
|
|
|
/* Clear out undefined bits at end of line */
|
|
*(pdwLim - 1) &= dwMask;
|
|
|
|
|
|
/* Need to continue masking regardless */
|
|
if (bRet)
|
|
{
|
|
while (*pdwBits == 0 && ++pdwBits < pdwLim);
|
|
|
|
if( pdwBits < pdwLim )
|
|
bRet = FALSE;
|
|
}
|
|
|
|
/* Onto the next scan line */
|
|
pdwBitsIn += pRData->cDWLine * pRData->iInterlace;
|
|
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
//**********************************************************
|
|
BOOL
|
|
bIsLineWhite(
|
|
register DWORD *pdwBits,
|
|
register RENDER *pRData,
|
|
int iWhiteIndex
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Scan a horizontal row of the bitmap, and return TRUE if it is
|
|
all WHITE, else FALSE. This is used to decide whether a
|
|
scan line should be sent to the printer. This routine also
|
|
masks off the unused bits at the end of each scan line.
|
|
|
|
Arguments:
|
|
|
|
pdwBits Pointer to area to scan for white
|
|
pRData Pointer to RENDER structure
|
|
iWhiteIndex White value to compare against, only
|
|
included here for functional compatibility
|
|
|
|
Return Value:
|
|
|
|
TRUE if entire bitmap is white, else FALSE
|
|
|
|
--*/
|
|
{
|
|
|
|
register DWORD *pdwLim;
|
|
|
|
|
|
DWORD dwMask; /* Mask to zap the trailing bits */
|
|
|
|
//Always TRUE for Txtonly as we don't want to send any graphics.
|
|
if(pRData->PrinterType == PT_TTY)
|
|
return TRUE;
|
|
|
|
/*
|
|
* As a speed optimisation, scan the bits in DWORD size clumps.
|
|
* This substantially reduces the number of iterations and memory
|
|
* references required. There will ususally be some trailing
|
|
* bits; these are handled individually - if we get that far.
|
|
*/
|
|
|
|
/* Mask to clear last few bits of scanline, if not full DWORD */
|
|
dwMask = *(pRData->pdwBitMask + (pRData->cBLine % DWBITS));
|
|
if( dwMask == 0 )
|
|
dwMask = (DWORD)~0; /* Size is DWORD multiple */
|
|
|
|
|
|
/* pDWLim is the DWORD past the data of interest - not used */
|
|
pdwLim = pdwBits + pRData->cDWLine;
|
|
|
|
/* Clear out undefined bits at end of line */
|
|
*(pdwLim - 1) &= dwMask;
|
|
|
|
while (*pdwBits == 0 && ++pdwBits < pdwLim);
|
|
|
|
if( pdwBits < pdwLim )
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
//**********************************************************
|
|
BOOL
|
|
bIsNegatedLineWhite(
|
|
DWORD *pdwBits,
|
|
RENDER *pRData,
|
|
int iWhiteIndex
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Scan a horizontal row of the bitmap, and return TRUE if it is
|
|
all WHITE, else FALSE. This is used to decide whether a
|
|
scan line should be sent to the printer. This routine also
|
|
masks off the unused bits at the end of each scan line.
|
|
|
|
Arguments:
|
|
|
|
pdwBits Pointer to area to scan for white
|
|
pRData Pointer to RENDER structure
|
|
iWhiteIndex White value to compare against, only
|
|
included here for functional compatibility
|
|
|
|
Return Value:
|
|
|
|
TRUE if entire bitmap is white, else FALSE
|
|
|
|
--*/
|
|
{
|
|
|
|
DWORD *pdwLim;
|
|
int iCnt;
|
|
|
|
|
|
DWORD dwMask; /* Mask to zap the trailing bits */
|
|
|
|
//Always TRUE for Txtonly as we don't want to send any graphics.
|
|
if(pRData->PrinterType == PT_TTY)
|
|
return TRUE;
|
|
|
|
/*
|
|
* As a speed optimisation, scan the bits in DWORD size clumps.
|
|
* This substantially reduces the number of iterations and memory
|
|
* references required. There will ususally be some trailing
|
|
* bits; these are handled individually - if we get that far.
|
|
*/
|
|
|
|
/* Mask to clear last few bits of scanline, if not full DWORD */
|
|
dwMask = *(pRData->pdwBitMask + (pRData->cBLine % DWBITS));
|
|
if( dwMask == 0 )
|
|
dwMask = (DWORD)~0; /* Size is DWORD multiple */
|
|
|
|
/* Clear out undefined bits at end of line */
|
|
pdwBits[pRData->cDWLine-1] |= ~dwMask;
|
|
|
|
//
|
|
// For performance we test 4 dwords at a time for white
|
|
//
|
|
pdwLim = pdwBits;
|
|
iCnt = pRData->cDWLine >> 2;
|
|
while (--iCnt >= 0)
|
|
{
|
|
if ((pdwBits[0] & pdwBits[1] & pdwBits[2] & pdwBits[3]) != -1)
|
|
goto InvertTheBits;
|
|
pdwBits += 4;
|
|
}
|
|
//
|
|
// test any left over dwords for white
|
|
//
|
|
iCnt = pRData->cDWLine & 3;
|
|
while (--iCnt >= 0)
|
|
{
|
|
if (*pdwBits != -1)
|
|
goto InvertTheBits;
|
|
pdwBits++;
|
|
}
|
|
return TRUE;
|
|
//
|
|
// if this isn't a white line we need to invert the bits
|
|
//
|
|
InvertTheBits:
|
|
dwMask = (DWORD)(pdwBits - pdwLim);
|
|
ZeroMemory (pdwLim,dwMask*DWBYTES);
|
|
vInvertBits(pdwBits,pRData->cDWLine-dwMask);
|
|
return FALSE;
|
|
}
|
|
|
|
//***************************************************
|
|
BOOL
|
|
bIsRGBBandWhite (
|
|
DWORD *pdwBitsIn,
|
|
RENDER *pRData,
|
|
int iWhiteIndex
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Scan a band of the bitmap, and return TRUE if it is
|
|
all WHITE, else FALSE. This is used to decide whether a
|
|
band should be sent to the printer.
|
|
|
|
Arguments:
|
|
|
|
pdwBitsIn Pointer to area to scan for white
|
|
pRData Pointer to RENDER structure
|
|
iWhiteIndex White value to compare against
|
|
included here for functional compatibility
|
|
|
|
Return Value:
|
|
|
|
TRUE if entire bitmap is white, else FALSE
|
|
|
|
--*/
|
|
{
|
|
|
|
register DWORD *pdwBits;
|
|
register DWORD *pdwLim;
|
|
|
|
int iLines; /* Number of scan lines to check */
|
|
|
|
DWORD dwMask; /* Mask to zap the trailing bits */
|
|
|
|
/*
|
|
* As a speed optimisation, scan the bits in DWORD size clumps.
|
|
* This substantially reduces the number of iterations and memory
|
|
* references required. There will ususally be some trailing
|
|
* bits; these are handled individually - if we get that far.
|
|
*/
|
|
|
|
/* Mask to clear last few bits of scanline, if not full DWORD */
|
|
dwMask = *(pRData->pdwBitMask + (pRData->cBLine % DWBITS));
|
|
if( dwMask == 0 )
|
|
dwMask = (DWORD)~0; /* Size is DWORD multiple */
|
|
|
|
iLines = pRData->iTransHigh;
|
|
|
|
while( --iLines >= 0 )
|
|
{
|
|
|
|
/* Calculate the starting address for this scan */
|
|
pdwBits = pdwBitsIn;
|
|
|
|
/* pDWLim is the DWORD past the data of interest - not used */
|
|
pdwLim = pdwBits + pRData->cDWLine;
|
|
|
|
/* Clear out undefined bits at end of line */
|
|
*(pdwLim - 1) &= dwMask;
|
|
*(pdwLim - 1) |= ~dwMask & RGB_WHITE;
|
|
|
|
|
|
/*
|
|
* NOTE: This test is more complex than needed because the
|
|
* engine ignores palette entries when doing BLTs. The WHITENESS
|
|
* rop sets all bits to 1. Hence, we choose to ignore the
|
|
* MSB in the comparison: this means we detect white space
|
|
* with an illegal palette entry. This makes GDI people happy,
|
|
* but not me.
|
|
*/
|
|
do {
|
|
if ((*pdwBits & RGB_WHITE) != RGB_WHITE)
|
|
return FALSE;
|
|
} while (++pdwBits < pdwLim);
|
|
|
|
/* Onto the next scan line */
|
|
pdwBitsIn += pRData->cDWLine * pRData->iInterlace;
|
|
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//*******************************************************
|
|
BOOL
|
|
bIsRGBLineWhite (
|
|
register DWORD *pdwBits,
|
|
RENDER *pRData,
|
|
int iWhiteIndex
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Scan a single row of the bitmap, and return TRUE if it is
|
|
all WHITE, else FALSE. This is used to decide whether a
|
|
band should be sent to the printer.
|
|
|
|
Arguments:
|
|
|
|
pdwBitsIn Pointer to area to scan for white
|
|
pRData Pointer to RENDER structure
|
|
iWhiteIndex White value to compare against
|
|
included here for functional compatibility
|
|
|
|
Return Value:
|
|
|
|
TRUE if entire bitmap is white, else FALSE
|
|
|
|
--*/
|
|
{
|
|
|
|
DWORD dwCnt;
|
|
|
|
DWORD dwMask; /* Mask to zap the trailing bits */
|
|
|
|
/*
|
|
* As a speed optimisation, scan the bits in DWORD size clumps.
|
|
* This substantially reduces the number of iterations and memory
|
|
* references required. There will ususally be some trailing
|
|
* bits; these are handled individually - if we get that far.
|
|
*/
|
|
|
|
/* Mask to clear last few bits of scanline, if not full DWORD */
|
|
dwMask = *(pRData->pdwBitMask + (pRData->cBLine % DWBITS));
|
|
if( dwMask == 0 )
|
|
dwMask = (DWORD)~0; /* Size is DWORD multiple */
|
|
|
|
/* Clear out undefined bits at end of line */
|
|
dwCnt = pRData->cDWLine;
|
|
pdwBits[dwCnt-1] &= dwMask;
|
|
pdwBits[dwCnt-1] |= ~dwMask & RGB_WHITE;
|
|
|
|
// test four dwords at a time
|
|
//
|
|
while (dwCnt >= 4)
|
|
{
|
|
if ((*pdwBits & pdwBits[1] & pdwBits[2] & pdwBits[3] & RGB_WHITE) != RGB_WHITE)
|
|
return FALSE;
|
|
pdwBits += 4;
|
|
dwCnt -= 4;
|
|
}
|
|
while (dwCnt--)
|
|
{
|
|
if ((*pdwBits & RGB_WHITE) != RGB_WHITE)
|
|
return FALSE;
|
|
pdwBits++;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//**********************************************************
|
|
BOOL
|
|
bIs8BPPBandWhite (
|
|
DWORD *pdwBitsIn,
|
|
RENDER *pRData,
|
|
int iWhiteIndex
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Scan a band of the bitmap, and return TRUE if it is
|
|
all WHITE, else FALSE. This is used to decide whether a
|
|
band should be sent to the printer.
|
|
|
|
Arguments:
|
|
|
|
pdwBitsIn Pointer to area to scan for white
|
|
pRData Pointer to RENDER structure
|
|
iWhiteIndex White value to compare against
|
|
|
|
Return Value:
|
|
|
|
TRUE if entire bitmap is white, else FALSE
|
|
|
|
--*/
|
|
{
|
|
|
|
register DWORD *pdwBits;
|
|
register DWORD *pdwLim;
|
|
|
|
int iLines; /* Number of scan lines to check */
|
|
|
|
DWORD dwMask; /* Mask to zap the trailing bits */
|
|
DWORD dwWhiteIndex;
|
|
|
|
dwWhiteIndex = (DWORD)iWhiteIndex;
|
|
|
|
/*
|
|
* As a speed optimisation, scan the bits in DWORD size clumps.
|
|
* This substantially reduces the number of iterations and memory
|
|
* references required. There will ususally be some trailing
|
|
* bits; these are handled individually - if we get that far.
|
|
*/
|
|
|
|
/* Mask to clear last few bits of scanline, if not full DWORD */
|
|
dwMask = *(pRData->pdwBitMask + (pRData->cBLine % DWBITS));
|
|
if( dwMask == 0 )
|
|
dwMask = (DWORD)~0; /* Size is DWORD multiple */
|
|
|
|
iLines = pRData->iTransHigh;
|
|
|
|
/*
|
|
* Need to set up the white index to be a dword multiple.
|
|
* iwhiteIndex looks like 0x000000ff but the comparison
|
|
* is done on dword boundaries so a stream of white looks
|
|
* like 0xffffffff.
|
|
*/
|
|
dwWhiteIndex |= dwWhiteIndex << 8;
|
|
dwWhiteIndex |= dwWhiteIndex << 16;
|
|
|
|
while( --iLines >= 0 )
|
|
{
|
|
|
|
/* Calculate the starting address for this scan */
|
|
pdwBits = pdwBitsIn;
|
|
|
|
/* pDWLim is the DWORD past the data of interest - not used */
|
|
pdwLim = pdwBits + pRData->cDWLine;
|
|
|
|
/* Clear out undefined bits at end of line */
|
|
*(pdwLim - 1) &= dwMask;
|
|
*(pdwLim - 1) |= ~dwMask & dwWhiteIndex;
|
|
|
|
while(*pdwBits == dwWhiteIndex && ++pdwBits < pdwLim);
|
|
|
|
if( pdwBits < pdwLim )
|
|
return FALSE;
|
|
|
|
/* Onto the next scan line */
|
|
pdwBitsIn += pRData->cDWLine * pRData->iInterlace;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//**********************************************************
|
|
BOOL
|
|
bIs8BPPLineWhite (
|
|
DWORD *pdwBits,
|
|
RENDER *pRData,
|
|
int iWhiteIndex
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Scan a single row of the bitmap, and return TRUE if it is
|
|
all WHITE, else FALSE. This is used to decide whether a
|
|
band should be sent to the printer.
|
|
|
|
Arguments:
|
|
|
|
pdwBits Pointer to area to scan for white
|
|
pRData Pointer to RENDER structure
|
|
iWhiteIndex White value to compare against
|
|
|
|
Return Value:
|
|
|
|
TRUE if entire bitmap is white, else FALSE
|
|
|
|
--*/
|
|
{
|
|
|
|
register DWORD *pdwLim;
|
|
|
|
|
|
DWORD dwMask; /* Mask to zap the trailing bits */
|
|
DWORD dwWhiteIndex;
|
|
|
|
dwWhiteIndex = (DWORD)iWhiteIndex;
|
|
|
|
|
|
/*
|
|
* Need to set up the white index to be a dword multiple.
|
|
* iwhiteIndex looks like 0x000000ff but the comparison
|
|
* is done on dword boundaries so a stream of white looks
|
|
* like 0xffffffff.
|
|
*/
|
|
|
|
dwWhiteIndex |= dwWhiteIndex << 8;
|
|
dwWhiteIndex |= dwWhiteIndex << 16;
|
|
/*
|
|
* As a speed optimisation, scan the bits in DWORD size clumps.
|
|
* This substantially reduces the number of iterations and memory
|
|
* references required. There will ususally be some trailing
|
|
* bits; these are handled individually - if we get that far.
|
|
*/
|
|
|
|
/* Mask to clear last few bits of scanline, if not full DWORD */
|
|
dwMask = *(pRData->pdwBitMask + (pRData->cBLine % DWBITS));
|
|
if( dwMask == 0 )
|
|
dwMask = (DWORD)~0; /* Size is DWORD multiple */
|
|
|
|
|
|
/* pDWLim is the DWORD past the data of interest - not used */
|
|
pdwLim = pdwBits + pRData->cDWLine;
|
|
|
|
/* Clear out undefined bits at end of line */
|
|
*(pdwLim - 1) &= dwMask;
|
|
*(pdwLim - 1) |= ~dwMask & dwWhiteIndex;
|
|
|
|
while(*pdwBits == dwWhiteIndex && ++pdwBits < pdwLim);
|
|
|
|
if( pdwBits < pdwLim )
|
|
return FALSE;
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//**********************************************************
|
|
BOOL
|
|
bIs24BPPBandWhite (
|
|
DWORD *pdwBitsIn,
|
|
RENDER *pRData,
|
|
int iWhiteIndex
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Scan a band of the bitmap, and return TRUE if it is
|
|
all WHITE, else FALSE. This is used to decide whether a
|
|
band should be sent to the printer.
|
|
|
|
Arguments:
|
|
|
|
pdwBitsIn Pointer to area to scan for white
|
|
pRData Pointer to RENDER structure
|
|
iWhiteIndex White value to compare against
|
|
included here for functional compatibility
|
|
|
|
Return Value:
|
|
|
|
TRUE if entire bitmap is white, else FALSE
|
|
|
|
--*/
|
|
{
|
|
|
|
register DWORD *pdwBits;
|
|
register DWORD *pdwLim;
|
|
|
|
int iLines; /* Number of scan lines to check */
|
|
|
|
DWORD dwMask; /* Mask to zap the trailing bits */
|
|
DWORD dwWhiteIndex;
|
|
|
|
dwWhiteIndex = (DWORD)iWhiteIndex;
|
|
dwWhiteIndex |= dwWhiteIndex << 8;
|
|
|
|
/*
|
|
* As a speed optimisation, scan the bits in DWORD size clumps.
|
|
* This substantially reduces the number of iterations and memory
|
|
* references required. There will ususally be some trailing
|
|
* bits; these are handled individually - if we get that far.
|
|
*/
|
|
|
|
/* Mask to clear last few bits of scanline, if not full DWORD */
|
|
dwMask = *(pRData->pdwBitMask + (pRData->cBLine % DWBITS));
|
|
if( dwMask == 0 )
|
|
dwMask = (DWORD)~0; /* Size is DWORD multiple */
|
|
|
|
iLines = pRData->iTransHigh;
|
|
|
|
|
|
while( --iLines >= 0 )
|
|
{
|
|
|
|
/* Calculate the starting address for this scan */
|
|
pdwBits = pdwBitsIn;
|
|
|
|
/* pDWLim is the DWORD past the data of interest - not used */
|
|
pdwLim = pdwBits + pRData->cDWLine;
|
|
|
|
/* Clear out undefined bits at end of line */
|
|
*(pdwLim - 1) &= dwMask;
|
|
*(pdwLim - 1) |= ~dwMask & BPP8_WHITE;
|
|
|
|
|
|
/*
|
|
* NOTE: This test is more complex than needed because the
|
|
* engine ignores palette entries when doing BLTs. The WHITENESS
|
|
* rop sets all bits to 1. Hence, we choose to ignore the
|
|
* MSB in the comparison: this means we detect white space
|
|
* with an illegal palette entry. This makes GDI people happy,
|
|
* but not me.
|
|
*/
|
|
while(*pdwBits == dwWhiteIndex && ++pdwBits < pdwLim);
|
|
|
|
if( pdwBits < pdwLim )
|
|
return FALSE;
|
|
|
|
/* Onto the next scan line */
|
|
pdwBitsIn += pRData->cDWLine * pRData->iInterlace;
|
|
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//*******************************************************
|
|
BOOL
|
|
bIs24BPPLineWhite (
|
|
register DWORD *pdwBits,
|
|
RENDER *pRData,
|
|
int iWhiteIndex
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Scan a single row of the bitmap, and return TRUE if it is
|
|
all WHITE, else FALSE. This is used to decide whether a
|
|
band should be sent to the printer.
|
|
|
|
Arguments:
|
|
|
|
pdwBitsIn Pointer to area to scan for white
|
|
pRData Pointer to RENDER structure
|
|
iWhiteIndex White value to compare against
|
|
included here for functional compatibility
|
|
|
|
Return Value:
|
|
|
|
TRUE if entire bitmap is white, else FALSE
|
|
|
|
--*/
|
|
{
|
|
DWORD dwMask; /* Mask to zap the trailing bits */
|
|
LONG iLimit = pRData->cDWLine;
|
|
|
|
/* Mask to clear last few bits of scanline, if not full DWORD */
|
|
dwMask = *(pRData->pdwBitMask + (pRData->cBLine % DWBITS));
|
|
|
|
if( dwMask != 0 )
|
|
{
|
|
/* Clear out undefined bits at end of line */
|
|
pdwBits[iLimit-1] &= dwMask;
|
|
pdwBits[iLimit-1] |= ~dwMask & BPP8_WHITE;
|
|
}
|
|
|
|
/*
|
|
* As a speed optimisation, scan the bits in 4 DWORD size clumps.
|
|
* This substantially reduces the number of iterations and memory
|
|
* references required. First we will test the odd dwords.
|
|
*/
|
|
|
|
while (iLimit & 3)
|
|
{
|
|
iLimit--;
|
|
if (*pdwBits++ != ~0)
|
|
return FALSE;
|
|
}
|
|
iLimit >>= 2;
|
|
while (--iLimit >= 0)
|
|
{
|
|
pdwBits += 4;
|
|
if ((pdwBits[-4] & pdwBits[-3] & pdwBits[-2] & pdwBits[-1]) != BPP8_WHITE)
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//*******************************************************
|
|
BOOL
|
|
bIs1BPPRegionWhite(
|
|
DWORD *pdwBitsIn,
|
|
RENDER *pRData,
|
|
RECTL *pRect
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function scans a specific region of the bitmap and returns
|
|
TRUE if it is all white, else FALSE.
|
|
|
|
Arguments:
|
|
|
|
pdwBitsIn Pointer to area to scan for white
|
|
pRData Pointer to RENDER structure
|
|
pRect Pointer to RECT structure describing the
|
|
region of the bitmap to test for white
|
|
|
|
Return Value:
|
|
|
|
TRUE if region is all white else false
|
|
|
|
--*/
|
|
{
|
|
|
|
DWORD *pdwBits;
|
|
|
|
int iLines; /* Number of scan lines to check */
|
|
int iWords; // number of words to check per line
|
|
|
|
DWORD dwEndMask; /* Mask to zap the trailing bits */
|
|
DWORD dwBegMask; // mask to zap leading bits
|
|
|
|
|
|
/*
|
|
* As a speed optimisation, scan the bits in DWORD size clumps.
|
|
* This substantially reduces the number of iterations and memory
|
|
* references required. There will ususally be some leading and
|
|
* trailing bits which are handled individually
|
|
*/
|
|
|
|
/* Mask to clear last few bits of scanline, if not full DWORD */
|
|
dwEndMask = *(pRData->pdwBitMask + (pRect->right % DWBITS));
|
|
dwBegMask = ~(*(pRData->pdwBitMask + (pRect->left % DWBITS)));
|
|
if( dwEndMask == 0 )
|
|
dwEndMask = (DWORD)~0; /* Size is DWORD multiple */
|
|
|
|
iLines = pRect->bottom - pRect->top;
|
|
|
|
// calculate offset in buffer for top and left offsets
|
|
pdwBitsIn += (pRData->cDWLine * pRect->top) + (pRect->left / DWBITS);
|
|
|
|
// calculate number of words to test
|
|
iWords = ((pRect->right + DWBITS - 1) / DWBITS) - (pRect->left / DWBITS);
|
|
|
|
// if only 1 dword combine begin and end masks
|
|
if (iWords == 0)
|
|
{
|
|
dwBegMask &= dwEndMask;
|
|
}
|
|
iWords--;
|
|
while( --iLines >= 0 )
|
|
{
|
|
|
|
/* Calculate the starting address for this scan */
|
|
pdwBits = pdwBitsIn;
|
|
|
|
//* test beginning dword
|
|
if (~(*pdwBits) & dwBegMask)
|
|
return FALSE;
|
|
|
|
pdwBits++;
|
|
|
|
//* test remaining dwords if necessary
|
|
if (iWords >= 0) {
|
|
if (iWords > 0)
|
|
{
|
|
int iCnt = iWords;
|
|
if (iCnt & 1)
|
|
{
|
|
if (pdwBits[0] != ~0)
|
|
return FALSE;
|
|
pdwBits++;
|
|
}
|
|
if (iCnt & 2)
|
|
{
|
|
if ((pdwBits[0] & pdwBits[1]) != ~0)
|
|
return FALSE;
|
|
pdwBits += 2;
|
|
}
|
|
while ((iCnt -= 4) >= 0)
|
|
{
|
|
if ((pdwBits[0] & pdwBits[1] & pdwBits[2] & pdwBits[3]) != ~0)
|
|
return FALSE;
|
|
pdwBits += 4;
|
|
}
|
|
}
|
|
//* test last dword
|
|
if (~(*pdwBits) & dwEndMask)
|
|
return FALSE;
|
|
}
|
|
/* Onto the next scan line */
|
|
pdwBitsIn += pRData->cDWLine;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//**************************************************
|
|
BOOL
|
|
bIs4BPPRegionWhite(
|
|
DWORD *pdwBitsIn,
|
|
RENDER *pRData,
|
|
RECTL *pRect
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function scans a specific region of the bitmap and returns
|
|
TRUE if it is all white, else FALSE.
|
|
|
|
Arguments:
|
|
|
|
pdwBitsIn Pointer to area to scan for white
|
|
pRData Pointer to RENDER structure
|
|
pRect Pointer to RECT structure describing the
|
|
region of the bitmap to test for white
|
|
|
|
Return Value:
|
|
|
|
TRUE if region is all white else false
|
|
|
|
--*/
|
|
{
|
|
|
|
DWORD *pdwBits;
|
|
|
|
int iLines; /* Number of scan lines to check */
|
|
int iWords; // number of words to check per line
|
|
int iRight;
|
|
int iLeft;
|
|
|
|
DWORD dwEndMask; /* Mask to zap the trailing bits */
|
|
DWORD dwBegMask; // mask to zap leading bits
|
|
|
|
|
|
/*
|
|
* As a speed optimisation, scan the bits in DWORD size clumps.
|
|
* This substantially reduces the number of iterations and memory
|
|
* references required. There will ususally be some leading and
|
|
* trailing bits which are handled individually
|
|
*/
|
|
|
|
//* Adjust horizontal positions by BPP
|
|
iRight = pRect->right * BPP4;
|
|
iLeft = pRect->left * BPP4;
|
|
|
|
//* Mask to clear first and last bits of scanline, if not full DWORD
|
|
//*
|
|
dwEndMask = *(pRData->pdwBitMask + (iRight % DWBITS));
|
|
dwBegMask = ~(*(pRData->pdwBitMask + (iLeft % DWBITS)));
|
|
if( dwEndMask == 0 )
|
|
dwEndMask = (DWORD)~0; /* Size is DWORD multiple */
|
|
|
|
iLines = pRect->bottom - pRect->top;
|
|
|
|
// calculate offset in buffer for top and left offsets
|
|
pdwBitsIn += (pRData->cDWLine * pRect->top) + (iLeft / DWBITS);
|
|
|
|
// calculate number of words to test
|
|
iWords = ((iRight + DWBITS - 1) / DWBITS) - (iLeft / DWBITS);
|
|
|
|
// if only 1 dword combine begin and end masks
|
|
if (iWords == 0)
|
|
dwBegMask &= dwEndMask;
|
|
|
|
//* MSB of each pixel is ignored so combine with pixel mask
|
|
//* see bIsRGBLineWhite for why MSB is ignored
|
|
dwEndMask &= RGB_WHITE;
|
|
dwBegMask &= RGB_WHITE;
|
|
|
|
iWords--;
|
|
while( --iLines >= 0 )
|
|
{
|
|
|
|
/* Calculate the starting address for this scan */
|
|
pdwBits = pdwBitsIn;
|
|
|
|
//* test beginning dword
|
|
if ((*pdwBits & dwBegMask) != dwBegMask)
|
|
return FALSE;
|
|
|
|
pdwBits++;
|
|
|
|
//* test remaining dwords if necessary
|
|
if (iWords >= 0) {
|
|
if (iWords > 0)
|
|
{
|
|
DWORD dwTmp = RGB_WHITE;
|
|
int iCnt = iWords;
|
|
while (iCnt & 3)
|
|
{
|
|
dwTmp &= *pdwBits++;
|
|
iCnt--;
|
|
}
|
|
iCnt >>= 2;
|
|
while (--iCnt >= 0)
|
|
{
|
|
dwTmp &= pdwBits[0];
|
|
dwTmp &= pdwBits[1];
|
|
dwTmp &= pdwBits[2];
|
|
dwTmp &= pdwBits[3];
|
|
pdwBits += 4;
|
|
}
|
|
if (dwTmp != RGB_WHITE)
|
|
return FALSE;
|
|
}
|
|
//* test last dword
|
|
if ((*pdwBits & dwEndMask) != dwEndMask)
|
|
return FALSE;
|
|
}
|
|
/* Onto the next scan line */
|
|
pdwBitsIn += pRData->cDWLine;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//**************************************************
|
|
BOOL
|
|
bIs8BPPRegionWhite(
|
|
DWORD *pdwBitsIn,
|
|
RENDER *pRData,
|
|
RECTL *pRect,
|
|
int iWhiteIndex
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function scans a specific region of the bitmap and returns
|
|
TRUE if it is all white, else FALSE.
|
|
|
|
Arguments:
|
|
|
|
pdwBitsIn Pointer to area to scan for white
|
|
pRData Pointer to RENDER structure
|
|
pRect Pointer to RECT structure describing the
|
|
region of the bitmap to test for white
|
|
|
|
Return Value:
|
|
|
|
TRUE if region is all white else false
|
|
|
|
--*/
|
|
{
|
|
|
|
DWORD *pdwBits;
|
|
|
|
int iLines; /* Number of scan lines to check */
|
|
int iWords; // number of words to check per line
|
|
int iRight;
|
|
int iLeft;
|
|
|
|
DWORD dwEndMask; /* Mask to zap the trailing bits */
|
|
DWORD dwBegMask; // mask to zap leading bits
|
|
|
|
DWORD dwWhiteIndex;
|
|
|
|
//* calculate WhiteIndex for 4 bytes at a time
|
|
dwWhiteIndex = (DWORD)iWhiteIndex;
|
|
dwWhiteIndex |= dwWhiteIndex << 8;
|
|
dwWhiteIndex |= dwWhiteIndex << 16;
|
|
|
|
//* Adjust horizontal positions by BPP
|
|
iRight = pRect->right * BPP8;
|
|
iLeft = pRect->left * BPP8;
|
|
|
|
//* Mask to clear first and last bits of scanline, if not full DWORD
|
|
//*
|
|
dwEndMask = *(pRData->pdwBitMask + (iRight % DWBITS));
|
|
dwBegMask = ~(*(pRData->pdwBitMask + (iLeft % DWBITS)));
|
|
if( dwEndMask == 0 )
|
|
dwEndMask = (DWORD)~0; /* Size is DWORD multiple */
|
|
|
|
iLines = pRect->bottom - pRect->top;
|
|
|
|
// calculate offset in buffer for top and left offsets
|
|
pdwBitsIn += (pRData->cDWLine * pRect->top) + (iLeft / DWBITS);
|
|
|
|
// calculate number of words to test
|
|
iWords = ((iRight + DWBITS - 1) / DWBITS) - (iLeft / DWBITS);
|
|
|
|
// if only 1 dword combine begin and end masks
|
|
if (iWords == 0)
|
|
dwBegMask &= dwEndMask;
|
|
iWords--;
|
|
while( --iLines >= 0 )
|
|
{
|
|
|
|
/* Calculate the starting address for this scan */
|
|
pdwBits = pdwBitsIn;
|
|
|
|
//* test beginning dword
|
|
if ((*pdwBits & dwBegMask) != (dwWhiteIndex & dwBegMask))
|
|
return FALSE;
|
|
|
|
pdwBits++;
|
|
|
|
//* test remaining dwords if necessary
|
|
if (iWords >= 0) {
|
|
if (iWords > 0)
|
|
{
|
|
int iCnt = iWords;
|
|
do {
|
|
if (*pdwBits != dwWhiteIndex)
|
|
return FALSE;
|
|
pdwBits++;
|
|
} while (--iCnt);
|
|
}
|
|
//* test last dword
|
|
if ((*pdwBits & dwEndMask) != (dwWhiteIndex & dwEndMask))
|
|
return FALSE;
|
|
}
|
|
/* Onto the next scan line */
|
|
pdwBitsIn += pRData->cDWLine;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************
|
|
BOOL
|
|
bIs24BPPRegionWhite(
|
|
DWORD *pdwBitsIn,
|
|
RENDER *pRData,
|
|
RECTL *pRect
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function scans a specific region of the bitmap and returns
|
|
TRUE if it is all white, else FALSE.
|
|
|
|
Arguments:
|
|
|
|
pdwBitsIn Pointer to area to scan for white
|
|
pRData Pointer to RENDER structure
|
|
pRect Pointer to RECT structure describing the
|
|
region of the bitmap to test for white
|
|
|
|
Return Value:
|
|
|
|
TRUE if region is all white else false
|
|
|
|
--*/
|
|
{
|
|
|
|
DWORD *pdwBits;
|
|
|
|
int iLines; // Number of scan lines to check */
|
|
int iWords; // number of words to check per line
|
|
int iRight;
|
|
int iLeft;
|
|
|
|
DWORD dwEndMask; // Mask to zap the trailing bits */
|
|
DWORD dwBegMask; // mask to zap leading bits
|
|
|
|
//* Adjust horizontal positions by BPP
|
|
iRight = pRect->right * BPP24;
|
|
iLeft = pRect->left * BPP24;
|
|
|
|
//* Mask to clear first and last bits of scanline, if not full DWORD
|
|
//*
|
|
dwEndMask = *(pRData->pdwBitMask + (iRight % DWBITS));
|
|
dwBegMask = ~(*(pRData->pdwBitMask + (iLeft % DWBITS)));
|
|
if( dwEndMask == 0 )
|
|
dwEndMask = (DWORD)~0; /* Size is DWORD multiple */
|
|
|
|
iLines = pRect->bottom - pRect->top;
|
|
|
|
// calculate offset in buffer for top and left offsets
|
|
pdwBitsIn += (pRData->cDWLine * pRect->top) + (iLeft / DWBITS);
|
|
|
|
// calculate number of words to test
|
|
iWords = ((iRight + DWBITS - 1) / DWBITS) - (iLeft / DWBITS);
|
|
|
|
// if only 1 dword combine begin and end masks
|
|
if (iWords == 0)
|
|
dwBegMask &= dwEndMask;
|
|
|
|
iWords--;
|
|
while( --iLines >= 0 )
|
|
{
|
|
|
|
/* Calculate the starting address for this scan */
|
|
pdwBits = pdwBitsIn;
|
|
|
|
//* test beginning dword
|
|
if ((*pdwBits & dwBegMask) != dwBegMask)
|
|
return FALSE;
|
|
|
|
pdwBits++;
|
|
|
|
//* test remaining dwords if necessary
|
|
if (iWords >= 0) {
|
|
if (iWords > 0)
|
|
{
|
|
int iCnt = iWords;
|
|
while (iCnt & 3)
|
|
{
|
|
if (*pdwBits != ~0)
|
|
return FALSE;
|
|
pdwBits++;
|
|
iCnt--;
|
|
}
|
|
iCnt >>= 2;
|
|
while (--iCnt >= 0)
|
|
{
|
|
if ((pdwBits[0] & pdwBits[1] & pdwBits[2] & pdwBits[3]) != ~0)
|
|
return FALSE;
|
|
pdwBits += 4;
|
|
}
|
|
}
|
|
//* test last dword
|
|
if ((*pdwBits & dwEndMask) != dwEndMask)
|
|
return FALSE;
|
|
}
|
|
/* Onto the next scan line */
|
|
pdwBitsIn += pRData->cDWLine;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//*********************************************************
|
|
BOOL
|
|
bIsRegionWhite(
|
|
SURFOBJ *pso,
|
|
RECTL *pRect
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine determines whether a given region of the
|
|
shadow bitmap is white.
|
|
|
|
Arguments:
|
|
|
|
pPDev - Pointer to PDEV.
|
|
pRect - Pointer to clip window within shadow bitmap
|
|
|
|
Return Value:
|
|
|
|
TRUE - for success
|
|
FALSE - for failure
|
|
|
|
Note:
|
|
01-07-97: Created by alvins
|
|
--*/
|
|
|
|
{
|
|
PDEV *pPDev = (PDEV *)pso->dhpdev;
|
|
PRASTERPDEV pRPDev = (PRASTERPDEV)pPDev->pRasterPDEV;
|
|
RENDER *pRD;
|
|
RECTL Rectl;
|
|
int y1,y2;
|
|
|
|
// If the render structure hasn't been initialize how can
|
|
// there have been data drawn in it. Also check the dirty flag
|
|
if (!(pPDev->fMode & PF_SURFACE_USED) || pRPDev == NULL)
|
|
return TRUE;
|
|
|
|
pRD = pRPDev->pvRenderData;
|
|
if (pRD == NULL)
|
|
return TRUE;
|
|
|
|
// lets make sure these values are positive
|
|
// and there's still something to test
|
|
//
|
|
Rectl.left = pRect->left > 0 ? pRect->left : 0;
|
|
Rectl.top = pRect->top > 0 ? pRect->top : 0;
|
|
Rectl.right = pRect->right > 0 ? pRect->right : 0;
|
|
Rectl.bottom = pRect->bottom > 0 ? pRect->bottom : 0;
|
|
|
|
if (Rectl.left == Rectl.right || Rectl.top == Rectl.bottom)
|
|
return TRUE;
|
|
|
|
// if not surface then also assume all white
|
|
if (pso->iType != STYPE_BITMAP)
|
|
return TRUE;
|
|
|
|
// need to actually check data at this point
|
|
y1 = Rectl.top / LINESPERBLOCK;
|
|
y2 = (Rectl.bottom-1) / LINESPERBLOCK;
|
|
while (y1 <= y2)
|
|
{
|
|
RECTL tRectl = Rectl;
|
|
|
|
if (pPDev->pbRasterScanBuf == NULL || pPDev->pbRasterScanBuf[y1])
|
|
{
|
|
// test a block at a time if we've block erased the surface
|
|
//
|
|
if (pPDev->pbRasterScanBuf)
|
|
{
|
|
if ((y1*LINESPERBLOCK) > tRectl.top)
|
|
tRectl.top = y1 * LINESPERBLOCK;
|
|
y1++;
|
|
if ((y1*LINESPERBLOCK) < tRectl.bottom)
|
|
tRectl.bottom = y1 * LINESPERBLOCK;
|
|
}
|
|
// surface is not block erased so make this last loop
|
|
//
|
|
else
|
|
y1 = y2+1;
|
|
|
|
switch (pRD->iBPP)
|
|
{
|
|
case 1:
|
|
if (!bIs1BPPRegionWhite(pso->pvBits,pRD,&tRectl))
|
|
return FALSE;
|
|
break;
|
|
case 4:
|
|
if (!bIs4BPPRegionWhite(pso->pvBits,pRD,&tRectl))
|
|
return FALSE;
|
|
break;
|
|
case 8:
|
|
if (!bIs8BPPRegionWhite(pso->pvBits,pRD,&tRectl,pRPDev->pPalData->iWhiteIndex))
|
|
return FALSE;
|
|
break;
|
|
case 24:
|
|
if (!bIs24BPPRegionWhite(pso->pvBits,pRD,&tRectl))
|
|
return FALSE;
|
|
break;
|
|
// if I don't recognize the format, I'll assume its empty
|
|
default:
|
|
return TRUE;
|
|
}
|
|
}
|
|
else
|
|
y1++;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//*******************************************************
|
|
BOOL
|
|
bIsNeverWhite (
|
|
register DWORD *pdwBits,
|
|
RENDER *pRData,
|
|
int iWhiteIndex
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function always returns FALSE and exists only to provide
|
|
a common function call format for all the IsWhite Line/Band
|
|
functions.
|
|
|
|
Arguments:
|
|
|
|
pdwBitsIn Pointer to area to scan for white
|
|
pRData Pointer to RENDER structure
|
|
iWhiteIndex White value to compare against
|
|
|
|
Return Value:
|
|
|
|
FALSE
|
|
|
|
--*/
|
|
{
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//******************************************************
|
|
int
|
|
iStripBlanks(
|
|
BYTE *pbOut,
|
|
BYTE *pbIn,
|
|
int iLeft,
|
|
int iRight,
|
|
int iHeight,
|
|
int iWidth
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function strips already identified white space
|
|
from the buffer.
|
|
|
|
Arguments:
|
|
|
|
pbOut Pointer to output buffer
|
|
pbIn Pointer source buffer
|
|
iLeft First non-white leading byte
|
|
iRight First white trailing byte
|
|
iHeight Number of scanlines
|
|
iWidth Width of source scanlines
|
|
|
|
Return Value:
|
|
|
|
Number of bytes in new buffer
|
|
|
|
--*/
|
|
{
|
|
int i,j;
|
|
BYTE * pbSrc;
|
|
BYTE * pbTgt;
|
|
int iDelta;
|
|
|
|
iDelta = iRight - iLeft;
|
|
pbTgt = pbOut;
|
|
pbSrc = pbIn+iLeft;
|
|
for (i = 0; i < iHeight; i++)
|
|
{
|
|
CopyMemory(pbTgt,pbSrc,iDelta);
|
|
pbTgt += iDelta;
|
|
pbSrc += iWidth;
|
|
}
|
|
return (iDelta * iHeight);
|
|
}
|