Пример #1
0
HRESULT CEncoder::Encode(
    DECL_EXTERNAL_CODECS_LOC_VARS
    ISequentialInStream *inStream,
    const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
    CFolder &folderItem,
    ISequentialOutStream *outStream,
    CRecordVector<UInt64> &packSizes,
    ICompressProgressInfo *compressProgress)
{
    RINOK(EncoderConstr());

    if (_mixerCoderSpec == NULL)
    {
        RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce));
    }
    _mixerCoderSpec->ReInit();
    // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);

    CObjectVector<CInOutTempBuffer> inOutTempBuffers;
    CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
    CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
    int numMethods = _bindInfo.Coders.Size();
    int i;
    for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
    {
        inOutTempBuffers.Add(CInOutTempBuffer());
        inOutTempBuffers.Back().Create();
        inOutTempBuffers.Back().InitWriting();
    }
    for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
    {
        CSequentialOutTempBufferImp *tempBufferSpec = new CSequentialOutTempBufferImp;
        CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
        tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
        tempBuffers.Add(tempBuffer);
        tempBufferSpecs.Add(tempBufferSpec);
    }

    for (i = 0; i < numMethods; i++)
        _mixerCoderSpec->SetCoderInfo(i, NULL, NULL);

    if (_bindInfo.InStreams.IsEmpty())
        return E_FAIL;
    UInt32 mainCoderIndex, mainStreamIndex;
    _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);

    if (inStreamSize != NULL)
    {
        CRecordVector<const UInt64 *> sizePointers;
        for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
            if (i == mainStreamIndex)
                sizePointers.Add(inStreamSize);
            else
                sizePointers.Add(NULL);
        _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);
    }


    // UInt64 outStreamStartPos;
    // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));

    CSequentialInStreamSizeCount2 *inStreamSizeCountSpec =
        new CSequentialInStreamSizeCount2;
    CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
    CSequentialOutStreamSizeCount *outStreamSizeCountSpec =
        new CSequentialOutStreamSizeCount;
    CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;

    inStreamSizeCountSpec->Init(inStream);
    outStreamSizeCountSpec->SetStream(outStream);
    outStreamSizeCountSpec->Init();

    CRecordVector<ISequentialInStream *> inStreamPointers;
    CRecordVector<ISequentialOutStream *> outStreamPointers;
    inStreamPointers.Add(inStreamSizeCount);
    outStreamPointers.Add(outStreamSizeCount);
    for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
        outStreamPointers.Add(tempBuffers[i - 1]);

    for (i = 0; i < _codersInfo.Size(); i++)
    {
        CCoderInfo &encodingInfo = _codersInfo[i];

        CMyComPtr<ICryptoResetInitVector> resetInitVector;
        _mixerCoderSpec->_coders[i].QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector);
        if (resetInitVector != NULL)
        {
            resetInitVector->ResetInitVector();
        }

        CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
        _mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
        if (writeCoderProperties != NULL)
        {
            CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
            CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
            outStreamSpec->Init();
            writeCoderProperties->WriteCoderProperties(outStream);
            size_t size = outStreamSpec->GetSize();
            encodingInfo.Props.SetCapacity(size);
            memmove(encodingInfo.Props, outStreamSpec->GetBuffer(), size);
        }
    }

    UInt32 progressIndex = mainCoderIndex;

    for (i = 0; i + 1 < _codersInfo.Size(); i++)
    {
        UInt64 m = _codersInfo[i].MethodID;
        if (m == k_Delta || m == k_BCJ || m == k_BCJ2)
            progressIndex = i + 1;
    }

    _mixerCoderSpec->SetProgressCoderIndex(progressIndex);

    RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
                            &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));

    ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods,
                                    folderItem);

    packSizes.Add(outStreamSizeCountSpec->GetSize());

    for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
    {
        CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
        RINOK(inOutTempBuffer.WriteToStream(outStream));
        packSizes.Add(inOutTempBuffer.GetDataSize());
    }

    for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
    {
        int binder = _bindInfo.FindBinderForInStream(
                         _bindReverseConverter->DestOutToSrcInMap[i]);
        UInt64 streamSize;
        if (binder < 0)
            streamSize = inStreamSizeCountSpec->GetSize();
        else
            streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
        folderItem.UnpackSizes.Add(streamSize);
    }
    for (i = numMethods - 1; i >= 0; i--)
        folderItem.Coders[numMethods - 1 - i].Props = _codersInfo[i].Props;
    return S_OK;
}
Пример #2
0
HRESULT CEncoder::Encode(ISequentialInStream *inStream,
    const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
    CFolder &folderItem,
    ISequentialOutStream *outStream,
    CRecordVector<UInt64> &packSizes,
    ICompressProgressInfo *compressProgress)
{
  if (_mixerCoderSpec == NULL)
  {
    RINOK(CreateMixerCoder(inSizeForReduce));
  }
  _mixerCoderSpec->ReInit();
  // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);

  CObjectVector<CInOutTempBuffer> inOutTempBuffers;
  CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
  CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
  int numMethods = _bindInfo.Coders.Size();
  int i;
  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
  {
    inOutTempBuffers.Add(CInOutTempBuffer());
    inOutTempBuffers.Back().Create();
    inOutTempBuffers.Back().InitWriting();
  }
  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
  {
    CSequentialOutTempBufferImp *tempBufferSpec = 
        new CSequentialOutTempBufferImp;
    CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
    tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
    tempBuffers.Add(tempBuffer);
    tempBufferSpecs.Add(tempBufferSpec);
  }

  for (i = 0; i < numMethods; i++)
    _mixerCoderSpec->SetCoderInfo(i, NULL, NULL);

  if (_bindInfo.InStreams.IsEmpty())
    return E_FAIL;
  UInt32 mainCoderIndex, mainStreamIndex;
  _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
  _mixerCoderSpec->SetProgressCoderIndex(mainCoderIndex);
  if (inStreamSize != NULL)
  {
    CRecordVector<const UInt64 *> sizePointers;
    for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
      if (i == mainStreamIndex)
        sizePointers.Add(inStreamSize);
      else
        sizePointers.Add(NULL);
    _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);
  }

  
  // UInt64 outStreamStartPos;
  // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
  
  CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = 
      new CSequentialInStreamSizeCount2;
  CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
  CSequentialOutStreamSizeCount *outStreamSizeCountSpec = 
      new CSequentialOutStreamSizeCount;
  CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;

  inStreamSizeCountSpec->Init(inStream);
  outStreamSizeCountSpec->SetStream(outStream);
  outStreamSizeCountSpec->Init();

  CRecordVector<ISequentialInStream *> inStreamPointers;
  CRecordVector<ISequentialOutStream *> outStreamPointers;
  inStreamPointers.Add(inStreamSizeCount);
  outStreamPointers.Add(outStreamSizeCount);
  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
    outStreamPointers.Add(tempBuffers[i - 1]);
  
  RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
    &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
  
  ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods,
      folderItem);
  
  packSizes.Add(outStreamSizeCountSpec->GetSize());
  
  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
  {
    CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
    inOutTempBuffer.FlushWrite();
    inOutTempBuffer.InitReading();
    inOutTempBuffer.WriteToStream(outStream);
    packSizes.Add(inOutTempBuffer.GetDataSize());
  }
  
  for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
  {
    int binder = _bindInfo.FindBinderForInStream(
        _bindReverseConverter->DestOutToSrcInMap[i]);
    UInt64 streamSize;
    if (binder < 0)
      streamSize = inStreamSizeCountSpec->GetSize();
    else
      streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
    folderItem.UnPackSizes.Add(streamSize);
  }
  for (i = numMethods - 1; i >= 0; i--)
  {
    // folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties;
    for (int j = 0; j < _codersInfo[i].AltCoders.Size(); j++)
      folderItem.Coders[numMethods - 1 - i].AltCoders[j].Properties 
          = _codersInfo[i].AltCoders[j].Properties;
  }
  return S_OK;
}