2 * Copyright 2009 Vincent Povirk for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
33 #include "wine/debug.h"
34 #include "wine/unicode.h"
36 #include "wincodecs_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
40 /***********************************************************************
41 * interface for self-registering
43 struct decoder_pattern
45 DWORD length
; /* 0 for end of list */
54 CLSID
const *clsid
; /* NULL for end of list */
59 GUID
const *container_format
;
62 GUID
const * const *formats
;
63 const struct decoder_pattern
*patterns
;
66 static HRESULT
register_decoders(struct regsvr_decoder
const *list
);
67 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
);
71 CLSID
const *clsid
; /* NULL for end of list */
76 GUID
const *container_format
;
79 GUID
const * const *formats
;
82 static HRESULT
register_encoders(struct regsvr_encoder
const *list
);
83 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
);
85 struct regsvr_converter
87 CLSID
const *clsid
; /* NULL for end of list */
92 GUID
const * const *formats
;
95 static HRESULT
register_converters(struct regsvr_converter
const *list
);
96 static HRESULT
unregister_converters(struct regsvr_converter
const *list
);
98 struct metadata_pattern
107 struct reader_containers
110 const struct metadata_pattern
*patterns
;
113 struct regsvr_metadatareader
115 CLSID
const *clsid
; /* NULL for end of list */
121 GUID
const *metadata_format
;
122 DWORD requires_fullstream
;
123 DWORD supports_padding
;
124 DWORD requires_fixedsize
;
125 const struct reader_containers
*containers
;
128 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
);
129 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
);
131 struct regsvr_pixelformat
133 CLSID
const *clsid
; /* NULL for end of list */
140 BYTE
const * const *channelmasks
;
141 WICPixelFormatNumericRepresentation numericrepresentation
;
145 static HRESULT
register_pixelformats(struct regsvr_pixelformat
const *list
);
146 static HRESULT
unregister_pixelformats(struct regsvr_pixelformat
const *list
);
148 /***********************************************************************
149 * static string constants
151 static const WCHAR clsid_keyname
[] = {
152 'C', 'L', 'S', 'I', 'D', 0 };
153 static const char author_valuename
[] = "Author";
154 static const char friendlyname_valuename
[] = "FriendlyName";
155 static const WCHAR vendor_valuename
[] = {'V','e','n','d','o','r',0};
156 static const WCHAR containerformat_valuename
[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
157 static const char version_valuename
[] = "Version";
158 static const char mimetypes_valuename
[] = "MimeTypes";
159 static const char extensions_valuename
[] = "FileExtensions";
160 static const WCHAR formats_keyname
[] = {'F','o','r','m','a','t','s',0};
161 static const WCHAR patterns_keyname
[] = {'P','a','t','t','e','r','n','s',0};
162 static const WCHAR instance_keyname
[] = {'I','n','s','t','a','n','c','e',0};
163 static const WCHAR clsid_valuename
[] = {'C','L','S','I','D',0};
164 static const char length_valuename
[] = "Length";
165 static const char position_valuename
[] = "Position";
166 static const char pattern_valuename
[] = "Pattern";
167 static const char mask_valuename
[] = "Mask";
168 static const char endofstream_valuename
[] = "EndOfStream";
169 static const WCHAR pixelformats_keyname
[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
170 static const WCHAR metadataformat_valuename
[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
171 static const char specversion_valuename
[] = "SpecVersion";
172 static const char requiresfullstream_valuename
[] = "RequiresFullStream";
173 static const char supportspadding_valuename
[] = "SupportsPadding";
174 static const char requiresfixedsize_valuename
[] = "FixedSize";
175 static const WCHAR containers_keyname
[] = {'C','o','n','t','a','i','n','e','r','s',0};
176 static const char dataoffset_valuename
[] = "DataOffset";
177 static const char bitsperpixel_valuename
[] = "BitLength";
178 static const char channelcount_valuename
[] = "ChannelCount";
179 static const char numericrepresentation_valuename
[] = "NumericRepresentation";
180 static const char supportstransparency_valuename
[] = "SupportsTransparency";
181 static const WCHAR channelmasks_keyname
[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
183 /***********************************************************************
186 static HRESULT
register_decoders(struct regsvr_decoder
const *list
)
188 LONG res
= ERROR_SUCCESS
;
194 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
195 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
196 if (res
== ERROR_SUCCESS
) {
197 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
198 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
199 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
200 if (res
== ERROR_SUCCESS
)
202 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
203 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
204 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
206 if (res
!= ERROR_SUCCESS
)
207 RegCloseKey(coclass_key
);
209 if (res
!= ERROR_SUCCESS
) goto error_return
;
211 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
213 HKEY instance_clsid_key
;
215 StringFromGUID2(list
->clsid
, buf
, 39);
216 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
217 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
218 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
220 StringFromGUID2(list
->clsid
, buf
, 39);
221 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
222 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
223 if (res
== ERROR_SUCCESS
) {
224 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
225 (const BYTE
*)buf
, 78);
226 RegCloseKey(instance_clsid_key
);
228 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
231 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
232 (const BYTE
*)list
->author
,
233 strlen(list
->author
) + 1);
234 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
237 if (list
->friendlyname
) {
238 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
239 (const BYTE
*)list
->friendlyname
,
240 strlen(list
->friendlyname
) + 1);
241 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
245 StringFromGUID2(list
->vendor
, buf
, 39);
246 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
247 (const BYTE
*)buf
, 78);
248 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
251 if (list
->container_format
) {
252 StringFromGUID2(list
->container_format
, buf
, 39);
253 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
254 (const BYTE
*)buf
, 78);
255 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
259 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
260 (const BYTE
*)list
->version
,
261 strlen(list
->version
) + 1);
262 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
265 if (list
->mimetypes
) {
266 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
267 (const BYTE
*)list
->mimetypes
,
268 strlen(list
->mimetypes
) + 1);
269 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
272 if (list
->extensions
) {
273 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
274 (const BYTE
*)list
->extensions
,
275 strlen(list
->extensions
) + 1);
276 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
281 GUID
const * const *format
;
283 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
284 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
285 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
286 for (format
=list
->formats
; *format
; ++format
)
289 StringFromGUID2(*format
, buf
, 39);
290 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
291 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
292 if (res
!= ERROR_SUCCESS
) break;
293 RegCloseKey(format_key
);
295 RegCloseKey(formats_key
);
296 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
299 if (list
->patterns
) {
303 res
= RegCreateKeyExW(clsid_key
, patterns_keyname
, 0, NULL
, 0,
304 KEY_READ
| KEY_WRITE
, NULL
, &patterns_key
, NULL
);
305 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
306 for (i
=0; list
->patterns
[i
].length
; i
++)
309 static const WCHAR int_format
[] = {'%','i',0};
310 snprintfW(buf
, 39, int_format
, i
);
311 res
= RegCreateKeyExW(patterns_key
, buf
, 0, NULL
, 0,
312 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
313 if (res
!= ERROR_SUCCESS
) break;
314 res
= RegSetValueExA(pattern_key
, length_valuename
, 0, REG_DWORD
,
315 (const BYTE
*)&list
->patterns
[i
].length
, 4);
316 if (res
== ERROR_SUCCESS
)
317 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
318 (const BYTE
*)&list
->patterns
[i
].position
, 4);
319 if (res
== ERROR_SUCCESS
)
320 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
321 list
->patterns
[i
].pattern
,
322 list
->patterns
[i
].length
);
323 if (res
== ERROR_SUCCESS
)
324 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
325 list
->patterns
[i
].mask
,
326 list
->patterns
[i
].length
);
327 if (res
== ERROR_SUCCESS
)
328 res
= RegSetValueExA(pattern_key
, endofstream_valuename
, 0, REG_DWORD
,
329 (const BYTE
*)&list
->patterns
[i
].endofstream
, 4);
330 RegCloseKey(pattern_key
);
332 RegCloseKey(patterns_key
);
333 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
336 error_close_clsid_key
:
337 RegCloseKey(clsid_key
);
340 error_close_coclass_key
:
341 RegCloseKey(instance_key
);
342 RegCloseKey(decoders_key
);
343 RegCloseKey(coclass_key
);
345 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
348 /***********************************************************************
349 * unregister_decoders
351 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
)
353 LONG res
= ERROR_SUCCESS
;
359 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
360 KEY_READ
| KEY_WRITE
, &coclass_key
);
361 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
363 if (res
== ERROR_SUCCESS
) {
364 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
365 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
366 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
367 if (res
== ERROR_SUCCESS
)
369 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
370 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
371 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
373 if (res
!= ERROR_SUCCESS
)
374 RegCloseKey(coclass_key
);
376 if (res
!= ERROR_SUCCESS
) goto error_return
;
378 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
379 StringFromGUID2(list
->clsid
, buf
, 39);
381 res
= RegDeleteTreeW(coclass_key
, buf
);
382 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
383 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
385 res
= RegDeleteTreeW(instance_key
, buf
);
386 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
387 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
390 error_close_coclass_key
:
391 RegCloseKey(instance_key
);
392 RegCloseKey(decoders_key
);
393 RegCloseKey(coclass_key
);
395 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
398 /***********************************************************************
401 static HRESULT
register_encoders(struct regsvr_encoder
const *list
)
403 LONG res
= ERROR_SUCCESS
;
409 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
410 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
411 if (res
== ERROR_SUCCESS
) {
412 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
413 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
414 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
415 if (res
== ERROR_SUCCESS
)
417 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
418 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
419 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
421 if (res
!= ERROR_SUCCESS
)
422 RegCloseKey(coclass_key
);
424 if (res
!= ERROR_SUCCESS
) goto error_return
;
426 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
428 HKEY instance_clsid_key
;
430 StringFromGUID2(list
->clsid
, buf
, 39);
431 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
432 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
433 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
435 StringFromGUID2(list
->clsid
, buf
, 39);
436 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
437 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
438 if (res
== ERROR_SUCCESS
) {
439 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
440 (const BYTE
*)buf
, 78);
441 RegCloseKey(instance_clsid_key
);
443 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
446 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
447 (const BYTE
*)list
->author
,
448 strlen(list
->author
) + 1);
449 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
452 if (list
->friendlyname
) {
453 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
454 (const BYTE
*)list
->friendlyname
,
455 strlen(list
->friendlyname
) + 1);
456 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
460 StringFromGUID2(list
->vendor
, buf
, 39);
461 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
462 (const BYTE
*)buf
, 78);
463 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
466 if (list
->container_format
) {
467 StringFromGUID2(list
->container_format
, buf
, 39);
468 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
469 (const BYTE
*)buf
, 78);
470 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
474 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
475 (const BYTE
*)list
->version
,
476 strlen(list
->version
) + 1);
477 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
480 if (list
->mimetypes
) {
481 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
482 (const BYTE
*)list
->mimetypes
,
483 strlen(list
->mimetypes
) + 1);
484 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
487 if (list
->extensions
) {
488 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
489 (const BYTE
*)list
->extensions
,
490 strlen(list
->extensions
) + 1);
491 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
496 GUID
const * const *format
;
498 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
499 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
500 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
501 for (format
=list
->formats
; *format
; ++format
)
504 StringFromGUID2(*format
, buf
, 39);
505 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
506 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
507 if (res
!= ERROR_SUCCESS
) break;
508 RegCloseKey(format_key
);
510 RegCloseKey(formats_key
);
511 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
514 error_close_clsid_key
:
515 RegCloseKey(clsid_key
);
518 error_close_coclass_key
:
519 RegCloseKey(instance_key
);
520 RegCloseKey(encoders_key
);
521 RegCloseKey(coclass_key
);
523 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
526 /***********************************************************************
527 * unregister_encoders
529 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
)
531 LONG res
= ERROR_SUCCESS
;
537 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
538 KEY_READ
| KEY_WRITE
, &coclass_key
);
539 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
541 if (res
== ERROR_SUCCESS
) {
542 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
543 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
544 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
545 if (res
== ERROR_SUCCESS
)
547 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
548 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
549 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
551 if (res
!= ERROR_SUCCESS
)
552 RegCloseKey(coclass_key
);
554 if (res
!= ERROR_SUCCESS
) goto error_return
;
556 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
557 StringFromGUID2(list
->clsid
, buf
, 39);
559 res
= RegDeleteTreeW(coclass_key
, buf
);
560 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
561 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
563 res
= RegDeleteTreeW(instance_key
, buf
);
564 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
565 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
568 error_close_coclass_key
:
569 RegCloseKey(instance_key
);
570 RegCloseKey(encoders_key
);
571 RegCloseKey(coclass_key
);
573 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
576 /***********************************************************************
577 * register_converters
579 static HRESULT
register_converters(struct regsvr_converter
const *list
)
581 LONG res
= ERROR_SUCCESS
;
587 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
588 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
589 if (res
== ERROR_SUCCESS
) {
590 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
591 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
592 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
593 if (res
== ERROR_SUCCESS
)
595 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
596 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
597 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
599 if (res
!= ERROR_SUCCESS
)
600 RegCloseKey(coclass_key
);
602 if (res
!= ERROR_SUCCESS
) goto error_return
;
604 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
606 HKEY instance_clsid_key
;
608 StringFromGUID2(list
->clsid
, buf
, 39);
609 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
610 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
611 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
613 StringFromGUID2(list
->clsid
, buf
, 39);
614 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
615 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
616 if (res
== ERROR_SUCCESS
) {
617 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
618 (const BYTE
*)buf
, 78);
619 RegCloseKey(instance_clsid_key
);
621 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
624 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
625 (const BYTE
*)list
->author
,
626 strlen(list
->author
) + 1);
627 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
630 if (list
->friendlyname
) {
631 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
632 (const BYTE
*)list
->friendlyname
,
633 strlen(list
->friendlyname
) + 1);
634 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
638 StringFromGUID2(list
->vendor
, buf
, 39);
639 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
640 (const BYTE
*)buf
, 78);
641 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
645 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
646 (const BYTE
*)list
->version
,
647 strlen(list
->version
) + 1);
648 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
653 GUID
const * const *format
;
655 res
= RegCreateKeyExW(clsid_key
, pixelformats_keyname
, 0, NULL
, 0,
656 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
657 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
658 for (format
=list
->formats
; *format
; ++format
)
661 StringFromGUID2(*format
, buf
, 39);
662 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
663 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
664 if (res
!= ERROR_SUCCESS
) break;
665 RegCloseKey(format_key
);
667 RegCloseKey(formats_key
);
668 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
671 error_close_clsid_key
:
672 RegCloseKey(clsid_key
);
675 error_close_coclass_key
:
676 RegCloseKey(instance_key
);
677 RegCloseKey(converters_key
);
678 RegCloseKey(coclass_key
);
680 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
683 /***********************************************************************
684 * unregister_converters
686 static HRESULT
unregister_converters(struct regsvr_converter
const *list
)
688 LONG res
= ERROR_SUCCESS
;
694 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
695 KEY_READ
| KEY_WRITE
, &coclass_key
);
696 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
698 if (res
== ERROR_SUCCESS
) {
699 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
700 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
701 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
702 if (res
== ERROR_SUCCESS
)
704 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
705 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
706 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
708 if (res
!= ERROR_SUCCESS
)
709 RegCloseKey(coclass_key
);
711 if (res
!= ERROR_SUCCESS
) goto error_return
;
713 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
714 StringFromGUID2(list
->clsid
, buf
, 39);
716 res
= RegDeleteTreeW(coclass_key
, buf
);
717 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
718 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
720 res
= RegDeleteTreeW(instance_key
, buf
);
721 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
722 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
725 error_close_coclass_key
:
726 RegCloseKey(instance_key
);
727 RegCloseKey(converters_key
);
728 RegCloseKey(coclass_key
);
730 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
733 /***********************************************************************
734 * register_metadatareaders
736 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
)
738 LONG res
= ERROR_SUCCESS
;
744 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
745 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
746 if (res
== ERROR_SUCCESS
) {
747 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
748 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
749 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
750 if (res
== ERROR_SUCCESS
)
752 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
753 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
754 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
756 if (res
!= ERROR_SUCCESS
)
757 RegCloseKey(coclass_key
);
759 if (res
!= ERROR_SUCCESS
) goto error_return
;
761 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
763 HKEY instance_clsid_key
;
765 StringFromGUID2(list
->clsid
, buf
, 39);
766 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
767 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
768 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
770 StringFromGUID2(list
->clsid
, buf
, 39);
771 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
772 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
773 if (res
== ERROR_SUCCESS
) {
774 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
775 (const BYTE
*)buf
, 78);
776 RegCloseKey(instance_clsid_key
);
778 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
781 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
782 (const BYTE
*)list
->author
,
783 strlen(list
->author
) + 1);
784 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
787 if (list
->friendlyname
) {
788 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
789 (const BYTE
*)list
->friendlyname
,
790 strlen(list
->friendlyname
) + 1);
791 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
795 StringFromGUID2(list
->vendor
, buf
, 39);
796 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
797 (const BYTE
*)buf
, 78);
798 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
801 if (list
->metadata_format
) {
802 StringFromGUID2(list
->metadata_format
, buf
, 39);
803 res
= RegSetValueExW(clsid_key
, metadataformat_valuename
, 0, REG_SZ
,
804 (const BYTE
*)buf
, 78);
805 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
809 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
810 (const BYTE
*)list
->version
,
811 strlen(list
->version
) + 1);
812 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
815 if (list
->specversion
) {
816 res
= RegSetValueExA(clsid_key
, specversion_valuename
, 0, REG_SZ
,
817 (const BYTE
*)list
->version
,
818 strlen(list
->version
) + 1);
819 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
822 res
= RegSetValueExA(clsid_key
, requiresfullstream_valuename
, 0, REG_DWORD
,
823 (const BYTE
*)&list
->requires_fullstream
, 4);
824 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
826 res
= RegSetValueExA(clsid_key
, supportspadding_valuename
, 0, REG_DWORD
,
827 (const BYTE
*)&list
->supports_padding
, 4);
828 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
830 if (list
->requires_fixedsize
) {
831 res
= RegSetValueExA(clsid_key
, requiresfixedsize_valuename
, 0, REG_DWORD
,
832 (const BYTE
*)&list
->requires_fixedsize
, 4);
833 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
836 if (list
->containers
) {
838 const struct reader_containers
*container
;
840 res
= RegCreateKeyExW(clsid_key
, containers_keyname
, 0, NULL
, 0,
841 KEY_READ
| KEY_WRITE
, NULL
, &containers_key
, NULL
);
842 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
843 for (container
=list
->containers
; container
->format
; ++container
)
847 StringFromGUID2(container
->format
, buf
, 39);
848 res
= RegCreateKeyExW(containers_key
, buf
, 0, NULL
, 0,
849 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
850 if (res
!= ERROR_SUCCESS
) break;
852 for (i
=0; container
->patterns
[i
].length
; i
++)
855 static const WCHAR int_format
[] = {'%','i',0};
856 snprintfW(buf
, 39, int_format
, i
);
857 res
= RegCreateKeyExW(format_key
, buf
, 0, NULL
, 0,
858 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
859 if (res
!= ERROR_SUCCESS
) break;
860 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
861 (const BYTE
*)&container
->patterns
[i
].position
, 4);
862 if (res
== ERROR_SUCCESS
)
863 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
864 container
->patterns
[i
].pattern
,
865 container
->patterns
[i
].length
);
866 if (res
== ERROR_SUCCESS
)
867 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
868 container
->patterns
[i
].mask
,
869 container
->patterns
[i
].length
);
870 if (res
== ERROR_SUCCESS
&& container
->patterns
[i
].data_offset
)
871 res
= RegSetValueExA(pattern_key
, dataoffset_valuename
, 0, REG_DWORD
,
872 (const BYTE
*)&container
->patterns
[i
].data_offset
, 4);
873 RegCloseKey(pattern_key
);
876 RegCloseKey(format_key
);
878 RegCloseKey(containers_key
);
881 error_close_clsid_key
:
882 RegCloseKey(clsid_key
);
885 error_close_coclass_key
:
886 RegCloseKey(instance_key
);
887 RegCloseKey(readers_key
);
888 RegCloseKey(coclass_key
);
890 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
893 /***********************************************************************
894 * unregister_metadatareaders
896 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
)
898 LONG res
= ERROR_SUCCESS
;
904 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
905 KEY_READ
| KEY_WRITE
, &coclass_key
);
906 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
908 if (res
== ERROR_SUCCESS
) {
909 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
910 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
911 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
912 if (res
== ERROR_SUCCESS
)
914 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
915 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
916 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
918 if (res
!= ERROR_SUCCESS
)
919 RegCloseKey(coclass_key
);
921 if (res
!= ERROR_SUCCESS
) goto error_return
;
923 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
924 StringFromGUID2(list
->clsid
, buf
, 39);
926 res
= RegDeleteTreeW(coclass_key
, buf
);
927 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
928 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
930 res
= RegDeleteTreeW(instance_key
, buf
);
931 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
932 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
935 error_close_coclass_key
:
936 RegCloseKey(instance_key
);
937 RegCloseKey(readers_key
);
938 RegCloseKey(coclass_key
);
940 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
943 /***********************************************************************
944 * register_pixelformats
946 static HRESULT
register_pixelformats(struct regsvr_pixelformat
const *list
)
948 LONG res
= ERROR_SUCCESS
;
954 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
955 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
956 if (res
== ERROR_SUCCESS
) {
957 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
958 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
959 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
960 if (res
== ERROR_SUCCESS
)
962 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
963 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
964 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
966 if (res
!= ERROR_SUCCESS
)
967 RegCloseKey(coclass_key
);
969 if (res
!= ERROR_SUCCESS
) goto error_return
;
971 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
973 HKEY instance_clsid_key
;
975 StringFromGUID2(list
->clsid
, buf
, 39);
976 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
977 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
978 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
980 StringFromGUID2(list
->clsid
, buf
, 39);
981 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
982 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
983 if (res
== ERROR_SUCCESS
) {
984 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
985 (const BYTE
*)buf
, 78);
986 RegCloseKey(instance_clsid_key
);
988 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
991 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
992 (const BYTE
*)list
->author
,
993 strlen(list
->author
) + 1);
994 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
997 if (list
->friendlyname
) {
998 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
999 (const BYTE
*)list
->friendlyname
,
1000 strlen(list
->friendlyname
) + 1);
1001 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1005 StringFromGUID2(list
->vendor
, buf
, 39);
1006 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
1007 (const BYTE
*)buf
, 78);
1008 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1011 if (list
->version
) {
1012 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
1013 (const BYTE
*)list
->version
,
1014 strlen(list
->version
) + 1);
1015 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1018 res
= RegSetValueExA(clsid_key
, bitsperpixel_valuename
, 0, REG_DWORD
,
1019 (const BYTE
*)&list
->bitsperpixel
, 4);
1020 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1022 res
= RegSetValueExA(clsid_key
, channelcount_valuename
, 0, REG_DWORD
,
1023 (const BYTE
*)&list
->channelcount
, 4);
1024 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1026 res
= RegSetValueExA(clsid_key
, numericrepresentation_valuename
, 0, REG_DWORD
,
1027 (const BYTE
*)&list
->numericrepresentation
, 4);
1028 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1030 res
= RegSetValueExA(clsid_key
, supportstransparency_valuename
, 0, REG_DWORD
,
1031 (const BYTE
*)&list
->supportsalpha
, 4);
1032 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1034 if (list
->channelmasks
) {
1035 static const WCHAR valuename_format
[] = {'%','d',0};
1038 WCHAR mask_valuename
[11];
1040 mask_size
= (list
->bitsperpixel
+ 7)/8;
1042 res
= RegCreateKeyExW(clsid_key
, channelmasks_keyname
, 0, NULL
, 0,
1043 KEY_READ
| KEY_WRITE
, NULL
, &masks_key
, NULL
);
1044 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1045 for (i
=0; i
< list
->channelcount
; i
++)
1047 sprintfW(mask_valuename
, valuename_format
, i
);
1048 res
= RegSetValueExW(masks_key
, mask_valuename
, 0, REG_BINARY
,
1049 list
->channelmasks
[i
], mask_size
);
1050 if (res
!= ERROR_SUCCESS
) break;
1052 RegCloseKey(masks_key
);
1053 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
1056 error_close_clsid_key
:
1057 RegCloseKey(clsid_key
);
1060 error_close_coclass_key
:
1061 RegCloseKey(instance_key
);
1062 RegCloseKey(formats_key
);
1063 RegCloseKey(coclass_key
);
1065 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1068 /***********************************************************************
1069 * unregister_pixelformats
1071 static HRESULT
unregister_pixelformats(struct regsvr_pixelformat
const *list
)
1073 LONG res
= ERROR_SUCCESS
;
1079 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
1080 KEY_READ
| KEY_WRITE
, &coclass_key
);
1081 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
1083 if (res
== ERROR_SUCCESS
) {
1084 StringFromGUID2(&CATID_WICPixelFormats
, buf
, 39);
1085 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
1086 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
1087 if (res
== ERROR_SUCCESS
)
1089 res
= RegCreateKeyExW(formats_key
, instance_keyname
, 0, NULL
, 0,
1090 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
1091 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1093 if (res
!= ERROR_SUCCESS
)
1094 RegCloseKey(coclass_key
);
1096 if (res
!= ERROR_SUCCESS
) goto error_return
;
1098 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
1099 StringFromGUID2(list
->clsid
, buf
, 39);
1101 res
= RegDeleteTreeW(coclass_key
, buf
);
1102 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1103 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1105 res
= RegDeleteTreeW(instance_key
, buf
);
1106 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
1107 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
1110 error_close_coclass_key
:
1111 RegCloseKey(instance_key
);
1112 RegCloseKey(formats_key
);
1113 RegCloseKey(coclass_key
);
1115 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
1118 /***********************************************************************
1121 static const BYTE mask_all
[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1123 static const BYTE bmp_magic
[] = {0x42,0x4d};
1125 static GUID
const * const bmp_formats
[] = {
1126 &GUID_WICPixelFormat1bppIndexed
,
1127 &GUID_WICPixelFormat2bppIndexed
,
1128 &GUID_WICPixelFormat4bppIndexed
,
1129 &GUID_WICPixelFormat8bppIndexed
,
1130 &GUID_WICPixelFormat16bppBGR555
,
1131 &GUID_WICPixelFormat16bppBGR565
,
1132 &GUID_WICPixelFormat24bppBGR
,
1133 &GUID_WICPixelFormat32bppBGR
,
1134 &GUID_WICPixelFormat32bppBGRA
,
1138 static struct decoder_pattern
const bmp_patterns
[] = {
1139 {2,0,bmp_magic
,mask_all
,0},
1143 static const BYTE dds_magic
[] = "DDS ";
1145 static GUID
const * const dds_formats
[] = {
1146 &GUID_WICPixelFormat32bppBGRA
,
1150 static struct decoder_pattern
const dds_patterns
[] = {
1151 {4,0,dds_magic
,mask_all
,0},
1155 static const BYTE gif87a_magic
[6] = "GIF87a";
1156 static const BYTE gif89a_magic
[6] = "GIF89a";
1158 static GUID
const * const gif_formats
[] = {
1159 &GUID_WICPixelFormat8bppIndexed
,
1163 static struct decoder_pattern
const gif_patterns
[] = {
1164 {6,0,gif87a_magic
,mask_all
,0},
1165 {6,0,gif89a_magic
,mask_all
,0},
1169 static const BYTE ico_magic
[] = {00,00,01,00};
1171 static GUID
const * const ico_formats
[] = {
1172 &GUID_WICPixelFormat32bppBGRA
,
1176 static struct decoder_pattern
const ico_patterns
[] = {
1177 {4,0,ico_magic
,mask_all
,0},
1181 static const BYTE jpeg_magic
[] = {0xff, 0xd8};
1183 static GUID
const * const jpeg_formats
[] = {
1184 &GUID_WICPixelFormat24bppBGR
,
1185 &GUID_WICPixelFormat32bppCMYK
,
1186 &GUID_WICPixelFormat8bppGray
,
1190 static struct decoder_pattern
const jpeg_patterns
[] = {
1191 {2,0,jpeg_magic
,mask_all
,0},
1195 static const BYTE wmp_magic_v0
[] = {0x49, 0x49, 0xbc, 0x00};
1196 static const BYTE wmp_magic_v1
[] = {0x49, 0x49, 0xbc, 0x01};
1198 static GUID
const * const wmp_formats
[] = {
1199 &GUID_WICPixelFormat128bppRGBAFixedPoint
,
1200 &GUID_WICPixelFormat128bppRGBAFloat
,
1201 &GUID_WICPixelFormat128bppRGBFloat
,
1202 &GUID_WICPixelFormat16bppBGR555
,
1203 &GUID_WICPixelFormat16bppBGR565
,
1204 &GUID_WICPixelFormat16bppGray
,
1205 &GUID_WICPixelFormat16bppGrayFixedPoint
,
1206 &GUID_WICPixelFormat16bppGrayHalf
,
1207 &GUID_WICPixelFormat24bppBGR
,
1208 &GUID_WICPixelFormat24bppRGB
,
1209 &GUID_WICPixelFormat32bppBGR
,
1210 &GUID_WICPixelFormat32bppBGR101010
,
1211 &GUID_WICPixelFormat32bppBGRA
,
1212 &GUID_WICPixelFormat32bppCMYK
,
1213 &GUID_WICPixelFormat32bppGrayFixedPoint
,
1214 &GUID_WICPixelFormat32bppGrayFloat
,
1215 &GUID_WICPixelFormat32bppRGBE
,
1216 &GUID_WICPixelFormat40bppCMYKAlpha
,
1217 &GUID_WICPixelFormat48bppRGB
,
1218 &GUID_WICPixelFormat48bppRGBFixedPoint
,
1219 &GUID_WICPixelFormat48bppRGBHalf
,
1220 &GUID_WICPixelFormat64bppCMYK
,
1221 &GUID_WICPixelFormat64bppRGBA
,
1222 &GUID_WICPixelFormat64bppRGBAFixedPoint
,
1223 &GUID_WICPixelFormat64bppRGBAHalf
,
1224 &GUID_WICPixelFormat80bppCMYKAlpha
,
1225 &GUID_WICPixelFormat8bppGray
,
1226 &GUID_WICPixelFormat96bppRGBFixedPoint
,
1227 &GUID_WICPixelFormatBlackWhite
,
1231 static struct decoder_pattern
const wmp_patterns
[] = {
1232 {4,0,wmp_magic_v0
,mask_all
,0},
1233 {4,0,wmp_magic_v1
,mask_all
,0},
1237 static const BYTE png_magic
[] = {137,80,78,71,13,10,26,10};
1239 static GUID
const * const png_formats
[] = {
1240 &GUID_WICPixelFormatBlackWhite
,
1241 &GUID_WICPixelFormat2bppGray
,
1242 &GUID_WICPixelFormat4bppGray
,
1243 &GUID_WICPixelFormat8bppGray
,
1244 &GUID_WICPixelFormat16bppGray
,
1245 &GUID_WICPixelFormat32bppBGRA
,
1246 &GUID_WICPixelFormat64bppRGBA
,
1247 &GUID_WICPixelFormat1bppIndexed
,
1248 &GUID_WICPixelFormat2bppIndexed
,
1249 &GUID_WICPixelFormat4bppIndexed
,
1250 &GUID_WICPixelFormat8bppIndexed
,
1251 &GUID_WICPixelFormat24bppBGR
,
1252 &GUID_WICPixelFormat48bppRGB
,
1256 static struct decoder_pattern
const png_patterns
[] = {
1257 {8,0,png_magic
,mask_all
,0},
1261 static const BYTE tiff_magic_le
[] = {0x49,0x49,42,0};
1262 static const BYTE tiff_magic_be
[] = {0x4d,0x4d,0,42};
1264 static GUID
const * const tiff_decode_formats
[] = {
1265 &GUID_WICPixelFormatBlackWhite
,
1266 &GUID_WICPixelFormat4bppGray
,
1267 &GUID_WICPixelFormat8bppGray
,
1268 &GUID_WICPixelFormat16bppGray
,
1269 &GUID_WICPixelFormat32bppGrayFloat
,
1270 &GUID_WICPixelFormat1bppIndexed
,
1271 &GUID_WICPixelFormat2bppIndexed
,
1272 &GUID_WICPixelFormat4bppIndexed
,
1273 &GUID_WICPixelFormat8bppIndexed
,
1274 &GUID_WICPixelFormat24bppBGR
,
1275 &GUID_WICPixelFormat32bppBGR
,
1276 &GUID_WICPixelFormat32bppBGRA
,
1277 &GUID_WICPixelFormat32bppPBGRA
,
1278 &GUID_WICPixelFormat48bppRGB
,
1279 &GUID_WICPixelFormat64bppRGBA
,
1280 &GUID_WICPixelFormat64bppPRGBA
,
1281 &GUID_WICPixelFormat32bppCMYK
,
1282 &GUID_WICPixelFormat64bppCMYK
,
1283 &GUID_WICPixelFormat96bppRGBFloat
,
1284 &GUID_WICPixelFormat128bppRGBAFloat
,
1285 &GUID_WICPixelFormat128bppPRGBAFloat
,
1289 static struct decoder_pattern
const tiff_patterns
[] = {
1290 {4,0,tiff_magic_le
,mask_all
,0},
1291 {4,0,tiff_magic_be
,mask_all
,0},
1295 static const BYTE tga_footer_magic
[18] = "TRUEVISION-XFILE.";
1297 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};
1298 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};
1300 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};
1301 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};
1303 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};
1304 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};
1306 static GUID
const * const tga_formats
[] = {
1307 &GUID_WICPixelFormat8bppGray
,
1308 &GUID_WICPixelFormat8bppIndexed
,
1309 &GUID_WICPixelFormat16bppGray
,
1310 &GUID_WICPixelFormat16bppBGR555
,
1311 &GUID_WICPixelFormat24bppBGR
,
1312 &GUID_WICPixelFormat32bppBGRA
,
1313 &GUID_WICPixelFormat32bppPBGRA
,
1317 static struct decoder_pattern
const tga_patterns
[] = {
1318 {18,18,tga_footer_magic
,mask_all
,1},
1319 {18,0,tga_indexed_magic
,tga_indexed_mask
,0},
1320 {18,0,tga_truecolor_magic
,tga_truecolor_mask
,0},
1321 {18,0,tga_grayscale_magic
,tga_grayscale_mask
,0},
1325 static struct regsvr_decoder
const decoder_list
[] = {
1326 { &CLSID_WICBmpDecoder
,
1330 &GUID_VendorMicrosoft
,
1331 &GUID_ContainerFormatBmp
,
1337 { &CLSID_WICDdsDecoder
,
1341 &GUID_VendorMicrosoft
,
1342 &GUID_ContainerFormatDds
,
1348 { &CLSID_WICGifDecoder
,
1352 &GUID_VendorMicrosoft
,
1353 &GUID_ContainerFormatGif
,
1359 { &CLSID_WICIcoDecoder
,
1363 &GUID_VendorMicrosoft
,
1364 &GUID_ContainerFormatIco
,
1365 "image/vnd.microsoft.icon",
1370 { &CLSID_WICJpegDecoder
,
1374 &GUID_VendorMicrosoft
,
1375 &GUID_ContainerFormatJpeg
,
1381 { &CLSID_WICWmpDecoder
,
1385 &GUID_VendorMicrosoft
,
1386 &GUID_ContainerFormatWmp
,
1392 { &CLSID_WICPngDecoder
,
1396 &GUID_VendorMicrosoft
,
1397 &GUID_ContainerFormatPng
,
1403 { &CLSID_WICTiffDecoder
,
1407 &GUID_VendorMicrosoft
,
1408 &GUID_ContainerFormatTiff
,
1411 tiff_decode_formats
,
1414 { &CLSID_WineTgaDecoder
,
1419 &GUID_WineContainerFormatTga
,
1425 { NULL
} /* list terminator */
1428 static GUID
const * const bmp_encode_formats
[] = {
1429 &GUID_WICPixelFormat16bppBGR555
,
1430 &GUID_WICPixelFormat16bppBGR565
,
1431 &GUID_WICPixelFormat24bppBGR
,
1432 &GUID_WICPixelFormat32bppBGR
,
1433 &GUID_WICPixelFormatBlackWhite
,
1434 &GUID_WICPixelFormat1bppIndexed
,
1435 &GUID_WICPixelFormat4bppIndexed
,
1436 &GUID_WICPixelFormat8bppIndexed
,
1440 static GUID
const * const png_encode_formats
[] = {
1441 &GUID_WICPixelFormat24bppBGR
,
1442 &GUID_WICPixelFormatBlackWhite
,
1443 &GUID_WICPixelFormat2bppGray
,
1444 &GUID_WICPixelFormat4bppGray
,
1445 &GUID_WICPixelFormat8bppGray
,
1446 &GUID_WICPixelFormat16bppGray
,
1447 &GUID_WICPixelFormat32bppBGR
,
1448 &GUID_WICPixelFormat32bppBGRA
,
1449 &GUID_WICPixelFormat48bppRGB
,
1450 &GUID_WICPixelFormat64bppRGBA
,
1451 &GUID_WICPixelFormat1bppIndexed
,
1452 &GUID_WICPixelFormat2bppIndexed
,
1453 &GUID_WICPixelFormat4bppIndexed
,
1454 &GUID_WICPixelFormat8bppIndexed
,
1458 static GUID
const * const tiff_encode_formats
[] = {
1459 &GUID_WICPixelFormatBlackWhite
,
1460 &GUID_WICPixelFormat4bppGray
,
1461 &GUID_WICPixelFormat8bppGray
,
1462 &GUID_WICPixelFormat1bppIndexed
,
1463 &GUID_WICPixelFormat4bppIndexed
,
1464 &GUID_WICPixelFormat8bppIndexed
,
1465 &GUID_WICPixelFormat24bppBGR
,
1466 &GUID_WICPixelFormat32bppBGRA
,
1467 &GUID_WICPixelFormat32bppPBGRA
,
1468 &GUID_WICPixelFormat48bppRGB
,
1469 &GUID_WICPixelFormat64bppRGBA
,
1470 &GUID_WICPixelFormat64bppPRGBA
,
1474 static GUID
const * const icns_encode_formats
[] = {
1475 &GUID_WICPixelFormat32bppBGRA
,
1479 static struct regsvr_encoder
const encoder_list
[] = {
1480 { &CLSID_WICBmpEncoder
,
1484 &GUID_VendorMicrosoft
,
1485 &GUID_ContainerFormatBmp
,
1490 { &CLSID_WICGifEncoder
,
1494 &GUID_VendorMicrosoft
,
1495 &GUID_ContainerFormatGif
,
1500 { &CLSID_WICJpegEncoder
,
1504 &GUID_VendorMicrosoft
,
1505 &GUID_ContainerFormatJpeg
,
1510 { &CLSID_WICPngEncoder
,
1514 &GUID_VendorMicrosoft
,
1515 &GUID_ContainerFormatPng
,
1520 { &CLSID_WICTiffEncoder
,
1524 &GUID_VendorMicrosoft
,
1525 &GUID_ContainerFormatTiff
,
1530 { &CLSID_WICIcnsEncoder
,
1535 NULL
, /* no container format guid */
1540 { NULL
} /* list terminator */
1543 static GUID
const * const converter_formats
[] = {
1544 &GUID_WICPixelFormat1bppIndexed
,
1545 &GUID_WICPixelFormat2bppIndexed
,
1546 &GUID_WICPixelFormat4bppIndexed
,
1547 &GUID_WICPixelFormat8bppIndexed
,
1548 &GUID_WICPixelFormatBlackWhite
,
1549 &GUID_WICPixelFormat2bppGray
,
1550 &GUID_WICPixelFormat4bppGray
,
1551 &GUID_WICPixelFormat8bppGray
,
1552 &GUID_WICPixelFormat16bppGray
,
1553 &GUID_WICPixelFormat16bppBGR555
,
1554 &GUID_WICPixelFormat16bppBGR565
,
1555 &GUID_WICPixelFormat16bppBGRA5551
,
1556 &GUID_WICPixelFormat24bppBGR
,
1557 &GUID_WICPixelFormat24bppRGB
,
1558 &GUID_WICPixelFormat32bppBGR
,
1559 &GUID_WICPixelFormat32bppRGB
,
1560 &GUID_WICPixelFormat32bppBGRA
,
1561 &GUID_WICPixelFormat32bppRGBA
,
1562 &GUID_WICPixelFormat32bppPBGRA
,
1563 &GUID_WICPixelFormat32bppPRGBA
,
1564 &GUID_WICPixelFormat32bppGrayFloat
,
1565 &GUID_WICPixelFormat48bppRGB
,
1566 &GUID_WICPixelFormat64bppRGBA
,
1567 &GUID_WICPixelFormat32bppCMYK
,
1571 static struct regsvr_converter
const converter_list
[] = {
1572 { &CLSID_WICDefaultFormatConverter
,
1574 "Default Pixel Format Converter",
1576 &GUID_VendorMicrosoft
,
1579 { NULL
} /* list terminator */
1582 static const BYTE no_magic
[1] = { 0 };
1583 static const BYTE no_mask
[1] = { 0 };
1585 static const struct metadata_pattern ifd_metadata_pattern
[] = {
1586 { 0, 1, no_magic
, no_mask
, 0 },
1590 static const struct reader_containers ifd_containers
[] = {
1592 &GUID_ContainerFormatTiff
,
1593 ifd_metadata_pattern
1595 { NULL
} /* list terminator */
1598 static const BYTE tEXt
[] = "tEXt";
1600 static const struct metadata_pattern pngtext_metadata_pattern
[] = {
1601 { 4, 4, tEXt
, mask_all
, 4 },
1605 static const struct reader_containers pngtext_containers
[] = {
1607 &GUID_ContainerFormatPng
,
1608 pngtext_metadata_pattern
1610 { NULL
} /* list terminator */
1613 static const BYTE gAMA
[] = "gAMA";
1615 static const struct metadata_pattern pnggama_metadata_pattern
[] = {
1616 { 4, 4, gAMA
, mask_all
, 4 },
1620 static const struct reader_containers pnggama_containers
[] = {
1622 &GUID_ContainerFormatPng
,
1623 pnggama_metadata_pattern
1625 { NULL
} /* list terminator */
1628 static const BYTE cHRM
[] = "cHRM";
1630 static const struct metadata_pattern pngchrm_metadata_pattern
[] = {
1631 { 4, 4, cHRM
, mask_all
, 4 },
1635 static const struct reader_containers pngchrm_containers
[] = {
1637 &GUID_ContainerFormatPng
,
1638 pngchrm_metadata_pattern
1640 { NULL
} /* list terminator */
1643 static const struct metadata_pattern lsd_metadata_patterns
[] = {
1644 { 0, 6, gif87a_magic
, mask_all
, 0 },
1645 { 0, 6, gif89a_magic
, mask_all
, 0 },
1649 static const struct reader_containers lsd_containers
[] = {
1651 &GUID_ContainerFormatGif
,
1652 lsd_metadata_patterns
1654 { NULL
} /* list terminator */
1657 static const BYTE imd_magic
[] = { 0x2c };
1659 static const struct metadata_pattern imd_metadata_pattern
[] = {
1660 { 0, 1, imd_magic
, mask_all
, 1 },
1664 static const struct reader_containers imd_containers
[] = {
1666 &GUID_ContainerFormatGif
,
1667 imd_metadata_pattern
1669 { NULL
} /* list terminator */
1672 static const BYTE gce_magic
[] = { 0x21, 0xf9, 0x04 };
1674 static const struct metadata_pattern gce_metadata_pattern
[] = {
1675 { 0, 3, gce_magic
, mask_all
, 3 },
1679 static const struct reader_containers gce_containers
[] = {
1681 &GUID_ContainerFormatGif
,
1682 gce_metadata_pattern
1684 { NULL
} /* list terminator */
1687 static const BYTE ape_magic
[] = { 0x21, 0xff, 0x0b };
1689 static const struct metadata_pattern ape_metadata_pattern
[] = {
1690 { 0, 3, ape_magic
, mask_all
, 0 },
1694 static const struct reader_containers ape_containers
[] = {
1696 &GUID_ContainerFormatGif
,
1697 ape_metadata_pattern
1699 { NULL
} /* list terminator */
1702 static const BYTE gif_comment_magic
[] = { 0x21, 0xfe };
1704 static const struct metadata_pattern gif_comment_metadata_pattern
[] = {
1705 { 0, 2, gif_comment_magic
, mask_all
, 0 },
1709 static const struct reader_containers gif_comment_containers
[] = {
1711 &GUID_ContainerFormatGif
,
1712 gif_comment_metadata_pattern
1714 { NULL
} /* list terminator */
1717 static struct regsvr_metadatareader
const metadatareader_list
[] = {
1718 { &CLSID_WICUnknownMetadataReader
,
1720 "Unknown Metadata Reader",
1723 &GUID_VendorMicrosoft
,
1724 &GUID_MetadataFormatUnknown
,
1728 { &CLSID_WICIfdMetadataReader
,
1733 &GUID_VendorMicrosoft
,
1734 &GUID_MetadataFormatIfd
,
1738 { &CLSID_WICPngChrmMetadataReader
,
1740 "Chunk cHRM Reader",
1743 &GUID_VendorMicrosoft
,
1744 &GUID_MetadataFormatChunkcHRM
,
1748 { &CLSID_WICPngGamaMetadataReader
,
1750 "Chunk gAMA Reader",
1753 &GUID_VendorMicrosoft
,
1754 &GUID_MetadataFormatChunkgAMA
,
1758 { &CLSID_WICPngTextMetadataReader
,
1760 "Chunk tEXt Reader",
1763 &GUID_VendorMicrosoft
,
1764 &GUID_MetadataFormatChunktEXt
,
1768 { &CLSID_WICLSDMetadataReader
,
1770 "Logical Screen Descriptor Reader",
1773 &GUID_VendorMicrosoft
,
1774 &GUID_MetadataFormatLSD
,
1778 { &CLSID_WICIMDMetadataReader
,
1780 "Image Descriptor Reader",
1783 &GUID_VendorMicrosoft
,
1784 &GUID_MetadataFormatIMD
,
1788 { &CLSID_WICGCEMetadataReader
,
1790 "Graphic Control Extension Reader",
1793 &GUID_VendorMicrosoft
,
1794 &GUID_MetadataFormatGCE
,
1798 { &CLSID_WICAPEMetadataReader
,
1800 "Application Extension Reader",
1803 &GUID_VendorMicrosoft
,
1804 &GUID_MetadataFormatAPE
,
1808 { &CLSID_WICGifCommentMetadataReader
,
1810 "Comment Extension Reader",
1813 &GUID_VendorMicrosoft
,
1814 &GUID_MetadataFormatGifComment
,
1816 gif_comment_containers
1818 { NULL
} /* list terminator */
1821 static BYTE
const channel_mask_1bit
[] = { 0x01 };
1822 static BYTE
const channel_mask_2bit
[] = { 0x03 };
1823 static BYTE
const channel_mask_4bit
[] = { 0x0f };
1825 static BYTE
const channel_mask_8bit
[] = { 0xff, 0x00, 0x00, 0x00 };
1826 static BYTE
const channel_mask_8bit2
[] = { 0x00, 0xff, 0x00, 0x00 };
1827 static BYTE
const channel_mask_8bit3
[] = { 0x00, 0x00, 0xff, 0x00 };
1828 static BYTE
const channel_mask_8bit4
[] = { 0x00, 0x00, 0x00, 0xff };
1830 static BYTE
const channel_mask_16bit
[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1831 static BYTE
const channel_mask_16bit2
[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1832 static BYTE
const channel_mask_16bit3
[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
1833 static BYTE
const channel_mask_16bit4
[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
1835 static BYTE
const channel_mask_32bit
[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1837 static BYTE
const channel_mask_96bit1
[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1838 static BYTE
const channel_mask_96bit2
[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 };
1839 static BYTE
const channel_mask_96bit3
[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff };
1841 static BYTE
const channel_mask_128bit1
[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1842 static BYTE
const channel_mask_128bit2
[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1843 static BYTE
const channel_mask_128bit3
[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 };
1844 static BYTE
const channel_mask_128bit4
[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff };
1846 static BYTE
const channel_mask_5bit
[] = { 0x1f, 0x00 };
1847 static BYTE
const channel_mask_5bit2
[] = { 0xe0, 0x03 };
1848 static BYTE
const channel_mask_5bit3
[] = { 0x00, 0x7c };
1849 static BYTE
const channel_mask_5bit4
[] = { 0x00, 0x80 };
1851 static BYTE
const channel_mask_BGR565_2
[] = { 0xe0, 0x07 };
1852 static BYTE
const channel_mask_BGR565_3
[] = { 0x00, 0xf8 };
1854 static BYTE
const * const channel_masks_1bit
[] = { channel_mask_1bit
};
1855 static BYTE
const * const channel_masks_2bit
[] = { channel_mask_2bit
};
1856 static BYTE
const * const channel_masks_4bit
[] = { channel_mask_4bit
};
1857 static BYTE
const * const channel_masks_8bit
[] = { channel_mask_8bit
,
1858 channel_mask_8bit2
, channel_mask_8bit3
, channel_mask_8bit4
};
1859 static BYTE
const * const channel_masks_16bit
[] = { channel_mask_16bit
,
1860 channel_mask_16bit2
, channel_mask_16bit3
, channel_mask_16bit4
};
1862 static BYTE
const * const channel_masks_32bit
[] = { channel_mask_32bit
};
1863 static BYTE
const * const channel_masks_96bit
[] = { channel_mask_96bit1
, channel_mask_96bit2
, channel_mask_96bit3
};
1864 static BYTE
const * const channel_masks_128bit
[] = { channel_mask_128bit1
, channel_mask_128bit2
, channel_mask_128bit3
, channel_mask_128bit4
};
1866 static BYTE
const * const channel_masks_BGRA5551
[] = { channel_mask_5bit
,
1867 channel_mask_5bit2
, channel_mask_5bit3
, channel_mask_5bit4
};
1869 static BYTE
const * const channel_masks_BGR565
[] = { channel_mask_5bit
,
1870 channel_mask_BGR565_2
, channel_mask_BGR565_3
};
1872 static struct regsvr_pixelformat
const pixelformat_list
[] = {
1873 { &GUID_WICPixelFormat1bppIndexed
,
1876 NULL
, /* no version */
1877 &GUID_VendorMicrosoft
,
1878 1, /* bitsperpixel */
1879 1, /* channel count */
1881 WICPixelFormatNumericRepresentationIndexed
,
1884 { &GUID_WICPixelFormat2bppIndexed
,
1887 NULL
, /* no version */
1888 &GUID_VendorMicrosoft
,
1889 2, /* bitsperpixel */
1890 1, /* channel count */
1892 WICPixelFormatNumericRepresentationIndexed
,
1895 { &GUID_WICPixelFormat4bppIndexed
,
1898 NULL
, /* no version */
1899 &GUID_VendorMicrosoft
,
1900 4, /* bitsperpixel */
1901 1, /* channel count */
1903 WICPixelFormatNumericRepresentationIndexed
,
1906 { &GUID_WICPixelFormat8bppIndexed
,
1909 NULL
, /* no version */
1910 &GUID_VendorMicrosoft
,
1911 8, /* bitsperpixel */
1912 1, /* channel count */
1914 WICPixelFormatNumericRepresentationIndexed
,
1917 { &GUID_WICPixelFormatBlackWhite
,
1920 NULL
, /* no version */
1921 &GUID_VendorMicrosoft
,
1922 1, /* bitsperpixel */
1923 1, /* channel count */
1925 WICPixelFormatNumericRepresentationUnsignedInteger
,
1928 { &GUID_WICPixelFormat2bppGray
,
1931 NULL
, /* no version */
1932 &GUID_VendorMicrosoft
,
1933 2, /* bitsperpixel */
1934 1, /* channel count */
1936 WICPixelFormatNumericRepresentationUnsignedInteger
,
1939 { &GUID_WICPixelFormat4bppGray
,
1942 NULL
, /* no version */
1943 &GUID_VendorMicrosoft
,
1944 4, /* bitsperpixel */
1945 1, /* channel count */
1947 WICPixelFormatNumericRepresentationUnsignedInteger
,
1950 { &GUID_WICPixelFormat8bppGray
,
1953 NULL
, /* no version */
1954 &GUID_VendorMicrosoft
,
1955 8, /* bitsperpixel */
1956 1, /* channel count */
1958 WICPixelFormatNumericRepresentationUnsignedInteger
,
1961 { &GUID_WICPixelFormat16bppGray
,
1964 NULL
, /* no version */
1965 &GUID_VendorMicrosoft
,
1966 16, /* bitsperpixel */
1967 1, /* channel count */
1968 channel_masks_16bit
,
1969 WICPixelFormatNumericRepresentationUnsignedInteger
,
1972 { &GUID_WICPixelFormat16bppBGR555
,
1975 NULL
, /* no version */
1976 &GUID_VendorMicrosoft
,
1977 16, /* bitsperpixel */
1978 3, /* channel count */
1979 channel_masks_BGRA5551
,
1980 WICPixelFormatNumericRepresentationUnsignedInteger
,
1983 { &GUID_WICPixelFormat16bppBGR565
,
1986 NULL
, /* no version */
1987 &GUID_VendorMicrosoft
,
1988 16, /* bitsperpixel */
1989 3, /* channel count */
1990 channel_masks_BGR565
,
1991 WICPixelFormatNumericRepresentationUnsignedInteger
,
1994 { &GUID_WICPixelFormat16bppBGRA5551
,
1997 NULL
, /* no version */
1998 &GUID_VendorMicrosoft
,
1999 16, /* bitsperpixel */
2000 4, /* channel count */
2001 channel_masks_BGRA5551
,
2002 WICPixelFormatNumericRepresentationUnsignedInteger
,
2005 { &GUID_WICPixelFormat24bppBGR
,
2008 NULL
, /* no version */
2009 &GUID_VendorMicrosoft
,
2010 24, /* bitsperpixel */
2011 3, /* channel count */
2013 WICPixelFormatNumericRepresentationUnsignedInteger
,
2016 { &GUID_WICPixelFormat24bppRGB
,
2019 NULL
, /* no version */
2020 &GUID_VendorMicrosoft
,
2021 24, /* bitsperpixel */
2022 3, /* channel count */
2024 WICPixelFormatNumericRepresentationUnsignedInteger
,
2027 { &GUID_WICPixelFormat32bppBGR
,
2030 NULL
, /* no version */
2031 &GUID_VendorMicrosoft
,
2032 32, /* bitsperpixel */
2033 3, /* channel count */
2035 WICPixelFormatNumericRepresentationUnsignedInteger
,
2038 { &GUID_WICPixelFormat32bppRGB
,
2041 NULL
, /* no version */
2042 &GUID_VendorMicrosoft
,
2043 32, /* bitsperpixel */
2044 3, /* channel count */
2046 WICPixelFormatNumericRepresentationUnsignedInteger
,
2049 { &GUID_WICPixelFormat32bppBGRA
,
2052 NULL
, /* no version */
2053 &GUID_VendorMicrosoft
,
2054 32, /* bitsperpixel */
2055 4, /* channel count */
2057 WICPixelFormatNumericRepresentationUnsignedInteger
,
2060 { &GUID_WICPixelFormat32bppRGBA
,
2063 NULL
, /* no version */
2064 &GUID_VendorMicrosoft
,
2065 32, /* bitsperpixel */
2066 4, /* channel count */
2068 WICPixelFormatNumericRepresentationUnsignedInteger
,
2071 { &GUID_WICPixelFormat32bppPBGRA
,
2074 NULL
, /* no version */
2075 &GUID_VendorMicrosoft
,
2076 32, /* bitsperpixel */
2077 4, /* channel count */
2079 WICPixelFormatNumericRepresentationUnsignedInteger
,
2082 { &GUID_WICPixelFormat32bppPRGBA
,
2085 NULL
, /* no version */
2086 &GUID_VendorMicrosoft
,
2087 32, /* bitsperpixel */
2088 4, /* channel count */
2090 WICPixelFormatNumericRepresentationUnsignedInteger
,
2093 { &GUID_WICPixelFormat32bppGrayFloat
,
2096 NULL
, /* no version */
2097 &GUID_VendorMicrosoft
,
2098 32, /* bitsperpixel */
2099 1, /* channel count */
2100 channel_masks_32bit
,
2101 WICPixelFormatNumericRepresentationFloat
,
2104 { &GUID_WICPixelFormat48bppRGB
,
2107 NULL
, /* no version */
2108 &GUID_VendorMicrosoft
,
2109 48, /* bitsperpixel */
2110 3, /* channel count */
2111 channel_masks_16bit
,
2112 WICPixelFormatNumericRepresentationUnsignedInteger
,
2115 { &GUID_WICPixelFormat64bppRGBA
,
2118 NULL
, /* no version */
2119 &GUID_VendorMicrosoft
,
2120 64, /* bitsperpixel */
2121 4, /* channel count */
2122 channel_masks_16bit
,
2123 WICPixelFormatNumericRepresentationUnsignedInteger
,
2126 { &GUID_WICPixelFormat64bppPRGBA
,
2129 NULL
, /* no version */
2130 &GUID_VendorMicrosoft
,
2131 64, /* bitsperpixel */
2132 4, /* channel count */
2133 channel_masks_16bit
,
2134 WICPixelFormatNumericRepresentationUnsignedInteger
,
2137 { &GUID_WICPixelFormat32bppCMYK
,
2140 NULL
, /* no version */
2141 &GUID_VendorMicrosoft
,
2142 32, /* bitsperpixel */
2143 4, /* channel count */
2145 WICPixelFormatNumericRepresentationUnsignedInteger
,
2148 { &GUID_WICPixelFormat64bppCMYK
,
2151 NULL
, /* no version */
2152 &GUID_VendorMicrosoft
,
2153 64, /* bitsperpixel */
2154 4, /* channel count */
2155 channel_masks_16bit
,
2156 WICPixelFormatNumericRepresentationUnsignedInteger
,
2159 { &GUID_WICPixelFormat96bppRGBFloat
,
2162 NULL
, /* no version */
2163 &GUID_VendorMicrosoft
,
2164 96, /* bitsperpixel */
2165 3, /* channel count */
2166 channel_masks_96bit
,
2167 WICPixelFormatNumericRepresentationFloat
,
2170 { &GUID_WICPixelFormat128bppRGBAFloat
,
2173 NULL
, /* no version */
2174 &GUID_VendorMicrosoft
,
2175 128, /* bitsperpixel */
2176 4, /* channel count */
2177 channel_masks_128bit
,
2178 WICPixelFormatNumericRepresentationFloat
,
2181 { &GUID_WICPixelFormat128bppPRGBAFloat
,
2183 "128bpp PRGBAFloat",
2184 NULL
, /* no version */
2185 &GUID_VendorMicrosoft
,
2186 128, /* bitsperpixel */
2187 4, /* channel count */
2188 channel_masks_128bit
,
2189 WICPixelFormatNumericRepresentationFloat
,
2192 { NULL
} /* list terminator */
2195 struct regsvr_category
2197 const CLSID
*clsid
; /* NULL for end of list */
2200 static const struct regsvr_category category_list
[] = {
2201 { &CATID_WICBitmapDecoders
},
2202 { &CATID_WICBitmapEncoders
},
2203 { &CATID_WICFormatConverters
},
2204 { &CATID_WICMetadataReader
},
2205 { &CATID_WICPixelFormats
},
2209 static HRESULT
register_categories(const struct regsvr_category
*list
)
2213 HKEY coclass_key
, categories_key
, instance_key
;
2215 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
2216 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
2217 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
2219 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2220 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
2221 KEY_READ
| KEY_WRITE
, NULL
, &categories_key
, NULL
);
2222 if (res
!= ERROR_SUCCESS
)
2224 RegCloseKey(coclass_key
);
2225 return HRESULT_FROM_WIN32(res
);
2228 res
= RegCreateKeyExW(categories_key
, instance_keyname
, 0, NULL
, 0,
2229 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
2231 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
2233 HKEY instance_clsid_key
;
2235 StringFromGUID2(list
->clsid
, buf
, 39);
2236 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
2237 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
2238 if (res
== ERROR_SUCCESS
)
2240 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
2241 (const BYTE
*)buf
, 78);
2242 RegCloseKey(instance_clsid_key
);
2246 RegCloseKey(instance_key
);
2247 RegCloseKey(categories_key
);
2248 RegCloseKey(coclass_key
);
2250 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
2253 static HRESULT
unregister_categories(const struct regsvr_category
*list
)
2257 HKEY coclass_key
, categories_key
, instance_key
;
2259 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
2260 KEY_READ
| KEY_WRITE
, &coclass_key
);
2261 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
2263 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2264 res
= RegOpenKeyExW(coclass_key
, buf
, 0,
2265 KEY_READ
| KEY_WRITE
, &categories_key
);
2266 if (res
!= ERROR_SUCCESS
)
2268 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
2269 RegCloseKey(coclass_key
);
2270 return HRESULT_FROM_WIN32(res
);
2273 res
= RegOpenKeyExW(categories_key
, instance_keyname
, 0,
2274 KEY_READ
| KEY_WRITE
, &instance_key
);
2276 for (; res
== ERROR_SUCCESS
&& list
->clsid
; list
++)
2278 StringFromGUID2(list
->clsid
, buf
, 39);
2279 res
= RegDeleteTreeW(instance_key
, buf
);
2282 RegCloseKey(instance_key
);
2283 RegCloseKey(categories_key
);
2285 StringFromGUID2(&CLSID_WICImagingCategories
, buf
, 39);
2286 res
= RegDeleteTreeW(coclass_key
, buf
);
2288 RegCloseKey(coclass_key
);
2290 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
2293 extern HRESULT WINAPI
WIC_DllRegisterServer(void) DECLSPEC_HIDDEN
;
2294 extern HRESULT WINAPI
WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
2296 HRESULT WINAPI
DllRegisterServer(void)
2302 hr
= WIC_DllRegisterServer();
2304 hr
= register_categories(category_list
);
2306 hr
= register_decoders(decoder_list
);
2308 hr
= register_encoders(encoder_list
);
2310 hr
= register_converters(converter_list
);
2312 hr
= register_metadatareaders(metadatareader_list
);
2314 hr
= register_pixelformats(pixelformat_list
);
2318 HRESULT WINAPI
DllUnregisterServer(void)
2324 hr
= WIC_DllUnregisterServer();
2326 hr
= unregister_categories(category_list
);
2328 hr
= unregister_decoders(decoder_list
);
2330 hr
= unregister_encoders(encoder_list
);
2332 hr
= unregister_converters(converter_list
);
2334 hr
= unregister_metadatareaders(metadatareader_list
);
2336 hr
= unregister_pixelformats(pixelformat_list
);