CONST BITMAPINFO *bmi,
UINT ColorUse)
{
- HBITMAP SourceBitmap, hOldSrcBmp = NULL, hOldDstBmp = NULL;
- HDC hdcSrc, hdcDst;
+ HBITMAP SourceBitmap;
+ PSURFACE psurfDst, psurfSrc;
INT result = 0;
+ RECT rcDst;
+ POINTL ptSrc;
PVOID pvBits;
+ EXLATEOBJ exlo;
SourceBitmap = DIB_CreateDIBSection(DC, bmi, ColorUse, &pvBits, NULL, 0, 0);
if (0 == SourceBitmap)
bmi->bmiHeader.biHeight,
bmi->bmiHeader.biBitCount));
- hdcSrc = NtGdiCreateCompatibleDC(0);
- hdcDst = NtGdiCreateCompatibleDC(0);
+ psurfDst = SURFACE_LockSurface(hBitmap);
+ psurfSrc = SURFACE_LockSurface(SourceBitmap);
- if(!(hdcSrc && hdcDst))
+ if(!(psurfSrc && psurfDst))
{
- DPRINT1("Error, could not create memory DCs.\n");
+ DPRINT1("Error, could not lock surfaces\n");
goto cleanup;
}
- hOldSrcBmp = NtGdiSelectBitmap(hdcSrc, SourceBitmap);
- hOldDstBmp = NtGdiSelectBitmap(hdcDst, hBitmap);
+ 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;
- if(!(hOldSrcBmp && hOldDstBmp))
- {
- DPRINT1("Error : Could not select bitmaps into DCs\n");
- goto cleanup;
- }
+ ptSrc.x = 0;
+ ptSrc.y = 0;
- result = NtGdiBitBlt(hdcDst, 0, 0, bmi->bmiHeader.biWidth, ScanLines, hdcSrc, 0, StartScan,
- SRCCOPY, 0, 0);
+ EXLATEOBJ_vInitialize(&exlo, psurfSrc->ppal, psurfDst->ppal, 0, 0, 0);
+ result = IntEngCopyBits(&psurfDst->SurfObj,
+ &psurfSrc->SurfObj,
+ NULL,
+ &exlo.xlo,
+ &rcDst,
+ &ptSrc);
if(result)
result = ScanLines;
+ EXLATEOBJ_vCleanup(&exlo);
+
cleanup:
- if(hdcSrc)
+ if(psurfSrc)
{
- if(hOldSrcBmp) NtGdiSelectBitmap(hdcSrc, hOldSrcBmp);
- NtGdiDeleteObjectApp(hdcSrc);
+ SURFACE_UnlockSurface(psurfSrc);
}
- if(hdcDst)
+ if(psurfDst)
{
- if(hOldDstBmp) NtGdiSelectBitmap(hdcDst, hOldDstBmp);
- NtGdiDeleteObjectApp(hdcDst);
+ SURFACE_UnlockSurface(psurfDst);
}
GreDeleteObject(SourceBitmap);
SourceSize.cx = bmi->bmiHeader.biWidth;
SourceSize.cy = ScanLines;
- DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
+ DIBWidth = WIDTH_BYTES_ALIGN32(SourceSize.cx, bmi->bmiHeader.biBitCount);
hSourceBitmap = EngCreateBitmap(SourceSize,
DIBWidth,
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 */
+ ScanLines = abs(Info->bmiHeader.biHeight);
goto done;
case 1:
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;
{
/* Create a DIBSECTION, blt it, profit */
PVOID pDIBits ;
- HBITMAP hBmpDest, hOldDest = NULL, hOldSrc = NULL;
- HDC hdcDest = NULL, 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");
goto done ;
}
- if(psurf->hdc)
- hdcSrc = psurf->hdc;
- else
- {
- hdcSrc = NtGdiCreateCompatibleDC(0);
- if(!hdcSrc)
- {
- DPRINT1("Error: could not create HDC!\n");
- ScanLines = 0;
- goto cleanup_blt;
- }
- hOldSrc = NtGdiSelectBitmap(hdcSrc, hBitmap);
- if(!hOldSrc)
- {
- DPRINT1("Error : Could not Select bitmap\n");
- ScanLines = 0;
- goto cleanup_blt;
- }
- }
+ psurfDest = SURFACE_LockSurface(hBmpDest);
- hdcDest = NtGdiCreateCompatibleDC(0);
- if(!hdcDest)
- {
- DPRINT1("Error: could not create HDC!\n");
- ScanLines = 0;
- goto cleanup_blt;
- }
- hOldDest = NtGdiSelectBitmap(hdcDest, hBmpDest);
- if(!hOldDest)
- {
- DPRINT1("Error : Could not Select bitmap\n");
- ScanLines = 0;
- goto cleanup_blt;
- }
+ rcDest.left = 0;
+ rcDest.top = 0;
+ rcDest.bottom = ScanLines;
+ rcDest.right = psurf->SurfObj.sizlBitmap.cx;
+
+ srcPoint.x = 0;
+ srcPoint.y = height < 0 ?
+ psurf->SurfObj.sizlBitmap.cy - (StartScan + ScanLines) : StartScan;
- ret = GreStretchBltMask(hdcDest,
- 0,
- 0,
- width,
- height,
- hdcSrc,
- 0,
- StartScan,
- psurf->SurfObj.sizlBitmap.cx,
- ScanLines,
- SRCCOPY,
- 0,
- NULL,
- 0,
- 0);
+ EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0, 0, 0);
+
+ ret = IntEngCopyBits(&psurfDest->SurfObj,
+ &psurf->SurfObj,
+ NULL,
+ &exlo.xlo,
+ &rcDest,
+ &srcPoint);
if(!ret)
ScanLines = 0;
_SEH2_TRY
{
RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, height, bpp));
- }
+ }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
}
- cleanup_blt:
- if(hdcSrc && (hdcSrc != psurf->hdc))
- {
- 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:
UINT cjMaxBits,
HANDLE hcmXform)
{
- HBITMAP hBitmap, hOldBitmap = NULL;
- HDC hdcMem = NULL;
+ PDC pdc;
+ INT ret = 0;
+ LONG height;
+ LONG width;
+ WORD planes, bpp;
+ DWORD compr, size;
+ HBITMAP hBitmap;
+ BOOL fastpath = FALSE;
NTSTATUS Status = STATUS_SUCCESS;
- PVOID pvDIBits;
- INT Ret = 0;
+ PBYTE safeBits ;
if (!Bits || !BitsInfo)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
- }
- /* Create a DIB Section, data will be probed there */
- hBitmap = NtGdiCreateDIBSection(hDC,
- NULL,
- 0,
- BitsInfo,
- Usage,
- 0,
- 0,
- 0,
- &pvDIBits);
-
- if(!hBitmap)
+ safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
+ if(!safeBits)
{
- DPRINT1("Failed to create a DIB.\n");
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
- _SEH2_TRY
- {
- ProbeForRead(Bits, cjMaxBits, 1);
- RtlCopyMemory(pvDIBits, Bits, DIB_GetDIBImageBytes(BitsInfo->bmiHeader.biWidth,
- BitsInfo->bmiHeader.biHeight,
- BitsInfo->bmiHeader.biBitCount));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ if (!(pdc = DC_LockDc(hDC)))
{
- Status = _SEH2_GetExceptionCode();
+ ExFreePoolWithTag(safeBits, TAG_DIB);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
}
- _SEH2_END
- if(!NT_SUCCESS(Status))
- {
- DPRINT1("Error : Could not read DIB bits\n");
- SetLastNtError(Status);
- goto cleanup;
- }
+ _SEH2_TRY
+ {
+ ProbeForRead(BitsInfo, cjMaxInfo, 1);
+ ProbeForRead(Bits, cjMaxBits, 1);
+ if (DIB_GetBitmapInfo( &BitsInfo->bmiHeader, &width, &height, &planes, &bpp, &compr, &size ) == -1)
+ {
+ DPRINT1("Invalid bitmap\n");
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ RtlCopyMemory(safeBits, Bits, cjMaxBits);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
- hdcMem = NtGdiCreateCompatibleDC(0);
- if(!hdcMem)
- {
- DPRINT1("Failed to create a memory DC!");
- goto cleanup;
- }
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("Error, failed to read the DIB bits\n");
+ goto cleanup;
+ }
- hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
- if(!hOldBitmap)
- {
- DPRINT1("Could not select the DIB into the memory DC\n");
- goto cleanup;
- }
+ if (width < 0)
+ {
+ DPRINT1("Bitmap has a negative width\n");
+ return 0;
+ }
- /* Do we want to stretch ? */
- if((SrcWidth == DestWidth) && (SrcHeight == DestHeight))
- {
- Ret = NtGdiBitBlt(hDC, XDest, YDest, XDest + DestWidth, YDest + DestHeight,
- hdcMem, XSrc, YSrc, ROP, 0, 0);
- }
- else
- {
- Ret = NtGdiStretchBlt(hDC, XDest, YDest, XDest + DestWidth, YDest + DestHeight,
- hdcMem, XSrc, YSrc, XSrc + SrcWidth, YSrc + SrcHeight,
- ROP, 0);
- }
+ hBitmap = NtGdiGetDCObject(hDC, OBJ_BITMAP);
- if(Ret)
- Ret = SrcHeight ;
+ if (XDest == 0 && YDest == 0 && XSrc == 0 && XSrc == 0 &&
+ DestWidth == SrcWidth && DestHeight == SrcHeight &&
+ compr == BI_RGB &&
+ ROP == SRCCOPY)
+ {
+ BITMAP bmp;
+ if (IntGdiGetObject(hBitmap, sizeof(bmp), &bmp) == sizeof(bmp))
+ {
+ if (bmp.bmBitsPixel == bpp &&
+ bmp.bmWidth == SrcWidth &&
+ bmp.bmHeight == SrcHeight &&
+ bmp.bmPlanes == planes)
+ fastpath = TRUE;
+ }
+ }
-cleanup:
- if(hdcMem)
- {
- if(hOldBitmap) NtGdiSelectBitmap(hdcMem, hOldBitmap);
- NtGdiDeleteObjectApp(hdcMem);
- }
- GreDeleteObject(hBitmap);
+ if (fastpath)
+ {
+ /* fast path */
+ DPRINT1("using fast path\n");
+ ret = IntSetDIBits( pdc, hBitmap, 0, height, safeBits, BitsInfo, Usage);
+ }
+ else
+ {
+ /* slow path - need to use StretchBlt */
+ HBITMAP hOldBitmap;
+ HDC hdcMem;
+ PVOID pvBits;
- return Ret;
+ hdcMem = NtGdiCreateCompatibleDC( hDC );
+ hBitmap = DIB_CreateDIBSection(pdc, BitsInfo, Usage, &pvBits, NULL, 0, 0);
+ if(!hBitmap)
+ {
+ 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) */
+ 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 );
+ }
+cleanup:
+ ExFreePoolWithTag(safeBits, TAG_DIB);
+ DC_UnlockDc(pdc);
+ return ret;
}
IN HANDLE hcmXform)
{
NTSTATUS Status = STATUS_SUCCESS;
+ PBYTE safeBits = NULL;
+ HBITMAP hbmResult = NULL;
+
+ if(pjInit && (fInit == CBM_INIT))
+ {
+ safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
+ if(!safeBits)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
+ }
_SEH2_TRY
{
if(pbmi) ProbeForRead(pbmi, cjMaxInitInfo, 1);
- if(pjInit && (fInit == CBM_INIT)) ProbeForRead(pjInit, cjMaxBits, 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,
- iUsage,
- fl,
- hcmXform);
+ hbmResult = GreCreateDIBitmapInternal(hDc,
+ cx,
+ cy,
+ fInit,
+ safeBits,
+ pbmi,
+ iUsage,
+ fl,
+ hcmXform);
+
+cleanup:
+ ExFreePoolWithTag(safeBits, TAG_DIB);
+ return hbmResult;
}
HBITMAP
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;
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;
hpal = (HPALETTE) 0xFFFFFFFF;
}
}
- else
+ else
{
hpal = BuildDIBPalette(bmi);
}
* 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);
}
/***********************************************************************
ppalEntries[i].peBlue = 0;
ppalEntries[i].peFlags = 0;
}
-
+
lpIndex++;
}
-
+
hpal = PALETTE_AllocPalette(PAL_INDEXED, nNumColors, (ULONG*)ppalEntries, 0, 0, 0);
ExFreePoolWithTag(ppalEntries, TAG_COLORMAP);