2 * Copyright 2009 Vincent Povirk for CodeWeavers
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
33 #include "wine/debug.h"
35 #include "wincodecs_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
39 /***********************************************************************
40 * interface for self-registering
42 struct decoder_pattern
44 DWORD length
; /* 0 for end of list */
53 CLSID
const *clsid
; /* NULL for end of list */
58 GUID
const *container_format
;
61 GUID
const * const *formats
;
62 const struct decoder_pattern
*patterns
;
65 static HRESULT
register_decoders(struct regsvr_decoder
const *list
);
66 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
);
70 CLSID
const *clsid
; /* NULL for end of list */
75 GUID
const *container_format
;
78 GUID
const * const *formats
;
81 static HRESULT
register_encoders(struct regsvr_encoder
const *list
);
82 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
);
84 struct regsvr_converter
86 CLSID
const *clsid
; /* NULL for end of list */
91 GUID
const * const *formats
;
94 static HRESULT
register_converters(struct regsvr_converter
const *list
);
95 static HRESULT
unregister_converters(struct regsvr_converter
const *list
);
97 struct metadata_pattern
106 struct reader_containers
109 const struct metadata_pattern
*patterns
;
112 struct regsvr_metadatareader
114 CLSID
const *clsid
; /* NULL for end of list */
120 GUID
const *metadata_format
;
121 DWORD requires_fullstream
;
122 DWORD supports_padding
;
123 DWORD requires_fixedsize
;
124 const struct reader_containers
*containers
;
127 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
);
128 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
);
130 struct regsvr_pixelformat
132 CLSID
const *clsid
; /* NULL for end of list */
139 BYTE
const * const *channelmasks
;
140 WICPixelFormatNumericRepresentation numericrepresentation
;
144 static HRESULT
register_pixelformats(struct regsvr_pixelformat
const *list
);
145 static HRESULT
unregister_pixelformats(struct regsvr_pixelformat
const *list
);
147 /***********************************************************************
148 * static string constants
150 static const WCHAR clsid_keyname
[] = L
"CLSID";
151 static const char author_valuename
[] = "Author";
152 static const char friendlyname_valuename
[] = "FriendlyName";
153 static const WCHAR vendor_valuename
[] = L
"Vendor";
154 static const WCHAR containerformat_valuename
[] = L
"ContainerFormat";
155 static const char version_valuename
[] = "Version";
156 static const char mimetypes_valuename
[] = "MimeTypes";
157 static const char extensions_valuename
[] = "FileExtensions";
158 static const WCHAR formats_keyname
[] = L
"Formats";
159 static const WCHAR patterns_keyname
[] = L
"Patterns";
160 static const WCHAR instance_keyname
[] = L
"Instance";
161 static const WCHAR clsid_valuename
[] = L
"CLSID";
162 static const char length_valuename
[] = "Length";
163 static const char position_valuename
[] = "Position";
164 static const char pattern_valuename
[] = "Pattern";
165 static const char mask_valuename
[] = "Mask";
166 static const char endofstream_valuename
[] = "EndOfStream";
167 static const WCHAR pixelformats_keyname
[] = L
"PixelFormats";
168 static const WCHAR metadataformat_valuename
[] = L
"MetadataFormat";
169 static const char specversion_valuename
[] = "SpecVersion";
170 static const char requiresfullstream_valuename
[] = "RequiresFullStream";
171 static const char supportspadding_valuename
[] = "SupportsPadding";
172 static const char requiresfixedsize_valuename
[] = "FixedSize";
173 static const WCHAR containers_keyname
[] = L
"Containers";
174 static const char dataoffset_valuename
[] = "DataOffset";
175 static const char bitsperpixel_valuename
[] = "BitLength";
176 static const char channelcount_valuename
[] = "ChannelCount";
177 static const char numericrepresentation_valuename
[] = "NumericRepresentation";
178 static const char supportstransparency_valuename
[] = "SupportsTransparency";
179 static const WCHAR channelmasks_keyname
[] = L
"ChannelMasks";
181 /***********************************************************************
184 static HRESULT
register_decoders(struct regsvr_decoder
const *list
)
186 LONG res
= ERROR_SUCCESS
;
192 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
193 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
194 if (res
== ERROR_SUCCESS
) {
195 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
196 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
197 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
198 if (res
== ERROR_SUCCESS
)
200 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
201 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
202 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
204 if (res
!= ERROR_SUCCESS
)
205 RegCloseKey(coclass_key
);
207 if (res
!= ERROR_SUCCESS
) goto error_return
;
209 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
211 HKEY instance_clsid_key
;
213 StringFromGUID2(list
->clsid
, buf
, 39);
214 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
215 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
216 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
218 StringFromGUID2(list
->clsid
, buf
, 39);
219 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
220 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
221 if (res
== ERROR_SUCCESS
) {
222 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
223 (const BYTE
*)buf
, 78);
224 RegCloseKey(instance_clsid_key
);
226 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
229 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
230 (const BYTE
*)list
->author
,
231 strlen(list
->author
) + 1);
232 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
235 if (list
->friendlyname
) {
236 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
237 (const BYTE
*)list
->friendlyname
,
238 strlen(list
->friendlyname
) + 1);
239 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
243 StringFromGUID2(list
->vendor
, buf
, 39);
244 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
245 (const BYTE
*)buf
, 78);
246 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
249 if (list
->container_format
) {
250 StringFromGUID2(list
->container_format
, buf
, 39);
251 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
252 (const BYTE
*)buf
, 78);
253 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
257 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
258 (const BYTE
*)list
->version
,
259 strlen(list
->version
) + 1);
260 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
263 if (list
->mimetypes
) {
264 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
265 (const BYTE
*)list
->mimetypes
,
266 strlen(list
->mimetypes
) + 1);
267 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
270 if (list
->extensions
) {
271 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
272 (const BYTE
*)list
->extensions
,
273 strlen(list
->extensions
) + 1);
274 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
279 GUID
const * const *format
;
281 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
282 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
283 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
284 for (format
=list
->formats
; *format
; ++format
)
287 StringFromGUID2(*format
, buf
, 39);
288 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
289 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
290 if (res
!= ERROR_SUCCESS
) break;
291 RegCloseKey(format_key
);
293 RegCloseKey(formats_key
);
294 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
297 if (list
->patterns
) {
301 res
= RegCreateKeyExW(clsid_key
, patterns_keyname
, 0, NULL
, 0,
302 KEY_READ
| KEY_WRITE
, NULL
, &patterns_key
, NULL
);
303 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
304 for (i
=0; list
->patterns
[i
].length
; i
++)
307 swprintf(buf
, 39, L
"%i", i
);
308 res
= RegCreateKeyExW(patterns_key
, buf
, 0, NULL
, 0,
309 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
310 if (res
!= ERROR_SUCCESS
) break;
311 res
= RegSetValueExA(pattern_key
, length_valuename
, 0, REG_DWORD
,
312 (const BYTE
*)&list
->patterns
[i
].length
, 4);
313 if (res
== ERROR_SUCCESS
)
314 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
315 (const BYTE
*)&list
->patterns
[i
].position
, 4);
316 if (res
== ERROR_SUCCESS
)
317 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
318 list
->patterns
[i
].pattern
,
319 list
->patterns
[i
].length
);
320 if (res
== ERROR_SUCCESS
)
321 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
322 list
->patterns
[i
].mask
,
323 list
->patterns
[i
].length
);
324 if (res
== ERROR_SUCCESS
)
325 res
= RegSetValueExA(pattern_key
, endofstream_valuename
, 0, REG_DWORD
,
326 (const BYTE
*)&list
->patterns
[i
].endofstream
, 4);
327 RegCloseKey(pattern_key
);
329 RegCloseKey(patterns_key
);
330 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
333 error_close_clsid_key
:
334 RegCloseKey(clsid_key
);
337 error_close_coclass_key
:
338 RegCloseKey(instance_key
);
339 RegCloseKey(decoders_key
);
340 RegCloseKey(coclass_key
);
342 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
345 /***********************************************************************
346 * unregister_decoders
348 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
)
350 LONG res
= ERROR_SUCCESS
;
356 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
357 KEY_READ
| KEY_WRITE
, &coclass_key
);
358 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
360 if (res
== ERROR_SUCCESS
) {
361 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
362 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
363 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
364 if (res
== ERROR_SUCCESS
)
366 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
367 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
368 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
370 if (res
!= ERROR_SUCCESS
)
371 RegCloseKey(coclass_key
);
373 if (res
!= ERROR_SUCCESS
) goto error_return
;
375 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
376 StringFromGUID2(list
->clsid
, buf
, 39);
378 res
= RegDeleteTreeW(coclass_key
, buf
);
379 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
380 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
382 res
= RegDeleteTreeW(instance_key
, buf
);
383 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
384 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
387 error_close_coclass_key
:
388 RegCloseKey(instance_key
);
389 RegCloseKey(decoders_key
);
390 RegCloseKey(coclass_key
);
392 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
395 /***********************************************************************
398 static HRESULT
register_encoders(struct regsvr_encoder
const *list
)
400 LONG res
= ERROR_SUCCESS
;
406 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
407 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
408 if (res
== ERROR_SUCCESS
) {
409 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
410 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
411 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
412 if (res
== ERROR_SUCCESS
)
414 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
415 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
416 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
418 if (res
!= ERROR_SUCCESS
)
419 RegCloseKey(coclass_key
);
421 if (res
!= ERROR_SUCCESS
) goto error_return
;
423 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
425 HKEY instance_clsid_key
;
427 StringFromGUID2(list
->clsid
, buf
, 39);
428 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
429 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
430 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
432 StringFromGUID2(list
->clsid
, buf
, 39);
433 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
434 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
435 if (res
== ERROR_SUCCESS
) {
436 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
437 (const BYTE
*)buf
, 78);
438 RegCloseKey(instance_clsid_key
);
440 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
443 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
444 (const BYTE
*)list
->author
,
445 strlen(list
->author
) + 1);
446 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
449 if (list
->friendlyname
) {
450 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
451 (const BYTE
*)list
->friendlyname
,
452 strlen(list
->friendlyname
) + 1);
453 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
457 StringFromGUID2(list
->vendor
, buf
, 39);
458 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
459 (const BYTE
*)buf
, 78);
460 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
463 if (list
->container_format
) {
464 StringFromGUID2(list
->container_format
, buf
, 39);
465 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
466 (const BYTE
*)buf
, 78);
467 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
471 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
472 (const BYTE
*)list
->version
,
473 strlen(list
->version
) + 1);
474 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
477 if (list
->mimetypes
) {
478 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
479 (const BYTE
*)list
->mimetypes
,
480 strlen(list
->mimetypes
) + 1);
481 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
484 if (list
->extensions
) {
485 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
486 (const BYTE
*)list
->extensions
,
487 strlen(list
->extensions
) + 1);
488 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
493 GUID
const * const *format
;
495 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
496 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
497 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
498 for (format
=list
->formats
; *format
; ++format
)
501 StringFromGUID2(*format
, buf
, 39);
502 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
503 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
504 if (res
!= ERROR_SUCCESS
) break;
505 RegCloseKey(format_key
);
507 RegCloseKey(formats_key
);
508 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
511 error_close_clsid_key
:
512 RegCloseKey(clsid_key
);
515 error_close_coclass_key
:
516 RegCloseKey(instance_key
);
517 RegCloseKey(encoders_key
);
518 RegCloseKey(coclass_key
);
520 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
523 /***********************************************************************
524 * unregister_encoders
526 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
)
528 LONG res
= ERROR_SUCCESS
;
534 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
535 KEY_READ
| KEY_WRITE
, &coclass_key
);
536 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
538 if (res
== ERROR_SUCCESS
) {
539 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
540 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
541 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
542 if (res
== ERROR_SUCCESS
)
544 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
545 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
546 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
548 if (res
!= ERROR_SUCCESS
)
549 RegCloseKey(coclass_key
);
551 if (res
!= ERROR_SUCCESS
) goto error_return
;
553 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
554 StringFromGUID2(list
->clsid
, buf
, 39);
556 res
= RegDeleteTreeW(coclass_key
, buf
);
557 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
558 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
560 res
= RegDeleteTreeW(instance_key
, buf
);
561 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
562 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
565 error_close_coclass_key
:
566 RegCloseKey(instance_key
);
567 RegCloseKey(encoders_key
);
568 RegCloseKey(coclass_key
);
570 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
573 /***********************************************************************
574 * register_converters
576 static HRESULT
register_converters(struct regsvr_converter
const *list
)
578 LONG res
= ERROR_SUCCESS
;
584 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
585 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
586 if (res
== ERROR_SUCCESS
) {
587 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
588 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
589 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
590 if (res
== ERROR_SUCCESS
)
592 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
593 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
594 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
596 if (res
!= ERROR_SUCCESS
)
597 RegCloseKey(coclass_key
);
599 if (res
!= ERROR_SUCCESS
) goto error_return
;
601 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
603 HKEY instance_clsid_key
;
605 StringFromGUID2(list
->clsid
, buf
, 39);
606 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
607 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
608 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
610 StringFromGUID2(list
->clsid
, buf
, 39);
611 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
612 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
613 if (res
== ERROR_SUCCESS
) {
614 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
615 (const BYTE
*)buf
, 78);
616 RegCloseKey(instance_clsid_key
);
618 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
621 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
622 (const BYTE
*)list
->author
,
623 strlen(list
->author
) + 1);
624 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
627 if (list
->friendlyname
) {
628 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
629 (const BYTE
*)list
->friendlyname
,
630 strlen(list
->friendlyname
) + 1);
631 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
635 StringFromGUID2(list
->vendor
, buf
, 39);
636 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
637 (const BYTE
*)buf
, 78);
638 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
642 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
643 (const BYTE
*)list
->version
,
644 strlen(list
->version
) + 1);
645 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
650 GUID
const * const *format
;
652 res
= RegCreateKeyExW(clsid_key
, pixelformats_keyname
, 0, NULL
, 0,
653 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
654 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
655 for (format
=list
->formats
; *format
; ++format
)
658 StringFromGUID2(*format
, buf
, 39);
659 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
660 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
661 if (res
!= ERROR_SUCCESS
) break;
662 RegCloseKey(format_key
);
664 RegCloseKey(formats_key
);
665 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
668 error_close_clsid_key
:
669 RegCloseKey(clsid_key
);
672 error_close_coclass_key
:
673 RegCloseKey(instance_key
);
674 RegCloseKey(converters_key
);
675 RegCloseKey(coclass_key
);
677 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
680 /***********************************************************************
681 * unregister_converters
683 static HRESULT
unregister_converters(struct regsvr_converter
const *list
)
685 LONG res
= ERROR_SUCCESS
;
691 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
692 KEY_READ
| KEY_WRITE
, &coclass_key
);
693 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
695 if (res
== ERROR_SUCCESS
) {
696 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
697 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
698 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
699 if (res
== ERROR_SUCCESS
)
701 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
702 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
703 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
705 if (res
!= ERROR_SUCCESS
)
706 RegCloseKey(coclass_key
);
708 if (res
!= ERROR_SUCCESS
) goto error_return
;
710 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
711 StringFromGUID2(list
->clsid
, buf
, 39);
713 res
= RegDeleteTreeW(coclass_key
, buf
);
714 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
715 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
717 res
= RegDeleteTreeW(instance_key
, buf
);
718 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
719 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
722 error_close_coclass_key
:
723 RegCloseKey(instance_key
);
724 RegCloseKey(converters_key
);
725 RegCloseKey(coclass_key
);
727 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
730 /***********************************************************************
731 * register_metadatareaders
733 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
)
735 LONG res
= ERROR_SUCCESS
;
741 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
742 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
743 if (res
== ERROR_SUCCESS
) {
744 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
745 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
746 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
747 if (res
== ERROR_SUCCESS
)
749 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
750 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
751 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
753 if (res
!= ERROR_SUCCESS
)
754 RegCloseKey(coclass_key
);
756 if (res
!= ERROR_SUCCESS
) goto error_return
;
758 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
760 HKEY instance_clsid_key
;
762 StringFromGUID2(list
->clsid
, buf
, 39);
763 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
764 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
765 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
767 StringFromGUID2(list
->clsid
, buf
, 39);
768 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
769 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
770 if (res
== ERROR_SUCCESS
) {
771 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
772 (const BYTE
*)buf
, 78);
773 RegCloseKey(instance_clsid_key
);
775 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
778 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
779 (const BYTE
*)list
->author
,
780 strlen(list
->author
) + 1);
781 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
784 if (list
->friendlyname
) {
785 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
786 (const BYTE
*)list
->friendlyname
,
787 strlen(list
->friendlyname
) + 1);
788 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
792 StringFromGUID2(list
->vendor
, buf
, 39);
793 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
794 (const BYTE
*)buf
, 78);
795 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
798 if (list
->metadata_format
) {
799 StringFromGUID2(list
->metadata_format
, buf
, 39);
800 res
= RegSetValueExW(clsid_key
, metadataformat_valuename
, 0, REG_SZ
,
801 (const BYTE
*)buf
, 78);
802 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
806 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
807 (const BYTE
*)list
->version
,
808 strlen(list
->version
) + 1);
809 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
812 if (list
->specversion
) {
813 res
= RegSetValueExA(clsid_key
, specversion_valuename
, 0, REG_SZ
,
814 (const BYTE
*)list
->version
,
815 strlen(list
->version
) + 1);
816 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
819 res
= RegSetValueExA(clsid_key
, requiresfullstream_valuename
, 0, REG_DWORD
,
820 (const BYTE
*)&list
->requires_fullstream
, 4);
821 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
823 res
= RegSetValueExA(clsid_key
, supportspadding_valuename
, 0, REG_DWORD
,
824 (const BYTE
*)&list
->supports_padding
, 4);
825 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
827 if (list
->requires_fixedsize
) {
828 res
= RegSetValueExA(clsid_key
, requiresfixedsize_valuename
, 0, REG_DWORD
,
829 (const BYTE
*)&list
->requires_fixedsize
, 4);
830 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
833 if (list
->containers
) {
835 const struct reader_containers
*container
;
837 res
= RegCreateKeyExW(clsid_key
, containers_keyname
, 0, NULL
, 0,
838 KEY_READ
| KEY_WRITE
, NULL
, &containers_key
, NULL
);
839 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
840 for (container
=list
->containers
; container
->format
; ++container
)
844 StringFromGUID2(container
->format
, buf
, 39);
845 res
= RegCreateKeyExW(containers_key
, buf
, 0, NULL
, 0,
846 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
847 if (res
!= ERROR_SUCCESS
) break;
849 for (i
=0; container
->patterns
[i
].length
; i
++)
852 swprintf(buf
, 39, L
"%i", i
);
853 res
= RegCreateKeyExW(format_key
, buf
, 0, NULL
, 0,
854 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
855 if (res
!= ERROR_SUCCESS
) break;
856 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
857 (const BYTE
*)&container
->patterns
[i
].position
, 4);
858 if (res
== ERROR_SUCCESS
)
859 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
860 container
->patterns
[i
].pattern
,
861 container
->patterns
[i
].length
);
862 if (res
== ERROR_SUCCESS
)
863 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
864 container
->patterns
[i
].mask
,
865 container
->patterns
[i
].length
);
866 if (res
== ERROR_SUCCESS
&& container
->patterns
[i
].data_offset
)
867 res
= RegSetValueExA(pattern_key
, dataoffset_valuename
, 0, REG_DWORD
,
868 (const BYTE
*)&container
->patterns
[i
].data_offset
, 4);
869 RegCloseKey(pattern_key
);
872 RegCloseKey(format_key
);
874 RegCloseKey(containers_key
);
877 error_close_clsid_key
:
878 RegCloseKey(clsid_key
);
881 error_close_coclass_key
:
882 RegCloseKey(instance_key
);
883 RegCloseKey(readers_key
);
884 RegCloseKey(coclass_key
);
886 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
889 /***********************************************************************
890 * unregister_metadatareaders
892 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
)
894 LONG res
= ERROR_SUCCESS
;
900 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
901 KEY_READ
| KEY_WRITE
, &coclass_key
);
902 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
904 if (res
== ERROR_SUCCESS
) {
905 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
906 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
907 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
908 if (res
== ERROR_SUCCESS
)
910 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
911 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
912 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
914 if (res
!= ERROR_SUCCESS
)
915 RegCloseKey(coclass_key
);
917 if (res
!= ERROR_SUCCESS
) goto error_return
;
919 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
920 StringFromGUID2(list
->clsid
, buf
, 39);
922 res
= RegDeleteTreeW(coclass_key
, buf
);
923 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
924 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
926 res
= RegDeleteTreeW(instance_key
, buf
);
927 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
928 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
931 error_close_coclass_key
:
932 RegCloseKey(instance_key
);
933 RegCloseKey(readers_key
);
934 RegCloseKey(coclass_key
);
936 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
939 /***********************************************************************
940 * register_pixelformats
942 static HRESULT
register_pixelformats(struct regsvr_pixelformat
const *list
)
944 LONG res
= ERROR_SUCCESS
;
950 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
951 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
952 if (res
== ERROR_SUCCESS
) {
953 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
954 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
955 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
956 if (res
== ERROR_SUCCESS
)
958 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
959 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
960 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
962 if (res
!= ERROR_SUCCESS
)
963 RegCloseKey(coclass_key
);
965 if (res
!= ERROR_SUCCESS
) goto error_return
;
967 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
969 HKEY instance_clsid_key
;
971 StringFromGUID2(list
->clsid
, buf
, 39);
972 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
973 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
974 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
976 StringFromGUID2(list
->clsid
, buf
, 39);
977 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
978 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
979 if (res
== ERROR_SUCCESS
) {
980 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
981 (const BYTE
*)buf
, 78);
982 RegCloseKey(instance_clsid_key
);
984 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
987 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
988 (const BYTE
*)list
->author
,
989 strlen(list
->author
) + 1);
990 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
993 if (list
->friendlyname
) {
994 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
995 (const BYTE
*)list
->friendlyname
,
996 strlen(list
->friendlyname
) + 1);
997 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1001 StringFromGUID2(list
->vendor
, buf
, 39);
1002 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
1003 (const BYTE
*)buf
, 78);
1004 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1007 if (list
->version
) {
1008 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
1009 (const BYTE
*)list
->version
,
1010 strlen(list
->version
) + 1);
1011 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1014 res
= RegSetValueExA(clsid_key
, bitsperpixel_valuename
, 0, REG_DWORD
,
1015 (const BYTE
*)&list
->bitsperpixel
, 4);
1016 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1018 res
= RegSetValueExA(clsid_key
, channelcount_valuename
, 0, REG_DWORD
,
1019 (const BYTE
*)&list
->channelcount
, 4);
1020 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1022 res
= RegSetValueExA(clsid_key
, numericrepresentation_valuename
, 0, REG_DWORD
,
1023 (const BYTE
*)&list
->numericrepresentation
, 4);
1024 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1026 res
= RegSetValueExA(clsid_key
, supportstransparency_valuename
, 0, REG_DWORD
,
1027 (const BYTE
*)&list
->supportsalpha
, 4);
1028 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1030 if (list
->channelmasks
) {
1033 WCHAR mask_valuename
[11];
1035 mask_size
= (list
->bitsperpixel
+ 7)/8;
1037 res
= RegCreateKeyExW(clsid_key
, channelmasks_keyname
, 0, NULL
, 0,
1038 KEY_READ
| KEY_WRITE
, NULL
, &masks_key
, NULL
);
1039 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1040 for (i
=0; i
< list
->channelcount
; i
++)
1042 swprintf(mask_valuename
, ARRAY_SIZE(mask_valuename
), L
"%d", i
);
1043 res
= RegSetValueExW(masks_key
, mask_valuename
, 0, REG_BINARY
,
1044 list
->channelmasks
[i
], mask_size
);
1045 if (res
!= ERROR_SUCCESS
) break;
1047 RegCloseKey(masks_key
);
1048 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1051 error_close_clsid_key
:
1052 RegCloseKey(clsid_key
);
1055 error_close_coclass_key
:
1056 RegCloseKey(instance_key
);
1057 RegCloseKey(formats_key
);
1058 RegCloseKey(coclass_key
);
1060 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1063 /***********************************************************************
1064 * unregister_pixelformats
1066 static HRESULT
unregister_pixelformats(struct regsvr_pixelformat
const *list
)
1068 LONG res
= ERROR_SUCCESS
;
1074 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
1075 KEY_READ
| KEY_WRITE
, &coclass_key
);
1076 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
1078 if (res
== ERROR_SUCCESS
) {
1079 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
1080 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
1081 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
1082 if (res
== ERROR_SUCCESS
)
1084 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
1085 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
1086 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1088 if (res
!= ERROR_SUCCESS
)
1089 RegCloseKey(coclass_key
);
1091 if (res
!= ERROR_SUCCESS
) goto error_return
;
1093 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
1094 StringFromGUID2(list
->clsid
, buf
, 39);
1096 res
= RegDeleteTreeW(coclass_key
, buf
);
1097 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1098 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1100 res
= RegDeleteTreeW(instance_key
, buf
);
1101 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1102 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1105 error_close_coclass_key
:
1106 RegCloseKey(instance_key
);
1107 RegCloseKey(formats_key
);
1108 RegCloseKey(coclass_key
);
1110 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1113 /***********************************************************************
1116 static const BYTE mask_all
[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1118 static const BYTE bmp_magic
[] = {0x42,0x4d};
1120 static GUID
const * const bmp_formats
[] = {
1121 &GUID_WICPixelFormat1bppIndexed
,
1122 &GUID_WICPixelFormat2bppIndexed
,
1123 &GUID_WICPixelFormat4bppIndexed
,
1124 &GUID_WICPixelFormat8bppIndexed
,
1125 &GUID_WICPixelFormat16bppBGR555
,
1126 &GUID_WICPixelFormat16bppBGR565
,
1127 &GUID_WICPixelFormat24bppBGR
,
1128 &GUID_WICPixelFormat32bppBGR
,
1129 &GUID_WICPixelFormat32bppBGRA
,
1133 static struct decoder_pattern
const bmp_patterns
[] = {
1134 {2,0,bmp_magic
,mask_all
,0},
1138 static const BYTE dds_magic
[] = "DDS ";
1140 static GUID
const * const dds_formats
[] = {
1141 &GUID_WICPixelFormat32bppBGRA
,
1145 static struct decoder_pattern
const dds_patterns
[] = {
1146 {4,0,dds_magic
,mask_all
,0},
1150 static const BYTE gif87a_magic
[6] = "GIF87a";
1151 static const BYTE gif89a_magic
[6] = "GIF89a";
1153 static GUID
const * const gif_formats
[] = {
1154 &GUID_WICPixelFormat8bppIndexed
,
1158 static struct decoder_pattern
const gif_patterns
[] = {
1159 {6,0,gif87a_magic
,mask_all
,0},
1160 {6,0,gif89a_magic
,mask_all
,0},
1164 static const BYTE ico_magic
[] = {00,00,01,00};
1166 static GUID
const * const ico_formats
[] = {
1167 &GUID_WICPixelFormat32bppBGRA
,
1171 static struct decoder_pattern
const ico_patterns
[] = {
1172 {4,0,ico_magic
,mask_all
,0},
1176 static const BYTE jpeg_magic
[] = {0xff, 0xd8};
1178 static GUID
const * const jpeg_formats
[] = {
1179 &GUID_WICPixelFormat24bppBGR
,
1180 &GUID_WICPixelFormat32bppCMYK
,
1181 &GUID_WICPixelFormat8bppGray
,
1185 static struct decoder_pattern
const jpeg_patterns
[] = {
1186 {2,0,jpeg_magic
,mask_all
,0},
1190 static const BYTE wmp_magic_v0
[] = {0x49, 0x49, 0xbc, 0x00};
1191 static const BYTE wmp_magic_v1
[] = {0x49, 0x49, 0xbc, 0x01};
1193 static GUID
const * const wmp_formats
[] = {
1194 &GUID_WICPixelFormat128bppRGBAFixedPoint
,
1195 &GUID_WICPixelFormat128bppRGBAFloat
,
1196 &GUID_WICPixelFormat128bppRGBFloat
,
1197 &GUID_WICPixelFormat16bppBGR555
,
1198 &GUID_WICPixelFormat16bppBGR565
,
1199 &GUID_WICPixelFormat16bppGray
,
1200 &GUID_WICPixelFormat16bppGrayFixedPoint
,
1201 &GUID_WICPixelFormat16bppGrayHalf
,
1202 &GUID_WICPixelFormat24bppBGR
,
1203 &GUID_WICPixelFormat24bppRGB
,
1204 &GUID_WICPixelFormat32bppBGR
,
1205 &GUID_WICPixelFormat32bppBGR101010
,
1206 &GUID_WICPixelFormat32bppBGRA
,
1207 &GUID_WICPixelFormat32bppCMYK
,
1208 &GUID_WICPixelFormat32bppGrayFixedPoint
,
1209 &GUID_WICPixelFormat32bppGrayFloat
,
1210 &GUID_WICPixelFormat32bppRGBE
,
1211 &GUID_WICPixelFormat40bppCMYKAlpha
,
1212 &GUID_WICPixelFormat48bppRGB
,
1213 &GUID_WICPixelFormat48bppRGBFixedPoint
,
1214 &GUID_WICPixelFormat48bppRGBHalf
,
1215 &GUID_WICPixelFormat64bppCMYK
,
1216 &GUID_WICPixelFormat64bppRGBA
,
1217 &GUID_WICPixelFormat64bppRGBAFixedPoint
,
1218 &GUID_WICPixelFormat64bppRGBAHalf
,
1219 &GUID_WICPixelFormat80bppCMYKAlpha
,
1220 &GUID_WICPixelFormat8bppGray
,
1221 &GUID_WICPixelFormat96bppRGBFixedPoint
,
1222 &GUID_WICPixelFormatBlackWhite
,
1226 static struct decoder_pattern
const wmp_patterns
[] = {
1227 {4,0,wmp_magic_v0
,mask_all
,0},
1228 {4,0,wmp_magic_v1
,mask_all
,0},
1232 static const BYTE png_magic
[] = {137,80,78,71,13,10,26,10};
1234 static GUID
const * const png_formats
[] = {
1235 &GUID_WICPixelFormatBlackWhite
,
1236 &GUID_WICPixelFormat2bppGray
,
1237 &GUID_WICPixelFormat4bppGray
,
1238 &GUID_WICPixelFormat8bppGray
,
1239 &GUID_WICPixelFormat16bppGray
,
1240 &GUID_WICPixelFormat32bppBGRA
,
1241 &GUID_WICPixelFormat64bppRGBA
,
1242 &GUID_WICPixelFormat1bppIndexed
,
1243 &GUID_WICPixelFormat2bppIndexed
,
1244 &GUID_WICPixelFormat4bppIndexed
,
1245 &GUID_WICPixelFormat8bppIndexed
,
1246 &GUID_WICPixelFormat24bppBGR
,
1247 &GUID_WICPixelFormat48bppRGB
,
1251 static struct decoder_pattern
const png_patterns
[] = {
1252 {8,0,png_magic
,mask_all
,0},
1256 static const BYTE tiff_magic_le
[] = {0x49,0x49,42,0};
1257 static const BYTE tiff_magic_be
[] = {0x4d,0x4d,0,42};
1259 static GUID
const * const tiff_decode_formats
[] = {
1260 &GUID_WICPixelFormatBlackWhite
,
1261 &GUID_WICPixelFormat4bppGray
,
1262 &GUID_WICPixelFormat8bppGray
,
1263 &GUID_WICPixelFormat16bppGray
,
1264 &GUID_WICPixelFormat32bppGrayFloat
,
1265 &GUID_WICPixelFormat1bppIndexed
,
1266 &GUID_WICPixelFormat2bppIndexed
,
1267 &GUID_WICPixelFormat4bppIndexed
,
1268 &GUID_WICPixelFormat8bppIndexed
,
1269 &GUID_WICPixelFormat24bppBGR
,
1270 &GUID_WICPixelFormat32bppBGR
,
1271 &GUID_WICPixelFormat32bppBGRA
,
1272 &GUID_WICPixelFormat32bppPBGRA
,
1273 &GUID_WICPixelFormat48bppRGB
,
1274 &GUID_WICPixelFormat64bppRGBA
,
1275 &GUID_WICPixelFormat64bppPRGBA
,
1276 &GUID_WICPixelFormat32bppCMYK
,
1277 &GUID_WICPixelFormat64bppCMYK
,
1278 &GUID_WICPixelFormat96bppRGBFloat
,
1279 &GUID_WICPixelFormat128bppRGBAFloat
,
1280 &GUID_WICPixelFormat128bppPRGBAFloat
,
1284 static struct decoder_pattern
const tiff_patterns
[] = {
1285 {4,0,tiff_magic_le
,mask_all
,0},
1286 {4,0,tiff_magic_be
,mask_all
,0},
1290 static const BYTE tga_footer_magic
[18] = "TRUEVISION-XFILE.";
1292 static const BYTE tga_indexed_magic
[18] = {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0};
1293 static const BYTE tga_indexed_mask
[18] = {0,0xff,0xf7,0,0,0,0,0,0,0,0,0,0,0,0,0,0xff,0xcf};
1295 static const BYTE tga_truecolor_magic
[18] = {0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1296 static const BYTE tga_truecolor_mask
[18] = {0,0xff,0xf7,0,0,0,0,0,0,0,0,0,0,0,0,0,0x87,0xc0};
1298 static const BYTE tga_grayscale_magic
[18] = {0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0};
1299 static const BYTE tga_grayscale_mask
[18] = {0,0xff,0xf7,0,0,0,0,0,0,0,0,0,0,0,0,0,0xff,0xcf};
1301 static GUID
const * const tga_formats
[] = {
1302 &GUID_WICPixelFormat8bppGray
,
1303 &GUID_WICPixelFormat8bppIndexed
,
1304 &GUID_WICPixelFormat16bppGray
,
1305 &GUID_WICPixelFormat16bppBGR555
,
1306 &GUID_WICPixelFormat24bppBGR
,
1307 &GUID_WICPixelFormat32bppBGRA
,
1308 &GUID_WICPixelFormat32bppPBGRA
,
1312 static struct decoder_pattern
const tga_patterns
[] = {
1313 {18,18,tga_footer_magic
,mask_all
,1},
1314 {18,0,tga_indexed_magic
,tga_indexed_mask
,0},
1315 {18,0,tga_truecolor_magic
,tga_truecolor_mask
,0},
1316 {18,0,tga_grayscale_magic
,tga_grayscale_mask
,0},
1320 static struct regsvr_decoder
const decoder_list
[] = {
1321 { &CLSID_WICBmpDecoder
,
1325 &GUID_VendorMicrosoft
,
1326 &GUID_ContainerFormatBmp
,
1332 { &CLSID_WICDdsDecoder
,
1336 &GUID_VendorMicrosoft
,
1337 &GUID_ContainerFormatDds
,
1343 { &CLSID_WICGifDecoder
,
1347 &GUID_VendorMicrosoft
,
1348 &GUID_ContainerFormatGif
,
1354 { &CLSID_WICIcoDecoder
,
1358 &GUID_VendorMicrosoft
,
1359 &GUID_ContainerFormatIco
,
1360 "image/vnd.microsoft.icon",
1365 { &CLSID_WICJpegDecoder
,
1369 &GUID_VendorMicrosoft
,
1370 &GUID_ContainerFormatJpeg
,
1376 { &CLSID_WICWmpDecoder
,
1380 &GUID_VendorMicrosoft
,
1381 &GUID_ContainerFormatWmp
,
1387 { &CLSID_WICPngDecoder
,
1391 &GUID_VendorMicrosoft
,
1392 &GUID_ContainerFormatPng
,
1398 { &CLSID_WICTiffDecoder
,
1402 &GUID_VendorMicrosoft
,
1403 &GUID_ContainerFormatTiff
,
1406 tiff_decode_formats
,
1409 { &CLSID_WineTgaDecoder
,
1414 &GUID_WineContainerFormatTga
,
1420 { NULL
} /* list terminator */
1423 static GUID
const * const bmp_encode_formats
[] = {
1424 &GUID_WICPixelFormat16bppBGR555
,
1425 &GUID_WICPixelFormat16bppBGR565
,
1426 &GUID_WICPixelFormat24bppBGR
,
1427 &GUID_WICPixelFormat32bppBGR
,
1428 &GUID_WICPixelFormatBlackWhite
,
1429 &GUID_WICPixelFormat1bppIndexed
,
1430 &GUID_WICPixelFormat4bppIndexed
,
1431 &GUID_WICPixelFormat8bppIndexed
,
1435 static GUID
const * const png_encode_formats
[] = {
1436 &GUID_WICPixelFormat24bppBGR
,
1437 &GUID_WICPixelFormatBlackWhite
,
1438 &GUID_WICPixelFormat2bppGray
,
1439 &GUID_WICPixelFormat4bppGray
,
1440 &GUID_WICPixelFormat8bppGray
,
1441 &GUID_WICPixelFormat16bppGray
,
1442 &GUID_WICPixelFormat32bppBGR
,
1443 &GUID_WICPixelFormat32bppBGRA
,
1444 &GUID_WICPixelFormat48bppRGB
,
1445 &GUID_WICPixelFormat64bppRGBA
,
1446 &GUID_WICPixelFormat1bppIndexed
,
1447 &GUID_WICPixelFormat2bppIndexed
,
1448 &GUID_WICPixelFormat4bppIndexed
,
1449 &GUID_WICPixelFormat8bppIndexed
,
1453 static GUID
const * const tiff_encode_formats
[] = {
1454 &GUID_WICPixelFormatBlackWhite
,
1455 &GUID_WICPixelFormat4bppGray
,
1456 &GUID_WICPixelFormat8bppGray
,
1457 &GUID_WICPixelFormat1bppIndexed
,
1458 &GUID_WICPixelFormat4bppIndexed
,
1459 &GUID_WICPixelFormat8bppIndexed
,
1460 &GUID_WICPixelFormat24bppBGR
,
1461 &GUID_WICPixelFormat32bppBGRA
,
1462 &GUID_WICPixelFormat32bppPBGRA
,
1463 &GUID_WICPixelFormat48bppRGB
,
1464 &GUID_WICPixelFormat64bppRGBA
,
1465 &GUID_WICPixelFormat64bppPRGBA
,
1469 static GUID
const * const icns_encode_formats
[] = {
1470 &GUID_WICPixelFormat32bppBGRA
,
1474 static struct regsvr_encoder
const encoder_list
[] = {
1475 { &CLSID_WICBmpEncoder
,
1479 &GUID_VendorMicrosoft
,
1480 &GUID_ContainerFormatBmp
,
1485 { &CLSID_WICGifEncoder
,
1489 &GUID_VendorMicrosoft
,
1490 &GUID_ContainerFormatGif
,
1495 { &CLSID_WICJpegEncoder
,
1499 &GUID_VendorMicrosoft
,
1500 &GUID_ContainerFormatJpeg
,
1505 { &CLSID_WICPngEncoder
,
1509 &GUID_VendorMicrosoft
,
1510 &GUID_ContainerFormatPng
,
1515 { &CLSID_WICTiffEncoder
,
1519 &GUID_VendorMicrosoft
,
1520 &GUID_ContainerFormatTiff
,
1525 { &CLSID_WICIcnsEncoder
,
1530 &GUID_WineContainerFormatIcns
,
1535 { NULL
} /* list terminator */
1538 static GUID
const * const converter_formats
[] = {
1539 &GUID_WICPixelFormat1bppIndexed
,
1540 &GUID_WICPixelFormat2bppIndexed
,
1541 &GUID_WICPixelFormat4bppIndexed
,
1542 &GUID_WICPixelFormat8bppIndexed
,
1543 &GUID_WICPixelFormatBlackWhite
,
1544 &GUID_WICPixelFormat2bppGray
,
1545 &GUID_WICPixelFormat4bppGray
,
1546 &GUID_WICPixelFormat8bppGray
,
1547 &GUID_WICPixelFormat16bppGray
,
1548 &GUID_WICPixelFormat16bppBGR555
,
1549 &GUID_WICPixelFormat16bppBGR565
,
1550 &GUID_WICPixelFormat16bppBGRA5551
,
1551 &GUID_WICPixelFormat24bppBGR
,
1552 &GUID_WICPixelFormat24bppRGB
,
1553 &GUID_WICPixelFormat32bppBGR
,
1554 &GUID_WICPixelFormat32bppRGB
,
1555 &GUID_WICPixelFormat32bppBGRA
,
1556 &GUID_WICPixelFormat32bppRGBA
,
1557 &GUID_WICPixelFormat32bppPBGRA
,
1558 &GUID_WICPixelFormat32bppPRGBA
,
1559 &GUID_WICPixelFormat32bppGrayFloat
,
1560 &GUID_WICPixelFormat48bppRGB
,
1561 &GUID_WICPixelFormat64bppRGBA
,
1562 &GUID_WICPixelFormat32bppCMYK
,
1566 static struct regsvr_converter
const converter_list
[] = {
1567 { &CLSID_WICDefaultFormatConverter
,
1569 "Default Pixel Format Converter",
1571 &GUID_VendorMicrosoft
,
1574 { NULL
} /* list terminator */
1577 static const BYTE no_magic
[1] = { 0 };
1578 static const BYTE no_mask
[1] = { 0 };
1580 static const struct metadata_pattern ifd_metadata_pattern
[] = {
1581 { 0, 1, no_magic
, no_mask
, 0 },
1585 static const struct reader_containers ifd_containers
[] = {
1587 &GUID_ContainerFormatTiff
,
1588 ifd_metadata_pattern
1590 { NULL
} /* list terminator */
1593 static const BYTE tEXt
[] = "tEXt";
1595 static const struct metadata_pattern pngtext_metadata_pattern
[] = {
1596 { 4, 4, tEXt
, mask_all
, 4 },
1600 static const struct reader_containers pngtext_containers
[] = {
1602 &GUID_ContainerFormatPng
,
1603 pngtext_metadata_pattern
1605 { NULL
} /* list terminator */
1608 static const BYTE gAMA
[] = "gAMA";
1610 static const struct metadata_pattern pnggama_metadata_pattern
[] = {
1611 { 4, 4, gAMA
, mask_all
, 4 },
1615 static const struct reader_containers pnggama_containers
[] = {
1617 &GUID_ContainerFormatPng
,
1618 pnggama_metadata_pattern
1620 { NULL
} /* list terminator */
1623 static const BYTE cHRM
[] = "cHRM";
1625 static const struct metadata_pattern pngchrm_metadata_pattern
[] = {
1626 { 4, 4, cHRM
, mask_all
, 4 },
1630 static const struct reader_containers pngchrm_containers
[] = {
1632 &GUID_ContainerFormatPng
,
1633 pngchrm_metadata_pattern
1635 { NULL
} /* list terminator */
1638 static const struct metadata_pattern lsd_metadata_patterns
[] = {
1639 { 0, 6, gif87a_magic
, mask_all
, 0 },
1640 { 0, 6, gif89a_magic
, mask_all
, 0 },
1644 static const struct reader_containers lsd_containers
[] = {
1646 &GUID_ContainerFormatGif
,
1647 lsd_metadata_patterns
1649 { NULL
} /* list terminator */
1652 static const BYTE imd_magic
[] = { 0x2c };
1654 static const struct metadata_pattern imd_metadata_pattern
[] = {
1655 { 0, 1, imd_magic
, mask_all
, 1 },
1659 static const struct reader_containers imd_containers
[] = {
1661 &GUID_ContainerFormatGif
,
1662 imd_metadata_pattern
1664 { NULL
} /* list terminator */
1667 static const BYTE gce_magic
[] = { 0x21, 0xf9, 0x04 };
1669 static const struct metadata_pattern gce_metadata_pattern
[] = {
1670 { 0, 3, gce_magic
, mask_all
, 3 },
1674 static const struct reader_containers gce_containers
[] = {
1676 &GUID_ContainerFormatGif
,
1677 gce_metadata_pattern
1679 { NULL
} /* list terminator */
1682 static const BYTE ape_magic
[] = { 0x21, 0xff, 0x0b };
1684 static const struct metadata_pattern ape_metadata_pattern
[] = {
1685 { 0, 3, ape_magic
, mask_all
, 0 },
1689 static const struct reader_containers ape_containers
[] = {
1691 &GUID_ContainerFormatGif
,
1692 ape_metadata_pattern
1694 { NULL
} /* list terminator */
1697 static const BYTE gif_comment_magic
[] = { 0x21, 0xfe };
1699 static const struct metadata_pattern gif_comment_metadata_pattern
[] = {
1700 { 0, 2, gif_comment_magic
, mask_all
, 0 },
1704 static const struct reader_containers gif_comment_containers
[] = {
1706 &GUID_ContainerFormatGif
,
1707 gif_comment_metadata_pattern
1709 { NULL
} /* list terminator */
1712 static struct regsvr_metadatareader
const metadatareader_list
[] = {
1713 { &CLSID_WICUnknownMetadataReader
,
1715 "Unknown Metadata Reader",
1718 &GUID_VendorMicrosoft
,
1719 &GUID_MetadataFormatUnknown
,
1723 { &CLSID_WICIfdMetadataReader
,
1728 &GUID_VendorMicrosoft
,
1729 &GUID_MetadataFormatIfd
,
1733 { &CLSID_WICPngChrmMetadataReader
,
1735 "Chunk cHRM Reader",
1738 &GUID_VendorMicrosoft
,
1739 &GUID_MetadataFormatChunkcHRM
,
1743 { &CLSID_WICPngGamaMetadataReader
,
1745 "Chunk gAMA Reader",
1748 &GUID_VendorMicrosoft
,
1749 &GUID_MetadataFormatChunkgAMA
,
1753 { &CLSID_WICPngTextMetadataReader
,
1755 "Chunk tEXt Reader",
1758 &GUID_VendorMicrosoft
,
1759 &GUID_MetadataFormatChunktEXt
,
1763 { &CLSID_WICLSDMetadataReader
,
1765 "Logical Screen Descriptor Reader",
1768 &GUID_VendorMicrosoft
,
1769 &GUID_MetadataFormatLSD
,
1773 { &CLSID_WICIMDMetadataReader
,
1775 "Image Descriptor Reader",
1778 &GUID_VendorMicrosoft
,
1779 &GUID_MetadataFormatIMD
,
1783 { &CLSID_WICGCEMetadataReader
,
1785 "Graphic Control Extension Reader",
1788 &GUID_VendorMicrosoft
,
1789 &GUID_MetadataFormatGCE
,
1793 { &CLSID_WICAPEMetadataReader
,
1795 "Application Extension Reader",
1798 &GUID_VendorMicrosoft
,
1799 &GUID_MetadataFormatAPE
,
1803 { &CLSID_WICGifCommentMetadataReader
,
1805 "Comment Extension Reader",
1808 &GUID_VendorMicrosoft
,
1809 &GUID_MetadataFormatGifComment
,
1811 gif_comment_containers
1813 { NULL
} /* list terminator */
1816 static BYTE
const channel_mask_1bit
[] = { 0x01 };
1817 static BYTE
const channel_mask_2bit
[] = { 0x03 };
1818 static BYTE
const channel_mask_4bit
[] = { 0x0f };
1820 static BYTE
const channel_mask_8bit
[] = { 0xff, 0x00, 0x00, 0x00 };
1821 static BYTE
const channel_mask_8bit2
[] = { 0x00, 0xff, 0x00, 0x00 };
1822 static BYTE
const channel_mask_8bit3
[] = { 0x00, 0x00, 0xff, 0x00 };
1823 static BYTE
const channel_mask_8bit4
[] = { 0x00, 0x00, 0x00, 0xff };
1825 static BYTE
const channel_mask_16bit
[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1826 static BYTE
const channel_mask_16bit2
[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1827 static BYTE
const channel_mask_16bit3
[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
1828 static BYTE
const channel_mask_16bit4
[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
1830 static BYTE
const channel_mask_32bit
[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1832 static BYTE
const channel_mask_96bit1
[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1833 static BYTE
const channel_mask_96bit2
[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 };
1834 static BYTE
const channel_mask_96bit3
[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff };
1836 static BYTE
const channel_mask_128bit1
[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1837 static BYTE
const channel_mask_128bit2
[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1838 static BYTE
const channel_mask_128bit3
[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 };
1839 static BYTE
const channel_mask_128bit4
[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff };
1841 static BYTE
const channel_mask_5bit
[] = { 0x1f, 0x00 };
1842 static BYTE
const channel_mask_5bit2
[] = { 0xe0, 0x03 };
1843 static BYTE
const channel_mask_5bit3
[] = { 0x00, 0x7c };
1844 static BYTE
const channel_mask_5bit4
[] = { 0x00, 0x80 };
1846 static BYTE
const channel_mask_BGR565_2
[] = { 0xe0, 0x07 };
1847 static BYTE
const channel_mask_BGR565_3
[] = { 0x00, 0xf8 };
1849 static BYTE
const * const channel_masks_1bit
[] = { channel_mask_1bit
};
1850 static BYTE
const * const channel_masks_2bit
[] = { channel_mask_2bit
};
1851 static BYTE
const * const channel_masks_4bit
[] = { channel_mask_4bit
};
1852 static BYTE
const * const channel_masks_8bit
[] = { channel_mask_8bit
,
1853 channel_mask_8bit2
, channel_mask_8bit3
, channel_mask_8bit4
};
1854 static BYTE
const * const channel_masks_16bit
[] = { channel_mask_16bit
,
1855 channel_mask_16bit2
, channel_mask_16bit3
, channel_mask_16bit4
};
1857 static BYTE
const * const channel_masks_32bit
[] = { channel_mask_32bit
};
1858 static BYTE
const * const channel_masks_96bit
[] = { channel_mask_96bit1
, channel_mask_96bit2
, channel_mask_96bit3
};
1859 static BYTE
const * const channel_masks_128bit
[] = { channel_mask_128bit1
, channel_mask_128bit2
, channel_mask_128bit3
, channel_mask_128bit4
};
1861 static BYTE
const * const channel_masks_BGRA5551
[] = { channel_mask_5bit
,
1862 channel_mask_5bit2
, channel_mask_5bit3
, channel_mask_5bit4
};
1864 static BYTE
const * const channel_masks_BGR565
[] = { channel_mask_5bit
,
1865 channel_mask_BGR565_2
, channel_mask_BGR565_3
};
1867 static struct regsvr_pixelformat
const pixelformat_list
[] = {
1868 { &GUID_WICPixelFormat1bppIndexed
,
1871 NULL
, /* no version */
1872 &GUID_VendorMicrosoft
,
1873 1, /* bitsperpixel */
1874 1, /* channel count */
1876 WICPixelFormatNumericRepresentationIndexed
,
1879 { &GUID_WICPixelFormat2bppIndexed
,
1882 NULL
, /* no version */
1883 &GUID_VendorMicrosoft
,
1884 2, /* bitsperpixel */
1885 1, /* channel count */
1887 WICPixelFormatNumericRepresentationIndexed
,
1890 { &GUID_WICPixelFormat4bppIndexed
,
1893 NULL
, /* no version */
1894 &GUID_VendorMicrosoft
,
1895 4, /* bitsperpixel */
1896 1, /* channel count */
1898 WICPixelFormatNumericRepresentationIndexed
,
1901 { &GUID_WICPixelFormat8bppIndexed
,
1904 NULL
, /* no version */
1905 &GUID_VendorMicrosoft
,
1906 8, /* bitsperpixel */
1907 1, /* channel count */
1909 WICPixelFormatNumericRepresentationIndexed
,
1912 { &GUID_WICPixelFormatBlackWhite
,
1915 NULL
, /* no version */
1916 &GUID_VendorMicrosoft
,
1917 1, /* bitsperpixel */
1918 1, /* channel count */
1920 WICPixelFormatNumericRepresentationUnsignedInteger
,
1923 { &GUID_WICPixelFormat2bppGray
,
1926 NULL
, /* no version */
1927 &GUID_VendorMicrosoft
,
1928 2, /* bitsperpixel */
1929 1, /* channel count */
1931 WICPixelFormatNumericRepresentationUnsignedInteger
,
1934 { &GUID_WICPixelFormat4bppGray
,
1937 NULL
, /* no version */
1938 &GUID_VendorMicrosoft
,
1939 4, /* bitsperpixel */
1940 1, /* channel count */
1942 WICPixelFormatNumericRepresentationUnsignedInteger
,
1945 { &GUID_WICPixelFormat8bppGray
,
1948 NULL
, /* no version */
1949 &GUID_VendorMicrosoft
,
1950 8, /* bitsperpixel */
1951 1, /* channel count */
1953 WICPixelFormatNumericRepresentationUnsignedInteger
,
1956 { &GUID_WICPixelFormat16bppGray
,
1959 NULL
, /* no version */
1960 &GUID_VendorMicrosoft
,
1961 16, /* bitsperpixel */
1962 1, /* channel count */
1963 channel_masks_16bit
,
1964 WICPixelFormatNumericRepresentationUnsignedInteger
,
1967 { &GUID_WICPixelFormat16bppBGR555
,
1970 NULL
, /* no version */
1971 &GUID_VendorMicrosoft
,
1972 16, /* bitsperpixel */
1973 3, /* channel count */
1974 channel_masks_BGRA5551
,
1975 WICPixelFormatNumericRepresentationUnsignedInteger
,
1978 { &GUID_WICPixelFormat16bppBGR565
,
1981 NULL
, /* no version */
1982 &GUID_VendorMicrosoft
,
1983 16, /* bitsperpixel */
1984 3, /* channel count */
1985 channel_masks_BGR565
,
1986 WICPixelFormatNumericRepresentationUnsignedInteger
,
1989 { &GUID_WICPixelFormat16bppBGRA5551
,
1992 NULL
, /* no version */
1993 &GUID_VendorMicrosoft
,
1994 16, /* bitsperpixel */
1995 4, /* channel count */
1996 channel_masks_BGRA5551
,
1997 WICPixelFormatNumericRepresentationUnsignedInteger
,
2000 { &GUID_WICPixelFormat24bppBGR
,
2003 NULL
, /* no version */
2004 &GUID_VendorMicrosoft
,
2005 24, /* bitsperpixel */
2006 3, /* channel count */
2008 WICPixelFormatNumericRepresentationUnsignedInteger
,
2011 { &GUID_WICPixelFormat24bppRGB
,
2014 NULL
, /* no version */
2015 &GUID_VendorMicrosoft
,
2016 24, /* bitsperpixel */
2017 3, /* channel count */
2019 WICPixelFormatNumericRepresentationUnsignedInteger
,
2022 { &GUID_WICPixelFormat32bppBGR
,
2025 NULL
, /* no version */
2026 &GUID_VendorMicrosoft
,
2027 32, /* bitsperpixel */
2028 3, /* channel count */
2030 WICPixelFormatNumericRepresentationUnsignedInteger
,
2033 { &GUID_WICPixelFormat32bppRGB
,
2036 NULL
, /* no version */
2037 &GUID_VendorMicrosoft
,
2038 32, /* bitsperpixel */
2039 3, /* channel count */
2041 WICPixelFormatNumericRepresentationUnsignedInteger
,
2044 { &GUID_WICPixelFormat32bppBGRA
,
2047 NULL
, /* no version */
2048 &GUID_VendorMicrosoft
,
2049 32, /* bitsperpixel */
2050 4, /* channel count */
2052 WICPixelFormatNumericRepresentationUnsignedInteger
,
2055 { &GUID_WICPixelFormat32bppRGBA
,
2058 NULL
, /* no version */
2059 &GUID_VendorMicrosoft
,
2060 32, /* bitsperpixel */
2061 4, /* channel count */
2063 WICPixelFormatNumericRepresentationUnsignedInteger
,
2066 { &GUID_WICPixelFormat32bppPBGRA
,
2069 NULL
, /* no version */
2070 &GUID_VendorMicrosoft
,
2071 32, /* bitsperpixel */
2072 4, /* channel count */
2074 WICPixelFormatNumericRepresentationUnsignedInteger
,
2077 { &GUID_WICPixelFormat32bppPRGBA
,
2080 NULL
, /* no version */
2081 &GUID_VendorMicrosoft
,
2082 32, /* bitsperpixel */
2083 4, /* channel count */
2085 WICPixelFormatNumericRepresentationUnsignedInteger
,
2088 { &GUID_WICPixelFormat32bppGrayFloat
,
2091 NULL
, /* no version */
2092 &GUID_VendorMicrosoft
,
2093 32, /* bitsperpixel */
2094 1, /* channel count */
2095 channel_masks_32bit
,
2096 WICPixelFormatNumericRepresentationFloat
,
2099 { &GUID_WICPixelFormat48bppRGB
,
2102 NULL
, /* no version */
2103 &GUID_VendorMicrosoft
,
2104 48, /* bitsperpixel */
2105 3, /* channel count */
2106 channel_masks_16bit
,
2107 WICPixelFormatNumericRepresentationUnsignedInteger
,
2110 { &GUID_WICPixelFormat64bppRGBA
,
2113 NULL
, /* no version */
2114 &GUID_VendorMicrosoft
,
2115 64, /* bitsperpixel */
2116 4, /* channel count */
2117 channel_masks_16bit
,
2118 WICPixelFormatNumericRepresentationUnsignedInteger
,
2121 { &GUID_WICPixelFormat64bppPRGBA
,
2124 NULL
, /* no version */
2125 &GUID_VendorMicrosoft
,
2126 64, /* bitsperpixel */
2127 4, /* channel count */
2128 channel_masks_16bit
,
2129 WICPixelFormatNumericRepresentationUnsignedInteger
,
2132 { &GUID_WICPixelFormat32bppCMYK
,
2135 NULL
, /* no version */
2136 &GUID_VendorMicrosoft
,
2137 32, /* bitsperpixel */
2138 4, /* channel count */
2140 WICPixelFormatNumericRepresentationUnsignedInteger
,
2143 { &GUID_WICPixelFormat64bppCMYK
,
2146 NULL
, /* no version */
2147 &GUID_VendorMicrosoft
,
2148 64, /* bitsperpixel */
2149 4, /* channel count */
2150 channel_masks_16bit
,
2151 WICPixelFormatNumericRepresentationUnsignedInteger
,
2154 { &GUID_WICPixelFormat96bppRGBFloat
,
2157 NULL
, /* no version */
2158 &GUID_VendorMicrosoft
,
2159 96, /* bitsperpixel */
2160 3, /* channel count */
2161 channel_masks_96bit
,
2162 WICPixelFormatNumericRepresentationFloat
,
2165 { &GUID_WICPixelFormat128bppRGBAFloat
,
2168 NULL
, /* no version */
2169 &GUID_VendorMicrosoft
,
2170 128, /* bitsperpixel */
2171 4, /* channel count */
2172 channel_masks_128bit
,
2173 WICPixelFormatNumericRepresentationFloat
,
2176 { &GUID_WICPixelFormat128bppPRGBAFloat
,
2178 "128bpp PRGBAFloat",
2179 NULL
, /* no version */
2180 &GUID_VendorMicrosoft
,
2181 128, /* bitsperpixel */
2182 4, /* channel count */
2183 channel_masks_128bit
,
2184 WICPixelFormatNumericRepresentationFloat
,
2187 { NULL
} /* list terminator */
2190 struct regsvr_category
2192 const CLSID
*clsid
; /* NULL for end of list */
2195 static const struct regsvr_category category_list
[] = {
2196 { &CATID_WICBitmapDecoders
},
2197 { &CATID_WICBitmapEncoders
},
2198 { &CATID_WICFormatConverters
},
2199 { &CATID_WICMetadataReader
},
2200 { &CATID_WICPixelFormats
},
2204 static HRESULT
register_categories(const struct regsvr_category
*list
)
2208 HKEY coclass_key
, categories_key
, instance_key
;
2210 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
2211 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
2212 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
2214 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2215 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
2216 KEY_READ
| KEY_WRITE
, NULL
, &categories_key
, NULL
);
2217 if (res
!= ERROR_SUCCESS
)
2219 RegCloseKey(coclass_key
);
2220 return HRESULT_FROM_WIN32(res
);
2223 res
= RegCreateKeyExW(categories_key
, instance_keyname
, 0, NULL
, 0,
2224 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
2226 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
2228 HKEY instance_clsid_key
;
2230 StringFromGUID2(list
->clsid
, buf
, 39);
2231 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
2232 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
2233 if (res
== ERROR_SUCCESS
)
2235 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
2236 (const BYTE
*)buf
, 78);
2237 RegCloseKey(instance_clsid_key
);
2241 RegCloseKey(instance_key
);
2242 RegCloseKey(categories_key
);
2243 RegCloseKey(coclass_key
);
2245 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
2248 static HRESULT
unregister_categories(const struct regsvr_category
*list
)
2252 HKEY coclass_key
, categories_key
, instance_key
;
2254 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
2255 KEY_READ
| KEY_WRITE
, &coclass_key
);
2256 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
2258 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2259 res
= RegOpenKeyExW(coclass_key
, buf
, 0,
2260 KEY_READ
| KEY_WRITE
, &categories_key
);
2261 if (res
!= ERROR_SUCCESS
)
2263 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
2264 RegCloseKey(coclass_key
);
2265 return HRESULT_FROM_WIN32(res
);
2268 res
= RegOpenKeyExW(categories_key
, instance_keyname
, 0,
2269 KEY_READ
| KEY_WRITE
, &instance_key
);
2271 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
2273 StringFromGUID2(list
->clsid
, buf
, 39);
2274 res
= RegDeleteTreeW(instance_key
, buf
);
2277 RegCloseKey(instance_key
);
2278 RegCloseKey(categories_key
);
2280 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2281 res
= RegDeleteTreeW(coclass_key
, buf
);
2283 RegCloseKey(coclass_key
);
2285 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
2288 extern HRESULT WINAPI
WIC_DllRegisterServer(void) DECLSPEC_HIDDEN
;
2289 extern HRESULT WINAPI
WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
2291 HRESULT WINAPI
DllRegisterServer(void)
2297 hr
= WIC_DllRegisterServer();
2299 hr
= register_categories(category_list
);
2301 hr
= register_decoders(decoder_list
);
2303 hr
= register_encoders(encoder_list
);
2305 hr
= register_converters(converter_list
);
2307 hr
= register_metadatareaders(metadatareader_list
);
2309 hr
= register_pixelformats(pixelformat_list
);
2313 HRESULT WINAPI
DllUnregisterServer(void)
2319 hr
= WIC_DllUnregisterServer();
2321 hr
= unregister_categories(category_list
);
2323 hr
= unregister_decoders(decoder_list
);
2325 hr
= unregister_encoders(encoder_list
);
2327 hr
= unregister_converters(converter_list
);
2329 hr
= unregister_metadatareaders(metadatareader_list
);
2331 hr
= unregister_pixelformats(pixelformat_list
);