2 * Copyright 2010 Damjan Jovanovic
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
20 #include "wine/port.h"
35 #include "wincodecs_private.h"
37 #include "wine/debug.h"
38 #include "wine/library.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
44 static void *libicns_handle
;
45 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
46 MAKE_FUNCPTR(icns_create_family
);
47 MAKE_FUNCPTR(icns_export_family_data
);
48 MAKE_FUNCPTR(icns_free_image
);
49 MAKE_FUNCPTR(icns_get_mask_type_for_icon_type
);
50 MAKE_FUNCPTR(icns_get_type_from_image_info
);
51 MAKE_FUNCPTR(icns_init_image_for_type
);
52 MAKE_FUNCPTR(icns_new_element_from_image
);
53 MAKE_FUNCPTR(icns_set_element_in_family
);
56 static void *load_libicns(void)
58 if((libicns_handle
= wine_dlopen(SONAME_LIBICNS
, RTLD_NOW
, NULL
, 0)) != NULL
) {
60 #define LOAD_FUNCPTR(f) \
61 if((p##f = wine_dlsym(libicns_handle, #f, NULL, 0)) == NULL) { \
62 libicns_handle = NULL; \
65 LOAD_FUNCPTR(icns_create_family
);
66 LOAD_FUNCPTR(icns_export_family_data
);
67 LOAD_FUNCPTR(icns_free_image
);
68 LOAD_FUNCPTR(icns_get_mask_type_for_icon_type
);
69 LOAD_FUNCPTR(icns_get_type_from_image_info
);
70 LOAD_FUNCPTR(icns_init_image_for_type
);
71 LOAD_FUNCPTR(icns_new_element_from_image
);
72 LOAD_FUNCPTR(icns_set_element_in_family
);
75 return libicns_handle
;
78 typedef struct IcnsEncoder
{
79 const IWICBitmapEncoderVtbl
*lpVtbl
;
82 icns_family_t
*icns_family
;
83 BOOL any_frame_committed
;
84 int outstanding_commits
;
86 CRITICAL_SECTION lock
;
89 typedef struct IcnsFrameEncode
{
90 const IWICBitmapFrameEncodeVtbl
*lpVtbl
;
96 icns_type_t icns_type
;
97 icns_image_t icns_image
;
102 static HRESULT WINAPI
IcnsFrameEncode_QueryInterface(IWICBitmapFrameEncode
*iface
, REFIID iid
,
105 IcnsFrameEncode
*This
= (IcnsFrameEncode
*)iface
;
106 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
108 if (!ppv
) return E_INVALIDARG
;
110 if (IsEqualIID(&IID_IUnknown
, iid
) ||
111 IsEqualIID(&IID_IWICBitmapFrameEncode
, iid
))
113 *ppv
= &This
->lpVtbl
;
118 return E_NOINTERFACE
;
121 IUnknown_AddRef((IUnknown
*)*ppv
);
125 static ULONG WINAPI
IcnsFrameEncode_AddRef(IWICBitmapFrameEncode
*iface
)
127 IcnsFrameEncode
*This
= (IcnsFrameEncode
*)iface
;
128 ULONG ref
= InterlockedIncrement(&This
->ref
);
130 TRACE("(%p) refcount=%u\n", iface
, ref
);
135 static ULONG WINAPI
IcnsFrameEncode_Release(IWICBitmapFrameEncode
*iface
)
137 IcnsFrameEncode
*This
= (IcnsFrameEncode
*)iface
;
138 ULONG ref
= InterlockedDecrement(&This
->ref
);
140 TRACE("(%p) refcount=%u\n", iface
, ref
);
144 if (!This
->committed
)
146 EnterCriticalSection(&This
->encoder
->lock
);
147 This
->encoder
->outstanding_commits
--;
148 LeaveCriticalSection(&This
->encoder
->lock
);
150 if (This
->icns_image
.imageData
!= NULL
)
151 picns_free_image(&This
->icns_image
);
153 IUnknown_Release((IUnknown
*)This
->encoder
);
154 HeapFree(GetProcessHeap(), 0, This
);
160 static HRESULT WINAPI
IcnsFrameEncode_Initialize(IWICBitmapFrameEncode
*iface
,
161 IPropertyBag2
*pIEncoderOptions
)
163 IcnsFrameEncode
*This
= (IcnsFrameEncode
*)iface
;
166 TRACE("(%p,%p)\n", iface
, pIEncoderOptions
);
168 EnterCriticalSection(&This
->encoder
->lock
);
170 if (This
->initialized
)
172 hr
= WINCODEC_ERR_WRONGSTATE
;
175 This
->initialized
= TRUE
;
178 LeaveCriticalSection(&This
->encoder
->lock
);
182 static HRESULT WINAPI
IcnsFrameEncode_SetSize(IWICBitmapFrameEncode
*iface
,
183 UINT uiWidth
, UINT uiHeight
)
185 IcnsFrameEncode
*This
= (IcnsFrameEncode
*)iface
;
188 TRACE("(%p,%u,%u)\n", iface
, uiWidth
, uiHeight
);
190 EnterCriticalSection(&This
->encoder
->lock
);
192 if (!This
->initialized
|| This
->icns_image
.imageData
)
194 hr
= WINCODEC_ERR_WRONGSTATE
;
198 This
->width
= uiWidth
;
199 This
->height
= uiHeight
;
202 LeaveCriticalSection(&This
->encoder
->lock
);
206 static HRESULT WINAPI
IcnsFrameEncode_SetResolution(IWICBitmapFrameEncode
*iface
,
207 double dpiX
, double dpiY
)
209 IcnsFrameEncode
*This
= (IcnsFrameEncode
*)iface
;
212 TRACE("(%p,%0.2f,%0.2f)\n", iface
, dpiX
, dpiY
);
214 EnterCriticalSection(&This
->encoder
->lock
);
216 if (!This
->initialized
|| This
->icns_image
.imageData
)
218 hr
= WINCODEC_ERR_WRONGSTATE
;
223 LeaveCriticalSection(&This
->encoder
->lock
);
227 static HRESULT WINAPI
IcnsFrameEncode_SetPixelFormat(IWICBitmapFrameEncode
*iface
,
228 WICPixelFormatGUID
*pPixelFormat
)
230 IcnsFrameEncode
*This
= (IcnsFrameEncode
*)iface
;
233 TRACE("(%p,%s)\n", iface
, debugstr_guid(pPixelFormat
));
235 EnterCriticalSection(&This
->encoder
->lock
);
237 if (!This
->initialized
|| This
->icns_image
.imageData
)
239 hr
= WINCODEC_ERR_WRONGSTATE
;
243 memcpy(pPixelFormat
, &GUID_WICPixelFormat32bppBGRA
, sizeof(GUID
));
246 LeaveCriticalSection(&This
->encoder
->lock
);
250 static HRESULT WINAPI
IcnsFrameEncode_SetColorContexts(IWICBitmapFrameEncode
*iface
,
251 UINT cCount
, IWICColorContext
**ppIColorContext
)
253 FIXME("(%p,%u,%p): stub\n", iface
, cCount
, ppIColorContext
);
257 static HRESULT WINAPI
IcnsFrameEncode_SetPalette(IWICBitmapFrameEncode
*iface
,
258 IWICPalette
*pIPalette
)
260 FIXME("(%p,%p): stub\n", iface
, pIPalette
);
261 return WINCODEC_ERR_UNSUPPORTEDOPERATION
;
264 static HRESULT WINAPI
IcnsFrameEncode_SetThumbnail(IWICBitmapFrameEncode
*iface
,
265 IWICBitmapSource
*pIThumbnail
)
267 FIXME("(%p,%p): stub\n", iface
, pIThumbnail
);
268 return WINCODEC_ERR_UNSUPPORTEDOPERATION
;
271 static HRESULT WINAPI
IcnsFrameEncode_WritePixels(IWICBitmapFrameEncode
*iface
,
272 UINT lineCount
, UINT cbStride
, UINT cbBufferSize
, BYTE
*pbPixels
)
274 IcnsFrameEncode
*This
= (IcnsFrameEncode
*)iface
;
279 TRACE("(%p,%u,%u,%u,%p)\n", iface
, lineCount
, cbStride
, cbBufferSize
, pbPixels
);
281 EnterCriticalSection(&This
->encoder
->lock
);
283 if (!This
->initialized
|| !This
->width
|| !This
->height
)
285 hr
= WINCODEC_ERR_WRONGSTATE
;
288 if (lineCount
== 0 || lineCount
+ This
->lines_written
> This
->height
)
294 if (!This
->icns_image
.imageData
)
296 icns_icon_info_t icns_info
;
297 icns_info
.isImage
= 1;
298 icns_info
.iconWidth
= This
->width
;
299 icns_info
.iconHeight
= This
->height
;
300 icns_info
.iconBitDepth
= 32;
301 icns_info
.iconChannels
= 4;
302 icns_info
.iconPixelDepth
= icns_info
.iconBitDepth
/ icns_info
.iconChannels
;
303 This
->icns_type
= picns_get_type_from_image_info(icns_info
);
304 if (This
->icns_type
== ICNS_NULL_TYPE
)
306 WARN("cannot generate ICNS icon from %dx%d image\n", This
->width
, This
->height
);
310 ret
= picns_init_image_for_type(This
->icns_type
, &This
->icns_image
);
311 if (ret
!= ICNS_STATUS_OK
)
313 WARN("error %d in icns_init_image_for_type\n", ret
);
319 for (i
= 0; i
< lineCount
; i
++)
321 BYTE
*src_row
, *dst_row
;
323 src_row
= pbPixels
+ cbStride
* i
;
324 dst_row
= This
->icns_image
.imageData
+ (This
->lines_written
+ i
)*(This
->width
*4);
325 /* swap bgr -> rgb */
326 for (j
= 0; j
< This
->width
*4; j
+= 4)
328 dst_row
[j
] = src_row
[j
+2];
329 dst_row
[j
+1] = src_row
[j
+1];
330 dst_row
[j
+2] = src_row
[j
];
331 dst_row
[j
+3] = src_row
[j
+3];
334 This
->lines_written
+= lineCount
;
337 LeaveCriticalSection(&This
->encoder
->lock
);
341 static HRESULT WINAPI
IcnsFrameEncode_WriteSource(IWICBitmapFrameEncode
*iface
,
342 IWICBitmapSource
*pIBitmapSource
, WICRect
*prc
)
344 IcnsFrameEncode
*This
= (IcnsFrameEncode
*)iface
;
347 WICPixelFormatGUID guid
;
349 BYTE
*pixeldata
= NULL
;
351 TRACE("(%p,%p,%p)\n", iface
, pIBitmapSource
, prc
);
353 if (!This
->initialized
|| !This
->width
|| !This
->height
)
355 hr
= WINCODEC_ERR_WRONGSTATE
;
359 hr
= IWICBitmapSource_GetPixelFormat(pIBitmapSource
, &guid
);
362 if (!IsEqualGUID(&guid
, &GUID_WICPixelFormat32bppBGRA
))
364 FIXME("format %s unsupported, could use WICConvertBitmapSource to convert\n", debugstr_guid(&guid
));
372 hr
= IWICBitmapSource_GetSize(pIBitmapSource
, &width
, &height
);
382 if (prc
->Width
!= This
->width
)
388 stride
= (32 * This
->width
+ 7)/8;
389 pixeldata
= HeapAlloc(GetProcessHeap(), 0, stride
* prc
->Height
);
396 hr
= IWICBitmapSource_CopyPixels(pIBitmapSource
, prc
, stride
,
397 stride
*prc
->Height
, pixeldata
);
400 hr
= IWICBitmapFrameEncode_WritePixels(iface
, prc
->Height
, stride
,
401 stride
*prc
->Height
, pixeldata
);
405 HeapFree(GetProcessHeap(), 0, pixeldata
);
409 static HRESULT WINAPI
IcnsFrameEncode_Commit(IWICBitmapFrameEncode
*iface
)
411 IcnsFrameEncode
*This
= (IcnsFrameEncode
*)iface
;
412 icns_element_t
*icns_element
= NULL
;
414 icns_element_t
*mask_element
= NULL
;
419 TRACE("(%p): stub\n", iface
);
421 memset(&mask
, 0, sizeof(mask
));
423 EnterCriticalSection(&This
->encoder
->lock
);
425 if (!This
->icns_image
.imageData
|| This
->lines_written
!= This
->height
|| This
->committed
)
427 hr
= WINCODEC_ERR_WRONGSTATE
;
431 ret
= picns_new_element_from_image(&This
->icns_image
, This
->icns_type
, &icns_element
);
432 if (ret
!= ICNS_STATUS_OK
&& icns_element
!= NULL
)
434 WARN("icns_new_element_from_image failed with error %d\n", ret
);
439 if (This
->icns_type
!= ICNS_512x512_32BIT_ARGB_DATA
&& This
->icns_type
!= ICNS_256x256_32BIT_ARGB_DATA
)
441 /* we need to write the mask too */
442 ret
= picns_init_image_for_type(picns_get_mask_type_for_icon_type(This
->icns_type
), &mask
);
443 if (ret
!= ICNS_STATUS_OK
)
445 WARN("icns_init_image_from_type failed to make mask, error %d\n", ret
);
449 for (i
= 0; i
< mask
.imageHeight
; i
++)
452 for (j
= 0; j
< mask
.imageWidth
; j
++)
453 mask
.imageData
[i
*mask
.imageWidth
+ j
] = This
->icns_image
.imageData
[i
*mask
.imageWidth
*4 + j
*4 + 3];
455 ret
= picns_new_element_from_image(&mask
, picns_get_mask_type_for_icon_type(This
->icns_type
), &mask_element
);
456 if (ret
!= ICNS_STATUS_OK
)
458 WARN("icns_new_element_from image failed to make element from mask, error %d\n", ret
);
464 ret
= picns_set_element_in_family(&This
->encoder
->icns_family
, icns_element
);
465 if (ret
!= ICNS_STATUS_OK
)
467 WARN("icns_set_element_in_family failed for image with error %d\n", ret
);
474 ret
= picns_set_element_in_family(&This
->encoder
->icns_family
, mask_element
);
475 if (ret
!= ICNS_STATUS_OK
)
477 WARN("icns_set_element_in_family failed for mask with error %d\n", ret
);
483 This
->committed
= TRUE
;
484 This
->encoder
->any_frame_committed
= TRUE
;
485 This
->encoder
->outstanding_commits
--;
488 LeaveCriticalSection(&This
->encoder
->lock
);
489 picns_free_image(&mask
);
495 static HRESULT WINAPI
IcnsFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode
*iface
,
496 IWICMetadataQueryWriter
**ppIMetadataQueryWriter
)
498 FIXME("(%p, %p): stub\n", iface
, ppIMetadataQueryWriter
);
502 static const IWICBitmapFrameEncodeVtbl IcnsEncoder_FrameVtbl
= {
503 IcnsFrameEncode_QueryInterface
,
504 IcnsFrameEncode_AddRef
,
505 IcnsFrameEncode_Release
,
506 IcnsFrameEncode_Initialize
,
507 IcnsFrameEncode_SetSize
,
508 IcnsFrameEncode_SetResolution
,
509 IcnsFrameEncode_SetPixelFormat
,
510 IcnsFrameEncode_SetColorContexts
,
511 IcnsFrameEncode_SetPalette
,
512 IcnsFrameEncode_SetThumbnail
,
513 IcnsFrameEncode_WritePixels
,
514 IcnsFrameEncode_WriteSource
,
515 IcnsFrameEncode_Commit
,
516 IcnsFrameEncode_GetMetadataQueryWriter
519 static HRESULT WINAPI
IcnsEncoder_QueryInterface(IWICBitmapEncoder
*iface
, REFIID iid
,
522 IcnsEncoder
*This
= (IcnsEncoder
*)iface
;
523 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
525 if (!ppv
) return E_INVALIDARG
;
527 if (IsEqualIID(&IID_IUnknown
, iid
) ||
528 IsEqualIID(&IID_IWICBitmapEncoder
, iid
))
535 return E_NOINTERFACE
;
538 IUnknown_AddRef((IUnknown
*)*ppv
);
542 static ULONG WINAPI
IcnsEncoder_AddRef(IWICBitmapEncoder
*iface
)
544 IcnsEncoder
*This
= (IcnsEncoder
*)iface
;
545 ULONG ref
= InterlockedIncrement(&This
->ref
);
547 TRACE("(%p) refcount=%u\n", iface
, ref
);
552 static ULONG WINAPI
IcnsEncoder_Release(IWICBitmapEncoder
*iface
)
554 IcnsEncoder
*This
= (IcnsEncoder
*)iface
;
555 ULONG ref
= InterlockedDecrement(&This
->ref
);
557 TRACE("(%p) refcount=%u\n", iface
, ref
);
561 This
->lock
.DebugInfo
->Spare
[0] = 0;
562 DeleteCriticalSection(&This
->lock
);
563 if (This
->icns_family
)
564 free(This
->icns_family
);
566 IStream_Release(This
->stream
);
567 HeapFree(GetProcessHeap(), 0, This
);
573 static HRESULT WINAPI
IcnsEncoder_Initialize(IWICBitmapEncoder
*iface
,
574 IStream
*pIStream
, WICBitmapEncoderCacheOption cacheOption
)
576 IcnsEncoder
*This
= (IcnsEncoder
*)iface
;
580 TRACE("(%p,%p,%u)\n", iface
, pIStream
, cacheOption
);
582 EnterCriticalSection(&This
->lock
);
584 if (This
->icns_family
)
586 hr
= WINCODEC_ERR_WRONGSTATE
;
589 ret
= picns_create_family(&This
->icns_family
);
590 if (ret
!= ICNS_STATUS_OK
)
592 WARN("error %d creating icns family\n", ret
);
596 IStream_AddRef(pIStream
);
597 This
->stream
= pIStream
;
600 LeaveCriticalSection(&This
->lock
);
605 static HRESULT WINAPI
IcnsEncoder_GetContainerFormat(IWICBitmapEncoder
*iface
,
606 GUID
*pguidContainerFormat
)
608 FIXME("(%p,%s): stub\n", iface
, debugstr_guid(pguidContainerFormat
));
612 static HRESULT WINAPI
IcnsEncoder_GetEncoderInfo(IWICBitmapEncoder
*iface
,
613 IWICBitmapEncoderInfo
**ppIEncoderInfo
)
615 FIXME("(%p,%p): stub\n", iface
, ppIEncoderInfo
);
619 static HRESULT WINAPI
IcnsEncoder_SetColorContexts(IWICBitmapEncoder
*iface
,
620 UINT cCount
, IWICColorContext
**ppIColorContext
)
622 FIXME("(%p,%u,%p): stub\n", iface
, cCount
, ppIColorContext
);
626 static HRESULT WINAPI
IcnsEncoder_SetPalette(IWICBitmapEncoder
*iface
, IWICPalette
*pIPalette
)
628 TRACE("(%p,%p)\n", iface
, pIPalette
);
629 return WINCODEC_ERR_UNSUPPORTEDOPERATION
;
632 static HRESULT WINAPI
IcnsEncoder_SetThumbnail(IWICBitmapEncoder
*iface
, IWICBitmapSource
*pIThumbnail
)
634 TRACE("(%p,%p)\n", iface
, pIThumbnail
);
635 return WINCODEC_ERR_UNSUPPORTEDOPERATION
;
638 static HRESULT WINAPI
IcnsEncoder_SetPreview(IWICBitmapEncoder
*iface
, IWICBitmapSource
*pIPreview
)
640 TRACE("(%p,%p)\n", iface
, pIPreview
);
641 return WINCODEC_ERR_UNSUPPORTEDOPERATION
;
644 static HRESULT WINAPI
IcnsEncoder_CreateNewFrame(IWICBitmapEncoder
*iface
,
645 IWICBitmapFrameEncode
**ppIFrameEncode
, IPropertyBag2
**ppIEncoderOptions
)
647 IcnsEncoder
*This
= (IcnsEncoder
*)iface
;
649 IcnsFrameEncode
*frameEncode
= NULL
;
651 TRACE("(%p,%p,%p)\n", iface
, ppIFrameEncode
, ppIEncoderOptions
);
653 EnterCriticalSection(&This
->lock
);
655 if (!This
->icns_family
)
657 hr
= WINCODEC_ERR_NOTINITIALIZED
;
661 hr
= CreatePropertyBag2(ppIEncoderOptions
);
665 frameEncode
= HeapAlloc(GetProcessHeap(), 0, sizeof(IcnsFrameEncode
));
666 if (frameEncode
== NULL
)
671 frameEncode
->lpVtbl
= &IcnsEncoder_FrameVtbl
;
672 frameEncode
->encoder
= This
;
673 frameEncode
->ref
= 1;
674 frameEncode
->initialized
= FALSE
;
675 frameEncode
->width
= 0;
676 frameEncode
->height
= 0;
677 memset(&frameEncode
->icns_image
, 0, sizeof(icns_image_t
));
678 frameEncode
->lines_written
= 0;
679 frameEncode
->committed
= FALSE
;
680 *ppIFrameEncode
= (IWICBitmapFrameEncode
*)frameEncode
;
681 This
->outstanding_commits
++;
682 IUnknown_AddRef((IUnknown
*)This
);
685 LeaveCriticalSection(&This
->lock
);
690 static HRESULT WINAPI
IcnsEncoder_Commit(IWICBitmapEncoder
*iface
)
692 IcnsEncoder
*This
= (IcnsEncoder
*)iface
;
693 icns_byte_t
*buffer
= NULL
;
694 icns_size_t buffer_size
;
699 TRACE("(%p)\n", iface
);
701 EnterCriticalSection(&This
->lock
);
703 if (!This
->any_frame_committed
|| This
->outstanding_commits
> 0 || This
->committed
)
705 hr
= WINCODEC_ERR_WRONGSTATE
;
709 ret
= picns_export_family_data(This
->icns_family
, &buffer_size
, &buffer
);
710 if (ret
!= ICNS_STATUS_OK
)
712 WARN("icns_export_family_data failed with error %d\n", ret
);
716 hr
= IStream_Write(This
->stream
, buffer
, buffer_size
, &byteswritten
);
717 if (FAILED(hr
) || byteswritten
!= buffer_size
)
719 WARN("writing file failed, hr = 0x%08X\n", hr
);
724 This
->committed
= TRUE
;
727 LeaveCriticalSection(&This
->lock
);
732 static HRESULT WINAPI
IcnsEncoder_GetMetadataQueryWriter(IWICBitmapEncoder
*iface
,
733 IWICMetadataQueryWriter
**ppIMetadataQueryWriter
)
735 FIXME("(%p,%p): stub\n", iface
, ppIMetadataQueryWriter
);
739 static const IWICBitmapEncoderVtbl IcnsEncoder_Vtbl
= {
740 IcnsEncoder_QueryInterface
,
743 IcnsEncoder_Initialize
,
744 IcnsEncoder_GetContainerFormat
,
745 IcnsEncoder_GetEncoderInfo
,
746 IcnsEncoder_SetColorContexts
,
747 IcnsEncoder_SetPalette
,
748 IcnsEncoder_SetThumbnail
,
749 IcnsEncoder_SetPreview
,
750 IcnsEncoder_CreateNewFrame
,
752 IcnsEncoder_GetMetadataQueryWriter
755 HRESULT
IcnsEncoder_CreateInstance(IUnknown
*pUnkOuter
, REFIID iid
, void** ppv
)
760 TRACE("(%p,%s,%p)\n", pUnkOuter
, debugstr_guid(iid
), ppv
);
764 if (pUnkOuter
) return CLASS_E_NOAGGREGATION
;
766 if (!libicns_handle
&& !load_libicns())
768 ERR("Failed writing ICNS because unable to find %s\n",SONAME_LIBICNS
);
772 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(IcnsEncoder
));
773 if (!This
) return E_OUTOFMEMORY
;
775 This
->lpVtbl
= &IcnsEncoder_Vtbl
;
778 This
->icns_family
= NULL
;
779 This
->any_frame_committed
= FALSE
;
780 This
->outstanding_commits
= 0;
781 This
->committed
= FALSE
;
782 InitializeCriticalSection(&This
->lock
);
783 This
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": IcnsEncoder.lock");
785 ret
= IUnknown_QueryInterface((IUnknown
*)This
, iid
, ppv
);
786 IUnknown_Release((IUnknown
*)This
);
791 #else /* !defined(SONAME_LIBICNS) */
793 HRESULT
IcnsEncoder_CreateInstance(IUnknown
*pUnkOuter
, REFIID iid
, void** ppv
)
795 ERR("Trying to save ICNS picture, but ICNS support is not compiled in.\n");