windowscodecs: Add support for 8bpp grayscale TIFF with 8bpp alpha.
[wine.git] / dlls / windowscodecs / regsvr.c
blobccb78b824cd3c3cb68058d477a55dfb8b2e18c40
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"
32 #include "wincodec.h"
33 #include "wincodecsdk.h"
35 #include "wine/debug.h"
36 #include "wine/unicode.h"
38 #include "wincodecs_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
42 /***********************************************************************
43 * interface for self-registering
45 struct decoder_pattern
47 DWORD length; /* 0 for end of list */
48 DWORD position;
49 const BYTE *pattern;
50 const BYTE *mask;
51 DWORD endofstream;
54 struct regsvr_decoder
56 CLSID const *clsid; /* NULL for end of list */
57 LPCSTR author;
58 LPCSTR friendlyname;
59 LPCSTR version;
60 GUID const *vendor;
61 GUID const *container_format;
62 LPCSTR mimetypes;
63 LPCSTR extensions;
64 GUID const * const *formats;
65 const struct decoder_pattern *patterns;
68 static HRESULT register_decoders(struct regsvr_decoder const *list);
69 static HRESULT unregister_decoders(struct regsvr_decoder const *list);
71 struct regsvr_encoder
73 CLSID const *clsid; /* NULL for end of list */
74 LPCSTR author;
75 LPCSTR friendlyname;
76 LPCSTR version;
77 GUID const *vendor;
78 GUID const *container_format;
79 LPCSTR mimetypes;
80 LPCSTR extensions;
81 GUID const * const *formats;
84 static HRESULT register_encoders(struct regsvr_encoder const *list);
85 static HRESULT unregister_encoders(struct regsvr_encoder const *list);
87 struct regsvr_converter
89 CLSID const *clsid; /* NULL for end of list */
90 LPCSTR author;
91 LPCSTR friendlyname;
92 LPCSTR version;
93 GUID const *vendor;
94 GUID const * const *formats;
97 static HRESULT register_converters(struct regsvr_converter const *list);
98 static HRESULT unregister_converters(struct regsvr_converter const *list);
100 struct metadata_pattern
102 DWORD position;
103 DWORD length;
104 const BYTE *pattern;
105 const BYTE *mask;
106 DWORD data_offset;
109 struct reader_containers
111 GUID const *format;
112 const struct metadata_pattern *patterns;
115 struct regsvr_metadatareader
117 CLSID const *clsid; /* NULL for end of list */
118 LPCSTR author;
119 LPCSTR friendlyname;
120 LPCSTR version;
121 LPCSTR specversion;
122 GUID const *vendor;
123 GUID const *metadata_format;
124 DWORD requires_fullstream;
125 DWORD supports_padding;
126 DWORD requires_fixedsize;
127 const struct reader_containers *containers;
130 static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list);
131 static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list);
133 struct regsvr_pixelformat
135 CLSID const *clsid; /* NULL for end of list */
136 LPCSTR author;
137 LPCSTR friendlyname;
138 LPCSTR version;
139 GUID const *vendor;
140 UINT bitsperpixel;
141 UINT channelcount;
142 BYTE const * const *channelmasks;
143 WICPixelFormatNumericRepresentation numericrepresentation;
144 UINT supportsalpha;
147 static HRESULT register_pixelformats(struct regsvr_pixelformat const *list);
148 static HRESULT unregister_pixelformats(struct regsvr_pixelformat const *list);
150 /***********************************************************************
151 * static string constants
153 static const WCHAR clsid_keyname[] = {
154 'C', 'L', 'S', 'I', 'D', 0 };
155 static const char author_valuename[] = "Author";
156 static const char friendlyname_valuename[] = "FriendlyName";
157 static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0};
158 static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
159 static const char version_valuename[] = "Version";
160 static const char mimetypes_valuename[] = "MimeTypes";
161 static const char extensions_valuename[] = "FileExtensions";
162 static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0};
163 static const WCHAR patterns_keyname[] = {'P','a','t','t','e','r','n','s',0};
164 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
165 static const WCHAR clsid_valuename[] = {'C','L','S','I','D',0};
166 static const char length_valuename[] = "Length";
167 static const char position_valuename[] = "Position";
168 static const char pattern_valuename[] = "Pattern";
169 static const char mask_valuename[] = "Mask";
170 static const char endofstream_valuename[] = "EndOfStream";
171 static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
172 static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
173 static const char specversion_valuename[] = "SpecVersion";
174 static const char requiresfullstream_valuename[] = "RequiresFullStream";
175 static const char supportspadding_valuename[] = "SupportsPadding";
176 static const char requiresfixedsize_valuename[] = "FixedSize";
177 static const WCHAR containers_keyname[] = {'C','o','n','t','a','i','n','e','r','s',0};
178 static const char dataoffset_valuename[] = "DataOffset";
179 static const char bitsperpixel_valuename[] = "BitLength";
180 static const char channelcount_valuename[] = "ChannelCount";
181 static const char numericrepresentation_valuename[] = "NumericRepresentation";
182 static const char supportstransparency_valuename[] = "SupportsTransparency";
183 static const WCHAR channelmasks_keyname[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
185 /***********************************************************************
186 * register_decoders
188 static HRESULT register_decoders(struct regsvr_decoder const *list)
190 LONG res = ERROR_SUCCESS;
191 HKEY coclass_key;
192 WCHAR buf[39];
193 HKEY decoders_key;
194 HKEY instance_key;
196 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
197 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
198 if (res == ERROR_SUCCESS) {
199 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
200 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
201 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
202 if (res == ERROR_SUCCESS)
204 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
205 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
206 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
208 if (res != ERROR_SUCCESS)
209 RegCloseKey(coclass_key);
211 if (res != ERROR_SUCCESS) goto error_return;
213 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
214 HKEY clsid_key;
215 HKEY instance_clsid_key;
217 StringFromGUID2(list->clsid, buf, 39);
218 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
219 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
220 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
222 StringFromGUID2(list->clsid, buf, 39);
223 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
224 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
225 if (res == ERROR_SUCCESS) {
226 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
227 (const BYTE*)buf, 78);
228 RegCloseKey(instance_clsid_key);
230 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
232 if (list->author) {
233 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
234 (const BYTE*)list->author,
235 strlen(list->author) + 1);
236 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
239 if (list->friendlyname) {
240 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
241 (const BYTE*)list->friendlyname,
242 strlen(list->friendlyname) + 1);
243 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
246 if (list->vendor) {
247 StringFromGUID2(list->vendor, buf, 39);
248 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
249 (const BYTE*)buf, 78);
250 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
253 if (list->container_format) {
254 StringFromGUID2(list->container_format, buf, 39);
255 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ,
256 (const BYTE*)buf, 78);
257 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
260 if (list->version) {
261 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
262 (const BYTE*)list->version,
263 strlen(list->version) + 1);
264 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
267 if (list->mimetypes) {
268 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ,
269 (const BYTE*)list->mimetypes,
270 strlen(list->mimetypes) + 1);
271 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
274 if (list->extensions) {
275 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ,
276 (const BYTE*)list->extensions,
277 strlen(list->extensions) + 1);
278 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
281 if (list->formats) {
282 HKEY formats_key;
283 GUID const * const *format;
285 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0,
286 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
287 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
288 for (format=list->formats; *format; ++format)
290 HKEY format_key;
291 StringFromGUID2(*format, buf, 39);
292 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
293 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
294 if (res != ERROR_SUCCESS) break;
295 RegCloseKey(format_key);
297 RegCloseKey(formats_key);
298 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
301 if (list->patterns) {
302 HKEY patterns_key;
303 int i;
305 res = RegCreateKeyExW(clsid_key, patterns_keyname, 0, NULL, 0,
306 KEY_READ | KEY_WRITE, NULL, &patterns_key, NULL);
307 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
308 for (i=0; list->patterns[i].length; i++)
310 HKEY pattern_key;
311 static const WCHAR int_format[] = {'%','i',0};
312 snprintfW(buf, 39, int_format, i);
313 res = RegCreateKeyExW(patterns_key, buf, 0, NULL, 0,
314 KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL);
315 if (res != ERROR_SUCCESS) break;
316 res = RegSetValueExA(pattern_key, length_valuename, 0, REG_DWORD,
317 (const BYTE*)&list->patterns[i].length, 4);
318 if (res == ERROR_SUCCESS)
319 res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD,
320 (const BYTE*)&list->patterns[i].position, 4);
321 if (res == ERROR_SUCCESS)
322 res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY,
323 list->patterns[i].pattern,
324 list->patterns[i].length);
325 if (res == ERROR_SUCCESS)
326 res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY,
327 list->patterns[i].mask,
328 list->patterns[i].length);
329 if (res == ERROR_SUCCESS)
330 res = RegSetValueExA(pattern_key, endofstream_valuename, 0, REG_DWORD,
331 (const BYTE*)&list->patterns[i].endofstream, 4);
332 RegCloseKey(pattern_key);
334 RegCloseKey(patterns_key);
335 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
338 error_close_clsid_key:
339 RegCloseKey(clsid_key);
342 error_close_coclass_key:
343 RegCloseKey(instance_key);
344 RegCloseKey(decoders_key);
345 RegCloseKey(coclass_key);
346 error_return:
347 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
350 /***********************************************************************
351 * unregister_decoders
353 static HRESULT unregister_decoders(struct regsvr_decoder const *list)
355 LONG res = ERROR_SUCCESS;
356 HKEY coclass_key;
357 WCHAR buf[39];
358 HKEY decoders_key;
359 HKEY instance_key;
361 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
362 KEY_READ | KEY_WRITE, &coclass_key);
363 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
365 if (res == ERROR_SUCCESS) {
366 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
367 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
368 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
369 if (res == ERROR_SUCCESS)
371 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
372 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
373 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
375 if (res != ERROR_SUCCESS)
376 RegCloseKey(coclass_key);
378 if (res != ERROR_SUCCESS) goto error_return;
380 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
381 StringFromGUID2(list->clsid, buf, 39);
383 res = RegDeleteTreeW(coclass_key, buf);
384 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
385 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
387 res = RegDeleteTreeW(instance_key, buf);
388 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
389 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
392 error_close_coclass_key:
393 RegCloseKey(instance_key);
394 RegCloseKey(decoders_key);
395 RegCloseKey(coclass_key);
396 error_return:
397 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
400 /***********************************************************************
401 * register_encoders
403 static HRESULT register_encoders(struct regsvr_encoder const *list)
405 LONG res = ERROR_SUCCESS;
406 HKEY coclass_key;
407 WCHAR buf[39];
408 HKEY encoders_key;
409 HKEY instance_key;
411 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
412 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
413 if (res == ERROR_SUCCESS) {
414 StringFromGUID2(&CATID_WICBitmapEncoders, buf, 39);
415 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
416 KEY_READ | KEY_WRITE, NULL, &encoders_key, NULL);
417 if (res == ERROR_SUCCESS)
419 res = RegCreateKeyExW(encoders_key, instance_keyname, 0, NULL, 0,
420 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
421 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
423 if (res != ERROR_SUCCESS)
424 RegCloseKey(coclass_key);
426 if (res != ERROR_SUCCESS) goto error_return;
428 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
429 HKEY clsid_key;
430 HKEY instance_clsid_key;
432 StringFromGUID2(list->clsid, buf, 39);
433 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
434 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
435 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
437 StringFromGUID2(list->clsid, buf, 39);
438 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
439 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
440 if (res == ERROR_SUCCESS) {
441 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
442 (const BYTE*)buf, 78);
443 RegCloseKey(instance_clsid_key);
445 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
447 if (list->author) {
448 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
449 (const BYTE*)list->author,
450 strlen(list->author) + 1);
451 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
454 if (list->friendlyname) {
455 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
456 (const BYTE*)list->friendlyname,
457 strlen(list->friendlyname) + 1);
458 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
461 if (list->vendor) {
462 StringFromGUID2(list->vendor, buf, 39);
463 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
464 (const BYTE*)buf, 78);
465 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
468 if (list->container_format) {
469 StringFromGUID2(list->container_format, buf, 39);
470 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ,
471 (const BYTE*)buf, 78);
472 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
475 if (list->version) {
476 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
477 (const BYTE*)list->version,
478 strlen(list->version) + 1);
479 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
482 if (list->mimetypes) {
483 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ,
484 (const BYTE*)list->mimetypes,
485 strlen(list->mimetypes) + 1);
486 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
489 if (list->extensions) {
490 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ,
491 (const BYTE*)list->extensions,
492 strlen(list->extensions) + 1);
493 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
496 if (list->formats) {
497 HKEY formats_key;
498 GUID const * const *format;
500 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0,
501 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
502 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
503 for (format=list->formats; *format; ++format)
505 HKEY format_key;
506 StringFromGUID2(*format, buf, 39);
507 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
508 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
509 if (res != ERROR_SUCCESS) break;
510 RegCloseKey(format_key);
512 RegCloseKey(formats_key);
513 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
516 error_close_clsid_key:
517 RegCloseKey(clsid_key);
520 error_close_coclass_key:
521 RegCloseKey(instance_key);
522 RegCloseKey(encoders_key);
523 RegCloseKey(coclass_key);
524 error_return:
525 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
528 /***********************************************************************
529 * unregister_encoders
531 static HRESULT unregister_encoders(struct regsvr_encoder const *list)
533 LONG res = ERROR_SUCCESS;
534 HKEY coclass_key;
535 WCHAR buf[39];
536 HKEY encoders_key;
537 HKEY instance_key;
539 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
540 KEY_READ | KEY_WRITE, &coclass_key);
541 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
543 if (res == ERROR_SUCCESS) {
544 StringFromGUID2(&CATID_WICBitmapEncoders, buf, 39);
545 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
546 KEY_READ | KEY_WRITE, NULL, &encoders_key, NULL);
547 if (res == ERROR_SUCCESS)
549 res = RegCreateKeyExW(encoders_key, instance_keyname, 0, NULL, 0,
550 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
551 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
553 if (res != ERROR_SUCCESS)
554 RegCloseKey(coclass_key);
556 if (res != ERROR_SUCCESS) goto error_return;
558 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
559 StringFromGUID2(list->clsid, buf, 39);
561 res = RegDeleteTreeW(coclass_key, buf);
562 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
563 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
565 res = RegDeleteTreeW(instance_key, buf);
566 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
567 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
570 error_close_coclass_key:
571 RegCloseKey(instance_key);
572 RegCloseKey(encoders_key);
573 RegCloseKey(coclass_key);
574 error_return:
575 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
578 /***********************************************************************
579 * register_converters
581 static HRESULT register_converters(struct regsvr_converter const *list)
583 LONG res = ERROR_SUCCESS;
584 HKEY coclass_key;
585 WCHAR buf[39];
586 HKEY converters_key;
587 HKEY instance_key;
589 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
590 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
591 if (res == ERROR_SUCCESS) {
592 StringFromGUID2(&CATID_WICFormatConverters, buf, 39);
593 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
594 KEY_READ | KEY_WRITE, NULL, &converters_key, NULL);
595 if (res == ERROR_SUCCESS)
597 res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0,
598 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
599 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
601 if (res != ERROR_SUCCESS)
602 RegCloseKey(coclass_key);
604 if (res != ERROR_SUCCESS) goto error_return;
606 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
607 HKEY clsid_key;
608 HKEY instance_clsid_key;
610 StringFromGUID2(list->clsid, buf, 39);
611 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
612 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
613 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
615 StringFromGUID2(list->clsid, buf, 39);
616 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
617 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
618 if (res == ERROR_SUCCESS) {
619 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
620 (const BYTE*)buf, 78);
621 RegCloseKey(instance_clsid_key);
623 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
625 if (list->author) {
626 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
627 (const BYTE*)list->author,
628 strlen(list->author) + 1);
629 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
632 if (list->friendlyname) {
633 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
634 (const BYTE*)list->friendlyname,
635 strlen(list->friendlyname) + 1);
636 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
639 if (list->vendor) {
640 StringFromGUID2(list->vendor, buf, 39);
641 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
642 (const BYTE*)buf, 78);
643 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
646 if (list->version) {
647 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
648 (const BYTE*)list->version,
649 strlen(list->version) + 1);
650 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
653 if (list->formats) {
654 HKEY formats_key;
655 GUID const * const *format;
657 res = RegCreateKeyExW(clsid_key, pixelformats_keyname, 0, NULL, 0,
658 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
659 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
660 for (format=list->formats; *format; ++format)
662 HKEY format_key;
663 StringFromGUID2(*format, buf, 39);
664 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
665 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
666 if (res != ERROR_SUCCESS) break;
667 RegCloseKey(format_key);
669 RegCloseKey(formats_key);
670 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
673 error_close_clsid_key:
674 RegCloseKey(clsid_key);
677 error_close_coclass_key:
678 RegCloseKey(instance_key);
679 RegCloseKey(converters_key);
680 RegCloseKey(coclass_key);
681 error_return:
682 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
685 /***********************************************************************
686 * unregister_converters
688 static HRESULT unregister_converters(struct regsvr_converter const *list)
690 LONG res = ERROR_SUCCESS;
691 HKEY coclass_key;
692 WCHAR buf[39];
693 HKEY converters_key;
694 HKEY instance_key;
696 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
697 KEY_READ | KEY_WRITE, &coclass_key);
698 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
700 if (res == ERROR_SUCCESS) {
701 StringFromGUID2(&CATID_WICFormatConverters, buf, 39);
702 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
703 KEY_READ | KEY_WRITE, NULL, &converters_key, NULL);
704 if (res == ERROR_SUCCESS)
706 res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0,
707 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
708 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
710 if (res != ERROR_SUCCESS)
711 RegCloseKey(coclass_key);
713 if (res != ERROR_SUCCESS) goto error_return;
715 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
716 StringFromGUID2(list->clsid, buf, 39);
718 res = RegDeleteTreeW(coclass_key, buf);
719 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
720 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
722 res = RegDeleteTreeW(instance_key, buf);
723 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
724 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
727 error_close_coclass_key:
728 RegCloseKey(instance_key);
729 RegCloseKey(converters_key);
730 RegCloseKey(coclass_key);
731 error_return:
732 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
735 /***********************************************************************
736 * register_metadatareaders
738 static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list)
740 LONG res = ERROR_SUCCESS;
741 HKEY coclass_key;
742 WCHAR buf[39];
743 HKEY readers_key;
744 HKEY instance_key;
746 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
747 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
748 if (res == ERROR_SUCCESS) {
749 StringFromGUID2(&CATID_WICMetadataReader, buf, 39);
750 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
751 KEY_READ | KEY_WRITE, NULL, &readers_key, NULL);
752 if (res == ERROR_SUCCESS)
754 res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0,
755 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
756 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
758 if (res != ERROR_SUCCESS)
759 RegCloseKey(coclass_key);
761 if (res != ERROR_SUCCESS) goto error_return;
763 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
764 HKEY clsid_key;
765 HKEY instance_clsid_key;
767 StringFromGUID2(list->clsid, buf, 39);
768 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
769 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
770 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
772 StringFromGUID2(list->clsid, buf, 39);
773 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
774 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
775 if (res == ERROR_SUCCESS) {
776 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
777 (const BYTE*)buf, 78);
778 RegCloseKey(instance_clsid_key);
780 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
782 if (list->author) {
783 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
784 (const BYTE*)list->author,
785 strlen(list->author) + 1);
786 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
789 if (list->friendlyname) {
790 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
791 (const BYTE*)list->friendlyname,
792 strlen(list->friendlyname) + 1);
793 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
796 if (list->vendor) {
797 StringFromGUID2(list->vendor, buf, 39);
798 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
799 (const BYTE*)buf, 78);
800 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
803 if (list->metadata_format) {
804 StringFromGUID2(list->metadata_format, buf, 39);
805 res = RegSetValueExW(clsid_key, metadataformat_valuename, 0, REG_SZ,
806 (const BYTE*)buf, 78);
807 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
810 if (list->version) {
811 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
812 (const BYTE*)list->version,
813 strlen(list->version) + 1);
814 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
817 if (list->specversion) {
818 res = RegSetValueExA(clsid_key, specversion_valuename, 0, REG_SZ,
819 (const BYTE*)list->version,
820 strlen(list->version) + 1);
821 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
824 res = RegSetValueExA(clsid_key, requiresfullstream_valuename, 0, REG_DWORD,
825 (const BYTE*)&list->requires_fullstream, 4);
826 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
828 res = RegSetValueExA(clsid_key, supportspadding_valuename, 0, REG_DWORD,
829 (const BYTE*)&list->supports_padding, 4);
830 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
832 if (list->requires_fixedsize) {
833 res = RegSetValueExA(clsid_key, requiresfixedsize_valuename, 0, REG_DWORD,
834 (const BYTE*)&list->requires_fixedsize, 4);
835 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
838 if (list->containers) {
839 HKEY containers_key;
840 const struct reader_containers *container;
842 res = RegCreateKeyExW(clsid_key, containers_keyname, 0, NULL, 0,
843 KEY_READ | KEY_WRITE, NULL, &containers_key, NULL);
844 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
845 for (container=list->containers; container->format; ++container)
847 HKEY format_key;
848 int i;
849 StringFromGUID2(container->format, buf, 39);
850 res = RegCreateKeyExW(containers_key, buf, 0, NULL, 0,
851 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
852 if (res != ERROR_SUCCESS) break;
854 for (i=0; container->patterns[i].length; i++)
856 HKEY pattern_key;
857 static const WCHAR int_format[] = {'%','i',0};
858 snprintfW(buf, 39, int_format, i);
859 res = RegCreateKeyExW(format_key, buf, 0, NULL, 0,
860 KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL);
861 if (res != ERROR_SUCCESS) break;
862 res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD,
863 (const BYTE*)&container->patterns[i].position, 4);
864 if (res == ERROR_SUCCESS)
865 res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY,
866 container->patterns[i].pattern,
867 container->patterns[i].length);
868 if (res == ERROR_SUCCESS)
869 res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY,
870 container->patterns[i].mask,
871 container->patterns[i].length);
872 if (res == ERROR_SUCCESS && container->patterns[i].data_offset)
873 res = RegSetValueExA(pattern_key, dataoffset_valuename, 0, REG_DWORD,
874 (const BYTE*)&container->patterns[i].data_offset, 4);
875 RegCloseKey(pattern_key);
878 RegCloseKey(format_key);
880 RegCloseKey(containers_key);
883 error_close_clsid_key:
884 RegCloseKey(clsid_key);
887 error_close_coclass_key:
888 RegCloseKey(instance_key);
889 RegCloseKey(readers_key);
890 RegCloseKey(coclass_key);
891 error_return:
892 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
895 /***********************************************************************
896 * unregister_metadatareaders
898 static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list)
900 LONG res = ERROR_SUCCESS;
901 HKEY coclass_key;
902 WCHAR buf[39];
903 HKEY readers_key;
904 HKEY instance_key;
906 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
907 KEY_READ | KEY_WRITE, &coclass_key);
908 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
910 if (res == ERROR_SUCCESS) {
911 StringFromGUID2(&CATID_WICMetadataReader, buf, 39);
912 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
913 KEY_READ | KEY_WRITE, NULL, &readers_key, NULL);
914 if (res == ERROR_SUCCESS)
916 res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0,
917 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
918 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
920 if (res != ERROR_SUCCESS)
921 RegCloseKey(coclass_key);
923 if (res != ERROR_SUCCESS) goto error_return;
925 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
926 StringFromGUID2(list->clsid, buf, 39);
928 res = RegDeleteTreeW(coclass_key, buf);
929 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
930 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
932 res = RegDeleteTreeW(instance_key, buf);
933 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
934 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
937 error_close_coclass_key:
938 RegCloseKey(instance_key);
939 RegCloseKey(readers_key);
940 RegCloseKey(coclass_key);
941 error_return:
942 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
945 /***********************************************************************
946 * register_pixelformats
948 static HRESULT register_pixelformats(struct regsvr_pixelformat const *list)
950 LONG res = ERROR_SUCCESS;
951 HKEY coclass_key;
952 WCHAR buf[39];
953 HKEY formats_key;
954 HKEY instance_key;
956 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
957 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
958 if (res == ERROR_SUCCESS) {
959 StringFromGUID2(&CATID_WICPixelFormats, buf, 39);
960 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
961 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
962 if (res == ERROR_SUCCESS)
964 res = RegCreateKeyExW(formats_key, instance_keyname, 0, NULL, 0,
965 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
966 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
968 if (res != ERROR_SUCCESS)
969 RegCloseKey(coclass_key);
971 if (res != ERROR_SUCCESS) goto error_return;
973 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
974 HKEY clsid_key;
975 HKEY instance_clsid_key;
977 StringFromGUID2(list->clsid, buf, 39);
978 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
979 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
980 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
982 StringFromGUID2(list->clsid, buf, 39);
983 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
984 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
985 if (res == ERROR_SUCCESS) {
986 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
987 (const BYTE*)buf, 78);
988 RegCloseKey(instance_clsid_key);
990 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
992 if (list->author) {
993 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
994 (const BYTE*)list->author,
995 strlen(list->author) + 1);
996 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
999 if (list->friendlyname) {
1000 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
1001 (const BYTE*)list->friendlyname,
1002 strlen(list->friendlyname) + 1);
1003 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1006 if (list->vendor) {
1007 StringFromGUID2(list->vendor, buf, 39);
1008 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
1009 (const BYTE*)buf, 78);
1010 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1013 if (list->version) {
1014 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
1015 (const BYTE*)list->version,
1016 strlen(list->version) + 1);
1017 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1020 res = RegSetValueExA(clsid_key, bitsperpixel_valuename, 0, REG_DWORD,
1021 (const BYTE*)&list->bitsperpixel, 4);
1022 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1024 res = RegSetValueExA(clsid_key, channelcount_valuename, 0, REG_DWORD,
1025 (const BYTE*)&list->channelcount, 4);
1026 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1028 res = RegSetValueExA(clsid_key, numericrepresentation_valuename, 0, REG_DWORD,
1029 (const BYTE*)&list->numericrepresentation, 4);
1030 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1032 res = RegSetValueExA(clsid_key, supportstransparency_valuename, 0, REG_DWORD,
1033 (const BYTE*)&list->supportsalpha, 4);
1034 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1036 if (list->channelmasks) {
1037 HKEY masks_key;
1038 UINT i, mask_size;
1039 WCHAR mask_valuename[11];
1040 const WCHAR valuename_format[] = {'%','d',0};
1042 mask_size = (list->bitsperpixel + 7)/8;
1044 res = RegCreateKeyExW(clsid_key, channelmasks_keyname, 0, NULL, 0,
1045 KEY_READ | KEY_WRITE, NULL, &masks_key, NULL);
1046 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1047 for (i=0; i < list->channelcount; i++)
1049 sprintfW(mask_valuename, valuename_format, i);
1050 res = RegSetValueExW(masks_key, mask_valuename, 0, REG_BINARY,
1051 list->channelmasks[i], mask_size);
1052 if (res != ERROR_SUCCESS) break;
1054 RegCloseKey(masks_key);
1055 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1058 error_close_clsid_key:
1059 RegCloseKey(clsid_key);
1062 error_close_coclass_key:
1063 RegCloseKey(instance_key);
1064 RegCloseKey(formats_key);
1065 RegCloseKey(coclass_key);
1066 error_return:
1067 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
1070 /***********************************************************************
1071 * unregister_pixelformats
1073 static HRESULT unregister_pixelformats(struct regsvr_pixelformat const *list)
1075 LONG res = ERROR_SUCCESS;
1076 HKEY coclass_key;
1077 WCHAR buf[39];
1078 HKEY formats_key;
1079 HKEY instance_key;
1081 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
1082 KEY_READ | KEY_WRITE, &coclass_key);
1083 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
1085 if (res == ERROR_SUCCESS) {
1086 StringFromGUID2(&CATID_WICPixelFormats, buf, 39);
1087 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
1088 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
1089 if (res == ERROR_SUCCESS)
1091 res = RegCreateKeyExW(formats_key, instance_keyname, 0, NULL, 0,
1092 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
1093 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1095 if (res != ERROR_SUCCESS)
1096 RegCloseKey(coclass_key);
1098 if (res != ERROR_SUCCESS) goto error_return;
1100 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
1101 StringFromGUID2(list->clsid, buf, 39);
1103 res = RegDeleteTreeW(coclass_key, buf);
1104 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
1105 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1107 res = RegDeleteTreeW(instance_key, buf);
1108 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
1109 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1112 error_close_coclass_key:
1113 RegCloseKey(instance_key);
1114 RegCloseKey(formats_key);
1115 RegCloseKey(coclass_key);
1116 error_return:
1117 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
1120 /***********************************************************************
1121 * decoder list
1123 static const BYTE mask_all[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1125 static const BYTE bmp_magic[] = {0x42,0x4d};
1127 static GUID const * const bmp_formats[] = {
1128 &GUID_WICPixelFormat1bppIndexed,
1129 &GUID_WICPixelFormat2bppIndexed,
1130 &GUID_WICPixelFormat4bppIndexed,
1131 &GUID_WICPixelFormat8bppIndexed,
1132 &GUID_WICPixelFormat16bppBGR555,
1133 &GUID_WICPixelFormat16bppBGR565,
1134 &GUID_WICPixelFormat24bppBGR,
1135 &GUID_WICPixelFormat32bppBGR,
1136 &GUID_WICPixelFormat32bppBGRA,
1137 NULL
1140 static struct decoder_pattern const bmp_patterns[] = {
1141 {2,0,bmp_magic,mask_all,0},
1145 static const BYTE gif87a_magic[6] = "GIF87a";
1146 static const BYTE gif89a_magic[6] = "GIF89a";
1148 static GUID const * const gif_formats[] = {
1149 &GUID_WICPixelFormat8bppIndexed,
1150 NULL
1153 static struct decoder_pattern const gif_patterns[] = {
1154 {6,0,gif87a_magic,mask_all,0},
1155 {6,0,gif89a_magic,mask_all,0},
1159 static const BYTE ico_magic[] = {00,00,01,00};
1161 static GUID const * const ico_formats[] = {
1162 &GUID_WICPixelFormat32bppBGRA,
1163 NULL
1166 static struct decoder_pattern const ico_patterns[] = {
1167 {4,0,ico_magic,mask_all,0},
1171 static const BYTE jpeg_magic[] = {0xff, 0xd8};
1173 static GUID const * const jpeg_formats[] = {
1174 &GUID_WICPixelFormat24bppBGR,
1175 &GUID_WICPixelFormat32bppCMYK,
1176 &GUID_WICPixelFormat8bppGray,
1177 NULL
1180 static struct decoder_pattern const jpeg_patterns[] = {
1181 {2,0,jpeg_magic,mask_all,0},
1185 static const BYTE png_magic[] = {137,80,78,71,13,10,26,10};
1187 static GUID const * const png_formats[] = {
1188 &GUID_WICPixelFormatBlackWhite,
1189 &GUID_WICPixelFormat2bppGray,
1190 &GUID_WICPixelFormat4bppGray,
1191 &GUID_WICPixelFormat8bppGray,
1192 &GUID_WICPixelFormat16bppGray,
1193 &GUID_WICPixelFormat32bppBGRA,
1194 &GUID_WICPixelFormat64bppRGBA,
1195 &GUID_WICPixelFormat1bppIndexed,
1196 &GUID_WICPixelFormat2bppIndexed,
1197 &GUID_WICPixelFormat4bppIndexed,
1198 &GUID_WICPixelFormat8bppIndexed,
1199 &GUID_WICPixelFormat24bppBGR,
1200 &GUID_WICPixelFormat48bppRGB,
1201 NULL
1204 static struct decoder_pattern const png_patterns[] = {
1205 {8,0,png_magic,mask_all,0},
1209 static const BYTE tiff_magic_le[] = {0x49,0x49,42,0};
1210 static const BYTE tiff_magic_be[] = {0x4d,0x4d,0,42};
1212 static GUID const * const tiff_decode_formats[] = {
1213 &GUID_WICPixelFormatBlackWhite,
1214 &GUID_WICPixelFormat4bppGray,
1215 &GUID_WICPixelFormat8bppGray,
1216 &GUID_WICPixelFormat4bppIndexed,
1217 &GUID_WICPixelFormat8bppIndexed,
1218 &GUID_WICPixelFormat24bppBGR,
1219 &GUID_WICPixelFormat32bppBGR,
1220 &GUID_WICPixelFormat32bppBGRA,
1221 &GUID_WICPixelFormat32bppPBGRA,
1222 &GUID_WICPixelFormat48bppRGB,
1223 &GUID_WICPixelFormat64bppRGBA,
1224 &GUID_WICPixelFormat64bppPRGBA,
1225 NULL
1228 static struct decoder_pattern const tiff_patterns[] = {
1229 {4,0,tiff_magic_le,mask_all,0},
1230 {4,0,tiff_magic_be,mask_all,0},
1234 static const BYTE tga_footer_magic[18] = "TRUEVISION-XFILE.";
1236 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};
1237 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};
1239 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};
1240 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};
1242 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};
1243 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};
1245 static GUID const * const tga_formats[] = {
1246 &GUID_WICPixelFormat8bppGray,
1247 &GUID_WICPixelFormat8bppIndexed,
1248 &GUID_WICPixelFormat16bppGray,
1249 &GUID_WICPixelFormat16bppBGR555,
1250 &GUID_WICPixelFormat24bppBGR,
1251 &GUID_WICPixelFormat32bppBGRA,
1252 &GUID_WICPixelFormat32bppPBGRA,
1253 NULL
1256 static struct decoder_pattern const tga_patterns[] = {
1257 {18,18,tga_footer_magic,mask_all,1},
1258 {18,0,tga_indexed_magic,tga_indexed_mask,0},
1259 {18,0,tga_truecolor_magic,tga_truecolor_mask,0},
1260 {18,0,tga_grayscale_magic,tga_grayscale_mask,0},
1264 static struct regsvr_decoder const decoder_list[] = {
1265 { &CLSID_WICBmpDecoder,
1266 "The Wine Project",
1267 "BMP Decoder",
1268 "1.0.0.0",
1269 &GUID_VendorMicrosoft,
1270 &GUID_ContainerFormatBmp,
1271 "image/bmp",
1272 ".bmp,.dib,.rle",
1273 bmp_formats,
1274 bmp_patterns
1276 { &CLSID_WICGifDecoder,
1277 "The Wine Project",
1278 "GIF Decoder",
1279 "1.0.0.0",
1280 &GUID_VendorMicrosoft,
1281 &GUID_ContainerFormatGif,
1282 "image/gif",
1283 ".gif",
1284 gif_formats,
1285 gif_patterns
1287 { &CLSID_WICIcoDecoder,
1288 "The Wine Project",
1289 "ICO Decoder",
1290 "1.0.0.0",
1291 &GUID_VendorMicrosoft,
1292 &GUID_ContainerFormatIco,
1293 "image/vnd.microsoft.icon",
1294 ".ico",
1295 ico_formats,
1296 ico_patterns
1298 { &CLSID_WICJpegDecoder,
1299 "The Wine Project",
1300 "JPEG Decoder",
1301 "1.0.0.0",
1302 &GUID_VendorMicrosoft,
1303 &GUID_ContainerFormatJpeg,
1304 "image/jpeg",
1305 ".jpg;.jpeg;.jfif",
1306 jpeg_formats,
1307 jpeg_patterns
1309 { &CLSID_WICPngDecoder,
1310 "The Wine Project",
1311 "PNG Decoder",
1312 "1.0.0.0",
1313 &GUID_VendorMicrosoft,
1314 &GUID_ContainerFormatPng,
1315 "image/png",
1316 ".png",
1317 png_formats,
1318 png_patterns
1320 { &CLSID_WICTiffDecoder,
1321 "The Wine Project",
1322 "TIFF Decoder",
1323 "1.0.0.0",
1324 &GUID_VendorMicrosoft,
1325 &GUID_ContainerFormatTiff,
1326 "image/tiff",
1327 ".tif;.tiff",
1328 tiff_decode_formats,
1329 tiff_patterns
1331 { &CLSID_WineTgaDecoder,
1332 "The Wine Project",
1333 "TGA Decoder",
1334 "1.0.0.0",
1335 &GUID_VendorWine,
1336 &GUID_WineContainerFormatTga,
1337 "image/x-targa",
1338 ".tga;.tpic",
1339 tga_formats,
1340 tga_patterns
1342 { NULL } /* list terminator */
1345 static GUID const * const bmp_encode_formats[] = {
1346 &GUID_WICPixelFormat16bppBGR555,
1347 &GUID_WICPixelFormat16bppBGR565,
1348 &GUID_WICPixelFormat24bppBGR,
1349 &GUID_WICPixelFormat32bppBGR,
1350 NULL
1353 static GUID const * const png_encode_formats[] = {
1354 &GUID_WICPixelFormat24bppBGR,
1355 &GUID_WICPixelFormatBlackWhite,
1356 &GUID_WICPixelFormat2bppGray,
1357 &GUID_WICPixelFormat4bppGray,
1358 &GUID_WICPixelFormat8bppGray,
1359 &GUID_WICPixelFormat16bppGray,
1360 &GUID_WICPixelFormat32bppBGR,
1361 &GUID_WICPixelFormat32bppBGRA,
1362 &GUID_WICPixelFormat48bppRGB,
1363 &GUID_WICPixelFormat64bppRGBA,
1364 NULL
1367 static GUID const * const tiff_encode_formats[] = {
1368 &GUID_WICPixelFormatBlackWhite,
1369 &GUID_WICPixelFormat4bppGray,
1370 &GUID_WICPixelFormat8bppGray,
1371 &GUID_WICPixelFormat24bppBGR,
1372 &GUID_WICPixelFormat32bppBGRA,
1373 &GUID_WICPixelFormat32bppPBGRA,
1374 &GUID_WICPixelFormat48bppRGB,
1375 &GUID_WICPixelFormat64bppRGBA,
1376 &GUID_WICPixelFormat64bppPRGBA,
1377 NULL
1380 static GUID const * const icns_encode_formats[] = {
1381 &GUID_WICPixelFormat32bppBGRA,
1382 NULL
1385 static struct regsvr_encoder const encoder_list[] = {
1386 { &CLSID_WICBmpEncoder,
1387 "The Wine Project",
1388 "BMP Encoder",
1389 "1.0.0.0",
1390 &GUID_VendorMicrosoft,
1391 &GUID_ContainerFormatBmp,
1392 "image/bmp",
1393 ".bmp,.dib,.rle",
1394 bmp_encode_formats
1396 { &CLSID_WICJpegEncoder,
1397 "The Wine Project",
1398 "JPEG Encoder",
1399 "1.0.0.0",
1400 &GUID_VendorMicrosoft,
1401 &GUID_ContainerFormatJpeg,
1402 "image/jpeg",
1403 ".jpg;.jpeg;.jfif",
1404 jpeg_formats
1406 { &CLSID_WICPngEncoder,
1407 "The Wine Project",
1408 "PNG Encoder",
1409 "1.0.0.0",
1410 &GUID_VendorMicrosoft,
1411 &GUID_ContainerFormatPng,
1412 "image/png",
1413 ".png",
1414 png_encode_formats
1416 { &CLSID_WICTiffEncoder,
1417 "The Wine Project",
1418 "TIFF Encoder",
1419 "1.0.0.0",
1420 &GUID_VendorMicrosoft,
1421 &GUID_ContainerFormatTiff,
1422 "image/tiff",
1423 ".tif;.tiff",
1424 tiff_encode_formats
1426 { &CLSID_WICIcnsEncoder,
1427 "The Wine Project",
1428 "ICNS Encoder",
1429 "1.0.0.0",
1430 &GUID_VendorWine,
1431 NULL, /* no container format guid */
1432 "image/icns",
1433 ".icns",
1434 icns_encode_formats
1436 { NULL } /* list terminator */
1439 static GUID const * const converter_formats[] = {
1440 &GUID_WICPixelFormat1bppIndexed,
1441 &GUID_WICPixelFormat2bppIndexed,
1442 &GUID_WICPixelFormat4bppIndexed,
1443 &GUID_WICPixelFormat8bppIndexed,
1444 &GUID_WICPixelFormatBlackWhite,
1445 &GUID_WICPixelFormat2bppGray,
1446 &GUID_WICPixelFormat4bppGray,
1447 &GUID_WICPixelFormat8bppGray,
1448 &GUID_WICPixelFormat16bppGray,
1449 &GUID_WICPixelFormat16bppBGR555,
1450 &GUID_WICPixelFormat16bppBGR565,
1451 &GUID_WICPixelFormat16bppBGRA5551,
1452 &GUID_WICPixelFormat24bppBGR,
1453 &GUID_WICPixelFormat24bppRGB,
1454 &GUID_WICPixelFormat32bppBGR,
1455 &GUID_WICPixelFormat32bppBGRA,
1456 &GUID_WICPixelFormat32bppPBGRA,
1457 &GUID_WICPixelFormat48bppRGB,
1458 &GUID_WICPixelFormat64bppRGBA,
1459 &GUID_WICPixelFormat32bppCMYK,
1460 NULL
1463 static struct regsvr_converter const converter_list[] = {
1464 { &CLSID_WICDefaultFormatConverter,
1465 "The Wine Project",
1466 "Default Pixel Format Converter",
1467 "1.0.0.0",
1468 &GUID_VendorMicrosoft,
1469 converter_formats
1471 { NULL } /* list terminator */
1474 static const BYTE no_magic[1] = { 0 };
1475 static const BYTE no_mask[1] = { 0 };
1477 static const struct metadata_pattern ifd_metadata_pattern[] = {
1478 { 0, 1, no_magic, no_mask, 0 },
1479 { 0 }
1482 static const struct reader_containers ifd_containers[] = {
1484 &GUID_ContainerFormatTiff,
1485 ifd_metadata_pattern
1487 { NULL } /* list terminator */
1490 static const BYTE tEXt[] = "tEXt";
1492 static const struct metadata_pattern pngtext_metadata_pattern[] = {
1493 { 4, 4, tEXt, mask_all, 4 },
1494 { 0 }
1497 static const struct reader_containers pngtext_containers[] = {
1499 &GUID_ContainerFormatPng,
1500 pngtext_metadata_pattern
1502 { NULL } /* list terminator */
1505 static const BYTE gAMA[] = "gAMA";
1507 static const struct metadata_pattern pnggama_metadata_pattern[] = {
1508 { 4, 4, gAMA, mask_all, 4 },
1509 { 0 }
1512 static const struct reader_containers pnggama_containers[] = {
1514 &GUID_ContainerFormatPng,
1515 pnggama_metadata_pattern
1517 { NULL } /* list terminator */
1520 static const struct metadata_pattern lsd_metadata_patterns[] = {
1521 { 0, 6, gif87a_magic, mask_all, 0 },
1522 { 0, 6, gif89a_magic, mask_all, 0 },
1523 { 0 }
1526 static const struct reader_containers lsd_containers[] = {
1528 &GUID_ContainerFormatGif,
1529 lsd_metadata_patterns
1531 { NULL } /* list terminator */
1534 static const BYTE imd_magic[] = { 0x2c };
1536 static const struct metadata_pattern imd_metadata_pattern[] = {
1537 { 0, 1, imd_magic, mask_all, 1 },
1538 { 0 }
1541 static const struct reader_containers imd_containers[] = {
1543 &GUID_ContainerFormatGif,
1544 imd_metadata_pattern
1546 { NULL } /* list terminator */
1549 static const BYTE gce_magic[] = { 0x21, 0xf9, 0x04 };
1551 static const struct metadata_pattern gce_metadata_pattern[] = {
1552 { 0, 3, gce_magic, mask_all, 3 },
1553 { 0 }
1556 static const struct reader_containers gce_containers[] = {
1558 &GUID_ContainerFormatGif,
1559 gce_metadata_pattern
1561 { NULL } /* list terminator */
1564 static const BYTE ape_magic[] = { 0x21, 0xff, 0x0b };
1566 static const struct metadata_pattern ape_metadata_pattern[] = {
1567 { 0, 3, ape_magic, mask_all, 0 },
1568 { 0 }
1571 static const struct reader_containers ape_containers[] = {
1573 &GUID_ContainerFormatGif,
1574 ape_metadata_pattern
1576 { NULL } /* list terminator */
1579 static const BYTE gif_comment_magic[] = { 0x21, 0xfe };
1581 static const struct metadata_pattern gif_comment_metadata_pattern[] = {
1582 { 0, 2, gif_comment_magic, mask_all, 0 },
1583 { 0 }
1586 static const struct reader_containers gif_comment_containers[] = {
1588 &GUID_ContainerFormatGif,
1589 gif_comment_metadata_pattern
1591 { NULL } /* list terminator */
1594 static struct regsvr_metadatareader const metadatareader_list[] = {
1595 { &CLSID_WICUnknownMetadataReader,
1596 "The Wine Project",
1597 "Unknown Metadata Reader",
1598 "1.0.0.0",
1599 "1.0.0.0",
1600 &GUID_VendorMicrosoft,
1601 &GUID_MetadataFormatUnknown,
1602 0, 0, 0,
1603 NULL
1605 { &CLSID_WICIfdMetadataReader,
1606 "The Wine Project",
1607 "Ifd Reader",
1608 "1.0.0.0",
1609 "1.0.0.0",
1610 &GUID_VendorMicrosoft,
1611 &GUID_MetadataFormatIfd,
1612 1, 1, 0,
1613 ifd_containers
1615 { &CLSID_WICPngGamaMetadataReader,
1616 "The Wine Project",
1617 "Chunk gAMA Reader",
1618 "1.0.0.0",
1619 "1.0.0.0",
1620 &GUID_VendorMicrosoft,
1621 &GUID_MetadataFormatChunkgAMA,
1622 0, 0, 0,
1623 pnggama_containers
1625 { &CLSID_WICPngTextMetadataReader,
1626 "The Wine Project",
1627 "Chunk tEXt Reader",
1628 "1.0.0.0",
1629 "1.0.0.0",
1630 &GUID_VendorMicrosoft,
1631 &GUID_MetadataFormatChunktEXt,
1632 0, 0, 0,
1633 pngtext_containers
1635 { &CLSID_WICLSDMetadataReader,
1636 "The Wine Project",
1637 "Logical Screen Descriptor Reader",
1638 "1.0.0.0",
1639 "1.0.0.0",
1640 &GUID_VendorMicrosoft,
1641 &GUID_MetadataFormatLSD,
1642 0, 0, 0,
1643 lsd_containers
1645 { &CLSID_WICIMDMetadataReader,
1646 "The Wine Project",
1647 "Image Descriptor Reader",
1648 "1.0.0.0",
1649 "1.0.0.0",
1650 &GUID_VendorMicrosoft,
1651 &GUID_MetadataFormatIMD,
1652 0, 0, 0,
1653 imd_containers
1655 { &CLSID_WICGCEMetadataReader,
1656 "The Wine Project",
1657 "Graphic Control Extension Reader",
1658 "1.0.0.0",
1659 "1.0.0.0",
1660 &GUID_VendorMicrosoft,
1661 &GUID_MetadataFormatGCE,
1662 0, 0, 0,
1663 gce_containers
1665 { &CLSID_WICAPEMetadataReader,
1666 "The Wine Project",
1667 "Application Extension Reader",
1668 "1.0.0.0",
1669 "1.0.0.0",
1670 &GUID_VendorMicrosoft,
1671 &GUID_MetadataFormatAPE,
1672 0, 0, 0,
1673 ape_containers
1675 { &CLSID_WICGifCommentMetadataReader,
1676 "The Wine Project",
1677 "Comment Extension Reader",
1678 "1.0.0.0",
1679 "1.0.0.0",
1680 &GUID_VendorMicrosoft,
1681 &GUID_MetadataFormatGifComment,
1682 0, 0, 0,
1683 gif_comment_containers
1685 { NULL } /* list terminator */
1688 static BYTE const channel_mask_1bit[] = { 0x01 };
1689 static BYTE const channel_mask_2bit[] = { 0x03 };
1690 static BYTE const channel_mask_4bit[] = { 0x0f };
1692 static BYTE const channel_mask_8bit[] = { 0xff, 0x00, 0x00, 0x00 };
1693 static BYTE const channel_mask_8bit2[] = { 0x00, 0xff, 0x00, 0x00 };
1694 static BYTE const channel_mask_8bit3[] = { 0x00, 0x00, 0xff, 0x00 };
1695 static BYTE const channel_mask_8bit4[] = { 0x00, 0x00, 0x00, 0xff };
1697 static BYTE const channel_mask_16bit[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1698 static BYTE const channel_mask_16bit2[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1699 static BYTE const channel_mask_16bit3[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
1700 static BYTE const channel_mask_16bit4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
1702 static BYTE const channel_mask_5bit[] = { 0x1f, 0x00 };
1703 static BYTE const channel_mask_5bit2[] = { 0xe0, 0x03 };
1704 static BYTE const channel_mask_5bit3[] = { 0x00, 0x7c };
1705 static BYTE const channel_mask_5bit4[] = { 0x00, 0x80 };
1707 static BYTE const channel_mask_BGR565_2[] = { 0xe0, 0x07 };
1708 static BYTE const channel_mask_BGR565_3[] = { 0x00, 0xf8 };
1710 static BYTE const * const channel_masks_1bit[] = { channel_mask_1bit };
1711 static BYTE const * const channel_masks_2bit[] = { channel_mask_2bit };
1712 static BYTE const * const channel_masks_4bit[] = { channel_mask_4bit };
1713 static BYTE const * const channel_masks_8bit[] = { channel_mask_8bit,
1714 channel_mask_8bit2, channel_mask_8bit3, channel_mask_8bit4 };
1715 static BYTE const * const channel_masks_16bit[] = { channel_mask_16bit,
1716 channel_mask_16bit2, channel_mask_16bit3, channel_mask_16bit4};
1718 static BYTE const * const channel_masks_BGRA5551[] = { channel_mask_5bit,
1719 channel_mask_5bit2, channel_mask_5bit3, channel_mask_5bit4 };
1721 static BYTE const * const channel_masks_BGR565[] = { channel_mask_5bit,
1722 channel_mask_BGR565_2, channel_mask_BGR565_3 };
1724 static struct regsvr_pixelformat const pixelformat_list[] = {
1725 { &GUID_WICPixelFormat1bppIndexed,
1726 "The Wine Project",
1727 "1bpp Indexed",
1728 NULL, /* no version */
1729 &GUID_VendorMicrosoft,
1730 1, /* bitsperpixel */
1731 1, /* channel count */
1732 channel_masks_1bit,
1733 WICPixelFormatNumericRepresentationIndexed,
1736 { &GUID_WICPixelFormat2bppIndexed,
1737 "The Wine Project",
1738 "2bpp Indexed",
1739 NULL, /* no version */
1740 &GUID_VendorMicrosoft,
1741 2, /* bitsperpixel */
1742 1, /* channel count */
1743 channel_masks_2bit,
1744 WICPixelFormatNumericRepresentationIndexed,
1747 { &GUID_WICPixelFormat4bppIndexed,
1748 "The Wine Project",
1749 "4bpp Indexed",
1750 NULL, /* no version */
1751 &GUID_VendorMicrosoft,
1752 4, /* bitsperpixel */
1753 1, /* channel count */
1754 channel_masks_4bit,
1755 WICPixelFormatNumericRepresentationIndexed,
1758 { &GUID_WICPixelFormat8bppIndexed,
1759 "The Wine Project",
1760 "8bpp Indexed",
1761 NULL, /* no version */
1762 &GUID_VendorMicrosoft,
1763 8, /* bitsperpixel */
1764 1, /* channel count */
1765 channel_masks_8bit,
1766 WICPixelFormatNumericRepresentationIndexed,
1769 { &GUID_WICPixelFormatBlackWhite,
1770 "The Wine Project",
1771 "Black and White",
1772 NULL, /* no version */
1773 &GUID_VendorMicrosoft,
1774 1, /* bitsperpixel */
1775 1, /* channel count */
1776 channel_masks_1bit,
1777 WICPixelFormatNumericRepresentationUnsignedInteger,
1780 { &GUID_WICPixelFormat2bppGray,
1781 "The Wine Project",
1782 "2bpp Grayscale",
1783 NULL, /* no version */
1784 &GUID_VendorMicrosoft,
1785 2, /* bitsperpixel */
1786 1, /* channel count */
1787 channel_masks_2bit,
1788 WICPixelFormatNumericRepresentationUnsignedInteger,
1791 { &GUID_WICPixelFormat4bppGray,
1792 "The Wine Project",
1793 "4bpp Grayscale",
1794 NULL, /* no version */
1795 &GUID_VendorMicrosoft,
1796 4, /* bitsperpixel */
1797 1, /* channel count */
1798 channel_masks_4bit,
1799 WICPixelFormatNumericRepresentationUnsignedInteger,
1802 { &GUID_WICPixelFormat8bppGray,
1803 "The Wine Project",
1804 "8bpp Grayscale",
1805 NULL, /* no version */
1806 &GUID_VendorMicrosoft,
1807 8, /* bitsperpixel */
1808 1, /* channel count */
1809 channel_masks_8bit,
1810 WICPixelFormatNumericRepresentationUnsignedInteger,
1813 { &GUID_WICPixelFormat16bppGray,
1814 "The Wine Project",
1815 "16bpp Grayscale",
1816 NULL, /* no version */
1817 &GUID_VendorMicrosoft,
1818 16, /* bitsperpixel */
1819 1, /* channel count */
1820 channel_masks_16bit,
1821 WICPixelFormatNumericRepresentationUnsignedInteger,
1824 { &GUID_WICPixelFormat16bppBGR555,
1825 "The Wine Project",
1826 "16bpp BGR555",
1827 NULL, /* no version */
1828 &GUID_VendorMicrosoft,
1829 16, /* bitsperpixel */
1830 3, /* channel count */
1831 channel_masks_BGRA5551,
1832 WICPixelFormatNumericRepresentationUnsignedInteger,
1835 { &GUID_WICPixelFormat16bppBGR565,
1836 "The Wine Project",
1837 "16bpp BGR565",
1838 NULL, /* no version */
1839 &GUID_VendorMicrosoft,
1840 16, /* bitsperpixel */
1841 3, /* channel count */
1842 channel_masks_BGR565,
1843 WICPixelFormatNumericRepresentationUnsignedInteger,
1846 { &GUID_WICPixelFormat16bppBGRA5551,
1847 "The Wine Project",
1848 "16bpp BGRA5551",
1849 NULL, /* no version */
1850 &GUID_VendorMicrosoft,
1851 16, /* bitsperpixel */
1852 4, /* channel count */
1853 channel_masks_BGRA5551,
1854 WICPixelFormatNumericRepresentationUnsignedInteger,
1857 { &GUID_WICPixelFormat24bppBGR,
1858 "The Wine Project",
1859 "24bpp BGR",
1860 NULL, /* no version */
1861 &GUID_VendorMicrosoft,
1862 24, /* bitsperpixel */
1863 3, /* channel count */
1864 channel_masks_8bit,
1865 WICPixelFormatNumericRepresentationUnsignedInteger,
1868 { &GUID_WICPixelFormat24bppRGB,
1869 "The Wine Project",
1870 "24bpp RGB",
1871 NULL, /* no version */
1872 &GUID_VendorMicrosoft,
1873 24, /* bitsperpixel */
1874 3, /* channel count */
1875 channel_masks_8bit,
1876 WICPixelFormatNumericRepresentationUnsignedInteger,
1879 { &GUID_WICPixelFormat32bppBGR,
1880 "The Wine Project",
1881 "32bpp BGR",
1882 NULL, /* no version */
1883 &GUID_VendorMicrosoft,
1884 32, /* bitsperpixel */
1885 3, /* channel count */
1886 channel_masks_8bit,
1887 WICPixelFormatNumericRepresentationUnsignedInteger,
1890 { &GUID_WICPixelFormat32bppBGRA,
1891 "The Wine Project",
1892 "32bpp BGRA",
1893 NULL, /* no version */
1894 &GUID_VendorMicrosoft,
1895 32, /* bitsperpixel */
1896 4, /* channel count */
1897 channel_masks_8bit,
1898 WICPixelFormatNumericRepresentationUnsignedInteger,
1901 { &GUID_WICPixelFormat32bppPBGRA,
1902 "The Wine Project",
1903 "32bpp PBGRA",
1904 NULL, /* no version */
1905 &GUID_VendorMicrosoft,
1906 32, /* bitsperpixel */
1907 4, /* channel count */
1908 channel_masks_8bit,
1909 WICPixelFormatNumericRepresentationUnsignedInteger,
1912 { &GUID_WICPixelFormat48bppRGB,
1913 "The Wine Project",
1914 "48bpp RGB",
1915 NULL, /* no version */
1916 &GUID_VendorMicrosoft,
1917 48, /* bitsperpixel */
1918 3, /* channel count */
1919 channel_masks_16bit,
1920 WICPixelFormatNumericRepresentationUnsignedInteger,
1923 { &GUID_WICPixelFormat64bppRGBA,
1924 "The Wine Project",
1925 "64bpp RGBA",
1926 NULL, /* no version */
1927 &GUID_VendorMicrosoft,
1928 64, /* bitsperpixel */
1929 4, /* channel count */
1930 channel_masks_16bit,
1931 WICPixelFormatNumericRepresentationUnsignedInteger,
1934 { &GUID_WICPixelFormat64bppPRGBA,
1935 "The Wine Project",
1936 "64bpp PRGBA",
1937 NULL, /* no version */
1938 &GUID_VendorMicrosoft,
1939 64, /* bitsperpixel */
1940 4, /* channel count */
1941 channel_masks_16bit,
1942 WICPixelFormatNumericRepresentationUnsignedInteger,
1945 { &GUID_WICPixelFormat32bppCMYK,
1946 "The Wine Project",
1947 "32bpp CMYK",
1948 NULL, /* no version */
1949 &GUID_VendorMicrosoft,
1950 32, /* bitsperpixel */
1951 4, /* channel count */
1952 channel_masks_8bit,
1953 WICPixelFormatNumericRepresentationUnsignedInteger,
1956 { NULL } /* list terminator */
1959 struct regsvr_category
1961 const CLSID *clsid; /* NULL for end of list */
1964 static const struct regsvr_category category_list[] = {
1965 { &CATID_WICBitmapDecoders },
1966 { &CATID_WICBitmapEncoders },
1967 { &CATID_WICFormatConverters },
1968 { &CATID_WICMetadataReader },
1969 { &CATID_WICPixelFormats },
1970 { NULL }
1973 static HRESULT register_categories(const struct regsvr_category *list)
1975 LONG res;
1976 WCHAR buf[39];
1977 HKEY coclass_key, categories_key, instance_key;
1979 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
1980 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
1981 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
1983 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
1984 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
1985 KEY_READ | KEY_WRITE, NULL, &categories_key, NULL);
1986 if (res != ERROR_SUCCESS)
1988 RegCloseKey(coclass_key);
1989 return HRESULT_FROM_WIN32(res);
1992 res = RegCreateKeyExW(categories_key, instance_keyname, 0, NULL, 0,
1993 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
1995 for (; res == ERROR_SUCCESS && list->clsid; list++)
1997 HKEY instance_clsid_key;
1999 StringFromGUID2(list->clsid, buf, 39);
2000 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
2001 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
2002 if (res == ERROR_SUCCESS)
2004 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
2005 (const BYTE *)buf, 78);
2006 RegCloseKey(instance_clsid_key);
2010 RegCloseKey(instance_key);
2011 RegCloseKey(categories_key);
2012 RegCloseKey(coclass_key);
2014 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
2017 static HRESULT unregister_categories(const struct regsvr_category *list)
2019 LONG res;
2020 WCHAR buf[39];
2021 HKEY coclass_key, categories_key, instance_key;
2023 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
2024 KEY_READ | KEY_WRITE, &coclass_key);
2025 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
2027 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
2028 res = RegOpenKeyExW(coclass_key, buf, 0,
2029 KEY_READ | KEY_WRITE, &categories_key);
2030 if (res != ERROR_SUCCESS)
2032 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
2033 RegCloseKey(coclass_key);
2034 return HRESULT_FROM_WIN32(res);
2037 res = RegOpenKeyExW(categories_key, instance_keyname, 0,
2038 KEY_READ | KEY_WRITE, &instance_key);
2040 for (; res == ERROR_SUCCESS && list->clsid; list++)
2042 StringFromGUID2(list->clsid, buf, 39);
2043 res = RegDeleteTreeW(instance_key, buf);
2046 RegCloseKey(instance_key);
2047 RegCloseKey(categories_key);
2049 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
2050 res = RegDeleteTreeW(coclass_key, buf);
2052 RegCloseKey(coclass_key);
2054 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
2057 extern HRESULT WINAPI WIC_DllRegisterServer(void) DECLSPEC_HIDDEN;
2058 extern HRESULT WINAPI WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN;
2060 HRESULT WINAPI DllRegisterServer(void)
2062 HRESULT hr;
2064 TRACE("\n");
2066 hr = WIC_DllRegisterServer();
2067 if (SUCCEEDED(hr))
2068 hr = register_categories(category_list);
2069 if (SUCCEEDED(hr))
2070 hr = register_decoders(decoder_list);
2071 if (SUCCEEDED(hr))
2072 hr = register_encoders(encoder_list);
2073 if (SUCCEEDED(hr))
2074 hr = register_converters(converter_list);
2075 if (SUCCEEDED(hr))
2076 hr = register_metadatareaders(metadatareader_list);
2077 if (SUCCEEDED(hr))
2078 hr = register_pixelformats(pixelformat_list);
2079 return hr;
2082 HRESULT WINAPI DllUnregisterServer(void)
2084 HRESULT hr;
2086 TRACE("\n");
2088 hr = WIC_DllUnregisterServer();
2089 if (SUCCEEDED(hr))
2090 hr = unregister_categories(category_list);
2091 if (SUCCEEDED(hr))
2092 hr = unregister_decoders(decoder_list);
2093 if (SUCCEEDED(hr))
2094 hr = unregister_encoders(encoder_list);
2095 if (SUCCEEDED(hr))
2096 hr = unregister_converters(converter_list);
2097 if (SUCCEEDED(hr))
2098 hr = unregister_metadatareaders(metadatareader_list);
2099 if (SUCCEEDED(hr))
2100 hr = unregister_pixelformats(pixelformat_list);
2101 return hr;