none
Unidrv - Preanalysis - Access to image RRS feed

  • Question

  • In my printer driver, I require information about my image that should use all bands, so I am trying to get preanalysis to work.

    I am expecting a 24bit bitmap as input.

    I am trying, for now, to output to disk the input image for debug purposes. 

    The problem: the image is black.

    What I am trying:

    BOOL APIENTRY OEMStartBanding(SURFOBJ *pso, POINTL *pptl)
    {
    	TRACEIN;
    
    	PDEVOBJ pDevObj = (PDEVOBJ)pso->dhpdev;
    	POEMPDEV pOemPDEV = (POEMPDEV)pDevObj->pdevOEM;
    
    	if (pptl == NULL)
    	{
    		VERBOSE(TEXT("OEMStartBanding: Start of OEM Pre-analysis pass...\r\n"));
    		VERBOSE(TEXT("OEM Pre-analysis pass...no drawing on surface in this pass.\r\n"));
    		pOemPDEV->bPreAnalysis = TRUE;
    	}
    
    	BOOL bRet = (pOemPDEV->m_pfnDrvStartBanding)(pso, pptl);
    
            // This call either here or in OEMNextBand
    	//if (pOemPDEV->bPreAnalysis)
    	//{
    	//	debugPrintPreanalysis(pso, pDevObj, pOemPDEV);
    	//}
    
    	TRACEOUT;
    
    	return bRet;
    }
    
    BOOL APIENTRY OEMNextBand(SURFOBJ *pso, POINTL *pptl)
    {
    	TRACEIN;
    
    	PDEVOBJ pDevObj = (PDEVOBJ)pso->dhpdev;
    	POEMPDEV pOemPDEV = (POEMPDEV)pDevObj->pdevOEM;	
    
    	if (pOemPDEV->bPreAnalysis)
    	{
    		debugPrintPreanalysis(pso, pDevObj, pOemPDEV);
    
    		// First call into OEMNextBand indicates end of pre-analysis path.
    		VERBOSE(TEXT("OEMNextBand: End of OEM Pre-analysis pass...\r\n"));
    		pOemPDEV->bPreAnalysis = false;
    	}
    
    	BOOL bRet = (pOemPDEV->m_pfnDrvNextBand)(pso, pptl);		
    	
    	TRACEOUT;
    
    	return bRet;
    }

    void debugPrintPreanalysis(SURFOBJ *pso, PDEVOBJ pDevObj, POEMPDEV pOemPDEV) { VERBOSE(TEXT("Preanalysis: Bitmap size: %d, %d\r\n"), pso->sizlBitmap.cx, pso->sizlBitmap.cy); if (pso->iType == STYPE_BITMAP) { VERBOSE(TEXT("Preanalysis Standard bitmap surface, format = %d\r\n"), pso->iBitmapFormat); VERBOSE(TEXT("Preanalysis Stride = %d And we have image (T/F) %d\r\n"), pso->lDelta, (pso->pvBits != NULL)); PDEVMODE pPubDev = (PDEVMODE)pDevObj->pPublicDM;

    // Create and populate BITMAPINFOHEADER BITMAPINFOHEADER pBitmapInfoHeader; pBitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);

    // I seem to have to switch width and height in pPubDev to match the info from ImageProcessing, in landscape
    // Also, I have to use public sizes because pso->sizlBitmap seems to hold the band size not entire image size

    //pBitmapInfoHeader.biWidth = (int)(pPubDev->dmPaperLength / 2.54) * pPubDev->dmYResolution / 100; //pBitmapInfoHeader.biHeight = (int)(pPubDev->dmPaperWidth / 2.54) * pPubDev->dmPrintQuality / 100;

    // Using the size in pso->sizlBitmap because otherwise I get an error saving the image - but it is clearly a single band

    pBitmapInfoHeader.biWidth = pso->sizlBitmap.cx;
    pBitmapInfoHeader.biHeight = pso->sizlBitmap.cy;

    pBitmapInfoHeader.biPlanes = 1; pBitmapInfoHeader.biBitCount = 24; pBitmapInfoHeader.biCompression = BI_RGB; pBitmapInfoHeader.biSizeImage = 0; pBitmapInfoHeader.biXPelsPerMeter = pPubDev->dmPrintQuality; pBitmapInfoHeader.biYPelsPerMeter = pPubDev->dmYResolution; pBitmapInfoHeader.biClrUsed = 0; pBitmapInfoHeader.biClrImportant = 0; VERBOSE(TEXT("Preanalysis: pBitmapInfoHeader.biWidth=%d, pBitmapInfoHeader.biHeight=%d\r\n\r\n"), pBitmapInfoHeader.biWidth, pBitmapInfoHeader.biHeight); #ifndef USE_HBITMAP_TO_OUTPUT_BITMAP

    // Same function I call in ImageProcessing to check my input - it works fine there BitmapOperations::createBMPFile24(pOemPDEV, reinterpret_cast<PBYTE>(pso->pvBits), pBitmapInfoHeader, TEXT("prean-input")); #else // Alternate experiment to use EngCreateBitmap HBITMAP bitmap = EngCreateBitmap(pso->sizlBitmap, pso->lDelta, pso->iBitmapFormat, BMF_TOPDOWN, pso->pvBits); BitmapOperations::createBMPFile24(pOemPDEV, bitmap, pBitmapInfoHeader, TEXT("prean-input")); #endif } else { VERBOSE(TEXT("Preanalysis Surface type %d\r\n"), pso->iType); } }


    In gpd

    *PreAnalysisOptions: 8


    The bitmap saved to disk is always empty. I thought I would have access to it during pre-analysis ?

    What am I doing wrong ?




    • Edited by Mihaela.G Wednesday, June 5, 2019 2:46 PM
    Tuesday, June 4, 2019 3:00 PM

Answers

  • The sample has an OEMCopyBits handler, as well handlers for many of the low-level GDI driver calls.  OEMCopyBits handles any calls to copy bitmaps from one surface to another, where one of the two is your surface.  Thus, if the app does a BitBlt or StretchDIBitsToDevice to send a bitmap to the page, it should get to you as OEMCopyBits.  It's worth a try.  Note that the result will not appear on YOUR surface; you would see the app's bitmap as the source surface.  You'll have to check its format to make sure you understand it.

    Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

    • Marked as answer by Mihaela.G Friday, June 7, 2019 3:56 PM
    Thursday, June 6, 2019 4:51 PM

All replies

  • The comments in the code say that the pre-analysis phase doesn't actually do any drawing.  The driver is given a chance to see what drawing calls will be coming, but you don't touch the surface, so the bits will remain zero.

    Can you learn what you need to learn by monitoring the calls to CopyBits?  I expect that's what you'd mostly get.


    Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

    Thursday, June 6, 2019 12:10 AM
  • Thank you for the reply 

    I may be able to - how do I do that ?

    I expected the surface to contain the image sent from the application, expected to be a 24 bpp bitmap.

    I would be happy with read-only access to this image.

    • Edited by Mihaela.G Thursday, June 6, 2019 1:52 PM
    Thursday, June 6, 2019 1:47 PM
  • The sample has an OEMCopyBits handler, as well handlers for many of the low-level GDI driver calls.  OEMCopyBits handles any calls to copy bitmaps from one surface to another, where one of the two is your surface.  Thus, if the app does a BitBlt or StretchDIBitsToDevice to send a bitmap to the page, it should get to you as OEMCopyBits.  It's worth a try.  Note that the result will not appear on YOUR surface; you would see the app's bitmap as the source surface.  You'll have to check its format to make sure you understand it.

    Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

    • Marked as answer by Mihaela.G Friday, June 7, 2019 3:56 PM
    Thursday, June 6, 2019 4:51 PM
  • This is so great, thank you, I have been confused on how these functions are being used, and how pre-analysis really works. Your suggestions helped me understand it.

    The OEMStretchBlt function is being called in all examples of applications I tried, and I am working my way into getting useful information from it.

    I am still wondering if all applications use the same function - pre-analysis will not be very useful if I use one function and the application is calling a different one. Some applications seem to use other functions as well, prior to OEMStretchBlt . I wonder if I can rely on OEMStretchBlt  - the application seems to be requesting some drawing application, but perhaps the ColorMode option in the gpd, or something else, decides on the bitmap copying function. 

    • Edited by Mihaela.G Monday, June 10, 2019 3:23 PM better explanation
    Friday, June 7, 2019 3:56 PM