mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 07:53:07 +00:00
- when converting from a DDB to a DIB, the palette should be the same in the resulting DIB as the original DDB. This fixes the colour issue we had in the taskbar icons. (there's still a bit position problem as highlighted in the 1-4 bitmaps)
- Reformat the NtGdiGetDIBitsInternal code to a more readable state. *note, this function needs a considerable work. svn path=/trunk/; revision=29093
This commit is contained in:
parent
90c3978be9
commit
a98103c630
1 changed files with 207 additions and 196 deletions
|
@ -348,225 +348,236 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
||||||
UINT MaxBits,
|
UINT MaxBits,
|
||||||
UINT MaxInfo)
|
UINT MaxInfo)
|
||||||
{
|
{
|
||||||
BITMAPOBJ *BitmapObj;
|
BITMAPOBJ *BitmapObj;
|
||||||
SURFOBJ *DestSurfObj;
|
SURFOBJ *DestSurfObj;
|
||||||
XLATEOBJ *XlateObj;
|
XLATEOBJ *XlateObj;
|
||||||
HBITMAP DestBitmap;
|
HBITMAP DestBitmap;
|
||||||
SIZEL DestSize;
|
SIZEL DestSize;
|
||||||
HPALETTE hSourcePalette;
|
HPALETTE hSourcePalette;
|
||||||
HPALETTE hDestPalette;
|
HPALETTE hDestPalette;
|
||||||
PPALGDI SourcePalette;
|
PPALGDI SourcePalette;
|
||||||
PPALGDI DestPalette;
|
PPALGDI DestPalette;
|
||||||
ULONG SourcePaletteType;
|
ULONG SourcePaletteType;
|
||||||
ULONG DestPaletteType;
|
ULONG DestPaletteType;
|
||||||
PDC Dc;
|
PDC Dc;
|
||||||
POINTL SourcePoint;
|
POINTL SourcePoint;
|
||||||
RECTL DestRect;
|
RECTL DestRect;
|
||||||
ULONG Result = 0;
|
ULONG Result = 0;
|
||||||
ULONG Index;
|
ULONG Index;
|
||||||
|
|
||||||
/* Get handle for the palette in DC. */
|
/* Get handle for the palette in DC. */
|
||||||
Dc = DC_LockDc(hDC);
|
Dc = DC_LockDc(hDC);
|
||||||
if (Dc == NULL)
|
if (Dc == NULL)
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (Dc->IsIC)
|
if (Dc->IsIC)
|
||||||
{
|
{
|
||||||
DC_UnlockDc(Dc);
|
DC_UnlockDc(Dc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
hSourcePalette = Dc->w.hPalette;
|
|
||||||
/* FIXME: This is incorrect. hDestPalette should be something other. */
|
|
||||||
hDestPalette = Dc->DevInfo->hpalDefault;
|
|
||||||
DC_UnlockDc(Dc);
|
|
||||||
|
|
||||||
/* Get pointer to the source bitmap object. */
|
hSourcePalette = Dc->w.hPalette;
|
||||||
BitmapObj = BITMAPOBJ_LockBitmap(hBitmap);
|
hDestPalette = Dc->w.hPalette; // unsure of this (Ged)
|
||||||
if (BitmapObj == NULL)
|
DC_UnlockDc(Dc);
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Bits == NULL)
|
/* Get pointer to the source bitmap object. */
|
||||||
{
|
BitmapObj = BITMAPOBJ_LockBitmap(hBitmap);
|
||||||
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
if (BitmapObj == NULL)
|
||||||
{
|
{
|
||||||
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||||
coreheader->bcWidth =BitmapObj->SurfObj.sizlBitmap.cx;
|
return 0;
|
||||||
coreheader->bcPlanes = 1;
|
}
|
||||||
coreheader->bcBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
|
|
||||||
|
|
||||||
coreheader->bcHeight = BitmapObj->SurfObj.sizlBitmap.cy;
|
if (Bits == NULL)
|
||||||
if (BitmapObj->SurfObj.lDelta > 0)
|
{
|
||||||
coreheader->bcHeight = -coreheader->bcHeight;
|
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||||
|
{
|
||||||
|
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
|
||||||
|
coreheader->bcWidth =BitmapObj->SurfObj.sizlBitmap.cx;
|
||||||
|
coreheader->bcPlanes = 1;
|
||||||
|
coreheader->bcBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
|
||||||
|
|
||||||
Result = BitmapObj->SurfObj.sizlBitmap.cy;
|
coreheader->bcHeight = BitmapObj->SurfObj.sizlBitmap.cy;
|
||||||
}
|
|
||||||
|
if (BitmapObj->SurfObj.lDelta > 0)
|
||||||
|
coreheader->bcHeight = -coreheader->bcHeight;
|
||||||
|
|
||||||
if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
|
|
||||||
{
|
|
||||||
Info->bmiHeader.biWidth = BitmapObj->SurfObj.sizlBitmap.cx;
|
|
||||||
Info->bmiHeader.biHeight = BitmapObj->SurfObj.sizlBitmap.cy;
|
|
||||||
/* Report negtive height for top-down bitmaps. */
|
|
||||||
if (BitmapObj->SurfObj.lDelta > 0)
|
|
||||||
Info->bmiHeader.biHeight = -Info->bmiHeader.biHeight;
|
|
||||||
Info->bmiHeader.biPlanes = 1;
|
|
||||||
Info->bmiHeader.biBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
|
|
||||||
if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
|
|
||||||
{
|
|
||||||
switch (BitmapObj->SurfObj.iBitmapFormat)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
Info->bmiHeader.biSizeImage = BitmapObj->SurfObj.cjBits;
|
|
||||||
Info->bmiHeader.biXPelsPerMeter = 0; /* FIXME */
|
|
||||||
Info->bmiHeader.biYPelsPerMeter = 0; /* FIXME */
|
|
||||||
Info->bmiHeader.biClrUsed =
|
|
||||||
Info->bmiHeader.biClrImportant = 1 << Info->bmiHeader.biBitCount; /* FIXME */
|
|
||||||
Result = BitmapObj->SurfObj.sizlBitmap.cy;
|
Result = BitmapObj->SurfObj.sizlBitmap.cy;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (StartScan > BitmapObj->SurfObj.sizlBitmap.cy)
|
|
||||||
{
|
|
||||||
Result = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ScanLines = min(ScanLines, BitmapObj->SurfObj.sizlBitmap.cy - StartScan);
|
|
||||||
DestSize.cx = BitmapObj->SurfObj.sizlBitmap.cx;
|
|
||||||
DestSize.cy = ScanLines;
|
|
||||||
|
|
||||||
DestBitmap = NULL;
|
if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
|
||||||
if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
|
{
|
||||||
{
|
Info->bmiHeader.biWidth = BitmapObj->SurfObj.sizlBitmap.cx;
|
||||||
DestBitmap = EngCreateBitmap(DestSize,
|
Info->bmiHeader.biHeight = BitmapObj->SurfObj.sizlBitmap.cy;
|
||||||
/* DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount), */
|
/* Report negtive height for top-down bitmaps. */
|
||||||
DestSize.cx * (Info->bmiHeader.biBitCount >> 3), /* HACK */
|
if (BitmapObj->SurfObj.lDelta > 0)
|
||||||
BitmapFormat(Info->bmiHeader.biBitCount, Info->bmiHeader.biCompression),
|
Info->bmiHeader.biHeight = -Info->bmiHeader.biHeight;
|
||||||
0 < Info->bmiHeader.biHeight ? 0 : BMF_TOPDOWN,
|
Info->bmiHeader.biPlanes = 1;
|
||||||
Bits);
|
Info->bmiHeader.biBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
|
||||||
}
|
if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
|
||||||
|
|
||||||
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
|
||||||
{
|
|
||||||
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
|
|
||||||
|
|
||||||
DestBitmap = EngCreateBitmap(DestSize,
|
|
||||||
DIB_GetDIBWidthBytes(DestSize.cx, coreheader->bcBitCount),
|
|
||||||
BitmapFormat(coreheader->bcBitCount, BI_RGB),
|
|
||||||
0 < coreheader->bcHeight ? 0 : BMF_TOPDOWN,
|
|
||||||
Bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(DestBitmap == NULL)
|
|
||||||
{
|
|
||||||
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DestSurfObj = EngLockSurface((HSURF)DestBitmap);
|
|
||||||
|
|
||||||
SourcePalette = PALETTE_LockPalette(hSourcePalette);
|
|
||||||
/* FIXME - SourcePalette can be NULL!!! Don't assert here! */
|
|
||||||
ASSERT(SourcePalette);
|
|
||||||
SourcePaletteType = SourcePalette->Mode;
|
|
||||||
PALETTE_UnlockPalette(SourcePalette);
|
|
||||||
|
|
||||||
DestPalette = PALETTE_LockPalette(hDestPalette);
|
|
||||||
/* FIXME - DestPalette can be NULL!!!! Don't assert here!!! */
|
|
||||||
ASSERT(DestPalette);
|
|
||||||
DestPaletteType = DestPalette->Mode;
|
|
||||||
|
|
||||||
/* Copy palette. */
|
|
||||||
/* FIXME: This is largely incomplete. */
|
|
||||||
if (Info->bmiHeader.biBitCount <= 8)
|
|
||||||
{
|
|
||||||
if (Usage == DIB_RGB_COLORS)
|
|
||||||
{
|
{
|
||||||
for (Index = 0;
|
switch (BitmapObj->SurfObj.iBitmapFormat)
|
||||||
Index < (1 << Info->bmiHeader.biBitCount) &&
|
{
|
||||||
Index < DestPalette->NumColors;
|
case BMF_1BPP:
|
||||||
Index++)
|
case BMF_4BPP:
|
||||||
{
|
case BMF_8BPP:
|
||||||
Info->bmiColors[Index].rgbRed =
|
case BMF_16BPP:
|
||||||
DestPalette->IndexedColors[Index].peRed;
|
case BMF_24BPP:
|
||||||
Info->bmiColors[Index].rgbGreen =
|
case BMF_32BPP:
|
||||||
DestPalette->IndexedColors[Index].peGreen;
|
Info->bmiHeader.biCompression = BI_RGB;
|
||||||
Info->bmiColors[Index].rgbBlue =
|
break;
|
||||||
DestPalette->IndexedColors[Index].peBlue;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info->bmiHeader.biSizeImage = BitmapObj->SurfObj.cjBits;
|
||||||
|
Info->bmiHeader.biXPelsPerMeter = 0; /* FIXME */
|
||||||
|
Info->bmiHeader.biYPelsPerMeter = 0; /* FIXME */
|
||||||
|
Info->bmiHeader.biClrUsed = 0;
|
||||||
|
Info->bmiHeader.biClrImportant = 1 << Info->bmiHeader.biBitCount; /* FIXME */
|
||||||
|
Result = BitmapObj->SurfObj.sizlBitmap.cy;
|
||||||
}
|
}
|
||||||
if (Usage == DIB_PAL_COLORS)
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (StartScan > BitmapObj->SurfObj.sizlBitmap.cy)
|
||||||
|
{
|
||||||
|
Result = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ScanLines = min(ScanLines, BitmapObj->SurfObj.sizlBitmap.cy - StartScan);
|
||||||
|
DestSize.cx = BitmapObj->SurfObj.sizlBitmap.cx;
|
||||||
|
DestSize.cy = ScanLines;
|
||||||
|
|
||||||
|
DestBitmap = NULL;
|
||||||
|
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||||
{
|
{
|
||||||
DPRINT1("GetDIBits with DIB_PAL_COLORS isn't implemented yet.");
|
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
|
||||||
|
|
||||||
|
DestBitmap = EngCreateBitmap(DestSize,
|
||||||
|
DIB_GetDIBWidthBytes(DestSize.cx, coreheader->bcBitCount),
|
||||||
|
BitmapFormat(coreheader->bcBitCount, BI_RGB),
|
||||||
|
0 < coreheader->bcHeight ? 0 : BMF_TOPDOWN,
|
||||||
|
Bits);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
PALETTE_UnlockPalette(DestPalette);
|
if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
|
||||||
|
{
|
||||||
|
INT one, two, three;
|
||||||
|
|
||||||
XlateObj = IntEngCreateXlate(
|
one = DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount),
|
||||||
DestPaletteType, SourcePaletteType, hDestPalette, hSourcePalette);
|
two = ((DestSize.cx * Info->bmiHeader.biBitCount + 31) & ~31) >> 3;
|
||||||
|
three = DestSize.cx * (Info->bmiHeader.biBitCount >> 3);
|
||||||
|
|
||||||
SourcePoint.x = 0;
|
DestBitmap = EngCreateBitmap(DestSize,
|
||||||
SourcePoint.y = BitmapObj->SurfObj.sizlBitmap.cy -
|
/* DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount), */
|
||||||
(StartScan + ScanLines);
|
DestSize.cx * (Info->bmiHeader.biBitCount >> 3), /* HACK */
|
||||||
|
BitmapFormat(Info->bmiHeader.biBitCount, Info->bmiHeader.biCompression),
|
||||||
|
0 < Info->bmiHeader.biHeight ? 0 : BMF_TOPDOWN,
|
||||||
|
Bits);
|
||||||
|
}
|
||||||
|
|
||||||
/* Determine destination rectangle */
|
if(DestBitmap == NULL)
|
||||||
DestRect.top = 0;
|
{
|
||||||
DestRect.left = 0;
|
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
||||||
DestRect.right = DestSize.cx;
|
return 0;
|
||||||
DestRect.bottom = DestSize.cy;
|
}
|
||||||
|
|
||||||
if (EngCopyBits(DestSurfObj, &BitmapObj->SurfObj,
|
DestSurfObj = EngLockSurface((HSURF)DestBitmap);
|
||||||
NULL, XlateObj, &DestRect, &SourcePoint))
|
|
||||||
{
|
|
||||||
Result = ScanLines;
|
|
||||||
}
|
|
||||||
|
|
||||||
EngDeleteXlate(XlateObj);
|
SourcePalette = PALETTE_LockPalette(hSourcePalette);
|
||||||
EngUnlockSurface(DestSurfObj);
|
/* FIXME - SourcePalette can be NULL!!! Don't assert here! */
|
||||||
}
|
ASSERT(SourcePalette);
|
||||||
}
|
SourcePaletteType = SourcePalette->Mode;
|
||||||
|
PALETTE_UnlockPalette(SourcePalette);
|
||||||
|
|
||||||
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
DestPalette = PALETTE_LockPalette(hDestPalette);
|
||||||
|
/* FIXME - DestPalette can be NULL!!!! Don't assert here!!! */
|
||||||
|
//ASSERT(DestPalette);
|
||||||
|
DestPaletteType = DestPalette->Mode;
|
||||||
|
|
||||||
return Result;
|
/* Copy palette. */
|
||||||
|
/* FIXME: This is largely incomplete. */
|
||||||
|
if (Info->bmiHeader.biBitCount <= 8)
|
||||||
|
{
|
||||||
|
if (Usage == DIB_RGB_COLORS)
|
||||||
|
{
|
||||||
|
for (Index = 0;
|
||||||
|
Index < (1 << Info->bmiHeader.biBitCount) && Index < DestPalette->NumColors;
|
||||||
|
Index++)
|
||||||
|
{
|
||||||
|
Info->bmiColors[Index].rgbRed = DestPalette->IndexedColors[Index].peRed;
|
||||||
|
Info->bmiColors[Index].rgbGreen = DestPalette->IndexedColors[Index].peGreen;
|
||||||
|
Info->bmiColors[Index].rgbBlue = DestPalette->IndexedColors[Index].peBlue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Usage == DIB_PAL_COLORS)
|
||||||
|
{
|
||||||
|
DPRINT1("GetDIBits with DIB_PAL_COLORS isn't implemented yet\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PALETTE_UnlockPalette(DestPalette);
|
||||||
|
|
||||||
|
XlateObj = IntEngCreateXlate(DestPaletteType, SourcePaletteType, hDestPalette, hSourcePalette);
|
||||||
|
|
||||||
|
SourcePoint.x = 0;
|
||||||
|
SourcePoint.y = BitmapObj->SurfObj.sizlBitmap.cy - (StartScan + ScanLines);
|
||||||
|
|
||||||
|
/* Determine destination rectangle */
|
||||||
|
DestRect.top = 0;
|
||||||
|
DestRect.left = 0;
|
||||||
|
DestRect.right = DestSize.cx;
|
||||||
|
DestRect.bottom = DestSize.cy;
|
||||||
|
|
||||||
|
if (EngCopyBits(DestSurfObj,
|
||||||
|
&BitmapObj->SurfObj,
|
||||||
|
NULL,
|
||||||
|
XlateObj,
|
||||||
|
&DestRect,
|
||||||
|
&SourcePoint))
|
||||||
|
{
|
||||||
|
Result = ScanLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
EngDeleteXlate(XlateObj);
|
||||||
|
EngUnlockSurface(DestSurfObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
||||||
|
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
INT STDCALL NtGdiStretchDIBits(HDC hDC,
|
INT STDCALL NtGdiStretchDIBits(HDC hDC,
|
||||||
INT XDest,
|
INT XDest,
|
||||||
INT YDest,
|
INT YDest,
|
||||||
INT DestWidth,
|
INT DestWidth,
|
||||||
INT DestHeight,
|
INT DestHeight,
|
||||||
INT XSrc,
|
INT XSrc,
|
||||||
INT YSrc,
|
INT YSrc,
|
||||||
INT SrcWidth,
|
INT SrcWidth,
|
||||||
INT SrcHeight,
|
INT SrcHeight,
|
||||||
CONST VOID *Bits,
|
CONST VOID *Bits,
|
||||||
CONST BITMAPINFO *BitsInfo,
|
CONST BITMAPINFO *BitsInfo,
|
||||||
UINT Usage,
|
UINT Usage,
|
||||||
DWORD ROP)
|
DWORD ROP)
|
||||||
{
|
{
|
||||||
HBITMAP hBitmap, hOldBitmap;
|
HBITMAP hBitmap, hOldBitmap;
|
||||||
HDC hdcMem;
|
HDC hdcMem;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue