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 +}