- Update to trunk
[reactos.git] / subsystems / win32 / win32k / misc / file.c
index 1e2281a..856de99 100644 (file)
@@ -149,213 +149,98 @@ W32kMapViewOfSection(
     return pvBase;
 }
 
-typedef struct tagBITMAPV5INFO
-{
-    BITMAPV5HEADER bmiHeader;
-    RGBQUAD        bmiColors[256];
-} BITMAPV5INFO, *PBITMAPV5INFO;
-
-// FIXME: this should go to dibobj.c
-NTSTATUS
-ProbeAndConvertBitmapInfo(
-    OUT BITMAPV5HEADER *pbmhDst,
-    OUT RGBQUAD *pbmiColorsDst,
-    ULONG cColors,
-    IN  PBITMAPINFO pbmiUnsafe)
-{
-    DWORD dwSize;
-    RGBQUAD *pbmiColors;
-    ULONG ulWidthBytes;
-
-    /* Get the size and probe */
-    ProbeForRead(&pbmiUnsafe->bmiHeader.biSize, sizeof(DWORD), 1);
-    dwSize = pbmiUnsafe->bmiHeader.biSize;
-    ProbeForRead(pbmiUnsafe, dwSize, 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;
-    }
-
-    pbmiColors = (RGBQUAD*)((PCHAR)pbmiUnsafe + dwSize);
-
-    pbmhDst->bV5Size = sizeof(BITMAPV5HEADER);
-
-    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 = 0;
-        pbmhDst->bV5XPelsPerMeter = 72;
-        pbmhDst->bV5YPelsPerMeter = 72;
-        pbmhDst->bV5ClrUsed = 0;
-        pbmhDst->bV5ClrImportant = 0;
-    }
-    else
-    {
-        /* Copy valid fields */
-        memcpy(pbmhDst, pbmiUnsafe, dwSize);
-
-        /* Zero out the rest of the V5 header */
-        memset((char*)pbmhDst + dwSize, 0, sizeof(BITMAPV5HEADER) - dwSize);
-    }
-
-
-    if (dwSize < sizeof(BITMAPV4HEADER))
-    {
-        if (pbmhDst->bV5Compression == BI_BITFIELDS)
-        {
-            DWORD *pMasks = (DWORD*)pbmiColors;
-            pbmhDst->bV5RedMask = pMasks[0];
-            pbmhDst->bV5GreenMask = pMasks[1];
-            pbmhDst->bV5BlueMask = pMasks[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)
-        pbmhDst->bV5ClrUsed = pbmhDst->bV5BitCount == 1 ? 2 :
-                              (pbmhDst->bV5BitCount == 4 ? 16 :
-                              (pbmhDst->bV5BitCount == 8 ? 256 : 0));
-
-    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 */
-    cColors = min(cColors, pbmhDst->bV5ClrUsed);
-    memcpy(pbmiColorsDst, pbmiColors, cColors * sizeof(RGBQUAD));
-
-    return STATUS_SUCCESS;
-}
-
-
 HBITMAP
 NTAPI
 UserLoadImage(PCWSTR pwszName)
 {
-    NTSTATUS Status;
+    NTSTATUS Status = STATUS_SUCCESS;
     HANDLE hFile, hSection;
     BITMAPFILEHEADER *pbmfh;
     LPBITMAPINFO pbmi;
-    ULONG cjInfoSize;
     PVOID pvBits;
     HBITMAP hbmp = 0;
-    BITMAPV5INFO bmiLocal;
+
+    DPRINT("Enter UserLoadImage(%ls)\n", pwszName);
 
     /* Open the file */
     hFile = W32kOpenFile(pwszName, FILE_READ_DATA);
-    if (hFile == INVALID_HANDLE_VALUE)
-          return NULL;
+    if (!hFile)
+    {
+        return NULL;
+    }
 
     /* Create a section */
     hSection = W32kCreateFileSection(hFile, SEC_COMMIT, PAGE_READONLY, 0);
     ZwClose(hFile);
     if (!hSection)
-          return NULL;
+    {
+        return NULL;
+    }
 
     /* Map the section */
     pbmfh = W32kMapViewOfSection(hSection, PAGE_READONLY, 0);
     ZwClose(hSection);
     if (!pbmfh)
-          return NULL;
-
-    /* Get a pointer to the BITMAPINFO */
-    pbmi = (LPBITMAPINFO)(pbmfh + 1);
-
-    /* Create a normalized local BITMAPINFO */
-    _SEH2_TRY
     {
-        Status = ProbeAndConvertBitmapInfo(&bmiLocal.bmiHeader,
-                                           bmiLocal.bmiColors,
-                                           256,
-                                           pbmi);
+        return NULL;
     }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-    {
-        Status = _SEH2_GetExceptionCode();
-    }
-    _SEH2_END
 
-    if (NT_SUCCESS(Status))
-    {
-        cjInfoSize = bmiLocal.bmiHeader.bV5Size +
-                     bmiLocal.bmiHeader.bV5ClrUsed * sizeof(RGBQUAD);
-        pvBits = (PVOID)((PCHAR)pbmi + cjInfoSize);
-
-        // FIXME: use Gre... so that the BITMAPINFO doesn't get probed
-        hbmp = NtGdiCreateDIBitmapInternal(NULL,
-                                           bmiLocal.bmiHeader.bV5Width,
-                                           bmiLocal.bmiHeader.bV5Height,
-                                           CBM_INIT,
-                                           pvBits,
-                                           pbmi,
-                                           DIB_RGB_COLORS,
-                                           bmiLocal.bmiHeader.bV5Size,
-                                           bmiLocal.bmiHeader.bV5SizeImage,
-                                           0,
-                                           0);
-    }
+    /* Get a pointer to the BITMAPINFO */
+    pbmi = (LPBITMAPINFO)(pbmfh + 1);
 
+       _SEH2_TRY
+       {
+               ProbeForRead(&pbmfh->bfSize, sizeof(DWORD), 1);
+               ProbeForRead(pbmfh, pbmfh->bfSize, 1);
+       }
+       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+       {
+               Status = _SEH2_GetExceptionCode();
+       }
+       _SEH2_END
+
+       if(!NT_SUCCESS(Status))
+       {
+               DPRINT1("Bad File?\n");
+               goto leave;
+       }
+
+    if (pbmfh->bfType == 0x4D42 /* 'BM' */)
+    {
+               /* Could be BITMAPCOREINFO */
+               BITMAPINFO* pConvertedInfo;
+               HDC hdc;
+
+               pvBits = (PVOID)((PCHAR)pbmfh + pbmfh->bfOffBits);
+
+               pConvertedInfo = DIB_ConvertBitmapInfo(pbmi, DIB_RGB_COLORS);
+               if(!pConvertedInfo)
+               {
+                       DPRINT1("Unable to convert the bitmap Info\n");
+                       goto leave;
+               }
+
+               hdc = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE);
+
+        hbmp = GreCreateDIBitmapInternal(hdc,
+                                         pConvertedInfo->bmiHeader.biWidth,
+                                                        pConvertedInfo->bmiHeader.biHeight,
+                                         CBM_INIT,
+                                         pvBits,
+                                         pConvertedInfo,
+                                         DIB_RGB_COLORS,
+                                         0,
+                                         0);
+
+               NtGdiDeleteObjectApp(hdc);
+               DIB_FreeConvertedBitmapInfo(pConvertedInfo, pbmi);
+    }
+       else
+       {
+               DPRINT1("Unknown file type!\n");
+       }
+
+leave:
     /* Unmap our section, we don't need it anymore */
     ZwUnmapViewOfSection(NtCurrentProcess(), pbmfh);