mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 15:14:59 -06:00
240 lines
6.8 KiB
C++
240 lines
6.8 KiB
C++
// CoderMixer2ST.cpp
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "CoderMixer2ST.h"
|
|
|
|
namespace NCoderMixer {
|
|
|
|
CCoderMixer2ST::CCoderMixer2ST() {}
|
|
|
|
CCoderMixer2ST::~CCoderMixer2ST(){ }
|
|
|
|
HRESULT CCoderMixer2ST::SetBindInfo(const CBindInfo &bindInfo)
|
|
{
|
|
_bindInfo = bindInfo;
|
|
return S_OK;
|
|
}
|
|
|
|
void CCoderMixer2ST::AddCoderCommon(bool isMain)
|
|
{
|
|
const CCoderStreamsInfo &csi = _bindInfo.Coders[_coders.Size()];
|
|
_coders.Add(CSTCoderInfo(csi.NumInStreams, csi.NumOutStreams, isMain));
|
|
}
|
|
|
|
void CCoderMixer2ST::AddCoder(ICompressCoder *coder, bool isMain)
|
|
{
|
|
AddCoderCommon(isMain);
|
|
_coders.Back().Coder = coder;
|
|
}
|
|
|
|
void CCoderMixer2ST::AddCoder2(ICompressCoder2 *coder, bool isMain)
|
|
{
|
|
AddCoderCommon(isMain);
|
|
_coders.Back().Coder2 = coder;
|
|
}
|
|
|
|
void CCoderMixer2ST::ReInit() { }
|
|
|
|
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);
|
|
|
|
CCoderInfo2 &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;
|
|
}
|
|
|
|
HRESULT CCoderMixer2ST::GetOutStream(
|
|
ISequentialOutStream **outStreams, const UInt64 **outSizes,
|
|
UInt32 streamIndex, ISequentialOutStream **outStreamRes)
|
|
{
|
|
CMyComPtr<ISequentialOutStream> seqOutStream;
|
|
int i;
|
|
for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
|
|
if (_bindInfo.OutStreams[i] == streamIndex)
|
|
{
|
|
seqOutStream = outStreams[i];
|
|
*outStreamRes = seqOutStream.Detach();
|
|
return S_OK;
|
|
}
|
|
int binderIndex = _bindInfo.FindBinderForOutStream(streamIndex);
|
|
if (binderIndex < 0)
|
|
return E_INVALIDARG;
|
|
|
|
UInt32 coderIndex, coderStreamIndex;
|
|
_bindInfo.FindInStream(_bindInfo.BindPairs[binderIndex].InIndex,
|
|
coderIndex, coderStreamIndex);
|
|
|
|
CCoderInfo2 &coder = _coders[coderIndex];
|
|
if (!coder.Coder)
|
|
return E_NOTIMPL;
|
|
coder.Coder.QueryInterface(IID_ISequentialOutStream, &seqOutStream);
|
|
if (!seqOutStream)
|
|
return E_NOTIMPL;
|
|
|
|
UInt32 startIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);
|
|
|
|
CMyComPtr<ICompressSetOutStream> setOutStream;
|
|
if (!coder.Coder)
|
|
return E_NOTIMPL;
|
|
coder.Coder.QueryInterface(IID_ICompressSetOutStream, &setOutStream);
|
|
if (!setOutStream)
|
|
return E_NOTIMPL;
|
|
|
|
if (coder.NumOutStreams > 1)
|
|
return E_NOTIMPL;
|
|
for (i = 0; i < (int)coder.NumOutStreams; i++)
|
|
{
|
|
CMyComPtr<ISequentialOutStream> seqOutStream2;
|
|
RINOK(GetOutStream(outStreams, outSizes, startIndex + i, &seqOutStream2));
|
|
RINOK(setOutStream->SetOutStream(seqOutStream2));
|
|
}
|
|
*outStreamRes = seqOutStream.Detach();
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
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;
|
|
CCoderInfo2 &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;
|
|
CCoderInfo2 &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;
|
|
}
|
|
|
|
/*
|
|
UInt64 CCoderMixer2ST::GetWriteProcessedSize(UInt32 binderIndex) const
|
|
{
|
|
return _streamBinders[binderIndex].ProcessedSize;
|
|
}
|
|
*/
|
|
|
|
}
|