fixed bug #1005296 - NSIS build error on Linux with g++ 3.4.0

- upgraded to the latest LZMA SDK


git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@3637 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
kichik 2004-08-20 19:17:21 +00:00
parent 98caca8be1
commit ec6957f356
52 changed files with 1715 additions and 2540 deletions

View file

@ -1,19 +1,36 @@
// InBuffer.cpp
#include "stdafx.h"
#include "StdAfx.h"
#include "InBuffer.h"
CInBuffer::CInBuffer(UINT32 bufferSize):
_bufferSize(bufferSize),
_bufferBase(0)
#include "../../Common/Alloc.h"
CInBuffer::CInBuffer():
_bufferBase(0),
_bufferSize(0),
_buffer(0),
_bufferLimit(0),
_stream(0)
{}
bool CInBuffer::Create(UInt32 bufferSize)
{
_bufferBase = new BYTE[_bufferSize];
const UInt32 kMinBlockSize = 1;
if (bufferSize < kMinBlockSize)
bufferSize = kMinBlockSize;
if (_bufferBase != 0 && _bufferSize == bufferSize)
return true;
Free();
_bufferSize = bufferSize;
_bufferBase = (Byte *)::BigAlloc(bufferSize);
return (_bufferBase != 0);
}
CInBuffer::~CInBuffer()
void CInBuffer::Free()
{
delete []_bufferBase;
BigFree(_bufferBase);
_bufferBase = 0;
}
void CInBuffer::Init(ISequentialInStream *stream)
@ -22,20 +39,31 @@ void CInBuffer::Init(ISequentialInStream *stream)
_processedSize = 0;
_buffer = _bufferBase;
_bufferLimit = _buffer;
_streamWasExhausted = false;
_wasFinished = false;
#ifdef _NO_EXCEPTIONS
ErrorCode = S_OK;
#endif
}
bool CInBuffer::ReadBlock()
{
if (_streamWasExhausted)
#ifdef _NO_EXCEPTIONS
if (ErrorCode != S_OK)
return false;
#endif
if (_wasFinished)
return false;
_processedSize += (_buffer - _bufferBase);
UINT32 numProcessedBytes;
UInt32 numProcessedBytes;
HRESULT result = _stream->ReadPart(_bufferBase, _bufferSize, &numProcessedBytes);
#ifdef _NO_EXCEPTIONS
ErrorCode = result;
#else
if (result != S_OK)
throw CInBufferException(result);
#endif
_buffer = _bufferBase;
_bufferLimit = _buffer + numProcessedBytes;
_streamWasExhausted = (numProcessedBytes == 0);
return (!_streamWasExhausted);
_wasFinished = (numProcessedBytes == 0);
return (!_wasFinished);
}

View file

@ -1,69 +1,74 @@
// InBuffer.h
// #pragma once
#ifndef __INBUFFER_H
#define __INBUFFER_H
#include "../IStream.h"
#ifndef _NO_EXCEPTIONS
class CInBufferException
{
public:
HRESULT ErrorCode;
CInBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
};
#endif
class CInBuffer
{
UINT64 _processedSize;
BYTE *_bufferBase;
UINT32 _bufferSize;
BYTE *_buffer;
BYTE *_bufferLimit;
UInt64 _processedSize;
Byte *_bufferBase;
UInt32 _bufferSize;
Byte *_buffer;
Byte *_bufferLimit;
ISequentialInStream *_stream;
bool _streamWasExhausted;
bool _wasFinished;
bool ReadBlock();
public:
CInBuffer(UINT32 bufferSize = 0x100000);
~CInBuffer();
#ifdef _NO_EXCEPTIONS
HRESULT ErrorCode;
#endif
CInBuffer();
~CInBuffer() { Free(); }
bool Create(UInt32 bufferSize);
void Free();
void Init(ISequentialInStream *stream);
/*
void ReleaseStream()
{ _stream.Release(); }
*/
// void ReleaseStream() { _stream.Release(); }
bool ReadByte(BYTE &b)
{
if(_buffer >= _bufferLimit)
if(!ReadBlock())
return false;
b = *_buffer++;
return true;
}
BYTE ReadByte()
{
if(_buffer >= _bufferLimit)
if(!ReadBlock())
return 0x0;
return *_buffer++;
}
void ReadBytes(void *data, UINT32 size, UINT32 &processedSize)
{
for(processedSize = 0; processedSize < size; processedSize++)
if (!ReadByte(((BYTE *)data)[processedSize]))
return;
}
bool ReadBytes(void *data, UINT32 size)
{
UINT32 processedSize;
ReadBytes(data, size, processedSize);
return (processedSize == size);
}
UINT64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
bool ReadByte(Byte &b)
{
if(_buffer >= _bufferLimit)
if(!ReadBlock())
return false;
b = *_buffer++;
return true;
}
Byte ReadByte()
{
if(_buffer >= _bufferLimit)
if(!ReadBlock())
return 0xFF;
return *_buffer++;
}
void ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
{
for(processedSize = 0; processedSize < size; processedSize++)
if (!ReadByte(((Byte *)data)[processedSize]))
return;
}
bool ReadBytes(void *data, UInt32 size)
{
UInt32 processedSize;
ReadBytes(data, size, processedSize);
return (processedSize == size);
}
UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
bool WasFinished() const { return _wasFinished; }
};
#endif

View file

@ -1,18 +1,28 @@
// Stream/OutByte.cpp
// OutByte.cpp
#include "StdAfx.h"
#include "OutBuffer.h"
COutBuffer::COutBuffer(UINT32 bufferSize):
_bufferSize(bufferSize)
#include "../../Common/Alloc.h"
bool COutBuffer::Create(UInt32 bufferSize)
{
_buffer = new BYTE[_bufferSize];
const UInt32 kMinBlockSize = 1;
if (bufferSize < kMinBlockSize)
bufferSize = kMinBlockSize;
if (_buffer != 0 && _bufferSize == bufferSize)
return true;
Free();
_bufferSize = bufferSize;
_buffer = (Byte *)::BigAlloc(bufferSize);
return (_buffer != 0);
}
COutBuffer::~COutBuffer()
void COutBuffer::Free()
{
delete []_buffer;
BigFree(_buffer);
_buffer = 0;
}
void COutBuffer::Init(ISequentialOutStream *stream)
@ -20,21 +30,16 @@ void COutBuffer::Init(ISequentialOutStream *stream)
_stream = stream;
_processedSize = 0;
_pos = 0;
#ifdef _NO_EXCEPTIONS
ErrorCode = S_OK;
#endif
}
/*
void COutBuffer::ReleaseStream()
{
_stream.Release();
}
*/
HRESULT COutBuffer::Flush()
{
if (_pos == 0)
return S_OK;
UINT32 processedSize;
UInt32 processedSize;
HRESULT result = _stream->Write(_buffer, _pos, &processedSize);
if (result != S_OK)
return result;
@ -47,7 +52,15 @@ HRESULT COutBuffer::Flush()
void COutBuffer::WriteBlock()
{
#ifdef _NO_EXCEPTIONS
if (ErrorCode != S_OK)
return;
#endif
HRESULT result = Flush();
#ifdef _NO_EXCEPTIONS
ErrorCode = result;
#else
if (result != S_OK)
throw COutBufferException(result);
#endif
}

View file

@ -1,49 +1,69 @@
// OutBuffer.h
// #pragma once
#ifndef __OUTBUFFER_H
#define __OUTBUFFER_H
#include "../IStream.h"
class COutBufferException
#ifndef _NO_EXCEPTIONS
struct COutBufferException
{
public:
HRESULT ErrorCode;
COutBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
};
#endif
class COutBuffer
{
BYTE *_buffer;
UINT32 _pos;
UINT32 _bufferSize;
Byte *_buffer;
UInt32 _pos;
UInt32 _bufferSize;
ISequentialOutStream *_stream;
UINT64 _processedSize;
UInt64 _processedSize;
void WriteBlock();
public:
COutBuffer(UINT32 bufferSize = (1 << 20));
~COutBuffer();
#ifdef _NO_EXCEPTIONS
HRESULT ErrorCode;
#endif
COutBuffer(): _buffer(0), _pos(0), _stream(0) {}
~COutBuffer() { Free(); }
bool Create(UInt32 bufferSize);
void Free();
void Init(ISequentialOutStream *stream);
HRESULT Flush();
// void ReleaseStream();
// void ReleaseStream(); { _stream.Release(); }
void WriteByte(BYTE b)
/*
void *GetBuffer(UInt32 &sizeAvail)
{
sizeAvail = _bufferSize - _pos;
return _buffer + _pos;
}
void MovePos(UInt32 num)
{
_pos += num;
if(_pos >= _bufferSize)
WriteBlock();
}
*/
void WriteByte(Byte b)
{
_buffer[_pos++] = b;
if(_pos >= _bufferSize)
WriteBlock();
}
void WriteBytes(const void *data, UINT32 size)
void WriteBytes(const void *data, UInt32 size)
{
for (UINT32 i = 0; i < size; i++)
WriteByte(((const BYTE *)data)[i]);
for (UInt32 i = 0; i < size; i++)
WriteByte(((const Byte *)data)[i]);
}
UINT64 GetProcessedSize() const { return _processedSize + _pos; }
UInt64 GetProcessedSize() const { return _processedSize + _pos; }
};
#endif

View file

@ -1,12 +1,8 @@
// stdafx.h
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#ifdef _WIN32
# include <windows.h>
#else
# include "../../../Platform.h"
#endif
#include "../../../Platform.h"
#endif

View file

@ -1,48 +1,14 @@
// 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)
#pragma pack(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)
#pragma pack()
#else
typedef UINT32 CIndex;
const UINT32 kMaxValForNormalize = (UINT32(1) << 31) - 1;
#endif
typedef UInt32 CIndex;
const UInt32 kMaxValForNormalize = (UInt32(1) << 31) - 1;
// #define HASH_ARRAY_2
@ -56,26 +22,31 @@ const UINT32 kMaxValForNormalize = (UINT32(1) << 31) - 1;
// #endif
//#pragma pack(push, PragmaBinTreePair, 1)
#pragma pack(1)
// #pragma pack(push, 1)
struct CPair
{
CIndex Left;
CIndex Right;
};
// #pragma pack(pop)
//#pragma pack(pop, PragmaBinTreePair)
#pragma pack()
/*
const int kNumBundleBits = 2;
const UInt32 kNumPairsInBundle = 1 << kNumBundleBits;
const UInt32 kBundleMask = kNumPairsInBundle - 1;
const UInt32 kNumBundleBytes = kNumPairsInBundle * sizeof(CPair);
struct CBundle
{
CPair Pairs[kNumPairsInBundle];
Byte Bytes[kNumBundleBytes];
};
*/
class CInTree: public CLZInWindow
{
UINT32 _cyclicBufferPos;
UINT32 _cyclicBufferSize;
UINT32 _historySize;
UINT32 _matchMaxLen;
UInt32 _cyclicBufferPos;
UInt32 _cyclicBufferSize;
UInt32 _historySize;
UInt32 _matchMaxLen;
CIndex *_hash;
@ -86,22 +57,23 @@ class CInTree: public CLZInWindow
#endif
#endif
// CBundle *_son;
CPair *_son;
UINT32 _cutValue;
UInt32 _cutValue;
void NormalizeLinks(CIndex *array, UINT32 numItems, UINT32 subValue);
void NormalizeLinks(CIndex *items, UInt32 numItems, UInt32 subValue);
void Normalize();
void FreeMemory();
public:
CInTree();
virtual ~CInTree();
HRESULT Create(UINT32 sizeHistory, UINT32 keepAddBufferBefore, UINT32 matchMaxLen,
UINT32 keepAddBufferAfter, UINT32 sizeReserv = (1<<17));
~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 SetCutValue(UInt32 cutValue) { _cutValue = cutValue; }
UInt32 GetLongestMatch(UInt32 *distances);
void DummyLongestMatch();
HRESULT MovePos()
{

View file

@ -1,7 +1,5 @@
// BinTree2.h
// #pragma once
#ifndef __BINTREE2__H
#define __BINTREE2__H

View file

@ -1,7 +1,5 @@
// BinTree3.h
// #pragma once
#ifndef __BINTREE3__H
#define __BINTREE3__H

View file

@ -1,7 +1,5 @@
// BinTree3Z.h
// #pragma once
#ifndef __BINTREE3Z__H
#define __BINTREE3Z__H

View file

@ -1,7 +1,5 @@
// BinTree3ZMain.h
// #pragma once
#ifndef __BINTREE3ZMAIN__H
#define __BINTREE3ZMAIN__H

View file

@ -1,7 +1,5 @@
// BinTree4.h
// #pragma once
#ifndef __BINTREE4__H
#define __BINTREE4__H

View file

@ -1,7 +1,5 @@
// BinTree4b.h
// #pragma once
#ifndef __BINTREE4B__H
#define __BINTREE4B__H

View file

@ -1,7 +1,5 @@
// BinTreeMF.h
// #pragma once
// #ifndef __BINTREEMF_H
// #define __BINTREEMF_H
@ -39,13 +37,8 @@ namespace BT_NAMESPACE {
#undef kIDUse3BytesByte
#undef kIDUse3BytesString
#ifdef __USE_3_BYTES
#define kIDUse3BytesByte 0x80
#define kIDUse3BytesString TEXT("T")
#else
#define kIDUse3BytesByte 0x00
#define kIDUse3BytesString TEXT("")
#endif
#define kIDUse3BytesByte 0x00
#define kIDUse3BytesString TEXT("")
// #undef kIDStringFull
@ -62,7 +55,6 @@ class CInTree2: public CInTree
virtual void BeforeMoveBlock();
virtual void AfterMoveBlock();
public:
virtual ~CInTree2() {}
void SetCallback(IMatchFinderCallback *callback)
{
_callback = callback;
@ -79,28 +71,28 @@ class CMatchFinderBinTree:
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_(Byte, GetIndexByte)(Int32 index);
STDMETHOD_(UInt32, GetMatchLen)(Int32 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;
// UInt32 m_WindowReservSize;
CInTree2 _matchFinder;
public:
// CMatchFinderBinTree(): m_WindowReservSize((1 << 19) + 256) {};
void SetCutValue(UINT32 cutValue)
void SetCutValue(UInt32 cutValue)
{ _matchFinder.SetCutValue(cutValue); }
/*
void SetWindowReservSize(UINT32 reservWindowSize)
void SetWindowReservSize(UInt32 reservWindowSize)
{ m_WindowReservSize = reservWindowSize; }
*/
virtual ~CMatchFinderBinTree() {}

View file

@ -32,40 +32,42 @@ STDMETHODIMP_(void) CMatchFinderBinTree::ReleaseStream()
STDMETHODIMP CMatchFinderBinTree::MovePos()
{ return _matchFinder.MovePos(); }
STDMETHODIMP_(BYTE) CMatchFinderBinTree::GetIndexByte(UINT32 index)
STDMETHODIMP_(Byte) CMatchFinderBinTree::GetIndexByte(Int32 index)
{ return _matchFinder.GetIndexByte(index); }
STDMETHODIMP_(UINT32) CMatchFinderBinTree::GetMatchLen(UINT32 index,
UINT32 back, UINT32 limit)
STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetMatchLen(Int32 index,
UInt32 back, UInt32 limit)
{ return _matchFinder.GetMatchLen(index, back, limit); }
STDMETHODIMP_(UINT32) CMatchFinderBinTree::GetNumAvailableBytes()
STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetNumAvailableBytes()
{ return _matchFinder.GetNumAvailableBytes(); }
STDMETHODIMP CMatchFinderBinTree::Create(UINT32 sizeHistory,
UINT32 keepAddBufferBefore, UINT32 matchMaxLen,
UINT32 keepAddBufferAfter)
STDMETHODIMP CMatchFinderBinTree::Create(UInt32 sizeHistory,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen,
UInt32 keepAddBufferAfter)
{
UINT32 windowReservSize = (sizeHistory + keepAddBufferBefore +
UInt32 windowReservSize = (sizeHistory + keepAddBufferBefore +
matchMaxLen + keepAddBufferAfter) / 2 + 256;
try
// try
{
return _matchFinder.Create(sizeHistory, keepAddBufferBefore,
matchMaxLen, keepAddBufferAfter, windowReservSize);
}
/*
catch(...)
{
return E_OUTOFMEMORY;
}
*/
}
STDMETHODIMP_(UINT32) CMatchFinderBinTree::GetLongestMatch(UINT32 *distances)
STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetLongestMatch(UInt32 *distances)
{ return _matchFinder.GetLongestMatch(distances); }
STDMETHODIMP_(void) CMatchFinderBinTree::DummyLongestMatch()
{ _matchFinder.DummyLongestMatch(); }
STDMETHODIMP_(const BYTE *) CMatchFinderBinTree::GetPointerToCurrentPos()
STDMETHODIMP_(const Byte *) CMatchFinderBinTree::GetPointerToCurrentPos()
{
return _matchFinder.GetPointerToCurrentPos();
}

View file

@ -1,40 +1,36 @@
// BinTreemain.h
// #include "StdAfx.h"
// #include "BinTree.h"
// #include "Common/NewHandler.h"
// BinTreeMain.h
#include "../../../../Common/Defs.h"
#include "../../../../Common/CRC.h"
#include "../../../../Common/Alloc.h"
namespace BT_NAMESPACE {
#ifdef HASH_ARRAY_2
static const UINT32 kHash2Size = 1 << 10;
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;
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;
static const UInt32 kHashSize = 1 << 23;
#else
static const UINT32 kHashSize = 1 << 20;
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);
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;
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);
static const UInt32 kNumHashDirectBytes = 2;
static const UInt32 kNumHashBytes = 2;
static const UInt32 kHashSize = 1 << (8 * kNumHashBytes);
#endif
#endif
@ -54,16 +50,9 @@ CInTree::CInTree():
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
BigFree(_son);
_son = 0;
BigFree(_hash);
_hash = 0;
CLZInWindow::Free();
}
@ -73,68 +62,63 @@ CInTree::~CInTree()
FreeMemory();
}
HRESULT CInTree::Create(UINT32 sizeHistory, UINT32 keepAddBufferBefore,
UINT32 matchMaxLen, UINT32 keepAddBufferAfter, UINT32 sizeReserv)
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 CMemoryException();
_hash = (CIndex *)::VirtualAlloc(0, (size + 1) * sizeof(CIndex), MEM_COMMIT, PAGE_READWRITE);
if (_hash == 0)
throw CMemoryException();
#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(...)
if (!CLZInWindow::Create(sizeHistory + keepAddBufferBefore,
matchMaxLen + keepAddBufferAfter, sizeReserv))
return E_OUTOFMEMORY;
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
_son = (CPair *)BigAlloc((_cyclicBufferSize + 1) * sizeof(CPair));
if (_son == 0)
{
FreeMemory();
return E_OUTOFMEMORY;
}
// UInt32 numBundles = (_cyclicBufferSize + kNumPairsInBundle) >> kNumBundleBits;
// _son = (CBundle *)::VirtualAlloc(0, numBundles * sizeof(CBundle), MEM_COMMIT, PAGE_READWRITE);
_hash = (CIndex *)BigAlloc((size + 1) * sizeof(CIndex));
if (_hash == 0)
{
FreeMemory();
return E_OUTOFMEMORY;
}
// _hash = &m_RightBase[_blockSize];
#ifdef HASH_ARRAY_2
_hash2 = &_hash[kHashSize];
#ifdef HASH_ARRAY_3
_hash3 = &_hash2[kHash2Size];
#endif
#endif
return S_OK;
}
static const UINT32 kEmptyHashValue = 0;
static const UInt32 kEmptyHashValue = 0;
HRESULT CInTree::Init(ISequentialInStream *stream)
{
RINOK(CLZInWindow::Init(stream));
unsigned int i;
UInt32 i;
for(i = 0; i < kHashSize; i++)
_hash[i] = kEmptyHashValue;
@ -149,81 +133,93 @@ HRESULT CInTree::Init(ISequentialInStream *stream)
_cyclicBufferPos = 0;
ReduceOffsets(0 - 1);
ReduceOffsets(-1);
return S_OK;
}
#ifdef HASH_ARRAY_2
#ifdef HASH_ARRAY_3
inline UINT32 Hash(const BYTE *pointer, UINT32 &hash2Value, UINT32 &hash3Value)
inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value, UInt32 &hash3Value)
{
UINT32 temp = CCRC::Table[pointer[0]] ^ pointer[1];
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)) &
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)
inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value)
{
hash2Value = (CCRC::Table[pointer[0]] ^ pointer[1]) & (kHash2Size - 1);
return (*((const UINT32 *)pointer)) & 0xFFFFFF;
return ((UInt32(pointer[0]) << 16)) | ((UInt32(pointer[1]) << 8)) | pointer[2];
}
#endif // HASH_ARRAY_3
#else // no HASH_ARRAY_2
#ifdef HASH_ZIP
inline UINT32 Hash(const BYTE *pointer)
inline UInt32 Hash(const Byte *pointer)
{
return ((UINT32(pointer[0]) << 8) ^
return ((UInt32(pointer[0]) << 8) ^
CCRC::Table[pointer[1]] ^ pointer[2]) & (kHashSize - 1);
}
#else // no HASH_ZIP
inline UINT32 Hash(const BYTE *pointer)
inline UInt32 Hash(const Byte *pointer)
{
return pointer[0] ^ (UINT32(pointer[1]) << 8);
return pointer[0] ^ (UInt32(pointer[1]) << 8);
}
#endif // HASH_ZIP
#endif // HASH_ARRAY_2
UINT32 CInTree::GetLongestMatch(UINT32 *distances)
UInt32 CInTree::GetLongestMatch(UInt32 *distances)
{
UINT32 currentLimit;
UInt32 lenLimit;
if (_pos + _matchMaxLen <= _streamPos)
currentLimit = _matchMaxLen;
lenLimit = _matchMaxLen;
else
{
currentLimit = _streamPos - _pos;
if(currentLimit < kNumHashBytes)
lenLimit = _streamPos - _pos;
if(lenLimit < kNumHashBytes)
return 0;
}
UINT32 matchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1;
BYTE *cur = _buffer + _pos;
UInt32 matchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1;
Byte *cur = _buffer + _pos;
/*
if ((_cyclicBufferPos & kBundleMask) == 0)
{
Byte *bytes = _son[_cyclicBufferPos >> kNumBundleBits].Bytes;
UInt32 bundleLimit = kNumBundleBytes;
if (bundleLimit > lenLimit)
bundleLimit = lenLimit;
for (UInt32 i = 0; i < bundleLimit; i++)
bytes[i] = cur[i];
}
*/
UINT32 matchHashLenMax = 0;
UInt32 matchHashLenMax = 0;
#ifdef HASH_ARRAY_2
UINT32 hash2Value;
UInt32 hash2Value;
#ifdef HASH_ARRAY_3
UINT32 hash3Value;
UINT32 hashValue = Hash(cur, hash2Value, hash3Value);
UInt32 hash3Value;
UInt32 hashValue = Hash(cur, hash2Value, hash3Value);
#else
UINT32 hashValue = Hash(cur, hash2Value);
UInt32 hashValue = Hash(cur, hash2Value);
#endif
#else
UINT32 hashValue = Hash(cur);
UInt32 hashValue = Hash(cur);
#endif
UINT32 curMatch = _hash[hashValue];
UInt32 curMatch = _hash[hashValue];
#ifdef HASH_ARRAY_2
UINT32 curMatch2 = _hash2[hash2Value];
UInt32 curMatch2 = _hash2[hash2Value];
#ifdef HASH_ARRAY_3
UINT32 curMatch3 = _hash3[hash3Value];
UInt32 curMatch3 = _hash3[hash3Value];
#endif
_hash2[hash2Value] = _pos;
bool matchLen2Exist = false;
UINT32 len2Distance = 0;
UInt32 len2Distance = 0;
if(curMatch2 >= matchMinPos)
{
if (_buffer[curMatch2] == cur[0])
@ -236,8 +232,8 @@ UINT32 CInTree::GetLongestMatch(UINT32 *distances)
#ifdef HASH_ARRAY_3
_hash3[hash3Value] = _pos;
UINT32 matchLen3Exist = false;
UINT32 len3Distance = 0;
UInt32 matchLen3Exist = false;
UInt32 len3Distance = 0;
if(curMatch3 >= matchMinPos)
{
if (_buffer[curMatch3] == cur[0])
@ -262,10 +258,14 @@ UINT32 CInTree::GetLongestMatch(UINT32 *distances)
_hash[hashValue] = _pos;
// UInt32 bi = _cyclicBufferPos >> kNumBundleBits;
// UInt32 bo = _cyclicBufferPos & kBundleMask;
// CPair &pair = _son[bi].Pairs[bo];
CPair &pair = _son[_cyclicBufferPos];
if(curMatch < matchMinPos)
{
_son[_cyclicBufferPos].Left = kEmptyHashValue;
_son[_cyclicBufferPos].Right = kEmptyHashValue;
pair.Left = kEmptyHashValue;
pair.Right = kEmptyHashValue;
#ifdef HASH_ARRAY_2
distances[2] = len2Distance;
@ -276,11 +276,11 @@ UINT32 CInTree::GetLongestMatch(UINT32 *distances)
return matchHashLenMax;
}
CIndex *ptrLeft = &_son[_cyclicBufferPos].Right;
CIndex *ptrRight = &_son[_cyclicBufferPos].Left;
CIndex *ptrLeft = &pair.Right;
CIndex *ptrRight = &pair.Left;
UINT32 maxLen, minSameLeft, minSameRight, minSame;
maxLen = minSameLeft = minSameRight = minSame = kNumHashDirectBytes;
UInt32 maxLen, minLeft, minRight;
maxLen = minLeft = minRight = kNumHashDirectBytes;
#ifdef HASH_ARRAY_2
#ifndef HASH_ARRAY_3
@ -294,46 +294,66 @@ UINT32 CInTree::GetLongestMatch(UINT32 *distances)
distances[maxLen] = _pos - curMatch - 1;
for(UINT32 count = _cutValue; count > 0; count--)
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) ?
/*
UInt32 delta = _pos - curMatch;
UInt32 cyclicPos = (delta <= _cyclicBufferPos) ?
(_cyclicBufferPos - delta):
(_cyclicBufferPos - delta + _cyclicBufferSize);
if (currentLen != currentLimit)
CBundle &bundle = _son[cyclicPos >> kNumBundleBits];
UInt32 bo = cyclicPos & kBundleMask;
CPair &pair = bundle.Pairs[bo];
Byte *pby1 = bundle.Bytes + bo;
UInt32 bundleLimit = kNumBundleBytes - bo;
UInt32 currentLen = minSame;
if (bundleLimit > lenLimit)
bundleLimit = lenLimit;
for(; currentLen < bundleLimit; currentLen++)
if (pby1[currentLen] != cur[currentLen])
break;
if (currentLen >= bundleLimit)
{
pby1 = _buffer + curMatch;
for(; currentLen < lenLimit; currentLen++)
if (pby1[currentLen] != cur[currentLen])
break;
}
*/
Byte *pby1 = _buffer + curMatch;
// CIndex left = pair.Left; // it's prefetch
UInt32 currentLen = MyMin(minLeft, minRight);
for(; currentLen < lenLimit; currentLen++)
if (pby1[currentLen] != cur[currentLen])
break;
UInt32 delta = _pos - curMatch;
while (currentLen > maxLen)
distances[++maxLen] = delta - 1;
UInt32 cyclicPos = (delta <= _cyclicBufferPos) ?
(_cyclicBufferPos - delta):
(_cyclicBufferPos - delta + _cyclicBufferSize);
CPair &pair = _son[cyclicPos];
if (currentLen != lenLimit)
{
if (pby1[currentLen] < cur[currentLen])
{
*ptrRight = curMatch;
ptrRight = &_son[cyclicPos].Right;
curMatch = _son[cyclicPos].Right;
if(currentLen > minSameLeft)
{
minSameLeft = currentLen;
minSame = MyMin(minSameLeft, minSameRight);
}
ptrRight = &pair.Right;
curMatch = pair.Right;
if(currentLen > minLeft)
minLeft = currentLen;
}
else
{
*ptrLeft = curMatch;
ptrLeft = &_son[cyclicPos].Left;
// curMatch = left;
curMatch = _son[cyclicPos].Left;
if(currentLen > minSameRight)
{
minSameRight = currentLen;
minSame = MyMin(minSameLeft, minSameRight);
}
ptrLeft = &pair.Left;
curMatch = pair.Left;
if(currentLen > minRight)
minRight = currentLen;
}
}
else
@ -341,18 +361,15 @@ UINT32 CInTree::GetLongestMatch(UINT32 *distances)
if(currentLen < _matchMaxLen)
{
*ptrLeft = curMatch;
ptrLeft = &_son[cyclicPos].Left;
curMatch = _son[cyclicPos].Left;
if(currentLen > minSameRight)
{
minSameRight = currentLen;
minSame = MyMin(minSameLeft, minSameRight);
}
ptrLeft = &pair.Left;
curMatch = pair.Left;
if(currentLen > minRight)
minRight = currentLen;
}
else
{
*ptrLeft = _son[cyclicPos].Right;
*ptrRight = _son[cyclicPos].Left;
*ptrLeft = pair.Right;
*ptrRight = pair.Left;
#ifdef HASH_ARRAY_2
if (matchLen2Exist && len2Distance < distances[2])
@ -400,84 +417,79 @@ UINT32 CInTree::GetLongestMatch(UINT32 *distances)
void CInTree::DummyLongestMatch()
{
UINT32 currentLimit;
UInt32 lenLimit;
if (_pos + _matchMaxLen <= _streamPos)
currentLimit = _matchMaxLen;
lenLimit = _matchMaxLen;
else
{
currentLimit = _streamPos - _pos;
if(currentLimit < kNumHashBytes)
lenLimit = _streamPos - _pos;
if(lenLimit < kNumHashBytes)
return;
}
UINT32 matchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1;
BYTE *cur = _buffer + _pos;
UInt32 matchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1;
Byte *cur = _buffer + _pos;
#ifdef HASH_ARRAY_2
UINT32 hash2Value;
UInt32 hash2Value;
#ifdef HASH_ARRAY_3
UINT32 hash3Value;
UINT32 hashValue = Hash(cur, hash2Value, hash3Value);
UInt32 hash3Value;
UInt32 hashValue = Hash(cur, hash2Value, hash3Value);
_hash3[hash3Value] = _pos;
#else
UINT32 hashValue = Hash(cur, hash2Value);
UInt32 hashValue = Hash(cur, hash2Value);
#endif
_hash2[hash2Value] = _pos;
#else
UINT32 hashValue = Hash(cur);
UInt32 hashValue = Hash(cur);
#endif
UINT32 curMatch = _hash[hashValue];
UInt32 curMatch = _hash[hashValue];
_hash[hashValue] = _pos;
CPair &pair = _son[_cyclicBufferPos];
if(curMatch < matchMinPos)
{
_son[_cyclicBufferPos].Left = kEmptyHashValue;
_son[_cyclicBufferPos].Right = kEmptyHashValue;
pair.Left = kEmptyHashValue;
pair.Right = kEmptyHashValue;
return;
}
CIndex *ptrLeft = &_son[_cyclicBufferPos].Right;
CIndex *ptrRight = &_son[_cyclicBufferPos].Left;
CIndex *ptrLeft = &pair.Right;
CIndex *ptrRight = &pair.Left;
UINT32 maxLen, minSameLeft, minSameRight, minSame;
maxLen = minSameLeft = minSameRight = minSame = kNumHashDirectBytes;
for(UINT32 count = _cutValue; count > 0; count--)
UInt32 maxLen, minLeft, minRight;
maxLen = minLeft = minRight = 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++*/)
Byte *pby1 = _buffer + curMatch;
UInt32 currentLen = MyMin(minLeft, minRight);
for(; currentLen < lenLimit; currentLen++)
if (pby1[currentLen] != cur[currentLen])
break;
UINT32 delta = _pos - curMatch;
UINT32 cyclicPos = (delta <= _cyclicBufferPos) ?
UInt32 delta = _pos - curMatch;
UInt32 cyclicPos = (delta <= _cyclicBufferPos) ?
(_cyclicBufferPos - delta):
(_cyclicBufferPos - delta + _cyclicBufferSize);
if (currentLen != currentLimit)
CPair &pair = _son[cyclicPos];
if (currentLen != lenLimit)
{
if (pby1[currentLen] < cur[currentLen])
{
*ptrRight = curMatch;
ptrRight = &_son[cyclicPos].Right;
curMatch = _son[cyclicPos].Right;
if(currentLen > minSameLeft)
{
minSameLeft = currentLen;
minSame = MyMin(minSameLeft, minSameRight);
}
ptrRight = &pair.Right;
curMatch = pair.Right;
if(currentLen > minLeft)
minLeft = currentLen;
}
else
{
*ptrLeft = curMatch;
ptrLeft = &_son[cyclicPos].Left;
curMatch = _son[cyclicPos].Left;
// curMatch = left;
if(currentLen > minSameRight)
{
minSameRight = currentLen;
minSame = MyMin(minSameLeft, minSameRight);
}
ptrLeft = &pair.Left;
curMatch = pair.Left;
if(currentLen > minRight)
minRight = currentLen;
}
}
else
@ -485,18 +497,15 @@ void CInTree::DummyLongestMatch()
if(currentLen < _matchMaxLen)
{
*ptrLeft = curMatch;
ptrLeft = &_son[cyclicPos].Left;
curMatch = _son[cyclicPos].Left;
if(currentLen > minSameRight)
{
minSameRight = currentLen;
minSame = MyMin(minSameLeft, minSameRight);
}
ptrLeft = &pair.Left;
curMatch = pair.Left;
if(currentLen > minRight)
minRight = currentLen;
}
else
{
*ptrLeft = _son[cyclicPos].Right;
*ptrRight = _son[cyclicPos].Left;
*ptrLeft = pair.Right;
*ptrRight = pair.Left;
return;
}
}
@ -507,23 +516,23 @@ void CInTree::DummyLongestMatch()
*ptrRight = kEmptyHashValue;
}
void CInTree::NormalizeLinks(CIndex *array, UINT32 numItems, UINT32 subValue)
void CInTree::NormalizeLinks(CIndex *items, UInt32 numItems, UInt32 subValue)
{
for (UINT32 i = 0; i < numItems; i++)
for (UInt32 i = 0; i < numItems; i++)
{
UINT32 value = array[i];
UInt32 value = items[i];
if (value <= subValue)
value = kEmptyHashValue;
else
value -= subValue;
array[i] = value;
items[i] = value;
}
}
void CInTree::Normalize()
{
UINT32 startItem = _pos - _historySize;
UINT32 subValue = startItem - 1;
UInt32 startItem = _pos - _historySize;
UInt32 subValue = startItem - 1;
// NormalizeLinks((CIndex *)(_son + startItem), _historySize * 2, subValue);
NormalizeLinks((CIndex *)_son, _cyclicBufferSize * 2, subValue);

View file

@ -1,7 +1,5 @@
// MatchFinders/IMatchFinder.h
// #pragma once
#ifndef __IMATCHFINDER_H
#define __IMATCHFINDER_H
@ -14,10 +12,10 @@ 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;
STDMETHOD_(Byte, GetIndexByte)(Int32 index) PURE;
STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 distance, UInt32 limit) PURE;
STDMETHOD_(UInt32, GetNumAvailableBytes)() PURE;
STDMETHOD_(const Byte *, GetPointerToCurrentPos)() PURE;
};
// {23170F69-40C1-278A-0000-000200020000}
@ -26,9 +24,9 @@ DEFINE_GUID(IID_IMatchFinder,
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(Create)(UInt32 historySize, UInt32 keepAddBufferBefore,
UInt32 matchMaxLen, UInt32 keepAddBufferAfter) PURE;
STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances) PURE;
STDMETHOD_(void, DummyLongestMatch)() PURE;
};

View file

@ -4,27 +4,28 @@
#include "LZInWindow.h"
#include "../../../Common/MyCom.h"
CLZInWindow::~CLZInWindow()
{
Free();
}
#include "../../../Common/Alloc.h"
void CLZInWindow::Free()
{
delete []_bufferBase;
::BigFree(_bufferBase);
_bufferBase = 0;
}
void CLZInWindow::Create(UINT32 keepSizeBefore, UINT32 keepSizeAfter, UINT32 keepSizeReserv)
bool CLZInWindow::Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)
{
_keepSizeBefore = keepSizeBefore;
_keepSizeAfter = keepSizeAfter;
_keepSizeReserv = keepSizeReserv;
_blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
Free();
_bufferBase = new BYTE[_blockSize];
UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
if (_bufferBase == 0 || _blockSize != blockSize)
{
Free();
_blockSize = blockSize;
_bufferBase = (Byte *)::BigAlloc(_blockSize);
}
_pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter;
return (_bufferBase != 0);
}
@ -64,17 +65,17 @@ HRESULT CLZInWindow::ReadBlock()
return S_OK;
while(true)
{
UINT32 size = (_bufferBase + _blockSize) - (_buffer + _streamPos);
UInt32 size = UInt32(_bufferBase - _buffer) + _blockSize - _streamPos;
if(size == 0)
return S_OK;
UINT32 numReadBytes;
UInt32 numReadBytes;
RINOK(_stream->ReadPart(_buffer + _streamPos, size, &numReadBytes));
if(numReadBytes == 0)
{
_posLimit = _streamPos;
const BYTE *pointerToPostion = _buffer + _posLimit;
const Byte *pointerToPostion = _buffer + _posLimit;
if(pointerToPostion > _pointerToLastSafePosition)
_posLimit = _pointerToLastSafePosition - _buffer;
_posLimit = (UInt32)(_pointerToLastSafePosition - _buffer);
_streamEndWasReached = true;
return S_OK;
}
@ -90,8 +91,8 @@ HRESULT CLZInWindow::ReadBlock()
void CLZInWindow::MoveBlock()
{
BeforeMoveBlock();
UINT32 offset = (_buffer + _pos - _keepSizeBefore) - _bufferBase;
UINT32 numBytes = (_buffer + _streamPos) - (_bufferBase + offset);
UInt32 offset = UInt32(_buffer - _bufferBase) + _pos - _keepSizeBefore;
UInt32 numBytes = UInt32(_buffer - _bufferBase) + _streamPos - offset;
memmove(_bufferBase, _bufferBase + offset, numBytes);
_buffer -= offset;
AfterMoveBlock();

View file

@ -1,7 +1,5 @@
// LZInWindow.h
// #pragma once
#ifndef __LZ_IN_WINDOW_H
#define __LZ_IN_WINDOW_H
@ -9,19 +7,19 @@
class CLZInWindow
{
BYTE *_bufferBase; // pointer to buffer with data
Byte *_bufferBase; // pointer to buffer with data
ISequentialInStream *_stream;
UINT32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
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;
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
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() {};
@ -30,23 +28,24 @@ protected:
void Free();
public:
CLZInWindow(): _bufferBase(0) {}
virtual ~CLZInWindow();
void Create(UINT32 keepSizeBefore, UINT32 keepSizeAfter,
UINT32 keepSizeReserv = (1<<17));
virtual ~CLZInWindow() { Free(); }
bool Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter,
UInt32 keepSizeReserv = (1<<17));
HRESULT Init(ISequentialInStream *stream);
// void ReleaseStream();
BYTE *GetBuffer() const { return _buffer; }
Byte *GetBuffer() const { return _buffer; }
const BYTE *GetPointerToCurrentPos() const { return _buffer + _pos; }
const Byte *GetPointerToCurrentPos() const { return _buffer + _pos; }
HRESULT MovePos()
{
_pos++;
if (_pos > _posLimit)
{
const BYTE *pointerToPostion = _buffer + _pos;
const Byte *pointerToPostion = _buffer + _pos;
if(pointerToPostion > _pointerToLastSafePosition)
MoveBlock();
return ReadBlock();
@ -54,29 +53,25 @@ public:
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;};
Byte GetIndexByte(Int32 index)const
{ return _buffer[(size_t)_pos + index]; }
// index + limit have not to exceed _keepSizeAfter;
UINT32 GetMatchLen(UINT32 index, UINT32 back, UINT32 limit) const
UInt32 GetMatchLen(Int32 index, UInt32 distance, 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++);
distance++;
Byte *pby = _buffer + (size_t)_pos + index;
UInt32 i;
for(i = 0; i < limit && pby[i] == pby[(size_t)i - distance]; i++);
return i;
}
UINT32 GetNumAvailableBytes() const { return _streamPos - _pos; }
UInt32 GetNumAvailableBytes() const { return _streamPos - _pos; }
void ReduceOffsets(UINT32 subValue)
void ReduceOffsets(Int32 subValue)
{
_buffer += subValue;
_posLimit -= subValue;

View file

@ -2,36 +2,29 @@
#include "StdAfx.h"
#include "../../../Common/Alloc.h"
#include "LZOutWindow.h"
void CLZOutWindow::Create(UINT32 windowSize)
bool 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)
{
const UInt32 kMinBlockSize = 1;
if (windowSize < kMinBlockSize)
windowSize = kMinBlockSize;
if (_buffer != 0 && _windowSize == windowSize)
return true;
Free();
_windowSize = windowSize;
_buffer = (Byte *)::BigAlloc(windowSize);
return (_buffer != 0);
}
void CLZOutWindow::Free()
{
::BigFree(_buffer);
_buffer = 0;
}
*/
void CLZOutWindow::Init(ISequentialOutStream *stream, bool solid)
{
@ -44,6 +37,9 @@ void CLZOutWindow::Init(ISequentialOutStream *stream, bool solid)
_streamPos = 0;
_pos = 0;
}
#ifdef _NO_EXCEPTIONS
ErrorCode = S_OK;
#endif
}
/*
@ -61,16 +57,25 @@ void CLZOutWindow::ReleaseStream()
void CLZOutWindow::FlushWithCheck()
{
HRESULT result = Flush();
#ifdef _NO_EXCEPTIONS
ErrorCode = result;
#else
if (result != S_OK)
throw CLZOutWindowException(result);
#endif
}
HRESULT CLZOutWindow::Flush()
{
UINT32 size = _pos - _streamPos;
UInt32 size = _pos - _streamPos;
if(size == 0)
return S_OK;
UINT32 processedSize;
#ifdef _NO_EXCEPTIONS
if (ErrorCode != S_OK)
return ErrorCode;
#endif
UInt32 processedSize;
HRESULT result = _stream->Write(_buffer + _streamPos, size, &processedSize);
if (result != S_OK)
return result;

View file

@ -1,78 +1,71 @@
// 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
#ifndef _NO_EXCEPTIONS
class CLZOutWindowException
{
public:
HRESULT ErrorCode;
CLZOutWindowException(HRESULT errorCode): ErrorCode(errorCode) {}
};
#endif
class CLZOutWindow
{
BYTE *_buffer;
UINT32 _pos;
UINT32 _windowSize;
UINT32 _streamPos;
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; }
#ifdef _NO_EXCEPTIONS
HRESULT ErrorCode;
#endif
void Free();
CLZOutWindow(): _buffer(0), _stream(0) {}
~CLZOutWindow() { Free(); /* ReleaseStream(); */ }
bool Create(UInt32 windowSize);
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)
void CopyBlock(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));
}
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(distance));
}
}
void PutOneByte(BYTE b)
void PutByte(Byte b)
{
_buffer[_pos++] = b;
if (_pos >= _windowSize)
FlushWithCheck();
_buffer[_pos++] = b;
if (_pos >= _windowSize)
FlushWithCheck();
}
BYTE GetOneByte(UINT32 index) const
Byte GetByte(UInt32 distance) const
{
UINT32 pos = _pos + index;
if (pos >= _windowSize)
pos += _windowSize;
return _buffer[pos];
UInt32 pos = _pos - distance - 1;
if (pos >= _windowSize)
pos += _windowSize;
return _buffer[pos];
}
// BYTE *GetBuffer() const { return _buffer; }
};
#endif

View file

@ -1,12 +1,8 @@
// stdafx.h
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#ifdef _WIN32
# include <windows.h>
#else
# include "../../../../Platform.h"
#endif
#include "../../../../Platform.h"
#endif

View file

@ -1,55 +1,29 @@
// LZMA.h
// #pragma once
#include "LZMALen.h"
#ifndef __LZMA_H
#define __LZMA_H
namespace NCompress {
namespace NLZMA {
const UINT32 kNumRepDistances = 4;
const UInt32 kNumRepDistances = 4;
const BYTE kNumStates = 12;
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};
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(unsigned int i = 0 ; i < kNumRepDistances; i++)
_repDistances[i] = 0;
}
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]; }
};
const int kNumPosSlotBits = 6;
@ -57,8 +31,9 @@ const int kDicLogSizeMin = 0;
const int kDicLogSizeMax = 32;
const int kDistTableSizeMax = kDicLogSizeMax * 2;
const UINT32 kNumLenToPosStates = 4;
inline UINT32 GetLenToPosState(UINT32 len)
const UInt32 kNumLenToPosStates = 4;
inline UInt32 GetLenToPosState(UInt32 len)
{
len -= 2;
if (len < kNumLenToPosStates)
@ -66,31 +41,41 @@ inline UINT32 GetLenToPosState(UINT32 len)
return kNumLenToPosStates - 1;
}
const UINT32 kMatchMinLen = 2;
namespace NLength {
const UINT32 kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1;
const int kNumPosStatesBitsMax = 4;
const UInt32 kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
const int kNumPosStatesBitsEncodingMax = 4;
const UInt32 kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
const int kNumLowBits = 3;
const int kNumMidBits = 3;
const int kNumHighBits = 8;
const UInt32 kNumLowSymbols = 1 << kNumLowBits;
const UInt32 kNumMidSymbols = 1 << kNumMidBits;
const UInt32 kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits);
}
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 kAlignTableSize = 1 << kNumAlignBits;
const UInt32 kAlignMask = (kAlignTableSize - 1);
const UINT32 kStartPosModelIndex = 4;
const UINT32 kEndPosModelIndex = 14;
const UINT32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
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 UInt32 kNumFullDistances = 1 << (kEndPosModelIndex / 2);
const int kNumLitPosStatesBitsEncodingMax = 4;
const int kNumLitContextBitsMax = 8;
const int kNumMoveBits = 5;
}}
#endif

View file

@ -1,356 +0,0 @@
// 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;
}
}}

View file

@ -1,107 +0,0 @@
// 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

File diff suppressed because it is too large Load diff

View file

@ -1,26 +1,36 @@
// LZMA/Encoder.h
// #pragma once
#ifndef __LZMA_ENCODER_H
#define __LZMA_ENCODER_H
#include "../../ICoder.h"
#include "../../../Common/MyCom.h"
#include "../../../Common/Alloc.h"
#include "../../ICoder.h"
#include "../LZ/IMatchFinder.h"
#include "../RangeCoder/RangeCoderBitTree.h"
#include "LZMA.h"
#include "LZMALen.h"
#include "LZMALiteral.h"
namespace NCompress {
namespace NLZMA {
class CMatchFinderException
typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder;
class CBaseState
{
public:
HRESULT ErrorCode;
CMatchFinderException(HRESULT errorCode): ErrorCode(errorCode) {}
protected:
CState _state;
Byte _previousByte;
bool _peviousIsMatch;
UInt32 _repDistances[kNumRepDistances];
void Init()
{
_state.Init();
_previousByte = 0;
_peviousIsMatch = false;
for(UInt32 i = 0 ; i < kNumRepDistances; i++)
_repDistances[i] = 0;
}
};
struct COptimal
@ -30,21 +40,21 @@ struct COptimal
bool Prev1IsChar;
bool Prev2;
UINT32 PosPrev2;
UINT32 BackPrev2;
UInt32 PosPrev2;
UInt32 BackPrev2;
UINT32 Price;
UINT32 PosPrev; // posNext;
UINT32 BackPrev;
UINT32 Backs[kNumRepDistances];
void MakeAsChar() { BackPrev = UINT32(-1); Prev1IsChar = false; }
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)
extern Byte g_FastPos[1024];
inline UInt32 GetPosSlot(UInt32 pos)
{
if (pos < (1 << 10))
return g_FastPos[pos];
@ -53,7 +63,7 @@ inline UINT32 GetPosSlot(UINT32 pos)
return g_FastPos[pos >> 18] + 36;
}
inline UINT32 GetPosSlot2(UINT32 pos)
inline UInt32 GetPosSlot2(UInt32 pos)
{
if (pos < (1 << 16))
return g_FastPos[pos >> 6] + 12;
@ -62,79 +72,190 @@ inline UINT32 GetPosSlot2(UINT32 pos)
return g_FastPos[pos >> 24] + 48;
}
const UINT32 kIfinityPrice = 0xFFFFFFF;
const UInt32 kIfinityPrice = 0xFFFFFFF;
typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder;
const UInt32 kNumOpts = 1 << 12;
class CLiteralEncoder2
{
CMyBitEncoder _encoders[0x300];
public:
void Init()
{
for (int i = 0; i < 0x300; i++)
_encoders[i].Init();
}
void Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol);
void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, Byte matchByte, Byte symbol);
UInt32 GetPrice(bool matchMode, Byte matchByte, Byte symbol) const;
};
class CLiteralEncoder
{
CLiteralEncoder2 *_coders;
int _numPrevBits;
int _numPosBits;
UInt32 _posMask;
public:
CLiteralEncoder(): _coders(0) {}
~CLiteralEncoder() { Free(); }
void Free()
{
MyFree(_coders);
_coders = 0;
}
bool Create(int numPosBits, int numPrevBits)
{
if (_coders == 0 || (numPosBits + numPrevBits) !=
(_numPrevBits + _numPosBits) )
{
Free();
UInt32 numStates = 1 << (numPosBits + numPrevBits);
_coders = (CLiteralEncoder2 *)MyAlloc(numStates * sizeof(CLiteralEncoder2));
}
_numPosBits = numPosBits;
_posMask = (1 << numPosBits) - 1;
_numPrevBits = numPrevBits;
return (_coders != 0);
}
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)); }
CLiteralEncoder2 *GetSubCoder(UInt32 pos, Byte prevByte)
{ return &_coders[GetState(pos, prevByte)]; }
/*
void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 pos, Byte prevByte,
Byte symbol)
{ _coders[GetState(pos, prevByte)].Encode(rangeEncoder, symbol); }
void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, UInt32 pos, Byte prevByte,
Byte matchByte, Byte symbol)
{ _coders[GetState(pos, prevByte)].Encode(rangeEncoder,
matchByte, symbol); }
*/
UInt32 GetPrice(UInt32 pos, Byte prevByte, bool matchMode, Byte matchByte, Byte symbol) const
{ return _coders[GetState(pos, prevByte)].GetPrice(matchMode, matchByte, symbol); }
};
namespace NLength {
class CEncoder
{
CMyBitEncoder _choice;
NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesEncodingMax];
CMyBitEncoder _choice2;
NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesEncodingMax];
NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumHighBits> _highCoder;
public:
void Init(UInt32 numPosStates);
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(UInt32 numPosStates)
{
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);
}
};
}
const UINT32 kNumOpts = 1 << 12;
class CEncoder :
public ICompressCoder,
// public IInitMatchFinder,
public ICompressSetCoderProperties,
public ICompressWriteCoderProperties,
public CBaseCoder,
public CBaseState,
public CMyUnknownImp
{
COptimal _optimum[kNumOpts];
public:
CMyComPtr<IMatchFinder> _matchFinder; // test it
NRangeCoder::CEncoder _rangeEncoder;
public:
private:
CMyBitEncoder _mainChoiceEncoders[kNumStates][NLength::kNumPosStatesEncodingMax];
CMyBitEncoder _matchChoiceEncoders[kNumStates];
CMyBitEncoder _matchRepChoiceEncoders[kNumStates];
CMyBitEncoder _matchRep1ChoiceEncoders[kNumStates];
CMyBitEncoder _matchRep2ChoiceEncoders[kNumStates];
CMyBitEncoder _matchRepShortChoiceEncoders[kNumStates][NLength::kNumPosStatesEncodingMax];
CMyBitEncoder _isMatch[kNumStates][NLength::kNumPosStatesEncodingMax];
CMyBitEncoder _isRep[kNumStates];
CMyBitEncoder _isRepG0[kNumStates];
CMyBitEncoder _isRepG1[kNumStates];
CMyBitEncoder _isRepG2[kNumStates];
CMyBitEncoder _isRep0Long[kNumStates][NLength::kNumPosStatesEncodingMax];
NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> _posSlotEncoder[kNumLenToPosStates];
NRangeCoder::CReverseBitTreeEncoder2<kNumMoveBits> _posEncoders[kNumPosModels];
NRangeCoder::CReverseBitTreeEncoder2<kNumMoveBits> _posAlignEncoder;
CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex];
NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumAlignBits> _posAlignEncoder;
NLength::CPriceTableEncoder _lenEncoder;
NLength::CPriceTableEncoder _repMatchLenEncoder;
NLiteral::CEncoder _literalEncoder;
CLiteralEncoder _literalEncoder;
UINT32 _matchDistances[kMatchMaxLen + 1];
UInt32 _matchDistances[kMatchMaxLen + 1];
bool _fastMode;
bool _maxMode;
UInt32 _numFastBytes;
UInt32 _longestMatchLength;
UINT32 _numFastBytes;
UINT32 _numFastBytesPrev;
UInt32 _additionalOffset;
UINT32 _longestMatchLength;
UINT32 _additionalOffset;
UINT32 _optimumEndIndex;
UINT32 _optimumCurrentIndex;
UInt32 _optimumEndIndex;
UInt32 _optimumCurrentIndex;
bool _longestMatchWasFound;
UINT32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
UInt32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
UINT32 _distancesPrices[kNumLenToPosStates][kNumFullDistances];
UInt32 _distancesPrices[kNumLenToPosStates][kNumFullDistances];
UINT32 _alignPrices[kAlignTableSize];
UINT32 _alignPriceCount;
UInt32 _alignPrices[kAlignTableSize];
UInt32 _alignPriceCount;
UINT32 _dictionarySize;
UINT32 _dictionarySizePrev;
UInt32 _distTableSize;
UINT32 _distTableSize;
UInt32 _posStateBits;
UInt32 _posStateMask;
UInt32 _numLiteralPosStateBits;
UInt32 _numLiteralContextBits;
UINT32 _posStateBits;
UINT32 _posStateMask;
UINT32 _numLiteralPosStateBits;
UINT32 _numLiteralContextBits;
UInt32 _dictionarySize;
UINT64 lastPosSlotFillingPos;
UINT64 nowPos64;
UInt32 _dictionarySizePrev;
UInt32 _numFastBytesPrev;
UInt64 lastPosSlotFillingPos;
UInt64 nowPos64;
bool _finished;
ISequentialInStream *_inStream;
@ -144,58 +265,49 @@ private:
#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
bool _needReleaseMFStream;
HRESULT ReadMatchDistances(UInt32 &len);
HRESULT MovePos(UInt32 num);
UInt32 GetRepLen1Price(CState state, UInt32 posState) const
{
return _matchRepChoiceEncoders[state.Index].GetPrice(0) +
_matchRepShortChoiceEncoders[state.Index][posState].GetPrice(0);
return _isRepG0[state.Index].GetPrice(0) +
_isRep0Long[state.Index][posState].GetPrice(0);
}
UINT32 GetRepPrice(UINT32 repIndex, UINT32 len, CState state, UINT32 posState) const
UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, CState state, UInt32 posState) const
{
UINT32 price = _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState);
UInt32 price = _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState);
if(repIndex == 0)
{
price += _matchRepChoiceEncoders[state.Index].GetPrice(0);
price += _matchRepShortChoiceEncoders[state.Index][posState].GetPrice(1);
price += _isRepG0[state.Index].GetPrice(0);
price += _isRep0Long[state.Index][posState].GetPrice(1);
}
else
{
price += _matchRepChoiceEncoders[state.Index].GetPrice(1);
price += _isRepG0[state.Index].GetPrice(1);
if (repIndex == 1)
price += _matchRep1ChoiceEncoders[state.Index].GetPrice(0);
price += _isRepG1[state.Index].GetPrice(0);
else
{
price += _matchRep1ChoiceEncoders[state.Index].GetPrice(1);
price += _matchRep2ChoiceEncoders[state.Index].GetPrice(repIndex - 2);
price += _isRepG1[state.Index].GetPrice(1);
price += _isRepG2[state.Index].GetPrice(repIndex - 2);
}
}
return price;
}
/*
UINT32 GetPosLen2Price(UINT32 pos, UINT32 posState) const
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 GetPosLen3Price(UInt32 pos, UInt32 len, UInt32 posState) const
{
UINT32 price;
UINT32 lenToPosState = GetLenToPosState(len);
UInt32 price;
UInt32 lenToPosState = GetLenToPosState(len);
if (pos < kNumFullDistances)
price = _distancesPrices[lenToPosState][pos];
else
@ -204,12 +316,12 @@ private:
return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
}
*/
UINT32 GetPosLenPrice(UINT32 pos, UINT32 len, UINT32 posState) const
UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) const
{
if (len == 2 && pos >= 0x80)
return kIfinityPrice;
UINT32 price;
UINT32 lenToPosState = GetLenToPosState(len);
UInt32 price;
UInt32 lenToPosState = GetLenToPosState(len);
if (pos < kNumFullDistances)
price = _distancesPrices[lenToPosState][pos];
else
@ -218,9 +330,9 @@ private:
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);
UInt32 Backward(UInt32 &backRes, UInt32 cur);
HRESULT GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes);
HRESULT GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes);
void FillPosSlotPrices();
void FillDistancesPrices();
@ -228,7 +340,11 @@ private:
void ReleaseStreams()
{
_matchFinder->ReleaseStream();
if (_matchFinder && _needReleaseMFStream)
{
_matchFinder->ReleaseStream();
_needReleaseMFStream = false;
}
// _rangeEncoder.ReleaseStream();
}
@ -245,21 +361,19 @@ private:
};
friend class CCoderReleaser;
void WriteEndMarker(UINT32 posState);
void WriteEndMarker(UInt32 posState);
public:
CEncoder();
virtual ~CEncoder() {}
void SetWriteEndMarkerMode(bool writeEndMarker)
{ _writeEndMark= writeEndMarker; }
HRESULT Create();
/*MY_UNKNOWN_IMP2(
MY_UNKNOWN_IMP2(
ICompressSetCoderProperties,
ICompressWriteCoderProperties
)*/
MY_UNKNOWN_IMP
)
STDMETHOD(Init)(
ISequentialOutStream *outStream);
@ -267,18 +381,18 @@ public:
// ICompressCoder interface
HRESULT SetStreams(ISequentialInStream *inStream,
ISequentialOutStream *outStream,
const UINT64 *inSize, const UINT64 *outSize);
HRESULT CodeOneBlock(UINT64 *inSize, UINT64 *outSize, INT32 *finished);
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,
const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress);
// ICompressCoder interface
STDMETHOD(Code)(ISequentialInStream *inStream,
ISequentialOutStream *outStream,
const UINT64 *inSize, const UINT64 *outSize,
const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress);
// IInitMatchFinder interface
@ -286,10 +400,12 @@ public:
// ICompressSetCoderProperties2
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
const PROPVARIANT *properties, UINT32 numProperties);
const PROPVARIANT *properties, UInt32 numProperties);
// ICompressWriteCoderProperties
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
virtual ~CEncoder() {}
};
}}

View file

@ -1,74 +0,0 @@
// 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;
}
}}}

View file

@ -1,114 +0,0 @@
// 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

View file

@ -1,69 +0,0 @@
// 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;
};
}}}

View file

@ -1,166 +0,0 @@
// 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

View file

@ -1,12 +1,8 @@
// stdafx.h
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#ifdef _WIN32
# include <windows.h>
#else
# include "../../../../Platform.h"
#endif
#include "../../../../Platform.h"
#endif

View file

@ -1,7 +1,4 @@
// Compress/RangeCoder.h
// This code is based on Eugene Shelwien's Rangecoder code
// #pragma once
// Compress/RangeCoder/RangeCoder.h
#ifndef __COMPRESS_RANGECODER_H
#define __COMPRESS_RANGECODER_H
@ -12,23 +9,24 @@
namespace NCompress {
namespace NRangeCoder {
const UINT32 kNumTopBits = 24;
const UINT32 kTopValue = (1 << kNumTopBits);
const int kNumTopBits = 24;
const UInt32 kTopValue = (1 << kNumTopBits);
class CEncoder
{
COutBuffer Stream;
UINT64 Low;
UINT32 Range;
UINT32 _ffNum;
BYTE _cache;
UInt64 Low;
UInt32 Range;
UInt32 _ffNum;
Byte _cache;
public:
COutBuffer Stream;
bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
void Init(ISequentialOutStream *stream)
{
Stream.Init(stream);
Low = 0;
Range = UINT32(-1);
Range = 0xFFFFFFFF;
_ffNum = 0;
_cache = 0;
}
@ -40,15 +38,14 @@ public:
ShiftLow();
}
HRESULT FlushStream()
{ return Stream.Flush(); }
HRESULT FlushStream() { return Stream.Flush(); }
/*
void ReleaseStream()
{ Stream.ReleaseStream(); }
*/
void Encode(UINT32 start, UINT32 size, UINT32 total)
void Encode(UInt32 start, UInt32 size, UInt32 total)
{
Low += start * (Range /= total);
Range *= size;
@ -60,13 +57,13 @@ public:
}
/*
void EncodeDirectBitsDiv(UINT32 value, UINT32 numTotalBits)
void EncodeDirectBitsDiv(UInt32 value, UInt32 numTotalBits)
{
Low += value * (Range >>= numTotalBits);
Normalize();
}
void EncodeDirectBitsDiv2(UINT32 value, UINT32 numTotalBits)
void EncodeDirectBitsDiv2(UInt32 value, UInt32 numTotalBits)
{
if (numTotalBits <= kNumBottomBits)
EncodeDirectBitsDiv(value, numTotalBits);
@ -79,19 +76,19 @@ public:
*/
void ShiftLow()
{
if (Low < (UINT32)0xFF000000 || UINT32(Low >> 32) == 1)
if (Low < (UInt32)0xFF000000 || UInt32(Low >> 32) == 1)
{
Stream.WriteByte(_cache + BYTE(Low >> 32));
Stream.WriteByte(Byte(_cache + Byte(Low >> 32)));
for (;_ffNum != 0; _ffNum--)
Stream.WriteByte(0xFF + BYTE(Low >> 32));
_cache = BYTE(UINT32(Low) >> 24);
Stream.WriteByte(Byte(0xFF + Byte(Low >> 32)));
_cache = Byte(UInt32(Low) >> 24);
}
else
_ffNum++;
Low = UINT32(Low) << 8;
Low = UInt32(Low) << 8;
}
void EncodeDirectBits(UINT32 value, UINT32 numTotalBits)
void EncodeDirectBits(UInt32 value, int numTotalBits)
{
for (int i = numTotalBits - 1; i >= 0; i--)
{
@ -106,9 +103,9 @@ public:
}
}
void EncodeBit(UINT32 size0, UINT32 numTotalBits, UINT32 symbol)
void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
{
UINT32 newBound = (Range >> numTotalBits) * size0;
UInt32 newBound = (Range >> numTotalBits) * size0;
if (symbol == 0)
Range = newBound;
else
@ -123,16 +120,17 @@ public:
}
}
UINT64 GetProcessedSize() { return Stream.GetProcessedSize() + _ffNum; }
UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _ffNum; }
};
class CDecoder
{
public:
CInBuffer Stream;
UINT32 Range;
UINT32 Code;
// UINT32 m_Word;
UInt32 Range;
UInt32 Code;
bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
void Normalize()
{
while (Range < kTopValue)
@ -146,19 +144,19 @@ public:
{
Stream.Init(stream);
Code = 0;
Range = UINT32(-1);
Range = 0xFFFFFFFF;
for(int i = 0; i < 5; i++)
Code = (Code << 8) | Stream.ReadByte();
}
// void ReleaseStream() { Stream.ReleaseStream(); }
UINT32 GetThreshold(UINT32 total)
UInt32 GetThreshold(UInt32 total)
{
return (Code) / ( Range /= total);
}
void Decode(UINT32 start, UINT32 size, UINT32 total)
void Decode(UInt32 start, UInt32 size)
{
Code -= start * Range;
Range *= size;
@ -166,31 +164,31 @@ public:
}
/*
UINT32 DecodeDirectBitsDiv(UINT32 numTotalBits)
UInt32 DecodeDirectBitsDiv(UInt32 numTotalBits)
{
Range >>= numTotalBits;
UINT32 threshold = Code / Range;
UInt32 threshold = Code / Range;
Code -= threshold * Range;
Normalize();
return threshold;
}
UINT32 DecodeDirectBitsDiv2(UINT32 numTotalBits)
UInt32 DecodeDirectBitsDiv2(UInt32 numTotalBits)
{
if (numTotalBits <= kNumBottomBits)
return DecodeDirectBitsDiv(numTotalBits);
UINT32 result = DecodeDirectBitsDiv(numTotalBits - kNumBottomBits) << kNumBottomBits;
UInt32 result = DecodeDirectBitsDiv(numTotalBits - kNumBottomBits) << kNumBottomBits;
return (result | DecodeDirectBitsDiv(kNumBottomBits));
}
*/
UINT32 DecodeDirectBits(UINT32 numTotalBits)
UInt32 DecodeDirectBits(UInt32 numTotalBits)
{
UINT32 range = Range;
UINT32 code = Code;
UINT32 result = 0;
for (UINT32 i = numTotalBits; i > 0; i--)
UInt32 range = Range;
UInt32 code = Code;
UInt32 result = 0;
for (UInt32 i = numTotalBits; i > 0; i--)
{
range >>= 1;
/*
@ -201,7 +199,7 @@ public:
result |= 1;
}
*/
UINT32 t = (code - range) >> 31;
UInt32 t = (code - range) >> 31;
code -= range & (t - 1);
// range = rangeTmp + ((range & 1) & (1 - t));
result = (result << 1) | (1 - t);
@ -217,10 +215,10 @@ public:
return result;
}
UINT32 DecodeBit(UINT32 size0, UINT32 numTotalBits)
UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
{
UINT32 newBound = (Range >> numTotalBits) * size0;
UINT32 symbol;
UInt32 newBound = (Range >> numTotalBits) * size0;
UInt32 symbol;
if (Code < newBound)
{
symbol = 0;
@ -236,7 +234,7 @@ public:
return symbol;
}
UINT64 GetProcessedSize() {return Stream.GetProcessedSize(); }
UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
};
}}

View file

@ -7,12 +7,27 @@
namespace NCompress {
namespace NRangeCoder {
CPriceTables::CPriceTables()
UInt32 CPriceTables::ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
static CPriceTables g_PriceTables;
CPriceTables::CPriceTables() { Init(); }
void CPriceTables::Init()
{
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++)
ProbPrices[j] = (i << kNumBitPriceShiftBits) +
(((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
}
/*
// simplest: bad solution
for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
StatePrices[i] = kBitPrice;
for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
ProbPrices[i] = kBitPrice;
*/
/*
@ -21,20 +36,20 @@ CPriceTables::CPriceTables()
// 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);
for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
ProbPrices[i] = UInt32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice);
*/
/*
// experimental, slow, solution:
for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
{
const int kCyclesBits = 5;
const UINT32 kCycles = (1 << kCyclesBits);
const UInt32 kCycles = (1 << kCyclesBits);
UINT32 range = UINT32(-1);
UINT32 bitCount = 0;
for (UINT32 j = 0; j < kCycles; j++)
UInt32 range = UInt32(-1);
UInt32 bitCount = 0;
for (UInt32 j = 0; j < kCycles; j++)
{
range >>= (kNumBitModelTotalBits - kNumMoveReducingBits);
range *= i;
@ -55,23 +70,11 @@ CPriceTables::CPriceTables()
range -= (1 << 31);
}
}
StatePrices[i] = (bitCount
ProbPrices[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;
}}

View file

@ -1,9 +1,7 @@
// Compress/RangeCoder/RangeCoderBit.h
// #pragma once
#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
#define __COMPRESS_RANGECODER_BIT_TREE_H
#ifndef __COMPRESS_RANGECODER_BIT_H
#define __COMPRESS_RANGECODER_BIT_H
#include "RangeCoder.h"
@ -11,74 +9,88 @@ namespace NCompress {
namespace NRangeCoder {
const int kNumBitModelTotalBits = 11;
const UINT32 kBitModelTotal = (1 << kNumBitModelTotalBits);
const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
const int kNumMoveReducingBits = 2;
const int kNumBitPriceShiftBits = 6;
const UINT32 kBitPrice = 1 << kNumBitPriceShiftBits;
const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
class CPriceTables
{
public:
UINT32 StatePrices[kBitModelTotal >> kNumMoveReducingBits];
static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
static void Init();
CPriceTables();
};
extern CPriceTables g_PriceTables;
/////////////////////////////
// CBitModel
template <int aNumMoveBits>
template <int numMoveBits>
class CBitModel
{
public:
UINT32 Probability;
void UpdateModel(UINT32 symbol)
UInt32 Prob;
void UpdateModel(UInt32 symbol)
{
/*
Probability -= (Probability + ((symbol - 1) & ((1 << aNumMoveBits) - 1))) >> aNumMoveBits;
Probability += (1 - symbol) << (kNumBitModelTotalBits - aNumMoveBits);
Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
*/
if (symbol == 0)
Probability += (kBitModelTotal - Probability) >> aNumMoveBits;
Prob += (kBitModelTotal - Prob) >> numMoveBits;
else
Probability -= (Probability) >> aNumMoveBits;
Prob -= (Prob) >> numMoveBits;
}
public:
void Init() { Probability = kBitModelTotal / 2; }
void Init() { Prob = kBitModelTotal / 2; }
};
template <int aNumMoveBits>
class CBitEncoder: public CBitModel<aNumMoveBits>
template <int numMoveBits>
class CBitEncoder: public CBitModel<numMoveBits>
{
public:
void Encode(CEncoder *encoder, UINT32 symbol)
void Encode(CEncoder *encoder, UInt32 symbol)
{
encoder->EncodeBit(Probability, kNumBitModelTotalBits, symbol);
UpdateModel(symbol);
encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
this->UpdateModel(symbol);
/*
UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
if (symbol == 0)
{
encoder->Range = newBound;
this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
}
else
{
encoder->Low += newBound;
encoder->Range -= newBound;
this->Prob -= (this->Prob) >> numMoveBits;
}
while (encoder->Range < kTopValue)
{
encoder->Range <<= 8;
encoder->ShiftLow();
}
*/
}
UINT32 GetPrice(UINT32 symbol) const
UInt32 GetPrice(UInt32 symbol) const
{
return g_PriceTables.StatePrices[
(((Probability - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
return CPriceTables::ProbPrices[
(((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
}
};
template <int aNumMoveBits>
class CBitDecoder: public CBitModel<aNumMoveBits>
template <int numMoveBits>
class CBitDecoder: public CBitModel<numMoveBits>
{
public:
UINT32 Decode(CDecoder *decoder)
UInt32 Decode(CDecoder *decoder)
{
UINT32 newBound = (decoder->Range >> kNumBitModelTotalBits) * Probability;
UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
if (decoder->Code < newBound)
{
decoder->Range = newBound;
Probability += (kBitModelTotal - Probability) >> aNumMoveBits;
this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
if (decoder->Range < kTopValue)
{
decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
@ -90,7 +102,7 @@ public:
{
decoder->Range -= newBound;
decoder->Code -= newBound;
Probability -= (Probability) >> aNumMoveBits;
this->Prob -= (this->Prob) >> numMoveBits;
if (decoder->Range < kTopValue)
{
decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
@ -103,5 +115,4 @@ public:
}}
#endif

View file

@ -1,9 +1,7 @@
// Compress/RangeCoder/RangeCoderBitTree.h
// #pragma once
#ifndef __COMPRESS_RANGECODER_BIT_H
#define __COMPRESS_RANGECODER_BIT_H
#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
#define __COMPRESS_RANGECODER_BIT_TREE_H
#include "RangeCoderBit.h"
#include "RangeCoderOpt.h"
@ -11,292 +9,154 @@
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>
template <int numMoveBits, UInt32 NumBitLevels>
class CBitTreeEncoder
{
CBitEncoder<numMoveBits> Models[1 << NumBitLevels];
public:
void Init()
{
for(UINT32 i = 1; i < (1 << NumBitLevels); i++)
for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
Models[i].Init();
}
void Encode(CEncoder *rangeEncoder, UINT32 symbol)
void Encode(CEncoder *rangeEncoder, UInt32 symbol)
{
UINT32 modelIndex = 1;
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
UInt32 modelIndex = 1;
for (UInt32 bitIndex = NumBitLevels; bitIndex > 0 ;)
{
bitIndex--;
UINT32 bit = (symbol >> bitIndex ) & 1;
UInt32 bit = (symbol >> bitIndex) & 1;
Models[modelIndex].Encode(rangeEncoder, bit);
modelIndex = (modelIndex << 1) | bit;
}
};
UINT32 GetPrice(UINT32 symbol) const
void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol)
{
UINT32 price = 0;
UINT32 modelIndex = 1;
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
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 bitIndex = NumBitLevels; bitIndex > 0 ;)
{
bitIndex--;
UINT32 bit = (symbol >> bitIndex ) & 1;
UInt32 bit = (symbol >> bitIndex) & 1;
price += Models[modelIndex].GetPrice(bit);
modelIndex = (modelIndex << 1) + bit;
}
return price;
}
UInt32 ReverseGetPrice(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;
}
};
//////////////////////////
// CBitTreeDecoder
template <int numMoveBits, UINT32 NumBitLevels>
template <int numMoveBits, UInt32 NumBitLevels>
class CBitTreeDecoder
{
CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
public:
void Init()
{
for(UINT32 i = 1; i < (1 << NumBitLevels); i++)
for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
Models[i].Init();
}
UINT32 Decode(CDecoder *rangeDecoder)
UInt32 Decode(CDecoder *rangeDecoder)
{
UINT32 modelIndex = 1;
UInt32 modelIndex = 1;
RC_INIT_VAR
for(UINT32 bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
for(UInt32 bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
{
// modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
RC_GETBIT(numMoveBits, Models[modelIndex].Probability, modelIndex)
RC_GETBIT(numMoveBits, Models[modelIndex].Prob, 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)
UInt32 ReverseDecode(CDecoder *rangeDecoder)
{
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;
UInt32 modelIndex = 1;
UInt32 symbol = 0;
RC_INIT_VAR
for(UINT32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
for(UInt32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
{
// UINT32 bit = Models[modelIndex].Decode(rangeDecoder);
// 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_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
}
RC_FLUSH_VAR
return symbol;
}
};
/*
//////////////////////////
// CBitTreeEncoder2
template <int numMoveBits>
void ReverseBitTreeEncode(CBitEncoder<numMoveBits> *Models,
CEncoder *rangeEncoder, UInt32 NumBitLevels, 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;
}
}
template <int numMoveBits>
class CBitTreeEncoder2
UInt32 ReverseBitTreeGetPrice(CBitEncoder<numMoveBits> *Models,
UInt32 NumBitLevels, UInt32 symbol)
{
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 price = 0;
UInt32 modelIndex = 1;
for (UInt32 i = NumBitLevels; i > 0; i--)
{
UINT32 numModels = 1 << NumBitLevels;
for(UINT32 i = 1; i < numModels; i++)
Models[i].Init();
UInt32 bit = symbol & 1;
symbol >>= 1;
price += Models[modelIndex].GetPrice(bit);
modelIndex = (modelIndex << 1) | bit;
}
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
return price;
}
template <int numMoveBits>
class CBitTreeDecoder2
UInt32 ReverseBitTreeDecode(CBitDecoder<numMoveBits> *Models,
CDecoder *rangeDecoder, UInt32 NumBitLevels)
{
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 modelIndex = 1;
UInt32 symbol = 0;
RC_INIT_VAR
for(UInt32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
{
UINT32 numModels = 1 << NumBitLevels;
for(UINT32 i = 1; i < numModels; i++)
Models[i].Init();
// UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
// modelIndex <<= 1;
// modelIndex += bit;
// symbol |= (bit << bitIndex);
RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
}
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);
}
};
*/
RC_FLUSH_VAR
return symbol;
}
}}

View file

@ -1,43 +1,31 @@
// 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_INIT_VAR \
UInt32 range = rangeDecoder->Range; \
UInt32 code = rangeDecoder->Code;
#define RC_FLUSH_VAR \
rangeDecoder->Range = range; \
#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_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_GETBIT2(numMoveBits, prob, mi, A0, A1) \
{ UInt32 bound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \
if (code < bound) \
{ A0; range = bound; \
prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \
mi <<= 1; } \
else \
{ A1; range -= bound; code -= bound; prob -= (prob) >> numMoveBits; \
mi = (mi + mi) + 1; }} \
RC_NORMALIZE
#define RC_GETBIT(numMoveBits, prob, modelIndex) RC_GETBIT2(numMoveBits, prob, modelIndex, ; , ;)
#define RC_GETBIT(numMoveBits, prob, mi) RC_GETBIT2(numMoveBits, prob, mi, ; , ;)
#endif

View file

@ -1,12 +1,8 @@
// stdafx.h
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#ifdef _WIN32
# include <windows.h>
#else
# include "../../../../Platform.h"
#endif
#include "../../../../Platform.h"
#endif

View file

@ -1,7 +1,5 @@
// ICoder.h
// #pragma once
#ifndef __ICODER_H
#define __ICODER_H
@ -13,7 +11,7 @@ DEFINE_GUID(IID_ICompressProgressInfo,
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200040000")
ICompressProgressInfo: public IUnknown
{
STDMETHOD(SetRatioInfo)(const UINT64 *inSize, const UINT64 *outSize) = 0;
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) = 0;
};
// {23170F69-40C1-278A-0000-000200050000}
@ -24,8 +22,8 @@ ICompressCoder: public IUnknown
{
STDMETHOD(Code)(ISequentialInStream *inStream,
ISequentialOutStream *outStream,
const UINT64 *inSize,
const UINT64 *outSize,
const UInt64 *inSize,
const UInt64 *outSize,
ICompressProgressInfo *progress) = 0;
};
@ -36,11 +34,11 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000200180000")
ICompressCoder2: public IUnknown
{
STDMETHOD(Code)(ISequentialInStream **inStreams,
const UINT64 **inSizes,
UINT32 numInStreams,
const UInt64 **inSizes,
UInt32 numInStreams,
ISequentialOutStream **outStreams,
const UINT64 **outSizes,
UINT32 numOutStreams,
const UInt64 **outSizes,
UInt32 numOutStreams,
ICompressProgressInfo *progress) PURE;
};
@ -58,7 +56,8 @@ namespace NCoderPropID
kMatchFinder,
kNumPasses = 0x460,
kAlgorithm = 0x470,
kMultiThread = 0x480
kMultiThread = 0x480,
kEndMarker = 0x490
};
}
@ -69,7 +68,7 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000200200000")
ICompressSetCoderProperties: public IUnknown
{
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
const PROPVARIANT *properties, UINT32 numProperties) PURE;
const PROPVARIANT *properties, UInt32 numProperties) PURE;
};
// {23170F69-40C1-278A-0000-000200210000}
@ -78,7 +77,7 @@ DEFINE_GUID(IID_ICompressSetDecoderProperties,
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200210000")
ICompressSetDecoderProperties: public IUnknown
{
STDMETHOD(SetDecoderProperties)(ISequentialInStream *anInStream) PURE;
STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;
};
// {23170F69-40C1-278A-0000-000200230000}
@ -96,7 +95,7 @@ DEFINE_GUID(IID_ICompressGetInStreamProcessedSize,
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200240000")
ICompressGetInStreamProcessedSize: public IUnknown
{
STDMETHOD(GetInStreamProcessedSize)(UINT64 *value) PURE;
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;
};
// {23170F69-40C1-278A-0000-000200250000}
@ -105,7 +104,25 @@ DEFINE_GUID(IID_ICompressGetSubStreamSize,
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200250000")
ICompressGetSubStreamSize: public IUnknown
{
STDMETHOD(GetSubStreamSize)(UINT64 subStream, UINT64 *value) PURE;
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE;
};
// {23170F69-40C1-278A-0000-000200260000}
DEFINE_GUID(IID_ICompressSetInStream,
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x26, 0x00, 0x00);
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200260000")
ICompressSetInStream: public IUnknown
{
STDMETHOD(SetInStream)(ISequentialInStream *inStream, const UInt64 *inSize) PURE;
};
// {23170F69-40C1-278A-0000-000200270000}
DEFINE_GUID(IID_ICompressSetOutStream,
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, 0x00, 0x00);
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200270000")
ICompressSetOutStream: public IUnknown
{
STDMETHOD(SetOutStream)(ISequentialOutStream *outStream, const UInt64 *outSize) PURE;
};
//////////////////////
@ -120,7 +137,7 @@ namespace NMethodPropID
kEncoder,
kInStreams,
kOutStreams,
kDescription,
kDescription
};
}

View file

@ -1,104 +0,0 @@
// IMyUnknown.h
// #pragma once
#ifndef __MYUNKNOWN_H
#define __MYUNKNOWN_H
#ifdef _WIN32
// #include <guiddef.h>
#include <basetyps.h>
#else
#include "../../Platform.h"
#include <string>
#define HRESULT LONG
#if ((_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED))
# define STDMETHODCALLTYPE __stdcall
#else
# if defined(__GNUC__) && defined(__i386__)
# define STDMETHODCALLTYPE __attribute__((__stdcall__))
# else
# define STDMETHODCALLTYPE
# endif
#endif
#define PROPID ULONG
#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f
#define STDMETHOD(f) STDMETHOD_(HRESULT, f)
#define STDMETHODIMP_(type) type STDMETHODCALLTYPE
#define STDMETHODIMP STDMETHODIMP_(HRESULT)
#define VT_UI4 1
#define VT_BSTR 2
typedef struct _PROPVARIANT
{
WORD vt;
ULONG ulVal;
wchar_t *bstrVal;
} PROPVARIANT;
#define S_OK 0
#define E_NOINTERFACE 0x80000001
#define E_ABORT 0x80000002
#define E_INVALIDARG 0x80070057
#define E_FAIL 0x80004005
#define E_OUTOFMEMORY 0x8007000E
#define PURE = 0;
typedef struct {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[8];
} GUID;
#ifdef __cplusplus
#define MY_EXTERN_C extern "C"
#else
#define MY_EXTERN_C extern
#endif
#ifdef INITGUID
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
#else
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
MY_EXTERN_C const GUID name
#endif
#ifdef __cplusplus
typedef const GUID & REFGUID;
#else
#define REFGUID const GUID * __MIDL_CONST
#endif
#define MIDL_INTERFACE(x) struct
inline int operator==(REFGUID g1, REFGUID g2)
{
for (unsigned int i = 0; i < sizeof(g1); i++)
if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i])
return false;
return true;
}
inline int operator!=(REFGUID g1, REFGUID g2)
{ return !(g1 == g2); }
struct IUnknown
{
STDMETHOD(QueryInterface) (REFGUID iid, void **outObject) PURE;
STDMETHOD_(ULONG, AddRef)() PURE;
STDMETHOD_(ULONG, Release)() PURE;
};
#endif
#endif

View file

@ -1,11 +1,10 @@
// IStream.h
// #pragma once
#ifndef __ISTREAMS_H
#define __ISTREAMS_H
#include "IMyUnknown.h"
#include "../Common/MyUnknown.h"
#include "../Common/Types.h"
// {23170F69-40C1-278A-0000-000000010000}
DEFINE_GUID(IID_ISequentialInStream,
@ -14,9 +13,15 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000010000")
ISequentialInStream : public IUnknown
{
public:
// out: if (processedSize == 0) then there are no more bytes
STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize) = 0;
STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize) = 0;
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) = 0;
STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize) = 0;
// For both function Out: if (processedSize == 0) then there are
// no more bytes in stream.
// Read function always tries to read "size" bytes from stream. It
// can read less only if it reaches end of stream.
// ReadPart function can read X bytes: (0<=X<="size") and X can
// be less than number of remaining bytes in stream.
};
// {23170F69-40C1-278A-0000-000000020000}
@ -26,8 +31,8 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000020000")
ISequentialOutStream : public IUnknown
{
public:
STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize) = 0;
STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize) = 0;
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) = 0;
STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize) = 0;
};
// {23170F69-40C1-278A-0000-000000030000}
@ -37,7 +42,7 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000030000")
IInStream : public ISequentialInStream
{
public:
STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition) = 0;
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) = 0;
};
// {23170F69-40C1-278A-0000-000000040000}
@ -47,8 +52,8 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000040000")
IOutStream : public ISequentialOutStream
{
public:
STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition) = 0;
STDMETHOD(SetSize)(INT64 aNewSize) = 0;
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) = 0;
STDMETHOD(SetSize)(Int64 newSize) = 0;
};
// {23170F69-40C1-278A-0000-000000060000}
@ -58,7 +63,17 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000060000")
IStreamGetSize : public IUnknown
{
public:
STDMETHOD(GetSize)(UINT64 *size) = 0;
STDMETHOD(GetSize)(UInt64 *size) = 0;
};
// {23170F69-40C1-278A-0000-000000070000}
DEFINE_GUID(IID_IOutStreamFlush,
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00);
MIDL_INTERFACE("23170F69-40C1-278A-0000-000000070000")
IOutStreamFlush : public IUnknown
{
public:
STDMETHOD(Flush)() = 0;
};
#endif

View file

@ -4,18 +4,15 @@
#include "CRC.h"
static const UINT32 kCRCPoly = 0xEDB88320;
static const UInt32 kCRCPoly = 0xEDB88320;
UINT32 CCRC::Table[256];
UInt32 CCRC::Table[256];
class CCRCTableInit
void CCRC::InitTable()
{
public:
CCRCTableInit()
{
for (UINT32 i = 0; i < 256; i++)
for (UInt32 i = 0; i < 256; i++)
{
UINT32 r = i;
UInt32 r = i;
for (int j = 0; j < 8; j++)
if (r & 1)
r = (r >> 1) ^ kCRCPoly;
@ -24,87 +21,35 @@ CCRCTableInit()
CCRC::Table[i] = r;
}
}
class CCRCTableInit
{
public:
CCRCTableInit() { CCRC::InitTable(); }
} g_CRCTableInit;
/*
const UINT32 CCRC::Table[] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
};
*/
#define UPDATE valueLoc = Table[(BYTE)valueLoc] ^ (valueLoc >> 8)
#define UPDATE4 UPDATE; UPDATE; UPDATE; UPDATE;
void CCRC::Update(const void *data, UINT32 size)
void CCRC::Update(Byte b)
{
UINT32 valueLoc = _value;
const BYTE *byteBuffer = (const BYTE *)data;
for(; (UINT_PTR(byteBuffer) & 3) != 0 && size > 0; size--, byteBuffer++)
valueLoc = Table[(((BYTE)(valueLoc)) ^ (*byteBuffer))] ^
(valueLoc >> 8);
const UINT32 kBlockSize = 4;
while (size >= kBlockSize)
{
size -= kBlockSize;
valueLoc ^= *(const UINT32 *)byteBuffer;
UPDATE4
byteBuffer += kBlockSize;
}
for(UINT32 i = 0; i < size; i++)
valueLoc = Table[(((BYTE)(valueLoc)) ^ (byteBuffer)[i])] ^
(valueLoc >> 8);
_value = valueLoc;
_value = Table[((Byte)(_value)) ^ b] ^ (_value >> 8);
}
void CCRC::Update(UInt32 v)
{
for (int i = 0; i < 4; i++)
Update((Byte)(v >> (8 * i)));
}
void CCRC::Update(const UInt64 &v)
{
for (int i = 0; i < 8; i++)
Update((Byte)(v >> (8 * i)));
}
void CCRC::Update(const void *data, UInt32 size)
{
UInt32 v = _value;
const Byte *p = (const Byte *)data;
for (; size > 0 ; size--, p++)
v = Table[((Byte)(v)) ^ *p] ^ (v >> 8);
_value = v;
}

View file

@ -1,7 +1,5 @@
// Common/CRC.h
// #pragma once
#ifndef __COMMON_CRC_H
#define __COMMON_CRC_H
@ -9,20 +7,25 @@
class CCRC
{
UINT32 _value;
UInt32 _value;
public:
static UINT32 Table[256];
static UInt32 Table[256];
static void InitTable();
CCRC(): _value(0xFFFFFFFF){};
void Init() { _value = 0xFFFFFFFF; }
void Update(const void *data, UINT32 size);
UINT32 GetDigest() const { return _value ^ 0xFFFFFFFF; }
static UINT32 CalculateDigest(const void *data, UINT32 size)
void Update(Byte v);
void Update(UInt32 v);
void Update(const UInt64 &v);
void Update(const void *data, UInt32 size);
UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; }
static UInt32 CalculateDigest(const void *data, UInt32 size)
{
CCRC crc;
crc.Update(data, size);
return crc.GetDigest();
}
static bool VerifyDigest(UINT32 digest, const void *data, UINT32 size)
static bool VerifyDigest(UInt32 digest, const void *data, UInt32 size)
{
return (CalculateDigest(data, size) == digest);
}

View file

@ -1,14 +0,0 @@
// ComTry.h
// #pragma once
#ifndef __Com_Try_H
#define __Com_Try_H
#include "Exception.h"
#define COM_TRY_BEGIN try {
#define COM_TRY_END } catch(const CSystemException &e) { return e.ErrorCode; }\
catch(...) { return E_FAIL; }
#endif

View file

@ -1,7 +1,5 @@
// Common/Defs.h
// #pragma once
#ifndef __COMMON_DEFS_H
#define __COMMON_DEFS_H
@ -19,10 +17,4 @@ inline int BoolToInt(bool value)
inline bool IntToBool(int value)
{ return (value != 0); }
class CMemoryException
{
public:
CMemoryException() {}
};
#endif

View file

@ -1,10 +1,10 @@
// MyCom.h
// #pragma once
#ifndef __MYCOM_H
#define __MYCOM_H
#include "MyWindows.h"
#define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; }
template <class T>
@ -50,10 +50,12 @@ public:
_p = NULL;
return pt;
}
/*HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
#ifdef WIN32
HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
{
return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
}*/
}
#endif
/*
HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
{
@ -65,16 +67,16 @@ public:
return hr;
}
*/
/*template <class Q>
template <class Q>
HRESULT QueryInterface(REFGUID iid, Q** pp) const
{
return _p->QueryInterface(iid, (void**)pp);
}*/
}
};
//////////////////////////////////////////////////////////
/*class CMyComBSTR
class CMyComBSTR
{
public:
BSTR m_str;
@ -83,7 +85,7 @@ public:
// CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
// CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); }
CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
/ *
/*
CMyComBSTR(REFGUID src)
{
LPOLESTR szGuid;
@ -91,7 +93,7 @@ public:
m_str = ::SysAllocString(szGuid);
CoTaskMemFree(szGuid);
}
* /
*/
~CMyComBSTR() { ::SysFreeString(m_str); }
CMyComBSTR& operator=(const CMyComBSTR& src)
{
@ -132,7 +134,7 @@ public:
m_str = NULL;
}
bool operator!() const { return (m_str == NULL); }
};*/
};
//////////////////////////////////////////////////////////
@ -184,4 +186,12 @@ STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
MY_QUERYINTERFACE_ENTRY(i4) \
)
#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \
MY_QUERYINTERFACE_ENTRY(i1) \
MY_QUERYINTERFACE_ENTRY(i2) \
MY_QUERYINTERFACE_ENTRY(i3) \
MY_QUERYINTERFACE_ENTRY(i4) \
MY_QUERYINTERFACE_ENTRY(i5) \
)
#endif

View file

@ -1,12 +1,8 @@
// stdafx.h
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#ifdef _WIN32
# include <windows.h>
#else
# include "../../Platform.h"
#endif
#include "../../Platform.h"
#endif

View file

@ -1,23 +1,19 @@
// Common/Types.h
// #pragma once
#ifndef __COMMON_TYPES_H
#define __COMMON_TYPES_H
#ifdef _WIN32
# include <basetsd.h>
typedef unsigned char Byte;
typedef short Int16;
typedef unsigned short UInt16;
typedef int Int32;
typedef unsigned int UInt32;
#ifdef _MSC_VER
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#else
# include "../../Platform.h"
#endif
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef short INT16;
#ifndef _WINDOWS_
// typedef unsigned long UINT32;
typedef UINT8 BYTE;
typedef long long int Int64;
typedef unsigned long long int UInt64;
#endif
#endif

View file

@ -5,8 +5,8 @@
#
# -- Objects and source files --
SRCS = zlib/deflate.c zlib/trees.c bzip2/blocksort.c bzip2/bzlib.c bzip2/compress.c bzip2/huffman.c 7zip/7zGuids.cpp 7zip/Common/CRC.cpp 7zip/7zip/Compress/LZ/LZInWindow.cpp 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp 7zip/7zip/Compress/LZMA/LZMALen.cpp 7zip/7zip/Compress/LZMA/LZMALiteral.cpp 7zip/7zip/Common/OutBuffer.cpp 7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp build.cpp crc32.c DialogTemplate.cpp exedata.cpp lang.cpp makenssi.cpp Plugins.cpp ResourceEditor.cpp ResourceVersionInfo.cpp script.cpp tokens.cpp util.cpp
OBJS = 7zGuids.o blocksort.o build.o bzlib.o compress.o CRC.o crc32.o deflate.o DialogTemplate.o exedata.o huffman.o lang.o LZInWindow.o LZMAEncoder.o LZMALen.o LZMALiteral.o makenssi.o OutBuffer.o Plugins.o RangeCoderBit.o ResourceEditor.o ResourceVersionInfo.o script.o tokens.o trees.o util.o
SRCS = zlib/deflate.c zlib/trees.c bzip2/blocksort.c bzip2/bzlib.c bzip2/compress.c bzip2/huffman.c 7zip/7zGuids.cpp 7zip/Common/CRC.cpp 7zip/7zip/Compress/LZ/LZInWindow.cpp 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp 7zip/7zip/Common/OutBuffer.cpp 7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp 7zip/Common/Alloc.cpp build.cpp crc32.c DialogTemplate.cpp exedata.cpp lang.cpp makenssi.cpp Plugins.cpp ResourceEditor.cpp ResourceVersionInfo.cpp script.cpp tokens.cpp util.cpp
OBJS = 7zGuids.o blocksort.o build.o bzlib.o compress.o CRC.o crc32.o deflate.o DialogTemplate.o exedata.o huffman.o lang.o LZInWindow.o LZMAEncoder.o Alloc.o makenssi.o OutBuffer.o Plugins.o RangeCoderBit.o ResourceEditor.o ResourceVersionInfo.o script.o tokens.o trees.o util.o
ifeq "$(strip $(findstring i386pe,$(shell ld -V)))" ""
LIBS = -lstdc++ -lpthread
EXESUFF =

View file

@ -20,18 +20,21 @@
typedef unsigned char BYTE, *PBYTE, *LPBYTE;
typedef unsigned short WORD, *LPWORD;
typedef unsigned long DWORD, *LPDWORD;
typedef short SHORT;
typedef unsigned short USHORT;
typedef unsigned int UINT;
typedef unsigned int UINT32;
typedef int INT;
typedef int INT32;
typedef long LONG;
typedef unsigned long ULONG;
typedef long long INT64;
typedef unsigned long long UINT64;
typedef long long INT64, LARGE_INTEGER;
typedef unsigned long long UINT64, ULARGE_INTEGER;
typedef int BOOL;
typedef void VOID;
typedef void *LPVOID;
typedef char CHAR, *PCHAR, *LPCH, *PCH, *NPSTR, *LPSTR, *PSTR;
typedef unsigned char UCHAR;
typedef const char *LPCCH, *PCSTR, *LPCSTR;
typedef unsigned short WCHAR, *PWCHAR, *LPWCH, *PWCH, *NWPSTR, *LPWSTR, *PWSTR;
typedef const unsigned short *LPCWCH, *PCWCH, *LPCWSTR, *PCWSTR;

View file

@ -102,7 +102,8 @@ WCHAR* StrToWstrAlloc(const char* istr, int codepage)
{
int len = strlen(istr);
char *in = (char *) istr;
char *out = (char *) wstr = new WCHAR[len + 1];
wstr = new WCHAR[len + 1];
char *out = (char *) wstr;
size_t insize = len + 1;
size_t outsize = (len + 1) * sizeof(WCHAR);
if (__iconv_adaptor(iconv, cd, &in, &insize, &out, &outsize) == (size_t) -1)

View file

@ -135,6 +135,18 @@ private:
#endif
int ConvertError(HRESULT result)
{
if (result != S_OK)
{
if (result == E_OUTOFMEMORY)
return LZMA_MEM_ERROR;
else
return LZMA_IO_ERROR;
}
return C_OK;
}
public:
MY_UNKNOWN_IMP
@ -207,7 +219,7 @@ public:
props[2].ulVal = 64;
if (_encoder->SetCoderProperties(propdIDs, props, kNumProps) != 0)
return LZMA_INIT_ERROR;
return _encoder->SetStreams(this, this, 0, 0);
return _encoder->SetStreams(this, this, 0, 0) == S_OK ? C_OK : LZMA_INIT_ERROR;
}
int Init(int level)
@ -251,18 +263,16 @@ public:
{
try
{
if (_encoder->WriteCoderProperties(this) == S_OK)
HRESULT hResult = _encoder->WriteCoderProperties(this);
if (res == S_OK)
{
while (true)
{
UINT64 inSize, outSize;
INT32 finished;
if (_encoder->CodeOneBlock(&inSize, &outSize, &finished))
{
if (res != C_OK)
res = LZMA_IO_ERROR;
res = ConvertError(_encoder->CodeOneBlock(&inSize, &outSize, &finished));
if (res != C_OK)
break;
}
if (finished)
{
res = C_OK;
@ -272,13 +282,9 @@ public:
}
else
{
res = LZMA_IO_ERROR;
res = ConvertError(hResult);
}
}
catch (CMemoryException)
{
res = LZMA_MEM_ERROR;
}
catch (...)
{
res = LZMA_IO_ERROR;

View file

@ -156,7 +156,13 @@ SOURCE=.\7zip\7zGuids.cpp
# End Source File
# Begin Source File
SOURCE=.\7zip\Common\Alloc.cpp
# ADD CPP /D "COMPRESS_MF_BT"
# End Source File
# Begin Source File
SOURCE=.\7zip\Common\CRC.cpp
# ADD CPP /D "COMPRESS_MF_BT"
# End Source File
# Begin Source File
@ -170,16 +176,6 @@ SOURCE=.\7zip\7zip\Compress\LZMA\LZMAEncoder.cpp
# End Source File
# Begin Source File
SOURCE=.\7zip\7zip\Compress\LZMA\LZMALen.cpp
# ADD CPP /D "COMPRESS_MF_BT"
# End Source File
# Begin Source File
SOURCE=.\7zip\7zip\Compress\LZMA\LZMALiteral.cpp
# ADD CPP /D "COMPRESS_MF_BT"
# End Source File
# Begin Source File
SOURCE=.\7zip\7zip\Common\OutBuffer.cpp
# ADD CPP /D "COMPRESS_MF_BT"
# End Source File