1 /* 2 * Copyright 2009 Vincent Povirk for CodeWeavers 3 * Copyright 2012 Dmitry Timoshkov 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 18 */ 19 20 #include "config.h" 21 22 #include <stdarg.h> 23 24 #define COBJMACROS 25 26 #include "windef.h" 27 #include "winbase.h" 28 #include "winreg.h" 29 #include "objbase.h" 30 31 #include "wincodecs_private.h" 32 33 #include "wine/debug.h" 34 #include "wine/unicode.h" 35 #include "wine/list.h" 36 37 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); 38 39 static const WCHAR mimetypes_valuename[] = {'M','i','m','e','T','y','p','e','s',0}; 40 static const WCHAR author_valuename[] = {'A','u','t','h','o','r',0}; 41 static const WCHAR friendlyname_valuename[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0}; 42 static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0}; 43 static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0}; 44 static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0}; 45 static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0}; 46 static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0}; 47 static const WCHAR version_valuename[] = {'V','e','r','s','i','o','n',0}; 48 static const WCHAR specversion_valuename[] = {'S','p','e','c','V','e','r','s','i','o','n',0}; 49 static const WCHAR bitsperpixel_valuename[] = {'B','i','t','L','e','n','g','t','h',0}; 50 static const WCHAR channelcount_valuename[] = {'C','h','a','n','n','e','l','C','o','u','n','t',0}; 51 static const WCHAR channelmasks_keyname[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0}; 52 static const WCHAR numericrepresentation_valuename[] = {'N','u','m','e','r','i','c','R','e','p','r','e','s','e','n','t','a','t','i','o','n',0}; 53 static const WCHAR supportstransparency_valuename[] = {'S','u','p','p','o','r','t','s','T','r','a','n','s','p','a','r','e','n','c','y',0}; 54 static const WCHAR requiresfullstream_valuename[] = {'R','e','q','u','i','r','e','s','F','u','l','l','S','t','r','e','a','m',0}; 55 static const WCHAR supportspadding_valuename[] = {'S','u','p','p','o','r','t','s','P','a','d','d','i','n','g',0}; 56 static const WCHAR fileextensions_valuename[] = {'F','i','l','e','E','x','t','e','n','s','i','o','n','s',0}; 57 static const WCHAR containers_keyname[] = {'C','o','n','t','a','i','n','e','r','s',0}; 58 59 static HRESULT ComponentInfo_GetStringValue(HKEY classkey, LPCWSTR value, 60 UINT buffer_size, WCHAR *buffer, UINT *actual_size) 61 { 62 LONG ret; 63 DWORD cbdata=buffer_size * sizeof(WCHAR); 64 65 if (!actual_size) 66 return E_INVALIDARG; 67 68 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL, 69 buffer, &cbdata); 70 71 if (ret == ERROR_FILE_NOT_FOUND) 72 { 73 *actual_size = 0; 74 return S_OK; 75 } 76 77 if (ret == 0 || ret == ERROR_MORE_DATA) 78 *actual_size = cbdata/sizeof(WCHAR); 79 80 if (!buffer && buffer_size != 0) 81 /* Yes, native returns the correct size in this case. */ 82 return E_INVALIDARG; 83 84 if (ret == ERROR_MORE_DATA) 85 return WINCODEC_ERR_INSUFFICIENTBUFFER; 86 87 return HRESULT_FROM_WIN32(ret); 88 } 89 90 static HRESULT ComponentInfo_GetGUIDValue(HKEY classkey, LPCWSTR value, 91 GUID *result) 92 { 93 LONG ret; 94 WCHAR guid_string[39]; 95 DWORD cbdata = sizeof(guid_string); 96 HRESULT hr; 97 98 if (!result) 99 return E_INVALIDARG; 100 101 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL, 102 guid_string, &cbdata); 103 104 if (ret != ERROR_SUCCESS) 105 return HRESULT_FROM_WIN32(ret); 106 107 if (cbdata < sizeof(guid_string)) 108 { 109 ERR("incomplete GUID value\n"); 110 return E_FAIL; 111 } 112 113 hr = CLSIDFromString(guid_string, result); 114 115 return hr; 116 } 117 118 static HRESULT ComponentInfo_GetDWORDValue(HKEY classkey, LPCWSTR value, 119 DWORD *result) 120 { 121 LONG ret; 122 DWORD cbdata = sizeof(DWORD); 123 124 if (!result) 125 return E_INVALIDARG; 126 127 ret = RegGetValueW(classkey, NULL, value, RRF_RT_DWORD, NULL, 128 result, &cbdata); 129 130 if (ret == ERROR_FILE_NOT_FOUND) 131 { 132 *result = 0; 133 return S_OK; 134 } 135 136 return HRESULT_FROM_WIN32(ret); 137 } 138 139 static HRESULT ComponentInfo_GetGuidList(HKEY classkey, LPCWSTR subkeyname, 140 UINT buffersize, GUID *buffer, UINT *actual_size) 141 { 142 LONG ret; 143 HKEY subkey; 144 UINT items_returned; 145 WCHAR guid_string[39]; 146 DWORD guid_string_size; 147 HRESULT hr=S_OK; 148 149 if (!actual_size) 150 return E_INVALIDARG; 151 152 ret = RegOpenKeyExW(classkey, subkeyname, 0, KEY_READ, &subkey); 153 if (ret == ERROR_FILE_NOT_FOUND) 154 { 155 *actual_size = 0; 156 return S_OK; 157 } 158 else if (ret != ERROR_SUCCESS) return HRESULT_FROM_WIN32(ret); 159 160 if (buffer) 161 { 162 items_returned = 0; 163 guid_string_size = 39; 164 while (items_returned < buffersize) 165 { 166 ret = RegEnumKeyExW(subkey, items_returned, guid_string, 167 &guid_string_size, NULL, NULL, NULL, NULL); 168 169 if (ret != ERROR_SUCCESS) 170 { 171 hr = HRESULT_FROM_WIN32(ret); 172 break; 173 } 174 175 if (guid_string_size != 38) 176 { 177 hr = E_FAIL; 178 break; 179 } 180 181 hr = CLSIDFromString(guid_string, &buffer[items_returned]); 182 if (FAILED(hr)) 183 break; 184 185 items_returned++; 186 guid_string_size = 39; 187 } 188 189 if (ret == ERROR_NO_MORE_ITEMS) 190 hr = S_OK; 191 192 *actual_size = items_returned; 193 } 194 else 195 { 196 ret = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, actual_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 197 if (ret != ERROR_SUCCESS) 198 hr = HRESULT_FROM_WIN32(ret); 199 } 200 201 RegCloseKey(subkey); 202 203 return hr; 204 } 205 206 typedef struct { 207 IWICBitmapDecoderInfo IWICBitmapDecoderInfo_iface; 208 LONG ref; 209 HKEY classkey; 210 CLSID clsid; 211 } BitmapDecoderInfo; 212 213 static inline BitmapDecoderInfo *impl_from_IWICBitmapDecoderInfo(IWICBitmapDecoderInfo *iface) 214 { 215 return CONTAINING_RECORD(iface, BitmapDecoderInfo, IWICBitmapDecoderInfo_iface); 216 } 217 218 static HRESULT WINAPI BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo *iface, REFIID iid, 219 void **ppv) 220 { 221 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); 222 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); 223 224 if (!ppv) return E_INVALIDARG; 225 226 if (IsEqualIID(&IID_IUnknown, iid) || 227 IsEqualIID(&IID_IWICComponentInfo, iid) || 228 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) || 229 IsEqualIID(&IID_IWICBitmapDecoderInfo ,iid)) 230 { 231 *ppv = &This->IWICBitmapDecoderInfo_iface; 232 } 233 else 234 { 235 *ppv = NULL; 236 return E_NOINTERFACE; 237 } 238 239 IUnknown_AddRef((IUnknown*)*ppv); 240 return S_OK; 241 } 242 243 static ULONG WINAPI BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo *iface) 244 { 245 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); 246 ULONG ref = InterlockedIncrement(&This->ref); 247 248 TRACE("(%p) refcount=%u\n", iface, ref); 249 250 return ref; 251 } 252 253 static ULONG WINAPI BitmapDecoderInfo_Release(IWICBitmapDecoderInfo *iface) 254 { 255 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); 256 ULONG ref = InterlockedDecrement(&This->ref); 257 258 TRACE("(%p) refcount=%u\n", iface, ref); 259 260 if (ref == 0) 261 { 262 RegCloseKey(This->classkey); 263 HeapFree(GetProcessHeap(), 0, This); 264 } 265 266 return ref; 267 } 268 269 static HRESULT WINAPI BitmapDecoderInfo_GetComponentType(IWICBitmapDecoderInfo *iface, 270 WICComponentType *pType) 271 { 272 TRACE("(%p,%p)\n", iface, pType); 273 if (!pType) return E_INVALIDARG; 274 *pType = WICDecoder; 275 return S_OK; 276 } 277 278 static HRESULT WINAPI BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo *iface, CLSID *pclsid) 279 { 280 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); 281 TRACE("(%p,%p)\n", iface, pclsid); 282 283 if (!pclsid) 284 return E_INVALIDARG; 285 286 memcpy(pclsid, &This->clsid, sizeof(CLSID)); 287 288 return S_OK; 289 } 290 291 static HRESULT WINAPI BitmapDecoderInfo_GetSigningStatus(IWICBitmapDecoderInfo *iface, DWORD *pStatus) 292 { 293 FIXME("(%p,%p): stub\n", iface, pStatus); 294 return E_NOTIMPL; 295 } 296 297 static HRESULT WINAPI BitmapDecoderInfo_GetAuthor(IWICBitmapDecoderInfo *iface, UINT cchAuthor, 298 WCHAR *wzAuthor, UINT *pcchActual) 299 { 300 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); 301 302 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual); 303 304 return ComponentInfo_GetStringValue(This->classkey, author_valuename, 305 cchAuthor, wzAuthor, pcchActual); 306 } 307 308 static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *iface, GUID *pguidVendor) 309 { 310 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); 311 312 TRACE("(%p,%p)\n", iface, pguidVendor); 313 314 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor); 315 } 316 317 static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, UINT cchVersion, 318 WCHAR *wzVersion, UINT *pcchActual) 319 { 320 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); 321 322 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual); 323 324 return ComponentInfo_GetStringValue(This->classkey, version_valuename, 325 cchVersion, wzVersion, pcchActual); 326 } 327 328 static HRESULT WINAPI BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo *iface, UINT cchSpecVersion, 329 WCHAR *wzSpecVersion, UINT *pcchActual) 330 { 331 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); 332 333 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual); 334 335 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename, 336 cchSpecVersion, wzSpecVersion, pcchActual); 337 } 338 339 static HRESULT WINAPI BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo *iface, UINT cchFriendlyName, 340 WCHAR *wzFriendlyName, UINT *pcchActual) 341 { 342 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); 343 344 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual); 345 346 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename, 347 cchFriendlyName, wzFriendlyName, pcchActual); 348 } 349 350 static HRESULT WINAPI BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo *iface, 351 GUID *pguidContainerFormat) 352 { 353 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); 354 TRACE("(%p,%p)\n", iface, pguidContainerFormat); 355 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat); 356 } 357 358 static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *iface, 359 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual) 360 { 361 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); 362 TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual); 363 return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual); 364 } 365 366 static HRESULT WINAPI BitmapDecoderInfo_GetColorManagementVersion(IWICBitmapDecoderInfo *iface, 367 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual) 368 { 369 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual); 370 return E_NOTIMPL; 371 } 372 373 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceManufacturer(IWICBitmapDecoderInfo *iface, 374 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual) 375 { 376 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual); 377 return E_NOTIMPL; 378 } 379 380 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceModels(IWICBitmapDecoderInfo *iface, 381 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual) 382 { 383 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual); 384 return E_NOTIMPL; 385 } 386 387 static HRESULT WINAPI BitmapDecoderInfo_GetMimeTypes(IWICBitmapDecoderInfo *iface, 388 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual) 389 { 390 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); 391 392 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual); 393 394 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename, 395 cchMimeTypes, wzMimeTypes, pcchActual); 396 } 397 398 static HRESULT WINAPI BitmapDecoderInfo_GetFileExtensions(IWICBitmapDecoderInfo *iface, 399 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual) 400 { 401 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); 402 403 TRACE("(%p,%u,%p,%p)\n", iface, cchFileExtensions, wzFileExtensions, pcchActual); 404 405 return ComponentInfo_GetStringValue(This->classkey, fileextensions_valuename, 406 cchFileExtensions, wzFileExtensions, pcchActual); 407 } 408 409 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportAnimation(IWICBitmapDecoderInfo *iface, 410 BOOL *pfSupportAnimation) 411 { 412 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation); 413 return E_NOTIMPL; 414 } 415 416 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportChromaKey(IWICBitmapDecoderInfo *iface, 417 BOOL *pfSupportChromaKey) 418 { 419 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey); 420 return E_NOTIMPL; 421 } 422 423 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportLossless(IWICBitmapDecoderInfo *iface, 424 BOOL *pfSupportLossless) 425 { 426 FIXME("(%p,%p): stub\n", iface, pfSupportLossless); 427 return E_NOTIMPL; 428 } 429 430 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportMultiframe(IWICBitmapDecoderInfo *iface, 431 BOOL *pfSupportMultiframe) 432 { 433 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe); 434 return E_NOTIMPL; 435 } 436 437 static HRESULT WINAPI BitmapDecoderInfo_MatchesMimeType(IWICBitmapDecoderInfo *iface, 438 LPCWSTR wzMimeType, BOOL *pfMatches) 439 { 440 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches); 441 return E_NOTIMPL; 442 } 443 444 static HRESULT WINAPI BitmapDecoderInfo_GetPatterns(IWICBitmapDecoderInfo *iface, 445 UINT cbSizePatterns, WICBitmapPattern *pPatterns, UINT *pcPatterns, UINT *pcbPatternsActual) 446 { 447 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); 448 UINT pattern_count=0, patterns_size=0; 449 WCHAR subkeyname[11]; 450 LONG res; 451 HKEY patternskey, patternkey; 452 static const WCHAR uintformatW[] = {'%','u',0}; 453 static const WCHAR patternsW[] = {'P','a','t','t','e','r','n','s',0}; 454 static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0}; 455 static const WCHAR lengthW[] = {'L','e','n','g','t','h',0}; 456 static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0}; 457 static const WCHAR maskW[] = {'M','a','s','k',0}; 458 static const WCHAR endofstreamW[] = {'E','n','d','O','f','S','t','r','e','a','m',0}; 459 HRESULT hr=S_OK; 460 UINT i; 461 BYTE *bPatterns=(BYTE*)pPatterns; 462 DWORD length, valuesize; 463 464 TRACE("(%p,%i,%p,%p,%p)\n", iface, cbSizePatterns, pPatterns, pcPatterns, pcbPatternsActual); 465 466 res = RegOpenKeyExW(This->classkey, patternsW, 0, KEY_READ, &patternskey); 467 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); 468 469 res = RegQueryInfoKeyW(patternskey, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 470 if (res == ERROR_SUCCESS) 471 { 472 patterns_size = pattern_count * sizeof(WICBitmapPattern); 473 474 for (i=0; i<pattern_count; i++) 475 { 476 snprintfW(subkeyname, 11, uintformatW, i); 477 res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey); 478 if (res == ERROR_SUCCESS) 479 { 480 valuesize = sizeof(ULONG); 481 res = RegGetValueW(patternkey, NULL, lengthW, RRF_RT_DWORD, NULL, 482 &length, &valuesize); 483 patterns_size += length*2; 484 485 if ((cbSizePatterns >= patterns_size) && (res == ERROR_SUCCESS)) 486 { 487 pPatterns[i].Length = length; 488 489 pPatterns[i].EndOfStream = 0; 490 valuesize = sizeof(BOOL); 491 RegGetValueW(patternkey, NULL, endofstreamW, RRF_RT_DWORD, NULL, 492 &pPatterns[i].EndOfStream, &valuesize); 493 494 pPatterns[i].Position.QuadPart = 0; 495 valuesize = sizeof(ULARGE_INTEGER); 496 res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL, 497 &pPatterns[i].Position, &valuesize); 498 499 if (res == ERROR_SUCCESS) 500 { 501 pPatterns[i].Pattern = bPatterns+patterns_size-length*2; 502 valuesize = length; 503 res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL, 504 pPatterns[i].Pattern, &valuesize); 505 } 506 507 if (res == ERROR_SUCCESS) 508 { 509 pPatterns[i].Mask = bPatterns+patterns_size-length; 510 valuesize = length; 511 res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL, 512 pPatterns[i].Mask, &valuesize); 513 } 514 } 515 516 RegCloseKey(patternkey); 517 } 518 if (res != ERROR_SUCCESS) 519 { 520 hr = HRESULT_FROM_WIN32(res); 521 break; 522 } 523 } 524 } 525 else hr = HRESULT_FROM_WIN32(res); 526 527 RegCloseKey(patternskey); 528 529 if (hr == S_OK) 530 { 531 *pcPatterns = pattern_count; 532 *pcbPatternsActual = patterns_size; 533 if (pPatterns && cbSizePatterns < patterns_size) 534 hr = WINCODEC_ERR_INSUFFICIENTBUFFER; 535 } 536 537 return hr; 538 } 539 540 static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *iface, 541 IStream *pIStream, BOOL *pfMatches) 542 { 543 WICBitmapPattern *patterns; 544 UINT pattern_count=0, patterns_size=0; 545 HRESULT hr; 546 UINT i; 547 ULONG pos; 548 BYTE *data=NULL; 549 ULONG datasize=0; 550 ULONG bytesread; 551 LARGE_INTEGER seekpos; 552 553 TRACE("(%p,%p,%p)\n", iface, pIStream, pfMatches); 554 555 hr = BitmapDecoderInfo_GetPatterns(iface, 0, NULL, &pattern_count, &patterns_size); 556 if (FAILED(hr)) return hr; 557 558 patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size); 559 if (!patterns) return E_OUTOFMEMORY; 560 561 hr = BitmapDecoderInfo_GetPatterns(iface, patterns_size, patterns, &pattern_count, &patterns_size); 562 if (FAILED(hr)) goto end; 563 564 for (i=0; i<pattern_count; i++) 565 { 566 if (datasize < patterns[i].Length) 567 { 568 HeapFree(GetProcessHeap(), 0, data); 569 datasize = patterns[i].Length; 570 data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length); 571 if (!data) 572 { 573 hr = E_OUTOFMEMORY; 574 break; 575 } 576 } 577 578 if (patterns[i].EndOfStream) 579 seekpos.QuadPart = -patterns[i].Position.QuadPart; 580 else 581 seekpos.QuadPart = patterns[i].Position.QuadPart; 582 hr = IStream_Seek(pIStream, seekpos, patterns[i].EndOfStream ? STREAM_SEEK_END : STREAM_SEEK_SET, NULL); 583 if (hr == STG_E_INVALIDFUNCTION) continue; /* before start of stream */ 584 if (FAILED(hr)) break; 585 586 hr = IStream_Read(pIStream, data, patterns[i].Length, &bytesread); 587 if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */ 588 continue; 589 if (FAILED(hr)) break; 590 591 for (pos=0; pos<patterns[i].Length; pos++) 592 { 593 if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos]) 594 break; 595 } 596 if (pos == patterns[i].Length) /* matches pattern */ 597 { 598 hr = S_OK; 599 *pfMatches = TRUE; 600 break; 601 } 602 } 603 604 if (i == pattern_count) /* does not match any pattern */ 605 { 606 hr = S_OK; 607 *pfMatches = FALSE; 608 } 609 610 end: 611 HeapFree(GetProcessHeap(), 0, patterns); 612 HeapFree(GetProcessHeap(), 0, data); 613 614 return hr; 615 } 616 617 static HRESULT WINAPI BitmapDecoderInfo_CreateInstance(IWICBitmapDecoderInfo *iface, 618 IWICBitmapDecoder **ppIBitmapDecoder) 619 { 620 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); 621 622 TRACE("(%p,%p)\n", iface, ppIBitmapDecoder); 623 624 return create_instance(&This->clsid, &IID_IWICBitmapDecoder, (void**)ppIBitmapDecoder); 625 } 626 627 static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = { 628 BitmapDecoderInfo_QueryInterface, 629 BitmapDecoderInfo_AddRef, 630 BitmapDecoderInfo_Release, 631 BitmapDecoderInfo_GetComponentType, 632 BitmapDecoderInfo_GetCLSID, 633 BitmapDecoderInfo_GetSigningStatus, 634 BitmapDecoderInfo_GetAuthor, 635 BitmapDecoderInfo_GetVendorGUID, 636 BitmapDecoderInfo_GetVersion, 637 BitmapDecoderInfo_GetSpecVersion, 638 BitmapDecoderInfo_GetFriendlyName, 639 BitmapDecoderInfo_GetContainerFormat, 640 BitmapDecoderInfo_GetPixelFormats, 641 BitmapDecoderInfo_GetColorManagementVersion, 642 BitmapDecoderInfo_GetDeviceManufacturer, 643 BitmapDecoderInfo_GetDeviceModels, 644 BitmapDecoderInfo_GetMimeTypes, 645 BitmapDecoderInfo_GetFileExtensions, 646 BitmapDecoderInfo_DoesSupportAnimation, 647 BitmapDecoderInfo_DoesSupportChromaKey, 648 BitmapDecoderInfo_DoesSupportLossless, 649 BitmapDecoderInfo_DoesSupportMultiframe, 650 BitmapDecoderInfo_MatchesMimeType, 651 BitmapDecoderInfo_GetPatterns, 652 BitmapDecoderInfo_MatchesPattern, 653 BitmapDecoderInfo_CreateInstance 654 }; 655 656 static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo) 657 { 658 BitmapDecoderInfo *This; 659 660 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapDecoderInfo)); 661 if (!This) 662 { 663 RegCloseKey(classkey); 664 return E_OUTOFMEMORY; 665 } 666 667 This->IWICBitmapDecoderInfo_iface.lpVtbl = &BitmapDecoderInfo_Vtbl; 668 This->ref = 1; 669 This->classkey = classkey; 670 memcpy(&This->clsid, clsid, sizeof(CLSID)); 671 672 *ppIInfo = (IWICComponentInfo *)&This->IWICBitmapDecoderInfo_iface; 673 return S_OK; 674 } 675 676 typedef struct { 677 IWICBitmapEncoderInfo IWICBitmapEncoderInfo_iface; 678 LONG ref; 679 HKEY classkey; 680 CLSID clsid; 681 } BitmapEncoderInfo; 682 683 static inline BitmapEncoderInfo *impl_from_IWICBitmapEncoderInfo(IWICBitmapEncoderInfo *iface) 684 { 685 return CONTAINING_RECORD(iface, BitmapEncoderInfo, IWICBitmapEncoderInfo_iface); 686 } 687 688 static HRESULT WINAPI BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo *iface, REFIID iid, 689 void **ppv) 690 { 691 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); 692 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); 693 694 if (!ppv) return E_INVALIDARG; 695 696 if (IsEqualIID(&IID_IUnknown, iid) || 697 IsEqualIID(&IID_IWICComponentInfo, iid) || 698 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) || 699 IsEqualIID(&IID_IWICBitmapEncoderInfo ,iid)) 700 { 701 *ppv = &This->IWICBitmapEncoderInfo_iface; 702 } 703 else 704 { 705 *ppv = NULL; 706 return E_NOINTERFACE; 707 } 708 709 IUnknown_AddRef((IUnknown*)*ppv); 710 return S_OK; 711 } 712 713 static ULONG WINAPI BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo *iface) 714 { 715 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); 716 ULONG ref = InterlockedIncrement(&This->ref); 717 718 TRACE("(%p) refcount=%u\n", iface, ref); 719 720 return ref; 721 } 722 723 static ULONG WINAPI BitmapEncoderInfo_Release(IWICBitmapEncoderInfo *iface) 724 { 725 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); 726 ULONG ref = InterlockedDecrement(&This->ref); 727 728 TRACE("(%p) refcount=%u\n", iface, ref); 729 730 if (ref == 0) 731 { 732 RegCloseKey(This->classkey); 733 HeapFree(GetProcessHeap(), 0, This); 734 } 735 736 return ref; 737 } 738 739 static HRESULT WINAPI BitmapEncoderInfo_GetComponentType(IWICBitmapEncoderInfo *iface, 740 WICComponentType *pType) 741 { 742 TRACE("(%p,%p)\n", iface, pType); 743 if (!pType) return E_INVALIDARG; 744 *pType = WICEncoder; 745 return S_OK; 746 } 747 748 static HRESULT WINAPI BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo *iface, CLSID *pclsid) 749 { 750 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); 751 TRACE("(%p,%p)\n", iface, pclsid); 752 753 if (!pclsid) 754 return E_INVALIDARG; 755 756 memcpy(pclsid, &This->clsid, sizeof(CLSID)); 757 758 return S_OK; 759 } 760 761 static HRESULT WINAPI BitmapEncoderInfo_GetSigningStatus(IWICBitmapEncoderInfo *iface, DWORD *pStatus) 762 { 763 FIXME("(%p,%p): stub\n", iface, pStatus); 764 return E_NOTIMPL; 765 } 766 767 static HRESULT WINAPI BitmapEncoderInfo_GetAuthor(IWICBitmapEncoderInfo *iface, UINT cchAuthor, 768 WCHAR *wzAuthor, UINT *pcchActual) 769 { 770 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); 771 772 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual); 773 774 return ComponentInfo_GetStringValue(This->classkey, author_valuename, 775 cchAuthor, wzAuthor, pcchActual); 776 } 777 778 static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *iface, GUID *pguidVendor) 779 { 780 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); 781 782 TRACE("(%p,%p)\n", iface, pguidVendor); 783 784 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor); 785 } 786 787 static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, UINT cchVersion, 788 WCHAR *wzVersion, UINT *pcchActual) 789 { 790 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); 791 792 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual); 793 794 return ComponentInfo_GetStringValue(This->classkey, version_valuename, 795 cchVersion, wzVersion, pcchActual); 796 } 797 798 static HRESULT WINAPI BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo *iface, UINT cchSpecVersion, 799 WCHAR *wzSpecVersion, UINT *pcchActual) 800 { 801 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); 802 803 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual); 804 805 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename, 806 cchSpecVersion, wzSpecVersion, pcchActual); 807 } 808 809 static HRESULT WINAPI BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo *iface, UINT cchFriendlyName, 810 WCHAR *wzFriendlyName, UINT *pcchActual) 811 { 812 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); 813 814 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual); 815 816 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename, 817 cchFriendlyName, wzFriendlyName, pcchActual); 818 } 819 820 static HRESULT WINAPI BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo *iface, 821 GUID *pguidContainerFormat) 822 { 823 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); 824 TRACE("(%p,%p)\n", iface, pguidContainerFormat); 825 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat); 826 } 827 828 static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *iface, 829 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual) 830 { 831 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); 832 TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual); 833 return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual); 834 } 835 836 static HRESULT WINAPI BitmapEncoderInfo_GetColorManagementVersion(IWICBitmapEncoderInfo *iface, 837 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual) 838 { 839 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual); 840 return E_NOTIMPL; 841 } 842 843 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceManufacturer(IWICBitmapEncoderInfo *iface, 844 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual) 845 { 846 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual); 847 return E_NOTIMPL; 848 } 849 850 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceModels(IWICBitmapEncoderInfo *iface, 851 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual) 852 { 853 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual); 854 return E_NOTIMPL; 855 } 856 857 static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *iface, 858 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual) 859 { 860 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); 861 862 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual); 863 864 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename, 865 cchMimeTypes, wzMimeTypes, pcchActual); 866 } 867 868 static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo *iface, 869 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual) 870 { 871 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); 872 873 TRACE("(%p,%u,%p,%p)\n", iface, cchFileExtensions, wzFileExtensions, pcchActual); 874 875 return ComponentInfo_GetStringValue(This->classkey, fileextensions_valuename, 876 cchFileExtensions, wzFileExtensions, pcchActual); 877 } 878 879 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo *iface, 880 BOOL *pfSupportAnimation) 881 { 882 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation); 883 return E_NOTIMPL; 884 } 885 886 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportChromaKey(IWICBitmapEncoderInfo *iface, 887 BOOL *pfSupportChromaKey) 888 { 889 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey); 890 return E_NOTIMPL; 891 } 892 893 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportLossless(IWICBitmapEncoderInfo *iface, 894 BOOL *pfSupportLossless) 895 { 896 FIXME("(%p,%p): stub\n", iface, pfSupportLossless); 897 return E_NOTIMPL; 898 } 899 900 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportMultiframe(IWICBitmapEncoderInfo *iface, 901 BOOL *pfSupportMultiframe) 902 { 903 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe); 904 return E_NOTIMPL; 905 } 906 907 static HRESULT WINAPI BitmapEncoderInfo_MatchesMimeType(IWICBitmapEncoderInfo *iface, 908 LPCWSTR wzMimeType, BOOL *pfMatches) 909 { 910 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches); 911 return E_NOTIMPL; 912 } 913 914 static HRESULT WINAPI BitmapEncoderInfo_CreateInstance(IWICBitmapEncoderInfo *iface, 915 IWICBitmapEncoder **ppIBitmapEncoder) 916 { 917 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); 918 919 TRACE("(%p,%p)\n", iface, ppIBitmapEncoder); 920 921 return create_instance(&This->clsid, &IID_IWICBitmapEncoder, (void**)ppIBitmapEncoder); 922 } 923 924 static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl = { 925 BitmapEncoderInfo_QueryInterface, 926 BitmapEncoderInfo_AddRef, 927 BitmapEncoderInfo_Release, 928 BitmapEncoderInfo_GetComponentType, 929 BitmapEncoderInfo_GetCLSID, 930 BitmapEncoderInfo_GetSigningStatus, 931 BitmapEncoderInfo_GetAuthor, 932 BitmapEncoderInfo_GetVendorGUID, 933 BitmapEncoderInfo_GetVersion, 934 BitmapEncoderInfo_GetSpecVersion, 935 BitmapEncoderInfo_GetFriendlyName, 936 BitmapEncoderInfo_GetContainerFormat, 937 BitmapEncoderInfo_GetPixelFormats, 938 BitmapEncoderInfo_GetColorManagementVersion, 939 BitmapEncoderInfo_GetDeviceManufacturer, 940 BitmapEncoderInfo_GetDeviceModels, 941 BitmapEncoderInfo_GetMimeTypes, 942 BitmapEncoderInfo_GetFileExtensions, 943 BitmapEncoderInfo_DoesSupportAnimation, 944 BitmapEncoderInfo_DoesSupportChromaKey, 945 BitmapEncoderInfo_DoesSupportLossless, 946 BitmapEncoderInfo_DoesSupportMultiframe, 947 BitmapEncoderInfo_MatchesMimeType, 948 BitmapEncoderInfo_CreateInstance 949 }; 950 951 static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo) 952 { 953 BitmapEncoderInfo *This; 954 955 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapEncoderInfo)); 956 if (!This) 957 { 958 RegCloseKey(classkey); 959 return E_OUTOFMEMORY; 960 } 961 962 This->IWICBitmapEncoderInfo_iface.lpVtbl = &BitmapEncoderInfo_Vtbl; 963 This->ref = 1; 964 This->classkey = classkey; 965 memcpy(&This->clsid, clsid, sizeof(CLSID)); 966 967 *ppIInfo = (IWICComponentInfo *)&This->IWICBitmapEncoderInfo_iface; 968 return S_OK; 969 } 970 971 typedef struct { 972 IWICFormatConverterInfo IWICFormatConverterInfo_iface; 973 LONG ref; 974 HKEY classkey; 975 CLSID clsid; 976 } FormatConverterInfo; 977 978 static inline FormatConverterInfo *impl_from_IWICFormatConverterInfo(IWICFormatConverterInfo *iface) 979 { 980 return CONTAINING_RECORD(iface, FormatConverterInfo, IWICFormatConverterInfo_iface); 981 } 982 983 static HRESULT WINAPI FormatConverterInfo_QueryInterface(IWICFormatConverterInfo *iface, REFIID iid, 984 void **ppv) 985 { 986 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface); 987 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); 988 989 if (!ppv) return E_INVALIDARG; 990 991 if (IsEqualIID(&IID_IUnknown, iid) || 992 IsEqualIID(&IID_IWICComponentInfo, iid) || 993 IsEqualIID(&IID_IWICFormatConverterInfo ,iid)) 994 { 995 *ppv = &This->IWICFormatConverterInfo_iface; 996 } 997 else 998 { 999 *ppv = NULL; 1000 return E_NOINTERFACE; 1001 } 1002 1003 IUnknown_AddRef((IUnknown*)*ppv); 1004 return S_OK; 1005 } 1006 1007 static ULONG WINAPI FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface) 1008 { 1009 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface); 1010 ULONG ref = InterlockedIncrement(&This->ref); 1011 1012 TRACE("(%p) refcount=%u\n", iface, ref); 1013 1014 return ref; 1015 } 1016 1017 static ULONG WINAPI FormatConverterInfo_Release(IWICFormatConverterInfo *iface) 1018 { 1019 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface); 1020 ULONG ref = InterlockedDecrement(&This->ref); 1021 1022 TRACE("(%p) refcount=%u\n", iface, ref); 1023 1024 if (ref == 0) 1025 { 1026 RegCloseKey(This->classkey); 1027 HeapFree(GetProcessHeap(), 0, This); 1028 } 1029 1030 return ref; 1031 } 1032 1033 static HRESULT WINAPI FormatConverterInfo_GetComponentType(IWICFormatConverterInfo *iface, 1034 WICComponentType *pType) 1035 { 1036 TRACE("(%p,%p)\n", iface, pType); 1037 if (!pType) return E_INVALIDARG; 1038 *pType = WICPixelFormatConverter; 1039 return S_OK; 1040 } 1041 1042 static HRESULT WINAPI FormatConverterInfo_GetCLSID(IWICFormatConverterInfo *iface, CLSID *pclsid) 1043 { 1044 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface); 1045 TRACE("(%p,%p)\n", iface, pclsid); 1046 1047 if (!pclsid) 1048 return E_INVALIDARG; 1049 1050 memcpy(pclsid, &This->clsid, sizeof(CLSID)); 1051 1052 return S_OK; 1053 } 1054 1055 static HRESULT WINAPI FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo *iface, DWORD *pStatus) 1056 { 1057 FIXME("(%p,%p): stub\n", iface, pStatus); 1058 return E_NOTIMPL; 1059 } 1060 1061 static HRESULT WINAPI FormatConverterInfo_GetAuthor(IWICFormatConverterInfo *iface, UINT cchAuthor, 1062 WCHAR *wzAuthor, UINT *pcchActual) 1063 { 1064 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface); 1065 1066 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual); 1067 1068 return ComponentInfo_GetStringValue(This->classkey, author_valuename, 1069 cchAuthor, wzAuthor, pcchActual); 1070 } 1071 1072 static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo *iface, GUID *pguidVendor) 1073 { 1074 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface); 1075 1076 TRACE("(%p,%p)\n", iface, pguidVendor); 1077 1078 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor); 1079 } 1080 1081 static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *iface, UINT cchVersion, 1082 WCHAR *wzVersion, UINT *pcchActual) 1083 { 1084 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface); 1085 1086 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual); 1087 1088 return ComponentInfo_GetStringValue(This->classkey, version_valuename, 1089 cchVersion, wzVersion, pcchActual); 1090 } 1091 1092 static HRESULT WINAPI FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo *iface, UINT cchSpecVersion, 1093 WCHAR *wzSpecVersion, UINT *pcchActual) 1094 { 1095 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface); 1096 1097 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual); 1098 1099 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename, 1100 cchSpecVersion, wzSpecVersion, pcchActual); 1101 } 1102 1103 static HRESULT WINAPI FormatConverterInfo_GetFriendlyName(IWICFormatConverterInfo *iface, UINT cchFriendlyName, 1104 WCHAR *wzFriendlyName, UINT *pcchActual) 1105 { 1106 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface); 1107 1108 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual); 1109 1110 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename, 1111 cchFriendlyName, wzFriendlyName, pcchActual); 1112 } 1113 1114 static HRESULT WINAPI FormatConverterInfo_GetPixelFormats(IWICFormatConverterInfo *iface, 1115 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual) 1116 { 1117 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual); 1118 return E_NOTIMPL; 1119 } 1120 1121 static HRESULT WINAPI FormatConverterInfo_CreateInstance(IWICFormatConverterInfo *iface, 1122 IWICFormatConverter **ppIFormatConverter) 1123 { 1124 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface); 1125 1126 TRACE("(%p,%p)\n", iface, ppIFormatConverter); 1127 1128 return create_instance(&This->clsid, &IID_IWICFormatConverter, 1129 (void**)ppIFormatConverter); 1130 } 1131 1132 static BOOL ConverterSupportsFormat(IWICFormatConverterInfo *iface, const WCHAR *formatguid) 1133 { 1134 LONG res; 1135 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface); 1136 HKEY formats_key, guid_key; 1137 1138 /* Avoid testing using IWICFormatConverter_GetPixelFormats because that 1139 would be O(n). A registry test should do better. */ 1140 1141 res = RegOpenKeyExW(This->classkey, pixelformats_keyname, 0, KEY_READ, &formats_key); 1142 if (res != ERROR_SUCCESS) return FALSE; 1143 1144 res = RegOpenKeyExW(formats_key, formatguid, 0, KEY_READ, &guid_key); 1145 if (res == ERROR_SUCCESS) RegCloseKey(guid_key); 1146 1147 RegCloseKey(formats_key); 1148 1149 return (res == ERROR_SUCCESS); 1150 } 1151 1152 static const IWICFormatConverterInfoVtbl FormatConverterInfo_Vtbl = { 1153 FormatConverterInfo_QueryInterface, 1154 FormatConverterInfo_AddRef, 1155 FormatConverterInfo_Release, 1156 FormatConverterInfo_GetComponentType, 1157 FormatConverterInfo_GetCLSID, 1158 FormatConverterInfo_GetSigningStatus, 1159 FormatConverterInfo_GetAuthor, 1160 FormatConverterInfo_GetVendorGUID, 1161 FormatConverterInfo_GetVersion, 1162 FormatConverterInfo_GetSpecVersion, 1163 FormatConverterInfo_GetFriendlyName, 1164 FormatConverterInfo_GetPixelFormats, 1165 FormatConverterInfo_CreateInstance 1166 }; 1167 1168 static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo) 1169 { 1170 FormatConverterInfo *This; 1171 1172 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo)); 1173 if (!This) 1174 { 1175 RegCloseKey(classkey); 1176 return E_OUTOFMEMORY; 1177 } 1178 1179 This->IWICFormatConverterInfo_iface.lpVtbl = &FormatConverterInfo_Vtbl; 1180 This->ref = 1; 1181 This->classkey = classkey; 1182 memcpy(&This->clsid, clsid, sizeof(CLSID)); 1183 1184 *ppIInfo = (IWICComponentInfo *)&This->IWICFormatConverterInfo_iface; 1185 return S_OK; 1186 } 1187 1188 typedef struct { 1189 IWICPixelFormatInfo2 IWICPixelFormatInfo2_iface; 1190 LONG ref; 1191 HKEY classkey; 1192 CLSID clsid; 1193 } PixelFormatInfo; 1194 1195 static inline PixelFormatInfo *impl_from_IWICPixelFormatInfo2(IWICPixelFormatInfo2 *iface) 1196 { 1197 return CONTAINING_RECORD(iface, PixelFormatInfo, IWICPixelFormatInfo2_iface); 1198 } 1199 1200 static HRESULT WINAPI PixelFormatInfo_QueryInterface(IWICPixelFormatInfo2 *iface, REFIID iid, 1201 void **ppv) 1202 { 1203 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); 1204 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); 1205 1206 if (!ppv) return E_INVALIDARG; 1207 1208 if (IsEqualIID(&IID_IUnknown, iid) || 1209 IsEqualIID(&IID_IWICComponentInfo, iid) || 1210 IsEqualIID(&IID_IWICPixelFormatInfo, iid) || 1211 IsEqualIID(&IID_IWICPixelFormatInfo2 ,iid)) 1212 { 1213 *ppv = &This->IWICPixelFormatInfo2_iface; 1214 } 1215 else 1216 { 1217 *ppv = NULL; 1218 return E_NOINTERFACE; 1219 } 1220 1221 IUnknown_AddRef((IUnknown*)*ppv); 1222 return S_OK; 1223 } 1224 1225 static ULONG WINAPI PixelFormatInfo_AddRef(IWICPixelFormatInfo2 *iface) 1226 { 1227 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); 1228 ULONG ref = InterlockedIncrement(&This->ref); 1229 1230 TRACE("(%p) refcount=%u\n", iface, ref); 1231 1232 return ref; 1233 } 1234 1235 static ULONG WINAPI PixelFormatInfo_Release(IWICPixelFormatInfo2 *iface) 1236 { 1237 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); 1238 ULONG ref = InterlockedDecrement(&This->ref); 1239 1240 TRACE("(%p) refcount=%u\n", iface, ref); 1241 1242 if (ref == 0) 1243 { 1244 RegCloseKey(This->classkey); 1245 HeapFree(GetProcessHeap(), 0, This); 1246 } 1247 1248 return ref; 1249 } 1250 1251 static HRESULT WINAPI PixelFormatInfo_GetComponentType(IWICPixelFormatInfo2 *iface, 1252 WICComponentType *pType) 1253 { 1254 TRACE("(%p,%p)\n", iface, pType); 1255 if (!pType) return E_INVALIDARG; 1256 *pType = WICPixelFormat; 1257 return S_OK; 1258 } 1259 1260 static HRESULT WINAPI PixelFormatInfo_GetCLSID(IWICPixelFormatInfo2 *iface, CLSID *pclsid) 1261 { 1262 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); 1263 TRACE("(%p,%p)\n", iface, pclsid); 1264 1265 if (!pclsid) 1266 return E_INVALIDARG; 1267 1268 memcpy(pclsid, &This->clsid, sizeof(CLSID)); 1269 1270 return S_OK; 1271 } 1272 1273 static HRESULT WINAPI PixelFormatInfo_GetSigningStatus(IWICPixelFormatInfo2 *iface, DWORD *pStatus) 1274 { 1275 TRACE("(%p,%p)\n", iface, pStatus); 1276 1277 if (!pStatus) 1278 return E_INVALIDARG; 1279 1280 /* Pixel formats don't require code, so they are considered signed. */ 1281 *pStatus = WICComponentSigned; 1282 1283 return S_OK; 1284 } 1285 1286 static HRESULT WINAPI PixelFormatInfo_GetAuthor(IWICPixelFormatInfo2 *iface, UINT cchAuthor, 1287 WCHAR *wzAuthor, UINT *pcchActual) 1288 { 1289 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); 1290 1291 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual); 1292 1293 return ComponentInfo_GetStringValue(This->classkey, author_valuename, 1294 cchAuthor, wzAuthor, pcchActual); 1295 } 1296 1297 static HRESULT WINAPI PixelFormatInfo_GetVendorGUID(IWICPixelFormatInfo2 *iface, GUID *pguidVendor) 1298 { 1299 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); 1300 1301 TRACE("(%p,%p)\n", iface, pguidVendor); 1302 1303 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor); 1304 } 1305 1306 static HRESULT WINAPI PixelFormatInfo_GetVersion(IWICPixelFormatInfo2 *iface, UINT cchVersion, 1307 WCHAR *wzVersion, UINT *pcchActual) 1308 { 1309 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); 1310 1311 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual); 1312 1313 return ComponentInfo_GetStringValue(This->classkey, version_valuename, 1314 cchVersion, wzVersion, pcchActual); 1315 } 1316 1317 static HRESULT WINAPI PixelFormatInfo_GetSpecVersion(IWICPixelFormatInfo2 *iface, UINT cchSpecVersion, 1318 WCHAR *wzSpecVersion, UINT *pcchActual) 1319 { 1320 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); 1321 1322 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual); 1323 1324 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename, 1325 cchSpecVersion, wzSpecVersion, pcchActual); 1326 } 1327 1328 static HRESULT WINAPI PixelFormatInfo_GetFriendlyName(IWICPixelFormatInfo2 *iface, UINT cchFriendlyName, 1329 WCHAR *wzFriendlyName, UINT *pcchActual) 1330 { 1331 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); 1332 1333 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual); 1334 1335 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename, 1336 cchFriendlyName, wzFriendlyName, pcchActual); 1337 } 1338 1339 static HRESULT WINAPI PixelFormatInfo_GetFormatGUID(IWICPixelFormatInfo2 *iface, 1340 GUID *pFormat) 1341 { 1342 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); 1343 TRACE("(%p,%p)\n", iface, pFormat); 1344 1345 if (!pFormat) 1346 return E_INVALIDARG; 1347 1348 *pFormat = This->clsid; 1349 1350 return S_OK; 1351 } 1352 1353 static HRESULT WINAPI PixelFormatInfo_GetColorContext(IWICPixelFormatInfo2 *iface, 1354 IWICColorContext **ppIColorContext) 1355 { 1356 FIXME("(%p,%p): stub\n", iface, ppIColorContext); 1357 return E_NOTIMPL; 1358 } 1359 1360 static HRESULT WINAPI PixelFormatInfo_GetBitsPerPixel(IWICPixelFormatInfo2 *iface, 1361 UINT *puiBitsPerPixel) 1362 { 1363 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); 1364 1365 TRACE("(%p,%p)\n", iface, puiBitsPerPixel); 1366 1367 return ComponentInfo_GetDWORDValue(This->classkey, bitsperpixel_valuename, puiBitsPerPixel); 1368 } 1369 1370 static HRESULT WINAPI PixelFormatInfo_GetChannelCount(IWICPixelFormatInfo2 *iface, 1371 UINT *puiChannelCount) 1372 { 1373 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); 1374 1375 TRACE("(%p,%p)\n", iface, puiChannelCount); 1376 1377 return ComponentInfo_GetDWORDValue(This->classkey, channelcount_valuename, puiChannelCount); 1378 } 1379 1380 static HRESULT WINAPI PixelFormatInfo_GetChannelMask(IWICPixelFormatInfo2 *iface, 1381 UINT uiChannelIndex, UINT cbMaskBuffer, BYTE *pbMaskBuffer, UINT *pcbActual) 1382 { 1383 static const WCHAR uintformatW[] = {'%','u',0}; 1384 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); 1385 UINT channel_count; 1386 HRESULT hr; 1387 LONG ret; 1388 WCHAR valuename[11]; 1389 DWORD cbData; 1390 1391 TRACE("(%p,%u,%u,%p,%p)\n", iface, uiChannelIndex, cbMaskBuffer, pbMaskBuffer, pcbActual); 1392 1393 if (!pcbActual) 1394 return E_INVALIDARG; 1395 1396 hr = PixelFormatInfo_GetChannelCount(iface, &channel_count); 1397 1398 if (SUCCEEDED(hr) && uiChannelIndex >= channel_count) 1399 hr = E_INVALIDARG; 1400 1401 if (SUCCEEDED(hr)) 1402 { 1403 snprintfW(valuename, 11, uintformatW, uiChannelIndex); 1404 1405 cbData = cbMaskBuffer; 1406 1407 ret = RegGetValueW(This->classkey, channelmasks_keyname, valuename, RRF_RT_REG_BINARY, NULL, pbMaskBuffer, &cbData); 1408 1409 if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) 1410 *pcbActual = cbData; 1411 1412 if (ret == ERROR_MORE_DATA) 1413 hr = E_INVALIDARG; 1414 else 1415 hr = HRESULT_FROM_WIN32(ret); 1416 } 1417 1418 return hr; 1419 } 1420 1421 static HRESULT WINAPI PixelFormatInfo_SupportsTransparency(IWICPixelFormatInfo2 *iface, 1422 BOOL *pfSupportsTransparency) 1423 { 1424 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); 1425 1426 TRACE("(%p,%p)\n", iface, pfSupportsTransparency); 1427 1428 return ComponentInfo_GetDWORDValue(This->classkey, supportstransparency_valuename, (DWORD*)pfSupportsTransparency); 1429 } 1430 1431 static HRESULT WINAPI PixelFormatInfo_GetNumericRepresentation(IWICPixelFormatInfo2 *iface, 1432 WICPixelFormatNumericRepresentation *pNumericRepresentation) 1433 { 1434 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); 1435 1436 TRACE("(%p,%p)\n", iface, pNumericRepresentation); 1437 1438 return ComponentInfo_GetDWORDValue(This->classkey, numericrepresentation_valuename, pNumericRepresentation); 1439 } 1440 1441 static const IWICPixelFormatInfo2Vtbl PixelFormatInfo_Vtbl = { 1442 PixelFormatInfo_QueryInterface, 1443 PixelFormatInfo_AddRef, 1444 PixelFormatInfo_Release, 1445 PixelFormatInfo_GetComponentType, 1446 PixelFormatInfo_GetCLSID, 1447 PixelFormatInfo_GetSigningStatus, 1448 PixelFormatInfo_GetAuthor, 1449 PixelFormatInfo_GetVendorGUID, 1450 PixelFormatInfo_GetVersion, 1451 PixelFormatInfo_GetSpecVersion, 1452 PixelFormatInfo_GetFriendlyName, 1453 PixelFormatInfo_GetFormatGUID, 1454 PixelFormatInfo_GetColorContext, 1455 PixelFormatInfo_GetBitsPerPixel, 1456 PixelFormatInfo_GetChannelCount, 1457 PixelFormatInfo_GetChannelMask, 1458 PixelFormatInfo_SupportsTransparency, 1459 PixelFormatInfo_GetNumericRepresentation 1460 }; 1461 1462 static HRESULT PixelFormatInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo) 1463 { 1464 PixelFormatInfo *This; 1465 1466 This = HeapAlloc(GetProcessHeap(), 0, sizeof(PixelFormatInfo)); 1467 if (!This) 1468 { 1469 RegCloseKey(classkey); 1470 return E_OUTOFMEMORY; 1471 } 1472 1473 This->IWICPixelFormatInfo2_iface.lpVtbl = &PixelFormatInfo_Vtbl; 1474 This->ref = 1; 1475 This->classkey = classkey; 1476 memcpy(&This->clsid, clsid, sizeof(CLSID)); 1477 1478 *ppIInfo = (IWICComponentInfo *)&This->IWICPixelFormatInfo2_iface; 1479 return S_OK; 1480 } 1481 1482 typedef struct 1483 { 1484 IWICMetadataReaderInfo IWICMetadataReaderInfo_iface; 1485 LONG ref; 1486 HKEY classkey; 1487 CLSID clsid; 1488 } MetadataReaderInfo; 1489 1490 static inline MetadataReaderInfo *impl_from_IWICMetadataReaderInfo(IWICMetadataReaderInfo *iface) 1491 { 1492 return CONTAINING_RECORD(iface, MetadataReaderInfo, IWICMetadataReaderInfo_iface); 1493 } 1494 1495 static HRESULT WINAPI MetadataReaderInfo_QueryInterface(IWICMetadataReaderInfo *iface, 1496 REFIID riid, void **ppv) 1497 { 1498 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); 1499 1500 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv); 1501 1502 if (!ppv) return E_INVALIDARG; 1503 1504 if (IsEqualIID(&IID_IUnknown, riid) || 1505 IsEqualIID(&IID_IWICComponentInfo, riid) || 1506 IsEqualIID(&IID_IWICMetadataHandlerInfo, riid) || 1507 IsEqualIID(&IID_IWICMetadataReaderInfo, riid)) 1508 { 1509 *ppv = &This->IWICMetadataReaderInfo_iface; 1510 } 1511 else 1512 { 1513 *ppv = NULL; 1514 return E_NOINTERFACE; 1515 } 1516 1517 IUnknown_AddRef((IUnknown *)*ppv); 1518 return S_OK; 1519 } 1520 1521 static ULONG WINAPI MetadataReaderInfo_AddRef(IWICMetadataReaderInfo *iface) 1522 { 1523 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); 1524 ULONG ref = InterlockedIncrement(&This->ref); 1525 1526 TRACE("(%p) refcount=%u\n", iface, ref); 1527 return ref; 1528 } 1529 1530 static ULONG WINAPI MetadataReaderInfo_Release(IWICMetadataReaderInfo *iface) 1531 { 1532 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); 1533 ULONG ref = InterlockedDecrement(&This->ref); 1534 1535 TRACE("(%p) refcount=%u\n", iface, ref); 1536 1537 if (!ref) 1538 { 1539 RegCloseKey(This->classkey); 1540 HeapFree(GetProcessHeap(), 0, This); 1541 } 1542 return ref; 1543 } 1544 1545 static HRESULT WINAPI MetadataReaderInfo_GetComponentType(IWICMetadataReaderInfo *iface, 1546 WICComponentType *type) 1547 { 1548 TRACE("(%p,%p)\n", iface, type); 1549 1550 if (!type) return E_INVALIDARG; 1551 *type = WICMetadataReader; 1552 return S_OK; 1553 } 1554 1555 static HRESULT WINAPI MetadataReaderInfo_GetCLSID(IWICMetadataReaderInfo *iface, 1556 CLSID *clsid) 1557 { 1558 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); 1559 1560 TRACE("(%p,%p)\n", iface, clsid); 1561 1562 if (!clsid) return E_INVALIDARG; 1563 *clsid = This->clsid; 1564 return S_OK; 1565 } 1566 1567 static HRESULT WINAPI MetadataReaderInfo_GetSigningStatus(IWICMetadataReaderInfo *iface, 1568 DWORD *status) 1569 { 1570 FIXME("(%p,%p): stub\n", iface, status); 1571 return E_NOTIMPL; 1572 } 1573 1574 static HRESULT WINAPI MetadataReaderInfo_GetAuthor(IWICMetadataReaderInfo *iface, 1575 UINT length, WCHAR *author, UINT *actual_length) 1576 { 1577 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); 1578 1579 TRACE("(%p,%u,%p,%p)\n", iface, length, author, actual_length); 1580 1581 return ComponentInfo_GetStringValue(This->classkey, author_valuename, 1582 length, author, actual_length); 1583 } 1584 1585 static HRESULT WINAPI MetadataReaderInfo_GetVendorGUID(IWICMetadataReaderInfo *iface, 1586 GUID *vendor) 1587 { 1588 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); 1589 1590 TRACE("(%p,%p)\n", iface, vendor); 1591 1592 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, vendor); 1593 } 1594 1595 static HRESULT WINAPI MetadataReaderInfo_GetVersion(IWICMetadataReaderInfo *iface, 1596 UINT length, WCHAR *version, UINT *actual_length) 1597 { 1598 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); 1599 1600 TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length); 1601 1602 return ComponentInfo_GetStringValue(This->classkey, version_valuename, 1603 length, version, actual_length); 1604 } 1605 1606 static HRESULT WINAPI MetadataReaderInfo_GetSpecVersion(IWICMetadataReaderInfo *iface, 1607 UINT length, WCHAR *version, UINT *actual_length) 1608 { 1609 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); 1610 1611 TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length); 1612 1613 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename, 1614 length, version, actual_length); 1615 } 1616 1617 static HRESULT WINAPI MetadataReaderInfo_GetFriendlyName(IWICMetadataReaderInfo *iface, 1618 UINT length, WCHAR *name, UINT *actual_length) 1619 { 1620 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); 1621 1622 TRACE("(%p,%u,%p,%p)\n", iface, length, name, actual_length); 1623 1624 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename, 1625 length, name, actual_length); 1626 } 1627 1628 static HRESULT WINAPI MetadataReaderInfo_GetMetadataFormat(IWICMetadataReaderInfo *iface, 1629 GUID *format) 1630 { 1631 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); 1632 TRACE("(%p,%p)\n", iface, format); 1633 return ComponentInfo_GetGUIDValue(This->classkey, metadataformat_valuename, format); 1634 } 1635 1636 static HRESULT WINAPI MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderInfo *iface, 1637 UINT length, GUID *formats, UINT *actual_length) 1638 { 1639 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); 1640 TRACE("(%p,%u,%p,%p)\n", iface, length, formats, actual_length); 1641 1642 return ComponentInfo_GetGuidList(This->classkey, containers_keyname, length, 1643 formats, actual_length); 1644 } 1645 1646 static HRESULT WINAPI MetadataReaderInfo_GetDeviceManufacturer(IWICMetadataReaderInfo *iface, 1647 UINT length, WCHAR *manufacturer, UINT *actual_length) 1648 { 1649 FIXME("(%p,%u,%p,%p): stub\n", iface, length, manufacturer, actual_length); 1650 return E_NOTIMPL; 1651 } 1652 1653 static HRESULT WINAPI MetadataReaderInfo_GetDeviceModels(IWICMetadataReaderInfo *iface, 1654 UINT length, WCHAR *models, UINT *actual_length) 1655 { 1656 FIXME("(%p,%u,%p,%p): stub\n", iface, length, models, actual_length); 1657 return E_NOTIMPL; 1658 } 1659 1660 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFullStream(IWICMetadataReaderInfo *iface, 1661 BOOL *param) 1662 { 1663 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); 1664 TRACE("(%p,%p)\n", iface, param); 1665 return ComponentInfo_GetDWORDValue(This->classkey, requiresfullstream_valuename, (DWORD *)param); 1666 } 1667 1668 static HRESULT WINAPI MetadataReaderInfo_DoesSupportPadding(IWICMetadataReaderInfo *iface, 1669 BOOL *param) 1670 { 1671 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); 1672 TRACE("(%p,%p)\n", iface, param); 1673 return ComponentInfo_GetDWORDValue(This->classkey, supportspadding_valuename, (DWORD *)param); 1674 } 1675 1676 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFixedSize(IWICMetadataReaderInfo *iface, 1677 BOOL *param) 1678 { 1679 FIXME("(%p,%p): stub\n", iface, param); 1680 return E_NOTIMPL; 1681 } 1682 1683 static HRESULT WINAPI MetadataReaderInfo_GetPatterns(IWICMetadataReaderInfo *iface, 1684 REFGUID container, UINT length, WICMetadataPattern *patterns, UINT *count, UINT *actual_length) 1685 { 1686 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); 1687 HRESULT hr=S_OK; 1688 LONG res; 1689 UINT pattern_count=0, patterns_size=0; 1690 DWORD valuesize, patternsize; 1691 BYTE *bPatterns=(BYTE*)patterns; 1692 HKEY containers_key, guid_key, pattern_key; 1693 WCHAR subkeyname[11]; 1694 WCHAR guidkeyname[39]; 1695 int i; 1696 static const WCHAR uintformatW[] = {'%','u',0}; 1697 static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0}; 1698 static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0}; 1699 static const WCHAR maskW[] = {'M','a','s','k',0}; 1700 static const WCHAR dataoffsetW[] = {'D','a','t','a','O','f','f','s','e','t',0}; 1701 1702 TRACE("(%p,%s,%u,%p,%p,%p)\n", iface, debugstr_guid(container), length, patterns, count, actual_length); 1703 1704 if (!actual_length || !container) return E_INVALIDARG; 1705 1706 res = RegOpenKeyExW(This->classkey, containers_keyname, 0, KEY_READ, &containers_key); 1707 if (res == ERROR_SUCCESS) 1708 { 1709 StringFromGUID2(container, guidkeyname, 39); 1710 1711 res = RegOpenKeyExW(containers_key, guidkeyname, 0, KEY_READ, &guid_key); 1712 if (res == ERROR_FILE_NOT_FOUND) hr = WINCODEC_ERR_COMPONENTNOTFOUND; 1713 else if (res != ERROR_SUCCESS) hr = HRESULT_FROM_WIN32(res); 1714 1715 RegCloseKey(containers_key); 1716 } 1717 else if (res == ERROR_FILE_NOT_FOUND) hr = WINCODEC_ERR_COMPONENTNOTFOUND; 1718 else hr = HRESULT_FROM_WIN32(res); 1719 1720 if (SUCCEEDED(hr)) 1721 { 1722 res = RegQueryInfoKeyW(guid_key, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 1723 if (res != ERROR_SUCCESS) hr = HRESULT_FROM_WIN32(res); 1724 1725 if (SUCCEEDED(hr)) 1726 { 1727 patterns_size = pattern_count * sizeof(WICMetadataPattern); 1728 1729 for (i=0; i<pattern_count; i++) 1730 { 1731 snprintfW(subkeyname, 11, uintformatW, i); 1732 res = RegOpenKeyExW(guid_key, subkeyname, 0, KEY_READ, &pattern_key); 1733 if (res == ERROR_SUCCESS) 1734 { 1735 res = RegGetValueW(pattern_key, NULL, patternW, RRF_RT_REG_BINARY, NULL, 1736 NULL, &patternsize); 1737 patterns_size += patternsize*2; 1738 1739 if ((length >= patterns_size) && (res == ERROR_SUCCESS)) 1740 { 1741 patterns[i].Length = patternsize; 1742 1743 patterns[i].DataOffset.QuadPart = 0; 1744 valuesize = sizeof(ULARGE_INTEGER); 1745 RegGetValueW(pattern_key, NULL, dataoffsetW, RRF_RT_DWORD|RRF_RT_QWORD, NULL, 1746 &patterns[i].DataOffset, &valuesize); 1747 1748 patterns[i].Position.QuadPart = 0; 1749 valuesize = sizeof(ULARGE_INTEGER); 1750 res = RegGetValueW(pattern_key, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL, 1751 &patterns[i].Position, &valuesize); 1752 1753 if (res == ERROR_SUCCESS) 1754 { 1755 patterns[i].Pattern = bPatterns+patterns_size-patternsize*2; 1756 valuesize = patternsize; 1757 res = RegGetValueW(pattern_key, NULL, patternW, RRF_RT_REG_BINARY, NULL, 1758 patterns[i].Pattern, &valuesize); 1759 } 1760 1761 if (res == ERROR_SUCCESS) 1762 { 1763 patterns[i].Mask = bPatterns+patterns_size-patternsize; 1764 valuesize = patternsize; 1765 res = RegGetValueW(pattern_key, NULL, maskW, RRF_RT_REG_BINARY, NULL, 1766 patterns[i].Mask, &valuesize); 1767 } 1768 } 1769 1770 RegCloseKey(pattern_key); 1771 } 1772 if (res != ERROR_SUCCESS) 1773 { 1774 hr = HRESULT_FROM_WIN32(res); 1775 break; 1776 } 1777 } 1778 } 1779 1780 RegCloseKey(guid_key); 1781 } 1782 1783 if (hr == S_OK) 1784 { 1785 *count = pattern_count; 1786 *actual_length = patterns_size; 1787 if (patterns && length < patterns_size) 1788 hr = WINCODEC_ERR_INSUFFICIENTBUFFER; 1789 } 1790 1791 return hr; 1792 } 1793 1794 static HRESULT WINAPI MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo *iface, 1795 REFGUID container, IStream *stream, BOOL *matches) 1796 { 1797 HRESULT hr; 1798 WICMetadataPattern *patterns; 1799 UINT pattern_count=0, patterns_size=0; 1800 ULONG datasize=0; 1801 BYTE *data=NULL; 1802 ULONG bytesread; 1803 UINT i; 1804 LARGE_INTEGER seekpos; 1805 ULONG pos; 1806 1807 TRACE("(%p,%s,%p,%p)\n", iface, debugstr_guid(container), stream, matches); 1808 1809 hr = MetadataReaderInfo_GetPatterns(iface, container, 0, NULL, &pattern_count, &patterns_size); 1810 if (FAILED(hr)) return hr; 1811 1812 patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size); 1813 if (!patterns) return E_OUTOFMEMORY; 1814 1815 hr = MetadataReaderInfo_GetPatterns(iface, container, patterns_size, patterns, &pattern_count, &patterns_size); 1816 if (FAILED(hr)) goto end; 1817 1818 for (i=0; i<pattern_count; i++) 1819 { 1820 if (datasize < patterns[i].Length) 1821 { 1822 HeapFree(GetProcessHeap(), 0, data); 1823 datasize = patterns[i].Length; 1824 data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length); 1825 if (!data) 1826 { 1827 hr = E_OUTOFMEMORY; 1828 break; 1829 } 1830 } 1831 1832 seekpos.QuadPart = patterns[i].Position.QuadPart; 1833 hr = IStream_Seek(stream, seekpos, STREAM_SEEK_SET, NULL); 1834 if (FAILED(hr)) break; 1835 1836 hr = IStream_Read(stream, data, patterns[i].Length, &bytesread); 1837 if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */ 1838 continue; 1839 if (FAILED(hr)) break; 1840 1841 for (pos=0; pos<patterns[i].Length; pos++) 1842 { 1843 if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos]) 1844 break; 1845 } 1846 if (pos == patterns[i].Length) /* matches pattern */ 1847 { 1848 hr = S_OK; 1849 *matches = TRUE; 1850 break; 1851 } 1852 } 1853 1854 if (i == pattern_count) /* does not match any pattern */ 1855 { 1856 hr = S_OK; 1857 *matches = FALSE; 1858 } 1859 1860 end: 1861 HeapFree(GetProcessHeap(), 0, patterns); 1862 HeapFree(GetProcessHeap(), 0, data); 1863 1864 return hr; 1865 } 1866 1867 static HRESULT WINAPI MetadataReaderInfo_CreateInstance(IWICMetadataReaderInfo *iface, 1868 IWICMetadataReader **reader) 1869 { 1870 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); 1871 1872 TRACE("(%p,%p)\n", iface, reader); 1873 1874 return create_instance(&This->clsid, &IID_IWICMetadataReader, (void **)reader); 1875 } 1876 1877 static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl = { 1878 MetadataReaderInfo_QueryInterface, 1879 MetadataReaderInfo_AddRef, 1880 MetadataReaderInfo_Release, 1881 MetadataReaderInfo_GetComponentType, 1882 MetadataReaderInfo_GetCLSID, 1883 MetadataReaderInfo_GetSigningStatus, 1884 MetadataReaderInfo_GetAuthor, 1885 MetadataReaderInfo_GetVendorGUID, 1886 MetadataReaderInfo_GetVersion, 1887 MetadataReaderInfo_GetSpecVersion, 1888 MetadataReaderInfo_GetFriendlyName, 1889 MetadataReaderInfo_GetMetadataFormat, 1890 MetadataReaderInfo_GetContainerFormats, 1891 MetadataReaderInfo_GetDeviceManufacturer, 1892 MetadataReaderInfo_GetDeviceModels, 1893 MetadataReaderInfo_DoesRequireFullStream, 1894 MetadataReaderInfo_DoesSupportPadding, 1895 MetadataReaderInfo_DoesRequireFixedSize, 1896 MetadataReaderInfo_GetPatterns, 1897 MetadataReaderInfo_MatchesPattern, 1898 MetadataReaderInfo_CreateInstance 1899 }; 1900 1901 static HRESULT MetadataReaderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **info) 1902 { 1903 MetadataReaderInfo *This; 1904 1905 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); 1906 if (!This) 1907 { 1908 RegCloseKey(classkey); 1909 return E_OUTOFMEMORY; 1910 } 1911 1912 This->IWICMetadataReaderInfo_iface.lpVtbl = &MetadataReaderInfo_Vtbl; 1913 This->ref = 1; 1914 This->classkey = classkey; 1915 This->clsid = *clsid; 1916 1917 *info = (IWICComponentInfo *)&This->IWICMetadataReaderInfo_iface; 1918 return S_OK; 1919 } 1920 1921 static const WCHAR clsid_keyname[] = {'C','L','S','I','D',0}; 1922 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0}; 1923 1924 struct category { 1925 WICComponentType type; 1926 const GUID *catid; 1927 HRESULT (*constructor)(HKEY,REFCLSID,IWICComponentInfo**); 1928 }; 1929 1930 static const struct category categories[] = { 1931 {WICDecoder, &CATID_WICBitmapDecoders, BitmapDecoderInfo_Constructor}, 1932 {WICEncoder, &CATID_WICBitmapEncoders, BitmapEncoderInfo_Constructor}, 1933 {WICPixelFormatConverter, &CATID_WICFormatConverters, FormatConverterInfo_Constructor}, 1934 {WICPixelFormat, &CATID_WICPixelFormats, PixelFormatInfo_Constructor}, 1935 {WICMetadataReader, &CATID_WICMetadataReader, MetadataReaderInfo_Constructor}, 1936 {0} 1937 }; 1938 1939 HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo) 1940 { 1941 HKEY clsidkey; 1942 HKEY classkey; 1943 HKEY catidkey; 1944 HKEY instancekey; 1945 WCHAR guidstring[39]; 1946 LONG res; 1947 const struct category *category; 1948 BOOL found = FALSE; 1949 HRESULT hr; 1950 1951 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey); 1952 if (res != ERROR_SUCCESS) 1953 return HRESULT_FROM_WIN32(res); 1954 1955 for (category=categories; category->type; category++) 1956 { 1957 StringFromGUID2(category->catid, guidstring, 39); 1958 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey); 1959 if (res == ERROR_SUCCESS) 1960 { 1961 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey); 1962 if (res == ERROR_SUCCESS) 1963 { 1964 StringFromGUID2(clsid, guidstring, 39); 1965 res = RegOpenKeyExW(instancekey, guidstring, 0, KEY_READ, &classkey); 1966 if (res == ERROR_SUCCESS) 1967 { 1968 RegCloseKey(classkey); 1969 found = TRUE; 1970 } 1971 RegCloseKey(instancekey); 1972 } 1973 RegCloseKey(catidkey); 1974 } 1975 if (found) break; 1976 } 1977 1978 if (found) 1979 { 1980 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &classkey); 1981 if (res == ERROR_SUCCESS) 1982 hr = category->constructor(classkey, clsid, ppIInfo); 1983 else 1984 hr = HRESULT_FROM_WIN32(res); 1985 } 1986 else 1987 { 1988 FIXME("%s is not supported\n", wine_dbgstr_guid(clsid)); 1989 hr = E_FAIL; 1990 } 1991 1992 RegCloseKey(clsidkey); 1993 1994 return hr; 1995 } 1996 1997 typedef struct { 1998 IEnumUnknown IEnumUnknown_iface; 1999 LONG ref; 2000 struct list objects; 2001 struct list *cursor; 2002 CRITICAL_SECTION lock; /* Must be held when reading or writing cursor */ 2003 } ComponentEnum; 2004 2005 static inline ComponentEnum *impl_from_IEnumUnknown(IEnumUnknown *iface) 2006 { 2007 return CONTAINING_RECORD(iface, ComponentEnum, IEnumUnknown_iface); 2008 } 2009 2010 typedef struct { 2011 struct list entry; 2012 IUnknown *unk; 2013 } ComponentEnumItem; 2014 2015 static const IEnumUnknownVtbl ComponentEnumVtbl; 2016 2017 static HRESULT WINAPI ComponentEnum_QueryInterface(IEnumUnknown *iface, REFIID iid, 2018 void **ppv) 2019 { 2020 ComponentEnum *This = impl_from_IEnumUnknown(iface); 2021 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); 2022 2023 if (!ppv) return E_INVALIDARG; 2024 2025 if (IsEqualIID(&IID_IUnknown, iid) || 2026 IsEqualIID(&IID_IEnumUnknown, iid)) 2027 { 2028 *ppv = &This->IEnumUnknown_iface; 2029 } 2030 else 2031 { 2032 *ppv = NULL; 2033 return E_NOINTERFACE; 2034 } 2035 2036 IUnknown_AddRef((IUnknown*)*ppv); 2037 return S_OK; 2038 } 2039 2040 static ULONG WINAPI ComponentEnum_AddRef(IEnumUnknown *iface) 2041 { 2042 ComponentEnum *This = impl_from_IEnumUnknown(iface); 2043 ULONG ref = InterlockedIncrement(&This->ref); 2044 2045 TRACE("(%p) refcount=%u\n", iface, ref); 2046 2047 return ref; 2048 } 2049 2050 static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface) 2051 { 2052 ComponentEnum *This = impl_from_IEnumUnknown(iface); 2053 ULONG ref = InterlockedDecrement(&This->ref); 2054 ComponentEnumItem *cursor, *cursor2; 2055 2056 TRACE("(%p) refcount=%u\n", iface, ref); 2057 2058 if (ref == 0) 2059 { 2060 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->objects, ComponentEnumItem, entry) 2061 { 2062 IUnknown_Release(cursor->unk); 2063 list_remove(&cursor->entry); 2064 HeapFree(GetProcessHeap(), 0, cursor); 2065 } 2066 This->lock.DebugInfo->Spare[0] = 0; 2067 DeleteCriticalSection(&This->lock); 2068 HeapFree(GetProcessHeap(), 0, This); 2069 } 2070 2071 return ref; 2072 } 2073 2074 static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt, 2075 IUnknown **rgelt, ULONG *pceltFetched) 2076 { 2077 ComponentEnum *This = impl_from_IEnumUnknown(iface); 2078 ULONG num_fetched=0; 2079 ComponentEnumItem *item; 2080 HRESULT hr=S_OK; 2081 2082 TRACE("(%p,%u,%p,%p)\n", iface, celt, rgelt, pceltFetched); 2083 2084 EnterCriticalSection(&This->lock); 2085 while (num_fetched<celt) 2086 { 2087 if (!This->cursor) 2088 { 2089 hr = S_FALSE; 2090 break; 2091 } 2092 item = LIST_ENTRY(This->cursor, ComponentEnumItem, entry); 2093 IUnknown_AddRef(item->unk); 2094 rgelt[num_fetched] = item->unk; 2095 num_fetched++; 2096 This->cursor = list_next(&This->objects, This->cursor); 2097 } 2098 LeaveCriticalSection(&This->lock); 2099 if (pceltFetched) 2100 *pceltFetched = num_fetched; 2101 return hr; 2102 } 2103 2104 static HRESULT WINAPI ComponentEnum_Skip(IEnumUnknown *iface, ULONG celt) 2105 { 2106 ComponentEnum *This = impl_from_IEnumUnknown(iface); 2107 ULONG i; 2108 HRESULT hr=S_OK; 2109 2110 TRACE("(%p,%u)\n", iface, celt); 2111 2112 EnterCriticalSection(&This->lock); 2113 for (i=0; i<celt; i++) 2114 { 2115 if (!This->cursor) 2116 { 2117 hr = S_FALSE; 2118 break; 2119 } 2120 This->cursor = list_next(&This->objects, This->cursor); 2121 } 2122 LeaveCriticalSection(&This->lock); 2123 return hr; 2124 } 2125 2126 static HRESULT WINAPI ComponentEnum_Reset(IEnumUnknown *iface) 2127 { 2128 ComponentEnum *This = impl_from_IEnumUnknown(iface); 2129 2130 TRACE("(%p)\n", iface); 2131 2132 EnterCriticalSection(&This->lock); 2133 This->cursor = list_head(&This->objects); 2134 LeaveCriticalSection(&This->lock); 2135 return S_OK; 2136 } 2137 2138 static HRESULT WINAPI ComponentEnum_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum) 2139 { 2140 ComponentEnum *This = impl_from_IEnumUnknown(iface); 2141 ComponentEnum *new_enum; 2142 ComponentEnumItem *old_item, *new_item; 2143 HRESULT ret=S_OK; 2144 struct list *old_cursor; 2145 2146 new_enum = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum)); 2147 if (!new_enum) 2148 { 2149 *ppenum = NULL; 2150 return E_OUTOFMEMORY; 2151 } 2152 2153 new_enum->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl; 2154 new_enum->ref = 1; 2155 new_enum->cursor = NULL; 2156 list_init(&new_enum->objects); 2157 InitializeCriticalSection(&new_enum->lock); 2158 new_enum->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock"); 2159 2160 EnterCriticalSection(&This->lock); 2161 old_cursor = This->cursor; 2162 LeaveCriticalSection(&This->lock); 2163 2164 LIST_FOR_EACH_ENTRY(old_item, &This->objects, ComponentEnumItem, entry) 2165 { 2166 new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem)); 2167 if (!new_item) 2168 { 2169 ret = E_OUTOFMEMORY; 2170 break; 2171 } 2172 new_item->unk = old_item->unk; 2173 list_add_tail(&new_enum->objects, &new_item->entry); 2174 IUnknown_AddRef(new_item->unk); 2175 if (&old_item->entry == old_cursor) new_enum->cursor = &new_item->entry; 2176 } 2177 2178 if (FAILED(ret)) 2179 { 2180 IEnumUnknown_Release(&new_enum->IEnumUnknown_iface); 2181 *ppenum = NULL; 2182 } 2183 else 2184 *ppenum = &new_enum->IEnumUnknown_iface; 2185 2186 return ret; 2187 } 2188 2189 static const IEnumUnknownVtbl ComponentEnumVtbl = { 2190 ComponentEnum_QueryInterface, 2191 ComponentEnum_AddRef, 2192 ComponentEnum_Release, 2193 ComponentEnum_Next, 2194 ComponentEnum_Skip, 2195 ComponentEnum_Reset, 2196 ComponentEnum_Clone 2197 }; 2198 2199 HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown) 2200 { 2201 ComponentEnum *This; 2202 ComponentEnumItem *item; 2203 const struct category *category; 2204 HKEY clsidkey, catidkey, instancekey; 2205 WCHAR guidstring[39]; 2206 LONG res; 2207 int i; 2208 HRESULT hr=S_OK; 2209 CLSID clsid; 2210 2211 if (options) FIXME("ignoring flags %x\n", options); 2212 2213 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey); 2214 if (res != ERROR_SUCCESS) 2215 return HRESULT_FROM_WIN32(res); 2216 2217 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum)); 2218 if (!This) 2219 { 2220 RegCloseKey(clsidkey); 2221 return E_OUTOFMEMORY; 2222 } 2223 2224 This->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl; 2225 This->ref = 1; 2226 list_init(&This->objects); 2227 InitializeCriticalSection(&This->lock); 2228 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock"); 2229 2230 for (category=categories; category->type && hr == S_OK; category++) 2231 { 2232 if ((category->type & componentTypes) == 0) continue; 2233 StringFromGUID2(category->catid, guidstring, 39); 2234 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey); 2235 if (res == ERROR_SUCCESS) 2236 { 2237 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey); 2238 if (res == ERROR_SUCCESS) 2239 { 2240 i=0; 2241 for (;;i++) 2242 { 2243 DWORD guidstring_size = 39; 2244 res = RegEnumKeyExW(instancekey, i, guidstring, &guidstring_size, NULL, NULL, NULL, NULL); 2245 if (res != ERROR_SUCCESS) break; 2246 2247 item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem)); 2248 if (!item) { hr = E_OUTOFMEMORY; break; } 2249 2250 hr = CLSIDFromString(guidstring, &clsid); 2251 if (SUCCEEDED(hr)) 2252 { 2253 hr = CreateComponentInfo(&clsid, (IWICComponentInfo**)&item->unk); 2254 if (SUCCEEDED(hr)) 2255 list_add_tail(&This->objects, &item->entry); 2256 } 2257 2258 if (FAILED(hr)) 2259 { 2260 HeapFree(GetProcessHeap(), 0, item); 2261 hr = S_OK; 2262 } 2263 } 2264 RegCloseKey(instancekey); 2265 } 2266 RegCloseKey(catidkey); 2267 } 2268 if (res != ERROR_SUCCESS && res != ERROR_NO_MORE_ITEMS) 2269 hr = HRESULT_FROM_WIN32(res); 2270 } 2271 RegCloseKey(clsidkey); 2272 2273 if (SUCCEEDED(hr)) 2274 { 2275 IEnumUnknown_Reset(&This->IEnumUnknown_iface); 2276 *ppIEnumUnknown = &This->IEnumUnknown_iface; 2277 } 2278 else 2279 { 2280 *ppIEnumUnknown = NULL; 2281 IEnumUnknown_Release(&This->IEnumUnknown_iface); 2282 } 2283 2284 return hr; 2285 } 2286 2287 static BOOL is_1bpp_format(const WICPixelFormatGUID *format) 2288 { 2289 return IsEqualGUID(format, &GUID_WICPixelFormatBlackWhite) || 2290 IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed); 2291 } 2292 2293 HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst) 2294 { 2295 HRESULT res; 2296 IEnumUnknown *enumconverters; 2297 IUnknown *unkconverterinfo; 2298 IWICFormatConverterInfo *converterinfo=NULL; 2299 IWICFormatConverter *converter=NULL; 2300 GUID srcFormat; 2301 WCHAR srcformatstr[39], dstformatstr[39]; 2302 BOOL canconvert; 2303 ULONG num_fetched; 2304 2305 TRACE("%s,%p,%p\n", debugstr_guid(dstFormat), pISrc, ppIDst); 2306 2307 res = IWICBitmapSource_GetPixelFormat(pISrc, &srcFormat); 2308 if (FAILED(res)) return res; 2309 2310 if (IsEqualGUID(&srcFormat, dstFormat) || (is_1bpp_format(&srcFormat) && is_1bpp_format(dstFormat))) 2311 { 2312 IWICBitmapSource_AddRef(pISrc); 2313 *ppIDst = pISrc; 2314 return S_OK; 2315 } 2316 2317 StringFromGUID2(&srcFormat, srcformatstr, 39); 2318 StringFromGUID2(dstFormat, dstformatstr, 39); 2319 2320 res = CreateComponentEnumerator(WICPixelFormatConverter, 0, &enumconverters); 2321 if (FAILED(res)) return res; 2322 2323 while (!converter) 2324 { 2325 res = IEnumUnknown_Next(enumconverters, 1, &unkconverterinfo, &num_fetched); 2326 2327 if (res == S_OK) 2328 { 2329 res = IUnknown_QueryInterface(unkconverterinfo, &IID_IWICFormatConverterInfo, (void**)&converterinfo); 2330 2331 if (SUCCEEDED(res)) 2332 { 2333 canconvert = ConverterSupportsFormat(converterinfo, srcformatstr); 2334 2335 if (canconvert) 2336 canconvert = ConverterSupportsFormat(converterinfo, dstformatstr); 2337 2338 if (canconvert) 2339 { 2340 res = IWICFormatConverterInfo_CreateInstance(converterinfo, &converter); 2341 2342 if (SUCCEEDED(res)) 2343 res = IWICFormatConverter_CanConvert(converter, &srcFormat, dstFormat, &canconvert); 2344 2345 if (SUCCEEDED(res) && canconvert) 2346 res = IWICFormatConverter_Initialize(converter, pISrc, dstFormat, WICBitmapDitherTypeNone, 2347 NULL, 0.0, WICBitmapPaletteTypeMedianCut); 2348 2349 if (FAILED(res) || !canconvert) 2350 { 2351 if (converter) 2352 { 2353 IWICFormatConverter_Release(converter); 2354 converter = NULL; 2355 } 2356 } 2357 } 2358 2359 IWICFormatConverterInfo_Release(converterinfo); 2360 } 2361 2362 IUnknown_Release(unkconverterinfo); 2363 } 2364 else 2365 break; 2366 } 2367 2368 IEnumUnknown_Release(enumconverters); 2369 2370 if (converter) 2371 { 2372 res = IWICFormatConverter_QueryInterface(converter, &IID_IWICBitmapSource, (void **)ppIDst); 2373 IWICFormatConverter_Release(converter); 2374 return res; 2375 } 2376 else 2377 { 2378 FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat)); 2379 *ppIDst = NULL; 2380 return WINCODEC_ERR_COMPONENTNOTFOUND; 2381 } 2382 } 2383