2003-05-18 17:16:18 +00:00
|
|
|
/*
|
2003-06-06 10:17:44 +00:00
|
|
|
* ReactOS W32 Subsystem
|
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
|
2003-05-18 17:16:18 +00:00
|
|
|
*
|
2003-06-06 10:17:44 +00:00
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
2003-05-18 17:16:18 +00:00
|
|
|
*
|
2003-06-06 10:17:44 +00:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
2009-10-27 10:34:16 +00:00
|
|
|
* 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.
|
2003-05-18 17:16:18 +00:00
|
|
|
*/
|
2005-06-29 07:09:25 +00:00
|
|
|
|
2010-04-26 13:58:46 +00:00
|
|
|
#include <win32k.h>
|
2005-06-29 07:09:25 +00:00
|
|
|
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
2003-03-06 00:56:59 +00:00
|
|
|
|
2008-12-01 00:13:45 +00:00
|
|
|
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 }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
UINT
|
|
|
|
APIENTRY
|
|
|
|
IntSetDIBColorTable(
|
|
|
|
HDC hDC,
|
|
|
|
UINT StartIndex,
|
|
|
|
UINT Entries,
|
|
|
|
CONST RGBQUAD *Colors)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
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;
|
|
|
|
|
2010-05-12 22:56:24 +00:00
|
|
|
if (psurf->ppal == NULL)
|
2009-06-10 00:23:15 +00:00
|
|
|
{
|
|
|
|
DC_UnlockDc(dc);
|
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-05-12 22:56:24 +00:00
|
|
|
PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
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;
|
2004-05-15 08:52:25 +00:00
|
|
|
}
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
UINT
|
|
|
|
APIENTRY
|
|
|
|
IntGetDIBColorTable(
|
|
|
|
HDC hDC,
|
|
|
|
UINT StartIndex,
|
|
|
|
UINT Entries,
|
|
|
|
RGBQUAD *Colors)
|
2004-05-15 08:52:25 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
PDC dc;
|
|
|
|
PSURFACE psurf;
|
|
|
|
PPALETTE PalGDI;
|
2009-12-25 17:54:41 +00:00
|
|
|
UINT Index, Count = 0;
|
2009-06-10 00:23:15 +00:00
|
|
|
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;
|
|
|
|
|
2010-05-12 22:56:24 +00:00
|
|
|
if (psurf->ppal == NULL)
|
2009-06-10 00:23:15 +00:00
|
|
|
{
|
|
|
|
DC_UnlockDc(dc);
|
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-05-12 22:56:24 +00:00
|
|
|
PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
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;
|
2009-12-25 17:54:41 +00:00
|
|
|
Count++;
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
|
|
|
PALETTE_UnlockPalette(PalGDI);
|
|
|
|
}
|
|
|
|
|
|
|
|
DC_UnlockDc(dc);
|
|
|
|
|
2009-12-25 17:54:41 +00:00
|
|
|
return Count;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Converts a DIB to a device-dependent bitmap
|
2009-06-10 00:23:15 +00:00
|
|
|
static INT
|
|
|
|
FASTCALL
|
2004-03-15 22:06:55 +00:00
|
|
|
IntSetDIBits(
|
2009-06-10 00:23:15 +00:00
|
|
|
PDC DC,
|
|
|
|
HBITMAP hBitmap,
|
|
|
|
UINT StartScan,
|
|
|
|
UINT ScanLines,
|
|
|
|
CONST VOID *Bits,
|
|
|
|
CONST BITMAPINFO *bmi,
|
|
|
|
UINT ColorUse)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
SURFACE *bitmap;
|
|
|
|
HBITMAP SourceBitmap;
|
|
|
|
INT result = 0;
|
|
|
|
BOOL copyBitsResult;
|
|
|
|
SURFOBJ *DestSurf, *SourceSurf;
|
|
|
|
SIZEL SourceSize;
|
|
|
|
POINTL ZeroPoint;
|
|
|
|
RECTL DestRect;
|
2009-08-04 20:37:10 +00:00
|
|
|
EXLATEOBJ exlo;
|
|
|
|
PPALETTE ppalDDB, ppalDIB;
|
2009-06-10 00:23:15 +00:00
|
|
|
//RGBQUAD *lpRGB;
|
2010-05-08 22:10:41 +00:00
|
|
|
HPALETTE DIB_Palette;
|
2009-08-04 20:37:10 +00:00
|
|
|
ULONG DIB_Palette_Type;
|
2009-06-10 00:23:15 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-05-12 22:56:24 +00:00
|
|
|
if (bitmap->ppal)
|
2009-06-10 00:23:15 +00:00
|
|
|
{
|
2010-05-08 22:10:41 +00:00
|
|
|
ppalDDB = bitmap->ppal;
|
|
|
|
GDIOBJ_IncrementShareCount(&ppalDDB->BaseObject);
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
2010-05-08 22:10:41 +00:00
|
|
|
else
|
|
|
|
// Destination palette obtained from the hDC
|
|
|
|
ppalDDB = PALETTE_ShareLockPalette(DC->ppdev->devinfo.hpalDefault);
|
2009-06-10 00:23:15 +00:00
|
|
|
|
2009-08-04 20:37:10 +00:00
|
|
|
if (NULL == ppalDDB)
|
2009-06-10 00:23:15 +00:00
|
|
|
{
|
|
|
|
EngUnlockSurface(SourceSurf);
|
|
|
|
EngDeleteSurface((HSURF)SourceBitmap);
|
|
|
|
SURFACE_UnlockSurface(bitmap);
|
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Source palette obtained from the BITMAPINFO
|
|
|
|
DIB_Palette = BuildDIBPalette((PBITMAPINFO)bmi, (PINT)&DIB_Palette_Type);
|
|
|
|
if (NULL == DIB_Palette)
|
|
|
|
{
|
|
|
|
EngUnlockSurface(SourceSurf);
|
|
|
|
EngDeleteSurface((HSURF)SourceBitmap);
|
|
|
|
SURFACE_UnlockSurface(bitmap);
|
2010-05-08 22:10:41 +00:00
|
|
|
PALETTE_ShareUnlockPalette(ppalDDB);
|
2009-06-10 00:23:15 +00:00
|
|
|
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-08-04 20:37:10 +00:00
|
|
|
ppalDIB = PALETTE_LockPalette(DIB_Palette);
|
|
|
|
|
|
|
|
/* Initialize XLATEOBJ for color translation */
|
|
|
|
EXLATEOBJ_vInitialize(&exlo, ppalDIB, ppalDDB, 0, 0, 0);
|
2009-06-10 00:23:15 +00:00
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
2009-08-04 20:37:10 +00:00
|
|
|
copyBitsResult = IntEngCopyBits(DestSurf, SourceSurf, NULL, &exlo.xlo, &DestRect, &ZeroPoint);
|
2009-06-10 00:23:15 +00:00
|
|
|
|
|
|
|
// If it succeeded, return number of scanlines copies
|
|
|
|
if (copyBitsResult == TRUE)
|
|
|
|
{
|
|
|
|
result = SourceSize.cy;
|
2008-11-18 21:24:33 +00:00
|
|
|
// or
|
2009-06-10 00:23:15 +00:00
|
|
|
// result = abs(bmi->bmiHeader.biHeight) - StartScan;
|
|
|
|
}
|
2002-09-17 23:20:44 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
// Clean up
|
2009-08-04 20:37:10 +00:00
|
|
|
EXLATEOBJ_vCleanup(&exlo);
|
|
|
|
PALETTE_UnlockPalette(ppalDIB);
|
2010-05-08 22:10:41 +00:00
|
|
|
PALETTE_ShareUnlockPalette(ppalDDB);
|
2009-06-10 00:23:15 +00:00
|
|
|
PALETTE_FreePaletteByHandle(DIB_Palette);
|
|
|
|
EngUnlockSurface(SourceSurf);
|
|
|
|
EngDeleteSurface((HSURF)SourceBitmap);
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
// if (ColorUse == DIB_PAL_COLORS)
|
|
|
|
// WinFree((LPSTR)lpRGB);
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
SURFACE_UnlockSurface(bitmap);
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
return result;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
// FIXME by Removing NtGdiSetDIBits!!!
|
2008-12-01 00:13:45 +00:00
|
|
|
// This is a victim of the Win32k Initialization BUG!!!!!
|
2008-04-19 19:00:34 +00:00
|
|
|
// Converts a DIB to a device-dependent bitmap
|
2009-06-10 00:23:15 +00:00
|
|
|
INT
|
|
|
|
APIENTRY
|
2008-04-19 19:00:34 +00:00
|
|
|
NtGdiSetDIBits(
|
2009-06-10 00:23:15 +00:00
|
|
|
HDC hDC,
|
|
|
|
HBITMAP hBitmap,
|
|
|
|
UINT StartScan,
|
|
|
|
UINT ScanLines,
|
|
|
|
CONST VOID *Bits,
|
|
|
|
CONST BITMAPINFO *bmi,
|
|
|
|
UINT ColorUse)
|
2008-04-19 19:00:34 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
PDC Dc;
|
|
|
|
INT Ret;
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
UINT cjBits;
|
|
|
|
|
|
|
|
if (!Bits) return 0;
|
|
|
|
|
|
|
|
_SEH2_TRY
|
|
|
|
{ // FYI: We converted from CORE in gdi.
|
|
|
|
ProbeForRead(bmi, sizeof(BITMAPINFO), 1);
|
|
|
|
cjBits = bmi->bmiHeader.biBitCount * bmi->bmiHeader.biPlanes * bmi->bmiHeader.biWidth;
|
|
|
|
cjBits = ((cjBits + 31) & ~31) / 8;
|
|
|
|
cjBits *= ScanLines;
|
|
|
|
ProbeForRead(Bits, cjBits, 1);
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
Status = _SEH2_GetExceptionCode();
|
|
|
|
}
|
|
|
|
_SEH2_END
|
2008-04-19 19:00:34 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2008-04-19 19:00:34 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
Dc = DC_LockDc(hDC);
|
|
|
|
if (NULL == Dc)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (Dc->dctype == DC_TYPE_INFO)
|
|
|
|
{
|
|
|
|
DC_UnlockDc(Dc);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
|
|
|
|
|
|
|
|
DC_UnlockDc(Dc);
|
|
|
|
|
|
|
|
return Ret;
|
|
|
|
}
|
2008-04-19 19:00:34 +00:00
|
|
|
|
2007-08-19 23:49:47 +00:00
|
|
|
W32KAPI
|
|
|
|
INT
|
|
|
|
APIENTRY
|
|
|
|
NtGdiSetDIBitsToDeviceInternal(
|
|
|
|
IN HDC hDC,
|
|
|
|
IN INT XDest,
|
|
|
|
IN INT YDest,
|
|
|
|
IN DWORD Width,
|
|
|
|
IN DWORD Height,
|
|
|
|
IN INT XSrc,
|
|
|
|
IN INT YSrc,
|
|
|
|
IN DWORD StartScan,
|
|
|
|
IN DWORD ScanLines,
|
|
|
|
IN LPBYTE Bits,
|
|
|
|
IN LPBITMAPINFO bmi,
|
|
|
|
IN DWORD ColorUse,
|
|
|
|
IN UINT cjMaxBits,
|
|
|
|
IN UINT cjMaxInfo,
|
|
|
|
IN BOOL bTransformCoordinates,
|
2009-06-10 00:23:15 +00:00
|
|
|
IN OPTIONAL HANDLE hcmXform)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2007-09-27 17:04:29 +00:00
|
|
|
INT ret = 0;
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
PDC pDC;
|
2008-04-19 00:24:34 +00:00
|
|
|
HBITMAP hSourceBitmap = NULL;
|
|
|
|
SURFOBJ *pDestSurf, *pSourceSurf = NULL;
|
2009-04-02 17:25:56 +00:00
|
|
|
SURFACE *pSurf;
|
2007-09-27 17:04:29 +00:00
|
|
|
RECTL rcDest;
|
|
|
|
POINTL ptSource;
|
|
|
|
INT DIBWidth;
|
|
|
|
SIZEL SourceSize;
|
2009-08-04 20:37:10 +00:00
|
|
|
EXLATEOBJ exlo;
|
|
|
|
PPALETTE ppalDDB = NULL, ppalDIB = NULL;
|
2010-05-08 22:10:41 +00:00
|
|
|
HPALETTE hpalDIB = NULL;
|
2009-08-04 20:37:10 +00:00
|
|
|
ULONG DIBPaletteType;
|
2007-09-27 17:04:29 +00:00
|
|
|
|
2007-12-08 18:32:22 +00:00
|
|
|
if (!Bits) return 0;
|
|
|
|
|
2008-12-01 00:13:45 +00:00
|
|
|
_SEH2_TRY
|
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
ProbeForRead(bmi, cjMaxInfo , 1);
|
2008-12-01 00:13:45 +00:00
|
|
|
ProbeForRead(Bits, cjMaxBits, 1);
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
Status = _SEH2_GetExceptionCode();
|
2008-12-01 00:13:45 +00:00
|
|
|
}
|
|
|
|
_SEH2_END
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
return 0;
|
2008-12-01 00:13:45 +00:00
|
|
|
}
|
|
|
|
|
2007-09-27 17:04:29 +00:00
|
|
|
pDC = DC_LockDc(hDC);
|
|
|
|
if (!pDC)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
2009-03-20 01:35:49 +00:00
|
|
|
if (pDC->dctype == DC_TYPE_INFO)
|
2007-09-27 17:04:29 +00:00
|
|
|
{
|
|
|
|
DC_UnlockDc(pDC);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-04-14 20:50:02 +00:00
|
|
|
pSurf = pDC->dclevel.pSurface;
|
2007-09-27 17:04:29 +00:00
|
|
|
|
2009-04-14 20:50:02 +00:00
|
|
|
pDestSurf = pSurf ? &pSurf->SurfObj : NULL;
|
2009-04-02 17:25:56 +00:00
|
|
|
|
2009-12-23 17:41:20 +00:00
|
|
|
ScanLines = min(ScanLines, abs(bmi->bmiHeader.biHeight) - StartScan);
|
|
|
|
|
2007-09-27 17:04:29 +00:00
|
|
|
rcDest.left = XDest;
|
|
|
|
rcDest.top = YDest;
|
2008-06-05 22:23:19 +00:00
|
|
|
if (bTransformCoordinates)
|
|
|
|
{
|
|
|
|
CoordLPtoDP(pDC, (LPPOINT)&rcDest);
|
|
|
|
}
|
|
|
|
rcDest.left += pDC->ptlDCOrig.x;
|
|
|
|
rcDest.top += pDC->ptlDCOrig.y;
|
|
|
|
rcDest.right = rcDest.left + Width;
|
|
|
|
rcDest.bottom = rcDest.top + Height;
|
2009-12-23 17:41:20 +00:00
|
|
|
rcDest.top += StartScan;
|
|
|
|
|
2007-09-27 17:04:29 +00:00
|
|
|
ptSource.x = XSrc;
|
|
|
|
ptSource.y = YSrc;
|
|
|
|
|
2008-12-01 00:13:45 +00:00
|
|
|
SourceSize.cx = bmi->bmiHeader.biWidth;
|
2009-12-23 17:41:20 +00:00
|
|
|
SourceSize.cy = ScanLines;
|
|
|
|
|
2008-12-01 00:13:45 +00:00
|
|
|
DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
|
2008-05-06 20:44:25 +00:00
|
|
|
|
2008-12-01 00:13:45 +00:00
|
|
|
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;
|
|
|
|
}
|
2008-05-06 20:44:25 +00:00
|
|
|
|
2008-12-01 00:13:45 +00:00
|
|
|
pSourceSurf = EngLockSurface((HSURF)hSourceBitmap);
|
|
|
|
if (!pSourceSurf)
|
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
|
|
goto Exit;
|
2008-12-01 00:13:45 +00:00
|
|
|
}
|
2008-04-19 00:24:34 +00:00
|
|
|
|
2009-04-02 17:25:56 +00:00
|
|
|
/* Obtain destination palette */
|
2010-05-12 22:56:24 +00:00
|
|
|
if (pSurf && pSurf->ppal)
|
2010-05-08 22:10:41 +00:00
|
|
|
{
|
|
|
|
ppalDDB = pSurf->ppal;
|
|
|
|
GDIOBJ_IncrementShareCount(&ppalDDB->BaseObject);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ppalDDB = PALETTE_ShareLockPalette(pDC->ppdev->devinfo.hpalDefault);
|
|
|
|
|
2009-08-04 20:37:10 +00:00
|
|
|
if (!ppalDDB)
|
2008-12-01 00:13:45 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
|
|
goto Exit;
|
2008-12-01 00:13:45 +00:00
|
|
|
}
|
2007-09-27 17:04:29 +00:00
|
|
|
|
2009-10-30 14:02:42 +00:00
|
|
|
/* Create a palette for the DIB */
|
|
|
|
hpalDIB = BuildDIBPalette(bmi, (PINT)&DIBPaletteType);
|
|
|
|
if (!hpalDIB)
|
2008-12-01 00:13:45 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
|
|
|
|
Status = STATUS_NO_MEMORY;
|
|
|
|
goto Exit;
|
2007-09-27 17:04:29 +00:00
|
|
|
}
|
2008-12-01 00:13:45 +00:00
|
|
|
|
2009-10-30 14:02:42 +00:00
|
|
|
/* Lock the DIB palette */
|
|
|
|
ppalDIB = PALETTE_LockPalette(hpalDIB);
|
2010-05-08 22:10:41 +00:00
|
|
|
if (!ppalDIB)
|
2009-10-30 14:02:42 +00:00
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
|
2009-08-04 20:37:10 +00:00
|
|
|
/* Initialize EXLATEOBJ */
|
|
|
|
EXLATEOBJ_vInitialize(&exlo, ppalDIB, ppalDDB, 0, 0, 0);
|
2007-09-27 17:04:29 +00:00
|
|
|
|
2008-12-01 00:13:45 +00:00
|
|
|
/* Copy the bits */
|
2010-05-08 22:10:41 +00:00
|
|
|
DPRINT("BitsToDev with dstsurf=(%d|%d) (%d|%d), src=(%d|%d) w=%d h=%d\n",
|
2009-12-23 17:41:20 +00:00
|
|
|
rcDest.left, rcDest.top, rcDest.right, rcDest.bottom,
|
|
|
|
ptSource.x, ptSource.y, SourceSize.cx, SourceSize.cy);
|
2008-12-01 00:13:45 +00:00
|
|
|
Status = IntEngBitBlt(pDestSurf,
|
|
|
|
pSourceSurf,
|
|
|
|
NULL,
|
2009-03-20 01:35:49 +00:00
|
|
|
pDC->rosdc.CombinedClip,
|
2009-08-04 20:37:10 +00:00
|
|
|
&exlo.xlo,
|
2008-12-01 00:13:45 +00:00
|
|
|
&rcDest,
|
|
|
|
&ptSource,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
ROP3_TO_ROP4(SRCCOPY));
|
2009-08-04 20:37:10 +00:00
|
|
|
|
|
|
|
/* Cleanup EXLATEOBJ */
|
|
|
|
EXLATEOBJ_vCleanup(&exlo);
|
|
|
|
|
2008-12-01 00:13:45 +00:00
|
|
|
Exit:
|
2007-09-27 17:04:29 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2009-12-23 17:41:20 +00:00
|
|
|
ret = ScanLines;
|
2007-09-27 17:04:29 +00:00
|
|
|
}
|
|
|
|
|
2009-08-04 20:37:10 +00:00
|
|
|
if (ppalDIB) PALETTE_UnlockPalette(ppalDIB);
|
2010-05-08 22:10:41 +00:00
|
|
|
if (ppalDDB) PALETTE_ShareUnlockPalette(ppalDDB);
|
2009-08-04 20:37:10 +00:00
|
|
|
|
2008-04-19 00:24:34 +00:00
|
|
|
if (pSourceSurf) EngUnlockSurface(pSourceSurf);
|
|
|
|
if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
|
2009-10-30 14:02:42 +00:00
|
|
|
if (hpalDIB) PALETTE_FreePaletteByHandle(hpalDIB);
|
2007-09-27 17:04:29 +00:00
|
|
|
DC_UnlockDc(pDC);
|
|
|
|
|
|
|
|
return ret;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2007-10-01 11:53:31 +00:00
|
|
|
|
2004-07-03 13:55:37 +00:00
|
|
|
/* Converts a device-dependent bitmap to a DIB */
|
2009-06-10 00:23:15 +00:00
|
|
|
INT
|
|
|
|
APIENTRY
|
|
|
|
NtGdiGetDIBitsInternal(
|
|
|
|
HDC hDC,
|
|
|
|
HBITMAP hBitmap,
|
|
|
|
UINT StartScan,
|
|
|
|
UINT ScanLines,
|
|
|
|
LPBYTE Bits,
|
|
|
|
LPBITMAPINFO Info,
|
|
|
|
UINT Usage,
|
|
|
|
UINT MaxBits,
|
|
|
|
UINT MaxInfo)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2007-09-18 15:24:34 +00:00
|
|
|
PDC Dc;
|
2009-01-08 16:33:40 +00:00
|
|
|
SURFACE *psurf = NULL;
|
2007-10-01 11:53:31 +00:00
|
|
|
HBITMAP hDestBitmap = NULL;
|
|
|
|
HPALETTE hDestPalette = NULL;
|
2009-08-04 20:37:10 +00:00
|
|
|
PPALETTE ppalSrc = NULL;
|
|
|
|
PPALETTE ppalDst = NULL;
|
2007-10-01 11:53:31 +00:00
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2007-09-18 15:24:34 +00:00
|
|
|
ULONG Result = 0;
|
2007-10-01 11:53:31 +00:00
|
|
|
BOOL bPaletteMatch = FALSE;
|
2008-12-01 00:13:45 +00:00
|
|
|
PBYTE ChkBits = Bits;
|
|
|
|
PVOID ColorPtr;
|
|
|
|
RGBQUAD *rgbQuads;
|
2009-03-21 19:15:52 +00:00
|
|
|
ULONG DestPaletteType;
|
|
|
|
ULONG Index;
|
2007-10-01 11:53:31 +00:00
|
|
|
|
|
|
|
DPRINT("Entered NtGdiGetDIBitsInternal()\n");
|
2007-09-18 15:24:34 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
if ((Usage && Usage != DIB_PAL_COLORS) || !Info || !hBitmap)
|
|
|
|
return 0;
|
2008-12-01 00:13:45 +00:00
|
|
|
|
|
|
|
// if ScanLines == 0, no need to copy Bits.
|
2009-06-10 00:23:15 +00:00
|
|
|
if (!ScanLines)
|
|
|
|
ChkBits = NULL;
|
2008-12-01 00:13:45 +00:00
|
|
|
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
2009-08-04 20:37:10 +00:00
|
|
|
ProbeForRead(&Info->bmiHeader.biSize, sizeof(DWORD), 1);
|
2010-05-08 22:10:41 +00:00
|
|
|
|
2008-12-01 00:13:45 +00:00
|
|
|
ProbeForWrite(Info, Info->bmiHeader.biSize, 1); // Comp for Core.
|
|
|
|
if (ChkBits) ProbeForWrite(ChkBits, MaxBits, 1);
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
Status = _SEH2_GetExceptionCode();
|
2008-12-01 00:13:45 +00:00
|
|
|
}
|
|
|
|
_SEH2_END
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
return 0;
|
2008-12-01 00:13:45 +00:00
|
|
|
}
|
|
|
|
|
2007-09-18 15:24:34 +00:00
|
|
|
Dc = DC_LockDc(hDC);
|
2007-10-01 11:53:31 +00:00
|
|
|
if (Dc == NULL) return 0;
|
2009-03-20 01:35:49 +00:00
|
|
|
if (Dc->dctype == DC_TYPE_INFO)
|
2007-09-18 15:24:34 +00:00
|
|
|
{
|
|
|
|
DC_UnlockDc(Dc);
|
|
|
|
return 0;
|
|
|
|
}
|
2003-12-20 14:51:41 +00:00
|
|
|
|
2007-10-01 11:53:31 +00:00
|
|
|
/* Get a pointer to the source bitmap object */
|
2009-01-08 16:33:40 +00:00
|
|
|
psurf = SURFACE_LockSurface(hBitmap);
|
|
|
|
if (psurf == NULL)
|
2010-05-08 22:10:41 +00:00
|
|
|
{
|
|
|
|
DC_UnlockDc(Dc);
|
2009-06-10 00:23:15 +00:00
|
|
|
return 0;
|
2010-05-08 22:10:41 +00:00
|
|
|
}
|
2006-09-02 23:58:53 +00:00
|
|
|
|
2010-05-12 22:56:24 +00:00
|
|
|
if (psurf->ppal)
|
2010-05-08 22:10:41 +00:00
|
|
|
{
|
|
|
|
ppalSrc = psurf->ppal;
|
|
|
|
GDIOBJ_IncrementShareCount(&ppalSrc->BaseObject);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ppalSrc = PALETTE_ShareLockPalette(Dc->ppdev->devinfo.hpalDefault);
|
|
|
|
|
|
|
|
DC_UnlockDc(Dc);
|
|
|
|
|
|
|
|
ASSERT(ppalSrc != NULL);
|
2009-01-02 22:08:09 +00:00
|
|
|
|
2008-12-01 00:13:45 +00:00
|
|
|
ColorPtr = ((PBYTE)Info + Info->bmiHeader.biSize);
|
|
|
|
rgbQuads = (RGBQUAD *)ColorPtr;
|
2007-09-18 15:24:34 +00:00
|
|
|
|
2009-03-29 00:25:47 +00:00
|
|
|
/* Copy palette information
|
|
|
|
* Always create a palette for 15 & 16 bit. */
|
2009-08-04 20:37:10 +00:00
|
|
|
if ((Info->bmiHeader.biBitCount == BitsPerFormat(psurf->SurfObj.iBitmapFormat) &&
|
|
|
|
Info->bmiHeader.biBitCount != 15 && Info->bmiHeader.biBitCount != 16) ||
|
|
|
|
!ChkBits)
|
2009-03-21 19:15:52 +00:00
|
|
|
{
|
2010-05-08 22:10:41 +00:00
|
|
|
ppalDst = ppalSrc;
|
2009-06-10 00:23:15 +00:00
|
|
|
bPaletteMatch = TRUE;
|
2009-03-21 19:15:52 +00:00
|
|
|
}
|
|
|
|
else
|
2009-06-10 00:23:15 +00:00
|
|
|
hDestPalette = BuildDIBPalette(Info, (PINT)&DestPaletteType); //hDestPalette = Dc->DevInfo->hpalDefault;
|
2009-03-21 19:15:52 +00:00
|
|
|
|
2009-08-04 20:37:10 +00:00
|
|
|
if (!bPaletteMatch)
|
2009-03-21 19:15:52 +00:00
|
|
|
{
|
2009-08-04 20:37:10 +00:00
|
|
|
ppalDst = PALETTE_LockPalette(hDestPalette);
|
|
|
|
/* FIXME - ppalDst can be NULL!!!! Don't assert here!!! */
|
|
|
|
DPRINT("ppalDst : %p\n", ppalDst);
|
|
|
|
ASSERT(ppalDst);
|
2009-03-21 19:15:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy palette. */
|
|
|
|
/* FIXME: This is largely incomplete. ATM no Core!*/
|
2009-06-10 00:23:15 +00:00
|
|
|
switch (Info->bmiHeader.biBitCount)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
case 4:
|
|
|
|
case 8:
|
|
|
|
Info->bmiHeader.biClrUsed = 0;
|
|
|
|
if (psurf->hSecure &&
|
|
|
|
BitsPerFormat(psurf->SurfObj.iBitmapFormat) == Info->bmiHeader.biBitCount)
|
2009-03-21 19:15:52 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
if (Usage == DIB_RGB_COLORS)
|
|
|
|
{
|
2009-08-04 20:37:10 +00:00
|
|
|
if (ppalDst->NumColors != 1 << Info->bmiHeader.biBitCount)
|
|
|
|
Info->bmiHeader.biClrUsed = ppalDst->NumColors;
|
2009-06-10 00:23:15 +00:00
|
|
|
for (Index = 0;
|
2009-08-04 20:37:10 +00:00
|
|
|
Index < (1 << Info->bmiHeader.biBitCount) && Index < ppalDst->NumColors;
|
2009-06-10 00:23:15 +00:00
|
|
|
Index++)
|
|
|
|
{
|
2009-08-04 20:37:10 +00:00
|
|
|
rgbQuads[Index].rgbRed = ppalDst->IndexedColors[Index].peRed;
|
|
|
|
rgbQuads[Index].rgbGreen = ppalDst->IndexedColors[Index].peGreen;
|
|
|
|
rgbQuads[Index].rgbBlue = ppalDst->IndexedColors[Index].peBlue;
|
2009-06-10 00:23:15 +00:00
|
|
|
rgbQuads[Index].rgbReserved = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2009-03-21 19:15:52 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
PWORD Ptr = ColorPtr;
|
|
|
|
for (Index = 0;
|
|
|
|
Index < (1 << Info->bmiHeader.biBitCount);
|
|
|
|
Index++)
|
|
|
|
{
|
|
|
|
Ptr[Index] = (WORD)Index;
|
|
|
|
}
|
2009-03-21 19:15:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
if (Usage == DIB_PAL_COLORS)
|
|
|
|
{
|
|
|
|
PWORD Ptr = ColorPtr;
|
|
|
|
for (Index = 0;
|
|
|
|
Index < (1 << Info->bmiHeader.biBitCount);
|
|
|
|
Index++)
|
|
|
|
{
|
|
|
|
Ptr[Index] = (WORD)Index;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (Info->bmiHeader.biBitCount > 1 && bPaletteMatch)
|
|
|
|
{
|
|
|
|
for (Index = 0;
|
2009-08-04 20:37:10 +00:00
|
|
|
Index < (1 << Info->bmiHeader.biBitCount) && Index < ppalDst->NumColors;
|
2009-06-10 00:23:15 +00:00
|
|
|
Index++)
|
|
|
|
{
|
2009-08-04 20:37:10 +00:00
|
|
|
Info->bmiColors[Index].rgbRed = ppalDst->IndexedColors[Index].peRed;
|
|
|
|
Info->bmiColors[Index].rgbGreen = ppalDst->IndexedColors[Index].peGreen;
|
|
|
|
Info->bmiColors[Index].rgbBlue = ppalDst->IndexedColors[Index].peBlue;
|
2009-06-10 00:23:15 +00:00
|
|
|
Info->bmiColors[Index].rgbReserved = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (Info->bmiHeader.biBitCount)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
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:
|
|
|
|
RtlCopyMemory(ColorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
{
|
|
|
|
INT r, g, b;
|
|
|
|
RGBQUAD *color;
|
|
|
|
|
|
|
|
RtlCopyMemory(rgbQuads, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
|
|
|
|
RtlCopyMemory(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++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-03-21 19:15:52 +00:00
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
|
|
|
|
case 15:
|
|
|
|
if (Info->bmiHeader.biCompression == BI_BITFIELDS)
|
2009-03-21 19:15:52 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
((PDWORD)Info->bmiColors)[0] = 0x7c00;
|
|
|
|
((PDWORD)Info->bmiColors)[1] = 0x03e0;
|
|
|
|
((PDWORD)Info->bmiColors)[2] = 0x001f;
|
2009-03-21 19:15:52 +00:00
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 16:
|
|
|
|
if (Info->bmiHeader.biCompression == BI_BITFIELDS)
|
2009-03-21 19:15:52 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
((PDWORD)Info->bmiColors)[0] = 0xf800;
|
|
|
|
((PDWORD)Info->bmiColors)[1] = 0x07e0;
|
|
|
|
((PDWORD)Info->bmiColors)[2] = 0x001f;
|
2009-03-21 19:15:52 +00:00
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 24:
|
|
|
|
case 32:
|
|
|
|
if (Info->bmiHeader.biCompression == BI_BITFIELDS)
|
2009-03-21 19:15:52 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
((PDWORD)Info->bmiColors)[0] = 0xff0000;
|
|
|
|
((PDWORD)Info->bmiColors)[1] = 0x00ff00;
|
|
|
|
((PDWORD)Info->bmiColors)[2] = 0x0000ff;
|
2009-03-21 19:15:52 +00:00
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
break;
|
2009-03-21 19:15:52 +00:00
|
|
|
}
|
|
|
|
|
2009-08-04 20:37:10 +00:00
|
|
|
if (!bPaletteMatch)
|
|
|
|
PALETTE_UnlockPalette(ppalDst);
|
2009-03-21 19:15:52 +00:00
|
|
|
|
2008-12-01 00:13:45 +00:00
|
|
|
/* fill out the BITMAPINFO struct */
|
|
|
|
if (!ChkBits)
|
|
|
|
{ // Core or not to Core? We have converted from Core in Gdi~ so?
|
2009-06-10 00:23:15 +00:00
|
|
|
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
|
|
|
{
|
|
|
|
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
|
|
|
|
coreheader->bcWidth = psurf->SurfObj.sizlBitmap.cx;
|
|
|
|
coreheader->bcPlanes = 1;
|
|
|
|
coreheader->bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
|
|
|
|
coreheader->bcHeight = psurf->SurfObj.sizlBitmap.cy;
|
|
|
|
if (psurf->SurfObj.lDelta > 0)
|
|
|
|
coreheader->bcHeight = -coreheader->bcHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
|
|
|
|
{
|
|
|
|
Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
|
|
|
|
Info->bmiHeader.biHeight = psurf->SurfObj.sizlBitmap.cy;
|
|
|
|
Info->bmiHeader.biPlanes = 1;
|
|
|
|
Info->bmiHeader.biBitCount = 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:
|
|
|
|
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 (psurf->SurfObj.lDelta > 0)
|
|
|
|
Info->bmiHeader.biHeight = -Info->bmiHeader.biHeight;
|
|
|
|
}
|
|
|
|
Result = psurf->SurfObj.sizlBitmap.cy;
|
2007-10-01 11:53:31 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
SIZEL DestSize;
|
|
|
|
POINTL SourcePoint;
|
2008-12-01 00:13:45 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// If we have a good dib pointer, why not just copy bits from there w/o XLATE'ing them.
|
|
|
|
//
|
2009-06-10 00:23:15 +00:00
|
|
|
/* 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;
|
|
|
|
|
|
|
|
hDestBitmap = NULL;
|
|
|
|
|
|
|
|
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))
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hDestBitmap == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2009-08-04 20:37:10 +00:00
|
|
|
EXLATEOBJ exlo;
|
2009-06-10 00:23:15 +00:00
|
|
|
SURFOBJ *DestSurfObj;
|
|
|
|
RECTL DestRect;
|
|
|
|
|
2009-08-04 20:37:10 +00:00
|
|
|
EXLATEOBJ_vInitialize(&exlo, ppalSrc, ppalDst, 0, 0, 0);
|
2009-06-10 00:23:15 +00:00
|
|
|
|
|
|
|
SourcePoint.x = 0;
|
|
|
|
SourcePoint.y = psurf->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 (IntEngCopyBits(DestSurfObj,
|
|
|
|
&psurf->SurfObj,
|
|
|
|
NULL,
|
2009-08-04 20:37:10 +00:00
|
|
|
&exlo.xlo,
|
2009-06-10 00:23:15 +00:00
|
|
|
&DestRect,
|
|
|
|
&SourcePoint))
|
|
|
|
{
|
|
|
|
DPRINT("GetDIBits %d \n",abs(Info->bmiHeader.biHeight) - StartScan);
|
|
|
|
Result = ScanLines;
|
|
|
|
}
|
|
|
|
|
2009-08-04 20:37:10 +00:00
|
|
|
EXLATEOBJ_vCleanup(&exlo);
|
2009-06-10 00:23:15 +00:00
|
|
|
EngUnlockSurface(DestSurfObj);
|
|
|
|
}
|
2007-09-18 15:24:34 +00:00
|
|
|
}
|
2007-10-01 11:53:31 +00:00
|
|
|
cleanup:
|
2010-05-08 22:10:41 +00:00
|
|
|
PALETTE_ShareUnlockPalette(ppalSrc);
|
2009-08-04 20:37:10 +00:00
|
|
|
|
2007-10-01 11:53:31 +00:00
|
|
|
if (hDestBitmap != NULL)
|
|
|
|
EngDeleteSurface((HSURF)hDestBitmap);
|
|
|
|
|
|
|
|
if (hDestPalette != NULL && bPaletteMatch == FALSE)
|
2008-03-19 00:56:40 +00:00
|
|
|
PALETTE_FreePaletteByHandle(hDestPalette);
|
2007-10-01 11:53:31 +00:00
|
|
|
|
2009-01-08 16:33:40 +00:00
|
|
|
SURFACE_UnlockSurface(psurf);
|
2003-12-20 14:51:41 +00:00
|
|
|
|
2007-10-01 11:53:31 +00:00
|
|
|
DPRINT("leaving NtGdiGetDIBitsInternal\n");
|
|
|
|
|
2007-09-18 15:24:34 +00:00
|
|
|
return Result;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2008-02-16 18:14:36 +00:00
|
|
|
INT
|
|
|
|
APIENTRY
|
|
|
|
NtGdiStretchDIBitsInternal(
|
|
|
|
HDC hDC,
|
|
|
|
INT XDest,
|
|
|
|
INT YDest,
|
|
|
|
INT DestWidth,
|
|
|
|
INT DestHeight,
|
|
|
|
INT XSrc,
|
|
|
|
INT YSrc,
|
|
|
|
INT SrcWidth,
|
|
|
|
INT SrcHeight,
|
|
|
|
LPBYTE Bits,
|
|
|
|
LPBITMAPINFO BitsInfo,
|
|
|
|
DWORD Usage,
|
|
|
|
DWORD ROP,
|
|
|
|
UINT cjMaxInfo,
|
|
|
|
UINT cjMaxBits,
|
|
|
|
HANDLE hcmXform)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
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,
|
2008-06-07 11:35:53 +00:00
|
|
|
* 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 */
|
2009-06-10 00:23:15 +00:00
|
|
|
IntSetDIBits(pDC, hBitmap, 0, abs(BitsInfo->bmiHeader.biHeight), Bits,
|
|
|
|
BitsInfo, Usage);
|
2008-04-19 00:24:34 +00:00
|
|
|
|
2008-06-07 11:35:53 +00:00
|
|
|
DC_UnlockDc(pDC);
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
2008-04-19 00:24:34 +00:00
|
|
|
|
2003-12-07 10:31:56 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
/* 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);
|
2003-12-07 10:31:56 +00:00
|
|
|
|
2008-06-07 11:35:53 +00:00
|
|
|
/* cleanup */
|
2009-06-10 00:23:15 +00:00
|
|
|
if (hPal)
|
|
|
|
GdiSelectPalette(hdcMem, hPal, FALSE);
|
2007-04-18 00:38:36 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
if (hOldBitmap)
|
|
|
|
NtGdiSelectBitmap(hdcMem, hOldBitmap);
|
2008-06-07 11:35:53 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
NtGdiDeleteObjectApp(hdcMem);
|
2008-06-07 11:35:53 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
GreDeleteObject(hBitmap);
|
2003-12-07 10:31:56 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
return SrcHeight;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-30 22:37:42 +00:00
|
|
|
HBITMAP
|
|
|
|
FASTCALL
|
2009-06-10 00:23:15 +00:00
|
|
|
IntCreateDIBitmap(
|
|
|
|
PDC Dc,
|
|
|
|
INT width,
|
|
|
|
INT height,
|
|
|
|
UINT bpp,
|
|
|
|
DWORD init,
|
|
|
|
LPBYTE bits,
|
|
|
|
PBITMAPINFO data,
|
|
|
|
DWORD coloruse)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
HBITMAP handle;
|
|
|
|
BOOL fColor;
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
// Check if we should create a monochrome or color bitmap. We create a monochrome bitmap only if it has exactly 2
|
|
|
|
// colors, which are black followed by white, nothing else. In all other cases, we create a color bitmap.
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
if (bpp != 1) fColor = TRUE;
|
|
|
|
else if ((coloruse != DIB_RGB_COLORS) || (init != CBM_INIT) || !data) fColor = FALSE;
|
|
|
|
else
|
2001-08-28 18:16:32 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
|
|
|
|
{
|
|
|
|
const RGBQUAD *rgb = data->bmiColors;
|
|
|
|
DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
|
2004-03-15 22:06:55 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
// 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);
|
2004-03-15 22:06:55 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
// 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;
|
|
|
|
}
|
2009-01-28 13:55:37 +00:00
|
|
|
}
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
// Now create the bitmap
|
|
|
|
if (fColor)
|
|
|
|
{
|
|
|
|
handle = IntCreateCompatibleBitmap(Dc, width, height);
|
2001-08-28 18:16:32 +00:00
|
|
|
}
|
2009-01-28 13:55:37 +00:00
|
|
|
else
|
|
|
|
{
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
handle = GreCreateBitmap(width,
|
|
|
|
height,
|
|
|
|
1,
|
|
|
|
1,
|
|
|
|
NULL);
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (height < 0)
|
|
|
|
height = -height;
|
|
|
|
|
|
|
|
if (NULL != handle && CBM_INIT == init)
|
|
|
|
{
|
|
|
|
IntSetDIBits(Dc, handle, 0, height, bits, data, coloruse);
|
|
|
|
}
|
|
|
|
|
|
|
|
return handle;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2004-03-15 22:06:55 +00:00
|
|
|
// The CreateDIBitmap function creates a device-dependent bitmap (DDB) from a DIB and, optionally, sets the bitmap bits
|
|
|
|
// The DDB that is created will be whatever bit depth your reference DC is
|
2008-03-30 22:37:42 +00:00
|
|
|
HBITMAP
|
|
|
|
APIENTRY
|
2009-06-10 00:23:15 +00:00
|
|
|
NtGdiCreateDIBitmapInternal(
|
|
|
|
IN HDC hDc,
|
|
|
|
IN INT cx,
|
|
|
|
IN INT cy,
|
|
|
|
IN DWORD fInit,
|
|
|
|
IN OPTIONAL LPBYTE pjInit,
|
|
|
|
IN OPTIONAL LPBITMAPINFO pbmi,
|
|
|
|
IN DWORD iUsage,
|
|
|
|
IN UINT cjMaxInitInfo,
|
|
|
|
IN UINT cjMaxBits,
|
|
|
|
IN FLONG fl,
|
|
|
|
IN HANDLE hcmXform)
|
2004-03-15 22:06:55 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
PDC Dc;
|
|
|
|
HBITMAP Bmp;
|
|
|
|
UINT bpp;
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2006-09-03 18:16:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
DC_UnlockDc(Dc);
|
2008-03-30 22:37:42 +00:00
|
|
|
NtGdiDeleteObjectApp(hDc);
|
2009-06-10 00:23:15 +00:00
|
|
|
}
|
|
|
|
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;
|
2008-11-18 14:51:14 +00:00
|
|
|
else
|
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
if (Dc->dctype != DC_TYPE_MEMORY)
|
2010-01-30 21:12:42 +00:00
|
|
|
bpp = Dc->ppdev->gdiinfo.cBitsPixel;
|
2009-06-10 00:23:15 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2008-11-18 14:51:14 +00:00
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
|
|
|
|
DC_UnlockDc(Dc);
|
|
|
|
}
|
|
|
|
return Bmp;
|
2004-03-15 22:06:55 +00:00
|
|
|
}
|
|
|
|
|
2008-03-30 22:37:42 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
HBITMAP
|
|
|
|
APIENTRY
|
|
|
|
NtGdiCreateDIBSection(
|
|
|
|
IN HDC hDC,
|
|
|
|
IN OPTIONAL HANDLE hSection,
|
|
|
|
IN DWORD dwOffset,
|
|
|
|
IN LPBITMAPINFO bmi,
|
|
|
|
IN DWORD Usage,
|
|
|
|
IN UINT cjHeader,
|
|
|
|
IN FLONG fl,
|
|
|
|
IN ULONG_PTR dwColorSpace,
|
|
|
|
OUT PVOID *Bits)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
HBITMAP hbitmap = 0;
|
|
|
|
DC *dc;
|
|
|
|
BOOL bDesktopDC = FALSE;
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
if (bDesktopDC)
|
|
|
|
NtGdiDeleteObjectApp(hDC);
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
return hbitmap;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
HBITMAP
|
|
|
|
APIENTRY
|
2003-05-18 17:16:18 +00:00
|
|
|
DIB_CreateDIBSection(
|
2009-06-10 00:23:15 +00:00
|
|
|
PDC dc,
|
|
|
|
BITMAPINFO *bmi,
|
|
|
|
UINT usage,
|
|
|
|
LPVOID *bits,
|
|
|
|
HANDLE section,
|
|
|
|
DWORD offset,
|
|
|
|
DWORD ovr_pitch)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
HBITMAP res = 0;
|
|
|
|
SURFACE *bmp = NULL;
|
|
|
|
void *mapBits = NULL;
|
|
|
|
PDC_ATTR pdcattr;
|
2010-05-12 22:56:24 +00:00
|
|
|
HPALETTE hpal ;
|
2009-06-10 00:23:15 +00:00
|
|
|
|
|
|
|
// 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};
|
2009-12-27 13:02:19 +00:00
|
|
|
ULONG ColorCount;
|
2009-06-10 00:23:15 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-01-09 02:06:39 +00:00
|
|
|
// hSecure = MmSecureVirtualMemory(bm.bmBits, totalSize, PAGE_READWRITE);
|
2009-06-10 00:23:15 +00:00
|
|
|
hSecure = (HANDLE)0x1; // HACK OF UNIMPLEMENTED KERNEL STUFF !!!!
|
2009-01-09 02:06:39 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
if (usage == DIB_PAL_COLORS)
|
2009-12-27 13:02:19 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
lpRGB = DIB_MapPaletteColors(dc, bmi);
|
2009-12-27 15:08:41 +00:00
|
|
|
ColorCount = bi->biClrUsed;
|
|
|
|
if (ColorCount == 0)
|
|
|
|
{
|
|
|
|
ColorCount = 1 << bi->biBitCount;
|
|
|
|
}
|
2009-12-27 13:02:19 +00:00
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
else
|
2009-12-27 13:02:19 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
lpRGB = bmi->bmiColors;
|
2009-12-27 13:02:19 +00:00
|
|
|
ColorCount = 1 << bi->biBitCount;
|
|
|
|
}
|
2001-03-31 15:35:08 +00:00
|
|
|
|
|
|
|
/* Set dsBitfields values */
|
2009-06-10 00:23:15 +00:00
|
|
|
if (usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
dsBitfields[0] = dsBitfields[1] = dsBitfields[2] = 0;
|
2009-01-09 02:06:39 +00:00
|
|
|
}
|
|
|
|
else if (bi->biCompression == BI_RGB)
|
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
switch (bi->biBitCount)
|
2009-01-09 02:06:39 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
case 15:
|
2010-05-09 11:35:36 +00:00
|
|
|
dsBitfields[0] = 0x7c00;
|
|
|
|
dsBitfields[1] = 0x03e0;
|
|
|
|
dsBitfields[2] = 0x001f;
|
|
|
|
break;
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
case 16:
|
2010-05-09 11:35:36 +00:00
|
|
|
dsBitfields[0] = 0xF800;
|
|
|
|
dsBitfields[1] = 0x07e0;
|
|
|
|
dsBitfields[2] = 0x001f;
|
2009-06-10 00:23:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 24:
|
|
|
|
case 32:
|
2010-05-09 11:35:36 +00:00
|
|
|
dsBitfields[0] = 0xff0000;
|
|
|
|
dsBitfields[1] = 0x00ff00;
|
|
|
|
dsBitfields[2] = 0x0000ff;
|
2009-06-10 00:23:15 +00:00
|
|
|
break;
|
2009-01-09 02:06:39 +00:00
|
|
|
}
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
2009-01-09 02:06:39 +00:00
|
|
|
else
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2009-01-09 02:06:39 +00:00
|
|
|
dsBitfields[0] = ((DWORD*)bmi->bmiColors)[0];
|
|
|
|
dsBitfields[1] = ((DWORD*)bmi->bmiColors)[1];
|
|
|
|
dsBitfields[2] = ((DWORD*)bmi->bmiColors)[2];
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2008-10-01 10:05:02 +00:00
|
|
|
// Create Device Dependent Bitmap and add DIB pointer
|
2004-07-03 13:55:37 +00:00
|
|
|
Size.cx = bm.bmWidth;
|
2004-12-30 02:32:19 +00:00
|
|
|
Size.cy = abs(bm.bmHeight);
|
2010-06-07 15:55:03 +00:00
|
|
|
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);
|
2009-06-10 00:23:15 +00:00
|
|
|
if (!res)
|
2008-11-20 15:11:43 +00:00
|
|
|
{
|
2005-07-26 11:22:48 +00:00
|
|
|
if (lpRGB != bmi->bmiColors)
|
2008-11-20 15:11:43 +00:00
|
|
|
{
|
2008-11-04 23:49:07 +00:00
|
|
|
ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
|
2008-11-20 15:11:43 +00:00
|
|
|
}
|
2004-12-27 16:47:02 +00:00
|
|
|
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
|
2009-06-10 00:23:15 +00:00
|
|
|
return NULL;
|
2008-11-20 15:11:43 +00:00
|
|
|
}
|
2009-01-08 16:33:40 +00:00
|
|
|
bmp = SURFACE_LockSurface(res);
|
2003-08-31 07:56:24 +00:00
|
|
|
if (NULL == bmp)
|
2008-11-20 15:11:43 +00:00
|
|
|
{
|
2005-07-26 11:22:48 +00:00
|
|
|
if (lpRGB != bmi->bmiColors)
|
2008-11-20 15:11:43 +00:00
|
|
|
{
|
2008-11-04 23:49:07 +00:00
|
|
|
ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
|
2008-11-20 15:11:43 +00:00
|
|
|
}
|
2009-01-09 02:06:39 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
2010-05-12 22:56:24 +00:00
|
|
|
GreDeleteObject(res);
|
2009-01-09 02:06:39 +00:00
|
|
|
return NULL;
|
2008-11-20 15:11:43 +00:00
|
|
|
}
|
2002-09-24 20:22:10 +00:00
|
|
|
|
2008-11-20 15:11:43 +00:00
|
|
|
/* WINE NOTE: WINE makes use of a colormap, which is a color translation
|
|
|
|
table between the DIB and the X physical device. Obviously,
|
|
|
|
this is left out of the ReactOS implementation. Instead,
|
|
|
|
we call NtGdiSetDIBColorTable. */
|
2009-12-25 17:54:41 +00:00
|
|
|
if (bi->biBitCount <= 8)
|
|
|
|
{
|
|
|
|
bi->biClrUsed = 1 << bi->biBitCount;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bi->biClrUsed = 0;
|
|
|
|
}
|
2002-09-24 20:22:10 +00:00
|
|
|
|
2009-01-28 11:55:56 +00:00
|
|
|
bmp->hDIBSection = section;
|
|
|
|
bmp->hSecure = hSecure;
|
|
|
|
bmp->dwOffset = offset;
|
2010-06-05 21:19:41 +00:00
|
|
|
bmp->flags = API_BITMAP;
|
2009-01-28 11:55:56 +00:00
|
|
|
bmp->dsBitfields[0] = dsBitfields[0];
|
|
|
|
bmp->dsBitfields[1] = dsBitfields[1];
|
|
|
|
bmp->dsBitfields[2] = dsBitfields[2];
|
|
|
|
bmp->biClrUsed = bi->biClrUsed;
|
|
|
|
bmp->biClrImportant = bi->biClrImportant;
|
|
|
|
|
2008-10-06 11:25:38 +00:00
|
|
|
if (bi->biClrUsed != 0)
|
2009-12-27 13:02:19 +00:00
|
|
|
{
|
2010-05-12 22:56:24 +00:00
|
|
|
hpal = PALETTE_AllocPaletteIndexedRGB(ColorCount, lpRGB);
|
2009-12-27 13:02:19 +00:00
|
|
|
}
|
2005-03-11 18:17:29 +00:00
|
|
|
else
|
2009-12-27 13:02:19 +00:00
|
|
|
{
|
2010-05-12 22:56:24 +00:00
|
|
|
hpal = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL,
|
2009-06-10 00:23:15 +00:00
|
|
|
dsBitfields[0],
|
|
|
|
dsBitfields[1],
|
|
|
|
dsBitfields[2]);
|
2009-12-27 13:02:19 +00:00
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
|
2010-05-12 22:56:24 +00:00
|
|
|
bmp->ppal = PALETTE_ShareLockPalette(hpal);
|
|
|
|
/* Lazy delete hpal, it will be freed at surface release */
|
|
|
|
GreDeleteObject(hpal);
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bmp)
|
|
|
|
bmp = NULL;
|
|
|
|
|
|
|
|
if (res)
|
|
|
|
{
|
|
|
|
SURFACE_FreeSurfaceByHandle(res);
|
|
|
|
res = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lpRGB != bmi->bmiColors)
|
|
|
|
{
|
|
|
|
ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bmp)
|
|
|
|
{
|
|
|
|
SURFACE_UnlockSurface(bmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return BITMAP handle and storage location
|
|
|
|
if (NULL != bm.bmBits && NULL != bits)
|
|
|
|
{
|
|
|
|
*bits = bm.bmBits;
|
|
|
|
}
|
2002-09-24 20:22:10 +00:00
|
|
|
|
2009-07-12 02:59:59 +00:00
|
|
|
if (res) pdcattr->ulDirty_ |= DC_DIBSECTION;
|
2008-12-15 05:25:31 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
return res;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* DIB_GetDIBWidthBytes
|
|
|
|
*
|
|
|
|
* Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
|
|
|
|
* http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
|
|
|
|
* 11/16/1999 (RJJ) lifted from wine
|
|
|
|
*/
|
2009-06-10 00:23:15 +00:00
|
|
|
INT FASTCALL DIB_GetDIBWidthBytes(INT width, INT depth)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
return ((width * depth + 31) & ~31) >> 3;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* DIB_GetDIBImageBytes
|
|
|
|
*
|
|
|
|
* Return the number of bytes used to hold the image in a DIB bitmap.
|
|
|
|
* 11/16/1999 (RJJ) lifted from wine
|
|
|
|
*/
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
INT APIENTRY DIB_GetDIBImageBytes(INT width, INT height, INT depth)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
return DIB_GetDIBWidthBytes(width, depth) * (height < 0 ? -height : height);
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* DIB_BitmapInfoSize
|
|
|
|
*
|
|
|
|
* Return the size of the bitmap info structure including color table.
|
|
|
|
* 11/16/1999 (RJJ) lifted from wine
|
|
|
|
*/
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
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));
|
|
|
|
}
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
RGBQUAD *
|
|
|
|
FASTCALL
|
2003-08-11 21:10:49 +00:00
|
|
|
DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
RGBQUAD *lpRGB;
|
|
|
|
ULONG nNumColors,i;
|
|
|
|
USHORT *lpIndex;
|
|
|
|
PPALETTE palGDI;
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
palGDI = PALETTE_LockPalette(dc->dclevel.hpal);
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
if (NULL == palGDI)
|
2003-08-28 12:35:59 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
return NULL;
|
2003-08-28 12:35:59 +00:00
|
|
|
}
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
if (palGDI->Mode != PAL_INDEXED)
|
2005-07-26 11:22:48 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
PALETTE_UnlockPalette(palGDI);
|
|
|
|
return NULL;
|
2005-07-26 11:22:48 +00:00
|
|
|
}
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
|
|
|
|
if (lpbmi->bmiHeader.biClrUsed)
|
2003-08-28 12:35:59 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
|
2003-08-28 12:35:59 +00:00
|
|
|
}
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
lpRGB = (RGBQUAD *)ExAllocatePoolWithTag(PagedPool, sizeof(RGBQUAD) * nNumColors, TAG_COLORMAP);
|
|
|
|
if (lpRGB == NULL)
|
|
|
|
{
|
|
|
|
PALETTE_UnlockPalette(palGDI);
|
|
|
|
return NULL;
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
lpIndex = (USHORT *)&lpbmi->bmiColors[0];
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
for (i = 0; i < nNumColors; i++)
|
2003-08-28 12:35:59 +00:00
|
|
|
{
|
2009-12-27 13:02:19 +00:00
|
|
|
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;
|
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
lpRGB[i].rgbReserved = 0;
|
|
|
|
lpIndex++;
|
2003-08-28 12:35:59 +00:00
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
PALETTE_UnlockPalette(palGDI);
|
2003-08-28 12:35:59 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
return lpRGB;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
HPALETTE
|
|
|
|
FASTCALL
|
|
|
|
BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType)
|
2001-03-31 15:35:08 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
BYTE bits;
|
|
|
|
ULONG ColorCount;
|
|
|
|
PALETTEENTRY *palEntries = NULL;
|
|
|
|
HPALETTE hPal;
|
|
|
|
ULONG RedMask, GreenMask, BlueMask;
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
// Determine Bits Per Pixel
|
|
|
|
bits = bmi->bmiHeader.biBitCount;
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
// Determine paletteType from Bits Per Pixel
|
|
|
|
if (bits <= 8)
|
2003-08-28 12:35:59 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
*paletteType = PAL_INDEXED;
|
|
|
|
RedMask = GreenMask = BlueMask = 0;
|
2003-08-28 12:35:59 +00:00
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
else if (bmi->bmiHeader.biCompression == BI_BITFIELDS)
|
2008-06-26 22:22:57 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
*paletteType = PAL_BITFIELDS;
|
|
|
|
RedMask = ((ULONG *)bmi->bmiColors)[0];
|
|
|
|
GreenMask = ((ULONG *)bmi->bmiColors)[1];
|
|
|
|
BlueMask = ((ULONG *)bmi->bmiColors)[2];
|
2008-06-26 22:22:57 +00:00
|
|
|
}
|
2010-05-09 11:35:36 +00:00
|
|
|
else if (bits == 15)
|
2003-08-28 12:35:59 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
*paletteType = PAL_BITFIELDS;
|
|
|
|
RedMask = 0x7c00;
|
|
|
|
GreenMask = 0x03e0;
|
|
|
|
BlueMask = 0x001f;
|
2003-08-28 12:35:59 +00:00
|
|
|
}
|
2010-05-09 11:35:36 +00:00
|
|
|
else if (bits == 16)
|
|
|
|
{
|
|
|
|
*paletteType = PAL_BITFIELDS;
|
|
|
|
RedMask = 0xF800;
|
|
|
|
GreenMask = 0x07e0;
|
|
|
|
BlueMask = 0x001f;
|
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
else
|
2003-08-28 12:35:59 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
*paletteType = PAL_BGR;
|
|
|
|
RedMask = 0xff0000;
|
|
|
|
GreenMask = 0x00ff00;
|
|
|
|
BlueMask = 0x0000ff;
|
2003-08-28 12:35:59 +00:00
|
|
|
}
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
if (bmi->bmiHeader.biClrUsed == 0)
|
2002-09-03 22:44:21 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
ColorCount = 1 << bmi->bmiHeader.biBitCount;
|
2002-09-03 22:44:21 +00:00
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
else
|
2002-09-03 22:44:21 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
ColorCount = bmi->bmiHeader.biClrUsed;
|
2002-09-03 22:44:21 +00:00
|
|
|
}
|
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
if (PAL_INDEXED == *paletteType)
|
2003-08-31 07:56:24 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)bmi->bmiColors);
|
2003-08-31 07:56:24 +00:00
|
|
|
}
|
2009-06-10 00:23:15 +00:00
|
|
|
else
|
2003-08-31 07:56:24 +00:00
|
|
|
{
|
2009-06-10 00:23:15 +00:00
|
|
|
hPal = PALETTE_AllocPalette(*paletteType, ColorCount,
|
|
|
|
(ULONG*) palEntries,
|
|
|
|
RedMask, GreenMask, BlueMask);
|
2003-08-31 07:56:24 +00:00
|
|
|
}
|
2002-10-05 17:13:16 +00:00
|
|
|
|
2009-06-10 00:23:15 +00:00
|
|
|
return hPal;
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
2003-08-28 12:35:59 +00:00
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
/* EOF */
|