Beispiel #1
0
HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream,
    ICompressProgressInfo *progress)
{
  if (header.FilterID > 1)
    return E_NOTIMPL;

  {
    CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
    _lzmaDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
    if (!setDecoderProperties)
      return E_NOTIMPL;
    RINOK(setDecoderProperties->SetDecoderProperties2(header.LzmaProps, 5));
  }

  CMyComPtr<ICompressSetOutStream> setOutStream;

  bool filteredMode = (header.FilterID == 1);

  if (filteredMode)
  {
    _bcjStream.QueryInterface(IID_ICompressSetOutStream, &setOutStream);
    if (!setOutStream)
      return E_NOTIMPL;
    RINOK(setOutStream->SetOutStream(outStream));
    outStream = _bcjStream;
  }

  const UInt64 *Size = header.HasSize() ? &header.Size : NULL;
  HRESULT res = _lzmaDecoderSpec->CodeResume(outStream, Size, progress);

  if (filteredMode)
  {
    CMyComPtr<IOutStreamFlush> flush;
    _bcjStream.QueryInterface(IID_IOutStreamFlush, &flush);
    if (flush)
    {
      HRESULT res2 = flush->Flush();
      if (res == S_OK)
        res = res2;
    }
    HRESULT res2 = setOutStream->ReleaseOutStream();
    if (res == S_OK)
      res = res2;
  }
  RINOK(res);

  if (header.HasSize())
    if (_lzmaDecoderSpec->GetOutputProcessedSize() != header.Size)
      return S_FALSE;

  return S_OK;
}
STDMETHODIMP CFilterCoder::Flush()
{
  if (_bufferPos != 0)
  {
    UInt32 endPos = Filter->Filter(_buffer, _bufferPos);
    if (endPos > _bufferPos)
    {
      for (; _bufferPos < endPos; _bufferPos++)
        _buffer[_bufferPos] = 0;
      if (Filter->Filter(_buffer, endPos) != endPos)
        return E_FAIL;
    }
    RINOK(WriteStream(_outStream, _buffer, _bufferPos));
    _bufferPos = 0;
  }
  CMyComPtr<IOutStreamFlush> flush;
  _outStream.QueryInterface(IID_IOutStreamFlush, &flush);
  if (flush)
    return  flush->Flush();
  return S_OK;
}
Beispiel #3
0
STDMETHODIMP CFilterCoder::Flush()
{
  if (_bufferPos != 0)
  {
    // _buffer contains only data refused by previous Filter->Filter call.
    UInt32 endPos = Filter->Filter(_buffer, _bufferPos);
    if (endPos > _bufferPos)
    {
      for (; _bufferPos < endPos; _bufferPos++)
        _buffer[_bufferPos] = 0;
      if (Filter->Filter(_buffer, endPos) != endPos)
        return E_FAIL;
    }
    RINOK(WriteWithLimit(_outStream, _bufferPos));
    _bufferPos = 0;
  }
  CMyComPtr<IOutStreamFlush> flush;
  _outStream.QueryInterface(IID_IOutStreamFlush, &flush);
  if (flush)
    return flush->Flush();
  return S_OK;
}
Beispiel #4
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;
}