/*
* PROJECT: ReactOS win32 kernel mode subsystem
* LICENSE: GPL - See COPYING in the top level directory
- * FILE: subsystems/win32/win32k/objects/dibobj.c
+ * FILE: win32ss/gdi/ntgdi/dibobj.c
* PURPOSE: Dib object functions
* PROGRAMMER:
*/
UINT StartScan,
UINT ScanLines,
CONST VOID *Bits,
+ ULONG cjMaxBits,
CONST BITMAPINFO *bmi,
UINT ColorUse)
{
POINTL ptSrc;
EXLATEOBJ exlo;
PPALETTE ppalDIB = 0;
+ ULONG cjSizeImage;
- if (!bmi) return 0;
+ if (!bmi || !Bits) return 0;
+
+ /* Check for uncompressed formats */
+ if ((bmi->bmiHeader.biCompression == BI_RGB) ||
+ (bmi->bmiHeader.biCompression == BI_BITFIELDS))
+ {
+ /* Calculate the image size */
+ cjSizeImage = DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
+ ScanLines,
+ bmi->bmiHeader.biBitCount);
+ }
+ /* Check if the header provided an image size */
+ else if (bmi->bmiHeader.biSizeImage != 0)
+ {
+ /* Use the given size */
+ cjSizeImage = bmi->bmiHeader.biSizeImage;
+ }
+ 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 */
+ if ((cjSizeImage > cjMaxBits) || (cjSizeImage == 0))
+ {
+ DPRINT1("Invalid bitmap size! cjSizeImage = %lu, cjMaxBits = %lu\n",
+ cjSizeImage, cjMaxBits);
+ return 0;
+ }
SourceBitmap = GreCreateBitmapEx(bmi->bmiHeader.biWidth,
ScanLines,
BitmapFormat(bmi->bmiHeader.biBitCount,
bmi->bmiHeader.biCompression),
bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
- bmi->bmiHeader.biSizeImage,
+ cjSizeImage,
(PVOID)Bits,
0);
if (!SourceBitmap)
ptSrc.x = 0;
ptSrc.y = 0;
+ NT_ASSERT(psurfSrc->SurfObj.cjBits <= cjMaxBits);
+
result = IntEngCopyBits(&psurfDst->SurfObj,
&psurfSrc->SurfObj,
NULL,
ULONG compression,
DWORD init,
LPBYTE bits,
+ ULONG cjMaxBits,
PBITMAPINFO data,
DWORD coloruse)
{
/* Undocumented flag which creates a DDB of the format specified by the bitmap info. */
handle = IntCreateCompatibleBitmap(Dc, width, height, planes, bpp);
if (!handle)
+ {
+ DPRINT1("IntCreateCompatibleBitmap() failed!\n");
return NULL;
+ }
+
/* The palette must also match the given data */
Surface = SURFACE_ShareLockSurface(handle);
ASSERT(Surface);
else
{
handle = GreCreateBitmap(width,
- height,
+ abs(height),
1,
1,
NULL);
if ((NULL != handle) && (CBM_INIT & init))
{
- IntSetDIBits(Dc, handle, 0, height, bits, data, coloruse);
+ IntSetDIBits(Dc, handle, 0, height, bits, cjMaxBits, data, coloruse);
}
return handle;
PBYTE safeBits = NULL;
HBITMAP hbmResult = NULL;
+ if (pjInit == NULL)
+ {
+ fInit &= ~CBM_INIT;
+ }
+
if(pjInit && (fInit & CBM_INIT))
{
if (cjMaxBits == 0) return NULL;
safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
if(!safeBits)
{
+ DPRINT1("Failed to allocate %lu bytes\n", cjMaxBits);
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
if(!NT_SUCCESS(Status))
{
+ DPRINT1("Got an exception! pjInit = %p\n", pjInit);
SetLastNtError(Status);
goto cleanup;
}
hdcDest = NtGdiCreateCompatibleDC(0);
if(!hdcDest)
{
+ DPRINT1("NtGdiCreateCompatibleDC failed\n");
return NULL;
}
}
Dc = DC_LockDc(hdcDest);
if (!Dc)
{
+ DPRINT1("Failed to lock hdcDest %p\n", hdcDest);
EngSetLastError(ERROR_INVALID_HANDLE);
return NULL;
}
planes = 0;
compression = 0;
}
- Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, planes, compression, fInit, pjInit, pbmi, iUsage);
+ Bmp = IntCreateDIBitmap(Dc, cx, cy, planes, bpp, compression, fInit, pjInit, cjMaxBits, pbmi, iUsage);
DC_UnlockDc(Dc);
if(!hDc)
return Bmp;
}
+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;
+}
HBITMAP
APIENTRY
INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse)
{
unsigned int colors, size, masks = 0;
+ unsigned int colorsize;
+
+ colorsize = (coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) :
+ (coloruse == DIB_PAL_INDICES) ? 0 :
+ sizeof(WORD);
if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
- return sizeof(BITMAPCOREHEADER) + colors *
- ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
+ return sizeof(BITMAPCOREHEADER) + colors * colorsize;
}
else /* Assume BITMAPINFOHEADER */
{
colors = 1 << info->bmiHeader.biBitCount;
if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
- return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
+ return size + colors * colorsize;
}
}