if (psurf == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (psurf->hSecure == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (psurf->ppal == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return 0;
}
if (psurf == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (psurf->hSecure == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (psurf->ppal == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return 0;
}
UINT StartScan,
UINT ScanLines,
CONST VOID *Bits,
- CONST BITMAPV5INFO *bmi,
+ CONST BITMAPINFO *bmi,
UINT ColorUse)
{
- SURFACE *bitmap;
HBITMAP SourceBitmap;
+ PSURFACE psurfDst, psurfSrc;
INT result = 0;
- BOOL copyBitsResult;
- SURFOBJ *DestSurf, *SourceSurf;
- SIZEL SourceSize;
- POINTL ZeroPoint;
- RECTL DestRect;
- EXLATEOBJ exlo;
- PPALETTE ppalDIB;
- //RGBQUAD *lpRGB;
- HPALETTE DIB_Palette;
- ULONG DIB_Palette_Type;
- INT DIBWidth;
-
- // Check parameters
- if (!(bitmap = SURFACE_LockSurface(hBitmap)))
- {
- return 0;
- }
-
- // Get RGB values
- //if (ColorUse == DIB_PAL_COLORS)
- // lpRGB = DIB_MapPaletteColors(hDC, bmi);
- //else
- // lpRGB = &bmi->bmiColors;
-
- DestSurf = &bitmap->SurfObj;
-
- // Create source surface
- SourceSize.cx = bmi->bmiHeader.bV5Width;
- SourceSize.cy = ScanLines;
-
- // Determine width of DIB
- DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.bV5BitCount);
-
- SourceBitmap = EngCreateBitmap(SourceSize,
- DIBWidth,
- BitmapFormat(bmi->bmiHeader.bV5BitCount, bmi->bmiHeader.bV5Compression),
- bmi->bmiHeader.bV5Height < 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;
- }
+ RECT rcDst;
+ POINTL ptSrc;
+ PVOID pvBits;
+ EXLATEOBJ exlo;
- ASSERT(bitmap->ppal);
-
- // Source palette obtained from the BITMAPINFO
- DIB_Palette = BuildDIBPalette((BITMAPINFO*)bmi, (PINT)&DIB_Palette_Type);
- if (NULL == DIB_Palette)
+ SourceBitmap = DIB_CreateDIBSection(DC, bmi, ColorUse, &pvBits, NULL, 0, 0);
+ if (0 == SourceBitmap)
{
- EngUnlockSurface(SourceSurf);
- EngDeleteSurface((HSURF)SourceBitmap);
- SURFACE_UnlockSurface(bitmap);
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ DPRINT1("Error : Could not create a DIBSection.\n");
+ EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
return 0;
}
- ppalDIB = PALETTE_LockPalette(DIB_Palette);
+ RtlCopyMemory(pvBits, Bits, DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
+ bmi->bmiHeader.biHeight,
+ bmi->bmiHeader.biBitCount));
- /* Initialize XLATEOBJ for color translation */
- EXLATEOBJ_vInitialize(&exlo, ppalDIB, bitmap->ppal, 0, 0, 0);
+ psurfDst = SURFACE_LockSurface(hBitmap);
+ psurfSrc = SURFACE_LockSurface(SourceBitmap);
- // Zero point
- ZeroPoint.x = 0;
- ZeroPoint.y = 0;
+ if(!(psurfSrc && psurfDst))
+ {
+ DPRINT1("Error, could not lock surfaces\n");
+ goto cleanup;
+ }
- // Determine destination rectangle
- DestRect.left = 0;
- DestRect.top = abs(bmi->bmiHeader.bV5Height) - StartScan - ScanLines;
- DestRect.right = SourceSize.cx;
- DestRect.bottom = DestRect.top + ScanLines;
+ rcDst.top = bmi->bmiHeader.biHeight < 0 ?
+ abs(bmi->bmiHeader.biHeight) - (ScanLines + StartScan) : StartScan;
+ rcDst.left = 0;
+ rcDst.bottom = rcDst.top + ScanLines;
+ rcDst.right = psurfDst->SurfObj.sizlBitmap.cx;
- copyBitsResult = IntEngCopyBits(DestSurf, SourceSurf, NULL, &exlo.xlo, &DestRect, &ZeroPoint);
+ ptSrc.x = 0;
+ ptSrc.y = 0;
- // If it succeeded, return number of scanlines copies
- if (copyBitsResult == TRUE)
- {
- result = SourceSize.cy;
-// or
-// result = abs(bmi->bmiHeader.biHeight) - StartScan;
- }
+ EXLATEOBJ_vInitialize(&exlo, psurfSrc->ppal, psurfDst->ppal, 0, 0, 0);
- // Clean up
- EXLATEOBJ_vCleanup(&exlo);
- PALETTE_UnlockPalette(ppalDIB);
- PALETTE_FreePaletteByHandle(DIB_Palette);
- EngUnlockSurface(SourceSurf);
- EngDeleteSurface((HSURF)SourceBitmap);
+ result = IntEngCopyBits(&psurfDst->SurfObj,
+ &psurfSrc->SurfObj,
+ NULL,
+ &exlo.xlo,
+ &rcDst,
+ &ptSrc);
+ if(result)
+ result = ScanLines;
-// if (ColorUse == DIB_PAL_COLORS)
-// WinFree((LPSTR)lpRGB);
+ EXLATEOBJ_vCleanup(&exlo);
- SURFACE_UnlockSurface(bitmap);
+cleanup:
+ if(psurfSrc)
+ {
+ SURFACE_UnlockSurface(psurfSrc);
+ }
+ if(psurfDst)
+ {
+ SURFACE_UnlockSurface(psurfDst);
+ }
+ GreDeleteObject(SourceBitmap);
return result;
}
PDC Dc;
INT Ret;
NTSTATUS Status = STATUS_SUCCESS;
- BITMAPV5INFO bmiLocal;
if (!Bits) return 0;
_SEH2_TRY
{
- Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse, 0);
- ProbeForRead(Bits, bmiLocal.bmiHeader.bV5SizeImage, 1);
+ ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1);
+ ProbeForRead(bmi, bmi->bmiHeader.biSize, 1);
+ ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, ColorUse), 1);
+ ProbeForRead(Bits,
+ DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
+ ScanLines,
+ bmi->bmiHeader.biBitCount),
+ 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Dc = DC_LockDc(hDC);
if (NULL == Dc)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return 0;
}
if (Dc->dctype == DC_TYPE_INFO)
return 0;
}
- Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, &bmiLocal, ColorUse);
+ Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
DC_UnlockDc(Dc);
EXLATEOBJ exlo;
PPALETTE ppalDIB = NULL;
HPALETTE hpalDIB = NULL;
- ULONG DIBPaletteType;
- BITMAPV5INFO bmiLocal ;
if (!Bits) return 0;
_SEH2_TRY
{
- Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse, cjMaxInfo);
+ ProbeForRead(bmi, cjMaxInfo, 1);
ProbeForRead(Bits, cjMaxBits, 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
pDC = DC_LockDc(hDC);
if (!pDC)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return 0;
}
if (pDC->dctype == DC_TYPE_INFO)
pDestSurf = pSurf ? &pSurf->SurfObj : NULL;
- ScanLines = min(ScanLines, abs(bmiLocal.bmiHeader.bV5Height) - StartScan);
+ ScanLines = min(ScanLines, abs(bmi->bmiHeader.biHeight) - StartScan);
rcDest.left = XDest;
rcDest.top = YDest;
ptSource.x = XSrc;
ptSource.y = YSrc;
- SourceSize.cx = bmiLocal.bmiHeader.bV5Width;
+ SourceSize.cx = bmi->bmiHeader.biWidth;
SourceSize.cy = ScanLines;
- DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmiLocal.bmiHeader.bV5BitCount);
+ DIBWidth = WIDTH_BYTES_ALIGN32(SourceSize.cx, bmi->bmiHeader.biBitCount);
hSourceBitmap = EngCreateBitmap(SourceSize,
DIBWidth,
- BitmapFormat(bmiLocal.bmiHeader.bV5BitCount,
- bmiLocal.bmiHeader.bV5Compression),
- bmiLocal.bmiHeader.bV5Height < 0 ? BMF_TOPDOWN : 0,
+ BitmapFormat(bmi->bmiHeader.biBitCount,
+ bmi->bmiHeader.biCompression),
+ bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
(PVOID) Bits);
if (!hSourceBitmap)
{
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
Status = STATUS_NO_MEMORY;
goto Exit;
}
ASSERT(pSurf->ppal);
/* Create a palette for the DIB */
- hpalDIB = BuildDIBPalette((PBITMAPINFO)&bmiLocal, (PINT)&DIBPaletteType);
+ hpalDIB = BuildDIBPalette(bmi);
if (!hpalDIB)
{
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
Status = STATUS_NO_MEMORY;
goto Exit;
}
ppalDIB = PALETTE_LockPalette(hpalDIB);
if (!ppalDIB)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
Status = STATUS_UNSUCCESSFUL;
goto Exit;
}
if(bitmap_type == -1)
{
DPRINT("Wrong bitmap format\n");
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
else if(bitmap_type == 0)
/* We need a BITMAPINFO to create a DIB, but we have to fill
* the BITMAPCOREINFO we're provided */
pbmci = (BITMAPCOREINFO*)Info;
- Info = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD), TAG_DIB);
+ Info = DIB_ConvertBitmapInfo((BITMAPINFO*)pbmci, Usage);
if(Info == NULL)
{
- DPRINT1("Error, could not allocate another BITMAPINFO!\n");
+ DPRINT1("Error, could not convert the BITMAPCOREINFO!\n");
return 0;
}
- RtlZeroMemory(Info, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
- Info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- Info->bmiHeader.biBitCount = pbmci->bmciHeader.bcBitCount;
- Info->bmiHeader.biPlanes = pbmci->bmciHeader.bcPlanes;
- Info->bmiHeader.biWidth = pbmci->bmciHeader.bcWidth;
- Info->bmiHeader.biHeight = pbmci->bmciHeader.bcHeight;
rgbQuads = Info->bmiColors;
}
ScanLines = 0;
goto done;
}
- /* Must not be selected */
- if(psurf->hdc != NULL)
- {
- ScanLines = 0;
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- goto done;
- }
-get_info:
/* Fill in the structure */
switch(bpp)
{
if(pbmci)
{
pbmci->bmciHeader.bcWidth = psurf->SurfObj.sizlBitmap.cx;
- pbmci->bmciHeader.bcHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
- -psurf->SurfObj.sizlBitmap.cy :
+ pbmci->bmciHeader.bcHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
+ -psurf->SurfObj.sizlBitmap.cy :
psurf->SurfObj.sizlBitmap.cy;
pbmci->bmciHeader.bcPlanes = 1;
pbmci->bmciHeader.bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
}
Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
- Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
- -psurf->SurfObj.sizlBitmap.cy :
+ Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
+ -psurf->SurfObj.sizlBitmap.cy :
psurf->SurfObj.sizlBitmap.cy;;
Info->bmiHeader.biPlanes = 1;
Info->bmiHeader.biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
Info->bmiHeader.biYPelsPerMeter = 0;
Info->bmiHeader.biClrUsed = 0;
Info->bmiHeader.biClrImportant = 0;
- ScanLines = psurf->SurfObj.sizlBitmap.cy;
- /* Get Complete info now */
- bpp = Info->bmiHeader.biBitCount ;
- goto get_info;
+ ScanLines = abs(Info->bmiHeader.biHeight);
+ goto done;
case 1:
case 4:
case 8:
Info->bmiHeader.biClrUsed = 0;
- /* If the bitmap if a DIB section and has the same format than what
+ /* If the bitmap if a DIB section and has the same format than what
* we're asked, go ahead! */
- if((psurf->hSecure) &&
+ if((psurf->hSecure) &&
(BitsPerFormat(psurf->SurfObj.iBitmapFormat) == bpp))
{
if(Usage == DIB_RGB_COLORS)
{
unsigned int colors = min(psurf->ppal->NumColors, 1 << bpp);
-
+
if(pbmci)
{
for(i=0; i < colors; i++)
}
}
if(colors != 1 << bpp) Info->bmiHeader.biClrUsed = colors;
- RtlCopyMemory(rgbQuads, psurf->ppal->IndexedColors, colors * sizeof(RGBQUAD));
+ for(i=0; i < colors; i++)
+ {
+ rgbQuads[i].rgbRed = psurf->ppal->IndexedColors[i].peRed;
+ rgbQuads[i].rgbGreen = psurf->ppal->IndexedColors[i].peGreen;
+ rgbQuads[i].rgbBlue = psurf->ppal->IndexedColors[i].peBlue;
+ }
}
else
{
rgbTriples[i].rgbtGreen = pDcPal->IndexedColors[i].peGreen;
rgbTriples[i].rgbtBlue = pDcPal->IndexedColors[i].peBlue;
}
-
+
rgbQuads[i].rgbRed = pDcPal->IndexedColors[i].peRed;
rgbQuads[i].rgbGreen = pDcPal->IndexedColors[i].peGreen;
rgbQuads[i].rgbBlue = pDcPal->IndexedColors[i].peBlue;
{
for(g = 0; g <= 5; g++)
{
- for(b = 0; b <= 5; b++)
+ for(b = 0; b <= 5; b++)
{
colorTriple->rgbtRed = (r * 0xff) / 5;
colorTriple->rgbtGreen = (g * 0xff) / 5;
case 16:
if (Info->bmiHeader.biCompression == BI_BITFIELDS)
{
- if (psurf->hSecure) RtlCopyMemory( Info->bmiColors, psurf->dsBitfields, 3 * sizeof(DWORD) );
+ if (psurf->hSecure)
+ {
+ ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
+ ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
+ ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
+ }
else
{
((PDWORD)Info->bmiColors)[0] = 0xf800;
case 32:
if (Info->bmiHeader.biCompression == BI_BITFIELDS)
{
- if (psurf->hSecure) RtlCopyMemory( Info->bmiColors, psurf->dsBitfields, 3 * sizeof(DWORD) );
+ if (psurf->hSecure)
+ {
+ ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
+ ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
+ ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
+ }
else
{
((PDWORD)Info->bmiColors)[0] = 0xff0000;
}
break;
}
+ Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(width, height, bpp);
if(Bits && ScanLines)
{
/* Create a DIBSECTION, blt it, profit */
PVOID pDIBits ;
- HBITMAP hBmpDest, hOldDest = NULL, hOldSrc = NULL;
- HDC hdcDest, hdcSrc;
+ HBITMAP hBmpDest;
+ PSURFACE psurfDest;
+ EXLATEOBJ exlo;
+ RECT rcDest;
+ POINTL srcPoint;
BOOL ret ;
if (StartScan > psurf->SurfObj.sizlBitmap.cy)
ScanLines = min(ScanLines, psurf->SurfObj.sizlBitmap.cy - StartScan);
}
+ /* Fixup values */
+ Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
+ Info->bmiHeader.biHeight = height < 0 ?
+ -ScanLines : ScanLines;
+ /* Create the DIB */
hBmpDest = DIB_CreateDIBSection(pDC, Info, Usage, &pDIBits, NULL, 0, 0);
-
+ /* Restore them */
+ Info->bmiHeader.biWidth = width;
+ Info->bmiHeader.biHeight = height;
+
if(!hBmpDest)
{
DPRINT1("Unable to create a DIB Section!\n");
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
ScanLines = 0;
goto done ;
}
- hdcDest = NtGdiCreateCompatibleDC(0);
- hdcSrc = NtGdiCreateCompatibleDC(0);
+ psurfDest = SURFACE_LockSurface(hBmpDest);
- if(!(hdcSrc && hdcDest))
- {
- DPRINT1("Error: could not create HDCs!\n");
- ScanLines = 0;
- goto cleanup_blt;
- }
+ rcDest.left = 0;
+ rcDest.top = 0;
+ rcDest.bottom = ScanLines;
+ rcDest.right = psurf->SurfObj.sizlBitmap.cx;
- hOldDest = NtGdiSelectBitmap(hdcDest, hBmpDest);
- hOldSrc = NtGdiSelectBitmap(hdcSrc, hBitmap);
+ srcPoint.x = 0;
+ srcPoint.y = height < 0 ?
+ psurf->SurfObj.sizlBitmap.cy - (StartScan + ScanLines) : StartScan;
- if(!(hOldDest && hOldSrc))
- {
- DPRINT1("Error : Could not Select bitmaps\n");
- goto cleanup_blt;
- }
+ EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0, 0, 0);
- ret = GreStretchBltMask(hdcDest,
- 0,
- 0,
- width,
- height,
- hdcSrc,
- 0,
- StartScan,
- psurf->SurfObj.sizlBitmap.cx,
- ScanLines,
- SRCCOPY,
- 0,
- NULL,
- 0,
- 0);
+ ret = IntEngCopyBits(&psurfDest->SurfObj,
+ &psurf->SurfObj,
+ NULL,
+ &exlo.xlo,
+ &rcDest,
+ &srcPoint);
if(!ret)
ScanLines = 0;
Status = STATUS_SUCCESS;
_SEH2_TRY
{
- RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, height, bpp));
- }
+ RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, ScanLines, bpp));
+ }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
}
- cleanup_blt:
- if(hdcSrc)
- {
- if(hOldSrc) NtGdiSelectBitmap(hdcSrc, hOldSrc);
- NtGdiDeleteObjectApp(hdcSrc);
- }
- if(hdcSrc)
- {
- if(hOldDest) NtGdiSelectBitmap(hdcDest, hOldDest);
- NtGdiDeleteObjectApp(hdcDest);
- }
GreDeleteObject(hBmpDest);
+ EXLATEOBJ_vCleanup(&exlo);
}
+ else ScanLines = abs(height);
done:
if(pDC) DC_UnlockDc(pDC);
if(psurf) SURFACE_UnlockSurface(psurf);
- if(pbmci) ExFreePoolWithTag(Info, TAG_DIB);
+ if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci);
return ScanLines;
}
UINT cjMaxBits,
HANDLE hcmXform)
{
- HBITMAP hBitmap, hOldBitmap = NULL;
+ PDC pdc;
+ INT ret = 0;
+ LONG height;
+ LONG width;
+ WORD planes, bpp;
+ DWORD compr, size;
+ HBITMAP hBitmap;
+ HBITMAP hOldBitmap;
HDC hdcMem;
- HPALETTE hPal = NULL;
- PDC pDC;
- NTSTATUS Status;
- BITMAPV5INFO bmiLocal ;
+ PVOID pvBits;
+ PBYTE safeBits;
if (!Bits || !BitsInfo)
+ return 0;
+
+ safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
+ if(!safeBits)
+ {
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return 0;
+ }
+
+ if (!(pdc = DC_LockDc(hDC)))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ ExFreePoolWithTag(safeBits, TAG_DIB);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return 0;
}
_SEH2_TRY
{
- Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, BitsInfo, Usage, cjMaxInfo);
+ ProbeForRead(BitsInfo, cjMaxInfo, 1);
ProbeForRead(Bits, cjMaxBits, 1);
+ if (DIB_GetBitmapInfo(&BitsInfo->bmiHeader, &width, &height, &planes, &bpp, &compr, &size) == -1)
+ {
+ DPRINT1("Invalid bitmap\n");
+ _SEH2_YIELD(goto cleanup;)
+ }
+ RtlCopyMemory(safeBits, Bits, cjMaxBits);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH2_GetExceptionCode();
+ DPRINT1("Error, failed to read the DIB bits\n");
+ _SEH2_YIELD(goto cleanup;)
}
_SEH2_END
- if (!NT_SUCCESS(Status))
- {
- 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(bmiLocal.bmiHeader.bV5Width),
- abs(bmiLocal.bmiHeader.bV5Height));
- if (hBitmap == NULL)
+ if (width < 0)
{
- 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);
+ DPRINT1("Bitmap has a negative width\n");
return 0;
}
- /* Select the bitmap into hdcMem, and save a handle to the old bitmap */
- hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
+ hBitmap = NtGdiGetDCObject(hDC, OBJ_BITMAP);
- if (Usage == DIB_PAL_COLORS)
+ if (XDest == 0 && YDest == 0 && XSrc == 0 && XSrc == 0 &&
+ DestWidth == SrcWidth && DestHeight == SrcHeight &&
+ compr == BI_RGB &&
+ ROP == SRCCOPY)
{
- hPal = NtGdiGetDCObject(hDC, GDI_OBJECT_TYPE_PALETTE);
- hPal = GdiSelectPalette(hdcMem, hPal, FALSE);
+ BITMAP bmp;
+ ret = IntGdiGetObject(hBitmap, sizeof(bmp), &bmp) == sizeof(bmp);
+ if (ret &&
+ bmp.bmBitsPixel == bpp &&
+ bmp.bmWidth == SrcWidth &&
+ bmp.bmHeight == SrcHeight &&
+ bmp.bmPlanes == planes)
+ {
+ /* fast path */
+ ret = IntSetDIBits(pdc, hBitmap, 0, height, safeBits, BitsInfo, Usage);
+ goto cleanup;
+ }
}
- if (bmiLocal.bmiHeader.bV5Compression == BI_RLE4 ||
- bmiLocal.bmiHeader.bV5Compression == BI_RLE8)
- {
- /* copy existing bitmap from destination dc */
- if (SrcWidth == DestWidth && SrcHeight == DestHeight)
- NtGdiBitBlt(hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, hDC, XDest, YDest, ROP, 0, 0);
- else
- NtGdiStretchBlt(hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, hDC, XDest, YDest, DestWidth, DestHeight,
- ROP, 0);
- }
+ /* slow path - need to use StretchBlt */
- pDC = DC_LockDc(hdcMem);
- if (pDC != NULL)
+ hdcMem = NtGdiCreateCompatibleDC(hDC);
+ hBitmap = DIB_CreateDIBSection(pdc, BitsInfo, Usage, &pvBits, NULL, 0, 0);
+ if(!hBitmap)
{
- /* Note BitsInfo->bmiHeader.biHeight is the number of scanline,
- * if it negitve we getting to many scanline for scanline is UINT not
- * a INT, so we need make the negtive value to positve and that make the
- * count correct for negtive bitmap, TODO : we need testcase for this api */
- IntSetDIBits(pDC, hBitmap, 0, abs(bmiLocal.bmiHeader.bV5Height), Bits,
- &bmiLocal, Usage);
-
- DC_UnlockDc(pDC);
+ DPRINT1("Error, failed to create a DIB section\n");
+ NtGdiDeleteObjectApp(hdcMem);
+ goto cleanup;
}
+ RtlCopyMemory(pvBits, safeBits, cjMaxBits);
+ hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
/* 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(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
- ROP, 0, 0);
- else
- NtGdiStretchBlt(hDC, XDest, YDest, DestWidth, DestHeight,
- hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, ROP, 0);
-
- /* cleanup */
- if (hPal)
- GdiSelectPalette(hdcMem, hPal, FALSE);
-
- if (hOldBitmap)
- NtGdiSelectBitmap(hdcMem, hOldBitmap);
+ ret = NtGdiStretchBlt(hDC, XDest, YDest, DestWidth, DestHeight,
+ hdcMem, XSrc, abs(height) - SrcHeight - YSrc,
+ SrcWidth, SrcHeight, ROP, 0);
+ if(ret)
+ ret = SrcHeight;
+ NtGdiSelectBitmap(hdcMem, hOldBitmap);
NtGdiDeleteObjectApp(hdcMem);
-
GreDeleteObject(hBitmap);
- return SrcHeight;
+cleanup:
+ ExFreePoolWithTag(safeBits, TAG_DIB);
+ DC_UnlockDc(pdc);
+ return ret;
}
UINT bpp,
DWORD init,
LPBYTE bits,
- PBITMAPV5INFO data,
+ PBITMAPINFO data,
DWORD coloruse)
{
HBITMAP handle;
else if ((coloruse != DIB_RGB_COLORS) || (init != CBM_INIT) || !data) fColor = FALSE;
else
{
- const RGBQUAD *rgb = data->bmiColors;
+ const RGBQUAD *rgb = (RGBQUAD*)((PBYTE)data + data->bmiHeader.biSize);
DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
// Check if the first color of the colormap is black
IN FLONG fl,
IN HANDLE hcmXform)
{
- BITMAPV5INFO bmiLocal ;
NTSTATUS Status = STATUS_SUCCESS;
+ PBYTE safeBits = NULL;
+ HBITMAP hbmResult = NULL;
+
+ if(pjInit && (fInit == CBM_INIT))
+ {
+ safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
+ if(!safeBits)
+ {
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
+ }
_SEH2_TRY
{
- if(pbmi) Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, pbmi, iUsage, cjMaxInitInfo);
- if(pjInit && (fInit == CBM_INIT)) ProbeForRead(pjInit, cjMaxBits, 1);
+ if(pbmi) ProbeForRead(pbmi, cjMaxInitInfo, 1);
+ if(pjInit && (fInit == CBM_INIT))
+ {
+ ProbeForRead(pjInit, cjMaxBits, 1);
+ RtlCopyMemory(safeBits, pjInit, cjMaxBits);
+ }
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
- return NULL;
+ goto cleanup;
}
- return GreCreateDIBitmapInternal(hDc,
- cx,
- cy,
- fInit,
- pjInit,
- pbmi ? &bmiLocal : NULL,
- iUsage,
- fl,
- hcmXform);
+ hbmResult = GreCreateDIBitmapInternal(hDc,
+ cx,
+ cy,
+ fInit,
+ safeBits,
+ pbmi,
+ iUsage,
+ fl,
+ hcmXform);
+
+cleanup:
+ if (safeBits) ExFreePoolWithTag(safeBits, TAG_DIB);
+ return hbmResult;
}
HBITMAP
IN INT cy,
IN DWORD fInit,
IN OPTIONAL LPBYTE pjInit,
- IN OPTIONAL PBITMAPV5INFO pbmi,
+ IN OPTIONAL PBITMAPINFO pbmi,
IN DWORD iUsage,
IN FLONG fl,
IN HANDLE hcmXform)
if (!hDc) /* 1bpp monochrome bitmap */
{ // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
- hdcDest = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE);
+ hdcDest = NtGdiCreateCompatibleDC(0);
if(!hdcDest)
{
return NULL;
Dc = DC_LockDc(hdcDest);
if (!Dc)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return NULL;
}
/* It's OK to set bpp=0 here, as IntCreateDIBitmap will create a compatible Bitmap
* if bpp != 1 and ignore the real value that was passed */
if (pbmi)
- bpp = pbmi->bmiHeader.bV5BitCount;
+ bpp = pbmi->bmiHeader.biBitCount;
else
bpp = 0;
Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
}
else
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
}
if (bDesktopDC)
SURFACE *bmp = NULL;
void *mapBits = NULL;
HPALETTE hpal ;
- ULONG palMode = PAL_INDEXED;
// Fill BITMAP32 structure with DIB data
CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader;
ULONG totalSize;
BITMAP bm;
SIZEL Size;
- CONST RGBQUAD *lpRGB = NULL;
HANDLE hSecure;
- DWORD dsBitfields[3] = {0};
- ULONG ColorCount;
DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
bm.bmType = 0;
bm.bmWidth = bi->biWidth;
bm.bmHeight = effHeight;
- bm.bmWidthBytes = ovr_pitch ? ovr_pitch : (ULONG) DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
+ bm.bmWidthBytes = ovr_pitch ? ovr_pitch : WIDTH_BYTES_ALIGN32(bm.bmWidth, bi->biBitCount);
bm.bmPlanes = bi->biPlanes;
bm.bmBitsPixel = bi->biBitCount;
// 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
+ totalSize = bi->biSizeImage && bi->biCompression != BI_RGB && bi->biCompression != BI_BITFIELDS
? bi->biSizeImage : (ULONG)(bm.bmWidthBytes * effHeight);
if (section)
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
if (usage == DIB_PAL_COLORS)
{
- lpRGB = DIB_MapPaletteColors(dc, bmi);
- ColorCount = bi->biClrUsed;
- if (ColorCount == 0)
- {
- ColorCount = max(1 << bi->biBitCount, 256);
- }
- }
- else if(bi->biBitCount <= 8)
- {
- lpRGB = bmi->bmiColors;
- ColorCount = 1 << bi->biBitCount;
+ if(dc)
+ {
+ PPALETTE pdcPal ;
+ pdcPal = PALETTE_LockPalette(dc->dclevel.hpal);
+ hpal = DIB_MapPaletteColors(pdcPal, bmi);
+ PALETTE_UnlockPalette(pdcPal);
+ }
+ else
+ {
+ /* For DIB Brushes */
+ DPRINT1("FIXME : Unsupported DIB_PAL_COLORS without a DC to map colors.\n");
+ /* HACK */
+ hpal = (HPALETTE) 0xFFFFFFFF;
+ }
}
- else
+ else
{
- lpRGB = NULL;
- ColorCount = 0;
+ hpal = BuildDIBPalette(bmi);
}
- /* Set dsBitfields values */
- if (usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
- {
- dsBitfields[0] = dsBitfields[1] = dsBitfields[2] = 0;
- palMode = PAL_INDEXED;
- }
- else if (bi->biCompression == BI_RGB)
- {
- dsBitfields[0] = dsBitfields[1] = dsBitfields[2] = 0;
- switch (bi->biBitCount)
- {
- case 15:
- palMode = PAL_RGB16_555;
- break;
-
- case 16:
- palMode = PAL_RGB16_565;
- break;
-
- case 24:
- case 32:
- palMode = PAL_RGB;
- break;
- }
- }
- else
- {
- RtlCopyMemory(dsBitfields, bmi->bmiColors, sizeof(dsBitfields));
- palMode = PAL_BITFIELDS;
- }
+ if(!hpal)
+ {
+ DPRINT1("Error : Could not create a palette for the DIB.\n");
+ goto cleanup;
+ }
// Create Device Dependent Bitmap and add DIB pointer
Size.cx = bm.bmWidth;
BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
(bi->biHeight < 0 ? BMF_TOPDOWN : 0),
bi->biSizeImage,
- bm.bmBits);
+ bm.bmBits,
+ 0);
if (!res)
{
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
goto cleanup;
}
bmp = SURFACE_LockSurface(res);
if (NULL == bmp)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
goto cleanup;
}
bmp->hSecure = hSecure;
bmp->dwOffset = offset;
bmp->flags = API_BITMAP;
- bmp->dsBitfields[0] = dsBitfields[0];
- bmp->dsBitfields[1] = dsBitfields[1];
- bmp->dsBitfields[2] = dsBitfields[2];
- bmp->biClrUsed = ColorCount;
bmp->biClrImportant = bi->biClrImportant;
+ bmp->SurfObj.fjBitmap &= ~BMF_DONT_FREE;
- hpal = PALETTE_AllocPalette(palMode, ColorCount, (ULONG*)lpRGB,
- dsBitfields[0],
- dsBitfields[1],
- dsBitfields[2]);
-
- bmp->ppal = PALETTE_ShareLockPalette(hpal);
- /* Lazy delete hpal, it will be freed at surface release */
- GreDeleteObject(hpal);
+ /* HACK */
+ if(hpal != (HPALETTE)0xFFFFFFFF)
+ {
+ bmp->ppal = PALETTE_ShareLockPalette(hpal);
+ /* Lazy delete hpal, it will be freed at surface release */
+ GreDeleteObject(hpal);
+ }
// Clean up in case of errors
cleanup:
}
}
- if (lpRGB != bmi->bmiColors && lpRGB)
- {
- ExFreePoolWithTag((PVOID)lpRGB, TAG_COLORMAP);
- }
-
if (bmp)
{
SURFACE_UnlockSurface(bmp);
* Get the info from a bitmap header.
* Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error.
*/
-int
+int
FASTCALL
DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size )
*height = core->bcHeight;
*planes = core->bcPlanes;
*bpp = core->bcBitCount;
- *compr = 0;
+ *compr = BI_RGB;
*size = 0;
return 0;
}
return -1;
}
-/***********************************************************************
- * 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
- */
-INT FASTCALL DIB_GetDIBWidthBytes(INT width, INT depth)
-{
- return ((width * depth + 31) & ~31) >> 3;
-}
-
/***********************************************************************
* DIB_GetDIBImageBytes
*
INT APIENTRY DIB_GetDIBImageBytes(INT width, INT height, INT depth)
{
- return DIB_GetDIBWidthBytes(width, depth) * (height < 0 ? -height : height);
+ return WIDTH_BYTES_ALIGN32(width, depth) * (height < 0 ? -height : height);
}
/***********************************************************************
}
}
-RGBQUAD *
+HPALETTE
FASTCALL
-DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi)
+DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi)
{
- RGBQUAD *lpRGB;
+ PALETTEENTRY* ppalEntries;
ULONG nNumColors,i;
USHORT *lpIndex;
- PPALETTE palGDI;
-
- palGDI = PALETTE_LockPalette(dc->dclevel.hpal);
+ HPALETTE hpal;
- if (NULL == palGDI)
+ if (!(ppal->flFlags & PAL_INDEXED))
{
return NULL;
}
- if (palGDI->Mode != PAL_INDEXED)
- {
- PALETTE_UnlockPalette(palGDI);
- return NULL;
- }
-
nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
if (lpbmi->bmiHeader.biClrUsed)
{
nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
}
- lpRGB = (RGBQUAD *)ExAllocatePoolWithTag(PagedPool, sizeof(RGBQUAD) * nNumColors, TAG_COLORMAP);
- if (lpRGB == NULL)
+ /* Don't have more colors than we need */
+ nNumColors = min(ppal->NumColors, nNumColors);
+
+ ppalEntries = ExAllocatePoolWithTag(PagedPool, sizeof(PALETTEENTRY) * nNumColors, TAG_COLORMAP);
+ if (ppalEntries == NULL)
{
- PALETTE_UnlockPalette(palGDI);
+ DPRINT1("Could not allocate palette entries\n");
return NULL;
}
- lpIndex = (USHORT *)&lpbmi->bmiColors[0];
+ lpIndex = (USHORT *)((PBYTE)lpbmi + lpbmi->bmiHeader.biSize);
for (i = 0; i < nNumColors; i++)
{
- if (*lpIndex < palGDI->NumColors)
+ if (*lpIndex < ppal->NumColors)
{
- lpRGB[i].rgbRed = palGDI->IndexedColors[*lpIndex].peRed;
- lpRGB[i].rgbGreen = palGDI->IndexedColors[*lpIndex].peGreen;
- lpRGB[i].rgbBlue = palGDI->IndexedColors[*lpIndex].peBlue;
+ ppalEntries[i] = ppal->IndexedColors[*lpIndex];
}
else
{
- lpRGB[i].rgbRed = 0;
- lpRGB[i].rgbGreen = 0;
- lpRGB[i].rgbBlue = 0;
+ ppalEntries[i].peRed = 0;
+ ppalEntries[i].peGreen = 0;
+ ppalEntries[i].peBlue = 0;
+ ppalEntries[i].peFlags = 0;
}
- lpRGB[i].rgbReserved = 0;
+
lpIndex++;
}
- PALETTE_UnlockPalette(palGDI);
- return lpRGB;
+ hpal = PALETTE_AllocPalette(PAL_INDEXED, nNumColors, (ULONG*)ppalEntries, 0, 0, 0);
+
+ ExFreePoolWithTag(ppalEntries, TAG_COLORMAP);
+
+ return hpal;
}
HPALETTE
FASTCALL
-BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType)
+BuildDIBPalette(CONST BITMAPINFO *bmi)
{
BYTE bits;
ULONG ColorCount;
HPALETTE hPal;
- ULONG RedMask, GreenMask, BlueMask;
+ ULONG RedMask = 0, GreenMask = 0, BlueMask = 0;
PDWORD pdwColors = (PDWORD)((PBYTE)bmi + bmi->bmiHeader.biSize);
+ INT paletteType;
// Determine Bits Per Pixel
bits = bmi->bmiHeader.biBitCount;
// Determine paletteType from Bits Per Pixel
if (bits <= 8)
{
- *paletteType = PAL_INDEXED;
+ paletteType = PAL_INDEXED;
RedMask = GreenMask = BlueMask = 0;
}
else if (bmi->bmiHeader.biCompression == BI_BITFIELDS)
{
- *paletteType = PAL_BITFIELDS;
+ paletteType = PAL_BITFIELDS;
RedMask = pdwColors[0];
GreenMask = pdwColors[1];
BlueMask = pdwColors[2];
}
- else if (bits == 15)
- {
- *paletteType = PAL_BITFIELDS;
- RedMask = 0x7c00;
- GreenMask = 0x03e0;
- BlueMask = 0x001f;
- }
- else if (bits == 16)
- {
- *paletteType = PAL_BITFIELDS;
- RedMask = 0xF800;
- GreenMask = 0x07e0;
- BlueMask = 0x001f;
- }
else
{
- *paletteType = PAL_BGR;
- RedMask = 0xff0000;
- GreenMask = 0x00ff00;
- BlueMask = 0x0000ff;
+ paletteType = PAL_BITFIELDS;
+ switch (bits)
+ {
+ case 15:
+ paletteType |= PAL_RGB16_555;
+ RedMask = 0x7C00;
+ GreenMask = 0x03E0;
+ BlueMask = 0x001F;
+ break;
+
+ case 16:
+ paletteType |= PAL_RGB16_565;
+ RedMask = 0xF800;
+ GreenMask = 0x07E0;
+ BlueMask = 0x001F;
+ break;
+
+ case 24:
+ case 32:
+ paletteType |= PAL_BGR;
+ RedMask = 0xFF0000;
+ GreenMask = 0x00FF00;
+ BlueMask = 0x0000FF;
+ break;
+ }
}
if (bmi->bmiHeader.biClrUsed == 0)
ColorCount = bmi->bmiHeader.biClrUsed;
}
- if (PAL_INDEXED == *paletteType)
+ if (PAL_INDEXED == paletteType)
{
hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)pdwColors);
}
else
{
- hPal = PALETTE_AllocPalette(*paletteType, ColorCount,
+ hPal = PALETTE_AllocPalette(paletteType, 0,
NULL,
RedMask, GreenMask, BlueMask);
}
return hPal;
}
-FORCEINLINE
-DWORD
-GetBMIColor(CONST BITMAPINFO* pbmi, INT i)
-{
- DWORD dwRet = 0;
- INT size;
- if(pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- /* BITMAPCOREINFO holds RGBTRIPLE values */
- size = sizeof(RGBTRIPLE);
- }
- else
- {
- size = sizeof(RGBQUAD);
- }
- memcpy(&dwRet, (PBYTE)pbmi + pbmi->bmiHeader.biSize + i*size, size);
- return dwRet;
-}
-
-NTSTATUS
+/* Converts a BITMAPCOREINFO to a BITMAPINFO structure,
+ * or does nothing if it's already a BITMAPINFO (or V4 or V5) */
+BITMAPINFO*
FASTCALL
-ProbeAndConvertToBitmapV5Info(
- OUT PBITMAPV5INFO pbmiDst,
- IN CONST BITMAPINFO* pbmiUnsafe,
- IN DWORD dwColorUse,
- IN UINT MaxSize)
+DIB_ConvertBitmapInfo (CONST BITMAPINFO* pbmi, DWORD Usage)
{
- DWORD dwSize;
- ULONG ulWidthBytes;
- PBITMAPV5HEADER pbmhDst = &pbmiDst->bmiHeader;
-
- /* Get the size and probe */
- ProbeForRead(&pbmiUnsafe->bmiHeader.biSize, sizeof(DWORD), 1);
- dwSize = pbmiUnsafe->bmiHeader.biSize;
- /* At least dwSize bytes must be valids */
- ProbeForRead(pbmiUnsafe, max(dwSize, MaxSize), 1);
- if(!MaxSize)
- ProbeForRead(pbmiUnsafe, DIB_BitmapInfoSize(pbmiUnsafe, dwColorUse), 1);
-
- /* Check the size */
- // FIXME: are intermediate sizes allowed? As what are they interpreted?
- // make sure we don't use a too big dwSize later
- if (dwSize != sizeof(BITMAPCOREHEADER) &&
- dwSize != sizeof(BITMAPINFOHEADER) &&
- dwSize != sizeof(BITMAPV4HEADER) &&
- dwSize != sizeof(BITMAPV5HEADER))
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- if (dwSize == sizeof(BITMAPCOREHEADER))
- {
- PBITMAPCOREHEADER pbch = (PBITMAPCOREHEADER)pbmiUnsafe;
-
- /* Manually copy the fields that are present */
- pbmhDst->bV5Width = pbch->bcWidth;
- pbmhDst->bV5Height = pbch->bcHeight;
- pbmhDst->bV5Planes = pbch->bcPlanes;
- pbmhDst->bV5BitCount = pbch->bcBitCount;
-
- /* Set some default values */
- pbmhDst->bV5Compression = BI_RGB;
- pbmhDst->bV5SizeImage = DIB_GetDIBImageBytes(pbch->bcWidth,
- pbch->bcHeight,
- pbch->bcPlanes*pbch->bcBitCount) ;
- pbmhDst->bV5XPelsPerMeter = 72;
- pbmhDst->bV5YPelsPerMeter = 72;
- pbmhDst->bV5ClrUsed = 0;
- pbmhDst->bV5ClrImportant = 0;
- }
- else
- {
- /* Copy valid fields */
- memcpy(pbmiDst, pbmiUnsafe, dwSize);
- if(!pbmhDst->bV5SizeImage)
- pbmhDst->bV5SizeImage = DIB_GetDIBImageBytes(pbmhDst->bV5Width,
- pbmhDst->bV5Height,
- pbmhDst->bV5Planes*pbmhDst->bV5BitCount) ;
-
- if(dwSize < sizeof(BITMAPV5HEADER))
- {
- /* Zero out the rest of the V5 header */
- memset((char*)pbmiDst + dwSize, 0, sizeof(BITMAPV5HEADER) - dwSize);
- }
- }
- pbmhDst->bV5Size = sizeof(BITMAPV5HEADER);
+ CONST BITMAPCOREINFO* pbmci = (BITMAPCOREINFO*)pbmi;
+ BITMAPINFO* pNewBmi ;
+ UINT numColors = 0, ColorsSize = 0;
+ if(pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) return (BITMAPINFO*)pbmi;
+ if(pbmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) return NULL;
- if (dwSize < sizeof(BITMAPV4HEADER))
- {
- if (pbmhDst->bV5Compression == BI_BITFIELDS)
- {
- pbmhDst->bV5RedMask = GetBMIColor(pbmiUnsafe, 0);
- pbmhDst->bV5GreenMask = GetBMIColor(pbmiUnsafe, 1);
- pbmhDst->bV5BlueMask = GetBMIColor(pbmiUnsafe, 2);
- pbmhDst->bV5AlphaMask = 0;
- pbmhDst->bV5ClrUsed = 0;
- }
+ if(pbmci->bmciHeader.bcBitCount <= 8)
+ {
+ numColors = 1 << pbmci->bmciHeader.bcBitCount;
+ if(Usage == DIB_PAL_COLORS)
+ {
+ ColorsSize = numColors * sizeof(WORD);
+ }
+ else
+ {
+ ColorsSize = numColors * sizeof(RGBQUAD);
+ }
+ }
+ else if (Usage == DIB_PAL_COLORS)
+ {
+ /* Invalid at high Res */
+ return NULL;
+ }
-// pbmhDst->bV5CSType;
-// pbmhDst->bV5Endpoints;
-// pbmhDst->bV5GammaRed;
-// pbmhDst->bV5GammaGreen;
-// pbmhDst->bV5GammaBlue;
- }
+ pNewBmi = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + ColorsSize, TAG_DIB);
+ if(!pNewBmi) return NULL;
- if (dwSize < sizeof(BITMAPV5HEADER))
- {
-// pbmhDst->bV5Intent;
-// pbmhDst->bV5ProfileData;
-// pbmhDst->bV5ProfileSize;
-// pbmhDst->bV5Reserved;
- }
+ RtlZeroMemory(pNewBmi, sizeof(BITMAPINFOHEADER) + ColorsSize);
- ulWidthBytes = ((pbmhDst->bV5Width * pbmhDst->bV5Planes *
- pbmhDst->bV5BitCount + 31) & ~31) / 8;
+ pNewBmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pNewBmi->bmiHeader.biBitCount = pbmci->bmciHeader.bcBitCount;
+ pNewBmi->bmiHeader.biWidth = pbmci->bmciHeader.bcWidth;
+ pNewBmi->bmiHeader.biHeight = pbmci->bmciHeader.bcHeight;
+ pNewBmi->bmiHeader.biPlanes = pbmci->bmciHeader.bcPlanes;
+ pNewBmi->bmiHeader.biCompression = BI_RGB ;
+ pNewBmi->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(pNewBmi->bmiHeader.biWidth,
+ pNewBmi->bmiHeader.biHeight,
+ pNewBmi->bmiHeader.biBitCount);
- if (pbmhDst->bV5SizeImage == 0)
- pbmhDst->bV5SizeImage = abs(ulWidthBytes * pbmhDst->bV5Height);
+ if(Usage == DIB_PAL_COLORS)
+ {
+ RtlCopyMemory(pNewBmi->bmiColors, pbmci->bmciColors, ColorsSize);
+ }
+ else
+ {
+ UINT i;
+ for(i=0; i<numColors; i++)
+ {
+ pNewBmi->bmiColors[i].rgbRed = pbmci->bmciColors[i].rgbtRed;
+ pNewBmi->bmiColors[i].rgbGreen = pbmci->bmciColors[i].rgbtGreen;
+ pNewBmi->bmiColors[i].rgbBlue = pbmci->bmciColors[i].rgbtBlue;
+ }
+ }
- if (pbmhDst->bV5ClrUsed == 0)
- {
- switch(pbmhDst->bV5BitCount)
- {
- case 1:
- pbmhDst->bV5ClrUsed = 2;
- break;
- case 4:
- pbmhDst->bV5ClrUsed = 16;
- break;
- case 8:
- pbmhDst->bV5ClrUsed = 256;
- break;
- default:
- pbmhDst->bV5ClrUsed = 0;
- break;
- }
- }
+ return pNewBmi ;
+}
- if (pbmhDst->bV5Planes != 1)
- {
- return STATUS_INVALID_PARAMETER;
- }
+/* Frees a BITMAPINFO created with DIB_ConvertBitmapInfo */
+VOID
+FASTCALL
+DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig)
+{
+ if(converted != orig)
+ ExFreePoolWithTag(converted, TAG_DIB);
+}
- if (pbmhDst->bV5BitCount != 0 && pbmhDst->bV5BitCount != 1 &&
- pbmhDst->bV5BitCount != 4 && pbmhDst->bV5BitCount != 8 &&
- pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 24 &&
- pbmhDst->bV5BitCount != 32)
- {
- DPRINT("Invalid bit count: %d\n", pbmhDst->bV5BitCount);
- return STATUS_INVALID_PARAMETER;
- }
- if ((pbmhDst->bV5BitCount == 0 &&
- pbmhDst->bV5Compression != BI_JPEG && pbmhDst->bV5Compression != BI_PNG))
- {
- DPRINT("Bit count 0 is invalid for compression %d.\n", pbmhDst->bV5Compression);
- return STATUS_INVALID_PARAMETER;
- }
- if (pbmhDst->bV5Compression == BI_BITFIELDS &&
- pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 32)
- {
- DPRINT("Bit count %d is invalid for compression BI_BITFIELDS.\n", pbmhDst->bV5BitCount);
- return STATUS_INVALID_PARAMETER;
- }
- /* Copy Colors */
- if(pbmhDst->bV5ClrUsed)
- {
- INT i;
- if(dwColorUse == DIB_PAL_COLORS)
- {
- RtlCopyMemory(pbmiDst->bmiColors,
- pbmiUnsafe->bmiColors,
- pbmhDst->bV5ClrUsed * sizeof(WORD));
- }
- else
- {
- for(i = 0; i < pbmhDst->bV5ClrUsed; i++)
- {
- ((DWORD*)pbmiDst->bmiColors)[i] = GetBMIColor(pbmiUnsafe, i);
- }
- }
- }
- return STATUS_SUCCESS;
-}
/* EOF */