Author: jgardou
Date: Tue Jun 8 02:40:42 2010
New Revision: 47690
URL:
http://svn.reactos.org/svn/reactos?rev=47690&view=rev
Log:
[WIN32K]
- remove duplicate prototypes.
- Add missing trail to debug print
- replace some now superfluous checks on bitmap palette with sanity ASSERTS
- begin using BITMAPV5HEADER as a default bitmap format, and introduce conversion to and
from everything prior that.
Congratulations to BITMAPCOREHEADER, for its backward compatibility personal failure.
Modified:
branches/reactos-yarotows/subsystems/win32/win32k/include/bitmaps.h
branches/reactos-yarotows/subsystems/win32/win32k/misc/file.c
branches/reactos-yarotows/subsystems/win32/win32k/objects/bitblt.c
branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c
Modified: branches/reactos-yarotows/subsystems/win32/win32k/include/bitmaps.h
URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/include/bitmaps.h [iso-8859-1]
(original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/include/bitmaps.h [iso-8859-1] Tue
Jun 8 02:40:42 2010
@@ -2,14 +2,19 @@
#include "surface.h"
-INT FASTCALL DIB_GetDIBWidthBytes (INT width, INT depth);
-int APIENTRY DIB_GetDIBImageBytes (INT width, INT height, INT depth);
-INT FASTCALL DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse);
+typedef struct tagBITMAPV5INFO
+{
+ BITMAPV5HEADER bmiHeader;
+ RGBQUAD bmiColors[256];
+} BITMAPV5INFO, *PBITMAPV5INFO;
+
INT APIENTRY BITMAP_GetObject(SURFACE * bmp, INT count, LPVOID buffer);
HBITMAP FASTCALL IntCreateBitmap(IN SIZEL Size, IN LONG Width, IN ULONG Format, IN ULONG
Flags, IN PVOID Bits);
HBITMAP FASTCALL BITMAP_CopyBitmap (HBITMAP hBitmap);
UINT FASTCALL BITMAP_GetRealBitsPixel(UINT nBitsPixel);
INT FASTCALL BITMAP_GetWidthBytes (INT bmWidth, INT bpp);
+NTSTATUS FASTCALL ProbeAndConvertToBitmapV5Info( OUT PBITMAPV5INFO pbmiDst, IN CONST
BITMAPINFO* pbmiUnsafe, IN DWORD dwUse);
+VOID FASTCALL GetBMIFromBitmapV5Info(IN PBITMAPV5INFO pbmiSrc, OUT PBITMAPINFO pbmiDst,
IN DWORD dwUse);
HBITMAP
APIENTRY
Modified: branches/reactos-yarotows/subsystems/win32/win32k/misc/file.c
URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/misc/file.c [iso-8859-1] (original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/misc/file.c [iso-8859-1] Tue Jun 8
02:40:42 2010
@@ -149,144 +149,8 @@
return pvBase;
}
-typedef struct tagBITMAPV5INFO
-{
- BITMAPV5HEADER bmiHeader;
- RGBQUAD bmiColors[256];
-} BITMAPV5INFO, *PBITMAPV5INFO;
-
// FIXME: this should go to dibobj.c
-NTSTATUS
-ProbeAndConvertBitmapInfo(
- OUT BITMAPV5HEADER *pbmhDst,
- OUT RGBQUAD *pbmiColorsDst,
- ULONG cColors,
- IN PBITMAPINFO pbmiUnsafe)
-{
- DWORD dwSize;
- RGBQUAD *pbmiColors;
- ULONG ulWidthBytes;
-
- /* Get the size and probe */
- ProbeForRead(&pbmiUnsafe->bmiHeader.biSize, sizeof(DWORD), 1);
- dwSize = pbmiUnsafe->bmiHeader.biSize;
- ProbeForRead(pbmiUnsafe, dwSize, 1);
-
- /* Check the size */
- // FIXME: are intermediate sizes allowed? As what are they interpreted?
- // make sure we don't use a too big dwSize later
- if (dwSize != sizeof(BITMAPCOREHEADER) &&
- dwSize != sizeof(BITMAPINFOHEADER) &&
- dwSize != sizeof(BITMAPV4HEADER) &&
- dwSize != sizeof(BITMAPV5HEADER))
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- pbmiColors = (RGBQUAD*)((PCHAR)pbmiUnsafe + dwSize);
-
- pbmhDst->bV5Size = sizeof(BITMAPV5HEADER);
-
- if (dwSize == sizeof(BITMAPCOREHEADER))
- {
- PBITMAPCOREHEADER pbch = (PBITMAPCOREHEADER)pbmiUnsafe;
-
- /* Manually copy the fields that are present */
- pbmhDst->bV5Width = pbch->bcWidth;
- pbmhDst->bV5Height = pbch->bcHeight;
- pbmhDst->bV5Planes = pbch->bcPlanes;
- pbmhDst->bV5BitCount = pbch->bcBitCount;
-
- /* Set some default values */
- pbmhDst->bV5Compression = BI_RGB;
- pbmhDst->bV5SizeImage = 0;
- pbmhDst->bV5XPelsPerMeter = 72;
- pbmhDst->bV5YPelsPerMeter = 72;
- pbmhDst->bV5ClrUsed = 0;
- pbmhDst->bV5ClrImportant = 0;
- }
- else
- {
- /* Copy valid fields */
- memcpy(pbmhDst, pbmiUnsafe, dwSize);
-
- /* Zero out the rest of the V5 header */
- memset((char*)pbmhDst + dwSize, 0, sizeof(BITMAPV5HEADER) - dwSize);
- }
-
-
- if (dwSize < sizeof(BITMAPV4HEADER))
- {
- if (pbmhDst->bV5Compression == BI_BITFIELDS)
- {
- DWORD *pMasks = (DWORD*)pbmiColors;
- pbmhDst->bV5RedMask = pMasks[0];
- pbmhDst->bV5GreenMask = pMasks[1];
- pbmhDst->bV5BlueMask = pMasks[2];
- pbmhDst->bV5AlphaMask = 0;
- pbmhDst->bV5ClrUsed = 0;
- }
-
-// pbmhDst->bV5CSType;
-// pbmhDst->bV5Endpoints;
-// pbmhDst->bV5GammaRed;
-// pbmhDst->bV5GammaGreen;
-// pbmhDst->bV5GammaBlue;
- }
-
- if (dwSize < sizeof(BITMAPV5HEADER))
- {
-// pbmhDst->bV5Intent;
-// pbmhDst->bV5ProfileData;
-// pbmhDst->bV5ProfileSize;
-// pbmhDst->bV5Reserved;
- }
-
- ulWidthBytes = ((pbmhDst->bV5Width * pbmhDst->bV5Planes *
- pbmhDst->bV5BitCount + 31) & ~31) / 8;
-
- if (pbmhDst->bV5SizeImage == 0)
- pbmhDst->bV5SizeImage = abs(ulWidthBytes * pbmhDst->bV5Height);
-
- if (pbmhDst->bV5ClrUsed == 0)
- pbmhDst->bV5ClrUsed = pbmhDst->bV5BitCount == 1 ? 2 :
- (pbmhDst->bV5BitCount == 4 ? 16 :
- (pbmhDst->bV5BitCount == 8 ? 256 : 0));
-
- if (pbmhDst->bV5Planes != 1)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- if (pbmhDst->bV5BitCount != 0 && pbmhDst->bV5BitCount != 1 &&
- pbmhDst->bV5BitCount != 4 && pbmhDst->bV5BitCount != 8 &&
- pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 24
&&
- pbmhDst->bV5BitCount != 32)
- {
- DPRINT("Invalid bit count: %d\n", pbmhDst->bV5BitCount);
- return STATUS_INVALID_PARAMETER;
- }
-
- if ((pbmhDst->bV5BitCount == 0 &&
- pbmhDst->bV5Compression != BI_JPEG && pbmhDst->bV5Compression !=
BI_PNG))
- {
- DPRINT("Bit count 0 is invalid for compression %d.\n",
pbmhDst->bV5Compression);
- return STATUS_INVALID_PARAMETER;
- }
-
- if (pbmhDst->bV5Compression == BI_BITFIELDS &&
- pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 32)
- {
- DPRINT("Bit count %d is invalid for compression BI_BITFIELDS.\n",
pbmhDst->bV5BitCount);
- return STATUS_INVALID_PARAMETER;
- }
-
- /* Copy Colors */
- cColors = min(cColors, pbmhDst->bV5ClrUsed);
- memcpy(pbmiColorsDst, pbmiColors, cColors * sizeof(RGBQUAD));
-
- return STATUS_SUCCESS;
-}
+
HBITMAP
@@ -333,10 +197,9 @@
/* Create a normalized local BITMAPINFO */
_SEH2_TRY
{
- Status = ProbeAndConvertBitmapInfo(&bmiLocal.bmiHeader,
- bmiLocal.bmiColors,
- 256,
- pbmi);
+ Status = ProbeAndConvertToBitmapV5Info(&bmiLocal,
+ pbmi,
+ DIB_RGB_COLORS);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/bitblt.c
URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/objects/bitblt.c [iso-8859-1]
(original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/objects/bitblt.c [iso-8859-1] Tue
Jun 8 02:40:42 2010
@@ -757,7 +757,7 @@
}
else if(DCSrc)
{
- DPRINT1("Getting a valid Source handle without using source!!!");
+ DPRINT1("Getting a valid Source handle without using source!!!\n");
GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
DCSrc = NULL ;
}
Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c
URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c [iso-8859-1]
(original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c [iso-8859-1] Tue
Jun 8 02:40:42 2010
@@ -221,16 +221,16 @@
CONST BITMAPINFO *bmi,
UINT ColorUse)
{
- SURFACE *bitmap;
+ SURFACE *bitmap;
HBITMAP SourceBitmap;
INT result = 0;
BOOL copyBitsResult;
- SURFOBJ *DestSurf, *SourceSurf;
+ SURFOBJ *DestSurf, *SourceSurf;
SIZEL SourceSize;
POINTL ZeroPoint;
RECTL DestRect;
EXLATEOBJ exlo;
- PPALETTE ppalDDB, ppalDIB;
+ PPALETTE ppalDIB;
//RGBQUAD *lpRGB;
HPALETTE DIB_Palette;
ULONG DIB_Palette_Type;
@@ -278,32 +278,15 @@
return 0;
}
- if (bitmap->ppal)
- {
- ppalDDB = bitmap->ppal;
- GDIOBJ_IncrementShareCount(&ppalDDB->BaseObject);
- }
- else
- // Destination palette obtained from the hDC
- ppalDDB = PALETTE_ShareLockPalette(DC->ppdev->devinfo.hpalDefault);
-
- if (NULL == ppalDDB)
+ ASSERT(bitmap->ppal);
+
+ // Source palette obtained from the BITMAPINFO
+ DIB_Palette = BuildDIBPalette(bmi, (PINT)&DIB_Palette_Type);
+ if (NULL == DIB_Palette)
{
EngUnlockSurface(SourceSurf);
EngDeleteSurface((HSURF)SourceBitmap);
SURFACE_UnlockSurface(bitmap);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
-
- // Source palette obtained from the BITMAPINFO
- DIB_Palette = BuildDIBPalette((PBITMAPINFO)bmi, (PINT)&DIB_Palette_Type);
- if (NULL == DIB_Palette)
- {
- EngUnlockSurface(SourceSurf);
- EngDeleteSurface((HSURF)SourceBitmap);
- SURFACE_UnlockSurface(bitmap);
- PALETTE_ShareUnlockPalette(ppalDDB);
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
return 0;
}
@@ -311,7 +294,7 @@
ppalDIB = PALETTE_LockPalette(DIB_Palette);
/* Initialize XLATEOBJ for color translation */
- EXLATEOBJ_vInitialize(&exlo, ppalDIB, ppalDDB, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exlo, ppalDIB, bitmap->ppal, 0, 0, 0);
// Zero point
ZeroPoint.x = 0;
@@ -336,7 +319,6 @@
// Clean up
EXLATEOBJ_vCleanup(&exlo);
PALETTE_UnlockPalette(ppalDIB);
- PALETTE_ShareUnlockPalette(ppalDDB);
PALETTE_FreePaletteByHandle(DIB_Palette);
EngUnlockSurface(SourceSurf);
EngDeleteSurface((HSURF)SourceBitmap);
@@ -366,17 +348,13 @@
PDC Dc;
INT Ret;
NTSTATUS Status = STATUS_SUCCESS;
- UINT cjBits;
+ BITMAPV5INFO bmiLocal;
if (!Bits) return 0;
_SEH2_TRY
- { // FYI: We converted from CORE in gdi.
- ProbeForRead(bmi, sizeof(BITMAPINFO), 1);
- cjBits = bmi->bmiHeader.biBitCount * bmi->bmiHeader.biPlanes *
bmi->bmiHeader.biWidth;
- cjBits = ((cjBits + 31) & ~31) / 8;
- cjBits *= ScanLines;
- ProbeForRead(Bits, cjBits, 1);
+ {
+ Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -401,7 +379,7 @@
return 0;
}
- Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
+ Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits,
(PBITMAPINFO)&bmiLocal, ColorUse);
DC_UnlockDc(Dc);
@@ -440,16 +418,16 @@
INT DIBWidth;
SIZEL SourceSize;
EXLATEOBJ exlo;
- PPALETTE ppalDDB = NULL, ppalDIB = NULL;
+ PPALETTE ppalDIB = NULL;
HPALETTE hpalDIB = NULL;
ULONG DIBPaletteType;
+ BITMAPV5INFO bmiLocal ;
if (!Bits) return 0;
_SEH2_TRY
{
- ProbeForRead(bmi, cjMaxInfo , 1);
- ProbeForRead(Bits, cjMaxBits, 1);
+ Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -478,7 +456,7 @@
pDestSurf = pSurf ? &pSurf->SurfObj : NULL;
- ScanLines = min(ScanLines, abs(bmi->bmiHeader.biHeight) - StartScan);
+ ScanLines = min(ScanLines, abs(bmiLocal.bmiHeader.bV5Height) - StartScan);
rcDest.left = XDest;
rcDest.top = YDest;
@@ -495,15 +473,16 @@
ptSource.x = XSrc;
ptSource.y = YSrc;
- SourceSize.cx = bmi->bmiHeader.biWidth;
+ SourceSize.cx = bmiLocal.bmiHeader.bV5Width;
SourceSize.cy = ScanLines;
- DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
+ DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmiLocal.bmiHeader.bV5BitCount);
hSourceBitmap = EngCreateBitmap(SourceSize,
DIBWidth,
- BitmapFormat(bmi->bmiHeader.biBitCount,
bmi->bmiHeader.biCompression),
- bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
+ BitmapFormat(bmiLocal.bmiHeader.bV5BitCount,
+ bmiLocal.bmiHeader.bV5Compression),
+ bmiLocal.bmiHeader.bV5Height < 0 ? BMF_TOPDOWN :
0,
(PVOID) Bits);
if (!hSourceBitmap)
{
@@ -519,42 +498,28 @@
goto Exit;
}
- /* Obtain destination palette */
- if (pSurf && pSurf->ppal)
- {
- ppalDDB = pSurf->ppal;
- GDIOBJ_IncrementShareCount(&ppalDDB->BaseObject);
- }
- else
- ppalDDB = PALETTE_ShareLockPalette(pDC->ppdev->devinfo.hpalDefault);
-
- if (!ppalDDB)
+ ASSERT(pSurf->ppal);
+
+ /* Create a palette for the DIB */
+ hpalDIB = BuildDIBPalette((PBITMAPINFO)&bmiLocal, (PINT)&DIBPaletteType);
+ if (!hpalDIB)
+ {
+ SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ Status = STATUS_NO_MEMORY;
+ goto Exit;
+ }
+
+ /* Lock the DIB palette */
+ ppalDIB = PALETTE_LockPalette(hpalDIB);
+ if (!ppalDIB)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
Status = STATUS_UNSUCCESSFUL;
goto Exit;
}
- /* Create a palette for the DIB */
- hpalDIB = BuildDIBPalette(bmi, (PINT)&DIBPaletteType);
- if (!hpalDIB)
- {
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- Status = STATUS_NO_MEMORY;
- goto Exit;
- }
-
- /* Lock the DIB palette */
- ppalDIB = PALETTE_LockPalette(hpalDIB);
- if (!ppalDIB)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- Status = STATUS_UNSUCCESSFUL;
- goto Exit;
- }
-
/* Initialize EXLATEOBJ */
- EXLATEOBJ_vInitialize(&exlo, ppalDIB, ppalDDB, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exlo, ppalDIB, pSurf->ppal, 0, 0, 0);
/* Copy the bits */
DPRINT("BitsToDev with dstsurf=(%d|%d) (%d|%d), src=(%d|%d) w=%d h=%d\n",
@@ -582,7 +547,6 @@
}
if (ppalDIB) PALETTE_UnlockPalette(ppalDIB);
- if (ppalDDB) PALETTE_ShareUnlockPalette(ppalDDB);
if (pSourceSurf) EngUnlockSurface(pSourceSurf);
if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
@@ -611,14 +575,12 @@
SURFACE *psurf = NULL;
HBITMAP hDestBitmap = NULL;
HPALETTE hDestPalette = NULL;
- PPALETTE ppalSrc = NULL;
+ BITMAPV5INFO bmiLocal ;
PPALETTE ppalDst = NULL;
NTSTATUS Status = STATUS_SUCCESS;
ULONG Result = 0;
BOOL bPaletteMatch = FALSE;
PBYTE ChkBits = Bits;
- PVOID ColorPtr;
- RGBQUAD *rgbQuads;
ULONG DestPaletteType;
ULONG Index;
@@ -633,9 +595,7 @@
_SEH2_TRY
{
- ProbeForRead(&Info->bmiHeader.biSize, sizeof(DWORD), 1);
-
- ProbeForWrite(Info, Info->bmiHeader.biSize, 1); // Comp for Core.
+ Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, Info, Usage);
if (ChkBits) ProbeForWrite(ChkBits, MaxBits, 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@@ -665,20 +625,9 @@
return 0;
}
- if (psurf->ppal)
- {
- ppalSrc = psurf->ppal;
- GDIOBJ_IncrementShareCount(&ppalSrc->BaseObject);
- }
- else
- ppalSrc = PALETTE_ShareLockPalette(Dc->ppdev->devinfo.hpalDefault);
+ ASSERT(psurf->ppal);
DC_UnlockDc(Dc);
-
- ASSERT(ppalSrc != NULL);
-
- ColorPtr = ((PBYTE)Info + Info->bmiHeader.biSize);
- rgbQuads = (RGBQUAD *)ColorPtr;
/* Copy palette information
* Always create a palette for 15 & 16 bit. */
@@ -686,53 +635,49 @@
Info->bmiHeader.biBitCount != 15 && Info->bmiHeader.biBitCount !=
16) ||
!ChkBits)
{
- ppalDst = ppalSrc;
+ ppalDst = psurf->ppal;
bPaletteMatch = TRUE;
}
else
- hDestPalette = BuildDIBPalette(Info, (PINT)&DestPaletteType); //hDestPalette
= Dc->DevInfo->hpalDefault;
-
- if (!bPaletteMatch)
- {
+ {
+ hDestPalette = BuildDIBPalette((PBITMAPINFO)&bmiLocal,
(PINT)&DestPaletteType);
ppalDst = PALETTE_LockPalette(hDestPalette);
- /* FIXME - ppalDst can be NULL!!!! Don't assert here!!! */
- DPRINT("ppalDst : %p\n", ppalDst);
- ASSERT(ppalDst);
- }
+ }
+
+ DPRINT("ppalDst : %p\n", ppalDst);
+ ASSERT(ppalDst);
/* Copy palette. */
- /* FIXME: This is largely incomplete. ATM no Core!*/
- switch (Info->bmiHeader.biBitCount)
+ switch (bmiLocal.bmiHeader.bV5BitCount)
{
case 1:
case 4:
case 8:
- Info->bmiHeader.biClrUsed = 0;
+ bmiLocal.bmiHeader.bV5ClrUsed = 0;
if (psurf->hSecure &&
- BitsPerFormat(psurf->SurfObj.iBitmapFormat) ==
Info->bmiHeader.biBitCount)
+ BitsPerFormat(psurf->SurfObj.iBitmapFormat) ==
bmiLocal.bmiHeader.bV5BitCount)
{
if (Usage == DIB_RGB_COLORS)
{
- if (ppalDst->NumColors != 1 <<
Info->bmiHeader.biBitCount)
- Info->bmiHeader.biClrUsed = ppalDst->NumColors;
+ if (ppalDst->NumColors != 1 <<
bmiLocal.bmiHeader.bV5BitCount)
+ bmiLocal.bmiHeader.bV5ClrUsed = ppalDst->NumColors;
for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount) &&
Index < ppalDst->NumColors;
+ Index < (1 << bmiLocal.bmiHeader.bV5BitCount)
&& Index < ppalDst->NumColors;
Index++)
{
- rgbQuads[Index].rgbRed =
ppalDst->IndexedColors[Index].peRed;
- rgbQuads[Index].rgbGreen =
ppalDst->IndexedColors[Index].peGreen;
- rgbQuads[Index].rgbBlue =
ppalDst->IndexedColors[Index].peBlue;
- rgbQuads[Index].rgbReserved = 0;
+ bmiLocal.bmiColors[Index].rgbRed =
ppalDst->IndexedColors[Index].peRed;
+ bmiLocal.bmiColors[Index].rgbGreen =
ppalDst->IndexedColors[Index].peGreen;
+ bmiLocal.bmiColors[Index].rgbBlue =
ppalDst->IndexedColors[Index].peBlue;
+ bmiLocal.bmiColors[Index].rgbReserved = 0;
}
}
else
{
- PWORD Ptr = ColorPtr;
for (Index = 0;
Index < (1 << Info->bmiHeader.biBitCount);
Index++)
{
- Ptr[Index] = (WORD)Index;
+ ((WORD*)bmiLocal.bmiColors)[Index] = Index;
}
}
}
@@ -740,12 +685,11 @@
{
if (Usage == DIB_PAL_COLORS)
{
- PWORD Ptr = ColorPtr;
for (Index = 0;
Index < (1 << Info->bmiHeader.biBitCount);
Index++)
{
- Ptr[Index] = (WORD)Index;
+ ((WORD*)bmiLocal.bmiColors)[Index] = (WORD)Index;
}
}
else if (Info->bmiHeader.biBitCount > 1 && bPaletteMatch)
@@ -754,33 +698,37 @@
Index < (1 << Info->bmiHeader.biBitCount) &&
Index < ppalDst->NumColors;
Index++)
{
- Info->bmiColors[Index].rgbRed =
ppalDst->IndexedColors[Index].peRed;
- Info->bmiColors[Index].rgbGreen =
ppalDst->IndexedColors[Index].peGreen;
- Info->bmiColors[Index].rgbBlue =
ppalDst->IndexedColors[Index].peBlue;
- Info->bmiColors[Index].rgbReserved = 0;
+ bmiLocal.bmiColors[Index].rgbRed =
ppalDst->IndexedColors[Index].peRed;
+ bmiLocal.bmiColors[Index].rgbGreen =
ppalDst->IndexedColors[Index].peGreen;
+ bmiLocal.bmiColors[Index].rgbBlue =
ppalDst->IndexedColors[Index].peBlue;
+ bmiLocal.bmiColors[Index].rgbReserved = 0;
}
}
else
{
- switch (Info->bmiHeader.biBitCount)
+ switch (bmiLocal.bmiHeader.bV5BitCount)
{
case 1:
- 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;
+ bmiLocal.bmiColors[0].rgbRed =0 ;
+ bmiLocal.bmiColors[0].rgbGreen = 0;
+ bmiLocal.bmiColors[0].rgbBlue = 0;
+ bmiLocal.bmiColors[0].rgbReserved = 0;
+ bmiLocal.bmiColors[1].rgbRed =0xFF ;
+ bmiLocal.bmiColors[1].rgbGreen = 0xFF;
+ bmiLocal.bmiColors[1].rgbBlue = 0xFF;
+ bmiLocal.bmiColors[1].rgbReserved = 0;
break;
case 4:
- RtlCopyMemory(ColorPtr, EGAColorsQuads,
sizeof(EGAColorsQuads));
+ RtlCopyMemory(bmiLocal.bmiColors, EGAColorsQuads,
sizeof(EGAColorsQuads));
break;
case 8:
{
INT r, g, b;
RGBQUAD *color;
- RtlCopyMemory(rgbQuads, DefLogPaletteQuads, 10 *
sizeof(RGBQUAD));
- RtlCopyMemory(rgbQuads + 246, DefLogPaletteQuads + 10, 10 *
sizeof(RGBQUAD));
- color = rgbQuads + 10;
+ RtlCopyMemory(bmiLocal.bmiColors, DefLogPaletteQuads, 10 *
sizeof(RGBQUAD));
+ RtlCopyMemory(bmiLocal.bmiColors + 246, DefLogPaletteQuads +
10, 10 * sizeof(RGBQUAD));
+ color = bmiLocal.bmiColors + 10;
for (r = 0; r <= 5; r++) /* FIXME */
for (g = 0; g <= 5; g++)
for (b = 0; b <= 5; b++)
@@ -798,20 +746,20 @@
}
case 15:
- if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ if (bmiLocal.bmiHeader.bV5Compression == BI_BITFIELDS)
{
- ((PDWORD)Info->bmiColors)[0] = 0x7c00;
- ((PDWORD)Info->bmiColors)[1] = 0x03e0;
- ((PDWORD)Info->bmiColors)[2] = 0x001f;
+ bmiLocal.bmiHeader.bV5RedMask = 0x7c00;
+ bmiLocal.bmiHeader.bV5GreenMask = 0x03e0;
+ bmiLocal.bmiHeader.bV5BlueMask = 0x001f;
}
break;
case 16:
if (Info->bmiHeader.biCompression == BI_BITFIELDS)
{
- ((PDWORD)Info->bmiColors)[0] = 0xf800;
- ((PDWORD)Info->bmiColors)[1] = 0x07e0;
- ((PDWORD)Info->bmiColors)[2] = 0x001f;
+ bmiLocal.bmiHeader.bV5RedMask = 0xf800;
+ bmiLocal.bmiHeader.bV5GreenMask = 0x07e0;
+ bmiLocal.bmiHeader.bV5BlueMask = 0x001f;
}
break;
@@ -819,71 +767,54 @@
case 32:
if (Info->bmiHeader.biCompression == BI_BITFIELDS)
{
- ((PDWORD)Info->bmiColors)[0] = 0xff0000;
- ((PDWORD)Info->bmiColors)[1] = 0x00ff00;
- ((PDWORD)Info->bmiColors)[2] = 0x0000ff;
+ bmiLocal.bmiHeader.bV5RedMask = 0xff0000;
+ bmiLocal.bmiHeader.bV5GreenMask = 0x00ff00;
+ bmiLocal.bmiHeader.bV5BlueMask = 0x0000ff;
}
break;
}
- if (!bPaletteMatch)
- PALETTE_UnlockPalette(ppalDst);
-
/* fill out the BITMAPINFO struct */
if (!ChkBits)
- { // Core or not to Core? We have converted from Core in Gdi~ so?
- if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
- coreheader->bcWidth = psurf->SurfObj.sizlBitmap.cx;
- coreheader->bcPlanes = 1;
- coreheader->bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
- coreheader->bcHeight = psurf->SurfObj.sizlBitmap.cy;
- if (psurf->SurfObj.lDelta > 0)
- coreheader->bcHeight = -coreheader->bcHeight;
- }
-
- if (Info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
- {
- Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
- Info->bmiHeader.biHeight = psurf->SurfObj.sizlBitmap.cy;
- Info->bmiHeader.biPlanes = 1;
- Info->bmiHeader.biBitCount =
BitsPerFormat(psurf->SurfObj.iBitmapFormat);
- switch (psurf->SurfObj.iBitmapFormat)
- {
- /* FIXME: What about BI_BITFIELDS? */
- case BMF_1BPP:
- case BMF_4BPP:
- case BMF_8BPP:
- case BMF_16BPP:
- case BMF_24BPP:
- case BMF_32BPP:
- Info->bmiHeader.biCompression = BI_RGB;
- break;
- case BMF_4RLE:
- Info->bmiHeader.biCompression = BI_RLE4;
- break;
- case BMF_8RLE:
- Info->bmiHeader.biCompression = BI_RLE8;
- break;
- case BMF_JPEG:
- Info->bmiHeader.biCompression = BI_JPEG;
- break;
- case BMF_PNG:
- Info->bmiHeader.biCompression = BI_PNG;
- break;
- }
- /* Image size has to be calculated */
- Info->bmiHeader.biSizeImage =
DIB_GetDIBWidthBytes(Info->bmiHeader.biWidth,
- Info->bmiHeader.biBitCount) *
Info->bmiHeader.biHeight;
- Info->bmiHeader.biXPelsPerMeter = 0; /* FIXME */
- Info->bmiHeader.biYPelsPerMeter = 0; /* FIXME */
- Info->bmiHeader.biClrUsed = 0;
- Info->bmiHeader.biClrImportant = 1 << Info->bmiHeader.biBitCount;
/* FIXME */
- /* Report negtive height for top-down bitmaps. */
- if (psurf->SurfObj.lDelta > 0)
- Info->bmiHeader.biHeight = -Info->bmiHeader.biHeight;
- }
+ {
+ bmiLocal.bmiHeader.bV5Width = psurf->SurfObj.sizlBitmap.cx;
+ bmiLocal.bmiHeader.bV5Height = psurf->SurfObj.sizlBitmap.cy;
+ bmiLocal.bmiHeader.bV5Planes = 1;
+ bmiLocal.bmiHeader.bV5BitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+ switch (psurf->SurfObj.iBitmapFormat)
+ {
+ /* FIXME: What about BI_BITFIELDS? */
+ case BMF_1BPP:
+ case BMF_4BPP:
+ case BMF_8BPP:
+ case BMF_16BPP:
+ case BMF_24BPP:
+ case BMF_32BPP:
+ bmiLocal.bmiHeader.bV5Compression = BI_RGB;
+ break;
+ case BMF_4RLE:
+ bmiLocal.bmiHeader.bV5Compression = BI_RLE4;
+ break;
+ case BMF_8RLE:
+ bmiLocal.bmiHeader.bV5Compression = BI_RLE8;
+ break;
+ case BMF_JPEG:
+ bmiLocal.bmiHeader.bV5Compression = BI_JPEG;
+ break;
+ case BMF_PNG:
+ bmiLocal.bmiHeader.bV5Compression = BI_PNG;
+ break;
+ }
+ /* Image size has to be calculated */
+ bmiLocal.bmiHeader.bV5SizeImage =
DIB_GetDIBWidthBytes(Info->bmiHeader.biWidth,
+ Info->bmiHeader.biBitCount) *
Info->bmiHeader.biHeight;
+ bmiLocal.bmiHeader.bV5XPelsPerMeter = 0; /* FIXME */
+ bmiLocal.bmiHeader.bV5YPelsPerMeter = 0; /* FIXME */
+ bmiLocal.bmiHeader.bV5ClrUsed = 0;
+ bmiLocal.bmiHeader.bV5ClrImportant = 1 << Info->bmiHeader.biBitCount; /*
FIXME */
+ /* Report negative height for top-down bitmaps. */
+ if (psurf->SurfObj.lDelta > 0)
+ bmiLocal.bmiHeader.bV5Height *= -1;
Result = psurf->SurfObj.sizlBitmap.cy;
}
else
@@ -907,27 +838,14 @@
hDestBitmap = NULL;
- if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
- hDestBitmap = EngCreateBitmap(DestSize,
- DIB_GetDIBWidthBytes(DestSize.cx,
coreheader->bcBitCount),
- BitmapFormat(coreheader->bcBitCount,
BI_RGB),
- 0 < coreheader->bcHeight ? 0 :
BMF_TOPDOWN,
- Bits);
- }
-
- if (Info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
- {
- Info->bmiHeader.biSizeImage = DIB_GetDIBWidthBytes(DestSize.cx,
+ bmiLocal.bmiHeader.bV5SizeImage = DIB_GetDIBWidthBytes(DestSize.cx,
Info->bmiHeader.biBitCount) *
DestSize.cy;
- hDestBitmap = EngCreateBitmap(DestSize,
- DIB_GetDIBWidthBytes(DestSize.cx,
Info->bmiHeader.biBitCount),
- BitmapFormat(Info->bmiHeader.biBitCount,
Info->bmiHeader.biCompression),
- 0 < Info->bmiHeader.biHeight ? 0 :
BMF_TOPDOWN,
- Bits);
- }
+ hDestBitmap = EngCreateBitmap(DestSize,
+ DIB_GetDIBWidthBytes(DestSize.cx,
Info->bmiHeader.biBitCount),
+ BitmapFormat(Info->bmiHeader.biBitCount,
Info->bmiHeader.biCompression),
+ 0 < Info->bmiHeader.biHeight ? 0 :
BMF_TOPDOWN,
+ Bits);
if (hDestBitmap == NULL)
goto cleanup;
@@ -939,7 +857,7 @@
SURFOBJ *DestSurfObj;
RECTL DestRect;
- EXLATEOBJ_vInitialize(&exlo, ppalSrc, ppalDst, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exlo, psurf->ppal, ppalDst, 0, 0, 0);
SourcePoint.x = 0;
SourcePoint.y = psurf->SurfObj.sizlBitmap.cy - (StartScan + ScanLines);
@@ -967,14 +885,19 @@
EngUnlockSurface(DestSurfObj);
}
}
+ /* Now that everything is over, get back the information to caller */
+ /* Note : Info has already been probed */
+ GetBMIFromBitmapV5Info(&bmiLocal, Info, Usage);
cleanup:
- PALETTE_ShareUnlockPalette(ppalSrc);
if (hDestBitmap != NULL)
EngDeleteSurface((HSURF)hDestBitmap);
- if (hDestPalette != NULL && bPaletteMatch == FALSE)
+ if (hDestPalette != NULL && !bPaletteMatch)
+ {
+ PALETTE_UnlockPalette(ppalDst);
PALETTE_FreePaletteByHandle(hDestPalette);
+ }
SURFACE_UnlockSurface(psurf);
@@ -1653,7 +1576,7 @@
{
colors = info->bmiHeader.biClrUsed;
if (!colors && (info->bmiHeader.biBitCount <= 8)) colors = 1
<< info->bmiHeader.biBitCount;
- return sizeof(BITMAPINFOHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ?
sizeof(RGBQUAD) : sizeof(WORD));
+ return info->bmiHeader.biSize + colors * ((coloruse == DIB_RGB_COLORS) ?
sizeof(RGBQUAD) : sizeof(WORD));
}
}
@@ -1722,9 +1645,9 @@
{
BYTE bits;
ULONG ColorCount;
- PALETTEENTRY *palEntries = NULL;
HPALETTE hPal;
ULONG RedMask, GreenMask, BlueMask;
+ PDWORD pdwColors = (PDWORD)((PBYTE)bmi + bmi->bmiHeader.biSize);
// Determine Bits Per Pixel
bits = bmi->bmiHeader.biBitCount;
@@ -1738,9 +1661,9 @@
else if (bmi->bmiHeader.biCompression == BI_BITFIELDS)
{
*paletteType = PAL_BITFIELDS;
- RedMask = ((ULONG *)bmi->bmiColors)[0];
- GreenMask = ((ULONG *)bmi->bmiColors)[1];
- BlueMask = ((ULONG *)bmi->bmiColors)[2];
+ RedMask = pdwColors[0];
+ GreenMask = pdwColors[1];
+ BlueMask = pdwColors[2];
}
else if (bits == 15)
{
@@ -1775,16 +1698,256 @@
if (PAL_INDEXED == *paletteType)
{
- hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)bmi->bmiColors);
+ hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)pdwColors);
}
else
{
hPal = PALETTE_AllocPalette(*paletteType, ColorCount,
- (ULONG*) palEntries,
+ NULL,
RedMask, GreenMask, BlueMask);
}
return hPal;
}
+FORCEINLINE
+DWORD
+GetBMIColor(CONST BITMAPINFO* pbmi, INT i)
+{
+ DWORD dwRet = 0;
+ INT size;
+ if(pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+ {
+ /* BITMAPCOREINFO holds RGBTRIPLE values */
+ size = sizeof(RGBTRIPLE);
+ }
+ else
+ {
+ size = sizeof(RGBQUAD);
+ }
+ memcpy(&dwRet, (PBYTE)pbmi + pbmi->bmiHeader.biSize + i*size, size);
+ return dwRet;
+}
+
+FORCEINLINE
+VOID
+SetBMIColor(CONST BITMAPINFO* pbmi, DWORD* color, INT i)
+{
+ if(pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+ {
+ *(RGBTRIPLE*)((PBYTE)pbmi + pbmi->bmiHeader.biSize + i*sizeof(RGBTRIPLE)) =
*(RGBTRIPLE*)color;
+ }
+ else
+ {
+ *(RGBQUAD*)((PBYTE)pbmi + pbmi->bmiHeader.biSize + i*sizeof(RGBQUAD)) =
*(RGBQUAD*)color;
+ }
+}
+
+NTSTATUS
+FASTCALL
+ProbeAndConvertToBitmapV5Info(
+ OUT PBITMAPV5INFO pbmiDst,
+ IN CONST BITMAPINFO* pbmiUnsafe,
+ IN DWORD dwColorUse)
+{
+ DWORD dwSize;
+ ULONG ulWidthBytes;
+ PBITMAPV5HEADER pbmhDst = &pbmiDst->bmiHeader;
+
+ /* Get the size and probe */
+ ProbeForRead(&pbmiUnsafe->bmiHeader.biSize, sizeof(DWORD), 1);
+ dwSize = pbmiUnsafe->bmiHeader.biSize;
+ ProbeForRead(pbmiUnsafe, dwSize, 1);
+
+ /* Check the size */
+ // FIXME: are intermediate sizes allowed? As what are they interpreted?
+ // make sure we don't use a too big dwSize later
+ if (dwSize != sizeof(BITMAPCOREHEADER) &&
+ dwSize != sizeof(BITMAPINFOHEADER) &&
+ dwSize != sizeof(BITMAPV4HEADER) &&
+ dwSize != sizeof(BITMAPV5HEADER))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (dwSize == sizeof(BITMAPCOREHEADER))
+ {
+ PBITMAPCOREHEADER pbch = (PBITMAPCOREHEADER)pbmiUnsafe;
+
+ /* Manually copy the fields that are present */
+ pbmhDst->bV5Width = pbch->bcWidth;
+ pbmhDst->bV5Height = pbch->bcHeight;
+ pbmhDst->bV5Planes = pbch->bcPlanes;
+ pbmhDst->bV5BitCount = pbch->bcBitCount;
+
+ /* Set some default values */
+ pbmhDst->bV5Compression = BI_RGB;
+ pbmhDst->bV5SizeImage = 0;
+ pbmhDst->bV5XPelsPerMeter = 72;
+ pbmhDst->bV5YPelsPerMeter = 72;
+ pbmhDst->bV5ClrUsed = 0;
+ pbmhDst->bV5ClrImportant = 0;
+ }
+ else
+ {
+ /* Copy valid fields */
+ memcpy(pbmiDst, pbmiUnsafe, dwSize);
+
+ if(dwSize < sizeof(BITMAPV5HEADER))
+ {
+ /* Zero out the rest of the V5 header */
+ memset((char*)pbmiDst + dwSize, 0, sizeof(BITMAPV5HEADER) - dwSize);
+ }
+ }
+ pbmhDst->bV5Size = sizeof(BITMAPV5HEADER);
+
+
+ if (dwSize < sizeof(BITMAPV4HEADER))
+ {
+ if (pbmhDst->bV5Compression == BI_BITFIELDS)
+ {
+ pbmhDst->bV5RedMask = GetBMIColor(pbmiUnsafe, 0);
+ pbmhDst->bV5GreenMask = GetBMIColor(pbmiUnsafe, 1);
+ pbmhDst->bV5BlueMask = GetBMIColor(pbmiUnsafe, 2);
+ pbmhDst->bV5AlphaMask = 0;
+ pbmhDst->bV5ClrUsed = 0;
+ }
+
+// pbmhDst->bV5CSType;
+// pbmhDst->bV5Endpoints;
+// pbmhDst->bV5GammaRed;
+// pbmhDst->bV5GammaGreen;
+// pbmhDst->bV5GammaBlue;
+ }
+
+ if (dwSize < sizeof(BITMAPV5HEADER))
+ {
+// pbmhDst->bV5Intent;
+// pbmhDst->bV5ProfileData;
+// pbmhDst->bV5ProfileSize;
+// pbmhDst->bV5Reserved;
+ }
+
+ ulWidthBytes = ((pbmhDst->bV5Width * pbmhDst->bV5Planes *
+ pbmhDst->bV5BitCount + 31) & ~31) / 8;
+
+ if (pbmhDst->bV5SizeImage == 0)
+ pbmhDst->bV5SizeImage = abs(ulWidthBytes * pbmhDst->bV5Height);
+
+ if (pbmhDst->bV5ClrUsed == 0)
+ {
+ switch(pbmhDst->bV5BitCount)
+ {
+ case 1:
+ pbmhDst->bV5ClrUsed = 2;
+ break;
+ case 4:
+ pbmhDst->bV5ClrUsed = 16;
+ break;
+ case 8:
+ pbmhDst->bV5ClrUsed = 256;
+ break;
+ default:
+ pbmhDst->bV5ClrUsed = 0;
+ break;
+ }
+ }
+
+ if (pbmhDst->bV5Planes != 1)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (pbmhDst->bV5BitCount != 0 && pbmhDst->bV5BitCount != 1 &&
+ pbmhDst->bV5BitCount != 4 && pbmhDst->bV5BitCount != 8 &&
+ pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 24
&&
+ pbmhDst->bV5BitCount != 32)
+ {
+ DPRINT("Invalid bit count: %d\n", pbmhDst->bV5BitCount);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if ((pbmhDst->bV5BitCount == 0 &&
+ pbmhDst->bV5Compression != BI_JPEG && pbmhDst->bV5Compression !=
BI_PNG))
+ {
+ DPRINT("Bit count 0 is invalid for compression %d.\n",
pbmhDst->bV5Compression);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (pbmhDst->bV5Compression == BI_BITFIELDS &&
+ pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 32)
+ {
+ DPRINT("Bit count %d is invalid for compression BI_BITFIELDS.\n",
pbmhDst->bV5BitCount);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Copy Colors */
+ if(pbmhDst->bV5ClrUsed)
+ {
+ INT i;
+ if(dwColorUse == DIB_PAL_COLORS)
+ {
+ RtlCopyMemory(pbmiDst->bmiColors,
+ pbmiUnsafe->bmiColors,
+ pbmhDst->bV5ClrUsed * sizeof(WORD));
+ }
+ else
+ {
+ for(i = 0; i < pbmhDst->bV5ClrUsed; i++)
+ {
+ ((DWORD*)pbmiDst->bmiColors)[i] = GetBMIColor(pbmiUnsafe, i);
+ }
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+VOID
+FASTCALL
+GetBMIFromBitmapV5Info(IN PBITMAPV5INFO pbmiSrc,
+ OUT PBITMAPINFO pbmiDst,
+ IN DWORD dwColorUse)
+{
+ if(pbmiDst->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+ {
+ /* Manually set value */
+ BITMAPCOREHEADER* pbmhCore = (BITMAPCOREHEADER*)&pbmiDst->bmiHeader;
+ pbmhCore->bcWidth = pbmiSrc->bmiHeader.bV5Width;
+ pbmhCore->bcHeight = pbmiSrc->bmiHeader.bV5Height;
+ pbmhCore->bcPlanes = pbmiSrc->bmiHeader.bV5Planes;
+ pbmhCore->bcBitCount = pbmiSrc->bmiHeader.bV5BitCount;
+ }
+ else
+ {
+ /* Copy valid Fields, keep bmiHeader.biSize safe */
+ RtlCopyMemory((PBYTE)pbmiDst + sizeof(DWORD), pbmiSrc,
pbmiDst->bmiHeader.biSize - sizeof(DWORD));
+ }
+ if((pbmiDst->bmiHeader.biSize < sizeof(BITMAPV4HEADER)) &&
+ (pbmiSrc->bmiHeader.bV5Compression == BI_BITFIELDS))
+ {
+ /* Masks are already set in V4 and V5 headers */
+ SetBMIColor(pbmiDst, &pbmiSrc->bmiHeader.bV5RedMask, 0);
+ SetBMIColor(pbmiDst, &pbmiSrc->bmiHeader.bV5GreenMask, 1);
+ SetBMIColor(pbmiDst, &pbmiSrc->bmiHeader.bV5BlueMask, 2);
+ }
+ else
+ {
+ INT i;
+ if(dwColorUse == DIB_PAL_COLORS)
+ {
+ RtlCopyMemory(pbmiDst->bmiColors,
+ pbmiSrc->bmiColors,
+ pbmiSrc->bmiHeader.bV5ClrUsed * sizeof(WORD));
+ }
+ else
+ {
+ for(i = 0; i < pbmiSrc->bmiHeader.bV5ClrUsed; i++)
+ {
+ SetBMIColor(pbmiDst, (DWORD*)pbmiSrc->bmiColors + i, i);
+ }
+ }
+ }
+}
+
/* EOF */