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"
21 /***********************************************************************
22 * interface for self-registering
24 struct decoder_pattern
26 DWORD length
; /* 0 for end of list */
35 CLSID
const *clsid
; /* NULL for end of list */
40 GUID
const *container_format
;
43 GUID
const * const *formats
;
44 const struct decoder_pattern
*patterns
;
47 static HRESULT
register_decoders(struct regsvr_decoder
const *list
);
48 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
);
52 CLSID
const *clsid
; /* NULL for end of list */
57 GUID
const *container_format
;
60 GUID
const * const *formats
;
63 static HRESULT
register_encoders(struct regsvr_encoder
const *list
);
64 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
);
66 struct regsvr_converter
68 CLSID
const *clsid
; /* NULL for end of list */
73 GUID
const * const *formats
;
76 static HRESULT
register_converters(struct regsvr_converter
const *list
);
77 static HRESULT
unregister_converters(struct regsvr_converter
const *list
);
79 struct metadata_pattern
88 struct reader_containers
91 const struct metadata_pattern
*patterns
;
94 struct regsvr_metadatareader
96 CLSID
const *clsid
; /* NULL for end of list */
102 GUID
const *metadata_format
;
103 DWORD requires_fullstream
;
104 DWORD supports_padding
;
105 DWORD requires_fixedsize
;
106 const struct reader_containers
*containers
;
109 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
);
110 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
);
112 struct regsvr_pixelformat
114 CLSID
const *clsid
; /* NULL for end of list */
121 BYTE
const * const *channelmasks
;
122 WICPixelFormatNumericRepresentation numericrepresentation
;
126 static HRESULT
register_pixelformats(struct regsvr_pixelformat
const *list
);
127 static HRESULT
unregister_pixelformats(struct regsvr_pixelformat
const *list
);
129 /***********************************************************************
130 * static string constants
132 static const WCHAR clsid_keyname
[] = {
133 'C', 'L', 'S', 'I', 'D', 0 };
134 static const WCHAR curver_keyname
[] = {
135 'C', 'u', 'r', 'V', 'e', 'r', 0 };
136 static const WCHAR ips_keyname
[] = {
137 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
139 static const WCHAR ips32_keyname
[] = {
140 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
142 static const WCHAR progid_keyname
[] = {
143 'P', 'r', 'o', 'g', 'I', 'D', 0 };
144 static const WCHAR viprogid_keyname
[] = {
145 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
146 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
148 static const char tmodel_valuename
[] = "ThreadingModel";
149 static const char author_valuename
[] = "Author";
150 static const char friendlyname_valuename
[] = "FriendlyName";
151 static const WCHAR vendor_valuename
[] = {'V','e','n','d','o','r',0};
152 static const WCHAR containerformat_valuename
[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
153 static const char version_valuename
[] = "Version";
154 static const char mimetypes_valuename
[] = "MimeTypes";
155 static const char extensions_valuename
[] = "FileExtensions";
156 static const WCHAR formats_keyname
[] = {'F','o','r','m','a','t','s',0};
157 static const WCHAR patterns_keyname
[] = {'P','a','t','t','e','r','n','s',0};
158 static const WCHAR instance_keyname
[] = {'I','n','s','t','a','n','c','e',0};
159 static const WCHAR clsid_valuename
[] = {'C','L','S','I','D',0};
160 static const char length_valuename
[] = "Length";
161 static const char position_valuename
[] = "Position";
162 static const char pattern_valuename
[] = "Pattern";
163 static const char mask_valuename
[] = "Mask";
164 static const char endofstream_valuename
[] = "EndOfStream";
165 static const WCHAR pixelformats_keyname
[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
166 static const WCHAR metadataformat_valuename
[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
167 static const char specversion_valuename
[] = "SpecVersion";
168 static const char requiresfullstream_valuename
[] = "RequiresFullStream";
169 static const char supportspadding_valuename
[] = "SupportsPadding";
170 static const char requiresfixedsize_valuename
[] = "FixedSize";
171 static const WCHAR containers_keyname
[] = {'C','o','n','t','a','i','n','e','r','s',0};
172 static const char dataoffset_valuename
[] = "DataOffset";
173 static const char bitsperpixel_valuename
[] = "BitLength";
174 static const char channelcount_valuename
[] = "ChannelCount";
175 static const char numericrepresentation_valuename
[] = "NumericRepresentation";
176 static const char supportstransparency_valuename
[] = "SupportsTransparency";
177 static const WCHAR channelmasks_keyname
[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
179 /***********************************************************************
182 static HRESULT
register_decoders(struct regsvr_decoder
const *list
)
184 LONG res
= ERROR_SUCCESS
;
190 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
191 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
192 if (res
== ERROR_SUCCESS
) {
193 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
194 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
195 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
196 if (res
== ERROR_SUCCESS
)
198 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
199 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
200 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
202 if (res
!= ERROR_SUCCESS
)
203 RegCloseKey(coclass_key
);
205 if (res
!= ERROR_SUCCESS
) goto error_return
;
207 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
209 HKEY instance_clsid_key
;
211 StringFromGUID2(list
->clsid
, buf
, 39);
212 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
213 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
214 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
216 StringFromGUID2(list
->clsid
, buf
, 39);
217 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
218 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
219 if (res
== ERROR_SUCCESS
) {
220 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
221 (CONST BYTE
*)(buf
), 78);
222 RegCloseKey(instance_clsid_key
);
224 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
227 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
228 (CONST BYTE
*)(list
->author
),
229 strlen(list
->author
) + 1);
230 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
233 if (list
->friendlyname
) {
234 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
235 (CONST BYTE
*)(list
->friendlyname
),
236 strlen(list
->friendlyname
) + 1);
237 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
241 StringFromGUID2(list
->vendor
, buf
, 39);
242 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
243 (CONST BYTE
*)(buf
), 78);
244 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
247 if (list
->container_format
) {
248 StringFromGUID2(list
->container_format
, buf
, 39);
249 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
250 (CONST BYTE
*)(buf
), 78);
251 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
255 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
256 (CONST BYTE
*)(list
->version
),
257 strlen(list
->version
) + 1);
258 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
261 if (list
->mimetypes
) {
262 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
263 (CONST BYTE
*)(list
->mimetypes
),
264 strlen(list
->mimetypes
) + 1);
265 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
268 if (list
->extensions
) {
269 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
270 (CONST BYTE
*)(list
->extensions
),
271 strlen(list
->extensions
) + 1);
272 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
277 GUID
const * const *format
;
279 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
280 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
281 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
282 for (format
=list
->formats
; *format
; ++format
)
285 StringFromGUID2(*format
, buf
, 39);
286 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
287 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
288 if (res
!= ERROR_SUCCESS
) break;
289 RegCloseKey(format_key
);
291 RegCloseKey(formats_key
);
292 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
295 if (list
->patterns
) {
299 res
= RegCreateKeyExW(clsid_key
, patterns_keyname
, 0, NULL
, 0,
300 KEY_READ
| KEY_WRITE
, NULL
, &patterns_key
, NULL
);
301 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
302 for (i
=0; list
->patterns
[i
].length
; i
++)
305 static const WCHAR int_format
[] = {'%','i',0};
306 snprintfW(buf
, 39, int_format
, i
);
307 res
= RegCreateKeyExW(patterns_key
, buf
, 0, NULL
, 0,
308 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
309 if (res
!= ERROR_SUCCESS
) break;
310 res
= RegSetValueExA(pattern_key
, length_valuename
, 0, REG_DWORD
,
311 (CONST BYTE
*)(&list
->patterns
[i
].length
), 4);
312 if (res
== ERROR_SUCCESS
)
313 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
314 (CONST BYTE
*)(&list
->patterns
[i
].position
), 4);
315 if (res
== ERROR_SUCCESS
)
316 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
317 list
->patterns
[i
].pattern
,
318 list
->patterns
[i
].length
);
319 if (res
== ERROR_SUCCESS
)
320 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
321 list
->patterns
[i
].mask
,
322 list
->patterns
[i
].length
);
323 if (res
== ERROR_SUCCESS
)
324 res
= RegSetValueExA(pattern_key
, endofstream_valuename
, 0, REG_DWORD
,
325 (CONST BYTE
*)&(list
->patterns
[i
].endofstream
), 4);
326 RegCloseKey(pattern_key
);
328 RegCloseKey(patterns_key
);
329 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
332 error_close_clsid_key
:
333 RegCloseKey(clsid_key
);
336 error_close_coclass_key
:
337 RegCloseKey(instance_key
);
338 RegCloseKey(decoders_key
);
339 RegCloseKey(coclass_key
);
341 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
344 /***********************************************************************
345 * unregister_decoders
347 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
)
349 LONG res
= ERROR_SUCCESS
;
355 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
356 KEY_READ
| KEY_WRITE
, &coclass_key
);
357 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
359 if (res
== ERROR_SUCCESS
) {
360 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
361 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
362 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
363 if (res
== ERROR_SUCCESS
)
365 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
366 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
367 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
369 if (res
!= ERROR_SUCCESS
)
370 RegCloseKey(coclass_key
);
372 if (res
!= ERROR_SUCCESS
) goto error_return
;
374 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
375 StringFromGUID2(list
->clsid
, buf
, 39);
377 res
= RegDeleteTreeW(coclass_key
, buf
);
378 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
379 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
381 res
= RegDeleteTreeW(instance_key
, buf
);
382 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
383 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
386 error_close_coclass_key
:
387 RegCloseKey(instance_key
);
388 RegCloseKey(decoders_key
);
389 RegCloseKey(coclass_key
);
391 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
394 /***********************************************************************
397 static HRESULT
register_encoders(struct regsvr_encoder
const *list
)
399 LONG res
= ERROR_SUCCESS
;
405 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
406 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
407 if (res
== ERROR_SUCCESS
) {
408 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
409 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
410 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
411 if (res
== ERROR_SUCCESS
)
413 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
414 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
415 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
417 if (res
!= ERROR_SUCCESS
)
418 RegCloseKey(coclass_key
);
420 if (res
!= ERROR_SUCCESS
) goto error_return
;
422 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
424 HKEY instance_clsid_key
;
426 StringFromGUID2(list
->clsid
, buf
, 39);
427 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
428 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
429 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
431 StringFromGUID2(list
->clsid
, buf
, 39);
432 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
433 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
434 if (res
== ERROR_SUCCESS
) {
435 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
436 (CONST BYTE
*)(buf
), 78);
437 RegCloseKey(instance_clsid_key
);
439 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
442 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
443 (CONST BYTE
*)(list
->author
),
444 strlen(list
->author
) + 1);
445 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
448 if (list
->friendlyname
) {
449 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
450 (CONST BYTE
*)(list
->friendlyname
),
451 strlen(list
->friendlyname
) + 1);
452 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
456 StringFromGUID2(list
->vendor
, buf
, 39);
457 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
458 (CONST BYTE
*)(buf
), 78);
459 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
462 if (list
->container_format
) {
463 StringFromGUID2(list
->container_format
, buf
, 39);
464 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
465 (CONST BYTE
*)(buf
), 78);
466 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
470 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
471 (CONST BYTE
*)(list
->version
),
472 strlen(list
->version
) + 1);
473 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
476 if (list
->mimetypes
) {
477 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
478 (CONST BYTE
*)(list
->mimetypes
),
479 strlen(list
->mimetypes
) + 1);
480 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
483 if (list
->extensions
) {
484 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
485 (CONST BYTE
*)(list
->extensions
),
486 strlen(list
->extensions
) + 1);
487 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
492 GUID
const * const *format
;
494 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
495 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
496 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
497 for (format
=list
->formats
; *format
; ++format
)
500 StringFromGUID2(*format
, buf
, 39);
501 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
502 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
503 if (res
!= ERROR_SUCCESS
) break;
504 RegCloseKey(format_key
);
506 RegCloseKey(formats_key
);
507 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
510 error_close_clsid_key
:
511 RegCloseKey(clsid_key
);
514 error_close_coclass_key
:
515 RegCloseKey(instance_key
);
516 RegCloseKey(encoders_key
);
517 RegCloseKey(coclass_key
);
519 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
522 /***********************************************************************
523 * unregister_encoders
525 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
)
527 LONG res
= ERROR_SUCCESS
;
533 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
534 KEY_READ
| KEY_WRITE
, &coclass_key
);
535 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
537 if (res
== ERROR_SUCCESS
) {
538 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
539 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
540 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
541 if (res
== ERROR_SUCCESS
)
543 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
544 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
545 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
547 if (res
!= ERROR_SUCCESS
)
548 RegCloseKey(coclass_key
);
550 if (res
!= ERROR_SUCCESS
) goto error_return
;
552 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
553 StringFromGUID2(list
->clsid
, buf
, 39);
555 res
= RegDeleteTreeW(coclass_key
, buf
);
556 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
557 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
559 res
= RegDeleteTreeW(instance_key
, buf
);
560 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
561 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
564 error_close_coclass_key
:
565 RegCloseKey(instance_key
);
566 RegCloseKey(encoders_key
);
567 RegCloseKey(coclass_key
);
569 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
572 /***********************************************************************
573 * register_converters
575 static HRESULT
register_converters(struct regsvr_converter
const *list
)
577 LONG res
= ERROR_SUCCESS
;
583 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
584 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
585 if (res
== ERROR_SUCCESS
) {
586 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
587 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
588 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
589 if (res
== ERROR_SUCCESS
)
591 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
592 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
593 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
595 if (res
!= ERROR_SUCCESS
)
596 RegCloseKey(coclass_key
);
598 if (res
!= ERROR_SUCCESS
) goto error_return
;
600 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
602 HKEY instance_clsid_key
;
604 StringFromGUID2(list
->clsid
, buf
, 39);
605 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
606 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
607 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
609 StringFromGUID2(list
->clsid
, buf
, 39);
610 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
611 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
612 if (res
== ERROR_SUCCESS
) {
613 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
614 (CONST BYTE
*)(buf
), 78);
615 RegCloseKey(instance_clsid_key
);
617 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
620 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
621 (CONST BYTE
*)(list
->author
),
622 strlen(list
->author
) + 1);
623 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
626 if (list
->friendlyname
) {
627 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
628 (CONST BYTE
*)(list
->friendlyname
),
629 strlen(list
->friendlyname
) + 1);
630 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
634 StringFromGUID2(list
->vendor
, buf
, 39);
635 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
636 (CONST BYTE
*)(buf
), 78);
637 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
641 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
642 (CONST BYTE
*)(list
->version
),
643 strlen(list
->version
) + 1);
644 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
649 GUID
const * const *format
;
651 res
= RegCreateKeyExW(clsid_key
, pixelformats_keyname
, 0, NULL
, 0,
652 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
653 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
654 for (format
=list
->formats
; *format
; ++format
)
657 StringFromGUID2(*format
, buf
, 39);
658 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
659 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
660 if (res
!= ERROR_SUCCESS
) break;
661 RegCloseKey(format_key
);
663 RegCloseKey(formats_key
);
664 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
667 error_close_clsid_key
:
668 RegCloseKey(clsid_key
);
671 error_close_coclass_key
:
672 RegCloseKey(instance_key
);
673 RegCloseKey(converters_key
);
674 RegCloseKey(coclass_key
);
676 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
679 /***********************************************************************
680 * unregister_converters
682 static HRESULT
unregister_converters(struct regsvr_converter
const *list
)
684 LONG res
= ERROR_SUCCESS
;
690 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
691 KEY_READ
| KEY_WRITE
, &coclass_key
);
692 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
694 if (res
== ERROR_SUCCESS
) {
695 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
696 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
697 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
698 if (res
== ERROR_SUCCESS
)
700 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
701 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
702 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
704 if (res
!= ERROR_SUCCESS
)
705 RegCloseKey(coclass_key
);
707 if (res
!= ERROR_SUCCESS
) goto error_return
;
709 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
710 StringFromGUID2(list
->clsid
, buf
, 39);
712 res
= RegDeleteTreeW(coclass_key
, buf
);
713 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
714 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
716 res
= RegDeleteTreeW(instance_key
, buf
);
717 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
718 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
721 error_close_coclass_key
:
722 RegCloseKey(instance_key
);
723 RegCloseKey(converters_key
);
724 RegCloseKey(coclass_key
);
726 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
729 /***********************************************************************
730 * register_metadatareaders
732 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
)
734 LONG res
= ERROR_SUCCESS
;
740 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
741 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
742 if (res
== ERROR_SUCCESS
) {
743 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
744 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
745 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
746 if (res
== ERROR_SUCCESS
)
748 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
749 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
750 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
752 if (res
!= ERROR_SUCCESS
)
753 RegCloseKey(coclass_key
);
755 if (res
!= ERROR_SUCCESS
) goto error_return
;
757 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
759 HKEY instance_clsid_key
;
761 StringFromGUID2(list
->clsid
, buf
, 39);
762 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
763 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
764 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
766 StringFromGUID2(list
->clsid
, buf
, 39);
767 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
768 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
769 if (res
== ERROR_SUCCESS
) {
770 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
771 (CONST BYTE
*)(buf
), 78);
772 RegCloseKey(instance_clsid_key
);
774 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
777 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
778 (CONST BYTE
*)(list
->author
),
779 strlen(list
->author
) + 1);
780 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
783 if (list
->friendlyname
) {
784 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
785 (CONST BYTE
*)(list
->friendlyname
),
786 strlen(list
->friendlyname
) + 1);
787 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
791 StringFromGUID2(list
->vendor
, buf
, 39);
792 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
793 (CONST BYTE
*)(buf
), 78);
794 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
797 if (list
->metadata_format
) {
798 StringFromGUID2(list
->metadata_format
, buf
, 39);
799 res
= RegSetValueExW(clsid_key
, metadataformat_valuename
, 0, REG_SZ
,
800 (CONST BYTE
*)(buf
), 78);
801 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
805 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
806 (CONST BYTE
*)(list
->version
),
807 strlen(list
->version
) + 1);
808 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
811 if (list
->specversion
) {
812 res
= RegSetValueExA(clsid_key
, specversion_valuename
, 0, REG_SZ
,
813 (CONST BYTE
*)(list
->version
),
814 strlen(list
->version
) + 1);
815 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
818 res
= RegSetValueExA(clsid_key
, requiresfullstream_valuename
, 0, REG_DWORD
,
819 (CONST BYTE
*)(&list
->requires_fullstream
), 4);
820 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
822 res
= RegSetValueExA(clsid_key
, supportspadding_valuename
, 0, REG_DWORD
,
823 (CONST BYTE
*)(&list
->supports_padding
), 4);
824 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
826 if (list
->requires_fixedsize
) {
827 res
= RegSetValueExA(clsid_key
, requiresfixedsize_valuename
, 0, REG_DWORD
,
828 (CONST BYTE
*)(&list
->requires_fixedsize
), 4);
829 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
832 if (list
->containers
) {
834 const struct reader_containers
*container
;
836 res
= RegCreateKeyExW(clsid_key
, containers_keyname
, 0, NULL
, 0,
837 KEY_READ
| KEY_WRITE
, NULL
, &containers_key
, NULL
);
838 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
839 for (container
=list
->containers
; container
->format
; ++container
)
843 StringFromGUID2(container
->format
, buf
, 39);
844 res
= RegCreateKeyExW(containers_key
, buf
, 0, NULL
, 0,
845 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
846 if (res
!= ERROR_SUCCESS
) break;
848 for (i
=0; container
->patterns
[i
].length
; i
++)
851 static const WCHAR int_format
[] = {'%','i',0};
852 snprintfW(buf
, 39, int_format
, i
);
853 res
= RegCreateKeyExW(format_key
, buf
, 0, NULL
, 0,
854 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
855 if (res
!= ERROR_SUCCESS
) break;
856 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
857 (CONST BYTE
*)(&container
->patterns
[i
].position
), 4);
858 if (res
== ERROR_SUCCESS
)
859 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
860 container
->patterns
[i
].pattern
,
861 container
->patterns
[i
].length
);
862 if (res
== ERROR_SUCCESS
)
863 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
864 container
->patterns
[i
].mask
,
865 container
->patterns
[i
].length
);
866 if (res
== ERROR_SUCCESS
&& container
->patterns
[i
].data_offset
)
867 res
= RegSetValueExA(pattern_key
, dataoffset_valuename
, 0, REG_DWORD
,
868 (CONST BYTE
*)&(container
->patterns
[i
].data_offset
), 4);
869 RegCloseKey(pattern_key
);
872 RegCloseKey(format_key
);
874 RegCloseKey(containers_key
);
877 error_close_clsid_key
:
878 RegCloseKey(clsid_key
);
881 error_close_coclass_key
:
882 RegCloseKey(instance_key
);
883 RegCloseKey(readers_key
);
884 RegCloseKey(coclass_key
);
886 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
889 /***********************************************************************
890 * unregister_metadatareaders
892 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
)
894 LONG res
= ERROR_SUCCESS
;
900 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
901 KEY_READ
| KEY_WRITE
, &coclass_key
);
902 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
904 if (res
== ERROR_SUCCESS
) {
905 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
906 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
907 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
908 if (res
== ERROR_SUCCESS
)
910 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
911 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
912 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
914 if (res
!= ERROR_SUCCESS
)
915 RegCloseKey(coclass_key
);
917 if (res
!= ERROR_SUCCESS
) goto error_return
;
919 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
920 StringFromGUID2(list
->clsid
, buf
, 39);
922 res
= RegDeleteTreeW(coclass_key
, buf
);
923 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
924 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
926 res
= RegDeleteTreeW(instance_key
, buf
);
927 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
928 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
931 error_close_coclass_key
:
932 RegCloseKey(instance_key
);
933 RegCloseKey(readers_key
);
934 RegCloseKey(coclass_key
);
936 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
939 /***********************************************************************
940 * register_pixelformats
942 static HRESULT
register_pixelformats(struct regsvr_pixelformat
const *list
)
944 LONG res
= ERROR_SUCCESS
;
950 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
951 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
952 if (res
== ERROR_SUCCESS
) {
953 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
954 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
955 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
956 if (res
== ERROR_SUCCESS
)
958 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
959 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
960 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
962 if (res
!= ERROR_SUCCESS
)
963 RegCloseKey(coclass_key
);
965 if (res
!= ERROR_SUCCESS
) goto error_return
;
967 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
969 HKEY instance_clsid_key
;
971 StringFromGUID2(list
->clsid
, buf
, 39);
972 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
973 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
974 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
976 StringFromGUID2(list
->clsid
, buf
, 39);
977 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
978 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
979 if (res
== ERROR_SUCCESS
) {
980 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
981 (CONST BYTE
*)(buf
), 78);
982 RegCloseKey(instance_clsid_key
);
984 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
987 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
988 (CONST BYTE
*)(list
->author
),
989 strlen(list
->author
) + 1);
990 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
993 if (list
->friendlyname
) {
994 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
995 (CONST BYTE
*)(list
->friendlyname
),
996 strlen(list
->friendlyname
) + 1);
997 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1001 StringFromGUID2(list
->vendor
, buf
, 39);
1002 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
1003 (CONST BYTE
*)(buf
), 78);
1004 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1007 if (list
->version
) {
1008 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
1009 (CONST BYTE
*)(list
->version
),
1010 strlen(list
->version
) + 1);
1011 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1014 res
= RegSetValueExA(clsid_key
, bitsperpixel_valuename
, 0, REG_DWORD
,
1015 (CONST BYTE
*)(&list
->bitsperpixel
), 4);
1016 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1018 res
= RegSetValueExA(clsid_key
, channelcount_valuename
, 0, REG_DWORD
,
1019 (CONST BYTE
*)(&list
->channelcount
), 4);
1020 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1022 res
= RegSetValueExA(clsid_key
, numericrepresentation_valuename
, 0, REG_DWORD
,
1023 (CONST BYTE
*)(&list
->numericrepresentation
), 4);
1024 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1026 res
= RegSetValueExA(clsid_key
, supportstransparency_valuename
, 0, REG_DWORD
,
1027 (CONST BYTE
*)(&list
->supportsalpha
), 4);
1028 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1030 if (list
->channelmasks
) {
1033 WCHAR mask_valuename
[11];
1034 const WCHAR valuename_format
[] = {'%','d',0};
1036 mask_size
= (list
->bitsperpixel
+ 7)/8;
1038 res
= RegCreateKeyExW(clsid_key
, channelmasks_keyname
, 0, NULL
, 0,
1039 KEY_READ
| KEY_WRITE
, NULL
, &masks_key
, NULL
);
1040 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1041 for (i
=0; i
< list
->channelcount
; i
++)
1043 sprintfW(mask_valuename
, valuename_format
, i
);
1044 res
= RegSetValueExW(masks_key
, mask_valuename
, 0, REG_BINARY
,
1045 list
->channelmasks
[i
], mask_size
);
1046 if (res
!= ERROR_SUCCESS
) break;
1048 RegCloseKey(masks_key
);
1049 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1052 error_close_clsid_key
:
1053 RegCloseKey(clsid_key
);
1056 error_close_coclass_key
:
1057 RegCloseKey(instance_key
);
1058 RegCloseKey(formats_key
);
1059 RegCloseKey(coclass_key
);
1061 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1064 /***********************************************************************
1065 * unregister_pixelformats
1067 static HRESULT
unregister_pixelformats(struct regsvr_pixelformat
const *list
)
1069 LONG res
= ERROR_SUCCESS
;
1075 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
1076 KEY_READ
| KEY_WRITE
, &coclass_key
);
1077 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
1079 if (res
== ERROR_SUCCESS
) {
1080 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
1081 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
1082 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
1083 if (res
== ERROR_SUCCESS
)
1085 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
1086 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
1087 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1089 if (res
!= ERROR_SUCCESS
)
1090 RegCloseKey(coclass_key
);
1092 if (res
!= ERROR_SUCCESS
) goto error_return
;
1094 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
1095 StringFromGUID2(list
->clsid
, buf
, 39);
1097 res
= RegDeleteTreeW(coclass_key
, buf
);
1098 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1099 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1101 res
= RegDeleteTreeW(instance_key
, buf
);
1102 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1103 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1106 error_close_coclass_key
:
1107 RegCloseKey(instance_key
);
1108 RegCloseKey(formats_key
);
1109 RegCloseKey(coclass_key
);
1111 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1114 /***********************************************************************
1117 static const BYTE mask_all
[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1119 static const BYTE bmp_magic
[] = {0x42,0x4d};
1121 static GUID
const * const bmp_formats
[] = {
1122 &GUID_WICPixelFormat1bppIndexed
,
1123 &GUID_WICPixelFormat2bppIndexed
,
1124 &GUID_WICPixelFormat4bppIndexed
,
1125 &GUID_WICPixelFormat8bppIndexed
,
1126 &GUID_WICPixelFormat16bppBGR555
,
1127 &GUID_WICPixelFormat16bppBGR565
,
1128 &GUID_WICPixelFormat24bppBGR
,
1129 &GUID_WICPixelFormat32bppBGR
,
1130 &GUID_WICPixelFormat32bppBGRA
,
1134 static struct decoder_pattern
const bmp_patterns
[] = {
1135 {2,0,bmp_magic
,mask_all
,0},
1139 static const BYTE gif87a_magic
[6] = "GIF87a";
1140 static const BYTE gif89a_magic
[6] = "GIF89a";
1142 static GUID
const * const gif_formats
[] = {
1143 &GUID_WICPixelFormat8bppIndexed
,
1147 static struct decoder_pattern
const gif_patterns
[] = {
1148 {6,0,gif87a_magic
,mask_all
,0},
1149 {6,0,gif89a_magic
,mask_all
,0},
1153 static const BYTE ico_magic
[] = {00,00,01,00};
1155 static GUID
const * const ico_formats
[] = {
1156 &GUID_WICPixelFormat32bppBGRA
,
1160 static struct decoder_pattern
const ico_patterns
[] = {
1161 {4,0,ico_magic
,mask_all
,0},
1165 static const BYTE jpeg_magic
[] = {0xff, 0xd8};
1167 static GUID
const * const jpeg_formats
[] = {
1168 &GUID_WICPixelFormat24bppBGR
,
1169 &GUID_WICPixelFormat32bppCMYK
,
1170 &GUID_WICPixelFormat8bppGray
,
1174 static struct decoder_pattern
const jpeg_patterns
[] = {
1175 {2,0,jpeg_magic
,mask_all
,0},
1179 static const BYTE png_magic
[] = {137,80,78,71,13,10,26,10};
1181 static GUID
const * const png_formats
[] = {
1182 &GUID_WICPixelFormatBlackWhite
,
1183 &GUID_WICPixelFormat2bppGray
,
1184 &GUID_WICPixelFormat4bppGray
,
1185 &GUID_WICPixelFormat8bppGray
,
1186 &GUID_WICPixelFormat16bppGray
,
1187 &GUID_WICPixelFormat32bppBGRA
,
1188 &GUID_WICPixelFormat64bppRGBA
,
1189 &GUID_WICPixelFormat1bppIndexed
,
1190 &GUID_WICPixelFormat2bppIndexed
,
1191 &GUID_WICPixelFormat4bppIndexed
,
1192 &GUID_WICPixelFormat8bppIndexed
,
1193 &GUID_WICPixelFormat24bppBGR
,
1194 &GUID_WICPixelFormat48bppRGB
,
1198 static struct decoder_pattern
const png_patterns
[] = {
1199 {8,0,png_magic
,mask_all
,0},
1203 static const BYTE tiff_magic_le
[] = {0x49,0x49,42,0};
1204 static const BYTE tiff_magic_be
[] = {0x4d,0x4d,0,42};
1206 static GUID
const * const tiff_decode_formats
[] = {
1207 &GUID_WICPixelFormatBlackWhite
,
1208 &GUID_WICPixelFormat4bppGray
,
1209 &GUID_WICPixelFormat8bppGray
,
1210 &GUID_WICPixelFormat4bppIndexed
,
1211 &GUID_WICPixelFormat8bppIndexed
,
1212 &GUID_WICPixelFormat24bppBGR
,
1213 &GUID_WICPixelFormat32bppBGR
,
1214 &GUID_WICPixelFormat32bppBGRA
,
1215 &GUID_WICPixelFormat32bppPBGRA
,
1216 &GUID_WICPixelFormat48bppRGB
,
1217 &GUID_WICPixelFormat64bppRGBA
,
1218 &GUID_WICPixelFormat64bppPRGBA
,
1222 static struct decoder_pattern
const tiff_patterns
[] = {
1223 {4,0,tiff_magic_le
,mask_all
,0},
1224 {4,0,tiff_magic_be
,mask_all
,0},
1228 static const BYTE tga_footer_magic
[18] = "TRUEVISION-XFILE.";
1230 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};
1231 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};
1233 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};
1234 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};
1236 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};
1237 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};
1239 static GUID
const * const tga_formats
[] = {
1240 &GUID_WICPixelFormat8bppGray
,
1241 &GUID_WICPixelFormat8bppIndexed
,
1242 &GUID_WICPixelFormat16bppGray
,
1243 &GUID_WICPixelFormat16bppBGR555
,
1244 &GUID_WICPixelFormat24bppBGR
,
1245 &GUID_WICPixelFormat32bppBGRA
,
1246 &GUID_WICPixelFormat32bppPBGRA
,
1250 static struct decoder_pattern
const tga_patterns
[] = {
1251 {18,18,tga_footer_magic
,mask_all
,1},
1252 {18,0,tga_indexed_magic
,tga_indexed_mask
,0},
1253 {18,0,tga_truecolor_magic
,tga_truecolor_mask
,0},
1254 {18,0,tga_grayscale_magic
,tga_grayscale_mask
,0},
1258 static struct regsvr_decoder
const decoder_list
[] = {
1259 { &CLSID_WICBmpDecoder
,
1263 &GUID_VendorMicrosoft
,
1264 &GUID_ContainerFormatBmp
,
1270 { &CLSID_WICGifDecoder
,
1274 &GUID_VendorMicrosoft
,
1275 &GUID_ContainerFormatGif
,
1281 { &CLSID_WICIcoDecoder
,
1285 &GUID_VendorMicrosoft
,
1286 &GUID_ContainerFormatIco
,
1287 "image/vnd.microsoft.icon",
1292 { &CLSID_WICJpegDecoder
,
1296 &GUID_VendorMicrosoft
,
1297 &GUID_ContainerFormatJpeg
,
1303 { &CLSID_WICPngDecoder
,
1307 &GUID_VendorMicrosoft
,
1308 &GUID_ContainerFormatPng
,
1314 { &CLSID_WICTiffDecoder
,
1318 &GUID_VendorMicrosoft
,
1319 &GUID_ContainerFormatTiff
,
1322 tiff_decode_formats
,
1325 { &CLSID_WineTgaDecoder
,
1330 &GUID_WineContainerFormatTga
,
1336 { NULL
} /* list terminator */
1339 static GUID
const * const bmp_encode_formats
[] = {
1340 &GUID_WICPixelFormat16bppBGR555
,
1341 &GUID_WICPixelFormat16bppBGR565
,
1342 &GUID_WICPixelFormat24bppBGR
,
1343 &GUID_WICPixelFormat32bppBGR
,
1347 static GUID
const * const png_encode_formats
[] = {
1348 &GUID_WICPixelFormat24bppBGR
,
1349 &GUID_WICPixelFormatBlackWhite
,
1350 &GUID_WICPixelFormat2bppGray
,
1351 &GUID_WICPixelFormat4bppGray
,
1352 &GUID_WICPixelFormat8bppGray
,
1353 &GUID_WICPixelFormat16bppGray
,
1354 &GUID_WICPixelFormat32bppBGR
,
1355 &GUID_WICPixelFormat32bppBGRA
,
1356 &GUID_WICPixelFormat48bppRGB
,
1357 &GUID_WICPixelFormat64bppRGBA
,
1361 static GUID
const * const tiff_encode_formats
[] = {
1362 &GUID_WICPixelFormatBlackWhite
,
1363 &GUID_WICPixelFormat4bppGray
,
1364 &GUID_WICPixelFormat8bppGray
,
1365 &GUID_WICPixelFormat24bppBGR
,
1366 &GUID_WICPixelFormat32bppBGRA
,
1367 &GUID_WICPixelFormat32bppPBGRA
,
1368 &GUID_WICPixelFormat48bppRGB
,
1369 &GUID_WICPixelFormat64bppRGBA
,
1370 &GUID_WICPixelFormat64bppPRGBA
,
1374 static GUID
const * const icns_encode_formats
[] = {
1375 &GUID_WICPixelFormat32bppBGRA
,
1379 static struct regsvr_encoder
const encoder_list
[] = {
1380 { &CLSID_WICBmpEncoder
,
1384 &GUID_VendorMicrosoft
,
1385 &GUID_ContainerFormatBmp
,
1390 { &CLSID_WICJpegEncoder
,
1394 &GUID_VendorMicrosoft
,
1395 &GUID_ContainerFormatJpeg
,
1400 { &CLSID_WICPngEncoder
,
1404 &GUID_VendorMicrosoft
,
1405 &GUID_ContainerFormatPng
,
1410 { &CLSID_WICTiffEncoder
,
1414 &GUID_VendorMicrosoft
,
1415 &GUID_ContainerFormatTiff
,
1420 { &CLSID_WICIcnsEncoder
,
1425 NULL
, /* no container format guid */
1430 { NULL
} /* list terminator */
1433 static GUID
const * const converter_formats
[] = {
1434 &GUID_WICPixelFormat1bppIndexed
,
1435 &GUID_WICPixelFormat2bppIndexed
,
1436 &GUID_WICPixelFormat4bppIndexed
,
1437 &GUID_WICPixelFormat8bppIndexed
,
1438 &GUID_WICPixelFormatBlackWhite
,
1439 &GUID_WICPixelFormat2bppGray
,
1440 &GUID_WICPixelFormat4bppGray
,
1441 &GUID_WICPixelFormat8bppGray
,
1442 &GUID_WICPixelFormat16bppGray
,
1443 &GUID_WICPixelFormat16bppBGR555
,
1444 &GUID_WICPixelFormat16bppBGR565
,
1445 &GUID_WICPixelFormat16bppBGRA5551
,
1446 &GUID_WICPixelFormat24bppBGR
,
1447 &GUID_WICPixelFormat24bppRGB
,
1448 &GUID_WICPixelFormat32bppBGR
,
1449 &GUID_WICPixelFormat32bppBGRA
,
1450 &GUID_WICPixelFormat32bppPBGRA
,
1451 &GUID_WICPixelFormat48bppRGB
,
1452 &GUID_WICPixelFormat64bppRGBA
,
1453 &GUID_WICPixelFormat32bppCMYK
,
1457 static struct regsvr_converter
const converter_list
[] = {
1458 { &CLSID_WICDefaultFormatConverter
,
1460 "Default Pixel Format Converter",
1462 &GUID_VendorMicrosoft
,
1465 { NULL
} /* list terminator */
1468 static const BYTE no_magic
[1] = { 0 };
1469 static const BYTE no_mask
[1] = { 0 };
1471 static const struct metadata_pattern ifd_metadata_pattern
[] = {
1472 { 0, 1, no_magic
, no_mask
, 0 },
1476 static const struct reader_containers ifd_containers
[] = {
1478 &GUID_ContainerFormatTiff
,
1479 ifd_metadata_pattern
1481 { NULL
} /* list terminator */
1484 static const BYTE tEXt
[] = "tEXt";
1486 static const struct metadata_pattern pngtext_metadata_pattern
[] = {
1487 { 4, 4, tEXt
, mask_all
, 4 },
1491 static const struct reader_containers pngtext_containers
[] = {
1493 &GUID_ContainerFormatPng
,
1494 pngtext_metadata_pattern
1496 { NULL
} /* list terminator */
1499 static const struct metadata_pattern lsd_metadata_patterns
[] = {
1500 { 0, 6, gif87a_magic
, mask_all
, 0 },
1501 { 0, 6, gif89a_magic
, mask_all
, 0 },
1505 static const struct reader_containers lsd_containers
[] = {
1507 &GUID_ContainerFormatGif
,
1508 lsd_metadata_patterns
1510 { NULL
} /* list terminator */
1513 static const BYTE imd_magic
[] = { 0x2c };
1515 static const struct metadata_pattern imd_metadata_pattern
[] = {
1516 { 0, 1, imd_magic
, mask_all
, 1 },
1520 static const struct reader_containers imd_containers
[] = {
1522 &GUID_ContainerFormatGif
,
1523 imd_metadata_pattern
1525 { NULL
} /* list terminator */
1528 static const BYTE gce_magic
[] = { 0x21, 0xf9, 0x04 };
1530 static const struct metadata_pattern gce_metadata_pattern
[] = {
1531 { 0, 3, gce_magic
, mask_all
, 3 },
1535 static const struct reader_containers gce_containers
[] = {
1537 &GUID_ContainerFormatGif
,
1538 gce_metadata_pattern
1540 { NULL
} /* list terminator */
1543 static const BYTE ape_magic
[] = { 0x21, 0xff, 0x0b };
1545 static const struct metadata_pattern ape_metadata_pattern
[] = {
1546 { 0, 3, ape_magic
, mask_all
, 0 },
1550 static const struct reader_containers ape_containers
[] = {
1552 &GUID_ContainerFormatGif
,
1553 ape_metadata_pattern
1555 { NULL
} /* list terminator */
1558 static const BYTE gif_comment_magic
[] = { 0x21, 0xfe };
1560 static const struct metadata_pattern gif_comment_metadata_pattern
[] = {
1561 { 0, 2, gif_comment_magic
, mask_all
, 0 },
1565 static const struct reader_containers gif_comment_containers
[] = {
1567 &GUID_ContainerFormatGif
,
1568 gif_comment_metadata_pattern
1570 { NULL
} /* list terminator */
1573 static struct regsvr_metadatareader
const metadatareader_list
[] = {
1574 { &CLSID_WICUnknownMetadataReader
,
1576 "Unknown Metadata Reader",
1579 &GUID_VendorMicrosoft
,
1580 &GUID_MetadataFormatUnknown
,
1584 { &CLSID_WICIfdMetadataReader
,
1589 &GUID_VendorMicrosoft
,
1590 &GUID_MetadataFormatIfd
,
1594 { &CLSID_WICPngTextMetadataReader
,
1596 "Chunk tEXt Reader",
1599 &GUID_VendorMicrosoft
,
1600 &GUID_MetadataFormatChunktEXt
,
1604 { &CLSID_WICLSDMetadataReader
,
1606 "Logical Screen Descriptor Reader",
1609 &GUID_VendorMicrosoft
,
1610 &GUID_MetadataFormatLSD
,
1614 { &CLSID_WICIMDMetadataReader
,
1616 "Image Descriptor Reader",
1619 &GUID_VendorMicrosoft
,
1620 &GUID_MetadataFormatIMD
,
1624 { &CLSID_WICGCEMetadataReader
,
1626 "Graphic Control Extension Reader",
1629 &GUID_VendorMicrosoft
,
1630 &GUID_MetadataFormatGCE
,
1634 { &CLSID_WICAPEMetadataReader
,
1636 "Application Extension Reader",
1639 &GUID_VendorMicrosoft
,
1640 &GUID_MetadataFormatAPE
,
1644 { &CLSID_WICGifCommentMetadataReader
,
1646 "Comment Extension Reader",
1649 &GUID_VendorMicrosoft
,
1650 &GUID_MetadataFormatGifComment
,
1652 gif_comment_containers
1654 { NULL
} /* list terminator */
1657 static BYTE
const channel_mask_1bit
[] = { 0x01 };
1658 static BYTE
const channel_mask_2bit
[] = { 0x03 };
1659 static BYTE
const channel_mask_4bit
[] = { 0x0f };
1661 static BYTE
const channel_mask_8bit
[] = { 0xff, 0x00, 0x00, 0x00 };
1662 static BYTE
const channel_mask_8bit2
[] = { 0x00, 0xff, 0x00, 0x00 };
1663 static BYTE
const channel_mask_8bit3
[] = { 0x00, 0x00, 0xff, 0x00 };
1664 static BYTE
const channel_mask_8bit4
[] = { 0x00, 0x00, 0x00, 0xff };
1666 static BYTE
const channel_mask_16bit
[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1667 static BYTE
const channel_mask_16bit2
[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1668 static BYTE
const channel_mask_16bit3
[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
1669 static BYTE
const channel_mask_16bit4
[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
1671 static BYTE
const channel_mask_5bit
[] = { 0x1f, 0x00 };
1672 static BYTE
const channel_mask_5bit2
[] = { 0xe0, 0x03 };
1673 static BYTE
const channel_mask_5bit3
[] = { 0x00, 0x7c };
1674 static BYTE
const channel_mask_5bit4
[] = { 0x00, 0x80 };
1676 static BYTE
const channel_mask_BGR565_2
[] = { 0xe0, 0x07 };
1677 static BYTE
const channel_mask_BGR565_3
[] = { 0x00, 0xf8 };
1679 static BYTE
const * const channel_masks_1bit
[] = { channel_mask_1bit
};
1680 static BYTE
const * const channel_masks_2bit
[] = { channel_mask_2bit
};
1681 static BYTE
const * const channel_masks_4bit
[] = { channel_mask_4bit
};
1682 static BYTE
const * const channel_masks_8bit
[] = { channel_mask_8bit
,
1683 channel_mask_8bit2
, channel_mask_8bit3
, channel_mask_8bit4
};
1684 static BYTE
const * const channel_masks_16bit
[] = { channel_mask_16bit
,
1685 channel_mask_16bit2
, channel_mask_16bit3
, channel_mask_16bit4
};
1687 static BYTE
const * const channel_masks_BGRA5551
[] = { channel_mask_5bit
,
1688 channel_mask_5bit2
, channel_mask_5bit3
, channel_mask_5bit4
};
1690 static BYTE
const * const channel_masks_BGR565
[] = { channel_mask_5bit
,
1691 channel_mask_BGR565_2
, channel_mask_BGR565_3
};
1693 static struct regsvr_pixelformat
const pixelformat_list
[] = {
1694 { &GUID_WICPixelFormat1bppIndexed
,
1697 NULL
, /* no version */
1698 &GUID_VendorMicrosoft
,
1699 1, /* bitsperpixel */
1700 1, /* channel count */
1702 WICPixelFormatNumericRepresentationIndexed
,
1705 { &GUID_WICPixelFormat2bppIndexed
,
1708 NULL
, /* no version */
1709 &GUID_VendorMicrosoft
,
1710 2, /* bitsperpixel */
1711 1, /* channel count */
1713 WICPixelFormatNumericRepresentationIndexed
,
1716 { &GUID_WICPixelFormat4bppIndexed
,
1719 NULL
, /* no version */
1720 &GUID_VendorMicrosoft
,
1721 4, /* bitsperpixel */
1722 1, /* channel count */
1724 WICPixelFormatNumericRepresentationIndexed
,
1727 { &GUID_WICPixelFormat8bppIndexed
,
1730 NULL
, /* no version */
1731 &GUID_VendorMicrosoft
,
1732 8, /* bitsperpixel */
1733 1, /* channel count */
1735 WICPixelFormatNumericRepresentationIndexed
,
1738 { &GUID_WICPixelFormatBlackWhite
,
1741 NULL
, /* no version */
1742 &GUID_VendorMicrosoft
,
1743 1, /* bitsperpixel */
1744 1, /* channel count */
1746 WICPixelFormatNumericRepresentationUnsignedInteger
,
1749 { &GUID_WICPixelFormat2bppGray
,
1752 NULL
, /* no version */
1753 &GUID_VendorMicrosoft
,
1754 2, /* bitsperpixel */
1755 1, /* channel count */
1757 WICPixelFormatNumericRepresentationUnsignedInteger
,
1760 { &GUID_WICPixelFormat4bppGray
,
1763 NULL
, /* no version */
1764 &GUID_VendorMicrosoft
,
1765 4, /* bitsperpixel */
1766 1, /* channel count */
1768 WICPixelFormatNumericRepresentationUnsignedInteger
,
1771 { &GUID_WICPixelFormat8bppGray
,
1774 NULL
, /* no version */
1775 &GUID_VendorMicrosoft
,
1776 8, /* bitsperpixel */
1777 1, /* channel count */
1779 WICPixelFormatNumericRepresentationUnsignedInteger
,
1782 { &GUID_WICPixelFormat16bppGray
,
1785 NULL
, /* no version */
1786 &GUID_VendorMicrosoft
,
1787 16, /* bitsperpixel */
1788 1, /* channel count */
1789 channel_masks_16bit
,
1790 WICPixelFormatNumericRepresentationUnsignedInteger
,
1793 { &GUID_WICPixelFormat16bppBGR555
,
1796 NULL
, /* no version */
1797 &GUID_VendorMicrosoft
,
1798 16, /* bitsperpixel */
1799 3, /* channel count */
1800 channel_masks_BGRA5551
,
1801 WICPixelFormatNumericRepresentationUnsignedInteger
,
1804 { &GUID_WICPixelFormat16bppBGR565
,
1807 NULL
, /* no version */
1808 &GUID_VendorMicrosoft
,
1809 16, /* bitsperpixel */
1810 3, /* channel count */
1811 channel_masks_BGR565
,
1812 WICPixelFormatNumericRepresentationUnsignedInteger
,
1815 { &GUID_WICPixelFormat16bppBGRA5551
,
1818 NULL
, /* no version */
1819 &GUID_VendorMicrosoft
,
1820 16, /* bitsperpixel */
1821 4, /* channel count */
1822 channel_masks_BGRA5551
,
1823 WICPixelFormatNumericRepresentationUnsignedInteger
,
1826 { &GUID_WICPixelFormat24bppBGR
,
1829 NULL
, /* no version */
1830 &GUID_VendorMicrosoft
,
1831 24, /* bitsperpixel */
1832 3, /* channel count */
1834 WICPixelFormatNumericRepresentationUnsignedInteger
,
1837 { &GUID_WICPixelFormat24bppRGB
,
1840 NULL
, /* no version */
1841 &GUID_VendorMicrosoft
,
1842 24, /* bitsperpixel */
1843 3, /* channel count */
1845 WICPixelFormatNumericRepresentationUnsignedInteger
,
1848 { &GUID_WICPixelFormat32bppBGR
,
1851 NULL
, /* no version */
1852 &GUID_VendorMicrosoft
,
1853 32, /* bitsperpixel */
1854 3, /* channel count */
1856 WICPixelFormatNumericRepresentationUnsignedInteger
,
1859 { &GUID_WICPixelFormat32bppBGRA
,
1862 NULL
, /* no version */
1863 &GUID_VendorMicrosoft
,
1864 32, /* bitsperpixel */
1865 4, /* channel count */
1867 WICPixelFormatNumericRepresentationUnsignedInteger
,
1870 { &GUID_WICPixelFormat32bppPBGRA
,
1873 NULL
, /* no version */
1874 &GUID_VendorMicrosoft
,
1875 32, /* bitsperpixel */
1876 4, /* channel count */
1878 WICPixelFormatNumericRepresentationUnsignedInteger
,
1881 { &GUID_WICPixelFormat48bppRGB
,
1884 NULL
, /* no version */
1885 &GUID_VendorMicrosoft
,
1886 48, /* bitsperpixel */
1887 3, /* channel count */
1888 channel_masks_16bit
,
1889 WICPixelFormatNumericRepresentationUnsignedInteger
,
1892 { &GUID_WICPixelFormat64bppRGBA
,
1895 NULL
, /* no version */
1896 &GUID_VendorMicrosoft
,
1897 64, /* bitsperpixel */
1898 4, /* channel count */
1899 channel_masks_16bit
,
1900 WICPixelFormatNumericRepresentationUnsignedInteger
,
1903 { &GUID_WICPixelFormat64bppPRGBA
,
1906 NULL
, /* no version */
1907 &GUID_VendorMicrosoft
,
1908 64, /* bitsperpixel */
1909 4, /* channel count */
1910 channel_masks_16bit
,
1911 WICPixelFormatNumericRepresentationUnsignedInteger
,
1914 { &GUID_WICPixelFormat32bppCMYK
,
1917 NULL
, /* no version */
1918 &GUID_VendorMicrosoft
,
1919 32, /* bitsperpixel */
1920 4, /* channel count */
1922 WICPixelFormatNumericRepresentationUnsignedInteger
,
1925 { NULL
} /* list terminator */
1928 struct regsvr_category
1930 const CLSID
*clsid
; /* NULL for end of list */
1933 static const struct regsvr_category category_list
[] = {
1934 { &CATID_WICBitmapDecoders
},
1935 { &CATID_WICBitmapEncoders
},
1936 { &CATID_WICFormatConverters
},
1937 { &CATID_WICMetadataReader
},
1938 { &CATID_WICPixelFormats
},
1942 static HRESULT
register_categories(const struct regsvr_category
*list
)
1946 HKEY coclass_key
, categories_key
, instance_key
;
1948 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
1949 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
1950 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
1952 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
1953 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
1954 KEY_READ
| KEY_WRITE
, NULL
, &categories_key
, NULL
);
1955 if (res
!= ERROR_SUCCESS
)
1957 RegCloseKey(coclass_key
);
1958 return HRESULT_FROM_WIN32(res
);
1961 res
= RegCreateKeyExW(categories_key
, instance_keyname
, 0, NULL
, 0,
1962 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
1964 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
1966 HKEY instance_clsid_key
;
1968 StringFromGUID2(list
->clsid
, buf
, 39);
1969 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
1970 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
1971 if (res
== ERROR_SUCCESS
)
1973 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
1974 (const BYTE
*)buf
, 78);
1975 RegCloseKey(instance_clsid_key
);
1979 RegCloseKey(instance_key
);
1980 RegCloseKey(categories_key
);
1981 RegCloseKey(coclass_key
);
1983 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1986 static HRESULT
unregister_categories(const struct regsvr_category
*list
)
1990 HKEY coclass_key
, categories_key
, instance_key
;
1992 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
1993 KEY_READ
| KEY_WRITE
, &coclass_key
);
1994 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
1996 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
1997 res
= RegOpenKeyExW(coclass_key
, buf
, 0,
1998 KEY_READ
| KEY_WRITE
, &categories_key
);
1999 if (res
!= ERROR_SUCCESS
)
2001 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
2002 RegCloseKey(coclass_key
);
2003 return HRESULT_FROM_WIN32(res
);
2006 res
= RegOpenKeyExW(categories_key
, instance_keyname
, 0,
2007 KEY_READ
| KEY_WRITE
, &instance_key
);
2009 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
2011 StringFromGUID2(list
->clsid
, buf
, 39);
2012 res
= RegDeleteTreeW(instance_key
, buf
);
2015 RegCloseKey(instance_key
);
2016 RegCloseKey(categories_key
);
2018 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2019 res
= RegDeleteTreeW(coclass_key
, buf
);
2021 RegCloseKey(coclass_key
);
2023 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
2026 extern HRESULT WINAPI
WIC_DllRegisterServer(void) DECLSPEC_HIDDEN
;
2027 extern HRESULT WINAPI
WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
2029 HRESULT WINAPI
DllRegisterServer(void)
2035 hr
= WIC_DllRegisterServer();
2037 hr
= register_categories(category_list
);
2039 hr
= register_decoders(decoder_list
);
2041 hr
= register_encoders(encoder_list
);
2043 hr
= register_converters(converter_list
);
2045 hr
= register_metadatareaders(metadatareader_list
);
2047 hr
= register_pixelformats(pixelformat_list
);
2051 HRESULT WINAPI
DllUnregisterServer(void)
2057 hr
= WIC_DllUnregisterServer();
2059 hr
= unregister_categories(category_list
);
2061 hr
= unregister_decoders(decoder_list
);
2063 hr
= unregister_encoders(encoder_list
);
2065 hr
= unregister_converters(converter_list
);
2067 hr
= unregister_metadatareaders(metadatareader_list
);
2069 hr
= unregister_pixelformats(pixelformat_list
);