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