Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninfo.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2009 Vincent Povirk for CodeWeavers 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 */ 00018 00019 #include "config.h" 00020 00021 #include <stdarg.h> 00022 00023 #define COBJMACROS 00024 00025 #include "windef.h" 00026 #include "winbase.h" 00027 #include "winreg.h" 00028 #include "objbase.h" 00029 #include "wincodec.h" 00030 00031 #include "wincodecs_private.h" 00032 00033 #include "wine/debug.h" 00034 #include "wine/unicode.h" 00035 #include "wine/list.h" 00036 00037 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); 00038 00039 static WCHAR const pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0}; 00040 00041 typedef struct { 00042 const IWICBitmapDecoderInfoVtbl *lpIWICBitmapDecoderInfoVtbl; 00043 LONG ref; 00044 HKEY classkey; 00045 CLSID clsid; 00046 } BitmapDecoderInfo; 00047 00048 static HRESULT WINAPI BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo *iface, REFIID iid, 00049 void **ppv) 00050 { 00051 BitmapDecoderInfo *This = (BitmapDecoderInfo*)iface; 00052 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); 00053 00054 if (!ppv) return E_INVALIDARG; 00055 00056 if (IsEqualIID(&IID_IUnknown, iid) || 00057 IsEqualIID(&IID_IWICComponentInfo, iid) || 00058 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) || 00059 IsEqualIID(&IID_IWICBitmapDecoderInfo ,iid)) 00060 { 00061 *ppv = This; 00062 } 00063 else 00064 { 00065 *ppv = NULL; 00066 return E_NOINTERFACE; 00067 } 00068 00069 IUnknown_AddRef((IUnknown*)*ppv); 00070 return S_OK; 00071 } 00072 00073 static ULONG WINAPI BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo *iface) 00074 { 00075 BitmapDecoderInfo *This = (BitmapDecoderInfo*)iface; 00076 ULONG ref = InterlockedIncrement(&This->ref); 00077 00078 TRACE("(%p) refcount=%u\n", iface, ref); 00079 00080 return ref; 00081 } 00082 00083 static ULONG WINAPI BitmapDecoderInfo_Release(IWICBitmapDecoderInfo *iface) 00084 { 00085 BitmapDecoderInfo *This = (BitmapDecoderInfo*)iface; 00086 ULONG ref = InterlockedDecrement(&This->ref); 00087 00088 TRACE("(%p) refcount=%u\n", iface, ref); 00089 00090 if (ref == 0) 00091 { 00092 RegCloseKey(This->classkey); 00093 HeapFree(GetProcessHeap(), 0, This); 00094 } 00095 00096 return ref; 00097 } 00098 00099 static HRESULT WINAPI BitmapDecoderInfo_GetComponentType(IWICBitmapDecoderInfo *iface, 00100 WICComponentType *pType) 00101 { 00102 TRACE("(%p,%p)\n", iface, pType); 00103 *pType = WICDecoder; 00104 return S_OK; 00105 } 00106 00107 static HRESULT WINAPI BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo *iface, CLSID *pclsid) 00108 { 00109 FIXME("(%p,%p): stub\n", iface, pclsid); 00110 return E_NOTIMPL; 00111 } 00112 00113 static HRESULT WINAPI BitmapDecoderInfo_GetSigningStatus(IWICBitmapDecoderInfo *iface, DWORD *pStatus) 00114 { 00115 FIXME("(%p,%p): stub\n", iface, pStatus); 00116 return E_NOTIMPL; 00117 } 00118 00119 static HRESULT WINAPI BitmapDecoderInfo_GetAuthor(IWICBitmapDecoderInfo *iface, UINT cchAuthor, 00120 WCHAR *wzAuthor, UINT *pcchActual) 00121 { 00122 FIXME("(%p,%u,%p,%p): stub\n", iface, cchAuthor, wzAuthor, pcchActual); 00123 return E_NOTIMPL; 00124 } 00125 00126 static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *iface, GUID *pguidVendor) 00127 { 00128 FIXME("(%p,%p): stub\n", iface, pguidVendor); 00129 return E_NOTIMPL; 00130 } 00131 00132 static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, UINT cchVersion, 00133 WCHAR *wzVersion, UINT *pcchActual) 00134 { 00135 FIXME("(%p,%u,%p,%p): stub\n", iface, cchVersion, wzVersion, pcchActual); 00136 return E_NOTIMPL; 00137 } 00138 00139 static HRESULT WINAPI BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo *iface, UINT cchSpecVersion, 00140 WCHAR *wzSpecVersion, UINT *pcchActual) 00141 { 00142 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual); 00143 return E_NOTIMPL; 00144 } 00145 00146 static HRESULT WINAPI BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo *iface, UINT cchFriendlyName, 00147 WCHAR *wzFriendlyName, UINT *pcchActual) 00148 { 00149 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFriendlyName, wzFriendlyName, pcchActual); 00150 return E_NOTIMPL; 00151 } 00152 00153 static HRESULT WINAPI BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo *iface, 00154 GUID *pguidContainerFormat) 00155 { 00156 FIXME("(%p,%p): stub\n", iface, pguidContainerFormat); 00157 return E_NOTIMPL; 00158 } 00159 00160 static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *iface, 00161 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual) 00162 { 00163 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual); 00164 return E_NOTIMPL; 00165 } 00166 00167 static HRESULT WINAPI BitmapDecoderInfo_GetColorManagementVersion(IWICBitmapDecoderInfo *iface, 00168 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual) 00169 { 00170 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual); 00171 return E_NOTIMPL; 00172 } 00173 00174 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceManufacturer(IWICBitmapDecoderInfo *iface, 00175 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual) 00176 { 00177 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual); 00178 return E_NOTIMPL; 00179 } 00180 00181 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceModels(IWICBitmapDecoderInfo *iface, 00182 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual) 00183 { 00184 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual); 00185 return E_NOTIMPL; 00186 } 00187 00188 static HRESULT WINAPI BitmapDecoderInfo_GetMimeTypes(IWICBitmapDecoderInfo *iface, 00189 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual) 00190 { 00191 FIXME("(%p,%u,%p,%p): stub\n", iface, cchMimeTypes, wzMimeTypes, pcchActual); 00192 return E_NOTIMPL; 00193 } 00194 00195 static HRESULT WINAPI BitmapDecoderInfo_GetFileExtensions(IWICBitmapDecoderInfo *iface, 00196 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual) 00197 { 00198 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual); 00199 return E_NOTIMPL; 00200 } 00201 00202 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportAnimation(IWICBitmapDecoderInfo *iface, 00203 BOOL *pfSupportAnimation) 00204 { 00205 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation); 00206 return E_NOTIMPL; 00207 } 00208 00209 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportChromaKey(IWICBitmapDecoderInfo *iface, 00210 BOOL *pfSupportChromaKey) 00211 { 00212 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey); 00213 return E_NOTIMPL; 00214 } 00215 00216 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportLossless(IWICBitmapDecoderInfo *iface, 00217 BOOL *pfSupportLossless) 00218 { 00219 FIXME("(%p,%p): stub\n", iface, pfSupportLossless); 00220 return E_NOTIMPL; 00221 } 00222 00223 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportMultiframe(IWICBitmapDecoderInfo *iface, 00224 BOOL *pfSupportMultiframe) 00225 { 00226 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe); 00227 return E_NOTIMPL; 00228 } 00229 00230 static HRESULT WINAPI BitmapDecoderInfo_MatchesMimeType(IWICBitmapDecoderInfo *iface, 00231 LPCWSTR wzMimeType, BOOL *pfMatches) 00232 { 00233 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches); 00234 return E_NOTIMPL; 00235 } 00236 00237 static HRESULT WINAPI BitmapDecoderInfo_GetPatterns(IWICBitmapDecoderInfo *iface, 00238 UINT cbSizePatterns, WICBitmapPattern *pPatterns, UINT *pcPatterns, UINT *pcbPatternsActual) 00239 { 00240 BitmapDecoderInfo *This = (BitmapDecoderInfo*)iface; 00241 UINT pattern_count=0, patterns_size=0; 00242 WCHAR subkeyname[11]; 00243 LONG res; 00244 HKEY patternskey, patternkey; 00245 static const WCHAR uintformatW[] = {'%','u',0}; 00246 static const WCHAR patternsW[] = {'P','a','t','t','e','r','n','s',0}; 00247 static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0}; 00248 static const WCHAR lengthW[] = {'L','e','n','g','t','h',0}; 00249 static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0}; 00250 static const WCHAR maskW[] = {'M','a','s','k',0}; 00251 static const WCHAR endofstreamW[] = {'E','n','d','O','f','S','t','r','e','a','m',0}; 00252 HRESULT hr=S_OK; 00253 UINT i; 00254 BYTE *bPatterns=(BYTE*)pPatterns; 00255 DWORD length, valuesize; 00256 00257 TRACE("(%p,%i,%p,%p,%p)\n", iface, cbSizePatterns, pPatterns, pcPatterns, pcbPatternsActual); 00258 00259 res = RegOpenKeyExW(This->classkey, patternsW, 0, KEY_READ, &patternskey); 00260 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); 00261 00262 res = RegQueryInfoKeyW(patternskey, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 00263 if (res == ERROR_SUCCESS) 00264 { 00265 patterns_size = pattern_count * sizeof(WICBitmapPattern); 00266 00267 for (i=0; i<pattern_count; i++) 00268 { 00269 snprintfW(subkeyname, 11, uintformatW, i); 00270 res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey); 00271 if (res == ERROR_SUCCESS) 00272 { 00273 valuesize = sizeof(ULONG); 00274 res = RegGetValueW(patternkey, NULL, lengthW, RRF_RT_DWORD, NULL, 00275 &length, &valuesize); 00276 patterns_size += length*2; 00277 00278 if ((cbSizePatterns >= patterns_size) && (res == ERROR_SUCCESS)) 00279 { 00280 pPatterns[i].Length = length; 00281 00282 pPatterns[i].EndOfStream = 0; 00283 valuesize = sizeof(BOOL); 00284 RegGetValueW(patternkey, NULL, endofstreamW, RRF_RT_DWORD, NULL, 00285 &pPatterns[i].EndOfStream, &valuesize); 00286 00287 pPatterns[i].Position.QuadPart = 0; 00288 valuesize = sizeof(ULARGE_INTEGER); 00289 res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL, 00290 &pPatterns[i].Position, &valuesize); 00291 00292 if (res == ERROR_SUCCESS) 00293 { 00294 pPatterns[i].Pattern = bPatterns+patterns_size-length*2; 00295 valuesize = length; 00296 res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL, 00297 pPatterns[i].Pattern, &valuesize); 00298 } 00299 00300 if (res == ERROR_SUCCESS) 00301 { 00302 pPatterns[i].Mask = bPatterns+patterns_size-length; 00303 valuesize = length; 00304 res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL, 00305 pPatterns[i].Mask, &valuesize); 00306 } 00307 } 00308 00309 RegCloseKey(patternkey); 00310 } 00311 if (res != ERROR_SUCCESS) 00312 { 00313 hr = HRESULT_FROM_WIN32(res); 00314 break; 00315 } 00316 } 00317 } 00318 else hr = HRESULT_FROM_WIN32(res); 00319 00320 RegCloseKey(patternskey); 00321 00322 if (hr == S_OK) 00323 { 00324 *pcPatterns = pattern_count; 00325 *pcbPatternsActual = patterns_size; 00326 if (pPatterns && cbSizePatterns < patterns_size) 00327 hr = WINCODEC_ERR_INSUFFICIENTBUFFER; 00328 } 00329 00330 return hr; 00331 } 00332 00333 static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *iface, 00334 IStream *pIStream, BOOL *pfMatches) 00335 { 00336 WICBitmapPattern *patterns; 00337 UINT pattern_count=0, patterns_size=0; 00338 HRESULT hr; 00339 int i, pos; 00340 BYTE *data=NULL; 00341 ULONG datasize=0; 00342 ULONG bytesread; 00343 LARGE_INTEGER seekpos; 00344 00345 TRACE("(%p,%p,%p)\n", iface, pIStream, pfMatches); 00346 00347 hr = BitmapDecoderInfo_GetPatterns(iface, 0, NULL, &pattern_count, &patterns_size); 00348 if (FAILED(hr)) return hr; 00349 00350 patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size); 00351 if (!patterns) return E_OUTOFMEMORY; 00352 00353 hr = BitmapDecoderInfo_GetPatterns(iface, patterns_size, patterns, &pattern_count, &patterns_size); 00354 if (FAILED(hr)) goto end; 00355 00356 for (i=0; i<pattern_count; i++) 00357 { 00358 if (datasize < patterns[i].Length) 00359 { 00360 HeapFree(GetProcessHeap(), 0, data); 00361 datasize = patterns[i].Length; 00362 data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length); 00363 if (!data) 00364 { 00365 hr = E_OUTOFMEMORY; 00366 break; 00367 } 00368 } 00369 00370 if (patterns[i].EndOfStream) 00371 seekpos.QuadPart = -patterns[i].Position.QuadPart; 00372 else 00373 seekpos.QuadPart = patterns[i].Position.QuadPart; 00374 hr = IStream_Seek(pIStream, seekpos, patterns[i].EndOfStream ? STREAM_SEEK_END : STREAM_SEEK_SET, NULL); 00375 if (hr == STG_E_INVALIDFUNCTION) continue; /* before start of stream */ 00376 if (FAILED(hr)) break; 00377 00378 hr = IStream_Read(pIStream, data, patterns[i].Length, &bytesread); 00379 if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */ 00380 continue; 00381 if (FAILED(hr)) break; 00382 00383 for (pos=0; pos<patterns[i].Length; pos++) 00384 { 00385 if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos]) 00386 break; 00387 } 00388 if (pos == patterns[i].Length) /* matches pattern */ 00389 { 00390 hr = S_OK; 00391 *pfMatches = TRUE; 00392 break; 00393 } 00394 } 00395 00396 if (i == pattern_count) /* does not match any pattern */ 00397 { 00398 hr = S_OK; 00399 *pfMatches = FALSE; 00400 } 00401 00402 end: 00403 HeapFree(GetProcessHeap(), 0, patterns); 00404 HeapFree(GetProcessHeap(), 0, data); 00405 00406 return hr; 00407 } 00408 00409 static HRESULT WINAPI BitmapDecoderInfo_CreateInstance(IWICBitmapDecoderInfo *iface, 00410 IWICBitmapDecoder **ppIBitmapDecoder) 00411 { 00412 BitmapDecoderInfo *This = (BitmapDecoderInfo*)iface; 00413 00414 TRACE("(%p,%p)\n", iface, ppIBitmapDecoder); 00415 00416 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER, 00417 &IID_IWICBitmapDecoder, (void**)ppIBitmapDecoder); 00418 } 00419 00420 static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = { 00421 BitmapDecoderInfo_QueryInterface, 00422 BitmapDecoderInfo_AddRef, 00423 BitmapDecoderInfo_Release, 00424 BitmapDecoderInfo_GetComponentType, 00425 BitmapDecoderInfo_GetCLSID, 00426 BitmapDecoderInfo_GetSigningStatus, 00427 BitmapDecoderInfo_GetAuthor, 00428 BitmapDecoderInfo_GetVendorGUID, 00429 BitmapDecoderInfo_GetVersion, 00430 BitmapDecoderInfo_GetSpecVersion, 00431 BitmapDecoderInfo_GetFriendlyName, 00432 BitmapDecoderInfo_GetContainerFormat, 00433 BitmapDecoderInfo_GetPixelFormats, 00434 BitmapDecoderInfo_GetColorManagementVersion, 00435 BitmapDecoderInfo_GetDeviceManufacturer, 00436 BitmapDecoderInfo_GetDeviceModels, 00437 BitmapDecoderInfo_GetMimeTypes, 00438 BitmapDecoderInfo_GetFileExtensions, 00439 BitmapDecoderInfo_DoesSupportAnimation, 00440 BitmapDecoderInfo_DoesSupportChromaKey, 00441 BitmapDecoderInfo_DoesSupportLossless, 00442 BitmapDecoderInfo_DoesSupportMultiframe, 00443 BitmapDecoderInfo_MatchesMimeType, 00444 BitmapDecoderInfo_GetPatterns, 00445 BitmapDecoderInfo_MatchesPattern, 00446 BitmapDecoderInfo_CreateInstance 00447 }; 00448 00449 static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo) 00450 { 00451 BitmapDecoderInfo *This; 00452 00453 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapDecoderInfo)); 00454 if (!This) 00455 { 00456 RegCloseKey(classkey); 00457 return E_OUTOFMEMORY; 00458 } 00459 00460 This->lpIWICBitmapDecoderInfoVtbl = &BitmapDecoderInfo_Vtbl; 00461 This->ref = 1; 00462 This->classkey = classkey; 00463 memcpy(&This->clsid, clsid, sizeof(CLSID)); 00464 00465 *ppIInfo = (IWICComponentInfo*)This; 00466 return S_OK; 00467 } 00468 00469 typedef struct { 00470 const IWICFormatConverterInfoVtbl *lpIWICFormatConverterInfoVtbl; 00471 LONG ref; 00472 HKEY classkey; 00473 CLSID clsid; 00474 } FormatConverterInfo; 00475 00476 static HRESULT WINAPI FormatConverterInfo_QueryInterface(IWICFormatConverterInfo *iface, REFIID iid, 00477 void **ppv) 00478 { 00479 FormatConverterInfo *This = (FormatConverterInfo*)iface; 00480 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); 00481 00482 if (!ppv) return E_INVALIDARG; 00483 00484 if (IsEqualIID(&IID_IUnknown, iid) || 00485 IsEqualIID(&IID_IWICComponentInfo, iid) || 00486 IsEqualIID(&IID_IWICFormatConverterInfo ,iid)) 00487 { 00488 *ppv = This; 00489 } 00490 else 00491 { 00492 *ppv = NULL; 00493 return E_NOINTERFACE; 00494 } 00495 00496 IUnknown_AddRef((IUnknown*)*ppv); 00497 return S_OK; 00498 } 00499 00500 static ULONG WINAPI FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface) 00501 { 00502 FormatConverterInfo *This = (FormatConverterInfo*)iface; 00503 ULONG ref = InterlockedIncrement(&This->ref); 00504 00505 TRACE("(%p) refcount=%u\n", iface, ref); 00506 00507 return ref; 00508 } 00509 00510 static ULONG WINAPI FormatConverterInfo_Release(IWICFormatConverterInfo *iface) 00511 { 00512 FormatConverterInfo *This = (FormatConverterInfo*)iface; 00513 ULONG ref = InterlockedDecrement(&This->ref); 00514 00515 TRACE("(%p) refcount=%u\n", iface, ref); 00516 00517 if (ref == 0) 00518 { 00519 RegCloseKey(This->classkey); 00520 HeapFree(GetProcessHeap(), 0, This); 00521 } 00522 00523 return ref; 00524 } 00525 00526 static HRESULT WINAPI FormatConverterInfo_GetComponentType(IWICFormatConverterInfo *iface, 00527 WICComponentType *pType) 00528 { 00529 TRACE("(%p,%p)\n", iface, pType); 00530 *pType = WICPixelFormatConverter; 00531 return S_OK; 00532 } 00533 00534 static HRESULT WINAPI FormatConverterInfo_GetCLSID(IWICFormatConverterInfo *iface, CLSID *pclsid) 00535 { 00536 FIXME("(%p,%p): stub\n", iface, pclsid); 00537 return E_NOTIMPL; 00538 } 00539 00540 static HRESULT WINAPI FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo *iface, DWORD *pStatus) 00541 { 00542 FIXME("(%p,%p): stub\n", iface, pStatus); 00543 return E_NOTIMPL; 00544 } 00545 00546 static HRESULT WINAPI FormatConverterInfo_GetAuthor(IWICFormatConverterInfo *iface, UINT cchAuthor, 00547 WCHAR *wzAuthor, UINT *pcchActual) 00548 { 00549 FIXME("(%p,%u,%p,%p): stub\n", iface, cchAuthor, wzAuthor, pcchActual); 00550 return E_NOTIMPL; 00551 } 00552 00553 static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo *iface, GUID *pguidVendor) 00554 { 00555 FIXME("(%p,%p): stub\n", iface, pguidVendor); 00556 return E_NOTIMPL; 00557 } 00558 00559 static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *iface, UINT cchVersion, 00560 WCHAR *wzVersion, UINT *pcchActual) 00561 { 00562 FIXME("(%p,%u,%p,%p): stub\n", iface, cchVersion, wzVersion, pcchActual); 00563 return E_NOTIMPL; 00564 } 00565 00566 static HRESULT WINAPI FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo *iface, UINT cchSpecVersion, 00567 WCHAR *wzSpecVersion, UINT *pcchActual) 00568 { 00569 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual); 00570 return E_NOTIMPL; 00571 } 00572 00573 static HRESULT WINAPI FormatConverterInfo_GetFriendlyName(IWICFormatConverterInfo *iface, UINT cchFriendlyName, 00574 WCHAR *wzFriendlyName, UINT *pcchActual) 00575 { 00576 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFriendlyName, wzFriendlyName, pcchActual); 00577 return E_NOTIMPL; 00578 } 00579 00580 static HRESULT WINAPI FormatConverterInfo_GetPixelFormats(IWICFormatConverterInfo *iface, 00581 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual) 00582 { 00583 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual); 00584 return E_NOTIMPL; 00585 } 00586 00587 static HRESULT WINAPI FormatConverterInfo_CreateInstance(IWICFormatConverterInfo *iface, 00588 IWICFormatConverter **ppIFormatConverter) 00589 { 00590 FormatConverterInfo *This = (FormatConverterInfo*)iface; 00591 00592 TRACE("(%p,%p)\n", iface, ppIFormatConverter); 00593 00594 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER, 00595 &IID_IWICFormatConverter, (void**)ppIFormatConverter); 00596 } 00597 00598 static BOOL ConverterSupportsFormat(IWICFormatConverterInfo *iface, const WCHAR *formatguid) 00599 { 00600 LONG res; 00601 FormatConverterInfo *This = (FormatConverterInfo*)iface; 00602 HKEY formats_key, guid_key; 00603 00604 /* Avoid testing using IWICFormatConverter_GetPixelFormats because that 00605 would be O(n). A registry test should do better. */ 00606 00607 res = RegOpenKeyExW(This->classkey, pixelformats_keyname, 0, KEY_READ, &formats_key); 00608 if (res != ERROR_SUCCESS) return FALSE; 00609 00610 res = RegOpenKeyExW(formats_key, formatguid, 0, KEY_READ, &guid_key); 00611 if (res == ERROR_SUCCESS) RegCloseKey(guid_key); 00612 00613 RegCloseKey(formats_key); 00614 00615 return (res == ERROR_SUCCESS); 00616 } 00617 00618 static const IWICFormatConverterInfoVtbl FormatConverterInfo_Vtbl = { 00619 FormatConverterInfo_QueryInterface, 00620 FormatConverterInfo_AddRef, 00621 FormatConverterInfo_Release, 00622 FormatConverterInfo_GetComponentType, 00623 FormatConverterInfo_GetCLSID, 00624 FormatConverterInfo_GetSigningStatus, 00625 FormatConverterInfo_GetAuthor, 00626 FormatConverterInfo_GetVendorGUID, 00627 FormatConverterInfo_GetVersion, 00628 FormatConverterInfo_GetSpecVersion, 00629 FormatConverterInfo_GetFriendlyName, 00630 FormatConverterInfo_GetPixelFormats, 00631 FormatConverterInfo_CreateInstance 00632 }; 00633 00634 static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo) 00635 { 00636 FormatConverterInfo *This; 00637 00638 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo)); 00639 if (!This) 00640 { 00641 RegCloseKey(classkey); 00642 return E_OUTOFMEMORY; 00643 } 00644 00645 This->lpIWICFormatConverterInfoVtbl = &FormatConverterInfo_Vtbl; 00646 This->ref = 1; 00647 This->classkey = classkey; 00648 memcpy(&This->clsid, clsid, sizeof(CLSID)); 00649 00650 *ppIInfo = (IWICComponentInfo*)This; 00651 return S_OK; 00652 } 00653 00654 static WCHAR const clsid_keyname[] = {'C','L','S','I','D',0}; 00655 static WCHAR const instance_keyname[] = {'I','n','s','t','a','n','c','e',0}; 00656 00657 struct category { 00658 WICComponentType type; 00659 const GUID *catid; 00660 HRESULT (*constructor)(HKEY,REFCLSID,IWICComponentInfo**); 00661 }; 00662 00663 static const struct category categories[] = { 00664 {WICDecoder, &CATID_WICBitmapDecoders, BitmapDecoderInfo_Constructor}, 00665 {WICPixelFormatConverter, &CATID_WICFormatConverters, FormatConverterInfo_Constructor}, 00666 {0} 00667 }; 00668 00669 HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo) 00670 { 00671 HKEY clsidkey; 00672 HKEY classkey; 00673 HKEY catidkey; 00674 HKEY instancekey; 00675 WCHAR guidstring[39]; 00676 LONG res; 00677 const struct category *category; 00678 int found=0; 00679 HRESULT hr; 00680 00681 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey); 00682 if (res != ERROR_SUCCESS) 00683 return HRESULT_FROM_WIN32(res); 00684 00685 for (category=categories; category->type; category++) 00686 { 00687 StringFromGUID2(category->catid, guidstring, 39); 00688 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey); 00689 if (res == ERROR_SUCCESS) 00690 { 00691 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey); 00692 if (res == ERROR_SUCCESS) 00693 { 00694 StringFromGUID2(clsid, guidstring, 39); 00695 res = RegOpenKeyExW(instancekey, guidstring, 0, KEY_READ, &classkey); 00696 if (res == ERROR_SUCCESS) 00697 { 00698 RegCloseKey(classkey); 00699 found = 1; 00700 } 00701 RegCloseKey(instancekey); 00702 } 00703 RegCloseKey(catidkey); 00704 } 00705 if (found) break; 00706 } 00707 00708 if (found) 00709 { 00710 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &classkey); 00711 if (res == ERROR_SUCCESS) 00712 hr = category->constructor(classkey, clsid, ppIInfo); 00713 else 00714 hr = HRESULT_FROM_WIN32(res); 00715 } 00716 else 00717 hr = E_FAIL; 00718 00719 RegCloseKey(clsidkey); 00720 00721 return hr; 00722 } 00723 00724 typedef struct { 00725 const IEnumUnknownVtbl *IEnumUnknown_Vtbl; 00726 LONG ref; 00727 struct list objects; 00728 struct list *cursor; 00729 CRITICAL_SECTION lock; /* Must be held when reading or writing cursor */ 00730 } ComponentEnum; 00731 00732 typedef struct { 00733 struct list entry; 00734 IUnknown *unk; 00735 } ComponentEnumItem; 00736 00737 static const IEnumUnknownVtbl ComponentEnumVtbl; 00738 00739 static HRESULT WINAPI ComponentEnum_QueryInterface(IEnumUnknown *iface, REFIID iid, 00740 void **ppv) 00741 { 00742 ComponentEnum *This = (ComponentEnum*)iface; 00743 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); 00744 00745 if (!ppv) return E_INVALIDARG; 00746 00747 if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IEnumUnknown, iid)) 00748 { 00749 *ppv = This; 00750 } 00751 else 00752 { 00753 *ppv = NULL; 00754 return E_NOINTERFACE; 00755 } 00756 00757 IUnknown_AddRef((IUnknown*)*ppv); 00758 return S_OK; 00759 } 00760 00761 static ULONG WINAPI ComponentEnum_AddRef(IEnumUnknown *iface) 00762 { 00763 ComponentEnum *This = (ComponentEnum*)iface; 00764 ULONG ref = InterlockedIncrement(&This->ref); 00765 00766 TRACE("(%p) refcount=%u\n", iface, ref); 00767 00768 return ref; 00769 } 00770 00771 static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface) 00772 { 00773 ComponentEnum *This = (ComponentEnum*)iface; 00774 ULONG ref = InterlockedDecrement(&This->ref); 00775 ComponentEnumItem *cursor, *cursor2; 00776 00777 TRACE("(%p) refcount=%u\n", iface, ref); 00778 00779 if (ref == 0) 00780 { 00781 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->objects, ComponentEnumItem, entry) 00782 { 00783 IUnknown_Release(cursor->unk); 00784 list_remove(&cursor->entry); 00785 HeapFree(GetProcessHeap(), 0, cursor); 00786 } 00787 This->lock.DebugInfo->Spare[0] = 0; 00788 DeleteCriticalSection(&This->lock); 00789 HeapFree(GetProcessHeap(), 0, This); 00790 } 00791 00792 return ref; 00793 } 00794 00795 static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt, 00796 IUnknown **rgelt, ULONG *pceltFetched) 00797 { 00798 ComponentEnum *This = (ComponentEnum*)iface; 00799 int num_fetched=0; 00800 ComponentEnumItem *item; 00801 HRESULT hr=S_OK; 00802 00803 TRACE("(%p,%u,%p,%p)\n", iface, celt, rgelt, pceltFetched); 00804 00805 EnterCriticalSection(&This->lock); 00806 while (num_fetched<celt) 00807 { 00808 if (!This->cursor) 00809 { 00810 hr = S_FALSE; 00811 break; 00812 } 00813 item = LIST_ENTRY(This->cursor, ComponentEnumItem, entry); 00814 IUnknown_AddRef(item->unk); 00815 rgelt[num_fetched] = item->unk; 00816 num_fetched++; 00817 This->cursor = list_next(&This->objects, This->cursor); 00818 } 00819 LeaveCriticalSection(&This->lock); 00820 if (pceltFetched) 00821 *pceltFetched = num_fetched; 00822 return hr; 00823 } 00824 00825 static HRESULT WINAPI ComponentEnum_Skip(IEnumUnknown *iface, ULONG celt) 00826 { 00827 ComponentEnum *This = (ComponentEnum*)iface; 00828 int i; 00829 HRESULT hr=S_OK; 00830 00831 TRACE("(%p,%u)\n", iface, celt); 00832 00833 EnterCriticalSection(&This->lock); 00834 for (i=0; i<celt; i++) 00835 { 00836 if (!This->cursor) 00837 { 00838 hr = S_FALSE; 00839 break; 00840 } 00841 This->cursor = list_next(&This->objects, This->cursor); 00842 } 00843 LeaveCriticalSection(&This->lock); 00844 return hr; 00845 } 00846 00847 static HRESULT WINAPI ComponentEnum_Reset(IEnumUnknown *iface) 00848 { 00849 ComponentEnum *This = (ComponentEnum*)iface; 00850 00851 TRACE("(%p)\n", iface); 00852 00853 EnterCriticalSection(&This->lock); 00854 This->cursor = list_head(&This->objects); 00855 LeaveCriticalSection(&This->lock); 00856 return S_OK; 00857 } 00858 00859 static HRESULT WINAPI ComponentEnum_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum) 00860 { 00861 ComponentEnum *This = (ComponentEnum*)iface; 00862 ComponentEnum *new_enum; 00863 ComponentEnumItem *old_item, *new_item; 00864 HRESULT ret=S_OK; 00865 struct list *old_cursor; 00866 00867 new_enum = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum)); 00868 if (!new_enum) 00869 { 00870 *ppenum = NULL; 00871 return E_OUTOFMEMORY; 00872 } 00873 00874 new_enum->IEnumUnknown_Vtbl = &ComponentEnumVtbl; 00875 new_enum->ref = 1; 00876 new_enum->cursor = NULL; 00877 list_init(&new_enum->objects); 00878 InitializeCriticalSection(&new_enum->lock); 00879 new_enum->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock"); 00880 00881 EnterCriticalSection(&This->lock); 00882 old_cursor = This->cursor; 00883 LeaveCriticalSection(&This->lock); 00884 00885 LIST_FOR_EACH_ENTRY(old_item, &This->objects, ComponentEnumItem, entry) 00886 { 00887 new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem)); 00888 if (!new_item) 00889 { 00890 ret = E_OUTOFMEMORY; 00891 break; 00892 } 00893 new_item->unk = old_item->unk; 00894 list_add_tail(&new_enum->objects, &new_item->entry); 00895 IUnknown_AddRef(new_item->unk); 00896 if (&old_item->entry == old_cursor) new_enum->cursor = &new_item->entry; 00897 } 00898 00899 if (FAILED(ret)) 00900 { 00901 IUnknown_Release((IUnknown*)new_enum); 00902 *ppenum = NULL; 00903 } 00904 else 00905 *ppenum = (IEnumUnknown*)new_enum; 00906 00907 return ret; 00908 } 00909 00910 static const IEnumUnknownVtbl ComponentEnumVtbl = { 00911 ComponentEnum_QueryInterface, 00912 ComponentEnum_AddRef, 00913 ComponentEnum_Release, 00914 ComponentEnum_Next, 00915 ComponentEnum_Skip, 00916 ComponentEnum_Reset, 00917 ComponentEnum_Clone 00918 }; 00919 00920 HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown) 00921 { 00922 ComponentEnum *This; 00923 ComponentEnumItem *item; 00924 const struct category *category; 00925 HKEY clsidkey, catidkey, instancekey; 00926 WCHAR guidstring[39]; 00927 LONG res; 00928 int i; 00929 HRESULT hr=S_OK; 00930 CLSID clsid; 00931 00932 if (options) FIXME("ignoring flags %x\n", options); 00933 00934 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey); 00935 if (res != ERROR_SUCCESS) 00936 return HRESULT_FROM_WIN32(res); 00937 00938 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum)); 00939 if (!This) 00940 { 00941 RegCloseKey(clsidkey); 00942 return E_OUTOFMEMORY; 00943 } 00944 00945 This->IEnumUnknown_Vtbl = &ComponentEnumVtbl; 00946 This->ref = 1; 00947 list_init(&This->objects); 00948 InitializeCriticalSection(&This->lock); 00949 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock"); 00950 00951 for (category=categories; category->type && hr == S_OK; category++) 00952 { 00953 if ((category->type & componentTypes) == 0) continue; 00954 StringFromGUID2(category->catid, guidstring, 39); 00955 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey); 00956 if (res == ERROR_SUCCESS) 00957 { 00958 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey); 00959 if (res == ERROR_SUCCESS) 00960 { 00961 i=0; 00962 for (;;i++) 00963 { 00964 DWORD guidstring_size = 39; 00965 res = RegEnumKeyExW(instancekey, i, guidstring, &guidstring_size, NULL, NULL, NULL, NULL); 00966 if (res != ERROR_SUCCESS) break; 00967 00968 item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem)); 00969 if (!item) { hr = E_OUTOFMEMORY; break; } 00970 00971 hr = CLSIDFromString(guidstring, &clsid); 00972 if (SUCCEEDED(hr)) 00973 { 00974 hr = CreateComponentInfo(&clsid, (IWICComponentInfo**)&item->unk); 00975 if (SUCCEEDED(hr)) 00976 list_add_tail(&This->objects, &item->entry); 00977 } 00978 00979 if (FAILED(hr)) 00980 { 00981 HeapFree(GetProcessHeap(), 0, item); 00982 hr = S_OK; 00983 } 00984 } 00985 RegCloseKey(instancekey); 00986 } 00987 RegCloseKey(catidkey); 00988 } 00989 if (res != ERROR_SUCCESS && res != ERROR_NO_MORE_ITEMS) 00990 hr = HRESULT_FROM_WIN32(res); 00991 } 00992 RegCloseKey(clsidkey); 00993 00994 if (SUCCEEDED(hr)) 00995 { 00996 IEnumUnknown_Reset((IEnumUnknown*)This); 00997 *ppIEnumUnknown = (IEnumUnknown*)This; 00998 } 00999 else 01000 { 01001 *ppIEnumUnknown = NULL; 01002 IUnknown_Release((IUnknown*)This); 01003 } 01004 01005 return hr; 01006 } 01007 01008 HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst) 01009 { 01010 HRESULT res; 01011 IEnumUnknown *enumconverters; 01012 IUnknown *unkconverterinfo; 01013 IWICFormatConverterInfo *converterinfo=NULL; 01014 IWICFormatConverter *converter=NULL; 01015 GUID srcFormat; 01016 WCHAR srcformatstr[39], dstformatstr[39]; 01017 BOOL canconvert; 01018 ULONG num_fetched; 01019 01020 res = IWICBitmapSource_GetPixelFormat(pISrc, &srcFormat); 01021 if (FAILED(res)) return res; 01022 01023 if (IsEqualGUID(&srcFormat, dstFormat)) 01024 { 01025 IWICBitmapSource_AddRef(pISrc); 01026 *ppIDst = pISrc; 01027 return S_OK; 01028 } 01029 01030 StringFromGUID2(&srcFormat, srcformatstr, 39); 01031 StringFromGUID2(dstFormat, dstformatstr, 39); 01032 01033 res = CreateComponentEnumerator(WICPixelFormatConverter, 0, &enumconverters); 01034 if (FAILED(res)) return res; 01035 01036 while (!converter) 01037 { 01038 res = IEnumUnknown_Next(enumconverters, 1, &unkconverterinfo, &num_fetched); 01039 01040 if (res == S_OK) 01041 { 01042 res = IUnknown_QueryInterface(unkconverterinfo, &IID_IWICFormatConverterInfo, (void**)&converterinfo); 01043 01044 if (SUCCEEDED(res)) 01045 { 01046 canconvert = ConverterSupportsFormat(converterinfo, srcformatstr); 01047 01048 if (canconvert) 01049 canconvert = ConverterSupportsFormat(converterinfo, dstformatstr); 01050 01051 if (canconvert) 01052 { 01053 res = IWICFormatConverterInfo_CreateInstance(converterinfo, &converter); 01054 01055 if (SUCCEEDED(res)) 01056 res = IWICFormatConverter_CanConvert(converter, &srcFormat, dstFormat, &canconvert); 01057 01058 if (SUCCEEDED(res) && canconvert) 01059 res = IWICFormatConverter_Initialize(converter, pISrc, dstFormat, WICBitmapDitherTypeNone, 01060 NULL, 0.0, WICBitmapPaletteTypeCustom); 01061 01062 if (FAILED(res) || !canconvert) 01063 { 01064 if (converter) 01065 { 01066 IWICFormatConverter_Release(converter); 01067 converter = NULL; 01068 } 01069 res = S_OK; 01070 } 01071 } 01072 01073 IWICFormatConverterInfo_Release(converterinfo); 01074 } 01075 01076 IUnknown_Release(unkconverterinfo); 01077 } 01078 else 01079 break; 01080 } 01081 01082 IEnumUnknown_Release(enumconverters); 01083 01084 if (converter) 01085 { 01086 *ppIDst = (IWICBitmapSource*)converter; 01087 return S_OK; 01088 } 01089 else 01090 { 01091 FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat)); 01092 *ppIDst = NULL; 01093 return WINCODEC_ERR_COMPONENTNOTFOUND; 01094 } 01095 } Generated on Sun May 27 2012 04:24:38 for ReactOS by
1.7.6.1
|