Mercurial > vba-linux
diff src/win32/7zip/7z/CPP/7zip/Common/CreateCoder.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Common/CreateCoder.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,292 @@ 1.4 +// CreateCoder.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +#include "CreateCoder.h" 1.9 + 1.10 +#include "../../Windows/PropVariant.h" 1.11 +#include "../../Windows/Defs.h" 1.12 +#include "FilterCoder.h" 1.13 +#include "RegisterCodec.h" 1.14 + 1.15 +static const unsigned int kNumCodecsMax = 64; 1.16 +unsigned int g_NumCodecs = 0; 1.17 +const CCodecInfo *g_Codecs[kNumCodecsMax]; 1.18 +void RegisterCodec(const CCodecInfo *codecInfo) 1.19 +{ 1.20 + if (g_NumCodecs < kNumCodecsMax) 1.21 + g_Codecs[g_NumCodecs++] = codecInfo; 1.22 +} 1.23 + 1.24 +#ifdef EXTERNAL_CODECS 1.25 +static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res) 1.26 +{ 1.27 + NWindows::NCOM::CPropVariant prop; 1.28 + RINOK(codecsInfo->GetProperty(index, propID, &prop)); 1.29 + if (prop.vt == VT_EMPTY) 1.30 + res = 1; 1.31 + else if (prop.vt == VT_UI4) 1.32 + res = prop.ulVal; 1.33 + else 1.34 + return E_INVALIDARG; 1.35 + return S_OK; 1.36 +} 1.37 + 1.38 +static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, bool &res) 1.39 +{ 1.40 + NWindows::NCOM::CPropVariant prop; 1.41 + RINOK(codecsInfo->GetProperty(index, propID, &prop)); 1.42 + if (prop.vt == VT_EMPTY) 1.43 + res = true; 1.44 + else if (prop.vt == VT_BOOL) 1.45 + res = VARIANT_BOOLToBool(prop.boolVal); 1.46 + else 1.47 + return E_INVALIDARG; 1.48 + return S_OK; 1.49 +} 1.50 + 1.51 +HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs) 1.52 +{ 1.53 + UInt32 num; 1.54 + RINOK(codecsInfo->GetNumberOfMethods(&num)); 1.55 + for (UInt32 i = 0; i < num; i++) 1.56 + { 1.57 + CCodecInfoEx info; 1.58 + NWindows::NCOM::CPropVariant prop; 1.59 + RINOK(codecsInfo->GetProperty(i, NMethodPropID::kID, &prop)); 1.60 + // if (prop.vt != VT_BSTR) 1.61 + // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal); 1.62 + // memmove(info.Id.ID, prop.bstrVal, info.Id.IDSize); 1.63 + if (prop.vt != VT_UI8) 1.64 + { 1.65 + continue; // old Interface 1.66 + // return E_INVALIDARG; 1.67 + } 1.68 + info.Id = prop.uhVal.QuadPart; 1.69 + prop.Clear(); 1.70 + 1.71 + RINOK(codecsInfo->GetProperty(i, NMethodPropID::kName, &prop)); 1.72 + if (prop.vt == VT_BSTR) 1.73 + info.Name = prop.bstrVal; 1.74 + else if (prop.vt != VT_EMPTY) 1.75 + return E_INVALIDARG;; 1.76 + 1.77 + RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kInStreams, info.NumInStreams)); 1.78 + RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kOutStreams, info.NumOutStreams)); 1.79 + RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned)); 1.80 + RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned)); 1.81 + 1.82 + externalCodecs.Add(info); 1.83 + } 1.84 + return S_OK; 1.85 +} 1.86 + 1.87 +#endif 1.88 + 1.89 +bool FindMethod( 1.90 + #ifdef EXTERNAL_CODECS 1.91 + ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs, 1.92 + #endif 1.93 + const UString &name, 1.94 + CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams) 1.95 +{ 1.96 + UInt32 i; 1.97 + for (i = 0; i < g_NumCodecs; i++) 1.98 + { 1.99 + const CCodecInfo &codec = *g_Codecs[i]; 1.100 + if (name.CompareNoCase(codec.Name) == 0) 1.101 + { 1.102 + methodId = codec.Id; 1.103 + numInStreams = codec.NumInStreams; 1.104 + numOutStreams = 1; 1.105 + return true; 1.106 + } 1.107 + } 1.108 + #ifdef EXTERNAL_CODECS 1.109 + if (externalCodecs) 1.110 + for (i = 0; i < (UInt32)externalCodecs->Size(); i++) 1.111 + { 1.112 + const CCodecInfoEx &codec = (*externalCodecs)[i]; 1.113 + if (codec.Name.CompareNoCase(name) == 0) 1.114 + { 1.115 + methodId = codec.Id; 1.116 + numInStreams = codec.NumInStreams; 1.117 + numOutStreams = codec.NumOutStreams; 1.118 + return true; 1.119 + } 1.120 + } 1.121 + #endif 1.122 + return false; 1.123 +} 1.124 + 1.125 +bool FindMethod( 1.126 + #ifdef EXTERNAL_CODECS 1.127 + ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs, 1.128 + #endif 1.129 + CMethodId methodId, UString &name) 1.130 +{ 1.131 + UInt32 i; 1.132 + for (i = 0; i < g_NumCodecs; i++) 1.133 + { 1.134 + const CCodecInfo &codec = *g_Codecs[i]; 1.135 + if (methodId == codec.Id) 1.136 + { 1.137 + name = codec.Name; 1.138 + return true; 1.139 + } 1.140 + } 1.141 + #ifdef EXTERNAL_CODECS 1.142 + if (externalCodecs) 1.143 + for (i = 0; i < (UInt32)externalCodecs->Size(); i++) 1.144 + { 1.145 + const CCodecInfoEx &codec = (*externalCodecs)[i]; 1.146 + if (methodId == codec.Id) 1.147 + { 1.148 + name = codec.Name; 1.149 + return true; 1.150 + } 1.151 + } 1.152 + #endif 1.153 + return false; 1.154 +} 1.155 + 1.156 +HRESULT CreateCoder( 1.157 + DECL_EXTERNAL_CODECS_LOC_VARS 1.158 + CMethodId methodId, 1.159 + CMyComPtr<ICompressFilter> &filter, 1.160 + CMyComPtr<ICompressCoder> &coder, 1.161 + CMyComPtr<ICompressCoder2> &coder2, 1.162 + bool encode, bool onlyCoder) 1.163 +{ 1.164 + bool created = false; 1.165 + UInt32 i; 1.166 + for (i = 0; i < g_NumCodecs; i++) 1.167 + { 1.168 + const CCodecInfo &codec = *g_Codecs[i]; 1.169 + if (codec.Id == methodId) 1.170 + { 1.171 + if (encode) 1.172 + { 1.173 + if (codec.CreateEncoder) 1.174 + { 1.175 + void *p = codec.CreateEncoder(); 1.176 + if (codec.IsFilter) filter = (ICompressFilter *)p; 1.177 + else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p; 1.178 + else coder2 = (ICompressCoder2 *)p; 1.179 + created = (p != 0); 1.180 + break; 1.181 + } 1.182 + } 1.183 + else 1.184 + if (codec.CreateDecoder) 1.185 + { 1.186 + void *p = codec.CreateDecoder(); 1.187 + if (codec.IsFilter) filter = (ICompressFilter *)p; 1.188 + else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p; 1.189 + else coder2 = (ICompressCoder2 *)p; 1.190 + created = (p != 0); 1.191 + break; 1.192 + } 1.193 + } 1.194 + } 1.195 + 1.196 + #ifdef EXTERNAL_CODECS 1.197 + if (!created && externalCodecs) 1.198 + for (i = 0; i < (UInt32)externalCodecs->Size(); i++) 1.199 + { 1.200 + const CCodecInfoEx &codec = (*externalCodecs)[i]; 1.201 + if (codec.Id == methodId) 1.202 + { 1.203 + if (encode) 1.204 + { 1.205 + if (codec.EncoderIsAssigned) 1.206 + { 1.207 + if (codec.IsSimpleCodec()) 1.208 + { 1.209 + HRESULT result = codecsInfo->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder); 1.210 + if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE) 1.211 + return result; 1.212 + if (!coder) 1.213 + { 1.214 + RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter)); 1.215 + } 1.216 + } 1.217 + else 1.218 + { 1.219 + RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2)); 1.220 + } 1.221 + break; 1.222 + } 1.223 + } 1.224 + else 1.225 + if (codec.DecoderIsAssigned) 1.226 + { 1.227 + if (codec.IsSimpleCodec()) 1.228 + { 1.229 + HRESULT result = codecsInfo->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder); 1.230 + if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE) 1.231 + return result; 1.232 + if (!coder) 1.233 + { 1.234 + RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter)); 1.235 + } 1.236 + } 1.237 + else 1.238 + { 1.239 + RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2)); 1.240 + } 1.241 + break; 1.242 + } 1.243 + } 1.244 + } 1.245 + #endif 1.246 + 1.247 + if (onlyCoder && filter) 1.248 + { 1.249 + CFilterCoder *coderSpec = new CFilterCoder; 1.250 + coder = coderSpec; 1.251 + coderSpec->Filter = filter; 1.252 + } 1.253 + return S_OK; 1.254 +} 1.255 + 1.256 +HRESULT CreateCoder( 1.257 + DECL_EXTERNAL_CODECS_LOC_VARS 1.258 + CMethodId methodId, 1.259 + CMyComPtr<ICompressCoder> &coder, 1.260 + CMyComPtr<ICompressCoder2> &coder2, 1.261 + bool encode) 1.262 +{ 1.263 + CMyComPtr<ICompressFilter> filter; 1.264 + return CreateCoder( 1.265 + EXTERNAL_CODECS_LOC_VARS 1.266 + methodId, 1.267 + filter, coder, coder2, encode, true); 1.268 +} 1.269 + 1.270 +HRESULT CreateCoder( 1.271 + DECL_EXTERNAL_CODECS_LOC_VARS 1.272 + CMethodId methodId, 1.273 + CMyComPtr<ICompressCoder> &coder, bool encode) 1.274 +{ 1.275 + CMyComPtr<ICompressFilter> filter; 1.276 + CMyComPtr<ICompressCoder2> coder2; 1.277 + return CreateCoder( 1.278 + EXTERNAL_CODECS_LOC_VARS 1.279 + methodId, 1.280 + coder, coder2, encode); 1.281 +} 1.282 + 1.283 +HRESULT CreateFilter( 1.284 + DECL_EXTERNAL_CODECS_LOC_VARS 1.285 + CMethodId methodId, 1.286 + CMyComPtr<ICompressFilter> &filter, 1.287 + bool encode) 1.288 +{ 1.289 + CMyComPtr<ICompressCoder> coder; 1.290 + CMyComPtr<ICompressCoder2> coder2; 1.291 + return CreateCoder( 1.292 + EXTERNAL_CODECS_LOC_VARS 1.293 + methodId, 1.294 + filter, coder, coder2, encode, false); 1.295 +}