1 /* 2 * Copyright 2009 Vincent Povirk for CodeWeavers 3 * 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. 8 * 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. 13 * 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 17 */ 18 19 #define COBJMACROS 20 #include <stdarg.h> 21 #include <string.h> 22 23 #include "windef.h" 24 #include "winbase.h" 25 #include "wingdi.h" 26 #include "winuser.h" 27 #include "winreg.h" 28 #include "winerror.h" 29 30 #include "objbase.h" 31 #include "ocidl.h" 32 33 #include "wine/debug.h" 34 #include "wine/unicode.h" 35 36 #include "wincodecs_private.h" 37 38 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); 39 40 /*********************************************************************** 41 * interface for self-registering 42 */ 43 struct decoder_pattern 44 { 45 DWORD length; /* 0 for end of list */ 46 DWORD position; 47 const BYTE *pattern; 48 const BYTE *mask; 49 DWORD endofstream; 50 }; 51 52 struct regsvr_decoder 53 { 54 CLSID const *clsid; /* NULL for end of list */ 55 LPCSTR author; 56 LPCSTR friendlyname; 57 LPCSTR version; 58 GUID const *vendor; 59 GUID const *container_format; 60 LPCSTR mimetypes; 61 LPCSTR extensions; 62 GUID const * const *formats; 63 const struct decoder_pattern *patterns; 64 }; 65 66 static HRESULT register_decoders(struct regsvr_decoder const *list); 67 static HRESULT unregister_decoders(struct regsvr_decoder const *list); 68 69 struct regsvr_encoder 70 { 71 CLSID const *clsid; /* NULL for end of list */ 72 LPCSTR author; 73 LPCSTR friendlyname; 74 LPCSTR version; 75 GUID const *vendor; 76 GUID const *container_format; 77 LPCSTR mimetypes; 78 LPCSTR extensions; 79 GUID const * const *formats; 80 }; 81 82 static HRESULT register_encoders(struct regsvr_encoder const *list); 83 static HRESULT unregister_encoders(struct regsvr_encoder const *list); 84 85 struct regsvr_converter 86 { 87 CLSID const *clsid; /* NULL for end of list */ 88 LPCSTR author; 89 LPCSTR friendlyname; 90 LPCSTR version; 91 GUID const *vendor; 92 GUID const * const *formats; 93 }; 94 95 static HRESULT register_converters(struct regsvr_converter const *list); 96 static HRESULT unregister_converters(struct regsvr_converter const *list); 97 98 struct metadata_pattern 99 { 100 DWORD position; 101 DWORD length; 102 const BYTE *pattern; 103 const BYTE *mask; 104 DWORD data_offset; 105 }; 106 107 struct reader_containers 108 { 109 GUID const *format; 110 const struct metadata_pattern *patterns; 111 }; 112 113 struct regsvr_metadatareader 114 { 115 CLSID const *clsid; /* NULL for end of list */ 116 LPCSTR author; 117 LPCSTR friendlyname; 118 LPCSTR version; 119 LPCSTR specversion; 120 GUID const *vendor; 121 GUID const *metadata_format; 122 DWORD requires_fullstream; 123 DWORD supports_padding; 124 DWORD requires_fixedsize; 125 const struct reader_containers *containers; 126 }; 127 128 static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list); 129 static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list); 130 131 struct regsvr_pixelformat 132 { 133 CLSID const *clsid; /* NULL for end of list */ 134 LPCSTR author; 135 LPCSTR friendlyname; 136 LPCSTR version; 137 GUID const *vendor; 138 UINT bitsperpixel; 139 UINT channelcount; 140 BYTE const * const *channelmasks; 141 WICPixelFormatNumericRepresentation numericrepresentation; 142 UINT supportsalpha; 143 }; 144 145 static HRESULT register_pixelformats(struct regsvr_pixelformat const *list); 146 static HRESULT unregister_pixelformats(struct regsvr_pixelformat const *list); 147 148 /*********************************************************************** 149 * static string constants 150 */ 151 static const WCHAR clsid_keyname[] = { 152 'C', 'L', 'S', 'I', 'D', 0 }; 153 static const char author_valuename[] = "Author"; 154 static const char friendlyname_valuename[] = "FriendlyName"; 155 static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0}; 156 static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0}; 157 static const char version_valuename[] = "Version"; 158 static const char mimetypes_valuename[] = "MimeTypes"; 159 static const char extensions_valuename[] = "FileExtensions"; 160 static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0}; 161 static const WCHAR patterns_keyname[] = {'P','a','t','t','e','r','n','s',0}; 162 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0}; 163 static const WCHAR clsid_valuename[] = {'C','L','S','I','D',0}; 164 static const char length_valuename[] = "Length"; 165 static const char position_valuename[] = "Position"; 166 static const char pattern_valuename[] = "Pattern"; 167 static const char mask_valuename[] = "Mask"; 168 static const char endofstream_valuename[] = "EndOfStream"; 169 static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0}; 170 static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0}; 171 static const char specversion_valuename[] = "SpecVersion"; 172 static const char requiresfullstream_valuename[] = "RequiresFullStream"; 173 static const char supportspadding_valuename[] = "SupportsPadding"; 174 static const char requiresfixedsize_valuename[] = "FixedSize"; 175 static const WCHAR containers_keyname[] = {'C','o','n','t','a','i','n','e','r','s',0}; 176 static const char dataoffset_valuename[] = "DataOffset"; 177 static const char bitsperpixel_valuename[] = "BitLength"; 178 static const char channelcount_valuename[] = "ChannelCount"; 179 static const char numericrepresentation_valuename[] = "NumericRepresentation"; 180 static const char supportstransparency_valuename[] = "SupportsTransparency"; 181 static const WCHAR channelmasks_keyname[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0}; 182 183 /*********************************************************************** 184 * register_decoders 185 */ 186 static HRESULT register_decoders(struct regsvr_decoder const *list) 187 { 188 LONG res = ERROR_SUCCESS; 189 HKEY coclass_key; 190 WCHAR buf[39]; 191 HKEY decoders_key; 192 HKEY instance_key; 193 194 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, 195 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); 196 if (res == ERROR_SUCCESS) { 197 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39); 198 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 199 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL); 200 if (res == ERROR_SUCCESS) 201 { 202 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0, 203 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL); 204 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 205 } 206 if (res != ERROR_SUCCESS) 207 RegCloseKey(coclass_key); 208 } 209 if (res != ERROR_SUCCESS) goto error_return; 210 211 for (; res == ERROR_SUCCESS && list->clsid; ++list) { 212 HKEY clsid_key; 213 HKEY instance_clsid_key; 214 215 StringFromGUID2(list->clsid, buf, 39); 216 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 217 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); 218 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 219 220 StringFromGUID2(list->clsid, buf, 39); 221 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0, 222 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL); 223 if (res == ERROR_SUCCESS) { 224 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ, 225 (const BYTE*)buf, 78); 226 RegCloseKey(instance_clsid_key); 227 } 228 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 229 230 if (list->author) { 231 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ, 232 (const BYTE*)list->author, 233 strlen(list->author) + 1); 234 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 235 } 236 237 if (list->friendlyname) { 238 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ, 239 (const BYTE*)list->friendlyname, 240 strlen(list->friendlyname) + 1); 241 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 242 } 243 244 if (list->vendor) { 245 StringFromGUID2(list->vendor, buf, 39); 246 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ, 247 (const BYTE*)buf, 78); 248 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 249 } 250 251 if (list->container_format) { 252 StringFromGUID2(list->container_format, buf, 39); 253 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ, 254 (const BYTE*)buf, 78); 255 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 256 } 257 258 if (list->version) { 259 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ, 260 (const BYTE*)list->version, 261 strlen(list->version) + 1); 262 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 263 } 264 265 if (list->mimetypes) { 266 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ, 267 (const BYTE*)list->mimetypes, 268 strlen(list->mimetypes) + 1); 269 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 270 } 271 272 if (list->extensions) { 273 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ, 274 (const BYTE*)list->extensions, 275 strlen(list->extensions) + 1); 276 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 277 } 278 279 if (list->formats) { 280 HKEY formats_key; 281 GUID const * const *format; 282 283 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0, 284 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL); 285 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 286 for (format=list->formats; *format; ++format) 287 { 288 HKEY format_key; 289 StringFromGUID2(*format, buf, 39); 290 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0, 291 KEY_READ | KEY_WRITE, NULL, &format_key, NULL); 292 if (res != ERROR_SUCCESS) break; 293 RegCloseKey(format_key); 294 } 295 RegCloseKey(formats_key); 296 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 297 } 298 299 if (list->patterns) { 300 HKEY patterns_key; 301 int i; 302 303 res = RegCreateKeyExW(clsid_key, patterns_keyname, 0, NULL, 0, 304 KEY_READ | KEY_WRITE, NULL, &patterns_key, NULL); 305 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 306 for (i=0; list->patterns[i].length; i++) 307 { 308 HKEY pattern_key; 309 static const WCHAR int_format[] = {'%','i',0}; 310 snprintfW(buf, 39, int_format, i); 311 res = RegCreateKeyExW(patterns_key, buf, 0, NULL, 0, 312 KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL); 313 if (res != ERROR_SUCCESS) break; 314 res = RegSetValueExA(pattern_key, length_valuename, 0, REG_DWORD, 315 (const BYTE*)&list->patterns[i].length, 4); 316 if (res == ERROR_SUCCESS) 317 res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD, 318 (const BYTE*)&list->patterns[i].position, 4); 319 if (res == ERROR_SUCCESS) 320 res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY, 321 list->patterns[i].pattern, 322 list->patterns[i].length); 323 if (res == ERROR_SUCCESS) 324 res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY, 325 list->patterns[i].mask, 326 list->patterns[i].length); 327 if (res == ERROR_SUCCESS) 328 res = RegSetValueExA(pattern_key, endofstream_valuename, 0, REG_DWORD, 329 (const BYTE*)&list->patterns[i].endofstream, 4); 330 RegCloseKey(pattern_key); 331 } 332 RegCloseKey(patterns_key); 333 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 334 } 335 336 error_close_clsid_key: 337 RegCloseKey(clsid_key); 338 } 339 340 error_close_coclass_key: 341 RegCloseKey(instance_key); 342 RegCloseKey(decoders_key); 343 RegCloseKey(coclass_key); 344 error_return: 345 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 346 } 347 348 /*********************************************************************** 349 * unregister_decoders 350 */ 351 static HRESULT unregister_decoders(struct regsvr_decoder const *list) 352 { 353 LONG res = ERROR_SUCCESS; 354 HKEY coclass_key; 355 WCHAR buf[39]; 356 HKEY decoders_key; 357 HKEY instance_key; 358 359 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, 360 KEY_READ | KEY_WRITE, &coclass_key); 361 if (res == ERROR_FILE_NOT_FOUND) return S_OK; 362 363 if (res == ERROR_SUCCESS) { 364 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39); 365 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 366 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL); 367 if (res == ERROR_SUCCESS) 368 { 369 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0, 370 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL); 371 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 372 } 373 if (res != ERROR_SUCCESS) 374 RegCloseKey(coclass_key); 375 } 376 if (res != ERROR_SUCCESS) goto error_return; 377 378 for (; res == ERROR_SUCCESS && list->clsid; ++list) { 379 StringFromGUID2(list->clsid, buf, 39); 380 381 res = RegDeleteTreeW(coclass_key, buf); 382 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 383 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 384 385 res = RegDeleteTreeW(instance_key, buf); 386 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 387 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 388 } 389 390 error_close_coclass_key: 391 RegCloseKey(instance_key); 392 RegCloseKey(decoders_key); 393 RegCloseKey(coclass_key); 394 error_return: 395 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 396 } 397 398 /*********************************************************************** 399 * register_encoders 400 */ 401 static HRESULT register_encoders(struct regsvr_encoder const *list) 402 { 403 LONG res = ERROR_SUCCESS; 404 HKEY coclass_key; 405 WCHAR buf[39]; 406 HKEY encoders_key; 407 HKEY instance_key; 408 409 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, 410 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); 411 if (res == ERROR_SUCCESS) { 412 StringFromGUID2(&CATID_WICBitmapEncoders, buf, 39); 413 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 414 KEY_READ | KEY_WRITE, NULL, &encoders_key, NULL); 415 if (res == ERROR_SUCCESS) 416 { 417 res = RegCreateKeyExW(encoders_key, instance_keyname, 0, NULL, 0, 418 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL); 419 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 420 } 421 if (res != ERROR_SUCCESS) 422 RegCloseKey(coclass_key); 423 } 424 if (res != ERROR_SUCCESS) goto error_return; 425 426 for (; res == ERROR_SUCCESS && list->clsid; ++list) { 427 HKEY clsid_key; 428 HKEY instance_clsid_key; 429 430 StringFromGUID2(list->clsid, buf, 39); 431 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 432 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); 433 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 434 435 StringFromGUID2(list->clsid, buf, 39); 436 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0, 437 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL); 438 if (res == ERROR_SUCCESS) { 439 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ, 440 (const BYTE*)buf, 78); 441 RegCloseKey(instance_clsid_key); 442 } 443 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 444 445 if (list->author) { 446 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ, 447 (const BYTE*)list->author, 448 strlen(list->author) + 1); 449 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 450 } 451 452 if (list->friendlyname) { 453 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ, 454 (const BYTE*)list->friendlyname, 455 strlen(list->friendlyname) + 1); 456 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 457 } 458 459 if (list->vendor) { 460 StringFromGUID2(list->vendor, buf, 39); 461 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ, 462 (const BYTE*)buf, 78); 463 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 464 } 465 466 if (list->container_format) { 467 StringFromGUID2(list->container_format, buf, 39); 468 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ, 469 (const BYTE*)buf, 78); 470 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 471 } 472 473 if (list->version) { 474 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ, 475 (const BYTE*)list->version, 476 strlen(list->version) + 1); 477 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 478 } 479 480 if (list->mimetypes) { 481 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ, 482 (const BYTE*)list->mimetypes, 483 strlen(list->mimetypes) + 1); 484 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 485 } 486 487 if (list->extensions) { 488 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ, 489 (const BYTE*)list->extensions, 490 strlen(list->extensions) + 1); 491 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 492 } 493 494 if (list->formats) { 495 HKEY formats_key; 496 GUID const * const *format; 497 498 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0, 499 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL); 500 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 501 for (format=list->formats; *format; ++format) 502 { 503 HKEY format_key; 504 StringFromGUID2(*format, buf, 39); 505 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0, 506 KEY_READ | KEY_WRITE, NULL, &format_key, NULL); 507 if (res != ERROR_SUCCESS) break; 508 RegCloseKey(format_key); 509 } 510 RegCloseKey(formats_key); 511 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 512 } 513 514 error_close_clsid_key: 515 RegCloseKey(clsid_key); 516 } 517 518 error_close_coclass_key: 519 RegCloseKey(instance_key); 520 RegCloseKey(encoders_key); 521 RegCloseKey(coclass_key); 522 error_return: 523 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 524 } 525 526 /*********************************************************************** 527 * unregister_encoders 528 */ 529 static HRESULT unregister_encoders(struct regsvr_encoder const *list) 530 { 531 LONG res = ERROR_SUCCESS; 532 HKEY coclass_key; 533 WCHAR buf[39]; 534 HKEY encoders_key; 535 HKEY instance_key; 536 537 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, 538 KEY_READ | KEY_WRITE, &coclass_key); 539 if (res == ERROR_FILE_NOT_FOUND) return S_OK; 540 541 if (res == ERROR_SUCCESS) { 542 StringFromGUID2(&CATID_WICBitmapEncoders, buf, 39); 543 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 544 KEY_READ | KEY_WRITE, NULL, &encoders_key, NULL); 545 if (res == ERROR_SUCCESS) 546 { 547 res = RegCreateKeyExW(encoders_key, instance_keyname, 0, NULL, 0, 548 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL); 549 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 550 } 551 if (res != ERROR_SUCCESS) 552 RegCloseKey(coclass_key); 553 } 554 if (res != ERROR_SUCCESS) goto error_return; 555 556 for (; res == ERROR_SUCCESS && list->clsid; ++list) { 557 StringFromGUID2(list->clsid, buf, 39); 558 559 res = RegDeleteTreeW(coclass_key, buf); 560 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 561 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 562 563 res = RegDeleteTreeW(instance_key, buf); 564 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 565 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 566 } 567 568 error_close_coclass_key: 569 RegCloseKey(instance_key); 570 RegCloseKey(encoders_key); 571 RegCloseKey(coclass_key); 572 error_return: 573 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 574 } 575 576 /*********************************************************************** 577 * register_converters 578 */ 579 static HRESULT register_converters(struct regsvr_converter const *list) 580 { 581 LONG res = ERROR_SUCCESS; 582 HKEY coclass_key; 583 WCHAR buf[39]; 584 HKEY converters_key; 585 HKEY instance_key; 586 587 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, 588 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); 589 if (res == ERROR_SUCCESS) { 590 StringFromGUID2(&CATID_WICFormatConverters, buf, 39); 591 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 592 KEY_READ | KEY_WRITE, NULL, &converters_key, NULL); 593 if (res == ERROR_SUCCESS) 594 { 595 res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0, 596 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL); 597 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 598 } 599 if (res != ERROR_SUCCESS) 600 RegCloseKey(coclass_key); 601 } 602 if (res != ERROR_SUCCESS) goto error_return; 603 604 for (; res == ERROR_SUCCESS && list->clsid; ++list) { 605 HKEY clsid_key; 606 HKEY instance_clsid_key; 607 608 StringFromGUID2(list->clsid, buf, 39); 609 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 610 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); 611 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 612 613 StringFromGUID2(list->clsid, buf, 39); 614 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0, 615 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL); 616 if (res == ERROR_SUCCESS) { 617 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ, 618 (const BYTE*)buf, 78); 619 RegCloseKey(instance_clsid_key); 620 } 621 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 622 623 if (list->author) { 624 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ, 625 (const BYTE*)list->author, 626 strlen(list->author) + 1); 627 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 628 } 629 630 if (list->friendlyname) { 631 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ, 632 (const BYTE*)list->friendlyname, 633 strlen(list->friendlyname) + 1); 634 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 635 } 636 637 if (list->vendor) { 638 StringFromGUID2(list->vendor, buf, 39); 639 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ, 640 (const BYTE*)buf, 78); 641 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 642 } 643 644 if (list->version) { 645 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ, 646 (const BYTE*)list->version, 647 strlen(list->version) + 1); 648 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 649 } 650 651 if (list->formats) { 652 HKEY formats_key; 653 GUID const * const *format; 654 655 res = RegCreateKeyExW(clsid_key, pixelformats_keyname, 0, NULL, 0, 656 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL); 657 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 658 for (format=list->formats; *format; ++format) 659 { 660 HKEY format_key; 661 StringFromGUID2(*format, buf, 39); 662 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0, 663 KEY_READ | KEY_WRITE, NULL, &format_key, NULL); 664 if (res != ERROR_SUCCESS) break; 665 RegCloseKey(format_key); 666 } 667 RegCloseKey(formats_key); 668 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 669 } 670 671 error_close_clsid_key: 672 RegCloseKey(clsid_key); 673 } 674 675 error_close_coclass_key: 676 RegCloseKey(instance_key); 677 RegCloseKey(converters_key); 678 RegCloseKey(coclass_key); 679 error_return: 680 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 681 } 682 683 /*********************************************************************** 684 * unregister_converters 685 */ 686 static HRESULT unregister_converters(struct regsvr_converter const *list) 687 { 688 LONG res = ERROR_SUCCESS; 689 HKEY coclass_key; 690 WCHAR buf[39]; 691 HKEY converters_key; 692 HKEY instance_key; 693 694 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, 695 KEY_READ | KEY_WRITE, &coclass_key); 696 if (res == ERROR_FILE_NOT_FOUND) return S_OK; 697 698 if (res == ERROR_SUCCESS) { 699 StringFromGUID2(&CATID_WICFormatConverters, buf, 39); 700 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 701 KEY_READ | KEY_WRITE, NULL, &converters_key, NULL); 702 if (res == ERROR_SUCCESS) 703 { 704 res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0, 705 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL); 706 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 707 } 708 if (res != ERROR_SUCCESS) 709 RegCloseKey(coclass_key); 710 } 711 if (res != ERROR_SUCCESS) goto error_return; 712 713 for (; res == ERROR_SUCCESS && list->clsid; ++list) { 714 StringFromGUID2(list->clsid, buf, 39); 715 716 res = RegDeleteTreeW(coclass_key, buf); 717 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 718 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 719 720 res = RegDeleteTreeW(instance_key, buf); 721 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 722 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 723 } 724 725 error_close_coclass_key: 726 RegCloseKey(instance_key); 727 RegCloseKey(converters_key); 728 RegCloseKey(coclass_key); 729 error_return: 730 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 731 } 732 733 /*********************************************************************** 734 * register_metadatareaders 735 */ 736 static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list) 737 { 738 LONG res = ERROR_SUCCESS; 739 HKEY coclass_key; 740 WCHAR buf[39]; 741 HKEY readers_key; 742 HKEY instance_key; 743 744 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, 745 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); 746 if (res == ERROR_SUCCESS) { 747 StringFromGUID2(&CATID_WICMetadataReader, buf, 39); 748 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 749 KEY_READ | KEY_WRITE, NULL, &readers_key, NULL); 750 if (res == ERROR_SUCCESS) 751 { 752 res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0, 753 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL); 754 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 755 } 756 if (res != ERROR_SUCCESS) 757 RegCloseKey(coclass_key); 758 } 759 if (res != ERROR_SUCCESS) goto error_return; 760 761 for (; res == ERROR_SUCCESS && list->clsid; ++list) { 762 HKEY clsid_key; 763 HKEY instance_clsid_key; 764 765 StringFromGUID2(list->clsid, buf, 39); 766 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 767 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); 768 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 769 770 StringFromGUID2(list->clsid, buf, 39); 771 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0, 772 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL); 773 if (res == ERROR_SUCCESS) { 774 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ, 775 (const BYTE*)buf, 78); 776 RegCloseKey(instance_clsid_key); 777 } 778 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 779 780 if (list->author) { 781 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ, 782 (const BYTE*)list->author, 783 strlen(list->author) + 1); 784 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 785 } 786 787 if (list->friendlyname) { 788 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ, 789 (const BYTE*)list->friendlyname, 790 strlen(list->friendlyname) + 1); 791 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 792 } 793 794 if (list->vendor) { 795 StringFromGUID2(list->vendor, buf, 39); 796 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ, 797 (const BYTE*)buf, 78); 798 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 799 } 800 801 if (list->metadata_format) { 802 StringFromGUID2(list->metadata_format, buf, 39); 803 res = RegSetValueExW(clsid_key, metadataformat_valuename, 0, REG_SZ, 804 (const BYTE*)buf, 78); 805 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 806 } 807 808 if (list->version) { 809 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ, 810 (const BYTE*)list->version, 811 strlen(list->version) + 1); 812 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 813 } 814 815 if (list->specversion) { 816 res = RegSetValueExA(clsid_key, specversion_valuename, 0, REG_SZ, 817 (const BYTE*)list->version, 818 strlen(list->version) + 1); 819 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 820 } 821 822 res = RegSetValueExA(clsid_key, requiresfullstream_valuename, 0, REG_DWORD, 823 (const BYTE*)&list->requires_fullstream, 4); 824 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 825 826 res = RegSetValueExA(clsid_key, supportspadding_valuename, 0, REG_DWORD, 827 (const BYTE*)&list->supports_padding, 4); 828 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 829 830 if (list->requires_fixedsize) { 831 res = RegSetValueExA(clsid_key, requiresfixedsize_valuename, 0, REG_DWORD, 832 (const BYTE*)&list->requires_fixedsize, 4); 833 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 834 } 835 836 if (list->containers) { 837 HKEY containers_key; 838 const struct reader_containers *container; 839 840 res = RegCreateKeyExW(clsid_key, containers_keyname, 0, NULL, 0, 841 KEY_READ | KEY_WRITE, NULL, &containers_key, NULL); 842 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 843 for (container=list->containers; container->format; ++container) 844 { 845 HKEY format_key; 846 int i; 847 StringFromGUID2(container->format, buf, 39); 848 res = RegCreateKeyExW(containers_key, buf, 0, NULL, 0, 849 KEY_READ | KEY_WRITE, NULL, &format_key, NULL); 850 if (res != ERROR_SUCCESS) break; 851 852 for (i=0; container->patterns[i].length; i++) 853 { 854 HKEY pattern_key; 855 static const WCHAR int_format[] = {'%','i',0}; 856 snprintfW(buf, 39, int_format, i); 857 res = RegCreateKeyExW(format_key, buf, 0, NULL, 0, 858 KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL); 859 if (res != ERROR_SUCCESS) break; 860 res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD, 861 (const BYTE*)&container->patterns[i].position, 4); 862 if (res == ERROR_SUCCESS) 863 res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY, 864 container->patterns[i].pattern, 865 container->patterns[i].length); 866 if (res == ERROR_SUCCESS) 867 res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY, 868 container->patterns[i].mask, 869 container->patterns[i].length); 870 if (res == ERROR_SUCCESS && container->patterns[i].data_offset) 871 res = RegSetValueExA(pattern_key, dataoffset_valuename, 0, REG_DWORD, 872 (const BYTE*)&container->patterns[i].data_offset, 4); 873 RegCloseKey(pattern_key); 874 } 875 876 RegCloseKey(format_key); 877 } 878 RegCloseKey(containers_key); 879 } 880 881 error_close_clsid_key: 882 RegCloseKey(clsid_key); 883 } 884 885 error_close_coclass_key: 886 RegCloseKey(instance_key); 887 RegCloseKey(readers_key); 888 RegCloseKey(coclass_key); 889 error_return: 890 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 891 } 892 893 /*********************************************************************** 894 * unregister_metadatareaders 895 */ 896 static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list) 897 { 898 LONG res = ERROR_SUCCESS; 899 HKEY coclass_key; 900 WCHAR buf[39]; 901 HKEY readers_key; 902 HKEY instance_key; 903 904 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, 905 KEY_READ | KEY_WRITE, &coclass_key); 906 if (res == ERROR_FILE_NOT_FOUND) return S_OK; 907 908 if (res == ERROR_SUCCESS) { 909 StringFromGUID2(&CATID_WICMetadataReader, buf, 39); 910 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 911 KEY_READ | KEY_WRITE, NULL, &readers_key, NULL); 912 if (res == ERROR_SUCCESS) 913 { 914 res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0, 915 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL); 916 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 917 } 918 if (res != ERROR_SUCCESS) 919 RegCloseKey(coclass_key); 920 } 921 if (res != ERROR_SUCCESS) goto error_return; 922 923 for (; res == ERROR_SUCCESS && list->clsid; ++list) { 924 StringFromGUID2(list->clsid, buf, 39); 925 926 res = RegDeleteTreeW(coclass_key, buf); 927 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 928 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 929 930 res = RegDeleteTreeW(instance_key, buf); 931 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 932 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 933 } 934 935 error_close_coclass_key: 936 RegCloseKey(instance_key); 937 RegCloseKey(readers_key); 938 RegCloseKey(coclass_key); 939 error_return: 940 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 941 } 942 943 /*********************************************************************** 944 * register_pixelformats 945 */ 946 static HRESULT register_pixelformats(struct regsvr_pixelformat const *list) 947 { 948 LONG res = ERROR_SUCCESS; 949 HKEY coclass_key; 950 WCHAR buf[39]; 951 HKEY formats_key; 952 HKEY instance_key; 953 954 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, 955 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); 956 if (res == ERROR_SUCCESS) { 957 StringFromGUID2(&CATID_WICPixelFormats, buf, 39); 958 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 959 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL); 960 if (res == ERROR_SUCCESS) 961 { 962 res = RegCreateKeyExW(formats_key, instance_keyname, 0, NULL, 0, 963 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL); 964 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 965 } 966 if (res != ERROR_SUCCESS) 967 RegCloseKey(coclass_key); 968 } 969 if (res != ERROR_SUCCESS) goto error_return; 970 971 for (; res == ERROR_SUCCESS && list->clsid; ++list) { 972 HKEY clsid_key; 973 HKEY instance_clsid_key; 974 975 StringFromGUID2(list->clsid, buf, 39); 976 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 977 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); 978 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 979 980 StringFromGUID2(list->clsid, buf, 39); 981 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0, 982 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL); 983 if (res == ERROR_SUCCESS) { 984 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ, 985 (const BYTE*)buf, 78); 986 RegCloseKey(instance_clsid_key); 987 } 988 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 989 990 if (list->author) { 991 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ, 992 (const BYTE*)list->author, 993 strlen(list->author) + 1); 994 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 995 } 996 997 if (list->friendlyname) { 998 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ, 999 (const BYTE*)list->friendlyname, 1000 strlen(list->friendlyname) + 1); 1001 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 1002 } 1003 1004 if (list->vendor) { 1005 StringFromGUID2(list->vendor, buf, 39); 1006 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ, 1007 (const BYTE*)buf, 78); 1008 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 1009 } 1010 1011 if (list->version) { 1012 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ, 1013 (const BYTE*)list->version, 1014 strlen(list->version) + 1); 1015 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 1016 } 1017 1018 res = RegSetValueExA(clsid_key, bitsperpixel_valuename, 0, REG_DWORD, 1019 (const BYTE*)&list->bitsperpixel, 4); 1020 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 1021 1022 res = RegSetValueExA(clsid_key, channelcount_valuename, 0, REG_DWORD, 1023 (const BYTE*)&list->channelcount, 4); 1024 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 1025 1026 res = RegSetValueExA(clsid_key, numericrepresentation_valuename, 0, REG_DWORD, 1027 (const BYTE*)&list->numericrepresentation, 4); 1028 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 1029 1030 res = RegSetValueExA(clsid_key, supportstransparency_valuename, 0, REG_DWORD, 1031 (const BYTE*)&list->supportsalpha, 4); 1032 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 1033 1034 if (list->channelmasks) { 1035 static const WCHAR valuename_format[] = {'%','d',0}; 1036 HKEY masks_key; 1037 UINT i, mask_size; 1038 WCHAR mask_valuename[11]; 1039 1040 mask_size = (list->bitsperpixel + 7)/8; 1041 1042 res = RegCreateKeyExW(clsid_key, channelmasks_keyname, 0, NULL, 0, 1043 KEY_READ | KEY_WRITE, NULL, &masks_key, NULL); 1044 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 1045 for (i=0; i < list->channelcount; i++) 1046 { 1047 sprintfW(mask_valuename, valuename_format, i); 1048 res = RegSetValueExW(masks_key, mask_valuename, 0, REG_BINARY, 1049 list->channelmasks[i], mask_size); 1050 if (res != ERROR_SUCCESS) break; 1051 } 1052 RegCloseKey(masks_key); 1053 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 1054 } 1055 1056 error_close_clsid_key: 1057 RegCloseKey(clsid_key); 1058 } 1059 1060 error_close_coclass_key: 1061 RegCloseKey(instance_key); 1062 RegCloseKey(formats_key); 1063 RegCloseKey(coclass_key); 1064 error_return: 1065 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 1066 } 1067 1068 /*********************************************************************** 1069 * unregister_pixelformats 1070 */ 1071 static HRESULT unregister_pixelformats(struct regsvr_pixelformat const *list) 1072 { 1073 LONG res = ERROR_SUCCESS; 1074 HKEY coclass_key; 1075 WCHAR buf[39]; 1076 HKEY formats_key; 1077 HKEY instance_key; 1078 1079 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, 1080 KEY_READ | KEY_WRITE, &coclass_key); 1081 if (res == ERROR_FILE_NOT_FOUND) return S_OK; 1082 1083 if (res == ERROR_SUCCESS) { 1084 StringFromGUID2(&CATID_WICPixelFormats, buf, 39); 1085 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 1086 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL); 1087 if (res == ERROR_SUCCESS) 1088 { 1089 res = RegCreateKeyExW(formats_key, instance_keyname, 0, NULL, 0, 1090 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL); 1091 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 1092 } 1093 if (res != ERROR_SUCCESS) 1094 RegCloseKey(coclass_key); 1095 } 1096 if (res != ERROR_SUCCESS) goto error_return; 1097 1098 for (; res == ERROR_SUCCESS && list->clsid; ++list) { 1099 StringFromGUID2(list->clsid, buf, 39); 1100 1101 res = RegDeleteTreeW(coclass_key, buf); 1102 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 1103 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 1104 1105 res = RegDeleteTreeW(instance_key, buf); 1106 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 1107 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 1108 } 1109 1110 error_close_coclass_key: 1111 RegCloseKey(instance_key); 1112 RegCloseKey(formats_key); 1113 RegCloseKey(coclass_key); 1114 error_return: 1115 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 1116 } 1117 1118 /*********************************************************************** 1119 * decoder list 1120 */ 1121 static const BYTE mask_all[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; 1122 1123 static const BYTE bmp_magic[] = {0x42,0x4d}; 1124 1125 static GUID const * const bmp_formats[] = { 1126 &GUID_WICPixelFormat1bppIndexed, 1127 &GUID_WICPixelFormat2bppIndexed, 1128 &GUID_WICPixelFormat4bppIndexed, 1129 &GUID_WICPixelFormat8bppIndexed, 1130 &GUID_WICPixelFormat16bppBGR555, 1131 &GUID_WICPixelFormat16bppBGR565, 1132 &GUID_WICPixelFormat24bppBGR, 1133 &GUID_WICPixelFormat32bppBGR, 1134 &GUID_WICPixelFormat32bppBGRA, 1135 NULL 1136 }; 1137 1138 static struct decoder_pattern const bmp_patterns[] = { 1139 {2,0,bmp_magic,mask_all,0}, 1140 {0} 1141 }; 1142 1143 static const BYTE gif87a_magic[6] = "GIF87a"; 1144 static const BYTE gif89a_magic[6] = "GIF89a"; 1145 1146 static GUID const * const gif_formats[] = { 1147 &GUID_WICPixelFormat8bppIndexed, 1148 NULL 1149 }; 1150 1151 static struct decoder_pattern const gif_patterns[] = { 1152 {6,0,gif87a_magic,mask_all,0}, 1153 {6,0,gif89a_magic,mask_all,0}, 1154 {0} 1155 }; 1156 1157 static const BYTE ico_magic[] = {00,00,01,00}; 1158 1159 static GUID const * const ico_formats[] = { 1160 &GUID_WICPixelFormat32bppBGRA, 1161 NULL 1162 }; 1163 1164 static struct decoder_pattern const ico_patterns[] = { 1165 {4,0,ico_magic,mask_all,0}, 1166 {0} 1167 }; 1168 1169 static const BYTE jpeg_magic[] = {0xff, 0xd8}; 1170 1171 static GUID const * const jpeg_formats[] = { 1172 &GUID_WICPixelFormat24bppBGR, 1173 &GUID_WICPixelFormat32bppCMYK, 1174 &GUID_WICPixelFormat8bppGray, 1175 NULL 1176 }; 1177 1178 static struct decoder_pattern const jpeg_patterns[] = { 1179 {2,0,jpeg_magic,mask_all,0}, 1180 {0} 1181 }; 1182 1183 static const BYTE png_magic[] = {137,80,78,71,13,10,26,10}; 1184 1185 static GUID const * const png_formats[] = { 1186 &GUID_WICPixelFormatBlackWhite, 1187 &GUID_WICPixelFormat2bppGray, 1188 &GUID_WICPixelFormat4bppGray, 1189 &GUID_WICPixelFormat8bppGray, 1190 &GUID_WICPixelFormat16bppGray, 1191 &GUID_WICPixelFormat32bppBGRA, 1192 &GUID_WICPixelFormat64bppRGBA, 1193 &GUID_WICPixelFormat1bppIndexed, 1194 &GUID_WICPixelFormat2bppIndexed, 1195 &GUID_WICPixelFormat4bppIndexed, 1196 &GUID_WICPixelFormat8bppIndexed, 1197 &GUID_WICPixelFormat24bppBGR, 1198 &GUID_WICPixelFormat48bppRGB, 1199 NULL 1200 }; 1201 1202 static struct decoder_pattern const png_patterns[] = { 1203 {8,0,png_magic,mask_all,0}, 1204 {0} 1205 }; 1206 1207 static const BYTE tiff_magic_le[] = {0x49,0x49,42,0}; 1208 static const BYTE tiff_magic_be[] = {0x4d,0x4d,0,42}; 1209 1210 static GUID const * const tiff_decode_formats[] = { 1211 &GUID_WICPixelFormatBlackWhite, 1212 &GUID_WICPixelFormat4bppGray, 1213 &GUID_WICPixelFormat8bppGray, 1214 &GUID_WICPixelFormat16bppGray, 1215 &GUID_WICPixelFormat32bppGrayFloat, 1216 &GUID_WICPixelFormat1bppIndexed, 1217 &GUID_WICPixelFormat2bppIndexed, 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 &GUID_WICPixelFormat32bppCMYK, 1228 &GUID_WICPixelFormat64bppCMYK, 1229 &GUID_WICPixelFormat128bppRGBAFloat, 1230 NULL 1231 }; 1232 1233 static struct decoder_pattern const tiff_patterns[] = { 1234 {4,0,tiff_magic_le,mask_all,0}, 1235 {4,0,tiff_magic_be,mask_all,0}, 1236 {0} 1237 }; 1238 1239 static const BYTE tga_footer_magic[18] = "TRUEVISION-XFILE."; 1240 1241 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}; 1242 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}; 1243 1244 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}; 1245 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}; 1246 1247 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}; 1248 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}; 1249 1250 static GUID const * const tga_formats[] = { 1251 &GUID_WICPixelFormat8bppGray, 1252 &GUID_WICPixelFormat8bppIndexed, 1253 &GUID_WICPixelFormat16bppGray, 1254 &GUID_WICPixelFormat16bppBGR555, 1255 &GUID_WICPixelFormat24bppBGR, 1256 &GUID_WICPixelFormat32bppBGRA, 1257 &GUID_WICPixelFormat32bppPBGRA, 1258 NULL 1259 }; 1260 1261 static struct decoder_pattern const tga_patterns[] = { 1262 {18,18,tga_footer_magic,mask_all,1}, 1263 {18,0,tga_indexed_magic,tga_indexed_mask,0}, 1264 {18,0,tga_truecolor_magic,tga_truecolor_mask,0}, 1265 {18,0,tga_grayscale_magic,tga_grayscale_mask,0}, 1266 {0} 1267 }; 1268 1269 static struct regsvr_decoder const decoder_list[] = { 1270 { &CLSID_WICBmpDecoder, 1271 "The Wine Project", 1272 "BMP Decoder", 1273 "1.0.0.0", 1274 &GUID_VendorMicrosoft, 1275 &GUID_ContainerFormatBmp, 1276 "image/bmp", 1277 ".bmp,.dib,.rle", 1278 bmp_formats, 1279 bmp_patterns 1280 }, 1281 { &CLSID_WICGifDecoder, 1282 "The Wine Project", 1283 "GIF Decoder", 1284 "1.0.0.0", 1285 &GUID_VendorMicrosoft, 1286 &GUID_ContainerFormatGif, 1287 "image/gif", 1288 ".gif", 1289 gif_formats, 1290 gif_patterns 1291 }, 1292 { &CLSID_WICIcoDecoder, 1293 "The Wine Project", 1294 "ICO Decoder", 1295 "1.0.0.0", 1296 &GUID_VendorMicrosoft, 1297 &GUID_ContainerFormatIco, 1298 "image/vnd.microsoft.icon", 1299 ".ico", 1300 ico_formats, 1301 ico_patterns 1302 }, 1303 { &CLSID_WICJpegDecoder, 1304 "The Wine Project", 1305 "JPEG Decoder", 1306 "1.0.0.0", 1307 &GUID_VendorMicrosoft, 1308 &GUID_ContainerFormatJpeg, 1309 "image/jpeg", 1310 ".jpg;.jpeg;.jfif", 1311 jpeg_formats, 1312 jpeg_patterns 1313 }, 1314 { &CLSID_WICPngDecoder, 1315 "The Wine Project", 1316 "PNG Decoder", 1317 "1.0.0.0", 1318 &GUID_VendorMicrosoft, 1319 &GUID_ContainerFormatPng, 1320 "image/png", 1321 ".png", 1322 png_formats, 1323 png_patterns 1324 }, 1325 { &CLSID_WICTiffDecoder, 1326 "The Wine Project", 1327 "TIFF Decoder", 1328 "1.0.0.0", 1329 &GUID_VendorMicrosoft, 1330 &GUID_ContainerFormatTiff, 1331 "image/tiff", 1332 ".tif;.tiff", 1333 tiff_decode_formats, 1334 tiff_patterns 1335 }, 1336 { &CLSID_WineTgaDecoder, 1337 "The Wine Project", 1338 "TGA Decoder", 1339 "1.0.0.0", 1340 &GUID_VendorWine, 1341 &GUID_WineContainerFormatTga, 1342 "image/x-targa", 1343 ".tga;.tpic", 1344 tga_formats, 1345 tga_patterns 1346 }, 1347 { NULL } /* list terminator */ 1348 }; 1349 1350 static GUID const * const bmp_encode_formats[] = { 1351 &GUID_WICPixelFormat16bppBGR555, 1352 &GUID_WICPixelFormat16bppBGR565, 1353 &GUID_WICPixelFormat24bppBGR, 1354 &GUID_WICPixelFormat32bppBGR, 1355 &GUID_WICPixelFormatBlackWhite, 1356 &GUID_WICPixelFormat1bppIndexed, 1357 &GUID_WICPixelFormat4bppIndexed, 1358 &GUID_WICPixelFormat8bppIndexed, 1359 NULL 1360 }; 1361 1362 static GUID const * const png_encode_formats[] = { 1363 &GUID_WICPixelFormat24bppBGR, 1364 &GUID_WICPixelFormatBlackWhite, 1365 &GUID_WICPixelFormat2bppGray, 1366 &GUID_WICPixelFormat4bppGray, 1367 &GUID_WICPixelFormat8bppGray, 1368 &GUID_WICPixelFormat16bppGray, 1369 &GUID_WICPixelFormat32bppBGR, 1370 &GUID_WICPixelFormat32bppBGRA, 1371 &GUID_WICPixelFormat48bppRGB, 1372 &GUID_WICPixelFormat64bppRGBA, 1373 &GUID_WICPixelFormat1bppIndexed, 1374 &GUID_WICPixelFormat2bppIndexed, 1375 &GUID_WICPixelFormat4bppIndexed, 1376 &GUID_WICPixelFormat8bppIndexed, 1377 NULL 1378 }; 1379 1380 static GUID const * const tiff_encode_formats[] = { 1381 &GUID_WICPixelFormatBlackWhite, 1382 &GUID_WICPixelFormat4bppGray, 1383 &GUID_WICPixelFormat8bppGray, 1384 &GUID_WICPixelFormat1bppIndexed, 1385 &GUID_WICPixelFormat4bppIndexed, 1386 &GUID_WICPixelFormat8bppIndexed, 1387 &GUID_WICPixelFormat24bppBGR, 1388 &GUID_WICPixelFormat32bppBGRA, 1389 &GUID_WICPixelFormat32bppPBGRA, 1390 &GUID_WICPixelFormat48bppRGB, 1391 &GUID_WICPixelFormat64bppRGBA, 1392 &GUID_WICPixelFormat64bppPRGBA, 1393 NULL 1394 }; 1395 1396 static GUID const * const icns_encode_formats[] = { 1397 &GUID_WICPixelFormat32bppBGRA, 1398 NULL 1399 }; 1400 1401 static struct regsvr_encoder const encoder_list[] = { 1402 { &CLSID_WICBmpEncoder, 1403 "The Wine Project", 1404 "BMP Encoder", 1405 "1.0.0.0", 1406 &GUID_VendorMicrosoft, 1407 &GUID_ContainerFormatBmp, 1408 "image/bmp", 1409 ".bmp,.dib,.rle", 1410 bmp_encode_formats 1411 }, 1412 { &CLSID_WICGifEncoder, 1413 "The Wine Project", 1414 "GIF Encoder", 1415 "1.0.0.0", 1416 &GUID_VendorMicrosoft, 1417 &GUID_ContainerFormatGif, 1418 "image/gif", 1419 ".gif", 1420 gif_formats 1421 }, 1422 { &CLSID_WICJpegEncoder, 1423 "The Wine Project", 1424 "JPEG Encoder", 1425 "1.0.0.0", 1426 &GUID_VendorMicrosoft, 1427 &GUID_ContainerFormatJpeg, 1428 "image/jpeg", 1429 ".jpg;.jpeg;.jfif", 1430 jpeg_formats 1431 }, 1432 { &CLSID_WICPngEncoder, 1433 "The Wine Project", 1434 "PNG Encoder", 1435 "1.0.0.0", 1436 &GUID_VendorMicrosoft, 1437 &GUID_ContainerFormatPng, 1438 "image/png", 1439 ".png", 1440 png_encode_formats 1441 }, 1442 { &CLSID_WICTiffEncoder, 1443 "The Wine Project", 1444 "TIFF Encoder", 1445 "1.0.0.0", 1446 &GUID_VendorMicrosoft, 1447 &GUID_ContainerFormatTiff, 1448 "image/tiff", 1449 ".tif;.tiff", 1450 tiff_encode_formats 1451 }, 1452 { &CLSID_WICIcnsEncoder, 1453 "The Wine Project", 1454 "ICNS Encoder", 1455 "1.0.0.0", 1456 &GUID_VendorWine, 1457 NULL, /* no container format guid */ 1458 "image/icns", 1459 ".icns", 1460 icns_encode_formats 1461 }, 1462 { NULL } /* list terminator */ 1463 }; 1464 1465 static GUID const * const converter_formats[] = { 1466 &GUID_WICPixelFormat1bppIndexed, 1467 &GUID_WICPixelFormat2bppIndexed, 1468 &GUID_WICPixelFormat4bppIndexed, 1469 &GUID_WICPixelFormat8bppIndexed, 1470 &GUID_WICPixelFormatBlackWhite, 1471 &GUID_WICPixelFormat2bppGray, 1472 &GUID_WICPixelFormat4bppGray, 1473 &GUID_WICPixelFormat8bppGray, 1474 &GUID_WICPixelFormat16bppGray, 1475 &GUID_WICPixelFormat16bppBGR555, 1476 &GUID_WICPixelFormat16bppBGR565, 1477 &GUID_WICPixelFormat16bppBGRA5551, 1478 &GUID_WICPixelFormat24bppBGR, 1479 &GUID_WICPixelFormat24bppRGB, 1480 &GUID_WICPixelFormat32bppBGR, 1481 &GUID_WICPixelFormat32bppRGB, 1482 &GUID_WICPixelFormat32bppBGRA, 1483 &GUID_WICPixelFormat32bppRGBA, 1484 &GUID_WICPixelFormat32bppPBGRA, 1485 &GUID_WICPixelFormat32bppPRGBA, 1486 &GUID_WICPixelFormat32bppGrayFloat, 1487 &GUID_WICPixelFormat48bppRGB, 1488 &GUID_WICPixelFormat64bppRGBA, 1489 &GUID_WICPixelFormat32bppCMYK, 1490 NULL 1491 }; 1492 1493 static struct regsvr_converter const converter_list[] = { 1494 { &CLSID_WICDefaultFormatConverter, 1495 "The Wine Project", 1496 "Default Pixel Format Converter", 1497 "1.0.0.0", 1498 &GUID_VendorMicrosoft, 1499 converter_formats 1500 }, 1501 { NULL } /* list terminator */ 1502 }; 1503 1504 static const BYTE no_magic[1] = { 0 }; 1505 static const BYTE no_mask[1] = { 0 }; 1506 1507 static const struct metadata_pattern ifd_metadata_pattern[] = { 1508 { 0, 1, no_magic, no_mask, 0 }, 1509 { 0 } 1510 }; 1511 1512 static const struct reader_containers ifd_containers[] = { 1513 { 1514 &GUID_ContainerFormatTiff, 1515 ifd_metadata_pattern 1516 }, 1517 { NULL } /* list terminator */ 1518 }; 1519 1520 static const BYTE tEXt[] = "tEXt"; 1521 1522 static const struct metadata_pattern pngtext_metadata_pattern[] = { 1523 { 4, 4, tEXt, mask_all, 4 }, 1524 { 0 } 1525 }; 1526 1527 static const struct reader_containers pngtext_containers[] = { 1528 { 1529 &GUID_ContainerFormatPng, 1530 pngtext_metadata_pattern 1531 }, 1532 { NULL } /* list terminator */ 1533 }; 1534 1535 static const BYTE gAMA[] = "gAMA"; 1536 1537 static const struct metadata_pattern pnggama_metadata_pattern[] = { 1538 { 4, 4, gAMA, mask_all, 4 }, 1539 { 0 } 1540 }; 1541 1542 static const struct reader_containers pnggama_containers[] = { 1543 { 1544 &GUID_ContainerFormatPng, 1545 pnggama_metadata_pattern 1546 }, 1547 { NULL } /* list terminator */ 1548 }; 1549 1550 static const BYTE cHRM[] = "cHRM"; 1551 1552 static const struct metadata_pattern pngchrm_metadata_pattern[] = { 1553 { 4, 4, cHRM, mask_all, 4 }, 1554 { 0 } 1555 }; 1556 1557 static const struct reader_containers pngchrm_containers[] = { 1558 { 1559 &GUID_ContainerFormatPng, 1560 pngchrm_metadata_pattern 1561 }, 1562 { NULL } /* list terminator */ 1563 }; 1564 1565 static const struct metadata_pattern lsd_metadata_patterns[] = { 1566 { 0, 6, gif87a_magic, mask_all, 0 }, 1567 { 0, 6, gif89a_magic, mask_all, 0 }, 1568 { 0 } 1569 }; 1570 1571 static const struct reader_containers lsd_containers[] = { 1572 { 1573 &GUID_ContainerFormatGif, 1574 lsd_metadata_patterns 1575 }, 1576 { NULL } /* list terminator */ 1577 }; 1578 1579 static const BYTE imd_magic[] = { 0x2c }; 1580 1581 static const struct metadata_pattern imd_metadata_pattern[] = { 1582 { 0, 1, imd_magic, mask_all, 1 }, 1583 { 0 } 1584 }; 1585 1586 static const struct reader_containers imd_containers[] = { 1587 { 1588 &GUID_ContainerFormatGif, 1589 imd_metadata_pattern 1590 }, 1591 { NULL } /* list terminator */ 1592 }; 1593 1594 static const BYTE gce_magic[] = { 0x21, 0xf9, 0x04 }; 1595 1596 static const struct metadata_pattern gce_metadata_pattern[] = { 1597 { 0, 3, gce_magic, mask_all, 3 }, 1598 { 0 } 1599 }; 1600 1601 static const struct reader_containers gce_containers[] = { 1602 { 1603 &GUID_ContainerFormatGif, 1604 gce_metadata_pattern 1605 }, 1606 { NULL } /* list terminator */ 1607 }; 1608 1609 static const BYTE ape_magic[] = { 0x21, 0xff, 0x0b }; 1610 1611 static const struct metadata_pattern ape_metadata_pattern[] = { 1612 { 0, 3, ape_magic, mask_all, 0 }, 1613 { 0 } 1614 }; 1615 1616 static const struct reader_containers ape_containers[] = { 1617 { 1618 &GUID_ContainerFormatGif, 1619 ape_metadata_pattern 1620 }, 1621 { NULL } /* list terminator */ 1622 }; 1623 1624 static const BYTE gif_comment_magic[] = { 0x21, 0xfe }; 1625 1626 static const struct metadata_pattern gif_comment_metadata_pattern[] = { 1627 { 0, 2, gif_comment_magic, mask_all, 0 }, 1628 { 0 } 1629 }; 1630 1631 static const struct reader_containers gif_comment_containers[] = { 1632 { 1633 &GUID_ContainerFormatGif, 1634 gif_comment_metadata_pattern 1635 }, 1636 { NULL } /* list terminator */ 1637 }; 1638 1639 static struct regsvr_metadatareader const metadatareader_list[] = { 1640 { &CLSID_WICUnknownMetadataReader, 1641 "The Wine Project", 1642 "Unknown Metadata Reader", 1643 "1.0.0.0", 1644 "1.0.0.0", 1645 &GUID_VendorMicrosoft, 1646 &GUID_MetadataFormatUnknown, 1647 0, 0, 0, 1648 NULL 1649 }, 1650 { &CLSID_WICIfdMetadataReader, 1651 "The Wine Project", 1652 "Ifd Reader", 1653 "1.0.0.0", 1654 "1.0.0.0", 1655 &GUID_VendorMicrosoft, 1656 &GUID_MetadataFormatIfd, 1657 1, 1, 0, 1658 ifd_containers 1659 }, 1660 { &CLSID_WICPngChrmMetadataReader, 1661 "The Wine Project", 1662 "Chunk cHRM Reader", 1663 "1.0.0.0", 1664 "1.0.0.0", 1665 &GUID_VendorMicrosoft, 1666 &GUID_MetadataFormatChunkcHRM, 1667 0, 0, 0, 1668 pngchrm_containers 1669 }, 1670 { &CLSID_WICPngGamaMetadataReader, 1671 "The Wine Project", 1672 "Chunk gAMA Reader", 1673 "1.0.0.0", 1674 "1.0.0.0", 1675 &GUID_VendorMicrosoft, 1676 &GUID_MetadataFormatChunkgAMA, 1677 0, 0, 0, 1678 pnggama_containers 1679 }, 1680 { &CLSID_WICPngTextMetadataReader, 1681 "The Wine Project", 1682 "Chunk tEXt Reader", 1683 "1.0.0.0", 1684 "1.0.0.0", 1685 &GUID_VendorMicrosoft, 1686 &GUID_MetadataFormatChunktEXt, 1687 0, 0, 0, 1688 pngtext_containers 1689 }, 1690 { &CLSID_WICLSDMetadataReader, 1691 "The Wine Project", 1692 "Logical Screen Descriptor Reader", 1693 "1.0.0.0", 1694 "1.0.0.0", 1695 &GUID_VendorMicrosoft, 1696 &GUID_MetadataFormatLSD, 1697 0, 0, 0, 1698 lsd_containers 1699 }, 1700 { &CLSID_WICIMDMetadataReader, 1701 "The Wine Project", 1702 "Image Descriptor Reader", 1703 "1.0.0.0", 1704 "1.0.0.0", 1705 &GUID_VendorMicrosoft, 1706 &GUID_MetadataFormatIMD, 1707 0, 0, 0, 1708 imd_containers 1709 }, 1710 { &CLSID_WICGCEMetadataReader, 1711 "The Wine Project", 1712 "Graphic Control Extension Reader", 1713 "1.0.0.0", 1714 "1.0.0.0", 1715 &GUID_VendorMicrosoft, 1716 &GUID_MetadataFormatGCE, 1717 0, 0, 0, 1718 gce_containers 1719 }, 1720 { &CLSID_WICAPEMetadataReader, 1721 "The Wine Project", 1722 "Application Extension Reader", 1723 "1.0.0.0", 1724 "1.0.0.0", 1725 &GUID_VendorMicrosoft, 1726 &GUID_MetadataFormatAPE, 1727 0, 0, 0, 1728 ape_containers 1729 }, 1730 { &CLSID_WICGifCommentMetadataReader, 1731 "The Wine Project", 1732 "Comment Extension Reader", 1733 "1.0.0.0", 1734 "1.0.0.0", 1735 &GUID_VendorMicrosoft, 1736 &GUID_MetadataFormatGifComment, 1737 0, 0, 0, 1738 gif_comment_containers 1739 }, 1740 { NULL } /* list terminator */ 1741 }; 1742 1743 static BYTE const channel_mask_1bit[] = { 0x01 }; 1744 static BYTE const channel_mask_2bit[] = { 0x03 }; 1745 static BYTE const channel_mask_4bit[] = { 0x0f }; 1746 1747 static BYTE const channel_mask_8bit[] = { 0xff, 0x00, 0x00, 0x00 }; 1748 static BYTE const channel_mask_8bit2[] = { 0x00, 0xff, 0x00, 0x00 }; 1749 static BYTE const channel_mask_8bit3[] = { 0x00, 0x00, 0xff, 0x00 }; 1750 static BYTE const channel_mask_8bit4[] = { 0x00, 0x00, 0x00, 0xff }; 1751 1752 static BYTE const channel_mask_16bit[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1753 static BYTE const channel_mask_16bit2[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }; 1754 static BYTE const channel_mask_16bit3[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 }; 1755 static BYTE const channel_mask_16bit4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff }; 1756 1757 static BYTE const channel_mask_32bit[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }; 1758 1759 static BYTE const channel_mask_128bit1[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; 1760 static BYTE const channel_mask_128bit2[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; 1761 static BYTE const channel_mask_128bit3[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 }; 1762 static BYTE const channel_mask_128bit4[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff }; 1763 1764 static BYTE const channel_mask_5bit[] = { 0x1f, 0x00 }; 1765 static BYTE const channel_mask_5bit2[] = { 0xe0, 0x03 }; 1766 static BYTE const channel_mask_5bit3[] = { 0x00, 0x7c }; 1767 static BYTE const channel_mask_5bit4[] = { 0x00, 0x80 }; 1768 1769 static BYTE const channel_mask_BGR565_2[] = { 0xe0, 0x07 }; 1770 static BYTE const channel_mask_BGR565_3[] = { 0x00, 0xf8 }; 1771 1772 static BYTE const * const channel_masks_1bit[] = { channel_mask_1bit }; 1773 static BYTE const * const channel_masks_2bit[] = { channel_mask_2bit }; 1774 static BYTE const * const channel_masks_4bit[] = { channel_mask_4bit }; 1775 static BYTE const * const channel_masks_8bit[] = { channel_mask_8bit, 1776 channel_mask_8bit2, channel_mask_8bit3, channel_mask_8bit4 }; 1777 static BYTE const * const channel_masks_16bit[] = { channel_mask_16bit, 1778 channel_mask_16bit2, channel_mask_16bit3, channel_mask_16bit4}; 1779 1780 static BYTE const * const channel_masks_32bit[] = { channel_mask_32bit }; 1781 static BYTE const * const channel_masks_128bit[] = { channel_mask_128bit1, channel_mask_128bit2, channel_mask_128bit3, channel_mask_128bit4 }; 1782 1783 static BYTE const * const channel_masks_BGRA5551[] = { channel_mask_5bit, 1784 channel_mask_5bit2, channel_mask_5bit3, channel_mask_5bit4 }; 1785 1786 static BYTE const * const channel_masks_BGR565[] = { channel_mask_5bit, 1787 channel_mask_BGR565_2, channel_mask_BGR565_3 }; 1788 1789 static struct regsvr_pixelformat const pixelformat_list[] = { 1790 { &GUID_WICPixelFormat1bppIndexed, 1791 "The Wine Project", 1792 "1bpp Indexed", 1793 NULL, /* no version */ 1794 &GUID_VendorMicrosoft, 1795 1, /* bitsperpixel */ 1796 1, /* channel count */ 1797 channel_masks_1bit, 1798 WICPixelFormatNumericRepresentationIndexed, 1799 0 1800 }, 1801 { &GUID_WICPixelFormat2bppIndexed, 1802 "The Wine Project", 1803 "2bpp Indexed", 1804 NULL, /* no version */ 1805 &GUID_VendorMicrosoft, 1806 2, /* bitsperpixel */ 1807 1, /* channel count */ 1808 channel_masks_2bit, 1809 WICPixelFormatNumericRepresentationIndexed, 1810 0 1811 }, 1812 { &GUID_WICPixelFormat4bppIndexed, 1813 "The Wine Project", 1814 "4bpp Indexed", 1815 NULL, /* no version */ 1816 &GUID_VendorMicrosoft, 1817 4, /* bitsperpixel */ 1818 1, /* channel count */ 1819 channel_masks_4bit, 1820 WICPixelFormatNumericRepresentationIndexed, 1821 0 1822 }, 1823 { &GUID_WICPixelFormat8bppIndexed, 1824 "The Wine Project", 1825 "8bpp Indexed", 1826 NULL, /* no version */ 1827 &GUID_VendorMicrosoft, 1828 8, /* bitsperpixel */ 1829 1, /* channel count */ 1830 channel_masks_8bit, 1831 WICPixelFormatNumericRepresentationIndexed, 1832 0 1833 }, 1834 { &GUID_WICPixelFormatBlackWhite, 1835 "The Wine Project", 1836 "Black and White", 1837 NULL, /* no version */ 1838 &GUID_VendorMicrosoft, 1839 1, /* bitsperpixel */ 1840 1, /* channel count */ 1841 channel_masks_1bit, 1842 WICPixelFormatNumericRepresentationUnsignedInteger, 1843 0 1844 }, 1845 { &GUID_WICPixelFormat2bppGray, 1846 "The Wine Project", 1847 "2bpp Grayscale", 1848 NULL, /* no version */ 1849 &GUID_VendorMicrosoft, 1850 2, /* bitsperpixel */ 1851 1, /* channel count */ 1852 channel_masks_2bit, 1853 WICPixelFormatNumericRepresentationUnsignedInteger, 1854 0 1855 }, 1856 { &GUID_WICPixelFormat4bppGray, 1857 "The Wine Project", 1858 "4bpp Grayscale", 1859 NULL, /* no version */ 1860 &GUID_VendorMicrosoft, 1861 4, /* bitsperpixel */ 1862 1, /* channel count */ 1863 channel_masks_4bit, 1864 WICPixelFormatNumericRepresentationUnsignedInteger, 1865 0 1866 }, 1867 { &GUID_WICPixelFormat8bppGray, 1868 "The Wine Project", 1869 "8bpp Grayscale", 1870 NULL, /* no version */ 1871 &GUID_VendorMicrosoft, 1872 8, /* bitsperpixel */ 1873 1, /* channel count */ 1874 channel_masks_8bit, 1875 WICPixelFormatNumericRepresentationUnsignedInteger, 1876 0 1877 }, 1878 { &GUID_WICPixelFormat16bppGray, 1879 "The Wine Project", 1880 "16bpp Grayscale", 1881 NULL, /* no version */ 1882 &GUID_VendorMicrosoft, 1883 16, /* bitsperpixel */ 1884 1, /* channel count */ 1885 channel_masks_16bit, 1886 WICPixelFormatNumericRepresentationUnsignedInteger, 1887 0 1888 }, 1889 { &GUID_WICPixelFormat16bppBGR555, 1890 "The Wine Project", 1891 "16bpp BGR555", 1892 NULL, /* no version */ 1893 &GUID_VendorMicrosoft, 1894 16, /* bitsperpixel */ 1895 3, /* channel count */ 1896 channel_masks_BGRA5551, 1897 WICPixelFormatNumericRepresentationUnsignedInteger, 1898 0 1899 }, 1900 { &GUID_WICPixelFormat16bppBGR565, 1901 "The Wine Project", 1902 "16bpp BGR565", 1903 NULL, /* no version */ 1904 &GUID_VendorMicrosoft, 1905 16, /* bitsperpixel */ 1906 3, /* channel count */ 1907 channel_masks_BGR565, 1908 WICPixelFormatNumericRepresentationUnsignedInteger, 1909 0 1910 }, 1911 { &GUID_WICPixelFormat16bppBGRA5551, 1912 "The Wine Project", 1913 "16bpp BGRA5551", 1914 NULL, /* no version */ 1915 &GUID_VendorMicrosoft, 1916 16, /* bitsperpixel */ 1917 4, /* channel count */ 1918 channel_masks_BGRA5551, 1919 WICPixelFormatNumericRepresentationUnsignedInteger, 1920 1 1921 }, 1922 { &GUID_WICPixelFormat24bppBGR, 1923 "The Wine Project", 1924 "24bpp BGR", 1925 NULL, /* no version */ 1926 &GUID_VendorMicrosoft, 1927 24, /* bitsperpixel */ 1928 3, /* channel count */ 1929 channel_masks_8bit, 1930 WICPixelFormatNumericRepresentationUnsignedInteger, 1931 0 1932 }, 1933 { &GUID_WICPixelFormat24bppRGB, 1934 "The Wine Project", 1935 "24bpp RGB", 1936 NULL, /* no version */ 1937 &GUID_VendorMicrosoft, 1938 24, /* bitsperpixel */ 1939 3, /* channel count */ 1940 channel_masks_8bit, 1941 WICPixelFormatNumericRepresentationUnsignedInteger, 1942 0 1943 }, 1944 { &GUID_WICPixelFormat32bppBGR, 1945 "The Wine Project", 1946 "32bpp BGR", 1947 NULL, /* no version */ 1948 &GUID_VendorMicrosoft, 1949 32, /* bitsperpixel */ 1950 3, /* channel count */ 1951 channel_masks_8bit, 1952 WICPixelFormatNumericRepresentationUnsignedInteger, 1953 0 1954 }, 1955 { &GUID_WICPixelFormat32bppRGB, 1956 "The Wine Project", 1957 "32bpp RGB", 1958 NULL, /* no version */ 1959 &GUID_VendorMicrosoft, 1960 32, /* bitsperpixel */ 1961 3, /* channel count */ 1962 channel_masks_8bit, 1963 WICPixelFormatNumericRepresentationUnsignedInteger, 1964 0 1965 }, 1966 { &GUID_WICPixelFormat32bppBGRA, 1967 "The Wine Project", 1968 "32bpp BGRA", 1969 NULL, /* no version */ 1970 &GUID_VendorMicrosoft, 1971 32, /* bitsperpixel */ 1972 4, /* channel count */ 1973 channel_masks_8bit, 1974 WICPixelFormatNumericRepresentationUnsignedInteger, 1975 1 1976 }, 1977 { &GUID_WICPixelFormat32bppRGBA, 1978 "The Wine Project", 1979 "32bpp RGBA", 1980 NULL, /* no version */ 1981 &GUID_VendorMicrosoft, 1982 32, /* bitsperpixel */ 1983 4, /* channel count */ 1984 channel_masks_8bit, 1985 WICPixelFormatNumericRepresentationUnsignedInteger, 1986 1 1987 }, 1988 { &GUID_WICPixelFormat32bppPBGRA, 1989 "The Wine Project", 1990 "32bpp PBGRA", 1991 NULL, /* no version */ 1992 &GUID_VendorMicrosoft, 1993 32, /* bitsperpixel */ 1994 4, /* channel count */ 1995 channel_masks_8bit, 1996 WICPixelFormatNumericRepresentationUnsignedInteger, 1997 1 1998 }, 1999 { &GUID_WICPixelFormat32bppPRGBA, 2000 "The Wine Project", 2001 "32bpp PRGBA", 2002 NULL, /* no version */ 2003 &GUID_VendorMicrosoft, 2004 32, /* bitsperpixel */ 2005 4, /* channel count */ 2006 channel_masks_8bit, 2007 WICPixelFormatNumericRepresentationUnsignedInteger, 2008 1 2009 }, 2010 { &GUID_WICPixelFormat32bppGrayFloat, 2011 "The Wine Project", 2012 "32bpp GrayFloat", 2013 NULL, /* no version */ 2014 &GUID_VendorMicrosoft, 2015 32, /* bitsperpixel */ 2016 1, /* channel count */ 2017 channel_masks_32bit, 2018 WICPixelFormatNumericRepresentationFloat, 2019 0 2020 }, 2021 { &GUID_WICPixelFormat48bppRGB, 2022 "The Wine Project", 2023 "48bpp RGB", 2024 NULL, /* no version */ 2025 &GUID_VendorMicrosoft, 2026 48, /* bitsperpixel */ 2027 3, /* channel count */ 2028 channel_masks_16bit, 2029 WICPixelFormatNumericRepresentationUnsignedInteger, 2030 0 2031 }, 2032 { &GUID_WICPixelFormat64bppRGBA, 2033 "The Wine Project", 2034 "64bpp RGBA", 2035 NULL, /* no version */ 2036 &GUID_VendorMicrosoft, 2037 64, /* bitsperpixel */ 2038 4, /* channel count */ 2039 channel_masks_16bit, 2040 WICPixelFormatNumericRepresentationUnsignedInteger, 2041 1 2042 }, 2043 { &GUID_WICPixelFormat64bppPRGBA, 2044 "The Wine Project", 2045 "64bpp PRGBA", 2046 NULL, /* no version */ 2047 &GUID_VendorMicrosoft, 2048 64, /* bitsperpixel */ 2049 4, /* channel count */ 2050 channel_masks_16bit, 2051 WICPixelFormatNumericRepresentationUnsignedInteger, 2052 1 2053 }, 2054 { &GUID_WICPixelFormat32bppCMYK, 2055 "The Wine Project", 2056 "32bpp CMYK", 2057 NULL, /* no version */ 2058 &GUID_VendorMicrosoft, 2059 32, /* bitsperpixel */ 2060 4, /* channel count */ 2061 channel_masks_8bit, 2062 WICPixelFormatNumericRepresentationUnsignedInteger, 2063 0 2064 }, 2065 { &GUID_WICPixelFormat64bppCMYK, 2066 "The Wine Project", 2067 "64bpp CMYK", 2068 NULL, /* no version */ 2069 &GUID_VendorMicrosoft, 2070 64, /* bitsperpixel */ 2071 4, /* channel count */ 2072 channel_masks_16bit, 2073 WICPixelFormatNumericRepresentationUnsignedInteger, 2074 0 2075 }, 2076 { &GUID_WICPixelFormat128bppRGBAFloat, 2077 "The Wine Project", 2078 "128bpp RGBAFloat", 2079 NULL, /* no version */ 2080 &GUID_VendorMicrosoft, 2081 128, /* bitsperpixel */ 2082 4, /* channel count */ 2083 channel_masks_128bit, 2084 WICPixelFormatNumericRepresentationFloat, 2085 1 2086 }, 2087 { NULL } /* list terminator */ 2088 }; 2089 2090 struct regsvr_category 2091 { 2092 const CLSID *clsid; /* NULL for end of list */ 2093 }; 2094 2095 static const struct regsvr_category category_list[] = { 2096 { &CATID_WICBitmapDecoders }, 2097 { &CATID_WICBitmapEncoders }, 2098 { &CATID_WICFormatConverters }, 2099 { &CATID_WICMetadataReader }, 2100 { &CATID_WICPixelFormats }, 2101 { NULL } 2102 }; 2103 2104 static HRESULT register_categories(const struct regsvr_category *list) 2105 { 2106 LONG res; 2107 WCHAR buf[39]; 2108 HKEY coclass_key, categories_key, instance_key; 2109 2110 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, 2111 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); 2112 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); 2113 2114 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39); 2115 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 2116 KEY_READ | KEY_WRITE, NULL, &categories_key, NULL); 2117 if (res != ERROR_SUCCESS) 2118 { 2119 RegCloseKey(coclass_key); 2120 return HRESULT_FROM_WIN32(res); 2121 } 2122 2123 res = RegCreateKeyExW(categories_key, instance_keyname, 0, NULL, 0, 2124 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL); 2125 2126 for (; res == ERROR_SUCCESS && list->clsid; list++) 2127 { 2128 HKEY instance_clsid_key; 2129 2130 StringFromGUID2(list->clsid, buf, 39); 2131 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0, 2132 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL); 2133 if (res == ERROR_SUCCESS) 2134 { 2135 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ, 2136 (const BYTE *)buf, 78); 2137 RegCloseKey(instance_clsid_key); 2138 } 2139 } 2140 2141 RegCloseKey(instance_key); 2142 RegCloseKey(categories_key); 2143 RegCloseKey(coclass_key); 2144 2145 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 2146 } 2147 2148 static HRESULT unregister_categories(const struct regsvr_category *list) 2149 { 2150 LONG res; 2151 WCHAR buf[39]; 2152 HKEY coclass_key, categories_key, instance_key; 2153 2154 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, 2155 KEY_READ | KEY_WRITE, &coclass_key); 2156 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); 2157 2158 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39); 2159 res = RegOpenKeyExW(coclass_key, buf, 0, 2160 KEY_READ | KEY_WRITE, &categories_key); 2161 if (res != ERROR_SUCCESS) 2162 { 2163 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 2164 RegCloseKey(coclass_key); 2165 return HRESULT_FROM_WIN32(res); 2166 } 2167 2168 res = RegOpenKeyExW(categories_key, instance_keyname, 0, 2169 KEY_READ | KEY_WRITE, &instance_key); 2170 2171 for (; res == ERROR_SUCCESS && list->clsid; list++) 2172 { 2173 StringFromGUID2(list->clsid, buf, 39); 2174 res = RegDeleteTreeW(instance_key, buf); 2175 } 2176 2177 RegCloseKey(instance_key); 2178 RegCloseKey(categories_key); 2179 2180 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39); 2181 res = RegDeleteTreeW(coclass_key, buf); 2182 2183 RegCloseKey(coclass_key); 2184 2185 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 2186 } 2187 2188 extern HRESULT WINAPI WIC_DllRegisterServer(void) DECLSPEC_HIDDEN; 2189 extern HRESULT WINAPI WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN; 2190 2191 HRESULT WINAPI DllRegisterServer(void) 2192 { 2193 HRESULT hr; 2194 2195 TRACE("\n"); 2196 2197 hr = WIC_DllRegisterServer(); 2198 if (SUCCEEDED(hr)) 2199 hr = register_categories(category_list); 2200 if (SUCCEEDED(hr)) 2201 hr = register_decoders(decoder_list); 2202 if (SUCCEEDED(hr)) 2203 hr = register_encoders(encoder_list); 2204 if (SUCCEEDED(hr)) 2205 hr = register_converters(converter_list); 2206 if (SUCCEEDED(hr)) 2207 hr = register_metadatareaders(metadatareader_list); 2208 if (SUCCEEDED(hr)) 2209 hr = register_pixelformats(pixelformat_list); 2210 return hr; 2211 } 2212 2213 HRESULT WINAPI DllUnregisterServer(void) 2214 { 2215 HRESULT hr; 2216 2217 TRACE("\n"); 2218 2219 hr = WIC_DllUnregisterServer(); 2220 if (SUCCEEDED(hr)) 2221 hr = unregister_categories(category_list); 2222 if (SUCCEEDED(hr)) 2223 hr = unregister_decoders(decoder_list); 2224 if (SUCCEEDED(hr)) 2225 hr = unregister_encoders(encoder_list); 2226 if (SUCCEEDED(hr)) 2227 hr = unregister_converters(converter_list); 2228 if (SUCCEEDED(hr)) 2229 hr = unregister_metadatareaders(metadatareader_list); 2230 if (SUCCEEDED(hr)) 2231 hr = unregister_pixelformats(pixelformat_list); 2232 return hr; 2233 } 2234