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 // InBuffer.cpp
#include "stdafx.h" #include "StdAfx.h"
#include "InBuffer.h" #include "InBuffer.h"
CInBuffer::CInBuffer(UINT32 bufferSize): #include "../../Common/Alloc.h"
_bufferSize(bufferSize),
_bufferBase(0) 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) void CInBuffer::Init(ISequentialInStream *stream)
@ -22,20 +39,31 @@ void CInBuffer::Init(ISequentialInStream *stream)
_processedSize = 0; _processedSize = 0;
_buffer = _bufferBase; _buffer = _bufferBase;
_bufferLimit = _buffer; _bufferLimit = _buffer;
_streamWasExhausted = false; _wasFinished = false;
#ifdef _NO_EXCEPTIONS
ErrorCode = S_OK;
#endif
} }
bool CInBuffer::ReadBlock() bool CInBuffer::ReadBlock()
{ {
if (_streamWasExhausted) #ifdef _NO_EXCEPTIONS
if (ErrorCode != S_OK)
return false;
#endif
if (_wasFinished)
return false; return false;
_processedSize += (_buffer - _bufferBase); _processedSize += (_buffer - _bufferBase);
UINT32 numProcessedBytes; UInt32 numProcessedBytes;
HRESULT result = _stream->ReadPart(_bufferBase, _bufferSize, &numProcessedBytes); HRESULT result = _stream->ReadPart(_bufferBase, _bufferSize, &numProcessedBytes);
#ifdef _NO_EXCEPTIONS
ErrorCode = result;
#else
if (result != S_OK) if (result != S_OK)
throw CInBufferException(result); throw CInBufferException(result);
#endif
_buffer = _bufferBase; _buffer = _bufferBase;
_bufferLimit = _buffer + numProcessedBytes; _bufferLimit = _buffer + numProcessedBytes;
_streamWasExhausted = (numProcessedBytes == 0); _wasFinished = (numProcessedBytes == 0);
return (!_streamWasExhausted); return (!_wasFinished);
} }

View file

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

View file

@ -1,18 +1,28 @@
// Stream/OutByte.cpp // OutByte.cpp
#include "StdAfx.h" #include "StdAfx.h"
#include "OutBuffer.h" #include "OutBuffer.h"
COutBuffer::COutBuffer(UINT32 bufferSize): #include "../../Common/Alloc.h"
_bufferSize(bufferSize)
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) void COutBuffer::Init(ISequentialOutStream *stream)
@ -20,21 +30,16 @@ void COutBuffer::Init(ISequentialOutStream *stream)
_stream = stream; _stream = stream;
_processedSize = 0; _processedSize = 0;
_pos = 0; _pos = 0;
#ifdef _NO_EXCEPTIONS
ErrorCode = S_OK;
#endif
} }
/*
void COutBuffer::ReleaseStream()
{
_stream.Release();
}
*/
HRESULT COutBuffer::Flush() HRESULT COutBuffer::Flush()
{ {
if (_pos == 0) if (_pos == 0)
return S_OK; return S_OK;
UINT32 processedSize; UInt32 processedSize;
HRESULT result = _stream->Write(_buffer, _pos, &processedSize); HRESULT result = _stream->Write(_buffer, _pos, &processedSize);
if (result != S_OK) if (result != S_OK)
return result; return result;
@ -47,7 +52,15 @@ HRESULT COutBuffer::Flush()
void COutBuffer::WriteBlock() void COutBuffer::WriteBlock()
{ {
#ifdef _NO_EXCEPTIONS
if (ErrorCode != S_OK)
return;
#endif
HRESULT result = Flush(); HRESULT result = Flush();
#ifdef _NO_EXCEPTIONS
ErrorCode = result;
#else
if (result != S_OK) if (result != S_OK)
throw COutBufferException(result); throw COutBufferException(result);
#endif
} }

View file

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

View file

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

View file

@ -1,48 +1,14 @@
// BinTree.h // BinTree.h
// #pragma once
// #ifndef __BINTREE_H // #ifndef __BINTREE_H
// #define __BINTREE_H // #define __BINTREE_H
#include "../LZInWindow.h" #include "../LZInWindow.h"
// #include "Common/Types.h"
// #include "Windows/Defs.h"
namespace BT_NAMESPACE { namespace BT_NAMESPACE {
// #define __USE_3_BYTES typedef UInt32 CIndex;
const UInt32 kMaxValForNormalize = (UInt32(1) << 31) - 1;
#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
// #define HASH_ARRAY_2 // #define HASH_ARRAY_2
@ -56,26 +22,31 @@ const UINT32 kMaxValForNormalize = (UINT32(1) << 31) - 1;
// #endif // #endif
//#pragma pack(push, PragmaBinTreePair, 1)
#pragma pack(1)
// #pragma pack(push, 1)
struct CPair struct CPair
{ {
CIndex Left; CIndex Left;
CIndex Right; CIndex Right;
}; };
// #pragma pack(pop) /*
//#pragma pack(pop, PragmaBinTreePair) const int kNumBundleBits = 2;
#pragma pack() 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 class CInTree: public CLZInWindow
{ {
UINT32 _cyclicBufferPos; UInt32 _cyclicBufferPos;
UINT32 _cyclicBufferSize; UInt32 _cyclicBufferSize;
UINT32 _historySize; UInt32 _historySize;
UINT32 _matchMaxLen; UInt32 _matchMaxLen;
CIndex *_hash; CIndex *_hash;
@ -86,22 +57,23 @@ class CInTree: public CLZInWindow
#endif #endif
#endif #endif
// CBundle *_son;
CPair *_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 Normalize();
void FreeMemory(); void FreeMemory();
public: public:
CInTree(); CInTree();
virtual ~CInTree(); ~CInTree();
HRESULT Create(UINT32 sizeHistory, UINT32 keepAddBufferBefore, UINT32 matchMaxLen, HRESULT Create(UInt32 sizeHistory, UInt32 keepAddBufferBefore, UInt32 matchMaxLen,
UINT32 keepAddBufferAfter, UINT32 sizeReserv = (1<<17)); UInt32 keepAddBufferAfter, UInt32 sizeReserv = (1<<17));
HRESULT Init(ISequentialInStream *stream); HRESULT Init(ISequentialInStream *stream);
void SetCutValue(UINT32 cutValue) { _cutValue = cutValue; } void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; }
UINT32 GetLongestMatch(UINT32 *distances); UInt32 GetLongestMatch(UInt32 *distances);
void DummyLongestMatch(); void DummyLongestMatch();
HRESULT MovePos() HRESULT MovePos()
{ {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,7 +1,5 @@
// BinTreeMF.h // BinTreeMF.h
// #pragma once
// #ifndef __BINTREEMF_H // #ifndef __BINTREEMF_H
// #define __BINTREEMF_H // #define __BINTREEMF_H
@ -39,13 +37,8 @@ namespace BT_NAMESPACE {
#undef kIDUse3BytesByte #undef kIDUse3BytesByte
#undef kIDUse3BytesString #undef kIDUse3BytesString
#ifdef __USE_3_BYTES #define kIDUse3BytesByte 0x00
#define kIDUse3BytesByte 0x80 #define kIDUse3BytesString TEXT("")
#define kIDUse3BytesString TEXT("T")
#else
#define kIDUse3BytesByte 0x00
#define kIDUse3BytesString TEXT("")
#endif
// #undef kIDStringFull // #undef kIDStringFull
@ -62,7 +55,6 @@ class CInTree2: public CInTree
virtual void BeforeMoveBlock(); virtual void BeforeMoveBlock();
virtual void AfterMoveBlock(); virtual void AfterMoveBlock();
public: public:
virtual ~CInTree2() {}
void SetCallback(IMatchFinderCallback *callback) void SetCallback(IMatchFinderCallback *callback)
{ {
_callback = callback; _callback = callback;
@ -79,28 +71,28 @@ class CMatchFinderBinTree:
STDMETHOD(Init)(ISequentialInStream *stream); STDMETHOD(Init)(ISequentialInStream *stream);
STDMETHOD_(void, ReleaseStream)(); STDMETHOD_(void, ReleaseStream)();
STDMETHOD(MovePos)(); STDMETHOD(MovePos)();
STDMETHOD_(BYTE, GetIndexByte)(UINT32 index); STDMETHOD_(Byte, GetIndexByte)(Int32 index);
STDMETHOD_(UINT32, GetMatchLen)(UINT32 index, UINT32 back, UINT32 limit); STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit);
STDMETHOD_(UINT32, GetNumAvailableBytes)(); STDMETHOD_(UInt32, GetNumAvailableBytes)();
STDMETHOD_(const BYTE *, GetPointerToCurrentPos)(); STDMETHOD_(const Byte *, GetPointerToCurrentPos)();
STDMETHOD(Create)(UINT32 sizeHistory, STDMETHOD(Create)(UInt32 sizeHistory,
UINT32 keepAddBufferBefore, UINT32 matchMaxLen, UInt32 keepAddBufferBefore, UInt32 matchMaxLen,
UINT32 keepAddBufferAfter); UInt32 keepAddBufferAfter);
STDMETHOD_(UINT32, GetLongestMatch)(UINT32 *distances); STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances);
STDMETHOD_(void, DummyLongestMatch)(); STDMETHOD_(void, DummyLongestMatch)();
// IMatchFinderSetCallback // IMatchFinderSetCallback
STDMETHOD(SetCallback)(IMatchFinderCallback *callback); STDMETHOD(SetCallback)(IMatchFinderCallback *callback);
private: private:
// UINT32 m_WindowReservSize; // UInt32 m_WindowReservSize;
CInTree2 _matchFinder; CInTree2 _matchFinder;
public: public:
// CMatchFinderBinTree(): m_WindowReservSize((1 << 19) + 256) {}; // CMatchFinderBinTree(): m_WindowReservSize((1 << 19) + 256) {};
void SetCutValue(UINT32 cutValue) void SetCutValue(UInt32 cutValue)
{ _matchFinder.SetCutValue(cutValue); } { _matchFinder.SetCutValue(cutValue); }
/* /*
void SetWindowReservSize(UINT32 reservWindowSize) void SetWindowReservSize(UInt32 reservWindowSize)
{ m_WindowReservSize = reservWindowSize; } { m_WindowReservSize = reservWindowSize; }
*/ */
virtual ~CMatchFinderBinTree() {} virtual ~CMatchFinderBinTree() {}

View file

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

View file

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

View file

@ -1,7 +1,5 @@
// MatchFinders/IMatchFinder.h // MatchFinders/IMatchFinder.h
// #pragma once
#ifndef __IMATCHFINDER_H #ifndef __IMATCHFINDER_H
#define __IMATCHFINDER_H #define __IMATCHFINDER_H
@ -14,10 +12,10 @@ IInWindowStream: public IUnknown
STDMETHOD(Init)(ISequentialInStream *inStream) PURE; STDMETHOD(Init)(ISequentialInStream *inStream) PURE;
STDMETHOD_(void, ReleaseStream)() PURE; STDMETHOD_(void, ReleaseStream)() PURE;
STDMETHOD(MovePos)() PURE; STDMETHOD(MovePos)() PURE;
STDMETHOD_(BYTE, GetIndexByte)(UINT32 index) PURE; STDMETHOD_(Byte, GetIndexByte)(Int32 index) PURE;
STDMETHOD_(UINT32, GetMatchLen)(UINT32 index, UINT32 distance, UINT32 limit) PURE; STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 distance, UInt32 limit) PURE;
STDMETHOD_(UINT32, GetNumAvailableBytes)() PURE; STDMETHOD_(UInt32, GetNumAvailableBytes)() PURE;
STDMETHOD_(const BYTE *, GetPointerToCurrentPos)() PURE; STDMETHOD_(const Byte *, GetPointerToCurrentPos)() PURE;
}; };
// {23170F69-40C1-278A-0000-000200020000} // {23170F69-40C1-278A-0000-000200020000}
@ -26,9 +24,9 @@ DEFINE_GUID(IID_IMatchFinder,
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020000") MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020000")
IMatchFinder: public IInWindowStream IMatchFinder: public IInWindowStream
{ {
STDMETHOD(Create)(UINT32 historySize, UINT32 keepAddBufferBefore, STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore,
UINT32 matchMaxLen, UINT32 keepAddBufferAfter) PURE; UInt32 matchMaxLen, UInt32 keepAddBufferAfter) PURE;
STDMETHOD_(UINT32, GetLongestMatch)(UINT32 *distances) PURE; STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances) PURE;
STDMETHOD_(void, DummyLongestMatch)() PURE; STDMETHOD_(void, DummyLongestMatch)() PURE;
}; };

View file

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

View file

@ -1,7 +1,5 @@
// LZInWindow.h // LZInWindow.h
// #pragma once
#ifndef __LZ_IN_WINDOW_H #ifndef __LZ_IN_WINDOW_H
#define __LZ_IN_WINDOW_H #define __LZ_IN_WINDOW_H
@ -9,19 +7,19 @@
class CLZInWindow class CLZInWindow
{ {
BYTE *_bufferBase; // pointer to buffer with data Byte *_bufferBase; // pointer to buffer with data
ISequentialInStream *_stream; 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 bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
const BYTE *_pointerToLastSafePosition; const Byte *_pointerToLastSafePosition;
protected: protected:
BYTE *_buffer; // Pointer to virtual Buffer begin Byte *_buffer; // Pointer to virtual Buffer begin
UINT32 _blockSize; // Size of Allocated memory block UInt32 _blockSize; // Size of Allocated memory block
UINT32 _pos; // offset (from _buffer) of curent byte UInt32 _pos; // offset (from _buffer) of curent byte
UINT32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
UINT32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
UINT32 _keepSizeReserv; // how many BYTEs must be kept as reserv UInt32 _keepSizeReserv; // how many BYTEs must be kept as reserv
UINT32 _streamPos; // offset (from _buffer) of first not read byte from Stream UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream
virtual void BeforeMoveBlock() {}; virtual void BeforeMoveBlock() {};
virtual void AfterMoveBlock() {}; virtual void AfterMoveBlock() {};
@ -30,23 +28,24 @@ protected:
void Free(); void Free();
public: public:
CLZInWindow(): _bufferBase(0) {} CLZInWindow(): _bufferBase(0) {}
virtual ~CLZInWindow(); virtual ~CLZInWindow() { Free(); }
void Create(UINT32 keepSizeBefore, UINT32 keepSizeAfter,
UINT32 keepSizeReserv = (1<<17)); bool Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter,
UInt32 keepSizeReserv = (1<<17));
HRESULT Init(ISequentialInStream *stream); HRESULT Init(ISequentialInStream *stream);
// void ReleaseStream(); // 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() HRESULT MovePos()
{ {
_pos++; _pos++;
if (_pos > _posLimit) if (_pos > _posLimit)
{ {
const BYTE *pointerToPostion = _buffer + _pos; const Byte *pointerToPostion = _buffer + _pos;
if(pointerToPostion > _pointerToLastSafePosition) if(pointerToPostion > _pointerToLastSafePosition)
MoveBlock(); MoveBlock();
return ReadBlock(); return ReadBlock();
@ -54,29 +53,25 @@ public:
else else
return S_OK; return S_OK;
} }
// BYTE GetCurrentByte()const; Byte GetIndexByte(Int32 index)const
BYTE GetIndexByte(UINT32 index)const { return _buffer[(size_t)_pos + index]; }
{ return _buffer[_pos + index]; }
// UINT32 GetCurPos()const { return _pos;};
// BYTE *GetBufferBeg()const { return _buffer;};
// index + limit have not to exceed _keepSizeAfter; // 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(_streamEndWasReached)
if ((_pos + index) + limit > _streamPos) if ((_pos + index) + limit > _streamPos)
limit = _streamPos - (_pos + index); limit = _streamPos - (_pos + index);
back++; distance++;
BYTE *pby = _buffer + _pos + index; Byte *pby = _buffer + (size_t)_pos + index;
UINT32 i; UInt32 i;
for(i = 0; i < limit && pby[i] == pby[i - back]; i++); for(i = 0; i < limit && pby[i] == pby[(size_t)i - distance]; i++);
return 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; _buffer += subValue;
_posLimit -= subValue; _posLimit -= subValue;

View file

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

View file

@ -1,78 +1,71 @@
// LZOutWindow.h // LZOutWindow.h
// #pragma once
#ifndef __LZ_OUT_WINDOW_H #ifndef __LZ_OUT_WINDOW_H
#define __LZ_OUT_WINDOW_H #define __LZ_OUT_WINDOW_H
#include "../../IStream.h" #include "../../IStream.h"
// m_KeepSizeBefore: how mach BYTEs must be in buffer before _pos; #ifndef _NO_EXCEPTIONS
// m_KeepSizeAfter: how mach BYTEs must be in buffer after _pos;
// m_KeepSizeReserv: how mach BYTEs must be in buffer for Moving Reserv;
// must be >= aKeepSizeAfter; // test it
class CLZOutWindowException class CLZOutWindowException
{ {
public: public:
HRESULT ErrorCode; HRESULT ErrorCode;
CLZOutWindowException(HRESULT errorCode): ErrorCode(errorCode) {} CLZOutWindowException(HRESULT errorCode): ErrorCode(errorCode) {}
}; };
#endif
class CLZOutWindow class CLZOutWindow
{ {
BYTE *_buffer; Byte *_buffer;
UINT32 _pos; UInt32 _pos;
UINT32 _windowSize; UInt32 _windowSize;
UINT32 _streamPos; UInt32 _streamPos;
ISequentialOutStream *_stream; ISequentialOutStream *_stream;
void FlushWithCheck(); void FlushWithCheck();
public: public:
CLZOutWindow(): _buffer(0), _stream(0) {} #ifdef _NO_EXCEPTIONS
~CLZOutWindow(); HRESULT ErrorCode;
void Create(UINT32 windowSize); #endif
bool IsCreated() const { return _buffer != 0; }
void Free();
CLZOutWindow(): _buffer(0), _stream(0) {}
~CLZOutWindow() { Free(); /* ReleaseStream(); */ }
bool Create(UInt32 windowSize);
void Init(ISequentialOutStream *stream, bool solid = false); void Init(ISequentialOutStream *stream, bool solid = false);
HRESULT Flush(); HRESULT Flush();
// void ReleaseStream(); // void ReleaseStream();
// UINT32 GetCurPos() const { return _pos; } void CopyBlock(UInt32 distance, UInt32 len)
// const BYTE *GetPointerToCurrentPos() const { return _buffer + _pos;};
void CopyBackBlock(UINT32 distance, UINT32 len)
{ {
UINT32 pos = _pos - distance - 1; UInt32 pos = _pos - distance - 1;
if (pos >= _windowSize) if (pos >= _windowSize)
pos += _windowSize; pos += _windowSize;
for(; len > 0; len--) for(; len > 0; len--)
{ {
if (pos >= _windowSize) if (pos >= _windowSize)
pos = 0; pos = 0;
_buffer[_pos++] = _buffer[pos++]; _buffer[_pos++] = _buffer[pos++];
if (_pos >= _windowSize) if (_pos >= _windowSize)
FlushWithCheck(); FlushWithCheck();
// PutOneByte(GetOneByte(0 - distance)); // PutOneByte(GetOneByte(distance));
} }
} }
void PutOneByte(BYTE b) void PutByte(Byte b)
{ {
_buffer[_pos++] = b; _buffer[_pos++] = b;
if (_pos >= _windowSize) if (_pos >= _windowSize)
FlushWithCheck(); FlushWithCheck();
} }
BYTE GetOneByte(UINT32 index) const Byte GetByte(UInt32 distance) const
{ {
UINT32 pos = _pos + index; UInt32 pos = _pos - distance - 1;
if (pos >= _windowSize) if (pos >= _windowSize)
pos += _windowSize; pos += _windowSize;
return _buffer[pos]; return _buffer[pos];
} }
// BYTE *GetBuffer() const { return _buffer; }
}; };
#endif #endif

View file

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

View file

@ -1,55 +1,29 @@
// LZMA.h // LZMA.h
// #pragma once
#include "LZMALen.h"
#ifndef __LZMA_H #ifndef __LZMA_H
#define __LZMA_H #define __LZMA_H
namespace NCompress { namespace NCompress {
namespace NLZMA { 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 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 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 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 kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
class CState class CState
{ {
public: public:
BYTE Index; Byte Index;
void Init() void Init() { Index = 0; }
{ Index = 0; } void UpdateChar() { Index = kLiteralNextStates[Index]; }
void UpdateChar() void UpdateMatch() { Index = kMatchNextStates[Index]; }
{ Index = kLiteralNextStates[Index]; } void UpdateRep() { Index = kRepNextStates[Index]; }
void UpdateMatch() void UpdateShortRep() { Index = kShortRepNextStates[Index]; }
{ 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;
}
}; };
const int kNumPosSlotBits = 6; const int kNumPosSlotBits = 6;
@ -57,8 +31,9 @@ const int kDicLogSizeMin = 0;
const int kDicLogSizeMax = 32; const int kDicLogSizeMax = 32;
const int kDistTableSizeMax = kDicLogSizeMax * 2; const int kDistTableSizeMax = kDicLogSizeMax * 2;
const UINT32 kNumLenToPosStates = 4; const UInt32 kNumLenToPosStates = 4;
inline UINT32 GetLenToPosState(UINT32 len)
inline UInt32 GetLenToPosState(UInt32 len)
{ {
len -= 2; len -= 2;
if (len < kNumLenToPosStates) if (len < kNumLenToPosStates)
@ -66,31 +41,41 @@ inline UINT32 GetLenToPosState(UINT32 len)
return kNumLenToPosStates - 1; 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 int kNumAlignBits = 4;
const UINT32 kAlignTableSize = 1 << kNumAlignBits; const UInt32 kAlignTableSize = 1 << kNumAlignBits;
const UINT32 kAlignMask = (kAlignTableSize - 1); const UInt32 kAlignMask = (kAlignTableSize - 1);
const UINT32 kStartPosModelIndex = 4; const UInt32 kStartPosModelIndex = 4;
const UINT32 kEndPosModelIndex = 14; const UInt32 kEndPosModelIndex = 14;
const UINT32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex; const UInt32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
const UINT32 kNumFullDistances = 1 << (kEndPosModelIndex / 2); const UInt32 kNumFullDistances = 1 << (kEndPosModelIndex / 2);
const UINT32 kMainChoiceLiteralIndex = 0;
const UINT32 kMainChoiceMatchIndex = 1;
const UINT32 kMatchChoiceDistanceIndex= 0;
const UINT32 kMatchChoiceRepetitionIndex = 1;
const int kNumMoveBits = 5;
const int kNumLitPosStatesBitsEncodingMax = 4; const int kNumLitPosStatesBitsEncodingMax = 4;
const int kNumLitContextBitsMax = 8; const int kNumLitContextBitsMax = 8;
const int kNumMoveBits = 5;
}} }}
#endif #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 // LZMA/Encoder.h
// #pragma once
#ifndef __LZMA_ENCODER_H #ifndef __LZMA_ENCODER_H
#define __LZMA_ENCODER_H #define __LZMA_ENCODER_H
#include "../../ICoder.h"
#include "../../../Common/MyCom.h" #include "../../../Common/MyCom.h"
#include "../../../Common/Alloc.h"
#include "../../ICoder.h"
#include "../LZ/IMatchFinder.h" #include "../LZ/IMatchFinder.h"
#include "../RangeCoder/RangeCoderBitTree.h"
#include "LZMA.h" #include "LZMA.h"
#include "LZMALen.h"
#include "LZMALiteral.h"
namespace NCompress { namespace NCompress {
namespace NLZMA { namespace NLZMA {
class CMatchFinderException typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder;
class CBaseState
{ {
public: protected:
HRESULT ErrorCode; CState _state;
CMatchFinderException(HRESULT errorCode): ErrorCode(errorCode) {} 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 struct COptimal
@ -30,21 +40,21 @@ struct COptimal
bool Prev1IsChar; bool Prev1IsChar;
bool Prev2; bool Prev2;
UINT32 PosPrev2; UInt32 PosPrev2;
UINT32 BackPrev2; UInt32 BackPrev2;
UINT32 Price; UInt32 Price;
UINT32 PosPrev; // posNext; UInt32 PosPrev; // posNext;
UINT32 BackPrev; UInt32 BackPrev;
UINT32 Backs[kNumRepDistances]; UInt32 Backs[kNumRepDistances];
void MakeAsChar() { BackPrev = UINT32(-1); Prev1IsChar = false; } void MakeAsChar() { BackPrev = UInt32(-1); Prev1IsChar = false; }
void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; } void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
bool IsShortRep() { return (BackPrev == 0); } bool IsShortRep() { return (BackPrev == 0); }
}; };
extern BYTE g_FastPos[1024]; extern Byte g_FastPos[1024];
inline UINT32 GetPosSlot(UINT32 pos) inline UInt32 GetPosSlot(UInt32 pos)
{ {
if (pos < (1 << 10)) if (pos < (1 << 10))
return g_FastPos[pos]; return g_FastPos[pos];
@ -53,7 +63,7 @@ inline UINT32 GetPosSlot(UINT32 pos)
return g_FastPos[pos >> 18] + 36; return g_FastPos[pos >> 18] + 36;
} }
inline UINT32 GetPosSlot2(UINT32 pos) inline UInt32 GetPosSlot2(UInt32 pos)
{ {
if (pos < (1 << 16)) if (pos < (1 << 16))
return g_FastPos[pos >> 6] + 12; return g_FastPos[pos >> 6] + 12;
@ -62,79 +72,190 @@ inline UINT32 GetPosSlot2(UINT32 pos)
return g_FastPos[pos >> 24] + 48; 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 : class CEncoder :
public ICompressCoder, public ICompressCoder,
// public IInitMatchFinder, // public IInitMatchFinder,
public ICompressSetCoderProperties, public ICompressSetCoderProperties,
public ICompressWriteCoderProperties, public ICompressWriteCoderProperties,
public CBaseCoder, public CBaseState,
public CMyUnknownImp public CMyUnknownImp
{ {
COptimal _optimum[kNumOpts]; COptimal _optimum[kNumOpts];
public:
CMyComPtr<IMatchFinder> _matchFinder; // test it CMyComPtr<IMatchFinder> _matchFinder; // test it
NRangeCoder::CEncoder _rangeEncoder; NRangeCoder::CEncoder _rangeEncoder;
public:
private: private:
CMyBitEncoder _mainChoiceEncoders[kNumStates][NLength::kNumPosStatesEncodingMax]; CMyBitEncoder _isMatch[kNumStates][NLength::kNumPosStatesEncodingMax];
CMyBitEncoder _matchChoiceEncoders[kNumStates]; CMyBitEncoder _isRep[kNumStates];
CMyBitEncoder _matchRepChoiceEncoders[kNumStates]; CMyBitEncoder _isRepG0[kNumStates];
CMyBitEncoder _matchRep1ChoiceEncoders[kNumStates]; CMyBitEncoder _isRepG1[kNumStates];
CMyBitEncoder _matchRep2ChoiceEncoders[kNumStates]; CMyBitEncoder _isRepG2[kNumStates];
CMyBitEncoder _matchRepShortChoiceEncoders[kNumStates][NLength::kNumPosStatesEncodingMax]; CMyBitEncoder _isRep0Long[kNumStates][NLength::kNumPosStatesEncodingMax];
NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> _posSlotEncoder[kNumLenToPosStates]; NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> _posSlotEncoder[kNumLenToPosStates];
NRangeCoder::CReverseBitTreeEncoder2<kNumMoveBits> _posEncoders[kNumPosModels]; CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex];
NRangeCoder::CReverseBitTreeEncoder2<kNumMoveBits> _posAlignEncoder; NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumAlignBits> _posAlignEncoder;
NLength::CPriceTableEncoder _lenEncoder; NLength::CPriceTableEncoder _lenEncoder;
NLength::CPriceTableEncoder _repMatchLenEncoder; NLength::CPriceTableEncoder _repMatchLenEncoder;
NLiteral::CEncoder _literalEncoder; CLiteralEncoder _literalEncoder;
UINT32 _matchDistances[kMatchMaxLen + 1]; UInt32 _matchDistances[kMatchMaxLen + 1];
bool _fastMode; bool _fastMode;
bool _maxMode; bool _maxMode;
UInt32 _numFastBytes;
UInt32 _longestMatchLength;
UINT32 _numFastBytes; UInt32 _additionalOffset;
UINT32 _numFastBytesPrev;
UINT32 _longestMatchLength; UInt32 _optimumEndIndex;
UInt32 _optimumCurrentIndex;
UINT32 _additionalOffset;
UINT32 _optimumEndIndex;
UINT32 _optimumCurrentIndex;
bool _longestMatchWasFound; bool _longestMatchWasFound;
UINT32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; UInt32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
UINT32 _distancesPrices[kNumLenToPosStates][kNumFullDistances]; UInt32 _distancesPrices[kNumLenToPosStates][kNumFullDistances];
UINT32 _alignPrices[kAlignTableSize]; UInt32 _alignPrices[kAlignTableSize];
UINT32 _alignPriceCount; UInt32 _alignPriceCount;
UINT32 _dictionarySize; UInt32 _distTableSize;
UINT32 _dictionarySizePrev;
UINT32 _distTableSize; UInt32 _posStateBits;
UInt32 _posStateMask;
UInt32 _numLiteralPosStateBits;
UInt32 _numLiteralContextBits;
UINT32 _posStateBits; UInt32 _dictionarySize;
UINT32 _posStateMask;
UINT32 _numLiteralPosStateBits;
UINT32 _numLiteralContextBits;
UINT64 lastPosSlotFillingPos; UInt32 _dictionarySizePrev;
UINT64 nowPos64; UInt32 _numFastBytesPrev;
UInt64 lastPosSlotFillingPos;
UInt64 nowPos64;
bool _finished; bool _finished;
ISequentialInStream *_inStream; ISequentialInStream *_inStream;
@ -144,58 +265,49 @@ private:
#endif #endif
bool _writeEndMark; 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); bool _needReleaseMFStream;
UINT32 GetRepLen1Price(CState state, UINT32 posState) const
HRESULT ReadMatchDistances(UInt32 &len);
HRESULT MovePos(UInt32 num);
UInt32 GetRepLen1Price(CState state, UInt32 posState) const
{ {
return _matchRepChoiceEncoders[state.Index].GetPrice(0) + return _isRepG0[state.Index].GetPrice(0) +
_matchRepShortChoiceEncoders[state.Index][posState].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) if(repIndex == 0)
{ {
price += _matchRepChoiceEncoders[state.Index].GetPrice(0); price += _isRepG0[state.Index].GetPrice(0);
price += _matchRepShortChoiceEncoders[state.Index][posState].GetPrice(1); price += _isRep0Long[state.Index][posState].GetPrice(1);
} }
else else
{ {
price += _matchRepChoiceEncoders[state.Index].GetPrice(1); price += _isRepG0[state.Index].GetPrice(1);
if (repIndex == 1) if (repIndex == 1)
price += _matchRep1ChoiceEncoders[state.Index].GetPrice(0); price += _isRepG1[state.Index].GetPrice(0);
else else
{ {
price += _matchRep1ChoiceEncoders[state.Index].GetPrice(1); price += _isRepG1[state.Index].GetPrice(1);
price += _matchRep2ChoiceEncoders[state.Index].GetPrice(repIndex - 2); price += _isRepG2[state.Index].GetPrice(repIndex - 2);
} }
} }
return price; return price;
} }
/* /*
UINT32 GetPosLen2Price(UINT32 pos, UINT32 posState) const UInt32 GetPosLen2Price(UInt32 pos, UInt32 posState) const
{ {
if (pos >= kNumFullDistances) if (pos >= kNumFullDistances)
return kIfinityPrice; return kIfinityPrice;
return _distancesPrices[0][pos] + _lenEncoder.GetPrice(0, posState); 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 price;
UINT32 lenToPosState = GetLenToPosState(len); UInt32 lenToPosState = GetLenToPosState(len);
if (pos < kNumFullDistances) if (pos < kNumFullDistances)
price = _distancesPrices[lenToPosState][pos]; price = _distancesPrices[lenToPosState][pos];
else else
@ -204,12 +316,12 @@ private:
return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState); 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) if (len == 2 && pos >= 0x80)
return kIfinityPrice; return kIfinityPrice;
UINT32 price; UInt32 price;
UINT32 lenToPosState = GetLenToPosState(len); UInt32 lenToPosState = GetLenToPosState(len);
if (pos < kNumFullDistances) if (pos < kNumFullDistances)
price = _distancesPrices[lenToPosState][pos]; price = _distancesPrices[lenToPosState][pos];
else else
@ -218,9 +330,9 @@ private:
return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState); return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
} }
UINT32 Backward(UINT32 &backRes, UINT32 cur); UInt32 Backward(UInt32 &backRes, UInt32 cur);
UINT32 GetOptimum(UINT32 &backRes, UINT32 position); HRESULT GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes);
UINT32 GetOptimumFast(UINT32 &backRes, UINT32 position); HRESULT GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes);
void FillPosSlotPrices(); void FillPosSlotPrices();
void FillDistancesPrices(); void FillDistancesPrices();
@ -228,7 +340,11 @@ private:
void ReleaseStreams() void ReleaseStreams()
{ {
_matchFinder->ReleaseStream(); if (_matchFinder && _needReleaseMFStream)
{
_matchFinder->ReleaseStream();
_needReleaseMFStream = false;
}
// _rangeEncoder.ReleaseStream(); // _rangeEncoder.ReleaseStream();
} }
@ -245,21 +361,19 @@ private:
}; };
friend class CCoderReleaser; friend class CCoderReleaser;
void WriteEndMarker(UINT32 posState); void WriteEndMarker(UInt32 posState);
public: public:
CEncoder(); CEncoder();
virtual ~CEncoder() {}
void SetWriteEndMarkerMode(bool writeEndMarker) void SetWriteEndMarkerMode(bool writeEndMarker)
{ _writeEndMark= writeEndMarker; } { _writeEndMark= writeEndMarker; }
HRESULT Create(); HRESULT Create();
/*MY_UNKNOWN_IMP2( MY_UNKNOWN_IMP2(
ICompressSetCoderProperties, ICompressSetCoderProperties,
ICompressWriteCoderProperties ICompressWriteCoderProperties
)*/ )
MY_UNKNOWN_IMP
STDMETHOD(Init)( STDMETHOD(Init)(
ISequentialOutStream *outStream); ISequentialOutStream *outStream);
@ -267,18 +381,18 @@ public:
// ICompressCoder interface // ICompressCoder interface
HRESULT SetStreams(ISequentialInStream *inStream, HRESULT SetStreams(ISequentialInStream *inStream,
ISequentialOutStream *outStream, ISequentialOutStream *outStream,
const UINT64 *inSize, const UINT64 *outSize); const UInt64 *inSize, const UInt64 *outSize);
HRESULT CodeOneBlock(UINT64 *inSize, UINT64 *outSize, INT32 *finished); HRESULT CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished);
HRESULT CodeReal(ISequentialInStream *inStream, HRESULT CodeReal(ISequentialInStream *inStream,
ISequentialOutStream *outStream, ISequentialOutStream *outStream,
const UINT64 *inSize, const UINT64 *outSize, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress); ICompressProgressInfo *progress);
// ICompressCoder interface // ICompressCoder interface
STDMETHOD(Code)(ISequentialInStream *inStream, STDMETHOD(Code)(ISequentialInStream *inStream,
ISequentialOutStream *outStream, ISequentialOutStream *outStream,
const UINT64 *inSize, const UINT64 *outSize, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress); ICompressProgressInfo *progress);
// IInitMatchFinder interface // IInitMatchFinder interface
@ -286,10 +400,12 @@ public:
// ICompressSetCoderProperties2 // ICompressSetCoderProperties2
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
const PROPVARIANT *properties, UINT32 numProperties); const PROPVARIANT *properties, UInt32 numProperties);
// ICompressWriteCoderProperties // ICompressWriteCoderProperties
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); 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 #ifndef __STDAFX_H
#define __STDAFX_H #define __STDAFX_H
#ifdef _WIN32 #include "../../../../Platform.h"
# include <windows.h>
#else
# include "../../../../Platform.h"
#endif
#endif #endif

View file

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

View file

@ -7,12 +7,27 @@
namespace NCompress { namespace NCompress {
namespace NRangeCoder { 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 // simplest: bad solution
for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++) for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
StatePrices[i] = kBitPrice; ProbPrices[i] = kBitPrice;
*/ */
/* /*
@ -21,20 +36,20 @@ CPriceTables::CPriceTables()
// float solution // float solution
double ln2 = log(double(2)); double ln2 = log(double(2));
double lnAll = log(double(kBitModelTotal >> kNumMoveReducingBits)); double lnAll = log(double(kBitModelTotal >> kNumMoveReducingBits));
for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++) for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
StatePrices[i] = UINT32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice); ProbPrices[i] = UInt32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice);
*/ */
/* /*
// experimental, slow, solution: // 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 int kCyclesBits = 5;
const UINT32 kCycles = (1 << kCyclesBits); const UInt32 kCycles = (1 << kCyclesBits);
UINT32 range = UINT32(-1); UInt32 range = UInt32(-1);
UINT32 bitCount = 0; UInt32 bitCount = 0;
for (UINT32 j = 0; j < kCycles; j++) for (UInt32 j = 0; j < kCycles; j++)
{ {
range >>= (kNumBitModelTotalBits - kNumMoveReducingBits); range >>= (kNumBitModelTotalBits - kNumMoveReducingBits);
range *= i; range *= i;
@ -55,23 +70,11 @@ CPriceTables::CPriceTables()
range -= (1 << 31); range -= (1 << 31);
} }
} }
StatePrices[i] = (bitCount ProbPrices[i] = (bitCount
// + (1 << (kCyclesBits - 1)) // + (1 << (kCyclesBits - 1))
) >> kCyclesBits; ) >> 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 // Compress/RangeCoder/RangeCoderBit.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 "RangeCoder.h" #include "RangeCoder.h"
@ -11,74 +9,88 @@ namespace NCompress {
namespace NRangeCoder { namespace NRangeCoder {
const int kNumBitModelTotalBits = 11; const int kNumBitModelTotalBits = 11;
const UINT32 kBitModelTotal = (1 << kNumBitModelTotalBits); const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
const int kNumMoveReducingBits = 2; const int kNumMoveReducingBits = 2;
const int kNumBitPriceShiftBits = 6; const int kNumBitPriceShiftBits = 6;
const UINT32 kBitPrice = 1 << kNumBitPriceShiftBits; const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
class CPriceTables class CPriceTables
{ {
public: public:
UINT32 StatePrices[kBitModelTotal >> kNumMoveReducingBits]; static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
static void Init();
CPriceTables(); CPriceTables();
}; };
extern CPriceTables g_PriceTables; template <int numMoveBits>
/////////////////////////////
// CBitModel
template <int aNumMoveBits>
class CBitModel class CBitModel
{ {
public: public:
UINT32 Probability; UInt32 Prob;
void UpdateModel(UINT32 symbol) void UpdateModel(UInt32 symbol)
{ {
/* /*
Probability -= (Probability + ((symbol - 1) & ((1 << aNumMoveBits) - 1))) >> aNumMoveBits; Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
Probability += (1 - symbol) << (kNumBitModelTotalBits - aNumMoveBits); Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
*/ */
if (symbol == 0) if (symbol == 0)
Probability += (kBitModelTotal - Probability) >> aNumMoveBits; Prob += (kBitModelTotal - Prob) >> numMoveBits;
else else
Probability -= (Probability) >> aNumMoveBits; Prob -= (Prob) >> numMoveBits;
} }
public: public:
void Init() { Probability = kBitModelTotal / 2; } void Init() { Prob = kBitModelTotal / 2; }
}; };
template <int aNumMoveBits> template <int numMoveBits>
class CBitEncoder: public CBitModel<aNumMoveBits> class CBitEncoder: public CBitModel<numMoveBits>
{ {
public: public:
void Encode(CEncoder *encoder, UINT32 symbol) void Encode(CEncoder *encoder, UInt32 symbol)
{ {
encoder->EncodeBit(Probability, kNumBitModelTotalBits, symbol); encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
UpdateModel(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[ return CPriceTables::ProbPrices[
(((Probability - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits]; (((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
} }
}; };
template <int aNumMoveBits> template <int numMoveBits>
class CBitDecoder: public CBitModel<aNumMoveBits> class CBitDecoder: public CBitModel<numMoveBits>
{ {
public: 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) if (decoder->Code < newBound)
{ {
decoder->Range = newBound; decoder->Range = newBound;
Probability += (kBitModelTotal - Probability) >> aNumMoveBits; this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
if (decoder->Range < kTopValue) if (decoder->Range < kTopValue)
{ {
decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte(); decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
@ -90,7 +102,7 @@ public:
{ {
decoder->Range -= newBound; decoder->Range -= newBound;
decoder->Code -= newBound; decoder->Code -= newBound;
Probability -= (Probability) >> aNumMoveBits; this->Prob -= (this->Prob) >> numMoveBits;
if (decoder->Range < kTopValue) if (decoder->Range < kTopValue)
{ {
decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte(); decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
@ -103,5 +115,4 @@ public:
}} }}
#endif #endif

View file

@ -1,9 +1,7 @@
// Compress/RangeCoder/RangeCoderBitTree.h // Compress/RangeCoder/RangeCoderBitTree.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 "RangeCoderBit.h" #include "RangeCoderBit.h"
#include "RangeCoderOpt.h" #include "RangeCoderOpt.h"
@ -11,292 +9,154 @@
namespace NCompress { namespace NCompress {
namespace NRangeCoder { namespace NRangeCoder {
/* template <int numMoveBits, UInt32 NumBitLevels>
template <int numMoveBits> class CMyBitEncoder:
public NCompression::NArithmetic::CBitEncoder<numMoveBits> {};
template <int numMoveBits> class CMyBitDecoder:
public NCompression::NArithmetic::CBitDecoder<numMoveBits> {};
*/
//////////////////////////
// CBitTreeEncoder
template <int numMoveBits, UINT32 NumBitLevels>
class CBitTreeEncoder class CBitTreeEncoder
{ {
CBitEncoder<numMoveBits> Models[1 << NumBitLevels]; CBitEncoder<numMoveBits> Models[1 << NumBitLevels];
public: public:
void Init() void Init()
{ {
for(UINT32 i = 1; i < (1 << NumBitLevels); i++) for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
Models[i].Init(); Models[i].Init();
} }
void Encode(CEncoder *rangeEncoder, UINT32 symbol) void Encode(CEncoder *rangeEncoder, UInt32 symbol)
{ {
UINT32 modelIndex = 1; UInt32 modelIndex = 1;
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;) for (UInt32 bitIndex = NumBitLevels; bitIndex > 0 ;)
{ {
bitIndex--; bitIndex--;
UINT32 bit = (symbol >> bitIndex ) & 1; UInt32 bit = (symbol >> bitIndex) & 1;
Models[modelIndex].Encode(rangeEncoder, bit); Models[modelIndex].Encode(rangeEncoder, bit);
modelIndex = (modelIndex << 1) | bit; modelIndex = (modelIndex << 1) | bit;
} }
}; };
UINT32 GetPrice(UINT32 symbol) const void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol)
{ {
UINT32 price = 0; UInt32 modelIndex = 1;
UINT32 modelIndex = 1; for (UInt32 i = 0; i < NumBitLevels; i++)
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;) {
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--; bitIndex--;
UINT32 bit = (symbol >> bitIndex ) & 1; UInt32 bit = (symbol >> bitIndex) & 1;
price += Models[modelIndex].GetPrice(bit); price += Models[modelIndex].GetPrice(bit);
modelIndex = (modelIndex << 1) + bit; modelIndex = (modelIndex << 1) + bit;
} }
return price; 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;
}
}; };
////////////////////////// template <int numMoveBits, UInt32 NumBitLevels>
// CBitTreeDecoder
template <int numMoveBits, UINT32 NumBitLevels>
class CBitTreeDecoder class CBitTreeDecoder
{ {
CBitDecoder<numMoveBits> Models[1 << NumBitLevels]; CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
public: public:
void Init() void Init()
{ {
for(UINT32 i = 1; i < (1 << NumBitLevels); i++) for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
Models[i].Init(); Models[i].Init();
} }
UINT32 Decode(CDecoder *rangeDecoder) UInt32 Decode(CDecoder *rangeDecoder)
{ {
UINT32 modelIndex = 1; UInt32 modelIndex = 1;
RC_INIT_VAR RC_INIT_VAR
for(UINT32 bitIndex = NumBitLevels; bitIndex > 0; bitIndex--) for(UInt32 bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
{ {
// modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder); // modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
RC_GETBIT(numMoveBits, Models[modelIndex].Probability, modelIndex) RC_GETBIT(numMoveBits, Models[modelIndex].Prob, modelIndex)
} }
RC_FLUSH_VAR RC_FLUSH_VAR
return modelIndex - (1 << NumBitLevels); return modelIndex - (1 << NumBitLevels);
}; };
}; UInt32 ReverseDecode(CDecoder *rangeDecoder)
////////////////////////////////
// CReverseBitTreeEncoder
template <int numMoveBits>
class CReverseBitTreeEncoder2
{
CBitEncoder<numMoveBits> *Models;
UINT32 NumBitLevels;
public:
CReverseBitTreeEncoder2(): Models(0) { }
~CReverseBitTreeEncoder2() { delete []Models; }
void Create(UINT32 numBitLevels)
{ {
NumBitLevels = numBitLevels; UInt32 modelIndex = 1;
Models = new CBitEncoder<numMoveBits>[1 << numBitLevels]; UInt32 symbol = 0;
// return (Models != 0);
}
void Init()
{
UINT32 numModels = 1 << NumBitLevels;
for(UINT32 i = 1; i < numModels; i++)
Models[i].Init();
}
void Encode(CEncoder *rangeEncoder, UINT32 symbol)
{
UINT32 modelIndex = 1;
for (UINT32 i = 0; i < NumBitLevels; i++)
{
UINT32 bit = symbol & 1;
Models[modelIndex].Encode(rangeEncoder, bit);
modelIndex = (modelIndex << 1) | bit;
symbol >>= 1;
}
}
UINT32 GetPrice(UINT32 symbol) const
{
UINT32 price = 0;
UINT32 modelIndex = 1;
for (UINT32 i = NumBitLevels; i > 0; i--)
{
UINT32 bit = symbol & 1;
symbol >>= 1;
price += Models[modelIndex].GetPrice(bit);
modelIndex = (modelIndex << 1) | bit;
}
return price;
}
};
/*
template <int numMoveBits, int numBitLevels>
class CReverseBitTreeEncoder: public CReverseBitTreeEncoder2<numMoveBits>
{
public:
CReverseBitTreeEncoder()
{ Create(numBitLevels); }
};
*/
////////////////////////////////
// CReverseBitTreeDecoder
template <int numMoveBits>
class CReverseBitTreeDecoder2
{
CBitDecoder<numMoveBits> *Models;
UINT32 NumBitLevels;
public:
CReverseBitTreeDecoder2(): Models(0) { }
~CReverseBitTreeDecoder2() { delete []Models; }
void Create(UINT32 numBitLevels)
{
NumBitLevels = numBitLevels;
Models = new CBitDecoder<numMoveBits>[1 << numBitLevels];
// return (Models != 0);
}
void Init()
{
UINT32 numModels = 1 << NumBitLevels;
for(UINT32 i = 1; i < numModels; i++)
Models[i].Init();
}
UINT32 Decode(CDecoder *rangeDecoder)
{
UINT32 modelIndex = 1;
UINT32 symbol = 0;
RC_INIT_VAR 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 <<= 1;
// modelIndex += bit; // modelIndex += bit;
// symbol |= (bit << bitIndex); // 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;
};
};
////////////////////////////
// CReverseBitTreeDecoder2
template <int numMoveBits, UINT32 NumBitLevels>
class CReverseBitTreeDecoder
{
CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
public:
void Init()
{
for(UINT32 i = 1; i < (1 << NumBitLevels); i++)
Models[i].Init();
}
UINT32 Decode(CDecoder *rangeDecoder)
{
UINT32 modelIndex = 1;
UINT32 symbol = 0;
RC_INIT_VAR
for(UINT32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
{
// UINT32 bit = Models[modelIndex].Decode(rangeDecoder);
// modelIndex <<= 1;
// modelIndex += bit;
// symbol |= (bit << bitIndex);
RC_GETBIT2(numMoveBits, Models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << bitIndex))
} }
RC_FLUSH_VAR RC_FLUSH_VAR
return symbol; return symbol;
} }
}; };
/* template <int numMoveBits>
////////////////////////// void ReverseBitTreeEncode(CBitEncoder<numMoveBits> *Models,
// CBitTreeEncoder2 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> template <int numMoveBits>
class CBitTreeEncoder2 UInt32 ReverseBitTreeGetPrice(CBitEncoder<numMoveBits> *Models,
UInt32 NumBitLevels, UInt32 symbol)
{ {
NCompression::NArithmetic::CBitEncoder<numMoveBits> *Models; UInt32 price = 0;
UINT32 NumBitLevels; UInt32 modelIndex = 1;
public: for (UInt32 i = NumBitLevels; i > 0; i--)
bool Create(UINT32 numBitLevels)
{
NumBitLevels = numBitLevels;
Models = new NCompression::NArithmetic::CBitEncoder<numMoveBits>[1 << numBitLevels];
return (Models != 0);
}
void Init()
{ {
UINT32 numModels = 1 << NumBitLevels; UInt32 bit = symbol & 1;
for(UINT32 i = 1; i < numModels; i++) symbol >>= 1;
Models[i].Init(); price += Models[modelIndex].GetPrice(bit);
modelIndex = (modelIndex << 1) | bit;
} }
void Encode(CMyRangeEncoder *rangeEncoder, UINT32 symbol) return price;
{ }
UINT32 modelIndex = 1;
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
{
bitIndex--;
UINT32 bit = (symbol >> bitIndex ) & 1;
Models[modelIndex].Encode(rangeEncoder, bit);
modelIndex = (modelIndex << 1) | bit;
}
}
UINT32 GetPrice(UINT32 symbol) const
{
UINT32 price = 0;
UINT32 modelIndex = 1;
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
{
bitIndex--;
UINT32 bit = (symbol >> bitIndex ) & 1;
price += Models[modelIndex].GetPrice(bit);
modelIndex = (modelIndex << 1) + bit;
}
return price;
}
};
//////////////////////////
// CBitTreeDecoder2
template <int numMoveBits> template <int numMoveBits>
class CBitTreeDecoder2 UInt32 ReverseBitTreeDecode(CBitDecoder<numMoveBits> *Models,
CDecoder *rangeDecoder, UInt32 NumBitLevels)
{ {
NCompression::NArithmetic::CBitDecoder<numMoveBits> *Models; UInt32 modelIndex = 1;
UINT32 NumBitLevels; UInt32 symbol = 0;
public: RC_INIT_VAR
bool Create(UINT32 numBitLevels) for(UInt32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
{
NumBitLevels = numBitLevels;
Models = new NCompression::NArithmetic::CBitDecoder<numMoveBits>[1 << numBitLevels];
return (Models != 0);
}
void Init()
{ {
UINT32 numModels = 1 << NumBitLevels; // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
for(UINT32 i = 1; i < numModels; i++) // modelIndex <<= 1;
Models[i].Init(); // modelIndex += bit;
// symbol |= (bit << bitIndex);
RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
} }
UINT32 Decode(CMyRangeDecoder *rangeDecoder) RC_FLUSH_VAR
{ return symbol;
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);
}
};
*/
}} }}

View file

@ -1,43 +1,31 @@
// Compress/RangeCoder/RangeCoderOpt.h // Compress/RangeCoder/RangeCoderOpt.h
// #pragma once
#ifndef __COMPRESS_RANGECODER_OPT_H #ifndef __COMPRESS_RANGECODER_OPT_H
#define __COMPRESS_RANGECODER_OPT_H #define __COMPRESS_RANGECODER_OPT_H
#define RC_INIT_VAR \ #define RC_INIT_VAR \
UINT32 range = rangeDecoder->Range; \ UInt32 range = rangeDecoder->Range; \
UINT32 code = rangeDecoder->Code; UInt32 code = rangeDecoder->Code;
#define RC_FLUSH_VAR \ #define RC_FLUSH_VAR \
rangeDecoder->Range = range; \ rangeDecoder->Range = range; \
rangeDecoder->Code = code; rangeDecoder->Code = code;
#define RC_NORMALIZE \ #define RC_NORMALIZE \
if (range < NCompress::NRangeCoder::kTopValue) \ if (range < NCompress::NRangeCoder::kTopValue) \
{ \ { code = (code << 8) | rangeDecoder->Stream.ReadByte(); range <<= 8; }
code = (code << 8) | rangeDecoder->Stream.ReadByte(); \
range <<= 8; }
#define RC_GETBIT2(numMoveBits, prob, modelIndex, Action0, Action1) \ #define RC_GETBIT2(numMoveBits, prob, mi, A0, A1) \
{UINT32 newBound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \ { UInt32 bound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \
if (code < newBound) \ if (code < bound) \
{ \ { A0; range = bound; \
Action0; \ prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \
range = newBound; \ mi <<= 1; } \
prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \ else \
modelIndex <<= 1; \ { A1; range -= bound; code -= bound; prob -= (prob) >> numMoveBits; \
} \ mi = (mi + mi) + 1; }} \
else \ RC_NORMALIZE
{ \
Action1; \
range -= newBound; \
code -= newBound; \
prob -= (prob) >> numMoveBits; \
modelIndex = (modelIndex << 1) + 1; \
}} \
RC_NORMALIZE
#define RC_GETBIT(numMoveBits, prob, modelIndex) RC_GETBIT2(numMoveBits, prob, modelIndex, ; , ;) #define RC_GETBIT(numMoveBits, prob, mi) RC_GETBIT2(numMoveBits, prob, mi, ; , ;)
#endif #endif

View file

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

View file

@ -1,7 +1,5 @@
// ICoder.h // ICoder.h
// #pragma once
#ifndef __ICODER_H #ifndef __ICODER_H
#define __ICODER_H #define __ICODER_H
@ -13,7 +11,7 @@ DEFINE_GUID(IID_ICompressProgressInfo,
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200040000") MIDL_INTERFACE("23170F69-40C1-278A-0000-000200040000")
ICompressProgressInfo: public IUnknown 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} // {23170F69-40C1-278A-0000-000200050000}
@ -24,8 +22,8 @@ ICompressCoder: public IUnknown
{ {
STDMETHOD(Code)(ISequentialInStream *inStream, STDMETHOD(Code)(ISequentialInStream *inStream,
ISequentialOutStream *outStream, ISequentialOutStream *outStream,
const UINT64 *inSize, const UInt64 *inSize,
const UINT64 *outSize, const UInt64 *outSize,
ICompressProgressInfo *progress) = 0; ICompressProgressInfo *progress) = 0;
}; };
@ -36,11 +34,11 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000200180000")
ICompressCoder2: public IUnknown ICompressCoder2: public IUnknown
{ {
STDMETHOD(Code)(ISequentialInStream **inStreams, STDMETHOD(Code)(ISequentialInStream **inStreams,
const UINT64 **inSizes, const UInt64 **inSizes,
UINT32 numInStreams, UInt32 numInStreams,
ISequentialOutStream **outStreams, ISequentialOutStream **outStreams,
const UINT64 **outSizes, const UInt64 **outSizes,
UINT32 numOutStreams, UInt32 numOutStreams,
ICompressProgressInfo *progress) PURE; ICompressProgressInfo *progress) PURE;
}; };
@ -58,7 +56,8 @@ namespace NCoderPropID
kMatchFinder, kMatchFinder,
kNumPasses = 0x460, kNumPasses = 0x460,
kAlgorithm = 0x470, kAlgorithm = 0x470,
kMultiThread = 0x480 kMultiThread = 0x480,
kEndMarker = 0x490
}; };
} }
@ -69,7 +68,7 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000200200000")
ICompressSetCoderProperties: public IUnknown ICompressSetCoderProperties: public IUnknown
{ {
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
const PROPVARIANT *properties, UINT32 numProperties) PURE; const PROPVARIANT *properties, UInt32 numProperties) PURE;
}; };
// {23170F69-40C1-278A-0000-000200210000} // {23170F69-40C1-278A-0000-000200210000}
@ -78,7 +77,7 @@ DEFINE_GUID(IID_ICompressSetDecoderProperties,
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200210000") MIDL_INTERFACE("23170F69-40C1-278A-0000-000200210000")
ICompressSetDecoderProperties: public IUnknown ICompressSetDecoderProperties: public IUnknown
{ {
STDMETHOD(SetDecoderProperties)(ISequentialInStream *anInStream) PURE; STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;
}; };
// {23170F69-40C1-278A-0000-000200230000} // {23170F69-40C1-278A-0000-000200230000}
@ -96,7 +95,7 @@ DEFINE_GUID(IID_ICompressGetInStreamProcessedSize,
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200240000") MIDL_INTERFACE("23170F69-40C1-278A-0000-000200240000")
ICompressGetInStreamProcessedSize: public IUnknown ICompressGetInStreamProcessedSize: public IUnknown
{ {
STDMETHOD(GetInStreamProcessedSize)(UINT64 *value) PURE; STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;
}; };
// {23170F69-40C1-278A-0000-000200250000} // {23170F69-40C1-278A-0000-000200250000}
@ -105,7 +104,25 @@ DEFINE_GUID(IID_ICompressGetSubStreamSize,
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200250000") MIDL_INTERFACE("23170F69-40C1-278A-0000-000200250000")
ICompressGetSubStreamSize: public IUnknown 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, kEncoder,
kInStreams, kInStreams,
kOutStreams, 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 // IStream.h
// #pragma once
#ifndef __ISTREAMS_H #ifndef __ISTREAMS_H
#define __ISTREAMS_H #define __ISTREAMS_H
#include "IMyUnknown.h" #include "../Common/MyUnknown.h"
#include "../Common/Types.h"
// {23170F69-40C1-278A-0000-000000010000} // {23170F69-40C1-278A-0000-000000010000}
DEFINE_GUID(IID_ISequentialInStream, DEFINE_GUID(IID_ISequentialInStream,
@ -14,9 +13,15 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000010000")
ISequentialInStream : public IUnknown ISequentialInStream : public IUnknown
{ {
public: public:
// out: if (processedSize == 0) then there are no more bytes STDMETHOD(Read)(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;
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} // {23170F69-40C1-278A-0000-000000020000}
@ -26,8 +31,8 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000020000")
ISequentialOutStream : public IUnknown ISequentialOutStream : public IUnknown
{ {
public: public:
STDMETHOD(Write)(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; STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize) = 0;
}; };
// {23170F69-40C1-278A-0000-000000030000} // {23170F69-40C1-278A-0000-000000030000}
@ -37,7 +42,7 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000030000")
IInStream : public ISequentialInStream IInStream : public ISequentialInStream
{ {
public: public:
STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition) = 0; STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) = 0;
}; };
// {23170F69-40C1-278A-0000-000000040000} // {23170F69-40C1-278A-0000-000000040000}
@ -47,8 +52,8 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000040000")
IOutStream : public ISequentialOutStream IOutStream : public ISequentialOutStream
{ {
public: public:
STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition) = 0; STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) = 0;
STDMETHOD(SetSize)(INT64 aNewSize) = 0; STDMETHOD(SetSize)(Int64 newSize) = 0;
}; };
// {23170F69-40C1-278A-0000-000000060000} // {23170F69-40C1-278A-0000-000000060000}
@ -58,7 +63,17 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000060000")
IStreamGetSize : public IUnknown IStreamGetSize : public IUnknown
{ {
public: 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 #endif

View file

@ -4,18 +4,15 @@
#include "CRC.h" #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: for (UInt32 i = 0; i < 256; i++)
CCRCTableInit()
{
for (UINT32 i = 0; i < 256; i++)
{ {
UINT32 r = i; UInt32 r = i;
for (int j = 0; j < 8; j++) for (int j = 0; j < 8; j++)
if (r & 1) if (r & 1)
r = (r >> 1) ^ kCRCPoly; r = (r >> 1) ^ kCRCPoly;
@ -24,87 +21,35 @@ CCRCTableInit()
CCRC::Table[i] = r; CCRC::Table[i] = r;
} }
} }
class CCRCTableInit
{
public:
CCRCTableInit() { CCRC::InitTable(); }
} g_CRCTableInit; } g_CRCTableInit;
/* void CCRC::Update(Byte b)
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)
{ {
UINT32 valueLoc = _value; _value = Table[((Byte)(_value)) ^ b] ^ (_value >> 8);
const BYTE *byteBuffer = (const BYTE *)data; }
for(; (UINT_PTR(byteBuffer) & 3) != 0 && size > 0; size--, byteBuffer++) void CCRC::Update(UInt32 v)
valueLoc = Table[(((BYTE)(valueLoc)) ^ (*byteBuffer))] ^ {
(valueLoc >> 8); for (int i = 0; i < 4; i++)
Update((Byte)(v >> (8 * i)));
const UINT32 kBlockSize = 4; }
while (size >= kBlockSize)
{ void CCRC::Update(const UInt64 &v)
size -= kBlockSize; {
valueLoc ^= *(const UINT32 *)byteBuffer; for (int i = 0; i < 8; i++)
UPDATE4 Update((Byte)(v >> (8 * i)));
byteBuffer += kBlockSize; }
}
for(UINT32 i = 0; i < size; i++) void CCRC::Update(const void *data, UInt32 size)
valueLoc = Table[(((BYTE)(valueLoc)) ^ (byteBuffer)[i])] ^ {
(valueLoc >> 8); UInt32 v = _value;
_value = valueLoc; 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 // Common/CRC.h
// #pragma once
#ifndef __COMMON_CRC_H #ifndef __COMMON_CRC_H
#define __COMMON_CRC_H #define __COMMON_CRC_H
@ -9,20 +7,25 @@
class CCRC class CCRC
{ {
UINT32 _value; UInt32 _value;
public: public:
static UINT32 Table[256]; static UInt32 Table[256];
static void InitTable();
CCRC(): _value(0xFFFFFFFF){}; CCRC(): _value(0xFFFFFFFF){};
void Init() { _value = 0xFFFFFFFF; } void Init() { _value = 0xFFFFFFFF; }
void Update(const void *data, UINT32 size); void Update(Byte v);
UINT32 GetDigest() const { return _value ^ 0xFFFFFFFF; } void Update(UInt32 v);
static UINT32 CalculateDigest(const void *data, UINT32 size) 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; CCRC crc;
crc.Update(data, size); crc.Update(data, size);
return crc.GetDigest(); 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); 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 // Common/Defs.h
// #pragma once
#ifndef __COMMON_DEFS_H #ifndef __COMMON_DEFS_H
#define __COMMON_DEFS_H #define __COMMON_DEFS_H
@ -19,10 +17,4 @@ inline int BoolToInt(bool value)
inline bool IntToBool(int value) inline bool IntToBool(int value)
{ return (value != 0); } { return (value != 0); }
class CMemoryException
{
public:
CMemoryException() {}
};
#endif #endif

View file

@ -1,10 +1,10 @@
// MyCom.h // MyCom.h
// #pragma once
#ifndef __MYCOM_H #ifndef __MYCOM_H
#define __MYCOM_H #define __MYCOM_H
#include "MyWindows.h"
#define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; } #define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; }
template <class T> template <class T>
@ -50,10 +50,12 @@ public:
_p = NULL; _p = NULL;
return pt; 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); return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
}*/ }
#endif
/* /*
HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
{ {
@ -65,16 +67,16 @@ public:
return hr; return hr;
} }
*/ */
/*template <class Q> template <class Q>
HRESULT QueryInterface(REFGUID iid, Q** pp) const HRESULT QueryInterface(REFGUID iid, Q** pp) const
{ {
return _p->QueryInterface(iid, (void**)pp); return _p->QueryInterface(iid, (void**)pp);
}*/ }
}; };
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
/*class CMyComBSTR class CMyComBSTR
{ {
public: public:
BSTR m_str; BSTR m_str;
@ -83,7 +85,7 @@ public:
// CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); } // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
// CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); } // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); }
CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); } CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
/ * /*
CMyComBSTR(REFGUID src) CMyComBSTR(REFGUID src)
{ {
LPOLESTR szGuid; LPOLESTR szGuid;
@ -91,7 +93,7 @@ public:
m_str = ::SysAllocString(szGuid); m_str = ::SysAllocString(szGuid);
CoTaskMemFree(szGuid); CoTaskMemFree(szGuid);
} }
* / */
~CMyComBSTR() { ::SysFreeString(m_str); } ~CMyComBSTR() { ::SysFreeString(m_str); }
CMyComBSTR& operator=(const CMyComBSTR& src) CMyComBSTR& operator=(const CMyComBSTR& src)
{ {
@ -132,7 +134,7 @@ public:
m_str = NULL; m_str = NULL;
} }
bool operator!() const { return (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) \ 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 #endif

View file

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

View file

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

View file

@ -5,8 +5,8 @@
# #
# -- Objects and source files -- # -- 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 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 LZMALen.o LZMALiteral.o makenssi.o OutBuffer.o Plugins.o RangeCoderBit.o ResourceEditor.o ResourceVersionInfo.o script.o tokens.o trees.o util.o 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)))" "" ifeq "$(strip $(findstring i386pe,$(shell ld -V)))" ""
LIBS = -lstdc++ -lpthread LIBS = -lstdc++ -lpthread
EXESUFF = EXESUFF =

View file

@ -20,18 +20,21 @@
typedef unsigned char BYTE, *PBYTE, *LPBYTE; typedef unsigned char BYTE, *PBYTE, *LPBYTE;
typedef unsigned short WORD, *LPWORD; typedef unsigned short WORD, *LPWORD;
typedef unsigned long DWORD, *LPDWORD; typedef unsigned long DWORD, *LPDWORD;
typedef short SHORT;
typedef unsigned short USHORT;
typedef unsigned int UINT; typedef unsigned int UINT;
typedef unsigned int UINT32; typedef unsigned int UINT32;
typedef int INT; typedef int INT;
typedef int INT32; typedef int INT32;
typedef long LONG; typedef long LONG;
typedef unsigned long ULONG; typedef unsigned long ULONG;
typedef long long INT64; typedef long long INT64, LARGE_INTEGER;
typedef unsigned long long UINT64; typedef unsigned long long UINT64, ULARGE_INTEGER;
typedef int BOOL; typedef int BOOL;
typedef void VOID; typedef void VOID;
typedef void *LPVOID; typedef void *LPVOID;
typedef char CHAR, *PCHAR, *LPCH, *PCH, *NPSTR, *LPSTR, *PSTR; typedef char CHAR, *PCHAR, *LPCH, *PCH, *NPSTR, *LPSTR, *PSTR;
typedef unsigned char UCHAR;
typedef const char *LPCCH, *PCSTR, *LPCSTR; typedef const char *LPCCH, *PCSTR, *LPCSTR;
typedef unsigned short WCHAR, *PWCHAR, *LPWCH, *PWCH, *NWPSTR, *LPWSTR, *PWSTR; typedef unsigned short WCHAR, *PWCHAR, *LPWCH, *PWCH, *NWPSTR, *LPWSTR, *PWSTR;
typedef const unsigned short *LPCWCH, *PCWCH, *LPCWSTR, *PCWSTR; 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); int len = strlen(istr);
char *in = (char *) 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 insize = len + 1;
size_t outsize = (len + 1) * sizeof(WCHAR); size_t outsize = (len + 1) * sizeof(WCHAR);
if (__iconv_adaptor(iconv, cd, &in, &insize, &out, &outsize) == (size_t) -1) if (__iconv_adaptor(iconv, cd, &in, &insize, &out, &outsize) == (size_t) -1)

View file

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

View file

@ -156,7 +156,13 @@ SOURCE=.\7zip\7zGuids.cpp
# End Source File # End Source File
# Begin 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 SOURCE=.\7zip\Common\CRC.cpp
# ADD CPP /D "COMPRESS_MF_BT"
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -170,16 +176,6 @@ SOURCE=.\7zip\7zip\Compress\LZMA\LZMAEncoder.cpp
# End Source File # End Source File
# Begin 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 SOURCE=.\7zip\7zip\Common\OutBuffer.cpp
# ADD CPP /D "COMPRESS_MF_BT" # ADD CPP /D "COMPRESS_MF_BT"
# End Source File # End Source File