Legacy Print driver is fuzzy

三世轮回 提交于 2020-04-17 22:40:45

问题


We have an old Print driver which takes a document and sends PCL to the spooler. The client then processes this PCL and displays everything as TIFF. Our users have been complaining that the TIFF is fuzzy and the image is not sharp. I am given this stupid task of solving the mystery

Is the PCL itself bad. I don't have enough knowledge about a PCL and if it has resolution. How do I trap the output of a driver that's being sent to the spooler? Or is it the client that is somehow not rendering the PCL with a good resolution. Do I need to go through the pain of learning how to debug this driver. I will but is it going to help me fix a resolution issue. I have never done driver development so its going to be a curve for me. But if I need to do then thats ok. Where should I start? Is the PCL thats bad or the client that converts PCL to bitmap bad?

This is the C++ code

    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 encoding (I have not had a chance to add this yet). I was looking at different forums as how the code should like and this is what I came up with. I will add, test the document and update the post

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

This is how fuzzy the users claim that the image looks. This is when printed from a word document to the driver. The original is very clear.

来源:https://stackoverflow.com/questions/61125988/legacy-print-driver-is-fuzzy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!