Vincent Povirk : windowscodecs: Implement GetPixelFormat for BMP decoder.

Alexandre Julliard julliard at winehq.org
Thu Jul 2 08:25:04 CDT 2009


Module: wine
Branch: master
Commit: 02d0462f067d4ade4dcecf98575fc67494a93aa7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=02d0462f067d4ade4dcecf98575fc67494a93aa7

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Wed Jul  1 13:18:02 2009 -0500

windowscodecs: Implement GetPixelFormat for BMP decoder.

---

 dlls/windowscodecs/bmpdecode.c       |   86 +++++++++++++++++++++++++++++++++-
 dlls/windowscodecs/tests/bmpformat.c |    4 ++
 2 files changed, 88 insertions(+), 2 deletions(-)

diff --git a/dlls/windowscodecs/bmpdecode.c b/dlls/windowscodecs/bmpdecode.c
index e2378ba..46b2527 100644
--- a/dlls/windowscodecs/bmpdecode.c
+++ b/dlls/windowscodecs/bmpdecode.c
@@ -64,6 +64,8 @@ typedef struct {
     IStream *stream;
     BITMAPFILEHEADER bfh;
     BITMAPV5HEADER bih;
+    const WICPixelFormatGUID *pixelformat;
+    int bitsperpixel;
 } BmpFrameDecode;
 
 static HRESULT WINAPI BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid,
@@ -151,8 +153,12 @@ static HRESULT WINAPI BmpFrameDecode_GetSize(IWICBitmapFrameDecode *iface,
 static HRESULT WINAPI BmpFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface,
     WICPixelFormatGUID *pPixelFormat)
 {
-    FIXME("(%p,%p): stub\n", iface, pPixelFormat);
-    return E_NOTIMPL;
+    BmpFrameDecode *This = (BmpFrameDecode*)iface;
+    TRACE("(%p,%p)\n", iface, pPixelFormat);
+
+    memcpy(pPixelFormat, This->pixelformat, sizeof(GUID));
+
+    return S_OK;
 }
 
 static HRESULT BmpHeader_GetResolution(BITMAPV5HEADER *bih, double *pDpiX, double *pDpiY)
@@ -241,6 +247,8 @@ typedef struct {
     BITMAPFILEHEADER bfh;
     BITMAPV5HEADER bih;
     BmpFrameDecode *framedecode;
+    const WICPixelFormatGUID *pixelformat;
+    int bitsperpixel;
 } BmpDecoder;
 
 static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream)
@@ -269,6 +277,78 @@ static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream)
     if (FAILED(hr)) return hr;
     if (bytestoread != bytesread) return E_FAIL;
 
+    /* decide what kind of bitmap this is and how/if we can read it */
+    if (This->bih.bV5Size == sizeof(BITMAPCOREHEADER))
+    {
+        BITMAPCOREHEADER *bch = (BITMAPCOREHEADER*)&This->bih;
+        TRACE("BITMAPCOREHEADER with depth=%i\n", bch->bcBitCount);
+        This->bitsperpixel = bch->bcBitCount;
+        switch(bch->bcBitCount)
+        {
+        case 1:
+            This->pixelformat = &GUID_WICPixelFormat1bppIndexed;
+            break;
+        case 2:
+            This->pixelformat = &GUID_WICPixelFormat2bppIndexed;
+            break;
+        case 4:
+            This->pixelformat = &GUID_WICPixelFormat4bppIndexed;
+            break;
+        case 8:
+            This->pixelformat = &GUID_WICPixelFormat8bppIndexed;
+            break;
+        case 24:
+            This->pixelformat = &GUID_WICPixelFormat24bppBGR;
+            break;
+        default:
+            This->pixelformat = &GUID_WICPixelFormatUndefined;
+            WARN("unsupported bit depth %i for BITMAPCOREHEADER\n", bch->bcBitCount);
+            break;
+        }
+    }
+    else /* struct is compatible with BITMAPINFOHEADER */
+    {
+        TRACE("bitmap header=%i compression=%i depth=%i\n", This->bih.bV5Size, This->bih.bV5Compression, This->bih.bV5BitCount);
+        switch(This->bih.bV5Compression)
+        {
+        case BI_RGB:
+            This->bitsperpixel = This->bih.bV5BitCount;
+            switch(This->bih.bV5BitCount)
+            {
+            case 1:
+                This->pixelformat = &GUID_WICPixelFormat1bppIndexed;
+                break;
+            case 2:
+                This->pixelformat = &GUID_WICPixelFormat2bppIndexed;
+                break;
+            case 4:
+                This->pixelformat = &GUID_WICPixelFormat4bppIndexed;
+                break;
+            case 8:
+                This->pixelformat = &GUID_WICPixelFormat8bppIndexed;
+                break;
+            case 16:
+                This->pixelformat = &GUID_WICPixelFormat16bppBGR555;
+                break;
+            case 24:
+                This->pixelformat = &GUID_WICPixelFormat24bppBGR;
+                break;
+            case 32:
+                This->pixelformat = &GUID_WICPixelFormat32bppBGR;
+                break;
+            default:
+                This->pixelformat = &GUID_WICPixelFormatUndefined;
+                FIXME("unsupported bit depth %i for uncompressed RGB\n", This->bih.bV5BitCount);
+            }
+            break;
+        default:
+            This->bitsperpixel = 0;
+            This->pixelformat = &GUID_WICPixelFormatUndefined;
+            FIXME("unsupported bitmap type header=%i compression=%i depth=%i\n", This->bih.bV5Size, This->bih.bV5Compression, This->bih.bV5BitCount);
+            break;
+        }
+    }
+
     This->initialized = TRUE;
 
     return S_OK;
@@ -423,6 +503,8 @@ static HRESULT WINAPI BmpDecoder_GetFrame(IWICBitmapDecoder *iface,
         IStream_AddRef(This->stream);
         This->framedecode->bfh = This->bfh;
         This->framedecode->bih = This->bih;
+        This->framedecode->pixelformat = This->pixelformat;
+        This->framedecode->bitsperpixel = This->bitsperpixel;
     }
 
     *ppIBitmapFrame = (IWICBitmapFrameDecode*)This->framedecode;
diff --git a/dlls/windowscodecs/tests/bmpformat.c b/dlls/windowscodecs/tests/bmpformat.c
index 05c34e9..11c5a67 100644
--- a/dlls/windowscodecs/tests/bmpformat.c
+++ b/dlls/windowscodecs/tests/bmpformat.c
@@ -102,6 +102,10 @@ static void test_decode_24bpp(void)
                 ok(dpiX == 96.0, "expected dpiX=96.0, got %f\n", dpiX);
                 ok(dpiY == 96.0, "expected dpiY=96.0, got %f\n", dpiY);
 
+                hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult);
+                ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr);
+                ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n");
+
                 IWICBitmapFrameDecode_Release(framedecode);
             }
 




More information about the wine-cvs mailing list