c++ - 旧版打印驱动程序模糊
问题描述
我们有一个旧的打印驱动程序,它接收一个文档并将 PCL 发送到假脱机程序。然后客户端处理此 PCL 并将所有内容显示为 TIFF。我们的用户一直抱怨 TIFF 模糊且图像不清晰。我被赋予了解谜这个愚蠢的任务
PCL本身是不是坏了。我对 PCL 以及它是否有分辨率没有足够的了解。如何捕获发送到假脱机程序的驱动程序的输出?还是客户端以某种方式无法以良好的分辨率呈现 PCL。我是否需要经历学习如何调试此驱动程序的痛苦。我会,但它会帮助我解决分辨率问题吗?我从来没有做过驱动程序开发,所以它对我来说将是一个曲线。但如果我需要这样做,那没关系。我应该从哪里开始?是 PCL 不好还是将 PCL 转换为位图的客户端不好?
这是 C++ 代码
BOOL APIENTRY
CreatePCLRasterGraphicPage(
SURFOBJ *pso,
BOOL firstPage,
char *pageText
)
/*++
Routine Description:
Creates standard PCL end-of-document lines.
Arguments:
SURFOBJ - Surface Object
BOOL - First Page ?
char * Page Text
Return Value:
BOOL - True if successful
--*/
{
PDEVOBJ pDevObj = (PDEVOBJ)pso->dhpdev;
POEMPDEV pOemPDEV = (POEMPDEV)pDevObj->pdevOEM;
DWORD dwOffset = 0;
DWORD dwWritten = 0;
DWORD dwPageBufferSize = 0;
int i = 0;
ULONG n = 0;
BYTE bitmapRow[1050];
BYTE compRow[2100];
DWORD dwRowSize = 0;
DWORD dwCompPCLBitmapSize = 0;
//wchar_t traceBuff[256];
pOemPDEV->dwCompBitmapBufSize = 0;
// TRACE OUT ----------------------------------------------------
//ZeroMemory(traceBuff, 256);
//StringCchPrintf(traceBuff, 256, L"Top of CreatePCLRasterGraphicPage");
//WriteTraceLine(traceBuff);
// -----------------------------------------------------------------
// Invert color
for (n = 0; n < pso->cjBits; n++)
*(((PBYTE &)pso->pvBits) + n) ^= 0xFF;
// compress each row and store in a buffer with PCL line headings
for (i = 0; i < pso->sizlBitmap.cy; i++) {
// Zero Memory hack for bottom of form black line
if (*(((PBYTE &)pso->pvScan0) + (i * pso->lDelta) + 319) == 0xFF)
ZeroMemory(((PBYTE &)pso->pvScan0) + (i * pso->lDelta), 320);
// Copy the bitmap scan line into bitmapRow and send them off to be compressed
ZeroMemory(bitmapRow, 1050);
ZeroMemory(compRow, 2100);
MoveMemory(bitmapRow, ((PBYTE &)pso->pvScan0) + (i * pso->lDelta), pso->lDelta);
dwRowSize = CompressBitmapRow(compRow, bitmapRow, pso->lDelta);
// Create PCL Row Heading
char bufPCLLineHead[9];
StringCchPrintfA(bufPCLLineHead, 9, "%c%s%d%s", 27, "*b", dwRowSize, "W");
if ((dwCompPCLBitmapSize + dwRowSize + strlen(bufPCLLineHead))
> pOemPDEV->dwCompBitmapBufSize) {
if (!GrowCompBitmapBuf(pOemPDEV)) {
//ZeroMemory(traceBuff, 256);
//StringCchPrintf(traceBuff, 256,
// L"Compressed bitmap buffer could not allocate more memory.");
//WriteTraceLine(traceBuff);
}
}
if (pOemPDEV->pCompBitmapBufStart) {
// write the PCL line heading to the buffer
MoveMemory(pOemPDEV->pCompBitmapBufStart + dwCompPCLBitmapSize,
bufPCLLineHead, strlen(bufPCLLineHead));
dwCompPCLBitmapSize += strlen(bufPCLLineHead);
// write the compressed row to the buffer
MoveMemory(pOemPDEV->pCompBitmapBufStart + dwCompPCLBitmapSize,
compRow, dwRowSize);
dwCompPCLBitmapSize += dwRowSize;
}
}
// Calculate size and create buffer
dwPageBufferSize = 21;
if (!firstPage)
dwPageBufferSize++;
bGrowBuffer(pOemPDEV, dwPageBufferSize);
// Add all Raster Header Lines
if (!firstPage)
{
// Add a Form Feed
char bufFormFeed[2];
StringCchPrintfA(bufFormFeed, 2, "%c", 12); // 1 char
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufFormFeed, 2);
dwOffset += 1;
}
// Position cursor at X0, Y0
char bufXY[8];
StringCchPrintfA(bufXY, 8, "%c%s", 27, "*p0x0Y"); // 7 chars
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufXY, 8);
dwOffset += 7;
// Start Raster Graphics
char bufStartRas[6];
StringCchPrintfA(bufStartRas, 6, "%c%s", 27, "*r1A"); // 5 chars
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufStartRas, 6);
dwOffset += 5;
// Raster Encoding - Run-Length Encoding
char bufRasEncoding[6];
StringCchPrintfA(bufRasEncoding, 6, "%c%s", 27, "*b1M"); // 5 chars
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufRasEncoding, 6);
dwOffset += 5;
// Write out bitmap header PCL
dwWritten = pDevObj->pDrvProcs->DrvWriteSpoolBuf(pDevObj, pOemPDEV->pBufStart, dwPageBufferSize);
// Write out PCL plus compressed bitmap bytes
dwWritten = pDevObj->pDrvProcs->DrvWriteSpoolBuf(pDevObj, pOemPDEV->pCompBitmapBufStart, dwCompPCLBitmapSize);
// End Raster Graphics
char bufEndRas[5];
StringCchPrintfA(bufEndRas, 5, "%c%s", 27, "*rB"); // 4 chars
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufEndRas, 5);
// Write out PCL end bitmap
dwWritten = pDevObj->pDrvProcs->DrvWriteSpoolBuf(pDevObj, bufEndRas, 4);
// Free Compressed Bitmap Memory
if (pOemPDEV->pCompBitmapBufStart) {
MemFree(pOemPDEV->pCompBitmapBufStart);
pOemPDEV->pCompBitmapBufStart = NULL;
pOemPDEV->dwCompBitmapBufSize = 0;
dwPageBufferSize = 0;
}
// Free Memory
vFreeBuffer(pOemPDEV);
// Write Page Text to the spooler
size_t charCount = 0;
StringCchLengthA(pageText, 32767, &charCount);
char bufWriteText[15];
ZeroMemory(bufWriteText, 15);
StringCchPrintfA(bufWriteText, 15, "%c%s%d%s", 27, "(r", charCount, "W");
dwWritten = pDevObj->pDrvProcs->DrvWriteSpoolBuf(pDevObj, bufWriteText, strlen(bufWriteText));
dwWritten = pDevObj->pDrvProcs->DrvWriteSpoolBuf(pDevObj, pageText, charCount);
return TRUE;
}
BOOL
GrowCompBitmapBuf(
POEMPDEV pOemPDEV
)
/*++
Routine Description:
Grows memory by 1000 bytes (per call) to hold compressed
bitmap and PCL data.
Arguments:
POEMPDEV - Pointer to the private PDEV structure
Return Value:
BOOL - True is successful
--*/
{
DWORD dwOldBufferSize = 0;
PBYTE pNewBuffer = NULL;
dwOldBufferSize = pOemPDEV->pCompBitmapBufStart ? pOemPDEV->dwCompBitmapBufSize : 0;
pOemPDEV->dwCompBitmapBufSize = dwOldBufferSize + 4096;
pNewBuffer = (PBYTE)MemAlloc(pOemPDEV->dwCompBitmapBufSize);
if (pNewBuffer == NULL) {
MemFree(pOemPDEV->pCompBitmapBufStart);
pOemPDEV->pCompBitmapBufStart = NULL;
pOemPDEV->dwCompBitmapBufSize = 0;
return FALSE;
}
if (pOemPDEV->pCompBitmapBufStart) {
CopyMemory(pNewBuffer, pOemPDEV->pCompBitmapBufStart, dwOldBufferSize);
MemFree(pOemPDEV->pCompBitmapBufStart);
pOemPDEV->pCompBitmapBufStart = pNewBuffer;
}
else {
pOemPDEV->pCompBitmapBufStart = pNewBuffer;
}
return TRUE;
}
RLE 编码(我还没有机会添加它)。我正在查看不同的论坛作为代码应该如何,这就是我想出的。我将添加、测试文档并更新帖子
public virtual sbyte[] decompressRL(sbyte[] data, int startOffset, int width, int count)
{
/*type 1 compression*/
int dataCount = count;
List<sbyte> decompressed = new List<sbyte>();
int numberOfDecompressedBytes = 0;
int dataStartOffset = startOffset;
while (dataCount-- > 0)
{
int cntrlByte = (int) data[dataStartOffset++];
// Repeated pattern
int val = data[dataStartOffset++];
dataCount--;
while (cntrlByte >= 0)
{
decompressed.Insert(numberOfDecompressedBytes++, new sbyte?((sbyte) val));
cntrlByte--;
}
}
mMaxUncompressedByteCount = numberOfDecompressedBytes;
return getBytes(decompressed);
}
解决方案
推荐阅读
- javascript - React 组件状态未使用传递的道具更新
- angular-material - 默认情况下,如何在 Angular Material 中的菜单图标对话框按钮上自动对焦?
- python - pandas 相当于 sql UPDATE 表 SET col3 = NULL WHERE col1 != col2
- angular - 在模板中输入对象会在 Angular 10 中给出错误“属性在其初始化之前使用”
- r - 对数后的逻辑回归参数 P 值变化 - R
- angular - Angular 材质:Mat-select put formgroup 作为值
- telegram - 获取电报中的用户ID
- java - 我在整个项目中使用了 LocalDate,现在我需要 LocalDateTime 来实现功能,该怎么办?
- android - android kotlin:将检索到的数据从 url 存储到房间数据库
- c# - 在 Docker 容器中部署后导出后未显示 C# 文件