[WINDOWSCODECS_WINETEST]
authorAmine Khaldi <amine.khaldi@reactos.org>
Thu, 19 Sep 2013 14:54:53 +0000 (14:54 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Thu, 19 Sep 2013 14:54:53 +0000 (14:54 +0000)
* Sync with Wine 1.7.1.

svn path=/trunk/; revision=60203

rostests/winetests/windowscodecs/CMakeLists.txt
rostests/winetests/windowscodecs/bitmap.c
rostests/winetests/windowscodecs/converter.c
rostests/winetests/windowscodecs/gifformat.c

index 49e318c..43a842e 100644 (file)
@@ -17,7 +17,6 @@ list(APPEND SOURCE
     tiffformat.c)
 
 add_executable(windowscodecs_winetest ${SOURCE})
-target_link_libraries(windowscodecs_winetest wine)
 set_module_type(windowscodecs_winetest win32cui)
 add_importlibs(windowscodecs_winetest windowscodecs oleaut32 ole32 user32 gdi32 msvcrt kernel32 ntdll)
 add_cd_file(TARGET windowscodecs_winetest DESTINATION reactos/bin FOR all)
index f2f9bcb..ac33e7c 100644 (file)
@@ -27,6 +27,7 @@
 #define COM_NO_WINDOWS_H
 
 #define COBJMACROS
+#define CONST_VTABLE
 
 #include <windef.h>
 #include <winbase.h>
@@ -49,6 +50,80 @@ static const char *debugstr_guid(const GUID *guid)
     return buf;
 }
 
+static HRESULT WINAPI bitmapsource_QueryInterface(IWICBitmapSource *iface, REFIID iid, void **ppv)
+{
+    if (IsEqualIID(&IID_IUnknown, iid) ||
+        IsEqualIID(&IID_IWICBitmapSource, iid))
+    {
+        *ppv = iface;
+    }
+    else
+    {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    return S_OK;
+}
+
+static ULONG WINAPI bitmapsource_AddRef(IWICBitmapSource *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI bitmapsource_Release(IWICBitmapSource *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI bitmapsource_GetSize(IWICBitmapSource *iface, UINT *width, UINT *height)
+{
+    *width = *height = 10;
+    return S_OK;
+}
+
+static HRESULT WINAPI bitmapsource_GetPixelFormat(IWICBitmapSource *iface,
+    WICPixelFormatGUID *format)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI bitmapsource_GetResolution(IWICBitmapSource *iface,
+    double *dpiX, double *dpiY)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI bitmapsource_CopyPalette(IWICBitmapSource *iface,
+    IWICPalette *palette)
+{
+    return E_NOTIMPL;
+}
+
+static WICRect g_rect;
+static BOOL called_CopyPixels;
+
+static HRESULT WINAPI bitmapsource_CopyPixels(IWICBitmapSource *iface,
+    const WICRect *rc, UINT stride, UINT buffer_size, BYTE *buffer)
+{
+    if (rc) g_rect = *rc;
+    called_CopyPixels = TRUE;
+    return S_OK;
+}
+
+static const IWICBitmapSourceVtbl sourcevtbl = {
+    bitmapsource_QueryInterface,
+    bitmapsource_AddRef,
+    bitmapsource_Release,
+    bitmapsource_GetSize,
+    bitmapsource_GetPixelFormat,
+    bitmapsource_GetResolution,
+    bitmapsource_CopyPalette,
+    bitmapsource_CopyPixels
+};
+
+static IWICBitmapSource bitmapsource = { &sourcevtbl };
+
 static HBITMAP create_dib(int width, int height, int bpp, LOGPALETTE *pal, const void *data)
 {
     char bmibuf[sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255];
@@ -657,15 +732,15 @@ static void test_CreateBitmapFromHBITMAP(void)
     hbmp = create_dib(3, 3, 8, NULL, data_8bpp_rgb_dib);
     ok(hbmp != 0, "failed to create bitmap\n");
 
-    hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, 0, 0, WICBitmapCacheOnLoad, &bitmap);
+    hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, 0, 0, WICBitmapIgnoreAlpha, &bitmap);
 todo_wine
     ok(hr == WINCODEC_ERR_WIN32ERROR || hr == 0x88980003 /*XP*/, "expected WINCODEC_ERR_WIN32ERROR, got %#x\n", hr);
 
-    hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, 0, WICBitmapCacheOnLoad, NULL);
+    hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, 0, WICBitmapIgnoreAlpha, NULL);
 todo_wine
     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
 
-    hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, 0, WICBitmapCacheOnLoad, &bitmap);
+    hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, 0, WICBitmapIgnoreAlpha, &bitmap);
 todo_wine
     ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr);
     if (hr != S_OK) return;
@@ -697,7 +772,7 @@ todo_wine
     ok(hpal != 0, "CreatePalette failed\n");
 
     hbmp = create_dib(3, 3, 8, pal, data_8bpp_pal_dib);
-    hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, hpal, WICBitmapCacheOnLoad, &bitmap);
+    hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, hpal, WICBitmapIgnoreAlpha, &bitmap);
     ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr);
 
     IWICBitmap_GetPixelFormat(bitmap, &format);
@@ -737,7 +812,7 @@ todo_wine
     ok(hpal != 0, "CreatePalette failed\n");
 
     hbmp = create_dib(3, 3, 8, pal, data_8bpp_pal_dib);
-    hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, hpal, WICBitmapCacheOnLoad, &bitmap);
+    hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, hpal, WICBitmapIgnoreAlpha, &bitmap);
     ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr);
 
     IWICBitmap_GetPixelFormat(bitmap, &format);
@@ -775,6 +850,112 @@ todo_wine
     DeleteObject(hpal);
 }
 
+static void test_clipper(void)
+{
+    IWICBitmapClipper *clipper;
+    UINT height, width;
+    IWICBitmap *bitmap;
+    BYTE buffer[500];
+    WICRect rect;
+    HRESULT hr;
+
+    hr = IWICImagingFactory_CreateBitmap(factory, 10, 10, &GUID_WICPixelFormat24bppBGR,
+        WICBitmapCacheOnLoad, &bitmap);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IWICImagingFactory_CreateBitmapClipper(factory, &clipper);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    rect.X = rect.Y = 0;
+    rect.Width = rect.Height = 11;
+    hr = IWICBitmapClipper_Initialize(clipper, (IWICBitmapSource*)bitmap, &rect);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+    rect.X = rect.Y = 5;
+    rect.Width = rect.Height = 6;
+    hr = IWICBitmapClipper_Initialize(clipper, (IWICBitmapSource*)bitmap, &rect);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+    rect.X = rect.Y = 5;
+    rect.Width = rect.Height = 5;
+    hr = IWICBitmapClipper_Initialize(clipper, (IWICBitmapSource*)bitmap, &rect);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    width = height = 0;
+    hr = IWICBitmapClipper_GetSize(clipper, &width, &height);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(width == 5, "got %d\n", width);
+    ok(height == 5, "got %d\n", height);
+
+    IWICBitmapClipper_Release(clipper);
+    IWICBitmap_Release(bitmap);
+
+    /* CopyPixels */
+    hr = IWICImagingFactory_CreateBitmapClipper(factory, &clipper);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    rect.X = rect.Y = 5;
+    rect.Width = rect.Height = 5;
+    hr = IWICBitmapClipper_Initialize(clipper, &bitmapsource, &rect);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    rect.X = rect.Y = 0;
+    rect.Width = rect.Height = 2;
+
+    /* passed rectangle is relative to clipper rectangle, underlying source gets intersected
+       rectangle */
+    memset(&g_rect, 0, sizeof(g_rect));
+    called_CopyPixels = FALSE;
+    hr = IWICBitmapClipper_CopyPixels(clipper, &rect, 0, sizeof(buffer), buffer);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(called_CopyPixels, "CopyPixels not called\n");
+    ok(g_rect.X == 5 && g_rect.Y == 5 && g_rect.Width == 2 && g_rect.Height == 2,
+        "got wrong rectangle (%d,%d)-(%d,%d)\n", g_rect.X, g_rect.Y, g_rect.Width, g_rect.Height);
+
+    /* whole clipping rectangle */
+    memset(&g_rect, 0, sizeof(g_rect));
+    called_CopyPixels = FALSE;
+
+    rect.X = rect.Y = 0;
+    rect.Width = rect.Height = 5;
+
+    hr = IWICBitmapClipper_CopyPixels(clipper, &rect, 0, sizeof(buffer), buffer);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(called_CopyPixels, "CopyPixels not called\n");
+    ok(g_rect.X == 5 && g_rect.Y == 5 && g_rect.Width == 5 && g_rect.Height == 5,
+        "got wrong rectangle (%d,%d)-(%d,%d)\n", g_rect.X, g_rect.Y, g_rect.Width, g_rect.Height);
+
+    /* larger than clipping rectangle */
+    memset(&g_rect, 0, sizeof(g_rect));
+    called_CopyPixels = FALSE;
+
+    rect.X = rect.Y = 0;
+    rect.Width = rect.Height = 20;
+
+    hr = IWICBitmapClipper_CopyPixels(clipper, &rect, 0, sizeof(buffer), buffer);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+    ok(!called_CopyPixels, "CopyPixels called\n");
+
+    rect.X = rect.Y = 5;
+    rect.Width = rect.Height = 5;
+
+    hr = IWICBitmapClipper_CopyPixels(clipper, &rect, 0, sizeof(buffer), buffer);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+    ok(!called_CopyPixels, "CopyPixels called\n");
+
+    /* null rectangle */
+    memset(&g_rect, 0, sizeof(g_rect));
+    called_CopyPixels = FALSE;
+
+    hr = IWICBitmapClipper_CopyPixels(clipper, NULL, 0, sizeof(buffer), buffer);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(called_CopyPixels, "CopyPixels not called\n");
+    ok(g_rect.X == 5 && g_rect.Y == 5 && g_rect.Width == 5 && g_rect.Height == 5,
+        "got wrong rectangle (%d,%d)-(%d,%d)\n", g_rect.X, g_rect.Y, g_rect.Width, g_rect.Height);
+
+    IWICBitmapClipper_Release(clipper);
+}
+
 START_TEST(bitmap)
 {
     HRESULT hr;
@@ -790,6 +971,7 @@ START_TEST(bitmap)
     test_CreateBitmapFromMemory();
     test_CreateBitmapFromHICON();
     test_CreateBitmapFromHBITMAP();
+    test_clipper();
 
     IWICImagingFactory_Release(factory);
 
index 4a7bac5..c7b516c 100644 (file)
@@ -372,6 +372,147 @@ static void test_default_converter(void)
     DeleteTestBitmap(src_obj);
 }
 
+typedef struct property_opt_test_data
+{
+    LPCOLESTR name;
+    VARTYPE var_type;
+    VARTYPE initial_var_type;
+    int i_init_val;
+    float f_init_val;
+} property_opt_test_data;
+
+static const WCHAR wszTiffCompressionMethod[] = {'T','i','f','f','C','o','m','p','r','e','s','s','i','o','n','M','e','t','h','o','d',0};
+static const WCHAR wszCompressionQuality[] = {'C','o','m','p','r','e','s','s','i','o','n','Q','u','a','l','i','t','y',0};
+
+static const struct property_opt_test_data testdata_tiff_props[] = {
+    { wszTiffCompressionMethod, VT_UI1,         VT_UI1,  WICTiffCompressionDontCare },
+    { wszCompressionQuality,    VT_R4,          VT_EMPTY },
+    { NULL }
+};
+
+static int find_property_index(const WCHAR* name, PROPBAG2* all_props, int all_prop_cnt)
+{
+    int i;
+    for (i=0; i < all_prop_cnt; i++)
+    {
+        if (lstrcmpW(name, all_props[i].pstrName) == 0)
+            return i;
+    }
+    return -1;
+}
+
+static void test_specific_encoder_properties(IPropertyBag2 *options, const property_opt_test_data* data, PROPBAG2* all_props, int all_prop_cnt)
+{
+    HRESULT hr;
+    int i = 0;
+    VARIANT pvarValue;
+    HRESULT phrError = S_OK;
+
+    while (data[i].name)
+    {
+        int idx = find_property_index(data[i].name, all_props, all_prop_cnt);
+        PROPBAG2 pb = {0};
+        pb.pstrName = (LPOLESTR)data[i].name;
+
+        hr = IPropertyBag2_Read(options, 1, &pb, NULL, &pvarValue, &phrError);
+
+        ok(idx >= 0, "Property %s not in output of GetPropertyInfo\n",
+           wine_dbgstr_w(data[i].name));
+        if (idx >= 0)
+        {
+            ok(all_props[idx].vt == data[i].var_type, "Property %s has unexpected vt type, vt=%i\n",
+               wine_dbgstr_w(data[i].name), all_props[idx].vt);
+            ok(all_props[idx].dwType == PROPBAG2_TYPE_DATA, "Property %s has unexpected dw type, vt=%i\n",
+               wine_dbgstr_w(data[i].name), all_props[idx].dwType);
+            ok(all_props[idx].cfType == 0, "Property %s has unexpected cf type, vt=%i\n",
+               wine_dbgstr_w(data[i].name), all_props[idx].cfType);
+        }
+
+        ok(SUCCEEDED(hr), "Reading property %s from bag failed, hr=%x\n",
+           wine_dbgstr_w(data[i].name), hr);
+
+        if (SUCCEEDED(hr))
+        {
+            /* On XP the initial type is always VT_EMPTY */
+            ok(V_VT(&pvarValue) == data[i].initial_var_type || V_VT(&pvarValue) == VT_EMPTY,
+               "Property %s has unexpected initial type, V_VT=%i\n",
+               wine_dbgstr_w(data[i].name), V_VT(&pvarValue));
+
+            if(V_VT(&pvarValue) == data[i].initial_var_type)
+            {
+                switch (data[i].initial_var_type)
+                {
+                    case VT_BOOL:
+                    case VT_UI1:
+                        ok(V_UNION(&pvarValue, bVal) == data[i].i_init_val, "Property %s has an unexpected initial value, pvarValue=%i\n",
+                           wine_dbgstr_w(data[i].name), V_UNION(&pvarValue, bVal));
+                        break;
+                    case VT_R4:
+                        ok(V_UNION(&pvarValue, fltVal) == data[i].f_init_val, "Property %s has an unexpected initial value, pvarValue=%f\n",
+                           wine_dbgstr_w(data[i].name), V_UNION(&pvarValue, fltVal));
+                        break;
+                    default:
+                        break;
+                }
+            }
+
+            VariantClear(&pvarValue);
+        }
+
+        i++;
+    }
+}
+
+static void test_encoder_properties(const CLSID* clsid_encoder, IPropertyBag2 *options)
+{
+    HRESULT hr;
+    ULONG cProperties = 0;
+    ULONG cProperties2 = 0;
+    PROPBAG2 all_props[64] = {{0}}; /* Should be enough for every encoder out there */
+    int i;
+
+    /* CountProperties */
+    {
+        hr = IPropertyBag2_CountProperties(options, &cProperties);
+        ok(SUCCEEDED(hr), "Reading property count, hr=%x\n", hr);
+    }
+
+    /* GetPropertyInfo */
+    {
+        hr = IPropertyBag2_GetPropertyInfo(options, cProperties, 1, all_props, &cProperties2);
+        ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "IPropertyBag2::GetPropertyInfo - iProperty out of bounce handled wrong, hr=%x\n", hr);
+
+        hr = IPropertyBag2_GetPropertyInfo(options, 0, cProperties+1, all_props, &cProperties2);
+        ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "IPropertyBag2::GetPropertyInfo - cProperty out of bounce handled wrong, hr=%x\n", hr);
+
+        if (cProperties == 0) /* GetPropertyInfo can be called for zero items on Windows 8 but not on Windows 7 (wine behaves like Win8) */
+        {
+            cProperties2 = cProperties;
+            hr = S_OK;
+        }
+        else
+        {
+            hr = IPropertyBag2_GetPropertyInfo(options, 0, min(64, cProperties), all_props, &cProperties2);
+            ok(SUCCEEDED(hr), "Reading infos from property bag failed, hr=%x\n", hr);
+        }
+
+        if (FAILED(hr))
+            return;
+
+        ok(cProperties == cProperties2, "Missmatch of property count (IPropertyBag2::CountProperties=%i, IPropertyBag2::GetPropertyInfo=%i)\n",
+           (int)cProperties, (int)cProperties2);
+    }
+
+    if (clsid_encoder == &CLSID_WICTiffEncoder)
+        test_specific_encoder_properties(options, testdata_tiff_props, all_props, cProperties2);
+
+    for (i=0; i < cProperties2; i++)
+    {
+        ok(all_props[i].pstrName != NULL, "Unset property name in output of IPropertyBag2::GetPropertyInfo\n");
+        CoTaskMemFree(all_props[i].pstrName);
+    }
+}
+
 static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* clsid_encoder,
     const struct bitmap_data **dsts, const CLSID *clsid_decoder, const char *name)
 {
@@ -414,6 +555,10 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls
                 ok(SUCCEEDED(hr), "CreateFrame failed, hr=%x\n", hr);
                 if (SUCCEEDED(hr))
                 {
+                    ok(options != NULL, "Encoder initialization has not created an property bag\n");
+                    if(options)
+                        test_encoder_properties(clsid_encoder, options);
+
                     hr = IWICBitmapFrameEncode_Initialize(frameencode, options);
                     ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr);
 
index ca7d9d2..d0e8117 100644 (file)
@@ -277,8 +277,9 @@ static void test_local_gif_palette(void)
     IWICBitmapDecoder *decoder;
     IWICBitmapFrameDecode *frame;
     IWICPalette *palette;
+    WICBitmapPaletteType type;
     GUID format;
-    UINT count, ret;
+    UINT count, ret, i;
     WICColor color[256];
 
     decoder = create_decoder(gif_local_palette, sizeof(gif_local_palette));
@@ -289,8 +290,27 @@ static void test_local_gif_palette(void)
 
     /* global palette */
     hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
-    ok(hr == WINCODEC_ERR_FRAMEMISSING,
-       "expected WINCODEC_ERR_FRAMEMISSING, got %#x\n", hr);
+    ok(hr == S_OK || broken(hr == WINCODEC_ERR_FRAMEMISSING), "CopyPalette %#x\n", hr);
+    if (hr == S_OK)
+    {
+        type = -1;
+        hr = IWICPalette_GetType(palette, &type);
+        ok(hr == S_OK, "GetType error %#x\n", hr);
+        ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type);
+
+        hr = IWICPalette_GetColorCount(palette, &count);
+        ok(hr == S_OK, "GetColorCount error %#x\n", hr);
+        ok(count == 256, "expected 256, got %u\n", count);
+
+        hr = IWICPalette_GetColors(palette, count, color, &ret);
+        ok(hr == S_OK, "GetColors error %#x\n", hr);
+        ok(ret == count, "expected %u, got %u\n", count, ret);
+        ok(color[0] == 0xff000000, "expected 0xff000000, got %#x\n", color[0]);
+        ok(color[1] == 0x00ffffff, "expected 0x00ffffff, got %#x\n", color[1]);
+
+        for (i = 2; i < 256; i++)
+            ok(color[i] == 0xff000000, "expected 0xff000000, got %#x\n", color[i]);
+    }
 
     /* frame palette */
     hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
@@ -308,6 +328,11 @@ static void test_local_gif_palette(void)
     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
     ok(count == 4, "expected 4, got %u\n", count);
 
+    type = -1;
+    hr = IWICPalette_GetType(palette, &type);
+    ok(hr == S_OK, "GetType error %#x\n", hr);
+    ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type);
+
     hr = IWICPalette_GetColors(palette, count, color, &ret);
     ok(hr == S_OK, "GetColors error %#x\n", hr);
     ok(ret == count, "expected %u, got %u\n", count, ret);