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