Microsoft KB Archive/230492: Difference between revisions

From BetaArchive Wiki
m (Text replacement - "&" to "&")
m (Text replacement - """ to """)
 
Line 62: Line 62:
   pbi - Contains the optimal DIB format. In the  
   pbi - Contains the optimal DIB format. In the  
         <= 8bpp case, the color table will contain the  
         <= 8bpp case, the color table will contain the  
         system palette. In the >=16bpp case, the &quot;color  
         system palette. In the >=16bpp case, the "color  
         table&quot; will contain the correct bit fields (see  
         table" will contain the correct bit fields (see  
         BI_BITFIELDS in the Platform SDK documentation  
         BI_BITFIELDS in the Platform SDK documentation  
         for more information).
         for more information).

Latest revision as of 13:44, 21 July 2020

HOWTO: Retrieving an Optimal DIB Format for a Device

Q230492



The information in this article applies to:


  • Microsoft Win32 Application Programming Interface (API)
  • Microsoft Windows 2000 Advanced Server
  • Microsoft Windows 2000 Server
  • Microsoft Windows 2000 Professional





SUMMARY

When writing applications that demand the highest possible performance from blt'ing operations that transfer from a DIB surface to a target device, it is extremely important to ensure that the attributes of source surface exactly match those of the destination device. If the attributes do not match, then a performance-consuming translation will occur when using such operations as BitBlt().

This article demonstrates a simple method for obtaining the attributes that describe the surface of a device. This surface information can be used with the CreateDIBSection() API to allow you to create a DIB surface that optimally matches the target device.



MORE INFORMATION

GetOptimalDIBFormat demonstrates how to retrieve the optimal format for a display device. GetRGBBitsPerPixel demonstrates how to call GetOptimalDIBFormat to derive the number of unique shades of red, green, and blue that can be represented on a surface.

Sample Code

/**********************************************************

GetOptimalDIBFormat

  Purpose:
   Retrieves the optimal DIB format for a display 
   device. The optimal DIB format is the format that 
   exactly matches the format of the target device. 
   Obtaining this is very important when dealing with 
   16bpp modes because you need to know what bitfields 
   value to use (555 or 565 for example).

   You normally use this function to get the best
   format to pass to CreateDIBSection() in order to
   maximize blt'ing performance.

  Input:
   hdc - Device to get the optimal format for.
   pbi - Pointer to a BITMAPINFO + color table
         (room for 256 colors is assumed).

  Output:
   pbi - Contains the optimal DIB format. In the 
         <= 8bpp case, the color table will contain the 
         system palette. In the >=16bpp case, the "color 
         table" will contain the correct bit fields (see 
         BI_BITFIELDS in the Platform SDK documentation 
         for more information).

  Notes:
   If you are going to use this function on a 8bpp device
   you should make sure the color table contains a identity
   palette for optimal blt'ing.

**********************************************************/ 
BOOL GetOptimalDIBFormat(HDC hdc, BITMAPINFOHEADER *pbi)
{
    HBITMAP hbm;
    BOOL bRet = TRUE;
    
    // Create a memory bitmap that is compatible with the
    // format of the target device.
    hbm = CreateCompatibleBitmap(hdc, 1, 1);
    if (!hbm)
        return FALSE;
    
    // Initialize the header.
    ZeroMemory(pbi, sizeof(BITMAPINFOHEADER));
    pbi->biSize = sizeof(BITMAPINFOHEADER);

    // First call to GetDIBits will fill in the optimal biBitCount.
    bRet = GetDIBits(hdc, hbm, 0, 1, NULL, (BITMAPINFO*)pbi, DIB_RGB_COLORS);
    
    // Second call to GetDIBits will get the optimal color table, o
    // or the optimal bitfields values.
    if (bRet)
        bRet = GetDIBits(hdc, hbm, 0, 1, NULL, (BITMAPINFO*)pbi, DIB_RGB_COLORS);
    
    // Clean up.
    DeleteObject(hbm);

    return bRet;
}

// Counts the number of set bits in a DWORD.
BYTE CountBits(DWORD dw)
{
    int iBits = 0;
    
    while (dw) {
        iBits += (dw & 1);
        dw >>= 1;
    }
    
    return iBits;
}

/**********************************************************

GetRGBBitsPerPixel

  Purpose:
   Retrieves the number of bits of color resolution for each 
   color channel of a specified.

  Input:
   hdc - Device to get the color information for.
   
  Output:
   pRed   - Number of distinct red levels the device can display.
   pGreen - Number of distinct green levels the device can display.
   pBlue  - Number of distinct blue levels the device can display.

  Notes:
   This function does not return any meaningful information for
   palette-based devices.

**********************************************************/ 
BOOL GetRGBBitsPerPixel(HDC hdc, PINT pRed, PINT pGreen, PINT pBlue)
{
    BITMAPINFOHEADER *pbi;
    LPDWORD lpdw;
    BOOL bRet = TRUE;

    // If the target device is palette-based, then bail because there is no
    // meaningful way to determine separate RGB bits per pixel.
    if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) 
        return FALSE;  

    // Shortcut for handling 24bpp cases.
    if (GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL) == 24) {
        *pRed = *pGreen = *pBlue = 8;
        return TRUE;
    }
   
    // Allocate room for a header and a color table.
    pbi = (BITMAPINFOHEADER *)GlobalAlloc(GPTR, sizeof(BITMAPINFOHEADER) + 
                                                sizeof(RGBQUAD)*256);
    if (!pbi)
        return FALSE;

    // Retrieve a description of the device surface.
    if (GetOptimalDIBFormat(hdc, pbi)) {
        // Get a pointer to the bitfields.
        lpdw = (PINT)((LPBYTE)pbi + sizeof(BITMAPINFOHEADER));

        *pRed   = CountBits(lpdw[0]);
        *pGreen = CountBits(lpdw[1]);
        *pBlue  = CountBits(lpdw[2]);
    } else
        bRet = FALSE;
    
    // Clean up.
    GlobalFree(pbi);

    return bRet;
} 



REFERENCES

For additional information about 16 and 32 bits-per-pel (bpp) DIB formats, please see the following article in the Microsoft Knowledge Base: For additional information about DIB sections and how to use them, please see the following article in the Microsoft Knowledge Base:

Q186221 SAMPLE: DibSectn.exe Uses DIBSections in Win32

Additional query words: bpp

Keywords : kbBitmap kbDevContext kbDibSect kbGDI kbOSWin2000 kbSDKWin32
Issue type : kbhowto
Technology : kbwin2000AdvServ kbwin2000AdvServSearch kbwin2000Serv kbwin2000ServSearch kbwin2000Search kbwin2000ProSearch kbwin2000Pro kbAudDeveloper kbWinAdvServSearch kbWin32sSearch kbWin32API


Last Reviewed: October 20, 2000
© 2001 Microsoft Corporation. All rights reserved. Terms of Use.