[SHELL32] CDrivesFolder: Implement the eject and disconnect menu items. CORE-13841
[reactos.git] / dll / win32 / windowscodecs / icnsformat.c
1 /*
2 * Copyright 2010 Damjan Jovanovic
3 *
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.
8 *
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.
13 *
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
17 */
18
19 #ifdef HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H
20 #define GetCurrentProcess GetCurrentProcess_Mac
21 #define GetCurrentThread GetCurrentThread_Mac
22 #define LoadResource LoadResource_Mac
23 #define AnimatePalette AnimatePalette_Mac
24 #define EqualRgn EqualRgn_Mac
25 #define FillRgn FillRgn_Mac
26 #define FrameRgn FrameRgn_Mac
27 #define GetPixel GetPixel_Mac
28 #define InvertRgn InvertRgn_Mac
29 #define LineTo LineTo_Mac
30 #define OffsetRgn OffsetRgn_Mac
31 #define PaintRgn PaintRgn_Mac
32 #define Polygon Polygon_Mac
33 #define ResizePalette ResizePalette_Mac
34 #define SetRectRgn SetRectRgn_Mac
35 #define EqualRect EqualRect_Mac
36 #define FillRect FillRect_Mac
37 #define FrameRect FrameRect_Mac
38 #define GetCursor GetCursor_Mac
39 #define InvertRect InvertRect_Mac
40 #define OffsetRect OffsetRect_Mac
41 #define PtInRect PtInRect_Mac
42 #define SetCursor SetCursor_Mac
43 #define SetRect SetRect_Mac
44 #define ShowCursor ShowCursor_Mac
45 #define UnionRect UnionRect_Mac
46 #include <ApplicationServices/ApplicationServices.h>
47 #undef GetCurrentProcess
48 #undef GetCurrentThread
49 #undef LoadResource
50 #undef AnimatePalette
51 #undef EqualRgn
52 #undef FillRgn
53 #undef FrameRgn
54 #undef GetPixel
55 #undef InvertRgn
56 #undef LineTo
57 #undef OffsetRgn
58 #undef PaintRgn
59 #undef Polygon
60 #undef ResizePalette
61 #undef SetRectRgn
62 #undef EqualRect
63 #undef FillRect
64 #undef FrameRect
65 #undef GetCursor
66 #undef InvertRect
67 #undef OffsetRect
68 #undef PtInRect
69 #undef SetCursor
70 #undef SetRect
71 #undef ShowCursor
72 #undef UnionRect
73 #undef DPRINTF
74 #endif
75
76 #include "wincodecs_private.h"
77
78 #if defined(HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H) && \
79 MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4
80
81 typedef struct IcnsEncoder {
82 IWICBitmapEncoder IWICBitmapEncoder_iface;
83 LONG ref;
84 IStream *stream;
85 IconFamilyHandle icns_family;
86 BOOL any_frame_committed;
87 int outstanding_commits;
88 BOOL committed;
89 CRITICAL_SECTION lock;
90 } IcnsEncoder;
91
92 static inline IcnsEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
93 {
94 return CONTAINING_RECORD(iface, IcnsEncoder, IWICBitmapEncoder_iface);
95 }
96
97 typedef struct IcnsFrameEncode {
98 IWICBitmapFrameEncode IWICBitmapFrameEncode_iface;
99 IcnsEncoder *encoder;
100 LONG ref;
101 BOOL initialized;
102 UINT size;
103 OSType icns_type;
104 BYTE* icns_image;
105 int lines_written;
106 BOOL committed;
107 } IcnsFrameEncode;
108
109 static inline IcnsFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface)
110 {
111 return CONTAINING_RECORD(iface, IcnsFrameEncode, IWICBitmapFrameEncode_iface);
112 }
113
114 static HRESULT WINAPI IcnsFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid,
115 void **ppv)
116 {
117 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
118 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
119
120 if (!ppv) return E_INVALIDARG;
121
122 if (IsEqualIID(&IID_IUnknown, iid) ||
123 IsEqualIID(&IID_IWICBitmapFrameEncode, iid))
124 {
125 *ppv = &This->IWICBitmapFrameEncode_iface;
126 }
127 else
128 {
129 *ppv = NULL;
130 return E_NOINTERFACE;
131 }
132
133 IUnknown_AddRef((IUnknown*)*ppv);
134 return S_OK;
135 }
136
137 static ULONG WINAPI IcnsFrameEncode_AddRef(IWICBitmapFrameEncode *iface)
138 {
139 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
140 ULONG ref = InterlockedIncrement(&This->ref);
141
142 TRACE("(%p) refcount=%u\n", iface, ref);
143
144 return ref;
145 }
146
147 static ULONG WINAPI IcnsFrameEncode_Release(IWICBitmapFrameEncode *iface)
148 {
149 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
150 ULONG ref = InterlockedDecrement(&This->ref);
151
152 TRACE("(%p) refcount=%u\n", iface, ref);
153
154 if (ref == 0)
155 {
156 if (!This->committed)
157 {
158 EnterCriticalSection(&This->encoder->lock);
159 This->encoder->outstanding_commits--;
160 LeaveCriticalSection(&This->encoder->lock);
161 }
162 HeapFree(GetProcessHeap(), 0, This->icns_image);
163
164 IWICBitmapEncoder_Release(&This->encoder->IWICBitmapEncoder_iface);
165 HeapFree(GetProcessHeap(), 0, This);
166 }
167
168 return ref;
169 }
170
171 static HRESULT WINAPI IcnsFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
172 IPropertyBag2 *pIEncoderOptions)
173 {
174 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
175 HRESULT hr = S_OK;
176
177 TRACE("(%p,%p)\n", iface, pIEncoderOptions);
178
179 EnterCriticalSection(&This->encoder->lock);
180
181 if (This->initialized)
182 {
183 hr = WINCODEC_ERR_WRONGSTATE;
184 goto end;
185 }
186 This->initialized = TRUE;
187
188 end:
189 LeaveCriticalSection(&This->encoder->lock);
190 return hr;
191 }
192
193 static HRESULT WINAPI IcnsFrameEncode_SetSize(IWICBitmapFrameEncode *iface,
194 UINT uiWidth, UINT uiHeight)
195 {
196 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
197 HRESULT hr = S_OK;
198
199 TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight);
200
201 EnterCriticalSection(&This->encoder->lock);
202
203 if (!This->initialized || This->icns_image)
204 {
205 hr = WINCODEC_ERR_WRONGSTATE;
206 goto end;
207 }
208
209 if (uiWidth != uiHeight)
210 {
211 WARN("cannot generate ICNS icon from %dx%d image\n", uiWidth, uiHeight);
212 hr = E_INVALIDARG;
213 goto end;
214 }
215
216 switch (uiWidth)
217 {
218 case 16:
219 case 32:
220 case 48:
221 case 128:
222 case 256:
223 case 512:
224 break;
225 default:
226 WARN("cannot generate ICNS icon from %dx%d image\n", This->size, This->size);
227 hr = E_INVALIDARG;
228 goto end;
229 }
230
231 This->size = uiWidth;
232
233 end:
234 LeaveCriticalSection(&This->encoder->lock);
235 return hr;
236 }
237
238 static HRESULT WINAPI IcnsFrameEncode_SetResolution(IWICBitmapFrameEncode *iface,
239 double dpiX, double dpiY)
240 {
241 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
242 HRESULT hr = S_OK;
243
244 TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY);
245
246 EnterCriticalSection(&This->encoder->lock);
247
248 if (!This->initialized || This->icns_image)
249 {
250 hr = WINCODEC_ERR_WRONGSTATE;
251 goto end;
252 }
253
254 end:
255 LeaveCriticalSection(&This->encoder->lock);
256 return S_OK;
257 }
258
259 static HRESULT WINAPI IcnsFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface,
260 WICPixelFormatGUID *pPixelFormat)
261 {
262 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
263 HRESULT hr = S_OK;
264
265 TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat));
266
267 EnterCriticalSection(&This->encoder->lock);
268
269 if (!This->initialized || This->icns_image)
270 {
271 hr = WINCODEC_ERR_WRONGSTATE;
272 goto end;
273 }
274
275 memcpy(pPixelFormat, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID));
276
277 end:
278 LeaveCriticalSection(&This->encoder->lock);
279 return S_OK;
280 }
281
282 static HRESULT WINAPI IcnsFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface,
283 UINT cCount, IWICColorContext **ppIColorContext)
284 {
285 FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
286 return E_NOTIMPL;
287 }
288
289 static HRESULT WINAPI IcnsFrameEncode_SetPalette(IWICBitmapFrameEncode *iface,
290 IWICPalette *pIPalette)
291 {
292 FIXME("(%p,%p): stub\n", iface, pIPalette);
293 return WINCODEC_ERR_UNSUPPORTEDOPERATION;
294 }
295
296 static HRESULT WINAPI IcnsFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface,
297 IWICBitmapSource *pIThumbnail)
298 {
299 FIXME("(%p,%p): stub\n", iface, pIThumbnail);
300 return WINCODEC_ERR_UNSUPPORTEDOPERATION;
301 }
302
303 static HRESULT WINAPI IcnsFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
304 UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels)
305 {
306 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
307 HRESULT hr = S_OK;
308 UINT i;
309
310 TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels);
311
312 EnterCriticalSection(&This->encoder->lock);
313
314 if (!This->initialized || !This->size)
315 {
316 hr = WINCODEC_ERR_WRONGSTATE;
317 goto end;
318 }
319 if (lineCount == 0 || lineCount + This->lines_written > This->size)
320 {
321 hr = E_INVALIDARG;
322 goto end;
323 }
324
325 if (!This->icns_image)
326 {
327 switch (This->size)
328 {
329 case 16: This->icns_type = kIconServices16PixelDataARGB; break;
330 case 32: This->icns_type = kIconServices32PixelDataARGB; break;
331 case 48: This->icns_type = kIconServices48PixelDataARGB; break;
332 case 128: This->icns_type = kIconServices128PixelDataARGB; break;
333 case 256: This->icns_type = kIconServices256PixelDataARGB; break;
334 case 512: This->icns_type = kIconServices512PixelDataARGB; break;
335 default:
336 WARN("cannot generate ICNS icon from %dx%d image\n", This->size, This->size);
337 hr = E_INVALIDARG;
338 goto end;
339 }
340 This->icns_image = HeapAlloc(GetProcessHeap(), 0, This->size * This->size * 4);
341 if (!This->icns_image)
342 {
343 WARN("failed to allocate image buffer\n");
344 hr = E_FAIL;
345 goto end;
346 }
347 }
348
349 for (i = 0; i < lineCount; i++)
350 {
351 BYTE *src_row, *dst_row;
352 UINT j;
353 src_row = pbPixels + cbStride * i;
354 dst_row = This->icns_image + (This->lines_written + i)*(This->size*4);
355 /* swap bgr -> rgb */
356 for (j = 0; j < This->size*4; j += 4)
357 {
358 dst_row[j] = src_row[j+3];
359 dst_row[j+1] = src_row[j+2];
360 dst_row[j+2] = src_row[j+1];
361 dst_row[j+3] = src_row[j];
362 }
363 }
364 This->lines_written += lineCount;
365
366 end:
367 LeaveCriticalSection(&This->encoder->lock);
368 return hr;
369 }
370
371 static HRESULT WINAPI IcnsFrameEncode_WriteSource(IWICBitmapFrameEncode *iface,
372 IWICBitmapSource *pIBitmapSource, WICRect *prc)
373 {
374 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
375 HRESULT hr;
376
377 TRACE("(%p,%p,%p)\n", iface, pIBitmapSource, prc);
378
379 if (!This->initialized)
380 return WINCODEC_ERR_WRONGSTATE;
381
382 hr = configure_write_source(iface, pIBitmapSource, prc,
383 &GUID_WICPixelFormat32bppBGRA, This->size, This->size,
384 1.0, 1.0);
385
386 if (SUCCEEDED(hr))
387 {
388 hr = write_source(iface, pIBitmapSource, prc,
389 &GUID_WICPixelFormat32bppBGRA, 32, This->size, This->size);
390 }
391
392 return hr;
393 }
394
395 static HRESULT WINAPI IcnsFrameEncode_Commit(IWICBitmapFrameEncode *iface)
396 {
397 IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
398 Handle handle;
399 OSErr ret;
400 HRESULT hr = S_OK;
401
402 TRACE("(%p)\n", iface);
403
404 EnterCriticalSection(&This->encoder->lock);
405
406 if (!This->icns_image || This->lines_written != This->size || This->committed)
407 {
408 hr = WINCODEC_ERR_WRONGSTATE;
409 goto end;
410 }
411
412 ret = PtrToHand(This->icns_image, &handle, This->size * This->size * 4);
413 if (ret != noErr || !handle)
414 {
415 WARN("PtrToHand failed with error %d\n", ret);
416 hr = E_FAIL;
417 goto end;
418 }
419
420 ret = SetIconFamilyData(This->encoder->icns_family, This->icns_type, handle);
421 DisposeHandle(handle);
422
423 if (ret != noErr)
424 {
425 WARN("SetIconFamilyData failed for image with error %d\n", ret);
426 hr = E_FAIL;
427 goto end;
428 }
429
430 This->committed = TRUE;
431 This->encoder->any_frame_committed = TRUE;
432 This->encoder->outstanding_commits--;
433
434 end:
435 LeaveCriticalSection(&This->encoder->lock);
436 return hr;
437 }
438
439 static HRESULT WINAPI IcnsFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface,
440 IWICMetadataQueryWriter **ppIMetadataQueryWriter)
441 {
442 FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter);
443 return E_NOTIMPL;
444 }
445
446 static const IWICBitmapFrameEncodeVtbl IcnsEncoder_FrameVtbl = {
447 IcnsFrameEncode_QueryInterface,
448 IcnsFrameEncode_AddRef,
449 IcnsFrameEncode_Release,
450 IcnsFrameEncode_Initialize,
451 IcnsFrameEncode_SetSize,
452 IcnsFrameEncode_SetResolution,
453 IcnsFrameEncode_SetPixelFormat,
454 IcnsFrameEncode_SetColorContexts,
455 IcnsFrameEncode_SetPalette,
456 IcnsFrameEncode_SetThumbnail,
457 IcnsFrameEncode_WritePixels,
458 IcnsFrameEncode_WriteSource,
459 IcnsFrameEncode_Commit,
460 IcnsFrameEncode_GetMetadataQueryWriter
461 };
462
463 static HRESULT WINAPI IcnsEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid,
464 void **ppv)
465 {
466 IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
467 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
468
469 if (!ppv) return E_INVALIDARG;
470
471 if (IsEqualIID(&IID_IUnknown, iid) ||
472 IsEqualIID(&IID_IWICBitmapEncoder, iid))
473 {
474 *ppv = &This->IWICBitmapEncoder_iface;
475 }
476 else
477 {
478 *ppv = NULL;
479 return E_NOINTERFACE;
480 }
481
482 IUnknown_AddRef((IUnknown*)*ppv);
483 return S_OK;
484 }
485
486 static ULONG WINAPI IcnsEncoder_AddRef(IWICBitmapEncoder *iface)
487 {
488 IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
489 ULONG ref = InterlockedIncrement(&This->ref);
490
491 TRACE("(%p) refcount=%u\n", iface, ref);
492
493 return ref;
494 }
495
496 static ULONG WINAPI IcnsEncoder_Release(IWICBitmapEncoder *iface)
497 {
498 IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
499 ULONG ref = InterlockedDecrement(&This->ref);
500
501 TRACE("(%p) refcount=%u\n", iface, ref);
502
503 if (ref == 0)
504 {
505 This->lock.DebugInfo->Spare[0] = 0;
506 DeleteCriticalSection(&This->lock);
507 if (This->icns_family)
508 DisposeHandle((Handle)This->icns_family);
509 if (This->stream)
510 IStream_Release(This->stream);
511 HeapFree(GetProcessHeap(), 0, This);
512 }
513
514 return ref;
515 }
516
517 static HRESULT WINAPI IcnsEncoder_Initialize(IWICBitmapEncoder *iface,
518 IStream *pIStream, WICBitmapEncoderCacheOption cacheOption)
519 {
520 IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
521 HRESULT hr = S_OK;
522
523 TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption);
524
525 EnterCriticalSection(&This->lock);
526
527 if (This->icns_family)
528 {
529 hr = WINCODEC_ERR_WRONGSTATE;
530 goto end;
531 }
532 This->icns_family = (IconFamilyHandle)NewHandle(0);
533 if (!This->icns_family)
534 {
535 WARN("error creating icns family\n");
536 hr = E_FAIL;
537 goto end;
538 }
539 IStream_AddRef(pIStream);
540 This->stream = pIStream;
541
542 end:
543 LeaveCriticalSection(&This->lock);
544
545 return hr;
546 }
547
548 static HRESULT WINAPI IcnsEncoder_GetContainerFormat(IWICBitmapEncoder *iface,
549 GUID *pguidContainerFormat)
550 {
551 FIXME("(%p,%s): stub\n", iface, debugstr_guid(pguidContainerFormat));
552 return E_NOTIMPL;
553 }
554
555 static HRESULT WINAPI IcnsEncoder_GetEncoderInfo(IWICBitmapEncoder *iface,
556 IWICBitmapEncoderInfo **ppIEncoderInfo)
557 {
558 FIXME("(%p,%p): stub\n", iface, ppIEncoderInfo);
559 return E_NOTIMPL;
560 }
561
562 static HRESULT WINAPI IcnsEncoder_SetColorContexts(IWICBitmapEncoder *iface,
563 UINT cCount, IWICColorContext **ppIColorContext)
564 {
565 FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
566 return E_NOTIMPL;
567 }
568
569 static HRESULT WINAPI IcnsEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *pIPalette)
570 {
571 TRACE("(%p,%p)\n", iface, pIPalette);
572 return WINCODEC_ERR_UNSUPPORTEDOPERATION;
573 }
574
575 static HRESULT WINAPI IcnsEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail)
576 {
577 TRACE("(%p,%p)\n", iface, pIThumbnail);
578 return WINCODEC_ERR_UNSUPPORTEDOPERATION;
579 }
580
581 static HRESULT WINAPI IcnsEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview)
582 {
583 TRACE("(%p,%p)\n", iface, pIPreview);
584 return WINCODEC_ERR_UNSUPPORTEDOPERATION;
585 }
586
587 static HRESULT WINAPI IcnsEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
588 IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions)
589 {
590 IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
591 HRESULT hr = S_OK;
592 IcnsFrameEncode *frameEncode = NULL;
593
594 TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);
595
596 EnterCriticalSection(&This->lock);
597
598 if (!This->icns_family)
599 {
600 hr = WINCODEC_ERR_NOTINITIALIZED;
601 goto end;
602 }
603
604 hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions);
605 if (FAILED(hr))
606 goto end;
607
608 frameEncode = HeapAlloc(GetProcessHeap(), 0, sizeof(IcnsFrameEncode));
609 if (frameEncode == NULL)
610 {
611 hr = E_OUTOFMEMORY;
612 goto end;
613 }
614 frameEncode->IWICBitmapFrameEncode_iface.lpVtbl = &IcnsEncoder_FrameVtbl;
615 frameEncode->encoder = This;
616 frameEncode->ref = 1;
617 frameEncode->initialized = FALSE;
618 frameEncode->size = 0;
619 frameEncode->icns_image = NULL;
620 frameEncode->lines_written = 0;
621 frameEncode->committed = FALSE;
622 *ppIFrameEncode = &frameEncode->IWICBitmapFrameEncode_iface;
623 This->outstanding_commits++;
624 IWICBitmapEncoder_AddRef(&This->IWICBitmapEncoder_iface);
625
626 end:
627 LeaveCriticalSection(&This->lock);
628
629 return hr;
630 }
631
632 static HRESULT WINAPI IcnsEncoder_Commit(IWICBitmapEncoder *iface)
633 {
634 IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface);
635 size_t buffer_size;
636 HRESULT hr = S_OK;
637 ULONG byteswritten;
638
639 TRACE("(%p)\n", iface);
640
641 EnterCriticalSection(&This->lock);
642
643 if (!This->any_frame_committed || This->outstanding_commits > 0 || This->committed)
644 {
645 hr = WINCODEC_ERR_WRONGSTATE;
646 goto end;
647 }
648
649 buffer_size = GetHandleSize((Handle)This->icns_family);
650 hr = IStream_Write(This->stream, *This->icns_family, buffer_size, &byteswritten);
651 if (FAILED(hr) || byteswritten != buffer_size)
652 {
653 WARN("writing file failed, hr = 0x%08X\n", hr);
654 hr = E_FAIL;
655 goto end;
656 }
657
658 This->committed = TRUE;
659
660 end:
661 LeaveCriticalSection(&This->lock);
662 return hr;
663 }
664
665 static HRESULT WINAPI IcnsEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface,
666 IWICMetadataQueryWriter **ppIMetadataQueryWriter)
667 {
668 FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter);
669 return E_NOTIMPL;
670 }
671
672 static const IWICBitmapEncoderVtbl IcnsEncoder_Vtbl = {
673 IcnsEncoder_QueryInterface,
674 IcnsEncoder_AddRef,
675 IcnsEncoder_Release,
676 IcnsEncoder_Initialize,
677 IcnsEncoder_GetContainerFormat,
678 IcnsEncoder_GetEncoderInfo,
679 IcnsEncoder_SetColorContexts,
680 IcnsEncoder_SetPalette,
681 IcnsEncoder_SetThumbnail,
682 IcnsEncoder_SetPreview,
683 IcnsEncoder_CreateNewFrame,
684 IcnsEncoder_Commit,
685 IcnsEncoder_GetMetadataQueryWriter
686 };
687
688 HRESULT IcnsEncoder_CreateInstance(REFIID iid, void** ppv)
689 {
690 IcnsEncoder *This;
691 HRESULT ret;
692
693 TRACE("(%s,%p)\n", debugstr_guid(iid), ppv);
694
695 *ppv = NULL;
696
697 This = HeapAlloc(GetProcessHeap(), 0, sizeof(IcnsEncoder));
698 if (!This) return E_OUTOFMEMORY;
699
700 This->IWICBitmapEncoder_iface.lpVtbl = &IcnsEncoder_Vtbl;
701 This->ref = 1;
702 This->stream = NULL;
703 This->icns_family = NULL;
704 This->any_frame_committed = FALSE;
705 This->outstanding_commits = 0;
706 This->committed = FALSE;
707 InitializeCriticalSection(&This->lock);
708 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IcnsEncoder.lock");
709
710 ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv);
711 IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface);
712
713 return ret;
714 }
715
716 #else /* !defined(HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H) ||
717 MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 */
718
719 HRESULT IcnsEncoder_CreateInstance(REFIID iid, void** ppv)
720 {
721 ERR("Trying to save ICNS picture, but ICNS support is not compiled in.\n");
722 return E_FAIL;
723 }
724
725 #endif