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 #define NONAMELESSUNION
20 #define NONAMELESSSTRUCT
35 #include "wincodecsdk.h"
37 #include "wine/debug.h"
38 #include "wine/unicode.h"
40 #include "wincodecs_private.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
44 /***********************************************************************
45 * interface for self-registering
47 struct decoder_pattern
49 DWORD length
; /* 0 for end of list */
58 CLSID
const *clsid
; /* NULL for end of list */
63 GUID
const *container_format
;
66 GUID
const * const *formats
;
67 const struct decoder_pattern
*patterns
;
70 static HRESULT
register_decoders(struct regsvr_decoder
const *list
);
71 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
);
75 CLSID
const *clsid
; /* NULL for end of list */
80 GUID
const *container_format
;
83 GUID
const * const *formats
;
86 static HRESULT
register_encoders(struct regsvr_encoder
const *list
);
87 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
);
89 struct regsvr_converter
91 CLSID
const *clsid
; /* NULL for end of list */
96 GUID
const * const *formats
;
99 static HRESULT
register_converters(struct regsvr_converter
const *list
);
100 static HRESULT
unregister_converters(struct regsvr_converter
const *list
);
102 struct metadata_pattern
111 struct reader_containers
114 const struct metadata_pattern
*patterns
;
117 struct regsvr_metadatareader
119 CLSID
const *clsid
; /* NULL for end of list */
125 GUID
const *metadata_format
;
126 DWORD requires_fullstream
;
127 DWORD supports_padding
;
128 DWORD requires_fixedsize
;
129 const struct reader_containers
*containers
;
132 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
);
133 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
);
135 /***********************************************************************
136 * static string constants
138 static const WCHAR clsid_keyname
[] = {
139 'C', 'L', 'S', 'I', 'D', 0 };
140 static const WCHAR curver_keyname
[] = {
141 'C', 'u', 'r', 'V', 'e', 'r', 0 };
142 static const WCHAR ips_keyname
[] = {
143 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
145 static const WCHAR ips32_keyname
[] = {
146 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
148 static const WCHAR progid_keyname
[] = {
149 'P', 'r', 'o', 'g', 'I', 'D', 0 };
150 static const WCHAR viprogid_keyname
[] = {
151 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
152 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
154 static const char tmodel_valuename
[] = "ThreadingModel";
155 static const char author_valuename
[] = "Author";
156 static const char friendlyname_valuename
[] = "FriendlyName";
157 static const WCHAR vendor_valuename
[] = {'V','e','n','d','o','r',0};
158 static const WCHAR containerformat_valuename
[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
159 static const char version_valuename
[] = "Version";
160 static const char mimetypes_valuename
[] = "MimeTypes";
161 static const char extensions_valuename
[] = "FileExtensions";
162 static const WCHAR formats_keyname
[] = {'F','o','r','m','a','t','s',0};
163 static const WCHAR patterns_keyname
[] = {'P','a','t','t','e','r','n','s',0};
164 static const WCHAR instance_keyname
[] = {'I','n','s','t','a','n','c','e',0};
165 static const WCHAR clsid_valuename
[] = {'C','L','S','I','D',0};
166 static const char length_valuename
[] = "Length";
167 static const char position_valuename
[] = "Position";
168 static const char pattern_valuename
[] = "Pattern";
169 static const char mask_valuename
[] = "Mask";
170 static const char endofstream_valuename
[] = "EndOfStream";
171 static const WCHAR pixelformats_keyname
[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
172 static const WCHAR metadataformat_valuename
[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
173 static const char specversion_valuename
[] = "SpecVersion";
174 static const char requiresfullstream_valuename
[] = "RequiresFullStream";
175 static const char supportspadding_valuename
[] = "SupportsPadding";
176 static const char requiresfixedsize_valuename
[] = "FixedSize";
177 static const WCHAR containers_keyname
[] = {'C','o','n','t','a','i','n','e','r','s',0};
178 static const char dataoffset_valuename
[] = "DataOffset";
180 /***********************************************************************
183 static HRESULT
register_decoders(struct regsvr_decoder
const *list
)
185 LONG res
= ERROR_SUCCESS
;
191 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
192 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
193 if (res
== ERROR_SUCCESS
) {
194 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
195 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
196 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
197 if (res
== ERROR_SUCCESS
)
199 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
200 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
201 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
203 if (res
!= ERROR_SUCCESS
)
204 RegCloseKey(coclass_key
);
206 if (res
!= ERROR_SUCCESS
) goto error_return
;
208 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
210 HKEY instance_clsid_key
;
212 StringFromGUID2(list
->clsid
, buf
, 39);
213 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
214 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
215 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
217 StringFromGUID2(list
->clsid
, buf
, 39);
218 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
219 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
220 if (res
== ERROR_SUCCESS
) {
221 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
222 (CONST BYTE
*)(buf
), 78);
223 RegCloseKey(instance_clsid_key
);
225 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
228 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
229 (CONST BYTE
*)(list
->author
),
230 strlen(list
->author
) + 1);
231 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
234 if (list
->friendlyname
) {
235 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
236 (CONST BYTE
*)(list
->friendlyname
),
237 strlen(list
->friendlyname
) + 1);
238 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
242 StringFromGUID2(list
->vendor
, buf
, 39);
243 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
244 (CONST BYTE
*)(buf
), 78);
245 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
248 if (list
->container_format
) {
249 StringFromGUID2(list
->container_format
, buf
, 39);
250 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
251 (CONST BYTE
*)(buf
), 78);
252 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
256 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
257 (CONST BYTE
*)(list
->version
),
258 strlen(list
->version
) + 1);
259 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
262 if (list
->mimetypes
) {
263 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
264 (CONST BYTE
*)(list
->mimetypes
),
265 strlen(list
->mimetypes
) + 1);
266 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
269 if (list
->extensions
) {
270 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
271 (CONST BYTE
*)(list
->extensions
),
272 strlen(list
->extensions
) + 1);
273 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
278 GUID
const * const *format
;
280 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
281 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
282 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
283 for (format
=list
->formats
; *format
; ++format
)
286 StringFromGUID2(*format
, buf
, 39);
287 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
288 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
289 if (res
!= ERROR_SUCCESS
) break;
290 RegCloseKey(format_key
);
292 RegCloseKey(formats_key
);
293 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
296 if (list
->patterns
) {
300 res
= RegCreateKeyExW(clsid_key
, patterns_keyname
, 0, NULL
, 0,
301 KEY_READ
| KEY_WRITE
, NULL
, &patterns_key
, NULL
);
302 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
303 for (i
=0; list
->patterns
[i
].length
; i
++)
306 static const WCHAR int_format
[] = {'%','i',0};
307 snprintfW(buf
, 39, int_format
, i
);
308 res
= RegCreateKeyExW(patterns_key
, buf
, 0, NULL
, 0,
309 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
310 if (res
!= ERROR_SUCCESS
) break;
311 res
= RegSetValueExA(pattern_key
, length_valuename
, 0, REG_DWORD
,
312 (CONST BYTE
*)(&list
->patterns
[i
].length
), 4);
313 if (res
== ERROR_SUCCESS
)
314 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
315 (CONST BYTE
*)(&list
->patterns
[i
].position
), 4);
316 if (res
== ERROR_SUCCESS
)
317 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
318 list
->patterns
[i
].pattern
,
319 list
->patterns
[i
].length
);
320 if (res
== ERROR_SUCCESS
)
321 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
322 list
->patterns
[i
].mask
,
323 list
->patterns
[i
].length
);
324 if (res
== ERROR_SUCCESS
)
325 res
= RegSetValueExA(pattern_key
, endofstream_valuename
, 0, REG_DWORD
,
326 (CONST BYTE
*)&(list
->patterns
[i
].endofstream
), 4);
327 RegCloseKey(pattern_key
);
329 RegCloseKey(patterns_key
);
330 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
333 error_close_clsid_key
:
334 RegCloseKey(clsid_key
);
337 error_close_coclass_key
:
338 RegCloseKey(instance_key
);
339 RegCloseKey(decoders_key
);
340 RegCloseKey(coclass_key
);
342 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
345 /***********************************************************************
346 * unregister_decoders
348 static HRESULT
unregister_decoders(struct regsvr_decoder
const *list
)
350 LONG res
= ERROR_SUCCESS
;
356 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
357 KEY_READ
| KEY_WRITE
, &coclass_key
);
358 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
360 if (res
== ERROR_SUCCESS
) {
361 StringFromGUID2(&CATID_WICBitmapDecoders
, buf
, 39);
362 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
363 KEY_READ
| KEY_WRITE
, NULL
, &decoders_key
, NULL
);
364 if (res
== ERROR_SUCCESS
)
366 res
= RegCreateKeyExW(decoders_key
, instance_keyname
, 0, NULL
, 0,
367 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
368 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
370 if (res
!= ERROR_SUCCESS
)
371 RegCloseKey(coclass_key
);
373 if (res
!= ERROR_SUCCESS
) goto error_return
;
375 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
376 StringFromGUID2(list
->clsid
, buf
, 39);
378 res
= RegDeleteTreeW(coclass_key
, buf
);
379 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
380 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
382 res
= RegDeleteTreeW(instance_key
, buf
);
383 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
384 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
387 error_close_coclass_key
:
388 RegCloseKey(instance_key
);
389 RegCloseKey(decoders_key
);
390 RegCloseKey(coclass_key
);
392 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
395 /***********************************************************************
398 static HRESULT
register_encoders(struct regsvr_encoder
const *list
)
400 LONG res
= ERROR_SUCCESS
;
406 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
407 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
408 if (res
== ERROR_SUCCESS
) {
409 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
410 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
411 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
412 if (res
== ERROR_SUCCESS
)
414 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
415 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
416 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
418 if (res
!= ERROR_SUCCESS
)
419 RegCloseKey(coclass_key
);
421 if (res
!= ERROR_SUCCESS
) goto error_return
;
423 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
425 HKEY instance_clsid_key
;
427 StringFromGUID2(list
->clsid
, buf
, 39);
428 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
429 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
430 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
432 StringFromGUID2(list
->clsid
, buf
, 39);
433 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
434 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
435 if (res
== ERROR_SUCCESS
) {
436 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
437 (CONST BYTE
*)(buf
), 78);
438 RegCloseKey(instance_clsid_key
);
440 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
443 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
444 (CONST BYTE
*)(list
->author
),
445 strlen(list
->author
) + 1);
446 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
449 if (list
->friendlyname
) {
450 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
451 (CONST BYTE
*)(list
->friendlyname
),
452 strlen(list
->friendlyname
) + 1);
453 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
457 StringFromGUID2(list
->vendor
, buf
, 39);
458 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
459 (CONST BYTE
*)(buf
), 78);
460 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
463 if (list
->container_format
) {
464 StringFromGUID2(list
->container_format
, buf
, 39);
465 res
= RegSetValueExW(clsid_key
, containerformat_valuename
, 0, REG_SZ
,
466 (CONST BYTE
*)(buf
), 78);
467 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
471 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
472 (CONST BYTE
*)(list
->version
),
473 strlen(list
->version
) + 1);
474 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
477 if (list
->mimetypes
) {
478 res
= RegSetValueExA(clsid_key
, mimetypes_valuename
, 0, REG_SZ
,
479 (CONST BYTE
*)(list
->mimetypes
),
480 strlen(list
->mimetypes
) + 1);
481 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
484 if (list
->extensions
) {
485 res
= RegSetValueExA(clsid_key
, extensions_valuename
, 0, REG_SZ
,
486 (CONST BYTE
*)(list
->extensions
),
487 strlen(list
->extensions
) + 1);
488 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
493 GUID
const * const *format
;
495 res
= RegCreateKeyExW(clsid_key
, formats_keyname
, 0, NULL
, 0,
496 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
497 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
498 for (format
=list
->formats
; *format
; ++format
)
501 StringFromGUID2(*format
, buf
, 39);
502 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
503 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
504 if (res
!= ERROR_SUCCESS
) break;
505 RegCloseKey(format_key
);
507 RegCloseKey(formats_key
);
508 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
511 error_close_clsid_key
:
512 RegCloseKey(clsid_key
);
515 error_close_coclass_key
:
516 RegCloseKey(instance_key
);
517 RegCloseKey(encoders_key
);
518 RegCloseKey(coclass_key
);
520 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
523 /***********************************************************************
524 * unregister_encoders
526 static HRESULT
unregister_encoders(struct regsvr_encoder
const *list
)
528 LONG res
= ERROR_SUCCESS
;
534 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
535 KEY_READ
| KEY_WRITE
, &coclass_key
);
536 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
538 if (res
== ERROR_SUCCESS
) {
539 StringFromGUID2(&CATID_WICBitmapEncoders
, buf
, 39);
540 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
541 KEY_READ
| KEY_WRITE
, NULL
, &encoders_key
, NULL
);
542 if (res
== ERROR_SUCCESS
)
544 res
= RegCreateKeyExW(encoders_key
, instance_keyname
, 0, NULL
, 0,
545 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
546 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
548 if (res
!= ERROR_SUCCESS
)
549 RegCloseKey(coclass_key
);
551 if (res
!= ERROR_SUCCESS
) goto error_return
;
553 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
554 StringFromGUID2(list
->clsid
, buf
, 39);
556 res
= RegDeleteTreeW(coclass_key
, buf
);
557 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
558 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
560 res
= RegDeleteTreeW(instance_key
, buf
);
561 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
562 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
565 error_close_coclass_key
:
566 RegCloseKey(instance_key
);
567 RegCloseKey(encoders_key
);
568 RegCloseKey(coclass_key
);
570 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
573 /***********************************************************************
574 * register_converters
576 static HRESULT
register_converters(struct regsvr_converter
const *list
)
578 LONG res
= ERROR_SUCCESS
;
584 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
585 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
586 if (res
== ERROR_SUCCESS
) {
587 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
588 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
589 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
590 if (res
== ERROR_SUCCESS
)
592 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
593 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
594 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
596 if (res
!= ERROR_SUCCESS
)
597 RegCloseKey(coclass_key
);
599 if (res
!= ERROR_SUCCESS
) goto error_return
;
601 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
603 HKEY instance_clsid_key
;
605 StringFromGUID2(list
->clsid
, buf
, 39);
606 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
607 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
608 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
610 StringFromGUID2(list
->clsid
, buf
, 39);
611 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
612 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
613 if (res
== ERROR_SUCCESS
) {
614 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
615 (CONST BYTE
*)(buf
), 78);
616 RegCloseKey(instance_clsid_key
);
618 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
621 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
622 (CONST BYTE
*)(list
->author
),
623 strlen(list
->author
) + 1);
624 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
627 if (list
->friendlyname
) {
628 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
629 (CONST BYTE
*)(list
->friendlyname
),
630 strlen(list
->friendlyname
) + 1);
631 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
635 StringFromGUID2(list
->vendor
, buf
, 39);
636 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
637 (CONST BYTE
*)(buf
), 78);
638 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
642 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
643 (CONST BYTE
*)(list
->version
),
644 strlen(list
->version
) + 1);
645 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
650 GUID
const * const *format
;
652 res
= RegCreateKeyExW(clsid_key
, pixelformats_keyname
, 0, NULL
, 0,
653 KEY_READ
| KEY_WRITE
, NULL
, &formats_key
, NULL
);
654 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
655 for (format
=list
->formats
; *format
; ++format
)
658 StringFromGUID2(*format
, buf
, 39);
659 res
= RegCreateKeyExW(formats_key
, buf
, 0, NULL
, 0,
660 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
661 if (res
!= ERROR_SUCCESS
) break;
662 RegCloseKey(format_key
);
664 RegCloseKey(formats_key
);
665 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
668 error_close_clsid_key
:
669 RegCloseKey(clsid_key
);
672 error_close_coclass_key
:
673 RegCloseKey(instance_key
);
674 RegCloseKey(converters_key
);
675 RegCloseKey(coclass_key
);
677 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
680 /***********************************************************************
681 * unregister_converters
683 static HRESULT
unregister_converters(struct regsvr_converter
const *list
)
685 LONG res
= ERROR_SUCCESS
;
691 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
692 KEY_READ
| KEY_WRITE
, &coclass_key
);
693 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
695 if (res
== ERROR_SUCCESS
) {
696 StringFromGUID2(&CATID_WICFormatConverters
, buf
, 39);
697 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
698 KEY_READ
| KEY_WRITE
, NULL
, &converters_key
, NULL
);
699 if (res
== ERROR_SUCCESS
)
701 res
= RegCreateKeyExW(converters_key
, instance_keyname
, 0, NULL
, 0,
702 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
703 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
705 if (res
!= ERROR_SUCCESS
)
706 RegCloseKey(coclass_key
);
708 if (res
!= ERROR_SUCCESS
) goto error_return
;
710 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
711 StringFromGUID2(list
->clsid
, buf
, 39);
713 res
= RegDeleteTreeW(coclass_key
, buf
);
714 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
715 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
717 res
= RegDeleteTreeW(instance_key
, buf
);
718 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
719 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
722 error_close_coclass_key
:
723 RegCloseKey(instance_key
);
724 RegCloseKey(converters_key
);
725 RegCloseKey(coclass_key
);
727 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
730 /***********************************************************************
731 * register_metadatareaders
733 static HRESULT
register_metadatareaders(struct regsvr_metadatareader
const *list
)
735 LONG res
= ERROR_SUCCESS
;
741 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
742 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
743 if (res
== ERROR_SUCCESS
) {
744 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
745 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
746 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
747 if (res
== ERROR_SUCCESS
)
749 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
750 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
751 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
753 if (res
!= ERROR_SUCCESS
)
754 RegCloseKey(coclass_key
);
756 if (res
!= ERROR_SUCCESS
) goto error_return
;
758 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
760 HKEY instance_clsid_key
;
762 StringFromGUID2(list
->clsid
, buf
, 39);
763 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
764 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
765 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
767 StringFromGUID2(list
->clsid
, buf
, 39);
768 res
= RegCreateKeyExW(instance_key
, buf
, 0, NULL
, 0,
769 KEY_READ
| KEY_WRITE
, NULL
, &instance_clsid_key
, NULL
);
770 if (res
== ERROR_SUCCESS
) {
771 res
= RegSetValueExW(instance_clsid_key
, clsid_valuename
, 0, REG_SZ
,
772 (CONST BYTE
*)(buf
), 78);
773 RegCloseKey(instance_clsid_key
);
775 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
778 res
= RegSetValueExA(clsid_key
, author_valuename
, 0, REG_SZ
,
779 (CONST BYTE
*)(list
->author
),
780 strlen(list
->author
) + 1);
781 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
784 if (list
->friendlyname
) {
785 res
= RegSetValueExA(clsid_key
, friendlyname_valuename
, 0, REG_SZ
,
786 (CONST BYTE
*)(list
->friendlyname
),
787 strlen(list
->friendlyname
) + 1);
788 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
792 StringFromGUID2(list
->vendor
, buf
, 39);
793 res
= RegSetValueExW(clsid_key
, vendor_valuename
, 0, REG_SZ
,
794 (CONST BYTE
*)(buf
), 78);
795 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
799 StringFromGUID2(list
->metadata_format
, buf
, 39);
800 res
= RegSetValueExW(clsid_key
, metadataformat_valuename
, 0, REG_SZ
,
801 (CONST BYTE
*)(buf
), 78);
802 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
806 res
= RegSetValueExA(clsid_key
, version_valuename
, 0, REG_SZ
,
807 (CONST BYTE
*)(list
->version
),
808 strlen(list
->version
) + 1);
809 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
812 if (list
->specversion
) {
813 res
= RegSetValueExA(clsid_key
, specversion_valuename
, 0, REG_SZ
,
814 (CONST BYTE
*)(list
->version
),
815 strlen(list
->version
) + 1);
816 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
819 res
= RegSetValueExA(clsid_key
, requiresfullstream_valuename
, 0, REG_DWORD
,
820 (CONST BYTE
*)(&list
->requires_fullstream
), 4);
821 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
823 res
= RegSetValueExA(clsid_key
, supportspadding_valuename
, 0, REG_DWORD
,
824 (CONST BYTE
*)(&list
->supports_padding
), 4);
825 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
827 if (list
->requires_fixedsize
) {
828 res
= RegSetValueExA(clsid_key
, requiresfixedsize_valuename
, 0, REG_DWORD
,
829 (CONST BYTE
*)(&list
->requires_fixedsize
), 4);
830 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
833 if (list
->containers
) {
835 const struct reader_containers
*container
;
837 res
= RegCreateKeyExW(clsid_key
, containers_keyname
, 0, NULL
, 0,
838 KEY_READ
| KEY_WRITE
, NULL
, &containers_key
, NULL
);
839 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
840 for (container
=list
->containers
; container
->format
; ++container
)
844 StringFromGUID2(container
->format
, buf
, 39);
845 res
= RegCreateKeyExW(containers_key
, buf
, 0, NULL
, 0,
846 KEY_READ
| KEY_WRITE
, NULL
, &format_key
, NULL
);
847 if (res
!= ERROR_SUCCESS
) break;
849 for (i
=0; container
->patterns
[i
].length
; i
++)
852 static const WCHAR int_format
[] = {'%','i',0};
853 snprintfW(buf
, 39, int_format
, i
);
854 res
= RegCreateKeyExW(format_key
, buf
, 0, NULL
, 0,
855 KEY_READ
| KEY_WRITE
, NULL
, &pattern_key
, NULL
);
856 if (res
!= ERROR_SUCCESS
) break;
857 res
= RegSetValueExA(pattern_key
, position_valuename
, 0, REG_DWORD
,
858 (CONST BYTE
*)(&container
->patterns
[i
].position
), 4);
859 if (res
== ERROR_SUCCESS
)
860 res
= RegSetValueExA(pattern_key
, pattern_valuename
, 0, REG_BINARY
,
861 container
->patterns
[i
].pattern
,
862 container
->patterns
[i
].length
);
863 if (res
== ERROR_SUCCESS
)
864 res
= RegSetValueExA(pattern_key
, mask_valuename
, 0, REG_BINARY
,
865 container
->patterns
[i
].mask
,
866 container
->patterns
[i
].length
);
867 if (res
== ERROR_SUCCESS
&& container
->patterns
[i
].data_offset
)
868 res
= RegSetValueExA(pattern_key
, dataoffset_valuename
, 0, REG_DWORD
,
869 (CONST BYTE
*)&(container
->patterns
[i
].data_offset
), 4);
870 RegCloseKey(pattern_key
);
873 RegCloseKey(format_key
);
875 RegCloseKey(containers_key
);
878 error_close_clsid_key
:
879 RegCloseKey(clsid_key
);
882 error_close_coclass_key
:
883 RegCloseKey(instance_key
);
884 RegCloseKey(readers_key
);
885 RegCloseKey(coclass_key
);
887 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
890 /***********************************************************************
891 * unregister_metadatareaders
893 static HRESULT
unregister_metadatareaders(struct regsvr_metadatareader
const *list
)
895 LONG res
= ERROR_SUCCESS
;
901 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
902 KEY_READ
| KEY_WRITE
, &coclass_key
);
903 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
905 if (res
== ERROR_SUCCESS
) {
906 StringFromGUID2(&CATID_WICMetadataReader
, buf
, 39);
907 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
908 KEY_READ
| KEY_WRITE
, NULL
, &readers_key
, NULL
);
909 if (res
== ERROR_SUCCESS
)
911 res
= RegCreateKeyExW(readers_key
, instance_keyname
, 0, NULL
, 0,
912 KEY_READ
| KEY_WRITE
, NULL
, &instance_key
, NULL
);
913 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
915 if (res
!= ERROR_SUCCESS
)
916 RegCloseKey(coclass_key
);
918 if (res
!= ERROR_SUCCESS
) goto error_return
;
920 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
921 StringFromGUID2(list
->clsid
, buf
, 39);
923 res
= RegDeleteTreeW(coclass_key
, buf
);
924 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
925 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
927 res
= RegDeleteTreeW(instance_key
, buf
);
928 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
929 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
932 error_close_coclass_key
:
933 RegCloseKey(instance_key
);
934 RegCloseKey(readers_key
);
935 RegCloseKey(coclass_key
);
937 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
940 /***********************************************************************
943 static const BYTE mask_all
[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
945 static const BYTE bmp_magic
[] = {0x42,0x4d};
947 static GUID
const * const bmp_formats
[] = {
948 &GUID_WICPixelFormat1bppIndexed
,
949 &GUID_WICPixelFormat2bppIndexed
,
950 &GUID_WICPixelFormat4bppIndexed
,
951 &GUID_WICPixelFormat8bppIndexed
,
952 &GUID_WICPixelFormat16bppBGR555
,
953 &GUID_WICPixelFormat16bppBGR565
,
954 &GUID_WICPixelFormat24bppBGR
,
955 &GUID_WICPixelFormat32bppBGR
,
956 &GUID_WICPixelFormat32bppBGRA
,
960 static struct decoder_pattern
const bmp_patterns
[] = {
961 {2,0,bmp_magic
,mask_all
,0},
965 static const BYTE gif87a_magic
[6] = "GIF87a";
966 static const BYTE gif89a_magic
[6] = "GIF89a";
968 static GUID
const * const gif_formats
[] = {
969 &GUID_WICPixelFormat8bppIndexed
,
973 static struct decoder_pattern
const gif_patterns
[] = {
974 {6,0,gif87a_magic
,mask_all
,0},
975 {6,0,gif89a_magic
,mask_all
,0},
979 static const BYTE ico_magic
[] = {00,00,01,00};
981 static GUID
const * const ico_formats
[] = {
982 &GUID_WICPixelFormat32bppBGRA
,
986 static struct decoder_pattern
const ico_patterns
[] = {
987 {4,0,ico_magic
,mask_all
,0},
991 static const BYTE jpeg_magic
[] = {0xff, 0xd8};
993 static GUID
const * const jpeg_formats
[] = {
994 &GUID_WICPixelFormat24bppBGR
,
995 &GUID_WICPixelFormat32bppCMYK
,
996 &GUID_WICPixelFormat8bppGray
,
1000 static struct decoder_pattern
const jpeg_patterns
[] = {
1001 {2,0,jpeg_magic
,mask_all
,0},
1005 static const BYTE png_magic
[] = {137,80,78,71,13,10,26,10};
1007 static GUID
const * const png_formats
[] = {
1008 &GUID_WICPixelFormatBlackWhite
,
1009 &GUID_WICPixelFormat2bppGray
,
1010 &GUID_WICPixelFormat4bppGray
,
1011 &GUID_WICPixelFormat8bppGray
,
1012 &GUID_WICPixelFormat16bppGray
,
1013 &GUID_WICPixelFormat32bppBGRA
,
1014 &GUID_WICPixelFormat64bppRGBA
,
1015 &GUID_WICPixelFormat1bppIndexed
,
1016 &GUID_WICPixelFormat2bppIndexed
,
1017 &GUID_WICPixelFormat4bppIndexed
,
1018 &GUID_WICPixelFormat8bppIndexed
,
1019 &GUID_WICPixelFormat24bppBGR
,
1020 &GUID_WICPixelFormat48bppRGB
,
1024 static struct decoder_pattern
const png_patterns
[] = {
1025 {8,0,png_magic
,mask_all
,0},
1029 static const BYTE tiff_magic_le
[] = {0x49,0x49,42,0};
1030 static const BYTE tiff_magic_be
[] = {0x4d,0x4d,0,42};
1032 static GUID
const * const tiff_decode_formats
[] = {
1033 &GUID_WICPixelFormatBlackWhite
,
1034 &GUID_WICPixelFormat4bppGray
,
1035 &GUID_WICPixelFormat8bppGray
,
1036 &GUID_WICPixelFormat4bppIndexed
,
1037 &GUID_WICPixelFormat8bppIndexed
,
1038 &GUID_WICPixelFormat24bppBGR
,
1039 &GUID_WICPixelFormat32bppBGR
,
1040 &GUID_WICPixelFormat32bppBGRA
,
1041 &GUID_WICPixelFormat32bppPBGRA
,
1042 &GUID_WICPixelFormat48bppRGB
,
1043 &GUID_WICPixelFormat64bppRGBA
,
1044 &GUID_WICPixelFormat64bppPRGBA
,
1048 static struct decoder_pattern
const tiff_patterns
[] = {
1049 {4,0,tiff_magic_le
,mask_all
,0},
1050 {4,0,tiff_magic_be
,mask_all
,0},
1054 static const BYTE tga_footer_magic
[18] = "TRUEVISION-XFILE.";
1056 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};
1057 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};
1059 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};
1060 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};
1062 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};
1063 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};
1065 static GUID
const * const tga_formats
[] = {
1066 &GUID_WICPixelFormat8bppGray
,
1067 &GUID_WICPixelFormat8bppIndexed
,
1068 &GUID_WICPixelFormat16bppGray
,
1069 &GUID_WICPixelFormat16bppBGR555
,
1070 &GUID_WICPixelFormat24bppBGR
,
1071 &GUID_WICPixelFormat32bppBGRA
,
1072 &GUID_WICPixelFormat32bppPBGRA
,
1076 static struct decoder_pattern
const tga_patterns
[] = {
1077 {18,18,tga_footer_magic
,mask_all
,1},
1078 {18,0,tga_indexed_magic
,tga_indexed_mask
,0},
1079 {18,0,tga_truecolor_magic
,tga_truecolor_mask
,0},
1080 {18,0,tga_grayscale_magic
,tga_grayscale_mask
,0},
1084 static struct regsvr_decoder
const decoder_list
[] = {
1085 { &CLSID_WICBmpDecoder
,
1089 &GUID_VendorMicrosoft
,
1090 &GUID_ContainerFormatBmp
,
1096 { &CLSID_WICGifDecoder
,
1100 &GUID_VendorMicrosoft
,
1101 &GUID_ContainerFormatGif
,
1107 { &CLSID_WICIcoDecoder
,
1111 &GUID_VendorMicrosoft
,
1112 &GUID_ContainerFormatIco
,
1113 "image/vnd.microsoft.icon",
1118 { &CLSID_WICJpegDecoder
,
1122 &GUID_VendorMicrosoft
,
1123 &GUID_ContainerFormatJpeg
,
1129 { &CLSID_WICPngDecoder
,
1133 &GUID_VendorMicrosoft
,
1134 &GUID_ContainerFormatPng
,
1140 { &CLSID_WICTiffDecoder
,
1144 &GUID_VendorMicrosoft
,
1145 &GUID_ContainerFormatTiff
,
1148 tiff_decode_formats
,
1151 { &CLSID_WineTgaDecoder
,
1156 &GUID_WineContainerFormatTga
,
1162 { NULL
} /* list terminator */
1165 static GUID
const * const bmp_encode_formats
[] = {
1166 &GUID_WICPixelFormat16bppBGR555
,
1167 &GUID_WICPixelFormat16bppBGR565
,
1168 &GUID_WICPixelFormat24bppBGR
,
1169 &GUID_WICPixelFormat32bppBGR
,
1173 static GUID
const * const png_encode_formats
[] = {
1174 &GUID_WICPixelFormat24bppBGR
,
1175 &GUID_WICPixelFormatBlackWhite
,
1176 &GUID_WICPixelFormat2bppGray
,
1177 &GUID_WICPixelFormat4bppGray
,
1178 &GUID_WICPixelFormat8bppGray
,
1179 &GUID_WICPixelFormat16bppGray
,
1180 &GUID_WICPixelFormat32bppBGR
,
1181 &GUID_WICPixelFormat32bppBGRA
,
1182 &GUID_WICPixelFormat48bppRGB
,
1183 &GUID_WICPixelFormat64bppRGBA
,
1187 static GUID
const * const tiff_encode_formats
[] = {
1188 &GUID_WICPixelFormatBlackWhite
,
1189 &GUID_WICPixelFormat4bppGray
,
1190 &GUID_WICPixelFormat8bppGray
,
1191 &GUID_WICPixelFormat24bppBGR
,
1192 &GUID_WICPixelFormat32bppBGRA
,
1193 &GUID_WICPixelFormat32bppPBGRA
,
1194 &GUID_WICPixelFormat48bppRGB
,
1195 &GUID_WICPixelFormat64bppRGBA
,
1196 &GUID_WICPixelFormat64bppPRGBA
,
1200 static GUID
const * const icns_encode_formats
[] = {
1201 &GUID_WICPixelFormat32bppBGRA
,
1205 static struct regsvr_encoder
const encoder_list
[] = {
1206 { &CLSID_WICBmpEncoder
,
1210 &GUID_VendorMicrosoft
,
1211 &GUID_ContainerFormatBmp
,
1216 { &CLSID_WICJpegEncoder
,
1220 &GUID_VendorMicrosoft
,
1221 &GUID_ContainerFormatJpeg
,
1226 { &CLSID_WICPngEncoder
,
1230 &GUID_VendorMicrosoft
,
1231 &GUID_ContainerFormatPng
,
1236 { &CLSID_WICTiffEncoder
,
1240 &GUID_VendorMicrosoft
,
1241 &GUID_ContainerFormatTiff
,
1246 { &CLSID_WICIcnsEncoder
,
1251 NULL
, /* no container format guid */
1256 { NULL
} /* list terminator */
1259 static GUID
const * const converter_formats
[] = {
1260 &GUID_WICPixelFormat1bppIndexed
,
1261 &GUID_WICPixelFormat2bppIndexed
,
1262 &GUID_WICPixelFormat4bppIndexed
,
1263 &GUID_WICPixelFormat8bppIndexed
,
1264 &GUID_WICPixelFormatBlackWhite
,
1265 &GUID_WICPixelFormat2bppGray
,
1266 &GUID_WICPixelFormat4bppGray
,
1267 &GUID_WICPixelFormat8bppGray
,
1268 &GUID_WICPixelFormat16bppGray
,
1269 &GUID_WICPixelFormat16bppBGR555
,
1270 &GUID_WICPixelFormat16bppBGR565
,
1271 &GUID_WICPixelFormat16bppBGRA5551
,
1272 &GUID_WICPixelFormat24bppBGR
,
1273 &GUID_WICPixelFormat32bppBGR
,
1274 &GUID_WICPixelFormat32bppBGRA
,
1275 &GUID_WICPixelFormat32bppPBGRA
,
1276 &GUID_WICPixelFormat48bppRGB
,
1277 &GUID_WICPixelFormat64bppRGBA
,
1278 &GUID_WICPixelFormat32bppCMYK
,
1282 static struct regsvr_converter
const converter_list
[] = {
1283 { &CLSID_WICDefaultFormatConverter
,
1285 "Default Pixel Format Converter",
1287 &GUID_VendorMicrosoft
,
1290 { NULL
} /* list terminator */
1293 static struct regsvr_metadatareader
const metadatareader_list
[] = {
1294 { &CLSID_WICUnknownMetadataReader
,
1296 "Unknown Metadata Reader",
1299 &GUID_VendorMicrosoft
,
1300 &GUID_MetadataFormatUnknown
,
1306 { NULL
} /* list terminator */
1309 extern HRESULT WINAPI
WIC_DllRegisterServer(void) DECLSPEC_HIDDEN
;
1310 extern HRESULT WINAPI
WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
1312 HRESULT WINAPI
DllRegisterServer(void)
1318 hr
= WIC_DllRegisterServer();
1320 hr
= register_decoders(decoder_list
);
1322 hr
= register_encoders(encoder_list
);
1324 hr
= register_converters(converter_list
);
1326 hr
= register_metadatareaders(metadatareader_list
);
1330 HRESULT WINAPI
DllUnregisterServer(void)
1336 hr
= WIC_DllUnregisterServer();
1338 hr
= unregister_decoders(decoder_list
);
1340 hr
= unregister_encoders(encoder_list
);
1342 hr
= unregister_converters(converter_list
);
1344 hr
= unregister_metadatareaders(metadatareader_list
);