wined3d: Don't normalize R8G8B8A8_UINT attributes.
[wine/multimedia.git] / dlls / windowscodecs / regsvr.c
blob91df294572fcacdb781cf7ca62fd86e33f5334c4
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 NONAMELESSUNION
20 #define NONAMELESSSTRUCT
21 #define COBJMACROS
22 #include <stdarg.h>
23 #include <string.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "winreg.h"
30 #include "winerror.h"
32 #include "objbase.h"
33 #include "ocidl.h"
34 #include "wincodec.h"
35 #include "wincodecsdk.h"
37 #include "wine/debug.h"
38 #include "wine/unicode.h"
40 #include "wincodecs_private.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
44 /***********************************************************************
45 * interface for self-registering
47 struct decoder_pattern
49 DWORD length; /* 0 for end of list */
50 DWORD position;
51 const BYTE *pattern;
52 const BYTE *mask;
53 DWORD endofstream;
56 struct regsvr_decoder
58 CLSID const *clsid; /* NULL for end of list */
59 LPCSTR author;
60 LPCSTR friendlyname;
61 LPCSTR version;
62 GUID const *vendor;
63 GUID const *container_format;
64 LPCSTR mimetypes;
65 LPCSTR extensions;
66 GUID const * const *formats;
67 const struct decoder_pattern *patterns;
70 static HRESULT register_decoders(struct regsvr_decoder const *list);
71 static HRESULT unregister_decoders(struct regsvr_decoder const *list);
73 struct regsvr_encoder
75 CLSID const *clsid; /* NULL for end of list */
76 LPCSTR author;
77 LPCSTR friendlyname;
78 LPCSTR version;
79 GUID const *vendor;
80 GUID const *container_format;
81 LPCSTR mimetypes;
82 LPCSTR extensions;
83 GUID const * const *formats;
86 static HRESULT register_encoders(struct regsvr_encoder const *list);
87 static HRESULT unregister_encoders(struct regsvr_encoder const *list);
89 struct regsvr_converter
91 CLSID const *clsid; /* NULL for end of list */
92 LPCSTR author;
93 LPCSTR friendlyname;
94 LPCSTR version;
95 GUID const *vendor;
96 GUID const * const *formats;
99 static HRESULT register_converters(struct regsvr_converter const *list);
100 static HRESULT unregister_converters(struct regsvr_converter const *list);
102 struct metadata_pattern
104 DWORD position;
105 DWORD length;
106 const BYTE *pattern;
107 const BYTE *mask;
108 DWORD data_offset;
111 struct reader_containers
113 GUID const *format;
114 const struct metadata_pattern *patterns;
117 struct regsvr_metadatareader
119 CLSID const *clsid; /* NULL for end of list */
120 LPCSTR author;
121 LPCSTR friendlyname;
122 LPCSTR version;
123 LPCSTR specversion;
124 GUID const *vendor;
125 GUID const *metadata_format;
126 DWORD requires_fullstream;
127 DWORD supports_padding;
128 DWORD requires_fixedsize;
129 const struct reader_containers *containers;
132 static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list);
133 static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list);
135 struct regsvr_pixelformat
137 CLSID const *clsid; /* NULL for end of list */
138 LPCSTR author;
139 LPCSTR friendlyname;
140 LPCSTR version;
141 GUID const *vendor;
142 UINT bitsperpixel;
143 UINT channelcount;
144 BYTE const * const *channelmasks;
145 WICPixelFormatNumericRepresentation numericrepresentation;
146 UINT supportsalpha;
149 static HRESULT register_pixelformats(struct regsvr_pixelformat const *list);
150 static HRESULT unregister_pixelformats(struct regsvr_pixelformat const *list);
152 /***********************************************************************
153 * static string constants
155 static const WCHAR clsid_keyname[] = {
156 'C', 'L', 'S', 'I', 'D', 0 };
157 static const char author_valuename[] = "Author";
158 static const char friendlyname_valuename[] = "FriendlyName";
159 static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0};
160 static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
161 static const char version_valuename[] = "Version";
162 static const char mimetypes_valuename[] = "MimeTypes";
163 static const char extensions_valuename[] = "FileExtensions";
164 static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0};
165 static const WCHAR patterns_keyname[] = {'P','a','t','t','e','r','n','s',0};
166 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
167 static const WCHAR clsid_valuename[] = {'C','L','S','I','D',0};
168 static const char length_valuename[] = "Length";
169 static const char position_valuename[] = "Position";
170 static const char pattern_valuename[] = "Pattern";
171 static const char mask_valuename[] = "Mask";
172 static const char endofstream_valuename[] = "EndOfStream";
173 static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
174 static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
175 static const char specversion_valuename[] = "SpecVersion";
176 static const char requiresfullstream_valuename[] = "RequiresFullStream";
177 static const char supportspadding_valuename[] = "SupportsPadding";
178 static const char requiresfixedsize_valuename[] = "FixedSize";
179 static const WCHAR containers_keyname[] = {'C','o','n','t','a','i','n','e','r','s',0};
180 static const char dataoffset_valuename[] = "DataOffset";
181 static const char bitsperpixel_valuename[] = "BitLength";
182 static const char channelcount_valuename[] = "ChannelCount";
183 static const char numericrepresentation_valuename[] = "NumericRepresentation";
184 static const char supportstransparency_valuename[] = "SupportsTransparency";
185 static const WCHAR channelmasks_keyname[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
187 /***********************************************************************
188 * register_decoders
190 static HRESULT register_decoders(struct regsvr_decoder const *list)
192 LONG res = ERROR_SUCCESS;
193 HKEY coclass_key;
194 WCHAR buf[39];
195 HKEY decoders_key;
196 HKEY instance_key;
198 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
199 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
200 if (res == ERROR_SUCCESS) {
201 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
202 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
203 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
204 if (res == ERROR_SUCCESS)
206 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
207 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
208 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
210 if (res != ERROR_SUCCESS)
211 RegCloseKey(coclass_key);
213 if (res != ERROR_SUCCESS) goto error_return;
215 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
216 HKEY clsid_key;
217 HKEY instance_clsid_key;
219 StringFromGUID2(list->clsid, buf, 39);
220 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
221 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
222 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
224 StringFromGUID2(list->clsid, buf, 39);
225 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
226 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
227 if (res == ERROR_SUCCESS) {
228 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
229 (const BYTE*)buf, 78);
230 RegCloseKey(instance_clsid_key);
232 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
234 if (list->author) {
235 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
236 (const BYTE*)list->author,
237 strlen(list->author) + 1);
238 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
241 if (list->friendlyname) {
242 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
243 (const BYTE*)list->friendlyname,
244 strlen(list->friendlyname) + 1);
245 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
248 if (list->vendor) {
249 StringFromGUID2(list->vendor, buf, 39);
250 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
251 (const BYTE*)buf, 78);
252 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
255 if (list->container_format) {
256 StringFromGUID2(list->container_format, buf, 39);
257 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ,
258 (const BYTE*)buf, 78);
259 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
262 if (list->version) {
263 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
264 (const BYTE*)list->version,
265 strlen(list->version) + 1);
266 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
269 if (list->mimetypes) {
270 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ,
271 (const BYTE*)list->mimetypes,
272 strlen(list->mimetypes) + 1);
273 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
276 if (list->extensions) {
277 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ,
278 (const BYTE*)list->extensions,
279 strlen(list->extensions) + 1);
280 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
283 if (list->formats) {
284 HKEY formats_key;
285 GUID const * const *format;
287 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0,
288 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
289 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
290 for (format=list->formats; *format; ++format)
292 HKEY format_key;
293 StringFromGUID2(*format, buf, 39);
294 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
295 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
296 if (res != ERROR_SUCCESS) break;
297 RegCloseKey(format_key);
299 RegCloseKey(formats_key);
300 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
303 if (list->patterns) {
304 HKEY patterns_key;
305 int i;
307 res = RegCreateKeyExW(clsid_key, patterns_keyname, 0, NULL, 0,
308 KEY_READ | KEY_WRITE, NULL, &patterns_key, NULL);
309 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
310 for (i=0; list->patterns[i].length; i++)
312 HKEY pattern_key;
313 static const WCHAR int_format[] = {'%','i',0};
314 snprintfW(buf, 39, int_format, i);
315 res = RegCreateKeyExW(patterns_key, buf, 0, NULL, 0,
316 KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL);
317 if (res != ERROR_SUCCESS) break;
318 res = RegSetValueExA(pattern_key, length_valuename, 0, REG_DWORD,
319 (const BYTE*)&list->patterns[i].length, 4);
320 if (res == ERROR_SUCCESS)
321 res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD,
322 (const BYTE*)&list->patterns[i].position, 4);
323 if (res == ERROR_SUCCESS)
324 res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY,
325 list->patterns[i].pattern,
326 list->patterns[i].length);
327 if (res == ERROR_SUCCESS)
328 res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY,
329 list->patterns[i].mask,
330 list->patterns[i].length);
331 if (res == ERROR_SUCCESS)
332 res = RegSetValueExA(pattern_key, endofstream_valuename, 0, REG_DWORD,
333 (const BYTE*)&list->patterns[i].endofstream, 4);
334 RegCloseKey(pattern_key);
336 RegCloseKey(patterns_key);
337 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
340 error_close_clsid_key:
341 RegCloseKey(clsid_key);
344 error_close_coclass_key:
345 RegCloseKey(instance_key);
346 RegCloseKey(decoders_key);
347 RegCloseKey(coclass_key);
348 error_return:
349 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
352 /***********************************************************************
353 * unregister_decoders
355 static HRESULT unregister_decoders(struct regsvr_decoder const *list)
357 LONG res = ERROR_SUCCESS;
358 HKEY coclass_key;
359 WCHAR buf[39];
360 HKEY decoders_key;
361 HKEY instance_key;
363 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
364 KEY_READ | KEY_WRITE, &coclass_key);
365 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
367 if (res == ERROR_SUCCESS) {
368 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
369 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
370 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
371 if (res == ERROR_SUCCESS)
373 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
374 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
375 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
377 if (res != ERROR_SUCCESS)
378 RegCloseKey(coclass_key);
380 if (res != ERROR_SUCCESS) goto error_return;
382 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
383 StringFromGUID2(list->clsid, buf, 39);
385 res = RegDeleteTreeW(coclass_key, buf);
386 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
387 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
389 res = RegDeleteTreeW(instance_key, buf);
390 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
391 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
394 error_close_coclass_key:
395 RegCloseKey(instance_key);
396 RegCloseKey(decoders_key);
397 RegCloseKey(coclass_key);
398 error_return:
399 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
402 /***********************************************************************
403 * register_encoders
405 static HRESULT register_encoders(struct regsvr_encoder const *list)
407 LONG res = ERROR_SUCCESS;
408 HKEY coclass_key;
409 WCHAR buf[39];
410 HKEY encoders_key;
411 HKEY instance_key;
413 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
414 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
415 if (res == ERROR_SUCCESS) {
416 StringFromGUID2(&CATID_WICBitmapEncoders, buf, 39);
417 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
418 KEY_READ | KEY_WRITE, NULL, &encoders_key, NULL);
419 if (res == ERROR_SUCCESS)
421 res = RegCreateKeyExW(encoders_key, instance_keyname, 0, NULL, 0,
422 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
423 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
425 if (res != ERROR_SUCCESS)
426 RegCloseKey(coclass_key);
428 if (res != ERROR_SUCCESS) goto error_return;
430 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
431 HKEY clsid_key;
432 HKEY instance_clsid_key;
434 StringFromGUID2(list->clsid, buf, 39);
435 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
436 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
437 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
439 StringFromGUID2(list->clsid, buf, 39);
440 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
441 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
442 if (res == ERROR_SUCCESS) {
443 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
444 (const BYTE*)buf, 78);
445 RegCloseKey(instance_clsid_key);
447 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
449 if (list->author) {
450 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
451 (const BYTE*)list->author,
452 strlen(list->author) + 1);
453 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
456 if (list->friendlyname) {
457 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
458 (const BYTE*)list->friendlyname,
459 strlen(list->friendlyname) + 1);
460 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
463 if (list->vendor) {
464 StringFromGUID2(list->vendor, buf, 39);
465 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
466 (const BYTE*)buf, 78);
467 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
470 if (list->container_format) {
471 StringFromGUID2(list->container_format, buf, 39);
472 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ,
473 (const BYTE*)buf, 78);
474 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
477 if (list->version) {
478 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
479 (const BYTE*)list->version,
480 strlen(list->version) + 1);
481 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
484 if (list->mimetypes) {
485 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ,
486 (const BYTE*)list->mimetypes,
487 strlen(list->mimetypes) + 1);
488 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
491 if (list->extensions) {
492 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ,
493 (const BYTE*)list->extensions,
494 strlen(list->extensions) + 1);
495 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
498 if (list->formats) {
499 HKEY formats_key;
500 GUID const * const *format;
502 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0,
503 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
504 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
505 for (format=list->formats; *format; ++format)
507 HKEY format_key;
508 StringFromGUID2(*format, buf, 39);
509 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
510 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
511 if (res != ERROR_SUCCESS) break;
512 RegCloseKey(format_key);
514 RegCloseKey(formats_key);
515 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
518 error_close_clsid_key:
519 RegCloseKey(clsid_key);
522 error_close_coclass_key:
523 RegCloseKey(instance_key);
524 RegCloseKey(encoders_key);
525 RegCloseKey(coclass_key);
526 error_return:
527 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
530 /***********************************************************************
531 * unregister_encoders
533 static HRESULT unregister_encoders(struct regsvr_encoder const *list)
535 LONG res = ERROR_SUCCESS;
536 HKEY coclass_key;
537 WCHAR buf[39];
538 HKEY encoders_key;
539 HKEY instance_key;
541 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
542 KEY_READ | KEY_WRITE, &coclass_key);
543 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
545 if (res == ERROR_SUCCESS) {
546 StringFromGUID2(&CATID_WICBitmapEncoders, buf, 39);
547 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
548 KEY_READ | KEY_WRITE, NULL, &encoders_key, NULL);
549 if (res == ERROR_SUCCESS)
551 res = RegCreateKeyExW(encoders_key, instance_keyname, 0, NULL, 0,
552 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
553 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
555 if (res != ERROR_SUCCESS)
556 RegCloseKey(coclass_key);
558 if (res != ERROR_SUCCESS) goto error_return;
560 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
561 StringFromGUID2(list->clsid, buf, 39);
563 res = RegDeleteTreeW(coclass_key, buf);
564 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
565 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
567 res = RegDeleteTreeW(instance_key, buf);
568 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
569 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
572 error_close_coclass_key:
573 RegCloseKey(instance_key);
574 RegCloseKey(encoders_key);
575 RegCloseKey(coclass_key);
576 error_return:
577 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
580 /***********************************************************************
581 * register_converters
583 static HRESULT register_converters(struct regsvr_converter const *list)
585 LONG res = ERROR_SUCCESS;
586 HKEY coclass_key;
587 WCHAR buf[39];
588 HKEY converters_key;
589 HKEY instance_key;
591 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
592 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
593 if (res == ERROR_SUCCESS) {
594 StringFromGUID2(&CATID_WICFormatConverters, buf, 39);
595 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
596 KEY_READ | KEY_WRITE, NULL, &converters_key, NULL);
597 if (res == ERROR_SUCCESS)
599 res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0,
600 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
601 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
603 if (res != ERROR_SUCCESS)
604 RegCloseKey(coclass_key);
606 if (res != ERROR_SUCCESS) goto error_return;
608 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
609 HKEY clsid_key;
610 HKEY instance_clsid_key;
612 StringFromGUID2(list->clsid, buf, 39);
613 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
614 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
615 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
617 StringFromGUID2(list->clsid, buf, 39);
618 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
619 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
620 if (res == ERROR_SUCCESS) {
621 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
622 (const BYTE*)buf, 78);
623 RegCloseKey(instance_clsid_key);
625 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
627 if (list->author) {
628 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
629 (const BYTE*)list->author,
630 strlen(list->author) + 1);
631 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
634 if (list->friendlyname) {
635 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
636 (const BYTE*)list->friendlyname,
637 strlen(list->friendlyname) + 1);
638 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
641 if (list->vendor) {
642 StringFromGUID2(list->vendor, buf, 39);
643 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
644 (const BYTE*)buf, 78);
645 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
648 if (list->version) {
649 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
650 (const BYTE*)list->version,
651 strlen(list->version) + 1);
652 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
655 if (list->formats) {
656 HKEY formats_key;
657 GUID const * const *format;
659 res = RegCreateKeyExW(clsid_key, pixelformats_keyname, 0, NULL, 0,
660 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
661 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
662 for (format=list->formats; *format; ++format)
664 HKEY format_key;
665 StringFromGUID2(*format, buf, 39);
666 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
667 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
668 if (res != ERROR_SUCCESS) break;
669 RegCloseKey(format_key);
671 RegCloseKey(formats_key);
672 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
675 error_close_clsid_key:
676 RegCloseKey(clsid_key);
679 error_close_coclass_key:
680 RegCloseKey(instance_key);
681 RegCloseKey(converters_key);
682 RegCloseKey(coclass_key);
683 error_return:
684 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
687 /***********************************************************************
688 * unregister_converters
690 static HRESULT unregister_converters(struct regsvr_converter const *list)
692 LONG res = ERROR_SUCCESS;
693 HKEY coclass_key;
694 WCHAR buf[39];
695 HKEY converters_key;
696 HKEY instance_key;
698 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
699 KEY_READ | KEY_WRITE, &coclass_key);
700 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
702 if (res == ERROR_SUCCESS) {
703 StringFromGUID2(&CATID_WICFormatConverters, buf, 39);
704 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
705 KEY_READ | KEY_WRITE, NULL, &converters_key, NULL);
706 if (res == ERROR_SUCCESS)
708 res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0,
709 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
710 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
712 if (res != ERROR_SUCCESS)
713 RegCloseKey(coclass_key);
715 if (res != ERROR_SUCCESS) goto error_return;
717 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
718 StringFromGUID2(list->clsid, buf, 39);
720 res = RegDeleteTreeW(coclass_key, buf);
721 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
722 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
724 res = RegDeleteTreeW(instance_key, buf);
725 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
726 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
729 error_close_coclass_key:
730 RegCloseKey(instance_key);
731 RegCloseKey(converters_key);
732 RegCloseKey(coclass_key);
733 error_return:
734 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
737 /***********************************************************************
738 * register_metadatareaders
740 static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list)
742 LONG res = ERROR_SUCCESS;
743 HKEY coclass_key;
744 WCHAR buf[39];
745 HKEY readers_key;
746 HKEY instance_key;
748 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
749 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
750 if (res == ERROR_SUCCESS) {
751 StringFromGUID2(&CATID_WICMetadataReader, buf, 39);
752 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
753 KEY_READ | KEY_WRITE, NULL, &readers_key, NULL);
754 if (res == ERROR_SUCCESS)
756 res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0,
757 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
758 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
760 if (res != ERROR_SUCCESS)
761 RegCloseKey(coclass_key);
763 if (res != ERROR_SUCCESS) goto error_return;
765 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
766 HKEY clsid_key;
767 HKEY instance_clsid_key;
769 StringFromGUID2(list->clsid, buf, 39);
770 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
771 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
772 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
774 StringFromGUID2(list->clsid, buf, 39);
775 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
776 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
777 if (res == ERROR_SUCCESS) {
778 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
779 (const BYTE*)buf, 78);
780 RegCloseKey(instance_clsid_key);
782 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
784 if (list->author) {
785 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
786 (const BYTE*)list->author,
787 strlen(list->author) + 1);
788 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
791 if (list->friendlyname) {
792 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
793 (const BYTE*)list->friendlyname,
794 strlen(list->friendlyname) + 1);
795 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
798 if (list->vendor) {
799 StringFromGUID2(list->vendor, buf, 39);
800 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
801 (const BYTE*)buf, 78);
802 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
805 if (list->metadata_format) {
806 StringFromGUID2(list->metadata_format, buf, 39);
807 res = RegSetValueExW(clsid_key, metadataformat_valuename, 0, REG_SZ,
808 (const BYTE*)buf, 78);
809 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
812 if (list->version) {
813 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
814 (const BYTE*)list->version,
815 strlen(list->version) + 1);
816 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
819 if (list->specversion) {
820 res = RegSetValueExA(clsid_key, specversion_valuename, 0, REG_SZ,
821 (const BYTE*)list->version,
822 strlen(list->version) + 1);
823 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
826 res = RegSetValueExA(clsid_key, requiresfullstream_valuename, 0, REG_DWORD,
827 (const BYTE*)&list->requires_fullstream, 4);
828 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
830 res = RegSetValueExA(clsid_key, supportspadding_valuename, 0, REG_DWORD,
831 (const BYTE*)&list->supports_padding, 4);
832 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
834 if (list->requires_fixedsize) {
835 res = RegSetValueExA(clsid_key, requiresfixedsize_valuename, 0, REG_DWORD,
836 (const BYTE*)&list->requires_fixedsize, 4);
837 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
840 if (list->containers) {
841 HKEY containers_key;
842 const struct reader_containers *container;
844 res = RegCreateKeyExW(clsid_key, containers_keyname, 0, NULL, 0,
845 KEY_READ | KEY_WRITE, NULL, &containers_key, NULL);
846 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
847 for (container=list->containers; container->format; ++container)
849 HKEY format_key;
850 int i;
851 StringFromGUID2(container->format, buf, 39);
852 res = RegCreateKeyExW(containers_key, buf, 0, NULL, 0,
853 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
854 if (res != ERROR_SUCCESS) break;
856 for (i=0; container->patterns[i].length; i++)
858 HKEY pattern_key;
859 static const WCHAR int_format[] = {'%','i',0};
860 snprintfW(buf, 39, int_format, i);
861 res = RegCreateKeyExW(format_key, buf, 0, NULL, 0,
862 KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL);
863 if (res != ERROR_SUCCESS) break;
864 res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD,
865 (const BYTE*)&container->patterns[i].position, 4);
866 if (res == ERROR_SUCCESS)
867 res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY,
868 container->patterns[i].pattern,
869 container->patterns[i].length);
870 if (res == ERROR_SUCCESS)
871 res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY,
872 container->patterns[i].mask,
873 container->patterns[i].length);
874 if (res == ERROR_SUCCESS && container->patterns[i].data_offset)
875 res = RegSetValueExA(pattern_key, dataoffset_valuename, 0, REG_DWORD,
876 (const BYTE*)&container->patterns[i].data_offset, 4);
877 RegCloseKey(pattern_key);
880 RegCloseKey(format_key);
882 RegCloseKey(containers_key);
885 error_close_clsid_key:
886 RegCloseKey(clsid_key);
889 error_close_coclass_key:
890 RegCloseKey(instance_key);
891 RegCloseKey(readers_key);
892 RegCloseKey(coclass_key);
893 error_return:
894 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
897 /***********************************************************************
898 * unregister_metadatareaders
900 static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list)
902 LONG res = ERROR_SUCCESS;
903 HKEY coclass_key;
904 WCHAR buf[39];
905 HKEY readers_key;
906 HKEY instance_key;
908 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
909 KEY_READ | KEY_WRITE, &coclass_key);
910 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
912 if (res == ERROR_SUCCESS) {
913 StringFromGUID2(&CATID_WICMetadataReader, buf, 39);
914 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
915 KEY_READ | KEY_WRITE, NULL, &readers_key, NULL);
916 if (res == ERROR_SUCCESS)
918 res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0,
919 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
920 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
922 if (res != ERROR_SUCCESS)
923 RegCloseKey(coclass_key);
925 if (res != ERROR_SUCCESS) goto error_return;
927 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
928 StringFromGUID2(list->clsid, buf, 39);
930 res = RegDeleteTreeW(coclass_key, buf);
931 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
932 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
934 res = RegDeleteTreeW(instance_key, buf);
935 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
936 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
939 error_close_coclass_key:
940 RegCloseKey(instance_key);
941 RegCloseKey(readers_key);
942 RegCloseKey(coclass_key);
943 error_return:
944 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
947 /***********************************************************************
948 * register_pixelformats
950 static HRESULT register_pixelformats(struct regsvr_pixelformat const *list)
952 LONG res = ERROR_SUCCESS;
953 HKEY coclass_key;
954 WCHAR buf[39];
955 HKEY formats_key;
956 HKEY instance_key;
958 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
959 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
960 if (res == ERROR_SUCCESS) {
961 StringFromGUID2(&CATID_WICPixelFormats, buf, 39);
962 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
963 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
964 if (res == ERROR_SUCCESS)
966 res = RegCreateKeyExW(formats_key, instance_keyname, 0, NULL, 0,
967 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
968 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
970 if (res != ERROR_SUCCESS)
971 RegCloseKey(coclass_key);
973 if (res != ERROR_SUCCESS) goto error_return;
975 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
976 HKEY clsid_key;
977 HKEY instance_clsid_key;
979 StringFromGUID2(list->clsid, buf, 39);
980 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
981 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
982 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
984 StringFromGUID2(list->clsid, buf, 39);
985 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
986 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
987 if (res == ERROR_SUCCESS) {
988 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
989 (const BYTE*)buf, 78);
990 RegCloseKey(instance_clsid_key);
992 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
994 if (list->author) {
995 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
996 (const BYTE*)list->author,
997 strlen(list->author) + 1);
998 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1001 if (list->friendlyname) {
1002 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
1003 (const BYTE*)list->friendlyname,
1004 strlen(list->friendlyname) + 1);
1005 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1008 if (list->vendor) {
1009 StringFromGUID2(list->vendor, buf, 39);
1010 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
1011 (const BYTE*)buf, 78);
1012 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1015 if (list->version) {
1016 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
1017 (const BYTE*)list->version,
1018 strlen(list->version) + 1);
1019 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1022 res = RegSetValueExA(clsid_key, bitsperpixel_valuename, 0, REG_DWORD,
1023 (const BYTE*)&list->bitsperpixel, 4);
1024 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1026 res = RegSetValueExA(clsid_key, channelcount_valuename, 0, REG_DWORD,
1027 (const BYTE*)&list->channelcount, 4);
1028 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1030 res = RegSetValueExA(clsid_key, numericrepresentation_valuename, 0, REG_DWORD,
1031 (const BYTE*)&list->numericrepresentation, 4);
1032 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1034 res = RegSetValueExA(clsid_key, supportstransparency_valuename, 0, REG_DWORD,
1035 (const BYTE*)&list->supportsalpha, 4);
1036 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1038 if (list->channelmasks) {
1039 HKEY masks_key;
1040 UINT i, mask_size;
1041 WCHAR mask_valuename[11];
1042 const WCHAR valuename_format[] = {'%','d',0};
1044 mask_size = (list->bitsperpixel + 7)/8;
1046 res = RegCreateKeyExW(clsid_key, channelmasks_keyname, 0, NULL, 0,
1047 KEY_READ | KEY_WRITE, NULL, &masks_key, NULL);
1048 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1049 for (i=0; i < list->channelcount; i++)
1051 sprintfW(mask_valuename, valuename_format, i);
1052 res = RegSetValueExW(masks_key, mask_valuename, 0, REG_BINARY,
1053 list->channelmasks[i], mask_size);
1054 if (res != ERROR_SUCCESS) break;
1056 RegCloseKey(masks_key);
1057 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1060 error_close_clsid_key:
1061 RegCloseKey(clsid_key);
1064 error_close_coclass_key:
1065 RegCloseKey(instance_key);
1066 RegCloseKey(formats_key);
1067 RegCloseKey(coclass_key);
1068 error_return:
1069 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
1072 /***********************************************************************
1073 * unregister_pixelformats
1075 static HRESULT unregister_pixelformats(struct regsvr_pixelformat const *list)
1077 LONG res = ERROR_SUCCESS;
1078 HKEY coclass_key;
1079 WCHAR buf[39];
1080 HKEY formats_key;
1081 HKEY instance_key;
1083 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
1084 KEY_READ | KEY_WRITE, &coclass_key);
1085 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
1087 if (res == ERROR_SUCCESS) {
1088 StringFromGUID2(&CATID_WICPixelFormats, buf, 39);
1089 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
1090 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
1091 if (res == ERROR_SUCCESS)
1093 res = RegCreateKeyExW(formats_key, instance_keyname, 0, NULL, 0,
1094 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
1095 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1097 if (res != ERROR_SUCCESS)
1098 RegCloseKey(coclass_key);
1100 if (res != ERROR_SUCCESS) goto error_return;
1102 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
1103 StringFromGUID2(list->clsid, buf, 39);
1105 res = RegDeleteTreeW(coclass_key, buf);
1106 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
1107 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1109 res = RegDeleteTreeW(instance_key, buf);
1110 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
1111 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1114 error_close_coclass_key:
1115 RegCloseKey(instance_key);
1116 RegCloseKey(formats_key);
1117 RegCloseKey(coclass_key);
1118 error_return:
1119 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
1122 /***********************************************************************
1123 * decoder list
1125 static const BYTE mask_all[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1127 static const BYTE bmp_magic[] = {0x42,0x4d};
1129 static GUID const * const bmp_formats[] = {
1130 &GUID_WICPixelFormat1bppIndexed,
1131 &GUID_WICPixelFormat2bppIndexed,
1132 &GUID_WICPixelFormat4bppIndexed,
1133 &GUID_WICPixelFormat8bppIndexed,
1134 &GUID_WICPixelFormat16bppBGR555,
1135 &GUID_WICPixelFormat16bppBGR565,
1136 &GUID_WICPixelFormat24bppBGR,
1137 &GUID_WICPixelFormat32bppBGR,
1138 &GUID_WICPixelFormat32bppBGRA,
1139 NULL
1142 static struct decoder_pattern const bmp_patterns[] = {
1143 {2,0,bmp_magic,mask_all,0},
1147 static const BYTE gif87a_magic[6] = "GIF87a";
1148 static const BYTE gif89a_magic[6] = "GIF89a";
1150 static GUID const * const gif_formats[] = {
1151 &GUID_WICPixelFormat8bppIndexed,
1152 NULL
1155 static struct decoder_pattern const gif_patterns[] = {
1156 {6,0,gif87a_magic,mask_all,0},
1157 {6,0,gif89a_magic,mask_all,0},
1161 static const BYTE ico_magic[] = {00,00,01,00};
1163 static GUID const * const ico_formats[] = {
1164 &GUID_WICPixelFormat32bppBGRA,
1165 NULL
1168 static struct decoder_pattern const ico_patterns[] = {
1169 {4,0,ico_magic,mask_all,0},
1173 static const BYTE jpeg_magic[] = {0xff, 0xd8};
1175 static GUID const * const jpeg_formats[] = {
1176 &GUID_WICPixelFormat24bppBGR,
1177 &GUID_WICPixelFormat32bppCMYK,
1178 &GUID_WICPixelFormat8bppGray,
1179 NULL
1182 static struct decoder_pattern const jpeg_patterns[] = {
1183 {2,0,jpeg_magic,mask_all,0},
1187 static const BYTE png_magic[] = {137,80,78,71,13,10,26,10};
1189 static GUID const * const png_formats[] = {
1190 &GUID_WICPixelFormatBlackWhite,
1191 &GUID_WICPixelFormat2bppGray,
1192 &GUID_WICPixelFormat4bppGray,
1193 &GUID_WICPixelFormat8bppGray,
1194 &GUID_WICPixelFormat16bppGray,
1195 &GUID_WICPixelFormat32bppBGRA,
1196 &GUID_WICPixelFormat64bppRGBA,
1197 &GUID_WICPixelFormat1bppIndexed,
1198 &GUID_WICPixelFormat2bppIndexed,
1199 &GUID_WICPixelFormat4bppIndexed,
1200 &GUID_WICPixelFormat8bppIndexed,
1201 &GUID_WICPixelFormat24bppBGR,
1202 &GUID_WICPixelFormat48bppRGB,
1203 NULL
1206 static struct decoder_pattern const png_patterns[] = {
1207 {8,0,png_magic,mask_all,0},
1211 static const BYTE tiff_magic_le[] = {0x49,0x49,42,0};
1212 static const BYTE tiff_magic_be[] = {0x4d,0x4d,0,42};
1214 static GUID const * const tiff_decode_formats[] = {
1215 &GUID_WICPixelFormatBlackWhite,
1216 &GUID_WICPixelFormat4bppGray,
1217 &GUID_WICPixelFormat8bppGray,
1218 &GUID_WICPixelFormat4bppIndexed,
1219 &GUID_WICPixelFormat8bppIndexed,
1220 &GUID_WICPixelFormat24bppBGR,
1221 &GUID_WICPixelFormat32bppBGR,
1222 &GUID_WICPixelFormat32bppBGRA,
1223 &GUID_WICPixelFormat32bppPBGRA,
1224 &GUID_WICPixelFormat48bppRGB,
1225 &GUID_WICPixelFormat64bppRGBA,
1226 &GUID_WICPixelFormat64bppPRGBA,
1227 NULL
1230 static struct decoder_pattern const tiff_patterns[] = {
1231 {4,0,tiff_magic_le,mask_all,0},
1232 {4,0,tiff_magic_be,mask_all,0},
1236 static const BYTE tga_footer_magic[18] = "TRUEVISION-XFILE.";
1238 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};
1239 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};
1241 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};
1242 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};
1244 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};
1245 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};
1247 static GUID const * const tga_formats[] = {
1248 &GUID_WICPixelFormat8bppGray,
1249 &GUID_WICPixelFormat8bppIndexed,
1250 &GUID_WICPixelFormat16bppGray,
1251 &GUID_WICPixelFormat16bppBGR555,
1252 &GUID_WICPixelFormat24bppBGR,
1253 &GUID_WICPixelFormat32bppBGRA,
1254 &GUID_WICPixelFormat32bppPBGRA,
1255 NULL
1258 static struct decoder_pattern const tga_patterns[] = {
1259 {18,18,tga_footer_magic,mask_all,1},
1260 {18,0,tga_indexed_magic,tga_indexed_mask,0},
1261 {18,0,tga_truecolor_magic,tga_truecolor_mask,0},
1262 {18,0,tga_grayscale_magic,tga_grayscale_mask,0},
1266 static struct regsvr_decoder const decoder_list[] = {
1267 { &CLSID_WICBmpDecoder,
1268 "The Wine Project",
1269 "BMP Decoder",
1270 "1.0.0.0",
1271 &GUID_VendorMicrosoft,
1272 &GUID_ContainerFormatBmp,
1273 "image/bmp",
1274 ".bmp,.dib,.rle",
1275 bmp_formats,
1276 bmp_patterns
1278 { &CLSID_WICGifDecoder,
1279 "The Wine Project",
1280 "GIF Decoder",
1281 "1.0.0.0",
1282 &GUID_VendorMicrosoft,
1283 &GUID_ContainerFormatGif,
1284 "image/gif",
1285 ".gif",
1286 gif_formats,
1287 gif_patterns
1289 { &CLSID_WICIcoDecoder,
1290 "The Wine Project",
1291 "ICO Decoder",
1292 "1.0.0.0",
1293 &GUID_VendorMicrosoft,
1294 &GUID_ContainerFormatIco,
1295 "image/vnd.microsoft.icon",
1296 ".ico",
1297 ico_formats,
1298 ico_patterns
1300 { &CLSID_WICJpegDecoder,
1301 "The Wine Project",
1302 "JPEG Decoder",
1303 "1.0.0.0",
1304 &GUID_VendorMicrosoft,
1305 &GUID_ContainerFormatJpeg,
1306 "image/jpeg",
1307 ".jpg;.jpeg;.jfif",
1308 jpeg_formats,
1309 jpeg_patterns
1311 { &CLSID_WICPngDecoder,
1312 "The Wine Project",
1313 "PNG Decoder",
1314 "1.0.0.0",
1315 &GUID_VendorMicrosoft,
1316 &GUID_ContainerFormatPng,
1317 "image/png",
1318 ".png",
1319 png_formats,
1320 png_patterns
1322 { &CLSID_WICTiffDecoder,
1323 "The Wine Project",
1324 "TIFF Decoder",
1325 "1.0.0.0",
1326 &GUID_VendorMicrosoft,
1327 &GUID_ContainerFormatTiff,
1328 "image/tiff",
1329 ".tif;.tiff",
1330 tiff_decode_formats,
1331 tiff_patterns
1333 { &CLSID_WineTgaDecoder,
1334 "The Wine Project",
1335 "TGA Decoder",
1336 "1.0.0.0",
1337 &GUID_VendorWine,
1338 &GUID_WineContainerFormatTga,
1339 "image/x-targa",
1340 ".tga;.tpic",
1341 tga_formats,
1342 tga_patterns
1344 { NULL } /* list terminator */
1347 static GUID const * const bmp_encode_formats[] = {
1348 &GUID_WICPixelFormat16bppBGR555,
1349 &GUID_WICPixelFormat16bppBGR565,
1350 &GUID_WICPixelFormat24bppBGR,
1351 &GUID_WICPixelFormat32bppBGR,
1352 NULL
1355 static GUID const * const png_encode_formats[] = {
1356 &GUID_WICPixelFormat24bppBGR,
1357 &GUID_WICPixelFormatBlackWhite,
1358 &GUID_WICPixelFormat2bppGray,
1359 &GUID_WICPixelFormat4bppGray,
1360 &GUID_WICPixelFormat8bppGray,
1361 &GUID_WICPixelFormat16bppGray,
1362 &GUID_WICPixelFormat32bppBGR,
1363 &GUID_WICPixelFormat32bppBGRA,
1364 &GUID_WICPixelFormat48bppRGB,
1365 &GUID_WICPixelFormat64bppRGBA,
1366 NULL
1369 static GUID const * const tiff_encode_formats[] = {
1370 &GUID_WICPixelFormatBlackWhite,
1371 &GUID_WICPixelFormat4bppGray,
1372 &GUID_WICPixelFormat8bppGray,
1373 &GUID_WICPixelFormat24bppBGR,
1374 &GUID_WICPixelFormat32bppBGRA,
1375 &GUID_WICPixelFormat32bppPBGRA,
1376 &GUID_WICPixelFormat48bppRGB,
1377 &GUID_WICPixelFormat64bppRGBA,
1378 &GUID_WICPixelFormat64bppPRGBA,
1379 NULL
1382 static GUID const * const icns_encode_formats[] = {
1383 &GUID_WICPixelFormat32bppBGRA,
1384 NULL
1387 static struct regsvr_encoder const encoder_list[] = {
1388 { &CLSID_WICBmpEncoder,
1389 "The Wine Project",
1390 "BMP Encoder",
1391 "1.0.0.0",
1392 &GUID_VendorMicrosoft,
1393 &GUID_ContainerFormatBmp,
1394 "image/bmp",
1395 ".bmp,.dib,.rle",
1396 bmp_encode_formats
1398 { &CLSID_WICJpegEncoder,
1399 "The Wine Project",
1400 "JPEG Encoder",
1401 "1.0.0.0",
1402 &GUID_VendorMicrosoft,
1403 &GUID_ContainerFormatJpeg,
1404 "image/jpeg",
1405 ".jpg;.jpeg;.jfif",
1406 jpeg_formats
1408 { &CLSID_WICPngEncoder,
1409 "The Wine Project",
1410 "PNG Encoder",
1411 "1.0.0.0",
1412 &GUID_VendorMicrosoft,
1413 &GUID_ContainerFormatPng,
1414 "image/png",
1415 ".png",
1416 png_encode_formats
1418 { &CLSID_WICTiffEncoder,
1419 "The Wine Project",
1420 "TIFF Encoder",
1421 "1.0.0.0",
1422 &GUID_VendorMicrosoft,
1423 &GUID_ContainerFormatTiff,
1424 "image/tiff",
1425 ".tif;.tiff",
1426 tiff_encode_formats
1428 { &CLSID_WICIcnsEncoder,
1429 "The Wine Project",
1430 "ICNS Encoder",
1431 "1.0.0.0",
1432 &GUID_VendorWine,
1433 NULL, /* no container format guid */
1434 "image/icns",
1435 ".icns",
1436 icns_encode_formats
1438 { NULL } /* list terminator */
1441 static GUID const * const converter_formats[] = {
1442 &GUID_WICPixelFormat1bppIndexed,
1443 &GUID_WICPixelFormat2bppIndexed,
1444 &GUID_WICPixelFormat4bppIndexed,
1445 &GUID_WICPixelFormat8bppIndexed,
1446 &GUID_WICPixelFormatBlackWhite,
1447 &GUID_WICPixelFormat2bppGray,
1448 &GUID_WICPixelFormat4bppGray,
1449 &GUID_WICPixelFormat8bppGray,
1450 &GUID_WICPixelFormat16bppGray,
1451 &GUID_WICPixelFormat16bppBGR555,
1452 &GUID_WICPixelFormat16bppBGR565,
1453 &GUID_WICPixelFormat16bppBGRA5551,
1454 &GUID_WICPixelFormat24bppBGR,
1455 &GUID_WICPixelFormat24bppRGB,
1456 &GUID_WICPixelFormat32bppBGR,
1457 &GUID_WICPixelFormat32bppBGRA,
1458 &GUID_WICPixelFormat32bppPBGRA,
1459 &GUID_WICPixelFormat48bppRGB,
1460 &GUID_WICPixelFormat64bppRGBA,
1461 &GUID_WICPixelFormat32bppCMYK,
1462 NULL
1465 static struct regsvr_converter const converter_list[] = {
1466 { &CLSID_WICDefaultFormatConverter,
1467 "The Wine Project",
1468 "Default Pixel Format Converter",
1469 "1.0.0.0",
1470 &GUID_VendorMicrosoft,
1471 converter_formats
1473 { NULL } /* list terminator */
1476 static const BYTE no_magic[1] = { 0 };
1477 static const BYTE no_mask[1] = { 0 };
1479 static const struct metadata_pattern ifd_metadata_pattern[] = {
1480 { 0, 1, no_magic, no_mask, 0 },
1481 { 0 }
1484 static const struct reader_containers ifd_containers[] = {
1486 &GUID_ContainerFormatTiff,
1487 ifd_metadata_pattern
1489 { NULL } /* list terminator */
1492 static const BYTE tEXt[] = "tEXt";
1494 static const struct metadata_pattern pngtext_metadata_pattern[] = {
1495 { 4, 4, tEXt, mask_all, 4 },
1496 { 0 }
1499 static const struct reader_containers pngtext_containers[] = {
1501 &GUID_ContainerFormatPng,
1502 pngtext_metadata_pattern
1504 { NULL } /* list terminator */
1507 static const struct metadata_pattern lsd_metadata_patterns[] = {
1508 { 0, 6, gif87a_magic, mask_all, 0 },
1509 { 0, 6, gif89a_magic, mask_all, 0 },
1510 { 0 }
1513 static const struct reader_containers lsd_containers[] = {
1515 &GUID_ContainerFormatGif,
1516 lsd_metadata_patterns
1518 { NULL } /* list terminator */
1521 static const BYTE imd_magic[] = { 0x2c };
1523 static const struct metadata_pattern imd_metadata_pattern[] = {
1524 { 0, 1, imd_magic, mask_all, 1 },
1525 { 0 }
1528 static const struct reader_containers imd_containers[] = {
1530 &GUID_ContainerFormatGif,
1531 imd_metadata_pattern
1533 { NULL } /* list terminator */
1536 static const BYTE gce_magic[] = { 0x21, 0xf9, 0x04 };
1538 static const struct metadata_pattern gce_metadata_pattern[] = {
1539 { 0, 3, gce_magic, mask_all, 3 },
1540 { 0 }
1543 static const struct reader_containers gce_containers[] = {
1545 &GUID_ContainerFormatGif,
1546 gce_metadata_pattern
1548 { NULL } /* list terminator */
1551 static const BYTE ape_magic[] = { 0x21, 0xff, 0x0b };
1553 static const struct metadata_pattern ape_metadata_pattern[] = {
1554 { 0, 3, ape_magic, mask_all, 0 },
1555 { 0 }
1558 static const struct reader_containers ape_containers[] = {
1560 &GUID_ContainerFormatGif,
1561 ape_metadata_pattern
1563 { NULL } /* list terminator */
1566 static const BYTE gif_comment_magic[] = { 0x21, 0xfe };
1568 static const struct metadata_pattern gif_comment_metadata_pattern[] = {
1569 { 0, 2, gif_comment_magic, mask_all, 0 },
1570 { 0 }
1573 static const struct reader_containers gif_comment_containers[] = {
1575 &GUID_ContainerFormatGif,
1576 gif_comment_metadata_pattern
1578 { NULL } /* list terminator */
1581 static struct regsvr_metadatareader const metadatareader_list[] = {
1582 { &CLSID_WICUnknownMetadataReader,
1583 "The Wine Project",
1584 "Unknown Metadata Reader",
1585 "1.0.0.0",
1586 "1.0.0.0",
1587 &GUID_VendorMicrosoft,
1588 &GUID_MetadataFormatUnknown,
1589 0, 0, 0,
1590 NULL
1592 { &CLSID_WICIfdMetadataReader,
1593 "The Wine Project",
1594 "Ifd Reader",
1595 "1.0.0.0",
1596 "1.0.0.0",
1597 &GUID_VendorMicrosoft,
1598 &GUID_MetadataFormatIfd,
1599 1, 1, 0,
1600 ifd_containers
1602 { &CLSID_WICPngTextMetadataReader,
1603 "The Wine Project",
1604 "Chunk tEXt Reader",
1605 "1.0.0.0",
1606 "1.0.0.0",
1607 &GUID_VendorMicrosoft,
1608 &GUID_MetadataFormatChunktEXt,
1609 0, 0, 0,
1610 pngtext_containers
1612 { &CLSID_WICLSDMetadataReader,
1613 "The Wine Project",
1614 "Logical Screen Descriptor Reader",
1615 "1.0.0.0",
1616 "1.0.0.0",
1617 &GUID_VendorMicrosoft,
1618 &GUID_MetadataFormatLSD,
1619 0, 0, 0,
1620 lsd_containers
1622 { &CLSID_WICIMDMetadataReader,
1623 "The Wine Project",
1624 "Image Descriptor Reader",
1625 "1.0.0.0",
1626 "1.0.0.0",
1627 &GUID_VendorMicrosoft,
1628 &GUID_MetadataFormatIMD,
1629 0, 0, 0,
1630 imd_containers
1632 { &CLSID_WICGCEMetadataReader,
1633 "The Wine Project",
1634 "Graphic Control Extension Reader",
1635 "1.0.0.0",
1636 "1.0.0.0",
1637 &GUID_VendorMicrosoft,
1638 &GUID_MetadataFormatGCE,
1639 0, 0, 0,
1640 gce_containers
1642 { &CLSID_WICAPEMetadataReader,
1643 "The Wine Project",
1644 "Application Extension Reader",
1645 "1.0.0.0",
1646 "1.0.0.0",
1647 &GUID_VendorMicrosoft,
1648 &GUID_MetadataFormatAPE,
1649 0, 0, 0,
1650 ape_containers
1652 { &CLSID_WICGifCommentMetadataReader,
1653 "The Wine Project",
1654 "Comment Extension Reader",
1655 "1.0.0.0",
1656 "1.0.0.0",
1657 &GUID_VendorMicrosoft,
1658 &GUID_MetadataFormatGifComment,
1659 0, 0, 0,
1660 gif_comment_containers
1662 { NULL } /* list terminator */
1665 static BYTE const channel_mask_1bit[] = { 0x01 };
1666 static BYTE const channel_mask_2bit[] = { 0x03 };
1667 static BYTE const channel_mask_4bit[] = { 0x0f };
1669 static BYTE const channel_mask_8bit[] = { 0xff, 0x00, 0x00, 0x00 };
1670 static BYTE const channel_mask_8bit2[] = { 0x00, 0xff, 0x00, 0x00 };
1671 static BYTE const channel_mask_8bit3[] = { 0x00, 0x00, 0xff, 0x00 };
1672 static BYTE const channel_mask_8bit4[] = { 0x00, 0x00, 0x00, 0xff };
1674 static BYTE const channel_mask_16bit[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1675 static BYTE const channel_mask_16bit2[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1676 static BYTE const channel_mask_16bit3[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
1677 static BYTE const channel_mask_16bit4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
1679 static BYTE const channel_mask_5bit[] = { 0x1f, 0x00 };
1680 static BYTE const channel_mask_5bit2[] = { 0xe0, 0x03 };
1681 static BYTE const channel_mask_5bit3[] = { 0x00, 0x7c };
1682 static BYTE const channel_mask_5bit4[] = { 0x00, 0x80 };
1684 static BYTE const channel_mask_BGR565_2[] = { 0xe0, 0x07 };
1685 static BYTE const channel_mask_BGR565_3[] = { 0x00, 0xf8 };
1687 static BYTE const * const channel_masks_1bit[] = { channel_mask_1bit };
1688 static BYTE const * const channel_masks_2bit[] = { channel_mask_2bit };
1689 static BYTE const * const channel_masks_4bit[] = { channel_mask_4bit };
1690 static BYTE const * const channel_masks_8bit[] = { channel_mask_8bit,
1691 channel_mask_8bit2, channel_mask_8bit3, channel_mask_8bit4 };
1692 static BYTE const * const channel_masks_16bit[] = { channel_mask_16bit,
1693 channel_mask_16bit2, channel_mask_16bit3, channel_mask_16bit4};
1695 static BYTE const * const channel_masks_BGRA5551[] = { channel_mask_5bit,
1696 channel_mask_5bit2, channel_mask_5bit3, channel_mask_5bit4 };
1698 static BYTE const * const channel_masks_BGR565[] = { channel_mask_5bit,
1699 channel_mask_BGR565_2, channel_mask_BGR565_3 };
1701 static struct regsvr_pixelformat const pixelformat_list[] = {
1702 { &GUID_WICPixelFormat1bppIndexed,
1703 "The Wine Project",
1704 "1bpp Indexed",
1705 NULL, /* no version */
1706 &GUID_VendorMicrosoft,
1707 1, /* bitsperpixel */
1708 1, /* channel count */
1709 channel_masks_1bit,
1710 WICPixelFormatNumericRepresentationIndexed,
1713 { &GUID_WICPixelFormat2bppIndexed,
1714 "The Wine Project",
1715 "2bpp Indexed",
1716 NULL, /* no version */
1717 &GUID_VendorMicrosoft,
1718 2, /* bitsperpixel */
1719 1, /* channel count */
1720 channel_masks_2bit,
1721 WICPixelFormatNumericRepresentationIndexed,
1724 { &GUID_WICPixelFormat4bppIndexed,
1725 "The Wine Project",
1726 "4bpp Indexed",
1727 NULL, /* no version */
1728 &GUID_VendorMicrosoft,
1729 4, /* bitsperpixel */
1730 1, /* channel count */
1731 channel_masks_4bit,
1732 WICPixelFormatNumericRepresentationIndexed,
1735 { &GUID_WICPixelFormat8bppIndexed,
1736 "The Wine Project",
1737 "8bpp Indexed",
1738 NULL, /* no version */
1739 &GUID_VendorMicrosoft,
1740 8, /* bitsperpixel */
1741 1, /* channel count */
1742 channel_masks_8bit,
1743 WICPixelFormatNumericRepresentationIndexed,
1746 { &GUID_WICPixelFormatBlackWhite,
1747 "The Wine Project",
1748 "Black and White",
1749 NULL, /* no version */
1750 &GUID_VendorMicrosoft,
1751 1, /* bitsperpixel */
1752 1, /* channel count */
1753 channel_masks_1bit,
1754 WICPixelFormatNumericRepresentationUnsignedInteger,
1757 { &GUID_WICPixelFormat2bppGray,
1758 "The Wine Project",
1759 "2bpp Grayscale",
1760 NULL, /* no version */
1761 &GUID_VendorMicrosoft,
1762 2, /* bitsperpixel */
1763 1, /* channel count */
1764 channel_masks_2bit,
1765 WICPixelFormatNumericRepresentationUnsignedInteger,
1768 { &GUID_WICPixelFormat4bppGray,
1769 "The Wine Project",
1770 "4bpp Grayscale",
1771 NULL, /* no version */
1772 &GUID_VendorMicrosoft,
1773 4, /* bitsperpixel */
1774 1, /* channel count */
1775 channel_masks_4bit,
1776 WICPixelFormatNumericRepresentationUnsignedInteger,
1779 { &GUID_WICPixelFormat8bppGray,
1780 "The Wine Project",
1781 "8bpp Grayscale",
1782 NULL, /* no version */
1783 &GUID_VendorMicrosoft,
1784 8, /* bitsperpixel */
1785 1, /* channel count */
1786 channel_masks_8bit,
1787 WICPixelFormatNumericRepresentationUnsignedInteger,
1790 { &GUID_WICPixelFormat16bppGray,
1791 "The Wine Project",
1792 "16bpp Grayscale",
1793 NULL, /* no version */
1794 &GUID_VendorMicrosoft,
1795 16, /* bitsperpixel */
1796 1, /* channel count */
1797 channel_masks_16bit,
1798 WICPixelFormatNumericRepresentationUnsignedInteger,
1801 { &GUID_WICPixelFormat16bppBGR555,
1802 "The Wine Project",
1803 "16bpp BGR555",
1804 NULL, /* no version */
1805 &GUID_VendorMicrosoft,
1806 16, /* bitsperpixel */
1807 3, /* channel count */
1808 channel_masks_BGRA5551,
1809 WICPixelFormatNumericRepresentationUnsignedInteger,
1812 { &GUID_WICPixelFormat16bppBGR565,
1813 "The Wine Project",
1814 "16bpp BGR565",
1815 NULL, /* no version */
1816 &GUID_VendorMicrosoft,
1817 16, /* bitsperpixel */
1818 3, /* channel count */
1819 channel_masks_BGR565,
1820 WICPixelFormatNumericRepresentationUnsignedInteger,
1823 { &GUID_WICPixelFormat16bppBGRA5551,
1824 "The Wine Project",
1825 "16bpp BGRA5551",
1826 NULL, /* no version */
1827 &GUID_VendorMicrosoft,
1828 16, /* bitsperpixel */
1829 4, /* channel count */
1830 channel_masks_BGRA5551,
1831 WICPixelFormatNumericRepresentationUnsignedInteger,
1834 { &GUID_WICPixelFormat24bppBGR,
1835 "The Wine Project",
1836 "24bpp BGR",
1837 NULL, /* no version */
1838 &GUID_VendorMicrosoft,
1839 24, /* bitsperpixel */
1840 3, /* channel count */
1841 channel_masks_8bit,
1842 WICPixelFormatNumericRepresentationUnsignedInteger,
1845 { &GUID_WICPixelFormat24bppRGB,
1846 "The Wine Project",
1847 "24bpp RGB",
1848 NULL, /* no version */
1849 &GUID_VendorMicrosoft,
1850 24, /* bitsperpixel */
1851 3, /* channel count */
1852 channel_masks_8bit,
1853 WICPixelFormatNumericRepresentationUnsignedInteger,
1856 { &GUID_WICPixelFormat32bppBGR,
1857 "The Wine Project",
1858 "32bpp BGR",
1859 NULL, /* no version */
1860 &GUID_VendorMicrosoft,
1861 32, /* bitsperpixel */
1862 3, /* channel count */
1863 channel_masks_8bit,
1864 WICPixelFormatNumericRepresentationUnsignedInteger,
1867 { &GUID_WICPixelFormat32bppBGRA,
1868 "The Wine Project",
1869 "32bpp BGRA",
1870 NULL, /* no version */
1871 &GUID_VendorMicrosoft,
1872 32, /* bitsperpixel */
1873 4, /* channel count */
1874 channel_masks_8bit,
1875 WICPixelFormatNumericRepresentationUnsignedInteger,
1878 { &GUID_WICPixelFormat32bppPBGRA,
1879 "The Wine Project",
1880 "32bpp PBGRA",
1881 NULL, /* no version */
1882 &GUID_VendorMicrosoft,
1883 32, /* bitsperpixel */
1884 4, /* channel count */
1885 channel_masks_8bit,
1886 WICPixelFormatNumericRepresentationUnsignedInteger,
1889 { &GUID_WICPixelFormat48bppRGB,
1890 "The Wine Project",
1891 "48bpp RGB",
1892 NULL, /* no version */
1893 &GUID_VendorMicrosoft,
1894 48, /* bitsperpixel */
1895 3, /* channel count */
1896 channel_masks_16bit,
1897 WICPixelFormatNumericRepresentationUnsignedInteger,
1900 { &GUID_WICPixelFormat64bppRGBA,
1901 "The Wine Project",
1902 "64bpp RGBA",
1903 NULL, /* no version */
1904 &GUID_VendorMicrosoft,
1905 64, /* bitsperpixel */
1906 4, /* channel count */
1907 channel_masks_16bit,
1908 WICPixelFormatNumericRepresentationUnsignedInteger,
1911 { &GUID_WICPixelFormat64bppPRGBA,
1912 "The Wine Project",
1913 "64bpp PRGBA",
1914 NULL, /* no version */
1915 &GUID_VendorMicrosoft,
1916 64, /* bitsperpixel */
1917 4, /* channel count */
1918 channel_masks_16bit,
1919 WICPixelFormatNumericRepresentationUnsignedInteger,
1922 { &GUID_WICPixelFormat32bppCMYK,
1923 "The Wine Project",
1924 "32bpp CMYK",
1925 NULL, /* no version */
1926 &GUID_VendorMicrosoft,
1927 32, /* bitsperpixel */
1928 4, /* channel count */
1929 channel_masks_8bit,
1930 WICPixelFormatNumericRepresentationUnsignedInteger,
1933 { NULL } /* list terminator */
1936 struct regsvr_category
1938 const CLSID *clsid; /* NULL for end of list */
1941 static const struct regsvr_category category_list[] = {
1942 { &CATID_WICBitmapDecoders },
1943 { &CATID_WICBitmapEncoders },
1944 { &CATID_WICFormatConverters },
1945 { &CATID_WICMetadataReader },
1946 { &CATID_WICPixelFormats },
1947 { NULL }
1950 static HRESULT register_categories(const struct regsvr_category *list)
1952 LONG res;
1953 WCHAR buf[39];
1954 HKEY coclass_key, categories_key, instance_key;
1956 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
1957 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
1958 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
1960 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
1961 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
1962 KEY_READ | KEY_WRITE, NULL, &categories_key, NULL);
1963 if (res != ERROR_SUCCESS)
1965 RegCloseKey(coclass_key);
1966 return HRESULT_FROM_WIN32(res);
1969 res = RegCreateKeyExW(categories_key, instance_keyname, 0, NULL, 0,
1970 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
1972 for (; res == ERROR_SUCCESS && list->clsid; list++)
1974 HKEY instance_clsid_key;
1976 StringFromGUID2(list->clsid, buf, 39);
1977 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
1978 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
1979 if (res == ERROR_SUCCESS)
1981 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
1982 (const BYTE *)buf, 78);
1983 RegCloseKey(instance_clsid_key);
1987 RegCloseKey(instance_key);
1988 RegCloseKey(categories_key);
1989 RegCloseKey(coclass_key);
1991 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
1994 static HRESULT unregister_categories(const struct regsvr_category *list)
1996 LONG res;
1997 WCHAR buf[39];
1998 HKEY coclass_key, categories_key, instance_key;
2000 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
2001 KEY_READ | KEY_WRITE, &coclass_key);
2002 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
2004 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
2005 res = RegOpenKeyExW(coclass_key, buf, 0,
2006 KEY_READ | KEY_WRITE, &categories_key);
2007 if (res != ERROR_SUCCESS)
2009 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
2010 RegCloseKey(coclass_key);
2011 return HRESULT_FROM_WIN32(res);
2014 res = RegOpenKeyExW(categories_key, instance_keyname, 0,
2015 KEY_READ | KEY_WRITE, &instance_key);
2017 for (; res == ERROR_SUCCESS && list->clsid; list++)
2019 StringFromGUID2(list->clsid, buf, 39);
2020 res = RegDeleteTreeW(instance_key, buf);
2023 RegCloseKey(instance_key);
2024 RegCloseKey(categories_key);
2026 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
2027 res = RegDeleteTreeW(coclass_key, buf);
2029 RegCloseKey(coclass_key);
2031 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
2034 extern HRESULT WINAPI WIC_DllRegisterServer(void) DECLSPEC_HIDDEN;
2035 extern HRESULT WINAPI WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN;
2037 HRESULT WINAPI DllRegisterServer(void)
2039 HRESULT hr;
2041 TRACE("\n");
2043 hr = WIC_DllRegisterServer();
2044 if (SUCCEEDED(hr))
2045 hr = register_categories(category_list);
2046 if (SUCCEEDED(hr))
2047 hr = register_decoders(decoder_list);
2048 if (SUCCEEDED(hr))
2049 hr = register_encoders(encoder_list);
2050 if (SUCCEEDED(hr))
2051 hr = register_converters(converter_list);
2052 if (SUCCEEDED(hr))
2053 hr = register_metadatareaders(metadatareader_list);
2054 if (SUCCEEDED(hr))
2055 hr = register_pixelformats(pixelformat_list);
2056 return hr;
2059 HRESULT WINAPI DllUnregisterServer(void)
2061 HRESULT hr;
2063 TRACE("\n");
2065 hr = WIC_DllUnregisterServer();
2066 if (SUCCEEDED(hr))
2067 hr = unregister_categories(category_list);
2068 if (SUCCEEDED(hr))
2069 hr = unregister_decoders(decoder_list);
2070 if (SUCCEEDED(hr))
2071 hr = unregister_encoders(encoder_list);
2072 if (SUCCEEDED(hr))
2073 hr = unregister_converters(converter_list);
2074 if (SUCCEEDED(hr))
2075 hr = unregister_metadatareaders(metadatareader_list);
2076 if (SUCCEEDED(hr))
2077 hr = unregister_pixelformats(pixelformat_list);
2078 return hr;