mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-13 08:11:33 -06:00
4.20
This commit is contained in:
committed by
Kornel Lesiński
parent
8c1b5c7b7e
commit
3c510ba80b
238
7zip/Archive/Common/CoderMixer2ST.cpp
Executable file
238
7zip/Archive/Common/CoderMixer2ST.cpp
Executable file
@@ -0,0 +1,238 @@
|
||||
// CoderMixer2ST.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "CoderMixer2ST.h"
|
||||
|
||||
namespace NCoderMixer2 {
|
||||
|
||||
CCoderMixer2ST::CCoderMixer2ST() {}
|
||||
|
||||
CCoderMixer2ST::~CCoderMixer2ST(){ }
|
||||
|
||||
void CCoderMixer2ST::SetBindInfo(const CBindInfo &bindInfo)
|
||||
{
|
||||
_bindInfo = bindInfo;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
CCoderInfo &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;
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
UInt64 CCoderMixer2ST::GetWriteProcessedSize(UInt32 binderIndex) const
|
||||
{
|
||||
return _streamBinders[binderIndex].ProcessedSize;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user