diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2010-03-15 03:00:00 +0300 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:16:02 +0300 |
commit | 993daef9cbed7febf494217f07e40e0a26b3bc06 (patch) | |
tree | 41db24cb11222422aa3c4d61b80646344e3efefc /CPP | |
parent | db5eb6d638f5a5ec10517ed4a994b849a6cc7d29 (diff) |
9.119.11
Diffstat (limited to 'CPP')
48 files changed, 1973 insertions, 1642 deletions
diff --git a/CPP/7zip/Archive/Com/ComHandler.cpp b/CPP/7zip/Archive/Com/ComHandler.cpp index 39fce0ae..58f76439 100755 --- a/CPP/7zip/Archive/Com/ComHandler.cpp +++ b/CPP/7zip/Archive/Com/ComHandler.cpp @@ -44,6 +44,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { case kpidClusterSize: prop = (UInt32)1 << _db.SectorSizeBits; break; case kpidSectorSize: prop = (UInt32)1 << _db.MiniSectorSizeBits; break; + case kpidMainSubfile: if (_db.MainSubfile >= 0) prop = (UInt32)_db.MainSubfile; break; } prop.Detach(value); return S_OK; diff --git a/CPP/7zip/Archive/Com/ComIn.cpp b/CPP/7zip/Archive/Com/ComIn.cpp index 8f622122..2203ca53 100755 --- a/CPP/7zip/Archive/Com/ComIn.cpp +++ b/CPP/7zip/Archive/Com/ComIn.cpp @@ -174,8 +174,9 @@ bool CompoundMsiNameToFileName(const UString &name, UString &resultName) return true; } -static UString ConvertName(const Byte *p) +static UString ConvertName(const Byte *p, bool &isMsi) { + isMsi = false; UString s; for (int i = 0; i < kNameSizeMax; i += 2) { @@ -186,10 +187,19 @@ static UString ConvertName(const Byte *p) } UString msiName; if (CompoundMsiNameToFileName(s, msiName)) + { + isMsi = true; return msiName; + } return CompoundNameToFileName(s); } +static UString ConvertName(const Byte *p) +{ + bool isMsi; + return ConvertName(p, isMsi); +} + UString CDatabase::GetItemPath(UInt32 index) const { UString s; @@ -207,6 +217,7 @@ UString CDatabase::GetItemPath(UInt32 index) const HRESULT CDatabase::Open(IInStream *inStream) { + MainSubfile = -1; static const UInt32 kHeaderSize = 512; Byte p[kHeaderSize]; RINOK(ReadStream_FALSE(inStream, p, kHeaderSize)); @@ -353,7 +364,26 @@ HRESULT CDatabase::Open(IInStream *inStream) } } - return AddNode(-1, root.SonDid); + RINOK(AddNode(-1, root.SonDid)); + + unsigned numCabs = 0; + for (int i = 0; i < Refs.Size(); i++) + { + const CItem &item = Items[Refs[i].Did]; + if (item.IsDir() || numCabs > 1) + continue; + bool isMsiName; + UString msiName = ConvertName(item.Name, isMsiName); + if (isMsiName && msiName.Right(4).CompareNoCase(L".cab") == 0) + { + numCabs++; + MainSubfile = i; + } + } + if (numCabs > 1) + MainSubfile = -1; + + return S_OK; } }} diff --git a/CPP/7zip/Archive/Com/ComIn.h b/CPP/7zip/Archive/Com/ComIn.h index 05fc7387..429d3796 100755 --- a/CPP/7zip/Archive/Com/ComIn.h +++ b/CPP/7zip/Archive/Com/ComIn.h @@ -88,6 +88,8 @@ public: int SectorSizeBits; int MiniSectorSizeBits; + Int32 MainSubfile; + void Clear(); bool IsLargeStream(UInt64 size) const { return size >= LongStreamMinSize; } UString GetItemPath(UInt32 index) const; diff --git a/CPP/7zip/Archive/DebHandler.cpp b/CPP/7zip/Archive/DebHandler.cpp index 9f083269..b9724c2a 100755 --- a/CPP/7zip/Archive/DebHandler.cpp +++ b/CPP/7zip/Archive/DebHandler.cpp @@ -68,10 +68,10 @@ struct CItem class CInArchive { CMyComPtr<IInStream> m_Stream; - UInt64 m_Position; HRESULT GetNextItemReal(bool &filled, CItem &itemInfo); public: + UInt64 m_Position; HRESULT Open(IInStream *inStream); HRESULT GetNextItem(bool &filled, CItem &itemInfo); HRESULT SkipData(UInt64 dataSize); @@ -155,9 +155,9 @@ HRESULT CInArchive::GetNextItemReal(bool &filled, CItem &item) size_t processedSize = sizeof(header); item.HeaderPos = m_Position; RINOK(ReadStream(m_Stream, header, &processedSize)); - m_Position += processedSize; if (processedSize != sizeof(header)) return S_OK; + m_Position += processedSize; char tempString[NHeader::kNameSize + 1]; MyStrNCpy(tempString, cur, NHeader::kNameSize); @@ -212,14 +212,20 @@ class CHandler: { CObjectVector<CItem> _items; CMyComPtr<IInStream> _stream; + Int32 _mainSubfile; + UInt64 _phySize; public: MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) INTERFACE_IInArchive(;) STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); }; +static STATPROPSTG kArcProps[] = +{ + { NULL, kpidPhySize, VT_UI8} +}; -STATPROPSTG kProps[] = +static STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidSize, VT_UI8}, @@ -227,7 +233,7 @@ STATPROPSTG kProps[] = }; IMP_IInArchive_Props -IMP_IInArchive_ArcProps_NO +IMP_IInArchive_ArcProps STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, @@ -235,6 +241,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, { COM_TRY_BEGIN { + _mainSubfile = -1; CInArchive archive; if (archive.Open(stream) != S_OK) return S_FALSE; @@ -258,6 +265,8 @@ STDMETHODIMP CHandler::Open(IInStream *stream, return S_FALSE; if (!filled) break; + if (item.Name.Left(5) == "data.") + _mainSubfile = _items.Size(); _items.Add(item); archive.SkipData(item.Size); if (openArchiveCallback != NULL) @@ -267,6 +276,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, } } _stream = stream; + _phySize = archive.m_Position; } return S_OK; COM_TRY_END @@ -285,6 +295,18 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) return S_OK; } +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + NCOM::CPropVariant prop; + switch(propID) + { + case kpidPhySize: prop = _phySize; break; + case kpidMainSubfile: if (_mainSubfile >= 0) prop = (UInt32)_mainSubfile; break; + } + prop.Detach(value); + return S_OK; +} + STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN diff --git a/CPP/7zip/Archive/PeHandler.cpp b/CPP/7zip/Archive/PeHandler.cpp index fd900a58..c791d6d7 100755 --- a/CPP/7zip/Archive/PeHandler.cpp +++ b/CPP/7zip/Archive/PeHandler.cpp @@ -259,8 +259,9 @@ struct CSection // UInt16 NumRelocs; bool IsDebug; bool IsRealSect; + bool IsAdditionalSection; - CSection(): IsRealSect(false), IsDebug(false) {} + CSection(): IsRealSect(false), IsDebug(false), IsAdditionalSection(false) {} UInt64 GetPackSize() const { return PSize; } void UpdateTotalSize(UInt32 &totalSize) @@ -448,6 +449,7 @@ struct CResItem bool IsBmp() const { return Type == 2; } bool IsIcon() const { return Type == 3; } bool IsString() const { return Type == 6; } + bool IsRcData() const { return Type == 10; } }; struct CStringItem @@ -530,6 +532,7 @@ class CHandler: COptHeader _optHeader; UInt32 _totalSize; UInt32 _totalSizeLimited; + Int32 _mainSubfile; CRecordVector<CResItem> _items; CObjectVector<CStringItem> _strings; @@ -648,7 +651,7 @@ STATPROPSTG kArcProps[] = { L"Stack Commit", kpidStackCommit, VT_UI8}, { L"Heap Reserve", kpidHeapReserve, VT_UI8}, { L"Heap Commit", kpidHeapCommit, VT_UI8}, - }; +}; STATPROPSTG kProps[] = { @@ -689,7 +692,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) case kpidLinkerVer: { CVersion v = { _optHeader.LinkerVerMajor, _optHeader.LinkerVerMinor }; - VerToProp(v, prop); break; + VerToProp(v, prop); break; } @@ -716,6 +719,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) case kpidStackCommit: prop = _optHeader.StackCommit; break; case kpidHeapReserve: prop = _optHeader.HeapReserve; break; case kpidHeapCommit: prop = _optHeader.HeapCommit; break; + case kpidMainSubfile: if (_mainSubfile >= 0) prop = (UInt32)_mainSubfile; break; } prop.Detach(value); return S_OK; @@ -1240,16 +1244,26 @@ HRESULT CHandler::OpenResources(int sectionIndex, IInStream *stream, IArchiveOpe { UInt32 mask = (1 << numBits) - 1; size_t end = ((maxOffset + mask) & ~mask); - if (end < sect.VSize) + if (end < sect.VSize && end <= sect.PSize) { CSection sect2; sect2.Flags = 0; + + // we skip Zeros to start of aligned block + size_t i; + for (i = maxOffset; i < end; i++) + if (_buf[i] != 0) + break; + if (i == end) + maxOffset = end; + sect2.Pa = sect.Pa + (UInt32)maxOffset; sect2.Va = sect.Va + (UInt32)maxOffset; sect2.PSize = sect.VSize - (UInt32)maxOffset; sect2.VSize = sect2.PSize; sect2.Name = ".rsrc_1"; sect2.Time = 0; + sect2.IsAdditionalSection = true; _sections.Add(sect2); } } @@ -1262,6 +1276,8 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) const UInt32 kBufSize = 1 << 18; const UInt32 kSigSize = 2; + _mainSubfile = -1; + CByteBuffer buffer; buffer.SetCapacity(kBufSize); Byte *buf = buffer; @@ -1358,6 +1374,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) CSection s2; s2.Pa = s2.Va = limit; s2.PSize = s2.VSize = s.Pa - limit; + s2.IsAdditionalSection = true; s2.Name = '['; s2.Name += GetDecString(num++); s2.Name += ']'; @@ -1374,6 +1391,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) _parseResources = true; + UInt64 mainSize = 0, mainSize2 = 0; for (int i = 0; i < _sections.Size(); i++) { const CSection § = _sections[i]; @@ -1386,12 +1404,26 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) { _resourceFileName = GetUnicodeString(sect.Name); for (int j = 0; j < _items.Size(); j++) - if (_items[j].Enabled) + { + const CResItem &item = _items[j]; + if (item.Enabled) { mixItem.ResourceIndex = j; mixItem.StringIndex = -1; + if (item.IsRcData()) + { + if (item.Size >= mainSize) + { + mainSize2 = mainSize; + mainSize = item.Size; + _mainSubfile = _mixItems.Size(); + } + else if (item.Size >= mainSize2) + mainSize2 = item.Size; + } _mixItems.Add(mixItem); } + } if (sect.PSize > sect.VSize) { int numBits = _optHeader.GetNumFileAlignBits(); @@ -1410,6 +1442,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) sect2.VSize = sect2.PSize; sect2.Name = ".rsrc_2"; sect2.Time = 0; + sect2.IsAdditionalSection = true; _sections.Add(sect2); } } @@ -1422,8 +1455,21 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) } mixItem.StringIndex = -1; mixItem.ResourceIndex = -1; + if (sect.IsAdditionalSection) + { + if (sect.PSize >= mainSize) + { + mainSize2 = mainSize; + mainSize = sect.PSize; + _mainSubfile = _mixItems.Size(); + } + else + mainSize2 = sect.PSize; + } _mixItems.Add(mixItem); } + if (mainSize2 >= (1 << 20) && mainSize < mainSize2 * 2) + _mainSubfile = -1; return S_OK; } diff --git a/CPP/7zip/Archive/PpmdHandler.cpp b/CPP/7zip/Archive/PpmdHandler.cpp new file mode 100755 index 00000000..9b2ef048 --- /dev/null +++ b/CPP/7zip/Archive/PpmdHandler.cpp @@ -0,0 +1,456 @@ +/* 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) + +}} diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp index 0a74a3d1..7fed3cab 100755 --- a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp +++ b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp @@ -15,6 +15,7 @@ #include "../../Common/StreamUtils.h" #include "../../Compress/LzmaEncoder.h" +#include "../../Compress/PpmdZip.h" #include "../Common/InStreamWithCRC.h" @@ -169,13 +170,14 @@ HRESULT CAddCommon::Compress( else { if (!_cryptoStreamSpec->Filter) + { _cryptoStreamSpec->Filter = _filterSpec = new NCrypto::NZip::CEncoder; - RINOK(_filterSpec->CryptoSetPassword((const Byte *)(const char *)_options.Password, _options.Password.Length())); + _filterSpec->CryptoSetPassword((const Byte *)(const char *)_options.Password, _options.Password.Length()); + } UInt32 crc = 0; RINOK(GetStreamCRC(inStream, crc)); RINOK(inCrcStreamSpec->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(_filterSpec->CryptoSetCRC(crc)); - RINOK(_filterSpec->WriteHeader(outStream)); + RINOK(_filterSpec->WriteHeader(outStream, crc)); } RINOK(_cryptoStreamSpec->SetOutStream(outStream)); outStreamReleaser.FilterCoder = _cryptoStreamSpec; @@ -235,6 +237,26 @@ HRESULT CAddCommon::Compress( numProps--; RINOK(_lzmaEncoder->SetCoderProperties(propIDs, props, numProps)); } + else if (method == NFileHeader::NCompressionMethod::kPPMd) + { + _compressExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_PPMd; + NCompress::NPpmdZip::CEncoder *encoder = new NCompress::NPpmdZip::CEncoder(); + _compressEncoder = encoder; + NWindows::NCOM::CPropVariant props[] = + { + // _options.Algo, + _options.MemSize, + _options.Order + + }; + PROPID propIDs[] = + { + // NCoderPropID::kAlgorithm, + NCoderPropID::kUsedMemorySize, + NCoderPropID::kOrder + }; + RINOK(encoder->SetCoderProperties(propIDs, props, sizeof(propIDs) / sizeof(propIDs[0]))); + } else { CMethodId methodId; diff --git a/CPP/7zip/Archive/Zip/ZipCompressionMode.h b/CPP/7zip/Archive/Zip/ZipCompressionMode.h index e5acfa6b..7ef7cfb2 100755 --- a/CPP/7zip/Archive/Zip/ZipCompressionMode.h +++ b/CPP/7zip/Archive/Zip/ZipCompressionMode.h @@ -18,6 +18,9 @@ struct CCompressionMethodMode bool NumMatchFinderCyclesDefined; UInt32 NumMatchFinderCycles; UInt32 DicSize; + UInt32 MemSize; + UInt32 Order; + #ifndef _7ZIP_ST UInt32 NumThreads; #endif diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp index df1ca20b..64477766 100755 --- a/CPP/7zip/Archive/Zip/ZipHandler.cpp +++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp @@ -18,6 +18,7 @@ #include "../../Compress/CopyCoder.h" #include "../../Compress/LzmaDecoder.h" #include "../../Compress/ImplodeDecoder.h" +#include "../../Compress/PpmdZip.h" #include "../../Compress/ShrinkDecoder.h" #include "../../Crypto/WzAes.h" @@ -595,6 +596,8 @@ HRESULT CZipDecoder::Decode( mi.Coder = new NCompress::NImplode::NDecoder::CCoder; else if (methodId == NFileHeader::NCompressionMethod::kLZMA) mi.Coder = new CLzmaDecoder; + else if (methodId == NFileHeader::NCompressionMethod::kPPMd) + mi.Coder = new NCompress::NPpmdZip::CDecoder(true); else { CMethodId szMethodID; diff --git a/CPP/7zip/Archive/Zip/ZipHandler.h b/CPP/7zip/Archive/Zip/ZipHandler.h index 6236b20c..55ebff25 100755 --- a/CPP/7zip/Archive/Zip/ZipHandler.h +++ b/CPP/7zip/Archive/Zip/ZipHandler.h @@ -53,6 +53,9 @@ private: UInt32 m_NumPasses; UInt32 m_NumFastBytes; UInt32 m_NumMatchFinderCycles; + UInt32 m_MemSize; + UInt32 m_Order; + bool m_NumMatchFinderCyclesDefined; bool m_ForceAesMode; @@ -77,6 +80,8 @@ private: m_DicSize = m_NumPasses = m_NumFastBytes = + m_Order = + m_MemSize = m_NumMatchFinderCycles = 0xFFFFFFFF; m_NumMatchFinderCyclesDefined = false; m_ForceAesMode = false; diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp index 3571fdeb..b190dd2f 100755 --- a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp +++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp @@ -51,6 +51,18 @@ static const UInt32 kLzmaDicSizeX5 = 1 << 24; static const UInt32 kLzmaDicSizeX7 = 1 << 25; static const UInt32 kLzmaDicSizeX9 = 1 << 26; +static const UInt32 kPpmdMemSizeX1 = (1 << 20); +static const UInt32 kPpmdMemSizeX3 = (1 << 22); +static const UInt32 kPpmdMemSizeX5 = (1 << 24); +static const UInt32 kPpmdMemSizeX7 = (1 << 26); +static const UInt32 kPpmdMemSizeX9 = (1 << 27); + +static const UInt32 kPpmdOrderX1 = 4; +static const UInt32 kPpmdOrderX3 = 6; +static const UInt32 kPpmdOrderX5 = 8; +static const UInt32 kPpmdOrderX7 = 10; +static const UInt32 kPpmdOrderX9 = 16; + static const UInt32 kBZip2NumPassesX1 = 1; static const UInt32 kBZip2NumPassesX7 = 2; static const UInt32 kBZip2NumPassesX9 = 7; @@ -290,13 +302,14 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt (mainMethod == NFileHeader::NCompressionMethod::kDeflated64); bool isLZMA = (mainMethod == NFileHeader::NCompressionMethod::kLZMA); bool isLz = (isLZMA || isDeflate); - bool isBZip2 = (mainMethod == NFileHeader::NCompressionMethod::kBZip2); options.NumPasses = m_NumPasses; options.DicSize = m_DicSize; options.NumFastBytes = m_NumFastBytes; options.NumMatchFinderCycles = m_NumMatchFinderCycles; options.NumMatchFinderCyclesDefined = m_NumMatchFinderCyclesDefined; options.Algo = m_Algo; + options.MemSize = m_MemSize; + options.Order = m_Order; #ifndef _7ZIP_ST options.NumThreads = _numThreads; #endif @@ -336,7 +349,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt options.Algo = (level >= 5 ? kLzAlgoX5 : kLzAlgoX1); } - if (isBZip2) + if (mainMethod == NFileHeader::NCompressionMethod::kBZip2) { if (options.NumPasses == 0xFFFFFFFF) options.NumPasses = (level >= 9 ? kBZip2NumPassesX9 : @@ -347,6 +360,26 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt (level >= 3 ? kBZip2DicSizeX3 : kBZip2DicSizeX1)); } + if (mainMethod == NFileHeader::NCompressionMethod::kPPMd) + { + if (options.MemSize == 0xFFFFFFFF) + options.MemSize = + (level >= 9 ? kPpmdMemSizeX9 : + (level >= 7 ? kPpmdMemSizeX7 : + (level >= 5 ? kPpmdMemSizeX5 : + (level >= 3 ? kPpmdMemSizeX3 : + kPpmdMemSizeX1)))); + + if (options.Order == 0xFFFFFFFF) + options.Order = + (level >= 9 ? kPpmdOrderX9 : + (level >= 7 ? kPpmdOrderX7 : + (level >= 5 ? kPpmdOrderX5 : + (level >= 3 ? kPpmdOrderX3 : + kPpmdOrderX1)))); + + options.Algo = 0; + } return Update( EXTERNAL_CODECS_VARS @@ -389,6 +422,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v else if (m == L"DEFLATE64") m_MainMethod = NFileHeader::NCompressionMethod::kDeflated64; else if (m == L"BZIP2") m_MainMethod = NFileHeader::NCompressionMethod::kBZip2; else if (m == L"LZMA") m_MainMethod = NFileHeader::NCompressionMethod::kLZMA; + else if (m == L"PPMD") m_MainMethod = NFileHeader::NCompressionMethod::kPPMd; else return E_INVALIDARG; } else if (prop.vt == VT_UI4) @@ -446,6 +480,18 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v RINOK(ParsePropDictionaryValue(name.Mid(1), prop, dicSize)); m_DicSize = dicSize; } + else if (name.Left(3) == L"MEM") + { + UInt32 memSize = kPpmdMemSizeX5; + RINOK(ParsePropDictionaryValue(name.Mid(3), prop, memSize)); + m_MemSize = memSize; + } + else if (name[0] == L'O') + { + UInt32 order = kPpmdOrderX5; + RINOK(ParsePropValue(name.Mid(1), prop, order)); + m_Order = order; + } else if (name.Left(4) == L"PASS") { UInt32 num = kDeflateNumPassesX9; diff --git a/CPP/7zip/Archive/Zip/ZipHeader.h b/CPP/7zip/Archive/Zip/ZipHeader.h index 1233af6c..eeff5980 100755 --- a/CPP/7zip/Archive/Zip/ZipHeader.h +++ b/CPP/7zip/Archive/Zip/ZipHeader.h @@ -89,6 +89,7 @@ namespace NFileHeader const Byte kExtractVersion_BZip2 = 46; const Byte kExtractVersion_Aes = 51; const Byte kExtractVersion_LZMA = 63; + const Byte kExtractVersion_PPMd = 63; // const Byte kSupportedVersion = 20; } diff --git a/CPP/7zip/Bundles/Alone/Alone.dsp b/CPP/7zip/Bundles/Alone/Alone.dsp index 4f57cba9..e6328f7e 100755 --- a/CPP/7zip/Bundles/Alone/Alone.dsp +++ b/CPP/7zip/Bundles/Alone/Alone.dsp @@ -148,6 +148,14 @@ SOURCE=..\..\UI\Console\ArError.h # End Source File # Begin Source File +SOURCE=..\..\UI\Console\BenchCon.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\BenchCon.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Console\CompressionMode.h # End Source File # Begin Source File @@ -176,14 +184,6 @@ SOURCE=..\..\UI\Console\List.h # End Source File # Begin Source File -SOURCE=..\..\UI\Console\BenchCon.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\UI\Console\BenchCon.h -# End Source File -# Begin Source File - SOURCE=..\..\UI\Console\Main.cpp # End Source File # Begin Source File @@ -1018,6 +1018,14 @@ SOURCE=..\..\Compress\PpmdSubAlloc.h SOURCE=..\..\Compress\PpmdType.h # End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdZip.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdZip.h +# End Source File # End Group # Begin Group "RangeCoder" @@ -1637,6 +1645,14 @@ SOURCE=..\..\UI\Common\ArchiveOpenCallback.h # End Source File # Begin Source File +SOURCE=..\..\UI\Common\Bench.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Bench.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\DefaultName.cpp # End Source File # Begin Source File @@ -1677,14 +1693,6 @@ SOURCE=..\..\UI\Common\LoadCodecs.h # End Source File # Begin Source File -SOURCE=..\..\UI\Common\Bench.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\UI\Common\Bench.h -# End Source File -# Begin Source File - SOURCE=..\..\UI\Common\OpenArchive.cpp # End Source File # Begin Source File @@ -2669,6 +2677,162 @@ SOURCE=..\..\..\..\C\MtCoder.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Ppmd.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7Dec.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7Enc.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd8.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd8.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd8Dec.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd8Enc.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\RotateDefs.h # End Source File # Begin Source File diff --git a/CPP/7zip/Bundles/Alone/makefile b/CPP/7zip/Bundles/Alone/makefile index ef6a33cb..9dd02872 100755 --- a/CPP/7zip/Bundles/Alone/makefile +++ b/CPP/7zip/Bundles/Alone/makefile @@ -97,6 +97,7 @@ AR_OBJS = \ $O\DeflateProps.obj \ $O\GzHandler.obj \ $O\LzmaHandler.obj \ + $O\PpmdHandler.obj \ $O\SplitHandler.obj \ $O\XzHandler.obj \ $O\ZHandler.obj \ @@ -195,6 +196,7 @@ COMPRESS_OBJS = \ $O\PpmdDecoder.obj \ $O\PpmdEncoder.obj \ $O\PpmdRegister.obj \ + $O\PpmdZip.obj \ $O\QuantumDecoder.obj \ $O\ShrinkDecoder.obj \ $O\ZDecoder.obj \ @@ -228,6 +230,12 @@ C_OBJS = \ $O\LzmaDec.obj \ $O\LzmaEnc.obj \ $O\MtCoder.obj \ + $O\Ppmd7.obj \ + $O\Ppmd7Dec.obj \ + $O\Ppmd7Enc.obj \ + $O\Ppmd8.obj \ + $O\Ppmd8Dec.obj \ + $O\Ppmd8Enc.obj \ $O\Sha256.obj \ $O\Sort.obj \ $O\Threads.obj \ diff --git a/CPP/7zip/Bundles/Fm/makefile b/CPP/7zip/Bundles/Fm/makefile index 3cd64c20..7068206c 100755 --- a/CPP/7zip/Bundles/Fm/makefile +++ b/CPP/7zip/Bundles/Fm/makefile @@ -176,6 +176,7 @@ AR_OBJS = \ $O\MubHandler.obj \ $O\NtfsHandler.obj \ $O\PeHandler.obj \ + $O\PpmdHandler.obj \ $O\RpmHandler.obj \ $O\SplitHandler.obj \ $O\SwfHandler.obj \ @@ -375,6 +376,7 @@ COMPRESS_OBJS = \ $O\PpmdDecoder.obj \ $O\PpmdEncoder.obj \ $O\PpmdRegister.obj \ + $O\PpmdZip.obj \ $O\QuantumDecoder.obj \ $O\Rar1Decoder.obj \ $O\Rar2Decoder.obj \ @@ -419,6 +421,12 @@ C_OBJS = \ $O\LzmaDec.obj \ $O\LzmaEnc.obj \ $O\MtCoder.obj \ + $O\Ppmd7.obj \ + $O\Ppmd7Dec.obj \ + $O\Ppmd7Enc.obj \ + $O\Ppmd8.obj \ + $O\Ppmd8Dec.obj \ + $O\Ppmd8Enc.obj \ $O\Sha256.obj \ $O\Sort.obj \ $O\Threads.obj \ diff --git a/CPP/7zip/Bundles/Format7z/makefile b/CPP/7zip/Bundles/Format7z/makefile index 3a091e22..d3609f7b 100755 --- a/CPP/7zip/Bundles/Format7z/makefile +++ b/CPP/7zip/Bundles/Format7z/makefile @@ -112,7 +112,6 @@ CRYPTO_OBJS = \ $O\Sha1.obj \ C_OBJS = \ - $O\Aes.obj \ $O\Alloc.obj \ $O\Bra.obj \ $O\Bra86.obj \ @@ -128,6 +127,9 @@ C_OBJS = \ $O\LzmaDec.obj \ $O\LzmaEnc.obj \ $O\MtCoder.obj \ + $O\Ppmd7.obj \ + $O\Ppmd7Dec.obj \ + $O\Ppmd7Enc.obj \ $O\Sha256.obj \ $O\Sort.obj \ $O\Threads.obj \ diff --git a/CPP/7zip/Bundles/Format7zExtract/makefile b/CPP/7zip/Bundles/Format7zExtract/makefile index 6769be45..fb76cbc0 100755 --- a/CPP/7zip/Bundles/Format7zExtract/makefile +++ b/CPP/7zip/Bundles/Format7zExtract/makefile @@ -98,6 +98,8 @@ C_OBJS = \ $O\Delta.obj \ $O\Lzma2Dec.obj \ $O\LzmaDec.obj \ + $O\Ppmd7.obj \ + $O\Ppmd7Dec.obj \ $O\Sha256.obj \ $O\Threads.obj \ diff --git a/CPP/7zip/Bundles/Format7zF/Format7z.dsp b/CPP/7zip/Bundles/Format7zF/Format7z.dsp index fd992ae0..4be37b86 100755 --- a/CPP/7zip/Bundles/Format7zF/Format7z.dsp +++ b/CPP/7zip/Bundles/Format7zF/Format7z.dsp @@ -349,27 +349,35 @@ SOURCE=..\..\..\Common\Wildcard.h # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Compress\PpmdContext.h -# End Source File -# Begin Source File +SOURCE=..\..\Compress\PpmdDecoder.cpp -SOURCE=..\..\Compress\PpmdDecode.h -# End Source File -# Begin Source File +!IF "$(CFG)" == "7z - Win32 Release" -SOURCE=..\..\Compress\PpmdDecoder.cpp -# End Source File -# Begin Source File +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF -SOURCE=..\..\Compress\PpmdDecoder.h # End Source File # Begin Source File -SOURCE=..\..\Compress\PpmdEncode.h +SOURCE=..\..\Compress\PpmdDecoder.h # End Source File # Begin Source File SOURCE=..\..\Compress\PpmdEncoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + # End Source File # Begin Source File @@ -434,6 +442,16 @@ SOURCE=..\..\Compress\Rar2Decoder.h # Begin Source File SOURCE=..\..\Compress\Rar3Decoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + # End Source File # Begin Source File @@ -545,6 +563,14 @@ SOURCE=..\..\Compress\ImplodeHuffmanDecoder.h # End Source File # Begin Source File +SOURCE=..\..\Compress\PpmdZip.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdZip.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\ShrinkDecoder.cpp # End Source File # Begin Source File @@ -1487,6 +1513,114 @@ SOURCE=..\..\..\..\C\MtCoder.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Ppmd.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7Dec.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7Enc.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd8.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd8.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd8Dec.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd8Enc.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\RotateDefs.h # End Source File # Begin Source File @@ -2264,6 +2398,20 @@ SOURCE=..\..\Archive\PeHandler.cpp # End Source File # Begin Source File +SOURCE=..\..\Archive\PpmdHandler.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=..\..\Archive\RpmHandler.cpp # End Source File # Begin Source File diff --git a/CPP/7zip/Bundles/Format7zF/makefile b/CPP/7zip/Bundles/Format7zF/makefile index fe0791a5..b72468c0 100755 --- a/CPP/7zip/Bundles/Format7zF/makefile +++ b/CPP/7zip/Bundles/Format7zF/makefile @@ -73,6 +73,7 @@ AR_OBJS = \ $O\MubHandler.obj \ $O\NtfsHandler.obj \ $O\PeHandler.obj \ + $O\PpmdHandler.obj \ $O\RpmHandler.obj \ $O\SplitHandler.obj \ $O\SwfHandler.obj \ @@ -226,6 +227,7 @@ COMPRESS_OBJS = \ $O\PpmdDecoder.obj \ $O\PpmdEncoder.obj \ $O\PpmdRegister.obj \ + $O\PpmdZip.obj \ $O\QuantumDecoder.obj \ $O\Rar1Decoder.obj \ $O\Rar2Decoder.obj \ @@ -270,6 +272,12 @@ C_OBJS = \ $O\LzmaDec.obj \ $O\LzmaEnc.obj \ $O\MtCoder.obj \ + $O\Ppmd7.obj \ + $O\Ppmd7Dec.obj \ + $O\Ppmd7Enc.obj \ + $O\Ppmd8.obj \ + $O\Ppmd8Dec.obj \ + $O\Ppmd8Enc.obj \ $O\Sha256.obj \ $O\Sort.obj \ $O\Threads.obj \ diff --git a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp index 6c624f8d..e355d6e1 100755 --- a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp +++ b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp @@ -513,6 +513,14 @@ SOURCE=..\..\Common\CreateCoder.h # End Source File # Begin Source File +SOURCE=..\..\Common\CWrappers.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\FilePathAutoRename.cpp # End Source File # Begin Source File @@ -770,6 +778,20 @@ SOURCE=..\..\..\..\C\LzmaDec.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Ppmd7.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7Dec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Sha256.c # SUBTRACT CPP /YX /Yc /Yu # End Source File diff --git a/CPP/7zip/Bundles/SFXCon/makefile b/CPP/7zip/Bundles/SFXCon/makefile index f465db5a..c92236bf 100755 --- a/CPP/7zip/Bundles/SFXCon/makefile +++ b/CPP/7zip/Bundles/SFXCon/makefile @@ -42,6 +42,7 @@ WIN_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\CreateCoder.obj \ + $O\CWrappers.obj \ $O\FilePathAutoRename.obj \ $O\FileStreams.obj \ $O\InBuffer.obj \ @@ -108,6 +109,8 @@ C_OBJS = \ $O\CpuArch.obj \ $O\Lzma2Dec.obj \ $O\LzmaDec.obj \ + $O\Ppmd7.obj \ + $O\Ppmd7Dec.obj \ $O\Sha256.obj \ $O\Threads.obj \ diff --git a/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp index 53b59569..68fe84d6 100755 --- a/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp +++ b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp @@ -273,6 +273,18 @@ SOURCE=..\..\Compress\CopyRegister.cpp # End Source File # Begin Source File +SOURCE=..\..\Compress\Lzma2Decoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Decoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Register.cpp +# End Source File +# Begin Source File + SOURCE=..\..\Compress\LzmaDecoder.cpp # End Source File # Begin Source File @@ -682,6 +694,15 @@ SOURCE=..\..\..\..\C\CpuArch.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Lzma2Dec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Dec.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\LzmaDec.c # SUBTRACT CPP /YX /Yc /Yu # End Source File diff --git a/CPP/7zip/Bundles/SFXSetup/makefile b/CPP/7zip/Bundles/SFXSetup/makefile index b2b892dc..9136e432 100755 --- a/CPP/7zip/Bundles/SFXSetup/makefile +++ b/CPP/7zip/Bundles/SFXSetup/makefile @@ -86,6 +86,8 @@ COMPRESS_OBJS = \ $O\BcjRegister.obj \ $O\CopyCoder.obj \ $O\CopyRegister.obj \ + $O\Lzma2Decoder.obj \ + $O\Lzma2Register.obj \ $O\LzmaDecoder.obj \ $O\LzmaRegister.obj \ @@ -93,6 +95,7 @@ C_OBJS = \ $O\Alloc.obj \ $O\Bra86.obj \ $O\CpuArch.obj \ + $O\Lzma2Dec.obj \ $O\LzmaDec.obj \ $O\Threads.obj \ diff --git a/CPP/7zip/Bundles/SFXWin/SFXWin.dsp b/CPP/7zip/Bundles/SFXWin/SFXWin.dsp index b4dedf32..9cd7e8d2 100755 --- a/CPP/7zip/Bundles/SFXWin/SFXWin.dsp +++ b/CPP/7zip/Bundles/SFXWin/SFXWin.dsp @@ -357,6 +357,14 @@ SOURCE=..\..\Common\CreateCoder.h # End Source File # Begin Source File +SOURCE=..\..\Common\CWrappers.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\FilePathAutoRename.cpp # End Source File # Begin Source File @@ -830,6 +838,20 @@ SOURCE=..\..\..\..\C\LzmaDec.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Ppmd7.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7Dec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Sha256.c # SUBTRACT CPP /YX /Yc /Yu # End Source File diff --git a/CPP/7zip/Bundles/SFXWin/makefile b/CPP/7zip/Bundles/SFXWin/makefile index 94793df3..458ac665 100755 --- a/CPP/7zip/Bundles/SFXWin/makefile +++ b/CPP/7zip/Bundles/SFXWin/makefile @@ -48,6 +48,7 @@ WIN_CTRL_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\CreateCoder.obj \ + $O\CWrappers.obj \ $O\FilePathAutoRename.obj \ $O\FileStreams.obj \ $O\InBuffer.obj \ @@ -125,6 +126,8 @@ C_OBJS = \ $O\CpuArch.obj \ $O\Lzma2Dec.obj \ $O\LzmaDec.obj \ + $O\Ppmd7.obj \ + $O\Ppmd7Dec.obj \ $O\Sha256.obj \ $O\Threads.obj \ diff --git a/CPP/7zip/Common/CWrappers.cpp b/CPP/7zip/Common/CWrappers.cpp index d440027d..41537e97 100755 --- a/CPP/7zip/Common/CWrappers.cpp +++ b/CPP/7zip/Common/CWrappers.cpp @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include "../../../C/Alloc.h" + #include "CWrappers.h" #include "StreamUtils.h" @@ -125,3 +127,100 @@ CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream) p.Seek = InStreamWrap_Seek; Res = S_OK; } + + +/* ---------- CByteInBufWrap ---------- */ + +void CByteInBufWrap::Free() +{ + ::MidFree(Buf); + Buf = 0; +} + +bool CByteInBufWrap::Alloc(UInt32 size) +{ + if (Buf == 0 || size != Size) + { + Free(); + Lim = Cur = Buf = (Byte *)::MidAlloc((size_t)size); + Size = size; + } + return (Buf != 0); +} + +Byte CByteInBufWrap::ReadByteFromNewBlock() +{ + if (Res == S_OK) + { + UInt32 avail; + Processed += (Cur - Buf); + Res = Stream->Read(Buf, Size, &avail); + Cur = Buf; + Lim = Buf + avail; + if (avail != 0) + return *Cur++; + } + Extra = true; + return 0; +} + +extern "C" static Byte Wrap_ReadByte(void *pp) +{ + CByteInBufWrap *p = (CByteInBufWrap *)pp; + if (p->Cur != p->Lim) + return *p->Cur++; + return p->ReadByteFromNewBlock(); +} + +CByteInBufWrap::CByteInBufWrap(): Buf(0) +{ + p.Read = Wrap_ReadByte; +} + + +/* ---------- CByteOutBufWrap ---------- */ + +void CByteOutBufWrap::Free() +{ + ::MidFree(Buf); + Buf = 0; +} + +bool CByteOutBufWrap::Alloc(size_t size) +{ + if (Buf == 0 || size != Size) + { + Free(); + Buf = (Byte *)::MidAlloc(size); + Size = size; + } + return (Buf != 0); +} + +HRESULT CByteOutBufWrap::Flush() +{ + if (Res == S_OK) + { + size_t size = (Cur - Buf); + Res = WriteStream(Stream, Buf, size); + if (Res == S_OK) + Processed += size; + Cur = Buf; + } + return Res; +} + +extern "C" static void Wrap_WriteByte(void *pp, Byte b) +{ + CByteOutBufWrap *p = (CByteOutBufWrap *)pp; + Byte *dest = p->Cur; + *dest = b; + p->Cur = ++dest; + if (dest == p->Lim) + p->Flush(); +} + +CByteOutBufWrap::CByteOutBufWrap(): Buf(0) +{ + p.Write = Wrap_WriteByte; +} diff --git a/CPP/7zip/Common/CWrappers.h b/CPP/7zip/Common/CWrappers.h index f7ac96cb..80a8a1b6 100755 --- a/CPP/7zip/Common/CWrappers.h +++ b/CPP/7zip/Common/CWrappers.h @@ -3,8 +3,6 @@ #ifndef __C_WRAPPERS_H #define __C_WRAPPERS_H -#include "../../../C/Types.h" - #include "../ICoder.h" #include "../../Common/MyCom.h" @@ -43,4 +41,69 @@ struct CSeqOutStreamWrap HRESULT SResToHRESULT(SRes res); +struct CByteInBufWrap +{ + IByteIn p; + const Byte *Cur; + const Byte *Lim; + Byte *Buf; + UInt32 Size; + ISequentialInStream *Stream; + UInt64 Processed; + bool Extra; + HRESULT Res; + + CByteInBufWrap(); + ~CByteInBufWrap() { Free(); } + void Free(); + bool Alloc(UInt32 size); + void Init() + { + Lim = Cur = Buf; + Processed = 0; + Extra = false; + Res = S_OK; + } + UInt64 GetProcessed() const { return Processed + (Cur - Buf); } + Byte ReadByteFromNewBlock(); + Byte ReadByte() + { + if (Cur != Lim) + return *Cur++; + return ReadByteFromNewBlock(); + } +}; + +struct CByteOutBufWrap +{ + IByteOut p; + Byte *Cur; + const Byte *Lim; + Byte *Buf; + size_t Size; + ISequentialOutStream *Stream; + UInt64 Processed; + HRESULT Res; + + CByteOutBufWrap(); + ~CByteOutBufWrap() { Free(); } + void Free(); + bool Alloc(size_t size); + void Init() + { + Cur = Buf; + Lim = Buf + Size; + Processed = 0; + Res = S_OK; + } + UInt64 GetProcessed() const { return Processed + (Cur - Buf); } + HRESULT Flush(); + void WriteByte(Byte b) + { + *Cur++ = b; + if (Cur == Lim) + Flush(); + } +}; + #endif diff --git a/CPP/7zip/Compress/PpmdContext.h b/CPP/7zip/Compress/PpmdContext.h deleted file mode 100755 index cfff53ed..00000000 --- a/CPP/7zip/Compress/PpmdContext.h +++ /dev/null @@ -1,490 +0,0 @@ -// PpmdContext.h -// 2009-05-30 : Igor Pavlov : Public domain -// This code is based on Dmitry Shkarin's PPMdH code (public domain) - -#ifndef __COMPRESS_PPMD_CONTEXT_H -#define __COMPRESS_PPMD_CONTEXT_H - -#include "../../Common/Types.h" - -#include "PpmdSubAlloc.h" -#include "RangeCoder.h" - -namespace NCompress { -namespace NPpmd { - -const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS, - INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124; - -struct SEE2_CONTEXT -{ - // SEE-contexts for PPM-contexts with masked symbols - UInt16 Summ; - Byte Shift, Count; - void init(int InitVal) { Summ = (UInt16)(InitVal << (Shift=PERIOD_BITS-4)); Count=4; } - unsigned int getMean() - { - unsigned int RetVal=(Summ >> Shift); - Summ = (UInt16)(Summ - RetVal); - return RetVal+(RetVal == 0); - } - void update() - { - if (Shift < PERIOD_BITS && --Count == 0) - { - Summ <<= 1; - Count = (Byte)(3 << Shift++); - } - } -}; - -struct PPM_CONTEXT -{ - UInt16 NumStats; // sizeof(UInt16) > sizeof(Byte) - UInt16 SummFreq; - - struct STATE - { - Byte Symbol, Freq; - UInt16 SuccessorLow; - UInt16 SuccessorHigh; - - UInt32 GetSuccessor() const { return SuccessorLow | ((UInt32)SuccessorHigh << 16); } - void SetSuccessor(UInt32 v) - { - SuccessorLow = (UInt16)(v & 0xFFFF); - SuccessorHigh = (UInt16)((v >> 16) & 0xFFFF); - } - }; - - UInt32 Stats; - UInt32 Suffix; - - PPM_CONTEXT* createChild(CSubAllocator &subAllocator, STATE* pStats, STATE& FirstState) - { - PPM_CONTEXT* pc = (PPM_CONTEXT*) subAllocator.AllocContext(); - if (pc) - { - pc->NumStats = 1; - pc->oneState() = FirstState; - pc->Suffix = subAllocator.GetOffset(this); - pStats->SetSuccessor(subAllocator.GetOffsetNoCheck(pc)); - } - return pc; - } - - STATE& oneState() const { return (STATE&) SummFreq; } -}; - -///////////////////////////////// - -const UInt16 InitBinEsc[] = - {0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; - -struct CInfo -{ - CSubAllocator SubAllocator; - SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont; - PPM_CONTEXT * MinContext, * MaxContext; - - PPM_CONTEXT::STATE* FoundState; // found next state transition - int NumMasked, InitEsc, OrderFall, RunLength, InitRL, MaxOrder; - Byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256]; - Byte EscCount, PrintCount, PrevSuccess, HiBitsFlag; - UInt16 BinSumm[128][64]; // binary SEE-contexts - - UInt16 &GetBinSumm(const PPM_CONTEXT::STATE &rs, int numStates) - { - HiBitsFlag = HB2Flag[FoundState->Symbol]; - return BinSumm[rs.Freq - 1][ - PrevSuccess + NS2BSIndx[numStates - 1] + - HiBitsFlag + 2 * HB2Flag[rs.Symbol] + - ((RunLength >> 26) & 0x20)]; - } - - PPM_CONTEXT *GetContext(UInt32 offset) const { return (PPM_CONTEXT *)SubAllocator.GetPtr(offset); } - PPM_CONTEXT *GetContextNoCheck(UInt32 offset) const { return (PPM_CONTEXT *)SubAllocator.GetPtrNoCheck(offset); } - PPM_CONTEXT::STATE *GetState(UInt32 offset) const { return (PPM_CONTEXT::STATE *)SubAllocator.GetPtr(offset); } - PPM_CONTEXT::STATE *GetStateNoCheck(UInt32 offset) const { return (PPM_CONTEXT::STATE *)SubAllocator.GetPtr(offset); } - - void RestartModelRare() - { - int i, k, m; - memset(CharMask,0,sizeof(CharMask)); - SubAllocator.InitSubAllocator(); - InitRL = -((MaxOrder < 12) ? MaxOrder : 12) - 1; - MinContext = MaxContext = (PPM_CONTEXT*) SubAllocator.AllocContext(); - MinContext->Suffix = 0; - OrderFall = MaxOrder; - MinContext->SummFreq = (UInt16)((MinContext->NumStats = 256) + 1); - FoundState = (PPM_CONTEXT::STATE*)SubAllocator.AllocUnits(256 / 2); - MinContext->Stats = SubAllocator.GetOffsetNoCheck(FoundState); - PrevSuccess = 0; - for (RunLength = InitRL, i = 0; i < 256; i++) - { - PPM_CONTEXT::STATE &state = FoundState[i]; - state.Symbol = (Byte)i; - state.Freq = 1; - state.SetSuccessor(0); - } - for (i = 0; i < 128; i++) - for (k = 0; k < 8; k++) - for ( m=0; m < 64; m += 8) - BinSumm[i][k + m] = (UInt16)(BIN_SCALE - InitBinEsc[k] / (i + 2)); - for (i = 0; i < 25; i++) - for (k = 0; k < 16; k++) - SEE2Cont[i][k].init(5*i+10); - } - - void StartModelRare(int maxOrder) - { - int i, k, m ,Step; - EscCount=PrintCount=1; - if (maxOrder < 2) - { - memset(CharMask,0,sizeof(CharMask)); - OrderFall = MaxOrder; - MinContext = MaxContext; - while (MinContext->Suffix != 0) - { - MinContext = GetContextNoCheck(MinContext->Suffix); - OrderFall--; - } - FoundState = GetState(MinContext->Stats); - MinContext = MaxContext; - } - else - { - MaxOrder = maxOrder; - RestartModelRare(); - NS2BSIndx[0] = 2 * 0; - NS2BSIndx[1] = 2 * 1; - memset(NS2BSIndx + 2, 2 * 2, 9); - memset(NS2BSIndx + 11, 2 * 3, 256 - 11); - for (i = 0; i < 3; i++) - NS2Indx[i] = (Byte)i; - for (m = i, k = Step = 1; i < 256; i++) - { - NS2Indx[i] = (Byte)m; - if ( !--k ) - { - k = ++Step; - m++; - } - } - memset(HB2Flag, 0, 0x40); - memset(HB2Flag + 0x40, 0x08, 0x100 - 0x40); - DummySEE2Cont.Shift = PERIOD_BITS; - } - } - - PPM_CONTEXT* CreateSuccessors(bool skip, PPM_CONTEXT::STATE* p1) - { - // static UpState declaration bypasses IntelC bug - // static PPM_CONTEXT::STATE UpState; - PPM_CONTEXT::STATE UpState; - - PPM_CONTEXT *pc = MinContext; - PPM_CONTEXT *UpBranch = GetContext(FoundState->GetSuccessor()); - PPM_CONTEXT::STATE * p, * ps[MAX_O], ** pps = ps; - if ( !skip ) - { - *pps++ = FoundState; - if ( !pc->Suffix ) - goto NO_LOOP; - } - if ( p1 ) - { - p = p1; - pc = GetContext(pc->Suffix); - goto LOOP_ENTRY; - } - do - { - pc = GetContext(pc->Suffix); - if (pc->NumStats != 1) - { - if ((p = GetStateNoCheck(pc->Stats))->Symbol != FoundState->Symbol) - do { p++; } while (p->Symbol != FoundState->Symbol); - } - else - p = &(pc->oneState()); -LOOP_ENTRY: - if (GetContext(p->GetSuccessor()) != UpBranch) - { - pc = GetContext(p->GetSuccessor()); - break; - } - *pps++ = p; - } - while ( pc->Suffix ); -NO_LOOP: - if (pps == ps) - return pc; - UpState.Symbol = *(Byte*) UpBranch; - UpState.SetSuccessor(SubAllocator.GetOffset(UpBranch) + 1); - if (pc->NumStats != 1) - { - if ((p = GetStateNoCheck(pc->Stats))->Symbol != UpState.Symbol) - do { p++; } while (p->Symbol != UpState.Symbol); - unsigned int cf = p->Freq-1; - unsigned int s0 = pc->SummFreq - pc->NumStats - cf; - UpState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : - ((2 * cf + 3 * s0 - 1) / (2 * s0)))); - } - else - UpState.Freq = pc->oneState().Freq; - do - { - pc = pc->createChild(SubAllocator, *--pps, UpState); - if ( !pc ) - return NULL; - } - while (pps != ps); - return pc; - } - - void UpdateModel() - { - PPM_CONTEXT::STATE fs = *FoundState, * p = NULL; - PPM_CONTEXT* pc, * Successor; - unsigned int ns1, ns, cf, sf, s0; - if (fs.Freq < MAX_FREQ / 4 && MinContext->Suffix != 0) - { - pc = GetContextNoCheck(MinContext->Suffix); - - if (pc->NumStats != 1) - { - if ((p = GetStateNoCheck(pc->Stats))->Symbol != fs.Symbol) - { - do { p++; } while (p->Symbol != fs.Symbol); - if (p[0].Freq >= p[-1].Freq) - { - _PPMD_SWAP(p[0],p[-1]); - p--; - } - } - if (p->Freq < MAX_FREQ-9) - { - p->Freq += 2; - pc->SummFreq += 2; - } - } - else - { - p = &(pc->oneState()); - p->Freq = (Byte)(p->Freq + ((p->Freq < 32) ? 1 : 0)); - } - } - if ( !OrderFall ) - { - MinContext = MaxContext = CreateSuccessors(true, p); - FoundState->SetSuccessor(SubAllocator.GetOffset(MinContext)); - if (MinContext == 0) - goto RESTART_MODEL; - return; - } - *SubAllocator.pText++ = fs.Symbol; - Successor = (PPM_CONTEXT*) SubAllocator.pText; - if (SubAllocator.pText >= SubAllocator.UnitsStart) - goto RESTART_MODEL; - if (fs.GetSuccessor() != 0) - { - if ((Byte *)GetContext(fs.GetSuccessor()) <= SubAllocator.pText) - { - PPM_CONTEXT* cs = CreateSuccessors(false, p); - fs.SetSuccessor(SubAllocator.GetOffset(cs)); - if (cs == NULL) - goto RESTART_MODEL; - } - if ( !--OrderFall ) - { - Successor = GetContext(fs.GetSuccessor()); - SubAllocator.pText -= (MaxContext != MinContext); - } - } - else - { - FoundState->SetSuccessor(SubAllocator.GetOffsetNoCheck(Successor)); - fs.SetSuccessor(SubAllocator.GetOffsetNoCheck(MinContext)); - } - s0 = MinContext->SummFreq - (ns = MinContext->NumStats) - (fs.Freq - 1); - for (pc = MaxContext; pc != MinContext; pc = GetContext(pc->Suffix)) - { - if ((ns1 = pc->NumStats) != 1) - { - if ((ns1 & 1) == 0) - { - void *ppp = SubAllocator.ExpandUnits(GetState(pc->Stats), ns1 >> 1); - pc->Stats = SubAllocator.GetOffset(ppp); - if (!ppp) - goto RESTART_MODEL; - } - pc->SummFreq = (UInt16)(pc->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & - (pc->SummFreq <= 8 * ns1))); - } - else - { - p = (PPM_CONTEXT::STATE*) SubAllocator.AllocUnits(1); - if ( !p ) - goto RESTART_MODEL; - *p = pc->oneState(); - pc->Stats = SubAllocator.GetOffsetNoCheck(p); - if (p->Freq < MAX_FREQ / 4 - 1) - p->Freq <<= 1; - else - p->Freq = MAX_FREQ - 4; - pc->SummFreq = (UInt16)(p->Freq + InitEsc + (ns > 3)); - } - cf = 2 * fs.Freq * (pc->SummFreq+6); - sf = s0 + pc->SummFreq; - if (cf < 6 * sf) - { - cf = 1 + (cf > sf)+(cf >= 4 * sf); - pc->SummFreq += 3; - } - else - { - cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf); - pc->SummFreq = (UInt16)(pc->SummFreq + cf); - } - p = GetState(pc->Stats) + ns1; - p->SetSuccessor(SubAllocator.GetOffset(Successor)); - p->Symbol = fs.Symbol; - p->Freq = (Byte)cf; - pc->NumStats = (UInt16)++ns1; - } - MaxContext = MinContext = GetContext(fs.GetSuccessor()); - return; -RESTART_MODEL: - RestartModelRare(); - EscCount = 0; - PrintCount = 0xFF; - } - - void ClearMask() - { - EscCount = 1; - memset(CharMask, 0, sizeof(CharMask)); - // if (++PrintCount == 0) - // PrintInfo(DecodedFile,EncodedFile); - } - - void update1(PPM_CONTEXT::STATE* p) - { - (FoundState = p)->Freq += 4; - MinContext->SummFreq += 4; - if (p[0].Freq > p[-1].Freq) - { - _PPMD_SWAP(p[0],p[-1]); - FoundState = --p; - if (p->Freq > MAX_FREQ) - rescale(); - } - } - - - void update2(PPM_CONTEXT::STATE* p) - { - (FoundState = p)->Freq += 4; - MinContext->SummFreq += 4; - if (p->Freq > MAX_FREQ) - rescale(); - EscCount++; - RunLength = InitRL; - } - - SEE2_CONTEXT* makeEscFreq2(int Diff, UInt32 &scale) - { - SEE2_CONTEXT* psee2c; - if (MinContext->NumStats != 256) - { - psee2c = SEE2Cont[NS2Indx[Diff-1]] + - (Diff < (GetContext(MinContext->Suffix))->NumStats - MinContext->NumStats) + - 2 * (MinContext->SummFreq < 11 * MinContext->NumStats) + - 4 * (NumMasked > Diff) + - HiBitsFlag; - scale = psee2c->getMean(); - } - else - { - psee2c = &DummySEE2Cont; - scale = 1; - } - return psee2c; - } - - - - void rescale() - { - int OldNS = MinContext->NumStats, i = MinContext->NumStats - 1, Adder, EscFreq; - PPM_CONTEXT::STATE* p1, * p; - PPM_CONTEXT::STATE *stats = GetStateNoCheck(MinContext->Stats); - for (p = FoundState; p != stats; p--) - _PPMD_SWAP(p[0], p[-1]); - stats->Freq += 4; - MinContext->SummFreq += 4; - EscFreq = MinContext->SummFreq - p->Freq; - Adder = (OrderFall != 0); - p->Freq = (Byte)((p->Freq + Adder) >> 1); - MinContext->SummFreq = p->Freq; - do - { - EscFreq -= (++p)->Freq; - p->Freq = (Byte)((p->Freq + Adder) >> 1); - MinContext->SummFreq = (UInt16)(MinContext->SummFreq + p->Freq); - if (p[0].Freq > p[-1].Freq) - { - PPM_CONTEXT::STATE tmp = *(p1 = p); - do - { - p1[0] = p1[-1]; - } - while (--p1 != stats && tmp.Freq > p1[-1].Freq); - *p1 = tmp; - } - } - while ( --i ); - if (p->Freq == 0) - { - do { i++; } while ((--p)->Freq == 0); - EscFreq += i; - MinContext->NumStats = (UInt16)(MinContext->NumStats - i); - if (MinContext->NumStats == 1) - { - PPM_CONTEXT::STATE tmp = *stats; - do { tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1)); EscFreq >>= 1; } while (EscFreq > 1); - SubAllocator.FreeUnits(stats, (OldNS+1) >> 1); - *(FoundState = &MinContext->oneState()) = tmp; return; - } - } - EscFreq -= (EscFreq >> 1); - MinContext->SummFreq = (UInt16)(MinContext->SummFreq + EscFreq); - int n0 = (OldNS+1) >> 1, n1 = (MinContext->NumStats + 1) >> 1; - if (n0 != n1) - MinContext->Stats = SubAllocator.GetOffset(SubAllocator.ShrinkUnits(stats, n0, n1)); - FoundState = GetState(MinContext->Stats); - } - - void NextContext() - { - PPM_CONTEXT *c = GetContext(FoundState->GetSuccessor()); - if (!OrderFall && (Byte *)c > SubAllocator.pText) - MinContext = MaxContext = c; - else - { - UpdateModel(); - if (EscCount == 0) - ClearMask(); - } - } -}; - -// Tabulated escapes for exponential symbol distribution -const Byte ExpEscape[16]={ 25,14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; -#define GET_MEAN(SUMM,SHIFT,ROUND) ((SUMM+(1 << (SHIFT-ROUND))) >> (SHIFT)) - -}} - -#endif diff --git a/CPP/7zip/Compress/PpmdDecode.h b/CPP/7zip/Compress/PpmdDecode.h deleted file mode 100755 index d5ca25fe..00000000 --- a/CPP/7zip/Compress/PpmdDecode.h +++ /dev/null @@ -1,155 +0,0 @@ -// PpmdDecode.h -// 2009-05-30 : Igor Pavlov : Public domain -// This code is based on Dmitry Shkarin's PPMdH code (public domain) - -#ifndef __COMPRESS_PPMD_DECODE_H -#define __COMPRESS_PPMD_DECODE_H - -#include "PpmdContext.h" - -namespace NCompress { -namespace NPpmd { - -class CRangeDecoderVirt -{ -public: - virtual UInt32 GetThreshold(UInt32 total) = 0; - virtual void Decode(UInt32 start, UInt32 size) = 0; - virtual UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) = 0; -}; - -typedef NRangeCoder::CDecoder CRangeDecoderMy; - -class CRangeDecoder:public CRangeDecoderVirt, public CRangeDecoderMy -{ - UInt32 GetThreshold(UInt32 total) { return CRangeDecoderMy::GetThreshold(total); } - void Decode(UInt32 start, UInt32 size) { CRangeDecoderMy::Decode(start, size); } - UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) { return CRangeDecoderMy::DecodeBit(size0, numTotalBits); } -}; - -struct CDecodeInfo: public CInfo -{ - void DecodeBinSymbol(CRangeDecoderVirt *rangeDecoder) - { - PPM_CONTEXT::STATE& rs = MinContext->oneState(); - UInt16& bs = GetBinSumm(rs, GetContextNoCheck(MinContext->Suffix)->NumStats); - if (rangeDecoder->DecodeBit(bs, TOT_BITS) == 0) - { - FoundState = &rs; - rs.Freq = (Byte)(rs.Freq + (rs.Freq < 128 ? 1: 0)); - bs = (UInt16)(bs + INTERVAL - GET_MEAN(bs, PERIOD_BITS, 2)); - PrevSuccess = 1; - RunLength++; - } - else - { - bs = (UInt16)(bs - GET_MEAN(bs, PERIOD_BITS, 2)); - InitEsc = ExpEscape[bs >> 10]; - NumMasked = 1; - CharMask[rs.Symbol] = EscCount; - PrevSuccess = 0; - FoundState = NULL; - } - } - - void DecodeSymbol1(CRangeDecoderVirt *rangeDecoder) - { - PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats); - int i, count, hiCnt; - if ((count = rangeDecoder->GetThreshold(MinContext->SummFreq)) < (hiCnt = p->Freq)) - { - PrevSuccess = (2 * hiCnt > MinContext->SummFreq); - RunLength += PrevSuccess; - rangeDecoder->Decode(0, p->Freq); // MinContext->SummFreq); - (FoundState = p)->Freq = (Byte)(hiCnt += 4); - MinContext->SummFreq += 4; - if (hiCnt > MAX_FREQ) - rescale(); - return; - } - PrevSuccess = 0; - i = MinContext->NumStats - 1; - while ((hiCnt += (++p)->Freq) <= count) - if (--i == 0) - { - HiBitsFlag = HB2Flag[FoundState->Symbol]; - rangeDecoder->Decode(hiCnt, MinContext->SummFreq - hiCnt); // , MinContext->SummFreq); - CharMask[p->Symbol] = EscCount; - i = (NumMasked = MinContext->NumStats)-1; - FoundState = NULL; - do { CharMask[(--p)->Symbol] = EscCount; } while ( --i ); - return; - } - rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , MinContext->SummFreq); - update1(p); - } - - - void DecodeSymbol2(CRangeDecoderVirt *rangeDecoder) - { - int count, hiCnt, i = MinContext->NumStats - NumMasked; - UInt32 freqSum; - SEE2_CONTEXT* psee2c = makeEscFreq2(i, freqSum); - PPM_CONTEXT::STATE* ps[256], ** pps = ps, * p = GetStateNoCheck(MinContext->Stats)-1; - hiCnt = 0; - do - { - do { p++; } while (CharMask[p->Symbol] == EscCount); - hiCnt += p->Freq; - *pps++ = p; - } - while ( --i ); - - freqSum += hiCnt; - count = rangeDecoder->GetThreshold(freqSum); - - p = *(pps = ps); - if (count < hiCnt) - { - hiCnt = 0; - while ((hiCnt += p->Freq) <= count) - p=*++pps; - rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , freqSum); - - psee2c->update(); - update2(p); - } - else - { - rangeDecoder->Decode(hiCnt, freqSum - hiCnt); // , freqSum); - - i = MinContext->NumStats - NumMasked; - pps--; - do { CharMask[(*++pps)->Symbol] = EscCount; } while ( --i ); - psee2c->Summ = (UInt16)(psee2c->Summ + freqSum); - NumMasked = MinContext->NumStats; - } - } - - int DecodeSymbol(CRangeDecoderVirt *rangeDecoder) - { - if (MinContext->NumStats != 1) - DecodeSymbol1(rangeDecoder); - else - DecodeBinSymbol(rangeDecoder); - while ( !FoundState ) - { - do - { - OrderFall++; - MinContext = GetContext(MinContext->Suffix); - if (MinContext == 0) - return -1; - } - while (MinContext->NumStats == NumMasked); - DecodeSymbol2(rangeDecoder); - } - Byte symbol = FoundState->Symbol; - NextContext(); - return symbol; - } -}; - -}} - -#endif diff --git a/CPP/7zip/Compress/PpmdDecoder.cpp b/CPP/7zip/Compress/PpmdDecoder.cpp index 0ac98c8b..c02f44f1 100755 --- a/CPP/7zip/Compress/PpmdDecoder.cpp +++ b/CPP/7zip/Compress/PpmdDecoder.cpp @@ -1,181 +1,165 @@ // PpmdDecoder.cpp -// 2009-05-30 : Igor Pavlov : Public domain +// 2009-03-11 : Igor Pavlov : Public domain #include "StdAfx.h" -#include "Common/Defs.h" -#include "Windows/Defs.h" +#include "../../../C/Alloc.h" +#include "../../../C/CpuArch.h" + +#include "../Common/StreamUtils.h" #include "PpmdDecoder.h" namespace NCompress { namespace NPpmd { -const int kLenIdFinished = -1; -const int kLenIdNeedInit = -2; +static const UInt32 kBufSize = (1 << 20); + +enum +{ + kStatus_NeedInit, + kStatus_Normal, + kStatus_Finished, + kStatus_Error +}; + +static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); } +static void SzBigFree(void *, void *address) { BigFree(address); } +static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; + +CDecoder::~CDecoder() +{ + ::MidFree(_outBuf); + Ppmd7_Free(&_ppmd, &g_BigAlloc); +} -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size) +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size) { if (size < 5) return E_INVALIDARG; - _order = properties[0]; - _usedMemorySize = 0; - for (int i = 0; i < 4; i++) - _usedMemorySize += ((UInt32)(properties[1 + i])) << (i * 8); - - if (_usedMemorySize > kMaxMemBlockSize) + _order = props[0]; + UInt32 memSize = GetUi32(props + 1); + if (_order < PPMD7_MIN_ORDER || + _order > PPMD7_MAX_ORDER || + memSize < PPMD7_MIN_MEM_SIZE || + memSize > PPMD7_MAX_MEM_SIZE) return E_NOTIMPL; - - if (!_rangeDecoder.Create(1 << 20)) + if (!_inStream.Alloc(1 << 20)) return E_OUTOFMEMORY; - if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize)) + if (!Ppmd7_Alloc(&_ppmd, memSize, &g_BigAlloc)) return E_OUTOFMEMORY; - return S_OK; } -class CDecoderFlusher +HRESULT CDecoder::CodeSpec(Byte *memStream, UInt32 size) { - CDecoder *_coder; -public: - bool NeedFlush; - CDecoderFlusher(CDecoder *coder): _coder(coder), NeedFlush(true) {} - ~CDecoderFlusher() + switch(_status) { - if (NeedFlush) - _coder->Flush(); - _coder->ReleaseStreams(); + case kStatus_Finished: return S_OK; + case kStatus_Error: return S_FALSE; + case kStatus_NeedInit: + _inStream.Init(); + if (!Ppmd7z_RangeDec_Init(&_rangeDec)) + { + _status = kStatus_Error; + return S_FALSE; + } + _status = kStatus_Normal; + Ppmd7_Init(&_ppmd, _order); + break; } -}; - -HRESULT CDecoder::CodeSpec(UInt32 size, Byte *memStream) -{ if (_outSizeDefined) { const UInt64 rem = _outSize - _processedSize; if (size > rem) size = (UInt32)rem; } - const UInt32 startSize = size; - if (_remainLen == kLenIdFinished) - return S_OK; - if (_remainLen == kLenIdNeedInit) + UInt32 i; + int sym = 0; + for (i = 0; i != size; i++) { - _rangeDecoder.Init(); - _remainLen = 0; - _info.MaxOrder = 0; - _info.StartModelRare(_order); + sym = Ppmd7_DecodeSymbol(&_ppmd, &_rangeDec.p); + if (_inStream.Extra || sym < 0) + break; + memStream[i] = (Byte)sym; } - while (size != 0) + + _processedSize += i; + if (_inStream.Extra) { - int symbol = _info.DecodeSymbol(&_rangeDecoder); - if (symbol < 0) - { - _remainLen = kLenIdFinished; - break; - } - if (memStream != 0) - *memStream++ = (Byte)symbol; - else - _outStream.WriteByte((Byte)symbol); - size--; + _status = kStatus_Error; + return _inStream.Res; } - _processedSize += startSize - size; + if (sym < 0) + _status = (sym < -1) ? kStatus_Error : kStatus_Finished; return S_OK; } -STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) { - if (!_outStream.Create(1 << 20)) - return E_OUTOFMEMORY; + if (!_outBuf) + { + _outBuf = (Byte *)::MidAlloc(kBufSize); + if (!_outBuf) + return E_OUTOFMEMORY; + } - SetInStream(inStream); - _outStream.SetStream(outStream); + _inStream.Stream = inStream; SetOutStreamSize(outSize); - CDecoderFlusher flusher(this); - for (;;) + do { - _processedSize = _outStream.GetProcessedSize(); - UInt32 curSize = (1 << 18); - RINOK(CodeSpec(curSize, NULL)); - if (_remainLen == kLenIdFinished) + const UInt64 startPos = _processedSize; + HRESULT res = CodeSpec(_outBuf, kBufSize); + size_t processed = (size_t)(_processedSize - startPos); + RINOK(WriteStream(outStream, _outBuf, processed)); + RINOK(res); + if (_status == kStatus_Finished) break; - if (progress != NULL) + if (progress) { - UInt64 inSize = _rangeDecoder.GetProcessedSize(); + UInt64 inSize = _inStream.GetProcessed(); RINOK(progress->SetRatioInfo(&inSize, &_processedSize)); } - if (_outSizeDefined) - if (_outStream.GetProcessedSize() >= _outSize) - break; } - flusher.NeedFlush = false; - return Flush(); + while (!_outSizeDefined || _processedSize < _outSize); + return S_OK; } -#ifdef _NO_EXCEPTIONS - -#define PPMD_TRY_BEGIN -#define PPMD_TRY_END - -#else - -#define PPMD_TRY_BEGIN try { -#define PPMD_TRY_END } \ - catch(const CInBufferException &e) { return e.ErrorCode; } \ - catch(const COutBufferException &e) { return e.ErrorCode; } \ - catch(...) { return S_FALSE; } - -#endif - - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) { - PPMD_TRY_BEGIN - return CodeReal(inStream, outStream, inSize, outSize, progress); - PPMD_TRY_END + _outSizeDefined = (outSize != NULL); + if (_outSizeDefined) + _outSize = *outSize; + _processedSize = 0; + _status = kStatus_NeedInit; + return S_OK; } +#ifndef NO_READ_FROM_CODER + STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { - _rangeDecoder.SetStream(inStream); + InSeqStream = inStream; + _inStream.Stream = inStream; return S_OK; } STDMETHODIMP CDecoder::ReleaseInStream() { - _rangeDecoder.ReleaseStream(); + InSeqStream.Release(); return S_OK; } -STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) -{ - _outSizeDefined = (outSize != NULL); - if (_outSizeDefined) - _outSize = *outSize; - _processedSize = 0; - _remainLen = kLenIdNeedInit; - _outStream.Init(); - return S_OK; -} - -#ifndef NO_READ_FROM_CODER - STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) { - PPMD_TRY_BEGIN - if (processedSize) - *processedSize = 0; const UInt64 startPos = _processedSize; - RINOK(CodeSpec(size, (Byte *)data)); + HRESULT res = CodeSpec((Byte *)data, size); if (processedSize) *processedSize = (UInt32)(_processedSize - startPos); - return Flush(); - PPMD_TRY_END + return res; } #endif diff --git a/CPP/7zip/Compress/PpmdDecoder.h b/CPP/7zip/Compress/PpmdDecoder.h index 31ab8f82..8ebcd700 100755 --- a/CPP/7zip/Compress/PpmdDecoder.h +++ b/CPP/7zip/Compress/PpmdDecoder.h @@ -1,17 +1,16 @@ // PpmdDecoder.h -// 2009-05-30 : Igor Pavlov : Public domain +// 2009-03-11 : Igor Pavlov : Public domain #ifndef __COMPRESS_PPMD_DECODER_H #define __COMPRESS_PPMD_DECODER_H -#include "../../Common/MyCom.h" +#include "../../../C/Ppmd7.h" -#include "../ICoder.h" +#include "../../Common/MyCom.h" -#include "../Common/OutBuffer.h" +#include "../Common/CWrappers.h" -#include "PpmdDecode.h" -#include "RangeCoder.h" +#include "../ICoder.h" namespace NCompress { namespace NPpmd { @@ -26,25 +25,23 @@ class CDecoder : #endif public CMyUnknownImp { - CRangeDecoder _rangeDecoder; - - COutBuffer _outStream; - - CDecodeInfo _info; + Byte *_outBuf; + CPpmd7z_RangeDec _rangeDec; + CByteInBufWrap _inStream; + CPpmd7 _ppmd; Byte _order; - UInt32 _usedMemorySize; - - int _remainLen; - UInt64 _outSize; bool _outSizeDefined; + int _status; + UInt64 _outSize; UInt64 _processedSize; - HRESULT CodeSpec(UInt32 num, Byte *memStream); + HRESULT CodeSpec(Byte *memStream, UInt32 size); public: #ifndef NO_READ_FROM_CODER + CMyComPtr<ISequentialInStream> InSeqStream; MY_UNKNOWN_IMP4( ICompressSetDecoderProperties2, ICompressSetInStream, @@ -55,31 +52,25 @@ public: ICompressSetDecoderProperties2) #endif - void ReleaseStreams() - { - ReleaseInStream(); - _outStream.ReleaseStream(); - } - - HRESULT Flush() { return _outStream.Flush(); } - - STDMETHOD(CodeReal)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); #ifndef NO_READ_FROM_CODER + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); #endif - CDecoder(): _outSizeDefined(false) {} + CDecoder(): _outBuf(NULL), _outSizeDefined(false) + { + Ppmd7z_RangeDec_CreateVTable(&_rangeDec); + _rangeDec.Stream = &_inStream.p; + Ppmd7_Construct(&_ppmd); + } + + ~CDecoder(); }; }} diff --git a/CPP/7zip/Compress/PpmdEncode.h b/CPP/7zip/Compress/PpmdEncode.h deleted file mode 100755 index 012f859c..00000000 --- a/CPP/7zip/Compress/PpmdEncode.h +++ /dev/null @@ -1,142 +0,0 @@ -// PpmdEncode.h -// 2009-05-30 : Igor Pavlov : Public domain -// This code is based on Dmitry Shkarin's PPMdH code (public domain) - -#ifndef __COMPRESS_PPMD_ENCODE_H -#define __COMPRESS_PPMD_ENCODE_H - -#include "PpmdContext.h" - -namespace NCompress { -namespace NPpmd { - -struct CEncodeInfo: public CInfo -{ - void EncodeBinSymbol(int symbol, NRangeCoder::CEncoder *rangeEncoder) - { - PPM_CONTEXT::STATE& rs = MinContext->oneState(); - UInt16 &bs = GetBinSumm(rs, GetContextNoCheck(MinContext->Suffix)->NumStats); - if (rs.Symbol == symbol) - { - FoundState = &rs; - rs.Freq = (Byte)(rs.Freq + (rs.Freq < 128 ? 1: 0)); - rangeEncoder->EncodeBit(bs, TOT_BITS, 0); - bs = (UInt16)(bs + INTERVAL - GET_MEAN(bs, PERIOD_BITS, 2)); - PrevSuccess = 1; - RunLength++; - } - else - { - rangeEncoder->EncodeBit(bs, TOT_BITS, 1); - bs = (UInt16)(bs - GET_MEAN(bs, PERIOD_BITS, 2)); - InitEsc = ExpEscape[bs >> 10]; - NumMasked = 1; - CharMask[rs.Symbol] = EscCount; - PrevSuccess = 0; - FoundState = NULL; - } - } - - void EncodeSymbol1(int symbol, NRangeCoder::CEncoder *rangeEncoder) - { - PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats); - if (p->Symbol == symbol) - { - PrevSuccess = (2 * (p->Freq) > MinContext->SummFreq); - RunLength += PrevSuccess; - rangeEncoder->Encode(0, p->Freq, MinContext->SummFreq); - (FoundState = p)->Freq += 4; - MinContext->SummFreq += 4; - if (p->Freq > MAX_FREQ) - rescale(); - return; - } - PrevSuccess = 0; - int LoCnt = p->Freq, i = MinContext->NumStats - 1; - while ((++p)->Symbol != symbol) - { - LoCnt += p->Freq; - if (--i == 0) - { - HiBitsFlag = HB2Flag[FoundState->Symbol]; - CharMask[p->Symbol] = EscCount; - i=(NumMasked = MinContext->NumStats)-1; - FoundState = NULL; - do { CharMask[(--p)->Symbol] = EscCount; } while ( --i ); - rangeEncoder->Encode(LoCnt, MinContext->SummFreq - LoCnt, MinContext->SummFreq); - return; - } - } - rangeEncoder->Encode(LoCnt, p->Freq, MinContext->SummFreq); - update1(p); - } - - void EncodeSymbol2(int symbol, NRangeCoder::CEncoder *rangeEncoder) - { - int hiCnt, i = MinContext->NumStats - NumMasked; - UInt32 scale; - SEE2_CONTEXT* psee2c = makeEscFreq2(i, scale); - PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats) - 1; - hiCnt = 0; - do - { - do { p++; } while (CharMask[p->Symbol] == EscCount); - hiCnt += p->Freq; - if (p->Symbol == symbol) - goto SYMBOL_FOUND; - CharMask[p->Symbol] = EscCount; - } - while ( --i ); - - rangeEncoder->Encode(hiCnt, scale, hiCnt + scale); - scale += hiCnt; - - psee2c->Summ = (UInt16)(psee2c->Summ + scale); - NumMasked = MinContext->NumStats; - return; -SYMBOL_FOUND: - - UInt32 highCount = hiCnt; - UInt32 lowCount = highCount - p->Freq; - if ( --i ) - { - PPM_CONTEXT::STATE* p1 = p; - do - { - do { p1++; } while (CharMask[p1->Symbol] == EscCount); - hiCnt += p1->Freq; - } - while ( --i ); - } - // SubRange.scale += hiCnt; - scale += hiCnt; - rangeEncoder->Encode(lowCount, highCount - lowCount, scale); - psee2c->update(); - update2(p); - } - - void EncodeSymbol(int c, NRangeCoder::CEncoder *rangeEncoder) - { - if (MinContext->NumStats != 1) - EncodeSymbol1(c, rangeEncoder); - else - EncodeBinSymbol(c, rangeEncoder); - while ( !FoundState ) - { - do - { - OrderFall++; - MinContext = GetContext(MinContext->Suffix); - if (MinContext == 0) - return; // S_OK; - } - while (MinContext->NumStats == NumMasked); - EncodeSymbol2(c, rangeEncoder); - } - NextContext(); - } -}; - -}} - -#endif diff --git a/CPP/7zip/Compress/PpmdEncoder.cpp b/CPP/7zip/Compress/PpmdEncoder.cpp index 0af2ae7d..d823ffe8 100755 --- a/CPP/7zip/Compress/PpmdEncoder.cpp +++ b/CPP/7zip/Compress/PpmdEncoder.cpp @@ -1,10 +1,10 @@ // PpmdEncoder.cpp -// 2009-05-30 : Igor Pavlov : Public domain +// 2009-03-11 : Igor Pavlov : Public domain #include "StdAfx.h" -// #include <fstream.h> -// #include <iomanip.h> +#include "../../../C/Alloc.h" +#include "../../../C/CpuArch.h" #include "../Common/StreamUtils.h" @@ -13,55 +13,46 @@ namespace NCompress { namespace NPpmd { -const UInt32 kMinMemSize = (1 << 11); -const UInt32 kMinOrder = 2; +static const UInt32 kBufSize = (1 << 20); -/* -UInt32 g_NumInner = 0; -UInt32 g_InnerCycles = 0; +static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); } +static void SzBigFree(void *, void *address) { BigFree(address); } +static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; -UInt32 g_Encode2 = 0; -UInt32 g_Encode2Cycles = 0; -UInt32 g_Encode2Cycles2 = 0; +CEncoder::CEncoder(): + _inBuf(NULL), + _usedMemSize(1 << 24), + _order(6) +{ + _rangeEnc.Stream = &_outStream.p; + Ppmd7_Construct(&_ppmd); +} -class CCounter +CEncoder::~CEncoder() { -public: - CCounter() {} - ~CCounter() - { - ofstream ofs("Res.dat"); - ofs << "innerEncode1 = " << setw(10) << g_NumInner << endl; - ofs << "g_InnerCycles = " << setw(10) << g_InnerCycles << endl; - ofs << "g_Encode2 = " << setw(10) << g_Encode2 << endl; - ofs << "g_Encode2Cycles = " << setw(10) << g_Encode2Cycles << endl; - ofs << "g_Encode2Cycles2= " << setw(10) << g_Encode2Cycles2 << endl; - - } -}; -CCounter g_Counter; -*/ + ::MidFree(_inBuf); + Ppmd7_Free(&_ppmd, &g_BigAlloc); +} STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) { for (UInt32 i = 0; i < numProps; i++) { const PROPVARIANT &prop = props[i]; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 v = (UInt32)prop.ulVal; switch(propIDs[i]) { case NCoderPropID::kUsedMemorySize: - if (prop.vt != VT_UI4) + if (v < (1 << 16) || v > PPMD7_MAX_MEM_SIZE || (v & 3) != 0) return E_INVALIDARG; - if (prop.ulVal < kMinMemSize || prop.ulVal > kMaxMemBlockSize) - return E_INVALIDARG; - _usedMemorySize = (UInt32)prop.ulVal; + _usedMemSize = v; break; case NCoderPropID::kOrder: - if (prop.vt != VT_UI4) - return E_INVALIDARG; - if (prop.ulVal < kMinOrder || prop.ulVal > kMaxOrderCompress) + if (v < 2 || v > 32) return E_INVALIDARG; - _order = (Byte)prop.ulVal; + _order = (Byte)v; break; default: return E_INVALIDARG; @@ -75,74 +66,54 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) const UInt32 kPropSize = 5; Byte props[kPropSize]; props[0] = _order; - for (int i = 0; i < 4; i++) - props[1 + i] = Byte(_usedMemorySize >> (8 * i)); + SetUi32(props + 1, _usedMemSize); return WriteStream(outStream, props, kPropSize); } -const UInt32 kUsedMemorySizeDefault = (1 << 24); -const int kOrderDefault = 6; - -CEncoder::CEncoder(): - _usedMemorySize(kUsedMemorySizeDefault), - _order(kOrderDefault) -{ -} - - -HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) +HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) { - if (!_inStream.Create(1 << 20)) - return E_OUTOFMEMORY; - if (!_rangeEncoder.Create(1 << 20)) + if (!_inBuf) + { + _inBuf = (Byte *)::MidAlloc(kBufSize); + if (!_inBuf) + return E_OUTOFMEMORY; + } + if (!_outStream.Alloc(1 << 20)) return E_OUTOFMEMORY; - if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize)) + if (!Ppmd7_Alloc(&_ppmd, _usedMemSize, &g_BigAlloc)) return E_OUTOFMEMORY; - _inStream.SetStream(inStream); - _inStream.Init(); - - _rangeEncoder.SetStream(outStream); - _rangeEncoder.Init(); + _outStream.Stream = outStream; + _outStream.Init(); - CEncoderFlusher flusher(this); - - _info.MaxOrder = 0; - _info.StartModelRare(_order); + Ppmd7z_RangeEnc_Init(&_rangeEnc); + Ppmd7_Init(&_ppmd, _order); + UInt64 processed = 0; for (;;) { - UInt32 size = (1 << 18); - do + UInt32 size; + RINOK(inStream->Read(_inBuf, kBufSize, &size)); + if (size == 0) + { + // We don't write EndMark in PPMD-7z. + // Ppmd7_EncodeSymbol(&_ppmd, &_rangeEnc, -1); + Ppmd7z_RangeEnc_FlushData(&_rangeEnc); + return _outStream.Flush(); + } + for (UInt32 i = 0; i < size; i++) { - Byte symbol; - if (!_inStream.ReadByte(symbol)) - { - // here we can write End Mark for stream version. - // In current version this feature is not used. - // _info.EncodeSymbol(-1, &_rangeEncoder); - return S_OK; - } - _info.EncodeSymbol(symbol, &_rangeEncoder); + Ppmd7_EncodeSymbol(&_ppmd, &_rangeEnc, _inBuf[i]); + RINOK(_outStream.Res); } - while (--size != 0); - if (progress != NULL) + processed += size; + if (progress) { - UInt64 inSize = _inStream.GetProcessedSize(); - UInt64 outSize = _rangeEncoder.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&inSize, &outSize)); + UInt64 outSize = _outStream.GetProcessed(); + RINOK(progress->SetRatioInfo(&processed, &outSize)); } } } -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - try { return CodeReal(inStream, outStream, inSize, outSize, progress); } - catch(const COutBufferException &e) { return e.ErrorCode; } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(...) { return E_FAIL; } -} - }} diff --git a/CPP/7zip/Compress/PpmdEncoder.h b/CPP/7zip/Compress/PpmdEncoder.h index 07b368a7..ed8b3713 100755 --- a/CPP/7zip/Compress/PpmdEncoder.h +++ b/CPP/7zip/Compress/PpmdEncoder.h @@ -1,17 +1,16 @@ // PpmdEncoder.h -// 2009-05-30 : Igor Pavlov : Public domain +// 2009-03-11 : Igor Pavlov : Public domain #ifndef __COMPRESS_PPMD_ENCODER_H #define __COMPRESS_PPMD_ENCODER_H +#include "../../../C/Ppmd7.h" + #include "../../Common/MyCom.h" #include "../ICoder.h" -#include "../Common/InBuffer.h" - -#include "PpmdEncode.h" -#include "RangeCoder.h" +#include "../Common/CWrappers.h" namespace NCompress { namespace NPpmd { @@ -22,56 +21,26 @@ class CEncoder : public ICompressWriteCoderProperties, public CMyUnknownImp { -public: - CInBuffer _inStream; + Byte *_inBuf; + CByteOutBufWrap _outStream; + CPpmd7z_RangeEnc _rangeEnc; + CPpmd7 _ppmd; - NRangeCoder::CEncoder _rangeEncoder; - - CEncodeInfo _info; - UInt32 _usedMemorySize; + UInt32 _usedMemSize; Byte _order; - HRESULT Flush() - { - _rangeEncoder.FlushData(); - return _rangeEncoder.FlushStream(); - } - - void ReleaseStreams() - { - _inStream.ReleaseStream(); - _rangeEncoder.ReleaseStream(); - } - - HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - class CEncoderFlusher - { - CEncoder *_encoder; - public: - CEncoderFlusher(CEncoder *encoder): _encoder(encoder) {} - ~CEncoderFlusher() - { - _encoder->Flush(); - _encoder->ReleaseStreams(); - } - }; - public: - MY_UNKNOWN_IMP2( ICompressSetCoderProperties, ICompressWriteCoderProperties) STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); CEncoder(); + ~CEncoder(); }; }} diff --git a/CPP/7zip/Compress/PpmdSubAlloc.h b/CPP/7zip/Compress/PpmdSubAlloc.h deleted file mode 100755 index 143f4632..00000000 --- a/CPP/7zip/Compress/PpmdSubAlloc.h +++ /dev/null @@ -1,293 +0,0 @@ -// PpmdSubAlloc.h -// 2009-05-30 : Igor Pavlov : Public domain -// This code is based on Dmitry Shkarin's PPMdH code (public domain) - -#ifndef __COMPRESS_PPMD_SUB_ALLOC_H -#define __COMPRESS_PPMD_SUB_ALLOC_H - -#include "../../../C/Alloc.h" - -#include "PpmdType.h" - -const UINT N1=4, N2=4, N3=4, N4=(128+3-1*N1-2*N2-3*N3)/4; -const UINT UNIT_SIZE=12, N_INDEXES=N1+N2+N3+N4; - -// Extra 1 * UNIT_SIZE for NULL support -// Extra 2 * UNIT_SIZE for s0 in GlueFreeBlocks() -const UInt32 kExtraSize = (UNIT_SIZE * 3); -const UInt32 kMaxMemBlockSize = 0xFFFFFFFF - kExtraSize; - -struct MEM_BLK -{ - UInt16 Stamp, NU; - UInt32 Next, Prev; - void InsertAt(Byte *Base, UInt32 p) - { - Prev = p; - MEM_BLK *pp = (MEM_BLK *)(Base + p); - Next = pp->Next; - pp->Next = ((MEM_BLK *)(Base + Next))->Prev = (UInt32)((Byte *)this - Base); - } - void Remove(Byte *Base) - { - ((MEM_BLK *)(Base + Prev))->Next = Next; - ((MEM_BLK *)(Base + Next))->Prev = Prev; - } -}; - - -class CSubAllocator -{ - UInt32 SubAllocatorSize; - Byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount; - UInt32 FreeList[N_INDEXES]; - - Byte *Base; - Byte *HeapStart, *LoUnit, *HiUnit; -public: - Byte *pText, *UnitsStart; - CSubAllocator(): - SubAllocatorSize(0), - GlueCount(0), - LoUnit(0), - HiUnit(0), - pText(0), - UnitsStart(0) - { - memset(Indx2Units, 0, sizeof(Indx2Units)); - memset(FreeList, 0, sizeof(FreeList)); - } - ~CSubAllocator() - { - StopSubAllocator(); - }; - - void *GetPtr(UInt32 offset) const { return (offset == 0) ? 0 : (void *)(Base + offset); } - void *GetPtrNoCheck(UInt32 offset) const { return (void *)(Base + offset); } - UInt32 GetOffset(void *ptr) const { return (ptr == 0) ? 0 : (UInt32)((Byte *)ptr - Base); } - UInt32 GetOffsetNoCheck(void *ptr) const { return (UInt32)((Byte *)ptr - Base); } - MEM_BLK *GetBlk(UInt32 offset) const { return (MEM_BLK *)(Base + offset); } - UInt32 *GetNode(UInt32 offset) const { return (UInt32 *)(Base + offset); } - - void InsertNode(void* p, int indx) - { - *(UInt32 *)p = FreeList[indx]; - FreeList[indx] = GetOffsetNoCheck(p); - } - - void* RemoveNode(int indx) - { - UInt32 offset = FreeList[indx]; - UInt32 *p = GetNode(offset); - FreeList[indx] = *p; - return (void *)p; - } - - UINT U2B(int NU) const { return (UINT)(NU) * UNIT_SIZE; } - - void SplitBlock(void* pv, int oldIndx, int newIndx) - { - int i, UDiff = Indx2Units[oldIndx] - Indx2Units[newIndx]; - Byte* p = ((Byte*)pv) + U2B(Indx2Units[newIndx]); - if (Indx2Units[i = Units2Indx[UDiff-1]] != UDiff) - { - InsertNode(p, --i); - p += U2B(i = Indx2Units[i]); - UDiff -= i; - } - InsertNode(p, Units2Indx[UDiff - 1]); - } - - UInt32 GetUsedMemory() const - { - UInt32 RetVal = SubAllocatorSize - (UInt32)(HiUnit - LoUnit) - (UInt32)(UnitsStart - pText); - for (UInt32 i = 0; i < N_INDEXES; i++) - for (UInt32 pn = FreeList[i]; pn != 0; RetVal -= (UInt32)Indx2Units[i] * UNIT_SIZE) - pn = *GetNode(pn); - return (RetVal >> 2); - } - - UInt32 GetSubAllocatorSize() const { return SubAllocatorSize; } - - void StopSubAllocator() - { - if (SubAllocatorSize != 0) - { - BigFree(Base); - SubAllocatorSize = 0; - Base = 0; - } - } - - bool StartSubAllocator(UInt32 size) - { - if (SubAllocatorSize == size) - return true; - StopSubAllocator(); - if (size == 0) - Base = 0; - else - { - if ((Base = (Byte *)::BigAlloc(size + kExtraSize)) == 0) - return false; - HeapStart = Base + UNIT_SIZE; // we need such code to support NULL; - } - SubAllocatorSize = size; - return true; - } - - void InitSubAllocator() - { - int i, k; - memset(FreeList, 0, sizeof(FreeList)); - HiUnit = (pText = HeapStart) + SubAllocatorSize; - UINT Diff = UNIT_SIZE * (SubAllocatorSize / 8 / UNIT_SIZE * 7); - LoUnit = UnitsStart = HiUnit - Diff; - for (i = 0, k=1; i < N1 ; i++, k += 1) Indx2Units[i] = (Byte)k; - for (k++; i < N1 + N2 ;i++, k += 2) Indx2Units[i] = (Byte)k; - for (k++; i < N1 + N2 + N3 ;i++,k += 3) Indx2Units[i] = (Byte)k; - for (k++; i < N1 + N2 + N3 + N4; i++, k += 4) Indx2Units[i] = (Byte)k; - GlueCount = 0; - for (k = i = 0; k < 128; k++) - { - i += (Indx2Units[i] < k+1); - Units2Indx[k] = (Byte)i; - } - } - - void GlueFreeBlocks() - { - UInt32 s0 = (UInt32)(HeapStart + SubAllocatorSize - Base); - - // We need add exta MEM_BLK with Stamp=0 - GetBlk(s0)->Stamp = 0; - s0 += UNIT_SIZE; - MEM_BLK *ps0 = GetBlk(s0); - - UInt32 p; - int i; - if (LoUnit != HiUnit) - *LoUnit=0; - ps0->Next = ps0->Prev = s0; - - for (i = 0; i < N_INDEXES; i++) - while (FreeList[i] != 0) - { - MEM_BLK *pp = (MEM_BLK *)RemoveNode(i); - pp->InsertAt(Base, s0); - pp->Stamp = 0xFFFF; - pp->NU = Indx2Units[i]; - } - for (p = ps0->Next; p != s0; p = GetBlk(p)->Next) - { - for (;;) - { - MEM_BLK *pp = GetBlk(p); - MEM_BLK *pp1 = GetBlk(p + pp->NU * UNIT_SIZE); - if (pp1->Stamp != 0xFFFF || int(pp->NU) + pp1->NU >= 0x10000) - break; - pp1->Remove(Base); - pp->NU = (UInt16)(pp->NU + pp1->NU); - } - } - while ((p = ps0->Next) != s0) - { - MEM_BLK *pp = GetBlk(p); - pp->Remove(Base); - int sz; - for (sz = pp->NU; sz > 128; sz -= 128, p += 128 * UNIT_SIZE) - InsertNode(Base + p, N_INDEXES - 1); - if (Indx2Units[i = Units2Indx[sz-1]] != sz) - { - int k = sz - Indx2Units[--i]; - InsertNode(Base + p + (sz - k) * UNIT_SIZE, k - 1); - } - InsertNode(Base + p, i); - } - } - void* AllocUnitsRare(int indx) - { - if ( !GlueCount ) - { - GlueCount = 255; - GlueFreeBlocks(); - if (FreeList[indx] != 0) - return RemoveNode(indx); - } - int i = indx; - do - { - if (++i == N_INDEXES) - { - GlueCount--; - i = U2B(Indx2Units[indx]); - return (UnitsStart - pText > i) ? (UnitsStart -= i) : (NULL); - } - } while (FreeList[i] == 0); - void* RetVal = RemoveNode(i); - SplitBlock(RetVal, i, indx); - return RetVal; - } - - void* AllocUnits(int NU) - { - int indx = Units2Indx[NU - 1]; - if (FreeList[indx] != 0) - return RemoveNode(indx); - void* RetVal = LoUnit; - LoUnit += U2B(Indx2Units[indx]); - if (LoUnit <= HiUnit) - return RetVal; - LoUnit -= U2B(Indx2Units[indx]); - return AllocUnitsRare(indx); - } - - void* AllocContext() - { - if (HiUnit != LoUnit) - return (HiUnit -= UNIT_SIZE); - if (FreeList[0] != 0) - return RemoveNode(0); - return AllocUnitsRare(0); - } - - void* ExpandUnits(void* oldPtr, int oldNU) - { - int i0=Units2Indx[oldNU - 1], i1=Units2Indx[oldNU - 1 + 1]; - if (i0 == i1) - return oldPtr; - void* ptr = AllocUnits(oldNU + 1); - if (ptr) - { - memcpy(ptr, oldPtr, U2B(oldNU)); - InsertNode(oldPtr, i0); - } - return ptr; - } - - void* ShrinkUnits(void* oldPtr, int oldNU, int newNU) - { - int i0 = Units2Indx[oldNU - 1], i1 = Units2Indx[newNU - 1]; - if (i0 == i1) - return oldPtr; - if (FreeList[i1] != 0) - { - void* ptr = RemoveNode(i1); - memcpy(ptr, oldPtr, U2B(newNU)); - InsertNode(oldPtr,i0); - return ptr; - } - else - { - SplitBlock(oldPtr, i0, i1); - return oldPtr; - } - } - - void FreeUnits(void* ptr, int oldNU) - { - InsertNode(ptr, Units2Indx[oldNU - 1]); - } -}; - -#endif diff --git a/CPP/7zip/Compress/PpmdType.h b/CPP/7zip/Compress/PpmdType.h deleted file mode 100755 index e4b0203c..00000000 --- a/CPP/7zip/Compress/PpmdType.h +++ /dev/null @@ -1,14 +0,0 @@ -// PpmdType.h -// 2009-05-30 : Igor Pavlov : Public domain -// This code is based on Dmitry Shkarin's PPMdH code (public domain) - -#ifndef __COMPRESS_PPMD_TYPE_H -#define __COMPRESS_PPMD_TYPE_H - -const int kMaxOrderCompress = 32; -const int MAX_O = 255; /* maximum allowed model order */ - -template <class T> -inline void _PPMD_SWAP(T& t1,T& t2) { T tmp = t1; t1 = t2; t2 = tmp; } - -#endif diff --git a/CPP/7zip/Compress/PpmdZip.cpp b/CPP/7zip/Compress/PpmdZip.cpp new file mode 100755 index 00000000..f576909f --- /dev/null +++ b/CPP/7zip/Compress/PpmdZip.cpp @@ -0,0 +1,223 @@ +// PpmdZip.cpp +// 2010-03-11 : Igor Pavlov : Public domain + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../Common/StreamUtils.h" + +#include "PpmdZip.h" + +namespace NCompress { +namespace NPpmdZip { + +static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); } +static void SzBigFree(void *, void *address) { BigFree(address); } +static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; + +CDecoder::CDecoder(bool fullFileMode): + _fullFileMode(fullFileMode) +{ + _ppmd.Stream.In = &_inStream.p; + Ppmd8_Construct(&_ppmd); +} + +CDecoder::~CDecoder() +{ + Ppmd8_Free(&_ppmd, &g_BigAlloc); +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + if (!_outStream.Alloc()) + return E_OUTOFMEMORY; + if (!_inStream.Alloc(1 << 20)) + return E_OUTOFMEMORY; + + _inStream.Stream = inStream; + _inStream.Init(); + + { + Byte buf[2]; + for (int i = 0; i < 2; i++) + buf[i] = _inStream.ReadByte(); + if (_inStream.Extra) + return S_FALSE; + + UInt32 val = GetUi16(buf); + UInt32 order = (val & 0xF) + 1; + UInt32 mem = ((val >> 4) & 0xFF) + 1; + UInt32 restor = (val >> 12); + if (order < 2 || restor > 2) + return S_FALSE; + + #ifndef PPMD8_FREEZE_SUPPORT + if (restor == 2) + return E_NOTIMPL; + #endif + + if (!Ppmd8_Alloc(&_ppmd, mem << 20, &g_BigAlloc)) + return E_OUTOFMEMORY; + + if (!Ppmd8_RangeDec_Init(&_ppmd)) + return S_FALSE; + Ppmd8_Init(&_ppmd, order, restor); + } + + bool wasFinished = false; + UInt64 processedSize = 0; + while (!outSize || processedSize < *outSize) + { + size_t size = kBufSize; + if (outSize != NULL) + { + const UInt64 rem = *outSize - processedSize; + if (size > rem) + size = (size_t)rem; + } + Byte *data = _outStream.Buf; + size_t i = 0; + int sym = 0; + do + { + sym = Ppmd8_DecodeSymbol(&_ppmd); + if (_inStream.Extra || sym < 0) + break; + data[i] = (Byte)sym; + } + while (++i != size); + processedSize += i; + + RINOK(WriteStream(outStream, _outStream.Buf, i)); + + RINOK(_inStream.Res); + if (_inStream.Extra) + return S_FALSE; + + if (sym < 0) + { + if (sym != -1) + return S_FALSE; + wasFinished = true; + break; + } + if (progress) + { + UInt64 inSize = _inStream.GetProcessed(); + RINOK(progress->SetRatioInfo(&inSize, &processedSize)); + } + } + RINOK(_inStream.Res); + if (_fullFileMode) + { + if (!wasFinished) + { + int res = Ppmd8_DecodeSymbol(&_ppmd); + RINOK(_inStream.Res); + if (_inStream.Extra || res != -1) + return S_FALSE; + } + if (!Ppmd8_RangeDec_IsFinishedOK(&_ppmd)) + return S_FALSE; + } + return S_OK; +} + + +// ---------- Encoder ---------- + +CEncoder::~CEncoder() +{ + Ppmd8_Free(&_ppmd, &g_BigAlloc); +} + +HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) +{ + for (UInt32 i = 0; i < numProps; i++) + { + const PROPVARIANT &prop = props[i]; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 v = (UInt32)prop.ulVal; + switch(propIDs[i]) + { + case NCoderPropID::kAlgorithm: + if (v > 1) + return E_INVALIDARG; + _restor = v; + break; + case NCoderPropID::kUsedMemorySize: + if (v < (1 << 20) || v > (1 << 28)) + return E_INVALIDARG; + _usedMemInMB = v >> 20; + break; + case NCoderPropID::kOrder: + if (v < PPMD8_MIN_ORDER || v > PPMD8_MAX_ORDER) + return E_INVALIDARG; + _order = (Byte)v; + break; + default: + return E_INVALIDARG; + } + } + return S_OK; +} + +CEncoder::CEncoder(): + _usedMemInMB(16), + _order(6), + _restor(PPMD8_RESTORE_METHOD_RESTART) +{ + _ppmd.Stream.Out = &_outStream.p; + Ppmd8_Construct(&_ppmd); +} + +HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) +{ + if (!_inStream.Alloc()) + return E_OUTOFMEMORY; + if (!_outStream.Alloc(1 << 20)) + return E_OUTOFMEMORY; + if (!Ppmd8_Alloc(&_ppmd, _usedMemInMB << 20, &g_BigAlloc)) + return E_OUTOFMEMORY; + + _outStream.Stream = outStream; + _outStream.Init(); + + Ppmd8_RangeEnc_Init(&_ppmd); + Ppmd8_Init(&_ppmd, _order, _restor); + + UInt32 val = (UInt32)((_order - 1) + ((_usedMemInMB - 1) << 4) + (_restor << 12)); + _outStream.WriteByte((Byte)(val & 0xFF)); + _outStream.WriteByte((Byte)(val >> 8)); + RINOK(_outStream.Res); + + UInt64 processed = 0; + for (;;) + { + UInt32 size; + RINOK(inStream->Read(_inStream.Buf, kBufSize, &size)); + if (size == 0) + { + Ppmd8_EncodeSymbol(&_ppmd, -1); + Ppmd8_RangeEnc_FlushData(&_ppmd); + return _outStream.Flush(); + } + for (UInt32 i = 0; i < size; i++) + { + Ppmd8_EncodeSymbol(&_ppmd, _inStream.Buf[i]); + RINOK(_outStream.Res); + } + processed += size; + if (progress != NULL) + { + UInt64 outSize = _outStream.GetProcessed(); + RINOK(progress->SetRatioInfo(&processed, &outSize)); + } + } +} + +}} diff --git a/CPP/7zip/Compress/PpmdZip.h b/CPP/7zip/Compress/PpmdZip.h new file mode 100755 index 00000000..7deb31f4 --- /dev/null +++ b/CPP/7zip/Compress/PpmdZip.h @@ -0,0 +1,74 @@ +// PpmdZip.h +// 2010-03-11 : Igor Pavlov : Public domain + +#ifndef __COMPRESS_PPMD_ZIP_H +#define __COMPRESS_PPMD_ZIP_H + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" +#include "../../../C/Ppmd8.h" + +#include "../../Common/MyCom.h" + +#include "../Common/CWrappers.h" + +#include "../ICoder.h" + +namespace NCompress { +namespace NPpmdZip { + +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); + } +}; + +class CDecoder : + public ICompressCoder, + public CMyUnknownImp +{ + CByteInBufWrap _inStream; + CBuf _outStream; + CPpmd8 _ppmd; + bool _fullFileMode; +public: + MY_UNKNOWN_IMP + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + CDecoder(bool fullFileMode); + ~CDecoder(); +}; + +class CEncoder : + public ICompressCoder, + public CMyUnknownImp +{ + CByteOutBufWrap _outStream; + CBuf _inStream; + CPpmd8 _ppmd; + UInt32 _usedMemInMB; + unsigned _order; + unsigned _restor; +public: + MY_UNKNOWN_IMP + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + HRESULT SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); + CEncoder(); + ~CEncoder(); +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp index 77106278..af5cef1a 100755 --- a/CPP/7zip/Compress/Rar3Decoder.cpp +++ b/CPP/7zip/Compress/Rar3Decoder.cpp @@ -1,9 +1,13 @@ // Rar3Decoder.cpp // According to unRAR license, this code may not be used to develop // a program that creates RAR archives + +/* This code uses Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ #include "StdAfx.h" +#include "../../../C/Alloc.h" + #include "../Common/StreamUtils.h" #include "Rar3Decoder.h" @@ -11,6 +15,10 @@ namespace NCompress { namespace NRar3 { +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 kNumAlignReps = 15; static const UInt32 kSymbolReadTable = 256; @@ -38,6 +46,48 @@ static const UInt32 kNormalMatchMinLen = 3; static const UInt32 kVmDataSizeMax = 1 << 16; static const UInt32 kVmCodeSizeMax = 1 << 16; +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; +} + CDecoder::CDecoder(): _window(0), _winPos(0), @@ -48,6 +98,7 @@ CDecoder::CDecoder(): _vmCode(0), m_IsSolid(false) { + Ppmd7_Construct(&_ppmd); } CDecoder::~CDecoder() @@ -55,6 +106,7 @@ CDecoder::~CDecoder() InitFilters(); ::MidFree(_vmData); ::MidFree(_window); + Ppmd7_Free(&_ppmd, &g_BigAlloc); } HRESULT CDecoder::WriteDataToStream(const Byte *data, UInt32 size) @@ -294,39 +346,39 @@ bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize) bool CDecoder::ReadVmCodeLZ() { - UInt32 firstByte = m_InBitStream.ReadBits(8); + UInt32 firstByte = ReadBits(8); UInt32 length = (firstByte & 7) + 1; if (length == 7) - length = m_InBitStream.ReadBits(8) + 7; + length = ReadBits(8) + 7; else if (length == 8) - length = m_InBitStream.ReadBits(16); + length = ReadBits(16); if (length > kVmDataSizeMax) return false; for (UInt32 i = 0; i < length; i++) - _vmData[i] = (Byte)m_InBitStream.ReadBits(8); + _vmData[i] = (Byte)ReadBits(8); return AddVmCode(firstByte, length); } bool CDecoder::ReadVmCodePPM() { int firstByte = DecodePpmSymbol(); - if (firstByte == -1) + if (firstByte < 0) return false; UInt32 length = (firstByte & 7) + 1; if (length == 7) { int b1 = DecodePpmSymbol(); - if (b1 == -1) + if (b1 < 0) return false; length = b1 + 7; } else if (length == 8) { int b1 = DecodePpmSymbol(); - if (b1 == -1) + if (b1 < 0) return false; int b2 = DecodePpmSymbol(); - if (b2 == -1) + if (b2 < 0) return false; length = b1 * 256 + b2; } @@ -335,7 +387,7 @@ bool CDecoder::ReadVmCodePPM() for (UInt32 i = 0; i < length; i++) { int b = DecodePpmSymbol(); - if (b == -1) + if (b < 0) return false; _vmData[i] = (Byte)b; } @@ -344,7 +396,7 @@ bool CDecoder::ReadVmCodePPM() #define RIF(x) { if (!(x)) return S_FALSE; } -UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } +UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.bitDecoder.ReadBits(numBits); } ///////////////////////////////////////////////// // PPM @@ -359,7 +411,7 @@ HRESULT CDecoder::InitPPM() maxMB = (Byte)ReadBits(8); else { - if (_ppm.SubAllocator.GetSubAllocatorSize()== 0) + if (PpmError || !Ppmd7_WasAllocated(&_ppmd)) return S_FALSE; } if (maxOrder & 0x40) @@ -371,34 +423,30 @@ HRESULT CDecoder::InitPPM() */ if (reset) { + PpmError = true; maxOrder = (maxOrder & 0x1F) + 1; if (maxOrder > 16) maxOrder = 16 + (maxOrder - 16) * 3; if (maxOrder == 1) { - // SubAlloc.StopSubAllocator(); - _ppm.SubAllocator.StopSubAllocator(); + Ppmd7_Free(&_ppmd, &g_BigAlloc); return S_FALSE; } - // SubAlloc.StartSubAllocator(MaxMB+1); - // StartModelRare(maxOrder); - - if (!_ppm.SubAllocator.StartSubAllocator((maxMB + 1) << 20)) + if (!Ppmd7_Alloc(&_ppmd, (maxMB + 1) << 20, &g_BigAlloc)) return E_OUTOFMEMORY; - _ppm.MaxOrder = 0; - _ppm.StartModelRare(maxOrder); - + Ppmd7_Init(&_ppmd, maxOrder); + PpmError = false; } - // return (minContext != NULL); - return S_OK; } -int CDecoder::DecodePpmSymbol() { return _ppm.DecodeSymbol(&m_InBitStream); } +int CDecoder::DecodePpmSymbol() { return Ppmd7_DecodeSymbol(&_ppmd, &m_InBitStream.s); } HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing) { keepDecompressing = false; + if (PpmError) + return S_FALSE; do { if (((_wrPtr - _winPos) & kWindowMask) < 260 && _wrPtr != _winPos) @@ -411,15 +459,19 @@ HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing) } } int c = DecodePpmSymbol(); - if (c == -1) + if (c < 0) { - // Original code sets PPMError=true here and then it returns S_OK. Why ??? - // return S_OK; + PpmError = true; return S_FALSE; } if (c == PpmEscChar) { int nextCh = DecodePpmSymbol(); + if (nextCh < 0) + { + PpmError = true; + return S_FALSE; + } if (nextCh == 0) return ReadTables(keepDecompressing); if (nextCh == 2 || nextCh == -1) @@ -427,7 +479,10 @@ HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing) if (nextCh == 3) { if (!ReadVmCodePPM()) + { + PpmError = true; return S_FALSE; + } continue; } if (nextCh == 4 || nextCh == 5) @@ -439,16 +494,22 @@ HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing) for (int i = 0; i < 3; i++) { int c = DecodePpmSymbol(); - if (c == -1) - return S_OK; + if (c < 0) + { + PpmError = true; + return S_FALSE; + } distance = (distance << 8) + (Byte)c; } distance++; length += 28; } int c = DecodePpmSymbol(); - if (c == -1) - return S_OK; + if (c < 0) + { + PpmError = true; + return S_FALSE; + } length += c; if (distance >= _lzSize) return S_FALSE; @@ -471,7 +532,7 @@ HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing) HRESULT CDecoder::ReadTables(bool &keepDecompressing) { keepDecompressing = true; - ReadBits((8 - m_InBitStream.GetBitPosition()) & 7); + ReadBits((8 - m_InBitStream.bitDecoder.GetBitPosition()) & 7); if (ReadBits(1) != 0) { _lzMode = false; @@ -510,7 +571,7 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing) i = 0; while (i < kTablesSizesSum) { - UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); + UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream.bitDecoder); if (number < 16) { newLevels[i] = Byte((number + m_LastLevels[i]) & 15); @@ -620,7 +681,7 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing) return S_OK; } } - UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream.bitDecoder); if (number < 256) { PutByte((Byte)number); @@ -664,10 +725,10 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing) rep0 = distance; } - UInt32 number = m_LenDecoder.DecodeSymbol(&m_InBitStream); + UInt32 number = m_LenDecoder.DecodeSymbol(&m_InBitStream.bitDecoder); if (number >= kLenTableSize) return S_FALSE; - length = 2 + kLenStart[number] + m_InBitStream.ReadBits(kLenDirectBits[number]); + length = 2 + kLenStart[number] + m_InBitStream.bitDecoder.ReadBits(kLenDirectBits[number]); } else { @@ -677,14 +738,14 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing) if (number < 271) { number -= 263; - rep0 = kLen2DistStarts[number] + m_InBitStream.ReadBits(kLen2DistDirectBits[number]); + rep0 = kLen2DistStarts[number] + m_InBitStream.bitDecoder.ReadBits(kLen2DistDirectBits[number]); length = 2; } else if (number < 299) { number -= 271; - length = kNormalMatchMinLen + (UInt32)kLenStart[number] + m_InBitStream.ReadBits(kLenDirectBits[number]); - UInt32 number = m_DistDecoder.DecodeSymbol(&m_InBitStream); + length = kNormalMatchMinLen + (UInt32)kLenStart[number] + m_InBitStream.bitDecoder.ReadBits(kLenDirectBits[number]); + UInt32 number = m_DistDecoder.DecodeSymbol(&m_InBitStream.bitDecoder); if (number >= kDistTableSize) return S_FALSE; rep0 = kDistStart[number]; @@ -692,7 +753,7 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing) if (number >= (kNumAlignBits * 2) + 2) { if (numBits > kNumAlignBits) - rep0 += (m_InBitStream.ReadBits(numBits - kNumAlignBits) << kNumAlignBits); + rep0 += (m_InBitStream.bitDecoder.ReadBits(numBits - kNumAlignBits) << kNumAlignBits); if (PrevAlignCount > 0) { PrevAlignCount--; @@ -700,7 +761,7 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing) } else { - UInt32 number = m_AlignDecoder.DecodeSymbol(&m_InBitStream); + UInt32 number = m_AlignDecoder.DecodeSymbol(&m_InBitStream.bitDecoder); if (number < (1 << kNumAlignBits)) { rep0 += number; @@ -716,7 +777,7 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing) } } else - rep0 += m_InBitStream.ReadBits(numBits); + rep0 += m_InBitStream.bitDecoder.ReadBits(numBits); length += ((kDistLimit4 - rep0) >> 31) + ((kDistLimit3 - rep0) >> 31); } else @@ -749,6 +810,7 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) memset(m_LastLevels, 0, kTablesSizesSum); TablesRead = false; PpmEscChar = 2; + PpmError = true; InitFilters(); } if (!m_IsSolid || !TablesRead) @@ -770,7 +832,7 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) { RINOK(DecodePPM(1 << 18, keepDecompressing)) } - UInt64 packSize = m_InBitStream.GetProcessedSize(); + UInt64 packSize = m_InBitStream.bitDecoder.GetProcessedSize(); RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize)); if (!keepDecompressing) break; @@ -804,14 +866,14 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream if (_window == 0) return E_OUTOFMEMORY; } - if (!m_InBitStream.Create(1 << 20)) + if (!m_InBitStream.bitDecoder.Create(1 << 20)) return E_OUTOFMEMORY; if (!_vm.Create()) return E_OUTOFMEMORY; - m_InBitStream.SetStream(inStream); - m_InBitStream.Init(); + m_InBitStream.bitDecoder.SetStream(inStream); + m_InBitStream.bitDecoder.Init(); _outStream = outStream; CCoderReleaser coderReleaser(this); diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h index 73d4c224..99b647dc 100755 --- a/CPP/7zip/Compress/Rar3Decoder.h +++ b/CPP/7zip/Compress/Rar3Decoder.h @@ -2,9 +2,13 @@ // According to unRAR license, this code may not be used to develop // a program that creates RAR archives +/* This code uses Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ + #ifndef __COMPRESS_RAR3_DECODER_H #define __COMPRESS_RAR3_DECODER_H +#include "../../../C/Ppmd7.h" + #include "../../Common/MyCom.h" #include "../ICoder.h" @@ -13,7 +17,6 @@ #include "BitmDecoder.h" #include "HuffmanDecoder.h" -#include "PpmdDecode.h" #include "Rar3Vm.h" namespace NCompress { @@ -38,8 +41,8 @@ const UInt32 kTablesSizesSum = kMainTableSize + kDistTableSize + kAlignTableSize class CBitDecoder { UInt32 m_Value; + unsigned m_BitPos; public: - UInt32 m_BitPos; CInBuffer m_Stream; bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);} @@ -50,26 +53,13 @@ public: m_Stream.Init(); m_BitPos = 0; m_Value = 0; - // m_BitPos = kNumBigValueBits; - // Normalize(); } - UInt64 GetProcessedSize() const - { return m_Stream.GetProcessedSize() - (m_BitPos) / 8; } + UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() - (m_BitPos) / 8; } UInt32 GetBitPosition() const { return ((8 - m_BitPos) & 7); } - /* - void Normalize() + UInt32 GetValue(unsigned numBits) { - for (;m_BitPos >= 8; m_BitPos -= 8) - m_Value = (m_Value << 8) | m_Stream.ReadByte(); - } - */ - - UInt32 GetValue(UInt32 numBits) - { - // return (m_Value << m_BitPos) >> (kNumBigValueBits - numBits); - // return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - numBits); if (m_BitPos < numBits) { m_BitPos += 8; @@ -83,13 +73,13 @@ public: return m_Value >> (m_BitPos - numBits); } - void MovePos(UInt32 numBits) + void MovePos(unsigned numBits) { m_BitPos -= numBits; m_Value = m_Value & ((1 << m_BitPos) - 1); } - UInt32 ReadBits(UInt32 numBits) + UInt32 ReadBits(unsigned numBits) { UInt32 res = GetValue(numBits); MovePos(numBits); @@ -97,67 +87,42 @@ public: } }; -const int kNumTopBits = 24; -const UInt32 kTopValue = (1 << kNumTopBits); +const UInt32 kTopValue = (1 << 24); const UInt32 kBot = (1 << 15); -class CRangeDecoder:public NPpmd::CRangeDecoderVirt, public CBitDecoder +struct CRangeDecoder { -public: + IPpmd7_RangeDec s; UInt32 Range; - UInt32 Low; UInt32 Code; + UInt32 Low; + CBitDecoder bitDecoder; + SRes Res; - void Normalize() - { - while ((Low ^ (Low + Range)) < kTopValue || - Range < kBot && ((Range = (0 - Low) & (kBot - 1)), 1)) - { - Code = (Code << 8) | m_Stream.ReadByte(); - Range <<= 8; - Low <<= 8; - } - } - +public: void InitRangeCoder() { Code = 0; Low = 0; Range = 0xFFFFFFFF; - for(int i = 0; i < 4; i++) - Code = (Code << 8) | ReadBits(8); - } - - virtual UInt32 GetThreshold(UInt32 total) - { - return (Code - Low) / ( Range /= total); - } - - virtual void Decode(UInt32 start, UInt32 size) - { - Low += start * Range; - Range *= size; - Normalize(); + for (int i = 0; i < 4; i++) + Code = (Code << 8) | bitDecoder.ReadBits(8); } - virtual UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) + void Normalize() { - if (((Code - Low) / (Range >>= numTotalBits)) < size0) - { - Decode(0, size0); - return 0; - } - else + while ((Low ^ (Low + Range)) < kTopValue || + Range < kBot && ((Range = (0 - Low) & (kBot - 1)), 1)) { - Decode(size0, (1 << numTotalBits) - size0); - return 1; + Code = (Code << 8) | bitDecoder.m_Stream.ReadByte(); + Range <<= 8; + Low <<= 8; } } - // UInt64 GetProcessedSizeRangeCoder() {return Stream.GetProcessedSize(); } + CRangeDecoder(); }; - struct CFilter: public NVm::CProgram { CRecordVector<Byte> GlobalData; @@ -219,8 +184,9 @@ class CDecoder: bool TablesRead; - NPpmd::CDecodeInfo _ppm; + CPpmd7 _ppmd; int PpmEscChar; + bool PpmError; HRESULT WriteDataToStream(const Byte *data, UInt32 size); HRESULT WriteData(const Byte *data, UInt32 size); @@ -252,7 +218,7 @@ public: void ReleaseStreams() { _outStream.Release(); - m_InBitStream.ReleaseStream(); + m_InBitStream.bitDecoder.ReleaseStream(); } STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, diff --git a/CPP/7zip/Crypto/ZipCrypto.cpp b/CPP/7zip/Crypto/ZipCrypto.cpp index f5972c57..baaaf98e 100755 --- a/CPP/7zip/Crypto/ZipCrypto.cpp +++ b/CPP/7zip/Crypto/ZipCrypto.cpp @@ -15,114 +15,74 @@ namespace NZip { void CCipher::UpdateKeys(Byte b) { Keys[0] = CRC_UPDATE_BYTE(Keys[0], b); - Keys[1] += Keys[0] & 0xff; - Keys[1] = Keys[1] * 134775813L + 1; + Keys[1] = (Keys[1] + (Keys[0] & 0xFF)) * 0x8088405 + 1; Keys[2] = CRC_UPDATE_BYTE(Keys[2], (Byte)(Keys[1] >> 24)); } -void CCipher::SetPassword(const Byte *password, UInt32 passwordLen) +STDMETHODIMP CCipher::CryptoSetPassword(const Byte *password, UInt32 passwordLen) { - Keys[0] = 305419896L; - Keys[1] = 591751049L; - Keys[2] = 878082192L; - for (UInt32 i = 0; i < passwordLen; i++) + Keys[0] = 0x12345678; + Keys[1] = 0x23456789; + Keys[2] = 0x34567890; + UInt32 i; + for (i = 0; i < passwordLen; i++) UpdateKeys(password[i]); -} - -Byte CCipher::DecryptByteSpec() -{ - UInt32 temp = Keys[2] | 2; - return (Byte)((temp * (temp ^ 1)) >> 8); -} - -Byte CCipher::DecryptByte(Byte b) -{ - Byte c = (Byte)(b ^ DecryptByteSpec()); - UpdateKeys(c); - return c; -} - -Byte CCipher::EncryptByte(Byte b) -{ - Byte c = (Byte)(b ^ DecryptByteSpec()); - UpdateKeys(b); - return c; -} - -void CCipher::DecryptHeader(Byte *buf) -{ - for (unsigned i = 0; i < kHeaderSize; i++) - buf[i] = DecryptByte(buf[i]); -} - -void CCipher::EncryptHeader(Byte *buf) -{ - for (unsigned i = 0; i < kHeaderSize; i++) - buf[i] = EncryptByte(buf[i]); -} - -STDMETHODIMP CEncoder::CryptoSetPassword(const Byte *data, UInt32 size) -{ - _cipher.SetPassword(data, size); + for (i = 0; i < 3; i++) + Keys2[i] = Keys[i]; return S_OK; } -STDMETHODIMP CEncoder::CryptoSetCRC(UInt32 crc) +STDMETHODIMP CCipher::Init() { - _crc = crc; return S_OK; } -STDMETHODIMP CEncoder::Init() +Byte CCipher::DecryptByteSpec() { - return S_OK; + UInt32 temp = Keys[2] | 2; + return (Byte)((temp * (temp ^ 1)) >> 8); } -HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream) +HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream, UInt32 crc) { - Byte header[kHeaderSize]; - g_RandomGenerator.Generate(header, kHeaderSize - 2); - - header[kHeaderSize - 1] = Byte(_crc >> 24); - header[kHeaderSize - 2] = Byte(_crc >> 16); - - _cipher.EncryptHeader(header); - return WriteStream(outStream, header, kHeaderSize); + Byte h[kHeaderSize]; + g_RandomGenerator.Generate(h, kHeaderSize - 2); + h[kHeaderSize - 1] = (Byte)(crc >> 24); + h[kHeaderSize - 2] = (Byte)(crc >> 16); + RestoreKeys(); + Filter(h, kHeaderSize); + return WriteStream(outStream, h, kHeaderSize); } STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size) { - UInt32 i; - for (i = 0; i < size; i++) - data[i] = _cipher.EncryptByte(data[i]); - return i; -} - -STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size) -{ - _cipher.SetPassword(data, size); - return S_OK; + for (UInt32 i = 0; i < size; i++) + { + Byte b = data[i]; + data[i] = (Byte)(b ^ DecryptByteSpec());; + UpdateKeys(b); + } + return size; } HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream) { - Byte header[kHeaderSize]; - RINOK(ReadStream_FAIL(inStream, header, kHeaderSize)); - _cipher.DecryptHeader(header); - return S_OK; -} - -STDMETHODIMP CDecoder::Init() -{ + Byte h[kHeaderSize]; + RINOK(ReadStream_FAIL(inStream, h, kHeaderSize)); + RestoreKeys(); + Filter(h, kHeaderSize); return S_OK; } STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) { - UInt32 i; - for (i = 0; i < size; i++) - data[i] = _cipher.DecryptByte(data[i]); - return i; + for (UInt32 i = 0; i < size; i++) + { + Byte c = (Byte)(data[i] ^ DecryptByteSpec()); + UpdateKeys(c); + data[i] = c; + } + return size; } }} diff --git a/CPP/7zip/Crypto/ZipCrypto.h b/CPP/7zip/Crypto/ZipCrypto.h index 040ebb09..6f104beb 100755 --- a/CPP/7zip/Crypto/ZipCrypto.h +++ b/CPP/7zip/Crypto/ZipCrypto.h @@ -13,59 +13,44 @@ namespace NZip { const unsigned kHeaderSize = 12; -class CCipher +class CCipher: + public ICompressFilter, + public ICryptoSetPassword, + public CMyUnknownImp { UInt32 Keys[3]; + UInt32 Keys2[3]; +protected: void UpdateKeys(Byte b); Byte DecryptByteSpec(); + void RestoreKeys() + { + for (int i = 0; i < 3; i++) + Keys[i] = Keys2[i]; + } + public: - void SetPassword(const Byte *password, UInt32 passwordLen); - Byte DecryptByte(Byte b); - Byte EncryptByte(Byte b); - void DecryptHeader(Byte *buf); - void EncryptHeader(Byte *buf); + STDMETHOD(Init)(); + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); }; -class CEncoder : - public ICompressFilter, - public ICryptoSetPassword, - public ICryptoSetCRC, - public CMyUnknownImp +class CEncoder: public CCipher { - CCipher _cipher; - UInt32 _crc; public: - MY_UNKNOWN_IMP2( - ICryptoSetPassword, - ICryptoSetCRC - ) - STDMETHOD(Init)(); + MY_UNKNOWN_IMP1(ICryptoSetPassword) STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); - - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); - STDMETHOD(CryptoSetCRC)(UInt32 crc); - HRESULT WriteHeader(ISequentialOutStream *outStream); + HRESULT WriteHeader(ISequentialOutStream *outStream, UInt32 crc); }; - -class CDecoder: - public ICompressFilter, - public ICryptoSetPassword, - public CMyUnknownImp +class CDecoder: public CCipher { - CCipher _cipher; public: MY_UNKNOWN_IMP1(ICryptoSetPassword) - - STDMETHOD(Init)(); STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); - HRESULT ReadHeader(ISequentialInStream *inStream); }; - }} #endif diff --git a/CPP/7zip/Guid.txt b/CPP/7zip/Guid.txt index 9843b16e..187ad49a 100755 --- a/CPP/7zip/Guid.txt +++ b/CPP/7zip/Guid.txt @@ -124,6 +124,7 @@ Handler GUIDs: 0A lzma 0B lzma86 0C xz + 0D ppmd D4 APM D5 Mslz diff --git a/CPP/7zip/MyVersion.h b/CPP/7zip/MyVersion.h index 28fbfaaa..6b6a3476 100755 --- a/CPP/7zip/MyVersion.h +++ b/CPP/7zip/MyVersion.h @@ -1,8 +1,8 @@ #define MY_VER_MAJOR 9 -#define MY_VER_MINOR 10 +#define MY_VER_MINOR 11 #define MY_VER_BUILD 0 -#define MY_VERSION "9.10 beta" -#define MY_7ZIP_VERSION "7-Zip 9.10 beta" -#define MY_DATE "2009-12-22" -#define MY_COPYRIGHT "Copyright (c) 1999-2009 Igor Pavlov" +#define MY_VERSION "9.11 beta" +#define MY_7ZIP_VERSION "7-Zip 9.11 beta" +#define MY_DATE "2010-03-15" +#define MY_COPYRIGHT "Copyright (c) 1999-2010 Igor Pavlov" #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE diff --git a/CPP/7zip/UI/Common/Extract.cpp b/CPP/7zip/UI/Common/Extract.cpp index f9de663b..f4c126a4 100755 --- a/CPP/7zip/UI/Common/Extract.cpp +++ b/CPP/7zip/UI/Common/Extract.cpp @@ -55,8 +55,9 @@ static HRESULT DecompressArchive( UString outDir = options.OutputDir; outDir.Replace(L"*", GetCorrectFsPath(arc.DefaultName)); #ifdef _WIN32 - outDir.TrimRight(); - outDir = GetCorrectFullFsPath(outDir); + // GetCorrectFullFsPath doesn't like "..". + // outDir.TrimRight(); + // outDir = GetCorrectFullFsPath(outDir); #endif if (!outDir.IsEmpty()) diff --git a/CPP/7zip/UI/Console/List.cpp b/CPP/7zip/UI/Console/List.cpp index f0f5c315..17f5392a 100755 --- a/CPP/7zip/UI/Console/List.cpp +++ b/CPP/7zip/UI/Console/List.cpp @@ -590,9 +590,14 @@ HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices, { if (archiveLink.VolumePaths.Size() != 0) arcPackSize += archiveLink.VolumesSize; - totalPackSize = arcPackSize; + totalPackSize = (numFiles == 0) ? 0 : arcPackSize; totalPackSizePointer = &totalPackSize; } + if (totalUnPackSizePointer == 0 && numFiles == 0) + { + totalUnPackSize = 0; + totalUnPackSizePointer = &totalUnPackSize; + } if (enableHeaders && !techMode) { fieldPrinter.PrintTitleLines(); diff --git a/CPP/7zip/UI/Far/ExtractEngine.cpp b/CPP/7zip/UI/Far/ExtractEngine.cpp index 677cac79..02d14f83 100755 --- a/CPP/7zip/UI/Far/ExtractEngine.cpp +++ b/CPP/7zip/UI/Far/ExtractEngine.cpp @@ -118,6 +118,12 @@ STDMETHODIMP CExtractCallBackImp::MessageError(const wchar_t *message) return S_OK; } +static void ReduceString(UString &s, int size) +{ + if (s.Length() > size) + s = s.Left(size / 2) + UString(L" ... ") + s.Right(size / 2); +} + STDMETHODIMP CExtractCallBackImp::SetOperationResult(Int32 operationResult, bool encrypted) { switch(operationResult) @@ -145,10 +151,11 @@ STDMETHODIMP CExtractCallBackImp::SetOperationResult(Int32 operationResult, bool default: return E_FAIL; } - char buffer[512]; - const AString s = UnicodeStringToMultiByte(m_CurrentFilePath, m_CodePage); - sprintf(buffer, g_StartupInfo.GetMsgString(idMessage), (const char *)s); - if (g_StartupInfo.ShowMessage(buffer) == -1) + UString name = m_CurrentFilePath; + ReduceString(name, 70); + AString s = g_StartupInfo.GetMsgString(idMessage); + s.Replace(" '%s'", ""); + if (g_StartupInfo.ShowMessageLines(s + (AString)("\n") + UnicodeStringToMultiByte(name, m_CodePage)) == -1) return E_ABORT; } } diff --git a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp index 150c71b1..213c2d48 100755 --- a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp +++ b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp @@ -29,6 +29,16 @@ struct CVolSeqName UString ChangedPart; CVolSeqName(): ChangedPart(L"000") {}; + void SetNumDigits(UInt64 numVolumes) + { + ChangedPart = L"000"; + while (numVolumes > 999) + { + numVolumes /= 10; + ChangedPart += L'0'; + } + } + bool ParseName(const UString &name) { if (name.Right(2) != L"01") @@ -81,6 +91,7 @@ class CThreadSplit: public CProgressThreadVirt public: UString FilePath; UString VolBasePath; + UInt64 NumVolumes; CRecordVector<UInt64> VolumeSizes; }; @@ -96,6 +107,7 @@ HRESULT CThreadSplit::ProcessVirt() Byte *buffer = (Byte *)(void *)bufferObject; UInt64 curVolSize = 0; CVolSeqName seqName; + seqName.SetNumDigits(NumVolumes); UInt64 length; if (!inFile.GetLength(length)) return GetLastError(); @@ -226,6 +238,7 @@ void CApp::Split() { CThreadSplit spliter; + spliter.NumVolumes = numVolumes; CProgressDialog &progressDialog = spliter.ProgressDialog; @@ -241,7 +254,7 @@ void CApp::Split() spliter.FilePath = srcPath + itemName; - spliter.VolBasePath = path + itemName; + spliter.VolBasePath = path + itemName; spliter.VolumeSizes = splitDialog.VolumeSizes; // if (splitDialog.VolumeSizes.Size() == 0) return; |