upgraded to lzma sdk 4.43 for faster compression
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@4772 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
51a96f2d75
commit
2cd2142ca3
42 changed files with 1900 additions and 1572 deletions
|
@ -7,11 +7,11 @@
|
|||
#include "../../Common/Alloc.h"
|
||||
|
||||
CInBuffer::CInBuffer():
|
||||
_bufferBase(0),
|
||||
_bufferSize(0),
|
||||
_buffer(0),
|
||||
_bufferLimit(0),
|
||||
_stream(0)
|
||||
_bufferBase(0),
|
||||
_stream(0),
|
||||
_bufferSize(0)
|
||||
{}
|
||||
|
||||
bool CInBuffer::Create(UInt32 bufferSize)
|
||||
|
@ -23,19 +23,23 @@ bool CInBuffer::Create(UInt32 bufferSize)
|
|||
return true;
|
||||
Free();
|
||||
_bufferSize = bufferSize;
|
||||
_bufferBase = (Byte *)::BigAlloc(bufferSize);
|
||||
_bufferBase = (Byte *)::MidAlloc(bufferSize);
|
||||
return (_bufferBase != 0);
|
||||
}
|
||||
|
||||
void CInBuffer::Free()
|
||||
{
|
||||
BigFree(_bufferBase);
|
||||
::MidFree(_bufferBase);
|
||||
_bufferBase = 0;
|
||||
}
|
||||
|
||||
void CInBuffer::Init(ISequentialInStream *stream)
|
||||
void CInBuffer::SetStream(ISequentialInStream *stream)
|
||||
{
|
||||
_stream = stream;
|
||||
}
|
||||
|
||||
void CInBuffer::Init()
|
||||
{
|
||||
_processedSize = 0;
|
||||
_buffer = _bufferBase;
|
||||
_bufferLimit = _buffer;
|
||||
|
@ -55,7 +59,7 @@ bool CInBuffer::ReadBlock()
|
|||
return false;
|
||||
_processedSize += (_buffer - _bufferBase);
|
||||
UInt32 numProcessedBytes;
|
||||
HRESULT result = _stream->ReadPart(_bufferBase, _bufferSize, &numProcessedBytes);
|
||||
HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes);
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
ErrorCode = result;
|
||||
#else
|
||||
|
@ -67,3 +71,10 @@ bool CInBuffer::ReadBlock()
|
|||
_wasFinished = (numProcessedBytes == 0);
|
||||
return (!_wasFinished);
|
||||
}
|
||||
|
||||
Byte CInBuffer::ReadBlock2()
|
||||
{
|
||||
if(!ReadBlock())
|
||||
return 0xFF;
|
||||
return *_buffer++;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#define __INBUFFER_H
|
||||
|
||||
#include "../IStream.h"
|
||||
#include "../../Common/MyCom.h"
|
||||
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
class CInBufferException
|
||||
|
@ -16,15 +17,16 @@ public:
|
|||
|
||||
class CInBuffer
|
||||
{
|
||||
UInt64 _processedSize;
|
||||
Byte *_bufferBase;
|
||||
UInt32 _bufferSize;
|
||||
Byte *_buffer;
|
||||
Byte *_bufferLimit;
|
||||
ISequentialInStream *_stream;
|
||||
Byte *_bufferBase;
|
||||
CMyComPtr<ISequentialInStream> _stream;
|
||||
UInt64 _processedSize;
|
||||
UInt32 _bufferSize;
|
||||
bool _wasFinished;
|
||||
|
||||
bool ReadBlock();
|
||||
Byte ReadBlock2();
|
||||
|
||||
public:
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
|
@ -37,8 +39,9 @@ public:
|
|||
bool Create(UInt32 bufferSize);
|
||||
void Free();
|
||||
|
||||
void Init(ISequentialInStream *stream);
|
||||
// void ReleaseStream() { _stream.Release(); }
|
||||
void SetStream(ISequentialInStream *stream);
|
||||
void Init();
|
||||
void ReleaseStream() { _stream.Release(); }
|
||||
|
||||
bool ReadByte(Byte &b)
|
||||
{
|
||||
|
@ -51,8 +54,7 @@ public:
|
|||
Byte ReadByte()
|
||||
{
|
||||
if(_buffer >= _bufferLimit)
|
||||
if(!ReadBlock())
|
||||
return 0xFF;
|
||||
return ReadBlock2();
|
||||
return *_buffer++;
|
||||
}
|
||||
void ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
|
||||
|
|
|
@ -15,48 +15,98 @@ bool COutBuffer::Create(UInt32 bufferSize)
|
|||
return true;
|
||||
Free();
|
||||
_bufferSize = bufferSize;
|
||||
_buffer = (Byte *)::BigAlloc(bufferSize);
|
||||
_buffer = (Byte *)::MidAlloc(bufferSize);
|
||||
return (_buffer != 0);
|
||||
}
|
||||
|
||||
void COutBuffer::Free()
|
||||
{
|
||||
BigFree(_buffer);
|
||||
::MidFree(_buffer);
|
||||
_buffer = 0;
|
||||
}
|
||||
|
||||
void COutBuffer::Init(ISequentialOutStream *stream)
|
||||
void COutBuffer::SetStream(ISequentialOutStream *stream)
|
||||
{
|
||||
_stream = stream;
|
||||
_processedSize = 0;
|
||||
}
|
||||
|
||||
void COutBuffer::Init()
|
||||
{
|
||||
_streamPos = 0;
|
||||
_limitPos = _bufferSize;
|
||||
_pos = 0;
|
||||
_processedSize = 0;
|
||||
_overDict = false;
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
ErrorCode = S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT COutBuffer::Flush()
|
||||
{
|
||||
if (_pos == 0)
|
||||
return S_OK;
|
||||
UInt32 processedSize;
|
||||
HRESULT result = _stream->Write(_buffer, _pos, &processedSize);
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
if (_pos != processedSize)
|
||||
return E_FAIL;
|
||||
_processedSize += processedSize;
|
||||
_pos = 0;
|
||||
return S_OK;
|
||||
UInt64 COutBuffer::GetProcessedSize() const
|
||||
{
|
||||
UInt64 res = _processedSize + _pos - _streamPos;
|
||||
if (_streamPos > _pos)
|
||||
res += _bufferSize;
|
||||
return res;
|
||||
}
|
||||
|
||||
void COutBuffer::WriteBlock()
|
||||
|
||||
HRESULT COutBuffer::FlushPart()
|
||||
{
|
||||
// _streamPos < _bufferSize
|
||||
UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos);
|
||||
HRESULT result = S_OK;
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
result = ErrorCode;
|
||||
#endif
|
||||
if (_buffer2 != 0)
|
||||
{
|
||||
memmove(_buffer2, _buffer + _streamPos, size);
|
||||
_buffer2 += size;
|
||||
}
|
||||
|
||||
if (_stream != 0
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
&& (ErrorCode == S_OK)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
UInt32 processedSize = 0;
|
||||
result = _stream->Write(_buffer + _streamPos, size, &processedSize);
|
||||
size = processedSize;
|
||||
}
|
||||
_streamPos += size;
|
||||
if (_streamPos == _bufferSize)
|
||||
_streamPos = 0;
|
||||
if (_pos == _bufferSize)
|
||||
{
|
||||
_overDict = true;
|
||||
_pos = 0;
|
||||
}
|
||||
_limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize;
|
||||
_processedSize += size;
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT COutBuffer::Flush()
|
||||
{
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
if (ErrorCode != S_OK)
|
||||
return;
|
||||
return ErrorCode;
|
||||
#endif
|
||||
HRESULT result = Flush();
|
||||
|
||||
while(_streamPos != _pos)
|
||||
{
|
||||
HRESULT result = FlushPart();
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void COutBuffer::FlushWithCheck()
|
||||
{
|
||||
HRESULT result = FlushPart();
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
ErrorCode = result;
|
||||
#else
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#define __OUTBUFFER_H
|
||||
|
||||
#include "../IStream.h"
|
||||
#include "../../Common/MyCom.h"
|
||||
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
struct COutBufferException
|
||||
|
@ -15,55 +16,49 @@ struct COutBufferException
|
|||
|
||||
class COutBuffer
|
||||
{
|
||||
protected:
|
||||
Byte *_buffer;
|
||||
UInt32 _pos;
|
||||
UInt32 _limitPos;
|
||||
UInt32 _streamPos;
|
||||
UInt32 _bufferSize;
|
||||
ISequentialOutStream *_stream;
|
||||
CMyComPtr<ISequentialOutStream> _stream;
|
||||
UInt64 _processedSize;
|
||||
Byte *_buffer2;
|
||||
bool _overDict;
|
||||
|
||||
void WriteBlock();
|
||||
HRESULT FlushPart();
|
||||
void FlushWithCheck();
|
||||
public:
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
HRESULT ErrorCode;
|
||||
#endif
|
||||
|
||||
COutBuffer(): _buffer(0), _pos(0), _stream(0) {}
|
||||
COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {}
|
||||
~COutBuffer() { Free(); }
|
||||
|
||||
bool Create(UInt32 bufferSize);
|
||||
void Free();
|
||||
|
||||
void Init(ISequentialOutStream *stream);
|
||||
void SetMemStream(Byte *buffer) { _buffer2 = buffer; }
|
||||
void SetStream(ISequentialOutStream *stream);
|
||||
void Init();
|
||||
HRESULT Flush();
|
||||
// void ReleaseStream(); { _stream.Release(); }
|
||||
|
||||
/*
|
||||
void *GetBuffer(UInt32 &sizeAvail)
|
||||
{
|
||||
sizeAvail = _bufferSize - _pos;
|
||||
return _buffer + _pos;
|
||||
}
|
||||
void MovePos(UInt32 num)
|
||||
{
|
||||
_pos += num;
|
||||
if(_pos >= _bufferSize)
|
||||
WriteBlock();
|
||||
}
|
||||
*/
|
||||
void ReleaseStream() { _stream.Release(); }
|
||||
|
||||
void WriteByte(Byte b)
|
||||
{
|
||||
_buffer[_pos++] = b;
|
||||
if(_pos >= _bufferSize)
|
||||
WriteBlock();
|
||||
if(_pos == _limitPos)
|
||||
FlushWithCheck();
|
||||
}
|
||||
void WriteBytes(const void *data, UInt32 size)
|
||||
void WriteBytes(const void *data, size_t size)
|
||||
{
|
||||
for (UInt32 i = 0; i < size; i++)
|
||||
for (size_t i = 0; i < size; i++)
|
||||
WriteByte(((const Byte *)data)[i]);
|
||||
}
|
||||
|
||||
UInt64 GetProcessedSize() const { return _processedSize + _pos; }
|
||||
UInt64 GetProcessedSize() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Platform.h"
|
||||
#include "../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
|
|
44
Source/7zip/7zip/Common/StreamUtils.cpp
Normal file
44
Source/7zip/7zip/Common/StreamUtils.cpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
// StreamUtils.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../Common/MyCom.h"
|
||||
#include "StreamUtils.h"
|
||||
|
||||
HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
if (processedSize != 0)
|
||||
*processedSize = 0;
|
||||
while(size != 0)
|
||||
{
|
||||
UInt32 processedSizeLoc;
|
||||
HRESULT res = stream->Read(data, size, &processedSizeLoc);
|
||||
if (processedSize != 0)
|
||||
*processedSize += processedSizeLoc;
|
||||
data = (Byte *)((Byte *)data + processedSizeLoc);
|
||||
size -= processedSizeLoc;
|
||||
RINOK(res);
|
||||
if (processedSizeLoc == 0)
|
||||
return S_OK;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
if (processedSize != 0)
|
||||
*processedSize = 0;
|
||||
while(size != 0)
|
||||
{
|
||||
UInt32 processedSizeLoc;
|
||||
HRESULT res = stream->Write(data, size, &processedSizeLoc);
|
||||
if (processedSize != 0)
|
||||
*processedSize += processedSizeLoc;
|
||||
data = (const void *)((const Byte *)data + processedSizeLoc);
|
||||
size -= processedSizeLoc;
|
||||
RINOK(res);
|
||||
if (processedSizeLoc == 0)
|
||||
break;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
11
Source/7zip/7zip/Common/StreamUtils.h
Normal file
11
Source/7zip/7zip/Common/StreamUtils.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
// StreamUtils.h
|
||||
|
||||
#ifndef __STREAMUTILS_H
|
||||
#define __STREAMUTILS_H
|
||||
|
||||
#include "../IStream.h"
|
||||
|
||||
HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize);
|
||||
HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize);
|
||||
|
||||
#endif
|
|
@ -1,92 +1,54 @@
|
|||
// BinTree.h
|
||||
|
||||
// #ifndef __BINTREE_H
|
||||
// #define __BINTREE_H
|
||||
|
||||
#include "../LZInWindow.h"
|
||||
#include "../IMatchFinder.h"
|
||||
|
||||
namespace BT_NAMESPACE {
|
||||
|
||||
typedef UInt32 CIndex;
|
||||
const UInt32 kMaxValForNormalize = (UInt32(1) << 31) - 1;
|
||||
|
||||
// #define HASH_ARRAY_2
|
||||
|
||||
// #ifdef HASH_ARRAY_2
|
||||
|
||||
// #define HASH_ARRAY_3
|
||||
|
||||
// #else
|
||||
|
||||
// #define HASH_ZIP
|
||||
|
||||
// #endif
|
||||
|
||||
struct CPair
|
||||
{
|
||||
CIndex Left;
|
||||
CIndex Right;
|
||||
};
|
||||
|
||||
/*
|
||||
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
|
||||
class CMatchFinder:
|
||||
public IMatchFinder,
|
||||
public CLZInWindow,
|
||||
public CMyUnknownImp,
|
||||
public IMatchFinderSetNumPasses
|
||||
{
|
||||
UInt32 _cyclicBufferPos;
|
||||
UInt32 _cyclicBufferSize;
|
||||
UInt32 _historySize;
|
||||
UInt32 _cyclicBufferSize; // it must be historySize + 1
|
||||
UInt32 _matchMaxLen;
|
||||
|
||||
CIndex *_hash;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
CIndex *_hash2;
|
||||
#ifdef HASH_ARRAY_3
|
||||
CIndex *_hash3;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// CBundle *_son;
|
||||
CPair *_son;
|
||||
|
||||
CIndex *_son;
|
||||
UInt32 _hashMask;
|
||||
UInt32 _cutValue;
|
||||
UInt32 _hashSizeSum;
|
||||
|
||||
void NormalizeLinks(CIndex *items, UInt32 numItems, UInt32 subValue);
|
||||
void Normalize();
|
||||
void FreeThisClassMemory();
|
||||
void FreeMemory();
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(SetStream)(ISequentialInStream *inStream);
|
||||
STDMETHOD_(void, ReleaseStream)();
|
||||
STDMETHOD(Init)();
|
||||
HRESULT MovePos();
|
||||
STDMETHOD_(Byte, GetIndexByte)(Int32 index);
|
||||
STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit);
|
||||
STDMETHOD_(UInt32, GetNumAvailableBytes)();
|
||||
STDMETHOD_(const Byte *, GetPointerToCurrentPos)();
|
||||
STDMETHOD_(Int32, NeedChangeBufferPos)(UInt32 numCheckBytes);
|
||||
STDMETHOD_(void, ChangeBufferPos)();
|
||||
|
||||
STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter);
|
||||
STDMETHOD(GetMatches)(UInt32 *distances);
|
||||
STDMETHOD(Skip)(UInt32 num);
|
||||
|
||||
public:
|
||||
CInTree();
|
||||
~CInTree();
|
||||
HRESULT Create(UInt32 sizeHistory, UInt32 keepAddBufferBefore, UInt32 matchMaxLen,
|
||||
UInt32 keepAddBufferAfter, UInt32 sizeReserv = (1<<17));
|
||||
HRESULT Init(ISequentialInStream *stream);
|
||||
void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; }
|
||||
UInt32 GetLongestMatch(UInt32 *distances);
|
||||
void DummyLongestMatch();
|
||||
HRESULT MovePos()
|
||||
{
|
||||
_cyclicBufferPos++;
|
||||
if (_cyclicBufferPos >= _cyclicBufferSize)
|
||||
_cyclicBufferPos = 0;
|
||||
RINOK(CLZInWindow::MovePos());
|
||||
if (_pos == kMaxValForNormalize)
|
||||
Normalize();
|
||||
return S_OK;
|
||||
}
|
||||
CMatchFinder();
|
||||
virtual ~CMatchFinder();
|
||||
virtual void SetNumPasses(UInt32 numPasses) { _cutValue = numPasses; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
// BinTree2.h
|
||||
|
||||
#ifndef __BINTREE2__H
|
||||
#define __BINTREE2__H
|
||||
#ifndef __BINTREE2_H
|
||||
#define __BINTREE2_H
|
||||
|
||||
#undef BT_CLSID
|
||||
#define BT_CLSID CLSID_CMatchFinderBT2
|
||||
|
||||
#undef BT_NAMESPACE
|
||||
#define BT_NAMESPACE NBT2
|
||||
|
||||
#include "BinTreeMF.h"
|
||||
#include "BinTreeMFMain.h"
|
||||
#include "BinTreeMain.h"
|
||||
|
||||
#undef BT_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
// BinTree3.h
|
||||
|
||||
#ifndef __BINTREE3__H
|
||||
#define __BINTREE3__H
|
||||
#ifndef __BINTREE3_H
|
||||
#define __BINTREE3_H
|
||||
|
||||
#undef BT_CLSID
|
||||
#define BT_CLSID CLSID_CMatchFinderBT3
|
||||
|
||||
#undef BT_NAMESPACE
|
||||
#define BT_NAMESPACE NBT3
|
||||
|
||||
#define HASH_ARRAY_2
|
||||
|
||||
#include "BinTreeMF.h"
|
||||
#include "BinTreeMFMain.h"
|
||||
#include "BinTreeMain.h"
|
||||
|
||||
#undef HASH_ARRAY_2
|
||||
|
||||
#endif
|
||||
#undef BT_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
// BinTree3Z.h
|
||||
|
||||
#ifndef __BINTREE3Z__H
|
||||
#define __BINTREE3Z__H
|
||||
#ifndef __BINTREE3Z_H
|
||||
#define __BINTREE3Z_H
|
||||
|
||||
#undef BT_NAMESPACE
|
||||
#define BT_NAMESPACE NBT3Z
|
||||
|
||||
#define HASH_ZIP
|
||||
|
||||
#include "BinTree.h"
|
||||
// #include "BinTreeMain.h"
|
||||
#include "BinTreeMain.h"
|
||||
|
||||
#undef HASH_ZIP
|
||||
|
||||
#endif
|
||||
#undef BT_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,22 +1,18 @@
|
|||
// BinTree4.h
|
||||
|
||||
#ifndef __BINTREE4__H
|
||||
#define __BINTREE4__H
|
||||
#ifndef __BINTREE4_H
|
||||
#define __BINTREE4_H
|
||||
|
||||
#undef BT_CLSID
|
||||
#define BT_CLSID CLSID_CMatchFinderBT4
|
||||
|
||||
#undef BT_NAMESPACE
|
||||
#define BT_NAMESPACE NBT4
|
||||
|
||||
#define HASH_ARRAY_2
|
||||
#define HASH_ARRAY_3
|
||||
|
||||
#include "BinTreeMF.h"
|
||||
#include "BinTreeMFMain.h"
|
||||
#include "BinTreeMain.h"
|
||||
|
||||
#undef HASH_ARRAY_2
|
||||
#undef HASH_ARRAY_3
|
||||
|
||||
#endif
|
||||
#undef BT_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,163 +4,187 @@
|
|||
#include "../../../../Common/CRC.h"
|
||||
#include "../../../../Common/Alloc.h"
|
||||
|
||||
#include "BinTree.h"
|
||||
|
||||
// #include <xmmintrin.h>
|
||||
// It's for prefetch
|
||||
// But prefetch doesn't give big gain in K8.
|
||||
|
||||
namespace BT_NAMESPACE {
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
static const UInt32 kHash2Size = 1 << 10;
|
||||
#define kNumHashDirectBytes 0
|
||||
#ifdef HASH_ARRAY_3
|
||||
static const UInt32 kNumHashDirectBytes = 0;
|
||||
static const UInt32 kNumHashBytes = 4;
|
||||
static const UInt32 kHash3Size = 1 << 18;
|
||||
#ifdef HASH_BIG
|
||||
static const UInt32 kHashSize = 1 << 23;
|
||||
#else
|
||||
static const UInt32 kHashSize = 1 << 20;
|
||||
#endif
|
||||
static const UInt32 kHash3Size = 1 << 16;
|
||||
#else
|
||||
static const UInt32 kNumHashDirectBytes = 3;
|
||||
static const UInt32 kNumHashBytes = 3;
|
||||
static const UInt32 kHashSize = 1 << (8 * kNumHashBytes);
|
||||
#endif
|
||||
static const UInt32 kHashSize = 0;
|
||||
static const UInt32 kMinMatchCheck = kNumHashBytes;
|
||||
static const UInt32 kStartMaxLen = 1;
|
||||
#else
|
||||
#ifdef HASH_ZIP
|
||||
static const UInt32 kNumHashDirectBytes = 0;
|
||||
#define kNumHashDirectBytes 0
|
||||
static const UInt32 kNumHashBytes = 3;
|
||||
static const UInt32 kHashSize = 1 << 16;
|
||||
static const UInt32 kMinMatchCheck = kNumHashBytes;
|
||||
static const UInt32 kStartMaxLen = 1;
|
||||
#else
|
||||
static const UInt32 kNumHashDirectBytes = 2;
|
||||
#define kNumHashDirectBytes 2
|
||||
static const UInt32 kNumHashBytes = 2;
|
||||
static const UInt32 kHashSize = 1 << (8 * kNumHashBytes);
|
||||
static const UInt32 kMinMatchCheck = kNumHashBytes + 1;
|
||||
static const UInt32 kStartMaxLen = 1;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
#ifdef HASH_ARRAY_3
|
||||
static const UInt32 kHash3Offset = kHash2Size;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
CInTree::CInTree():
|
||||
_hash(0),
|
||||
#ifdef HASH_ARRAY_2
|
||||
_hash2(0),
|
||||
#ifdef HASH_ARRAY_3
|
||||
_hash3(0),
|
||||
#endif
|
||||
#endif
|
||||
_son(0),
|
||||
_cutValue(0xFF)
|
||||
static const UInt32 kFixHashSize = 0
|
||||
#ifdef HASH_ARRAY_2
|
||||
+ kHash2Size
|
||||
#ifdef HASH_ARRAY_3
|
||||
+ kHash3Size
|
||||
#endif
|
||||
#endif
|
||||
;
|
||||
|
||||
CMatchFinder::CMatchFinder():
|
||||
_hash(0)
|
||||
{
|
||||
}
|
||||
|
||||
void CInTree::FreeMemory()
|
||||
void CMatchFinder::FreeThisClassMemory()
|
||||
{
|
||||
BigFree(_son);
|
||||
_son = 0;
|
||||
BigFree(_hash);
|
||||
_hash = 0;
|
||||
}
|
||||
|
||||
void CMatchFinder::FreeMemory()
|
||||
{
|
||||
FreeThisClassMemory();
|
||||
CLZInWindow::Free();
|
||||
}
|
||||
|
||||
CInTree::~CInTree()
|
||||
CMatchFinder::~CMatchFinder()
|
||||
{
|
||||
FreeMemory();
|
||||
}
|
||||
|
||||
HRESULT CInTree::Create(UInt32 sizeHistory, UInt32 keepAddBufferBefore,
|
||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, UInt32 sizeReserv)
|
||||
STDMETHODIMP CMatchFinder::Create(UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter)
|
||||
{
|
||||
FreeMemory();
|
||||
if (!CLZInWindow::Create(sizeHistory + keepAddBufferBefore,
|
||||
matchMaxLen + keepAddBufferAfter, sizeReserv))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (_blockSize + 256 > kMaxValForNormalize)
|
||||
if (historySize > kMaxValForNormalize - 256)
|
||||
{
|
||||
FreeMemory();
|
||||
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)
|
||||
_cutValue =
|
||||
#ifdef _HASH_CHAIN
|
||||
8 + (matchMaxLen >> 2);
|
||||
#else
|
||||
16 + (matchMaxLen >> 1);
|
||||
#endif
|
||||
UInt32 sizeReserv = (historySize + keepAddBufferBefore +
|
||||
matchMaxLen + keepAddBufferAfter) / 2 + 256;
|
||||
if (CLZInWindow::Create(historySize + keepAddBufferBefore,
|
||||
matchMaxLen + keepAddBufferAfter, sizeReserv))
|
||||
{
|
||||
FreeMemory();
|
||||
return E_OUTOFMEMORY;
|
||||
_matchMaxLen = matchMaxLen;
|
||||
UInt32 newCyclicBufferSize = historySize + 1;
|
||||
if (_hash != 0 && newCyclicBufferSize == _cyclicBufferSize)
|
||||
return S_OK;
|
||||
FreeThisClassMemory();
|
||||
_cyclicBufferSize = newCyclicBufferSize; // don't change it
|
||||
|
||||
UInt32 hs = kHashSize;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
hs = historySize - 1;
|
||||
hs |= (hs >> 1);
|
||||
hs |= (hs >> 2);
|
||||
hs |= (hs >> 4);
|
||||
hs |= (hs >> 8);
|
||||
hs >>= 1;
|
||||
hs |= 0xFFFF;
|
||||
if (hs > (1 << 24))
|
||||
{
|
||||
#ifdef HASH_ARRAY_3
|
||||
hs >>= 1;
|
||||
#else
|
||||
hs = (1 << 24) - 1;
|
||||
#endif
|
||||
}
|
||||
_hashMask = hs;
|
||||
hs++;
|
||||
#endif
|
||||
_hashSizeSum = hs + kFixHashSize;
|
||||
UInt32 numItems = _hashSizeSum + _cyclicBufferSize
|
||||
#ifndef _HASH_CHAIN
|
||||
* 2
|
||||
#endif
|
||||
;
|
||||
size_t sizeInBytes = (size_t)numItems * sizeof(CIndex);
|
||||
if (sizeInBytes / sizeof(CIndex) != numItems)
|
||||
return E_OUTOFMEMORY;
|
||||
_hash = (CIndex *)BigAlloc(sizeInBytes);
|
||||
_son = _hash + _hashSizeSum;
|
||||
if (_hash != 0)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// _hash = &m_RightBase[_blockSize];
|
||||
#ifdef HASH_ARRAY_2
|
||||
_hash2 = &_hash[kHashSize];
|
||||
#ifdef HASH_ARRAY_3
|
||||
_hash3 = &_hash2[kHash2Size];
|
||||
#endif
|
||||
#endif
|
||||
return S_OK;
|
||||
FreeMemory();
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
static const UInt32 kEmptyHashValue = 0;
|
||||
|
||||
HRESULT CInTree::Init(ISequentialInStream *stream)
|
||||
STDMETHODIMP CMatchFinder::SetStream(ISequentialInStream *stream)
|
||||
{
|
||||
RINOK(CLZInWindow::Init(stream));
|
||||
UInt32 i;
|
||||
for(i = 0; i < kHashSize; i++)
|
||||
CLZInWindow::SetStream(stream);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CMatchFinder::Init()
|
||||
{
|
||||
RINOK(CLZInWindow::Init());
|
||||
for(UInt32 i = 0; i < _hashSizeSum; i++)
|
||||
_hash[i] = kEmptyHashValue;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
for(i = 0; i < kHash2Size; i++)
|
||||
_hash2[i] = kEmptyHashValue;
|
||||
#ifdef HASH_ARRAY_3
|
||||
for(i = 0; i < kHash3Size; i++)
|
||||
_hash3[i] = kEmptyHashValue;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
_cyclicBufferPos = 0;
|
||||
|
||||
ReduceOffsets(-1);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) CMatchFinder::ReleaseStream()
|
||||
{
|
||||
// ReleaseStream();
|
||||
}
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
#ifdef HASH_ARRAY_3
|
||||
inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value, UInt32 &hash3Value)
|
||||
{
|
||||
UInt32 temp = CCRC::Table[pointer[0]] ^ pointer[1];
|
||||
hash2Value = temp & (kHash2Size - 1);
|
||||
hash3Value = (temp ^ (UInt32(pointer[2]) << 8)) & (kHash3Size - 1);
|
||||
return (temp ^ (UInt32(pointer[2]) << 8) ^ (CCRC::Table[pointer[3]] << 5)) &
|
||||
(kHashSize - 1);
|
||||
}
|
||||
|
||||
#define HASH_CALC { \
|
||||
UInt32 temp = CCRC::Table[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hash3Value = (temp ^ (UInt32(cur[2]) << 8)) & (kHash3Size - 1); \
|
||||
hashValue = (temp ^ (UInt32(cur[2]) << 8) ^ (CCRC::Table[cur[3]] << 5)) & _hashMask; }
|
||||
|
||||
#else // no HASH_ARRAY_3
|
||||
inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value)
|
||||
{
|
||||
hash2Value = (CCRC::Table[pointer[0]] ^ pointer[1]) & (kHash2Size - 1);
|
||||
return ((UInt32(pointer[0]) << 16)) | ((UInt32(pointer[1]) << 8)) | pointer[2];
|
||||
}
|
||||
#define HASH_CALC { \
|
||||
UInt32 temp = CCRC::Table[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hashValue = (temp ^ (UInt32(cur[2]) << 8)) & _hashMask; }
|
||||
#endif // HASH_ARRAY_3
|
||||
#else // no HASH_ARRAY_2
|
||||
#ifdef HASH_ZIP
|
||||
inline UInt32 Hash(const Byte *pointer)
|
||||
{
|
||||
return ((UInt32(pointer[0]) << 8) ^
|
||||
CCRC::Table[pointer[1]] ^ pointer[2]) & (kHashSize - 1);
|
||||
return ((UInt32(pointer[0]) << 8) ^ CCRC::Table[pointer[1]] ^ pointer[2]) & (kHashSize - 1);
|
||||
}
|
||||
#else // no HASH_ZIP
|
||||
inline UInt32 Hash(const Byte *pointer)
|
||||
|
@ -170,7 +194,7 @@ inline UInt32 Hash(const Byte *pointer)
|
|||
#endif // HASH_ZIP
|
||||
#endif // HASH_ARRAY_2
|
||||
|
||||
UInt32 CInTree::GetLongestMatch(UInt32 *distances)
|
||||
STDMETHODIMP CMatchFinder::GetMatches(UInt32 *distances)
|
||||
{
|
||||
UInt32 lenLimit;
|
||||
if (_pos + _matchMaxLen <= _streamPos)
|
||||
|
@ -178,346 +202,288 @@ UInt32 CInTree::GetLongestMatch(UInt32 *distances)
|
|||
else
|
||||
{
|
||||
lenLimit = _streamPos - _pos;
|
||||
if(lenLimit < kNumHashBytes)
|
||||
return 0;
|
||||
if(lenLimit < kMinMatchCheck)
|
||||
{
|
||||
distances[0] = 0;
|
||||
return MovePos();
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 matchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1;
|
||||
Byte *cur = _buffer + _pos;
|
||||
int offset = 1;
|
||||
|
||||
/*
|
||||
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 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
|
||||
const Byte *cur = _buffer + _pos;
|
||||
|
||||
UInt32 maxLen = kStartMaxLen; // to avoid items for len < hashSize;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
UInt32 hash2Value;
|
||||
#ifdef HASH_ARRAY_3
|
||||
UInt32 hash3Value;
|
||||
UInt32 hashValue = Hash(cur, hash2Value, hash3Value);
|
||||
#else
|
||||
UInt32 hashValue = Hash(cur, hash2Value);
|
||||
#endif
|
||||
UInt32 hashValue;
|
||||
HASH_CALC;
|
||||
#else
|
||||
UInt32 hashValue = Hash(cur);
|
||||
#endif
|
||||
|
||||
UInt32 curMatch = _hash[hashValue];
|
||||
UInt32 curMatch = _hash[kFixHashSize + hashValue];
|
||||
#ifdef HASH_ARRAY_2
|
||||
UInt32 curMatch2 = _hash2[hash2Value];
|
||||
UInt32 curMatch2 = _hash[hash2Value];
|
||||
#ifdef HASH_ARRAY_3
|
||||
UInt32 curMatch3 = _hash3[hash3Value];
|
||||
UInt32 curMatch3 = _hash[kHash3Offset + hash3Value];
|
||||
#endif
|
||||
_hash2[hash2Value] = _pos;
|
||||
bool matchLen2Exist = false;
|
||||
UInt32 len2Distance = 0;
|
||||
if(curMatch2 >= matchMinPos)
|
||||
{
|
||||
_hash[hash2Value] = _pos;
|
||||
if(curMatch2 > matchMinPos)
|
||||
if (_buffer[curMatch2] == cur[0])
|
||||
{
|
||||
len2Distance = _pos - curMatch2 - 1;
|
||||
matchHashLenMax = 2;
|
||||
matchLen2Exist = true;
|
||||
distances[offset++] = maxLen = 2;
|
||||
distances[offset++] = _pos - curMatch2 - 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HASH_ARRAY_3
|
||||
_hash3[hash3Value] = _pos;
|
||||
UInt32 matchLen3Exist = false;
|
||||
UInt32 len3Distance = 0;
|
||||
if(curMatch3 >= matchMinPos)
|
||||
{
|
||||
_hash[kHash3Offset + hash3Value] = _pos;
|
||||
if(curMatch3 > matchMinPos)
|
||||
if (_buffer[curMatch3] == cur[0])
|
||||
{
|
||||
len3Distance = _pos - curMatch3 - 1;
|
||||
matchHashLenMax = 3;
|
||||
matchLen3Exist = true;
|
||||
if (matchLen2Exist)
|
||||
{
|
||||
if (len3Distance < len2Distance)
|
||||
len2Distance = len3Distance;
|
||||
}
|
||||
else
|
||||
{
|
||||
len2Distance = len3Distance;
|
||||
matchLen2Exist = true;
|
||||
}
|
||||
if (curMatch3 == curMatch2)
|
||||
offset -= 2;
|
||||
distances[offset++] = maxLen = 3;
|
||||
distances[offset++] = _pos - curMatch3 - 1;
|
||||
curMatch2 = curMatch3;
|
||||
}
|
||||
#endif
|
||||
if (offset != 1 && curMatch2 == curMatch)
|
||||
{
|
||||
offset -= 2;
|
||||
maxLen = kStartMaxLen;
|
||||
}
|
||||
#endif
|
||||
|
||||
_hash[kFixHashSize + hashValue] = _pos;
|
||||
|
||||
CIndex *son = _son;
|
||||
|
||||
#ifdef _HASH_CHAIN
|
||||
son[_cyclicBufferPos] = curMatch;
|
||||
#else
|
||||
CIndex *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||
CIndex *ptr1 = son + (_cyclicBufferPos << 1);
|
||||
|
||||
UInt32 len0, len1;
|
||||
len0 = len1 = kNumHashDirectBytes;
|
||||
#endif
|
||||
|
||||
#if kNumHashDirectBytes != 0
|
||||
if(curMatch > matchMinPos)
|
||||
{
|
||||
if (_buffer[curMatch + kNumHashDirectBytes] != cur[kNumHashDirectBytes])
|
||||
{
|
||||
distances[offset++] = maxLen = kNumHashDirectBytes;
|
||||
distances[offset++] = _pos - curMatch - 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
_hash[hashValue] = _pos;
|
||||
|
||||
// UInt32 bi = _cyclicBufferPos >> kNumBundleBits;
|
||||
// UInt32 bo = _cyclicBufferPos & kBundleMask;
|
||||
// CPair &pair = _son[bi].Pairs[bo];
|
||||
CPair &pair = _son[_cyclicBufferPos];
|
||||
if(curMatch < matchMinPos)
|
||||
UInt32 count = _cutValue;
|
||||
while(true)
|
||||
{
|
||||
pair.Left = kEmptyHashValue;
|
||||
pair.Right = kEmptyHashValue;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
distances[2] = len2Distance;
|
||||
#ifdef HASH_ARRAY_3
|
||||
distances[3] = len3Distance;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return matchHashLenMax;
|
||||
}
|
||||
CIndex *ptrLeft = &pair.Right;
|
||||
CIndex *ptrRight = &pair.Left;
|
||||
|
||||
UInt32 maxLen, minLeft, minRight;
|
||||
maxLen = minLeft = minRight = kNumHashDirectBytes;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
#ifndef HASH_ARRAY_3
|
||||
if (matchLen2Exist)
|
||||
distances[2] = len2Distance;
|
||||
else
|
||||
if (kNumHashDirectBytes >= 2)
|
||||
distances[2] = _pos - curMatch - 1;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
distances[maxLen] = _pos - curMatch - 1;
|
||||
|
||||
for(UInt32 count = _cutValue; count > 0; count--)
|
||||
{
|
||||
/*
|
||||
UInt32 delta = _pos - curMatch;
|
||||
UInt32 cyclicPos = (delta <= _cyclicBufferPos) ?
|
||||
(_cyclicBufferPos - delta):
|
||||
(_cyclicBufferPos - delta + _cyclicBufferSize);
|
||||
|
||||
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)
|
||||
if(curMatch <= matchMinPos || count-- == 0)
|
||||
{
|
||||
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 = &pair.Right;
|
||||
curMatch = pair.Right;
|
||||
if(currentLen > minLeft)
|
||||
minLeft = currentLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptrLeft = curMatch;
|
||||
ptrLeft = &pair.Left;
|
||||
curMatch = pair.Left;
|
||||
if(currentLen > minRight)
|
||||
minRight = currentLen;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(currentLen < _matchMaxLen)
|
||||
{
|
||||
*ptrLeft = curMatch;
|
||||
ptrLeft = &pair.Left;
|
||||
curMatch = pair.Left;
|
||||
if(currentLen > minRight)
|
||||
minRight = currentLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptrLeft = pair.Right;
|
||||
*ptrRight = pair.Left;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
if (matchLen2Exist && len2Distance < distances[2])
|
||||
distances[2] = len2Distance;
|
||||
#ifdef HASH_ARRAY_3
|
||||
if (matchLen3Exist && len3Distance < distances[3])
|
||||
distances[3] = len3Distance;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return maxLen;
|
||||
}
|
||||
}
|
||||
if(curMatch < matchMinPos)
|
||||
#ifndef _HASH_CHAIN
|
||||
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
*ptrLeft = kEmptyHashValue;
|
||||
*ptrRight = kEmptyHashValue;
|
||||
#ifdef HASH_ARRAY_2
|
||||
if (matchLen2Exist)
|
||||
{
|
||||
if (maxLen < 2)
|
||||
{
|
||||
distances[2] = len2Distance;
|
||||
maxLen = 2;
|
||||
}
|
||||
else if (len2Distance < distances[2])
|
||||
distances[2] = len2Distance;
|
||||
}
|
||||
#ifdef HASH_ARRAY_3
|
||||
if (matchLen3Exist)
|
||||
{
|
||||
if (maxLen < 3)
|
||||
UInt32 delta = _pos - curMatch;
|
||||
UInt32 cyclicPos = (delta <= _cyclicBufferPos) ?
|
||||
(_cyclicBufferPos - delta):
|
||||
(_cyclicBufferPos - delta + _cyclicBufferSize);
|
||||
CIndex *pair = son +
|
||||
#ifdef _HASH_CHAIN
|
||||
cyclicPos;
|
||||
#else
|
||||
(cyclicPos << 1);
|
||||
#endif
|
||||
|
||||
// _mm_prefetch((const char *)pair, _MM_HINT_T0);
|
||||
|
||||
const Byte *pb = _buffer + curMatch;
|
||||
UInt32 len =
|
||||
#ifdef _HASH_CHAIN
|
||||
kNumHashDirectBytes;
|
||||
if (pb[maxLen] == cur[maxLen])
|
||||
#else
|
||||
MyMin(len0, len1);
|
||||
#endif
|
||||
if (pb[len] == cur[len])
|
||||
{
|
||||
distances[3] = len3Distance;
|
||||
maxLen = 3;
|
||||
while(++len != lenLimit)
|
||||
if (pb[len] != cur[len])
|
||||
break;
|
||||
if (maxLen < len)
|
||||
{
|
||||
distances[offset++] = maxLen = len;
|
||||
distances[offset++] = delta - 1;
|
||||
if (len == lenLimit)
|
||||
{
|
||||
#ifndef _HASH_CHAIN
|
||||
*ptr1 = pair[0];
|
||||
*ptr0 = pair[1];
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (len3Distance < distances[3])
|
||||
distances[3] = len3Distance;
|
||||
#ifdef _HASH_CHAIN
|
||||
curMatch = *pair;
|
||||
#else
|
||||
if (pb[len] < cur[len])
|
||||
{
|
||||
*ptr1 = curMatch;
|
||||
ptr1 = pair + 1;
|
||||
curMatch = *ptr1;
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr0 = curMatch;
|
||||
ptr0 = pair;
|
||||
curMatch = *ptr0;
|
||||
len0 = len;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return maxLen;
|
||||
distances[0] = offset - 1;
|
||||
if (++_cyclicBufferPos == _cyclicBufferSize)
|
||||
_cyclicBufferPos = 0;
|
||||
RINOK(CLZInWindow::MovePos());
|
||||
if (_pos == kMaxValForNormalize)
|
||||
Normalize();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CInTree::DummyLongestMatch()
|
||||
STDMETHODIMP CMatchFinder::Skip(UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
#ifdef _HASH_CHAIN
|
||||
if (_streamPos - _pos < kNumHashBytes)
|
||||
{
|
||||
RINOK(MovePos());
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
UInt32 lenLimit;
|
||||
if (_pos + _matchMaxLen <= _streamPos)
|
||||
lenLimit = _matchMaxLen;
|
||||
else
|
||||
{
|
||||
lenLimit = _streamPos - _pos;
|
||||
if(lenLimit < kNumHashBytes)
|
||||
return;
|
||||
if(lenLimit < kMinMatchCheck)
|
||||
{
|
||||
RINOK(MovePos());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
UInt32 matchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1;
|
||||
Byte *cur = _buffer + _pos;
|
||||
UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
|
||||
#endif
|
||||
const Byte *cur = _buffer + _pos;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
UInt32 hash2Value;
|
||||
#ifdef HASH_ARRAY_3
|
||||
UInt32 hash3Value;
|
||||
UInt32 hashValue = Hash(cur, hash2Value, hash3Value);
|
||||
_hash3[hash3Value] = _pos;
|
||||
UInt32 hashValue;
|
||||
HASH_CALC;
|
||||
_hash[kHash3Offset + hash3Value] = _pos;
|
||||
#else
|
||||
UInt32 hashValue = Hash(cur, hash2Value);
|
||||
UInt32 hashValue;
|
||||
HASH_CALC;
|
||||
#endif
|
||||
_hash2[hash2Value] = _pos;
|
||||
_hash[hash2Value] = _pos;
|
||||
#else
|
||||
UInt32 hashValue = Hash(cur);
|
||||
#endif
|
||||
|
||||
UInt32 curMatch = _hash[hashValue];
|
||||
_hash[hashValue] = _pos;
|
||||
UInt32 curMatch = _hash[kFixHashSize + hashValue];
|
||||
_hash[kFixHashSize + hashValue] = _pos;
|
||||
|
||||
CPair &pair = _son[_cyclicBufferPos];
|
||||
#ifdef _HASH_CHAIN
|
||||
_son[_cyclicBufferPos] = curMatch;
|
||||
#else
|
||||
CIndex *son = _son;
|
||||
CIndex *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||
CIndex *ptr1 = son + (_cyclicBufferPos << 1);
|
||||
|
||||
if(curMatch < matchMinPos)
|
||||
UInt32 len0, len1;
|
||||
len0 = len1 = kNumHashDirectBytes;
|
||||
UInt32 count = _cutValue;
|
||||
while(true)
|
||||
{
|
||||
pair.Left = kEmptyHashValue;
|
||||
pair.Right = kEmptyHashValue;
|
||||
return;
|
||||
}
|
||||
CIndex *ptrLeft = &pair.Right;
|
||||
CIndex *ptrRight = &pair.Left;
|
||||
|
||||
UInt32 maxLen, minLeft, minRight;
|
||||
maxLen = minLeft = minRight = kNumHashDirectBytes;
|
||||
for(UInt32 count = _cutValue; count > 0; count--)
|
||||
{
|
||||
Byte *pby1 = _buffer + curMatch;
|
||||
UInt32 currentLen = MyMin(minLeft, minRight);
|
||||
for(; currentLen < lenLimit; currentLen++)
|
||||
if (pby1[currentLen] != cur[currentLen])
|
||||
break;
|
||||
|
||||
if(curMatch <= matchMinPos || count-- == 0)
|
||||
{
|
||||
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||
break;
|
||||
}
|
||||
|
||||
UInt32 delta = _pos - curMatch;
|
||||
UInt32 cyclicPos = (delta <= _cyclicBufferPos) ?
|
||||
(_cyclicBufferPos - delta):
|
||||
(_cyclicBufferPos - delta + _cyclicBufferSize);
|
||||
CPair &pair = _son[cyclicPos];
|
||||
|
||||
if (currentLen != lenLimit)
|
||||
(_cyclicBufferPos - delta):
|
||||
(_cyclicBufferPos - delta + _cyclicBufferSize);
|
||||
CIndex *pair = son + (cyclicPos << 1);
|
||||
|
||||
// _mm_prefetch((const char *)pair, _MM_HINT_T0);
|
||||
|
||||
const Byte *pb = _buffer + curMatch;
|
||||
UInt32 len = MyMin(len0, len1);
|
||||
|
||||
if (pb[len] == cur[len])
|
||||
{
|
||||
if (pby1[currentLen] < cur[currentLen])
|
||||
while(++len != lenLimit)
|
||||
if (pb[len] != cur[len])
|
||||
break;
|
||||
if (len == lenLimit)
|
||||
{
|
||||
*ptrRight = curMatch;
|
||||
ptrRight = &pair.Right;
|
||||
curMatch = pair.Right;
|
||||
if(currentLen > minLeft)
|
||||
minLeft = currentLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptrLeft = curMatch;
|
||||
ptrLeft = &pair.Left;
|
||||
curMatch = pair.Left;
|
||||
if(currentLen > minRight)
|
||||
minRight = currentLen;
|
||||
*ptr1 = pair[0];
|
||||
*ptr0 = pair[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pb[len] < cur[len])
|
||||
{
|
||||
*ptr1 = curMatch;
|
||||
ptr1 = pair + 1;
|
||||
curMatch = *ptr1;
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(currentLen < _matchMaxLen)
|
||||
{
|
||||
*ptrLeft = curMatch;
|
||||
ptrLeft = &pair.Left;
|
||||
curMatch = pair.Left;
|
||||
if(currentLen > minRight)
|
||||
minRight = currentLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptrLeft = pair.Right;
|
||||
*ptrRight = pair.Left;
|
||||
return;
|
||||
}
|
||||
*ptr0 = curMatch;
|
||||
ptr0 = pair;
|
||||
curMatch = *ptr0;
|
||||
len0 = len;
|
||||
}
|
||||
if(curMatch < matchMinPos)
|
||||
break;
|
||||
}
|
||||
*ptrLeft = kEmptyHashValue;
|
||||
*ptrRight = kEmptyHashValue;
|
||||
#endif
|
||||
if (++_cyclicBufferPos == _cyclicBufferSize)
|
||||
_cyclicBufferPos = 0;
|
||||
RINOK(CLZInWindow::MovePos());
|
||||
if (_pos == kMaxValForNormalize)
|
||||
Normalize();
|
||||
}
|
||||
while(--num != 0);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CInTree::NormalizeLinks(CIndex *items, UInt32 numItems, UInt32 subValue)
|
||||
void CMatchFinder::Normalize()
|
||||
{
|
||||
UInt32 subValue = _pos - _cyclicBufferSize;
|
||||
CIndex *items = _hash;
|
||||
UInt32 numItems = (_hashSizeSum + _cyclicBufferSize
|
||||
#ifndef _HASH_CHAIN
|
||||
* 2
|
||||
#endif
|
||||
);
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 value = items[i];
|
||||
|
@ -527,25 +493,39 @@ void CInTree::NormalizeLinks(CIndex *items, UInt32 numItems, UInt32 subValue)
|
|||
value -= subValue;
|
||||
items[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void CInTree::Normalize()
|
||||
{
|
||||
UInt32 startItem = _pos - _historySize;
|
||||
UInt32 subValue = startItem - 1;
|
||||
// NormalizeLinks((CIndex *)(_son + startItem), _historySize * 2, subValue);
|
||||
NormalizeLinks((CIndex *)_son, _cyclicBufferSize * 2, subValue);
|
||||
|
||||
NormalizeLinks(_hash, kHashSize, subValue);
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
NormalizeLinks(_hash2, kHash2Size, subValue);
|
||||
#ifdef HASH_ARRAY_3
|
||||
NormalizeLinks(_hash3, kHash3Size, subValue);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ReduceOffsets(subValue);
|
||||
}
|
||||
|
||||
HRESULT CMatchFinder::MovePos()
|
||||
{
|
||||
if (++_cyclicBufferPos == _cyclicBufferSize)
|
||||
_cyclicBufferPos = 0;
|
||||
RINOK(CLZInWindow::MovePos());
|
||||
if (_pos == kMaxValForNormalize)
|
||||
Normalize();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(Byte) CMatchFinder::GetIndexByte(Int32 index)
|
||||
{ return CLZInWindow::GetIndexByte(index); }
|
||||
|
||||
STDMETHODIMP_(UInt32) CMatchFinder::GetMatchLen(Int32 index,
|
||||
UInt32 back, UInt32 limit)
|
||||
{ return CLZInWindow::GetMatchLen(index, back, limit); }
|
||||
|
||||
STDMETHODIMP_(UInt32) CMatchFinder::GetNumAvailableBytes()
|
||||
{ return CLZInWindow::GetNumAvailableBytes(); }
|
||||
|
||||
STDMETHODIMP_(const Byte *) CMatchFinder::GetPointerToCurrentPos()
|
||||
{ return CLZInWindow::GetPointerToCurrentPos(); }
|
||||
|
||||
STDMETHODIMP_(Int32) CMatchFinder::NeedChangeBufferPos(UInt32 numCheckBytes)
|
||||
{ return CLZInWindow::NeedMove(numCheckBytes) ? 1: 0; }
|
||||
|
||||
STDMETHODIMP_(void) CMatchFinder::ChangeBufferPos()
|
||||
{ CLZInWindow::MoveBlock();}
|
||||
|
||||
#undef HASH_CALC
|
||||
#undef kNumHashDirectBytes
|
||||
|
||||
}
|
||||
|
|
|
@ -3,61 +3,30 @@
|
|||
#ifndef __IMATCHFINDER_H
|
||||
#define __IMATCHFINDER_H
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200010000}
|
||||
DEFINE_GUID(IID_IInWindowStream,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200010000")
|
||||
IInWindowStream: public IUnknown
|
||||
struct IInWindowStream: public IUnknown
|
||||
{
|
||||
STDMETHOD(Init)(ISequentialInStream *inStream) PURE;
|
||||
STDMETHOD(SetStream)(ISequentialInStream *inStream) PURE;
|
||||
STDMETHOD_(void, ReleaseStream)() PURE;
|
||||
STDMETHOD(MovePos)() PURE;
|
||||
STDMETHOD(Init)() 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;
|
||||
STDMETHOD_(Int32, NeedChangeBufferPos)(UInt32 numCheckBytes) PURE;
|
||||
STDMETHOD_(void, ChangeBufferPos)() PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200020000}
|
||||
DEFINE_GUID(IID_IMatchFinder,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020000")
|
||||
IMatchFinder: public IInWindowStream
|
||||
struct IMatchFinder: public IInWindowStream
|
||||
{
|
||||
STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter) PURE;
|
||||
STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances) PURE;
|
||||
STDMETHOD_(void, DummyLongestMatch)() PURE;
|
||||
STDMETHOD(GetMatches)(UInt32 *distances) PURE;
|
||||
STDMETHOD(Skip)(UInt32 num) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200020100}
|
||||
DEFINE_GUID(IID_IMatchFinderCallback,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x01, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020100")
|
||||
IMatchFinderCallback: public IUnknown
|
||||
struct IMatchFinderSetNumPasses
|
||||
{
|
||||
STDMETHOD(BeforeChangingBufferPos)() PURE;
|
||||
STDMETHOD(AfterChangingBufferPos)() PURE;
|
||||
virtual void SetNumPasses(UInt32 numPasses) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200020200}
|
||||
DEFINE_GUID(IID_IMatchFinderSetCallback,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x02, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020200")
|
||||
IMatchFinderSetCallback: public IUnknown
|
||||
{
|
||||
STDMETHOD(SetCallback)(IMatchFinderCallback *callback) PURE;
|
||||
};
|
||||
|
||||
/*
|
||||
// {23170F69-40C1-278A-0000-000200030000}
|
||||
DEFINE_GUID(IID_IInitMatchFinder,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200030000")
|
||||
IMatchFinderInit: public IUnknown
|
||||
{
|
||||
STDMETHOD(InitMatchFinder)(IMatchFinder *matchFinder) PURE;
|
||||
};
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,22 +16,27 @@ bool CLZInWindow::Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 kee
|
|||
{
|
||||
_keepSizeBefore = keepSizeBefore;
|
||||
_keepSizeAfter = keepSizeAfter;
|
||||
_keepSizeReserv = keepSizeReserv;
|
||||
UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
|
||||
if (_bufferBase == 0 || _blockSize != blockSize)
|
||||
{
|
||||
Free();
|
||||
_blockSize = blockSize;
|
||||
_bufferBase = (Byte *)::BigAlloc(_blockSize);
|
||||
if (_blockSize != 0)
|
||||
_bufferBase = (Byte *)::BigAlloc(_blockSize);
|
||||
}
|
||||
_pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter;
|
||||
if (_blockSize == 0)
|
||||
return true;
|
||||
return (_bufferBase != 0);
|
||||
}
|
||||
|
||||
|
||||
HRESULT CLZInWindow::Init(ISequentialInStream *stream)
|
||||
void CLZInWindow::SetStream(ISequentialInStream *stream)
|
||||
{
|
||||
_stream = stream;
|
||||
}
|
||||
|
||||
HRESULT CLZInWindow::Init()
|
||||
{
|
||||
_buffer = _bufferBase;
|
||||
_pos = 0;
|
||||
_streamPos = 0;
|
||||
|
@ -65,11 +70,11 @@ HRESULT CLZInWindow::ReadBlock()
|
|||
return S_OK;
|
||||
while(true)
|
||||
{
|
||||
UInt32 size = UInt32(_bufferBase - _buffer) + _blockSize - _streamPos;
|
||||
UInt32 size = (UInt32)(_bufferBase - _buffer) + _blockSize - _streamPos;
|
||||
if(size == 0)
|
||||
return S_OK;
|
||||
UInt32 numReadBytes;
|
||||
RINOK(_stream->ReadPart(_buffer + _streamPos, size, &numReadBytes));
|
||||
RINOK(_stream->Read(_buffer + _streamPos, size, &numReadBytes));
|
||||
if(numReadBytes == 0)
|
||||
{
|
||||
_posLimit = _streamPos;
|
||||
|
@ -90,10 +95,11 @@ HRESULT CLZInWindow::ReadBlock()
|
|||
|
||||
void CLZInWindow::MoveBlock()
|
||||
{
|
||||
BeforeMoveBlock();
|
||||
UInt32 offset = UInt32(_buffer - _bufferBase) + _pos - _keepSizeBefore;
|
||||
UInt32 numBytes = UInt32(_buffer - _bufferBase) + _streamPos - offset;
|
||||
UInt32 offset = (UInt32)(_buffer - _bufferBase) + _pos - _keepSizeBefore;
|
||||
// we need one additional byte, since MovePos moves on 1 byte.
|
||||
if (offset > 0)
|
||||
offset--;
|
||||
UInt32 numBytes = (UInt32)(_buffer - _bufferBase) + _streamPos - offset;
|
||||
memmove(_bufferBase, _bufferBase + offset, numBytes);
|
||||
_buffer -= offset;
|
||||
AfterMoveBlock();
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ class CLZInWindow
|
|||
{
|
||||
Byte *_bufferBase; // pointer to buffer with data
|
||||
ISequentialInStream *_stream;
|
||||
UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
|
||||
UInt32 _posLimit; // offset (from _buffer) when new block reading must be done
|
||||
bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
|
||||
const Byte *_pointerToLastSafePosition;
|
||||
protected:
|
||||
|
@ -18,22 +18,20 @@ protected:
|
|||
UInt32 _pos; // offset (from _buffer) of curent byte
|
||||
UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
|
||||
UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
|
||||
UInt32 _keepSizeReserv; // how many BYTEs must be kept as reserv
|
||||
UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream
|
||||
|
||||
virtual void BeforeMoveBlock() {};
|
||||
virtual void AfterMoveBlock() {};
|
||||
void MoveBlock();
|
||||
virtual HRESULT ReadBlock();
|
||||
HRESULT ReadBlock();
|
||||
void Free();
|
||||
public:
|
||||
CLZInWindow(): _bufferBase(0) {}
|
||||
virtual ~CLZInWindow() { Free(); }
|
||||
|
||||
bool Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter,
|
||||
UInt32 keepSizeReserv = (1<<17));
|
||||
// keepSizeBefore + keepSizeAfter + keepSizeReserv < 4G)
|
||||
bool Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv = (1<<17));
|
||||
|
||||
HRESULT Init(ISequentialInStream *stream);
|
||||
void SetStream(ISequentialInStream *stream);
|
||||
HRESULT Init();
|
||||
// void ReleaseStream();
|
||||
|
||||
Byte *GetBuffer() const { return _buffer; }
|
||||
|
@ -53,17 +51,17 @@ public:
|
|||
else
|
||||
return S_OK;
|
||||
}
|
||||
Byte GetIndexByte(Int32 index)const
|
||||
{ return _buffer[(size_t)_pos + index]; }
|
||||
Byte GetIndexByte(Int32 index) const { return _buffer[(size_t)_pos + index]; }
|
||||
|
||||
// index + limit have not to exceed _keepSizeAfter;
|
||||
// -2G <= index < 2G
|
||||
UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) const
|
||||
{
|
||||
if(_streamEndWasReached)
|
||||
if ((_pos + index) + limit > _streamPos)
|
||||
limit = _streamPos - (_pos + index);
|
||||
distance++;
|
||||
Byte *pby = _buffer + (size_t)_pos + index;
|
||||
const Byte *pby = _buffer + (size_t)_pos + index;
|
||||
UInt32 i;
|
||||
for(i = 0; i < limit && pby[i] == pby[(size_t)i - distance]; i++);
|
||||
return i;
|
||||
|
@ -79,6 +77,11 @@ public:
|
|||
_streamPos -= subValue;
|
||||
}
|
||||
|
||||
bool NeedMove(UInt32 numCheckBytes)
|
||||
{
|
||||
UInt32 reserv = _pointerToLastSafePosition - (_buffer + _pos);
|
||||
return (reserv <= numCheckBytes);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,84 +5,13 @@
|
|||
#include "../../../Common/Alloc.h"
|
||||
#include "LZOutWindow.h"
|
||||
|
||||
bool CLZOutWindow::Create(UInt32 windowSize)
|
||||
void CLZOutWindow::Init(bool solid)
|
||||
{
|
||||
_pos = 0;
|
||||
_streamPos = 0;
|
||||
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)
|
||||
{
|
||||
// ReleaseStream();
|
||||
_stream = stream;
|
||||
// _stream->AddRef();
|
||||
|
||||
if(!solid)
|
||||
{
|
||||
_streamPos = 0;
|
||||
_pos = 0;
|
||||
}
|
||||
COutBuffer::Init();
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
ErrorCode = S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
void CLZOutWindow::ReleaseStream()
|
||||
{
|
||||
if(_stream != 0)
|
||||
{
|
||||
// Flush(); // Test it
|
||||
_stream->Release();
|
||||
_stream = 0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
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;
|
||||
if(size == 0)
|
||||
return S_OK;
|
||||
#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;
|
||||
if (size != processedSize)
|
||||
return E_FAIL;
|
||||
if (_pos >= _windowSize)
|
||||
_pos = 0;
|
||||
_streamPos = _pos;
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -4,66 +4,51 @@
|
|||
#define __LZ_OUT_WINDOW_H
|
||||
|
||||
#include "../../IStream.h"
|
||||
#include "../../Common/OutBuffer.h"
|
||||
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
class CLZOutWindowException
|
||||
{
|
||||
public:
|
||||
HRESULT ErrorCode;
|
||||
CLZOutWindowException(HRESULT errorCode): ErrorCode(errorCode) {}
|
||||
};
|
||||
typedef COutBufferException CLZOutWindowException;
|
||||
#endif
|
||||
|
||||
class CLZOutWindow
|
||||
class CLZOutWindow: public COutBuffer
|
||||
{
|
||||
Byte *_buffer;
|
||||
UInt32 _pos;
|
||||
UInt32 _windowSize;
|
||||
UInt32 _streamPos;
|
||||
ISequentialOutStream *_stream;
|
||||
void FlushWithCheck();
|
||||
public:
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
HRESULT ErrorCode;
|
||||
#endif
|
||||
|
||||
void Free();
|
||||
CLZOutWindow(): _buffer(0), _stream(0) {}
|
||||
~CLZOutWindow() { Free(); /* ReleaseStream(); */ }
|
||||
bool Create(UInt32 windowSize);
|
||||
void Init(bool solid = false);
|
||||
|
||||
void Init(ISequentialOutStream *stream, bool solid = false);
|
||||
HRESULT Flush();
|
||||
// void ReleaseStream();
|
||||
|
||||
void CopyBlock(UInt32 distance, UInt32 len)
|
||||
// distance >= 0, len > 0,
|
||||
bool CopyBlock(UInt32 distance, UInt32 len)
|
||||
{
|
||||
UInt32 pos = _pos - distance - 1;
|
||||
if (pos >= _windowSize)
|
||||
pos += _windowSize;
|
||||
for(; len > 0; len--)
|
||||
if (distance >= _pos)
|
||||
{
|
||||
if (pos >= _windowSize)
|
||||
if (!_overDict || distance >= _bufferSize)
|
||||
return false;
|
||||
pos += _bufferSize;
|
||||
}
|
||||
do
|
||||
{
|
||||
if (pos == _bufferSize)
|
||||
pos = 0;
|
||||
_buffer[_pos++] = _buffer[pos++];
|
||||
if (_pos >= _windowSize)
|
||||
if (_pos == _limitPos)
|
||||
FlushWithCheck();
|
||||
// PutOneByte(GetOneByte(distance));
|
||||
}
|
||||
while(--len != 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PutByte(Byte b)
|
||||
{
|
||||
_buffer[_pos++] = b;
|
||||
if (_pos >= _windowSize)
|
||||
if (_pos == _limitPos)
|
||||
FlushWithCheck();
|
||||
}
|
||||
|
||||
Byte GetByte(UInt32 distance) const
|
||||
{
|
||||
UInt32 pos = _pos - distance - 1;
|
||||
if (pos >= _windowSize)
|
||||
pos += _windowSize;
|
||||
if (pos >= _bufferSize)
|
||||
pos += _bufferSize;
|
||||
return _buffer[pos];
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,6 +3,4 @@
|
|||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../../Platform.h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
void UpdateMatch() { Index = kMatchNextStates[Index]; }
|
||||
void UpdateRep() { Index = kRepNextStates[Index]; }
|
||||
void UpdateShortRep() { Index = kShortRepNextStates[Index]; }
|
||||
bool IsCharState() const { return Index < 7; }
|
||||
};
|
||||
|
||||
const int kNumPosSlotBits = 6;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -21,13 +21,11 @@ class CBaseState
|
|||
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;
|
||||
}
|
||||
|
@ -53,23 +51,23 @@ struct COptimal
|
|||
};
|
||||
|
||||
|
||||
extern Byte g_FastPos[1024];
|
||||
extern Byte g_FastPos[1 << 11];
|
||||
inline UInt32 GetPosSlot(UInt32 pos)
|
||||
{
|
||||
if (pos < (1 << 10))
|
||||
if (pos < (1 << 11))
|
||||
return g_FastPos[pos];
|
||||
if (pos < (1 << 19))
|
||||
return g_FastPos[pos >> 9] + 18;
|
||||
return g_FastPos[pos >> 18] + 36;
|
||||
if (pos < (1 << 21))
|
||||
return g_FastPos[pos >> 10] + 20;
|
||||
return g_FastPos[pos >> 20] + 40;
|
||||
}
|
||||
|
||||
inline UInt32 GetPosSlot2(UInt32 pos)
|
||||
{
|
||||
if (pos < (1 << 16))
|
||||
if (pos < (1 << 17))
|
||||
return g_FastPos[pos >> 6] + 12;
|
||||
if (pos < (1 << 25))
|
||||
return g_FastPos[pos >> 15] + 30;
|
||||
return g_FastPos[pos >> 24] + 48;
|
||||
if (pos < (1 << 27))
|
||||
return g_FastPos[pos >> 16] + 32;
|
||||
return g_FastPos[pos >> 26] + 52;
|
||||
}
|
||||
|
||||
const UInt32 kIfinityPrice = 0xFFFFFFF;
|
||||
|
@ -107,8 +105,7 @@ public:
|
|||
}
|
||||
bool Create(int numPosBits, int numPrevBits)
|
||||
{
|
||||
if (_coders == 0 || (numPosBits + numPrevBits) !=
|
||||
(_numPrevBits + _numPosBits) )
|
||||
if (_coders == 0 || (numPosBits + numPrevBits) != (_numPrevBits + _numPosBits))
|
||||
{
|
||||
Free();
|
||||
UInt32 numStates = 1 << (numPosBits + numPrevBits);
|
||||
|
@ -125,21 +122,8 @@ public:
|
|||
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); }
|
||||
{ return &_coders[((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits))]; }
|
||||
};
|
||||
|
||||
namespace NLength {
|
||||
|
@ -147,31 +131,29 @@ 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;
|
||||
CMyBitEncoder _choice2;
|
||||
NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesEncodingMax];
|
||||
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;
|
||||
void SetPrices(UInt32 posState, UInt32 numSymbols, UInt32 *prices) const;
|
||||
};
|
||||
|
||||
const UInt32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols;
|
||||
|
||||
class CPriceTableEncoder: public CEncoder
|
||||
{
|
||||
UInt32 _prices[kNumSymbolsTotal][kNumPosStatesEncodingMax];
|
||||
UInt32 _prices[kNumPosStatesEncodingMax][kNumSymbolsTotal];
|
||||
UInt32 _tableSize;
|
||||
UInt32 _counters[kNumPosStatesEncodingMax];
|
||||
public:
|
||||
void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; }
|
||||
UInt32 GetPrice(UInt32 symbol, UInt32 posState) const
|
||||
{ return _prices[symbol][posState]; }
|
||||
UInt32 GetPrice(UInt32 symbol, UInt32 posState) const { return _prices[posState][symbol]; }
|
||||
void UpdateTable(UInt32 posState)
|
||||
{
|
||||
for (UInt32 len = 0; len < _tableSize; len++)
|
||||
_prices[len][posState] = CEncoder::GetPrice(len, posState);
|
||||
SetPrices(posState, _tableSize, _prices[posState]);
|
||||
_counters[posState] = _tableSize;
|
||||
}
|
||||
void UpdateTables(UInt32 numPosStates)
|
||||
|
@ -179,20 +161,20 @@ public:
|
|||
for (UInt32 posState = 0; posState < numPosStates; posState++)
|
||||
UpdateTable(posState);
|
||||
}
|
||||
void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState)
|
||||
void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState, bool updatePrice)
|
||||
{
|
||||
CEncoder::Encode(rangeEncoder, symbol, posState);
|
||||
if (--_counters[posState] == 0)
|
||||
UpdateTable(posState);
|
||||
if (updatePrice)
|
||||
if (--_counters[posState] == 0)
|
||||
UpdateTable(posState);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
class CEncoder :
|
||||
public ICompressCoder,
|
||||
// public IInitMatchFinder,
|
||||
public ICompressSetOutStream,
|
||||
public ICompressSetCoderProperties,
|
||||
public ICompressWriteCoderProperties,
|
||||
public CBaseState,
|
||||
|
@ -201,8 +183,6 @@ class CEncoder :
|
|||
COptimal _optimum[kNumOpts];
|
||||
CMyComPtr<IMatchFinder> _matchFinder; // test it
|
||||
NRangeCoder::CEncoder _rangeEncoder;
|
||||
public:
|
||||
private:
|
||||
|
||||
CMyBitEncoder _isMatch[kNumStates][NLength::kNumPosStatesEncodingMax];
|
||||
CMyBitEncoder _isRep[kNumStates];
|
||||
|
@ -221,12 +201,13 @@ private:
|
|||
|
||||
CLiteralEncoder _literalEncoder;
|
||||
|
||||
UInt32 _matchDistances[kMatchMaxLen + 1];
|
||||
UInt32 _matchDistances[kMatchMaxLen * 2 + 2 + 1];
|
||||
|
||||
bool _fastMode;
|
||||
bool _maxMode;
|
||||
// bool _maxMode;
|
||||
UInt32 _numFastBytes;
|
||||
UInt32 _longestMatchLength;
|
||||
UInt32 _numDistancePairs;
|
||||
|
||||
UInt32 _additionalOffset;
|
||||
|
||||
|
@ -254,11 +235,12 @@ private:
|
|||
UInt32 _dictionarySizePrev;
|
||||
UInt32 _numFastBytesPrev;
|
||||
|
||||
UInt64 lastPosSlotFillingPos;
|
||||
UInt32 _matchPriceCount;
|
||||
UInt64 nowPos64;
|
||||
bool _finished;
|
||||
ISequentialInStream *_inStream;
|
||||
|
||||
UInt32 _matchFinderCycles;
|
||||
int _matchFinderIndex;
|
||||
#ifdef COMPRESS_MF_MT
|
||||
bool _multiThread;
|
||||
|
@ -267,36 +249,50 @@ private:
|
|||
bool _writeEndMark;
|
||||
|
||||
bool _needReleaseMFStream;
|
||||
|
||||
IMatchFinderSetNumPasses *setMfPasses;
|
||||
|
||||
void ReleaseMatchFinder()
|
||||
{
|
||||
setMfPasses = 0;
|
||||
_matchFinder.Release();
|
||||
}
|
||||
|
||||
HRESULT ReadMatchDistances(UInt32 &len);
|
||||
HRESULT ReadMatchDistances(UInt32 &len, UInt32 &numDistancePairs);
|
||||
|
||||
HRESULT MovePos(UInt32 num);
|
||||
UInt32 GetRepLen1Price(CState state, UInt32 posState) const
|
||||
{
|
||||
return _isRepG0[state.Index].GetPrice(0) +
|
||||
_isRep0Long[state.Index][posState].GetPrice(0);
|
||||
return _isRepG0[state.Index].GetPrice0() +
|
||||
_isRep0Long[state.Index][posState].GetPrice0();
|
||||
}
|
||||
UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, CState state, UInt32 posState) const
|
||||
|
||||
UInt32 GetPureRepPrice(UInt32 repIndex, CState state, UInt32 posState) const
|
||||
{
|
||||
UInt32 price = _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState);
|
||||
UInt32 price;
|
||||
if(repIndex == 0)
|
||||
{
|
||||
price += _isRepG0[state.Index].GetPrice(0);
|
||||
price += _isRep0Long[state.Index][posState].GetPrice(1);
|
||||
price = _isRepG0[state.Index].GetPrice0();
|
||||
price += _isRep0Long[state.Index][posState].GetPrice1();
|
||||
}
|
||||
else
|
||||
{
|
||||
price += _isRepG0[state.Index].GetPrice(1);
|
||||
price = _isRepG0[state.Index].GetPrice1();
|
||||
if (repIndex == 1)
|
||||
price += _isRepG1[state.Index].GetPrice(0);
|
||||
price += _isRepG1[state.Index].GetPrice0();
|
||||
else
|
||||
{
|
||||
price += _isRepG1[state.Index].GetPrice(1);
|
||||
price += _isRepG1[state.Index].GetPrice1();
|
||||
price += _isRepG2[state.Index].GetPrice(repIndex - 2);
|
||||
}
|
||||
}
|
||||
return price;
|
||||
}
|
||||
UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, CState state, UInt32 posState) const
|
||||
{
|
||||
return _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState) +
|
||||
GetPureRepPrice(repIndex, state, posState);
|
||||
}
|
||||
/*
|
||||
UInt32 GetPosLen2Price(UInt32 pos, UInt32 posState) const
|
||||
{
|
||||
|
@ -318,8 +314,6 @@ private:
|
|||
*/
|
||||
UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) const
|
||||
{
|
||||
if (len == 2 && pos >= 0x80)
|
||||
return kIfinityPrice;
|
||||
UInt32 price;
|
||||
UInt32 lenToPosState = GetLenToPosState(len);
|
||||
if (pos < kNumFullDistances)
|
||||
|
@ -334,21 +328,25 @@ private:
|
|||
HRESULT GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes);
|
||||
HRESULT GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes);
|
||||
|
||||
void FillPosSlotPrices();
|
||||
void FillDistancesPrices();
|
||||
void FillAlignPrices();
|
||||
|
||||
void ReleaseStreams()
|
||||
void ReleaseMFStream()
|
||||
{
|
||||
if (_matchFinder && _needReleaseMFStream)
|
||||
{
|
||||
_matchFinder->ReleaseStream();
|
||||
_needReleaseMFStream = false;
|
||||
}
|
||||
// _rangeEncoder.ReleaseStream();
|
||||
}
|
||||
|
||||
HRESULT Flush();
|
||||
void ReleaseStreams()
|
||||
{
|
||||
ReleaseMFStream();
|
||||
ReleaseOutStream();
|
||||
}
|
||||
|
||||
HRESULT Flush(UInt32 nowPos);
|
||||
class CCoderReleaser
|
||||
{
|
||||
CEncoder *_coder;
|
||||
|
@ -370,13 +368,13 @@ public:
|
|||
|
||||
HRESULT Create();
|
||||
|
||||
MY_UNKNOWN_IMP2(
|
||||
MY_UNKNOWN_IMP3(
|
||||
ICompressSetOutStream,
|
||||
ICompressSetCoderProperties,
|
||||
ICompressWriteCoderProperties
|
||||
)
|
||||
|
||||
STDMETHOD(Init)(
|
||||
ISequentialOutStream *outStream);
|
||||
HRESULT Init();
|
||||
|
||||
// ICompressCoder interface
|
||||
HRESULT SetStreams(ISequentialInStream *inStream,
|
||||
|
@ -395,9 +393,6 @@ public:
|
|||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// IInitMatchFinder interface
|
||||
STDMETHOD(InitMatchFinder)(IMatchFinder *matchFinder);
|
||||
|
||||
// ICompressSetCoderProperties2
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties);
|
||||
|
@ -405,6 +400,9 @@ public:
|
|||
// ICompressWriteCoderProperties
|
||||
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
|
||||
|
||||
STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
|
||||
STDMETHOD(ReleaseOutStream)();
|
||||
|
||||
virtual ~CEncoder() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../../Platform.h"
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -14,20 +14,21 @@ const UInt32 kTopValue = (1 << kNumTopBits);
|
|||
|
||||
class CEncoder
|
||||
{
|
||||
UInt64 Low;
|
||||
UInt32 Range;
|
||||
UInt32 _ffNum;
|
||||
UInt32 _cacheSize;
|
||||
Byte _cache;
|
||||
public:
|
||||
UInt64 Low;
|
||||
UInt32 Range;
|
||||
COutBuffer Stream;
|
||||
bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
|
||||
|
||||
void Init(ISequentialOutStream *stream)
|
||||
void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
|
||||
void Init()
|
||||
{
|
||||
Stream.Init(stream);
|
||||
Stream.Init();
|
||||
Low = 0;
|
||||
Range = 0xFFFFFFFF;
|
||||
_ffNum = 0;
|
||||
_cacheSize = 1;
|
||||
_cache = 0;
|
||||
}
|
||||
|
||||
|
@ -40,10 +41,7 @@ public:
|
|||
|
||||
HRESULT FlushStream() { return Stream.Flush(); }
|
||||
|
||||
/*
|
||||
void ReleaseStream()
|
||||
{ Stream.ReleaseStream(); }
|
||||
*/
|
||||
void ReleaseStream() { Stream.ReleaseStream(); }
|
||||
|
||||
void Encode(UInt32 start, UInt32 size, UInt32 total)
|
||||
{
|
||||
|
@ -56,36 +54,21 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void EncodeDirectBitsDiv(UInt32 value, UInt32 numTotalBits)
|
||||
{
|
||||
Low += value * (Range >>= numTotalBits);
|
||||
Normalize();
|
||||
}
|
||||
|
||||
void EncodeDirectBitsDiv2(UInt32 value, UInt32 numTotalBits)
|
||||
{
|
||||
if (numTotalBits <= kNumBottomBits)
|
||||
EncodeDirectBitsDiv(value, numTotalBits);
|
||||
else
|
||||
{
|
||||
EncodeDirectBitsDiv(value >> kNumBottomBits, (numTotalBits - kNumBottomBits));
|
||||
EncodeDirectBitsDiv(value & ((1 << kBottomValueBits) - 1), kNumBottomBits);
|
||||
}
|
||||
}
|
||||
*/
|
||||
void ShiftLow()
|
||||
{
|
||||
if (Low < (UInt32)0xFF000000 || UInt32(Low >> 32) == 1)
|
||||
if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0)
|
||||
{
|
||||
Stream.WriteByte(Byte(_cache + Byte(Low >> 32)));
|
||||
for (;_ffNum != 0; _ffNum--)
|
||||
Stream.WriteByte(Byte(0xFF + Byte(Low >> 32)));
|
||||
_cache = Byte(UInt32(Low) >> 24);
|
||||
Byte temp = _cache;
|
||||
do
|
||||
{
|
||||
Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32)));
|
||||
temp = 0xFF;
|
||||
}
|
||||
while(--_cacheSize != 0);
|
||||
_cache = (Byte)((UInt32)Low >> 24);
|
||||
}
|
||||
else
|
||||
_ffNum++;
|
||||
Low = UInt32(Low) << 8;
|
||||
_cacheSize++;
|
||||
Low = (UInt32)Low << 8;
|
||||
}
|
||||
|
||||
void EncodeDirectBits(UInt32 value, int numTotalBits)
|
||||
|
@ -120,7 +103,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _ffNum; }
|
||||
UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; }
|
||||
};
|
||||
|
||||
class CDecoder
|
||||
|
@ -140,16 +123,17 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void Init(ISequentialInStream *stream)
|
||||
void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
|
||||
void Init()
|
||||
{
|
||||
Stream.Init(stream);
|
||||
Stream.Init();
|
||||
Code = 0;
|
||||
Range = 0xFFFFFFFF;
|
||||
for(int i = 0; i < 5; i++)
|
||||
Code = (Code << 8) | Stream.ReadByte();
|
||||
}
|
||||
|
||||
// void ReleaseStream() { Stream.ReleaseStream(); }
|
||||
void ReleaseStream() { Stream.ReleaseStream(); }
|
||||
|
||||
UInt32 GetThreshold(UInt32 total)
|
||||
{
|
||||
|
@ -163,32 +147,12 @@ public:
|
|||
Normalize();
|
||||
}
|
||||
|
||||
/*
|
||||
UInt32 DecodeDirectBitsDiv(UInt32 numTotalBits)
|
||||
{
|
||||
Range >>= numTotalBits;
|
||||
UInt32 threshold = Code / Range;
|
||||
Code -= threshold * Range;
|
||||
|
||||
Normalize();
|
||||
return threshold;
|
||||
}
|
||||
|
||||
UInt32 DecodeDirectBitsDiv2(UInt32 numTotalBits)
|
||||
{
|
||||
if (numTotalBits <= kNumBottomBits)
|
||||
return DecodeDirectBitsDiv(numTotalBits);
|
||||
UInt32 result = DecodeDirectBitsDiv(numTotalBits - kNumBottomBits) << kNumBottomBits;
|
||||
return (result | DecodeDirectBitsDiv(kNumBottomBits));
|
||||
}
|
||||
*/
|
||||
|
||||
UInt32 DecodeDirectBits(UInt32 numTotalBits)
|
||||
UInt32 DecodeDirectBits(int numTotalBits)
|
||||
{
|
||||
UInt32 range = Range;
|
||||
UInt32 code = Code;
|
||||
UInt32 result = 0;
|
||||
for (UInt32 i = numTotalBits; i > 0; i--)
|
||||
for (int i = numTotalBits; i != 0; i--)
|
||||
{
|
||||
range >>= 1;
|
||||
/*
|
||||
|
@ -201,7 +165,6 @@ public:
|
|||
*/
|
||||
UInt32 t = (code - range) >> 31;
|
||||
code -= range & (t - 1);
|
||||
// range = rangeTmp + ((range & 1) & (1 - t));
|
||||
result = (result << 1) | (1 - t);
|
||||
|
||||
if (range < kTopValue)
|
||||
|
|
|
@ -50,9 +50,10 @@ class CBitEncoder: public CBitModel<numMoveBits>
|
|||
public:
|
||||
void Encode(CEncoder *encoder, UInt32 symbol)
|
||||
{
|
||||
/*
|
||||
encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
|
||||
this->UpdateModel(symbol);
|
||||
/*
|
||||
*/
|
||||
UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
|
||||
if (symbol == 0)
|
||||
{
|
||||
|
@ -65,18 +66,19 @@ public:
|
|||
encoder->Range -= newBound;
|
||||
this->Prob -= (this->Prob) >> numMoveBits;
|
||||
}
|
||||
while (encoder->Range < kTopValue)
|
||||
if (encoder->Range < kTopValue)
|
||||
{
|
||||
encoder->Range <<= 8;
|
||||
encoder->ShiftLow();
|
||||
}
|
||||
*/
|
||||
}
|
||||
UInt32 GetPrice(UInt32 symbol) const
|
||||
{
|
||||
return CPriceTables::ProbPrices[
|
||||
(((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
|
||||
}
|
||||
UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; }
|
||||
UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
namespace NCompress {
|
||||
namespace NRangeCoder {
|
||||
|
||||
template <int numMoveBits, UInt32 NumBitLevels>
|
||||
template <int numMoveBits, int NumBitLevels>
|
||||
class CBitTreeEncoder
|
||||
{
|
||||
CBitEncoder<numMoveBits> Models[1 << NumBitLevels];
|
||||
|
@ -22,7 +22,7 @@ public:
|
|||
void Encode(CEncoder *rangeEncoder, UInt32 symbol)
|
||||
{
|
||||
UInt32 modelIndex = 1;
|
||||
for (UInt32 bitIndex = NumBitLevels; bitIndex > 0 ;)
|
||||
for (int bitIndex = NumBitLevels; bitIndex != 0 ;)
|
||||
{
|
||||
bitIndex--;
|
||||
UInt32 bit = (symbol >> bitIndex) & 1;
|
||||
|
@ -33,7 +33,7 @@ public:
|
|||
void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol)
|
||||
{
|
||||
UInt32 modelIndex = 1;
|
||||
for (UInt32 i = 0; i < NumBitLevels; i++)
|
||||
for (int i = 0; i < NumBitLevels; i++)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
Models[modelIndex].Encode(rangeEncoder, bit);
|
||||
|
@ -43,14 +43,12 @@ public:
|
|||
}
|
||||
UInt32 GetPrice(UInt32 symbol) const
|
||||
{
|
||||
symbol |= (1 << NumBitLevels);
|
||||
UInt32 price = 0;
|
||||
UInt32 modelIndex = 1;
|
||||
for (UInt32 bitIndex = NumBitLevels; bitIndex > 0 ;)
|
||||
while (symbol != 1)
|
||||
{
|
||||
bitIndex--;
|
||||
UInt32 bit = (symbol >> bitIndex) & 1;
|
||||
price += Models[modelIndex].GetPrice(bit);
|
||||
modelIndex = (modelIndex << 1) + bit;
|
||||
price += Models[symbol >> 1].GetPrice(symbol & 1);
|
||||
symbol >>= 1;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
@ -58,7 +56,7 @@ public:
|
|||
{
|
||||
UInt32 price = 0;
|
||||
UInt32 modelIndex = 1;
|
||||
for (UInt32 i = NumBitLevels; i > 0; i--)
|
||||
for (int i = NumBitLevels; i != 0; i--)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
|
@ -69,7 +67,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template <int numMoveBits, UInt32 NumBitLevels>
|
||||
template <int numMoveBits, int NumBitLevels>
|
||||
class CBitTreeDecoder
|
||||
{
|
||||
CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
|
||||
|
@ -83,7 +81,7 @@ public:
|
|||
{
|
||||
UInt32 modelIndex = 1;
|
||||
RC_INIT_VAR
|
||||
for(UInt32 bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
|
||||
for(int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--)
|
||||
{
|
||||
// modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
|
||||
RC_GETBIT(numMoveBits, Models[modelIndex].Prob, modelIndex)
|
||||
|
@ -96,7 +94,7 @@ public:
|
|||
UInt32 modelIndex = 1;
|
||||
UInt32 symbol = 0;
|
||||
RC_INIT_VAR
|
||||
for(UInt32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
{
|
||||
// UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
|
||||
// modelIndex <<= 1;
|
||||
|
@ -111,10 +109,10 @@ public:
|
|||
|
||||
template <int numMoveBits>
|
||||
void ReverseBitTreeEncode(CBitEncoder<numMoveBits> *Models,
|
||||
CEncoder *rangeEncoder, UInt32 NumBitLevels, UInt32 symbol)
|
||||
CEncoder *rangeEncoder, int NumBitLevels, UInt32 symbol)
|
||||
{
|
||||
UInt32 modelIndex = 1;
|
||||
for (UInt32 i = 0; i < NumBitLevels; i++)
|
||||
for (int i = 0; i < NumBitLevels; i++)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
Models[modelIndex].Encode(rangeEncoder, bit);
|
||||
|
@ -129,7 +127,7 @@ UInt32 ReverseBitTreeGetPrice(CBitEncoder<numMoveBits> *Models,
|
|||
{
|
||||
UInt32 price = 0;
|
||||
UInt32 modelIndex = 1;
|
||||
for (UInt32 i = NumBitLevels; i > 0; i--)
|
||||
for (int i = NumBitLevels; i != 0; i--)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
|
@ -141,12 +139,12 @@ UInt32 ReverseBitTreeGetPrice(CBitEncoder<numMoveBits> *Models,
|
|||
|
||||
template <int numMoveBits>
|
||||
UInt32 ReverseBitTreeDecode(CBitDecoder<numMoveBits> *Models,
|
||||
CDecoder *rangeDecoder, UInt32 NumBitLevels)
|
||||
CDecoder *rangeDecoder, int NumBitLevels)
|
||||
{
|
||||
UInt32 modelIndex = 1;
|
||||
UInt32 symbol = 0;
|
||||
RC_INIT_VAR
|
||||
for(UInt32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
{
|
||||
// UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
|
||||
// modelIndex <<= 1;
|
||||
|
|
|
@ -3,6 +3,4 @@
|
|||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../../Platform.h"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -5,33 +5,27 @@
|
|||
|
||||
#include "IStream.h"
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200040000}
|
||||
DEFINE_GUID(IID_ICompressProgressInfo,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200040000")
|
||||
ICompressProgressInfo: public IUnknown
|
||||
// "23170F69-40C1-278A-0000-000400xx0000"
|
||||
#define CODER_INTERFACE(i, x) \
|
||||
DEFINE_GUID(IID_ ## i, \
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x04, 0x00, x, 0x00, 0x00); \
|
||||
struct i: public IUnknown
|
||||
|
||||
CODER_INTERFACE(ICompressProgressInfo, 0x04)
|
||||
{
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) = 0;
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200050000}
|
||||
DEFINE_GUID(IID_ICompressCoder,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200050000")
|
||||
ICompressCoder: public IUnknown
|
||||
CODER_INTERFACE(ICompressCoder, 0x05)
|
||||
{
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize,
|
||||
const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress) = 0;
|
||||
ICompressProgressInfo *progress) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200180000}
|
||||
DEFINE_GUID(IID_ICompressCoder2,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x18, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200180000")
|
||||
ICompressCoder2: public IUnknown
|
||||
CODER_INTERFACE(ICompressCoder2, 0x18)
|
||||
{
|
||||
STDMETHOD(Code)(ISequentialInStream **inStreams,
|
||||
const UInt64 **inSizes,
|
||||
|
@ -54,75 +48,100 @@ namespace NCoderPropID
|
|||
kLitPosBits,
|
||||
kNumFastBytes = 0x450,
|
||||
kMatchFinder,
|
||||
kMatchFinderCycles,
|
||||
kNumPasses = 0x460,
|
||||
kAlgorithm = 0x470,
|
||||
kMultiThread = 0x480,
|
||||
kNumThreads,
|
||||
kEndMarker = 0x490
|
||||
};
|
||||
}
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200200000}
|
||||
DEFINE_GUID(IID_ICompressSetCoderProperties,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200200000")
|
||||
ICompressSetCoderProperties: public IUnknown
|
||||
CODER_INTERFACE(ICompressSetCoderProperties, 0x20)
|
||||
{
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200210000}
|
||||
DEFINE_GUID(IID_ICompressSetDecoderProperties,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x21, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200210000")
|
||||
ICompressSetDecoderProperties: public IUnknown
|
||||
/*
|
||||
CODER_INTERFACE(ICompressSetCoderProperties, 0x21)
|
||||
{
|
||||
STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;
|
||||
};
|
||||
*/
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200230000}
|
||||
DEFINE_GUID(IID_ICompressWriteCoderProperties,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x23, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200230000")
|
||||
ICompressWriteCoderProperties: public IUnknown
|
||||
CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22)
|
||||
{
|
||||
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE;
|
||||
};
|
||||
|
||||
CODER_INTERFACE(ICompressWriteCoderProperties, 0x23)
|
||||
{
|
||||
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStreams) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200240000}
|
||||
DEFINE_GUID(IID_ICompressGetInStreamProcessedSize,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x24, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200240000")
|
||||
ICompressGetInStreamProcessedSize: public IUnknown
|
||||
CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24)
|
||||
{
|
||||
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000200250000}
|
||||
DEFINE_GUID(IID_ICompressGetSubStreamSize,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x25, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000200250000")
|
||||
ICompressGetSubStreamSize: public IUnknown
|
||||
CODER_INTERFACE(ICompressSetCoderMt, 0x25)
|
||||
{
|
||||
STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE;
|
||||
};
|
||||
|
||||
CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
|
||||
{
|
||||
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
|
||||
CODER_INTERFACE(ICompressSetInStream, 0x31)
|
||||
{
|
||||
STDMETHOD(SetInStream)(ISequentialInStream *inStream, const UInt64 *inSize) PURE;
|
||||
STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE;
|
||||
STDMETHOD(ReleaseInStream)() 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
|
||||
CODER_INTERFACE(ICompressSetOutStream, 0x32)
|
||||
{
|
||||
STDMETHOD(SetOutStream)(ISequentialOutStream *outStream, const UInt64 *outSize) PURE;
|
||||
STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE;
|
||||
STDMETHOD(ReleaseOutStream)() PURE;
|
||||
};
|
||||
|
||||
CODER_INTERFACE(ICompressSetInStreamSize, 0x33)
|
||||
{
|
||||
STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE;
|
||||
};
|
||||
|
||||
CODER_INTERFACE(ICompressSetOutStreamSize, 0x34)
|
||||
{
|
||||
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE;
|
||||
};
|
||||
|
||||
CODER_INTERFACE(ICompressFilter, 0x40)
|
||||
{
|
||||
STDMETHOD(Init)() PURE;
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE;
|
||||
// Filter return outSize (UInt32)
|
||||
// if (outSize <= size): Filter have converted outSize bytes
|
||||
// if (outSize > size): Filter have not converted anything.
|
||||
// and it needs at least outSize bytes to convert one block
|
||||
// (it's for crypto block algorithms).
|
||||
};
|
||||
|
||||
CODER_INTERFACE(ICryptoProperties, 0x80)
|
||||
{
|
||||
STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE;
|
||||
STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE;
|
||||
};
|
||||
|
||||
CODER_INTERFACE(ICryptoSetPassword, 0x90)
|
||||
{
|
||||
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE;
|
||||
};
|
||||
|
||||
CODER_INTERFACE(ICryptoSetCRC, 0xA0)
|
||||
{
|
||||
STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE;
|
||||
};
|
||||
|
||||
//////////////////////
|
||||
|
|
|
@ -1,79 +1,62 @@
|
|||
// IStream.h
|
||||
|
||||
#ifndef __ISTREAMS_H
|
||||
#define __ISTREAMS_H
|
||||
#ifndef __ISTREAM_H
|
||||
#define __ISTREAM_H
|
||||
|
||||
#include "../Common/MyUnknown.h"
|
||||
#include "../Common/Types.h"
|
||||
|
||||
// {23170F69-40C1-278A-0000-000000010000}
|
||||
DEFINE_GUID(IID_ISequentialInStream,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000000010000")
|
||||
ISequentialInStream : public IUnknown
|
||||
// "23170F69-40C1-278A-0000-000300xx0000"
|
||||
|
||||
#define STREAM_INTERFACE_SUB(i, b, x) \
|
||||
DEFINE_GUID(IID_ ## i, \
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x03, 0x00, x, 0x00, 0x00); \
|
||||
struct i: public b
|
||||
|
||||
#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x)
|
||||
|
||||
STREAM_INTERFACE(ISequentialInStream, 0x01)
|
||||
{
|
||||
public:
|
||||
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.
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE;
|
||||
/*
|
||||
Out: if size != 0, return_value = S_OK and (*processedSize == 0),
|
||||
then there are no more bytes in stream.
|
||||
if (size > 0) && there are bytes in stream,
|
||||
this function must read at least 1 byte.
|
||||
This function is allowed to read less than number of remaining bytes in stream.
|
||||
You must call Read function in loop, if you need exact amount of data
|
||||
*/
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000000020000}
|
||||
DEFINE_GUID(IID_ISequentialOutStream,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000000020000")
|
||||
ISequentialOutStream : public IUnknown
|
||||
STREAM_INTERFACE(ISequentialOutStream, 0x02)
|
||||
{
|
||||
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) PURE;
|
||||
/*
|
||||
if (size > 0) this function must write at least 1 byte.
|
||||
This function is allowed to write less than "size".
|
||||
You must call Write function in loop, if you need to write exact amount of data
|
||||
*/
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000000030000}
|
||||
DEFINE_GUID(IID_IInStream,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000000030000")
|
||||
IInStream : public ISequentialInStream
|
||||
STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03)
|
||||
{
|
||||
public:
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) = 0;
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000000040000}
|
||||
DEFINE_GUID(IID_IOutStream,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000000040000")
|
||||
IOutStream : public ISequentialOutStream
|
||||
STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04)
|
||||
{
|
||||
public:
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) = 0;
|
||||
STDMETHOD(SetSize)(Int64 newSize) = 0;
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
|
||||
STDMETHOD(SetSize)(Int64 newSize) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000000060000}
|
||||
DEFINE_GUID(IID_IStreamGetSize,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000000060000")
|
||||
IStreamGetSize : public IUnknown
|
||||
STREAM_INTERFACE(IStreamGetSize, 0x06)
|
||||
{
|
||||
public:
|
||||
STDMETHOD(GetSize)(UInt64 *size) = 0;
|
||||
STDMETHOD(GetSize)(UInt64 *size) PURE;
|
||||
};
|
||||
|
||||
// {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
|
||||
STREAM_INTERFACE(IOutStreamFlush, 0x07)
|
||||
{
|
||||
public:
|
||||
STDMETHOD(Flush)() = 0;
|
||||
STDMETHOD(Flush)() PURE;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,51 +2,117 @@
|
|||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#ifndef WIN32
|
||||
#ifdef _WIN32
|
||||
#include "MyWindows.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "Alloc.h"
|
||||
// #include "NewHandler.h"
|
||||
|
||||
void *MyAlloc(size_t size)
|
||||
/* #define _SZ_ALLOC_DEBUG */
|
||||
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
#include <stdio.h>
|
||||
int g_allocCount = 0;
|
||||
int g_allocCountMid = 0;
|
||||
int g_allocCountBig = 0;
|
||||
#endif
|
||||
|
||||
void *MyAlloc(size_t size) throw()
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount++);
|
||||
#endif
|
||||
return ::malloc(size);
|
||||
}
|
||||
|
||||
void MyFree(void *address)
|
||||
void MyFree(void *address) throw()
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
fprintf(stderr, "\nFree; count = %10d", --g_allocCount);
|
||||
#endif
|
||||
|
||||
::free(address);
|
||||
}
|
||||
|
||||
void *BigAlloc(size_t size)
|
||||
#ifdef _WIN32
|
||||
|
||||
void *MidAlloc(size_t size) throw()
|
||||
{
|
||||
#ifdef WIN32
|
||||
return ::VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
||||
#else
|
||||
return ::malloc(size);
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
|
||||
#endif
|
||||
return ::VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
void BigFree(void *address)
|
||||
void MidFree(void *address) throw()
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
|
||||
#endif
|
||||
if (address == 0)
|
||||
return;
|
||||
#ifdef WIN32
|
||||
::VirtualFree(address, 0, MEM_RELEASE);
|
||||
#else
|
||||
::free(address);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
void *BigAllocE(size_t size)
|
||||
static SIZE_T g_LargePageSize =
|
||||
#ifdef _WIN64
|
||||
(1 << 21);
|
||||
#else
|
||||
(1 << 22);
|
||||
#endif
|
||||
|
||||
typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
|
||||
|
||||
bool SetLargePageSize()
|
||||
{
|
||||
void *res = BigAlloc(size);
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
if (res == 0)
|
||||
throw CNewException();
|
||||
#endif
|
||||
return res;
|
||||
GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
|
||||
::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
|
||||
if (largePageMinimum == 0)
|
||||
return false;
|
||||
SIZE_T size = largePageMinimum();
|
||||
if (size == 0 || (size & (size - 1)) != 0)
|
||||
return false;
|
||||
g_LargePageSize = size;
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void *BigAlloc(size_t size) throw()
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
|
||||
#endif
|
||||
|
||||
if (size >= (1 << 18))
|
||||
{
|
||||
void *res = ::VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
|
||||
MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
|
||||
if (res != 0)
|
||||
return res;
|
||||
}
|
||||
return ::VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
void BigFree(void *address) throw()
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
|
||||
#endif
|
||||
|
||||
if (address == 0)
|
||||
return;
|
||||
::VirtualFree(address, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,10 +5,25 @@
|
|||
|
||||
#include <stddef.h>
|
||||
|
||||
void *MyAlloc(size_t size);
|
||||
void MyFree(void *address);
|
||||
void *BigAlloc(size_t size);
|
||||
void BigFree(void *address);
|
||||
// void *BigAllocE(size_t size);
|
||||
void *MyAlloc(size_t size) throw();
|
||||
void MyFree(void *address) throw();
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
bool SetLargePageSize();
|
||||
|
||||
void *MidAlloc(size_t size) throw();
|
||||
void MidFree(void *address) throw();
|
||||
void *BigAlloc(size_t size) throw();
|
||||
void BigFree(void *address) throw();
|
||||
|
||||
#else
|
||||
|
||||
#define MidAlloc(size) MyAlloc(size)
|
||||
#define MidFree(address) MyFree(address)
|
||||
#define BigAlloc(size) MyAlloc(size)
|
||||
#define BigFree(address) MyFree(address)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -28,24 +28,30 @@ public:
|
|||
CCRCTableInit() { CCRC::InitTable(); }
|
||||
} g_CRCTableInit;
|
||||
|
||||
void CCRC::Update(Byte b)
|
||||
void CCRC::UpdateByte(Byte b)
|
||||
{
|
||||
_value = Table[((Byte)(_value)) ^ b] ^ (_value >> 8);
|
||||
}
|
||||
|
||||
void CCRC::Update(UInt32 v)
|
||||
void CCRC::UpdateUInt16(UInt16 v)
|
||||
{
|
||||
UpdateByte(Byte(v));
|
||||
UpdateByte(Byte(v >> 8));
|
||||
}
|
||||
|
||||
void CCRC::UpdateUInt32(UInt32 v)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
Update((Byte)(v >> (8 * i)));
|
||||
UpdateByte((Byte)(v >> (8 * i)));
|
||||
}
|
||||
|
||||
void CCRC::Update(const UInt64 &v)
|
||||
void CCRC::UpdateUInt64(UInt64 v)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
Update((Byte)(v >> (8 * i)));
|
||||
UpdateByte((Byte)(v >> (8 * i)));
|
||||
}
|
||||
|
||||
void CCRC::Update(const void *data, UInt32 size)
|
||||
void CCRC::Update(const void *data, size_t size)
|
||||
{
|
||||
UInt32 v = _value;
|
||||
const Byte *p = (const Byte *)data;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#ifndef __COMMON_CRC_H
|
||||
#define __COMMON_CRC_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "Types.h"
|
||||
|
||||
class CCRC
|
||||
|
@ -14,18 +15,19 @@ public:
|
|||
|
||||
CCRC(): _value(0xFFFFFFFF){};
|
||||
void Init() { _value = 0xFFFFFFFF; }
|
||||
void Update(Byte v);
|
||||
void Update(UInt32 v);
|
||||
void Update(const UInt64 &v);
|
||||
void Update(const void *data, UInt32 size);
|
||||
void UpdateByte(Byte v);
|
||||
void UpdateUInt16(UInt16 v);
|
||||
void UpdateUInt32(UInt32 v);
|
||||
void UpdateUInt64(UInt64 v);
|
||||
void Update(const void *data, size_t size);
|
||||
UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; }
|
||||
static UInt32 CalculateDigest(const void *data, UInt32 size)
|
||||
static UInt32 CalculateDigest(const void *data, size_t 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, size_t size)
|
||||
{
|
||||
return (CalculateDigest(data, size) == digest);
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
_p = NULL;
|
||||
return pt;
|
||||
}
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
|
||||
{
|
||||
return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
|
||||
|
@ -148,8 +148,10 @@ public:
|
|||
|
||||
#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
|
||||
(REFGUID iid, void **outObject) {
|
||||
|
||||
#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \
|
||||
{ *outObject = (void *)(i *)this; AddRef(); return S_OK; }
|
||||
|
||||
#define MY_QUERYINTERFACE_END return E_NOINTERFACE; }
|
||||
|
||||
#define MY_ADDREF_RELEASE \
|
||||
|
@ -164,7 +166,9 @@ STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
|
|||
MY_ADDREF_RELEASE
|
||||
|
||||
|
||||
#define MY_UNKNOWN_IMP MY_UNKNOWN_IMP_SPEC(;)
|
||||
#define MY_UNKNOWN_IMP STDMETHOD(QueryInterface)(REFGUID, void **) { \
|
||||
MY_QUERYINTERFACE_END \
|
||||
MY_ADDREF_RELEASE
|
||||
|
||||
#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \
|
||||
MY_QUERYINTERFACE_ENTRY(i) \
|
||||
|
@ -174,11 +178,13 @@ STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
|
|||
MY_QUERYINTERFACE_ENTRY(i1) \
|
||||
MY_QUERYINTERFACE_ENTRY(i2) \
|
||||
)
|
||||
|
||||
#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \
|
||||
MY_QUERYINTERFACE_ENTRY(i1) \
|
||||
MY_QUERYINTERFACE_ENTRY(i2) \
|
||||
MY_QUERYINTERFACE_ENTRY(i3) \
|
||||
)
|
||||
|
||||
#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \
|
||||
MY_QUERYINTERFACE_ENTRY(i1) \
|
||||
MY_QUERYINTERFACE_ENTRY(i2) \
|
||||
|
|
54
Source/7zip/Common/MyGuidDef.h
Normal file
54
Source/7zip/Common/MyGuidDef.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
// Common/MyGuidDef.h
|
||||
|
||||
#ifndef GUID_DEFINED
|
||||
#define GUID_DEFINED
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
typedef struct {
|
||||
UInt32 Data1;
|
||||
UInt16 Data2;
|
||||
UInt16 Data3;
|
||||
unsigned char Data4[8];
|
||||
} GUID;
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define REFGUID const GUID &
|
||||
#else
|
||||
#define REFGUID const GUID *
|
||||
#endif
|
||||
|
||||
#define REFCLSID REFGUID
|
||||
#define REFIID REFGUID
|
||||
|
||||
#ifdef __cplusplus
|
||||
inline bool operator==(REFGUID g1, REFGUID g2)
|
||||
{
|
||||
for (int i = 0; i < (int)sizeof(g1); i++)
|
||||
if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
inline bool operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); }
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define MY_EXTERN_C extern "C"
|
||||
#else
|
||||
#define MY_EXTERN_C extern
|
||||
#endif
|
||||
|
||||
#endif // GUID_DEFINED
|
||||
|
||||
|
||||
#ifdef DEFINE_GUID
|
||||
#undef DEFINE_GUID
|
||||
#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
|
|
@ -3,9 +3,8 @@
|
|||
#ifndef __MYUNKNOWN_H
|
||||
#define __MYUNKNOWN_H
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
|
||||
// #include <guiddef.h>
|
||||
#ifdef _WIN32_WCE
|
||||
#if (_WIN32_WCE > 300)
|
||||
#include <basetyps.h>
|
||||
|
|
|
@ -3,21 +3,71 @@
|
|||
#ifndef __MYWINDOWS_H
|
||||
#define __MYWINDOWS_H
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../../Platform.h"
|
||||
|
||||
#include "Types.h"
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/*
|
||||
#define CHAR_PATH_SEPARATOR '\\'
|
||||
#define WCHAR_PATH_SEPARATOR L'\\'
|
||||
#define STRING_PATH_SEPARATOR "\\"
|
||||
#define WSTRING_PATH_SEPARATOR L"\\"
|
||||
*/
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
#define CHAR_PATH_SEPARATOR '/'
|
||||
#define WCHAR_PATH_SEPARATOR L'/'
|
||||
#define STRING_PATH_SEPARATOR "/"
|
||||
#define WSTRING_PATH_SEPARATOR L"/"
|
||||
|
||||
#include <stddef.h> // for wchar_t
|
||||
#include <string.h>
|
||||
*/
|
||||
#include "MyGuidDef.h"
|
||||
/*
|
||||
typedef char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
|
||||
#undef BYTE
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
|
||||
#undef WORD
|
||||
typedef unsigned short WORD;
|
||||
typedef short VARIANT_BOOL;
|
||||
|
||||
typedef wchar_t OLECHAR;
|
||||
typedef int INT;
|
||||
typedef Int32 INT32;
|
||||
typedef unsigned int UINT;
|
||||
typedef UInt32 UINT32;
|
||||
typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit
|
||||
typedef UINT32 ULONG;
|
||||
|
||||
#undef DWORD
|
||||
typedef UINT32 DWORD;
|
||||
|
||||
typedef Int64 LONGLONG;
|
||||
typedef UInt64 ULONGLONG;
|
||||
|
||||
typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER;
|
||||
typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER;
|
||||
|
||||
typedef const CHAR *LPCSTR;
|
||||
typedef CHAR TCHAR;
|
||||
typedef const TCHAR *LPCTSTR;
|
||||
typedef wchar_t WCHAR;
|
||||
typedef WCHAR OLECHAR;
|
||||
typedef const WCHAR *LPCWSTR;
|
||||
typedef OLECHAR *BSTR;
|
||||
typedef const OLECHAR *LPCOLESTR;
|
||||
typedef OLECHAR *LPOLESTR;
|
||||
|
||||
*/
|
||||
typedef struct _FILETIME
|
||||
{
|
||||
DWORD dwLowDateTime;
|
||||
|
@ -31,6 +81,7 @@ typedef LONG SCODE;
|
|||
|
||||
#define S_OK ((HRESULT)0x00000000L)
|
||||
#define S_FALSE ((HRESULT)0x00000001L)
|
||||
#define E_NOTIMPL ((HRESULT)0x80004001L)
|
||||
#define E_NOINTERFACE ((HRESULT)0x80004002L)
|
||||
#define E_ABORT ((HRESULT)0x80004004L)
|
||||
#define E_FAIL ((HRESULT)0x80004005L)
|
||||
|
@ -51,46 +102,7 @@ typedef LONG SCODE;
|
|||
|
||||
#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
|
||||
#define REFGUID const GUID &
|
||||
#else
|
||||
#define REFGUID const GUID * __MIDL_CONST
|
||||
#endif
|
||||
|
||||
#define REFCLSID REFGUID
|
||||
#define REFIID REFGUID
|
||||
|
||||
#define MIDL_INTERFACE(x) struct
|
||||
inline bool operator==(REFGUID g1, REFGUID g2)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(g1); i++)
|
||||
if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
inline bool operator!=(REFGUID g1, REFGUID g2)
|
||||
{ return !(g1 == g2); }
|
||||
|
||||
struct IUnknown
|
||||
{
|
||||
|
@ -164,20 +176,20 @@ typedef struct tagPROPVARIANT
|
|||
};
|
||||
} PROPVARIANT;
|
||||
|
||||
typedef tagPROPVARIANT tagVARIANT;
|
||||
typedef PROPVARIANT tagVARIANT;
|
||||
typedef tagVARIANT VARIANT;
|
||||
typedef VARIANT VARIANTARG;
|
||||
|
||||
BSTR SysAllocStringByteLen(LPCSTR psz, unsigned int len);
|
||||
BSTR SysAllocString(const OLECHAR *sz);
|
||||
void SysFreeString(BSTR bstr);
|
||||
UINT SysStringByteLen(BSTR bstr);
|
||||
UINT SysStringLen(BSTR bstr);
|
||||
MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);
|
||||
MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz);
|
||||
MY_EXTERN_C void SysFreeString(BSTR bstr);
|
||||
MY_EXTERN_C UINT SysStringByteLen(BSTR bstr);
|
||||
MY_EXTERN_C UINT SysStringLen(BSTR bstr);
|
||||
|
||||
DWORD GetLastError();
|
||||
HRESULT VariantClear(VARIANTARG *prop);
|
||||
HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src);
|
||||
LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2);
|
||||
MY_EXTERN_C DWORD GetLastError();
|
||||
MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop);
|
||||
MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src);
|
||||
MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2);
|
||||
|
||||
#define CP_ACP 0
|
||||
#define CP_OEMCP 1
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../Platform.h"
|
||||
// #include "MyWindows.h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,17 +3,55 @@
|
|||
#ifndef __COMMON_TYPES_H
|
||||
#define __COMMON_TYPES_H
|
||||
|
||||
#ifndef _7ZIP_BYTE_DEFINED
|
||||
#define _7ZIP_BYTE_DEFINED
|
||||
typedef unsigned char Byte;
|
||||
#endif
|
||||
|
||||
#ifndef _7ZIP_INT16_DEFINED
|
||||
#define _7ZIP_INT16_DEFINED
|
||||
typedef short Int16;
|
||||
#endif
|
||||
|
||||
#ifndef _7ZIP_UINT16_DEFINED
|
||||
#define _7ZIP_UINT16_DEFINED
|
||||
typedef unsigned short UInt16;
|
||||
#endif
|
||||
|
||||
#ifndef _7ZIP_INT32_DEFINED
|
||||
#define _7ZIP_INT32_DEFINED
|
||||
typedef int Int32;
|
||||
#endif
|
||||
|
||||
#ifndef _7ZIP_UINT32_DEFINED
|
||||
#define _7ZIP_UINT32_DEFINED
|
||||
typedef unsigned int UInt32;
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#ifndef _7ZIP_INT64_DEFINED
|
||||
#define _7ZIP_INT64_DEFINED
|
||||
typedef __int64 Int64;
|
||||
#endif
|
||||
|
||||
#ifndef _7ZIP_UINT64_DEFINED
|
||||
#define _7ZIP_UINT64_DEFINED
|
||||
typedef unsigned __int64 UInt64;
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifndef _7ZIP_INT64_DEFINED
|
||||
#define _7ZIP_INT64_DEFINED
|
||||
typedef long long int Int64;
|
||||
#endif
|
||||
|
||||
#ifndef _7ZIP_UINT64_DEFINED
|
||||
#define _7ZIP_UINT64_DEFINED
|
||||
typedef unsigned long long int UInt64;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
167
Source/7zip/sdk.diff
Normal file
167
Source/7zip/sdk.diff
Normal file
|
@ -0,0 +1,167 @@
|
|||
Only in 7zip: 7zGuids.cpp
|
||||
Only in 7zip-orig/7zip: Archive
|
||||
Only in 7zip/7zip: CVS
|
||||
Only in 7zip/7zip/Common: CVS
|
||||
Only in 7zip-orig/7zip/Common: FileStreams.cpp
|
||||
Only in 7zip-orig/7zip/Common: FileStreams.h
|
||||
diff -ru 7zip-orig/7zip/Common/StdAfx.h 7zip/7zip/Common/StdAfx.h
|
||||
--- 7zip-orig/7zip/Common/StdAfx.h Mon Jul 11 15:14:54 2005
|
||||
+++ 7zip/7zip/Common/StdAfx.h Mon Oct 16 10:39:10 2006
|
||||
@@ -4,6 +4,5 @@
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../Common/MyWindows.h"
|
||||
-#include "../../Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
Only in 7zip-orig/7zip/Compress: Branch
|
||||
Only in 7zip/7zip/Compress: CVS
|
||||
Only in 7zip/7zip/Compress/LZ/BinTree: BinTree3ZMain.h
|
||||
Only in 7zip/7zip/Compress/LZ/BinTree: BinTree4b.h
|
||||
Only in 7zip/7zip/Compress/LZ/BinTree: BinTreeMF.h
|
||||
Only in 7zip/7zip/Compress/LZ/BinTree: BinTreeMFMain.h
|
||||
Only in 7zip/7zip/Compress/LZ/BinTree: CVS
|
||||
Only in 7zip/7zip/Compress/LZ: CVS
|
||||
Only in 7zip-orig/7zip/Compress/LZ: HashChain
|
||||
Only in 7zip/7zip/Compress/LZMA: CVS
|
||||
Only in 7zip-orig/7zip/Compress/LZMA: LZMADecoder.cpp
|
||||
Only in 7zip-orig/7zip/Compress/LZMA: LZMADecoder.h
|
||||
diff -ru 7zip-orig/7zip/Compress/LZMA/LZMAEncoder.cpp 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp
|
||||
--- 7zip-orig/7zip/Compress/LZMA/LZMAEncoder.cpp Sat May 20 08:23:48 2006
|
||||
+++ 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp Mon Oct 16 10:26:43 2006
|
||||
@@ -55,13 +55,13 @@
|
||||
kHC4
|
||||
};
|
||||
|
||||
-static const wchar_t *kMatchFinderIDs[] =
|
||||
+/*static const wchar_t *kMatchFinderIDs[] =
|
||||
{
|
||||
L"BT2",
|
||||
L"BT3",
|
||||
L"BT4",
|
||||
L"HC4"
|
||||
-};
|
||||
+};*/
|
||||
|
||||
Byte g_FastPos[1 << 11];
|
||||
|
||||
@@ -318,7 +318,7 @@
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
-static bool AreStringsEqual(const wchar_t *base, const wchar_t *testString)
|
||||
+/*static bool AreStringsEqual(const wchar_t *base, const wchar_t *testString)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
@@ -340,7 +340,7 @@
|
||||
if (AreStringsEqual(kMatchFinderIDs[m], s))
|
||||
return m;
|
||||
return -1;
|
||||
-}
|
||||
+}*/
|
||||
|
||||
STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties)
|
||||
@@ -378,7 +378,8 @@
|
||||
}
|
||||
case NCoderPropID::kMatchFinder:
|
||||
{
|
||||
- if (prop.vt != VT_BSTR)
|
||||
+ return E_NOTIMPL;
|
||||
+ /*if (prop.vt != VT_BSTR)
|
||||
return E_INVALIDARG;
|
||||
int matchFinderIndexPrev = _matchFinderIndex;
|
||||
int m = FindMatchFinder(prop.bstrVal);
|
||||
@@ -390,7 +391,7 @@
|
||||
_dictionarySizePrev = (UInt32)-1;
|
||||
ReleaseMatchFinder();
|
||||
}
|
||||
- break;
|
||||
+ break;*/
|
||||
}
|
||||
#ifdef COMPRESS_MF_MT
|
||||
case NCoderPropID::kMultiThread:
|
||||
Only in 7zip-orig/7zip/Compress: LZMA_Alone
|
||||
Only in 7zip-orig/7zip/Compress: LZMA_C
|
||||
Only in 7zip/7zip/Compress/RangeCoder: CVS
|
||||
Only in 7zip: CVS
|
||||
Only in 7zip/Common: CVS
|
||||
Only in 7zip-orig/Common: C_FileIO.cpp
|
||||
Only in 7zip-orig/Common: C_FileIO.h
|
||||
Only in 7zip-orig/Common: ComTry.h
|
||||
Only in 7zip-orig/Common: CommandLineParser.cpp
|
||||
Only in 7zip-orig/Common: CommandLineParser.h
|
||||
Only in 7zip-orig/Common: MyInitGuid.h
|
||||
diff -ru 7zip-orig/Common/MyWindows.h 7zip/Common/MyWindows.h
|
||||
--- 7zip-orig/Common/MyWindows.h Sun Apr 16 16:53:43 2006
|
||||
+++ 7zip/Common/MyWindows.h Mon Oct 16 10:20:04 2006
|
||||
@@ -3,17 +3,22 @@
|
||||
#ifndef __MYWINDOWS_H
|
||||
#define __MYWINDOWS_H
|
||||
|
||||
+#include "../../Platform.h"
|
||||
+
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
+/*
|
||||
#define CHAR_PATH_SEPARATOR '\\'
|
||||
#define WCHAR_PATH_SEPARATOR L'\\'
|
||||
#define STRING_PATH_SEPARATOR "\\"
|
||||
#define WSTRING_PATH_SEPARATOR L"\\"
|
||||
+*/
|
||||
|
||||
#else
|
||||
|
||||
+/*
|
||||
#define CHAR_PATH_SEPARATOR '/'
|
||||
#define WCHAR_PATH_SEPARATOR L'/'
|
||||
#define STRING_PATH_SEPARATOR "/"
|
||||
@@ -21,9 +26,9 @@
|
||||
|
||||
#include <stddef.h> // for wchar_t
|
||||
#include <string.h>
|
||||
-
|
||||
+*/
|
||||
#include "MyGuidDef.h"
|
||||
-
|
||||
+/*
|
||||
typedef char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
|
||||
@@ -62,7 +67,7 @@
|
||||
typedef OLECHAR *BSTR;
|
||||
typedef const OLECHAR *LPCOLESTR;
|
||||
typedef OLECHAR *LPOLESTR;
|
||||
-
|
||||
+*/
|
||||
typedef struct _FILETIME
|
||||
{
|
||||
DWORD dwLowDateTime;
|
||||
Only in 7zip-orig/Common: NewHandler.cpp
|
||||
Only in 7zip-orig/Common: NewHandler.h
|
||||
diff -ru 7zip-orig/Common/StdAfx.h 7zip/Common/StdAfx.h
|
||||
--- 7zip-orig/Common/StdAfx.h Mon Jul 11 15:16:00 2005
|
||||
+++ 7zip/Common/StdAfx.h Mon Oct 16 10:39:16 2006
|
||||
@@ -4,6 +4,5 @@
|
||||
#define __STDAFX_H
|
||||
|
||||
// #include "MyWindows.h"
|
||||
-#include "NewHandler.h"
|
||||
|
||||
#endif
|
||||
Only in 7zip-orig/Common: String.cpp
|
||||
Only in 7zip-orig/Common: String.h
|
||||
Only in 7zip-orig/Common: StringConvert.cpp
|
||||
Only in 7zip-orig/Common: StringConvert.h
|
||||
Only in 7zip-orig/Common: StringToInt.cpp
|
||||
Only in 7zip-orig/Common: StringToInt.h
|
||||
Only in 7zip-orig/Common: Vector.cpp
|
||||
Only in 7zip-orig/Common: Vector.h
|
||||
Only in 7zip: LZMADecode.c
|
||||
Only in 7zip: LZMADecode.h
|
||||
Only in 7zip-orig: Windows
|
||||
Only in 7zip: copying.txt
|
||||
Only in 7zip: readme.txt
|
Loading…
Add table
Add a link
Reference in a new issue