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