diff options
Diffstat (limited to 'src/libs/7zip/win/CPP/7zip/Archive/PpmdHandler.cpp')
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/PpmdHandler.cpp | 456 |
1 files changed, 0 insertions, 456 deletions
diff --git a/src/libs/7zip/win/CPP/7zip/Archive/PpmdHandler.cpp b/src/libs/7zip/win/CPP/7zip/Archive/PpmdHandler.cpp deleted file mode 100644 index 9b2ef0482..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/PpmdHandler.cpp +++ /dev/null @@ -1,456 +0,0 @@ -/* PpmdHandler.c -- PPMd format handler -2010-03-10 : Igor Pavlov : Public domain -This code is based on: - PPMd var.H (2001) / var.I (2002): Dmitry Shkarin : Public domain - Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" -#include "../../../C/Alloc.h" -#include "../../../C/Ppmd7.h" -#include "../../../C/Ppmd8.h" - -#include "Common/ComTry.h" -#include "Common/IntToString.h" -#include "Common/StringConvert.h" - -#include "Windows/PropVariant.h" -#include "Windows/Time.h" - -#include "../Common/CWrappers.h" -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -using namespace NWindows; - -namespace NArchive { -namespace NPpmd { - -static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); } -static void SzBigFree(void *, void *address) { BigFree(address); } -static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; - -static const UInt32 kBufSize = (1 << 20); - -struct CBuf -{ - Byte *Buf; - - CBuf(): Buf(0) {} - ~CBuf() { ::MidFree(Buf); } - bool Alloc() - { - if (!Buf) - Buf = (Byte *)::MidAlloc(kBufSize); - return (Buf != 0); - } -}; - -static const UInt32 kHeaderSize = 16; -static const UInt32 kSignature = 0x84ACAF8F; -static const unsigned kNewHeaderVer = 8; - -struct CItem -{ - UInt32 Attrib; - UInt32 Time; - AString Name; - - unsigned Order; - unsigned MemInMB; - unsigned Ver; - unsigned Restor; - - HRESULT ReadHeader(ISequentialInStream *s, UInt32 &headerSize); - bool IsSupported() const { return Ver == 7 || (Ver == 8 && Restor <= 1); } -}; - -HRESULT CItem::ReadHeader(ISequentialInStream *s, UInt32 &headerSize) -{ - Byte h[kHeaderSize]; - RINOK(ReadStream_FALSE(s, h, kHeaderSize)); - if (GetUi32(h) != kSignature) - return S_FALSE; - Attrib = GetUi32(h + 4); - Time = GetUi32(h + 12); - - unsigned info = GetUi16(h + 8); - Order = (info & 0xF) + 1; - MemInMB = ((info >> 4) & 0xFF) + 1; - Ver = info >> 12; - - UInt32 nameLen = GetUi16(h + 10); - Restor = nameLen >> 14; - if (Restor > 2) - return S_FALSE; - if (Ver >= kNewHeaderVer) - nameLen &= 0x3FFF; - if (nameLen > (1 << 9)) - return S_FALSE; - char *name = Name.GetBuffer(nameLen + 1); - HRESULT res = ReadStream_FALSE(s, name, nameLen); - name[nameLen] = 0; - headerSize = kHeaderSize + nameLen; - Name.ReleaseBuffer(); - return res; -} - -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public CMyUnknownImp -{ - CItem _item; - UInt32 _headerSize; - UInt64 _packSize; - bool _packSizeDefined; - CMyComPtr<ISequentialInStream> _stream; - -public: - MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq) - INTERFACE_IInArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); -}; - -STATPROPSTG kProps[] = -{ - { NULL, kpidPath, VT_BSTR}, - { NULL, kpidMTime, VT_FILETIME}, - { NULL, kpidAttrib, VT_UI4}, - { NULL, kpidMethod, VT_BSTR} -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_NO_Table - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - switch(propID) - { - case kpidPhySize: if (_packSizeDefined) prop = _packSize; break; - } - prop.Detach(value); - return S_OK; -} - - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = 1; - return S_OK; -} - -static void UIntToString(AString &s, const char *prefix, unsigned value) -{ - s += prefix; - char temp[16]; - ::ConvertUInt32ToString((UInt32)value, temp); - s += temp; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - switch(propID) - { - case kpidPath: prop = MultiByteToUnicodeString(_item.Name, CP_ACP); break; - case kpidMTime: - { - FILETIME utc; - if (NTime::DosTimeToFileTime(_item.Time, utc)) - prop = utc; - break; - } - case kpidAttrib: prop = _item.Attrib; break; - case kpidPackSize: if (_packSizeDefined) prop = _packSize; break; - case kpidMethod: - { - AString s = "PPMd"; - s += (char)('A' + _item.Ver); - UIntToString(s, ":o", _item.Order); - UIntToString(s, ":mem", _item.MemInMB); - s += 'm'; - if (_item.Ver >= kNewHeaderVer && _item.Restor != 0) - UIntToString(s, ":r", _item.Restor); - prop = s; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *) -{ - return OpenSeq(stream); -} - -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) -{ - COM_TRY_BEGIN - HRESULT res; - try - { - Close(); - res = _item.ReadHeader(stream, _headerSize); - } - catch(...) { res = S_FALSE; } - if (res == S_OK) - _stream = stream; - else - Close(); - return res; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _packSizeDefined = false; - _stream.Release(); - return S_OK; -} - -static const UInt32 kTopValue = (1 << 24); -static const UInt32 kBot = (1 << 15); - -struct CRangeDecoder -{ - IPpmd7_RangeDec s; - UInt32 Range; - UInt32 Code; - UInt32 Low; - CByteInBufWrap *Stream; - -public: - bool Init() - { - Code = 0; - Low = 0; - Range = 0xFFFFFFFF; - for (int i = 0; i < 4; i++) - Code = (Code << 8) | Stream->ReadByte(); - return Code < 0xFFFFFFFF; - } - - void Normalize() - { - while ((Low ^ (Low + Range)) < kTopValue || - Range < kBot && ((Range = (0 - Low) & (kBot - 1)), 1)) - { - Code = (Code << 8) | Stream->ReadByte(); - Range <<= 8; - Low <<= 8; - } - } - - CRangeDecoder(); -}; - - -extern "C" { - -static UInt32 Range_GetThreshold(void *pp, UInt32 total) -{ - CRangeDecoder *p = (CRangeDecoder *)pp; - return p->Code / (p->Range /= total); -} - -static void Range_Decode(void *pp, UInt32 start, UInt32 size) -{ - CRangeDecoder *p = (CRangeDecoder *)pp; - start *= p->Range; - p->Low += start; - p->Code -= start; - p->Range *= size; - p->Normalize(); -} - -static UInt32 Range_DecodeBit(void *pp, UInt32 size0) -{ - CRangeDecoder *p = (CRangeDecoder *)pp; - if (p->Code / (p->Range >>= 14) < size0) - { - Range_Decode(p, 0, size0); - return 0; - } - else - { - Range_Decode(p, size0, (1 << 14) - size0); - return 1; - } -} - -} - -CRangeDecoder::CRangeDecoder() -{ - s.GetThreshold = Range_GetThreshold; - s.Decode = Range_Decode; - s.DecodeBit = Range_DecodeBit; -} - -struct CPpmdCpp -{ - unsigned Ver; - CRangeDecoder _rc; - CPpmd7 _ppmd7; - CPpmd8 _ppmd8; - - CPpmdCpp(unsigned version) - { - Ver = version; - Ppmd7_Construct(&_ppmd7); - Ppmd8_Construct(&_ppmd8); - } - - ~CPpmdCpp() - { - Ppmd7_Free(&_ppmd7, &g_BigAlloc); - Ppmd8_Free(&_ppmd8, &g_BigAlloc); - } - - bool Alloc(UInt32 memInMB) - { - memInMB <<= 20; - if (Ver == 7) - return Ppmd7_Alloc(&_ppmd7, memInMB, &g_BigAlloc) != 0; - return Ppmd8_Alloc(&_ppmd8, memInMB, &g_BigAlloc) != 0; - } - - void Init(unsigned order, unsigned restor) - { - if (Ver == 7) - Ppmd7_Init(&_ppmd7, order); - else - Ppmd8_Init(&_ppmd8, order, restor);; - } - - bool InitRc(CByteInBufWrap *inStream) - { - if (Ver == 7) - { - _rc.Stream = inStream; - return _rc.Init(); - } - else - { - _ppmd8.Stream.In = &inStream->p; - return Ppmd8_RangeDec_Init(&_ppmd8) != 0; - } - } - - bool IsFinishedOK() - { - if (Ver == 7) - return Ppmd7z_RangeDec_IsFinishedOK(&_rc); - return Ppmd8_RangeDec_IsFinishedOK(&_ppmd8); - } -}; - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - if (numItems == 0) - return S_OK; - if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0)) - return E_INVALIDARG; - - // extractCallback->SetTotal(_packSize); - UInt64 currentTotalPacked = 0; - RINOK(extractCallback->SetCompleted(¤tTotalPacked)); - CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); - if (!testMode && !realOutStream) - return S_OK; - - extractCallback->PrepareOperation(askMode); - - CByteInBufWrap inBuf; - if (!inBuf.Alloc(1 << 20)) - return E_OUTOFMEMORY; - inBuf.Stream = _stream; - - CBuf outBuf; - if (!outBuf.Alloc()) - return E_OUTOFMEMORY; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr<ICompressProgressInfo> progress = lps; - lps->Init(extractCallback, true); - - CPpmdCpp ppmd(_item.Ver); - if (!ppmd.Alloc(_item.MemInMB)) - return E_OUTOFMEMORY; - Int32 opRes = NExtract::NOperationResult::kUnSupportedMethod; - if (_item.IsSupported()) - { - opRes = NExtract::NOperationResult::kDataError; - ppmd.Init(_item.Order, _item.Restor); - inBuf.Init(); - UInt64 outSize = 0; - if (ppmd.InitRc(&inBuf) && !inBuf.Extra && inBuf.Res == S_OK) - for (;;) - { - lps->InSize = _packSize = inBuf.GetProcessed(); - lps->OutSize = outSize; - RINOK(lps->SetCur()); - - size_t i; - int sym = 0; - - if (ppmd.Ver == 7) - { - for (i = 0; i < kBufSize; i++) - { - sym = Ppmd7_DecodeSymbol(&ppmd._ppmd7, &ppmd._rc.s); - if (inBuf.Extra || sym < 0) - break; - outBuf.Buf[i] = (Byte)sym; - } - } - else - { - for (i = 0; i < kBufSize; i++) - { - sym = Ppmd8_DecodeSymbol(&ppmd._ppmd8); - if (inBuf.Extra || sym < 0) - break; - outBuf.Buf[i] = (Byte)sym; - } - } - - outSize += i; - _packSize = _headerSize + inBuf.GetProcessed(); - _packSizeDefined = true; - if (realOutStream) - { - RINOK(WriteStream(realOutStream, outBuf.Buf, i)); - } - if (sym < 0) - { - if (sym == -1 && ppmd.IsFinishedOK()) - opRes = NExtract::NOperationResult::kOK; - break; - } - } - RINOK(inBuf.Res); - } - realOutStream.Release(); - return extractCallback->SetOperationResult(opRes); -} - -static IInArchive *CreateArc() { return new CHandler; } - -static CArcInfo g_ArcInfo = - { L"Ppmd", L"pmd", 0, 0xD, { 0x8F, 0xAF, 0xAC, 0x84 }, 4, false, CreateArc, 0 }; - -REGISTER_ARC(Ppmd) - -}} |