mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-10 08:07:09 -06:00
4.20
This commit is contained in:
committed by
Kornel Lesiński
parent
8c1b5c7b7e
commit
3c510ba80b
@@ -2,8 +2,7 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#define INITGUID
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
#include "PPMDEncoder.h"
|
||||
|
||||
@@ -101,6 +101,10 @@ SOURCE=.\PPMD.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
# ADD CPP /Yc
|
||||
# End Source File
|
||||
@@ -197,9 +201,21 @@ SOURCE=..\..\Common\OutBuffer.h
|
||||
SOURCE=..\RangeCoder\RangeCoder.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.rc
|
||||
SOURCE=..\..\..\Common\Alloc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Types.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
// Compress/PPM/PPMD/Context.h
|
||||
// Compress/PPMD/Context.h
|
||||
// This code is based on Dmitry Shkarin's PPMdH code
|
||||
|
||||
#pragma once
|
||||
#ifndef __COMPRESS_PPMD_CONTEXT_H
|
||||
#define __COMPRESS_PPMD_CONTEXT_H
|
||||
|
||||
#ifndef __COMPRESS_PPM_PPMD_CONTEXT_H
|
||||
#define __COMPRESS_PPM_PPMD_CONTEXT_H
|
||||
#include "../../../Common/Types.h"
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
#include "PPMDSubAlloc.h"
|
||||
#include "../RangeCoder/RangeCoder.h"
|
||||
#include "PPMDSubAlloc.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NPPMD {
|
||||
@@ -20,12 +18,12 @@ const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS,
|
||||
#pragma pack(1)
|
||||
struct SEE2_CONTEXT
|
||||
{ // SEE-contexts for PPM-contexts with masked symbols
|
||||
WORD Summ;
|
||||
BYTE Shift, Count;
|
||||
UInt16 Summ;
|
||||
Byte Shift, Count;
|
||||
void init(int InitVal) { Summ=InitVal << (Shift=PERIOD_BITS-4); Count=4; }
|
||||
UINT getMean()
|
||||
unsigned int getMean()
|
||||
{
|
||||
UINT RetVal=(Summ >> Shift);
|
||||
unsigned int RetVal=(Summ >> Shift);
|
||||
Summ -= RetVal;
|
||||
return RetVal+(RetVal == 0);
|
||||
}
|
||||
@@ -41,14 +39,14 @@ struct SEE2_CONTEXT
|
||||
|
||||
struct PPM_CONTEXT
|
||||
{
|
||||
WORD NumStats,SummFreq; // sizeof(WORD) > sizeof(BYTE)
|
||||
struct STATE { BYTE Symbol, Freq; PPM_CONTEXT* Successor; } _PACK_ATTR * Stats;
|
||||
UInt16 NumStats,SummFreq; // sizeof(UInt16) > sizeof(Byte)
|
||||
struct STATE { Byte Symbol, Freq; PPM_CONTEXT* Successor; } _PACK_ATTR * Stats;
|
||||
PPM_CONTEXT* Suffix;
|
||||
|
||||
PPM_CONTEXT* createChild(CSubAllocator &aSubAllocator, STATE* pStats, STATE& FirstState)
|
||||
PPM_CONTEXT* createChild(CSubAllocator &subAllocator, STATE* pStats, STATE& FirstState)
|
||||
{
|
||||
PPM_CONTEXT* pc = (PPM_CONTEXT*) aSubAllocator.AllocContext();
|
||||
if ( pc )
|
||||
PPM_CONTEXT* pc = (PPM_CONTEXT*) subAllocator.AllocContext();
|
||||
if (pc)
|
||||
{
|
||||
pc->NumStats = 1;
|
||||
pc->oneState() = FirstState;
|
||||
@@ -64,7 +62,7 @@ struct PPM_CONTEXT
|
||||
|
||||
/////////////////////////////////
|
||||
|
||||
const WORD InitBinEsc[] =
|
||||
const UInt16 InitBinEsc[] =
|
||||
{0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
|
||||
|
||||
struct CInfo
|
||||
@@ -75,15 +73,15 @@ struct CInfo
|
||||
|
||||
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;
|
||||
WORD BinSumm[128][64]; // binary SEE-contexts
|
||||
Byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
|
||||
Byte EscCount, PrintCount, PrevSuccess, HiBitsFlag;
|
||||
UInt16 BinSumm[128][64]; // binary SEE-contexts
|
||||
|
||||
WORD &GetBinSumm(const PPM_CONTEXT::STATE &rs, int aNumStates)
|
||||
UInt16 &GetBinSumm(const PPM_CONTEXT::STATE &rs, int numStates)
|
||||
{
|
||||
HiBitsFlag = HB2Flag[FoundState->Symbol];
|
||||
return BinSumm[rs.Freq - 1][
|
||||
PrevSuccess + NS2BSIndx[aNumStates - 1] +
|
||||
PrevSuccess + NS2BSIndx[numStates - 1] +
|
||||
HiBitsFlag + 2 * HB2Flag[rs.Symbol] +
|
||||
((RunLength >> 26) & 0x20)];
|
||||
}
|
||||
@@ -114,7 +112,7 @@ struct CInfo
|
||||
SEE2Cont[i][k].init(5*i+10);
|
||||
}
|
||||
|
||||
void _FASTCALL StartModelRare(int MaxOrder)
|
||||
void StartModelRare(int MaxOrder)
|
||||
{
|
||||
int i, k, m ,Step;
|
||||
EscCount=PrintCount=1;
|
||||
@@ -156,7 +154,7 @@ struct CInfo
|
||||
}
|
||||
}
|
||||
|
||||
PPM_CONTEXT* CreateSuccessors(BOOL Skip, PPM_CONTEXT::STATE* p1)
|
||||
PPM_CONTEXT* CreateSuccessors(bool skip, PPM_CONTEXT::STATE* p1)
|
||||
{
|
||||
// static UpState declaration bypasses IntelC bug
|
||||
// static PPM_CONTEXT::STATE UpState;
|
||||
@@ -164,7 +162,7 @@ struct CInfo
|
||||
|
||||
PPM_CONTEXT* pc = MinContext, * UpBranch = FoundState->Successor;
|
||||
PPM_CONTEXT::STATE * p, * ps[MAX_O], ** pps = ps;
|
||||
if ( !Skip )
|
||||
if ( !skip )
|
||||
{
|
||||
*pps++ = FoundState;
|
||||
if ( !pc->Suffix )
|
||||
@@ -198,14 +196,14 @@ LOOP_ENTRY:
|
||||
NO_LOOP:
|
||||
if (pps == ps)
|
||||
return pc;
|
||||
UpState.Symbol = *(BYTE*) UpBranch;
|
||||
UpState.Successor = (PPM_CONTEXT*) (((BYTE*) UpBranch)+1);
|
||||
UpState.Symbol = *(Byte*) UpBranch;
|
||||
UpState.Successor = (PPM_CONTEXT*) (((Byte*) UpBranch)+1);
|
||||
if (pc->NumStats != 1)
|
||||
{
|
||||
if ((p = pc->Stats)->Symbol != UpState.Symbol)
|
||||
do { p++; } while (p->Symbol != UpState.Symbol);
|
||||
UINT cf = p->Freq-1;
|
||||
UINT s0 = pc->SummFreq - pc->NumStats - cf;
|
||||
unsigned int cf = p->Freq-1;
|
||||
unsigned int s0 = pc->SummFreq - pc->NumStats - cf;
|
||||
UpState.Freq = 1 + ((2 * cf <= s0) ? (5 * cf > s0) :
|
||||
((2 * cf + 3 * s0 - 1) / (2 * s0)));
|
||||
}
|
||||
@@ -225,7 +223,7 @@ NO_LOOP:
|
||||
{
|
||||
PPM_CONTEXT::STATE fs = *FoundState, * p = NULL;
|
||||
PPM_CONTEXT* pc, * Successor;
|
||||
UINT ns1, ns, cf, sf, s0;
|
||||
unsigned int ns1, ns, cf, sf, s0;
|
||||
if (fs.Freq < MAX_FREQ/4 && (pc=MinContext->Suffix) != NULL)
|
||||
{
|
||||
if (pc->NumStats != 1)
|
||||
@@ -253,7 +251,7 @@ NO_LOOP:
|
||||
}
|
||||
if ( !OrderFall )
|
||||
{
|
||||
MinContext = MaxContext = FoundState->Successor = CreateSuccessors(TRUE, p);
|
||||
MinContext = MaxContext = FoundState->Successor = CreateSuccessors(true, p);
|
||||
if ( !MinContext )
|
||||
goto RESTART_MODEL;
|
||||
return;
|
||||
@@ -264,8 +262,8 @@ NO_LOOP:
|
||||
goto RESTART_MODEL;
|
||||
if ( fs.Successor )
|
||||
{
|
||||
if ((BYTE*) fs.Successor <= SubAllocator.pText &&
|
||||
(fs.Successor=CreateSuccessors(FALSE,p)) == NULL)
|
||||
if ((Byte*) fs.Successor <= SubAllocator.pText &&
|
||||
(fs.Successor=CreateSuccessors(false, p)) == NULL)
|
||||
goto RESTART_MODEL;
|
||||
if ( !--OrderFall )
|
||||
{
|
||||
@@ -363,19 +361,19 @@ RESTART_MODEL:
|
||||
RunLength = InitRL;
|
||||
}
|
||||
|
||||
SEE2_CONTEXT* makeEscFreq2(int Diff, UINT32 &aScale)
|
||||
SEE2_CONTEXT* makeEscFreq2(int Diff, UInt32 &scale)
|
||||
{
|
||||
SEE2_CONTEXT* psee2c;
|
||||
if (MinContext->NumStats != 256)
|
||||
{
|
||||
psee2c = SEE2Cont[NS2Indx[Diff-1]] + (Diff < MinContext->Suffix->NumStats - MinContext->NumStats)+
|
||||
2 * (MinContext->SummFreq < 11 * MinContext->NumStats) + 4 * (NumMasked > Diff) + HiBitsFlag;
|
||||
aScale = psee2c->getMean();
|
||||
scale = psee2c->getMean();
|
||||
}
|
||||
else
|
||||
{
|
||||
psee2c = &DummySEE2Cont;
|
||||
aScale = 1;
|
||||
scale = 1;
|
||||
}
|
||||
return psee2c;
|
||||
}
|
||||
@@ -427,7 +425,7 @@ RESTART_MODEL:
|
||||
|
||||
void NextContext()
|
||||
{
|
||||
if (!OrderFall && (BYTE*) FoundState->Successor > SubAllocator.pText)
|
||||
if (!OrderFall && (Byte*) FoundState->Successor > SubAllocator.pText)
|
||||
MinContext = MaxContext = FoundState->Successor;
|
||||
else
|
||||
{
|
||||
@@ -439,7 +437,7 @@ RESTART_MODEL:
|
||||
};
|
||||
|
||||
// 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 };
|
||||
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))
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// Decode.h
|
||||
// PPMDDecode.h
|
||||
// This code is based on Dmitry Shkarin's PPMdH code
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __COMPRESS_PPM_PPMD_DECODE_H
|
||||
#define __COMPRESS_PPM_PPMD_DECODE_H
|
||||
#ifndef __COMPRESS_PPMD_DECODE_H
|
||||
#define __COMPRESS_PPMD_DECODE_H
|
||||
|
||||
#include "PPMDContext.h"
|
||||
|
||||
@@ -16,18 +14,18 @@ struct CDecodeInfo: public CInfo
|
||||
void DecodeBinSymbol(NRangeCoder::CDecoder *rangeDecoder)
|
||||
{
|
||||
PPM_CONTEXT::STATE& rs = MinContext->oneState();
|
||||
WORD& bs = GetBinSumm(rs, MinContext->Suffix->NumStats);
|
||||
UInt16& bs = GetBinSumm(rs, MinContext->Suffix->NumStats);
|
||||
if (rangeDecoder->DecodeBit(bs, TOT_BITS) == 0)
|
||||
{
|
||||
FoundState = &rs;
|
||||
rs.Freq += (rs.Freq < 128);
|
||||
bs += UINT16(INTERVAL-GET_MEAN(bs,PERIOD_BITS,2));
|
||||
bs += UInt16(INTERVAL-GET_MEAN(bs,PERIOD_BITS,2));
|
||||
PrevSuccess = 1;
|
||||
RunLength++;
|
||||
}
|
||||
else
|
||||
{
|
||||
bs -= UINT16(GET_MEAN(bs,PERIOD_BITS,2));
|
||||
bs -= UInt16(GET_MEAN(bs,PERIOD_BITS,2));
|
||||
InitEsc = ExpEscape[bs >> 10];
|
||||
NumMasked = 1;
|
||||
CharMask[rs.Symbol] = EscCount;
|
||||
@@ -44,7 +42,7 @@ struct CDecodeInfo: public CInfo
|
||||
{
|
||||
PrevSuccess = (2 * hiCnt > MinContext->SummFreq);
|
||||
RunLength += PrevSuccess;
|
||||
rangeDecoder->Decode(0, MinContext->Stats->Freq, MinContext->SummFreq);
|
||||
rangeDecoder->Decode(0, MinContext->Stats->Freq); // MinContext->SummFreq);
|
||||
(FoundState = p)->Freq=(hiCnt += 4);
|
||||
MinContext->SummFreq += 4;
|
||||
if (hiCnt > MAX_FREQ)
|
||||
@@ -57,14 +55,14 @@ struct CDecodeInfo: public CInfo
|
||||
if (--i == 0)
|
||||
{
|
||||
HiBitsFlag = HB2Flag[FoundState->Symbol];
|
||||
rangeDecoder->Decode(hiCnt, MinContext->SummFreq - hiCnt, MinContext->SummFreq);
|
||||
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);
|
||||
rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , MinContext->SummFreq);
|
||||
update1(p);
|
||||
}
|
||||
|
||||
@@ -72,7 +70,7 @@ struct CDecodeInfo: public CInfo
|
||||
void DecodeSymbol2(NRangeCoder::CDecoder *rangeDecoder)
|
||||
{
|
||||
int count, hiCnt, i = MinContext->NumStats - NumMasked;
|
||||
UINT32 freqSum;
|
||||
UInt32 freqSum;
|
||||
SEE2_CONTEXT* psee2c = makeEscFreq2(i, freqSum);
|
||||
PPM_CONTEXT::STATE* ps[256], ** pps = ps, * p = MinContext->Stats-1;
|
||||
hiCnt = 0;
|
||||
@@ -93,14 +91,14 @@ struct CDecodeInfo: public CInfo
|
||||
hiCnt = 0;
|
||||
while ((hiCnt += p->Freq) <= count)
|
||||
p=*++pps;
|
||||
rangeDecoder->Decode(hiCnt - p->Freq, p->Freq, freqSum);
|
||||
rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , freqSum);
|
||||
|
||||
psee2c->update();
|
||||
update2(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
rangeDecoder->Decode(hiCnt, freqSum - hiCnt, freqSum);
|
||||
rangeDecoder->Decode(hiCnt, freqSum - hiCnt); // , freqSum);
|
||||
|
||||
i = MinContext->NumStats - NumMasked;
|
||||
pps--;
|
||||
@@ -128,7 +126,7 @@ struct CDecodeInfo: public CInfo
|
||||
while (MinContext->NumStats == NumMasked);
|
||||
DecodeSymbol2(rangeDecoder);
|
||||
}
|
||||
BYTE symbol = FoundState->Symbol;
|
||||
Byte symbol = FoundState->Symbol;
|
||||
NextContext();
|
||||
return symbol;
|
||||
}
|
||||
|
||||
@@ -10,17 +10,14 @@
|
||||
namespace NCompress {
|
||||
namespace NPPMD {
|
||||
|
||||
STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream)
|
||||
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
RINOK(inStream->Read(&_order,
|
||||
sizeof(_order), &processedSize));
|
||||
if (processedSize != sizeof(_order))
|
||||
return E_FAIL;
|
||||
RINOK(inStream->Read(&_usedMemorySize,
|
||||
sizeof(_usedMemorySize), &processedSize));
|
||||
if (processedSize != sizeof(_usedMemorySize))
|
||||
return E_FAIL;
|
||||
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);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -32,51 +29,46 @@ public:
|
||||
~CDecoderFlusher()
|
||||
{
|
||||
_coder->Flush();
|
||||
// _coder->ReleaseStreams();
|
||||
_coder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
|
||||
UINT32 GetMatchLen(const BYTE *pointer1, const BYTE *pointer2,
|
||||
UINT32 limit)
|
||||
UInt32 GetMatchLen(const Byte *pointer1, const Byte *pointer2,
|
||||
UInt32 limit)
|
||||
{
|
||||
UINT32 i;
|
||||
UInt32 i;
|
||||
for(i = 0; i < limit && *pointer1 == *pointer2;
|
||||
pointer1++, pointer2++, i++);
|
||||
return i;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
_rangeDecoder.Init(inStream);
|
||||
_outStream.Init(outStream);
|
||||
if (!_rangeDecoder.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!_outStream.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
_rangeDecoder.SetStream(inStream);
|
||||
_rangeDecoder.Init();
|
||||
_outStream.SetStream(outStream);
|
||||
_outStream.Init();
|
||||
|
||||
CDecoderFlusher flusher(this);
|
||||
|
||||
/*
|
||||
if (outSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
*/
|
||||
UInt64 progressPosValuePrev = 0, pos = 0;
|
||||
|
||||
UINT64 progressPosValuePrev = 0, pos = 0;
|
||||
|
||||
try
|
||||
{
|
||||
if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize))
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize))
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
// _info.Init();
|
||||
// _info.MaxOrder = _order;
|
||||
_info.MaxOrder = 0;
|
||||
_info.StartModelRare(_order);
|
||||
|
||||
UINT64 size = (outSize == NULL) ? (UINT64)(INT64)(-1) : *outSize;
|
||||
UInt64 size = (outSize == NULL) ? (UInt64)(Int64)(-1) : *outSize;
|
||||
|
||||
while(pos < size)
|
||||
{
|
||||
@@ -87,7 +79,7 @@ STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
|
||||
_outStream.WriteByte(symbol);
|
||||
if (pos - progressPosValuePrev >= (1 << 18) && progress != NULL)
|
||||
{
|
||||
UINT64 inSize = _rangeDecoder.GetProcessedSize();
|
||||
UInt64 inSize = _rangeDecoder.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&inSize, &pos));
|
||||
progressPosValuePrev = pos;
|
||||
}
|
||||
@@ -96,7 +88,7 @@ STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
@@ -105,5 +97,4 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
catch(...) { return E_FAIL; }
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// Compress/PPM/PPMDDecoder.h
|
||||
|
||||
#pragma once
|
||||
#ifndef __COMPRESS_PPMD_DECODER_H
|
||||
#define __COMPRESS_PPMD_DECODER_H
|
||||
|
||||
#ifndef __COMPRESS_PPM_PPMD_DECODER_H
|
||||
#define __COMPRESS_PPM_PPMD_DECODER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/OutBuffer.h"
|
||||
@@ -18,7 +16,7 @@ namespace NPPMD {
|
||||
|
||||
class CDecoder :
|
||||
public ICompressCoder,
|
||||
public ICompressSetDecoderProperties,
|
||||
public ICompressSetDecoderProperties2,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
NRangeCoder::CDecoder _rangeDecoder;
|
||||
@@ -27,39 +25,32 @@ class CDecoder :
|
||||
|
||||
CDecodeInfo _info;
|
||||
|
||||
BYTE _order;
|
||||
UINT32 _usedMemorySize;
|
||||
Byte _order;
|
||||
UInt32 _usedMemorySize;
|
||||
|
||||
public:
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressSetDecoderProperties)
|
||||
MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
|
||||
|
||||
/*
|
||||
void ReleaseStreams()
|
||||
{
|
||||
_rangeDecoder.ReleaseStream();
|
||||
_outStream.ReleaseStream();
|
||||
}
|
||||
*/
|
||||
|
||||
// STDMETHOD(Code)(UINT32 aNumBytes, UINT32 &aProcessedBytes);
|
||||
HRESULT Flush()
|
||||
{ return _outStream.Flush(); }
|
||||
|
||||
HRESULT Flush() { return _outStream.Flush(); }
|
||||
|
||||
STDMETHOD(CodeReal)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
|
||||
// ICompressSetDecoderProperties
|
||||
STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream);
|
||||
|
||||
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// PPMDEncode.h
|
||||
// This code is based on Dmitry Shkarin's PPMdH code
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __COMPRESS_PPM_PPMD_ENCODE_H
|
||||
#define __COMPRESS_PPM_PPMD_ENCODE_H
|
||||
#ifndef __COMPRESS_PPMD_ENCODE_H
|
||||
#define __COMPRESS_PPMD_ENCODE_H
|
||||
|
||||
#include "PPMDContext.h"
|
||||
|
||||
@@ -17,20 +15,20 @@ struct CEncodeInfo: public CInfo
|
||||
void EncodeBinSymbol(int symbol, NRangeCoder::CEncoder *rangeEncoder)
|
||||
{
|
||||
PPM_CONTEXT::STATE& rs = MinContext->oneState();
|
||||
WORD &bs = GetBinSumm(rs, MinContext->Suffix->NumStats);
|
||||
UInt16 &bs = GetBinSumm(rs, MinContext->Suffix->NumStats);
|
||||
if (rs.Symbol == symbol)
|
||||
{
|
||||
FoundState = &rs;
|
||||
rs.Freq += (rs.Freq < 128);
|
||||
rangeEncoder->EncodeBit(bs, TOT_BITS, 0);
|
||||
bs += UINT16(INTERVAL-GET_MEAN(bs,PERIOD_BITS, 2));
|
||||
bs += UInt16(INTERVAL-GET_MEAN(bs,PERIOD_BITS, 2));
|
||||
PrevSuccess = 1;
|
||||
RunLength++;
|
||||
}
|
||||
else
|
||||
{
|
||||
rangeEncoder->EncodeBit(bs, TOT_BITS, 1);
|
||||
bs -= UINT16(GET_MEAN(bs,PERIOD_BITS, 2));
|
||||
bs -= UInt16(GET_MEAN(bs,PERIOD_BITS, 2));
|
||||
InitEsc = ExpEscape[bs >> 10];
|
||||
NumMasked = 1;
|
||||
CharMask[rs.Symbol] = EscCount;
|
||||
@@ -76,7 +74,7 @@ struct CEncodeInfo: public CInfo
|
||||
void EncodeSymbol2(int symbol, NRangeCoder::CEncoder *rangeEncoder)
|
||||
{
|
||||
int hiCnt, i = MinContext->NumStats - NumMasked;
|
||||
UINT32 scale;
|
||||
UInt32 scale;
|
||||
SEE2_CONTEXT* psee2c = makeEscFreq2(i, scale);
|
||||
PPM_CONTEXT::STATE* p = MinContext->Stats - 1;
|
||||
hiCnt = 0;
|
||||
@@ -98,8 +96,8 @@ struct CEncodeInfo: public CInfo
|
||||
return;
|
||||
SYMBOL_FOUND:
|
||||
|
||||
UINT32 highCount = hiCnt;
|
||||
UINT32 lowCount = highCount - p->Freq;
|
||||
UInt32 highCount = hiCnt;
|
||||
UInt32 lowCount = highCount - p->Freq;
|
||||
if ( --i )
|
||||
{
|
||||
PPM_CONTEXT::STATE* p1 = p;
|
||||
|
||||
@@ -14,13 +14,16 @@
|
||||
namespace NCompress {
|
||||
namespace NPPMD {
|
||||
|
||||
/*
|
||||
UINT32 g_NumInner = 0;
|
||||
UINT32 g_InnerCycles = 0;
|
||||
const UInt32 kMinMemSize = (1 << 11);
|
||||
const UInt32 kMinOrder = 2;
|
||||
|
||||
UINT32 g_Encode2 = 0;
|
||||
UINT32 g_Encode2Cycles = 0;
|
||||
UINT32 g_Encode2Cycles2 = 0;
|
||||
/*
|
||||
UInt32 g_NumInner = 0;
|
||||
UInt32 g_InnerCycles = 0;
|
||||
|
||||
UInt32 g_Encode2 = 0;
|
||||
UInt32 g_Encode2Cycles = 0;
|
||||
UInt32 g_Encode2Cycles2 = 0;
|
||||
|
||||
class CCounter
|
||||
{
|
||||
@@ -53,9 +56,9 @@ STDMETHODIMP CEncoder::SetRangeEncoder(CRangeEncoder *aRangeEncoder)
|
||||
*/
|
||||
|
||||
STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UINT32 numProperties)
|
||||
const PROPVARIANT *properties, UInt32 numProperties)
|
||||
{
|
||||
for (UINT32 i = 0; i < numProperties; i++)
|
||||
for (UInt32 i = 0; i < numProperties; i++)
|
||||
{
|
||||
const PROPVARIANT &aProperty = properties[i];
|
||||
switch(propIDs[i])
|
||||
@@ -72,7 +75,7 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
|
||||
return E_INVALIDARG;
|
||||
if (aProperty.ulVal < kMinOrder || aProperty.ulVal > kMaxOrderCompress)
|
||||
return E_INVALIDARG;
|
||||
_order = BYTE(aProperty.ulVal);
|
||||
_order = Byte(aProperty.ulVal);
|
||||
break;
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
@@ -83,11 +86,15 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
|
||||
|
||||
STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
|
||||
{
|
||||
RINOK(outStream->Write(&_order, sizeof(_order), NULL));
|
||||
return outStream->Write(&_usedMemorySize, sizeof(_usedMemorySize), NULL);
|
||||
const UInt32 kPropSize = 5;
|
||||
Byte properties[kPropSize];
|
||||
properties[0] = _order;
|
||||
for (int i = 0; i < 4; i++)
|
||||
properties[1 + i] = Byte(_usedMemorySize >> (8 * i));
|
||||
return outStream->Write(properties, kPropSize, NULL);
|
||||
}
|
||||
|
||||
const UINT32 kUsedMemorySizeDefault = (1 << 24);
|
||||
const UInt32 kUsedMemorySizeDefault = (1 << 24);
|
||||
const int kOrderDefault = 6;
|
||||
|
||||
CEncoder::CEncoder():
|
||||
@@ -112,7 +119,7 @@ public:
|
||||
~CEncoderFlusher()
|
||||
{
|
||||
_encoder->Flush();
|
||||
// _encoder->ReleaseStreams();
|
||||
_encoder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -120,16 +127,23 @@ public:
|
||||
|
||||
HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
_inStream.Init(inStream);
|
||||
_rangeEncoder.Init(outStream);
|
||||
if (!_inStream.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!_rangeEncoder.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
CEncoderFlusher aFlusher(this);
|
||||
_inStream.SetStream(inStream);
|
||||
_inStream.Init();
|
||||
_rangeEncoder.SetStream(outStream);
|
||||
_rangeEncoder.Init();
|
||||
|
||||
UINT64 pos = 0;
|
||||
UINT64 prevProgressPos = 0;
|
||||
CEncoderFlusher flusher(this);
|
||||
|
||||
UInt64 pos = 0;
|
||||
UInt64 prevProgressPos = 0;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -148,7 +162,7 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
|
||||
|
||||
while (true)
|
||||
{
|
||||
BYTE symbol;
|
||||
Byte symbol;
|
||||
if (!_inStream.ReadByte(symbol))
|
||||
{
|
||||
// here we can write End Mark for stream version.
|
||||
@@ -161,7 +175,7 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
|
||||
pos++;
|
||||
if (pos - prevProgressPos >= (1 << 18) && progress != NULL)
|
||||
{
|
||||
UINT64 outSize = _rangeEncoder.GetProcessedSize();
|
||||
UInt64 outSize = _rangeEncoder.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&pos, &outSize));
|
||||
prevProgressPos = pos;
|
||||
}
|
||||
@@ -169,7 +183,7 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
|
||||
}
|
||||
|
||||
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// Compress/PPMD/Encoder.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __COMPRESS_PPMD_ENCODER_H
|
||||
#define __COMPRESS_PPMD_ENCODER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
@@ -28,8 +26,8 @@ public:
|
||||
NRangeCoder::CEncoder _rangeEncoder;
|
||||
|
||||
CEncodeInfo _info;
|
||||
UINT32 _usedMemorySize;
|
||||
BYTE _order;
|
||||
UInt32 _usedMemorySize;
|
||||
Byte _order;
|
||||
|
||||
public:
|
||||
|
||||
@@ -39,23 +37,21 @@ public:
|
||||
|
||||
// ICoder interface
|
||||
HRESULT Flush();
|
||||
/*
|
||||
void ReleaseStreams()
|
||||
{
|
||||
_inStream.ReleaseStream();
|
||||
_rangeEncoder.ReleaseStream();
|
||||
}
|
||||
*/
|
||||
|
||||
HRESULT CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UINT32 numProperties);
|
||||
const PROPVARIANT *properties, UInt32 numProperties);
|
||||
|
||||
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
|
||||
|
||||
|
||||
@@ -1,35 +1,42 @@
|
||||
// SubAlloc.h
|
||||
// PPMDSubAlloc.h
|
||||
// This code is based on Dmitry Shkarin's PPMdH code
|
||||
|
||||
#pragma once
|
||||
#ifndef __PPMD_SUBALLOC_H
|
||||
#define __PPMD_SUBALLOC_H
|
||||
|
||||
#ifndef __SubAlloc_H
|
||||
#define __SubAlloc_H
|
||||
#include "PPMDType.h"
|
||||
|
||||
#include "PPMdType.h"
|
||||
#include "../../../Common/Alloc.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;
|
||||
|
||||
#pragma pack(1)
|
||||
struct MEM_BLK {
|
||||
WORD Stamp, NU;
|
||||
MEM_BLK* next, * prev;
|
||||
void insertAt(MEM_BLK* p) {
|
||||
next=(prev=p)->next; p->next=next->prev=this;
|
||||
}
|
||||
void remove() { prev->next=next; next->prev=prev; }
|
||||
struct MEM_BLK
|
||||
{
|
||||
UInt16 Stamp, NU;
|
||||
MEM_BLK *Next, *Prev;
|
||||
void InsertAt(MEM_BLK* p)
|
||||
{
|
||||
Next = (Prev = p)->Next;
|
||||
p->Next = Next->Prev = this;
|
||||
}
|
||||
void Remove()
|
||||
{
|
||||
Prev->Next=Next;
|
||||
Next->Prev=Prev;
|
||||
}
|
||||
} _PACK_ATTR;
|
||||
#pragma pack()
|
||||
|
||||
|
||||
class CSubAllocator
|
||||
{
|
||||
DWORD SubAllocatorSize;
|
||||
BYTE Indx2Units[N_INDEXES], Units2Indx[128], GlueCount;
|
||||
struct NODE { NODE* next; } FreeList[N_INDEXES];
|
||||
UInt32 SubAllocatorSize;
|
||||
Byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount;
|
||||
struct NODE { NODE* Next; } FreeList[N_INDEXES];
|
||||
public:
|
||||
BYTE* HeapStart, * pText, * UnitsStart, * LoUnit, * HiUnit;
|
||||
Byte* HeapStart, *pText, *UnitsStart, *LoUnit, *HiUnit;
|
||||
CSubAllocator():
|
||||
SubAllocatorSize(0),
|
||||
GlueCount(0),
|
||||
@@ -47,159 +54,200 @@ public:
|
||||
};
|
||||
|
||||
|
||||
inline void InsertNode(void* p,int indx) {
|
||||
((NODE*) p)->next=FreeList[indx].next; FreeList[indx].next=(NODE*) p;
|
||||
}
|
||||
inline void* RemoveNode(int indx) {
|
||||
NODE* RetVal=FreeList[indx].next; FreeList[indx].next=RetVal->next;
|
||||
return RetVal;
|
||||
}
|
||||
inline UINT U2B(int NU) { return 8*NU+4*NU; }
|
||||
inline 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]);
|
||||
}
|
||||
void InsertNode(void* p, int indx)
|
||||
{
|
||||
((NODE*) p)->Next = FreeList[indx].Next;
|
||||
FreeList[indx].Next = (NODE*)p;
|
||||
}
|
||||
|
||||
DWORD _STDCALL GetUsedMemory()
|
||||
{
|
||||
DWORD i, k, RetVal=SubAllocatorSize-(HiUnit-LoUnit)-(UnitsStart-pText);
|
||||
for (k=i=0;i < N_INDEXES;i++, k=0) {
|
||||
for (NODE* pn=FreeList+i;(pn=pn->next) != NULL;k++)
|
||||
;
|
||||
RetVal -= UNIT_SIZE*Indx2Units[i]*k;
|
||||
void* RemoveNode(int indx)
|
||||
{
|
||||
NODE* RetVal = FreeList[indx].Next;
|
||||
FreeList[indx].Next = RetVal->Next;
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
UINT U2B(int NU) { return 8 * NU + 4 * NU; }
|
||||
|
||||
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()
|
||||
{
|
||||
UInt32 i, k, RetVal = SubAllocatorSize - (HiUnit - LoUnit) - (UnitsStart-pText);
|
||||
for (k = i = 0; i < N_INDEXES; i++, k = 0)
|
||||
{
|
||||
for (NODE* pn = FreeList + i;(pn = pn->Next) != NULL; k++)
|
||||
;
|
||||
RetVal -= UNIT_SIZE*Indx2Units[i] * k;
|
||||
}
|
||||
return (RetVal >> 2);
|
||||
}
|
||||
|
||||
void _STDCALL StopSubAllocator()
|
||||
}
|
||||
|
||||
void StopSubAllocator()
|
||||
{
|
||||
if ( SubAllocatorSize )
|
||||
{
|
||||
#ifdef WIN32
|
||||
VirtualFree(HeapStart, 0, MEM_RELEASE);
|
||||
#else
|
||||
delete[] HeapStart;
|
||||
#endif
|
||||
BigFree(HeapStart);
|
||||
SubAllocatorSize = 0;
|
||||
HeapStart = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool _STDCALL StartSubAllocator(UINT32 aSize)
|
||||
bool StartSubAllocator(UInt32 size)
|
||||
{
|
||||
if (SubAllocatorSize == aSize)
|
||||
if (SubAllocatorSize == size)
|
||||
return true;
|
||||
StopSubAllocator();
|
||||
#ifdef WIN32
|
||||
if ((HeapStart = (BYTE *)::VirtualAlloc(0, aSize, MEM_COMMIT, PAGE_READWRITE)) == 0)
|
||||
if ((HeapStart = (Byte *)::BigAlloc(size)) == 0)
|
||||
return false;
|
||||
#else
|
||||
if ((HeapStart = new BYTE[aSize]) == NULL)
|
||||
return false;
|
||||
#endif
|
||||
SubAllocatorSize = aSize;
|
||||
SubAllocatorSize = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void InitSubAllocator()
|
||||
{
|
||||
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]=k;
|
||||
for (k++;i < N1+N2 ;i++,k += 2) Indx2Units[i]=k;
|
||||
for (k++;i < N1+N2+N3 ;i++,k += 3) Indx2Units[i]=k;
|
||||
for (k++;i < N1+N2+N3+N4;i++,k += 4) Indx2Units[i]=k;
|
||||
for (GlueCount=k=i=0;k < 128;k++) {
|
||||
i += (Indx2Units[i] < k+1); Units2Indx[k]=i;
|
||||
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]=k;
|
||||
for (k++; i < N1 + N2 ;i++, k += 2) Indx2Units[i]=k;
|
||||
for (k++; i < N1 + N2 + N3 ;i++,k += 3) Indx2Units[i]=k;
|
||||
for (k++; i < N1 + N2 + N3 + N4; i++, k += 4) Indx2Units[i]=k;
|
||||
for (GlueCount = k = i = 0; k < 128; k++)
|
||||
{
|
||||
i += (Indx2Units[i] < k+1);
|
||||
Units2Indx[k]=i;
|
||||
}
|
||||
}
|
||||
inline void GlueFreeBlocks()
|
||||
{
|
||||
MEM_BLK s0, * p, * p1;
|
||||
}
|
||||
|
||||
void GlueFreeBlocks()
|
||||
{
|
||||
MEM_BLK s0, *p, *p1;
|
||||
int i, k, sz;
|
||||
if (LoUnit != HiUnit) *LoUnit=0;
|
||||
for (i=0, s0.next=s0.prev=&s0;i < N_INDEXES;i++)
|
||||
while ( FreeList[i].next ) {
|
||||
p=(MEM_BLK*) RemoveNode(i); p->insertAt(&s0);
|
||||
p->Stamp=0xFFFF; p->NU=Indx2Units[i];
|
||||
}
|
||||
for (p=s0.next;p != &s0;p=p->next)
|
||||
while ((p1=p+p->NU)->Stamp == 0xFFFF && int(p->NU)+p1->NU < 0x10000) {
|
||||
p1->remove(); p->NU += p1->NU;
|
||||
}
|
||||
while ((p=s0.next) != &s0) {
|
||||
for (p->remove(), sz=p->NU;sz > 128;sz -= 128, p += 128)
|
||||
InsertNode(p,N_INDEXES-1);
|
||||
if (Indx2Units[i=Units2Indx[sz-1]] != sz) {
|
||||
k=sz-Indx2Units[--i]; InsertNode(p+(sz-k),k-1);
|
||||
}
|
||||
InsertNode(p,i);
|
||||
if (LoUnit != HiUnit)
|
||||
*LoUnit=0;
|
||||
for (i = 0, s0.Next = s0.Prev = &s0; i < N_INDEXES; i++)
|
||||
while ( FreeList[i].Next )
|
||||
{
|
||||
p = (MEM_BLK*) RemoveNode(i);
|
||||
p->InsertAt(&s0);
|
||||
p->Stamp = 0xFFFF;
|
||||
p->NU = Indx2Units[i];
|
||||
}
|
||||
for (p=s0.Next; p != &s0; p =p->Next)
|
||||
while ((p1 = p + p->NU)->Stamp == 0xFFFF && int(p->NU) + p1->NU < 0x10000)
|
||||
{
|
||||
p1->Remove();
|
||||
p->NU += p1->NU;
|
||||
}
|
||||
while ((p=s0.Next) != &s0)
|
||||
{
|
||||
for (p->Remove(), sz=p->NU; sz > 128; sz -= 128, p += 128)
|
||||
InsertNode(p, N_INDEXES - 1);
|
||||
if (Indx2Units[i = Units2Indx[sz-1]] != sz)
|
||||
{
|
||||
k = sz-Indx2Units[--i];
|
||||
InsertNode(p + (sz - k), k - 1);
|
||||
}
|
||||
InsertNode(p,i);
|
||||
}
|
||||
}
|
||||
void* AllocUnitsRare(int indx)
|
||||
{
|
||||
if ( !GlueCount ) {
|
||||
GlueCount = 255; GlueFreeBlocks();
|
||||
if ( FreeList[indx].next ) return RemoveNode(indx);
|
||||
}
|
||||
void* AllocUnitsRare(int indx)
|
||||
{
|
||||
if ( !GlueCount )
|
||||
{
|
||||
GlueCount = 255;
|
||||
GlueFreeBlocks();
|
||||
if (FreeList[indx].Next)
|
||||
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].next );
|
||||
void* RetVal=RemoveNode(i); SplitBlock(RetVal,i,indx);
|
||||
int i = indx;
|
||||
do
|
||||
{
|
||||
if (++i == N_INDEXES)
|
||||
{
|
||||
GlueCount--;
|
||||
i = U2B(Indx2Units[indx]);
|
||||
return (UnitsStart - pText > i) ? (UnitsStart -= i) : (NULL);
|
||||
}
|
||||
} while (!FreeList[i].Next);
|
||||
void* RetVal = RemoveNode(i);
|
||||
SplitBlock(RetVal, i, indx);
|
||||
return RetVal;
|
||||
}
|
||||
inline void* AllocUnits(int NU)
|
||||
{
|
||||
int indx=Units2Indx[NU-1];
|
||||
if ( FreeList[indx].next ) return RemoveNode(indx);
|
||||
void* RetVal=LoUnit; LoUnit += U2B(Indx2Units[indx]);
|
||||
if (LoUnit <= HiUnit) return RetVal;
|
||||
LoUnit -= U2B(Indx2Units[indx]); return AllocUnitsRare(indx);
|
||||
}
|
||||
inline void* AllocContext()
|
||||
{
|
||||
if (HiUnit != LoUnit) return (HiUnit -= UNIT_SIZE);
|
||||
if ( FreeList->next ) return RemoveNode(0);
|
||||
}
|
||||
|
||||
void* AllocUnits(int NU)
|
||||
{
|
||||
int indx = Units2Indx[NU - 1];
|
||||
if (FreeList[indx].Next)
|
||||
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->Next)
|
||||
return RemoveNode(0);
|
||||
return AllocUnitsRare(0);
|
||||
}
|
||||
inline 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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
inline 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].next ) {
|
||||
void* ptr=RemoveNode(i1); memcpy(ptr,OldPtr,U2B(NewNU));
|
||||
InsertNode(OldPtr,i0); return ptr;
|
||||
} else {
|
||||
SplitBlock(OldPtr,i0,i1); return OldPtr;
|
||||
}
|
||||
|
||||
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].Next )
|
||||
{
|
||||
void* ptr = RemoveNode(i1);
|
||||
memcpy(ptr, oldPtr, U2B(newNU));
|
||||
InsertNode(oldPtr,i0);
|
||||
return ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
SplitBlock(oldPtr, i0, i1);
|
||||
return oldPtr;
|
||||
}
|
||||
}
|
||||
inline void FreeUnits(void* ptr,int OldNU)
|
||||
{
|
||||
InsertNode(ptr,Units2Indx[OldNU-1]);
|
||||
}
|
||||
}
|
||||
|
||||
void FreeUnits(void* ptr, int oldNU)
|
||||
{
|
||||
InsertNode(ptr, Units2Indx[oldNU - 1]);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,45 +3,15 @@
|
||||
* Written and distributed to public domain by Dmitry Shkarin 1997, *
|
||||
* 1999-2001 *
|
||||
* Contents: compilation parameters and miscelaneous definitions *
|
||||
* Comments: system & compiler dependent file *
|
||||
* Comments: system & compiler dependent file
|
||||
|
||||
* modified by Igor Pavlov (2004-08-29).
|
||||
****************************************************************************/
|
||||
#if !defined(_PPMDTYPE_H_)
|
||||
#define _PPMDTYPE_H_
|
||||
#ifndef __PPMD_TYPE_H
|
||||
#define __PPMD_TYPE_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
const UINT32 kMinMemSize = (1 << 11);
|
||||
const UINT32 kMinOrder = 2;
|
||||
const int kMaxOrderCompress = 32;
|
||||
const int MAX_O=255; /* maximum allowed model order */
|
||||
|
||||
#define _WIN32_ENVIRONMENT_
|
||||
//#define _DOS32_ENVIRONMENT_
|
||||
//#define _POSIX_ENVIRONMENT_
|
||||
//#define _UNKNOWN_ENVIRONMENT_
|
||||
#if defined(_WIN32_ENVIRONMENT_)+defined(_DOS32_ENVIRONMENT_)+defined(_POSIX_ENVIRONMENT_)+defined(_UNKNOWN_ENVIRONMENT_) != 1
|
||||
#error Only one environment must be defined
|
||||
#endif /* defined(_WIN32_ENVIRONMENT_)+defined(_DOS32_ENVIRONMENT_)+defined(_POSIX_ENVIRONMENT_)+defined(_UNKNOWN_ENVIRONMENT_) != 1 */
|
||||
|
||||
#if defined(_WIN32_ENVIRONMENT_)
|
||||
#include <wtypes.h>
|
||||
#else /* _DOS32_ENVIRONMENT_ || _POSIX_ENVIRONMENT_ || _UNKNOWN_ENVIRONMENT_ */
|
||||
typedef int BOOL;
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned long DWORD;
|
||||
typedef unsigned int UINT;
|
||||
#endif /* defined(_WIN32_ENVIRONMENT_) */
|
||||
|
||||
#if !defined(_UNKNOWN_ENVIRONMENT_) && !defined(__GNUC__)
|
||||
#define _FASTCALL __fastcall
|
||||
#define _STDCALL __stdcall
|
||||
#else
|
||||
#define _FASTCALL
|
||||
#define _STDCALL
|
||||
#endif /* !defined(_UNKNOWN_ENVIRONMENT_) && !defined(__GNUC__) */
|
||||
const int MAX_O = 255; /* maximum allowed model order */
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define _PACK_ATTR __attribute__ ((packed))
|
||||
@@ -49,14 +19,7 @@ typedef unsigned int UINT;
|
||||
#define _PACK_ATTR
|
||||
#endif /* defined(__GNUC__) */
|
||||
|
||||
// PPMd module works with file streams via ...GETC/...PUTC macros only
|
||||
typedef FILE _PPMD_FILE;
|
||||
#define _PPMD_E_GETC(fp) getc(fp)
|
||||
#define _PPMD_E_PUTC(c,fp) putc((c),fp)
|
||||
#define _PPMD_D_GETC(fp) getc(fp)
|
||||
#define _PPMD_D_PUTC(c,fp) putc((c),fp)
|
||||
|
||||
template <class T>
|
||||
inline void _PPMD_SWAP(T& t1,T& t2) { T tmp=t1; t1=t2; t2=tmp; }
|
||||
inline void _PPMD_SWAP(T& t1,T& t2) { T tmp = t1; t1 = t2; t2 = tmp; }
|
||||
|
||||
#endif /* !defined(_PPMDTYPE_H_) */
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,9,2,0
|
||||
PRODUCTVERSION 3,9,2,0
|
||||
FILEVERSION 4,16,0,0
|
||||
PRODUCTVERSION 4,16,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -85,14 +85,14 @@ BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "PPMd Coder\0"
|
||||
VALUE "FileVersion", "3, 9, 2, 0\0"
|
||||
VALUE "FileVersion", "4, 16, 0, 0\0"
|
||||
VALUE "InternalName", "PPMd\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "PPMd.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "3, 9, 2, 0\0"
|
||||
VALUE "ProductVersion", "4, 16, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
||||
Reference in New Issue
Block a user