Beispiel #1
0
STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams,
      const UInt64 **inSizes,
      UInt32 numInStreams,
      ISequentialOutStream **outStreams,
      const UInt64 **outSizes,
      UInt32 numOutStreams,
      ICompressProgressInfo *progress)
{
  if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
      numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
    return E_INVALIDARG;

  // Find main coder
  int _mainCoderIndex = -1;
  int i;
  for (i = 0; i < _coders.Size(); i++)
    if (_coders[i].IsMain)
    {
      _mainCoderIndex = i;
      break;
    }
  if (_mainCoderIndex < 0)
  for (i = 0; i < _coders.Size(); i++)
    if (_coders[i].NumInStreams > 1)
    {
      if (_mainCoderIndex >= 0)
        return E_NOTIMPL;
      _mainCoderIndex = i;
    }
  if (_mainCoderIndex < 0)
    _mainCoderIndex = 0;
 
  // _mainCoderIndex = 0;
  // _mainCoderIndex = _coders.Size() - 1;
  CCoderInfo &mainCoder = _coders[_mainCoderIndex];

  CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams;
  CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams;
  UInt32 startInIndex = _bindInfo.GetCoderInStreamIndex(_mainCoderIndex);
  UInt32 startOutIndex = _bindInfo.GetCoderOutStreamIndex(_mainCoderIndex);
  for (i = 0; i < (int)mainCoder.NumInStreams; i++)
  {
    CMyComPtr<ISequentialInStream> seqInStream;
    RINOK(GetInStream(inStreams, inSizes, startInIndex + i, &seqInStream));
    seqInStreams.Add(seqInStream);
  }
  for (i = 0; i < (int)mainCoder.NumOutStreams; i++)
  {
    CMyComPtr<ISequentialOutStream> seqOutStream;
    RINOK(GetOutStream(outStreams, outSizes, startOutIndex + i, &seqOutStream));
    seqOutStreams.Add(seqOutStream);
  }
  CRecordVector< ISequentialInStream * > seqInStreamsSpec;
  CRecordVector< ISequentialOutStream * > seqOutStreamsSpec;
  for (i = 0; i < (int)mainCoder.NumInStreams; i++)
    seqInStreamsSpec.Add(seqInStreams[i]);
  for (i = 0; i < (int)mainCoder.NumOutStreams; i++)
    seqOutStreamsSpec.Add(seqOutStreams[i]);

  for (i = 0; i < _coders.Size(); i++)
  {
    if (i == _mainCoderIndex)
      continue;
    CCoderInfo &coder = _coders[i];
    CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
    coder.Coder.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize);
    if (setOutStreamSize)
    {
      RINOK(setOutStreamSize->SetOutStreamSize(coder.OutSizePointers[0]));
    }
  }
  if (mainCoder.Coder)
  {
    RINOK(mainCoder.Coder->Code(
        seqInStreamsSpec[0], seqOutStreamsSpec[0],
        mainCoder.InSizePointers[0], mainCoder.OutSizePointers[0],
        progress));
  }
  else
  {
    RINOK(mainCoder.Coder2->Code(
        &seqInStreamsSpec.Front(),
        &mainCoder.InSizePointers.Front(), mainCoder.NumInStreams,
        &seqOutStreamsSpec.Front(),
        &mainCoder.OutSizePointers.Front(), mainCoder.NumOutStreams,
        progress));
  }
  CMyComPtr<IOutStreamFlush> flush;
  seqOutStreams.Front().QueryInterface(IID_IOutStreamFlush, &flush);
  if (flush)
    return flush->Flush();
  return S_OK;
}
Beispiel #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;
}
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;
}