/*
- * $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 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 }
+};
+
+
+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);
- if (PalGDI == NULL)
- {
- BITMAPOBJ_UnlockBitmap(BitmapObj);
- DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
-
- 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);
- if (PalGDI == NULL)
- {
- BITMAPOBJ_UnlockBitmap(BitmapObj);
- DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
-
- 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;
- }
- 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;
+ SURFACE *bitmap;
+ HBITMAP SourceBitmap;
+ INT result = 0;
+ BOOL copyBitsResult;
+ SURFOBJ *DestSurf, *SourceSurf;
+ SIZEL SourceSize;
+ POINTL ZeroPoint;
+ RECTL DestRect;
+ EXLATEOBJ exlo;
+ PPALETTE ppalDIB;
+ //RGBQUAD *lpRGB;
+ HPALETTE DIB_Palette;
+ ULONG DIB_Palette_Type;
+ INT DIBWidth;
+
+ // Check parameters
+ if (!(bitmap = SURFACE_LockSurface(hBitmap)))
+ {
+ return 0;
+ }
+
+ // Get RGB values
+ //if (ColorUse == DIB_PAL_COLORS)
+ // lpRGB = DIB_MapPaletteColors(hDC, bmi);
+ //else
+ // lpRGB = &bmi->bmiColors;
+
+ DestSurf = &bitmap->SurfObj;
+
+ // 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)
+ {
+ SURFACE_UnlockSurface(bitmap);
+ SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ return 0;
+ }
+
+ SourceSurf = EngLockSurface((HSURF)SourceBitmap);
+ if (NULL == SourceSurf)
+ {
+ EngDeleteSurface((HSURF)SourceBitmap);
+ SURFACE_UnlockSurface(bitmap);
+ SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ return 0;
+ }
+
+ ASSERT(bitmap->ppal);
+
+ // Source palette obtained from the BITMAPINFO
+ DIB_Palette = BuildDIBPalette(bmi, (PINT)&DIB_Palette_Type);
+ if (NULL == DIB_Palette)
+ {
+ EngUnlockSurface(SourceSurf);
+ EngDeleteSurface((HSURF)SourceBitmap);
+ SURFACE_UnlockSurface(bitmap);
+ SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ return 0;
+ }
+
+ ppalDIB = PALETTE_LockPalette(DIB_Palette);
+
+ /* Initialize XLATEOBJ for color translation */
+ EXLATEOBJ_vInitialize(&exlo, ppalDIB, bitmap->ppal, 0, 0, 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 = IntEngCopyBits(DestSurf, SourceSurf, NULL, &exlo.xlo, &DestRect, &ZeroPoint);
+
+ // If it succeeded, return number of scanlines copies
+ if (copyBitsResult == TRUE)
+ {
+ result = SourceSize.cy;
+// or
+// result = abs(bmi->bmiHeader.biHeight) - StartScan;
+ }
+
+ // Clean up
+ EXLATEOBJ_vCleanup(&exlo);
+ PALETTE_UnlockPalette(ppalDIB);
+ PALETTE_FreePaletteByHandle(DIB_Palette);
+ EngUnlockSurface(SourceSurf);
+ EngDeleteSurface((HSURF)SourceBitmap);
+
+// if (ColorUse == DIB_PAL_COLORS)
+// WinFree((LPSTR)lpRGB);
+
+ SURFACE_UnlockSurface(bitmap);
+
+ 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;
+ BITMAPV5INFO bmiLocal;
- Dc = DC_LockDc(hDC);
- if (NULL == Dc)
+ if (!Bits) return 0;
+
+ _SEH2_TRY
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
+ Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse);
}
- 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, (PBITMAPINFO)&bmiLocal, 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;
+ ULONG DIBPaletteType;
+ BITMAPV5INFO bmiLocal ;
if (!Bits) return 0;
+ _SEH2_TRY
+ {
+ Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse);
+ }
+ _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(bmiLocal.bmiHeader.bV5Height) - 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);
-
- 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;
- }
-
- pSourceSurf = EngLockSurface((HSURF)hSourceBitmap);
- if (!pSourceSurf)
- {
- Status = STATUS_UNSUCCESSFUL;
- _SEH_LEAVE;
- }
-
+ SourceSize.cx = bmiLocal.bmiHeader.bV5Width;
+ SourceSize.cy = ScanLines;
- /* 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);
+ DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmiLocal.bmiHeader.bV5BitCount);
- DIBPalette = BuildDIBPalette(bmi, (PINT)&DIBPaletteType);
- if (!DIBPalette)
- {
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- Status = STATUS_NO_MEMORY;
- _SEH_LEAVE;
- }
+ hSourceBitmap = EngCreateBitmap(SourceSize,
+ DIBWidth,
+ BitmapFormat(bmiLocal.bmiHeader.bV5BitCount,
+ bmiLocal.bmiHeader.bV5Compression),
+ bmiLocal.bmiHeader.bV5Height < 0 ? BMF_TOPDOWN : 0,
+ (PVOID) Bits);
+ if (!hSourceBitmap)
+ {
+ SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ 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((PBITMAPINFO)&bmiLocal, (PINT)&DIBPaletteType);
+ 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;
+ SURFACE *psurf = NULL;
HBITMAP hDestBitmap = NULL;
- HPALETTE hSourcePalette = NULL;
HPALETTE hDestPalette = NULL;
- PPALGDI SourcePalette = NULL;
- PPALGDI DestPalette = NULL;
+ BITMAPV5INFO bmiLocal ;
+ PPALETTE ppalDst = NULL;
NTSTATUS Status = STATUS_SUCCESS;
ULONG Result = 0;
BOOL bPaletteMatch = FALSE;
+ PBYTE ChkBits = Bits;
+ ULONG DestPaletteType;
+ ULONG Index;
DPRINT("Entered NtGdiGetDIBitsInternal()\n");
- /* Get handle for the palette in DC. */
+ if ((Usage && Usage != DIB_PAL_COLORS) || !Info || !hBitmap)
+ return 0;
+
+ // if ScanLines == 0, no need to copy Bits.
+ if (!ScanLines)
+ ChkBits = NULL;
+
+ _SEH2_TRY
+ {
+ Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, Info, Usage);
+ if (ChkBits) ProbeForWrite(ChkBits, MaxBits, 1);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if (!NT_SUCCESS(Status))
+ {
+ return 0;
+ }
+
Dc = DC_LockDc(hDC);
if (Dc == NULL) return 0;
- if (Dc->DC_Type == DC_TYPE_INFO)
+ if (Dc->dctype == DC_TYPE_INFO)
{
DC_UnlockDc(Dc);
return 0;
}
- /* Source palette obtained from the windows hdc */
- hSourcePalette = Dc->DcLevel.hpal;
- DC_UnlockDc(Dc);
-
- /* don't do anything if we fail this */
- if (Usage != DIB_RGB_COLORS && Usage != DIB_PAL_COLORS)
- return 0;
/* Get a pointer to the source bitmap object */
- BitmapObj = BITMAPOBJ_LockBitmap(hBitmap);
- if (BitmapObj == NULL)
+ psurf = SURFACE_LockSurface(hBitmap);
+ if (psurf == NULL)
+ {
+ DC_UnlockDc(Dc);
return 0;
+ }
- /* fill out the BITMAPINFO struct */
- if (Bits == NULL)
- {
- _SEH_TRY
- {
- if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
-
- ProbeForWrite(Info, sizeof(BITMAPINFO), 1);
-
- coreheader = (BITMAPCOREHEADER*) Info;
- coreheader->bcWidth = BitmapObj->SurfObj.sizlBitmap.cx;
- coreheader->bcPlanes = 1;
- coreheader->bcBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
- /* Resulting height may be smaller than original height */
- coreheader->bcHeight = min(ScanLines, BitmapObj->SurfObj.sizlBitmap.cy - StartScan);
- coreheader->bcSize = DIB_GetDIBWidthBytes(coreheader->bcWidth,
- coreheader->bcBitCount) * coreheader->bcHeight;
- if (BitmapObj->SurfObj.lDelta > 0)
- coreheader->bcHeight = -coreheader->bcHeight;
- }
+ ASSERT(psurf->ppal);
- if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
- {
- ProbeForWrite(Info, sizeof(BITMAPINFO), 1);
-
- Info->bmiHeader.biWidth = BitmapObj->SurfObj.sizlBitmap.cx;
- /* Resulting height may be smaller than original height */
- Info->bmiHeader.biHeight = min(ScanLines, BitmapObj->SurfObj.sizlBitmap.cy - StartScan);
- Info->bmiHeader.biPlanes = 1;
- Info->bmiHeader.biBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
- switch (BitmapObj->SurfObj.iBitmapFormat)
- {
- 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;
- }
- /* Image size has to be calculated */
- Info->bmiHeader.biSizeImage = DIB_GetDIBWidthBytes(Info->bmiHeader.biWidth,
- Info->bmiHeader.biBitCount) * Info->bmiHeader.biHeight;
- Info->bmiHeader.biXPelsPerMeter = 0; /* FIXME */
- Info->bmiHeader.biYPelsPerMeter = 0; /* FIXME */
- Info->bmiHeader.biClrUsed = 0;
- Info->bmiHeader.biClrImportant = 1 << Info->bmiHeader.biBitCount; /* FIXME */
- /* Report negtive height for top-down bitmaps. */
- if (BitmapObj->SurfObj.lDelta > 0)
- Info->bmiHeader.biHeight = -Info->bmiHeader.biHeight;
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END
+ DC_UnlockDc(Dc);
- if (NT_SUCCESS(Status))
- {
- Result = BitmapObj->SurfObj.sizlBitmap.cy;
- }
+ /* Copy palette information
+ * Always create a palette for 15 & 16 bit. */
+ if ((Info->bmiHeader.biBitCount == BitsPerFormat(psurf->SurfObj.iBitmapFormat) &&
+ Info->bmiHeader.biBitCount != 15 && Info->bmiHeader.biBitCount != 16) ||
+ !ChkBits)
+ {
+ ppalDst = psurf->ppal;
+ bPaletteMatch = TRUE;
}
else
{
- SIZEL DestSize;
- ULONG SourcePaletteType = 0;
- ULONG DestPaletteType;
- POINTL SourcePoint;
- ULONG Index;
-
- _SEH_TRY
- {
- 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;
+ hDestPalette = BuildDIBPalette((PBITMAPINFO)&bmiLocal, (PINT)&DestPaletteType);
+ ppalDst = PALETTE_LockPalette(hDestPalette);
+ }
- SourcePalette = PALETTE_LockPalette(hSourcePalette);
- /* FIXME - SourcePalette can be NULL!!! Don't assert here! */
- ASSERT(SourcePalette);
- SourcePaletteType = SourcePalette->Mode;
- PALETTE_UnlockPalette(SourcePalette);
+ DPRINT("ppalDst : %p\n", ppalDst);
+ ASSERT(ppalDst);
- if (bPaletteMatch)
+ /* Copy palette. */
+ switch (bmiLocal.bmiHeader.bV5BitCount)
+ {
+ case 1:
+ case 4:
+ case 8:
+ bmiLocal.bmiHeader.bV5ClrUsed = 0;
+ if (psurf->hSecure &&
+ BitsPerFormat(psurf->SurfObj.iBitmapFormat) == bmiLocal.bmiHeader.bV5BitCount)
{
- DestPalette = PALETTE_LockPalette(hDestPalette);
- /* FIXME - DestPalette can be NULL!!!! Don't assert here!!! */
- DPRINT("DestPalette : %p\n", DestPalette);
- ASSERT(DestPalette);
- DestPaletteType = DestPalette->Mode;
+ if (Usage == DIB_RGB_COLORS)
+ {
+ if (ppalDst->NumColors != 1 << bmiLocal.bmiHeader.bV5BitCount)
+ bmiLocal.bmiHeader.bV5ClrUsed = ppalDst->NumColors;
+ for (Index = 0;
+ Index < (1 << bmiLocal.bmiHeader.bV5BitCount) && Index < ppalDst->NumColors;
+ Index++)
+ {
+ bmiLocal.bmiColors[Index].rgbRed = ppalDst->IndexedColors[Index].peRed;
+ bmiLocal.bmiColors[Index].rgbGreen = ppalDst->IndexedColors[Index].peGreen;
+ bmiLocal.bmiColors[Index].rgbBlue = ppalDst->IndexedColors[Index].peBlue;
+ bmiLocal.bmiColors[Index].rgbReserved = 0;
+ }
+ }
+ else
+ {
+ for (Index = 0;
+ Index < (1 << Info->bmiHeader.biBitCount);
+ Index++)
+ {
+ ((WORD*)bmiLocal.bmiColors)[Index] = Index;
+ }
+ }
}
else
{
- DestPalette = SourcePalette;
- }
-
- /* Copy palette. */
- /* FIXME: This is largely incomplete. */
- if (Info->bmiHeader.biBitCount <= 8)
- {
- if (Usage == DIB_RGB_COLORS)
+ if (Usage == DIB_PAL_COLORS)
{
for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount) && Index < DestPalette->NumColors;
- Index++)
+ Index < (1 << Info->bmiHeader.biBitCount);
+ 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;
- Info->bmiColors[Index].rgbReserved = 0;
+ ((WORD*)bmiLocal.bmiColors)[Index] = (WORD)Index;
}
}
-
- if (Usage == DIB_PAL_COLORS)
+ else if (Info->bmiHeader.biBitCount > 1 && bPaletteMatch)
+ {
+ for (Index = 0;
+ Index < (1 << Info->bmiHeader.biBitCount) && Index < ppalDst->NumColors;
+ Index++)
+ {
+ bmiLocal.bmiColors[Index].rgbRed = ppalDst->IndexedColors[Index].peRed;
+ bmiLocal.bmiColors[Index].rgbGreen = ppalDst->IndexedColors[Index].peGreen;
+ bmiLocal.bmiColors[Index].rgbBlue = ppalDst->IndexedColors[Index].peBlue;
+ bmiLocal.bmiColors[Index].rgbReserved = 0;
+ }
+ }
+ else
{
- DPRINT1("GetDIBits with DIB_PAL_COLORS isn't implemented yet\n");
+ switch (bmiLocal.bmiHeader.bV5BitCount)
+ {
+ case 1:
+ bmiLocal.bmiColors[0].rgbRed =0 ;
+ bmiLocal.bmiColors[0].rgbGreen = 0;
+ bmiLocal.bmiColors[0].rgbBlue = 0;
+ bmiLocal.bmiColors[0].rgbReserved = 0;
+ bmiLocal.bmiColors[1].rgbRed =0xFF ;
+ bmiLocal.bmiColors[1].rgbGreen = 0xFF;
+ bmiLocal.bmiColors[1].rgbBlue = 0xFF;
+ bmiLocal.bmiColors[1].rgbReserved = 0;
+ break;
+ case 4:
+ RtlCopyMemory(bmiLocal.bmiColors, EGAColorsQuads, sizeof(EGAColorsQuads));
+ break;
+ case 8:
+ {
+ INT r, g, b;
+ RGBQUAD *color;
+
+ RtlCopyMemory(bmiLocal.bmiColors, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
+ RtlCopyMemory(bmiLocal.bmiColors + 246, DefLogPaletteQuads + 10, 10 * sizeof(RGBQUAD));
+ color = bmiLocal.bmiColors + 10;
+ for (r = 0; r <= 5; r++) /* FIXME */
+ for (g = 0; g <= 5; g++)
+ for (b = 0; b <= 5; b++)
+ {
+ color->rgbRed = (r * 0xff) / 5;
+ color->rgbGreen = (g * 0xff) / 5;
+ color->rgbBlue = (b * 0xff) / 5;
+ color->rgbReserved = 0;
+ color++;
+ }
+ }
+ break;
+ }
}
}
- if (bPaletteMatch)
- PALETTE_UnlockPalette(DestPalette);
+ case 15:
+ if (bmiLocal.bmiHeader.bV5Compression == BI_BITFIELDS)
+ {
+ bmiLocal.bmiHeader.bV5RedMask = 0x7c00;
+ bmiLocal.bmiHeader.bV5GreenMask = 0x03e0;
+ bmiLocal.bmiHeader.bV5BlueMask = 0x001f;
+ }
+ break;
- /* Create the destination bitmap to for the copy operation */
- if (StartScan > BitmapObj->SurfObj.sizlBitmap.cy)
+ case 16:
+ if (Info->bmiHeader.biCompression == BI_BITFIELDS)
{
- _SEH_YIELD(goto cleanup);
+ bmiLocal.bmiHeader.bV5RedMask = 0xf800;
+ bmiLocal.bmiHeader.bV5GreenMask = 0x07e0;
+ bmiLocal.bmiHeader.bV5BlueMask = 0x001f;
}
- else
+ break;
+
+ case 24:
+ case 32:
+ if (Info->bmiHeader.biCompression == BI_BITFIELDS)
{
- ScanLines = min(ScanLines, BitmapObj->SurfObj.sizlBitmap.cy - StartScan);
- DestSize.cx = BitmapObj->SurfObj.sizlBitmap.cx;
- DestSize.cy = ScanLines;
+ bmiLocal.bmiHeader.bV5RedMask = 0xff0000;
+ bmiLocal.bmiHeader.bV5GreenMask = 0x00ff00;
+ bmiLocal.bmiHeader.bV5BlueMask = 0x0000ff;
+ }
+ break;
+ }
- hDestBitmap = NULL;
+ /* fill out the BITMAPINFO struct */
+ if (!ChkBits)
+ {
+ bmiLocal.bmiHeader.bV5Width = psurf->SurfObj.sizlBitmap.cx;
+ bmiLocal.bmiHeader.bV5Height = psurf->SurfObj.sizlBitmap.cy;
+ bmiLocal.bmiHeader.bV5Planes = 1;
+ bmiLocal.bmiHeader.bV5BitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+ 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:
+ bmiLocal.bmiHeader.bV5Compression = BI_RGB;
+ break;
+ case BMF_4RLE:
+ bmiLocal.bmiHeader.bV5Compression = BI_RLE4;
+ break;
+ case BMF_8RLE:
+ bmiLocal.bmiHeader.bV5Compression = BI_RLE8;
+ break;
+ case BMF_JPEG:
+ bmiLocal.bmiHeader.bV5Compression = BI_JPEG;
+ break;
+ case BMF_PNG:
+ bmiLocal.bmiHeader.bV5Compression = BI_PNG;
+ break;
+ }
+ /* Image size has to be calculated */
+ bmiLocal.bmiHeader.bV5SizeImage = DIB_GetDIBWidthBytes(Info->bmiHeader.biWidth,
+ Info->bmiHeader.biBitCount) * Info->bmiHeader.biHeight;
+ bmiLocal.bmiHeader.bV5XPelsPerMeter = 0; /* FIXME */
+ bmiLocal.bmiHeader.bV5YPelsPerMeter = 0; /* FIXME */
+ bmiLocal.bmiHeader.bV5ClrUsed = 0;
+ bmiLocal.bmiHeader.bV5ClrImportant = 1 << Info->bmiHeader.biBitCount; /* FIXME */
+ /* Report negative height for top-down bitmaps. */
+ if (psurf->SurfObj.lDelta > 0)
+ bmiLocal.bmiHeader.bV5Height *= -1;
+ Result = psurf->SurfObj.sizlBitmap.cy;
+ }
+ else
+ {
+ SIZEL DestSize;
+ POINTL SourcePoint;
- ProbeForWrite(Bits, BitmapObj->SurfObj.cjBits, 1);
+//
+// If we have a good dib pointer, why not just copy bits from there w/o XLATE'ing them.
+//
+ /* Create the destination bitmap too for the copy operation */
+ if (StartScan > psurf->SurfObj.sizlBitmap.cy)
+ {
+ goto cleanup;
+ }
+ else
+ {
+ ScanLines = min(ScanLines, psurf->SurfObj.sizlBitmap.cy - StartScan);
+ DestSize.cx = psurf->SurfObj.sizlBitmap.cx;
+ DestSize.cy = ScanLines;
- if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
- coreheader->bcSize = DIB_GetDIBWidthBytes(DestSize.cx,
- coreheader->bcBitCount) * DestSize.cy;
-
- hDestBitmap = EngCreateBitmap(DestSize,
- DIB_GetDIBWidthBytes(DestSize.cx, coreheader->bcBitCount),
- BitmapFormat(coreheader->bcBitCount, BI_RGB),
- 0 < coreheader->bcHeight ? 0 : BMF_TOPDOWN,
- Bits);
- }
+ hDestBitmap = NULL;
- if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
- {
- Info->bmiHeader.biSizeImage = DIB_GetDIBWidthBytes(DestSize.cx,
- Info->bmiHeader.biBitCount) * DestSize.cy;
-
- hDestBitmap = EngCreateBitmap(DestSize,
- DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount),
- BitmapFormat(Info->bmiHeader.biBitCount, Info->bmiHeader.biCompression),
- 0 < Info->bmiHeader.biHeight ? 0 : BMF_TOPDOWN,
- Bits);
- }
+ bmiLocal.bmiHeader.bV5SizeImage = DIB_GetDIBWidthBytes(DestSize.cx,
+ Info->bmiHeader.biBitCount) * DestSize.cy;
- if (hDestBitmap == NULL)
- _SEH_YIELD(goto cleanup);
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
+ hDestBitmap = EngCreateBitmap(DestSize,
+ DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount),
+ BitmapFormat(Info->bmiHeader.biBitCount, Info->bmiHeader.biCompression),
+ 0 < Info->bmiHeader.biHeight ? 0 : BMF_TOPDOWN,
+ Bits);
+
+ if (hDestBitmap == NULL)
+ goto cleanup;
}
- _SEH_END
if (NT_SUCCESS(Status))
{
- XLATEOBJ *XlateObj;
+ EXLATEOBJ exlo;
SURFOBJ *DestSurfObj;
RECTL DestRect;
- XlateObj = IntEngCreateXlate(DestPaletteType,
- SourcePaletteType,
- hDestPalette,
- hSourcePalette);
+ EXLATEOBJ_vInitialize(&exlo, psurf->ppal, ppalDst, 0, 0, 0);
SourcePoint.x = 0;
- SourcePoint.y = BitmapObj->SurfObj.sizlBitmap.cy - (StartScan + ScanLines);
+ SourcePoint.y = psurf->SurfObj.sizlBitmap.cy - (StartScan + ScanLines);
/* Determine destination rectangle */
DestRect.top = 0;
DestSurfObj = EngLockSurface((HSURF)hDestBitmap);
- if (EngCopyBits(DestSurfObj,
- &BitmapObj->SurfObj,
- NULL,
- XlateObj,
- &DestRect,
- &SourcePoint))
+ if (IntEngCopyBits(DestSurfObj,
+ &psurf->SurfObj,
+ NULL,
+ &exlo.xlo,
+ &DestRect,
+ &SourcePoint))
{
+ DPRINT("GetDIBits %d \n",abs(Info->bmiHeader.biHeight) - StartScan);
Result = ScanLines;
}
- EngDeleteXlate(XlateObj);
+ EXLATEOBJ_vCleanup(&exlo);
EngUnlockSurface(DestSurfObj);
}
}
-
+ /* Now that everything is over, get back the information to caller */
+ /* Note : Info has already been probed */
+ GetBMIFromBitmapV5Info(&bmiLocal, Info, Usage);
cleanup:
+
if (hDestBitmap != NULL)
EngDeleteSurface((HSURF)hDestBitmap);
- if (hDestPalette != NULL && bPaletteMatch == FALSE)
+ if (hDestPalette != NULL && !bPaletteMatch)
+ {
+ PALETTE_UnlockPalette(ppalDst);
PALETTE_FreePaletteByHandle(hDestPalette);
+ }
- BITMAPOBJ_UnlockBitmap(BitmapObj);
+ SURFACE_UnlockSurface(psurf);
DPRINT("leaving NtGdiGetDIBitsInternal\n");
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,
+ HBITMAP hBitmap, hOldBitmap = NULL;
+ HDC hdcMem;
+ HPALETTE hPal = NULL;
+ PDC pDC;
+ BOOL Hit = FALSE;
+
+ if (!Bits || !BitsInfo)
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ _SEH2_TRY
+ {
+ ProbeForRead(BitsInfo, cjMaxInfo, 1);
+ ProbeForRead(Bits, cjMaxBits, 1);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Hit = TRUE;
+ }
+ _SEH2_END
+
+ if (Hit)
+ {
+ DPRINT1("NtGdiStretchDIBitsInternal fail to read BitMapInfo: %x or Bits: %x\n",BitsInfo,Bits);
+ return 0;
+ }
+
+ hdcMem = NtGdiCreateCompatibleDC(hDC);
+ if (hdcMem == NULL)
+ {
+ DPRINT1("NtGdiCreateCompatibleDC fail create hdc\n");
+ return 0;
+ }
+
+ hBitmap = NtGdiCreateCompatibleBitmap(hDC,
+ abs(BitsInfo->bmiHeader.biWidth),
+ abs(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);
+ IntSetDIBits(pDC, hBitmap, 0, abs(BitsInfo->bmiHeader.biHeight), Bits,
+ BitsInfo, Usage);
DC_UnlockDc(pDC);
- }
+ }
- /* 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);
+ /* 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(hPal)
- GdiSelectPalette(hdcMem, hPal, FALSE);
+ if (hPal)
+ GdiSelectPalette(hdcMem, hPal, FALSE);
- if (hOldBitmap)
- NtGdiSelectBitmap(hdcMem, hOldBitmap);
+ if (hOldBitmap)
+ NtGdiSelectBitmap(hdcMem, hOldBitmap);
- NtGdiDeleteObjectApp(hdcMem);
+ NtGdiDeleteObjectApp(hdcMem);
- NtGdiDeleteObject(hBitmap);
+ GreDeleteObject(hBitmap);
- return SrcHeight;
+ return SrcHeight;
}
HBITMAP
FASTCALL
-IntCreateDIBitmap(PDC Dc,
- INT width,
- INT height,
- UINT bpp,
- DWORD init,
- LPBYTE bits,
- PBITMAPINFO data,
- DWORD coloruse)
+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;
+ 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 = 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;
- }
+ PDC Dc;
+ HBITMAP Bmp;
+ UINT bpp;
- Dc = DC_LockDc(hDc);
- if (!Dc)
- {
- NtGdiDeleteObjectApp(hDc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- 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)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return NULL;
- }
+ if (!hDc) // CreateBitmap
+ { // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
+ hDc = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE);
+ if (!hDc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return NULL;
+ }
- Bmp = IntCreateDIBitmap(Dc, cx, cy, cjMaxInitInfo, fInit, pjInit, pbmi, iUsage);
- DC_UnlockDc(Dc);
- }
- return Bmp;
+ Dc = DC_LockDc(hDc);
+ if (!Dc)
+ {
+ NtGdiDeleteObjectApp(hDc);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return NULL;
+ }
+ bpp = 1;
+ Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
+
+ DC_UnlockDc(Dc);
+ NtGdiDeleteObjectApp(hDc);
+ }
+ else // CreateCompatibleBitmap
+ {
+ Dc = DC_LockDc(hDc);
+ if (!Dc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return NULL;
+ }
+ /* pbmi == null
+ First create an un-initialised bitmap. The depth of the bitmap
+ should match that of the hdc and not that supplied in bmih.
+ */
+ if (pbmi)
+ bpp = pbmi->bmiHeader.biBitCount;
+ else
+ {
+ if (Dc->dctype != DC_TYPE_MEMORY)
+ bpp = Dc->ppdev->gdiinfo.cBitsPixel;
+ else
+ {
+ DIBSECTION dibs;
+ INT Count;
+ SURFACE *psurf = Dc->dclevel.pSurface;
+ Count = BITMAP_GetObject(psurf, sizeof(dibs), &dibs);
+ if (!Count)
+ bpp = 1;
+ else
+ {
+ if (Count == sizeof(BITMAP))
+ /* A device-dependent bitmap is selected in the DC */
+ bpp = dibs.dsBm.bmBitsPixel;
+ else
+ /* A DIB section is selected in the DC */
+ bpp = dibs.dsBmih.biBitCount;
+ }
+ }
+ }
+ Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
+ DC_UnlockDc(Dc);
+ }
+ 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 LPBITMAPINFO 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;
+
+ 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);
+ }
- if (bDesktopDC)
- NtGdiDeleteObjectApp(hDC);
+ if (bDesktopDC)
+ NtGdiDeleteObjectApp(hDC);
- return hbitmap;
+ 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,
+ 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;
- 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");
-
- /* CreateDIBSection should fail for compressed formats */
- if (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8)
- {
- return (HBITMAP)NULL;
- }
-
- 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;
- /* Set dsBitfields values */
- if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
+ HBITMAP res = 0;
+ SURFACE *bmp = NULL;
+ void *mapBits = NULL;
+ PDC_ATTR pdcattr;
+ HPALETTE hpal ;
+
+ // Fill BITMAP32 structure with DIB data
+ BITMAPINFOHEADER *bi = &bmi->bmiHeader;
+ INT effHeight;
+ ULONG totalSize;
+ BITMAP bm;
+ SIZEL Size;
+ RGBQUAD *lpRGB;
+ HANDLE hSecure;
+ DWORD dsBitfields[3] = {0};
+ ULONG ColorCount;
+
+ DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
+ bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
+ 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)
{
- dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
+ return (HBITMAP)NULL;
}
- else switch(bi->biBitCount)
+
+ pdcattr = dc->pdcattr;
+
+ 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)
{
- 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;
+ 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;
+ }
- case 24:
- dib->dsBitfields[0] = 0xff0000;
- dib->dsBitfields[1] = 0x00ff00;
- dib->dsBitfields[2] = 0x0000ff;
- break;
+ 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;
+ }
- 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;
+ 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);
+ }
+
+// hSecure = MmSecureVirtualMemory(bm.bmBits, totalSize, PAGE_READWRITE);
+ hSecure = (HANDLE)0x1; // HACK OF UNIMPLEMENTED KERNEL STUFF !!!!
+
+ if (usage == DIB_PAL_COLORS)
+ {
+ lpRGB = DIB_MapPaletteColors(dc, bmi);
+ ColorCount = bi->biClrUsed;
+ if (ColorCount == 0)
+ {
+ ColorCount = 1 << bi->biBitCount;
+ }
+ }
+ else
+ {
+ lpRGB = bmi->bmiColors;
+ ColorCount = 1 << bi->biBitCount;
+ }
+
+ /* Set dsBitfields values */
+ if (usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
+ {
+ dsBitfields[0] = dsBitfields[1] = dsBitfields[2] = 0;
+ }
+ else if (bi->biCompression == BI_RGB)
+ {
+ switch (bi->biBitCount)
+ {
+ case 15:
+ dsBitfields[0] = 0x7c00;
+ dsBitfields[1] = 0x03e0;
+ dsBitfields[2] = 0x001f;
+ break;
+
+ case 16:
+ dsBitfields[0] = 0xF800;
+ dsBitfields[1] = 0x07e0;
+ dsBitfields[2] = 0x001f;
+ break;
+
+ case 24:
+ case 32:
+ dsBitfields[0] = 0xff0000;
+ dsBitfields[1] = 0x00ff00;
+ dsBitfields[2] = 0x0000ff;
+ break;
+ }
+ }
+ else
+ {
+ dsBitfields[0] = ((DWORD*)bmi->bmiColors)[0];
+ dsBitfields[1] = ((DWORD*)bmi->bmiColors)[1];
+ dsBitfields[2] = ((DWORD*)bmi->bmiColors)[2];
}
- dib->dshSection = section;
- dib->dsOffset = offset;
// 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)
- {
+ 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);
+ if (!res)
+ {
if (lpRGB != bmi->bmiColors)
- {
- ExFreePool(lpRGB);
- }
+ {
+ ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
+ }
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- return NULL;
- }
- bmp = BITMAPOBJ_LockBitmap(res);
+ return NULL;
+ }
+ 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. */
- bi->biClrUsed = 0;
- if(bi->biBitCount == 1) { bi->biClrUsed = 2; } else
- if(bi->biBitCount == 4) { bi->biClrUsed = 16; } else
- if(bi->biBitCount == 8) { bi->biClrUsed = 256; }
+ {
+ ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
+ }
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ GreDeleteObject(res);
+ return 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. */
+ if (bi->biBitCount <= 8)
+ {
+ bi->biClrUsed = 1 << bi->biBitCount;
+ }
+ else
+ {
+ bi->biClrUsed = 0;
+ }
+
+ bmp->hDIBSection = section;
+ bmp->hSecure = hSecure;
+ bmp->dwOffset = offset;
+ bmp->flags = API_BITMAP;
+ bmp->dsBitfields[0] = dsBitfields[0];
+ bmp->dsBitfields[1] = dsBitfields[1];
+ bmp->dsBitfields[2] = dsBitfields[2];
+ bmp->biClrUsed = bi->biClrUsed;
+ bmp->biClrImportant = bi->biClrImportant;
if (bi->biClrUsed != 0)
- bmp->hDIBPalette = PALETTE_AllocPaletteIndexedRGB(bi->biClrUsed, lpRGB);
+ {
+ hpal = PALETTE_AllocPaletteIndexedRGB(ColorCount, lpRGB);
+ }
else
- bmp->hDIBPalette = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL,
- dib->dsBitfields[0],
- dib->dsBitfields[1],
- dib->dsBitfields[2]);
+ {
+ hpal = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL,
+ dsBitfields[0],
+ dsBitfields[1],
+ dsBitfields[2]);
+ }
- dib->dsBmih = *bi;
- dib->dsBmih.biSizeImage = totalSize;
- }
+ bmp->ppal = PALETTE_ShareLockPalette(hpal);
+ /* Lazy delete hpal, it will be freed at surface release */
+ GreDeleteObject(hpal);
+
+ // Clean up in case of errors
+ 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;
+ }
- // 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;
- } */
+ if (bmp)
+ bmp = NULL;
- if (dib) { ExFreePool(dib); dib = NULL; }
- if (bmp) { bmp = NULL; }
- if (res) { BITMAPOBJ_FreeBitmapByHandle(res); res = 0; }
- }
+ if (res)
+ {
+ SURFACE_FreeSurfaceByHandle(res);
+ res = 0;
+ }
+ }
- if (lpRGB != bmi->bmiColors)
+ if (lpRGB != bmi->bmiColors)
{
- ExFreePool(lpRGB);
+ ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
}
- 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;
+ if (res) pdcattr->ulDirty_ |= DC_DIBSECTION;
+
+ return res;
}
/***********************************************************************
* 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));
- }
+ 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 info->bmiHeader.biSize + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
+ }
}
-RGBQUAD * FASTCALL
+RGBQUAD *
+FASTCALL
DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi)
{
- RGBQUAD *lpRGB;
- ULONG nNumColors,i;
- USHORT *lpIndex;
- PPALGDI palGDI;
+ RGBQUAD *lpRGB;
+ ULONG nNumColors,i;
+ USHORT *lpIndex;
+ PPALETTE palGDI;
- palGDI = PALETTE_LockPalette(dc->DcLevel.hpal);
+ palGDI = PALETTE_LockPalette(dc->dclevel.hpal);
- if (NULL == palGDI)
+ if (NULL == palGDI)
{
- return NULL;
+ return NULL;
}
- if (palGDI->Mode != PAL_INDEXED)
+ if (palGDI->Mode != PAL_INDEXED)
+ {
+ PALETTE_UnlockPalette(palGDI);
+ return NULL;
+ }
+
+ nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
+ if (lpbmi->bmiHeader.biClrUsed)
+ {
+ nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
+ }
+
+ lpRGB = (RGBQUAD *)ExAllocatePoolWithTag(PagedPool, sizeof(RGBQUAD) * nNumColors, TAG_COLORMAP);
+ if (lpRGB == NULL)
+ {
+ PALETTE_UnlockPalette(palGDI);
+ return NULL;
+ }
+
+ lpIndex = (USHORT *)&lpbmi->bmiColors[0];
+
+ for (i = 0; i < nNumColors; i++)
+ {
+ if (*lpIndex < palGDI->NumColors)
+ {
+ lpRGB[i].rgbRed = palGDI->IndexedColors[*lpIndex].peRed;
+ lpRGB[i].rgbGreen = palGDI->IndexedColors[*lpIndex].peGreen;
+ lpRGB[i].rgbBlue = palGDI->IndexedColors[*lpIndex].peBlue;
+ }
+ else
+ {
+ lpRGB[i].rgbRed = 0;
+ lpRGB[i].rgbGreen = 0;
+ lpRGB[i].rgbBlue = 0;
+ }
+ lpRGB[i].rgbReserved = 0;
+ lpIndex++;
+ }
+ PALETTE_UnlockPalette(palGDI);
+
+ return lpRGB;
+}
+
+HPALETTE
+FASTCALL
+BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType)
+{
+ BYTE bits;
+ ULONG ColorCount;
+ HPALETTE hPal;
+ ULONG RedMask, GreenMask, BlueMask;
+ PDWORD pdwColors = (PDWORD)((PBYTE)bmi + bmi->bmiHeader.biSize);
+
+ // Determine Bits Per Pixel
+ bits = bmi->bmiHeader.biBitCount;
+
+ // Determine paletteType from Bits Per Pixel
+ if (bits <= 8)
+ {
+ *paletteType = PAL_INDEXED;
+ RedMask = GreenMask = BlueMask = 0;
+ }
+ else if (bmi->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ *paletteType = PAL_BITFIELDS;
+ RedMask = pdwColors[0];
+ GreenMask = pdwColors[1];
+ BlueMask = pdwColors[2];
+ }
+ else if (bits == 15)
+ {
+ *paletteType = PAL_BITFIELDS;
+ RedMask = 0x7c00;
+ GreenMask = 0x03e0;
+ BlueMask = 0x001f;
+ }
+ else if (bits == 16)
{
- PALETTE_UnlockPalette(palGDI);
- return NULL;
+ *paletteType = PAL_BITFIELDS;
+ RedMask = 0xF800;
+ GreenMask = 0x07e0;
+ BlueMask = 0x001f;
+ }
+ else
+ {
+ *paletteType = PAL_BGR;
+ RedMask = 0xff0000;
+ GreenMask = 0x00ff00;
+ BlueMask = 0x0000ff;
}
- nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
- if (lpbmi->bmiHeader.biClrUsed)
+ if (bmi->bmiHeader.biClrUsed == 0)
+ {
+ ColorCount = 1 << bmi->bmiHeader.biBitCount;
+ }
+ else
{
- nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
+ ColorCount = bmi->bmiHeader.biClrUsed;
}
- lpRGB = (RGBQUAD *)ExAllocatePoolWithTag(PagedPool, sizeof(RGBQUAD) * nNumColors, TAG_COLORMAP);
- if (lpRGB == NULL)
- {
- PALETTE_UnlockPalette(palGDI);
- return NULL;
- }
+ if (PAL_INDEXED == *paletteType)
+ {
+ hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)pdwColors);
+ }
+ else
+ {
+ hPal = PALETTE_AllocPalette(*paletteType, ColorCount,
+ NULL,
+ RedMask, GreenMask, BlueMask);
+ }
- lpIndex = (USHORT *)&lpbmi->bmiColors[0];
+ return hPal;
+}
- for (i = 0; i < nNumColors; i++)
+FORCEINLINE
+DWORD
+GetBMIColor(CONST BITMAPINFO* pbmi, INT i)
+{
+ DWORD dwRet = 0;
+ INT size;
+ if(pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
- lpRGB[i].rgbRed = palGDI->IndexedColors[*lpIndex].peRed;
- lpRGB[i].rgbGreen = palGDI->IndexedColors[*lpIndex].peGreen;
- lpRGB[i].rgbBlue = palGDI->IndexedColors[*lpIndex].peBlue;
- lpRGB[i].rgbReserved = 0;
- lpIndex++;
+ /* BITMAPCOREINFO holds RGBTRIPLE values */
+ size = sizeof(RGBTRIPLE);
}
- PALETTE_UnlockPalette(palGDI);
+ else
+ {
+ size = sizeof(RGBQUAD);
+ }
+ memcpy(&dwRet, (PBYTE)pbmi + pbmi->bmiHeader.biSize + i*size, size);
+ return dwRet;
+}
- return lpRGB;
+FORCEINLINE
+VOID
+SetBMIColor(CONST BITMAPINFO* pbmi, DWORD* color, INT i)
+{
+ if(pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+ {
+ *(RGBTRIPLE*)((PBYTE)pbmi + pbmi->bmiHeader.biSize + i*sizeof(RGBTRIPLE)) = *(RGBTRIPLE*)color;
+ }
+ else
+ {
+ *(RGBQUAD*)((PBYTE)pbmi + pbmi->bmiHeader.biSize + i*sizeof(RGBQUAD)) = *(RGBQUAD*)color;
+ }
}
-HPALETTE FASTCALL
-BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType)
+NTSTATUS
+FASTCALL
+ProbeAndConvertToBitmapV5Info(
+ OUT PBITMAPV5INFO pbmiDst,
+ IN CONST BITMAPINFO* pbmiUnsafe,
+ IN DWORD dwColorUse)
{
- BYTE bits;
- ULONG ColorCount;
- PALETTEENTRY *palEntries = NULL;
- HPALETTE hPal;
- ULONG RedMask, GreenMask, BlueMask;
+ DWORD dwSize;
+ ULONG ulWidthBytes;
+ PBITMAPV5HEADER pbmhDst = &pbmiDst->bmiHeader;
+
+ /* Get the size and probe */
+ ProbeForRead(&pbmiUnsafe->bmiHeader.biSize, sizeof(DWORD), 1);
+ dwSize = pbmiUnsafe->bmiHeader.biSize;
+ ProbeForRead(pbmiUnsafe, dwSize, 1);
+
+ /* Check the size */
+ // FIXME: are intermediate sizes allowed? As what are they interpreted?
+ // make sure we don't use a too big dwSize later
+ if (dwSize != sizeof(BITMAPCOREHEADER) &&
+ dwSize != sizeof(BITMAPINFOHEADER) &&
+ dwSize != sizeof(BITMAPV4HEADER) &&
+ dwSize != sizeof(BITMAPV5HEADER))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (dwSize == sizeof(BITMAPCOREHEADER))
+ {
+ PBITMAPCOREHEADER pbch = (PBITMAPCOREHEADER)pbmiUnsafe;
+
+ /* Manually copy the fields that are present */
+ pbmhDst->bV5Width = pbch->bcWidth;
+ pbmhDst->bV5Height = pbch->bcHeight;
+ pbmhDst->bV5Planes = pbch->bcPlanes;
+ pbmhDst->bV5BitCount = pbch->bcBitCount;
+
+ /* Set some default values */
+ pbmhDst->bV5Compression = BI_RGB;
+ pbmhDst->bV5SizeImage = 0;
+ pbmhDst->bV5XPelsPerMeter = 72;
+ pbmhDst->bV5YPelsPerMeter = 72;
+ pbmhDst->bV5ClrUsed = 0;
+ pbmhDst->bV5ClrImportant = 0;
+ }
+ else
+ {
+ /* Copy valid fields */
+ memcpy(pbmiDst, pbmiUnsafe, dwSize);
- // Determine Bits Per Pixel
- bits = bmi->bmiHeader.biBitCount;
+ if(dwSize < sizeof(BITMAPV5HEADER))
+ {
+ /* Zero out the rest of the V5 header */
+ memset((char*)pbmiDst + dwSize, 0, sizeof(BITMAPV5HEADER) - dwSize);
+ }
+ }
+ pbmhDst->bV5Size = sizeof(BITMAPV5HEADER);
- // Determine paletteType from Bits Per Pixel
- if (bits <= 8)
+
+ if (dwSize < sizeof(BITMAPV4HEADER))
{
- *paletteType = PAL_INDEXED;
- RedMask = GreenMask = BlueMask = 0;
+ if (pbmhDst->bV5Compression == BI_BITFIELDS)
+ {
+ pbmhDst->bV5RedMask = GetBMIColor(pbmiUnsafe, 0);
+ pbmhDst->bV5GreenMask = GetBMIColor(pbmiUnsafe, 1);
+ pbmhDst->bV5BlueMask = GetBMIColor(pbmiUnsafe, 2);
+ pbmhDst->bV5AlphaMask = 0;
+ pbmhDst->bV5ClrUsed = 0;
+ }
+
+// pbmhDst->bV5CSType;
+// pbmhDst->bV5Endpoints;
+// pbmhDst->bV5GammaRed;
+// pbmhDst->bV5GammaGreen;
+// pbmhDst->bV5GammaBlue;
}
- else if(bmi->bmiHeader.biCompression == BI_BITFIELDS)
+
+ if (dwSize < sizeof(BITMAPV5HEADER))
{
- *paletteType = PAL_BITFIELDS;
- RedMask = ((ULONG *)bmi->bmiColors)[0];
- GreenMask = ((ULONG *)bmi->bmiColors)[1];
- BlueMask = ((ULONG *)bmi->bmiColors)[2];
+// pbmhDst->bV5Intent;
+// pbmhDst->bV5ProfileData;
+// pbmhDst->bV5ProfileSize;
+// pbmhDst->bV5Reserved;
}
- else if(bits < 24)
+
+ ulWidthBytes = ((pbmhDst->bV5Width * pbmhDst->bV5Planes *
+ pbmhDst->bV5BitCount + 31) & ~31) / 8;
+
+ if (pbmhDst->bV5SizeImage == 0)
+ pbmhDst->bV5SizeImage = abs(ulWidthBytes * pbmhDst->bV5Height);
+
+ if (pbmhDst->bV5ClrUsed == 0)
{
- *paletteType = PAL_BITFIELDS;
- RedMask = 0x7c00;
- GreenMask = 0x03e0;
- BlueMask = 0x001f;
+ switch(pbmhDst->bV5BitCount)
+ {
+ case 1:
+ pbmhDst->bV5ClrUsed = 2;
+ break;
+ case 4:
+ pbmhDst->bV5ClrUsed = 16;
+ break;
+ case 8:
+ pbmhDst->bV5ClrUsed = 256;
+ break;
+ default:
+ pbmhDst->bV5ClrUsed = 0;
+ break;
+ }
}
- else
+
+ if (pbmhDst->bV5Planes != 1)
{
- *paletteType = PAL_BGR;
- RedMask = 0xff0000;
- GreenMask = 0x00ff00;
- BlueMask = 0x0000ff;
+ return STATUS_INVALID_PARAMETER;
}
- if (bmi->bmiHeader.biClrUsed == 0)
+ if (pbmhDst->bV5BitCount != 0 && pbmhDst->bV5BitCount != 1 &&
+ pbmhDst->bV5BitCount != 4 && pbmhDst->bV5BitCount != 8 &&
+ pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 24 &&
+ pbmhDst->bV5BitCount != 32)
{
- ColorCount = 1 << bmi->bmiHeader.biBitCount;
+ DPRINT("Invalid bit count: %d\n", pbmhDst->bV5BitCount);
+ return STATUS_INVALID_PARAMETER;
}
- else
+
+ if ((pbmhDst->bV5BitCount == 0 &&
+ pbmhDst->bV5Compression != BI_JPEG && pbmhDst->bV5Compression != BI_PNG))
{
- ColorCount = bmi->bmiHeader.biClrUsed;
+ DPRINT("Bit count 0 is invalid for compression %d.\n", pbmhDst->bV5Compression);
+ return STATUS_INVALID_PARAMETER;
}
- if (PAL_INDEXED == *paletteType)
+ if (pbmhDst->bV5Compression == BI_BITFIELDS &&
+ pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 32)
{
- hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)bmi->bmiColors);
+ DPRINT("Bit count %d is invalid for compression BI_BITFIELDS.\n", pbmhDst->bV5BitCount);
+ return STATUS_INVALID_PARAMETER;
}
- else
+
+ /* Copy Colors */
+ if(pbmhDst->bV5ClrUsed)
{
- hPal = PALETTE_AllocPalette(*paletteType, ColorCount,
- (ULONG*) palEntries,
- RedMask, GreenMask, BlueMask );
+ INT i;
+ if(dwColorUse == DIB_PAL_COLORS)
+ {
+ RtlCopyMemory(pbmiDst->bmiColors,
+ pbmiUnsafe->bmiColors,
+ pbmhDst->bV5ClrUsed * sizeof(WORD));
+ }
+ else
+ {
+ for(i = 0; i < pbmhDst->bV5ClrUsed; i++)
+ {
+ ((DWORD*)pbmiDst->bmiColors)[i] = GetBMIColor(pbmiUnsafe, i);
+ }
+ }
}
- return hPal;
+ return STATUS_SUCCESS;
+}
+
+VOID
+FASTCALL
+GetBMIFromBitmapV5Info(IN PBITMAPV5INFO pbmiSrc,
+ OUT PBITMAPINFO pbmiDst,
+ IN DWORD dwColorUse)
+{
+ if(pbmiDst->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+ {
+ /* Manually set value */
+ BITMAPCOREHEADER* pbmhCore = (BITMAPCOREHEADER*)&pbmiDst->bmiHeader;
+ pbmhCore->bcWidth = pbmiSrc->bmiHeader.bV5Width;
+ pbmhCore->bcHeight = pbmiSrc->bmiHeader.bV5Height;
+ pbmhCore->bcPlanes = pbmiSrc->bmiHeader.bV5Planes;
+ pbmhCore->bcBitCount = pbmiSrc->bmiHeader.bV5BitCount;
+ }
+ else
+ {
+ /* Copy valid Fields, keep bmiHeader.biSize safe */
+ RtlCopyMemory((PBYTE)pbmiDst + sizeof(DWORD), pbmiSrc, pbmiDst->bmiHeader.biSize - sizeof(DWORD));
+ }
+ if((pbmiDst->bmiHeader.biSize < sizeof(BITMAPV4HEADER)) &&
+ (pbmiSrc->bmiHeader.bV5Compression == BI_BITFIELDS))
+ {
+ /* Masks are already set in V4 and V5 headers */
+ SetBMIColor(pbmiDst, &pbmiSrc->bmiHeader.bV5RedMask, 0);
+ SetBMIColor(pbmiDst, &pbmiSrc->bmiHeader.bV5GreenMask, 1);
+ SetBMIColor(pbmiDst, &pbmiSrc->bmiHeader.bV5BlueMask, 2);
+ }
+ else
+ {
+ INT i;
+ if(dwColorUse == DIB_PAL_COLORS)
+ {
+ RtlCopyMemory(pbmiDst->bmiColors,
+ pbmiSrc->bmiColors,
+ pbmiSrc->bmiHeader.bV5ClrUsed * sizeof(WORD));
+ }
+ else
+ {
+ for(i = 0; i < pbmiSrc->bmiHeader.bV5ClrUsed; i++)
+ {
+ SetBMIColor(pbmiDst, (DWORD*)pbmiSrc->bmiColors + i, i);
+ }
+ }
+ }
}
/* EOF */