mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / windowscodecs / regsvr.c
blob5ab43353320643bcd1a991396ae2cb09bf5a32d8
1 /*
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 COBJMACROS
20 #include <stdarg.h>
21 #include <string.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26 #include "winuser.h"
27 #include "winreg.h"
28 #include "winerror.h"
30 #include "objbase.h"
31 #include "ocidl.h"
33 #include "wine/debug.h"
35 #include "wincodecs_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
39 /***********************************************************************
40 * interface for self-registering
42 struct decoder_pattern
44 DWORD length; /* 0 for end of list */
45 DWORD position;
46 const BYTE *pattern;
47 const BYTE *mask;
48 DWORD endofstream;
51 struct regsvr_decoder
53 CLSID const *clsid; /* NULL for end of list */
54 LPCSTR author;
55 LPCSTR friendlyname;
56 LPCSTR version;
57 GUID const *vendor;
58 GUID const *container_format;
59 LPCSTR mimetypes;
60 LPCSTR extensions;
61 GUID const * const *formats;
62 const struct decoder_pattern *patterns;
65 static HRESULT register_decoders(struct regsvr_decoder const *list);
66 static HRESULT unregister_decoders(struct regsvr_decoder const *list);
68 struct regsvr_encoder
70 CLSID const *clsid; /* NULL for end of list */
71 LPCSTR author;
72 LPCSTR friendlyname;
73 LPCSTR version;
74 GUID const *vendor;
75 GUID const *container_format;
76 LPCSTR mimetypes;
77 LPCSTR extensions;
78 GUID const * const *formats;
81 static HRESULT register_encoders(struct regsvr_encoder const *list);
82 static HRESULT unregister_encoders(struct regsvr_encoder const *list);
84 struct regsvr_converter
86 CLSID const *clsid; /* NULL for end of list */
87 LPCSTR author;
88 LPCSTR friendlyname;
89 LPCSTR version;
90 GUID const *vendor;
91 GUID const * const *formats;
94 static HRESULT register_converters(struct regsvr_converter const *list);
95 static HRESULT unregister_converters(struct regsvr_converter const *list);
97 struct metadata_pattern
99 DWORD position;
100 DWORD length;
101 const BYTE *pattern;
102 const BYTE *mask;
103 DWORD data_offset;
106 struct reader_containers
108 GUID const *format;
109 const struct metadata_pattern *patterns;
112 struct regsvr_metadatareader
114 CLSID const *clsid; /* NULL for end of list */
115 LPCSTR author;
116 LPCSTR friendlyname;
117 LPCSTR version;
118 LPCSTR specversion;
119 GUID const *vendor;
120 GUID const *metadata_format;
121 DWORD requires_fullstream;
122 DWORD supports_padding;
123 DWORD requires_fixedsize;
124 const struct reader_containers *containers;
127 static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list);
128 static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list);
130 struct regsvr_pixelformat
132 CLSID const *clsid; /* NULL for end of list */
133 LPCSTR author;
134 LPCSTR friendlyname;
135 LPCSTR version;
136 GUID const *vendor;
137 UINT bitsperpixel;
138 UINT channelcount;
139 BYTE const * const *channelmasks;
140 WICPixelFormatNumericRepresentation numericrepresentation;
141 UINT supportsalpha;
144 static HRESULT register_pixelformats(struct regsvr_pixelformat const *list);
145 static HRESULT unregister_pixelformats(struct regsvr_pixelformat const *list);
147 /***********************************************************************
148 * static string constants
150 static const WCHAR clsid_keyname[] = L"CLSID";
151 static const char author_valuename[] = "Author";
152 static const char friendlyname_valuename[] = "FriendlyName";
153 static const WCHAR vendor_valuename[] = L"Vendor";
154 static const WCHAR containerformat_valuename[] = L"ContainerFormat";
155 static const char version_valuename[] = "Version";
156 static const char mimetypes_valuename[] = "MimeTypes";
157 static const char extensions_valuename[] = "FileExtensions";
158 static const WCHAR formats_keyname[] = L"Formats";
159 static const WCHAR patterns_keyname[] = L"Patterns";
160 static const WCHAR instance_keyname[] = L"Instance";
161 static const WCHAR clsid_valuename[] = L"CLSID";
162 static const char length_valuename[] = "Length";
163 static const char position_valuename[] = "Position";
164 static const char pattern_valuename[] = "Pattern";
165 static const char mask_valuename[] = "Mask";
166 static const char endofstream_valuename[] = "EndOfStream";
167 static const WCHAR pixelformats_keyname[] = L"PixelFormats";
168 static const WCHAR metadataformat_valuename[] = L"MetadataFormat";
169 static const char specversion_valuename[] = "SpecVersion";
170 static const char requiresfullstream_valuename[] = "RequiresFullStream";
171 static const char supportspadding_valuename[] = "SupportsPadding";
172 static const char requiresfixedsize_valuename[] = "FixedSize";
173 static const WCHAR containers_keyname[] = L"Containers";
174 static const char dataoffset_valuename[] = "DataOffset";
175 static const char bitsperpixel_valuename[] = "BitLength";
176 static const char channelcount_valuename[] = "ChannelCount";
177 static const char numericrepresentation_valuename[] = "NumericRepresentation";
178 static const char supportstransparency_valuename[] = "SupportsTransparency";
179 static const WCHAR channelmasks_keyname[] = L"ChannelMasks";
181 /***********************************************************************
182 * register_decoders
184 static HRESULT register_decoders(struct regsvr_decoder const *list)
186 LONG res = ERROR_SUCCESS;
187 HKEY coclass_key;
188 WCHAR buf[39];
189 HKEY decoders_key;
190 HKEY instance_key;
192 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
193 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
194 if (res == ERROR_SUCCESS) {
195 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
196 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
197 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
198 if (res == ERROR_SUCCESS)
200 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
201 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
202 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
204 if (res != ERROR_SUCCESS)
205 RegCloseKey(coclass_key);
207 if (res != ERROR_SUCCESS) goto error_return;
209 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
210 HKEY clsid_key;
211 HKEY instance_clsid_key;
213 StringFromGUID2(list->clsid, buf, 39);
214 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
215 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
216 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
218 StringFromGUID2(list->clsid, buf, 39);
219 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
220 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
221 if (res == ERROR_SUCCESS) {
222 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
223 (const BYTE*)buf, 78);
224 RegCloseKey(instance_clsid_key);
226 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
228 if (list->author) {
229 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
230 (const BYTE*)list->author,
231 strlen(list->author) + 1);
232 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
235 if (list->friendlyname) {
236 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
237 (const BYTE*)list->friendlyname,
238 strlen(list->friendlyname) + 1);
239 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
242 if (list->vendor) {
243 StringFromGUID2(list->vendor, buf, 39);
244 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
245 (const BYTE*)buf, 78);
246 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
249 if (list->container_format) {
250 StringFromGUID2(list->container_format, buf, 39);
251 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ,
252 (const BYTE*)buf, 78);
253 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
256 if (list->version) {
257 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
258 (const BYTE*)list->version,
259 strlen(list->version) + 1);
260 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
263 if (list->mimetypes) {
264 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ,
265 (const BYTE*)list->mimetypes,
266 strlen(list->mimetypes) + 1);
267 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
270 if (list->extensions) {
271 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ,
272 (const BYTE*)list->extensions,
273 strlen(list->extensions) + 1);
274 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
277 if (list->formats) {
278 HKEY formats_key;
279 GUID const * const *format;
281 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0,
282 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
283 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
284 for (format=list->formats; *format; ++format)
286 HKEY format_key;
287 StringFromGUID2(*format, buf, 39);
288 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
289 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
290 if (res != ERROR_SUCCESS) break;
291 RegCloseKey(format_key);
293 RegCloseKey(formats_key);
294 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
297 if (list->patterns) {
298 HKEY patterns_key;
299 int i;
301 res = RegCreateKeyExW(clsid_key, patterns_keyname, 0, NULL, 0,
302 KEY_READ | KEY_WRITE, NULL, &patterns_key, NULL);
303 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
304 for (i=0; list->patterns[i].length; i++)
306 HKEY pattern_key;
307 swprintf(buf, 39, L"%i", 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);
341 error_return:
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;
351 HKEY coclass_key;
352 WCHAR buf[39];
353 HKEY decoders_key;
354 HKEY instance_key;
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);
391 error_return:
392 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
395 /***********************************************************************
396 * register_encoders
398 static HRESULT register_encoders(struct regsvr_encoder const *list)
400 LONG res = ERROR_SUCCESS;
401 HKEY coclass_key;
402 WCHAR buf[39];
403 HKEY encoders_key;
404 HKEY instance_key;
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) {
424 HKEY clsid_key;
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;
442 if (list->author) {
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;
456 if (list->vendor) {
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;
470 if (list->version) {
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;
491 if (list->formats) {
492 HKEY formats_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)
500 HKEY format_key;
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);
519 error_return:
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;
529 HKEY coclass_key;
530 WCHAR buf[39];
531 HKEY encoders_key;
532 HKEY instance_key;
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);
569 error_return:
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;
579 HKEY coclass_key;
580 WCHAR buf[39];
581 HKEY converters_key;
582 HKEY instance_key;
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) {
602 HKEY clsid_key;
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;
620 if (list->author) {
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;
634 if (list->vendor) {
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;
641 if (list->version) {
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;
648 if (list->formats) {
649 HKEY formats_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)
657 HKEY format_key;
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);
676 error_return:
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;
686 HKEY coclass_key;
687 WCHAR buf[39];
688 HKEY converters_key;
689 HKEY instance_key;
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);
726 error_return:
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;
736 HKEY coclass_key;
737 WCHAR buf[39];
738 HKEY readers_key;
739 HKEY instance_key;
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) {
759 HKEY clsid_key;
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;
777 if (list->author) {
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;
791 if (list->vendor) {
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;
798 if (list->metadata_format) {
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;
805 if (list->version) {
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) {
834 HKEY containers_key;
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)
842 HKEY format_key;
843 int i;
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++)
851 HKEY pattern_key;
852 swprintf(buf, 39, L"%i", i);
853 res = RegCreateKeyExW(format_key, buf, 0, NULL, 0,
854 KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL);
855 if (res != ERROR_SUCCESS) break;
856 res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD,
857 (const BYTE*)&container->patterns[i].position, 4);
858 if (res == ERROR_SUCCESS)
859 res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY,
860 container->patterns[i].pattern,
861 container->patterns[i].length);
862 if (res == ERROR_SUCCESS)
863 res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY,
864 container->patterns[i].mask,
865 container->patterns[i].length);
866 if (res == ERROR_SUCCESS && container->patterns[i].data_offset)
867 res = RegSetValueExA(pattern_key, dataoffset_valuename, 0, REG_DWORD,
868 (const BYTE*)&container->patterns[i].data_offset, 4);
869 RegCloseKey(pattern_key);
872 RegCloseKey(format_key);
874 RegCloseKey(containers_key);
877 error_close_clsid_key:
878 RegCloseKey(clsid_key);
881 error_close_coclass_key:
882 RegCloseKey(instance_key);
883 RegCloseKey(readers_key);
884 RegCloseKey(coclass_key);
885 error_return:
886 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
889 /***********************************************************************
890 * unregister_metadatareaders
892 static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list)
894 LONG res = ERROR_SUCCESS;
895 HKEY coclass_key;
896 WCHAR buf[39];
897 HKEY readers_key;
898 HKEY instance_key;
900 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
901 KEY_READ | KEY_WRITE, &coclass_key);
902 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
904 if (res == ERROR_SUCCESS) {
905 StringFromGUID2(&CATID_WICMetadataReader, buf, 39);
906 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
907 KEY_READ | KEY_WRITE, NULL, &readers_key, NULL);
908 if (res == ERROR_SUCCESS)
910 res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0,
911 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
912 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
914 if (res != ERROR_SUCCESS)
915 RegCloseKey(coclass_key);
917 if (res != ERROR_SUCCESS) goto error_return;
919 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
920 StringFromGUID2(list->clsid, buf, 39);
922 res = RegDeleteTreeW(coclass_key, buf);
923 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
924 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
926 res = RegDeleteTreeW(instance_key, buf);
927 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
928 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
931 error_close_coclass_key:
932 RegCloseKey(instance_key);
933 RegCloseKey(readers_key);
934 RegCloseKey(coclass_key);
935 error_return:
936 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
939 /***********************************************************************
940 * register_pixelformats
942 static HRESULT register_pixelformats(struct regsvr_pixelformat const *list)
944 LONG res = ERROR_SUCCESS;
945 HKEY coclass_key;
946 WCHAR buf[39];
947 HKEY formats_key;
948 HKEY instance_key;
950 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
951 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
952 if (res == ERROR_SUCCESS) {
953 StringFromGUID2(&CATID_WICPixelFormats, buf, 39);
954 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
955 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
956 if (res == ERROR_SUCCESS)
958 res = RegCreateKeyExW(formats_key, instance_keyname, 0, NULL, 0,
959 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
960 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
962 if (res != ERROR_SUCCESS)
963 RegCloseKey(coclass_key);
965 if (res != ERROR_SUCCESS) goto error_return;
967 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
968 HKEY clsid_key;
969 HKEY instance_clsid_key;
971 StringFromGUID2(list->clsid, buf, 39);
972 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
973 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
974 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
976 StringFromGUID2(list->clsid, buf, 39);
977 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
978 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
979 if (res == ERROR_SUCCESS) {
980 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
981 (const BYTE*)buf, 78);
982 RegCloseKey(instance_clsid_key);
984 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
986 if (list->author) {
987 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
988 (const BYTE*)list->author,
989 strlen(list->author) + 1);
990 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
993 if (list->friendlyname) {
994 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
995 (const BYTE*)list->friendlyname,
996 strlen(list->friendlyname) + 1);
997 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1000 if (list->vendor) {
1001 StringFromGUID2(list->vendor, buf, 39);
1002 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
1003 (const BYTE*)buf, 78);
1004 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1007 if (list->version) {
1008 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
1009 (const BYTE*)list->version,
1010 strlen(list->version) + 1);
1011 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1014 res = RegSetValueExA(clsid_key, bitsperpixel_valuename, 0, REG_DWORD,
1015 (const BYTE*)&list->bitsperpixel, 4);
1016 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1018 res = RegSetValueExA(clsid_key, channelcount_valuename, 0, REG_DWORD,
1019 (const BYTE*)&list->channelcount, 4);
1020 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1022 res = RegSetValueExA(clsid_key, numericrepresentation_valuename, 0, REG_DWORD,
1023 (const BYTE*)&list->numericrepresentation, 4);
1024 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1026 res = RegSetValueExA(clsid_key, supportstransparency_valuename, 0, REG_DWORD,
1027 (const BYTE*)&list->supportsalpha, 4);
1028 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1030 if (list->channelmasks) {
1031 HKEY masks_key;
1032 UINT i, mask_size;
1033 WCHAR mask_valuename[11];
1035 mask_size = (list->bitsperpixel + 7)/8;
1037 res = RegCreateKeyExW(clsid_key, channelmasks_keyname, 0, NULL, 0,
1038 KEY_READ | KEY_WRITE, NULL, &masks_key, NULL);
1039 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1040 for (i=0; i < list->channelcount; i++)
1042 swprintf(mask_valuename, ARRAY_SIZE(mask_valuename), L"%d", i);
1043 res = RegSetValueExW(masks_key, mask_valuename, 0, REG_BINARY,
1044 list->channelmasks[i], mask_size);
1045 if (res != ERROR_SUCCESS) break;
1047 RegCloseKey(masks_key);
1048 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1051 error_close_clsid_key:
1052 RegCloseKey(clsid_key);
1055 error_close_coclass_key:
1056 RegCloseKey(instance_key);
1057 RegCloseKey(formats_key);
1058 RegCloseKey(coclass_key);
1059 error_return:
1060 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
1063 /***********************************************************************
1064 * unregister_pixelformats
1066 static HRESULT unregister_pixelformats(struct regsvr_pixelformat const *list)
1068 LONG res = ERROR_SUCCESS;
1069 HKEY coclass_key;
1070 WCHAR buf[39];
1071 HKEY formats_key;
1072 HKEY instance_key;
1074 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
1075 KEY_READ | KEY_WRITE, &coclass_key);
1076 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
1078 if (res == ERROR_SUCCESS) {
1079 StringFromGUID2(&CATID_WICPixelFormats, buf, 39);
1080 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
1081 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
1082 if (res == ERROR_SUCCESS)
1084 res = RegCreateKeyExW(formats_key, instance_keyname, 0, NULL, 0,
1085 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
1086 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1088 if (res != ERROR_SUCCESS)
1089 RegCloseKey(coclass_key);
1091 if (res != ERROR_SUCCESS) goto error_return;
1093 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
1094 StringFromGUID2(list->clsid, buf, 39);
1096 res = RegDeleteTreeW(coclass_key, buf);
1097 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
1098 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1100 res = RegDeleteTreeW(instance_key, buf);
1101 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
1102 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1105 error_close_coclass_key:
1106 RegCloseKey(instance_key);
1107 RegCloseKey(formats_key);
1108 RegCloseKey(coclass_key);
1109 error_return:
1110 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
1113 /***********************************************************************
1114 * decoder list
1116 static const BYTE mask_all[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1118 static const BYTE bmp_magic[] = {0x42,0x4d};
1120 static GUID const * const bmp_formats[] = {
1121 &GUID_WICPixelFormat1bppIndexed,
1122 &GUID_WICPixelFormat2bppIndexed,
1123 &GUID_WICPixelFormat4bppIndexed,
1124 &GUID_WICPixelFormat8bppIndexed,
1125 &GUID_WICPixelFormat16bppBGR555,
1126 &GUID_WICPixelFormat16bppBGR565,
1127 &GUID_WICPixelFormat24bppBGR,
1128 &GUID_WICPixelFormat32bppBGR,
1129 &GUID_WICPixelFormat32bppBGRA,
1130 NULL
1133 static struct decoder_pattern const bmp_patterns[] = {
1134 {2,0,bmp_magic,mask_all,0},
1138 static const BYTE dds_magic[] = "DDS ";
1140 static GUID const * const dds_formats[] = {
1141 &GUID_WICPixelFormat32bppBGRA,
1142 NULL
1145 static struct decoder_pattern const dds_patterns[] = {
1146 {4,0,dds_magic,mask_all,0},
1150 static const BYTE gif87a_magic[6] = "GIF87a";
1151 static const BYTE gif89a_magic[6] = "GIF89a";
1153 static GUID const * const gif_formats[] = {
1154 &GUID_WICPixelFormat8bppIndexed,
1155 NULL
1158 static struct decoder_pattern const gif_patterns[] = {
1159 {6,0,gif87a_magic,mask_all,0},
1160 {6,0,gif89a_magic,mask_all,0},
1164 static const BYTE ico_magic[] = {00,00,01,00};
1166 static GUID const * const ico_formats[] = {
1167 &GUID_WICPixelFormat32bppBGRA,
1168 NULL
1171 static struct decoder_pattern const ico_patterns[] = {
1172 {4,0,ico_magic,mask_all,0},
1176 static const BYTE jpeg_magic[] = {0xff, 0xd8};
1178 static GUID const * const jpeg_formats[] = {
1179 &GUID_WICPixelFormat24bppBGR,
1180 &GUID_WICPixelFormat32bppCMYK,
1181 &GUID_WICPixelFormat8bppGray,
1182 NULL
1185 static struct decoder_pattern const jpeg_patterns[] = {
1186 {2,0,jpeg_magic,mask_all,0},
1190 static const BYTE wmp_magic_v0[] = {0x49, 0x49, 0xbc, 0x00};
1191 static const BYTE wmp_magic_v1[] = {0x49, 0x49, 0xbc, 0x01};
1193 static GUID const * const wmp_formats[] = {
1194 &GUID_WICPixelFormat128bppRGBAFixedPoint,
1195 &GUID_WICPixelFormat128bppRGBAFloat,
1196 &GUID_WICPixelFormat128bppRGBFloat,
1197 &GUID_WICPixelFormat16bppBGR555,
1198 &GUID_WICPixelFormat16bppBGR565,
1199 &GUID_WICPixelFormat16bppGray,
1200 &GUID_WICPixelFormat16bppGrayFixedPoint,
1201 &GUID_WICPixelFormat16bppGrayHalf,
1202 &GUID_WICPixelFormat24bppBGR,
1203 &GUID_WICPixelFormat24bppRGB,
1204 &GUID_WICPixelFormat32bppBGR,
1205 &GUID_WICPixelFormat32bppBGR101010,
1206 &GUID_WICPixelFormat32bppBGRA,
1207 &GUID_WICPixelFormat32bppCMYK,
1208 &GUID_WICPixelFormat32bppGrayFixedPoint,
1209 &GUID_WICPixelFormat32bppGrayFloat,
1210 &GUID_WICPixelFormat32bppRGBE,
1211 &GUID_WICPixelFormat40bppCMYKAlpha,
1212 &GUID_WICPixelFormat48bppRGB,
1213 &GUID_WICPixelFormat48bppRGBFixedPoint,
1214 &GUID_WICPixelFormat48bppRGBHalf,
1215 &GUID_WICPixelFormat64bppCMYK,
1216 &GUID_WICPixelFormat64bppRGBA,
1217 &GUID_WICPixelFormat64bppRGBAFixedPoint,
1218 &GUID_WICPixelFormat64bppRGBAHalf,
1219 &GUID_WICPixelFormat80bppCMYKAlpha,
1220 &GUID_WICPixelFormat8bppGray,
1221 &GUID_WICPixelFormat96bppRGBFixedPoint,
1222 &GUID_WICPixelFormatBlackWhite,
1223 NULL
1226 static struct decoder_pattern const wmp_patterns[] = {
1227 {4,0,wmp_magic_v0,mask_all,0},
1228 {4,0,wmp_magic_v1,mask_all,0},
1232 static const BYTE png_magic[] = {137,80,78,71,13,10,26,10};
1234 static GUID const * const png_formats[] = {
1235 &GUID_WICPixelFormatBlackWhite,
1236 &GUID_WICPixelFormat2bppGray,
1237 &GUID_WICPixelFormat4bppGray,
1238 &GUID_WICPixelFormat8bppGray,
1239 &GUID_WICPixelFormat16bppGray,
1240 &GUID_WICPixelFormat32bppBGRA,
1241 &GUID_WICPixelFormat64bppRGBA,
1242 &GUID_WICPixelFormat1bppIndexed,
1243 &GUID_WICPixelFormat2bppIndexed,
1244 &GUID_WICPixelFormat4bppIndexed,
1245 &GUID_WICPixelFormat8bppIndexed,
1246 &GUID_WICPixelFormat24bppBGR,
1247 &GUID_WICPixelFormat48bppRGB,
1248 NULL
1251 static struct decoder_pattern const png_patterns[] = {
1252 {8,0,png_magic,mask_all,0},
1256 static const BYTE tiff_magic_le[] = {0x49,0x49,42,0};
1257 static const BYTE tiff_magic_be[] = {0x4d,0x4d,0,42};
1259 static GUID const * const tiff_decode_formats[] = {
1260 &GUID_WICPixelFormatBlackWhite,
1261 &GUID_WICPixelFormat4bppGray,
1262 &GUID_WICPixelFormat8bppGray,
1263 &GUID_WICPixelFormat16bppGray,
1264 &GUID_WICPixelFormat32bppGrayFloat,
1265 &GUID_WICPixelFormat1bppIndexed,
1266 &GUID_WICPixelFormat2bppIndexed,
1267 &GUID_WICPixelFormat4bppIndexed,
1268 &GUID_WICPixelFormat8bppIndexed,
1269 &GUID_WICPixelFormat24bppBGR,
1270 &GUID_WICPixelFormat32bppBGR,
1271 &GUID_WICPixelFormat32bppBGRA,
1272 &GUID_WICPixelFormat32bppPBGRA,
1273 &GUID_WICPixelFormat48bppRGB,
1274 &GUID_WICPixelFormat64bppRGBA,
1275 &GUID_WICPixelFormat64bppPRGBA,
1276 &GUID_WICPixelFormat32bppCMYK,
1277 &GUID_WICPixelFormat64bppCMYK,
1278 &GUID_WICPixelFormat96bppRGBFloat,
1279 &GUID_WICPixelFormat128bppRGBAFloat,
1280 &GUID_WICPixelFormat128bppPRGBAFloat,
1281 NULL
1284 static struct decoder_pattern const tiff_patterns[] = {
1285 {4,0,tiff_magic_le,mask_all,0},
1286 {4,0,tiff_magic_be,mask_all,0},
1290 static const BYTE tga_footer_magic[18] = "TRUEVISION-XFILE.";
1292 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};
1293 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};
1295 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};
1296 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};
1298 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};
1299 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};
1301 static GUID const * const tga_formats[] = {
1302 &GUID_WICPixelFormat8bppGray,
1303 &GUID_WICPixelFormat8bppIndexed,
1304 &GUID_WICPixelFormat16bppGray,
1305 &GUID_WICPixelFormat16bppBGR555,
1306 &GUID_WICPixelFormat24bppBGR,
1307 &GUID_WICPixelFormat32bppBGRA,
1308 &GUID_WICPixelFormat32bppPBGRA,
1309 NULL
1312 static struct decoder_pattern const tga_patterns[] = {
1313 {18,18,tga_footer_magic,mask_all,1},
1314 {18,0,tga_indexed_magic,tga_indexed_mask,0},
1315 {18,0,tga_truecolor_magic,tga_truecolor_mask,0},
1316 {18,0,tga_grayscale_magic,tga_grayscale_mask,0},
1320 static struct regsvr_decoder const decoder_list[] = {
1321 { &CLSID_WICBmpDecoder,
1322 "The Wine Project",
1323 "BMP Decoder",
1324 "1.0.0.0",
1325 &GUID_VendorMicrosoft,
1326 &GUID_ContainerFormatBmp,
1327 "image/bmp",
1328 ".bmp,.dib,.rle",
1329 bmp_formats,
1330 bmp_patterns
1332 { &CLSID_WICDdsDecoder,
1333 "The Wine Project",
1334 "DDS Decoder",
1335 "1.0.0.0",
1336 &GUID_VendorMicrosoft,
1337 &GUID_ContainerFormatDds,
1338 "image/vnd.ms-dds",
1339 ".dds",
1340 dds_formats,
1341 dds_patterns
1343 { &CLSID_WICGifDecoder,
1344 "The Wine Project",
1345 "GIF Decoder",
1346 "1.0.0.0",
1347 &GUID_VendorMicrosoft,
1348 &GUID_ContainerFormatGif,
1349 "image/gif",
1350 ".gif",
1351 gif_formats,
1352 gif_patterns
1354 { &CLSID_WICIcoDecoder,
1355 "The Wine Project",
1356 "ICO Decoder",
1357 "1.0.0.0",
1358 &GUID_VendorMicrosoft,
1359 &GUID_ContainerFormatIco,
1360 "image/vnd.microsoft.icon",
1361 ".ico",
1362 ico_formats,
1363 ico_patterns
1365 { &CLSID_WICJpegDecoder,
1366 "The Wine Project",
1367 "JPEG Decoder",
1368 "1.0.0.0",
1369 &GUID_VendorMicrosoft,
1370 &GUID_ContainerFormatJpeg,
1371 "image/jpeg",
1372 ".jpg;.jpeg;.jfif",
1373 jpeg_formats,
1374 jpeg_patterns
1376 { &CLSID_WICWmpDecoder,
1377 "The Wine Project",
1378 "JPEG-XR Decoder",
1379 "1.0.0.0",
1380 &GUID_VendorMicrosoft,
1381 &GUID_ContainerFormatWmp,
1382 "image/jxr",
1383 ".jxr;.hdp;.wdp",
1384 wmp_formats,
1385 wmp_patterns
1387 { &CLSID_WICPngDecoder,
1388 "The Wine Project",
1389 "PNG Decoder",
1390 "1.0.0.0",
1391 &GUID_VendorMicrosoft,
1392 &GUID_ContainerFormatPng,
1393 "image/png",
1394 ".png",
1395 png_formats,
1396 png_patterns
1398 { &CLSID_WICTiffDecoder,
1399 "The Wine Project",
1400 "TIFF Decoder",
1401 "1.0.0.0",
1402 &GUID_VendorMicrosoft,
1403 &GUID_ContainerFormatTiff,
1404 "image/tiff",
1405 ".tif;.tiff",
1406 tiff_decode_formats,
1407 tiff_patterns
1409 { &CLSID_WineTgaDecoder,
1410 "The Wine Project",
1411 "TGA Decoder",
1412 "1.0.0.0",
1413 &GUID_VendorWine,
1414 &GUID_WineContainerFormatTga,
1415 "image/x-targa",
1416 ".tga;.tpic",
1417 tga_formats,
1418 tga_patterns
1420 { NULL } /* list terminator */
1423 static GUID const * const bmp_encode_formats[] = {
1424 &GUID_WICPixelFormat16bppBGR555,
1425 &GUID_WICPixelFormat16bppBGR565,
1426 &GUID_WICPixelFormat24bppBGR,
1427 &GUID_WICPixelFormat32bppBGR,
1428 &GUID_WICPixelFormatBlackWhite,
1429 &GUID_WICPixelFormat1bppIndexed,
1430 &GUID_WICPixelFormat4bppIndexed,
1431 &GUID_WICPixelFormat8bppIndexed,
1432 NULL
1435 static GUID const * const png_encode_formats[] = {
1436 &GUID_WICPixelFormat24bppBGR,
1437 &GUID_WICPixelFormatBlackWhite,
1438 &GUID_WICPixelFormat2bppGray,
1439 &GUID_WICPixelFormat4bppGray,
1440 &GUID_WICPixelFormat8bppGray,
1441 &GUID_WICPixelFormat16bppGray,
1442 &GUID_WICPixelFormat32bppBGR,
1443 &GUID_WICPixelFormat32bppBGRA,
1444 &GUID_WICPixelFormat48bppRGB,
1445 &GUID_WICPixelFormat64bppRGBA,
1446 &GUID_WICPixelFormat1bppIndexed,
1447 &GUID_WICPixelFormat2bppIndexed,
1448 &GUID_WICPixelFormat4bppIndexed,
1449 &GUID_WICPixelFormat8bppIndexed,
1450 NULL
1453 static GUID const * const tiff_encode_formats[] = {
1454 &GUID_WICPixelFormatBlackWhite,
1455 &GUID_WICPixelFormat4bppGray,
1456 &GUID_WICPixelFormat8bppGray,
1457 &GUID_WICPixelFormat1bppIndexed,
1458 &GUID_WICPixelFormat4bppIndexed,
1459 &GUID_WICPixelFormat8bppIndexed,
1460 &GUID_WICPixelFormat24bppBGR,
1461 &GUID_WICPixelFormat32bppBGRA,
1462 &GUID_WICPixelFormat32bppPBGRA,
1463 &GUID_WICPixelFormat48bppRGB,
1464 &GUID_WICPixelFormat64bppRGBA,
1465 &GUID_WICPixelFormat64bppPRGBA,
1466 NULL
1469 static GUID const * const icns_encode_formats[] = {
1470 &GUID_WICPixelFormat32bppBGRA,
1471 NULL
1474 static struct regsvr_encoder const encoder_list[] = {
1475 { &CLSID_WICBmpEncoder,
1476 "The Wine Project",
1477 "BMP Encoder",
1478 "1.0.0.0",
1479 &GUID_VendorMicrosoft,
1480 &GUID_ContainerFormatBmp,
1481 "image/bmp",
1482 ".bmp,.dib,.rle",
1483 bmp_encode_formats
1485 { &CLSID_WICGifEncoder,
1486 "The Wine Project",
1487 "GIF Encoder",
1488 "1.0.0.0",
1489 &GUID_VendorMicrosoft,
1490 &GUID_ContainerFormatGif,
1491 "image/gif",
1492 ".gif",
1493 gif_formats
1495 { &CLSID_WICJpegEncoder,
1496 "The Wine Project",
1497 "JPEG Encoder",
1498 "1.0.0.0",
1499 &GUID_VendorMicrosoft,
1500 &GUID_ContainerFormatJpeg,
1501 "image/jpeg",
1502 ".jpg;.jpeg;.jfif",
1503 jpeg_formats
1505 { &CLSID_WICPngEncoder,
1506 "The Wine Project",
1507 "PNG Encoder",
1508 "1.0.0.0",
1509 &GUID_VendorMicrosoft,
1510 &GUID_ContainerFormatPng,
1511 "image/png",
1512 ".png",
1513 png_encode_formats
1515 { &CLSID_WICTiffEncoder,
1516 "The Wine Project",
1517 "TIFF Encoder",
1518 "1.0.0.0",
1519 &GUID_VendorMicrosoft,
1520 &GUID_ContainerFormatTiff,
1521 "image/tiff",
1522 ".tif;.tiff",
1523 tiff_encode_formats
1525 { &CLSID_WICIcnsEncoder,
1526 "The Wine Project",
1527 "ICNS Encoder",
1528 "1.0.0.0",
1529 &GUID_VendorWine,
1530 &GUID_WineContainerFormatIcns,
1531 "image/icns",
1532 ".icns",
1533 icns_encode_formats
1535 { NULL } /* list terminator */
1538 static GUID const * const converter_formats[] = {
1539 &GUID_WICPixelFormat1bppIndexed,
1540 &GUID_WICPixelFormat2bppIndexed,
1541 &GUID_WICPixelFormat4bppIndexed,
1542 &GUID_WICPixelFormat8bppIndexed,
1543 &GUID_WICPixelFormatBlackWhite,
1544 &GUID_WICPixelFormat2bppGray,
1545 &GUID_WICPixelFormat4bppGray,
1546 &GUID_WICPixelFormat8bppGray,
1547 &GUID_WICPixelFormat16bppGray,
1548 &GUID_WICPixelFormat16bppBGR555,
1549 &GUID_WICPixelFormat16bppBGR565,
1550 &GUID_WICPixelFormat16bppBGRA5551,
1551 &GUID_WICPixelFormat24bppBGR,
1552 &GUID_WICPixelFormat24bppRGB,
1553 &GUID_WICPixelFormat32bppBGR,
1554 &GUID_WICPixelFormat32bppRGB,
1555 &GUID_WICPixelFormat32bppBGRA,
1556 &GUID_WICPixelFormat32bppRGBA,
1557 &GUID_WICPixelFormat32bppPBGRA,
1558 &GUID_WICPixelFormat32bppPRGBA,
1559 &GUID_WICPixelFormat32bppGrayFloat,
1560 &GUID_WICPixelFormat48bppRGB,
1561 &GUID_WICPixelFormat64bppRGBA,
1562 &GUID_WICPixelFormat32bppCMYK,
1563 NULL
1566 static struct regsvr_converter const converter_list[] = {
1567 { &CLSID_WICDefaultFormatConverter,
1568 "The Wine Project",
1569 "Default Pixel Format Converter",
1570 "1.0.0.0",
1571 &GUID_VendorMicrosoft,
1572 converter_formats
1574 { NULL } /* list terminator */
1577 static const BYTE no_magic[1] = { 0 };
1578 static const BYTE no_mask[1] = { 0 };
1580 static const struct metadata_pattern ifd_metadata_pattern[] = {
1581 { 0, 1, no_magic, no_mask, 0 },
1582 { 0 }
1585 static const struct reader_containers ifd_containers[] = {
1587 &GUID_ContainerFormatTiff,
1588 ifd_metadata_pattern
1590 { NULL } /* list terminator */
1593 static const BYTE tEXt[] = "tEXt";
1595 static const struct metadata_pattern pngtext_metadata_pattern[] = {
1596 { 4, 4, tEXt, mask_all, 4 },
1597 { 0 }
1600 static const struct reader_containers pngtext_containers[] = {
1602 &GUID_ContainerFormatPng,
1603 pngtext_metadata_pattern
1605 { NULL } /* list terminator */
1608 static const BYTE gAMA[] = "gAMA";
1610 static const struct metadata_pattern pnggama_metadata_pattern[] = {
1611 { 4, 4, gAMA, mask_all, 4 },
1612 { 0 }
1615 static const struct reader_containers pnggama_containers[] = {
1617 &GUID_ContainerFormatPng,
1618 pnggama_metadata_pattern
1620 { NULL } /* list terminator */
1623 static const BYTE cHRM[] = "cHRM";
1625 static const struct metadata_pattern pngchrm_metadata_pattern[] = {
1626 { 4, 4, cHRM, mask_all, 4 },
1627 { 0 }
1630 static const struct reader_containers pngchrm_containers[] = {
1632 &GUID_ContainerFormatPng,
1633 pngchrm_metadata_pattern
1635 { NULL } /* list terminator */
1638 static const struct metadata_pattern lsd_metadata_patterns[] = {
1639 { 0, 6, gif87a_magic, mask_all, 0 },
1640 { 0, 6, gif89a_magic, mask_all, 0 },
1641 { 0 }
1644 static const struct reader_containers lsd_containers[] = {
1646 &GUID_ContainerFormatGif,
1647 lsd_metadata_patterns
1649 { NULL } /* list terminator */
1652 static const BYTE imd_magic[] = { 0x2c };
1654 static const struct metadata_pattern imd_metadata_pattern[] = {
1655 { 0, 1, imd_magic, mask_all, 1 },
1656 { 0 }
1659 static const struct reader_containers imd_containers[] = {
1661 &GUID_ContainerFormatGif,
1662 imd_metadata_pattern
1664 { NULL } /* list terminator */
1667 static const BYTE gce_magic[] = { 0x21, 0xf9, 0x04 };
1669 static const struct metadata_pattern gce_metadata_pattern[] = {
1670 { 0, 3, gce_magic, mask_all, 3 },
1671 { 0 }
1674 static const struct reader_containers gce_containers[] = {
1676 &GUID_ContainerFormatGif,
1677 gce_metadata_pattern
1679 { NULL } /* list terminator */
1682 static const BYTE ape_magic[] = { 0x21, 0xff, 0x0b };
1684 static const struct metadata_pattern ape_metadata_pattern[] = {
1685 { 0, 3, ape_magic, mask_all, 0 },
1686 { 0 }
1689 static const struct reader_containers ape_containers[] = {
1691 &GUID_ContainerFormatGif,
1692 ape_metadata_pattern
1694 { NULL } /* list terminator */
1697 static const BYTE gif_comment_magic[] = { 0x21, 0xfe };
1699 static const struct metadata_pattern gif_comment_metadata_pattern[] = {
1700 { 0, 2, gif_comment_magic, mask_all, 0 },
1701 { 0 }
1704 static const struct reader_containers gif_comment_containers[] = {
1706 &GUID_ContainerFormatGif,
1707 gif_comment_metadata_pattern
1709 { NULL } /* list terminator */
1712 static struct regsvr_metadatareader const metadatareader_list[] = {
1713 { &CLSID_WICUnknownMetadataReader,
1714 "The Wine Project",
1715 "Unknown Metadata Reader",
1716 "1.0.0.0",
1717 "1.0.0.0",
1718 &GUID_VendorMicrosoft,
1719 &GUID_MetadataFormatUnknown,
1720 0, 0, 0,
1721 NULL
1723 { &CLSID_WICIfdMetadataReader,
1724 "The Wine Project",
1725 "Ifd Reader",
1726 "1.0.0.0",
1727 "1.0.0.0",
1728 &GUID_VendorMicrosoft,
1729 &GUID_MetadataFormatIfd,
1730 1, 1, 0,
1731 ifd_containers
1733 { &CLSID_WICPngChrmMetadataReader,
1734 "The Wine Project",
1735 "Chunk cHRM Reader",
1736 "1.0.0.0",
1737 "1.0.0.0",
1738 &GUID_VendorMicrosoft,
1739 &GUID_MetadataFormatChunkcHRM,
1740 0, 0, 0,
1741 pngchrm_containers
1743 { &CLSID_WICPngGamaMetadataReader,
1744 "The Wine Project",
1745 "Chunk gAMA Reader",
1746 "1.0.0.0",
1747 "1.0.0.0",
1748 &GUID_VendorMicrosoft,
1749 &GUID_MetadataFormatChunkgAMA,
1750 0, 0, 0,
1751 pnggama_containers
1753 { &CLSID_WICPngTextMetadataReader,
1754 "The Wine Project",
1755 "Chunk tEXt Reader",
1756 "1.0.0.0",
1757 "1.0.0.0",
1758 &GUID_VendorMicrosoft,
1759 &GUID_MetadataFormatChunktEXt,
1760 0, 0, 0,
1761 pngtext_containers
1763 { &CLSID_WICLSDMetadataReader,
1764 "The Wine Project",
1765 "Logical Screen Descriptor Reader",
1766 "1.0.0.0",
1767 "1.0.0.0",
1768 &GUID_VendorMicrosoft,
1769 &GUID_MetadataFormatLSD,
1770 0, 0, 0,
1771 lsd_containers
1773 { &CLSID_WICIMDMetadataReader,
1774 "The Wine Project",
1775 "Image Descriptor Reader",
1776 "1.0.0.0",
1777 "1.0.0.0",
1778 &GUID_VendorMicrosoft,
1779 &GUID_MetadataFormatIMD,
1780 0, 0, 0,
1781 imd_containers
1783 { &CLSID_WICGCEMetadataReader,
1784 "The Wine Project",
1785 "Graphic Control Extension Reader",
1786 "1.0.0.0",
1787 "1.0.0.0",
1788 &GUID_VendorMicrosoft,
1789 &GUID_MetadataFormatGCE,
1790 0, 0, 0,
1791 gce_containers
1793 { &CLSID_WICAPEMetadataReader,
1794 "The Wine Project",
1795 "Application Extension Reader",
1796 "1.0.0.0",
1797 "1.0.0.0",
1798 &GUID_VendorMicrosoft,
1799 &GUID_MetadataFormatAPE,
1800 0, 0, 0,
1801 ape_containers
1803 { &CLSID_WICGifCommentMetadataReader,
1804 "The Wine Project",
1805 "Comment Extension Reader",
1806 "1.0.0.0",
1807 "1.0.0.0",
1808 &GUID_VendorMicrosoft,
1809 &GUID_MetadataFormatGifComment,
1810 0, 0, 0,
1811 gif_comment_containers
1813 { NULL } /* list terminator */
1816 static BYTE const channel_mask_1bit[] = { 0x01 };
1817 static BYTE const channel_mask_2bit[] = { 0x03 };
1818 static BYTE const channel_mask_4bit[] = { 0x0f };
1820 static BYTE const channel_mask_8bit[] = { 0xff, 0x00, 0x00, 0x00 };
1821 static BYTE const channel_mask_8bit2[] = { 0x00, 0xff, 0x00, 0x00 };
1822 static BYTE const channel_mask_8bit3[] = { 0x00, 0x00, 0xff, 0x00 };
1823 static BYTE const channel_mask_8bit4[] = { 0x00, 0x00, 0x00, 0xff };
1825 static BYTE const channel_mask_16bit[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1826 static BYTE const channel_mask_16bit2[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1827 static BYTE const channel_mask_16bit3[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
1828 static BYTE const channel_mask_16bit4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
1830 static BYTE const channel_mask_32bit[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1832 static BYTE const channel_mask_96bit1[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1833 static BYTE const channel_mask_96bit2[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 };
1834 static BYTE const channel_mask_96bit3[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff };
1836 static BYTE const channel_mask_128bit1[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1837 static BYTE const channel_mask_128bit2[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1838 static BYTE const channel_mask_128bit3[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 };
1839 static BYTE const channel_mask_128bit4[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff };
1841 static BYTE const channel_mask_5bit[] = { 0x1f, 0x00 };
1842 static BYTE const channel_mask_5bit2[] = { 0xe0, 0x03 };
1843 static BYTE const channel_mask_5bit3[] = { 0x00, 0x7c };
1844 static BYTE const channel_mask_5bit4[] = { 0x00, 0x80 };
1846 static BYTE const channel_mask_BGR565_2[] = { 0xe0, 0x07 };
1847 static BYTE const channel_mask_BGR565_3[] = { 0x00, 0xf8 };
1849 static BYTE const * const channel_masks_1bit[] = { channel_mask_1bit };
1850 static BYTE const * const channel_masks_2bit[] = { channel_mask_2bit };
1851 static BYTE const * const channel_masks_4bit[] = { channel_mask_4bit };
1852 static BYTE const * const channel_masks_8bit[] = { channel_mask_8bit,
1853 channel_mask_8bit2, channel_mask_8bit3, channel_mask_8bit4 };
1854 static BYTE const * const channel_masks_16bit[] = { channel_mask_16bit,
1855 channel_mask_16bit2, channel_mask_16bit3, channel_mask_16bit4};
1857 static BYTE const * const channel_masks_32bit[] = { channel_mask_32bit };
1858 static BYTE const * const channel_masks_96bit[] = { channel_mask_96bit1, channel_mask_96bit2, channel_mask_96bit3 };
1859 static BYTE const * const channel_masks_128bit[] = { channel_mask_128bit1, channel_mask_128bit2, channel_mask_128bit3, channel_mask_128bit4 };
1861 static BYTE const * const channel_masks_BGRA5551[] = { channel_mask_5bit,
1862 channel_mask_5bit2, channel_mask_5bit3, channel_mask_5bit4 };
1864 static BYTE const * const channel_masks_BGR565[] = { channel_mask_5bit,
1865 channel_mask_BGR565_2, channel_mask_BGR565_3 };
1867 static struct regsvr_pixelformat const pixelformat_list[] = {
1868 { &GUID_WICPixelFormat1bppIndexed,
1869 "The Wine Project",
1870 "1bpp Indexed",
1871 NULL, /* no version */
1872 &GUID_VendorMicrosoft,
1873 1, /* bitsperpixel */
1874 1, /* channel count */
1875 channel_masks_1bit,
1876 WICPixelFormatNumericRepresentationIndexed,
1879 { &GUID_WICPixelFormat2bppIndexed,
1880 "The Wine Project",
1881 "2bpp Indexed",
1882 NULL, /* no version */
1883 &GUID_VendorMicrosoft,
1884 2, /* bitsperpixel */
1885 1, /* channel count */
1886 channel_masks_2bit,
1887 WICPixelFormatNumericRepresentationIndexed,
1890 { &GUID_WICPixelFormat4bppIndexed,
1891 "The Wine Project",
1892 "4bpp Indexed",
1893 NULL, /* no version */
1894 &GUID_VendorMicrosoft,
1895 4, /* bitsperpixel */
1896 1, /* channel count */
1897 channel_masks_4bit,
1898 WICPixelFormatNumericRepresentationIndexed,
1901 { &GUID_WICPixelFormat8bppIndexed,
1902 "The Wine Project",
1903 "8bpp Indexed",
1904 NULL, /* no version */
1905 &GUID_VendorMicrosoft,
1906 8, /* bitsperpixel */
1907 1, /* channel count */
1908 channel_masks_8bit,
1909 WICPixelFormatNumericRepresentationIndexed,
1912 { &GUID_WICPixelFormatBlackWhite,
1913 "The Wine Project",
1914 "Black and White",
1915 NULL, /* no version */
1916 &GUID_VendorMicrosoft,
1917 1, /* bitsperpixel */
1918 1, /* channel count */
1919 channel_masks_1bit,
1920 WICPixelFormatNumericRepresentationUnsignedInteger,
1923 { &GUID_WICPixelFormat2bppGray,
1924 "The Wine Project",
1925 "2bpp Grayscale",
1926 NULL, /* no version */
1927 &GUID_VendorMicrosoft,
1928 2, /* bitsperpixel */
1929 1, /* channel count */
1930 channel_masks_2bit,
1931 WICPixelFormatNumericRepresentationUnsignedInteger,
1934 { &GUID_WICPixelFormat4bppGray,
1935 "The Wine Project",
1936 "4bpp Grayscale",
1937 NULL, /* no version */
1938 &GUID_VendorMicrosoft,
1939 4, /* bitsperpixel */
1940 1, /* channel count */
1941 channel_masks_4bit,
1942 WICPixelFormatNumericRepresentationUnsignedInteger,
1945 { &GUID_WICPixelFormat8bppGray,
1946 "The Wine Project",
1947 "8bpp Grayscale",
1948 NULL, /* no version */
1949 &GUID_VendorMicrosoft,
1950 8, /* bitsperpixel */
1951 1, /* channel count */
1952 channel_masks_8bit,
1953 WICPixelFormatNumericRepresentationUnsignedInteger,
1956 { &GUID_WICPixelFormat16bppGray,
1957 "The Wine Project",
1958 "16bpp Grayscale",
1959 NULL, /* no version */
1960 &GUID_VendorMicrosoft,
1961 16, /* bitsperpixel */
1962 1, /* channel count */
1963 channel_masks_16bit,
1964 WICPixelFormatNumericRepresentationUnsignedInteger,
1967 { &GUID_WICPixelFormat16bppBGR555,
1968 "The Wine Project",
1969 "16bpp BGR555",
1970 NULL, /* no version */
1971 &GUID_VendorMicrosoft,
1972 16, /* bitsperpixel */
1973 3, /* channel count */
1974 channel_masks_BGRA5551,
1975 WICPixelFormatNumericRepresentationUnsignedInteger,
1978 { &GUID_WICPixelFormat16bppBGR565,
1979 "The Wine Project",
1980 "16bpp BGR565",
1981 NULL, /* no version */
1982 &GUID_VendorMicrosoft,
1983 16, /* bitsperpixel */
1984 3, /* channel count */
1985 channel_masks_BGR565,
1986 WICPixelFormatNumericRepresentationUnsignedInteger,
1989 { &GUID_WICPixelFormat16bppBGRA5551,
1990 "The Wine Project",
1991 "16bpp BGRA5551",
1992 NULL, /* no version */
1993 &GUID_VendorMicrosoft,
1994 16, /* bitsperpixel */
1995 4, /* channel count */
1996 channel_masks_BGRA5551,
1997 WICPixelFormatNumericRepresentationUnsignedInteger,
2000 { &GUID_WICPixelFormat24bppBGR,
2001 "The Wine Project",
2002 "24bpp BGR",
2003 NULL, /* no version */
2004 &GUID_VendorMicrosoft,
2005 24, /* bitsperpixel */
2006 3, /* channel count */
2007 channel_masks_8bit,
2008 WICPixelFormatNumericRepresentationUnsignedInteger,
2011 { &GUID_WICPixelFormat24bppRGB,
2012 "The Wine Project",
2013 "24bpp RGB",
2014 NULL, /* no version */
2015 &GUID_VendorMicrosoft,
2016 24, /* bitsperpixel */
2017 3, /* channel count */
2018 channel_masks_8bit,
2019 WICPixelFormatNumericRepresentationUnsignedInteger,
2022 { &GUID_WICPixelFormat32bppBGR,
2023 "The Wine Project",
2024 "32bpp BGR",
2025 NULL, /* no version */
2026 &GUID_VendorMicrosoft,
2027 32, /* bitsperpixel */
2028 3, /* channel count */
2029 channel_masks_8bit,
2030 WICPixelFormatNumericRepresentationUnsignedInteger,
2033 { &GUID_WICPixelFormat32bppRGB,
2034 "The Wine Project",
2035 "32bpp RGB",
2036 NULL, /* no version */
2037 &GUID_VendorMicrosoft,
2038 32, /* bitsperpixel */
2039 3, /* channel count */
2040 channel_masks_8bit,
2041 WICPixelFormatNumericRepresentationUnsignedInteger,
2044 { &GUID_WICPixelFormat32bppBGRA,
2045 "The Wine Project",
2046 "32bpp BGRA",
2047 NULL, /* no version */
2048 &GUID_VendorMicrosoft,
2049 32, /* bitsperpixel */
2050 4, /* channel count */
2051 channel_masks_8bit,
2052 WICPixelFormatNumericRepresentationUnsignedInteger,
2055 { &GUID_WICPixelFormat32bppRGBA,
2056 "The Wine Project",
2057 "32bpp RGBA",
2058 NULL, /* no version */
2059 &GUID_VendorMicrosoft,
2060 32, /* bitsperpixel */
2061 4, /* channel count */
2062 channel_masks_8bit,
2063 WICPixelFormatNumericRepresentationUnsignedInteger,
2066 { &GUID_WICPixelFormat32bppPBGRA,
2067 "The Wine Project",
2068 "32bpp PBGRA",
2069 NULL, /* no version */
2070 &GUID_VendorMicrosoft,
2071 32, /* bitsperpixel */
2072 4, /* channel count */
2073 channel_masks_8bit,
2074 WICPixelFormatNumericRepresentationUnsignedInteger,
2077 { &GUID_WICPixelFormat32bppPRGBA,
2078 "The Wine Project",
2079 "32bpp PRGBA",
2080 NULL, /* no version */
2081 &GUID_VendorMicrosoft,
2082 32, /* bitsperpixel */
2083 4, /* channel count */
2084 channel_masks_8bit,
2085 WICPixelFormatNumericRepresentationUnsignedInteger,
2088 { &GUID_WICPixelFormat32bppGrayFloat,
2089 "The Wine Project",
2090 "32bpp GrayFloat",
2091 NULL, /* no version */
2092 &GUID_VendorMicrosoft,
2093 32, /* bitsperpixel */
2094 1, /* channel count */
2095 channel_masks_32bit,
2096 WICPixelFormatNumericRepresentationFloat,
2099 { &GUID_WICPixelFormat48bppRGB,
2100 "The Wine Project",
2101 "48bpp RGB",
2102 NULL, /* no version */
2103 &GUID_VendorMicrosoft,
2104 48, /* bitsperpixel */
2105 3, /* channel count */
2106 channel_masks_16bit,
2107 WICPixelFormatNumericRepresentationUnsignedInteger,
2110 { &GUID_WICPixelFormat64bppRGBA,
2111 "The Wine Project",
2112 "64bpp RGBA",
2113 NULL, /* no version */
2114 &GUID_VendorMicrosoft,
2115 64, /* bitsperpixel */
2116 4, /* channel count */
2117 channel_masks_16bit,
2118 WICPixelFormatNumericRepresentationUnsignedInteger,
2121 { &GUID_WICPixelFormat64bppPRGBA,
2122 "The Wine Project",
2123 "64bpp PRGBA",
2124 NULL, /* no version */
2125 &GUID_VendorMicrosoft,
2126 64, /* bitsperpixel */
2127 4, /* channel count */
2128 channel_masks_16bit,
2129 WICPixelFormatNumericRepresentationUnsignedInteger,
2132 { &GUID_WICPixelFormat32bppCMYK,
2133 "The Wine Project",
2134 "32bpp CMYK",
2135 NULL, /* no version */
2136 &GUID_VendorMicrosoft,
2137 32, /* bitsperpixel */
2138 4, /* channel count */
2139 channel_masks_8bit,
2140 WICPixelFormatNumericRepresentationUnsignedInteger,
2143 { &GUID_WICPixelFormat64bppCMYK,
2144 "The Wine Project",
2145 "64bpp CMYK",
2146 NULL, /* no version */
2147 &GUID_VendorMicrosoft,
2148 64, /* bitsperpixel */
2149 4, /* channel count */
2150 channel_masks_16bit,
2151 WICPixelFormatNumericRepresentationUnsignedInteger,
2154 { &GUID_WICPixelFormat96bppRGBFloat,
2155 "The Wine Project",
2156 "96bpp RGBFloat",
2157 NULL, /* no version */
2158 &GUID_VendorMicrosoft,
2159 96, /* bitsperpixel */
2160 3, /* channel count */
2161 channel_masks_96bit,
2162 WICPixelFormatNumericRepresentationFloat,
2165 { &GUID_WICPixelFormat128bppRGBAFloat,
2166 "The Wine Project",
2167 "128bpp RGBAFloat",
2168 NULL, /* no version */
2169 &GUID_VendorMicrosoft,
2170 128, /* bitsperpixel */
2171 4, /* channel count */
2172 channel_masks_128bit,
2173 WICPixelFormatNumericRepresentationFloat,
2176 { &GUID_WICPixelFormat128bppPRGBAFloat,
2177 "The Wine Project",
2178 "128bpp PRGBAFloat",
2179 NULL, /* no version */
2180 &GUID_VendorMicrosoft,
2181 128, /* bitsperpixel */
2182 4, /* channel count */
2183 channel_masks_128bit,
2184 WICPixelFormatNumericRepresentationFloat,
2187 { NULL } /* list terminator */
2190 struct regsvr_category
2192 const CLSID *clsid; /* NULL for end of list */
2195 static const struct regsvr_category category_list[] = {
2196 { &CATID_WICBitmapDecoders },
2197 { &CATID_WICBitmapEncoders },
2198 { &CATID_WICFormatConverters },
2199 { &CATID_WICMetadataReader },
2200 { &CATID_WICPixelFormats },
2201 { NULL }
2204 static HRESULT register_categories(const struct regsvr_category *list)
2206 LONG res;
2207 WCHAR buf[39];
2208 HKEY coclass_key, categories_key, instance_key;
2210 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
2211 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
2212 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
2214 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
2215 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
2216 KEY_READ | KEY_WRITE, NULL, &categories_key, NULL);
2217 if (res != ERROR_SUCCESS)
2219 RegCloseKey(coclass_key);
2220 return HRESULT_FROM_WIN32(res);
2223 res = RegCreateKeyExW(categories_key, instance_keyname, 0, NULL, 0,
2224 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
2226 for (; res == ERROR_SUCCESS && list->clsid; list++)
2228 HKEY instance_clsid_key;
2230 StringFromGUID2(list->clsid, buf, 39);
2231 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
2232 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
2233 if (res == ERROR_SUCCESS)
2235 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
2236 (const BYTE *)buf, 78);
2237 RegCloseKey(instance_clsid_key);
2241 RegCloseKey(instance_key);
2242 RegCloseKey(categories_key);
2243 RegCloseKey(coclass_key);
2245 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
2248 static HRESULT unregister_categories(const struct regsvr_category *list)
2250 LONG res;
2251 WCHAR buf[39];
2252 HKEY coclass_key, categories_key, instance_key;
2254 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
2255 KEY_READ | KEY_WRITE, &coclass_key);
2256 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
2258 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
2259 res = RegOpenKeyExW(coclass_key, buf, 0,
2260 KEY_READ | KEY_WRITE, &categories_key);
2261 if (res != ERROR_SUCCESS)
2263 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
2264 RegCloseKey(coclass_key);
2265 return HRESULT_FROM_WIN32(res);
2268 res = RegOpenKeyExW(categories_key, instance_keyname, 0,
2269 KEY_READ | KEY_WRITE, &instance_key);
2271 for (; res == ERROR_SUCCESS && list->clsid; list++)
2273 StringFromGUID2(list->clsid, buf, 39);
2274 res = RegDeleteTreeW(instance_key, buf);
2277 RegCloseKey(instance_key);
2278 RegCloseKey(categories_key);
2280 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
2281 res = RegDeleteTreeW(coclass_key, buf);
2283 RegCloseKey(coclass_key);
2285 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
2288 extern HRESULT WINAPI WIC_DllRegisterServer(void) DECLSPEC_HIDDEN;
2289 extern HRESULT WINAPI WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN;
2291 HRESULT WINAPI DllRegisterServer(void)
2293 HRESULT hr;
2295 TRACE("\n");
2297 hr = WIC_DllRegisterServer();
2298 if (SUCCEEDED(hr))
2299 hr = register_categories(category_list);
2300 if (SUCCEEDED(hr))
2301 hr = register_decoders(decoder_list);
2302 if (SUCCEEDED(hr))
2303 hr = register_encoders(encoder_list);
2304 if (SUCCEEDED(hr))
2305 hr = register_converters(converter_list);
2306 if (SUCCEEDED(hr))
2307 hr = register_metadatareaders(metadatareader_list);
2308 if (SUCCEEDED(hr))
2309 hr = register_pixelformats(pixelformat_list);
2310 return hr;
2313 HRESULT WINAPI DllUnregisterServer(void)
2315 HRESULT hr;
2317 TRACE("\n");
2319 hr = WIC_DllUnregisterServer();
2320 if (SUCCEEDED(hr))
2321 hr = unregister_categories(category_list);
2322 if (SUCCEEDED(hr))
2323 hr = unregister_decoders(decoder_list);
2324 if (SUCCEEDED(hr))
2325 hr = unregister_encoders(encoder_list);
2326 if (SUCCEEDED(hr))
2327 hr = unregister_converters(converter_list);
2328 if (SUCCEEDED(hr))
2329 hr = unregister_metadatareaders(metadatareader_list);
2330 if (SUCCEEDED(hr))
2331 hr = unregister_pixelformats(pixelformat_list);
2332 return hr;