[WIN32K]
[reactos.git] / subsystems / win32 / win32k / objects / dibobj.c
index f320f61..f5816da 100644 (file)
@@ -17,7 +17,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -109,14 +109,15 @@ IntSetDIBColorTable(
         if (StartIndex + Entries > (1 << biBitCount))
             Entries = (1 << biBitCount) - StartIndex;
 
-        PalGDI = PALETTE_LockPalette(psurf->hDIBPalette);
-        if (PalGDI == NULL)
+        if (psurf->ppal == NULL)
         {
             DC_UnlockDc(dc);
             SetLastWin32Error(ERROR_INVALID_HANDLE);
             return 0;
         }
 
+        PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
+
         for (Index = StartIndex;
              Index < StartIndex + Entries && Index < PalGDI->NumColors;
              Index++)
@@ -181,14 +182,15 @@ IntGetDIBColorTable(
         if (StartIndex + Entries > (1 << biBitCount))
             Entries = (1 << biBitCount) - StartIndex;
 
-        PalGDI = PALETTE_LockPalette(psurf->hDIBPalette);
-        if (PalGDI == NULL)
+        if (psurf->ppal == NULL)
         {
             DC_UnlockDc(dc);
             SetLastWin32Error(ERROR_INVALID_HANDLE);
             return 0;
         }
 
+        PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
+
         for (Index = StartIndex;
              Index < StartIndex + Entries && Index < PalGDI->NumColors;
              Index++)
@@ -230,7 +232,7 @@ IntSetDIBits(
     EXLATEOBJ   exlo;
     PPALETTE    ppalDDB, ppalDIB;
     //RGBQUAD    *lpRGB;
-    HPALETTE    DDB_Palette, DIB_Palette;
+    HPALETTE    DIB_Palette;
     ULONG       DIB_Palette_Type;
     INT         DIBWidth;
 
@@ -276,18 +278,15 @@ IntSetDIBits(
         return 0;
     }
 
-    // Use hDIBPalette if it exists
-    if (bitmap->hDIBPalette)
+    if (bitmap->ppal)
     {
-        DDB_Palette = bitmap->hDIBPalette;
+        ppalDDB = bitmap->ppal;
+        GDIOBJ_IncrementShareCount(&ppalDDB->BaseObject);
     }
     else
-    {
         // Destination palette obtained from the hDC
-        DDB_Palette = DC->ppdev->devinfo.hpalDefault;
-    }
+        ppalDDB = PALETTE_ShareLockPalette(DC->ppdev->devinfo.hpalDefault);
 
-    ppalDDB = PALETTE_LockPalette(DDB_Palette);
     if (NULL == ppalDDB)
     {
         EngUnlockSurface(SourceSurf);
@@ -304,6 +303,7 @@ IntSetDIBits(
         EngUnlockSurface(SourceSurf);
         EngDeleteSurface((HSURF)SourceBitmap);
         SURFACE_UnlockSurface(bitmap);
+        PALETTE_ShareUnlockPalette(ppalDDB);
         SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
         return 0;
     }
@@ -336,7 +336,7 @@ IntSetDIBits(
     // Clean up
     EXLATEOBJ_vCleanup(&exlo);
     PALETTE_UnlockPalette(ppalDIB);
-    PALETTE_UnlockPalette(ppalDDB);
+    PALETTE_ShareUnlockPalette(ppalDDB);
     PALETTE_FreePaletteByHandle(DIB_Palette);
     EngUnlockSurface(SourceSurf);
     EngDeleteSurface((HSURF)SourceBitmap);
@@ -441,7 +441,7 @@ NtGdiSetDIBitsToDeviceInternal(
     SIZEL SourceSize;
     EXLATEOBJ exlo;
     PPALETTE ppalDDB = NULL, ppalDIB = NULL;
-    HPALETTE hpalDDB, hpalDIB = NULL;
+    HPALETTE hpalDIB = NULL;
     ULONG DIBPaletteType;
 
     if (!Bits) return 0;
@@ -474,15 +474,7 @@ NtGdiSetDIBitsToDeviceInternal(
         return 0;
     }
 
-    /* Use destination palette obtained from the DC by default */
-    hpalDDB = pDC->ppdev->devinfo.hpalDefault;
-
-    /* Try to use hDIBPalette if it exists */
     pSurf = pDC->dclevel.pSurface;
-    if (pSurf && pSurf->hDIBPalette)
-    {
-        hpalDDB = pSurf->hDIBPalette;
-    }
 
     pDestSurf = pSurf ? &pSurf->SurfObj : NULL;
 
@@ -528,7 +520,14 @@ NtGdiSetDIBitsToDeviceInternal(
     }
 
     /* Obtain destination palette */
-    ppalDDB = PALETTE_LockPalette(hpalDDB);
+    if (pSurf && pSurf->ppal)
+    {
+        ppalDDB = pSurf->ppal;
+        GDIOBJ_IncrementShareCount(&ppalDDB->BaseObject);
+    }
+    else
+        ppalDDB = PALETTE_ShareLockPalette(pDC->ppdev->devinfo.hpalDefault);
+
     if (!ppalDDB)
     {
         SetLastWin32Error(ERROR_INVALID_HANDLE);
@@ -547,7 +546,7 @@ NtGdiSetDIBitsToDeviceInternal(
 
     /* Lock the DIB palette */
     ppalDIB = PALETTE_LockPalette(hpalDIB);
-    if (!ppalDDB)
+    if (!ppalDIB)
     {
         SetLastWin32Error(ERROR_INVALID_HANDLE);
         Status = STATUS_UNSUCCESSFUL;
@@ -558,7 +557,7 @@ NtGdiSetDIBitsToDeviceInternal(
     EXLATEOBJ_vInitialize(&exlo, ppalDIB, ppalDDB, 0, 0, 0);
 
     /* Copy the bits */
-    DPRINT("BitsToDev with dstsurf=(%d|%d) (%d|%d), src=(%d|%d) w=%d h=%d\n", 
+    DPRINT("BitsToDev with dstsurf=(%d|%d) (%d|%d), src=(%d|%d) w=%d h=%d\n",
         rcDest.left, rcDest.top, rcDest.right, rcDest.bottom,
         ptSource.x, ptSource.y, SourceSize.cx, SourceSize.cy);
     Status = IntEngBitBlt(pDestSurf,
@@ -583,7 +582,7 @@ Exit:
     }
 
     if (ppalDIB) PALETTE_UnlockPalette(ppalDIB);
-    if (ppalDDB) PALETTE_UnlockPalette(ppalDDB);
+    if (ppalDDB) PALETTE_ShareUnlockPalette(ppalDDB);
 
     if (pSourceSurf) EngUnlockSurface(pSourceSurf);
     if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
@@ -611,7 +610,6 @@ NtGdiGetDIBitsInternal(
     PDC Dc;
     SURFACE *psurf = NULL;
     HBITMAP hDestBitmap = NULL;
-    HPALETTE hSourcePalette = NULL;
     HPALETTE hDestPalette = NULL;
     PPALETTE ppalSrc = NULL;
     PPALETTE ppalDst = NULL;
@@ -636,7 +634,7 @@ NtGdiGetDIBitsInternal(
     _SEH2_TRY
     {
         ProbeForRead(&Info->bmiHeader.biSize, sizeof(DWORD), 1);
-        
+
         ProbeForWrite(Info, Info->bmiHeader.biSize, 1); // Comp for Core.
         if (ChkBits) ProbeForWrite(ChkBits, MaxBits, 1);
     }
@@ -658,18 +656,26 @@ NtGdiGetDIBitsInternal(
         DC_UnlockDc(Dc);
         return 0;
     }
-    DC_UnlockDc(Dc);
 
     /* Get a pointer to the source bitmap object */
     psurf = SURFACE_LockSurface(hBitmap);
     if (psurf == NULL)
+    {
+        DC_UnlockDc(Dc);
         return 0;
+    }
 
-    hSourcePalette = psurf->hDIBPalette;
-    if (!hSourcePalette)
+    if (psurf->ppal)
     {
-        hSourcePalette = pPrimarySurface->devinfo.hpalDefault;
+        ppalSrc = psurf->ppal;
+        GDIOBJ_IncrementShareCount(&ppalSrc->BaseObject);
     }
+    else
+        ppalSrc = PALETTE_ShareLockPalette(Dc->ppdev->devinfo.hpalDefault);
+
+    DC_UnlockDc(Dc);
+
+    ASSERT(ppalSrc != NULL);
 
     ColorPtr = ((PBYTE)Info + Info->bmiHeader.biSize);
     rgbQuads = (RGBQUAD *)ColorPtr;
@@ -680,16 +686,12 @@ NtGdiGetDIBitsInternal(
          Info->bmiHeader.biBitCount != 15 && Info->bmiHeader.biBitCount != 16) ||
          !ChkBits)
     {
-        hDestPalette = hSourcePalette;
+        ppalDst = ppalSrc;
         bPaletteMatch = TRUE;
     }
     else
         hDestPalette = BuildDIBPalette(Info, (PINT)&DestPaletteType); //hDestPalette = Dc->DevInfo->hpalDefault;
 
-    ppalSrc = PALETTE_LockPalette(hSourcePalette);
-    /* FIXME - ppalSrc can be NULL!!! Don't assert here! */
-    ASSERT(ppalSrc);
-
     if (!bPaletteMatch)
     {
         ppalDst = PALETTE_LockPalette(hDestPalette);
@@ -697,10 +699,6 @@ NtGdiGetDIBitsInternal(
         DPRINT("ppalDst : %p\n", ppalDst);
         ASSERT(ppalDst);
     }
-    else
-    {
-        ppalDst = ppalSrc;
-    }
 
     /* Copy palette. */
     /* FIXME: This is largely incomplete. ATM no Core!*/
@@ -970,7 +968,7 @@ NtGdiGetDIBitsInternal(
         }
     }
 cleanup:
-    PALETTE_UnlockPalette(ppalSrc);
+    PALETTE_ShareUnlockPalette(ppalSrc);
 
     if (hDestBitmap != NULL)
         EngDeleteSurface((HSURF)hDestBitmap);
@@ -1180,11 +1178,11 @@ IntCreateDIBitmap(
     }
     else
     {
-        handle = IntGdiCreateBitmap(width,
-                                    height,
-                                    1,
-                                    1,
-                                    NULL);
+        handle = GreCreateBitmap(width,
+                                 height,
+                                 1,
+                                 1,
+                                 NULL);
     }
 
     if (height < 0)
@@ -1348,6 +1346,7 @@ DIB_CreateDIBSection(
     SURFACE *bmp = NULL;
     void *mapBits = NULL;
     PDC_ATTR pdcattr;
+    HPALETTE hpal ;
 
     // Fill BITMAP32 structure with DIB data
     BITMAPINFOHEADER *bi = &bmi->bmiHeader;
@@ -1464,17 +1463,22 @@ DIB_CreateDIBSection(
         switch (bi->biBitCount)
         {
             case 15:
+                dsBitfields[0] = 0x7c00;
+                dsBitfields[1] = 0x03e0;
+                dsBitfields[2] = 0x001f;
+                break;
+
             case 16:
-                dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)lpRGB       : 0x7c00;
-                dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 1) : 0x03e0;
-                dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 2) : 0x001f;
+                dsBitfields[0] = 0xF800;
+                dsBitfields[1] = 0x07e0;
+                dsBitfields[2] = 0x001f;
                 break;
 
             case 24:
             case 32:
-                dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)lpRGB       : 0xff0000;
-                dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 1) : 0x00ff00;
-                dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 2) : 0x0000ff;
+                dsBitfields[0] = 0xff0000;
+                dsBitfields[1] = 0x00ff00;
+                dsBitfields[2] = 0x0000ff;
                 break;
         }
     }
@@ -1488,12 +1492,14 @@ DIB_CreateDIBSection(
     // Create Device Dependent Bitmap and add DIB pointer
     Size.cx = bm.bmWidth;
     Size.cy = abs(bm.bmHeight);
-    res = IntCreateBitmap(Size,
-                          bm.bmWidthBytes,
-                          BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
-                          BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
-                          (bi->biHeight < 0 ? BMF_TOPDOWN : 0),
-                          bm.bmBits);
+    res = GreCreateBitmapEx(bm.bmWidth,
+                            abs(bm.bmHeight),
+                            bm.bmWidthBytes,
+                            BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
+                            BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
+                              (bi->biHeight < 0 ? BMF_TOPDOWN : 0),
+                            bi->biSizeImage,
+                            bm.bmBits);
     if (!res)
     {
         if (lpRGB != bmi->bmiColors)
@@ -1511,7 +1517,7 @@ DIB_CreateDIBSection(
             ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
         }
         SetLastWin32Error(ERROR_INVALID_HANDLE);
-        GreDeleteObject(bmp);
+        GreDeleteObject(res);
         return NULL;
     }
 
@@ -1531,7 +1537,7 @@ DIB_CreateDIBSection(
     bmp->hDIBSection = section;
     bmp->hSecure = hSecure;
     bmp->dwOffset = offset;
-    bmp->flFlags = BITMAPOBJ_IS_APIBITMAP;
+    bmp->flags = API_BITMAP;
     bmp->dsBitfields[0] = dsBitfields[0];
     bmp->dsBitfields[1] = dsBitfields[1];
     bmp->dsBitfields[2] = dsBitfields[2];
@@ -1540,16 +1546,20 @@ DIB_CreateDIBSection(
 
     if (bi->biClrUsed != 0)
     {
-        bmp->hDIBPalette = PALETTE_AllocPaletteIndexedRGB(ColorCount, lpRGB);
+        hpal = PALETTE_AllocPaletteIndexedRGB(ColorCount, lpRGB);
     }
     else
     {
-        bmp->hDIBPalette = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL,
+        hpal = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL,
                                                 dsBitfields[0],
                                                 dsBitfields[1],
                                                 dsBitfields[2]);
     }
 
+    bmp->ppal = PALETTE_ShareLockPalette(hpal);
+    /* Lazy delete hpal, it will be freed at surface release */
+    GreDeleteObject(hpal);
+
     // Clean up in case of errors
     if (!res || !bmp || !bm.bmBits)
     {
@@ -1732,13 +1742,20 @@ BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType)
         GreenMask = ((ULONG *)bmi->bmiColors)[1];
         BlueMask = ((ULONG *)bmi->bmiColors)[2];
     }
-    else if (bits < 24)
+    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;