PRB: Large DIBs May Not Display Under Win32s
ID: Q126575
|
The information in this article applies to:
-
Microsoft Win32s versions 1.1, 1.15, 1.20
SYMPTOMS
DIB functions fail when using large DIBs under Win32s.
CAUSE
There is a two-megabyte limit on the size of the area of a DIB that can be
blitted using blting functions under Win32s. In versions of Win32s up to
1.2, Microsoft set this size to accommodate DIB blts of 1024*768*24 bits-
per-pixel. In version 1.25, the maximum size of the blitted area will be
enlarged to accommodate 1280*1024*24 bits-per-pixel.
The following functions are affected:
SetDIBits
SetDIBitsToDevice
CreateDIBitmap
StretchDIBits
WORKAROUND
To work around the problem, break down large blts into bands that are
smaller than two megabytes. Please keep in mind that the biSizeImage field
of the BITMAPINFOHEADER used with the blting functions will need to be set
to a value smaller than the DIB size limit.
The following code demonstrates a simple implementation of StretchDIBits()
that can be used with large DIBs under Win32s.
/* Macro to determine the bytes in a DWORD aligned DIB scanline */
#define BYTESPERLINE(Width, BPP) ((WORD)((((DWORD)(Width) *
(DWORD)(BPP) + 31) >> 5)) << 2)
int NewStretchDIBits(
HDC hdc, // handle of device context
int XDest, // x-coordinate of upper-left corner of dest. rect.
int YDest, // y-coordinate of upper-left corner of dest. rect.
int nDestWidth, // width of destination rectangle
int nDestHeight, // height of destination rectangle
int XSrc, // x-coordinate of upper-left corner of source rect.
int YSrc, // y-coordinate of upper-left corner of source rect.
int nSrcWidth, // width of source rectangle
int nSrcHeight, // height of source rectangle
VOID *lpBits, // address of bitmap bits
BITMAPINFO *lpBitsInfo, // address of bitmap data
UINT iUsage, // usage
DWORD dwRop // raster operation code
)
{
BITMAPINFOHEADER bmiTemp;
float fDestYDelta;
LPBYTE lpNewBits;
int i;
// Check for NULL pointers and return error
if (lpBits == NULL) return 0;
if (lpBitsInfo == NULL) return 0;
// Get increment value for Y axis of destination
fDestYDelta = (float)nDestHeight / (float)nSrcHeight;
// Make backup copy of BITMAPINFOHEADER
bmiTemp = lpBitsInfo->bmiHeader;
// Adjust image sizes for one scan line
lpBitsInfo->bmiHeader.biSizeImage =
BYTESPERLINE(lpBitsInfo->bmiHeader.biWidth,
lpBitsInfo->bmiHeader.biBitCount);
lpBitsInfo->bmiHeader.biHeight = 1;
// Initialize pointer to the image data
lpNewBits = (LPBYTE)lpBits;
// Do the stretching
for (i = 0; i < nSrcHeight; i++)
if (!StretchDIBits(hdc,
XDest, YDest + (int)floor(fDestYDelta * (nSrcHeight - (i+1))),
nDestWidth, (int)ceil(fDestYDelta),
XSrc, 0,
nSrcWidth, 1,
lpNewBits, lpBitsInfo,
iUsage, SRCCOPY))
break; // Error!
else
// Increment image pointer by one scan line
lpNewBits += lpBitsInfo->bmiHeader.biSizeImage;
// Restore BITMAPINFOHEADER
lpBitsInfo->bmiHeader = bmiTemp;
return(i);
}
STATUS
This behavior is by design.
Additional query words:
1.15 1.20 1.10
Keywords :
Version : WINDOWS:1.1,1.15,1.20
Platform : WINDOWS
Issue type :