Author: tkreuzer Date: Thu May 10 19:28:53 2012 New Revision: 56561
URL: http://svn.reactos.org/svn/reactos?rev=56561&view=rev Log: [WIN32K] Some work on NtGdiGetDIBitsInternal
Modified: branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.c
Modified: branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.c URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/ntgdi/di... ============================================================================== --- branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.c [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.c [iso-8859-1] Thu May 10 19:28:53 2012 @@ -616,6 +616,8 @@ HANDLE hSecure; HBITMAP hbmp;
+__debugbreak(); + if (fInit & CBM_INIT) { if (pjInit) @@ -663,9 +665,96 @@ return hbmp; }
+ULONG +SURFACE_iCompression( + _In_ PSURFACE psurf) +{ + /* Check what compression the surface has */ + if (psurf->SurfObj.iBitmapFormat == BMF_4RLE) return BI_RLE4; + if (psurf->SurfObj.iBitmapFormat == BMF_8RLE) return BI_RLE8; + if (psurf->SurfObj.iBitmapFormat == BMF_JPEG) return BI_JPEG; + if (psurf->SurfObj.iBitmapFormat == BMF_PNG) return BI_PNG; + + /* Check the type of the palette */ + if (psurf->ppal->flFlags & (PAL_INDEXED|PAL_RGB|PAL_RGB16_555)) + return PAL_RGB; + + /* Everything else must be bitfields */ + ASSERT(psurf->ppal->flFlags & PAL_BITFIELDS); + return BI_BITFIELDS; +} + INT APIENTRY -GreGetDIBitsInternal( +GreGetDIBitmapInfo( + _In_ HBITMAP hbm, + _Inout_ LPBITMAPINFO pbmi, + _In_ UINT iUsage, + _In_ UINT cjMaxInfo) +{ + PSURFACE psurf; + + /* Lock the bitmap */ + psurf = SURFACE_ShareLockSurface(hbm); + if (!psurf) + { + return 0; + } + + /* Fill the bitmap info header */ + pbmi->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx; + if (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) + pbmi->bmiHeader.biHeight = -psurf->SurfObj.sizlBitmap.cy; + else + pbmi->bmiHeader.biHeight = psurf->SurfObj.sizlBitmap.cy; + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biCompression = SURFACE_iCompression(psurf); + pbmi->bmiHeader.biSizeImage = psurf->SurfObj.cjBits; + pbmi->bmiHeader.biXPelsPerMeter = psurf->sizlDim.cx; + pbmi->bmiHeader.biYPelsPerMeter = psurf->sizlDim.cy; + + /* Check if the caller requests a color table */ + if (pbmi->bmiHeader.biBitCount != 0) + { + /* Synthesize a color table */ + __debugbreak(); + } + else + { + /* Just return the bit depth */ + pbmi->bmiHeader.biBitCount = + gajBitsPerFormat[psurf->SurfObj.iBitmapFormat]; + } + + /* Set the number of colors */ + pbmi->bmiHeader.biClrUsed = 1 << pbmi->bmiHeader.biBitCount; + pbmi->bmiHeader.biClrImportant = pbmi->bmiHeader.biClrUsed; + + if (pbmi->bmiHeader.biSize >= sizeof(BITMAPV4HEADER)) + { + PBITMAPV4HEADER pbV4Header = (PBITMAPV4HEADER)pbmi; + + pbV4Header->bV4RedMask = 0; + pbV4Header->bV4GreenMask = 0; + pbV4Header->bV4BlueMask = 0; + pbV4Header->bV4AlphaMask = 0; + pbV4Header->bV4CSType = 0; + //pbV4Header->bV4Endpoints; + pbV4Header->bV4GammaRed = 0; + pbV4Header->bV4GammaGreen = 0; + pbV4Header->bV4GammaBlue = 0; + } + + /* Unlock the bitmap surface */ + SURFACE_ShareUnlockSurface(psurf); + + return 1; +} + + +INT +APIENTRY +GreGetDIBits( _In_ HDC hdc, _In_ HBITMAP hbm, _In_ UINT iStartScan, @@ -676,11 +765,94 @@ _In_ UINT cjMaxBits, _In_ UINT cjMaxInfo) { - - __debugbreak(); - - - return 0; + PDC pdc; + PSURFACE psurf; + ULONG iCompression, cBitsPixel, cjLine; + LONG lDeltaDst; + PBYTE pjSrc; + + /* Lock the DC */ + pdc = DC_LockDc(hdc); + if (!pdc) + { + return 0; + } + + /* Lock the bitmap */ + psurf = SURFACE_ShareLockSurface(hbm); + if (!psurf) + { + + return 0; + } + + /* Check if there is anything to do */ + if (iStartScan < (ULONG)psurf->SurfObj.sizlBitmap.cy) + { + /* Get the bit depth of the bitmap */ + cBitsPixel = gajBitsPerFormat[psurf->SurfObj.iBitmapFormat]; + + /* Get the compression of the bitmap */ + iCompression = SURFACE_iCompression(psurf); + + /* Check if the requested format matches the actual one */ + if ((cBitsPixel == pbmi->bmiHeader.biBitCount) && + (iCompression == pbmi->bmiHeader.biCompression)) + { + /* Calculate width of one dest line */ + lDeltaDst = WIDTH_BYTES_ALIGN32(pbmi->bmiHeader.biWidth, cBitsPixel); + + /* Calculate the maximum number of scan lines to be copied */ + cScans = min(cScans, psurf->SurfObj.sizlBitmap.cy - iStartScan); + cScans = min(cScans, cjMaxBits / lDeltaDst); + + /* Calculate the maximum length of a line */ + cjLine = min(lDeltaDst, abs(psurf->SurfObj.lDelta)); + + /* Check for top-down bitmaps */ + if (pbmi->bmiHeader.biHeight > 0) + { + /* Adjust lDelta and start position */ + lDeltaDst = -lDeltaDst; + pjBits += (cScans - 1) * lDeltaDst; + } + + /* Calculate the start address from where to copy */ + pjSrc = psurf->SurfObj.pvScan0; + pjSrc += iStartScan * psurf->SurfObj.lDelta; + + /* Loop all scan lines */ + while (cScans--) + { + /* Copy one scan line */ + RtlCopyMemory(pjBits, pjSrc, cjLine); + + /* go to the next scan line */ + pjSrc += psurf->SurfObj.lDelta; + pjBits += lDeltaDst; + } + + { + // TODO: create color table + } + } + else + { + __debugbreak(); + } + } + else + { + /* There is nothing to copy */ + cScans = 0; + } + + /* Unlock the bitmap surface */ + SURFACE_ShareUnlockSurface(psurf); + + DC_UnlockDc(pdc); + + return cScans; }
INT @@ -691,13 +863,84 @@ _In_ UINT iStartScan, _In_ UINT cScans, _Out_opt_ LPBYTE pjBits, - _Inout_ LPBITMAPINFO pbmi, + _Inout_ LPBITMAPINFO pbmiUser, _In_ UINT iUsage, _In_ UINT cjMaxBits, _In_ UINT cjMaxInfo) { + PBITMAPINFO pbmi; + HANDLE hSecure; + INT iResult; + //ULONG cjHeader; + __debugbreak(); - return 0; + + /* Check if the size of the bitmap info is large enough */ + if (cjMaxInfo < sizeof(BITMAPINFOHEADER)) + { + return 0; + } + + if (pjBits) + { + hSecure = EngSecureMem(pjBits, cjMaxBits); + if (!hSecure) + { + return 0; + } + } + + pbmi = ExAllocatePoolWithTag(PagedPool, cjMaxInfo, GDITAG_BITMAPINFO); + if (!pbmi) + { + __debugbreak(); + } + + _SEH2_TRY + { + ProbeForWrite(pbmiUser, cjMaxInfo, 1); + RtlCopyMemory(pbmi, pbmiUser, cjMaxInfo); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + __debugbreak(); + } + _SEH2_END; + + // FIXME: check pbmi size + + if (pjBits) + { + /* Call the internal functiomn */ + iResult = GreGetDIBits(hdc, + hbm, + iStartScan, + cScans, + pjBits, + pbmi, + iUsage, + cjMaxBits, + cjMaxInfo); + } + else + { + iResult = GreGetDIBitmapInfo(hbm, pbmi, iUsage, cjMaxInfo); + } + + _SEH2_TRY + { + RtlCopyMemory(pbmiUser, pbmi, cjMaxInfo); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + } + _SEH2_END; + + + ExFreePoolWithTag(pbmi, GDITAG_BITMAPINFO); + + + return iResult; }
INT