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