[WIN32K]
[reactos.git] / subsystems / win32 / win32k / objects / dibobj.c
index 49b0129..e4caf1d 100644 (file)
@@ -262,115 +262,70 @@ IntSetDIBits(
     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;
-    }
+       RECT            rcDst;
+       POINTL          ptSrc;
+       PVOID           pvBits;
+       EXLATEOBJ       exlo;
 
-    // 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)
+    SourceBitmap = DIB_CreateDIBSection(DC, bmi, ColorUse, &pvBits, NULL, 0, 0);
+       if (0 == SourceBitmap)
     {
-        SURFACE_UnlockSurface(bitmap);
+               DPRINT1("Error : Could not create a DIBSection.\n");
         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;
-    }
+       RtlCopyMemory(pvBits, Bits, DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
+                                                                                                        bmi->bmiHeader.biHeight,
+                                                                                                        bmi->bmiHeader.biBitCount));
 
-    ASSERT(bitmap->ppal);
+       psurfDst = SURFACE_LockSurface(hBitmap);
+       psurfSrc = SURFACE_LockSurface(SourceBitmap);
 
-    // Source palette obtained from the BITMAPINFO
-    DIB_Palette = BuildDIBPalette((BITMAPINFO*)bmi, (PINT)&DIB_Palette_Type);
-    if (NULL == DIB_Palette)
-    {
-        EngUnlockSurface(SourceSurf);
-        EngDeleteSurface((HSURF)SourceBitmap);
-        SURFACE_UnlockSurface(bitmap);
-        SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
-        return 0;
-    }
-
-    ppalDIB = PALETTE_LockPalette(DIB_Palette);
-
-    /* Initialize XLATEOBJ for color translation */
-    EXLATEOBJ_vInitialize(&exlo, ppalDIB, bitmap->ppal, 0, 0, 0);
-
-    // 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;
 }
@@ -392,14 +347,19 @@ NtGdiSetDIBits(
     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)
     {
@@ -424,7 +384,7 @@ NtGdiSetDIBits(
         return 0;
     }
 
-    Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, &bmiLocal, ColorUse);
+    Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
 
     DC_UnlockDc(Dc);
 
@@ -465,14 +425,12 @@ NtGdiSetDIBitsToDeviceInternal(
     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)
@@ -502,7 +460,7 @@ NtGdiSetDIBitsToDeviceInternal(
 
     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;
@@ -519,16 +477,16 @@ NtGdiSetDIBitsToDeviceInternal(
     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)
     {
@@ -547,7 +505,7 @@ NtGdiSetDIBitsToDeviceInternal(
     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);
@@ -697,13 +655,6 @@ NtGdiGetDIBitsInternal(
         ScanLines = 0;
         goto done;
     }
-       /* Must not be selected */
-       if(psurf->hdc != NULL)
-       {
-               ScanLines = 0;
-               SetLastWin32Error(ERROR_INVALID_PARAMETER);
-               goto done;
-       }
 
        /* Fill in the structure */
        switch(bpp)
@@ -712,15 +663,15 @@ NtGdiGetDIBitsInternal(
                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);
@@ -752,8 +703,7 @@ NtGdiGetDIBitsInternal(
         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:
@@ -761,15 +711,15 @@ NtGdiGetDIBitsInternal(
        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++)
@@ -780,7 +730,12 @@ NtGdiGetDIBitsInternal(
                                        }
                                }
                                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
                        {
@@ -818,7 +773,7 @@ NtGdiGetDIBitsInternal(
                         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;
@@ -867,7 +822,7 @@ NtGdiGetDIBitsInternal(
                                                        {
                                 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;
@@ -948,13 +903,17 @@ NtGdiGetDIBitsInternal(
         }
         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)
@@ -967,8 +926,16 @@ NtGdiGetDIBitsInternal(
             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");
@@ -977,40 +944,25 @@ NtGdiGetDIBitsInternal(
                        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;
@@ -1020,7 +972,7 @@ NtGdiGetDIBitsInternal(
                        _SEH2_TRY
                        {
                                RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, height, bpp));
-                       } 
+                       }
                        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
                        {
                                Status = _SEH2_GetExceptionCode();
@@ -1034,19 +986,10 @@ NtGdiGetDIBitsInternal(
                        }
                }
 
-       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:
 
@@ -1078,23 +1021,44 @@ NtGdiStretchDIBitsInternal(
     UINT cjMaxBits,
     HANDLE hcmXform)
 {
-    HBITMAP hBitmap, hOldBitmap = NULL;
-    HDC hdcMem;
-    HPALETTE hPal = NULL;
-    PDC pDC;
-    NTSTATUS Status;
-    BITMAPV5INFO bmiLocal ;
+    PDC pdc;
+    INT ret = 0;
+    LONG height;
+    LONG width;
+    WORD planes, bpp;
+    DWORD compr, size;
+    HBITMAP hBitmap;
+    BOOL fastpath = FALSE;
+    NTSTATUS Status = STATUS_SUCCESS;
+       PBYTE safeBits ;
 
     if (!Bits || !BitsInfo)
-    {
-        SetLastWin32Error(ERROR_INVALID_PARAMETER);
         return 0;
-    }
+
+       safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
+       if(!safeBits)
+       {
+               SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+               return 0;
+       }
+
+    if (!(pdc = DC_LockDc(hDC)))
+       {
+               ExFreePoolWithTag(safeBits, TAG_DIB);
+               SetLastWin32Error(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");
+            Status = STATUS_INVALID_PARAMETER;
+        }
+               RtlCopyMemory(safeBits, Bits, cjMaxBits);
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -1102,90 +1066,76 @@ NtGdiStretchDIBitsInternal(
     }
     _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)
+    if(!NT_SUCCESS(Status))
     {
-        DPRINT1("NtGdiCreateCompatibleDC fail create hdc\n");
-        return 0;
+        DPRINT1("Error, failed to read the DIB bits\n");
+        goto cleanup;
     }
 
-    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;
+        if (IntGdiGetObject(hBitmap, sizeof(bmp), &bmp) == sizeof(bmp))
+        {
+            if (bmp.bmBitsPixel == bpp &&
+                bmp.bmWidth == SrcWidth &&
+                bmp.bmHeight == SrcHeight &&
+                bmp.bmPlanes == planes)
+                fastpath = TRUE;
+        }
     }
 
-    if (bmiLocal.bmiHeader.bV5Compression == BI_RLE4 ||
-            bmiLocal.bmiHeader.bV5Compression == BI_RLE8)
+    if (fastpath)
     {
-        /* 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);
+        /* fast path */
+        DPRINT1("using fast path\n");
+        ret = IntSetDIBits( pdc, hBitmap, 0, height, safeBits, BitsInfo, Usage);
     }
-
-    pDC = DC_LockDc(hdcMem);
-    if (pDC != NULL)
+    else
     {
-        /* 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);
+        /* slow path - need to use StretchBlt */
+        HBITMAP hOldBitmap;
+        HDC hdcMem;
+        PVOID pvBits;
 
-        DC_UnlockDc(pDC);
+        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 );
     }
-
-
-    /* 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);
-
-    NtGdiDeleteObjectApp(hdcMem);
-
-    GreDeleteObject(hBitmap);
-
-    return SrcHeight;
+cleanup:
+       ExFreePoolWithTag(safeBits, TAG_DIB);
+    DC_UnlockDc(pdc);
+    return ret;
 }
 
 
@@ -1198,7 +1148,7 @@ IntCreateDIBitmap(
     UINT bpp,
     DWORD init,
     LPBYTE bits,
-    PBITMAPV5INFO data,
+    PBITMAPINFO data,
     DWORD coloruse)
 {
     HBITMAP handle;
@@ -1211,7 +1161,7 @@ IntCreateDIBitmap(
     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
@@ -1268,13 +1218,28 @@ NtGdiCreateDIBitmapInternal(
     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)
+               {
+                       SetLastWin32Error(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)
     {
@@ -1285,18 +1250,22 @@ NtGdiCreateDIBitmapInternal(
     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:
+       ExFreePoolWithTag(safeBits, TAG_DIB);
+       return hbmResult;
 }
 
 HBITMAP
@@ -1307,7 +1276,7 @@ GreCreateDIBitmapInternal(
     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)
@@ -1319,7 +1288,7 @@ GreCreateDIBitmapInternal(
 
     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;
@@ -1339,7 +1308,7 @@ GreCreateDIBitmapInternal(
     /* 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);
@@ -1435,7 +1404,6 @@ DIB_CreateDIBSection(
     SURFACE *bmp = NULL;
     void *mapBits = NULL;
     HPALETTE hpal ;
-       INT palMode = PAL_INDEXED;
 
     // Fill BITMAP32 structure with DIB data
     CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader;
@@ -1459,7 +1427,7 @@ DIB_CreateDIBSection(
     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;
@@ -1525,26 +1493,30 @@ DIB_CreateDIBSection(
 
     if (usage == DIB_PAL_COLORS)
     {
-               PPALETTE pdcPal ;
-        pdcPal = PALETTE_LockPalette(dc->dclevel.hpal);
-               if(!pdcPal)
+               if(dc)
                {
-                       DPRINT1("Unable to lock DC palette?!\n");
-                       goto cleanup;
+                       PPALETTE pdcPal ;
+                       pdcPal = PALETTE_LockPalette(dc->dclevel.hpal);
+                       hpal = DIB_MapPaletteColors(pdcPal, bmi);
+                       PALETTE_UnlockPalette(pdcPal);
                }
-               if(pdcPal->Mode != PAL_INDEXED)
+               else
                {
-                       DPRINT1("Not indexed palette selected in the DC?!\n");
-                       PALETTE_UnlockPalette(pdcPal);
+                       /* For DIB Brushes */
+                       DPRINT1("FIXME : Unsupported DIB_PAL_COLORS without a DC to map colors.\n");
+                       /* HACK */
+                       hpal = (HPALETTE) 0xFFFFFFFF;
                }
-               hpal = PALETTE_AllocPalette(PAL_INDEXED,
-                       pdcPal->NumColors,
-                       (ULONG*)pdcPal->IndexedColors, 0, 0, 0);
-               PALETTE_UnlockPalette(pdcPal);
     }
-    else 
+    else
+       {
+        hpal = BuildDIBPalette(bmi);
+       }
+
+       if(!hpal)
        {
-        hpal = BuildDIBPalette(bmi, &palMode);
+               DPRINT1("Error : Could not create a palette for the DIB.\n");
+               goto cleanup;
        }
 
     // Create Device Dependent Bitmap and add DIB pointer
@@ -1557,7 +1529,8 @@ DIB_CreateDIBSection(
                             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);
@@ -1580,9 +1553,13 @@ DIB_CreateDIBSection(
     bmp->flags = API_BITMAP;
     bmp->biClrImportant = bi->biClrImportant;
 
-       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:
@@ -1632,7 +1609,7 @@ cleanup:
  * 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 )
@@ -1644,7 +1621,7 @@ DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
         *height = core->bcHeight;
         *planes = core->bcPlanes;
         *bpp    = core->bcBitCount;
-        *compr  = 0;
+        *compr  = BI_RGB;
         *size   = 0;
         return 0;
     }
@@ -1662,18 +1639,6 @@ DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
     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
  *
@@ -1683,7 +1648,7 @@ INT FASTCALL DIB_GetDIBWidthBytes(INT width, INT depth)
 
 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);
 }
 
 /***********************************************************************
@@ -1716,25 +1681,17 @@ INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse)
     }
 }
 
-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);
-
-    if (NULL == palGDI)
-    {
-        return NULL;
-    }
+       HPALETTE hpal;
 
-    if (palGDI->Mode != PAL_INDEXED)
+    if (ppal->Mode != PAL_INDEXED)
     {
-        PALETTE_UnlockPalette(palGDI);
         return NULL;
     }
 
@@ -1744,46 +1701,52 @@ DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi)
         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;
@@ -1791,36 +1754,27 @@ BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType)
     // 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;
+        paletteType = PAL_RGB16_555;
     }
     else if (bits == 16)
     {
-        *paletteType = PAL_BITFIELDS;
-        RedMask = 0xF800;
-        GreenMask = 0x07e0;
-        BlueMask = 0x001f;
+        paletteType = PAL_RGB16_565;
     }
     else
     {
-        *paletteType = PAL_RGB;
-        RedMask = 0xff0000;
-        GreenMask = 0x00ff00;
-        BlueMask = 0x0000ff;
+               paletteType = PAL_BGR;
     }
 
     if (bmi->bmiHeader.biClrUsed == 0)
@@ -1832,13 +1786,13 @@ BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType)
         ColorCount = bmi->bmiHeader.biClrUsed;
     }
 
-    if (PAL_INDEXED == *paletteType)
+    if (PAL_INDEXED == paletteType)
     {
         hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)pdwColors);
     }
     else
     {
-        hPal = PALETTE_AllocPalette(*paletteType, 0,
+        hPal = PALETTE_AllocPalette(paletteType, 0,
                                     NULL,
                                     RedMask, GreenMask, BlueMask);
     }
@@ -1846,195 +1800,6 @@ BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType)
     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
-FASTCALL
-ProbeAndConvertToBitmapV5Info(
-    OUT PBITMAPV5INFO pbmiDst,
-    IN CONST BITMAPINFO* pbmiUnsafe,
-    IN DWORD dwColorUse,
-    IN UINT MaxSize)
-{
-    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);
-
-
-    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;
-        }
-
-//        pbmhDst->bV5CSType;
-//        pbmhDst->bV5Endpoints;
-//        pbmhDst->bV5GammaRed;
-//        pbmhDst->bV5GammaGreen;
-//        pbmhDst->bV5GammaBlue;
-    }
-
-    if (dwSize < sizeof(BITMAPV5HEADER))
-    {
-//        pbmhDst->bV5Intent;
-//        pbmhDst->bV5ProfileData;
-//        pbmhDst->bV5ProfileSize;
-//        pbmhDst->bV5Reserved;
-    }
-
-    ulWidthBytes = ((pbmhDst->bV5Width * pbmhDst->bV5Planes *
-                     pbmhDst->bV5BitCount + 31) & ~31) / 8;
-
-    if (pbmhDst->bV5SizeImage == 0)
-        pbmhDst->bV5SizeImage = abs(ulWidthBytes * pbmhDst->bV5Height);
-
-    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;
-        }
-    }
-
-    if (pbmhDst->bV5Planes != 1)
-    {
-        return STATUS_INVALID_PARAMETER;
-    }
-
-    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;
-}
-
 /* Converts a BITMAPCOREINFO to a BITMAPINFO structure,
  * or does nothing if it's already a BITMAPINFO (or V4 or V5) */
 BITMAPINFO*