ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

info.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.