Sync with trunk r58033.
[reactos.git] / dll / win32 / windowscodecs / converter.c
index b1c0952..8611560 100644 (file)
@@ -47,11 +47,14 @@ enum pixelformat {
     format_16bppGray,
     format_16bppBGR555,
     format_16bppBGR565,
+    format_16bppBGRA5551,
     format_24bppBGR,
     format_32bppBGR,
     format_32bppBGRA,
+    format_32bppPBGRA,
     format_48bppRGB,
     format_64bppRGBA,
+    format_32bppCMYK,
 };
 
 typedef HRESULT (*copyfunc)(struct FormatConverter *This, const WICRect *prc,
@@ -64,7 +67,7 @@ struct pixelformatinfo {
 };
 
 typedef struct FormatConverter {
-    const IWICFormatConverterVtbl *lpVtbl;
+    IWICFormatConverter IWICFormatConverter_iface;
     LONG ref;
     IWICBitmapSource *source;
     const struct pixelformatinfo *dst_format, *src_format;
@@ -74,14 +77,9 @@ typedef struct FormatConverter {
     CRITICAL_SECTION lock; /* must be held when initialized */
 } FormatConverter;
 
-static void make_grayscale_palette(WICColor *colors, UINT num_colors)
+static inline FormatConverter *impl_from_IWICFormatConverter(IWICFormatConverter *iface)
 {
-    int i, v;
-    for (i=0; i<num_colors; i++)
-    {
-        v = i * 255 / (num_colors-1);
-        colors[i] = 0xff000000 | v<<16 | v<<8 | v;
-    }
+    return CONTAINING_RECORD(iface, FormatConverter, IWICFormatConverter_iface);
 }
 
 static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRect *prc,
@@ -105,24 +103,19 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
             IWICPalette *palette;
             UINT actualcolors;
 
-            if (source_format == format_1bppIndexed)
-            {
-                res = PaletteImpl_Create(&palette);
-                if (FAILED(res)) return res;
+            res = PaletteImpl_Create(&palette);
+            if (FAILED(res)) return res;
 
+            if (source_format == format_1bppIndexed)
                 res = IWICBitmapSource_CopyPalette(This->source, palette);
-                if (SUCCEEDED(res))
-                    res = IWICPalette_GetColors(palette, 2, colors, &actualcolors);
+            else
+                res = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedBW, FALSE);
 
-                IWICPalette_Release(palette);
+            if (SUCCEEDED(res))
+                res = IWICPalette_GetColors(palette, 2, colors, &actualcolors);
 
-                if (FAILED(res)) return res;
-            }
-            else
-            {
-                colors[0] = 0xff000000;
-                colors[1] = 0xffffffff;
-            }
+            IWICPalette_Release(palette);
+            if (FAILED(res)) return res;
 
             srcstride = (prc->Width+7)/8;
             srcdatasize = srcstride * prc->Height;
@@ -137,7 +130,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
                 srcrow = srcdata;
                 dstrow = pbBuffer;
                 for (y=0; y<prc->Height; y++) {
-                    srcbyte=(const BYTE*)srcrow;
+                    srcbyte = srcrow;
                     dstpixel=(DWORD*)dstrow;
                     for (x=0; x<prc->Width; x+=8) {
                         BYTE srcval;
@@ -177,21 +170,19 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
             IWICPalette *palette;
             UINT actualcolors;
 
-            if (source_format == format_2bppIndexed)
-            {
-                res = PaletteImpl_Create(&palette);
-                if (FAILED(res)) return res;
+            res = PaletteImpl_Create(&palette);
+            if (FAILED(res)) return res;
 
+            if (source_format == format_2bppIndexed)
                 res = IWICBitmapSource_CopyPalette(This->source, palette);
-                if (SUCCEEDED(res))
-                    res = IWICPalette_GetColors(palette, 4, colors, &actualcolors);
+            else
+                res = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray4, FALSE);
 
-                IWICPalette_Release(palette);
+            if (SUCCEEDED(res))
+                res = IWICPalette_GetColors(palette, 4, colors, &actualcolors);
 
-                if (FAILED(res)) return res;
-            }
-            else
-                make_grayscale_palette(colors, 4);
+            IWICPalette_Release(palette);
+            if (FAILED(res)) return res;
 
             srcstride = (prc->Width+3)/4;
             srcdatasize = srcstride * prc->Height;
@@ -206,7 +197,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
                 srcrow = srcdata;
                 dstrow = pbBuffer;
                 for (y=0; y<prc->Height; y++) {
-                    srcbyte=(const BYTE*)srcrow;
+                    srcbyte = srcrow;
                     dstpixel=(DWORD*)dstrow;
                     for (x=0; x<prc->Width; x+=4) {
                         BYTE srcval;
@@ -242,21 +233,19 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
             IWICPalette *palette;
             UINT actualcolors;
 
-            if (source_format == format_4bppIndexed)
-            {
-                res = PaletteImpl_Create(&palette);
-                if (FAILED(res)) return res;
+            res = PaletteImpl_Create(&palette);
+            if (FAILED(res)) return res;
 
+            if (source_format == format_4bppIndexed)
                 res = IWICBitmapSource_CopyPalette(This->source, palette);
-                if (SUCCEEDED(res))
-                    res = IWICPalette_GetColors(palette, 16, colors, &actualcolors);
+            else
+                res = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray16, FALSE);
 
-                IWICPalette_Release(palette);
+            if (SUCCEEDED(res))
+                res = IWICPalette_GetColors(palette, 16, colors, &actualcolors);
 
-                if (FAILED(res)) return res;
-            }
-            else
-                make_grayscale_palette(colors, 16);
+            IWICPalette_Release(palette);
+            if (FAILED(res)) return res;
 
             srcstride = (prc->Width+1)/2;
             srcdatasize = srcstride * prc->Height;
@@ -271,7 +260,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
                 srcrow = srcdata;
                 dstrow = pbBuffer;
                 for (y=0; y<prc->Height; y++) {
-                    srcbyte=(const BYTE*)srcrow;
+                    srcbyte = srcrow;
                     dstpixel=(DWORD*)dstrow;
                     for (x=0; x<prc->Width; x+=2) {
                         BYTE srcval;
@@ -314,7 +303,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
                 srcrow = srcdata;
                 dstrow = pbBuffer;
                 for (y=0; y<prc->Height; y++) {
-                    srcbyte=(const BYTE*)srcrow;
+                    srcbyte = srcrow;
                     dstpixel=(DWORD*)dstrow;
                     for (x=0; x<prc->Width; x++)
                     {
@@ -370,7 +359,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
                 srcrow = srcdata;
                 dstrow = pbBuffer;
                 for (y=0; y<prc->Height; y++) {
-                    srcbyte=(const BYTE*)srcrow;
+                    srcbyte = srcrow;
                     dstpixel=(DWORD*)dstrow;
                     for (x=0; x<prc->Width; x++)
                         *dstpixel++ = colors[*srcbyte++];
@@ -409,7 +398,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
                 srcrow = srcdata;
                 dstrow = pbBuffer;
                 for (y=0; y<prc->Height; y++) {
-                    srcbyte=(const BYTE*)srcrow;
+                    srcbyte = srcrow;
                     dstpixel=(DWORD*)dstrow;
                     for (x=0; x<prc->Width; x++)
                     {
@@ -522,6 +511,54 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
             return res;
         }
         return S_OK;
+    case format_16bppBGRA5551:
+        if (prc)
+        {
+            HRESULT res;
+            UINT x, y;
+            BYTE *srcdata;
+            UINT srcstride, srcdatasize;
+            const BYTE *srcrow;
+            const WORD *srcpixel;
+            BYTE *dstrow;
+            DWORD *dstpixel;
+
+            srcstride = 2 * prc->Width;
+            srcdatasize = srcstride * prc->Height;
+
+            srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
+            if (!srcdata) return E_OUTOFMEMORY;
+
+            res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
+
+            if (SUCCEEDED(res))
+            {
+                srcrow = srcdata;
+                dstrow = pbBuffer;
+                for (y=0; y<prc->Height; y++) {
+                    srcpixel=(const WORD*)srcrow;
+                    dstpixel=(DWORD*)dstrow;
+                    for (x=0; x<prc->Width; x++) {
+                        WORD srcval;
+                        srcval=*srcpixel++;
+                        *dstpixel++=((srcval & 0x8000) ? 0xff000000 : 0) | /* alpha */
+                                    ((srcval << 9) & 0xf80000) | /* r */
+                                    ((srcval << 4) & 0x070000) | /* r - 3 bits */
+                                    ((srcval << 6) & 0x00f800) | /* g */
+                                    ((srcval << 1) & 0x000700) | /* g - 3 bits */
+                                    ((srcval << 3) & 0x0000f8) | /* b */
+                                    ((srcval >> 2) & 0x000007);  /* b - 3 bits */
+                    }
+                    srcrow += srcstride;
+                    dstrow += cbStride;
+                }
+            }
+
+            HeapFree(GetProcessHeap(), 0, srcdata);
+
+            return res;
+        }
+        return S_OK;
     case format_24bppBGR:
         if (prc)
         {
@@ -584,6 +621,28 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
         if (prc)
             return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
         return S_OK;
+    case format_32bppPBGRA:
+        if (prc)
+        {
+            HRESULT res;
+            UINT x, y;
+
+            res = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
+            if (FAILED(res)) return res;
+
+            for (y=0; y<prc->Height; y++)
+                for (x=0; x<prc->Width; x++)
+                {
+                    BYTE alpha = pbBuffer[cbStride*y+4*x+3];
+                    if (alpha != 0 && alpha != 255)
+                    {
+                        pbBuffer[cbStride*y+4*x] = pbBuffer[cbStride*y+4*x] * 255 / alpha;
+                        pbBuffer[cbStride*y+4*x+1] = pbBuffer[cbStride*y+4*x+1] * 255 / alpha;
+                        pbBuffer[cbStride*y+4*x+2] = pbBuffer[cbStride*y+4*x+2] * 255 / alpha;
+                    }
+                }
+        }
+        return S_OK;
     case format_48bppRGB:
         if (prc)
         {
@@ -673,6 +732,27 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
             return res;
         }
         return S_OK;
+    case format_32bppCMYK:
+        if (prc)
+        {
+            HRESULT res;
+            UINT x, y;
+
+            res = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
+            if (FAILED(res)) return res;
+
+            for (y=0; y<prc->Height; y++)
+                for (x=0; x<prc->Width; x++)
+                {
+                    BYTE *pixel = pbBuffer+cbStride*y+4*x;
+                    BYTE c=pixel[0], m=pixel[1], y=pixel[2], k=pixel[3];
+                    pixel[0] = (255-y)*(255-k)/255; /* blue */
+                    pixel[1] = (255-m)*(255-k)/255; /* green */
+                    pixel[2] = (255-c)*(255-k)/255; /* red */
+                    pixel[3] = 255; /* alpha */
+                }
+        }
+        return S_OK;
     default:
         return WINCODEC_ERR_UNSUPPORTEDOPERATION;
     }
@@ -685,6 +765,7 @@ static HRESULT copypixels_to_32bppBGR(struct FormatConverter *This, const WICRec
     {
     case format_32bppBGR:
     case format_32bppBGRA:
+    case format_32bppPBGRA:
         if (prc)
             return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
         return S_OK;
@@ -693,6 +774,39 @@ static HRESULT copypixels_to_32bppBGR(struct FormatConverter *This, const WICRec
     }
 }
 
+static HRESULT copypixels_to_32bppPBGRA(struct FormatConverter *This, const WICRect *prc,
+    UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
+{
+    HRESULT hr;
+
+    switch (source_format)
+    {
+    case format_32bppPBGRA:
+        if (prc)
+            return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
+        return S_OK;
+    default:
+        hr = copypixels_to_32bppBGRA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format);
+        if (SUCCEEDED(hr) && prc)
+        {
+            UINT x, y;
+
+            for (y=0; y<prc->Height; y++)
+                for (x=0; x<prc->Width; x++)
+                {
+                    BYTE alpha = pbBuffer[cbStride*y+4*x+3];
+                    if (alpha != 255)
+                    {
+                        pbBuffer[cbStride*y+4*x] = pbBuffer[cbStride*y+4*x] * alpha / 255;
+                        pbBuffer[cbStride*y+4*x+1] = pbBuffer[cbStride*y+4*x+1] * alpha / 255;
+                        pbBuffer[cbStride*y+4*x+2] = pbBuffer[cbStride*y+4*x+2] * alpha / 255;
+                    }
+                }
+        }
+        return hr;
+    }
+}
+
 static const struct pixelformatinfo supported_formats[] = {
     {format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL},
     {format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL},
@@ -705,11 +819,14 @@ static const struct pixelformatinfo supported_formats[] = {
     {format_16bppGray, &GUID_WICPixelFormat16bppGray, NULL},
     {format_16bppBGR555, &GUID_WICPixelFormat16bppBGR555, NULL},
     {format_16bppBGR565, &GUID_WICPixelFormat16bppBGR565, NULL},
+    {format_16bppBGRA5551, &GUID_WICPixelFormat16bppBGRA5551, NULL},
     {format_24bppBGR, &GUID_WICPixelFormat24bppBGR, NULL},
     {format_32bppBGR, &GUID_WICPixelFormat32bppBGR, copypixels_to_32bppBGR},
     {format_32bppBGRA, &GUID_WICPixelFormat32bppBGRA, copypixels_to_32bppBGRA},
+    {format_32bppPBGRA, &GUID_WICPixelFormat32bppPBGRA, copypixels_to_32bppPBGRA},
     {format_48bppRGB, &GUID_WICPixelFormat48bppRGB, NULL},
     {format_64bppRGBA, &GUID_WICPixelFormat64bppRGBA, NULL},
+    {format_32bppCMYK, &GUID_WICPixelFormat32bppCMYK, NULL},
     {0}
 };
 
@@ -726,7 +843,7 @@ static const struct pixelformatinfo *get_formatinfo(const WICPixelFormatGUID *fo
 static HRESULT WINAPI FormatConverter_QueryInterface(IWICFormatConverter *iface, REFIID iid,
     void **ppv)
 {
-    FormatConverter *This = (FormatConverter*)iface;
+    FormatConverter *This = impl_from_IWICFormatConverter(iface);
     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
 
     if (!ppv) return E_INVALIDARG;
@@ -735,7 +852,7 @@ static HRESULT WINAPI FormatConverter_QueryInterface(IWICFormatConverter *iface,
         IsEqualIID(&IID_IWICBitmapSource, iid) ||
         IsEqualIID(&IID_IWICFormatConverter, iid))
     {
-        *ppv = This;
+        *ppv = &This->IWICFormatConverter_iface;
     }
     else
     {
@@ -749,7 +866,7 @@ static HRESULT WINAPI FormatConverter_QueryInterface(IWICFormatConverter *iface,
 
 static ULONG WINAPI FormatConverter_AddRef(IWICFormatConverter *iface)
 {
-    FormatConverter *This = (FormatConverter*)iface;
+    FormatConverter *This = impl_from_IWICFormatConverter(iface);
     ULONG ref = InterlockedIncrement(&This->ref);
 
     TRACE("(%p) refcount=%u\n", iface, ref);
@@ -759,7 +876,7 @@ static ULONG WINAPI FormatConverter_AddRef(IWICFormatConverter *iface)
 
 static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface)
 {
-    FormatConverter *This = (FormatConverter*)iface;
+    FormatConverter *This = impl_from_IWICFormatConverter(iface);
     ULONG ref = InterlockedDecrement(&This->ref);
 
     TRACE("(%p) refcount=%u\n", iface, ref);
@@ -778,7 +895,7 @@ static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface)
 static HRESULT WINAPI FormatConverter_GetSize(IWICFormatConverter *iface,
     UINT *puiWidth, UINT *puiHeight)
 {
-    FormatConverter *This = (FormatConverter*)iface;
+    FormatConverter *This = impl_from_IWICFormatConverter(iface);
 
     TRACE("(%p,%p,%p)\n", iface, puiWidth, puiHeight);
 
@@ -791,7 +908,7 @@ static HRESULT WINAPI FormatConverter_GetSize(IWICFormatConverter *iface,
 static HRESULT WINAPI FormatConverter_GetPixelFormat(IWICFormatConverter *iface,
     WICPixelFormatGUID *pPixelFormat)
 {
-    FormatConverter *This = (FormatConverter*)iface;
+    FormatConverter *This = impl_from_IWICFormatConverter(iface);
 
     TRACE("(%p,%p): stub\n", iface, pPixelFormat);
 
@@ -806,7 +923,7 @@ static HRESULT WINAPI FormatConverter_GetPixelFormat(IWICFormatConverter *iface,
 static HRESULT WINAPI FormatConverter_GetResolution(IWICFormatConverter *iface,
     double *pDpiX, double *pDpiY)
 {
-    FormatConverter *This = (FormatConverter*)iface;
+    FormatConverter *This = impl_from_IWICFormatConverter(iface);
 
     TRACE("(%p,%p,%p): stub\n", iface, pDpiX, pDpiY);
 
@@ -826,12 +943,28 @@ static HRESULT WINAPI FormatConverter_CopyPalette(IWICFormatConverter *iface,
 static HRESULT WINAPI FormatConverter_CopyPixels(IWICFormatConverter *iface,
     const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
 {
-    FormatConverter *This = (FormatConverter*)iface;
+    FormatConverter *This = impl_from_IWICFormatConverter(iface);
+    WICRect rc;
+    HRESULT hr;
     TRACE("(%p,%p,%u,%u,%p)\n", iface, prc, cbStride, cbBufferSize, pbBuffer);
 
     if (This->source)
+    {
+        if (!prc)
+        {
+            UINT width, height;
+            hr = IWICBitmapSource_GetSize(This->source, &width, &height);
+            if (FAILED(hr)) return hr;
+            rc.X = 0;
+            rc.Y = 0;
+            rc.Width = width;
+            rc.Height = height;
+            prc = &rc;
+        }
+
         return This->dst_format->copy_function(This, prc, cbStride, cbBufferSize,
             pbBuffer, This->src_format->format);
+    }
     else
         return WINCODEC_ERR_NOTINITIALIZED;
 }
@@ -840,7 +973,7 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
     IWICBitmapSource *pISource, REFWICPixelFormatGUID dstFormat, WICBitmapDitherType dither,
     IWICPalette *pIPalette, double alphaThresholdPercent, WICBitmapPaletteType paletteTranslate)
 {
-    FormatConverter *This = (FormatConverter*)iface;
+    FormatConverter *This = impl_from_IWICFormatConverter(iface);
     const struct pixelformatinfo *srcinfo, *dstinfo;
     static INT fixme=0;
     GUID srcFormat;
@@ -866,6 +999,7 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
     if (!srcinfo)
     {
         res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+        FIXME("Unsupported source format %s\n", debugstr_guid(&srcFormat));
         goto end;
     }
 
@@ -873,6 +1007,7 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
     if (!dstinfo)
     {
         res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+        FIXME("Unsupported destination format %s\n", debugstr_guid(dstFormat));
         goto end;
     }
 
@@ -887,7 +1022,10 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
         This->source = pISource;
     }
     else
+    {
+        FIXME("Unsupported conversion %s -> %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat));
         res = WINCODEC_ERR_UNSUPPORTEDOPERATION;
+    }
 
 end:
 
@@ -900,23 +1038,34 @@ static HRESULT WINAPI FormatConverter_CanConvert(IWICFormatConverter *iface,
     REFWICPixelFormatGUID srcPixelFormat, REFWICPixelFormatGUID dstPixelFormat,
     BOOL *pfCanConvert)
 {
-    FormatConverter *This = (FormatConverter*)iface;
+    FormatConverter *This = impl_from_IWICFormatConverter(iface);
     const struct pixelformatinfo *srcinfo, *dstinfo;
 
     TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(srcPixelFormat),
         debugstr_guid(dstPixelFormat), pfCanConvert);
 
     srcinfo = get_formatinfo(srcPixelFormat);
-    if (!srcinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+    if (!srcinfo)
+    {
+        FIXME("Unsupported source format %s\n", debugstr_guid(srcPixelFormat));
+        return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+    }
 
     dstinfo = get_formatinfo(dstPixelFormat);
-    if (!dstinfo) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+    if (!dstinfo)
+    {
+        FIXME("Unsupported destination format %s\n", debugstr_guid(dstPixelFormat));
+        return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+    }
 
     if (dstinfo->copy_function &&
         SUCCEEDED(dstinfo->copy_function(This, NULL, 0, 0, NULL, dstinfo->format)))
         *pfCanConvert = TRUE;
     else
+    {
+        FIXME("Unsupported conversion %s -> %s\n", debugstr_guid(srcPixelFormat), debugstr_guid(dstPixelFormat));
         *pfCanConvert = FALSE;
+    }
 
     return S_OK;
 }
@@ -948,14 +1097,14 @@ HRESULT FormatConverter_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** p
     This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverter));
     if (!This) return E_OUTOFMEMORY;
 
-    This->lpVtbl = &FormatConverter_Vtbl;
+    This->IWICFormatConverter_iface.lpVtbl = &FormatConverter_Vtbl;
     This->ref = 1;
     This->source = NULL;
     InitializeCriticalSection(&This->lock);
     This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FormatConverter.lock");
 
-    ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
-    IUnknown_Release((IUnknown*)This);
+    ret = IWICFormatConverter_QueryInterface(&This->IWICFormatConverter_iface, iid, ppv);
+    IWICFormatConverter_Release(&This->IWICFormatConverter_iface);
 
     return ret;
 }