makefiles: Explicitly create destination dirs when installing symlinks.
[wine/zf.git] / dlls / windowscodecs / regsvr.c
blob38c252c2760290751258ff3d1aa3edc71832c6e5
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"
34 #include "wine/unicode.h"
36 #include "wincodecs_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
40 /***********************************************************************
41 * interface for self-registering
43 struct decoder_pattern
45 DWORD length; /* 0 for end of list */
46 DWORD position;
47 const BYTE *pattern;
48 const BYTE *mask;
49 DWORD endofstream;
52 struct regsvr_decoder
54 CLSID const *clsid; /* NULL for end of list */
55 LPCSTR author;
56 LPCSTR friendlyname;
57 LPCSTR version;
58 GUID const *vendor;
59 GUID const *container_format;
60 LPCSTR mimetypes;
61 LPCSTR extensions;
62 GUID const * const *formats;
63 const struct decoder_pattern *patterns;
66 static HRESULT register_decoders(struct regsvr_decoder const *list);
67 static HRESULT unregister_decoders(struct regsvr_decoder const *list);
69 struct regsvr_encoder
71 CLSID const *clsid; /* NULL for end of list */
72 LPCSTR author;
73 LPCSTR friendlyname;
74 LPCSTR version;
75 GUID const *vendor;
76 GUID const *container_format;
77 LPCSTR mimetypes;
78 LPCSTR extensions;
79 GUID const * const *formats;
82 static HRESULT register_encoders(struct regsvr_encoder const *list);
83 static HRESULT unregister_encoders(struct regsvr_encoder const *list);
85 struct regsvr_converter
87 CLSID const *clsid; /* NULL for end of list */
88 LPCSTR author;
89 LPCSTR friendlyname;
90 LPCSTR version;
91 GUID const *vendor;
92 GUID const * const *formats;
95 static HRESULT register_converters(struct regsvr_converter const *list);
96 static HRESULT unregister_converters(struct regsvr_converter const *list);
98 struct metadata_pattern
100 DWORD position;
101 DWORD length;
102 const BYTE *pattern;
103 const BYTE *mask;
104 DWORD data_offset;
107 struct reader_containers
109 GUID const *format;
110 const struct metadata_pattern *patterns;
113 struct regsvr_metadatareader
115 CLSID const *clsid; /* NULL for end of list */
116 LPCSTR author;
117 LPCSTR friendlyname;
118 LPCSTR version;
119 LPCSTR specversion;
120 GUID const *vendor;
121 GUID const *metadata_format;
122 DWORD requires_fullstream;
123 DWORD supports_padding;
124 DWORD requires_fixedsize;
125 const struct reader_containers *containers;
128 static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list);
129 static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list);
131 struct regsvr_pixelformat
133 CLSID const *clsid; /* NULL for end of list */
134 LPCSTR author;
135 LPCSTR friendlyname;
136 LPCSTR version;
137 GUID const *vendor;
138 UINT bitsperpixel;
139 UINT channelcount;
140 BYTE const * const *channelmasks;
141 WICPixelFormatNumericRepresentation numericrepresentation;
142 UINT supportsalpha;
145 static HRESULT register_pixelformats(struct regsvr_pixelformat const *list);
146 static HRESULT unregister_pixelformats(struct regsvr_pixelformat const *list);
148 /***********************************************************************
149 * static string constants
151 static const WCHAR clsid_keyname[] = {
152 'C', 'L', 'S', 'I', 'D', 0 };
153 static const char author_valuename[] = "Author";
154 static const char friendlyname_valuename[] = "FriendlyName";
155 static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0};
156 static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
157 static const char version_valuename[] = "Version";
158 static const char mimetypes_valuename[] = "MimeTypes";
159 static const char extensions_valuename[] = "FileExtensions";
160 static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0};
161 static const WCHAR patterns_keyname[] = {'P','a','t','t','e','r','n','s',0};
162 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
163 static const WCHAR clsid_valuename[] = {'C','L','S','I','D',0};
164 static const char length_valuename[] = "Length";
165 static const char position_valuename[] = "Position";
166 static const char pattern_valuename[] = "Pattern";
167 static const char mask_valuename[] = "Mask";
168 static const char endofstream_valuename[] = "EndOfStream";
169 static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
170 static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
171 static const char specversion_valuename[] = "SpecVersion";
172 static const char requiresfullstream_valuename[] = "RequiresFullStream";
173 static const char supportspadding_valuename[] = "SupportsPadding";
174 static const char requiresfixedsize_valuename[] = "FixedSize";
175 static const WCHAR containers_keyname[] = {'C','o','n','t','a','i','n','e','r','s',0};
176 static const char dataoffset_valuename[] = "DataOffset";
177 static const char bitsperpixel_valuename[] = "BitLength";
178 static const char channelcount_valuename[] = "ChannelCount";
179 static const char numericrepresentation_valuename[] = "NumericRepresentation";
180 static const char supportstransparency_valuename[] = "SupportsTransparency";
181 static const WCHAR channelmasks_keyname[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
183 /***********************************************************************
184 * register_decoders
186 static HRESULT register_decoders(struct regsvr_decoder const *list)
188 LONG res = ERROR_SUCCESS;
189 HKEY coclass_key;
190 WCHAR buf[39];
191 HKEY decoders_key;
192 HKEY instance_key;
194 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
195 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
196 if (res == ERROR_SUCCESS) {
197 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
198 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
199 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
200 if (res == ERROR_SUCCESS)
202 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
203 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
204 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
206 if (res != ERROR_SUCCESS)
207 RegCloseKey(coclass_key);
209 if (res != ERROR_SUCCESS) goto error_return;
211 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
212 HKEY clsid_key;
213 HKEY instance_clsid_key;
215 StringFromGUID2(list->clsid, buf, 39);
216 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
217 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
218 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
220 StringFromGUID2(list->clsid, buf, 39);
221 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
222 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
223 if (res == ERROR_SUCCESS) {
224 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
225 (const BYTE*)buf, 78);
226 RegCloseKey(instance_clsid_key);
228 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
230 if (list->author) {
231 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
232 (const BYTE*)list->author,
233 strlen(list->author) + 1);
234 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
237 if (list->friendlyname) {
238 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
239 (const BYTE*)list->friendlyname,
240 strlen(list->friendlyname) + 1);
241 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
244 if (list->vendor) {
245 StringFromGUID2(list->vendor, buf, 39);
246 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
247 (const BYTE*)buf, 78);
248 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
251 if (list->container_format) {
252 StringFromGUID2(list->container_format, buf, 39);
253 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ,
254 (const BYTE*)buf, 78);
255 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
258 if (list->version) {
259 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
260 (const BYTE*)list->version,
261 strlen(list->version) + 1);
262 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
265 if (list->mimetypes) {
266 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ,
267 (const BYTE*)list->mimetypes,
268 strlen(list->mimetypes) + 1);
269 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
272 if (list->extensions) {
273 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ,
274 (const BYTE*)list->extensions,
275 strlen(list->extensions) + 1);
276 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
279 if (list->formats) {
280 HKEY formats_key;
281 GUID const * const *format;
283 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0,
284 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
285 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
286 for (format=list->formats; *format; ++format)
288 HKEY format_key;
289 StringFromGUID2(*format, buf, 39);
290 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
291 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
292 if (res != ERROR_SUCCESS) break;
293 RegCloseKey(format_key);
295 RegCloseKey(formats_key);
296 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
299 if (list->patterns) {
300 HKEY patterns_key;
301 int i;
303 res = RegCreateKeyExW(clsid_key, patterns_keyname, 0, NULL, 0,
304 KEY_READ | KEY_WRITE, NULL, &patterns_key, NULL);
305 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
306 for (i=0; list->patterns[i].length; i++)
308 HKEY pattern_key;
309 static const WCHAR int_format[] = {'%','i',0};
310 snprintfW(buf, 39, int_format, i);
311 res = RegCreateKeyExW(patterns_key, buf, 0, NULL, 0,
312 KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL);
313 if (res != ERROR_SUCCESS) break;
314 res = RegSetValueExA(pattern_key, length_valuename, 0, REG_DWORD,
315 (const BYTE*)&list->patterns[i].length, 4);
316 if (res == ERROR_SUCCESS)
317 res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD,
318 (const BYTE*)&list->patterns[i].position, 4);
319 if (res == ERROR_SUCCESS)
320 res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY,
321 list->patterns[i].pattern,
322 list->patterns[i].length);
323 if (res == ERROR_SUCCESS)
324 res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY,
325 list->patterns[i].mask,
326 list->patterns[i].length);
327 if (res == ERROR_SUCCESS)
328 res = RegSetValueExA(pattern_key, endofstream_valuename, 0, REG_DWORD,
329 (const BYTE*)&list->patterns[i].endofstream, 4);
330 RegCloseKey(pattern_key);
332 RegCloseKey(patterns_key);
333 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
336 error_close_clsid_key:
337 RegCloseKey(clsid_key);
340 error_close_coclass_key:
341 RegCloseKey(instance_key);
342 RegCloseKey(decoders_key);
343 RegCloseKey(coclass_key);
344 error_return:
345 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
348 /***********************************************************************
349 * unregister_decoders
351 static HRESULT unregister_decoders(struct regsvr_decoder const *list)
353 LONG res = ERROR_SUCCESS;
354 HKEY coclass_key;
355 WCHAR buf[39];
356 HKEY decoders_key;
357 HKEY instance_key;
359 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
360 KEY_READ | KEY_WRITE, &coclass_key);
361 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
363 if (res == ERROR_SUCCESS) {
364 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
365 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
366 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
367 if (res == ERROR_SUCCESS)
369 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
370 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
371 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
373 if (res != ERROR_SUCCESS)
374 RegCloseKey(coclass_key);
376 if (res != ERROR_SUCCESS) goto error_return;
378 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
379 StringFromGUID2(list->clsid, buf, 39);
381 res = RegDeleteTreeW(coclass_key, buf);
382 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
383 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
385 res = RegDeleteTreeW(instance_key, buf);
386 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
387 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
390 error_close_coclass_key:
391 RegCloseKey(instance_key);
392 RegCloseKey(decoders_key);
393 RegCloseKey(coclass_key);
394 error_return:
395 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
398 /***********************************************************************
399 * register_encoders
401 static HRESULT register_encoders(struct regsvr_encoder const *list)
403 LONG res = ERROR_SUCCESS;
404 HKEY coclass_key;
405 WCHAR buf[39];
406 HKEY encoders_key;
407 HKEY instance_key;
409 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
410 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
411 if (res == ERROR_SUCCESS) {
412 StringFromGUID2(&CATID_WICBitmapEncoders, buf, 39);
413 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
414 KEY_READ | KEY_WRITE, NULL, &encoders_key, NULL);
415 if (res == ERROR_SUCCESS)
417 res = RegCreateKeyExW(encoders_key, instance_keyname, 0, NULL, 0,
418 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
419 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
421 if (res != ERROR_SUCCESS)
422 RegCloseKey(coclass_key);
424 if (res != ERROR_SUCCESS) goto error_return;
426 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
427 HKEY clsid_key;
428 HKEY instance_clsid_key;
430 StringFromGUID2(list->clsid, buf, 39);
431 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
432 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
433 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
435 StringFromGUID2(list->clsid, buf, 39);
436 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
437 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
438 if (res == ERROR_SUCCESS) {
439 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
440 (const BYTE*)buf, 78);
441 RegCloseKey(instance_clsid_key);
443 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
445 if (list->author) {
446 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
447 (const BYTE*)list->author,
448 strlen(list->author) + 1);
449 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
452 if (list->friendlyname) {
453 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
454 (const BYTE*)list->friendlyname,
455 strlen(list->friendlyname) + 1);
456 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
459 if (list->vendor) {
460 StringFromGUID2(list->vendor, buf, 39);
461 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
462 (const BYTE*)buf, 78);
463 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
466 if (list->container_format) {
467 StringFromGUID2(list->container_format, buf, 39);
468 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ,
469 (const BYTE*)buf, 78);
470 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
473 if (list->version) {
474 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
475 (const BYTE*)list->version,
476 strlen(list->version) + 1);
477 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
480 if (list->mimetypes) {
481 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ,
482 (const BYTE*)list->mimetypes,
483 strlen(list->mimetypes) + 1);
484 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
487 if (list->extensions) {
488 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ,
489 (const BYTE*)list->extensions,
490 strlen(list->extensions) + 1);
491 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
494 if (list->formats) {
495 HKEY formats_key;
496 GUID const * const *format;
498 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0,
499 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
500 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
501 for (format=list->formats; *format; ++format)
503 HKEY format_key;
504 StringFromGUID2(*format, buf, 39);
505 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
506 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
507 if (res != ERROR_SUCCESS) break;
508 RegCloseKey(format_key);
510 RegCloseKey(formats_key);
511 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
514 error_close_clsid_key:
515 RegCloseKey(clsid_key);
518 error_close_coclass_key:
519 RegCloseKey(instance_key);
520 RegCloseKey(encoders_key);
521 RegCloseKey(coclass_key);
522 error_return:
523 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
526 /***********************************************************************
527 * unregister_encoders
529 static HRESULT unregister_encoders(struct regsvr_encoder const *list)
531 LONG res = ERROR_SUCCESS;
532 HKEY coclass_key;
533 WCHAR buf[39];
534 HKEY encoders_key;
535 HKEY instance_key;
537 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
538 KEY_READ | KEY_WRITE, &coclass_key);
539 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
541 if (res == ERROR_SUCCESS) {
542 StringFromGUID2(&CATID_WICBitmapEncoders, buf, 39);
543 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
544 KEY_READ | KEY_WRITE, NULL, &encoders_key, NULL);
545 if (res == ERROR_SUCCESS)
547 res = RegCreateKeyExW(encoders_key, instance_keyname, 0, NULL, 0,
548 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
549 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
551 if (res != ERROR_SUCCESS)
552 RegCloseKey(coclass_key);
554 if (res != ERROR_SUCCESS) goto error_return;
556 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
557 StringFromGUID2(list->clsid, buf, 39);
559 res = RegDeleteTreeW(coclass_key, buf);
560 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
561 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
563 res = RegDeleteTreeW(instance_key, buf);
564 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
565 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
568 error_close_coclass_key:
569 RegCloseKey(instance_key);
570 RegCloseKey(encoders_key);
571 RegCloseKey(coclass_key);
572 error_return:
573 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
576 /***********************************************************************
577 * register_converters
579 static HRESULT register_converters(struct regsvr_converter const *list)
581 LONG res = ERROR_SUCCESS;
582 HKEY coclass_key;
583 WCHAR buf[39];
584 HKEY converters_key;
585 HKEY instance_key;
587 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
588 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
589 if (res == ERROR_SUCCESS) {
590 StringFromGUID2(&CATID_WICFormatConverters, buf, 39);
591 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
592 KEY_READ | KEY_WRITE, NULL, &converters_key, NULL);
593 if (res == ERROR_SUCCESS)
595 res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0,
596 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
597 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
599 if (res != ERROR_SUCCESS)
600 RegCloseKey(coclass_key);
602 if (res != ERROR_SUCCESS) goto error_return;
604 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
605 HKEY clsid_key;
606 HKEY instance_clsid_key;
608 StringFromGUID2(list->clsid, buf, 39);
609 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
610 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
611 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
613 StringFromGUID2(list->clsid, buf, 39);
614 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
615 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
616 if (res == ERROR_SUCCESS) {
617 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
618 (const BYTE*)buf, 78);
619 RegCloseKey(instance_clsid_key);
621 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
623 if (list->author) {
624 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
625 (const BYTE*)list->author,
626 strlen(list->author) + 1);
627 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
630 if (list->friendlyname) {
631 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
632 (const BYTE*)list->friendlyname,
633 strlen(list->friendlyname) + 1);
634 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
637 if (list->vendor) {
638 StringFromGUID2(list->vendor, buf, 39);
639 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
640 (const BYTE*)buf, 78);
641 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
644 if (list->version) {
645 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
646 (const BYTE*)list->version,
647 strlen(list->version) + 1);
648 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
651 if (list->formats) {
652 HKEY formats_key;
653 GUID const * const *format;
655 res = RegCreateKeyExW(clsid_key, pixelformats_keyname, 0, NULL, 0,
656 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
657 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
658 for (format=list->formats; *format; ++format)
660 HKEY format_key;
661 StringFromGUID2(*format, buf, 39);
662 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
663 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
664 if (res != ERROR_SUCCESS) break;
665 RegCloseKey(format_key);
667 RegCloseKey(formats_key);
668 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
671 error_close_clsid_key:
672 RegCloseKey(clsid_key);
675 error_close_coclass_key:
676 RegCloseKey(instance_key);
677 RegCloseKey(converters_key);
678 RegCloseKey(coclass_key);
679 error_return:
680 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
683 /***********************************************************************
684 * unregister_converters
686 static HRESULT unregister_converters(struct regsvr_converter const *list)
688 LONG res = ERROR_SUCCESS;
689 HKEY coclass_key;
690 WCHAR buf[39];
691 HKEY converters_key;
692 HKEY instance_key;
694 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
695 KEY_READ | KEY_WRITE, &coclass_key);
696 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
698 if (res == ERROR_SUCCESS) {
699 StringFromGUID2(&CATID_WICFormatConverters, buf, 39);
700 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
701 KEY_READ | KEY_WRITE, NULL, &converters_key, NULL);
702 if (res == ERROR_SUCCESS)
704 res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0,
705 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
706 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
708 if (res != ERROR_SUCCESS)
709 RegCloseKey(coclass_key);
711 if (res != ERROR_SUCCESS) goto error_return;
713 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
714 StringFromGUID2(list->clsid, buf, 39);
716 res = RegDeleteTreeW(coclass_key, buf);
717 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
718 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
720 res = RegDeleteTreeW(instance_key, buf);
721 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
722 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
725 error_close_coclass_key:
726 RegCloseKey(instance_key);
727 RegCloseKey(converters_key);
728 RegCloseKey(coclass_key);
729 error_return:
730 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
733 /***********************************************************************
734 * register_metadatareaders
736 static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list)
738 LONG res = ERROR_SUCCESS;
739 HKEY coclass_key;
740 WCHAR buf[39];
741 HKEY readers_key;
742 HKEY instance_key;
744 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
745 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
746 if (res == ERROR_SUCCESS) {
747 StringFromGUID2(&CATID_WICMetadataReader, buf, 39);
748 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
749 KEY_READ | KEY_WRITE, NULL, &readers_key, NULL);
750 if (res == ERROR_SUCCESS)
752 res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0,
753 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
754 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
756 if (res != ERROR_SUCCESS)
757 RegCloseKey(coclass_key);
759 if (res != ERROR_SUCCESS) goto error_return;
761 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
762 HKEY clsid_key;
763 HKEY instance_clsid_key;
765 StringFromGUID2(list->clsid, buf, 39);
766 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
767 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
768 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
770 StringFromGUID2(list->clsid, buf, 39);
771 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
772 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
773 if (res == ERROR_SUCCESS) {
774 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
775 (const BYTE*)buf, 78);
776 RegCloseKey(instance_clsid_key);
778 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
780 if (list->author) {
781 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
782 (const BYTE*)list->author,
783 strlen(list->author) + 1);
784 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
787 if (list->friendlyname) {
788 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
789 (const BYTE*)list->friendlyname,
790 strlen(list->friendlyname) + 1);
791 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
794 if (list->vendor) {
795 StringFromGUID2(list->vendor, buf, 39);
796 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
797 (const BYTE*)buf, 78);
798 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
801 if (list->metadata_format) {
802 StringFromGUID2(list->metadata_format, buf, 39);
803 res = RegSetValueExW(clsid_key, metadataformat_valuename, 0, REG_SZ,
804 (const BYTE*)buf, 78);
805 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
808 if (list->version) {
809 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
810 (const BYTE*)list->version,
811 strlen(list->version) + 1);
812 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
815 if (list->specversion) {
816 res = RegSetValueExA(clsid_key, specversion_valuename, 0, REG_SZ,
817 (const BYTE*)list->version,
818 strlen(list->version) + 1);
819 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
822 res = RegSetValueExA(clsid_key, requiresfullstream_valuename, 0, REG_DWORD,
823 (const BYTE*)&list->requires_fullstream, 4);
824 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
826 res = RegSetValueExA(clsid_key, supportspadding_valuename, 0, REG_DWORD,
827 (const BYTE*)&list->supports_padding, 4);
828 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
830 if (list->requires_fixedsize) {
831 res = RegSetValueExA(clsid_key, requiresfixedsize_valuename, 0, REG_DWORD,
832 (const BYTE*)&list->requires_fixedsize, 4);
833 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
836 if (list->containers) {
837 HKEY containers_key;
838 const struct reader_containers *container;
840 res = RegCreateKeyExW(clsid_key, containers_keyname, 0, NULL, 0,
841 KEY_READ | KEY_WRITE, NULL, &containers_key, NULL);
842 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
843 for (container=list->containers; container->format; ++container)
845 HKEY format_key;
846 int i;
847 StringFromGUID2(container->format, buf, 39);
848 res = RegCreateKeyExW(containers_key, buf, 0, NULL, 0,
849 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
850 if (res != ERROR_SUCCESS) break;
852 for (i=0; container->patterns[i].length; i++)
854 HKEY pattern_key;
855 static const WCHAR int_format[] = {'%','i',0};
856 snprintfW(buf, 39, int_format, i);
857 res = RegCreateKeyExW(format_key, buf, 0, NULL, 0,
858 KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL);
859 if (res != ERROR_SUCCESS) break;
860 res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD,
861 (const BYTE*)&container->patterns[i].position, 4);
862 if (res == ERROR_SUCCESS)
863 res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY,
864 container->patterns[i].pattern,
865 container->patterns[i].length);
866 if (res == ERROR_SUCCESS)
867 res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY,
868 container->patterns[i].mask,
869 container->patterns[i].length);
870 if (res == ERROR_SUCCESS && container->patterns[i].data_offset)
871 res = RegSetValueExA(pattern_key, dataoffset_valuename, 0, REG_DWORD,
872 (const BYTE*)&container->patterns[i].data_offset, 4);
873 RegCloseKey(pattern_key);
876 RegCloseKey(format_key);
878 RegCloseKey(containers_key);
881 error_close_clsid_key:
882 RegCloseKey(clsid_key);
885 error_close_coclass_key:
886 RegCloseKey(instance_key);
887 RegCloseKey(readers_key);
888 RegCloseKey(coclass_key);
889 error_return:
890 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
893 /***********************************************************************
894 * unregister_metadatareaders
896 static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list)
898 LONG res = ERROR_SUCCESS;
899 HKEY coclass_key;
900 WCHAR buf[39];
901 HKEY readers_key;
902 HKEY instance_key;
904 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
905 KEY_READ | KEY_WRITE, &coclass_key);
906 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
908 if (res == ERROR_SUCCESS) {
909 StringFromGUID2(&CATID_WICMetadataReader, buf, 39);
910 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
911 KEY_READ | KEY_WRITE, NULL, &readers_key, NULL);
912 if (res == ERROR_SUCCESS)
914 res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0,
915 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
916 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
918 if (res != ERROR_SUCCESS)
919 RegCloseKey(coclass_key);
921 if (res != ERROR_SUCCESS) goto error_return;
923 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
924 StringFromGUID2(list->clsid, buf, 39);
926 res = RegDeleteTreeW(coclass_key, buf);
927 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
928 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
930 res = RegDeleteTreeW(instance_key, buf);
931 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
932 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
935 error_close_coclass_key:
936 RegCloseKey(instance_key);
937 RegCloseKey(readers_key);
938 RegCloseKey(coclass_key);
939 error_return:
940 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
943 /***********************************************************************
944 * register_pixelformats
946 static HRESULT register_pixelformats(struct regsvr_pixelformat const *list)
948 LONG res = ERROR_SUCCESS;
949 HKEY coclass_key;
950 WCHAR buf[39];
951 HKEY formats_key;
952 HKEY instance_key;
954 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
955 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
956 if (res == ERROR_SUCCESS) {
957 StringFromGUID2(&CATID_WICPixelFormats, buf, 39);
958 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
959 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
960 if (res == ERROR_SUCCESS)
962 res = RegCreateKeyExW(formats_key, instance_keyname, 0, NULL, 0,
963 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
964 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
966 if (res != ERROR_SUCCESS)
967 RegCloseKey(coclass_key);
969 if (res != ERROR_SUCCESS) goto error_return;
971 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
972 HKEY clsid_key;
973 HKEY instance_clsid_key;
975 StringFromGUID2(list->clsid, buf, 39);
976 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
977 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
978 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
980 StringFromGUID2(list->clsid, buf, 39);
981 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
982 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
983 if (res == ERROR_SUCCESS) {
984 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
985 (const BYTE*)buf, 78);
986 RegCloseKey(instance_clsid_key);
988 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
990 if (list->author) {
991 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
992 (const BYTE*)list->author,
993 strlen(list->author) + 1);
994 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
997 if (list->friendlyname) {
998 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
999 (const BYTE*)list->friendlyname,
1000 strlen(list->friendlyname) + 1);
1001 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1004 if (list->vendor) {
1005 StringFromGUID2(list->vendor, buf, 39);
1006 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
1007 (const BYTE*)buf, 78);
1008 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1011 if (list->version) {
1012 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
1013 (const BYTE*)list->version,
1014 strlen(list->version) + 1);
1015 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1018 res = RegSetValueExA(clsid_key, bitsperpixel_valuename, 0, REG_DWORD,
1019 (const BYTE*)&list->bitsperpixel, 4);
1020 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1022 res = RegSetValueExA(clsid_key, channelcount_valuename, 0, REG_DWORD,
1023 (const BYTE*)&list->channelcount, 4);
1024 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1026 res = RegSetValueExA(clsid_key, numericrepresentation_valuename, 0, REG_DWORD,
1027 (const BYTE*)&list->numericrepresentation, 4);
1028 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1030 res = RegSetValueExA(clsid_key, supportstransparency_valuename, 0, REG_DWORD,
1031 (const BYTE*)&list->supportsalpha, 4);
1032 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1034 if (list->channelmasks) {
1035 static const WCHAR valuename_format[] = {'%','d',0};
1036 HKEY masks_key;
1037 UINT i, mask_size;
1038 WCHAR mask_valuename[11];
1040 mask_size = (list->bitsperpixel + 7)/8;
1042 res = RegCreateKeyExW(clsid_key, channelmasks_keyname, 0, NULL, 0,
1043 KEY_READ | KEY_WRITE, NULL, &masks_key, NULL);
1044 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1045 for (i=0; i < list->channelcount; i++)
1047 sprintfW(mask_valuename, valuename_format, i);
1048 res = RegSetValueExW(masks_key, mask_valuename, 0, REG_BINARY,
1049 list->channelmasks[i], mask_size);
1050 if (res != ERROR_SUCCESS) break;
1052 RegCloseKey(masks_key);
1053 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1056 error_close_clsid_key:
1057 RegCloseKey(clsid_key);
1060 error_close_coclass_key:
1061 RegCloseKey(instance_key);
1062 RegCloseKey(formats_key);
1063 RegCloseKey(coclass_key);
1064 error_return:
1065 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
1068 /***********************************************************************
1069 * unregister_pixelformats
1071 static HRESULT unregister_pixelformats(struct regsvr_pixelformat const *list)
1073 LONG res = ERROR_SUCCESS;
1074 HKEY coclass_key;
1075 WCHAR buf[39];
1076 HKEY formats_key;
1077 HKEY instance_key;
1079 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
1080 KEY_READ | KEY_WRITE, &coclass_key);
1081 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
1083 if (res == ERROR_SUCCESS) {
1084 StringFromGUID2(&CATID_WICPixelFormats, buf, 39);
1085 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
1086 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
1087 if (res == ERROR_SUCCESS)
1089 res = RegCreateKeyExW(formats_key, instance_keyname, 0, NULL, 0,
1090 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
1091 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1093 if (res != ERROR_SUCCESS)
1094 RegCloseKey(coclass_key);
1096 if (res != ERROR_SUCCESS) goto error_return;
1098 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
1099 StringFromGUID2(list->clsid, buf, 39);
1101 res = RegDeleteTreeW(coclass_key, buf);
1102 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
1103 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1105 res = RegDeleteTreeW(instance_key, buf);
1106 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
1107 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1110 error_close_coclass_key:
1111 RegCloseKey(instance_key);
1112 RegCloseKey(formats_key);
1113 RegCloseKey(coclass_key);
1114 error_return:
1115 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
1118 /***********************************************************************
1119 * decoder list
1121 static const BYTE mask_all[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1123 static const BYTE bmp_magic[] = {0x42,0x4d};
1125 static GUID const * const bmp_formats[] = {
1126 &GUID_WICPixelFormat1bppIndexed,
1127 &GUID_WICPixelFormat2bppIndexed,
1128 &GUID_WICPixelFormat4bppIndexed,
1129 &GUID_WICPixelFormat8bppIndexed,
1130 &GUID_WICPixelFormat16bppBGR555,
1131 &GUID_WICPixelFormat16bppBGR565,
1132 &GUID_WICPixelFormat24bppBGR,
1133 &GUID_WICPixelFormat32bppBGR,
1134 &GUID_WICPixelFormat32bppBGRA,
1135 NULL
1138 static struct decoder_pattern const bmp_patterns[] = {
1139 {2,0,bmp_magic,mask_all,0},
1143 static const BYTE dds_magic[] = "DDS ";
1145 static GUID const * const dds_formats[] = {
1146 &GUID_WICPixelFormat32bppBGRA,
1147 NULL
1150 static struct decoder_pattern const dds_patterns[] = {
1151 {4,0,dds_magic,mask_all,0},
1155 static const BYTE gif87a_magic[6] = "GIF87a";
1156 static const BYTE gif89a_magic[6] = "GIF89a";
1158 static GUID const * const gif_formats[] = {
1159 &GUID_WICPixelFormat8bppIndexed,
1160 NULL
1163 static struct decoder_pattern const gif_patterns[] = {
1164 {6,0,gif87a_magic,mask_all,0},
1165 {6,0,gif89a_magic,mask_all,0},
1169 static const BYTE ico_magic[] = {00,00,01,00};
1171 static GUID const * const ico_formats[] = {
1172 &GUID_WICPixelFormat32bppBGRA,
1173 NULL
1176 static struct decoder_pattern const ico_patterns[] = {
1177 {4,0,ico_magic,mask_all,0},
1181 static const BYTE jpeg_magic[] = {0xff, 0xd8};
1183 static GUID const * const jpeg_formats[] = {
1184 &GUID_WICPixelFormat24bppBGR,
1185 &GUID_WICPixelFormat32bppCMYK,
1186 &GUID_WICPixelFormat8bppGray,
1187 NULL
1190 static struct decoder_pattern const jpeg_patterns[] = {
1191 {2,0,jpeg_magic,mask_all,0},
1195 static const BYTE wmp_magic_v0[] = {0x49, 0x49, 0xbc, 0x00};
1196 static const BYTE wmp_magic_v1[] = {0x49, 0x49, 0xbc, 0x01};
1198 static GUID const * const wmp_formats[] = {
1199 &GUID_WICPixelFormat128bppRGBAFixedPoint,
1200 &GUID_WICPixelFormat128bppRGBAFloat,
1201 &GUID_WICPixelFormat128bppRGBFloat,
1202 &GUID_WICPixelFormat16bppBGR555,
1203 &GUID_WICPixelFormat16bppBGR565,
1204 &GUID_WICPixelFormat16bppGray,
1205 &GUID_WICPixelFormat16bppGrayFixedPoint,
1206 &GUID_WICPixelFormat16bppGrayHalf,
1207 &GUID_WICPixelFormat24bppBGR,
1208 &GUID_WICPixelFormat24bppRGB,
1209 &GUID_WICPixelFormat32bppBGR,
1210 &GUID_WICPixelFormat32bppBGR101010,
1211 &GUID_WICPixelFormat32bppBGRA,
1212 &GUID_WICPixelFormat32bppCMYK,
1213 &GUID_WICPixelFormat32bppGrayFixedPoint,
1214 &GUID_WICPixelFormat32bppGrayFloat,
1215 &GUID_WICPixelFormat32bppRGBE,
1216 &GUID_WICPixelFormat40bppCMYKAlpha,
1217 &GUID_WICPixelFormat48bppRGB,
1218 &GUID_WICPixelFormat48bppRGBFixedPoint,
1219 &GUID_WICPixelFormat48bppRGBHalf,
1220 &GUID_WICPixelFormat64bppCMYK,
1221 &GUID_WICPixelFormat64bppRGBA,
1222 &GUID_WICPixelFormat64bppRGBAFixedPoint,
1223 &GUID_WICPixelFormat64bppRGBAHalf,
1224 &GUID_WICPixelFormat80bppCMYKAlpha,
1225 &GUID_WICPixelFormat8bppGray,
1226 &GUID_WICPixelFormat96bppRGBFixedPoint,
1227 &GUID_WICPixelFormatBlackWhite,
1228 NULL
1231 static struct decoder_pattern const wmp_patterns[] = {
1232 {4,0,wmp_magic_v0,mask_all,0},
1233 {4,0,wmp_magic_v1,mask_all,0},
1237 static const BYTE png_magic[] = {137,80,78,71,13,10,26,10};
1239 static GUID const * const png_formats[] = {
1240 &GUID_WICPixelFormatBlackWhite,
1241 &GUID_WICPixelFormat2bppGray,
1242 &GUID_WICPixelFormat4bppGray,
1243 &GUID_WICPixelFormat8bppGray,
1244 &GUID_WICPixelFormat16bppGray,
1245 &GUID_WICPixelFormat32bppBGRA,
1246 &GUID_WICPixelFormat64bppRGBA,
1247 &GUID_WICPixelFormat1bppIndexed,
1248 &GUID_WICPixelFormat2bppIndexed,
1249 &GUID_WICPixelFormat4bppIndexed,
1250 &GUID_WICPixelFormat8bppIndexed,
1251 &GUID_WICPixelFormat24bppBGR,
1252 &GUID_WICPixelFormat48bppRGB,
1253 NULL
1256 static struct decoder_pattern const png_patterns[] = {
1257 {8,0,png_magic,mask_all,0},
1261 static const BYTE tiff_magic_le[] = {0x49,0x49,42,0};
1262 static const BYTE tiff_magic_be[] = {0x4d,0x4d,0,42};
1264 static GUID const * const tiff_decode_formats[] = {
1265 &GUID_WICPixelFormatBlackWhite,
1266 &GUID_WICPixelFormat4bppGray,
1267 &GUID_WICPixelFormat8bppGray,
1268 &GUID_WICPixelFormat16bppGray,
1269 &GUID_WICPixelFormat32bppGrayFloat,
1270 &GUID_WICPixelFormat1bppIndexed,
1271 &GUID_WICPixelFormat2bppIndexed,
1272 &GUID_WICPixelFormat4bppIndexed,
1273 &GUID_WICPixelFormat8bppIndexed,
1274 &GUID_WICPixelFormat24bppBGR,
1275 &GUID_WICPixelFormat32bppBGR,
1276 &GUID_WICPixelFormat32bppBGRA,
1277 &GUID_WICPixelFormat32bppPBGRA,
1278 &GUID_WICPixelFormat48bppRGB,
1279 &GUID_WICPixelFormat64bppRGBA,
1280 &GUID_WICPixelFormat64bppPRGBA,
1281 &GUID_WICPixelFormat32bppCMYK,
1282 &GUID_WICPixelFormat64bppCMYK,
1283 &GUID_WICPixelFormat96bppRGBFloat,
1284 &GUID_WICPixelFormat128bppRGBAFloat,
1285 &GUID_WICPixelFormat128bppPRGBAFloat,
1286 NULL
1289 static struct decoder_pattern const tiff_patterns[] = {
1290 {4,0,tiff_magic_le,mask_all,0},
1291 {4,0,tiff_magic_be,mask_all,0},
1295 static const BYTE tga_footer_magic[18] = "TRUEVISION-XFILE.";
1297 static const BYTE tga_indexed_magic[18] = {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0};
1298 static const BYTE tga_indexed_mask[18] = {0,0xff,0xf7,0,0,0,0,0,0,0,0,0,0,0,0,0,0xff,0xcf};
1300 static const BYTE tga_truecolor_magic[18] = {0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1301 static const BYTE tga_truecolor_mask[18] = {0,0xff,0xf7,0,0,0,0,0,0,0,0,0,0,0,0,0,0x87,0xc0};
1303 static const BYTE tga_grayscale_magic[18] = {0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0};
1304 static const BYTE tga_grayscale_mask[18] = {0,0xff,0xf7,0,0,0,0,0,0,0,0,0,0,0,0,0,0xff,0xcf};
1306 static GUID const * const tga_formats[] = {
1307 &GUID_WICPixelFormat8bppGray,
1308 &GUID_WICPixelFormat8bppIndexed,
1309 &GUID_WICPixelFormat16bppGray,
1310 &GUID_WICPixelFormat16bppBGR555,
1311 &GUID_WICPixelFormat24bppBGR,
1312 &GUID_WICPixelFormat32bppBGRA,
1313 &GUID_WICPixelFormat32bppPBGRA,
1314 NULL
1317 static struct decoder_pattern const tga_patterns[] = {
1318 {18,18,tga_footer_magic,mask_all,1},
1319 {18,0,tga_indexed_magic,tga_indexed_mask,0},
1320 {18,0,tga_truecolor_magic,tga_truecolor_mask,0},
1321 {18,0,tga_grayscale_magic,tga_grayscale_mask,0},
1325 static struct regsvr_decoder const decoder_list[] = {
1326 { &CLSID_WICBmpDecoder,
1327 "The Wine Project",
1328 "BMP Decoder",
1329 "1.0.0.0",
1330 &GUID_VendorMicrosoft,
1331 &GUID_ContainerFormatBmp,
1332 "image/bmp",
1333 ".bmp,.dib,.rle",
1334 bmp_formats,
1335 bmp_patterns
1337 { &CLSID_WICDdsDecoder,
1338 "The Wine Project",
1339 "DDS Decoder",
1340 "1.0.0.0",
1341 &GUID_VendorMicrosoft,
1342 &GUID_ContainerFormatDds,
1343 "image/vnd.ms-dds",
1344 ".dds",
1345 dds_formats,
1346 dds_patterns
1348 { &CLSID_WICGifDecoder,
1349 "The Wine Project",
1350 "GIF Decoder",
1351 "1.0.0.0",
1352 &GUID_VendorMicrosoft,
1353 &GUID_ContainerFormatGif,
1354 "image/gif",
1355 ".gif",
1356 gif_formats,
1357 gif_patterns
1359 { &CLSID_WICIcoDecoder,
1360 "The Wine Project",
1361 "ICO Decoder",
1362 "1.0.0.0",
1363 &GUID_VendorMicrosoft,
1364 &GUID_ContainerFormatIco,
1365 "image/vnd.microsoft.icon",
1366 ".ico",
1367 ico_formats,
1368 ico_patterns
1370 { &CLSID_WICJpegDecoder,
1371 "The Wine Project",
1372 "JPEG Decoder",
1373 "1.0.0.0",
1374 &GUID_VendorMicrosoft,
1375 &GUID_ContainerFormatJpeg,
1376 "image/jpeg",
1377 ".jpg;.jpeg;.jfif",
1378 jpeg_formats,
1379 jpeg_patterns
1381 { &CLSID_WICWmpDecoder,
1382 "The Wine Project",
1383 "JPEG-XR Decoder",
1384 "1.0.0.0",
1385 &GUID_VendorMicrosoft,
1386 &GUID_ContainerFormatWmp,
1387 "image/jxr",
1388 ".jxr;.hdp;.wdp",
1389 wmp_formats,
1390 wmp_patterns
1392 { &CLSID_WICPngDecoder,
1393 "The Wine Project",
1394 "PNG Decoder",
1395 "1.0.0.0",
1396 &GUID_VendorMicrosoft,
1397 &GUID_ContainerFormatPng,
1398 "image/png",
1399 ".png",
1400 png_formats,
1401 png_patterns
1403 { &CLSID_WICTiffDecoder,
1404 "The Wine Project",
1405 "TIFF Decoder",
1406 "1.0.0.0",
1407 &GUID_VendorMicrosoft,
1408 &GUID_ContainerFormatTiff,
1409 "image/tiff",
1410 ".tif;.tiff",
1411 tiff_decode_formats,
1412 tiff_patterns
1414 { &CLSID_WineTgaDecoder,
1415 "The Wine Project",
1416 "TGA Decoder",
1417 "1.0.0.0",
1418 &GUID_VendorWine,
1419 &GUID_WineContainerFormatTga,
1420 "image/x-targa",
1421 ".tga;.tpic",
1422 tga_formats,
1423 tga_patterns
1425 { NULL } /* list terminator */
1428 static GUID const * const bmp_encode_formats[] = {
1429 &GUID_WICPixelFormat16bppBGR555,
1430 &GUID_WICPixelFormat16bppBGR565,
1431 &GUID_WICPixelFormat24bppBGR,
1432 &GUID_WICPixelFormat32bppBGR,
1433 &GUID_WICPixelFormatBlackWhite,
1434 &GUID_WICPixelFormat1bppIndexed,
1435 &GUID_WICPixelFormat4bppIndexed,
1436 &GUID_WICPixelFormat8bppIndexed,
1437 NULL
1440 static GUID const * const png_encode_formats[] = {
1441 &GUID_WICPixelFormat24bppBGR,
1442 &GUID_WICPixelFormatBlackWhite,
1443 &GUID_WICPixelFormat2bppGray,
1444 &GUID_WICPixelFormat4bppGray,
1445 &GUID_WICPixelFormat8bppGray,
1446 &GUID_WICPixelFormat16bppGray,
1447 &GUID_WICPixelFormat32bppBGR,
1448 &GUID_WICPixelFormat32bppBGRA,
1449 &GUID_WICPixelFormat48bppRGB,
1450 &GUID_WICPixelFormat64bppRGBA,
1451 &GUID_WICPixelFormat1bppIndexed,
1452 &GUID_WICPixelFormat2bppIndexed,
1453 &GUID_WICPixelFormat4bppIndexed,
1454 &GUID_WICPixelFormat8bppIndexed,
1455 NULL
1458 static GUID const * const tiff_encode_formats[] = {
1459 &GUID_WICPixelFormatBlackWhite,
1460 &GUID_WICPixelFormat4bppGray,
1461 &GUID_WICPixelFormat8bppGray,
1462 &GUID_WICPixelFormat1bppIndexed,
1463 &GUID_WICPixelFormat4bppIndexed,
1464 &GUID_WICPixelFormat8bppIndexed,
1465 &GUID_WICPixelFormat24bppBGR,
1466 &GUID_WICPixelFormat32bppBGRA,
1467 &GUID_WICPixelFormat32bppPBGRA,
1468 &GUID_WICPixelFormat48bppRGB,
1469 &GUID_WICPixelFormat64bppRGBA,
1470 &GUID_WICPixelFormat64bppPRGBA,
1471 NULL
1474 static GUID const * const icns_encode_formats[] = {
1475 &GUID_WICPixelFormat32bppBGRA,
1476 NULL
1479 static struct regsvr_encoder const encoder_list[] = {
1480 { &CLSID_WICBmpEncoder,
1481 "The Wine Project",
1482 "BMP Encoder",
1483 "1.0.0.0",
1484 &GUID_VendorMicrosoft,
1485 &GUID_ContainerFormatBmp,
1486 "image/bmp",
1487 ".bmp,.dib,.rle",
1488 bmp_encode_formats
1490 { &CLSID_WICGifEncoder,
1491 "The Wine Project",
1492 "GIF Encoder",
1493 "1.0.0.0",
1494 &GUID_VendorMicrosoft,
1495 &GUID_ContainerFormatGif,
1496 "image/gif",
1497 ".gif",
1498 gif_formats
1500 { &CLSID_WICJpegEncoder,
1501 "The Wine Project",
1502 "JPEG Encoder",
1503 "1.0.0.0",
1504 &GUID_VendorMicrosoft,
1505 &GUID_ContainerFormatJpeg,
1506 "image/jpeg",
1507 ".jpg;.jpeg;.jfif",
1508 jpeg_formats
1510 { &CLSID_WICPngEncoder,
1511 "The Wine Project",
1512 "PNG Encoder",
1513 "1.0.0.0",
1514 &GUID_VendorMicrosoft,
1515 &GUID_ContainerFormatPng,
1516 "image/png",
1517 ".png",
1518 png_encode_formats
1520 { &CLSID_WICTiffEncoder,
1521 "The Wine Project",
1522 "TIFF Encoder",
1523 "1.0.0.0",
1524 &GUID_VendorMicrosoft,
1525 &GUID_ContainerFormatTiff,
1526 "image/tiff",
1527 ".tif;.tiff",
1528 tiff_encode_formats
1530 { &CLSID_WICIcnsEncoder,
1531 "The Wine Project",
1532 "ICNS Encoder",
1533 "1.0.0.0",
1534 &GUID_VendorWine,
1535 NULL, /* no container format guid */
1536 "image/icns",
1537 ".icns",
1538 icns_encode_formats
1540 { NULL } /* list terminator */
1543 static GUID const * const converter_formats[] = {
1544 &GUID_WICPixelFormat1bppIndexed,
1545 &GUID_WICPixelFormat2bppIndexed,
1546 &GUID_WICPixelFormat4bppIndexed,
1547 &GUID_WICPixelFormat8bppIndexed,
1548 &GUID_WICPixelFormatBlackWhite,
1549 &GUID_WICPixelFormat2bppGray,
1550 &GUID_WICPixelFormat4bppGray,
1551 &GUID_WICPixelFormat8bppGray,
1552 &GUID_WICPixelFormat16bppGray,
1553 &GUID_WICPixelFormat16bppBGR555,
1554 &GUID_WICPixelFormat16bppBGR565,
1555 &GUID_WICPixelFormat16bppBGRA5551,
1556 &GUID_WICPixelFormat24bppBGR,
1557 &GUID_WICPixelFormat24bppRGB,
1558 &GUID_WICPixelFormat32bppBGR,
1559 &GUID_WICPixelFormat32bppRGB,
1560 &GUID_WICPixelFormat32bppBGRA,
1561 &GUID_WICPixelFormat32bppRGBA,
1562 &GUID_WICPixelFormat32bppPBGRA,
1563 &GUID_WICPixelFormat32bppPRGBA,
1564 &GUID_WICPixelFormat32bppGrayFloat,
1565 &GUID_WICPixelFormat48bppRGB,
1566 &GUID_WICPixelFormat64bppRGBA,
1567 &GUID_WICPixelFormat32bppCMYK,
1568 NULL
1571 static struct regsvr_converter const converter_list[] = {
1572 { &CLSID_WICDefaultFormatConverter,
1573 "The Wine Project",
1574 "Default Pixel Format Converter",
1575 "1.0.0.0",
1576 &GUID_VendorMicrosoft,
1577 converter_formats
1579 { NULL } /* list terminator */
1582 static const BYTE no_magic[1] = { 0 };
1583 static const BYTE no_mask[1] = { 0 };
1585 static const struct metadata_pattern ifd_metadata_pattern[] = {
1586 { 0, 1, no_magic, no_mask, 0 },
1587 { 0 }
1590 static const struct reader_containers ifd_containers[] = {
1592 &GUID_ContainerFormatTiff,
1593 ifd_metadata_pattern
1595 { NULL } /* list terminator */
1598 static const BYTE tEXt[] = "tEXt";
1600 static const struct metadata_pattern pngtext_metadata_pattern[] = {
1601 { 4, 4, tEXt, mask_all, 4 },
1602 { 0 }
1605 static const struct reader_containers pngtext_containers[] = {
1607 &GUID_ContainerFormatPng,
1608 pngtext_metadata_pattern
1610 { NULL } /* list terminator */
1613 static const BYTE gAMA[] = "gAMA";
1615 static const struct metadata_pattern pnggama_metadata_pattern[] = {
1616 { 4, 4, gAMA, mask_all, 4 },
1617 { 0 }
1620 static const struct reader_containers pnggama_containers[] = {
1622 &GUID_ContainerFormatPng,
1623 pnggama_metadata_pattern
1625 { NULL } /* list terminator */
1628 static const BYTE cHRM[] = "cHRM";
1630 static const struct metadata_pattern pngchrm_metadata_pattern[] = {
1631 { 4, 4, cHRM, mask_all, 4 },
1632 { 0 }
1635 static const struct reader_containers pngchrm_containers[] = {
1637 &GUID_ContainerFormatPng,
1638 pngchrm_metadata_pattern
1640 { NULL } /* list terminator */
1643 static const struct metadata_pattern lsd_metadata_patterns[] = {
1644 { 0, 6, gif87a_magic, mask_all, 0 },
1645 { 0, 6, gif89a_magic, mask_all, 0 },
1646 { 0 }
1649 static const struct reader_containers lsd_containers[] = {
1651 &GUID_ContainerFormatGif,
1652 lsd_metadata_patterns
1654 { NULL } /* list terminator */
1657 static const BYTE imd_magic[] = { 0x2c };
1659 static const struct metadata_pattern imd_metadata_pattern[] = {
1660 { 0, 1, imd_magic, mask_all, 1 },
1661 { 0 }
1664 static const struct reader_containers imd_containers[] = {
1666 &GUID_ContainerFormatGif,
1667 imd_metadata_pattern
1669 { NULL } /* list terminator */
1672 static const BYTE gce_magic[] = { 0x21, 0xf9, 0x04 };
1674 static const struct metadata_pattern gce_metadata_pattern[] = {
1675 { 0, 3, gce_magic, mask_all, 3 },
1676 { 0 }
1679 static const struct reader_containers gce_containers[] = {
1681 &GUID_ContainerFormatGif,
1682 gce_metadata_pattern
1684 { NULL } /* list terminator */
1687 static const BYTE ape_magic[] = { 0x21, 0xff, 0x0b };
1689 static const struct metadata_pattern ape_metadata_pattern[] = {
1690 { 0, 3, ape_magic, mask_all, 0 },
1691 { 0 }
1694 static const struct reader_containers ape_containers[] = {
1696 &GUID_ContainerFormatGif,
1697 ape_metadata_pattern
1699 { NULL } /* list terminator */
1702 static const BYTE gif_comment_magic[] = { 0x21, 0xfe };
1704 static const struct metadata_pattern gif_comment_metadata_pattern[] = {
1705 { 0, 2, gif_comment_magic, mask_all, 0 },
1706 { 0 }
1709 static const struct reader_containers gif_comment_containers[] = {
1711 &GUID_ContainerFormatGif,
1712 gif_comment_metadata_pattern
1714 { NULL } /* list terminator */
1717 static struct regsvr_metadatareader const metadatareader_list[] = {
1718 { &CLSID_WICUnknownMetadataReader,
1719 "The Wine Project",
1720 "Unknown Metadata Reader",
1721 "1.0.0.0",
1722 "1.0.0.0",
1723 &GUID_VendorMicrosoft,
1724 &GUID_MetadataFormatUnknown,
1725 0, 0, 0,
1726 NULL
1728 { &CLSID_WICIfdMetadataReader,
1729 "The Wine Project",
1730 "Ifd Reader",
1731 "1.0.0.0",
1732 "1.0.0.0",
1733 &GUID_VendorMicrosoft,
1734 &GUID_MetadataFormatIfd,
1735 1, 1, 0,
1736 ifd_containers
1738 { &CLSID_WICPngChrmMetadataReader,
1739 "The Wine Project",
1740 "Chunk cHRM Reader",
1741 "1.0.0.0",
1742 "1.0.0.0",
1743 &GUID_VendorMicrosoft,
1744 &GUID_MetadataFormatChunkcHRM,
1745 0, 0, 0,
1746 pngchrm_containers
1748 { &CLSID_WICPngGamaMetadataReader,
1749 "The Wine Project",
1750 "Chunk gAMA Reader",
1751 "1.0.0.0",
1752 "1.0.0.0",
1753 &GUID_VendorMicrosoft,
1754 &GUID_MetadataFormatChunkgAMA,
1755 0, 0, 0,
1756 pnggama_containers
1758 { &CLSID_WICPngTextMetadataReader,
1759 "The Wine Project",
1760 "Chunk tEXt Reader",
1761 "1.0.0.0",
1762 "1.0.0.0",
1763 &GUID_VendorMicrosoft,
1764 &GUID_MetadataFormatChunktEXt,
1765 0, 0, 0,
1766 pngtext_containers
1768 { &CLSID_WICLSDMetadataReader,
1769 "The Wine Project",
1770 "Logical Screen Descriptor Reader",
1771 "1.0.0.0",
1772 "1.0.0.0",
1773 &GUID_VendorMicrosoft,
1774 &GUID_MetadataFormatLSD,
1775 0, 0, 0,
1776 lsd_containers
1778 { &CLSID_WICIMDMetadataReader,
1779 "The Wine Project",
1780 "Image Descriptor Reader",
1781 "1.0.0.0",
1782 "1.0.0.0",
1783 &GUID_VendorMicrosoft,
1784 &GUID_MetadataFormatIMD,
1785 0, 0, 0,
1786 imd_containers
1788 { &CLSID_WICGCEMetadataReader,
1789 "The Wine Project",
1790 "Graphic Control Extension Reader",
1791 "1.0.0.0",
1792 "1.0.0.0",
1793 &GUID_VendorMicrosoft,
1794 &GUID_MetadataFormatGCE,
1795 0, 0, 0,
1796 gce_containers
1798 { &CLSID_WICAPEMetadataReader,
1799 "The Wine Project",
1800 "Application Extension Reader",
1801 "1.0.0.0",
1802 "1.0.0.0",
1803 &GUID_VendorMicrosoft,
1804 &GUID_MetadataFormatAPE,
1805 0, 0, 0,
1806 ape_containers
1808 { &CLSID_WICGifCommentMetadataReader,
1809 "The Wine Project",
1810 "Comment Extension Reader",
1811 "1.0.0.0",
1812 "1.0.0.0",
1813 &GUID_VendorMicrosoft,
1814 &GUID_MetadataFormatGifComment,
1815 0, 0, 0,
1816 gif_comment_containers
1818 { NULL } /* list terminator */
1821 static BYTE const channel_mask_1bit[] = { 0x01 };
1822 static BYTE const channel_mask_2bit[] = { 0x03 };
1823 static BYTE const channel_mask_4bit[] = { 0x0f };
1825 static BYTE const channel_mask_8bit[] = { 0xff, 0x00, 0x00, 0x00 };
1826 static BYTE const channel_mask_8bit2[] = { 0x00, 0xff, 0x00, 0x00 };
1827 static BYTE const channel_mask_8bit3[] = { 0x00, 0x00, 0xff, 0x00 };
1828 static BYTE const channel_mask_8bit4[] = { 0x00, 0x00, 0x00, 0xff };
1830 static BYTE const channel_mask_16bit[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1831 static BYTE const channel_mask_16bit2[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1832 static BYTE const channel_mask_16bit3[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
1833 static BYTE const channel_mask_16bit4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
1835 static BYTE const channel_mask_32bit[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1837 static BYTE const channel_mask_96bit1[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1838 static BYTE const channel_mask_96bit2[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 };
1839 static BYTE const channel_mask_96bit3[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff };
1841 static BYTE const channel_mask_128bit1[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1842 static BYTE const channel_mask_128bit2[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1843 static BYTE const channel_mask_128bit3[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 };
1844 static BYTE const channel_mask_128bit4[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff };
1846 static BYTE const channel_mask_5bit[] = { 0x1f, 0x00 };
1847 static BYTE const channel_mask_5bit2[] = { 0xe0, 0x03 };
1848 static BYTE const channel_mask_5bit3[] = { 0x00, 0x7c };
1849 static BYTE const channel_mask_5bit4[] = { 0x00, 0x80 };
1851 static BYTE const channel_mask_BGR565_2[] = { 0xe0, 0x07 };
1852 static BYTE const channel_mask_BGR565_3[] = { 0x00, 0xf8 };
1854 static BYTE const * const channel_masks_1bit[] = { channel_mask_1bit };
1855 static BYTE const * const channel_masks_2bit[] = { channel_mask_2bit };
1856 static BYTE const * const channel_masks_4bit[] = { channel_mask_4bit };
1857 static BYTE const * const channel_masks_8bit[] = { channel_mask_8bit,
1858 channel_mask_8bit2, channel_mask_8bit3, channel_mask_8bit4 };
1859 static BYTE const * const channel_masks_16bit[] = { channel_mask_16bit,
1860 channel_mask_16bit2, channel_mask_16bit3, channel_mask_16bit4};
1862 static BYTE const * const channel_masks_32bit[] = { channel_mask_32bit };
1863 static BYTE const * const channel_masks_96bit[] = { channel_mask_96bit1, channel_mask_96bit2, channel_mask_96bit3 };
1864 static BYTE const * const channel_masks_128bit[] = { channel_mask_128bit1, channel_mask_128bit2, channel_mask_128bit3, channel_mask_128bit4 };
1866 static BYTE const * const channel_masks_BGRA5551[] = { channel_mask_5bit,
1867 channel_mask_5bit2, channel_mask_5bit3, channel_mask_5bit4 };
1869 static BYTE const * const channel_masks_BGR565[] = { channel_mask_5bit,
1870 channel_mask_BGR565_2, channel_mask_BGR565_3 };
1872 static struct regsvr_pixelformat const pixelformat_list[] = {
1873 { &GUID_WICPixelFormat1bppIndexed,
1874 "The Wine Project",
1875 "1bpp Indexed",
1876 NULL, /* no version */
1877 &GUID_VendorMicrosoft,
1878 1, /* bitsperpixel */
1879 1, /* channel count */
1880 channel_masks_1bit,
1881 WICPixelFormatNumericRepresentationIndexed,
1884 { &GUID_WICPixelFormat2bppIndexed,
1885 "The Wine Project",
1886 "2bpp Indexed",
1887 NULL, /* no version */
1888 &GUID_VendorMicrosoft,
1889 2, /* bitsperpixel */
1890 1, /* channel count */
1891 channel_masks_2bit,
1892 WICPixelFormatNumericRepresentationIndexed,
1895 { &GUID_WICPixelFormat4bppIndexed,
1896 "The Wine Project",
1897 "4bpp Indexed",
1898 NULL, /* no version */
1899 &GUID_VendorMicrosoft,
1900 4, /* bitsperpixel */
1901 1, /* channel count */
1902 channel_masks_4bit,
1903 WICPixelFormatNumericRepresentationIndexed,
1906 { &GUID_WICPixelFormat8bppIndexed,
1907 "The Wine Project",
1908 "8bpp Indexed",
1909 NULL, /* no version */
1910 &GUID_VendorMicrosoft,
1911 8, /* bitsperpixel */
1912 1, /* channel count */
1913 channel_masks_8bit,
1914 WICPixelFormatNumericRepresentationIndexed,
1917 { &GUID_WICPixelFormatBlackWhite,
1918 "The Wine Project",
1919 "Black and White",
1920 NULL, /* no version */
1921 &GUID_VendorMicrosoft,
1922 1, /* bitsperpixel */
1923 1, /* channel count */
1924 channel_masks_1bit,
1925 WICPixelFormatNumericRepresentationUnsignedInteger,
1928 { &GUID_WICPixelFormat2bppGray,
1929 "The Wine Project",
1930 "2bpp Grayscale",
1931 NULL, /* no version */
1932 &GUID_VendorMicrosoft,
1933 2, /* bitsperpixel */
1934 1, /* channel count */
1935 channel_masks_2bit,
1936 WICPixelFormatNumericRepresentationUnsignedInteger,
1939 { &GUID_WICPixelFormat4bppGray,
1940 "The Wine Project",
1941 "4bpp Grayscale",
1942 NULL, /* no version */
1943 &GUID_VendorMicrosoft,
1944 4, /* bitsperpixel */
1945 1, /* channel count */
1946 channel_masks_4bit,
1947 WICPixelFormatNumericRepresentationUnsignedInteger,
1950 { &GUID_WICPixelFormat8bppGray,
1951 "The Wine Project",
1952 "8bpp Grayscale",
1953 NULL, /* no version */
1954 &GUID_VendorMicrosoft,
1955 8, /* bitsperpixel */
1956 1, /* channel count */
1957 channel_masks_8bit,
1958 WICPixelFormatNumericRepresentationUnsignedInteger,
1961 { &GUID_WICPixelFormat16bppGray,
1962 "The Wine Project",
1963 "16bpp Grayscale",
1964 NULL, /* no version */
1965 &GUID_VendorMicrosoft,
1966 16, /* bitsperpixel */
1967 1, /* channel count */
1968 channel_masks_16bit,
1969 WICPixelFormatNumericRepresentationUnsignedInteger,
1972 { &GUID_WICPixelFormat16bppBGR555,
1973 "The Wine Project",
1974 "16bpp BGR555",
1975 NULL, /* no version */
1976 &GUID_VendorMicrosoft,
1977 16, /* bitsperpixel */
1978 3, /* channel count */
1979 channel_masks_BGRA5551,
1980 WICPixelFormatNumericRepresentationUnsignedInteger,
1983 { &GUID_WICPixelFormat16bppBGR565,
1984 "The Wine Project",
1985 "16bpp BGR565",
1986 NULL, /* no version */
1987 &GUID_VendorMicrosoft,
1988 16, /* bitsperpixel */
1989 3, /* channel count */
1990 channel_masks_BGR565,
1991 WICPixelFormatNumericRepresentationUnsignedInteger,
1994 { &GUID_WICPixelFormat16bppBGRA5551,
1995 "The Wine Project",
1996 "16bpp BGRA5551",
1997 NULL, /* no version */
1998 &GUID_VendorMicrosoft,
1999 16, /* bitsperpixel */
2000 4, /* channel count */
2001 channel_masks_BGRA5551,
2002 WICPixelFormatNumericRepresentationUnsignedInteger,
2005 { &GUID_WICPixelFormat24bppBGR,
2006 "The Wine Project",
2007 "24bpp BGR",
2008 NULL, /* no version */
2009 &GUID_VendorMicrosoft,
2010 24, /* bitsperpixel */
2011 3, /* channel count */
2012 channel_masks_8bit,
2013 WICPixelFormatNumericRepresentationUnsignedInteger,
2016 { &GUID_WICPixelFormat24bppRGB,
2017 "The Wine Project",
2018 "24bpp RGB",
2019 NULL, /* no version */
2020 &GUID_VendorMicrosoft,
2021 24, /* bitsperpixel */
2022 3, /* channel count */
2023 channel_masks_8bit,
2024 WICPixelFormatNumericRepresentationUnsignedInteger,
2027 { &GUID_WICPixelFormat32bppBGR,
2028 "The Wine Project",
2029 "32bpp BGR",
2030 NULL, /* no version */
2031 &GUID_VendorMicrosoft,
2032 32, /* bitsperpixel */
2033 3, /* channel count */
2034 channel_masks_8bit,
2035 WICPixelFormatNumericRepresentationUnsignedInteger,
2038 { &GUID_WICPixelFormat32bppRGB,
2039 "The Wine Project",
2040 "32bpp RGB",
2041 NULL, /* no version */
2042 &GUID_VendorMicrosoft,
2043 32, /* bitsperpixel */
2044 3, /* channel count */
2045 channel_masks_8bit,
2046 WICPixelFormatNumericRepresentationUnsignedInteger,
2049 { &GUID_WICPixelFormat32bppBGRA,
2050 "The Wine Project",
2051 "32bpp BGRA",
2052 NULL, /* no version */
2053 &GUID_VendorMicrosoft,
2054 32, /* bitsperpixel */
2055 4, /* channel count */
2056 channel_masks_8bit,
2057 WICPixelFormatNumericRepresentationUnsignedInteger,
2060 { &GUID_WICPixelFormat32bppRGBA,
2061 "The Wine Project",
2062 "32bpp RGBA",
2063 NULL, /* no version */
2064 &GUID_VendorMicrosoft,
2065 32, /* bitsperpixel */
2066 4, /* channel count */
2067 channel_masks_8bit,
2068 WICPixelFormatNumericRepresentationUnsignedInteger,
2071 { &GUID_WICPixelFormat32bppPBGRA,
2072 "The Wine Project",
2073 "32bpp PBGRA",
2074 NULL, /* no version */
2075 &GUID_VendorMicrosoft,
2076 32, /* bitsperpixel */
2077 4, /* channel count */
2078 channel_masks_8bit,
2079 WICPixelFormatNumericRepresentationUnsignedInteger,
2082 { &GUID_WICPixelFormat32bppPRGBA,
2083 "The Wine Project",
2084 "32bpp PRGBA",
2085 NULL, /* no version */
2086 &GUID_VendorMicrosoft,
2087 32, /* bitsperpixel */
2088 4, /* channel count */
2089 channel_masks_8bit,
2090 WICPixelFormatNumericRepresentationUnsignedInteger,
2093 { &GUID_WICPixelFormat32bppGrayFloat,
2094 "The Wine Project",
2095 "32bpp GrayFloat",
2096 NULL, /* no version */
2097 &GUID_VendorMicrosoft,
2098 32, /* bitsperpixel */
2099 1, /* channel count */
2100 channel_masks_32bit,
2101 WICPixelFormatNumericRepresentationFloat,
2104 { &GUID_WICPixelFormat48bppRGB,
2105 "The Wine Project",
2106 "48bpp RGB",
2107 NULL, /* no version */
2108 &GUID_VendorMicrosoft,
2109 48, /* bitsperpixel */
2110 3, /* channel count */
2111 channel_masks_16bit,
2112 WICPixelFormatNumericRepresentationUnsignedInteger,
2115 { &GUID_WICPixelFormat64bppRGBA,
2116 "The Wine Project",
2117 "64bpp RGBA",
2118 NULL, /* no version */
2119 &GUID_VendorMicrosoft,
2120 64, /* bitsperpixel */
2121 4, /* channel count */
2122 channel_masks_16bit,
2123 WICPixelFormatNumericRepresentationUnsignedInteger,
2126 { &GUID_WICPixelFormat64bppPRGBA,
2127 "The Wine Project",
2128 "64bpp PRGBA",
2129 NULL, /* no version */
2130 &GUID_VendorMicrosoft,
2131 64, /* bitsperpixel */
2132 4, /* channel count */
2133 channel_masks_16bit,
2134 WICPixelFormatNumericRepresentationUnsignedInteger,
2137 { &GUID_WICPixelFormat32bppCMYK,
2138 "The Wine Project",
2139 "32bpp CMYK",
2140 NULL, /* no version */
2141 &GUID_VendorMicrosoft,
2142 32, /* bitsperpixel */
2143 4, /* channel count */
2144 channel_masks_8bit,
2145 WICPixelFormatNumericRepresentationUnsignedInteger,
2148 { &GUID_WICPixelFormat64bppCMYK,
2149 "The Wine Project",
2150 "64bpp CMYK",
2151 NULL, /* no version */
2152 &GUID_VendorMicrosoft,
2153 64, /* bitsperpixel */
2154 4, /* channel count */
2155 channel_masks_16bit,
2156 WICPixelFormatNumericRepresentationUnsignedInteger,
2159 { &GUID_WICPixelFormat96bppRGBFloat,
2160 "The Wine Project",
2161 "96bpp RGBFloat",
2162 NULL, /* no version */
2163 &GUID_VendorMicrosoft,
2164 96, /* bitsperpixel */
2165 3, /* channel count */
2166 channel_masks_96bit,
2167 WICPixelFormatNumericRepresentationFloat,
2170 { &GUID_WICPixelFormat128bppRGBAFloat,
2171 "The Wine Project",
2172 "128bpp RGBAFloat",
2173 NULL, /* no version */
2174 &GUID_VendorMicrosoft,
2175 128, /* bitsperpixel */
2176 4, /* channel count */
2177 channel_masks_128bit,
2178 WICPixelFormatNumericRepresentationFloat,
2181 { &GUID_WICPixelFormat128bppPRGBAFloat,
2182 "The Wine Project",
2183 "128bpp PRGBAFloat",
2184 NULL, /* no version */
2185 &GUID_VendorMicrosoft,
2186 128, /* bitsperpixel */
2187 4, /* channel count */
2188 channel_masks_128bit,
2189 WICPixelFormatNumericRepresentationFloat,
2192 { NULL } /* list terminator */
2195 struct regsvr_category
2197 const CLSID *clsid; /* NULL for end of list */
2200 static const struct regsvr_category category_list[] = {
2201 { &CATID_WICBitmapDecoders },
2202 { &CATID_WICBitmapEncoders },
2203 { &CATID_WICFormatConverters },
2204 { &CATID_WICMetadataReader },
2205 { &CATID_WICPixelFormats },
2206 { NULL }
2209 static HRESULT register_categories(const struct regsvr_category *list)
2211 LONG res;
2212 WCHAR buf[39];
2213 HKEY coclass_key, categories_key, instance_key;
2215 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
2216 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
2217 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
2219 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
2220 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
2221 KEY_READ | KEY_WRITE, NULL, &categories_key, NULL);
2222 if (res != ERROR_SUCCESS)
2224 RegCloseKey(coclass_key);
2225 return HRESULT_FROM_WIN32(res);
2228 res = RegCreateKeyExW(categories_key, instance_keyname, 0, NULL, 0,
2229 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
2231 for (; res == ERROR_SUCCESS && list->clsid; list++)
2233 HKEY instance_clsid_key;
2235 StringFromGUID2(list->clsid, buf, 39);
2236 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
2237 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
2238 if (res == ERROR_SUCCESS)
2240 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
2241 (const BYTE *)buf, 78);
2242 RegCloseKey(instance_clsid_key);
2246 RegCloseKey(instance_key);
2247 RegCloseKey(categories_key);
2248 RegCloseKey(coclass_key);
2250 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
2253 static HRESULT unregister_categories(const struct regsvr_category *list)
2255 LONG res;
2256 WCHAR buf[39];
2257 HKEY coclass_key, categories_key, instance_key;
2259 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
2260 KEY_READ | KEY_WRITE, &coclass_key);
2261 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
2263 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
2264 res = RegOpenKeyExW(coclass_key, buf, 0,
2265 KEY_READ | KEY_WRITE, &categories_key);
2266 if (res != ERROR_SUCCESS)
2268 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
2269 RegCloseKey(coclass_key);
2270 return HRESULT_FROM_WIN32(res);
2273 res = RegOpenKeyExW(categories_key, instance_keyname, 0,
2274 KEY_READ | KEY_WRITE, &instance_key);
2276 for (; res == ERROR_SUCCESS && list->clsid; list++)
2278 StringFromGUID2(list->clsid, buf, 39);
2279 res = RegDeleteTreeW(instance_key, buf);
2282 RegCloseKey(instance_key);
2283 RegCloseKey(categories_key);
2285 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
2286 res = RegDeleteTreeW(coclass_key, buf);
2288 RegCloseKey(coclass_key);
2290 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
2293 extern HRESULT WINAPI WIC_DllRegisterServer(void) DECLSPEC_HIDDEN;
2294 extern HRESULT WINAPI WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN;
2296 HRESULT WINAPI DllRegisterServer(void)
2298 HRESULT hr;
2300 TRACE("\n");
2302 hr = WIC_DllRegisterServer();
2303 if (SUCCEEDED(hr))
2304 hr = register_categories(category_list);
2305 if (SUCCEEDED(hr))
2306 hr = register_decoders(decoder_list);
2307 if (SUCCEEDED(hr))
2308 hr = register_encoders(encoder_list);
2309 if (SUCCEEDED(hr))
2310 hr = register_converters(converter_list);
2311 if (SUCCEEDED(hr))
2312 hr = register_metadatareaders(metadatareader_list);
2313 if (SUCCEEDED(hr))
2314 hr = register_pixelformats(pixelformat_list);
2315 return hr;
2318 HRESULT WINAPI DllUnregisterServer(void)
2320 HRESULT hr;
2322 TRACE("\n");
2324 hr = WIC_DllUnregisterServer();
2325 if (SUCCEEDED(hr))
2326 hr = unregister_categories(category_list);
2327 if (SUCCEEDED(hr))
2328 hr = unregister_decoders(decoder_list);
2329 if (SUCCEEDED(hr))
2330 hr = unregister_encoders(encoder_list);
2331 if (SUCCEEDED(hr))
2332 hr = unregister_converters(converter_list);
2333 if (SUCCEEDED(hr))
2334 hr = unregister_metadatareaders(metadatareader_list);
2335 if (SUCCEEDED(hr))
2336 hr = unregister_pixelformats(pixelformat_list);
2337 return hr;