- 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:
Ged Murphy 2007-09-18 15:24:34 +00:00
parent 90c3978be9
commit a98103c630

View file

@ -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;