oleaut32: Also search local typeinfos in ITypeInfo::GetRefTypeInfo.
[wine.git] / dlls / windowscodecs / icnsformat.c
blob254f81ff269b3c6eeeddc0916f8d33bda7052e1e
1 /*
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
19 #include "config.h"
20 #include "wine/port.h"
22 #include <stdarg.h>
24 #ifdef HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H
25 #define GetCurrentProcess GetCurrentProcess_Mac
26 #define GetCurrentThread GetCurrentThread_Mac
27 #define LoadResource LoadResource_Mac
28 #define AnimatePalette AnimatePalette_Mac
29 #define EqualRgn EqualRgn_Mac
30 #define FillRgn FillRgn_Mac
31 #define FrameRgn FrameRgn_Mac
32 #define GetPixel GetPixel_Mac
33 #define InvertRgn InvertRgn_Mac
34 #define LineTo LineTo_Mac
35 #define OffsetRgn OffsetRgn_Mac
36 #define PaintRgn PaintRgn_Mac
37 #define Polygon Polygon_Mac
38 #define ResizePalette ResizePalette_Mac
39 #define SetRectRgn SetRectRgn_Mac
40 #define EqualRect EqualRect_Mac
41 #define FillRect FillRect_Mac
42 #define FrameRect FrameRect_Mac
43 #define GetCursor GetCursor_Mac
44 #define InvertRect InvertRect_Mac
45 #define OffsetRect OffsetRect_Mac
46 #define PtInRect PtInRect_Mac
47 #define SetCursor SetCursor_Mac
48 #define SetRect SetRect_Mac
49 #define ShowCursor ShowCursor_Mac
50 #define UnionRect UnionRect_Mac
51 #include <ApplicationServices/ApplicationServices.h>
52 #undef GetCurrentProcess
53 #undef GetCurrentThread
54 #undef LoadResource
55 #undef AnimatePalette
56 #undef EqualRgn
57 #undef FillRgn
58 #undef FrameRgn
59 #undef GetPixel
60 #undef InvertRgn
61 #undef LineTo
62 #undef OffsetRgn
63 #undef PaintRgn
64 #undef Polygon
65 #undef ResizePalette
66 #undef SetRectRgn
67 #undef EqualRect
68 #undef FillRect
69 #undef FrameRect
70 #undef GetCursor
71 #undef InvertRect
72 #undef OffsetRect
73 #undef PtInRect
74 #undef SetCursor
75 #undef SetRect
76 #undef ShowCursor
77 #undef UnionRect
78 #undef DPRINTF
79 #endif
81 #define COBJMACROS
83 #include "windef.h"
84 #include "winbase.h"
85 #include "objbase.h"
86 #include "wincodec.h"
88 #include "wincodecs_private.h"
90 #include "wine/debug.h"
91 #include "wine/library.h"
93 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
95 #if defined(HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H) && \
96 MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4
98 typedef struct IcnsEncoder {
99 IWICBitmapEncoder IWICBitmapEncoder_iface;
100 LONG ref;
101 IStream *stream;
102 IconFamilyHandle icns_family;
103 BOOL any_frame_committed;
104 int outstanding_commits;
105 BOOL committed;
106 CRITICAL_SECTION lock;
107 } IcnsEncoder;
109 static inline IcnsEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
111 return CONTAINING_RECORD(iface, IcnsEncoder, IWICBitmapEncoder_iface);
114 typedef struct IcnsFrameEncode {
115 IWICBitmapFrameEncode IWICBitmapFrameEncode_iface;
116 IcnsEncoder *encoder;
117 LONG ref;
118 BOOL initialized;
119 UINT size;
120 OSType icns_type;
121 BYTE* icns_image;
122 int lines_written;
123 BOOL committed;
124 } IcnsFrameEncode;
126 static inline IcnsFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface)
128 return CONTAINING_RECORD(iface, IcnsFrameEncode, IWICBitmapFrameEncode_iface);
131 static HRESULT WINAPI IcnsFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid,
132 void **ppv)
134 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
135 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
137 if (!ppv) return E_INVALIDARG;
139 if (IsEqualIID(&IID_IUnknown, iid) ||
140 IsEqualIID(&IID_IWICBitmapFrameEncode, iid))
142 *ppv = &This->IWICBitmapFrameEncode_iface;
144 else
146 *ppv = NULL;
147 return E_NOINTERFACE;
150 IUnknown_AddRef((IUnknown*)*ppv);
151 return S_OK;
154 static ULONG WINAPI IcnsFrameEncode_AddRef(IWICBitmapFrameEncode *iface)
156 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
157 ULONG ref = InterlockedIncrement(&This->ref);
159 TRACE("(%p) refcount=%u\n", iface, ref);
161 return ref;
164 static ULONG WINAPI IcnsFrameEncode_Release(IWICBitmapFrameEncode *iface)
166 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
167 ULONG ref = InterlockedDecrement(&This->ref);
169 TRACE("(%p) refcount=%u\n", iface, ref);
171 if (ref == 0)
173 if (!This->committed)
175 EnterCriticalSection(&This->encoder->lock);
176 This->encoder->outstanding_commits--;
177 LeaveCriticalSection(&This->encoder->lock);
179 if (This->icns_image != NULL)
180 HeapFree(GetProcessHeap(), 0, This->icns_image);
182 IUnknown_Release((IUnknown*)This->encoder);
183 HeapFree(GetProcessHeap(), 0, This);
186 return ref;
189 static HRESULT WINAPI IcnsFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
190 IPropertyBag2 *pIEncoderOptions)
192 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
193 HRESULT hr = S_OK;
195 TRACE("(%p,%p)\n", iface, pIEncoderOptions);
197 EnterCriticalSection(&This->encoder->lock);
199 if (This->initialized)
201 hr = WINCODEC_ERR_WRONGSTATE;
202 goto end;
204 This->initialized = TRUE;
206 end:
207 LeaveCriticalSection(&This->encoder->lock);
208 return hr;
211 static HRESULT WINAPI IcnsFrameEncode_SetSize(IWICBitmapFrameEncode *iface,
212 UINT uiWidth, UINT uiHeight)
214 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
215 HRESULT hr = S_OK;
217 TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight);
219 EnterCriticalSection(&This->encoder->lock);
221 if (!This->initialized || This->icns_image)
223 hr = WINCODEC_ERR_WRONGSTATE;
224 goto end;
227 if (uiWidth != uiHeight)
229 WARN("cannot generate ICNS icon from %dx%d image\n", uiWidth, uiHeight);
230 hr = E_INVALIDARG;
231 goto end;
234 switch (uiWidth)
236 case 16:
237 case 32:
238 case 48:
239 case 128:
240 case 256:
241 case 512:
242 break;
243 default:
244 WARN("cannot generate ICNS icon from %dx%d image\n", This->size, This->size);
245 hr = E_INVALIDARG;
246 goto end;
249 This->size = uiWidth;
251 end:
252 LeaveCriticalSection(&This->encoder->lock);
253 return hr;
256 static HRESULT WINAPI IcnsFrameEncode_SetResolution(IWICBitmapFrameEncode *iface,
257 double dpiX, double dpiY)
259 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
260 HRESULT hr = S_OK;
262 TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY);
264 EnterCriticalSection(&This->encoder->lock);
266 if (!This->initialized || This->icns_image)
268 hr = WINCODEC_ERR_WRONGSTATE;
269 goto end;
272 end:
273 LeaveCriticalSection(&This->encoder->lock);
274 return S_OK;
277 static HRESULT WINAPI IcnsFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface,
278 WICPixelFormatGUID *pPixelFormat)
280 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
281 HRESULT hr = S_OK;
283 TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat));
285 EnterCriticalSection(&This->encoder->lock);
287 if (!This->initialized || This->icns_image)
289 hr = WINCODEC_ERR_WRONGSTATE;
290 goto end;
293 memcpy(pPixelFormat, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID));
295 end:
296 LeaveCriticalSection(&This->encoder->lock);
297 return S_OK;
300 static HRESULT WINAPI IcnsFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface,
301 UINT cCount, IWICColorContext **ppIColorContext)
303 FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
304 return E_NOTIMPL;
307 static HRESULT WINAPI IcnsFrameEncode_SetPalette(IWICBitmapFrameEncode *iface,
308 IWICPalette *pIPalette)
310 FIXME("(%p,%p): stub\n", iface, pIPalette);
311 return WINCODEC_ERR_UNSUPPORTEDOPERATION;
314 static HRESULT WINAPI IcnsFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface,
315 IWICBitmapSource *pIThumbnail)
317 FIXME("(%p,%p): stub\n", iface, pIThumbnail);
318 return WINCODEC_ERR_UNSUPPORTEDOPERATION;
321 static HRESULT WINAPI IcnsFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
322 UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels)
324 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
325 HRESULT hr = S_OK;
326 UINT i;
328 TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels);
330 EnterCriticalSection(&This->encoder->lock);
332 if (!This->initialized || !This->size)
334 hr = WINCODEC_ERR_WRONGSTATE;
335 goto end;
337 if (lineCount == 0 || lineCount + This->lines_written > This->size)
339 hr = E_INVALIDARG;
340 goto end;
343 if (!This->icns_image)
345 switch (This->size)
347 case 16: This->icns_type = kIconServices16PixelDataARGB; break;
348 case 32: This->icns_type = kIconServices32PixelDataARGB; break;
349 case 48: This->icns_type = kIconServices48PixelDataARGB; break;
350 case 128: This->icns_type = kIconServices128PixelDataARGB; break;
351 case 256: This->icns_type = kIconServices256PixelDataARGB; break;
352 case 512: This->icns_type = kIconServices512PixelDataARGB; break;
353 default:
354 WARN("cannot generate ICNS icon from %dx%d image\n", This->size, This->size);
355 hr = E_INVALIDARG;
356 goto end;
358 This->icns_image = HeapAlloc(GetProcessHeap(), 0, This->size * This->size * 4);
359 if (!This->icns_image)
361 WARN("failed to allocate image buffer\n");
362 hr = E_FAIL;
363 goto end;
367 for (i = 0; i < lineCount; i++)
369 BYTE *src_row, *dst_row;
370 UINT j;
371 src_row = pbPixels + cbStride * i;
372 dst_row = This->icns_image + (This->lines_written + i)*(This->size*4);
373 /* swap bgr -> rgb */
374 for (j = 0; j < This->size*4; j += 4)
376 dst_row[j] = src_row[j+3];
377 dst_row[j+1] = src_row[j+2];
378 dst_row[j+2] = src_row[j+1];
379 dst_row[j+3] = src_row[j];
382 This->lines_written += lineCount;
384 end:
385 LeaveCriticalSection(&This->encoder->lock);
386 return hr;
389 static HRESULT WINAPI IcnsFrameEncode_WriteSource(IWICBitmapFrameEncode *iface,
390 IWICBitmapSource *pIBitmapSource, WICRect *prc)
392 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
393 HRESULT hr;
394 WICRect rc;
395 WICPixelFormatGUID guid;
396 UINT stride;
397 BYTE *pixeldata = NULL;
399 TRACE("(%p,%p,%p)\n", iface, pIBitmapSource, prc);
401 if (!This->initialized || !This->size)
403 hr = WINCODEC_ERR_WRONGSTATE;
404 goto end;
407 hr = IWICBitmapSource_GetPixelFormat(pIBitmapSource, &guid);
408 if (FAILED(hr))
409 goto end;
410 if (!IsEqualGUID(&guid, &GUID_WICPixelFormat32bppBGRA))
412 FIXME("format %s unsupported, could use WICConvertBitmapSource to convert\n", debugstr_guid(&guid));
413 hr = E_FAIL;
414 goto end;
417 if (!prc)
419 UINT width, height;
420 hr = IWICBitmapSource_GetSize(pIBitmapSource, &width, &height);
421 if (FAILED(hr))
422 goto end;
423 rc.X = 0;
424 rc.Y = 0;
425 rc.Width = width;
426 rc.Height = height;
427 prc = &rc;
430 if (prc->Width != This->size)
432 hr = E_INVALIDARG;
433 goto end;
436 stride = (32 * This->size + 7)/8;
437 pixeldata = HeapAlloc(GetProcessHeap(), 0, stride * prc->Height);
438 if (!pixeldata)
440 hr = E_OUTOFMEMORY;
441 goto end;
444 hr = IWICBitmapSource_CopyPixels(pIBitmapSource, prc, stride,
445 stride*prc->Height, pixeldata);
446 if (SUCCEEDED(hr))
448 hr = IWICBitmapFrameEncode_WritePixels(iface, prc->Height, stride,
449 stride*prc->Height, pixeldata);
452 end:
453 HeapFree(GetProcessHeap(), 0, pixeldata);
454 return hr;
457 static HRESULT WINAPI IcnsFrameEncode_Commit(IWICBitmapFrameEncode *iface)
459 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
460 Handle handle;
461 OSErr ret;
462 HRESULT hr = S_OK;
464 TRACE("(%p): stub\n", iface);
466 EnterCriticalSection(&This->encoder->lock);
468 if (!This->icns_image || This->lines_written != This->size || This->committed)
470 hr = WINCODEC_ERR_WRONGSTATE;
471 goto end;
474 ret = PtrToHand(This->icns_image, &handle, This->size * This->size * 4);
475 if (ret != noErr || !handle)
477 WARN("PtrToHand failed with error %d\n", ret);
478 hr = E_FAIL;
479 goto end;
482 ret = SetIconFamilyData(This->encoder->icns_family, This->icns_type, handle);
483 DisposeHandle(handle);
485 if (ret != noErr)
487 WARN("SetIconFamilyData failed for image with error %d\n", ret);
488 hr = E_FAIL;
489 goto end;
492 This->committed = TRUE;
493 This->encoder->any_frame_committed = TRUE;
494 This->encoder->outstanding_commits--;
496 end:
497 LeaveCriticalSection(&This->encoder->lock);
498 return hr;
501 static HRESULT WINAPI IcnsFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface,
502 IWICMetadataQueryWriter **ppIMetadataQueryWriter)
504 FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter);
505 return E_NOTIMPL;
508 static const IWICBitmapFrameEncodeVtbl IcnsEncoder_FrameVtbl = {
509 IcnsFrameEncode_QueryInterface,
510 IcnsFrameEncode_AddRef,
511 IcnsFrameEncode_Release,
512 IcnsFrameEncode_Initialize,
513 IcnsFrameEncode_SetSize,
514 IcnsFrameEncode_SetResolution,
515 IcnsFrameEncode_SetPixelFormat,
516 IcnsFrameEncode_SetColorContexts,
517 IcnsFrameEncode_SetPalette,
518 IcnsFrameEncode_SetThumbnail,
519 IcnsFrameEncode_WritePixels,
520 IcnsFrameEncode_WriteSource,
521 IcnsFrameEncode_Commit,
522 IcnsFrameEncode_GetMetadataQueryWriter
525 static HRESULT WINAPI IcnsEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid,
526 void **ppv)
528 IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
529 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
531 if (!ppv) return E_INVALIDARG;
533 if (IsEqualIID(&IID_IUnknown, iid) ||
534 IsEqualIID(&IID_IWICBitmapEncoder, iid))
536 *ppv = This;
538 else
540 *ppv = NULL;
541 return E_NOINTERFACE;
544 IUnknown_AddRef((IUnknown*)*ppv);
545 return S_OK;
548 static ULONG WINAPI IcnsEncoder_AddRef(IWICBitmapEncoder *iface)
550 IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
551 ULONG ref = InterlockedIncrement(&This->ref);
553 TRACE("(%p) refcount=%u\n", iface, ref);
555 return ref;
558 static ULONG WINAPI IcnsEncoder_Release(IWICBitmapEncoder *iface)
560 IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
561 ULONG ref = InterlockedDecrement(&This->ref);
563 TRACE("(%p) refcount=%u\n", iface, ref);
565 if (ref == 0)
567 This->lock.DebugInfo->Spare[0] = 0;
568 DeleteCriticalSection(&This->lock);
569 if (This->icns_family)
570 DisposeHandle((Handle)This->icns_family);
571 if (This->stream)
572 IStream_Release(This->stream);
573 HeapFree(GetProcessHeap(), 0, This);
576 return ref;
579 static HRESULT WINAPI IcnsEncoder_Initialize(IWICBitmapEncoder *iface,
580 IStream *pIStream, WICBitmapEncoderCacheOption cacheOption)
582 IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
583 HRESULT hr = S_OK;
585 TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption);
587 EnterCriticalSection(&This->lock);
589 if (This->icns_family)
591 hr = WINCODEC_ERR_WRONGSTATE;
592 goto end;
594 This->icns_family = (IconFamilyHandle)NewHandle(0);
595 if (!This->icns_family)
597 WARN("error creating icns family\n");
598 hr = E_FAIL;
599 goto end;
601 IStream_AddRef(pIStream);
602 This->stream = pIStream;
604 end:
605 LeaveCriticalSection(&This->lock);
607 return hr;
610 static HRESULT WINAPI IcnsEncoder_GetContainerFormat(IWICBitmapEncoder *iface,
611 GUID *pguidContainerFormat)
613 FIXME("(%p,%s): stub\n", iface, debugstr_guid(pguidContainerFormat));
614 return E_NOTIMPL;
617 static HRESULT WINAPI IcnsEncoder_GetEncoderInfo(IWICBitmapEncoder *iface,
618 IWICBitmapEncoderInfo **ppIEncoderInfo)
620 FIXME("(%p,%p): stub\n", iface, ppIEncoderInfo);
621 return E_NOTIMPL;
624 static HRESULT WINAPI IcnsEncoder_SetColorContexts(IWICBitmapEncoder *iface,
625 UINT cCount, IWICColorContext **ppIColorContext)
627 FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
628 return E_NOTIMPL;
631 static HRESULT WINAPI IcnsEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *pIPalette)
633 TRACE("(%p,%p)\n", iface, pIPalette);
634 return WINCODEC_ERR_UNSUPPORTEDOPERATION;
637 static HRESULT WINAPI IcnsEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail)
639 TRACE("(%p,%p)\n", iface, pIThumbnail);
640 return WINCODEC_ERR_UNSUPPORTEDOPERATION;
643 static HRESULT WINAPI IcnsEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview)
645 TRACE("(%p,%p)\n", iface, pIPreview);
646 return WINCODEC_ERR_UNSUPPORTEDOPERATION;
649 static HRESULT WINAPI IcnsEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
650 IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions)
652 IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
653 HRESULT hr = S_OK;
654 IcnsFrameEncode *frameEncode = NULL;
656 TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
658 EnterCriticalSection(&This->lock);
660 if (!This->icns_family)
662 hr = WINCODEC_ERR_NOTINITIALIZED;
663 goto end;
666 hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions);
667 if (FAILED(hr))
668 goto end;
670 frameEncode = HeapAlloc(GetProcessHeap(), 0, sizeof(IcnsFrameEncode));
671 if (frameEncode == NULL)
673 hr = E_OUTOFMEMORY;
674 goto end;
676 frameEncode->IWICBitmapFrameEncode_iface.lpVtbl = &IcnsEncoder_FrameVtbl;
677 frameEncode->encoder = This;
678 frameEncode->ref = 1;
679 frameEncode->initialized = FALSE;
680 frameEncode->size = 0;
681 frameEncode->icns_image = NULL;
682 frameEncode->lines_written = 0;
683 frameEncode->committed = FALSE;
684 *ppIFrameEncode = &frameEncode->IWICBitmapFrameEncode_iface;
685 This->outstanding_commits++;
686 IUnknown_AddRef((IUnknown*)This);
688 end:
689 LeaveCriticalSection(&This->lock);
691 return hr;
694 static HRESULT WINAPI IcnsEncoder_Commit(IWICBitmapEncoder *iface)
696 IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
697 size_t buffer_size;
698 HRESULT hr = S_OK;
699 ULONG byteswritten;
701 TRACE("(%p)\n", iface);
703 EnterCriticalSection(&This->lock);
705 if (!This->any_frame_committed || This->outstanding_commits > 0 || This->committed)
707 hr = WINCODEC_ERR_WRONGSTATE;
708 goto end;
711 buffer_size = GetHandleSize((Handle)This->icns_family);
712 hr = IStream_Write(This->stream, *This->icns_family, buffer_size, &byteswritten);
713 if (FAILED(hr) || byteswritten != buffer_size)
715 WARN("writing file failed, hr = 0x%08X\n", hr);
716 hr = E_FAIL;
717 goto end;
720 This->committed = TRUE;
722 end:
723 LeaveCriticalSection(&This->lock);
724 return hr;
727 static HRESULT WINAPI IcnsEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface,
728 IWICMetadataQueryWriter **ppIMetadataQueryWriter)
730 FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter);
731 return E_NOTIMPL;
734 static const IWICBitmapEncoderVtbl IcnsEncoder_Vtbl = {
735 IcnsEncoder_QueryInterface,
736 IcnsEncoder_AddRef,
737 IcnsEncoder_Release,
738 IcnsEncoder_Initialize,
739 IcnsEncoder_GetContainerFormat,
740 IcnsEncoder_GetEncoderInfo,
741 IcnsEncoder_SetColorContexts,
742 IcnsEncoder_SetPalette,
743 IcnsEncoder_SetThumbnail,
744 IcnsEncoder_SetPreview,
745 IcnsEncoder_CreateNewFrame,
746 IcnsEncoder_Commit,
747 IcnsEncoder_GetMetadataQueryWriter
750 HRESULT IcnsEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
752 IcnsEncoder *This;
753 HRESULT ret;
755 TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);
757 *ppv = NULL;
759 if (pUnkOuter) return CLASS_E_NOAGGREGATION;
761 This = HeapAlloc(GetProcessHeap(), 0, sizeof(IcnsEncoder));
762 if (!This) return E_OUTOFMEMORY;
764 This->IWICBitmapEncoder_iface.lpVtbl = &IcnsEncoder_Vtbl;
765 This->ref = 1;
766 This->stream = NULL;
767 This->icns_family = NULL;
768 This->any_frame_committed = FALSE;
769 This->outstanding_commits = 0;
770 This->committed = FALSE;
771 InitializeCriticalSection(&This->lock);
772 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IcnsEncoder.lock");
774 ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
775 IUnknown_Release((IUnknown*)This);
777 return ret;
780 #else /* !defined(HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H) ||
781 MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 */
783 HRESULT IcnsEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
785 ERR("Trying to save ICNS picture, but ICNS support is not compiled in.\n");
786 return E_FAIL;
789 #endif