{ 0xff, 0xff, 0xff, 0x00 }
};
+static const 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 const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
{ 0x00, 0x00, 0x00, 0x00 },
{ 0xff, 0xff, 0xff, 0x00 }
};
+static const RGBQUAD DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
+/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
+ { 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 }
+};
+
UINT
APIENTRY
UINT StartScan,
UINT ScanLines,
CONST VOID *Bits,
- CONST BITMAPINFO *bmi,
+ CONST BITMAPV5INFO *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;
DestSurf = &bitmap->SurfObj;
// Create source surface
- SourceSize.cx = bmi->bmiHeader.biWidth;
+ SourceSize.cx = bmi->bmiHeader.bV5Width;
SourceSize.cy = ScanLines;
// Determine width of DIB
- DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
+ DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.bV5BitCount);
SourceBitmap = EngCreateBitmap(SourceSize,
DIBWidth,
- BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression),
- bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
+ BitmapFormat(bmi->bmiHeader.bV5BitCount, bmi->bmiHeader.bV5Compression),
+ bmi->bmiHeader.bV5Height < 0 ? BMF_TOPDOWN : 0,
(PVOID) Bits);
if (0 == SourceBitmap)
{
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)
- {
- EngUnlockSurface(SourceSurf);
- EngDeleteSurface((HSURF)SourceBitmap);
- SURFACE_UnlockSurface(bitmap);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
+ ASSERT(bitmap->ppal);
// Source palette obtained from the BITMAPINFO
- DIB_Palette = BuildDIBPalette((PBITMAPINFO)bmi, (PINT)&DIB_Palette_Type);
+ DIB_Palette = BuildDIBPalette((BITMAPINFO*)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;
}
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;
// Determine destination rectangle
DestRect.left = 0;
- DestRect.top = abs(bmi->bmiHeader.biHeight) - StartScan - ScanLines;
+ DestRect.top = abs(bmi->bmiHeader.bV5Height) - StartScan - ScanLines;
DestRect.right = SourceSize.cx;
DestRect.bottom = DestRect.top + ScanLines;
// Clean up
EXLATEOBJ_vCleanup(&exlo);
PALETTE_UnlockPalette(ppalDIB);
- PALETTE_ShareUnlockPalette(ppalDDB);
PALETTE_FreePaletteByHandle(DIB_Palette);
EngUnlockSurface(SourceSurf);
EngDeleteSurface((HSURF)SourceBitmap);
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, 0);
+ ProbeForRead(Bits, bmiLocal.bmiHeader.bV5SizeImage, 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
return 0;
}
- Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
+ Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, &bmiLocal, ColorUse);
DC_UnlockDc(Dc);
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);
+ Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse, cjMaxInfo);
ProbeForRead(Bits, cjMaxBits, 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
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;
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)
{
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)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- Status = STATUS_UNSUCCESSFUL;
- goto Exit;
- }
+ ASSERT(pSurf->ppal);
/* Create a palette for the DIB */
- hpalDIB = BuildDIBPalette(bmi, (PINT)&DIBPaletteType);
+ hpalDIB = BuildDIBPalette((PBITMAPINFO)&bmiLocal, (PINT)&DIBPaletteType);
if (!hpalDIB)
{
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
}
/* 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",
}
if (ppalDIB) PALETTE_UnlockPalette(ppalDIB);
- if (ppalDDB) PALETTE_ShareUnlockPalette(ppalDDB);
if (pSourceSurf) EngUnlockSurface(pSourceSurf);
if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
UINT MaxBits,
UINT MaxInfo)
{
- PDC Dc;
- SURFACE *psurf = NULL;
- HBITMAP hDestBitmap = NULL;
- HPALETTE hDestPalette = NULL;
- PPALETTE ppalSrc = NULL;
- PPALETTE ppalDst = NULL;
- NTSTATUS Status = STATUS_SUCCESS;
- ULONG Result = 0;
- BOOL bPaletteMatch = FALSE;
- PBYTE ChkBits = Bits;
- PVOID ColorPtr;
- RGBQUAD *rgbQuads;
- ULONG DestPaletteType;
- ULONG Index;
+ BITMAPCOREINFO* pbmci = NULL;
+ PSURFACE psurf = NULL;
+ PDC pDC;
+ LONG width, height;
+ WORD planes, bpp;
+ DWORD compr, size ;
+ int i, bitmap_type;
+ RGBTRIPLE* rgbTriples;
+ RGBQUAD* rgbQuads;
+ VOID* colorPtr;
+ NTSTATUS Status = STATUS_SUCCESS;
DPRINT("Entered NtGdiGetDIBitsInternal()\n");
if ((Usage && Usage != DIB_PAL_COLORS) || !Info || !hBitmap)
return 0;
- // if ScanLines == 0, no need to copy Bits.
- if (!ScanLines)
- ChkBits = NULL;
-
_SEH2_TRY
{
- ProbeForRead(&Info->bmiHeader.biSize, sizeof(DWORD), 1);
-
- ProbeForWrite(Info, Info->bmiHeader.biSize, 1); // Comp for Core.
- if (ChkBits) ProbeForWrite(ChkBits, MaxBits, 1);
+ /* Probe for read and write */
+ ProbeForRead(Info, MaxInfo, 1);
+ ProbeForWrite(Info, MaxInfo, 1);
+ if (Bits) ProbeForWrite(Bits, MaxBits, 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
return 0;
}
- Dc = DC_LockDc(hDC);
- if (Dc == NULL) return 0;
- if (Dc->dctype == DC_TYPE_INFO)
+ colorPtr = (LPBYTE)Info + Info->bmiHeader.biSize;
+ rgbTriples = colorPtr;
+ rgbQuads = colorPtr;
+
+ bitmap_type = DIB_GetBitmapInfo(&Info->bmiHeader,
+ &width,
+ &height,
+ &planes,
+ &bpp,
+ &compr,
+ &size);
+ if(bitmap_type == -1)
+ {
+ DPRINT("Wrong bitmap format\n");
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ else if(bitmap_type == 0)
+ {
+ /* We need a BITMAPINFO to create a DIB, but we have to fill
+ * the BITMAPCOREINFO we're provided */
+ pbmci = (BITMAPCOREINFO*)Info;
+ Info = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD), TAG_DIB);
+ if(Info == NULL)
+ {
+ DPRINT1("Error, could not allocate another BITMAPINFO!\n");
+ return 0;
+ }
+ RtlZeroMemory(Info, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+ Info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ Info->bmiHeader.biBitCount = pbmci->bmciHeader.bcBitCount;
+ Info->bmiHeader.biPlanes = pbmci->bmciHeader.bcPlanes;
+ Info->bmiHeader.biWidth = pbmci->bmciHeader.bcWidth;
+ Info->bmiHeader.biHeight = pbmci->bmciHeader.bcHeight;
+ rgbQuads = Info->bmiColors;
+ }
+
+ pDC = DC_LockDc(hDC);
+ if (pDC == NULL || pDC->dctype == DC_TYPE_INFO)
{
- DC_UnlockDc(Dc);
- return 0;
+ ScanLines = 0;
+ goto done;
}
/* Get a pointer to the source bitmap object */
psurf = SURFACE_LockSurface(hBitmap);
if (psurf == NULL)
{
- DC_UnlockDc(Dc);
- return 0;
- }
-
- if (psurf->ppal)
- {
- ppalSrc = psurf->ppal;
- GDIOBJ_IncrementShareCount(&ppalSrc->BaseObject);
- }
- else
- ppalSrc = PALETTE_ShareLockPalette(Dc->ppdev->devinfo.hpalDefault);
-
- 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. */
- if ((Info->bmiHeader.biBitCount == BitsPerFormat(psurf->SurfObj.iBitmapFormat) &&
- Info->bmiHeader.biBitCount != 15 && Info->bmiHeader.biBitCount != 16) ||
- !ChkBits)
- {
- ppalDst = ppalSrc;
- bPaletteMatch = TRUE;
- }
- else
- hDestPalette = BuildDIBPalette(Info, (PINT)&DestPaletteType); //hDestPalette = Dc->DevInfo->hpalDefault;
-
- if (!bPaletteMatch)
- {
- ppalDst = PALETTE_LockPalette(hDestPalette);
- /* FIXME - ppalDst can be NULL!!!! Don't assert here!!! */
- DPRINT("ppalDst : %p\n", ppalDst);
- ASSERT(ppalDst);
- }
-
- /* Copy palette. */
- /* FIXME: This is largely incomplete. ATM no Core!*/
- switch (Info->bmiHeader.biBitCount)
- {
- case 1:
- case 4:
- case 8:
- Info->bmiHeader.biClrUsed = 0;
- if (psurf->hSecure &&
- BitsPerFormat(psurf->SurfObj.iBitmapFormat) == Info->bmiHeader.biBitCount)
- {
- if (Usage == DIB_RGB_COLORS)
- {
- if (ppalDst->NumColors != 1 << Info->bmiHeader.biBitCount)
- Info->bmiHeader.biClrUsed = ppalDst->NumColors;
- for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount) && Index < ppalDst->NumColors;
- Index++)
+ ScanLines = 0;
+ goto done;
+ }
+ /* Must not be selected */
+ if(psurf->hdc != NULL)
+ {
+ ScanLines = 0;
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ goto done;
+ }
+
+get_info:
+ /* Fill in the structure */
+ switch(bpp)
+ {
+ case 0: /* Only info */
+ if(pbmci)
+ {
+ pbmci->bmciHeader.bcWidth = psurf->SurfObj.sizlBitmap.cx;
+ pbmci->bmciHeader.bcHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
+ -psurf->SurfObj.sizlBitmap.cy :
+ psurf->SurfObj.sizlBitmap.cy;
+ pbmci->bmciHeader.bcPlanes = 1;
+ pbmci->bmciHeader.bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+ }
+ Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
+ Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
+ -psurf->SurfObj.sizlBitmap.cy :
+ psurf->SurfObj.sizlBitmap.cy;;
+ Info->bmiHeader.biPlanes = 1;
+ Info->bmiHeader.biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+ Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( Info->bmiHeader.biWidth,
+ Info->bmiHeader.biHeight,
+ Info->bmiHeader.biBitCount);
+ if(psurf->hSecure)
+ {
+ switch(Info->bmiHeader.biBitCount)
+ {
+ case 16:
+ case 32:
+ Info->bmiHeader.biCompression = BI_BITFIELDS;
+ break;
+ default:
+ Info->bmiHeader.biCompression = BI_RGB;
+ break;
+ }
+ }
+ else if(Info->bmiHeader.biBitCount > 8)
+ {
+ Info->bmiHeader.biCompression = BI_BITFIELDS;
+ }
+ else
+ {
+ Info->bmiHeader.biCompression = BI_RGB;
+ }
+ Info->bmiHeader.biXPelsPerMeter = 0;
+ Info->bmiHeader.biYPelsPerMeter = 0;
+ Info->bmiHeader.biClrUsed = 0;
+ Info->bmiHeader.biClrImportant = 0;
+ ScanLines = psurf->SurfObj.sizlBitmap.cy;
+ /* Get Complete info now */
+ bpp = Info->bmiHeader.biBitCount ;
+ goto get_info;
+
+ case 1:
+ case 4:
+ case 8:
+ Info->bmiHeader.biClrUsed = 0;
+
+ /* If the bitmap if a DIB section and has the same format than what
+ * we're asked, go ahead! */
+ if((psurf->hSecure) &&
+ (BitsPerFormat(psurf->SurfObj.iBitmapFormat) == bpp))
+ {
+ if(Usage == DIB_RGB_COLORS)
+ {
+ unsigned int colors = min(psurf->ppal->NumColors, 1 << bpp);
+
+ if(pbmci)
+ {
+ for(i=0; i < colors; i++)
+ {
+ rgbTriples[i].rgbtRed = psurf->ppal->IndexedColors[i].peRed;
+ rgbTriples[i].rgbtGreen = psurf->ppal->IndexedColors[i].peGreen;
+ rgbTriples[i].rgbtBlue = psurf->ppal->IndexedColors[i].peBlue;
+ }
+ }
+ if(colors != 1 << bpp) Info->bmiHeader.biClrUsed = colors;
+ RtlCopyMemory(rgbQuads, psurf->ppal->IndexedColors, colors * sizeof(RGBQUAD));
+ }
+ else
+ {
+ for(i=0; i < 1 << bpp; i++)
+ {
+ if(pbmci) ((WORD*)rgbTriples)[i] = i;
+ ((WORD*)rgbQuads)[i] = i;
+ }
+ }
+ }
+ else
+ {
+ if(Usage == DIB_PAL_COLORS)
+ {
+ for(i=0; i < 1 << bpp; i++)
+ {
+ if(pbmci) ((WORD*)rgbTriples)[i] = i;
+ ((WORD*)rgbQuads)[i] = i;
+ }
+ }
+ else if(bpp > 1 && bpp == BitsPerFormat(psurf->SurfObj.iBitmapFormat)) {
+ /* For color DDBs in native depth (mono DDBs always have
+ a black/white palette):
+ Generate the color map from the selected palette */
+ PPALETTE pDcPal = PALETTE_LockPalette(pDC->dclevel.hpal);
+ if(!pDcPal)
+ {
+ ScanLines = 0 ;
+ goto done ;
+ }
+ for (i = 0; i < pDcPal->NumColors; i++) {
+ if (pbmci)
{
- 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;
+ rgbTriples[i].rgbtRed = pDcPal->IndexedColors[i].peRed;
+ rgbTriples[i].rgbtGreen = pDcPal->IndexedColors[i].peGreen;
+ rgbTriples[i].rgbtBlue = pDcPal->IndexedColors[i].peBlue;
}
- }
- else
- {
- PWORD Ptr = ColorPtr;
- for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount);
- Index++)
- {
- Ptr[Index] = (WORD)Index;
- }
- }
- }
- else
- {
- if (Usage == DIB_PAL_COLORS)
- {
- PWORD Ptr = ColorPtr;
- for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount);
- Index++)
+
+ rgbQuads[i].rgbRed = pDcPal->IndexedColors[i].peRed;
+ rgbQuads[i].rgbGreen = pDcPal->IndexedColors[i].peGreen;
+ rgbQuads[i].rgbBlue = pDcPal->IndexedColors[i].peBlue;
+ rgbQuads[i].rgbReserved = 0;
+ }
+ PALETTE_UnlockPalette(pDcPal);
+ } else {
+ switch (bpp) {
+ case 1:
+ if (pbmci)
{
- Ptr[Index] = (WORD)Index;
+ rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
+ rgbTriples[0].rgbtBlue = 0;
+ rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
+ rgbTriples[1].rgbtBlue = 0xff;
}
- }
- else if (Info->bmiHeader.biBitCount > 1 && bPaletteMatch)
- {
- for (Index = 0;
- 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;
- }
- }
- else
- {
- switch (Info->bmiHeader.biBitCount)
+ 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:
+ if (pbmci)
+ RtlCopyMemory(rgbTriples, EGAColorsTriples, sizeof(EGAColorsTriples));
+ RtlCopyMemory(rgbQuads, EGAColorsQuads, sizeof(EGAColorsQuads));
+
+ break;
+
+ case 8:
{
- 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;
- break;
- case 4:
- RtlCopyMemory(ColorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
- break;
- case 8:
+ INT r, g, b;
+ RGBQUAD *color;
+ if (pbmci)
{
- INT r, g, b;
- RGBQUAD *color;
-
- RtlCopyMemory(rgbQuads, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
- RtlCopyMemory(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;
+ RGBTRIPLE *colorTriple;
+
+ RtlCopyMemory(rgbTriples, DefLogPaletteTriples,
+ 10 * sizeof(RGBTRIPLE));
+ RtlCopyMemory(rgbTriples + 246, DefLogPaletteTriples + 10,
+ 10 * sizeof(RGBTRIPLE));
+ colorTriple = rgbTriples + 10;
+ for(r = 0; r <= 5; r++) /* FIXME */
+ {
+ for(g = 0; g <= 5; g++)
+ {
+ for(b = 0; b <= 5; b++)
+ {
+ colorTriple->rgbtRed = (r * 0xff) / 5;
+ colorTriple->rgbtGreen = (g * 0xff) / 5;
+ colorTriple->rgbtBlue = (b * 0xff) / 5;
color++;
}
+ }
+ }
}
- break;
+ 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++;
+ }
+ }
+ }
}
}
}
+ }
+ break;
- case 15:
- if (Info->bmiHeader.biCompression == BI_BITFIELDS)
- {
- ((PDWORD)Info->bmiColors)[0] = 0x7c00;
- ((PDWORD)Info->bmiColors)[1] = 0x03e0;
- ((PDWORD)Info->bmiColors)[2] = 0x001f;
- }
- break;
+ case 15:
+ if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ ((PDWORD)Info->bmiColors)[0] = 0x7c00;
+ ((PDWORD)Info->bmiColors)[1] = 0x03e0;
+ ((PDWORD)Info->bmiColors)[2] = 0x001f;
+ }
+ break;
- case 16:
- if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ case 16:
+ if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ if (psurf->hSecure) RtlCopyMemory( Info->bmiColors, psurf->dsBitfields, 3 * sizeof(DWORD) );
+ else
{
((PDWORD)Info->bmiColors)[0] = 0xf800;
((PDWORD)Info->bmiColors)[1] = 0x07e0;
((PDWORD)Info->bmiColors)[2] = 0x001f;
}
- break;
+ }
+ break;
- case 24:
- case 32:
- if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ case 24:
+ case 32:
+ if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ if (psurf->hSecure) RtlCopyMemory( Info->bmiColors, psurf->dsBitfields, 3 * sizeof(DWORD) );
+ else
{
((PDWORD)Info->bmiColors)[0] = 0xff0000;
((PDWORD)Info->bmiColors)[1] = 0x00ff00;
((PDWORD)Info->bmiColors)[2] = 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;
}
- Result = psurf->SurfObj.sizlBitmap.cy;
+ break;
}
- else
- {
- SIZEL DestSize;
- POINTL SourcePoint;
-//
-// If we have a good dib pointer, why not just copy bits from there w/o XLATE'ing them.
-//
- /* Create the destination bitmap too for the copy operation */
- if (StartScan > psurf->SurfObj.sizlBitmap.cy)
+ if(Bits && ScanLines)
+ {
+ /* Create a DIBSECTION, blt it, profit */
+ PVOID pDIBits ;
+ HBITMAP hBmpDest, hOldDest = NULL, hOldSrc = NULL;
+ HDC hdcDest, hdcSrc;
+ BOOL ret ;
+
+ if (StartScan > psurf->SurfObj.sizlBitmap.cy)
{
- goto cleanup;
+ ScanLines = 0;
+ goto done;
}
else
{
ScanLines = min(ScanLines, psurf->SurfObj.sizlBitmap.cy - StartScan);
- DestSize.cx = psurf->SurfObj.sizlBitmap.cx;
- DestSize.cy = ScanLines;
-
- 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,
- 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);
- }
-
- if (hDestBitmap == NULL)
- goto cleanup;
- }
-
- if (NT_SUCCESS(Status))
- {
- EXLATEOBJ exlo;
- SURFOBJ *DestSurfObj;
- RECTL DestRect;
-
- EXLATEOBJ_vInitialize(&exlo, ppalSrc, ppalDst, 0, 0, 0);
-
- SourcePoint.x = 0;
- SourcePoint.y = psurf->SurfObj.sizlBitmap.cy - (StartScan + ScanLines);
-
- /* Determine destination rectangle */
- DestRect.top = 0;
- DestRect.left = 0;
- DestRect.right = DestSize.cx;
- DestRect.bottom = DestSize.cy;
-
- DestSurfObj = EngLockSurface((HSURF)hDestBitmap);
-
- if (IntEngCopyBits(DestSurfObj,
- &psurf->SurfObj,
- NULL,
- &exlo.xlo,
- &DestRect,
- &SourcePoint))
- {
- DPRINT("GetDIBits %d \n",abs(Info->bmiHeader.biHeight) - StartScan);
- Result = ScanLines;
- }
-
- EXLATEOBJ_vCleanup(&exlo);
- EngUnlockSurface(DestSurfObj);
- }
- }
-cleanup:
- PALETTE_ShareUnlockPalette(ppalSrc);
-
- if (hDestBitmap != NULL)
- EngDeleteSurface((HSURF)hDestBitmap);
-
- if (hDestPalette != NULL && bPaletteMatch == FALSE)
- PALETTE_FreePaletteByHandle(hDestPalette);
-
- SURFACE_UnlockSurface(psurf);
-
- DPRINT("leaving NtGdiGetDIBitsInternal\n");
-
- return Result;
+ }
+
+ hBmpDest = DIB_CreateDIBSection(pDC, Info, Usage, &pDIBits, NULL, 0, 0);
+
+ if(!hBmpDest)
+ {
+ DPRINT1("Unable to create a DIB Section!\n");
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ ScanLines = 0;
+ goto done ;
+ }
+
+ hdcDest = NtGdiCreateCompatibleDC(0);
+ hdcSrc = NtGdiCreateCompatibleDC(0);
+
+ if(!(hdcSrc && hdcDest))
+ {
+ DPRINT1("Error: could not create HDCs!\n");
+ ScanLines = 0;
+ goto cleanup_blt;
+ }
+
+ hOldDest = NtGdiSelectBitmap(hdcDest, hBmpDest);
+ hOldSrc = NtGdiSelectBitmap(hdcSrc, hBitmap);
+
+ if(!(hOldDest && hOldSrc))
+ {
+ DPRINT1("Error : Could not Select bitmaps\n");
+ goto cleanup_blt;
+ }
+
+ ret = GreStretchBltMask(hdcDest,
+ 0,
+ 0,
+ width,
+ height,
+ hdcSrc,
+ 0,
+ StartScan,
+ psurf->SurfObj.sizlBitmap.cx,
+ ScanLines,
+ SRCCOPY,
+ 0,
+ NULL,
+ 0,
+ 0);
+
+ if(!ret)
+ ScanLines = 0;
+ else
+ {
+ Status = STATUS_SUCCESS;
+ _SEH2_TRY
+ {
+ RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, height, bpp));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("Unable to copy bits to the user provided pointer\n");
+ ScanLines = 0;
+ }
+ }
+
+ cleanup_blt:
+ if(hdcSrc)
+ {
+ if(hOldSrc) NtGdiSelectBitmap(hdcSrc, hOldSrc);
+ NtGdiDeleteObjectApp(hdcSrc);
+ }
+ if(hdcSrc)
+ {
+ if(hOldDest) NtGdiSelectBitmap(hdcDest, hOldDest);
+ NtGdiDeleteObjectApp(hdcDest);
+ }
+ GreDeleteObject(hBmpDest);
+ }
+
+done:
+
+ if(pDC) DC_UnlockDc(pDC);
+ if(psurf) SURFACE_UnlockSurface(psurf);
+ if(pbmci) ExFreePoolWithTag(Info, TAG_DIB);
+
+ return ScanLines;
}
+
INT
APIENTRY
NtGdiStretchDIBitsInternal(
HDC hdcMem;
HPALETTE hPal = NULL;
PDC pDC;
- BOOL Hit = FALSE;
+ NTSTATUS Status;
+ BITMAPV5INFO bmiLocal ;
if (!Bits || !BitsInfo)
{
_SEH2_TRY
{
- ProbeForRead(BitsInfo, cjMaxInfo, 1);
+ Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, BitsInfo, Usage, cjMaxInfo);
ProbeForRead(Bits, cjMaxBits, 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Hit = TRUE;
+ Status = _SEH2_GetExceptionCode();
}
_SEH2_END
- if (Hit)
+ if (!NT_SUCCESS(Status))
{
DPRINT1("NtGdiStretchDIBitsInternal fail to read BitMapInfo: %x or Bits: %x\n",BitsInfo,Bits);
return 0;
}
hBitmap = NtGdiCreateCompatibleBitmap(hDC,
- abs(BitsInfo->bmiHeader.biWidth),
- abs(BitsInfo->bmiHeader.biHeight));
+ abs(bmiLocal.bmiHeader.bV5Width),
+ abs(bmiLocal.bmiHeader.bV5Height));
if (hBitmap == NULL)
{
DPRINT1("NtGdiCreateCompatibleBitmap fail create bitmap\n");
hPal = GdiSelectPalette(hdcMem, hPal, FALSE);
}
- if (BitsInfo->bmiHeader.biCompression == BI_RLE4 ||
- BitsInfo->bmiHeader.biCompression == BI_RLE8)
+ 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(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
+ NtGdiBitBlt(hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
SrcWidth, SrcHeight, hDC, XDest, YDest, ROP, 0, 0);
else
- NtGdiStretchBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
+ NtGdiStretchBlt(hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
SrcWidth, SrcHeight, hDC, XDest, YDest, DestWidth, DestHeight,
ROP, 0);
}
* 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(BitsInfo->bmiHeader.biHeight), Bits,
- BitsInfo, Usage);
+ IntSetDIBits(pDC, hBitmap, 0, abs(bmiLocal.bmiHeader.bV5Height), Bits,
+ &bmiLocal, Usage);
DC_UnlockDc(pDC);
}
left (negative biHeight) */
if (SrcWidth == DestWidth && SrcHeight == DestHeight)
NtGdiBitBlt(hDC, XDest, YDest, DestWidth, DestHeight,
- hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
+ hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
ROP, 0, 0);
else
NtGdiStretchBlt(hDC, XDest, YDest, DestWidth, DestHeight,
- hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
+ hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
SrcWidth, SrcHeight, ROP, 0);
/* cleanup */
UINT bpp,
DWORD init,
LPBYTE bits,
- PBITMAPINFO data,
+ PBITMAPV5INFO data,
DWORD coloruse)
{
HBITMAP handle;
else if ((coloruse != DIB_RGB_COLORS) || (init != CBM_INIT) || !data) fColor = FALSE;
else
{
- if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
- {
- const RGBQUAD *rgb = data->bmiColors;
- DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
-
- // Check if the first color of the colormap is black
- if ((col == RGB(0, 0, 0)))
- {
- rgb++;
- col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
+ const RGBQUAD *rgb = data->bmiColors;
+ DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
- // If the second color is white, create a monochrome bitmap
- fColor = (col != RGB(0xff,0xff,0xff));
- }
- else fColor = TRUE;
- }
- else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+ // Check if the first color of the colormap is black
+ if ((col == RGB(0, 0, 0)))
{
- RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
- DWORD col = RGB(rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue);
+ rgb++;
+ col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
- if ((col == RGB(0,0,0)))
- {
- rgb++;
- col = RGB(rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue);
- fColor = (col != RGB(0xff,0xff,0xff));
- }
- else fColor = TRUE;
- }
- else
- {
- DPRINT("(%ld): wrong size for data\n", data->bmiHeader.biSize);
- return 0;
+ // If the second color is white, create a monochrome bitmap
+ fColor = (col != RGB(0xff,0xff,0xff));
}
+ else fColor = TRUE;
}
// Now create the bitmap
}
else
{
- handle = IntGdiCreateBitmap(width,
- height,
- 1,
- 1,
- NULL);
+ handle = GreCreateBitmap(width,
+ height,
+ 1,
+ 1,
+ NULL);
}
if (height < 0)
IN UINT cjMaxBits,
IN FLONG fl,
IN HANDLE hcmXform)
+{
+ BITMAPV5INFO bmiLocal ;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ _SEH2_TRY
+ {
+ if(pbmi) Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, pbmi, iUsage, cjMaxInitInfo);
+ if(pjInit && (fInit == CBM_INIT)) ProbeForRead(pjInit, cjMaxBits, 1);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return NULL;
+ }
+
+ return GreCreateDIBitmapInternal(hDc,
+ cx,
+ cy,
+ fInit,
+ pjInit,
+ pbmi ? &bmiLocal : NULL,
+ iUsage,
+ fl,
+ hcmXform);
+}
+
+HBITMAP
+FASTCALL
+GreCreateDIBitmapInternal(
+ IN HDC hDc,
+ IN INT cx,
+ IN INT cy,
+ IN DWORD fInit,
+ IN OPTIONAL LPBYTE pjInit,
+ IN OPTIONAL PBITMAPV5INFO pbmi,
+ IN DWORD iUsage,
+ IN FLONG fl,
+ IN HANDLE hcmXform)
{
PDC Dc;
HBITMAP Bmp;
- UINT bpp;
+ WORD bpp;
+ HDC hdcDest;
- if (!hDc) // CreateBitmap
+ if (!hDc) /* 1bpp monochrome bitmap */
{ // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
- hDc = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE);
- if (!hDc)
+ hdcDest = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE);
+ if(!hdcDest)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return NULL;
- }
-
- Dc = DC_LockDc(hDc);
- if (!Dc)
- {
- NtGdiDeleteObjectApp(hDc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
}
- bpp = 1;
- Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
+ }
+ else
+ {
+ hdcDest = hDc;
+ }
- DC_UnlockDc(Dc);
- NtGdiDeleteObjectApp(hDc);
+ Dc = DC_LockDc(hdcDest);
+ if (!Dc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return NULL;
}
- else // CreateCompatibleBitmap
+ /* 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;
+ else
+ bpp = 0;
+ Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
+ DC_UnlockDc(Dc);
+
+ if(!hDc)
{
- Dc = DC_LockDc(hDc);
- if (!Dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return NULL;
- }
- /* pbmi == null
- First create an un-initialised bitmap. The depth of the bitmap
- should match that of the hdc and not that supplied in bmih.
- */
- if (pbmi)
- bpp = pbmi->bmiHeader.biBitCount;
- else
- {
- if (Dc->dctype != DC_TYPE_MEMORY)
- bpp = Dc->ppdev->gdiinfo.cBitsPixel;
- else
- {
- DIBSECTION dibs;
- INT Count;
- SURFACE *psurf = Dc->dclevel.pSurface;
- Count = BITMAP_GetObject(psurf, sizeof(dibs), &dibs);
- if (!Count)
- bpp = 1;
- else
- {
- if (Count == sizeof(BITMAP))
- /* A device-dependent bitmap is selected in the DC */
- bpp = dibs.dsBm.bmBitsPixel;
- else
- /* A DIB section is selected in the DC */
- bpp = dibs.dsBmih.biBitCount;
- }
- }
- }
- Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
- DC_UnlockDc(Dc);
+ NtGdiDeleteObjectApp(hdcDest);
}
return Bmp;
}
IN HDC hDC,
IN OPTIONAL HANDLE hSection,
IN DWORD dwOffset,
- IN LPBITMAPINFO bmi,
+ IN BITMAPINFO* bmi,
IN DWORD Usage,
IN UINT cjHeader,
IN FLONG fl,
HBITMAP hbitmap = 0;
DC *dc;
BOOL bDesktopDC = FALSE;
+ NTSTATUS Status = STATUS_SUCCESS;
if (!bmi) return hbitmap; // Make sure.
+ _SEH2_TRY
+ {
+ ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1);
+ ProbeForRead(bmi, bmi->bmiHeader.biSize, 1);
+ ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, Usage), 1);
+ }
+ _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 (hDC == 0)
{
if ((dc = DC_LockDc(hDC)))
{
hbitmap = DIB_CreateDIBSection(dc,
- (BITMAPINFO*)bmi,
+ bmi,
Usage,
Bits,
hSection,
APIENTRY
DIB_CreateDIBSection(
PDC dc,
- BITMAPINFO *bmi,
+ CONST BITMAPINFO *bmi,
UINT usage,
LPVOID *bits,
HANDLE section,
HBITMAP res = 0;
SURFACE *bmp = NULL;
void *mapBits = NULL;
- PDC_ATTR pdcattr;
HPALETTE hpal ;
+ ULONG palMode = PAL_INDEXED;
// Fill BITMAP32 structure with DIB data
- BITMAPINFOHEADER *bi = &bmi->bmiHeader;
+ CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader;
INT effHeight;
ULONG totalSize;
BITMAP bm;
SIZEL Size;
- RGBQUAD *lpRGB;
+ CONST RGBQUAD *lpRGB = NULL;
HANDLE hSecure;
DWORD dsBitfields[3] = {0};
ULONG ColorCount;
return (HBITMAP)NULL;
}
- pdcattr = dc->pdcattr;
-
effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
bm.bmType = 0;
bm.bmWidth = bi->biWidth;
{
offset = 0;
bm.bmBits = EngAllocUserMem(totalSize, 0);
+ if(!bm.bmBits) goto cleanup;
}
// hSecure = MmSecureVirtualMemory(bm.bmBits, totalSize, PAGE_READWRITE);
ColorCount = bi->biClrUsed;
if (ColorCount == 0)
{
- ColorCount = 1 << bi->biBitCount;
+ ColorCount = max(1 << bi->biBitCount, 256);
}
}
- else
+ else if(bi->biBitCount <= 8)
{
lpRGB = bmi->bmiColors;
ColorCount = 1 << bi->biBitCount;
}
+ else
+ {
+ lpRGB = NULL;
+ ColorCount = 0;
+ }
/* Set dsBitfields values */
if (usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
{
dsBitfields[0] = dsBitfields[1] = dsBitfields[2] = 0;
+ palMode = PAL_INDEXED;
}
else if (bi->biCompression == BI_RGB)
{
+ dsBitfields[0] = dsBitfields[1] = dsBitfields[2] = 0;
switch (bi->biBitCount)
{
case 15:
- dsBitfields[0] = 0x7c00;
- dsBitfields[1] = 0x03e0;
- dsBitfields[2] = 0x001f;
- break;
+ palMode = PAL_RGB16_555;
+ break;
case 16:
- dsBitfields[0] = 0xF800;
- dsBitfields[1] = 0x07e0;
- dsBitfields[2] = 0x001f;
+ palMode = PAL_RGB16_565;
break;
case 24:
case 32:
- dsBitfields[0] = 0xff0000;
- dsBitfields[1] = 0x00ff00;
- dsBitfields[2] = 0x0000ff;
+ palMode = PAL_RGB;
break;
}
}
else
{
- dsBitfields[0] = ((DWORD*)bmi->bmiColors)[0];
- dsBitfields[1] = ((DWORD*)bmi->bmiColors)[1];
- dsBitfields[2] = ((DWORD*)bmi->bmiColors)[2];
+ RtlCopyMemory(dsBitfields, bmi->bmiColors, sizeof(dsBitfields));
+ palMode = PAL_BITFIELDS;
}
// Create Device Dependent Bitmap and add DIB pointer
Size.cx = bm.bmWidth;
Size.cy = abs(bm.bmHeight);
- res = IntCreateBitmap(Size,
- bm.bmWidthBytes,
- BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
- BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
- (bi->biHeight < 0 ? BMF_TOPDOWN : 0),
- bm.bmBits);
+ res = GreCreateBitmapEx(bm.bmWidth,
+ abs(bm.bmHeight),
+ bm.bmWidthBytes,
+ BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
+ BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
+ (bi->biHeight < 0 ? BMF_TOPDOWN : 0),
+ bi->biSizeImage,
+ bm.bmBits);
if (!res)
{
- if (lpRGB != bmi->bmiColors)
- {
- ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
- }
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- return NULL;
+ goto cleanup;
}
bmp = SURFACE_LockSurface(res);
if (NULL == bmp)
{
- if (lpRGB != bmi->bmiColors)
- {
- ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
- }
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- GreDeleteObject(res);
- return NULL;
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ goto cleanup;
}
/* WINE NOTE: WINE makes use of a colormap, which is a color translation
table between the DIB and the X physical device. Obviously,
this is left out of the ReactOS implementation. Instead,
we call NtGdiSetDIBColorTable. */
- if (bi->biBitCount <= 8)
- {
- bi->biClrUsed = 1 << bi->biBitCount;
- }
- else
- {
- bi->biClrUsed = 0;
- }
-
bmp->hDIBSection = section;
bmp->hSecure = hSecure;
bmp->dwOffset = offset;
bmp->dsBitfields[0] = dsBitfields[0];
bmp->dsBitfields[1] = dsBitfields[1];
bmp->dsBitfields[2] = dsBitfields[2];
- bmp->biClrUsed = bi->biClrUsed;
+ bmp->biClrUsed = ColorCount;
bmp->biClrImportant = bi->biClrImportant;
- if (bi->biClrUsed != 0)
- {
- hpal = PALETTE_AllocPaletteIndexedRGB(ColorCount, lpRGB);
- }
- else
- {
- hpal = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL,
+ hpal = PALETTE_AllocPalette(palMode, ColorCount, (ULONG*)lpRGB,
dsBitfields[0],
dsBitfields[1],
dsBitfields[2]);
- }
bmp->ppal = PALETTE_ShareLockPalette(hpal);
/* Lazy delete hpal, it will be freed at surface release */
GreDeleteObject(hpal);
// Clean up in case of errors
+cleanup:
if (!res || !bmp || !bm.bmBits)
{
DPRINT("got an error res=%08x, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits);
}
}
- if (lpRGB != bmi->bmiColors)
+ if (lpRGB != bmi->bmiColors && lpRGB)
{
- ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
+ ExFreePoolWithTag((PVOID)lpRGB, TAG_COLORMAP);
}
if (bmp)
*bits = bm.bmBits;
}
- if (res) pdcattr->ulDirty_ |= DC_DIBSECTION;
-
return res;
}
+/***********************************************************************
+ * DIB_GetBitmapInfo
+ *
+ * Get the info from a bitmap header.
+ * Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error.
+ */
+int
+FASTCALL
+DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
+ LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size )
+{
+ if (header->biSize == sizeof(BITMAPCOREHEADER))
+ {
+ const BITMAPCOREHEADER *core = (const 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)) /* assume BITMAPINFOHEADER */
+ {
+ *width = header->biWidth;
+ *height = header->biHeight;
+ *planes = header->biPlanes;
+ *bpp = header->biBitCount;
+ *compr = header->biCompression;
+ *size = header->biSizeImage;
+ return 1;
+ }
+ DPRINT1("(%d): unknown/wrong size for header\n", header->biSize );
+ return -1;
+}
+
/***********************************************************************
* DIB_GetDIBWidthBytes
*
INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse)
{
- int colors;
+ unsigned int colors, size, masks = 0;
if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
- BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
+ const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
- return sizeof(BITMAPCOREHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
+ return sizeof(BITMAPCOREHEADER) + colors *
+ ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
}
else /* assume BITMAPINFOHEADER */
{
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));
+ if (colors > 256) colors = 256;
+ if (!colors && (info->bmiHeader.biBitCount <= 8))
+ colors = 1 << info->bmiHeader.biBitCount;
+ if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
+ size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
+ return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
}
}
{
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;
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)
{
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)
+{
+ PVOID pvColors = ((PBYTE)pbmi + pbmi->bmiHeader.biSize);
+ if(pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+ {
+ RGBTRIPLE *pColor = pvColors;
+ pColor[i] = *(RGBTRIPLE*)color;
+ }
+ else
+ {
+ RGBQUAD *pColor = pvColors;
+ pColor[i] = *(RGBQUAD*)color;
+ }
+}
+
+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;
+}
+
+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(&pbmiDst->bmiHeader.biWidth,
+ &pbmiSrc->bmiHeader.bV5Width,
+ 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;
+ ULONG cColorsUsed;
+
+ cColorsUsed = pbmiSrc->bmiHeader.bV5ClrUsed;
+ if (cColorsUsed == 0 && pbmiSrc->bmiHeader.bV5BitCount <= 8)
+ cColorsUsed = (1 << pbmiSrc->bmiHeader.bV5BitCount);
+
+ if(dwColorUse == DIB_PAL_COLORS)
+ {
+ RtlCopyMemory(pbmiDst->bmiColors,
+ pbmiSrc->bmiColors,
+ cColorsUsed * sizeof(WORD));
+ }
+ else
+ {
+ for(i = 0; i < cColorsUsed; i++)
+ {
+ SetBMIColor(pbmiDst, (DWORD*)pbmiSrc->bmiColors + i, i);
+ }
+ }
+ }
+}
+
/* EOF */