Author: jgardou Date: Sun Aug 1 12:17:35 2010 New Revision: 48389
URL: http://svn.reactos.org/svn/reactos?rev=48389&view=rev Log: [WIN32K] - Finally get rid of ProbeAndConvertToBitmapV5Info - Rewrite renderBITMAPfromDIB, and a good bunch of DIB related functions accordingly. - Rewrite BITMAP_CopyBitmap into something simpler. - Use already existing DIB functions in IntGdiCreateDIBBrush - Use DIB sections in NtGdiStretchDIBitsInternal and NtGdiSetDIBits. - Use Bitmap hdc for NtGdiGetDIBitsInternal if there is one.
Modified: branches/reactos-yarotows/subsystems/win32/win32k/include/bitmaps.h branches/reactos-yarotows/subsystems/win32/win32k/include/dib.h branches/reactos-yarotows/subsystems/win32/win32k/ntuser/clipboard.c branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c branches/reactos-yarotows/subsystems/win32/win32k/objects/bitmaps.c branches/reactos-yarotows/subsystems/win32/win32k/objects/brush.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/win3... ============================================================================== --- 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] Sun Aug 1 12:17:35 2010 @@ -13,7 +13,6 @@ 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, UINT MaxSize);
HBITMAP APIENTRY @@ -43,7 +42,7 @@ IN INT cy, IN DWORD fInit, IN OPTIONAL LPBYTE pjInit, - IN OPTIONAL PBITMAPV5INFO pbmi, + IN OPTIONAL PBITMAPINFO pbmi, IN DWORD iUsage, IN FLONG fl, IN HANDLE hcmXform);
Modified: branches/reactos-yarotows/subsystems/win32/win32k/include/dib.h URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/include/dib.h [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/include/dib.h [iso-8859-1] Sun Aug 1 12:17:35 2010 @@ -13,11 +13,11 @@ DIB_GetDIBImageBytes (INT width, INT height, INT depth); INT FASTCALL DIB_GetDIBWidthBytes (INT width, INT depth); -RGBQUAD * FASTCALL -DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi); +HPALETTE FASTCALL +DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi);
HPALETTE FASTCALL -BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType); +BuildDIBPalette (CONST BITMAPINFO *bmi);
BITMAPINFO* FASTCALL DIB_ConvertBitmapInfo(CONST BITMAPINFO* bmi, DWORD Usage); VOID FASTCALL DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig);
Modified: branches/reactos-yarotows/subsystems/win32/win32k/ntuser/clipboard.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/ntuser/clipboard.c [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/ntuser/clipboard.c [iso-8859-1] Sun Aug 1 12:17:35 2010 @@ -247,9 +247,11 @@ { HDC hdc; HBITMAP hbitmap; - unsigned int offset = 0; /* Stupid compiler */ - BITMAPV5INFO bmi; + PBITMAPINFO pBmi, pConvertedBmi = NULL; NTSTATUS Status ; + UINT offset = 0; /* Stupid compiler */ + + pBmi = (BITMAPINFO*)pDIB;
//hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE); hdc = UserGetDCEx(ClipboardWindow, NULL, DCX_USESTYLE); @@ -257,9 +259,19 @@ /* Probe it */ _SEH2_TRY { - Status = ProbeAndConvertToBitmapV5Info(&bmi, (BITMAPINFO*)pDIB, DIB_RGB_COLORS, 0); - offset = DIB_BitmapInfoSize((BITMAPINFO*)pDIB, DIB_RGB_COLORS); - ProbeForRead(pDIB + offset, bmi.bmiHeader.bV5SizeImage, 1); + ProbeForRead(&pBmi->bmiHeader.biSize, sizeof(DWORD), 1); + ProbeForRead(pBmi, pBmi->bmiHeader.biSize, 1); + ProbeForRead(pBmi, DIB_BitmapInfoSize(pBmi, DIB_RGB_COLORS), 1); + pConvertedBmi = DIB_ConvertBitmapInfo(pBmi, DIB_RGB_COLORS); + if(!pConvertedBmi) + { + Status = STATUS_INVALID_PARAMETER; + } + else + { + offset = DIB_BitmapInfoSize((BITMAPINFO*)pBmi, DIB_RGB_COLORS); + ProbeForRead(pDIB + offset, pConvertedBmi->bmiHeader.biSizeImage, 1); + } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -274,16 +286,18 @@ }
hbitmap = GreCreateDIBitmapInternal(hdc, - bmi.bmiHeader.bV5Width, - bmi.bmiHeader.bV5Height, + pConvertedBmi->bmiHeader.biWidth, + pConvertedBmi->bmiHeader.biHeight, CBM_INIT, pDIB+offset, - &bmi, + pConvertedBmi, DIB_RGB_COLORS, 0, 0); //UserReleaseDC(NULL, hdc, FALSE); UserReleaseDC(ClipboardWindow, hdc, FALSE); + + DIB_FreeConvertedBitmapInfo(pConvertedBmi, pBmi);
return hbitmap; }
Modified: branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] Sun Aug 1 12:17:35 2010 @@ -1325,12 +1325,10 @@ if(bAlpha && (diFlags & DI_IMAGE)) { BLENDFUNCTION pixelblend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; - DWORD Pixel; - BYTE Red, Green, Blue, Alpha; - DWORD Count = 0; + BYTE Alpha; INT i, j; PSURFACE psurf; - PBYTE pBits ; + PBYTE pBits, ptr ; HBITMAP hMemBmp = NULL;
pBits = ExAllocatePoolWithTag(PagedPool, @@ -1363,20 +1361,15 @@ /* premultiply with the alpha channel value */ for (i = 0; i < abs(bmpColor.bmHeight); i++) { - Count = i*bmpColor.bmWidthBytes; + ptr = pBits + i*bmpColor.bmWidthBytes; for (j = 0; j < bmpColor.bmWidth; j++) { - Pixel = *(DWORD *)(pBits + Count); - - Alpha = ((BYTE)(Pixel >> 24) & 0xff); - - Red = (((BYTE)(Pixel >> 0)) * Alpha) / 0xff; - Green = (((BYTE)(Pixel >> 8)) * Alpha) / 0xff; - Blue = (((BYTE)(Pixel >> 16)) * Alpha) / 0xff; - - *(DWORD *)(pBits + Count) = (DWORD)(Red | (Green << 8) | (Blue << 16) | (Alpha << 24)); - - Count += sizeof(DWORD); + Alpha = ptr[3]; + ptr[0] *= Alpha / 0xff; + ptr[1] *= Alpha / 0xff; + ptr[2] *= Alpha / 0xff; + + ptr += 4; } }
Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/bitmaps.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/objects/bitmaps.c [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/objects/bitmaps.c [iso-8859-1] Sun Aug 1 12:17:35 2010 @@ -912,7 +912,7 @@ return 0; }
- Bitmap = GDIOBJ_LockObj(hBitmap, GDI_OBJECT_TYPE_BITMAP); + Bitmap = SURFACE_LockSurface(hBitmap); if (Bitmap == NULL) { return 0; @@ -925,40 +925,22 @@
Size.cx = abs(bm.bmWidth); Size.cy = abs(bm.bmHeight); - res = GreCreateBitmap(abs(bm.bmWidth), - abs(bm.bmHeight), - 1, - bm.bmBitsPixel, - NULL); + res = GreCreateBitmapEx(Size.cx, + Size.cy, + bm.bmWidthBytes, + Bitmap->SurfObj.iBitmapFormat, + Bitmap->SurfObj.fjBitmap, + Bitmap->SurfObj.cjBits, + NULL); +
if (res) { - PBYTE buf; - - resBitmap = GDIOBJ_LockObj(res, GDI_OBJECT_TYPE_BITMAP); + resBitmap = SURFACE_LockSurface(res); if (resBitmap) { - buf = ExAllocatePoolWithTag(PagedPool, - bm.bmWidthBytes * abs(bm.bmHeight), - TAG_BITMAP); - if (buf == NULL) - { - GDIOBJ_UnlockObjByPtr((POBJ)resBitmap); - GDIOBJ_UnlockObjByPtr((POBJ)Bitmap); - GreDeleteObject(res); - return 0; - } - IntGetBitmapBits(Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf); - IntSetBitmapBits(resBitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf); - ExFreePoolWithTag(buf,TAG_BITMAP); - resBitmap->flags = Bitmap->flags; - /* Copy palette */ - if (Bitmap->ppal) - { - resBitmap->ppal = Bitmap->ppal ; - GDIOBJ_IncrementShareCount(&Bitmap->ppal->BaseObject); - } - GDIOBJ_UnlockObjByPtr((POBJ)resBitmap); + IntSetBitmapBits(resBitmap, Bitmap->SurfObj.cjBits, Bitmap->SurfObj.pvBits); + SURFACE_UnlockSurface(resBitmap); } else { @@ -967,7 +949,7 @@ } }
- GDIOBJ_UnlockObjByPtr((POBJ)Bitmap); + SURFACE_UnlockSurface(Bitmap);
return res; }
Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/brush.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/objects/brush.c [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/objects/brush.c [iso-8859-1] Sun Aug 1 12:17:35 2010 @@ -244,129 +244,6 @@ return sizeof(LOGBRUSH); }
-/** - * @name CalculateColorTableSize - * - * Internal routine to calculate the number of color table entries. - * - * @param BitmapInfoHeader - * Input bitmap information header, can be any version of - * BITMAPINFOHEADER or BITMAPCOREHEADER. - * - * @param ColorSpec - * Pointer to variable which specifiing the color mode (DIB_RGB_COLORS - * or DIB_RGB_COLORS). On successful return this value is normalized - * according to the bitmap info. - * - * @param ColorTableSize - * On successful return this variable is filled with number of - * entries in color table for the image with specified parameters. - * - * @return - * TRUE if the input values together form a valid image, FALSE otherwise. - */ -BOOL -APIENTRY -CalculateColorTableSize( - CONST BITMAPINFOHEADER *BitmapInfoHeader, - UINT *ColorSpec, - UINT *ColorTableSize) -{ - WORD BitCount; - DWORD ClrUsed; - DWORD Compression; - - /* - * At first get some basic parameters from the passed BitmapInfoHeader - * structure. It can have one of the following formats: - * - BITMAPCOREHEADER (the oldest one with totally different layout - * from the others) - * - BITMAPINFOHEADER (the standard and most common header) - * - BITMAPV4HEADER (extension of BITMAPINFOHEADER) - * - BITMAPV5HEADER (extension of BITMAPV4HEADER) - */ - if (BitmapInfoHeader->biSize == sizeof(BITMAPCOREHEADER)) - { - BitCount = ((LPBITMAPCOREHEADER)BitmapInfoHeader)->bcBitCount; - ClrUsed = 0; - Compression = BI_RGB; - } - else - { - BitCount = BitmapInfoHeader->biBitCount; - ClrUsed = BitmapInfoHeader->biClrUsed; - Compression = BitmapInfoHeader->biCompression; - } - - switch (Compression) - { - case BI_BITFIELDS: - if (*ColorSpec == DIB_PAL_COLORS) - *ColorSpec = DIB_RGB_COLORS; - - if (BitCount != 16 && BitCount != 32) - return FALSE; - - /* For BITMAPV4HEADER/BITMAPV5HEADER the masks are included in - * the structure itself (bV4RedMask, bV4GreenMask, and bV4BlueMask). - * For BITMAPINFOHEADER the color masks are stored in the palette. */ - if (BitmapInfoHeader->biSize > sizeof(BITMAPINFOHEADER)) - *ColorTableSize = 0; - else - *ColorTableSize = 3; - - return TRUE; - - case BI_RGB: - switch (BitCount) - { - case 1: - *ColorTableSize = ClrUsed ? min(ClrUsed, 2) : 2; - return TRUE; - - case 4: - *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16; - return TRUE; - - case 8: - *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256; - return TRUE; - - default: - if (*ColorSpec == DIB_PAL_COLORS) - *ColorSpec = DIB_RGB_COLORS; - if (BitCount != 16 && BitCount != 24 && BitCount != 32) - return FALSE; - *ColorTableSize = ClrUsed; - return TRUE; - } - - case BI_RLE4: - if (BitCount == 4) - { - *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16; - return TRUE; - } - return FALSE; - - case BI_RLE8: - if (BitCount == 8) - { - *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256; - return TRUE; - } - return FALSE; - - case BI_JPEG: - case BI_PNG: - *ColorTableSize = ClrUsed; - return TRUE; - - default: - return FALSE; - } -} - HBRUSH APIENTRY IntGdiCreateDIBBrush( @@ -379,9 +256,7 @@ PBRUSH pbrush; HBITMAP hPattern; ULONG_PTR DataPtr; - UINT PaletteEntryCount; PSURFACE psurfPattern; - INT PaletteType; HPALETTE hpal ;
if (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER)) @@ -390,20 +265,7 @@ return NULL; }
- if (!CalculateColorTableSize(&BitmapInfo->bmiHeader, - &ColorSpec, - &PaletteEntryCount)) - { - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return NULL; - } - - // FIXME: What about BI_BITFIELDS - DataPtr = (ULONG_PTR)BitmapInfo + BitmapInfo->bmiHeader.biSize; - if (ColorSpec == DIB_RGB_COLORS) - DataPtr += PaletteEntryCount * sizeof(RGBQUAD); - else - DataPtr += PaletteEntryCount * sizeof(USHORT); + DataPtr = (ULONG_PTR)BitmapInfo + DIB_BitmapInfoSize(BitmapInfo, ColorSpec);
hPattern = GreCreateBitmap(BitmapInfo->bmiHeader.biWidth, BitmapInfo->bmiHeader.biHeight, @@ -418,7 +280,8 @@
psurfPattern = SURFACE_LockSurface(hPattern); ASSERT(psurfPattern != NULL); - hpal = BuildDIBPalette(BitmapInfo, &PaletteType); + if(ColorSpec == DIB_PAL_COLORS) DPRINT1("FIXME, unsupported color spec!\n"); + hpal = BuildDIBPalette(BitmapInfo); psurfPattern->ppal = PALETTE_ShareLockPalette(hpal); /* Lazy delete palette, it will be freed when its shared reference is zeroed */ GreDeleteObject(hpal);
Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- 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] Sun Aug 1 12:17:35 2010 @@ -262,115 +262,62 @@ UINT StartScan, UINT ScanLines, CONST VOID *Bits, - CONST BITMAPV5INFO *bmi, + CONST BITMAPINFO *bmi, UINT ColorUse) { - SURFACE *bitmap; - HBITMAP SourceBitmap; + HBITMAP SourceBitmap, hOldSrcBmp = NULL, hOldDstBmp = NULL; + HDC hdcSrc, hdcDst; INT result = 0; - BOOL copyBitsResult; - SURFOBJ *DestSurf, *SourceSurf; - SIZEL SourceSize; - POINTL ZeroPoint; - RECTL DestRect; - EXLATEOBJ exlo; - PPALETTE ppalDIB; - //RGBQUAD *lpRGB; - HPALETTE DIB_Palette; - ULONG DIB_Palette_Type; - INT DIBWidth; - - // Check parameters - if (!(bitmap = SURFACE_LockSurface(hBitmap))) - { - return 0; - } - - // Get RGB values - //if (ColorUse == DIB_PAL_COLORS) - // lpRGB = DIB_MapPaletteColors(hDC, bmi); - //else - // lpRGB = &bmi->bmiColors; - - DestSurf = &bitmap->SurfObj; - - // Create source surface - SourceSize.cx = bmi->bmiHeader.bV5Width; - SourceSize.cy = ScanLines; - - // Determine width of DIB - DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.bV5BitCount); - - SourceBitmap = EngCreateBitmap(SourceSize, - DIBWidth, - BitmapFormat(bmi->bmiHeader.bV5BitCount, bmi->bmiHeader.bV5Compression), - bmi->bmiHeader.bV5Height < 0 ? BMF_TOPDOWN : 0, - (PVOID) Bits); - if (0 == SourceBitmap) - { - SURFACE_UnlockSurface(bitmap); + PVOID pvBits; + + SourceBitmap = DIB_CreateDIBSection(DC, bmi, ColorUse, &pvBits, NULL, 0, 0); + if (0 == SourceBitmap) + { + DPRINT1("Error : Could not create a DIBSection.\n"); SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); return 0; }
- SourceSurf = EngLockSurface((HSURF)SourceBitmap); - if (NULL == SourceSurf) - { - EngDeleteSurface((HSURF)SourceBitmap); - SURFACE_UnlockSurface(bitmap); - SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); - return 0; - } - - ASSERT(bitmap->ppal); - - // Source palette obtained from the BITMAPINFO - DIB_Palette = BuildDIBPalette((BITMAPINFO*)bmi, (PINT)&DIB_Palette_Type); - if (NULL == DIB_Palette) - { - EngUnlockSurface(SourceSurf); - EngDeleteSurface((HSURF)SourceBitmap); - SURFACE_UnlockSurface(bitmap); - SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); - return 0; - } - - ppalDIB = PALETTE_LockPalette(DIB_Palette); - - /* Initialize XLATEOBJ for color translation */ - EXLATEOBJ_vInitialize(&exlo, ppalDIB, bitmap->ppal, 0, 0, 0); - - // Zero point - ZeroPoint.x = 0; - ZeroPoint.y = 0; - - // Determine destination rectangle - DestRect.left = 0; - DestRect.top = abs(bmi->bmiHeader.bV5Height) - StartScan - ScanLines; - DestRect.right = SourceSize.cx; - DestRect.bottom = DestRect.top + ScanLines; - - copyBitsResult = IntEngCopyBits(DestSurf, SourceSurf, NULL, &exlo.xlo, &DestRect, &ZeroPoint); - - // If it succeeded, return number of scanlines copies - if (copyBitsResult == TRUE) - { - result = SourceSize.cy; -// or -// result = abs(bmi->bmiHeader.biHeight) - StartScan; - } - - // Clean up - EXLATEOBJ_vCleanup(&exlo); - PALETTE_UnlockPalette(ppalDIB); - PALETTE_FreePaletteByHandle(DIB_Palette); - EngUnlockSurface(SourceSurf); - EngDeleteSurface((HSURF)SourceBitmap); - -// if (ColorUse == DIB_PAL_COLORS) -// WinFree((LPSTR)lpRGB); - - SURFACE_UnlockSurface(bitmap); + RtlCopyMemory(pvBits, Bits, DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth, + bmi->bmiHeader.biHeight, + bmi->bmiHeader.biBitCount)); + + hdcSrc = NtGdiCreateCompatibleDC(0); + hdcDst = NtGdiCreateCompatibleDC(0); + + if(!(hdcSrc && hdcDst)) + { + DPRINT1("Error, could not create memory DCs.\n"); + goto cleanup; + } + + hOldSrcBmp = NtGdiSelectBitmap(hdcSrc, SourceBitmap); + hOldDstBmp = NtGdiSelectBitmap(hdcDst, hBitmap); + + if(!(hOldSrcBmp && hOldDstBmp)) + { + DPRINT1("Error : Could not select bitmaps into DCs\n"); + goto cleanup; + } + + result = NtGdiBitBlt(hdcDst, 0, 0, bmi->bmiHeader.biWidth, ScanLines, hdcSrc, 0, StartScan, + SRCCOPY, 0, 0); + + if(result) + result = ScanLines; + +cleanup: + if(hdcSrc) + { + if(hOldSrcBmp) NtGdiSelectBitmap(hdcSrc, hOldSrcBmp); + NtGdiDeleteObjectApp(hdcSrc); + } + if(hdcDst) + { + if(hOldDstBmp) NtGdiSelectBitmap(hdcDst, hOldDstBmp); + NtGdiDeleteObjectApp(hdcDst); + } + GreDeleteObject(SourceBitmap);
return result; } @@ -392,14 +339,19 @@ PDC Dc; INT Ret; NTSTATUS Status = STATUS_SUCCESS; - BITMAPV5INFO bmiLocal;
if (!Bits) return 0;
_SEH2_TRY { - Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse, 0); - ProbeForRead(Bits, bmiLocal.bmiHeader.bV5SizeImage, 1); + ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1); + ProbeForRead(bmi, bmi->bmiHeader.biSize, 1); + ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, ColorUse), 1); + ProbeForRead(Bits, + DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth, + ScanLines, + bmi->bmiHeader.biBitCount), + 1); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -424,7 +376,7 @@ return 0; }
- Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, &bmiLocal, ColorUse); + Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
DC_UnlockDc(Dc);
@@ -465,14 +417,12 @@ EXLATEOBJ exlo; PPALETTE ppalDIB = NULL; HPALETTE hpalDIB = NULL; - ULONG DIBPaletteType; - BITMAPV5INFO bmiLocal ;
if (!Bits) return 0;
_SEH2_TRY { - Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse, cjMaxInfo); + ProbeForRead(bmi, cjMaxInfo, 1); ProbeForRead(Bits, cjMaxBits, 1); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -502,7 +452,7 @@
pDestSurf = pSurf ? &pSurf->SurfObj : NULL;
- ScanLines = min(ScanLines, abs(bmiLocal.bmiHeader.bV5Height) - StartScan); + ScanLines = min(ScanLines, abs(bmi->bmiHeader.biHeight) - StartScan);
rcDest.left = XDest; rcDest.top = YDest; @@ -519,16 +469,16 @@ ptSource.x = XSrc; ptSource.y = YSrc;
- SourceSize.cx = bmiLocal.bmiHeader.bV5Width; + SourceSize.cx = bmi->bmiHeader.biWidth; SourceSize.cy = ScanLines;
- DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmiLocal.bmiHeader.bV5BitCount); + DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
hSourceBitmap = EngCreateBitmap(SourceSize, DIBWidth, - BitmapFormat(bmiLocal.bmiHeader.bV5BitCount, - bmiLocal.bmiHeader.bV5Compression), - bmiLocal.bmiHeader.bV5Height < 0 ? BMF_TOPDOWN : 0, + BitmapFormat(bmi->bmiHeader.biBitCount, + bmi->bmiHeader.biCompression), + bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0, (PVOID) Bits); if (!hSourceBitmap) { @@ -547,7 +497,7 @@ ASSERT(pSurf->ppal);
/* Create a palette for the DIB */ - hpalDIB = BuildDIBPalette((PBITMAPINFO)&bmiLocal, (PINT)&DIBPaletteType); + hpalDIB = BuildDIBPalette(bmi); if (!hpalDIB) { SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); @@ -697,13 +647,6 @@ ScanLines = 0; goto done; } - /* Must not be selected */ - if(psurf->hdc != NULL) - { - ScanLines = 0; - SetLastWin32Error(ERROR_INVALID_PARAMETER); - goto done; - }
/* Fill in the structure */ switch(bpp) @@ -948,13 +891,14 @@ } break; } + Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(width, height, bpp);
if(Bits && ScanLines) { /* Create a DIBSECTION, blt it, profit */ PVOID pDIBits ; HBITMAP hBmpDest, hOldDest = NULL, hOldSrc = NULL; - HDC hdcDest, hdcSrc; + HDC hdcDest = NULL, hdcSrc; BOOL ret ;
if (StartScan > psurf->SurfObj.sizlBitmap.cy) @@ -977,22 +921,38 @@ goto done ; }
+ if(psurf->hdc) + hdcSrc = psurf->hdc; + else + { + hdcSrc = NtGdiCreateCompatibleDC(0); + if(!hdcSrc) + { + DPRINT1("Error: could not create HDC!\n"); + ScanLines = 0; + goto cleanup_blt; + } + hOldSrc = NtGdiSelectBitmap(hdcSrc, hBitmap); + if(!hOldSrc) + { + DPRINT1("Error : Could not Select bitmap\n"); + ScanLines = 0; + goto cleanup_blt; + } + } + hdcDest = NtGdiCreateCompatibleDC(0); - hdcSrc = NtGdiCreateCompatibleDC(0); - - if(!(hdcSrc && hdcDest)) + if(!hdcDest) { - DPRINT1("Error: could not create HDCs!\n"); + DPRINT1("Error: could not create HDC!\n"); ScanLines = 0; goto cleanup_blt; } - hOldDest = NtGdiSelectBitmap(hdcDest, hBmpDest); - hOldSrc = NtGdiSelectBitmap(hdcSrc, hBitmap); - - if(!(hOldDest && hOldSrc)) + if(!hOldDest) { - DPRINT1("Error : Could not Select bitmaps\n"); + DPRINT1("Error : Could not Select bitmap\n"); + ScanLines = 0; goto cleanup_blt; }
@@ -1035,7 +995,7 @@ }
cleanup_blt: - if(hdcSrc) + if(hdcSrc && (hdcSrc != psurf->hdc)) { if(hOldSrc) NtGdiSelectBitmap(hdcSrc, hOldSrc); NtGdiDeleteObjectApp(hdcSrc); @@ -1079,11 +1039,10 @@ HANDLE hcmXform) { HBITMAP hBitmap, hOldBitmap = NULL; - HDC hdcMem; - HPALETTE hPal = NULL; - PDC pDC; - NTSTATUS Status; - BITMAPV5INFO bmiLocal ; + HDC hdcMem = NULL; + NTSTATUS Status = STATUS_SUCCESS; + PVOID pvDIBits; + INT Ret = 0;
if (!Bits || !BitsInfo) { @@ -1091,101 +1050,82 @@ return 0; }
- _SEH2_TRY - { - Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, BitsInfo, Usage, cjMaxInfo); - ProbeForRead(Bits, cjMaxBits, 1); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END - - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtGdiStretchDIBitsInternal fail to read BitMapInfo: %x or Bits: %x\n",BitsInfo,Bits); - return 0; - } - - hdcMem = NtGdiCreateCompatibleDC(hDC); - if (hdcMem == NULL) - { - DPRINT1("NtGdiCreateCompatibleDC fail create hdc\n"); - return 0; - } - - hBitmap = NtGdiCreateCompatibleBitmap(hDC, - abs(bmiLocal.bmiHeader.bV5Width), - abs(bmiLocal.bmiHeader.bV5Height)); - if (hBitmap == NULL) - { - DPRINT1("NtGdiCreateCompatibleBitmap fail create bitmap\n"); - DPRINT1("hDC : 0x%08x \n", hDC); - DPRINT1("BitsInfo->bmiHeader.biWidth : 0x%08x \n", BitsInfo->bmiHeader.biWidth); - DPRINT1("BitsInfo->bmiHeader.biHeight : 0x%08x \n", BitsInfo->bmiHeader.biHeight); - return 0; - } - - /* Select the bitmap into hdcMem, and save a handle to the old bitmap */ - hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap); - - if (Usage == DIB_PAL_COLORS) - { - hPal = NtGdiGetDCObject(hDC, GDI_OBJECT_TYPE_PALETTE); - hPal = GdiSelectPalette(hdcMem, hPal, FALSE); - } - - if (bmiLocal.bmiHeader.bV5Compression == BI_RLE4 || - bmiLocal.bmiHeader.bV5Compression == BI_RLE8) - { - /* copy existing bitmap from destination dc */ - if (SrcWidth == DestWidth && SrcHeight == DestHeight) - NtGdiBitBlt(hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc, - SrcWidth, SrcHeight, hDC, XDest, YDest, ROP, 0, 0); - else - NtGdiStretchBlt(hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc, - SrcWidth, SrcHeight, hDC, XDest, YDest, DestWidth, DestHeight, - ROP, 0); - } - - pDC = DC_LockDc(hdcMem); - if (pDC != NULL) - { - /* Note BitsInfo->bmiHeader.biHeight is the number of scanline, - * if it negitve we getting to many scanline for scanline is UINT not - * 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 */ - IntSetDIBits(pDC, hBitmap, 0, abs(bmiLocal.bmiHeader.bV5Height), Bits, - &bmiLocal, Usage); - - DC_UnlockDc(pDC); - } - - - /* Origin for DIBitmap may be bottom left (positive biHeight) or top - left (negative biHeight) */ - if (SrcWidth == DestWidth && SrcHeight == DestHeight) - NtGdiBitBlt(hDC, XDest, YDest, DestWidth, DestHeight, - hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc, - ROP, 0, 0); - else - NtGdiStretchBlt(hDC, XDest, YDest, DestWidth, DestHeight, - hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc, - SrcWidth, SrcHeight, ROP, 0); - - /* cleanup */ - if (hPal) - GdiSelectPalette(hdcMem, hPal, FALSE); - - if (hOldBitmap) - NtGdiSelectBitmap(hdcMem, hOldBitmap); - - NtGdiDeleteObjectApp(hdcMem); - - GreDeleteObject(hBitmap); - - return SrcHeight; + /* Create a DIB Section, data will be probed there */ + hBitmap = NtGdiCreateDIBSection(hDC, + NULL, + 0, + BitsInfo, + Usage, + 0, + 0, + 0, + &pvDIBits); + + if(!hBitmap) + { + DPRINT1("Failed to create a DIB.\n"); + return 0; + } + + _SEH2_TRY + { + ProbeForRead(Bits, cjMaxBits, 1); + RtlCopyMemory(pvDIBits, Bits, DIB_GetDIBImageBytes(BitsInfo->bmiHeader.biWidth, + BitsInfo->bmiHeader.biHeight, + BitsInfo->bmiHeader.biBitCount)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END + + if(!NT_SUCCESS(Status)) + { + DPRINT1("Error : Could not read DIB bits\n"); + SetLastNtError(Status); + goto cleanup; + } + + hdcMem = NtGdiCreateCompatibleDC(0); + if(!hdcMem) + { + DPRINT1("Failed to create a memory DC!"); + goto cleanup; + } + + hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap); + if(!hOldBitmap) + { + DPRINT1("Could not select the DIB into the memory DC\n"); + goto cleanup; + } + + /* Do we want to stretch ? */ + if((SrcWidth == DestWidth) && (SrcHeight == DestHeight)) + { + Ret = NtGdiBitBlt(hDC, XDest, YDest, XDest + DestWidth, YDest + DestHeight, + hdcMem, XSrc, YSrc, ROP, 0, 0); + } + else + { + Ret = NtGdiStretchBlt(hDC, XDest, YDest, XDest + DestWidth, YDest + DestHeight, + hdcMem, XSrc, YSrc, XSrc + SrcWidth, YSrc + SrcHeight, + ROP, 0); + } + + if(Ret) + Ret = SrcHeight ; + +cleanup: + if(hdcMem) + { + if(hOldBitmap) NtGdiSelectBitmap(hdcMem, hOldBitmap); + NtGdiDeleteObjectApp(hdcMem); + } + GreDeleteObject(hBitmap); + + return Ret; }
@@ -1198,7 +1138,7 @@ UINT bpp, DWORD init, LPBYTE bits, - PBITMAPV5INFO data, + PBITMAPINFO data, DWORD coloruse) { HBITMAP handle; @@ -1211,7 +1151,7 @@ else if ((coloruse != DIB_RGB_COLORS) || (init != CBM_INIT) || !data) fColor = FALSE; else { - const RGBQUAD *rgb = data->bmiColors; + const RGBQUAD *rgb = (RGBQUAD*)((PBYTE)data + data->bmiHeader.biSize); DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
// Check if the first color of the colormap is black @@ -1268,12 +1208,11 @@ IN FLONG fl, IN HANDLE hcmXform) { - BITMAPV5INFO bmiLocal ; NTSTATUS Status = STATUS_SUCCESS;
_SEH2_TRY { - if(pbmi) Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, pbmi, iUsage, cjMaxInitInfo); + if(pbmi) ProbeForRead(pbmi, cjMaxInitInfo, 1); if(pjInit && (fInit == CBM_INIT)) ProbeForRead(pjInit, cjMaxBits, 1); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -1293,7 +1232,7 @@ cy, fInit, pjInit, - pbmi ? &bmiLocal : NULL, + pbmi, iUsage, fl, hcmXform); @@ -1307,7 +1246,7 @@ IN INT cy, IN DWORD fInit, IN OPTIONAL LPBYTE pjInit, - IN OPTIONAL PBITMAPV5INFO pbmi, + IN OPTIONAL PBITMAPINFO pbmi, IN DWORD iUsage, IN FLONG fl, IN HANDLE hcmXform) @@ -1339,7 +1278,7 @@ /* It's OK to set bpp=0 here, as IntCreateDIBitmap will create a compatible Bitmap * if bpp != 1 and ignore the real value that was passed */ if (pbmi) - bpp = pbmi->bmiHeader.bV5BitCount; + bpp = pbmi->bmiHeader.biBitCount; else bpp = 0; Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage); @@ -1435,7 +1374,6 @@ SURFACE *bmp = NULL; void *mapBits = NULL; HPALETTE hpal ; - INT palMode = PAL_INDEXED;
// Fill BITMAP32 structure with DIB data CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader; @@ -1527,24 +1465,18 @@ { PPALETTE pdcPal ; pdcPal = PALETTE_LockPalette(dc->dclevel.hpal); - if(!pdcPal) - { - DPRINT1("Unable to lock DC palette?!\n"); - goto cleanup; - } - if(pdcPal->Mode != PAL_INDEXED) - { - DPRINT1("Not indexed palette selected in the DC?!\n"); - PALETTE_UnlockPalette(pdcPal); - } - hpal = PALETTE_AllocPalette(PAL_INDEXED, - pdcPal->NumColors, - (ULONG*)pdcPal->IndexedColors, 0, 0, 0); + hpal = DIB_MapPaletteColors(pdcPal, bmi); PALETTE_UnlockPalette(pdcPal); } else { - hpal = BuildDIBPalette(bmi, &palMode); + hpal = BuildDIBPalette(bmi); + } + + if(!hpal) + { + DPRINT1("Error : Could not create a aplette for the DIB.\n"); + goto cleanup; }
// Create Device Dependent Bitmap and add DIB pointer @@ -1716,25 +1648,17 @@ } }
-RGBQUAD * +HPALETTE FASTCALL -DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi) -{ - RGBQUAD *lpRGB; +DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi) +{ + PALETTEENTRY* ppalEntries; ULONG nNumColors,i; USHORT *lpIndex; - PPALETTE palGDI; - - palGDI = PALETTE_LockPalette(dc->dclevel.hpal); - - if (NULL == palGDI) - { - return NULL; - } - - if (palGDI->Mode != PAL_INDEXED) - { - PALETTE_UnlockPalette(palGDI); + HPALETTE hpal; + + if (ppal->Mode != PAL_INDEXED) + { return NULL; }
@@ -1744,46 +1668,52 @@ nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed); }
- lpRGB = (RGBQUAD *)ExAllocatePoolWithTag(PagedPool, sizeof(RGBQUAD) * nNumColors, TAG_COLORMAP); - if (lpRGB == NULL) - { - PALETTE_UnlockPalette(palGDI); + /* Don't have more colors than we need */ + nNumColors = min(ppal->NumColors, nNumColors); + + ppalEntries = ExAllocatePoolWithTag(PagedPool, sizeof(PALETTEENTRY) * nNumColors, TAG_COLORMAP); + if (ppalEntries == NULL) + { + DPRINT1("Could not allocate palette entries\n"); return NULL; }
- lpIndex = (USHORT *)&lpbmi->bmiColors[0]; + lpIndex = (USHORT *)((PBYTE)lpbmi + lpbmi->bmiHeader.biSize);
for (i = 0; i < nNumColors; i++) { - if (*lpIndex < palGDI->NumColors) + if (*lpIndex < ppal->NumColors) { - lpRGB[i].rgbRed = palGDI->IndexedColors[*lpIndex].peRed; - lpRGB[i].rgbGreen = palGDI->IndexedColors[*lpIndex].peGreen; - lpRGB[i].rgbBlue = palGDI->IndexedColors[*lpIndex].peBlue; + ppalEntries[i] = ppal->IndexedColors[*lpIndex]; } else { - lpRGB[i].rgbRed = 0; - lpRGB[i].rgbGreen = 0; - lpRGB[i].rgbBlue = 0; + ppalEntries[i].peRed = 0; + ppalEntries[i].peGreen = 0; + ppalEntries[i].peBlue = 0; + ppalEntries[i].peFlags = 0; } - lpRGB[i].rgbReserved = 0; + lpIndex++; } - PALETTE_UnlockPalette(palGDI); - - return lpRGB; + + hpal = PALETTE_AllocPalette(PAL_INDEXED, nNumColors, (ULONG*)ppalEntries, 0, 0, 0); + + ExFreePoolWithTag(ppalEntries, TAG_COLORMAP); + + return hpal; }
HPALETTE FASTCALL -BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType) +BuildDIBPalette(CONST BITMAPINFO *bmi) { BYTE bits; ULONG ColorCount; HPALETTE hPal; - ULONG RedMask, GreenMask, BlueMask; + ULONG RedMask = 0, GreenMask = 0, BlueMask = 0; PDWORD pdwColors = (PDWORD)((PBYTE)bmi + bmi->bmiHeader.biSize); + INT paletteType;
// Determine Bits Per Pixel bits = bmi->bmiHeader.biBitCount; @@ -1791,36 +1721,36 @@ // Determine paletteType from Bits Per Pixel if (bits <= 8) { - *paletteType = PAL_INDEXED; + paletteType = PAL_INDEXED; RedMask = GreenMask = BlueMask = 0; } else if (bmi->bmiHeader.biCompression == BI_BITFIELDS) { - *paletteType = PAL_BITFIELDS; + paletteType = PAL_BITFIELDS; RedMask = pdwColors[0]; GreenMask = pdwColors[1]; BlueMask = pdwColors[2]; } else if (bits == 15) { - *paletteType = PAL_BITFIELDS; - RedMask = 0x7c00; - GreenMask = 0x03e0; - BlueMask = 0x001f; + paletteType = PAL_RGB16_555; } else if (bits == 16) { - *paletteType = PAL_BITFIELDS; - RedMask = 0xF800; - GreenMask = 0x07e0; - BlueMask = 0x001f; + paletteType = PAL_RGB16_565; } else { - *paletteType = PAL_RGB; - RedMask = 0xff0000; - GreenMask = 0x00ff00; - BlueMask = 0x0000ff; + if((pdwColors[0] == 0x0000FF) /* R */ + && (pdwColors[1] == 0x00FF00) /* G */ + && (pdwColors[2] == 0xFF0000))/* B */ + { + paletteType = PAL_BGR; + } + else + { + paletteType == PAL_RGB; + } }
if (bmi->bmiHeader.biClrUsed == 0) @@ -1832,207 +1762,18 @@ ColorCount = bmi->bmiHeader.biClrUsed; }
- if (PAL_INDEXED == *paletteType) + if (PAL_INDEXED == paletteType) { hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)pdwColors); } else { - hPal = PALETTE_AllocPalette(*paletteType, 0, + hPal = PALETTE_AllocPalette(paletteType, 0, 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; -} - -NTSTATUS -FASTCALL -ProbeAndConvertToBitmapV5Info( - OUT PBITMAPV5INFO pbmiDst, - IN CONST BITMAPINFO* pbmiUnsafe, - IN DWORD dwColorUse, - IN UINT MaxSize) -{ - DWORD dwSize; - ULONG ulWidthBytes; - PBITMAPV5HEADER pbmhDst = &pbmiDst->bmiHeader; - - /* Get the size and probe */ - ProbeForRead(&pbmiUnsafe->bmiHeader.biSize, sizeof(DWORD), 1); - dwSize = pbmiUnsafe->bmiHeader.biSize; - /* At least dwSize bytes must be valids */ - ProbeForRead(pbmiUnsafe, max(dwSize, MaxSize), 1); - if(!MaxSize) - ProbeForRead(pbmiUnsafe, DIB_BitmapInfoSize(pbmiUnsafe, dwColorUse), 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 = DIB_GetDIBImageBytes(pbch->bcWidth, - pbch->bcHeight, - pbch->bcPlanes*pbch->bcBitCount) ; - pbmhDst->bV5XPelsPerMeter = 72; - pbmhDst->bV5YPelsPerMeter = 72; - pbmhDst->bV5ClrUsed = 0; - pbmhDst->bV5ClrImportant = 0; - } - else - { - /* Copy valid fields */ - memcpy(pbmiDst, pbmiUnsafe, dwSize); - if(!pbmhDst->bV5SizeImage) - pbmhDst->bV5SizeImage = DIB_GetDIBImageBytes(pbmhDst->bV5Width, - pbmhDst->bV5Height, - pbmhDst->bV5Planes*pbmhDst->bV5BitCount) ; - - 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; }
/* Converts a BITMAPCOREINFO to a BITMAPINFO structure,