{ 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
CONST BITMAPINFO *bmi,
UINT ColorUse)
{
- SURFACE *bitmap;
HBITMAP SourceBitmap;
+ PSURFACE psurfDst, psurfSrc;
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.biWidth;
- SourceSize.cy = ScanLines;
+ RECT rcDst;
+ POINTL ptSrc;
+ PVOID pvBits;
+ EXLATEOBJ exlo;
- // Determine width of DIB
- DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
-
- SourceBitmap = EngCreateBitmap(SourceSize,
- DIBWidth,
- BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression),
- bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
- (PVOID) Bits);
- if (0 == SourceBitmap)
+ SourceBitmap = DIB_CreateDIBSection(DC, bmi, ColorUse, &pvBits, NULL, 0, 0);
+ if (0 == SourceBitmap)
{
- SURFACE_UnlockSurface(bitmap);
+ 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;
- }
+ RtlCopyMemory(pvBits, Bits, DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
+ bmi->bmiHeader.biHeight,
+ bmi->bmiHeader.biBitCount));
- ASSERT(bitmap->ppal);
+ psurfDst = SURFACE_LockSurface(hBitmap);
+ psurfSrc = SURFACE_LockSurface(SourceBitmap);
- // 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_NO_SYSTEM_RESOURCES);
- return 0;
- }
+ if(!(psurfSrc && psurfDst))
+ {
+ DPRINT1("Error, could not lock surfaces.\n");
+ goto cleanup;
+ }
- ppalDIB = PALETTE_LockPalette(DIB_Palette);
+ rcDst.top = bmi->bmiHeader.biHeight < 0 ?
+ abs(bmi->bmiHeader.biHeight) - (ScanLines + StartScan) : StartScan;
+ rcDst.left = 0;
+ rcDst.bottom = rcDst.top + ScanLines;
+ rcDst.right = psurfDst->SurfObj.sizlBitmap.cx;
- /* Initialize XLATEOBJ for color translation */
- EXLATEOBJ_vInitialize(&exlo, ppalDIB, bitmap->ppal, 0, 0, 0);
+ ptSrc.x = 0;
+ ptSrc.y = 0;
- // Zero point
- ZeroPoint.x = 0;
- ZeroPoint.y = 0;
+ EXLATEOBJ_vInitialize(&exlo, psurfSrc->ppal, psurfDst->ppal, 0, 0, 0);
- // Determine destination rectangle
- DestRect.left = 0;
- DestRect.top = abs(bmi->bmiHeader.biHeight) - StartScan - ScanLines;
- DestRect.right = SourceSize.cx;
- DestRect.bottom = DestRect.top + ScanLines;
+ result = IntEngCopyBits(&psurfDst->SurfObj,
+ &psurfSrc->SurfObj,
+ NULL,
+ &exlo.xlo,
+ &rcDst,
+ &ptSrc);
+ if(result)
+ result = ScanLines;
- copyBitsResult = IntEngCopyBits(DestSurf, SourceSurf, NULL, &exlo.xlo, &DestRect, &ZeroPoint);
+ EXLATEOBJ_vCleanup(&exlo);
- // 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);
+cleanup:
+ if(psurfSrc)
+ {
+ SURFACE_UnlockSurface(psurfSrc);
+ }
+ if(psurfDst)
+ {
+ SURFACE_UnlockSurface(psurfDst);
+ }
+ GreDeleteObject(SourceBitmap);
return result;
}
PDC Dc;
INT Ret;
NTSTATUS Status = STATUS_SUCCESS;
- BITMAPV5INFO bmiLocal;
if (!Bits) return 0;
_SEH2_TRY
{
- Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse);
+ 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)
{
return 0;
}
- Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, (PBITMAPINFO)&bmiLocal, ColorUse);
+ Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
DC_UnlockDc(Dc);
EXLATEOBJ exlo;
PPALETTE ppalDIB = NULL;
HPALETTE hpalDIB = NULL;
- ULONG DIBPaletteType;
- BITMAPV5INFO bmiLocal ;
if (!Bits) return 0;
_SEH2_TRY
{
- Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse);
+ ProbeForRead(bmi, cjMaxInfo, 1);
+ ProbeForRead(Bits, cjMaxBits, 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
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;
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)
{
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);
UINT MaxBits,
UINT MaxInfo)
{
- PDC Dc;
- SURFACE *psurf = NULL;
- HBITMAP hDestBitmap = NULL;
- HPALETTE hDestPalette = NULL;
- BITMAPV5INFO bmiLocal ;
- PPALETTE ppalDst = NULL;
- NTSTATUS Status = STATUS_SUCCESS;
- ULONG Result = 0;
- BOOL bPaletteMatch = FALSE;
- PBYTE ChkBits = Bits;
- 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
{
- Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, Info, Usage);
- 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 = DIB_ConvertBitmapInfo((BITMAPINFO*)pbmci, Usage);
+ if(Info == NULL)
+ {
+ DPRINT1("Error, could not convert the BITMAPCOREINFO!\n");
+ return 0;
+ }
+ 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;
- }
-
- ASSERT(psurf->ppal);
-
- DC_UnlockDc(Dc);
-
- /* 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 = psurf->ppal;
- bPaletteMatch = TRUE;
- }
- else
- {
- hDestPalette = BuildDIBPalette((PBITMAPINFO)&bmiLocal, (PINT)&DestPaletteType);
- ppalDst = PALETTE_LockPalette(hDestPalette);
- }
-
- DPRINT("ppalDst : %p\n", ppalDst);
- ASSERT(ppalDst);
-
- /* Copy palette. */
- switch (bmiLocal.bmiHeader.bV5BitCount)
- {
- case 1:
- case 4:
- case 8:
- bmiLocal.bmiHeader.bV5ClrUsed = 0;
- if (psurf->hSecure &&
- BitsPerFormat(psurf->SurfObj.iBitmapFormat) == bmiLocal.bmiHeader.bV5BitCount)
- {
- if (Usage == DIB_RGB_COLORS)
- {
- if (ppalDst->NumColors != 1 << bmiLocal.bmiHeader.bV5BitCount)
- bmiLocal.bmiHeader.bV5ClrUsed = ppalDst->NumColors;
- for (Index = 0;
- Index < (1 << bmiLocal.bmiHeader.bV5BitCount) && Index < ppalDst->NumColors;
- Index++)
- {
- 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
- {
- for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount);
- Index++)
+ ScanLines = 0;
+ goto done;
+ }
+
+ /* 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 = abs(Info->bmiHeader.biHeight);
+ goto done;
+
+ 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;
+ for(i=0; i < colors; i++)
+ {
+ rgbQuads[i].rgbRed = psurf->ppal->IndexedColors[i].peRed;
+ rgbQuads[i].rgbGreen = psurf->ppal->IndexedColors[i].peGreen;
+ rgbQuads[i].rgbBlue = psurf->ppal->IndexedColors[i].peBlue;
+ }
+ }
+ 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)
{
- ((WORD*)bmiLocal.bmiColors)[Index] = Index;
+ rgbTriples[i].rgbtRed = pDcPal->IndexedColors[i].peRed;
+ rgbTriples[i].rgbtGreen = pDcPal->IndexedColors[i].peGreen;
+ rgbTriples[i].rgbtBlue = pDcPal->IndexedColors[i].peBlue;
}
- }
- }
- else
- {
- if (Usage == DIB_PAL_COLORS)
- {
- for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount);
- Index++)
- {
- ((WORD*)bmiLocal.bmiColors)[Index] = (WORD)Index;
- }
- }
- else if (Info->bmiHeader.biBitCount > 1 && bPaletteMatch)
- {
- for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount) && Index < ppalDst->NumColors;
- 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)
{
- 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;
+ rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
+ rgbTriples[0].rgbtBlue = 0;
+ rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
+ rgbTriples[1].rgbtBlue = 0xff;
}
- }
- else
- {
- switch (bmiLocal.bmiHeader.bV5BitCount)
+ 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:
- 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(bmiLocal.bmiColors, EGAColorsQuads, sizeof(EGAColorsQuads));
- break;
- case 8:
+ INT r, g, b;
+ RGBQUAD *color;
+ if (pbmci)
{
- INT r, g, b;
- RGBQUAD *color;
-
- 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++)
- {
- 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 (bmiLocal.bmiHeader.bV5Compression == BI_BITFIELDS)
- {
- bmiLocal.bmiHeader.bV5RedMask = 0x7c00;
- bmiLocal.bmiHeader.bV5GreenMask = 0x03e0;
- bmiLocal.bmiHeader.bV5BlueMask = 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)
+ {
+ ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
+ ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
+ ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
+ }
+ else
{
- bmiLocal.bmiHeader.bV5RedMask = 0xf800;
- bmiLocal.bmiHeader.bV5GreenMask = 0x07e0;
- bmiLocal.bmiHeader.bV5BlueMask = 0x001f;
+ ((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)
+ {
+ ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
+ ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
+ ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
+ }
+ else
{
- bmiLocal.bmiHeader.bV5RedMask = 0xff0000;
- bmiLocal.bmiHeader.bV5GreenMask = 0x00ff00;
- bmiLocal.bmiHeader.bV5BlueMask = 0x0000ff;
+ ((PDWORD)Info->bmiColors)[0] = 0xff0000;
+ ((PDWORD)Info->bmiColors)[1] = 0x00ff00;
+ ((PDWORD)Info->bmiColors)[2] = 0x0000ff;
}
- break;
- }
-
- /* fill out the BITMAPINFO struct */
- if (!ChkBits)
- {
- 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
- {
- 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)
+ break;
+ }
+ Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(width, height, bpp);
+
+ if(Bits && ScanLines)
+ {
+ /* Create a DIBSECTION, blt it, profit */
+ PVOID pDIBits ;
+ HBITMAP hBmpDest;
+ PSURFACE psurfDest;
+ EXLATEOBJ exlo;
+ RECT rcDest;
+ POINTL srcPoint;
+ 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;
-
- 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);
-
- if (hDestBitmap == NULL)
- goto cleanup;
- }
-
- if (NT_SUCCESS(Status))
- {
- EXLATEOBJ exlo;
- SURFOBJ *DestSurfObj;
- RECTL DestRect;
-
- EXLATEOBJ_vInitialize(&exlo, psurf->ppal, 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);
- }
- }
- /* Now that everything is over, get back the information to caller */
- /* Note : Info has already been probed */
- GetBMIFromBitmapV5Info(&bmiLocal, Info, Usage);
-cleanup:
-
- if (hDestBitmap != NULL)
- EngDeleteSurface((HSURF)hDestBitmap);
-
- if (hDestPalette != NULL && !bPaletteMatch)
- {
- PALETTE_UnlockPalette(ppalDst);
- PALETTE_FreePaletteByHandle(hDestPalette);
- }
-
- SURFACE_UnlockSurface(psurf);
-
- DPRINT("leaving NtGdiGetDIBitsInternal\n");
-
- return Result;
+ }
+
+ /* Fixup values */
+ Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
+ Info->bmiHeader.biHeight = height < 0 ?
+ -ScanLines : ScanLines;
+ /* Create the DIB */
+ hBmpDest = DIB_CreateDIBSection(pDC, Info, Usage, &pDIBits, NULL, 0, 0);
+ /* Restore them */
+ Info->bmiHeader.biWidth = width;
+ Info->bmiHeader.biHeight = height;
+
+ if(!hBmpDest)
+ {
+ DPRINT1("Unable to create a DIB Section!\n");
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ ScanLines = 0;
+ goto done ;
+ }
+
+ psurfDest = SURFACE_LockSurface(hBmpDest);
+
+ rcDest.left = 0;
+ rcDest.top = 0;
+ rcDest.bottom = ScanLines;
+ rcDest.right = psurf->SurfObj.sizlBitmap.cx;
+
+ srcPoint.x = 0;
+ srcPoint.y = height < 0 ?
+ psurf->SurfObj.sizlBitmap.cy - (StartScan + ScanLines) : StartScan;
+
+ EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0, 0, 0);
+
+ ret = IntEngCopyBits(&psurfDest->SurfObj,
+ &psurf->SurfObj,
+ NULL,
+ &exlo.xlo,
+ &rcDest,
+ &srcPoint);
+
+ 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;
+ }
+ }
+
+ GreDeleteObject(hBmpDest);
+ EXLATEOBJ_vCleanup(&exlo);
+ }
+ else ScanLines = abs(height);
+
+done:
+
+ if(pDC) DC_UnlockDc(pDC);
+ if(psurf) SURFACE_UnlockSurface(psurf);
+ if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci);
+
+ return ScanLines;
}
+
INT
APIENTRY
NtGdiStretchDIBitsInternal(
HANDLE hcmXform)
{
HBITMAP hBitmap, hOldBitmap = NULL;
- HDC hdcMem;
- HPALETTE hPal = NULL;
- PDC pDC;
- BOOL Hit = FALSE;
+ HDC hdcMem = NULL;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PVOID pvDIBits;
+ INT Ret = 0;
if (!Bits || !BitsInfo)
{
return 0;
}
- _SEH2_TRY
- {
- ProbeForRead(BitsInfo, cjMaxInfo, 1);
- ProbeForRead(Bits, cjMaxBits, 1);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Hit = TRUE;
- }
- _SEH2_END
-
- if (Hit)
- {
- 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(BitsInfo->bmiHeader.biWidth),
- abs(BitsInfo->bmiHeader.biHeight));
- 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 (BitsInfo->bmiHeader.biCompression == BI_RLE4 ||
- BitsInfo->bmiHeader.biCompression == BI_RLE8)
- {
- /* copy existing bitmap from destination dc */
- if (SrcWidth == DestWidth && SrcHeight == DestHeight)
- NtGdiBitBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, hDC, XDest, YDest, ROP, 0, 0);
- else
- NtGdiStretchBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - 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(BitsInfo->bmiHeader.biHeight), Bits,
- BitsInfo, 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(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
- ROP, 0, 0);
- else
- NtGdiStretchBlt(hDC, XDest, YDest, DestWidth, DestHeight,
- hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, ROP, 0);
-
- /* cleanup */
- if (hPal)
- GdiSelectPalette(hdcMem, hPal, FALSE);
-
- if (hOldBitmap)
- NtGdiSelectBitmap(hdcMem, hOldBitmap);
-
- NtGdiDeleteObjectApp(hdcMem);
+ /* 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;
+ }
+
+ /* Set bits */
+ _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 ;
- GreDeleteObject(hBitmap);
+cleanup:
+ if(hdcMem)
+ {
+ if(hOldBitmap) NtGdiSelectBitmap(hdcMem, hOldBitmap);
+ NtGdiDeleteObjectApp(hdcMem);
+ }
+ GreDeleteObject(hBitmap);
- return SrcHeight;
+ return Ret;
}
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);
+ 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
- if ((col == RGB(0, 0, 0)))
- {
- rgb++;
- 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
IN UINT cjMaxBits,
IN FLONG fl,
IN HANDLE hcmXform)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ _SEH2_TRY
+ {
+ if(pbmi) ProbeForRead(pbmi, cjMaxInitInfo, 1);
+ 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,
+ iUsage,
+ fl,
+ hcmXform);
+}
+
+HBITMAP
+FASTCALL
+GreCreateDIBitmapInternal(
+ IN HDC hDc,
+ IN INT cx,
+ IN INT cy,
+ IN DWORD fInit,
+ IN OPTIONAL LPBYTE pjInit,
+ IN OPTIONAL PBITMAPINFO 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 = NtGdiCreateCompatibleDC(0);
+ if(!hdcDest)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
}
+ }
+ else
+ {
+ hdcDest = hDc;
+ }
- 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);
-
- 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.biBitCount;
+ 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 ;
// 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;
HANDLE hSecure;
- DWORD dsBitfields[3] = {0};
- ULONG ColorCount;
DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
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);
if (usage == DIB_PAL_COLORS)
{
- lpRGB = DIB_MapPaletteColors(dc, bmi);
- ColorCount = bi->biClrUsed;
- if (ColorCount == 0)
- {
- ColorCount = 1 << bi->biBitCount;
- }
- }
- else
- {
- lpRGB = bmi->bmiColors;
- ColorCount = 1 << bi->biBitCount;
- }
-
- /* Set dsBitfields values */
- if (usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
- {
- dsBitfields[0] = dsBitfields[1] = dsBitfields[2] = 0;
- }
- else if (bi->biCompression == BI_RGB)
- {
- switch (bi->biBitCount)
- {
- case 15:
- dsBitfields[0] = 0x7c00;
- dsBitfields[1] = 0x03e0;
- dsBitfields[2] = 0x001f;
- break;
-
- case 16:
- dsBitfields[0] = 0xF800;
- dsBitfields[1] = 0x07e0;
- dsBitfields[2] = 0x001f;
- break;
-
- case 24:
- case 32:
- dsBitfields[0] = 0xff0000;
- dsBitfields[1] = 0x00ff00;
- dsBitfields[2] = 0x0000ff;
- break;
- }
- }
- else
- {
- dsBitfields[0] = ((DWORD*)bmi->bmiColors)[0];
- dsBitfields[1] = ((DWORD*)bmi->bmiColors)[1];
- dsBitfields[2] = ((DWORD*)bmi->bmiColors)[2];
- }
+ if(dc)
+ {
+ PPALETTE pdcPal ;
+ pdcPal = PALETTE_LockPalette(dc->dclevel.hpal);
+ hpal = DIB_MapPaletteColors(pdcPal, bmi);
+ PALETTE_UnlockPalette(pdcPal);
+ }
+ else
+ {
+ /* For DIB Brushes */
+ DPRINT1("FIXME : Unsupported DIB_PAL_COLORS without a DC to map colors.\n");
+ /* HACK */
+ hpal = (HPALETTE) 0xFFFFFFFF;
+ }
+ }
+ else
+ {
+ hpal = BuildDIBPalette(bmi);
+ }
+
+ if(!hpal)
+ {
+ DPRINT1("Error : Could not create a palette for the DIB.\n");
+ goto cleanup;
+ }
// Create Device Dependent Bitmap and add DIB pointer
Size.cx = bm.bmWidth;
BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
(bi->biHeight < 0 ? BMF_TOPDOWN : 0),
bi->biSizeImage,
- bm.bmBits);
+ bm.bmBits,
+ 0);
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->flags = API_BITMAP;
- bmp->dsBitfields[0] = dsBitfields[0];
- bmp->dsBitfields[1] = dsBitfields[1];
- bmp->dsBitfields[2] = dsBitfields[2];
- bmp->biClrUsed = bi->biClrUsed;
bmp->biClrImportant = bi->biClrImportant;
- if (bi->biClrUsed != 0)
- {
- hpal = PALETTE_AllocPaletteIndexedRGB(ColorCount, lpRGB);
- }
- else
- {
- hpal = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL,
- dsBitfields[0],
- dsBitfields[1],
- dsBitfields[2]);
- }
-
- bmp->ppal = PALETTE_ShareLockPalette(hpal);
- /* Lazy delete hpal, it will be freed at surface release */
- GreDeleteObject(hpal);
+ /* HACK */
+ if(hpal != (HPALETTE)0xFFFFFFFF)
+ {
+ 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)
- {
- ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
- }
-
if (bmp)
{
SURFACE_UnlockSurface(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 info->bmiHeader.biSize + 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));
}
}
-RGBQUAD *
+HPALETTE
FASTCALL
-DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi)
+DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi)
{
- RGBQUAD *lpRGB;
+ PALETTEENTRY* ppalEntries;
ULONG nNumColors,i;
USHORT *lpIndex;
- PPALETTE palGDI;
-
- palGDI = PALETTE_LockPalette(dc->dclevel.hpal);
-
- if (NULL == palGDI)
- {
- return NULL;
- }
+ HPALETTE hpal;
- if (palGDI->Mode != PAL_INDEXED)
+ if (ppal->Mode != PAL_INDEXED)
{
- PALETTE_UnlockPalette(palGDI);
return NULL;
}
nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
}
- lpRGB = (RGBQUAD *)ExAllocatePoolWithTag(PagedPool, sizeof(RGBQUAD) * nNumColors, TAG_COLORMAP);
- if (lpRGB == NULL)
+ /* Don't have more colors than we need */
+ nNumColors = min(ppal->NumColors, nNumColors);
+
+ ppalEntries = ExAllocatePoolWithTag(PagedPool, sizeof(PALETTEENTRY) * nNumColors, TAG_COLORMAP);
+ if (ppalEntries == NULL)
{
- PALETTE_UnlockPalette(palGDI);
+ 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);
+
+ hpal = PALETTE_AllocPalette(PAL_INDEXED, nNumColors, (ULONG*)ppalEntries, 0, 0, 0);
+
+ ExFreePoolWithTag(ppalEntries, TAG_COLORMAP);
- return lpRGB;
+ 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;
// 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_BGR;
- RedMask = 0xff0000;
- GreenMask = 0x00ff00;
- BlueMask = 0x0000ff;
+ paletteType = PAL_BGR;
}
if (bmi->bmiHeader.biClrUsed == 0)
ColorCount = bmi->bmiHeader.biClrUsed;
}
- if (PAL_INDEXED == *paletteType)
+ if (PAL_INDEXED == paletteType)
{
hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)pdwColors);
}
else
{
- hPal = PALETTE_AllocPalette(*paletteType, ColorCount,
+ hPal = PALETTE_AllocPalette(paletteType, 0,
NULL,
RedMask, GreenMask, BlueMask);
}
return hPal;
}
-FORCEINLINE
-DWORD
-GetBMIColor(CONST BITMAPINFO* pbmi, INT i)
+/* Converts a BITMAPCOREINFO to a BITMAPINFO structure,
+ * or does nothing if it's already a BITMAPINFO (or V4 or V5) */
+BITMAPINFO*
+FASTCALL
+DIB_ConvertBitmapInfo (CONST BITMAPINFO* pbmi, DWORD Usage)
{
- 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;
+ CONST BITMAPCOREINFO* pbmci = (BITMAPCOREINFO*)pbmi;
+ BITMAPINFO* pNewBmi ;
+ UINT numColors = 0, ColorsSize = 0;
+
+ if(pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) return (BITMAPINFO*)pbmi;
+ if(pbmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) return NULL;
+
+ if(pbmci->bmciHeader.bcBitCount <= 8)
+ {
+ numColors = 1 << pbmci->bmciHeader.bcBitCount;
+ if(Usage == DIB_PAL_COLORS)
+ {
+ ColorsSize = numColors * sizeof(WORD);
+ }
+ else
+ {
+ ColorsSize = numColors * sizeof(RGBQUAD);
+ }
+ }
+ else if (Usage == DIB_PAL_COLORS)
+ {
+ /* Invalid at high Res */
+ return NULL;
+ }
+
+ pNewBmi = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + ColorsSize, TAG_DIB);
+ if(!pNewBmi) return NULL;
+
+ RtlZeroMemory(pNewBmi, sizeof(BITMAPINFOHEADER) + ColorsSize);
+
+ pNewBmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pNewBmi->bmiHeader.biBitCount = pbmci->bmciHeader.bcBitCount;
+ pNewBmi->bmiHeader.biWidth = pbmci->bmciHeader.bcWidth;
+ pNewBmi->bmiHeader.biHeight = pbmci->bmciHeader.bcHeight;
+ pNewBmi->bmiHeader.biPlanes = pbmci->bmciHeader.bcPlanes;
+ pNewBmi->bmiHeader.biCompression = BI_RGB ;
+ pNewBmi->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(pNewBmi->bmiHeader.biWidth,
+ pNewBmi->bmiHeader.biHeight,
+ pNewBmi->bmiHeader.biBitCount);
+
+ if(Usage == DIB_PAL_COLORS)
+ {
+ RtlCopyMemory(pNewBmi->bmiColors, pbmci->bmciColors, ColorsSize);
+ }
+ else
+ {
+ UINT i;
+ for(i=0; i<numColors; i++)
+ {
+ pNewBmi->bmiColors[i].rgbRed = pbmci->bmciColors[i].rgbtRed;
+ pNewBmi->bmiColors[i].rgbGreen = pbmci->bmciColors[i].rgbtGreen;
+ pNewBmi->bmiColors[i].rgbBlue = pbmci->bmciColors[i].rgbtBlue;
+ }
+ }
+
+ return pNewBmi ;
}
-FORCEINLINE
+/* Frees a BITMAPINFO created with DIB_ConvertBitmapInfo */
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)
+DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig)
{
- 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(converted != orig)
+ ExFreePoolWithTag(converted, TAG_DIB);
+}
- 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 */