2003-05-18 17:16:18 +00:00
|
|
|
/*
|
2011-09-20 19:41:33 +00:00
|
|
|
* PROJECT: ReactOS win32 kernel mode subsystem
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
2015-11-10 17:41:55 +00:00
|
|
|
* FILE: win32ss/gdi/ntgdi/dibobj.c
|
2011-09-20 19:41:33 +00:00
|
|
|
* PURPOSE: Dib object functions
|
|
|
|
* PROGRAMMER:
|
2003-05-18 17:16:18 +00:00
|
|
|
*/
|
2005-06-29 07:09:25 +00:00
|
|
|
|
2010-04-26 13:58:46 +00:00
|
|
|
#include <win32k.h>
|
2005-06-29 07:09:25 +00:00
|
|
|
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
2003-03-06 00:56:59 +00:00
|
|
|
|
2011-02-28 23:46:02 +00:00
|
|
|
static const RGBQUAD DefLogPaletteQuads[20] = /* Copy of Default Logical Palette */
|
|
|
|
{
|
|
|
|
/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
|
2008-12-01 00:13:45 +00:00
|
|
|
{ 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
{ 0x00, 0x00, 0x80, 0x00 },
|
|
|
|
{ 0x00, 0x80, 0x00, 0x00 },
|
|
|
|
{ 0x00, 0x80, 0x80, 0x00 },
|
|
|
|
{ 0x80, 0x00, 0x00, 0x00 },
|
|
|
|
{ 0x80, 0x00, 0x80, 0x00 },
|
|
|
|
{ 0x80, 0x80, 0x00, 0x00 },
|
|
|
|
{ 0xc0, 0xc0, 0xc0, 0x00 },
|
|
|
|
{ 0xc0, 0xdc, 0xc0, 0x00 },
|
|
|
|
{ 0xf0, 0xca, 0xa6, 0x00 },
|
|
|
|
{ 0xf0, 0xfb, 0xff, 0x00 },
|
|
|
|
{ 0xa4, 0xa0, 0xa0, 0x00 },
|
|
|
|
{ 0x80, 0x80, 0x80, 0x00 },
|
2016-10-26 10:21:46 +00:00
|
|
|
{ 0x00, 0x00, 0xff, 0x00 },
|
2008-12-01 00:13:45 +00:00
|
|
|
{ 0x00, 0xff, 0x00, 0x00 },
|
|
|
|
{ 0x00, 0xff, 0xff, 0x00 },
|
|
|
|
{ 0xff, 0x00, 0x00, 0x00 },
|
|
|
|
{ 0xff, 0x00, 0xff, 0x00 },
|
|
|
|
{ 0xff, 0xff, 0x00, 0x00 },
|
|
|
|
{ 0xff, 0xff, 0xff, 0x00 }
|
|
|
|
};
|
|
|
|
|
2012-05-05 21:39:35 +00:00
|
|
|
PPALETTE
|
|
|
|
NTAPI
|
|
|
|
CreateDIBPalette(
|
|
|
|
_In_ const BITMAPINFO *pbmi,
|
|
|
|
_In_ PDC pdc,
|
|
|
|
_In_ ULONG iUsage)
|
|
|
|
{
|
|
|
|
PPALETTE ppal;
|
2012-05-09 08:13:49 +00:00
|
|
|
ULONG i, cBitsPixel, cColors;
|
|
|
|
|
|
|
|
if (pbmi->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
|
|
|
|
{
|
|
|
|
PBITMAPCOREINFO pbci = (PBITMAPCOREINFO)pbmi;
|
|
|
|
cBitsPixel = pbci->bmciHeader.bcBitCount;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cBitsPixel = pbmi->bmiHeader.biBitCount;
|
|
|
|
}
|
2012-05-05 21:39:35 +00:00
|
|
|
|
|
|
|
/* Check if the colors are indexed */
|
2012-05-09 08:13:49 +00:00
|
|
|
if (cBitsPixel <= 8)
|
2012-05-05 21:39:35 +00:00
|
|
|
{
|
|
|
|
/* We create a "full" palette */
|
2012-05-09 08:13:49 +00:00
|
|
|
cColors = 1 << cBitsPixel;
|
2012-05-05 21:39:35 +00:00
|
|
|
|
|
|
|
/* Allocate the palette */
|
|
|
|
ppal = PALETTE_AllocPalette(PAL_INDEXED,
|
|
|
|
cColors,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
|
|
|
|
/* Check if the BITMAPINFO specifies how many colors to use */
|
2012-05-09 08:13:49 +00:00
|
|
|
if ((pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
|
|
|
|
(pbmi->bmiHeader.biClrUsed != 0))
|
2012-05-05 21:39:35 +00:00
|
|
|
{
|
|
|
|
/* This is how many colors we can actually process */
|
|
|
|
cColors = min(cColors, pbmi->bmiHeader.biClrUsed);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check how to use the colors */
|
|
|
|
if (iUsage == DIB_PAL_COLORS)
|
|
|
|
{
|
|
|
|
COLORREF crColor;
|
|
|
|
|
|
|
|
/* The colors are an array of WORD indices into the DC palette */
|
|
|
|
PWORD pwColors = (PWORD)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
|
|
|
|
|
|
|
|
/* Use the DCs palette or, if no DC is given, the default one */
|
|
|
|
PPALETTE ppalDC = pdc ? pdc->dclevel.ppal : gppalDefault;
|
|
|
|
|
|
|
|
/* Loop all color indices in the DIB */
|
|
|
|
for (i = 0; i < cColors; i++)
|
|
|
|
{
|
2012-05-05 22:50:47 +00:00
|
|
|
/* Get the palette index and handle wraparound when exceeding
|
|
|
|
the number of colors in the DC palette */
|
|
|
|
WORD wIndex = pwColors[i] % ppalDC->NumColors;
|
|
|
|
|
|
|
|
/* USe the RGB value from the DC palette */
|
|
|
|
crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, wIndex);
|
2012-05-05 21:39:35 +00:00
|
|
|
PALETTE_vSetRGBColorForIndex(ppal, i, crColor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (iUsage == DIB_PAL_BRUSHHACK)
|
|
|
|
{
|
|
|
|
/* The colors are an array of WORD indices into the DC palette */
|
|
|
|
PWORD pwColors = (PWORD)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
|
|
|
|
|
|
|
|
/* Loop all color indices in the DIB */
|
|
|
|
for (i = 0; i < cColors; i++)
|
|
|
|
{
|
|
|
|
/* Set the index directly as the RGB color, the real palette
|
|
|
|
containing RGB values will be calculated when the brush is
|
|
|
|
realized */
|
|
|
|
PALETTE_vSetRGBColorForIndex(ppal, i, pwColors[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Mark the palette as a brush hack palette */
|
|
|
|
ppal->flFlags |= PAL_BRUSHHACK;
|
|
|
|
}
|
2012-05-05 22:06:15 +00:00
|
|
|
// else if (iUsage == 2)
|
|
|
|
// {
|
2012-05-05 21:39:35 +00:00
|
|
|
// FIXME: this one is undocumented
|
2012-05-05 22:06:15 +00:00
|
|
|
// ASSERT(FALSE);
|
|
|
|
// }
|
2012-05-09 08:13:49 +00:00
|
|
|
else if (pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
|
2012-05-05 21:39:35 +00:00
|
|
|
{
|
|
|
|
/* The colors are an array of RGBQUAD values */
|
|
|
|
RGBQUAD *prgb = (RGBQUAD*)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
|
2021-06-23 19:37:53 +00:00
|
|
|
RGBQUAD colors[256] = {{0}};
|
2012-05-05 21:39:35 +00:00
|
|
|
|
|
|
|
// FIXME: do we need to handle PALETTEINDEX / PALETTERGB macro?
|
|
|
|
|
2021-06-23 17:59:42 +00:00
|
|
|
/* Use SEH to verify we can READ prgb[] succesfully */
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
RtlCopyMemory(colors, prgb, cColors * sizeof(colors[0]));
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
/* Do Nothing */
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
|
|
|
|
|
|
|
for (i = 0; i < cColors; ++i)
|
2012-05-05 21:39:35 +00:00
|
|
|
{
|
2021-06-23 17:59:42 +00:00
|
|
|
/* Get the color value and translate it to a COLORREF */
|
|
|
|
COLORREF crColor = RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue);
|
|
|
|
|
|
|
|
/* Set the RGB value in the palette */
|
|
|
|
PALETTE_vSetRGBColorForIndex(ppal, i, crColor);
|
|
|
|
|
2012-05-09 08:13:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* The colors are an array of RGBTRIPLE values */
|
|
|
|
RGBTRIPLE *prgb = (RGBTRIPLE*)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
|
|
|
|
|
|
|
|
/* Loop all color indices in the DIB */
|
|
|
|
for (i = 0; i < cColors; i++)
|
|
|
|
{
|
|
|
|
/* Get the color value and translate it to a COLORREF */
|
|
|
|
RGBTRIPLE rgb = prgb[i];
|
|
|
|
COLORREF crColor = RGB(rgb.rgbtRed, rgb.rgbtGreen, rgb.rgbtBlue);
|
|
|
|
|
2012-05-05 21:39:35 +00:00
|
|
|
/* Set the RGB value in the palette */
|
|
|
|
PALETTE_vSetRGBColorForIndex(ppal, i, crColor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* This is a bitfield / RGB palette */
|
|
|
|
ULONG flRedMask, flGreenMask, flBlueMask;
|
|
|
|
|
|
|
|
/* Check if the DIB contains bitfield values */
|
2012-05-09 08:13:49 +00:00
|
|
|
if ((pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
|
|
|
|
(pbmi->bmiHeader.biCompression == BI_BITFIELDS))
|
2012-05-05 21:39:35 +00:00
|
|
|
{
|
|
|
|
/* Check if we have a v4/v5 header */
|
|
|
|
if (pbmi->bmiHeader.biSize >= sizeof(BITMAPV4HEADER))
|
|
|
|
{
|
|
|
|
/* The masks are dedicated fields in the header */
|
|
|
|
PBITMAPV4HEADER pbmV4Header = (PBITMAPV4HEADER)&pbmi->bmiHeader;
|
|
|
|
flRedMask = pbmV4Header->bV4RedMask;
|
|
|
|
flGreenMask = pbmV4Header->bV4GreenMask;
|
|
|
|
flBlueMask = pbmV4Header->bV4BlueMask;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* The masks are the first 3 values in the DIB color table */
|
|
|
|
PDWORD pdwColors = (PVOID)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
|
|
|
|
flRedMask = pdwColors[0];
|
|
|
|
flGreenMask = pdwColors[1];
|
|
|
|
flBlueMask = pdwColors[2];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Check what bit depth we have. Note: optimization flags are
|
|
|
|
calculated in PALETTE_AllocPalette() */
|
2012-05-09 08:13:49 +00:00
|
|
|
if (cBitsPixel == 16)
|
2012-05-05 21:39:35 +00:00
|
|
|
{
|
|
|
|
/* This is an RGB 555 palette */
|
|
|
|
flRedMask = 0x7C00;
|
|
|
|
flGreenMask = 0x03E0;
|
|
|
|
flBlueMask = 0x001F;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* This is an RGB 888 palette */
|
|
|
|
flRedMask = 0xFF0000;
|
|
|
|
flGreenMask = 0x00FF00;
|
|
|
|
flBlueMask = 0x0000FF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate the bitfield palette */
|
|
|
|
ppal = PALETTE_AllocPalette(PAL_BITFIELDS,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
flRedMask,
|
|
|
|
flGreenMask,
|
|
|
|
flBlueMask);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We're done, return the palette */
|
|
|
|
return ppal;
|
|
|
|
}
|
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
// Converts a DIB to a device-dependent bitmap
|
2009-06-10 00:23:15 +00:00
|
|
|
static INT
|
|
|
|
FASTCALL
|
2004-03-15 22:06:55 +00:00
|
|
|
IntSetDIBits(
|
2009-06-10 00:23:15 +00:00
|
|
|
PDC DC,
|
|
|
|
HBITMAP hBitmap,
|
|
|
|
UINT StartScan,
|
|
|
|
UINT ScanLines,
|
|
|
|
CONST VOID *Bits,
|
2015-12-23 14:55:34 +00:00
|
|
|
ULONG cjMaxBits,
|
2010-08-01 12:17:35 +00:00
|
|
|
CONST BITMAPINFO *bmi,
|
2009-06-10 00:23:15 +00:00
|
|
|
UINT ColorUse)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2010-08-02 19:40:42 +00:00
|
|
|
HBITMAP SourceBitmap;
|
2011-02-28 23:46:02 +00:00
|
|
|
PSURFACE psurfDst, psurfSrc;
|
2009-06-10 00:23:15 +00:00
|
|
|
INT result = 0;
|
2011-02-28 23:46:02 +00:00
|
|
|
RECT rcDst;
|
|
|
|
POINTL ptSrc;
|
|
|
|
EXLATEOBJ exlo;
|
2011-10-06 13:38:45 +00:00
|
|
|
PPALETTE ppalDIB = 0;
|
2015-12-29 20:28:23 +00:00
|
|
|
ULONG cjSizeImage;
|
2011-10-06 13:38:45 +00:00
|
|
|
|
2016-01-03 16:16:04 +00:00
|
|
|
if (!bmi || !Bits) return 0;
|
2012-05-08 16:21:27 +00:00
|
|
|
|
2016-01-03 16:16:04 +00:00
|
|
|
/* Check for uncompressed formats */
|
|
|
|
if ((bmi->bmiHeader.biCompression == BI_RGB) ||
|
2015-12-29 20:28:23 +00:00
|
|
|
(bmi->bmiHeader.biCompression == BI_BITFIELDS))
|
|
|
|
{
|
|
|
|
/* Calculate the image size */
|
|
|
|
cjSizeImage = DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
|
|
|
|
ScanLines,
|
|
|
|
bmi->bmiHeader.biBitCount);
|
2016-01-03 16:16:04 +00:00
|
|
|
}
|
|
|
|
/* Check if the header provided an image size */
|
|
|
|
else if (bmi->bmiHeader.biSizeImage != 0)
|
|
|
|
{
|
|
|
|
/* Use the given size */
|
|
|
|
cjSizeImage = bmi->bmiHeader.biSizeImage;
|
2015-12-29 20:28:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Compressed format without a size. This is invalid. */
|
|
|
|
DPRINT1("Compressed format without a size!");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if the size that we have is ok */
|
2016-01-03 19:46:57 +00:00
|
|
|
if ((cjSizeImage > cjMaxBits) || (cjSizeImage == 0))
|
2015-12-29 20:28:23 +00:00
|
|
|
{
|
2016-01-03 19:46:57 +00:00
|
|
|
DPRINT1("Invalid bitmap size! cjSizeImage = %lu, cjMaxBits = %lu\n",
|
2015-12-29 20:28:23 +00:00
|
|
|
cjSizeImage, cjMaxBits);
|
2015-12-23 14:55:34 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-10-06 13:38:45 +00:00
|
|
|
SourceBitmap = GreCreateBitmapEx(bmi->bmiHeader.biWidth,
|
|
|
|
ScanLines,
|
|
|
|
0,
|
|
|
|
BitmapFormat(bmi->bmiHeader.biBitCount,
|
|
|
|
bmi->bmiHeader.biCompression),
|
|
|
|
bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
|
2015-12-29 20:28:23 +00:00
|
|
|
cjSizeImage,
|
2016-01-03 19:46:57 +00:00
|
|
|
(PVOID)Bits,
|
2011-10-06 13:38:45 +00:00
|
|
|
0);
|
|
|
|
if (!SourceBitmap)
|
2009-06-10 00:23:15 +00:00
|
|
|
{
|
2011-10-06 13:38:45 +00:00
|
|
|
DPRINT1("Error: Could not create a bitmap.\n");
|
2010-12-25 11:01:14 +00:00
|
|
|
EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
|
2009-06-10 00:23:15 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-04-18 19:09:05 +00:00
|
|
|
psurfDst = SURFACE_ShareLockSurface(hBitmap);
|
|
|
|
psurfSrc = SURFACE_ShareLockSurface(SourceBitmap);
|
2009-06-10 00:23:15 +00:00
|
|
|
|
2011-02-28 23:46:02 +00:00
|
|
|
if(!(psurfSrc && psurfDst))
|
|
|
|
{
|
2011-12-14 04:07:06 +00:00
|
|
|
DPRINT1("Error: Could not lock surfaces\n");
|
2011-02-28 23:46:02 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
|
2011-10-06 13:38:45 +00:00
|
|
|
/* Create a palette for the DIB */
|
2012-05-05 21:39:35 +00:00
|
|
|
ppalDIB = CreateDIBPalette(bmi, DC, ColorUse);
|
2011-10-06 13:38:45 +00:00
|
|
|
if (!ppalDIB)
|
|
|
|
{
|
2012-05-05 21:39:35 +00:00
|
|
|
EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
|
2011-10-06 13:38:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize EXLATEOBJ */
|
|
|
|
EXLATEOBJ_vInitialize(&exlo,
|
|
|
|
ppalDIB,
|
|
|
|
psurfDst->ppal,
|
|
|
|
RGB(0xff, 0xff, 0xff),
|
|
|
|
RGB(0xff, 0xff, 0xff), //DC->pdcattr->crBackgroundClr,
|
|
|
|
0); // DC->pdcattr->crForegroundClr);
|
|
|
|
|
2011-03-09 15:46:13 +00:00
|
|
|
rcDst.top = StartScan;
|
2011-02-28 23:46:02 +00:00
|
|
|
rcDst.left = 0;
|
|
|
|
rcDst.bottom = rcDst.top + ScanLines;
|
|
|
|
rcDst.right = psurfDst->SurfObj.sizlBitmap.cx;
|
|
|
|
ptSrc.x = 0;
|
|
|
|
ptSrc.y = 0;
|
2002-09-17 23:20:44 +00:00
|
|
|
|
2011-02-28 23:46:02 +00:00
|
|
|
result = IntEngCopyBits(&psurfDst->SurfObj,
|
|
|
|
&psurfSrc->SurfObj,
|
|
|
|
NULL,
|
|
|
|
&exlo.xlo,
|
|
|
|
&rcDst,
|
|
|
|
&ptSrc);
|
|
|
|
if(result)
|
|
|
|
result = ScanLines;
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2011-02-28 23:46:02 +00:00
|
|
|
EXLATEOBJ_vCleanup(&exlo);
|
2010-08-02 19:40:42 +00:00
|
|
|
|
2010-08-01 12:17:35 +00:00
|
|
|
cleanup:
|
2011-10-06 13:38:45 +00:00
|
|
|
if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
|
|
|
|
if(psurfSrc) SURFACE_ShareUnlockSurface(psurfSrc);
|
|
|
|
if(psurfDst) SURFACE_ShareUnlockSurface(psurfDst);
|
2011-02-28 23:46:02 +00:00
|
|
|
GreDeleteObject(SourceBitmap);
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
return result;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2014-08-23 14:20:16 +00:00
|
|
|
static
|
|
|
|
HBITMAP
|
|
|
|
IntGdiCreateMaskFromRLE(
|
|
|
|
DWORD Width,
|
|
|
|
DWORD Height,
|
|
|
|
ULONG Compression,
|
|
|
|
const BYTE* Bits,
|
|
|
|
DWORD BitsSize)
|
|
|
|
{
|
|
|
|
HBITMAP Mask;
|
|
|
|
DWORD x, y;
|
|
|
|
SURFOBJ* SurfObj;
|
|
|
|
UINT i = 0;
|
|
|
|
BYTE Data, NumPixels, ToSkip;
|
|
|
|
|
|
|
|
ASSERT((Compression == BI_RLE8) || (Compression == BI_RLE4));
|
|
|
|
|
|
|
|
/* Create the bitmap */
|
|
|
|
Mask = GreCreateBitmapEx(Width, Height, 0, BMF_1BPP, 0, 0, NULL, 0);
|
|
|
|
if (!Mask)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
SurfObj = EngLockSurface((HSURF)Mask);
|
|
|
|
if (!SurfObj)
|
|
|
|
{
|
|
|
|
GreDeleteObject(Mask);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
ASSERT(SurfObj->pvBits != NULL);
|
|
|
|
|
|
|
|
x = y = 0;
|
|
|
|
|
|
|
|
while (i < BitsSize)
|
|
|
|
{
|
|
|
|
NumPixels = Bits[i];
|
|
|
|
Data = Bits[i + 1];
|
|
|
|
i += 2;
|
|
|
|
|
|
|
|
if (NumPixels != 0)
|
|
|
|
{
|
|
|
|
if ((x + NumPixels) > Width)
|
|
|
|
NumPixels = Width - x;
|
|
|
|
|
|
|
|
if (NumPixels == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
DIB_1BPP_HLine(SurfObj, x, x + NumPixels, y, 1);
|
|
|
|
x += NumPixels;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Data < 3)
|
|
|
|
{
|
|
|
|
switch (Data)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
/* End of line */
|
|
|
|
y++;
|
|
|
|
if (y == Height)
|
|
|
|
goto done;
|
|
|
|
x = 0;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
/* End of file */
|
|
|
|
goto done;
|
|
|
|
case 2:
|
|
|
|
/* Jump */
|
|
|
|
if (i >= (BitsSize - 1))
|
|
|
|
goto done;
|
|
|
|
x += Bits[i];
|
|
|
|
if (x > Width)
|
|
|
|
x = Width;
|
|
|
|
y += Bits[i + 1];
|
|
|
|
if (y >= Height)
|
|
|
|
goto done;
|
|
|
|
i += 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* Done for this run */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Embedded data into the RLE */
|
|
|
|
NumPixels = Data;
|
|
|
|
if (Compression == BI_RLE8)
|
|
|
|
ToSkip = NumPixels;
|
|
|
|
else
|
|
|
|
ToSkip = (NumPixels / 2) + (NumPixels & 1);
|
|
|
|
|
|
|
|
if ((i + ToSkip) > BitsSize)
|
|
|
|
goto done;
|
|
|
|
ToSkip = (ToSkip + 1) & ~1;
|
|
|
|
|
|
|
|
if ((x + NumPixels) > Width)
|
|
|
|
NumPixels = Width - x;
|
|
|
|
|
|
|
|
if (NumPixels != 0)
|
|
|
|
{
|
|
|
|
DIB_1BPP_HLine(SurfObj, x, x + NumPixels, y, 1);
|
|
|
|
x += NumPixels;
|
|
|
|
}
|
|
|
|
i += ToSkip;
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
EngUnlockSurface(SurfObj);
|
|
|
|
return Mask;
|
|
|
|
}
|
|
|
|
|
2007-08-19 23:49:47 +00:00
|
|
|
W32KAPI
|
|
|
|
INT
|
|
|
|
APIENTRY
|
|
|
|
NtGdiSetDIBitsToDeviceInternal(
|
|
|
|
IN HDC hDC,
|
|
|
|
IN INT XDest,
|
|
|
|
IN INT YDest,
|
|
|
|
IN DWORD Width,
|
|
|
|
IN DWORD Height,
|
|
|
|
IN INT XSrc,
|
|
|
|
IN INT YSrc,
|
|
|
|
IN DWORD StartScan,
|
|
|
|
IN DWORD ScanLines,
|
|
|
|
IN LPBYTE Bits,
|
|
|
|
IN LPBITMAPINFO bmi,
|
|
|
|
IN DWORD ColorUse,
|
|
|
|
IN UINT cjMaxBits,
|
|
|
|
IN UINT cjMaxInfo,
|
|
|
|
IN BOOL bTransformCoordinates,
|
2009-06-10 00:23:15 +00:00
|
|
|
IN OPTIONAL HANDLE hcmXform)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2017-08-15 18:13:14 +00:00
|
|
|
INT ret;
|
2015-03-08 22:44:36 +00:00
|
|
|
PDC pDC = NULL;
|
2014-08-23 14:20:16 +00:00
|
|
|
HBITMAP hSourceBitmap = NULL, hMaskBitmap = NULL;
|
|
|
|
SURFOBJ *pDestSurf, *pSourceSurf = NULL, *pMaskSurf = NULL;
|
2009-04-02 17:25:56 +00:00
|
|
|
SURFACE *pSurf;
|
2007-09-27 17:04:29 +00:00
|
|
|
RECTL rcDest;
|
|
|
|
POINTL ptSource;
|
2011-09-11 16:56:56 +00:00
|
|
|
//INT DIBWidth;
|
2007-09-27 17:04:29 +00:00
|
|
|
SIZEL SourceSize;
|
2009-08-04 20:37:10 +00:00
|
|
|
EXLATEOBJ exlo;
|
2010-06-08 00:40:42 +00:00
|
|
|
PPALETTE ppalDIB = NULL;
|
2011-10-18 13:13:37 +00:00
|
|
|
LPBITMAPINFO pbmiSafe;
|
2017-08-15 18:13:14 +00:00
|
|
|
BOOL bResult;
|
2007-09-27 17:04:29 +00:00
|
|
|
|
2007-12-08 18:32:22 +00:00
|
|
|
if (!Bits) return 0;
|
|
|
|
|
2011-10-18 13:13:37 +00:00
|
|
|
pbmiSafe = ExAllocatePoolWithTag(PagedPool, cjMaxInfo, 'pmTG');
|
|
|
|
if (!pbmiSafe) return 0;
|
|
|
|
|
2008-12-01 00:13:45 +00:00
|
|
|
_SEH2_TRY
|
|
|
|
{
|
2010-08-01 12:17:35 +00:00
|
|
|
ProbeForRead(bmi, cjMaxInfo, 1);
|
2010-06-09 00:08:50 +00:00
|
|
|
ProbeForRead(Bits, cjMaxBits, 1);
|
2011-10-18 13:13:37 +00:00
|
|
|
RtlCopyMemory(pbmiSafe, bmi, cjMaxInfo);
|
|
|
|
bmi = pbmiSafe;
|
2008-12-01 00:13:45 +00:00
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
2017-08-15 18:13:14 +00:00
|
|
|
ret = 0;
|
2015-03-08 22:44:36 +00:00
|
|
|
goto Exit;
|
2008-12-01 00:13:45 +00:00
|
|
|
}
|
2021-07-02 22:34:43 +00:00
|
|
|
_SEH2_END;
|
2008-12-01 00:13:45 +00:00
|
|
|
|
2012-08-02 10:06:08 +00:00
|
|
|
ScanLines = min(ScanLines, abs(bmi->bmiHeader.biHeight) - StartScan);
|
2015-03-08 22:44:36 +00:00
|
|
|
if (ScanLines == 0)
|
|
|
|
{
|
|
|
|
DPRINT1("ScanLines == 0\n");
|
2017-08-15 18:13:14 +00:00
|
|
|
ret = 0;
|
2015-03-08 22:44:36 +00:00
|
|
|
goto Exit;
|
|
|
|
}
|
2012-08-02 10:06:08 +00:00
|
|
|
|
2007-09-27 17:04:29 +00:00
|
|
|
pDC = DC_LockDc(hDC);
|
|
|
|
if (!pDC)
|
|
|
|
{
|
2010-12-25 11:01:14 +00:00
|
|
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
2017-08-15 18:13:14 +00:00
|
|
|
ret = 0;
|
2015-03-08 22:44:36 +00:00
|
|
|
goto Exit;
|
2007-09-27 17:04:29 +00:00
|
|
|
}
|
2012-07-31 20:44:56 +00:00
|
|
|
|
2012-08-02 10:06:08 +00:00
|
|
|
if (pDC->dctype == DC_TYPE_INFO)
|
|
|
|
{
|
2017-08-15 18:13:14 +00:00
|
|
|
ret = 0;
|
2012-08-22 20:11:41 +00:00
|
|
|
goto Exit;
|
2007-09-27 17:04:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
rcDest.left = XDest;
|
|
|
|
rcDest.top = YDest;
|
2008-06-05 22:23:19 +00:00
|
|
|
if (bTransformCoordinates)
|
|
|
|
{
|
2011-03-07 10:00:27 +00:00
|
|
|
IntLPtoDP(pDC, (LPPOINT)&rcDest, 2);
|
2008-06-05 22:23:19 +00:00
|
|
|
}
|
|
|
|
rcDest.left += pDC->ptlDCOrig.x;
|
|
|
|
rcDest.top += pDC->ptlDCOrig.y;
|
|
|
|
rcDest.right = rcDest.left + Width;
|
|
|
|
rcDest.bottom = rcDest.top + Height;
|
2009-12-23 17:41:20 +00:00
|
|
|
rcDest.top += StartScan;
|
|
|
|
|
2016-12-22 17:34:58 +00:00
|
|
|
if (pDC->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR))
|
|
|
|
{
|
|
|
|
IntUpdateBoundsRect(pDC, &rcDest);
|
|
|
|
}
|
|
|
|
|
2007-09-27 17:04:29 +00:00
|
|
|
ptSource.x = XSrc;
|
|
|
|
ptSource.y = YSrc;
|
|
|
|
|
2010-08-01 12:17:35 +00:00
|
|
|
SourceSize.cx = bmi->bmiHeader.biWidth;
|
2009-12-23 17:41:20 +00:00
|
|
|
SourceSize.cy = ScanLines;
|
2012-09-30 20:30:23 +00:00
|
|
|
|
2011-09-11 16:56:56 +00:00
|
|
|
//DIBWidth = WIDTH_BYTES_ALIGN32(SourceSize.cx, bmi->bmiHeader.biBitCount);
|
2008-05-06 20:44:25 +00:00
|
|
|
|
2011-03-07 10:00:27 +00:00
|
|
|
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);
|
|
|
|
|
2008-12-01 00:13:45 +00:00
|
|
|
if (!hSourceBitmap)
|
|
|
|
{
|
2010-12-25 11:01:14 +00:00
|
|
|
EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
|
2017-08-15 18:13:14 +00:00
|
|
|
ret = 0;
|
2008-12-01 00:13:45 +00:00
|
|
|
goto Exit;
|
|
|
|
}
|
2008-05-06 20:44:25 +00:00
|
|
|
|
2008-12-01 00:13:45 +00:00
|
|
|
pSourceSurf = EngLockSurface((HSURF)hSourceBitmap);
|
|
|
|
if (!pSourceSurf)
|
|
|
|
{
|
2017-08-15 18:13:14 +00:00
|
|
|
ret = 0;
|
2009-06-10 00:23:15 +00:00
|
|
|
goto Exit;
|
2008-12-01 00:13:45 +00:00
|
|
|
}
|
2008-04-19 00:24:34 +00:00
|
|
|
|
2014-08-23 14:20:16 +00:00
|
|
|
/* HACK: If this is a RLE bitmap, only the relevant pixels must be set. */
|
|
|
|
if ((bmi->bmiHeader.biCompression == BI_RLE8) || (bmi->bmiHeader.biCompression == BI_RLE4))
|
|
|
|
{
|
|
|
|
hMaskBitmap = IntGdiCreateMaskFromRLE(bmi->bmiHeader.biWidth,
|
|
|
|
ScanLines,
|
|
|
|
bmi->bmiHeader.biCompression,
|
|
|
|
Bits,
|
|
|
|
cjMaxBits);
|
|
|
|
if (!hMaskBitmap)
|
|
|
|
{
|
|
|
|
EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
|
2017-08-15 18:13:14 +00:00
|
|
|
ret = 0;
|
2014-08-23 14:20:16 +00:00
|
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
pMaskSurf = EngLockSurface((HSURF)hMaskBitmap);
|
|
|
|
if (!pMaskSurf)
|
|
|
|
{
|
2017-08-15 18:13:14 +00:00
|
|
|
ret = 0;
|
2014-08-23 14:20:16 +00:00
|
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-30 14:02:42 +00:00
|
|
|
/* Create a palette for the DIB */
|
2012-05-05 21:39:35 +00:00
|
|
|
ppalDIB = CreateDIBPalette(bmi, pDC, ColorUse);
|
|
|
|
if (!ppalDIB)
|
2008-12-01 00:13:45 +00:00
|
|
|
{
|
2010-12-25 11:01:14 +00:00
|
|
|
EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
|
2017-08-15 18:13:14 +00:00
|
|
|
ret = 0;
|
2009-06-10 00:23:15 +00:00
|
|
|
goto Exit;
|
2007-09-27 17:04:29 +00:00
|
|
|
}
|
2012-09-30 20:30:23 +00:00
|
|
|
|
2012-08-22 20:11:41 +00:00
|
|
|
/* This is actually a blit */
|
2014-07-23 16:05:47 +00:00
|
|
|
DC_vPrepareDCsForBlit(pDC, &rcDest, NULL, NULL);
|
2012-08-22 20:11:41 +00:00
|
|
|
pSurf = pDC->dclevel.pSurface;
|
|
|
|
if (!pSurf)
|
|
|
|
{
|
|
|
|
DC_vFinishBlit(pDC, NULL);
|
|
|
|
ret = ScanLines;
|
|
|
|
goto Exit;
|
|
|
|
}
|
2012-09-30 20:30:23 +00:00
|
|
|
|
2012-08-22 20:11:41 +00:00
|
|
|
ASSERT(pSurf->ppal);
|
2008-12-01 00:13:45 +00:00
|
|
|
|
2009-08-04 20:37:10 +00:00
|
|
|
/* Initialize EXLATEOBJ */
|
2011-03-07 10:00:27 +00:00
|
|
|
EXLATEOBJ_vInitialize(&exlo,
|
|
|
|
ppalDIB,
|
|
|
|
pSurf->ppal,
|
|
|
|
RGB(0xff, 0xff, 0xff),
|
|
|
|
pDC->pdcattr->crBackgroundClr,
|
|
|
|
pDC->pdcattr->crForegroundClr);
|
2012-09-30 20:30:23 +00:00
|
|
|
|
2012-08-22 20:11:41 +00:00
|
|
|
pDestSurf = &pSurf->SurfObj;
|
2007-09-27 17:04:29 +00:00
|
|
|
|
2008-12-01 00:13:45 +00:00
|
|
|
/* Copy the bits */
|
2021-02-20 23:28:36 +00:00
|
|
|
DPRINT("BitsToDev with rcDest=(%d|%d) (%d|%d), ptSource=(%d|%d) w=%d h=%d\n",
|
2011-02-28 23:46:02 +00:00
|
|
|
rcDest.left, rcDest.top, rcDest.right, rcDest.bottom,
|
|
|
|
ptSource.x, ptSource.y, SourceSize.cx, SourceSize.cy);
|
2021-02-20 23:28:36 +00:00
|
|
|
|
|
|
|
/* This fixes the large Google text on Google.com from being upside down */
|
|
|
|
if (rcDest.top > rcDest.bottom)
|
|
|
|
{
|
|
|
|
RECTL_vMakeWellOrdered(&rcDest);
|
|
|
|
ptSource.y -= SourceSize.cy;
|
|
|
|
}
|
|
|
|
|
2017-08-15 18:13:14 +00:00
|
|
|
bResult = IntEngBitBlt(pDestSurf,
|
2008-12-01 00:13:45 +00:00
|
|
|
pSourceSurf,
|
2014-08-23 14:20:16 +00:00
|
|
|
pMaskSurf,
|
2017-07-13 01:59:41 +00:00
|
|
|
(CLIPOBJ *)&pDC->co,
|
2009-08-04 20:37:10 +00:00
|
|
|
&exlo.xlo,
|
2008-12-01 00:13:45 +00:00
|
|
|
&rcDest,
|
|
|
|
&ptSource,
|
2014-08-23 14:20:16 +00:00
|
|
|
pMaskSurf ? &ptSource : NULL,
|
2008-12-01 00:13:45 +00:00
|
|
|
NULL,
|
|
|
|
NULL,
|
2014-08-23 14:20:16 +00:00
|
|
|
pMaskSurf ? ROP4_MASK : ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY));
|
2009-08-04 20:37:10 +00:00
|
|
|
|
|
|
|
/* Cleanup EXLATEOBJ */
|
|
|
|
EXLATEOBJ_vCleanup(&exlo);
|
2012-09-30 20:30:23 +00:00
|
|
|
|
2012-08-22 20:11:41 +00:00
|
|
|
/* We're done */
|
|
|
|
DC_vFinishBlit(pDC, NULL);
|
2009-08-04 20:37:10 +00:00
|
|
|
|
2017-08-15 18:13:14 +00:00
|
|
|
ret = bResult ? ScanLines : 0;
|
|
|
|
|
2008-12-01 00:13:45 +00:00
|
|
|
Exit:
|
2007-09-27 17:04:29 +00:00
|
|
|
|
2011-04-15 15:29:08 +00:00
|
|
|
if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
|
2008-04-19 00:24:34 +00:00
|
|
|
if (pSourceSurf) EngUnlockSurface(pSourceSurf);
|
|
|
|
if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
|
2014-08-23 14:20:16 +00:00
|
|
|
if (pMaskSurf) EngUnlockSurface(pMaskSurf);
|
|
|
|
if (hMaskBitmap) EngDeleteSurface((HSURF)hMaskBitmap);
|
2015-03-08 22:44:36 +00:00
|
|
|
if (pDC) DC_UnlockDc(pDC);
|
2012-10-06 20:15:36 +00:00
|
|
|
ExFreePoolWithTag(pbmiSafe, 'pmTG');
|
2015-03-08 22:44:36 +00:00
|
|
|
|
2007-09-27 17:04:29 +00:00
|
|
|
return ret;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2007-10-01 11:53:31 +00:00
|
|
|
|
2004-07-03 13:55:37 +00:00
|
|
|
/* Converts a device-dependent bitmap to a DIB */
|
2009-06-10 00:23:15 +00:00
|
|
|
INT
|
|
|
|
APIENTRY
|
2012-09-30 20:30:23 +00:00
|
|
|
GreGetDIBitsInternal(
|
2009-06-10 00:23:15 +00:00
|
|
|
HDC hDC,
|
|
|
|
HBITMAP hBitmap,
|
|
|
|
UINT StartScan,
|
|
|
|
UINT ScanLines,
|
|
|
|
LPBYTE Bits,
|
|
|
|
LPBITMAPINFO Info,
|
|
|
|
UINT Usage,
|
|
|
|
UINT MaxBits,
|
|
|
|
UINT MaxInfo)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2011-02-28 23:46:02 +00:00
|
|
|
BITMAPCOREINFO* pbmci = NULL;
|
|
|
|
PSURFACE psurf = NULL;
|
|
|
|
PDC pDC;
|
|
|
|
LONG width, height;
|
|
|
|
WORD planes, bpp;
|
|
|
|
DWORD compr, size ;
|
2012-03-04 11:32:43 +00:00
|
|
|
USHORT i;
|
|
|
|
int bitmap_type;
|
2011-02-28 23:46:02 +00:00
|
|
|
RGBQUAD* rgbQuads;
|
|
|
|
VOID* colorPtr;
|
2007-10-01 11:53:31 +00:00
|
|
|
|
2015-02-15 00:05:50 +00:00
|
|
|
DPRINT("Entered GreGetDIBitsInternal()\n");
|
2007-09-18 15:24:34 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
if ((Usage && Usage != DIB_PAL_COLORS) || !Info || !hBitmap)
|
|
|
|
return 0;
|
2008-12-01 00:13:45 +00:00
|
|
|
|
2017-03-04 10:37:00 +00:00
|
|
|
pDC = DC_LockDc(hDC);
|
|
|
|
if (pDC == NULL || pDC->dctype == DC_TYPE_INFO)
|
|
|
|
{
|
|
|
|
ScanLines = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get a pointer to the source bitmap object */
|
|
|
|
psurf = SURFACE_ShareLockSurface(hBitmap);
|
|
|
|
if (psurf == NULL)
|
|
|
|
{
|
|
|
|
ScanLines = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2011-02-28 23:46:02 +00:00
|
|
|
colorPtr = (LPBYTE)Info + Info->bmiHeader.biSize;
|
|
|
|
rgbQuads = colorPtr;
|
|
|
|
|
|
|
|
bitmap_type = DIB_GetBitmapInfo(&Info->bmiHeader,
|
|
|
|
&width,
|
|
|
|
&height,
|
|
|
|
&planes,
|
|
|
|
&bpp,
|
|
|
|
&compr,
|
|
|
|
&size);
|
|
|
|
if(bitmap_type == -1)
|
|
|
|
{
|
2021-02-20 23:28:36 +00:00
|
|
|
DPRINT1("Wrong bitmap format\n");
|
2011-02-28 23:46:02 +00:00
|
|
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
2017-03-04 10:37:00 +00:00
|
|
|
ScanLines = 0;
|
|
|
|
goto done;
|
2011-02-28 23:46:02 +00:00
|
|
|
}
|
|
|
|
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;
|
2017-03-04 10:37:00 +00:00
|
|
|
/* fill in the the bit count, so we can calculate the right ColorsSize during the conversion */
|
|
|
|
pbmci->bmciHeader.bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
|
2011-02-28 23:46:02 +00:00
|
|
|
Info = DIB_ConvertBitmapInfo((BITMAPINFO*)pbmci, Usage);
|
|
|
|
if(Info == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("Error, could not convert the BITMAPCOREINFO!\n");
|
2017-03-04 10:37:00 +00:00
|
|
|
ScanLines = 0;
|
|
|
|
goto done;
|
2011-02-28 23:46:02 +00:00
|
|
|
}
|
|
|
|
rgbQuads = Info->bmiColors;
|
|
|
|
}
|
2010-07-29 16:12:43 +00:00
|
|
|
|
2017-03-04 10:37:00 +00:00
|
|
|
/* Validate input:
|
|
|
|
- negative width is always an invalid value
|
|
|
|
- non-null Bits and zero bpp is an invalid combination
|
|
|
|
- only check the rest of the input params if either bpp is non-zero or Bits are set */
|
|
|
|
if (width < 0 || (bpp == 0 && Bits))
|
2007-09-18 15:24:34 +00:00
|
|
|
{
|
2011-02-28 23:46:02 +00:00
|
|
|
ScanLines = 0;
|
2010-07-29 16:12:43 +00:00
|
|
|
goto done;
|
2007-09-18 15:24:34 +00:00
|
|
|
}
|
2003-12-20 14:51:41 +00:00
|
|
|
|
2017-03-04 10:37:00 +00:00
|
|
|
if (Bits || bpp)
|
2010-05-08 22:10:41 +00:00
|
|
|
{
|
2017-06-11 11:18:57 +00:00
|
|
|
if ((height == 0 || width == 0) || (compr && compr != BI_BITFIELDS && compr != BI_RGB))
|
2017-03-04 10:37:00 +00:00
|
|
|
{
|
|
|
|
ScanLines = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
2009-03-21 19:15:52 +00:00
|
|
|
}
|
|
|
|
|
2017-03-04 10:37:00 +00:00
|
|
|
Info->bmiHeader.biClrUsed = 0;
|
|
|
|
Info->bmiHeader.biClrImportant = 0;
|
|
|
|
|
2011-02-28 23:46:02 +00:00
|
|
|
/* Fill in the structure */
|
|
|
|
switch(bpp)
|
|
|
|
{
|
|
|
|
case 0: /* Only info */
|
|
|
|
Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
|
|
|
|
Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
|
|
|
|
-psurf->SurfObj.sizlBitmap.cy :
|
2016-02-04 20:42:07 +00:00
|
|
|
psurf->SurfObj.sizlBitmap.cy;
|
2011-02-28 23:46:02 +00:00
|
|
|
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);
|
2021-09-13 01:33:14 +00:00
|
|
|
Info->bmiHeader.biCompression = (Info->bmiHeader.biBitCount == 16 || Info->bmiHeader.biBitCount == 32) ?
|
2017-03-04 10:37:00 +00:00
|
|
|
BI_BITFIELDS : BI_RGB;
|
2011-02-28 23:46:02 +00:00
|
|
|
Info->bmiHeader.biXPelsPerMeter = 0;
|
2010-07-29 16:12:43 +00:00
|
|
|
Info->bmiHeader.biYPelsPerMeter = 0;
|
2017-03-04 10:37:00 +00:00
|
|
|
|
|
|
|
if (Info->bmiHeader.biBitCount <= 8 && Info->bmiHeader.biClrUsed == 0)
|
|
|
|
Info->bmiHeader.biClrUsed = 1 << Info->bmiHeader.biBitCount;
|
|
|
|
|
|
|
|
ScanLines = 1;
|
2011-02-28 23:46:02 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
case 4:
|
|
|
|
case 8:
|
2017-03-04 10:37:00 +00:00
|
|
|
Info->bmiHeader.biClrUsed = 1 << bpp;
|
2011-02-28 23:46:02 +00:00
|
|
|
|
2016-10-26 10:21:46 +00:00
|
|
|
/* If the bitmap is a DIB section and has the same format as what
|
|
|
|
* is requested, go ahead! */
|
2011-02-28 23:46:02 +00:00
|
|
|
if((psurf->hSecure) &&
|
|
|
|
(BitsPerFormat(psurf->SurfObj.iBitmapFormat) == bpp))
|
|
|
|
{
|
|
|
|
if(Usage == DIB_RGB_COLORS)
|
|
|
|
{
|
2012-03-04 11:32:43 +00:00
|
|
|
ULONG colors = min(psurf->ppal->NumColors, 256);
|
|
|
|
if(colors != 256) Info->bmiHeader.biClrUsed = colors;
|
|
|
|
for(i = 0; i < colors; i++)
|
2011-02-28 23:46:02 +00:00
|
|
|
{
|
|
|
|
rgbQuads[i].rgbRed = psurf->ppal->IndexedColors[i].peRed;
|
|
|
|
rgbQuads[i].rgbGreen = psurf->ppal->IndexedColors[i].peGreen;
|
|
|
|
rgbQuads[i].rgbBlue = psurf->ppal->IndexedColors[i].peBlue;
|
2012-11-08 12:40:41 +00:00
|
|
|
rgbQuads[i].rgbReserved = 0;
|
2011-02-28 23:46:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-03-04 11:32:43 +00:00
|
|
|
for(i = 0; i < 256; i++)
|
2011-02-28 23:46:02 +00:00
|
|
|
((WORD*)rgbQuads)[i] = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(Usage == DIB_PAL_COLORS)
|
|
|
|
{
|
2012-03-04 11:32:43 +00:00
|
|
|
for(i = 0; i < 256; i++)
|
2011-02-28 23:46:02 +00:00
|
|
|
{
|
|
|
|
((WORD*)rgbQuads)[i] = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(bpp > 1 && bpp == BitsPerFormat(psurf->SurfObj.iBitmapFormat))
|
|
|
|
{
|
2010-07-29 16:12:43 +00:00
|
|
|
/* For color DDBs in native depth (mono DDBs always have
|
|
|
|
a black/white palette):
|
|
|
|
Generate the color map from the selected palette */
|
2011-04-18 19:09:05 +00:00
|
|
|
PPALETTE pDcPal = PALETTE_ShareLockPalette(pDC->dclevel.hpal);
|
2011-02-28 23:46:02 +00:00
|
|
|
if(!pDcPal)
|
|
|
|
{
|
|
|
|
ScanLines = 0 ;
|
|
|
|
goto done ;
|
|
|
|
}
|
|
|
|
for (i = 0; i < pDcPal->NumColors; i++)
|
|
|
|
{
|
2010-07-29 16:12:43 +00:00
|
|
|
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;
|
2011-02-28 23:46:02 +00:00
|
|
|
}
|
2011-04-18 19:09:05 +00:00
|
|
|
PALETTE_ShareUnlockPalette(pDcPal);
|
2011-02-28 23:46:02 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (bpp)
|
|
|
|
{
|
2010-07-29 16:12:43 +00:00
|
|
|
case 1:
|
2013-01-02 14:52:34 +00:00
|
|
|
rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen = rgbQuads[0].rgbBlue = 0;
|
2010-07-29 16:12:43 +00:00
|
|
|
rgbQuads[0].rgbReserved = 0;
|
2013-01-02 14:52:34 +00:00
|
|
|
rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen = rgbQuads[1].rgbBlue = 0xff;
|
2010-07-29 16:12:43 +00:00
|
|
|
rgbQuads[1].rgbReserved = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
2017-03-19 00:35:48 +00:00
|
|
|
/* The EGA palette is the first and last 8 colours of the default palette
|
|
|
|
with the innermost pair swapped */
|
|
|
|
RtlCopyMemory(rgbQuads, DefLogPaletteQuads, 7 * sizeof(RGBQUAD));
|
|
|
|
RtlCopyMemory(rgbQuads + 7, DefLogPaletteQuads + 12, 1 * sizeof(RGBQUAD));
|
|
|
|
RtlCopyMemory(rgbQuads + 8, DefLogPaletteQuads + 7, 1 * sizeof(RGBQUAD));
|
|
|
|
RtlCopyMemory(rgbQuads + 9, DefLogPaletteQuads + 13, 7 * sizeof(RGBQUAD));
|
2010-07-29 16:12:43 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 8:
|
2011-02-28 23:46:02 +00:00
|
|
|
{
|
2016-10-26 10:21:46 +00:00
|
|
|
INT i;
|
|
|
|
|
|
|
|
memcpy(rgbQuads, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
|
|
|
|
memcpy(rgbQuads + 246, DefLogPaletteQuads + 10, 10 * sizeof(RGBQUAD));
|
|
|
|
|
|
|
|
for (i = 10; i < 246; i++)
|
2011-02-28 23:46:02 +00:00
|
|
|
{
|
2016-10-26 10:21:46 +00:00
|
|
|
rgbQuads[i].rgbRed = (i & 0x07) << 5;
|
|
|
|
rgbQuads[i].rgbGreen = (i & 0x38) << 2;
|
|
|
|
rgbQuads[i].rgbBlue = i & 0xc0;
|
|
|
|
rgbQuads[i].rgbReserved = 0;
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
|
|
|
}
|
2011-02-28 23:46:02 +00:00
|
|
|
}
|
2009-03-21 19:15:52 +00:00
|
|
|
}
|
2010-07-29 16:12:43 +00:00
|
|
|
}
|
|
|
|
break;
|
2009-06-10 00:23:15 +00:00
|
|
|
|
2010-07-29 16:12:43 +00:00
|
|
|
case 15:
|
|
|
|
if (Info->bmiHeader.biCompression == BI_BITFIELDS)
|
|
|
|
{
|
|
|
|
((PDWORD)Info->bmiColors)[0] = 0x7c00;
|
|
|
|
((PDWORD)Info->bmiColors)[1] = 0x03e0;
|
|
|
|
((PDWORD)Info->bmiColors)[2] = 0x001f;
|
|
|
|
}
|
|
|
|
break;
|
2009-06-10 00:23:15 +00:00
|
|
|
|
2010-07-29 16:12:43 +00:00
|
|
|
case 16:
|
|
|
|
if (Info->bmiHeader.biCompression == BI_BITFIELDS)
|
|
|
|
{
|
2010-07-30 02:15:46 +00:00
|
|
|
if (psurf->hSecure)
|
2011-02-28 23:46:02 +00:00
|
|
|
{
|
|
|
|
((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
|
2010-07-30 02:15:46 +00:00
|
|
|
((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
|
|
|
|
((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
|
2011-02-28 23:46:02 +00:00
|
|
|
}
|
2010-07-29 16:12:43 +00:00
|
|
|
else
|
2009-03-21 19:15:52 +00:00
|
|
|
{
|
2010-07-29 16:12:43 +00:00
|
|
|
((PDWORD)Info->bmiColors)[0] = 0xf800;
|
|
|
|
((PDWORD)Info->bmiColors)[1] = 0x07e0;
|
|
|
|
((PDWORD)Info->bmiColors)[2] = 0x001f;
|
2009-03-21 19:15:52 +00:00
|
|
|
}
|
2010-07-29 16:12:43 +00:00
|
|
|
}
|
|
|
|
break;
|
2009-06-10 00:23:15 +00:00
|
|
|
|
2010-07-29 16:12:43 +00:00
|
|
|
case 24:
|
|
|
|
case 32:
|
|
|
|
if (Info->bmiHeader.biCompression == BI_BITFIELDS)
|
|
|
|
{
|
2010-07-30 02:15:46 +00:00
|
|
|
if (psurf->hSecure)
|
2011-02-28 23:46:02 +00:00
|
|
|
{
|
|
|
|
((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
|
2010-07-30 02:15:46 +00:00
|
|
|
((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
|
|
|
|
((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
|
2011-02-28 23:46:02 +00:00
|
|
|
}
|
2010-07-29 16:12:43 +00:00
|
|
|
else
|
2009-03-21 19:15:52 +00:00
|
|
|
{
|
2010-07-29 16:12:43 +00:00
|
|
|
((PDWORD)Info->bmiColors)[0] = 0xff0000;
|
|
|
|
((PDWORD)Info->bmiColors)[1] = 0x00ff00;
|
|
|
|
((PDWORD)Info->bmiColors)[2] = 0x0000ff;
|
2009-03-21 19:15:52 +00:00
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
2010-07-29 16:12:43 +00:00
|
|
|
break;
|
2017-03-04 10:37:00 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
ScanLines = 0;
|
|
|
|
goto done;
|
2007-10-01 11:53:31 +00:00
|
|
|
}
|
2017-03-04 10:37:00 +00:00
|
|
|
|
2011-02-28 23:46:02 +00:00
|
|
|
Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(width, height, bpp);
|
2017-03-04 10:37:00 +00:00
|
|
|
Info->bmiHeader.biPlanes = 1;
|
2008-12-01 00:13:45 +00:00
|
|
|
|
2011-02-28 23:46:02 +00:00
|
|
|
if(Bits && ScanLines)
|
|
|
|
{
|
|
|
|
/* Create a DIBSECTION, blt it, profit */
|
|
|
|
PVOID pDIBits ;
|
|
|
|
HBITMAP hBmpDest;
|
|
|
|
PSURFACE psurfDest;
|
|
|
|
EXLATEOBJ exlo;
|
|
|
|
RECT rcDest;
|
|
|
|
POINTL srcPoint;
|
|
|
|
BOOL ret ;
|
[WIN32SS][COMCTL32] Commit Flip_Fix_9.patch
flip_fix_9.patch fixes:
CORE-16984 " 'SPINA Thrulg' / 'SPINA Thyr' / 'Sim Thyr' have images flipped"
CORE-17194 "StretchDIBits test" isn't work correctly"
"Output of 'Project 3 Test'"
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
CORE-14671 "'Peazip' shows icons in buttons and menubar vertically flipped"
"Double Commander shoes icons flipped in buttons, menubar, listview and the treeview"
CORE-13273 "Welcome to Lazarus" icon shows flipped
CORE-13026 "'CudaText app' icon shows flipped"
Not all of those are duplicates, although they appear to be at first glance.
It affects different controls and some of those tickets do have different 'guilty revs' than others.
The patch does consist of 3 parts:
1.) win32ss/gdi/ntgdi/dibobj.c
This one is the most clean part of it, that addresses most of the flipping issues now.
2.) The hack in comctl32.h redefining the version:
We used that in the past to appease some, but not all of the issues listed above.
But it does hide additional issues, e.g. in DvDStyler, therefore we seem to still need that appeasement even today.
Most likely it would make sense to aim to avoid this part in the future.
part 2.) was committed as first appeasement on its own already into
0.4.14-RC-24-g 198b61e
0.4.13-RC-7-g 67211fa
0.4.12-RC-5-g 8449527
0.4.11-RC-16-g b906163
0.4.10-RC-7-g f1e80fe
0.4.9-RC-34-g 9d758ae
3.) toolbar.c change
That part fixes at least the toolbar case for DvDStyler
without relying on the comctl32.h hack any longer,
but it was still not enough to completely get rid of part 2.) yet.
Many thanks to all contributors: 'I_kill_Bugs', Doug Lyons and also 'Julenuri' for testing.
The patch gave nice testbot results:
KVM: https://reactos.org/testman/compare.php?ids=75704,75714
VBox: https://reactos.org/testman/compare.php?ids=75705,75715
and we also created a summary of manual test-results:
https://jira.reactos.org/browse/CORE-17415?focusedCommentId=126668&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-126668
If you read this comment via git blame and your goal is to get rid of the hack in comctl32.h, I would highly recommend
to redo the tests of that testing table, and if that is asked too much, then please test at least the following cases:
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
"DVDStyler 3.0.4 erroneously black/transparent within comboboxes of properties of VMGM menu"
and try to add what might be needed to fix them, and double-check again:
"DoubleCommander optionsDlg the most complex testcase, contains flip-prone icons in treeview, listview, menubar, buttons, statics". Only some of its flipped icons were impacted by the comctl32.h change before.
2021-01-05 19:30:40 +00:00
|
|
|
int newLines = -1;
|
2010-07-29 16:12:43 +00:00
|
|
|
|
[WIN32SS][COMCTL32] Commit Flip_Fix_9.patch
flip_fix_9.patch fixes:
CORE-16984 " 'SPINA Thrulg' / 'SPINA Thyr' / 'Sim Thyr' have images flipped"
CORE-17194 "StretchDIBits test" isn't work correctly"
"Output of 'Project 3 Test'"
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
CORE-14671 "'Peazip' shows icons in buttons and menubar vertically flipped"
"Double Commander shoes icons flipped in buttons, menubar, listview and the treeview"
CORE-13273 "Welcome to Lazarus" icon shows flipped
CORE-13026 "'CudaText app' icon shows flipped"
Not all of those are duplicates, although they appear to be at first glance.
It affects different controls and some of those tickets do have different 'guilty revs' than others.
The patch does consist of 3 parts:
1.) win32ss/gdi/ntgdi/dibobj.c
This one is the most clean part of it, that addresses most of the flipping issues now.
2.) The hack in comctl32.h redefining the version:
We used that in the past to appease some, but not all of the issues listed above.
But it does hide additional issues, e.g. in DvDStyler, therefore we seem to still need that appeasement even today.
Most likely it would make sense to aim to avoid this part in the future.
part 2.) was committed as first appeasement on its own already into
0.4.14-RC-24-g 198b61e
0.4.13-RC-7-g 67211fa
0.4.12-RC-5-g 8449527
0.4.11-RC-16-g b906163
0.4.10-RC-7-g f1e80fe
0.4.9-RC-34-g 9d758ae
3.) toolbar.c change
That part fixes at least the toolbar case for DvDStyler
without relying on the comctl32.h hack any longer,
but it was still not enough to completely get rid of part 2.) yet.
Many thanks to all contributors: 'I_kill_Bugs', Doug Lyons and also 'Julenuri' for testing.
The patch gave nice testbot results:
KVM: https://reactos.org/testman/compare.php?ids=75704,75714
VBox: https://reactos.org/testman/compare.php?ids=75705,75715
and we also created a summary of manual test-results:
https://jira.reactos.org/browse/CORE-17415?focusedCommentId=126668&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-126668
If you read this comment via git blame and your goal is to get rid of the hack in comctl32.h, I would highly recommend
to redo the tests of that testing table, and if that is asked too much, then please test at least the following cases:
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
"DVDStyler 3.0.4 erroneously black/transparent within comboboxes of properties of VMGM menu"
and try to add what might be needed to fix them, and double-check again:
"DoubleCommander optionsDlg the most complex testcase, contains flip-prone icons in treeview, listview, menubar, buttons, statics". Only some of its flipped icons were impacted by the comctl32.h change before.
2021-01-05 19:30:40 +00:00
|
|
|
if (StartScan >= abs(Info->bmiHeader.biHeight))
|
2009-06-10 00:23:15 +00:00
|
|
|
{
|
[WIN32SS][COMCTL32] Commit Flip_Fix_9.patch
flip_fix_9.patch fixes:
CORE-16984 " 'SPINA Thrulg' / 'SPINA Thyr' / 'Sim Thyr' have images flipped"
CORE-17194 "StretchDIBits test" isn't work correctly"
"Output of 'Project 3 Test'"
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
CORE-14671 "'Peazip' shows icons in buttons and menubar vertically flipped"
"Double Commander shoes icons flipped in buttons, menubar, listview and the treeview"
CORE-13273 "Welcome to Lazarus" icon shows flipped
CORE-13026 "'CudaText app' icon shows flipped"
Not all of those are duplicates, although they appear to be at first glance.
It affects different controls and some of those tickets do have different 'guilty revs' than others.
The patch does consist of 3 parts:
1.) win32ss/gdi/ntgdi/dibobj.c
This one is the most clean part of it, that addresses most of the flipping issues now.
2.) The hack in comctl32.h redefining the version:
We used that in the past to appease some, but not all of the issues listed above.
But it does hide additional issues, e.g. in DvDStyler, therefore we seem to still need that appeasement even today.
Most likely it would make sense to aim to avoid this part in the future.
part 2.) was committed as first appeasement on its own already into
0.4.14-RC-24-g 198b61e
0.4.13-RC-7-g 67211fa
0.4.12-RC-5-g 8449527
0.4.11-RC-16-g b906163
0.4.10-RC-7-g f1e80fe
0.4.9-RC-34-g 9d758ae
3.) toolbar.c change
That part fixes at least the toolbar case for DvDStyler
without relying on the comctl32.h hack any longer,
but it was still not enough to completely get rid of part 2.) yet.
Many thanks to all contributors: 'I_kill_Bugs', Doug Lyons and also 'Julenuri' for testing.
The patch gave nice testbot results:
KVM: https://reactos.org/testman/compare.php?ids=75704,75714
VBox: https://reactos.org/testman/compare.php?ids=75705,75715
and we also created a summary of manual test-results:
https://jira.reactos.org/browse/CORE-17415?focusedCommentId=126668&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-126668
If you read this comment via git blame and your goal is to get rid of the hack in comctl32.h, I would highly recommend
to redo the tests of that testing table, and if that is asked too much, then please test at least the following cases:
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
"DVDStyler 3.0.4 erroneously black/transparent within comboboxes of properties of VMGM menu"
and try to add what might be needed to fix them, and double-check again:
"DoubleCommander optionsDlg the most complex testcase, contains flip-prone icons in treeview, listview, menubar, buttons, statics". Only some of its flipped icons were impacted by the comctl32.h change before.
2021-01-05 19:30:40 +00:00
|
|
|
ScanLines = 1;
|
2010-07-29 16:12:43 +00:00
|
|
|
goto done;
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
[WIN32SS][COMCTL32] Commit Flip_Fix_9.patch
flip_fix_9.patch fixes:
CORE-16984 " 'SPINA Thrulg' / 'SPINA Thyr' / 'Sim Thyr' have images flipped"
CORE-17194 "StretchDIBits test" isn't work correctly"
"Output of 'Project 3 Test'"
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
CORE-14671 "'Peazip' shows icons in buttons and menubar vertically flipped"
"Double Commander shoes icons flipped in buttons, menubar, listview and the treeview"
CORE-13273 "Welcome to Lazarus" icon shows flipped
CORE-13026 "'CudaText app' icon shows flipped"
Not all of those are duplicates, although they appear to be at first glance.
It affects different controls and some of those tickets do have different 'guilty revs' than others.
The patch does consist of 3 parts:
1.) win32ss/gdi/ntgdi/dibobj.c
This one is the most clean part of it, that addresses most of the flipping issues now.
2.) The hack in comctl32.h redefining the version:
We used that in the past to appease some, but not all of the issues listed above.
But it does hide additional issues, e.g. in DvDStyler, therefore we seem to still need that appeasement even today.
Most likely it would make sense to aim to avoid this part in the future.
part 2.) was committed as first appeasement on its own already into
0.4.14-RC-24-g 198b61e
0.4.13-RC-7-g 67211fa
0.4.12-RC-5-g 8449527
0.4.11-RC-16-g b906163
0.4.10-RC-7-g f1e80fe
0.4.9-RC-34-g 9d758ae
3.) toolbar.c change
That part fixes at least the toolbar case for DvDStyler
without relying on the comctl32.h hack any longer,
but it was still not enough to completely get rid of part 2.) yet.
Many thanks to all contributors: 'I_kill_Bugs', Doug Lyons and also 'Julenuri' for testing.
The patch gave nice testbot results:
KVM: https://reactos.org/testman/compare.php?ids=75704,75714
VBox: https://reactos.org/testman/compare.php?ids=75705,75715
and we also created a summary of manual test-results:
https://jira.reactos.org/browse/CORE-17415?focusedCommentId=126668&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-126668
If you read this comment via git blame and your goal is to get rid of the hack in comctl32.h, I would highly recommend
to redo the tests of that testing table, and if that is asked too much, then please test at least the following cases:
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
"DVDStyler 3.0.4 erroneously black/transparent within comboboxes of properties of VMGM menu"
and try to add what might be needed to fix them, and double-check again:
"DoubleCommander optionsDlg the most complex testcase, contains flip-prone icons in treeview, listview, menubar, buttons, statics". Only some of its flipped icons were impacted by the comctl32.h change before.
2021-01-05 19:30:40 +00:00
|
|
|
ScanLines = min(ScanLines, abs(Info->bmiHeader.biHeight) - StartScan);
|
2011-02-28 23:46:02 +00:00
|
|
|
}
|
|
|
|
|
[WIN32SS][COMCTL32] Commit Flip_Fix_9.patch
flip_fix_9.patch fixes:
CORE-16984 " 'SPINA Thrulg' / 'SPINA Thyr' / 'Sim Thyr' have images flipped"
CORE-17194 "StretchDIBits test" isn't work correctly"
"Output of 'Project 3 Test'"
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
CORE-14671 "'Peazip' shows icons in buttons and menubar vertically flipped"
"Double Commander shoes icons flipped in buttons, menubar, listview and the treeview"
CORE-13273 "Welcome to Lazarus" icon shows flipped
CORE-13026 "'CudaText app' icon shows flipped"
Not all of those are duplicates, although they appear to be at first glance.
It affects different controls and some of those tickets do have different 'guilty revs' than others.
The patch does consist of 3 parts:
1.) win32ss/gdi/ntgdi/dibobj.c
This one is the most clean part of it, that addresses most of the flipping issues now.
2.) The hack in comctl32.h redefining the version:
We used that in the past to appease some, but not all of the issues listed above.
But it does hide additional issues, e.g. in DvDStyler, therefore we seem to still need that appeasement even today.
Most likely it would make sense to aim to avoid this part in the future.
part 2.) was committed as first appeasement on its own already into
0.4.14-RC-24-g 198b61e
0.4.13-RC-7-g 67211fa
0.4.12-RC-5-g 8449527
0.4.11-RC-16-g b906163
0.4.10-RC-7-g f1e80fe
0.4.9-RC-34-g 9d758ae
3.) toolbar.c change
That part fixes at least the toolbar case for DvDStyler
without relying on the comctl32.h hack any longer,
but it was still not enough to completely get rid of part 2.) yet.
Many thanks to all contributors: 'I_kill_Bugs', Doug Lyons and also 'Julenuri' for testing.
The patch gave nice testbot results:
KVM: https://reactos.org/testman/compare.php?ids=75704,75714
VBox: https://reactos.org/testman/compare.php?ids=75705,75715
and we also created a summary of manual test-results:
https://jira.reactos.org/browse/CORE-17415?focusedCommentId=126668&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-126668
If you read this comment via git blame and your goal is to get rid of the hack in comctl32.h, I would highly recommend
to redo the tests of that testing table, and if that is asked too much, then please test at least the following cases:
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
"DVDStyler 3.0.4 erroneously black/transparent within comboboxes of properties of VMGM menu"
and try to add what might be needed to fix them, and double-check again:
"DoubleCommander optionsDlg the most complex testcase, contains flip-prone icons in treeview, listview, menubar, buttons, statics". Only some of its flipped icons were impacted by the comctl32.h change before.
2021-01-05 19:30:40 +00:00
|
|
|
if (abs(Info->bmiHeader.biHeight) < psurf->SurfObj.sizlBitmap.cy)
|
|
|
|
{
|
|
|
|
StartScan += psurf->SurfObj.sizlBitmap.cy - abs(Info->bmiHeader.biHeight);
|
|
|
|
}
|
2011-02-28 23:46:02 +00:00
|
|
|
/* Fixup values */
|
2012-03-04 11:32:43 +00:00
|
|
|
Info->bmiHeader.biHeight = (height < 0) ?
|
|
|
|
-(LONG)ScanLines : ScanLines;
|
2011-02-28 23:46:02 +00:00
|
|
|
/* Create the DIB */
|
|
|
|
hBmpDest = DIB_CreateDIBSection(pDC, Info, Usage, &pDIBits, NULL, 0, 0);
|
|
|
|
/* Restore them */
|
|
|
|
Info->bmiHeader.biHeight = height;
|
|
|
|
|
|
|
|
if(!hBmpDest)
|
|
|
|
{
|
|
|
|
DPRINT1("Unable to create a DIB Section!\n");
|
|
|
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
ScanLines = 0;
|
|
|
|
goto done ;
|
|
|
|
}
|
|
|
|
|
|
|
|
psurfDest = SURFACE_ShareLockSurface(hBmpDest);
|
2012-12-18 21:44:58 +00:00
|
|
|
|
[WIN32SS][COMCTL32] Commit Flip_Fix_9.patch
flip_fix_9.patch fixes:
CORE-16984 " 'SPINA Thrulg' / 'SPINA Thyr' / 'Sim Thyr' have images flipped"
CORE-17194 "StretchDIBits test" isn't work correctly"
"Output of 'Project 3 Test'"
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
CORE-14671 "'Peazip' shows icons in buttons and menubar vertically flipped"
"Double Commander shoes icons flipped in buttons, menubar, listview and the treeview"
CORE-13273 "Welcome to Lazarus" icon shows flipped
CORE-13026 "'CudaText app' icon shows flipped"
Not all of those are duplicates, although they appear to be at first glance.
It affects different controls and some of those tickets do have different 'guilty revs' than others.
The patch does consist of 3 parts:
1.) win32ss/gdi/ntgdi/dibobj.c
This one is the most clean part of it, that addresses most of the flipping issues now.
2.) The hack in comctl32.h redefining the version:
We used that in the past to appease some, but not all of the issues listed above.
But it does hide additional issues, e.g. in DvDStyler, therefore we seem to still need that appeasement even today.
Most likely it would make sense to aim to avoid this part in the future.
part 2.) was committed as first appeasement on its own already into
0.4.14-RC-24-g 198b61e
0.4.13-RC-7-g 67211fa
0.4.12-RC-5-g 8449527
0.4.11-RC-16-g b906163
0.4.10-RC-7-g f1e80fe
0.4.9-RC-34-g 9d758ae
3.) toolbar.c change
That part fixes at least the toolbar case for DvDStyler
without relying on the comctl32.h hack any longer,
but it was still not enough to completely get rid of part 2.) yet.
Many thanks to all contributors: 'I_kill_Bugs', Doug Lyons and also 'Julenuri' for testing.
The patch gave nice testbot results:
KVM: https://reactos.org/testman/compare.php?ids=75704,75714
VBox: https://reactos.org/testman/compare.php?ids=75705,75715
and we also created a summary of manual test-results:
https://jira.reactos.org/browse/CORE-17415?focusedCommentId=126668&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-126668
If you read this comment via git blame and your goal is to get rid of the hack in comctl32.h, I would highly recommend
to redo the tests of that testing table, and if that is asked too much, then please test at least the following cases:
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
"DVDStyler 3.0.4 erroneously black/transparent within comboboxes of properties of VMGM menu"
and try to add what might be needed to fix them, and double-check again:
"DoubleCommander optionsDlg the most complex testcase, contains flip-prone icons in treeview, listview, menubar, buttons, statics". Only some of its flipped icons were impacted by the comctl32.h change before.
2021-01-05 19:30:40 +00:00
|
|
|
RECTL_vSetRect(&rcDest, 0, 0, Info->bmiHeader.biWidth, ScanLines);
|
|
|
|
Info->bmiHeader.biWidth = width;
|
2011-02-28 12:47:01 +00:00
|
|
|
srcPoint.x = 0;
|
|
|
|
|
[WIN32SS][COMCTL32] Commit Flip_Fix_9.patch
flip_fix_9.patch fixes:
CORE-16984 " 'SPINA Thrulg' / 'SPINA Thyr' / 'Sim Thyr' have images flipped"
CORE-17194 "StretchDIBits test" isn't work correctly"
"Output of 'Project 3 Test'"
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
CORE-14671 "'Peazip' shows icons in buttons and menubar vertically flipped"
"Double Commander shoes icons flipped in buttons, menubar, listview and the treeview"
CORE-13273 "Welcome to Lazarus" icon shows flipped
CORE-13026 "'CudaText app' icon shows flipped"
Not all of those are duplicates, although they appear to be at first glance.
It affects different controls and some of those tickets do have different 'guilty revs' than others.
The patch does consist of 3 parts:
1.) win32ss/gdi/ntgdi/dibobj.c
This one is the most clean part of it, that addresses most of the flipping issues now.
2.) The hack in comctl32.h redefining the version:
We used that in the past to appease some, but not all of the issues listed above.
But it does hide additional issues, e.g. in DvDStyler, therefore we seem to still need that appeasement even today.
Most likely it would make sense to aim to avoid this part in the future.
part 2.) was committed as first appeasement on its own already into
0.4.14-RC-24-g 198b61e
0.4.13-RC-7-g 67211fa
0.4.12-RC-5-g 8449527
0.4.11-RC-16-g b906163
0.4.10-RC-7-g f1e80fe
0.4.9-RC-34-g 9d758ae
3.) toolbar.c change
That part fixes at least the toolbar case for DvDStyler
without relying on the comctl32.h hack any longer,
but it was still not enough to completely get rid of part 2.) yet.
Many thanks to all contributors: 'I_kill_Bugs', Doug Lyons and also 'Julenuri' for testing.
The patch gave nice testbot results:
KVM: https://reactos.org/testman/compare.php?ids=75704,75714
VBox: https://reactos.org/testman/compare.php?ids=75705,75715
and we also created a summary of manual test-results:
https://jira.reactos.org/browse/CORE-17415?focusedCommentId=126668&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-126668
If you read this comment via git blame and your goal is to get rid of the hack in comctl32.h, I would highly recommend
to redo the tests of that testing table, and if that is asked too much, then please test at least the following cases:
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
"DVDStyler 3.0.4 erroneously black/transparent within comboboxes of properties of VMGM menu"
and try to add what might be needed to fix them, and double-check again:
"DoubleCommander optionsDlg the most complex testcase, contains flip-prone icons in treeview, listview, menubar, buttons, statics". Only some of its flipped icons were impacted by the comctl32.h change before.
2021-01-05 19:30:40 +00:00
|
|
|
if (abs(Info->bmiHeader.biHeight) <= psurf->SurfObj.sizlBitmap.cy)
|
2011-02-28 12:47:01 +00:00
|
|
|
{
|
[WIN32SS][COMCTL32] Commit Flip_Fix_9.patch
flip_fix_9.patch fixes:
CORE-16984 " 'SPINA Thrulg' / 'SPINA Thyr' / 'Sim Thyr' have images flipped"
CORE-17194 "StretchDIBits test" isn't work correctly"
"Output of 'Project 3 Test'"
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
CORE-14671 "'Peazip' shows icons in buttons and menubar vertically flipped"
"Double Commander shoes icons flipped in buttons, menubar, listview and the treeview"
CORE-13273 "Welcome to Lazarus" icon shows flipped
CORE-13026 "'CudaText app' icon shows flipped"
Not all of those are duplicates, although they appear to be at first glance.
It affects different controls and some of those tickets do have different 'guilty revs' than others.
The patch does consist of 3 parts:
1.) win32ss/gdi/ntgdi/dibobj.c
This one is the most clean part of it, that addresses most of the flipping issues now.
2.) The hack in comctl32.h redefining the version:
We used that in the past to appease some, but not all of the issues listed above.
But it does hide additional issues, e.g. in DvDStyler, therefore we seem to still need that appeasement even today.
Most likely it would make sense to aim to avoid this part in the future.
part 2.) was committed as first appeasement on its own already into
0.4.14-RC-24-g 198b61e
0.4.13-RC-7-g 67211fa
0.4.12-RC-5-g 8449527
0.4.11-RC-16-g b906163
0.4.10-RC-7-g f1e80fe
0.4.9-RC-34-g 9d758ae
3.) toolbar.c change
That part fixes at least the toolbar case for DvDStyler
without relying on the comctl32.h hack any longer,
but it was still not enough to completely get rid of part 2.) yet.
Many thanks to all contributors: 'I_kill_Bugs', Doug Lyons and also 'Julenuri' for testing.
The patch gave nice testbot results:
KVM: https://reactos.org/testman/compare.php?ids=75704,75714
VBox: https://reactos.org/testman/compare.php?ids=75705,75715
and we also created a summary of manual test-results:
https://jira.reactos.org/browse/CORE-17415?focusedCommentId=126668&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-126668
If you read this comment via git blame and your goal is to get rid of the hack in comctl32.h, I would highly recommend
to redo the tests of that testing table, and if that is asked too much, then please test at least the following cases:
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
"DVDStyler 3.0.4 erroneously black/transparent within comboboxes of properties of VMGM menu"
and try to add what might be needed to fix them, and double-check again:
"DoubleCommander optionsDlg the most complex testcase, contains flip-prone icons in treeview, listview, menubar, buttons, statics". Only some of its flipped icons were impacted by the comctl32.h change before.
2021-01-05 19:30:40 +00:00
|
|
|
srcPoint.y = psurf->SurfObj.sizlBitmap.cy - StartScan - ScanLines;
|
2011-02-28 12:47:01 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
[WIN32SS][COMCTL32] Commit Flip_Fix_9.patch
flip_fix_9.patch fixes:
CORE-16984 " 'SPINA Thrulg' / 'SPINA Thyr' / 'Sim Thyr' have images flipped"
CORE-17194 "StretchDIBits test" isn't work correctly"
"Output of 'Project 3 Test'"
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
CORE-14671 "'Peazip' shows icons in buttons and menubar vertically flipped"
"Double Commander shoes icons flipped in buttons, menubar, listview and the treeview"
CORE-13273 "Welcome to Lazarus" icon shows flipped
CORE-13026 "'CudaText app' icon shows flipped"
Not all of those are duplicates, although they appear to be at first glance.
It affects different controls and some of those tickets do have different 'guilty revs' than others.
The patch does consist of 3 parts:
1.) win32ss/gdi/ntgdi/dibobj.c
This one is the most clean part of it, that addresses most of the flipping issues now.
2.) The hack in comctl32.h redefining the version:
We used that in the past to appease some, but not all of the issues listed above.
But it does hide additional issues, e.g. in DvDStyler, therefore we seem to still need that appeasement even today.
Most likely it would make sense to aim to avoid this part in the future.
part 2.) was committed as first appeasement on its own already into
0.4.14-RC-24-g 198b61e
0.4.13-RC-7-g 67211fa
0.4.12-RC-5-g 8449527
0.4.11-RC-16-g b906163
0.4.10-RC-7-g f1e80fe
0.4.9-RC-34-g 9d758ae
3.) toolbar.c change
That part fixes at least the toolbar case for DvDStyler
without relying on the comctl32.h hack any longer,
but it was still not enough to completely get rid of part 2.) yet.
Many thanks to all contributors: 'I_kill_Bugs', Doug Lyons and also 'Julenuri' for testing.
The patch gave nice testbot results:
KVM: https://reactos.org/testman/compare.php?ids=75704,75714
VBox: https://reactos.org/testman/compare.php?ids=75705,75715
and we also created a summary of manual test-results:
https://jira.reactos.org/browse/CORE-17415?focusedCommentId=126668&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-126668
If you read this comment via git blame and your goal is to get rid of the hack in comctl32.h, I would highly recommend
to redo the tests of that testing table, and if that is asked too much, then please test at least the following cases:
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
"DVDStyler 3.0.4 erroneously black/transparent within comboboxes of properties of VMGM menu"
and try to add what might be needed to fix them, and double-check again:
"DoubleCommander optionsDlg the most complex testcase, contains flip-prone icons in treeview, listview, menubar, buttons, statics". Only some of its flipped icons were impacted by the comctl32.h change before.
2021-01-05 19:30:40 +00:00
|
|
|
/* Determine the actual number of lines copied from the */
|
|
|
|
/* original bitmap. It might be different from ScanLines. */
|
|
|
|
newLines = abs(Info->bmiHeader.biHeight) - psurf->SurfObj.sizlBitmap.cy;
|
|
|
|
newLines = min((int)(StartScan + ScanLines - newLines), psurf->SurfObj.sizlBitmap.cy);
|
|
|
|
if (newLines > 0)
|
|
|
|
{
|
|
|
|
srcPoint.y = psurf->SurfObj.sizlBitmap.cy - newLines;
|
|
|
|
if (StartScan > psurf->SurfObj.sizlBitmap.cy)
|
|
|
|
{
|
|
|
|
newLines -= (StartScan - psurf->SurfObj.sizlBitmap.cy);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
newLines = 0;
|
|
|
|
srcPoint.y = psurf->SurfObj.sizlBitmap.cy;
|
|
|
|
}
|
2011-02-28 12:47:01 +00:00
|
|
|
}
|
2010-07-29 16:12:43 +00:00
|
|
|
|
2011-02-28 23:46:02 +00:00
|
|
|
EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0xffffff, 0xffffff, 0);
|
2010-08-02 16:49:51 +00:00
|
|
|
|
2011-02-28 23:46:02 +00:00
|
|
|
ret = IntEngCopyBits(&psurfDest->SurfObj,
|
|
|
|
&psurf->SurfObj,
|
|
|
|
NULL,
|
|
|
|
&exlo.xlo,
|
|
|
|
&rcDest,
|
|
|
|
&srcPoint);
|
2010-07-29 16:12:43 +00:00
|
|
|
|
2011-02-27 17:38:18 +00:00
|
|
|
SURFACE_ShareUnlockSurface(psurfDest);
|
|
|
|
|
2011-02-28 23:46:02 +00:00
|
|
|
if(!ret)
|
|
|
|
ScanLines = 0;
|
|
|
|
else
|
|
|
|
{
|
2012-09-30 20:30:23 +00:00
|
|
|
RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, ScanLines, bpp));
|
2011-02-28 23:46:02 +00:00
|
|
|
}
|
[WIN32SS][COMCTL32] Commit Flip_Fix_9.patch
flip_fix_9.patch fixes:
CORE-16984 " 'SPINA Thrulg' / 'SPINA Thyr' / 'Sim Thyr' have images flipped"
CORE-17194 "StretchDIBits test" isn't work correctly"
"Output of 'Project 3 Test'"
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
CORE-14671 "'Peazip' shows icons in buttons and menubar vertically flipped"
"Double Commander shoes icons flipped in buttons, menubar, listview and the treeview"
CORE-13273 "Welcome to Lazarus" icon shows flipped
CORE-13026 "'CudaText app' icon shows flipped"
Not all of those are duplicates, although they appear to be at first glance.
It affects different controls and some of those tickets do have different 'guilty revs' than others.
The patch does consist of 3 parts:
1.) win32ss/gdi/ntgdi/dibobj.c
This one is the most clean part of it, that addresses most of the flipping issues now.
2.) The hack in comctl32.h redefining the version:
We used that in the past to appease some, but not all of the issues listed above.
But it does hide additional issues, e.g. in DvDStyler, therefore we seem to still need that appeasement even today.
Most likely it would make sense to aim to avoid this part in the future.
part 2.) was committed as first appeasement on its own already into
0.4.14-RC-24-g 198b61e
0.4.13-RC-7-g 67211fa
0.4.12-RC-5-g 8449527
0.4.11-RC-16-g b906163
0.4.10-RC-7-g f1e80fe
0.4.9-RC-34-g 9d758ae
3.) toolbar.c change
That part fixes at least the toolbar case for DvDStyler
without relying on the comctl32.h hack any longer,
but it was still not enough to completely get rid of part 2.) yet.
Many thanks to all contributors: 'I_kill_Bugs', Doug Lyons and also 'Julenuri' for testing.
The patch gave nice testbot results:
KVM: https://reactos.org/testman/compare.php?ids=75704,75714
VBox: https://reactos.org/testman/compare.php?ids=75705,75715
and we also created a summary of manual test-results:
https://jira.reactos.org/browse/CORE-17415?focusedCommentId=126668&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-126668
If you read this comment via git blame and your goal is to get rid of the hack in comctl32.h, I would highly recommend
to redo the tests of that testing table, and if that is asked too much, then please test at least the following cases:
CORE-14701 "DVDStyler 3.0.4 transparent toolbars"
CORE-14701 "DVDStyler 3.0.4 erroneously black around icons of welcome-dlg"
"DVDStyler 3.0.4 erroneously black/transparent within comboboxes of properties of VMGM menu"
and try to add what might be needed to fix them, and double-check again:
"DoubleCommander optionsDlg the most complex testcase, contains flip-prone icons in treeview, listview, menubar, buttons, statics". Only some of its flipped icons were impacted by the comctl32.h change before.
2021-01-05 19:30:40 +00:00
|
|
|
/* Update if line count has changed */
|
|
|
|
if (newLines != -1)
|
|
|
|
{
|
|
|
|
ScanLines = (UINT)newLines;
|
|
|
|
}
|
2011-02-28 23:46:02 +00:00
|
|
|
GreDeleteObject(hBmpDest);
|
|
|
|
EXLATEOBJ_vCleanup(&exlo);
|
|
|
|
}
|
2017-03-04 10:37:00 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Signals success and not the actual number of scan lines*/
|
|
|
|
ScanLines = 1;
|
|
|
|
}
|
2007-10-01 11:53:31 +00:00
|
|
|
|
2010-07-29 16:12:43 +00:00
|
|
|
done:
|
2003-12-20 14:51:41 +00:00
|
|
|
|
2017-03-04 10:37:00 +00:00
|
|
|
if (pbmci)
|
|
|
|
DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci, Usage);
|
|
|
|
|
|
|
|
if (psurf)
|
|
|
|
SURFACE_ShareUnlockSurface(psurf);
|
|
|
|
|
|
|
|
if (pDC)
|
|
|
|
DC_UnlockDc(pDC);
|
2007-10-01 11:53:31 +00:00
|
|
|
|
2011-02-28 23:46:02 +00:00
|
|
|
return ScanLines;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2015-03-10 00:11:29 +00:00
|
|
|
_Success_(return!=0)
|
|
|
|
__kernel_entry
|
2012-09-30 20:30:23 +00:00
|
|
|
INT
|
|
|
|
APIENTRY
|
|
|
|
NtGdiGetDIBitsInternal(
|
|
|
|
_In_ HDC hdc,
|
|
|
|
_In_ HBITMAP hbm,
|
|
|
|
_In_ UINT iStartScan,
|
|
|
|
_In_ UINT cScans,
|
2015-03-10 00:11:29 +00:00
|
|
|
_Out_writes_bytes_opt_(cjMaxBits) LPBYTE pjBits,
|
|
|
|
_Inout_ LPBITMAPINFO pbmi,
|
2012-09-30 20:30:23 +00:00
|
|
|
_In_ UINT iUsage,
|
|
|
|
_In_ UINT cjMaxBits,
|
|
|
|
_In_ UINT cjMaxInfo)
|
|
|
|
{
|
2015-03-10 00:11:29 +00:00
|
|
|
PBITMAPINFO pbmiSafe;
|
2012-09-30 20:30:23 +00:00
|
|
|
HANDLE hSecure = NULL;
|
|
|
|
INT iResult = 0;
|
2012-09-30 22:02:02 +00:00
|
|
|
UINT cjAlloc;
|
2012-09-30 20:30:23 +00:00
|
|
|
|
|
|
|
/* Check for bad iUsage */
|
|
|
|
if (iUsage > 2) return 0;
|
|
|
|
|
|
|
|
/* Check if the size of the bitmap info is large enough */
|
2012-10-11 13:33:09 +00:00
|
|
|
if (cjMaxInfo < sizeof(BITMAPCOREHEADER))
|
2012-09-30 20:30:23 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Use maximum size */
|
|
|
|
cjMaxInfo = min(cjMaxInfo, sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD));
|
|
|
|
|
2012-09-30 21:21:03 +00:00
|
|
|
// HACK: the underlying code sucks and doesn't care for the size, so we
|
|
|
|
// give it the maximum ever needed
|
2012-09-30 22:02:02 +00:00
|
|
|
cjAlloc = sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD);
|
2012-09-30 21:21:03 +00:00
|
|
|
|
2012-09-30 20:30:23 +00:00
|
|
|
/* Allocate a buffer the bitmapinfo */
|
2015-03-10 00:11:29 +00:00
|
|
|
pbmiSafe = ExAllocatePoolWithTag(PagedPool, cjAlloc, 'imBG');
|
|
|
|
if (!pbmiSafe)
|
2012-09-30 20:30:23 +00:00
|
|
|
{
|
|
|
|
/* Fail */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Use SEH */
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
/* Probe and copy the BITMAPINFO */
|
2015-03-10 00:11:29 +00:00
|
|
|
ProbeForRead(pbmi, cjMaxInfo, 1);
|
2015-03-10 10:01:44 +00:00
|
|
|
RtlCopyMemory(pbmiSafe, pbmi, cjMaxInfo);
|
2012-09-30 20:30:23 +00:00
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
2021-07-02 22:34:43 +00:00
|
|
|
goto cleanup;
|
2012-09-30 20:30:23 +00:00
|
|
|
}
|
|
|
|
_SEH2_END;
|
|
|
|
|
|
|
|
/* Check if the header size is large enough */
|
2015-03-10 00:11:29 +00:00
|
|
|
if ((pbmiSafe->bmiHeader.biSize < sizeof(BITMAPCOREHEADER)) ||
|
|
|
|
(pbmiSafe->bmiHeader.biSize > cjMaxInfo))
|
2012-09-30 20:30:23 +00:00
|
|
|
{
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if the caller provided bitmap bits */
|
|
|
|
if (pjBits)
|
|
|
|
{
|
|
|
|
/* Secure the user mode memory */
|
|
|
|
hSecure = EngSecureMem(pjBits, cjMaxBits);
|
|
|
|
if (!hSecure)
|
|
|
|
{
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now call the internal function */
|
|
|
|
iResult = GreGetDIBitsInternal(hdc,
|
|
|
|
hbm,
|
|
|
|
iStartScan,
|
|
|
|
cScans,
|
|
|
|
pjBits,
|
2015-03-10 00:11:29 +00:00
|
|
|
pbmiSafe,
|
2012-09-30 20:30:23 +00:00
|
|
|
iUsage,
|
|
|
|
cjMaxBits,
|
|
|
|
cjMaxInfo);
|
|
|
|
|
|
|
|
/* Check for success */
|
|
|
|
if (iResult)
|
|
|
|
{
|
|
|
|
/* Use SEH to copy back to user mode */
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
2012-10-10 23:05:38 +00:00
|
|
|
/* Copy the data back */
|
2015-03-10 00:11:29 +00:00
|
|
|
cjMaxInfo = min(cjMaxInfo, (UINT)DIB_BitmapInfoSize(pbmiSafe, (WORD)iUsage));
|
|
|
|
ProbeForWrite(pbmi, cjMaxInfo, 1);
|
|
|
|
RtlCopyMemory(pbmi, pbmiSafe, cjMaxInfo);
|
2012-09-30 20:30:23 +00:00
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
/* Ignore */
|
2015-03-10 00:11:29 +00:00
|
|
|
(VOID)0;
|
2012-09-30 20:30:23 +00:00
|
|
|
}
|
|
|
|
_SEH2_END;
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (hSecure) EngUnsecureMem(hSecure);
|
2015-03-10 00:11:29 +00:00
|
|
|
ExFreePoolWithTag(pbmiSafe, 'imBG');
|
2012-09-30 20:30:23 +00:00
|
|
|
|
|
|
|
return iResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-09 15:46:13 +00:00
|
|
|
W32KAPI
|
2008-02-16 18:14:36 +00:00
|
|
|
INT
|
|
|
|
APIENTRY
|
|
|
|
NtGdiStretchDIBitsInternal(
|
2011-03-09 15:46:13 +00:00
|
|
|
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,
|
2011-12-14 04:07:06 +00:00
|
|
|
IN DWORD dwRop, // MS ntgdi.h says dwRop4(?)
|
2011-03-09 15:46:13 +00:00
|
|
|
IN UINT cjMaxInfo,
|
|
|
|
IN UINT cjMaxBits,
|
|
|
|
IN HANDLE hcmXform)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2011-03-09 15:46:13 +00:00
|
|
|
SIZEL sizel;
|
|
|
|
RECTL rcSrc, rcDst;
|
2010-08-05 21:12:57 +00:00
|
|
|
PDC pdc;
|
2011-10-06 10:56:58 +00:00
|
|
|
HBITMAP hbmTmp = 0;
|
|
|
|
PSURFACE psurfTmp = 0, psurfDst = 0;
|
|
|
|
PPALETTE ppalDIB = 0;
|
2011-03-09 15:46:13 +00:00
|
|
|
EXLATEOBJ exlo;
|
2021-07-02 22:34:43 +00:00
|
|
|
PBYTE pvBits;
|
|
|
|
|
|
|
|
LPBITMAPINFO pbmiSafe;
|
|
|
|
UINT cjAlloc;
|
|
|
|
HBITMAP hBitmap, hOldBitmap = NULL;
|
|
|
|
HDC hdcMem;
|
|
|
|
HPALETTE hPal = NULL;
|
|
|
|
ULONG BmpFormat = 0;
|
|
|
|
INT LinesCopied = 0;
|
|
|
|
|
|
|
|
/* Check for bad iUsage */
|
|
|
|
if (dwUsage > 2) return 0;
|
|
|
|
|
|
|
|
/* We must have LPBITMAPINFO */
|
|
|
|
if (!pbmi)
|
|
|
|
{
|
|
|
|
DPRINT1("Error, Invalid Parameter.\n");
|
|
|
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if the size of the bitmap info is large enough */
|
|
|
|
if (cjMaxInfo < sizeof(BITMAPCOREHEADER))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Use maximum size */
|
|
|
|
cjMaxInfo = min(cjMaxInfo, sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD));
|
|
|
|
|
|
|
|
// HACK: the underlying code sucks and doesn't care for the size, so we
|
|
|
|
// give it the maximum ever needed
|
|
|
|
cjAlloc = sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD);
|
|
|
|
|
|
|
|
/* Allocate a buffer the bitmapinfo */
|
|
|
|
pbmiSafe = ExAllocatePoolWithTag(PagedPool, cjAlloc, 'imBG');
|
|
|
|
if (!pbmiSafe)
|
|
|
|
{
|
|
|
|
/* Fail */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Use SEH */
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
/* Probe and copy the BITMAPINFO */
|
|
|
|
ProbeForRead(pbmi, cjMaxInfo, 1);
|
|
|
|
RtlCopyMemory(pbmiSafe, pbmi, cjMaxInfo);
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
ExFreePoolWithTag(pbmiSafe, 'imBG');
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
|
|
|
|
|
|
|
/* Check if the header size is large enough */
|
|
|
|
if ((pbmiSafe->bmiHeader.biSize < sizeof(BITMAPCOREHEADER)) ||
|
|
|
|
(pbmiSafe->bmiHeader.biSize > cjMaxInfo))
|
|
|
|
{
|
|
|
|
ExFreePoolWithTag(pbmiSafe, 'imBG');
|
|
|
|
return 0;
|
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
|
2011-03-09 15:46:13 +00:00
|
|
|
if (!(pdc = DC_LockDc(hdc)))
|
2011-01-09 18:11:44 +00:00
|
|
|
{
|
2011-03-09 15:46:13 +00:00
|
|
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
2011-01-09 18:11:44 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
|
2013-01-05 19:57:59 +00:00
|
|
|
/* Check for info / mem DC without surface */
|
|
|
|
if (!pdc->dclevel.pSurface)
|
|
|
|
{
|
|
|
|
DC_UnlockDc(pdc);
|
|
|
|
// CHECKME
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2011-03-09 15:46:13 +00:00
|
|
|
/* Transform dest size */
|
|
|
|
sizel.cx = cxDst;
|
|
|
|
sizel.cy = cyDst;
|
|
|
|
IntLPtoDP(pdc, (POINTL*)&sizel, 1);
|
|
|
|
DC_UnlockDc(pdc);
|
2003-12-07 10:31:56 +00:00
|
|
|
|
2013-01-05 19:57:59 +00:00
|
|
|
if (pjInit && (cjMaxBits > 0))
|
2011-03-09 15:46:13 +00:00
|
|
|
{
|
2021-07-02 22:34:43 +00:00
|
|
|
pvBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
|
2013-01-05 19:57:59 +00:00
|
|
|
if (!pvBits)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2007-04-18 00:38:36 +00:00
|
|
|
|
2013-01-05 19:57:59 +00:00
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
ProbeForRead(pjInit, cjMaxBits, 1);
|
|
|
|
RtlCopyMemory(pvBits, pjInit, cjMaxBits);
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
2021-07-02 22:34:43 +00:00
|
|
|
ExFreePoolWithTag(pvBits, TAG_DIB);
|
|
|
|
return 0;
|
2013-01-05 19:57:59 +00:00
|
|
|
}
|
2021-07-02 22:34:43 +00:00
|
|
|
_SEH2_END;
|
2011-10-06 10:56:58 +00:00
|
|
|
}
|
2013-01-05 19:57:59 +00:00
|
|
|
else
|
2011-10-06 10:56:58 +00:00
|
|
|
{
|
2013-01-05 19:57:59 +00:00
|
|
|
pvBits = NULL;
|
2011-10-06 10:56:58 +00:00
|
|
|
}
|
|
|
|
|
2021-07-02 22:34:43 +00:00
|
|
|
/* Here we select between the dwRop with SRCCOPY or not. */
|
|
|
|
if (dwRop == SRCCOPY)
|
2011-02-19 22:29:31 +00:00
|
|
|
{
|
2021-07-02 22:34:43 +00:00
|
|
|
hdcMem = NtGdiCreateCompatibleDC(hdc);
|
|
|
|
if (hdcMem == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("NtGdiCreateCompatibleDC failed to create hdc.\n");
|
|
|
|
EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
|
|
|
|
return 0;
|
|
|
|
}
|
2008-06-07 11:35:53 +00:00
|
|
|
|
2021-07-02 22:34:43 +00:00
|
|
|
hBitmap = NtGdiCreateCompatibleBitmap(hdc,
|
|
|
|
abs(pbmiSafe->bmiHeader.biWidth),
|
|
|
|
abs(pbmiSafe->bmiHeader.biHeight));
|
|
|
|
if (hBitmap == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("NtGdiCreateCompatibleBitmap failed to create bitmap.\n");
|
|
|
|
DPRINT1("hdc : 0x%08x \n", hdc);
|
|
|
|
DPRINT1("width : 0x%08x \n", pbmiSafe->bmiHeader.biWidth);
|
|
|
|
DPRINT1("height : 0x%08x \n", pbmiSafe->bmiHeader.biHeight);
|
|
|
|
EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
|
|
|
|
return 0;
|
|
|
|
}
|
2012-09-30 20:30:23 +00:00
|
|
|
|
2021-07-02 22:34:43 +00:00
|
|
|
/* Select the bitmap into hdcMem, and save a handle to the old bitmap */
|
|
|
|
hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
|
2016-12-22 17:34:58 +00:00
|
|
|
|
2021-07-02 22:34:43 +00:00
|
|
|
if (dwUsage == DIB_PAL_COLORS)
|
|
|
|
{
|
|
|
|
hPal = NtGdiGetDCObject(hdc, GDI_OBJECT_TYPE_PALETTE);
|
|
|
|
hPal = GdiSelectPalette(hdcMem, hPal, FALSE);
|
|
|
|
}
|
2011-10-06 10:56:58 +00:00
|
|
|
|
2021-07-02 22:34:43 +00:00
|
|
|
pdc = DC_LockDc(hdcMem);
|
|
|
|
if (pdc != NULL)
|
|
|
|
{
|
|
|
|
IntSetDIBits(pdc, hBitmap, 0, abs(pbmiSafe->bmiHeader.biHeight), pvBits,
|
|
|
|
cjMaxBits, pbmiSafe, dwUsage);
|
|
|
|
DC_UnlockDc(pdc);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Origin for DIBitmap may be bottom left (positive biHeight) or top
|
|
|
|
left (negative biHeight) */
|
|
|
|
if (cxSrc == cxDst && cySrc == cyDst)
|
|
|
|
{
|
|
|
|
NtGdiBitBlt(hdc, xDst, yDst, cxDst, cyDst,
|
|
|
|
hdcMem, xSrc, abs(pbmiSafe->bmiHeader.biHeight) - cySrc - ySrc,
|
|
|
|
dwRop, 0, 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NtGdiStretchBlt(hdc, xDst, yDst, cxDst, cyDst,
|
|
|
|
hdcMem, xSrc, abs(pbmiSafe->bmiHeader.biHeight) - cySrc - ySrc,
|
|
|
|
cxSrc, cySrc, dwRop, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* cleanup */
|
|
|
|
if (hPal)
|
|
|
|
GdiSelectPalette(hdcMem, hPal, FALSE);
|
|
|
|
|
|
|
|
if (hOldBitmap)
|
|
|
|
NtGdiSelectBitmap(hdcMem, hOldBitmap);
|
|
|
|
|
|
|
|
NtGdiDeleteObjectApp(hdcMem);
|
|
|
|
GreDeleteObject(hBitmap);
|
|
|
|
|
|
|
|
} /* End of dwRop == SRCCOPY */
|
|
|
|
else
|
|
|
|
{ /* Start of dwRop != SRCCOPY */
|
|
|
|
/* FIXME: Locking twice is cheesy, coord tranlation in UM will fix it */
|
|
|
|
if (!(pdc = DC_LockDc(hdc)))
|
|
|
|
{
|
|
|
|
DPRINT1("Could not lock dc\n");
|
|
|
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
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);
|
|
|
|
|
|
|
|
if (pdc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR))
|
|
|
|
{
|
|
|
|
IntUpdateBoundsRect(pdc, &rcDst);
|
|
|
|
}
|
|
|
|
|
|
|
|
BmpFormat = BitmapFormat(pbmiSafe->bmiHeader.biBitCount,
|
|
|
|
pbmiSafe->bmiHeader.biCompression);
|
|
|
|
|
|
|
|
hbmTmp = GreCreateBitmapEx(pbmiSafe->bmiHeader.biWidth,
|
|
|
|
abs(pbmiSafe->bmiHeader.biHeight),
|
|
|
|
0,
|
|
|
|
BmpFormat,
|
|
|
|
pbmiSafe->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
|
|
|
|
cjMaxBits,
|
|
|
|
pvBits,
|
|
|
|
0);
|
|
|
|
|
|
|
|
if (!hbmTmp)
|
|
|
|
{
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
psurfTmp = SURFACE_ShareLockSurface(hbmTmp);
|
|
|
|
if (!psurfTmp)
|
|
|
|
{
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create a palette for the DIB */
|
|
|
|
ppalDIB = CreateDIBPalette(pbmiSafe, pdc, dwUsage);
|
|
|
|
if (!ppalDIB)
|
|
|
|
{
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Prepare DC for blit */
|
|
|
|
DC_vPrepareDCsForBlit(pdc, &rcDst, NULL, NULL);
|
|
|
|
|
|
|
|
psurfDst = pdc->dclevel.pSurface;
|
|
|
|
|
|
|
|
/* Initialize XLATEOBJ */
|
|
|
|
EXLATEOBJ_vInitialize(&exlo,
|
|
|
|
ppalDIB,
|
|
|
|
psurfDst->ppal,
|
|
|
|
RGB(0xff, 0xff, 0xff),
|
|
|
|
pdc->pdcattr->crBackgroundClr,
|
|
|
|
pdc->pdcattr->crForegroundClr);
|
|
|
|
|
|
|
|
/* Perform the stretch operation */
|
|
|
|
IntEngStretchBlt(&psurfDst->SurfObj,
|
|
|
|
&psurfTmp->SurfObj,
|
|
|
|
NULL,
|
|
|
|
(CLIPOBJ *)&pdc->co,
|
|
|
|
&exlo.xlo,
|
|
|
|
&pdc->dclevel.ca,
|
|
|
|
&rcDst,
|
|
|
|
&rcSrc,
|
|
|
|
NULL,
|
|
|
|
&pdc->eboFill.BrushObject,
|
|
|
|
NULL,
|
|
|
|
WIN32_ROP3_TO_ENG_ROP4(dwRop));
|
|
|
|
|
|
|
|
/* Cleanup */
|
|
|
|
DC_vFinishBlit(pdc, NULL);
|
|
|
|
EXLATEOBJ_vCleanup(&exlo);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
|
|
|
|
if (psurfTmp) SURFACE_ShareUnlockSurface(psurfTmp);
|
|
|
|
if (hbmTmp) GreDeleteObject(hbmTmp);
|
|
|
|
if (pdc) DC_UnlockDc(pdc);
|
2011-10-06 10:56:58 +00:00
|
|
|
}
|
|
|
|
|
2021-07-02 22:34:43 +00:00
|
|
|
if (pbmiSafe) ExFreePoolWithTag(pbmiSafe, 'imBG');
|
|
|
|
if (pvBits) ExFreePoolWithTag(pvBits, TAG_DIB);
|
|
|
|
|
|
|
|
/* This is not what MSDN says is returned from this function, but it
|
|
|
|
* follows Wine's dlls/gdi32/dib.c function nulldrv_StretchDIBits
|
|
|
|
* and it fixes over 100 gdi32:dib regression tests. */
|
|
|
|
if (dwRop == SRCCOPY)
|
2011-10-06 10:56:58 +00:00
|
|
|
{
|
2021-07-02 22:34:43 +00:00
|
|
|
LinesCopied = abs(pbmiSafe->bmiHeader.biHeight);
|
2011-10-06 10:56:58 +00:00
|
|
|
}
|
2021-07-02 22:34:43 +00:00
|
|
|
else
|
2011-10-06 10:56:58 +00:00
|
|
|
{
|
2021-07-02 22:34:43 +00:00
|
|
|
LinesCopied = pbmiSafe->bmiHeader.biHeight;
|
2011-10-06 10:56:58 +00:00
|
|
|
}
|
|
|
|
|
2021-07-02 22:34:43 +00:00
|
|
|
return LinesCopied;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-30 22:37:42 +00:00
|
|
|
HBITMAP
|
|
|
|
FASTCALL
|
2009-06-10 00:23:15 +00:00
|
|
|
IntCreateDIBitmap(
|
|
|
|
PDC Dc,
|
|
|
|
INT width,
|
|
|
|
INT height,
|
2014-10-24 17:31:46 +00:00
|
|
|
UINT planes,
|
2009-06-10 00:23:15 +00:00
|
|
|
UINT bpp,
|
2014-10-24 17:31:46 +00:00
|
|
|
ULONG compression,
|
2009-06-10 00:23:15 +00:00
|
|
|
DWORD init,
|
|
|
|
LPBYTE bits,
|
2015-12-23 14:55:34 +00:00
|
|
|
ULONG cjMaxBits,
|
2010-08-01 12:17:35 +00:00
|
|
|
PBITMAPINFO data,
|
2009-06-10 00:23:15 +00:00
|
|
|
DWORD coloruse)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
HBITMAP handle;
|
|
|
|
BOOL fColor;
|
2014-10-24 17:31:46 +00:00
|
|
|
ULONG BmpFormat = 0;
|
|
|
|
|
|
|
|
if (planes && bpp)
|
|
|
|
BmpFormat = BitmapFormat(planes * bpp, compression);
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
// Check if we should create a monochrome or color bitmap. We create a monochrome bitmap only if it has exactly 2
|
|
|
|
// colors, which are black followed by white, nothing else. In all other cases, we create a color bitmap.
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2014-10-24 17:31:46 +00:00
|
|
|
if (BmpFormat != BMF_1BPP) fColor = TRUE;
|
2014-10-24 18:45:25 +00:00
|
|
|
else if ((coloruse > DIB_RGB_COLORS) || ((init & CBM_INIT) == 0) || !data) fColor = FALSE;
|
2009-06-10 00:23:15 +00:00
|
|
|
else
|
2001-08-28 18:16:32 +00:00
|
|
|
{
|
2010-08-01 12:17:35 +00:00
|
|
|
const RGBQUAD *rgb = (RGBQUAD*)((PBYTE)data + data->bmiHeader.biSize);
|
2010-06-09 00:08:50 +00:00
|
|
|
DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
|
2004-03-15 22:06:55 +00:00
|
|
|
|
2010-06-09 00:08:50 +00:00
|
|
|
// Check if the first color of the colormap is black
|
2014-10-16 19:14:52 +00:00
|
|
|
if (col == RGB(0, 0, 0))
|
2009-06-10 00:23:15 +00:00
|
|
|
{
|
2010-06-09 00:08:50 +00:00
|
|
|
rgb++;
|
|
|
|
col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
|
2009-06-10 00:23:15 +00:00
|
|
|
|
2010-06-09 00:08:50 +00:00
|
|
|
// If the second color is white, create a monochrome bitmap
|
|
|
|
fColor = (col != RGB(0xff,0xff,0xff));
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
2010-06-09 00:08:50 +00:00
|
|
|
else fColor = TRUE;
|
2009-01-28 13:55:37 +00:00
|
|
|
}
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
// Now create the bitmap
|
|
|
|
if (fColor)
|
|
|
|
{
|
2014-10-24 17:31:46 +00:00
|
|
|
if (init & CBM_CREATDIB)
|
|
|
|
{
|
2014-10-25 18:11:36 +00:00
|
|
|
PSURFACE Surface;
|
|
|
|
PPALETTE Palette;
|
|
|
|
|
2014-10-24 17:31:46 +00:00
|
|
|
/* Undocumented flag which creates a DDB of the format specified by the bitmap info. */
|
|
|
|
handle = IntCreateCompatibleBitmap(Dc, width, height, planes, bpp);
|
2014-10-25 18:11:36 +00:00
|
|
|
if (!handle)
|
2015-12-29 20:28:23 +00:00
|
|
|
{
|
|
|
|
DPRINT1("IntCreateCompatibleBitmap() failed!\n");
|
2014-10-25 18:11:36 +00:00
|
|
|
return NULL;
|
2015-12-29 20:28:23 +00:00
|
|
|
}
|
|
|
|
|
2014-10-25 18:11:36 +00:00
|
|
|
/* The palette must also match the given data */
|
|
|
|
Surface = SURFACE_ShareLockSurface(handle);
|
|
|
|
ASSERT(Surface);
|
|
|
|
Palette = CreateDIBPalette(data, Dc, coloruse);
|
|
|
|
ASSERT(Palette);
|
|
|
|
SURFACE_vSetPalette(Surface, Palette);
|
|
|
|
|
|
|
|
PALETTE_ShareUnlockPalette(Palette);
|
|
|
|
SURFACE_ShareUnlockSurface(Surface);
|
2014-10-24 17:31:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Create a regular compatible bitmap, in the same format as the device */
|
|
|
|
handle = IntCreateCompatibleBitmap(Dc, width, height, 0, 0);
|
|
|
|
}
|
2001-08-28 18:16:32 +00:00
|
|
|
}
|
2009-01-28 13:55:37 +00:00
|
|
|
else
|
|
|
|
{
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
handle = GreCreateBitmap(width,
|
2015-03-25 22:26:52 +00:00
|
|
|
abs(height),
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
1,
|
|
|
|
1,
|
|
|
|
NULL);
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (height < 0)
|
|
|
|
height = -height;
|
|
|
|
|
2014-10-24 17:31:46 +00:00
|
|
|
if ((NULL != handle) && (CBM_INIT & init))
|
2009-06-10 00:23:15 +00:00
|
|
|
{
|
2015-12-23 14:55:34 +00:00
|
|
|
IntSetDIBits(Dc, handle, 0, height, bits, cjMaxBits, data, coloruse);
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return handle;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2004-03-15 22:06:55 +00:00
|
|
|
// The CreateDIBitmap function creates a device-dependent bitmap (DDB) from a DIB and, optionally, sets the bitmap bits
|
|
|
|
// The DDB that is created will be whatever bit depth your reference DC is
|
2008-03-30 22:37:42 +00:00
|
|
|
HBITMAP
|
|
|
|
APIENTRY
|
2009-06-10 00:23:15 +00:00
|
|
|
NtGdiCreateDIBitmapInternal(
|
|
|
|
IN HDC hDc,
|
|
|
|
IN INT cx,
|
|
|
|
IN INT cy,
|
|
|
|
IN DWORD fInit,
|
|
|
|
IN OPTIONAL LPBYTE pjInit,
|
|
|
|
IN OPTIONAL LPBITMAPINFO pbmi,
|
|
|
|
IN DWORD iUsage,
|
|
|
|
IN UINT cjMaxInitInfo,
|
|
|
|
IN UINT cjMaxBits,
|
|
|
|
IN FLONG fl,
|
|
|
|
IN HANDLE hcmXform)
|
2004-03-15 22:06:55 +00:00
|
|
|
{
|
2010-06-09 00:08:50 +00:00
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2011-02-28 23:46:02 +00:00
|
|
|
PBYTE safeBits = NULL;
|
|
|
|
HBITMAP hbmResult = NULL;
|
|
|
|
|
2016-01-03 16:16:04 +00:00
|
|
|
if (pjInit == NULL)
|
|
|
|
{
|
|
|
|
fInit &= ~CBM_INIT;
|
|
|
|
}
|
|
|
|
|
2014-10-24 18:45:25 +00:00
|
|
|
if(pjInit && (fInit & CBM_INIT))
|
2011-02-28 23:46:02 +00:00
|
|
|
{
|
2012-05-08 16:21:27 +00:00
|
|
|
if (cjMaxBits == 0) return NULL;
|
2011-02-28 23:46:02 +00:00
|
|
|
safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
|
|
|
|
if(!safeBits)
|
|
|
|
{
|
2015-12-29 20:28:23 +00:00
|
|
|
DPRINT1("Failed to allocate %lu bytes\n", cjMaxBits);
|
2011-02-28 23:46:02 +00:00
|
|
|
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
2010-06-09 00:08:50 +00:00
|
|
|
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
2010-08-01 12:17:35 +00:00
|
|
|
if(pbmi) ProbeForRead(pbmi, cjMaxInitInfo, 1);
|
2014-10-24 18:45:25 +00:00
|
|
|
if(pjInit && (fInit & CBM_INIT))
|
2011-02-28 23:46:02 +00:00
|
|
|
{
|
|
|
|
ProbeForRead(pjInit, cjMaxBits, 1);
|
|
|
|
RtlCopyMemory(safeBits, pjInit, cjMaxBits);
|
|
|
|
}
|
2010-06-09 00:08:50 +00:00
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
Status = _SEH2_GetExceptionCode();
|
|
|
|
}
|
2021-07-02 22:34:43 +00:00
|
|
|
_SEH2_END;
|
2010-06-09 00:08:50 +00:00
|
|
|
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
2015-12-29 20:28:23 +00:00
|
|
|
DPRINT1("Got an exception! pjInit = %p\n", pjInit);
|
2010-06-09 00:08:50 +00:00
|
|
|
SetLastNtError(Status);
|
2011-02-28 23:46:02 +00:00
|
|
|
goto cleanup;
|
2010-06-09 00:08:50 +00:00
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
|
2010-09-01 22:36:00 +00:00
|
|
|
hbmResult = GreCreateDIBitmapInternal(hDc,
|
2011-02-28 23:46:02 +00:00
|
|
|
cx,
|
|
|
|
cy,
|
|
|
|
fInit,
|
2010-09-01 22:36:00 +00:00
|
|
|
safeBits,
|
|
|
|
pbmi,
|
|
|
|
iUsage,
|
|
|
|
fl,
|
2012-05-04 17:37:07 +00:00
|
|
|
cjMaxBits,
|
2010-09-01 22:36:00 +00:00
|
|
|
hcmXform);
|
|
|
|
|
|
|
|
cleanup:
|
2011-02-28 23:46:02 +00:00
|
|
|
if (safeBits) ExFreePoolWithTag(safeBits, TAG_DIB);
|
|
|
|
return hbmResult;
|
2010-06-10 11:36:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
HBITMAP
|
2012-05-04 17:37:07 +00:00
|
|
|
NTAPI
|
2010-06-10 11:36:20 +00:00
|
|
|
GreCreateDIBitmapInternal(
|
|
|
|
IN HDC hDc,
|
|
|
|
IN INT cx,
|
|
|
|
IN INT cy,
|
|
|
|
IN DWORD fInit,
|
|
|
|
IN OPTIONAL LPBYTE pjInit,
|
2010-08-01 12:17:35 +00:00
|
|
|
IN OPTIONAL PBITMAPINFO pbmi,
|
2010-06-10 11:36:20 +00:00
|
|
|
IN DWORD iUsage,
|
|
|
|
IN FLONG fl,
|
2012-05-04 17:37:07 +00:00
|
|
|
IN UINT cjMaxBits,
|
2010-06-10 11:36:20 +00:00
|
|
|
IN HANDLE hcmXform)
|
|
|
|
{
|
|
|
|
PDC Dc;
|
|
|
|
HBITMAP Bmp;
|
2014-10-24 17:31:46 +00:00
|
|
|
USHORT bpp, planes;
|
|
|
|
DWORD compression;
|
2010-06-10 14:32:05 +00:00
|
|
|
HDC hdcDest;
|
2010-06-10 11:36:20 +00:00
|
|
|
|
2010-06-10 14:32:05 +00:00
|
|
|
if (!hDc) /* 1bpp monochrome bitmap */
|
2011-02-28 23:46:02 +00:00
|
|
|
{
|
|
|
|
// Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
|
2010-08-02 14:45:51 +00:00
|
|
|
hdcDest = NtGdiCreateCompatibleDC(0);
|
2010-06-10 14:32:05 +00:00
|
|
|
if(!hdcDest)
|
2009-06-10 00:23:15 +00:00
|
|
|
{
|
2015-12-29 20:28:23 +00:00
|
|
|
DPRINT1("NtGdiCreateCompatibleDC failed\n");
|
2009-06-10 00:23:15 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2010-06-10 14:32:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hdcDest = hDc;
|
|
|
|
}
|
2006-09-03 18:16:08 +00:00
|
|
|
|
2010-06-10 14:32:05 +00:00
|
|
|
Dc = DC_LockDc(hdcDest);
|
|
|
|
if (!Dc)
|
|
|
|
{
|
2015-12-29 20:28:23 +00:00
|
|
|
DPRINT1("Failed to lock hdcDest %p\n", hdcDest);
|
2010-12-25 11:01:14 +00:00
|
|
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
2010-06-10 14:32:05 +00:00
|
|
|
return NULL;
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
2010-06-10 14:32:05 +00:00
|
|
|
/* 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)
|
2014-10-24 17:31:46 +00:00
|
|
|
{
|
2014-10-24 18:45:25 +00:00
|
|
|
if (pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
|
|
|
{
|
|
|
|
BITMAPCOREHEADER* CoreHeader = (BITMAPCOREHEADER*)&pbmi->bmiHeader;
|
|
|
|
bpp = CoreHeader->bcBitCount;
|
2014-10-25 18:11:36 +00:00
|
|
|
planes = CoreHeader->bcPlanes ? CoreHeader->bcPlanes : 1;
|
2014-10-24 18:45:25 +00:00
|
|
|
compression = BI_RGB;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bpp = pbmi->bmiHeader.biBitCount;
|
2014-10-25 18:11:36 +00:00
|
|
|
planes = pbmi->bmiHeader.biPlanes ? pbmi->bmiHeader.biPlanes : 1;
|
2014-10-24 18:45:25 +00:00
|
|
|
compression = pbmi->bmiHeader.biCompression;
|
|
|
|
}
|
2014-10-24 17:31:46 +00:00
|
|
|
}
|
2010-06-10 14:32:05 +00:00
|
|
|
else
|
2014-10-24 17:31:46 +00:00
|
|
|
{
|
2010-06-10 14:32:05 +00:00
|
|
|
bpp = 0;
|
2014-10-24 17:31:46 +00:00
|
|
|
planes = 0;
|
|
|
|
compression = 0;
|
|
|
|
}
|
2015-12-23 14:55:34 +00:00
|
|
|
Bmp = IntCreateDIBitmap(Dc, cx, cy, planes, bpp, compression, fInit, pjInit, cjMaxBits, pbmi, iUsage);
|
2010-06-10 14:32:05 +00:00
|
|
|
DC_UnlockDc(Dc);
|
|
|
|
|
|
|
|
if(!hDc)
|
2009-06-10 00:23:15 +00:00
|
|
|
{
|
2010-06-10 14:32:05 +00:00
|
|
|
NtGdiDeleteObjectApp(hdcDest);
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
|
|
|
return Bmp;
|
2004-03-15 22:06:55 +00:00
|
|
|
}
|
|
|
|
|
2015-03-25 22:27:16 +00:00
|
|
|
HBITMAP
|
|
|
|
NTAPI
|
|
|
|
GreCreateDIBitmapFromPackedDIB(
|
|
|
|
_In_reads_(cjPackedDIB )PVOID pvPackedDIB,
|
|
|
|
_In_ UINT cjPackedDIB,
|
|
|
|
_In_ ULONG uUsage)
|
|
|
|
{
|
|
|
|
PBITMAPINFO pbmi;
|
|
|
|
PBYTE pjBits;
|
|
|
|
UINT cjInfo, cjBits;
|
|
|
|
HBITMAP hbm;
|
|
|
|
|
|
|
|
/* We only support BITMAPINFOHEADER, make sure the size is ok */
|
|
|
|
if (cjPackedDIB < sizeof(BITMAPINFOHEADER))
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The packed DIB starts with the BITMAPINFOHEADER */
|
|
|
|
pbmi = pvPackedDIB;
|
|
|
|
|
|
|
|
if (cjPackedDIB < pbmi->bmiHeader.biSize)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate the info size and make sure the packed DIB is large enough */
|
|
|
|
cjInfo = DIB_BitmapInfoSize(pbmi, uUsage);
|
|
|
|
if (cjPackedDIB <= cjInfo)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The bitmap bits start after the header */
|
|
|
|
pjBits = (PBYTE)pvPackedDIB + cjInfo;
|
|
|
|
cjBits = cjPackedDIB - cjInfo;
|
|
|
|
|
|
|
|
hbm = GreCreateDIBitmapInternal(NULL,
|
|
|
|
pbmi->bmiHeader.biWidth,
|
|
|
|
abs(pbmi->bmiHeader.biHeight),
|
|
|
|
CBM_INIT | CBM_CREATDIB,
|
|
|
|
pjBits,
|
|
|
|
pbmi,
|
|
|
|
uUsage,
|
|
|
|
0,
|
|
|
|
cjBits,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
return hbm;
|
|
|
|
}
|
2008-03-30 22:37:42 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
HBITMAP
|
|
|
|
APIENTRY
|
|
|
|
NtGdiCreateDIBSection(
|
|
|
|
IN HDC hDC,
|
|
|
|
IN OPTIONAL HANDLE hSection,
|
|
|
|
IN DWORD dwOffset,
|
2010-07-29 16:12:43 +00:00
|
|
|
IN BITMAPINFO* bmi,
|
2009-06-10 00:23:15 +00:00
|
|
|
IN DWORD Usage,
|
|
|
|
IN UINT cjHeader,
|
|
|
|
IN FLONG fl,
|
|
|
|
IN ULONG_PTR dwColorSpace,
|
|
|
|
OUT PVOID *Bits)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
HBITMAP hbitmap = 0;
|
|
|
|
DC *dc;
|
|
|
|
BOOL bDesktopDC = FALSE;
|
2011-02-28 23:46:02 +00:00
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2009-06-10 00:23:15 +00:00
|
|
|
|
|
|
|
if (!bmi) return hbitmap; // Make sure.
|
|
|
|
|
2011-02-28 23:46:02 +00:00
|
|
|
_SEH2_TRY
|
2010-07-25 11:35:45 +00:00
|
|
|
{
|
2010-07-29 16:12:43 +00:00
|
|
|
ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1);
|
2011-02-28 23:46:02 +00:00
|
|
|
ProbeForRead(bmi, bmi->bmiHeader.biSize, 1);
|
2012-03-04 11:32:43 +00:00
|
|
|
ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, (WORD)Usage), 1);
|
2010-07-25 11:35:45 +00:00
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
Status = _SEH2_GetExceptionCode();
|
|
|
|
}
|
2021-07-02 22:34:43 +00:00
|
|
|
_SEH2_END;
|
2010-07-25 11:35:45 +00:00
|
|
|
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
// If the reference hdc is null, take the desktop dc
|
|
|
|
if (hDC == 0)
|
|
|
|
{
|
|
|
|
hDC = NtGdiCreateCompatibleDC(0);
|
|
|
|
bDesktopDC = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((dc = DC_LockDc(hDC)))
|
|
|
|
{
|
|
|
|
hbitmap = DIB_CreateDIBSection(dc,
|
2010-07-29 16:12:43 +00:00
|
|
|
bmi,
|
2009-06-10 00:23:15 +00:00
|
|
|
Usage,
|
|
|
|
Bits,
|
|
|
|
hSection,
|
|
|
|
dwOffset,
|
|
|
|
0);
|
|
|
|
DC_UnlockDc(dc);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-12-25 11:01:14 +00:00
|
|
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
if (bDesktopDC)
|
|
|
|
NtGdiDeleteObjectApp(hDC);
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
return hbitmap;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
HBITMAP
|
|
|
|
APIENTRY
|
2003-05-18 17:16:18 +00:00
|
|
|
DIB_CreateDIBSection(
|
2009-06-10 00:23:15 +00:00
|
|
|
PDC dc,
|
2010-07-29 16:12:43 +00:00
|
|
|
CONST BITMAPINFO *bmi,
|
2009-06-10 00:23:15 +00:00
|
|
|
UINT usage,
|
|
|
|
LPVOID *bits,
|
|
|
|
HANDLE section,
|
|
|
|
DWORD offset,
|
|
|
|
DWORD ovr_pitch)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
HBITMAP res = 0;
|
|
|
|
SURFACE *bmp = NULL;
|
|
|
|
void *mapBits = NULL;
|
2012-10-10 23:05:38 +00:00
|
|
|
PPALETTE ppalDIB = NULL;
|
2009-06-10 00:23:15 +00:00
|
|
|
|
|
|
|
// Fill BITMAP32 structure with DIB data
|
2010-07-29 16:12:43 +00:00
|
|
|
CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader;
|
2009-06-10 00:23:15 +00:00
|
|
|
INT effHeight;
|
|
|
|
ULONG totalSize;
|
|
|
|
BITMAP bm;
|
2011-09-11 16:56:56 +00:00
|
|
|
//SIZEL Size;
|
2009-06-10 00:23:15 +00:00
|
|
|
HANDLE hSecure;
|
|
|
|
|
2012-07-31 20:44:56 +00:00
|
|
|
DPRINT("format (%ld,%ld), planes %u, bpp %u, size %lu, colors %lu (%s)\n",
|
2010-07-29 16:12:43 +00:00
|
|
|
bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
|
|
|
|
bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
|
2009-06-10 00:23:15 +00:00
|
|
|
|
|
|
|
/* CreateDIBSection should fail for compressed formats */
|
2010-07-29 16:12:43 +00:00
|
|
|
if (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8)
|
2009-06-10 00:23:15 +00:00
|
|
|
{
|
2011-03-07 10:00:27 +00:00
|
|
|
DPRINT1("no compressed format allowed\n");
|
2009-06-10 00:23:15 +00:00
|
|
|
return (HBITMAP)NULL;
|
|
|
|
}
|
|
|
|
|
2010-07-29 16:12:43 +00:00
|
|
|
effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
|
2009-06-10 00:23:15 +00:00
|
|
|
bm.bmType = 0;
|
2010-07-29 16:12:43 +00:00
|
|
|
bm.bmWidth = bi->biWidth;
|
2009-06-10 00:23:15 +00:00
|
|
|
bm.bmHeight = effHeight;
|
2010-09-01 16:52:23 +00:00
|
|
|
bm.bmWidthBytes = ovr_pitch ? ovr_pitch : WIDTH_BYTES_ALIGN32(bm.bmWidth, bi->biBitCount);
|
2009-06-10 00:23:15 +00:00
|
|
|
|
2010-07-29 16:12:43 +00:00
|
|
|
bm.bmPlanes = bi->biPlanes;
|
|
|
|
bm.bmBitsPixel = bi->biBitCount;
|
2009-06-10 00:23:15 +00:00
|
|
|
bm.bmBits = NULL;
|
|
|
|
|
|
|
|
// 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.
|
2015-03-08 17:25:44 +00:00
|
|
|
totalSize = (bi->biSizeImage && (bi->biCompression != BI_RGB) && (bi->biCompression != BI_BITFIELDS))
|
2010-07-29 16:12:43 +00:00
|
|
|
? bi->biSizeImage : (ULONG)(bm.bmWidthBytes * effHeight);
|
2009-06-10 00:23:15 +00:00
|
|
|
|
|
|
|
if (section)
|
|
|
|
{
|
|
|
|
SYSTEM_BASIC_INFORMATION Sbi;
|
|
|
|
NTSTATUS Status;
|
|
|
|
DWORD mapOffset;
|
|
|
|
LARGE_INTEGER SectionOffset;
|
|
|
|
SIZE_T mapSize;
|
|
|
|
|
|
|
|
Status = ZwQuerySystemInformation(SystemBasicInformation,
|
|
|
|
&Sbi,
|
|
|
|
sizeof Sbi,
|
|
|
|
0);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2011-03-07 10:00:27 +00:00
|
|
|
DPRINT1("ZwQuerySystemInformation failed (0x%lx)\n", Status);
|
2009-06-10 00:23:15 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
mapOffset = offset - (offset % Sbi.AllocationGranularity);
|
2015-03-08 17:25:44 +00:00
|
|
|
mapSize = totalSize + (offset - mapOffset);
|
2009-06-10 00:23:15 +00:00
|
|
|
|
|
|
|
SectionOffset.LowPart = mapOffset;
|
|
|
|
SectionOffset.HighPart = 0;
|
|
|
|
|
|
|
|
Status = ZwMapViewOfSection(section,
|
|
|
|
NtCurrentProcess(),
|
|
|
|
&mapBits,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&SectionOffset,
|
|
|
|
&mapSize,
|
|
|
|
ViewShare,
|
|
|
|
0,
|
|
|
|
PAGE_READWRITE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2011-03-07 10:00:27 +00:00
|
|
|
DPRINT1("ZwMapViewOfSection failed (0x%lx)\n", Status);
|
2010-12-25 11:01:14 +00:00
|
|
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
2009-06-10 00:23:15 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mapBits) bm.bmBits = (char *)mapBits + (offset - mapOffset);
|
|
|
|
}
|
|
|
|
else if (ovr_pitch && offset)
|
2018-03-18 14:53:52 +00:00
|
|
|
bm.bmBits = UlongToPtr(offset);
|
2009-06-10 00:23:15 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
offset = 0;
|
|
|
|
bm.bmBits = EngAllocUserMem(totalSize, 0);
|
2011-03-07 10:00:27 +00:00
|
|
|
if(!bm.bmBits)
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to allocate memory\n");
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-01-09 02:06:39 +00:00
|
|
|
// hSecure = MmSecureVirtualMemory(bm.bmBits, totalSize, PAGE_READWRITE);
|
2009-06-10 00:23:15 +00:00
|
|
|
hSecure = (HANDLE)0x1; // HACK OF UNIMPLEMENTED KERNEL STUFF !!!!
|
2009-01-09 02:06:39 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2008-10-01 10:05:02 +00:00
|
|
|
// Create Device Dependent Bitmap and add DIB pointer
|
2011-09-11 16:56:56 +00:00
|
|
|
//Size.cx = bm.bmWidth;
|
|
|
|
//Size.cy = abs(bm.bmHeight);
|
2010-06-07 15:55:03 +00:00
|
|
|
res = GreCreateBitmapEx(bm.bmWidth,
|
|
|
|
abs(bm.bmHeight),
|
|
|
|
bm.bmWidthBytes,
|
2010-07-29 16:12:43 +00:00
|
|
|
BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
|
2010-06-07 15:55:03 +00:00
|
|
|
BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
|
2011-03-09 15:46:13 +00:00
|
|
|
((bi->biHeight < 0) ? BMF_TOPDOWN : 0),
|
2015-03-08 17:25:44 +00:00
|
|
|
totalSize,
|
2010-08-02 00:53:25 +00:00
|
|
|
bm.bmBits,
|
2011-02-28 23:46:02 +00:00
|
|
|
0);
|
2009-06-10 00:23:15 +00:00
|
|
|
if (!res)
|
2008-11-20 15:11:43 +00:00
|
|
|
{
|
2011-03-07 10:00:27 +00:00
|
|
|
DPRINT1("GreCreateBitmapEx failed\n");
|
2010-12-25 11:01:14 +00:00
|
|
|
EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
|
2010-07-25 11:35:45 +00:00
|
|
|
goto cleanup;
|
2008-11-20 15:11:43 +00:00
|
|
|
}
|
2011-04-15 15:29:08 +00:00
|
|
|
bmp = SURFACE_ShareLockSurface(res); // HACK
|
2003-08-31 07:56:24 +00:00
|
|
|
if (NULL == bmp)
|
2008-11-20 15:11:43 +00:00
|
|
|
{
|
2011-03-07 10:00:27 +00:00
|
|
|
DPRINT1("SURFACE_LockSurface failed\n");
|
2011-02-28 23:46:02 +00:00
|
|
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
2010-07-25 11:35:45 +00:00
|
|
|
goto cleanup;
|
2008-11-20 15:11:43 +00:00
|
|
|
}
|
2002-09-24 20:22:10 +00:00
|
|
|
|
2008-11-20 15:11:43 +00:00
|
|
|
/* 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. */
|
2009-01-28 11:55:56 +00:00
|
|
|
bmp->hDIBSection = section;
|
|
|
|
bmp->hSecure = hSecure;
|
|
|
|
bmp->dwOffset = offset;
|
2010-06-05 21:19:41 +00:00
|
|
|
bmp->flags = API_BITMAP;
|
2010-07-29 16:12:43 +00:00
|
|
|
bmp->biClrImportant = bi->biClrImportant;
|
2009-01-28 11:55:56 +00:00
|
|
|
|
2012-05-05 21:39:35 +00:00
|
|
|
/* Create a palette for the DIB */
|
|
|
|
ppalDIB = CreateDIBPalette(bmi, dc, usage);
|
2010-05-12 22:56:24 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
// Clean up in case of errors
|
2010-07-25 11:35:45 +00:00
|
|
|
cleanup:
|
2012-10-10 23:05:38 +00:00
|
|
|
if (!res || !bmp || !bm.bmBits || !ppalDIB)
|
2009-06-10 00:23:15 +00:00
|
|
|
{
|
2012-07-31 20:44:56 +00:00
|
|
|
DPRINT("Got an error res=%p, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits);
|
2009-06-10 00:23:15 +00:00
|
|
|
if (bm.bmBits)
|
|
|
|
{
|
|
|
|
// MmUnsecureVirtualMemory(hSecure); // FIXME: Implement this!
|
|
|
|
if (section)
|
|
|
|
{
|
|
|
|
ZwUnmapViewOfSection(NtCurrentProcess(), mapBits);
|
|
|
|
bm.bmBits = NULL;
|
|
|
|
}
|
2011-02-28 23:46:02 +00:00
|
|
|
else if (!offset)
|
|
|
|
EngFreeUserMem(bm.bmBits), bm.bmBits = NULL;
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (bmp)
|
2012-10-10 23:05:38 +00:00
|
|
|
{
|
|
|
|
SURFACE_ShareUnlockSurface(bmp);
|
2009-06-10 00:23:15 +00:00
|
|
|
bmp = NULL;
|
2012-10-10 23:05:38 +00:00
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
|
|
|
|
if (res)
|
|
|
|
{
|
[WIN32K]
Rewrite of the GDI handle manager
- The old handle manager used a completely retarded spinlock in combination with KeDelayExecutionThread() for both exclusive
and shared locks. This is probably the most uneffective algorithm possible. It was also duplicating code everywhere and it was a overall mess It
is now replaced with a lock-free reference counter for shared locks and a pushlock for exclusive locks. -> Better performance and scalability.
- Allocate user mode object attributes from the new gdi pool. This way, we don't need any caching, since the pool serves as a cache. Its also
much faster and uses much less memory.
- Allow object allocations of different size, instead of fixed size from a table. This way a single allocation can take care of actual needs.
- Allow allcoating objects without a handle and insert them into the handle table later
- Properly synchronize the process GDIHandleCount. Now gdiview and taskmanager show the correct number of gdi handles.
- Implement a new event tracking system, that is capable of tracking all reverences and locks of objects and pool allocations to help track
possible leaks
- Make sure that all objects of a process are deleted in cleanup
- Make sure all usermode memory allocations are freed, when cleaning up the process pool.
- Make sure that each object type is using the correct type of lock (either shared or exclusive, not a mixture)
- Fix some object / reference leaks
- Lots of inferface improvements
- Use global variables for certain things instead of members in the mapped gdi handle table
- Make IntSysCreateRectpRgn create a region without a handle
- Fix detection od source and mask use in GreStretchBltMask
- Use GDIOBJ_bLockMultipleObjects in NtGdiCombineRegion to avoid possible deadlocks
- Fix NtGdiAbortPath to reset DCPATH_ACTIVE flag in the dc and only bail out on error, instead of always
- Replace DC_AllocateDcAttr and DC_AllocDcAttr with DC_bAllocDcAttr using the new user mode pool
- Remove DCU_SyncDcAttrtoUser and DCU_SynchDcAttrtoUser. Those functions were unused and didn't do anything useful anyway,
- Replace IntGdiSetDCOwnerEx and DC_SetOwnership with GreSetDCOwner, remove unused NoSetBrush parameter
- Replace GDIOBJ_bValidateHandle and IsObjectDead with GreIsHandleValid
- Chage GDIOBJ_bLockMultipleObjects: pass object type, return a BOOL, whether all objects could be locked, cleanup on failure
svn path=/trunk/; revision=51470
2011-04-28 08:26:46 +00:00
|
|
|
GreDeleteObject(res);
|
2009-06-10 00:23:15 +00:00
|
|
|
res = 0;
|
|
|
|
}
|
2012-12-18 21:44:58 +00:00
|
|
|
|
2012-10-10 23:05:38 +00:00
|
|
|
if(ppalDIB)
|
|
|
|
{
|
|
|
|
PALETTE_ShareUnlockPalette(ppalDIB);
|
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (bmp)
|
|
|
|
{
|
2012-10-10 23:05:38 +00:00
|
|
|
/* If we're here, everything went fine */
|
|
|
|
SURFACE_vSetPalette(bmp, ppalDIB);
|
|
|
|
PALETTE_ShareUnlockPalette(ppalDIB);
|
2011-04-15 15:29:08 +00:00
|
|
|
SURFACE_ShareUnlockSurface(bmp);
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return BITMAP handle and storage location
|
|
|
|
if (NULL != bm.bmBits && NULL != bits)
|
|
|
|
{
|
|
|
|
*bits = bm.bmBits;
|
|
|
|
}
|
2002-09-24 20:22:10 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
return res;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2010-07-29 16:12:43 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* DIB_GetBitmapInfo
|
|
|
|
*
|
|
|
|
* Get the info from a bitmap header.
|
|
|
|
* Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error.
|
|
|
|
*/
|
2010-08-05 21:12:57 +00:00
|
|
|
int
|
2010-07-29 16:12:43 +00:00
|
|
|
FASTCALL
|
|
|
|
DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
|
2011-02-28 23:46:02 +00:00
|
|
|
LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size )
|
2010-07-29 16:12:43 +00:00
|
|
|
{
|
|
|
|
if (header->biSize == sizeof(BITMAPCOREHEADER))
|
|
|
|
{
|
|
|
|
const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
|
|
|
|
*width = core->bcWidth;
|
|
|
|
*height = core->bcHeight;
|
|
|
|
*planes = core->bcPlanes;
|
|
|
|
*bpp = core->bcBitCount;
|
2010-08-05 21:12:57 +00:00
|
|
|
*compr = BI_RGB;
|
2010-07-29 16:12:43 +00:00
|
|
|
*size = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
2011-12-14 04:07:06 +00:00
|
|
|
if (header->biSize >= sizeof(BITMAPINFOHEADER)) /* Assume BITMAPINFOHEADER */
|
2010-07-29 16:12:43 +00:00
|
|
|
{
|
|
|
|
*width = header->biWidth;
|
|
|
|
*height = header->biHeight;
|
|
|
|
*planes = header->biPlanes;
|
|
|
|
*bpp = header->biBitCount;
|
|
|
|
*compr = header->biCompression;
|
|
|
|
*size = header->biSizeImage;
|
|
|
|
return 1;
|
|
|
|
}
|
2012-07-31 20:44:56 +00:00
|
|
|
DPRINT1("(%u): unknown/wrong size for header\n", header->biSize );
|
2010-07-29 16:12:43 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* DIB_GetDIBImageBytes
|
|
|
|
*
|
|
|
|
* Return the number of bytes used to hold the image in a DIB bitmap.
|
|
|
|
* 11/16/1999 (RJJ) lifted from wine
|
|
|
|
*/
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
INT APIENTRY DIB_GetDIBImageBytes(INT width, INT height, INT depth)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2010-09-01 16:52:23 +00:00
|
|
|
return WIDTH_BYTES_ALIGN32(width, depth) * (height < 0 ? -height : height);
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* DIB_BitmapInfoSize
|
|
|
|
*
|
|
|
|
* Return the size of the bitmap info structure including color table.
|
|
|
|
* 11/16/1999 (RJJ) lifted from wine
|
|
|
|
*/
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2010-07-29 16:12:43 +00:00
|
|
|
unsigned int colors, size, masks = 0;
|
2015-03-25 22:37:16 +00:00
|
|
|
unsigned int colorsize;
|
|
|
|
|
|
|
|
colorsize = (coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) :
|
|
|
|
(coloruse == DIB_PAL_INDICES) ? 0 :
|
|
|
|
sizeof(WORD);
|
2009-06-10 00:23:15 +00:00
|
|
|
|
|
|
|
if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
|
|
|
{
|
2010-07-29 16:12:43 +00:00
|
|
|
const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
|
2009-06-10 00:23:15 +00:00
|
|
|
colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
|
2015-03-25 22:37:16 +00:00
|
|
|
return sizeof(BITMAPCOREHEADER) + colors * colorsize;
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
2011-12-14 04:07:06 +00:00
|
|
|
else /* Assume BITMAPINFOHEADER */
|
2009-06-10 00:23:15 +00:00
|
|
|
{
|
|
|
|
colors = info->bmiHeader.biClrUsed;
|
2010-07-29 16:12:43 +00:00
|
|
|
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) );
|
2015-03-25 22:37:16 +00:00
|
|
|
return size + colors * colorsize;
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2010-08-01 12:17:35 +00:00
|
|
|
HPALETTE
|
2009-06-10 00:23:15 +00:00
|
|
|
FASTCALL
|
2012-05-02 10:09:05 +00:00
|
|
|
DIB_MapPaletteColors(PPALETTE ppalDc, CONST BITMAPINFO* lpbmi)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2012-05-02 10:09:05 +00:00
|
|
|
PPALETTE ppalNew;
|
2009-06-10 00:23:15 +00:00
|
|
|
ULONG nNumColors,i;
|
|
|
|
USHORT *lpIndex;
|
2011-02-28 23:46:02 +00:00
|
|
|
HPALETTE hpal;
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2012-05-02 10:09:05 +00:00
|
|
|
if (!(ppalDc->flFlags & PAL_INDEXED))
|
2005-07-26 11:22:48 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
return NULL;
|
2005-07-26 11:22:48 +00:00
|
|
|
}
|
|
|
|
|
2010-07-29 16:12:43 +00:00
|
|
|
nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
|
|
|
|
if (lpbmi->bmiHeader.biClrUsed)
|
2003-08-28 12:35:59 +00:00
|
|
|
{
|
2010-07-29 16:12:43 +00:00
|
|
|
nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
|
2003-08-28 12:35:59 +00:00
|
|
|
}
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2012-05-02 10:09:05 +00:00
|
|
|
ppalNew = PALETTE_AllocPalWithHandle(PAL_INDEXED, nNumColors, NULL, 0, 0, 0);
|
|
|
|
if (ppalNew == NULL)
|
2009-06-10 00:23:15 +00:00
|
|
|
{
|
2012-05-02 10:09:05 +00:00
|
|
|
DPRINT1("Could not allocate palette\n");
|
2009-06-10 00:23:15 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2010-08-01 12:17:35 +00:00
|
|
|
lpIndex = (USHORT *)((PBYTE)lpbmi + lpbmi->bmiHeader.biSize);
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
for (i = 0; i < nNumColors; i++)
|
2003-08-28 12:35:59 +00:00
|
|
|
{
|
2012-05-02 10:09:05 +00:00
|
|
|
ULONG iColorIndex = *lpIndex % ppalDc->NumColors;
|
|
|
|
ppalNew->IndexedColors[i] = ppalDc->IndexedColors[iColorIndex];
|
2009-06-10 00:23:15 +00:00
|
|
|
lpIndex++;
|
2003-08-28 12:35:59 +00:00
|
|
|
}
|
2010-08-05 21:12:57 +00:00
|
|
|
|
2012-05-02 10:09:05 +00:00
|
|
|
hpal = ppalNew->BaseObject.hHmgr;
|
|
|
|
PALETTE_UnlockPalette(ppalNew);
|
2003-08-28 12:35:59 +00:00
|
|
|
|
2011-02-28 23:46:02 +00:00
|
|
|
return hpal;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2010-07-29 18:01:14 +00:00
|
|
|
/* 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)
|
|
|
|
{
|
2011-02-28 23:46:02 +00:00
|
|
|
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)
|
|
|
|
{
|
2011-12-14 04:07:06 +00:00
|
|
|
/* Invalid at high-res */
|
2011-02-28 23:46:02 +00:00
|
|
|
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);
|
2017-03-04 10:37:00 +00:00
|
|
|
pNewBmi->bmiHeader.biClrUsed = numColors;
|
2011-02-28 23:46:02 +00:00
|
|
|
|
|
|
|
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 ;
|
2010-07-29 18:01:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Frees a BITMAPINFO created with DIB_ConvertBitmapInfo */
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
2013-01-02 14:52:34 +00:00
|
|
|
DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig, DWORD usage)
|
2010-07-29 18:01:14 +00:00
|
|
|
{
|
2013-01-02 14:52:34 +00:00
|
|
|
BITMAPCOREINFO* pbmci;
|
|
|
|
if(converted == orig)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(usage == -1)
|
|
|
|
{
|
|
|
|
/* Caller don't want any conversion */
|
2011-02-28 23:46:02 +00:00
|
|
|
ExFreePoolWithTag(converted, TAG_DIB);
|
2013-01-02 14:52:34 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Perform inverse conversion */
|
|
|
|
pbmci = (BITMAPCOREINFO*)orig;
|
|
|
|
|
|
|
|
ASSERT(pbmci->bmciHeader.bcSize == sizeof(BITMAPCOREHEADER));
|
|
|
|
pbmci->bmciHeader.bcBitCount = converted->bmiHeader.biBitCount;
|
|
|
|
pbmci->bmciHeader.bcWidth = converted->bmiHeader.biWidth;
|
|
|
|
pbmci->bmciHeader.bcHeight = converted->bmiHeader.biHeight;
|
|
|
|
pbmci->bmciHeader.bcPlanes = converted->bmiHeader.biPlanes;
|
|
|
|
|
|
|
|
if(pbmci->bmciHeader.bcBitCount <= 8)
|
|
|
|
{
|
|
|
|
UINT numColors = converted->bmiHeader.biClrUsed;
|
|
|
|
if(!numColors) numColors = 1 << pbmci->bmciHeader.bcBitCount;
|
|
|
|
if(usage == DIB_PAL_COLORS)
|
|
|
|
{
|
|
|
|
RtlZeroMemory(pbmci->bmciColors, (1 << pbmci->bmciHeader.bcBitCount) * sizeof(WORD));
|
|
|
|
RtlCopyMemory(pbmci->bmciColors, converted->bmiColors, numColors * sizeof(WORD));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
UINT i;
|
|
|
|
RtlZeroMemory(pbmci->bmciColors, (1 << pbmci->bmciHeader.bcBitCount) * sizeof(RGBTRIPLE));
|
|
|
|
for(i=0; i<numColors; i++)
|
|
|
|
{
|
|
|
|
pbmci->bmciColors[i].rgbtRed = converted->bmiColors[i].rgbRed;
|
|
|
|
pbmci->bmciColors[i].rgbtGreen = converted->bmiColors[i].rgbGreen;
|
|
|
|
pbmci->bmciColors[i].rgbtBlue = converted->bmiColors[i].rgbBlue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Now free it, it's not needed anymore */
|
|
|
|
ExFreePoolWithTag(converted, TAG_DIB);
|
2010-07-29 18:01:14 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
/* EOF */
|