2 * Copyright 2009 Vincent Povirk
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "wincodecs_private.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
36 struct FormatConverter
;
57 typedef HRESULT (*copyfunc
)(struct FormatConverter
*This
, const WICRect
*prc
,
58 UINT cbStride
, UINT cbBufferSize
, BYTE
*pbBuffer
, enum pixelformat source_format
);
60 struct pixelformatinfo
{
61 enum pixelformat format
;
62 const WICPixelFormatGUID
*guid
;
63 copyfunc copy_function
;
66 typedef struct FormatConverter
{
67 const IWICFormatConverterVtbl
*lpVtbl
;
69 IWICBitmapSource
*source
;
70 const struct pixelformatinfo
*dst_format
, *src_format
;
71 WICBitmapDitherType dither
;
72 double alpha_threshold
;
73 WICBitmapPaletteType palette_type
;
76 static void make_grayscale_palette(WICColor
*colors
, UINT num_colors
)
79 for (i
=0; i
<num_colors
; i
++)
81 v
= i
* 255 / (num_colors
-1);
82 colors
[i
] = 0xff000000 | v
<<16 | v
<<8 | v
;
86 static HRESULT
copypixels_to_32bppBGRA(struct FormatConverter
*This
, const WICRect
*prc
,
87 UINT cbStride
, UINT cbBufferSize
, BYTE
*pbBuffer
, enum pixelformat source_format
)
89 switch (source_format
)
91 case format_1bppIndexed
:
92 case format_BlackWhite
:
98 UINT srcstride
, srcdatasize
;
104 IWICPalette
*palette
;
107 if (source_format
== format_1bppIndexed
)
109 res
= PaletteImpl_Create(&palette
);
110 if (FAILED(res
)) return res
;
112 res
= IWICBitmapSource_CopyPalette(This
->source
, palette
);
114 res
= IWICPalette_GetColors(palette
, 2, colors
, &actualcolors
);
116 IWICPalette_Release(palette
);
118 if (FAILED(res
)) return res
;
122 colors
[0] = 0xff000000;
123 colors
[1] = 0xffffffff;
126 srcstride
= (prc
->Width
+7)/8;
127 srcdatasize
= srcstride
* prc
->Height
;
129 srcdata
= HeapAlloc(GetProcessHeap(), 0, srcdatasize
);
130 if (!srcdata
) return E_OUTOFMEMORY
;
132 res
= IWICBitmapSource_CopyPixels(This
->source
, prc
, srcstride
, srcdatasize
, srcdata
);
138 for (y
=0; y
<prc
->Height
; y
++) {
139 srcbyte
=(const BYTE
*)srcrow
;
140 dstpixel
=(DWORD
*)dstrow
;
141 for (x
=0; x
<prc
->Width
; x
+=8) {
144 *dstpixel
++ = colors
[srcval
>>7&1];
145 if (x
+1 < prc
->Width
) *dstpixel
++ = colors
[srcval
>>6&1];
146 if (x
+2 < prc
->Width
) *dstpixel
++ = colors
[srcval
>>5&1];
147 if (x
+3 < prc
->Width
) *dstpixel
++ = colors
[srcval
>>4&1];
148 if (x
+4 < prc
->Width
) *dstpixel
++ = colors
[srcval
>>3&1];
149 if (x
+5 < prc
->Width
) *dstpixel
++ = colors
[srcval
>>2&1];
150 if (x
+6 < prc
->Width
) *dstpixel
++ = colors
[srcval
>>1&1];
151 if (x
+7 < prc
->Width
) *dstpixel
++ = colors
[srcval
&1];
158 HeapFree(GetProcessHeap(), 0, srcdata
);
163 case format_2bppIndexed
:
164 case format_2bppGray
:
170 UINT srcstride
, srcdatasize
;
176 IWICPalette
*palette
;
179 if (source_format
== format_2bppIndexed
)
181 res
= PaletteImpl_Create(&palette
);
182 if (FAILED(res
)) return res
;
184 res
= IWICBitmapSource_CopyPalette(This
->source
, palette
);
186 res
= IWICPalette_GetColors(palette
, 4, colors
, &actualcolors
);
188 IWICPalette_Release(palette
);
190 if (FAILED(res
)) return res
;
193 make_grayscale_palette(colors
, 4);
195 srcstride
= (prc
->Width
+3)/4;
196 srcdatasize
= srcstride
* prc
->Height
;
198 srcdata
= HeapAlloc(GetProcessHeap(), 0, srcdatasize
);
199 if (!srcdata
) return E_OUTOFMEMORY
;
201 res
= IWICBitmapSource_CopyPixels(This
->source
, prc
, srcstride
, srcdatasize
, srcdata
);
207 for (y
=0; y
<prc
->Height
; y
++) {
208 srcbyte
=(const BYTE
*)srcrow
;
209 dstpixel
=(DWORD
*)dstrow
;
210 for (x
=0; x
<prc
->Width
; x
+=4) {
213 *dstpixel
++ = colors
[srcval
>>6];
214 if (x
+1 < prc
->Width
) *dstpixel
++ = colors
[srcval
>>4&0x3];
215 if (x
+2 < prc
->Width
) *dstpixel
++ = colors
[srcval
>>2&0x3];
216 if (x
+1 < prc
->Width
) *dstpixel
++ = colors
[srcval
&0x3];
223 HeapFree(GetProcessHeap(), 0, srcdata
);
228 case format_4bppIndexed
:
229 case format_4bppGray
:
235 UINT srcstride
, srcdatasize
;
241 IWICPalette
*palette
;
244 if (source_format
== format_4bppIndexed
)
246 res
= PaletteImpl_Create(&palette
);
247 if (FAILED(res
)) return res
;
249 res
= IWICBitmapSource_CopyPalette(This
->source
, palette
);
251 res
= IWICPalette_GetColors(palette
, 16, colors
, &actualcolors
);
253 IWICPalette_Release(palette
);
255 if (FAILED(res
)) return res
;
258 make_grayscale_palette(colors
, 16);
260 srcstride
= (prc
->Width
+1)/2;
261 srcdatasize
= srcstride
* prc
->Height
;
263 srcdata
= HeapAlloc(GetProcessHeap(), 0, srcdatasize
);
264 if (!srcdata
) return E_OUTOFMEMORY
;
266 res
= IWICBitmapSource_CopyPixels(This
->source
, prc
, srcstride
, srcdatasize
, srcdata
);
272 for (y
=0; y
<prc
->Height
; y
++) {
273 srcbyte
=(const BYTE
*)srcrow
;
274 dstpixel
=(DWORD
*)dstrow
;
275 for (x
=0; x
<prc
->Width
; x
+=2) {
278 *dstpixel
++ = colors
[srcval
>>4];
279 if (x
+1 < prc
->Width
) *dstpixel
++ = colors
[srcval
&0xf];
286 HeapFree(GetProcessHeap(), 0, srcdata
);
291 case format_8bppGray
:
297 UINT srcstride
, srcdatasize
;
303 srcstride
= prc
->Width
;
304 srcdatasize
= srcstride
* prc
->Height
;
306 srcdata
= HeapAlloc(GetProcessHeap(), 0, srcdatasize
);
307 if (!srcdata
) return E_OUTOFMEMORY
;
309 res
= IWICBitmapSource_CopyPixels(This
->source
, prc
, srcstride
, srcdatasize
, srcdata
);
315 for (y
=0; y
<prc
->Height
; y
++) {
316 srcbyte
=(const BYTE
*)srcrow
;
317 dstpixel
=(DWORD
*)dstrow
;
318 for (x
=0; x
<prc
->Width
; x
++)
320 *dstpixel
++ = 0xff000000|(*srcbyte
<<16)|(*srcbyte
<<8)|*srcbyte
;
328 HeapFree(GetProcessHeap(), 0, srcdata
);
333 case format_8bppIndexed
:
339 UINT srcstride
, srcdatasize
;
344 WICColor colors
[256];
345 IWICPalette
*palette
;
348 res
= PaletteImpl_Create(&palette
);
349 if (FAILED(res
)) return res
;
351 res
= IWICBitmapSource_CopyPalette(This
->source
, palette
);
353 res
= IWICPalette_GetColors(palette
, 256, colors
, &actualcolors
);
355 IWICPalette_Release(palette
);
357 if (FAILED(res
)) return res
;
359 srcstride
= prc
->Width
;
360 srcdatasize
= srcstride
* prc
->Height
;
362 srcdata
= HeapAlloc(GetProcessHeap(), 0, srcdatasize
);
363 if (!srcdata
) return E_OUTOFMEMORY
;
365 res
= IWICBitmapSource_CopyPixels(This
->source
, prc
, srcstride
, srcdatasize
, srcdata
);
371 for (y
=0; y
<prc
->Height
; y
++) {
372 srcbyte
=(const BYTE
*)srcrow
;
373 dstpixel
=(DWORD
*)dstrow
;
374 for (x
=0; x
<prc
->Width
; x
++)
375 *dstpixel
++ = colors
[*srcbyte
++];
381 HeapFree(GetProcessHeap(), 0, srcdata
);
386 case format_16bppGray
:
392 UINT srcstride
, srcdatasize
;
398 srcstride
= prc
->Width
* 2;
399 srcdatasize
= srcstride
* prc
->Height
;
401 srcdata
= HeapAlloc(GetProcessHeap(), 0, srcdatasize
);
402 if (!srcdata
) return E_OUTOFMEMORY
;
404 res
= IWICBitmapSource_CopyPixels(This
->source
, prc
, srcstride
, srcdatasize
, srcdata
);
410 for (y
=0; y
<prc
->Height
; y
++) {
411 srcbyte
=(const BYTE
*)srcrow
;
412 dstpixel
=(DWORD
*)dstrow
;
413 for (x
=0; x
<prc
->Width
; x
++)
415 *dstpixel
++ = 0xff000000|(*srcbyte
<<16)|(*srcbyte
<<8)|*srcbyte
;
423 HeapFree(GetProcessHeap(), 0, srcdata
);
428 case format_16bppBGR555
:
434 UINT srcstride
, srcdatasize
;
436 const WORD
*srcpixel
;
440 srcstride
= 2 * prc
->Width
;
441 srcdatasize
= srcstride
* prc
->Height
;
443 srcdata
= HeapAlloc(GetProcessHeap(), 0, srcdatasize
);
444 if (!srcdata
) return E_OUTOFMEMORY
;
446 res
= IWICBitmapSource_CopyPixels(This
->source
, prc
, srcstride
, srcdatasize
, srcdata
);
452 for (y
=0; y
<prc
->Height
; y
++) {
453 srcpixel
=(const WORD
*)srcrow
;
454 dstpixel
=(DWORD
*)dstrow
;
455 for (x
=0; x
<prc
->Width
; x
++) {
458 *dstpixel
++=0xff000000 | /* constant 255 alpha */
459 ((srcval
<< 9) & 0xf80000) | /* r */
460 ((srcval
<< 4) & 0x070000) | /* r - 3 bits */
461 ((srcval
<< 6) & 0x00f800) | /* g */
462 ((srcval
<< 1) & 0x000700) | /* g - 3 bits */
463 ((srcval
<< 3) & 0x0000f8) | /* b */
464 ((srcval
>> 2) & 0x000007); /* b - 3 bits */
471 HeapFree(GetProcessHeap(), 0, srcdata
);
476 case format_16bppBGR565
:
482 UINT srcstride
, srcdatasize
;
484 const WORD
*srcpixel
;
488 srcstride
= 2 * prc
->Width
;
489 srcdatasize
= srcstride
* prc
->Height
;
491 srcdata
= HeapAlloc(GetProcessHeap(), 0, srcdatasize
);
492 if (!srcdata
) return E_OUTOFMEMORY
;
494 res
= IWICBitmapSource_CopyPixels(This
->source
, prc
, srcstride
, srcdatasize
, srcdata
);
500 for (y
=0; y
<prc
->Height
; y
++) {
501 srcpixel
=(const WORD
*)srcrow
;
502 dstpixel
=(DWORD
*)dstrow
;
503 for (x
=0; x
<prc
->Width
; x
++) {
506 *dstpixel
++=0xff000000 | /* constant 255 alpha */
507 ((srcval
<< 8) & 0xf80000) | /* r */
508 ((srcval
<< 3) & 0x070000) | /* r - 3 bits */
509 ((srcval
<< 5) & 0x00fc00) | /* g */
510 ((srcval
>> 1) & 0x000300) | /* g - 2 bits */
511 ((srcval
<< 3) & 0x0000f8) | /* b */
512 ((srcval
>> 2) & 0x000007); /* b - 3 bits */
519 HeapFree(GetProcessHeap(), 0, srcdata
);
524 case format_24bppBGR
:
530 UINT srcstride
, srcdatasize
;
532 const BYTE
*srcpixel
;
536 srcstride
= 3 * prc
->Width
;
537 srcdatasize
= srcstride
* prc
->Height
;
539 srcdata
= HeapAlloc(GetProcessHeap(), 0, srcdatasize
);
540 if (!srcdata
) return E_OUTOFMEMORY
;
542 res
= IWICBitmapSource_CopyPixels(This
->source
, prc
, srcstride
, srcdatasize
, srcdata
);
548 for (y
=0; y
<prc
->Height
; y
++) {
551 for (x
=0; x
<prc
->Width
; x
++) {
552 *dstpixel
++=*srcpixel
++; /* blue */
553 *dstpixel
++=*srcpixel
++; /* green */
554 *dstpixel
++=*srcpixel
++; /* red */
555 *dstpixel
++=255; /* alpha */
562 HeapFree(GetProcessHeap(), 0, srcdata
);
567 case format_32bppBGR
:
573 res
= IWICBitmapSource_CopyPixels(This
->source
, prc
, cbStride
, cbBufferSize
, pbBuffer
);
574 if (FAILED(res
)) return res
;
576 /* set all alpha values to 255 */
577 for (y
=0; y
<prc
->Height
; y
++)
578 for (x
=0; x
<prc
->Width
; x
++)
579 pbBuffer
[cbStride
*y
+4*x
+3] = 0xff;
582 case format_32bppBGRA
:
584 return IWICBitmapSource_CopyPixels(This
->source
, prc
, cbStride
, cbBufferSize
, pbBuffer
);
586 case format_48bppRGB
:
592 UINT srcstride
, srcdatasize
;
594 const BYTE
*srcpixel
;
598 srcstride
= 6 * prc
->Width
;
599 srcdatasize
= srcstride
* prc
->Height
;
601 srcdata
= HeapAlloc(GetProcessHeap(), 0, srcdatasize
);
602 if (!srcdata
) return E_OUTOFMEMORY
;
604 res
= IWICBitmapSource_CopyPixels(This
->source
, prc
, srcstride
, srcdatasize
, srcdata
);
610 for (y
=0; y
<prc
->Height
; y
++) {
612 dstpixel
=(DWORD
*)dstrow
;
613 for (x
=0; x
<prc
->Width
; x
++) {
614 BYTE red
, green
, blue
;
615 red
= *srcpixel
++; srcpixel
++;
616 green
= *srcpixel
++; srcpixel
++;
617 blue
= *srcpixel
++; srcpixel
++;
618 *dstpixel
++=0xff000000|red
<<16|green
<<8|blue
;
625 HeapFree(GetProcessHeap(), 0, srcdata
);
630 case format_64bppRGBA
:
636 UINT srcstride
, srcdatasize
;
638 const BYTE
*srcpixel
;
642 srcstride
= 8 * prc
->Width
;
643 srcdatasize
= srcstride
* prc
->Height
;
645 srcdata
= HeapAlloc(GetProcessHeap(), 0, srcdatasize
);
646 if (!srcdata
) return E_OUTOFMEMORY
;
648 res
= IWICBitmapSource_CopyPixels(This
->source
, prc
, srcstride
, srcdatasize
, srcdata
);
654 for (y
=0; y
<prc
->Height
; y
++) {
656 dstpixel
=(DWORD
*)dstrow
;
657 for (x
=0; x
<prc
->Width
; x
++) {
658 BYTE red
, green
, blue
, alpha
;
659 red
= *srcpixel
++; srcpixel
++;
660 green
= *srcpixel
++; srcpixel
++;
661 blue
= *srcpixel
++; srcpixel
++;
662 alpha
= *srcpixel
++; srcpixel
++;
663 *dstpixel
++=alpha
<<24|red
<<16|green
<<8|blue
;
670 HeapFree(GetProcessHeap(), 0, srcdata
);
676 return WINCODEC_ERR_UNSUPPORTEDOPERATION
;
680 static HRESULT
copypixels_to_32bppBGR(struct FormatConverter
*This
, const WICRect
*prc
,
681 UINT cbStride
, UINT cbBufferSize
, BYTE
*pbBuffer
, enum pixelformat source_format
)
683 switch (source_format
)
685 case format_32bppBGR
:
686 case format_32bppBGRA
:
688 return IWICBitmapSource_CopyPixels(This
->source
, prc
, cbStride
, cbBufferSize
, pbBuffer
);
691 return copypixels_to_32bppBGRA(This
, prc
, cbStride
, cbBufferSize
, pbBuffer
, source_format
);
695 static const struct pixelformatinfo supported_formats
[] = {
696 {format_1bppIndexed
, &GUID_WICPixelFormat1bppIndexed
, NULL
},
697 {format_2bppIndexed
, &GUID_WICPixelFormat2bppIndexed
, NULL
},
698 {format_4bppIndexed
, &GUID_WICPixelFormat4bppIndexed
, NULL
},
699 {format_8bppIndexed
, &GUID_WICPixelFormat8bppIndexed
, NULL
},
700 {format_BlackWhite
, &GUID_WICPixelFormatBlackWhite
, NULL
},
701 {format_2bppGray
, &GUID_WICPixelFormat2bppGray
, NULL
},
702 {format_4bppGray
, &GUID_WICPixelFormat4bppGray
, NULL
},
703 {format_8bppGray
, &GUID_WICPixelFormat8bppGray
, NULL
},
704 {format_16bppGray
, &GUID_WICPixelFormat16bppGray
, NULL
},
705 {format_16bppBGR555
, &GUID_WICPixelFormat16bppBGR555
, NULL
},
706 {format_16bppBGR565
, &GUID_WICPixelFormat16bppBGR565
, NULL
},
707 {format_24bppBGR
, &GUID_WICPixelFormat24bppBGR
, NULL
},
708 {format_32bppBGR
, &GUID_WICPixelFormat32bppBGR
, copypixels_to_32bppBGR
},
709 {format_32bppBGRA
, &GUID_WICPixelFormat32bppBGRA
, copypixels_to_32bppBGRA
},
710 {format_48bppRGB
, &GUID_WICPixelFormat48bppRGB
, NULL
},
711 {format_64bppRGBA
, &GUID_WICPixelFormat64bppRGBA
, NULL
},
715 static const struct pixelformatinfo
*get_formatinfo(const WICPixelFormatGUID
*format
)
719 for (i
=0; supported_formats
[i
].guid
; i
++)
720 if (IsEqualGUID(supported_formats
[i
].guid
, format
)) return &supported_formats
[i
];
725 static HRESULT WINAPI
FormatConverter_QueryInterface(IWICFormatConverter
*iface
, REFIID iid
,
728 FormatConverter
*This
= (FormatConverter
*)iface
;
729 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
731 if (!ppv
) return E_INVALIDARG
;
733 if (IsEqualIID(&IID_IUnknown
, iid
) ||
734 IsEqualIID(&IID_IWICBitmapSource
, iid
) ||
735 IsEqualIID(&IID_IWICFormatConverter
, iid
))
742 return E_NOINTERFACE
;
745 IUnknown_AddRef((IUnknown
*)*ppv
);
749 static ULONG WINAPI
FormatConverter_AddRef(IWICFormatConverter
*iface
)
751 FormatConverter
*This
= (FormatConverter
*)iface
;
752 ULONG ref
= InterlockedIncrement(&This
->ref
);
754 TRACE("(%p) refcount=%u\n", iface
, ref
);
759 static ULONG WINAPI
FormatConverter_Release(IWICFormatConverter
*iface
)
761 FormatConverter
*This
= (FormatConverter
*)iface
;
762 ULONG ref
= InterlockedDecrement(&This
->ref
);
764 TRACE("(%p) refcount=%u\n", iface
, ref
);
768 if (This
->source
) IWICBitmapSource_Release(This
->source
);
769 HeapFree(GetProcessHeap(), 0, This
);
775 static HRESULT WINAPI
FormatConverter_GetSize(IWICFormatConverter
*iface
,
776 UINT
*puiWidth
, UINT
*puiHeight
)
778 FormatConverter
*This
= (FormatConverter
*)iface
;
780 TRACE("(%p,%p,%p)\n", iface
, puiWidth
, puiHeight
);
783 return IWICBitmapSource_GetSize(This
->source
, puiWidth
, puiHeight
);
785 return WINCODEC_ERR_NOTINITIALIZED
;
788 static HRESULT WINAPI
FormatConverter_GetPixelFormat(IWICFormatConverter
*iface
,
789 WICPixelFormatGUID
*pPixelFormat
)
791 FormatConverter
*This
= (FormatConverter
*)iface
;
793 TRACE("(%p,%p): stub\n", iface
, pPixelFormat
);
796 memcpy(pPixelFormat
, This
->dst_format
->guid
, sizeof(GUID
));
798 return WINCODEC_ERR_NOTINITIALIZED
;
803 static HRESULT WINAPI
FormatConverter_GetResolution(IWICFormatConverter
*iface
,
804 double *pDpiX
, double *pDpiY
)
806 FormatConverter
*This
= (FormatConverter
*)iface
;
808 TRACE("(%p,%p,%p): stub\n", iface
, pDpiX
, pDpiY
);
811 return IWICBitmapSource_GetResolution(This
->source
, pDpiX
, pDpiY
);
813 return WINCODEC_ERR_NOTINITIALIZED
;
816 static HRESULT WINAPI
FormatConverter_CopyPalette(IWICFormatConverter
*iface
,
817 IWICPalette
*pIPalette
)
819 FIXME("(%p,%p): stub\n", iface
, pIPalette
);
823 static HRESULT WINAPI
FormatConverter_CopyPixels(IWICFormatConverter
*iface
,
824 const WICRect
*prc
, UINT cbStride
, UINT cbBufferSize
, BYTE
*pbBuffer
)
826 FormatConverter
*This
= (FormatConverter
*)iface
;
827 TRACE("(%p,%p,%u,%u,%p)\n", iface
, prc
, cbStride
, cbBufferSize
, pbBuffer
);
830 return This
->dst_format
->copy_function(This
, prc
, cbStride
, cbBufferSize
,
831 pbBuffer
, This
->src_format
->format
);
833 return WINCODEC_ERR_NOTINITIALIZED
;
836 static HRESULT WINAPI
FormatConverter_Initialize(IWICFormatConverter
*iface
,
837 IWICBitmapSource
*pISource
, REFWICPixelFormatGUID dstFormat
, WICBitmapDitherType dither
,
838 IWICPalette
*pIPalette
, double alphaThresholdPercent
, WICBitmapPaletteType paletteTranslate
)
840 FormatConverter
*This
= (FormatConverter
*)iface
;
841 const struct pixelformatinfo
*srcinfo
, *dstinfo
;
846 TRACE("(%p,%p,%s,%u,%p,%0.1f,%u)\n", iface
, pISource
, debugstr_guid(dstFormat
),
847 dither
, pIPalette
, alphaThresholdPercent
, paletteTranslate
);
849 if (pIPalette
&& !fixme
++) FIXME("ignoring palette\n");
851 if (This
->source
) return WINCODEC_ERR_WRONGSTATE
;
853 res
= IWICBitmapSource_GetPixelFormat(pISource
, &srcFormat
);
854 if (FAILED(res
)) return res
;
856 srcinfo
= get_formatinfo(&srcFormat
);
857 if (!srcinfo
) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT
;
859 dstinfo
= get_formatinfo(dstFormat
);
860 if (!dstinfo
) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT
;
862 if (dstinfo
->copy_function
)
864 IWICBitmapSource_AddRef(pISource
);
865 This
->source
= pISource
;
866 This
->src_format
= srcinfo
;
867 This
->dst_format
= dstinfo
;
868 This
->dither
= dither
;
869 This
->alpha_threshold
= alphaThresholdPercent
;
870 This
->palette_type
= paletteTranslate
;
873 return WINCODEC_ERR_UNSUPPORTEDOPERATION
;
878 static HRESULT WINAPI
FormatConverter_CanConvert(IWICFormatConverter
*iface
,
879 REFWICPixelFormatGUID srcPixelFormat
, REFWICPixelFormatGUID dstPixelFormat
,
882 FormatConverter
*This
= (FormatConverter
*)iface
;
883 const struct pixelformatinfo
*srcinfo
, *dstinfo
;
885 TRACE("(%p,%s,%s,%p)\n", iface
, debugstr_guid(srcPixelFormat
),
886 debugstr_guid(dstPixelFormat
), pfCanConvert
);
888 srcinfo
= get_formatinfo(srcPixelFormat
);
889 if (!srcinfo
) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT
;
891 dstinfo
= get_formatinfo(dstPixelFormat
);
892 if (!dstinfo
) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT
;
894 if (dstinfo
->copy_function
&&
895 SUCCEEDED(dstinfo
->copy_function(This
, NULL
, 0, 0, NULL
, dstinfo
->format
)))
896 *pfCanConvert
= TRUE
;
898 *pfCanConvert
= FALSE
;
903 static const IWICFormatConverterVtbl FormatConverter_Vtbl
= {
904 FormatConverter_QueryInterface
,
905 FormatConverter_AddRef
,
906 FormatConverter_Release
,
907 FormatConverter_GetSize
,
908 FormatConverter_GetPixelFormat
,
909 FormatConverter_GetResolution
,
910 FormatConverter_CopyPalette
,
911 FormatConverter_CopyPixels
,
912 FormatConverter_Initialize
,
913 FormatConverter_CanConvert
916 HRESULT
FormatConverter_CreateInstance(IUnknown
*pUnkOuter
, REFIID iid
, void** ppv
)
918 FormatConverter
*This
;
921 TRACE("(%p,%s,%p)\n", pUnkOuter
, debugstr_guid(iid
), ppv
);
925 if (pUnkOuter
) return CLASS_E_NOAGGREGATION
;
927 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverter
));
928 if (!This
) return E_OUTOFMEMORY
;
930 This
->lpVtbl
= &FormatConverter_Vtbl
;
934 ret
= IUnknown_QueryInterface((IUnknown
*)This
, iid
, ppv
);
935 IUnknown_Release((IUnknown
*)This
);