mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 22:07:07 -06:00
4.48 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
0b33f700a6
commit
fd8b1d78b4
@@ -5,9 +5,9 @@
|
||||
#include "../../Common/RegisterCodec.h"
|
||||
|
||||
#include "x86_2.h"
|
||||
static void *CreateCodec() { return (void *)(ICompressCoder2 *)(new CBCJ2_x86_Decoder()); }
|
||||
static void *CreateCodec() { return (void *)(ICompressCoder2 *)(new NCompress::NBcj2::CDecoder()); }
|
||||
#ifndef EXTRACT_ONLY
|
||||
static void *CreateCodecOut() { return (void *)(ICompressCoder2 *)(new CBCJ2_x86_Encoder()); }
|
||||
static void *CreateCodecOut() { return (void *)(ICompressCoder2 *)(new NCompress::NBcj2::CEncoder()); }
|
||||
#else
|
||||
#define CreateCodecOut 0
|
||||
#endif
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 1);
|
||||
return (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, 1);
|
||||
}
|
||||
|
||||
UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 0);
|
||||
return (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, 0);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,7 @@ extern "C"
|
||||
struct CBranch86
|
||||
{
|
||||
UInt32 _prevMask;
|
||||
UInt32 _prevPos;
|
||||
void x86Init() { x86_Convert_Init(_prevMask, _prevPos); }
|
||||
void x86Init() { x86_Convert_Init(_prevMask); }
|
||||
};
|
||||
|
||||
MyClassB(BCJ_x86, 0x01, 3, CBranch86 ,
|
||||
|
||||
@@ -8,10 +8,12 @@ extern "C"
|
||||
#include "../../../../C/Alloc.h"
|
||||
}
|
||||
|
||||
inline bool IsJcc(Byte b0, Byte b1)
|
||||
{
|
||||
return (b0 == 0x0F && (b1 & 0xF0) == 0x80);
|
||||
}
|
||||
namespace NCompress {
|
||||
namespace NBcj2 {
|
||||
|
||||
inline bool IsJcc(Byte b0, Byte b1) { return (b0 == 0x0F && (b1 & 0xF0) == 0x80); }
|
||||
inline bool IsJ(Byte b0, Byte b1) { return ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)); }
|
||||
inline unsigned GetIndex(Byte b0, Byte b1) { return ((b1 == 0xE8) ? b0 : ((b1 == 0xE9) ? 256 : 257)); }
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
|
||||
@@ -22,7 +24,7 @@ static bool inline Test86MSByte(Byte b)
|
||||
return (b == 0 || b == 0xFF);
|
||||
}
|
||||
|
||||
bool CBCJ2_x86_Encoder::Create()
|
||||
bool CEncoder::Create()
|
||||
{
|
||||
if (!_mainStream.Create(1 << 16))
|
||||
return false;
|
||||
@@ -41,12 +43,12 @@ bool CBCJ2_x86_Encoder::Create()
|
||||
return true;
|
||||
}
|
||||
|
||||
CBCJ2_x86_Encoder::~CBCJ2_x86_Encoder()
|
||||
CEncoder::~CEncoder()
|
||||
{
|
||||
::MidFree(_buffer);
|
||||
}
|
||||
|
||||
HRESULT CBCJ2_x86_Encoder::Flush()
|
||||
HRESULT CEncoder::Flush()
|
||||
{
|
||||
RINOK(_mainStream.Flush());
|
||||
RINOK(_callStream.Flush());
|
||||
@@ -57,7 +59,7 @@ HRESULT CBCJ2_x86_Encoder::Flush()
|
||||
|
||||
const UInt32 kDefaultLimit = (1 << 24);
|
||||
|
||||
HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
|
||||
HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
@@ -91,10 +93,8 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
|
||||
_jumpStream.Init();
|
||||
_rangeEncoder.SetStream(outStreams[3]);
|
||||
_rangeEncoder.Init();
|
||||
for (int i = 0; i < 256; i++)
|
||||
_statusE8Encoder[i].Init();
|
||||
_statusE9Encoder.Init();
|
||||
_statusJccEncoder.Init();
|
||||
for (int i = 0; i < 256 + 2; i++)
|
||||
_statusEncoder[i].Init();
|
||||
CCoderReleaser releaser(this);
|
||||
|
||||
CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;
|
||||
@@ -135,12 +135,19 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
|
||||
{
|
||||
Byte b = _buffer[bufferPos];
|
||||
_mainStream.WriteByte(b);
|
||||
UInt32 index;
|
||||
if (b == 0xE8)
|
||||
_statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0);
|
||||
index = prevByte;
|
||||
else if (b == 0xE9)
|
||||
_statusE9Encoder.Encode(&_rangeEncoder, 0);
|
||||
index = 256;
|
||||
else if (IsJcc(prevByte, b))
|
||||
_statusJccEncoder.Encode(&_rangeEncoder, 0);
|
||||
index = 257;
|
||||
else
|
||||
{
|
||||
prevByte = b;
|
||||
continue;
|
||||
}
|
||||
_statusEncoder[index].Encode(&_rangeEncoder, 0);
|
||||
prevByte = b;
|
||||
}
|
||||
return Flush();
|
||||
@@ -153,7 +160,7 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
|
||||
{
|
||||
Byte b = _buffer[bufferPos];
|
||||
_mainStream.WriteByte(b);
|
||||
if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))
|
||||
if (!IsJ(prevByte, b))
|
||||
{
|
||||
bufferPos++;
|
||||
prevByte = b;
|
||||
@@ -209,40 +216,19 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
|
||||
convert = (dest < inSize);
|
||||
else
|
||||
convert = Test86MSByte(nextByte);
|
||||
unsigned index = GetIndex(prevByte, b);
|
||||
if (convert)
|
||||
{
|
||||
if (b == 0xE8)
|
||||
_statusE8Encoder[prevByte].Encode(&_rangeEncoder, 1);
|
||||
else if (b == 0xE9)
|
||||
_statusE9Encoder.Encode(&_rangeEncoder, 1);
|
||||
else
|
||||
_statusJccEncoder.Encode(&_rangeEncoder, 1);
|
||||
|
||||
_statusEncoder[index].Encode(&_rangeEncoder, 1);
|
||||
bufferPos += 5;
|
||||
if (b == 0xE8)
|
||||
{
|
||||
_callStream.WriteByte((Byte)(dest >> 24));
|
||||
_callStream.WriteByte((Byte)(dest >> 16));
|
||||
_callStream.WriteByte((Byte)(dest >> 8));
|
||||
_callStream.WriteByte((Byte)(dest));
|
||||
}
|
||||
else
|
||||
{
|
||||
_jumpStream.WriteByte((Byte)(dest >> 24));
|
||||
_jumpStream.WriteByte((Byte)(dest >> 16));
|
||||
_jumpStream.WriteByte((Byte)(dest >> 8));
|
||||
_jumpStream.WriteByte((Byte)(dest));
|
||||
}
|
||||
COutBuffer &s = (b == 0xE8) ? _callStream : _jumpStream;
|
||||
for (int i = 24; i >= 0; i -= 8)
|
||||
s.WriteByte((Byte)(dest >> i));
|
||||
prevByte = nextByte;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (b == 0xE8)
|
||||
_statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0);
|
||||
else if (b == 0xE9)
|
||||
_statusE9Encoder.Encode(&_rangeEncoder, 0);
|
||||
else
|
||||
_statusJccEncoder.Encode(&_rangeEncoder, 0);
|
||||
_statusEncoder[index].Encode(&_rangeEncoder, 0);
|
||||
bufferPos++;
|
||||
prevByte = b;
|
||||
}
|
||||
@@ -262,7 +248,7 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams,
|
||||
STDMETHODIMP CEncoder::Code(ISequentialInStream **inStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
@@ -281,7 +267,7 @@ STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams,
|
||||
|
||||
#endif
|
||||
|
||||
HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams,
|
||||
HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams,
|
||||
const UInt64 ** /* inSizes */,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
@@ -315,10 +301,8 @@ HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams,
|
||||
_rangeDecoder.Init();
|
||||
_outStream.Init();
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
_statusE8Decoder[i].Init();
|
||||
_statusE9Decoder.Init();
|
||||
_statusJccDecoder.Init();
|
||||
for (int i = 0; i < 256 + 2; i++)
|
||||
_statusDecoder[i].Init();
|
||||
|
||||
CCoderReleaser releaser(this);
|
||||
|
||||
@@ -326,62 +310,38 @@ HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams,
|
||||
UInt32 processedBytes = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (processedBytes > (1 << 20) && progress != NULL)
|
||||
if (processedBytes >= (1 << 20) && progress != NULL)
|
||||
{
|
||||
UInt64 nowPos64 = _outStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(NULL, &nowPos64));
|
||||
processedBytes = 0;
|
||||
}
|
||||
processedBytes++;
|
||||
Byte b;
|
||||
if (!_mainInStream.ReadByte(b))
|
||||
return Flush();
|
||||
_outStream.WriteByte(b);
|
||||
if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))
|
||||
UInt32 i;
|
||||
Byte b = 0;
|
||||
const UInt32 kBurstSize = (1 << 18);
|
||||
for (i = 0; i < kBurstSize; i++)
|
||||
{
|
||||
if (!_mainInStream.ReadByte(b))
|
||||
return Flush();
|
||||
_outStream.WriteByte(b);
|
||||
if (IsJ(prevByte, b))
|
||||
break;
|
||||
prevByte = b;
|
||||
continue;
|
||||
}
|
||||
bool status;
|
||||
if (b == 0xE8)
|
||||
status = (_statusE8Decoder[prevByte].Decode(&_rangeDecoder) == 1);
|
||||
else if (b == 0xE9)
|
||||
status = (_statusE9Decoder.Decode(&_rangeDecoder) == 1);
|
||||
else
|
||||
status = (_statusJccDecoder.Decode(&_rangeDecoder) == 1);
|
||||
if (status)
|
||||
processedBytes += i;
|
||||
if (i == kBurstSize)
|
||||
continue;
|
||||
unsigned index = GetIndex(prevByte, b);
|
||||
if (_statusDecoder[index].Decode(&_rangeDecoder) == 1)
|
||||
{
|
||||
UInt32 src;
|
||||
if (b == 0xE8)
|
||||
UInt32 src = 0;
|
||||
CInBuffer &s = (b == 0xE8) ? _callStream : _jumpStream;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Byte b0;
|
||||
if(!_callStream.ReadByte(b0))
|
||||
return S_FALSE;
|
||||
src = ((UInt32)b0) << 24;
|
||||
if(!_callStream.ReadByte(b0))
|
||||
return S_FALSE;
|
||||
src |= ((UInt32)b0) << 16;
|
||||
if(!_callStream.ReadByte(b0))
|
||||
return S_FALSE;
|
||||
src |= ((UInt32)b0) << 8;
|
||||
if(!_callStream.ReadByte(b0))
|
||||
return S_FALSE;
|
||||
src |= ((UInt32)b0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Byte b0;
|
||||
if(!_jumpStream.ReadByte(b0))
|
||||
return S_FALSE;
|
||||
src = ((UInt32)b0) << 24;
|
||||
if(!_jumpStream.ReadByte(b0))
|
||||
return S_FALSE;
|
||||
src |= ((UInt32)b0) << 16;
|
||||
if(!_jumpStream.ReadByte(b0))
|
||||
return S_FALSE;
|
||||
src |= ((UInt32)b0) << 8;
|
||||
if(!_jumpStream.ReadByte(b0))
|
||||
if(!s.ReadByte(b0))
|
||||
return S_FALSE;
|
||||
src <<= 8;
|
||||
src |= ((UInt32)b0);
|
||||
}
|
||||
UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ;
|
||||
@@ -397,7 +357,7 @@ HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams,
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CBCJ2_x86_Decoder::Code(ISequentialInStream **inStreams,
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream **inStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
@@ -410,6 +370,9 @@ STDMETHODIMP CBCJ2_x86_Decoder::Code(ISequentialInStream **inStreams,
|
||||
return CodeReal(inStreams, inSizes, numInStreams,
|
||||
outStreams, outSizes,numOutStreams, progress);
|
||||
}
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(const COutBufferException &e) { return e.ErrorCode; }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -7,38 +7,28 @@
|
||||
#include "../RangeCoder/RangeCoderBit.h"
|
||||
#include "../../ICoder.h"
|
||||
|
||||
// {23170F69-40C1-278B-0303-010100000100}
|
||||
#define MyClass2_a(Name, id, subId, encodingId) \
|
||||
DEFINE_GUID(CLSID_CCompressConvert ## Name, \
|
||||
0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00);
|
||||
|
||||
#define MyClass_a(Name, id, subId) \
|
||||
MyClass2_a(Name ## _Encoder, id, subId, 0x01) \
|
||||
MyClass2_a(Name ## _Decoder, id, subId, 0x00)
|
||||
|
||||
MyClass_a(BCJ2_x86, 0x01, 0x1B)
|
||||
namespace NCompress {
|
||||
namespace NBcj2 {
|
||||
|
||||
const int kNumMoveBits = 5;
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
|
||||
class CBCJ2_x86_Encoder:
|
||||
class CEncoder:
|
||||
public ICompressCoder2,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
Byte *_buffer;
|
||||
public:
|
||||
CBCJ2_x86_Encoder(): _buffer(0) {};
|
||||
~CBCJ2_x86_Encoder();
|
||||
CEncoder(): _buffer(0) {};
|
||||
~CEncoder();
|
||||
bool Create();
|
||||
|
||||
COutBuffer _mainStream;
|
||||
COutBuffer _callStream;
|
||||
COutBuffer _jumpStream;
|
||||
NCompress::NRangeCoder::CEncoder _rangeEncoder;
|
||||
NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusE8Encoder[256];
|
||||
NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusE9Encoder;
|
||||
NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusJccEncoder;
|
||||
NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusEncoder[256 + 2];
|
||||
|
||||
HRESULT Flush();
|
||||
void ReleaseStreams()
|
||||
@@ -51,9 +41,9 @@ public:
|
||||
|
||||
class CCoderReleaser
|
||||
{
|
||||
CBCJ2_x86_Encoder *_coder;
|
||||
CEncoder *_coder;
|
||||
public:
|
||||
CCoderReleaser(CBCJ2_x86_Encoder *coder): _coder(coder) {}
|
||||
CCoderReleaser(CEncoder *coder): _coder(coder) {}
|
||||
~CCoderReleaser() { _coder->ReleaseStreams(); }
|
||||
};
|
||||
|
||||
@@ -79,7 +69,7 @@ public:
|
||||
|
||||
#endif
|
||||
|
||||
class CBCJ2_x86_Decoder:
|
||||
class CDecoder:
|
||||
public ICompressCoder2,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
@@ -88,9 +78,7 @@ public:
|
||||
CInBuffer _callStream;
|
||||
CInBuffer _jumpStream;
|
||||
NCompress::NRangeCoder::CDecoder _rangeDecoder;
|
||||
NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusE8Decoder[256];
|
||||
NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusE9Decoder;
|
||||
NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusJccDecoder;
|
||||
NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusDecoder[256 + 2];
|
||||
|
||||
COutBuffer _outStream;
|
||||
|
||||
@@ -106,9 +94,9 @@ public:
|
||||
HRESULT Flush() { return _outStream.Flush(); }
|
||||
class CCoderReleaser
|
||||
{
|
||||
CBCJ2_x86_Decoder *_coder;
|
||||
CDecoder *_coder;
|
||||
public:
|
||||
CCoderReleaser(CBCJ2_x86_Decoder *coder): _coder(coder) {}
|
||||
CCoderReleaser(CDecoder *coder): _coder(coder) {}
|
||||
~CCoderReleaser() { _coder->ReleaseStreams(); }
|
||||
};
|
||||
|
||||
@@ -130,4 +118,6 @@ public:
|
||||
ICompressProgressInfo *progress);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user