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.
160 lines
4.1 KiB
160 lines
4.1 KiB
/*
|
|
* drc.c - Support Delta Row Compression
|
|
*/
|
|
|
|
#include "pdev.h"
|
|
|
|
|
|
// Support DRC
|
|
|
|
/*
|
|
* PutDRCData
|
|
*/
|
|
static PBYTE
|
|
PutDRCData(
|
|
PBYTE pData,
|
|
DWORD dwOffset,
|
|
DWORD dwSize,
|
|
PBYTE pOut,
|
|
PBYTE pOutEnd)
|
|
{
|
|
DWORD dwCount, dwOff;
|
|
|
|
while (dwSize > 0) {
|
|
dwCount = min(dwSize, 8);
|
|
// offset
|
|
if (dwOffset > 30) {
|
|
if (pOut >= pOutEnd)
|
|
return NULL;
|
|
*pOut++ = (BYTE)(((dwCount - 1) << 5) + 31);
|
|
dwOffset -= 31;
|
|
while (dwOffset >= 255) {
|
|
dwOff = min(dwOffset, 255);
|
|
if (pOut >= pOutEnd)
|
|
return NULL;
|
|
*pOut++ = (BYTE)dwOff;
|
|
dwOffset -= dwOff;
|
|
}
|
|
if (pOut >= pOutEnd)
|
|
return NULL;
|
|
*pOut++ = (BYTE)dwOffset;
|
|
} else {
|
|
if (pOut >= pOutEnd)
|
|
return NULL;
|
|
*pOut++ = (BYTE)(((dwCount - 1) << 5) + dwOffset);
|
|
}
|
|
dwOffset = 0;
|
|
|
|
// data
|
|
if (&pOut[dwCount] >= pOutEnd)
|
|
return NULL;
|
|
CopyMemory(pOut, pData, dwCount);
|
|
pOut += dwCount;
|
|
pData += dwCount;
|
|
dwSize -= dwCount;
|
|
}
|
|
|
|
return pOut;
|
|
}
|
|
|
|
/*
|
|
* OEMCompression
|
|
*/
|
|
INT APIENTRY
|
|
OEMCompression(
|
|
PDEVOBJ pdevobj,
|
|
PBYTE pInBuf,
|
|
PBYTE pOutBuf,
|
|
DWORD dwInLen,
|
|
DWORD dwOutLen)
|
|
{
|
|
PLIPSPDEV pOEM = (PLIPSPDEV)pdevobj->pdevOEM;
|
|
PBYTE pPre, pIn, pInEnd, pOut, pOutEnd, pStart, pBegin;
|
|
PBYTE pPre0, pIn0, pOutHead, pOut0, pOutEnd0;
|
|
DWORD dwI, dwLen, dwSize, dwOffset, dwCount;
|
|
INT rc;
|
|
|
|
#ifdef LBP_2030
|
|
if (pOEM->fcolor == COLOR) // DRC can't support on 8color mode.
|
|
return -1;
|
|
#endif
|
|
// NTRAID#NTBUG9-571824-2002/03/09-yasuho-:
|
|
// Possible buffer overrun if integer overflow was occured.
|
|
if (pOEM->dwBmpWidth == 0 || pOEM->dwBmpHeight == 0 ||
|
|
pOEM->dwBmpWidth > dwInLen || pOEM->dwBmpHeight > dwInLen ||
|
|
(pOEM->dwBmpWidth * pOEM->dwBmpHeight) != dwInLen)
|
|
return -1;
|
|
|
|
// Do DRC compression
|
|
rc = -1;
|
|
pPre = NULL;
|
|
pIn = pInBuf;
|
|
pOut = pOutBuf;
|
|
pOutEnd = &pOut[dwOutLen];
|
|
|
|
for (dwI = 0; dwI < pOEM->dwBmpHeight; dwI++) {
|
|
pStart = pBegin = pIn;
|
|
pInEnd = &pIn[pOEM->dwBmpWidth];
|
|
pOutHead = pOut;
|
|
while (pIn < pInEnd) {
|
|
if (pPre == NULL) {
|
|
if (*pIn == 0) {
|
|
pIn++;
|
|
continue;
|
|
}
|
|
} else if (*pPre == *pIn) {
|
|
pPre++, pIn++;
|
|
continue;
|
|
}
|
|
pIn0 = pIn;
|
|
if (pPre == NULL) {
|
|
do {
|
|
pIn++;
|
|
} while (pIn < pInEnd && *pIn);
|
|
} else {
|
|
do {
|
|
pPre++, pIn++;
|
|
} while (pIn < pInEnd && *pPre != *pIn);
|
|
}
|
|
dwOffset = (DWORD)(pIn0 - pStart);
|
|
dwSize = (DWORD)(pIn - pIn0);
|
|
if (!(pOut = PutDRCData(pIn0, dwOffset, dwSize, pOut, pOutEnd)))
|
|
goto out;
|
|
pStart = pIn;
|
|
}
|
|
|
|
// Insert length of raster data
|
|
if (pOut == pOutHead) {
|
|
// identical
|
|
if (pOut >= pOutEnd)
|
|
goto out;
|
|
*pOut++ = 0;
|
|
} else {
|
|
dwSize = (DWORD)(pOut - pOutHead);
|
|
dwCount = (dwSize / 255) + 1;
|
|
if (&pOut[dwCount] >= pOutEnd)
|
|
goto out;
|
|
pPre0 = pOut;
|
|
pOut0 = pOut = &pOut[dwCount];
|
|
while (pPre0 >= pOutHead)
|
|
*--pOut0 = *--pPre0;
|
|
pOut0 = pOutHead;
|
|
while (dwSize >= 255) {
|
|
dwLen = min(dwSize, 255);
|
|
*pOut0++ = (BYTE)dwLen;
|
|
dwSize -= dwLen;
|
|
}
|
|
*pOut0++ = (BYTE)dwSize;
|
|
}
|
|
|
|
// set to previous raster
|
|
pPre = pBegin;
|
|
}
|
|
|
|
rc = (INT)(pOut - pOutBuf);
|
|
|
|
out:
|
|
return rc;
|
|
}
|
|
|
|
|