[2/2] windowscodecs: Implement ComponentFactory_CreateBitmapFromMemory.

Vincent Povirk madewokherd at gmail.com
Thu Dec 27 09:41:09 CST 2012


I'm pretty sure CreateBitmapFromMemory copies the data rather than
referencing existing data.

On Thu, Dec 27, 2012 at 3:29 AM, Dmitry Timoshkov <dmitry at baikal.ru> wrote:
> ---
>  dlls/windowscodecs/bitmap.c            | 31 +++++++++++++++++++++----------
>  dlls/windowscodecs/imgfactory.c        | 18 +++++++++++-------
>  dlls/windowscodecs/tests/bitmap.c      |  5 -----
>  dlls/windowscodecs/wincodecs_private.h |  1 +
>  4 files changed, 33 insertions(+), 22 deletions(-)
>
> diff --git a/dlls/windowscodecs/bitmap.c b/dlls/windowscodecs/bitmap.c
> index 520fdef..4d48651 100644
> --- a/dlls/windowscodecs/bitmap.c
> +++ b/dlls/windowscodecs/bitmap.c
> @@ -40,6 +40,7 @@ typedef struct BitmapImpl {
>      int palette_set;
>      LONG lock; /* 0 if not locked, -1 if locked for writing, count if locked for reading */
>      BYTE *data;
> +    BOOL owndata;
>      UINT width, height;
>      UINT stride;
>      UINT bpp;
> @@ -260,7 +261,8 @@ static ULONG WINAPI BitmapImpl_Release(IWICBitmap *iface)
>          if (This->palette) IWICPalette_Release(This->palette);
>          This->cs.DebugInfo->Spare[0] = 0;
>          DeleteCriticalSection(&This->cs);
> -        HeapFree(GetProcessHeap(), 0, This->data);
> +        if (This->owndata)
> +            HeapFree(GetProcessHeap(), 0, This->data);
>          HeapFree(GetProcessHeap(), 0, This);
>      }
>
> @@ -447,28 +449,37 @@ static const IWICBitmapVtbl BitmapImpl_Vtbl = {
>  };
>
>  HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight,
> +    UINT stride, UINT datasize, BYTE *data,
>      REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option,
>      IWICBitmap **ppIBitmap)
>  {
>      HRESULT hr;
>      BitmapImpl *This;
> -    UINT bpp, stride, datasize;
> -    BYTE *data;
> +    UINT bpp;
>
>      hr = get_pixelformat_bpp(pixelFormat, &bpp);
>      if (FAILED(hr)) return hr;
>
> -    stride = (((bpp*uiWidth)+31)/32)*4;
> -    datasize = stride * uiHeight;
> +    if (!stride) stride = (((bpp*uiWidth)+31)/32)*4;
> +    if (!datasize) datasize = stride * uiHeight;
> +
> +    if (datasize < stride * uiHeight) return WINCODEC_ERR_INSUFFICIENTBUFFER;
> +    if (stride < (((bpp*uiWidth)+31)/32)*4) return E_INVALIDARG;
>
>      This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapImpl));
> -    data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, datasize);
> -    if (!This || !data)
> +    if (!This) return E_OUTOFMEMORY;
> +    if (!data)
>      {
> -        HeapFree(GetProcessHeap(), 0, This);
> -        HeapFree(GetProcessHeap(), 0, data);
> -        return E_OUTOFMEMORY;
> +        data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, datasize);
> +        if (!data)
> +        {
> +            HeapFree(GetProcessHeap(), 0, This);
> +            return E_OUTOFMEMORY;
> +        }
> +        This->owndata = TRUE;
>      }
> +    else
> +        This->owndata = FALSE;
>
>      This->IWICBitmap_iface.lpVtbl = &BitmapImpl_Vtbl;
>      This->ref = 1;
> diff --git a/dlls/windowscodecs/imgfactory.c b/dlls/windowscodecs/imgfactory.c
> index 54b390b..1d05ef5 100644
> --- a/dlls/windowscodecs/imgfactory.c
> +++ b/dlls/windowscodecs/imgfactory.c
> @@ -1,5 +1,6 @@
>  /*
>   * Copyright 2009 Vincent Povirk for CodeWeavers
> + * Copyright 2012 Dmitry Timoshkov
>   *
>   * This library is free software; you can redistribute it and/or
>   * modify it under the terms of the GNU Lesser General Public
> @@ -459,7 +460,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, 0, NULL, pixelFormat, option, ppIBitmap);
>  }
>
>  static HRESULT WINAPI ComponentFactory_CreateBitmapFromSource(IWICComponentFactory *iface,
> @@ -506,7 +507,7 @@ static HRESULT WINAPI ComponentFactory_CreateBitmapFromSource(IWICComponentFacto
>      }
>
>      if (SUCCEEDED(hr))
> -        hr = BitmapImpl_Create(width, height, &pixelformat, option, &result);
> +        hr = BitmapImpl_Create(width, height, 0, 0, NULL, &pixelformat, option, &result);
>
>      if (SUCCEEDED(hr))
>      {
> @@ -576,12 +577,15 @@ static HRESULT WINAPI ComponentFactory_CreateBitmapFromSourceRect(IWICComponentF
>  }
>
>  static HRESULT WINAPI ComponentFactory_CreateBitmapFromMemory(IWICComponentFactory *iface,
> -    UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat, UINT cbStride,
> -    UINT cbBufferSize, BYTE *pbBuffer, IWICBitmap **ppIBitmap)
> +    UINT width, UINT height, REFWICPixelFormatGUID format, UINT stride,
> +    UINT size, BYTE *buffer, IWICBitmap **bitmap)
>  {
> -    FIXME("(%p,%u,%u,%s,%u,%u,%p,%p): stub\n", iface, uiWidth, uiHeight,
> -        debugstr_guid(pixelFormat), cbStride, cbBufferSize, pbBuffer, ppIBitmap);
> -    return E_NOTIMPL;
> +    TRACE("(%p,%u,%u,%s,%u,%u,%p,%p\n", iface, width, height,
> +        debugstr_guid(format), stride, size, buffer, bitmap);
> +
> +    if (!stride || !size || !buffer || !bitmap) return E_INVALIDARG;
> +
> +    return BitmapImpl_Create(width, height, stride, size, buffer, format, WICBitmapCacheOnLoad, bitmap);
>  }
>
>  static HRESULT WINAPI ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory *iface,
> diff --git a/dlls/windowscodecs/tests/bitmap.c b/dlls/windowscodecs/tests/bitmap.c
> index cec714b..3cdbffd 100644
> --- a/dlls/windowscodecs/tests/bitmap.c
> +++ b/dlls/windowscodecs/tests/bitmap.c
> @@ -436,27 +436,22 @@ 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,
> diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h
> index 6857176..508bb2c 100644
> --- a/dlls/windowscodecs/wincodecs_private.h
> +++ b/dlls/windowscodecs/wincodecs_private.h
> @@ -45,6 +45,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,
> +    UINT stride, UINT datasize, BYTE *data,
>      REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option,
>      IWICBitmap **ppIBitmap) DECLSPEC_HIDDEN;
>  extern HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler) DECLSPEC_HIDDEN;
> --
> 1.8.0.2
>
>
>



More information about the wine-devel mailing list