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
24 #include "wine/port.h"
28 #ifdef HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H
29 #define GetCurrentProcess GetCurrentProcess_Mac
30 #define GetCurrentThread GetCurrentThread_Mac
31 #define LoadResource LoadResource_Mac
32 #define AnimatePalette AnimatePalette_Mac
33 #define EqualRgn EqualRgn_Mac
34 #define FillRgn FillRgn_Mac
35 #define FrameRgn FrameRgn_Mac
36 #define GetPixel GetPixel_Mac
37 #define InvertRgn InvertRgn_Mac
38 #define LineTo LineTo_Mac
39 #define OffsetRgn OffsetRgn_Mac
40 #define PaintRgn PaintRgn_Mac
41 #define Polygon Polygon_Mac
42 #define ResizePalette ResizePalette_Mac
43 #define SetRectRgn SetRectRgn_Mac
44 #define EqualRect EqualRect_Mac
45 #define FillRect FillRect_Mac
46 #define FrameRect FrameRect_Mac
47 #define GetCursor GetCursor_Mac
48 #define InvertRect InvertRect_Mac
49 #define OffsetRect OffsetRect_Mac
50 #define PtInRect PtInRect_Mac
51 #define SetCursor SetCursor_Mac
52 #define SetRect SetRect_Mac
53 #define ShowCursor ShowCursor_Mac
54 #define UnionRect UnionRect_Mac
55 #include <ApplicationServices/ApplicationServices.h>
56 #undef GetCurrentProcess
57 #undef GetCurrentThread
85 #define WIN32_NO_STATUS
91 #include "wincodecs_private.h"
93 #include "wine/debug.h"
95 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
97 #if defined(HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H) && \
98 MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4
100 typedef struct IcnsEncoder
{
101 struct encoder encoder
;
103 IconFamilyHandle icns_family
;
104 struct encoder_frame frame
;
110 static inline IcnsEncoder
*impl_from_encoder(struct encoder
*iface
)
112 return CONTAINING_RECORD(iface
, IcnsEncoder
, encoder
);
115 void CDECL
IcnsEncoder_destroy(struct encoder
*iface
)
117 IcnsEncoder
*This
= impl_from_encoder(iface
);
119 free(This
->icns_image
);
121 if (This
->icns_family
)
122 DisposeHandle((Handle
)This
->icns_family
);
124 RtlFreeHeap(GetProcessHeap(), 0, This
);
127 HRESULT CDECL
IcnsEncoder_get_supported_format(struct encoder
*iface
,
128 GUID
*pixel_format
, DWORD
*bpp
, BOOL
*indexed
)
130 *pixel_format
= GUID_WICPixelFormat32bppBGRA
;
136 HRESULT CDECL
IcnsEncoder_create_frame(struct encoder
*iface
, const struct encoder_frame
*frame
)
138 IcnsEncoder
*This
= impl_from_encoder(iface
);
140 This
->frame
= *frame
;
142 switch (frame
->width
)
144 case 16: This
->icns_type
= kIconServices16PixelDataARGB
; break;
145 case 32: This
->icns_type
= kIconServices32PixelDataARGB
; break;
146 case 48: This
->icns_type
= kIconServices48PixelDataARGB
; break;
147 case 128: This
->icns_type
= kIconServices128PixelDataARGB
; break;
148 case 256: This
->icns_type
= kIconServices256PixelDataARGB
; break;
149 case 512: This
->icns_type
= kIconServices512PixelDataARGB
; break;
151 ERR("cannot generate ICNS icon from %dx%d image\n", frame
->width
, frame
->height
);
154 This
->icns_image
= malloc(frame
->width
* frame
->height
* 4);
155 if (!This
->icns_image
)
157 WARN("failed to allocate image buffer\n");
160 This
->lines_written
= 0;
165 static HRESULT CDECL
IcnsEncoder_write_lines(struct encoder
* iface
,
166 BYTE
*data
, DWORD line_count
, DWORD stride
)
168 IcnsEncoder
*This
= impl_from_encoder(iface
);
171 for (i
= 0; i
< line_count
; i
++)
173 BYTE
*src_row
, *dst_row
;
175 src_row
= data
+ stride
* i
;
176 dst_row
= This
->icns_image
+ (This
->lines_written
+ i
)*(This
->frame
.width
*4);
177 /* swap bgr -> rgb */
178 for (j
= 0; j
< This
->frame
.width
*4; j
+= 4)
180 dst_row
[j
] = src_row
[j
+3];
181 dst_row
[j
+1] = src_row
[j
+2];
182 dst_row
[j
+2] = src_row
[j
+1];
183 dst_row
[j
+3] = src_row
[j
];
186 This
->lines_written
+= line_count
;
191 static HRESULT CDECL
IcnsEncoder_commit_frame(struct encoder
*iface
)
193 IcnsEncoder
*This
= impl_from_encoder(iface
);
197 ret
= PtrToHand(This
->icns_image
, &handle
, This
->frame
.width
* This
->frame
.height
* 4);
198 if (ret
!= noErr
|| !handle
)
200 WARN("PtrToHand failed with error %d\n", ret
);
204 ret
= SetIconFamilyData(This
->icns_family
, This
->icns_type
, handle
);
205 DisposeHandle(handle
);
209 WARN("SetIconFamilyData failed for image with error %d\n", ret
);
213 free(This
->icns_image
);
214 This
->icns_image
= NULL
;
219 static HRESULT CDECL
IcnsEncoder_initialize(struct encoder
*iface
, IStream
*stream
)
221 IcnsEncoder
*This
= impl_from_encoder(iface
);
223 This
->icns_family
= (IconFamilyHandle
)NewHandle(0);
224 if (!This
->icns_family
)
226 WARN("error creating icns family\n");
230 This
->stream
= stream
;
235 static HRESULT CDECL
IcnsEncoder_commit_file(struct encoder
*iface
)
237 IcnsEncoder
*This
= impl_from_encoder(iface
);
242 buffer_size
= GetHandleSize((Handle
)This
->icns_family
);
243 hr
= stream_write(This
->stream
, *This
->icns_family
, buffer_size
, &byteswritten
);
244 if (FAILED(hr
) || byteswritten
!= buffer_size
)
246 WARN("writing file failed, hr = 0x%08X\n", hr
);
253 static const struct encoder_funcs IcnsEncoder_vtable
= {
254 IcnsEncoder_initialize
,
255 IcnsEncoder_get_supported_format
,
256 IcnsEncoder_create_frame
,
257 IcnsEncoder_write_lines
,
258 IcnsEncoder_commit_frame
,
259 IcnsEncoder_commit_file
,
263 HRESULT CDECL
icns_encoder_create(struct encoder_info
*info
, struct encoder
**result
)
269 This
= RtlAllocateHeap(GetProcessHeap(), 0, sizeof(IcnsEncoder
));
270 if (!This
) return E_OUTOFMEMORY
;
272 This
->encoder
.vtable
= &IcnsEncoder_vtable
;
274 This
->icns_family
= NULL
;
275 This
->icns_image
= NULL
;
277 *result
= &This
->encoder
;
278 info
->flags
= ENCODER_FLAGS_MULTI_FRAME
|ENCODER_FLAGS_ICNS_SIZE
;
279 info
->container_format
= GUID_WineContainerFormatIcns
;
280 info
->clsid
= CLSID_WICIcnsEncoder
;
281 info
->encoder_options
[0] = ENCODER_OPTION_END
;
286 #else /* !defined(HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H) ||
287 MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 */
289 HRESULT CDECL
icns_encoder_create(struct encoder_info
*info
, struct encoder
**result
)
291 ERR("Trying to save ICNS picture, but ICNS support is not compiled in.\n");