Mercurial > vba-linux
view 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 source
1 // CreateCoder.cpp3 #include "StdAfx.h"5 #include "CreateCoder.h"7 #include "../../Windows/PropVariant.h"8 #include "../../Windows/Defs.h"9 #include "FilterCoder.h"10 #include "RegisterCodec.h"12 static const unsigned int kNumCodecsMax = 64;13 unsigned int g_NumCodecs = 0;14 const CCodecInfo *g_Codecs[kNumCodecsMax];15 void RegisterCodec(const CCodecInfo *codecInfo)16 {17 if (g_NumCodecs < kNumCodecsMax)18 g_Codecs[g_NumCodecs++] = codecInfo;19 }21 #ifdef EXTERNAL_CODECS22 static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res)23 {24 NWindows::NCOM::CPropVariant prop;25 RINOK(codecsInfo->GetProperty(index, propID, &prop));26 if (prop.vt == VT_EMPTY)27 res = 1;28 else if (prop.vt == VT_UI4)29 res = prop.ulVal;30 else31 return E_INVALIDARG;32 return S_OK;33 }35 static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, bool &res)36 {37 NWindows::NCOM::CPropVariant prop;38 RINOK(codecsInfo->GetProperty(index, propID, &prop));39 if (prop.vt == VT_EMPTY)40 res = true;41 else if (prop.vt == VT_BOOL)42 res = VARIANT_BOOLToBool(prop.boolVal);43 else44 return E_INVALIDARG;45 return S_OK;46 }48 HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs)49 {50 UInt32 num;51 RINOK(codecsInfo->GetNumberOfMethods(&num));52 for (UInt32 i = 0; i < num; i++)53 {54 CCodecInfoEx info;55 NWindows::NCOM::CPropVariant prop;56 RINOK(codecsInfo->GetProperty(i, NMethodPropID::kID, &prop));57 // if (prop.vt != VT_BSTR)58 // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal);59 // memmove(info.Id.ID, prop.bstrVal, info.Id.IDSize);60 if (prop.vt != VT_UI8)61 {62 continue; // old Interface63 // return E_INVALIDARG;64 }65 info.Id = prop.uhVal.QuadPart;66 prop.Clear();68 RINOK(codecsInfo->GetProperty(i, NMethodPropID::kName, &prop));69 if (prop.vt == VT_BSTR)70 info.Name = prop.bstrVal;71 else if (prop.vt != VT_EMPTY)72 return E_INVALIDARG;;74 RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kInStreams, info.NumInStreams));75 RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kOutStreams, info.NumOutStreams));76 RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned));77 RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned));79 externalCodecs.Add(info);80 }81 return S_OK;82 }84 #endif86 bool FindMethod(87 #ifdef EXTERNAL_CODECS88 ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,89 #endif90 const UString &name,91 CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams)92 {93 UInt32 i;94 for (i = 0; i < g_NumCodecs; i++)95 {96 const CCodecInfo &codec = *g_Codecs[i];97 if (name.CompareNoCase(codec.Name) == 0)98 {99 methodId = codec.Id;100 numInStreams = codec.NumInStreams;101 numOutStreams = 1;102 return true;103 }104 }105 #ifdef EXTERNAL_CODECS106 if (externalCodecs)107 for (i = 0; i < (UInt32)externalCodecs->Size(); i++)108 {109 const CCodecInfoEx &codec = (*externalCodecs)[i];110 if (codec.Name.CompareNoCase(name) == 0)111 {112 methodId = codec.Id;113 numInStreams = codec.NumInStreams;114 numOutStreams = codec.NumOutStreams;115 return true;116 }117 }118 #endif119 return false;120 }122 bool FindMethod(123 #ifdef EXTERNAL_CODECS124 ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,125 #endif126 CMethodId methodId, UString &name)127 {128 UInt32 i;129 for (i = 0; i < g_NumCodecs; i++)130 {131 const CCodecInfo &codec = *g_Codecs[i];132 if (methodId == codec.Id)133 {134 name = codec.Name;135 return true;136 }137 }138 #ifdef EXTERNAL_CODECS139 if (externalCodecs)140 for (i = 0; i < (UInt32)externalCodecs->Size(); i++)141 {142 const CCodecInfoEx &codec = (*externalCodecs)[i];143 if (methodId == codec.Id)144 {145 name = codec.Name;146 return true;147 }148 }149 #endif150 return false;151 }153 HRESULT CreateCoder(154 DECL_EXTERNAL_CODECS_LOC_VARS155 CMethodId methodId,156 CMyComPtr<ICompressFilter> &filter,157 CMyComPtr<ICompressCoder> &coder,158 CMyComPtr<ICompressCoder2> &coder2,159 bool encode, bool onlyCoder)160 {161 bool created = false;162 UInt32 i;163 for (i = 0; i < g_NumCodecs; i++)164 {165 const CCodecInfo &codec = *g_Codecs[i];166 if (codec.Id == methodId)167 {168 if (encode)169 {170 if (codec.CreateEncoder)171 {172 void *p = codec.CreateEncoder();173 if (codec.IsFilter) filter = (ICompressFilter *)p;174 else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;175 else coder2 = (ICompressCoder2 *)p;176 created = (p != 0);177 break;178 }179 }180 else181 if (codec.CreateDecoder)182 {183 void *p = codec.CreateDecoder();184 if (codec.IsFilter) filter = (ICompressFilter *)p;185 else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;186 else coder2 = (ICompressCoder2 *)p;187 created = (p != 0);188 break;189 }190 }191 }193 #ifdef EXTERNAL_CODECS194 if (!created && externalCodecs)195 for (i = 0; i < (UInt32)externalCodecs->Size(); i++)196 {197 const CCodecInfoEx &codec = (*externalCodecs)[i];198 if (codec.Id == methodId)199 {200 if (encode)201 {202 if (codec.EncoderIsAssigned)203 {204 if (codec.IsSimpleCodec())205 {206 HRESULT result = codecsInfo->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder);207 if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)208 return result;209 if (!coder)210 {211 RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter));212 }213 }214 else215 {216 RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2));217 }218 break;219 }220 }221 else222 if (codec.DecoderIsAssigned)223 {224 if (codec.IsSimpleCodec())225 {226 HRESULT result = codecsInfo->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder);227 if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)228 return result;229 if (!coder)230 {231 RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter));232 }233 }234 else235 {236 RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2));237 }238 break;239 }240 }241 }242 #endif244 if (onlyCoder && filter)245 {246 CFilterCoder *coderSpec = new CFilterCoder;247 coder = coderSpec;248 coderSpec->Filter = filter;249 }250 return S_OK;251 }253 HRESULT CreateCoder(254 DECL_EXTERNAL_CODECS_LOC_VARS255 CMethodId methodId,256 CMyComPtr<ICompressCoder> &coder,257 CMyComPtr<ICompressCoder2> &coder2,258 bool encode)259 {260 CMyComPtr<ICompressFilter> filter;261 return CreateCoder(262 EXTERNAL_CODECS_LOC_VARS263 methodId,264 filter, coder, coder2, encode, true);265 }267 HRESULT CreateCoder(268 DECL_EXTERNAL_CODECS_LOC_VARS269 CMethodId methodId,270 CMyComPtr<ICompressCoder> &coder, bool encode)271 {272 CMyComPtr<ICompressFilter> filter;273 CMyComPtr<ICompressCoder2> coder2;274 return CreateCoder(275 EXTERNAL_CODECS_LOC_VARS276 methodId,277 coder, coder2, encode);278 }280 HRESULT CreateFilter(281 DECL_EXTERNAL_CODECS_LOC_VARS282 CMethodId methodId,283 CMyComPtr<ICompressFilter> &filter,284 bool encode)285 {286 CMyComPtr<ICompressCoder> coder;287 CMyComPtr<ICompressCoder2> coder2;288 return CreateCoder(289 EXTERNAL_CODECS_LOC_VARS290 methodId,291 filter, coder, coder2, encode, false);292 }