예제 #1
0
HRESULT CCoderMixer2ST::GetInStream(
    ISequentialInStream **inStreams, const UInt64 **inSizes,
    UInt32 streamIndex, ISequentialInStream **inStreamRes)
{
  CMyComPtr<ISequentialInStream> seqInStream;
  int i;
  for(i = 0; i < _bindInfo.InStreams.Size(); i++)
    if (_bindInfo.InStreams[i] == streamIndex)
    {
      seqInStream = inStreams[i];
      *inStreamRes = seqInStream.Detach();
      return  S_OK;
    }
  int binderIndex = _bindInfo.FindBinderForInStream(streamIndex);
  if (binderIndex < 0)
    return E_INVALIDARG;

  UInt32 coderIndex, coderStreamIndex;
  _bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex,
      coderIndex, coderStreamIndex);

  CCoderInfo &coder = _coders[coderIndex];
  if (!coder.Coder)
    return E_NOTIMPL;
  coder.Coder.QueryInterface(IID_ISequentialInStream, &seqInStream);
  if (!seqInStream)
    return E_NOTIMPL;

  UInt32 startIndex = _bindInfo.GetCoderInStreamIndex(coderIndex);

  CMyComPtr<ICompressSetInStream> setInStream;
  if (!coder.Coder)
    return E_NOTIMPL;
  coder.Coder.QueryInterface(IID_ICompressSetInStream, &setInStream);
  if (!setInStream)
    return E_NOTIMPL;

  if (coder.NumInStreams > 1)
    return E_NOTIMPL;
  for (i = 0; i < (int)coder.NumInStreams; i++)
  {
    CMyComPtr<ISequentialInStream> seqInStream2;
    RINOK(GetInStream(inStreams, inSizes, startIndex + i, &seqInStream2));
    RINOK(setInStream->SetInStream(seqInStream2));
  }
  *inStreamRes = seqInStream.Detach();
  return S_OK;
}
예제 #2
0
HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter)
{
    useFilter = false;

    if (_decoderInStream)
        if (Method != _curMethod)
            Release();
    _curMethod = Method;
    if (!_codecInStream)
    {
        switch (Method)
        {
        // case NMethodType::kCopy: return E_NOTIMPL;
        case NMethodType::kDeflate:
            _codecInStream = new NCompress::NDeflate::NDecoder::CNsisCOMCoder();
            break;
        case NMethodType::kBZip2:
            _codecInStream = new NCompress::NBZip2::CNsisDecoder();
            break;
        case NMethodType::kLZMA:
            _lzmaDecoder = new NCompress::NLzma::CDecoder();
            _codecInStream = _lzmaDecoder;
            break;
        default:
            return E_NOTIMPL;
        }
    }

    if (FilterFlag)
    {
        Byte flag;
        RINOK(ReadStream_FALSE(inStream, &flag, 1));
        if (flag > 1)
            return E_NOTIMPL;
        useFilter = (flag != 0);
    }

    if (!useFilter)
        _decoderInStream = _codecInStream;
    else
    {
        if (!_filterInStream)
        {
            _filter = new CFilterCoder(false);
            _filterInStream = _filter;
            _filter->Filter = new NCompress::NBcj::CCoder(false);
        }
        RINOK(_filter->SetInStream(_codecInStream));
        _decoderInStream = _filterInStream;
    }

    if (Method == NMethodType::kLZMA)
    {
        const unsigned kPropsSize = LZMA_PROPS_SIZE;
        Byte props[kPropsSize];
        RINOK(ReadStream_FALSE(inStream, props, kPropsSize));
        RINOK(_lzmaDecoder->SetDecoderProperties2((const Byte *)props, kPropsSize));
    }

    {
        CMyComPtr<ICompressSetInStream> setInStream;
        _codecInStream.QueryInterface(IID_ICompressSetInStream, &setInStream);
        if (!setInStream)
            return E_NOTIMPL;
        RINOK(setInStream->SetInStream(inStream));
    }

    {
        CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
        _codecInStream.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize);
        if (!setOutStreamSize)
            return E_NOTIMPL;
        RINOK(setOutStreamSize->SetOutStreamSize(NULL));
    }

    if (useFilter)
    {
        RINOK(_filter->SetOutStreamSize(NULL));
    }

    return S_OK;
}
예제 #3
0
HRESULT CDecoder::Init(IInStream *inStream, NMethodType::EEnum method, bool thereIsFilterFlag, bool &useFilter)
{
    useFilter = false;
    CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;

    if (_decoderInStream)
        if (method != _method)
            Release();
    _method = method;
    if (!_codecInStream)
    {
        CMyComPtr<ICompressCoder> coder;
#ifndef EXCLUDE_COM
        const NArchive::N7z::CMethodID *methodID = 0;
        switch (method)
        {
        case NMethodType::kCopy:
            methodID = &k_Copy;
            break;
        case NMethodType::kDeflate:
            methodID = &k_Deflate;
            break;
        case NMethodType::kBZip2:
            methodID = &k_BZip2;
            break;
        case NMethodType::kLZMA:
            methodID = &k_LZMA;
            break;
        default:
            return E_NOTIMPL;
        }
        N7z::CMethodInfo methodInfo;
        if (!N7z::GetMethodInfo(*methodID, methodInfo))
            return E_NOTIMPL;
        RINOK(_libraries.CreateCoder(methodInfo.FilePath, methodInfo.Decoder, &coder));
#else
        switch(method)
        {
        case NMethodType::kCopy:
            coder = new NCompress::CCopyCoder();
            break;
        case NMethodType::kDeflate:
            coder = new NCompress::NDeflate::NDecoder::CCOMCoder();
            break;
        case NMethodType::kBZip2:
            coder = new NCompress::NBZip2::CDecoder();
            break;
        case NMethodType::kLZMA:
            new NCompress::NLZMA::CDecoder();
            break;
        default:
            return E_NOTIMPL;
        }
#endif
        coder.QueryInterface(IID_ISequentialInStream, &_codecInStream);
        if (!_codecInStream)
            return E_NOTIMPL;
    }

    if (thereIsFilterFlag)
    {
        UInt32 processedSize;
        BYTE flag;
        RINOK(inStream->Read(&flag, 1, &processedSize));
        if (processedSize != 1)
            return E_FAIL;
        if (flag > 1)
            return E_NOTIMPL;
        useFilter = (flag != 0);
    }

    if (useFilter)
    {
        if (!_filterInStream)
        {
#ifndef EXCLUDE_COM
            N7z::CMethodInfo methodInfo;
            if (!N7z::GetMethodInfo(k_BCJ_X86, methodInfo))
                return E_NOTIMPL;
            CMyComPtr<ICompressCoder> coder;
            RINOK(_libraries.CreateCoderSpec(methodInfo.FilePath, methodInfo.Decoder, &coder));
            coder.QueryInterface(IID_ISequentialInStream, &_filterInStream);
            if (!_filterInStream)
                return E_NOTIMPL;
#else
            return E_NOTIMPL;
#endif
        }
        CMyComPtr<ICompressSetInStream> setInStream;
        _filterInStream.QueryInterface(IID_ICompressSetInStream, &setInStream);
        if (!setInStream)
            return E_NOTIMPL;
        RINOK(setInStream->SetInStream(_codecInStream));
        _decoderInStream = _filterInStream;
    }
    else
        _decoderInStream = _codecInStream;

    if (method == NMethodType::kLZMA)
    {
        CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
        _codecInStream.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
        if (setDecoderProperties)
        {
            static const UInt32 kPropertiesSize = 5;
            BYTE properties[kPropertiesSize];
            UInt32 processedSize;
            RINOK(inStream->Read(properties, kPropertiesSize, &processedSize));
            if (processedSize != kPropertiesSize)
                return E_FAIL;
            RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)properties, kPropertiesSize));
        }
    }

    {
        CMyComPtr<ICompressSetInStream> setInStream;
        _codecInStream.QueryInterface(IID_ICompressSetInStream, &setInStream);
        if (!setInStream)
            return E_NOTIMPL;
        RINOK(setInStream->SetInStream(inStream));
    }

    {
        CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
        _codecInStream.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize);
        if (!setOutStreamSize)
            return E_NOTIMPL;
        RINOK(setOutStreamSize->SetOutStreamSize(NULL));
    }

    if (useFilter)
    {
        /*
        CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
        _filterInStream.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize);
        if (!setOutStreamSize)
          return E_NOTIMPL;
        RINOK(setOutStreamSize->SetOutStreamSize(NULL));
        */
    }

    return S_OK;
}