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 WCHAR curver_keyname
[] = {
137 'C', 'u', 'r', 'V', 'e', 'r', 0 };
138 static const WCHAR ips_keyname
[] = {
139 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
141 static const WCHAR ips32_keyname
[] = {
142 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
144 static const WCHAR progid_keyname
[] = {
145 'P', 'r', 'o', 'g', 'I', 'D', 0 };
146 static const WCHAR viprogid_keyname
[] = {
147 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
148 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
150 static const char tmodel_valuename
[] = "ThreadingModel";
151 static const char author_valuename
[] = "Author";
152 static const char friendlyname_valuename
[] = "FriendlyName";
153 static const WCHAR vendor_valuename
[] = {'V','e','n','d','o','r',0};
154 static const WCHAR containerformat_valuename
[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
155 static const char version_valuename
[] = "Version";
156 static const char mimetypes_valuename
[] = "MimeTypes";
157 static const char extensions_valuename
[] = "FileExtensions";
158 static const WCHAR formats_keyname
[] = {'F','o','r','m','a','t','s',0};
159 static const WCHAR patterns_keyname
[] = {'P','a','t','t','e','r','n','s',0};
160 static const WCHAR instance_keyname
[] = {'I','n','s','t','a','n','c','e',0};
161 static const WCHAR clsid_valuename
[] = {'C','L','S','I','D',0};
162 static const char length_valuename
[] = "Length";
163 static const char position_valuename
[] = "Position";
164 static const char pattern_valuename
[] = "Pattern";
165 static const char mask_valuename
[] = "Mask";
166 static const char endofstream_valuename
[] = "EndOfStream";
167 static const WCHAR pixelformats_keyname
[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
168 static const WCHAR metadataformat_valuename
[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
169 static const char specversion_valuename
[] = "SpecVersion";
170 static const char requiresfullstream_valuename
[] = "RequiresFullStream";
171 static const char supportspadding_valuename
[] = "SupportsPadding";
172 static const char requiresfixedsize_valuename
[] = "FixedSize";
173 static const WCHAR containers_keyname
[] = {'C','o','n','t','a','i','n','e','r','s',0};
174 static const char dataoffset_valuename
[] = "DataOffset";
175 static const char bitsperpixel_valuename
[] = "BitLength";
176 static const char channelcount_valuename
[] = "ChannelCount";
177 static const char numericrepresentation_valuename
[] = "NumericRepresentation";
178 static const char supportstransparency_valuename
[] = "SupportsTransparency";
179 static const WCHAR channelmasks_keyname
[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
181 /***********************************************************************
184 static HRESULT
register_decoders(struct regsvr_decoder
const *list
)
186 LONG res
= ERROR_SUCCESS
;
192 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
193 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
194 if (res
== ERROR_SUCCESS
) {
195 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
196 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
197 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
198 if (res
== ERROR_SUCCESS
)
200 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
201 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
202 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
204 if (res
!= ERROR_SUCCESS
)
205 RegCloseKey(coclass_key
);
207 if (res
!= ERROR_SUCCESS
) goto error_return
;
209 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
211 HKEY instance_clsid_key
;
213 StringFromGUID2(list
->clsid
, buf
, 39);
214 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
215 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
216 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
218 StringFromGUID2(list
->clsid
, buf
, 39);
219 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
220 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
221 if (res
== ERROR_SUCCESS
) {
222 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
223 (const BYTE
*)buf
, 78);
224 RegCloseKey(instance_clsid_key
);
226 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
229 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
230 (const BYTE
*)list
->author
,
231 strlen(list
->author
) + 1);
232 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
235 if (list
->friendlyname
) {
236 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
237 (const BYTE
*)list
->friendlyname
,
238 strlen(list
->friendlyname
) + 1);
239 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
243 StringFromGUID2(list
->vendor
, buf
, 39);
244 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
245 (const BYTE
*)buf
, 78);
246 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
249 if (list
->container_format
) {
250 StringFromGUID2(list
->container_format
, buf
, 39);
251 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
252 (const BYTE
*)buf
, 78);
253 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
257 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
258 (const BYTE
*)list
->version
,
259 strlen(list
->version
) + 1);
260 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
263 if (list
->mimetypes
) {
264 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
265 (const BYTE
*)list
->mimetypes
,
266 strlen(list
->mimetypes
) + 1);
267 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
270 if (list
->extensions
) {
271 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
272 (const BYTE
*)list
->extensions
,
273 strlen(list
->extensions
) + 1);
274 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
279 GUID
const * const *format
;
281 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
282 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
283 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
284 for (format
=list
->formats
; *format
; ++format
)
287 StringFromGUID2(*format
, buf
, 39);
288 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
289 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
290 if (res
!= ERROR_SUCCESS
) break;
291 RegCloseKey(format_key
);
293 RegCloseKey(formats_key
);
294 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
297 if (list
->patterns
) {
301 res
= RegCreateKeyExW(clsid_key
, patterns_keyname
, 0, NULL
, 0,
302 KEY_READ
| KEY_WRITE
, NULL
, &patterns_key
, NULL
);
303 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
304 for (i
=0; list
->patterns
[i
].length
; i
++)
307 static const WCHAR int_format
[] = {'%','i',0};
308 snprintfW(buf
, 39, int_format
, i
);
309 res
= RegCreateKeyExW(patterns_key
, buf
, 0, NULL
, 0,
310 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
311 if (res
!= ERROR_SUCCESS
) break;
312 res
= RegSetValueExA(pattern_key
, length_valuename
, 0, REG_DWORD
,
313 (const BYTE
*)&list
->patterns
[i
].length
, 4);
314 if (res
== ERROR_SUCCESS
)
315 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
316 (const BYTE
*)&list
->patterns
[i
].position
, 4);
317 if (res
== ERROR_SUCCESS
)
318 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
319 list
->patterns
[i
].pattern
,
320 list
->patterns
[i
].length
);
321 if (res
== ERROR_SUCCESS
)
322 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
323 list
->patterns
[i
].mask
,
324 list
->patterns
[i
].length
);
325 if (res
== ERROR_SUCCESS
)
326 res
= RegSetValueExA(pattern_key
, endofstream_valuename
, 0, REG_DWORD
,
327 (const BYTE
*)&list
->patterns
[i
].endofstream
, 4);
328 RegCloseKey(pattern_key
);
330 RegCloseKey(patterns_key
);
331 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
334 error_close_clsid_key
:
335 RegCloseKey(clsid_key
);
338 error_close_coclass_key
:
339 RegCloseKey(instance_key
);
340 RegCloseKey(decoders_key
);
341 RegCloseKey(coclass_key
);
343 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
346 /***********************************************************************
347 * unregister_decoders
349 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
)
351 LONG res
= ERROR_SUCCESS
;
357 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
358 KEY_READ
| KEY_WRITE
, &coclass_key
);
359 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
361 if (res
== ERROR_SUCCESS
) {
362 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
363 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
364 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
365 if (res
== ERROR_SUCCESS
)
367 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
368 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
369 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
371 if (res
!= ERROR_SUCCESS
)
372 RegCloseKey(coclass_key
);
374 if (res
!= ERROR_SUCCESS
) goto error_return
;
376 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
377 StringFromGUID2(list
->clsid
, buf
, 39);
379 res
= SHDeleteKeyW(coclass_key
, buf
);
380 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
381 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
383 res
= SHDeleteKeyW(instance_key
, buf
);
384 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
385 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
388 error_close_coclass_key
:
389 RegCloseKey(instance_key
);
390 RegCloseKey(decoders_key
);
391 RegCloseKey(coclass_key
);
393 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
396 /***********************************************************************
399 static HRESULT
register_encoders(struct regsvr_encoder
const *list
)
401 LONG res
= ERROR_SUCCESS
;
407 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
408 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
409 if (res
== ERROR_SUCCESS
) {
410 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
411 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
412 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
413 if (res
== ERROR_SUCCESS
)
415 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
416 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
417 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
419 if (res
!= ERROR_SUCCESS
)
420 RegCloseKey(coclass_key
);
422 if (res
!= ERROR_SUCCESS
) goto error_return
;
424 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
426 HKEY instance_clsid_key
;
428 StringFromGUID2(list
->clsid
, buf
, 39);
429 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
430 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
431 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
433 StringFromGUID2(list
->clsid
, buf
, 39);
434 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
435 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
436 if (res
== ERROR_SUCCESS
) {
437 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
438 (const BYTE
*)buf
, 78);
439 RegCloseKey(instance_clsid_key
);
441 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
444 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
445 (const BYTE
*)list
->author
,
446 strlen(list
->author
) + 1);
447 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
450 if (list
->friendlyname
) {
451 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
452 (const BYTE
*)list
->friendlyname
,
453 strlen(list
->friendlyname
) + 1);
454 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
458 StringFromGUID2(list
->vendor
, buf
, 39);
459 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
460 (const BYTE
*)buf
, 78);
461 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
464 if (list
->container_format
) {
465 StringFromGUID2(list
->container_format
, buf
, 39);
466 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
467 (const BYTE
*)buf
, 78);
468 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
472 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
473 (const BYTE
*)list
->version
,
474 strlen(list
->version
) + 1);
475 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
478 if (list
->mimetypes
) {
479 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
480 (const BYTE
*)list
->mimetypes
,
481 strlen(list
->mimetypes
) + 1);
482 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
485 if (list
->extensions
) {
486 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
487 (const BYTE
*)list
->extensions
,
488 strlen(list
->extensions
) + 1);
489 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
494 GUID
const * const *format
;
496 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
497 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
498 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
499 for (format
=list
->formats
; *format
; ++format
)
502 StringFromGUID2(*format
, buf
, 39);
503 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
504 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
505 if (res
!= ERROR_SUCCESS
) break;
506 RegCloseKey(format_key
);
508 RegCloseKey(formats_key
);
509 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
512 error_close_clsid_key
:
513 RegCloseKey(clsid_key
);
516 error_close_coclass_key
:
517 RegCloseKey(instance_key
);
518 RegCloseKey(encoders_key
);
519 RegCloseKey(coclass_key
);
521 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
524 /***********************************************************************
525 * unregister_encoders
527 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
)
529 LONG res
= ERROR_SUCCESS
;
535 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
536 KEY_READ
| KEY_WRITE
, &coclass_key
);
537 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
539 if (res
== ERROR_SUCCESS
) {
540 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
541 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
542 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
543 if (res
== ERROR_SUCCESS
)
545 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
546 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
547 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
549 if (res
!= ERROR_SUCCESS
)
550 RegCloseKey(coclass_key
);
552 if (res
!= ERROR_SUCCESS
) goto error_return
;
554 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
555 StringFromGUID2(list
->clsid
, buf
, 39);
557 res
= SHDeleteKeyW(coclass_key
, buf
);
558 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
559 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
561 res
= SHDeleteKeyW(instance_key
, buf
);
562 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
563 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
566 error_close_coclass_key
:
567 RegCloseKey(instance_key
);
568 RegCloseKey(encoders_key
);
569 RegCloseKey(coclass_key
);
571 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
574 /***********************************************************************
575 * register_converters
577 static HRESULT
register_converters(struct regsvr_converter
const *list
)
579 LONG res
= ERROR_SUCCESS
;
585 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
586 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
587 if (res
== ERROR_SUCCESS
) {
588 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
589 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
590 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
591 if (res
== ERROR_SUCCESS
)
593 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
594 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
595 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
597 if (res
!= ERROR_SUCCESS
)
598 RegCloseKey(coclass_key
);
600 if (res
!= ERROR_SUCCESS
) goto error_return
;
602 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
604 HKEY instance_clsid_key
;
606 StringFromGUID2(list
->clsid
, buf
, 39);
607 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
608 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
609 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
611 StringFromGUID2(list
->clsid
, buf
, 39);
612 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
613 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
614 if (res
== ERROR_SUCCESS
) {
615 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
616 (const BYTE
*)buf
, 78);
617 RegCloseKey(instance_clsid_key
);
619 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
622 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
623 (const BYTE
*)list
->author
,
624 strlen(list
->author
) + 1);
625 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
628 if (list
->friendlyname
) {
629 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
630 (const BYTE
*)list
->friendlyname
,
631 strlen(list
->friendlyname
) + 1);
632 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
636 StringFromGUID2(list
->vendor
, buf
, 39);
637 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
638 (const BYTE
*)buf
, 78);
639 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
643 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
644 (const BYTE
*)list
->version
,
645 strlen(list
->version
) + 1);
646 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
651 GUID
const * const *format
;
653 res
= RegCreateKeyExW(clsid_key
, pixelformats_keyname
, 0, NULL
, 0,
654 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
655 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
656 for (format
=list
->formats
; *format
; ++format
)
659 StringFromGUID2(*format
, buf
, 39);
660 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
661 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
662 if (res
!= ERROR_SUCCESS
) break;
663 RegCloseKey(format_key
);
665 RegCloseKey(formats_key
);
666 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
669 error_close_clsid_key
:
670 RegCloseKey(clsid_key
);
673 error_close_coclass_key
:
674 RegCloseKey(instance_key
);
675 RegCloseKey(converters_key
);
676 RegCloseKey(coclass_key
);
678 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
681 /***********************************************************************
682 * unregister_converters
684 static HRESULT
unregister_converters(struct regsvr_converter
const *list
)
686 LONG res
= ERROR_SUCCESS
;
692 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
693 KEY_READ
| KEY_WRITE
, &coclass_key
);
694 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
696 if (res
== ERROR_SUCCESS
) {
697 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
698 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
699 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
700 if (res
== ERROR_SUCCESS
)
702 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
703 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
704 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
706 if (res
!= ERROR_SUCCESS
)
707 RegCloseKey(coclass_key
);
709 if (res
!= ERROR_SUCCESS
) goto error_return
;
711 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
712 StringFromGUID2(list
->clsid
, buf
, 39);
714 res
= SHDeleteKeyW(coclass_key
, buf
);
715 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
716 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
718 res
= SHDeleteKeyW(instance_key
, buf
);
719 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
720 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
723 error_close_coclass_key
:
724 RegCloseKey(instance_key
);
725 RegCloseKey(converters_key
);
726 RegCloseKey(coclass_key
);
728 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
731 /***********************************************************************
732 * register_metadatareaders
734 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
)
736 LONG res
= ERROR_SUCCESS
;
742 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
743 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
744 if (res
== ERROR_SUCCESS
) {
745 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
746 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
747 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
748 if (res
== ERROR_SUCCESS
)
750 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
751 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
752 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
754 if (res
!= ERROR_SUCCESS
)
755 RegCloseKey(coclass_key
);
757 if (res
!= ERROR_SUCCESS
) goto error_return
;
759 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
761 HKEY instance_clsid_key
;
763 StringFromGUID2(list
->clsid
, buf
, 39);
764 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
765 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
766 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
768 StringFromGUID2(list
->clsid
, buf
, 39);
769 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
770 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
771 if (res
== ERROR_SUCCESS
) {
772 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
773 (const BYTE
*)buf
, 78);
774 RegCloseKey(instance_clsid_key
);
776 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
779 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
780 (const BYTE
*)list
->author
,
781 strlen(list
->author
) + 1);
782 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
785 if (list
->friendlyname
) {
786 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
787 (const BYTE
*)list
->friendlyname
,
788 strlen(list
->friendlyname
) + 1);
789 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
793 StringFromGUID2(list
->vendor
, buf
, 39);
794 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
795 (const BYTE
*)buf
, 78);
796 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
799 if (list
->metadata_format
) {
800 StringFromGUID2(list
->metadata_format
, buf
, 39);
801 res
= RegSetValueExW(clsid_key
, metadataformat_valuename
, 0, REG_SZ
,
802 (const BYTE
*)buf
, 78);
803 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
807 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
808 (const BYTE
*)list
->version
,
809 strlen(list
->version
) + 1);
810 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
813 if (list
->specversion
) {
814 res
= RegSetValueExA(clsid_key
, specversion_valuename
, 0, REG_SZ
,
815 (const BYTE
*)list
->version
,
816 strlen(list
->version
) + 1);
817 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
820 res
= RegSetValueExA(clsid_key
, requiresfullstream_valuename
, 0, REG_DWORD
,
821 (const BYTE
*)&list
->requires_fullstream
, 4);
822 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
824 res
= RegSetValueExA(clsid_key
, supportspadding_valuename
, 0, REG_DWORD
,
825 (const BYTE
*)&list
->supports_padding
, 4);
826 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
828 if (list
->requires_fixedsize
) {
829 res
= RegSetValueExA(clsid_key
, requiresfixedsize_valuename
, 0, REG_DWORD
,
830 (const BYTE
*)&list
->requires_fixedsize
, 4);
831 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
834 if (list
->containers
) {
836 const struct reader_containers
*container
;
838 res
= RegCreateKeyExW(clsid_key
, containers_keyname
, 0, NULL
, 0,
839 KEY_READ
| KEY_WRITE
, NULL
, &containers_key
, NULL
);
840 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
841 for (container
=list
->containers
; container
->format
; ++container
)
845 StringFromGUID2(container
->format
, buf
, 39);
846 res
= RegCreateKeyExW(containers_key
, buf
, 0, NULL
, 0,
847 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
848 if (res
!= ERROR_SUCCESS
) break;
850 for (i
=0; container
->patterns
[i
].length
; i
++)
853 static const WCHAR int_format
[] = {'%','i',0};
854 snprintfW(buf
, 39, int_format
, i
);
855 res
= RegCreateKeyExW(format_key
, buf
, 0, NULL
, 0,
856 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
857 if (res
!= ERROR_SUCCESS
) break;
858 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
859 (const BYTE
*)&container
->patterns
[i
].position
, 4);
860 if (res
== ERROR_SUCCESS
)
861 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
862 container
->patterns
[i
].pattern
,
863 container
->patterns
[i
].length
);
864 if (res
== ERROR_SUCCESS
)
865 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
866 container
->patterns
[i
].mask
,
867 container
->patterns
[i
].length
);
868 if (res
== ERROR_SUCCESS
&& container
->patterns
[i
].data_offset
)
869 res
= RegSetValueExA(pattern_key
, dataoffset_valuename
, 0, REG_DWORD
,
870 (const BYTE
*)&container
->patterns
[i
].data_offset
, 4);
871 RegCloseKey(pattern_key
);
874 RegCloseKey(format_key
);
876 RegCloseKey(containers_key
);
879 error_close_clsid_key
:
880 RegCloseKey(clsid_key
);
883 error_close_coclass_key
:
884 RegCloseKey(instance_key
);
885 RegCloseKey(readers_key
);
886 RegCloseKey(coclass_key
);
888 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
891 /***********************************************************************
892 * unregister_metadatareaders
894 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
)
896 LONG res
= ERROR_SUCCESS
;
902 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
903 KEY_READ
| KEY_WRITE
, &coclass_key
);
904 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
906 if (res
== ERROR_SUCCESS
) {
907 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
908 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
909 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
910 if (res
== ERROR_SUCCESS
)
912 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
913 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
914 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
916 if (res
!= ERROR_SUCCESS
)
917 RegCloseKey(coclass_key
);
919 if (res
!= ERROR_SUCCESS
) goto error_return
;
921 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
922 StringFromGUID2(list
->clsid
, buf
, 39);
924 res
= SHDeleteKeyW(coclass_key
, buf
);
925 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
926 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
928 res
= SHDeleteKeyW(instance_key
, buf
);
929 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
930 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
933 error_close_coclass_key
:
934 RegCloseKey(instance_key
);
935 RegCloseKey(readers_key
);
936 RegCloseKey(coclass_key
);
938 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
941 /***********************************************************************
942 * register_pixelformats
944 static HRESULT
register_pixelformats(struct regsvr_pixelformat
const *list
)
946 LONG res
= ERROR_SUCCESS
;
952 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
953 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
954 if (res
== ERROR_SUCCESS
) {
955 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
956 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
957 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
958 if (res
== ERROR_SUCCESS
)
960 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
961 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
962 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
964 if (res
!= ERROR_SUCCESS
)
965 RegCloseKey(coclass_key
);
967 if (res
!= ERROR_SUCCESS
) goto error_return
;
969 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
971 HKEY instance_clsid_key
;
973 StringFromGUID2(list
->clsid
, buf
, 39);
974 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
975 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
976 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
978 StringFromGUID2(list
->clsid
, buf
, 39);
979 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
980 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
981 if (res
== ERROR_SUCCESS
) {
982 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
983 (const BYTE
*)buf
, 78);
984 RegCloseKey(instance_clsid_key
);
986 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
989 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
990 (const BYTE
*)list
->author
,
991 strlen(list
->author
) + 1);
992 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
995 if (list
->friendlyname
) {
996 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
997 (const BYTE
*)list
->friendlyname
,
998 strlen(list
->friendlyname
) + 1);
999 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1003 StringFromGUID2(list
->vendor
, buf
, 39);
1004 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
1005 (const BYTE
*)buf
, 78);
1006 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1009 if (list
->version
) {
1010 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
1011 (const BYTE
*)list
->version
,
1012 strlen(list
->version
) + 1);
1013 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1016 res
= RegSetValueExA(clsid_key
, bitsperpixel_valuename
, 0, REG_DWORD
,
1017 (const BYTE
*)&list
->bitsperpixel
, 4);
1018 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1020 res
= RegSetValueExA(clsid_key
, channelcount_valuename
, 0, REG_DWORD
,
1021 (const BYTE
*)&list
->channelcount
, 4);
1022 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1024 res
= RegSetValueExA(clsid_key
, numericrepresentation_valuename
, 0, REG_DWORD
,
1025 (const BYTE
*)&list
->numericrepresentation
, 4);
1026 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1028 res
= RegSetValueExA(clsid_key
, supportstransparency_valuename
, 0, REG_DWORD
,
1029 (const BYTE
*)&list
->supportsalpha
, 4);
1030 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1032 if (list
->channelmasks
) {
1035 WCHAR mask_valuename
[11];
1036 const WCHAR valuename_format
[] = {'%','d',0};
1038 mask_size
= (list
->bitsperpixel
+ 7)/8;
1040 res
= RegCreateKeyExW(clsid_key
, channelmasks_keyname
, 0, NULL
, 0,
1041 KEY_READ
| KEY_WRITE
, NULL
, &masks_key
, NULL
);
1042 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1043 for (i
=0; i
< list
->channelcount
; i
++)
1045 sprintfW(mask_valuename
, valuename_format
, i
);
1046 res
= RegSetValueExW(masks_key
, mask_valuename
, 0, REG_BINARY
,
1047 list
->channelmasks
[i
], mask_size
);
1048 if (res
!= ERROR_SUCCESS
) break;
1050 RegCloseKey(masks_key
);
1051 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1054 error_close_clsid_key
:
1055 RegCloseKey(clsid_key
);
1058 error_close_coclass_key
:
1059 RegCloseKey(instance_key
);
1060 RegCloseKey(formats_key
);
1061 RegCloseKey(coclass_key
);
1063 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1066 /***********************************************************************
1067 * unregister_pixelformats
1069 static HRESULT
unregister_pixelformats(struct regsvr_pixelformat
const *list
)
1071 LONG res
= ERROR_SUCCESS
;
1077 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
1078 KEY_READ
| KEY_WRITE
, &coclass_key
);
1079 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
1081 if (res
== ERROR_SUCCESS
) {
1082 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
1083 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
1084 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
1085 if (res
== ERROR_SUCCESS
)
1087 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
1088 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
1089 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1091 if (res
!= ERROR_SUCCESS
)
1092 RegCloseKey(coclass_key
);
1094 if (res
!= ERROR_SUCCESS
) goto error_return
;
1096 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
1097 StringFromGUID2(list
->clsid
, buf
, 39);
1099 res
= SHDeleteKeyW(coclass_key
, buf
);
1100 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1101 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1103 res
= SHDeleteKeyW(instance_key
, buf
);
1104 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1105 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1108 error_close_coclass_key
:
1109 RegCloseKey(instance_key
);
1110 RegCloseKey(formats_key
);
1111 RegCloseKey(coclass_key
);
1113 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1116 /***********************************************************************
1119 static const BYTE mask_all
[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1121 static const BYTE bmp_magic
[] = {0x42,0x4d};
1123 static GUID
const * const bmp_formats
[] = {
1124 &GUID_WICPixelFormat1bppIndexed
,
1125 &GUID_WICPixelFormat2bppIndexed
,
1126 &GUID_WICPixelFormat4bppIndexed
,
1127 &GUID_WICPixelFormat8bppIndexed
,
1128 &GUID_WICPixelFormat16bppBGR555
,
1129 &GUID_WICPixelFormat16bppBGR565
,
1130 &GUID_WICPixelFormat24bppBGR
,
1131 &GUID_WICPixelFormat32bppBGR
,
1132 &GUID_WICPixelFormat32bppBGRA
,
1136 static struct decoder_pattern
const bmp_patterns
[] = {
1137 {2,0,bmp_magic
,mask_all
,0},
1141 static const BYTE gif87a_magic
[6] = "GIF87a";
1142 static const BYTE gif89a_magic
[6] = "GIF89a";
1144 static GUID
const * const gif_formats
[] = {
1145 &GUID_WICPixelFormat8bppIndexed
,
1149 static struct decoder_pattern
const gif_patterns
[] = {
1150 {6,0,gif87a_magic
,mask_all
,0},
1151 {6,0,gif89a_magic
,mask_all
,0},
1155 static const BYTE ico_magic
[] = {00,00,01,00};
1157 static GUID
const * const ico_formats
[] = {
1158 &GUID_WICPixelFormat32bppBGRA
,
1162 static struct decoder_pattern
const ico_patterns
[] = {
1163 {4,0,ico_magic
,mask_all
,0},
1167 static const BYTE jpeg_magic
[] = {0xff, 0xd8};
1169 static GUID
const * const jpeg_formats
[] = {
1170 &GUID_WICPixelFormat24bppBGR
,
1171 &GUID_WICPixelFormat32bppCMYK
,
1172 &GUID_WICPixelFormat8bppGray
,
1176 static struct decoder_pattern
const jpeg_patterns
[] = {
1177 {2,0,jpeg_magic
,mask_all
,0},
1181 static const BYTE png_magic
[] = {137,80,78,71,13,10,26,10};
1183 static GUID
const * const png_formats
[] = {
1184 &GUID_WICPixelFormatBlackWhite
,
1185 &GUID_WICPixelFormat2bppGray
,
1186 &GUID_WICPixelFormat4bppGray
,
1187 &GUID_WICPixelFormat8bppGray
,
1188 &GUID_WICPixelFormat16bppGray
,
1189 &GUID_WICPixelFormat32bppBGRA
,
1190 &GUID_WICPixelFormat64bppRGBA
,
1191 &GUID_WICPixelFormat1bppIndexed
,
1192 &GUID_WICPixelFormat2bppIndexed
,
1193 &GUID_WICPixelFormat4bppIndexed
,
1194 &GUID_WICPixelFormat8bppIndexed
,
1195 &GUID_WICPixelFormat24bppBGR
,
1196 &GUID_WICPixelFormat48bppRGB
,
1200 static struct decoder_pattern
const png_patterns
[] = {
1201 {8,0,png_magic
,mask_all
,0},
1205 static const BYTE tiff_magic_le
[] = {0x49,0x49,42,0};
1206 static const BYTE tiff_magic_be
[] = {0x4d,0x4d,0,42};
1208 static GUID
const * const tiff_decode_formats
[] = {
1209 &GUID_WICPixelFormatBlackWhite
,
1210 &GUID_WICPixelFormat4bppGray
,
1211 &GUID_WICPixelFormat8bppGray
,
1212 &GUID_WICPixelFormat4bppIndexed
,
1213 &GUID_WICPixelFormat8bppIndexed
,
1214 &GUID_WICPixelFormat24bppBGR
,
1215 &GUID_WICPixelFormat32bppBGR
,
1216 &GUID_WICPixelFormat32bppBGRA
,
1217 &GUID_WICPixelFormat32bppPBGRA
,
1218 &GUID_WICPixelFormat48bppRGB
,
1219 &GUID_WICPixelFormat64bppRGBA
,
1220 &GUID_WICPixelFormat64bppPRGBA
,
1224 static struct decoder_pattern
const tiff_patterns
[] = {
1225 {4,0,tiff_magic_le
,mask_all
,0},
1226 {4,0,tiff_magic_be
,mask_all
,0},
1230 static const BYTE tga_footer_magic
[18] = "TRUEVISION-XFILE.";
1232 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};
1233 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};
1235 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};
1236 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};
1238 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};
1239 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};
1241 static GUID
const * const tga_formats
[] = {
1242 &GUID_WICPixelFormat8bppGray
,
1243 &GUID_WICPixelFormat8bppIndexed
,
1244 &GUID_WICPixelFormat16bppGray
,
1245 &GUID_WICPixelFormat16bppBGR555
,
1246 &GUID_WICPixelFormat24bppBGR
,
1247 &GUID_WICPixelFormat32bppBGRA
,
1248 &GUID_WICPixelFormat32bppPBGRA
,
1252 static struct decoder_pattern
const tga_patterns
[] = {
1253 {18,18,tga_footer_magic
,mask_all
,1},
1254 {18,0,tga_indexed_magic
,tga_indexed_mask
,0},
1255 {18,0,tga_truecolor_magic
,tga_truecolor_mask
,0},
1256 {18,0,tga_grayscale_magic
,tga_grayscale_mask
,0},
1260 static struct regsvr_decoder
const decoder_list
[] = {
1261 { &CLSID_WICBmpDecoder
,
1265 &GUID_VendorMicrosoft
,
1266 &GUID_ContainerFormatBmp
,
1272 { &CLSID_WICGifDecoder
,
1276 &GUID_VendorMicrosoft
,
1277 &GUID_ContainerFormatGif
,
1283 { &CLSID_WICIcoDecoder
,
1287 &GUID_VendorMicrosoft
,
1288 &GUID_ContainerFormatIco
,
1289 "image/vnd.microsoft.icon",
1294 { &CLSID_WICJpegDecoder
,
1298 &GUID_VendorMicrosoft
,
1299 &GUID_ContainerFormatJpeg
,
1305 { &CLSID_WICPngDecoder
,
1309 &GUID_VendorMicrosoft
,
1310 &GUID_ContainerFormatPng
,
1316 { &CLSID_WICTiffDecoder
,
1320 &GUID_VendorMicrosoft
,
1321 &GUID_ContainerFormatTiff
,
1324 tiff_decode_formats
,
1327 { &CLSID_WineTgaDecoder
,
1332 &GUID_WineContainerFormatTga
,
1338 { NULL
} /* list terminator */
1341 static GUID
const * const bmp_encode_formats
[] = {
1342 &GUID_WICPixelFormat16bppBGR555
,
1343 &GUID_WICPixelFormat16bppBGR565
,
1344 &GUID_WICPixelFormat24bppBGR
,
1345 &GUID_WICPixelFormat32bppBGR
,
1349 static GUID
const * const png_encode_formats
[] = {
1350 &GUID_WICPixelFormat24bppBGR
,
1351 &GUID_WICPixelFormatBlackWhite
,
1352 &GUID_WICPixelFormat2bppGray
,
1353 &GUID_WICPixelFormat4bppGray
,
1354 &GUID_WICPixelFormat8bppGray
,
1355 &GUID_WICPixelFormat16bppGray
,
1356 &GUID_WICPixelFormat32bppBGR
,
1357 &GUID_WICPixelFormat32bppBGRA
,
1358 &GUID_WICPixelFormat48bppRGB
,
1359 &GUID_WICPixelFormat64bppRGBA
,
1363 static GUID
const * const tiff_encode_formats
[] = {
1364 &GUID_WICPixelFormatBlackWhite
,
1365 &GUID_WICPixelFormat4bppGray
,
1366 &GUID_WICPixelFormat8bppGray
,
1367 &GUID_WICPixelFormat24bppBGR
,
1368 &GUID_WICPixelFormat32bppBGRA
,
1369 &GUID_WICPixelFormat32bppPBGRA
,
1370 &GUID_WICPixelFormat48bppRGB
,
1371 &GUID_WICPixelFormat64bppRGBA
,
1372 &GUID_WICPixelFormat64bppPRGBA
,
1376 static GUID
const * const icns_encode_formats
[] = {
1377 &GUID_WICPixelFormat32bppBGRA
,
1381 static struct regsvr_encoder
const encoder_list
[] = {
1382 { &CLSID_WICBmpEncoder
,
1386 &GUID_VendorMicrosoft
,
1387 &GUID_ContainerFormatBmp
,
1392 { &CLSID_WICJpegEncoder
,
1396 &GUID_VendorMicrosoft
,
1397 &GUID_ContainerFormatJpeg
,
1402 { &CLSID_WICPngEncoder
,
1406 &GUID_VendorMicrosoft
,
1407 &GUID_ContainerFormatPng
,
1412 { &CLSID_WICTiffEncoder
,
1416 &GUID_VendorMicrosoft
,
1417 &GUID_ContainerFormatTiff
,
1422 { &CLSID_WICIcnsEncoder
,
1427 NULL
, /* no container format guid */
1432 { NULL
} /* list terminator */
1435 static GUID
const * const converter_formats
[] = {
1436 &GUID_WICPixelFormat1bppIndexed
,
1437 &GUID_WICPixelFormat2bppIndexed
,
1438 &GUID_WICPixelFormat4bppIndexed
,
1439 &GUID_WICPixelFormat8bppIndexed
,
1440 &GUID_WICPixelFormatBlackWhite
,
1441 &GUID_WICPixelFormat2bppGray
,
1442 &GUID_WICPixelFormat4bppGray
,
1443 &GUID_WICPixelFormat8bppGray
,
1444 &GUID_WICPixelFormat16bppGray
,
1445 &GUID_WICPixelFormat16bppBGR555
,
1446 &GUID_WICPixelFormat16bppBGR565
,
1447 &GUID_WICPixelFormat16bppBGRA5551
,
1448 &GUID_WICPixelFormat24bppBGR
,
1449 &GUID_WICPixelFormat24bppRGB
,
1450 &GUID_WICPixelFormat32bppBGR
,
1451 &GUID_WICPixelFormat32bppBGRA
,
1452 &GUID_WICPixelFormat32bppPBGRA
,
1453 &GUID_WICPixelFormat48bppRGB
,
1454 &GUID_WICPixelFormat64bppRGBA
,
1455 &GUID_WICPixelFormat32bppCMYK
,
1459 static struct regsvr_converter
const converter_list
[] = {
1460 { &CLSID_WICDefaultFormatConverter
,
1462 "Default Pixel Format Converter",
1464 &GUID_VendorMicrosoft
,
1467 { NULL
} /* list terminator */
1470 static const BYTE no_magic
[1] = { 0 };
1471 static const BYTE no_mask
[1] = { 0 };
1473 static const struct metadata_pattern ifd_metadata_pattern
[] = {
1474 { 0, 1, no_magic
, no_mask
, 0 },
1478 static const struct reader_containers ifd_containers
[] = {
1480 &GUID_ContainerFormatTiff
,
1481 ifd_metadata_pattern
1483 { NULL
} /* list terminator */
1486 static const BYTE tEXt
[] = "tEXt";
1488 static const struct metadata_pattern pngtext_metadata_pattern
[] = {
1489 { 4, 4, tEXt
, mask_all
, 4 },
1493 static const struct reader_containers pngtext_containers
[] = {
1495 &GUID_ContainerFormatPng
,
1496 pngtext_metadata_pattern
1498 { NULL
} /* list terminator */
1501 static const struct metadata_pattern lsd_metadata_patterns
[] = {
1502 { 0, 6, gif87a_magic
, mask_all
, 0 },
1503 { 0, 6, gif89a_magic
, mask_all
, 0 },
1507 static const struct reader_containers lsd_containers
[] = {
1509 &GUID_ContainerFormatGif
,
1510 lsd_metadata_patterns
1512 { NULL
} /* list terminator */
1515 static const BYTE imd_magic
[] = { 0x2c };
1517 static const struct metadata_pattern imd_metadata_pattern
[] = {
1518 { 0, 1, imd_magic
, mask_all
, 1 },
1522 static const struct reader_containers imd_containers
[] = {
1524 &GUID_ContainerFormatGif
,
1525 imd_metadata_pattern
1527 { NULL
} /* list terminator */
1530 static const BYTE gce_magic
[] = { 0x21, 0xf9, 0x04 };
1532 static const struct metadata_pattern gce_metadata_pattern
[] = {
1533 { 0, 3, gce_magic
, mask_all
, 3 },
1537 static const struct reader_containers gce_containers
[] = {
1539 &GUID_ContainerFormatGif
,
1540 gce_metadata_pattern
1542 { NULL
} /* list terminator */
1545 static const BYTE ape_magic
[] = { 0x21, 0xff, 0x0b };
1547 static const struct metadata_pattern ape_metadata_pattern
[] = {
1548 { 0, 3, ape_magic
, mask_all
, 0 },
1552 static const struct reader_containers ape_containers
[] = {
1554 &GUID_ContainerFormatGif
,
1555 ape_metadata_pattern
1557 { NULL
} /* list terminator */
1560 static const BYTE gif_comment_magic
[] = { 0x21, 0xfe };
1562 static const struct metadata_pattern gif_comment_metadata_pattern
[] = {
1563 { 0, 2, gif_comment_magic
, mask_all
, 0 },
1567 static const struct reader_containers gif_comment_containers
[] = {
1569 &GUID_ContainerFormatGif
,
1570 gif_comment_metadata_pattern
1572 { NULL
} /* list terminator */
1575 static struct regsvr_metadatareader
const metadatareader_list
[] = {
1576 { &CLSID_WICUnknownMetadataReader
,
1578 "Unknown Metadata Reader",
1581 &GUID_VendorMicrosoft
,
1582 &GUID_MetadataFormatUnknown
,
1586 { &CLSID_WICIfdMetadataReader
,
1591 &GUID_VendorMicrosoft
,
1592 &GUID_MetadataFormatIfd
,
1596 { &CLSID_WICPngTextMetadataReader
,
1598 "Chunk tEXt Reader",
1601 &GUID_VendorMicrosoft
,
1602 &GUID_MetadataFormatChunktEXt
,
1606 { &CLSID_WICLSDMetadataReader
,
1608 "Logical Screen Descriptor Reader",
1611 &GUID_VendorMicrosoft
,
1612 &GUID_MetadataFormatLSD
,
1616 { &CLSID_WICIMDMetadataReader
,
1618 "Image Descriptor Reader",
1621 &GUID_VendorMicrosoft
,
1622 &GUID_MetadataFormatIMD
,
1626 { &CLSID_WICGCEMetadataReader
,
1628 "Graphic Control Extension Reader",
1631 &GUID_VendorMicrosoft
,
1632 &GUID_MetadataFormatGCE
,
1636 { &CLSID_WICAPEMetadataReader
,
1638 "Application Extension Reader",
1641 &GUID_VendorMicrosoft
,
1642 &GUID_MetadataFormatAPE
,
1646 { &CLSID_WICGifCommentMetadataReader
,
1648 "Comment Extension Reader",
1651 &GUID_VendorMicrosoft
,
1652 &GUID_MetadataFormatGifComment
,
1654 gif_comment_containers
1656 { NULL
} /* list terminator */
1659 static BYTE
const channel_mask_1bit
[] = { 0x01 };
1660 static BYTE
const channel_mask_2bit
[] = { 0x03 };
1661 static BYTE
const channel_mask_4bit
[] = { 0x0f };
1663 static BYTE
const channel_mask_8bit
[] = { 0xff, 0x00, 0x00, 0x00 };
1664 static BYTE
const channel_mask_8bit2
[] = { 0x00, 0xff, 0x00, 0x00 };
1665 static BYTE
const channel_mask_8bit3
[] = { 0x00, 0x00, 0xff, 0x00 };
1666 static BYTE
const channel_mask_8bit4
[] = { 0x00, 0x00, 0x00, 0xff };
1668 static BYTE
const channel_mask_16bit
[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1669 static BYTE
const channel_mask_16bit2
[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1670 static BYTE
const channel_mask_16bit3
[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
1671 static BYTE
const channel_mask_16bit4
[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
1673 static BYTE
const channel_mask_5bit
[] = { 0x1f, 0x00 };
1674 static BYTE
const channel_mask_5bit2
[] = { 0xe0, 0x03 };
1675 static BYTE
const channel_mask_5bit3
[] = { 0x00, 0x7c };
1676 static BYTE
const channel_mask_5bit4
[] = { 0x00, 0x80 };
1678 static BYTE
const channel_mask_BGR565_2
[] = { 0xe0, 0x07 };
1679 static BYTE
const channel_mask_BGR565_3
[] = { 0x00, 0xf8 };
1681 static BYTE
const * const channel_masks_1bit
[] = { channel_mask_1bit
};
1682 static BYTE
const * const channel_masks_2bit
[] = { channel_mask_2bit
};
1683 static BYTE
const * const channel_masks_4bit
[] = { channel_mask_4bit
};
1684 static BYTE
const * const channel_masks_8bit
[] = { channel_mask_8bit
,
1685 channel_mask_8bit2
, channel_mask_8bit3
, channel_mask_8bit4
};
1686 static BYTE
const * const channel_masks_16bit
[] = { channel_mask_16bit
,
1687 channel_mask_16bit2
, channel_mask_16bit3
, channel_mask_16bit4
};
1689 static BYTE
const * const channel_masks_BGRA5551
[] = { channel_mask_5bit
,
1690 channel_mask_5bit2
, channel_mask_5bit3
, channel_mask_5bit4
};
1692 static BYTE
const * const channel_masks_BGR565
[] = { channel_mask_5bit
,
1693 channel_mask_BGR565_2
, channel_mask_BGR565_3
};
1695 static struct regsvr_pixelformat
const pixelformat_list
[] = {
1696 { &GUID_WICPixelFormat1bppIndexed
,
1699 NULL
, /* no version */
1700 &GUID_VendorMicrosoft
,
1701 1, /* bitsperpixel */
1702 1, /* channel count */
1704 WICPixelFormatNumericRepresentationIndexed
,
1707 { &GUID_WICPixelFormat2bppIndexed
,
1710 NULL
, /* no version */
1711 &GUID_VendorMicrosoft
,
1712 2, /* bitsperpixel */
1713 1, /* channel count */
1715 WICPixelFormatNumericRepresentationIndexed
,
1718 { &GUID_WICPixelFormat4bppIndexed
,
1721 NULL
, /* no version */
1722 &GUID_VendorMicrosoft
,
1723 4, /* bitsperpixel */
1724 1, /* channel count */
1726 WICPixelFormatNumericRepresentationIndexed
,
1729 { &GUID_WICPixelFormat8bppIndexed
,
1732 NULL
, /* no version */
1733 &GUID_VendorMicrosoft
,
1734 8, /* bitsperpixel */
1735 1, /* channel count */
1737 WICPixelFormatNumericRepresentationIndexed
,
1740 { &GUID_WICPixelFormatBlackWhite
,
1743 NULL
, /* no version */
1744 &GUID_VendorMicrosoft
,
1745 1, /* bitsperpixel */
1746 1, /* channel count */
1748 WICPixelFormatNumericRepresentationUnsignedInteger
,
1751 { &GUID_WICPixelFormat2bppGray
,
1754 NULL
, /* no version */
1755 &GUID_VendorMicrosoft
,
1756 2, /* bitsperpixel */
1757 1, /* channel count */
1759 WICPixelFormatNumericRepresentationUnsignedInteger
,
1762 { &GUID_WICPixelFormat4bppGray
,
1765 NULL
, /* no version */
1766 &GUID_VendorMicrosoft
,
1767 4, /* bitsperpixel */
1768 1, /* channel count */
1770 WICPixelFormatNumericRepresentationUnsignedInteger
,
1773 { &GUID_WICPixelFormat8bppGray
,
1776 NULL
, /* no version */
1777 &GUID_VendorMicrosoft
,
1778 8, /* bitsperpixel */
1779 1, /* channel count */
1781 WICPixelFormatNumericRepresentationUnsignedInteger
,
1784 { &GUID_WICPixelFormat16bppGray
,
1787 NULL
, /* no version */
1788 &GUID_VendorMicrosoft
,
1789 16, /* bitsperpixel */
1790 1, /* channel count */
1791 channel_masks_16bit
,
1792 WICPixelFormatNumericRepresentationUnsignedInteger
,
1795 { &GUID_WICPixelFormat16bppBGR555
,
1798 NULL
, /* no version */
1799 &GUID_VendorMicrosoft
,
1800 16, /* bitsperpixel */
1801 3, /* channel count */
1802 channel_masks_BGRA5551
,
1803 WICPixelFormatNumericRepresentationUnsignedInteger
,
1806 { &GUID_WICPixelFormat16bppBGR565
,
1809 NULL
, /* no version */
1810 &GUID_VendorMicrosoft
,
1811 16, /* bitsperpixel */
1812 3, /* channel count */
1813 channel_masks_BGR565
,
1814 WICPixelFormatNumericRepresentationUnsignedInteger
,
1817 { &GUID_WICPixelFormat16bppBGRA5551
,
1820 NULL
, /* no version */
1821 &GUID_VendorMicrosoft
,
1822 16, /* bitsperpixel */
1823 4, /* channel count */
1824 channel_masks_BGRA5551
,
1825 WICPixelFormatNumericRepresentationUnsignedInteger
,
1828 { &GUID_WICPixelFormat24bppBGR
,
1831 NULL
, /* no version */
1832 &GUID_VendorMicrosoft
,
1833 24, /* bitsperpixel */
1834 3, /* channel count */
1836 WICPixelFormatNumericRepresentationUnsignedInteger
,
1839 { &GUID_WICPixelFormat24bppRGB
,
1842 NULL
, /* no version */
1843 &GUID_VendorMicrosoft
,
1844 24, /* bitsperpixel */
1845 3, /* channel count */
1847 WICPixelFormatNumericRepresentationUnsignedInteger
,
1850 { &GUID_WICPixelFormat32bppBGR
,
1853 NULL
, /* no version */
1854 &GUID_VendorMicrosoft
,
1855 32, /* bitsperpixel */
1856 3, /* channel count */
1858 WICPixelFormatNumericRepresentationUnsignedInteger
,
1861 { &GUID_WICPixelFormat32bppBGRA
,
1864 NULL
, /* no version */
1865 &GUID_VendorMicrosoft
,
1866 32, /* bitsperpixel */
1867 4, /* channel count */
1869 WICPixelFormatNumericRepresentationUnsignedInteger
,
1872 { &GUID_WICPixelFormat32bppPBGRA
,
1875 NULL
, /* no version */
1876 &GUID_VendorMicrosoft
,
1877 32, /* bitsperpixel */
1878 4, /* channel count */
1880 WICPixelFormatNumericRepresentationUnsignedInteger
,
1883 { &GUID_WICPixelFormat48bppRGB
,
1886 NULL
, /* no version */
1887 &GUID_VendorMicrosoft
,
1888 48, /* bitsperpixel */
1889 3, /* channel count */
1890 channel_masks_16bit
,
1891 WICPixelFormatNumericRepresentationUnsignedInteger
,
1894 { &GUID_WICPixelFormat64bppRGBA
,
1897 NULL
, /* no version */
1898 &GUID_VendorMicrosoft
,
1899 64, /* bitsperpixel */
1900 4, /* channel count */
1901 channel_masks_16bit
,
1902 WICPixelFormatNumericRepresentationUnsignedInteger
,
1905 { &GUID_WICPixelFormat64bppPRGBA
,
1908 NULL
, /* no version */
1909 &GUID_VendorMicrosoft
,
1910 64, /* bitsperpixel */
1911 4, /* channel count */
1912 channel_masks_16bit
,
1913 WICPixelFormatNumericRepresentationUnsignedInteger
,
1916 { &GUID_WICPixelFormat32bppCMYK
,
1919 NULL
, /* no version */
1920 &GUID_VendorMicrosoft
,
1921 32, /* bitsperpixel */
1922 4, /* channel count */
1924 WICPixelFormatNumericRepresentationUnsignedInteger
,
1927 { NULL
} /* list terminator */
1930 struct regsvr_category
1932 const CLSID
*clsid
; /* NULL for end of list */
1935 static const struct regsvr_category category_list
[] = {
1936 { &CATID_WICBitmapDecoders
},
1937 { &CATID_WICBitmapEncoders
},
1938 { &CATID_WICFormatConverters
},
1939 { &CATID_WICMetadataReader
},
1940 { &CATID_WICPixelFormats
},
1944 static HRESULT
register_categories(const struct regsvr_category
*list
)
1948 HKEY coclass_key
, categories_key
, instance_key
;
1950 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
1951 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
1952 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
1954 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
1955 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
1956 KEY_READ
| KEY_WRITE
, NULL
, &categories_key
, NULL
);
1957 if (res
!= ERROR_SUCCESS
)
1959 RegCloseKey(coclass_key
);
1960 return HRESULT_FROM_WIN32(res
);
1963 res
= RegCreateKeyExW(categories_key
, instance_keyname
, 0, NULL
, 0,
1964 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
1966 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
1968 HKEY instance_clsid_key
;
1970 StringFromGUID2(list
->clsid
, buf
, 39);
1971 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
1972 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
1973 if (res
== ERROR_SUCCESS
)
1975 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
1976 (const BYTE
*)buf
, 78);
1977 RegCloseKey(instance_clsid_key
);
1981 RegCloseKey(instance_key
);
1982 RegCloseKey(categories_key
);
1983 RegCloseKey(coclass_key
);
1985 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1988 static HRESULT
unregister_categories(const struct regsvr_category
*list
)
1992 HKEY coclass_key
, categories_key
, instance_key
;
1994 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
1995 KEY_READ
| KEY_WRITE
, &coclass_key
);
1996 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
1998 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
1999 res
= RegOpenKeyExW(coclass_key
, buf
, 0,
2000 KEY_READ
| KEY_WRITE
, &categories_key
);
2001 if (res
!= ERROR_SUCCESS
)
2003 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
2004 RegCloseKey(coclass_key
);
2005 return HRESULT_FROM_WIN32(res
);
2008 res
= RegOpenKeyExW(categories_key
, instance_keyname
, 0,
2009 KEY_READ
| KEY_WRITE
, &instance_key
);
2011 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
2013 StringFromGUID2(list
->clsid
, buf
, 39);
2014 res
= SHDeleteKeyW(instance_key
, buf
);
2017 RegCloseKey(instance_key
);
2018 RegCloseKey(categories_key
);
2020 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2021 res
= SHDeleteKeyW(coclass_key
, buf
);
2023 RegCloseKey(coclass_key
);
2025 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
2028 extern HRESULT WINAPI
WIC_DllRegisterServer(void) DECLSPEC_HIDDEN
;
2029 extern HRESULT WINAPI
WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
2031 HRESULT WINAPI
DllRegisterServer(void)
2037 hr
= WIC_DllRegisterServer();
2039 hr
= register_categories(category_list
);
2041 hr
= register_decoders(decoder_list
);
2043 hr
= register_encoders(encoder_list
);
2045 hr
= register_converters(converter_list
);
2047 hr
= register_metadatareaders(metadatareader_list
);
2049 hr
= register_pixelformats(pixelformat_list
);
2053 HRESULT WINAPI
DllUnregisterServer(void)
2059 hr
= WIC_DllUnregisterServer();
2061 hr
= unregister_categories(category_list
);
2063 hr
= unregister_decoders(decoder_list
);
2065 hr
= unregister_encoders(encoder_list
);
2067 hr
= unregister_converters(converter_list
);
2069 hr
= unregister_metadatareaders(metadatareader_list
);
2071 hr
= unregister_pixelformats(pixelformat_list
);