mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-09 06:07:05 -06:00
4.20
This commit is contained in:
committed by
Kornel Lesiński
parent
8c1b5c7b7e
commit
3c510ba80b
@@ -10,20 +10,17 @@ namespace NCompress{
|
||||
namespace NArj {
|
||||
namespace NDecoder1 {
|
||||
|
||||
static const UINT32 kHistorySize = 26624;
|
||||
static const UINT32 kMatchMaxLen = 256;
|
||||
static const UINT32 kMatchMinLen = 3;
|
||||
static const UInt32 kHistorySize = 26624;
|
||||
static const UInt32 kMatchMaxLen = 256;
|
||||
static const UInt32 kMatchMinLen = 3;
|
||||
|
||||
static const UINT32 kNC = 255 + kMatchMaxLen + 2 - kMatchMinLen;
|
||||
static const UInt32 kNC = 255 + kMatchMaxLen + 2 - kMatchMinLen;
|
||||
|
||||
CCoder::CCoder()
|
||||
{}
|
||||
|
||||
void CCoder::make_table(int nchar, BYTE *bitlen, int tablebits,
|
||||
UINT32 *table, int tablesize)
|
||||
void CCoder::MakeTable(int nchar, Byte *bitlen, int tablebits,
|
||||
UInt32 *table, int tablesize)
|
||||
{
|
||||
UINT32 count[17], weight[17], start[18], *p;
|
||||
UINT32 i, k, len, ch, jutbits, avail, nextcode, mask;
|
||||
UInt32 count[17], weight[17], start[18], *p;
|
||||
UInt32 i, k, len, ch, jutbits, avail, nextcode, mask;
|
||||
|
||||
for (i = 1; i <= 16; i++)
|
||||
count[i] = 0;
|
||||
@@ -33,7 +30,7 @@ void CCoder::make_table(int nchar, BYTE *bitlen, int tablebits,
|
||||
start[1] = 0;
|
||||
for (i = 1; i <= 16; i++)
|
||||
start[i + 1] = start[i] + (count[i] << (16 - i));
|
||||
if (start[17] != (UINT32) (1 << 16))
|
||||
if (start[17] != (UInt32) (1 << 16))
|
||||
throw "Data error";
|
||||
|
||||
jutbits = 16 - tablebits;
|
||||
@@ -49,7 +46,7 @@ void CCoder::make_table(int nchar, BYTE *bitlen, int tablebits,
|
||||
}
|
||||
|
||||
i = start[tablebits + 1] >> jutbits;
|
||||
if (i != (UINT32) (1 << 16))
|
||||
if (i != (UInt32) (1 << 16))
|
||||
{
|
||||
k = 1 << tablebits;
|
||||
while (i != k)
|
||||
@@ -66,7 +63,7 @@ void CCoder::make_table(int nchar, BYTE *bitlen, int tablebits,
|
||||
nextcode = k + weight[len];
|
||||
if ((int)len <= tablebits)
|
||||
{
|
||||
if (nextcode > (UINT32)tablesize)
|
||||
if (nextcode > (UInt32)tablesize)
|
||||
throw "Data error";
|
||||
for (i = start[len]; i < nextcode; i++)
|
||||
table[i] = ch;
|
||||
@@ -97,10 +94,10 @@ void CCoder::make_table(int nchar, BYTE *bitlen, int tablebits,
|
||||
|
||||
void CCoder::read_pt_len(int nn, int nbit, int i_special)
|
||||
{
|
||||
UINT32 n = m_InBitStream.ReadBits(nbit);
|
||||
UInt32 n = m_InBitStream.ReadBits(nbit);
|
||||
if (n == 0)
|
||||
{
|
||||
UINT32 c = m_InBitStream.ReadBits(nbit);
|
||||
UInt32 c = m_InBitStream.ReadBits(nbit);
|
||||
int i;
|
||||
for (i = 0; i < nn; i++)
|
||||
pt_len[i] = 0;
|
||||
@@ -109,14 +106,14 @@ void CCoder::read_pt_len(int nn, int nbit, int i_special)
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 i = 0;
|
||||
UInt32 i = 0;
|
||||
while (i < n)
|
||||
{
|
||||
UINT32 bitBuf = m_InBitStream.GetValue(16);
|
||||
UInt32 bitBuf = m_InBitStream.GetValue(16);
|
||||
int c = bitBuf >> 13;
|
||||
if (c == 7)
|
||||
{
|
||||
UINT32 mask = 1 << (12);
|
||||
UInt32 mask = 1 << (12);
|
||||
while (mask & bitBuf)
|
||||
{
|
||||
mask >>= 1;
|
||||
@@ -124,24 +121,24 @@ void CCoder::read_pt_len(int nn, int nbit, int i_special)
|
||||
}
|
||||
}
|
||||
m_InBitStream.MovePos((c < 7) ? 3 : (int)(c - 3));
|
||||
pt_len[i++] = (BYTE)c;
|
||||
if (i == (UINT32)i_special)
|
||||
pt_len[i++] = (Byte)c;
|
||||
if (i == (UInt32)i_special)
|
||||
{
|
||||
c = m_InBitStream.ReadBits(2);
|
||||
while (--c >= 0)
|
||||
pt_len[i++] = 0;
|
||||
}
|
||||
}
|
||||
while (i < (UINT32)nn)
|
||||
while (i < (UInt32)nn)
|
||||
pt_len[i++] = 0;
|
||||
make_table(nn, pt_len, 8, pt_table, PTABLESIZE);
|
||||
MakeTable(nn, pt_len, 8, pt_table, PTABLESIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void CCoder::read_c_len()
|
||||
{
|
||||
int i, c, n;
|
||||
UINT32 mask;
|
||||
UInt32 mask;
|
||||
|
||||
n = m_InBitStream.ReadBits(CBIT);
|
||||
if (n == 0)
|
||||
@@ -157,7 +154,7 @@ void CCoder::read_c_len()
|
||||
i = 0;
|
||||
while (i < n)
|
||||
{
|
||||
UINT32 bitBuf = m_InBitStream.GetValue(16);
|
||||
UInt32 bitBuf = m_InBitStream.GetValue(16);
|
||||
c = pt_table[bitBuf >> (8)];
|
||||
if (c >= NT)
|
||||
{
|
||||
@@ -184,18 +181,18 @@ void CCoder::read_c_len()
|
||||
c_len[i++] = 0;
|
||||
}
|
||||
else
|
||||
c_len[i++] = (BYTE)(c - 2);
|
||||
c_len[i++] = (Byte)(c - 2);
|
||||
}
|
||||
while (i < NC)
|
||||
c_len[i++] = 0;
|
||||
make_table(NC, c_len, 12, c_table, CTABLESIZE);
|
||||
MakeTable(NC, c_len, 12, c_table, CTABLESIZE);
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 CCoder::decode_c()
|
||||
UInt32 CCoder::decode_c()
|
||||
{
|
||||
UINT32 j, mask;
|
||||
UINT32 bitbuf = m_InBitStream.GetValue(16);
|
||||
UInt32 j, mask;
|
||||
UInt32 bitbuf = m_InBitStream.GetValue(16);
|
||||
j = c_table[bitbuf >> 4];
|
||||
if (j >= NC)
|
||||
{
|
||||
@@ -213,10 +210,10 @@ UINT32 CCoder::decode_c()
|
||||
return j;
|
||||
}
|
||||
|
||||
UINT32 CCoder::decode_p()
|
||||
UInt32 CCoder::decode_p()
|
||||
{
|
||||
UINT32 j, mask;
|
||||
UINT32 bitbuf = m_InBitStream.GetValue(16);
|
||||
UInt32 j, mask;
|
||||
UInt32 bitbuf = m_InBitStream.GetValue(16);
|
||||
j = pt_table[bitbuf >> (8)];
|
||||
if (j >= NP)
|
||||
{
|
||||
@@ -241,9 +238,17 @@ UINT32 CCoder::decode_p()
|
||||
|
||||
|
||||
STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (outSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!m_OutWindowStream.Create(kHistorySize))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!m_InBitStream.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
int size1 = sizeof(c_table) / sizeof(c_table[0]);
|
||||
for (int i = 0; i < size1; i++)
|
||||
{
|
||||
@@ -253,20 +258,16 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
c_table[i] = 0;
|
||||
}
|
||||
|
||||
if (outSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!m_OutWindowStream.IsCreated())
|
||||
{
|
||||
try { m_OutWindowStream.Create(kHistorySize); }
|
||||
catch(...) { return E_OUTOFMEMORY; }
|
||||
}
|
||||
UINT64 pos = 0;
|
||||
m_OutWindowStream.Init(outStream, false);
|
||||
m_InBitStream.Init(inStream);
|
||||
UInt64 pos = 0;
|
||||
m_OutWindowStream.SetStream(outStream);
|
||||
m_OutWindowStream.Init(false);
|
||||
m_InBitStream.SetStream(inStream);
|
||||
m_InBitStream.Init();
|
||||
|
||||
CCoderReleaser coderReleaser(this);
|
||||
|
||||
UINT32 blockSize = 0;
|
||||
UInt32 blockSize = 0;
|
||||
|
||||
while(pos < *outSize)
|
||||
{
|
||||
@@ -274,7 +275,7 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
{
|
||||
if (progress != NULL)
|
||||
{
|
||||
UINT64 packSize = m_InBitStream.GetProcessedSize();
|
||||
UInt64 packSize = m_InBitStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &pos));
|
||||
}
|
||||
blockSize = m_InBitStream.ReadBits(16);
|
||||
@@ -284,28 +285,29 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
}
|
||||
blockSize--;
|
||||
|
||||
UINT32 number = decode_c();
|
||||
UInt32 number = decode_c();
|
||||
if (number < 256)
|
||||
{
|
||||
m_OutWindowStream.PutOneByte(number);
|
||||
m_OutWindowStream.PutByte(number);
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 len = number - 256 + kMatchMinLen;
|
||||
UINT32 distance = decode_p();
|
||||
UInt32 len = number - 256 + kMatchMinLen;
|
||||
UInt32 distance = decode_p();
|
||||
if (distance >= pos)
|
||||
throw "data error";
|
||||
m_OutWindowStream.CopyBackBlock(distance, len);
|
||||
m_OutWindowStream.CopyBlock(distance, len);
|
||||
pos += len;
|
||||
}
|
||||
}
|
||||
coderReleaser.NeedFlush = false;
|
||||
return m_OutWindowStream.Flush();
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress);}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// Arj/Decoder1.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __COMPRESS_ARJ_DECODER1_H
|
||||
#define __COMPRESS_ARJ_DECODER1_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/MSBFDecoder.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
@@ -28,7 +26,7 @@ namespace NDecoder1 {
|
||||
#define MAXDICBIT 16
|
||||
#define MATCHBIT 8
|
||||
#define MAXMATCH 256
|
||||
#define NC (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD)
|
||||
#define NC (0xFF + MAXMATCH + 2 - THRESHOLD)
|
||||
#define NP (MAXDICBIT + 1)
|
||||
#define CBIT 9
|
||||
#define NT (CODE_BIT + 3)
|
||||
@@ -52,55 +50,53 @@ class CCoder :
|
||||
CLZOutWindow m_OutWindowStream;
|
||||
NStream::NMSBF::CDecoder<CInBuffer> m_InBitStream;
|
||||
|
||||
UINT32 left[2 * NC - 1];
|
||||
UINT32 right[2 * NC - 1];
|
||||
BYTE c_len[NC];
|
||||
BYTE pt_len[NPT];
|
||||
UInt32 left[2 * NC - 1];
|
||||
UInt32 right[2 * NC - 1];
|
||||
Byte c_len[NC];
|
||||
Byte pt_len[NPT];
|
||||
|
||||
UINT32 c_table[CTABLESIZE];
|
||||
UINT32 pt_table[PTABLESIZE];
|
||||
UInt32 c_table[CTABLESIZE];
|
||||
UInt32 pt_table[PTABLESIZE];
|
||||
|
||||
|
||||
/*
|
||||
void CCoder::ReleaseStreams()
|
||||
{
|
||||
m_OutWindowStream.ReleaseStream();
|
||||
m_InBitStream.ReleaseStream();
|
||||
}
|
||||
*/
|
||||
|
||||
class CCoderReleaser
|
||||
{
|
||||
CCoder *m_Coder;
|
||||
public:
|
||||
CCoderReleaser(CCoder *aCoder): m_Coder(aCoder) {}
|
||||
bool NeedFlush;
|
||||
CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {}
|
||||
~CCoderReleaser()
|
||||
{
|
||||
m_Coder->m_OutWindowStream.Flush();
|
||||
// m_Coder->ReleaseStreams();
|
||||
if (NeedFlush)
|
||||
m_Coder->m_OutWindowStream.Flush();
|
||||
m_Coder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
friend class CCoderReleaser;
|
||||
|
||||
void make_table(int nchar, BYTE *bitlen, int tablebits,
|
||||
UINT32 *table, int tablesize);
|
||||
void MakeTable(int nchar, Byte *bitlen, int tablebits,
|
||||
UInt32 *table, int tablesize);
|
||||
|
||||
void read_c_len();
|
||||
void read_pt_len(int nn, int nbit, int i_special);
|
||||
UINT32 decode_c();
|
||||
UINT32 decode_p();
|
||||
|
||||
UInt32 decode_c();
|
||||
UInt32 decode_p();
|
||||
|
||||
public:
|
||||
CCoder();
|
||||
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(CodeReal)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
};
|
||||
|
||||
@@ -4,43 +4,40 @@
|
||||
|
||||
#include "Decoder2.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
namespace NCompress{
|
||||
namespace NArj {
|
||||
namespace NDecoder2 {
|
||||
|
||||
static const UINT32 kHistorySize = 26624;
|
||||
static const UINT32 kMatchMaxLen = 256;
|
||||
static const UINT32 kMatchMinLen = 3;
|
||||
|
||||
CCoder::CCoder()
|
||||
{}
|
||||
static const UInt32 kHistorySize = 26624;
|
||||
static const UInt32 kMatchMaxLen = 256;
|
||||
static const UInt32 kMatchMinLen = 3;
|
||||
|
||||
STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (outSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!m_OutWindowStream.IsCreated())
|
||||
{
|
||||
try { m_OutWindowStream.Create(kHistorySize); }
|
||||
catch(...) { return E_OUTOFMEMORY; }
|
||||
}
|
||||
UINT64 pos = 0;
|
||||
m_OutWindowStream.Init(outStream, false);
|
||||
m_InBitStream.Init(inStream);
|
||||
if (!m_OutWindowStream.Create(kHistorySize))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!m_InBitStream.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
UInt64 pos = 0;
|
||||
m_OutWindowStream.SetStream(outStream);
|
||||
m_OutWindowStream.Init(false);
|
||||
m_InBitStream.SetStream(inStream);
|
||||
m_InBitStream.Init();
|
||||
CCoderReleaser coderReleaser(this);
|
||||
|
||||
while(pos < *outSize)
|
||||
{
|
||||
const UINT32 kStartWidth = 0;
|
||||
const UINT32 kStopWidth = 7;
|
||||
UINT32 power = 1 << kStartWidth;
|
||||
UINT32 width;
|
||||
UINT32 len = 0;
|
||||
const UInt32 kStartWidth = 0;
|
||||
const UInt32 kStopWidth = 7;
|
||||
UInt32 power = 1 << kStartWidth;
|
||||
UInt32 width;
|
||||
UInt32 len = 0;
|
||||
for (width = kStartWidth; width < kStopWidth; width++)
|
||||
{
|
||||
if (m_InBitStream.ReadBits(1) == 0)
|
||||
@@ -52,18 +49,18 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
len += m_InBitStream.ReadBits(width);
|
||||
if (len == 0)
|
||||
{
|
||||
m_OutWindowStream.PutOneByte(m_InBitStream.ReadBits(8));
|
||||
m_OutWindowStream.PutByte(m_InBitStream.ReadBits(8));
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = len - 1 + kMatchMinLen;
|
||||
const UINT32 kStartWidth = 9;
|
||||
const UINT32 kStopWidth = 13;
|
||||
UINT32 power = 1 << kStartWidth;
|
||||
UINT32 width;
|
||||
UINT32 distance = 0;
|
||||
const UInt32 kStartWidth = 9;
|
||||
const UInt32 kStopWidth = 13;
|
||||
UInt32 power = 1 << kStartWidth;
|
||||
UInt32 width;
|
||||
UInt32 distance = 0;
|
||||
for (width = kStartWidth; width < kStopWidth; width++)
|
||||
{
|
||||
if (m_InBitStream.ReadBits(1) == 0)
|
||||
@@ -75,15 +72,16 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
distance += m_InBitStream.ReadBits(width);
|
||||
if (distance >= pos)
|
||||
throw "data error";
|
||||
m_OutWindowStream.CopyBackBlock(distance, len);
|
||||
m_OutWindowStream.CopyBlock(distance, len);
|
||||
pos += len;
|
||||
}
|
||||
}
|
||||
coderReleaser.NeedFlush = false;
|
||||
return m_OutWindowStream.Flush();
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress);}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// Arj/Decoder2.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __COMPRESS_ARJ_DECODER2_H
|
||||
#define __COMPRESS_ARJ_DECODER2_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/MSBFDecoder.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
@@ -28,38 +26,36 @@ class CCoder :
|
||||
CLZOutWindow m_OutWindowStream;
|
||||
NStream::NMSBF::CDecoder<CInBuffer> m_InBitStream;
|
||||
|
||||
/*
|
||||
void CCoder::ReleaseStreams()
|
||||
{
|
||||
m_OutWindowStream.ReleaseStream();
|
||||
m_InBitStream.ReleaseStream();
|
||||
}
|
||||
*/
|
||||
|
||||
class CCoderReleaser
|
||||
{
|
||||
CCoder *m_Coder;
|
||||
public:
|
||||
CCoderReleaser(CCoder *aCoder): m_Coder(aCoder) {}
|
||||
bool NeedFlush;
|
||||
CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {}
|
||||
~CCoderReleaser()
|
||||
{
|
||||
m_Coder->m_OutWindowStream.Flush();
|
||||
// m_Coder->ReleaseStreams();
|
||||
if (NeedFlush)
|
||||
m_Coder->m_OutWindowStream.Flush();
|
||||
m_Coder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
friend class CCoderReleaser;
|
||||
|
||||
public:
|
||||
CCoder();
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(CodeReal)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
};
|
||||
|
||||
8
7zip/Compress/Arj/StdAfx.h
Executable file
8
7zip/Compress/Arj/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
289
7zip/Compress/BWT/BlockSort.cpp
Executable file
289
7zip/Compress/BWT/BlockSort.cpp
Executable file
@@ -0,0 +1,289 @@
|
||||
// BlockSort.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "BlockSort.h"
|
||||
|
||||
#include "Common/Alloc.h"
|
||||
|
||||
namespace NCompress {
|
||||
|
||||
static const int kNumHashBytes = 2;
|
||||
static const UInt32 kNumHashValues = 1 << (kNumHashBytes * 8);
|
||||
|
||||
static const int kNumFlagsBits = 5; // 32 Flags in UInt32 word
|
||||
static const UInt32 kNumFlagsInWord = (1 << kNumFlagsBits);
|
||||
static const UInt32 kFlagsMask = kNumFlagsInWord - 1;
|
||||
static const UInt32 kAllFlags = 0xFFFFFFFF;
|
||||
|
||||
bool CBlockSorter::Create(UInt32 blockSizeMax)
|
||||
{
|
||||
if (Indices != 0 && blockSizeMax == BlockSizeMax)
|
||||
return true;
|
||||
Free();
|
||||
BlockSizeMax = blockSizeMax;
|
||||
Indices = (UInt32 *)::BigAlloc((blockSizeMax * 2 +
|
||||
((blockSizeMax + kFlagsMask) >> kNumFlagsBits) + kNumHashValues) * sizeof(UInt32));
|
||||
return (Indices != 0);
|
||||
}
|
||||
|
||||
void CBlockSorter::Free()
|
||||
{
|
||||
::BigFree(Indices);
|
||||
Indices = 0;
|
||||
}
|
||||
|
||||
// SortGroup - is recursive Radix-Range-Sort function with Bubble-Sort optimization
|
||||
// It uses both mask & maskSize (Range-Sort), since it can change values (Groups)
|
||||
// during sorting
|
||||
// returns: 0 - if there are groups, 1 - no more groups
|
||||
UInt32 CBlockSorter::SortGroup(UInt32 groupOffset, UInt32 groupSize, UInt32 mask, UInt32 maskSize)
|
||||
{
|
||||
if (groupSize <= 2)
|
||||
{
|
||||
if (groupSize <= 1)
|
||||
return 0;
|
||||
UInt32 *ind2 = Indices + groupOffset;
|
||||
UInt32 stringPos = ind2[0] + NumSortedBytes;
|
||||
if (stringPos >= BlockSize)
|
||||
stringPos -= BlockSize;
|
||||
UInt32 group = Groups[stringPos];
|
||||
stringPos = ind2[1] + NumSortedBytes;
|
||||
if (stringPos >= BlockSize)
|
||||
stringPos -= BlockSize;
|
||||
if (group == Groups[stringPos])
|
||||
return 1;
|
||||
if (group > Groups[stringPos])
|
||||
{
|
||||
UInt32 temp = ind2[0];
|
||||
ind2[0] = ind2[1];
|
||||
ind2[1] = temp;
|
||||
}
|
||||
Flags[groupOffset >> kNumFlagsBits] &= ~(1 << (groupOffset & kFlagsMask));
|
||||
Groups[ind2[1]] = groupOffset + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check that all strings are in one group (cannot sort)
|
||||
UInt32 *ind2 = Indices + groupOffset;
|
||||
{
|
||||
UInt32 stringPos = ind2[0] + NumSortedBytes;
|
||||
if (stringPos >= BlockSize)
|
||||
stringPos -= BlockSize;
|
||||
UInt32 group = Groups[stringPos];
|
||||
UInt32 j;
|
||||
for (j = 1; j < groupSize; j++)
|
||||
{
|
||||
stringPos = ind2[j] + NumSortedBytes;
|
||||
if (stringPos >= BlockSize)
|
||||
stringPos -= BlockSize;
|
||||
if (Groups[stringPos] != group)
|
||||
break;
|
||||
}
|
||||
if (j == groupSize)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (groupSize <= 15)
|
||||
{
|
||||
// Bubble-Sort
|
||||
UInt32 lastChange = groupSize;
|
||||
do
|
||||
{
|
||||
UInt32 stringPos = ind2[0] + NumSortedBytes;
|
||||
if (stringPos >= BlockSize)
|
||||
stringPos -= BlockSize;
|
||||
UInt32 group = Groups[stringPos];
|
||||
|
||||
UInt32 sortSize = lastChange;
|
||||
lastChange = 0;
|
||||
for (UInt32 j = 1; j < sortSize; j++)
|
||||
{
|
||||
stringPos = ind2[j] + NumSortedBytes;
|
||||
if (stringPos >= BlockSize)
|
||||
stringPos -= BlockSize;
|
||||
if (Groups[stringPos] < group)
|
||||
{
|
||||
UInt32 temp = ind2[j];
|
||||
ind2[j] = ind2[j - 1];
|
||||
ind2[j - 1] = temp;
|
||||
lastChange = j;
|
||||
}
|
||||
else
|
||||
group = Groups[stringPos];
|
||||
}
|
||||
}
|
||||
while(lastChange > 1);
|
||||
|
||||
// Write Flags
|
||||
UInt32 stringPos = ind2[0] + NumSortedBytes;
|
||||
if (stringPos >= BlockSize)
|
||||
stringPos -= BlockSize;
|
||||
UInt32 group = Groups[stringPos];
|
||||
|
||||
UInt32 j;
|
||||
for (j = 1; j < groupSize; j++)
|
||||
{
|
||||
stringPos = ind2[j] + NumSortedBytes;
|
||||
if (stringPos >= BlockSize)
|
||||
stringPos -= BlockSize;
|
||||
if (Groups[stringPos] != group)
|
||||
{
|
||||
group = Groups[stringPos];
|
||||
UInt32 t = groupOffset + j - 1;
|
||||
Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
|
||||
}
|
||||
}
|
||||
|
||||
// Write new Groups values and Check that there are groups
|
||||
UInt32 thereAreGroups = 0;
|
||||
for (j = 0; j < groupSize; j++)
|
||||
{
|
||||
UInt32 group = groupOffset + j;
|
||||
while (true)
|
||||
{
|
||||
Groups[ind2[j]] = group;
|
||||
if ((Flags[(groupOffset + j) >> kNumFlagsBits] & (1 << ((groupOffset + j) & kFlagsMask))) == 0)
|
||||
break;
|
||||
j++;
|
||||
thereAreGroups = 1;
|
||||
}
|
||||
}
|
||||
return thereAreGroups;
|
||||
}
|
||||
|
||||
// Radix-Range Sort
|
||||
UInt32 i;
|
||||
do
|
||||
{
|
||||
if (maskSize == 0)
|
||||
return 1;
|
||||
UInt32 j = groupSize;
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
UInt32 stringPos = ind2[i] + NumSortedBytes;
|
||||
if (stringPos >= BlockSize)
|
||||
stringPos -= BlockSize;
|
||||
if (Groups[stringPos] >= mask)
|
||||
{
|
||||
for (j--; j > i; j--)
|
||||
{
|
||||
stringPos = ind2[j] + NumSortedBytes;
|
||||
if (stringPos >= BlockSize)
|
||||
stringPos -= BlockSize;
|
||||
if (Groups[stringPos] < mask)
|
||||
{
|
||||
UInt32 temp = ind2[i];
|
||||
ind2[i] = ind2[j];
|
||||
ind2[j] = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= j)
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(++i < j);
|
||||
maskSize >>= 1;
|
||||
if (i == 0)
|
||||
mask += maskSize;
|
||||
else if (i == groupSize)
|
||||
mask -= maskSize;
|
||||
else
|
||||
break;
|
||||
}
|
||||
while(true);
|
||||
UInt32 t = (groupOffset + i - 1);
|
||||
Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
|
||||
|
||||
for (UInt32 j = i; j < groupSize; j++)
|
||||
Groups[ind2[j]] = groupOffset + i;
|
||||
|
||||
UInt32 res = SortGroup(groupOffset, i, mask - maskSize, maskSize);
|
||||
return res | SortGroup(groupOffset + i, groupSize - i, mask + maskSize, maskSize);
|
||||
}
|
||||
|
||||
UInt32 CBlockSorter::Sort(const Byte *data, UInt32 blockSize)
|
||||
{
|
||||
BlockSize = blockSize;
|
||||
UInt32 *counters = Indices + blockSize;
|
||||
Groups = counters + kNumHashValues;
|
||||
Flags = Groups + blockSize;
|
||||
UInt32 i;
|
||||
|
||||
// Radix-Sort for 2 bytes
|
||||
for (i = 0; i < kNumHashValues; i++)
|
||||
counters[i] = 0;
|
||||
for (i = 0; i < blockSize - 1; i++)
|
||||
counters[((UInt32)data[i] << 8) | data[i + 1]]++;
|
||||
counters[((UInt32)data[i] << 8) | data[0]]++;
|
||||
|
||||
{
|
||||
{
|
||||
UInt32 numWords = (blockSize + kFlagsMask) >> kNumFlagsBits;
|
||||
for (i = 0; i < numWords; i++)
|
||||
Flags[i] = kAllFlags;
|
||||
}
|
||||
|
||||
UInt32 sum = 0;
|
||||
for (i = 0; i < kNumHashValues; i++)
|
||||
{
|
||||
UInt32 groupSize = counters[i];
|
||||
if (groupSize > 0)
|
||||
{
|
||||
UInt32 t = sum + groupSize - 1;
|
||||
Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
|
||||
sum += groupSize;
|
||||
}
|
||||
counters[i] = sum - groupSize;
|
||||
}
|
||||
|
||||
for (i = 0; i < blockSize - 1; i++)
|
||||
Groups[i] = counters[((UInt32)data[i] << 8) | data[i + 1]];
|
||||
Groups[i] = counters[((UInt32)data[i] << 8) | data[0]];
|
||||
|
||||
for (i = 0; i < blockSize - 1; i++)
|
||||
Indices[counters[((UInt32)data[i] << 8) | data[i + 1]]++] = i;
|
||||
Indices[counters[((UInt32)data[i] << 8) | data[0]]++] = i;
|
||||
}
|
||||
|
||||
UInt32 mask;
|
||||
for (mask = 2; mask < blockSize; mask <<= 1);
|
||||
mask >>= 1;
|
||||
for (NumSortedBytes = kNumHashBytes; true; NumSortedBytes <<= 1)
|
||||
{
|
||||
UInt32 newLimit = 0;
|
||||
for (i = 0; i < blockSize;)
|
||||
{
|
||||
if ((Flags[i >> kNumFlagsBits] & (1 << (i & kFlagsMask))) == 0)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
UInt32 groupSize;
|
||||
for(groupSize = 1;
|
||||
(Flags[(i + groupSize) >> kNumFlagsBits] & (1 << ((i + groupSize) & kFlagsMask))) != 0;
|
||||
groupSize++);
|
||||
|
||||
groupSize++;
|
||||
|
||||
if (NumSortedBytes >= blockSize)
|
||||
for (UInt32 j = 0; j < groupSize; j++)
|
||||
{
|
||||
UInt32 t = (i + j);
|
||||
Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
|
||||
Groups[Indices[t]] = t;
|
||||
}
|
||||
else
|
||||
if (SortGroup(i, groupSize, mask, mask) != 0)
|
||||
newLimit = i + groupSize;
|
||||
i += groupSize;
|
||||
}
|
||||
if (newLimit == 0)
|
||||
break;
|
||||
}
|
||||
return Groups[0];
|
||||
}
|
||||
|
||||
}
|
||||
29
7zip/Compress/BWT/BlockSort.h
Executable file
29
7zip/Compress/BWT/BlockSort.h
Executable file
@@ -0,0 +1,29 @@
|
||||
// BlockSort.h
|
||||
|
||||
#ifndef __BLOCKSORT_H
|
||||
#define __BLOCKSORT_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
namespace NCompress {
|
||||
|
||||
class CBlockSorter
|
||||
{
|
||||
UInt32 *Groups;
|
||||
UInt32 *Flags;
|
||||
UInt32 BlockSize;
|
||||
UInt32 NumSortedBytes;
|
||||
UInt32 BlockSizeMax;
|
||||
UInt32 SortGroup(UInt32 groupOffset, UInt32 groupSize, UInt32 mask, UInt32 maskSize);
|
||||
public:
|
||||
UInt32 *Indices;
|
||||
CBlockSorter(): Indices(0) {}
|
||||
~CBlockSorter() { Free(); }
|
||||
bool Create(UInt32 blockSizeMax);
|
||||
void Free();
|
||||
UInt32 Sort(const Byte *data, UInt32 blockSize);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
140
7zip/Compress/BWT/Mtf8.h
Executable file
140
7zip/Compress/BWT/Mtf8.h
Executable file
@@ -0,0 +1,140 @@
|
||||
// Mtf8.h
|
||||
|
||||
#ifndef __MTF8_H
|
||||
#define __MTF8_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
namespace NCompress {
|
||||
|
||||
class CMtf8Encoder
|
||||
{
|
||||
public:
|
||||
Byte Buffer[256];
|
||||
int FindAndMove(Byte v)
|
||||
{
|
||||
int pos;
|
||||
for (pos = 0; Buffer[pos] != v; pos++);
|
||||
int resPos = pos;
|
||||
for (; pos >= 8; pos -= 8)
|
||||
{
|
||||
Buffer[pos] = Buffer[pos - 1];
|
||||
Buffer[pos - 1] = Buffer[pos - 2];
|
||||
Buffer[pos - 2] = Buffer[pos - 3];
|
||||
Buffer[pos - 3] = Buffer[pos - 4];
|
||||
Buffer[pos - 4] = Buffer[pos - 5];
|
||||
Buffer[pos - 5] = Buffer[pos - 6];
|
||||
Buffer[pos - 6] = Buffer[pos - 7];
|
||||
Buffer[pos - 7] = Buffer[pos - 8];
|
||||
}
|
||||
for (; pos > 0; pos--)
|
||||
Buffer[pos] = Buffer[pos - 1];
|
||||
Buffer[0] = v;
|
||||
return resPos;
|
||||
}
|
||||
};
|
||||
|
||||
class CMtf8Decoder
|
||||
{
|
||||
public:
|
||||
Byte Buffer[256];
|
||||
void Init(int size) {};
|
||||
Byte GetHead() const { return Buffer[0]; }
|
||||
Byte GetAndMove(int pos)
|
||||
{
|
||||
Byte res = Buffer[pos];
|
||||
for (; pos >= 8; pos -= 8)
|
||||
{
|
||||
Buffer[pos] = Buffer[pos - 1];
|
||||
Buffer[pos - 1] = Buffer[pos - 2];
|
||||
Buffer[pos - 2] = Buffer[pos - 3];
|
||||
Buffer[pos - 3] = Buffer[pos - 4];
|
||||
Buffer[pos - 4] = Buffer[pos - 5];
|
||||
Buffer[pos - 5] = Buffer[pos - 6];
|
||||
Buffer[pos - 6] = Buffer[pos - 7];
|
||||
Buffer[pos - 7] = Buffer[pos - 8];
|
||||
}
|
||||
for (; pos > 0; pos--)
|
||||
Buffer[pos] = Buffer[pos - 1];
|
||||
Buffer[0] = res;
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
const int kSmallSize = 64;
|
||||
class CMtf8Decoder
|
||||
{
|
||||
Byte SmallBuffer[kSmallSize];
|
||||
int SmallSize;
|
||||
Byte Counts[16];
|
||||
int Size;
|
||||
public:
|
||||
Byte Buffer[256];
|
||||
|
||||
Byte GetHead() const
|
||||
{
|
||||
if (SmallSize > 0)
|
||||
return SmallBuffer[kSmallSize - SmallSize];
|
||||
return Buffer[0];
|
||||
}
|
||||
|
||||
void Init(int size)
|
||||
{
|
||||
Size = size;
|
||||
SmallSize = 0;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
Counts[i] = ((size >= 16) ? 16 : size);
|
||||
size -= Counts[i];
|
||||
}
|
||||
}
|
||||
|
||||
Byte GetAndMove(int pos)
|
||||
{
|
||||
if (pos < SmallSize)
|
||||
{
|
||||
Byte *p = SmallBuffer + kSmallSize - SmallSize;
|
||||
Byte res = p[pos];
|
||||
for (; pos > 0; pos--)
|
||||
p[pos] = p[pos - 1];
|
||||
SmallBuffer[kSmallSize - SmallSize] = res;
|
||||
return res;
|
||||
}
|
||||
if (SmallSize == kSmallSize)
|
||||
{
|
||||
int i = Size - 1;
|
||||
int g = 16;
|
||||
do
|
||||
{
|
||||
g--;
|
||||
int offset = (g << 4);
|
||||
for (int t = Counts[g] - 1; t >= 0; t--, i--)
|
||||
Buffer[i] = Buffer[offset + t];
|
||||
}
|
||||
while(g != 0);
|
||||
|
||||
for (i = kSmallSize - 1; i >= 0; i--)
|
||||
Buffer[i] = SmallBuffer[i];
|
||||
Init(Size);
|
||||
}
|
||||
pos -= SmallSize;
|
||||
int g;
|
||||
for (g = 0; pos >= Counts[g]; g++)
|
||||
pos -= Counts[g];
|
||||
int offset = (g << 4);
|
||||
Byte res = Buffer[offset + pos];
|
||||
for (pos; pos < 16 - 1; pos++)
|
||||
Buffer[offset + pos] = Buffer[offset + pos + 1];
|
||||
|
||||
SmallSize++;
|
||||
SmallBuffer[kSmallSize - SmallSize] = res;
|
||||
|
||||
Counts[g]--;
|
||||
return res;
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
}
|
||||
#endif
|
||||
6
7zip/Compress/BWT/StdAfx.h
Executable file
6
7zip/Compress/BWT/StdAfx.h
Executable file
@@ -0,0 +1,6 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#endif
|
||||
@@ -115,130 +115,6 @@ SOURCE=.\StdAfx.cpp
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Origianl"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\blocksort.c
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\bzlib.c
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\bzlib.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\bzlib_private.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\compress.c
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\crctable.c
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\decompress.c
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\huffman.c
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\randtable.c
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Common"
|
||||
@@ -246,6 +122,14 @@ SOURCE=.\Original\randtable.c
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\NewHandler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -253,6 +137,94 @@ SOURCE=..\..\..\Common\NewHandler.cpp
|
||||
SOURCE=..\..\..\Common\NewHandler.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Huffman"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Huffman\HuffmanDecoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Huffman\HuffmanEncoder.cpp
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Huffman\HuffmanEncoder.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "7-Zip Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\InBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\InBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\MSBFDecoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\MSBFEncoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\OutBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\OutBuffer.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "BWT"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\BWT\BlockSort.cpp
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\BWT\BlockSort.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\BWT\Mtf8.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2CRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2CRC.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2Decoder.cpp
|
||||
@@ -289,9 +261,5 @@ SOURCE=.\BZip2Encoder.cpp
|
||||
|
||||
SOURCE=.\BZip2Encoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2Error.cpp
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
|
||||
26
7zip/Compress/BZip2/BZip2CRC.cpp
Executable file
26
7zip/Compress/BZip2/BZip2CRC.cpp
Executable file
@@ -0,0 +1,26 @@
|
||||
// BZip2CRC.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "BZip2CRC.h"
|
||||
|
||||
UInt32 CBZip2CRC::Table[256];
|
||||
|
||||
static const UInt32 kBZip2CRCPoly = 0x04c11db7; /* AUTODIN II, Ethernet, & FDDI */
|
||||
|
||||
void CBZip2CRC::InitTable()
|
||||
{
|
||||
for (UInt32 i = 0; i < 256; i++)
|
||||
{
|
||||
UInt32 r = (i << 24);
|
||||
for (int j = 8; j > 0; j--)
|
||||
r = (r & 0x80000000) ? ((r << 1) ^ kBZip2CRCPoly) : (r << 1);
|
||||
Table[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
class CBZip2CRCTableInit
|
||||
{
|
||||
public:
|
||||
CBZip2CRCTableInit() { CBZip2CRC::InitTable(); }
|
||||
} g_CRCTableInit;
|
||||
30
7zip/Compress/BZip2/BZip2CRC.h
Executable file
30
7zip/Compress/BZip2/BZip2CRC.h
Executable file
@@ -0,0 +1,30 @@
|
||||
// BZip2CRC.h
|
||||
|
||||
#ifndef __BZIP2_CRC_H
|
||||
#define __BZIP2_CRC_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
class CBZip2CRC
|
||||
{
|
||||
UInt32 _value;
|
||||
static UInt32 Table[256];
|
||||
public:
|
||||
static void InitTable();
|
||||
CBZip2CRC(): _value(0xFFFFFFFF) {};
|
||||
void Init() { _value = 0xFFFFFFFF; }
|
||||
void UpdateByte(Byte b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); }
|
||||
UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; }
|
||||
};
|
||||
|
||||
class CBZip2CombinedCRC
|
||||
{
|
||||
UInt32 _value;
|
||||
public:
|
||||
CBZip2CombinedCRC(): _value(0){};
|
||||
void Init() { _value = 0; }
|
||||
void Update(UInt32 v) { _value = ((_value << 1) | (_value >> 31)) ^ v; }
|
||||
UInt32 GetDigest() const { return _value ; }
|
||||
};
|
||||
|
||||
#endif
|
||||
54
7zip/Compress/BZip2/BZip2Const.h
Executable file
54
7zip/Compress/BZip2/BZip2Const.h
Executable file
@@ -0,0 +1,54 @@
|
||||
// Compress/BZip2Const.h
|
||||
|
||||
#ifndef __COMPRESS_BZIP2_CONST_H
|
||||
#define __COMPRESS_BZIP2_CONST_H
|
||||
|
||||
namespace NCompress {
|
||||
namespace NBZip2 {
|
||||
|
||||
const Byte kArSig0 = 'B';
|
||||
const Byte kArSig1 = 'Z';
|
||||
const Byte kArSig2 = 'h';
|
||||
const Byte kArSig3 = '0';
|
||||
|
||||
const Byte kFinSig0 = 0x17;
|
||||
const Byte kFinSig1 = 0x72;
|
||||
const Byte kFinSig2 = 0x45;
|
||||
const Byte kFinSig3 = 0x38;
|
||||
const Byte kFinSig4 = 0x50;
|
||||
const Byte kFinSig5 = 0x90;
|
||||
|
||||
const Byte kBlockSig0 = 0x31;
|
||||
const Byte kBlockSig1 = 0x41;
|
||||
const Byte kBlockSig2 = 0x59;
|
||||
const Byte kBlockSig3 = 0x26;
|
||||
const Byte kBlockSig4 = 0x53;
|
||||
const Byte kBlockSig5 = 0x59;
|
||||
|
||||
const int kNumOrigBits = 24;
|
||||
|
||||
const int kNumTablesBits = 3;
|
||||
const int kNumTablesMin = 2;
|
||||
const int kNumTablesMax = 6;
|
||||
|
||||
const int kNumLevelsBits = 5;
|
||||
|
||||
const int kMaxHuffmanLen = 20; // Check it
|
||||
|
||||
const int kMaxAlphaSize = 258;
|
||||
|
||||
const int kGroupSize = 50;
|
||||
|
||||
const int kBlockSizeMultMin = 1;
|
||||
const int kBlockSizeMultMax = 9;
|
||||
const UInt32 kBlockSizeStep = 100000;
|
||||
const UInt32 kBlockSizeMax = kBlockSizeMultMax * kBlockSizeStep;
|
||||
|
||||
const int kNumSelectorsBits = 15;
|
||||
const UInt32 kNumSelectorsMax = (2 + (kBlockSizeMax / kGroupSize));
|
||||
|
||||
const int kRleModeRepSize = 4;
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -4,122 +4,402 @@
|
||||
|
||||
#include "BZip2Decoder.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "Original/bzlib.h"
|
||||
#include "../../../Common/Alloc.h"
|
||||
#include "../../../Common/Defs.h"
|
||||
#include "../BWT/Mtf8.h"
|
||||
#include "BZip2CRC.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NBZip2 {
|
||||
|
||||
static const UINT32 kBufferSize = (1 << 20);
|
||||
static const UInt32 kBufferSize = (1 << 17);
|
||||
|
||||
CDecoder::CDecoder()
|
||||
{
|
||||
m_InBuffer = new BYTE[kBufferSize];
|
||||
m_OutBuffer = new BYTE[kBufferSize];
|
||||
}
|
||||
|
||||
CDecoder::~CDecoder()
|
||||
{
|
||||
delete []m_OutBuffer;
|
||||
delete []m_InBuffer;
|
||||
}
|
||||
|
||||
struct CBZip2Decompressor: public bz_stream
|
||||
{
|
||||
// bz_stream m_Object;
|
||||
public:
|
||||
int Init(int verbosity, int small) { return BZ2_bzDecompressInit(this, verbosity, small); }
|
||||
int Decompress() { return BZ2_bzDecompress(this); }
|
||||
int End() { return BZ2_bzDecompressEnd(this); }
|
||||
UINT64 GetTotalIn() const { return (UINT64(total_in_hi32) << 32) + total_in_lo32; }
|
||||
UINT64 GetTotalOut() const { return (UINT64(total_out_hi32) << 32) + total_out_lo32; }
|
||||
static Int16 kRandNums[512] = {
|
||||
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
|
||||
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
|
||||
733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
|
||||
419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
|
||||
878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
|
||||
862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
|
||||
150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
|
||||
170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
|
||||
73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
|
||||
909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
|
||||
641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
|
||||
161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
|
||||
382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
|
||||
98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
|
||||
227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
|
||||
469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
|
||||
184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
|
||||
715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
|
||||
951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
|
||||
652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
|
||||
645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
|
||||
609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
|
||||
653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
|
||||
411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
|
||||
170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
|
||||
857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
|
||||
669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
|
||||
944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
|
||||
344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
|
||||
897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
|
||||
433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
|
||||
686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
|
||||
946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
|
||||
978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
|
||||
680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
|
||||
707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
|
||||
297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
|
||||
134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
|
||||
343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
|
||||
140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
|
||||
170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
|
||||
369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
|
||||
804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
|
||||
896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
|
||||
661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
|
||||
768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
|
||||
61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
|
||||
372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
|
||||
780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
|
||||
920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
|
||||
645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
|
||||
936, 638
|
||||
};
|
||||
|
||||
class CBZip2DecompressorReleaser
|
||||
CState::~CState()
|
||||
{
|
||||
CBZip2Decompressor *m_Decompressor;
|
||||
public:
|
||||
CBZip2DecompressorReleaser(CBZip2Decompressor *aDecompressor): m_Decompressor(aDecompressor) {}
|
||||
void Diable() { m_Decompressor = NULL; }
|
||||
~CBZip2DecompressorReleaser() { if (m_Decompressor != NULL) m_Decompressor->End(); }
|
||||
};
|
||||
::BigFree(tt);
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
bool CState::Alloc()
|
||||
{
|
||||
CBZip2Decompressor bzStream;
|
||||
bzStream.bzalloc = NULL;
|
||||
bzStream.bzfree = NULL;
|
||||
bzStream.opaque = NULL;
|
||||
if (tt == 0)
|
||||
tt = (UInt32 *)BigAlloc(kBlockSizeMax * sizeof(UInt32));
|
||||
return (tt != 0);
|
||||
}
|
||||
|
||||
UInt32 CDecoder::ReadBits(int numBits) { return m_InStream.ReadBits(numBits); }
|
||||
Byte CDecoder::ReadByte() {return (Byte)ReadBits(8); }
|
||||
bool CDecoder::ReadBit() { return ReadBits(1) != 0; }
|
||||
|
||||
int result = bzStream.Init(0, 0);
|
||||
switch(result)
|
||||
UInt32 CDecoder::ReadCRC()
|
||||
{
|
||||
UInt32 crc = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
case BZ_OK:
|
||||
break;
|
||||
case BZ_MEM_ERROR:
|
||||
return E_OUTOFMEMORY;
|
||||
default:
|
||||
return E_FAIL;
|
||||
crc <<= 8;
|
||||
crc |= ReadByte();
|
||||
}
|
||||
CBZip2DecompressorReleaser releaser(&bzStream);
|
||||
bzStream.avail_in = 0;
|
||||
while (true)
|
||||
return crc;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::ReadBlock(UInt32 blockSizeMax, CState &state)
|
||||
{
|
||||
state.BlockRandomised = ReadBit();
|
||||
state.OrigPtr = ReadBits(kNumOrigBits);
|
||||
|
||||
// in original code it compares OrigPtr to (UInt32)(10 + blockSizeMax)) : why ?
|
||||
if (state.OrigPtr >= blockSizeMax)
|
||||
return S_FALSE;
|
||||
|
||||
CMtf8Decoder mtf;
|
||||
int numInUse = 0;
|
||||
{
|
||||
if (bzStream.avail_in == 0)
|
||||
{
|
||||
bzStream.next_in = (char *)m_InBuffer;
|
||||
UINT32 processedSize;
|
||||
RINOK(inStream->Read(m_InBuffer, kBufferSize, &processedSize));
|
||||
bzStream.avail_in = processedSize;
|
||||
}
|
||||
bool inUse16[16];
|
||||
int i;
|
||||
for (i = 0; i < 16; i++)
|
||||
inUse16[i] = ReadBit();
|
||||
for (i = 0; i < 256; i++)
|
||||
if (inUse16[i >> 4])
|
||||
if (ReadBit())
|
||||
mtf.Buffer[numInUse++] = (Byte)i;
|
||||
if (numInUse == 0)
|
||||
return S_FALSE;
|
||||
mtf.Init(numInUse);
|
||||
}
|
||||
int alphaSize = numInUse + 2;
|
||||
|
||||
bzStream.next_out = (char *)m_OutBuffer;
|
||||
bzStream.avail_out = kBufferSize;
|
||||
result = bzStream.Decompress();
|
||||
UINT32 numBytesToWrite = kBufferSize - bzStream.avail_out;
|
||||
if (numBytesToWrite > 0)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
RINOK(outStream->Write(m_OutBuffer, numBytesToWrite, &processedSize));
|
||||
if (numBytesToWrite != processedSize)
|
||||
return E_FAIL;
|
||||
}
|
||||
int numTables = ReadBits(kNumTablesBits);
|
||||
if (numTables < kNumTablesMin || numTables > kNumTablesMax)
|
||||
return S_FALSE;
|
||||
|
||||
UInt32 numSelectors = ReadBits(kNumSelectorsBits);
|
||||
if (numSelectors < 1 || numSelectors > kNumSelectorsMax)
|
||||
return S_FALSE;
|
||||
|
||||
if (result == BZ_STREAM_END)
|
||||
break;
|
||||
switch(result)
|
||||
{
|
||||
Byte mtfPos[kNumTablesMax];
|
||||
int t = 0;
|
||||
do
|
||||
mtfPos[t] = (Byte)t;
|
||||
while(++t < numTables);
|
||||
UInt32 i = 0;
|
||||
do
|
||||
{
|
||||
case BZ_DATA_ERROR:
|
||||
case BZ_DATA_ERROR_MAGIC:
|
||||
return S_FALSE;
|
||||
case BZ_OK:
|
||||
int j = 0;
|
||||
while (ReadBit())
|
||||
if (++j >= numTables)
|
||||
return S_FALSE;
|
||||
Byte tmp = mtfPos[j];
|
||||
for (;j > 0; j--)
|
||||
mtfPos[j] = mtfPos[j - 1];
|
||||
state.m_Selectors[i] = mtfPos[0] = tmp;
|
||||
}
|
||||
while(++i < numSelectors);
|
||||
}
|
||||
|
||||
int t = 0;
|
||||
do
|
||||
{
|
||||
Byte lens[kMaxAlphaSize];
|
||||
int len = (int)ReadBits(kNumLevelsBits);
|
||||
int i;
|
||||
for (i = 0; i < alphaSize; i++)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (len < 1 || len > kMaxHuffmanLen)
|
||||
return S_FALSE;
|
||||
if (!ReadBit())
|
||||
break;
|
||||
if (ReadBit())
|
||||
len--;
|
||||
else
|
||||
len++;
|
||||
}
|
||||
lens[i] = (Byte)len;
|
||||
}
|
||||
for (; i < kMaxAlphaSize; i++)
|
||||
lens[i] = 0;
|
||||
m_HuffmanDecoders[t].SetCodeLengths(lens);
|
||||
}
|
||||
while(++t < numTables);
|
||||
|
||||
{
|
||||
for (int i = 0; i < 256; i++)
|
||||
state.CharCounters[i] = 0;
|
||||
}
|
||||
|
||||
UInt32 blockSize = 0;
|
||||
{
|
||||
UInt32 groupIndex = 0;
|
||||
UInt32 groupSize = 0;
|
||||
CHuffmanDecoder *huffmanDecoder = 0;
|
||||
int runPower = 0;
|
||||
UInt32 runCounter = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (groupSize == 0)
|
||||
{
|
||||
if (groupIndex >= numSelectors)
|
||||
return S_FALSE;
|
||||
groupSize = kGroupSize;
|
||||
huffmanDecoder = &m_HuffmanDecoders[state.m_Selectors[groupIndex++]];
|
||||
}
|
||||
groupSize--; \
|
||||
|
||||
int nextSym = (int)huffmanDecoder->DecodeSymbol(&m_InStream);
|
||||
|
||||
if (nextSym < 2)
|
||||
{
|
||||
runCounter += ((UInt32)(nextSym + 1) << runPower++);
|
||||
if (blockSizeMax - blockSize < runCounter)
|
||||
return S_FALSE;
|
||||
continue;
|
||||
}
|
||||
if (runCounter != 0)
|
||||
{
|
||||
Byte b = mtf.GetHead();
|
||||
state.CharCounters[b] += runCounter;
|
||||
do
|
||||
state.tt[blockSize++] = (UInt32)b;
|
||||
while(--runCounter != 0);
|
||||
runPower = 0;
|
||||
}
|
||||
if (nextSym > numInUse)
|
||||
break;
|
||||
case BZ_MEM_ERROR:
|
||||
return E_OUTOFMEMORY;
|
||||
default:
|
||||
return E_FAIL;
|
||||
}
|
||||
if (progress != NULL)
|
||||
{
|
||||
UINT64 totalIn = bzStream.GetTotalIn();
|
||||
UINT64 totalOut = bzStream.GetTotalOut();
|
||||
RINOK(progress->SetRatioInfo(&totalIn, &totalOut));
|
||||
Byte b = mtf.GetAndMove(nextSym - 1);
|
||||
if (blockSize >= blockSizeMax)
|
||||
return S_FALSE;
|
||||
state.CharCounters[b]++;
|
||||
state.tt[blockSize++] = (UInt32)b;
|
||||
}
|
||||
}
|
||||
// result = bzStream.End();
|
||||
|
||||
if (state.OrigPtr >= blockSize)
|
||||
return S_FALSE;
|
||||
state.BlockSize = blockSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CState::DecodeBlock(COutBuffer &m_OutStream)
|
||||
{
|
||||
UInt32 *charCounters = this->CharCounters;
|
||||
{
|
||||
UInt32 sum = 0;
|
||||
for (UInt32 i = 0; i < 256; i++)
|
||||
{
|
||||
sum += charCounters[i];
|
||||
charCounters[i] = sum - charCounters[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the T^(-1) vector
|
||||
UInt32 blockSize = this->BlockSize;
|
||||
UInt32 i = 0;
|
||||
do
|
||||
tt[charCounters[tt[i] & 0xFF]++] |= (i << 8);
|
||||
while(++i < blockSize);
|
||||
|
||||
// Decode
|
||||
|
||||
CBZip2CRC crc;
|
||||
|
||||
UInt32 randIndex = 1;
|
||||
UInt32 randToGo = kRandNums[0] - 2;
|
||||
|
||||
int numReps = 0;
|
||||
|
||||
// it's for speed optimization: prefetch & prevByte_init;
|
||||
UInt32 tPos = tt[tt[OrigPtr] >> 8];
|
||||
Byte prevByte = (Byte)(tPos & 0xFF);
|
||||
|
||||
do
|
||||
{
|
||||
Byte b = (Byte)(tPos & 0xFF);
|
||||
tPos = tt[tPos >> 8];
|
||||
|
||||
if (BlockRandomised)
|
||||
{
|
||||
if (randToGo == 0)
|
||||
{
|
||||
b ^= 1;
|
||||
randToGo = kRandNums[randIndex++];
|
||||
randIndex &= 0x1FF;
|
||||
}
|
||||
randToGo--;
|
||||
}
|
||||
|
||||
if (numReps == kRleModeRepSize)
|
||||
{
|
||||
for (; b > 0; b--)
|
||||
{
|
||||
crc.UpdateByte(prevByte);
|
||||
m_OutStream.WriteByte(prevByte);
|
||||
}
|
||||
numReps = 0;
|
||||
continue;
|
||||
}
|
||||
if (prevByte == b)
|
||||
numReps++;
|
||||
else
|
||||
{
|
||||
numReps = 1;
|
||||
prevByte = b;
|
||||
}
|
||||
crc.UpdateByte(b);
|
||||
m_OutStream.WriteByte(b);
|
||||
}
|
||||
while(--blockSize != 0);
|
||||
return (StoredCRC == crc.GetDigest()) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::DecodeFile(bool &isBZ, ICompressProgressInfo *progress)
|
||||
{
|
||||
isBZ = false;
|
||||
Byte s[6];
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
s[i] = ReadByte();
|
||||
if (s[0] != kArSig0 ||
|
||||
s[1] != kArSig1 ||
|
||||
s[2] != kArSig2 ||
|
||||
s[3] <= kArSig3 ||
|
||||
s[3] > kArSig3 + kBlockSizeMultMax)
|
||||
return S_OK;
|
||||
isBZ = true;
|
||||
UInt32 dicSize = (UInt32)(s[3] - kArSig3) * kBlockSizeStep;
|
||||
|
||||
if (!m_State.Alloc())
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
CBZip2CombinedCRC computedCombinedCRC;
|
||||
while (true)
|
||||
{
|
||||
if (progress)
|
||||
{
|
||||
UInt64 packSize = m_InStream.GetProcessedSize();
|
||||
UInt64 unpackSize = m_OutStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &unpackSize));
|
||||
}
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
s[i] = ReadByte();
|
||||
UInt32 crc = ReadCRC();
|
||||
if (s[0] == kFinSig0)
|
||||
{
|
||||
if (s[1] != kFinSig1 ||
|
||||
s[2] != kFinSig2 ||
|
||||
s[3] != kFinSig3 ||
|
||||
s[4] != kFinSig4 ||
|
||||
s[5] != kFinSig5)
|
||||
return S_FALSE;
|
||||
|
||||
return (crc == computedCombinedCRC.GetDigest()) ? S_OK : S_FALSE;
|
||||
}
|
||||
if (s[0] != kBlockSig0 ||
|
||||
s[1] != kBlockSig1 ||
|
||||
s[2] != kBlockSig2 ||
|
||||
s[3] != kBlockSig3 ||
|
||||
s[4] != kBlockSig4 ||
|
||||
s[5] != kBlockSig5)
|
||||
return S_FALSE;
|
||||
m_State.StoredCRC = crc;
|
||||
computedCombinedCRC.Update(crc);
|
||||
RINOK(ReadBlock(dicSize, m_State));
|
||||
RINOK(m_State.DecodeBlock(m_OutStream));
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CDecoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (!m_InStream.Create(kBufferSize))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!m_OutStream.Create(kBufferSize))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
m_InStream.SetStream(inStream);
|
||||
m_InStream.Init();
|
||||
|
||||
m_OutStream.SetStream(outStream);
|
||||
m_OutStream.Init();
|
||||
|
||||
CDecoderFlusher flusher(this);
|
||||
|
||||
bool isBZ;
|
||||
RINOK(DecodeFile(isBZ, progress));
|
||||
return isBZ ? S_OK: S_FALSE;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
return E_INVALIDARG;
|
||||
*value = m_InStream.GetProcessedSize();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,39 +1,88 @@
|
||||
// Compress/BZip2/Decoder.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __COMPRESS_BZIP2_DECODER_H
|
||||
#define __COMPRESS_BZIP2_DECODER_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
// #include "../../Interface/CompressInterface.h"
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../Common/MSBFDecoder.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
#include "../../Common/OutBuffer.h"
|
||||
#include "../Huffman/HuffmanDecoder.h"
|
||||
#include "BZip2Const.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NBZip2 {
|
||||
|
||||
typedef NCompress::NHuffman::CDecoder<kMaxHuffmanLen, kMaxAlphaSize> CHuffmanDecoder;
|
||||
|
||||
struct CState
|
||||
{
|
||||
UInt32 *tt;
|
||||
bool BlockRandomised;
|
||||
UInt32 OrigPtr;
|
||||
UInt32 BlockSize;
|
||||
UInt32 CharCounters[256];
|
||||
Byte m_Selectors[kNumSelectorsMax];
|
||||
UInt32 StoredCRC;
|
||||
|
||||
CState(): tt(0) {}
|
||||
~CState();
|
||||
bool Alloc();
|
||||
HRESULT DecodeBlock(COutBuffer &m_OutStream);
|
||||
};
|
||||
|
||||
class CDecoder :
|
||||
public ICompressCoder,
|
||||
public ICompressGetInStreamProcessedSize,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
BYTE *m_InBuffer;
|
||||
BYTE *m_OutBuffer;
|
||||
NStream::NMSBF::CDecoder<CInBuffer> m_InStream;
|
||||
COutBuffer m_OutStream;
|
||||
|
||||
CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax];
|
||||
|
||||
CState m_State;
|
||||
|
||||
UInt32 ReadBits(int numBits);
|
||||
Byte ReadByte();
|
||||
bool ReadBit();
|
||||
UInt32 ReadCRC();
|
||||
HRESULT ReadBlock(UInt32 blockSizeMax, CState &state);
|
||||
HRESULT PrepareBlock(CState &state);
|
||||
HRESULT DecodeFile(bool &isBZ, ICompressProgressInfo *progress);
|
||||
HRESULT CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
class CDecoderFlusher
|
||||
{
|
||||
CDecoder *_decoder;
|
||||
public:
|
||||
bool NeedFlush;
|
||||
CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
|
||||
~CDecoderFlusher()
|
||||
{
|
||||
if (NeedFlush)
|
||||
_decoder->Flush();
|
||||
_decoder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
CDecoder();
|
||||
~CDecoder();
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
HRESULT Flush();
|
||||
// void (ReleaseStreams)();
|
||||
|
||||
STDMETHOD(CodeReal)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
HRESULT Flush() { return m_OutStream.Flush(); }
|
||||
void ReleaseStreams()
|
||||
{
|
||||
m_InStream.ReleaseStream();
|
||||
m_OutStream.ReleaseStream();
|
||||
}
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -2,119 +2,632 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "BZip2Encoder.h"
|
||||
#include "Original/bzlib.h"
|
||||
|
||||
#include "../../../Common/Alloc.h"
|
||||
#include "../BWT/Mtf8.h"
|
||||
#include "BZip2CRC.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NBZip2 {
|
||||
|
||||
static const UINT32 kBufferSize = (1 << 20);
|
||||
static const UInt32 kBufferSize = (1 << 17);
|
||||
static const int kNumHuffPasses = 4;
|
||||
|
||||
CEncoder::CEncoder()
|
||||
{
|
||||
m_InBuffer = new BYTE[kBufferSize];
|
||||
m_OutBuffer = new BYTE[kBufferSize];
|
||||
}
|
||||
CEncoder::CEncoder():
|
||||
m_Block(0),
|
||||
m_NeedHuffmanCreate(true),
|
||||
m_NumPasses(1),
|
||||
m_OptimizeNumTables(false),
|
||||
m_BlockSizeMult(kBlockSizeMultMax)
|
||||
{}
|
||||
|
||||
CEncoder::~CEncoder()
|
||||
{
|
||||
delete []m_OutBuffer;
|
||||
delete []m_InBuffer;
|
||||
::BigFree(m_Block);
|
||||
}
|
||||
|
||||
struct CBZip2Compressor: public bz_stream
|
||||
UInt32 CEncoder::ReadRleBlock(Byte *buffer)
|
||||
{
|
||||
public:
|
||||
int Init(int blockSize100k, int verbosity, int small)
|
||||
{ return BZ2_bzCompressInit(this, blockSize100k, verbosity, small); }
|
||||
int Compress(int action ) { return BZ2_bzCompress(this, action ); }
|
||||
int End() { return BZ2_bzCompressEnd(this); }
|
||||
UINT64 GetTotalIn() const { return (UINT64(total_in_hi32) << 32) + total_in_lo32; }
|
||||
UINT64 GetTotalOut() const { return (UINT64(total_out_hi32) << 32) + total_out_lo32; }
|
||||
};
|
||||
UInt32 i = 0;
|
||||
Byte prevByte;
|
||||
if (m_InStream.ReadByte(prevByte))
|
||||
{
|
||||
UInt32 blockSize = m_BlockSizeMult * kBlockSizeStep - 1;
|
||||
int numReps = 1;
|
||||
buffer[i++] = prevByte;
|
||||
while (i < blockSize) // "- 1" to support RLE
|
||||
{
|
||||
Byte b;
|
||||
if (!m_InStream.ReadByte(b))
|
||||
break;
|
||||
if (b != prevByte)
|
||||
{
|
||||
if (numReps >= kRleModeRepSize)
|
||||
buffer[i++] = numReps - kRleModeRepSize;
|
||||
buffer[i++] = b;
|
||||
numReps = 1;
|
||||
prevByte = b;
|
||||
continue;
|
||||
}
|
||||
numReps++;
|
||||
if (numReps <= kRleModeRepSize)
|
||||
buffer[i++] = b;
|
||||
else if (numReps == kRleModeRepSize + 255)
|
||||
{
|
||||
buffer[i++] = numReps - kRleModeRepSize;
|
||||
numReps = 0;
|
||||
}
|
||||
}
|
||||
// it's to support original BZip2 decoder
|
||||
if (numReps >= kRleModeRepSize)
|
||||
buffer[i++] = numReps - kRleModeRepSize;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
class CBZip2CompressorReleaser
|
||||
void CEncoder::WriteBits2(UInt32 value, UInt32 numBits)
|
||||
{ m_OutStreamCurrent->WriteBits(value, numBits); }
|
||||
void CEncoder::WriteByte2(Byte b) { WriteBits2(b , 8); }
|
||||
void CEncoder::WriteBit2(bool v) { WriteBits2((v ? 1 : 0), 1); }
|
||||
void CEncoder::WriteCRC2(UInt32 v)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
WriteByte2(((Byte)(v >> (24 - i * 8))));
|
||||
}
|
||||
|
||||
void CEncoder::WriteBits(UInt32 value, UInt32 numBits)
|
||||
{ m_OutStream.WriteBits(value, numBits); }
|
||||
void CEncoder::WriteByte(Byte b) { WriteBits(b , 8); }
|
||||
void CEncoder::WriteBit(bool v) { WriteBits((v ? 1 : 0), 1); }
|
||||
void CEncoder::WriteCRC(UInt32 v)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
WriteByte(((Byte)(v >> (24 - i * 8))));
|
||||
}
|
||||
|
||||
|
||||
// blockSize > 0
|
||||
void CEncoder::EncodeBlock(Byte *block, UInt32 blockSize)
|
||||
{
|
||||
CBZip2Compressor *m_Compressor;
|
||||
public:
|
||||
CBZip2CompressorReleaser(CBZip2Compressor *compressor): m_Compressor(compressor) {}
|
||||
void Disable() { m_Compressor = NULL; }
|
||||
~CBZip2CompressorReleaser() { if (m_Compressor != NULL) m_Compressor->End(); }
|
||||
};
|
||||
WriteBit2(false); // Randomised = false
|
||||
|
||||
{
|
||||
UInt32 origPtr = m_BlockSorter.Sort(block, blockSize);
|
||||
WriteBits2(origPtr, kNumOrigBits);
|
||||
}
|
||||
|
||||
CMtf8Encoder mtf;
|
||||
int numInUse = 0;
|
||||
{
|
||||
bool inUse[256];
|
||||
bool inUse16[16];
|
||||
UInt32 i;
|
||||
for (i = 0; i < 256; i++)
|
||||
inUse[i] = false;
|
||||
for (i = 0; i < 16; i++)
|
||||
inUse16[i] = false;
|
||||
for (i = 0; i < blockSize; i++)
|
||||
inUse[block[i]] = true;
|
||||
for (i = 0; i < 256; i++)
|
||||
if (inUse[i])
|
||||
{
|
||||
inUse16[i >> 4] = true;
|
||||
mtf.Buffer[numInUse++] = (Byte)i;
|
||||
}
|
||||
for (i = 0; i < 16; i++)
|
||||
WriteBit2(inUse16[i]);
|
||||
for (i = 0; i < 256; i++)
|
||||
if (inUse16[i >> 4])
|
||||
WriteBit2(inUse[i]);
|
||||
}
|
||||
int alphaSize = numInUse + 2;
|
||||
|
||||
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
Byte *mtfs = m_MtfArray;
|
||||
UInt32 mtfArraySize = 0;
|
||||
UInt32 symbolCounts[kMaxAlphaSize];
|
||||
{
|
||||
for (int i = 0; i < kMaxAlphaSize; i++)
|
||||
symbolCounts[i] = 0;
|
||||
}
|
||||
|
||||
{
|
||||
UInt32 rleSize = 0;
|
||||
UInt32 i = 0;
|
||||
do
|
||||
{
|
||||
UInt32 index = m_BlockSorter.Indices[i];
|
||||
if (index == 0)
|
||||
index = blockSize - 1;
|
||||
else
|
||||
index--;
|
||||
int pos = mtf.FindAndMove(block[index]);
|
||||
if (pos == 0)
|
||||
rleSize++;
|
||||
else
|
||||
{
|
||||
while (rleSize != 0)
|
||||
{
|
||||
rleSize--;
|
||||
mtfs[mtfArraySize++] = (rleSize & 1);
|
||||
symbolCounts[rleSize & 1]++;
|
||||
rleSize >>= 1;
|
||||
}
|
||||
if (pos >= 0xFE)
|
||||
{
|
||||
mtfs[mtfArraySize++] = 0xFF;
|
||||
mtfs[mtfArraySize++] = pos - 0xFE;
|
||||
}
|
||||
else
|
||||
mtfs[mtfArraySize++] = pos + 1;
|
||||
symbolCounts[pos + 1]++;
|
||||
}
|
||||
}
|
||||
while (++i < blockSize);
|
||||
|
||||
while (rleSize != 0)
|
||||
{
|
||||
rleSize--;
|
||||
mtfs[mtfArraySize++] = (rleSize & 1);
|
||||
symbolCounts[rleSize & 1]++;
|
||||
rleSize >>= 1;
|
||||
}
|
||||
|
||||
if (alphaSize < 256)
|
||||
mtfs[mtfArraySize++] = (Byte)(alphaSize - 1);
|
||||
else
|
||||
{
|
||||
mtfs[mtfArraySize++] = 0xFF;
|
||||
mtfs[mtfArraySize++] = (Byte)(alphaSize - 256);
|
||||
}
|
||||
symbolCounts[alphaSize - 1]++;
|
||||
}
|
||||
|
||||
UInt32 numSymbols = 0;
|
||||
{
|
||||
for (int i = 0; i < kMaxAlphaSize; i++)
|
||||
numSymbols += symbolCounts[i];
|
||||
}
|
||||
|
||||
int bestNumTables = kNumTablesMin;
|
||||
UInt32 bestPrice = 0xFFFFFFFF;
|
||||
UInt32 startPos = m_OutStreamCurrent->GetPos();
|
||||
UInt32 startCurByte = m_OutStreamCurrent->GetCurByte();
|
||||
for (int nt = kNumTablesMin; nt <= kNumTablesMax + 1; nt++)
|
||||
{
|
||||
int numTables;
|
||||
|
||||
if(m_OptimizeNumTables)
|
||||
{
|
||||
m_OutStreamCurrent->SetPos(startPos);
|
||||
m_OutStreamCurrent->SetCurState((startPos & 7), startCurByte);
|
||||
if (nt <= kNumTablesMax)
|
||||
numTables = nt;
|
||||
else
|
||||
numTables = bestNumTables;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (numSymbols < 200) numTables = 2;
|
||||
else if (numSymbols < 600) numTables = 3;
|
||||
else if (numSymbols < 1200) numTables = 4;
|
||||
else if (numSymbols < 2400) numTables = 5;
|
||||
else numTables = 6;
|
||||
}
|
||||
|
||||
WriteBits2(numTables, kNumTablesBits);
|
||||
|
||||
UInt32 numSelectors = (numSymbols + kGroupSize - 1) / kGroupSize;
|
||||
WriteBits2(numSelectors, kNumSelectorsBits);
|
||||
|
||||
{
|
||||
UInt32 remFreq = numSymbols;
|
||||
int gs = 0;
|
||||
int t = numTables;
|
||||
do
|
||||
{
|
||||
UInt32 tFreq = remFreq / t;
|
||||
int ge = gs;
|
||||
UInt32 aFreq = 0;
|
||||
while (aFreq < tFreq) // && ge < alphaSize)
|
||||
aFreq += symbolCounts[ge++];
|
||||
|
||||
if (ge - 1 > gs && t != numTables && t != 1 && (((numTables - t) & 1) == 1))
|
||||
aFreq -= symbolCounts[--ge];
|
||||
|
||||
NCompression::NHuffman::CEncoder &huffEncoder = m_HuffEncoders[t - 1];
|
||||
int i = 0;
|
||||
do
|
||||
huffEncoder.m_Items[i].Len = (i >= gs && i < ge) ? 0 : 1;
|
||||
while (++i < alphaSize);
|
||||
gs = ge;
|
||||
remFreq -= aFreq;
|
||||
}
|
||||
while(--t != 0);
|
||||
}
|
||||
|
||||
|
||||
for (int pass = 0; pass < kNumHuffPasses; pass++)
|
||||
{
|
||||
{
|
||||
int t = 0;
|
||||
do
|
||||
m_HuffEncoders[t].StartNewBlock();
|
||||
while(++t < numTables);
|
||||
}
|
||||
|
||||
{
|
||||
UInt32 mtfPos = 0;
|
||||
UInt32 g = 0;
|
||||
do
|
||||
{
|
||||
UInt32 symbols[kGroupSize];
|
||||
int i = 0;
|
||||
do
|
||||
{
|
||||
UInt32 symbol = mtfs[mtfPos++];
|
||||
if (symbol >= 0xFF)
|
||||
symbol += mtfs[mtfPos++];
|
||||
symbols[i] = symbol;
|
||||
}
|
||||
while (++i < kGroupSize && mtfPos < mtfArraySize);
|
||||
|
||||
UInt32 bestPrice = 0xFFFFFFFF;
|
||||
int t = 0;
|
||||
do
|
||||
{
|
||||
NCompression::NHuffman::CItem *items = m_HuffEncoders[t].m_Items;
|
||||
UInt32 price = 0;
|
||||
int j = 0;
|
||||
do
|
||||
price += items[symbols[j]].Len;
|
||||
while (++j < i);
|
||||
if (price < bestPrice)
|
||||
{
|
||||
m_Selectors[g] = (Byte)t;
|
||||
bestPrice = price;
|
||||
}
|
||||
}
|
||||
while(++t < numTables);
|
||||
NCompression::NHuffman::CEncoder &huffEncoder = m_HuffEncoders[m_Selectors[g++]];
|
||||
int j = 0;
|
||||
do
|
||||
huffEncoder.AddSymbol(symbols[j]);
|
||||
while (++j < i);
|
||||
}
|
||||
while (mtfPos < mtfArraySize);
|
||||
}
|
||||
|
||||
int t = 0;
|
||||
do
|
||||
{
|
||||
NCompression::NHuffman::CEncoder &huffEncoder = m_HuffEncoders[t];
|
||||
int i = 0;
|
||||
do
|
||||
if (huffEncoder.m_Items[i].Freq == 0)
|
||||
huffEncoder.m_Items[i].Freq = 1;
|
||||
while(++i < alphaSize);
|
||||
Byte levels[kMaxAlphaSize];
|
||||
huffEncoder.BuildTree(levels);
|
||||
}
|
||||
while(++t < numTables);
|
||||
}
|
||||
|
||||
{
|
||||
Byte mtfSel[kNumTablesMax];
|
||||
{
|
||||
int t = 0;
|
||||
do
|
||||
mtfSel[t] = (Byte)t;
|
||||
while(++t < numTables);
|
||||
}
|
||||
|
||||
UInt32 i = 0;
|
||||
do
|
||||
{
|
||||
Byte sel = m_Selectors[i];
|
||||
int pos;
|
||||
for (pos = 0; mtfSel[pos] != sel; pos++)
|
||||
WriteBit2(true);
|
||||
WriteBit2(false);
|
||||
for (; pos > 0; pos--)
|
||||
mtfSel[pos] = mtfSel[pos - 1];
|
||||
mtfSel[0] = sel;
|
||||
}
|
||||
while(++i < numSelectors);
|
||||
}
|
||||
|
||||
{
|
||||
int t = 0;
|
||||
do
|
||||
{
|
||||
NCompression::NHuffman::CItem *items = m_HuffEncoders[t].m_Items;
|
||||
UInt32 len = items[0].Len;
|
||||
WriteBits2(len, kNumLevelsBits);
|
||||
int i = 0;
|
||||
do
|
||||
{
|
||||
UInt32 level = items[i].Len;
|
||||
while (len != level)
|
||||
{
|
||||
WriteBit2(true);
|
||||
if (len < level)
|
||||
{
|
||||
WriteBit2(false);
|
||||
len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteBit2(true);
|
||||
len--;
|
||||
}
|
||||
}
|
||||
WriteBit2(false);
|
||||
}
|
||||
while (++i < alphaSize);
|
||||
}
|
||||
while(++t < numTables);
|
||||
}
|
||||
|
||||
{
|
||||
UInt32 groupSize = 0;
|
||||
UInt32 groupIndex = 0;
|
||||
NCompression::NHuffman::CEncoder *huffEncoder = 0;
|
||||
UInt32 mtfPos = 0;
|
||||
do
|
||||
{
|
||||
UInt32 symbol = mtfs[mtfPos++];
|
||||
if (symbol >= 0xFF)
|
||||
symbol += mtfs[mtfPos++];
|
||||
if (groupSize == 0)
|
||||
{
|
||||
groupSize = kGroupSize;
|
||||
huffEncoder = &m_HuffEncoders[m_Selectors[groupIndex++]];
|
||||
}
|
||||
groupSize--; \
|
||||
huffEncoder->CodeOneValue(m_OutStreamCurrent, symbol);
|
||||
}
|
||||
while (mtfPos < mtfArraySize);
|
||||
}
|
||||
|
||||
if (!m_OptimizeNumTables)
|
||||
break;
|
||||
UInt32 price = m_OutStreamCurrent->GetPos() - startPos;
|
||||
if (price <= bestPrice)
|
||||
{
|
||||
if (nt == kNumTablesMax)
|
||||
break;
|
||||
bestPrice = price;
|
||||
bestNumTables = nt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// blockSize > 0
|
||||
UInt32 CEncoder::EncodeBlockWithHeaders(Byte *block, UInt32 blockSize)
|
||||
{
|
||||
WriteByte2(kBlockSig0);
|
||||
WriteByte2(kBlockSig1);
|
||||
WriteByte2(kBlockSig2);
|
||||
WriteByte2(kBlockSig3);
|
||||
WriteByte2(kBlockSig4);
|
||||
WriteByte2(kBlockSig5);
|
||||
|
||||
CBZip2CRC crc;
|
||||
int numReps = 0;
|
||||
Byte prevByte = block[0];
|
||||
UInt32 i = 0;
|
||||
do
|
||||
{
|
||||
Byte b = block[i];
|
||||
if (numReps == kRleModeRepSize)
|
||||
{
|
||||
for (; b > 0; b--)
|
||||
crc.UpdateByte(prevByte);
|
||||
numReps = 0;
|
||||
continue;
|
||||
}
|
||||
if (prevByte == b)
|
||||
numReps++;
|
||||
else
|
||||
{
|
||||
numReps = 1;
|
||||
prevByte = b;
|
||||
}
|
||||
crc.UpdateByte(b);
|
||||
}
|
||||
while (++i < blockSize);
|
||||
UInt32 crcRes = crc.GetDigest();
|
||||
WriteCRC2(crcRes);
|
||||
EncodeBlock(block, blockSize);
|
||||
return crcRes;
|
||||
}
|
||||
|
||||
void CEncoder::EncodeBlock2(CBZip2CombinedCRC &combinedCRC,
|
||||
Byte *block, UInt32 blockSize, UInt32 numPasses)
|
||||
{
|
||||
bool needCompare = false;
|
||||
CBZip2CombinedCRC specCombinedCRC = combinedCRC;
|
||||
|
||||
UInt32 startBytePos = m_OutStreamCurrent->GetBytePos();
|
||||
UInt32 startPos = m_OutStreamCurrent->GetPos();
|
||||
UInt32 startCurByte = m_OutStreamCurrent->GetCurByte();
|
||||
UInt32 endCurByte;
|
||||
UInt32 endPos;
|
||||
if (numPasses > 1 && blockSize >= (1 << 10))
|
||||
{
|
||||
UInt32 blockSize0 = blockSize / 2;
|
||||
for (;(block[blockSize0] == block[blockSize0 - 1] ||
|
||||
block[blockSize0 - 1] == block[blockSize0 - 2]) &&
|
||||
blockSize0 < blockSize; blockSize0++);
|
||||
if (blockSize0 < blockSize)
|
||||
{
|
||||
EncodeBlock2(specCombinedCRC, block, blockSize0, numPasses - 1);
|
||||
EncodeBlock2(specCombinedCRC, block + blockSize0, blockSize - blockSize0,
|
||||
numPasses - 1);
|
||||
endPos = m_OutStreamCurrent->GetPos();
|
||||
endCurByte = m_OutStreamCurrent->GetCurByte();
|
||||
if ((endPos & 7) > 0)
|
||||
WriteBits2(0, 8 - (endPos & 7));
|
||||
m_OutStreamCurrent->SetCurState((startPos & 7), startCurByte);
|
||||
needCompare = true;
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 startBytePos2 = m_OutStreamCurrent->GetBytePos();
|
||||
UInt32 startPos2 = m_OutStreamCurrent->GetPos();
|
||||
UInt32 crcVal = EncodeBlockWithHeaders(block, blockSize);
|
||||
UInt32 endPos2 = m_OutStreamCurrent->GetPos();
|
||||
|
||||
combinedCRC.Update(crcVal);
|
||||
|
||||
if (needCompare)
|
||||
{
|
||||
UInt32 size2 = endPos2 - startPos2;
|
||||
if (size2 < endPos - startPos)
|
||||
{
|
||||
UInt32 numBytes = m_OutStreamCurrent->GetBytePos() - startBytePos2;
|
||||
Byte *buffer = m_OutStreamCurrent->GetStream();
|
||||
for (UInt32 i = 0; i < numBytes; i++)
|
||||
buffer[startBytePos + i] = buffer[startBytePos2 + i];
|
||||
m_OutStreamCurrent->SetPos(startPos + endPos2 - startPos2);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_OutStreamCurrent->SetPos(endPos);
|
||||
m_OutStreamCurrent->SetCurState((endPos & 7), endCurByte);
|
||||
combinedCRC = specCombinedCRC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CEncoder::EncodeBlock3(CBZip2CombinedCRC &combinedCRC, UInt32 blockSize)
|
||||
{
|
||||
CMsbfEncoderTemp outStreamTemp;
|
||||
outStreamTemp.SetStream(m_TempArray);
|
||||
outStreamTemp.Init();
|
||||
m_OutStreamCurrent = &outStreamTemp;
|
||||
|
||||
EncodeBlock2(combinedCRC, m_Block, blockSize, m_NumPasses);
|
||||
|
||||
UInt32 size = outStreamTemp.GetPos();
|
||||
UInt32 bytesSize = (size / 8);
|
||||
for (UInt32 i = 0; i < bytesSize; i++)
|
||||
m_OutStream.WriteBits(m_TempArray[i], 8);
|
||||
WriteBits(outStreamTemp.GetCurByte(), (size & 7));
|
||||
}
|
||||
|
||||
HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
CBZip2Compressor bzStream;
|
||||
bzStream.bzalloc = NULL;
|
||||
bzStream.bzfree = NULL;
|
||||
bzStream.opaque = NULL;
|
||||
|
||||
int result = bzStream.Init(9, 0, 0);
|
||||
switch(result)
|
||||
if (!m_BlockSorter.Create(kBlockSizeMax))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (m_Block == 0)
|
||||
{
|
||||
case BZ_OK:
|
||||
break;
|
||||
case BZ_MEM_ERROR:
|
||||
m_Block = (Byte *)BigAlloc(kBlockSizeMax * 5 + kBlockSizeMax / 10 + (20 << 10));
|
||||
if (m_Block == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
default:
|
||||
return E_FAIL;
|
||||
m_MtfArray = m_Block + kBlockSizeMax;
|
||||
m_TempArray = m_MtfArray + kBlockSizeMax * 2 + 2;
|
||||
}
|
||||
CBZip2CompressorReleaser releaser(&bzStream);
|
||||
bzStream.avail_in = 0;
|
||||
if (!m_InStream.Create(kBufferSize))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!m_OutStream.Create(kBufferSize))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (m_NeedHuffmanCreate)
|
||||
{
|
||||
for (int i = 0; i < kNumTablesMax; i++)
|
||||
if (!m_HuffEncoders[i].Create(kMaxAlphaSize, 0, 0, kMaxHuffmanLen))
|
||||
return E_OUTOFMEMORY;
|
||||
m_NeedHuffmanCreate = false;
|
||||
}
|
||||
|
||||
m_InStream.SetStream(inStream);
|
||||
m_InStream.Init();
|
||||
|
||||
m_OutStream.SetStream(outStream);
|
||||
m_OutStream.Init();
|
||||
|
||||
CFlusher flusher(this);
|
||||
|
||||
CBZip2CombinedCRC combinedCRC;
|
||||
|
||||
WriteByte(kArSig0);
|
||||
WriteByte(kArSig1);
|
||||
WriteByte(kArSig2);
|
||||
WriteByte((Byte)(kArSig3 + m_BlockSizeMult));
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (bzStream.avail_in == 0)
|
||||
{
|
||||
bzStream.next_in = (char *)m_InBuffer;
|
||||
UINT32 processedSize;
|
||||
RINOK(inStream->Read(m_InBuffer, kBufferSize, &processedSize));
|
||||
bzStream.avail_in = processedSize;
|
||||
}
|
||||
|
||||
bzStream.next_out = (char *)m_OutBuffer;
|
||||
bzStream.avail_out = kBufferSize;
|
||||
bool askFinish = (bzStream.avail_in == 0);
|
||||
result = bzStream.Compress(askFinish ? BZ_FINISH : BZ_RUN);
|
||||
UINT32 numBytesToWrite = kBufferSize - bzStream.avail_out;
|
||||
if (numBytesToWrite > 0)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
RINOK(outStream->Write(m_OutBuffer, numBytesToWrite, &processedSize));
|
||||
if (numBytesToWrite != processedSize)
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (result == BZ_STREAM_END)
|
||||
UInt32 blockSize = ReadRleBlock(m_Block);
|
||||
if (blockSize == 0)
|
||||
break;
|
||||
switch(result)
|
||||
EncodeBlock3(combinedCRC, blockSize);
|
||||
if (progress)
|
||||
{
|
||||
case BZ_RUN_OK:
|
||||
if (!askFinish)
|
||||
break;
|
||||
return E_FAIL;
|
||||
case BZ_FINISH_OK:
|
||||
if (askFinish)
|
||||
break;
|
||||
return E_FAIL;
|
||||
case BZ_MEM_ERROR:
|
||||
return E_OUTOFMEMORY;
|
||||
default:
|
||||
return E_FAIL;
|
||||
}
|
||||
if (progress != NULL)
|
||||
{
|
||||
UINT64 totalIn = bzStream.GetTotalIn();
|
||||
UINT64 totalOut = bzStream.GetTotalOut();
|
||||
RINOK(progress->SetRatioInfo(&totalIn, &totalOut));
|
||||
UInt64 packSize = m_InStream.GetProcessedSize();
|
||||
UInt64 unpackSize = m_OutStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &unpackSize));
|
||||
}
|
||||
}
|
||||
// result = bzStream.End();
|
||||
WriteByte(kFinSig0);
|
||||
WriteByte(kFinSig1);
|
||||
WriteByte(kFinSig2);
|
||||
WriteByte(kFinSig3);
|
||||
WriteByte(kFinSig4);
|
||||
WriteByte(kFinSig5);
|
||||
|
||||
WriteCRC(combinedCRC.GetDigest());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties)
|
||||
{
|
||||
for(UInt32 i = 0; i < numProperties; i++)
|
||||
{
|
||||
const PROPVARIANT &property = properties[i];
|
||||
switch(propIDs[i])
|
||||
{
|
||||
case NCoderPropID::kNumPasses:
|
||||
{
|
||||
if (property.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
UInt32 numPasses = property.ulVal;
|
||||
if(numPasses == 0 || numPasses > 10)
|
||||
return E_INVALIDARG;
|
||||
m_NumPasses = numPasses;
|
||||
m_OptimizeNumTables = (m_NumPasses > 1);
|
||||
break;
|
||||
}
|
||||
case NCoderPropID::kDictionarySize:
|
||||
{
|
||||
if (property.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
UInt32 dictionary = property.ulVal / kBlockSizeStep;
|
||||
if (dictionary < kBlockSizeMultMin)
|
||||
dictionary = kBlockSizeMultMin;
|
||||
else if (dictionary > kBlockSizeMultMax)
|
||||
dictionary = kBlockSizeMultMax;
|
||||
m_BlockSizeMult = dictionary;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,34 +1,158 @@
|
||||
// Compress/BZip2/Encoder.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __COMPRESS_BZIP2_ENCODER_H
|
||||
#define __COMPRESS_BZIP2_ENCODER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../ICoder.h"
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../Common/MSBFEncoder.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
#include "../../Common/OutBuffer.h"
|
||||
#include "../Huffman/HuffmanEncoder.h"
|
||||
#include "../BWT/BlockSort.h"
|
||||
#include "BZip2Const.h"
|
||||
#include "BZip2CRC.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NBZip2 {
|
||||
|
||||
class CMsbfEncoderTemp
|
||||
{
|
||||
UInt32 m_Pos;
|
||||
int m_BitPos;
|
||||
Byte m_CurByte;
|
||||
Byte *Buffer;
|
||||
public:
|
||||
void SetStream(Byte *buffer) { Buffer = buffer; }
|
||||
Byte *GetStream() const { return Buffer; }
|
||||
|
||||
void Init()
|
||||
{
|
||||
m_Pos = 0;
|
||||
m_BitPos = 8;
|
||||
m_CurByte = 0;
|
||||
}
|
||||
|
||||
void Flush()
|
||||
{
|
||||
if(m_BitPos < 8)
|
||||
WriteBits(0, m_BitPos);
|
||||
}
|
||||
|
||||
void WriteBits(UInt32 value, int numBits)
|
||||
{
|
||||
while(numBits > 0)
|
||||
{
|
||||
int numNewBits = MyMin(numBits, m_BitPos);
|
||||
numBits -= numNewBits;
|
||||
|
||||
m_CurByte <<= numNewBits;
|
||||
UInt32 newBits = value >> numBits;
|
||||
m_CurByte |= Byte(newBits);
|
||||
value -= (newBits << numBits);
|
||||
|
||||
m_BitPos -= numNewBits;
|
||||
|
||||
if (m_BitPos == 0)
|
||||
{
|
||||
Buffer[m_Pos++] = m_CurByte;
|
||||
m_BitPos = 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 GetBytePos() const { return m_Pos ; }
|
||||
UInt32 GetPos() const { return m_Pos * 8 + (8 - m_BitPos); }
|
||||
Byte GetCurByte() const { return m_CurByte; }
|
||||
void SetPos(UInt32 bitPos)
|
||||
{
|
||||
m_Pos = bitPos / 8;
|
||||
m_BitPos = 8 - (bitPos & 7);
|
||||
}
|
||||
void SetCurState(UInt32 bitPos, Byte curByte)
|
||||
{
|
||||
m_BitPos = 8 - bitPos;
|
||||
m_CurByte = curByte;
|
||||
}
|
||||
};
|
||||
|
||||
class CEncoder :
|
||||
public ICompressCoder,
|
||||
public ICompressSetCoderProperties,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
BYTE *m_InBuffer;
|
||||
BYTE *m_OutBuffer;
|
||||
Byte *m_Block;
|
||||
CInBuffer m_InStream;
|
||||
NStream::NMSBF::CEncoder<COutBuffer> m_OutStream;
|
||||
CMsbfEncoderTemp *m_OutStreamCurrent;
|
||||
CBlockSorter m_BlockSorter;
|
||||
|
||||
bool m_NeedHuffmanCreate;
|
||||
NCompression::NHuffman::CEncoder m_HuffEncoders[kNumTablesMax];
|
||||
|
||||
Byte *m_MtfArray;
|
||||
Byte *m_TempArray;
|
||||
|
||||
Byte m_Selectors[kNumSelectorsMax];
|
||||
|
||||
UInt32 m_BlockSizeMult;
|
||||
UInt32 m_NumPasses;
|
||||
bool m_OptimizeNumTables;
|
||||
|
||||
UInt32 ReadRleBlock(Byte *buffer);
|
||||
|
||||
void WriteBits2(UInt32 value, UInt32 numBits);
|
||||
void WriteByte2(Byte b);
|
||||
void WriteBit2(bool v);
|
||||
void WriteCRC2(UInt32 v);
|
||||
|
||||
void WriteBits(UInt32 value, UInt32 numBits);
|
||||
void WriteByte(Byte b);
|
||||
void WriteBit(bool v);
|
||||
void WriteCRC(UInt32 v);
|
||||
|
||||
void EncodeBlock(Byte *block, UInt32 blockSize);
|
||||
UInt32 EncodeBlockWithHeaders(Byte *block, UInt32 blockSize);
|
||||
void EncodeBlock2(CBZip2CombinedCRC &combinedCRC, Byte *block, UInt32 blockSize, UInt32 numPasses);
|
||||
void EncodeBlock3(CBZip2CombinedCRC &combinedCRC, UInt32 blockSize);
|
||||
|
||||
public:
|
||||
CEncoder();
|
||||
~CEncoder();
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
HRESULT Flush() { return m_OutStream.Flush(); }
|
||||
|
||||
void ReleaseStreams()
|
||||
{
|
||||
m_InStream.ReleaseStream();
|
||||
m_OutStream.ReleaseStream();
|
||||
}
|
||||
|
||||
// STDMETHOD(ReleaseStreams)();
|
||||
class CFlusher
|
||||
{
|
||||
CEncoder *_coder;
|
||||
public:
|
||||
bool NeedFlush;
|
||||
CFlusher(CEncoder *coder): _coder(coder), NeedFlush(true) {}
|
||||
~CFlusher()
|
||||
{
|
||||
if (NeedFlush)
|
||||
_coder->Flush();
|
||||
_coder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
|
||||
|
||||
HRESULT CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#define INITGUID
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
#include "BZip2Encoder.h"
|
||||
#include "BZip2Decoder.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
// {23170F69-40C1-278B-0402-020000000000}
|
||||
DEFINE_GUID(CLSID_CCompressBZip2Decoder,
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,8,1,0
|
||||
PRODUCTVERSION 3,8,1,0
|
||||
FILEVERSION 4,19,0,0
|
||||
PRODUCTVERSION 4,19,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -85,14 +85,14 @@ BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", " \0"
|
||||
VALUE "FileDescription", "BZip2 Coder\0"
|
||||
VALUE "FileVersion", "3, 8, 1, 0\0"
|
||||
VALUE "FileVersion", "4, 19, 0, 0\0"
|
||||
VALUE "InternalName", "BZip2\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "BZip2.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "3, 8, 1, 0\0"
|
||||
VALUE "ProductVersion", "4, 19, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
||||
9
7zip/Compress/BZip2Original/BZip2.def
Executable file
9
7zip/Compress/BZip2Original/BZip2.def
Executable file
@@ -0,0 +1,9 @@
|
||||
; BZip2.def
|
||||
|
||||
LIBRARY BZip2.dll
|
||||
|
||||
EXPORTS
|
||||
CreateObject PRIVATE
|
||||
GetNumberOfMethods PRIVATE
|
||||
GetMethodProperty PRIVATE
|
||||
|
||||
305
7zip/Compress/BZip2Original/BZip2.dsp
Executable file
305
7zip/Compress/BZip2Original/BZip2.dsp
Executable file
@@ -0,0 +1,305 @@
|
||||
# Microsoft Developer Studio Project File - Name="BZip2" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=BZip2 - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "BZip2.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "BZip2.mak" CFG="BZip2 - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "BZip2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "BZip2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "BZ_NO_STDIO" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\BZip2.dll" /opt:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\BZip2.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "BZip2 - Win32 Release"
|
||||
# Name "BZip2 - Win32 Debug"
|
||||
# Begin Group "Spec"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DllExports.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
# ADD CPP /Yc"StdAfx.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Origianl"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\blocksort.c
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\bzlib.c
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\bzlib.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\bzlib_private.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\compress.c
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\crctable.c
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\decompress.c
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\huffman.c
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Original\randtable.c
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\NewHandler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\NewHandler.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2Decoder.cpp
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2Decoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2Encoder.cpp
|
||||
|
||||
!IF "$(CFG)" == "BZip2 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2Encoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2Error.cpp
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
7zip/Compress/BZip2Original/BZip2.dsw
Executable file
29
7zip/Compress/BZip2Original/BZip2.dsw
Executable file
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "BZip2"=.\BZip2.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
131
7zip/Compress/BZip2Original/BZip2Decoder.cpp
Executable file
131
7zip/Compress/BZip2Original/BZip2Decoder.cpp
Executable file
@@ -0,0 +1,131 @@
|
||||
// BZip2Decoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "BZip2Decoder.h"
|
||||
|
||||
#include "../../../Common/Alloc.h"
|
||||
#include "Original/bzlib.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NBZip2 {
|
||||
|
||||
static const UInt32 kBufferSize = (1 << 20);
|
||||
|
||||
CDecoder::~CDecoder()
|
||||
{
|
||||
BigFree(m_InBuffer);
|
||||
}
|
||||
|
||||
struct CBZip2Decompressor: public bz_stream
|
||||
{
|
||||
int Init(int verbosity, int small) { return BZ2_bzDecompressInit(this, verbosity, small); }
|
||||
int Decompress() { return BZ2_bzDecompress(this); }
|
||||
int End() { return BZ2_bzDecompressEnd(this); }
|
||||
UInt64 GetTotalIn() const { return (UInt64(total_in_hi32) << 32) + total_in_lo32; }
|
||||
UInt64 GetTotalOut() const { return (UInt64(total_out_hi32) << 32) + total_out_lo32; }
|
||||
};
|
||||
|
||||
class CBZip2DecompressorReleaser
|
||||
{
|
||||
CBZip2Decompressor *m_Decompressor;
|
||||
public:
|
||||
CBZip2DecompressorReleaser(CBZip2Decompressor *decompressor): m_Decompressor(decompressor) {}
|
||||
void Diable() { m_Decompressor = NULL; }
|
||||
~CBZip2DecompressorReleaser() { if (m_Decompressor != NULL) m_Decompressor->End(); }
|
||||
};
|
||||
|
||||
STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
m_InSize = 0;
|
||||
if (m_InBuffer == 0)
|
||||
{
|
||||
m_InBuffer = (Byte *)BigAlloc(kBufferSize * 2);
|
||||
if (m_InBuffer == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
Byte *outBuffer = m_InBuffer + kBufferSize;
|
||||
|
||||
CBZip2Decompressor bzStream;
|
||||
bzStream.bzalloc = NULL;
|
||||
bzStream.bzfree = NULL;
|
||||
bzStream.opaque = NULL;
|
||||
|
||||
int result = bzStream.Init(0, 0);
|
||||
switch(result)
|
||||
{
|
||||
case BZ_OK:
|
||||
break;
|
||||
case BZ_MEM_ERROR:
|
||||
return E_OUTOFMEMORY;
|
||||
default:
|
||||
return E_FAIL;
|
||||
}
|
||||
CBZip2DecompressorReleaser releaser(&bzStream);
|
||||
bzStream.avail_in = 0;
|
||||
while (true)
|
||||
{
|
||||
if (bzStream.avail_in == 0)
|
||||
{
|
||||
bzStream.next_in = (char *)m_InBuffer;
|
||||
UInt32 processedSize;
|
||||
RINOK(inStream->Read(m_InBuffer, kBufferSize, &processedSize));
|
||||
bzStream.avail_in = processedSize;
|
||||
}
|
||||
|
||||
bzStream.next_out = (char *)outBuffer;
|
||||
bzStream.avail_out = kBufferSize;
|
||||
result = bzStream.Decompress();
|
||||
UInt32 numBytesToWrite = kBufferSize - bzStream.avail_out;
|
||||
if (numBytesToWrite > 0)
|
||||
{
|
||||
UInt32 processedSize;
|
||||
RINOK(outStream->Write(outBuffer, numBytesToWrite, &processedSize));
|
||||
if (numBytesToWrite != processedSize)
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (result == BZ_STREAM_END)
|
||||
break;
|
||||
switch(result)
|
||||
{
|
||||
case BZ_DATA_ERROR:
|
||||
case BZ_DATA_ERROR_MAGIC:
|
||||
return S_FALSE;
|
||||
case BZ_OK:
|
||||
break;
|
||||
case BZ_MEM_ERROR:
|
||||
return E_OUTOFMEMORY;
|
||||
default:
|
||||
return E_FAIL;
|
||||
}
|
||||
if (progress != NULL)
|
||||
{
|
||||
UInt64 totalIn = bzStream.GetTotalIn();
|
||||
UInt64 totalOut = bzStream.GetTotalOut();
|
||||
RINOK(progress->SetRatioInfo(&totalIn, &totalOut));
|
||||
}
|
||||
}
|
||||
m_InSize = bzStream.GetTotalIn();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
return E_INVALIDARG;
|
||||
*value = m_InSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
38
7zip/Compress/BZip2Original/BZip2Decoder.h
Executable file
38
7zip/Compress/BZip2Original/BZip2Decoder.h
Executable file
@@ -0,0 +1,38 @@
|
||||
// Compress/BZip2/Decoder.h
|
||||
|
||||
#ifndef __COMPRESS_BZIP2_DECODER_H
|
||||
#define __COMPRESS_BZIP2_DECODER_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NBZip2 {
|
||||
|
||||
class CDecoder :
|
||||
public ICompressCoder,
|
||||
public ICompressGetInStreamProcessedSize,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
Byte *m_InBuffer;
|
||||
UInt64 m_InSize;
|
||||
public:
|
||||
CDecoder(): m_InBuffer(0), m_InSize(0) {};
|
||||
~CDecoder();
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
|
||||
|
||||
STDMETHOD(CodeReal)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
120
7zip/Compress/BZip2Original/BZip2Encoder.cpp
Executable file
120
7zip/Compress/BZip2Original/BZip2Encoder.cpp
Executable file
@@ -0,0 +1,120 @@
|
||||
// BZip2Encoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "BZip2Encoder.h"
|
||||
|
||||
#include "../../../Common/Alloc.h"
|
||||
#include "Original/bzlib.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NBZip2 {
|
||||
|
||||
static const UInt32 kBufferSize = (1 << 20);
|
||||
|
||||
CEncoder::~CEncoder()
|
||||
{
|
||||
BigFree(m_InBuffer);
|
||||
}
|
||||
|
||||
struct CBZip2Compressor: public bz_stream
|
||||
{
|
||||
int Init(int blockSize100k, int verbosity, int small)
|
||||
{ return BZ2_bzCompressInit(this, blockSize100k, verbosity, small); }
|
||||
int Compress(int action ) { return BZ2_bzCompress(this, action ); }
|
||||
int End() { return BZ2_bzCompressEnd(this); }
|
||||
UInt64 GetTotalIn() const { return (UInt64(total_in_hi32) << 32) + total_in_lo32; }
|
||||
UInt64 GetTotalOut() const { return (UInt64(total_out_hi32) << 32) + total_out_lo32; }
|
||||
};
|
||||
|
||||
class CBZip2CompressorReleaser
|
||||
{
|
||||
CBZip2Compressor *m_Compressor;
|
||||
public:
|
||||
CBZip2CompressorReleaser(CBZip2Compressor *compressor): m_Compressor(compressor) {}
|
||||
void Disable() { m_Compressor = NULL; }
|
||||
~CBZip2CompressorReleaser() { if (m_Compressor != NULL) m_Compressor->End(); }
|
||||
};
|
||||
|
||||
|
||||
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (m_InBuffer == 0)
|
||||
{
|
||||
m_InBuffer = (Byte *)BigAlloc(kBufferSize * 2);
|
||||
if (m_InBuffer == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
Byte *outBuffer = m_InBuffer + kBufferSize;
|
||||
|
||||
CBZip2Compressor bzStream;
|
||||
bzStream.bzalloc = NULL;
|
||||
bzStream.bzfree = NULL;
|
||||
bzStream.opaque = NULL;
|
||||
|
||||
int result = bzStream.Init(9, 0, 0);
|
||||
switch(result)
|
||||
{
|
||||
case BZ_OK:
|
||||
break;
|
||||
case BZ_MEM_ERROR:
|
||||
return E_OUTOFMEMORY;
|
||||
default:
|
||||
return E_FAIL;
|
||||
}
|
||||
CBZip2CompressorReleaser releaser(&bzStream);
|
||||
bzStream.avail_in = 0;
|
||||
while (true)
|
||||
{
|
||||
if (bzStream.avail_in == 0)
|
||||
{
|
||||
bzStream.next_in = (char *)m_InBuffer;
|
||||
UInt32 processedSize;
|
||||
RINOK(inStream->Read(m_InBuffer, kBufferSize, &processedSize));
|
||||
bzStream.avail_in = processedSize;
|
||||
}
|
||||
|
||||
bzStream.next_out = (char *)outBuffer;
|
||||
bzStream.avail_out = kBufferSize;
|
||||
bool askFinish = (bzStream.avail_in == 0);
|
||||
result = bzStream.Compress(askFinish ? BZ_FINISH : BZ_RUN);
|
||||
UInt32 numBytesToWrite = kBufferSize - bzStream.avail_out;
|
||||
if (numBytesToWrite > 0)
|
||||
{
|
||||
UInt32 processedSize;
|
||||
RINOK(outStream->Write(outBuffer, numBytesToWrite, &processedSize));
|
||||
if (numBytesToWrite != processedSize)
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (result == BZ_STREAM_END)
|
||||
break;
|
||||
switch(result)
|
||||
{
|
||||
case BZ_RUN_OK:
|
||||
if (!askFinish)
|
||||
break;
|
||||
return E_FAIL;
|
||||
case BZ_FINISH_OK:
|
||||
if (askFinish)
|
||||
break;
|
||||
return E_FAIL;
|
||||
case BZ_MEM_ERROR:
|
||||
return E_OUTOFMEMORY;
|
||||
default:
|
||||
return E_FAIL;
|
||||
}
|
||||
if (progress != NULL)
|
||||
{
|
||||
UInt64 totalIn = bzStream.GetTotalIn();
|
||||
UInt64 totalOut = bzStream.GetTotalOut();
|
||||
RINOK(progress->SetRatioInfo(&totalIn, &totalOut));
|
||||
}
|
||||
}
|
||||
// result = bzStream.End();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
30
7zip/Compress/BZip2Original/BZip2Encoder.h
Executable file
30
7zip/Compress/BZip2Original/BZip2Encoder.h
Executable file
@@ -0,0 +1,30 @@
|
||||
// Compress/BZip2/Encoder.h
|
||||
|
||||
#ifndef __COMPRESS_BZIP2_ENCODER_H
|
||||
#define __COMPRESS_BZIP2_ENCODER_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NBZip2 {
|
||||
|
||||
class CEncoder :
|
||||
public ICompressCoder,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
Byte *m_InBuffer;
|
||||
public:
|
||||
CEncoder(): m_InBuffer(0) {};
|
||||
~CEncoder();
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
86
7zip/Compress/BZip2Original/DllExports.cpp
Executable file
86
7zip/Compress/BZip2Original/DllExports.cpp
Executable file
@@ -0,0 +1,86 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
#include "BZip2Encoder.h"
|
||||
#include "BZip2Decoder.h"
|
||||
|
||||
// {23170F69-40C1-278B-0402-020000000000}
|
||||
DEFINE_GUID(CLSID_CCompressBZip2Decoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0402-020000000100}
|
||||
DEFINE_GUID(CLSID_CCompressBZip2Encoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00);
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
int correctInterface = (*iid == IID_ICompressCoder);
|
||||
CMyComPtr<ICompressCoder> coder;
|
||||
if (*clsid == CLSID_CCompressBZip2Decoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCompress::NBZip2::CDecoder;
|
||||
}
|
||||
else if (*clsid == CLSID_CCompressBZip2Encoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCompress::NBZip2::CEncoder;
|
||||
}
|
||||
else
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
*outObject = coder.Detach();
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDAPI GetNumberOfMethods(UINT32 *numMethods)
|
||||
{
|
||||
*numMethods = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
if (index != 0)
|
||||
return E_INVALIDARG;
|
||||
::VariantClear((tagVARIANT *)value);
|
||||
switch(propID)
|
||||
{
|
||||
case NMethodPropID::kID:
|
||||
{
|
||||
const char id[] = { 0x04, 0x02, 0x02 };
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
case NMethodPropID::kName:
|
||||
if ((value->bstrVal = ::SysAllocString(L"BZip2")) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kDecoder:
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)&CLSID_CCompressBZip2Decoder, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kEncoder:
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)&CLSID_CCompressBZip2Encoder, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
3
7zip/Compress/BZip2Original/StdAfx.cpp
Executable file
3
7zip/Compress/BZip2Original/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
8
7zip/Compress/BZip2Original/StdAfx.h
Executable file
8
7zip/Compress/BZip2Original/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
15
7zip/Compress/BZip2Original/resource.h
Executable file
15
7zip/Compress/BZip2Original/resource.h
Executable file
@@ -0,0 +1,15 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by resource.rc
|
||||
//
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
121
7zip/Compress/BZip2Original/resource.rc
Executable file
121
7zip/Compress/BZip2Original/resource.rc
Executable file
@@ -0,0 +1,121 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Russian resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
||||
#pragma code_page(1251)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Russian resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,16,0,0
|
||||
PRODUCTVERSION 4,16,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", " \0"
|
||||
VALUE "FileDescription", "BZip2 Coder\0"
|
||||
VALUE "FileVersion", "4, 16, 0, 0\0"
|
||||
VALUE "InternalName", "BZip2\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "BZip2.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "4, 16, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
@@ -3,67 +3,14 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ARM.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "BranchARM.c"
|
||||
|
||||
static HRESULT BC_ARM_Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
|
||||
UInt32 CBC_ARM_Encoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
UINT32 nowPos = 0;
|
||||
UINT64 nowPos64 = 0;
|
||||
UINT32 bufferPos = 0;
|
||||
while(true)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
UINT32 size = kBufferSize - bufferPos;
|
||||
RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
|
||||
UINT32 endPos = bufferPos + processedSize;
|
||||
if (endPos < 4)
|
||||
{
|
||||
if (endPos > 0)
|
||||
{
|
||||
RINOK(outStream->Write(buffer, endPos, &processedSize));
|
||||
if (endPos != processedSize)
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
for (bufferPos = 0; bufferPos <= endPos - 4; bufferPos += 4)
|
||||
{
|
||||
if (buffer[bufferPos + 3] == 0xeb)
|
||||
{
|
||||
UINT32 src =
|
||||
(buffer[bufferPos + 2] << 16) |
|
||||
(buffer[bufferPos + 1] << 8) |
|
||||
(buffer[bufferPos + 0]);
|
||||
|
||||
src <<= 2;
|
||||
UINT32 dest;
|
||||
if (encoding)
|
||||
dest = nowPos + bufferPos + 8 + src;
|
||||
else
|
||||
dest = src - (nowPos + bufferPos + 8);
|
||||
dest >>= 2;
|
||||
buffer[bufferPos + 2] = (dest >> 16);
|
||||
buffer[bufferPos + 1] = (dest >> 8);
|
||||
buffer[bufferPos + 0] = dest;
|
||||
}
|
||||
}
|
||||
nowPos += bufferPos;
|
||||
nowPos64 += bufferPos;
|
||||
RINOK(outStream->Write(buffer, bufferPos, &processedSize));
|
||||
if (bufferPos != processedSize)
|
||||
return E_FAIL;
|
||||
if (progress != NULL)
|
||||
{
|
||||
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
|
||||
}
|
||||
|
||||
UINT32 i = 0;
|
||||
while(bufferPos < endPos)
|
||||
buffer[i++] = buffer[bufferPos++];
|
||||
bufferPos = i;
|
||||
}
|
||||
return ::ARM_Convert(data, size, _bufferPos, 1);
|
||||
}
|
||||
|
||||
MyClassImp(BC_ARM)
|
||||
UInt32 CBC_ARM_Decoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::ARM_Convert(data, size, _bufferPos, 0);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
// ARM.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARM_H
|
||||
#define __ARM_H
|
||||
|
||||
#include "Coder.h"
|
||||
#include "BranchCoder.h"
|
||||
|
||||
MyClass(BC_ARM, 0x05, 1)
|
||||
MyClassA(BC_ARM, 0x05, 1)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,74 +3,14 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ARMThumb.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "BranchARMThumb.c"
|
||||
|
||||
static HRESULT BC_ARMThumb_Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
|
||||
UInt32 CBC_ARMThumb_Encoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
UINT32 nowPos = 0;
|
||||
UINT64 nowPos64 = 0;
|
||||
UINT32 bufferPos = 0;
|
||||
while(true)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
UINT32 size = kBufferSize - bufferPos;
|
||||
RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
|
||||
UINT32 endPos = bufferPos + processedSize;
|
||||
if (endPos < 4)
|
||||
{
|
||||
if (endPos > 0)
|
||||
{
|
||||
RINOK(outStream->Write(buffer, endPos, &processedSize));
|
||||
if (endPos != processedSize)
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
for (bufferPos = 0; bufferPos <= endPos - 4; bufferPos += 2)
|
||||
{
|
||||
if ((buffer[bufferPos + 1] & 0xF8) == 0xF0 &&
|
||||
(buffer[bufferPos + 3] & 0xF8) == 0xF8)
|
||||
{
|
||||
UINT32 src =
|
||||
((buffer[bufferPos + 1] & 0x7) << 19) |
|
||||
(buffer[bufferPos + 0] << 11) |
|
||||
((buffer[bufferPos + 3] & 0x7) << 8) |
|
||||
(buffer[bufferPos + 2]);
|
||||
|
||||
src <<= 1;
|
||||
UINT32 dest;
|
||||
if (encoding)
|
||||
dest = nowPos + bufferPos + 4 + src;
|
||||
else
|
||||
dest = src - (nowPos + bufferPos + 4);
|
||||
dest >>= 1;
|
||||
|
||||
buffer[bufferPos + 1] = 0xF0 | ((dest >> 19) & 0x7);
|
||||
buffer[bufferPos + 0] = (dest >> 11);
|
||||
buffer[bufferPos + 3] = 0xF8 | ((dest >> 8) & 0x7);
|
||||
buffer[bufferPos + 2] = (dest);
|
||||
bufferPos += 2;
|
||||
}
|
||||
}
|
||||
nowPos += bufferPos;
|
||||
nowPos64 += bufferPos;
|
||||
RINOK(outStream->Write(buffer, bufferPos, &processedSize));
|
||||
if (bufferPos != processedSize)
|
||||
return E_FAIL;
|
||||
if (progress != NULL)
|
||||
{
|
||||
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
|
||||
}
|
||||
|
||||
UINT32 i = 0;
|
||||
while(bufferPos < endPos)
|
||||
buffer[i++] = buffer[bufferPos++];
|
||||
bufferPos = i;
|
||||
}
|
||||
return ::ARMThumb_Convert(data, size, _bufferPos, 1);
|
||||
}
|
||||
|
||||
MyClassImp(BC_ARMThumb)
|
||||
|
||||
|
||||
UInt32 CBC_ARMThumb_Decoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::ARMThumb_Convert(data, size, _bufferPos, 0);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
// ARMThumb.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARMTHUMB_H
|
||||
#define __ARMTHUMB_H
|
||||
|
||||
#include "Coder.h"
|
||||
#include "BranchCoder.h"
|
||||
|
||||
MyClass(BC_ARMThumb, 0x07, 1)
|
||||
MyClassA(BC_ARMThumb, 0x07, 1)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
// Alpha.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "Alpha.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
static HRESULT BC_Alpha_Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
|
||||
{
|
||||
UINT32 nowPos = 0;
|
||||
UINT64 nowPos64 = 0;
|
||||
UINT32 bufferPos = 0;
|
||||
while(true)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
UINT32 size = kBufferSize - bufferPos;
|
||||
RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
|
||||
UINT32 endPos = bufferPos + processedSize;
|
||||
if (endPos < 4)
|
||||
{
|
||||
if (endPos > 0)
|
||||
{
|
||||
RINOK(outStream->Write(buffer, endPos, &processedSize));
|
||||
if (endPos != processedSize)
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
for (bufferPos = 0; bufferPos <= endPos - 4; bufferPos += 4)
|
||||
{
|
||||
// if (buffer[bufferPos + 3] == 0xc3 && (buffer[bufferPos + 2] >> 5) == 7) // its jump
|
||||
// if (buffer[bufferPos + 3] == 0xd3 && (buffer[bufferPos + 2] >> 5) == 2)
|
||||
// if (buffer[bufferPos + 3] == 0xd3)
|
||||
if ((buffer[bufferPos + 3] >> 2) == 0x34)
|
||||
{
|
||||
UINT32 src =
|
||||
((buffer[bufferPos + 2] & 0x1F) << 16) |
|
||||
(buffer[bufferPos + 1] << 8) |
|
||||
(buffer[bufferPos + 0]);
|
||||
|
||||
src <<= 2;
|
||||
|
||||
UINT32 dest;
|
||||
if (encoding)
|
||||
dest = (nowPos + bufferPos + 4) + src;
|
||||
else
|
||||
dest = src - (nowPos + bufferPos + 4);
|
||||
dest >>= 2;
|
||||
dest &= 0x1FFFFF;
|
||||
buffer[bufferPos + 2] &= (~0x1F);
|
||||
buffer[bufferPos + 2] |= (dest >> 16);
|
||||
buffer[bufferPos + 1] = (dest >> 8);
|
||||
buffer[bufferPos + 0] = dest;
|
||||
}
|
||||
}
|
||||
nowPos += bufferPos;
|
||||
nowPos64 += bufferPos;
|
||||
RINOK(outStream->Write(buffer, bufferPos, &processedSize));
|
||||
if (bufferPos != processedSize)
|
||||
return E_FAIL;
|
||||
if (progress != NULL)
|
||||
{
|
||||
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
|
||||
}
|
||||
|
||||
UINT32 i = 0;
|
||||
while(bufferPos < endPos)
|
||||
buffer[i++] = buffer[bufferPos++];
|
||||
bufferPos = i;
|
||||
}
|
||||
}
|
||||
|
||||
MyClassImp(BC_Alpha)
|
||||
@@ -1,12 +0,0 @@
|
||||
// Alpha.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ALPHA_H
|
||||
#define __ALPHA_H
|
||||
|
||||
#include "Coder.h"
|
||||
|
||||
MyClass(BC_Alpha, 0x03, 1)
|
||||
|
||||
#endif
|
||||
@@ -123,24 +123,6 @@ SOURCE=.\StdAfx.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Alpha.cpp
|
||||
|
||||
!IF "$(CFG)" == "Branch - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Branch - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Alpha.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ARM.cpp
|
||||
|
||||
!IF "$(CFG)" == "Branch - Win32 Release"
|
||||
@@ -177,7 +159,15 @@ SOURCE=.\ARMThumb.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Coder.h
|
||||
SOURCE=.\BranchCoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BranchCoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BranchX86.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -199,24 +189,6 @@ SOURCE=.\IA64.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\M68.cpp
|
||||
|
||||
!IF "$(CFG)" == "Branch - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Branch - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\M68.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\PPC.cpp
|
||||
|
||||
!IF "$(CFG)" == "Branch - Win32 Release"
|
||||
@@ -235,6 +207,14 @@ SOURCE=.\PPC.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\SPARC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\SPARC.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\x86.cpp
|
||||
|
||||
!IF "$(CFG)" == "Branch - Win32 Release"
|
||||
@@ -305,6 +285,14 @@ SOURCE=..\RangeCoder\RangeCoderBit.h
|
||||
# Begin Group "Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
|
||||
26
7zip/Compress/Branch/BranchARM.c
Executable file
26
7zip/Compress/Branch/BranchARM.c
Executable file
@@ -0,0 +1,26 @@
|
||||
// BranchARM.c
|
||||
|
||||
#include "BranchARM.h"
|
||||
|
||||
UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i + 4 <= size; i += 4)
|
||||
{
|
||||
if (data[i + 3] == 0xEB)
|
||||
{
|
||||
UInt32 src = (data[i + 2] << 16) | (data[i + 1] << 8) | (data[i + 0]);
|
||||
src <<= 2;
|
||||
UInt32 dest;
|
||||
if (encoding)
|
||||
dest = nowPos + i + 8 + src;
|
||||
else
|
||||
dest = src - (nowPos + i + 8);
|
||||
dest >>= 2;
|
||||
data[i + 2] = (dest >> 16);
|
||||
data[i + 1] = (dest >> 8);
|
||||
data[i + 0] = dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
10
7zip/Compress/Branch/BranchARM.h
Executable file
10
7zip/Compress/Branch/BranchARM.h
Executable file
@@ -0,0 +1,10 @@
|
||||
// BranchARM.h
|
||||
|
||||
#ifndef __BRANCH_ARM_H
|
||||
#define __BRANCH_ARM_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
|
||||
|
||||
#endif
|
||||
35
7zip/Compress/Branch/BranchARMThumb.c
Executable file
35
7zip/Compress/Branch/BranchARMThumb.c
Executable file
@@ -0,0 +1,35 @@
|
||||
// BranchARMThumb.c
|
||||
|
||||
#include "BranchARMThumb.h"
|
||||
|
||||
UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i + 4 <= size; i += 2)
|
||||
{
|
||||
if ((data[i + 1] & 0xF8) == 0xF0 &&
|
||||
(data[i + 3] & 0xF8) == 0xF8)
|
||||
{
|
||||
UInt32 src =
|
||||
((data[i + 1] & 0x7) << 19) |
|
||||
(data[i + 0] << 11) |
|
||||
((data[i + 3] & 0x7) << 8) |
|
||||
(data[i + 2]);
|
||||
|
||||
src <<= 1;
|
||||
UInt32 dest;
|
||||
if (encoding)
|
||||
dest = nowPos + i + 4 + src;
|
||||
else
|
||||
dest = src - (nowPos + i + 4);
|
||||
dest >>= 1;
|
||||
|
||||
data[i + 1] = 0xF0 | ((dest >> 19) & 0x7);
|
||||
data[i + 0] = (dest >> 11);
|
||||
data[i + 3] = 0xF8 | ((dest >> 8) & 0x7);
|
||||
data[i + 2] = (dest);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
10
7zip/Compress/Branch/BranchARMThumb.h
Executable file
10
7zip/Compress/Branch/BranchARMThumb.h
Executable file
@@ -0,0 +1,10 @@
|
||||
// BranchARMThumb.h
|
||||
|
||||
#ifndef __BRANCH_ARM_THUMB_H
|
||||
#define __BRANCH_ARM_THUMB_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
|
||||
|
||||
#endif
|
||||
18
7zip/Compress/Branch/BranchCoder.cpp
Executable file
18
7zip/Compress/Branch/BranchCoder.cpp
Executable file
@@ -0,0 +1,18 @@
|
||||
// BranchCoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "BranchCoder.h"
|
||||
|
||||
STDMETHODIMP CBranchConverter::Init()
|
||||
{
|
||||
_bufferPos = 0;
|
||||
SubInit();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(UInt32) CBranchConverter::Filter(Byte *data, UInt32 size)
|
||||
{
|
||||
UInt32 processedSize = SubFilter(data, size);
|
||||
_bufferPos += processedSize;
|
||||
return processedSize;
|
||||
}
|
||||
54
7zip/Compress/Branch/BranchCoder.h
Executable file
54
7zip/Compress/Branch/BranchCoder.h
Executable file
@@ -0,0 +1,54 @@
|
||||
// BranchCoder.h
|
||||
|
||||
#ifndef __BRANCH_CODER_H
|
||||
#define __BRANCH_CODER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/Types.h"
|
||||
#include "Common/Alloc.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
|
||||
class CBranchConverter:
|
||||
public ICompressFilter,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
protected:
|
||||
UInt32 _bufferPos;
|
||||
virtual void SubInit() {}
|
||||
virtual UInt32 SubFilter(Byte *data, UInt32 size) = 0;
|
||||
public:
|
||||
MY_UNKNOWN_IMP;
|
||||
STDMETHOD(Init)();
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
||||
};
|
||||
|
||||
#define MyClassEncoderA(Name) class C ## Name: public CBranchConverter \
|
||||
{ public: UInt32 SubFilter(Byte *data, UInt32 size); };
|
||||
|
||||
#define MyClassDecoderA(Name) class C ## Name: public CBranchConverter \
|
||||
{ public: UInt32 SubFilter(Byte *data, UInt32 size); };
|
||||
|
||||
#define MyClassEncoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \
|
||||
{ public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT};
|
||||
|
||||
#define MyClassDecoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \
|
||||
{ public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT};
|
||||
|
||||
#define MyClass2b(Name, id, subId, encodingId) \
|
||||
DEFINE_GUID(CLSID_CCompressConvert ## Name, \
|
||||
0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00);
|
||||
|
||||
#define MyClassA(Name, id, subId) \
|
||||
MyClass2b(Name ## _Encoder, id, subId, 0x01) \
|
||||
MyClassEncoderA(Name ## _Encoder) \
|
||||
MyClass2b(Name ## _Decoder, id, subId, 0x00) \
|
||||
MyClassDecoderA(Name ## _Decoder)
|
||||
|
||||
#define MyClassB(Name, id, subId, ADD_ITEMS, ADD_INIT) \
|
||||
MyClass2b(Name ## _Encoder, id, subId, 0x01) \
|
||||
MyClassEncoderB(Name ## _Encoder, ADD_ITEMS, ADD_INIT) \
|
||||
MyClass2b(Name ## _Decoder, id, subId, 0x00) \
|
||||
MyClassDecoderB(Name ## _Decoder, ADD_ITEMS, ADD_INIT)
|
||||
|
||||
#endif
|
||||
65
7zip/Compress/Branch/BranchIA64.c
Executable file
65
7zip/Compress/Branch/BranchIA64.c
Executable file
@@ -0,0 +1,65 @@
|
||||
// BranchIA64.c
|
||||
|
||||
#include "BranchIA64.h"
|
||||
|
||||
const Byte kBranchTable[32] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
4, 4, 6, 6, 0, 0, 7, 7,
|
||||
4, 4, 0, 0, 4, 4, 0, 0
|
||||
};
|
||||
|
||||
UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i + 16 <= size; i += 16)
|
||||
{
|
||||
UInt32 instrTemplate = data[i] & 0x1F;
|
||||
UInt32 mask = kBranchTable[instrTemplate];
|
||||
UInt32 bitPos = 5;
|
||||
for (int slot = 0; slot < 3; slot++, bitPos += 41)
|
||||
{
|
||||
if (((mask >> slot) & 1) == 0)
|
||||
continue;
|
||||
UInt32 bytePos = (bitPos >> 3);
|
||||
UInt32 bitRes = bitPos & 0x7;
|
||||
// UInt64 instruction = *(UInt64 *)(data + i + bytePos);
|
||||
UInt64 instruction = 0;
|
||||
int j;
|
||||
for (j = 0; j < 6; j++)
|
||||
instruction += (UInt64)(data[i + j + bytePos]) << (8 * j);
|
||||
|
||||
UInt64 instNorm = instruction >> bitRes;
|
||||
if (((instNorm >> 37) & 0xF) == 0x5
|
||||
&& ((instNorm >> 9) & 0x7) == 0
|
||||
// && (instNorm & 0x3F)== 0
|
||||
)
|
||||
{
|
||||
UInt32 src = UInt32((instNorm >> 13) & 0xFFFFF);
|
||||
src |= ((instNorm >> 36) & 1) << 20;
|
||||
|
||||
src <<= 4;
|
||||
|
||||
UInt32 dest;
|
||||
if (encoding)
|
||||
dest = nowPos + i + src;
|
||||
else
|
||||
dest = src - (nowPos + i);
|
||||
|
||||
dest >>= 4;
|
||||
|
||||
instNorm &= ~(UInt64(0x8FFFFF) << 13);
|
||||
instNorm |= (UInt64(dest & 0xFFFFF) << 13);
|
||||
instNorm |= (UInt64(dest & 0x100000) << (36 - 20));
|
||||
|
||||
instruction &= (1 << bitRes) - 1;
|
||||
instruction |= (instNorm << bitRes);
|
||||
// *(UInt64 *)(data + i + bytePos) = instruction;
|
||||
for (j = 0; j < 6; j++)
|
||||
data[i + j + bytePos] = Byte(instruction >> (8 * j));
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
10
7zip/Compress/Branch/BranchIA64.h
Executable file
10
7zip/Compress/Branch/BranchIA64.h
Executable file
@@ -0,0 +1,10 @@
|
||||
// BranchIA64.h
|
||||
|
||||
#ifndef __BRANCH_IA64_H
|
||||
#define __BRANCH_IA64_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
|
||||
|
||||
#endif
|
||||
36
7zip/Compress/Branch/BranchPPC.c
Executable file
36
7zip/Compress/Branch/BranchPPC.c
Executable file
@@ -0,0 +1,36 @@
|
||||
// BranchPPC.c
|
||||
|
||||
#include "BranchPPC.h"
|
||||
|
||||
UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i + 4 <= size; i += 4)
|
||||
{
|
||||
// PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link)
|
||||
if ((data[i] >> 2) == 0x12 &&
|
||||
(
|
||||
(data[i + 3] & 3) == 1
|
||||
// || (data[i+3] & 3) == 3
|
||||
)
|
||||
)
|
||||
{
|
||||
UInt32 src = ((data[i + 0] & 3) << 24) |
|
||||
(data[i + 1] << 16) |
|
||||
(data[i + 2] << 8) |
|
||||
(data[i + 3] & (~3));
|
||||
|
||||
UInt32 dest;
|
||||
if (encoding)
|
||||
dest = nowPos + i + src;
|
||||
else
|
||||
dest = src - (nowPos + i);
|
||||
data[i + 0] = 0x48 | ((dest >> 24) & 0x3);
|
||||
data[i + 1] = (dest >> 16);
|
||||
data[i + 2] = (dest >> 8);
|
||||
data[i + 3] &= 0x3;
|
||||
data[i + 3] |= dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
10
7zip/Compress/Branch/BranchPPC.h
Executable file
10
7zip/Compress/Branch/BranchPPC.h
Executable file
@@ -0,0 +1,10 @@
|
||||
// BranchPPC.h
|
||||
|
||||
#ifndef __BRANCH_PPC_H
|
||||
#define __BRANCH_PPC_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
|
||||
|
||||
#endif
|
||||
36
7zip/Compress/Branch/BranchSPARC.c
Executable file
36
7zip/Compress/Branch/BranchSPARC.c
Executable file
@@ -0,0 +1,36 @@
|
||||
// BranchSPARC.c
|
||||
|
||||
#include "BranchSPARC.h"
|
||||
|
||||
UInt32 SPARC_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i + 4 <= size; i += 4)
|
||||
{
|
||||
if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 ||
|
||||
data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)
|
||||
{
|
||||
UInt32 src =
|
||||
((UInt32)data[i + 0] << 24) |
|
||||
((UInt32)data[i + 1] << 16) |
|
||||
((UInt32)data[i + 2] << 8) |
|
||||
((UInt32)data[i + 3]);
|
||||
|
||||
src <<= 2;
|
||||
UInt32 dest;
|
||||
if (encoding)
|
||||
dest = nowPos + i + src;
|
||||
else
|
||||
dest = src - (nowPos + i);
|
||||
dest >>= 2;
|
||||
|
||||
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
|
||||
|
||||
data[i + 0] = (Byte)(dest >> 24);
|
||||
data[i + 1] = (Byte)(dest >> 16);
|
||||
data[i + 2] = (Byte)(dest >> 8);
|
||||
data[i + 3] = (Byte)dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
10
7zip/Compress/Branch/BranchSPARC.h
Executable file
10
7zip/Compress/Branch/BranchSPARC.h
Executable file
@@ -0,0 +1,10 @@
|
||||
// BranchSPARC.h
|
||||
|
||||
#ifndef __BRANCH_SPARC_H
|
||||
#define __BRANCH_SPARC_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
UInt32 SPARC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
|
||||
|
||||
#endif
|
||||
101
7zip/Compress/Branch/BranchX86.c
Executable file
101
7zip/Compress/Branch/BranchX86.c
Executable file
@@ -0,0 +1,101 @@
|
||||
/* BranchX86.c */
|
||||
|
||||
#include "BranchX86.h"
|
||||
|
||||
/*
|
||||
static int inline Test86MSByte(Byte b)
|
||||
{
|
||||
return (b == 0 || b == 0xFF);
|
||||
}
|
||||
*/
|
||||
#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
|
||||
|
||||
const int kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
|
||||
const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
|
||||
|
||||
/*
|
||||
void x86_Convert_Init(UInt32 *prevMask, UInt32 *prevPos)
|
||||
{
|
||||
*prevMask = 0;
|
||||
*prevPos = (UInt32)(-5);
|
||||
}
|
||||
*/
|
||||
|
||||
UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos,
|
||||
UInt32 *prevMask, UInt32 *prevPos, int encoding)
|
||||
{
|
||||
UInt32 bufferPos = 0;
|
||||
UInt32 limit;
|
||||
|
||||
if (endPos < 5)
|
||||
return 0;
|
||||
|
||||
if (nowPos - *prevPos > 5)
|
||||
*prevPos = nowPos - 5;
|
||||
|
||||
limit = endPos - 5;
|
||||
while(bufferPos <= limit)
|
||||
{
|
||||
Byte b = buffer[bufferPos];
|
||||
UInt32 offset;
|
||||
if (b != 0xE8 && b != 0xE9)
|
||||
{
|
||||
bufferPos++;
|
||||
continue;
|
||||
}
|
||||
offset = (nowPos + bufferPos - *prevPos);
|
||||
*prevPos = (nowPos + bufferPos);
|
||||
if (offset > 5)
|
||||
*prevMask = 0;
|
||||
else
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < offset; i++)
|
||||
{
|
||||
*prevMask &= 0x77;
|
||||
*prevMask <<= 1;
|
||||
}
|
||||
}
|
||||
b = buffer[bufferPos + 4];
|
||||
if (Test86MSByte(b) && kMaskToAllowedStatus[(*prevMask >> 1) & 0x7] &&
|
||||
(*prevMask >> 1) < 0x10)
|
||||
{
|
||||
UInt32 src =
|
||||
((UInt32)(b) << 24) |
|
||||
((UInt32)(buffer[bufferPos + 3]) << 16) |
|
||||
((UInt32)(buffer[bufferPos + 2]) << 8) |
|
||||
(buffer[bufferPos + 1]);
|
||||
|
||||
UInt32 dest;
|
||||
while(1)
|
||||
{
|
||||
UInt32 index;
|
||||
if (encoding)
|
||||
dest = (nowPos + bufferPos + 5) + src;
|
||||
else
|
||||
dest = src - (nowPos + bufferPos + 5);
|
||||
if (*prevMask == 0)
|
||||
break;
|
||||
index = kMaskToBitNumber[*prevMask >> 1];
|
||||
b = (Byte)(dest >> (24 - index * 8));
|
||||
if (!Test86MSByte(b))
|
||||
break;
|
||||
src = dest ^ ((1 << (32 - index * 8)) - 1);
|
||||
}
|
||||
buffer[bufferPos + 4] = (Byte)(~(((dest >> 24) & 1) - 1));
|
||||
buffer[bufferPos + 3] = (Byte)(dest >> 16);
|
||||
buffer[bufferPos + 2] = (Byte)(dest >> 8);
|
||||
buffer[bufferPos + 1] = (Byte)dest;
|
||||
bufferPos += 5;
|
||||
*prevMask = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufferPos++;
|
||||
*prevMask |= 1;
|
||||
if (Test86MSByte(b))
|
||||
*prevMask |= 0x10;
|
||||
}
|
||||
}
|
||||
return bufferPos;
|
||||
}
|
||||
19
7zip/Compress/Branch/BranchX86.h
Executable file
19
7zip/Compress/Branch/BranchX86.h
Executable file
@@ -0,0 +1,19 @@
|
||||
/* BranchX86.h */
|
||||
|
||||
#ifndef __BRANCHX86_H
|
||||
#define __BRANCHX86_H
|
||||
|
||||
#ifndef UInt32
|
||||
#define UInt32 unsigned int
|
||||
#endif
|
||||
|
||||
#ifndef Byte
|
||||
#define Byte unsigned char
|
||||
#endif
|
||||
|
||||
#define x86_Convert_Init(prevMask, prevPos) { prevMask = 0; prevPos = (UInt32)(-5); }
|
||||
|
||||
UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos,
|
||||
UInt32 *prevMask, UInt32 *prevPos, int encoding);
|
||||
|
||||
#endif
|
||||
@@ -1,66 +0,0 @@
|
||||
// Branch/Coder.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CallPowerPC_CODER_H
|
||||
#define __CallPowerPC_CODER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/Types.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
|
||||
const int kBufferSize = 1 << 17;
|
||||
|
||||
class CDataBuffer
|
||||
{
|
||||
protected:
|
||||
BYTE *_buffer;
|
||||
public:
|
||||
CDataBuffer()
|
||||
{ _buffer = new BYTE[kBufferSize]; }
|
||||
~CDataBuffer()
|
||||
{ delete []_buffer; }
|
||||
};
|
||||
|
||||
#define MyClass3(Name) \
|
||||
class C ## Name: \
|
||||
public ICompressCoder, \
|
||||
public CDataBuffer, \
|
||||
public CMyUnknownImp \
|
||||
{ \
|
||||
public: \
|
||||
MY_UNKNOWN_IMP \
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream, \
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, \
|
||||
ICompressProgressInfo *progress); \
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278B-0303-010100000100}
|
||||
#define MyClass2(Name, id, subId, encodingId) \
|
||||
DEFINE_GUID(CLSID_CCompressConvert ## Name, \
|
||||
0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00); \
|
||||
MyClass3(Name) \
|
||||
|
||||
|
||||
#define MyClass(Name, id, subId) \
|
||||
MyClass2(Name ## _Encoder, id, subId, 0x01) \
|
||||
MyClass2(Name ## _Decoder, id, subId, 0x00)
|
||||
|
||||
#define MyClassImp(Name) \
|
||||
STDMETHODIMP C ## Name ## _Encoder::Code(ISequentialInStream *inStream, \
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, \
|
||||
ICompressProgressInfo *progress) \
|
||||
{ \
|
||||
return Name ## _Code(inStream, outStream, inSize, outSize, \
|
||||
progress, _buffer, true); \
|
||||
} \
|
||||
STDMETHODIMP C ## Name ## _Decoder::Code(ISequentialInStream *inStream, \
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, \
|
||||
ICompressProgressInfo *progress) \
|
||||
{ \
|
||||
return Name ## _Code(inStream, outStream, inSize, outSize, \
|
||||
progress, _buffer, false); \
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -2,52 +2,28 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#define INITGUID
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
#include "Coder.h"
|
||||
#include "x86.h"
|
||||
#include "PPC.h"
|
||||
#include "Alpha.h"
|
||||
#include "IA64.h"
|
||||
#include "ARM.h"
|
||||
#include "ARMThumb.h"
|
||||
#include "M68.h"
|
||||
#include "x86_2.h"
|
||||
#include "SPARC.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
|
||||
|
||||
#define MY_CreateClass(n) \
|
||||
#define MY_CreateClass0(n) \
|
||||
if (*clsid == CLSID_CCompressConvert ## n ## _Encoder) { \
|
||||
if (!correctInterface) \
|
||||
return E_NOINTERFACE; \
|
||||
coder = (ICompressCoder *)new C ## n ## _Encoder(); \
|
||||
filter = (ICompressFilter *)new C ## n ## _Encoder(); \
|
||||
} else if (*clsid == CLSID_CCompressConvert ## n ## _Decoder){ \
|
||||
if (!correctInterface) \
|
||||
return E_NOINTERFACE; \
|
||||
coder = (ICompressCoder *)new C ## n ## _Decoder(); \
|
||||
filter = (ICompressFilter *)new C ## n ## _Decoder(); \
|
||||
}
|
||||
|
||||
/*
|
||||
#define MyOBJECT_ENTRY(Name) \
|
||||
OBJECT_ENTRY(CLSID_CCompressConvert ## Name ## _Encoder, C ## Name ## _Encoder) \
|
||||
OBJECT_ENTRY(CLSID_CCompressConvert ## Name ## _Decoder, C ## Name ## _Decoder) \
|
||||
|
||||
|
||||
BEGIN_OBJECT_MAP(ObjectMap)
|
||||
MyOBJECT_ENTRY(BCJ_x86)
|
||||
MyOBJECT_ENTRY(BCJ2_x86)
|
||||
MyOBJECT_ENTRY(BC_PPC_B)
|
||||
MyOBJECT_ENTRY(BC_Alpha)
|
||||
MyOBJECT_ENTRY(BC_IA64)
|
||||
MyOBJECT_ENTRY(BC_ARM)
|
||||
MyOBJECT_ENTRY(BC_ARMThumb)
|
||||
MyOBJECT_ENTRY(BC_M68_B)
|
||||
END_OBJECT_MAP()
|
||||
*/
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
@@ -61,22 +37,19 @@ STDAPI CreateObject(
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
int correctInterface = (*interfaceID == IID_ICompressCoder);
|
||||
CMyComPtr<ICompressCoder> coder;
|
||||
|
||||
MY_CreateClass(BCJ_x86)
|
||||
int correctInterface = (*interfaceID == IID_ICompressFilter);
|
||||
CMyComPtr<ICompressFilter> filter;
|
||||
MY_CreateClass0(BCJ_x86)
|
||||
else
|
||||
MY_CreateClass(BC_PPC_B)
|
||||
MY_CreateClass0(BC_ARM)
|
||||
else
|
||||
MY_CreateClass(BC_Alpha)
|
||||
MY_CreateClass0(BC_PPC_B)
|
||||
else
|
||||
MY_CreateClass(BC_IA64)
|
||||
MY_CreateClass0(BC_IA64)
|
||||
else
|
||||
MY_CreateClass(BC_ARM)
|
||||
MY_CreateClass0(BC_ARMThumb)
|
||||
else
|
||||
MY_CreateClass(BC_ARMThumb)
|
||||
else
|
||||
MY_CreateClass(BC_M68_B)
|
||||
MY_CreateClass0(BC_SPARC)
|
||||
else
|
||||
{
|
||||
CMyComPtr<ICompressCoder2> coder2;
|
||||
@@ -98,8 +71,9 @@ STDAPI CreateObject(
|
||||
*outObject = coder2.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
*outObject = coder.Detach();
|
||||
*outObject = filter.Detach();
|
||||
return S_OK;
|
||||
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
@@ -123,11 +97,12 @@ static CBranchMethodItem g_Methods[] =
|
||||
METHOD_ITEM(BCJ_x86, 0x01, 0x03, L"BCJ", 1),
|
||||
METHOD_ITEM(BCJ2_x86, 0x01, 0x1B, L"BCJ2", 4),
|
||||
METHOD_ITEM(BC_PPC_B, 0x02, 0x05, L"BC_PPC_B", 1),
|
||||
METHOD_ITEM(BC_Alpha, 0x03, 1, L"BC_Alpha", 1),
|
||||
// METHOD_ITEM(BC_Alpha, 0x03, 1, L"BC_Alpha", 1),
|
||||
METHOD_ITEM(BC_IA64, 0x04, 1, L"BC_IA64", 1),
|
||||
METHOD_ITEM(BC_ARM, 0x05, 1, L"BC_ARM", 1),
|
||||
METHOD_ITEM(BC_M68_B, 0x06, 5, L"BC_M68_B", 1),
|
||||
METHOD_ITEM(BC_ARMThumb, 0x07, 1, L"BC_ARMThumb", 1)
|
||||
// METHOD_ITEM(BC_M68_B, 0x06, 5, L"BC_M68_B", 1),
|
||||
METHOD_ITEM(BC_ARMThumb, 0x07, 1, L"BC_ARMThumb", 1),
|
||||
METHOD_ITEM(BC_SPARC, 0x08, 0x05, L"BC_SPARC", 1)
|
||||
};
|
||||
|
||||
STDAPI GetNumberOfMethods(UINT32 *numMethods)
|
||||
@@ -175,4 +150,3 @@ STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,101 +3,14 @@
|
||||
#include "StdAfx.h"
|
||||
#include "IA64.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "BranchIA64.c"
|
||||
|
||||
const BYTE kBranchTable[32] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
4, 4, 6, 6, 0, 0, 7, 7,
|
||||
4, 4, 0, 0, 4, 4, 0, 0
|
||||
};
|
||||
|
||||
|
||||
static HRESULT BC_IA64_Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
|
||||
UInt32 CBC_IA64_Encoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
UINT32 nowPos = 0;
|
||||
UINT64 nowPos64 = 0;
|
||||
UINT32 bufferPos = 0;
|
||||
while(true)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
UINT32 size = kBufferSize - bufferPos;
|
||||
RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
|
||||
UINT32 endPos = bufferPos + processedSize;
|
||||
if (endPos < 16)
|
||||
{
|
||||
if (endPos > 0)
|
||||
{
|
||||
RINOK(outStream->Write(buffer, endPos, &processedSize));
|
||||
if (endPos != processedSize)
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
for (bufferPos = 0; bufferPos <= endPos - 16; bufferPos += 16)
|
||||
{
|
||||
UINT32 instrTemplate = buffer[bufferPos] & 0x1F;
|
||||
// ofs << hex << setw(4) << instrTemplate << endl;
|
||||
UINT32 mask = kBranchTable[instrTemplate];
|
||||
UINT32 bitPos = 5;
|
||||
for (int slot = 0; slot < 3; slot++, bitPos += 41)
|
||||
{
|
||||
if (((mask >> slot) & 1) == 0)
|
||||
continue;
|
||||
UINT32 bytePos = (bitPos >> 3);
|
||||
UINT32 bitRes = bitPos & 0x7;
|
||||
UINT64 instruction = *(UINT64 *)(buffer + bufferPos + bytePos);
|
||||
UINT64 instNorm = instruction >> bitRes;
|
||||
if (((instNorm >> 37) & 0xF) == 0x5
|
||||
&& ((instNorm >> 9) & 0x7) == 0
|
||||
// && (instNorm & 0x3F)== 0
|
||||
)
|
||||
{
|
||||
UINT32 src = UINT32((instNorm >> 13) & 0xFFFFF);
|
||||
src |= ((instNorm >> 36) & 1) << 20;
|
||||
|
||||
src <<= 4;
|
||||
|
||||
UINT32 dest;
|
||||
if (encoding)
|
||||
dest = nowPos + bufferPos + src;
|
||||
else
|
||||
dest = src - (nowPos + bufferPos);
|
||||
|
||||
dest >>= 4;
|
||||
|
||||
UINT64 instNorm2 = instNorm;
|
||||
|
||||
instNorm &= ~(UINT64(0x8FFFFF) << 13);
|
||||
instNorm |= (UINT64(dest & 0xFFFFF) << 13);
|
||||
instNorm |= (UINT64(dest & 0x100000) << (36 - 20));
|
||||
|
||||
instruction &= (1 << bitRes) - 1;
|
||||
instruction |= (instNorm << bitRes);
|
||||
*(UINT64 *)(buffer + bufferPos + bytePos) = instruction;
|
||||
}
|
||||
}
|
||||
}
|
||||
nowPos += bufferPos;
|
||||
nowPos64 += bufferPos;
|
||||
RINOK(outStream->Write(buffer, bufferPos, &processedSize));
|
||||
if (bufferPos != processedSize)
|
||||
return E_FAIL;
|
||||
if (progress != NULL)
|
||||
{
|
||||
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
|
||||
}
|
||||
|
||||
UINT32 i = 0;
|
||||
while(bufferPos < endPos)
|
||||
buffer[i++] = buffer[bufferPos++];
|
||||
bufferPos = i;
|
||||
}
|
||||
return ::IA64_Convert(data, size, _bufferPos, 1);
|
||||
}
|
||||
|
||||
MyClassImp(BC_IA64)
|
||||
|
||||
|
||||
UInt32 CBC_IA64_Decoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::IA64_Convert(data, size, _bufferPos, 0);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
// IA64.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __IA64_H
|
||||
#define __IA64_H
|
||||
|
||||
#include "Coder.h"
|
||||
#include "BranchCoder.h"
|
||||
|
||||
MyClass(BC_IA64, 0x04, 1)
|
||||
|
||||
// MyClass(IA64_Parse, 0x08, 1)
|
||||
MyClassA(BC_IA64, 0x04, 1)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
// M68.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "M68.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
static HRESULT BC_M68_B_Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
|
||||
{
|
||||
UINT32 nowPos = 0;
|
||||
UINT64 nowPos64 = 0;
|
||||
UINT32 bufferPos = 0;
|
||||
while(true)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
UINT32 size = kBufferSize - bufferPos;
|
||||
RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
|
||||
UINT32 endPos = bufferPos + processedSize;
|
||||
if (endPos < 4)
|
||||
{
|
||||
if (endPos > 0)
|
||||
{
|
||||
RINOK(outStream->Write(buffer, endPos, &processedSize));
|
||||
if (endPos != processedSize)
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
for (bufferPos = 0; bufferPos <= endPos - 4;)
|
||||
{
|
||||
if (buffer[bufferPos] == 0x61 && buffer[bufferPos + 1] == 0x00)
|
||||
{
|
||||
UINT32 src =
|
||||
(buffer[bufferPos + 2] << 8) |
|
||||
(buffer[bufferPos + 3]);
|
||||
|
||||
UINT32 dest;
|
||||
if (encoding)
|
||||
dest = nowPos + bufferPos + 2 + src;
|
||||
else
|
||||
dest = src - (nowPos + bufferPos + 2);
|
||||
buffer[bufferPos + 2] = (dest >> 8);
|
||||
buffer[bufferPos + 3] = dest;
|
||||
bufferPos += 4;
|
||||
}
|
||||
else
|
||||
bufferPos += 2;
|
||||
}
|
||||
nowPos += bufferPos;
|
||||
nowPos64 += bufferPos;
|
||||
RINOK(outStream->Write(buffer, bufferPos, &processedSize));
|
||||
if (bufferPos != processedSize)
|
||||
return E_FAIL;
|
||||
if (progress != NULL)
|
||||
{
|
||||
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
|
||||
}
|
||||
|
||||
UINT32 i = 0;
|
||||
while(bufferPos < endPos)
|
||||
buffer[i++] = buffer[bufferPos++];
|
||||
bufferPos = i;
|
||||
}
|
||||
}
|
||||
|
||||
MyClassImp(BC_M68_B)
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
// M68.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __M68_H
|
||||
#define __M68_H
|
||||
|
||||
#include "Coder.h"
|
||||
|
||||
MyClass(BC_M68_B, 0x06, 5)
|
||||
|
||||
#endif
|
||||
@@ -4,73 +4,14 @@
|
||||
#include "PPC.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "BranchPPC.c"
|
||||
|
||||
static HRESULT BC_PPC_B_Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
|
||||
UInt32 CBC_PPC_B_Encoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
UINT32 nowPos = 0;
|
||||
UINT64 nowPos64 = 0;
|
||||
UINT32 bufferPos = 0;
|
||||
while(true)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
UINT32 size = kBufferSize - bufferPos;
|
||||
RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
|
||||
UINT32 endPos = bufferPos + processedSize;
|
||||
if (endPos < 4)
|
||||
{
|
||||
if (endPos > 0)
|
||||
{
|
||||
RINOK(outStream->Write(buffer, endPos, &processedSize));
|
||||
if (endPos != processedSize)
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
for (bufferPos = 0; bufferPos <= endPos - 4; bufferPos += 4)
|
||||
{
|
||||
// PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link)
|
||||
if ((buffer[bufferPos] >> 2) == 0x12 &&
|
||||
(
|
||||
(buffer[bufferPos + 3] & 3) == 1
|
||||
// || (buffer[bufferPos+3] & 3) == 3
|
||||
)
|
||||
)
|
||||
{
|
||||
UINT32 src = ((buffer[bufferPos + 0] & 3) << 24) |
|
||||
(buffer[bufferPos + 1] << 16) |
|
||||
(buffer[bufferPos + 2] << 8) |
|
||||
(buffer[bufferPos + 3] & (~3));
|
||||
|
||||
UINT32 dest;
|
||||
if (encoding)
|
||||
dest = nowPos + bufferPos + src;
|
||||
else
|
||||
dest = src - (nowPos + bufferPos);
|
||||
buffer[bufferPos + 0] = 0x48 | ((dest >> 24) & 0x3);
|
||||
buffer[bufferPos + 1] = (dest >> 16);
|
||||
buffer[bufferPos + 2] = (dest >> 8);
|
||||
buffer[bufferPos + 3] &= 0x3;
|
||||
buffer[bufferPos + 3] |= dest;
|
||||
}
|
||||
}
|
||||
nowPos += bufferPos;
|
||||
nowPos64 += bufferPos;
|
||||
RINOK(outStream->Write(buffer, bufferPos, &processedSize));
|
||||
if (bufferPos != processedSize)
|
||||
return E_FAIL;
|
||||
if (progress != NULL)
|
||||
{
|
||||
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
|
||||
}
|
||||
|
||||
UINT32 i = 0;
|
||||
while(bufferPos < endPos)
|
||||
buffer[i++] = buffer[bufferPos++];
|
||||
bufferPos = i;
|
||||
}
|
||||
return ::PPC_B_Convert(data, size, _bufferPos, 1);
|
||||
}
|
||||
|
||||
MyClassImp(BC_PPC_B)
|
||||
|
||||
UInt32 CBC_PPC_B_Decoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::PPC_B_Convert(data, size, _bufferPos, 0);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
// PPC.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __PPC_H
|
||||
#define __PPC_H
|
||||
|
||||
#include "Coder.h"
|
||||
#include "BranchCoder.h"
|
||||
|
||||
MyClass(BC_PPC_B, 0x02, 5)
|
||||
MyClassA(BC_PPC_B, 0x02, 5)
|
||||
|
||||
#endif
|
||||
|
||||
17
7zip/Compress/Branch/SPARC.cpp
Executable file
17
7zip/Compress/Branch/SPARC.cpp
Executable file
@@ -0,0 +1,17 @@
|
||||
// SPARC.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "SPARC.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "BranchSPARC.c"
|
||||
|
||||
UInt32 CBC_SPARC_Encoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::SPARC_Convert(data, size, _bufferPos, 1);
|
||||
}
|
||||
|
||||
UInt32 CBC_SPARC_Decoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::SPARC_Convert(data, size, _bufferPos, 0);
|
||||
}
|
||||
10
7zip/Compress/Branch/SPARC.h
Executable file
10
7zip/Compress/Branch/SPARC.h
Executable file
@@ -0,0 +1,10 @@
|
||||
// SPARC.h
|
||||
|
||||
#ifndef __SPARC_H
|
||||
#define __SPARC_H
|
||||
|
||||
#include "BranchCoder.h"
|
||||
|
||||
MyClassA(BC_SPARC, 0x08, 5)
|
||||
|
||||
#endif
|
||||
@@ -1,3 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,9,2,0
|
||||
PRODUCTVERSION 3,9,2,0
|
||||
FILEVERSION 4,17,0,0
|
||||
PRODUCTVERSION 4,17,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -84,15 +84,15 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "Branch converter\0"
|
||||
VALUE "FileVersion", "3, 9, 2, 0\0"
|
||||
VALUE "FileDescription", "Branch filter\0"
|
||||
VALUE "FileVersion", "4, 17, 0, 0\0"
|
||||
VALUE "InternalName", "Branch\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "Branch.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "3, 9, 2, 0\0"
|
||||
VALUE "ProductVersion", "4, 17, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -1,124 +1,18 @@
|
||||
// x86.h
|
||||
// x86.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "x86.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
static bool inline Test86MSByte(BYTE b)
|
||||
#include "BranchX86.c"
|
||||
|
||||
UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return (b == 0 || b == 0xFF);
|
||||
return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 1);
|
||||
}
|
||||
|
||||
const bool kMaskToAllowedStatus[8] = {true, true, true, false, true, false, false, false};
|
||||
const BYTE kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
|
||||
|
||||
static HRESULT BCJ_x86_Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
|
||||
UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
UINT64 nowPos64 = 0;
|
||||
UINT32 nowPos = 0;
|
||||
UINT32 bufferPos = 0;
|
||||
UINT32 prevMask = 0;
|
||||
UINT32 prevPos = (- 5);
|
||||
|
||||
while(true)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
UINT32 size = kBufferSize - bufferPos;
|
||||
RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
|
||||
UINT32 endPos = bufferPos + processedSize;
|
||||
if (endPos < 5)
|
||||
{
|
||||
if (endPos > 0)
|
||||
{
|
||||
RINOK(outStream->Write(buffer, endPos, &processedSize));
|
||||
if (endPos != processedSize)
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
bufferPos = 0;
|
||||
if (nowPos - prevPos > 5)
|
||||
prevPos = nowPos - 5;
|
||||
|
||||
UINT32 limit = endPos - 5;
|
||||
while(bufferPos <= limit)
|
||||
{
|
||||
if (buffer[bufferPos] != 0xE8 && buffer[bufferPos] != 0xE9)
|
||||
{
|
||||
bufferPos++;
|
||||
continue;
|
||||
}
|
||||
UINT32 offset = (nowPos + bufferPos - prevPos);
|
||||
prevPos = (nowPos + bufferPos);
|
||||
if (offset > 5)
|
||||
prevMask = 0;
|
||||
else
|
||||
{
|
||||
for (UINT32 i = 0; i < offset; i++)
|
||||
{
|
||||
prevMask &= 0x77;
|
||||
prevMask <<= 1;
|
||||
}
|
||||
}
|
||||
BYTE &nextByte = buffer[bufferPos + 4];
|
||||
if (Test86MSByte(nextByte) && kMaskToAllowedStatus[(prevMask >> 1) & 0x7] &&
|
||||
(prevMask >> 1) < 0x10)
|
||||
{
|
||||
UINT32 src =
|
||||
(UINT32(nextByte) << 24) |
|
||||
(UINT32(buffer[bufferPos + 3]) << 16) |
|
||||
(UINT32(buffer[bufferPos + 2]) << 8) |
|
||||
(buffer[bufferPos + 1]);
|
||||
|
||||
UINT32 dest;
|
||||
while(true)
|
||||
{
|
||||
if (encoding)
|
||||
dest = (nowPos + bufferPos + 5) + src;
|
||||
else
|
||||
dest = src - (nowPos + bufferPos + 5);
|
||||
if (prevMask == 0)
|
||||
break;
|
||||
UINT32 index = kMaskToBitNumber[prevMask >> 1];
|
||||
if (!Test86MSByte(dest >> (24 - index * 8)))
|
||||
break;
|
||||
src = dest ^ ((1 << (32 - index * 8)) - 1);
|
||||
// src = dest;
|
||||
}
|
||||
nextByte = ~(((dest >> 24) & 1) - 1);
|
||||
buffer[bufferPos + 3] = (dest >> 16);
|
||||
buffer[bufferPos + 2] = (dest >> 8);
|
||||
buffer[bufferPos + 1] = dest;
|
||||
bufferPos += 5;
|
||||
prevMask = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufferPos++;
|
||||
prevMask |= 1;
|
||||
if (Test86MSByte(nextByte))
|
||||
prevMask |= 0x10;
|
||||
}
|
||||
}
|
||||
nowPos += bufferPos;
|
||||
nowPos64 += bufferPos;
|
||||
RINOK(outStream->Write(buffer, bufferPos, &processedSize));
|
||||
if (bufferPos != processedSize)
|
||||
return E_FAIL;
|
||||
if (progress != NULL)
|
||||
{
|
||||
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
|
||||
}
|
||||
|
||||
UINT32 i = 0;
|
||||
while(bufferPos < endPos)
|
||||
buffer[i++] = buffer[bufferPos++];
|
||||
bufferPos = i;
|
||||
}
|
||||
return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 0);
|
||||
}
|
||||
|
||||
|
||||
MyClassImp(BCJ_x86)
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
// x86.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __X86_H
|
||||
#define __X86_H
|
||||
|
||||
#include "Coder.h"
|
||||
#include "BranchCoder.h"
|
||||
#include "BranchX86.h"
|
||||
|
||||
MyClass(BCJ_x86, 0x01, 3)
|
||||
// MyClass(x86_J, 0x01, 2)
|
||||
struct CBranch86
|
||||
{
|
||||
UInt32 _prevMask;
|
||||
UInt32 _prevPos;
|
||||
void x86Init() { x86_Convert_Init(_prevMask, _prevPos); }
|
||||
};
|
||||
|
||||
MyClassB(BCJ_x86, 0x01, 3, CBranch86 ,
|
||||
virtual void SubInit() { x86Init(); })
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,27 +3,46 @@
|
||||
#include "StdAfx.h"
|
||||
#include "x86_2.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../../../Common/Alloc.h"
|
||||
|
||||
inline UINT32 Swap4(UINT32 value)
|
||||
{
|
||||
return (value << 24) | (value >> 24) |
|
||||
( (value >> 8) & 0xFF00) | ( (value << 8) & 0xFF0000);
|
||||
}
|
||||
static const int kBufferSize = 1 << 17;
|
||||
|
||||
inline bool IsJcc(BYTE b0, BYTE b1)
|
||||
inline bool IsJcc(Byte b0, Byte b1)
|
||||
{
|
||||
return (b0 == 0x0F && (b1 & 0xF0) == 0x80);
|
||||
}
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
|
||||
static bool inline Test86MSByte(BYTE b)
|
||||
static bool inline Test86MSByte(Byte b)
|
||||
{
|
||||
return (b == 0 || b == 0xFF);
|
||||
}
|
||||
|
||||
bool CBCJ2_x86_Encoder::Create()
|
||||
{
|
||||
if (!_mainStream.Create(1 << 16))
|
||||
return false;
|
||||
if (!_callStream.Create(1 << 20))
|
||||
return false;
|
||||
if (!_jumpStream.Create(1 << 20))
|
||||
return false;
|
||||
if (!_rangeEncoder.Create(1 << 20))
|
||||
return false;
|
||||
if (_buffer == 0)
|
||||
{
|
||||
_buffer = (Byte *)BigAlloc(kBufferSize);
|
||||
if (_buffer == 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CBCJ2_x86_Encoder::~CBCJ2_x86_Encoder()
|
||||
{
|
||||
BigFree(_buffer);
|
||||
}
|
||||
|
||||
HRESULT CBCJ2_x86_Encoder::Flush()
|
||||
{
|
||||
RINOK(_mainStream.Flush());
|
||||
@@ -33,21 +52,24 @@ HRESULT CBCJ2_x86_Encoder::Flush()
|
||||
return _rangeEncoder.FlushStream();
|
||||
}
|
||||
|
||||
const UINT32 kDefaultLimit = (1 << 24);
|
||||
const UInt32 kDefaultLimit = (1 << 24);
|
||||
|
||||
HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
|
||||
const UINT64 **inSizes,
|
||||
UINT32 numInStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UINT64 **outSizes,
|
||||
UINT32 numOutStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (numInStreams != 1 || numOutStreams != 4)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!Create())
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
bool sizeIsDefined = false;
|
||||
UINT64 inSize;
|
||||
UInt64 inSize;
|
||||
if (inSizes != NULL)
|
||||
if (inSizes[0] != NULL)
|
||||
{
|
||||
@@ -56,48 +78,50 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
|
||||
sizeIsDefined = true;
|
||||
}
|
||||
|
||||
|
||||
ISequentialInStream *inStream = inStreams[0];
|
||||
|
||||
_mainStream.Init(outStreams[0]);
|
||||
_callStream.Init(outStreams[1]);
|
||||
_jumpStream.Init(outStreams[2]);
|
||||
_rangeEncoder.Init(outStreams[3]);
|
||||
_mainStream.SetStream(outStreams[0]);
|
||||
_mainStream.Init();
|
||||
_callStream.SetStream(outStreams[1]);
|
||||
_callStream.Init();
|
||||
_jumpStream.SetStream(outStreams[2]);
|
||||
_jumpStream.Init();
|
||||
_rangeEncoder.SetStream(outStreams[3]);
|
||||
_rangeEncoder.Init();
|
||||
for (int i = 0; i < 256; i++)
|
||||
_statusE8Encoder[i].Init();
|
||||
_statusE9Encoder.Init();
|
||||
_statusJccEncoder.Init();
|
||||
// CCoderReleaser releaser(this);
|
||||
CCoderReleaser releaser(this);
|
||||
|
||||
CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;
|
||||
{
|
||||
inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize);
|
||||
}
|
||||
|
||||
UInt32 nowPos = 0;
|
||||
UInt64 nowPos64 = 0;
|
||||
UInt32 bufferPos = 0;
|
||||
UInt32 processedSize;
|
||||
|
||||
UINT32 nowPos = 0;
|
||||
UINT64 nowPos64 = 0;
|
||||
UINT32 bufferPos = 0;
|
||||
UINT32 processedSize;
|
||||
Byte prevByte = 0;
|
||||
|
||||
BYTE prevByte = 0;
|
||||
|
||||
UINT64 subStreamIndex = 0;
|
||||
UINT64 subStreamStartPos = 0;
|
||||
UINT64 subStreamEndPos = 0;
|
||||
UInt64 subStreamIndex = 0;
|
||||
UInt64 subStreamStartPos = 0;
|
||||
UInt64 subStreamEndPos = 0;
|
||||
|
||||
while(true)
|
||||
{
|
||||
UINT32 size = kBufferSize - bufferPos;
|
||||
UInt32 size = kBufferSize - bufferPos;
|
||||
RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize));
|
||||
UINT32 endPos = bufferPos + processedSize;
|
||||
UInt32 endPos = bufferPos + processedSize;
|
||||
|
||||
if (endPos < 5)
|
||||
{
|
||||
// change it
|
||||
for (bufferPos = 0; bufferPos < endPos; bufferPos++)
|
||||
{
|
||||
BYTE b = _buffer[bufferPos];
|
||||
Byte b = _buffer[bufferPos];
|
||||
_mainStream.WriteByte(b);
|
||||
if (b == 0xE8)
|
||||
_statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0);
|
||||
@@ -112,10 +136,10 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
|
||||
|
||||
bufferPos = 0;
|
||||
|
||||
UINT32 limit = endPos - 5;
|
||||
UInt32 limit = endPos - 5;
|
||||
while(bufferPos <= limit)
|
||||
{
|
||||
BYTE b = _buffer[bufferPos];
|
||||
Byte b = _buffer[bufferPos];
|
||||
_mainStream.WriteByte(b);
|
||||
if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))
|
||||
{
|
||||
@@ -123,21 +147,21 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
|
||||
prevByte = b;
|
||||
continue;
|
||||
}
|
||||
BYTE nextByte = _buffer[bufferPos + 4];
|
||||
UINT32 src =
|
||||
(UINT32(nextByte) << 24) |
|
||||
(UINT32(_buffer[bufferPos + 3]) << 16) |
|
||||
(UINT32(_buffer[bufferPos + 2]) << 8) |
|
||||
Byte nextByte = _buffer[bufferPos + 4];
|
||||
UInt32 src =
|
||||
(UInt32(nextByte) << 24) |
|
||||
(UInt32(_buffer[bufferPos + 3]) << 16) |
|
||||
(UInt32(_buffer[bufferPos + 2]) << 8) |
|
||||
(_buffer[bufferPos + 1]);
|
||||
UINT32 dest = (nowPos + bufferPos + 5) + src;
|
||||
UInt32 dest = (nowPos + bufferPos + 5) + src;
|
||||
// if (Test86MSByte(nextByte))
|
||||
bool convert;
|
||||
if (getSubStreamSize != NULL)
|
||||
{
|
||||
UINT64 currentPos = (nowPos64 + bufferPos);
|
||||
UInt64 currentPos = (nowPos64 + bufferPos);
|
||||
while (subStreamEndPos < currentPos)
|
||||
{
|
||||
UINT64 subStreamSize;
|
||||
UInt64 subStreamSize;
|
||||
HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize);
|
||||
if (result == S_OK)
|
||||
{
|
||||
@@ -165,7 +189,7 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
|
||||
convert = Test86MSByte(nextByte);
|
||||
else
|
||||
{
|
||||
UINT64 dest64 = (currentPos + 5) + INT64(INT32(src));
|
||||
UInt64 dest64 = (currentPos + 5) + Int64(Int32(src));
|
||||
convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos);
|
||||
}
|
||||
}
|
||||
@@ -182,13 +206,21 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
|
||||
else
|
||||
_statusJccEncoder.Encode(&_rangeEncoder, 1);
|
||||
|
||||
dest = Swap4(dest);
|
||||
|
||||
bufferPos += 5;
|
||||
if (b == 0xE8)
|
||||
_callStream.WriteBytes(&dest, sizeof(dest));
|
||||
{
|
||||
_callStream.WriteByte((Byte)(dest >> 24));
|
||||
_callStream.WriteByte((Byte)(dest >> 16));
|
||||
_callStream.WriteByte((Byte)(dest >> 8));
|
||||
_callStream.WriteByte((Byte)(dest));
|
||||
}
|
||||
else
|
||||
_jumpStream.WriteBytes(&dest, sizeof(dest));
|
||||
{
|
||||
_jumpStream.WriteByte((Byte)(dest >> 24));
|
||||
_jumpStream.WriteByte((Byte)(dest >> 16));
|
||||
_jumpStream.WriteByte((Byte)(dest >> 8));
|
||||
_jumpStream.WriteByte((Byte)(dest));
|
||||
}
|
||||
prevByte = nextByte;
|
||||
}
|
||||
else
|
||||
@@ -211,8 +243,7 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
|
||||
RINOK(progress->SetRatioInfo(&nowPos64, NULL));
|
||||
}
|
||||
|
||||
|
||||
UINT32 i = 0;
|
||||
UInt32 i = 0;
|
||||
while(bufferPos < endPos)
|
||||
_buffer[i++] = _buffer[bufferPos++];
|
||||
bufferPos = i;
|
||||
@@ -220,11 +251,11 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
|
||||
}
|
||||
|
||||
STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams,
|
||||
const UINT64 **inSizes,
|
||||
UINT32 numInStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UINT64 **outSizes,
|
||||
UINT32 numOutStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try
|
||||
@@ -239,41 +270,58 @@ STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams,
|
||||
#endif
|
||||
|
||||
HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams,
|
||||
const UINT64 **inSizes,
|
||||
UINT32 numInStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UINT64 **outSizes,
|
||||
UINT32 numOutStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (numInStreams != 4 || numOutStreams != 1)
|
||||
return E_INVALIDARG;
|
||||
|
||||
_mainInStream.Init(inStreams[0]);
|
||||
_callStream.Init(inStreams[1]);
|
||||
_jumpStream.Init(inStreams[2]);
|
||||
_rangeDecoder.Init(inStreams[3]);
|
||||
if (!_mainInStream.Create(1 << 16))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!_callStream.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!_jumpStream.Create(1 << 16))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!_rangeDecoder.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!_outStream.Create(1 << 16))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
_mainInStream.SetStream(inStreams[0]);
|
||||
_callStream.SetStream(inStreams[1]);
|
||||
_jumpStream.SetStream(inStreams[2]);
|
||||
_rangeDecoder.SetStream(inStreams[3]);
|
||||
_outStream.SetStream(outStreams[0]);
|
||||
|
||||
_mainInStream.Init();
|
||||
_callStream.Init();
|
||||
_jumpStream.Init();
|
||||
_rangeDecoder.Init();
|
||||
_outStream.Init();
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
_statusE8Decoder[i].Init();
|
||||
_statusE9Decoder.Init();
|
||||
_statusJccDecoder.Init();
|
||||
|
||||
_outStream.Init(outStreams[0]);
|
||||
CCoderReleaser releaser(this);
|
||||
|
||||
// CCoderReleaser releaser(this);
|
||||
|
||||
BYTE prevByte = 0;
|
||||
UINT32 processedBytes = 0;
|
||||
Byte prevByte = 0;
|
||||
UInt32 processedBytes = 0;
|
||||
while(true)
|
||||
{
|
||||
if (processedBytes > (1 << 20) && progress != NULL)
|
||||
{
|
||||
UINT64 nowPos64 = _outStream.GetProcessedSize();
|
||||
UInt64 nowPos64 = _outStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(NULL, &nowPos64));
|
||||
processedBytes = 0;
|
||||
}
|
||||
processedBytes++;
|
||||
BYTE b;
|
||||
Byte b;
|
||||
if (!_mainInStream.ReadByte(b))
|
||||
return Flush();
|
||||
_outStream.WriteByte(b);
|
||||
@@ -291,20 +339,44 @@ HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams,
|
||||
status = (_statusJccDecoder.Decode(&_rangeDecoder) == 1);
|
||||
if (status)
|
||||
{
|
||||
UINT32 src;
|
||||
UInt32 src;
|
||||
if (b == 0xE8)
|
||||
{
|
||||
if (!_callStream.ReadBytes(&src, sizeof(src)))
|
||||
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
|
||||
{
|
||||
if (!_jumpStream.ReadBytes(&src, sizeof(src)))
|
||||
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))
|
||||
return S_FALSE;
|
||||
src |= ((UInt32)b0);
|
||||
}
|
||||
src = Swap4(src);
|
||||
UINT32 dest = src - (UINT32(_outStream.GetProcessedSize()) + 4) ;
|
||||
_outStream.WriteBytes(&dest, sizeof(dest));
|
||||
UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ;
|
||||
_outStream.WriteByte((Byte)(dest));
|
||||
_outStream.WriteByte((Byte)(dest >> 8));
|
||||
_outStream.WriteByte((Byte)(dest >> 16));
|
||||
_outStream.WriteByte((Byte)(dest >> 24));
|
||||
prevByte = (dest >> 24);
|
||||
processedBytes += 4;
|
||||
}
|
||||
@@ -314,11 +386,11 @@ HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams,
|
||||
}
|
||||
|
||||
STDMETHODIMP CBCJ2_x86_Decoder::Code(ISequentialInStream **inStreams,
|
||||
const UINT64 **inSizes,
|
||||
UINT32 numInStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UINT64 **outSizes,
|
||||
UINT32 numOutStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
// x86_2.h
|
||||
|
||||
#pragma once
|
||||
#ifndef __BRANCH_X86_2_H
|
||||
#define __BRANCH_X86_2_H
|
||||
|
||||
#ifndef __X86_2_H
|
||||
#define __X86_2_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "Coder.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../RangeCoder/RangeCoderBit.h"
|
||||
// #include "../../Common/InBuffer.h"
|
||||
#include "../../ICoder.h"
|
||||
|
||||
// {23170F69-40C1-278B-0303-010100000100}
|
||||
#define MyClass2_a(Name, id, subId, encodingId) \
|
||||
@@ -27,11 +24,13 @@ const int kNumMoveBits = 5;
|
||||
|
||||
class CBCJ2_x86_Encoder:
|
||||
public ICompressCoder2,
|
||||
public CDataBuffer,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
Byte *_buffer;
|
||||
public:
|
||||
CBCJ2_x86_Encoder(): _mainStream(1 << 16) {}
|
||||
CBCJ2_x86_Encoder(): _buffer(0) {};
|
||||
~CBCJ2_x86_Encoder();
|
||||
bool Create();
|
||||
|
||||
COutBuffer _mainStream;
|
||||
COutBuffer _callStream;
|
||||
@@ -42,7 +41,6 @@ public:
|
||||
NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusJccEncoder;
|
||||
|
||||
HRESULT Flush();
|
||||
/*
|
||||
void ReleaseStreams()
|
||||
{
|
||||
_mainStream.ReleaseStream();
|
||||
@@ -55,32 +53,27 @@ public:
|
||||
{
|
||||
CBCJ2_x86_Encoder *_coder;
|
||||
public:
|
||||
CCoderReleaser(CBCJ2_x86_Encoder *aCoder): _coder(aCoder) {}
|
||||
~CCoderReleaser()
|
||||
{
|
||||
_coder->ReleaseStreams();
|
||||
}
|
||||
CCoderReleaser(CBCJ2_x86_Encoder *coder): _coder(coder) {}
|
||||
~CCoderReleaser() { _coder->ReleaseStreams(); }
|
||||
};
|
||||
friend class CCoderReleaser;
|
||||
*/
|
||||
|
||||
public:
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
HRESULT CodeReal(ISequentialInStream **inStreams,
|
||||
const UINT64 **inSizes,
|
||||
UINT32 numInStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UINT64 **outSizes,
|
||||
UINT32 numOutStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress);
|
||||
STDMETHOD(Code)(ISequentialInStream **inStreams,
|
||||
const UINT64 **inSizes,
|
||||
UINT32 numInStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UINT64 **outSizes,
|
||||
UINT32 numOutStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress);
|
||||
};
|
||||
|
||||
@@ -91,8 +84,6 @@ class CBCJ2_x86_Decoder:
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
CBCJ2_x86_Decoder(): _outStream(1 << 16), _mainInStream(1 << 16) {}
|
||||
|
||||
CInBuffer _mainInStream;
|
||||
CInBuffer _callStream;
|
||||
CInBuffer _jumpStream;
|
||||
@@ -103,7 +94,6 @@ public:
|
||||
|
||||
COutBuffer _outStream;
|
||||
|
||||
/*
|
||||
void ReleaseStreams()
|
||||
{
|
||||
_mainInStream.ReleaseStream();
|
||||
@@ -112,35 +102,31 @@ public:
|
||||
_rangeDecoder.ReleaseStream();
|
||||
_outStream.ReleaseStream();
|
||||
}
|
||||
*/
|
||||
|
||||
HRESULT Flush() { return _outStream.Flush(); }
|
||||
/*
|
||||
class CCoderReleaser
|
||||
{
|
||||
CBCJ2_x86_Decoder *_coder;
|
||||
public:
|
||||
CCoderReleaser(CBCJ2_x86_Decoder *aCoder): _coder(aCoder) {}
|
||||
CCoderReleaser(CBCJ2_x86_Decoder *coder): _coder(coder) {}
|
||||
~CCoderReleaser() { _coder->ReleaseStreams(); }
|
||||
};
|
||||
friend class CCoderReleaser;
|
||||
*/
|
||||
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
HRESULT CodeReal(ISequentialInStream **inStreams,
|
||||
const UINT64 **inSizes,
|
||||
UINT32 numInStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UINT64 **outSizes,
|
||||
UINT32 numOutStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress);
|
||||
STDMETHOD(Code)(ISequentialInStream **inStreams,
|
||||
const UINT64 **inSizes,
|
||||
UINT32 numInStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UINT64 **outSizes,
|
||||
UINT32 numOutStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,100 +1,38 @@
|
||||
// Coder.cpp
|
||||
// ByteSwap.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ByteSwap.h"
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
const int kBufferSize = 1 << 17;
|
||||
STDMETHODIMP CByteSwap2::Init() { return S_OK; }
|
||||
|
||||
CBuffer::CBuffer():
|
||||
_buffer(0)
|
||||
STDMETHODIMP_(UInt32) CByteSwap2::Filter(Byte *data, UInt32 size)
|
||||
{
|
||||
_buffer = new BYTE[kBufferSize];
|
||||
}
|
||||
|
||||
CBuffer::~CBuffer()
|
||||
{
|
||||
delete []_buffer;
|
||||
}
|
||||
|
||||
STDMETHODIMP CByteSwap2::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
const UINT32 kStep = 2;
|
||||
UINT32 bufferPos = 0;
|
||||
UINT64 nowPos64 = 0;
|
||||
while(true)
|
||||
const UInt32 kStep = 2;
|
||||
UInt32 i;
|
||||
for (i = 0; i + kStep <= size; i += kStep)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
UINT32 size = kBufferSize - bufferPos;
|
||||
RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize));
|
||||
if (processedSize == 0)
|
||||
return outStream->Write(_buffer, bufferPos, NULL);
|
||||
|
||||
UINT32 endPos = bufferPos + processedSize;
|
||||
for (UINT32 curPos = 0; curPos + kStep <= endPos; curPos += kStep)
|
||||
{
|
||||
BYTE data[kStep];
|
||||
data[0] = _buffer[curPos + 0];
|
||||
data[1] = _buffer[curPos + 1];
|
||||
_buffer[curPos + 0] = data[1];
|
||||
_buffer[curPos + 1] = data[0];
|
||||
}
|
||||
RINOK(outStream->Write(_buffer, curPos, &processedSize));
|
||||
if (curPos != processedSize)
|
||||
return E_FAIL;
|
||||
nowPos64 += curPos;
|
||||
if (progress != NULL)
|
||||
{
|
||||
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
|
||||
}
|
||||
bufferPos = 0;
|
||||
while(curPos < endPos)
|
||||
_buffer[bufferPos++] = _buffer[curPos++];
|
||||
Byte b = data[i];
|
||||
data[i] = data[i + 1];
|
||||
data[i + 1] = b;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
STDMETHODIMP CByteSwap4::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
STDMETHODIMP CByteSwap4::Init() { return S_OK; }
|
||||
|
||||
STDMETHODIMP_(UInt32) CByteSwap4::Filter(Byte *data, UInt32 size)
|
||||
{
|
||||
const UINT32 kStep = 4;
|
||||
UINT32 bufferPos = 0;
|
||||
UINT64 nowPos64 = 0;
|
||||
while(true)
|
||||
const UInt32 kStep = 4;
|
||||
UInt32 i;
|
||||
for (i = 0; i + kStep <= size; i += kStep)
|
||||
{
|
||||
UINT32 processedSize;
|
||||
UINT32 size = kBufferSize - bufferPos;
|
||||
RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize));
|
||||
if (processedSize == 0)
|
||||
return outStream->Write(_buffer, bufferPos, NULL);
|
||||
|
||||
UINT32 endPos = bufferPos + processedSize;
|
||||
for (UINT32 curPos = 0; curPos + kStep <= endPos; curPos += kStep)
|
||||
{
|
||||
BYTE data[kStep];
|
||||
data[0] = _buffer[curPos + 0];
|
||||
data[1] = _buffer[curPos + 1];
|
||||
data[2] = _buffer[curPos + 2];
|
||||
data[3] = _buffer[curPos + 3];
|
||||
_buffer[curPos + 0] = data[3];
|
||||
_buffer[curPos + 1] = data[2];
|
||||
_buffer[curPos + 2] = data[1];
|
||||
_buffer[curPos + 3] = data[0];
|
||||
}
|
||||
RINOK(outStream->Write(_buffer, curPos, &processedSize));
|
||||
if (curPos != processedSize)
|
||||
return E_FAIL;
|
||||
nowPos64 += curPos;
|
||||
if (progress != NULL)
|
||||
{
|
||||
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
|
||||
}
|
||||
bufferPos = 0;
|
||||
while(curPos < endPos)
|
||||
_buffer[bufferPos++] = _buffer[curPos++];
|
||||
Byte b0 = data[i];
|
||||
Byte b1 = data[i + 1];
|
||||
data[i] = data[i + 3];
|
||||
data[i + 1] = data[i + 2];
|
||||
data[i + 2] = b1;
|
||||
data[i + 3] = b0;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,38 +14,24 @@ DEFINE_GUID(CLSID_CCompressConvertByteSwap2,
|
||||
DEFINE_GUID(CLSID_CCompressConvertByteSwap4,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
class CBuffer
|
||||
{
|
||||
protected:
|
||||
BYTE *_buffer;
|
||||
public:
|
||||
CBuffer();
|
||||
~CBuffer();
|
||||
};
|
||||
|
||||
class CByteSwap2 :
|
||||
public ICompressCoder,
|
||||
public CBuffer,
|
||||
class CByteSwap2:
|
||||
public ICompressFilter,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
STDMETHOD(Init)();
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
||||
};
|
||||
|
||||
class CByteSwap4 :
|
||||
public ICompressCoder,
|
||||
public CBuffer,
|
||||
class CByteSwap4:
|
||||
public ICompressFilter,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
STDMETHOD(Init)();
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#define INITGUID
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "ByteSwap.h"
|
||||
#include "../../ICoder.h"
|
||||
@@ -18,19 +17,19 @@ STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
int correctInterface = (*iid == IID_ICompressCoder);
|
||||
CMyComPtr<ICompressCoder> coder;
|
||||
int correctInterface = (*iid == IID_ICompressFilter);
|
||||
CMyComPtr<ICompressFilter> coder;
|
||||
if (*clsid == CLSID_CCompressConvertByteSwap2)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new CByteSwap2();
|
||||
coder = (ICompressFilter *)new CByteSwap2();
|
||||
}
|
||||
else if (*clsid == CLSID_CCompressConvertByteSwap4)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new CByteSwap4();
|
||||
coder = (ICompressFilter *)new CByteSwap4();
|
||||
}
|
||||
else
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,9,2,0
|
||||
PRODUCTVERSION 3,9,2,0
|
||||
FILEVERSION 4,7,0,0
|
||||
PRODUCTVERSION 4,7,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -84,15 +84,15 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "Byte Swap converter \0"
|
||||
VALUE "FileVersion", "3, 9, 2, 0\0"
|
||||
VALUE "FileDescription", "Byte Swap filter\0"
|
||||
VALUE "FileVersion", "4, 7, 0, 0\0"
|
||||
VALUE "InternalName", "Swap\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2004 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "Swap.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "3, 9, 2, 0\0"
|
||||
VALUE "ProductVersion", "4, 7, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -113,6 +113,18 @@ SOURCE=.\StdAfx.cpp
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CopyCoder.cpp
|
||||
|
||||
@@ -3,32 +3,38 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "CopyCoder.h"
|
||||
#include "../../../Common/Alloc.h"
|
||||
|
||||
namespace NCompress {
|
||||
|
||||
static const UINT32 kBufferSize = 1 << 17;
|
||||
|
||||
CCopyCoder::CCopyCoder():
|
||||
TotalSize(0)
|
||||
{
|
||||
_buffer = new BYTE[kBufferSize];
|
||||
}
|
||||
static const UInt32 kBufferSize = 1 << 17;
|
||||
|
||||
CCopyCoder::~CCopyCoder()
|
||||
{
|
||||
delete []_buffer;
|
||||
BigFree(_buffer);
|
||||
}
|
||||
|
||||
STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (_buffer == 0)
|
||||
{
|
||||
_buffer = (Byte *)BigAlloc(kBufferSize);
|
||||
if (_buffer == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
TotalSize = 0;
|
||||
while(true)
|
||||
{
|
||||
UINT32 realProcessedSize;
|
||||
RINOK(inStream->ReadPart(_buffer, kBufferSize, &realProcessedSize));
|
||||
UInt32 realProcessedSize;
|
||||
UInt32 size = kBufferSize;
|
||||
if (outSize != 0)
|
||||
if (size > *outSize - TotalSize)
|
||||
size = (UInt32)(*outSize - TotalSize);
|
||||
RINOK(inStream->ReadPart(_buffer, size, &realProcessedSize));
|
||||
if(realProcessedSize == 0)
|
||||
break;
|
||||
RINOK(outStream->Write(_buffer, realProcessedSize, NULL));
|
||||
|
||||
@@ -1,31 +1,28 @@
|
||||
// Compress/CopyCoder.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __COMPRESS_COPYCODER_H
|
||||
#define __COMPRESS_COPYCODER_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
|
||||
namespace NCompress {
|
||||
|
||||
class CCopyCoder:
|
||||
public ICompressCoder,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
BYTE *_buffer;
|
||||
Byte *_buffer;
|
||||
public:
|
||||
UINT64 TotalSize;
|
||||
CCopyCoder();
|
||||
UInt64 TotalSize;
|
||||
CCopyCoder(): TotalSize(0) , _buffer(0) {};
|
||||
~CCopyCoder();
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
};
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <initguid.h>
|
||||
#include "../../../Common/MyInitGuid.h"
|
||||
#include "../../../Common/ComTry.h"
|
||||
|
||||
#include "CopyCoder.h"
|
||||
#include "../../../Common/ComTry.h"
|
||||
|
||||
// {23170F69-40C1-278B-0000-000000000000}
|
||||
DEFINE_GUID(CLSID_CCompressCopyCoder,
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,8,1,0
|
||||
PRODUCTVERSION 3,8,1,0
|
||||
FILEVERSION 4,7,0,0
|
||||
PRODUCTVERSION 4,7,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -85,14 +85,14 @@ BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "Copy Coder\0"
|
||||
VALUE "FileVersion", "3, 8, 1, 0\0"
|
||||
VALUE "FileVersion", "4, 7, 0, 0\0"
|
||||
VALUE "InternalName", "Copy\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2004 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "Copy.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "3, 8, 1, 0\0"
|
||||
VALUE "ProductVersion", "4, 7, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -188,6 +188,14 @@ SOURCE=..\..\Common\OutBuffer.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\CRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -210,6 +218,26 @@ SOURCE=..\..\..\Common\NewHandler.h
|
||||
# Begin Group "LZ"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Group "BinTree"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\BinTree\BinTree.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\BinTree\BinTree3Z.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\BinTree\BinTreeMain.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\IMatchFinder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\LZInWindow.cpp
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// DeflateConst.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DEFLATE_CONST_H
|
||||
#define __DEFLATE_CONST_H
|
||||
|
||||
@@ -10,59 +8,59 @@
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
|
||||
const UINT32 kLenTableSize = 29;
|
||||
const UInt32 kLenTableSize = 29;
|
||||
|
||||
const UINT32 kStaticDistTableSize = 32;
|
||||
const UINT32 kStaticLenTableSize = 31;
|
||||
const UInt32 kStaticDistTableSize = 32;
|
||||
const UInt32 kStaticLenTableSize = 31;
|
||||
|
||||
const UINT32 kReadTableNumber = 0x100;
|
||||
const UINT32 kMatchNumber = kReadTableNumber + 1;
|
||||
const UInt32 kReadTableNumber = 0x100;
|
||||
const UInt32 kMatchNumber = kReadTableNumber + 1;
|
||||
|
||||
const UINT32 kMainTableSize = kMatchNumber + kLenTableSize; //298;
|
||||
const UINT32 kStaticMainTableSize = kMatchNumber + kStaticLenTableSize; //298;
|
||||
const UInt32 kMainTableSize = kMatchNumber + kLenTableSize; //298;
|
||||
const UInt32 kStaticMainTableSize = kMatchNumber + kStaticLenTableSize; //298;
|
||||
|
||||
const UINT32 kDistTableStart = kMainTableSize;
|
||||
const UInt32 kDistTableStart = kMainTableSize;
|
||||
|
||||
const UINT32 kHeapTablesSizesSum32 = kMainTableSize + kDistTableSize32;
|
||||
const UINT32 kHeapTablesSizesSum64 = kMainTableSize + kDistTableSize64;
|
||||
const UInt32 kHeapTablesSizesSum32 = kMainTableSize + kDistTableSize32;
|
||||
const UInt32 kHeapTablesSizesSum64 = kMainTableSize + kDistTableSize64;
|
||||
|
||||
const UINT32 kLevelTableSize = 19;
|
||||
const UInt32 kLevelTableSize = 19;
|
||||
|
||||
const UINT32 kMaxTableSize32 = kHeapTablesSizesSum32; // test it
|
||||
const UINT32 kMaxTableSize64 = kHeapTablesSizesSum64; // test it
|
||||
const UInt32 kMaxTableSize32 = kHeapTablesSizesSum32; // test it
|
||||
const UInt32 kMaxTableSize64 = kHeapTablesSizesSum64; // test it
|
||||
|
||||
const UINT32 kStaticMaxTableSize = kStaticMainTableSize + kStaticDistTableSize;
|
||||
const UInt32 kStaticMaxTableSize = kStaticMainTableSize + kStaticDistTableSize;
|
||||
|
||||
const UINT32 kTableDirectLevels = 16;
|
||||
const UINT32 kTableLevelRepNumber = kTableDirectLevels;
|
||||
const UINT32 kTableLevel0Number = kTableLevelRepNumber + 1;
|
||||
const UINT32 kTableLevel0Number2 = kTableLevel0Number + 1;
|
||||
const UInt32 kTableDirectLevels = 16;
|
||||
const UInt32 kTableLevelRepNumber = kTableDirectLevels;
|
||||
const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1;
|
||||
const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1;
|
||||
|
||||
const UINT32 kLevelMask = 0xF;
|
||||
const UInt32 kLevelMask = 0xF;
|
||||
|
||||
const BYTE kLenStart32[kLenTableSize] =
|
||||
const Byte kLenStart32[kLenTableSize] =
|
||||
{0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255};
|
||||
const BYTE kLenStart64[kLenTableSize] =
|
||||
const Byte kLenStart64[kLenTableSize] =
|
||||
{0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 0};
|
||||
|
||||
const BYTE kLenDirectBits32[kLenTableSize] =
|
||||
const Byte kLenDirectBits32[kLenTableSize] =
|
||||
{0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
|
||||
const BYTE kLenDirectBits64[kLenTableSize] =
|
||||
const Byte kLenDirectBits64[kLenTableSize] =
|
||||
{0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 16};
|
||||
|
||||
const UINT32 kDistStart[kDistTableSize64] =
|
||||
const UInt32 kDistStart[kDistTableSize64] =
|
||||
{0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,
|
||||
1024,1536,2048,3072,4096,6144,8192,12288,16384,24576, 32768, 49152};
|
||||
const BYTE kDistDirectBits[kDistTableSize64] =
|
||||
const Byte kDistDirectBits[kDistTableSize64] =
|
||||
{0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14};
|
||||
|
||||
const BYTE kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
|
||||
const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
|
||||
|
||||
const BYTE kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
|
||||
const Byte kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
|
||||
|
||||
const UINT32 kMatchMinLen = 3;
|
||||
const UINT32 kMatchMaxLen32 = kNumLenCombinations32 + kMatchMinLen - 1; //256 + 2; test it
|
||||
const UINT32 kMatchMaxLen64 = kNumLenCombinations64 + kMatchMinLen - 1; //255 + 2; test it
|
||||
const UInt32 kMatchMinLen = 3;
|
||||
const UInt32 kMatchMaxLen32 = kNumLenCombinations32 + kMatchMinLen - 1; //256 + 2; test it
|
||||
const UInt32 kMatchMaxLen64 = kNumLenCombinations64 + kMatchMinLen - 1; //255 + 2; test it
|
||||
|
||||
const int kFinalBlockFieldSize = 1;
|
||||
|
||||
@@ -88,18 +86,18 @@ namespace NBlockType
|
||||
};
|
||||
}
|
||||
|
||||
const UINT32 kDeflateNumberOfLengthCodesFieldSize = 5;
|
||||
const UINT32 kDeflateNumberOfDistanceCodesFieldSize = 5;
|
||||
const UINT32 kDeflateNumberOfLevelCodesFieldSize = 4;
|
||||
const UInt32 kDeflateNumberOfLengthCodesFieldSize = 5;
|
||||
const UInt32 kDeflateNumberOfDistanceCodesFieldSize = 5;
|
||||
const UInt32 kDeflateNumberOfLevelCodesFieldSize = 4;
|
||||
|
||||
const UINT32 kDeflateNumberOfLitLenCodesMin = 257;
|
||||
const UInt32 kDeflateNumberOfLitLenCodesMin = 257;
|
||||
|
||||
const UINT32 kDeflateNumberOfDistanceCodesMin = 1;
|
||||
const UINT32 kDeflateNumberOfLevelCodesMin = 4;
|
||||
const UInt32 kDeflateNumberOfDistanceCodesMin = 1;
|
||||
const UInt32 kDeflateNumberOfLevelCodesMin = 4;
|
||||
|
||||
const UINT32 kDeflateLevelCodeFieldSize = 3;
|
||||
const UInt32 kDeflateLevelCodeFieldSize = 3;
|
||||
|
||||
const UINT32 kDeflateStoredBlockLengthFieldSizeSize = 16;
|
||||
const UInt32 kDeflateStoredBlockLengthFieldSizeSize = 16;
|
||||
|
||||
}}
|
||||
|
||||
|
||||
@@ -3,29 +3,21 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "DeflateDecoder.h"
|
||||
#include "DeflateConst.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
namespace NDecoder {
|
||||
|
||||
CCoder::CCoder(bool deflate64Mode):
|
||||
m_MainDecoder(kStaticMainTableSize),
|
||||
m_DistDecoder(kStaticDistTableSize),
|
||||
m_LevelDecoder(kLevelTableSize),
|
||||
_deflate64Mode(deflate64Mode)
|
||||
{}
|
||||
CCoder::CCoder(bool deflate64Mode): _deflate64Mode(deflate64Mode) {}
|
||||
|
||||
void CCoder::DeCodeLevelTable(BYTE *newLevels, int numLevels)
|
||||
void CCoder::DeCodeLevelTable(Byte *newLevels, int numLevels)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < numLevels)
|
||||
{
|
||||
UINT32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
||||
UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number < kTableDirectLevels)
|
||||
newLevels[i++] = BYTE(number);
|
||||
newLevels[i++] = Byte(number);
|
||||
else
|
||||
{
|
||||
if (number == kTableLevelRepNumber)
|
||||
@@ -62,12 +54,12 @@ void CCoder::ReadTables(void)
|
||||
case NBlockType::kStored:
|
||||
{
|
||||
m_StoredMode = true;
|
||||
UINT32 currentBitPosition = m_InBitStream.GetBitPosition();
|
||||
UINT32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0;
|
||||
UInt32 currentBitPosition = m_InBitStream.GetBitPosition();
|
||||
UInt32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0;
|
||||
if (numBitsForAlign > 0)
|
||||
m_InBitStream.ReadBits(numBitsForAlign);
|
||||
m_StoredBlockSize = m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize);
|
||||
WORD onesComplementReverse = ~WORD(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize));
|
||||
UInt16 onesComplementReverse = ~(UInt16)(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize));
|
||||
if (m_StoredBlockSize != onesComplementReverse)
|
||||
throw CException(CException::kData);
|
||||
break;
|
||||
@@ -76,8 +68,8 @@ void CCoder::ReadTables(void)
|
||||
case NBlockType::kDynamicHuffman:
|
||||
{
|
||||
m_StoredMode = false;
|
||||
BYTE litLenLevels[kStaticMainTableSize];
|
||||
BYTE distLevels[kStaticDistTableSize];
|
||||
Byte litLenLevels[kStaticMainTableSize];
|
||||
Byte distLevels[kStaticDistTableSize];
|
||||
if (blockType == NBlockType::kFixedHuffman)
|
||||
{
|
||||
int i;
|
||||
@@ -108,13 +100,13 @@ void CCoder::ReadTables(void)
|
||||
int numLevels = _deflate64Mode ? kHeapTablesSizesSum64 :
|
||||
kHeapTablesSizesSum32;
|
||||
|
||||
BYTE levelLevels[kLevelTableSize];
|
||||
Byte levelLevels[kLevelTableSize];
|
||||
int i;
|
||||
for (i = 0; i < kLevelTableSize; i++)
|
||||
{
|
||||
int position = kCodeLengthAlphabetOrder[i];
|
||||
if(i < numLevelCodes)
|
||||
levelLevels[position] = BYTE(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize));
|
||||
levelLevels[position] = Byte(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize));
|
||||
else
|
||||
levelLevels[position] = 0;
|
||||
}
|
||||
@@ -128,7 +120,7 @@ void CCoder::ReadTables(void)
|
||||
throw CException(CException::kData);
|
||||
}
|
||||
|
||||
BYTE tmpLevels[kStaticMaxTableSize];
|
||||
Byte tmpLevels[kStaticMaxTableSize];
|
||||
DeCodeLevelTable(tmpLevels, numLitLenLevels + numDistLevels);
|
||||
|
||||
memmove(litLenLevels, tmpLevels, numLitLenLevels);
|
||||
@@ -155,23 +147,19 @@ void CCoder::ReadTables(void)
|
||||
}
|
||||
|
||||
HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
{
|
||||
try
|
||||
{
|
||||
m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32 /* , kMatchMaxLen */);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
UINT64 pos = 0;
|
||||
m_OutWindowStream.Init(outStream, false);
|
||||
m_InBitStream.Init(inStream);
|
||||
// CCoderReleaser coderReleaser(this);
|
||||
if (!m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!m_InBitStream.Create(1 << 17))
|
||||
return E_OUTOFMEMORY;
|
||||
UInt64 pos = 0;
|
||||
m_OutWindowStream.SetStream(outStream);
|
||||
m_OutWindowStream.Init(false);
|
||||
m_InBitStream.SetStream(inStream);
|
||||
m_InBitStream.Init();
|
||||
CCoderReleaser coderReleaser(this);
|
||||
|
||||
m_FinalBlock = false;
|
||||
|
||||
@@ -179,14 +167,14 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
{
|
||||
if (progress != NULL)
|
||||
{
|
||||
UINT64 packSize = m_InBitStream.GetProcessedSize();
|
||||
UInt64 packSize = m_InBitStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &pos));
|
||||
}
|
||||
ReadTables();
|
||||
if(m_StoredMode)
|
||||
{
|
||||
for (UINT32 i = 0; i < m_StoredBlockSize; i++)
|
||||
m_OutWindowStream.PutOneByte(BYTE(m_InBitStream.ReadBits(8)));
|
||||
for (UInt32 i = 0; i < m_StoredBlockSize; i++)
|
||||
m_OutWindowStream.PutByte(Byte(m_InBitStream.ReadBits(8)));
|
||||
pos += m_StoredBlockSize;
|
||||
continue;
|
||||
}
|
||||
@@ -195,13 +183,13 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
if (m_InBitStream.NumExtraBytes > 4)
|
||||
throw CException(CException::kData);
|
||||
|
||||
UINT32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
|
||||
UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number < 256)
|
||||
{
|
||||
if (outSize != NULL)
|
||||
if (pos >= *outSize)
|
||||
throw CException(CException::kData);
|
||||
m_OutWindowStream.PutOneByte(BYTE(number));
|
||||
m_OutWindowStream.PutByte(Byte(number));
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
@@ -212,28 +200,28 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
throw CException(CException::kData);
|
||||
number -= kMatchNumber;
|
||||
|
||||
UINT32 length;
|
||||
UInt32 length;
|
||||
if (_deflate64Mode)
|
||||
{
|
||||
length = UINT32(kLenStart64[number]) + kMatchMinLen;
|
||||
UINT32 numBits = kLenDirectBits64[number];
|
||||
length = UInt32(kLenStart64[number]) + kMatchMinLen;
|
||||
UInt32 numBits = kLenDirectBits64[number];
|
||||
if (numBits > 0)
|
||||
length += m_InBitStream.ReadBits(numBits);
|
||||
}
|
||||
else
|
||||
{
|
||||
length = UINT32(kLenStart32[number]) + kMatchMinLen;
|
||||
UINT32 numBits = kLenDirectBits32[number];
|
||||
length = UInt32(kLenStart32[number]) + kMatchMinLen;
|
||||
UInt32 numBits = kLenDirectBits32[number];
|
||||
if (numBits > 0)
|
||||
length += m_InBitStream.ReadBits(numBits);
|
||||
}
|
||||
|
||||
|
||||
number = m_DistDecoder.DecodeSymbol(&m_InBitStream);
|
||||
UINT32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]);
|
||||
UInt32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]);
|
||||
if (distance >= pos)
|
||||
throw "data error";
|
||||
m_OutWindowStream.CopyBackBlock(distance, length);
|
||||
m_OutWindowStream.CopyBlock(distance, length);
|
||||
pos += length;
|
||||
}
|
||||
else if (number == kReadTableNumber)
|
||||
@@ -242,11 +230,12 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
throw CException(CException::kData);
|
||||
}
|
||||
}
|
||||
coderReleaser.NeedFlush = false;
|
||||
return m_OutWindowStream.Flush();
|
||||
}
|
||||
|
||||
HRESULT CCoder::BaseCode(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
@@ -255,7 +244,7 @@ HRESULT CCoder::BaseCode(ISequentialInStream *inStream,
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
HRESULT CCoder::BaseGetInStreamProcessedSize(UINT64 *value)
|
||||
HRESULT CCoder::BaseGetInStreamProcessedSize(UInt64 *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
return E_INVALIDARG;
|
||||
@@ -263,25 +252,25 @@ HRESULT CCoder::BaseGetInStreamProcessedSize(UINT64 *value)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCOMCoder::GetInStreamProcessedSize(UINT64 *value)
|
||||
STDMETHODIMP CCOMCoder::GetInStreamProcessedSize(UInt64 *value)
|
||||
{
|
||||
return BaseGetInStreamProcessedSize(value);
|
||||
}
|
||||
|
||||
HRESULT CCOMCoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
return BaseCode(inStream, outStream, inSize, outSize, progress);
|
||||
}
|
||||
|
||||
STDMETHODIMP CCOMCoder64::GetInStreamProcessedSize(UINT64 *value)
|
||||
STDMETHODIMP CCOMCoder64::GetInStreamProcessedSize(UInt64 *value)
|
||||
{
|
||||
return BaseGetInStreamProcessedSize(value);
|
||||
}
|
||||
|
||||
HRESULT CCOMCoder64::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
return BaseCode(inStream, outStream, inSize, outSize, progress);
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// DeflateDecoder.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DEFLATE_DECODER_H
|
||||
#define __DEFLATE_DECODER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/LSBFDecoder.h"
|
||||
@@ -14,6 +12,7 @@
|
||||
#include "../Huffman/HuffmanDecoder.h"
|
||||
|
||||
#include "DeflateExtConst.h"
|
||||
#include "DeflateConst.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
@@ -30,26 +29,24 @@ public:
|
||||
};
|
||||
|
||||
typedef NStream::NLSBF::CDecoder<CInBuffer> CInBit;
|
||||
typedef NCompress::NHuffman::CDecoder<kNumHuffmanBits> CHuffmanDecoder;
|
||||
|
||||
class CCoder
|
||||
{
|
||||
CLZOutWindow m_OutWindowStream;
|
||||
CInBit m_InBitStream;
|
||||
CHuffmanDecoder m_MainDecoder;
|
||||
CHuffmanDecoder m_DistDecoder;
|
||||
CHuffmanDecoder m_LevelDecoder; // table for decoding other tables;
|
||||
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kStaticMainTableSize> m_MainDecoder;
|
||||
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kStaticDistTableSize> m_DistDecoder;
|
||||
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
|
||||
|
||||
bool m_FinalBlock;
|
||||
bool m_StoredMode;
|
||||
UINT32 m_StoredBlockSize;
|
||||
UInt32 m_StoredBlockSize;
|
||||
|
||||
bool _deflate64Mode;
|
||||
|
||||
void DeCodeLevelTable(BYTE *newLevels, int numLevels);
|
||||
void DeCodeLevelTable(Byte *newLevels, int numLevels);
|
||||
void ReadTables();
|
||||
|
||||
/*
|
||||
void CCoder::ReleaseStreams()
|
||||
{
|
||||
m_OutWindowStream.ReleaseStream();
|
||||
@@ -59,29 +56,30 @@ class CCoder
|
||||
{
|
||||
CCoder *m_Coder;
|
||||
public:
|
||||
CCoderReleaser(CCoder *coder): m_Coder(coder) {}
|
||||
bool NeedFlush;
|
||||
CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {}
|
||||
~CCoderReleaser()
|
||||
{
|
||||
m_Coder->m_OutWindowStream.Flush();
|
||||
if (NeedFlush)
|
||||
m_Coder->m_OutWindowStream.Flush();
|
||||
m_Coder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
friend class CCoderReleaser;
|
||||
*/
|
||||
|
||||
public:
|
||||
CCoder(bool deflate64Mode = false);
|
||||
|
||||
HRESULT CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
HRESULT BaseCode(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// IGetInStreamProcessedSize
|
||||
HRESULT BaseGetInStreamProcessedSize(UINT64 *aValue);
|
||||
HRESULT BaseGetInStreamProcessedSize(UInt64 *aValue);
|
||||
};
|
||||
|
||||
class CCOMCoder :
|
||||
@@ -95,11 +93,11 @@ public:
|
||||
MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// IGetInStreamProcessedSize
|
||||
STDMETHOD(GetInStreamProcessedSize)(UINT64 *aValue);
|
||||
STDMETHOD(GetInStreamProcessedSize)(UInt64 *aValue);
|
||||
|
||||
CCOMCoder(): CCoder(false) {}
|
||||
};
|
||||
@@ -114,11 +112,11 @@ public:
|
||||
MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// IGetInStreamProcessedSize
|
||||
STDMETHOD(GetInStreamProcessedSize)(UINT64 *aValue);
|
||||
STDMETHOD(GetInStreamProcessedSize)(UInt64 *aValue);
|
||||
|
||||
CCOMCoder64(): CCoder(true) {}
|
||||
};
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "../LZ/BinTree/BinTree3ZMain.h"
|
||||
#include "../../../Common/Alloc.h"
|
||||
#include "../LZ/BinTree/BinTree3Z.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
@@ -25,22 +26,22 @@ static const int kValueBlockSize = 0x2000;
|
||||
static const int kMaxCodeBitLength = 15;
|
||||
static const int kMaxLevelBitLength = 7;
|
||||
|
||||
static const BYTE kFlagImm = 0;
|
||||
static const BYTE kFlagLenPos = 4;
|
||||
static const Byte kFlagImm = 0;
|
||||
static const Byte kFlagLenPos = 4;
|
||||
|
||||
static const UINT32 kMaxUncompressedBlockSize = 0xFFFF; // test it !!!
|
||||
static const UInt32 kMaxUncompressedBlockSize = 0xFFFF; // test it !!!
|
||||
|
||||
static const UINT32 kBlockUncompressedSizeThreshold =
|
||||
static const UInt32 kBlockUncompressedSizeThreshold =
|
||||
kMaxUncompressedBlockSize - kMatchMaxLen32 - kNumOpts;
|
||||
|
||||
static const int kNumGoodBacks = 0x10000;
|
||||
|
||||
static BYTE kNoLiteralDummy = 13;
|
||||
static BYTE kNoLenDummy = 13;
|
||||
static BYTE kNoPosDummy = 6;
|
||||
static Byte kNoLiteralDummy = 13;
|
||||
static Byte kNoLenDummy = 13;
|
||||
static Byte kNoPosDummy = 6;
|
||||
|
||||
static BYTE g_LenSlots[kNumLenCombinations32];
|
||||
static BYTE g_FastPos[1 << 9];
|
||||
static Byte g_LenSlots[kNumLenCombinations32];
|
||||
static Byte g_FastPos[1 << 9];
|
||||
|
||||
class CFastPosInit
|
||||
{
|
||||
@@ -53,15 +54,15 @@ public:
|
||||
int c = kLenStart32[i];
|
||||
int j = 1 << kLenDirectBits32[i];
|
||||
for(int k = 0; k < j; k++, c++)
|
||||
g_LenSlots[c] = i;
|
||||
g_LenSlots[c] = (Byte)i;
|
||||
}
|
||||
|
||||
const int kFastSlots = 18;
|
||||
int c = 0;
|
||||
for (BYTE slotFast = 0; slotFast < kFastSlots; slotFast++)
|
||||
for (Byte slotFast = 0; slotFast < kFastSlots; slotFast++)
|
||||
{
|
||||
UINT32 k = (1 << kDistDirectBits[slotFast]);
|
||||
for (UINT32 j = 0; j < k; j++, c++)
|
||||
UInt32 k = (1 << kDistDirectBits[slotFast]);
|
||||
for (UInt32 j = 0; j < k; j++, c++)
|
||||
g_FastPos[c] = slotFast;
|
||||
}
|
||||
}
|
||||
@@ -70,9 +71,9 @@ public:
|
||||
static CFastPosInit g_FastPosInit;
|
||||
|
||||
|
||||
inline UINT32 GetPosSlot(UINT32 pos)
|
||||
inline UInt32 GetPosSlot(UInt32 pos)
|
||||
{
|
||||
// for (UINT32 i = 1; pos >= kDistStart[i]; i++);
|
||||
// for (UInt32 i = 1; pos >= kDistStart[i]; i++);
|
||||
// return i - 1;
|
||||
if (pos < 0x200)
|
||||
return g_FastPos[pos];
|
||||
@@ -81,11 +82,6 @@ inline UINT32 GetPosSlot(UINT32 pos)
|
||||
|
||||
CCoder::CCoder(bool deflate64Mode):
|
||||
_deflate64Mode(deflate64Mode),
|
||||
m_MainCoder(kMainTableSize,
|
||||
deflate64Mode ? kLenDirectBits64 : kLenDirectBits32,
|
||||
kMatchNumber, kMaxCodeBitLength),
|
||||
m_DistCoder(deflate64Mode ? kDistTableSize64 : kDistTableSize32, kDistDirectBits, 0, kMaxCodeBitLength),
|
||||
m_LevelCoder(kLevelTableSize, kLevelDirectBits, 0, kMaxLevelBitLength),
|
||||
m_NumPasses(1),
|
||||
m_NumFastBytes(32),
|
||||
m_OnePosMatchesMemory(0),
|
||||
@@ -99,47 +95,57 @@ CCoder::CCoder(bool deflate64Mode):
|
||||
kNumLenCombinations32;
|
||||
m_LenStart = deflate64Mode ? kLenStart64 : kLenStart32;
|
||||
m_LenDirectBits = deflate64Mode ? kLenDirectBits64 : kLenDirectBits32;
|
||||
|
||||
m_Values = new CCodeValue[kValueBlockSize + kNumOpts];
|
||||
}
|
||||
|
||||
HRESULT CCoder::Create()
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
m_MatchFinder.Create(
|
||||
_deflate64Mode ? kHistorySize64 : kHistorySize32,
|
||||
kNumOpts + kNumGoodBacks, m_NumFastBytes,
|
||||
m_MatchMaxLen - m_NumFastBytes);
|
||||
if (!m_MatchFinder)
|
||||
{
|
||||
m_MatchFinder = new NBT3Z::CMatchFinderBinTree;
|
||||
if (m_MatchFinder == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (m_Values == 0)
|
||||
{
|
||||
m_Values = (CCodeValue *)MyAlloc((kValueBlockSize + kNumOpts) * sizeof(CCodeValue));
|
||||
if (m_Values == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
RINOK(m_MatchFinder->Create(_deflate64Mode ? kHistorySize64 : kHistorySize32,
|
||||
kNumOpts + kNumGoodBacks, m_NumFastBytes, m_MatchMaxLen - m_NumFastBytes));
|
||||
if (!m_OutStream.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
m_MatchLengthEdge = m_NumFastBytes + 1;
|
||||
|
||||
Free();
|
||||
if (m_NumPasses > 1)
|
||||
{
|
||||
m_OnePosMatchesMemory = new UINT16[kNumGoodBacks * (m_NumFastBytes + 1)];
|
||||
try
|
||||
{
|
||||
m_OnePosMatchesArray = new COnePosMatches[kNumGoodBacks];
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
delete []m_OnePosMatchesMemory;
|
||||
m_OnePosMatchesMemory = 0;
|
||||
throw;
|
||||
}
|
||||
UINT16 *goodBacksWordsCurrent = m_OnePosMatchesMemory;
|
||||
m_OnePosMatchesMemory = (UInt16 *)BigAlloc(kNumGoodBacks * (m_NumFastBytes + 1) * sizeof(UInt16));
|
||||
if (m_OnePosMatchesMemory == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
m_OnePosMatchesArray = (COnePosMatches *)MyAlloc(kNumGoodBacks * sizeof(COnePosMatches));
|
||||
if (m_OnePosMatchesArray == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
UInt16 *goodBacksWordsCurrent = m_OnePosMatchesMemory;
|
||||
for(int i = 0; i < kNumGoodBacks; i++, goodBacksWordsCurrent += (m_NumFastBytes + 1))
|
||||
m_OnePosMatchesArray[i].Init(goodBacksWordsCurrent);
|
||||
}
|
||||
else
|
||||
m_MatchDistances = new UINT16[m_NumFastBytes + 1];
|
||||
{
|
||||
m_MatchDistances = (UInt16 *)MyAlloc((m_NumFastBytes + 1) * sizeof(UInt16));
|
||||
if (m_MatchDistances == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
// ICompressSetEncoderProperties2
|
||||
HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UINT32 numProperties)
|
||||
const PROPVARIANT *properties, UInt32 numProperties)
|
||||
{
|
||||
for(UINT32 i = 0; i < numProperties; i++)
|
||||
for(UInt32 i = 0; i < numProperties; i++)
|
||||
{
|
||||
const PROPVARIANT &property = properties[i];
|
||||
switch(propIDs[i])
|
||||
@@ -171,52 +177,52 @@ void CCoder::Free()
|
||||
{
|
||||
if (m_NumPasses > 1)
|
||||
{
|
||||
delete []m_OnePosMatchesMemory;
|
||||
delete []m_OnePosMatchesArray;
|
||||
BigFree(m_OnePosMatchesMemory);
|
||||
MyFree(m_OnePosMatchesArray);
|
||||
}
|
||||
else
|
||||
delete []m_MatchDistances;
|
||||
MyFree(m_MatchDistances);
|
||||
}
|
||||
}
|
||||
|
||||
CCoder::~CCoder()
|
||||
{
|
||||
Free();
|
||||
delete []m_Values;
|
||||
MyFree(m_Values);
|
||||
}
|
||||
|
||||
void CCoder::ReadGoodBacks()
|
||||
{
|
||||
UINT32 goodIndex;
|
||||
UInt32 goodIndex;
|
||||
if (m_NumPasses > 1)
|
||||
{
|
||||
goodIndex = m_FinderPos % kNumGoodBacks;
|
||||
m_MatchDistances = m_OnePosMatchesArray[goodIndex].MatchDistances;
|
||||
}
|
||||
UINT32 distanceTmp[kMatchMaxLen32 + 1];
|
||||
UINT32 len = m_MatchFinder.GetLongestMatch(distanceTmp);
|
||||
for(UINT32 i = kMatchMinLen; i <= len; i++)
|
||||
m_MatchDistances[i] = distanceTmp[i];
|
||||
UInt32 distanceTmp[kMatchMaxLen32 + 1];
|
||||
UInt32 len = m_MatchFinder->GetLongestMatch(distanceTmp);
|
||||
for(UInt32 i = kMatchMinLen; i <= len; i++)
|
||||
m_MatchDistances[i] = (UInt16)distanceTmp[i];
|
||||
|
||||
m_LongestMatchDistance = m_MatchDistances[len];
|
||||
if (len == m_NumFastBytes && m_NumFastBytes != m_MatchMaxLen)
|
||||
m_LongestMatchLength = len + m_MatchFinder.GetMatchLen(len,
|
||||
m_LongestMatchLength = len + m_MatchFinder->GetMatchLen(len,
|
||||
m_LongestMatchDistance, m_MatchMaxLen - len);
|
||||
else
|
||||
m_LongestMatchLength = len;
|
||||
if (m_NumPasses > 1)
|
||||
{
|
||||
m_OnePosMatchesArray[goodIndex].LongestMatchDistance = UINT16(m_LongestMatchDistance);
|
||||
m_OnePosMatchesArray[goodIndex].LongestMatchLength = UINT16(m_LongestMatchLength);
|
||||
m_OnePosMatchesArray[goodIndex].LongestMatchDistance = UInt16(m_LongestMatchDistance);
|
||||
m_OnePosMatchesArray[goodIndex].LongestMatchLength = UInt16(m_LongestMatchLength);
|
||||
}
|
||||
HRESULT result = m_MatchFinder.MovePos();
|
||||
HRESULT result = m_MatchFinder->MovePos();
|
||||
if (result != S_OK)
|
||||
throw CMatchFinderException(result);
|
||||
m_FinderPos++;
|
||||
m_AdditionalOffset++;
|
||||
}
|
||||
|
||||
void CCoder::GetBacks(UINT32 pos)
|
||||
void CCoder::GetBacks(UInt32 pos)
|
||||
{
|
||||
if(pos == m_FinderPos)
|
||||
ReadGoodBacks();
|
||||
@@ -230,7 +236,7 @@ void CCoder::GetBacks(UINT32 pos)
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 goodIndex = pos % kNumGoodBacks;
|
||||
UInt32 goodIndex = pos % kNumGoodBacks;
|
||||
m_MatchDistances = m_OnePosMatchesArray[goodIndex].MatchDistances;
|
||||
m_LongestMatchDistance = m_OnePosMatchesArray[goodIndex].LongestMatchDistance;
|
||||
m_LongestMatchLength = m_OnePosMatchesArray[goodIndex].LongestMatchLength;
|
||||
@@ -239,19 +245,19 @@ void CCoder::GetBacks(UINT32 pos)
|
||||
}
|
||||
|
||||
|
||||
void CCoder::MovePos(UINT32 num)
|
||||
void CCoder::MovePos(UInt32 num)
|
||||
{
|
||||
if (m_NumPasses > 1)
|
||||
{
|
||||
for(UINT32 i = 0; i < num; i++)
|
||||
GetBacks(UINT32(m_BlockStartPostion + m_CurrentBlockUncompressedSize + i + 1));
|
||||
for(UInt32 i = 0; i < num; i++)
|
||||
GetBacks(UInt32(m_BlockStartPostion + m_CurrentBlockUncompressedSize + i + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (;num > 0; num--)
|
||||
{
|
||||
m_MatchFinder.DummyLongestMatch();
|
||||
HRESULT result = m_MatchFinder.MovePos();
|
||||
m_MatchFinder->DummyLongestMatch();
|
||||
HRESULT result = m_MatchFinder->MovePos();
|
||||
if (result != S_OK)
|
||||
throw CMatchFinderException(result);
|
||||
m_FinderPos++;
|
||||
@@ -260,21 +266,21 @@ void CCoder::MovePos(UINT32 num)
|
||||
}
|
||||
}
|
||||
|
||||
static const UINT32 kIfinityPrice = 0xFFFFFFF;
|
||||
static const UInt32 kIfinityPrice = 0xFFFFFFF;
|
||||
|
||||
UINT32 CCoder::Backward(UINT32 &backRes, UINT32 cur)
|
||||
UInt32 CCoder::Backward(UInt32 &backRes, UInt32 cur)
|
||||
{
|
||||
m_OptimumEndIndex = cur;
|
||||
UINT32 posMem = m_Optimum[cur].PosPrev;
|
||||
UINT16 backMem = m_Optimum[cur].BackPrev;
|
||||
UInt32 posMem = m_Optimum[cur].PosPrev;
|
||||
UInt16 backMem = m_Optimum[cur].BackPrev;
|
||||
do
|
||||
{
|
||||
UINT32 posPrev = posMem;
|
||||
UINT16 backCur = backMem;
|
||||
UInt32 posPrev = posMem;
|
||||
UInt16 backCur = backMem;
|
||||
backMem = m_Optimum[posPrev].BackPrev;
|
||||
posMem = m_Optimum[posPrev].PosPrev;
|
||||
m_Optimum[posPrev].BackPrev = backCur;
|
||||
m_Optimum[posPrev].PosPrev = cur;
|
||||
m_Optimum[posPrev].PosPrev = (UInt16)cur;
|
||||
cur = posPrev;
|
||||
}
|
||||
while(cur > 0);
|
||||
@@ -283,11 +289,11 @@ UINT32 CCoder::Backward(UINT32 &backRes, UINT32 cur)
|
||||
return m_OptimumCurrentIndex;
|
||||
}
|
||||
|
||||
UINT32 CCoder::GetOptimal(UINT32 &backRes)
|
||||
UInt32 CCoder::GetOptimal(UInt32 &backRes)
|
||||
{
|
||||
if(m_OptimumEndIndex != m_OptimumCurrentIndex)
|
||||
{
|
||||
UINT32 len = m_Optimum[m_OptimumCurrentIndex].PosPrev - m_OptimumCurrentIndex;
|
||||
UInt32 len = m_Optimum[m_OptimumCurrentIndex].PosPrev - m_OptimumCurrentIndex;
|
||||
backRes = m_Optimum[m_OptimumCurrentIndex].BackPrev;
|
||||
m_OptimumCurrentIndex = m_Optimum[m_OptimumCurrentIndex].PosPrev;
|
||||
return len;
|
||||
@@ -295,10 +301,10 @@ UINT32 CCoder::GetOptimal(UINT32 &backRes)
|
||||
m_OptimumCurrentIndex = 0;
|
||||
m_OptimumEndIndex = 0;
|
||||
|
||||
GetBacks(UINT32(m_BlockStartPostion + m_CurrentBlockUncompressedSize));
|
||||
GetBacks(UInt32(m_BlockStartPostion + m_CurrentBlockUncompressedSize));
|
||||
|
||||
UINT32 lenMain = m_LongestMatchLength;
|
||||
UINT32 backMain = m_LongestMatchDistance;
|
||||
UInt32 lenMain = m_LongestMatchLength;
|
||||
UInt32 backMain = m_LongestMatchDistance;
|
||||
|
||||
if(lenMain < kMatchMinLen)
|
||||
return 1;
|
||||
@@ -308,13 +314,13 @@ UINT32 CCoder::GetOptimal(UINT32 &backRes)
|
||||
MovePos(lenMain - 1);
|
||||
return lenMain;
|
||||
}
|
||||
m_Optimum[1].Price = m_LiteralPrices[m_MatchFinder.GetIndexByte(0 - m_AdditionalOffset)];
|
||||
m_Optimum[1].Price = m_LiteralPrices[m_MatchFinder->GetIndexByte(0 - m_AdditionalOffset)];
|
||||
m_Optimum[1].PosPrev = 0;
|
||||
|
||||
m_Optimum[2].Price = kIfinityPrice;
|
||||
m_Optimum[2].PosPrev = 1;
|
||||
|
||||
for(UINT32 i = kMatchMinLen; i <= lenMain; i++)
|
||||
for(UInt32 i = kMatchMinLen; i <= lenMain; i++)
|
||||
{
|
||||
m_Optimum[i].PosPrev = 0;
|
||||
m_Optimum[i].BackPrev = m_MatchDistances[i];
|
||||
@@ -322,26 +328,26 @@ UINT32 CCoder::GetOptimal(UINT32 &backRes)
|
||||
}
|
||||
|
||||
|
||||
UINT32 cur = 0;
|
||||
UINT32 lenEnd = lenMain;
|
||||
UInt32 cur = 0;
|
||||
UInt32 lenEnd = lenMain;
|
||||
while(true)
|
||||
{
|
||||
cur++;
|
||||
if(cur == lenEnd)
|
||||
return Backward(backRes, cur);
|
||||
GetBacks(UINT32(m_BlockStartPostion + m_CurrentBlockUncompressedSize + cur));
|
||||
UINT32 newLen = m_LongestMatchLength;
|
||||
GetBacks(UInt32(m_BlockStartPostion + m_CurrentBlockUncompressedSize + cur));
|
||||
UInt32 newLen = m_LongestMatchLength;
|
||||
if(newLen >= m_MatchLengthEdge)
|
||||
return Backward(backRes, cur);
|
||||
|
||||
UINT32 curPrice = m_Optimum[cur].Price;
|
||||
UINT32 curAnd1Price = curPrice +
|
||||
m_LiteralPrices[m_MatchFinder.GetIndexByte(cur - m_AdditionalOffset)];
|
||||
UInt32 curPrice = m_Optimum[cur].Price;
|
||||
UInt32 curAnd1Price = curPrice +
|
||||
m_LiteralPrices[m_MatchFinder->GetIndexByte(cur - m_AdditionalOffset)];
|
||||
COptimal &optimum = m_Optimum[cur + 1];
|
||||
if (curAnd1Price < optimum.Price)
|
||||
{
|
||||
optimum.Price = curAnd1Price;
|
||||
optimum.PosPrev = cur;
|
||||
optimum.PosPrev = (UInt16)cur;
|
||||
}
|
||||
if (newLen < kMatchMinLen)
|
||||
continue;
|
||||
@@ -349,24 +355,24 @@ UINT32 CCoder::GetOptimal(UINT32 &backRes)
|
||||
{
|
||||
if (cur + newLen > kNumOpts - 1)
|
||||
newLen = kNumOpts - 1 - cur;
|
||||
UINT32 lenEndNew = cur + newLen;
|
||||
UInt32 lenEndNew = cur + newLen;
|
||||
if (lenEnd < lenEndNew)
|
||||
{
|
||||
for(UINT32 i = lenEnd + 1; i <= lenEndNew; i++)
|
||||
for(UInt32 i = lenEnd + 1; i <= lenEndNew; i++)
|
||||
m_Optimum[i].Price = kIfinityPrice;
|
||||
lenEnd = lenEndNew;
|
||||
}
|
||||
}
|
||||
for(UINT32 lenTest = kMatchMinLen; lenTest <= newLen; lenTest++)
|
||||
for(UInt32 lenTest = kMatchMinLen; lenTest <= newLen; lenTest++)
|
||||
{
|
||||
UINT16 curBack = m_MatchDistances[lenTest];
|
||||
UINT32 curAndLenPrice = curPrice +
|
||||
UInt16 curBack = m_MatchDistances[lenTest];
|
||||
UInt32 curAndLenPrice = curPrice +
|
||||
m_LenPrices[lenTest - kMatchMinLen] + m_PosPrices[GetPosSlot(curBack)];
|
||||
COptimal &optimum = m_Optimum[cur + lenTest];
|
||||
if (curAndLenPrice < optimum.Price)
|
||||
{
|
||||
optimum.Price = curAndLenPrice;
|
||||
optimum.PosPrev = cur;
|
||||
optimum.PosPrev = (UInt16)cur;
|
||||
optimum.BackPrev = curBack;
|
||||
}
|
||||
}
|
||||
@@ -389,13 +395,13 @@ void CCoder::InitStructures()
|
||||
m_MainCoder.StartNewBlock();
|
||||
m_DistCoder.StartNewBlock();
|
||||
|
||||
UINT32 i;
|
||||
UInt32 i;
|
||||
for(i = 0; i < 256; i++)
|
||||
m_LiteralPrices[i] = 8;
|
||||
for(i = 0; i < m_NumLenCombinations; i++)
|
||||
m_LenPrices[i] = 5 + m_LenDirectBits[g_LenSlots[i]]; // test it
|
||||
m_LenPrices[i] = (Byte)(5 + m_LenDirectBits[g_LenSlots[i]]); // test it
|
||||
for(i = 0; i < kDistTableSize64; i++)
|
||||
m_PosPrices[i] = 5 + kDistDirectBits[i];
|
||||
m_PosPrices[i] = (Byte)(5 + kDistDirectBits[i]);
|
||||
}
|
||||
|
||||
void CCoder::WriteBlockData(bool writeMode, bool finalBlock)
|
||||
@@ -407,27 +413,27 @@ void CCoder::WriteBlockData(bool writeMode, bool finalBlock)
|
||||
{
|
||||
if(method == NBlockType::kStored)
|
||||
{
|
||||
for(UINT32 i = 0; i < m_CurrentBlockUncompressedSize; i++)
|
||||
for(UInt32 i = 0; i < m_CurrentBlockUncompressedSize; i++)
|
||||
{
|
||||
BYTE b = m_MatchFinder.GetIndexByte(i - m_AdditionalOffset -
|
||||
Byte b = m_MatchFinder->GetIndexByte(i - m_AdditionalOffset -
|
||||
m_CurrentBlockUncompressedSize);
|
||||
m_OutStream.WriteBits(b, 8);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (UINT32 i = 0; i < m_ValueIndex; i++)
|
||||
for (UInt32 i = 0; i < m_ValueIndex; i++)
|
||||
{
|
||||
if (m_Values[i].Flag == kFlagImm)
|
||||
m_MainCoder.CodeOneValue(&m_ReverseOutStream, m_Values[i].Imm);
|
||||
else if (m_Values[i].Flag == kFlagLenPos)
|
||||
{
|
||||
UINT32 len = m_Values[i].Len;
|
||||
UINT32 lenSlot = g_LenSlots[len];
|
||||
UInt32 len = m_Values[i].Len;
|
||||
UInt32 lenSlot = g_LenSlots[len];
|
||||
m_MainCoder.CodeOneValue(&m_ReverseOutStream, kMatchNumber + lenSlot);
|
||||
m_OutStream.WriteBits(len - m_LenStart[lenSlot], m_LenDirectBits[lenSlot]);
|
||||
UINT32 dist = m_Values[i].Pos;
|
||||
UINT32 posSlot = GetPosSlot(dist);
|
||||
UInt32 dist = m_Values[i].Pos;
|
||||
UInt32 posSlot = GetPosSlot(dist);
|
||||
m_DistCoder.CodeOneValue(&m_ReverseOutStream, posSlot);
|
||||
m_OutStream.WriteBits(dist - kDistStart[posSlot], kDistDirectBits[posSlot]);
|
||||
}
|
||||
@@ -438,7 +444,7 @@ void CCoder::WriteBlockData(bool writeMode, bool finalBlock)
|
||||
m_MainCoder.StartNewBlock();
|
||||
m_DistCoder.StartNewBlock();
|
||||
m_ValueIndex = 0;
|
||||
UINT32 i;
|
||||
UInt32 i;
|
||||
for(i = 0; i < 256; i++)
|
||||
if(m_LastLevels[i] != 0)
|
||||
m_LiteralPrices[i] = m_LastLevels[i];
|
||||
@@ -449,8 +455,8 @@ void CCoder::WriteBlockData(bool writeMode, bool finalBlock)
|
||||
|
||||
for(i = 0; i < m_NumLenCombinations; i++)
|
||||
{
|
||||
UINT32 slot = g_LenSlots[i];
|
||||
BYTE dummy = m_LastLevels[kMatchNumber + slot];
|
||||
UInt32 slot = g_LenSlots[i];
|
||||
Byte dummy = m_LastLevels[kMatchNumber + slot];
|
||||
if (dummy != 0)
|
||||
m_LenPrices[i] = dummy;
|
||||
else
|
||||
@@ -459,7 +465,7 @@ void CCoder::WriteBlockData(bool writeMode, bool finalBlock)
|
||||
}
|
||||
for(i = 0; i < kDistTableSize64; i++)
|
||||
{
|
||||
BYTE dummy = m_LastLevels[kDistTableStart + i];
|
||||
Byte dummy = m_LastLevels[kDistTableStart + i];
|
||||
if (dummy != 0)
|
||||
m_PosPrices[i] = dummy;
|
||||
else
|
||||
@@ -468,7 +474,7 @@ void CCoder::WriteBlockData(bool writeMode, bool finalBlock)
|
||||
}
|
||||
}
|
||||
|
||||
void CCoder::CodeLevelTable(BYTE *newLevels, int numLevels, bool codeMode)
|
||||
void CCoder::CodeLevelTable(Byte *newLevels, int numLevels, bool codeMode)
|
||||
{
|
||||
int prevLen = 0xFF; // last emitted length
|
||||
int nextLen = newLevels[0]; // length of next code
|
||||
@@ -480,7 +486,7 @@ void CCoder::CodeLevelTable(BYTE *newLevels, int numLevels, bool codeMode)
|
||||
maxCount = 138;
|
||||
minCount = 3;
|
||||
}
|
||||
BYTE oldValueInGuardElement = newLevels[numLevels]; // push guard value
|
||||
Byte oldValueInGuardElement = newLevels[numLevels]; // push guard value
|
||||
try
|
||||
{
|
||||
newLevels[numLevels] = 0xFF; // guard already set
|
||||
@@ -568,7 +574,7 @@ void CCoder::CodeLevelTable(BYTE *newLevels, int numLevels, bool codeMode)
|
||||
|
||||
int CCoder::WriteTables(bool writeMode, bool finalBlock)
|
||||
{
|
||||
BYTE newLevels[kMaxTableSize64 + 1]; // (+ 1) for guard
|
||||
Byte newLevels[kMaxTableSize64 + 1]; // (+ 1) for guard
|
||||
|
||||
m_MainCoder.BuildTree(&newLevels[0]);
|
||||
m_DistCoder.BuildTree(&newLevels[kDistTableStart]);
|
||||
@@ -604,22 +610,22 @@ int CCoder::WriteTables(bool writeMode, bool finalBlock)
|
||||
memcpy(m_LastLevels, newLevels, kMaxTableSize64);
|
||||
|
||||
|
||||
BYTE levelLevels[kLevelTableSize];
|
||||
Byte levelLevels[kLevelTableSize];
|
||||
m_LevelCoder.BuildTree(levelLevels);
|
||||
|
||||
BYTE levelLevelsStream[kLevelTableSize];
|
||||
Byte levelLevelsStream[kLevelTableSize];
|
||||
int numLevelCodes = kDeflateNumberOfLevelCodesMin;
|
||||
int i;
|
||||
for (i = 0; i < kLevelTableSize; i++)
|
||||
{
|
||||
int streamPos = kCodeLengthAlphabetOrder[i];
|
||||
int level = levelLevels[streamPos];
|
||||
Byte level = levelLevels[streamPos];
|
||||
if (level > 0 && i >= numLevelCodes)
|
||||
numLevelCodes = i + 1;
|
||||
levelLevelsStream[i] = level;
|
||||
}
|
||||
|
||||
UINT32 numLZHuffmanBits = m_MainCoder.GetBlockBitLength();
|
||||
UInt32 numLZHuffmanBits = m_MainCoder.GetBlockBitLength();
|
||||
numLZHuffmanBits += m_DistCoder.GetBlockBitLength();
|
||||
numLZHuffmanBits += m_LevelCoder.GetBlockBitLength();
|
||||
numLZHuffmanBits += kDeflateNumberOfLengthCodesFieldSize +
|
||||
@@ -627,18 +633,18 @@ int CCoder::WriteTables(bool writeMode, bool finalBlock)
|
||||
kDeflateNumberOfLevelCodesFieldSize;
|
||||
numLZHuffmanBits += numLevelCodes * kDeflateLevelCodeFieldSize;
|
||||
|
||||
UINT32 nextBitPosition =
|
||||
UInt32 nextBitPosition =
|
||||
(m_OutStream.GetBitPosition() + kBlockTypeFieldSize) % 8;
|
||||
UINT32 numBitsForAlign = nextBitPosition > 0 ? (8 - nextBitPosition): 0;
|
||||
UInt32 numBitsForAlign = nextBitPosition > 0 ? (8 - nextBitPosition): 0;
|
||||
|
||||
UINT32 numStoreBits = numBitsForAlign + (2 * sizeof(UINT16)) * 8;
|
||||
UInt32 numStoreBits = numBitsForAlign + (2 * 2) * 8;
|
||||
numStoreBits += m_CurrentBlockUncompressedSize * 8;
|
||||
if(numStoreBits < numLZHuffmanBits)
|
||||
{
|
||||
m_OutStream.WriteBits(NBlockType::kStored, kBlockTypeFieldSize); // test it
|
||||
m_OutStream.WriteBits(0, numBitsForAlign); // test it
|
||||
UINT16 currentBlockUncompressedSize = UINT16(m_CurrentBlockUncompressedSize);
|
||||
UINT16 currentBlockUncompressedSizeNot = ~currentBlockUncompressedSize;
|
||||
UInt16 currentBlockUncompressedSize = UInt16(m_CurrentBlockUncompressedSize);
|
||||
UInt16 currentBlockUncompressedSizeNot = ~currentBlockUncompressedSize;
|
||||
m_OutStream.WriteBits(currentBlockUncompressedSize, kDeflateStoredBlockLengthFieldSizeSize);
|
||||
m_OutStream.WriteBits(currentBlockUncompressedSizeNot, kDeflateStoredBlockLengthFieldSizeSize);
|
||||
return NBlockType::kStored;
|
||||
@@ -669,23 +675,33 @@ int CCoder::WriteTables(bool writeMode, bool finalBlock)
|
||||
}
|
||||
|
||||
HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (!m_Created)
|
||||
{
|
||||
RINOK(Create());
|
||||
|
||||
if (!m_MainCoder.Create(kMainTableSize, _deflate64Mode ? kLenDirectBits64 : kLenDirectBits32,
|
||||
kMatchNumber, kMaxCodeBitLength))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!m_DistCoder.Create(_deflate64Mode ? kDistTableSize64 : kDistTableSize32,
|
||||
kDistDirectBits, 0, kMaxCodeBitLength))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!m_LevelCoder.Create(kLevelTableSize, kLevelDirectBits, 0, kMaxLevelBitLength))
|
||||
return E_OUTOFMEMORY;
|
||||
m_Created = true;
|
||||
}
|
||||
|
||||
UINT64 nowPos = 0;
|
||||
UInt64 nowPos = 0;
|
||||
m_FinderPos = 0;
|
||||
|
||||
RINOK(m_MatchFinder.Init(inStream));
|
||||
m_OutStream.Init(outStream);
|
||||
RINOK(m_MatchFinder->Init(inStream));
|
||||
m_OutStream.SetStream(outStream);
|
||||
m_OutStream.Init();
|
||||
m_ReverseOutStream.Init(&m_OutStream);
|
||||
|
||||
// CCoderReleaser coderReleaser(this);
|
||||
CCoderReleaser coderReleaser(this);
|
||||
InitStructures();
|
||||
|
||||
while(true)
|
||||
@@ -696,29 +712,29 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
noMoreBytes = (m_AdditionalOffset == 0 && m_MatchFinder.GetNumAvailableBytes() == 0);
|
||||
noMoreBytes = (m_AdditionalOffset == 0 && m_MatchFinder->GetNumAvailableBytes() == 0);
|
||||
|
||||
if (((m_CurrentBlockUncompressedSize >= kBlockUncompressedSizeThreshold ||
|
||||
m_ValueIndex >= kValueBlockSize) &&
|
||||
(m_OptimumEndIndex == m_OptimumCurrentIndex))
|
||||
|| noMoreBytes)
|
||||
break;
|
||||
UINT32 pos;
|
||||
UINT32 len = GetOptimal(pos);
|
||||
UInt32 pos;
|
||||
UInt32 len = GetOptimal(pos);
|
||||
if (len >= kMatchMinLen)
|
||||
{
|
||||
UINT32 newLen = len - kMatchMinLen;
|
||||
UInt32 newLen = len - kMatchMinLen;
|
||||
m_Values[m_ValueIndex].Flag = kFlagLenPos;
|
||||
m_Values[m_ValueIndex].Len = BYTE(newLen);
|
||||
UINT32 lenSlot = g_LenSlots[newLen];
|
||||
m_Values[m_ValueIndex].Len = Byte(newLen);
|
||||
UInt32 lenSlot = g_LenSlots[newLen];
|
||||
m_MainCoder.AddSymbol(kMatchNumber + lenSlot);
|
||||
m_Values[m_ValueIndex].Pos = UINT16(pos);
|
||||
UINT32 posSlot = GetPosSlot(pos);
|
||||
m_Values[m_ValueIndex].Pos = UInt16(pos);
|
||||
UInt32 posSlot = GetPosSlot(pos);
|
||||
m_DistCoder.AddSymbol(posSlot);
|
||||
}
|
||||
else if (len == 1)
|
||||
{
|
||||
BYTE b = m_MatchFinder.GetIndexByte(0 - m_AdditionalOffset);
|
||||
Byte b = m_MatchFinder->GetIndexByte(0 - m_AdditionalOffset);
|
||||
len = 1;
|
||||
m_MainCoder.AddSymbol(b);
|
||||
m_Values[m_ValueIndex].Flag = kFlagImm;
|
||||
@@ -738,14 +754,14 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
if (writeMode)
|
||||
break;
|
||||
nowPos = m_BlockStartPostion;
|
||||
m_AdditionalOffset = UINT32(m_FinderPos - m_BlockStartPostion);
|
||||
m_AdditionalOffset = UInt32(m_FinderPos - m_BlockStartPostion);
|
||||
m_CurrentBlockUncompressedSize = 0;
|
||||
}
|
||||
m_BlockStartPostion += m_CurrentBlockUncompressedSize;
|
||||
m_CurrentBlockUncompressedSize = 0;
|
||||
if (progress != NULL)
|
||||
{
|
||||
UINT64 packSize = m_OutStream.GetProcessedSize();
|
||||
UInt64 packSize = m_OutStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&nowPos, &packSize));
|
||||
}
|
||||
if (noMoreBytes)
|
||||
@@ -755,7 +771,7 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
}
|
||||
|
||||
HRESULT CCoder::BaseCode(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
@@ -765,21 +781,21 @@ HRESULT CCoder::BaseCode(ISequentialInStream *inStream,
|
||||
}
|
||||
|
||||
STDMETHODIMP CCOMCoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{ return BaseCode(inStream, outStream, inSize, outSize, progress); }
|
||||
|
||||
STDMETHODIMP CCOMCoder::SetCoderProperties(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UINT32 numProperties)
|
||||
const PROPVARIANT *properties, UInt32 numProperties)
|
||||
{ return BaseSetEncoderProperties2(propIDs, properties, numProperties); }
|
||||
|
||||
STDMETHODIMP CCOMCoder64::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{ return BaseCode(inStream, outStream, inSize, outSize, progress); }
|
||||
|
||||
STDMETHODIMP CCOMCoder64::SetCoderProperties(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UINT32 numProperties)
|
||||
const PROPVARIANT *properties, UInt32 numProperties)
|
||||
{ return BaseSetEncoderProperties2(propIDs, properties, numProperties); }
|
||||
|
||||
}}}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// DeflateEncoder.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DEFLATE_ENCODER_H
|
||||
#define __DEFLATE_ENCODER_H
|
||||
|
||||
@@ -9,7 +7,7 @@
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/LSBFEncoder.h"
|
||||
#include "../LZ/BinTree/BinTree3Z.h"
|
||||
#include "../LZ/IMatchFinder.h"
|
||||
#include "../Huffman/HuffmanEncoder.h"
|
||||
|
||||
#include "DeflateConst.h"
|
||||
@@ -20,22 +18,22 @@ namespace NEncoder {
|
||||
|
||||
struct CCodeValue
|
||||
{
|
||||
BYTE Flag;
|
||||
Byte Flag;
|
||||
union
|
||||
{
|
||||
BYTE Imm;
|
||||
BYTE Len;
|
||||
Byte Imm;
|
||||
Byte Len;
|
||||
};
|
||||
UINT16 Pos;
|
||||
UInt16 Pos;
|
||||
};
|
||||
|
||||
class COnePosMatches
|
||||
{
|
||||
public:
|
||||
UINT16 *MatchDistances;
|
||||
UINT16 LongestMatchLength;
|
||||
UINT16 LongestMatchDistance;
|
||||
void Init(UINT16 *matchDistances)
|
||||
UInt16 *MatchDistances;
|
||||
UInt16 LongestMatchLength;
|
||||
UInt16 LongestMatchDistance;
|
||||
void Init(UInt16 *matchDistances)
|
||||
{
|
||||
MatchDistances = matchDistances;
|
||||
};
|
||||
@@ -43,21 +41,20 @@ public:
|
||||
|
||||
struct COptimal
|
||||
{
|
||||
UINT32 Price;
|
||||
UINT16 PosPrev;
|
||||
UINT16 BackPrev;
|
||||
UInt32 Price;
|
||||
UInt16 PosPrev;
|
||||
UInt16 BackPrev;
|
||||
};
|
||||
|
||||
const int kNumOpts = 0x1000;
|
||||
|
||||
class CCoder
|
||||
{
|
||||
UINT32 m_FinderPos;
|
||||
UInt32 m_FinderPos;
|
||||
|
||||
COptimal m_Optimum[kNumOpts];
|
||||
|
||||
// CComPtr<IInWindowStreamMatch> m_MatchFinder;
|
||||
NBT3Z::CInTree m_MatchFinder;
|
||||
CMyComPtr<IMatchFinder> m_MatchFinder;
|
||||
|
||||
NStream::NLSBF::CEncoder m_OutStream;
|
||||
NStream::NLSBF::CReverseEncoder m_ReverseOutStream;
|
||||
@@ -66,93 +63,88 @@ class CCoder
|
||||
NCompression::NHuffman::CEncoder m_DistCoder;
|
||||
NCompression::NHuffman::CEncoder m_LevelCoder;
|
||||
|
||||
BYTE m_LastLevels[kMaxTableSize64];
|
||||
Byte m_LastLevels[kMaxTableSize64];
|
||||
|
||||
UINT32 m_ValueIndex;
|
||||
UInt32 m_ValueIndex;
|
||||
CCodeValue *m_Values;
|
||||
|
||||
UINT32 m_OptimumEndIndex;
|
||||
UINT32 m_OptimumCurrentIndex;
|
||||
UINT32 m_AdditionalOffset;
|
||||
UInt32 m_OptimumEndIndex;
|
||||
UInt32 m_OptimumCurrentIndex;
|
||||
UInt32 m_AdditionalOffset;
|
||||
|
||||
UINT32 m_LongestMatchLength;
|
||||
UINT32 m_LongestMatchDistance;
|
||||
UINT16 *m_MatchDistances;
|
||||
UInt32 m_LongestMatchLength;
|
||||
UInt32 m_LongestMatchDistance;
|
||||
UInt16 *m_MatchDistances;
|
||||
|
||||
UINT32 m_NumFastBytes;
|
||||
UINT32 m_MatchLengthEdge;
|
||||
UInt32 m_NumFastBytes;
|
||||
UInt32 m_MatchLengthEdge;
|
||||
|
||||
BYTE m_LiteralPrices[256];
|
||||
Byte m_LiteralPrices[256];
|
||||
|
||||
BYTE m_LenPrices[kNumLenCombinations32];
|
||||
BYTE m_PosPrices[kDistTableSize64];
|
||||
Byte m_LenPrices[kNumLenCombinations32];
|
||||
Byte m_PosPrices[kDistTableSize64];
|
||||
|
||||
UINT32 m_CurrentBlockUncompressedSize;
|
||||
UInt32 m_CurrentBlockUncompressedSize;
|
||||
|
||||
COnePosMatches *m_OnePosMatchesArray;
|
||||
UINT16 *m_OnePosMatchesMemory;
|
||||
UInt16 *m_OnePosMatchesMemory;
|
||||
|
||||
UINT64 m_BlockStartPostion;
|
||||
UInt64 m_BlockStartPostion;
|
||||
int m_NumPasses;
|
||||
|
||||
bool m_Created;
|
||||
|
||||
bool _deflate64Mode;
|
||||
UINT32 m_NumLenCombinations;
|
||||
UINT32 m_MatchMaxLen;
|
||||
const BYTE *m_LenStart;
|
||||
const BYTE *m_LenDirectBits;
|
||||
UInt32 m_NumLenCombinations;
|
||||
UInt32 m_MatchMaxLen;
|
||||
const Byte *m_LenStart;
|
||||
const Byte *m_LenDirectBits;
|
||||
|
||||
HRESULT Create();
|
||||
void Free();
|
||||
|
||||
void GetBacks(UINT32 aPos);
|
||||
void GetBacks(UInt32 aPos);
|
||||
|
||||
void ReadGoodBacks();
|
||||
void MovePos(UINT32 num);
|
||||
UINT32 Backward(UINT32 &backRes, UINT32 cur);
|
||||
UINT32 GetOptimal(UINT32 &backRes);
|
||||
void MovePos(UInt32 num);
|
||||
UInt32 Backward(UInt32 &backRes, UInt32 cur);
|
||||
UInt32 GetOptimal(UInt32 &backRes);
|
||||
|
||||
void InitStructures();
|
||||
void CodeLevelTable(BYTE *newLevels, int numLevels, bool codeMode);
|
||||
void CodeLevelTable(Byte *newLevels, int numLevels, bool codeMode);
|
||||
int WriteTables(bool writeMode, bool finalBlock);
|
||||
void CopyBackBlockOp(UINT32 distance, UINT32 length);
|
||||
void CopyBackBlockOp(UInt32 distance, UInt32 length);
|
||||
void WriteBlockData(bool writeMode, bool finalBlock);
|
||||
|
||||
/*
|
||||
void CCoder::ReleaseStreams()
|
||||
{
|
||||
m_MatchFinder.ReleaseStream();
|
||||
// m_MatchFinder.ReleaseStream();
|
||||
m_OutStream.ReleaseStream();
|
||||
}
|
||||
class CCoderReleaser
|
||||
{
|
||||
CCoder *m_Coder;
|
||||
public:
|
||||
CCoderReleaser(CCoder *aCoder): m_Coder(aCoder) {}
|
||||
~CCoderReleaser()
|
||||
{
|
||||
m_Coder->ReleaseStreams();
|
||||
}
|
||||
CCoderReleaser(CCoder *coder): m_Coder(coder) {}
|
||||
~CCoderReleaser() { m_Coder->ReleaseStreams(); }
|
||||
};
|
||||
friend class CCoderReleaser;
|
||||
*/
|
||||
|
||||
public:
|
||||
CCoder(bool deflate64Mode = false);
|
||||
~CCoder();
|
||||
|
||||
HRESULT CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
HRESULT BaseCode(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// ICompressSetCoderProperties
|
||||
HRESULT BaseSetEncoderProperties2(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UINT32 numProperties);
|
||||
const PROPVARIANT *properties, UInt32 numProperties);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
@@ -167,11 +159,11 @@ public:
|
||||
MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
|
||||
CCOMCoder(): CCoder(false) {};
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
// ICompressSetCoderProperties
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UINT32 numProperties);
|
||||
const PROPVARIANT *properties, UInt32 numProperties);
|
||||
};
|
||||
|
||||
class CCOMCoder64 :
|
||||
@@ -184,11 +176,11 @@ public:
|
||||
MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
|
||||
CCOMCoder64(): CCoder(true) {};
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
// ICompressSetCoderProperties
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UINT32 numProperties);
|
||||
const PROPVARIANT *properties, UInt32 numProperties);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// DeflateExtConst.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DEFLATE_EXTCONST_H
|
||||
#define __DEFLATE_EXTCONST_H
|
||||
|
||||
@@ -10,17 +8,17 @@
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
|
||||
// const UINT32 kDistTableSize = 30;
|
||||
const UINT32 kDistTableSize32 = 30;
|
||||
const UINT32 kDistTableSize64 = 32;
|
||||
// const UInt32 kDistTableSize = 30;
|
||||
const UInt32 kDistTableSize32 = 30;
|
||||
const UInt32 kDistTableSize64 = 32;
|
||||
|
||||
const UINT32 kHistorySize32 = 0x8000;
|
||||
const UINT32 kHistorySize64 = 0x10000;
|
||||
const UINT32 kNumLenCombinations32 = 256;
|
||||
const UINT32 kNumLenCombinations64 = 255;
|
||||
const UInt32 kHistorySize32 = 0x8000;
|
||||
const UInt32 kHistorySize64 = 0x10000;
|
||||
const UInt32 kNumLenCombinations32 = 256;
|
||||
const UInt32 kNumLenCombinations64 = 255;
|
||||
// don't change kNumLenCombinations64. It must be less than 255.
|
||||
|
||||
const UINT32 kNumHuffmanBits = 15;
|
||||
const UInt32 kNumHuffmanBits = 15;
|
||||
|
||||
}}
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#define INITGUID
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
#include "DeflateEncoder.h"
|
||||
#include "DeflateDecoder.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
|
||||
// {23170F69-40C1-278B-0401-080000000000}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,9,2,0
|
||||
PRODUCTVERSION 3,9,2,0
|
||||
FILEVERSION 4,19,0,0
|
||||
PRODUCTVERSION 4,19,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -85,14 +85,14 @@ BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", " \0"
|
||||
VALUE "FileDescription", "Deflate Coder\0"
|
||||
VALUE "FileVersion", "3, 9, 2, 0\0"
|
||||
VALUE "FileVersion", "4, 19, 0, 0\0"
|
||||
VALUE "InternalName", "Deflate\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "Deflate.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "3, 9, 2, 0\0"
|
||||
VALUE "ProductVersion", "4, 19, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -1,60 +1,42 @@
|
||||
// Compress/HuffmanDecoder.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __COMPRESS_HUFFMANDECODER_H
|
||||
#define __COMPRESS_HUFFMANDECODER_H
|
||||
|
||||
#include "../../../Common/Types.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NHuffman {
|
||||
|
||||
class CDecoderException{};
|
||||
|
||||
const UINT32 kValueTableBits = 8;
|
||||
const UInt32 kValueTableBits = 9;
|
||||
|
||||
template <int kNumBitsInLongestCode>
|
||||
template <int kNumBitsInLongestCode, UInt32 m_NumSymbols>
|
||||
class CDecoder
|
||||
{
|
||||
UINT32 m_Limitits[kNumBitsInLongestCode + 1]; // m_Limitits[i] = value limit for symbols with length = i
|
||||
UINT32 m_Positions[kNumBitsInLongestCode + 1]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i
|
||||
UINT32 m_NumSymbols;
|
||||
UINT32 *m_Symbols; // symbols: at first with len = 1 then 2, ... 15.
|
||||
BYTE m_Lengths[1 << kValueTableBits];
|
||||
UInt32 m_Limitits[kNumBitsInLongestCode + 1]; // m_Limitits[i] = value limit for symbols with length = i
|
||||
UInt32 m_Positions[kNumBitsInLongestCode + 1]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i
|
||||
UInt32 m_Symbols[m_NumSymbols]; // symbols: at first with len = 1 then 2, ... 15.
|
||||
Byte m_Lengths[1 << kValueTableBits];
|
||||
public:
|
||||
CDecoder(UINT32 numSymbols):
|
||||
m_NumSymbols(numSymbols)
|
||||
{ m_Symbols = new UINT32[m_NumSymbols]; }
|
||||
|
||||
~CDecoder()
|
||||
{ delete []m_Symbols; }
|
||||
|
||||
void SetNumSymbols(UINT32 numSymbols)
|
||||
{ m_NumSymbols = numSymbols; }
|
||||
void SetCodeLengths(const BYTE *codeLengths);
|
||||
void SetNumSymbols(UInt32 numSymbols) { m_NumSymbols = numSymbols; }
|
||||
void SetCodeLengths(const Byte *codeLengths);
|
||||
template <class TBitDecoder>
|
||||
UINT32 DecodeSymbol(TBitDecoder *bitStream)
|
||||
UInt32 DecodeSymbol(TBitDecoder *bitStream)
|
||||
{
|
||||
UINT32 numBits;
|
||||
UInt32 numBits;
|
||||
|
||||
UINT32 value = bitStream->GetValue(kNumBitsInLongestCode);
|
||||
UInt32 value = bitStream->GetValue(kNumBitsInLongestCode);
|
||||
|
||||
if (value < m_Limitits[kValueTableBits])
|
||||
numBits = m_Lengths[value >> (kNumBitsInLongestCode - kValueTableBits)];
|
||||
else if (value < m_Limitits[10])
|
||||
if (value < m_Limitits[9])
|
||||
numBits = 9;
|
||||
else
|
||||
numBits = 10;
|
||||
else if (value < m_Limitits[11])
|
||||
numBits = 11;
|
||||
else if (value < m_Limitits[12])
|
||||
numBits = 12;
|
||||
else
|
||||
for (numBits = 13; numBits < kNumBitsInLongestCode; numBits++)
|
||||
for (numBits = kValueTableBits + 1; numBits < kNumBitsInLongestCode; numBits++)
|
||||
if (value < m_Limitits[numBits])
|
||||
break;
|
||||
bitStream->MovePos(numBits);
|
||||
UINT32 index = m_Positions[numBits] +
|
||||
UInt32 index = m_Positions[numBits] +
|
||||
((value - m_Limitits[numBits - 1]) >> (kNumBitsInLongestCode - numBits));
|
||||
if (index >= m_NumSymbols)
|
||||
throw CDecoderException(); // test it
|
||||
@@ -62,27 +44,26 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <int kNumBitsInLongestCode>
|
||||
void CDecoder<kNumBitsInLongestCode>::SetCodeLengths(const BYTE *codeLengths)
|
||||
template <int kNumBitsInLongestCode, UInt32 m_NumSymbols>
|
||||
void CDecoder<kNumBitsInLongestCode, m_NumSymbols>::SetCodeLengths(const Byte *codeLengths)
|
||||
{
|
||||
int lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1];
|
||||
int i;
|
||||
for(i = 1; i <= kNumBitsInLongestCode; i++)
|
||||
lenCounts[i] = 0;
|
||||
UINT32 symbol;
|
||||
UInt32 symbol;
|
||||
for (symbol = 0; symbol < m_NumSymbols; symbol++)
|
||||
{
|
||||
BYTE codeLength = codeLengths[symbol];
|
||||
Byte codeLength = codeLengths[symbol];
|
||||
if (codeLength > kNumBitsInLongestCode)
|
||||
throw CDecoderException();
|
||||
lenCounts[codeLength]++;
|
||||
}
|
||||
lenCounts[0] = 0;
|
||||
tmpPositions[0] = m_Positions[0] = m_Limitits[0] = 0;
|
||||
UINT32 startPos = 0;
|
||||
UINT32 index = 0;
|
||||
const UINT32 kMaxValue = (1 << kNumBitsInLongestCode);
|
||||
UInt32 startPos = 0;
|
||||
UInt32 index = 0;
|
||||
const UInt32 kMaxValue = (1 << kNumBitsInLongestCode);
|
||||
for (i = 1; i <= kNumBitsInLongestCode; i++)
|
||||
{
|
||||
startPos += lenCounts[i] << (kNumBitsInLongestCode - i);
|
||||
@@ -94,8 +75,8 @@ void CDecoder<kNumBitsInLongestCode>::SetCodeLengths(const BYTE *codeLengths)
|
||||
|
||||
if(i <= kValueTableBits)
|
||||
{
|
||||
UINT32 limit = (m_Limitits[i] >> (kNumBitsInLongestCode - kValueTableBits)); // change it
|
||||
memset(m_Lengths + index, BYTE(i), limit - index);
|
||||
UInt32 limit = (m_Limitits[i] >> (kNumBitsInLongestCode - kValueTableBits)); // change it
|
||||
memset(m_Lengths + index, Byte(i), limit - index);
|
||||
index = limit;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,41 +4,63 @@
|
||||
|
||||
#include "HuffmanEncoder.h"
|
||||
#include "Common/Defs.h"
|
||||
#include "Common/Alloc.h"
|
||||
|
||||
namespace NCompression {
|
||||
namespace NHuffman {
|
||||
|
||||
static const char *kIncorrectBitLenCountsMessage = "Incorrect bit len counts";
|
||||
|
||||
CEncoder::CEncoder(UINT32 numSymbols,
|
||||
const BYTE *extraBits, UINT32 extraBase, UINT32 maxLength):
|
||||
m_NumSymbols(numSymbols),
|
||||
m_ExtraBits(extraBits),
|
||||
m_ExtraBase(extraBase),
|
||||
m_MaxLength(maxLength),
|
||||
m_HeapSize(numSymbols * 2+ 1)
|
||||
CEncoder::CEncoder():
|
||||
m_Items(0),
|
||||
m_Heap(0),
|
||||
m_Depth(0)
|
||||
{}
|
||||
|
||||
void CEncoder::Free()
|
||||
{
|
||||
m_Items = new CItem[m_HeapSize];
|
||||
m_Heap = new UINT32[m_HeapSize];
|
||||
m_Depth = new BYTE[m_HeapSize];
|
||||
MyFree(m_Items);
|
||||
MyFree(m_Heap);
|
||||
MyFree(m_Depth);
|
||||
m_Items = 0;
|
||||
m_Heap = 0;
|
||||
m_Depth = 0;
|
||||
}
|
||||
|
||||
bool CEncoder::Create(UInt32 numSymbols,
|
||||
const Byte *extraBits, UInt32 extraBase, UInt32 maxLength)
|
||||
{
|
||||
m_NumSymbols = numSymbols;
|
||||
m_ExtraBits = extraBits;
|
||||
m_ExtraBase = extraBase;
|
||||
m_MaxLength = maxLength;
|
||||
m_HeapSize = numSymbols * 2 + 1;
|
||||
Free();
|
||||
m_Items = (CItem *)MyAlloc(m_HeapSize * sizeof(CItem));
|
||||
m_Heap = (UInt32 *)MyAlloc(m_HeapSize * sizeof(UInt32));
|
||||
m_Depth = (Byte *)MyAlloc(m_HeapSize * sizeof(Byte));
|
||||
if (m_Items == 0 || m_Heap == 0 || m_Depth == 0)
|
||||
{
|
||||
Free();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CEncoder::~CEncoder()
|
||||
{
|
||||
delete []m_Depth;
|
||||
delete []m_Heap;
|
||||
delete []m_Items;
|
||||
Free();
|
||||
}
|
||||
|
||||
void CEncoder::StartNewBlock()
|
||||
{
|
||||
for (UINT32 i = 0; i < m_NumSymbols; i++)
|
||||
for (UInt32 i = 0; i < m_NumSymbols; i++)
|
||||
m_Items[i].Freq = 0;
|
||||
}
|
||||
|
||||
void CEncoder::SetFreqs(const UINT32 *freqs)
|
||||
void CEncoder::SetFreqs(const UInt32 *freqs)
|
||||
{
|
||||
for (UINT32 i = 0; i < m_NumSymbols; i++)
|
||||
for (UInt32 i = 0; i < m_NumSymbols; i++)
|
||||
m_Items[i].Freq = freqs[i];
|
||||
}
|
||||
|
||||
@@ -48,9 +70,9 @@ static const int kSmallest = 1;
|
||||
// Remove the smallest element from the heap and recreate the heap with
|
||||
// one less element. Updates heap and m_HeapLength.
|
||||
|
||||
UINT32 CEncoder::RemoveSmallest()
|
||||
UInt32 CEncoder::RemoveSmallest()
|
||||
{
|
||||
UINT32 top = m_Heap[kSmallest];
|
||||
UInt32 top = m_Heap[kSmallest];
|
||||
m_Heap[kSmallest] = m_Heap[m_HeapLength--];
|
||||
DownHeap(kSmallest);
|
||||
return top;
|
||||
@@ -72,15 +94,15 @@ bool CEncoder::Smaller(int n, int m)
|
||||
// when the m_Heap property is re-established (each father CompareFreqs than its
|
||||
// two sons).
|
||||
|
||||
void CEncoder::DownHeap(UINT32 k)
|
||||
void CEncoder::DownHeap(UInt32 k)
|
||||
{
|
||||
UINT32 symbol = m_Heap[k];
|
||||
for (UINT32 j = k << 1; j <= m_HeapLength;) // j: left son of k
|
||||
UInt32 symbol = m_Heap[k];
|
||||
for (UInt32 j = k << 1; j <= m_HeapLength;) // j: left son of k
|
||||
{
|
||||
// Set j to the smallest of the two sons:
|
||||
if (j < m_HeapLength && Smaller(m_Heap[j+1], m_Heap[j]))
|
||||
j++;
|
||||
UINT32 htemp = m_Heap[j]; // htemp required because of bug in SASC compiler
|
||||
UInt32 htemp = m_Heap[j]; // htemp required because of bug in SASC compiler
|
||||
if (Smaller(symbol, htemp)) // Exit if v is smaller than both sons
|
||||
break;
|
||||
m_Heap[k] = htemp; // Exchange v with the smallest son
|
||||
@@ -100,22 +122,22 @@ void CEncoder::DownHeap(UINT32 k)
|
||||
// The length m_BlockBitLength is updated; static_len is also updated if stree is
|
||||
// not null.
|
||||
|
||||
void CEncoder::GenerateBitLen(UINT32 maxCode, UINT32 heapMax)
|
||||
void CEncoder::GenerateBitLen(UInt32 maxCode, UInt32 heapMax)
|
||||
{
|
||||
int overflow = 0; // number of elements with bit length too large
|
||||
|
||||
for (UINT32 i = 0; i <= kNumBitsInLongestCode; i++)
|
||||
for (UInt32 i = 0; i <= kNumBitsInLongestCode; i++)
|
||||
m_BitLenCounters[i] = 0;
|
||||
|
||||
/* In a first pass, compute the optimal bit lengths (which may
|
||||
* overflow in the case of the bit length tree).
|
||||
*/
|
||||
m_Items[m_Heap[heapMax]].Len = 0; /* root of the heap */
|
||||
UINT32 h; /* heap index */
|
||||
UInt32 h; /* heap index */
|
||||
for (h = heapMax+1; h < m_HeapSize; h++)
|
||||
{
|
||||
UINT32 symbol = m_Heap[h];
|
||||
UINT32 len = m_Items[m_Items[symbol].Dad].Len + 1;
|
||||
UInt32 symbol = m_Heap[h];
|
||||
UInt32 len = m_Items[m_Items[symbol].Dad].Len + 1;
|
||||
if (len > m_MaxLength)
|
||||
{
|
||||
len = m_MaxLength;
|
||||
@@ -125,7 +147,7 @@ void CEncoder::GenerateBitLen(UINT32 maxCode, UINT32 heapMax)
|
||||
if (symbol > maxCode)
|
||||
continue; // not a leaf node
|
||||
m_BitLenCounters[len]++;
|
||||
UINT32 extraBits;
|
||||
UInt32 extraBits;
|
||||
if (m_ExtraBits != 0 && symbol >= m_ExtraBase)
|
||||
extraBits = m_ExtraBits[symbol - m_ExtraBase];
|
||||
else
|
||||
@@ -139,7 +161,7 @@ void CEncoder::GenerateBitLen(UINT32 maxCode, UINT32 heapMax)
|
||||
// Find the first bit length which could increase:
|
||||
do
|
||||
{
|
||||
UINT32 bits = m_MaxLength-1;
|
||||
UInt32 bits = m_MaxLength-1;
|
||||
while (m_BitLenCounters[bits] == 0)
|
||||
bits--;
|
||||
m_BitLenCounters[bits]--; // move one leaf down the m_Items
|
||||
@@ -155,12 +177,12 @@ void CEncoder::GenerateBitLen(UINT32 maxCode, UINT32 heapMax)
|
||||
// h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
|
||||
// lengths instead of fixing only the wrong ones. This idea is taken
|
||||
// from 'ar' written by Haruhiko Okumura.)
|
||||
for (UINT32 bits = m_MaxLength; bits != 0; bits--)
|
||||
for (UInt32 bits = m_MaxLength; bits != 0; bits--)
|
||||
{
|
||||
UINT32 numNodes = m_BitLenCounters[bits];
|
||||
UInt32 numNodes = m_BitLenCounters[bits];
|
||||
while (numNodes != 0)
|
||||
{
|
||||
UINT32 m = m_Heap[--h];
|
||||
UInt32 m = m_Heap[--h];
|
||||
if (m > maxCode)
|
||||
continue;
|
||||
if (m_Items[m].Len != (unsigned) bits)
|
||||
@@ -182,22 +204,22 @@ void CEncoder::GenerateBitLen(UINT32 maxCode, UINT32 heapMax)
|
||||
// OUT assertion: the field code is set for all tree elements of non
|
||||
// zero code length.
|
||||
|
||||
// UINT32 maxCode = largest code with non zero frequency
|
||||
// UInt32 maxCode = largest code with non zero frequency
|
||||
|
||||
|
||||
void CEncoder::GenerateCodes(UINT32 maxCode)
|
||||
void CEncoder::GenerateCodes(UInt32 maxCode)
|
||||
{
|
||||
UINT32 nextCodes[kNumBitsInLongestCode + 1]; // next code value for each bit length
|
||||
UINT32 code = 0; // running code value
|
||||
UInt32 nextCodes[kNumBitsInLongestCode + 1]; // next code value for each bit length
|
||||
UInt32 code = 0; // running code value
|
||||
// The distribution counts are first used to generate the code values
|
||||
// without bit reversal.
|
||||
for (UINT32 bits = 1; bits <= kNumBitsInLongestCode; bits++)
|
||||
for (UInt32 bits = 1; bits <= kNumBitsInLongestCode; bits++)
|
||||
nextCodes[bits] = code = (code + m_BitLenCounters[bits - 1]) << 1;
|
||||
// Check that the bit counts in m_BitLenCounters are consistent. The last code
|
||||
// must be all ones.
|
||||
if (code + m_BitLenCounters[kNumBitsInLongestCode] - 1 != (1 << kNumBitsInLongestCode) - 1)
|
||||
throw kIncorrectBitLenCountsMessage;
|
||||
for (UINT32 n = 0; n <= maxCode; n++)
|
||||
for (UInt32 n = 0; n <= maxCode; n++)
|
||||
{
|
||||
int len = m_Items[n].Len;
|
||||
if (len == 0)
|
||||
@@ -215,7 +237,7 @@ void CEncoder::GenerateCodes(UINT32 maxCode)
|
||||
// and corresponding code. The length m_BlockBitLength is updated; static_len is
|
||||
// also updated if stree is not null. The field max_code is set.
|
||||
|
||||
void CEncoder::BuildTree(BYTE *levels)
|
||||
void CEncoder::BuildTree(Byte *levels)
|
||||
{
|
||||
m_BlockBitLength = 0;
|
||||
int maxCode = -1; // WAS = -1; largest code with non zero frequency */
|
||||
@@ -226,7 +248,7 @@ void CEncoder::BuildTree(BYTE *levels)
|
||||
//
|
||||
|
||||
m_HeapLength = 0;
|
||||
UINT32 n; // iterate over m_Heap elements
|
||||
UInt32 n; // iterate over m_Heap elements
|
||||
for (n = 0; n < m_NumSymbols; n++)
|
||||
{
|
||||
if (m_Items[n].Freq != 0)
|
||||
@@ -260,18 +282,18 @@ void CEncoder::BuildTree(BYTE *levels)
|
||||
// Construct the Huffman tree by repeatedly combining the least two
|
||||
// frequent nodes.
|
||||
int node = m_NumSymbols; // next internal node of the tree
|
||||
UINT32 heapMax = m_NumSymbols * 2+ 1;
|
||||
UInt32 heapMax = m_NumSymbols * 2+ 1;
|
||||
do
|
||||
{
|
||||
n = RemoveSmallest(); /* n = node of least frequency */
|
||||
UINT32 m = m_Heap[kSmallest]; /* m = node of next least frequency */
|
||||
UInt32 m = m_Heap[kSmallest]; /* m = node of next least frequency */
|
||||
|
||||
m_Heap[--heapMax] = n; /* keep the nodes sorted by frequency */
|
||||
m_Heap[--heapMax] = m;
|
||||
|
||||
// Create a new node father of n and m
|
||||
m_Items[node].Freq = m_Items[n].Freq + m_Items[m].Freq;
|
||||
m_Depth[node] = (BYTE) (MyMax(m_Depth[n], m_Depth[m]) + 1);
|
||||
m_Depth[node] = (Byte) (MyMax(m_Depth[n], m_Depth[m]) + 1);
|
||||
m_Items[n].Dad = m_Items[m].Dad = node;
|
||||
// and insert the new node in the m_Heap
|
||||
m_Heap[kSmallest] = node++;
|
||||
@@ -290,7 +312,7 @@ void CEncoder::BuildTree(BYTE *levels)
|
||||
GenerateCodes (maxCode);
|
||||
|
||||
for (n = 0; n < m_NumSymbols; n++)
|
||||
levels[n] = BYTE(m_Items[n].Len);
|
||||
levels[n] = Byte(m_Items[n].Len);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Compression/HuffmanEncoder.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __COMPRESSION_HUFFMANENCODER_H
|
||||
#define __COMPRESSION_HUFFMANENCODER_H
|
||||
|
||||
@@ -10,54 +8,58 @@
|
||||
namespace NCompression {
|
||||
namespace NHuffman {
|
||||
|
||||
const int kNumBitsInLongestCode = 15;
|
||||
const int kNumBitsInLongestCode = 20;
|
||||
|
||||
struct CItem
|
||||
{
|
||||
UINT32 Freq;
|
||||
UINT32 Code;
|
||||
UINT32 Dad;
|
||||
UINT32 Len;
|
||||
UInt32 Freq;
|
||||
UInt32 Code;
|
||||
UInt32 Dad;
|
||||
UInt32 Len;
|
||||
};
|
||||
|
||||
class CEncoder
|
||||
{
|
||||
UINT32 m_NumSymbols; // number of symbols in adwSymbol
|
||||
public:
|
||||
UInt32 m_NumSymbols; // number of symbols in adwSymbol
|
||||
|
||||
CItem *m_Items;
|
||||
UINT32 *m_Heap;
|
||||
UINT32 m_HeapSize;
|
||||
BYTE *m_Depth;
|
||||
const BYTE *m_ExtraBits;
|
||||
UINT32 m_ExtraBase;
|
||||
UINT32 m_MaxLength;
|
||||
UInt32 *m_Heap;
|
||||
UInt32 m_HeapSize;
|
||||
Byte *m_Depth;
|
||||
const Byte *m_ExtraBits;
|
||||
UInt32 m_ExtraBase;
|
||||
UInt32 m_MaxLength;
|
||||
|
||||
UINT32 m_HeapLength;
|
||||
UINT32 m_BitLenCounters[kNumBitsInLongestCode + 1];
|
||||
UInt32 m_HeapLength;
|
||||
UInt32 m_BitLenCounters[kNumBitsInLongestCode + 1];
|
||||
|
||||
UINT32 RemoveSmallest();
|
||||
UInt32 RemoveSmallest();
|
||||
bool Smaller(int n, int m);
|
||||
void DownHeap(UINT32 k);
|
||||
void GenerateBitLen(UINT32 maxCode, UINT32 heapMax);
|
||||
void GenerateCodes(UINT32 maxCode);
|
||||
void DownHeap(UInt32 k);
|
||||
void GenerateBitLen(UInt32 maxCode, UInt32 heapMax);
|
||||
void GenerateCodes(UInt32 maxCode);
|
||||
|
||||
UINT32 m_BlockBitLength;
|
||||
UInt32 m_BlockBitLength;
|
||||
|
||||
void Free();
|
||||
|
||||
public:
|
||||
|
||||
CEncoder(UINT32 numSymbols, const BYTE *extraBits,
|
||||
UINT32 extraBase, UINT32 maxLength);
|
||||
CEncoder();
|
||||
~CEncoder();
|
||||
bool Create(UInt32 numSymbols, const Byte *extraBits,
|
||||
UInt32 extraBase, UInt32 maxLength);
|
||||
void StartNewBlock();
|
||||
|
||||
void AddSymbol(UINT32 symbol)
|
||||
{ m_Items[symbol].Freq++; }
|
||||
void AddSymbol(UInt32 symbol) { m_Items[symbol].Freq++; }
|
||||
|
||||
void SetFreqs(const UINT32 *freqs);
|
||||
void BuildTree(BYTE *levels);
|
||||
UINT32 GetBlockBitLength() const { return m_BlockBitLength; }
|
||||
void SetFreqs(const UInt32 *freqs);
|
||||
void BuildTree(Byte *levels);
|
||||
UInt32 GetBlockBitLength() const { return m_BlockBitLength; }
|
||||
|
||||
template <class TBitEncoder>
|
||||
void CodeOneValue(TBitEncoder *bitEncoder, UINT32 symbol)
|
||||
void CodeOneValue(TBitEncoder *bitEncoder, UInt32 symbol)
|
||||
{ bitEncoder->WriteBits(m_Items[symbol].Code, m_Items[symbol].Len); }
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user