/*
- * $Id$
- *
* ReactOS W32 Subsystem
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
*
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
-UINT STDCALL
-IntSetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, CONST RGBQUAD *Colors)
+static const RGBQUAD EGAColorsQuads[16] = {
+/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
+ { 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 },
+ { 0x80, 0x80, 0x80, 0x00 },
+ { 0xc0, 0xc0, 0xc0, 0x00 },
+ { 0x00, 0x00, 0xff, 0x00 },
+ { 0x00, 0xff, 0x00, 0x00 },
+ { 0x00, 0xff, 0xff, 0x00 },
+ { 0xff, 0x00, 0x00, 0x00 },
+ { 0xff, 0x00, 0xff, 0x00 },
+ { 0xff, 0xff, 0x00, 0x00 },
+ { 0xff, 0xff, 0xff, 0x00 }
+};
+
+static const RGBTRIPLE EGAColorsTriples[16] = {
+/* rgbBlue, rgbGreen, rgbRed */
+ { 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x80 },
+ { 0x00, 0x80, 0x00 },
+ { 0x00, 0x80, 0x80 },
+ { 0x80, 0x00, 0x00 },
+ { 0x80, 0x00, 0x80 },
+ { 0x80, 0x80, 0x00 },
+ { 0x80, 0x80, 0x80 },
+ { 0xc0, 0xc0, 0xc0 },
+ { 0x00, 0x00, 0xff },
+ { 0x00, 0xff, 0x00 },
+ { 0x00, 0xff, 0xff },
+ { 0xff, 0x00, 0x00 },
+ { 0xff, 0x00, 0xff },
+ { 0xff, 0xff, 0x00 },
+ { 0xff, 0xff, 0xff }
+};
+
+static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
+/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
+ { 0x00, 0x00, 0x00, 0x00 },
+ { 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 },
+ { 0x00, 0x00, 0xf0, 0x00 },
+ { 0x00, 0xff, 0x00, 0x00 },
+ { 0x00, 0xff, 0xff, 0x00 },
+ { 0xff, 0x00, 0x00, 0x00 },
+ { 0xff, 0x00, 0xff, 0x00 },
+ { 0xff, 0xff, 0x00, 0x00 },
+ { 0xff, 0xff, 0xff, 0x00 }
+};
+
+static const RGBQUAD DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
+/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
+ { 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x80 },
+ { 0x00, 0x80, 0x00 },
+ { 0x00, 0x80, 0x80 },
+ { 0x80, 0x00, 0x00 },
+ { 0x80, 0x00, 0x80 },
+ { 0x80, 0x80, 0x00 },
+ { 0xc0, 0xc0, 0xc0 },
+ { 0xc0, 0xdc, 0xc0 },
+ { 0xf0, 0xca, 0xa6 },
+ { 0xf0, 0xfb, 0xff },
+ { 0xa4, 0xa0, 0xa0 },
+ { 0x80, 0x80, 0x80 },
+ { 0x00, 0x00, 0xf0 },
+ { 0x00, 0xff, 0x00 },
+ { 0x00, 0xff, 0xff },
+ { 0xff, 0x00, 0x00 },
+ { 0xff, 0x00, 0xff },
+ { 0xff, 0xff, 0x00 },
+ { 0xff, 0xff, 0xff }
+};
+
+
+UINT
+APIENTRY
+IntSetDIBColorTable(
+ HDC hDC,
+ UINT StartIndex,
+ UINT Entries,
+ CONST RGBQUAD *Colors)
{
- PDC dc;
- PBITMAPOBJ BitmapObj;
- PPALGDI PalGDI;
- UINT Index;
-
- if (!(dc = DC_LockDc(hDC))) return 0;
- if (dc->DC_Type == DC_TYPE_INFO)
- {
- DC_UnlockDc(dc);
- return 0;
- }
-
- BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
- if (BitmapObj == NULL)
- {
- DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- if (BitmapObj->dib == NULL)
- {
- BITMAPOBJ_UnlockBitmap(BitmapObj);
- DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- if (BitmapObj->dib->dsBmih.biBitCount <= 8 &&
- StartIndex < (1 << BitmapObj->dib->dsBmih.biBitCount))
- {
- if (StartIndex + Entries > (1 << BitmapObj->dib->dsBmih.biBitCount))
- Entries = (1 << BitmapObj->dib->dsBmih.biBitCount) - StartIndex;
-
- PalGDI = PALETTE_LockPalette(BitmapObj->hDIBPalette);
-
- for (Index = StartIndex;
- Index < StartIndex + Entries && Index < PalGDI->NumColors;
- Index++)
- {
- PalGDI->IndexedColors[Index].peRed = Colors[Index - StartIndex].rgbRed;
- PalGDI->IndexedColors[Index].peGreen = Colors[Index - StartIndex].rgbGreen;
- PalGDI->IndexedColors[Index].peBlue = Colors[Index - StartIndex].rgbBlue;
- }
- PALETTE_UnlockPalette(PalGDI);
- }
- else
- Entries = 0;
-
- BITMAPOBJ_UnlockBitmap(BitmapObj);
- DC_UnlockDc(dc);
-
- return Entries;
+ PDC dc;
+ PSURFACE psurf;
+ PPALETTE PalGDI;
+ UINT Index;
+ ULONG biBitCount;
+
+ if (!(dc = DC_LockDc(hDC))) return 0;
+ if (dc->dctype == DC_TYPE_INFO)
+ {
+ DC_UnlockDc(dc);
+ return 0;
+ }
+
+ psurf = dc->dclevel.pSurface;
+ if (psurf == NULL)
+ {
+ DC_UnlockDc(dc);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ if (psurf->hSecure == NULL)
+ {
+ DC_UnlockDc(dc);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+ if (biBitCount <= 8 && StartIndex < (1 << biBitCount))
+ {
+ if (StartIndex + Entries > (1 << biBitCount))
+ Entries = (1 << biBitCount) - StartIndex;
+
+ if (psurf->ppal == NULL)
+ {
+ DC_UnlockDc(dc);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+
+ PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
+
+ for (Index = StartIndex;
+ Index < StartIndex + Entries && Index < PalGDI->NumColors;
+ Index++)
+ {
+ PalGDI->IndexedColors[Index].peRed = Colors[Index - StartIndex].rgbRed;
+ PalGDI->IndexedColors[Index].peGreen = Colors[Index - StartIndex].rgbGreen;
+ PalGDI->IndexedColors[Index].peBlue = Colors[Index - StartIndex].rgbBlue;
+ }
+ PALETTE_UnlockPalette(PalGDI);
+ }
+ else
+ Entries = 0;
+
+ /* Mark the brushes invalid */
+ dc->pdcattr->ulDirty_ |= DIRTY_FILL|DIRTY_LINE|DIRTY_BACKGROUND|DIRTY_TEXT;
+
+ DC_UnlockDc(dc);
+
+ return Entries;
}
-UINT STDCALL
-IntGetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, RGBQUAD *Colors)
+UINT
+APIENTRY
+IntGetDIBColorTable(
+ HDC hDC,
+ UINT StartIndex,
+ UINT Entries,
+ RGBQUAD *Colors)
{
- PDC dc;
- PBITMAPOBJ BitmapObj;
- PPALGDI PalGDI;
- UINT Index;
-
- if (!(dc = DC_LockDc(hDC))) return 0;
- if (dc->DC_Type == DC_TYPE_INFO)
- {
- DC_UnlockDc(dc);
- return 0;
- }
-
- BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
- if (BitmapObj == NULL)
- {
- DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- if (BitmapObj->dib == NULL)
- {
- BITMAPOBJ_UnlockBitmap(BitmapObj);
- DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- if (BitmapObj->dib->dsBmih.biBitCount <= 8 &&
- StartIndex < (1 << BitmapObj->dib->dsBmih.biBitCount))
- {
- if (StartIndex + Entries > (1 << BitmapObj->dib->dsBmih.biBitCount))
- Entries = (1 << BitmapObj->dib->dsBmih.biBitCount) - StartIndex;
-
- PalGDI = PALETTE_LockPalette(BitmapObj->hDIBPalette);
-
- for (Index = StartIndex;
- Index < StartIndex + Entries && Index < PalGDI->NumColors;
- Index++)
- {
- Colors[Index - StartIndex].rgbRed = PalGDI->IndexedColors[Index].peRed;
- Colors[Index - StartIndex].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
- Colors[Index - StartIndex].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
- }
- PALETTE_UnlockPalette(PalGDI);
- }
- else
- Entries = 0;
-
- BITMAPOBJ_UnlockBitmap(BitmapObj);
- DC_UnlockDc(dc);
-
- return Entries;
+ PDC dc;
+ PSURFACE psurf;
+ PPALETTE PalGDI;
+ UINT Index, Count = 0;
+ ULONG biBitCount;
+
+ if (!(dc = DC_LockDc(hDC))) return 0;
+ if (dc->dctype == DC_TYPE_INFO)
+ {
+ DC_UnlockDc(dc);
+ return 0;
+ }
+
+ psurf = dc->dclevel.pSurface;
+ if (psurf == NULL)
+ {
+ DC_UnlockDc(dc);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ if (psurf->hSecure == NULL)
+ {
+ DC_UnlockDc(dc);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+ if (biBitCount <= 8 &&
+ StartIndex < (1 << biBitCount))
+ {
+ if (StartIndex + Entries > (1 << biBitCount))
+ Entries = (1 << biBitCount) - StartIndex;
+
+ if (psurf->ppal == NULL)
+ {
+ DC_UnlockDc(dc);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+
+ PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
+
+ for (Index = StartIndex;
+ Index < StartIndex + Entries && Index < PalGDI->NumColors;
+ Index++)
+ {
+ Colors[Index - StartIndex].rgbRed = PalGDI->IndexedColors[Index].peRed;
+ Colors[Index - StartIndex].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
+ Colors[Index - StartIndex].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
+ Colors[Index - StartIndex].rgbReserved = 0;
+ Count++;
+ }
+ PALETTE_UnlockPalette(PalGDI);
+ }
+
+ DC_UnlockDc(dc);
+
+ return Count;
}
// Converts a DIB to a device-dependent bitmap
-static INT FASTCALL
+static INT
+FASTCALL
IntSetDIBits(
- PDC DC,
- HBITMAP hBitmap,
- UINT StartScan,
- UINT ScanLines,
- CONST VOID *Bits,
- CONST BITMAPINFO *bmi,
- UINT ColorUse)
+ PDC DC,
+ HBITMAP hBitmap,
+ UINT StartScan,
+ UINT ScanLines,
+ CONST VOID *Bits,
+ CONST BITMAPINFO *bmi,
+ UINT ColorUse)
{
- BITMAPOBJ *bitmap;
- HBITMAP SourceBitmap;
- INT result = 0;
- BOOL copyBitsResult;
- SURFOBJ *DestSurf, *SourceSurf;
- SIZEL SourceSize;
- POINTL ZeroPoint;
- RECTL DestRect;
- XLATEOBJ *XlateObj;
- PPALGDI hDCPalette;
- //RGBQUAD *lpRGB;
- HPALETTE DDB_Palette, DIB_Palette;
- ULONG DDB_Palette_Type, DIB_Palette_Type;
- INT DIBWidth;
-
- // Check parameters
- if (!(bitmap = BITMAPOBJ_LockBitmap(hBitmap)))
- {
- return 0;
- }
-
- // Get RGB values
- //if (ColorUse == DIB_PAL_COLORS)
- // lpRGB = DIB_MapPaletteColors(hDC, bmi);
- //else
- // lpRGB = &bmi->bmiColors;
-
- DestSurf = &bitmap->SurfObj;
-
- // Create source surface
- SourceSize.cx = bmi->bmiHeader.biWidth;
- SourceSize.cy = ScanLines;
-
- // Determine width of DIB
- DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
-
- SourceBitmap = EngCreateBitmap(SourceSize,
- DIBWidth,
- BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression),
- bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
- (PVOID) Bits);
- if (0 == SourceBitmap)
- {
- BITMAPOBJ_UnlockBitmap(bitmap);
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- return 0;
- }
-
- SourceSurf = EngLockSurface((HSURF)SourceBitmap);
- if (NULL == SourceSurf)
- {
- EngDeleteSurface((HSURF)SourceBitmap);
- BITMAPOBJ_UnlockBitmap(bitmap);
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- return 0;
- }
-
- // Destination palette obtained from the hDC
- hDCPalette = PALETTE_LockPalette(((GDIDEVICE *)DC->pPDev)->DevInfo.hpalDefault);
- if (NULL == hDCPalette)
- {
- EngUnlockSurface(SourceSurf);
- EngDeleteSurface((HSURF)SourceBitmap);
- BITMAPOBJ_UnlockBitmap(bitmap);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
- DDB_Palette_Type = hDCPalette->Mode;
- DDB_Palette = ((GDIDEVICE *)DC->pPDev)->DevInfo.hpalDefault;
- PALETTE_UnlockPalette(hDCPalette);
-
- // Source palette obtained from the BITMAPINFO
- DIB_Palette = BuildDIBPalette ( (PBITMAPINFO)bmi, (PINT)&DIB_Palette_Type );
- if (NULL == DIB_Palette)
- {
- EngUnlockSurface(SourceSurf);
- EngDeleteSurface((HSURF)SourceBitmap);
- BITMAPOBJ_UnlockBitmap(bitmap);
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- return 0;
- }
-
- // Determine XLATEOBJ for color translation
- XlateObj = IntEngCreateXlate(DDB_Palette_Type, DIB_Palette_Type, DDB_Palette, DIB_Palette);
- if (NULL == XlateObj)
- {
- PALETTE_FreePaletteByHandle(DIB_Palette);
- EngUnlockSurface(SourceSurf);
- EngDeleteSurface((HSURF)SourceBitmap);
- BITMAPOBJ_UnlockBitmap(bitmap);
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- return 0;
- }
-
- // Zero point
- ZeroPoint.x = 0;
- ZeroPoint.y = 0;
-
- // Determine destination rectangle
- DestRect.left = 0;
- DestRect.top = abs(bmi->bmiHeader.biHeight) - StartScan - ScanLines;
- DestRect.right = SourceSize.cx;
- DestRect.bottom = DestRect.top + ScanLines;
-
- copyBitsResult = EngCopyBits(DestSurf, SourceSurf, NULL, XlateObj, &DestRect, &ZeroPoint);
-
- // If it succeeded, return number of scanlines copies
- if(copyBitsResult == TRUE)
- {
- result = SourceSize.cy - 1;
- }
-
- // Clean up
- EngDeleteXlate(XlateObj);
- PALETTE_FreePaletteByHandle(DIB_Palette);
- EngUnlockSurface(SourceSurf);
- EngDeleteSurface((HSURF)SourceBitmap);
-
-// if (ColorUse == DIB_PAL_COLORS)
-// WinFree((LPSTR)lpRGB);
-
- BITMAPOBJ_UnlockBitmap(bitmap);
-
- return result;
+ HBITMAP SourceBitmap, hOldSrcBmp = NULL, hOldDstBmp = NULL;
+ HDC hdcSrc, hdcDst;
+ INT result = 0;
+ PVOID pvBits;
+
+ SourceBitmap = DIB_CreateDIBSection(DC, bmi, ColorUse, &pvBits, NULL, 0, 0);
+ if (0 == SourceBitmap)
+ {
+ DPRINT1("Error : Could not create a DIBSection.\n");
+ SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ return 0;
+ }
+
+ RtlCopyMemory(pvBits, Bits, DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
+ bmi->bmiHeader.biHeight,
+ bmi->bmiHeader.biBitCount));
+
+ hdcSrc = NtGdiCreateCompatibleDC(0);
+ hdcDst = NtGdiCreateCompatibleDC(0);
+
+ if(!(hdcSrc && hdcDst))
+ {
+ DPRINT1("Error, could not create memory DCs.\n");
+ goto cleanup;
+ }
+
+ hOldSrcBmp = NtGdiSelectBitmap(hdcSrc, SourceBitmap);
+ hOldDstBmp = NtGdiSelectBitmap(hdcDst, hBitmap);
+
+ if(!(hOldSrcBmp && hOldDstBmp))
+ {
+ DPRINT1("Error : Could not select bitmaps into DCs\n");
+ goto cleanup;
+ }
+
+ result = NtGdiBitBlt(hdcDst, 0, 0, bmi->bmiHeader.biWidth, ScanLines, hdcSrc, 0, StartScan,
+ SRCCOPY, 0, 0);
+
+ if(result)
+ result = ScanLines;
+
+cleanup:
+ if(hdcSrc)
+ {
+ if(hOldSrcBmp) NtGdiSelectBitmap(hdcSrc, hOldSrcBmp);
+ NtGdiDeleteObjectApp(hdcSrc);
+ }
+ if(hdcDst)
+ {
+ if(hOldDstBmp) NtGdiSelectBitmap(hdcDst, hOldDstBmp);
+ NtGdiDeleteObjectApp(hdcDst);
+ }
+ GreDeleteObject(SourceBitmap);
+
+ return result;
}
+// FIXME by Removing NtGdiSetDIBits!!!
+// This is a victim of the Win32k Initialization BUG!!!!!
// Converts a DIB to a device-dependent bitmap
-INT STDCALL
+INT
+APIENTRY
NtGdiSetDIBits(
- HDC hDC,
- HBITMAP hBitmap,
- UINT StartScan,
- UINT ScanLines,
- CONST VOID *Bits,
- CONST BITMAPINFO *bmi,
- UINT ColorUse)
+ HDC hDC,
+ HBITMAP hBitmap,
+ UINT StartScan,
+ UINT ScanLines,
+ CONST VOID *Bits,
+ CONST BITMAPINFO *bmi,
+ UINT ColorUse)
{
- PDC Dc;
- INT Ret;
+ PDC Dc;
+ INT Ret;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ if (!Bits) return 0;
- Dc = DC_LockDc(hDC);
- if (NULL == Dc)
+ _SEH2_TRY
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
+ ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1);
+ ProbeForRead(bmi, bmi->bmiHeader.biSize, 1);
+ ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, ColorUse), 1);
+ ProbeForRead(Bits,
+ DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
+ ScanLines,
+ bmi->bmiHeader.biBitCount),
+ 1);
}
- if (Dc->DC_Type == DC_TYPE_INFO)
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- DC_UnlockDc(Dc);
- return 0;
+ Status = _SEH2_GetExceptionCode();
}
+ _SEH2_END
- Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
+ if (!NT_SUCCESS(Status))
+ {
+ return 0;
+ }
- DC_UnlockDc(Dc);
+ Dc = DC_LockDc(hDC);
+ if (NULL == Dc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+ if (Dc->dctype == DC_TYPE_INFO)
+ {
+ DC_UnlockDc(Dc);
+ return 0;
+ }
- return Ret;
-}
+ Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
+ DC_UnlockDc(Dc);
+ return Ret;
+}
W32KAPI
INT
IN UINT cjMaxBits,
IN UINT cjMaxInfo,
IN BOOL bTransformCoordinates,
- IN OPTIONAL HANDLE hcmXform
-)
+ IN OPTIONAL HANDLE hcmXform)
{
INT ret = 0;
NTSTATUS Status = STATUS_SUCCESS;
PDC pDC;
HBITMAP hSourceBitmap = NULL;
SURFOBJ *pDestSurf, *pSourceSurf = NULL;
+ SURFACE *pSurf;
RECTL rcDest;
POINTL ptSource;
INT DIBWidth;
SIZEL SourceSize;
- XLATEOBJ *XlateObj = NULL;
- PPALGDI pDCPalette;
- HPALETTE DDBPalette, DIBPalette = NULL;
- ULONG DDBPaletteType, DIBPaletteType;
+ EXLATEOBJ exlo;
+ PPALETTE ppalDIB = NULL;
+ HPALETTE hpalDIB = NULL;
if (!Bits) return 0;
+ _SEH2_TRY
+ {
+ ProbeForRead(bmi, cjMaxInfo, 1);
+ ProbeForRead(Bits, cjMaxBits, 1);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if (!NT_SUCCESS(Status))
+ {
+ return 0;
+ }
+
pDC = DC_LockDc(hDC);
if (!pDC)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
- if (pDC->DC_Type == DC_TYPE_INFO)
+ if (pDC->dctype == DC_TYPE_INFO)
{
DC_UnlockDc(pDC);
return 0;
}
- pDestSurf = EngLockSurface((HSURF)pDC->w.hBitmap);
- if (!pDestSurf)
- {
- /* FIXME: SetLastError ? */
- DC_UnlockDc(pDC);
- return 0;
- }
+ pSurf = pDC->dclevel.pSurface;
+
+ pDestSurf = pSurf ? &pSurf->SurfObj : NULL;
+
+ ScanLines = min(ScanLines, abs(bmi->bmiHeader.biHeight) - StartScan);
rcDest.left = XDest;
rcDest.top = YDest;
rcDest.top += pDC->ptlDCOrig.y;
rcDest.right = rcDest.left + Width;
rcDest.bottom = rcDest.top + Height;
+ rcDest.top += StartScan;
+
ptSource.x = XSrc;
ptSource.y = YSrc;
- /* Enter SEH, as the bits are user mode */
- _SEH_TRY
- {
- SourceSize.cx = bmi->bmiHeader.biWidth;
- SourceSize.cy = ScanLines;
- DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
+ SourceSize.cx = bmi->bmiHeader.biWidth;
+ SourceSize.cy = ScanLines;
- ProbeForRead(Bits, DIBWidth * abs(bmi->bmiHeader.biHeight), 1);
- hSourceBitmap = EngCreateBitmap(SourceSize,
- DIBWidth,
- BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression),
- bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
- (PVOID) Bits);
- if (!hSourceBitmap)
- {
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- Status = STATUS_NO_MEMORY;
- _SEH_LEAVE;
- }
+ DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
- pSourceSurf = EngLockSurface((HSURF)hSourceBitmap);
- if (!pSourceSurf)
- {
- Status = STATUS_UNSUCCESSFUL;
- _SEH_LEAVE;
- }
-
-
- /* Obtain destination palette from the DC */
- pDCPalette = PALETTE_LockPalette(((GDIDEVICE *)pDC->pPDev)->DevInfo.hpalDefault);
- if (!pDCPalette)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- Status = STATUS_UNSUCCESSFUL;
- _SEH_LEAVE;
- }
- DDBPaletteType = pDCPalette->Mode;
- DDBPalette = ((GDIDEVICE *)pDC->pPDev)->DevInfo.hpalDefault;
- PALETTE_UnlockPalette(pDCPalette);
-
- DIBPalette = BuildDIBPalette(bmi, (PINT)&DIBPaletteType);
- if (!DIBPalette)
- {
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- Status = STATUS_NO_MEMORY;
- _SEH_LEAVE;
- }
+ hSourceBitmap = EngCreateBitmap(SourceSize,
+ DIBWidth,
+ BitmapFormat(bmi->bmiHeader.biBitCount,
+ bmi->bmiHeader.biCompression),
+ bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
+ (PVOID) Bits);
+ if (!hSourceBitmap)
+ {
+ SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ Status = STATUS_NO_MEMORY;
+ goto Exit;
+ }
- /* Determine XlateObj */
- XlateObj = IntEngCreateXlate(DDBPaletteType, DIBPaletteType, DDBPalette, DIBPalette);
- if (!XlateObj)
- {
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- Status = STATUS_NO_MEMORY;
- _SEH_LEAVE;
- }
+ pSourceSurf = EngLockSurface((HSURF)hSourceBitmap);
+ if (!pSourceSurf)
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ goto Exit;
+ }
- /* Copy the bits */
- Status = IntEngBitBlt(pDestSurf,
- pSourceSurf,
- NULL,
- pDC->CombinedClip,
- XlateObj,
- &rcDest,
- &ptSource,
- NULL,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCCOPY));
+ ASSERT(pSurf->ppal);
+ /* Create a palette for the DIB */
+ hpalDIB = BuildDIBPalette(bmi);
+ if (!hpalDIB)
+ {
+ SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ Status = STATUS_NO_MEMORY;
+ goto Exit;
}
- _SEH_HANDLE
+
+ /* Lock the DIB palette */
+ ppalDIB = PALETTE_LockPalette(hpalDIB);
+ if (!ppalDIB)
{
- Status = _SEH_GetExceptionCode();
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ Status = STATUS_UNSUCCESSFUL;
+ goto Exit;
}
- _SEH_END
+ /* Initialize EXLATEOBJ */
+ EXLATEOBJ_vInitialize(&exlo, ppalDIB, pSurf->ppal, 0, 0, 0);
+
+ /* Copy the bits */
+ DPRINT("BitsToDev with dstsurf=(%d|%d) (%d|%d), src=(%d|%d) w=%d h=%d\n",
+ rcDest.left, rcDest.top, rcDest.right, rcDest.bottom,
+ ptSource.x, ptSource.y, SourceSize.cx, SourceSize.cy);
+ Status = IntEngBitBlt(pDestSurf,
+ pSourceSurf,
+ NULL,
+ pDC->rosdc.CombinedClip,
+ &exlo.xlo,
+ &rcDest,
+ &ptSource,
+ NULL,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCCOPY));
+
+ /* Cleanup EXLATEOBJ */
+ EXLATEOBJ_vCleanup(&exlo);
+
+Exit:
if (NT_SUCCESS(Status))
{
- /* FIXME: Should probably be only the number of lines actually copied */
ret = ScanLines;
}
+ if (ppalDIB) PALETTE_UnlockPalette(ppalDIB);
+
if (pSourceSurf) EngUnlockSurface(pSourceSurf);
if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
- if (XlateObj) EngDeleteXlate(XlateObj);
- if (DIBPalette) PALETTE_FreePaletteByHandle(DIBPalette);
- EngUnlockSurface(pDestSurf);
+ if (hpalDIB) PALETTE_FreePaletteByHandle(hpalDIB);
DC_UnlockDc(pDC);
return ret;
/* Converts a device-dependent bitmap to a DIB */
-INT STDCALL
-NtGdiGetDIBitsInternal(HDC hDC,
- HBITMAP hBitmap,
- UINT StartScan,
- UINT ScanLines,
- LPBYTE Bits,
- LPBITMAPINFO Info,
- UINT Usage,
- UINT MaxBits,
- UINT MaxInfo)
+INT
+APIENTRY
+NtGdiGetDIBitsInternal(
+ HDC hDC,
+ HBITMAP hBitmap,
+ UINT StartScan,
+ UINT ScanLines,
+ LPBYTE Bits,
+ LPBITMAPINFO Info,
+ UINT Usage,
+ UINT MaxBits,
+ UINT MaxInfo)
{
- PDC Dc;
- BITMAPOBJ *BitmapObj = NULL;
- HBITMAP hDestBitmap = NULL;
- HPALETTE hSourcePalette = NULL;
- HPALETTE hDestPalette = NULL;
- PPALGDI SourcePalette = NULL;
- PPALGDI DestPalette = NULL;
- NTSTATUS Status = STATUS_SUCCESS;
- ULONG Result = 0;
- BOOL bPaletteMatch = FALSE;
+ BITMAPCOREINFO* pbmci = NULL;
+ PSURFACE psurf = NULL;
+ PDC pDC;
+ LONG width, height;
+ WORD planes, bpp;
+ DWORD compr, size ;
+ int i, bitmap_type;
+ RGBTRIPLE* rgbTriples;
+ RGBQUAD* rgbQuads;
+ VOID* colorPtr;
+ NTSTATUS Status = STATUS_SUCCESS;
DPRINT("Entered NtGdiGetDIBitsInternal()\n");
- /* Get handle for the palette in DC. */
- Dc = DC_LockDc(hDC);
- if (Dc == NULL) return 0;
- if (Dc->DC_Type == DC_TYPE_INFO)
- {
- DC_UnlockDc(Dc);
+ if ((Usage && Usage != DIB_PAL_COLORS) || !Info || !hBitmap)
return 0;
+
+ _SEH2_TRY
+ {
+ /* Probe for read and write */
+ ProbeForRead(Info, MaxInfo, 1);
+ ProbeForWrite(Info, MaxInfo, 1);
+ if (Bits) ProbeForWrite(Bits, MaxBits, 1);
}
- /* Source palette obtained from the windows hdc */
- hSourcePalette = Dc->DcLevel.hpal;
- DC_UnlockDc(Dc);
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
- /* don't do anything if we fail this */
- if (Usage != DIB_RGB_COLORS && Usage != DIB_PAL_COLORS)
+ if (!NT_SUCCESS(Status))
+ {
return 0;
+ }
- /* Get a pointer to the source bitmap object */
- BitmapObj = BITMAPOBJ_LockBitmap(hBitmap);
- if (BitmapObj == NULL)
- return 0;
+ colorPtr = (LPBYTE)Info + Info->bmiHeader.biSize;
+ rgbTriples = colorPtr;
+ rgbQuads = colorPtr;
+
+ bitmap_type = DIB_GetBitmapInfo(&Info->bmiHeader,
+ &width,
+ &height,
+ &planes,
+ &bpp,
+ &compr,
+ &size);
+ if(bitmap_type == -1)
+ {
+ DPRINT("Wrong bitmap format\n");
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ else if(bitmap_type == 0)
+ {
+ /* We need a BITMAPINFO to create a DIB, but we have to fill
+ * the BITMAPCOREINFO we're provided */
+ pbmci = (BITMAPCOREINFO*)Info;
+ Info = DIB_ConvertBitmapInfo((BITMAPINFO*)pbmci, Usage);
+ if(Info == NULL)
+ {
+ DPRINT1("Error, could not convert the BITMAPCOREINFO!\n");
+ return 0;
+ }
+ rgbQuads = Info->bmiColors;
+ }
- /* fill out the BITMAPINFO struct */
- if (Bits == NULL)
+ pDC = DC_LockDc(hDC);
+ if (pDC == NULL || pDC->dctype == DC_TYPE_INFO)
{
- _SEH_TRY
- {
- if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- BITMAPCOREHEADER* coreheader;
-
- ProbeForWrite(Info, sizeof(BITMAPINFO), 1);
-
- coreheader = (BITMAPCOREHEADER*) Info;
- coreheader->bcWidth =BitmapObj->SurfObj.sizlBitmap.cx;
- coreheader->bcPlanes = 1;
- coreheader->bcBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
- coreheader->bcHeight = BitmapObj->SurfObj.sizlBitmap.cy;
+ ScanLines = 0;
+ goto done;
+ }
- if (BitmapObj->SurfObj.lDelta > 0)
- coreheader->bcHeight = -coreheader->bcHeight;
- }
+ /* Get a pointer to the source bitmap object */
+ psurf = SURFACE_LockSurface(hBitmap);
+ if (psurf == NULL)
+ {
+ ScanLines = 0;
+ goto done;
+ }
- if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
- {
- ProbeForWrite(Info, sizeof(BITMAPINFO), 1);
-
- Info->bmiHeader.biWidth = BitmapObj->SurfObj.sizlBitmap.cx;
- Info->bmiHeader.biHeight = BitmapObj->SurfObj.sizlBitmap.cy;
- /* Report negtive height for top-down bitmaps. */
- if (BitmapObj->SurfObj.lDelta > 0)
- Info->bmiHeader.biHeight = -Info->bmiHeader.biHeight;
- Info->bmiHeader.biPlanes = 1;
- Info->bmiHeader.biBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
- if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
- {
- switch (BitmapObj->SurfObj.iBitmapFormat)
+ /* Fill in the structure */
+ switch(bpp)
+ {
+ case 0: /* Only info */
+ if(pbmci)
+ {
+ pbmci->bmciHeader.bcWidth = psurf->SurfObj.sizlBitmap.cx;
+ pbmci->bmciHeader.bcHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
+ -psurf->SurfObj.sizlBitmap.cy :
+ psurf->SurfObj.sizlBitmap.cy;
+ pbmci->bmciHeader.bcPlanes = 1;
+ pbmci->bmciHeader.bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+ }
+ Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
+ Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
+ -psurf->SurfObj.sizlBitmap.cy :
+ psurf->SurfObj.sizlBitmap.cy;;
+ Info->bmiHeader.biPlanes = 1;
+ Info->bmiHeader.biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+ Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( Info->bmiHeader.biWidth,
+ Info->bmiHeader.biHeight,
+ Info->bmiHeader.biBitCount);
+ if(psurf->hSecure)
+ {
+ switch(Info->bmiHeader.biBitCount)
+ {
+ case 16:
+ case 32:
+ Info->bmiHeader.biCompression = BI_BITFIELDS;
+ break;
+ default:
+ Info->bmiHeader.biCompression = BI_RGB;
+ break;
+ }
+ }
+ else if(Info->bmiHeader.biBitCount > 8)
+ {
+ Info->bmiHeader.biCompression = BI_BITFIELDS;
+ }
+ else
+ {
+ Info->bmiHeader.biCompression = BI_RGB;
+ }
+ Info->bmiHeader.biXPelsPerMeter = 0;
+ Info->bmiHeader.biYPelsPerMeter = 0;
+ Info->bmiHeader.biClrUsed = 0;
+ Info->bmiHeader.biClrImportant = 0;
+ ScanLines = psurf->SurfObj.sizlBitmap.cy;
+ /* Get Complete info now */
+ goto done;
+
+ case 1:
+ case 4:
+ case 8:
+ Info->bmiHeader.biClrUsed = 0;
+
+ /* If the bitmap if a DIB section and has the same format than what
+ * we're asked, go ahead! */
+ if((psurf->hSecure) &&
+ (BitsPerFormat(psurf->SurfObj.iBitmapFormat) == bpp))
+ {
+ if(Usage == DIB_RGB_COLORS)
+ {
+ unsigned int colors = min(psurf->ppal->NumColors, 1 << bpp);
+
+ if(pbmci)
+ {
+ for(i=0; i < colors; i++)
+ {
+ rgbTriples[i].rgbtRed = psurf->ppal->IndexedColors[i].peRed;
+ rgbTriples[i].rgbtGreen = psurf->ppal->IndexedColors[i].peGreen;
+ rgbTriples[i].rgbtBlue = psurf->ppal->IndexedColors[i].peBlue;
+ }
+ }
+ if(colors != 1 << bpp) Info->bmiHeader.biClrUsed = colors;
+ RtlCopyMemory(rgbQuads, psurf->ppal->IndexedColors, colors * sizeof(RGBQUAD));
+ }
+ else
+ {
+ for(i=0; i < 1 << bpp; i++)
+ {
+ if(pbmci) ((WORD*)rgbTriples)[i] = i;
+ ((WORD*)rgbQuads)[i] = i;
+ }
+ }
+ }
+ else
+ {
+ if(Usage == DIB_PAL_COLORS)
+ {
+ for(i=0; i < 1 << bpp; i++)
+ {
+ if(pbmci) ((WORD*)rgbTriples)[i] = i;
+ ((WORD*)rgbQuads)[i] = i;
+ }
+ }
+ else if(bpp > 1 && bpp == BitsPerFormat(psurf->SurfObj.iBitmapFormat)) {
+ /* For color DDBs in native depth (mono DDBs always have
+ a black/white palette):
+ Generate the color map from the selected palette */
+ PPALETTE pDcPal = PALETTE_LockPalette(pDC->dclevel.hpal);
+ if(!pDcPal)
+ {
+ ScanLines = 0 ;
+ goto done ;
+ }
+ for (i = 0; i < pDcPal->NumColors; i++) {
+ if (pbmci)
{
- case BMF_1BPP:
- case BMF_4BPP:
- case BMF_8BPP:
- case BMF_16BPP:
- case BMF_24BPP:
- case BMF_32BPP:
- Info->bmiHeader.biCompression = BI_RGB;
- break;
- case BMF_4RLE:
- Info->bmiHeader.biCompression = BI_RLE4;
- break;
- case BMF_8RLE:
- Info->bmiHeader.biCompression = BI_RLE8;
- break;
- case BMF_JPEG:
- Info->bmiHeader.biCompression = BI_JPEG;
- break;
- case BMF_PNG:
- Info->bmiHeader.biCompression = BI_PNG;
- break;
+ rgbTriples[i].rgbtRed = pDcPal->IndexedColors[i].peRed;
+ rgbTriples[i].rgbtGreen = pDcPal->IndexedColors[i].peGreen;
+ rgbTriples[i].rgbtBlue = pDcPal->IndexedColors[i].peBlue;
+ }
+
+ rgbQuads[i].rgbRed = pDcPal->IndexedColors[i].peRed;
+ rgbQuads[i].rgbGreen = pDcPal->IndexedColors[i].peGreen;
+ rgbQuads[i].rgbBlue = pDcPal->IndexedColors[i].peBlue;
+ rgbQuads[i].rgbReserved = 0;
+ }
+ PALETTE_UnlockPalette(pDcPal);
+ } else {
+ switch (bpp) {
+ case 1:
+ if (pbmci)
+ {
+ rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
+ rgbTriples[0].rgbtBlue = 0;
+ rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
+ rgbTriples[1].rgbtBlue = 0xff;
+ }
+ rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
+ rgbQuads[0].rgbBlue = 0;
+ rgbQuads[0].rgbReserved = 0;
+ rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
+ rgbQuads[1].rgbBlue = 0xff;
+ rgbQuads[1].rgbReserved = 0;
+ break;
+
+ case 4:
+ if (pbmci)
+ RtlCopyMemory(rgbTriples, EGAColorsTriples, sizeof(EGAColorsTriples));
+ RtlCopyMemory(rgbQuads, EGAColorsQuads, sizeof(EGAColorsQuads));
+
+ break;
+
+ case 8:
+ {
+ INT r, g, b;
+ RGBQUAD *color;
+ if (pbmci)
+ {
+ RGBTRIPLE *colorTriple;
+
+ RtlCopyMemory(rgbTriples, DefLogPaletteTriples,
+ 10 * sizeof(RGBTRIPLE));
+ RtlCopyMemory(rgbTriples + 246, DefLogPaletteTriples + 10,
+ 10 * sizeof(RGBTRIPLE));
+ colorTriple = rgbTriples + 10;
+ for(r = 0; r <= 5; r++) /* FIXME */
+ {
+ for(g = 0; g <= 5; g++)
+ {
+ for(b = 0; b <= 5; b++)
+ {
+ colorTriple->rgbtRed = (r * 0xff) / 5;
+ colorTriple->rgbtGreen = (g * 0xff) / 5;
+ colorTriple->rgbtBlue = (b * 0xff) / 5;
+ color++;
+ }
+ }
+ }
+ }
+ memcpy(rgbQuads, DefLogPaletteQuads,
+ 10 * sizeof(RGBQUAD));
+ memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
+ 10 * sizeof(RGBQUAD));
+ color = rgbQuads + 10;
+ for(r = 0; r <= 5; r++) /* FIXME */
+ {
+ for(g = 0; g <= 5; g++)
+ {
+ for(b = 0; b <= 5; b++)
+ {
+ color->rgbRed = (r * 0xff) / 5;
+ color->rgbGreen = (g * 0xff) / 5;
+ color->rgbBlue = (b * 0xff) / 5;
+ color->rgbReserved = 0;
+ color++;
+ }
+ }
+ }
}
-
- Info->bmiHeader.biSizeImage = BitmapObj->SurfObj.cjBits;
- Info->bmiHeader.biXPelsPerMeter = 0; /* FIXME */
- Info->bmiHeader.biYPelsPerMeter = 0; /* FIXME */
- Info->bmiHeader.biClrUsed = 0;
- Info->bmiHeader.biClrImportant = 1 << Info->bmiHeader.biBitCount; /* FIXME */
}
}
}
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END
+ break;
- if (NT_SUCCESS(Status))
+ case 15:
+ if (Info->bmiHeader.biCompression == BI_BITFIELDS)
{
- Result = BitmapObj->SurfObj.sizlBitmap.cy;
+ ((PDWORD)Info->bmiColors)[0] = 0x7c00;
+ ((PDWORD)Info->bmiColors)[1] = 0x03e0;
+ ((PDWORD)Info->bmiColors)[2] = 0x001f;
}
- }
- else
- {
- SIZEL DestSize;
- ULONG SourcePaletteType = 0;
- ULONG DestPaletteType;
- POINTL SourcePoint;
- ULONG Index;
+ break;
- _SEH_TRY
+ case 16:
+ if (Info->bmiHeader.biCompression == BI_BITFIELDS)
{
- ProbeForRead(Info, sizeof(BITMAPINFO), 1);
-
- if (Info->bmiHeader.biBitCount == BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat))
- {
- hDestPalette = hSourcePalette;
- bPaletteMatch = TRUE;
- }
- else
- hDestPalette = BuildDIBPalette(Info, (PINT)&DestPaletteType); //hDestPalette = Dc->DevInfo->hpalDefault;
-
- SourcePalette = PALETTE_LockPalette(hSourcePalette);
- /* FIXME - SourcePalette can be NULL!!! Don't assert here! */
- ASSERT(SourcePalette);
- SourcePaletteType = SourcePalette->Mode;
- PALETTE_UnlockPalette(SourcePalette);
-
- if (bPaletteMatch)
- {
- DestPalette = PALETTE_LockPalette(hDestPalette);
- /* FIXME - DestPalette can be NULL!!!! Don't assert here!!! */
- DPRINT("DestPalette : %p\n", DestPalette);
- ASSERT(DestPalette);
- DestPaletteType = DestPalette->Mode;
- }
+ if (psurf->hSecure)
+ {
+ ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
+ ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
+ ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
+ }
else
{
- DestPalette = SourcePalette;
- }
-
- /* Copy palette. */
- /* FIXME: This is largely incomplete. */
- if (Info->bmiHeader.biBitCount <= 8)
- {
- if (Usage == DIB_RGB_COLORS)
- {
- for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount) && Index < DestPalette->NumColors;
- Index++)
- {
- Info->bmiColors[Index].rgbRed = DestPalette->IndexedColors[Index].peRed;
- Info->bmiColors[Index].rgbGreen = DestPalette->IndexedColors[Index].peGreen;
- Info->bmiColors[Index].rgbBlue = DestPalette->IndexedColors[Index].peBlue;
- }
- }
-
- if (Usage == DIB_PAL_COLORS)
- {
- DPRINT1("GetDIBits with DIB_PAL_COLORS isn't implemented yet\n");
- }
- }
-
- if (bPaletteMatch)
- PALETTE_UnlockPalette(DestPalette);
-
- /* Create the destination bitmap to for the copy operation */
- if (StartScan > BitmapObj->SurfObj.sizlBitmap.cy)
- {
- _SEH_YIELD(goto cleanup);
+ ((PDWORD)Info->bmiColors)[0] = 0xf800;
+ ((PDWORD)Info->bmiColors)[1] = 0x07e0;
+ ((PDWORD)Info->bmiColors)[2] = 0x001f;
}
- else
- {
- ScanLines = min(ScanLines, BitmapObj->SurfObj.sizlBitmap.cy - StartScan);
- DestSize.cx = BitmapObj->SurfObj.sizlBitmap.cx;
- DestSize.cy = ScanLines;
-
- hDestBitmap = NULL;
-
- ProbeForWrite(Bits, sizeof(BitmapObj->SurfObj.cjBits), 1);
-
- if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
-
- hDestBitmap = EngCreateBitmap(DestSize,
- DIB_GetDIBWidthBytes(DestSize.cx, coreheader->bcBitCount),
- BitmapFormat(coreheader->bcBitCount, BI_RGB),
- 0 < coreheader->bcHeight ? 0 : BMF_TOPDOWN,
- Bits);
- }
-
- if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
- {
- hDestBitmap = EngCreateBitmap(DestSize,
- /* DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount), */
- DestSize.cx * (Info->bmiHeader.biBitCount >> 3), /* HACK */
- BitmapFormat(Info->bmiHeader.biBitCount, Info->bmiHeader.biCompression),
- 0 < Info->bmiHeader.biHeight ? 0 : BMF_TOPDOWN,
- Bits);
- }
-
- if (hDestBitmap == NULL)
- _SEH_YIELD(goto cleanup);
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
}
- _SEH_END
+ break;
- if (NT_SUCCESS(Status))
+ case 24:
+ case 32:
+ if (Info->bmiHeader.biCompression == BI_BITFIELDS)
{
- XLATEOBJ *XlateObj;
- SURFOBJ *DestSurfObj;
- RECTL DestRect;
-
- XlateObj = IntEngCreateXlate(DestPaletteType,
- SourcePaletteType,
- hDestPalette,
- hSourcePalette);
-
- SourcePoint.x = 0;
- SourcePoint.y = BitmapObj->SurfObj.sizlBitmap.cy - (StartScan + ScanLines);
-
- /* Determine destination rectangle */
- DestRect.top = 0;
- DestRect.left = 0;
- DestRect.right = DestSize.cx;
- DestRect.bottom = DestSize.cy;
-
- DestSurfObj = EngLockSurface((HSURF)hDestBitmap);
-
- if (EngCopyBits(DestSurfObj,
- &BitmapObj->SurfObj,
- NULL,
- XlateObj,
- &DestRect,
- &SourcePoint))
+ if (psurf->hSecure)
+ {
+ ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
+ ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
+ ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
+ }
+ else
{
- Result = ScanLines;
+ ((PDWORD)Info->bmiColors)[0] = 0xff0000;
+ ((PDWORD)Info->bmiColors)[1] = 0x00ff00;
+ ((PDWORD)Info->bmiColors)[2] = 0x0000ff;
}
-
- EngDeleteXlate(XlateObj);
- EngUnlockSurface(DestSurfObj);
}
+ break;
}
+ Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(width, height, bpp);
-cleanup:
- if (hDestBitmap != NULL)
- EngDeleteSurface((HSURF)hDestBitmap);
-
- if (hDestPalette != NULL && bPaletteMatch == FALSE)
- PALETTE_FreePaletteByHandle(hDestPalette);
-
- BITMAPOBJ_UnlockBitmap(BitmapObj);
-
- DPRINT("leaving NtGdiGetDIBitsInternal\n");
+ if(Bits && ScanLines)
+ {
+ /* Create a DIBSECTION, blt it, profit */
+ PVOID pDIBits ;
+ HBITMAP hBmpDest, hOldDest = NULL, hOldSrc = NULL;
+ HDC hdcDest = NULL, hdcSrc;
+ BOOL ret ;
- return Result;
+ if (StartScan > psurf->SurfObj.sizlBitmap.cy)
+ {
+ ScanLines = 0;
+ goto done;
+ }
+ else
+ {
+ ScanLines = min(ScanLines, psurf->SurfObj.sizlBitmap.cy - StartScan);
+ }
+
+ hBmpDest = DIB_CreateDIBSection(pDC, Info, Usage, &pDIBits, NULL, 0, 0);
+
+ if(!hBmpDest)
+ {
+ DPRINT1("Unable to create a DIB Section!\n");
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ ScanLines = 0;
+ goto done ;
+ }
+
+ if(psurf->hdc)
+ hdcSrc = psurf->hdc;
+ else
+ {
+ hdcSrc = NtGdiCreateCompatibleDC(0);
+ if(!hdcSrc)
+ {
+ DPRINT1("Error: could not create HDC!\n");
+ ScanLines = 0;
+ goto cleanup_blt;
+ }
+ hOldSrc = NtGdiSelectBitmap(hdcSrc, hBitmap);
+ if(!hOldSrc)
+ {
+ DPRINT1("Error : Could not Select bitmap\n");
+ ScanLines = 0;
+ goto cleanup_blt;
+ }
+ }
+
+ hdcDest = NtGdiCreateCompatibleDC(0);
+ if(!hdcDest)
+ {
+ DPRINT1("Error: could not create HDC!\n");
+ ScanLines = 0;
+ goto cleanup_blt;
+ }
+ hOldDest = NtGdiSelectBitmap(hdcDest, hBmpDest);
+ if(!hOldDest)
+ {
+ DPRINT1("Error : Could not Select bitmap\n");
+ ScanLines = 0;
+ goto cleanup_blt;
+ }
+
+ ret = GreStretchBltMask(hdcDest,
+ 0,
+ 0,
+ width,
+ height,
+ hdcSrc,
+ 0,
+ StartScan,
+ psurf->SurfObj.sizlBitmap.cx,
+ ScanLines,
+ SRCCOPY,
+ 0,
+ NULL,
+ 0,
+ 0);
+
+ if(!ret)
+ ScanLines = 0;
+ else
+ {
+ Status = STATUS_SUCCESS;
+ _SEH2_TRY
+ {
+ RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, height, bpp));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("Unable to copy bits to the user provided pointer\n");
+ ScanLines = 0;
+ }
+ }
+
+ cleanup_blt:
+ if(hdcSrc && (hdcSrc != psurf->hdc))
+ {
+ if(hOldSrc) NtGdiSelectBitmap(hdcSrc, hOldSrc);
+ NtGdiDeleteObjectApp(hdcSrc);
+ }
+ if(hdcSrc)
+ {
+ if(hOldDest) NtGdiSelectBitmap(hdcDest, hOldDest);
+ NtGdiDeleteObjectApp(hdcDest);
+ }
+ GreDeleteObject(hBmpDest);
+ }
+
+done:
+
+ if(pDC) DC_UnlockDc(pDC);
+ if(psurf) SURFACE_UnlockSurface(psurf);
+ if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci);
+
+ return ScanLines;
}
+
INT
APIENTRY
NtGdiStretchDIBitsInternal(
UINT cjMaxBits,
HANDLE hcmXform)
{
- HBITMAP hBitmap, hOldBitmap = NULL;
- HDC hdcMem;
- HPALETTE hPal = NULL;
- PDC pDC;
-
- if (!Bits || !BitsInfo)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- hdcMem = NtGdiCreateCompatibleDC(hDC);
- if (hdcMem == NULL)
- {
- DPRINT1("NtGdiCreateCompatibleDC fail create hdc\n");
- return 0;
- }
-
- hBitmap = NtGdiCreateCompatibleBitmap(hDC, BitsInfo->bmiHeader.biWidth,
- BitsInfo->bmiHeader.biHeight);
- if (hBitmap == NULL)
- {
- DPRINT1("NtGdiCreateCompatibleBitmap fail create bitmap\n");
- DPRINT1("hDC : 0x%08x \n", hDC);
- DPRINT1("BitsInfo->bmiHeader.biWidth : 0x%08x \n", BitsInfo->bmiHeader.biWidth);
- DPRINT1("BitsInfo->bmiHeader.biHeight : 0x%08x \n", BitsInfo->bmiHeader.biHeight);
- return 0;
- }
-
- /* Select the bitmap into hdcMem, and save a handle to the old bitmap */
- hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
-
- if(Usage == DIB_PAL_COLORS)
- {
- hPal = NtGdiGetDCObject(hDC, GDI_OBJECT_TYPE_PALETTE);
- hPal = GdiSelectPalette(hdcMem, hPal, FALSE);
- }
-
- if (BitsInfo->bmiHeader.biCompression == BI_RLE4 ||
- BitsInfo->bmiHeader.biCompression == BI_RLE8)
- {
- /* copy existing bitmap from destination dc */
- if (SrcWidth == DestWidth && SrcHeight == DestHeight)
- NtGdiBitBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, hDC, XDest, YDest, ROP, 0, 0);
- else
- NtGdiStretchBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, hDC, XDest, YDest, DestWidth, DestHeight,
- ROP, 0);
- }
-
- pDC = DC_LockDc(hdcMem);
- if (pDC != NULL)
- {
- /* Note BitsInfo->bmiHeader.biHeight is the number of scanline,
- * if it negitve we getting to many scanline for scanline is UINT not
- * a INT, so we need make the negtive value to positve and that make the
- * count correct for negtive bitmap, TODO : we need testcase for this api */
-
- IntSetDIBits(pDC, hBitmap, 0, abs(BitsInfo->bmiHeader.biHeight), Bits,
- BitsInfo, Usage);
+ HBITMAP hBitmap, hOldBitmap = NULL;
+ HDC hdcMem = NULL;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PVOID pvDIBits;
+ INT Ret = 0;
- DC_UnlockDc(pDC);
- }
+ if (!Bits || !BitsInfo)
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ /* Create a DIB Section, data will be probed there */
+ hBitmap = NtGdiCreateDIBSection(hDC,
+ NULL,
+ 0,
+ BitsInfo,
+ Usage,
+ 0,
+ 0,
+ 0,
+ &pvDIBits);
+
+ if(!hBitmap)
+ {
+ DPRINT1("Failed to create a DIB.\n");
+ return 0;
+ }
+
+ _SEH2_TRY
+ {
+ ProbeForRead(Bits, cjMaxBits, 1);
+ RtlCopyMemory(pvDIBits, Bits, DIB_GetDIBImageBytes(BitsInfo->bmiHeader.biWidth,
+ BitsInfo->bmiHeader.biHeight,
+ BitsInfo->bmiHeader.biBitCount));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("Error : Could not read DIB bits\n");
+ SetLastNtError(Status);
+ goto cleanup;
+ }
+
+ hdcMem = NtGdiCreateCompatibleDC(0);
+ if(!hdcMem)
+ {
+ DPRINT1("Failed to create a memory DC!");
+ goto cleanup;
+ }
+
+ hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
+ if(!hOldBitmap)
+ {
+ DPRINT1("Could not select the DIB into the memory DC\n");
+ goto cleanup;
+ }
+
+ /* Do we want to stretch ? */
+ if((SrcWidth == DestWidth) && (SrcHeight == DestHeight))
+ {
+ Ret = NtGdiBitBlt(hDC, XDest, YDest, XDest + DestWidth, YDest + DestHeight,
+ hdcMem, XSrc, YSrc, ROP, 0, 0);
+ }
+ else
+ {
+ Ret = NtGdiStretchBlt(hDC, XDest, YDest, XDest + DestWidth, YDest + DestHeight,
+ hdcMem, XSrc, YSrc, XSrc + SrcWidth, YSrc + SrcHeight,
+ ROP, 0);
+ }
+
+ if(Ret)
+ Ret = SrcHeight ;
- /* Origin for DIBitmap may be bottom left (positive biHeight) or top
- left (negative biHeight) */
- if (SrcWidth == DestWidth && SrcHeight == DestHeight)
- NtGdiBitBlt(hDC, XDest, YDest, DestWidth, DestHeight,
- hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
- ROP, 0, 0);
- else
- NtGdiStretchBlt(hDC, XDest, YDest, DestWidth, DestHeight,
- hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, ROP, 0);
+cleanup:
+ if(hdcMem)
+ {
+ if(hOldBitmap) NtGdiSelectBitmap(hdcMem, hOldBitmap);
+ NtGdiDeleteObjectApp(hdcMem);
+ }
+ GreDeleteObject(hBitmap);
+
+ return Ret;
+}
- /* cleanup */
- if(hPal)
- GdiSelectPalette(hdcMem, hPal, FALSE);
- if (hOldBitmap)
- NtGdiSelectBitmap(hdcMem, hOldBitmap);
+HBITMAP
+FASTCALL
+IntCreateDIBitmap(
+ PDC Dc,
+ INT width,
+ INT height,
+ UINT bpp,
+ DWORD init,
+ LPBYTE bits,
+ PBITMAPINFO data,
+ DWORD coloruse)
+{
+ HBITMAP handle;
+ BOOL fColor;
- NtGdiDeleteObjectApp(hdcMem);
+ // 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.
- NtGdiDeleteObject(hBitmap);
+ if (bpp != 1) fColor = TRUE;
+ else if ((coloruse != DIB_RGB_COLORS) || (init != CBM_INIT) || !data) fColor = FALSE;
+ else
+ {
+ const RGBQUAD *rgb = (RGBQUAD*)((PBYTE)data + data->bmiHeader.biSize);
+ DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
- return SrcHeight;
-}
+ // Check if the first color of the colormap is black
+ if ((col == RGB(0, 0, 0)))
+ {
+ rgb++;
+ col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
+ // If the second color is white, create a monochrome bitmap
+ fColor = (col != RGB(0xff,0xff,0xff));
+ }
+ else fColor = TRUE;
+ }
-HBITMAP
-FASTCALL
-IntCreateDIBitmap(PDC Dc,
- INT width,
- INT height,
- UINT bpp,
- DWORD init,
- LPBYTE bits,
- PBITMAPINFO data,
- DWORD coloruse)
-{
- HBITMAP handle;
- BOOL fColor;
-
- // 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.
-
- if (bpp != 1) fColor = TRUE;
- else if ((coloruse != DIB_RGB_COLORS) || (init != CBM_INIT) || !data) fColor = FALSE;
- else
- {
- if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
- {
- const RGBQUAD *rgb = data->bmiColors;
- DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
-
- // Check if the first color of the colormap is black
- if ((col == RGB(0, 0, 0)))
- {
- rgb++;
- col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
-
- // If the second color is white, create a monochrome bitmap
- fColor = (col != RGB(0xff,0xff,0xff));
- }
- else fColor = TRUE;
- }
- else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
- DWORD col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue);
-
- if ((col == RGB(0,0,0)))
- {
- rgb++;
- col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
- fColor = (col != RGB(0xff,0xff,0xff));
- }
- else fColor = TRUE;
- }
- else
- {
- DPRINT("(%ld): wrong size for data\n", data->bmiHeader.biSize );
- return 0;
- }
- }
-
- // Now create the bitmap
- if (fColor)
- {
- handle = IntCreateCompatibleBitmap(Dc, width, height);
- }
- else
- {
- handle = IntGdiCreateBitmap(width,
- height,
- 1,
- 1,
- NULL);
- }
-
- if (height < 0)
- height = -height;
-
- if (NULL != handle && CBM_INIT == init)
- {
- IntSetDIBits(Dc, handle, 0, height, bits, data, coloruse);
- }
-
- return handle;
+ // Now create the bitmap
+ if (fColor)
+ {
+ handle = IntCreateCompatibleBitmap(Dc, width, height);
+ }
+ else
+ {
+ handle = GreCreateBitmap(width,
+ height,
+ 1,
+ 1,
+ NULL);
+ }
+
+ if (height < 0)
+ height = -height;
+
+ if (NULL != handle && CBM_INIT == init)
+ {
+ IntSetDIBits(Dc, handle, 0, height, bits, data, coloruse);
+ }
+
+ return handle;
}
// 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
HBITMAP
APIENTRY
-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)
+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)
{
- PDC Dc;
- HBITMAP Bmp;
-
- if (!hDc)
- {
- hDc = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE);
- if (!hDc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return NULL;
- }
+ NTSTATUS Status = STATUS_SUCCESS;
- Dc = DC_LockDc(hDc);
- if (!Dc)
- {
- NtGdiDeleteObjectApp(hDc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ _SEH2_TRY
+ {
+ if(pbmi) ProbeForRead(pbmi, cjMaxInitInfo, 1);
+ if(pjInit && (fInit == CBM_INIT)) ProbeForRead(pjInit, cjMaxBits, 1);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
return NULL;
- }
-
- cjMaxInitInfo = 1;
- Bmp = IntCreateDIBitmap(Dc, cx, cy, cjMaxInitInfo, fInit, pjInit, pbmi, iUsage);
-
- DC_UnlockDc(Dc);
- NtGdiDeleteObjectApp(hDc);
- }
- else
- {
- Dc = DC_LockDc(hDc);
- if (!Dc)
- {
+ }
+
+ return GreCreateDIBitmapInternal(hDc,
+ cx,
+ cy,
+ fInit,
+ pjInit,
+ pbmi,
+ iUsage,
+ fl,
+ hcmXform);
+}
+
+HBITMAP
+FASTCALL
+GreCreateDIBitmapInternal(
+ IN HDC hDc,
+ IN INT cx,
+ IN INT cy,
+ IN DWORD fInit,
+ IN OPTIONAL LPBYTE pjInit,
+ IN OPTIONAL PBITMAPINFO pbmi,
+ IN DWORD iUsage,
+ IN FLONG fl,
+ IN HANDLE hcmXform)
+{
+ PDC Dc;
+ HBITMAP Bmp;
+ WORD bpp;
+ HDC hdcDest;
+
+ if (!hDc) /* 1bpp monochrome bitmap */
+ { // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
+ hdcDest = NtGdiCreateCompatibleDC(0);
+ if(!hdcDest)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ hdcDest = hDc;
+ }
+
+ Dc = DC_LockDc(hdcDest);
+ if (!Dc)
+ {
SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
- }
+ }
+ /* It's OK to set bpp=0 here, as IntCreateDIBitmap will create a compatible Bitmap
+ * if bpp != 1 and ignore the real value that was passed */
+ if (pbmi)
+ bpp = pbmi->bmiHeader.biBitCount;
+ else
+ bpp = 0;
+ Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
+ DC_UnlockDc(Dc);
- Bmp = IntCreateDIBitmap(Dc, cx, cy, cjMaxInitInfo, fInit, pjInit, pbmi, iUsage);
- DC_UnlockDc(Dc);
- }
- return Bmp;
+ if(!hDc)
+ {
+ NtGdiDeleteObjectApp(hdcDest);
+ }
+ return Bmp;
}
-HBITMAP STDCALL NtGdiCreateDIBSection(HDC hDC,
- IN OPTIONAL HANDLE hSection,
- IN DWORD dwOffset,
- IN LPBITMAPINFO bmi,
- DWORD Usage,
- IN UINT cjHeader,
- IN FLONG fl,
- IN ULONG_PTR dwColorSpace,
- PVOID *Bits)
+HBITMAP
+APIENTRY
+NtGdiCreateDIBSection(
+ IN HDC hDC,
+ IN OPTIONAL HANDLE hSection,
+ IN DWORD dwOffset,
+ IN BITMAPINFO* bmi,
+ IN DWORD Usage,
+ IN UINT cjHeader,
+ IN FLONG fl,
+ IN ULONG_PTR dwColorSpace,
+ OUT PVOID *Bits)
{
- HBITMAP hbitmap = 0;
- DC *dc;
- BOOL bDesktopDC = FALSE;
-
- if (!bmi) return hbitmap; // Make sure.
-
- // 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, (BITMAPINFO*)bmi, Usage, Bits,
- hSection, dwOffset, 0);
- DC_UnlockDc(dc);
- }
- else
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- }
+ HBITMAP hbitmap = 0;
+ DC *dc;
+ BOOL bDesktopDC = FALSE;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ if (!bmi) return hbitmap; // Make sure.
+
+ _SEH2_TRY
+ {
+ ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1);
+ ProbeForRead(bmi, bmi->bmiHeader.biSize, 1);
+ ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, Usage), 1);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return NULL;
+ }
- if (bDesktopDC)
- NtGdiDeleteObjectApp(hDC);
+ // If the reference hdc is null, take the desktop dc
+ if (hDC == 0)
+ {
+ hDC = NtGdiCreateCompatibleDC(0);
+ bDesktopDC = TRUE;
+ }
- return hbitmap;
+ if ((dc = DC_LockDc(hDC)))
+ {
+ hbitmap = DIB_CreateDIBSection(dc,
+ bmi,
+ Usage,
+ Bits,
+ hSection,
+ dwOffset,
+ 0);
+ DC_UnlockDc(dc);
+ }
+ else
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ }
+
+ if (bDesktopDC)
+ NtGdiDeleteObjectApp(hDC);
+
+ return hbitmap;
}
-HBITMAP STDCALL
+HBITMAP
+APIENTRY
DIB_CreateDIBSection(
- PDC dc, BITMAPINFO *bmi, UINT usage,
- LPVOID *bits, HANDLE section,
- DWORD offset, DWORD ovr_pitch)
+ PDC dc,
+ CONST BITMAPINFO *bmi,
+ UINT usage,
+ LPVOID *bits,
+ HANDLE section,
+ DWORD offset,
+ DWORD ovr_pitch)
{
- HBITMAP res = 0;
- BITMAPOBJ *bmp = NULL;
- DIBSECTION *dib = NULL;
-
- // Fill BITMAP32 structure with DIB data
- BITMAPINFOHEADER *bi = &bmi->bmiHeader;
- INT effHeight;
- ULONG totalSize;
- UINT Entries = 0;
- BITMAP bm;
- SIZEL Size;
- RGBQUAD *lpRGB;
-
- DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
- bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
- bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
-
- effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
- bm.bmType = 0;
- bm.bmWidth = bi->biWidth;
- bm.bmHeight = effHeight;
- bm.bmWidthBytes = ovr_pitch ? ovr_pitch : (ULONG) DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
-
- bm.bmPlanes = bi->biPlanes;
- bm.bmBitsPixel = bi->biBitCount;
- 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.
- totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
- ? bi->biSizeImage : (ULONG) (bm.bmWidthBytes * effHeight);
-
- if (section)
- {
-/* bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS,
- 0L, offset, totalSize); */
- DbgPrint("DIB_CreateDIBSection: Cannot yet handle section DIBs\n");
- SetLastWin32Error(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
- }
- else if (ovr_pitch && offset)
- bm.bmBits = (LPVOID) offset;
- else {
- offset = 0;
- bm.bmBits = EngAllocUserMem(totalSize, 0);
- }
-
- if(usage == DIB_PAL_COLORS)
- lpRGB = DIB_MapPaletteColors(dc, bmi);
- else
- lpRGB = bmi->bmiColors;
-
- // Allocate Memory for DIB and fill structure
- if (bm.bmBits)
- {
- dib = ExAllocatePoolWithTag(PagedPool, sizeof(DIBSECTION), TAG_DIB);
- if (dib != NULL) RtlZeroMemory(dib, sizeof(DIBSECTION));
- }
-
- if (dib)
- {
- dib->dsBm = bm;
- dib->dsBmih = *bi;
- dib->dsBmih.biSizeImage = totalSize;
-
- /* Set dsBitfields values */
- if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
- {
- dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
- }
- else switch(bi->biBitCount)
- {
- case 16:
- dib->dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)lpRGB : 0x7c00;
- dib->dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 1) : 0x03e0;
- dib->dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 2) : 0x001f; break;
-
- case 24:
- dib->dsBitfields[0] = 0xff0000;
- dib->dsBitfields[1] = 0x00ff00;
- dib->dsBitfields[2] = 0x0000ff;
- break;
+ HBITMAP res = 0;
+ SURFACE *bmp = NULL;
+ void *mapBits = NULL;
+ HPALETTE hpal ;
+
+ // Fill BITMAP32 structure with DIB data
+ CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader;
+ INT effHeight;
+ ULONG totalSize;
+ BITMAP bm;
+ SIZEL Size;
+ HANDLE hSecure;
+
+ DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
+ bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
+ bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
+
+ /* CreateDIBSection should fail for compressed formats */
+ if (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8)
+ {
+ return (HBITMAP)NULL;
+ }
- case 32:
- dib->dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)lpRGB : 0xff0000;
- dib->dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 1) : 0x00ff00;
- dib->dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 2) : 0x0000ff;
- break;
+ effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
+ bm.bmType = 0;
+ bm.bmWidth = bi->biWidth;
+ bm.bmHeight = effHeight;
+ bm.bmWidthBytes = ovr_pitch ? ovr_pitch : (ULONG) DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
+
+ bm.bmPlanes = bi->biPlanes;
+ bm.bmBitsPixel = bi->biBitCount;
+ 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.
+ totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
+ ? bi->biSizeImage : (ULONG)(bm.bmWidthBytes * effHeight);
+
+ 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))
+ {
+ return NULL;
+ }
+
+ mapOffset = offset - (offset % Sbi.AllocationGranularity);
+ mapSize = bi->biSizeImage + (offset - mapOffset);
+
+ SectionOffset.LowPart = mapOffset;
+ SectionOffset.HighPart = 0;
+
+ Status = ZwMapViewOfSection(section,
+ NtCurrentProcess(),
+ &mapBits,
+ 0,
+ 0,
+ &SectionOffset,
+ &mapSize,
+ ViewShare,
+ 0,
+ PAGE_READWRITE);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ if (mapBits) bm.bmBits = (char *)mapBits + (offset - mapOffset);
+ }
+ else if (ovr_pitch && offset)
+ bm.bmBits = (LPVOID) offset;
+ else
+ {
+ offset = 0;
+ bm.bmBits = EngAllocUserMem(totalSize, 0);
+ if(!bm.bmBits) goto cleanup;
}
- dib->dshSection = section;
- dib->dsOffset = offset;
- }
- // Create Device Dependent Bitmap and add DIB pointer
- if (dib)
- {
+// hSecure = MmSecureVirtualMemory(bm.bmBits, totalSize, PAGE_READWRITE);
+ hSecure = (HANDLE)0x1; // HACK OF UNIMPLEMENTED KERNEL STUFF !!!!
+
+ if (usage == DIB_PAL_COLORS)
+ {
+ if(dc)
+ {
+ PPALETTE pdcPal ;
+ pdcPal = PALETTE_LockPalette(dc->dclevel.hpal);
+ hpal = DIB_MapPaletteColors(pdcPal, bmi);
+ PALETTE_UnlockPalette(pdcPal);
+ }
+ else
+ {
+ /* For DIB Brushes */
+ DPRINT1("FIXME : Unsupported DIB_PAL_COLORS without a DC to map colors.\n");
+ /* HACK */
+ hpal = (HPALETTE) 0xFFFFFFFF;
+ }
+ }
+ else
+ {
+ hpal = BuildDIBPalette(bmi);
+ }
+
+ if(!hpal)
+ {
+ DPRINT1("Error : Could not create a palette for the DIB.\n");
+ goto cleanup;
+ }
+
+ // Create Device Dependent Bitmap and add DIB pointer
Size.cx = bm.bmWidth;
Size.cy = abs(bm.bmHeight);
- res = IntCreateBitmap(Size, bm.bmWidthBytes,
- BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
- BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
- (bi->biHeight < 0 ? BMF_TOPDOWN : 0),
- bm.bmBits);
- if (! res)
- {
- if (lpRGB != bmi->bmiColors)
- {
- ExFreePool(lpRGB);
- }
+ res = GreCreateBitmapEx(bm.bmWidth,
+ abs(bm.bmHeight),
+ bm.bmWidthBytes,
+ BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
+ BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
+ (bi->biHeight < 0 ? BMF_TOPDOWN : 0),
+ bi->biSizeImage,
+ bm.bmBits,
+ 0);
+ if (!res)
+ {
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- return NULL;
- }
- bmp = BITMAPOBJ_LockBitmap(res);
+ goto cleanup;
+ }
+ bmp = SURFACE_LockSurface(res);
if (NULL == bmp)
- {
- if (lpRGB != bmi->bmiColors)
- {
- ExFreePool(lpRGB);
- }
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- NtGdiDeleteObject(bmp);
- return NULL;
- }
- bmp->dib = (DIBSECTION *) dib;
- bmp->flFlags = BITMAPOBJ_IS_APIBITMAP;
-
- /* WINE NOTE: WINE makes use of a colormap, which is a color translation table between the DIB and the X physical
- device. Obviously, this is left out of the ReactOS implementation. Instead, we call
- NtGdiSetDIBColorTable. */
- if(bi->biBitCount == 1) { Entries = 2; } else
- if(bi->biBitCount == 4) { Entries = 16; } else
- if(bi->biBitCount == 8) { Entries = 256; }
-
- if (Entries)
- bmp->hDIBPalette = PALETTE_AllocPaletteIndexedRGB(Entries, lpRGB);
- else
- bmp->hDIBPalette = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL,
- dib->dsBitfields[0],
- dib->dsBitfields[1],
- dib->dsBitfields[2]);
- }
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ goto cleanup;
+ }
- // Clean up in case of errors
- if (!res || !bmp || !dib || !bm.bmBits)
- {
- DPRINT("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n", res, bmp, dib, bm.bmBits);
-/* if (bm.bmBits)
- {
- if (section)
- UnmapViewOfFile(bm.bmBits), bm.bmBits = NULL;
- else if (!offset)
- VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
- } */
+ /* 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. */
+ bmp->hDIBSection = section;
+ bmp->hSecure = hSecure;
+ bmp->dwOffset = offset;
+ bmp->flags = API_BITMAP;
+ bmp->biClrImportant = bi->biClrImportant;
+
+ /* HACK */
+ if(hpal != (HPALETTE)0xFFFFFFFF)
+ {
+ bmp->ppal = PALETTE_ShareLockPalette(hpal);
+ /* Lazy delete hpal, it will be freed at surface release */
+ GreDeleteObject(hpal);
+ }
+
+ // Clean up in case of errors
+cleanup:
+ if (!res || !bmp || !bm.bmBits)
+ {
+ DPRINT("got an error res=%08x, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits);
+ if (bm.bmBits)
+ {
+ // MmUnsecureVirtualMemory(hSecure); // FIXME: Implement this!
+ if (section)
+ {
+ ZwUnmapViewOfSection(NtCurrentProcess(), mapBits);
+ bm.bmBits = NULL;
+ }
+ else
+ if (!offset)
+ EngFreeUserMem(bm.bmBits), bm.bmBits = NULL;
+ }
- if (dib) { ExFreePool(dib); dib = NULL; }
- if (bmp) { bmp = NULL; }
- if (res) { BITMAPOBJ_FreeBitmapByHandle(res); res = 0; }
- }
+ if (bmp)
+ bmp = NULL;
- if (lpRGB != bmi->bmiColors)
- {
- ExFreePool(lpRGB);
+ if (res)
+ {
+ SURFACE_FreeSurfaceByHandle(res);
+ res = 0;
+ }
}
- if (bmp)
+ if (bmp)
{
- BITMAPOBJ_UnlockBitmap(bmp);
+ SURFACE_UnlockSurface(bmp);
}
- // Return BITMAP handle and storage location
- if (NULL != bm.bmBits && NULL != bits)
+ // Return BITMAP handle and storage location
+ if (NULL != bm.bmBits && NULL != bits)
{
- *bits = bm.bmBits;
+ *bits = bm.bmBits;
}
- return res;
+ return res;
+}
+
+/***********************************************************************
+ * DIB_GetBitmapInfo
+ *
+ * Get the info from a bitmap header.
+ * Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error.
+ */
+int
+FASTCALL
+DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
+ LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size )
+{
+ if (header->biSize == sizeof(BITMAPCOREHEADER))
+ {
+ const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
+ *width = core->bcWidth;
+ *height = core->bcHeight;
+ *planes = core->bcPlanes;
+ *bpp = core->bcBitCount;
+ *compr = 0;
+ *size = 0;
+ return 0;
+ }
+ if (header->biSize >= sizeof(BITMAPINFOHEADER)) /* assume BITMAPINFOHEADER */
+ {
+ *width = header->biWidth;
+ *height = header->biHeight;
+ *planes = header->biPlanes;
+ *bpp = header->biBitCount;
+ *compr = header->biCompression;
+ *size = header->biSizeImage;
+ return 1;
+ }
+ DPRINT1("(%d): unknown/wrong size for header\n", header->biSize );
+ return -1;
}
/***********************************************************************
* http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
* 11/16/1999 (RJJ) lifted from wine
*/
-INT FASTCALL DIB_GetDIBWidthBytes (INT width, INT depth)
+INT FASTCALL DIB_GetDIBWidthBytes(INT width, INT depth)
{
- return ((width * depth + 31) & ~31) >> 3;
+ return ((width * depth + 31) & ~31) >> 3;
}
/***********************************************************************
* 11/16/1999 (RJJ) lifted from wine
*/
-INT STDCALL DIB_GetDIBImageBytes (INT width, INT height, INT depth)
+INT APIENTRY DIB_GetDIBImageBytes(INT width, INT height, INT depth)
{
- return DIB_GetDIBWidthBytes( width, depth ) * (height < 0 ? -height : height);
+ return DIB_GetDIBWidthBytes(width, depth) * (height < 0 ? -height : height);
}
/***********************************************************************
* 11/16/1999 (RJJ) lifted from wine
*/
-INT FASTCALL DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse)
+INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse)
{
- int colors;
-
- if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
- colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
- return sizeof(BITMAPCOREHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
- }
- else /* assume BITMAPINFOHEADER */
- {
- colors = info->bmiHeader.biClrUsed;
- if (!colors && (info->bmiHeader.biBitCount <= 8)) colors = 1 << info->bmiHeader.biBitCount;
- return sizeof(BITMAPINFOHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
- }
+ unsigned int colors, size, masks = 0;
+
+ 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));
+ }
+ else /* assume BITMAPINFOHEADER */
+ {
+ colors = info->bmiHeader.biClrUsed;
+ if (colors > 256) colors = 256;
+ if (!colors && (info->bmiHeader.biBitCount <= 8))
+ colors = 1 << info->bmiHeader.biBitCount;
+ if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
+ size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
+ return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
+ }
}
-RGBQUAD * FASTCALL
-DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi)
+HPALETTE
+FASTCALL
+DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi)
{
- RGBQUAD *lpRGB;
- ULONG nNumColors,i;
- USHORT *lpIndex;
- PPALGDI palGDI;
-
- palGDI = PALETTE_LockPalette(dc->DcLevel.hpal);
+ PALETTEENTRY* ppalEntries;
+ ULONG nNumColors,i;
+ USHORT *lpIndex;
+ HPALETTE hpal;
- if (NULL == palGDI)
+ if (ppal->Mode != PAL_INDEXED)
{
-// RELEASEDCINFO(hDC);
- return NULL;
+ return NULL;
}
- if (palGDI->Mode != PAL_INDEXED)
+ nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
+ if (lpbmi->bmiHeader.biClrUsed)
{
- PALETTE_UnlockPalette(palGDI);
- return NULL;
+ nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
}
- nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
- if (lpbmi->bmiHeader.biClrUsed)
+ /* Don't have more colors than we need */
+ nNumColors = min(ppal->NumColors, nNumColors);
+
+ ppalEntries = ExAllocatePoolWithTag(PagedPool, sizeof(PALETTEENTRY) * nNumColors, TAG_COLORMAP);
+ if (ppalEntries == NULL)
{
- nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
+ DPRINT1("Could not allocate palette entries\n");
+ return NULL;
}
- lpRGB = (RGBQUAD *)ExAllocatePoolWithTag(PagedPool, sizeof(RGBQUAD) * nNumColors, TAG_COLORMAP);
- if (lpRGB == NULL)
- {
- PALETTE_UnlockPalette(palGDI);
- return NULL;
- }
+ lpIndex = (USHORT *)((PBYTE)lpbmi + lpbmi->bmiHeader.biSize);
- lpIndex = (USHORT *)&lpbmi->bmiColors[0];
-
- for (i = 0; i < nNumColors; i++)
+ for (i = 0; i < nNumColors; i++)
{
- lpRGB[i].rgbRed = palGDI->IndexedColors[*lpIndex].peRed;
- lpRGB[i].rgbGreen = palGDI->IndexedColors[*lpIndex].peGreen;
- lpRGB[i].rgbBlue = palGDI->IndexedColors[*lpIndex].peBlue;
- lpIndex++;
+ if (*lpIndex < ppal->NumColors)
+ {
+ ppalEntries[i] = ppal->IndexedColors[*lpIndex];
+ }
+ else
+ {
+ ppalEntries[i].peRed = 0;
+ ppalEntries[i].peGreen = 0;
+ ppalEntries[i].peBlue = 0;
+ ppalEntries[i].peFlags = 0;
+ }
+
+ lpIndex++;
}
-// RELEASEDCINFO(hDC);
- PALETTE_UnlockPalette(palGDI);
+
+ hpal = PALETTE_AllocPalette(PAL_INDEXED, nNumColors, (ULONG*)ppalEntries, 0, 0, 0);
+
+ ExFreePoolWithTag(ppalEntries, TAG_COLORMAP);
- return lpRGB;
+ return hpal;
}
-HPALETTE FASTCALL
-BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType)
+HPALETTE
+FASTCALL
+BuildDIBPalette(CONST BITMAPINFO *bmi)
{
- BYTE bits;
- ULONG ColorCount;
- PALETTEENTRY *palEntries = NULL;
- HPALETTE hPal;
- ULONG RedMask, GreenMask, BlueMask;
-
- // Determine Bits Per Pixel
- bits = bmi->bmiHeader.biBitCount;
-
- // Determine paletteType from Bits Per Pixel
- if (bits <= 8)
+ BYTE bits;
+ ULONG ColorCount;
+ HPALETTE hPal;
+ ULONG RedMask = 0, GreenMask = 0, BlueMask = 0;
+ PDWORD pdwColors = (PDWORD)((PBYTE)bmi + bmi->bmiHeader.biSize);
+ INT paletteType;
+
+ // Determine Bits Per Pixel
+ bits = bmi->bmiHeader.biBitCount;
+
+ // Determine paletteType from Bits Per Pixel
+ if (bits <= 8)
{
- *paletteType = PAL_INDEXED;
- RedMask = GreenMask = BlueMask = 0;
+ paletteType = PAL_INDEXED;
+ RedMask = GreenMask = BlueMask = 0;
}
- else if(bmi->bmiHeader.biCompression == BI_BITFIELDS)
+ else if (bmi->bmiHeader.biCompression == BI_BITFIELDS)
{
- *paletteType = PAL_BITFIELDS;
- RedMask = ((ULONG *)bmi->bmiColors)[0];
- GreenMask = ((ULONG *)bmi->bmiColors)[1];
- BlueMask = ((ULONG *)bmi->bmiColors)[2];
+ paletteType = PAL_BITFIELDS;
+ RedMask = pdwColors[0];
+ GreenMask = pdwColors[1];
+ BlueMask = pdwColors[2];
}
- else if(bits < 24)
+ else if (bits == 15)
{
- *paletteType = PAL_BITFIELDS;
- RedMask = 0x7c00;
- GreenMask = 0x03e0;
- BlueMask = 0x001f;
+ paletteType = PAL_RGB16_555;
}
- else
+ else if (bits == 16)
{
- *paletteType = PAL_BGR;
- RedMask = 0xff0000;
- GreenMask = 0x00ff00;
- BlueMask = 0x0000ff;
+ paletteType = PAL_RGB16_565;
+ }
+ else
+ {
+ paletteType = PAL_BGR;
}
- if (bmi->bmiHeader.biClrUsed == 0)
+ if (bmi->bmiHeader.biClrUsed == 0)
{
- ColorCount = 1 << bmi->bmiHeader.biBitCount;
+ ColorCount = 1 << bmi->bmiHeader.biBitCount;
}
- else
+ else
{
- ColorCount = bmi->bmiHeader.biClrUsed;
+ ColorCount = bmi->bmiHeader.biClrUsed;
}
- if (PAL_INDEXED == *paletteType)
+ if (PAL_INDEXED == paletteType)
{
- hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)bmi->bmiColors);
+ hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)pdwColors);
}
- else
+ else
{
- hPal = PALETTE_AllocPalette(*paletteType, ColorCount,
- (ULONG*) palEntries,
- RedMask, GreenMask, BlueMask );
+ hPal = PALETTE_AllocPalette(paletteType, 0,
+ NULL,
+ RedMask, GreenMask, BlueMask);
}
- return hPal;
+ return hPal;
+}
+
+/* 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)
+{
+ CONST BITMAPCOREINFO* pbmci = (BITMAPCOREINFO*)pbmi;
+ BITMAPINFO* pNewBmi ;
+ UINT numColors = 0, ColorsSize = 0;
+
+ if(pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) return (BITMAPINFO*)pbmi;
+ if(pbmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) return NULL;
+
+ if(pbmci->bmciHeader.bcBitCount <= 8)
+ {
+ numColors = 1 << pbmci->bmciHeader.bcBitCount;
+ if(Usage == DIB_PAL_COLORS)
+ {
+ ColorsSize = numColors * sizeof(WORD);
+ }
+ else
+ {
+ ColorsSize = numColors * sizeof(RGBQUAD);
+ }
+ }
+ else if (Usage == DIB_PAL_COLORS)
+ {
+ /* Invalid at high Res */
+ return NULL;
+ }
+
+ pNewBmi = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + ColorsSize, TAG_DIB);
+ if(!pNewBmi) return NULL;
+
+ RtlZeroMemory(pNewBmi, sizeof(BITMAPINFOHEADER) + ColorsSize);
+
+ pNewBmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pNewBmi->bmiHeader.biBitCount = pbmci->bmciHeader.bcBitCount;
+ pNewBmi->bmiHeader.biWidth = pbmci->bmciHeader.bcWidth;
+ pNewBmi->bmiHeader.biHeight = pbmci->bmciHeader.bcHeight;
+ pNewBmi->bmiHeader.biPlanes = pbmci->bmciHeader.bcPlanes;
+ pNewBmi->bmiHeader.biCompression = BI_RGB ;
+ pNewBmi->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(pNewBmi->bmiHeader.biWidth,
+ pNewBmi->bmiHeader.biHeight,
+ pNewBmi->bmiHeader.biBitCount);
+
+ if(Usage == DIB_PAL_COLORS)
+ {
+ RtlCopyMemory(pNewBmi->bmiColors, pbmci->bmciColors, ColorsSize);
+ }
+ else
+ {
+ UINT i;
+ for(i=0; i<numColors; i++)
+ {
+ pNewBmi->bmiColors[i].rgbRed = pbmci->bmciColors[i].rgbtRed;
+ pNewBmi->bmiColors[i].rgbGreen = pbmci->bmciColors[i].rgbtGreen;
+ pNewBmi->bmiColors[i].rgbBlue = pbmci->bmciColors[i].rgbtBlue;
+ }
+ }
+
+ return pNewBmi ;
+}
+
+/* Frees a BITMAPINFO created with DIB_ConvertBitmapInfo */
+VOID
+FASTCALL
+DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig)
+{
+ if(converted != orig)
+ ExFreePoolWithTag(converted, TAG_DIB);
}
+
+
+
+
+
/* EOF */