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 "wincodecsdk.h"
35 #include "wine/debug.h"
36 #include "wine/unicode.h"
38 #include "wincodecs_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
42 /***********************************************************************
43 * interface for self-registering
45 struct decoder_pattern
47 DWORD length
; /* 0 for end of list */
56 CLSID
const *clsid
; /* NULL for end of list */
61 GUID
const *container_format
;
64 GUID
const * const *formats
;
65 const struct decoder_pattern
*patterns
;
68 static HRESULT
register_decoders(struct regsvr_decoder
const *list
);
69 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
);
73 CLSID
const *clsid
; /* NULL for end of list */
78 GUID
const *container_format
;
81 GUID
const * const *formats
;
84 static HRESULT
register_encoders(struct regsvr_encoder
const *list
);
85 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
);
87 struct regsvr_converter
89 CLSID
const *clsid
; /* NULL for end of list */
94 GUID
const * const *formats
;
97 static HRESULT
register_converters(struct regsvr_converter
const *list
);
98 static HRESULT
unregister_converters(struct regsvr_converter
const *list
);
100 struct metadata_pattern
109 struct reader_containers
112 const struct metadata_pattern
*patterns
;
115 struct regsvr_metadatareader
117 CLSID
const *clsid
; /* NULL for end of list */
123 GUID
const *metadata_format
;
124 DWORD requires_fullstream
;
125 DWORD supports_padding
;
126 DWORD requires_fixedsize
;
127 const struct reader_containers
*containers
;
130 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
);
131 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
);
133 struct regsvr_pixelformat
135 CLSID
const *clsid
; /* NULL for end of list */
142 BYTE
const * const *channelmasks
;
143 WICPixelFormatNumericRepresentation numericrepresentation
;
147 static HRESULT
register_pixelformats(struct regsvr_pixelformat
const *list
);
148 static HRESULT
unregister_pixelformats(struct regsvr_pixelformat
const *list
);
150 /***********************************************************************
151 * static string constants
153 static const WCHAR clsid_keyname
[] = {
154 'C', 'L', 'S', 'I', 'D', 0 };
155 static const char author_valuename
[] = "Author";
156 static const char friendlyname_valuename
[] = "FriendlyName";
157 static const WCHAR vendor_valuename
[] = {'V','e','n','d','o','r',0};
158 static const WCHAR containerformat_valuename
[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
159 static const char version_valuename
[] = "Version";
160 static const char mimetypes_valuename
[] = "MimeTypes";
161 static const char extensions_valuename
[] = "FileExtensions";
162 static const WCHAR formats_keyname
[] = {'F','o','r','m','a','t','s',0};
163 static const WCHAR patterns_keyname
[] = {'P','a','t','t','e','r','n','s',0};
164 static const WCHAR instance_keyname
[] = {'I','n','s','t','a','n','c','e',0};
165 static const WCHAR clsid_valuename
[] = {'C','L','S','I','D',0};
166 static const char length_valuename
[] = "Length";
167 static const char position_valuename
[] = "Position";
168 static const char pattern_valuename
[] = "Pattern";
169 static const char mask_valuename
[] = "Mask";
170 static const char endofstream_valuename
[] = "EndOfStream";
171 static const WCHAR pixelformats_keyname
[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
172 static const WCHAR metadataformat_valuename
[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
173 static const char specversion_valuename
[] = "SpecVersion";
174 static const char requiresfullstream_valuename
[] = "RequiresFullStream";
175 static const char supportspadding_valuename
[] = "SupportsPadding";
176 static const char requiresfixedsize_valuename
[] = "FixedSize";
177 static const WCHAR containers_keyname
[] = {'C','o','n','t','a','i','n','e','r','s',0};
178 static const char dataoffset_valuename
[] = "DataOffset";
179 static const char bitsperpixel_valuename
[] = "BitLength";
180 static const char channelcount_valuename
[] = "ChannelCount";
181 static const char numericrepresentation_valuename
[] = "NumericRepresentation";
182 static const char supportstransparency_valuename
[] = "SupportsTransparency";
183 static const WCHAR channelmasks_keyname
[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
185 /***********************************************************************
188 static HRESULT
register_decoders(struct regsvr_decoder
const *list
)
190 LONG res
= ERROR_SUCCESS
;
196 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
197 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
198 if (res
== ERROR_SUCCESS
) {
199 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
200 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
201 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
202 if (res
== ERROR_SUCCESS
)
204 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
205 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
206 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
208 if (res
!= ERROR_SUCCESS
)
209 RegCloseKey(coclass_key
);
211 if (res
!= ERROR_SUCCESS
) goto error_return
;
213 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
215 HKEY instance_clsid_key
;
217 StringFromGUID2(list
->clsid
, buf
, 39);
218 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
219 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
220 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
222 StringFromGUID2(list
->clsid
, buf
, 39);
223 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
224 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
225 if (res
== ERROR_SUCCESS
) {
226 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
227 (const BYTE
*)buf
, 78);
228 RegCloseKey(instance_clsid_key
);
230 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
233 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
234 (const BYTE
*)list
->author
,
235 strlen(list
->author
) + 1);
236 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
239 if (list
->friendlyname
) {
240 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
241 (const BYTE
*)list
->friendlyname
,
242 strlen(list
->friendlyname
) + 1);
243 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
247 StringFromGUID2(list
->vendor
, buf
, 39);
248 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
249 (const BYTE
*)buf
, 78);
250 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
253 if (list
->container_format
) {
254 StringFromGUID2(list
->container_format
, buf
, 39);
255 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
256 (const BYTE
*)buf
, 78);
257 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
261 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
262 (const BYTE
*)list
->version
,
263 strlen(list
->version
) + 1);
264 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
267 if (list
->mimetypes
) {
268 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
269 (const BYTE
*)list
->mimetypes
,
270 strlen(list
->mimetypes
) + 1);
271 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
274 if (list
->extensions
) {
275 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
276 (const BYTE
*)list
->extensions
,
277 strlen(list
->extensions
) + 1);
278 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
283 GUID
const * const *format
;
285 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
286 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
287 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
288 for (format
=list
->formats
; *format
; ++format
)
291 StringFromGUID2(*format
, buf
, 39);
292 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
293 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
294 if (res
!= ERROR_SUCCESS
) break;
295 RegCloseKey(format_key
);
297 RegCloseKey(formats_key
);
298 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
301 if (list
->patterns
) {
305 res
= RegCreateKeyExW(clsid_key
, patterns_keyname
, 0, NULL
, 0,
306 KEY_READ
| KEY_WRITE
, NULL
, &patterns_key
, NULL
);
307 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
308 for (i
=0; list
->patterns
[i
].length
; i
++)
311 static const WCHAR int_format
[] = {'%','i',0};
312 snprintfW(buf
, 39, int_format
, i
);
313 res
= RegCreateKeyExW(patterns_key
, buf
, 0, NULL
, 0,
314 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
315 if (res
!= ERROR_SUCCESS
) break;
316 res
= RegSetValueExA(pattern_key
, length_valuename
, 0, REG_DWORD
,
317 (const BYTE
*)&list
->patterns
[i
].length
, 4);
318 if (res
== ERROR_SUCCESS
)
319 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
320 (const BYTE
*)&list
->patterns
[i
].position
, 4);
321 if (res
== ERROR_SUCCESS
)
322 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
323 list
->patterns
[i
].pattern
,
324 list
->patterns
[i
].length
);
325 if (res
== ERROR_SUCCESS
)
326 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
327 list
->patterns
[i
].mask
,
328 list
->patterns
[i
].length
);
329 if (res
== ERROR_SUCCESS
)
330 res
= RegSetValueExA(pattern_key
, endofstream_valuename
, 0, REG_DWORD
,
331 (const BYTE
*)&list
->patterns
[i
].endofstream
, 4);
332 RegCloseKey(pattern_key
);
334 RegCloseKey(patterns_key
);
335 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
338 error_close_clsid_key
:
339 RegCloseKey(clsid_key
);
342 error_close_coclass_key
:
343 RegCloseKey(instance_key
);
344 RegCloseKey(decoders_key
);
345 RegCloseKey(coclass_key
);
347 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
350 /***********************************************************************
351 * unregister_decoders
353 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
)
355 LONG res
= ERROR_SUCCESS
;
361 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
362 KEY_READ
| KEY_WRITE
, &coclass_key
);
363 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
365 if (res
== ERROR_SUCCESS
) {
366 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
367 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
368 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
369 if (res
== ERROR_SUCCESS
)
371 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
372 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
373 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
375 if (res
!= ERROR_SUCCESS
)
376 RegCloseKey(coclass_key
);
378 if (res
!= ERROR_SUCCESS
) goto error_return
;
380 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
381 StringFromGUID2(list
->clsid
, buf
, 39);
383 res
= RegDeleteTreeW(coclass_key
, buf
);
384 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
385 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
387 res
= RegDeleteTreeW(instance_key
, buf
);
388 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
389 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
392 error_close_coclass_key
:
393 RegCloseKey(instance_key
);
394 RegCloseKey(decoders_key
);
395 RegCloseKey(coclass_key
);
397 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
400 /***********************************************************************
403 static HRESULT
register_encoders(struct regsvr_encoder
const *list
)
405 LONG res
= ERROR_SUCCESS
;
411 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
412 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
413 if (res
== ERROR_SUCCESS
) {
414 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
415 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
416 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
417 if (res
== ERROR_SUCCESS
)
419 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
420 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
421 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
423 if (res
!= ERROR_SUCCESS
)
424 RegCloseKey(coclass_key
);
426 if (res
!= ERROR_SUCCESS
) goto error_return
;
428 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
430 HKEY instance_clsid_key
;
432 StringFromGUID2(list
->clsid
, buf
, 39);
433 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
434 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
435 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
437 StringFromGUID2(list
->clsid
, buf
, 39);
438 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
439 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
440 if (res
== ERROR_SUCCESS
) {
441 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
442 (const BYTE
*)buf
, 78);
443 RegCloseKey(instance_clsid_key
);
445 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
448 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
449 (const BYTE
*)list
->author
,
450 strlen(list
->author
) + 1);
451 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
454 if (list
->friendlyname
) {
455 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
456 (const BYTE
*)list
->friendlyname
,
457 strlen(list
->friendlyname
) + 1);
458 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
462 StringFromGUID2(list
->vendor
, buf
, 39);
463 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
464 (const BYTE
*)buf
, 78);
465 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
468 if (list
->container_format
) {
469 StringFromGUID2(list
->container_format
, buf
, 39);
470 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
471 (const BYTE
*)buf
, 78);
472 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
476 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
477 (const BYTE
*)list
->version
,
478 strlen(list
->version
) + 1);
479 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
482 if (list
->mimetypes
) {
483 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
484 (const BYTE
*)list
->mimetypes
,
485 strlen(list
->mimetypes
) + 1);
486 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
489 if (list
->extensions
) {
490 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
491 (const BYTE
*)list
->extensions
,
492 strlen(list
->extensions
) + 1);
493 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
498 GUID
const * const *format
;
500 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
501 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
502 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
503 for (format
=list
->formats
; *format
; ++format
)
506 StringFromGUID2(*format
, buf
, 39);
507 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
508 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
509 if (res
!= ERROR_SUCCESS
) break;
510 RegCloseKey(format_key
);
512 RegCloseKey(formats_key
);
513 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
516 error_close_clsid_key
:
517 RegCloseKey(clsid_key
);
520 error_close_coclass_key
:
521 RegCloseKey(instance_key
);
522 RegCloseKey(encoders_key
);
523 RegCloseKey(coclass_key
);
525 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
528 /***********************************************************************
529 * unregister_encoders
531 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
)
533 LONG res
= ERROR_SUCCESS
;
539 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
540 KEY_READ
| KEY_WRITE
, &coclass_key
);
541 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
543 if (res
== ERROR_SUCCESS
) {
544 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
545 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
546 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
547 if (res
== ERROR_SUCCESS
)
549 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
550 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
551 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
553 if (res
!= ERROR_SUCCESS
)
554 RegCloseKey(coclass_key
);
556 if (res
!= ERROR_SUCCESS
) goto error_return
;
558 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
559 StringFromGUID2(list
->clsid
, buf
, 39);
561 res
= RegDeleteTreeW(coclass_key
, buf
);
562 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
563 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
565 res
= RegDeleteTreeW(instance_key
, buf
);
566 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
567 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
570 error_close_coclass_key
:
571 RegCloseKey(instance_key
);
572 RegCloseKey(encoders_key
);
573 RegCloseKey(coclass_key
);
575 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
578 /***********************************************************************
579 * register_converters
581 static HRESULT
register_converters(struct regsvr_converter
const *list
)
583 LONG res
= ERROR_SUCCESS
;
589 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
590 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
591 if (res
== ERROR_SUCCESS
) {
592 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
593 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
594 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
595 if (res
== ERROR_SUCCESS
)
597 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
598 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
599 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
601 if (res
!= ERROR_SUCCESS
)
602 RegCloseKey(coclass_key
);
604 if (res
!= ERROR_SUCCESS
) goto error_return
;
606 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
608 HKEY instance_clsid_key
;
610 StringFromGUID2(list
->clsid
, buf
, 39);
611 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
612 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
613 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
615 StringFromGUID2(list
->clsid
, buf
, 39);
616 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
617 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
618 if (res
== ERROR_SUCCESS
) {
619 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
620 (const BYTE
*)buf
, 78);
621 RegCloseKey(instance_clsid_key
);
623 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
626 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
627 (const BYTE
*)list
->author
,
628 strlen(list
->author
) + 1);
629 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
632 if (list
->friendlyname
) {
633 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
634 (const BYTE
*)list
->friendlyname
,
635 strlen(list
->friendlyname
) + 1);
636 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
640 StringFromGUID2(list
->vendor
, buf
, 39);
641 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
642 (const BYTE
*)buf
, 78);
643 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
647 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
648 (const BYTE
*)list
->version
,
649 strlen(list
->version
) + 1);
650 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
655 GUID
const * const *format
;
657 res
= RegCreateKeyExW(clsid_key
, pixelformats_keyname
, 0, NULL
, 0,
658 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
659 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
660 for (format
=list
->formats
; *format
; ++format
)
663 StringFromGUID2(*format
, buf
, 39);
664 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
665 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
666 if (res
!= ERROR_SUCCESS
) break;
667 RegCloseKey(format_key
);
669 RegCloseKey(formats_key
);
670 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
673 error_close_clsid_key
:
674 RegCloseKey(clsid_key
);
677 error_close_coclass_key
:
678 RegCloseKey(instance_key
);
679 RegCloseKey(converters_key
);
680 RegCloseKey(coclass_key
);
682 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
685 /***********************************************************************
686 * unregister_converters
688 static HRESULT
unregister_converters(struct regsvr_converter
const *list
)
690 LONG res
= ERROR_SUCCESS
;
696 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
697 KEY_READ
| KEY_WRITE
, &coclass_key
);
698 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
700 if (res
== ERROR_SUCCESS
) {
701 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
702 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
703 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
704 if (res
== ERROR_SUCCESS
)
706 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
707 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
708 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
710 if (res
!= ERROR_SUCCESS
)
711 RegCloseKey(coclass_key
);
713 if (res
!= ERROR_SUCCESS
) goto error_return
;
715 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
716 StringFromGUID2(list
->clsid
, buf
, 39);
718 res
= RegDeleteTreeW(coclass_key
, buf
);
719 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
720 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
722 res
= RegDeleteTreeW(instance_key
, buf
);
723 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
724 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
727 error_close_coclass_key
:
728 RegCloseKey(instance_key
);
729 RegCloseKey(converters_key
);
730 RegCloseKey(coclass_key
);
732 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
735 /***********************************************************************
736 * register_metadatareaders
738 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
)
740 LONG res
= ERROR_SUCCESS
;
746 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
747 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
748 if (res
== ERROR_SUCCESS
) {
749 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
750 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
751 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
752 if (res
== ERROR_SUCCESS
)
754 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
755 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
756 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
758 if (res
!= ERROR_SUCCESS
)
759 RegCloseKey(coclass_key
);
761 if (res
!= ERROR_SUCCESS
) goto error_return
;
763 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
765 HKEY instance_clsid_key
;
767 StringFromGUID2(list
->clsid
, buf
, 39);
768 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
769 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
770 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
772 StringFromGUID2(list
->clsid
, buf
, 39);
773 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
774 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
775 if (res
== ERROR_SUCCESS
) {
776 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
777 (const BYTE
*)buf
, 78);
778 RegCloseKey(instance_clsid_key
);
780 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
783 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
784 (const BYTE
*)list
->author
,
785 strlen(list
->author
) + 1);
786 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
789 if (list
->friendlyname
) {
790 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
791 (const BYTE
*)list
->friendlyname
,
792 strlen(list
->friendlyname
) + 1);
793 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
797 StringFromGUID2(list
->vendor
, buf
, 39);
798 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
799 (const BYTE
*)buf
, 78);
800 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
803 if (list
->metadata_format
) {
804 StringFromGUID2(list
->metadata_format
, buf
, 39);
805 res
= RegSetValueExW(clsid_key
, metadataformat_valuename
, 0, REG_SZ
,
806 (const BYTE
*)buf
, 78);
807 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
811 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
812 (const BYTE
*)list
->version
,
813 strlen(list
->version
) + 1);
814 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
817 if (list
->specversion
) {
818 res
= RegSetValueExA(clsid_key
, specversion_valuename
, 0, REG_SZ
,
819 (const BYTE
*)list
->version
,
820 strlen(list
->version
) + 1);
821 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
824 res
= RegSetValueExA(clsid_key
, requiresfullstream_valuename
, 0, REG_DWORD
,
825 (const BYTE
*)&list
->requires_fullstream
, 4);
826 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
828 res
= RegSetValueExA(clsid_key
, supportspadding_valuename
, 0, REG_DWORD
,
829 (const BYTE
*)&list
->supports_padding
, 4);
830 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
832 if (list
->requires_fixedsize
) {
833 res
= RegSetValueExA(clsid_key
, requiresfixedsize_valuename
, 0, REG_DWORD
,
834 (const BYTE
*)&list
->requires_fixedsize
, 4);
835 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
838 if (list
->containers
) {
840 const struct reader_containers
*container
;
842 res
= RegCreateKeyExW(clsid_key
, containers_keyname
, 0, NULL
, 0,
843 KEY_READ
| KEY_WRITE
, NULL
, &containers_key
, NULL
);
844 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
845 for (container
=list
->containers
; container
->format
; ++container
)
849 StringFromGUID2(container
->format
, buf
, 39);
850 res
= RegCreateKeyExW(containers_key
, buf
, 0, NULL
, 0,
851 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
852 if (res
!= ERROR_SUCCESS
) break;
854 for (i
=0; container
->patterns
[i
].length
; i
++)
857 static const WCHAR int_format
[] = {'%','i',0};
858 snprintfW(buf
, 39, int_format
, i
);
859 res
= RegCreateKeyExW(format_key
, buf
, 0, NULL
, 0,
860 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
861 if (res
!= ERROR_SUCCESS
) break;
862 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
863 (const BYTE
*)&container
->patterns
[i
].position
, 4);
864 if (res
== ERROR_SUCCESS
)
865 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
866 container
->patterns
[i
].pattern
,
867 container
->patterns
[i
].length
);
868 if (res
== ERROR_SUCCESS
)
869 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
870 container
->patterns
[i
].mask
,
871 container
->patterns
[i
].length
);
872 if (res
== ERROR_SUCCESS
&& container
->patterns
[i
].data_offset
)
873 res
= RegSetValueExA(pattern_key
, dataoffset_valuename
, 0, REG_DWORD
,
874 (const BYTE
*)&container
->patterns
[i
].data_offset
, 4);
875 RegCloseKey(pattern_key
);
878 RegCloseKey(format_key
);
880 RegCloseKey(containers_key
);
883 error_close_clsid_key
:
884 RegCloseKey(clsid_key
);
887 error_close_coclass_key
:
888 RegCloseKey(instance_key
);
889 RegCloseKey(readers_key
);
890 RegCloseKey(coclass_key
);
892 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
895 /***********************************************************************
896 * unregister_metadatareaders
898 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
)
900 LONG res
= ERROR_SUCCESS
;
906 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
907 KEY_READ
| KEY_WRITE
, &coclass_key
);
908 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
910 if (res
== ERROR_SUCCESS
) {
911 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
912 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
913 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
914 if (res
== ERROR_SUCCESS
)
916 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
917 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
918 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
920 if (res
!= ERROR_SUCCESS
)
921 RegCloseKey(coclass_key
);
923 if (res
!= ERROR_SUCCESS
) goto error_return
;
925 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
926 StringFromGUID2(list
->clsid
, buf
, 39);
928 res
= RegDeleteTreeW(coclass_key
, buf
);
929 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
930 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
932 res
= RegDeleteTreeW(instance_key
, buf
);
933 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
934 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
937 error_close_coclass_key
:
938 RegCloseKey(instance_key
);
939 RegCloseKey(readers_key
);
940 RegCloseKey(coclass_key
);
942 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
945 /***********************************************************************
946 * register_pixelformats
948 static HRESULT
register_pixelformats(struct regsvr_pixelformat
const *list
)
950 LONG res
= ERROR_SUCCESS
;
956 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
957 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
958 if (res
== ERROR_SUCCESS
) {
959 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
960 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
961 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
962 if (res
== ERROR_SUCCESS
)
964 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
965 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
966 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
968 if (res
!= ERROR_SUCCESS
)
969 RegCloseKey(coclass_key
);
971 if (res
!= ERROR_SUCCESS
) goto error_return
;
973 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
975 HKEY instance_clsid_key
;
977 StringFromGUID2(list
->clsid
, buf
, 39);
978 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
979 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
980 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
982 StringFromGUID2(list
->clsid
, buf
, 39);
983 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
984 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
985 if (res
== ERROR_SUCCESS
) {
986 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
987 (const BYTE
*)buf
, 78);
988 RegCloseKey(instance_clsid_key
);
990 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
993 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
994 (const BYTE
*)list
->author
,
995 strlen(list
->author
) + 1);
996 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
999 if (list
->friendlyname
) {
1000 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
1001 (const BYTE
*)list
->friendlyname
,
1002 strlen(list
->friendlyname
) + 1);
1003 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1007 StringFromGUID2(list
->vendor
, buf
, 39);
1008 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
1009 (const BYTE
*)buf
, 78);
1010 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1013 if (list
->version
) {
1014 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
1015 (const BYTE
*)list
->version
,
1016 strlen(list
->version
) + 1);
1017 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1020 res
= RegSetValueExA(clsid_key
, bitsperpixel_valuename
, 0, REG_DWORD
,
1021 (const BYTE
*)&list
->bitsperpixel
, 4);
1022 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1024 res
= RegSetValueExA(clsid_key
, channelcount_valuename
, 0, REG_DWORD
,
1025 (const BYTE
*)&list
->channelcount
, 4);
1026 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1028 res
= RegSetValueExA(clsid_key
, numericrepresentation_valuename
, 0, REG_DWORD
,
1029 (const BYTE
*)&list
->numericrepresentation
, 4);
1030 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1032 res
= RegSetValueExA(clsid_key
, supportstransparency_valuename
, 0, REG_DWORD
,
1033 (const BYTE
*)&list
->supportsalpha
, 4);
1034 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1036 if (list
->channelmasks
) {
1039 WCHAR mask_valuename
[11];
1040 const WCHAR valuename_format
[] = {'%','d',0};
1042 mask_size
= (list
->bitsperpixel
+ 7)/8;
1044 res
= RegCreateKeyExW(clsid_key
, channelmasks_keyname
, 0, NULL
, 0,
1045 KEY_READ
| KEY_WRITE
, NULL
, &masks_key
, NULL
);
1046 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1047 for (i
=0; i
< list
->channelcount
; i
++)
1049 sprintfW(mask_valuename
, valuename_format
, i
);
1050 res
= RegSetValueExW(masks_key
, mask_valuename
, 0, REG_BINARY
,
1051 list
->channelmasks
[i
], mask_size
);
1052 if (res
!= ERROR_SUCCESS
) break;
1054 RegCloseKey(masks_key
);
1055 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1058 error_close_clsid_key
:
1059 RegCloseKey(clsid_key
);
1062 error_close_coclass_key
:
1063 RegCloseKey(instance_key
);
1064 RegCloseKey(formats_key
);
1065 RegCloseKey(coclass_key
);
1067 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1070 /***********************************************************************
1071 * unregister_pixelformats
1073 static HRESULT
unregister_pixelformats(struct regsvr_pixelformat
const *list
)
1075 LONG res
= ERROR_SUCCESS
;
1081 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
1082 KEY_READ
| KEY_WRITE
, &coclass_key
);
1083 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
1085 if (res
== ERROR_SUCCESS
) {
1086 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
1087 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
1088 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
1089 if (res
== ERROR_SUCCESS
)
1091 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
1092 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
1093 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1095 if (res
!= ERROR_SUCCESS
)
1096 RegCloseKey(coclass_key
);
1098 if (res
!= ERROR_SUCCESS
) goto error_return
;
1100 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
1101 StringFromGUID2(list
->clsid
, buf
, 39);
1103 res
= RegDeleteTreeW(coclass_key
, buf
);
1104 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1105 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1107 res
= RegDeleteTreeW(instance_key
, buf
);
1108 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1109 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1112 error_close_coclass_key
:
1113 RegCloseKey(instance_key
);
1114 RegCloseKey(formats_key
);
1115 RegCloseKey(coclass_key
);
1117 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1120 /***********************************************************************
1123 static const BYTE mask_all
[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1125 static const BYTE bmp_magic
[] = {0x42,0x4d};
1127 static GUID
const * const bmp_formats
[] = {
1128 &GUID_WICPixelFormat1bppIndexed
,
1129 &GUID_WICPixelFormat2bppIndexed
,
1130 &GUID_WICPixelFormat4bppIndexed
,
1131 &GUID_WICPixelFormat8bppIndexed
,
1132 &GUID_WICPixelFormat16bppBGR555
,
1133 &GUID_WICPixelFormat16bppBGR565
,
1134 &GUID_WICPixelFormat24bppBGR
,
1135 &GUID_WICPixelFormat32bppBGR
,
1136 &GUID_WICPixelFormat32bppBGRA
,
1140 static struct decoder_pattern
const bmp_patterns
[] = {
1141 {2,0,bmp_magic
,mask_all
,0},
1145 static const BYTE gif87a_magic
[6] = "GIF87a";
1146 static const BYTE gif89a_magic
[6] = "GIF89a";
1148 static GUID
const * const gif_formats
[] = {
1149 &GUID_WICPixelFormat8bppIndexed
,
1153 static struct decoder_pattern
const gif_patterns
[] = {
1154 {6,0,gif87a_magic
,mask_all
,0},
1155 {6,0,gif89a_magic
,mask_all
,0},
1159 static const BYTE ico_magic
[] = {00,00,01,00};
1161 static GUID
const * const ico_formats
[] = {
1162 &GUID_WICPixelFormat32bppBGRA
,
1166 static struct decoder_pattern
const ico_patterns
[] = {
1167 {4,0,ico_magic
,mask_all
,0},
1171 static const BYTE jpeg_magic
[] = {0xff, 0xd8};
1173 static GUID
const * const jpeg_formats
[] = {
1174 &GUID_WICPixelFormat24bppBGR
,
1175 &GUID_WICPixelFormat32bppCMYK
,
1176 &GUID_WICPixelFormat8bppGray
,
1180 static struct decoder_pattern
const jpeg_patterns
[] = {
1181 {2,0,jpeg_magic
,mask_all
,0},
1185 static const BYTE png_magic
[] = {137,80,78,71,13,10,26,10};
1187 static GUID
const * const png_formats
[] = {
1188 &GUID_WICPixelFormatBlackWhite
,
1189 &GUID_WICPixelFormat2bppGray
,
1190 &GUID_WICPixelFormat4bppGray
,
1191 &GUID_WICPixelFormat8bppGray
,
1192 &GUID_WICPixelFormat16bppGray
,
1193 &GUID_WICPixelFormat32bppBGRA
,
1194 &GUID_WICPixelFormat64bppRGBA
,
1195 &GUID_WICPixelFormat1bppIndexed
,
1196 &GUID_WICPixelFormat2bppIndexed
,
1197 &GUID_WICPixelFormat4bppIndexed
,
1198 &GUID_WICPixelFormat8bppIndexed
,
1199 &GUID_WICPixelFormat24bppBGR
,
1200 &GUID_WICPixelFormat48bppRGB
,
1204 static struct decoder_pattern
const png_patterns
[] = {
1205 {8,0,png_magic
,mask_all
,0},
1209 static const BYTE tiff_magic_le
[] = {0x49,0x49,42,0};
1210 static const BYTE tiff_magic_be
[] = {0x4d,0x4d,0,42};
1212 static GUID
const * const tiff_decode_formats
[] = {
1213 &GUID_WICPixelFormatBlackWhite
,
1214 &GUID_WICPixelFormat4bppGray
,
1215 &GUID_WICPixelFormat8bppGray
,
1216 &GUID_WICPixelFormat4bppIndexed
,
1217 &GUID_WICPixelFormat8bppIndexed
,
1218 &GUID_WICPixelFormat24bppBGR
,
1219 &GUID_WICPixelFormat32bppBGR
,
1220 &GUID_WICPixelFormat32bppBGRA
,
1221 &GUID_WICPixelFormat32bppPBGRA
,
1222 &GUID_WICPixelFormat48bppRGB
,
1223 &GUID_WICPixelFormat64bppRGBA
,
1224 &GUID_WICPixelFormat64bppPRGBA
,
1228 static struct decoder_pattern
const tiff_patterns
[] = {
1229 {4,0,tiff_magic_le
,mask_all
,0},
1230 {4,0,tiff_magic_be
,mask_all
,0},
1234 static const BYTE tga_footer_magic
[18] = "TRUEVISION-XFILE.";
1236 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};
1237 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};
1239 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};
1240 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};
1242 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};
1243 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};
1245 static GUID
const * const tga_formats
[] = {
1246 &GUID_WICPixelFormat8bppGray
,
1247 &GUID_WICPixelFormat8bppIndexed
,
1248 &GUID_WICPixelFormat16bppGray
,
1249 &GUID_WICPixelFormat16bppBGR555
,
1250 &GUID_WICPixelFormat24bppBGR
,
1251 &GUID_WICPixelFormat32bppBGRA
,
1252 &GUID_WICPixelFormat32bppPBGRA
,
1256 static struct decoder_pattern
const tga_patterns
[] = {
1257 {18,18,tga_footer_magic
,mask_all
,1},
1258 {18,0,tga_indexed_magic
,tga_indexed_mask
,0},
1259 {18,0,tga_truecolor_magic
,tga_truecolor_mask
,0},
1260 {18,0,tga_grayscale_magic
,tga_grayscale_mask
,0},
1264 static struct regsvr_decoder
const decoder_list
[] = {
1265 { &CLSID_WICBmpDecoder
,
1269 &GUID_VendorMicrosoft
,
1270 &GUID_ContainerFormatBmp
,
1276 { &CLSID_WICGifDecoder
,
1280 &GUID_VendorMicrosoft
,
1281 &GUID_ContainerFormatGif
,
1287 { &CLSID_WICIcoDecoder
,
1291 &GUID_VendorMicrosoft
,
1292 &GUID_ContainerFormatIco
,
1293 "image/vnd.microsoft.icon",
1298 { &CLSID_WICJpegDecoder
,
1302 &GUID_VendorMicrosoft
,
1303 &GUID_ContainerFormatJpeg
,
1309 { &CLSID_WICPngDecoder
,
1313 &GUID_VendorMicrosoft
,
1314 &GUID_ContainerFormatPng
,
1320 { &CLSID_WICTiffDecoder
,
1324 &GUID_VendorMicrosoft
,
1325 &GUID_ContainerFormatTiff
,
1328 tiff_decode_formats
,
1331 { &CLSID_WineTgaDecoder
,
1336 &GUID_WineContainerFormatTga
,
1342 { NULL
} /* list terminator */
1345 static GUID
const * const bmp_encode_formats
[] = {
1346 &GUID_WICPixelFormat16bppBGR555
,
1347 &GUID_WICPixelFormat16bppBGR565
,
1348 &GUID_WICPixelFormat24bppBGR
,
1349 &GUID_WICPixelFormat32bppBGR
,
1353 static GUID
const * const png_encode_formats
[] = {
1354 &GUID_WICPixelFormat24bppBGR
,
1355 &GUID_WICPixelFormatBlackWhite
,
1356 &GUID_WICPixelFormat2bppGray
,
1357 &GUID_WICPixelFormat4bppGray
,
1358 &GUID_WICPixelFormat8bppGray
,
1359 &GUID_WICPixelFormat16bppGray
,
1360 &GUID_WICPixelFormat32bppBGR
,
1361 &GUID_WICPixelFormat32bppBGRA
,
1362 &GUID_WICPixelFormat48bppRGB
,
1363 &GUID_WICPixelFormat64bppRGBA
,
1367 static GUID
const * const tiff_encode_formats
[] = {
1368 &GUID_WICPixelFormatBlackWhite
,
1369 &GUID_WICPixelFormat4bppGray
,
1370 &GUID_WICPixelFormat8bppGray
,
1371 &GUID_WICPixelFormat24bppBGR
,
1372 &GUID_WICPixelFormat32bppBGRA
,
1373 &GUID_WICPixelFormat32bppPBGRA
,
1374 &GUID_WICPixelFormat48bppRGB
,
1375 &GUID_WICPixelFormat64bppRGBA
,
1376 &GUID_WICPixelFormat64bppPRGBA
,
1380 static GUID
const * const icns_encode_formats
[] = {
1381 &GUID_WICPixelFormat32bppBGRA
,
1385 static struct regsvr_encoder
const encoder_list
[] = {
1386 { &CLSID_WICBmpEncoder
,
1390 &GUID_VendorMicrosoft
,
1391 &GUID_ContainerFormatBmp
,
1396 { &CLSID_WICJpegEncoder
,
1400 &GUID_VendorMicrosoft
,
1401 &GUID_ContainerFormatJpeg
,
1406 { &CLSID_WICPngEncoder
,
1410 &GUID_VendorMicrosoft
,
1411 &GUID_ContainerFormatPng
,
1416 { &CLSID_WICTiffEncoder
,
1420 &GUID_VendorMicrosoft
,
1421 &GUID_ContainerFormatTiff
,
1426 { &CLSID_WICIcnsEncoder
,
1431 NULL
, /* no container format guid */
1436 { NULL
} /* list terminator */
1439 static GUID
const * const converter_formats
[] = {
1440 &GUID_WICPixelFormat1bppIndexed
,
1441 &GUID_WICPixelFormat2bppIndexed
,
1442 &GUID_WICPixelFormat4bppIndexed
,
1443 &GUID_WICPixelFormat8bppIndexed
,
1444 &GUID_WICPixelFormatBlackWhite
,
1445 &GUID_WICPixelFormat2bppGray
,
1446 &GUID_WICPixelFormat4bppGray
,
1447 &GUID_WICPixelFormat8bppGray
,
1448 &GUID_WICPixelFormat16bppGray
,
1449 &GUID_WICPixelFormat16bppBGR555
,
1450 &GUID_WICPixelFormat16bppBGR565
,
1451 &GUID_WICPixelFormat16bppBGRA5551
,
1452 &GUID_WICPixelFormat24bppBGR
,
1453 &GUID_WICPixelFormat24bppRGB
,
1454 &GUID_WICPixelFormat32bppBGR
,
1455 &GUID_WICPixelFormat32bppBGRA
,
1456 &GUID_WICPixelFormat32bppPBGRA
,
1457 &GUID_WICPixelFormat48bppRGB
,
1458 &GUID_WICPixelFormat64bppRGBA
,
1459 &GUID_WICPixelFormat32bppCMYK
,
1463 static struct regsvr_converter
const converter_list
[] = {
1464 { &CLSID_WICDefaultFormatConverter
,
1466 "Default Pixel Format Converter",
1468 &GUID_VendorMicrosoft
,
1471 { NULL
} /* list terminator */
1474 static const BYTE no_magic
[1] = { 0 };
1475 static const BYTE no_mask
[1] = { 0 };
1477 static const struct metadata_pattern ifd_metadata_pattern
[] = {
1478 { 0, 1, no_magic
, no_mask
, 0 },
1482 static const struct reader_containers ifd_containers
[] = {
1484 &GUID_ContainerFormatTiff
,
1485 ifd_metadata_pattern
1487 { NULL
} /* list terminator */
1490 static const BYTE tEXt
[] = "tEXt";
1492 static const struct metadata_pattern pngtext_metadata_pattern
[] = {
1493 { 4, 4, tEXt
, mask_all
, 4 },
1497 static const struct reader_containers pngtext_containers
[] = {
1499 &GUID_ContainerFormatPng
,
1500 pngtext_metadata_pattern
1502 { NULL
} /* list terminator */
1505 static const BYTE gAMA
[] = "gAMA";
1507 static const struct metadata_pattern pnggama_metadata_pattern
[] = {
1508 { 4, 4, gAMA
, mask_all
, 4 },
1512 static const struct reader_containers pnggama_containers
[] = {
1514 &GUID_ContainerFormatPng
,
1515 pnggama_metadata_pattern
1517 { NULL
} /* list terminator */
1520 static const struct metadata_pattern lsd_metadata_patterns
[] = {
1521 { 0, 6, gif87a_magic
, mask_all
, 0 },
1522 { 0, 6, gif89a_magic
, mask_all
, 0 },
1526 static const struct reader_containers lsd_containers
[] = {
1528 &GUID_ContainerFormatGif
,
1529 lsd_metadata_patterns
1531 { NULL
} /* list terminator */
1534 static const BYTE imd_magic
[] = { 0x2c };
1536 static const struct metadata_pattern imd_metadata_pattern
[] = {
1537 { 0, 1, imd_magic
, mask_all
, 1 },
1541 static const struct reader_containers imd_containers
[] = {
1543 &GUID_ContainerFormatGif
,
1544 imd_metadata_pattern
1546 { NULL
} /* list terminator */
1549 static const BYTE gce_magic
[] = { 0x21, 0xf9, 0x04 };
1551 static const struct metadata_pattern gce_metadata_pattern
[] = {
1552 { 0, 3, gce_magic
, mask_all
, 3 },
1556 static const struct reader_containers gce_containers
[] = {
1558 &GUID_ContainerFormatGif
,
1559 gce_metadata_pattern
1561 { NULL
} /* list terminator */
1564 static const BYTE ape_magic
[] = { 0x21, 0xff, 0x0b };
1566 static const struct metadata_pattern ape_metadata_pattern
[] = {
1567 { 0, 3, ape_magic
, mask_all
, 0 },
1571 static const struct reader_containers ape_containers
[] = {
1573 &GUID_ContainerFormatGif
,
1574 ape_metadata_pattern
1576 { NULL
} /* list terminator */
1579 static const BYTE gif_comment_magic
[] = { 0x21, 0xfe };
1581 static const struct metadata_pattern gif_comment_metadata_pattern
[] = {
1582 { 0, 2, gif_comment_magic
, mask_all
, 0 },
1586 static const struct reader_containers gif_comment_containers
[] = {
1588 &GUID_ContainerFormatGif
,
1589 gif_comment_metadata_pattern
1591 { NULL
} /* list terminator */
1594 static struct regsvr_metadatareader
const metadatareader_list
[] = {
1595 { &CLSID_WICUnknownMetadataReader
,
1597 "Unknown Metadata Reader",
1600 &GUID_VendorMicrosoft
,
1601 &GUID_MetadataFormatUnknown
,
1605 { &CLSID_WICIfdMetadataReader
,
1610 &GUID_VendorMicrosoft
,
1611 &GUID_MetadataFormatIfd
,
1615 { &CLSID_WICPngGamaMetadataReader
,
1617 "Chunk gAMA Reader",
1620 &GUID_VendorMicrosoft
,
1621 &GUID_MetadataFormatChunkgAMA
,
1625 { &CLSID_WICPngTextMetadataReader
,
1627 "Chunk tEXt Reader",
1630 &GUID_VendorMicrosoft
,
1631 &GUID_MetadataFormatChunktEXt
,
1635 { &CLSID_WICLSDMetadataReader
,
1637 "Logical Screen Descriptor Reader",
1640 &GUID_VendorMicrosoft
,
1641 &GUID_MetadataFormatLSD
,
1645 { &CLSID_WICIMDMetadataReader
,
1647 "Image Descriptor Reader",
1650 &GUID_VendorMicrosoft
,
1651 &GUID_MetadataFormatIMD
,
1655 { &CLSID_WICGCEMetadataReader
,
1657 "Graphic Control Extension Reader",
1660 &GUID_VendorMicrosoft
,
1661 &GUID_MetadataFormatGCE
,
1665 { &CLSID_WICAPEMetadataReader
,
1667 "Application Extension Reader",
1670 &GUID_VendorMicrosoft
,
1671 &GUID_MetadataFormatAPE
,
1675 { &CLSID_WICGifCommentMetadataReader
,
1677 "Comment Extension Reader",
1680 &GUID_VendorMicrosoft
,
1681 &GUID_MetadataFormatGifComment
,
1683 gif_comment_containers
1685 { NULL
} /* list terminator */
1688 static BYTE
const channel_mask_1bit
[] = { 0x01 };
1689 static BYTE
const channel_mask_2bit
[] = { 0x03 };
1690 static BYTE
const channel_mask_4bit
[] = { 0x0f };
1692 static BYTE
const channel_mask_8bit
[] = { 0xff, 0x00, 0x00, 0x00 };
1693 static BYTE
const channel_mask_8bit2
[] = { 0x00, 0xff, 0x00, 0x00 };
1694 static BYTE
const channel_mask_8bit3
[] = { 0x00, 0x00, 0xff, 0x00 };
1695 static BYTE
const channel_mask_8bit4
[] = { 0x00, 0x00, 0x00, 0xff };
1697 static BYTE
const channel_mask_16bit
[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1698 static BYTE
const channel_mask_16bit2
[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1699 static BYTE
const channel_mask_16bit3
[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
1700 static BYTE
const channel_mask_16bit4
[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
1702 static BYTE
const channel_mask_5bit
[] = { 0x1f, 0x00 };
1703 static BYTE
const channel_mask_5bit2
[] = { 0xe0, 0x03 };
1704 static BYTE
const channel_mask_5bit3
[] = { 0x00, 0x7c };
1705 static BYTE
const channel_mask_5bit4
[] = { 0x00, 0x80 };
1707 static BYTE
const channel_mask_BGR565_2
[] = { 0xe0, 0x07 };
1708 static BYTE
const channel_mask_BGR565_3
[] = { 0x00, 0xf8 };
1710 static BYTE
const * const channel_masks_1bit
[] = { channel_mask_1bit
};
1711 static BYTE
const * const channel_masks_2bit
[] = { channel_mask_2bit
};
1712 static BYTE
const * const channel_masks_4bit
[] = { channel_mask_4bit
};
1713 static BYTE
const * const channel_masks_8bit
[] = { channel_mask_8bit
,
1714 channel_mask_8bit2
, channel_mask_8bit3
, channel_mask_8bit4
};
1715 static BYTE
const * const channel_masks_16bit
[] = { channel_mask_16bit
,
1716 channel_mask_16bit2
, channel_mask_16bit3
, channel_mask_16bit4
};
1718 static BYTE
const * const channel_masks_BGRA5551
[] = { channel_mask_5bit
,
1719 channel_mask_5bit2
, channel_mask_5bit3
, channel_mask_5bit4
};
1721 static BYTE
const * const channel_masks_BGR565
[] = { channel_mask_5bit
,
1722 channel_mask_BGR565_2
, channel_mask_BGR565_3
};
1724 static struct regsvr_pixelformat
const pixelformat_list
[] = {
1725 { &GUID_WICPixelFormat1bppIndexed
,
1728 NULL
, /* no version */
1729 &GUID_VendorMicrosoft
,
1730 1, /* bitsperpixel */
1731 1, /* channel count */
1733 WICPixelFormatNumericRepresentationIndexed
,
1736 { &GUID_WICPixelFormat2bppIndexed
,
1739 NULL
, /* no version */
1740 &GUID_VendorMicrosoft
,
1741 2, /* bitsperpixel */
1742 1, /* channel count */
1744 WICPixelFormatNumericRepresentationIndexed
,
1747 { &GUID_WICPixelFormat4bppIndexed
,
1750 NULL
, /* no version */
1751 &GUID_VendorMicrosoft
,
1752 4, /* bitsperpixel */
1753 1, /* channel count */
1755 WICPixelFormatNumericRepresentationIndexed
,
1758 { &GUID_WICPixelFormat8bppIndexed
,
1761 NULL
, /* no version */
1762 &GUID_VendorMicrosoft
,
1763 8, /* bitsperpixel */
1764 1, /* channel count */
1766 WICPixelFormatNumericRepresentationIndexed
,
1769 { &GUID_WICPixelFormatBlackWhite
,
1772 NULL
, /* no version */
1773 &GUID_VendorMicrosoft
,
1774 1, /* bitsperpixel */
1775 1, /* channel count */
1777 WICPixelFormatNumericRepresentationUnsignedInteger
,
1780 { &GUID_WICPixelFormat2bppGray
,
1783 NULL
, /* no version */
1784 &GUID_VendorMicrosoft
,
1785 2, /* bitsperpixel */
1786 1, /* channel count */
1788 WICPixelFormatNumericRepresentationUnsignedInteger
,
1791 { &GUID_WICPixelFormat4bppGray
,
1794 NULL
, /* no version */
1795 &GUID_VendorMicrosoft
,
1796 4, /* bitsperpixel */
1797 1, /* channel count */
1799 WICPixelFormatNumericRepresentationUnsignedInteger
,
1802 { &GUID_WICPixelFormat8bppGray
,
1805 NULL
, /* no version */
1806 &GUID_VendorMicrosoft
,
1807 8, /* bitsperpixel */
1808 1, /* channel count */
1810 WICPixelFormatNumericRepresentationUnsignedInteger
,
1813 { &GUID_WICPixelFormat16bppGray
,
1816 NULL
, /* no version */
1817 &GUID_VendorMicrosoft
,
1818 16, /* bitsperpixel */
1819 1, /* channel count */
1820 channel_masks_16bit
,
1821 WICPixelFormatNumericRepresentationUnsignedInteger
,
1824 { &GUID_WICPixelFormat16bppBGR555
,
1827 NULL
, /* no version */
1828 &GUID_VendorMicrosoft
,
1829 16, /* bitsperpixel */
1830 3, /* channel count */
1831 channel_masks_BGRA5551
,
1832 WICPixelFormatNumericRepresentationUnsignedInteger
,
1835 { &GUID_WICPixelFormat16bppBGR565
,
1838 NULL
, /* no version */
1839 &GUID_VendorMicrosoft
,
1840 16, /* bitsperpixel */
1841 3, /* channel count */
1842 channel_masks_BGR565
,
1843 WICPixelFormatNumericRepresentationUnsignedInteger
,
1846 { &GUID_WICPixelFormat16bppBGRA5551
,
1849 NULL
, /* no version */
1850 &GUID_VendorMicrosoft
,
1851 16, /* bitsperpixel */
1852 4, /* channel count */
1853 channel_masks_BGRA5551
,
1854 WICPixelFormatNumericRepresentationUnsignedInteger
,
1857 { &GUID_WICPixelFormat24bppBGR
,
1860 NULL
, /* no version */
1861 &GUID_VendorMicrosoft
,
1862 24, /* bitsperpixel */
1863 3, /* channel count */
1865 WICPixelFormatNumericRepresentationUnsignedInteger
,
1868 { &GUID_WICPixelFormat24bppRGB
,
1871 NULL
, /* no version */
1872 &GUID_VendorMicrosoft
,
1873 24, /* bitsperpixel */
1874 3, /* channel count */
1876 WICPixelFormatNumericRepresentationUnsignedInteger
,
1879 { &GUID_WICPixelFormat32bppBGR
,
1882 NULL
, /* no version */
1883 &GUID_VendorMicrosoft
,
1884 32, /* bitsperpixel */
1885 3, /* channel count */
1887 WICPixelFormatNumericRepresentationUnsignedInteger
,
1890 { &GUID_WICPixelFormat32bppBGRA
,
1893 NULL
, /* no version */
1894 &GUID_VendorMicrosoft
,
1895 32, /* bitsperpixel */
1896 4, /* channel count */
1898 WICPixelFormatNumericRepresentationUnsignedInteger
,
1901 { &GUID_WICPixelFormat32bppPBGRA
,
1904 NULL
, /* no version */
1905 &GUID_VendorMicrosoft
,
1906 32, /* bitsperpixel */
1907 4, /* channel count */
1909 WICPixelFormatNumericRepresentationUnsignedInteger
,
1912 { &GUID_WICPixelFormat48bppRGB
,
1915 NULL
, /* no version */
1916 &GUID_VendorMicrosoft
,
1917 48, /* bitsperpixel */
1918 3, /* channel count */
1919 channel_masks_16bit
,
1920 WICPixelFormatNumericRepresentationUnsignedInteger
,
1923 { &GUID_WICPixelFormat64bppRGBA
,
1926 NULL
, /* no version */
1927 &GUID_VendorMicrosoft
,
1928 64, /* bitsperpixel */
1929 4, /* channel count */
1930 channel_masks_16bit
,
1931 WICPixelFormatNumericRepresentationUnsignedInteger
,
1934 { &GUID_WICPixelFormat64bppPRGBA
,
1937 NULL
, /* no version */
1938 &GUID_VendorMicrosoft
,
1939 64, /* bitsperpixel */
1940 4, /* channel count */
1941 channel_masks_16bit
,
1942 WICPixelFormatNumericRepresentationUnsignedInteger
,
1945 { &GUID_WICPixelFormat32bppCMYK
,
1948 NULL
, /* no version */
1949 &GUID_VendorMicrosoft
,
1950 32, /* bitsperpixel */
1951 4, /* channel count */
1953 WICPixelFormatNumericRepresentationUnsignedInteger
,
1956 { NULL
} /* list terminator */
1959 struct regsvr_category
1961 const CLSID
*clsid
; /* NULL for end of list */
1964 static const struct regsvr_category category_list
[] = {
1965 { &CATID_WICBitmapDecoders
},
1966 { &CATID_WICBitmapEncoders
},
1967 { &CATID_WICFormatConverters
},
1968 { &CATID_WICMetadataReader
},
1969 { &CATID_WICPixelFormats
},
1973 static HRESULT
register_categories(const struct regsvr_category
*list
)
1977 HKEY coclass_key
, categories_key
, instance_key
;
1979 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
1980 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
1981 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
1983 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
1984 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
1985 KEY_READ
| KEY_WRITE
, NULL
, &categories_key
, NULL
);
1986 if (res
!= ERROR_SUCCESS
)
1988 RegCloseKey(coclass_key
);
1989 return HRESULT_FROM_WIN32(res
);
1992 res
= RegCreateKeyExW(categories_key
, instance_keyname
, 0, NULL
, 0,
1993 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
1995 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
1997 HKEY instance_clsid_key
;
1999 StringFromGUID2(list
->clsid
, buf
, 39);
2000 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
2001 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
2002 if (res
== ERROR_SUCCESS
)
2004 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
2005 (const BYTE
*)buf
, 78);
2006 RegCloseKey(instance_clsid_key
);
2010 RegCloseKey(instance_key
);
2011 RegCloseKey(categories_key
);
2012 RegCloseKey(coclass_key
);
2014 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
2017 static HRESULT
unregister_categories(const struct regsvr_category
*list
)
2021 HKEY coclass_key
, categories_key
, instance_key
;
2023 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
2024 KEY_READ
| KEY_WRITE
, &coclass_key
);
2025 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
2027 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2028 res
= RegOpenKeyExW(coclass_key
, buf
, 0,
2029 KEY_READ
| KEY_WRITE
, &categories_key
);
2030 if (res
!= ERROR_SUCCESS
)
2032 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
2033 RegCloseKey(coclass_key
);
2034 return HRESULT_FROM_WIN32(res
);
2037 res
= RegOpenKeyExW(categories_key
, instance_keyname
, 0,
2038 KEY_READ
| KEY_WRITE
, &instance_key
);
2040 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
2042 StringFromGUID2(list
->clsid
, buf
, 39);
2043 res
= RegDeleteTreeW(instance_key
, buf
);
2046 RegCloseKey(instance_key
);
2047 RegCloseKey(categories_key
);
2049 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2050 res
= RegDeleteTreeW(coclass_key
, buf
);
2052 RegCloseKey(coclass_key
);
2054 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
2057 extern HRESULT WINAPI
WIC_DllRegisterServer(void) DECLSPEC_HIDDEN
;
2058 extern HRESULT WINAPI
WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
2060 HRESULT WINAPI
DllRegisterServer(void)
2066 hr
= WIC_DllRegisterServer();
2068 hr
= register_categories(category_list
);
2070 hr
= register_decoders(decoder_list
);
2072 hr
= register_encoders(encoder_list
);
2074 hr
= register_converters(converter_list
);
2076 hr
= register_metadatareaders(metadatareader_list
);
2078 hr
= register_pixelformats(pixelformat_list
);
2082 HRESULT WINAPI
DllUnregisterServer(void)
2088 hr
= WIC_DllUnregisterServer();
2090 hr
= unregister_categories(category_list
);
2092 hr
= unregister_decoders(decoder_list
);
2094 hr
= unregister_encoders(encoder_list
);
2096 hr
= unregister_converters(converter_list
);
2098 hr
= unregister_metadatareaders(metadatareader_list
);
2100 hr
= unregister_pixelformats(pixelformat_list
);