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/dibitmap.c?rev=56561&r1=56560&r2=56561&view=diff
==============================================================================
--- 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


Reply via email to