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 HKEY masks_key; 1036 UINT i, mask_size; 1037 WCHAR mask_valuename[11]; 1038 const WCHAR valuename_format[] = {'%','d',0}; 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_WICPixelFormat2bppIndexed, 1358 &GUID_WICPixelFormat4bppIndexed, 1359 &GUID_WICPixelFormat8bppIndexed, 1360 NULL 1361 }; 1362 1363 static GUID const * const png_encode_formats[] = { 1364 &GUID_WICPixelFormat24bppBGR, 1365 &GUID_WICPixelFormatBlackWhite, 1366 &GUID_WICPixelFormat2bppGray, 1367 &GUID_WICPixelFormat4bppGray, 1368 &GUID_WICPixelFormat8bppGray, 1369 &GUID_WICPixelFormat16bppGray, 1370 &GUID_WICPixelFormat32bppBGR, 1371 &GUID_WICPixelFormat32bppBGRA, 1372 &GUID_WICPixelFormat48bppRGB, 1373 &GUID_WICPixelFormat64bppRGBA, 1374 &GUID_WICPixelFormat1bppIndexed, 1375 &GUID_WICPixelFormat2bppIndexed, 1376 &GUID_WICPixelFormat4bppIndexed, 1377 &GUID_WICPixelFormat8bppIndexed, 1378 NULL 1379 }; 1380 1381 static GUID const * const tiff_encode_formats[] = { 1382 &GUID_WICPixelFormatBlackWhite, 1383 &GUID_WICPixelFormat4bppGray, 1384 &GUID_WICPixelFormat8bppGray, 1385 &GUID_WICPixelFormat1bppIndexed, 1386 &GUID_WICPixelFormat2bppIndexed, 1387 &GUID_WICPixelFormat4bppIndexed, 1388 &GUID_WICPixelFormat8bppIndexed, 1389 &GUID_WICPixelFormat24bppBGR, 1390 &GUID_WICPixelFormat32bppBGRA, 1391 &GUID_WICPixelFormat32bppPBGRA, 1392 &GUID_WICPixelFormat48bppRGB, 1393 &GUID_WICPixelFormat64bppRGBA, 1394 &GUID_WICPixelFormat64bppPRGBA, 1395 NULL 1396 }; 1397 1398 static GUID const * const icns_encode_formats[] = { 1399 &GUID_WICPixelFormat32bppBGRA, 1400 NULL 1401 }; 1402 1403 static struct regsvr_encoder const encoder_list[] = { 1404 { &CLSID_WICBmpEncoder, 1405 "The Wine Project", 1406 "BMP Encoder", 1407 "1.0.0.0", 1408 &GUID_VendorMicrosoft, 1409 &GUID_ContainerFormatBmp, 1410 "image/bmp", 1411 ".bmp,.dib,.rle", 1412 bmp_encode_formats 1413 }, 1414 { &CLSID_WICGifEncoder, 1415 "The Wine Project", 1416 "GIF Encoder", 1417 "1.0.0.0", 1418 &GUID_VendorMicrosoft, 1419 &GUID_ContainerFormatGif, 1420 "image/gif", 1421 ".gif", 1422 gif_formats 1423 }, 1424 { &CLSID_WICJpegEncoder, 1425 "The Wine Project", 1426 "JPEG Encoder", 1427 "1.0.0.0", 1428 &GUID_VendorMicrosoft, 1429 &GUID_ContainerFormatJpeg, 1430 "image/jpeg", 1431 ".jpg;.jpeg;.jfif", 1432 jpeg_formats 1433 }, 1434 { &CLSID_WICPngEncoder, 1435 "The Wine Project", 1436 "PNG Encoder", 1437 "1.0.0.0", 1438 &GUID_VendorMicrosoft, 1439 &GUID_ContainerFormatPng, 1440 "image/png", 1441 ".png", 1442 png_encode_formats 1443 }, 1444 { &CLSID_WICTiffEncoder, 1445 "The Wine Project", 1446 "TIFF Encoder", 1447 "1.0.0.0", 1448 &GUID_VendorMicrosoft, 1449 &GUID_ContainerFormatTiff, 1450 "image/tiff", 1451 ".tif;.tiff", 1452 tiff_encode_formats 1453 }, 1454 { &CLSID_WICIcnsEncoder, 1455 "The Wine Project", 1456 "ICNS Encoder", 1457 "1.0.0.0", 1458 &GUID_VendorWine, 1459 NULL, /* no container format guid */ 1460 "image/icns", 1461 ".icns", 1462 icns_encode_formats 1463 }, 1464 { NULL } /* list terminator */ 1465 }; 1466 1467 static GUID const * const converter_formats[] = { 1468 &GUID_WICPixelFormat1bppIndexed, 1469 &GUID_WICPixelFormat2bppIndexed, 1470 &GUID_WICPixelFormat4bppIndexed, 1471 &GUID_WICPixelFormat8bppIndexed, 1472 &GUID_WICPixelFormatBlackWhite, 1473 &GUID_WICPixelFormat2bppGray, 1474 &GUID_WICPixelFormat4bppGray, 1475 &GUID_WICPixelFormat8bppGray, 1476 &GUID_WICPixelFormat16bppGray, 1477 &GUID_WICPixelFormat16bppBGR555, 1478 &GUID_WICPixelFormat16bppBGR565, 1479 &GUID_WICPixelFormat16bppBGRA5551, 1480 &GUID_WICPixelFormat24bppBGR, 1481 &GUID_WICPixelFormat24bppRGB, 1482 &GUID_WICPixelFormat32bppBGR, 1483 &GUID_WICPixelFormat32bppRGB, 1484 &GUID_WICPixelFormat32bppBGRA, 1485 &GUID_WICPixelFormat32bppRGBA, 1486 &GUID_WICPixelFormat32bppPBGRA, 1487 &GUID_WICPixelFormat32bppPRGBA, 1488 &GUID_WICPixelFormat32bppGrayFloat, 1489 &GUID_WICPixelFormat48bppRGB, 1490 &GUID_WICPixelFormat64bppRGBA, 1491 &GUID_WICPixelFormat32bppCMYK, 1492 NULL 1493 }; 1494 1495 static struct regsvr_converter const converter_list[] = { 1496 { &CLSID_WICDefaultFormatConverter, 1497 "The Wine Project", 1498 "Default Pixel Format Converter", 1499 "1.0.0.0", 1500 &GUID_VendorMicrosoft, 1501 converter_formats 1502 }, 1503 { NULL } /* list terminator */ 1504 }; 1505 1506 static const BYTE no_magic[1] = { 0 }; 1507 static const BYTE no_mask[1] = { 0 }; 1508 1509 static const struct metadata_pattern ifd_metadata_pattern[] = { 1510 { 0, 1, no_magic, no_mask, 0 }, 1511 { 0 } 1512 }; 1513 1514 static const struct reader_containers ifd_containers[] = { 1515 { 1516 &GUID_ContainerFormatTiff, 1517 ifd_metadata_pattern 1518 }, 1519 { NULL } /* list terminator */ 1520 }; 1521 1522 static const BYTE tEXt[] = "tEXt"; 1523 1524 static const struct metadata_pattern pngtext_metadata_pattern[] = { 1525 { 4, 4, tEXt, mask_all, 4 }, 1526 { 0 } 1527 }; 1528 1529 static const struct reader_containers pngtext_containers[] = { 1530 { 1531 &GUID_ContainerFormatPng, 1532 pngtext_metadata_pattern 1533 }, 1534 { NULL } /* list terminator */ 1535 }; 1536 1537 static const BYTE gAMA[] = "gAMA"; 1538 1539 static const struct metadata_pattern pnggama_metadata_pattern[] = { 1540 { 4, 4, gAMA, mask_all, 4 }, 1541 { 0 } 1542 }; 1543 1544 static const struct reader_containers pnggama_containers[] = { 1545 { 1546 &GUID_ContainerFormatPng, 1547 pnggama_metadata_pattern 1548 }, 1549 { NULL } /* list terminator */ 1550 }; 1551 1552 static const BYTE cHRM[] = "cHRM"; 1553 1554 static const struct metadata_pattern pngchrm_metadata_pattern[] = { 1555 { 4, 4, cHRM, mask_all, 4 }, 1556 { 0 } 1557 }; 1558 1559 static const struct reader_containers pngchrm_containers[] = { 1560 { 1561 &GUID_ContainerFormatPng, 1562 pngchrm_metadata_pattern 1563 }, 1564 { NULL } /* list terminator */ 1565 }; 1566 1567 static const struct metadata_pattern lsd_metadata_patterns[] = { 1568 { 0, 6, gif87a_magic, mask_all, 0 }, 1569 { 0, 6, gif89a_magic, mask_all, 0 }, 1570 { 0 } 1571 }; 1572 1573 static const struct reader_containers lsd_containers[] = { 1574 { 1575 &GUID_ContainerFormatGif, 1576 lsd_metadata_patterns 1577 }, 1578 { NULL } /* list terminator */ 1579 }; 1580 1581 static const BYTE imd_magic[] = { 0x2c }; 1582 1583 static const struct metadata_pattern imd_metadata_pattern[] = { 1584 { 0, 1, imd_magic, mask_all, 1 }, 1585 { 0 } 1586 }; 1587 1588 static const struct reader_containers imd_containers[] = { 1589 { 1590 &GUID_ContainerFormatGif, 1591 imd_metadata_pattern 1592 }, 1593 { NULL } /* list terminator */ 1594 }; 1595 1596 static const BYTE gce_magic[] = { 0x21, 0xf9, 0x04 }; 1597 1598 static const struct metadata_pattern gce_metadata_pattern[] = { 1599 { 0, 3, gce_magic, mask_all, 3 }, 1600 { 0 } 1601 }; 1602 1603 static const struct reader_containers gce_containers[] = { 1604 { 1605 &GUID_ContainerFormatGif, 1606 gce_metadata_pattern 1607 }, 1608 { NULL } /* list terminator */ 1609 }; 1610 1611 static const BYTE ape_magic[] = { 0x21, 0xff, 0x0b }; 1612 1613 static const struct metadata_pattern ape_metadata_pattern[] = { 1614 { 0, 3, ape_magic, mask_all, 0 }, 1615 { 0 } 1616 }; 1617 1618 static const struct reader_containers ape_containers[] = { 1619 { 1620 &GUID_ContainerFormatGif, 1621 ape_metadata_pattern 1622 }, 1623 { NULL } /* list terminator */ 1624 }; 1625 1626 static const BYTE gif_comment_magic[] = { 0x21, 0xfe }; 1627 1628 static const struct metadata_pattern gif_comment_metadata_pattern[] = { 1629 { 0, 2, gif_comment_magic, mask_all, 0 }, 1630 { 0 } 1631 }; 1632 1633 static const struct reader_containers gif_comment_containers[] = { 1634 { 1635 &GUID_ContainerFormatGif, 1636 gif_comment_metadata_pattern 1637 }, 1638 { NULL } /* list terminator */ 1639 }; 1640 1641 static struct regsvr_metadatareader const metadatareader_list[] = { 1642 { &CLSID_WICUnknownMetadataReader, 1643 "The Wine Project", 1644 "Unknown Metadata Reader", 1645 "1.0.0.0", 1646 "1.0.0.0", 1647 &GUID_VendorMicrosoft, 1648 &GUID_MetadataFormatUnknown, 1649 0, 0, 0, 1650 NULL 1651 }, 1652 { &CLSID_WICIfdMetadataReader, 1653 "The Wine Project", 1654 "Ifd Reader", 1655 "1.0.0.0", 1656 "1.0.0.0", 1657 &GUID_VendorMicrosoft, 1658 &GUID_MetadataFormatIfd, 1659 1, 1, 0, 1660 ifd_containers 1661 }, 1662 { &CLSID_WICPngChrmMetadataReader, 1663 "The Wine Project", 1664 "Chunk cHRM Reader", 1665 "1.0.0.0", 1666 "1.0.0.0", 1667 &GUID_VendorMicrosoft, 1668 &GUID_MetadataFormatChunkcHRM, 1669 0, 0, 0, 1670 pngchrm_containers 1671 }, 1672 { &CLSID_WICPngGamaMetadataReader, 1673 "The Wine Project", 1674 "Chunk gAMA Reader", 1675 "1.0.0.0", 1676 "1.0.0.0", 1677 &GUID_VendorMicrosoft, 1678 &GUID_MetadataFormatChunkgAMA, 1679 0, 0, 0, 1680 pnggama_containers 1681 }, 1682 { &CLSID_WICPngTextMetadataReader, 1683 "The Wine Project", 1684 "Chunk tEXt Reader", 1685 "1.0.0.0", 1686 "1.0.0.0", 1687 &GUID_VendorMicrosoft, 1688 &GUID_MetadataFormatChunktEXt, 1689 0, 0, 0, 1690 pngtext_containers 1691 }, 1692 { &CLSID_WICLSDMetadataReader, 1693 "The Wine Project", 1694 "Logical Screen Descriptor Reader", 1695 "1.0.0.0", 1696 "1.0.0.0", 1697 &GUID_VendorMicrosoft, 1698 &GUID_MetadataFormatLSD, 1699 0, 0, 0, 1700 lsd_containers 1701 }, 1702 { &CLSID_WICIMDMetadataReader, 1703 "The Wine Project", 1704 "Image Descriptor Reader", 1705 "1.0.0.0", 1706 "1.0.0.0", 1707 &GUID_VendorMicrosoft, 1708 &GUID_MetadataFormatIMD, 1709 0, 0, 0, 1710 imd_containers 1711 }, 1712 { &CLSID_WICGCEMetadataReader, 1713 "The Wine Project", 1714 "Graphic Control Extension Reader", 1715 "1.0.0.0", 1716 "1.0.0.0", 1717 &GUID_VendorMicrosoft, 1718 &GUID_MetadataFormatGCE, 1719 0, 0, 0, 1720 gce_containers 1721 }, 1722 { &CLSID_WICAPEMetadataReader, 1723 "The Wine Project", 1724 "Application Extension Reader", 1725 "1.0.0.0", 1726 "1.0.0.0", 1727 &GUID_VendorMicrosoft, 1728 &GUID_MetadataFormatAPE, 1729 0, 0, 0, 1730 ape_containers 1731 }, 1732 { &CLSID_WICGifCommentMetadataReader, 1733 "The Wine Project", 1734 "Comment Extension Reader", 1735 "1.0.0.0", 1736 "1.0.0.0", 1737 &GUID_VendorMicrosoft, 1738 &GUID_MetadataFormatGifComment, 1739 0, 0, 0, 1740 gif_comment_containers 1741 }, 1742 { NULL } /* list terminator */ 1743 }; 1744 1745 static BYTE const channel_mask_1bit[] = { 0x01 }; 1746 static BYTE const channel_mask_2bit[] = { 0x03 }; 1747 static BYTE const channel_mask_4bit[] = { 0x0f }; 1748 1749 static BYTE const channel_mask_8bit[] = { 0xff, 0x00, 0x00, 0x00 }; 1750 static BYTE const channel_mask_8bit2[] = { 0x00, 0xff, 0x00, 0x00 }; 1751 static BYTE const channel_mask_8bit3[] = { 0x00, 0x00, 0xff, 0x00 }; 1752 static BYTE const channel_mask_8bit4[] = { 0x00, 0x00, 0x00, 0xff }; 1753 1754 static BYTE const channel_mask_16bit[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1755 static BYTE const channel_mask_16bit2[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }; 1756 static BYTE const channel_mask_16bit3[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 }; 1757 static BYTE const channel_mask_16bit4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff }; 1758 1759 static BYTE const channel_mask_32bit[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }; 1760 1761 static BYTE const channel_mask_128bit1[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; 1762 static BYTE const channel_mask_128bit2[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; 1763 static BYTE const channel_mask_128bit3[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 }; 1764 static BYTE const channel_mask_128bit4[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff }; 1765 1766 static BYTE const channel_mask_5bit[] = { 0x1f, 0x00 }; 1767 static BYTE const channel_mask_5bit2[] = { 0xe0, 0x03 }; 1768 static BYTE const channel_mask_5bit3[] = { 0x00, 0x7c }; 1769 static BYTE const channel_mask_5bit4[] = { 0x00, 0x80 }; 1770 1771 static BYTE const channel_mask_BGR565_2[] = { 0xe0, 0x07 }; 1772 static BYTE const channel_mask_BGR565_3[] = { 0x00, 0xf8 }; 1773 1774 static BYTE const * const channel_masks_1bit[] = { channel_mask_1bit }; 1775 static BYTE const * const channel_masks_2bit[] = { channel_mask_2bit }; 1776 static BYTE const * const channel_masks_4bit[] = { channel_mask_4bit }; 1777 static BYTE const * const channel_masks_8bit[] = { channel_mask_8bit, 1778 channel_mask_8bit2, channel_mask_8bit3, channel_mask_8bit4 }; 1779 static BYTE const * const channel_masks_16bit[] = { channel_mask_16bit, 1780 channel_mask_16bit2, channel_mask_16bit3, channel_mask_16bit4}; 1781 1782 static BYTE const * const channel_masks_32bit[] = { channel_mask_32bit }; 1783 static BYTE const * const channel_masks_128bit[] = { channel_mask_128bit1, channel_mask_128bit2, channel_mask_128bit3, channel_mask_128bit4 }; 1784 1785 static BYTE const * const channel_masks_BGRA5551[] = { channel_mask_5bit, 1786 channel_mask_5bit2, channel_mask_5bit3, channel_mask_5bit4 }; 1787 1788 static BYTE const * const channel_masks_BGR565[] = { channel_mask_5bit, 1789 channel_mask_BGR565_2, channel_mask_BGR565_3 }; 1790 1791 static struct regsvr_pixelformat const pixelformat_list[] = { 1792 { &GUID_WICPixelFormat1bppIndexed, 1793 "The Wine Project", 1794 "1bpp Indexed", 1795 NULL, /* no version */ 1796 &GUID_VendorMicrosoft, 1797 1, /* bitsperpixel */ 1798 1, /* channel count */ 1799 channel_masks_1bit, 1800 WICPixelFormatNumericRepresentationIndexed, 1801 0 1802 }, 1803 { &GUID_WICPixelFormat2bppIndexed, 1804 "The Wine Project", 1805 "2bpp Indexed", 1806 NULL, /* no version */ 1807 &GUID_VendorMicrosoft, 1808 2, /* bitsperpixel */ 1809 1, /* channel count */ 1810 channel_masks_2bit, 1811 WICPixelFormatNumericRepresentationIndexed, 1812 0 1813 }, 1814 { &GUID_WICPixelFormat4bppIndexed, 1815 "The Wine Project", 1816 "4bpp Indexed", 1817 NULL, /* no version */ 1818 &GUID_VendorMicrosoft, 1819 4, /* bitsperpixel */ 1820 1, /* channel count */ 1821 channel_masks_4bit, 1822 WICPixelFormatNumericRepresentationIndexed, 1823 0 1824 }, 1825 { &GUID_WICPixelFormat8bppIndexed, 1826 "The Wine Project", 1827 "8bpp Indexed", 1828 NULL, /* no version */ 1829 &GUID_VendorMicrosoft, 1830 8, /* bitsperpixel */ 1831 1, /* channel count */ 1832 channel_masks_8bit, 1833 WICPixelFormatNumericRepresentationIndexed, 1834 0 1835 }, 1836 { &GUID_WICPixelFormatBlackWhite, 1837 "The Wine Project", 1838 "Black and White", 1839 NULL, /* no version */ 1840 &GUID_VendorMicrosoft, 1841 1, /* bitsperpixel */ 1842 1, /* channel count */ 1843 channel_masks_1bit, 1844 WICPixelFormatNumericRepresentationUnsignedInteger, 1845 0 1846 }, 1847 { &GUID_WICPixelFormat2bppGray, 1848 "The Wine Project", 1849 "2bpp Grayscale", 1850 NULL, /* no version */ 1851 &GUID_VendorMicrosoft, 1852 2, /* bitsperpixel */ 1853 1, /* channel count */ 1854 channel_masks_2bit, 1855 WICPixelFormatNumericRepresentationUnsignedInteger, 1856 0 1857 }, 1858 { &GUID_WICPixelFormat4bppGray, 1859 "The Wine Project", 1860 "4bpp Grayscale", 1861 NULL, /* no version */ 1862 &GUID_VendorMicrosoft, 1863 4, /* bitsperpixel */ 1864 1, /* channel count */ 1865 channel_masks_4bit, 1866 WICPixelFormatNumericRepresentationUnsignedInteger, 1867 0 1868 }, 1869 { &GUID_WICPixelFormat8bppGray, 1870 "The Wine Project", 1871 "8bpp Grayscale", 1872 NULL, /* no version */ 1873 &GUID_VendorMicrosoft, 1874 8, /* bitsperpixel */ 1875 1, /* channel count */ 1876 channel_masks_8bit, 1877 WICPixelFormatNumericRepresentationUnsignedInteger, 1878 0 1879 }, 1880 { &GUID_WICPixelFormat16bppGray, 1881 "The Wine Project", 1882 "16bpp Grayscale", 1883 NULL, /* no version */ 1884 &GUID_VendorMicrosoft, 1885 16, /* bitsperpixel */ 1886 1, /* channel count */ 1887 channel_masks_16bit, 1888 WICPixelFormatNumericRepresentationUnsignedInteger, 1889 0 1890 }, 1891 { &GUID_WICPixelFormat16bppBGR555, 1892 "The Wine Project", 1893 "16bpp BGR555", 1894 NULL, /* no version */ 1895 &GUID_VendorMicrosoft, 1896 16, /* bitsperpixel */ 1897 3, /* channel count */ 1898 channel_masks_BGRA5551, 1899 WICPixelFormatNumericRepresentationUnsignedInteger, 1900 0 1901 }, 1902 { &GUID_WICPixelFormat16bppBGR565, 1903 "The Wine Project", 1904 "16bpp BGR565", 1905 NULL, /* no version */ 1906 &GUID_VendorMicrosoft, 1907 16, /* bitsperpixel */ 1908 3, /* channel count */ 1909 channel_masks_BGR565, 1910 WICPixelFormatNumericRepresentationUnsignedInteger, 1911 0 1912 }, 1913 { &GUID_WICPixelFormat16bppBGRA5551, 1914 "The Wine Project", 1915 "16bpp BGRA5551", 1916 NULL, /* no version */ 1917 &GUID_VendorMicrosoft, 1918 16, /* bitsperpixel */ 1919 4, /* channel count */ 1920 channel_masks_BGRA5551, 1921 WICPixelFormatNumericRepresentationUnsignedInteger, 1922 1 1923 }, 1924 { &GUID_WICPixelFormat24bppBGR, 1925 "The Wine Project", 1926 "24bpp BGR", 1927 NULL, /* no version */ 1928 &GUID_VendorMicrosoft, 1929 24, /* bitsperpixel */ 1930 3, /* channel count */ 1931 channel_masks_8bit, 1932 WICPixelFormatNumericRepresentationUnsignedInteger, 1933 0 1934 }, 1935 { &GUID_WICPixelFormat24bppRGB, 1936 "The Wine Project", 1937 "24bpp RGB", 1938 NULL, /* no version */ 1939 &GUID_VendorMicrosoft, 1940 24, /* bitsperpixel */ 1941 3, /* channel count */ 1942 channel_masks_8bit, 1943 WICPixelFormatNumericRepresentationUnsignedInteger, 1944 0 1945 }, 1946 { &GUID_WICPixelFormat32bppBGR, 1947 "The Wine Project", 1948 "32bpp BGR", 1949 NULL, /* no version */ 1950 &GUID_VendorMicrosoft, 1951 32, /* bitsperpixel */ 1952 3, /* channel count */ 1953 channel_masks_8bit, 1954 WICPixelFormatNumericRepresentationUnsignedInteger, 1955 0 1956 }, 1957 { &GUID_WICPixelFormat32bppRGB, 1958 "The Wine Project", 1959 "32bpp RGB", 1960 NULL, /* no version */ 1961 &GUID_VendorMicrosoft, 1962 32, /* bitsperpixel */ 1963 3, /* channel count */ 1964 channel_masks_8bit, 1965 WICPixelFormatNumericRepresentationUnsignedInteger, 1966 0 1967 }, 1968 { &GUID_WICPixelFormat32bppBGRA, 1969 "The Wine Project", 1970 "32bpp BGRA", 1971 NULL, /* no version */ 1972 &GUID_VendorMicrosoft, 1973 32, /* bitsperpixel */ 1974 4, /* channel count */ 1975 channel_masks_8bit, 1976 WICPixelFormatNumericRepresentationUnsignedInteger, 1977 1 1978 }, 1979 { &GUID_WICPixelFormat32bppRGBA, 1980 "The Wine Project", 1981 "32bpp RGBA", 1982 NULL, /* no version */ 1983 &GUID_VendorMicrosoft, 1984 32, /* bitsperpixel */ 1985 4, /* channel count */ 1986 channel_masks_8bit, 1987 WICPixelFormatNumericRepresentationUnsignedInteger, 1988 1 1989 }, 1990 { &GUID_WICPixelFormat32bppPBGRA, 1991 "The Wine Project", 1992 "32bpp PBGRA", 1993 NULL, /* no version */ 1994 &GUID_VendorMicrosoft, 1995 32, /* bitsperpixel */ 1996 4, /* channel count */ 1997 channel_masks_8bit, 1998 WICPixelFormatNumericRepresentationUnsignedInteger, 1999 1 2000 }, 2001 { &GUID_WICPixelFormat32bppPRGBA, 2002 "The Wine Project", 2003 "32bpp PRGBA", 2004 NULL, /* no version */ 2005 &GUID_VendorMicrosoft, 2006 32, /* bitsperpixel */ 2007 4, /* channel count */ 2008 channel_masks_8bit, 2009 WICPixelFormatNumericRepresentationUnsignedInteger, 2010 1 2011 }, 2012 { &GUID_WICPixelFormat32bppGrayFloat, 2013 "The Wine Project", 2014 "32bpp GrayFloat", 2015 NULL, /* no version */ 2016 &GUID_VendorMicrosoft, 2017 32, /* bitsperpixel */ 2018 1, /* channel count */ 2019 channel_masks_32bit, 2020 WICPixelFormatNumericRepresentationFloat, 2021 0 2022 }, 2023 { &GUID_WICPixelFormat48bppRGB, 2024 "The Wine Project", 2025 "48bpp RGB", 2026 NULL, /* no version */ 2027 &GUID_VendorMicrosoft, 2028 48, /* bitsperpixel */ 2029 3, /* channel count */ 2030 channel_masks_16bit, 2031 WICPixelFormatNumericRepresentationUnsignedInteger, 2032 0 2033 }, 2034 { &GUID_WICPixelFormat64bppRGBA, 2035 "The Wine Project", 2036 "64bpp RGBA", 2037 NULL, /* no version */ 2038 &GUID_VendorMicrosoft, 2039 64, /* bitsperpixel */ 2040 4, /* channel count */ 2041 channel_masks_16bit, 2042 WICPixelFormatNumericRepresentationUnsignedInteger, 2043 1 2044 }, 2045 { &GUID_WICPixelFormat64bppPRGBA, 2046 "The Wine Project", 2047 "64bpp PRGBA", 2048 NULL, /* no version */ 2049 &GUID_VendorMicrosoft, 2050 64, /* bitsperpixel */ 2051 4, /* channel count */ 2052 channel_masks_16bit, 2053 WICPixelFormatNumericRepresentationUnsignedInteger, 2054 1 2055 }, 2056 { &GUID_WICPixelFormat32bppCMYK, 2057 "The Wine Project", 2058 "32bpp CMYK", 2059 NULL, /* no version */ 2060 &GUID_VendorMicrosoft, 2061 32, /* bitsperpixel */ 2062 4, /* channel count */ 2063 channel_masks_8bit, 2064 WICPixelFormatNumericRepresentationUnsignedInteger, 2065 0 2066 }, 2067 { &GUID_WICPixelFormat64bppCMYK, 2068 "The Wine Project", 2069 "64bpp CMYK", 2070 NULL, /* no version */ 2071 &GUID_VendorMicrosoft, 2072 64, /* bitsperpixel */ 2073 4, /* channel count */ 2074 channel_masks_16bit, 2075 WICPixelFormatNumericRepresentationUnsignedInteger, 2076 0 2077 }, 2078 { &GUID_WICPixelFormat128bppRGBAFloat, 2079 "The Wine Project", 2080 "128bpp RGBAFloat", 2081 NULL, /* no version */ 2082 &GUID_VendorMicrosoft, 2083 128, /* bitsperpixel */ 2084 4, /* channel count */ 2085 channel_masks_128bit, 2086 WICPixelFormatNumericRepresentationFloat, 2087 1 2088 }, 2089 { NULL } /* list terminator */ 2090 }; 2091 2092 struct regsvr_category 2093 { 2094 const CLSID *clsid; /* NULL for end of list */ 2095 }; 2096 2097 static const struct regsvr_category category_list[] = { 2098 { &CATID_WICBitmapDecoders }, 2099 { &CATID_WICBitmapEncoders }, 2100 { &CATID_WICFormatConverters }, 2101 { &CATID_WICMetadataReader }, 2102 { &CATID_WICPixelFormats }, 2103 { NULL } 2104 }; 2105 2106 static HRESULT register_categories(const struct regsvr_category *list) 2107 { 2108 LONG res; 2109 WCHAR buf[39]; 2110 HKEY coclass_key, categories_key, instance_key; 2111 2112 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, 2113 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); 2114 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); 2115 2116 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39); 2117 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 2118 KEY_READ | KEY_WRITE, NULL, &categories_key, NULL); 2119 if (res != ERROR_SUCCESS) 2120 { 2121 RegCloseKey(coclass_key); 2122 return HRESULT_FROM_WIN32(res); 2123 } 2124 2125 res = RegCreateKeyExW(categories_key, instance_keyname, 0, NULL, 0, 2126 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL); 2127 2128 for (; res == ERROR_SUCCESS && list->clsid; list++) 2129 { 2130 HKEY instance_clsid_key; 2131 2132 StringFromGUID2(list->clsid, buf, 39); 2133 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0, 2134 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL); 2135 if (res == ERROR_SUCCESS) 2136 { 2137 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ, 2138 (const BYTE *)buf, 78); 2139 RegCloseKey(instance_clsid_key); 2140 } 2141 } 2142 2143 RegCloseKey(instance_key); 2144 RegCloseKey(categories_key); 2145 RegCloseKey(coclass_key); 2146 2147 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 2148 } 2149 2150 static HRESULT unregister_categories(const struct regsvr_category *list) 2151 { 2152 LONG res; 2153 WCHAR buf[39]; 2154 HKEY coclass_key, categories_key, instance_key; 2155 2156 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, 2157 KEY_READ | KEY_WRITE, &coclass_key); 2158 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); 2159 2160 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39); 2161 res = RegOpenKeyExW(coclass_key, buf, 0, 2162 KEY_READ | KEY_WRITE, &categories_key); 2163 if (res != ERROR_SUCCESS) 2164 { 2165 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 2166 RegCloseKey(coclass_key); 2167 return HRESULT_FROM_WIN32(res); 2168 } 2169 2170 res = RegOpenKeyExW(categories_key, instance_keyname, 0, 2171 KEY_READ | KEY_WRITE, &instance_key); 2172 2173 for (; res == ERROR_SUCCESS && list->clsid; list++) 2174 { 2175 StringFromGUID2(list->clsid, buf, 39); 2176 res = RegDeleteTreeW(instance_key, buf); 2177 } 2178 2179 RegCloseKey(instance_key); 2180 RegCloseKey(categories_key); 2181 2182 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39); 2183 res = RegDeleteTreeW(coclass_key, buf); 2184 2185 RegCloseKey(coclass_key); 2186 2187 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 2188 } 2189 2190 extern HRESULT WINAPI WIC_DllRegisterServer(void) DECLSPEC_HIDDEN; 2191 extern HRESULT WINAPI WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN; 2192 2193 HRESULT WINAPI DllRegisterServer(void) 2194 { 2195 HRESULT hr; 2196 2197 TRACE("\n"); 2198 2199 hr = WIC_DllRegisterServer(); 2200 if (SUCCEEDED(hr)) 2201 hr = register_categories(category_list); 2202 if (SUCCEEDED(hr)) 2203 hr = register_decoders(decoder_list); 2204 if (SUCCEEDED(hr)) 2205 hr = register_encoders(encoder_list); 2206 if (SUCCEEDED(hr)) 2207 hr = register_converters(converter_list); 2208 if (SUCCEEDED(hr)) 2209 hr = register_metadatareaders(metadatareader_list); 2210 if (SUCCEEDED(hr)) 2211 hr = register_pixelformats(pixelformat_list); 2212 return hr; 2213 } 2214 2215 HRESULT WINAPI DllUnregisterServer(void) 2216 { 2217 HRESULT hr; 2218 2219 TRACE("\n"); 2220 2221 hr = WIC_DllUnregisterServer(); 2222 if (SUCCEEDED(hr)) 2223 hr = unregister_categories(category_list); 2224 if (SUCCEEDED(hr)) 2225 hr = unregister_decoders(decoder_list); 2226 if (SUCCEEDED(hr)) 2227 hr = unregister_encoders(encoder_list); 2228 if (SUCCEEDED(hr)) 2229 hr = unregister_converters(converter_list); 2230 if (SUCCEEDED(hr)) 2231 hr = unregister_metadatareaders(metadatareader_list); 2232 if (SUCCEEDED(hr)) 2233 hr = unregister_pixelformats(pixelformat_list); 2234 return hr; 2235 } 2236