- Always calculate the location of the color table.
- CreateCompatibleBitmap: Create a DIB section if necessary.
- Added some tests.
HBITMAP hbmpRet = 0;
DC *dc;
- TRACE("(%p,%d,%d) = \n", hdc, width, height );
- if (!(dc = DC_GetDCPtr( hdc ))) return 0;
- if ((width >= 0x10000) || (height >= 0x10000)) {
- FIXME("got bad width %d or height %d, please look for reason\n",
- width, height );
+ TRACE("(%p,%d,%d) = \n", hdc, width, height);
+
+ if ((width >= 0x10000) || (height >= 0x10000))
+ {
+ FIXME("got bad width %d or height %d, please look for reason\n",
+ width, height);
}
else
{
- INT planes, bpp;
+ if (!(dc = DC_GetDCPtr(hdc))) return 0;
if (GDIMAGIC( dc->header.wMagic ) != MEMORY_DC_MAGIC)
{
- planes = GetDeviceCaps( hdc, PLANES );
- bpp = GetDeviceCaps( hdc, BITSPIXEL );
+ hbmpRet = CreateBitmap(width, height,
+ GetDeviceCaps(hdc, PLANES),
+ GetDeviceCaps(hdc, BITSPIXEL),
+ NULL);
}
- else /* memory DC, get the depth of the bitmap */
+ else /* Memory DC */
{
BITMAPOBJ *bmp = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
- planes = bmp->bitmap.bmPlanes;
- bpp = bmp->bitmap.bmBitsPixel;
- GDI_ReleaseObj( dc->hBitmap );
+
+ if (!bmp->dib)
+ {
+ /* A device-dependent bitmap is selected in the DC */
+ hbmpRet = CreateBitmap(width, height,
+ bmp->bitmap.bmPlanes,
+ bmp->bitmap.bmBitsPixel,
+ NULL);
+ }
+ else
+ {
+ /* A DIB section is selected in the DC */
+ BITMAPINFO *bi;
+ void *bits;
+
+ /* Allocate memory for a BITMAPINFOHEADER structure and a
+ color table. The maximum number of colors in a color table
+ is 256 which corresponds to a bitmap with depth 8.
+ Bitmaps with higher depths don't have color tables. */
+ bi = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+
+ if (bi)
+ {
+ bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
+ bi->bmiHeader.biWidth = width;
+ bi->bmiHeader.biHeight = height;
+ bi->bmiHeader.biPlanes = bmp->dib->dsBmih.biPlanes;
+ bi->bmiHeader.biBitCount = bmp->dib->dsBmih.biBitCount;
+ bi->bmiHeader.biCompression = bmp->dib->dsBmih.biCompression;
+ bi->bmiHeader.biSizeImage = 0;
+ bi->bmiHeader.biXPelsPerMeter = bmp->dib->dsBmih.biXPelsPerMeter;
+ bi->bmiHeader.biYPelsPerMeter = bmp->dib->dsBmih.biYPelsPerMeter;
+ bi->bmiHeader.biClrUsed = bmp->dib->dsBmih.biClrUsed;
+ bi->bmiHeader.biClrImportant = bmp->dib->dsBmih.biClrImportant;
+
+ if (bi->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ /* Copy the color masks */
+ CopyMemory(bi->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD));
+ }
+ else if (bi->bmiHeader.biBitCount <= 8)
+ {
+ /* Copy the color table */
+ GetDIBColorTable(hdc, 0, 256, bi->bmiColors);
+ }
+
+ hbmpRet = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
+ HeapFree(GetProcessHeap(), 0, bi);
+ }
+ }
+ GDI_ReleaseObj(dc->hBitmap);
}
- hbmpRet = CreateBitmap( width, height, planes, bpp, NULL );
+ GDI_ReleaseObj(hdc);
}
+
TRACE("\t\t%p\n", hbmpRet);
- GDI_ReleaseObj(hdc);
return hbmpRet;
}
* SetBitmapDimensionEx [GDI32.@]
*
* Assigns dimensions to a bitmap.
+ * MSDN says that this function will fail if hbitmap is a handle created by
+ * CreateDIBSection, but that's not true on Windows 2000.
*
* RETURNS
* Success: TRUE
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+/*
+ Important information:
+
+ * Current Windows versions support two different DIB structures:
+
+ - BITMAPCOREINFO / BITMAPCOREHEADER (legacy structures; used in OS/2)
+ - BITMAPINFO / BITMAPINFOHEADER
+
+ Most Windows API functions taking a BITMAPINFO* / BITMAPINFOHEADER* also
+ accept the old "core" structures, and so must WINE.
+ You can distinguish them by looking at the first member (bcSize/biSize),
+ or use the internal function DIB_GetBitmapInfo.
+
+
+ * The palettes are stored in different formats:
+
+ - BITMAPCOREINFO: Array of RGBTRIPLE
+ - BITMAPINFO: Array of RGBQUAD
+
+
+ * There are even more DIB headers, but they all extend BITMAPINFOHEADER:
+
+ - BITMAPV4HEADER: Introduced in Windows 95 / NT 4.0
+ - BITMAPV5HEADER: Introduced in Windows 98 / 2000
+
+
+ * You should never access the color table using the bmiColors member,
+ because the passed structure may have one of the extended headers
+ mentioned above. Use this to calculate the location:
+
+ BITMAPINFO* info;
+ void* colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
+
+
+ * More information:
+ Search for "Bitmap Structures" in MSDN
+*/
+
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
+
+/*
+ Some of the following helper functions are duplicated in
+ dlls/x11drv/dib.c
+*/
+
/***********************************************************************
* DIB_GetDIBWidthBytes
*
{
HBITMAP hBitmap, hOldBitmap;
HPALETTE hpal = NULL;
- HDC hdcMem;
+ HDC hdcMem;
+ LONG height;
+ LONG width;
+ WORD bpp;
+ DWORD compr;
+
+ if (DIB_GetBitmapInfo( (BITMAPINFOHEADER*) info, &width, &height, &bpp, &compr ) == -1)
+ {
+ ERR("Invalid bitmap\n");
+ return 0;
+ }
+
+ if (width < 0)
+ {
+ ERR("Bitmap has a negative width\n");
+ return 0;
+ }
GDI_ReleaseObj( hdc );
hdcMem = CreateCompatibleDC( hdc );
- hBitmap = CreateCompatibleBitmap(hdc, info->bmiHeader.biWidth,
- info->bmiHeader.biHeight);
+ hBitmap = CreateCompatibleBitmap(hdc, width, height);
hOldBitmap = SelectObject( hdcMem, hBitmap );
if(wUsage == DIB_PAL_COLORS)
{
*/
/* copy existing bitmap from destination dc */
- StretchBlt( hdcMem, xSrc, abs(info->bmiHeader.biHeight) - heightSrc - ySrc,
+ StretchBlt( hdcMem, xSrc, abs(height) - heightSrc - ySrc,
widthSrc, heightSrc, hdc, xDst, yDst, widthDst, heightDst,
dwRop );
}
- SetDIBits(hdcMem, hBitmap, 0, info->bmiHeader.biHeight, bits,
- info, wUsage);
+ SetDIBits(hdcMem, hBitmap, 0, height, bits, info, wUsage);
/* Origin for DIBitmap may be bottom left (positive biHeight) or top
left (negative biHeight) */
StretchBlt( hdc, xDst, yDst, widthDst, heightDst,
- hdcMem, xSrc, abs(info->bmiHeader.biHeight) - heightSrc - ySrc,
+ hdcMem, xSrc, abs(height) - heightSrc - ySrc,
widthSrc, heightSrc, dwRop );
if(hpal)
SelectPalette(hdcMem, hpal, FALSE);
NB. RGBQUAD and PALETTEENTRY have different orderings of red, green
and blue - sigh */
-static RGBQUAD EGAColors[16] = {
-/* rgbBlue, rgbGreen, rgbRed, rgbReserverd */
+static RGBQUAD EGAColorsQuads[16] = {
+/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
{ 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x80, 0x00 },
{ 0x00, 0x80, 0x00, 0x00 },
{ 0xff, 0xff, 0xff, 0x00 }
};
+static RGBTRIPLE EGAColorsTriples[16] = {
+/* rgbBlue, rgbGreen, rgbRed */
+ { 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x80 },
+ { 0x00, 0x80, 0x00 },
+ { 0x00, 0x80, 0x80 },
+ { 0x80, 0x00, 0x00 },
+ { 0x80, 0x00, 0x80 },
+ { 0x80, 0x80, 0x00 },
+ { 0x80, 0x80, 0x80 },
+ { 0xc0, 0xc0, 0xc0 },
+ { 0x00, 0x00, 0xff },
+ { 0x00, 0xff, 0x00 },
+ { 0x00, 0xff, 0xff },
+ { 0xff, 0x00, 0x00 } ,
+ { 0xff, 0x00, 0xff },
+ { 0xff, 0xff, 0x00 },
+ { 0xff, 0xff, 0xff }
+};
-static RGBQUAD DefLogPalette[20] = { /* Copy of Default Logical Palette */
-/* rgbBlue, rgbGreen, rgbRed, rgbReserverd */
+static RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
+/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
{ 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x80, 0x00 },
{ 0x00, 0x80, 0x00, 0x00 },
{ 0xff, 0xff, 0xff, 0x00 }
};
+static RGBTRIPLE DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
+/* rgbBlue, rgbGreen, rgbRed */
+ { 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x80 },
+ { 0x00, 0x80, 0x00 },
+ { 0x00, 0x80, 0x80 },
+ { 0x80, 0x00, 0x00 },
+ { 0x80, 0x00, 0x80 },
+ { 0x80, 0x80, 0x00 },
+ { 0xc0, 0xc0, 0xc0 },
+ { 0xc0, 0xdc, 0xc0 },
+ { 0xf0, 0xca, 0xa6 },
+ { 0xf0, 0xfb, 0xff },
+ { 0xa4, 0xa0, 0xa0 },
+ { 0x80, 0x80, 0x80 },
+ { 0x00, 0x00, 0xf0 },
+ { 0x00, 0xff, 0x00 },
+ { 0x00, 0xff, 0xff },
+ { 0xff, 0x00, 0x00 },
+ { 0xff, 0x00, 0xff },
+ { 0xff, 0xff, 0x00 },
+ { 0xff, 0xff, 0xff}
+};
+
/******************************************************************************
* GetDIBits [GDI32.@]
BITMAPOBJ * bmp;
int i;
HDC memdc;
+ int bitmap_type;
+ BOOL core_header;
+ LONG width;
+ LONG height;
+ WORD bpp;
+ DWORD compr;
+ void* colorPtr;
+ RGBTRIPLE* rgbTriples;
+ RGBQUAD* rgbQuads;
if (!info) return 0;
+
+ bitmap_type = DIB_GetBitmapInfo( (BITMAPINFOHEADER*) info, &width, &height, &bpp, &compr);
+ if (bitmap_type == -1)
+ {
+ ERR("Invalid bitmap format\n");
+ return 0;
+ }
+ core_header = (bitmap_type == 0);
memdc = CreateCompatibleDC(hdc);
if (!(dc = DC_GetDCUpdate( hdc )))
{
return 0;
}
- /* Transfer color info */
+ colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
+ rgbTriples = (RGBTRIPLE *) colorPtr;
+ rgbQuads = (RGBQUAD *) colorPtr;
- if (info->bmiHeader.biBitCount <= 8 && info->bmiHeader.biBitCount > 0 ) {
+ /* Transfer color info */
- info->bmiHeader.biClrUsed = 0;
+ if (bpp <= 8 && bpp > 0)
+ {
+ if (!core_header) info->bmiHeader.biClrUsed = 0;
/* If the bitmap object already has a dib section at the
same color depth then get the color map from it */
- if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == info->bmiHeader.biBitCount) {
+ if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == bpp) {
if(coloruse == DIB_RGB_COLORS) {
- HBITMAP oldbm;
- oldbm = SelectObject(memdc, hbitmap);
- GetDIBColorTable(memdc, 0, 1 << info->bmiHeader.biBitCount, info->bmiColors);
+ HBITMAP oldbm = SelectObject(memdc, hbitmap);
+ unsigned int colors = 1 << bpp;
+
+ if (core_header)
+ {
+ /* Convert the color table (RGBQUAD to RGBTRIPLE) */
+ RGBQUAD* buffer = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD));
+
+ if (buffer)
+ {
+ RGBTRIPLE* index = rgbTriples;
+ GetDIBColorTable(memdc, 0, colors, buffer);
+
+ for (i=0; i < colors; i++, index++)
+ {
+ index->rgbtRed = buffer[i].rgbRed;
+ index->rgbtGreen = buffer[i].rgbGreen;
+ index->rgbtBlue = buffer[i].rgbBlue;
+ }
+
+ HeapFree(GetProcessHeap(), 0, buffer);
+ }
+ }
+ else
+ {
+ GetDIBColorTable(memdc, 0, colors, colorPtr);
+ }
SelectObject(memdc, oldbm);
}
else {
- WORD *index = (WORD*)info->bmiColors;
- int i;
+ WORD *index = colorPtr;
for(i = 0; i < 1 << info->bmiHeader.biBitCount; i++, index++)
*index = i;
}
- }
+ }
else {
- if(info->bmiHeader.biBitCount >= bmp->bitmap.bmBitsPixel) {
+ if(bpp >= bmp->bitmap.bmBitsPixel) {
/* Generate the color map from the selected palette */
PALETTEENTRY * palEntry;
PALETTEOBJ * palette;
palEntry = palette->logpalette.palPalEntry;
for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++, palEntry++) {
if (coloruse == DIB_RGB_COLORS) {
- info->bmiColors[i].rgbRed = palEntry->peRed;
- info->bmiColors[i].rgbGreen = palEntry->peGreen;
- info->bmiColors[i].rgbBlue = palEntry->peBlue;
- info->bmiColors[i].rgbReserved = 0;
+ if (core_header)
+ {
+ rgbTriples[i].rgbtRed = palEntry->peRed;
+ rgbTriples[i].rgbtGreen = palEntry->peGreen;
+ rgbTriples[i].rgbtBlue = palEntry->peBlue;
+ }
+ else
+ {
+ rgbQuads[i].rgbRed = palEntry->peRed;
+ rgbQuads[i].rgbGreen = palEntry->peGreen;
+ rgbQuads[i].rgbBlue = palEntry->peBlue;
+ rgbQuads[i].rgbReserved = 0;
+ }
}
- else ((WORD *)info->bmiColors)[i] = (WORD)i;
+ else ((WORD *)colorPtr)[i] = (WORD)i;
}
GDI_ReleaseObj( dc->hPalette );
} else {
- switch (info->bmiHeader.biBitCount) {
+ switch (bpp) {
case 1:
- info->bmiColors[0].rgbRed = info->bmiColors[0].rgbGreen =
- info->bmiColors[0].rgbBlue = 0;
- info->bmiColors[0].rgbReserved = 0;
- info->bmiColors[1].rgbRed = info->bmiColors[1].rgbGreen =
- info->bmiColors[1].rgbBlue = 0xff;
- info->bmiColors[1].rgbReserved = 0;
+ if (core_header)
+ {
+ rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
+ rgbTriples[0].rgbtBlue = 0;
+ rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
+ rgbTriples[1].rgbtBlue = 0xff;
+ }
+ else
+ {
+ rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
+ rgbQuads[0].rgbBlue = 0;
+ rgbQuads[0].rgbReserved = 0;
+ rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
+ rgbQuads[1].rgbBlue = 0xff;
+ rgbQuads[1].rgbReserved = 0;
+ }
break;
case 4:
- memcpy(info->bmiColors, EGAColors, sizeof(EGAColors));
+ if (core_header)
+ memcpy(colorPtr, EGAColorsTriples, sizeof(EGAColorsTriples));
+ else
+ memcpy(colorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
+
break;
case 8:
{
- INT r, g, b;
- RGBQUAD *color;
-
- memcpy(info->bmiColors, DefLogPalette,
- 10 * sizeof(RGBQUAD));
- memcpy(info->bmiColors + 246, DefLogPalette + 10,
- 10 * sizeof(RGBQUAD));
- color = info->bmiColors + 10;
- for(r = 0; r <= 5; r++) /* FIXME */
- for(g = 0; g <= 5; g++)
- for(b = 0; b <= 5; b++) {
- color->rgbRed = (r * 0xff) / 5;
- color->rgbGreen = (g * 0xff) / 5;
- color->rgbBlue = (b * 0xff) / 5;
- color->rgbReserved = 0;
- color++;
- }
+ if (core_header)
+ {
+ INT r, g, b;
+ RGBTRIPLE *color;
+
+ memcpy(rgbTriples, DefLogPaletteTriples,
+ 10 * sizeof(RGBTRIPLE));
+ memcpy(rgbTriples + 246, DefLogPaletteTriples + 10,
+ 10 * sizeof(RGBTRIPLE));
+ color = rgbTriples + 10;
+ for(r = 0; r <= 5; r++) /* FIXME */
+ for(g = 0; g <= 5; g++)
+ for(b = 0; b <= 5; b++) {
+ color->rgbtRed = (r * 0xff) / 5;
+ color->rgbtGreen = (g * 0xff) / 5;
+ color->rgbtBlue = (b * 0xff) / 5;
+ color++;
+ }
+ }
+ else
+ {
+ INT r, g, b;
+ RGBQUAD *color;
+
+ memcpy(rgbQuads, DefLogPaletteQuads,
+ 10 * sizeof(RGBQUAD));
+ memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
+ 10 * sizeof(RGBQUAD));
+ color = rgbQuads + 10;
+ for(r = 0; r <= 5; r++) /* FIXME */
+ for(g = 0; g <= 5; g++)
+ for(b = 0; b <= 5; b++) {
+ color->rgbRed = (r * 0xff) / 5;
+ color->rgbGreen = (g * 0xff) / 5;
+ color->rgbBlue = (b * 0xff) / 5;
+ color->rgbReserved = 0;
+ color++;
+ }
+ }
}
}
}
if (bits && lines)
{
/* If the bitmap object already have a dib section that contains image data, get the bits from it */
- if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && info->bmiHeader.biBitCount >= 15)
+ if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
{
/*FIXME: Only RGB dibs supported for now */
unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb = bmp->dib->dsBm.bmWidthBytes;
- unsigned int dstwidth = info->bmiHeader.biWidth;
- int dstwidthb = DIB_GetDIBWidthBytes( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
+ unsigned int dstwidth = width;
+ int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
unsigned int x, y, width, widthb;
- if ((info->bmiHeader.biHeight < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
+ if ((height < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
{
dbits = (LPBYTE)bits + (dstwidthb * (lines-1));
dstwidthb = -dstwidthb;
}
- switch( info->bmiHeader.biBitCount ) {
+ switch( bpp ) {
case 15:
case 16: /* 16 bpp dstDIB */
}
}
}
- else if( info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
+ else
{
/* fill in struct members */
- if( info->bmiHeader.biBitCount == 0)
- {
- info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
- info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
- info->bmiHeader.biPlanes = 1;
- info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
- info->bmiHeader.biSizeImage =
- DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
- bmp->bitmap.bmHeight,
- bmp->bitmap.bmBitsPixel );
- info->bmiHeader.biCompression = 0;
- }
- else
- {
- info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
- info->bmiHeader.biWidth,
- info->bmiHeader.biHeight,
- info->bmiHeader.biBitCount );
- }
- lines = info->bmiHeader.biHeight;
+ if (bpp == 0)
+ {
+ if (core_header)
+ {
+ BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
+ coreheader->bcWidth = bmp->bitmap.bmWidth;
+ coreheader->bcHeight = bmp->bitmap.bmHeight;
+ coreheader->bcPlanes = 1;
+ coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
+ }
+ else
+ {
+ info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
+ info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
+ info->bmiHeader.biPlanes = 1;
+ info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
+ info->bmiHeader.biSizeImage =
+ DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
+ bmp->bitmap.bmHeight,
+ bmp->bitmap.bmBitsPixel );
+ info->bmiHeader.biCompression = 0;
+ }
+ lines = abs(bmp->bitmap.bmHeight);
+ }
}
- TRACE("biSizeImage = %ld, biWidth = %ld, biHeight = %ld\n",
- info->bmiHeader.biSizeImage, info->bmiHeader.biWidth,
- info->bmiHeader.biHeight);
+ if (!core_header)
+ {
+ TRACE("biSizeImage = %ld, ", info->bmiHeader.biSizeImage);
+ }
+ TRACE("biWidth = %ld, biHeight = %ld\n", width, height);
GDI_ReleaseObj( hdc );
GDI_ReleaseObj( hbitmap );
if (bmp && bmp->dib && bits32)
{
const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
- INT height = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
- INT width_bytes = DIB_GetDIBWidthBytes(bi->biWidth, bi->biBitCount);
- INT size = (bi->biSizeImage && bi->biCompression != BI_RGB) ?
- bi->biSizeImage : width_bytes * height;
+ LONG width, height;
+ WORD bpp;
+ DWORD compr;
+ BOOL core_header;
+ INT width_bytes;
+ INT size;
+ WORD count, sel;
+ int i;
+
+ core_header = (DIB_GetBitmapInfo(bi, &width, &height, &bpp, &compr) == 0);
+
+ height = height >= 0 ? height : -height;
+ width_bytes = DIB_GetDIBWidthBytes(width, bpp);
+
+ if (core_header)
+ {
+ size = width_bytes * height;
+ }
+ else
+ {
+ size = (bi->biSizeImage && compr != BI_RGB) ?
+ bi->biSizeImage : width_bytes * height;
+ }
/* calculate number of sel's needed for size with 64K steps */
- WORD count = (size + 0xffff) / 0x10000;
- WORD sel = AllocSelectorArray16(count);
- int i;
+ count = (size + 0xffff) / 0x10000;
+ sel = AllocSelectorArray16(count);
for (i = 0; i < count; i++)
{
HDC hdc, hdcmem, hdcmem2;
HBITMAP hdib, oldbm, hdib2, oldbm2;
char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
+ char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
+ BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
+ HBITMAP hcoredib;
+ char coreBits[256];
BYTE *bits;
RGBQUAD rgb[256];
int ret;
hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
ok(hdib != NULL, "CreateDIBSection failed\n");
+ /* Test if the old BITMAPCOREINFO structure is supported */
+
+ pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
+ pbci->bmciHeader.bcBitCount = 0;
+
+ ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
+ ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
+ ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
+ && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
+ "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
+
+ ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
+ ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
+ ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
+ (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
+ (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
+ "The color table has not been translated to the old BITMAPCOREINFO format\n");
+
+ hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
+ ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
+
+ ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
+ ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
+ ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
+ ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
+ (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
+ (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
+ "The color table has not been translated to the old BITMAPCOREINFO format\n");
+
+ DeleteObject(hcoredib);
+
hdcmem = CreateCompatibleDC(hdc);
oldbm = SelectObject(hdcmem, hdib);
RLE_DELTA = 2 /* Delta */
};
+
+/*
+ Some of the following helper functions are duplicated in
+ dlls/gdi/dib.c
+*/
+
/***********************************************************************
* X11DRV_DIB_GetXImageWidthBytes
*
}
+/***********************************************************************
+ * X11DRV_DIB_GetDIBImageBytes
+ *
+ * Return the number of bytes used to hold the image in a DIB bitmap.
+ */
+static int X11DRV_DIB_GetDIBImageBytes( int width, int height, int depth )
+{
+ return X11DRV_DIB_GetDIBWidthBytes( width, depth ) * abs( height );
+}
+
+
/***********************************************************************
* X11DRV_DIB_BitmapInfoSize
*
*/
int X11DRV_DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse )
{
- int colors;
+ unsigned int colors;
if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
/***********************************************************************
- * DIB_GetBitmapInfo
+ * DIB_GetBitmapInfoEx
*
* Get the info from a bitmap header.
* Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
*/
-static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
- int *height, WORD *bpp, WORD *compr )
+static int DIB_GetBitmapInfoEx( const BITMAPINFOHEADER *header, LONG *width,
+ LONG *height, WORD *planes, WORD *bpp,
+ WORD *compr, DWORD *size )
{
if (header->biSize == sizeof(BITMAPCOREHEADER))
{
BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
*width = core->bcWidth;
*height = core->bcHeight;
+ *planes = core->bcPlanes;
*bpp = core->bcBitCount;
*compr = 0;
+ *size = 0;
return 0;
}
if (header->biSize >= sizeof(BITMAPINFOHEADER))
{
*width = header->biWidth;
*height = header->biHeight;
+ *planes = header->biPlanes;
*bpp = header->biBitCount;
*compr = header->biCompression;
+ *size = header->biSizeImage;
return 1;
}
ERR("(%ld): unknown/wrong size for header\n", header->biSize );
}
+/***********************************************************************
+ * DIB_GetBitmapInfo
+ *
+ * Get the info from a bitmap header.
+ * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
+ */
+static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
+ LONG *height, WORD *bpp, WORD *compr )
+{
+ WORD planes;
+ DWORD size;
+
+ return DIB_GetBitmapInfoEx( header, width, height, &planes, bpp, compr, &size);
+}
+
+
/***********************************************************************
* X11DRV_DIB_GenColorMap
*
int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
const BITMAPINFO *info, int *nColors )
{
- int colors;
+ unsigned int colors;
BOOL isInfo;
const void *colorPtr;
int *colorMapping;
- if ((isInfo = (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER))))
+ isInfo = info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER);
+
+ if (isInfo)
{
- /* assume BITMAPINFOHEADER */
colors = info->bmiHeader.biClrUsed;
if (!colors) colors = 1 << info->bmiHeader.biBitCount;
- colorPtr = info->bmiColors;
}
- else /* BITMAPCOREHEADER */
+ else
{
colors = 1 << ((BITMAPCOREHEADER *)info)->bcBitCount;
- colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
}
+ colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
+
if (colors > 256)
{
ERR("called with >256 colors!\n");
const BITMAPINFO *info )
{
RGBQUAD *colorTable;
- int colors, i;
+ unsigned int colors;
+ int i;
+ BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
- colors = info->bmiHeader.biClrUsed;
- if (!colors) colors = 1 << info->bmiHeader.biBitCount;
+ if (core_info)
+ {
+ colors = 1 << ((BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
+ }
+ else
+ {
+ colors = info->bmiHeader.biClrUsed;
+ if (!colors) colors = 1 << info->bmiHeader.biBitCount;
+ }
if (colors > 256) {
ERR("called with >256 colors!\n");
return NULL;
if(coloruse == DIB_RGB_COLORS)
- memcpy(colorTable, info->bmiColors, colors * sizeof(RGBQUAD));
- else {
+ {
+ if (core_info)
+ {
+ /* Convert RGBTRIPLEs to RGBQUADs */
+ for (i=0; i < colors; i++)
+ {
+ colorTable[i].rgbRed = ((BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
+ colorTable[i].rgbGreen = ((BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
+ colorTable[i].rgbBlue = ((BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
+ colorTable[i].rgbReserved = 0;
+ }
+ }
+ else
+ {
+ memcpy(colorTable, (LPBYTE) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
+ }
+ }
+ else
+ {
HPALETTE hpal = GetCurrentObject(physDev->hdc, OBJ_PAL);
PALETTEENTRY pal_ents[256];
- WORD *index;
+ WORD *index = (WORD*) ((LPBYTE) info + (WORD) info->bmiHeader.biSize);
GetPaletteEntries(hpal, 0, 256, pal_ents);
- for(i = 0, index = (WORD*)info->bmiColors; i < colors; i++, index++) {
+
+ for(i = 0; i < colors; i++, index++)
+ {
colorTable[i].rgbRed = pal_ents[*index].peRed;
colorTable[i].rgbGreen = pal_ents[*index].peGreen;
colorTable[i].rgbBlue = pal_ents[*index].peBlue;
*/
int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
{
- int color;
+ unsigned int color;
if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
return oldcol;
const BITMAPINFO *info, UINT coloruse )
{
X11DRV_DIB_IMAGEBITS_DESCR descr;
- DWORD width;
INT result;
- int height;
+ LONG width, height;
BOOL top_down;
POINT pt;
+ void* colorPtr;
if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
&descr.infoBpp, &descr.compression ) == -1)
return 0;
+
top_down = (height < 0);
if (top_down) height = -height;
XSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[GetROP2(physDev->hdc) - 1]);
wine_tsx11_unlock();
+ colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
+
switch (descr.infoBpp)
{
case 1:
break;
case 15:
case 16:
- descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
- descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
- descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
+ descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0x7c00;
+ descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x03e0;
+ descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x001f;
descr.colorMap = 0;
break;
case 24:
case 32:
- descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
- descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
- descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
+ descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0xff0000;
+ descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x00ff00;
+ descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x0000ff;
descr.colorMap = 0;
break;
}
{
X11DRV_DIB_IMAGEBITS_DESCR descr;
BITMAPOBJ *bmp;
- int height, tmpheight;
+ LONG height, tmpheight;
INT result;
+ void* colorPtr;
descr.physDev = physDev;
if (startscan + lines > height) lines = height - startscan;
+ colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
+
switch (descr.infoBpp)
{
case 1:
break;
case 15:
case 16:
- descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
- descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
- descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
+ descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0x7c00;
+ descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x03e0;
+ descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x001f;
descr.colorMap = 0;
break;
case 24:
case 32:
- descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
- descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
- descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
+ descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0xff0000;
+ descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x00ff00;
+ descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x0000ff;
descr.colorMap = 0;
break;
PALETTEENTRY palette[256];
BITMAPOBJ *bmp;
int height;
+ LONG tempHeight;
+ int bitmap_type;
+ BOOL core_header;
+ void* colorPtr;
GetPaletteEntries( GetCurrentObject( physDev->hdc, OBJ_PAL ), 0, 256, palette );
if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
dib = (X11DRV_DIBSECTION *) bmp->dib;
+
+ bitmap_type = DIB_GetBitmapInfo( (BITMAPINFOHEADER*) info, &descr.infoWidth, &tempHeight, &descr.infoBpp, &descr.compression);
+ descr.lines = tempHeight;
+ if (bitmap_type == -1)
+ {
+ ERR("Invalid bitmap\n");
+ lines = 0;
+ goto done;
+ }
+ core_header = (bitmap_type == 0);
+ colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
- (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
- startscan );
+ (int)descr.infoWidth, descr.lines, startscan);
if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
- height = info->bmiHeader.biHeight;
+ height = descr.lines;
if (height < 0) height = -height;
if( lines > height ) lines = height;
/* Top-down images have a negative biHeight, the scanlines of theses images
* (the number of scan lines to copy).
* Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
*/
- if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
+ if( descr.lines < 0 && lines > 0) lines = -lines;
if( startscan >= bmp->bitmap.bmHeight )
{
goto done;
}
- if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
- &descr.infoBpp, &descr.compression ) == -1)
- {
- lines = 0;
- goto done;
- }
-
descr.colorMap = NULL;
switch (descr.infoBpp)
case 8:
descr.rMask= descr.gMask = descr.bMask = 0;
if(coloruse == DIB_RGB_COLORS)
- descr.colorMap = info->bmiColors;
+ descr.colorMap = colorPtr;
else {
int num_colors = 1 << descr.infoBpp, i;
RGBQUAD *rgb;
COLORREF colref;
- WORD *index = (WORD*)info->bmiColors;
+ WORD *index = (WORD*)colorPtr;
descr.colorMap = rgb = HeapAlloc(GetProcessHeap(), 0, num_colors * sizeof(RGBQUAD));
for(i = 0; i < num_colors; i++, rgb++, index++) {
colref = X11DRV_PALETTE_ToLogical(X11DRV_PALETTE_ToPhysical(physDev, PALETTEINDEX(*index)));
break;
case 15:
case 16:
- descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
- descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
- descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
+ descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0x7c00;
+ descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x03e0;
+ descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x001f;
break;
case 24:
case 32:
- descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
- descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
- descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
+ descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0xff0000;
+ descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x00ff00;
+ descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x0000ff;
break;
}
descr.xDest = 0;
descr.yDest = 0;
descr.xSrc = 0;
- descr.sizeImage = info->bmiHeader.biSizeImage;
+ descr.sizeImage = core_header ? 0 : info->bmiHeader.biSizeImage;
if (descr.lines > 0)
{
X11DRV_DIB_GetImageBits( &descr );
X11DRV_DIB_Unlock(bmp, TRUE);
- if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
- info->bmiHeader.biSizeImage = X11DRV_DIB_GetDIBWidthBytes( info->bmiHeader.biWidth,
- info->bmiHeader.biBitCount )
- * abs( info->bmiHeader.biHeight );
+ if(!core_header && info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
+ info->bmiHeader.biSizeImage = X11DRV_DIB_GetDIBImageBytes( descr.infoWidth,
+ descr.lines,
+ descr.infoBpp);
if (descr.compression == BI_BITFIELDS)
{
- *(DWORD *)info->bmiColors = descr.rMask;
- *((DWORD *)info->bmiColors+1) = descr.gMask;
- *((DWORD *)info->bmiColors+2) = descr.bMask;
+ *(DWORD *) colorPtr = descr.rMask;
+ *((DWORD *)colorPtr + 1) = descr.gMask;
+ *((DWORD *)colorPtr + 2) = descr.bMask;
}
- else
+ else if (!core_header)
{
/* if RLE or JPEG compression were supported,
* this line would be invalid. */
info->bmiHeader.biCompression = 0;
}
- if(descr.colorMap && descr.colorMap != info->bmiColors)
+ if(descr.colorMap && descr.colorMap != colorPtr)
HeapFree(GetProcessHeap(), 0, descr.colorMap);
done:
GDI_ReleaseObj( hbitmap );
X11DRV_DIB_IMAGEBITS_DESCR descr;
int identity[2] = {0,1};
- if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
+ if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, (DWORD*) &descr.lines,
&descr.infoBpp, &descr.compression ) == -1)
return;
int nColorMap;
RGBQUAD *colorTable = NULL;
- /* Fill BITMAP32 structure with DIB data */
- const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
+ /* Fill BITMAP structure with DIB data */
INT effHeight, totalSize;
BITMAP bm;
LPVOID mapBits = NULL;
- TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
- bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
- bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
+ int bitmap_type;
+ BOOL core_header;
+ LONG width, height;
+ WORD planes, bpp, compression;
+ DWORD sizeImage;
+ void* colorPtr;
- effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
+ if (((bitmap_type = DIB_GetBitmapInfoEx((BITMAPINFOHEADER*) bmi,
+ &width, &height, &planes, &bpp, &compression, &sizeImage)) == -1))
+ {
+ ERR("Invalid bitmap\n");
+ return 0;
+ }
+ core_header = (bitmap_type == 0);
+
+ TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, %s\n",
+ width, height, planes, bpp,
+ sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
+
+ effHeight = height >= 0 ? height : -height;
bm.bmType = 0;
- bm.bmWidth = bi->biWidth;
+ bm.bmWidth = width;
bm.bmHeight = effHeight;
- bm.bmWidthBytes = ovr_pitch ? ovr_pitch : X11DRV_DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
- bm.bmPlanes = bi->biPlanes;
- bm.bmBitsPixel = bi->biBitCount;
+ bm.bmWidthBytes = ovr_pitch ? ovr_pitch : X11DRV_DIB_GetDIBWidthBytes(bm.bmWidth, bpp);
+ bm.bmPlanes = planes;
+ bm.bmBitsPixel = bpp;
bm.bmBits = NULL;
- /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
+ /* Get storage location for DIB bits. Only use sizeImage if it's valid and
we're dealing with a compressed bitmap. Otherwise, use width * height. */
- if (bi->biSizeImage && (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8))
- totalSize = bi->biSizeImage;
+ if (sizeImage && (compression == BI_RLE4 || compression == BI_RLE8))
+ totalSize = sizeImage;
else
totalSize = bm.bmWidthBytes * effHeight;
if (dib)
{
dib->dibSection.dsBm = bm;
- dib->dibSection.dsBmih = *bi;
+
+ if (core_header)
+ {
+ /* Convert the BITMAPCOREHEADER to a BITMAPINFOHEADER.
+ The structure is already filled with zeros */
+ dib->dibSection.dsBmih.biSize = sizeof(BITMAPINFOHEADER);
+ dib->dibSection.dsBmih.biWidth = width;
+ dib->dibSection.dsBmih.biHeight = height;
+ dib->dibSection.dsBmih.biPlanes = planes;
+ dib->dibSection.dsBmih.biBitCount = bpp;
+ dib->dibSection.dsBmih.biCompression = compression;
+ }
+ else
+ {
+ /* Truncate extended bitmap headers (BITMAPV4HEADER etc.) */
+ dib->dibSection.dsBmih = *((BITMAPINFOHEADER*) bmi);
+ dib->dibSection.dsBmih.biSize = sizeof(BITMAPINFOHEADER);
+ }
+
dib->dibSection.dsBmih.biSizeImage = totalSize;
+ colorPtr = (LPBYTE) bmi + (WORD) bmi->bmiHeader.biSize;
/* Set dsBitfields values */
- if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
+ if ( usage == DIB_PAL_COLORS || bpp <= 8)
{
dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
}
- else switch( bi->biBitCount )
+ else switch( bpp )
{
case 15:
case 16:
- dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
- dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
- dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
+ dib->dibSection.dsBitfields[0] = (compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0x7c00;
+ dib->dibSection.dsBitfields[1] = (compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x03e0;
+ dib->dibSection.dsBitfields[2] = (compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x001f;
break;
case 24:
case 32:
- dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff0000;
- dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x00ff00;
- dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x0000ff;
+ dib->dibSection.dsBitfields[0] = (compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0xff0000;
+ dib->dibSection.dsBitfields[1] = (compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x00ff00;
+ dib->dibSection.dsBitfields[2] = (compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x0000ff;
break;
}
dib->dibSection.dshSection = section;
/* Create Device Dependent Bitmap and add DIB pointer */
if (dib)
{
- int depth = (bi->biBitCount == 1) ? 1 : GetDeviceCaps(physDev->hdc, BITSPIXEL);
- res = CreateBitmap(bi->biWidth, effHeight, 1, depth, NULL);
+ int depth = (bpp == 1) ? 1 : GetDeviceCaps(physDev->hdc, BITSPIXEL);
+ res = CreateBitmap(width, effHeight, 1, depth, NULL);
if (res)
{