- More BITMAPINFO->BITMAPV5INFO
  - Do not use PAL_BITFIELDS when creating the DIB palette and we know that it's RGB
  - PSEH-ize NtGdiCreateDIBSection

svn path=/branches/reactos-yarotows/; revision=48248
This commit is contained in:
Jérôme Gardou 2010-07-25 11:35:45 +00:00
parent 7bb96de441
commit fbcac4b275
4 changed files with 128 additions and 140 deletions

View file

@ -5,7 +5,7 @@
INT FASTCALL INT FASTCALL
DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse); DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse);
HBITMAP APIENTRY HBITMAP APIENTRY
DIB_CreateDIBSection (PDC dc, PBITMAPINFO bmi, UINT usage, LPVOID *bits, HANDLE section, DWORD offset, DWORD ovr_pitch); DIB_CreateDIBSection (PDC dc, CONST BITMAPV5INFO *bmi, UINT usage, LPVOID *bits, HANDLE section, DWORD offset, DWORD ovr_pitch);
INT APIENTRY INT APIENTRY
DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, PLONG width, PLONG height, PWORD planes, PWORD bpp, PLONG compr, PLONG size ); DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, PLONG width, PLONG height, PWORD planes, PWORD bpp, PLONG compr, PLONG size );
INT APIENTRY INT APIENTRY
@ -13,7 +13,7 @@ DIB_GetDIBImageBytes (INT width, INT height, INT depth);
INT FASTCALL INT FASTCALL
DIB_GetDIBWidthBytes (INT width, INT depth); DIB_GetDIBWidthBytes (INT width, INT depth);
RGBQUAD * FASTCALL RGBQUAD * FASTCALL
DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi); DIB_MapPaletteColors(PDC dc, CONST BITMAPV5INFO* lpbmi);
HPALETTE FASTCALL HPALETTE FASTCALL
BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType); BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType);

View file

@ -247,7 +247,7 @@ renderBITMAPfromDIB(LPBYTE pDIB)
{ {
HDC hdc; HDC hdc;
HBITMAP hbitmap; HBITMAP hbitmap;
unsigned int offset; unsigned int offset = 0; /* Stupid compiler */
BITMAPV5INFO bmi; BITMAPV5INFO bmi;
NTSTATUS Status ; NTSTATUS Status ;

View file

@ -291,7 +291,7 @@ IntCreateCompatibleBitmap(
PSURFACE psurfBmp; PSURFACE psurfBmp;
size.cx = abs(Width); size.cx = abs(Width);
size.cy = abs(Height); size.cy = abs(Height);
Bmp = GreCreateBitmap(abs(Width), Bmp = GreCreateBitmap(abs(Width),
abs(Height), abs(Height),
1, 1,
dibs.dsBm.bmBitsPixel, dibs.dsBm.bmBitsPixel,
@ -309,73 +309,61 @@ IntCreateCompatibleBitmap(
else else
{ {
/* A DIB section is selected in the DC */ /* A DIB section is selected in the DC */
BITMAPINFO *bi; BITMAPV5INFO bi;
PVOID Bits; PVOID Bits;
/* Allocate memory for a BITMAPINFOHEADER structure and a RtlZeroMemory(&bi.bmiHeader, sizeof(bi.bmiHeader));
color table. The maximum number of colors in a color table bi.bmiHeader.bV5Size = sizeof(bi.bmiHeader);
is 256 which corresponds to a bitmap with depth 8. bi.bmiHeader.bV5Width = Width;
Bitmaps with higher depths don't have color tables. */ bi.bmiHeader.bV5Height = Height;
bi = ExAllocatePoolWithTag(PagedPool, bi.bmiHeader.bV5Planes = dibs.dsBmih.biPlanes;
sizeof(BITMAPINFOHEADER) + bi.bmiHeader.bV5BitCount = dibs.dsBmih.biBitCount;
256 * sizeof(RGBQUAD), bi.bmiHeader.bV5Compression = dibs.dsBmih.biCompression;
TAG_TEMP); bi.bmiHeader.bV5SizeImage = 0;
bi.bmiHeader.bV5XPelsPerMeter = dibs.dsBmih.biXPelsPerMeter;
bi.bmiHeader.bV5YPelsPerMeter = dibs.dsBmih.biYPelsPerMeter;
bi.bmiHeader.bV5ClrUsed = dibs.dsBmih.biClrUsed;
bi.bmiHeader.bV5ClrImportant = dibs.dsBmih.biClrImportant;
if (bi) if (bi.bmiHeader.bV5Compression == BI_BITFIELDS)
{ {
bi->bmiHeader.biSize = sizeof(bi->bmiHeader); /* Copy the color masks */
bi->bmiHeader.biWidth = Width; bi.bmiHeader.bV5RedMask = dibs.dsBitfields[0];
bi->bmiHeader.biHeight = Height; bi.bmiHeader.bV5GreenMask = dibs.dsBitfields[1];
bi->bmiHeader.biPlanes = dibs.dsBmih.biPlanes; bi.bmiHeader.bV5BlueMask = dibs.dsBitfields[2];
bi->bmiHeader.biBitCount = dibs.dsBmih.biBitCount; }
bi->bmiHeader.biCompression = dibs.dsBmih.biCompression; else if (bi.bmiHeader.bV5BitCount <= 8)
bi->bmiHeader.biSizeImage = 0; {
bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter; /* Copy the color table */
bi->bmiHeader.biYPelsPerMeter = dibs.dsBmih.biYPelsPerMeter; UINT Index;
bi->bmiHeader.biClrUsed = dibs.dsBmih.biClrUsed; PPALETTE PalGDI;
bi->bmiHeader.biClrImportant = dibs.dsBmih.biClrImportant;
if (bi->bmiHeader.biCompression == BI_BITFIELDS) if (!psurf->ppal)
{ {
/* Copy the color masks */ SetLastWin32Error(ERROR_INVALID_HANDLE);
RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3 * sizeof(DWORD)); return 0;
} }
else if (bi->bmiHeader.biBitCount <= 8)
PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
for (Index = 0;
Index < 256 && Index < PalGDI->NumColors;
Index++)
{ {
/* Copy the color table */ bi.bmiColors[Index].rgbRed = PalGDI->IndexedColors[Index].peRed;
UINT Index; bi.bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
PPALETTE PalGDI; bi.bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
bi.bmiColors[Index].rgbReserved = 0;
if (!psurf->ppal)
{
ExFreePoolWithTag(bi, TAG_TEMP);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
for (Index = 0;
Index < 256 && Index < PalGDI->NumColors;
Index++)
{
bi->bmiColors[Index].rgbRed = PalGDI->IndexedColors[Index].peRed;
bi->bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
bi->bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
bi->bmiColors[Index].rgbReserved = 0;
}
PALETTE_UnlockPalette(PalGDI);
} }
PALETTE_UnlockPalette(PalGDI);
Bmp = DIB_CreateDIBSection(Dc, Bmp = DIB_CreateDIBSection(Dc,
bi, &bi,
DIB_RGB_COLORS, DIB_RGB_COLORS,
&Bits, &Bits,
NULL, NULL,
0, 0,
0); 0);
ExFreePoolWithTag(bi, TAG_TEMP);
return Bmp; return Bmp;
} }
} }

View file

@ -218,7 +218,7 @@ IntSetDIBits(
UINT StartScan, UINT StartScan,
UINT ScanLines, UINT ScanLines,
CONST VOID *Bits, CONST VOID *Bits,
CONST BITMAPINFO *bmi, CONST BITMAPV5INFO *bmi,
UINT ColorUse) UINT ColorUse)
{ {
SURFACE *bitmap; SURFACE *bitmap;
@ -251,16 +251,16 @@ IntSetDIBits(
DestSurf = &bitmap->SurfObj; DestSurf = &bitmap->SurfObj;
// Create source surface // Create source surface
SourceSize.cx = bmi->bmiHeader.biWidth; SourceSize.cx = bmi->bmiHeader.bV5Width;
SourceSize.cy = ScanLines; SourceSize.cy = ScanLines;
// Determine width of DIB // Determine width of DIB
DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount); DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.bV5BitCount);
SourceBitmap = EngCreateBitmap(SourceSize, SourceBitmap = EngCreateBitmap(SourceSize,
DIBWidth, DIBWidth,
BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression), BitmapFormat(bmi->bmiHeader.bV5BitCount, bmi->bmiHeader.bV5Compression),
bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0, bmi->bmiHeader.bV5Height < 0 ? BMF_TOPDOWN : 0,
(PVOID) Bits); (PVOID) Bits);
if (0 == SourceBitmap) if (0 == SourceBitmap)
{ {
@ -281,7 +281,7 @@ IntSetDIBits(
ASSERT(bitmap->ppal); ASSERT(bitmap->ppal);
// Source palette obtained from the BITMAPINFO // Source palette obtained from the BITMAPINFO
DIB_Palette = BuildDIBPalette(bmi, (PINT)&DIB_Palette_Type); DIB_Palette = BuildDIBPalette((BITMAPINFO*)bmi, (PINT)&DIB_Palette_Type);
if (NULL == DIB_Palette) if (NULL == DIB_Palette)
{ {
EngUnlockSurface(SourceSurf); EngUnlockSurface(SourceSurf);
@ -302,7 +302,7 @@ IntSetDIBits(
// Determine destination rectangle // Determine destination rectangle
DestRect.left = 0; DestRect.left = 0;
DestRect.top = abs(bmi->bmiHeader.biHeight) - StartScan - ScanLines; DestRect.top = abs(bmi->bmiHeader.bV5Height) - StartScan - ScanLines;
DestRect.right = SourceSize.cx; DestRect.right = SourceSize.cx;
DestRect.bottom = DestRect.top + ScanLines; DestRect.bottom = DestRect.top + ScanLines;
@ -380,7 +380,7 @@ NtGdiSetDIBits(
return 0; return 0;
} }
Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, (PBITMAPINFO)&bmiLocal, ColorUse); Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, &bmiLocal, ColorUse);
DC_UnlockDc(Dc); DC_UnlockDc(Dc);
@ -1019,7 +1019,7 @@ NtGdiStretchDIBitsInternal(
* a INT, so we need make the negtive value to positve and that make the * a INT, so we need make the negtive value to positve and that make the
* count correct for negtive bitmap, TODO : we need testcase for this api */ * count correct for negtive bitmap, TODO : we need testcase for this api */
IntSetDIBits(pDC, hBitmap, 0, abs(bmiLocal.bmiHeader.bV5Height), Bits, IntSetDIBits(pDC, hBitmap, 0, abs(bmiLocal.bmiHeader.bV5Height), Bits,
(PBITMAPINFO)&bmiLocal, Usage); &bmiLocal, Usage);
DC_UnlockDc(pDC); DC_UnlockDc(pDC);
} }
@ -1107,7 +1107,7 @@ IntCreateDIBitmap(
if (NULL != handle && CBM_INIT == init) if (NULL != handle && CBM_INIT == init)
{ {
IntSetDIBits(Dc, handle, 0, height, bits, (BITMAPINFO*)data, coloruse); IntSetDIBits(Dc, handle, 0, height, bits, data, coloruse);
} }
return handle; return handle;
@ -1231,9 +1231,27 @@ NtGdiCreateDIBSection(
HBITMAP hbitmap = 0; HBITMAP hbitmap = 0;
DC *dc; DC *dc;
BOOL bDesktopDC = FALSE; BOOL bDesktopDC = FALSE;
BITMAPV5INFO bmiLocal;
NTSTATUS Status;
if (!bmi) return hbitmap; // Make sure. if (!bmi) return hbitmap; // Make sure.
_SEH2_TRY
{
Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, Usage, 0);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return NULL;
}
// If the reference hdc is null, take the desktop dc // If the reference hdc is null, take the desktop dc
if (hDC == 0) if (hDC == 0)
{ {
@ -1244,7 +1262,7 @@ NtGdiCreateDIBSection(
if ((dc = DC_LockDc(hDC))) if ((dc = DC_LockDc(hDC)))
{ {
hbitmap = DIB_CreateDIBSection(dc, hbitmap = DIB_CreateDIBSection(dc,
(BITMAPINFO*)bmi, &bmiLocal,
Usage, Usage,
Bits, Bits,
hSection, hSection,
@ -1267,7 +1285,7 @@ HBITMAP
APIENTRY APIENTRY
DIB_CreateDIBSection( DIB_CreateDIBSection(
PDC dc, PDC dc,
BITMAPINFO *bmi, CONST BITMAPV5INFO *bmi,
UINT usage, UINT usage,
LPVOID *bits, LPVOID *bits,
HANDLE section, HANDLE section,
@ -1278,42 +1296,43 @@ DIB_CreateDIBSection(
SURFACE *bmp = NULL; SURFACE *bmp = NULL;
void *mapBits = NULL; void *mapBits = NULL;
HPALETTE hpal ; HPALETTE hpal ;
ULONG palMode = PAL_INDEXED;
// Fill BITMAP32 structure with DIB data // Fill BITMAP32 structure with DIB data
BITMAPINFOHEADER *bi = &bmi->bmiHeader; CONST BITMAPV5HEADER *bi = &bmi->bmiHeader;
INT effHeight; INT effHeight;
ULONG totalSize; ULONG totalSize;
BITMAP bm; BITMAP bm;
SIZEL Size; SIZEL Size;
RGBQUAD *lpRGB; CONST RGBQUAD *lpRGB = NULL;
HANDLE hSecure; HANDLE hSecure;
DWORD dsBitfields[3] = {0}; DWORD dsBitfields[3] = {0};
ULONG ColorCount; ULONG ColorCount;
DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n", DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount, bi->bV5Width, bi->bV5Height, bi->bV5Planes, bi->bV5BitCount,
bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB"); bi->bV5SizeImage, bi->bV5ClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
/* CreateDIBSection should fail for compressed formats */ /* CreateDIBSection should fail for compressed formats */
if (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8) if (bi->bV5Compression == BI_RLE4 || bi->bV5Compression == BI_RLE8)
{ {
return (HBITMAP)NULL; return (HBITMAP)NULL;
} }
effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight; effHeight = bi->bV5Height >= 0 ? bi->bV5Height : -bi->bV5Height;
bm.bmType = 0; bm.bmType = 0;
bm.bmWidth = bi->biWidth; bm.bmWidth = bi->bV5Width;
bm.bmHeight = effHeight; bm.bmHeight = effHeight;
bm.bmWidthBytes = ovr_pitch ? ovr_pitch : (ULONG) DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount); bm.bmWidthBytes = ovr_pitch ? ovr_pitch : (ULONG) DIB_GetDIBWidthBytes(bm.bmWidth, bi->bV5BitCount);
bm.bmPlanes = bi->biPlanes; bm.bmPlanes = bi->bV5Planes;
bm.bmBitsPixel = bi->biBitCount; bm.bmBitsPixel = bi->bV5BitCount;
bm.bmBits = NULL; 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 biSizeImage if it's valid and
// we're dealing with a compressed bitmap. Otherwise, use width * height. // we're dealing with a compressed bitmap. Otherwise, use width * height.
totalSize = bi->biSizeImage && bi->biCompression != BI_RGB totalSize = bi->bV5SizeImage && bi->bV5Compression != BI_RGB
? bi->biSizeImage : (ULONG)(bm.bmWidthBytes * effHeight); ? bi->bV5SizeImage : (ULONG)(bm.bmWidthBytes * effHeight);
if (section) if (section)
{ {
@ -1333,7 +1352,7 @@ DIB_CreateDIBSection(
} }
mapOffset = offset - (offset % Sbi.AllocationGranularity); mapOffset = offset - (offset % Sbi.AllocationGranularity);
mapSize = bi->biSizeImage + (offset - mapOffset); mapSize = bi->bV5SizeImage + (offset - mapOffset);
SectionOffset.LowPart = mapOffset; SectionOffset.LowPart = mapOffset;
SectionOffset.HighPart = 0; SectionOffset.HighPart = 0;
@ -1362,6 +1381,7 @@ DIB_CreateDIBSection(
{ {
offset = 0; offset = 0;
bm.bmBits = EngAllocUserMem(totalSize, 0); bm.bmBits = EngAllocUserMem(totalSize, 0);
if(!bm.bmBits) goto cleanup;
} }
// hSecure = MmSecureVirtualMemory(bm.bmBits, totalSize, PAGE_READWRITE); // hSecure = MmSecureVirtualMemory(bm.bmBits, totalSize, PAGE_READWRITE);
@ -1370,52 +1390,54 @@ DIB_CreateDIBSection(
if (usage == DIB_PAL_COLORS) if (usage == DIB_PAL_COLORS)
{ {
lpRGB = DIB_MapPaletteColors(dc, bmi); lpRGB = DIB_MapPaletteColors(dc, bmi);
ColorCount = bi->biClrUsed; ColorCount = bi->bV5ClrUsed;
if (ColorCount == 0) if (ColorCount == 0)
{ {
ColorCount = 1 << bi->biBitCount; ColorCount = max(1 << bi->bV5BitCount, 256);
} }
} }
else else if(bi->bV5BitCount <= 8)
{ {
lpRGB = bmi->bmiColors; lpRGB = bmi->bmiColors;
ColorCount = 1 << bi->biBitCount; ColorCount = 1 << bi->bV5BitCount;
} }
else
{
lpRGB = NULL;
ColorCount = 0;
}
/* Set dsBitfields values */ /* Set dsBitfields values */
if (usage == DIB_PAL_COLORS || bi->biBitCount <= 8) if (usage == DIB_PAL_COLORS || bi->bV5BitCount <= 8)
{ {
dsBitfields[0] = dsBitfields[1] = dsBitfields[2] = 0; dsBitfields[0] = dsBitfields[1] = dsBitfields[2] = 0;
palMode = PAL_INDEXED;
} }
else if (bi->biCompression == BI_RGB) else if (bi->bV5Compression == BI_RGB)
{ {
switch (bi->biBitCount) dsBitfields[0] = dsBitfields[1] = dsBitfields[2] = 0;
switch (bi->bV5BitCount)
{ {
case 15: case 15:
dsBitfields[0] = 0x7c00; palMode = PAL_RGB16_555;
dsBitfields[1] = 0x03e0; break;
dsBitfields[2] = 0x001f;
break;
case 16: case 16:
dsBitfields[0] = 0xF800; palMode = PAL_RGB16_565;
dsBitfields[1] = 0x07e0;
dsBitfields[2] = 0x001f;
break; break;
case 24: case 24:
case 32: case 32:
dsBitfields[0] = 0xff0000; palMode = PAL_RGB;
dsBitfields[1] = 0x00ff00;
dsBitfields[2] = 0x0000ff;
break; break;
} }
} }
else else
{ {
dsBitfields[0] = ((DWORD*)bmi->bmiColors)[0]; dsBitfields[0] = bi->bV5RedMask;
dsBitfields[1] = ((DWORD*)bmi->bmiColors)[1]; dsBitfields[1] = bi->bV5GreenMask;
dsBitfields[2] = ((DWORD*)bmi->bmiColors)[2]; dsBitfields[2] = bi->bV5BlueMask;
palMode = PAL_BITFIELDS;
} }
// Create Device Dependent Bitmap and add DIB pointer // Create Device Dependent Bitmap and add DIB pointer
@ -1424,45 +1446,27 @@ DIB_CreateDIBSection(
res = GreCreateBitmapEx(bm.bmWidth, res = GreCreateBitmapEx(bm.bmWidth,
abs(bm.bmHeight), abs(bm.bmHeight),
bm.bmWidthBytes, bm.bmWidthBytes,
BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression), BitmapFormat(bi->bV5BitCount * bi->bV5Planes, bi->bV5Compression),
BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT | BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
(bi->biHeight < 0 ? BMF_TOPDOWN : 0), (bi->bV5Height < 0 ? BMF_TOPDOWN : 0),
bi->biSizeImage, bi->bV5SizeImage,
bm.bmBits); bm.bmBits);
if (!res) if (!res)
{ {
if (lpRGB != bmi->bmiColors)
{
ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
}
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
return NULL; goto cleanup;
} }
bmp = SURFACE_LockSurface(res); bmp = SURFACE_LockSurface(res);
if (NULL == bmp) if (NULL == bmp)
{ {
if (lpRGB != bmi->bmiColors) SetLastWin32Error(ERROR_INVALID_HANDLE);
{ goto cleanup;
ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
}
SetLastWin32Error(ERROR_INVALID_HANDLE);
GreDeleteObject(res);
return NULL;
} }
/* WINE NOTE: WINE makes use of a colormap, which is a color translation /* WINE NOTE: WINE makes use of a colormap, which is a color translation
table between the DIB and the X physical device. Obviously, table between the DIB and the X physical device. Obviously,
this is left out of the ReactOS implementation. Instead, this is left out of the ReactOS implementation. Instead,
we call NtGdiSetDIBColorTable. */ we call NtGdiSetDIBColorTable. */
if (bi->biBitCount <= 8)
{
bi->biClrUsed = 1 << bi->biBitCount;
}
else
{
bi->biClrUsed = 0;
}
bmp->hDIBSection = section; bmp->hDIBSection = section;
bmp->hSecure = hSecure; bmp->hSecure = hSecure;
bmp->dwOffset = offset; bmp->dwOffset = offset;
@ -1470,26 +1474,20 @@ DIB_CreateDIBSection(
bmp->dsBitfields[0] = dsBitfields[0]; bmp->dsBitfields[0] = dsBitfields[0];
bmp->dsBitfields[1] = dsBitfields[1]; bmp->dsBitfields[1] = dsBitfields[1];
bmp->dsBitfields[2] = dsBitfields[2]; bmp->dsBitfields[2] = dsBitfields[2];
bmp->biClrUsed = bi->biClrUsed; bmp->biClrUsed = ColorCount;
bmp->biClrImportant = bi->biClrImportant; bmp->biClrImportant = bi->bV5ClrImportant;
if (bi->biClrUsed != 0) hpal = PALETTE_AllocPalette(palMode, ColorCount, (ULONG*)lpRGB,
{
hpal = PALETTE_AllocPaletteIndexedRGB(ColorCount, lpRGB);
}
else
{
hpal = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL,
dsBitfields[0], dsBitfields[0],
dsBitfields[1], dsBitfields[1],
dsBitfields[2]); dsBitfields[2]);
}
bmp->ppal = PALETTE_ShareLockPalette(hpal); bmp->ppal = PALETTE_ShareLockPalette(hpal);
/* Lazy delete hpal, it will be freed at surface release */ /* Lazy delete hpal, it will be freed at surface release */
GreDeleteObject(hpal); GreDeleteObject(hpal);
// Clean up in case of errors // Clean up in case of errors
cleanup:
if (!res || !bmp || !bm.bmBits) if (!res || !bmp || !bm.bmBits)
{ {
DPRINT("got an error res=%08x, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits); DPRINT("got an error res=%08x, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits);
@ -1516,9 +1514,9 @@ DIB_CreateDIBSection(
} }
} }
if (lpRGB != bmi->bmiColors) if (lpRGB != bmi->bmiColors && lpRGB)
{ {
ExFreePoolWithTag(lpRGB, TAG_COLORMAP); ExFreePoolWithTag((PVOID)lpRGB, TAG_COLORMAP);
} }
if (bmp) if (bmp)
@ -1586,7 +1584,7 @@ INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse)
RGBQUAD * RGBQUAD *
FASTCALL FASTCALL
DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi) DIB_MapPaletteColors(PDC dc, CONST BITMAPV5INFO* lpbmi)
{ {
RGBQUAD *lpRGB; RGBQUAD *lpRGB;
ULONG nNumColors,i; ULONG nNumColors,i;
@ -1606,10 +1604,10 @@ DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi)
return NULL; return NULL;
} }
nNumColors = 1 << lpbmi->bmiHeader.biBitCount; nNumColors = 1 << lpbmi->bmiHeader.bV5BitCount;
if (lpbmi->bmiHeader.biClrUsed) if (lpbmi->bmiHeader.bV5ClrUsed)
{ {
nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed); nNumColors = min(nNumColors, lpbmi->bmiHeader.bV5ClrUsed);
} }
lpRGB = (RGBQUAD *)ExAllocatePoolWithTag(PagedPool, sizeof(RGBQUAD) * nNumColors, TAG_COLORMAP); lpRGB = (RGBQUAD *)ExAllocatePoolWithTag(PagedPool, sizeof(RGBQUAD) * nNumColors, TAG_COLORMAP);
@ -1767,6 +1765,8 @@ ProbeAndConvertToBitmapV5Info(
dwSize = pbmiUnsafe->bmiHeader.biSize; dwSize = pbmiUnsafe->bmiHeader.biSize;
/* At least dwSize bytes must be valids */ /* At least dwSize bytes must be valids */
ProbeForRead(pbmiUnsafe, max(dwSize, MaxSize), 1); ProbeForRead(pbmiUnsafe, max(dwSize, MaxSize), 1);
if(!MaxSize)
ProbeForRead(pbmiUnsafe, DIB_BitmapInfoSize(pbmiUnsafe, dwColorUse), 1);
/* Check the size */ /* Check the size */
// FIXME: are intermediate sizes allowed? As what are they interpreted? // FIXME: are intermediate sizes allowed? As what are they interpreted?