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
19 #include "wincodecs_private.h"
23 /***********************************************************************
24 * interface for self-registering
26 struct decoder_pattern
28 DWORD length
; /* 0 for end of list */
37 CLSID
const *clsid
; /* NULL for end of list */
42 GUID
const *container_format
;
45 GUID
const * const *formats
;
46 const struct decoder_pattern
*patterns
;
49 static HRESULT
register_decoders(struct regsvr_decoder
const *list
);
50 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
);
54 CLSID
const *clsid
; /* NULL for end of list */
59 GUID
const *container_format
;
62 GUID
const * const *formats
;
65 static HRESULT
register_encoders(struct regsvr_encoder
const *list
);
66 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
);
68 struct regsvr_converter
70 CLSID
const *clsid
; /* NULL for end of list */
75 GUID
const * const *formats
;
78 static HRESULT
register_converters(struct regsvr_converter
const *list
);
79 static HRESULT
unregister_converters(struct regsvr_converter
const *list
);
81 struct metadata_pattern
90 struct reader_containers
93 const struct metadata_pattern
*patterns
;
96 struct regsvr_metadatareader
98 CLSID
const *clsid
; /* NULL for end of list */
104 GUID
const *metadata_format
;
105 DWORD requires_fullstream
;
106 DWORD supports_padding
;
107 DWORD requires_fixedsize
;
108 const struct reader_containers
*containers
;
111 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
);
112 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
);
114 struct regsvr_pixelformat
116 CLSID
const *clsid
; /* NULL for end of list */
123 BYTE
const * const *channelmasks
;
124 WICPixelFormatNumericRepresentation numericrepresentation
;
128 static HRESULT
register_pixelformats(struct regsvr_pixelformat
const *list
);
129 static HRESULT
unregister_pixelformats(struct regsvr_pixelformat
const *list
);
131 /***********************************************************************
132 * static string constants
134 static const WCHAR clsid_keyname
[] = {
135 'C', 'L', 'S', 'I', 'D', 0 };
136 static const char author_valuename
[] = "Author";
137 static const char friendlyname_valuename
[] = "FriendlyName";
138 static const WCHAR vendor_valuename
[] = {'V','e','n','d','o','r',0};
139 static const WCHAR containerformat_valuename
[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
140 static const char version_valuename
[] = "Version";
141 static const char mimetypes_valuename
[] = "MimeTypes";
142 static const char extensions_valuename
[] = "FileExtensions";
143 static const WCHAR formats_keyname
[] = {'F','o','r','m','a','t','s',0};
144 static const WCHAR patterns_keyname
[] = {'P','a','t','t','e','r','n','s',0};
145 static const WCHAR instance_keyname
[] = {'I','n','s','t','a','n','c','e',0};
146 static const WCHAR clsid_valuename
[] = {'C','L','S','I','D',0};
147 static const char length_valuename
[] = "Length";
148 static const char position_valuename
[] = "Position";
149 static const char pattern_valuename
[] = "Pattern";
150 static const char mask_valuename
[] = "Mask";
151 static const char endofstream_valuename
[] = "EndOfStream";
152 static const WCHAR pixelformats_keyname
[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
153 static const WCHAR metadataformat_valuename
[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
154 static const char specversion_valuename
[] = "SpecVersion";
155 static const char requiresfullstream_valuename
[] = "RequiresFullStream";
156 static const char supportspadding_valuename
[] = "SupportsPadding";
157 static const char requiresfixedsize_valuename
[] = "FixedSize";
158 static const WCHAR containers_keyname
[] = {'C','o','n','t','a','i','n','e','r','s',0};
159 static const char dataoffset_valuename
[] = "DataOffset";
160 static const char bitsperpixel_valuename
[] = "BitLength";
161 static const char channelcount_valuename
[] = "ChannelCount";
162 static const char numericrepresentation_valuename
[] = "NumericRepresentation";
163 static const char supportstransparency_valuename
[] = "SupportsTransparency";
164 static const WCHAR channelmasks_keyname
[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
166 /***********************************************************************
169 static HRESULT
register_decoders(struct regsvr_decoder
const *list
)
171 LONG res
= ERROR_SUCCESS
;
177 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
178 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
179 if (res
== ERROR_SUCCESS
) {
180 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
181 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
182 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
183 if (res
== ERROR_SUCCESS
)
185 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
186 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
187 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
189 if (res
!= ERROR_SUCCESS
)
190 RegCloseKey(coclass_key
);
192 if (res
!= ERROR_SUCCESS
) goto error_return
;
194 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
196 HKEY instance_clsid_key
;
198 StringFromGUID2(list
->clsid
, buf
, 39);
199 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
200 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
201 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
203 StringFromGUID2(list
->clsid
, buf
, 39);
204 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
205 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
206 if (res
== ERROR_SUCCESS
) {
207 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
208 (const BYTE
*)buf
, 78);
209 RegCloseKey(instance_clsid_key
);
211 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
214 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
215 (const BYTE
*)list
->author
,
216 strlen(list
->author
) + 1);
217 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
220 if (list
->friendlyname
) {
221 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
222 (const BYTE
*)list
->friendlyname
,
223 strlen(list
->friendlyname
) + 1);
224 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
228 StringFromGUID2(list
->vendor
, buf
, 39);
229 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
230 (const BYTE
*)buf
, 78);
231 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
234 if (list
->container_format
) {
235 StringFromGUID2(list
->container_format
, buf
, 39);
236 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
237 (const BYTE
*)buf
, 78);
238 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
242 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
243 (const BYTE
*)list
->version
,
244 strlen(list
->version
) + 1);
245 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
248 if (list
->mimetypes
) {
249 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
250 (const BYTE
*)list
->mimetypes
,
251 strlen(list
->mimetypes
) + 1);
252 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
255 if (list
->extensions
) {
256 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
257 (const BYTE
*)list
->extensions
,
258 strlen(list
->extensions
) + 1);
259 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
264 GUID
const * const *format
;
266 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
267 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
268 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
269 for (format
=list
->formats
; *format
; ++format
)
272 StringFromGUID2(*format
, buf
, 39);
273 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
274 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
275 if (res
!= ERROR_SUCCESS
) break;
276 RegCloseKey(format_key
);
278 RegCloseKey(formats_key
);
279 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
282 if (list
->patterns
) {
286 res
= RegCreateKeyExW(clsid_key
, patterns_keyname
, 0, NULL
, 0,
287 KEY_READ
| KEY_WRITE
, NULL
, &patterns_key
, NULL
);
288 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
289 for (i
=0; list
->patterns
[i
].length
; i
++)
292 static const WCHAR int_format
[] = {'%','i',0};
293 snprintfW(buf
, 39, int_format
, i
);
294 res
= RegCreateKeyExW(patterns_key
, buf
, 0, NULL
, 0,
295 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
296 if (res
!= ERROR_SUCCESS
) break;
297 res
= RegSetValueExA(pattern_key
, length_valuename
, 0, REG_DWORD
,
298 (const BYTE
*)&list
->patterns
[i
].length
, 4);
299 if (res
== ERROR_SUCCESS
)
300 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
301 (const BYTE
*)&list
->patterns
[i
].position
, 4);
302 if (res
== ERROR_SUCCESS
)
303 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
304 list
->patterns
[i
].pattern
,
305 list
->patterns
[i
].length
);
306 if (res
== ERROR_SUCCESS
)
307 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
308 list
->patterns
[i
].mask
,
309 list
->patterns
[i
].length
);
310 if (res
== ERROR_SUCCESS
)
311 res
= RegSetValueExA(pattern_key
, endofstream_valuename
, 0, REG_DWORD
,
312 (const BYTE
*)&list
->patterns
[i
].endofstream
, 4);
313 RegCloseKey(pattern_key
);
315 RegCloseKey(patterns_key
);
316 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
319 error_close_clsid_key
:
320 RegCloseKey(clsid_key
);
323 error_close_coclass_key
:
324 RegCloseKey(instance_key
);
325 RegCloseKey(decoders_key
);
326 RegCloseKey(coclass_key
);
328 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
331 /***********************************************************************
332 * unregister_decoders
334 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
)
336 LONG res
= ERROR_SUCCESS
;
342 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
343 KEY_READ
| KEY_WRITE
, &coclass_key
);
344 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
346 if (res
== ERROR_SUCCESS
) {
347 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
348 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
349 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
350 if (res
== ERROR_SUCCESS
)
352 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
353 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
354 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
356 if (res
!= ERROR_SUCCESS
)
357 RegCloseKey(coclass_key
);
359 if (res
!= ERROR_SUCCESS
) goto error_return
;
361 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
362 StringFromGUID2(list
->clsid
, buf
, 39);
364 res
= RegDeleteTreeW(coclass_key
, buf
);
365 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
366 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
368 res
= RegDeleteTreeW(instance_key
, buf
);
369 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
370 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
373 error_close_coclass_key
:
374 RegCloseKey(instance_key
);
375 RegCloseKey(decoders_key
);
376 RegCloseKey(coclass_key
);
378 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
381 /***********************************************************************
384 static HRESULT
register_encoders(struct regsvr_encoder
const *list
)
386 LONG res
= ERROR_SUCCESS
;
392 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
393 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
394 if (res
== ERROR_SUCCESS
) {
395 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
396 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
397 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
398 if (res
== ERROR_SUCCESS
)
400 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
401 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
402 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
404 if (res
!= ERROR_SUCCESS
)
405 RegCloseKey(coclass_key
);
407 if (res
!= ERROR_SUCCESS
) goto error_return
;
409 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
411 HKEY instance_clsid_key
;
413 StringFromGUID2(list
->clsid
, buf
, 39);
414 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
415 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
416 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
418 StringFromGUID2(list
->clsid
, buf
, 39);
419 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
420 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
421 if (res
== ERROR_SUCCESS
) {
422 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
423 (const BYTE
*)buf
, 78);
424 RegCloseKey(instance_clsid_key
);
426 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
429 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
430 (const BYTE
*)list
->author
,
431 strlen(list
->author
) + 1);
432 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
435 if (list
->friendlyname
) {
436 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
437 (const BYTE
*)list
->friendlyname
,
438 strlen(list
->friendlyname
) + 1);
439 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
443 StringFromGUID2(list
->vendor
, buf
, 39);
444 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
445 (const BYTE
*)buf
, 78);
446 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
449 if (list
->container_format
) {
450 StringFromGUID2(list
->container_format
, buf
, 39);
451 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
452 (const BYTE
*)buf
, 78);
453 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
457 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
458 (const BYTE
*)list
->version
,
459 strlen(list
->version
) + 1);
460 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
463 if (list
->mimetypes
) {
464 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
465 (const BYTE
*)list
->mimetypes
,
466 strlen(list
->mimetypes
) + 1);
467 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
470 if (list
->extensions
) {
471 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
472 (const BYTE
*)list
->extensions
,
473 strlen(list
->extensions
) + 1);
474 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
479 GUID
const * const *format
;
481 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
482 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
483 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
484 for (format
=list
->formats
; *format
; ++format
)
487 StringFromGUID2(*format
, buf
, 39);
488 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
489 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
490 if (res
!= ERROR_SUCCESS
) break;
491 RegCloseKey(format_key
);
493 RegCloseKey(formats_key
);
494 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
497 error_close_clsid_key
:
498 RegCloseKey(clsid_key
);
501 error_close_coclass_key
:
502 RegCloseKey(instance_key
);
503 RegCloseKey(encoders_key
);
504 RegCloseKey(coclass_key
);
506 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
509 /***********************************************************************
510 * unregister_encoders
512 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
)
514 LONG res
= ERROR_SUCCESS
;
520 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
521 KEY_READ
| KEY_WRITE
, &coclass_key
);
522 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
524 if (res
== ERROR_SUCCESS
) {
525 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
526 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
527 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
528 if (res
== ERROR_SUCCESS
)
530 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
531 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
532 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
534 if (res
!= ERROR_SUCCESS
)
535 RegCloseKey(coclass_key
);
537 if (res
!= ERROR_SUCCESS
) goto error_return
;
539 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
540 StringFromGUID2(list
->clsid
, buf
, 39);
542 res
= RegDeleteTreeW(coclass_key
, buf
);
543 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
544 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
546 res
= RegDeleteTreeW(instance_key
, buf
);
547 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
548 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
551 error_close_coclass_key
:
552 RegCloseKey(instance_key
);
553 RegCloseKey(encoders_key
);
554 RegCloseKey(coclass_key
);
556 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
559 /***********************************************************************
560 * register_converters
562 static HRESULT
register_converters(struct regsvr_converter
const *list
)
564 LONG res
= ERROR_SUCCESS
;
570 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
571 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
572 if (res
== ERROR_SUCCESS
) {
573 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
574 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
575 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
576 if (res
== ERROR_SUCCESS
)
578 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
579 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
580 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
582 if (res
!= ERROR_SUCCESS
)
583 RegCloseKey(coclass_key
);
585 if (res
!= ERROR_SUCCESS
) goto error_return
;
587 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
589 HKEY instance_clsid_key
;
591 StringFromGUID2(list
->clsid
, buf
, 39);
592 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
593 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
594 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
596 StringFromGUID2(list
->clsid
, buf
, 39);
597 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
598 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
599 if (res
== ERROR_SUCCESS
) {
600 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
601 (const BYTE
*)buf
, 78);
602 RegCloseKey(instance_clsid_key
);
604 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
607 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
608 (const BYTE
*)list
->author
,
609 strlen(list
->author
) + 1);
610 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
613 if (list
->friendlyname
) {
614 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
615 (const BYTE
*)list
->friendlyname
,
616 strlen(list
->friendlyname
) + 1);
617 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
621 StringFromGUID2(list
->vendor
, buf
, 39);
622 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
623 (const BYTE
*)buf
, 78);
624 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
628 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
629 (const BYTE
*)list
->version
,
630 strlen(list
->version
) + 1);
631 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
636 GUID
const * const *format
;
638 res
= RegCreateKeyExW(clsid_key
, pixelformats_keyname
, 0, NULL
, 0,
639 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
640 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
641 for (format
=list
->formats
; *format
; ++format
)
644 StringFromGUID2(*format
, buf
, 39);
645 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
646 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
647 if (res
!= ERROR_SUCCESS
) break;
648 RegCloseKey(format_key
);
650 RegCloseKey(formats_key
);
651 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
654 error_close_clsid_key
:
655 RegCloseKey(clsid_key
);
658 error_close_coclass_key
:
659 RegCloseKey(instance_key
);
660 RegCloseKey(converters_key
);
661 RegCloseKey(coclass_key
);
663 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
666 /***********************************************************************
667 * unregister_converters
669 static HRESULT
unregister_converters(struct regsvr_converter
const *list
)
671 LONG res
= ERROR_SUCCESS
;
677 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
678 KEY_READ
| KEY_WRITE
, &coclass_key
);
679 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
681 if (res
== ERROR_SUCCESS
) {
682 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
683 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
684 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
685 if (res
== ERROR_SUCCESS
)
687 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
688 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
689 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
691 if (res
!= ERROR_SUCCESS
)
692 RegCloseKey(coclass_key
);
694 if (res
!= ERROR_SUCCESS
) goto error_return
;
696 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
697 StringFromGUID2(list
->clsid
, buf
, 39);
699 res
= RegDeleteTreeW(coclass_key
, buf
);
700 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
701 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
703 res
= RegDeleteTreeW(instance_key
, buf
);
704 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
705 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
708 error_close_coclass_key
:
709 RegCloseKey(instance_key
);
710 RegCloseKey(converters_key
);
711 RegCloseKey(coclass_key
);
713 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
716 /***********************************************************************
717 * register_metadatareaders
719 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
)
721 LONG res
= ERROR_SUCCESS
;
727 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
728 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
729 if (res
== ERROR_SUCCESS
) {
730 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
731 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
732 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
733 if (res
== ERROR_SUCCESS
)
735 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
736 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
737 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
739 if (res
!= ERROR_SUCCESS
)
740 RegCloseKey(coclass_key
);
742 if (res
!= ERROR_SUCCESS
) goto error_return
;
744 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
746 HKEY instance_clsid_key
;
748 StringFromGUID2(list
->clsid
, buf
, 39);
749 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
750 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
751 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
753 StringFromGUID2(list
->clsid
, buf
, 39);
754 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
755 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
756 if (res
== ERROR_SUCCESS
) {
757 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
758 (const BYTE
*)buf
, 78);
759 RegCloseKey(instance_clsid_key
);
761 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
764 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
765 (const BYTE
*)list
->author
,
766 strlen(list
->author
) + 1);
767 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
770 if (list
->friendlyname
) {
771 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
772 (const BYTE
*)list
->friendlyname
,
773 strlen(list
->friendlyname
) + 1);
774 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
778 StringFromGUID2(list
->vendor
, buf
, 39);
779 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
780 (const BYTE
*)buf
, 78);
781 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
784 if (list
->metadata_format
) {
785 StringFromGUID2(list
->metadata_format
, buf
, 39);
786 res
= RegSetValueExW(clsid_key
, metadataformat_valuename
, 0, REG_SZ
,
787 (const BYTE
*)buf
, 78);
788 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
792 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
793 (const BYTE
*)list
->version
,
794 strlen(list
->version
) + 1);
795 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
798 if (list
->specversion
) {
799 res
= RegSetValueExA(clsid_key
, specversion_valuename
, 0, REG_SZ
,
800 (const BYTE
*)list
->version
,
801 strlen(list
->version
) + 1);
802 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
805 res
= RegSetValueExA(clsid_key
, requiresfullstream_valuename
, 0, REG_DWORD
,
806 (const BYTE
*)&list
->requires_fullstream
, 4);
807 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
809 res
= RegSetValueExA(clsid_key
, supportspadding_valuename
, 0, REG_DWORD
,
810 (const BYTE
*)&list
->supports_padding
, 4);
811 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
813 if (list
->requires_fixedsize
) {
814 res
= RegSetValueExA(clsid_key
, requiresfixedsize_valuename
, 0, REG_DWORD
,
815 (const BYTE
*)&list
->requires_fixedsize
, 4);
816 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
819 if (list
->containers
) {
821 const struct reader_containers
*container
;
823 res
= RegCreateKeyExW(clsid_key
, containers_keyname
, 0, NULL
, 0,
824 KEY_READ
| KEY_WRITE
, NULL
, &containers_key
, NULL
);
825 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
826 for (container
=list
->containers
; container
->format
; ++container
)
830 StringFromGUID2(container
->format
, buf
, 39);
831 res
= RegCreateKeyExW(containers_key
, buf
, 0, NULL
, 0,
832 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
833 if (res
!= ERROR_SUCCESS
) break;
835 for (i
=0; container
->patterns
[i
].length
; i
++)
838 static const WCHAR int_format
[] = {'%','i',0};
839 snprintfW(buf
, 39, int_format
, i
);
840 res
= RegCreateKeyExW(format_key
, buf
, 0, NULL
, 0,
841 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
842 if (res
!= ERROR_SUCCESS
) break;
843 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
844 (const BYTE
*)&container
->patterns
[i
].position
, 4);
845 if (res
== ERROR_SUCCESS
)
846 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
847 container
->patterns
[i
].pattern
,
848 container
->patterns
[i
].length
);
849 if (res
== ERROR_SUCCESS
)
850 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
851 container
->patterns
[i
].mask
,
852 container
->patterns
[i
].length
);
853 if (res
== ERROR_SUCCESS
&& container
->patterns
[i
].data_offset
)
854 res
= RegSetValueExA(pattern_key
, dataoffset_valuename
, 0, REG_DWORD
,
855 (const BYTE
*)&container
->patterns
[i
].data_offset
, 4);
856 RegCloseKey(pattern_key
);
859 RegCloseKey(format_key
);
861 RegCloseKey(containers_key
);
864 error_close_clsid_key
:
865 RegCloseKey(clsid_key
);
868 error_close_coclass_key
:
869 RegCloseKey(instance_key
);
870 RegCloseKey(readers_key
);
871 RegCloseKey(coclass_key
);
873 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
876 /***********************************************************************
877 * unregister_metadatareaders
879 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
)
881 LONG res
= ERROR_SUCCESS
;
887 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
888 KEY_READ
| KEY_WRITE
, &coclass_key
);
889 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
891 if (res
== ERROR_SUCCESS
) {
892 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
893 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
894 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
895 if (res
== ERROR_SUCCESS
)
897 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
898 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
899 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
901 if (res
!= ERROR_SUCCESS
)
902 RegCloseKey(coclass_key
);
904 if (res
!= ERROR_SUCCESS
) goto error_return
;
906 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
907 StringFromGUID2(list
->clsid
, buf
, 39);
909 res
= RegDeleteTreeW(coclass_key
, buf
);
910 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
911 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
913 res
= RegDeleteTreeW(instance_key
, buf
);
914 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
915 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
918 error_close_coclass_key
:
919 RegCloseKey(instance_key
);
920 RegCloseKey(readers_key
);
921 RegCloseKey(coclass_key
);
923 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
926 /***********************************************************************
927 * register_pixelformats
929 static HRESULT
register_pixelformats(struct regsvr_pixelformat
const *list
)
931 LONG res
= ERROR_SUCCESS
;
937 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
938 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
939 if (res
== ERROR_SUCCESS
) {
940 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
941 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
942 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
943 if (res
== ERROR_SUCCESS
)
945 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
946 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
947 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
949 if (res
!= ERROR_SUCCESS
)
950 RegCloseKey(coclass_key
);
952 if (res
!= ERROR_SUCCESS
) goto error_return
;
954 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
956 HKEY instance_clsid_key
;
958 StringFromGUID2(list
->clsid
, buf
, 39);
959 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
960 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
961 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
963 StringFromGUID2(list
->clsid
, buf
, 39);
964 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
965 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
966 if (res
== ERROR_SUCCESS
) {
967 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
968 (const BYTE
*)buf
, 78);
969 RegCloseKey(instance_clsid_key
);
971 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
974 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
975 (const BYTE
*)list
->author
,
976 strlen(list
->author
) + 1);
977 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
980 if (list
->friendlyname
) {
981 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
982 (const BYTE
*)list
->friendlyname
,
983 strlen(list
->friendlyname
) + 1);
984 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
988 StringFromGUID2(list
->vendor
, buf
, 39);
989 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
990 (const BYTE
*)buf
, 78);
991 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
995 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
996 (const BYTE
*)list
->version
,
997 strlen(list
->version
) + 1);
998 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1001 res
= RegSetValueExA(clsid_key
, bitsperpixel_valuename
, 0, REG_DWORD
,
1002 (const BYTE
*)&list
->bitsperpixel
, 4);
1003 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1005 res
= RegSetValueExA(clsid_key
, channelcount_valuename
, 0, REG_DWORD
,
1006 (const BYTE
*)&list
->channelcount
, 4);
1007 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1009 res
= RegSetValueExA(clsid_key
, numericrepresentation_valuename
, 0, REG_DWORD
,
1010 (const BYTE
*)&list
->numericrepresentation
, 4);
1011 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1013 res
= RegSetValueExA(clsid_key
, supportstransparency_valuename
, 0, REG_DWORD
,
1014 (const BYTE
*)&list
->supportsalpha
, 4);
1015 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1017 if (list
->channelmasks
) {
1020 WCHAR mask_valuename
[11];
1021 const WCHAR valuename_format
[] = {'%','d',0};
1023 mask_size
= (list
->bitsperpixel
+ 7)/8;
1025 res
= RegCreateKeyExW(clsid_key
, channelmasks_keyname
, 0, NULL
, 0,
1026 KEY_READ
| KEY_WRITE
, NULL
, &masks_key
, NULL
);
1027 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1028 for (i
=0; i
< list
->channelcount
; i
++)
1030 sprintfW(mask_valuename
, valuename_format
, i
);
1031 res
= RegSetValueExW(masks_key
, mask_valuename
, 0, REG_BINARY
,
1032 list
->channelmasks
[i
], mask_size
);
1033 if (res
!= ERROR_SUCCESS
) break;
1035 RegCloseKey(masks_key
);
1036 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1039 error_close_clsid_key
:
1040 RegCloseKey(clsid_key
);
1043 error_close_coclass_key
:
1044 RegCloseKey(instance_key
);
1045 RegCloseKey(formats_key
);
1046 RegCloseKey(coclass_key
);
1048 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1051 /***********************************************************************
1052 * unregister_pixelformats
1054 static HRESULT
unregister_pixelformats(struct regsvr_pixelformat
const *list
)
1056 LONG res
= ERROR_SUCCESS
;
1062 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
1063 KEY_READ
| KEY_WRITE
, &coclass_key
);
1064 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
1066 if (res
== ERROR_SUCCESS
) {
1067 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
1068 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
1069 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
1070 if (res
== ERROR_SUCCESS
)
1072 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
1073 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
1074 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1076 if (res
!= ERROR_SUCCESS
)
1077 RegCloseKey(coclass_key
);
1079 if (res
!= ERROR_SUCCESS
) goto error_return
;
1081 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
1082 StringFromGUID2(list
->clsid
, buf
, 39);
1084 res
= RegDeleteTreeW(coclass_key
, buf
);
1085 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1086 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1088 res
= RegDeleteTreeW(instance_key
, buf
);
1089 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1090 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1093 error_close_coclass_key
:
1094 RegCloseKey(instance_key
);
1095 RegCloseKey(formats_key
);
1096 RegCloseKey(coclass_key
);
1098 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1101 /***********************************************************************
1104 static const BYTE mask_all
[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1106 static const BYTE bmp_magic
[] = {0x42,0x4d};
1108 static GUID
const * const bmp_formats
[] = {
1109 &GUID_WICPixelFormat1bppIndexed
,
1110 &GUID_WICPixelFormat2bppIndexed
,
1111 &GUID_WICPixelFormat4bppIndexed
,
1112 &GUID_WICPixelFormat8bppIndexed
,
1113 &GUID_WICPixelFormat16bppBGR555
,
1114 &GUID_WICPixelFormat16bppBGR565
,
1115 &GUID_WICPixelFormat24bppBGR
,
1116 &GUID_WICPixelFormat32bppBGR
,
1117 &GUID_WICPixelFormat32bppBGRA
,
1121 static struct decoder_pattern
const bmp_patterns
[] = {
1122 {2,0,bmp_magic
,mask_all
,0},
1126 static const BYTE gif87a_magic
[6] = "GIF87a";
1127 static const BYTE gif89a_magic
[6] = "GIF89a";
1129 static GUID
const * const gif_formats
[] = {
1130 &GUID_WICPixelFormat8bppIndexed
,
1134 static struct decoder_pattern
const gif_patterns
[] = {
1135 {6,0,gif87a_magic
,mask_all
,0},
1136 {6,0,gif89a_magic
,mask_all
,0},
1140 static const BYTE ico_magic
[] = {00,00,01,00};
1142 static GUID
const * const ico_formats
[] = {
1143 &GUID_WICPixelFormat32bppBGRA
,
1147 static struct decoder_pattern
const ico_patterns
[] = {
1148 {4,0,ico_magic
,mask_all
,0},
1152 static const BYTE jpeg_magic
[] = {0xff, 0xd8};
1154 static GUID
const * const jpeg_formats
[] = {
1155 &GUID_WICPixelFormat24bppBGR
,
1156 &GUID_WICPixelFormat32bppCMYK
,
1157 &GUID_WICPixelFormat8bppGray
,
1161 static struct decoder_pattern
const jpeg_patterns
[] = {
1162 {2,0,jpeg_magic
,mask_all
,0},
1166 static const BYTE png_magic
[] = {137,80,78,71,13,10,26,10};
1168 static GUID
const * const png_formats
[] = {
1169 &GUID_WICPixelFormatBlackWhite
,
1170 &GUID_WICPixelFormat2bppGray
,
1171 &GUID_WICPixelFormat4bppGray
,
1172 &GUID_WICPixelFormat8bppGray
,
1173 &GUID_WICPixelFormat16bppGray
,
1174 &GUID_WICPixelFormat32bppBGRA
,
1175 &GUID_WICPixelFormat64bppRGBA
,
1176 &GUID_WICPixelFormat1bppIndexed
,
1177 &GUID_WICPixelFormat2bppIndexed
,
1178 &GUID_WICPixelFormat4bppIndexed
,
1179 &GUID_WICPixelFormat8bppIndexed
,
1180 &GUID_WICPixelFormat24bppBGR
,
1181 &GUID_WICPixelFormat48bppRGB
,
1185 static struct decoder_pattern
const png_patterns
[] = {
1186 {8,0,png_magic
,mask_all
,0},
1190 static const BYTE tiff_magic_le
[] = {0x49,0x49,42,0};
1191 static const BYTE tiff_magic_be
[] = {0x4d,0x4d,0,42};
1193 static GUID
const * const tiff_decode_formats
[] = {
1194 &GUID_WICPixelFormatBlackWhite
,
1195 &GUID_WICPixelFormat4bppGray
,
1196 &GUID_WICPixelFormat8bppGray
,
1197 &GUID_WICPixelFormat16bppGray
,
1198 &GUID_WICPixelFormat32bppGrayFloat
,
1199 &GUID_WICPixelFormat1bppIndexed
,
1200 &GUID_WICPixelFormat2bppIndexed
,
1201 &GUID_WICPixelFormat4bppIndexed
,
1202 &GUID_WICPixelFormat8bppIndexed
,
1203 &GUID_WICPixelFormat24bppBGR
,
1204 &GUID_WICPixelFormat32bppBGR
,
1205 &GUID_WICPixelFormat32bppBGRA
,
1206 &GUID_WICPixelFormat32bppPBGRA
,
1207 &GUID_WICPixelFormat48bppRGB
,
1208 &GUID_WICPixelFormat64bppRGBA
,
1209 &GUID_WICPixelFormat64bppPRGBA
,
1210 &GUID_WICPixelFormat32bppCMYK
,
1211 &GUID_WICPixelFormat64bppCMYK
,
1212 &GUID_WICPixelFormat128bppRGBAFloat
,
1216 static struct decoder_pattern
const tiff_patterns
[] = {
1217 {4,0,tiff_magic_le
,mask_all
,0},
1218 {4,0,tiff_magic_be
,mask_all
,0},
1222 static const BYTE tga_footer_magic
[18] = "TRUEVISION-XFILE.";
1224 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};
1225 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};
1227 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};
1228 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};
1230 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};
1231 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};
1233 static GUID
const * const tga_formats
[] = {
1234 &GUID_WICPixelFormat8bppGray
,
1235 &GUID_WICPixelFormat8bppIndexed
,
1236 &GUID_WICPixelFormat16bppGray
,
1237 &GUID_WICPixelFormat16bppBGR555
,
1238 &GUID_WICPixelFormat24bppBGR
,
1239 &GUID_WICPixelFormat32bppBGRA
,
1240 &GUID_WICPixelFormat32bppPBGRA
,
1244 static struct decoder_pattern
const tga_patterns
[] = {
1245 {18,18,tga_footer_magic
,mask_all
,1},
1246 {18,0,tga_indexed_magic
,tga_indexed_mask
,0},
1247 {18,0,tga_truecolor_magic
,tga_truecolor_mask
,0},
1248 {18,0,tga_grayscale_magic
,tga_grayscale_mask
,0},
1252 static struct regsvr_decoder
const decoder_list
[] = {
1253 { &CLSID_WICBmpDecoder
,
1257 &GUID_VendorMicrosoft
,
1258 &GUID_ContainerFormatBmp
,
1264 { &CLSID_WICGifDecoder
,
1268 &GUID_VendorMicrosoft
,
1269 &GUID_ContainerFormatGif
,
1275 { &CLSID_WICIcoDecoder
,
1279 &GUID_VendorMicrosoft
,
1280 &GUID_ContainerFormatIco
,
1281 "image/vnd.microsoft.icon",
1286 { &CLSID_WICJpegDecoder
,
1290 &GUID_VendorMicrosoft
,
1291 &GUID_ContainerFormatJpeg
,
1297 { &CLSID_WICPngDecoder
,
1301 &GUID_VendorMicrosoft
,
1302 &GUID_ContainerFormatPng
,
1308 { &CLSID_WICTiffDecoder
,
1312 &GUID_VendorMicrosoft
,
1313 &GUID_ContainerFormatTiff
,
1316 tiff_decode_formats
,
1319 { &CLSID_WineTgaDecoder
,
1324 &GUID_WineContainerFormatTga
,
1330 { NULL
} /* list terminator */
1333 static GUID
const * const bmp_encode_formats
[] = {
1334 &GUID_WICPixelFormat16bppBGR555
,
1335 &GUID_WICPixelFormat16bppBGR565
,
1336 &GUID_WICPixelFormat24bppBGR
,
1337 &GUID_WICPixelFormat32bppBGR
,
1338 &GUID_WICPixelFormatBlackWhite
,
1339 &GUID_WICPixelFormat1bppIndexed
,
1340 &GUID_WICPixelFormat2bppIndexed
,
1341 &GUID_WICPixelFormat4bppIndexed
,
1342 &GUID_WICPixelFormat8bppIndexed
,
1346 static GUID
const * const png_encode_formats
[] = {
1347 &GUID_WICPixelFormat24bppBGR
,
1348 &GUID_WICPixelFormatBlackWhite
,
1349 &GUID_WICPixelFormat2bppGray
,
1350 &GUID_WICPixelFormat4bppGray
,
1351 &GUID_WICPixelFormat8bppGray
,
1352 &GUID_WICPixelFormat16bppGray
,
1353 &GUID_WICPixelFormat32bppBGR
,
1354 &GUID_WICPixelFormat32bppBGRA
,
1355 &GUID_WICPixelFormat48bppRGB
,
1356 &GUID_WICPixelFormat64bppRGBA
,
1357 &GUID_WICPixelFormat1bppIndexed
,
1358 &GUID_WICPixelFormat2bppIndexed
,
1359 &GUID_WICPixelFormat4bppIndexed
,
1360 &GUID_WICPixelFormat8bppIndexed
,
1364 static GUID
const * const tiff_encode_formats
[] = {
1365 &GUID_WICPixelFormatBlackWhite
,
1366 &GUID_WICPixelFormat4bppGray
,
1367 &GUID_WICPixelFormat8bppGray
,
1368 &GUID_WICPixelFormat1bppIndexed
,
1369 &GUID_WICPixelFormat2bppIndexed
,
1370 &GUID_WICPixelFormat4bppIndexed
,
1371 &GUID_WICPixelFormat8bppIndexed
,
1372 &GUID_WICPixelFormat24bppBGR
,
1373 &GUID_WICPixelFormat32bppBGRA
,
1374 &GUID_WICPixelFormat32bppPBGRA
,
1375 &GUID_WICPixelFormat48bppRGB
,
1376 &GUID_WICPixelFormat64bppRGBA
,
1377 &GUID_WICPixelFormat64bppPRGBA
,
1381 static GUID
const * const icns_encode_formats
[] = {
1382 &GUID_WICPixelFormat32bppBGRA
,
1386 static struct regsvr_encoder
const encoder_list
[] = {
1387 { &CLSID_WICBmpEncoder
,
1391 &GUID_VendorMicrosoft
,
1392 &GUID_ContainerFormatBmp
,
1397 { &CLSID_WICGifEncoder
,
1401 &GUID_VendorMicrosoft
,
1402 &GUID_ContainerFormatGif
,
1407 { &CLSID_WICJpegEncoder
,
1411 &GUID_VendorMicrosoft
,
1412 &GUID_ContainerFormatJpeg
,
1417 { &CLSID_WICPngEncoder
,
1421 &GUID_VendorMicrosoft
,
1422 &GUID_ContainerFormatPng
,
1427 { &CLSID_WICTiffEncoder
,
1431 &GUID_VendorMicrosoft
,
1432 &GUID_ContainerFormatTiff
,
1437 { &CLSID_WICIcnsEncoder
,
1442 NULL
, /* no container format guid */
1447 { NULL
} /* list terminator */
1450 static GUID
const * const converter_formats
[] = {
1451 &GUID_WICPixelFormat1bppIndexed
,
1452 &GUID_WICPixelFormat2bppIndexed
,
1453 &GUID_WICPixelFormat4bppIndexed
,
1454 &GUID_WICPixelFormat8bppIndexed
,
1455 &GUID_WICPixelFormatBlackWhite
,
1456 &GUID_WICPixelFormat2bppGray
,
1457 &GUID_WICPixelFormat4bppGray
,
1458 &GUID_WICPixelFormat8bppGray
,
1459 &GUID_WICPixelFormat16bppGray
,
1460 &GUID_WICPixelFormat16bppBGR555
,
1461 &GUID_WICPixelFormat16bppBGR565
,
1462 &GUID_WICPixelFormat16bppBGRA5551
,
1463 &GUID_WICPixelFormat24bppBGR
,
1464 &GUID_WICPixelFormat24bppRGB
,
1465 &GUID_WICPixelFormat32bppBGR
,
1466 &GUID_WICPixelFormat32bppRGB
,
1467 &GUID_WICPixelFormat32bppBGRA
,
1468 &GUID_WICPixelFormat32bppRGBA
,
1469 &GUID_WICPixelFormat32bppPBGRA
,
1470 &GUID_WICPixelFormat32bppPRGBA
,
1471 &GUID_WICPixelFormat32bppGrayFloat
,
1472 &GUID_WICPixelFormat48bppRGB
,
1473 &GUID_WICPixelFormat64bppRGBA
,
1474 &GUID_WICPixelFormat32bppCMYK
,
1478 static struct regsvr_converter
const converter_list
[] = {
1479 { &CLSID_WICDefaultFormatConverter
,
1481 "Default Pixel Format Converter",
1483 &GUID_VendorMicrosoft
,
1486 { NULL
} /* list terminator */
1489 static const BYTE no_magic
[1] = { 0 };
1490 static const BYTE no_mask
[1] = { 0 };
1492 static const struct metadata_pattern ifd_metadata_pattern
[] = {
1493 { 0, 1, no_magic
, no_mask
, 0 },
1497 static const struct reader_containers ifd_containers
[] = {
1499 &GUID_ContainerFormatTiff
,
1500 ifd_metadata_pattern
1502 { NULL
} /* list terminator */
1505 static const BYTE tEXt
[] = "tEXt";
1507 static const struct metadata_pattern pngtext_metadata_pattern
[] = {
1508 { 4, 4, tEXt
, mask_all
, 4 },
1512 static const struct reader_containers pngtext_containers
[] = {
1514 &GUID_ContainerFormatPng
,
1515 pngtext_metadata_pattern
1517 { NULL
} /* list terminator */
1520 static const BYTE gAMA
[] = "gAMA";
1522 static const struct metadata_pattern pnggama_metadata_pattern
[] = {
1523 { 4, 4, gAMA
, mask_all
, 4 },
1527 static const struct reader_containers pnggama_containers
[] = {
1529 &GUID_ContainerFormatPng
,
1530 pnggama_metadata_pattern
1532 { NULL
} /* list terminator */
1535 static const BYTE cHRM
[] = "cHRM";
1537 static const struct metadata_pattern pngchrm_metadata_pattern
[] = {
1538 { 4, 4, cHRM
, mask_all
, 4 },
1542 static const struct reader_containers pngchrm_containers
[] = {
1544 &GUID_ContainerFormatPng
,
1545 pngchrm_metadata_pattern
1547 { NULL
} /* list terminator */
1550 static const struct metadata_pattern lsd_metadata_patterns
[] = {
1551 { 0, 6, gif87a_magic
, mask_all
, 0 },
1552 { 0, 6, gif89a_magic
, mask_all
, 0 },
1556 static const struct reader_containers lsd_containers
[] = {
1558 &GUID_ContainerFormatGif
,
1559 lsd_metadata_patterns
1561 { NULL
} /* list terminator */
1564 static const BYTE imd_magic
[] = { 0x2c };
1566 static const struct metadata_pattern imd_metadata_pattern
[] = {
1567 { 0, 1, imd_magic
, mask_all
, 1 },
1571 static const struct reader_containers imd_containers
[] = {
1573 &GUID_ContainerFormatGif
,
1574 imd_metadata_pattern
1576 { NULL
} /* list terminator */
1579 static const BYTE gce_magic
[] = { 0x21, 0xf9, 0x04 };
1581 static const struct metadata_pattern gce_metadata_pattern
[] = {
1582 { 0, 3, gce_magic
, mask_all
, 3 },
1586 static const struct reader_containers gce_containers
[] = {
1588 &GUID_ContainerFormatGif
,
1589 gce_metadata_pattern
1591 { NULL
} /* list terminator */
1594 static const BYTE ape_magic
[] = { 0x21, 0xff, 0x0b };
1596 static const struct metadata_pattern ape_metadata_pattern
[] = {
1597 { 0, 3, ape_magic
, mask_all
, 0 },
1601 static const struct reader_containers ape_containers
[] = {
1603 &GUID_ContainerFormatGif
,
1604 ape_metadata_pattern
1606 { NULL
} /* list terminator */
1609 static const BYTE gif_comment_magic
[] = { 0x21, 0xfe };
1611 static const struct metadata_pattern gif_comment_metadata_pattern
[] = {
1612 { 0, 2, gif_comment_magic
, mask_all
, 0 },
1616 static const struct reader_containers gif_comment_containers
[] = {
1618 &GUID_ContainerFormatGif
,
1619 gif_comment_metadata_pattern
1621 { NULL
} /* list terminator */
1624 static struct regsvr_metadatareader
const metadatareader_list
[] = {
1625 { &CLSID_WICUnknownMetadataReader
,
1627 "Unknown Metadata Reader",
1630 &GUID_VendorMicrosoft
,
1631 &GUID_MetadataFormatUnknown
,
1635 { &CLSID_WICIfdMetadataReader
,
1640 &GUID_VendorMicrosoft
,
1641 &GUID_MetadataFormatIfd
,
1645 { &CLSID_WICPngChrmMetadataReader
,
1647 "Chunk cHRM Reader",
1650 &GUID_VendorMicrosoft
,
1651 &GUID_MetadataFormatChunkcHRM
,
1655 { &CLSID_WICPngGamaMetadataReader
,
1657 "Chunk gAMA Reader",
1660 &GUID_VendorMicrosoft
,
1661 &GUID_MetadataFormatChunkgAMA
,
1665 { &CLSID_WICPngTextMetadataReader
,
1667 "Chunk tEXt Reader",
1670 &GUID_VendorMicrosoft
,
1671 &GUID_MetadataFormatChunktEXt
,
1675 { &CLSID_WICLSDMetadataReader
,
1677 "Logical Screen Descriptor Reader",
1680 &GUID_VendorMicrosoft
,
1681 &GUID_MetadataFormatLSD
,
1685 { &CLSID_WICIMDMetadataReader
,
1687 "Image Descriptor Reader",
1690 &GUID_VendorMicrosoft
,
1691 &GUID_MetadataFormatIMD
,
1695 { &CLSID_WICGCEMetadataReader
,
1697 "Graphic Control Extension Reader",
1700 &GUID_VendorMicrosoft
,
1701 &GUID_MetadataFormatGCE
,
1705 { &CLSID_WICAPEMetadataReader
,
1707 "Application Extension Reader",
1710 &GUID_VendorMicrosoft
,
1711 &GUID_MetadataFormatAPE
,
1715 { &CLSID_WICGifCommentMetadataReader
,
1717 "Comment Extension Reader",
1720 &GUID_VendorMicrosoft
,
1721 &GUID_MetadataFormatGifComment
,
1723 gif_comment_containers
1725 { NULL
} /* list terminator */
1728 static BYTE
const channel_mask_1bit
[] = { 0x01 };
1729 static BYTE
const channel_mask_2bit
[] = { 0x03 };
1730 static BYTE
const channel_mask_4bit
[] = { 0x0f };
1732 static BYTE
const channel_mask_8bit
[] = { 0xff, 0x00, 0x00, 0x00 };
1733 static BYTE
const channel_mask_8bit2
[] = { 0x00, 0xff, 0x00, 0x00 };
1734 static BYTE
const channel_mask_8bit3
[] = { 0x00, 0x00, 0xff, 0x00 };
1735 static BYTE
const channel_mask_8bit4
[] = { 0x00, 0x00, 0x00, 0xff };
1737 static BYTE
const channel_mask_16bit
[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1738 static BYTE
const channel_mask_16bit2
[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1739 static BYTE
const channel_mask_16bit3
[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
1740 static BYTE
const channel_mask_16bit4
[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
1742 static BYTE
const channel_mask_32bit
[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1744 static BYTE
const channel_mask_128bit1
[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1745 static BYTE
const channel_mask_128bit2
[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1746 static BYTE
const channel_mask_128bit3
[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 };
1747 static BYTE
const channel_mask_128bit4
[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff };
1749 static BYTE
const channel_mask_5bit
[] = { 0x1f, 0x00 };
1750 static BYTE
const channel_mask_5bit2
[] = { 0xe0, 0x03 };
1751 static BYTE
const channel_mask_5bit3
[] = { 0x00, 0x7c };
1752 static BYTE
const channel_mask_5bit4
[] = { 0x00, 0x80 };
1754 static BYTE
const channel_mask_BGR565_2
[] = { 0xe0, 0x07 };
1755 static BYTE
const channel_mask_BGR565_3
[] = { 0x00, 0xf8 };
1757 static BYTE
const * const channel_masks_1bit
[] = { channel_mask_1bit
};
1758 static BYTE
const * const channel_masks_2bit
[] = { channel_mask_2bit
};
1759 static BYTE
const * const channel_masks_4bit
[] = { channel_mask_4bit
};
1760 static BYTE
const * const channel_masks_8bit
[] = { channel_mask_8bit
,
1761 channel_mask_8bit2
, channel_mask_8bit3
, channel_mask_8bit4
};
1762 static BYTE
const * const channel_masks_16bit
[] = { channel_mask_16bit
,
1763 channel_mask_16bit2
, channel_mask_16bit3
, channel_mask_16bit4
};
1765 static BYTE
const * const channel_masks_32bit
[] = { channel_mask_32bit
};
1766 static BYTE
const * const channel_masks_128bit
[] = { channel_mask_128bit1
, channel_mask_128bit2
, channel_mask_128bit3
, channel_mask_128bit4
};
1768 static BYTE
const * const channel_masks_BGRA5551
[] = { channel_mask_5bit
,
1769 channel_mask_5bit2
, channel_mask_5bit3
, channel_mask_5bit4
};
1771 static BYTE
const * const channel_masks_BGR565
[] = { channel_mask_5bit
,
1772 channel_mask_BGR565_2
, channel_mask_BGR565_3
};
1774 static struct regsvr_pixelformat
const pixelformat_list
[] = {
1775 { &GUID_WICPixelFormat1bppIndexed
,
1778 NULL
, /* no version */
1779 &GUID_VendorMicrosoft
,
1780 1, /* bitsperpixel */
1781 1, /* channel count */
1783 WICPixelFormatNumericRepresentationIndexed
,
1786 { &GUID_WICPixelFormat2bppIndexed
,
1789 NULL
, /* no version */
1790 &GUID_VendorMicrosoft
,
1791 2, /* bitsperpixel */
1792 1, /* channel count */
1794 WICPixelFormatNumericRepresentationIndexed
,
1797 { &GUID_WICPixelFormat4bppIndexed
,
1800 NULL
, /* no version */
1801 &GUID_VendorMicrosoft
,
1802 4, /* bitsperpixel */
1803 1, /* channel count */
1805 WICPixelFormatNumericRepresentationIndexed
,
1808 { &GUID_WICPixelFormat8bppIndexed
,
1811 NULL
, /* no version */
1812 &GUID_VendorMicrosoft
,
1813 8, /* bitsperpixel */
1814 1, /* channel count */
1816 WICPixelFormatNumericRepresentationIndexed
,
1819 { &GUID_WICPixelFormatBlackWhite
,
1822 NULL
, /* no version */
1823 &GUID_VendorMicrosoft
,
1824 1, /* bitsperpixel */
1825 1, /* channel count */
1827 WICPixelFormatNumericRepresentationUnsignedInteger
,
1830 { &GUID_WICPixelFormat2bppGray
,
1833 NULL
, /* no version */
1834 &GUID_VendorMicrosoft
,
1835 2, /* bitsperpixel */
1836 1, /* channel count */
1838 WICPixelFormatNumericRepresentationUnsignedInteger
,
1841 { &GUID_WICPixelFormat4bppGray
,
1844 NULL
, /* no version */
1845 &GUID_VendorMicrosoft
,
1846 4, /* bitsperpixel */
1847 1, /* channel count */
1849 WICPixelFormatNumericRepresentationUnsignedInteger
,
1852 { &GUID_WICPixelFormat8bppGray
,
1855 NULL
, /* no version */
1856 &GUID_VendorMicrosoft
,
1857 8, /* bitsperpixel */
1858 1, /* channel count */
1860 WICPixelFormatNumericRepresentationUnsignedInteger
,
1863 { &GUID_WICPixelFormat16bppGray
,
1866 NULL
, /* no version */
1867 &GUID_VendorMicrosoft
,
1868 16, /* bitsperpixel */
1869 1, /* channel count */
1870 channel_masks_16bit
,
1871 WICPixelFormatNumericRepresentationUnsignedInteger
,
1874 { &GUID_WICPixelFormat16bppBGR555
,
1877 NULL
, /* no version */
1878 &GUID_VendorMicrosoft
,
1879 16, /* bitsperpixel */
1880 3, /* channel count */
1881 channel_masks_BGRA5551
,
1882 WICPixelFormatNumericRepresentationUnsignedInteger
,
1885 { &GUID_WICPixelFormat16bppBGR565
,
1888 NULL
, /* no version */
1889 &GUID_VendorMicrosoft
,
1890 16, /* bitsperpixel */
1891 3, /* channel count */
1892 channel_masks_BGR565
,
1893 WICPixelFormatNumericRepresentationUnsignedInteger
,
1896 { &GUID_WICPixelFormat16bppBGRA5551
,
1899 NULL
, /* no version */
1900 &GUID_VendorMicrosoft
,
1901 16, /* bitsperpixel */
1902 4, /* channel count */
1903 channel_masks_BGRA5551
,
1904 WICPixelFormatNumericRepresentationUnsignedInteger
,
1907 { &GUID_WICPixelFormat24bppBGR
,
1910 NULL
, /* no version */
1911 &GUID_VendorMicrosoft
,
1912 24, /* bitsperpixel */
1913 3, /* channel count */
1915 WICPixelFormatNumericRepresentationUnsignedInteger
,
1918 { &GUID_WICPixelFormat24bppRGB
,
1921 NULL
, /* no version */
1922 &GUID_VendorMicrosoft
,
1923 24, /* bitsperpixel */
1924 3, /* channel count */
1926 WICPixelFormatNumericRepresentationUnsignedInteger
,
1929 { &GUID_WICPixelFormat32bppBGR
,
1932 NULL
, /* no version */
1933 &GUID_VendorMicrosoft
,
1934 32, /* bitsperpixel */
1935 3, /* channel count */
1937 WICPixelFormatNumericRepresentationUnsignedInteger
,
1940 { &GUID_WICPixelFormat32bppRGB
,
1943 NULL
, /* no version */
1944 &GUID_VendorMicrosoft
,
1945 32, /* bitsperpixel */
1946 3, /* channel count */
1948 WICPixelFormatNumericRepresentationUnsignedInteger
,
1951 { &GUID_WICPixelFormat32bppBGRA
,
1954 NULL
, /* no version */
1955 &GUID_VendorMicrosoft
,
1956 32, /* bitsperpixel */
1957 4, /* channel count */
1959 WICPixelFormatNumericRepresentationUnsignedInteger
,
1962 { &GUID_WICPixelFormat32bppRGBA
,
1965 NULL
, /* no version */
1966 &GUID_VendorMicrosoft
,
1967 32, /* bitsperpixel */
1968 4, /* channel count */
1970 WICPixelFormatNumericRepresentationUnsignedInteger
,
1973 { &GUID_WICPixelFormat32bppPBGRA
,
1976 NULL
, /* no version */
1977 &GUID_VendorMicrosoft
,
1978 32, /* bitsperpixel */
1979 4, /* channel count */
1981 WICPixelFormatNumericRepresentationUnsignedInteger
,
1984 { &GUID_WICPixelFormat32bppPRGBA
,
1987 NULL
, /* no version */
1988 &GUID_VendorMicrosoft
,
1989 32, /* bitsperpixel */
1990 4, /* channel count */
1992 WICPixelFormatNumericRepresentationUnsignedInteger
,
1995 { &GUID_WICPixelFormat32bppGrayFloat
,
1998 NULL
, /* no version */
1999 &GUID_VendorMicrosoft
,
2000 32, /* bitsperpixel */
2001 1, /* channel count */
2002 channel_masks_32bit
,
2003 WICPixelFormatNumericRepresentationFloat
,
2006 { &GUID_WICPixelFormat48bppRGB
,
2009 NULL
, /* no version */
2010 &GUID_VendorMicrosoft
,
2011 48, /* bitsperpixel */
2012 3, /* channel count */
2013 channel_masks_16bit
,
2014 WICPixelFormatNumericRepresentationUnsignedInteger
,
2017 { &GUID_WICPixelFormat64bppRGBA
,
2020 NULL
, /* no version */
2021 &GUID_VendorMicrosoft
,
2022 64, /* bitsperpixel */
2023 4, /* channel count */
2024 channel_masks_16bit
,
2025 WICPixelFormatNumericRepresentationUnsignedInteger
,
2028 { &GUID_WICPixelFormat64bppPRGBA
,
2031 NULL
, /* no version */
2032 &GUID_VendorMicrosoft
,
2033 64, /* bitsperpixel */
2034 4, /* channel count */
2035 channel_masks_16bit
,
2036 WICPixelFormatNumericRepresentationUnsignedInteger
,
2039 { &GUID_WICPixelFormat32bppCMYK
,
2042 NULL
, /* no version */
2043 &GUID_VendorMicrosoft
,
2044 32, /* bitsperpixel */
2045 4, /* channel count */
2047 WICPixelFormatNumericRepresentationUnsignedInteger
,
2050 { &GUID_WICPixelFormat64bppCMYK
,
2053 NULL
, /* no version */
2054 &GUID_VendorMicrosoft
,
2055 64, /* bitsperpixel */
2056 4, /* channel count */
2057 channel_masks_16bit
,
2058 WICPixelFormatNumericRepresentationUnsignedInteger
,
2061 { &GUID_WICPixelFormat128bppRGBAFloat
,
2064 NULL
, /* no version */
2065 &GUID_VendorMicrosoft
,
2066 128, /* bitsperpixel */
2067 4, /* channel count */
2068 channel_masks_128bit
,
2069 WICPixelFormatNumericRepresentationFloat
,
2072 { NULL
} /* list terminator */
2075 struct regsvr_category
2077 const CLSID
*clsid
; /* NULL for end of list */
2080 static const struct regsvr_category category_list
[] = {
2081 { &CATID_WICBitmapDecoders
},
2082 { &CATID_WICBitmapEncoders
},
2083 { &CATID_WICFormatConverters
},
2084 { &CATID_WICMetadataReader
},
2085 { &CATID_WICPixelFormats
},
2089 static HRESULT
register_categories(const struct regsvr_category
*list
)
2093 HKEY coclass_key
, categories_key
, instance_key
;
2095 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
2096 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
2097 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
2099 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2100 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
2101 KEY_READ
| KEY_WRITE
, NULL
, &categories_key
, NULL
);
2102 if (res
!= ERROR_SUCCESS
)
2104 RegCloseKey(coclass_key
);
2105 return HRESULT_FROM_WIN32(res
);
2108 res
= RegCreateKeyExW(categories_key
, instance_keyname
, 0, NULL
, 0,
2109 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
2111 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
2113 HKEY instance_clsid_key
;
2115 StringFromGUID2(list
->clsid
, buf
, 39);
2116 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
2117 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
2118 if (res
== ERROR_SUCCESS
)
2120 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
2121 (const BYTE
*)buf
, 78);
2122 RegCloseKey(instance_clsid_key
);
2126 RegCloseKey(instance_key
);
2127 RegCloseKey(categories_key
);
2128 RegCloseKey(coclass_key
);
2130 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
2133 static HRESULT
unregister_categories(const struct regsvr_category
*list
)
2137 HKEY coclass_key
, categories_key
, instance_key
;
2139 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
2140 KEY_READ
| KEY_WRITE
, &coclass_key
);
2141 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
2143 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2144 res
= RegOpenKeyExW(coclass_key
, buf
, 0,
2145 KEY_READ
| KEY_WRITE
, &categories_key
);
2146 if (res
!= ERROR_SUCCESS
)
2148 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
2149 RegCloseKey(coclass_key
);
2150 return HRESULT_FROM_WIN32(res
);
2153 res
= RegOpenKeyExW(categories_key
, instance_keyname
, 0,
2154 KEY_READ
| KEY_WRITE
, &instance_key
);
2156 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
2158 StringFromGUID2(list
->clsid
, buf
, 39);
2159 res
= RegDeleteTreeW(instance_key
, buf
);
2162 RegCloseKey(instance_key
);
2163 RegCloseKey(categories_key
);
2165 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2166 res
= RegDeleteTreeW(coclass_key
, buf
);
2168 RegCloseKey(coclass_key
);
2170 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
2173 extern HRESULT WINAPI
WIC_DllRegisterServer(void) DECLSPEC_HIDDEN
;
2174 extern HRESULT WINAPI
WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
2176 HRESULT WINAPI
DllRegisterServer(void)
2182 hr
= WIC_DllRegisterServer();
2184 hr
= register_categories(category_list
);
2186 hr
= register_decoders(decoder_list
);
2188 hr
= register_encoders(encoder_list
);
2190 hr
= register_converters(converter_list
);
2192 hr
= register_metadatareaders(metadatareader_list
);
2194 hr
= register_pixelformats(pixelformat_list
);
2198 HRESULT WINAPI
DllUnregisterServer(void)
2204 hr
= WIC_DllUnregisterServer();
2206 hr
= unregister_categories(category_list
);
2208 hr
= unregister_decoders(decoder_list
);
2210 hr
= unregister_encoders(encoder_list
);
2212 hr
= unregister_converters(converter_list
);
2214 hr
= unregister_metadatareaders(metadatareader_list
);
2216 hr
= unregister_pixelformats(pixelformat_list
);