#define NDEBUG
#include <debug.h>
-static const RGBQUAD EGAColorsQuads[16] = {
-/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
+static const RGBQUAD EGAColorsQuads[16] =
+{
+ /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
{ 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x80, 0x00 },
{ 0x00, 0x80, 0x00, 0x00 },
{ 0xff, 0xff, 0xff, 0x00 }
};
-static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
-/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
+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 },
{ 0x00, 0x00, 0x80, 0x00 },
{ 0x00, 0x80, 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
if (psurf == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (psurf->hSecure == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (psurf->ppal == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return 0;
}
- PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
+ PalGDI = psurf->ppal;
for (Index = StartIndex;
- Index < StartIndex + Entries && Index < PalGDI->NumColors;
- Index++)
+ Index < StartIndex + Entries && Index < PalGDI->NumColors;
+ Index++)
{
PalGDI->IndexedColors[Index].peRed = Colors[Index - StartIndex].rgbRed;
PalGDI->IndexedColors[Index].peGreen = Colors[Index - StartIndex].rgbGreen;
PalGDI->IndexedColors[Index].peBlue = Colors[Index - StartIndex].rgbBlue;
}
- PALETTE_UnlockPalette(PalGDI);
}
else
Entries = 0;
{
PDC dc;
PSURFACE psurf;
- PPALETTE PalGDI;
+ PPALETTE ppal;
UINT Index, Count = 0;
- ULONG biBitCount;
if (!(dc = DC_LockDc(hDC))) return 0;
if (dc->dctype == DC_TYPE_INFO)
if (psurf == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (psurf->hSecure == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
- biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
- if (biBitCount <= 8 &&
- StartIndex < (1 << biBitCount))
- {
- if (StartIndex + Entries > (1 << biBitCount))
- Entries = (1 << biBitCount) - StartIndex;
-
- if (psurf->ppal == NULL)
- {
- DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
+ ppal = psurf->ppal;
+ ASSERT(ppal);
- PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
+ if (ppal->flFlags & PAL_INDEXED)
+ {
for (Index = StartIndex;
- Index < StartIndex + Entries && Index < PalGDI->NumColors;
- Index++)
+ Index < StartIndex + Entries && Index < ppal->NumColors;
+ Index++)
{
- Colors[Index - StartIndex].rgbRed = PalGDI->IndexedColors[Index].peRed;
- Colors[Index - StartIndex].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
- Colors[Index - StartIndex].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
+ Colors[Index - StartIndex].rgbRed = ppal->IndexedColors[Index].peRed;
+ Colors[Index - StartIndex].rgbGreen = ppal->IndexedColors[Index].peGreen;
+ Colors[Index - StartIndex].rgbBlue = ppal->IndexedColors[Index].peBlue;
Colors[Index - StartIndex].rgbReserved = 0;
Count++;
}
- PALETTE_UnlockPalette(PalGDI);
}
DC_UnlockDc(dc);
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;
+ RECT rcDst;
+ POINTL ptSrc;
+ PVOID pvBits;
+ EXLATEOBJ exlo;
- // Create source surface
- SourceSize.cx = bmi->bmiHeader.biWidth;
- SourceSize.cy = ScanLines;
-
- // 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);
+ SourceBitmap = DIB_CreateDIBSection(DC, bmi, ColorUse, &pvBits, NULL, 0, 0);
if (0 == SourceBitmap)
{
- SURFACE_UnlockSurface(bitmap);
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ DPRINT1("Error : Could not create a DIBSection.\n");
+ EngSetLastError(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_ShareLockSurface(hBitmap);
+ psurfSrc = SURFACE_ShareLockSurface(SourceBitmap);
- // Source palette obtained from the BITMAPINFO
- DIB_Palette = BuildDIBPalette(bmi, (PINT)&DIB_Palette_Type);
- if (NULL == DIB_Palette)
+ if(!(psurfSrc && psurfDst))
{
- EngUnlockSurface(SourceSurf);
- EngDeleteSurface((HSURF)SourceBitmap);
- SURFACE_UnlockSurface(bitmap);
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- return 0;
+ DPRINT1("Error, could not lock surfaces\n");
+ goto cleanup;
}
- ppalDIB = PALETTE_LockPalette(DIB_Palette);
+ rcDst.top = 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;
+ /* 1bpp bitmaps have 0 for white, 1 for black */
+ EXLATEOBJ_vInitialize(&exlo, psurfSrc->ppal, psurfDst->ppal, 0xFFFFFF, 0xFFFFFF, 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)
+cleanup:
+ if(psurfSrc)
{
- result = SourceSize.cy;
-// or
-// result = abs(bmi->bmiHeader.biHeight) - StartScan;
+ SURFACE_ShareUnlockSurface(psurfSrc);
}
-
- // 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);
+ if(psurfDst)
+ {
+ SURFACE_ShareUnlockSurface(psurfDst);
+ }
+ GreDeleteObject(SourceBitmap);
return result;
}
CONST BITMAPINFO *bmi,
UINT ColorUse)
{
- PDC Dc;
+ PDC Dc = NULL;
INT Ret;
NTSTATUS Status = STATUS_SUCCESS;
- BITMAPV5INFO bmiLocal;
if (!Bits) return 0;
_SEH2_TRY
{
- Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse, 0);
- ProbeForRead(Bits, bmiLocal.bmiHeader.bV5SizeImage, 1);
+ ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1);
+ ProbeForRead(bmi, bmi->bmiHeader.biSize, 1);
+ ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, ColorUse), 1);
+ ProbeForRead(Bits,
+ DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
+ ScanLines,
+ bmi->bmiHeader.biBitCount),
+ 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
return 0;
}
- Dc = DC_LockDc(hDC);
- if (NULL == Dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
- if (Dc->dctype == DC_TYPE_INFO)
+ /* Lock DC if asked to */
+ if(ColorUse == DIB_PAL_COLORS)
{
- DC_UnlockDc(Dc);
- return 0;
+ Dc = DC_LockDc(hDC);
+ if (NULL == Dc)
+ {
+ EngSetLastError(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+ if (Dc->dctype == DC_TYPE_INFO)
+ {
+ DC_UnlockDc(Dc);
+ return 0;
+ }
}
- Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, (PBITMAPINFO)&bmiLocal, ColorUse);
+ Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
- DC_UnlockDc(Dc);
+ if(Dc) DC_UnlockDc(Dc);
return Ret;
}
EXLATEOBJ exlo;
PPALETTE ppalDIB = NULL;
HPALETTE hpalDIB = NULL;
- ULONG DIBPaletteType;
- BITMAPV5INFO bmiLocal ;
if (!Bits) return 0;
_SEH2_TRY
{
- Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse, cjMaxInfo);
+ ProbeForRead(bmi, cjMaxInfo, 1);
ProbeForRead(Bits, cjMaxBits, 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
pDC = DC_LockDc(hDC);
if (!pDC)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return 0;
}
if (pDC->dctype == DC_TYPE_INFO)
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;
if (bTransformCoordinates)
{
- CoordLPtoDP(pDC, (LPPOINT)&rcDest);
+ IntLPtoDP(pDC, (LPPOINT)&rcDest, 2);
}
rcDest.left += pDC->ptlDCOrig.x;
rcDest.top += pDC->ptlDCOrig.y;
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 = WIDTH_BYTES_ALIGN32(SourceSize.cx, bmi->bmiHeader.biBitCount);
+
+ hSourceBitmap = GreCreateBitmapEx(bmi->bmiHeader.biWidth,
+ ScanLines,
+ 0,
+ BitmapFormat(bmi->bmiHeader.biBitCount,
+ bmi->bmiHeader.biCompression),
+ bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
+ bmi->bmiHeader.biSizeImage,
+ Bits,
+ 0);
- hSourceBitmap = EngCreateBitmap(SourceSize,
- DIBWidth,
- BitmapFormat(bmiLocal.bmiHeader.bV5BitCount,
- bmiLocal.bmiHeader.bV5Compression),
- bmiLocal.bmiHeader.bV5Height < 0 ? BMF_TOPDOWN : 0,
- (PVOID) Bits);
if (!hSourceBitmap)
{
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
Status = STATUS_NO_MEMORY;
goto Exit;
}
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);
+ EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
Status = STATUS_NO_MEMORY;
goto Exit;
}
/* Lock the DIB palette */
- ppalDIB = PALETTE_LockPalette(hpalDIB);
+ ppalDIB = PALETTE_ShareLockPalette(hpalDIB);
if (!ppalDIB)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
Status = STATUS_UNSUCCESSFUL;
goto Exit;
}
/* Initialize EXLATEOBJ */
- EXLATEOBJ_vInitialize(&exlo, ppalDIB, pSurf->ppal, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exlo,
+ ppalDIB,
+ pSurf->ppal,
+ RGB(0xff, 0xff, 0xff),
+ pDC->pdcattr->crBackgroundClr,
+ pDC->pdcattr->crForegroundClr);
/* Copy the bits */
DPRINT("BitsToDev with dstsurf=(%d|%d) (%d|%d), src=(%d|%d) w=%d h=%d\n",
- rcDest.left, rcDest.top, rcDest.right, rcDest.bottom,
- ptSource.x, ptSource.y, SourceSize.cx, SourceSize.cy);
+ rcDest.left, rcDest.top, rcDest.right, rcDest.bottom,
+ ptSource.x, ptSource.y, SourceSize.cx, SourceSize.cy);
Status = IntEngBitBlt(pDestSurf,
pSourceSurf,
NULL,
NULL,
NULL,
NULL,
- ROP3_TO_ROP4(SRCCOPY));
+ ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY));
/* Cleanup EXLATEOBJ */
EXLATEOBJ_vCleanup(&exlo);
ret = ScanLines;
}
- if (ppalDIB) PALETTE_UnlockPalette(ppalDIB);
+ if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
if (pSourceSurf) EngUnlockSurface(pSourceSurf);
if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
- if (hpalDIB) PALETTE_FreePaletteByHandle(hpalDIB);
+ if (hpalDIB) GreDeleteObject(hpalDIB);
DC_UnlockDc(pDC);
return ret;
UINT MaxBits,
UINT MaxInfo)
{
- PDC Dc;
- SURFACE *psurf = NULL;
- HBITMAP hDestBitmap = NULL;
- HPALETTE hDestPalette = NULL;
- BITMAPV5INFO bmiLocal ;
- PPALETTE ppalDst = NULL;
+ 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;
- ULONG Result = 0;
- BOOL bPaletteMatch = FALSE;
- PBYTE ChkBits = Bits;
- ULONG DestPaletteType;
- ULONG Index;
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, MaxInfo);
- 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)
{
- DC_UnlockDc(Dc);
+ DPRINT("Wrong bitmap format\n");
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
-
- /* Get a pointer to the source bitmap object */
- psurf = SURFACE_LockSurface(hBitmap);
- if (psurf == NULL)
+ else if(bitmap_type == 0)
{
- DC_UnlockDc(Dc);
- return 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;
}
- ASSERT(psurf->ppal);
-
- DC_UnlockDc(Dc);
-
- /* Copy palette information
- * Always create a palette for 15 & 16 bit. */
- if ((bmiLocal.bmiHeader.bV5BitCount == BitsPerFormat(psurf->SurfObj.iBitmapFormat) &&
- bmiLocal.bmiHeader.bV5BitCount != 15 && bmiLocal.bmiHeader.bV5BitCount != 16) ||
- !ChkBits)
+ pDC = DC_LockDc(hDC);
+ if (pDC == NULL || pDC->dctype == DC_TYPE_INFO)
{
- ppalDst = psurf->ppal;
- bPaletteMatch = TRUE;
+ ScanLines = 0;
+ goto done;
}
- else
+
+ /* Get a pointer to the source bitmap object */
+ psurf = SURFACE_ShareLockSurface(hBitmap);
+ if (psurf == NULL)
{
- hDestPalette = BuildDIBPalette((PBITMAPINFO)&bmiLocal, (PINT)&DestPaletteType);
- ppalDst = PALETTE_LockPalette(hDestPalette);
+ ScanLines = 0;
+ goto done;
}
- DPRINT("ppalDst : %p\n", ppalDst);
- ASSERT(ppalDst);
-
- /* Copy palette. */
- switch (bmiLocal.bmiHeader.bV5BitCount)
+ /* Fill in the structure */
+ switch(bpp)
{
- case 1:
- case 4:
- case 8:
- bmiLocal.bmiHeader.bV5ClrUsed = 0;
- if (psurf->hSecure &&
- BitsPerFormat(psurf->SurfObj.iBitmapFormat) == bmiLocal.bmiHeader.bV5BitCount)
+ 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)
{
- if (Usage == DIB_RGB_COLORS)
+ 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)
{
- if (ppalDst->NumColors != 1 << bmiLocal.bmiHeader.bV5BitCount)
- bmiLocal.bmiHeader.bV5ClrUsed = ppalDst->NumColors;
- for (Index = 0;
- Index < (1 << bmiLocal.bmiHeader.bV5BitCount) && Index < ppalDst->NumColors;
- Index++)
+ for(i=0; i < colors; i++)
{
- 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[i].rgbtRed = psurf->ppal->IndexedColors[i].peRed;
+ rgbTriples[i].rgbtGreen = psurf->ppal->IndexedColors[i].peGreen;
+ rgbTriples[i].rgbtBlue = psurf->ppal->IndexedColors[i].peBlue;
}
}
- else
+ if(colors != 1 << bpp) Info->bmiHeader.biClrUsed = colors;
+ for(i=0; i < colors; i++)
{
- for (Index = 0;
- Index < (1 << bmiLocal.bmiHeader.bV5BitCount);
- Index++)
- {
- ((WORD*)bmiLocal.bmiColors)[Index] = Index;
- }
+ 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
{
- if (Usage == DIB_PAL_COLORS)
+ 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++)
{
- for (Index = 0;
- Index < (1 << bmiLocal.bmiHeader.bV5BitCount);
- Index++)
+ 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_ShareLockPalette(pDC->dclevel.hpal);
+ if(!pDcPal)
+ {
+ ScanLines = 0 ;
+ goto done ;
+ }
+ for (i = 0; i < pDcPal->NumColors; i++)
+ {
+ if (pbmci)
{
- ((WORD*)bmiLocal.bmiColors)[Index] = (WORD)Index;
+ rgbTriples[i].rgbtRed = pDcPal->IndexedColors[i].peRed;
+ rgbTriples[i].rgbtGreen = pDcPal->IndexedColors[i].peGreen;
+ rgbTriples[i].rgbtBlue = pDcPal->IndexedColors[i].peBlue;
}
+
+ 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;
}
- else if (bmiLocal.bmiHeader.bV5BitCount > 1 && bPaletteMatch)
+ PALETTE_ShareUnlockPalette(pDcPal);
+ }
+ else
+ {
+ switch (bpp)
{
- for (Index = 0;
- Index < (1 << bmiLocal.bmiHeader.bV5BitCount) && Index < ppalDst->NumColors;
- Index++)
+ 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
+ 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:
{
- switch (bmiLocal.bmiHeader.bV5BitCount)
+ INT r, g, b;
+ RGBQUAD *color;
+ if (pbmci)
{
- 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:
+ 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 */
{
- 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;
- color++;
- }
+ 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++;
+ }
+ }
+ }
+ }
+ 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;
}
}
+ }
}
+ }
+ 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 (bmiLocal.bmiHeader.bV5Compression == BI_BITFIELDS)
+ case 16:
+ if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ if (psurf->hSecure)
{
- bmiLocal.bmiHeader.bV5RedMask = 0xf800;
- bmiLocal.bmiHeader.bV5GreenMask = 0x07e0;
- bmiLocal.bmiHeader.bV5BlueMask = 0x001f;
+ ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
+ ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
+ ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
}
- break;
-
- case 24:
- case 32:
- if (bmiLocal.bmiHeader.bV5Compression == BI_BITFIELDS)
+ else
{
- bmiLocal.bmiHeader.bV5RedMask = 0xff0000;
- bmiLocal.bmiHeader.bV5GreenMask = 0x00ff00;
- bmiLocal.bmiHeader.bV5BlueMask = 0x0000ff;
+ ((PDWORD)Info->bmiColors)[0] = 0xf800;
+ ((PDWORD)Info->bmiColors)[1] = 0x07e0;
+ ((PDWORD)Info->bmiColors)[2] = 0x001f;
}
- break;
- }
+ }
+ break;
- /* fill out the BITMAPINFO struct */
- if (!ChkBits)
- {
- bmiLocal.bmiHeader.bV5Width = psurf->SurfObj.sizlBitmap.cx;
- /* Report negative height for top-down bitmaps. */
- if (psurf->SurfObj.fjBitmap & BMF_TOPDOWN)
- bmiLocal.bmiHeader.bV5Height = - psurf->SurfObj.sizlBitmap.cy;
- else
- bmiLocal.bmiHeader.bV5Height = psurf->SurfObj.sizlBitmap.cy;
- bmiLocal.bmiHeader.bV5Planes = 1;
- bmiLocal.bmiHeader.bV5BitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
- switch (psurf->SurfObj.iBitmapFormat)
+ case 24:
+ case 32:
+ if (Info->bmiHeader.biCompression == BI_BITFIELDS)
{
- /* 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;
+ 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
+ {
+ ((PDWORD)Info->bmiColors)[0] = 0xff0000;
+ ((PDWORD)Info->bmiColors)[1] = 0x00ff00;
+ ((PDWORD)Info->bmiColors)[2] = 0x0000ff;
+ }
}
-
- bmiLocal.bmiHeader.bV5SizeImage = psurf->SurfObj.cjBits;
- bmiLocal.bmiHeader.bV5XPelsPerMeter = psurf->sizlDim.cx; /* FIXME */
- bmiLocal.bmiHeader.bV5YPelsPerMeter = psurf->sizlDim.cy; /* FIXME */
- bmiLocal.bmiHeader.bV5ClrUsed = 0;
- bmiLocal.bmiHeader.bV5ClrImportant = 1 << bmiLocal.bmiHeader.bV5BitCount; /* FIXME */
- Result = psurf->SurfObj.sizlBitmap.cy;
+ break;
}
- else
+ Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(width, height, bpp);
+
+ if(Bits && ScanLines)
{
- SIZEL DestSize;
- POINTL SourcePoint;
+ /* Create a DIBSECTION, blt it, profit */
+ PVOID pDIBits ;
+ HBITMAP hBmpDest;
+ PSURFACE psurfDest;
+ EXLATEOBJ exlo;
+ RECT rcDest;
+ POINTL srcPoint;
+ BOOL ret ;
-//
-// 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)
{
- 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,
- bmiLocal.bmiHeader.bV5BitCount) * DestSize.cy;
-
- hDestBitmap = EngCreateBitmap(DestSize,
- DIB_GetDIBWidthBytes(DestSize.cx,
- bmiLocal.bmiHeader.bV5BitCount),
- BitmapFormat(bmiLocal.bmiHeader.bV5BitCount,
- bmiLocal.bmiHeader.bV5Compression),
- bmiLocal.bmiHeader.bV5Height > 0 ? 0 : BMF_TOPDOWN,
- Bits);
-
- if (hDestBitmap == NULL)
- goto cleanup;
}
- if (NT_SUCCESS(Status))
+ /* 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)
{
- EXLATEOBJ exlo;
- SURFOBJ *DestSurfObj;
- RECTL DestRect;
+ DPRINT1("Unable to create a DIB Section!\n");
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ ScanLines = 0;
+ goto done ;
+ }
- EXLATEOBJ_vInitialize(&exlo, psurf->ppal, ppalDst, 0, 0, 0);
+ psurfDest = SURFACE_ShareLockSurface(hBmpDest);
- SourcePoint.x = 0;
- SourcePoint.y = psurf->SurfObj.sizlBitmap.cy - (StartScan + ScanLines);
+ rcDest.left = 0;
+ rcDest.top = 0;
+ rcDest.bottom = ScanLines;
+ rcDest.right = psurf->SurfObj.sizlBitmap.cx;
- /* Determine destination rectangle */
- DestRect.top = 0;
- DestRect.left = 0;
- DestRect.right = DestSize.cx;
- DestRect.bottom = DestSize.cy;
+ srcPoint.x = 0;
- DestSurfObj = EngLockSurface((HSURF)hDestBitmap);
+ if(height < 0)
+ {
+ srcPoint.y = 0;
- if (IntEngCopyBits(DestSurfObj,
- &psurf->SurfObj,
- NULL,
- &exlo.xlo,
- &DestRect,
- &SourcePoint))
+ if(ScanLines <= StartScan)
{
- DPRINT("GetDIBits %d \n",abs(bmiLocal.bmiHeader.bV5Height) - StartScan);
- Result = ScanLines;
+ ScanLines = 1;
+ SURFACE_ShareUnlockSurface(psurfDest);
+ GreDeleteObject(hBmpDest);
+ goto done;
}
- EXLATEOBJ_vCleanup(&exlo);
- EngUnlockSurface(DestSurfObj);
+ ScanLines -= StartScan;
+ }
+ else
+ {
+ srcPoint.y = StartScan;
}
- }
- /* Now that everything is over, get back the information to caller */
- _SEH2_TRY
- {
- /* Note : Info has already been probed */
- GetBMIFromBitmapV5Info(&bmiLocal, Info, Usage);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- /* FIXME: fail or something */
- }
- _SEH2_END
+ EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0xffffff, 0xffffff, 0);
-cleanup:
+ ret = IntEngCopyBits(&psurfDest->SurfObj,
+ &psurf->SurfObj,
+ NULL,
+ &exlo.xlo,
+ &rcDest,
+ &srcPoint);
- if (hDestBitmap != NULL)
- EngDeleteSurface((HSURF)hDestBitmap);
+ SURFACE_ShareUnlockSurface(psurfDest);
- if (hDestPalette != NULL && !bPaletteMatch)
- {
- PALETTE_UnlockPalette(ppalDst);
- PALETTE_FreePaletteByHandle(hDestPalette);
+ if(!ret)
+ ScanLines = 0;
+ else
+ {
+ Status = STATUS_SUCCESS;
+ _SEH2_TRY
+ {
+ RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, ScanLines, 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);
- SURFACE_UnlockSurface(psurf);
+done:
- DPRINT("leaving NtGdiGetDIBitsInternal\n");
+ if(pDC) DC_UnlockDc(pDC);
+ if(psurf) SURFACE_ShareUnlockSurface(psurf);
+ if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci);
- return Result;
+ return ScanLines;
}
+#define ROP_TO_ROP4(Rop) ((Rop) >> 16)
+
+W32KAPI
INT
APIENTRY
NtGdiStretchDIBitsInternal(
- HDC hDC,
- INT XDest,
- INT YDest,
- INT DestWidth,
- INT DestHeight,
- INT XSrc,
- INT YSrc,
- INT SrcWidth,
- INT SrcHeight,
- LPBYTE Bits,
- LPBITMAPINFO BitsInfo,
- DWORD Usage,
- DWORD ROP,
- UINT cjMaxInfo,
- UINT cjMaxBits,
- HANDLE hcmXform)
+ IN HDC hdc,
+ IN INT xDst,
+ IN INT yDst,
+ IN INT cxDst,
+ IN INT cyDst,
+ IN INT xSrc,
+ IN INT ySrc,
+ IN INT cxSrc,
+ IN INT cySrc,
+ IN OPTIONAL LPBYTE pjInit,
+ IN LPBITMAPINFO pbmi,
+ IN DWORD dwUsage,
+ IN DWORD dwRop, // ms ntgdi.h says dwRop4(?)
+ IN UINT cjMaxInfo,
+ IN UINT cjMaxBits,
+ IN HANDLE hcmXform)
{
- HBITMAP hBitmap, hOldBitmap = NULL;
- HDC hdcMem;
- HPALETTE hPal = NULL;
- PDC pDC;
- NTSTATUS Status;
- BITMAPV5INFO bmiLocal ;
-
- if (!Bits || !BitsInfo)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- _SEH2_TRY
- {
- Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, BitsInfo, Usage, cjMaxInfo);
- ProbeForRead(Bits, cjMaxBits, 1);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END
+ BOOL bResult = FALSE;
+ SIZEL sizel;
+ RECTL rcSrc, rcDst;
+ PDC pdc;
+ HBITMAP hbmTmp;
+ PSURFACE psurfTmp, psurfDst;
+ EXLATEOBJ exlo;
- if (!NT_SUCCESS(Status))
+ if (!(pdc = DC_LockDc(hdc)))
{
- DPRINT1("NtGdiStretchDIBitsInternal fail to read BitMapInfo: %x or Bits: %x\n",BitsInfo,Bits);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return 0;
}
- hdcMem = NtGdiCreateCompatibleDC(hDC);
- if (hdcMem == NULL)
- {
- DPRINT1("NtGdiCreateCompatibleDC fail create hdc\n");
+ /* Transform dest size */
+ sizel.cx = cxDst;
+ sizel.cy = cyDst;
+ IntLPtoDP(pdc, (POINTL*)&sizel, 1);
+ DC_UnlockDc(pdc);
+
+ /* Check if we can use NtGdiSetDIBitsToDeviceInternal */
+ if (sizel.cx == cxSrc && sizel.cy == cySrc && dwRop == SRCCOPY)
+ {
+ /* Yes, we can! */
+ return NtGdiSetDIBitsToDeviceInternal(hdc,
+ xDst,
+ yDst,
+ cxDst,
+ cyDst,
+ xSrc,
+ ySrc,
+ 0,
+ cySrc,
+ pjInit,
+ pbmi,
+ dwUsage,
+ cjMaxBits,
+ cjMaxInfo,
+ TRUE,
+ hcmXform);
+ }
+
+ /* Create an intermediate bitmap from the DIB */
+ hbmTmp = NtGdiCreateDIBitmapInternal(hdc,
+ cxSrc,
+ cySrc,
+ CBM_INIT,
+ pjInit,
+ pbmi,
+ dwUsage,
+ cjMaxInfo,
+ cjMaxBits,
+ 0,
+ hcmXform);
+ if (!hbmTmp)
+ {
+ DPRINT1("NtGdiCreateDIBitmapInternal failed\n");
return 0;
}
- hBitmap = NtGdiCreateCompatibleBitmap(hDC,
- abs(bmiLocal.bmiHeader.bV5Width),
- abs(bmiLocal.bmiHeader.bV5Height));
- if (hBitmap == NULL)
+ /* FIXME: locking twice is cheesy, coord tranlation in UM will fix it */
+ if (!(pdc = DC_LockDc(hdc)))
{
- 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);
+ DPRINT1("Could not lock dc\n");
+ EngSetLastError(ERROR_INVALID_HANDLE);
+ GreDeleteObject(hbmTmp);
return 0;
}
- /* Select the bitmap into hdcMem, and save a handle to the old bitmap */
- hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
-
- if (Usage == DIB_PAL_COLORS)
- {
- hPal = NtGdiGetDCObject(hDC, GDI_OBJECT_TYPE_PALETTE);
- hPal = GdiSelectPalette(hdcMem, hPal, FALSE);
- }
-
- if (bmiLocal.bmiHeader.bV5Compression == BI_RLE4 ||
- bmiLocal.bmiHeader.bV5Compression == BI_RLE8)
+ psurfTmp = SURFACE_ShareLockSurface(hbmTmp);
+ if (!psurfTmp)
{
- /* copy existing bitmap from destination dc */
- if (SrcWidth == DestWidth && SrcHeight == DestHeight)
- NtGdiBitBlt(hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, hDC, XDest, YDest, ROP, 0, 0);
- else
- NtGdiStretchBlt(hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, hDC, XDest, YDest, DestWidth, DestHeight,
- ROP, 0);
+ DPRINT1("Could not lock bitmap :-(\n");
+ goto cleanup;
}
- pDC = DC_LockDc(hdcMem);
- if (pDC != NULL)
+ psurfDst = pdc->dclevel.pSurface;
+ if (!psurfDst)
{
- /* Note BitsInfo->bmiHeader.biHeight is the number of scanline,
- * if it negitve we getting to many scanline for scanline is UINT not
- * a INT, so we need make the negtive value to positve and that make the
- * count correct for negtive bitmap, TODO : we need testcase for this api */
- IntSetDIBits(pDC, hBitmap, 0, abs(bmiLocal.bmiHeader.bV5Height), Bits,
- (PBITMAPINFO)&bmiLocal, Usage);
-
- DC_UnlockDc(pDC);
+ // CHECKME
+ bResult = TRUE;
+ goto cleanup;
}
+ /* Calculate source and destination rect */
+ rcSrc.left = xSrc;
+ rcSrc.top = ySrc;
+ rcSrc.right = xSrc + abs(cxSrc);
+ rcSrc.bottom = ySrc + abs(cySrc);
+ rcDst.left = xDst;
+ rcDst.top = yDst;
+ rcDst.right = rcDst.left + cxDst;
+ rcDst.bottom = rcDst.top + cyDst;
+ IntLPtoDP(pdc, (POINTL*)&rcDst, 2);
+ RECTL_vOffsetRect(&rcDst, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
- /* Origin for DIBitmap may be bottom left (positive biHeight) or top
- left (negative biHeight) */
- if (SrcWidth == DestWidth && SrcHeight == DestHeight)
- NtGdiBitBlt(hDC, XDest, YDest, DestWidth, DestHeight,
- hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
- ROP, 0, 0);
- else
- NtGdiStretchBlt(hDC, XDest, YDest, DestWidth, DestHeight,
- hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, ROP, 0);
-
- /* cleanup */
- if (hPal)
- GdiSelectPalette(hdcMem, hPal, FALSE);
+ /* Initialize XLATEOBJ */
+ EXLATEOBJ_vInitialize(&exlo,
+ psurfTmp->ppal,
+ psurfDst->ppal,
+ RGB(0xff, 0xff, 0xff),
+ pdc->pdcattr->crBackgroundClr,
+ pdc->pdcattr->crForegroundClr);
- if (hOldBitmap)
- NtGdiSelectBitmap(hdcMem, hOldBitmap);
+ /* Prepare DC for blit */
+ DC_vPrepareDCsForBlit(pdc, rcDst, NULL, rcSrc);
- NtGdiDeleteObjectApp(hdcMem);
+ /* Perform the stretch operation */
+ bResult = IntEngStretchBlt(&psurfDst->SurfObj,
+ &psurfTmp->SurfObj,
+ NULL,
+ pdc->rosdc.CombinedClip,
+ &exlo.xlo,
+ &rcDst,
+ &rcSrc,
+ NULL,
+ &pdc->eboFill.BrushObject,
+ NULL,
+ ROP_TO_ROP4(dwRop));
- GreDeleteObject(hBitmap);
+ /* Cleanup */
+ DC_vFinishBlit(pdc, NULL);
+ EXLATEOBJ_vCleanup(&exlo);
+cleanup:
+ if (psurfTmp) SURFACE_ShareUnlockSurface(psurfTmp);
+ if (hbmTmp) GreDeleteObject(hbmTmp);
+ if (pdc) DC_UnlockDc(pdc);
- return SrcHeight;
+ return bResult;
}
UINT bpp,
DWORD init,
LPBYTE bits,
- PBITMAPV5INFO data,
+ PBITMAPINFO data,
DWORD coloruse)
{
HBITMAP handle;
else if ((coloruse != DIB_RGB_COLORS) || (init != CBM_INIT) || !data) fColor = FALSE;
else
{
- const RGBQUAD *rgb = data->bmiColors;
+ const RGBQUAD *rgb = (RGBQUAD*)((PBYTE)data + data->bmiHeader.biSize);
DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
// Check if the first color of the colormap is black
if (NULL != handle && CBM_INIT == init)
{
- IntSetDIBits(Dc, handle, 0, height, bits, (BITMAPINFO*)data, coloruse);
+ IntSetDIBits(Dc, handle, 0, height, bits, data, coloruse);
}
return handle;
IN FLONG fl,
IN HANDLE hcmXform)
{
- BITMAPV5INFO bmiLocal ;
NTSTATUS Status = STATUS_SUCCESS;
+ PBYTE safeBits = NULL;
+ HBITMAP hbmResult = NULL;
+
+ if(pjInit && (fInit == CBM_INIT))
+ {
+ safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
+ if(!safeBits)
+ {
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
+ }
_SEH2_TRY
{
- if(pbmi) Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, pbmi, iUsage, cjMaxInitInfo);
- if(pjInit && (fInit == CBM_INIT)) ProbeForRead(pjInit, cjMaxBits, 1);
+ if(pbmi) ProbeForRead(pbmi, cjMaxInitInfo, 1);
+ if(pjInit && (fInit == CBM_INIT))
+ {
+ ProbeForRead(pjInit, cjMaxBits, 1);
+ RtlCopyMemory(safeBits, pjInit, cjMaxBits);
+ }
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
- return NULL;
+ goto cleanup;
}
- return GreCreateDIBitmapInternal(hDc,
- cx,
- cy,
- fInit,
- pjInit,
- pbmi ? &bmiLocal : NULL,
- iUsage,
- fl,
- hcmXform);
+ hbmResult = GreCreateDIBitmapInternal(hDc,
+ cx,
+ cy,
+ fInit,
+ safeBits,
+ pbmi,
+ iUsage,
+ fl,
+ hcmXform);
+
+cleanup:
+ if (safeBits) ExFreePoolWithTag(safeBits, TAG_DIB);
+ return hbmResult;
}
HBITMAP
IN INT cy,
IN DWORD fInit,
IN OPTIONAL LPBYTE pjInit,
- IN OPTIONAL PBITMAPV5INFO pbmi,
+ IN OPTIONAL PBITMAPINFO pbmi,
IN DWORD iUsage,
IN FLONG fl,
IN HANDLE hcmXform)
HDC hdcDest;
if (!hDc) /* 1bpp monochrome bitmap */
- { // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
- hdcDest = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE);
+ {
+ // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
+ hdcDest = NtGdiCreateCompatibleDC(0);
if(!hdcDest)
{
return NULL;
Dc = DC_LockDc(hdcDest);
if (!Dc)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return NULL;
}
/* It's OK to set bpp=0 here, as IntCreateDIBitmap will create a compatible Bitmap
* if bpp != 1 and ignore the real value that was passed */
if (pbmi)
- bpp = pbmi->bmiHeader.bV5BitCount;
+ bpp = pbmi->bmiHeader.biBitCount;
else
bpp = 0;
Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
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,
}
else
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
}
if (bDesktopDC)
APIENTRY
DIB_CreateDIBSection(
PDC dc,
- BITMAPINFO *bmi,
+ CONST BITMAPINFO *bmi,
UINT usage,
LPVOID *bits,
HANDLE section,
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,
/* CreateDIBSection should fail for compressed formats */
if (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8)
{
+ DPRINT1("no compressed format allowed\n");
return (HBITMAP)NULL;
}
bm.bmType = 0;
bm.bmWidth = bi->biWidth;
bm.bmHeight = effHeight;
- bm.bmWidthBytes = ovr_pitch ? ovr_pitch : (ULONG) DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
+ bm.bmWidthBytes = ovr_pitch ? ovr_pitch : WIDTH_BYTES_ALIGN32(bm.bmWidth, bi->biBitCount);
bm.bmPlanes = bi->biPlanes;
bm.bmBitsPixel = bi->biBitCount;
// Get storage location for DIB bits. Only use biSizeImage if it's valid and
// we're dealing with a compressed bitmap. Otherwise, use width * height.
- totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
+ totalSize = bi->biSizeImage && bi->biCompression != BI_RGB && bi->biCompression != BI_BITFIELDS
? bi->biSizeImage : (ULONG)(bm.bmWidthBytes * effHeight);
if (section)
0);
if (!NT_SUCCESS(Status))
{
+ DPRINT1("ZwQuerySystemInformation failed (0x%lx)\n", Status);
return NULL;
}
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ DPRINT1("ZwMapViewOfSection failed (0x%lx)\n", Status);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
{
offset = 0;
bm.bmBits = EngAllocUserMem(totalSize, 0);
+ if(!bm.bmBits)
+ {
+ DPRINT1("Failed to allocate memory\n");
+ 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)
+ if(dc)
+ {
+ PPALETTE ppalDc;
+ ppalDc = PALETTE_ShareLockPalette(dc->dclevel.hpal);
+ hpal = DIB_MapPaletteColors(ppalDc, bmi);
+ PALETTE_ShareUnlockPalette(ppalDc);
+ }
+ else
{
- ColorCount = 1 << bi->biBitCount;
+ /* For DIB Brushes */
+ DPRINT1("FIXME : Unsupported DIB_PAL_COLORS without a DC to map colors.\n");
+ /* HACK */
+ hpal = (HPALETTE) 0xFFFFFFFF;
}
}
else
{
- lpRGB = bmi->bmiColors;
- ColorCount = 1 << bi->biBitCount;
+ hpal = BuildDIBPalette(bmi);
}
- /* Set dsBitfields values */
- if (usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
+ if(!hpal)
{
- 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];
+ DPRINT1("Error : Could not create a palette for the DIB.\n");
+ goto cleanup;
}
// Create Device Dependent Bitmap and add DIB pointer
bm.bmWidthBytes,
BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
- (bi->biHeight < 0 ? BMF_TOPDOWN : 0),
+ ((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;
+ DPRINT1("GreCreateBitmapEx failed\n");
+ EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
+ goto cleanup;
}
- bmp = SURFACE_LockSurface(res);
+ bmp = SURFACE_ShareLockSurface(res); // HACK
if (NULL == bmp)
{
- if (lpRGB != bmi->bmiColors)
- {
- ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
- }
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- GreDeleteObject(res);
- return NULL;
+ DPRINT1("SURFACE_LockSurface failed\n");
+ EngSetLastError(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;
+ bmp->SurfObj.fjBitmap &= ~BMF_DONT_FREE;
- if (bi->biClrUsed != 0)
- {
- hpal = PALETTE_AllocPaletteIndexedRGB(ColorCount, lpRGB);
- }
- else
+ /* HACK */
+ if(hpal != (HPALETTE)0xFFFFFFFF)
{
- 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);
}
- 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);
ZwUnmapViewOfSection(NtCurrentProcess(), mapBits);
bm.bmBits = NULL;
}
- else
- if (!offset)
- EngFreeUserMem(bm.bmBits), bm.bmBits = NULL;
+ else if (!offset)
+ EngFreeUserMem(bm.bmBits), bm.bmBits = NULL;
}
if (bmp)
if (res)
{
- SURFACE_FreeSurfaceByHandle(res);
+ GreDeleteObject(res);
res = 0;
}
}
- if (lpRGB != bmi->bmiColors)
- {
- ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
- }
-
if (bmp)
{
- SURFACE_UnlockSurface(bmp);
+ SURFACE_ShareUnlockSurface(bmp);
}
// Return BITMAP handle and storage location
}
/***********************************************************************
- * DIB_GetDIBWidthBytes
+ * DIB_GetBitmapInfo
*
- * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
- * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
- * 11/16/1999 (RJJ) lifted from wine
+ * Get the info from a bitmap header.
+ * Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error.
*/
-INT FASTCALL DIB_GetDIBWidthBytes(INT width, INT depth)
+int
+FASTCALL
+DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
+ LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size )
{
- return ((width * depth + 31) & ~31) >> 3;
+ if (header->biSize == sizeof(BITMAPCOREHEADER))
+ {
+ const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
+ *width = core->bcWidth;
+ *height = core->bcHeight;
+ *planes = core->bcPlanes;
+ *bpp = core->bcBitCount;
+ *compr = BI_RGB;
+ *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;
}
/***********************************************************************
INT APIENTRY DIB_GetDIBImageBytes(INT width, INT height, INT depth)
{
- return DIB_GetDIBWidthBytes(width, depth) * (height < 0 ? -height : height);
+ return WIDTH_BYTES_ALIGN32(width, depth) * (height < 0 ? -height : height);
}
/***********************************************************************
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);
+ HPALETTE hpal;
- if (NULL == palGDI)
+ if (!(ppal->flFlags & PAL_INDEXED))
{
return NULL;
}
- if (palGDI->Mode != PAL_INDEXED)
- {
- PALETTE_UnlockPalette(palGDI);
- return NULL;
- }
-
nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
if (lpbmi->bmiHeader.biClrUsed)
{
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);
- return lpRGB;
+ hpal = PALETTE_AllocPalette(PAL_INDEXED, nNumColors, (ULONG*)ppalEntries, 0, 0, 0);
+
+ ExFreePoolWithTag(ppalEntries, TAG_COLORMAP);
+
+ return hpal;
}
HPALETTE
FASTCALL
-BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType)
+BuildDIBPalette(CONST BITMAPINFO *bmi)
{
BYTE bits;
ULONG ColorCount;
HPALETTE hPal;
- ULONG RedMask, GreenMask, BlueMask;
+ ULONG RedMask = 0, GreenMask = 0, BlueMask = 0;
PDWORD pdwColors = (PDWORD)((PBYTE)bmi + bmi->bmiHeader.biSize);
+ INT paletteType;
// Determine Bits Per Pixel
bits = bmi->bmiHeader.biBitCount;
// 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;
- RedMask = pdwColors[0];
- GreenMask = pdwColors[1];
- BlueMask = pdwColors[2];
- }
- else if (bits == 15)
- {
- *paletteType = PAL_BITFIELDS;
- RedMask = 0x7c00;
- GreenMask = 0x03e0;
- BlueMask = 0x001f;
- }
- else if (bits == 16)
- {
- *paletteType = PAL_BITFIELDS;
- RedMask = 0xF800;
- GreenMask = 0x07e0;
- BlueMask = 0x001f;
+ paletteType = PAL_BITFIELDS;
+ if (bmi->bmiHeader.biSize >= sizeof(BITMAPV4HEADER))
+ {
+ PBITMAPV4HEADER pV4Header = (PBITMAPV4HEADER)&bmi->bmiHeader;
+ RedMask = pV4Header->bV4RedMask;
+ GreenMask = pV4Header->bV4GreenMask;
+ BlueMask = pV4Header->bV4BlueMask;
+ }
+ else
+ {
+ RedMask = pdwColors[0];
+ GreenMask = pdwColors[1];
+ BlueMask = pdwColors[2];
+ }
}
else
{
- *paletteType = PAL_BGR;
- RedMask = 0xff0000;
- GreenMask = 0x00ff00;
- BlueMask = 0x0000ff;
+ paletteType = PAL_BITFIELDS;
+ switch (bits)
+ {
+ case 16:
+ paletteType |= PAL_RGB16_555;
+ RedMask = 0x7C00;
+ GreenMask = 0x03E0;
+ BlueMask = 0x001F;
+ break;
+
+ case 24:
+ case 32:
+ paletteType |= PAL_BGR;
+ RedMask = 0xFF0000;
+ GreenMask = 0x00FF00;
+ BlueMask = 0x0000FF;
+ break;
+ }
}
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)
-{
- 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
+/* Converts a BITMAPCOREINFO to a BITMAPINFO structure,
+ * or does nothing if it's already a BITMAPINFO (or V4 or V5) */
+BITMAPINFO*
FASTCALL
-ProbeAndConvertToBitmapV5Info(
- OUT PBITMAPV5INFO pbmiDst,
- IN CONST BITMAPINFO* pbmiUnsafe,
- IN DWORD dwColorUse,
- IN UINT MaxSize)
+DIB_ConvertBitmapInfo (CONST BITMAPINFO* pbmi, DWORD Usage)
{
- 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);
-
- /* 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);
+ 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 (dwSize < sizeof(BITMAPV4HEADER))
+ if(pbmci->bmciHeader.bcBitCount <= 8)
{
- if (pbmhDst->bV5Compression == BI_BITFIELDS)
+ numColors = 1 << pbmci->bmciHeader.bcBitCount;
+ if(Usage == DIB_PAL_COLORS)
{
- pbmhDst->bV5RedMask = GetBMIColor(pbmiUnsafe, 0);
- pbmhDst->bV5GreenMask = GetBMIColor(pbmiUnsafe, 1);
- pbmhDst->bV5BlueMask = GetBMIColor(pbmiUnsafe, 2);
- pbmhDst->bV5AlphaMask = 0;
- pbmhDst->bV5ClrUsed = 0;
+ ColorsSize = numColors * sizeof(WORD);
}
-
-// 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)
+ else
{
- case 1:
- pbmhDst->bV5ClrUsed = 2;
- break;
- case 4:
- pbmhDst->bV5ClrUsed = 16;
- break;
- case 8:
- pbmhDst->bV5ClrUsed = 256;
- break;
- default:
- pbmhDst->bV5ClrUsed = 0;
- break;
+ ColorsSize = numColors * sizeof(RGBQUAD);
}
}
-
- if (pbmhDst->bV5Planes != 1)
+ else if (Usage == DIB_PAL_COLORS)
{
- return STATUS_INVALID_PARAMETER;
+ /* Invalid at high Res */
+ return NULL;
}
- 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;
- }
+ pNewBmi = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + ColorsSize, TAG_DIB);
+ if(!pNewBmi) return NULL;
- 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;
- }
+ 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 (pbmhDst->bV5Compression == BI_BITFIELDS &&
- pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 32)
+ if(Usage == DIB_PAL_COLORS)
{
- DPRINT("Bit count %d is invalid for compression BI_BITFIELDS.\n", pbmhDst->bV5BitCount);
- return STATUS_INVALID_PARAMETER;
+ RtlCopyMemory(pNewBmi->bmiColors, pbmci->bmciColors, ColorsSize);
}
-
- /* Copy Colors */
- if(pbmhDst->bV5ClrUsed)
+ else
{
- INT i;
- if(dwColorUse == DIB_PAL_COLORS)
- {
- RtlCopyMemory(pbmiDst->bmiColors,
- pbmiUnsafe->bmiColors,
- pbmhDst->bV5ClrUsed * sizeof(WORD));
- }
- else
+ UINT i;
+ for(i=0; i<numColors; i++)
{
- for(i = 0; i < pbmhDst->bV5ClrUsed; i++)
- {
- ((DWORD*)pbmiDst->bmiColors)[i] = GetBMIColor(pbmiUnsafe, 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 STATUS_SUCCESS;
+ return pNewBmi ;
}
+/* Frees a BITMAPINFO created with DIB_ConvertBitmapInfo */
VOID
FASTCALL
-GetBMIFromBitmapV5Info(IN PBITMAPV5INFO pbmiSrc,
- OUT PBITMAPINFO pbmiDst,
- IN DWORD dwColorUse)
+DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig)
{
- 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;
+ if(converted != orig)
+ ExFreePoolWithTag(converted, TAG_DIB);
+}
+
+
+
- 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 */