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:
parent
98caca8be1
commit
ec6957f356
52 changed files with 1715 additions and 2540 deletions
|
@ -1,19 +1,36 @@
|
|||
// InBuffer.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "InBuffer.h"
|
||||
|
||||
CInBuffer::CInBuffer(UINT32 bufferSize):
|
||||
_bufferSize(bufferSize),
|
||||
_bufferBase(0)
|
||||
#include "../../Common/Alloc.h"
|
||||
|
||||
CInBuffer::CInBuffer():
|
||||
_bufferBase(0),
|
||||
_bufferSize(0),
|
||||
_buffer(0),
|
||||
_bufferLimit(0),
|
||||
_stream(0)
|
||||
{}
|
||||
|
||||
bool CInBuffer::Create(UInt32 bufferSize)
|
||||
{
|
||||
_bufferBase = new BYTE[_bufferSize];
|
||||
const UInt32 kMinBlockSize = 1;
|
||||
if (bufferSize < kMinBlockSize)
|
||||
bufferSize = kMinBlockSize;
|
||||
if (_bufferBase != 0 && _bufferSize == bufferSize)
|
||||
return true;
|
||||
Free();
|
||||
_bufferSize = bufferSize;
|
||||
_bufferBase = (Byte *)::BigAlloc(bufferSize);
|
||||
return (_bufferBase != 0);
|
||||
}
|
||||
|
||||
CInBuffer::~CInBuffer()
|
||||
void CInBuffer::Free()
|
||||
{
|
||||
delete []_bufferBase;
|
||||
BigFree(_bufferBase);
|
||||
_bufferBase = 0;
|
||||
}
|
||||
|
||||
void CInBuffer::Init(ISequentialInStream *stream)
|
||||
|
@ -22,20 +39,31 @@ void CInBuffer::Init(ISequentialInStream *stream)
|
|||
_processedSize = 0;
|
||||
_buffer = _bufferBase;
|
||||
_bufferLimit = _buffer;
|
||||
_streamWasExhausted = false;
|
||||
_wasFinished = false;
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
ErrorCode = S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CInBuffer::ReadBlock()
|
||||
{
|
||||
if (_streamWasExhausted)
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
if (ErrorCode != S_OK)
|
||||
return false;
|
||||
#endif
|
||||
if (_wasFinished)
|
||||
return false;
|
||||
_processedSize += (_buffer - _bufferBase);
|
||||
UINT32 numProcessedBytes;
|
||||
UInt32 numProcessedBytes;
|
||||
HRESULT result = _stream->ReadPart(_bufferBase, _bufferSize, &numProcessedBytes);
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
ErrorCode = result;
|
||||
#else
|
||||
if (result != S_OK)
|
||||
throw CInBufferException(result);
|
||||
#endif
|
||||
_buffer = _bufferBase;
|
||||
_bufferLimit = _buffer + numProcessedBytes;
|
||||
_streamWasExhausted = (numProcessedBytes == 0);
|
||||
return (!_streamWasExhausted);
|
||||
_wasFinished = (numProcessedBytes == 0);
|
||||
return (!_wasFinished);
|
||||
}
|
||||
|
|
|
@ -1,69 +1,74 @@
|
|||
// InBuffer.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __INBUFFER_H
|
||||
#define __INBUFFER_H
|
||||
|
||||
#include "../IStream.h"
|
||||
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
class CInBufferException
|
||||
{
|
||||
public:
|
||||
HRESULT ErrorCode;
|
||||
CInBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
|
||||
};
|
||||
#endif
|
||||
|
||||
class CInBuffer
|
||||
{
|
||||
UINT64 _processedSize;
|
||||
BYTE *_bufferBase;
|
||||
UINT32 _bufferSize;
|
||||
BYTE *_buffer;
|
||||
BYTE *_bufferLimit;
|
||||
UInt64 _processedSize;
|
||||
Byte *_bufferBase;
|
||||
UInt32 _bufferSize;
|
||||
Byte *_buffer;
|
||||
Byte *_bufferLimit;
|
||||
ISequentialInStream *_stream;
|
||||
bool _streamWasExhausted;
|
||||
bool _wasFinished;
|
||||
|
||||
bool ReadBlock();
|
||||
|
||||
public:
|
||||
CInBuffer(UINT32 bufferSize = 0x100000);
|
||||
~CInBuffer();
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
HRESULT ErrorCode;
|
||||
#endif
|
||||
|
||||
CInBuffer();
|
||||
~CInBuffer() { Free(); }
|
||||
|
||||
bool Create(UInt32 bufferSize);
|
||||
void Free();
|
||||
|
||||
void Init(ISequentialInStream *stream);
|
||||
/*
|
||||
void ReleaseStream()
|
||||
{ _stream.Release(); }
|
||||
*/
|
||||
// void ReleaseStream() { _stream.Release(); }
|
||||
|
||||
bool ReadByte(BYTE &b)
|
||||
{
|
||||
if(_buffer >= _bufferLimit)
|
||||
if(!ReadBlock())
|
||||
return false;
|
||||
b = *_buffer++;
|
||||
return true;
|
||||
}
|
||||
BYTE ReadByte()
|
||||
{
|
||||
if(_buffer >= _bufferLimit)
|
||||
if(!ReadBlock())
|
||||
return 0x0;
|
||||
return *_buffer++;
|
||||
}
|
||||
void ReadBytes(void *data, UINT32 size, UINT32 &processedSize)
|
||||
{
|
||||
for(processedSize = 0; processedSize < size; processedSize++)
|
||||
if (!ReadByte(((BYTE *)data)[processedSize]))
|
||||
return;
|
||||
}
|
||||
bool ReadBytes(void *data, UINT32 size)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
ReadBytes(data, size, processedSize);
|
||||
return (processedSize == size);
|
||||
}
|
||||
UINT64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
|
||||
bool ReadByte(Byte &b)
|
||||
{
|
||||
if(_buffer >= _bufferLimit)
|
||||
if(!ReadBlock())
|
||||
return false;
|
||||
b = *_buffer++;
|
||||
return true;
|
||||
}
|
||||
Byte ReadByte()
|
||||
{
|
||||
if(_buffer >= _bufferLimit)
|
||||
if(!ReadBlock())
|
||||
return 0xFF;
|
||||
return *_buffer++;
|
||||
}
|
||||
void ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
|
||||
{
|
||||
for(processedSize = 0; processedSize < size; processedSize++)
|
||||
if (!ReadByte(((Byte *)data)[processedSize]))
|
||||
return;
|
||||
}
|
||||
bool ReadBytes(void *data, UInt32 size)
|
||||
{
|
||||
UInt32 processedSize;
|
||||
ReadBytes(data, size, processedSize);
|
||||
return (processedSize == size);
|
||||
}
|
||||
UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
|
||||
bool WasFinished() const { return _wasFinished; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,18 +1,28 @@
|
|||
// Stream/OutByte.cpp
|
||||
// OutByte.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "OutBuffer.h"
|
||||
|
||||
COutBuffer::COutBuffer(UINT32 bufferSize):
|
||||
_bufferSize(bufferSize)
|
||||
#include "../../Common/Alloc.h"
|
||||
|
||||
bool COutBuffer::Create(UInt32 bufferSize)
|
||||
{
|
||||
_buffer = new BYTE[_bufferSize];
|
||||
const UInt32 kMinBlockSize = 1;
|
||||
if (bufferSize < kMinBlockSize)
|
||||
bufferSize = kMinBlockSize;
|
||||
if (_buffer != 0 && _bufferSize == bufferSize)
|
||||
return true;
|
||||
Free();
|
||||
_bufferSize = bufferSize;
|
||||
_buffer = (Byte *)::BigAlloc(bufferSize);
|
||||
return (_buffer != 0);
|
||||
}
|
||||
|
||||
COutBuffer::~COutBuffer()
|
||||
void COutBuffer::Free()
|
||||
{
|
||||
delete []_buffer;
|
||||
BigFree(_buffer);
|
||||
_buffer = 0;
|
||||
}
|
||||
|
||||
void COutBuffer::Init(ISequentialOutStream *stream)
|
||||
|
@ -20,21 +30,16 @@ void COutBuffer::Init(ISequentialOutStream *stream)
|
|||
_stream = stream;
|
||||
_processedSize = 0;
|
||||
_pos = 0;
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
ErrorCode = S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
void COutBuffer::ReleaseStream()
|
||||
{
|
||||
_stream.Release();
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
HRESULT COutBuffer::Flush()
|
||||
{
|
||||
if (_pos == 0)
|
||||
return S_OK;
|
||||
UINT32 processedSize;
|
||||
UInt32 processedSize;
|
||||
HRESULT result = _stream->Write(_buffer, _pos, &processedSize);
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
|
@ -47,7 +52,15 @@ HRESULT COutBuffer::Flush()
|
|||
|
||||
void COutBuffer::WriteBlock()
|
||||
{
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
if (ErrorCode != S_OK)
|
||||
return;
|
||||
#endif
|
||||
HRESULT result = Flush();
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
ErrorCode = result;
|
||||
#else
|
||||
if (result != S_OK)
|
||||
throw COutBufferException(result);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,49 +1,69 @@
|
|||
// OutBuffer.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __OUTBUFFER_H
|
||||
#define __OUTBUFFER_H
|
||||
|
||||
#include "../IStream.h"
|
||||
|
||||
class COutBufferException
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
struct COutBufferException
|
||||
{
|
||||
public:
|
||||
HRESULT ErrorCode;
|
||||
COutBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
|
||||
};
|
||||
#endif
|
||||
|
||||
class COutBuffer
|
||||
{
|
||||
BYTE *_buffer;
|
||||
UINT32 _pos;
|
||||
UINT32 _bufferSize;
|
||||
Byte *_buffer;
|
||||
UInt32 _pos;
|
||||
UInt32 _bufferSize;
|
||||
ISequentialOutStream *_stream;
|
||||
UINT64 _processedSize;
|
||||
UInt64 _processedSize;
|
||||
|
||||
void WriteBlock();
|
||||
public:
|
||||
COutBuffer(UINT32 bufferSize = (1 << 20));
|
||||
~COutBuffer();
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
HRESULT ErrorCode;
|
||||
#endif
|
||||
|
||||
COutBuffer(): _buffer(0), _pos(0), _stream(0) {}
|
||||
~COutBuffer() { Free(); }
|
||||
|
||||
bool Create(UInt32 bufferSize);
|
||||
void Free();
|
||||
|
||||
void Init(ISequentialOutStream *stream);
|
||||
HRESULT Flush();
|
||||
// void ReleaseStream();
|
||||
// void ReleaseStream(); { _stream.Release(); }
|
||||
|
||||
void WriteByte(BYTE b)
|
||||
/*
|
||||
void *GetBuffer(UInt32 &sizeAvail)
|
||||
{
|
||||
sizeAvail = _bufferSize - _pos;
|
||||
return _buffer + _pos;
|
||||
}
|
||||
void MovePos(UInt32 num)
|
||||
{
|
||||
_pos += num;
|
||||
if(_pos >= _bufferSize)
|
||||
WriteBlock();
|
||||
}
|
||||
*/
|
||||
|
||||
void WriteByte(Byte b)
|
||||
{
|
||||
_buffer[_pos++] = b;
|
||||
if(_pos >= _bufferSize)
|
||||
WriteBlock();
|
||||
}
|
||||
void WriteBytes(const void *data, UINT32 size)
|
||||
void WriteBytes(const void *data, UInt32 size)
|
||||
{
|
||||
for (UINT32 i = 0; i < size; i++)
|
||||
WriteByte(((const BYTE *)data)[i]);
|
||||
for (UInt32 i = 0; i < size; i++)
|
||||
WriteByte(((const Byte *)data)[i]);
|
||||
}
|
||||
|
||||
UINT64 GetProcessedSize() const { return _processedSize + _pos; }
|
||||
UInt64 GetProcessedSize() const { return _processedSize + _pos; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include "../../../Platform.h"
|
||||
#endif
|
||||
#include "../../../Platform.h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,48 +1,14 @@
|
|||
// BinTree.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
// #ifndef __BINTREE_H
|
||||
// #define __BINTREE_H
|
||||
|
||||
#include "../LZInWindow.h"
|
||||
// #include "Common/Types.h"
|
||||
// #include "Windows/Defs.h"
|
||||
|
||||
namespace BT_NAMESPACE {
|
||||
|
||||
// #define __USE_3_BYTES
|
||||
|
||||
#ifdef __USE_3_BYTES
|
||||
|
||||
//#pragma pack(push, PragmaBinTree, 1)
|
||||
#pragma pack(1)
|
||||
|
||||
struct CIndex
|
||||
{
|
||||
BYTE Data[3];
|
||||
CIndex(){}
|
||||
CIndex(UINT32 value)
|
||||
{
|
||||
Data[0] = value & 0xFF;
|
||||
Data[1] = (value >> 8) & 0xFF;
|
||||
Data[2] = (value >> 16) & 0xFF;
|
||||
}
|
||||
operator UINT32() const { return (*((const UINT32 *)Data)) & 0xFFFFFF; }
|
||||
};
|
||||
const UINT32 kMaxValForNormalize = CIndex(-1);
|
||||
|
||||
//#pragma pack(pop, PragmaBinTree)
|
||||
#pragma pack()
|
||||
|
||||
#else
|
||||
|
||||
typedef UINT32 CIndex;
|
||||
const UINT32 kMaxValForNormalize = (UINT32(1) << 31) - 1;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
typedef UInt32 CIndex;
|
||||
const UInt32 kMaxValForNormalize = (UInt32(1) << 31) - 1;
|
||||
|
||||
// #define HASH_ARRAY_2
|
||||
|
||||
|
@ -56,26 +22,31 @@ const UINT32 kMaxValForNormalize = (UINT32(1) << 31) - 1;
|
|||
|
||||
// #endif
|
||||
|
||||
//#pragma pack(push, PragmaBinTreePair, 1)
|
||||
#pragma pack(1)
|
||||
// #pragma pack(push, 1)
|
||||
|
||||
struct CPair
|
||||
{
|
||||
CIndex Left;
|
||||
CIndex Right;
|
||||
};
|
||||
|
||||
// #pragma pack(pop)
|
||||
//#pragma pack(pop, PragmaBinTreePair)
|
||||
#pragma pack()
|
||||
/*
|
||||
const int kNumBundleBits = 2;
|
||||
const UInt32 kNumPairsInBundle = 1 << kNumBundleBits;
|
||||
const UInt32 kBundleMask = kNumPairsInBundle - 1;
|
||||
const UInt32 kNumBundleBytes = kNumPairsInBundle * sizeof(CPair);
|
||||
|
||||
struct CBundle
|
||||
{
|
||||
CPair Pairs[kNumPairsInBundle];
|
||||
Byte Bytes[kNumBundleBytes];
|
||||
};
|
||||
*/
|
||||
|
||||
class CInTree: public CLZInWindow
|
||||
{
|
||||
UINT32 _cyclicBufferPos;
|
||||
UINT32 _cyclicBufferSize;
|
||||
UINT32 _historySize;
|
||||
UINT32 _matchMaxLen;
|
||||
UInt32 _cyclicBufferPos;
|
||||
UInt32 _cyclicBufferSize;
|
||||
UInt32 _historySize;
|
||||
UInt32 _matchMaxLen;
|
||||
|
||||
CIndex *_hash;
|
||||
|
||||
|
@ -86,22 +57,23 @@ class CInTree: public CLZInWindow
|
|||
#endif
|
||||
#endif
|
||||
|
||||
// CBundle *_son;
|
||||
CPair *_son;
|
||||
|
||||
UINT32 _cutValue;
|
||||
UInt32 _cutValue;
|
||||
|
||||
void NormalizeLinks(CIndex *array, UINT32 numItems, UINT32 subValue);
|
||||
void NormalizeLinks(CIndex *items, UInt32 numItems, UInt32 subValue);
|
||||
void Normalize();
|
||||
void FreeMemory();
|
||||
|
||||
public:
|
||||
CInTree();
|
||||
virtual ~CInTree();
|
||||
HRESULT Create(UINT32 sizeHistory, UINT32 keepAddBufferBefore, UINT32 matchMaxLen,
|
||||
UINT32 keepAddBufferAfter, UINT32 sizeReserv = (1<<17));
|
||||
~CInTree();
|
||||
HRESULT Create(UInt32 sizeHistory, UInt32 keepAddBufferBefore, UInt32 matchMaxLen,
|
||||
UInt32 keepAddBufferAfter, UInt32 sizeReserv = (1<<17));
|
||||
HRESULT Init(ISequentialInStream *stream);
|
||||
void SetCutValue(UINT32 cutValue) { _cutValue = cutValue; }
|
||||
UINT32 GetLongestMatch(UINT32 *distances);
|
||||
void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; }
|
||||
UInt32 GetLongestMatch(UInt32 *distances);
|
||||
void DummyLongestMatch();
|
||||
HRESULT MovePos()
|
||||
{
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// BinTree2.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __BINTREE2__H
|
||||
#define __BINTREE2__H
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// BinTree3.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __BINTREE3__H
|
||||
#define __BINTREE3__H
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// BinTree3Z.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __BINTREE3Z__H
|
||||
#define __BINTREE3Z__H
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// BinTree3ZMain.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __BINTREE3ZMAIN__H
|
||||
#define __BINTREE3ZMAIN__H
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// BinTree4.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __BINTREE4__H
|
||||
#define __BINTREE4__H
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// BinTree4b.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __BINTREE4B__H
|
||||
#define __BINTREE4B__H
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// BinTreeMF.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
// #ifndef __BINTREEMF_H
|
||||
// #define __BINTREEMF_H
|
||||
|
||||
|
@ -39,13 +37,8 @@ namespace BT_NAMESPACE {
|
|||
#undef kIDUse3BytesByte
|
||||
#undef kIDUse3BytesString
|
||||
|
||||
#ifdef __USE_3_BYTES
|
||||
#define kIDUse3BytesByte 0x80
|
||||
#define kIDUse3BytesString TEXT("T")
|
||||
#else
|
||||
#define kIDUse3BytesByte 0x00
|
||||
#define kIDUse3BytesString TEXT("")
|
||||
#endif
|
||||
#define kIDUse3BytesByte 0x00
|
||||
#define kIDUse3BytesString TEXT("")
|
||||
|
||||
// #undef kIDStringFull
|
||||
|
||||
|
@ -62,7 +55,6 @@ class CInTree2: public CInTree
|
|||
virtual void BeforeMoveBlock();
|
||||
virtual void AfterMoveBlock();
|
||||
public:
|
||||
virtual ~CInTree2() {}
|
||||
void SetCallback(IMatchFinderCallback *callback)
|
||||
{
|
||||
_callback = callback;
|
||||
|
@ -79,28 +71,28 @@ class CMatchFinderBinTree:
|
|||
STDMETHOD(Init)(ISequentialInStream *stream);
|
||||
STDMETHOD_(void, ReleaseStream)();
|
||||
STDMETHOD(MovePos)();
|
||||
STDMETHOD_(BYTE, GetIndexByte)(UINT32 index);
|
||||
STDMETHOD_(UINT32, GetMatchLen)(UINT32 index, UINT32 back, UINT32 limit);
|
||||
STDMETHOD_(UINT32, GetNumAvailableBytes)();
|
||||
STDMETHOD_(const BYTE *, GetPointerToCurrentPos)();
|
||||
STDMETHOD(Create)(UINT32 sizeHistory,
|
||||
UINT32 keepAddBufferBefore, UINT32 matchMaxLen,
|
||||
UINT32 keepAddBufferAfter);
|
||||
STDMETHOD_(UINT32, GetLongestMatch)(UINT32 *distances);
|
||||
STDMETHOD_(Byte, GetIndexByte)(Int32 index);
|
||||
STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit);
|
||||
STDMETHOD_(UInt32, GetNumAvailableBytes)();
|
||||
STDMETHOD_(const Byte *, GetPointerToCurrentPos)();
|
||||
STDMETHOD(Create)(UInt32 sizeHistory,
|
||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen,
|
||||
UInt32 keepAddBufferAfter);
|
||||
STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances);
|
||||
STDMETHOD_(void, DummyLongestMatch)();
|
||||
|
||||
// IMatchFinderSetCallback
|
||||
STDMETHOD(SetCallback)(IMatchFinderCallback *callback);
|
||||
|
||||
private:
|
||||
// UINT32 m_WindowReservSize;
|
||||
// UInt32 m_WindowReservSize;
|
||||
CInTree2 _matchFinder;
|
||||
public:
|
||||
// CMatchFinderBinTree(): m_WindowReservSize((1 << 19) + 256) {};
|
||||
void SetCutValue(UINT32 cutValue)
|
||||
void SetCutValue(UInt32 cutValue)
|
||||
{ _matchFinder.SetCutValue(cutValue); }
|
||||
/*
|
||||
void SetWindowReservSize(UINT32 reservWindowSize)
|
||||
void SetWindowReservSize(UInt32 reservWindowSize)
|
||||
{ m_WindowReservSize = reservWindowSize; }
|
||||
*/
|
||||
virtual ~CMatchFinderBinTree() {}
|
||||
|
|
|
@ -32,40 +32,42 @@ STDMETHODIMP_(void) CMatchFinderBinTree::ReleaseStream()
|
|||
STDMETHODIMP CMatchFinderBinTree::MovePos()
|
||||
{ return _matchFinder.MovePos(); }
|
||||
|
||||
STDMETHODIMP_(BYTE) CMatchFinderBinTree::GetIndexByte(UINT32 index)
|
||||
STDMETHODIMP_(Byte) CMatchFinderBinTree::GetIndexByte(Int32 index)
|
||||
{ return _matchFinder.GetIndexByte(index); }
|
||||
|
||||
STDMETHODIMP_(UINT32) CMatchFinderBinTree::GetMatchLen(UINT32 index,
|
||||
UINT32 back, UINT32 limit)
|
||||
STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetMatchLen(Int32 index,
|
||||
UInt32 back, UInt32 limit)
|
||||
{ return _matchFinder.GetMatchLen(index, back, limit); }
|
||||
|
||||
STDMETHODIMP_(UINT32) CMatchFinderBinTree::GetNumAvailableBytes()
|
||||
STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetNumAvailableBytes()
|
||||
{ return _matchFinder.GetNumAvailableBytes(); }
|
||||
|
||||
STDMETHODIMP CMatchFinderBinTree::Create(UINT32 sizeHistory,
|
||||
UINT32 keepAddBufferBefore, UINT32 matchMaxLen,
|
||||
UINT32 keepAddBufferAfter)
|
||||
STDMETHODIMP CMatchFinderBinTree::Create(UInt32 sizeHistory,
|
||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen,
|
||||
UInt32 keepAddBufferAfter)
|
||||
{
|
||||
UINT32 windowReservSize = (sizeHistory + keepAddBufferBefore +
|
||||
UInt32 windowReservSize = (sizeHistory + keepAddBufferBefore +
|
||||
matchMaxLen + keepAddBufferAfter) / 2 + 256;
|
||||
try
|
||||
// try
|
||||
{
|
||||
return _matchFinder.Create(sizeHistory, keepAddBufferBefore,
|
||||
matchMaxLen, keepAddBufferAfter, windowReservSize);
|
||||
}
|
||||
/*
|
||||
catch(...)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
STDMETHODIMP_(UINT32) CMatchFinderBinTree::GetLongestMatch(UINT32 *distances)
|
||||
STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetLongestMatch(UInt32 *distances)
|
||||
{ return _matchFinder.GetLongestMatch(distances); }
|
||||
|
||||
STDMETHODIMP_(void) CMatchFinderBinTree::DummyLongestMatch()
|
||||
{ _matchFinder.DummyLongestMatch(); }
|
||||
|
||||
STDMETHODIMP_(const BYTE *) CMatchFinderBinTree::GetPointerToCurrentPos()
|
||||
STDMETHODIMP_(const Byte *) CMatchFinderBinTree::GetPointerToCurrentPos()
|
||||
{
|
||||
return _matchFinder.GetPointerToCurrentPos();
|
||||
}
|
||||
|
|
|
@ -1,40 +1,36 @@
|
|||
// BinTreemain.h
|
||||
|
||||
// #include "StdAfx.h"
|
||||
|
||||
// #include "BinTree.h"
|
||||
// #include "Common/NewHandler.h"
|
||||
// BinTreeMain.h
|
||||
|
||||
#include "../../../../Common/Defs.h"
|
||||
#include "../../../../Common/CRC.h"
|
||||
#include "../../../../Common/Alloc.h"
|
||||
|
||||
namespace BT_NAMESPACE {
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
static const UINT32 kHash2Size = 1 << 10;
|
||||
static const UInt32 kHash2Size = 1 << 10;
|
||||
#ifdef HASH_ARRAY_3
|
||||
static const UINT32 kNumHashDirectBytes = 0;
|
||||
static const UINT32 kNumHashBytes = 4;
|
||||
static const UINT32 kHash3Size = 1 << 18;
|
||||
static const UInt32 kNumHashDirectBytes = 0;
|
||||
static const UInt32 kNumHashBytes = 4;
|
||||
static const UInt32 kHash3Size = 1 << 18;
|
||||
#ifdef HASH_BIG
|
||||
static const UINT32 kHashSize = 1 << 23;
|
||||
static const UInt32 kHashSize = 1 << 23;
|
||||
#else
|
||||
static const UINT32 kHashSize = 1 << 20;
|
||||
static const UInt32 kHashSize = 1 << 20;
|
||||
#endif
|
||||
#else
|
||||
static const UINT32 kNumHashDirectBytes = 3;
|
||||
static const UINT32 kNumHashBytes = 3;
|
||||
static const UINT32 kHashSize = 1 << (8 * kNumHashBytes);
|
||||
static const UInt32 kNumHashDirectBytes = 3;
|
||||
static const UInt32 kNumHashBytes = 3;
|
||||
static const UInt32 kHashSize = 1 << (8 * kNumHashBytes);
|
||||
#endif
|
||||
#else
|
||||
#ifdef HASH_ZIP
|
||||
static const UINT32 kNumHashDirectBytes = 0;
|
||||
static const UINT32 kNumHashBytes = 3;
|
||||
static const UINT32 kHashSize = 1 << 16;
|
||||
static const UInt32 kNumHashDirectBytes = 0;
|
||||
static const UInt32 kNumHashBytes = 3;
|
||||
static const UInt32 kHashSize = 1 << 16;
|
||||
#else
|
||||
static const UINT32 kNumHashDirectBytes = 2;
|
||||
static const UINT32 kNumHashBytes = 2;
|
||||
static const UINT32 kHashSize = 1 << (8 * kNumHashBytes);
|
||||
static const UInt32 kNumHashDirectBytes = 2;
|
||||
static const UInt32 kNumHashBytes = 2;
|
||||
static const UInt32 kHashSize = 1 << (8 * kNumHashBytes);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -54,16 +50,9 @@ CInTree::CInTree():
|
|||
|
||||
void CInTree::FreeMemory()
|
||||
{
|
||||
#ifdef WIN32
|
||||
if (_son != 0)
|
||||
VirtualFree(_son, 0, MEM_RELEASE);
|
||||
if (_hash != 0)
|
||||
VirtualFree(_hash, 0, MEM_RELEASE);
|
||||
#else
|
||||
delete []_son;
|
||||
delete []_hash;
|
||||
#endif
|
||||
BigFree(_son);
|
||||
_son = 0;
|
||||
BigFree(_hash);
|
||||
_hash = 0;
|
||||
CLZInWindow::Free();
|
||||
}
|
||||
|
@ -73,68 +62,63 @@ CInTree::~CInTree()
|
|||
FreeMemory();
|
||||
}
|
||||
|
||||
HRESULT CInTree::Create(UINT32 sizeHistory, UINT32 keepAddBufferBefore,
|
||||
UINT32 matchMaxLen, UINT32 keepAddBufferAfter, UINT32 sizeReserv)
|
||||
HRESULT CInTree::Create(UInt32 sizeHistory, UInt32 keepAddBufferBefore,
|
||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, UInt32 sizeReserv)
|
||||
{
|
||||
FreeMemory();
|
||||
try
|
||||
{
|
||||
CLZInWindow::Create(sizeHistory + keepAddBufferBefore,
|
||||
matchMaxLen + keepAddBufferAfter, sizeReserv);
|
||||
|
||||
if (_blockSize + 256 > kMaxValForNormalize)
|
||||
return E_INVALIDARG;
|
||||
|
||||
_historySize = sizeHistory;
|
||||
_matchMaxLen = matchMaxLen;
|
||||
|
||||
_cyclicBufferSize = sizeHistory + 1;
|
||||
|
||||
|
||||
UINT32 size = kHashSize;
|
||||
#ifdef HASH_ARRAY_2
|
||||
size += kHash2Size;
|
||||
#ifdef HASH_ARRAY_3
|
||||
size += kHash3Size;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
_son = (CPair *)::VirtualAlloc(0, (_cyclicBufferSize + 1) * sizeof(CPair), MEM_COMMIT, PAGE_READWRITE);
|
||||
if (_son == 0)
|
||||
throw CMemoryException();
|
||||
_hash = (CIndex *)::VirtualAlloc(0, (size + 1) * sizeof(CIndex), MEM_COMMIT, PAGE_READWRITE);
|
||||
if (_hash == 0)
|
||||
throw CMemoryException();
|
||||
#else
|
||||
_son = new CPair[_cyclicBufferSize + 1];
|
||||
_hash = new CIndex[size + 1];
|
||||
#endif
|
||||
|
||||
// m_RightBase = &m_LeftBase[_blockSize];
|
||||
|
||||
// _hash = &m_RightBase[_blockSize];
|
||||
#ifdef HASH_ARRAY_2
|
||||
_hash2 = &_hash[kHashSize];
|
||||
#ifdef HASH_ARRAY_3
|
||||
_hash3 = &_hash2[kHash2Size];
|
||||
#endif
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
catch(...)
|
||||
if (!CLZInWindow::Create(sizeHistory + keepAddBufferBefore,
|
||||
matchMaxLen + keepAddBufferAfter, sizeReserv))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (_blockSize + 256 > kMaxValForNormalize)
|
||||
return E_INVALIDARG;
|
||||
|
||||
_historySize = sizeHistory;
|
||||
_matchMaxLen = matchMaxLen;
|
||||
|
||||
_cyclicBufferSize = sizeHistory + 1;
|
||||
|
||||
|
||||
UInt32 size = kHashSize;
|
||||
#ifdef HASH_ARRAY_2
|
||||
size += kHash2Size;
|
||||
#ifdef HASH_ARRAY_3
|
||||
size += kHash3Size;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
_son = (CPair *)BigAlloc((_cyclicBufferSize + 1) * sizeof(CPair));
|
||||
if (_son == 0)
|
||||
{
|
||||
FreeMemory();
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
// UInt32 numBundles = (_cyclicBufferSize + kNumPairsInBundle) >> kNumBundleBits;
|
||||
// _son = (CBundle *)::VirtualAlloc(0, numBundles * sizeof(CBundle), MEM_COMMIT, PAGE_READWRITE);
|
||||
_hash = (CIndex *)BigAlloc((size + 1) * sizeof(CIndex));
|
||||
if (_hash == 0)
|
||||
{
|
||||
FreeMemory();
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
// _hash = &m_RightBase[_blockSize];
|
||||
#ifdef HASH_ARRAY_2
|
||||
_hash2 = &_hash[kHashSize];
|
||||
#ifdef HASH_ARRAY_3
|
||||
_hash3 = &_hash2[kHash2Size];
|
||||
#endif
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const UINT32 kEmptyHashValue = 0;
|
||||
static const UInt32 kEmptyHashValue = 0;
|
||||
|
||||
HRESULT CInTree::Init(ISequentialInStream *stream)
|
||||
{
|
||||
RINOK(CLZInWindow::Init(stream));
|
||||
unsigned int i;
|
||||
UInt32 i;
|
||||
for(i = 0; i < kHashSize; i++)
|
||||
_hash[i] = kEmptyHashValue;
|
||||
|
||||
|
@ -149,81 +133,93 @@ HRESULT CInTree::Init(ISequentialInStream *stream)
|
|||
|
||||
_cyclicBufferPos = 0;
|
||||
|
||||
ReduceOffsets(0 - 1);
|
||||
ReduceOffsets(-1);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
#ifdef HASH_ARRAY_3
|
||||
inline UINT32 Hash(const BYTE *pointer, UINT32 &hash2Value, UINT32 &hash3Value)
|
||||
inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value, UInt32 &hash3Value)
|
||||
{
|
||||
UINT32 temp = CCRC::Table[pointer[0]] ^ pointer[1];
|
||||
UInt32 temp = CCRC::Table[pointer[0]] ^ pointer[1];
|
||||
hash2Value = temp & (kHash2Size - 1);
|
||||
hash3Value = (temp ^ (UINT32(pointer[2]) << 8)) & (kHash3Size - 1);
|
||||
return (temp ^ (UINT32(pointer[2]) << 8) ^ (CCRC::Table[pointer[3]] << 5)) &
|
||||
hash3Value = (temp ^ (UInt32(pointer[2]) << 8)) & (kHash3Size - 1);
|
||||
return (temp ^ (UInt32(pointer[2]) << 8) ^ (CCRC::Table[pointer[3]] << 5)) &
|
||||
(kHashSize - 1);
|
||||
}
|
||||
#else // no HASH_ARRAY_3
|
||||
inline UINT32 Hash(const BYTE *pointer, UINT32 &hash2Value)
|
||||
inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value)
|
||||
{
|
||||
hash2Value = (CCRC::Table[pointer[0]] ^ pointer[1]) & (kHash2Size - 1);
|
||||
return (*((const UINT32 *)pointer)) & 0xFFFFFF;
|
||||
return ((UInt32(pointer[0]) << 16)) | ((UInt32(pointer[1]) << 8)) | pointer[2];
|
||||
}
|
||||
#endif // HASH_ARRAY_3
|
||||
#else // no HASH_ARRAY_2
|
||||
#ifdef HASH_ZIP
|
||||
inline UINT32 Hash(const BYTE *pointer)
|
||||
inline UInt32 Hash(const Byte *pointer)
|
||||
{
|
||||
return ((UINT32(pointer[0]) << 8) ^
|
||||
return ((UInt32(pointer[0]) << 8) ^
|
||||
CCRC::Table[pointer[1]] ^ pointer[2]) & (kHashSize - 1);
|
||||
}
|
||||
#else // no HASH_ZIP
|
||||
inline UINT32 Hash(const BYTE *pointer)
|
||||
inline UInt32 Hash(const Byte *pointer)
|
||||
{
|
||||
return pointer[0] ^ (UINT32(pointer[1]) << 8);
|
||||
return pointer[0] ^ (UInt32(pointer[1]) << 8);
|
||||
}
|
||||
#endif // HASH_ZIP
|
||||
#endif // HASH_ARRAY_2
|
||||
|
||||
UINT32 CInTree::GetLongestMatch(UINT32 *distances)
|
||||
UInt32 CInTree::GetLongestMatch(UInt32 *distances)
|
||||
{
|
||||
UINT32 currentLimit;
|
||||
UInt32 lenLimit;
|
||||
if (_pos + _matchMaxLen <= _streamPos)
|
||||
currentLimit = _matchMaxLen;
|
||||
lenLimit = _matchMaxLen;
|
||||
else
|
||||
{
|
||||
currentLimit = _streamPos - _pos;
|
||||
if(currentLimit < kNumHashBytes)
|
||||
lenLimit = _streamPos - _pos;
|
||||
if(lenLimit < kNumHashBytes)
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT32 matchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1;
|
||||
BYTE *cur = _buffer + _pos;
|
||||
UInt32 matchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1;
|
||||
Byte *cur = _buffer + _pos;
|
||||
|
||||
/*
|
||||
if ((_cyclicBufferPos & kBundleMask) == 0)
|
||||
{
|
||||
Byte *bytes = _son[_cyclicBufferPos >> kNumBundleBits].Bytes;
|
||||
UInt32 bundleLimit = kNumBundleBytes;
|
||||
if (bundleLimit > lenLimit)
|
||||
bundleLimit = lenLimit;
|
||||
for (UInt32 i = 0; i < bundleLimit; i++)
|
||||
bytes[i] = cur[i];
|
||||
}
|
||||
*/
|
||||
|
||||
UINT32 matchHashLenMax = 0;
|
||||
UInt32 matchHashLenMax = 0;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
UINT32 hash2Value;
|
||||
UInt32 hash2Value;
|
||||
#ifdef HASH_ARRAY_3
|
||||
UINT32 hash3Value;
|
||||
UINT32 hashValue = Hash(cur, hash2Value, hash3Value);
|
||||
UInt32 hash3Value;
|
||||
UInt32 hashValue = Hash(cur, hash2Value, hash3Value);
|
||||
#else
|
||||
UINT32 hashValue = Hash(cur, hash2Value);
|
||||
UInt32 hashValue = Hash(cur, hash2Value);
|
||||
#endif
|
||||
#else
|
||||
UINT32 hashValue = Hash(cur);
|
||||
UInt32 hashValue = Hash(cur);
|
||||
#endif
|
||||
|
||||
UINT32 curMatch = _hash[hashValue];
|
||||
UInt32 curMatch = _hash[hashValue];
|
||||
#ifdef HASH_ARRAY_2
|
||||
UINT32 curMatch2 = _hash2[hash2Value];
|
||||
UInt32 curMatch2 = _hash2[hash2Value];
|
||||
#ifdef HASH_ARRAY_3
|
||||
UINT32 curMatch3 = _hash3[hash3Value];
|
||||
UInt32 curMatch3 = _hash3[hash3Value];
|
||||
#endif
|
||||
_hash2[hash2Value] = _pos;
|
||||
bool matchLen2Exist = false;
|
||||
UINT32 len2Distance = 0;
|
||||
UInt32 len2Distance = 0;
|
||||
if(curMatch2 >= matchMinPos)
|
||||
{
|
||||
if (_buffer[curMatch2] == cur[0])
|
||||
|
@ -236,8 +232,8 @@ UINT32 CInTree::GetLongestMatch(UINT32 *distances)
|
|||
|
||||
#ifdef HASH_ARRAY_3
|
||||
_hash3[hash3Value] = _pos;
|
||||
UINT32 matchLen3Exist = false;
|
||||
UINT32 len3Distance = 0;
|
||||
UInt32 matchLen3Exist = false;
|
||||
UInt32 len3Distance = 0;
|
||||
if(curMatch3 >= matchMinPos)
|
||||
{
|
||||
if (_buffer[curMatch3] == cur[0])
|
||||
|
@ -262,10 +258,14 @@ UINT32 CInTree::GetLongestMatch(UINT32 *distances)
|
|||
|
||||
_hash[hashValue] = _pos;
|
||||
|
||||
// UInt32 bi = _cyclicBufferPos >> kNumBundleBits;
|
||||
// UInt32 bo = _cyclicBufferPos & kBundleMask;
|
||||
// CPair &pair = _son[bi].Pairs[bo];
|
||||
CPair &pair = _son[_cyclicBufferPos];
|
||||
if(curMatch < matchMinPos)
|
||||
{
|
||||
_son[_cyclicBufferPos].Left = kEmptyHashValue;
|
||||
_son[_cyclicBufferPos].Right = kEmptyHashValue;
|
||||
pair.Left = kEmptyHashValue;
|
||||
pair.Right = kEmptyHashValue;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
distances[2] = len2Distance;
|
||||
|
@ -276,11 +276,11 @@ UINT32 CInTree::GetLongestMatch(UINT32 *distances)
|
|||
|
||||
return matchHashLenMax;
|
||||
}
|
||||
CIndex *ptrLeft = &_son[_cyclicBufferPos].Right;
|
||||
CIndex *ptrRight = &_son[_cyclicBufferPos].Left;
|
||||
CIndex *ptrLeft = &pair.Right;
|
||||
CIndex *ptrRight = &pair.Left;
|
||||
|
||||
UINT32 maxLen, minSameLeft, minSameRight, minSame;
|
||||
maxLen = minSameLeft = minSameRight = minSame = kNumHashDirectBytes;
|
||||
UInt32 maxLen, minLeft, minRight;
|
||||
maxLen = minLeft = minRight = kNumHashDirectBytes;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
#ifndef HASH_ARRAY_3
|
||||
|
@ -294,46 +294,66 @@ UINT32 CInTree::GetLongestMatch(UINT32 *distances)
|
|||
|
||||
distances[maxLen] = _pos - curMatch - 1;
|
||||
|
||||
for(UINT32 count = _cutValue; count > 0; count--)
|
||||
for(UInt32 count = _cutValue; count > 0; count--)
|
||||
{
|
||||
BYTE *pby1 = _buffer + curMatch;
|
||||
// CIndex left = _son[curMatch].Left; // it's prefetch
|
||||
UINT32 currentLen;
|
||||
for(currentLen = minSame; currentLen < currentLimit; currentLen++/*, dwComps++*/)
|
||||
if (pby1[currentLen] != cur[currentLen])
|
||||
break;
|
||||
while (currentLen > maxLen)
|
||||
distances[++maxLen] = _pos - curMatch - 1;
|
||||
|
||||
UINT32 delta = _pos - curMatch;
|
||||
UINT32 cyclicPos = (delta <= _cyclicBufferPos) ?
|
||||
/*
|
||||
UInt32 delta = _pos - curMatch;
|
||||
UInt32 cyclicPos = (delta <= _cyclicBufferPos) ?
|
||||
(_cyclicBufferPos - delta):
|
||||
(_cyclicBufferPos - delta + _cyclicBufferSize);
|
||||
|
||||
if (currentLen != currentLimit)
|
||||
CBundle &bundle = _son[cyclicPos >> kNumBundleBits];
|
||||
UInt32 bo = cyclicPos & kBundleMask;
|
||||
CPair &pair = bundle.Pairs[bo];
|
||||
|
||||
Byte *pby1 = bundle.Bytes + bo;
|
||||
UInt32 bundleLimit = kNumBundleBytes - bo;
|
||||
UInt32 currentLen = minSame;
|
||||
if (bundleLimit > lenLimit)
|
||||
bundleLimit = lenLimit;
|
||||
for(; currentLen < bundleLimit; currentLen++)
|
||||
if (pby1[currentLen] != cur[currentLen])
|
||||
break;
|
||||
if (currentLen >= bundleLimit)
|
||||
{
|
||||
pby1 = _buffer + curMatch;
|
||||
for(; currentLen < lenLimit; currentLen++)
|
||||
if (pby1[currentLen] != cur[currentLen])
|
||||
break;
|
||||
}
|
||||
*/
|
||||
Byte *pby1 = _buffer + curMatch;
|
||||
// CIndex left = pair.Left; // it's prefetch
|
||||
UInt32 currentLen = MyMin(minLeft, minRight);
|
||||
for(; currentLen < lenLimit; currentLen++)
|
||||
if (pby1[currentLen] != cur[currentLen])
|
||||
break;
|
||||
UInt32 delta = _pos - curMatch;
|
||||
while (currentLen > maxLen)
|
||||
distances[++maxLen] = delta - 1;
|
||||
|
||||
UInt32 cyclicPos = (delta <= _cyclicBufferPos) ?
|
||||
(_cyclicBufferPos - delta):
|
||||
(_cyclicBufferPos - delta + _cyclicBufferSize);
|
||||
CPair &pair = _son[cyclicPos];
|
||||
|
||||
if (currentLen != lenLimit)
|
||||
{
|
||||
if (pby1[currentLen] < cur[currentLen])
|
||||
{
|
||||
*ptrRight = curMatch;
|
||||
ptrRight = &_son[cyclicPos].Right;
|
||||
curMatch = _son[cyclicPos].Right;
|
||||
if(currentLen > minSameLeft)
|
||||
{
|
||||
minSameLeft = currentLen;
|
||||
minSame = MyMin(minSameLeft, minSameRight);
|
||||
}
|
||||
ptrRight = &pair.Right;
|
||||
curMatch = pair.Right;
|
||||
if(currentLen > minLeft)
|
||||
minLeft = currentLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptrLeft = curMatch;
|
||||
ptrLeft = &_son[cyclicPos].Left;
|
||||
// curMatch = left;
|
||||
curMatch = _son[cyclicPos].Left;
|
||||
if(currentLen > minSameRight)
|
||||
{
|
||||
minSameRight = currentLen;
|
||||
minSame = MyMin(minSameLeft, minSameRight);
|
||||
}
|
||||
ptrLeft = &pair.Left;
|
||||
curMatch = pair.Left;
|
||||
if(currentLen > minRight)
|
||||
minRight = currentLen;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -341,18 +361,15 @@ UINT32 CInTree::GetLongestMatch(UINT32 *distances)
|
|||
if(currentLen < _matchMaxLen)
|
||||
{
|
||||
*ptrLeft = curMatch;
|
||||
ptrLeft = &_son[cyclicPos].Left;
|
||||
curMatch = _son[cyclicPos].Left;
|
||||
if(currentLen > minSameRight)
|
||||
{
|
||||
minSameRight = currentLen;
|
||||
minSame = MyMin(minSameLeft, minSameRight);
|
||||
}
|
||||
ptrLeft = &pair.Left;
|
||||
curMatch = pair.Left;
|
||||
if(currentLen > minRight)
|
||||
minRight = currentLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptrLeft = _son[cyclicPos].Right;
|
||||
*ptrRight = _son[cyclicPos].Left;
|
||||
*ptrLeft = pair.Right;
|
||||
*ptrRight = pair.Left;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
if (matchLen2Exist && len2Distance < distances[2])
|
||||
|
@ -400,84 +417,79 @@ UINT32 CInTree::GetLongestMatch(UINT32 *distances)
|
|||
|
||||
void CInTree::DummyLongestMatch()
|
||||
{
|
||||
UINT32 currentLimit;
|
||||
UInt32 lenLimit;
|
||||
if (_pos + _matchMaxLen <= _streamPos)
|
||||
currentLimit = _matchMaxLen;
|
||||
lenLimit = _matchMaxLen;
|
||||
else
|
||||
{
|
||||
currentLimit = _streamPos - _pos;
|
||||
if(currentLimit < kNumHashBytes)
|
||||
lenLimit = _streamPos - _pos;
|
||||
if(lenLimit < kNumHashBytes)
|
||||
return;
|
||||
}
|
||||
UINT32 matchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1;
|
||||
BYTE *cur = _buffer + _pos;
|
||||
|
||||
UInt32 matchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1;
|
||||
Byte *cur = _buffer + _pos;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
UINT32 hash2Value;
|
||||
UInt32 hash2Value;
|
||||
#ifdef HASH_ARRAY_3
|
||||
UINT32 hash3Value;
|
||||
UINT32 hashValue = Hash(cur, hash2Value, hash3Value);
|
||||
UInt32 hash3Value;
|
||||
UInt32 hashValue = Hash(cur, hash2Value, hash3Value);
|
||||
_hash3[hash3Value] = _pos;
|
||||
#else
|
||||
UINT32 hashValue = Hash(cur, hash2Value);
|
||||
UInt32 hashValue = Hash(cur, hash2Value);
|
||||
#endif
|
||||
_hash2[hash2Value] = _pos;
|
||||
#else
|
||||
UINT32 hashValue = Hash(cur);
|
||||
UInt32 hashValue = Hash(cur);
|
||||
#endif
|
||||
|
||||
UINT32 curMatch = _hash[hashValue];
|
||||
UInt32 curMatch = _hash[hashValue];
|
||||
_hash[hashValue] = _pos;
|
||||
|
||||
CPair &pair = _son[_cyclicBufferPos];
|
||||
|
||||
if(curMatch < matchMinPos)
|
||||
{
|
||||
_son[_cyclicBufferPos].Left = kEmptyHashValue;
|
||||
_son[_cyclicBufferPos].Right = kEmptyHashValue;
|
||||
pair.Left = kEmptyHashValue;
|
||||
pair.Right = kEmptyHashValue;
|
||||
return;
|
||||
}
|
||||
CIndex *ptrLeft = &_son[_cyclicBufferPos].Right;
|
||||
CIndex *ptrRight = &_son[_cyclicBufferPos].Left;
|
||||
CIndex *ptrLeft = &pair.Right;
|
||||
CIndex *ptrRight = &pair.Left;
|
||||
|
||||
UINT32 maxLen, minSameLeft, minSameRight, minSame;
|
||||
maxLen = minSameLeft = minSameRight = minSame = kNumHashDirectBytes;
|
||||
for(UINT32 count = _cutValue; count > 0; count--)
|
||||
UInt32 maxLen, minLeft, minRight;
|
||||
maxLen = minLeft = minRight = kNumHashDirectBytes;
|
||||
for(UInt32 count = _cutValue; count > 0; count--)
|
||||
{
|
||||
BYTE *pby1 = _buffer + curMatch;
|
||||
// CIndex left = _son[curMatch].Left; // it's prefetch
|
||||
UINT32 currentLen;
|
||||
for(currentLen = minSame; currentLen < currentLimit; currentLen++/*, dwComps++*/)
|
||||
Byte *pby1 = _buffer + curMatch;
|
||||
UInt32 currentLen = MyMin(minLeft, minRight);
|
||||
for(; currentLen < lenLimit; currentLen++)
|
||||
if (pby1[currentLen] != cur[currentLen])
|
||||
break;
|
||||
|
||||
UINT32 delta = _pos - curMatch;
|
||||
UINT32 cyclicPos = (delta <= _cyclicBufferPos) ?
|
||||
UInt32 delta = _pos - curMatch;
|
||||
UInt32 cyclicPos = (delta <= _cyclicBufferPos) ?
|
||||
(_cyclicBufferPos - delta):
|
||||
(_cyclicBufferPos - delta + _cyclicBufferSize);
|
||||
|
||||
if (currentLen != currentLimit)
|
||||
CPair &pair = _son[cyclicPos];
|
||||
|
||||
if (currentLen != lenLimit)
|
||||
{
|
||||
if (pby1[currentLen] < cur[currentLen])
|
||||
{
|
||||
*ptrRight = curMatch;
|
||||
ptrRight = &_son[cyclicPos].Right;
|
||||
curMatch = _son[cyclicPos].Right;
|
||||
if(currentLen > minSameLeft)
|
||||
{
|
||||
minSameLeft = currentLen;
|
||||
minSame = MyMin(minSameLeft, minSameRight);
|
||||
}
|
||||
ptrRight = &pair.Right;
|
||||
curMatch = pair.Right;
|
||||
if(currentLen > minLeft)
|
||||
minLeft = currentLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptrLeft = curMatch;
|
||||
ptrLeft = &_son[cyclicPos].Left;
|
||||
curMatch = _son[cyclicPos].Left;
|
||||
// curMatch = left;
|
||||
if(currentLen > minSameRight)
|
||||
{
|
||||
minSameRight = currentLen;
|
||||
minSame = MyMin(minSameLeft, minSameRight);
|
||||
}
|
||||
ptrLeft = &pair.Left;
|
||||
curMatch = pair.Left;
|
||||
if(currentLen > minRight)
|
||||
minRight = currentLen;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -485,18 +497,15 @@ void CInTree::DummyLongestMatch()
|
|||
if(currentLen < _matchMaxLen)
|
||||
{
|
||||
*ptrLeft = curMatch;
|
||||
ptrLeft = &_son[cyclicPos].Left;
|
||||
curMatch = _son[cyclicPos].Left;
|
||||
if(currentLen > minSameRight)
|
||||
{
|
||||
minSameRight = currentLen;
|
||||
minSame = MyMin(minSameLeft, minSameRight);
|
||||
}
|
||||
ptrLeft = &pair.Left;
|
||||
curMatch = pair.Left;
|
||||
if(currentLen > minRight)
|
||||
minRight = currentLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptrLeft = _son[cyclicPos].Right;
|
||||
*ptrRight = _son[cyclicPos].Left;
|
||||
*ptrLeft = pair.Right;
|
||||
*ptrRight = pair.Left;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -507,23 +516,23 @@ void CInTree::DummyLongestMatch()
|
|||
*ptrRight = kEmptyHashValue;
|
||||
}
|
||||
|
||||
void CInTree::NormalizeLinks(CIndex *array, UINT32 numItems, UINT32 subValue)
|
||||
void CInTree::NormalizeLinks(CIndex *items, UInt32 numItems, UInt32 subValue)
|
||||
{
|
||||
for (UINT32 i = 0; i < numItems; i++)
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
UINT32 value = array[i];
|
||||
UInt32 value = items[i];
|
||||
if (value <= subValue)
|
||||
value = kEmptyHashValue;
|
||||
else
|
||||
value -= subValue;
|
||||
array[i] = value;
|
||||
items[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void CInTree::Normalize()
|
||||
{
|
||||
UINT32 startItem = _pos - _historySize;
|
||||
UINT32 subValue = startItem - 1;
|
||||
UInt32 startItem = _pos - _historySize;
|
||||
UInt32 subValue = startItem - 1;
|
||||
// NormalizeLinks((CIndex *)(_son + startItem), _historySize * 2, subValue);
|
||||
NormalizeLinks((CIndex *)_son, _cyclicBufferSize * 2, subValue);
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// MatchFinders/IMatchFinder.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __IMATCHFINDER_H
|
||||
#define __IMATCHFINDER_H
|
||||
|
||||
|
@ -14,10 +12,10 @@ IInWindowStream: public IUnknown
|
|||
STDMETHOD(Init)(ISequentialInStream *inStream) PURE;
|
||||
STDMETHOD_(void, ReleaseStream)() PURE;
|
||||
STDMETHOD(MovePos)() PURE;
|
||||
STDMETHOD_(BYTE, GetIndexByte)(UINT32 index) PURE;
|
||||
STDMETHOD_(UINT32, GetMatchLen)(UINT32 index, UINT32 distance, UINT32 limit) PURE;
|
||||
STDMETHOD_(UINT32, GetNumAvailableBytes)() PURE;
|
||||
STDMETHOD_(const BYTE *, GetPointerToCurrentPos)() PURE;
|
||||
STDMETHOD_(Byte, GetIndexByte)(Int32 index) PURE;
|
||||
STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 distance, UInt32 limit) PURE;
|
||||
STDMETHOD_(UInt32, GetNumAvailableBytes)() PURE;
|
||||
STDMETHOD_(const Byte *, GetPointerToCurrentPos)() PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200020000}
|
||||
|
@ -26,9 +24,9 @@ DEFINE_GUID(IID_IMatchFinder,
|
|||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020000")
|
||||
IMatchFinder: public IInWindowStream
|
||||
{
|
||||
STDMETHOD(Create)(UINT32 historySize, UINT32 keepAddBufferBefore,
|
||||
UINT32 matchMaxLen, UINT32 keepAddBufferAfter) PURE;
|
||||
STDMETHOD_(UINT32, GetLongestMatch)(UINT32 *distances) PURE;
|
||||
STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter) PURE;
|
||||
STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances) PURE;
|
||||
STDMETHOD_(void, DummyLongestMatch)() PURE;
|
||||
};
|
||||
|
||||
|
|
|
@ -4,27 +4,28 @@
|
|||
|
||||
#include "LZInWindow.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
CLZInWindow::~CLZInWindow()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
#include "../../../Common/Alloc.h"
|
||||
|
||||
void CLZInWindow::Free()
|
||||
{
|
||||
delete []_bufferBase;
|
||||
::BigFree(_bufferBase);
|
||||
_bufferBase = 0;
|
||||
}
|
||||
|
||||
void CLZInWindow::Create(UINT32 keepSizeBefore, UINT32 keepSizeAfter, UINT32 keepSizeReserv)
|
||||
bool CLZInWindow::Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)
|
||||
{
|
||||
_keepSizeBefore = keepSizeBefore;
|
||||
_keepSizeAfter = keepSizeAfter;
|
||||
_keepSizeReserv = keepSizeReserv;
|
||||
_blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
|
||||
Free();
|
||||
_bufferBase = new BYTE[_blockSize];
|
||||
UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
|
||||
if (_bufferBase == 0 || _blockSize != blockSize)
|
||||
{
|
||||
Free();
|
||||
_blockSize = blockSize;
|
||||
_bufferBase = (Byte *)::BigAlloc(_blockSize);
|
||||
}
|
||||
_pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter;
|
||||
return (_bufferBase != 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -64,17 +65,17 @@ HRESULT CLZInWindow::ReadBlock()
|
|||
return S_OK;
|
||||
while(true)
|
||||
{
|
||||
UINT32 size = (_bufferBase + _blockSize) - (_buffer + _streamPos);
|
||||
UInt32 size = UInt32(_bufferBase - _buffer) + _blockSize - _streamPos;
|
||||
if(size == 0)
|
||||
return S_OK;
|
||||
UINT32 numReadBytes;
|
||||
UInt32 numReadBytes;
|
||||
RINOK(_stream->ReadPart(_buffer + _streamPos, size, &numReadBytes));
|
||||
if(numReadBytes == 0)
|
||||
{
|
||||
_posLimit = _streamPos;
|
||||
const BYTE *pointerToPostion = _buffer + _posLimit;
|
||||
const Byte *pointerToPostion = _buffer + _posLimit;
|
||||
if(pointerToPostion > _pointerToLastSafePosition)
|
||||
_posLimit = _pointerToLastSafePosition - _buffer;
|
||||
_posLimit = (UInt32)(_pointerToLastSafePosition - _buffer);
|
||||
_streamEndWasReached = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -90,8 +91,8 @@ HRESULT CLZInWindow::ReadBlock()
|
|||
void CLZInWindow::MoveBlock()
|
||||
{
|
||||
BeforeMoveBlock();
|
||||
UINT32 offset = (_buffer + _pos - _keepSizeBefore) - _bufferBase;
|
||||
UINT32 numBytes = (_buffer + _streamPos) - (_bufferBase + offset);
|
||||
UInt32 offset = UInt32(_buffer - _bufferBase) + _pos - _keepSizeBefore;
|
||||
UInt32 numBytes = UInt32(_buffer - _bufferBase) + _streamPos - offset;
|
||||
memmove(_bufferBase, _bufferBase + offset, numBytes);
|
||||
_buffer -= offset;
|
||||
AfterMoveBlock();
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// LZInWindow.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __LZ_IN_WINDOW_H
|
||||
#define __LZ_IN_WINDOW_H
|
||||
|
||||
|
@ -9,19 +7,19 @@
|
|||
|
||||
class CLZInWindow
|
||||
{
|
||||
BYTE *_bufferBase; // pointer to buffer with data
|
||||
Byte *_bufferBase; // pointer to buffer with data
|
||||
ISequentialInStream *_stream;
|
||||
UINT32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
|
||||
UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
|
||||
bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
|
||||
const BYTE *_pointerToLastSafePosition;
|
||||
const Byte *_pointerToLastSafePosition;
|
||||
protected:
|
||||
BYTE *_buffer; // Pointer to virtual Buffer begin
|
||||
UINT32 _blockSize; // Size of Allocated memory block
|
||||
UINT32 _pos; // offset (from _buffer) of curent byte
|
||||
UINT32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
|
||||
UINT32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
|
||||
UINT32 _keepSizeReserv; // how many BYTEs must be kept as reserv
|
||||
UINT32 _streamPos; // offset (from _buffer) of first not read byte from Stream
|
||||
Byte *_buffer; // Pointer to virtual Buffer begin
|
||||
UInt32 _blockSize; // Size of Allocated memory block
|
||||
UInt32 _pos; // offset (from _buffer) of curent byte
|
||||
UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
|
||||
UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
|
||||
UInt32 _keepSizeReserv; // how many BYTEs must be kept as reserv
|
||||
UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream
|
||||
|
||||
virtual void BeforeMoveBlock() {};
|
||||
virtual void AfterMoveBlock() {};
|
||||
|
@ -30,23 +28,24 @@ protected:
|
|||
void Free();
|
||||
public:
|
||||
CLZInWindow(): _bufferBase(0) {}
|
||||
virtual ~CLZInWindow();
|
||||
void Create(UINT32 keepSizeBefore, UINT32 keepSizeAfter,
|
||||
UINT32 keepSizeReserv = (1<<17));
|
||||
virtual ~CLZInWindow() { Free(); }
|
||||
|
||||
bool Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter,
|
||||
UInt32 keepSizeReserv = (1<<17));
|
||||
|
||||
HRESULT Init(ISequentialInStream *stream);
|
||||
// void ReleaseStream();
|
||||
|
||||
BYTE *GetBuffer() const { return _buffer; }
|
||||
Byte *GetBuffer() const { return _buffer; }
|
||||
|
||||
const BYTE *GetPointerToCurrentPos() const { return _buffer + _pos; }
|
||||
const Byte *GetPointerToCurrentPos() const { return _buffer + _pos; }
|
||||
|
||||
HRESULT MovePos()
|
||||
{
|
||||
_pos++;
|
||||
if (_pos > _posLimit)
|
||||
{
|
||||
const BYTE *pointerToPostion = _buffer + _pos;
|
||||
const Byte *pointerToPostion = _buffer + _pos;
|
||||
if(pointerToPostion > _pointerToLastSafePosition)
|
||||
MoveBlock();
|
||||
return ReadBlock();
|
||||
|
@ -54,29 +53,25 @@ public:
|
|||
else
|
||||
return S_OK;
|
||||
}
|
||||
// BYTE GetCurrentByte()const;
|
||||
BYTE GetIndexByte(UINT32 index)const
|
||||
{ return _buffer[_pos + index]; }
|
||||
|
||||
// UINT32 GetCurPos()const { return _pos;};
|
||||
// BYTE *GetBufferBeg()const { return _buffer;};
|
||||
Byte GetIndexByte(Int32 index)const
|
||||
{ return _buffer[(size_t)_pos + index]; }
|
||||
|
||||
// index + limit have not to exceed _keepSizeAfter;
|
||||
UINT32 GetMatchLen(UINT32 index, UINT32 back, UINT32 limit) const
|
||||
UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) const
|
||||
{
|
||||
if(_streamEndWasReached)
|
||||
if ((_pos + index) + limit > _streamPos)
|
||||
limit = _streamPos - (_pos + index);
|
||||
back++;
|
||||
BYTE *pby = _buffer + _pos + index;
|
||||
UINT32 i;
|
||||
for(i = 0; i < limit && pby[i] == pby[i - back]; i++);
|
||||
distance++;
|
||||
Byte *pby = _buffer + (size_t)_pos + index;
|
||||
UInt32 i;
|
||||
for(i = 0; i < limit && pby[i] == pby[(size_t)i - distance]; i++);
|
||||
return i;
|
||||
}
|
||||
|
||||
UINT32 GetNumAvailableBytes() const { return _streamPos - _pos; }
|
||||
UInt32 GetNumAvailableBytes() const { return _streamPos - _pos; }
|
||||
|
||||
void ReduceOffsets(UINT32 subValue)
|
||||
void ReduceOffsets(Int32 subValue)
|
||||
{
|
||||
_buffer += subValue;
|
||||
_posLimit -= subValue;
|
||||
|
|
|
@ -2,36 +2,29 @@
|
|||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/Alloc.h"
|
||||
#include "LZOutWindow.h"
|
||||
|
||||
void CLZOutWindow::Create(UINT32 windowSize)
|
||||
bool CLZOutWindow::Create(UInt32 windowSize)
|
||||
{
|
||||
_pos = 0;
|
||||
_streamPos = 0;
|
||||
UINT32 newBlockSize = windowSize;
|
||||
const UINT32 kMinBlockSize = 1;
|
||||
if (newBlockSize < kMinBlockSize)
|
||||
newBlockSize = kMinBlockSize;
|
||||
if (_buffer != 0 && _windowSize == newBlockSize)
|
||||
return;
|
||||
delete []_buffer;
|
||||
_buffer = 0;
|
||||
_windowSize = newBlockSize;
|
||||
_buffer = new BYTE[_windowSize];
|
||||
}
|
||||
|
||||
CLZOutWindow::~CLZOutWindow()
|
||||
{
|
||||
// ReleaseStream();
|
||||
delete []_buffer;
|
||||
}
|
||||
|
||||
/*
|
||||
void CLZOutWindow::SetWindowSize(UINT32 windowSize)
|
||||
{
|
||||
const UInt32 kMinBlockSize = 1;
|
||||
if (windowSize < kMinBlockSize)
|
||||
windowSize = kMinBlockSize;
|
||||
if (_buffer != 0 && _windowSize == windowSize)
|
||||
return true;
|
||||
Free();
|
||||
_windowSize = windowSize;
|
||||
_buffer = (Byte *)::BigAlloc(windowSize);
|
||||
return (_buffer != 0);
|
||||
}
|
||||
|
||||
void CLZOutWindow::Free()
|
||||
{
|
||||
::BigFree(_buffer);
|
||||
_buffer = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
void CLZOutWindow::Init(ISequentialOutStream *stream, bool solid)
|
||||
{
|
||||
|
@ -44,6 +37,9 @@ void CLZOutWindow::Init(ISequentialOutStream *stream, bool solid)
|
|||
_streamPos = 0;
|
||||
_pos = 0;
|
||||
}
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
ErrorCode = S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -61,16 +57,25 @@ void CLZOutWindow::ReleaseStream()
|
|||
void CLZOutWindow::FlushWithCheck()
|
||||
{
|
||||
HRESULT result = Flush();
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
ErrorCode = result;
|
||||
#else
|
||||
if (result != S_OK)
|
||||
throw CLZOutWindowException(result);
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CLZOutWindow::Flush()
|
||||
{
|
||||
UINT32 size = _pos - _streamPos;
|
||||
UInt32 size = _pos - _streamPos;
|
||||
if(size == 0)
|
||||
return S_OK;
|
||||
UINT32 processedSize;
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
if (ErrorCode != S_OK)
|
||||
return ErrorCode;
|
||||
#endif
|
||||
|
||||
UInt32 processedSize;
|
||||
HRESULT result = _stream->Write(_buffer + _streamPos, size, &processedSize);
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
|
|
|
@ -1,78 +1,71 @@
|
|||
// LZOutWindow.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __LZ_OUT_WINDOW_H
|
||||
#define __LZ_OUT_WINDOW_H
|
||||
|
||||
#include "../../IStream.h"
|
||||
|
||||
// m_KeepSizeBefore: how mach BYTEs must be in buffer before _pos;
|
||||
// m_KeepSizeAfter: how mach BYTEs must be in buffer after _pos;
|
||||
// m_KeepSizeReserv: how mach BYTEs must be in buffer for Moving Reserv;
|
||||
// must be >= aKeepSizeAfter; // test it
|
||||
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
class CLZOutWindowException
|
||||
{
|
||||
public:
|
||||
HRESULT ErrorCode;
|
||||
CLZOutWindowException(HRESULT errorCode): ErrorCode(errorCode) {}
|
||||
};
|
||||
#endif
|
||||
|
||||
class CLZOutWindow
|
||||
{
|
||||
BYTE *_buffer;
|
||||
UINT32 _pos;
|
||||
UINT32 _windowSize;
|
||||
UINT32 _streamPos;
|
||||
Byte *_buffer;
|
||||
UInt32 _pos;
|
||||
UInt32 _windowSize;
|
||||
UInt32 _streamPos;
|
||||
ISequentialOutStream *_stream;
|
||||
void FlushWithCheck();
|
||||
|
||||
public:
|
||||
CLZOutWindow(): _buffer(0), _stream(0) {}
|
||||
~CLZOutWindow();
|
||||
void Create(UINT32 windowSize);
|
||||
bool IsCreated() const { return _buffer != 0; }
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
HRESULT ErrorCode;
|
||||
#endif
|
||||
|
||||
void Free();
|
||||
CLZOutWindow(): _buffer(0), _stream(0) {}
|
||||
~CLZOutWindow() { Free(); /* ReleaseStream(); */ }
|
||||
bool Create(UInt32 windowSize);
|
||||
|
||||
void Init(ISequentialOutStream *stream, bool solid = false);
|
||||
HRESULT Flush();
|
||||
// void ReleaseStream();
|
||||
|
||||
// UINT32 GetCurPos() const { return _pos; }
|
||||
// const BYTE *GetPointerToCurrentPos() const { return _buffer + _pos;};
|
||||
|
||||
void CopyBackBlock(UINT32 distance, UINT32 len)
|
||||
void CopyBlock(UInt32 distance, UInt32 len)
|
||||
{
|
||||
UINT32 pos = _pos - distance - 1;
|
||||
if (pos >= _windowSize)
|
||||
pos += _windowSize;
|
||||
for(; len > 0; len--)
|
||||
{
|
||||
if (pos >= _windowSize)
|
||||
pos = 0;
|
||||
_buffer[_pos++] = _buffer[pos++];
|
||||
if (_pos >= _windowSize)
|
||||
FlushWithCheck();
|
||||
// PutOneByte(GetOneByte(0 - distance));
|
||||
}
|
||||
UInt32 pos = _pos - distance - 1;
|
||||
if (pos >= _windowSize)
|
||||
pos += _windowSize;
|
||||
for(; len > 0; len--)
|
||||
{
|
||||
if (pos >= _windowSize)
|
||||
pos = 0;
|
||||
_buffer[_pos++] = _buffer[pos++];
|
||||
if (_pos >= _windowSize)
|
||||
FlushWithCheck();
|
||||
// PutOneByte(GetOneByte(distance));
|
||||
}
|
||||
}
|
||||
|
||||
void PutOneByte(BYTE b)
|
||||
|
||||
void PutByte(Byte b)
|
||||
{
|
||||
_buffer[_pos++] = b;
|
||||
if (_pos >= _windowSize)
|
||||
FlushWithCheck();
|
||||
_buffer[_pos++] = b;
|
||||
if (_pos >= _windowSize)
|
||||
FlushWithCheck();
|
||||
}
|
||||
|
||||
BYTE GetOneByte(UINT32 index) const
|
||||
|
||||
Byte GetByte(UInt32 distance) const
|
||||
{
|
||||
UINT32 pos = _pos + index;
|
||||
if (pos >= _windowSize)
|
||||
pos += _windowSize;
|
||||
return _buffer[pos];
|
||||
UInt32 pos = _pos - distance - 1;
|
||||
if (pos >= _windowSize)
|
||||
pos += _windowSize;
|
||||
return _buffer[pos];
|
||||
}
|
||||
|
||||
// BYTE *GetBuffer() const { return _buffer; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include "../../../../Platform.h"
|
||||
#endif
|
||||
#include "../../../../Platform.h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,55 +1,29 @@
|
|||
// LZMA.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#include "LZMALen.h"
|
||||
|
||||
#ifndef __LZMA_H
|
||||
#define __LZMA_H
|
||||
|
||||
namespace NCompress {
|
||||
namespace NLZMA {
|
||||
|
||||
const UINT32 kNumRepDistances = 4;
|
||||
const UInt32 kNumRepDistances = 4;
|
||||
|
||||
const BYTE kNumStates = 12;
|
||||
const int kNumStates = 12;
|
||||
|
||||
const BYTE kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
|
||||
const BYTE kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
|
||||
const BYTE kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
|
||||
const BYTE kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
|
||||
const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
|
||||
const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
|
||||
const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
|
||||
const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
|
||||
|
||||
class CState
|
||||
{
|
||||
public:
|
||||
BYTE Index;
|
||||
void Init()
|
||||
{ Index = 0; }
|
||||
void UpdateChar()
|
||||
{ Index = kLiteralNextStates[Index]; }
|
||||
void UpdateMatch()
|
||||
{ Index = kMatchNextStates[Index]; }
|
||||
void UpdateRep()
|
||||
{ Index = kRepNextStates[Index]; }
|
||||
void UpdateShortRep()
|
||||
{ Index = kShortRepNextStates[Index]; }
|
||||
};
|
||||
|
||||
class CBaseCoder
|
||||
{
|
||||
protected:
|
||||
CState _state;
|
||||
BYTE _previousByte;
|
||||
bool _peviousIsMatch;
|
||||
UINT32 _repDistances[kNumRepDistances];
|
||||
void Init()
|
||||
{
|
||||
_state.Init();
|
||||
_previousByte = 0;
|
||||
_peviousIsMatch = false;
|
||||
for(unsigned int i = 0 ; i < kNumRepDistances; i++)
|
||||
_repDistances[i] = 0;
|
||||
}
|
||||
Byte Index;
|
||||
void Init() { Index = 0; }
|
||||
void UpdateChar() { Index = kLiteralNextStates[Index]; }
|
||||
void UpdateMatch() { Index = kMatchNextStates[Index]; }
|
||||
void UpdateRep() { Index = kRepNextStates[Index]; }
|
||||
void UpdateShortRep() { Index = kShortRepNextStates[Index]; }
|
||||
};
|
||||
|
||||
const int kNumPosSlotBits = 6;
|
||||
|
@ -57,8 +31,9 @@ const int kDicLogSizeMin = 0;
|
|||
const int kDicLogSizeMax = 32;
|
||||
const int kDistTableSizeMax = kDicLogSizeMax * 2;
|
||||
|
||||
const UINT32 kNumLenToPosStates = 4;
|
||||
inline UINT32 GetLenToPosState(UINT32 len)
|
||||
const UInt32 kNumLenToPosStates = 4;
|
||||
|
||||
inline UInt32 GetLenToPosState(UInt32 len)
|
||||
{
|
||||
len -= 2;
|
||||
if (len < kNumLenToPosStates)
|
||||
|
@ -66,31 +41,41 @@ inline UINT32 GetLenToPosState(UINT32 len)
|
|||
return kNumLenToPosStates - 1;
|
||||
}
|
||||
|
||||
const UINT32 kMatchMinLen = 2;
|
||||
namespace NLength {
|
||||
|
||||
const UINT32 kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1;
|
||||
const int kNumPosStatesBitsMax = 4;
|
||||
const UInt32 kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
|
||||
|
||||
const int kNumPosStatesBitsEncodingMax = 4;
|
||||
const UInt32 kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
|
||||
|
||||
const int kNumLowBits = 3;
|
||||
const int kNumMidBits = 3;
|
||||
const int kNumHighBits = 8;
|
||||
const UInt32 kNumLowSymbols = 1 << kNumLowBits;
|
||||
const UInt32 kNumMidSymbols = 1 << kNumMidBits;
|
||||
const UInt32 kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits);
|
||||
|
||||
}
|
||||
|
||||
const UInt32 kMatchMinLen = 2;
|
||||
const UInt32 kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1;
|
||||
|
||||
const int kNumAlignBits = 4;
|
||||
const UINT32 kAlignTableSize = 1 << kNumAlignBits;
|
||||
const UINT32 kAlignMask = (kAlignTableSize - 1);
|
||||
const UInt32 kAlignTableSize = 1 << kNumAlignBits;
|
||||
const UInt32 kAlignMask = (kAlignTableSize - 1);
|
||||
|
||||
const UINT32 kStartPosModelIndex = 4;
|
||||
const UINT32 kEndPosModelIndex = 14;
|
||||
const UINT32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
|
||||
const UInt32 kStartPosModelIndex = 4;
|
||||
const UInt32 kEndPosModelIndex = 14;
|
||||
const UInt32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
|
||||
|
||||
const UINT32 kNumFullDistances = 1 << (kEndPosModelIndex / 2);
|
||||
|
||||
const UINT32 kMainChoiceLiteralIndex = 0;
|
||||
const UINT32 kMainChoiceMatchIndex = 1;
|
||||
|
||||
const UINT32 kMatchChoiceDistanceIndex= 0;
|
||||
const UINT32 kMatchChoiceRepetitionIndex = 1;
|
||||
|
||||
const int kNumMoveBits = 5;
|
||||
const UInt32 kNumFullDistances = 1 << (kEndPosModelIndex / 2);
|
||||
|
||||
const int kNumLitPosStatesBitsEncodingMax = 4;
|
||||
const int kNumLitContextBitsMax = 8;
|
||||
|
||||
const int kNumMoveBits = 5;
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}}
|
|
@ -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
|
@ -1,26 +1,36 @@
|
|||
// LZMA/Encoder.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __LZMA_ENCODER_H
|
||||
#define __LZMA_ENCODER_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../../Common/Alloc.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../LZ/IMatchFinder.h"
|
||||
#include "../RangeCoder/RangeCoderBitTree.h"
|
||||
|
||||
#include "LZMA.h"
|
||||
#include "LZMALen.h"
|
||||
#include "LZMALiteral.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NLZMA {
|
||||
|
||||
class CMatchFinderException
|
||||
typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder;
|
||||
|
||||
class CBaseState
|
||||
{
|
||||
public:
|
||||
HRESULT ErrorCode;
|
||||
CMatchFinderException(HRESULT errorCode): ErrorCode(errorCode) {}
|
||||
protected:
|
||||
CState _state;
|
||||
Byte _previousByte;
|
||||
bool _peviousIsMatch;
|
||||
UInt32 _repDistances[kNumRepDistances];
|
||||
void Init()
|
||||
{
|
||||
_state.Init();
|
||||
_previousByte = 0;
|
||||
_peviousIsMatch = false;
|
||||
for(UInt32 i = 0 ; i < kNumRepDistances; i++)
|
||||
_repDistances[i] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct COptimal
|
||||
|
@ -30,21 +40,21 @@ struct COptimal
|
|||
bool Prev1IsChar;
|
||||
bool Prev2;
|
||||
|
||||
UINT32 PosPrev2;
|
||||
UINT32 BackPrev2;
|
||||
UInt32 PosPrev2;
|
||||
UInt32 BackPrev2;
|
||||
|
||||
UINT32 Price;
|
||||
UINT32 PosPrev; // posNext;
|
||||
UINT32 BackPrev;
|
||||
UINT32 Backs[kNumRepDistances];
|
||||
void MakeAsChar() { BackPrev = UINT32(-1); Prev1IsChar = false; }
|
||||
UInt32 Price;
|
||||
UInt32 PosPrev; // posNext;
|
||||
UInt32 BackPrev;
|
||||
UInt32 Backs[kNumRepDistances];
|
||||
void MakeAsChar() { BackPrev = UInt32(-1); Prev1IsChar = false; }
|
||||
void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
|
||||
bool IsShortRep() { return (BackPrev == 0); }
|
||||
};
|
||||
|
||||
|
||||
extern BYTE g_FastPos[1024];
|
||||
inline UINT32 GetPosSlot(UINT32 pos)
|
||||
extern Byte g_FastPos[1024];
|
||||
inline UInt32 GetPosSlot(UInt32 pos)
|
||||
{
|
||||
if (pos < (1 << 10))
|
||||
return g_FastPos[pos];
|
||||
|
@ -53,7 +63,7 @@ inline UINT32 GetPosSlot(UINT32 pos)
|
|||
return g_FastPos[pos >> 18] + 36;
|
||||
}
|
||||
|
||||
inline UINT32 GetPosSlot2(UINT32 pos)
|
||||
inline UInt32 GetPosSlot2(UInt32 pos)
|
||||
{
|
||||
if (pos < (1 << 16))
|
||||
return g_FastPos[pos >> 6] + 12;
|
||||
|
@ -62,79 +72,190 @@ inline UINT32 GetPosSlot2(UINT32 pos)
|
|||
return g_FastPos[pos >> 24] + 48;
|
||||
}
|
||||
|
||||
const UINT32 kIfinityPrice = 0xFFFFFFF;
|
||||
const UInt32 kIfinityPrice = 0xFFFFFFF;
|
||||
|
||||
typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder;
|
||||
const UInt32 kNumOpts = 1 << 12;
|
||||
|
||||
|
||||
class CLiteralEncoder2
|
||||
{
|
||||
CMyBitEncoder _encoders[0x300];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for (int i = 0; i < 0x300; i++)
|
||||
_encoders[i].Init();
|
||||
}
|
||||
void Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol);
|
||||
void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, Byte matchByte, Byte symbol);
|
||||
UInt32 GetPrice(bool matchMode, Byte matchByte, Byte symbol) const;
|
||||
};
|
||||
|
||||
class CLiteralEncoder
|
||||
{
|
||||
CLiteralEncoder2 *_coders;
|
||||
int _numPrevBits;
|
||||
int _numPosBits;
|
||||
UInt32 _posMask;
|
||||
public:
|
||||
CLiteralEncoder(): _coders(0) {}
|
||||
~CLiteralEncoder() { Free(); }
|
||||
void Free()
|
||||
{
|
||||
MyFree(_coders);
|
||||
_coders = 0;
|
||||
}
|
||||
bool Create(int numPosBits, int numPrevBits)
|
||||
{
|
||||
if (_coders == 0 || (numPosBits + numPrevBits) !=
|
||||
(_numPrevBits + _numPosBits) )
|
||||
{
|
||||
Free();
|
||||
UInt32 numStates = 1 << (numPosBits + numPrevBits);
|
||||
_coders = (CLiteralEncoder2 *)MyAlloc(numStates * sizeof(CLiteralEncoder2));
|
||||
}
|
||||
_numPosBits = numPosBits;
|
||||
_posMask = (1 << numPosBits) - 1;
|
||||
_numPrevBits = numPrevBits;
|
||||
return (_coders != 0);
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
|
||||
for (UInt32 i = 0; i < numStates; i++)
|
||||
_coders[i].Init();
|
||||
}
|
||||
UInt32 GetState(UInt32 pos, Byte prevByte) const
|
||||
{ return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }
|
||||
CLiteralEncoder2 *GetSubCoder(UInt32 pos, Byte prevByte)
|
||||
{ return &_coders[GetState(pos, prevByte)]; }
|
||||
/*
|
||||
void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 pos, Byte prevByte,
|
||||
Byte symbol)
|
||||
{ _coders[GetState(pos, prevByte)].Encode(rangeEncoder, symbol); }
|
||||
void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, UInt32 pos, Byte prevByte,
|
||||
Byte matchByte, Byte symbol)
|
||||
{ _coders[GetState(pos, prevByte)].Encode(rangeEncoder,
|
||||
matchByte, symbol); }
|
||||
*/
|
||||
UInt32 GetPrice(UInt32 pos, Byte prevByte, bool matchMode, Byte matchByte, Byte symbol) const
|
||||
{ return _coders[GetState(pos, prevByte)].GetPrice(matchMode, matchByte, symbol); }
|
||||
};
|
||||
|
||||
namespace NLength {
|
||||
|
||||
class CEncoder
|
||||
{
|
||||
CMyBitEncoder _choice;
|
||||
NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesEncodingMax];
|
||||
CMyBitEncoder _choice2;
|
||||
NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesEncodingMax];
|
||||
NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumHighBits> _highCoder;
|
||||
public:
|
||||
void Init(UInt32 numPosStates);
|
||||
void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState);
|
||||
UInt32 GetPrice(UInt32 symbol, UInt32 posState) const;
|
||||
};
|
||||
|
||||
const UInt32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols;
|
||||
|
||||
class CPriceTableEncoder: public CEncoder
|
||||
{
|
||||
UInt32 _prices[kNumSymbolsTotal][kNumPosStatesEncodingMax];
|
||||
UInt32 _tableSize;
|
||||
UInt32 _counters[kNumPosStatesEncodingMax];
|
||||
public:
|
||||
void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; }
|
||||
UInt32 GetPrice(UInt32 symbol, UInt32 posState) const
|
||||
{ return _prices[symbol][posState]; }
|
||||
void UpdateTable(UInt32 posState)
|
||||
{
|
||||
for (UInt32 len = 0; len < _tableSize; len++)
|
||||
_prices[len][posState] = CEncoder::GetPrice(len, posState);
|
||||
_counters[posState] = _tableSize;
|
||||
}
|
||||
void UpdateTables(UInt32 numPosStates)
|
||||
{
|
||||
for (UInt32 posState = 0; posState < numPosStates; posState++)
|
||||
UpdateTable(posState);
|
||||
}
|
||||
void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState)
|
||||
{
|
||||
CEncoder::Encode(rangeEncoder, symbol, posState);
|
||||
if (--_counters[posState] == 0)
|
||||
UpdateTable(posState);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
const UINT32 kNumOpts = 1 << 12;
|
||||
|
||||
class CEncoder :
|
||||
public ICompressCoder,
|
||||
// public IInitMatchFinder,
|
||||
public ICompressSetCoderProperties,
|
||||
public ICompressWriteCoderProperties,
|
||||
public CBaseCoder,
|
||||
public CBaseState,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
COptimal _optimum[kNumOpts];
|
||||
public:
|
||||
CMyComPtr<IMatchFinder> _matchFinder; // test it
|
||||
NRangeCoder::CEncoder _rangeEncoder;
|
||||
public:
|
||||
private:
|
||||
|
||||
CMyBitEncoder _mainChoiceEncoders[kNumStates][NLength::kNumPosStatesEncodingMax];
|
||||
CMyBitEncoder _matchChoiceEncoders[kNumStates];
|
||||
CMyBitEncoder _matchRepChoiceEncoders[kNumStates];
|
||||
CMyBitEncoder _matchRep1ChoiceEncoders[kNumStates];
|
||||
CMyBitEncoder _matchRep2ChoiceEncoders[kNumStates];
|
||||
CMyBitEncoder _matchRepShortChoiceEncoders[kNumStates][NLength::kNumPosStatesEncodingMax];
|
||||
CMyBitEncoder _isMatch[kNumStates][NLength::kNumPosStatesEncodingMax];
|
||||
CMyBitEncoder _isRep[kNumStates];
|
||||
CMyBitEncoder _isRepG0[kNumStates];
|
||||
CMyBitEncoder _isRepG1[kNumStates];
|
||||
CMyBitEncoder _isRepG2[kNumStates];
|
||||
CMyBitEncoder _isRep0Long[kNumStates][NLength::kNumPosStatesEncodingMax];
|
||||
|
||||
NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> _posSlotEncoder[kNumLenToPosStates];
|
||||
|
||||
NRangeCoder::CReverseBitTreeEncoder2<kNumMoveBits> _posEncoders[kNumPosModels];
|
||||
NRangeCoder::CReverseBitTreeEncoder2<kNumMoveBits> _posAlignEncoder;
|
||||
CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex];
|
||||
NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumAlignBits> _posAlignEncoder;
|
||||
|
||||
NLength::CPriceTableEncoder _lenEncoder;
|
||||
NLength::CPriceTableEncoder _repMatchLenEncoder;
|
||||
|
||||
NLiteral::CEncoder _literalEncoder;
|
||||
CLiteralEncoder _literalEncoder;
|
||||
|
||||
UINT32 _matchDistances[kMatchMaxLen + 1];
|
||||
UInt32 _matchDistances[kMatchMaxLen + 1];
|
||||
|
||||
bool _fastMode;
|
||||
bool _maxMode;
|
||||
UInt32 _numFastBytes;
|
||||
UInt32 _longestMatchLength;
|
||||
|
||||
UINT32 _numFastBytes;
|
||||
UINT32 _numFastBytesPrev;
|
||||
UInt32 _additionalOffset;
|
||||
|
||||
UINT32 _longestMatchLength;
|
||||
|
||||
UINT32 _additionalOffset;
|
||||
|
||||
UINT32 _optimumEndIndex;
|
||||
UINT32 _optimumCurrentIndex;
|
||||
UInt32 _optimumEndIndex;
|
||||
UInt32 _optimumCurrentIndex;
|
||||
|
||||
bool _longestMatchWasFound;
|
||||
|
||||
UINT32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
|
||||
UInt32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
|
||||
|
||||
UINT32 _distancesPrices[kNumLenToPosStates][kNumFullDistances];
|
||||
UInt32 _distancesPrices[kNumLenToPosStates][kNumFullDistances];
|
||||
|
||||
UINT32 _alignPrices[kAlignTableSize];
|
||||
UINT32 _alignPriceCount;
|
||||
UInt32 _alignPrices[kAlignTableSize];
|
||||
UInt32 _alignPriceCount;
|
||||
|
||||
UINT32 _dictionarySize;
|
||||
UINT32 _dictionarySizePrev;
|
||||
UInt32 _distTableSize;
|
||||
|
||||
UINT32 _distTableSize;
|
||||
UInt32 _posStateBits;
|
||||
UInt32 _posStateMask;
|
||||
UInt32 _numLiteralPosStateBits;
|
||||
UInt32 _numLiteralContextBits;
|
||||
|
||||
UINT32 _posStateBits;
|
||||
UINT32 _posStateMask;
|
||||
UINT32 _numLiteralPosStateBits;
|
||||
UINT32 _numLiteralContextBits;
|
||||
UInt32 _dictionarySize;
|
||||
|
||||
UINT64 lastPosSlotFillingPos;
|
||||
UINT64 nowPos64;
|
||||
UInt32 _dictionarySizePrev;
|
||||
UInt32 _numFastBytesPrev;
|
||||
|
||||
UInt64 lastPosSlotFillingPos;
|
||||
UInt64 nowPos64;
|
||||
bool _finished;
|
||||
ISequentialInStream *_inStream;
|
||||
|
||||
|
@ -144,58 +265,49 @@ private:
|
|||
#endif
|
||||
|
||||
bool _writeEndMark;
|
||||
|
||||
UINT32 ReadMatchDistances()
|
||||
{
|
||||
UINT32 len = _matchFinder->GetLongestMatch(_matchDistances);
|
||||
if (len == _numFastBytes)
|
||||
len += _matchFinder->GetMatchLen(len, _matchDistances[len],
|
||||
kMatchMaxLen - len);
|
||||
_additionalOffset++;
|
||||
HRESULT result = _matchFinder->MovePos();
|
||||
if (result != S_OK)
|
||||
throw CMatchFinderException(result);
|
||||
return len;
|
||||
}
|
||||
|
||||
void MovePos(UINT32 num);
|
||||
UINT32 GetRepLen1Price(CState state, UINT32 posState) const
|
||||
bool _needReleaseMFStream;
|
||||
|
||||
HRESULT ReadMatchDistances(UInt32 &len);
|
||||
|
||||
HRESULT MovePos(UInt32 num);
|
||||
UInt32 GetRepLen1Price(CState state, UInt32 posState) const
|
||||
{
|
||||
return _matchRepChoiceEncoders[state.Index].GetPrice(0) +
|
||||
_matchRepShortChoiceEncoders[state.Index][posState].GetPrice(0);
|
||||
return _isRepG0[state.Index].GetPrice(0) +
|
||||
_isRep0Long[state.Index][posState].GetPrice(0);
|
||||
}
|
||||
UINT32 GetRepPrice(UINT32 repIndex, UINT32 len, CState state, UINT32 posState) const
|
||||
UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, CState state, UInt32 posState) const
|
||||
{
|
||||
UINT32 price = _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState);
|
||||
UInt32 price = _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState);
|
||||
if(repIndex == 0)
|
||||
{
|
||||
price += _matchRepChoiceEncoders[state.Index].GetPrice(0);
|
||||
price += _matchRepShortChoiceEncoders[state.Index][posState].GetPrice(1);
|
||||
price += _isRepG0[state.Index].GetPrice(0);
|
||||
price += _isRep0Long[state.Index][posState].GetPrice(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
price += _matchRepChoiceEncoders[state.Index].GetPrice(1);
|
||||
price += _isRepG0[state.Index].GetPrice(1);
|
||||
if (repIndex == 1)
|
||||
price += _matchRep1ChoiceEncoders[state.Index].GetPrice(0);
|
||||
price += _isRepG1[state.Index].GetPrice(0);
|
||||
else
|
||||
{
|
||||
price += _matchRep1ChoiceEncoders[state.Index].GetPrice(1);
|
||||
price += _matchRep2ChoiceEncoders[state.Index].GetPrice(repIndex - 2);
|
||||
price += _isRepG1[state.Index].GetPrice(1);
|
||||
price += _isRepG2[state.Index].GetPrice(repIndex - 2);
|
||||
}
|
||||
}
|
||||
return price;
|
||||
}
|
||||
/*
|
||||
UINT32 GetPosLen2Price(UINT32 pos, UINT32 posState) const
|
||||
UInt32 GetPosLen2Price(UInt32 pos, UInt32 posState) const
|
||||
{
|
||||
if (pos >= kNumFullDistances)
|
||||
return kIfinityPrice;
|
||||
return _distancesPrices[0][pos] + _lenEncoder.GetPrice(0, posState);
|
||||
}
|
||||
UINT32 GetPosLen3Price(UINT32 pos, UINT32 len, UINT32 posState) const
|
||||
UInt32 GetPosLen3Price(UInt32 pos, UInt32 len, UInt32 posState) const
|
||||
{
|
||||
UINT32 price;
|
||||
UINT32 lenToPosState = GetLenToPosState(len);
|
||||
UInt32 price;
|
||||
UInt32 lenToPosState = GetLenToPosState(len);
|
||||
if (pos < kNumFullDistances)
|
||||
price = _distancesPrices[lenToPosState][pos];
|
||||
else
|
||||
|
@ -204,12 +316,12 @@ private:
|
|||
return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
|
||||
}
|
||||
*/
|
||||
UINT32 GetPosLenPrice(UINT32 pos, UINT32 len, UINT32 posState) const
|
||||
UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) const
|
||||
{
|
||||
if (len == 2 && pos >= 0x80)
|
||||
return kIfinityPrice;
|
||||
UINT32 price;
|
||||
UINT32 lenToPosState = GetLenToPosState(len);
|
||||
UInt32 price;
|
||||
UInt32 lenToPosState = GetLenToPosState(len);
|
||||
if (pos < kNumFullDistances)
|
||||
price = _distancesPrices[lenToPosState][pos];
|
||||
else
|
||||
|
@ -218,9 +330,9 @@ private:
|
|||
return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
|
||||
}
|
||||
|
||||
UINT32 Backward(UINT32 &backRes, UINT32 cur);
|
||||
UINT32 GetOptimum(UINT32 &backRes, UINT32 position);
|
||||
UINT32 GetOptimumFast(UINT32 &backRes, UINT32 position);
|
||||
UInt32 Backward(UInt32 &backRes, UInt32 cur);
|
||||
HRESULT GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes);
|
||||
HRESULT GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes);
|
||||
|
||||
void FillPosSlotPrices();
|
||||
void FillDistancesPrices();
|
||||
|
@ -228,7 +340,11 @@ private:
|
|||
|
||||
void ReleaseStreams()
|
||||
{
|
||||
_matchFinder->ReleaseStream();
|
||||
if (_matchFinder && _needReleaseMFStream)
|
||||
{
|
||||
_matchFinder->ReleaseStream();
|
||||
_needReleaseMFStream = false;
|
||||
}
|
||||
// _rangeEncoder.ReleaseStream();
|
||||
}
|
||||
|
||||
|
@ -245,21 +361,19 @@ private:
|
|||
};
|
||||
friend class CCoderReleaser;
|
||||
|
||||
void WriteEndMarker(UINT32 posState);
|
||||
void WriteEndMarker(UInt32 posState);
|
||||
|
||||
public:
|
||||
CEncoder();
|
||||
virtual ~CEncoder() {}
|
||||
void SetWriteEndMarkerMode(bool writeEndMarker)
|
||||
{ _writeEndMark= writeEndMarker; }
|
||||
|
||||
HRESULT Create();
|
||||
|
||||
/*MY_UNKNOWN_IMP2(
|
||||
MY_UNKNOWN_IMP2(
|
||||
ICompressSetCoderProperties,
|
||||
ICompressWriteCoderProperties
|
||||
)*/
|
||||
MY_UNKNOWN_IMP
|
||||
)
|
||||
|
||||
STDMETHOD(Init)(
|
||||
ISequentialOutStream *outStream);
|
||||
|
@ -267,18 +381,18 @@ public:
|
|||
// ICompressCoder interface
|
||||
HRESULT SetStreams(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize);
|
||||
HRESULT CodeOneBlock(UINT64 *inSize, UINT64 *outSize, INT32 *finished);
|
||||
const UInt64 *inSize, const UInt64 *outSize);
|
||||
HRESULT CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished);
|
||||
|
||||
HRESULT CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// ICompressCoder interface
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// IInitMatchFinder interface
|
||||
|
@ -286,10 +400,12 @@ public:
|
|||
|
||||
// ICompressSetCoderProperties2
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UINT32 numProperties);
|
||||
const PROPVARIANT *properties, UInt32 numProperties);
|
||||
|
||||
// ICompressWriteCoderProperties
|
||||
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
|
||||
|
||||
virtual ~CEncoder() {}
|
||||
};
|
||||
|
||||
}}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
};
|
||||
|
||||
}}}
|
|
@ -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
|
|
@ -1,12 +1,8 @@
|
|||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include "../../../../Platform.h"
|
||||
#endif
|
||||
#include "../../../../Platform.h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
// Compress/RangeCoder.h
|
||||
// This code is based on Eugene Shelwien's Rangecoder code
|
||||
|
||||
// #pragma once
|
||||
// Compress/RangeCoder/RangeCoder.h
|
||||
|
||||
#ifndef __COMPRESS_RANGECODER_H
|
||||
#define __COMPRESS_RANGECODER_H
|
||||
|
@ -12,23 +9,24 @@
|
|||
namespace NCompress {
|
||||
namespace NRangeCoder {
|
||||
|
||||
const UINT32 kNumTopBits = 24;
|
||||
const UINT32 kTopValue = (1 << kNumTopBits);
|
||||
const int kNumTopBits = 24;
|
||||
const UInt32 kTopValue = (1 << kNumTopBits);
|
||||
|
||||
class CEncoder
|
||||
{
|
||||
COutBuffer Stream;
|
||||
UINT64 Low;
|
||||
UINT32 Range;
|
||||
UINT32 _ffNum;
|
||||
BYTE _cache;
|
||||
|
||||
UInt64 Low;
|
||||
UInt32 Range;
|
||||
UInt32 _ffNum;
|
||||
Byte _cache;
|
||||
public:
|
||||
COutBuffer Stream;
|
||||
bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
|
||||
|
||||
void Init(ISequentialOutStream *stream)
|
||||
{
|
||||
Stream.Init(stream);
|
||||
Low = 0;
|
||||
Range = UINT32(-1);
|
||||
Range = 0xFFFFFFFF;
|
||||
_ffNum = 0;
|
||||
_cache = 0;
|
||||
}
|
||||
|
@ -40,15 +38,14 @@ public:
|
|||
ShiftLow();
|
||||
}
|
||||
|
||||
HRESULT FlushStream()
|
||||
{ return Stream.Flush(); }
|
||||
HRESULT FlushStream() { return Stream.Flush(); }
|
||||
|
||||
/*
|
||||
void ReleaseStream()
|
||||
{ Stream.ReleaseStream(); }
|
||||
*/
|
||||
|
||||
void Encode(UINT32 start, UINT32 size, UINT32 total)
|
||||
void Encode(UInt32 start, UInt32 size, UInt32 total)
|
||||
{
|
||||
Low += start * (Range /= total);
|
||||
Range *= size;
|
||||
|
@ -60,13 +57,13 @@ public:
|
|||
}
|
||||
|
||||
/*
|
||||
void EncodeDirectBitsDiv(UINT32 value, UINT32 numTotalBits)
|
||||
void EncodeDirectBitsDiv(UInt32 value, UInt32 numTotalBits)
|
||||
{
|
||||
Low += value * (Range >>= numTotalBits);
|
||||
Normalize();
|
||||
}
|
||||
|
||||
void EncodeDirectBitsDiv2(UINT32 value, UINT32 numTotalBits)
|
||||
void EncodeDirectBitsDiv2(UInt32 value, UInt32 numTotalBits)
|
||||
{
|
||||
if (numTotalBits <= kNumBottomBits)
|
||||
EncodeDirectBitsDiv(value, numTotalBits);
|
||||
|
@ -79,19 +76,19 @@ public:
|
|||
*/
|
||||
void ShiftLow()
|
||||
{
|
||||
if (Low < (UINT32)0xFF000000 || UINT32(Low >> 32) == 1)
|
||||
if (Low < (UInt32)0xFF000000 || UInt32(Low >> 32) == 1)
|
||||
{
|
||||
Stream.WriteByte(_cache + BYTE(Low >> 32));
|
||||
Stream.WriteByte(Byte(_cache + Byte(Low >> 32)));
|
||||
for (;_ffNum != 0; _ffNum--)
|
||||
Stream.WriteByte(0xFF + BYTE(Low >> 32));
|
||||
_cache = BYTE(UINT32(Low) >> 24);
|
||||
Stream.WriteByte(Byte(0xFF + Byte(Low >> 32)));
|
||||
_cache = Byte(UInt32(Low) >> 24);
|
||||
}
|
||||
else
|
||||
_ffNum++;
|
||||
Low = UINT32(Low) << 8;
|
||||
Low = UInt32(Low) << 8;
|
||||
}
|
||||
|
||||
void EncodeDirectBits(UINT32 value, UINT32 numTotalBits)
|
||||
void EncodeDirectBits(UInt32 value, int numTotalBits)
|
||||
{
|
||||
for (int i = numTotalBits - 1; i >= 0; i--)
|
||||
{
|
||||
|
@ -106,9 +103,9 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void EncodeBit(UINT32 size0, UINT32 numTotalBits, UINT32 symbol)
|
||||
void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
|
||||
{
|
||||
UINT32 newBound = (Range >> numTotalBits) * size0;
|
||||
UInt32 newBound = (Range >> numTotalBits) * size0;
|
||||
if (symbol == 0)
|
||||
Range = newBound;
|
||||
else
|
||||
|
@ -123,16 +120,17 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
UINT64 GetProcessedSize() { return Stream.GetProcessedSize() + _ffNum; }
|
||||
UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _ffNum; }
|
||||
};
|
||||
|
||||
class CDecoder
|
||||
{
|
||||
public:
|
||||
CInBuffer Stream;
|
||||
UINT32 Range;
|
||||
UINT32 Code;
|
||||
// UINT32 m_Word;
|
||||
UInt32 Range;
|
||||
UInt32 Code;
|
||||
bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
|
||||
|
||||
void Normalize()
|
||||
{
|
||||
while (Range < kTopValue)
|
||||
|
@ -146,19 +144,19 @@ public:
|
|||
{
|
||||
Stream.Init(stream);
|
||||
Code = 0;
|
||||
Range = UINT32(-1);
|
||||
Range = 0xFFFFFFFF;
|
||||
for(int i = 0; i < 5; i++)
|
||||
Code = (Code << 8) | Stream.ReadByte();
|
||||
}
|
||||
|
||||
// void ReleaseStream() { Stream.ReleaseStream(); }
|
||||
|
||||
UINT32 GetThreshold(UINT32 total)
|
||||
UInt32 GetThreshold(UInt32 total)
|
||||
{
|
||||
return (Code) / ( Range /= total);
|
||||
}
|
||||
|
||||
void Decode(UINT32 start, UINT32 size, UINT32 total)
|
||||
void Decode(UInt32 start, UInt32 size)
|
||||
{
|
||||
Code -= start * Range;
|
||||
Range *= size;
|
||||
|
@ -166,31 +164,31 @@ public:
|
|||
}
|
||||
|
||||
/*
|
||||
UINT32 DecodeDirectBitsDiv(UINT32 numTotalBits)
|
||||
UInt32 DecodeDirectBitsDiv(UInt32 numTotalBits)
|
||||
{
|
||||
Range >>= numTotalBits;
|
||||
UINT32 threshold = Code / Range;
|
||||
UInt32 threshold = Code / Range;
|
||||
Code -= threshold * Range;
|
||||
|
||||
Normalize();
|
||||
return threshold;
|
||||
}
|
||||
|
||||
UINT32 DecodeDirectBitsDiv2(UINT32 numTotalBits)
|
||||
UInt32 DecodeDirectBitsDiv2(UInt32 numTotalBits)
|
||||
{
|
||||
if (numTotalBits <= kNumBottomBits)
|
||||
return DecodeDirectBitsDiv(numTotalBits);
|
||||
UINT32 result = DecodeDirectBitsDiv(numTotalBits - kNumBottomBits) << kNumBottomBits;
|
||||
UInt32 result = DecodeDirectBitsDiv(numTotalBits - kNumBottomBits) << kNumBottomBits;
|
||||
return (result | DecodeDirectBitsDiv(kNumBottomBits));
|
||||
}
|
||||
*/
|
||||
|
||||
UINT32 DecodeDirectBits(UINT32 numTotalBits)
|
||||
UInt32 DecodeDirectBits(UInt32 numTotalBits)
|
||||
{
|
||||
UINT32 range = Range;
|
||||
UINT32 code = Code;
|
||||
UINT32 result = 0;
|
||||
for (UINT32 i = numTotalBits; i > 0; i--)
|
||||
UInt32 range = Range;
|
||||
UInt32 code = Code;
|
||||
UInt32 result = 0;
|
||||
for (UInt32 i = numTotalBits; i > 0; i--)
|
||||
{
|
||||
range >>= 1;
|
||||
/*
|
||||
|
@ -201,7 +199,7 @@ public:
|
|||
result |= 1;
|
||||
}
|
||||
*/
|
||||
UINT32 t = (code - range) >> 31;
|
||||
UInt32 t = (code - range) >> 31;
|
||||
code -= range & (t - 1);
|
||||
// range = rangeTmp + ((range & 1) & (1 - t));
|
||||
result = (result << 1) | (1 - t);
|
||||
|
@ -217,10 +215,10 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
UINT32 DecodeBit(UINT32 size0, UINT32 numTotalBits)
|
||||
UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
|
||||
{
|
||||
UINT32 newBound = (Range >> numTotalBits) * size0;
|
||||
UINT32 symbol;
|
||||
UInt32 newBound = (Range >> numTotalBits) * size0;
|
||||
UInt32 symbol;
|
||||
if (Code < newBound)
|
||||
{
|
||||
symbol = 0;
|
||||
|
@ -236,7 +234,7 @@ public:
|
|||
return symbol;
|
||||
}
|
||||
|
||||
UINT64 GetProcessedSize() {return Stream.GetProcessedSize(); }
|
||||
UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
|
||||
};
|
||||
|
||||
}}
|
||||
|
|
|
@ -7,12 +7,27 @@
|
|||
namespace NCompress {
|
||||
namespace NRangeCoder {
|
||||
|
||||
CPriceTables::CPriceTables()
|
||||
UInt32 CPriceTables::ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
|
||||
static CPriceTables g_PriceTables;
|
||||
|
||||
CPriceTables::CPriceTables() { Init(); }
|
||||
|
||||
void CPriceTables::Init()
|
||||
{
|
||||
const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
|
||||
for(int i = kNumBits - 1; i >= 0; i--)
|
||||
{
|
||||
UInt32 start = 1 << (kNumBits - i - 1);
|
||||
UInt32 end = 1 << (kNumBits - i);
|
||||
for (UInt32 j = start; j < end; j++)
|
||||
ProbPrices[j] = (i << kNumBitPriceShiftBits) +
|
||||
(((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
|
||||
}
|
||||
|
||||
/*
|
||||
// simplest: bad solution
|
||||
for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
||||
StatePrices[i] = kBitPrice;
|
||||
for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
||||
ProbPrices[i] = kBitPrice;
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -21,20 +36,20 @@ CPriceTables::CPriceTables()
|
|||
// float solution
|
||||
double ln2 = log(double(2));
|
||||
double lnAll = log(double(kBitModelTotal >> kNumMoveReducingBits));
|
||||
for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
||||
StatePrices[i] = UINT32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice);
|
||||
for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
||||
ProbPrices[i] = UInt32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice);
|
||||
*/
|
||||
|
||||
/*
|
||||
// experimental, slow, solution:
|
||||
for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
||||
for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
||||
{
|
||||
const int kCyclesBits = 5;
|
||||
const UINT32 kCycles = (1 << kCyclesBits);
|
||||
const UInt32 kCycles = (1 << kCyclesBits);
|
||||
|
||||
UINT32 range = UINT32(-1);
|
||||
UINT32 bitCount = 0;
|
||||
for (UINT32 j = 0; j < kCycles; j++)
|
||||
UInt32 range = UInt32(-1);
|
||||
UInt32 bitCount = 0;
|
||||
for (UInt32 j = 0; j < kCycles; j++)
|
||||
{
|
||||
range >>= (kNumBitModelTotalBits - kNumMoveReducingBits);
|
||||
range *= i;
|
||||
|
@ -55,23 +70,11 @@ CPriceTables::CPriceTables()
|
|||
range -= (1 << 31);
|
||||
}
|
||||
}
|
||||
StatePrices[i] = (bitCount
|
||||
ProbPrices[i] = (bitCount
|
||||
// + (1 << (kCyclesBits - 1))
|
||||
) >> kCyclesBits;
|
||||
}
|
||||
*/
|
||||
|
||||
const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
|
||||
for(int i = kNumBits - 1; i >= 0; i--)
|
||||
{
|
||||
UINT32 start = 1 << (kNumBits - i - 1);
|
||||
UINT32 end = 1 << (kNumBits - i);
|
||||
for (UINT32 j = start; j < end; j++)
|
||||
StatePrices[j] = (i << kNumBitPriceShiftBits) +
|
||||
(((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
|
||||
}
|
||||
}
|
||||
|
||||
CPriceTables g_PriceTables;
|
||||
|
||||
}}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
// Compress/RangeCoder/RangeCoderBit.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
|
||||
#define __COMPRESS_RANGECODER_BIT_TREE_H
|
||||
#ifndef __COMPRESS_RANGECODER_BIT_H
|
||||
#define __COMPRESS_RANGECODER_BIT_H
|
||||
|
||||
#include "RangeCoder.h"
|
||||
|
||||
|
@ -11,74 +9,88 @@ namespace NCompress {
|
|||
namespace NRangeCoder {
|
||||
|
||||
const int kNumBitModelTotalBits = 11;
|
||||
const UINT32 kBitModelTotal = (1 << kNumBitModelTotalBits);
|
||||
const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
|
||||
|
||||
const int kNumMoveReducingBits = 2;
|
||||
|
||||
const int kNumBitPriceShiftBits = 6;
|
||||
const UINT32 kBitPrice = 1 << kNumBitPriceShiftBits;
|
||||
const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
|
||||
|
||||
class CPriceTables
|
||||
{
|
||||
public:
|
||||
UINT32 StatePrices[kBitModelTotal >> kNumMoveReducingBits];
|
||||
static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
|
||||
static void Init();
|
||||
CPriceTables();
|
||||
};
|
||||
|
||||
extern CPriceTables g_PriceTables;
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CBitModel
|
||||
|
||||
template <int aNumMoveBits>
|
||||
template <int numMoveBits>
|
||||
class CBitModel
|
||||
{
|
||||
public:
|
||||
UINT32 Probability;
|
||||
void UpdateModel(UINT32 symbol)
|
||||
UInt32 Prob;
|
||||
void UpdateModel(UInt32 symbol)
|
||||
{
|
||||
/*
|
||||
Probability -= (Probability + ((symbol - 1) & ((1 << aNumMoveBits) - 1))) >> aNumMoveBits;
|
||||
Probability += (1 - symbol) << (kNumBitModelTotalBits - aNumMoveBits);
|
||||
Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
|
||||
Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
|
||||
*/
|
||||
if (symbol == 0)
|
||||
Probability += (kBitModelTotal - Probability) >> aNumMoveBits;
|
||||
Prob += (kBitModelTotal - Prob) >> numMoveBits;
|
||||
else
|
||||
Probability -= (Probability) >> aNumMoveBits;
|
||||
Prob -= (Prob) >> numMoveBits;
|
||||
}
|
||||
public:
|
||||
void Init() { Probability = kBitModelTotal / 2; }
|
||||
void Init() { Prob = kBitModelTotal / 2; }
|
||||
};
|
||||
|
||||
template <int aNumMoveBits>
|
||||
class CBitEncoder: public CBitModel<aNumMoveBits>
|
||||
template <int numMoveBits>
|
||||
class CBitEncoder: public CBitModel<numMoveBits>
|
||||
{
|
||||
public:
|
||||
void Encode(CEncoder *encoder, UINT32 symbol)
|
||||
void Encode(CEncoder *encoder, UInt32 symbol)
|
||||
{
|
||||
encoder->EncodeBit(Probability, kNumBitModelTotalBits, symbol);
|
||||
UpdateModel(symbol);
|
||||
encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
|
||||
this->UpdateModel(symbol);
|
||||
/*
|
||||
UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
|
||||
if (symbol == 0)
|
||||
{
|
||||
encoder->Range = newBound;
|
||||
this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
|
||||
}
|
||||
else
|
||||
{
|
||||
encoder->Low += newBound;
|
||||
encoder->Range -= newBound;
|
||||
this->Prob -= (this->Prob) >> numMoveBits;
|
||||
}
|
||||
while (encoder->Range < kTopValue)
|
||||
{
|
||||
encoder->Range <<= 8;
|
||||
encoder->ShiftLow();
|
||||
}
|
||||
*/
|
||||
}
|
||||
UINT32 GetPrice(UINT32 symbol) const
|
||||
UInt32 GetPrice(UInt32 symbol) const
|
||||
{
|
||||
return g_PriceTables.StatePrices[
|
||||
(((Probability - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
|
||||
return CPriceTables::ProbPrices[
|
||||
(((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <int aNumMoveBits>
|
||||
class CBitDecoder: public CBitModel<aNumMoveBits>
|
||||
template <int numMoveBits>
|
||||
class CBitDecoder: public CBitModel<numMoveBits>
|
||||
{
|
||||
public:
|
||||
UINT32 Decode(CDecoder *decoder)
|
||||
UInt32 Decode(CDecoder *decoder)
|
||||
{
|
||||
UINT32 newBound = (decoder->Range >> kNumBitModelTotalBits) * Probability;
|
||||
UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
|
||||
if (decoder->Code < newBound)
|
||||
{
|
||||
decoder->Range = newBound;
|
||||
Probability += (kBitModelTotal - Probability) >> aNumMoveBits;
|
||||
this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
|
||||
if (decoder->Range < kTopValue)
|
||||
{
|
||||
decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
|
||||
|
@ -90,7 +102,7 @@ public:
|
|||
{
|
||||
decoder->Range -= newBound;
|
||||
decoder->Code -= newBound;
|
||||
Probability -= (Probability) >> aNumMoveBits;
|
||||
this->Prob -= (this->Prob) >> numMoveBits;
|
||||
if (decoder->Range < kTopValue)
|
||||
{
|
||||
decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
|
||||
|
@ -103,5 +115,4 @@ public:
|
|||
|
||||
}}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
// Compress/RangeCoder/RangeCoderBitTree.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __COMPRESS_RANGECODER_BIT_H
|
||||
#define __COMPRESS_RANGECODER_BIT_H
|
||||
#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
|
||||
#define __COMPRESS_RANGECODER_BIT_TREE_H
|
||||
|
||||
#include "RangeCoderBit.h"
|
||||
#include "RangeCoderOpt.h"
|
||||
|
@ -11,292 +9,154 @@
|
|||
namespace NCompress {
|
||||
namespace NRangeCoder {
|
||||
|
||||
/*
|
||||
template <int numMoveBits> class CMyBitEncoder:
|
||||
public NCompression::NArithmetic::CBitEncoder<numMoveBits> {};
|
||||
template <int numMoveBits> class CMyBitDecoder:
|
||||
public NCompression::NArithmetic::CBitDecoder<numMoveBits> {};
|
||||
*/
|
||||
|
||||
//////////////////////////
|
||||
// CBitTreeEncoder
|
||||
|
||||
template <int numMoveBits, UINT32 NumBitLevels>
|
||||
template <int numMoveBits, UInt32 NumBitLevels>
|
||||
class CBitTreeEncoder
|
||||
{
|
||||
CBitEncoder<numMoveBits> Models[1 << NumBitLevels];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(UINT32 i = 1; i < (1 << NumBitLevels); i++)
|
||||
for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
void Encode(CEncoder *rangeEncoder, UINT32 symbol)
|
||||
void Encode(CEncoder *rangeEncoder, UInt32 symbol)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
|
||||
UInt32 modelIndex = 1;
|
||||
for (UInt32 bitIndex = NumBitLevels; bitIndex > 0 ;)
|
||||
{
|
||||
bitIndex--;
|
||||
UINT32 bit = (symbol >> bitIndex ) & 1;
|
||||
UInt32 bit = (symbol >> bitIndex) & 1;
|
||||
Models[modelIndex].Encode(rangeEncoder, bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
}
|
||||
};
|
||||
UINT32 GetPrice(UINT32 symbol) const
|
||||
void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol)
|
||||
{
|
||||
UINT32 price = 0;
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
|
||||
UInt32 modelIndex = 1;
|
||||
for (UInt32 i = 0; i < NumBitLevels; i++)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
Models[modelIndex].Encode(rangeEncoder, bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
symbol >>= 1;
|
||||
}
|
||||
}
|
||||
UInt32 GetPrice(UInt32 symbol) const
|
||||
{
|
||||
UInt32 price = 0;
|
||||
UInt32 modelIndex = 1;
|
||||
for (UInt32 bitIndex = NumBitLevels; bitIndex > 0 ;)
|
||||
{
|
||||
bitIndex--;
|
||||
UINT32 bit = (symbol >> bitIndex ) & 1;
|
||||
UInt32 bit = (symbol >> bitIndex) & 1;
|
||||
price += Models[modelIndex].GetPrice(bit);
|
||||
modelIndex = (modelIndex << 1) + bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
UInt32 ReverseGetPrice(UInt32 symbol) const
|
||||
{
|
||||
UInt32 price = 0;
|
||||
UInt32 modelIndex = 1;
|
||||
for (UInt32 i = NumBitLevels; i > 0; i--)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
price += Models[modelIndex].GetPrice(bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////
|
||||
// CBitTreeDecoder
|
||||
|
||||
template <int numMoveBits, UINT32 NumBitLevels>
|
||||
template <int numMoveBits, UInt32 NumBitLevels>
|
||||
class CBitTreeDecoder
|
||||
{
|
||||
CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(UINT32 i = 1; i < (1 << NumBitLevels); i++)
|
||||
for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
UINT32 Decode(CDecoder *rangeDecoder)
|
||||
UInt32 Decode(CDecoder *rangeDecoder)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
UInt32 modelIndex = 1;
|
||||
RC_INIT_VAR
|
||||
for(UINT32 bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
|
||||
for(UInt32 bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
|
||||
{
|
||||
// modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
|
||||
RC_GETBIT(numMoveBits, Models[modelIndex].Probability, modelIndex)
|
||||
RC_GETBIT(numMoveBits, Models[modelIndex].Prob, modelIndex)
|
||||
}
|
||||
RC_FLUSH_VAR
|
||||
return modelIndex - (1 << NumBitLevels);
|
||||
};
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
// CReverseBitTreeEncoder
|
||||
|
||||
template <int numMoveBits>
|
||||
class CReverseBitTreeEncoder2
|
||||
{
|
||||
CBitEncoder<numMoveBits> *Models;
|
||||
UINT32 NumBitLevels;
|
||||
public:
|
||||
CReverseBitTreeEncoder2(): Models(0) { }
|
||||
~CReverseBitTreeEncoder2() { delete []Models; }
|
||||
void Create(UINT32 numBitLevels)
|
||||
UInt32 ReverseDecode(CDecoder *rangeDecoder)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new CBitEncoder<numMoveBits>[1 << numBitLevels];
|
||||
// return (Models != 0);
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
UINT32 numModels = 1 << NumBitLevels;
|
||||
for(UINT32 i = 1; i < numModels; i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
void Encode(CEncoder *rangeEncoder, UINT32 symbol)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 i = 0; i < NumBitLevels; i++)
|
||||
{
|
||||
UINT32 bit = symbol & 1;
|
||||
Models[modelIndex].Encode(rangeEncoder, bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
symbol >>= 1;
|
||||
}
|
||||
}
|
||||
UINT32 GetPrice(UINT32 symbol) const
|
||||
{
|
||||
UINT32 price = 0;
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 i = NumBitLevels; i > 0; i--)
|
||||
{
|
||||
UINT32 bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
price += Models[modelIndex].GetPrice(bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
template <int numMoveBits, int numBitLevels>
|
||||
class CReverseBitTreeEncoder: public CReverseBitTreeEncoder2<numMoveBits>
|
||||
{
|
||||
public:
|
||||
CReverseBitTreeEncoder()
|
||||
{ Create(numBitLevels); }
|
||||
};
|
||||
*/
|
||||
////////////////////////////////
|
||||
// CReverseBitTreeDecoder
|
||||
|
||||
template <int numMoveBits>
|
||||
class CReverseBitTreeDecoder2
|
||||
{
|
||||
CBitDecoder<numMoveBits> *Models;
|
||||
UINT32 NumBitLevels;
|
||||
public:
|
||||
CReverseBitTreeDecoder2(): Models(0) { }
|
||||
~CReverseBitTreeDecoder2() { delete []Models; }
|
||||
void Create(UINT32 numBitLevels)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new CBitDecoder<numMoveBits>[1 << numBitLevels];
|
||||
// return (Models != 0);
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
UINT32 numModels = 1 << NumBitLevels;
|
||||
for(UINT32 i = 1; i < numModels; i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
UINT32 Decode(CDecoder *rangeDecoder)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
UINT32 symbol = 0;
|
||||
UInt32 modelIndex = 1;
|
||||
UInt32 symbol = 0;
|
||||
RC_INIT_VAR
|
||||
for(UINT32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
for(UInt32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
{
|
||||
// UINT32 bit = Models[modelIndex].Decode(rangeDecoder);
|
||||
// UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
|
||||
// modelIndex <<= 1;
|
||||
// modelIndex += bit;
|
||||
// symbol |= (bit << bitIndex);
|
||||
RC_GETBIT2(numMoveBits, Models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << bitIndex))
|
||||
}
|
||||
RC_FLUSH_VAR
|
||||
return symbol;
|
||||
};
|
||||
};
|
||||
////////////////////////////
|
||||
// CReverseBitTreeDecoder2
|
||||
|
||||
template <int numMoveBits, UINT32 NumBitLevels>
|
||||
class CReverseBitTreeDecoder
|
||||
{
|
||||
CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(UINT32 i = 1; i < (1 << NumBitLevels); i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
UINT32 Decode(CDecoder *rangeDecoder)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
UINT32 symbol = 0;
|
||||
RC_INIT_VAR
|
||||
for(UINT32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
{
|
||||
// UINT32 bit = Models[modelIndex].Decode(rangeDecoder);
|
||||
// modelIndex <<= 1;
|
||||
// modelIndex += bit;
|
||||
// symbol |= (bit << bitIndex);
|
||||
RC_GETBIT2(numMoveBits, Models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << bitIndex))
|
||||
RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
|
||||
}
|
||||
RC_FLUSH_VAR
|
||||
return symbol;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
//////////////////////////
|
||||
// CBitTreeEncoder2
|
||||
template <int numMoveBits>
|
||||
void ReverseBitTreeEncode(CBitEncoder<numMoveBits> *Models,
|
||||
CEncoder *rangeEncoder, UInt32 NumBitLevels, UInt32 symbol)
|
||||
{
|
||||
UInt32 modelIndex = 1;
|
||||
for (UInt32 i = 0; i < NumBitLevels; i++)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
Models[modelIndex].Encode(rangeEncoder, bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
symbol >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
template <int numMoveBits>
|
||||
class CBitTreeEncoder2
|
||||
UInt32 ReverseBitTreeGetPrice(CBitEncoder<numMoveBits> *Models,
|
||||
UInt32 NumBitLevels, UInt32 symbol)
|
||||
{
|
||||
NCompression::NArithmetic::CBitEncoder<numMoveBits> *Models;
|
||||
UINT32 NumBitLevels;
|
||||
public:
|
||||
bool Create(UINT32 numBitLevels)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new NCompression::NArithmetic::CBitEncoder<numMoveBits>[1 << numBitLevels];
|
||||
return (Models != 0);
|
||||
}
|
||||
void Init()
|
||||
UInt32 price = 0;
|
||||
UInt32 modelIndex = 1;
|
||||
for (UInt32 i = NumBitLevels; i > 0; i--)
|
||||
{
|
||||
UINT32 numModels = 1 << NumBitLevels;
|
||||
for(UINT32 i = 1; i < numModels; i++)
|
||||
Models[i].Init();
|
||||
UInt32 bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
price += Models[modelIndex].GetPrice(bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
}
|
||||
void Encode(CMyRangeEncoder *rangeEncoder, UINT32 symbol)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
|
||||
{
|
||||
bitIndex--;
|
||||
UINT32 bit = (symbol >> bitIndex ) & 1;
|
||||
Models[modelIndex].Encode(rangeEncoder, bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
}
|
||||
}
|
||||
UINT32 GetPrice(UINT32 symbol) const
|
||||
{
|
||||
UINT32 price = 0;
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
|
||||
{
|
||||
bitIndex--;
|
||||
UINT32 bit = (symbol >> bitIndex ) & 1;
|
||||
price += Models[modelIndex].GetPrice(bit);
|
||||
modelIndex = (modelIndex << 1) + bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////
|
||||
// CBitTreeDecoder2
|
||||
return price;
|
||||
}
|
||||
|
||||
template <int numMoveBits>
|
||||
class CBitTreeDecoder2
|
||||
UInt32 ReverseBitTreeDecode(CBitDecoder<numMoveBits> *Models,
|
||||
CDecoder *rangeDecoder, UInt32 NumBitLevels)
|
||||
{
|
||||
NCompression::NArithmetic::CBitDecoder<numMoveBits> *Models;
|
||||
UINT32 NumBitLevels;
|
||||
public:
|
||||
bool Create(UINT32 numBitLevels)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new NCompression::NArithmetic::CBitDecoder<numMoveBits>[1 << numBitLevels];
|
||||
return (Models != 0);
|
||||
}
|
||||
void Init()
|
||||
UInt32 modelIndex = 1;
|
||||
UInt32 symbol = 0;
|
||||
RC_INIT_VAR
|
||||
for(UInt32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
{
|
||||
UINT32 numModels = 1 << NumBitLevels;
|
||||
for(UINT32 i = 1; i < numModels; i++)
|
||||
Models[i].Init();
|
||||
// UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
|
||||
// modelIndex <<= 1;
|
||||
// modelIndex += bit;
|
||||
// symbol |= (bit << bitIndex);
|
||||
RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
|
||||
}
|
||||
UINT32 Decode(CMyRangeDecoder *rangeDecoder)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
RC_INIT_VAR
|
||||
for(UINT32 bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
|
||||
{
|
||||
// modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
|
||||
RC_GETBIT(numMoveBits, Models[modelIndex].Probability, modelIndex)
|
||||
}
|
||||
RC_FLUSH_VAR
|
||||
return modelIndex - (1 << NumBitLevels);
|
||||
}
|
||||
};
|
||||
*/
|
||||
RC_FLUSH_VAR
|
||||
return symbol;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
|
|
@ -1,43 +1,31 @@
|
|||
// Compress/RangeCoder/RangeCoderOpt.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __COMPRESS_RANGECODER_OPT_H
|
||||
#define __COMPRESS_RANGECODER_OPT_H
|
||||
|
||||
#define RC_INIT_VAR \
|
||||
UINT32 range = rangeDecoder->Range; \
|
||||
UINT32 code = rangeDecoder->Code;
|
||||
#define RC_INIT_VAR \
|
||||
UInt32 range = rangeDecoder->Range; \
|
||||
UInt32 code = rangeDecoder->Code;
|
||||
|
||||
#define RC_FLUSH_VAR \
|
||||
rangeDecoder->Range = range; \
|
||||
#define RC_FLUSH_VAR \
|
||||
rangeDecoder->Range = range; \
|
||||
rangeDecoder->Code = code;
|
||||
|
||||
#define RC_NORMALIZE \
|
||||
if (range < NCompress::NRangeCoder::kTopValue) \
|
||||
{ \
|
||||
code = (code << 8) | rangeDecoder->Stream.ReadByte(); \
|
||||
range <<= 8; }
|
||||
#define RC_NORMALIZE \
|
||||
if (range < NCompress::NRangeCoder::kTopValue) \
|
||||
{ code = (code << 8) | rangeDecoder->Stream.ReadByte(); range <<= 8; }
|
||||
|
||||
#define RC_GETBIT2(numMoveBits, prob, modelIndex, Action0, Action1) \
|
||||
{UINT32 newBound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \
|
||||
if (code < newBound) \
|
||||
{ \
|
||||
Action0; \
|
||||
range = newBound; \
|
||||
prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \
|
||||
modelIndex <<= 1; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
Action1; \
|
||||
range -= newBound; \
|
||||
code -= newBound; \
|
||||
prob -= (prob) >> numMoveBits; \
|
||||
modelIndex = (modelIndex << 1) + 1; \
|
||||
}} \
|
||||
RC_NORMALIZE
|
||||
#define RC_GETBIT2(numMoveBits, prob, mi, A0, A1) \
|
||||
{ UInt32 bound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \
|
||||
if (code < bound) \
|
||||
{ A0; range = bound; \
|
||||
prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \
|
||||
mi <<= 1; } \
|
||||
else \
|
||||
{ A1; range -= bound; code -= bound; prob -= (prob) >> numMoveBits; \
|
||||
mi = (mi + mi) + 1; }} \
|
||||
RC_NORMALIZE
|
||||
|
||||
#define RC_GETBIT(numMoveBits, prob, modelIndex) RC_GETBIT2(numMoveBits, prob, modelIndex, ; , ;)
|
||||
#define RC_GETBIT(numMoveBits, prob, mi) RC_GETBIT2(numMoveBits, prob, mi, ; , ;)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include "../../../../Platform.h"
|
||||
#endif
|
||||
#include "../../../../Platform.h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// ICoder.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __ICODER_H
|
||||
#define __ICODER_H
|
||||
|
||||
|
@ -13,7 +11,7 @@ DEFINE_GUID(IID_ICompressProgressInfo,
|
|||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200040000")
|
||||
ICompressProgressInfo: public IUnknown
|
||||
{
|
||||
STDMETHOD(SetRatioInfo)(const UINT64 *inSize, const UINT64 *outSize) = 0;
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) = 0;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200050000}
|
||||
|
@ -24,8 +22,8 @@ ICompressCoder: public IUnknown
|
|||
{
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize,
|
||||
const UINT64 *outSize,
|
||||
const UInt64 *inSize,
|
||||
const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress) = 0;
|
||||
};
|
||||
|
||||
|
@ -36,11 +34,11 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000200180000")
|
|||
ICompressCoder2: public IUnknown
|
||||
{
|
||||
STDMETHOD(Code)(ISequentialInStream **inStreams,
|
||||
const UINT64 **inSizes,
|
||||
UINT32 numInStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UINT64 **outSizes,
|
||||
UINT32 numOutStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress) PURE;
|
||||
};
|
||||
|
||||
|
@ -58,7 +56,8 @@ namespace NCoderPropID
|
|||
kMatchFinder,
|
||||
kNumPasses = 0x460,
|
||||
kAlgorithm = 0x470,
|
||||
kMultiThread = 0x480
|
||||
kMultiThread = 0x480,
|
||||
kEndMarker = 0x490
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -69,7 +68,7 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000200200000")
|
|||
ICompressSetCoderProperties: public IUnknown
|
||||
{
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UINT32 numProperties) PURE;
|
||||
const PROPVARIANT *properties, UInt32 numProperties) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200210000}
|
||||
|
@ -78,7 +77,7 @@ DEFINE_GUID(IID_ICompressSetDecoderProperties,
|
|||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200210000")
|
||||
ICompressSetDecoderProperties: public IUnknown
|
||||
{
|
||||
STDMETHOD(SetDecoderProperties)(ISequentialInStream *anInStream) PURE;
|
||||
STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200230000}
|
||||
|
@ -96,7 +95,7 @@ DEFINE_GUID(IID_ICompressGetInStreamProcessedSize,
|
|||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200240000")
|
||||
ICompressGetInStreamProcessedSize: public IUnknown
|
||||
{
|
||||
STDMETHOD(GetInStreamProcessedSize)(UINT64 *value) PURE;
|
||||
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200250000}
|
||||
|
@ -105,7 +104,25 @@ DEFINE_GUID(IID_ICompressGetSubStreamSize,
|
|||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200250000")
|
||||
ICompressGetSubStreamSize: public IUnknown
|
||||
{
|
||||
STDMETHOD(GetSubStreamSize)(UINT64 subStream, UINT64 *value) PURE;
|
||||
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200260000}
|
||||
DEFINE_GUID(IID_ICompressSetInStream,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x26, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200260000")
|
||||
ICompressSetInStream: public IUnknown
|
||||
{
|
||||
STDMETHOD(SetInStream)(ISequentialInStream *inStream, const UInt64 *inSize) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200270000}
|
||||
DEFINE_GUID(IID_ICompressSetOutStream,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200270000")
|
||||
ICompressSetOutStream: public IUnknown
|
||||
{
|
||||
STDMETHOD(SetOutStream)(ISequentialOutStream *outStream, const UInt64 *outSize) PURE;
|
||||
};
|
||||
|
||||
//////////////////////
|
||||
|
@ -120,7 +137,7 @@ namespace NMethodPropID
|
|||
kEncoder,
|
||||
kInStreams,
|
||||
kOutStreams,
|
||||
kDescription,
|
||||
kDescription
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -1,11 +1,10 @@
|
|||
// IStream.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __ISTREAMS_H
|
||||
#define __ISTREAMS_H
|
||||
|
||||
#include "IMyUnknown.h"
|
||||
#include "../Common/MyUnknown.h"
|
||||
#include "../Common/Types.h"
|
||||
|
||||
// {23170F69-40C1-278A-0000-000000010000}
|
||||
DEFINE_GUID(IID_ISequentialInStream,
|
||||
|
@ -14,9 +13,15 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000010000")
|
|||
ISequentialInStream : public IUnknown
|
||||
{
|
||||
public:
|
||||
// out: if (processedSize == 0) then there are no more bytes
|
||||
STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize) = 0;
|
||||
STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize) = 0;
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) = 0;
|
||||
STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize) = 0;
|
||||
|
||||
// For both function Out: if (processedSize == 0) then there are
|
||||
// no more bytes in stream.
|
||||
// Read function always tries to read "size" bytes from stream. It
|
||||
// can read less only if it reaches end of stream.
|
||||
// ReadPart function can read X bytes: (0<=X<="size") and X can
|
||||
// be less than number of remaining bytes in stream.
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000000020000}
|
||||
|
@ -26,8 +31,8 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000020000")
|
|||
ISequentialOutStream : public IUnknown
|
||||
{
|
||||
public:
|
||||
STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize) = 0;
|
||||
STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize) = 0;
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) = 0;
|
||||
STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize) = 0;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000000030000}
|
||||
|
@ -37,7 +42,7 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000030000")
|
|||
IInStream : public ISequentialInStream
|
||||
{
|
||||
public:
|
||||
STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition) = 0;
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) = 0;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000000040000}
|
||||
|
@ -47,8 +52,8 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000040000")
|
|||
IOutStream : public ISequentialOutStream
|
||||
{
|
||||
public:
|
||||
STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition) = 0;
|
||||
STDMETHOD(SetSize)(INT64 aNewSize) = 0;
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) = 0;
|
||||
STDMETHOD(SetSize)(Int64 newSize) = 0;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000000060000}
|
||||
|
@ -58,7 +63,17 @@ MIDL_INTERFACE("23170F69-40C1-278A-0000-000000060000")
|
|||
IStreamGetSize : public IUnknown
|
||||
{
|
||||
public:
|
||||
STDMETHOD(GetSize)(UINT64 *size) = 0;
|
||||
STDMETHOD(GetSize)(UInt64 *size) = 0;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000000070000}
|
||||
DEFINE_GUID(IID_IOutStreamFlush,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000000070000")
|
||||
IOutStreamFlush : public IUnknown
|
||||
{
|
||||
public:
|
||||
STDMETHOD(Flush)() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,18 +4,15 @@
|
|||
|
||||
#include "CRC.h"
|
||||
|
||||
static const UINT32 kCRCPoly = 0xEDB88320;
|
||||
static const UInt32 kCRCPoly = 0xEDB88320;
|
||||
|
||||
UINT32 CCRC::Table[256];
|
||||
UInt32 CCRC::Table[256];
|
||||
|
||||
class CCRCTableInit
|
||||
void CCRC::InitTable()
|
||||
{
|
||||
public:
|
||||
CCRCTableInit()
|
||||
{
|
||||
for (UINT32 i = 0; i < 256; i++)
|
||||
for (UInt32 i = 0; i < 256; i++)
|
||||
{
|
||||
UINT32 r = i;
|
||||
UInt32 r = i;
|
||||
for (int j = 0; j < 8; j++)
|
||||
if (r & 1)
|
||||
r = (r >> 1) ^ kCRCPoly;
|
||||
|
@ -24,87 +21,35 @@ CCRCTableInit()
|
|||
CCRC::Table[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
class CCRCTableInit
|
||||
{
|
||||
public:
|
||||
CCRCTableInit() { CCRC::InitTable(); }
|
||||
} g_CRCTableInit;
|
||||
|
||||
/*
|
||||
const UINT32 CCRC::Table[] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
|
||||
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
|
||||
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||||
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||||
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
|
||||
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
|
||||
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
|
||||
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
|
||||
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
|
||||
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
|
||||
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
|
||||
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
|
||||
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
|
||||
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
|
||||
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
|
||||
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
|
||||
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||||
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
|
||||
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
|
||||
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
|
||||
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
|
||||
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
|
||||
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
|
||||
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||||
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
|
||||
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
|
||||
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
|
||||
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
|
||||
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
|
||||
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
|
||||
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
|
||||
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
|
||||
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
|
||||
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
|
||||
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
|
||||
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
|
||||
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||||
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
|
||||
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
|
||||
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
|
||||
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
|
||||
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
|
||||
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
|
||||
0x2d02ef8dL
|
||||
};
|
||||
*/
|
||||
|
||||
#define UPDATE valueLoc = Table[(BYTE)valueLoc] ^ (valueLoc >> 8)
|
||||
#define UPDATE4 UPDATE; UPDATE; UPDATE; UPDATE;
|
||||
|
||||
void CCRC::Update(const void *data, UINT32 size)
|
||||
void CCRC::Update(Byte b)
|
||||
{
|
||||
UINT32 valueLoc = _value;
|
||||
const BYTE *byteBuffer = (const BYTE *)data;
|
||||
|
||||
for(; (UINT_PTR(byteBuffer) & 3) != 0 && size > 0; size--, byteBuffer++)
|
||||
valueLoc = Table[(((BYTE)(valueLoc)) ^ (*byteBuffer))] ^
|
||||
(valueLoc >> 8);
|
||||
|
||||
const UINT32 kBlockSize = 4;
|
||||
while (size >= kBlockSize)
|
||||
{
|
||||
size -= kBlockSize;
|
||||
valueLoc ^= *(const UINT32 *)byteBuffer;
|
||||
UPDATE4
|
||||
byteBuffer += kBlockSize;
|
||||
}
|
||||
for(UINT32 i = 0; i < size; i++)
|
||||
valueLoc = Table[(((BYTE)(valueLoc)) ^ (byteBuffer)[i])] ^
|
||||
(valueLoc >> 8);
|
||||
_value = valueLoc;
|
||||
_value = Table[((Byte)(_value)) ^ b] ^ (_value >> 8);
|
||||
}
|
||||
|
||||
void CCRC::Update(UInt32 v)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
Update((Byte)(v >> (8 * i)));
|
||||
}
|
||||
|
||||
void CCRC::Update(const UInt64 &v)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
Update((Byte)(v >> (8 * i)));
|
||||
}
|
||||
|
||||
void CCRC::Update(const void *data, UInt32 size)
|
||||
{
|
||||
UInt32 v = _value;
|
||||
const Byte *p = (const Byte *)data;
|
||||
for (; size > 0 ; size--, p++)
|
||||
v = Table[((Byte)(v)) ^ *p] ^ (v >> 8);
|
||||
_value = v;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// Common/CRC.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __COMMON_CRC_H
|
||||
#define __COMMON_CRC_H
|
||||
|
||||
|
@ -9,20 +7,25 @@
|
|||
|
||||
class CCRC
|
||||
{
|
||||
UINT32 _value;
|
||||
UInt32 _value;
|
||||
public:
|
||||
static UINT32 Table[256];
|
||||
static UInt32 Table[256];
|
||||
static void InitTable();
|
||||
|
||||
CCRC(): _value(0xFFFFFFFF){};
|
||||
void Init() { _value = 0xFFFFFFFF; }
|
||||
void Update(const void *data, UINT32 size);
|
||||
UINT32 GetDigest() const { return _value ^ 0xFFFFFFFF; }
|
||||
static UINT32 CalculateDigest(const void *data, UINT32 size)
|
||||
void Update(Byte v);
|
||||
void Update(UInt32 v);
|
||||
void Update(const UInt64 &v);
|
||||
void Update(const void *data, UInt32 size);
|
||||
UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; }
|
||||
static UInt32 CalculateDigest(const void *data, UInt32 size)
|
||||
{
|
||||
CCRC crc;
|
||||
crc.Update(data, size);
|
||||
return crc.GetDigest();
|
||||
}
|
||||
static bool VerifyDigest(UINT32 digest, const void *data, UINT32 size)
|
||||
static bool VerifyDigest(UInt32 digest, const void *data, UInt32 size)
|
||||
{
|
||||
return (CalculateDigest(data, size) == digest);
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -1,7 +1,5 @@
|
|||
// Common/Defs.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __COMMON_DEFS_H
|
||||
#define __COMMON_DEFS_H
|
||||
|
||||
|
@ -19,10 +17,4 @@ inline int BoolToInt(bool value)
|
|||
inline bool IntToBool(int value)
|
||||
{ return (value != 0); }
|
||||
|
||||
class CMemoryException
|
||||
{
|
||||
public:
|
||||
CMemoryException() {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// MyCom.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __MYCOM_H
|
||||
#define __MYCOM_H
|
||||
|
||||
#include "MyWindows.h"
|
||||
|
||||
#define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; }
|
||||
|
||||
template <class T>
|
||||
|
@ -50,10 +50,12 @@ public:
|
|||
_p = NULL;
|
||||
return pt;
|
||||
}
|
||||
/*HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
|
||||
#ifdef WIN32
|
||||
HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
|
||||
{
|
||||
return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
|
||||
}*/
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
|
||||
{
|
||||
|
@ -65,16 +67,16 @@ public:
|
|||
return hr;
|
||||
}
|
||||
*/
|
||||
/*template <class Q>
|
||||
template <class Q>
|
||||
HRESULT QueryInterface(REFGUID iid, Q** pp) const
|
||||
{
|
||||
return _p->QueryInterface(iid, (void**)pp);
|
||||
}*/
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
/*class CMyComBSTR
|
||||
class CMyComBSTR
|
||||
{
|
||||
public:
|
||||
BSTR m_str;
|
||||
|
@ -83,7 +85,7 @@ public:
|
|||
// CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
|
||||
// CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); }
|
||||
CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
|
||||
/ *
|
||||
/*
|
||||
CMyComBSTR(REFGUID src)
|
||||
{
|
||||
LPOLESTR szGuid;
|
||||
|
@ -91,7 +93,7 @@ public:
|
|||
m_str = ::SysAllocString(szGuid);
|
||||
CoTaskMemFree(szGuid);
|
||||
}
|
||||
* /
|
||||
*/
|
||||
~CMyComBSTR() { ::SysFreeString(m_str); }
|
||||
CMyComBSTR& operator=(const CMyComBSTR& src)
|
||||
{
|
||||
|
@ -132,7 +134,7 @@ public:
|
|||
m_str = NULL;
|
||||
}
|
||||
bool operator!() const { return (m_str == NULL); }
|
||||
};*/
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
@ -184,4 +186,12 @@ STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
|
|||
MY_QUERYINTERFACE_ENTRY(i4) \
|
||||
)
|
||||
|
||||
#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \
|
||||
MY_QUERYINTERFACE_ENTRY(i1) \
|
||||
MY_QUERYINTERFACE_ENTRY(i2) \
|
||||
MY_QUERYINTERFACE_ENTRY(i3) \
|
||||
MY_QUERYINTERFACE_ENTRY(i4) \
|
||||
MY_QUERYINTERFACE_ENTRY(i5) \
|
||||
)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include "../../Platform.h"
|
||||
#endif
|
||||
#include "../../Platform.h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,23 +1,19 @@
|
|||
// Common/Types.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __COMMON_TYPES_H
|
||||
#define __COMMON_TYPES_H
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <basetsd.h>
|
||||
typedef unsigned char Byte;
|
||||
typedef short Int16;
|
||||
typedef unsigned short UInt16;
|
||||
typedef int Int32;
|
||||
typedef unsigned int UInt32;
|
||||
#ifdef _MSC_VER
|
||||
typedef __int64 Int64;
|
||||
typedef unsigned __int64 UInt64;
|
||||
#else
|
||||
# include "../../Platform.h"
|
||||
#endif
|
||||
|
||||
typedef unsigned char UINT8;
|
||||
typedef unsigned short UINT16;
|
||||
typedef short INT16;
|
||||
#ifndef _WINDOWS_
|
||||
// typedef unsigned long UINT32;
|
||||
typedef UINT8 BYTE;
|
||||
typedef long long int Int64;
|
||||
typedef unsigned long long int UInt64;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#
|
||||
|
||||
# -- Objects and source files --
|
||||
SRCS = zlib/deflate.c zlib/trees.c bzip2/blocksort.c bzip2/bzlib.c bzip2/compress.c bzip2/huffman.c 7zip/7zGuids.cpp 7zip/Common/CRC.cpp 7zip/7zip/Compress/LZ/LZInWindow.cpp 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp 7zip/7zip/Compress/LZMA/LZMALen.cpp 7zip/7zip/Compress/LZMA/LZMALiteral.cpp 7zip/7zip/Common/OutBuffer.cpp 7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp build.cpp crc32.c DialogTemplate.cpp exedata.cpp lang.cpp makenssi.cpp Plugins.cpp ResourceEditor.cpp ResourceVersionInfo.cpp script.cpp tokens.cpp util.cpp
|
||||
OBJS = 7zGuids.o blocksort.o build.o bzlib.o compress.o CRC.o crc32.o deflate.o DialogTemplate.o exedata.o huffman.o lang.o LZInWindow.o LZMAEncoder.o LZMALen.o LZMALiteral.o makenssi.o OutBuffer.o Plugins.o RangeCoderBit.o ResourceEditor.o ResourceVersionInfo.o script.o tokens.o trees.o util.o
|
||||
SRCS = zlib/deflate.c zlib/trees.c bzip2/blocksort.c bzip2/bzlib.c bzip2/compress.c bzip2/huffman.c 7zip/7zGuids.cpp 7zip/Common/CRC.cpp 7zip/7zip/Compress/LZ/LZInWindow.cpp 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp 7zip/7zip/Common/OutBuffer.cpp 7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp 7zip/Common/Alloc.cpp build.cpp crc32.c DialogTemplate.cpp exedata.cpp lang.cpp makenssi.cpp Plugins.cpp ResourceEditor.cpp ResourceVersionInfo.cpp script.cpp tokens.cpp util.cpp
|
||||
OBJS = 7zGuids.o blocksort.o build.o bzlib.o compress.o CRC.o crc32.o deflate.o DialogTemplate.o exedata.o huffman.o lang.o LZInWindow.o LZMAEncoder.o Alloc.o makenssi.o OutBuffer.o Plugins.o RangeCoderBit.o ResourceEditor.o ResourceVersionInfo.o script.o tokens.o trees.o util.o
|
||||
ifeq "$(strip $(findstring i386pe,$(shell ld -V)))" ""
|
||||
LIBS = -lstdc++ -lpthread
|
||||
EXESUFF =
|
||||
|
|
|
@ -20,18 +20,21 @@
|
|||
typedef unsigned char BYTE, *PBYTE, *LPBYTE;
|
||||
typedef unsigned short WORD, *LPWORD;
|
||||
typedef unsigned long DWORD, *LPDWORD;
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned int UINT;
|
||||
typedef unsigned int UINT32;
|
||||
typedef int INT;
|
||||
typedef int INT32;
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef long long INT64;
|
||||
typedef unsigned long long UINT64;
|
||||
typedef long long INT64, LARGE_INTEGER;
|
||||
typedef unsigned long long UINT64, ULARGE_INTEGER;
|
||||
typedef int BOOL;
|
||||
typedef void VOID;
|
||||
typedef void *LPVOID;
|
||||
typedef char CHAR, *PCHAR, *LPCH, *PCH, *NPSTR, *LPSTR, *PSTR;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef const char *LPCCH, *PCSTR, *LPCSTR;
|
||||
typedef unsigned short WCHAR, *PWCHAR, *LPWCH, *PWCH, *NWPSTR, *LPWSTR, *PWSTR;
|
||||
typedef const unsigned short *LPCWCH, *PCWCH, *LPCWSTR, *PCWSTR;
|
||||
|
|
|
@ -102,7 +102,8 @@ WCHAR* StrToWstrAlloc(const char* istr, int codepage)
|
|||
{
|
||||
int len = strlen(istr);
|
||||
char *in = (char *) istr;
|
||||
char *out = (char *) wstr = new WCHAR[len + 1];
|
||||
wstr = new WCHAR[len + 1];
|
||||
char *out = (char *) wstr;
|
||||
size_t insize = len + 1;
|
||||
size_t outsize = (len + 1) * sizeof(WCHAR);
|
||||
if (__iconv_adaptor(iconv, cd, &in, &insize, &out, &outsize) == (size_t) -1)
|
||||
|
|
|
@ -135,6 +135,18 @@ private:
|
|||
|
||||
#endif
|
||||
|
||||
int ConvertError(HRESULT result)
|
||||
{
|
||||
if (result != S_OK)
|
||||
{
|
||||
if (result == E_OUTOFMEMORY)
|
||||
return LZMA_MEM_ERROR;
|
||||
else
|
||||
return LZMA_IO_ERROR;
|
||||
}
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
|
@ -207,7 +219,7 @@ public:
|
|||
props[2].ulVal = 64;
|
||||
if (_encoder->SetCoderProperties(propdIDs, props, kNumProps) != 0)
|
||||
return LZMA_INIT_ERROR;
|
||||
return _encoder->SetStreams(this, this, 0, 0);
|
||||
return _encoder->SetStreams(this, this, 0, 0) == S_OK ? C_OK : LZMA_INIT_ERROR;
|
||||
}
|
||||
|
||||
int Init(int level)
|
||||
|
@ -251,18 +263,16 @@ public:
|
|||
{
|
||||
try
|
||||
{
|
||||
if (_encoder->WriteCoderProperties(this) == S_OK)
|
||||
HRESULT hResult = _encoder->WriteCoderProperties(this);
|
||||
if (res == S_OK)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
UINT64 inSize, outSize;
|
||||
INT32 finished;
|
||||
if (_encoder->CodeOneBlock(&inSize, &outSize, &finished))
|
||||
{
|
||||
if (res != C_OK)
|
||||
res = LZMA_IO_ERROR;
|
||||
res = ConvertError(_encoder->CodeOneBlock(&inSize, &outSize, &finished));
|
||||
if (res != C_OK)
|
||||
break;
|
||||
}
|
||||
if (finished)
|
||||
{
|
||||
res = C_OK;
|
||||
|
@ -272,13 +282,9 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
res = LZMA_IO_ERROR;
|
||||
res = ConvertError(hResult);
|
||||
}
|
||||
}
|
||||
catch (CMemoryException)
|
||||
{
|
||||
res = LZMA_MEM_ERROR;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
res = LZMA_IO_ERROR;
|
||||
|
|
|
@ -156,7 +156,13 @@ SOURCE=.\7zip\7zGuids.cpp
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zip\Common\Alloc.cpp
|
||||
# ADD CPP /D "COMPRESS_MF_BT"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zip\Common\CRC.cpp
|
||||
# ADD CPP /D "COMPRESS_MF_BT"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
|
@ -170,16 +176,6 @@ SOURCE=.\7zip\7zip\Compress\LZMA\LZMAEncoder.cpp
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zip\7zip\Compress\LZMA\LZMALen.cpp
|
||||
# ADD CPP /D "COMPRESS_MF_BT"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zip\7zip\Compress\LZMA\LZMALiteral.cpp
|
||||
# ADD CPP /D "COMPRESS_MF_BT"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zip\7zip\Common\OutBuffer.cpp
|
||||
# ADD CPP /D "COMPRESS_MF_BT"
|
||||
# End Source File
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue