[3/4] windowscodecs: Implement CreateBitmapFromMemory.

Vincent Povirk madewokherd at gmail.com
Wed Jan 2 14:34:47 CST 2013


-------------- next part --------------
From 6405ac0d352717524aee7daaf6844533f1237e4a Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Wed, 2 Jan 2013 14:10:09 -0600
Subject: [PATCH 3/4] windowscodecs: Implement CreateBitmapFromMemory.

---
 dlls/windowscodecs/bitmap.c            | 10 +++++---
 dlls/windowscodecs/imgfactory.c        | 45 +++++++++++++++++++++++++++++++---
 dlls/windowscodecs/tests/bitmap.c      | 11 +++------
 dlls/windowscodecs/wincodecs_private.h |  2 +-
 4 files changed, 53 insertions(+), 15 deletions(-)

diff --git a/dlls/windowscodecs/bitmap.c b/dlls/windowscodecs/bitmap.c
index 520fdef..d719a7d 100644
--- a/dlls/windowscodecs/bitmap.c
+++ b/dlls/windowscodecs/bitmap.c
@@ -446,21 +446,25 @@ static const IWICBitmapVtbl BitmapImpl_Vtbl = {
     BitmapImpl_SetResolution
 };
 
-HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight,
+HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight, UINT stride,
     REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option,
     IWICBitmap **ppIBitmap)
 {
     HRESULT hr;
     BitmapImpl *This;
-    UINT bpp, stride, datasize;
+    UINT bpp, datasize;
     BYTE *data;
 
     hr = get_pixelformat_bpp(pixelFormat, &bpp);
     if (FAILED(hr)) return hr;
 
-    stride = (((bpp*uiWidth)+31)/32)*4;
+    if (!stride)
+        stride = (((bpp*uiWidth)+31)/32)*4;
     datasize = stride * uiHeight;
 
+    if (stride < ((bpp*uiWidth)+7)/8)
+        return E_INVALIDARG;
+
     This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapImpl));
     data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, datasize);
     if (!This || !data)
diff --git a/dlls/windowscodecs/imgfactory.c b/dlls/windowscodecs/imgfactory.c
index 54b390b..5dbfcc4 100644
--- a/dlls/windowscodecs/imgfactory.c
+++ b/dlls/windowscodecs/imgfactory.c
@@ -459,7 +459,7 @@ static HRESULT WINAPI ComponentFactory_CreateBitmap(IWICComponentFactory *iface,
 {
     TRACE("(%p,%u,%u,%s,%u,%p)\n", iface, uiWidth, uiHeight,
         debugstr_guid(pixelFormat), option, ppIBitmap);
-    return BitmapImpl_Create(uiWidth, uiHeight, pixelFormat, option, ppIBitmap);
+    return BitmapImpl_Create(uiWidth, uiHeight, 0, pixelFormat, option, ppIBitmap);
 }
 
 static HRESULT WINAPI ComponentFactory_CreateBitmapFromSource(IWICComponentFactory *iface,
@@ -506,7 +506,7 @@ static HRESULT WINAPI ComponentFactory_CreateBitmapFromSource(IWICComponentFacto
     }
 
     if (SUCCEEDED(hr))
-        hr = BitmapImpl_Create(width, height, &pixelformat, option, &result);
+        hr = BitmapImpl_Create(width, height, 0, &pixelformat, option, &result);
 
     if (SUCCEEDED(hr))
     {
@@ -579,9 +579,46 @@ static HRESULT WINAPI ComponentFactory_CreateBitmapFromMemory(IWICComponentFacto
     UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat, UINT cbStride,
     UINT cbBufferSize, BYTE *pbBuffer, IWICBitmap **ppIBitmap)
 {
-    FIXME("(%p,%u,%u,%s,%u,%u,%p,%p): stub\n", iface, uiWidth, uiHeight,
+    HRESULT hr;
+    IWICBitmap *bitmap;
+    IWICBitmapLock *lock;
+
+    TRACE("(%p,%u,%u,%s,%u,%u,%p,%p)\n", iface, uiWidth, uiHeight,
         debugstr_guid(pixelFormat), cbStride, cbBufferSize, pbBuffer, ppIBitmap);
-    return E_NOTIMPL;
+
+    if (!pbBuffer || cbStride == 0)
+        return E_INVALIDARG;
+
+    if (cbBufferSize < uiHeight * cbStride)
+        return WINCODEC_ERR_INSUFFICIENTBUFFER;
+
+    hr = BitmapImpl_Create(uiWidth, uiHeight, cbStride, pixelFormat, WICBitmapCacheOnDemand, &bitmap);
+
+    if (SUCCEEDED(hr))
+    {
+        hr = IWICBitmap_Lock(bitmap, NULL, WICBitmapLockWrite, &lock);
+        if (SUCCEEDED(hr))
+        {
+            UINT buffersize;
+            BYTE *buffer;
+
+            hr = IWICBitmapLock_GetDataPointer(lock, &buffersize, &buffer);
+
+            memcpy(buffer, pbBuffer, uiHeight * cbStride);
+
+            IWICBitmapLock_Release(lock);
+        }
+
+        if (FAILED(hr))
+            IWICBitmap_Release(bitmap);
+    }
+
+    if (SUCCEEDED(hr))
+        *ppIBitmap = bitmap;
+    else
+        *ppIBitmap = NULL;
+
+    return hr;
 }
 
 static HRESULT WINAPI ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory *iface,
diff --git a/dlls/windowscodecs/tests/bitmap.c b/dlls/windowscodecs/tests/bitmap.c
index daf0f02..c6d3dda 100644
--- a/dlls/windowscodecs/tests/bitmap.c
+++ b/dlls/windowscodecs/tests/bitmap.c
@@ -441,32 +441,26 @@ static void test_CreateBitmapFromMemory(void)
 
     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
                                                    0, 0, NULL, &bitmap);
-todo_wine
     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
 
     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
                                                    0, sizeof(data3x3), data3x3, &bitmap);
-todo_wine
     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
 
     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
                                                    6, sizeof(data3x3), data3x3, &bitmap);
-todo_wine
     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
 
     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
                                                    12, sizeof(data3x3), data3x3, &bitmap);
-todo_wine
     ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "expected WINCODEC_ERR_INSUFFICIENTBUFFER, got %#x\n", hr);
 
     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
                                                    9, sizeof(data3x3) - 1, data3x3, &bitmap);
-todo_wine
     ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "expected WINCODEC_ERR_INSUFFICIENTBUFFER, got %#x\n", hr);
 
     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
                                                    9, sizeof(data3x3), data3x3, &bitmap);
-todo_wine
     ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromMemory error %#x\n", hr);
     if (hr != S_OK) return;
 
@@ -499,7 +493,10 @@ todo_wine
     hr = IWICBitmap_CopyPixels(bitmap, NULL, 13, sizeof(data), data);
     ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr);
     for (i = 0; i < sizeof(data); i++)
-        ok(data[i] == data3x2[i], "%u: expected %u, got %u\n", i, data3x2[i], data[i]);
+        if ((i % 13) < 9)
+            ok(data[i] == data3x2[i], "%u: expected %u, got %u\n", i, data3x2[i], data[i]);
+        else
+            todo_wine ok(data[i] == data3x2[i], "%u: expected %u, got %u\n", i, data3x2[i], data[i]);
 
     rc.X = rc.Y = 0;
     rc.Width = 3;
diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h
index 6857176..5308421 100644
--- a/dlls/windowscodecs/wincodecs_private.h
+++ b/dlls/windowscodecs/wincodecs_private.h
@@ -44,7 +44,7 @@ extern HRESULT IcnsEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void*
 
 extern HRESULT TgaDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN;
 
-extern HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight,
+extern HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight, UINT stride,
     REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option,
     IWICBitmap **ppIBitmap) DECLSPEC_HIDDEN;
 extern HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler) DECLSPEC_HIDDEN;
-- 
1.8.0


More information about the wine-patches mailing list