IN ULONG iFormat,
IN USHORT fjBitmap,
IN ULONG cjSizeImage,
- IN OPTIONAL PVOID pvBits)
+ IN OPTIONAL PVOID pvBits,
+ IN FLONG flags)
{
PSURFACE psurf;
SURFOBJ *pso;
HBITMAP hbmp;
PVOID pvCompressedBits;
SIZEL sizl;
- FLONG fl = 0;
/* Verify format */
if (iFormat < BMF_1BPP || iFormat > BMF_PNG) return NULL;
pvCompressedBits = pvBits;
pvBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
Decompress4bpp(sizl, pvCompressedBits, pvBits, pso->lDelta);
- fl |= BMF_RLE_HACK;
+ fjBitmap |= BMF_RLE_HACK;
}
else if (iFormat == BMF_8RLE)
{
pvCompressedBits = pvBits;
pvBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
Decompress8bpp(sizl, pvCompressedBits, pvBits, pso->lDelta);
- fl |= BMF_RLE_HACK;
+ fjBitmap |= BMF_RLE_HACK;
}
+ /* Mark as API bitmap */
+ psurf->flags |= (flags | API_BITMAP);
+
/* Set the bitmap bits */
if (!SURFACE_bSetBitmapBits(psurf, fjBitmap, cjWidthBytes, pvBits))
{
return NULL;
}
- /* Mark as API bitmap */
- psurf->flags |= API_BITMAP;
-
/* Unlock the surface and return */
SURFACE_UnlockSurface(psurf);
return hbmp;
}
+/* Creates a DDB surface,
+ * as in CreateCompatibleBitmap or CreateBitmap.
+ */
HBITMAP
APIENTRY
GreCreateBitmap(
BitmapFormat(cBitsPixel * cPlanes, BI_RGB),
0, /* no bitmap flags */
0, /* auto size */
- pvBits);
+ pvBits,
+ DDB_SURFACE /* DDB */);
}
HBITMAP
IN UINT cBitsPixel,
IN OPTIONAL LPBYTE pUnsafeBits)
{
- PSURFACE psurf;
- SURFOBJ *pso;
HBITMAP hbmp;
- FLONG fl = 0;
ULONG cjWidthBytes, iFormat;
/* NOTE: Windows also doesn't store nr. of planes separately! */
}
/* Make sure that cjBits will not overflow */
- cjWidthBytes = DIB_GetDIBWidthBytes(nWidth, cBitsPixel);
+ cjWidthBytes = BITMAP_GetWidthBytes(nWidth, cBitsPixel);
if ((ULONGLONG)cjWidthBytes * nHeight >= 0x100000000ULL)
{
DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
return NULL;
}
- /* Allocate a surface */
- psurf = SURFACE_AllocSurface(STYPE_BITMAP, nWidth, nHeight, iFormat);
- if (!psurf)
- {
- DPRINT1("SURFACE_AllocSurface failed.\n");
- EngSetLastError(ERROR_OUTOFMEMORY);
- return NULL;
- }
-
- /* Get the handle for the bitmap and the surfobj */
- hbmp = (HBITMAP)psurf->SurfObj.hsurf;
- pso = &psurf->SurfObj;
+ /* cBitsPixel = cBitsPixel * cPlanes now! */
+ hbmp = GreCreateBitmap(nWidth, nHeight, 1, cBitsPixel, NULL);
- /* Allocate the bitmap bits */
- if (!SURFACE_bSetBitmapBits(psurf, fl, 0, NULL))
- {
- /* Bail out if that failed */
- DPRINT1("SURFACE_bSetBitmapBits failed.\n");
- SURFACE_FreeSurfaceByHandle(hbmp);
- return NULL;
- }
-
if (pUnsafeBits)
{
+ PSURFACE psurf = SURFACE_LockSurface(hbmp);
_SEH2_TRY
{
ProbeForRead(pUnsafeBits, cjWidthBytes * nHeight, 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
+ SURFACE_UnlockSurface(psurf);
SURFACE_FreeSurfaceByHandle(hbmp);
_SEH2_YIELD(return NULL;)
}
_SEH2_END
- }
- /* Mark as API bitmap */
- psurf->flags |= API_BITMAP;
+ SURFACE_UnlockSurface(psurf);
+ }
- /* Unlock the surface and return */
- SURFACE_UnlockSurface(psurf);
return hbmp;
}
PSURFACE psurfBmp;
size.cx = abs(Width);
size.cy = abs(Height);
- Bmp = GreCreateBitmap(abs(Width),
+ Bmp = GreCreateBitmap(abs(Width),
abs(Height),
1,
dibs.dsBm.bmBitsPixel,
else
{
/* A DIB section is selected in the DC */
- BITMAPINFO *bi;
+ BYTE buf[sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD)] = {0};
PVOID Bits;
-
- /* Allocate memory for a BITMAPINFOHEADER structure and a
- color table. The maximum number of colors in a color table
- is 256 which corresponds to a bitmap with depth 8.
- Bitmaps with higher depths don't have color tables. */
- bi = ExAllocatePoolWithTag(PagedPool,
- sizeof(BITMAPINFOHEADER) +
- 256 * sizeof(RGBQUAD),
- TAG_TEMP);
-
- if (bi)
+ BITMAPINFO* bi = (BITMAPINFO*)buf;
+
+ bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
+ bi->bmiHeader.biWidth = Width;
+ bi->bmiHeader.biHeight = Height;
+ bi->bmiHeader.biPlanes = dibs.dsBmih.biPlanes;
+ bi->bmiHeader.biBitCount = dibs.dsBmih.biBitCount;
+ bi->bmiHeader.biCompression = dibs.dsBmih.biCompression;
+ bi->bmiHeader.biSizeImage = 0;
+ bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter;
+ bi->bmiHeader.biYPelsPerMeter = dibs.dsBmih.biYPelsPerMeter;
+ bi->bmiHeader.biClrUsed = dibs.dsBmih.biClrUsed;
+ bi->bmiHeader.biClrImportant = dibs.dsBmih.biClrImportant;
+
+ if (bi->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ /* Copy the color masks */
+ RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3*sizeof(RGBQUAD));
+ }
+ else if (bi->bmiHeader.biBitCount <= 8)
{
- bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
- bi->bmiHeader.biWidth = Width;
- bi->bmiHeader.biHeight = Height;
- bi->bmiHeader.biPlanes = dibs.dsBmih.biPlanes;
- bi->bmiHeader.biBitCount = dibs.dsBmih.biBitCount;
- bi->bmiHeader.biCompression = dibs.dsBmih.biCompression;
- bi->bmiHeader.biSizeImage = 0;
- bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter;
- bi->bmiHeader.biYPelsPerMeter = dibs.dsBmih.biYPelsPerMeter;
- bi->bmiHeader.biClrUsed = dibs.dsBmih.biClrUsed;
- bi->bmiHeader.biClrImportant = dibs.dsBmih.biClrImportant;
-
- if (bi->bmiHeader.biCompression == BI_BITFIELDS)
+ /* Copy the color table */
+ UINT Index;
+ PPALETTE PalGDI;
+
+ if (!psurf->ppal)
{
- /* Copy the color masks */
- RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3 * sizeof(DWORD));
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
}
- else if (bi->bmiHeader.biBitCount <= 8)
+
+ PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
+
+ for (Index = 0;
+ Index < 256 && Index < PalGDI->NumColors;
+ Index++)
{
- /* Copy the color table */
- UINT Index;
- PPALETTE PalGDI;
-
- if (!psurf->ppal)
- {
- ExFreePoolWithTag(bi, TAG_TEMP);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
-
- PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
-
- for (Index = 0;
- Index < 256 && Index < PalGDI->NumColors;
- Index++)
- {
- bi->bmiColors[Index].rgbRed = PalGDI->IndexedColors[Index].peRed;
- bi->bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
- bi->bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
- bi->bmiColors[Index].rgbReserved = 0;
- }
- PALETTE_UnlockPalette(PalGDI);
+ bi->bmiColors[Index].rgbRed = PalGDI->IndexedColors[Index].peRed;
+ bi->bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
+ bi->bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
+ bi->bmiColors[Index].rgbReserved = 0;
}
+ PALETTE_UnlockPalette(PalGDI);
Bmp = DIB_CreateDIBSection(Dc,
bi,
NULL,
0,
0);
-
- ExFreePoolWithTag(bi, TAG_TEMP);
return Bmp;
}
}
return ret;
}
+VOID
+FASTCALL
+UnsafeGetBitmapBits(
+ PSURFACE psurf,
+ DWORD Bytes,
+ OUT PBYTE pvBits)
+{
+ PUCHAR pjDst, pjSrc;
+ LONG lDeltaDst, lDeltaSrc;
+ ULONG nWidth, nHeight, cBitsPixel;
+
+ nWidth = psurf->SurfObj.sizlBitmap.cx;
+ nHeight = psurf->SurfObj.sizlBitmap.cy;
+ cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+
+ /* Get pointers */
+ pjSrc = psurf->SurfObj.pvScan0;
+ pjDst = pvBits;
+ lDeltaSrc = psurf->SurfObj.lDelta;
+ lDeltaDst = BITMAP_GetWidthBytes(nWidth, cBitsPixel);
+
+ while (nHeight--)
+ {
+ /* Copy one line */
+ RtlCopyMemory(pjDst, pjSrc, lDeltaDst);
+ pjSrc += lDeltaSrc;
+ pjDst += lDeltaDst;
+ }
+}
+
LONG APIENTRY
NtGdiGetBitmapBits(
HBITMAP hBitmap,
_SEH2_TRY
{
ProbeForWrite(pUnsafeBits, Bytes, 1);
- ret = IntGetBitmapBits(psurf, Bytes, pUnsafeBits);
+ UnsafeGetBitmapBits(psurf, Bytes, pUnsafeBits);
+ ret = Bytes;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
return 0;
}
- Bitmap = GDIOBJ_LockObj(hBitmap, GDI_OBJECT_TYPE_BITMAP);
+ Bitmap = SURFACE_LockSurface(hBitmap);
if (Bitmap == NULL)
{
return 0;
Size.cx = abs(bm.bmWidth);
Size.cy = abs(bm.bmHeight);
- res = GreCreateBitmap(abs(bm.bmWidth),
- abs(bm.bmHeight),
- 1,
- bm.bmBitsPixel,
- NULL);
+ res = GreCreateBitmapEx(Size.cx,
+ Size.cy,
+ bm.bmWidthBytes,
+ Bitmap->SurfObj.iBitmapFormat,
+ Bitmap->SurfObj.fjBitmap,
+ Bitmap->SurfObj.cjBits,
+ NULL,
+ Bitmap->flags);
+
if (res)
{
- PBYTE buf;
-
- resBitmap = GDIOBJ_LockObj(res, GDI_OBJECT_TYPE_BITMAP);
+ resBitmap = SURFACE_LockSurface(res);
if (resBitmap)
{
- buf = ExAllocatePoolWithTag(PagedPool,
- bm.bmWidthBytes * abs(bm.bmHeight),
- TAG_BITMAP);
- if (buf == NULL)
- {
- GDIOBJ_UnlockObjByPtr((POBJ)resBitmap);
- GDIOBJ_UnlockObjByPtr((POBJ)Bitmap);
- GreDeleteObject(res);
- return 0;
- }
- IntGetBitmapBits(Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf);
- IntSetBitmapBits(resBitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf);
- ExFreePoolWithTag(buf,TAG_BITMAP);
- resBitmap->flags = Bitmap->flags;
- /* Copy palette */
- if (Bitmap->ppal)
- {
- resBitmap->ppal = Bitmap->ppal ;
- GDIOBJ_IncrementShareCount(&Bitmap->ppal->BaseObject);
- }
- GDIOBJ_UnlockObjByPtr((POBJ)resBitmap);
+ IntSetBitmapBits(resBitmap, Bitmap->SurfObj.cjBits, Bitmap->SurfObj.pvBits);
+ resBitmap->ppal = Bitmap->ppal;
+ GDIOBJ_IncrementShareCount((POBJ)Bitmap->ppal);
+ SURFACE_UnlockSurface(resBitmap);
}
else
{
}
}
- GDIOBJ_UnlockObjByPtr((POBJ)Bitmap);
+ SURFACE_UnlockSurface(Bitmap);
return res;
}
pBitmap->bmType = 0;
pBitmap->bmWidth = psurf->SurfObj.sizlBitmap.cx;
pBitmap->bmHeight = psurf->SurfObj.sizlBitmap.cy;
- pBitmap->bmWidthBytes = abs(psurf->SurfObj.lDelta);
pBitmap->bmPlanes = 1;
pBitmap->bmBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+ pBitmap->bmWidthBytes = BITMAP_GetWidthBytes(pBitmap->bmWidth, pBitmap->bmBitsPixel);
/* Check for DIB section */
if (psurf->hSecure)
{
/* Set bmBits in this case */
pBitmap->bmBits = psurf->SurfObj.pvBits;
+ /* DIBs data are 32 bits aligned */
+ pBitmap->bmWidthBytes = DIB_GetDIBWidthBytes(pBitmap->bmWidth, pBitmap->bmBitsPixel);
if (Count >= sizeof(DIBSECTION))
{
pds->dsBmih.biHeight = pds->dsBm.bmHeight;
pds->dsBmih.biPlanes = pds->dsBm.bmPlanes;
pds->dsBmih.biBitCount = pds->dsBm.bmBitsPixel;
- switch (psurf->SurfObj.iBitmapFormat)
- {
- /* FIXME: What about BI_BITFIELDS? */
- case BMF_1BPP:
- case BMF_4BPP:
- case BMF_8BPP:
- case BMF_16BPP:
- case BMF_24BPP:
- case BMF_32BPP:
- pds->dsBmih.biCompression = BI_RGB;
- break;
- case BMF_4RLE:
- pds->dsBmih.biCompression = BI_RLE4;
- break;
- case BMF_8RLE:
- pds->dsBmih.biCompression = BI_RLE8;
- break;
- case BMF_JPEG:
- pds->dsBmih.biCompression = BI_JPEG;
- break;
- case BMF_PNG:
- pds->dsBmih.biCompression = BI_PNG;
- break;
- }
+ if(psurf->ppal->Mode & PAL_BITFIELDS)
+ {
+ pds->dsBmih.biCompression = BI_BITFIELDS;
+ }
+ else
+ {
+ switch (psurf->SurfObj.iBitmapFormat)
+ {
+ case BMF_1BPP:
+ case BMF_4BPP:
+ case BMF_8BPP:
+ case BMF_16BPP:
+ case BMF_24BPP:
+ case BMF_32BPP:
+ pds->dsBmih.biCompression = BI_RGB;
+ break;
+ case BMF_4RLE:
+ pds->dsBmih.biCompression = BI_RLE4;
+ break;
+ case BMF_8RLE:
+ pds->dsBmih.biCompression = BI_RLE8;
+ break;
+ case BMF_JPEG:
+ pds->dsBmih.biCompression = BI_JPEG;
+ break;
+ case BMF_PNG:
+ pds->dsBmih.biCompression = BI_PNG;
+ break;
+ }
+ }
pds->dsBmih.biSizeImage = psurf->SurfObj.cjBits;
pds->dsBmih.biXPelsPerMeter = 0;
pds->dsBmih.biYPelsPerMeter = 0;
- pds->dsBmih.biClrUsed = psurf->biClrUsed;
+ pds->dsBmih.biClrUsed = psurf->ppal->NumColors;
pds->dsBmih.biClrImportant = psurf->biClrImportant;
- pds->dsBitfields[0] = psurf->dsBitfields[0];
- pds->dsBitfields[1] = psurf->dsBitfields[1];
- pds->dsBitfields[2] = psurf->dsBitfields[2];
+ pds->dsBitfields[0] = psurf->ppal->RedMask;
+ pds->dsBitfields[1] = psurf->ppal->GreenMask;
+ pds->dsBitfields[2] = psurf->ppal->BlueMask;
pds->dshSection = psurf->hDIBSection;
pds->dsOffset = psurf->dwOffset;
return hdc;
}
+
/* EOF */