- First LZMA enhanced NSIS version - experimental
- Added SetCompressorDictSize (only works for LZMA) - Added SetCompressionLevel (only "works" for zlib and bzip2) - doesn't work for now - Section is only supposed to get 4 parameters if /o is specified - Updated version numbers git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@3190 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
320cefa4b0
commit
594c3ed0f6
84 changed files with 8083 additions and 41 deletions
116
Source/7zip/7zip/Compress/LZ/BinTree/BinTree.h
Normal file
116
Source/7zip/7zip/Compress/LZ/BinTree/BinTree.h
Normal file
|
@ -0,0 +1,116 @@
|
|||
// BinTree.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
// #ifndef __BINTREE_H
|
||||
// #define __BINTREE_H
|
||||
|
||||
#include "../LZInWindow.h"
|
||||
// #include "Common/Types.h"
|
||||
// #include "Windows/Defs.h"
|
||||
|
||||
namespace BT_NAMESPACE {
|
||||
|
||||
// #define __USE_3_BYTES
|
||||
|
||||
#ifdef __USE_3_BYTES
|
||||
|
||||
#pragma pack(push, PragmaBinTree, 1)
|
||||
|
||||
struct CIndex
|
||||
{
|
||||
BYTE Data[3];
|
||||
CIndex(){}
|
||||
CIndex(UINT32 value)
|
||||
{
|
||||
Data[0] = value & 0xFF;
|
||||
Data[1] = (value >> 8) & 0xFF;
|
||||
Data[2] = (value >> 16) & 0xFF;
|
||||
}
|
||||
operator UINT32() const { return (*((const UINT32 *)Data)) & 0xFFFFFF; }
|
||||
};
|
||||
const UINT32 kMaxValForNormalize = CIndex(-1);
|
||||
|
||||
#pragma pack(pop, PragmaBinTree)
|
||||
|
||||
#else
|
||||
|
||||
typedef UINT32 CIndex;
|
||||
const UINT32 kMaxValForNormalize = (UINT32(1) << 31) - 1;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// #define HASH_ARRAY_2
|
||||
|
||||
// #ifdef HASH_ARRAY_2
|
||||
|
||||
// #define HASH_ARRAY_3
|
||||
|
||||
// #else
|
||||
|
||||
// #define HASH_ZIP
|
||||
|
||||
// #endif
|
||||
|
||||
#pragma pack(push, PragmaBinTreePair, 1)
|
||||
// #pragma pack(push, 1)
|
||||
|
||||
struct CPair
|
||||
{
|
||||
CIndex Left;
|
||||
CIndex Right;
|
||||
};
|
||||
|
||||
// #pragma pack(pop)
|
||||
#pragma pack(pop, PragmaBinTreePair)
|
||||
|
||||
class CInTree: public CLZInWindow
|
||||
{
|
||||
UINT32 _cyclicBufferPos;
|
||||
UINT32 _cyclicBufferSize;
|
||||
UINT32 _historySize;
|
||||
UINT32 _matchMaxLen;
|
||||
|
||||
CIndex *_hash;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
CIndex *_hash2;
|
||||
#ifdef HASH_ARRAY_3
|
||||
CIndex *_hash3;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
CPair *_son;
|
||||
|
||||
UINT32 _cutValue;
|
||||
|
||||
void NormalizeLinks(CIndex *array, UINT32 numItems, UINT32 subValue);
|
||||
void Normalize();
|
||||
void FreeMemory();
|
||||
|
||||
public:
|
||||
CInTree();
|
||||
~CInTree();
|
||||
HRESULT Create(UINT32 sizeHistory, UINT32 keepAddBufferBefore, UINT32 matchMaxLen,
|
||||
UINT32 keepAddBufferAfter, UINT32 sizeReserv = (1<<17));
|
||||
HRESULT Init(ISequentialInStream *stream);
|
||||
void SetCutValue(UINT32 cutValue) { _cutValue = cutValue; }
|
||||
UINT32 GetLongestMatch(UINT32 *distances);
|
||||
void DummyLongestMatch();
|
||||
HRESULT MovePos()
|
||||
{
|
||||
_cyclicBufferPos++;
|
||||
if (_cyclicBufferPos >= _cyclicBufferSize)
|
||||
_cyclicBufferPos = 0;
|
||||
RINOK(CLZInWindow::MovePos());
|
||||
if (_pos == kMaxValForNormalize)
|
||||
Normalize();
|
||||
return S_OK;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// #endif
|
18
Source/7zip/7zip/Compress/LZ/BinTree/BinTree2.h
Normal file
18
Source/7zip/7zip/Compress/LZ/BinTree/BinTree2.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
// BinTree2.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __BINTREE2__H
|
||||
#define __BINTREE2__H
|
||||
|
||||
#undef BT_CLSID
|
||||
#define BT_CLSID CLSID_CMatchFinderBT2
|
||||
|
||||
#undef BT_NAMESPACE
|
||||
#define BT_NAMESPACE NBT2
|
||||
|
||||
#include "BinTreeMF.h"
|
||||
#include "BinTreeMFMain.h"
|
||||
|
||||
#endif
|
||||
|
22
Source/7zip/7zip/Compress/LZ/BinTree/BinTree3.h
Normal file
22
Source/7zip/7zip/Compress/LZ/BinTree/BinTree3.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
// BinTree3.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __BINTREE3__H
|
||||
#define __BINTREE3__H
|
||||
|
||||
#undef BT_CLSID
|
||||
#define BT_CLSID CLSID_CMatchFinderBT3
|
||||
|
||||
#undef BT_NAMESPACE
|
||||
#define BT_NAMESPACE NBT3
|
||||
|
||||
#define HASH_ARRAY_2
|
||||
|
||||
#include "BinTreeMF.h"
|
||||
#include "BinTreeMFMain.h"
|
||||
|
||||
#undef HASH_ARRAY_2
|
||||
|
||||
#endif
|
||||
|
19
Source/7zip/7zip/Compress/LZ/BinTree/BinTree3Z.h
Normal file
19
Source/7zip/7zip/Compress/LZ/BinTree/BinTree3Z.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
// BinTree3Z.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __BINTREE3Z__H
|
||||
#define __BINTREE3Z__H
|
||||
|
||||
#undef BT_NAMESPACE
|
||||
#define BT_NAMESPACE NBT3Z
|
||||
|
||||
#define HASH_ZIP
|
||||
|
||||
#include "BinTree.h"
|
||||
// #include "BinTreeMain.h"
|
||||
|
||||
#undef HASH_ZIP
|
||||
|
||||
#endif
|
||||
|
18
Source/7zip/7zip/Compress/LZ/BinTree/BinTree3ZMain.h
Normal file
18
Source/7zip/7zip/Compress/LZ/BinTree/BinTree3ZMain.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
// BinTree3ZMain.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __BINTREE3ZMAIN__H
|
||||
#define __BINTREE3ZMAIN__H
|
||||
|
||||
#undef BT_NAMESPACE
|
||||
#define BT_NAMESPACE NBT3Z
|
||||
|
||||
#define HASH_ZIP
|
||||
|
||||
#include "BinTreeMain.h"
|
||||
|
||||
#undef HASH_ZIP
|
||||
|
||||
#endif
|
||||
|
24
Source/7zip/7zip/Compress/LZ/BinTree/BinTree4.h
Normal file
24
Source/7zip/7zip/Compress/LZ/BinTree/BinTree4.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
// BinTree4.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __BINTREE4__H
|
||||
#define __BINTREE4__H
|
||||
|
||||
#undef BT_CLSID
|
||||
#define BT_CLSID CLSID_CMatchFinderBT4
|
||||
|
||||
#undef BT_NAMESPACE
|
||||
#define BT_NAMESPACE NBT4
|
||||
|
||||
#define HASH_ARRAY_2
|
||||
#define HASH_ARRAY_3
|
||||
|
||||
#include "BinTreeMF.h"
|
||||
#include "BinTreeMFMain.h"
|
||||
|
||||
#undef HASH_ARRAY_2
|
||||
#undef HASH_ARRAY_3
|
||||
|
||||
#endif
|
||||
|
26
Source/7zip/7zip/Compress/LZ/BinTree/BinTree4b.h
Normal file
26
Source/7zip/7zip/Compress/LZ/BinTree/BinTree4b.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
// BinTree4b.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __BINTREE4B__H
|
||||
#define __BINTREE4B__H
|
||||
|
||||
#undef BT_CLSID
|
||||
#define BT_CLSID CLSID_CMatchFinderBT4b
|
||||
|
||||
#undef BT_NAMESPACE
|
||||
#define BT_NAMESPACE NBT4B
|
||||
|
||||
#define HASH_ARRAY_2
|
||||
#define HASH_ARRAY_3
|
||||
#define HASH_BIG
|
||||
|
||||
#include "BinTreeMF.h"
|
||||
#include "BinTreeMFMain.h"
|
||||
|
||||
#undef HASH_ARRAY_2
|
||||
#undef HASH_ARRAY_3
|
||||
#undef HASH_BIG
|
||||
|
||||
#endif
|
||||
|
110
Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMF.h
Normal file
110
Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMF.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
// BinTreeMF.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
// #ifndef __BINTREEMF_H
|
||||
// #define __BINTREEMF_H
|
||||
|
||||
#include "../../../ICoder.h"
|
||||
#include "BinTree.h"
|
||||
|
||||
namespace BT_NAMESPACE {
|
||||
|
||||
#undef kIDByte
|
||||
#undef kIDString
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
#ifdef HASH_ARRAY_3
|
||||
#ifdef HASH_BIG
|
||||
#define kIDByte 0x4
|
||||
#define kIDString TEXT("4b")
|
||||
#else
|
||||
#define kIDByte 0x3
|
||||
#define kIDString TEXT("4")
|
||||
#endif
|
||||
#else
|
||||
#define kIDByte 0x2
|
||||
#define kIDString TEXT("3")
|
||||
#endif
|
||||
#else
|
||||
#ifdef HASH_ZIP
|
||||
#define kIDByte 0x0
|
||||
#define kIDString TEXT("3Z")
|
||||
#else
|
||||
#define kIDByte 0x1
|
||||
#define kIDString TEXT("2")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef kIDUse3BytesByte
|
||||
#undef kIDUse3BytesString
|
||||
|
||||
#ifdef __USE_3_BYTES
|
||||
#define kIDUse3BytesByte 0x80
|
||||
#define kIDUse3BytesString TEXT("T")
|
||||
#else
|
||||
#define kIDUse3BytesByte 0x00
|
||||
#define kIDUse3BytesString TEXT("")
|
||||
#endif
|
||||
|
||||
// #undef kIDStringFull
|
||||
|
||||
// #define kIDStringFull TEXT("Compress.MatchFinderBT") kIDString kIDUse3BytesString
|
||||
|
||||
// {23170F69-40C1-278C-02XX-0000000000}
|
||||
DEFINE_GUID(BT_CLSID,
|
||||
0x23170F69, 0x40C1, 0x278C, 0x02, kIDByte | kIDUse3BytesByte,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
class CInTree2: public CInTree
|
||||
{
|
||||
CMyComPtr<IMatchFinderCallback> _callback;
|
||||
virtual void BeforeMoveBlock();
|
||||
virtual void AfterMoveBlock();
|
||||
public:
|
||||
void SetCallback(IMatchFinderCallback *callback)
|
||||
{
|
||||
_callback = callback;
|
||||
}
|
||||
};
|
||||
|
||||
class CMatchFinderBinTree:
|
||||
public IMatchFinder,
|
||||
public IMatchFinderSetCallback,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
MY_UNKNOWN_IMP1(IMatchFinderSetCallback)
|
||||
|
||||
STDMETHOD(Init)(ISequentialInStream *stream);
|
||||
STDMETHOD_(void, ReleaseStream)();
|
||||
STDMETHOD(MovePos)();
|
||||
STDMETHOD_(BYTE, GetIndexByte)(UINT32 index);
|
||||
STDMETHOD_(UINT32, GetMatchLen)(UINT32 index, UINT32 back, UINT32 limit);
|
||||
STDMETHOD_(UINT32, GetNumAvailableBytes)();
|
||||
STDMETHOD_(const BYTE *, GetPointerToCurrentPos)();
|
||||
STDMETHOD(Create)(UINT32 sizeHistory,
|
||||
UINT32 keepAddBufferBefore, UINT32 matchMaxLen,
|
||||
UINT32 keepAddBufferAfter);
|
||||
STDMETHOD_(UINT32, GetLongestMatch)(UINT32 *distances);
|
||||
STDMETHOD_(void, DummyLongestMatch)();
|
||||
|
||||
// IMatchFinderSetCallback
|
||||
STDMETHOD(SetCallback)(IMatchFinderCallback *callback);
|
||||
|
||||
private:
|
||||
// UINT32 m_WindowReservSize;
|
||||
CInTree2 _matchFinder;
|
||||
public:
|
||||
// CMatchFinderBinTree(): m_WindowReservSize((1 << 19) + 256) {};
|
||||
void SetCutValue(UINT32 cutValue)
|
||||
{ _matchFinder.SetCutValue(cutValue); }
|
||||
/*
|
||||
void SetWindowReservSize(UINT32 reservWindowSize)
|
||||
{ m_WindowReservSize = reservWindowSize; }
|
||||
*/
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
81
Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMFMain.h
Normal file
81
Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMFMain.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
// BinTreeMFMain.h
|
||||
|
||||
// #include "StdAfx.h"
|
||||
|
||||
// #include "BinTreeMF.h"
|
||||
#include "BinTreeMain.h"
|
||||
|
||||
namespace BT_NAMESPACE {
|
||||
|
||||
void CInTree2::BeforeMoveBlock()
|
||||
{
|
||||
if (_callback)
|
||||
_callback->BeforeChangingBufferPos();
|
||||
CInTree::BeforeMoveBlock();
|
||||
}
|
||||
|
||||
void CInTree2::AfterMoveBlock()
|
||||
{
|
||||
CInTree::AfterMoveBlock();
|
||||
if (_callback)
|
||||
_callback->AfterChangingBufferPos();
|
||||
}
|
||||
|
||||
STDMETHODIMP CMatchFinderBinTree::Init(ISequentialInStream *stream)
|
||||
{ return _matchFinder.Init(stream); }
|
||||
|
||||
STDMETHODIMP_(void) CMatchFinderBinTree::ReleaseStream()
|
||||
{
|
||||
// _matchFinder.ReleaseStream();
|
||||
}
|
||||
|
||||
STDMETHODIMP CMatchFinderBinTree::MovePos()
|
||||
{ return _matchFinder.MovePos(); }
|
||||
|
||||
STDMETHODIMP_(BYTE) CMatchFinderBinTree::GetIndexByte(UINT32 index)
|
||||
{ return _matchFinder.GetIndexByte(index); }
|
||||
|
||||
STDMETHODIMP_(UINT32) CMatchFinderBinTree::GetMatchLen(UINT32 index,
|
||||
UINT32 back, UINT32 limit)
|
||||
{ return _matchFinder.GetMatchLen(index, back, limit); }
|
||||
|
||||
STDMETHODIMP_(UINT32) CMatchFinderBinTree::GetNumAvailableBytes()
|
||||
{ return _matchFinder.GetNumAvailableBytes(); }
|
||||
|
||||
STDMETHODIMP CMatchFinderBinTree::Create(UINT32 sizeHistory,
|
||||
UINT32 keepAddBufferBefore, UINT32 matchMaxLen,
|
||||
UINT32 keepAddBufferAfter)
|
||||
{
|
||||
UINT32 windowReservSize = (sizeHistory + keepAddBufferBefore +
|
||||
matchMaxLen + keepAddBufferAfter) / 2 + 256;
|
||||
try
|
||||
{
|
||||
return _matchFinder.Create(sizeHistory, keepAddBufferBefore,
|
||||
matchMaxLen, keepAddBufferAfter, windowReservSize);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP_(UINT32) CMatchFinderBinTree::GetLongestMatch(UINT32 *distances)
|
||||
{ return _matchFinder.GetLongestMatch(distances); }
|
||||
|
||||
STDMETHODIMP_(void) CMatchFinderBinTree::DummyLongestMatch()
|
||||
{ _matchFinder.DummyLongestMatch(); }
|
||||
|
||||
STDMETHODIMP_(const BYTE *) CMatchFinderBinTree::GetPointerToCurrentPos()
|
||||
{
|
||||
return _matchFinder.GetPointerToCurrentPos();
|
||||
}
|
||||
|
||||
// IMatchFinderSetCallback
|
||||
STDMETHODIMP CMatchFinderBinTree::SetCallback(IMatchFinderCallback *callback)
|
||||
{
|
||||
_matchFinder.SetCallback(callback);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
}
|
542
Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMain.h
Normal file
542
Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMain.h
Normal file
|
@ -0,0 +1,542 @@
|
|||
// BinTreemain.h
|
||||
|
||||
// #include "StdAfx.h"
|
||||
|
||||
// #include "BinTree.h"
|
||||
// #include "Common/NewHandler.h"
|
||||
|
||||
#include "../../../../Common/Defs.h"
|
||||
#include "../../../../Common/CRC.h"
|
||||
|
||||
namespace BT_NAMESPACE {
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
static const UINT32 kHash2Size = 1 << 10;
|
||||
#ifdef HASH_ARRAY_3
|
||||
static const UINT32 kNumHashDirectBytes = 0;
|
||||
static const UINT32 kNumHashBytes = 4;
|
||||
static const UINT32 kHash3Size = 1 << 18;
|
||||
#ifdef HASH_BIG
|
||||
static const UINT32 kHashSize = 1 << 23;
|
||||
#else
|
||||
static const UINT32 kHashSize = 1 << 20;
|
||||
#endif
|
||||
#else
|
||||
static const UINT32 kNumHashDirectBytes = 3;
|
||||
static const UINT32 kNumHashBytes = 3;
|
||||
static const UINT32 kHashSize = 1 << (8 * kNumHashBytes);
|
||||
#endif
|
||||
#else
|
||||
#ifdef HASH_ZIP
|
||||
static const UINT32 kNumHashDirectBytes = 0;
|
||||
static const UINT32 kNumHashBytes = 3;
|
||||
static const UINT32 kHashSize = 1 << 16;
|
||||
#else
|
||||
static const UINT32 kNumHashDirectBytes = 2;
|
||||
static const UINT32 kNumHashBytes = 2;
|
||||
static const UINT32 kHashSize = 1 << (8 * kNumHashBytes);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
CInTree::CInTree():
|
||||
#ifdef HASH_ARRAY_2
|
||||
_hash2(0),
|
||||
#ifdef HASH_ARRAY_3
|
||||
_hash3(0),
|
||||
#endif
|
||||
#endif
|
||||
_hash(0),
|
||||
_son(0),
|
||||
_cutValue(0xFF)
|
||||
{
|
||||
}
|
||||
|
||||
void CInTree::FreeMemory()
|
||||
{
|
||||
#ifdef WIN32
|
||||
if (_son != 0)
|
||||
VirtualFree(_son, 0, MEM_RELEASE);
|
||||
if (_hash != 0)
|
||||
VirtualFree(_hash, 0, MEM_RELEASE);
|
||||
#else
|
||||
delete []_son;
|
||||
delete []_hash;
|
||||
#endif
|
||||
_son = 0;
|
||||
_hash = 0;
|
||||
CLZInWindow::Free();
|
||||
}
|
||||
|
||||
CInTree::~CInTree()
|
||||
{
|
||||
FreeMemory();
|
||||
}
|
||||
|
||||
HRESULT CInTree::Create(UINT32 sizeHistory, UINT32 keepAddBufferBefore,
|
||||
UINT32 matchMaxLen, UINT32 keepAddBufferAfter, UINT32 sizeReserv)
|
||||
{
|
||||
FreeMemory();
|
||||
try
|
||||
{
|
||||
CLZInWindow::Create(sizeHistory + keepAddBufferBefore,
|
||||
matchMaxLen + keepAddBufferAfter, sizeReserv);
|
||||
|
||||
if (_blockSize + 256 > kMaxValForNormalize)
|
||||
return E_INVALIDARG;
|
||||
|
||||
_historySize = sizeHistory;
|
||||
_matchMaxLen = matchMaxLen;
|
||||
|
||||
_cyclicBufferSize = sizeHistory + 1;
|
||||
|
||||
|
||||
UINT32 size = kHashSize;
|
||||
#ifdef HASH_ARRAY_2
|
||||
size += kHash2Size;
|
||||
#ifdef HASH_ARRAY_3
|
||||
size += kHash3Size;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
_son = (CPair *)::VirtualAlloc(0, (_cyclicBufferSize + 1) * sizeof(CPair), MEM_COMMIT, PAGE_READWRITE);
|
||||
if (_son == 0)
|
||||
throw 1; // CNewException();
|
||||
_hash = (CIndex *)::VirtualAlloc(0, (size + 1) * sizeof(CIndex), MEM_COMMIT, PAGE_READWRITE);
|
||||
if (_hash == 0)
|
||||
throw 1; // CNewException();
|
||||
#else
|
||||
_son = new CPair[_cyclicBufferSize + 1];
|
||||
_hash = new CIndex[size + 1];
|
||||
#endif
|
||||
|
||||
// m_RightBase = &m_LeftBase[_blockSize];
|
||||
|
||||
// _hash = &m_RightBase[_blockSize];
|
||||
#ifdef HASH_ARRAY_2
|
||||
_hash2 = &_hash[kHashSize];
|
||||
#ifdef HASH_ARRAY_3
|
||||
_hash3 = &_hash2[kHash2Size];
|
||||
#endif
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
FreeMemory();
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
static const UINT32 kEmptyHashValue = 0;
|
||||
|
||||
HRESULT CInTree::Init(ISequentialInStream *stream)
|
||||
{
|
||||
RINOK(CLZInWindow::Init(stream));
|
||||
int i;
|
||||
for(i = 0; i < kHashSize; i++)
|
||||
_hash[i] = kEmptyHashValue;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
for(i = 0; i < kHash2Size; i++)
|
||||
_hash2[i] = kEmptyHashValue;
|
||||
#ifdef HASH_ARRAY_3
|
||||
for(i = 0; i < kHash3Size; i++)
|
||||
_hash3[i] = kEmptyHashValue;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
_cyclicBufferPos = 0;
|
||||
|
||||
ReduceOffsets(0 - 1);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
#ifdef HASH_ARRAY_3
|
||||
inline UINT32 Hash(const BYTE *pointer, UINT32 &hash2Value, UINT32 &hash3Value)
|
||||
{
|
||||
UINT32 temp = CCRC::Table[pointer[0]] ^ pointer[1];
|
||||
hash2Value = temp & (kHash2Size - 1);
|
||||
hash3Value = (temp ^ (UINT32(pointer[2]) << 8)) & (kHash3Size - 1);
|
||||
return (temp ^ (UINT32(pointer[2]) << 8) ^ (CCRC::Table[pointer[3]] << 5)) &
|
||||
(kHashSize - 1);
|
||||
}
|
||||
#else // no HASH_ARRAY_3
|
||||
inline UINT32 Hash(const BYTE *pointer, UINT32 &hash2Value)
|
||||
{
|
||||
hash2Value = (CCRC::Table[pointer[0]] ^ pointer[1]) & (kHash2Size - 1);
|
||||
return (*((const UINT32 *)pointer)) & 0xFFFFFF;
|
||||
}
|
||||
#endif // HASH_ARRAY_3
|
||||
#else // no HASH_ARRAY_2
|
||||
#ifdef HASH_ZIP
|
||||
inline UINT32 Hash(const BYTE *pointer)
|
||||
{
|
||||
return ((UINT32(pointer[0]) << 8) ^
|
||||
CCRC::Table[pointer[1]] ^ pointer[2]) & (kHashSize - 1);
|
||||
}
|
||||
#else // no HASH_ZIP
|
||||
inline UINT32 Hash(const BYTE *pointer)
|
||||
{
|
||||
return pointer[0] ^ (UINT32(pointer[1]) << 8);
|
||||
}
|
||||
#endif // HASH_ZIP
|
||||
#endif // HASH_ARRAY_2
|
||||
|
||||
UINT32 CInTree::GetLongestMatch(UINT32 *distances)
|
||||
{
|
||||
UINT32 currentLimit;
|
||||
if (_pos + _matchMaxLen <= _streamPos)
|
||||
currentLimit = _matchMaxLen;
|
||||
else
|
||||
{
|
||||
currentLimit = _streamPos - _pos;
|
||||
if(currentLimit < kNumHashBytes)
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT32 matchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1;
|
||||
BYTE *cur = _buffer + _pos;
|
||||
|
||||
UINT32 matchHashLenMax = 0;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
UINT32 hash2Value;
|
||||
#ifdef HASH_ARRAY_3
|
||||
UINT32 hash3Value;
|
||||
UINT32 hashValue = Hash(cur, hash2Value, hash3Value);
|
||||
#else
|
||||
UINT32 hashValue = Hash(cur, hash2Value);
|
||||
#endif
|
||||
#else
|
||||
UINT32 hashValue = Hash(cur);
|
||||
#endif
|
||||
|
||||
UINT32 curMatch = _hash[hashValue];
|
||||
#ifdef HASH_ARRAY_2
|
||||
UINT32 curMatch2 = _hash2[hash2Value];
|
||||
#ifdef HASH_ARRAY_3
|
||||
UINT32 curMatch3 = _hash3[hash3Value];
|
||||
#endif
|
||||
_hash2[hash2Value] = _pos;
|
||||
bool matchLen2Exist = false;
|
||||
UINT32 len2Distance = 0;
|
||||
if(curMatch2 >= matchMinPos)
|
||||
{
|
||||
if (_buffer[curMatch2] == cur[0])
|
||||
{
|
||||
len2Distance = _pos - curMatch2 - 1;
|
||||
matchHashLenMax = 2;
|
||||
matchLen2Exist = true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HASH_ARRAY_3
|
||||
_hash3[hash3Value] = _pos;
|
||||
UINT32 matchLen3Exist = false;
|
||||
UINT32 len3Distance = 0;
|
||||
if(curMatch3 >= matchMinPos)
|
||||
{
|
||||
if (_buffer[curMatch3] == cur[0])
|
||||
{
|
||||
len3Distance = _pos - curMatch3 - 1;
|
||||
matchHashLenMax = 3;
|
||||
matchLen3Exist = true;
|
||||
if (matchLen2Exist)
|
||||
{
|
||||
if (len3Distance < len2Distance)
|
||||
len2Distance = len3Distance;
|
||||
}
|
||||
else
|
||||
{
|
||||
len2Distance = len3Distance;
|
||||
matchLen2Exist = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
_hash[hashValue] = _pos;
|
||||
|
||||
if(curMatch < matchMinPos)
|
||||
{
|
||||
_son[_cyclicBufferPos].Left = kEmptyHashValue;
|
||||
_son[_cyclicBufferPos].Right = kEmptyHashValue;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
distances[2] = len2Distance;
|
||||
#ifdef HASH_ARRAY_3
|
||||
distances[3] = len3Distance;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return matchHashLenMax;
|
||||
}
|
||||
CIndex *ptrLeft = &_son[_cyclicBufferPos].Right;
|
||||
CIndex *ptrRight = &_son[_cyclicBufferPos].Left;
|
||||
|
||||
UINT32 maxLen, minSameLeft, minSameRight, minSame;
|
||||
maxLen = minSameLeft = minSameRight = minSame = kNumHashDirectBytes;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
#ifndef HASH_ARRAY_3
|
||||
if (matchLen2Exist)
|
||||
distances[2] = len2Distance;
|
||||
else
|
||||
if (kNumHashDirectBytes >= 2)
|
||||
distances[2] = _pos - curMatch - 1;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
distances[maxLen] = _pos - curMatch - 1;
|
||||
|
||||
for(UINT32 count = _cutValue; count > 0; count--)
|
||||
{
|
||||
BYTE *pby1 = _buffer + curMatch;
|
||||
// CIndex left = _son[curMatch].Left; // it's prefetch
|
||||
UINT32 currentLen;
|
||||
for(currentLen = minSame; currentLen < currentLimit; currentLen++/*, dwComps++*/)
|
||||
if (pby1[currentLen] != cur[currentLen])
|
||||
break;
|
||||
while (currentLen > maxLen)
|
||||
distances[++maxLen] = _pos - curMatch - 1;
|
||||
|
||||
UINT32 delta = _pos - curMatch;
|
||||
UINT32 cyclicPos = (delta <= _cyclicBufferPos) ?
|
||||
(_cyclicBufferPos - delta):
|
||||
(_cyclicBufferPos - delta + _cyclicBufferSize);
|
||||
|
||||
if (currentLen != currentLimit)
|
||||
{
|
||||
if (pby1[currentLen] < cur[currentLen])
|
||||
{
|
||||
*ptrRight = curMatch;
|
||||
ptrRight = &_son[cyclicPos].Right;
|
||||
curMatch = _son[cyclicPos].Right;
|
||||
if(currentLen > minSameLeft)
|
||||
{
|
||||
minSameLeft = currentLen;
|
||||
minSame = MyMin(minSameLeft, minSameRight);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptrLeft = curMatch;
|
||||
ptrLeft = &_son[cyclicPos].Left;
|
||||
// curMatch = left;
|
||||
curMatch = _son[cyclicPos].Left;
|
||||
if(currentLen > minSameRight)
|
||||
{
|
||||
minSameRight = currentLen;
|
||||
minSame = MyMin(minSameLeft, minSameRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(currentLen < _matchMaxLen)
|
||||
{
|
||||
*ptrLeft = curMatch;
|
||||
ptrLeft = &_son[cyclicPos].Left;
|
||||
curMatch = _son[cyclicPos].Left;
|
||||
if(currentLen > minSameRight)
|
||||
{
|
||||
minSameRight = currentLen;
|
||||
minSame = MyMin(minSameLeft, minSameRight);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptrLeft = _son[cyclicPos].Right;
|
||||
*ptrRight = _son[cyclicPos].Left;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
if (matchLen2Exist && len2Distance < distances[2])
|
||||
distances[2] = len2Distance;
|
||||
#ifdef HASH_ARRAY_3
|
||||
if (matchLen3Exist && len3Distance < distances[3])
|
||||
distances[3] = len3Distance;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return maxLen;
|
||||
}
|
||||
}
|
||||
if(curMatch < matchMinPos)
|
||||
break;
|
||||
}
|
||||
*ptrLeft = kEmptyHashValue;
|
||||
*ptrRight = kEmptyHashValue;
|
||||
#ifdef HASH_ARRAY_2
|
||||
if (matchLen2Exist)
|
||||
{
|
||||
if (maxLen < 2)
|
||||
{
|
||||
distances[2] = len2Distance;
|
||||
maxLen = 2;
|
||||
}
|
||||
else if (len2Distance < distances[2])
|
||||
distances[2] = len2Distance;
|
||||
}
|
||||
#ifdef HASH_ARRAY_3
|
||||
if (matchLen3Exist)
|
||||
{
|
||||
if (maxLen < 3)
|
||||
{
|
||||
distances[3] = len3Distance;
|
||||
maxLen = 3;
|
||||
}
|
||||
else if (len3Distance < distances[3])
|
||||
distances[3] = len3Distance;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return maxLen;
|
||||
}
|
||||
|
||||
void CInTree::DummyLongestMatch()
|
||||
{
|
||||
UINT32 currentLimit;
|
||||
if (_pos + _matchMaxLen <= _streamPos)
|
||||
currentLimit = _matchMaxLen;
|
||||
else
|
||||
{
|
||||
currentLimit = _streamPos - _pos;
|
||||
if(currentLimit < kNumHashBytes)
|
||||
return;
|
||||
}
|
||||
UINT32 matchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1;
|
||||
BYTE *cur = _buffer + _pos;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
UINT32 hash2Value;
|
||||
#ifdef HASH_ARRAY_3
|
||||
UINT32 hash3Value;
|
||||
UINT32 hashValue = Hash(cur, hash2Value, hash3Value);
|
||||
_hash3[hash3Value] = _pos;
|
||||
#else
|
||||
UINT32 hashValue = Hash(cur, hash2Value);
|
||||
#endif
|
||||
_hash2[hash2Value] = _pos;
|
||||
#else
|
||||
UINT32 hashValue = Hash(cur);
|
||||
#endif
|
||||
|
||||
UINT32 curMatch = _hash[hashValue];
|
||||
_hash[hashValue] = _pos;
|
||||
|
||||
if(curMatch < matchMinPos)
|
||||
{
|
||||
_son[_cyclicBufferPos].Left = kEmptyHashValue;
|
||||
_son[_cyclicBufferPos].Right = kEmptyHashValue;
|
||||
return;
|
||||
}
|
||||
CIndex *ptrLeft = &_son[_cyclicBufferPos].Right;
|
||||
CIndex *ptrRight = &_son[_cyclicBufferPos].Left;
|
||||
|
||||
UINT32 maxLen, minSameLeft, minSameRight, minSame;
|
||||
maxLen = minSameLeft = minSameRight = minSame = kNumHashDirectBytes;
|
||||
for(UINT32 count = _cutValue; count > 0; count--)
|
||||
{
|
||||
BYTE *pby1 = _buffer + curMatch;
|
||||
// CIndex left = _son[curMatch].Left; // it's prefetch
|
||||
UINT32 currentLen;
|
||||
for(currentLen = minSame; currentLen < currentLimit; currentLen++/*, dwComps++*/)
|
||||
if (pby1[currentLen] != cur[currentLen])
|
||||
break;
|
||||
|
||||
UINT32 delta = _pos - curMatch;
|
||||
UINT32 cyclicPos = (delta <= _cyclicBufferPos) ?
|
||||
(_cyclicBufferPos - delta):
|
||||
(_cyclicBufferPos - delta + _cyclicBufferSize);
|
||||
|
||||
if (currentLen != currentLimit)
|
||||
{
|
||||
if (pby1[currentLen] < cur[currentLen])
|
||||
{
|
||||
*ptrRight = curMatch;
|
||||
ptrRight = &_son[cyclicPos].Right;
|
||||
curMatch = _son[cyclicPos].Right;
|
||||
if(currentLen > minSameLeft)
|
||||
{
|
||||
minSameLeft = currentLen;
|
||||
minSame = MyMin(minSameLeft, minSameRight);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptrLeft = curMatch;
|
||||
ptrLeft = &_son[cyclicPos].Left;
|
||||
curMatch = _son[cyclicPos].Left;
|
||||
// curMatch = left;
|
||||
if(currentLen > minSameRight)
|
||||
{
|
||||
minSameRight = currentLen;
|
||||
minSame = MyMin(minSameLeft, minSameRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(currentLen < _matchMaxLen)
|
||||
{
|
||||
*ptrLeft = curMatch;
|
||||
ptrLeft = &_son[cyclicPos].Left;
|
||||
curMatch = _son[cyclicPos].Left;
|
||||
if(currentLen > minSameRight)
|
||||
{
|
||||
minSameRight = currentLen;
|
||||
minSame = MyMin(minSameLeft, minSameRight);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptrLeft = _son[cyclicPos].Right;
|
||||
*ptrRight = _son[cyclicPos].Left;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(curMatch < matchMinPos)
|
||||
break;
|
||||
}
|
||||
*ptrLeft = kEmptyHashValue;
|
||||
*ptrRight = kEmptyHashValue;
|
||||
}
|
||||
|
||||
void CInTree::NormalizeLinks(CIndex *array, UINT32 numItems, UINT32 subValue)
|
||||
{
|
||||
for (UINT32 i = 0; i < numItems; i++)
|
||||
{
|
||||
UINT32 value = array[i];
|
||||
if (value <= subValue)
|
||||
value = kEmptyHashValue;
|
||||
else
|
||||
value -= subValue;
|
||||
array[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void CInTree::Normalize()
|
||||
{
|
||||
UINT32 startItem = _pos - _historySize;
|
||||
UINT32 subValue = startItem - 1;
|
||||
// NormalizeLinks((CIndex *)(_son + startItem), _historySize * 2, subValue);
|
||||
NormalizeLinks((CIndex *)_son, _cyclicBufferSize * 2, subValue);
|
||||
|
||||
NormalizeLinks(_hash, kHashSize, subValue);
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
NormalizeLinks(_hash2, kHash2Size, subValue);
|
||||
#ifdef HASH_ARRAY_3
|
||||
NormalizeLinks(_hash3, kHash3Size, subValue);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ReduceOffsets(subValue);
|
||||
}
|
||||
|
||||
}
|
65
Source/7zip/7zip/Compress/LZ/IMatchFinder.h
Normal file
65
Source/7zip/7zip/Compress/LZ/IMatchFinder.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
// MatchFinders/IMatchFinder.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __IMATCHFINDER_H
|
||||
#define __IMATCHFINDER_H
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200010000}
|
||||
DEFINE_GUID(IID_IInWindowStream,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200010000")
|
||||
IInWindowStream: public IUnknown
|
||||
{
|
||||
STDMETHOD(Init)(ISequentialInStream *inStream) PURE;
|
||||
STDMETHOD_(void, ReleaseStream)() PURE;
|
||||
STDMETHOD(MovePos)() PURE;
|
||||
STDMETHOD_(BYTE, GetIndexByte)(UINT32 index) PURE;
|
||||
STDMETHOD_(UINT32, GetMatchLen)(UINT32 index, UINT32 distance, UINT32 limit) PURE;
|
||||
STDMETHOD_(UINT32, GetNumAvailableBytes)() PURE;
|
||||
STDMETHOD_(const BYTE *, GetPointerToCurrentPos)() PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200020000}
|
||||
DEFINE_GUID(IID_IMatchFinder,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020000")
|
||||
IMatchFinder: public IInWindowStream
|
||||
{
|
||||
STDMETHOD(Create)(UINT32 historySize, UINT32 keepAddBufferBefore,
|
||||
UINT32 matchMaxLen, UINT32 keepAddBufferAfter) PURE;
|
||||
STDMETHOD_(UINT32, GetLongestMatch)(UINT32 *distances) PURE;
|
||||
STDMETHOD_(void, DummyLongestMatch)() PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200020100}
|
||||
DEFINE_GUID(IID_IMatchFinderCallback,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x01, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020100")
|
||||
IMatchFinderCallback: public IUnknown
|
||||
{
|
||||
STDMETHOD(BeforeChangingBufferPos)() PURE;
|
||||
STDMETHOD(AfterChangingBufferPos)() PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200020200}
|
||||
DEFINE_GUID(IID_IMatchFinderSetCallback,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x02, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020200")
|
||||
IMatchFinderSetCallback: public IUnknown
|
||||
{
|
||||
STDMETHOD(SetCallback)(IMatchFinderCallback *callback) PURE;
|
||||
};
|
||||
|
||||
/*
|
||||
// {23170F69-40C1-278A-0000-000200030000}
|
||||
DEFINE_GUID(IID_IInitMatchFinder,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200030000")
|
||||
IMatchFinderInit: public IUnknown
|
||||
{
|
||||
STDMETHOD(InitMatchFinder)(IMatchFinder *matchFinder) PURE;
|
||||
};
|
||||
*/
|
||||
|
||||
#endif
|
98
Source/7zip/7zip/Compress/LZ/LZInWindow.cpp
Normal file
98
Source/7zip/7zip/Compress/LZ/LZInWindow.cpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
// LZInWindow.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "LZInWindow.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
CLZInWindow::~CLZInWindow()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
|
||||
void CLZInWindow::Free()
|
||||
{
|
||||
delete []_bufferBase;
|
||||
_bufferBase = 0;
|
||||
}
|
||||
|
||||
void CLZInWindow::Create(UINT32 keepSizeBefore, UINT32 keepSizeAfter, UINT32 keepSizeReserv)
|
||||
{
|
||||
_keepSizeBefore = keepSizeBefore;
|
||||
_keepSizeAfter = keepSizeAfter;
|
||||
_keepSizeReserv = keepSizeReserv;
|
||||
_blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
|
||||
Free();
|
||||
_bufferBase = new BYTE[_blockSize];
|
||||
_pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CLZInWindow::Init(ISequentialInStream *stream)
|
||||
{
|
||||
_stream = stream;
|
||||
_buffer = _bufferBase;
|
||||
_pos = 0;
|
||||
_streamPos = 0;
|
||||
_streamEndWasReached = false;
|
||||
return ReadBlock();
|
||||
}
|
||||
|
||||
/*
|
||||
void CLZInWindow::ReleaseStream()
|
||||
{
|
||||
_stream.Release();
|
||||
}
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////
|
||||
// ReadBlock
|
||||
|
||||
// In State:
|
||||
// (_buffer + _streamPos) <= (_bufferBase + _blockSize)
|
||||
// Out State:
|
||||
// _posLimit <= _blockSize - _keepSizeAfter;
|
||||
// if(_streamEndWasReached == false):
|
||||
// _streamPos >= _pos + _keepSizeAfter
|
||||
// _posLimit = _streamPos - _keepSizeAfter;
|
||||
// else
|
||||
//
|
||||
|
||||
HRESULT CLZInWindow::ReadBlock()
|
||||
{
|
||||
if(_streamEndWasReached)
|
||||
return S_OK;
|
||||
while(true)
|
||||
{
|
||||
UINT32 size = (_bufferBase + _blockSize) - (_buffer + _streamPos);
|
||||
if(size == 0)
|
||||
return S_OK;
|
||||
UINT32 numReadBytes;
|
||||
RINOK(_stream->ReadPart(_buffer + _streamPos, size, &numReadBytes));
|
||||
if(numReadBytes == 0)
|
||||
{
|
||||
_posLimit = _streamPos;
|
||||
const BYTE *pointerToPostion = _buffer + _posLimit;
|
||||
if(pointerToPostion > _pointerToLastSafePosition)
|
||||
_posLimit = _pointerToLastSafePosition - _buffer;
|
||||
_streamEndWasReached = true;
|
||||
return S_OK;
|
||||
}
|
||||
_streamPos += numReadBytes;
|
||||
if(_streamPos >= _pos + _keepSizeAfter)
|
||||
{
|
||||
_posLimit = _streamPos - _keepSizeAfter;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLZInWindow::MoveBlock()
|
||||
{
|
||||
BeforeMoveBlock();
|
||||
UINT32 offset = (_buffer + _pos - _keepSizeBefore) - _bufferBase;
|
||||
UINT32 numBytes = (_buffer + _streamPos) - (_bufferBase + offset);
|
||||
memmove(_bufferBase, _bufferBase + offset, numBytes);
|
||||
_buffer -= offset;
|
||||
AfterMoveBlock();
|
||||
}
|
89
Source/7zip/7zip/Compress/LZ/LZInWindow.h
Normal file
89
Source/7zip/7zip/Compress/LZ/LZInWindow.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
// LZInWindow.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __LZ_IN_WINDOW_H
|
||||
#define __LZ_IN_WINDOW_H
|
||||
|
||||
#include "../../IStream.h"
|
||||
|
||||
class CLZInWindow
|
||||
{
|
||||
BYTE *_bufferBase; // pointer to buffer with data
|
||||
ISequentialInStream *_stream;
|
||||
UINT32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
|
||||
bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
|
||||
const BYTE *_pointerToLastSafePosition;
|
||||
protected:
|
||||
BYTE *_buffer; // Pointer to virtual Buffer begin
|
||||
UINT32 _blockSize; // Size of Allocated memory block
|
||||
UINT32 _pos; // offset (from _buffer) of curent byte
|
||||
UINT32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
|
||||
UINT32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
|
||||
UINT32 _keepSizeReserv; // how many BYTEs must be kept as reserv
|
||||
UINT32 _streamPos; // offset (from _buffer) of first not read byte from Stream
|
||||
|
||||
virtual void BeforeMoveBlock() {};
|
||||
virtual void AfterMoveBlock() {};
|
||||
void MoveBlock();
|
||||
virtual HRESULT ReadBlock();
|
||||
void Free();
|
||||
public:
|
||||
CLZInWindow(): _bufferBase(0) {}
|
||||
~CLZInWindow();
|
||||
void Create(UINT32 keepSizeBefore, UINT32 keepSizeAfter,
|
||||
UINT32 keepSizeReserv = (1<<17));
|
||||
|
||||
HRESULT Init(ISequentialInStream *stream);
|
||||
// void ReleaseStream();
|
||||
|
||||
BYTE *GetBuffer() const { return _buffer; }
|
||||
|
||||
const BYTE *GetPointerToCurrentPos() const { return _buffer + _pos; }
|
||||
|
||||
HRESULT MovePos()
|
||||
{
|
||||
_pos++;
|
||||
if (_pos > _posLimit)
|
||||
{
|
||||
const BYTE *pointerToPostion = _buffer + _pos;
|
||||
if(pointerToPostion > _pointerToLastSafePosition)
|
||||
MoveBlock();
|
||||
return ReadBlock();
|
||||
}
|
||||
else
|
||||
return S_OK;
|
||||
}
|
||||
// BYTE GetCurrentByte()const;
|
||||
BYTE GetIndexByte(UINT32 index)const
|
||||
{ return _buffer[_pos + index]; }
|
||||
|
||||
// UINT32 GetCurPos()const { return _pos;};
|
||||
// BYTE *GetBufferBeg()const { return _buffer;};
|
||||
|
||||
// index + limit have not to exceed _keepSizeAfter;
|
||||
UINT32 GetMatchLen(UINT32 index, UINT32 back, UINT32 limit) const
|
||||
{
|
||||
if(_streamEndWasReached)
|
||||
if ((_pos + index) + limit > _streamPos)
|
||||
limit = _streamPos - (_pos + index);
|
||||
back++;
|
||||
BYTE *pby = _buffer + _pos + index;
|
||||
UINT32 i;
|
||||
for(i = 0; i < limit && pby[i] == pby[i - back]; i++);
|
||||
return i;
|
||||
}
|
||||
|
||||
UINT32 GetNumAvailableBytes() const { return _streamPos - _pos; }
|
||||
|
||||
void ReduceOffsets(UINT32 subValue)
|
||||
{
|
||||
_buffer += subValue;
|
||||
_posLimit -= subValue;
|
||||
_pos -= subValue;
|
||||
_streamPos -= subValue;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
83
Source/7zip/7zip/Compress/LZ/LZOutWindow.cpp
Normal file
83
Source/7zip/7zip/Compress/LZ/LZOutWindow.cpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
// LZOutWindow.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "LZOutWindow.h"
|
||||
|
||||
void CLZOutWindow::Create(UINT32 windowSize)
|
||||
{
|
||||
_pos = 0;
|
||||
_streamPos = 0;
|
||||
UINT32 newBlockSize = windowSize;
|
||||
const UINT32 kMinBlockSize = 1;
|
||||
if (newBlockSize < kMinBlockSize)
|
||||
newBlockSize = kMinBlockSize;
|
||||
if (_buffer != 0 && _windowSize == newBlockSize)
|
||||
return;
|
||||
delete []_buffer;
|
||||
_buffer = 0;
|
||||
_windowSize = newBlockSize;
|
||||
_buffer = new BYTE[_windowSize];
|
||||
}
|
||||
|
||||
CLZOutWindow::~CLZOutWindow()
|
||||
{
|
||||
// ReleaseStream();
|
||||
delete []_buffer;
|
||||
}
|
||||
|
||||
/*
|
||||
void CLZOutWindow::SetWindowSize(UINT32 windowSize)
|
||||
{
|
||||
_windowSize = windowSize;
|
||||
}
|
||||
*/
|
||||
|
||||
void CLZOutWindow::Init(ISequentialOutStream *stream, bool solid)
|
||||
{
|
||||
// ReleaseStream();
|
||||
_stream = stream;
|
||||
// _stream->AddRef();
|
||||
|
||||
if(!solid)
|
||||
{
|
||||
_streamPos = 0;
|
||||
_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void CLZOutWindow::ReleaseStream()
|
||||
{
|
||||
if(_stream != 0)
|
||||
{
|
||||
// Flush(); // Test it
|
||||
_stream->Release();
|
||||
_stream = 0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void CLZOutWindow::FlushWithCheck()
|
||||
{
|
||||
HRESULT result = Flush();
|
||||
if (result != S_OK)
|
||||
throw CLZOutWindowException(result);
|
||||
}
|
||||
|
||||
HRESULT CLZOutWindow::Flush()
|
||||
{
|
||||
UINT32 size = _pos - _streamPos;
|
||||
if(size == 0)
|
||||
return S_OK;
|
||||
UINT32 processedSize;
|
||||
HRESULT result = _stream->Write(_buffer + _streamPos, size, &processedSize);
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
if (size != processedSize)
|
||||
return E_FAIL;
|
||||
if (_pos >= _windowSize)
|
||||
_pos = 0;
|
||||
_streamPos = _pos;
|
||||
return S_OK;
|
||||
}
|
78
Source/7zip/7zip/Compress/LZ/LZOutWindow.h
Normal file
78
Source/7zip/7zip/Compress/LZ/LZOutWindow.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
// LZOutWindow.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __LZ_OUT_WINDOW_H
|
||||
#define __LZ_OUT_WINDOW_H
|
||||
|
||||
#include "../../IStream.h"
|
||||
|
||||
// m_KeepSizeBefore: how mach BYTEs must be in buffer before _pos;
|
||||
// m_KeepSizeAfter: how mach BYTEs must be in buffer after _pos;
|
||||
// m_KeepSizeReserv: how mach BYTEs must be in buffer for Moving Reserv;
|
||||
// must be >= aKeepSizeAfter; // test it
|
||||
|
||||
class CLZOutWindowException
|
||||
{
|
||||
public:
|
||||
HRESULT ErrorCode;
|
||||
CLZOutWindowException(HRESULT errorCode): ErrorCode(errorCode) {}
|
||||
};
|
||||
|
||||
class CLZOutWindow
|
||||
{
|
||||
BYTE *_buffer;
|
||||
UINT32 _pos;
|
||||
UINT32 _windowSize;
|
||||
UINT32 _streamPos;
|
||||
ISequentialOutStream *_stream;
|
||||
void FlushWithCheck();
|
||||
|
||||
public:
|
||||
CLZOutWindow(): _buffer(0), _stream(0) {}
|
||||
~CLZOutWindow();
|
||||
void Create(UINT32 windowSize);
|
||||
bool IsCreated() const { return _buffer != 0; }
|
||||
|
||||
void Init(ISequentialOutStream *stream, bool solid = false);
|
||||
HRESULT Flush();
|
||||
// void ReleaseStream();
|
||||
|
||||
// UINT32 GetCurPos() const { return _pos; }
|
||||
// const BYTE *GetPointerToCurrentPos() const { return _buffer + _pos;};
|
||||
|
||||
void CopyBackBlock(UINT32 distance, UINT32 len)
|
||||
{
|
||||
UINT32 pos = _pos - distance - 1;
|
||||
if (pos >= _windowSize)
|
||||
pos += _windowSize;
|
||||
for(; len > 0; len--)
|
||||
{
|
||||
if (pos >= _windowSize)
|
||||
pos = 0;
|
||||
_buffer[_pos++] = _buffer[pos++];
|
||||
if (_pos >= _windowSize)
|
||||
FlushWithCheck();
|
||||
// PutOneByte(GetOneByte(0 - distance));
|
||||
}
|
||||
}
|
||||
|
||||
void PutOneByte(BYTE b)
|
||||
{
|
||||
_buffer[_pos++] = b;
|
||||
if (_pos >= _windowSize)
|
||||
FlushWithCheck();
|
||||
}
|
||||
|
||||
BYTE GetOneByte(UINT32 index) const
|
||||
{
|
||||
UINT32 pos = _pos + index;
|
||||
if (pos >= _windowSize)
|
||||
pos += _windowSize;
|
||||
return _buffer[pos];
|
||||
}
|
||||
|
||||
// BYTE *GetBuffer() const { return _buffer; }
|
||||
};
|
||||
|
||||
#endif
|
8
Source/7zip/7zip/Compress/LZ/StdAfx.h
Normal file
8
Source/7zip/7zip/Compress/LZ/StdAfx.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#endif
|
96
Source/7zip/7zip/Compress/LZMA/LZMA.h
Normal file
96
Source/7zip/7zip/Compress/LZMA/LZMA.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
// LZMA.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#include "LZMALen.h"
|
||||
|
||||
#ifndef __LZMA_H
|
||||
#define __LZMA_H
|
||||
|
||||
namespace NCompress {
|
||||
namespace NLZMA {
|
||||
|
||||
const UINT32 kNumRepDistances = 4;
|
||||
|
||||
const BYTE kNumStates = 12;
|
||||
|
||||
const BYTE kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
|
||||
const BYTE kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
|
||||
const BYTE kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
|
||||
const BYTE kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
|
||||
|
||||
class CState
|
||||
{
|
||||
public:
|
||||
BYTE Index;
|
||||
void Init()
|
||||
{ Index = 0; }
|
||||
void UpdateChar()
|
||||
{ Index = kLiteralNextStates[Index]; }
|
||||
void UpdateMatch()
|
||||
{ Index = kMatchNextStates[Index]; }
|
||||
void UpdateRep()
|
||||
{ Index = kRepNextStates[Index]; }
|
||||
void UpdateShortRep()
|
||||
{ Index = kShortRepNextStates[Index]; }
|
||||
};
|
||||
|
||||
class CBaseCoder
|
||||
{
|
||||
protected:
|
||||
CState _state;
|
||||
BYTE _previousByte;
|
||||
bool _peviousIsMatch;
|
||||
UINT32 _repDistances[kNumRepDistances];
|
||||
void Init()
|
||||
{
|
||||
_state.Init();
|
||||
_previousByte = 0;
|
||||
_peviousIsMatch = false;
|
||||
for(int i = 0 ; i < kNumRepDistances; i++)
|
||||
_repDistances[i] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
const int kNumPosSlotBits = 6;
|
||||
const int kDicLogSizeMin = 0;
|
||||
const int kDicLogSizeMax = 32;
|
||||
const int kDistTableSizeMax = kDicLogSizeMax * 2;
|
||||
|
||||
const UINT32 kNumLenToPosStates = 4;
|
||||
inline UINT32 GetLenToPosState(UINT32 len)
|
||||
{
|
||||
len -= 2;
|
||||
if (len < kNumLenToPosStates)
|
||||
return len;
|
||||
return kNumLenToPosStates - 1;
|
||||
}
|
||||
|
||||
const UINT32 kMatchMinLen = 2;
|
||||
|
||||
const UINT32 kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1;
|
||||
|
||||
const int kNumAlignBits = 4;
|
||||
const UINT32 kAlignTableSize = 1 << kNumAlignBits;
|
||||
const UINT32 kAlignMask = (kAlignTableSize - 1);
|
||||
|
||||
const UINT32 kStartPosModelIndex = 4;
|
||||
const UINT32 kEndPosModelIndex = 14;
|
||||
const UINT32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
|
||||
|
||||
const UINT32 kNumFullDistances = 1 << (kEndPosModelIndex / 2);
|
||||
|
||||
const UINT32 kMainChoiceLiteralIndex = 0;
|
||||
const UINT32 kMainChoiceMatchIndex = 1;
|
||||
|
||||
const UINT32 kMatchChoiceDistanceIndex= 0;
|
||||
const UINT32 kMatchChoiceRepetitionIndex = 1;
|
||||
|
||||
const int kNumMoveBits = 5;
|
||||
|
||||
const int kNumLitPosStatesBitsEncodingMax = 4;
|
||||
const int kNumLitContextBitsMax = 8;
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
356
Source/7zip/7zip/Compress/LZMA/LZMADecoder.cpp
Normal file
356
Source/7zip/7zip/Compress/LZMA/LZMADecoder.cpp
Normal file
|
@ -0,0 +1,356 @@
|
|||
// LZMADecoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "LZMADecoder.h"
|
||||
#include "../../../Common/Defs.h"
|
||||
#include "../../../Common/ComTry.h"
|
||||
|
||||
/*
|
||||
#include "fstream.h"
|
||||
#include "iomanip.h"
|
||||
|
||||
ofstream ofs("res.dat");
|
||||
|
||||
const kNumCounters = 3;
|
||||
UINT32 g_Counter[kNumCounters];
|
||||
class C1
|
||||
{
|
||||
public:
|
||||
~C1()
|
||||
{
|
||||
for (int i = 0; i < kNumCounters; i++)
|
||||
ofs << setw(10) << g_Counter[i] << endl;
|
||||
}
|
||||
} g_C1;
|
||||
*/
|
||||
|
||||
/*
|
||||
const UINT32 kLenTableMax = 20;
|
||||
const UINT32 kNumDists = NCompress::NLZMA::kDistTableSizeMax / 2;
|
||||
UINT32 g_Counts[kLenTableMax][kNumDists];
|
||||
class C1
|
||||
{
|
||||
public:
|
||||
~C1 ()
|
||||
{
|
||||
UINT32 sums[kLenTableMax];
|
||||
for (int len = 2; len < kLenTableMax; len++)
|
||||
{
|
||||
sums[len] = 0;
|
||||
for (int dist = 0; dist < kNumDists; dist++)
|
||||
sums[len] += g_Counts[len][dist];
|
||||
if (sums[len] == 0)
|
||||
sums[len] = 1;
|
||||
}
|
||||
for (int dist = 0; dist < kNumDists; dist++)
|
||||
{
|
||||
ofs << setw(4) << dist << " ";
|
||||
for (int len = 2; len < kLenTableMax; len++)
|
||||
{
|
||||
ofs << setw(4) << g_Counts[len][dist] * 1000 / sums[len];
|
||||
}
|
||||
ofs << endl;
|
||||
}
|
||||
}
|
||||
} g_Class;
|
||||
|
||||
void UpdateStat(UINT32 len, UINT32 dist)
|
||||
{
|
||||
if (len >= kLenTableMax)
|
||||
len = kLenTableMax - 1;
|
||||
g_Counts[len][dist / 2]++;
|
||||
}
|
||||
*/
|
||||
|
||||
namespace NCompress {
|
||||
namespace NLZMA {
|
||||
|
||||
HRESULT CDecoder::SetDictionarySize(UINT32 dictionarySize)
|
||||
{
|
||||
if (_dictionarySize != dictionarySize)
|
||||
{
|
||||
_dictionarySize = dictionarySize;
|
||||
_dictionarySizeCheck = MyMax(_dictionarySize, UINT32(1));
|
||||
UINT32 blockSize = MyMax(_dictionarySizeCheck, UINT32(1 << 12));
|
||||
try
|
||||
{
|
||||
_outWindowStream.Create(blockSize /*, kMatchMaxLen */);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::SetLiteralProperties(
|
||||
UINT32 numLiteralPosStateBits, UINT32 numLiteralContextBits)
|
||||
{
|
||||
if (numLiteralPosStateBits > 8)
|
||||
return E_INVALIDARG;
|
||||
if (numLiteralContextBits > 8)
|
||||
return E_INVALIDARG;
|
||||
_literalDecoder.Create(numLiteralPosStateBits, numLiteralContextBits);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::SetPosBitsProperties(UINT32 numPosStateBits)
|
||||
{
|
||||
if (numPosStateBits > NLength::kNumPosStatesBitsMax)
|
||||
return E_INVALIDARG;
|
||||
UINT32 numPosStates = 1 << numPosStateBits;
|
||||
_lenDecoder.Create(numPosStates);
|
||||
_repMatchLenDecoder.Create(numPosStates);
|
||||
_posStateMask = numPosStates - 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
CDecoder::CDecoder():
|
||||
_dictionarySize((UINT32)-1)
|
||||
{
|
||||
Create();
|
||||
}
|
||||
|
||||
HRESULT CDecoder::Create()
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
for(int i = 0; i < kNumPosModels; i++)
|
||||
_posDecoders[i].Create(((kStartPosModelIndex + i) >> 1) - 1);
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CDecoder::Init(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream)
|
||||
{
|
||||
_rangeDecoder.Init(inStream);
|
||||
|
||||
_outWindowStream.Init(outStream);
|
||||
|
||||
int i;
|
||||
for(i = 0; i < kNumStates; i++)
|
||||
{
|
||||
for (UINT32 j = 0; j <= _posStateMask; j++)
|
||||
{
|
||||
_mainChoiceDecoders[i][j].Init();
|
||||
_matchRepShortChoiceDecoders[i][j].Init();
|
||||
}
|
||||
_matchChoiceDecoders[i].Init();
|
||||
_matchRepChoiceDecoders[i].Init();
|
||||
_matchRep1ChoiceDecoders[i].Init();
|
||||
_matchRep2ChoiceDecoders[i].Init();
|
||||
}
|
||||
|
||||
_literalDecoder.Init();
|
||||
|
||||
// _repMatchLenDecoder.Init();
|
||||
|
||||
for (i = 0; i < kNumLenToPosStates; i++)
|
||||
_posSlotDecoder[i].Init();
|
||||
|
||||
for(i = 0; i < kNumPosModels; i++)
|
||||
_posDecoders[i].Init();
|
||||
|
||||
_lenDecoder.Init();
|
||||
_repMatchLenDecoder.Init();
|
||||
|
||||
_posAlignDecoder.Init();
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
/*
|
||||
if (outSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
*/
|
||||
|
||||
Init(inStream, outStream);
|
||||
CDecoderFlusher flusher(this);
|
||||
|
||||
CState state;
|
||||
state.Init();
|
||||
bool peviousIsMatch = false;
|
||||
BYTE previousByte = 0;
|
||||
UINT32 repDistances[kNumRepDistances];
|
||||
for(int i = 0 ; i < kNumRepDistances; i++)
|
||||
repDistances[i] = 0;
|
||||
|
||||
UINT64 nowPos64 = 0;
|
||||
UINT64 size = (outSize == NULL) ? (UINT64)(INT64)(-1) : *outSize;
|
||||
while(nowPos64 < size)
|
||||
{
|
||||
UINT64 nextPos = MyMin(nowPos64 + (1 << 18), size);
|
||||
while(nowPos64 < nextPos)
|
||||
{
|
||||
UINT32 posState = UINT32(nowPos64) & _posStateMask;
|
||||
if (_mainChoiceDecoders[state.Index][posState].Decode(&_rangeDecoder) == kMainChoiceLiteralIndex)
|
||||
{
|
||||
state.UpdateChar();
|
||||
if(peviousIsMatch)
|
||||
{
|
||||
BYTE matchByte = _outWindowStream.GetOneByte(0 - repDistances[0] - 1);
|
||||
previousByte = _literalDecoder.DecodeWithMatchByte(&_rangeDecoder,
|
||||
UINT32(nowPos64), previousByte, matchByte);
|
||||
peviousIsMatch = false;
|
||||
}
|
||||
else
|
||||
previousByte = _literalDecoder.DecodeNormal(&_rangeDecoder,
|
||||
UINT32(nowPos64), previousByte);
|
||||
_outWindowStream.PutOneByte(previousByte);
|
||||
nowPos64++;
|
||||
}
|
||||
else
|
||||
{
|
||||
peviousIsMatch = true;
|
||||
UINT32 distance, len;
|
||||
if(_matchChoiceDecoders[state.Index].Decode(&_rangeDecoder) ==
|
||||
kMatchChoiceRepetitionIndex)
|
||||
{
|
||||
if(_matchRepChoiceDecoders[state.Index].Decode(&_rangeDecoder) == 0)
|
||||
{
|
||||
if(_matchRepShortChoiceDecoders[state.Index][posState].Decode(&_rangeDecoder) == 0)
|
||||
{
|
||||
state.UpdateShortRep();
|
||||
previousByte = _outWindowStream.GetOneByte(0 - repDistances[0] - 1);
|
||||
_outWindowStream.PutOneByte(previousByte);
|
||||
nowPos64++;
|
||||
continue;
|
||||
}
|
||||
distance = repDistances[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if(_matchRep1ChoiceDecoders[state.Index].Decode(&_rangeDecoder) == 0)
|
||||
distance = repDistances[1];
|
||||
else
|
||||
{
|
||||
if (_matchRep2ChoiceDecoders[state.Index].Decode(&_rangeDecoder) == 0)
|
||||
distance = repDistances[2];
|
||||
else
|
||||
{
|
||||
distance = repDistances[3];
|
||||
repDistances[3] = repDistances[2];
|
||||
}
|
||||
repDistances[2] = repDistances[1];
|
||||
}
|
||||
repDistances[1] = repDistances[0];
|
||||
repDistances[0] = distance;
|
||||
}
|
||||
len = _repMatchLenDecoder.Decode(&_rangeDecoder, posState) + kMatchMinLen;
|
||||
state.UpdateRep();
|
||||
}
|
||||
else
|
||||
{
|
||||
len = kMatchMinLen + _lenDecoder.Decode(&_rangeDecoder, posState);
|
||||
state.UpdateMatch();
|
||||
UINT32 posSlot = _posSlotDecoder[GetLenToPosState(len)].Decode(&_rangeDecoder);
|
||||
if (posSlot >= kStartPosModelIndex)
|
||||
{
|
||||
UINT32 numDirectBits = (posSlot >> 1) - 1;
|
||||
distance = ((2 | (posSlot & 1)) << numDirectBits);
|
||||
|
||||
if (posSlot < kEndPosModelIndex)
|
||||
distance += _posDecoders[posSlot - kStartPosModelIndex].Decode(&_rangeDecoder);
|
||||
else
|
||||
{
|
||||
distance += (_rangeDecoder.DecodeDirectBits(
|
||||
numDirectBits - kNumAlignBits) << kNumAlignBits);
|
||||
distance += _posAlignDecoder.Decode(&_rangeDecoder);
|
||||
}
|
||||
}
|
||||
else
|
||||
distance = posSlot;
|
||||
|
||||
repDistances[3] = repDistances[2];
|
||||
repDistances[2] = repDistances[1];
|
||||
repDistances[1] = repDistances[0];
|
||||
repDistances[0] = distance;
|
||||
// UpdateStat(len, posSlot);
|
||||
}
|
||||
if (distance >= nowPos64 || distance >= _dictionarySizeCheck)
|
||||
{
|
||||
if (distance == (UINT32)(-1) && size == (UINT64)(INT64)(-1))
|
||||
{
|
||||
flusher.NeedFlush = false;
|
||||
return Flush();
|
||||
}
|
||||
throw "data error";
|
||||
}
|
||||
_outWindowStream.CopyBackBlock(distance, len);
|
||||
nowPos64 += len;
|
||||
previousByte = _outWindowStream.GetOneByte(0 - 1);
|
||||
}
|
||||
}
|
||||
if (progress != NULL)
|
||||
{
|
||||
UINT64 inSize = _rangeDecoder.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
|
||||
}
|
||||
}
|
||||
flusher.NeedFlush = false;
|
||||
return Flush();
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(const CLZOutWindowException &e) { return e.ErrorCode; }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
|
||||
static HRESULT DecodeProperties(ISequentialInStream *inStream,
|
||||
UINT32 &numPosStateBits,
|
||||
UINT32 &numLiteralPosStateBits,
|
||||
UINT32 &numLiteralContextBits,
|
||||
UINT32 &dictionarySize)
|
||||
{
|
||||
UINT32 processesedSize;
|
||||
|
||||
BYTE firstByte;
|
||||
RINOK(inStream->Read(&firstByte, sizeof(firstByte), &processesedSize));
|
||||
if (processesedSize != sizeof(firstByte))
|
||||
return E_INVALIDARG;
|
||||
|
||||
numLiteralContextBits = firstByte % 9;
|
||||
BYTE remainder = firstByte / 9;
|
||||
numLiteralPosStateBits = remainder % 5;
|
||||
numPosStateBits = remainder / 5;
|
||||
|
||||
RINOK(inStream->Read(&dictionarySize, sizeof(dictionarySize), &processesedSize));
|
||||
if (processesedSize != sizeof(dictionarySize))
|
||||
return E_INVALIDARG;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream)
|
||||
{
|
||||
UINT32 numPosStateBits;
|
||||
UINT32 numLiteralPosStateBits;
|
||||
UINT32 numLiteralContextBits;
|
||||
UINT32 dictionarySize;
|
||||
RINOK(DecodeProperties(inStream,
|
||||
numPosStateBits,
|
||||
numLiteralPosStateBits,
|
||||
numLiteralContextBits,
|
||||
dictionarySize));
|
||||
RINOK(SetDictionarySize(dictionarySize));
|
||||
RINOK(SetLiteralProperties(numLiteralPosStateBits, numLiteralContextBits));
|
||||
RINOK(SetPosBitsProperties(numPosStateBits));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
107
Source/7zip/7zip/Compress/LZMA/LZMADecoder.h
Normal file
107
Source/7zip/7zip/Compress/LZMA/LZMADecoder.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
// LZMA/Decoder.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __LZMA_DECODER_H
|
||||
#define __LZMA_DECODER_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../LZ/LZOutWindow.h"
|
||||
|
||||
#include "LZMA.h"
|
||||
#include "LZMALen.h"
|
||||
#include "LZMALiteral.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NLZMA {
|
||||
|
||||
typedef NRangeCoder::CBitDecoder<kNumMoveBits> CMyBitDecoder;
|
||||
|
||||
class CDecoder:
|
||||
public ICompressCoder,
|
||||
public ICompressSetDecoderProperties,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CLZOutWindow _outWindowStream;
|
||||
NRangeCoder::CDecoder _rangeDecoder;
|
||||
|
||||
CMyBitDecoder _mainChoiceDecoders[kNumStates][NLength::kNumPosStatesMax];
|
||||
CMyBitDecoder _matchChoiceDecoders[kNumStates];
|
||||
CMyBitDecoder _matchRepChoiceDecoders[kNumStates];
|
||||
CMyBitDecoder _matchRep1ChoiceDecoders[kNumStates];
|
||||
CMyBitDecoder _matchRep2ChoiceDecoders[kNumStates];
|
||||
CMyBitDecoder _matchRepShortChoiceDecoders[kNumStates][NLength::kNumPosStatesMax];
|
||||
|
||||
NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumPosSlotBits> _posSlotDecoder[kNumLenToPosStates];
|
||||
|
||||
NRangeCoder::CReverseBitTreeDecoder2<kNumMoveBits> _posDecoders[kNumPosModels];
|
||||
NRangeCoder::CReverseBitTreeDecoder<kNumMoveBits, kNumAlignBits> _posAlignDecoder;
|
||||
|
||||
NLength::CDecoder _lenDecoder;
|
||||
NLength::CDecoder _repMatchLenDecoder;
|
||||
|
||||
NLiteral::CDecoder _literalDecoder;
|
||||
|
||||
UINT32 _dictionarySize;
|
||||
UINT32 _dictionarySizeCheck;
|
||||
|
||||
UINT32 _posStateMask;
|
||||
|
||||
public:
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressSetDecoderProperties)
|
||||
|
||||
CDecoder();
|
||||
HRESULT Create();
|
||||
|
||||
|
||||
HRESULT Init(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream);
|
||||
/*
|
||||
void ReleaseStreams()
|
||||
{
|
||||
_outWindowStream.ReleaseStream();
|
||||
_rangeDecoder.ReleaseStream();
|
||||
}
|
||||
*/
|
||||
|
||||
class CDecoderFlusher
|
||||
{
|
||||
CDecoder *_decoder;
|
||||
public:
|
||||
bool NeedFlush;
|
||||
CDecoderFlusher(CDecoder *decoder):
|
||||
_decoder(decoder), NeedFlush(true) {}
|
||||
~CDecoderFlusher()
|
||||
{
|
||||
if (NeedFlush)
|
||||
_decoder->Flush();
|
||||
// _decoder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
|
||||
HRESULT Flush()
|
||||
{ return _outWindowStream.Flush(); }
|
||||
|
||||
// ICompressCoder interface
|
||||
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);
|
||||
|
||||
// ICompressSetDecoderProperties
|
||||
STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream);
|
||||
|
||||
HRESULT SetDictionarySize(UINT32 dictionarySize);
|
||||
HRESULT SetLiteralProperties(UINT32 numLiteralPosStateBits,
|
||||
UINT32 numLiteralContextBits);
|
||||
HRESULT SetPosBitsProperties(UINT32 numPosStateBits);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
1264
Source/7zip/7zip/Compress/LZMA/LZMAEncoder.cpp
Normal file
1264
Source/7zip/7zip/Compress/LZMA/LZMAEncoder.cpp
Normal file
File diff suppressed because it is too large
Load diff
294
Source/7zip/7zip/Compress/LZMA/LZMAEncoder.h
Normal file
294
Source/7zip/7zip/Compress/LZMA/LZMAEncoder.h
Normal file
|
@ -0,0 +1,294 @@
|
|||
// LZMA/Encoder.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __LZMA_ENCODER_H
|
||||
#define __LZMA_ENCODER_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../LZ/IMatchFinder.h"
|
||||
|
||||
#include "LZMA.h"
|
||||
#include "LZMALen.h"
|
||||
#include "LZMALiteral.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NLZMA {
|
||||
|
||||
class CMatchFinderException
|
||||
{
|
||||
public:
|
||||
HRESULT ErrorCode;
|
||||
CMatchFinderException(HRESULT errorCode): ErrorCode(errorCode) {}
|
||||
};
|
||||
|
||||
struct COptimal
|
||||
{
|
||||
CState State;
|
||||
|
||||
bool Prev1IsChar;
|
||||
bool Prev2;
|
||||
|
||||
UINT32 PosPrev2;
|
||||
UINT32 BackPrev2;
|
||||
|
||||
UINT32 Price;
|
||||
UINT32 PosPrev; // posNext;
|
||||
UINT32 BackPrev;
|
||||
UINT32 Backs[kNumRepDistances];
|
||||
void MakeAsChar() { BackPrev = UINT32(-1); Prev1IsChar = false; }
|
||||
void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
|
||||
bool IsShortRep() { return (BackPrev == 0); }
|
||||
};
|
||||
|
||||
|
||||
extern BYTE g_FastPos[1024];
|
||||
inline UINT32 GetPosSlot(UINT32 pos)
|
||||
{
|
||||
if (pos < (1 << 10))
|
||||
return g_FastPos[pos];
|
||||
if (pos < (1 << 19))
|
||||
return g_FastPos[pos >> 9] + 18;
|
||||
return g_FastPos[pos >> 18] + 36;
|
||||
}
|
||||
|
||||
inline UINT32 GetPosSlot2(UINT32 pos)
|
||||
{
|
||||
if (pos < (1 << 16))
|
||||
return g_FastPos[pos >> 6] + 12;
|
||||
if (pos < (1 << 25))
|
||||
return g_FastPos[pos >> 15] + 30;
|
||||
return g_FastPos[pos >> 24] + 48;
|
||||
}
|
||||
|
||||
const UINT32 kIfinityPrice = 0xFFFFFFF;
|
||||
|
||||
typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder;
|
||||
|
||||
const UINT32 kNumOpts = 1 << 12;
|
||||
|
||||
class CEncoder :
|
||||
public ICompressCoder,
|
||||
// public IInitMatchFinder,
|
||||
public ICompressSetCoderProperties,
|
||||
public ICompressWriteCoderProperties,
|
||||
public CBaseCoder,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
COptimal _optimum[kNumOpts];
|
||||
public:
|
||||
CMyComPtr<IMatchFinder> _matchFinder; // test it
|
||||
NRangeCoder::CEncoder _rangeEncoder;
|
||||
private:
|
||||
|
||||
CMyBitEncoder _mainChoiceEncoders[kNumStates][NLength::kNumPosStatesEncodingMax];
|
||||
CMyBitEncoder _matchChoiceEncoders[kNumStates];
|
||||
CMyBitEncoder _matchRepChoiceEncoders[kNumStates];
|
||||
CMyBitEncoder _matchRep1ChoiceEncoders[kNumStates];
|
||||
CMyBitEncoder _matchRep2ChoiceEncoders[kNumStates];
|
||||
CMyBitEncoder _matchRepShortChoiceEncoders[kNumStates][NLength::kNumPosStatesEncodingMax];
|
||||
|
||||
NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> _posSlotEncoder[kNumLenToPosStates];
|
||||
|
||||
NRangeCoder::CReverseBitTreeEncoder2<kNumMoveBits> _posEncoders[kNumPosModels];
|
||||
NRangeCoder::CReverseBitTreeEncoder2<kNumMoveBits> _posAlignEncoder;
|
||||
|
||||
NLength::CPriceTableEncoder _lenEncoder;
|
||||
NLength::CPriceTableEncoder _repMatchLenEncoder;
|
||||
|
||||
NLiteral::CEncoder _literalEncoder;
|
||||
|
||||
UINT32 _matchDistances[kMatchMaxLen + 1];
|
||||
|
||||
bool _fastMode;
|
||||
bool _maxMode;
|
||||
UINT32 _numFastBytes;
|
||||
UINT32 _longestMatchLength;
|
||||
|
||||
UINT32 _additionalOffset;
|
||||
|
||||
UINT32 _optimumEndIndex;
|
||||
UINT32 _optimumCurrentIndex;
|
||||
|
||||
bool _longestMatchWasFound;
|
||||
|
||||
UINT32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
|
||||
|
||||
UINT32 _distancesPrices[kNumLenToPosStates][kNumFullDistances];
|
||||
|
||||
UINT32 _alignPrices[kAlignTableSize];
|
||||
UINT32 _alignPriceCount;
|
||||
|
||||
UINT32 _distTableSize;
|
||||
|
||||
UINT32 _posStateBits;
|
||||
UINT32 _posStateMask;
|
||||
UINT32 _numLiteralPosStateBits;
|
||||
UINT32 _numLiteralContextBits;
|
||||
|
||||
UINT32 _dictionarySize;
|
||||
|
||||
UINT32 _dictionarySizePrev;
|
||||
UINT32 _numFastBytesPrev;
|
||||
|
||||
UINT64 lastPosSlotFillingPos;
|
||||
UINT64 nowPos64;
|
||||
bool _finished;
|
||||
ISequentialInStream *_inStream;
|
||||
|
||||
int _matchFinderIndex;
|
||||
#ifdef COMPRESS_MF_MT
|
||||
bool _multiThread;
|
||||
#endif
|
||||
|
||||
bool _writeEndMark;
|
||||
|
||||
UINT32 ReadMatchDistances()
|
||||
{
|
||||
UINT32 len = _matchFinder->GetLongestMatch(_matchDistances);
|
||||
if (len == _numFastBytes)
|
||||
len += _matchFinder->GetMatchLen(len, _matchDistances[len],
|
||||
kMatchMaxLen - len);
|
||||
_additionalOffset++;
|
||||
HRESULT result = _matchFinder->MovePos();
|
||||
if (result != S_OK)
|
||||
throw CMatchFinderException(result);
|
||||
return len;
|
||||
}
|
||||
|
||||
void MovePos(UINT32 num);
|
||||
UINT32 GetRepLen1Price(CState state, UINT32 posState) const
|
||||
{
|
||||
return _matchRepChoiceEncoders[state.Index].GetPrice(0) +
|
||||
_matchRepShortChoiceEncoders[state.Index][posState].GetPrice(0);
|
||||
}
|
||||
UINT32 GetRepPrice(UINT32 repIndex, UINT32 len, CState state, UINT32 posState) const
|
||||
{
|
||||
UINT32 price = _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState);
|
||||
if(repIndex == 0)
|
||||
{
|
||||
price += _matchRepChoiceEncoders[state.Index].GetPrice(0);
|
||||
price += _matchRepShortChoiceEncoders[state.Index][posState].GetPrice(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
price += _matchRepChoiceEncoders[state.Index].GetPrice(1);
|
||||
if (repIndex == 1)
|
||||
price += _matchRep1ChoiceEncoders[state.Index].GetPrice(0);
|
||||
else
|
||||
{
|
||||
price += _matchRep1ChoiceEncoders[state.Index].GetPrice(1);
|
||||
price += _matchRep2ChoiceEncoders[state.Index].GetPrice(repIndex - 2);
|
||||
}
|
||||
}
|
||||
return price;
|
||||
}
|
||||
/*
|
||||
UINT32 GetPosLen2Price(UINT32 pos, UINT32 posState) const
|
||||
{
|
||||
if (pos >= kNumFullDistances)
|
||||
return kIfinityPrice;
|
||||
return _distancesPrices[0][pos] + _lenEncoder.GetPrice(0, posState);
|
||||
}
|
||||
UINT32 GetPosLen3Price(UINT32 pos, UINT32 len, UINT32 posState) const
|
||||
{
|
||||
UINT32 price;
|
||||
UINT32 lenToPosState = GetLenToPosState(len);
|
||||
if (pos < kNumFullDistances)
|
||||
price = _distancesPrices[lenToPosState][pos];
|
||||
else
|
||||
price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
|
||||
_alignPrices[pos & kAlignMask];
|
||||
return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
|
||||
}
|
||||
*/
|
||||
UINT32 GetPosLenPrice(UINT32 pos, UINT32 len, UINT32 posState) const
|
||||
{
|
||||
if (len == 2 && pos >= 0x80)
|
||||
return kIfinityPrice;
|
||||
UINT32 price;
|
||||
UINT32 lenToPosState = GetLenToPosState(len);
|
||||
if (pos < kNumFullDistances)
|
||||
price = _distancesPrices[lenToPosState][pos];
|
||||
else
|
||||
price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
|
||||
_alignPrices[pos & kAlignMask];
|
||||
return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
|
||||
}
|
||||
|
||||
UINT32 Backward(UINT32 &backRes, UINT32 cur);
|
||||
UINT32 GetOptimum(UINT32 &backRes, UINT32 position);
|
||||
UINT32 GetOptimumFast(UINT32 &backRes, UINT32 position);
|
||||
|
||||
void FillPosSlotPrices();
|
||||
void FillDistancesPrices();
|
||||
void FillAlignPrices();
|
||||
|
||||
void ReleaseStreams()
|
||||
{
|
||||
_matchFinder->ReleaseStream();
|
||||
// _rangeEncoder.ReleaseStream();
|
||||
}
|
||||
|
||||
HRESULT Flush();
|
||||
class CCoderReleaser
|
||||
{
|
||||
CEncoder *_coder;
|
||||
public:
|
||||
CCoderReleaser(CEncoder *coder): _coder(coder) {}
|
||||
~CCoderReleaser()
|
||||
{
|
||||
_coder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
friend class CCoderReleaser;
|
||||
|
||||
void WriteEndMarker(UINT32 posState);
|
||||
|
||||
public:
|
||||
CEncoder();
|
||||
void SetWriteEndMarkerMode(bool writeEndMarker)
|
||||
{ _writeEndMark= writeEndMarker; }
|
||||
|
||||
HRESULT Create();
|
||||
|
||||
MY_UNKNOWN_IMP2(
|
||||
ICompressSetCoderProperties,
|
||||
ICompressWriteCoderProperties
|
||||
)
|
||||
|
||||
STDMETHOD(Init)(
|
||||
ISequentialOutStream *outStream);
|
||||
|
||||
// ICompressCoder interface
|
||||
HRESULT SetStreams(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize);
|
||||
HRESULT CodeOneBlock(UINT64 *inSize, UINT64 *outSize, INT32 *finished);
|
||||
|
||||
HRESULT CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// ICompressCoder interface
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// IInitMatchFinder interface
|
||||
STDMETHOD(InitMatchFinder)(IMatchFinder *matchFinder);
|
||||
|
||||
// ICompressSetCoderProperties2
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UINT32 numProperties);
|
||||
|
||||
// ICompressWriteCoderProperties
|
||||
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
74
Source/7zip/7zip/Compress/LZMA/LZMALen.cpp
Normal file
74
Source/7zip/7zip/Compress/LZMA/LZMALen.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
// LZMALen.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "LZMALen.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NLZMA {
|
||||
namespace NLength {
|
||||
|
||||
void CEncoder::Init()
|
||||
{
|
||||
_choice.Init();
|
||||
for (UINT32 posState = 0; posState < _numPosStates; posState++)
|
||||
{
|
||||
_lowCoder[posState].Init();
|
||||
_midCoder[posState].Init();
|
||||
}
|
||||
_choice2.Init();
|
||||
_highCoder.Init();
|
||||
}
|
||||
|
||||
void CEncoder::Encode(NRangeCoder::CEncoder *rangeEncoder, UINT32 symbol, UINT32 posState)
|
||||
{
|
||||
if(symbol < kNumLowSymbols)
|
||||
{
|
||||
_choice.Encode(rangeEncoder, 0);
|
||||
_lowCoder[posState].Encode(rangeEncoder, symbol);
|
||||
}
|
||||
else
|
||||
{
|
||||
symbol -= kNumLowSymbols;
|
||||
_choice.Encode(rangeEncoder, 1);
|
||||
if(symbol < kNumMidSymbols)
|
||||
{
|
||||
_choice2.Encode(rangeEncoder, 0);
|
||||
_midCoder[posState].Encode(rangeEncoder, symbol);
|
||||
}
|
||||
else
|
||||
{
|
||||
_choice2.Encode(rangeEncoder, 1);
|
||||
_highCoder.Encode(rangeEncoder, symbol - kNumMidSymbols);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 CEncoder::GetPrice(UINT32 symbol, UINT32 posState) const
|
||||
{
|
||||
UINT32 price = 0;
|
||||
if(symbol < kNumLowSymbols)
|
||||
{
|
||||
price += _choice.GetPrice(0);
|
||||
price += _lowCoder[posState].GetPrice(symbol);
|
||||
}
|
||||
else
|
||||
{
|
||||
symbol -= kNumLowSymbols;
|
||||
price += _choice.GetPrice(1);
|
||||
if(symbol < kNumMidSymbols)
|
||||
{
|
||||
price += _choice2.GetPrice(0);
|
||||
price += _midCoder[posState].GetPrice(symbol);
|
||||
}
|
||||
else
|
||||
{
|
||||
price += _choice2.GetPrice(1);
|
||||
price += _highCoder.GetPrice(symbol - kNumMidSymbols);
|
||||
}
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
114
Source/7zip/7zip/Compress/LZMA/LZMALen.h
Normal file
114
Source/7zip/7zip/Compress/LZMA/LZMALen.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
// LenCoder.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __LENCODER_H
|
||||
#define __LENCODER_H
|
||||
|
||||
#include "../RangeCoder/RangeCoderBitTree.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NLZMA {
|
||||
namespace NLength {
|
||||
|
||||
const int kNumMoveBits = 5;
|
||||
|
||||
const int kNumPosStatesBitsMax = 4;
|
||||
const UINT32 kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
|
||||
|
||||
const int kNumPosStatesBitsEncodingMax = 4;
|
||||
const UINT32 kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
|
||||
|
||||
const int kNumLenBits = 3;
|
||||
const UINT32 kNumLowSymbols = 1 << kNumLenBits;
|
||||
const int kNumMidBits = 3;
|
||||
const UINT32 kNumMidSymbols = 1 << kNumMidBits;
|
||||
|
||||
const int kNumHighBits = 8;
|
||||
|
||||
const UINT32 kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits);
|
||||
|
||||
class CEncoder
|
||||
{
|
||||
NRangeCoder::CBitEncoder<kNumMoveBits> _choice;
|
||||
NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumLenBits> _lowCoder[kNumPosStatesEncodingMax];
|
||||
NRangeCoder::CBitEncoder<kNumMoveBits> _choice2;
|
||||
NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesEncodingMax];
|
||||
NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumHighBits> _highCoder;
|
||||
protected:
|
||||
UINT32 _numPosStates;
|
||||
public:
|
||||
void Create(UINT32 numPosStates)
|
||||
{ _numPosStates = numPosStates; }
|
||||
void Init();
|
||||
void Encode(NRangeCoder::CEncoder *rangeEncoder, UINT32 symbol, UINT32 posState);
|
||||
UINT32 GetPrice(UINT32 symbol, UINT32 posState) const;
|
||||
};
|
||||
|
||||
const UINT32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols;
|
||||
|
||||
class CPriceTableEncoder: public CEncoder
|
||||
{
|
||||
UINT32 _prices[kNumSymbolsTotal][kNumPosStatesEncodingMax];
|
||||
UINT32 _tableSize;
|
||||
UINT32 _counters[kNumPosStatesEncodingMax];
|
||||
public:
|
||||
void SetTableSize(UINT32 tableSize)
|
||||
{ _tableSize = tableSize; }
|
||||
UINT32 GetPrice(UINT32 symbol, UINT32 posState) const
|
||||
{ return _prices[symbol][posState]; }
|
||||
void UpdateTable(UINT32 posState)
|
||||
{
|
||||
for (UINT32 len = 0; len < _tableSize; len++)
|
||||
_prices[len][posState] = CEncoder::GetPrice(len , posState);
|
||||
_counters[posState] = _tableSize;
|
||||
}
|
||||
void UpdateTables()
|
||||
{
|
||||
for (UINT32 posState = 0; posState < _numPosStates; posState++)
|
||||
UpdateTable(posState);
|
||||
}
|
||||
void Encode(NRangeCoder::CEncoder *rangeEncoder, UINT32 symbol, UINT32 posState)
|
||||
{
|
||||
CEncoder::Encode(rangeEncoder, symbol, posState);
|
||||
if (--_counters[posState] == 0)
|
||||
UpdateTable(posState);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CDecoder
|
||||
{
|
||||
NRangeCoder::CBitDecoder<kNumMoveBits> _choice;
|
||||
NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumLenBits> _lowCoder[kNumPosStatesMax];
|
||||
NRangeCoder::CBitDecoder<kNumMoveBits> _choice2;
|
||||
NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesMax];
|
||||
NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumHighBits> _highCoder;
|
||||
UINT32 _numPosStates;
|
||||
public:
|
||||
void Create(UINT32 numPosStates)
|
||||
{ _numPosStates = numPosStates; }
|
||||
void Init()
|
||||
{
|
||||
_choice.Init();
|
||||
for (UINT32 posState = 0; posState < _numPosStates; posState++)
|
||||
{
|
||||
_lowCoder[posState].Init();
|
||||
_midCoder[posState].Init();
|
||||
}
|
||||
_choice2.Init();
|
||||
_highCoder.Init();
|
||||
}
|
||||
UINT32 Decode(NRangeCoder::CDecoder *rangeDecoder, UINT32 posState)
|
||||
{
|
||||
if(_choice.Decode(rangeDecoder) == 0)
|
||||
return _lowCoder[posState].Decode(rangeDecoder);
|
||||
if(_choice2.Decode(rangeDecoder) == 0)
|
||||
return kNumLowSymbols + _midCoder[posState].Decode(rangeDecoder);
|
||||
return kNumLowSymbols + kNumMidSymbols + _highCoder.Decode(rangeDecoder);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
69
Source/7zip/7zip/Compress/LZMA/LZMALiteral.cpp
Normal file
69
Source/7zip/7zip/Compress/LZMA/LZMALiteral.cpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
// LZMALiteral.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "LZMALiteral.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NLZMA {
|
||||
namespace NLiteral {
|
||||
|
||||
void CEncoder2::Init()
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int j = 1; j < (1 << 8); j++)
|
||||
_encoders[i][j].Init();
|
||||
}
|
||||
|
||||
void CEncoder2::Encode(NRangeCoder::CEncoder *rangeEncoder,
|
||||
bool matchMode, BYTE matchByte, BYTE symbol)
|
||||
{
|
||||
UINT32 context = 1;
|
||||
bool same = true;
|
||||
for (int i = 7; i >= 0; i--)
|
||||
{
|
||||
UINT32 bit = (symbol >> i) & 1;
|
||||
UINT state;
|
||||
if (matchMode && same)
|
||||
{
|
||||
UINT32 matchBit = (matchByte >> i) & 1;
|
||||
state = 1 + matchBit;
|
||||
same = (matchBit == bit);
|
||||
}
|
||||
else
|
||||
state = 0;
|
||||
_encoders[state][context].Encode(rangeEncoder, bit);
|
||||
context = (context << 1) | bit;
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 CEncoder2::GetPrice(bool matchMode, BYTE matchByte, BYTE symbol) const
|
||||
{
|
||||
UINT32 price = 0;
|
||||
UINT32 context = 1;
|
||||
int i = 7;
|
||||
if (matchMode)
|
||||
{
|
||||
for (; i >= 0; i--)
|
||||
{
|
||||
UINT32 matchBit = (matchByte >> i) & 1;
|
||||
UINT32 bit = (symbol >> i) & 1;
|
||||
price += _encoders[1 + matchBit][context].GetPrice(bit);
|
||||
context = (context << 1) | bit;
|
||||
if (matchBit != bit)
|
||||
{
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (; i >= 0; i--)
|
||||
{
|
||||
UINT32 bit = (symbol >> i) & 1;
|
||||
price += _encoders[0][context].GetPrice(bit);
|
||||
context = (context << 1) | bit;
|
||||
}
|
||||
return price;
|
||||
};
|
||||
|
||||
}}}
|
166
Source/7zip/7zip/Compress/LZMA/LZMALiteral.h
Normal file
166
Source/7zip/7zip/Compress/LZMA/LZMALiteral.h
Normal file
|
@ -0,0 +1,166 @@
|
|||
// LiteralCoder.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __LITERALCODER_H
|
||||
#define __LITERALCODER_H
|
||||
|
||||
#include "../RangeCoder/RangeCoderBit.h"
|
||||
#include "../RangeCoder/RangeCoderOpt.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NLZMA {
|
||||
namespace NLiteral {
|
||||
|
||||
const int kNumMoveBits = 5;
|
||||
|
||||
class CEncoder2
|
||||
{
|
||||
NRangeCoder::CBitEncoder<kNumMoveBits> _encoders[3][1 << 8];
|
||||
public:
|
||||
void Init();
|
||||
void Encode(NRangeCoder::CEncoder *rangeEncoder, bool matchMode, BYTE matchByte, BYTE symbol);
|
||||
UINT32 GetPrice(bool matchMode, BYTE matchByte, BYTE symbol) const;
|
||||
};
|
||||
|
||||
class CDecoder2
|
||||
{
|
||||
NRangeCoder::CBitDecoder<kNumMoveBits> _decoders[3][1 << 8];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int j = 1; j < (1 << 8); j++)
|
||||
_decoders[i][j].Init();
|
||||
}
|
||||
|
||||
BYTE DecodeNormal(NRangeCoder::CDecoder *rangeDecoder)
|
||||
{
|
||||
UINT32 symbol = 1;
|
||||
RC_INIT_VAR
|
||||
do
|
||||
{
|
||||
// symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
|
||||
RC_GETBIT(kNumMoveBits, _decoders[0][symbol].Probability, symbol)
|
||||
}
|
||||
while (symbol < 0x100);
|
||||
RC_FLUSH_VAR
|
||||
return symbol;
|
||||
}
|
||||
|
||||
BYTE DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, BYTE matchByte)
|
||||
{
|
||||
UINT32 symbol = 1;
|
||||
RC_INIT_VAR
|
||||
do
|
||||
{
|
||||
UINT32 matchBit = (matchByte >> 7) & 1;
|
||||
matchByte <<= 1;
|
||||
// UINT32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder);
|
||||
// symbol = (symbol << 1) | bit;
|
||||
UINT32 bit;
|
||||
RC_GETBIT2(kNumMoveBits, _decoders[1 + matchBit][symbol].Probability, symbol,
|
||||
bit = 0, bit = 1)
|
||||
if (matchBit != bit)
|
||||
{
|
||||
while (symbol < 0x100)
|
||||
{
|
||||
// symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
|
||||
RC_GETBIT(kNumMoveBits, _decoders[0][symbol].Probability, symbol)
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (symbol < 0x100);
|
||||
RC_FLUSH_VAR
|
||||
return symbol;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
const UINT32 kNumPrevByteBits = 1;
|
||||
const UINT32 kNumPrevByteStates = (1 << kNumPrevByteBits);
|
||||
|
||||
inline UINT32 GetLiteralState(BYTE prevByte)
|
||||
{ return (prevByte >> (8 - kNumPrevByteBits)); }
|
||||
*/
|
||||
|
||||
class CEncoder
|
||||
{
|
||||
CEncoder2 *_coders;
|
||||
UINT32 _numPrevBits;
|
||||
UINT32 _numPosBits;
|
||||
UINT32 _posMask;
|
||||
public:
|
||||
CEncoder(): _coders(0) {}
|
||||
~CEncoder() { Free(); }
|
||||
void Free()
|
||||
{
|
||||
delete []_coders;
|
||||
_coders = 0;
|
||||
}
|
||||
void Create(UINT32 numPosBits, UINT32 numPrevBits)
|
||||
{
|
||||
Free();
|
||||
_numPosBits = numPosBits;
|
||||
_posMask = (1 << numPosBits) - 1;
|
||||
_numPrevBits = numPrevBits;
|
||||
UINT32 numStates = 1 << (_numPrevBits + _numPosBits);
|
||||
_coders = new CEncoder2[numStates];
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
UINT32 numStates = 1 << (_numPrevBits + _numPosBits);
|
||||
for (UINT32 i = 0; i < numStates; i++)
|
||||
_coders[i].Init();
|
||||
}
|
||||
UINT32 GetState(UINT32 pos, BYTE prevByte) const
|
||||
{ return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }
|
||||
void Encode(NRangeCoder::CEncoder *rangeEncoder, UINT32 pos, BYTE prevByte,
|
||||
bool matchMode, BYTE matchByte, BYTE symbol)
|
||||
{ _coders[GetState(pos, prevByte)].Encode(rangeEncoder, matchMode,
|
||||
matchByte, symbol); }
|
||||
UINT32 GetPrice(UINT32 pos, BYTE prevByte, bool matchMode, BYTE matchByte, BYTE symbol) const
|
||||
{ return _coders[GetState(pos, prevByte)].GetPrice(matchMode, matchByte, symbol); }
|
||||
};
|
||||
|
||||
class CDecoder
|
||||
{
|
||||
CDecoder2 *_coders;
|
||||
UINT32 _numPrevBits;
|
||||
UINT32 _numPosBits;
|
||||
UINT32 _posMask;
|
||||
public:
|
||||
CDecoder(): _coders(0) {}
|
||||
~CDecoder() { Free(); }
|
||||
void Free()
|
||||
{
|
||||
delete []_coders;
|
||||
_coders = 0;
|
||||
}
|
||||
void Create(UINT32 numPosBits, UINT32 numPrevBits)
|
||||
{
|
||||
Free();
|
||||
_numPosBits = numPosBits;
|
||||
_posMask = (1 << numPosBits) - 1;
|
||||
_numPrevBits = numPrevBits;
|
||||
UINT32 numStates = 1 << (_numPrevBits + _numPosBits);
|
||||
_coders = new CDecoder2[numStates];
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
UINT32 numStates = 1 << (_numPrevBits + _numPosBits);
|
||||
for (UINT32 i = 0; i < numStates; i++)
|
||||
_coders[i].Init();
|
||||
}
|
||||
UINT32 GetState(UINT32 pos, BYTE prevByte) const
|
||||
{ return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }
|
||||
BYTE DecodeNormal(NRangeCoder::CDecoder *rangeDecoder, UINT32 pos, BYTE prevByte)
|
||||
{ return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
|
||||
BYTE DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, UINT32 pos, BYTE prevByte, BYTE matchByte)
|
||||
{ return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
8
Source/7zip/7zip/Compress/LZMA/StdAfx.h
Normal file
8
Source/7zip/7zip/Compress/LZMA/StdAfx.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#endif
|
29
Source/7zip/7zip/Compress/LZMA_SMALL/InBuffer.h
Normal file
29
Source/7zip/7zip/Compress/LZMA_SMALL/InBuffer.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Stream/InByte.h
|
||||
|
||||
#include "LZMAState.h"
|
||||
|
||||
#ifndef __STREAM_INBYTE_H
|
||||
#define __STREAM_INBYTE_H
|
||||
|
||||
class CInBuffer
|
||||
{
|
||||
CLZMAStateP m_lzmaState;
|
||||
public:
|
||||
void Init(CLZMAStateP lzmaState)
|
||||
{
|
||||
m_lzmaState = lzmaState;
|
||||
}
|
||||
BYTE ReadByte()
|
||||
{
|
||||
if (!m_lzmaState->avail_in)
|
||||
{
|
||||
LZMAGetIO(m_lzmaState);
|
||||
}
|
||||
if (!m_lzmaState->avail_in)
|
||||
return 0;
|
||||
m_lzmaState->avail_in--;
|
||||
return *m_lzmaState->next_in++;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
62
Source/7zip/7zip/Compress/LZMA_SMALL/LZMA.h
Normal file
62
Source/7zip/7zip/Compress/LZMA_SMALL/LZMA.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
// LZMA.h
|
||||
|
||||
#include "LZMALenCoder.h"
|
||||
|
||||
#ifndef __LZMA_H
|
||||
#define __LZMA_H
|
||||
|
||||
const int kNumRepDistances = 4;
|
||||
|
||||
const int kNumStates = 12;
|
||||
|
||||
const BYTE kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
|
||||
const BYTE kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
|
||||
const BYTE kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
|
||||
const BYTE kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
|
||||
|
||||
class CState
|
||||
{
|
||||
public:
|
||||
int Index;
|
||||
void Init() { Index = 0; }
|
||||
void UpdateChar() { Index = kLiteralNextStates[Index]; }
|
||||
void UpdateMatch() { Index = kMatchNextStates[Index]; }
|
||||
void UpdateRep() { Index = kRepNextStates[Index]; }
|
||||
void UpdateShortRep() { Index = kShortRepNextStates[Index]; }
|
||||
};
|
||||
|
||||
const int kNumPosSlotBits = 6;
|
||||
|
||||
const int kNumLenToPosStates = 4;
|
||||
|
||||
/*
|
||||
inline int GetLenToPosState(int len)
|
||||
{
|
||||
if (len < kNumLenToPosStates + 2)
|
||||
return len - 2;
|
||||
return kNumLenToPosStates - 1;
|
||||
}
|
||||
*/
|
||||
|
||||
inline int GetLenToPosState2(int len)
|
||||
{
|
||||
if (len < kNumLenToPosStates)
|
||||
return len;
|
||||
return kNumLenToPosStates - 1;
|
||||
}
|
||||
|
||||
const int kMatchMinLen = 2;
|
||||
const int kMatchMaxLen = kMatchMinLen + kLenNumSymbolsTotal - 1;
|
||||
|
||||
const int kNumAlignBits = 4;
|
||||
const int kAlignTableSize = 1 << kNumAlignBits;
|
||||
|
||||
const int kStartPosModelIndex = 4;
|
||||
const int kEndPosModelIndex = 14;
|
||||
const int kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
|
||||
const int kNumFullDistances = 1 << (kEndPosModelIndex / 2);
|
||||
|
||||
const int kNumLitPosStatesBitsEncodingMax = 4;
|
||||
const int kNumLitContextBitsMax = 8;
|
||||
|
||||
#endif
|
25
Source/7zip/7zip/Compress/LZMA_SMALL/LZMAConf.h
Normal file
25
Source/7zip/7zip/Compress/LZMA_SMALL/LZMAConf.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef __LZMACONF_H
|
||||
#define __LZMACONF_H
|
||||
|
||||
// define __LOC_OPT for some speed optimization:
|
||||
// It converts some class-member variables to local variables
|
||||
// before some loops and it use inline code substitution
|
||||
|
||||
#define __LOC_OPT
|
||||
// #define __UNROLL
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "../../../../exehead/util.h"
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define LZMAAlloc my_GlobalAlloc
|
||||
#define LZMAFree GlobalFree
|
||||
#define LZMAMemCopy mini_memcpy
|
||||
|
||||
#endif
|
183
Source/7zip/7zip/Compress/LZMA_SMALL/LZMADecoder.cpp
Normal file
183
Source/7zip/7zip/Compress/LZMA_SMALL/LZMADecoder.cpp
Normal file
|
@ -0,0 +1,183 @@
|
|||
// LZMADecoder.cpp
|
||||
|
||||
#include "LZMADecoder.h"
|
||||
|
||||
UINT32 CLZMADecoder::Create(BYTE *memoryPointer,
|
||||
int numLiteralContextBits,
|
||||
int numLiteralPosStateBits,
|
||||
int numPosStateBits)
|
||||
{
|
||||
|
||||
int numPosStates = 1 << numPosStateBits;
|
||||
m_PosStateMask = numPosStates - 1;
|
||||
return m_LiteralDecoder.Create(memoryPointer, numLiteralPosStateBits, numLiteralContextBits);
|
||||
}
|
||||
|
||||
UINT32 CLZMADecoder::Code(CLZMAStateP lzmaState)
|
||||
{
|
||||
m_RangeDecoder.Init(lzmaState);
|
||||
m_OutWindowStream.Init(lzmaState);
|
||||
|
||||
int i;
|
||||
for(i = 0; i < kNumStates; i++)
|
||||
{
|
||||
for (int j = 0; j <= m_PosStateMask; j++)
|
||||
{
|
||||
m_MainChoiceDecoders[i][j].Init();
|
||||
m_MatchRepShortChoiceDecoders[i][j].Init();
|
||||
}
|
||||
m_MatchChoiceDecoders[i].Init();
|
||||
m_MatchRepChoiceDecoders[i].Init();
|
||||
m_MatchRep1ChoiceDecoders[i].Init();
|
||||
m_MatchRep2ChoiceDecoders[i].Init();
|
||||
}
|
||||
|
||||
m_LiteralDecoder.Init();
|
||||
|
||||
for (i = 0; i < kNumLenToPosStates; i++)
|
||||
m_PosSlotDecoder[i].Init();
|
||||
m_PosDecoder.Init();
|
||||
m_PosAlignDecoder.Init();
|
||||
|
||||
// m_LenDecoder.Init(m_PosStateMask + 1);
|
||||
// m_RepMatchLenDecoder.Init(m_PosStateMask + 1);
|
||||
m_LenDecoder.Init();
|
||||
m_RepMatchLenDecoder.Init();
|
||||
|
||||
|
||||
////////////////////////
|
||||
// code
|
||||
|
||||
CState state;
|
||||
state.Init();
|
||||
bool peviousIsMatch = false;
|
||||
BYTE previousByte = 0;
|
||||
// kNumRepDistances == 4
|
||||
UINT32 repDistances[kNumRepDistances] = {1, 1, 1, 1};
|
||||
|
||||
/*for(i = 0 ; i < kNumRepDistances; i++)
|
||||
repDistances[i] = 1;*/
|
||||
|
||||
UINT32 nowPos = 0;
|
||||
while(nowPos < 0xFFFFFFFF)
|
||||
{
|
||||
int posState = nowPos & m_PosStateMask;
|
||||
if (m_MainChoiceDecoders[state.Index][posState].Decode(&m_RangeDecoder) == 0)
|
||||
{
|
||||
state.UpdateChar();
|
||||
if(peviousIsMatch)
|
||||
{
|
||||
#ifdef __STREAM_VERSION
|
||||
BYTE matchByte = m_OutWindowStream.GetOneByte(0 - repDistances[0]);
|
||||
#else
|
||||
BYTE matchByte = *(outStream - repDistances[0]);
|
||||
#endif
|
||||
previousByte = m_LiteralDecoder.DecodeWithMatchByte(&m_RangeDecoder,
|
||||
nowPos, previousByte, matchByte);
|
||||
peviousIsMatch = false;
|
||||
}
|
||||
else
|
||||
previousByte = m_LiteralDecoder.DecodeNormal(&m_RangeDecoder,
|
||||
nowPos, previousByte);
|
||||
|
||||
#ifdef __STREAM_VERSION
|
||||
m_OutWindowStream.PutOneByte(previousByte);
|
||||
#else
|
||||
*outStream++ = previousByte;
|
||||
#endif
|
||||
|
||||
nowPos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
peviousIsMatch = true;
|
||||
UINT32 distance;
|
||||
int len;
|
||||
if(m_MatchChoiceDecoders[state.Index].Decode(&m_RangeDecoder) == 1)
|
||||
{
|
||||
if(m_MatchRepChoiceDecoders[state.Index].Decode(&m_RangeDecoder) == 0)
|
||||
{
|
||||
if(m_MatchRepShortChoiceDecoders[state.Index][posState].Decode(&m_RangeDecoder) == 0)
|
||||
{
|
||||
state.UpdateShortRep();
|
||||
|
||||
#ifdef __STREAM_VERSION
|
||||
previousByte = m_OutWindowStream.GetOneByte(0 - repDistances[0]);
|
||||
m_OutWindowStream.PutOneByte(previousByte);
|
||||
#else
|
||||
previousByte = *(outStream - repDistances[0]);
|
||||
*outStream++ = previousByte;
|
||||
#endif
|
||||
|
||||
nowPos++;
|
||||
continue;
|
||||
}
|
||||
distance = repDistances[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_MatchRep1ChoiceDecoders[state.Index].Decode(&m_RangeDecoder) == 0)
|
||||
distance = repDistances[1];
|
||||
else
|
||||
{
|
||||
if (m_MatchRep2ChoiceDecoders[state.Index].Decode(&m_RangeDecoder) == 0)
|
||||
distance = repDistances[2];
|
||||
else
|
||||
{
|
||||
distance = repDistances[3];
|
||||
repDistances[3] = repDistances[2];
|
||||
}
|
||||
repDistances[2] = repDistances[1];
|
||||
}
|
||||
repDistances[1] = repDistances[0];
|
||||
repDistances[0] = distance;
|
||||
}
|
||||
len = m_RepMatchLenDecoder.Decode(&m_RangeDecoder, posState);
|
||||
state.UpdateRep();
|
||||
}
|
||||
else
|
||||
{
|
||||
len = m_LenDecoder.Decode(&m_RangeDecoder, posState);
|
||||
state.UpdateMatch();
|
||||
int posSlot = m_PosSlotDecoder[GetLenToPosState2(len)].Decode(&m_RangeDecoder);
|
||||
if (posSlot >= kStartPosModelIndex)
|
||||
{
|
||||
int numDirectBits = ((posSlot >> 1) - 1);
|
||||
distance = ((2 | (posSlot & 1)) << numDirectBits);
|
||||
if (posSlot < kEndPosModelIndex)
|
||||
distance += m_PosDecoder.Decode(&m_RangeDecoder, posSlot);
|
||||
else
|
||||
{
|
||||
distance += (m_RangeDecoder.DecodeDirectBits(
|
||||
numDirectBits - kNumAlignBits) << kNumAlignBits);
|
||||
distance += m_PosAlignDecoder.Decode(&m_RangeDecoder);
|
||||
}
|
||||
}
|
||||
else
|
||||
distance = posSlot;
|
||||
distance++;
|
||||
repDistances[3] = repDistances[2];
|
||||
repDistances[2] = repDistances[1];
|
||||
repDistances[1] = repDistances[0];
|
||||
repDistances[0] = distance;
|
||||
}
|
||||
if (distance > nowPos || distance == 0)
|
||||
{
|
||||
// it's for stream version (without knowing uncompressed size)
|
||||
// if (distance >= _dictionarySizeCheck)
|
||||
if (distance == (UINT32)(0))
|
||||
break;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
len += kMatchMinLen;
|
||||
m_OutWindowStream.CopyBackBlock(m_OutWindowStream._pos - distance, len);
|
||||
previousByte = m_OutWindowStream.GetOneByte((UINT32)(-1));
|
||||
|
||||
nowPos += len;
|
||||
}
|
||||
}
|
||||
m_OutWindowStream._windowSize = 0;
|
||||
m_OutWindowStream.Flush();
|
||||
return 0;
|
||||
}
|
82
Source/7zip/7zip/Compress/LZMA_SMALL/LZMADecoder.h
Normal file
82
Source/7zip/7zip/Compress/LZMA_SMALL/LZMADecoder.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
// LZMADecoder.h
|
||||
|
||||
#ifndef __LZMADECODER_H
|
||||
#define __LZMADECODER_H
|
||||
|
||||
#include "LZMAConf.h"
|
||||
#include "LZMAState.h"
|
||||
#include "LZMA.h"
|
||||
#include "LZMALiteralCoder.h"
|
||||
#include "LZOutWindow.h"
|
||||
|
||||
class CPosSpecDecoder
|
||||
{
|
||||
CBitDecoder m_Models[kNumFullDistances - kEndPosModelIndex];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(int i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
|
||||
m_Models[i].Init();
|
||||
}
|
||||
int Decode(CRangeDecoder *rangeDecoder, int slot)
|
||||
{
|
||||
int numLeveles = (slot >> 1) - 1;
|
||||
|
||||
CBitDecoder *models =
|
||||
m_Models + (((2 | (slot & 1)) << numLeveles)) - slot - 1;
|
||||
|
||||
int modelIndex = 1;
|
||||
int symbol = 0;
|
||||
#ifdef __LOC_OPT
|
||||
RC_INIT_VAR
|
||||
#endif
|
||||
for(int bitIndex = 0; bitIndex < numLeveles; bitIndex++)
|
||||
{
|
||||
#ifdef __LOC_OPT
|
||||
RC_GETBIT2(models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << bitIndex))
|
||||
#else
|
||||
int bit = models[modelIndex].Decode(rangeDecoder);
|
||||
modelIndex <<= 1;
|
||||
modelIndex += bit;
|
||||
symbol |= (bit << bitIndex);
|
||||
#endif
|
||||
}
|
||||
#ifdef __LOC_OPT
|
||||
RC_FLUSH_VAR
|
||||
#endif
|
||||
return symbol;
|
||||
};
|
||||
};
|
||||
|
||||
class CLZMADecoder
|
||||
{
|
||||
CLZOutWindow m_OutWindowStream;
|
||||
CRangeDecoder m_RangeDecoder;
|
||||
|
||||
CBitDecoder m_MainChoiceDecoders[kNumStates][kLenNumPosStatesMax];
|
||||
CBitDecoder m_MatchRepShortChoiceDecoders[kNumStates][kLenNumPosStatesMax];
|
||||
CBitDecoder m_MatchChoiceDecoders[kNumStates];
|
||||
CBitDecoder m_MatchRepChoiceDecoders[kNumStates];
|
||||
CBitDecoder m_MatchRep1ChoiceDecoders[kNumStates];
|
||||
CBitDecoder m_MatchRep2ChoiceDecoders[kNumStates];
|
||||
|
||||
CLZMALiteralDecoder m_LiteralDecoder;
|
||||
|
||||
CBitTreeDecoder6 m_PosSlotDecoder[kNumLenToPosStates];
|
||||
CPosSpecDecoder m_PosDecoder;
|
||||
CReverseBitTreeDecoder4 m_PosAlignDecoder;
|
||||
|
||||
CLZMALenDecoder m_LenDecoder;
|
||||
CLZMALenDecoder m_RepMatchLenDecoder;
|
||||
|
||||
int m_PosStateMask;
|
||||
|
||||
public:
|
||||
UINT32 Create(BYTE *memoryPointer,
|
||||
int numLiteralContextBits,
|
||||
int numLiteralPosStateBits,
|
||||
int numPosStateBits);
|
||||
UINT32 Code(CLZMAStateP lzmaState);
|
||||
};
|
||||
|
||||
#endif
|
53
Source/7zip/7zip/Compress/LZMA_SMALL/LZMALenCoder.h
Normal file
53
Source/7zip/7zip/Compress/LZMA_SMALL/LZMALenCoder.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
// LZMALenCoder.h
|
||||
|
||||
#ifndef __LZMALENCODER_H
|
||||
#define __LZMALENCODER_H
|
||||
|
||||
#include "RangeCoderBitTree.h"
|
||||
|
||||
const int kLenNumPosStatesBitsMax = 4;
|
||||
const int kLenNumPosStatesMax = (1 << kLenNumPosStatesBitsMax);
|
||||
|
||||
const int kLenNumPosStatesBitsEncodingMax = 4;
|
||||
const int kLenNumPosStatesEncodingMax = (1 << kLenNumPosStatesBitsEncodingMax);
|
||||
|
||||
const int kLenNumLowBits = 3;
|
||||
const int kLenNumLowSymbols = 1 << kLenNumLowBits;
|
||||
const int kLenNumMidBits = 3;
|
||||
const int kLenNumMidSymbols = 1 << kLenNumMidBits;
|
||||
|
||||
const int kLenNumHighBits = 8;
|
||||
const int kLenNumSymbolsTotal = kLenNumLowSymbols + kLenNumMidSymbols + (1 << kLenNumHighBits);
|
||||
|
||||
class CLZMALenDecoder
|
||||
{
|
||||
CBitDecoder m_Choice;
|
||||
CBitDecoder m_Choice2;
|
||||
CBitTreeDecoder3 m_LowCoder[kLenNumPosStatesMax];
|
||||
CBitTreeDecoder3 m_MidCoder[kLenNumPosStatesMax];
|
||||
CBitTreeDecoder8 m_HighCoder;
|
||||
public:
|
||||
// void Init(int numPosStates)
|
||||
void Init()
|
||||
{
|
||||
m_Choice.Init();
|
||||
m_Choice2.Init();
|
||||
// for (int posState = 0; posState < numPosStates; posState++)
|
||||
for (int posState = 0; posState < kLenNumPosStatesMax; posState++)
|
||||
{
|
||||
m_LowCoder[posState].Init();
|
||||
m_MidCoder[posState].Init();
|
||||
}
|
||||
m_HighCoder.Init();
|
||||
}
|
||||
int Decode(CRangeDecoder *rangeDecoder, int posState)
|
||||
{
|
||||
if(m_Choice.Decode(rangeDecoder) == 0)
|
||||
return m_LowCoder[posState].Decode(rangeDecoder);
|
||||
if(m_Choice2.Decode(rangeDecoder) == 0)
|
||||
return kLenNumLowSymbols + m_MidCoder[posState].Decode(rangeDecoder);
|
||||
return kLenNumLowSymbols + kLenNumMidSymbols + m_HighCoder.Decode(rangeDecoder);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
107
Source/7zip/7zip/Compress/LZMA_SMALL/LZMALiteralCoder.h
Normal file
107
Source/7zip/7zip/Compress/LZMA_SMALL/LZMALiteralCoder.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
// LZMALiteralCoder.h
|
||||
|
||||
#ifndef __LZMALITERALCODER_H
|
||||
#define __LZMALITERALCODER_H
|
||||
|
||||
#include "RangeCoderBit.h"
|
||||
#include "RangeCoderOpt.h"
|
||||
|
||||
class CLZMALiteralDecoder2
|
||||
{
|
||||
CBitDecoder m_Decoders[3][1 << 8];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int j = 0; j < (1 << 8); j++)
|
||||
m_Decoders[i][j].Init();
|
||||
}
|
||||
BYTE DecodeNormal(CRangeDecoder *rangeDecoder)
|
||||
{
|
||||
int symbol = 1;
|
||||
#ifdef __LOC_OPT
|
||||
RC_INIT_VAR
|
||||
#endif
|
||||
do
|
||||
{
|
||||
#ifdef __LOC_OPT
|
||||
RC_GETBIT(m_Decoders[0][symbol].Probability, symbol)
|
||||
#else
|
||||
symbol = (symbol + symbol) | m_Decoders[0][symbol].Decode(rangeDecoder);
|
||||
#endif
|
||||
}
|
||||
while (symbol < 0x100);
|
||||
#ifdef __LOC_OPT
|
||||
RC_FLUSH_VAR
|
||||
#endif
|
||||
return symbol;
|
||||
}
|
||||
BYTE DecodeWithMatchByte(CRangeDecoder *rangeDecoder, BYTE matchByte)
|
||||
{
|
||||
int symbol = 1;
|
||||
#ifdef __LOC_OPT
|
||||
RC_INIT_VAR
|
||||
#endif
|
||||
do
|
||||
{
|
||||
int matchBit = (matchByte >> 7) & 1;
|
||||
matchByte <<= 1;
|
||||
#ifdef __LOC_OPT
|
||||
int bit;
|
||||
RC_GETBIT2(m_Decoders[1 + matchBit][symbol].Probability, symbol,
|
||||
bit = 0, bit = 1)
|
||||
#else
|
||||
int bit = m_Decoders[1 + matchBit][symbol].Decode(rangeDecoder);
|
||||
symbol = (symbol + symbol) | bit;
|
||||
#endif
|
||||
if (matchBit != bit)
|
||||
{
|
||||
while (symbol < 0x100)
|
||||
{
|
||||
#ifdef __LOC_OPT
|
||||
RC_GETBIT(m_Decoders[0][symbol].Probability, symbol)
|
||||
#else
|
||||
symbol = (symbol + symbol) | m_Decoders[0][symbol].Decode(rangeDecoder);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (symbol < 0x100);
|
||||
#ifdef __LOC_OPT
|
||||
RC_FLUSH_VAR
|
||||
#endif
|
||||
return symbol;
|
||||
}
|
||||
};
|
||||
|
||||
class CLZMALiteralDecoder
|
||||
{
|
||||
CLZMALiteralDecoder2 *m_Coders;
|
||||
int m_NumPrevBits;
|
||||
int m_PosMask;
|
||||
public:
|
||||
CLZMALiteralDecoder(): m_Coders(0) {}
|
||||
UINT32 Create(BYTE *memory, int numPosBits, int numPrevBits)
|
||||
{
|
||||
m_PosMask = (1 << numPosBits) - 1;
|
||||
m_NumPrevBits = numPrevBits;
|
||||
int numStates = 1 << (numPrevBits + numPosBits);
|
||||
m_Coders = (CLZMALiteralDecoder2 *)memory;
|
||||
return sizeof(CLZMALiteralDecoder2) * numStates;
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
int numStates = (m_PosMask + 1) << m_NumPrevBits;
|
||||
for (int i = 0; i < numStates; i++)
|
||||
m_Coders[i].Init();
|
||||
}
|
||||
int GetState(int pos, BYTE prevByte) const
|
||||
{ return ((pos & m_PosMask) << m_NumPrevBits) + (prevByte >> (8 - m_NumPrevBits)); }
|
||||
BYTE DecodeNormal(CRangeDecoder *rangeDecoder, int pos, BYTE prevByte)
|
||||
{ return m_Coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
|
||||
BYTE DecodeWithMatchByte(CRangeDecoder *rangeDecoder, int pos, BYTE prevByte, BYTE matchByte)
|
||||
{ return m_Coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
|
||||
};
|
||||
|
||||
#endif
|
39
Source/7zip/7zip/Compress/LZMA_SMALL/LZMAState.h
Normal file
39
Source/7zip/7zip/Compress/LZMA_SMALL/LZMAState.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include <Windows.h>
|
||||
|
||||
#ifndef __LZMA_STATE__H___
|
||||
#define __LZMA_STATE__H___
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *lzmaDecoder;
|
||||
void *DynamicData;
|
||||
void *Dictionary;
|
||||
UINT32 DictionarySize;
|
||||
BYTE FirstProp;
|
||||
|
||||
HANDLE hThread; /* decompression thread */
|
||||
|
||||
BYTE *next_in; /* next input byte */
|
||||
UINT avail_in; /* number of bytes available at next_in */
|
||||
|
||||
BYTE *next_out; /* next output byte should be put there */
|
||||
UINT avail_out; /* remaining free space at next_out */
|
||||
|
||||
CRITICAL_SECTION cs;
|
||||
BOOL cs_initialized;
|
||||
BOOL it_locked; /* installer thread locked */
|
||||
BOOL dt_locked; /* decompression thread locked */
|
||||
|
||||
BOOL finished;
|
||||
int res;
|
||||
} CLZMAState;
|
||||
|
||||
typedef CLZMAState
|
||||
#ifndef __cplusplus
|
||||
FAR
|
||||
#endif
|
||||
*CLZMAStateP;
|
||||
|
||||
void __stdcall LZMAGetIO(CLZMAStateP lzmaState);
|
||||
|
||||
#endif
|
76
Source/7zip/7zip/Compress/LZMA_SMALL/LZOutWindow.h
Normal file
76
Source/7zip/7zip/Compress/LZMA_SMALL/LZOutWindow.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
// LZOutWindow.h
|
||||
|
||||
#ifndef __LZOUTWINDOW_H
|
||||
#define __LZOUTWINDOW_H
|
||||
|
||||
#include "Types.h"
|
||||
#include "LZMAState.h"
|
||||
#include "LZMAConf.h"
|
||||
|
||||
class CLZOutWindow
|
||||
{
|
||||
public:
|
||||
BYTE *_buffer;
|
||||
UINT32 _pos;
|
||||
UINT32 _windowSize;
|
||||
UINT32 _streamPos;
|
||||
CLZMAStateP m_lzmaState;
|
||||
void Init(CLZMAStateP lzmaState)
|
||||
{
|
||||
m_lzmaState = lzmaState;
|
||||
_buffer = (LPBYTE) lzmaState->Dictionary;
|
||||
_windowSize = lzmaState->DictionarySize;
|
||||
_streamPos = 0;
|
||||
_pos = 0;
|
||||
}
|
||||
void CopyBackBlock(UINT32 fromPos, int len)
|
||||
{
|
||||
if (fromPos >= _windowSize)
|
||||
fromPos += _windowSize;
|
||||
while (len--)
|
||||
{
|
||||
_buffer[_pos++] = _buffer[fromPos++];
|
||||
if (fromPos >= _windowSize)
|
||||
fromPos = 0;
|
||||
Flush();
|
||||
}
|
||||
}
|
||||
void PutOneByte(BYTE b)
|
||||
{
|
||||
_buffer[_pos++] = b;
|
||||
Flush();
|
||||
}
|
||||
void Flush()
|
||||
{
|
||||
UINT32 size = _pos - _streamPos;
|
||||
if (size < 65536 && _pos < _windowSize)
|
||||
return;
|
||||
|
||||
CLZMAStateP lzmaState = m_lzmaState;
|
||||
while (size--)
|
||||
{
|
||||
if (!lzmaState->avail_out)
|
||||
{
|
||||
LZMAGetIO(lzmaState);
|
||||
}
|
||||
*lzmaState->next_out = _buffer[_streamPos];
|
||||
lzmaState->next_out++;
|
||||
lzmaState->avail_out--;
|
||||
_streamPos++;
|
||||
}
|
||||
if (_pos >= _windowSize)
|
||||
{
|
||||
_pos = 0;
|
||||
_streamPos = 0;
|
||||
}
|
||||
}
|
||||
BYTE GetOneByte(UINT32 index) const
|
||||
{
|
||||
UINT32 pos = _pos + index;
|
||||
if (pos >= _windowSize)
|
||||
pos += _windowSize;
|
||||
return _buffer[pos];
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
87
Source/7zip/7zip/Compress/LZMA_SMALL/RangeCoder.h
Normal file
87
Source/7zip/7zip/Compress/LZMA_SMALL/RangeCoder.h
Normal file
|
@ -0,0 +1,87 @@
|
|||
// Compression/RangeCoder.h
|
||||
|
||||
#ifndef __COMPRESSION_RANGECODER_H
|
||||
#define __COMPRESSION_RANGECODER_H
|
||||
|
||||
#include "InBuffer.h"
|
||||
|
||||
const int kNumTopBits = 24;
|
||||
const UINT32 kTopValue = (1 << kNumTopBits);
|
||||
|
||||
class CRangeDecoder
|
||||
{
|
||||
public:
|
||||
CInBuffer Stream;
|
||||
UINT32 Range;
|
||||
UINT32 Code;
|
||||
void Normalize()
|
||||
{
|
||||
while (Range < kTopValue)
|
||||
{
|
||||
Code = (Code << 8) | Stream.ReadByte();
|
||||
Range <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
void Init(CLZMAStateP state)
|
||||
{
|
||||
Stream.Init(state);
|
||||
Code = 0;
|
||||
Range = UINT32(-1);
|
||||
for(int i = 0; i < 5; i++)
|
||||
Code = (Code << 8) | Stream.ReadByte();
|
||||
}
|
||||
|
||||
UINT32 DecodeDirectBits(int numTotalBits)
|
||||
{
|
||||
UINT32 range = Range;
|
||||
UINT32 code = Code;
|
||||
UINT32 result = 0;
|
||||
for (int i = numTotalBits; i > 0; i--)
|
||||
{
|
||||
range >>= 1;
|
||||
/*
|
||||
result <<= 1;
|
||||
if (code >= range)
|
||||
{
|
||||
code -= range;
|
||||
result |= 1;
|
||||
}
|
||||
*/
|
||||
UINT32 t = (code - range) >> 31;
|
||||
code -= range & (t - 1);
|
||||
// range = aRangeTmp + ((range & 1) & (1 - t));
|
||||
result = (result + result) | (1 - t);
|
||||
|
||||
if (range < kTopValue)
|
||||
{
|
||||
code = (code << 8) | Stream.ReadByte();
|
||||
range <<= 8;
|
||||
}
|
||||
}
|
||||
Range = range;
|
||||
Code = code;
|
||||
return result;
|
||||
}
|
||||
|
||||
int DecodeBit(UINT32 size0, int numTotalBits)
|
||||
{
|
||||
UINT32 newBound = (Range >> numTotalBits) * size0;
|
||||
int symbol;
|
||||
if (Code < newBound)
|
||||
{
|
||||
symbol = 0;
|
||||
Range = newBound;
|
||||
}
|
||||
else
|
||||
{
|
||||
symbol = 1;
|
||||
Code -= newBound;
|
||||
Range -= newBound;
|
||||
}
|
||||
Normalize();
|
||||
return symbol;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
64
Source/7zip/7zip/Compress/LZMA_SMALL/RangeCoderBit.h
Normal file
64
Source/7zip/7zip/Compress/LZMA_SMALL/RangeCoderBit.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
// RangeCoderBit.h
|
||||
|
||||
#ifndef __RANGECODERBIT_H
|
||||
#define __RANGECODERBIT_H
|
||||
|
||||
#include "Types.h"
|
||||
#include "RangeCoder.h"
|
||||
|
||||
const int kNumBitModelTotalBits = 11;
|
||||
const int kBitModelTotal = (1 << kNumBitModelTotalBits);
|
||||
|
||||
const int kNumMoveBits = 5;
|
||||
|
||||
struct CBitModel
|
||||
{
|
||||
UINT32 Probability; // it's fast version on 32-bit systems
|
||||
// unsigned short Probability; // use it if you want to reduce memory twice
|
||||
|
||||
void UpdateModel(int symbol)
|
||||
{
|
||||
/*
|
||||
Probability -= (Probability + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
|
||||
Probability += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
|
||||
*/
|
||||
if (symbol == 0)
|
||||
Probability += (kBitModelTotal - Probability) >> kNumMoveBits;
|
||||
else
|
||||
Probability -= (Probability) >> kNumMoveBits;
|
||||
}
|
||||
void Init() { Probability = kBitModelTotal / 2; }
|
||||
};
|
||||
|
||||
struct CBitDecoder: public CBitModel
|
||||
{
|
||||
int Decode(CRangeDecoder *rangeDecoder)
|
||||
{
|
||||
UINT32 newBound = (rangeDecoder->Range >> kNumBitModelTotalBits) * Probability;
|
||||
if (rangeDecoder->Code < newBound)
|
||||
{
|
||||
rangeDecoder->Range = newBound;
|
||||
Probability += (kBitModelTotal - Probability) >> kNumMoveBits;
|
||||
if (rangeDecoder->Range < kTopValue)
|
||||
{
|
||||
rangeDecoder->Code = (rangeDecoder->Code << 8) | rangeDecoder->Stream.ReadByte();
|
||||
rangeDecoder->Range <<= 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rangeDecoder->Range -= newBound;
|
||||
rangeDecoder->Code -= newBound;
|
||||
Probability -= (Probability) >> kNumMoveBits;
|
||||
if (rangeDecoder->Range < kTopValue)
|
||||
{
|
||||
rangeDecoder->Code = (rangeDecoder->Code << 8) | rangeDecoder->Stream.ReadByte();
|
||||
rangeDecoder->Range <<= 8;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
183
Source/7zip/7zip/Compress/LZMA_SMALL/RangeCoderBitTree.h
Normal file
183
Source/7zip/7zip/Compress/LZMA_SMALL/RangeCoderBitTree.h
Normal file
|
@ -0,0 +1,183 @@
|
|||
// RangeCoderBitTree.h
|
||||
|
||||
#ifndef __RANGECODERBITTREE_H
|
||||
#define __RANGECODERBITTREE_H
|
||||
|
||||
#include "RangeCoderBit.h"
|
||||
#include "RangeCoderOpt.h"
|
||||
|
||||
class CBitTreeDecoder3
|
||||
{
|
||||
CBitDecoder m_Models[1 << 3];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(int i = 1; i < (1 << 3); i++)
|
||||
m_Models[i].Init();
|
||||
}
|
||||
int Decode(CRangeDecoder *rangeDecoder)
|
||||
{
|
||||
int modelIndex = 1;
|
||||
#ifdef __LOC_OPT
|
||||
RC_INIT_VAR
|
||||
#endif
|
||||
#ifndef __UNROLL
|
||||
for(int bitIndex = 3; bitIndex > 0; bitIndex--)
|
||||
#endif
|
||||
{
|
||||
#ifdef __LOC_OPT
|
||||
RC_GETBIT(m_Models[modelIndex].Probability, modelIndex)
|
||||
#ifdef __UNROLL
|
||||
RC_GETBIT(m_Models[modelIndex].Probability, modelIndex)
|
||||
RC_GETBIT(m_Models[modelIndex].Probability, modelIndex)
|
||||
#endif
|
||||
#else
|
||||
modelIndex = (modelIndex + modelIndex) + m_Models[modelIndex].Decode(rangeDecoder);
|
||||
#ifdef __UNROLL
|
||||
modelIndex = (modelIndex + modelIndex) + m_Models[modelIndex].Decode(rangeDecoder);
|
||||
modelIndex = (modelIndex + modelIndex) + m_Models[modelIndex].Decode(rangeDecoder);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#ifdef __LOC_OPT
|
||||
RC_FLUSH_VAR
|
||||
#endif
|
||||
return modelIndex - (1 << 3);
|
||||
};
|
||||
};
|
||||
|
||||
class CBitTreeDecoder6
|
||||
{
|
||||
CBitDecoder m_Models[1 << 6];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(int i = 1; i < (1 << 6); i++)
|
||||
m_Models[i].Init();
|
||||
}
|
||||
int Decode(CRangeDecoder *rangeDecoder)
|
||||
{
|
||||
int modelIndex = 1;
|
||||
#ifdef __LOC_OPT
|
||||
RC_INIT_VAR
|
||||
#endif
|
||||
#ifndef __UNROLL
|
||||
for(int bitIndex = 6; bitIndex > 0; bitIndex--)
|
||||
#endif
|
||||
{
|
||||
#ifdef __LOC_OPT
|
||||
RC_GETBIT(m_Models[modelIndex].Probability, modelIndex)
|
||||
#ifdef __UNROLL
|
||||
RC_GETBIT(m_Models[modelIndex].Probability, modelIndex)
|
||||
RC_GETBIT(m_Models[modelIndex].Probability, modelIndex)
|
||||
RC_GETBIT(m_Models[modelIndex].Probability, modelIndex)
|
||||
RC_GETBIT(m_Models[modelIndex].Probability, modelIndex)
|
||||
RC_GETBIT(m_Models[modelIndex].Probability, modelIndex)
|
||||
#endif
|
||||
#else
|
||||
modelIndex = (modelIndex + modelIndex) + m_Models[modelIndex].Decode(rangeDecoder);
|
||||
#ifdef __UNROLL
|
||||
modelIndex = (modelIndex + modelIndex) + m_Models[modelIndex].Decode(rangeDecoder);
|
||||
modelIndex = (modelIndex + modelIndex) + m_Models[modelIndex].Decode(rangeDecoder);
|
||||
modelIndex = (modelIndex + modelIndex) + m_Models[modelIndex].Decode(rangeDecoder);
|
||||
modelIndex = (modelIndex + modelIndex) + m_Models[modelIndex].Decode(rangeDecoder);
|
||||
modelIndex = (modelIndex + modelIndex) + m_Models[modelIndex].Decode(rangeDecoder);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#ifdef __LOC_OPT
|
||||
RC_FLUSH_VAR
|
||||
#endif
|
||||
return modelIndex - (1 << 6);
|
||||
};
|
||||
};
|
||||
|
||||
class CBitTreeDecoder8
|
||||
{
|
||||
CBitDecoder m_Models[1 << 8];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(int i = 1; i < (1 << 8); i++)
|
||||
m_Models[i].Init();
|
||||
}
|
||||
int Decode(CRangeDecoder *rangeDecoder)
|
||||
{
|
||||
int modelIndex = 1;
|
||||
#ifdef __LOC_OPT
|
||||
RC_INIT_VAR
|
||||
#endif
|
||||
for(int bitIndex = 8; bitIndex > 0; bitIndex--)
|
||||
{
|
||||
#ifdef __LOC_OPT
|
||||
RC_GETBIT(m_Models[modelIndex].Probability, modelIndex)
|
||||
#else
|
||||
modelIndex = (modelIndex + modelIndex) + m_Models[modelIndex].Decode(rangeDecoder);
|
||||
#endif
|
||||
}
|
||||
#ifdef __LOC_OPT
|
||||
RC_FLUSH_VAR
|
||||
#endif
|
||||
return modelIndex - (1 << 8);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class CReverseBitTreeDecoder4
|
||||
{
|
||||
CBitDecoder m_Models[1 << 4];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(int i = 1; i < (1 << 4); i++)
|
||||
m_Models[i].Init();
|
||||
}
|
||||
int Decode(CRangeDecoder *rangeDecoder)
|
||||
{
|
||||
int modelIndex = 1;
|
||||
int symbol = 0;
|
||||
#ifdef __LOC_OPT
|
||||
RC_INIT_VAR
|
||||
#endif
|
||||
#ifndef __UNROLL
|
||||
for(int bitIndex = 0; bitIndex < 4; bitIndex++)
|
||||
#endif
|
||||
{
|
||||
#ifdef __LOC_OPT
|
||||
#ifndef __UNROLL
|
||||
RC_GETBIT2(m_Models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << bitIndex))
|
||||
#else
|
||||
RC_GETBIT2(m_Models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << 0))
|
||||
RC_GETBIT2(m_Models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << 1))
|
||||
RC_GETBIT2(m_Models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << 2))
|
||||
RC_GETBIT2(m_Models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << 3))
|
||||
#endif
|
||||
#else
|
||||
#ifndef __UNROLL
|
||||
int bit = m_Models[modelIndex].Decode(rangeDecoder);
|
||||
modelIndex = modelIndex + modelIndex + bit;
|
||||
symbol |= (bit << bitIndex);
|
||||
#else
|
||||
int bit = m_Models[modelIndex].Decode(rangeDecoder);
|
||||
modelIndex = modelIndex + modelIndex + bit;
|
||||
symbol |= (bit << 0);
|
||||
bit = m_Models[modelIndex].Decode(rangeDecoder);
|
||||
modelIndex = modelIndex + modelIndex + bit;
|
||||
symbol |= (bit << 1);
|
||||
bit = m_Models[modelIndex].Decode(rangeDecoder);
|
||||
modelIndex = modelIndex + modelIndex + bit;
|
||||
symbol |= (bit << 2);
|
||||
bit = m_Models[modelIndex].Decode(rangeDecoder);
|
||||
modelIndex = modelIndex + modelIndex + bit;
|
||||
symbol |= (bit << 3);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#ifdef __LOC_OPT
|
||||
RC_FLUSH_VAR
|
||||
#endif
|
||||
return symbol;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
41
Source/7zip/7zip/Compress/LZMA_SMALL/RangeCoderOpt.h
Normal file
41
Source/7zip/7zip/Compress/LZMA_SMALL/RangeCoderOpt.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
// RangeCoderOpt.h
|
||||
|
||||
#ifndef __RANGECODEROPT_H
|
||||
#define __RANGECODEROPT_H
|
||||
|
||||
#include "RangeCoderBit.h"
|
||||
|
||||
#define RC_INIT_VAR \
|
||||
UINT32 range = rangeDecoder->Range; \
|
||||
UINT32 code = rangeDecoder->Code;
|
||||
|
||||
#define RC_FLUSH_VAR \
|
||||
rangeDecoder->Range = range; \
|
||||
rangeDecoder->Code = code;
|
||||
|
||||
#define RC_NORMALIZE \
|
||||
if (range < kTopValue) \
|
||||
{ range <<= 8; code = (code << 8) | rangeDecoder->Stream.ReadByte(); }
|
||||
|
||||
#define RC_GETBIT2(prob, modelIndex, Action0, Action1) \
|
||||
{UINT32 newBound = (range >> kNumBitModelTotalBits) * prob; \
|
||||
if (code < newBound) \
|
||||
{ \
|
||||
Action0; \
|
||||
range = newBound; \
|
||||
prob += (kBitModelTotal - prob) >> kNumMoveBits; \
|
||||
modelIndex <<= 1; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
Action1; \
|
||||
range -= newBound; \
|
||||
code -= newBound; \
|
||||
prob -= (prob) >> kNumMoveBits; \
|
||||
modelIndex = (modelIndex + modelIndex) + 1; \
|
||||
}} \
|
||||
RC_NORMALIZE
|
||||
|
||||
#define RC_GETBIT(prob, modelIndex) RC_GETBIT2(prob, modelIndex, ; , ;)
|
||||
|
||||
#endif
|
17
Source/7zip/7zip/Compress/LZMA_SMALL/Types.h
Normal file
17
Source/7zip/7zip/Compress/LZMA_SMALL/Types.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
// Common/Types.h
|
||||
|
||||
#ifndef __COMMON_TYPES_H
|
||||
#define __COMMON_TYPES_H
|
||||
|
||||
#ifdef WIN32
|
||||
#include <basetsd.h>
|
||||
#else
|
||||
typedef unsigned int UINT32;
|
||||
#endif
|
||||
|
||||
#ifndef _WINDOWS_
|
||||
typedef unsigned char BYTE;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
244
Source/7zip/7zip/Compress/RangeCoder/RangeCoder.h
Normal file
244
Source/7zip/7zip/Compress/RangeCoder/RangeCoder.h
Normal file
|
@ -0,0 +1,244 @@
|
|||
// Compress/RangeCoder.h
|
||||
// This code is based on Eugene Shelwien's Rangecoder code
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __COMPRESS_RANGECODER_H
|
||||
#define __COMPRESS_RANGECODER_H
|
||||
|
||||
#include "../../Common/InBuffer.h"
|
||||
#include "../../Common/OutBuffer.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRangeCoder {
|
||||
|
||||
const UINT32 kNumTopBits = 24;
|
||||
const UINT32 kTopValue = (1 << kNumTopBits);
|
||||
|
||||
class CEncoder
|
||||
{
|
||||
COutBuffer Stream;
|
||||
UINT64 Low;
|
||||
UINT32 Range;
|
||||
UINT32 _ffNum;
|
||||
BYTE _cache;
|
||||
|
||||
public:
|
||||
void Init(ISequentialOutStream *stream)
|
||||
{
|
||||
Stream.Init(stream);
|
||||
Low = 0;
|
||||
Range = UINT32(-1);
|
||||
_ffNum = 0;
|
||||
_cache = 0;
|
||||
}
|
||||
|
||||
void FlushData()
|
||||
{
|
||||
// Low += 1;
|
||||
for(int i = 0; i < 5; i++)
|
||||
ShiftLow();
|
||||
}
|
||||
|
||||
HRESULT FlushStream()
|
||||
{ return Stream.Flush(); }
|
||||
|
||||
/*
|
||||
void ReleaseStream()
|
||||
{ Stream.ReleaseStream(); }
|
||||
*/
|
||||
|
||||
void Encode(UINT32 start, UINT32 size, UINT32 total)
|
||||
{
|
||||
Low += start * (Range /= total);
|
||||
Range *= size;
|
||||
while (Range < kTopValue)
|
||||
{
|
||||
Range <<= 8;
|
||||
ShiftLow();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void EncodeDirectBitsDiv(UINT32 value, UINT32 numTotalBits)
|
||||
{
|
||||
Low += value * (Range >>= numTotalBits);
|
||||
Normalize();
|
||||
}
|
||||
|
||||
void EncodeDirectBitsDiv2(UINT32 value, UINT32 numTotalBits)
|
||||
{
|
||||
if (numTotalBits <= kNumBottomBits)
|
||||
EncodeDirectBitsDiv(value, numTotalBits);
|
||||
else
|
||||
{
|
||||
EncodeDirectBitsDiv(value >> kNumBottomBits, (numTotalBits - kNumBottomBits));
|
||||
EncodeDirectBitsDiv(value & ((1 << kBottomValueBits) - 1), kNumBottomBits);
|
||||
}
|
||||
}
|
||||
*/
|
||||
void ShiftLow()
|
||||
{
|
||||
if (Low < (UINT32)0xFF000000 || UINT32(Low >> 32) == 1)
|
||||
{
|
||||
Stream.WriteByte(_cache + BYTE(Low >> 32));
|
||||
for (;_ffNum != 0; _ffNum--)
|
||||
Stream.WriteByte(0xFF + BYTE(Low >> 32));
|
||||
_cache = BYTE(UINT32(Low) >> 24);
|
||||
}
|
||||
else
|
||||
_ffNum++;
|
||||
Low = UINT32(Low) << 8;
|
||||
}
|
||||
|
||||
void EncodeDirectBits(UINT32 value, UINT32 numTotalBits)
|
||||
{
|
||||
for (int i = numTotalBits - 1; i >= 0; i--)
|
||||
{
|
||||
Range >>= 1;
|
||||
if (((value >> i) & 1) == 1)
|
||||
Low += Range;
|
||||
if (Range < kTopValue)
|
||||
{
|
||||
Range <<= 8;
|
||||
ShiftLow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EncodeBit(UINT32 size0, UINT32 numTotalBits, UINT32 symbol)
|
||||
{
|
||||
UINT32 newBound = (Range >> numTotalBits) * size0;
|
||||
if (symbol == 0)
|
||||
Range = newBound;
|
||||
else
|
||||
{
|
||||
Low += newBound;
|
||||
Range -= newBound;
|
||||
}
|
||||
while (Range < kTopValue)
|
||||
{
|
||||
Range <<= 8;
|
||||
ShiftLow();
|
||||
}
|
||||
}
|
||||
|
||||
UINT64 GetProcessedSize() { return Stream.GetProcessedSize() + _ffNum; }
|
||||
};
|
||||
|
||||
class CDecoder
|
||||
{
|
||||
public:
|
||||
CInBuffer Stream;
|
||||
UINT32 Range;
|
||||
UINT32 Code;
|
||||
// UINT32 m_Word;
|
||||
void Normalize()
|
||||
{
|
||||
while (Range < kTopValue)
|
||||
{
|
||||
Code = (Code << 8) | Stream.ReadByte();
|
||||
Range <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
void Init(ISequentialInStream *stream)
|
||||
{
|
||||
Stream.Init(stream);
|
||||
Code = 0;
|
||||
Range = UINT32(-1);
|
||||
for(int i = 0; i < 5; i++)
|
||||
Code = (Code << 8) | Stream.ReadByte();
|
||||
}
|
||||
|
||||
// void ReleaseStream() { Stream.ReleaseStream(); }
|
||||
|
||||
UINT32 GetThreshold(UINT32 total)
|
||||
{
|
||||
return (Code) / ( Range /= total);
|
||||
}
|
||||
|
||||
void Decode(UINT32 start, UINT32 size, UINT32 total)
|
||||
{
|
||||
Code -= start * Range;
|
||||
Range *= size;
|
||||
Normalize();
|
||||
}
|
||||
|
||||
/*
|
||||
UINT32 DecodeDirectBitsDiv(UINT32 numTotalBits)
|
||||
{
|
||||
Range >>= numTotalBits;
|
||||
UINT32 threshold = Code / Range;
|
||||
Code -= threshold * Range;
|
||||
|
||||
Normalize();
|
||||
return threshold;
|
||||
}
|
||||
|
||||
UINT32 DecodeDirectBitsDiv2(UINT32 numTotalBits)
|
||||
{
|
||||
if (numTotalBits <= kNumBottomBits)
|
||||
return DecodeDirectBitsDiv(numTotalBits);
|
||||
UINT32 result = DecodeDirectBitsDiv(numTotalBits - kNumBottomBits) << kNumBottomBits;
|
||||
return (result | DecodeDirectBitsDiv(kNumBottomBits));
|
||||
}
|
||||
*/
|
||||
|
||||
UINT32 DecodeDirectBits(UINT32 numTotalBits)
|
||||
{
|
||||
UINT32 range = Range;
|
||||
UINT32 code = Code;
|
||||
UINT32 result = 0;
|
||||
for (UINT32 i = numTotalBits; i > 0; i--)
|
||||
{
|
||||
range >>= 1;
|
||||
/*
|
||||
result <<= 1;
|
||||
if (code >= range)
|
||||
{
|
||||
code -= range;
|
||||
result |= 1;
|
||||
}
|
||||
*/
|
||||
UINT32 t = (code - range) >> 31;
|
||||
code -= range & (t - 1);
|
||||
// range = rangeTmp + ((range & 1) & (1 - t));
|
||||
result = (result << 1) | (1 - t);
|
||||
|
||||
if (range < kTopValue)
|
||||
{
|
||||
code = (code << 8) | Stream.ReadByte();
|
||||
range <<= 8;
|
||||
}
|
||||
}
|
||||
Range = range;
|
||||
Code = code;
|
||||
return result;
|
||||
}
|
||||
|
||||
UINT32 DecodeBit(UINT32 size0, UINT32 numTotalBits)
|
||||
{
|
||||
UINT32 newBound = (Range >> numTotalBits) * size0;
|
||||
UINT32 symbol;
|
||||
if (Code < newBound)
|
||||
{
|
||||
symbol = 0;
|
||||
Range = newBound;
|
||||
}
|
||||
else
|
||||
{
|
||||
symbol = 1;
|
||||
Code -= newBound;
|
||||
Range -= newBound;
|
||||
}
|
||||
Normalize();
|
||||
return symbol;
|
||||
}
|
||||
|
||||
UINT64 GetProcessedSize() {return Stream.GetProcessedSize(); }
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
77
Source/7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp
Normal file
77
Source/7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
// Compress/RangeCoder/RangeCoderBit.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "RangeCoderBit.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRangeCoder {
|
||||
|
||||
CPriceTables::CPriceTables()
|
||||
{
|
||||
/*
|
||||
// simplest: bad solution
|
||||
for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
||||
StatePrices[i] = kBitPrice;
|
||||
*/
|
||||
|
||||
/*
|
||||
const double kDummyMultMid = (1.0 / kBitPrice) / 2;
|
||||
const double kDummyMultMid = 0;
|
||||
// float solution
|
||||
double ln2 = log(double(2));
|
||||
double lnAll = log(double(kBitModelTotal >> kNumMoveReducingBits));
|
||||
for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
||||
StatePrices[i] = UINT32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice);
|
||||
*/
|
||||
|
||||
/*
|
||||
// experimental, slow, solution:
|
||||
for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
||||
{
|
||||
const int kCyclesBits = 5;
|
||||
const UINT32 kCycles = (1 << kCyclesBits);
|
||||
|
||||
UINT32 range = UINT32(-1);
|
||||
UINT32 bitCount = 0;
|
||||
for (UINT32 j = 0; j < kCycles; j++)
|
||||
{
|
||||
range >>= (kNumBitModelTotalBits - kNumMoveReducingBits);
|
||||
range *= i;
|
||||
while(range < (1 << 31))
|
||||
{
|
||||
range <<= 1;
|
||||
bitCount++;
|
||||
}
|
||||
}
|
||||
bitCount <<= kNumBitPriceShiftBits;
|
||||
range -= (1 << 31);
|
||||
for (int k = kNumBitPriceShiftBits - 1; k >= 0; k--)
|
||||
{
|
||||
range <<= 1;
|
||||
if (range > (1 << 31))
|
||||
{
|
||||
bitCount += (1 << k);
|
||||
range -= (1 << 31);
|
||||
}
|
||||
}
|
||||
StatePrices[i] = (bitCount
|
||||
// + (1 << (kCyclesBits - 1))
|
||||
) >> kCyclesBits;
|
||||
}
|
||||
*/
|
||||
|
||||
const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
|
||||
for(int i = kNumBits - 1; i >= 0; i--)
|
||||
{
|
||||
UINT32 start = 1 << (kNumBits - i - 1);
|
||||
UINT32 end = 1 << (kNumBits - i);
|
||||
for (UINT32 j = start; j < end; j++)
|
||||
StatePrices[j] = (i << kNumBitPriceShiftBits) +
|
||||
(((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
|
||||
}
|
||||
}
|
||||
|
||||
CPriceTables g_PriceTables;
|
||||
|
||||
}}
|
107
Source/7zip/7zip/Compress/RangeCoder/RangeCoderBit.h
Normal file
107
Source/7zip/7zip/Compress/RangeCoder/RangeCoderBit.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
// Compress/RangeCoder/RangeCoderBit.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
|
||||
#define __COMPRESS_RANGECODER_BIT_TREE_H
|
||||
|
||||
#include "RangeCoder.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRangeCoder {
|
||||
|
||||
const int kNumBitModelTotalBits = 11;
|
||||
const UINT32 kBitModelTotal = (1 << kNumBitModelTotalBits);
|
||||
|
||||
const int kNumMoveReducingBits = 2;
|
||||
|
||||
const int kNumBitPriceShiftBits = 6;
|
||||
const UINT32 kBitPrice = 1 << kNumBitPriceShiftBits;
|
||||
|
||||
class CPriceTables
|
||||
{
|
||||
public:
|
||||
UINT32 StatePrices[kBitModelTotal >> kNumMoveReducingBits];
|
||||
CPriceTables();
|
||||
};
|
||||
|
||||
extern CPriceTables g_PriceTables;
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CBitModel
|
||||
|
||||
template <int aNumMoveBits>
|
||||
class CBitModel
|
||||
{
|
||||
public:
|
||||
UINT32 Probability;
|
||||
void UpdateModel(UINT32 symbol)
|
||||
{
|
||||
/*
|
||||
Probability -= (Probability + ((symbol - 1) & ((1 << aNumMoveBits) - 1))) >> aNumMoveBits;
|
||||
Probability += (1 - symbol) << (kNumBitModelTotalBits - aNumMoveBits);
|
||||
*/
|
||||
if (symbol == 0)
|
||||
Probability += (kBitModelTotal - Probability) >> aNumMoveBits;
|
||||
else
|
||||
Probability -= (Probability) >> aNumMoveBits;
|
||||
}
|
||||
public:
|
||||
void Init() { Probability = kBitModelTotal / 2; }
|
||||
};
|
||||
|
||||
template <int aNumMoveBits>
|
||||
class CBitEncoder: public CBitModel<aNumMoveBits>
|
||||
{
|
||||
public:
|
||||
void Encode(CEncoder *encoder, UINT32 symbol)
|
||||
{
|
||||
encoder->EncodeBit(Probability, kNumBitModelTotalBits, symbol);
|
||||
UpdateModel(symbol);
|
||||
}
|
||||
UINT32 GetPrice(UINT32 symbol) const
|
||||
{
|
||||
return g_PriceTables.StatePrices[
|
||||
(((Probability - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <int aNumMoveBits>
|
||||
class CBitDecoder: public CBitModel<aNumMoveBits>
|
||||
{
|
||||
public:
|
||||
UINT32 Decode(CDecoder *decoder)
|
||||
{
|
||||
UINT32 newBound = (decoder->Range >> kNumBitModelTotalBits) * Probability;
|
||||
if (decoder->Code < newBound)
|
||||
{
|
||||
decoder->Range = newBound;
|
||||
Probability += (kBitModelTotal - Probability) >> aNumMoveBits;
|
||||
if (decoder->Range < kTopValue)
|
||||
{
|
||||
decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
|
||||
decoder->Range <<= 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
decoder->Range -= newBound;
|
||||
decoder->Code -= newBound;
|
||||
Probability -= (Probability) >> aNumMoveBits;
|
||||
if (decoder->Range < kTopValue)
|
||||
{
|
||||
decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
|
||||
decoder->Range <<= 8;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif
|
303
Source/7zip/7zip/Compress/RangeCoder/RangeCoderBitTree.h
Normal file
303
Source/7zip/7zip/Compress/RangeCoder/RangeCoderBitTree.h
Normal file
|
@ -0,0 +1,303 @@
|
|||
// Compress/RangeCoder/RangeCoderBitTree.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __COMPRESS_RANGECODER_BIT_H
|
||||
#define __COMPRESS_RANGECODER_BIT_H
|
||||
|
||||
#include "RangeCoderBit.h"
|
||||
#include "RangeCoderOpt.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRangeCoder {
|
||||
|
||||
/*
|
||||
template <int numMoveBits> class CMyBitEncoder:
|
||||
public NCompression::NArithmetic::CBitEncoder<numMoveBits> {};
|
||||
template <int numMoveBits> class CMyBitDecoder:
|
||||
public NCompression::NArithmetic::CBitDecoder<numMoveBits> {};
|
||||
*/
|
||||
|
||||
//////////////////////////
|
||||
// CBitTreeEncoder
|
||||
|
||||
template <int numMoveBits, UINT32 NumBitLevels>
|
||||
class CBitTreeEncoder
|
||||
{
|
||||
CBitEncoder<numMoveBits> Models[1 << NumBitLevels];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(UINT32 i = 1; i < (1 << NumBitLevels); i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
void Encode(CEncoder *rangeEncoder, UINT32 symbol)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
|
||||
{
|
||||
bitIndex--;
|
||||
UINT32 bit = (symbol >> bitIndex ) & 1;
|
||||
Models[modelIndex].Encode(rangeEncoder, bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
}
|
||||
};
|
||||
UINT32 GetPrice(UINT32 symbol) const
|
||||
{
|
||||
UINT32 price = 0;
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
|
||||
{
|
||||
bitIndex--;
|
||||
UINT32 bit = (symbol >> bitIndex ) & 1;
|
||||
price += Models[modelIndex].GetPrice(bit);
|
||||
modelIndex = (modelIndex << 1) + bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////
|
||||
// CBitTreeDecoder
|
||||
|
||||
template <int numMoveBits, UINT32 NumBitLevels>
|
||||
class CBitTreeDecoder
|
||||
{
|
||||
CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(UINT32 i = 1; i < (1 << NumBitLevels); i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
UINT32 Decode(CDecoder *rangeDecoder)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
RC_INIT_VAR
|
||||
for(UINT32 bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
|
||||
{
|
||||
// modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
|
||||
RC_GETBIT(numMoveBits, Models[modelIndex].Probability, modelIndex)
|
||||
}
|
||||
RC_FLUSH_VAR
|
||||
return modelIndex - (1 << NumBitLevels);
|
||||
};
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
// CReverseBitTreeEncoder
|
||||
|
||||
template <int numMoveBits>
|
||||
class CReverseBitTreeEncoder2
|
||||
{
|
||||
CBitEncoder<numMoveBits> *Models;
|
||||
UINT32 NumBitLevels;
|
||||
public:
|
||||
CReverseBitTreeEncoder2(): Models(0) { }
|
||||
~CReverseBitTreeEncoder2() { delete []Models; }
|
||||
void Create(UINT32 numBitLevels)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new CBitEncoder<numMoveBits>[1 << numBitLevels];
|
||||
// return (Models != 0);
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
UINT32 numModels = 1 << NumBitLevels;
|
||||
for(UINT32 i = 1; i < numModels; i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
void Encode(CEncoder *rangeEncoder, UINT32 symbol)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 i = 0; i < NumBitLevels; i++)
|
||||
{
|
||||
UINT32 bit = symbol & 1;
|
||||
Models[modelIndex].Encode(rangeEncoder, bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
symbol >>= 1;
|
||||
}
|
||||
}
|
||||
UINT32 GetPrice(UINT32 symbol) const
|
||||
{
|
||||
UINT32 price = 0;
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 i = NumBitLevels; i > 0; i--)
|
||||
{
|
||||
UINT32 bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
price += Models[modelIndex].GetPrice(bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
template <int numMoveBits, int numBitLevels>
|
||||
class CReverseBitTreeEncoder: public CReverseBitTreeEncoder2<numMoveBits>
|
||||
{
|
||||
public:
|
||||
CReverseBitTreeEncoder()
|
||||
{ Create(numBitLevels); }
|
||||
};
|
||||
*/
|
||||
////////////////////////////////
|
||||
// CReverseBitTreeDecoder
|
||||
|
||||
template <int numMoveBits>
|
||||
class CReverseBitTreeDecoder2
|
||||
{
|
||||
CBitDecoder<numMoveBits> *Models;
|
||||
UINT32 NumBitLevels;
|
||||
public:
|
||||
CReverseBitTreeDecoder2(): Models(0) { }
|
||||
~CReverseBitTreeDecoder2() { delete []Models; }
|
||||
void Create(UINT32 numBitLevels)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new CBitDecoder<numMoveBits>[1 << numBitLevels];
|
||||
// return (Models != 0);
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
UINT32 numModels = 1 << NumBitLevels;
|
||||
for(UINT32 i = 1; i < numModels; i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
UINT32 Decode(CDecoder *rangeDecoder)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
UINT32 symbol = 0;
|
||||
RC_INIT_VAR
|
||||
for(UINT32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
{
|
||||
// UINT32 bit = Models[modelIndex].Decode(rangeDecoder);
|
||||
// modelIndex <<= 1;
|
||||
// modelIndex += bit;
|
||||
// symbol |= (bit << bitIndex);
|
||||
RC_GETBIT2(numMoveBits, Models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << bitIndex))
|
||||
}
|
||||
RC_FLUSH_VAR
|
||||
return symbol;
|
||||
};
|
||||
};
|
||||
////////////////////////////
|
||||
// CReverseBitTreeDecoder2
|
||||
|
||||
template <int numMoveBits, UINT32 NumBitLevels>
|
||||
class CReverseBitTreeDecoder
|
||||
{
|
||||
CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(UINT32 i = 1; i < (1 << NumBitLevels); i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
UINT32 Decode(CDecoder *rangeDecoder)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
UINT32 symbol = 0;
|
||||
RC_INIT_VAR
|
||||
for(UINT32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
{
|
||||
// UINT32 bit = Models[modelIndex].Decode(rangeDecoder);
|
||||
// modelIndex <<= 1;
|
||||
// modelIndex += bit;
|
||||
// symbol |= (bit << bitIndex);
|
||||
RC_GETBIT2(numMoveBits, Models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << bitIndex))
|
||||
}
|
||||
RC_FLUSH_VAR
|
||||
return symbol;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
//////////////////////////
|
||||
// CBitTreeEncoder2
|
||||
|
||||
template <int numMoveBits>
|
||||
class CBitTreeEncoder2
|
||||
{
|
||||
NCompression::NArithmetic::CBitEncoder<numMoveBits> *Models;
|
||||
UINT32 NumBitLevels;
|
||||
public:
|
||||
bool Create(UINT32 numBitLevels)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new NCompression::NArithmetic::CBitEncoder<numMoveBits>[1 << numBitLevels];
|
||||
return (Models != 0);
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
UINT32 numModels = 1 << NumBitLevels;
|
||||
for(UINT32 i = 1; i < numModels; i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
void Encode(CMyRangeEncoder *rangeEncoder, UINT32 symbol)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
|
||||
{
|
||||
bitIndex--;
|
||||
UINT32 bit = (symbol >> bitIndex ) & 1;
|
||||
Models[modelIndex].Encode(rangeEncoder, bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
}
|
||||
}
|
||||
UINT32 GetPrice(UINT32 symbol) const
|
||||
{
|
||||
UINT32 price = 0;
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
|
||||
{
|
||||
bitIndex--;
|
||||
UINT32 bit = (symbol >> bitIndex ) & 1;
|
||||
price += Models[modelIndex].GetPrice(bit);
|
||||
modelIndex = (modelIndex << 1) + bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////
|
||||
// CBitTreeDecoder2
|
||||
|
||||
template <int numMoveBits>
|
||||
class CBitTreeDecoder2
|
||||
{
|
||||
NCompression::NArithmetic::CBitDecoder<numMoveBits> *Models;
|
||||
UINT32 NumBitLevels;
|
||||
public:
|
||||
bool Create(UINT32 numBitLevels)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new NCompression::NArithmetic::CBitDecoder<numMoveBits>[1 << numBitLevels];
|
||||
return (Models != 0);
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
UINT32 numModels = 1 << NumBitLevels;
|
||||
for(UINT32 i = 1; i < numModels; i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
UINT32 Decode(CMyRangeDecoder *rangeDecoder)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
RC_INIT_VAR
|
||||
for(UINT32 bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
|
||||
{
|
||||
// modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
|
||||
RC_GETBIT(numMoveBits, Models[modelIndex].Probability, modelIndex)
|
||||
}
|
||||
RC_FLUSH_VAR
|
||||
return modelIndex - (1 << NumBitLevels);
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
43
Source/7zip/7zip/Compress/RangeCoder/RangeCoderOpt.h
Normal file
43
Source/7zip/7zip/Compress/RangeCoder/RangeCoderOpt.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Compress/RangeCoder/RangeCoderOpt.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __COMPRESS_RANGECODER_OPT_H
|
||||
#define __COMPRESS_RANGECODER_OPT_H
|
||||
|
||||
#define RC_INIT_VAR \
|
||||
UINT32 range = rangeDecoder->Range; \
|
||||
UINT32 code = rangeDecoder->Code;
|
||||
|
||||
#define RC_FLUSH_VAR \
|
||||
rangeDecoder->Range = range; \
|
||||
rangeDecoder->Code = code;
|
||||
|
||||
#define RC_NORMALIZE \
|
||||
if (range < NCompress::NRangeCoder::kTopValue) \
|
||||
{ \
|
||||
code = (code << 8) | rangeDecoder->Stream.ReadByte(); \
|
||||
range <<= 8; }
|
||||
|
||||
#define RC_GETBIT2(numMoveBits, prob, modelIndex, Action0, Action1) \
|
||||
{UINT32 newBound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \
|
||||
if (code < newBound) \
|
||||
{ \
|
||||
Action0; \
|
||||
range = newBound; \
|
||||
prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \
|
||||
modelIndex <<= 1; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
Action1; \
|
||||
range -= newBound; \
|
||||
code -= newBound; \
|
||||
prob -= (prob) >> numMoveBits; \
|
||||
modelIndex = (modelIndex << 1) + 1; \
|
||||
}} \
|
||||
RC_NORMALIZE
|
||||
|
||||
#define RC_GETBIT(numMoveBits, prob, modelIndex) RC_GETBIT2(numMoveBits, prob, modelIndex, ; , ;)
|
||||
|
||||
#endif
|
8
Source/7zip/7zip/Compress/RangeCoder/StdAfx.h
Normal file
8
Source/7zip/7zip/Compress/RangeCoder/StdAfx.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue