mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 21:14:58 -06:00
4.44 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
804edc5756
commit
d9666cf046
319
CPP/7zip/Compress/Arj/ArjDecoder1.cpp
Executable file
319
CPP/7zip/Compress/Arj/ArjDecoder1.cpp
Executable file
@@ -0,0 +1,319 @@
|
||||
// Arj/Decoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ArjDecoder1.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
namespace NCompress{
|
||||
namespace NArj {
|
||||
namespace NDecoder1 {
|
||||
|
||||
static const UInt32 kHistorySize = 26624;
|
||||
static const UInt32 kMatchMaxLen = 256;
|
||||
static const UInt32 kMatchMinLen = 3;
|
||||
|
||||
static const UInt32 kNC = 255 + kMatchMaxLen + 2 - kMatchMinLen;
|
||||
|
||||
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;
|
||||
|
||||
for (i = 1; i <= 16; i++)
|
||||
count[i] = 0;
|
||||
for (i = 0; (int)i < nchar; i++)
|
||||
count[bitlen[i]]++;
|
||||
|
||||
start[1] = 0;
|
||||
for (i = 1; i <= 16; i++)
|
||||
start[i + 1] = start[i] + (count[i] << (16 - i));
|
||||
if (start[17] != (UInt32) (1 << 16))
|
||||
throw "Data error";
|
||||
|
||||
jutbits = 16 - tablebits;
|
||||
for (i = 1; (int)i <= tablebits; i++)
|
||||
{
|
||||
start[i] >>= jutbits;
|
||||
weight[i] = 1 << (tablebits - i);
|
||||
}
|
||||
while (i <= 16)
|
||||
{
|
||||
weight[i] = 1 << (16 - i);
|
||||
i++;
|
||||
}
|
||||
|
||||
i = start[tablebits + 1] >> jutbits;
|
||||
if (i != (UInt32) (1 << 16))
|
||||
{
|
||||
k = 1 << tablebits;
|
||||
while (i != k)
|
||||
table[i++] = 0;
|
||||
}
|
||||
|
||||
avail = nchar;
|
||||
mask = 1 << (15 - tablebits);
|
||||
for (ch = 0; (int)ch < nchar; ch++)
|
||||
{
|
||||
if ((len = bitlen[ch]) == 0)
|
||||
continue;
|
||||
k = start[len];
|
||||
nextcode = k + weight[len];
|
||||
if ((int)len <= tablebits)
|
||||
{
|
||||
if (nextcode > (UInt32)tablesize)
|
||||
throw "Data error";
|
||||
for (i = start[len]; i < nextcode; i++)
|
||||
table[i] = ch;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = &table[k >> jutbits];
|
||||
i = len - tablebits;
|
||||
while (i != 0)
|
||||
{
|
||||
if (*p == 0)
|
||||
{
|
||||
right[avail] = left[avail] = 0;
|
||||
*p = avail++;
|
||||
}
|
||||
if (k & mask)
|
||||
p = &right[*p];
|
||||
else
|
||||
p = &left[*p];
|
||||
k <<= 1;
|
||||
i--;
|
||||
}
|
||||
*p = ch;
|
||||
}
|
||||
start[len] = nextcode;
|
||||
}
|
||||
}
|
||||
|
||||
void CCoder::read_pt_len(int nn, int nbit, int i_special)
|
||||
{
|
||||
UInt32 n = m_InBitStream.ReadBits(nbit);
|
||||
if (n == 0)
|
||||
{
|
||||
UInt32 c = m_InBitStream.ReadBits(nbit);
|
||||
int i;
|
||||
for (i = 0; i < nn; i++)
|
||||
pt_len[i] = 0;
|
||||
for (i = 0; i < 256; i++)
|
||||
pt_table[i] = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 i = 0;
|
||||
while (i < n)
|
||||
{
|
||||
UInt32 bitBuf = m_InBitStream.GetValue(16);
|
||||
int c = bitBuf >> 13;
|
||||
if (c == 7)
|
||||
{
|
||||
UInt32 mask = 1 << (12);
|
||||
while (mask & bitBuf)
|
||||
{
|
||||
mask >>= 1;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
m_InBitStream.MovePos((c < 7) ? 3 : (int)(c - 3));
|
||||
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)
|
||||
pt_len[i++] = 0;
|
||||
MakeTable(nn, pt_len, 8, pt_table, PTABLESIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void CCoder::read_c_len()
|
||||
{
|
||||
int i, c, n;
|
||||
UInt32 mask;
|
||||
|
||||
n = m_InBitStream.ReadBits(CBIT);
|
||||
if (n == 0)
|
||||
{
|
||||
c = m_InBitStream.ReadBits(CBIT);
|
||||
for (i = 0; i < NC; i++)
|
||||
c_len[i] = 0;
|
||||
for (i = 0; i < CTABLESIZE; i++)
|
||||
c_table[i] = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 0;
|
||||
while (i < n)
|
||||
{
|
||||
UInt32 bitBuf = m_InBitStream.GetValue(16);
|
||||
c = pt_table[bitBuf >> (8)];
|
||||
if (c >= NT)
|
||||
{
|
||||
mask = 1 << (7);
|
||||
do
|
||||
{
|
||||
if (bitBuf & mask)
|
||||
c = right[c];
|
||||
else
|
||||
c = left[c];
|
||||
mask >>= 1;
|
||||
} while (c >= NT);
|
||||
}
|
||||
m_InBitStream.MovePos((int)(pt_len[c]));
|
||||
if (c <= 2)
|
||||
{
|
||||
if (c == 0)
|
||||
c = 1;
|
||||
else if (c == 1)
|
||||
c = m_InBitStream.ReadBits(4) + 3;
|
||||
else
|
||||
c = m_InBitStream.ReadBits(CBIT) + 20;
|
||||
while (--c >= 0)
|
||||
c_len[i++] = 0;
|
||||
}
|
||||
else
|
||||
c_len[i++] = (Byte)(c - 2);
|
||||
}
|
||||
while (i < NC)
|
||||
c_len[i++] = 0;
|
||||
MakeTable(NC, c_len, 12, c_table, CTABLESIZE);
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 CCoder::decode_c()
|
||||
{
|
||||
UInt32 j, mask;
|
||||
UInt32 bitbuf = m_InBitStream.GetValue(16);
|
||||
j = c_table[bitbuf >> 4];
|
||||
if (j >= NC)
|
||||
{
|
||||
mask = 1 << (3);
|
||||
do
|
||||
{
|
||||
if (bitbuf & mask)
|
||||
j = right[j];
|
||||
else
|
||||
j = left[j];
|
||||
mask >>= 1;
|
||||
} while (j >= NC);
|
||||
}
|
||||
m_InBitStream.MovePos((int)(c_len[j]));
|
||||
return j;
|
||||
}
|
||||
|
||||
UInt32 CCoder::decode_p()
|
||||
{
|
||||
UInt32 j, mask;
|
||||
UInt32 bitbuf = m_InBitStream.GetValue(16);
|
||||
j = pt_table[bitbuf >> (8)];
|
||||
if (j >= NP)
|
||||
{
|
||||
mask = 1 << (7);
|
||||
do
|
||||
{
|
||||
if (bitbuf & mask)
|
||||
j = right[j];
|
||||
else
|
||||
j = left[j];
|
||||
mask >>= 1;
|
||||
} while (j >= NP);
|
||||
}
|
||||
m_InBitStream.MovePos((int)(pt_len[j]));
|
||||
if (j != 0)
|
||||
{
|
||||
j--;
|
||||
j = (1 << j) + m_InBitStream.ReadBits((int)j);
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
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++)
|
||||
{
|
||||
if (i % 100 == 0)
|
||||
c_table[i] = 0;
|
||||
|
||||
c_table[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
UInt64 pos = 0;
|
||||
m_OutWindowStream.SetStream(outStream);
|
||||
m_OutWindowStream.Init(false);
|
||||
m_InBitStream.SetStream(inStream);
|
||||
m_InBitStream.Init();
|
||||
|
||||
CCoderReleaser coderReleaser(this);
|
||||
|
||||
UInt32 blockSize = 0;
|
||||
|
||||
while(pos < *outSize)
|
||||
{
|
||||
if (blockSize == 0)
|
||||
{
|
||||
if (progress != NULL)
|
||||
{
|
||||
UInt64 packSize = m_InBitStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &pos));
|
||||
}
|
||||
blockSize = m_InBitStream.ReadBits(16);
|
||||
read_pt_len(NT, TBIT, 3);
|
||||
read_c_len();
|
||||
read_pt_len(NP, PBIT, -1);
|
||||
}
|
||||
blockSize--;
|
||||
|
||||
UInt32 number = decode_c();
|
||||
if (number < 256)
|
||||
{
|
||||
m_OutWindowStream.PutByte((Byte)number);
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 len = number - 256 + kMatchMinLen;
|
||||
UInt32 distance = decode_p();
|
||||
if (distance >= pos)
|
||||
throw "data error";
|
||||
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,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress);}
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(const CLZOutWindowException &e) { return e.ErrorCode; }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
}}}
|
||||
105
CPP/7zip/Compress/Arj/ArjDecoder1.h
Executable file
105
CPP/7zip/Compress/Arj/ArjDecoder1.h
Executable file
@@ -0,0 +1,105 @@
|
||||
// Arj/Decoder1.h
|
||||
|
||||
#ifndef __COMPRESS_ARJ_DECODER1_H
|
||||
#define __COMPRESS_ARJ_DECODER1_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/MSBFDecoder.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
#include "../LZ/LZOutWindow.h"
|
||||
|
||||
/*
|
||||
// {23170F69-40C1-278B-0404-010000000000}
|
||||
DEFINE_GUID(CLSID_CCompressArjDecoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
*/
|
||||
|
||||
namespace NCompress {
|
||||
namespace NArj {
|
||||
namespace NDecoder1 {
|
||||
|
||||
#define CODE_BIT 16
|
||||
|
||||
#define THRESHOLD 3
|
||||
#define DDICSIZ 26624
|
||||
#define MAXDICBIT 16
|
||||
#define MATCHBIT 8
|
||||
#define MAXMATCH 256
|
||||
#define NC (0xFF + MAXMATCH + 2 - THRESHOLD)
|
||||
#define NP (MAXDICBIT + 1)
|
||||
#define CBIT 9
|
||||
#define NT (CODE_BIT + 3)
|
||||
#define PBIT 5
|
||||
#define TBIT 5
|
||||
|
||||
#if NT > NP
|
||||
#define NPT NT
|
||||
#else
|
||||
#define NPT NP
|
||||
#endif
|
||||
|
||||
#define CTABLESIZE 4096
|
||||
#define PTABLESIZE 256
|
||||
|
||||
|
||||
class CCoder :
|
||||
public ICompressCoder,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
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 c_table[CTABLESIZE];
|
||||
UInt32 pt_table[PTABLESIZE];
|
||||
|
||||
void ReleaseStreams()
|
||||
{
|
||||
m_OutWindowStream.ReleaseStream();
|
||||
m_InBitStream.ReleaseStream();
|
||||
}
|
||||
|
||||
class CCoderReleaser
|
||||
{
|
||||
CCoder *m_Coder;
|
||||
public:
|
||||
bool NeedFlush;
|
||||
CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {}
|
||||
~CCoderReleaser()
|
||||
{
|
||||
if (NeedFlush)
|
||||
m_Coder->m_OutWindowStream.Flush();
|
||||
m_Coder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
friend class CCoderReleaser;
|
||||
|
||||
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();
|
||||
|
||||
public:
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
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);
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
93
CPP/7zip/Compress/Arj/ArjDecoder2.cpp
Executable file
93
CPP/7zip/Compress/Arj/ArjDecoder2.cpp
Executable file
@@ -0,0 +1,93 @@
|
||||
// Arj/Decoder2.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ArjDecoder2.h"
|
||||
|
||||
namespace NCompress{
|
||||
namespace NArj {
|
||||
namespace NDecoder2 {
|
||||
|
||||
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,
|
||||
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;
|
||||
|
||||
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;
|
||||
for (width = kStartWidth; width < kStopWidth; width++)
|
||||
{
|
||||
if (m_InBitStream.ReadBits(1) == 0)
|
||||
break;
|
||||
len += power;
|
||||
power <<= 1;
|
||||
}
|
||||
if (width != 0)
|
||||
len += m_InBitStream.ReadBits(width);
|
||||
if (len == 0)
|
||||
{
|
||||
m_OutWindowStream.PutByte((Byte)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;
|
||||
for (width = kStartWidth; width < kStopWidth; width++)
|
||||
{
|
||||
if (m_InBitStream.ReadBits(1) == 0)
|
||||
break;
|
||||
distance += power;
|
||||
power <<= 1;
|
||||
}
|
||||
if (width != 0)
|
||||
distance += m_InBitStream.ReadBits(width);
|
||||
if (distance >= pos)
|
||||
throw "data error";
|
||||
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,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress);}
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(const CLZOutWindowException &e) { return e.ErrorCode; }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
}}}
|
||||
65
CPP/7zip/Compress/Arj/ArjDecoder2.h
Executable file
65
CPP/7zip/Compress/Arj/ArjDecoder2.h
Executable file
@@ -0,0 +1,65 @@
|
||||
// Arj/Decoder2.h
|
||||
|
||||
#ifndef __COMPRESS_ARJ_DECODER2_H
|
||||
#define __COMPRESS_ARJ_DECODER2_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/MSBFDecoder.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
#include "../LZ/LZOutWindow.h"
|
||||
|
||||
/*
|
||||
// {23170F69-40C1-278B-0404-020000000000}
|
||||
DEFINE_GUID(CLSID_CCompressArj2Decoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
*/
|
||||
|
||||
namespace NCompress {
|
||||
namespace NArj {
|
||||
namespace NDecoder2 {
|
||||
|
||||
class CCoder :
|
||||
public ICompressCoder,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CLZOutWindow m_OutWindowStream;
|
||||
NStream::NMSBF::CDecoder<CInBuffer> m_InBitStream;
|
||||
|
||||
void ReleaseStreams()
|
||||
{
|
||||
m_OutWindowStream.ReleaseStream();
|
||||
m_InBitStream.ReleaseStream();
|
||||
}
|
||||
|
||||
class CCoderReleaser
|
||||
{
|
||||
CCoder *m_Coder;
|
||||
public:
|
||||
bool NeedFlush;
|
||||
CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {}
|
||||
~CCoderReleaser()
|
||||
{
|
||||
if (NeedFlush)
|
||||
m_Coder->m_OutWindowStream.Flush();
|
||||
m_Coder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
friend class CCoderReleaser;
|
||||
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
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);
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
8
CPP/7zip/Compress/Arj/StdAfx.h
Executable file
8
CPP/7zip/Compress/Arj/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
487
CPP/7zip/Compress/BWT/BlockSort.cpp
Executable file
487
CPP/7zip/Compress/BWT/BlockSort.cpp
Executable file
@@ -0,0 +1,487 @@
|
||||
// BlockSort.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "BlockSort.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/Sort.h"
|
||||
}
|
||||
|
||||
// use BLOCK_SORT_EXTERNAL_FLAGS if blockSize > 1M
|
||||
// #define BLOCK_SORT_USE_HEAP_SORT
|
||||
|
||||
#if _MSC_VER >= 1300
|
||||
#define NO_INLINE __declspec(noinline) __fastcall
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
#define NO_INLINE __fastcall
|
||||
#else
|
||||
#define NO_INLINE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Don't change it !!
|
||||
static const int kNumHashBytes = 2;
|
||||
static const UInt32 kNumHashValues = 1 << (kNumHashBytes * 8);
|
||||
|
||||
static const int kNumRefBitsMax = 12; // must be < (kNumHashBytes * 8) = 16
|
||||
static const UInt32 kNumRefsMax = (1 << kNumRefBitsMax);
|
||||
|
||||
#define BS_TEMP_SIZE kNumHashValues
|
||||
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
|
||||
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;
|
||||
|
||||
#else
|
||||
|
||||
const int kNumBitsMax = 20;
|
||||
const UInt32 kIndexMask = (1 << kNumBitsMax) - 1;
|
||||
const int kNumExtraBits = 32 - kNumBitsMax;
|
||||
const int kNumExtra0Bits = kNumExtraBits - 2;
|
||||
const UInt32 kNumExtra0Mask = (1 << kNumExtra0Bits) - 1;
|
||||
|
||||
#define SetFinishedGroupSize(p, size) \
|
||||
{ *(p) |= ((((size) - 1) & kNumExtra0Mask) << kNumBitsMax); \
|
||||
if ((size) > (1 << kNumExtra0Bits)) { \
|
||||
*(p) |= 0x40000000; *((p) + 1) |= ((((size) - 1)>> kNumExtra0Bits) << kNumBitsMax); } } \
|
||||
|
||||
inline void SetGroupSize(UInt32 *p, UInt32 size)
|
||||
{
|
||||
if (--size == 0)
|
||||
return;
|
||||
*p |= 0x80000000 | ((size & kNumExtra0Mask) << kNumBitsMax);
|
||||
if (size >= (1 << kNumExtra0Bits))
|
||||
{
|
||||
*p |= 0x40000000;
|
||||
p[1] |= ((size >> kNumExtra0Bits) << kNumBitsMax);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// SortGroup - is recursive Range-Sort function with HeapSort optimization for small blocks
|
||||
// "range" is not real range. It's only for optimization.
|
||||
// returns: 1 - if there are groups, 0 - no more groups
|
||||
|
||||
UInt32 NO_INLINE SortGroup(UInt32 BlockSize, UInt32 NumSortedBytes, UInt32 groupOffset, UInt32 groupSize, int NumRefBits, UInt32 *Indices
|
||||
#ifndef BLOCK_SORT_USE_HEAP_SORT
|
||||
, UInt32 left, UInt32 range
|
||||
#endif
|
||||
)
|
||||
{
|
||||
UInt32 *ind2 = Indices + groupOffset;
|
||||
if (groupSize <= 1)
|
||||
{
|
||||
/*
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
SetFinishedGroupSize(ind2, 1);
|
||||
#endif
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
UInt32 *Groups = Indices + BlockSize + BS_TEMP_SIZE;
|
||||
if (groupSize <= ((UInt32)1 << NumRefBits)
|
||||
#ifndef BLOCK_SORT_USE_HEAP_SORT
|
||||
&& groupSize <= range
|
||||
#endif
|
||||
)
|
||||
{
|
||||
UInt32 *temp = Indices + BlockSize;
|
||||
UInt32 j;
|
||||
{
|
||||
UInt32 gPrev;
|
||||
UInt32 gRes = 0;
|
||||
{
|
||||
UInt32 sp = ind2[0] + NumSortedBytes;
|
||||
if (sp >= BlockSize) sp -= BlockSize;
|
||||
gPrev = Groups[sp];
|
||||
temp[0] = (gPrev << NumRefBits);
|
||||
}
|
||||
|
||||
for (j = 1; j < groupSize; j++)
|
||||
{
|
||||
UInt32 sp = ind2[j] + NumSortedBytes;
|
||||
if (sp >= BlockSize) sp -= BlockSize;
|
||||
UInt32 g = Groups[sp];
|
||||
temp[j] = (g << NumRefBits) | j;
|
||||
gRes |= (gPrev ^ g);
|
||||
}
|
||||
if (gRes == 0)
|
||||
{
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
SetGroupSize(ind2, groupSize);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
HeapSort(temp, groupSize);
|
||||
const UInt32 mask = ((1 << NumRefBits) - 1);
|
||||
UInt32 thereAreGroups = 0;
|
||||
|
||||
UInt32 group = groupOffset;
|
||||
UInt32 cg = (temp[0] >> NumRefBits);
|
||||
temp[0] = ind2[temp[0] & mask];
|
||||
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
UInt32 *Flags = Groups + BlockSize;
|
||||
#else
|
||||
UInt32 prevGroupStart = 0;
|
||||
#endif
|
||||
|
||||
for (j = 1; j < groupSize; j++)
|
||||
{
|
||||
UInt32 val = temp[j];
|
||||
UInt32 cgCur = (val >> NumRefBits);
|
||||
|
||||
if (cgCur != cg)
|
||||
{
|
||||
cg = cgCur;
|
||||
group = groupOffset + j;
|
||||
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
UInt32 t = group - 1;
|
||||
Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
|
||||
#else
|
||||
SetGroupSize(temp + prevGroupStart, j - prevGroupStart);
|
||||
prevGroupStart = j;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
thereAreGroups = 1;
|
||||
UInt32 ind = ind2[val & mask];
|
||||
temp[j] = ind;
|
||||
Groups[ind] = group;
|
||||
}
|
||||
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
SetGroupSize(temp + prevGroupStart, j - prevGroupStart);
|
||||
#endif
|
||||
|
||||
for (j = 0; j < groupSize; j++)
|
||||
ind2[j] = temp[j];
|
||||
return thereAreGroups;
|
||||
}
|
||||
|
||||
// Check that all strings are in one group (cannot sort)
|
||||
{
|
||||
UInt32 sp = ind2[0] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize;
|
||||
UInt32 group = Groups[sp];
|
||||
UInt32 j;
|
||||
for (j = 1; j < groupSize; j++)
|
||||
{
|
||||
sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize;
|
||||
if (Groups[sp] != group)
|
||||
break;
|
||||
}
|
||||
if (j == groupSize)
|
||||
{
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
SetGroupSize(ind2, groupSize);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BLOCK_SORT_USE_HEAP_SORT
|
||||
//--------------------------------------
|
||||
// Range Sort
|
||||
UInt32 i;
|
||||
UInt32 mid;
|
||||
for (;;)
|
||||
{
|
||||
if (range <= 1)
|
||||
{
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
SetGroupSize(ind2, groupSize);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
mid = left + ((range + 1) >> 1);
|
||||
UInt32 j = groupSize;
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
UInt32 sp = ind2[i] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize;
|
||||
if (Groups[sp] >= mid)
|
||||
{
|
||||
for (j--; j > i; j--)
|
||||
{
|
||||
sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize;
|
||||
if (Groups[sp] < mid)
|
||||
{
|
||||
UInt32 temp = ind2[i]; ind2[i] = ind2[j]; ind2[j] = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= j)
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(++i < j);
|
||||
if (i == 0)
|
||||
{
|
||||
range = range - (mid - left);
|
||||
left = mid;
|
||||
}
|
||||
else if (i == groupSize)
|
||||
range = (mid - left);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
{
|
||||
UInt32 t = (groupOffset + i - 1);
|
||||
UInt32 *Flags = Groups + BlockSize;
|
||||
Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
|
||||
}
|
||||
#endif
|
||||
|
||||
for (UInt32 j = i; j < groupSize; j++)
|
||||
Groups[ind2[j]] = groupOffset + i;
|
||||
|
||||
UInt32 res = SortGroup(BlockSize, NumSortedBytes, groupOffset, i, NumRefBits, Indices, left, mid - left);
|
||||
return res | SortGroup(BlockSize, NumSortedBytes, groupOffset + i, groupSize - i, NumRefBits, Indices, mid, range - (mid - left));
|
||||
|
||||
#else
|
||||
|
||||
//--------------------------------------
|
||||
// Heap Sort
|
||||
|
||||
{
|
||||
UInt32 j;
|
||||
for (j = 0; j < groupSize; j++)
|
||||
{
|
||||
UInt32 sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize;
|
||||
ind2[j] = sp;
|
||||
}
|
||||
|
||||
HeapSortRef(ind2, Groups, groupSize);
|
||||
|
||||
// Write Flags
|
||||
UInt32 sp = ind2[0];
|
||||
UInt32 group = Groups[sp];
|
||||
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
UInt32 *Flags = Groups + BlockSize;
|
||||
#else
|
||||
UInt32 prevGroupStart = 0;
|
||||
#endif
|
||||
|
||||
for (j = 1; j < groupSize; j++)
|
||||
{
|
||||
sp = ind2[j];
|
||||
if (Groups[sp] != group)
|
||||
{
|
||||
group = Groups[sp];
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
UInt32 t = groupOffset + j - 1;
|
||||
Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
|
||||
#else
|
||||
SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart);
|
||||
prevGroupStart = j;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart);
|
||||
#endif
|
||||
|
||||
// Write new Groups values and Check that there are groups
|
||||
UInt32 thereAreGroups = 0;
|
||||
for (j = 0; j < groupSize; j++)
|
||||
{
|
||||
UInt32 group = groupOffset + j;
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
UInt32 subGroupSize = ((ind2[j] & ~0xC0000000) >> kNumBitsMax);
|
||||
if ((ind2[j] & 0x40000000) != 0)
|
||||
subGroupSize += ((ind2[j + 1] >> kNumBitsMax) << kNumExtra0Bits);
|
||||
subGroupSize++;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 original = ind2[j];
|
||||
UInt32 sp = original & kIndexMask;
|
||||
if (sp < NumSortedBytes) sp += BlockSize; sp -= NumSortedBytes;
|
||||
ind2[j] = sp | (original & ~kIndexMask);
|
||||
Groups[sp] = group;
|
||||
if (--subGroupSize == 0)
|
||||
break;
|
||||
j++;
|
||||
thereAreGroups = 1;
|
||||
}
|
||||
#else
|
||||
for (;;)
|
||||
{
|
||||
UInt32 sp = ind2[j]; if (sp < NumSortedBytes) sp += BlockSize; sp -= NumSortedBytes;
|
||||
ind2[j] = sp;
|
||||
Groups[sp] = group;
|
||||
if ((Flags[(groupOffset + j) >> kNumFlagsBits] & (1 << ((groupOffset + j) & kFlagsMask))) == 0)
|
||||
break;
|
||||
j++;
|
||||
thereAreGroups = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return thereAreGroups;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// conditions: blockSize > 0
|
||||
UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
|
||||
{
|
||||
UInt32 *counters = Indices + 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 *Groups = counters + BS_TEMP_SIZE;
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
UInt32 *Flags = Groups + blockSize;
|
||||
{
|
||||
UInt32 numWords = (blockSize + kFlagsMask) >> kNumFlagsBits;
|
||||
for (i = 0; i < numWords; i++)
|
||||
Flags[i] = kAllFlags;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
UInt32 sum = 0;
|
||||
for (i = 0; i < kNumHashValues; i++)
|
||||
{
|
||||
UInt32 groupSize = counters[i];
|
||||
if (groupSize > 0)
|
||||
{
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
UInt32 t = sum + groupSize - 1;
|
||||
Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
|
||||
#endif
|
||||
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;
|
||||
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
UInt32 prev = 0;
|
||||
for (i = 0; i < kNumHashValues; i++)
|
||||
{
|
||||
UInt32 prevGroupSize = counters[i] - prev;
|
||||
if (prevGroupSize == 0)
|
||||
continue;
|
||||
SetGroupSize(Indices + prev, prevGroupSize);
|
||||
prev = counters[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int NumRefBits;
|
||||
for (NumRefBits = 0; ((blockSize - 1) >> NumRefBits) != 0; NumRefBits++);
|
||||
NumRefBits = 32 - NumRefBits;
|
||||
if (NumRefBits > kNumRefBitsMax)
|
||||
NumRefBits = kNumRefBitsMax;
|
||||
|
||||
for (UInt32 NumSortedBytes = kNumHashBytes; ; NumSortedBytes <<= 1)
|
||||
{
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
UInt32 finishedGroupSize = 0;
|
||||
#endif
|
||||
UInt32 newLimit = 0;
|
||||
for (i = 0; i < blockSize;)
|
||||
{
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
|
||||
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++;
|
||||
|
||||
#else
|
||||
|
||||
UInt32 groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax);
|
||||
bool finishedGroup = ((Indices[i] & 0x80000000) == 0);
|
||||
if ((Indices[i] & 0x40000000) != 0)
|
||||
{
|
||||
groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits);
|
||||
Indices[i + 1] &= kIndexMask;
|
||||
}
|
||||
Indices[i] &= kIndexMask;
|
||||
groupSize++;
|
||||
if (finishedGroup || groupSize == 1)
|
||||
{
|
||||
Indices[i - finishedGroupSize] &= kIndexMask;
|
||||
if (finishedGroupSize > 1)
|
||||
Indices[i - finishedGroupSize + 1] &= kIndexMask;
|
||||
UInt32 newGroupSize = groupSize + finishedGroupSize;
|
||||
SetFinishedGroupSize(Indices + i - finishedGroupSize, newGroupSize);
|
||||
finishedGroupSize = newGroupSize;
|
||||
i += groupSize;
|
||||
continue;
|
||||
}
|
||||
finishedGroupSize = 0;
|
||||
|
||||
#endif
|
||||
|
||||
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(blockSize, NumSortedBytes, i, groupSize, NumRefBits, Indices
|
||||
#ifndef BLOCK_SORT_USE_HEAP_SORT
|
||||
, 0, blockSize
|
||||
#endif
|
||||
) != 0)
|
||||
newLimit = i + groupSize;
|
||||
i += groupSize;
|
||||
}
|
||||
if (newLimit == 0)
|
||||
break;
|
||||
}
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
for (i = 0; i < blockSize;)
|
||||
{
|
||||
UInt32 groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax);
|
||||
if ((Indices[i] & 0x40000000) != 0)
|
||||
{
|
||||
groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits);
|
||||
Indices[i + 1] &= kIndexMask;
|
||||
}
|
||||
Indices[i] &= kIndexMask;
|
||||
groupSize++;
|
||||
i += groupSize;
|
||||
}
|
||||
#endif
|
||||
return Groups[0];
|
||||
}
|
||||
|
||||
21
CPP/7zip/Compress/BWT/BlockSort.h
Executable file
21
CPP/7zip/Compress/BWT/BlockSort.h
Executable file
@@ -0,0 +1,21 @@
|
||||
// BlockSort.h
|
||||
|
||||
#ifndef __BLOCKSORT_H
|
||||
#define __BLOCKSORT_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
// use BLOCK_SORT_EXTERNAL_FLAGS if blockSize can be > 1M
|
||||
// #define BLOCK_SORT_EXTERNAL_FLAGS
|
||||
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) ((((blockSize) + 31) >> 5))
|
||||
#else
|
||||
#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) 0
|
||||
#endif
|
||||
|
||||
#define BLOCK_SORT_BUF_SIZE(blockSize) ((blockSize) * 2 + BLOCK_SORT_EXTERNAL_SIZE(blockSize) + (1 << 16))
|
||||
|
||||
UInt32 BlockSort(UInt32 *indices, const Byte *data, UInt32 blockSize);
|
||||
|
||||
#endif
|
||||
195
CPP/7zip/Compress/BWT/Mtf8.h
Executable file
195
CPP/7zip/Compress/BWT/Mtf8.h
Executable file
@@ -0,0 +1,195 @@
|
||||
// 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) {};
|
||||
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;
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
#ifdef _WIN64
|
||||
#define MODE_64BIT
|
||||
#endif
|
||||
|
||||
#ifdef MODE_64BIT
|
||||
typedef UInt64 CMtfVar;
|
||||
#define MTF_MOVS 3
|
||||
#else
|
||||
typedef UInt32 CMtfVar;
|
||||
#define MTF_MOVS 2
|
||||
#endif
|
||||
|
||||
#define MTF_MASK ((1 << MTF_MOVS) - 1)
|
||||
|
||||
|
||||
class CMtf8Decoder
|
||||
{
|
||||
public:
|
||||
CMtfVar Buffer[256 >> MTF_MOVS];
|
||||
void StartInit() { memset(Buffer, 0, sizeof(Buffer)); }
|
||||
void Add(unsigned int pos, Byte val) { Buffer[pos >> MTF_MOVS] |= ((CMtfVar)val << ((pos & MTF_MASK) << 3)); }
|
||||
Byte GetHead() const { return (Byte)Buffer[0]; }
|
||||
Byte GetAndMove(unsigned int pos)
|
||||
{
|
||||
UInt32 lim = ((UInt32)pos >> MTF_MOVS);
|
||||
pos = (pos & MTF_MASK) << 3;
|
||||
CMtfVar prev = (Buffer[lim] >> pos) & 0xFF;
|
||||
|
||||
UInt32 i = 0;
|
||||
if ((lim & 1) != 0)
|
||||
{
|
||||
CMtfVar next = Buffer[0];
|
||||
Buffer[0] = (next << 8) | prev;
|
||||
prev = (next >> (MTF_MASK << 3));
|
||||
i = 1;
|
||||
lim -= 1;
|
||||
}
|
||||
for (; i < lim; i += 2)
|
||||
{
|
||||
CMtfVar next = Buffer[i];
|
||||
Buffer[i] = (next << 8) | prev;
|
||||
prev = (next >> (MTF_MASK << 3));
|
||||
next = Buffer[i + 1];
|
||||
Buffer[i + 1] = (next << 8) | prev;
|
||||
prev = (next >> (MTF_MASK << 3));
|
||||
}
|
||||
CMtfVar next = Buffer[i];
|
||||
CMtfVar mask = (((CMtfVar)0x100 << pos) - 1);
|
||||
Buffer[i] = (next & ~mask) | (((next << 8) | prev) & mask);
|
||||
return (Byte)Buffer[0];
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
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
CPP/7zip/Compress/BWT/StdAfx.h
Executable file
6
CPP/7zip/Compress/BWT/StdAfx.h
Executable file
@@ -0,0 +1,6 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#endif
|
||||
303
CPP/7zip/Compress/BZip2/BZip2.dsp
Executable file
303
CPP/7zip/Compress/BZip2/BZip2.dsp
Executable file
@@ -0,0 +1,303 @@
|
||||
# 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 "NDEBUG" /D "BZ_NO_STDIO" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_BZIP2_MT" /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 "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_BZIP2_MT" /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=..\Codec.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DllExports.cpp
|
||||
# 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 "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 Group "Huffman"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Huffman\HuffmanDecoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.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=..\..\..\..\C\Compress\Huffman\HuffmanEncode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Sort.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=..\..\..\..\C\Sort.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 Group "Windows"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Synchronization.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Synchronization.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Thread.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2Const.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2CRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BZip2CRC.h
|
||||
# End Source File
|
||||
# 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
|
||||
# End Target
|
||||
# End Project
|
||||
29
CPP/7zip/Compress/BZip2/BZip2.dsw
Executable file
29
CPP/7zip/Compress/BZip2/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>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
26
CPP/7zip/Compress/BZip2/BZip2CRC.cpp
Executable file
26
CPP/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_BZip2CRCTableInit;
|
||||
31
CPP/7zip/Compress/BZip2/BZip2CRC.h
Executable file
31
CPP/7zip/Compress/BZip2/BZip2CRC.h
Executable file
@@ -0,0 +1,31 @@
|
||||
// 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); }
|
||||
void UpdateByte(unsigned int 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
CPP/7zip/Compress/BZip2/BZip2Const.h
Executable file
54
CPP/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
|
||||
770
CPP/7zip/Compress/BZip2/BZip2Decoder.cpp
Executable file
770
CPP/7zip/Compress/BZip2/BZip2Decoder.cpp
Executable file
@@ -0,0 +1,770 @@
|
||||
// BZip2Decoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "BZip2Decoder.h"
|
||||
|
||||
#include "../../../Common/Alloc.h"
|
||||
#include "../../../Common/Defs.h"
|
||||
#include "../BWT/Mtf8.h"
|
||||
#include "BZip2CRC.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NBZip2 {
|
||||
|
||||
const UInt32 kNumThreadsMax = 4;
|
||||
|
||||
static const UInt32 kBufferSize = (1 << 17);
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
bool CState::Alloc()
|
||||
{
|
||||
if (Counters == 0)
|
||||
Counters = (UInt32 *)BigAlloc((256 + kBlockSizeMax) * sizeof(UInt32));
|
||||
return (Counters != 0);
|
||||
}
|
||||
|
||||
void CState::Free()
|
||||
{
|
||||
::BigFree(Counters);
|
||||
Counters = 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; }
|
||||
|
||||
UInt32 CDecoder::ReadCRC()
|
||||
{
|
||||
UInt32 crc = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
crc <<= 8;
|
||||
crc |= ReadByte();
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
UInt32 NO_INLINE ReadBits(NStream::NMSBF::CDecoder<CInBuffer> *m_InStream, int num)
|
||||
{
|
||||
return m_InStream->ReadBits(num);
|
||||
}
|
||||
|
||||
UInt32 NO_INLINE ReadBit(NStream::NMSBF::CDecoder<CInBuffer> *m_InStream)
|
||||
{
|
||||
return m_InStream->ReadBits(1);
|
||||
}
|
||||
|
||||
static HRESULT NO_INLINE ReadBlock(NStream::NMSBF::CDecoder<CInBuffer> *m_InStream,
|
||||
UInt32 *CharCounters, UInt32 blockSizeMax, Byte *m_Selectors, CHuffmanDecoder *m_HuffmanDecoders,
|
||||
UInt32 *blockSizeRes, UInt32 *origPtrRes, bool *randRes)
|
||||
{
|
||||
*randRes = ReadBit(m_InStream) ? true : false;
|
||||
*origPtrRes = ReadBits(m_InStream, kNumOrigBits);
|
||||
|
||||
// in original code it compares OrigPtr to (UInt32)(10 + blockSizeMax)) : why ?
|
||||
if (*origPtrRes >= blockSizeMax)
|
||||
return S_FALSE;
|
||||
|
||||
CMtf8Decoder mtf;
|
||||
mtf.StartInit();
|
||||
|
||||
int numInUse = 0;
|
||||
{
|
||||
Byte inUse16[16];
|
||||
int i;
|
||||
for (i = 0; i < 16; i++)
|
||||
inUse16[i] = (Byte)ReadBit(m_InStream);
|
||||
for (i = 0; i < 256; i++)
|
||||
if (inUse16[i >> 4])
|
||||
{
|
||||
if (ReadBit(m_InStream))
|
||||
mtf.Add(numInUse++, (Byte)i);
|
||||
}
|
||||
if (numInUse == 0)
|
||||
return S_FALSE;
|
||||
// mtf.Init(numInUse);
|
||||
}
|
||||
int alphaSize = numInUse + 2;
|
||||
|
||||
int numTables = ReadBits(m_InStream, kNumTablesBits);
|
||||
if (numTables < kNumTablesMin || numTables > kNumTablesMax)
|
||||
return S_FALSE;
|
||||
|
||||
UInt32 numSelectors = ReadBits(m_InStream, kNumSelectorsBits);
|
||||
if (numSelectors < 1 || numSelectors > kNumSelectorsMax)
|
||||
return S_FALSE;
|
||||
|
||||
{
|
||||
Byte mtfPos[kNumTablesMax];
|
||||
int t = 0;
|
||||
do
|
||||
mtfPos[t] = (Byte)t;
|
||||
while(++t < numTables);
|
||||
UInt32 i = 0;
|
||||
do
|
||||
{
|
||||
int j = 0;
|
||||
while (ReadBit(m_InStream))
|
||||
if (++j >= numTables)
|
||||
return S_FALSE;
|
||||
Byte tmp = mtfPos[j];
|
||||
for (;j > 0; j--)
|
||||
mtfPos[j] = mtfPos[j - 1];
|
||||
m_Selectors[i] = mtfPos[0] = tmp;
|
||||
}
|
||||
while(++i < numSelectors);
|
||||
}
|
||||
|
||||
int t = 0;
|
||||
do
|
||||
{
|
||||
Byte lens[kMaxAlphaSize];
|
||||
int len = (int)ReadBits(m_InStream, kNumLevelsBits);
|
||||
int i;
|
||||
for (i = 0; i < alphaSize; i++)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (len < 1 || len > kMaxHuffmanLen)
|
||||
return S_FALSE;
|
||||
if (!ReadBit(m_InStream))
|
||||
break;
|
||||
len += 1 - (int)(ReadBit(m_InStream) << 1);
|
||||
}
|
||||
lens[i] = (Byte)len;
|
||||
}
|
||||
for (; i < kMaxAlphaSize; i++)
|
||||
lens[i] = 0;
|
||||
if(!m_HuffmanDecoders[t].SetCodeLengths(lens))
|
||||
return S_FALSE;
|
||||
}
|
||||
while(++t < numTables);
|
||||
|
||||
{
|
||||
for (int i = 0; i < 256; i++)
|
||||
CharCounters[i] = 0;
|
||||
}
|
||||
|
||||
UInt32 blockSize = 0;
|
||||
{
|
||||
UInt32 groupIndex = 0;
|
||||
UInt32 groupSize = 0;
|
||||
CHuffmanDecoder *huffmanDecoder = 0;
|
||||
int runPower = 0;
|
||||
UInt32 runCounter = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (groupSize == 0)
|
||||
{
|
||||
if (groupIndex >= numSelectors)
|
||||
return S_FALSE;
|
||||
groupSize = kGroupSize;
|
||||
huffmanDecoder = &m_HuffmanDecoders[m_Selectors[groupIndex++]];
|
||||
}
|
||||
groupSize--;
|
||||
|
||||
UInt32 nextSym = huffmanDecoder->DecodeSymbol(m_InStream);
|
||||
|
||||
if (nextSym < 2)
|
||||
{
|
||||
runCounter += ((UInt32)(nextSym + 1) << runPower++);
|
||||
if (blockSizeMax - blockSize < runCounter)
|
||||
return S_FALSE;
|
||||
continue;
|
||||
}
|
||||
if (runCounter != 0)
|
||||
{
|
||||
UInt32 b = (UInt32)mtf.GetHead();
|
||||
CharCounters[b] += runCounter;
|
||||
do
|
||||
CharCounters[256 + blockSize++] = b;
|
||||
while(--runCounter != 0);
|
||||
runPower = 0;
|
||||
}
|
||||
if (nextSym <= (UInt32)numInUse)
|
||||
{
|
||||
UInt32 b = (UInt32)mtf.GetAndMove((int)nextSym - 1);
|
||||
if (blockSize >= blockSizeMax)
|
||||
return S_FALSE;
|
||||
CharCounters[b]++;
|
||||
CharCounters[256 + blockSize++] = b;
|
||||
}
|
||||
else if (nextSym == (UInt32)numInUse + 1)
|
||||
break;
|
||||
else
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
*blockSizeRes = blockSize;
|
||||
return (*origPtrRes < blockSize) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
void NO_INLINE DecodeBlock1(UInt32 *charCounters, UInt32 blockSize)
|
||||
{
|
||||
{
|
||||
UInt32 sum = 0;
|
||||
for (UInt32 i = 0; i < 256; i++)
|
||||
{
|
||||
sum += charCounters[i];
|
||||
charCounters[i] = sum - charCounters[i];
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 *tt = charCounters + 256;
|
||||
// Compute the T^(-1) vector
|
||||
UInt32 i = 0;
|
||||
do
|
||||
tt[charCounters[tt[i] & 0xFF]++] |= (i << 8);
|
||||
while(++i < blockSize);
|
||||
}
|
||||
|
||||
static UInt32 NO_INLINE DecodeBlock2(const UInt32 *tt, UInt32 blockSize, UInt32 OrigPtr, COutBuffer &m_OutStream)
|
||||
{
|
||||
CBZip2CRC crc;
|
||||
|
||||
// it's for speed optimization: prefetch & prevByte_init;
|
||||
UInt32 tPos = tt[tt[OrigPtr] >> 8];
|
||||
unsigned int prevByte = (unsigned int)(tPos & 0xFF);
|
||||
|
||||
int numReps = 0;
|
||||
|
||||
do
|
||||
{
|
||||
unsigned int b = (unsigned int)(tPos & 0xFF);
|
||||
tPos = tt[tPos >> 8];
|
||||
|
||||
if (numReps == kRleModeRepSize)
|
||||
{
|
||||
for (; b > 0; b--)
|
||||
{
|
||||
crc.UpdateByte(prevByte);
|
||||
m_OutStream.WriteByte((Byte)prevByte);
|
||||
}
|
||||
numReps = 0;
|
||||
continue;
|
||||
}
|
||||
if (b != prevByte)
|
||||
numReps = 0;
|
||||
numReps++;
|
||||
prevByte = b;
|
||||
crc.UpdateByte(b);
|
||||
m_OutStream.WriteByte((Byte)b);
|
||||
|
||||
/*
|
||||
prevByte = b;
|
||||
crc.UpdateByte(b);
|
||||
m_OutStream.WriteByte((Byte)b);
|
||||
for (; --blockSize != 0;)
|
||||
{
|
||||
b = (unsigned int)(tPos & 0xFF);
|
||||
tPos = tt[tPos >> 8];
|
||||
crc.UpdateByte(b);
|
||||
m_OutStream.WriteByte((Byte)b);
|
||||
if (b != prevByte)
|
||||
{
|
||||
prevByte = b;
|
||||
continue;
|
||||
}
|
||||
if (--blockSize == 0)
|
||||
break;
|
||||
|
||||
b = (unsigned int)(tPos & 0xFF);
|
||||
tPos = tt[tPos >> 8];
|
||||
crc.UpdateByte(b);
|
||||
m_OutStream.WriteByte((Byte)b);
|
||||
if (b != prevByte)
|
||||
{
|
||||
prevByte = b;
|
||||
continue;
|
||||
}
|
||||
if (--blockSize == 0)
|
||||
break;
|
||||
|
||||
b = (unsigned int)(tPos & 0xFF);
|
||||
tPos = tt[tPos >> 8];
|
||||
crc.UpdateByte(b);
|
||||
m_OutStream.WriteByte((Byte)b);
|
||||
if (b != prevByte)
|
||||
{
|
||||
prevByte = b;
|
||||
continue;
|
||||
}
|
||||
--blockSize;
|
||||
break;
|
||||
}
|
||||
if (blockSize == 0)
|
||||
break;
|
||||
|
||||
b = (unsigned int)(tPos & 0xFF);
|
||||
tPos = tt[tPos >> 8];
|
||||
|
||||
for (; b > 0; b--)
|
||||
{
|
||||
crc.UpdateByte(prevByte);
|
||||
m_OutStream.WriteByte((Byte)prevByte);
|
||||
}
|
||||
*/
|
||||
}
|
||||
while(--blockSize != 0);
|
||||
return crc.GetDigest();
|
||||
}
|
||||
|
||||
static UInt32 NO_INLINE DecodeBlock2Rand(const UInt32 *tt, UInt32 blockSize, UInt32 OrigPtr, COutBuffer &m_OutStream)
|
||||
{
|
||||
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];
|
||||
unsigned int prevByte = (unsigned int)(tPos & 0xFF);
|
||||
|
||||
do
|
||||
{
|
||||
unsigned int b = (unsigned int)(tPos & 0xFF);
|
||||
tPos = tt[tPos >> 8];
|
||||
|
||||
{
|
||||
if (randToGo == 0)
|
||||
{
|
||||
b ^= 1;
|
||||
randToGo = kRandNums[randIndex++];
|
||||
randIndex &= 0x1FF;
|
||||
}
|
||||
randToGo--;
|
||||
}
|
||||
|
||||
if (numReps == kRleModeRepSize)
|
||||
{
|
||||
for (; b > 0; b--)
|
||||
{
|
||||
crc.UpdateByte(prevByte);
|
||||
m_OutStream.WriteByte((Byte)prevByte);
|
||||
}
|
||||
numReps = 0;
|
||||
continue;
|
||||
}
|
||||
if (b != prevByte)
|
||||
numReps = 0;
|
||||
numReps++;
|
||||
prevByte = b;
|
||||
crc.UpdateByte(b);
|
||||
m_OutStream.WriteByte((Byte)b);
|
||||
}
|
||||
while(--blockSize != 0);
|
||||
return crc.GetDigest();
|
||||
}
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
|
||||
static DWORD WINAPI MFThread(void *p) { ((CState *)p)->ThreadFunc(); return 0; }
|
||||
|
||||
CDecoder::CDecoder():
|
||||
m_States(0)
|
||||
{
|
||||
m_NumThreadsPrev = 0;
|
||||
NumThreads = 1;
|
||||
CS.Enter();
|
||||
}
|
||||
|
||||
CDecoder::~CDecoder()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
|
||||
bool CDecoder::Create()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (m_States != 0 && m_NumThreadsPrev == NumThreads)
|
||||
return true;
|
||||
Free();
|
||||
MtMode = (NumThreads > 1);
|
||||
m_NumThreadsPrev = NumThreads;
|
||||
m_States = new CState[NumThreads];
|
||||
if (m_States == 0)
|
||||
return false;
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
for (UInt32 t = 0; t < NumThreads; t++)
|
||||
{
|
||||
CState &ti = m_States[t];
|
||||
ti.Decoder = this;
|
||||
if (MtMode)
|
||||
if (!ti.Thread.Create(MFThread, &ti))
|
||||
{
|
||||
NumThreads = t;
|
||||
Free();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch(...) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDecoder::Free()
|
||||
{
|
||||
if (!m_States)
|
||||
return;
|
||||
CloseThreads = true;
|
||||
CS.Leave();
|
||||
for (UInt32 t = 0; t < NumThreads; t++)
|
||||
{
|
||||
CState &s = m_States[t];
|
||||
if (MtMode)
|
||||
s.Thread.Wait();
|
||||
s.Free();
|
||||
}
|
||||
delete []m_States;
|
||||
m_States = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
HRESULT CDecoder::ReadSignatures(bool &wasFinished, UInt32 &crc)
|
||||
{
|
||||
wasFinished = false;
|
||||
Byte s[6];
|
||||
for (int i = 0; i < 6; i++)
|
||||
s[i] = ReadByte();
|
||||
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;
|
||||
|
||||
wasFinished = true;
|
||||
return (crc == CombinedCRC.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;
|
||||
CombinedCRC.Update(crc);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::DecodeFile(bool &isBZ, ICompressProgressInfo *progress)
|
||||
{
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
Progress = progress;
|
||||
if (!Create())
|
||||
return E_FAIL;
|
||||
for (UInt32 t = 0; t < NumThreads; t++)
|
||||
{
|
||||
CState &s = m_States[t];
|
||||
if (!s.Alloc())
|
||||
return E_OUTOFMEMORY;
|
||||
s.StreamWasFinishedEvent.Reset();
|
||||
s.WaitingWasStartedEvent.Reset();
|
||||
s.CanWriteEvent.Reset();
|
||||
}
|
||||
#else
|
||||
if (!m_States[0].Alloc())
|
||||
return E_OUTOFMEMORY;
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
CombinedCRC.Init();
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
if (MtMode)
|
||||
{
|
||||
NextBlockIndex = 0;
|
||||
StreamWasFinished1 = StreamWasFinished2 = false;
|
||||
CloseThreads = false;
|
||||
CanStartWaitingEvent.Reset();
|
||||
m_States[0].CanWriteEvent.Set();
|
||||
BlockSizeMax = dicSize;
|
||||
Result1 = Result2 = S_OK;
|
||||
CS.Leave();
|
||||
UInt32 t;
|
||||
for (t = 0; t < NumThreads; t++)
|
||||
m_States[t].StreamWasFinishedEvent.Lock();
|
||||
CS.Enter();
|
||||
CanStartWaitingEvent.Set();
|
||||
for (t = 0; t < NumThreads; t++)
|
||||
m_States[t].WaitingWasStartedEvent.Lock();
|
||||
CanStartWaitingEvent.Reset();
|
||||
RINOK(Result2);
|
||||
RINOK(Result1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
CState &state = m_States[0];
|
||||
for (;;)
|
||||
{
|
||||
if (progress)
|
||||
{
|
||||
UInt64 packSize = m_InStream.GetProcessedSize();
|
||||
UInt64 unpackSize = m_OutStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &unpackSize));
|
||||
}
|
||||
bool wasFinished;
|
||||
UInt32 crc;
|
||||
RINOK(ReadSignatures(wasFinished, crc));
|
||||
if (wasFinished)
|
||||
return S_OK;
|
||||
|
||||
UInt32 blockSize, origPtr;
|
||||
bool randMode;
|
||||
RINOK(ReadBlock(&m_InStream, state.Counters, dicSize,
|
||||
m_Selectors, m_HuffmanDecoders,
|
||||
&blockSize, &origPtr, &randMode));
|
||||
DecodeBlock1(state.Counters, blockSize);
|
||||
if ((randMode ?
|
||||
DecodeBlock2Rand(state.Counters + 256, blockSize, origPtr, m_OutStream) :
|
||||
DecodeBlock2(state.Counters + 256, blockSize, origPtr, m_OutStream)) != crc)
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
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,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(const COutBufferException &e) { return e.ErrorCode; }
|
||||
catch(...) { return E_FAIL; }
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
return E_INVALIDARG;
|
||||
*value = m_InStream.GetProcessedSize();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
void CState::FinishStream()
|
||||
{
|
||||
Decoder->StreamWasFinished1 = true;
|
||||
StreamWasFinishedEvent.Set();
|
||||
Decoder->CS.Leave();
|
||||
Decoder->CanStartWaitingEvent.Lock();
|
||||
WaitingWasStartedEvent.Set();
|
||||
}
|
||||
|
||||
void CState::ThreadFunc()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
Decoder->CS.Enter();
|
||||
if (Decoder->CloseThreads)
|
||||
{
|
||||
Decoder->CS.Leave();
|
||||
return;
|
||||
}
|
||||
if (Decoder->StreamWasFinished1)
|
||||
{
|
||||
FinishStream();
|
||||
continue;
|
||||
}
|
||||
HRESULT res = S_OK;
|
||||
|
||||
UInt32 blockIndex = Decoder->NextBlockIndex;
|
||||
UInt32 nextBlockIndex = blockIndex + 1;
|
||||
if (nextBlockIndex == Decoder->NumThreads)
|
||||
nextBlockIndex = 0;
|
||||
Decoder->NextBlockIndex = nextBlockIndex;
|
||||
UInt32 crc;
|
||||
UInt64 packSize;
|
||||
UInt32 blockSize = 0, origPtr = 0;
|
||||
bool randMode = false;
|
||||
|
||||
try
|
||||
{
|
||||
bool wasFinished;
|
||||
res = Decoder->ReadSignatures(wasFinished, crc);
|
||||
if (res != S_OK)
|
||||
{
|
||||
Decoder->Result1 = res;
|
||||
FinishStream();
|
||||
continue;
|
||||
}
|
||||
if (wasFinished)
|
||||
{
|
||||
Decoder->Result1 = res;
|
||||
FinishStream();
|
||||
continue;
|
||||
}
|
||||
|
||||
res = ReadBlock(&Decoder->m_InStream, Counters, Decoder->BlockSizeMax,
|
||||
Decoder->m_Selectors, Decoder->m_HuffmanDecoders,
|
||||
&blockSize, &origPtr, &randMode);
|
||||
if (res != S_OK)
|
||||
{
|
||||
Decoder->Result1 = res;
|
||||
FinishStream();
|
||||
continue;
|
||||
}
|
||||
packSize = Decoder->m_InStream.GetProcessedSize();
|
||||
}
|
||||
catch(const CInBufferException &e) { res = e.ErrorCode; if (res != S_OK) res = E_FAIL; }
|
||||
catch(...) { res = E_FAIL; }
|
||||
if (res != S_OK)
|
||||
{
|
||||
Decoder->Result1 = res;
|
||||
FinishStream();
|
||||
continue;
|
||||
}
|
||||
|
||||
Decoder->CS.Leave();
|
||||
|
||||
DecodeBlock1(Counters, blockSize);
|
||||
|
||||
bool needFinish = true;
|
||||
try
|
||||
{
|
||||
Decoder->m_States[blockIndex].CanWriteEvent.Lock();
|
||||
needFinish = Decoder->StreamWasFinished2;
|
||||
if (!needFinish)
|
||||
{
|
||||
if ((randMode ?
|
||||
DecodeBlock2Rand(Counters + 256, blockSize, origPtr, Decoder->m_OutStream) :
|
||||
DecodeBlock2(Counters + 256, blockSize, origPtr, Decoder->m_OutStream)) == crc)
|
||||
{
|
||||
if (Decoder->Progress)
|
||||
{
|
||||
UInt64 unpackSize = Decoder->m_OutStream.GetProcessedSize();
|
||||
res = Decoder->Progress->SetRatioInfo(&packSize, &unpackSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
res = S_FALSE;
|
||||
}
|
||||
}
|
||||
catch(const COutBufferException &e) { res = e.ErrorCode; if (res != S_OK) res = E_FAIL; }
|
||||
catch(...) { res = E_FAIL; }
|
||||
if (res != S_OK)
|
||||
{
|
||||
Decoder->Result2 = res;
|
||||
Decoder->StreamWasFinished2 = true;
|
||||
}
|
||||
Decoder->m_States[nextBlockIndex].CanWriteEvent.Set();
|
||||
if (res != S_OK || needFinish)
|
||||
{
|
||||
StreamWasFinishedEvent.Set();
|
||||
Decoder->CanStartWaitingEvent.Lock();
|
||||
WaitingWasStartedEvent.Set();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads)
|
||||
{
|
||||
NumThreads = numThreads;
|
||||
if (NumThreads < 1)
|
||||
NumThreads = 1;
|
||||
if (NumThreads > kNumThreadsMax)
|
||||
NumThreads = kNumThreadsMax;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
}}
|
||||
164
CPP/7zip/Compress/BZip2/BZip2Decoder.h
Executable file
164
CPP/7zip/Compress/BZip2/BZip2Decoder.h
Executable file
@@ -0,0 +1,164 @@
|
||||
// Compress/BZip2/Decoder.h
|
||||
|
||||
#ifndef __COMPRESS_BZIP2_DECODER_H
|
||||
#define __COMPRESS_BZIP2_DECODER_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../Common/MSBFDecoder.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
#include "../../Common/OutBuffer.h"
|
||||
#include "../Huffman/HuffmanDecoder.h"
|
||||
#include "BZip2Const.h"
|
||||
#include "BZip2CRC.h"
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
#include "../../../Windows/Thread.h"
|
||||
#include "../../../Windows/Synchronization.h"
|
||||
#endif
|
||||
|
||||
#if _MSC_VER >= 1300
|
||||
#define NO_INLINE __declspec(noinline) __fastcall
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
#define NO_INLINE __fastcall
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace NCompress {
|
||||
namespace NBZip2 {
|
||||
|
||||
typedef NCompress::NHuffman::CDecoder<kMaxHuffmanLen, kMaxAlphaSize> CHuffmanDecoder;
|
||||
|
||||
class CDecoder;
|
||||
|
||||
struct CState
|
||||
{
|
||||
UInt32 *Counters;
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
|
||||
CDecoder *Decoder;
|
||||
NWindows::CThread Thread;
|
||||
bool m_OptimizeNumTables;
|
||||
|
||||
NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent;
|
||||
NWindows::NSynchronization::CAutoResetEvent WaitingWasStartedEvent;
|
||||
|
||||
// it's not member of this thread. We just need one event per thread
|
||||
NWindows::NSynchronization::CAutoResetEvent CanWriteEvent;
|
||||
|
||||
Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
|
||||
|
||||
void FinishStream();
|
||||
void ThreadFunc();
|
||||
|
||||
#endif
|
||||
|
||||
CState(): Counters(0) {}
|
||||
~CState() { Free(); }
|
||||
bool Alloc();
|
||||
void Free();
|
||||
};
|
||||
|
||||
class CDecoder :
|
||||
public ICompressCoder,
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
public ICompressSetCoderMt,
|
||||
#endif
|
||||
public ICompressGetInStreamProcessedSize,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
COutBuffer m_OutStream;
|
||||
Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
|
||||
NStream::NMSBF::CDecoder<CInBuffer> m_InStream;
|
||||
Byte m_Selectors[kNumSelectorsMax];
|
||||
CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax];
|
||||
private:
|
||||
|
||||
UInt32 m_NumThreadsPrev;
|
||||
|
||||
UInt32 ReadBits(int numBits);
|
||||
Byte ReadByte();
|
||||
bool ReadBit();
|
||||
UInt32 ReadCRC();
|
||||
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:
|
||||
CBZip2CombinedCRC CombinedCRC;
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
ICompressProgressInfo *Progress;
|
||||
CState *m_States;
|
||||
|
||||
NWindows::NSynchronization::CCriticalSection CS;
|
||||
UInt32 NumThreads;
|
||||
bool MtMode;
|
||||
UInt32 NextBlockIndex;
|
||||
bool CloseThreads;
|
||||
bool StreamWasFinished1;
|
||||
bool StreamWasFinished2;
|
||||
NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent;
|
||||
|
||||
HRESULT Result1;
|
||||
HRESULT Result2;
|
||||
|
||||
UInt32 BlockSizeMax;
|
||||
CDecoder();
|
||||
~CDecoder();
|
||||
bool Create();
|
||||
void Free();
|
||||
|
||||
#else
|
||||
CState m_States[1];
|
||||
#endif
|
||||
|
||||
HRESULT ReadSignatures(bool &wasFinished, UInt32 &crc);
|
||||
|
||||
|
||||
HRESULT Flush() { return m_OutStream.Flush(); }
|
||||
void ReleaseStreams()
|
||||
{
|
||||
m_InStream.ReleaseStream();
|
||||
m_OutStream.ReleaseStream();
|
||||
}
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
MY_UNKNOWN_IMP2(ICompressSetCoderMt, ICompressGetInStreamProcessedSize)
|
||||
#else
|
||||
MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
|
||||
#endif
|
||||
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
|
||||
#endif
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
883
CPP/7zip/Compress/BZip2/BZip2Encoder.cpp
Executable file
883
CPP/7zip/Compress/BZip2/BZip2Encoder.cpp
Executable file
@@ -0,0 +1,883 @@
|
||||
// BZip2Encoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/Alloc.h"
|
||||
|
||||
#include "BZip2Encoder.h"
|
||||
|
||||
#include "../BWT/BlockSort.h"
|
||||
#include "../BWT/Mtf8.h"
|
||||
#include "BZip2CRC.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/Compress/Huffman/HuffmanEncode.h"
|
||||
}
|
||||
|
||||
namespace NCompress {
|
||||
namespace NBZip2 {
|
||||
|
||||
const int kMaxHuffmanLenForEncoding = 16; // it must be < kMaxHuffmanLen = 20
|
||||
|
||||
static const UInt32 kBufferSize = (1 << 17);
|
||||
static const int kNumHuffPasses = 4;
|
||||
|
||||
bool CThreadInfo::Create()
|
||||
{
|
||||
if (m_BlockSorterIndex != 0)
|
||||
return true;
|
||||
m_BlockSorterIndex = (UInt32 *)::BigAlloc(BLOCK_SORT_BUF_SIZE(kBlockSizeMax) * sizeof(UInt32));
|
||||
if (m_BlockSorterIndex == 0)
|
||||
return false;
|
||||
|
||||
|
||||
if (m_Block == 0)
|
||||
{
|
||||
m_Block = (Byte *)::MidAlloc(kBlockSizeMax * 5 + kBlockSizeMax / 10 + (20 << 10));
|
||||
if (m_Block == 0)
|
||||
return false;
|
||||
m_MtfArray = m_Block + kBlockSizeMax;
|
||||
m_TempArray = m_MtfArray + kBlockSizeMax * 2 + 2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CThreadInfo::Free()
|
||||
{
|
||||
::BigFree(m_BlockSorterIndex);
|
||||
m_BlockSorterIndex = 0;
|
||||
::MidFree(m_Block);
|
||||
m_Block = 0;
|
||||
}
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
void CThreadInfo::FinishStream(bool needLeave)
|
||||
{
|
||||
Encoder->StreamWasFinished = true;
|
||||
StreamWasFinishedEvent.Set();
|
||||
if (needLeave)
|
||||
Encoder->CS.Leave();
|
||||
Encoder->CanStartWaitingEvent.Lock();
|
||||
WaitingWasStartedEvent.Set();
|
||||
}
|
||||
|
||||
DWORD CThreadInfo::ThreadFunc()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
Encoder->CS.Enter();
|
||||
if (Encoder->CloseThreads)
|
||||
{
|
||||
Encoder->CS.Leave();
|
||||
return 0;
|
||||
}
|
||||
if (Encoder->StreamWasFinished)
|
||||
{
|
||||
FinishStream(true);
|
||||
continue;
|
||||
}
|
||||
HRESULT res = S_OK;
|
||||
bool needLeave = true;
|
||||
try
|
||||
{
|
||||
UInt32 blockSize = Encoder->ReadRleBlock(m_Block);
|
||||
m_PackSize = Encoder->m_InStream.GetProcessedSize();
|
||||
m_BlockIndex = Encoder->NextBlockIndex;
|
||||
if (++Encoder->NextBlockIndex == Encoder->NumThreads)
|
||||
Encoder->NextBlockIndex = 0;
|
||||
if (blockSize == 0)
|
||||
{
|
||||
FinishStream(true);
|
||||
continue;
|
||||
}
|
||||
Encoder->CS.Leave();
|
||||
needLeave = false;
|
||||
res = EncodeBlock3(blockSize);
|
||||
}
|
||||
catch(const CInBufferException &e) { res = e.ErrorCode; }
|
||||
catch(const COutBufferException &e) { res = e.ErrorCode; }
|
||||
catch(...) { res = E_FAIL; }
|
||||
if (res != S_OK)
|
||||
{
|
||||
Encoder->Result = res;
|
||||
FinishStream(needLeave);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static DWORD WINAPI MFThread(void *threadCoderInfo)
|
||||
{
|
||||
return ((CThreadInfo *)threadCoderInfo)->ThreadFunc();
|
||||
}
|
||||
#endif
|
||||
|
||||
CEncoder::CEncoder():
|
||||
NumPasses(1),
|
||||
m_OptimizeNumTables(false),
|
||||
m_BlockSizeMult(kBlockSizeMultMax)
|
||||
{
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
ThreadsInfo = 0;
|
||||
m_NumThreadsPrev = 0;
|
||||
NumThreads = 1;
|
||||
CS.Enter();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
CEncoder::~CEncoder()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
|
||||
bool CEncoder::Create()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ThreadsInfo != 0 && m_NumThreadsPrev == NumThreads)
|
||||
return true;
|
||||
Free();
|
||||
MtMode = (NumThreads > 1);
|
||||
m_NumThreadsPrev = NumThreads;
|
||||
ThreadsInfo = new CThreadInfo[NumThreads];
|
||||
if (ThreadsInfo == 0)
|
||||
return false;
|
||||
for (UInt32 t = 0; t < NumThreads; t++)
|
||||
{
|
||||
CThreadInfo &ti = ThreadsInfo[t];
|
||||
ti.Encoder = this;
|
||||
if (MtMode)
|
||||
if (!ti.Thread.Create(MFThread, &ti))
|
||||
{
|
||||
NumThreads = t;
|
||||
Free();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(...) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
void CEncoder::Free()
|
||||
{
|
||||
if (!ThreadsInfo)
|
||||
return;
|
||||
CloseThreads = true;
|
||||
CS.Leave();
|
||||
for (UInt32 t = 0; t < NumThreads; t++)
|
||||
{
|
||||
CThreadInfo &ti = ThreadsInfo[t];
|
||||
if (MtMode)
|
||||
ti.Thread.Wait();
|
||||
ti.Free();
|
||||
}
|
||||
delete []ThreadsInfo;
|
||||
ThreadsInfo = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
UInt32 CEncoder::ReadRleBlock(Byte *buffer)
|
||||
{
|
||||
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++] = (Byte)(numReps - kRleModeRepSize);
|
||||
buffer[i++] = b;
|
||||
numReps = 1;
|
||||
prevByte = b;
|
||||
continue;
|
||||
}
|
||||
numReps++;
|
||||
if (numReps <= kRleModeRepSize)
|
||||
buffer[i++] = b;
|
||||
else if (numReps == kRleModeRepSize + 255)
|
||||
{
|
||||
buffer[i++] = (Byte)(numReps - kRleModeRepSize);
|
||||
numReps = 0;
|
||||
}
|
||||
}
|
||||
// it's to support original BZip2 decoder
|
||||
if (numReps >= kRleModeRepSize)
|
||||
buffer[i++] = (Byte)(numReps - kRleModeRepSize);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
void CThreadInfo::WriteBits2(UInt32 value, UInt32 numBits)
|
||||
{ m_OutStreamCurrent->WriteBits(value, numBits); }
|
||||
void CThreadInfo::WriteByte2(Byte b) { WriteBits2(b , 8); }
|
||||
void CThreadInfo::WriteBit2(bool v) { WriteBits2((v ? 1 : 0), 1); }
|
||||
void CThreadInfo::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 CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize)
|
||||
{
|
||||
WriteBit2(false); // Randomised = false
|
||||
|
||||
{
|
||||
UInt32 origPtr = BlockSort(m_BlockSorterIndex, block, blockSize);
|
||||
// if (m_BlockSorterIndex[origPtr] != 0) throw 1;
|
||||
m_BlockSorterIndex[origPtr] = 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;
|
||||
|
||||
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;
|
||||
const UInt32 *bsIndex = m_BlockSorterIndex;
|
||||
block--;
|
||||
do
|
||||
{
|
||||
int pos = mtf.FindAndMove(block[bsIndex[i]]);
|
||||
if (pos == 0)
|
||||
rleSize++;
|
||||
else
|
||||
{
|
||||
while (rleSize != 0)
|
||||
{
|
||||
rleSize--;
|
||||
mtfs[mtfArraySize++] = (Byte)(rleSize & 1);
|
||||
symbolCounts[rleSize & 1]++;
|
||||
rleSize >>= 1;
|
||||
}
|
||||
if (pos >= 0xFE)
|
||||
{
|
||||
mtfs[mtfArraySize++] = 0xFF;
|
||||
mtfs[mtfArraySize++] = (Byte)(pos - 0xFE);
|
||||
}
|
||||
else
|
||||
mtfs[mtfArraySize++] = (Byte)(pos + 1);
|
||||
symbolCounts[pos + 1]++;
|
||||
}
|
||||
}
|
||||
while (++i < blockSize);
|
||||
|
||||
while (rleSize != 0)
|
||||
{
|
||||
rleSize--;
|
||||
mtfs[mtfArraySize++] = (Byte)(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();
|
||||
Byte 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];
|
||||
|
||||
Byte *lens = Lens[t - 1];
|
||||
int i = 0;
|
||||
do
|
||||
lens[i] = (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
|
||||
memset(Freqs[t], 0, sizeof(Freqs[t]));
|
||||
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
|
||||
{
|
||||
const Byte *lens = Lens[t];
|
||||
UInt32 price = 0;
|
||||
int j = 0;
|
||||
do
|
||||
price += lens[symbols[j]];
|
||||
while (++j < i);
|
||||
if (price < bestPrice)
|
||||
{
|
||||
m_Selectors[g] = (Byte)t;
|
||||
bestPrice = price;
|
||||
}
|
||||
}
|
||||
while(++t < numTables);
|
||||
UInt32 *freqs = Freqs[m_Selectors[g++]];
|
||||
int j = 0;
|
||||
do
|
||||
freqs[symbols[j]]++;
|
||||
while (++j < i);
|
||||
}
|
||||
while (mtfPos < mtfArraySize);
|
||||
}
|
||||
|
||||
int t = 0;
|
||||
do
|
||||
{
|
||||
UInt32 *freqs = Freqs[t];
|
||||
int i = 0;
|
||||
do
|
||||
if (freqs[i] == 0)
|
||||
freqs[i] = 1;
|
||||
while(++i < alphaSize);
|
||||
Huffman_Generate(freqs, Codes[t], Lens[t], kMaxAlphaSize, kMaxHuffmanLenForEncoding);
|
||||
}
|
||||
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
|
||||
{
|
||||
const Byte *lens = Lens[t];
|
||||
UInt32 len = lens[0];
|
||||
WriteBits2(len, kNumLevelsBits);
|
||||
int i = 0;
|
||||
do
|
||||
{
|
||||
UInt32 level = lens[i];
|
||||
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;
|
||||
const Byte *lens = 0;
|
||||
const UInt32 *codes = 0;
|
||||
UInt32 mtfPos = 0;
|
||||
do
|
||||
{
|
||||
UInt32 symbol = mtfs[mtfPos++];
|
||||
if (symbol >= 0xFF)
|
||||
symbol += mtfs[mtfPos++];
|
||||
if (groupSize == 0)
|
||||
{
|
||||
groupSize = kGroupSize;
|
||||
int t = m_Selectors[groupIndex++];
|
||||
lens = Lens[t];
|
||||
codes = Codes[t];
|
||||
}
|
||||
groupSize--;
|
||||
m_OutStreamCurrent->WriteBits(codes[symbol], lens[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 CThreadInfo::EncodeBlockWithHeaders(const 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 CThreadInfo::EncodeBlock2(const Byte *block, UInt32 blockSize, UInt32 numPasses)
|
||||
{
|
||||
UInt32 numCrcs = m_NumCrcs;
|
||||
bool needCompare = false;
|
||||
|
||||
UInt32 startBytePos = m_OutStreamCurrent->GetBytePos();
|
||||
UInt32 startPos = m_OutStreamCurrent->GetPos();
|
||||
Byte startCurByte = m_OutStreamCurrent->GetCurByte();
|
||||
Byte endCurByte = 0;
|
||||
UInt32 endPos = 0;
|
||||
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(block, blockSize0, numPasses - 1);
|
||||
EncodeBlock2(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();
|
||||
|
||||
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);
|
||||
m_NumCrcs = numCrcs;
|
||||
m_CRCs[m_NumCrcs++] = crcVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_OutStreamCurrent->SetPos(endPos);
|
||||
m_OutStreamCurrent->SetCurState((endPos & 7), endCurByte);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_NumCrcs = numCrcs;
|
||||
m_CRCs[m_NumCrcs++] = crcVal;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CThreadInfo::EncodeBlock3(UInt32 blockSize)
|
||||
{
|
||||
CMsbfEncoderTemp outStreamTemp;
|
||||
outStreamTemp.SetStream(m_TempArray);
|
||||
outStreamTemp.Init();
|
||||
m_OutStreamCurrent = &outStreamTemp;
|
||||
|
||||
m_NumCrcs = 0;
|
||||
|
||||
EncodeBlock2(m_Block, blockSize, Encoder->NumPasses);
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
if (Encoder->MtMode)
|
||||
Encoder->ThreadsInfo[m_BlockIndex].CanWriteEvent.Lock();
|
||||
#endif
|
||||
for (UInt32 i = 0; i < m_NumCrcs; i++)
|
||||
Encoder->CombinedCRC.Update(m_CRCs[i]);
|
||||
Encoder->WriteBytes(m_TempArray, outStreamTemp.GetPos(), outStreamTemp.GetCurByte());
|
||||
HRESULT res = S_OK;
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
if (Encoder->MtMode)
|
||||
{
|
||||
UInt32 blockIndex = m_BlockIndex + 1;
|
||||
if (blockIndex == Encoder->NumThreads)
|
||||
blockIndex = 0;
|
||||
|
||||
if (Encoder->Progress)
|
||||
{
|
||||
UInt64 unpackSize = Encoder->m_OutStream.GetProcessedSize();
|
||||
res = Encoder->Progress->SetRatioInfo(&m_PackSize, &unpackSize);
|
||||
}
|
||||
|
||||
Encoder->ThreadsInfo[blockIndex].CanWriteEvent.Set();
|
||||
}
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
void CEncoder::WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte)
|
||||
{
|
||||
UInt32 bytesSize = (sizeInBits / 8);
|
||||
for (UInt32 i = 0; i < bytesSize; i++)
|
||||
m_OutStream.WriteBits(data[i], 8);
|
||||
WriteBits(lastByte, (sizeInBits & 7));
|
||||
}
|
||||
|
||||
|
||||
HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 * /* outSize */,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
Progress = progress;
|
||||
if (!Create())
|
||||
return E_FAIL;
|
||||
for (UInt32 t = 0; t < NumThreads; t++)
|
||||
#endif
|
||||
{
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
CThreadInfo &ti = ThreadsInfo[t];
|
||||
ti.StreamWasFinishedEvent.Reset();
|
||||
ti.WaitingWasStartedEvent.Reset();
|
||||
ti.CanWriteEvent.Reset();
|
||||
#else
|
||||
CThreadInfo &ti = ThreadsInfo;
|
||||
ti.Encoder = this;
|
||||
#endif
|
||||
|
||||
ti.m_OptimizeNumTables = m_OptimizeNumTables;
|
||||
|
||||
if (!ti.Create())
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
|
||||
CFlusher flusher(this);
|
||||
|
||||
CombinedCRC.Init();
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
NextBlockIndex = 0;
|
||||
StreamWasFinished = false;
|
||||
CloseThreads = false;
|
||||
CanStartWaitingEvent.Reset();
|
||||
#endif
|
||||
|
||||
WriteByte(kArSig0);
|
||||
WriteByte(kArSig1);
|
||||
WriteByte(kArSig2);
|
||||
WriteByte((Byte)(kArSig3 + m_BlockSizeMult));
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
|
||||
if (MtMode)
|
||||
{
|
||||
ThreadsInfo[0].CanWriteEvent.Set();
|
||||
Result = S_OK;
|
||||
CS.Leave();
|
||||
UInt32 t;
|
||||
for (t = 0; t < NumThreads; t++)
|
||||
ThreadsInfo[t].StreamWasFinishedEvent.Lock();
|
||||
CS.Enter();
|
||||
CanStartWaitingEvent.Set();
|
||||
for (t = 0; t < NumThreads; t++)
|
||||
ThreadsInfo[t].WaitingWasStartedEvent.Lock();
|
||||
CanStartWaitingEvent.Reset();
|
||||
RINOK(Result);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
CThreadInfo &ti =
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
ThreadsInfo[0];
|
||||
#else
|
||||
ThreadsInfo;
|
||||
#endif
|
||||
UInt32 blockSize = ReadRleBlock(ti.m_Block);
|
||||
if (blockSize == 0)
|
||||
break;
|
||||
RINOK(ti.EncodeBlock3(blockSize));
|
||||
if (progress)
|
||||
{
|
||||
UInt64 packSize = m_InStream.GetProcessedSize();
|
||||
UInt64 unpackSize = m_OutStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &unpackSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
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(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(const COutBufferException &e) { return e.ErrorCode; }
|
||||
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 = 1;
|
||||
if (numPasses > kNumPassesMax)
|
||||
numPasses = kNumPassesMax;
|
||||
NumPasses = numPasses;
|
||||
m_OptimizeNumTables = (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;
|
||||
}
|
||||
case NCoderPropID::kNumThreads:
|
||||
{
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
if (property.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
NumThreads = property.ulVal;
|
||||
if (NumThreads < 1)
|
||||
NumThreads = 1;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
STDMETHODIMP CEncoder::SetNumberOfThreads(UInt32 numThreads)
|
||||
{
|
||||
NumThreads = numThreads;
|
||||
if (NumThreads < 1)
|
||||
NumThreads = 1;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
}}
|
||||
246
CPP/7zip/Compress/BZip2/BZip2Encoder.h
Executable file
246
CPP/7zip/Compress/BZip2/BZip2Encoder.h
Executable file
@@ -0,0 +1,246 @@
|
||||
// Compress/BZip2/Encoder.h
|
||||
|
||||
#ifndef __COMPRESS_BZIP2_ENCODER_H
|
||||
#define __COMPRESS_BZIP2_ENCODER_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../Common/MSBFEncoder.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
#include "../../Common/OutBuffer.h"
|
||||
#include "BZip2Const.h"
|
||||
#include "BZip2CRC.h"
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
#include "../../../Windows/Thread.h"
|
||||
#include "../../../Windows/Synchronization.h"
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
const int kNumPassesMax = 10;
|
||||
|
||||
class CThreadInfo
|
||||
{
|
||||
public:
|
||||
Byte *m_Block;
|
||||
private:
|
||||
Byte *m_MtfArray;
|
||||
Byte *m_TempArray;
|
||||
UInt32 *m_BlockSorterIndex;
|
||||
|
||||
CMsbfEncoderTemp *m_OutStreamCurrent;
|
||||
|
||||
Byte Lens[kNumTablesMax][kMaxAlphaSize];
|
||||
UInt32 Freqs[kNumTablesMax][kMaxAlphaSize];
|
||||
UInt32 Codes[kNumTablesMax][kMaxAlphaSize];
|
||||
|
||||
Byte m_Selectors[kNumSelectorsMax];
|
||||
|
||||
UInt32 m_CRCs[1 << kNumPassesMax];
|
||||
UInt32 m_NumCrcs;
|
||||
|
||||
int m_BlockIndex;
|
||||
|
||||
void FinishStream(bool needLeave);
|
||||
|
||||
void WriteBits2(UInt32 value, UInt32 numBits);
|
||||
void WriteByte2(Byte b);
|
||||
void WriteBit2(bool v);
|
||||
void WriteCRC2(UInt32 v);
|
||||
|
||||
void EncodeBlock(const Byte *block, UInt32 blockSize);
|
||||
UInt32 EncodeBlockWithHeaders(const Byte *block, UInt32 blockSize);
|
||||
void EncodeBlock2(const Byte *block, UInt32 blockSize, UInt32 numPasses);
|
||||
public:
|
||||
bool m_OptimizeNumTables;
|
||||
CEncoder *Encoder;
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
NWindows::CThread Thread;
|
||||
|
||||
NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent;
|
||||
NWindows::NSynchronization::CAutoResetEvent WaitingWasStartedEvent;
|
||||
|
||||
// it's not member of this thread. We just need one event per thread
|
||||
NWindows::NSynchronization::CAutoResetEvent CanWriteEvent;
|
||||
|
||||
UInt64 m_PackSize;
|
||||
|
||||
Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
|
||||
#endif
|
||||
|
||||
CThreadInfo(): m_BlockSorterIndex(0), m_Block(0) {}
|
||||
~CThreadInfo() { Free(); }
|
||||
bool Create();
|
||||
void Free();
|
||||
|
||||
HRESULT EncodeBlock3(UInt32 blockSize);
|
||||
DWORD ThreadFunc();
|
||||
};
|
||||
|
||||
class CEncoder :
|
||||
public ICompressCoder,
|
||||
public ICompressSetCoderProperties,
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
public ICompressSetCoderMt,
|
||||
#endif
|
||||
public CMyUnknownImp
|
||||
{
|
||||
UInt32 m_BlockSizeMult;
|
||||
bool m_OptimizeNumTables;
|
||||
|
||||
UInt32 m_NumPassesPrev;
|
||||
|
||||
UInt32 m_NumThreadsPrev;
|
||||
public:
|
||||
CInBuffer m_InStream;
|
||||
Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
|
||||
NStream::NMSBF::CEncoder<COutBuffer> m_OutStream;
|
||||
UInt32 NumPasses;
|
||||
CBZip2CombinedCRC CombinedCRC;
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
CThreadInfo *ThreadsInfo;
|
||||
NWindows::NSynchronization::CCriticalSection CS;
|
||||
UInt32 NumThreads;
|
||||
bool MtMode;
|
||||
UInt32 NextBlockIndex;
|
||||
|
||||
bool CloseThreads;
|
||||
bool StreamWasFinished;
|
||||
NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent;
|
||||
|
||||
HRESULT Result;
|
||||
ICompressProgressInfo *Progress;
|
||||
#else
|
||||
CThreadInfo ThreadsInfo;
|
||||
#endif
|
||||
|
||||
UInt32 ReadRleBlock(Byte *buffer);
|
||||
void WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte);
|
||||
|
||||
void WriteBits(UInt32 value, UInt32 numBits);
|
||||
void WriteByte(Byte b);
|
||||
void WriteBit(bool v);
|
||||
void WriteCRC(UInt32 v);
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
bool Create();
|
||||
void Free();
|
||||
#endif
|
||||
|
||||
public:
|
||||
CEncoder();
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
~CEncoder();
|
||||
#endif
|
||||
|
||||
HRESULT Flush() { return m_OutStream.Flush(); }
|
||||
|
||||
void ReleaseStreams()
|
||||
{
|
||||
m_InStream.ReleaseStream();
|
||||
m_OutStream.ReleaseStream();
|
||||
}
|
||||
|
||||
class CFlusher
|
||||
{
|
||||
CEncoder *_coder;
|
||||
public:
|
||||
bool NeedFlush;
|
||||
CFlusher(CEncoder *coder): _coder(coder), NeedFlush(true) {}
|
||||
~CFlusher()
|
||||
{
|
||||
if (NeedFlush)
|
||||
_coder->Flush();
|
||||
_coder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
MY_UNKNOWN_IMP2(ICompressSetCoderMt, ICompressSetCoderProperties)
|
||||
#else
|
||||
MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
|
||||
#endif
|
||||
|
||||
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,
|
||||
ICompressProgressInfo *progress);
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties);
|
||||
|
||||
#ifdef COMPRESS_BZIP2_MT
|
||||
STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
|
||||
#endif
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
93
CPP/7zip/Compress/BZip2/DllExports.cpp
Executable file
93
CPP/7zip/Compress/BZip2/DllExports.cpp
Executable file
@@ -0,0 +1,93 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
#ifdef _WIN32
|
||||
#include "Common/Alloc.h"
|
||||
#endif
|
||||
|
||||
#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*/)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (dwReason == DLL_PROCESS_ATTACH)
|
||||
SetLargePageSize();
|
||||
#endif
|
||||
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
CPP/7zip/Compress/BZip2/StdAfx.cpp
Executable file
3
CPP/7zip/Compress/BZip2/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
8
CPP/7zip/Compress/BZip2/StdAfx.h
Executable file
8
CPP/7zip/Compress/BZip2/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
56
CPP/7zip/Compress/BZip2/makefile
Executable file
56
CPP/7zip/Compress/BZip2/makefile
Executable file
@@ -0,0 +1,56 @@
|
||||
PROG = BZip2.dll
|
||||
DEF_FILE = ../Codec.def
|
||||
CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_BZIP2_MT
|
||||
LIBS = $(LIBS) oleaut32.lib
|
||||
|
||||
BZIP2_OBJS = \
|
||||
$O\DllExports.obj \
|
||||
$O\BZip2CRC.obj \
|
||||
|
||||
BZIP2_OPT_OBJS = \
|
||||
$O\BZip2Decoder.obj \
|
||||
$O\BZip2Encoder.obj \
|
||||
|
||||
COMMON_OBJS = \
|
||||
$O\Alloc.obj \
|
||||
|
||||
WIN_OBJS = \
|
||||
$O\Synchronization.obj
|
||||
|
||||
7ZIP_COMMON_OBJS = \
|
||||
$O\InBuffer.obj \
|
||||
$O\OutBuffer.obj \
|
||||
|
||||
C_OBJS = \
|
||||
$O\Sort.obj \
|
||||
|
||||
OBJS = \
|
||||
$O\StdAfx.obj \
|
||||
$(BZIP2_OBJS) \
|
||||
$(BZIP2_OPT_OBJS) \
|
||||
$(COMMON_OBJS) \
|
||||
$(WIN_OBJS) \
|
||||
$(7ZIP_COMMON_OBJS) \
|
||||
$O\BlockSort.obj \
|
||||
$(C_OBJS) \
|
||||
$O\HuffmanEncode.obj \
|
||||
$O\resource.res
|
||||
|
||||
!include "../../../Build.mak"
|
||||
|
||||
$(BZIP2_OBJS): $(*B).cpp
|
||||
$(COMPL)
|
||||
$(BZIP2_OPT_OBJS): $(*B).cpp
|
||||
$(COMPL_O2)
|
||||
$(COMMON_OBJS): ../../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(WIN_OBJS): ../../../Windows/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$O\BlockSort.obj: ../BWT/$(*B).cpp
|
||||
$(COMPL_O2)
|
||||
$(C_OBJS): ../../../../C/$(*B).c
|
||||
$(COMPL_O2)
|
||||
$O\HuffmanEncode.obj: ../../../../C/Compress/Huffman/$(*B).c
|
||||
$(COMPL_O2)
|
||||
3
CPP/7zip/Compress/BZip2/resource.rc
Executable file
3
CPP/7zip/Compress/BZip2/resource.rc
Executable file
@@ -0,0 +1,3 @@
|
||||
#include "../../MyVersionInfo.rc"
|
||||
|
||||
MY_VERSION_INFO_DLL("BZip2 Codec", "BZip2")
|
||||
131
CPP/7zip/Compress/BZip2Original/BZip2Decoder.cpp
Executable file
131
CPP/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;
|
||||
for (;;)
|
||||
{
|
||||
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
CPP/7zip/Compress/BZip2Original/BZip2Decoder.h
Executable file
38
CPP/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
CPP/7zip/Compress/BZip2Original/BZip2Encoder.cpp
Executable file
120
CPP/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;
|
||||
for (;;)
|
||||
{
|
||||
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
CPP/7zip/Compress/BZip2Original/BZip2Encoder.h
Executable file
30
CPP/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
|
||||
10
CPP/7zip/Compress/BZip2Original/BZip2Error.cpp
Executable file
10
CPP/7zip/Compress/BZip2Original/BZip2Error.cpp
Executable file
@@ -0,0 +1,10 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Original/bzlib.h"
|
||||
|
||||
extern "C"
|
||||
|
||||
void bz_internal_error (int errcode)
|
||||
{
|
||||
throw "error";
|
||||
}
|
||||
86
CPP/7zip/Compress/BZip2Original/DllExports.cpp
Executable file
86
CPP/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
CPP/7zip/Compress/BZip2Original/StdAfx.cpp
Executable file
3
CPP/7zip/Compress/BZip2Original/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
8
CPP/7zip/Compress/BZip2Original/StdAfx.h
Executable file
8
CPP/7zip/Compress/BZip2Original/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
16
CPP/7zip/Compress/Branch/ARM.cpp
Executable file
16
CPP/7zip/Compress/Branch/ARM.cpp
Executable file
@@ -0,0 +1,16 @@
|
||||
// ARM.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "ARM.h"
|
||||
|
||||
#include "../../../../C/Compress/Branch/BranchARM.c"
|
||||
|
||||
UInt32 CBC_ARM_Encoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::ARM_Convert(data, size, _bufferPos, 1);
|
||||
}
|
||||
|
||||
UInt32 CBC_ARM_Decoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::ARM_Convert(data, size, _bufferPos, 0);
|
||||
}
|
||||
10
CPP/7zip/Compress/Branch/ARM.h
Executable file
10
CPP/7zip/Compress/Branch/ARM.h
Executable file
@@ -0,0 +1,10 @@
|
||||
// ARM.h
|
||||
|
||||
#ifndef __ARM_H
|
||||
#define __ARM_H
|
||||
|
||||
#include "BranchCoder.h"
|
||||
|
||||
MyClassA(BC_ARM, 0x05, 1)
|
||||
|
||||
#endif
|
||||
16
CPP/7zip/Compress/Branch/ARMThumb.cpp
Executable file
16
CPP/7zip/Compress/Branch/ARMThumb.cpp
Executable file
@@ -0,0 +1,16 @@
|
||||
// ARMThumb.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "ARMThumb.h"
|
||||
|
||||
#include "../../../../C/Compress/Branch/BranchARMThumb.c"
|
||||
|
||||
UInt32 CBC_ARMThumb_Encoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::ARMThumb_Convert(data, size, _bufferPos, 1);
|
||||
}
|
||||
|
||||
UInt32 CBC_ARMThumb_Decoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::ARMThumb_Convert(data, size, _bufferPos, 0);
|
||||
}
|
||||
10
CPP/7zip/Compress/Branch/ARMThumb.h
Executable file
10
CPP/7zip/Compress/Branch/ARMThumb.h
Executable file
@@ -0,0 +1,10 @@
|
||||
// ARMThumb.h
|
||||
|
||||
#ifndef __ARMTHUMB_H
|
||||
#define __ARMTHUMB_H
|
||||
|
||||
#include "BranchCoder.h"
|
||||
|
||||
MyClassA(BC_ARMThumb, 0x07, 1)
|
||||
|
||||
#endif
|
||||
298
CPP/7zip/Compress/Branch/Branch.dsp
Executable file
298
CPP/7zip/Compress/Branch/Branch.dsp
Executable file
@@ -0,0 +1,298 @@
|
||||
# Microsoft Developer Studio Project File - Name="Branch" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=Branch - 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 "Branch.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 "Branch.mak" CFG="Branch - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Branch - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "Branch - 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)" == "Branch - 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 "BRANCH_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O2 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BRANCH_EXPORTS" /FD /c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# 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\Branch.dll" /opt:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "Branch - 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 "BRANCH_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BRANCH_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\Branch.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "Branch - Win32 Release"
|
||||
# Name "Branch - Win32 Debug"
|
||||
# Begin Group "Spec"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Codec.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DllExports.cpp
|
||||
# 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 "Methods"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ARM.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=.\ARM.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ARMThumb.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=.\ARMThumb.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BranchCoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BranchCoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BranchTypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BranchX86.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\IA64.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=.\IA64.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\PPC.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=.\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"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Branch - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\x86.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\x86_2.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=.\x86_2.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Stream"
|
||||
|
||||
# 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\OutBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\OutBuffer.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "RangeCoder"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\RangeCoder\RangeCoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\RangeCoder\RangeCoderBit.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
|
||||
# End Target
|
||||
# End Project
|
||||
29
CPP/7zip/Compress/Branch/Branch.dsw
Executable file
29
CPP/7zip/Compress/Branch/Branch.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: "Branch"=.\Branch.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
18
CPP/7zip/Compress/Branch/BranchCoder.cpp
Executable file
18
CPP/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
CPP/7zip/Compress/Branch/BranchCoder.h
Executable file
54
CPP/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
|
||||
152
CPP/7zip/Compress/Branch/DllExports.cpp
Executable file
152
CPP/7zip/Compress/Branch/DllExports.cpp
Executable file
@@ -0,0 +1,152 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
#include "x86.h"
|
||||
#include "PPC.h"
|
||||
#include "IA64.h"
|
||||
#include "ARM.h"
|
||||
#include "ARMThumb.h"
|
||||
#include "x86_2.h"
|
||||
#include "SPARC.h"
|
||||
|
||||
#define MY_CreateClass0(n) \
|
||||
if (*clsid == CLSID_CCompressConvert ## n ## _Encoder) { \
|
||||
if (!correctInterface) \
|
||||
return E_NOINTERFACE; \
|
||||
filter = (ICompressFilter *)new C ## n ## _Encoder(); \
|
||||
} else if (*clsid == CLSID_CCompressConvert ## n ## _Decoder){ \
|
||||
if (!correctInterface) \
|
||||
return E_NOINTERFACE; \
|
||||
filter = (ICompressFilter *)new C ## n ## _Decoder(); \
|
||||
}
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STDAPI CreateObject(
|
||||
const GUID *clsid,
|
||||
const GUID *interfaceID,
|
||||
void **outObject)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
int correctInterface = (*interfaceID == IID_ICompressFilter);
|
||||
CMyComPtr<ICompressFilter> filter;
|
||||
MY_CreateClass0(BCJ_x86)
|
||||
else
|
||||
MY_CreateClass0(BC_ARM)
|
||||
else
|
||||
MY_CreateClass0(BC_PPC_B)
|
||||
else
|
||||
MY_CreateClass0(BC_IA64)
|
||||
else
|
||||
MY_CreateClass0(BC_ARMThumb)
|
||||
else
|
||||
MY_CreateClass0(BC_SPARC)
|
||||
else
|
||||
{
|
||||
CMyComPtr<ICompressCoder2> coder2;
|
||||
correctInterface = (*interfaceID == IID_ICompressCoder2);
|
||||
if (*clsid == CLSID_CCompressConvertBCJ2_x86_Encoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder2 = (ICompressCoder2 *)new CBCJ2_x86_Encoder();
|
||||
}
|
||||
else if (*clsid == CLSID_CCompressConvertBCJ2_x86_Decoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder2 = (ICompressCoder2 *)new CBCJ2_x86_Decoder();
|
||||
}
|
||||
else
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
*outObject = coder2.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
*outObject = filter.Detach();
|
||||
return S_OK;
|
||||
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
struct CBranchMethodItem
|
||||
{
|
||||
char ID[4];
|
||||
const wchar_t *UserName;
|
||||
const GUID *Decoder;
|
||||
const GUID *Encoder;
|
||||
UINT32 NumInStreams;
|
||||
};
|
||||
|
||||
#define METHOD_ITEM(Name, id, subId, UserName, NumInStreams) \
|
||||
{ { 0x03, 0x03, id, subId }, UserName, \
|
||||
&CLSID_CCompressConvert ## Name ## _Decoder, \
|
||||
&CLSID_CCompressConvert ## Name ## _Encoder, NumInStreams }
|
||||
|
||||
|
||||
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_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_SPARC, 0x08, 0x05, L"BC_SPARC", 1)
|
||||
};
|
||||
|
||||
STDAPI GetNumberOfMethods(UINT32 *numMethods)
|
||||
{
|
||||
*numMethods = sizeof(g_Methods) / sizeof(g_Methods[1]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
if (index > sizeof(g_Methods) / sizeof(g_Methods[1]))
|
||||
return E_INVALIDARG;
|
||||
VariantClear((tagVARIANT *)value);
|
||||
const CBranchMethodItem &method = g_Methods[index];
|
||||
switch(propID)
|
||||
{
|
||||
case NMethodPropID::kID:
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(method.ID,
|
||||
sizeof(method.ID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kName:
|
||||
if ((value->bstrVal = ::SysAllocString(method.UserName)) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kDecoder:
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)method.Decoder, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kEncoder:
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)method.Encoder, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kInStreams:
|
||||
{
|
||||
if (method.NumInStreams != 1)
|
||||
{
|
||||
value->vt = VT_UI4;
|
||||
value->ulVal = method.NumInStreams;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
16
CPP/7zip/Compress/Branch/IA64.cpp
Executable file
16
CPP/7zip/Compress/Branch/IA64.cpp
Executable file
@@ -0,0 +1,16 @@
|
||||
// IA64.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "IA64.h"
|
||||
|
||||
#include "../../../../C/Compress/Branch/BranchIA64.c"
|
||||
|
||||
UInt32 CBC_IA64_Encoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::IA64_Convert(data, size, _bufferPos, 1);
|
||||
}
|
||||
|
||||
UInt32 CBC_IA64_Decoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::IA64_Convert(data, size, _bufferPos, 0);
|
||||
}
|
||||
10
CPP/7zip/Compress/Branch/IA64.h
Executable file
10
CPP/7zip/Compress/Branch/IA64.h
Executable file
@@ -0,0 +1,10 @@
|
||||
// IA64.h
|
||||
|
||||
#ifndef __IA64_H
|
||||
#define __IA64_H
|
||||
|
||||
#include "BranchCoder.h"
|
||||
|
||||
MyClassA(BC_IA64, 0x04, 1)
|
||||
|
||||
#endif
|
||||
17
CPP/7zip/Compress/Branch/PPC.cpp
Executable file
17
CPP/7zip/Compress/Branch/PPC.cpp
Executable file
@@ -0,0 +1,17 @@
|
||||
// PPC.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "PPC.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "../../../../C/Compress/Branch/BranchPPC.c"
|
||||
|
||||
UInt32 CBC_PPC_B_Encoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::PPC_B_Convert(data, size, _bufferPos, 1);
|
||||
}
|
||||
|
||||
UInt32 CBC_PPC_B_Decoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::PPC_B_Convert(data, size, _bufferPos, 0);
|
||||
}
|
||||
10
CPP/7zip/Compress/Branch/PPC.h
Executable file
10
CPP/7zip/Compress/Branch/PPC.h
Executable file
@@ -0,0 +1,10 @@
|
||||
// PPC.h
|
||||
|
||||
#ifndef __PPC_H
|
||||
#define __PPC_H
|
||||
|
||||
#include "BranchCoder.h"
|
||||
|
||||
MyClassA(BC_PPC_B, 0x02, 5)
|
||||
|
||||
#endif
|
||||
17
CPP/7zip/Compress/Branch/SPARC.cpp
Executable file
17
CPP/7zip/Compress/Branch/SPARC.cpp
Executable file
@@ -0,0 +1,17 @@
|
||||
// SPARC.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "SPARC.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "../../../../C/Compress/Branch/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
CPP/7zip/Compress/Branch/SPARC.h
Executable file
10
CPP/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
|
||||
3
CPP/7zip/Compress/Branch/StdAfx.cpp
Executable file
3
CPP/7zip/Compress/Branch/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
8
CPP/7zip/Compress/Branch/StdAfx.h
Executable file
8
CPP/7zip/Compress/Branch/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
48
CPP/7zip/Compress/Branch/makefile
Executable file
48
CPP/7zip/Compress/Branch/makefile
Executable file
@@ -0,0 +1,48 @@
|
||||
PROG = Branch.dll
|
||||
DEF_FILE = ../Codec.def
|
||||
CFLAGS = $(CFLAGS) -I ../../../
|
||||
LIBS = $(LIBS) oleaut32.lib
|
||||
|
||||
BRANCH_OBJS = \
|
||||
$O\DllExports.obj \
|
||||
|
||||
BRANCH_OPT_OBJS = \
|
||||
$O\ARM.obj \
|
||||
$O\ARMThumb.obj \
|
||||
$O\BranchCoder.obj \
|
||||
$O\IA64.obj \
|
||||
$O\PPC.obj \
|
||||
$O\SPARC.obj \
|
||||
$O\x86.obj \
|
||||
$O\x86_2.obj \
|
||||
|
||||
COMMON_OBJS = \
|
||||
$O\Alloc.obj \
|
||||
|
||||
7ZIP_COMMON_OBJS = \
|
||||
$O\InBuffer.obj \
|
||||
$O\OutBuffer.obj \
|
||||
|
||||
|
||||
OBJS = \
|
||||
$O\StdAfx.obj \
|
||||
$(BRANCH_OBJS) \
|
||||
$(BRANCH_OPT_OBJS) \
|
||||
$(COMMON_OBJS) \
|
||||
$(7ZIP_COMMON_OBJS) \
|
||||
$O\RangeCoderBit.obj \
|
||||
$O\resource.res
|
||||
|
||||
|
||||
!include "../../../Build.mak"
|
||||
|
||||
$(BRANCH_OBJS): $(*B).cpp
|
||||
$(COMPL)
|
||||
$(BRANCH_OPT_OBJS): $(*B).cpp
|
||||
$(COMPL_O2)
|
||||
$(COMMON_OBJS): ../../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$O\RangeCoderBit.obj: ../RangeCoder/$(*B).cpp
|
||||
$(COMPL)
|
||||
3
CPP/7zip/Compress/Branch/resource.rc
Executable file
3
CPP/7zip/Compress/Branch/resource.rc
Executable file
@@ -0,0 +1,3 @@
|
||||
#include "../../MyVersionInfo.rc"
|
||||
|
||||
MY_VERSION_INFO_DLL("Branch Filter", "Branch")
|
||||
18
CPP/7zip/Compress/Branch/x86.cpp
Executable file
18
CPP/7zip/Compress/Branch/x86.cpp
Executable file
@@ -0,0 +1,18 @@
|
||||
// x86.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "x86.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
#include "../../../../C/Compress/Branch/BranchX86.c"
|
||||
|
||||
UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 1);
|
||||
}
|
||||
|
||||
UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size)
|
||||
{
|
||||
return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 0);
|
||||
}
|
||||
19
CPP/7zip/Compress/Branch/x86.h
Executable file
19
CPP/7zip/Compress/Branch/x86.h
Executable file
@@ -0,0 +1,19 @@
|
||||
// x86.h
|
||||
|
||||
#ifndef __X86_H
|
||||
#define __X86_H
|
||||
|
||||
#include "BranchCoder.h"
|
||||
#include "../../../../C/Compress/Branch/BranchX86.h"
|
||||
|
||||
struct CBranch86
|
||||
{
|
||||
UInt32 _prevMask;
|
||||
UInt32 _prevPos;
|
||||
void x86Init() { x86_Convert_Init(_prevMask, _prevPos); }
|
||||
};
|
||||
|
||||
MyClassB(BCJ_x86, 0x01, 3, CBranch86 ,
|
||||
virtual void SubInit() { x86Init(); })
|
||||
|
||||
#endif
|
||||
412
CPP/7zip/Compress/Branch/x86_2.cpp
Executable file
412
CPP/7zip/Compress/Branch/x86_2.cpp
Executable file
@@ -0,0 +1,412 @@
|
||||
// x86_2.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "x86_2.h"
|
||||
|
||||
#include "../../../Common/Alloc.h"
|
||||
|
||||
static const int kBufferSize = 1 << 17;
|
||||
|
||||
inline bool IsJcc(Byte b0, Byte b1)
|
||||
{
|
||||
return (b0 == 0x0F && (b1 & 0xF0) == 0x80);
|
||||
}
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
|
||||
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 *)MidAlloc(kBufferSize);
|
||||
if (_buffer == 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CBCJ2_x86_Encoder::~CBCJ2_x86_Encoder()
|
||||
{
|
||||
::MidFree(_buffer);
|
||||
}
|
||||
|
||||
HRESULT CBCJ2_x86_Encoder::Flush()
|
||||
{
|
||||
RINOK(_mainStream.Flush());
|
||||
RINOK(_callStream.Flush());
|
||||
RINOK(_jumpStream.Flush());
|
||||
_rangeEncoder.FlushData();
|
||||
return _rangeEncoder.FlushStream();
|
||||
}
|
||||
|
||||
const UInt32 kDefaultLimit = (1 << 24);
|
||||
|
||||
HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
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 = 0;
|
||||
if (inSizes != NULL)
|
||||
if (inSizes[0] != NULL)
|
||||
{
|
||||
inSize = *inSizes[0];
|
||||
if (inSize <= kDefaultLimit)
|
||||
sizeIsDefined = true;
|
||||
}
|
||||
|
||||
ISequentialInStream *inStream = inStreams[0];
|
||||
|
||||
_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);
|
||||
|
||||
CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;
|
||||
{
|
||||
inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize);
|
||||
}
|
||||
|
||||
UInt32 nowPos = 0;
|
||||
UInt64 nowPos64 = 0;
|
||||
UInt32 bufferPos = 0;
|
||||
|
||||
Byte prevByte = 0;
|
||||
|
||||
UInt64 subStreamIndex = 0;
|
||||
UInt64 subStreamStartPos = 0;
|
||||
UInt64 subStreamEndPos = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
UInt32 processedSize = 0;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 size = kBufferSize - (bufferPos + processedSize);
|
||||
UInt32 processedSizeLoc;
|
||||
if (size == 0)
|
||||
break;
|
||||
RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc));
|
||||
if (processedSizeLoc == 0)
|
||||
break;
|
||||
processedSize += processedSizeLoc;
|
||||
}
|
||||
UInt32 endPos = bufferPos + processedSize;
|
||||
|
||||
if (endPos < 5)
|
||||
{
|
||||
// change it
|
||||
for (bufferPos = 0; bufferPos < endPos; bufferPos++)
|
||||
{
|
||||
Byte b = _buffer[bufferPos];
|
||||
_mainStream.WriteByte(b);
|
||||
if (b == 0xE8)
|
||||
_statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0);
|
||||
else if (b == 0xE9)
|
||||
_statusE9Encoder.Encode(&_rangeEncoder, 0);
|
||||
else if (IsJcc(prevByte, b))
|
||||
_statusJccEncoder.Encode(&_rangeEncoder, 0);
|
||||
prevByte = b;
|
||||
}
|
||||
return Flush();
|
||||
}
|
||||
|
||||
bufferPos = 0;
|
||||
|
||||
UInt32 limit = endPos - 5;
|
||||
while(bufferPos <= limit)
|
||||
{
|
||||
Byte b = _buffer[bufferPos];
|
||||
_mainStream.WriteByte(b);
|
||||
if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))
|
||||
{
|
||||
bufferPos++;
|
||||
prevByte = b;
|
||||
continue;
|
||||
}
|
||||
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;
|
||||
// if (Test86MSByte(nextByte))
|
||||
bool convert;
|
||||
if (getSubStreamSize != NULL)
|
||||
{
|
||||
UInt64 currentPos = (nowPos64 + bufferPos);
|
||||
while (subStreamEndPos < currentPos)
|
||||
{
|
||||
UInt64 subStreamSize;
|
||||
HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize);
|
||||
if (result == S_OK)
|
||||
{
|
||||
subStreamStartPos = subStreamEndPos;
|
||||
subStreamEndPos += subStreamSize;
|
||||
subStreamIndex++;
|
||||
}
|
||||
else if (result == S_FALSE || result == E_NOTIMPL)
|
||||
{
|
||||
getSubStreamSize.Release();
|
||||
subStreamStartPos = 0;
|
||||
subStreamEndPos = subStreamStartPos - 1;
|
||||
}
|
||||
else
|
||||
return result;
|
||||
}
|
||||
if (getSubStreamSize == NULL)
|
||||
{
|
||||
if (sizeIsDefined)
|
||||
convert = (dest < inSize);
|
||||
else
|
||||
convert = Test86MSByte(nextByte);
|
||||
}
|
||||
else if (subStreamEndPos - subStreamStartPos > kDefaultLimit)
|
||||
convert = Test86MSByte(nextByte);
|
||||
else
|
||||
{
|
||||
UInt64 dest64 = (currentPos + 5) + Int64(Int32(src));
|
||||
convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos);
|
||||
}
|
||||
}
|
||||
else if (sizeIsDefined)
|
||||
convert = (dest < inSize);
|
||||
else
|
||||
convert = Test86MSByte(nextByte);
|
||||
if (convert)
|
||||
{
|
||||
if (b == 0xE8)
|
||||
_statusE8Encoder[prevByte].Encode(&_rangeEncoder, 1);
|
||||
else if (b == 0xE9)
|
||||
_statusE9Encoder.Encode(&_rangeEncoder, 1);
|
||||
else
|
||||
_statusJccEncoder.Encode(&_rangeEncoder, 1);
|
||||
|
||||
bufferPos += 5;
|
||||
if (b == 0xE8)
|
||||
{
|
||||
_callStream.WriteByte((Byte)(dest >> 24));
|
||||
_callStream.WriteByte((Byte)(dest >> 16));
|
||||
_callStream.WriteByte((Byte)(dest >> 8));
|
||||
_callStream.WriteByte((Byte)(dest));
|
||||
}
|
||||
else
|
||||
{
|
||||
_jumpStream.WriteByte((Byte)(dest >> 24));
|
||||
_jumpStream.WriteByte((Byte)(dest >> 16));
|
||||
_jumpStream.WriteByte((Byte)(dest >> 8));
|
||||
_jumpStream.WriteByte((Byte)(dest));
|
||||
}
|
||||
prevByte = nextByte;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (b == 0xE8)
|
||||
_statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0);
|
||||
else if (b == 0xE9)
|
||||
_statusE9Encoder.Encode(&_rangeEncoder, 0);
|
||||
else
|
||||
_statusJccEncoder.Encode(&_rangeEncoder, 0);
|
||||
bufferPos++;
|
||||
prevByte = b;
|
||||
}
|
||||
}
|
||||
nowPos += bufferPos;
|
||||
nowPos64 += bufferPos;
|
||||
|
||||
if (progress != NULL)
|
||||
{
|
||||
RINOK(progress->SetRatioInfo(&nowPos64, NULL));
|
||||
}
|
||||
|
||||
UInt32 i = 0;
|
||||
while(bufferPos < endPos)
|
||||
_buffer[i++] = _buffer[bufferPos++];
|
||||
bufferPos = i;
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try
|
||||
{
|
||||
return CodeReal(inStreams, inSizes, numInStreams,
|
||||
outStreams, outSizes,numOutStreams, progress);
|
||||
}
|
||||
catch(const COutBufferException &e) { return e.ErrorCode; }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams,
|
||||
const UInt64 ** /* inSizes */,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UInt64 ** /* outSizes */,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (numInStreams != 4 || numOutStreams != 1)
|
||||
return E_INVALIDARG;
|
||||
|
||||
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();
|
||||
|
||||
CCoderReleaser releaser(this);
|
||||
|
||||
Byte prevByte = 0;
|
||||
UInt32 processedBytes = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (processedBytes > (1 << 20) && progress != NULL)
|
||||
{
|
||||
UInt64 nowPos64 = _outStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(NULL, &nowPos64));
|
||||
processedBytes = 0;
|
||||
}
|
||||
processedBytes++;
|
||||
Byte b;
|
||||
if (!_mainInStream.ReadByte(b))
|
||||
return Flush();
|
||||
_outStream.WriteByte(b);
|
||||
if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))
|
||||
{
|
||||
prevByte = b;
|
||||
continue;
|
||||
}
|
||||
bool status;
|
||||
if (b == 0xE8)
|
||||
status = (_statusE8Decoder[prevByte].Decode(&_rangeDecoder) == 1);
|
||||
else if (b == 0xE9)
|
||||
status = (_statusE9Decoder.Decode(&_rangeDecoder) == 1);
|
||||
else
|
||||
status = (_statusJccDecoder.Decode(&_rangeDecoder) == 1);
|
||||
if (status)
|
||||
{
|
||||
UInt32 src;
|
||||
if (b == 0xE8)
|
||||
{
|
||||
Byte b0;
|
||||
if(!_callStream.ReadByte(b0))
|
||||
return S_FALSE;
|
||||
src = ((UInt32)b0) << 24;
|
||||
if(!_callStream.ReadByte(b0))
|
||||
return S_FALSE;
|
||||
src |= ((UInt32)b0) << 16;
|
||||
if(!_callStream.ReadByte(b0))
|
||||
return S_FALSE;
|
||||
src |= ((UInt32)b0) << 8;
|
||||
if(!_callStream.ReadByte(b0))
|
||||
return S_FALSE;
|
||||
src |= ((UInt32)b0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Byte b0;
|
||||
if(!_jumpStream.ReadByte(b0))
|
||||
return S_FALSE;
|
||||
src = ((UInt32)b0) << 24;
|
||||
if(!_jumpStream.ReadByte(b0))
|
||||
return S_FALSE;
|
||||
src |= ((UInt32)b0) << 16;
|
||||
if(!_jumpStream.ReadByte(b0))
|
||||
return S_FALSE;
|
||||
src |= ((UInt32)b0) << 8;
|
||||
if(!_jumpStream.ReadByte(b0))
|
||||
return S_FALSE;
|
||||
src |= ((UInt32)b0);
|
||||
}
|
||||
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 = (Byte)(dest >> 24);
|
||||
processedBytes += 4;
|
||||
}
|
||||
else
|
||||
prevByte = b;
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CBCJ2_x86_Decoder::Code(ISequentialInStream **inStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try
|
||||
{
|
||||
return CodeReal(inStreams, inSizes, numInStreams,
|
||||
outStreams, outSizes,numOutStreams, progress);
|
||||
}
|
||||
catch(const COutBufferException &e) { return e.ErrorCode; }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
133
CPP/7zip/Compress/Branch/x86_2.h
Executable file
133
CPP/7zip/Compress/Branch/x86_2.h
Executable file
@@ -0,0 +1,133 @@
|
||||
// x86_2.h
|
||||
|
||||
#ifndef __BRANCH_X86_2_H
|
||||
#define __BRANCH_X86_2_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../RangeCoder/RangeCoderBit.h"
|
||||
#include "../../ICoder.h"
|
||||
|
||||
// {23170F69-40C1-278B-0303-010100000100}
|
||||
#define MyClass2_a(Name, id, subId, encodingId) \
|
||||
DEFINE_GUID(CLSID_CCompressConvert ## Name, \
|
||||
0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00);
|
||||
|
||||
#define MyClass_a(Name, id, subId) \
|
||||
MyClass2_a(Name ## _Encoder, id, subId, 0x01) \
|
||||
MyClass2_a(Name ## _Decoder, id, subId, 0x00)
|
||||
|
||||
MyClass_a(BCJ2_x86, 0x01, 0x1B)
|
||||
|
||||
const int kNumMoveBits = 5;
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
|
||||
class CBCJ2_x86_Encoder:
|
||||
public ICompressCoder2,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
Byte *_buffer;
|
||||
public:
|
||||
CBCJ2_x86_Encoder(): _buffer(0) {};
|
||||
~CBCJ2_x86_Encoder();
|
||||
bool Create();
|
||||
|
||||
COutBuffer _mainStream;
|
||||
COutBuffer _callStream;
|
||||
COutBuffer _jumpStream;
|
||||
NCompress::NRangeCoder::CEncoder _rangeEncoder;
|
||||
NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusE8Encoder[256];
|
||||
NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusE9Encoder;
|
||||
NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusJccEncoder;
|
||||
|
||||
HRESULT Flush();
|
||||
void ReleaseStreams()
|
||||
{
|
||||
_mainStream.ReleaseStream();
|
||||
_callStream.ReleaseStream();
|
||||
_jumpStream.ReleaseStream();
|
||||
_rangeEncoder.ReleaseStream();
|
||||
}
|
||||
|
||||
class CCoderReleaser
|
||||
{
|
||||
CBCJ2_x86_Encoder *_coder;
|
||||
public:
|
||||
CCoderReleaser(CBCJ2_x86_Encoder *coder): _coder(coder) {}
|
||||
~CCoderReleaser() { _coder->ReleaseStreams(); }
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
HRESULT CodeReal(ISequentialInStream **inStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress);
|
||||
STDMETHOD(Code)(ISequentialInStream **inStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
class CBCJ2_x86_Decoder:
|
||||
public ICompressCoder2,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
CInBuffer _mainInStream;
|
||||
CInBuffer _callStream;
|
||||
CInBuffer _jumpStream;
|
||||
NCompress::NRangeCoder::CDecoder _rangeDecoder;
|
||||
NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusE8Decoder[256];
|
||||
NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusE9Decoder;
|
||||
NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusJccDecoder;
|
||||
|
||||
COutBuffer _outStream;
|
||||
|
||||
void ReleaseStreams()
|
||||
{
|
||||
_mainInStream.ReleaseStream();
|
||||
_callStream.ReleaseStream();
|
||||
_jumpStream.ReleaseStream();
|
||||
_rangeDecoder.ReleaseStream();
|
||||
_outStream.ReleaseStream();
|
||||
}
|
||||
|
||||
HRESULT Flush() { return _outStream.Flush(); }
|
||||
class CCoderReleaser
|
||||
{
|
||||
CBCJ2_x86_Decoder *_coder;
|
||||
public:
|
||||
CCoderReleaser(CBCJ2_x86_Decoder *coder): _coder(coder) {}
|
||||
~CCoderReleaser() { _coder->ReleaseStreams(); }
|
||||
};
|
||||
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
HRESULT CodeReal(ISequentialInStream **inStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress);
|
||||
STDMETHOD(Code)(ISequentialInStream **inStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress);
|
||||
};
|
||||
|
||||
#endif
|
||||
38
CPP/7zip/Compress/ByteSwap/ByteSwap.cpp
Executable file
38
CPP/7zip/Compress/ByteSwap/ByteSwap.cpp
Executable file
@@ -0,0 +1,38 @@
|
||||
// ByteSwap.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ByteSwap.h"
|
||||
|
||||
STDMETHODIMP CByteSwap2::Init() { return S_OK; }
|
||||
|
||||
STDMETHODIMP_(UInt32) CByteSwap2::Filter(Byte *data, UInt32 size)
|
||||
{
|
||||
const UInt32 kStep = 2;
|
||||
UInt32 i;
|
||||
for (i = 0; i + kStep <= size; i += kStep)
|
||||
{
|
||||
Byte b = data[i];
|
||||
data[i] = data[i + 1];
|
||||
data[i + 1] = b;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
STDMETHODIMP CByteSwap4::Init() { return S_OK; }
|
||||
|
||||
STDMETHODIMP_(UInt32) CByteSwap4::Filter(Byte *data, UInt32 size)
|
||||
{
|
||||
const UInt32 kStep = 4;
|
||||
UInt32 i;
|
||||
for (i = 0; i + kStep <= size; i += kStep)
|
||||
{
|
||||
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;
|
||||
}
|
||||
125
CPP/7zip/Compress/ByteSwap/ByteSwap.dsp
Executable file
125
CPP/7zip/Compress/ByteSwap/ByteSwap.dsp
Executable file
@@ -0,0 +1,125 @@
|
||||
# Microsoft Developer Studio Project File - Name="ByteSwap" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=ByteSwap - 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 "ByteSwap.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 "ByteSwap.mak" CFG="ByteSwap - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "ByteSwap - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "ByteSwap - 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)" == "ByteSwap - 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 "BYTESWAP_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BYTESWAP_EXPORTS" /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\Swap.dll" /opt:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "ByteSwap - 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 "BYTESWAP_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BYTESWAP_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\Swap.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "ByteSwap - Win32 Release"
|
||||
# Name "ByteSwap - Win32 Debug"
|
||||
# Begin Group "Spec"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Codec.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DllExports.cpp
|
||||
# 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 Source File
|
||||
|
||||
SOURCE=.\ByteSwap.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ByteSwap.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
CPP/7zip/Compress/ByteSwap/ByteSwap.dsw
Executable file
29
CPP/7zip/Compress/ByteSwap/ByteSwap.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: "ByteSwap"=.\ByteSwap.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
37
CPP/7zip/Compress/ByteSwap/ByteSwap.h
Executable file
37
CPP/7zip/Compress/ByteSwap/ByteSwap.h
Executable file
@@ -0,0 +1,37 @@
|
||||
// ByteSwap.h
|
||||
|
||||
#ifndef __BYTESWAP_H
|
||||
#define __BYTESWAP_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
// {23170F69-40C1-278B-0203-020000000000}
|
||||
DEFINE_GUID(CLSID_CCompressConvertByteSwap2,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x02, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0203-040000000000}
|
||||
DEFINE_GUID(CLSID_CCompressConvertByteSwap4,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
class CByteSwap2:
|
||||
public ICompressFilter,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(Init)();
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
||||
};
|
||||
|
||||
class CByteSwap4:
|
||||
public ICompressFilter,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(Init)();
|
||||
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
||||
};
|
||||
|
||||
#endif
|
||||
91
CPP/7zip/Compress/ByteSwap/DllExports.cpp
Executable file
91
CPP/7zip/Compress/ByteSwap/DllExports.cpp
Executable file
@@ -0,0 +1,91 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "ByteSwap.h"
|
||||
#include "../../ICoder.h"
|
||||
|
||||
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_ICompressFilter);
|
||||
CMyComPtr<ICompressFilter> coder;
|
||||
if (*clsid == CLSID_CCompressConvertByteSwap2)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressFilter *)new CByteSwap2();
|
||||
}
|
||||
else if (*clsid == CLSID_CCompressConvertByteSwap4)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressFilter *)new CByteSwap4();
|
||||
}
|
||||
else
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
*outObject = coder.Detach();
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct CSwapMethodInfo
|
||||
{
|
||||
char ID[3];
|
||||
const wchar_t *Name;
|
||||
const GUID *clsid;
|
||||
};
|
||||
|
||||
static CSwapMethodInfo g_Methods[] =
|
||||
{
|
||||
{ { 0x2, 0x03, 0x02 }, L"Swap2", &CLSID_CCompressConvertByteSwap2 },
|
||||
{ { 0x2, 0x03, 0x04 }, L"Swap4", &CLSID_CCompressConvertByteSwap4 }
|
||||
};
|
||||
|
||||
STDAPI GetNumberOfMethods(UINT32 *numMethods)
|
||||
{
|
||||
*numMethods = sizeof(g_Methods) / sizeof(g_Methods[1]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
if (index > sizeof(g_Methods) / sizeof(g_Methods[1]))
|
||||
return E_INVALIDARG;
|
||||
::VariantClear((tagVARIANT *)value);
|
||||
const CSwapMethodInfo &method = g_Methods[index];
|
||||
switch(propID)
|
||||
{
|
||||
case NMethodPropID::kID:
|
||||
{
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(method.ID,
|
||||
sizeof(method.ID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
case NMethodPropID::kName:
|
||||
{
|
||||
if ((value->bstrVal = ::SysAllocString(method.Name)) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
case NMethodPropID::kDecoder:
|
||||
case NMethodPropID::kEncoder:
|
||||
{
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)method.clsid, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
3
CPP/7zip/Compress/ByteSwap/StdAfx.cpp
Executable file
3
CPP/7zip/Compress/ByteSwap/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
8
CPP/7zip/Compress/ByteSwap/StdAfx.h
Executable file
8
CPP/7zip/Compress/ByteSwap/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
23
CPP/7zip/Compress/ByteSwap/makefile
Executable file
23
CPP/7zip/Compress/ByteSwap/makefile
Executable file
@@ -0,0 +1,23 @@
|
||||
PROG = Swap.dll
|
||||
DEF_FILE = ../Codec.def
|
||||
CFLAGS = $(CFLAGS) -I ../../../
|
||||
LIBS = $(LIBS) oleaut32.lib
|
||||
|
||||
SWAP_OBJS = \
|
||||
$O\DllExports.obj \
|
||||
|
||||
SWAP_OPT_OBJS = \
|
||||
$O\ByteSwap.obj \
|
||||
|
||||
OBJS = \
|
||||
$O\StdAfx.obj \
|
||||
$(SWAP_OBJS) \
|
||||
$(SWAP_OPT_OBJS) \
|
||||
$O\resource.res
|
||||
|
||||
!include "../../../Build.mak"
|
||||
|
||||
$(SWAP_OBJS): $(*B).cpp
|
||||
$(COMPL)
|
||||
$(SWAP_OPT_OBJS): $(*B).cpp
|
||||
$(COMPL_O2)
|
||||
3
CPP/7zip/Compress/ByteSwap/resource.rc
Executable file
3
CPP/7zip/Compress/ByteSwap/resource.rc
Executable file
@@ -0,0 +1,3 @@
|
||||
#include "../../MyVersionInfo.rc"
|
||||
|
||||
MY_VERSION_INFO_DLL("SWAP filter Codec", "SWAP")
|
||||
4
CPP/7zip/Compress/Codec.def
Executable file
4
CPP/7zip/Compress/Codec.def
Executable file
@@ -0,0 +1,4 @@
|
||||
EXPORTS
|
||||
CreateObject PRIVATE
|
||||
GetNumberOfMethods PRIVATE
|
||||
GetMethodProperty PRIVATE
|
||||
149
CPP/7zip/Compress/Copy/Copy.dsp
Executable file
149
CPP/7zip/Compress/Copy/Copy.dsp
Executable file
@@ -0,0 +1,149 @@
|
||||
# Microsoft Developer Studio Project File - Name="Copy" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=Copy - 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 "Copy.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 "Copy.mak" CFG="Copy - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Copy - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "Copy - 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)" == "Copy - 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 "COPY_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COPY_EXPORTS" /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 0x409 /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\Copy.dll" /opt:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "Copy - 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 "COPY_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COPY_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 0x409 /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\Copy.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "Copy - Win32 Release"
|
||||
# Name "Copy - Win32 Debug"
|
||||
# Begin Group "Spec"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Codec.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DllExports.cpp
|
||||
# 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 "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 Group "7-Zip Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamUtils.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CopyCoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CopyCoder.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
CPP/7zip/Compress/Copy/Copy.dsw
Executable file
29
CPP/7zip/Compress/Copy/Copy.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: "Copy"=".\Copy.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
52
CPP/7zip/Compress/Copy/CopyCoder.cpp
Executable file
52
CPP/7zip/Compress/Copy/CopyCoder.cpp
Executable file
@@ -0,0 +1,52 @@
|
||||
// Compress/CopyCoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "CopyCoder.h"
|
||||
#include "../../../Common/Alloc.h"
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
namespace NCompress {
|
||||
|
||||
static const UInt32 kBufferSize = 1 << 17;
|
||||
|
||||
CCopyCoder::~CCopyCoder()
|
||||
{
|
||||
::MidFree(_buffer);
|
||||
}
|
||||
|
||||
STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UInt64 * /* inSize */, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (_buffer == 0)
|
||||
{
|
||||
_buffer = (Byte *)::MidAlloc(kBufferSize);
|
||||
if (_buffer == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
TotalSize = 0;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 realProcessedSize;
|
||||
UInt32 size = kBufferSize;
|
||||
if (outSize != 0)
|
||||
if (size > *outSize - TotalSize)
|
||||
size = (UInt32)(*outSize - TotalSize);
|
||||
RINOK(inStream->Read(_buffer, size, &realProcessedSize));
|
||||
if(realProcessedSize == 0)
|
||||
break;
|
||||
RINOK(WriteStream(outStream, _buffer, realProcessedSize, NULL));
|
||||
TotalSize += realProcessedSize;
|
||||
if (progress != NULL)
|
||||
{
|
||||
RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
31
CPP/7zip/Compress/Copy/CopyCoder.h
Executable file
31
CPP/7zip/Compress/Copy/CopyCoder.h
Executable file
@@ -0,0 +1,31 @@
|
||||
// Compress/CopyCoder.h
|
||||
|
||||
#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;
|
||||
public:
|
||||
UInt64 TotalSize;
|
||||
CCopyCoder(): TotalSize(0) , _buffer(0) {};
|
||||
~CCopyCoder();
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
70
CPP/7zip/Compress/Copy/DllExports.cpp
Executable file
70
CPP/7zip/Compress/Copy/DllExports.cpp
Executable file
@@ -0,0 +1,70 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/MyInitGuid.h"
|
||||
#include "../../../Common/ComTry.h"
|
||||
|
||||
#include "CopyCoder.h"
|
||||
|
||||
// {23170F69-40C1-278B-0000-000000000000}
|
||||
DEFINE_GUID(CLSID_CCompressCopyCoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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;
|
||||
if (*clsid != CLSID_CCompressCopyCoder)
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
if (*iid != IID_ICompressCoder)
|
||||
return E_NOINTERFACE;
|
||||
CMyComPtr<ICompressCoder> coder = (ICompressCoder *)new NCompress::CCopyCoder();
|
||||
*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[] = { 0x0 };
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
case NMethodPropID::kName:
|
||||
{
|
||||
if ((value->bstrVal = ::SysAllocString(L"Copy")) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
case NMethodPropID::kDecoder:
|
||||
case NMethodPropID::kEncoder:
|
||||
{
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)&CLSID_CCompressCopyCoder, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
3
CPP/7zip/Compress/Copy/StdAfx.cpp
Executable file
3
CPP/7zip/Compress/Copy/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
8
CPP/7zip/Compress/Copy/StdAfx.h
Executable file
8
CPP/7zip/Compress/Copy/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
30
CPP/7zip/Compress/Copy/makefile
Executable file
30
CPP/7zip/Compress/Copy/makefile
Executable file
@@ -0,0 +1,30 @@
|
||||
PROG = Copy.dll
|
||||
DEF_FILE = ../Codec.def
|
||||
CFLAGS = $(CFLAGS) -I ../../../
|
||||
LIBS = $(LIBS) oleaut32.lib
|
||||
|
||||
COPY_OBJS = \
|
||||
$O\DllExports.obj \
|
||||
$O\CopyCoder.obj \
|
||||
|
||||
COMMON_OBJS = \
|
||||
$O\Alloc.obj \
|
||||
|
||||
7ZIP_COMMON_OBJS = \
|
||||
$O\StreamUtils.obj \
|
||||
|
||||
OBJS = \
|
||||
$O\StdAfx.obj \
|
||||
$(COPY_OBJS) \
|
||||
$(COMMON_OBJS) \
|
||||
$(7ZIP_COMMON_OBJS) \
|
||||
$O\resource.res
|
||||
|
||||
!include "../../../Build.mak"
|
||||
|
||||
$(COPY_OBJS): $(*B).cpp
|
||||
$(COMPL)
|
||||
$(COMMON_OBJS): ../../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
3
CPP/7zip/Compress/Copy/resource.rc
Executable file
3
CPP/7zip/Compress/Copy/resource.rc
Executable file
@@ -0,0 +1,3 @@
|
||||
#include "../../MyVersionInfo.rc"
|
||||
|
||||
MY_VERSION_INFO_DLL("Copy Codec", "Copy")
|
||||
341
CPP/7zip/Compress/Deflate/Deflate.dsp
Executable file
341
CPP/7zip/Compress/Deflate/Deflate.dsp
Executable file
@@ -0,0 +1,341 @@
|
||||
# Microsoft Developer Studio Project File - Name="Deflate" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=Deflate - 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 "Deflate.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 "Deflate.mak" CFG="Deflate - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Deflate - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "Deflate - 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)" == "Deflate - 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 "DEFLATE_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEFLATE_EXPORTS" /D "_ST_MODE" /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 0x409 /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\Deflate.dll" /opt:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "Deflate - 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 "DEFLATE_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEFLATE_EXPORTS" /D "_ST_MODE" /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 0x409 /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\Deflate.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "Deflate - Win32 Release"
|
||||
# Name "Deflate - Win32 Debug"
|
||||
# Begin Group "Spec"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Codec.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DllExports.cpp
|
||||
# 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 "Huffman"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Huffman\HuffmanDecoder.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Interface"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# End Group
|
||||
# Begin Group "7zip 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\LSBFDecoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LSBFDecoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LSBFEncoder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LSBFEncoder.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 "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\CRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\CRC.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 Group "Windows"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# End Group
|
||||
# Begin Group "LZ"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\LZOutWindow.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\LZOutWindow.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "LZ_C"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\7zCrc.c
|
||||
|
||||
!IF "$(CFG)" == "Deflate - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\7zCrc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c
|
||||
|
||||
!IF "$(CFG)" == "Deflate - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "C Huffman"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.c
|
||||
|
||||
!IF "$(CFG)" == "Deflate - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Sort.c
|
||||
|
||||
!IF "$(CFG)" == "Deflate - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Sort.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DeflateConst.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DeflateDecoder.cpp
|
||||
|
||||
!IF "$(CFG)" == "Deflate - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DeflateDecoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DeflateEncoder.cpp
|
||||
|
||||
!IF "$(CFG)" == "Deflate - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DeflateEncoder.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
CPP/7zip/Compress/Deflate/Deflate.dsw
Executable file
29
CPP/7zip/Compress/Deflate/Deflate.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: "Deflate"=.\Deflate.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
134
CPP/7zip/Compress/Deflate/DeflateConst.h
Executable file
134
CPP/7zip/Compress/Deflate/DeflateConst.h
Executable file
@@ -0,0 +1,134 @@
|
||||
// DeflateConst.h
|
||||
|
||||
#ifndef __DEFLATE_CONST_H
|
||||
#define __DEFLATE_CONST_H
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
|
||||
const int kNumHuffmanBits = 15;
|
||||
|
||||
const UInt32 kHistorySize32 = (1 << 15);
|
||||
const UInt32 kHistorySize64 = (1 << 16);
|
||||
|
||||
const UInt32 kDistTableSize32 = 30;
|
||||
const UInt32 kDistTableSize64 = 32;
|
||||
|
||||
const UInt32 kNumLenSymbols32 = 256;
|
||||
const UInt32 kNumLenSymbols64 = 255; // don't change it. It must be <= 255.
|
||||
const UInt32 kNumLenSymbolsMax = kNumLenSymbols32;
|
||||
|
||||
const UInt32 kNumLenSlots = 29;
|
||||
|
||||
const UInt32 kFixedDistTableSize = 32;
|
||||
const UInt32 kFixedLenTableSize = 31;
|
||||
|
||||
const UInt32 kSymbolEndOfBlock = 0x100;
|
||||
const UInt32 kSymbolMatch = kSymbolEndOfBlock + 1;
|
||||
|
||||
const UInt32 kMainTableSize = kSymbolMatch + kNumLenSlots;
|
||||
const UInt32 kFixedMainTableSize = kSymbolMatch + kFixedLenTableSize;
|
||||
|
||||
const UInt32 kLevelTableSize = 19;
|
||||
|
||||
const UInt32 kTableDirectLevels = 16;
|
||||
const UInt32 kTableLevelRepNumber = kTableDirectLevels;
|
||||
const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1;
|
||||
const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1;
|
||||
|
||||
const UInt32 kLevelMask = 0xF;
|
||||
|
||||
const Byte kLenStart32[kFixedLenTableSize] =
|
||||
{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, 0, 0};
|
||||
const Byte kLenStart64[kFixedLenTableSize] =
|
||||
{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, 0, 0};
|
||||
|
||||
const Byte kLenDirectBits32[kFixedLenTableSize] =
|
||||
{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, 0, 0};
|
||||
const Byte kLenDirectBits64[kFixedLenTableSize] =
|
||||
{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, 0, 0};
|
||||
|
||||
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] =
|
||||
{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[3] = {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 UInt32 kMatchMinLen = 3;
|
||||
const UInt32 kMatchMaxLen32 = kNumLenSymbols32 + kMatchMinLen - 1; //256 + 2
|
||||
const UInt32 kMatchMaxLen64 = kNumLenSymbols64 + kMatchMinLen - 1; //255 + 2
|
||||
const UInt32 kMatchMaxLen = kMatchMaxLen32;
|
||||
|
||||
const int kFinalBlockFieldSize = 1;
|
||||
|
||||
namespace NFinalBlockField
|
||||
{
|
||||
enum
|
||||
{
|
||||
kNotFinalBlock = 0,
|
||||
kFinalBlock = 1
|
||||
};
|
||||
}
|
||||
|
||||
const int kBlockTypeFieldSize = 2;
|
||||
|
||||
namespace NBlockType
|
||||
{
|
||||
enum
|
||||
{
|
||||
kStored = 0,
|
||||
kFixedHuffman = 1,
|
||||
kDynamicHuffman = 2
|
||||
};
|
||||
}
|
||||
|
||||
const int kNumLenCodesFieldSize = 5;
|
||||
const int kNumDistCodesFieldSize = 5;
|
||||
const int kNumLevelCodesFieldSize = 4;
|
||||
|
||||
const UInt32 kNumLitLenCodesMin = 257;
|
||||
const UInt32 kNumDistCodesMin = 1;
|
||||
const UInt32 kNumLevelCodesMin = 4;
|
||||
|
||||
const int kLevelFieldSize = 3;
|
||||
|
||||
const int kStoredBlockLengthFieldSize = 16;
|
||||
|
||||
struct CLevels
|
||||
{
|
||||
Byte litLenLevels[kFixedMainTableSize];
|
||||
Byte distLevels[kFixedDistTableSize];
|
||||
|
||||
void SubClear()
|
||||
{
|
||||
UInt32 i;
|
||||
for(i = kNumLitLenCodesMin; i < kFixedMainTableSize; i++)
|
||||
litLenLevels[i] = 0;
|
||||
for(i = 0; i < kFixedDistTableSize; i++)
|
||||
distLevels[i] = 0;
|
||||
}
|
||||
|
||||
void SetFixedLevels()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 144; i++)
|
||||
litLenLevels[i] = 8;
|
||||
for (; i < 256; i++)
|
||||
litLenLevels[i] = 9;
|
||||
for (; i < 280; i++)
|
||||
litLenLevels[i] = 7;
|
||||
for (; i < 288; i++)
|
||||
litLenLevels[i] = 8;
|
||||
for (i = 0; i < kFixedDistTableSize; i++) // test it: InfoZip only uses kDistTableSize
|
||||
distLevels[i] = 5;
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
339
CPP/7zip/Compress/Deflate/DeflateDecoder.cpp
Executable file
339
CPP/7zip/Compress/Deflate/DeflateDecoder.cpp
Executable file
@@ -0,0 +1,339 @@
|
||||
// DeflateDecoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "DeflateDecoder.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
namespace NDecoder {
|
||||
|
||||
static const int kLenIdFinished = -1;
|
||||
static const int kLenIdNeedInit = -2;
|
||||
|
||||
CCoder::CCoder(bool deflate64Mode, bool deflateNSIS):
|
||||
_deflate64Mode(deflate64Mode),
|
||||
_deflateNSIS(deflateNSIS),
|
||||
_keepHistory(false) {}
|
||||
|
||||
UInt32 CCoder::ReadBits(int numBits)
|
||||
{
|
||||
return m_InBitStream.ReadBits(numBits);
|
||||
}
|
||||
|
||||
bool CCoder::DeCodeLevelTable(Byte *values, int numSymbols)
|
||||
{
|
||||
int i = 0;
|
||||
do
|
||||
{
|
||||
UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number < kTableDirectLevels)
|
||||
values[i++] = (Byte)number;
|
||||
else if (number < kLevelTableSize)
|
||||
{
|
||||
if (number == kTableLevelRepNumber)
|
||||
{
|
||||
if (i == 0)
|
||||
return false;
|
||||
int num = ReadBits(2) + 3;
|
||||
for (; num > 0 && i < numSymbols; num--, i++)
|
||||
values[i] = values[i - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
int num;
|
||||
if (number == kTableLevel0Number)
|
||||
num = ReadBits(3) + 3;
|
||||
else
|
||||
num = ReadBits(7) + 11;
|
||||
for (;num > 0 && i < numSymbols; num--)
|
||||
values[i++] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
while(i < numSymbols);
|
||||
return true;
|
||||
}
|
||||
|
||||
#define RIF(x) { if (!(x)) return false; }
|
||||
|
||||
bool CCoder::ReadTables(void)
|
||||
{
|
||||
m_FinalBlock = (ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock);
|
||||
UInt32 blockType = ReadBits(kBlockTypeFieldSize);
|
||||
if (blockType > NBlockType::kDynamicHuffman)
|
||||
return false;
|
||||
|
||||
if (blockType == NBlockType::kStored)
|
||||
{
|
||||
m_StoredMode = true;
|
||||
UInt32 currentBitPosition = m_InBitStream.GetBitPosition();
|
||||
int numBitsForAlign = (int)(currentBitPosition > 0 ? (8 - currentBitPosition): 0);
|
||||
ReadBits(numBitsForAlign);
|
||||
m_StoredBlockSize = ReadBits(kStoredBlockLengthFieldSize);
|
||||
if (_deflateNSIS)
|
||||
return true;
|
||||
return (m_StoredBlockSize == (UInt16)~ReadBits(kStoredBlockLengthFieldSize));
|
||||
}
|
||||
|
||||
m_StoredMode = false;
|
||||
|
||||
CLevels levels;
|
||||
if (blockType == NBlockType::kFixedHuffman)
|
||||
{
|
||||
levels.SetFixedLevels();
|
||||
_numDistLevels = _deflate64Mode ? kDistTableSize64 : kDistTableSize32;
|
||||
}
|
||||
else
|
||||
{
|
||||
int numLitLenLevels = ReadBits(kNumLenCodesFieldSize) + kNumLitLenCodesMin;
|
||||
_numDistLevels = ReadBits(kNumDistCodesFieldSize) + kNumDistCodesMin;
|
||||
int numLevelCodes = ReadBits(kNumLevelCodesFieldSize) + kNumLevelCodesMin;
|
||||
|
||||
if (!_deflate64Mode)
|
||||
if (_numDistLevels > kDistTableSize32)
|
||||
return false;
|
||||
|
||||
Byte levelLevels[kLevelTableSize];
|
||||
for (int i = 0; i < kLevelTableSize; i++)
|
||||
{
|
||||
int position = kCodeLengthAlphabetOrder[i];
|
||||
if(i < numLevelCodes)
|
||||
levelLevels[position] = (Byte)ReadBits(kLevelFieldSize);
|
||||
else
|
||||
levelLevels[position] = 0;
|
||||
}
|
||||
|
||||
RIF(m_LevelDecoder.SetCodeLengths(levelLevels));
|
||||
|
||||
Byte tmpLevels[kFixedMainTableSize + kFixedDistTableSize];
|
||||
if (!DeCodeLevelTable(tmpLevels, numLitLenLevels + _numDistLevels))
|
||||
return false;
|
||||
|
||||
levels.SubClear();
|
||||
memcpy(levels.litLenLevels, tmpLevels, numLitLenLevels);
|
||||
memcpy(levels.distLevels, tmpLevels + numLitLenLevels, _numDistLevels);
|
||||
}
|
||||
RIF(m_MainDecoder.SetCodeLengths(levels.litLenLevels));
|
||||
return m_DistDecoder.SetCodeLengths(levels.distLevels);
|
||||
}
|
||||
|
||||
HRESULT CCoder::CodeSpec(UInt32 curSize)
|
||||
{
|
||||
if (_remainLen == kLenIdFinished)
|
||||
return S_OK;
|
||||
if (_remainLen == kLenIdNeedInit)
|
||||
{
|
||||
if (!_keepHistory)
|
||||
if (!m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!m_InBitStream.Create(1 << 17))
|
||||
return E_OUTOFMEMORY;
|
||||
m_OutWindowStream.Init(_keepHistory);
|
||||
m_InBitStream.Init();
|
||||
m_FinalBlock = false;
|
||||
_remainLen = 0;
|
||||
_needReadTable = true;
|
||||
}
|
||||
|
||||
if (curSize == 0)
|
||||
return S_OK;
|
||||
|
||||
while(_remainLen > 0 && curSize > 0)
|
||||
{
|
||||
_remainLen--;
|
||||
Byte b = m_OutWindowStream.GetByte(_rep0);
|
||||
m_OutWindowStream.PutByte(b);
|
||||
curSize--;
|
||||
}
|
||||
|
||||
while(curSize > 0)
|
||||
{
|
||||
if (_needReadTable)
|
||||
{
|
||||
if (m_FinalBlock)
|
||||
{
|
||||
_remainLen = kLenIdFinished;
|
||||
break;
|
||||
}
|
||||
if (!ReadTables())
|
||||
return S_FALSE;
|
||||
_needReadTable = false;
|
||||
}
|
||||
|
||||
if(m_StoredMode)
|
||||
{
|
||||
for (; m_StoredBlockSize > 0 && curSize > 0; m_StoredBlockSize--, curSize--)
|
||||
m_OutWindowStream.PutByte((Byte)m_InBitStream.ReadBits(8));
|
||||
_needReadTable = (m_StoredBlockSize == 0);
|
||||
continue;
|
||||
}
|
||||
while(curSize > 0)
|
||||
{
|
||||
if (m_InBitStream.NumExtraBytes > 4)
|
||||
return S_FALSE;
|
||||
|
||||
UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number < 0x100)
|
||||
{
|
||||
m_OutWindowStream.PutByte((Byte)number);
|
||||
curSize--;
|
||||
continue;
|
||||
}
|
||||
else if (number == kSymbolEndOfBlock)
|
||||
{
|
||||
_needReadTable = true;
|
||||
break;
|
||||
}
|
||||
else if (number < kMainTableSize)
|
||||
{
|
||||
number -= kSymbolMatch;
|
||||
UInt32 len;
|
||||
{
|
||||
int numBits;
|
||||
if (_deflate64Mode)
|
||||
{
|
||||
len = kLenStart64[number];
|
||||
numBits = kLenDirectBits64[number];
|
||||
}
|
||||
else
|
||||
{
|
||||
len = kLenStart32[number];
|
||||
numBits = kLenDirectBits32[number];
|
||||
}
|
||||
len += kMatchMinLen + m_InBitStream.ReadBits(numBits);
|
||||
}
|
||||
UInt32 locLen = len;
|
||||
if (locLen > curSize)
|
||||
locLen = (UInt32)curSize;
|
||||
number = m_DistDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number >= _numDistLevels)
|
||||
return S_FALSE;
|
||||
UInt32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]);
|
||||
if (!m_OutWindowStream.CopyBlock(distance, locLen))
|
||||
return S_FALSE;
|
||||
curSize -= locLen;
|
||||
len -= locLen;
|
||||
if (len != 0)
|
||||
{
|
||||
_remainLen = (Int32)len;
|
||||
_rep0 = distance;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UInt64 *, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
SetInStream(inStream);
|
||||
m_OutWindowStream.SetStream(outStream);
|
||||
SetOutStreamSize(outSize);
|
||||
CCoderReleaser flusher(this);
|
||||
|
||||
const UInt64 start = m_OutWindowStream.GetProcessedSize();
|
||||
for (;;)
|
||||
{
|
||||
UInt32 curSize = 1 << 18;
|
||||
if (outSize != 0)
|
||||
{
|
||||
const UInt64 rem = *outSize - (m_OutWindowStream.GetProcessedSize() - start);
|
||||
if (curSize > rem)
|
||||
curSize = (UInt32)rem;
|
||||
}
|
||||
if (curSize == 0)
|
||||
break;
|
||||
RINOK(CodeSpec(curSize));
|
||||
if (_remainLen == kLenIdFinished)
|
||||
break;
|
||||
if (progress != NULL)
|
||||
{
|
||||
const UInt64 inSize = m_InBitStream.GetProcessedSize();
|
||||
const UInt64 nowPos64 = m_OutWindowStream.GetProcessedSize() - start;
|
||||
RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
|
||||
}
|
||||
}
|
||||
flusher.NeedFlush = false;
|
||||
return Flush();
|
||||
}
|
||||
|
||||
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
|
||||
#define DEFLATE_TRY_BEGIN
|
||||
#define DEFLATE_TRY_END
|
||||
|
||||
#else
|
||||
|
||||
#define DEFLATE_TRY_BEGIN try {
|
||||
#define DEFLATE_TRY_END } \
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; } \
|
||||
catch(const CLZOutWindowException &e) { return e.ErrorCode; } \
|
||||
catch(...) { return S_FALSE; }
|
||||
|
||||
#endif
|
||||
|
||||
HRESULT CCoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
DEFLATE_TRY_BEGIN
|
||||
return CodeReal(inStream, outStream, inSize, outSize, progress);
|
||||
DEFLATE_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoder::GetInStreamProcessedSize(UInt64 *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
return E_INVALIDARG;
|
||||
*value = m_InBitStream.GetProcessedSize();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoder::SetInStream(ISequentialInStream *inStream)
|
||||
{
|
||||
m_InBitStream.SetStream(inStream);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoder::ReleaseInStream()
|
||||
{
|
||||
m_InBitStream.ReleaseStream();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoder::SetOutStreamSize(const UInt64 * /* outSize */)
|
||||
{
|
||||
_remainLen = kLenIdNeedInit;
|
||||
m_OutWindowStream.Init(_keepHistory);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifdef _ST_MODE
|
||||
|
||||
STDMETHODIMP CCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
DEFLATE_TRY_BEGIN
|
||||
if (processedSize)
|
||||
*processedSize = 0;
|
||||
const UInt64 startPos = m_OutWindowStream.GetProcessedSize();
|
||||
m_OutWindowStream.SetMemStream((Byte *)data);
|
||||
RINOK(CodeSpec(size));
|
||||
if (processedSize)
|
||||
*processedSize = (UInt32)(m_OutWindowStream.GetProcessedSize() - startPos);
|
||||
return Flush();
|
||||
DEFLATE_TRY_END
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}}}
|
||||
134
CPP/7zip/Compress/Deflate/DeflateDecoder.h
Executable file
134
CPP/7zip/Compress/Deflate/DeflateDecoder.h
Executable file
@@ -0,0 +1,134 @@
|
||||
// DeflateDecoder.h
|
||||
|
||||
#ifndef __DEFLATE_DECODER_H
|
||||
#define __DEFLATE_DECODER_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/LSBFDecoder.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
#include "../LZ/LZOutWindow.h"
|
||||
#include "../Huffman/HuffmanDecoder.h"
|
||||
|
||||
#include "DeflateConst.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
namespace NDecoder {
|
||||
|
||||
class CCoder:
|
||||
public ICompressCoder,
|
||||
public ICompressGetInStreamProcessedSize,
|
||||
#ifdef _ST_MODE
|
||||
public ICompressSetInStream,
|
||||
public ICompressSetOutStreamSize,
|
||||
public ISequentialInStream,
|
||||
#endif
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CLZOutWindow m_OutWindowStream;
|
||||
NStream::NLSBF::CDecoder<CInBuffer> m_InBitStream;
|
||||
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kFixedMainTableSize> m_MainDecoder;
|
||||
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kFixedDistTableSize> m_DistDecoder;
|
||||
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
|
||||
|
||||
UInt32 m_StoredBlockSize;
|
||||
|
||||
bool m_FinalBlock;
|
||||
bool m_StoredMode;
|
||||
UInt32 _numDistLevels;
|
||||
|
||||
|
||||
bool _deflateNSIS;
|
||||
bool _deflate64Mode;
|
||||
bool _keepHistory;
|
||||
Int32 _remainLen;
|
||||
UInt32 _rep0;
|
||||
bool _needReadTable;
|
||||
|
||||
UInt32 ReadBits(int numBits);
|
||||
|
||||
bool DeCodeLevelTable(Byte *values, int numSymbols);
|
||||
bool ReadTables();
|
||||
|
||||
void ReleaseStreams()
|
||||
{
|
||||
m_OutWindowStream.ReleaseStream();
|
||||
ReleaseInStream();
|
||||
}
|
||||
|
||||
HRESULT Flush() { return m_OutWindowStream.Flush(); }
|
||||
class CCoderReleaser
|
||||
{
|
||||
CCoder *m_Coder;
|
||||
public:
|
||||
bool NeedFlush;
|
||||
CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {}
|
||||
~CCoderReleaser()
|
||||
{
|
||||
if (NeedFlush)
|
||||
m_Coder->Flush();
|
||||
m_Coder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
friend class CCoderReleaser;
|
||||
|
||||
HRESULT CodeSpec(UInt32 curSize);
|
||||
public:
|
||||
CCoder(bool deflate64Mode, bool deflateNSIS = false);
|
||||
void SetKeepHistory(bool keepHistory) { _keepHistory = keepHistory; }
|
||||
|
||||
HRESULT CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
#ifdef _ST_MODE
|
||||
MY_UNKNOWN_IMP4(
|
||||
ICompressGetInStreamProcessedSize,
|
||||
ICompressSetInStream,
|
||||
ICompressSetOutStreamSize,
|
||||
ISequentialInStream
|
||||
)
|
||||
#else
|
||||
MY_UNKNOWN_IMP1(
|
||||
ICompressGetInStreamProcessedSize)
|
||||
#endif
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
|
||||
STDMETHOD(ReleaseInStream)();
|
||||
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
|
||||
|
||||
#ifdef _ST_MODE
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
#endif
|
||||
|
||||
// IGetInStreamProcessedSize
|
||||
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
|
||||
};
|
||||
|
||||
class CCOMCoder : public CCoder
|
||||
{
|
||||
public:
|
||||
CCOMCoder(): CCoder(false) {}
|
||||
};
|
||||
|
||||
class CNsisCOMCoder : public CCoder
|
||||
{
|
||||
public:
|
||||
CNsisCOMCoder(): CCoder(false, true) {}
|
||||
};
|
||||
|
||||
class CCOMCoder64 : public CCoder
|
||||
{
|
||||
public:
|
||||
CCOMCoder64(): CCoder(true) {}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
963
CPP/7zip/Compress/Deflate/DeflateEncoder.cpp
Executable file
963
CPP/7zip/Compress/Deflate/DeflateEncoder.cpp
Executable file
@@ -0,0 +1,963 @@
|
||||
// DeflateEncoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "DeflateEncoder.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "../../../Common/Alloc.h"
|
||||
// #include "../LZ/BinTree/BinTree3Z.h"
|
||||
|
||||
#if _MSC_VER >= 1300
|
||||
#define NO_INLINE __declspec(noinline)
|
||||
#else
|
||||
#define NO_INLINE
|
||||
#endif
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/Compress/Huffman/HuffmanEncode.h"
|
||||
}
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
namespace NEncoder {
|
||||
|
||||
const int kNumDivPassesMax = 10; // [0, 16); ratio/speed/ram tradeoff; use big value for better compression ratio.
|
||||
const UInt32 kNumTables = (1 << kNumDivPassesMax);
|
||||
|
||||
static UInt32 kFixedHuffmanCodeBlockSizeMax = (1 << 8); // [0, (1 << 32)); ratio/speed tradeoff; use big value for better compression ratio.
|
||||
static UInt32 kDivideCodeBlockSizeMin = (1 << 6); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio.
|
||||
static UInt32 kDivideBlockSizeMin = (1 << 6); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio.
|
||||
|
||||
static const UInt32 kMaxUncompressedBlockSize = ((1 << 16) - 1) * 1; // [1, (1 << 32))
|
||||
static const UInt32 kMatchArraySize = kMaxUncompressedBlockSize * 10; // [kMatchMaxLen * 2, (1 << 32))
|
||||
static const UInt32 kMatchArrayLimit = kMatchArraySize - kMatchMaxLen * 4 * sizeof(UInt16);
|
||||
static const UInt32 kBlockUncompressedSizeThreshold = kMaxUncompressedBlockSize -
|
||||
kMatchMaxLen - kNumOpts;
|
||||
|
||||
static const int kMaxCodeBitLength = 15;
|
||||
static const int kMaxLevelBitLength = 7;
|
||||
|
||||
static Byte kNoLiteralStatPrice = 13;
|
||||
static Byte kNoLenStatPrice = 13;
|
||||
static Byte kNoPosStatPrice = 6;
|
||||
|
||||
static Byte g_LenSlots[kNumLenSymbolsMax];
|
||||
static Byte g_FastPos[1 << 9];
|
||||
|
||||
class CFastPosInit
|
||||
{
|
||||
public:
|
||||
CFastPosInit()
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < kNumLenSlots; i++)
|
||||
{
|
||||
int c = kLenStart32[i];
|
||||
int j = 1 << kLenDirectBits32[i];
|
||||
for(int k = 0; k < j; k++, c++)
|
||||
g_LenSlots[c] = (Byte)i;
|
||||
}
|
||||
|
||||
const int kFastSlots = 18;
|
||||
int c = 0;
|
||||
for (Byte slotFast = 0; slotFast < kFastSlots; slotFast++)
|
||||
{
|
||||
UInt32 k = (1 << kDistDirectBits[slotFast]);
|
||||
for (UInt32 j = 0; j < k; j++, c++)
|
||||
g_FastPos[c] = slotFast;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static CFastPosInit g_FastPosInit;
|
||||
|
||||
|
||||
inline UInt32 GetPosSlot(UInt32 pos)
|
||||
{
|
||||
if (pos < 0x200)
|
||||
return g_FastPos[pos];
|
||||
return g_FastPos[pos >> 8] + 16;
|
||||
}
|
||||
|
||||
void *SzAlloc(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void SzFree(void *address)
|
||||
{
|
||||
free(address);
|
||||
}
|
||||
|
||||
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||
|
||||
CCoder::CCoder(bool deflate64Mode):
|
||||
m_Deflate64Mode(deflate64Mode),
|
||||
m_NumPasses(1),
|
||||
m_NumDivPasses(1),
|
||||
m_NumFastBytes(32),
|
||||
m_OnePosMatchesMemory(0),
|
||||
m_DistanceMemory(0),
|
||||
m_Created(false),
|
||||
m_Values(0),
|
||||
m_Tables(0),
|
||||
m_MatchFinderCycles(0)
|
||||
// m_SetMfPasses(0)
|
||||
{
|
||||
m_MatchMaxLen = deflate64Mode ? kMatchMaxLen64 : kMatchMaxLen32;
|
||||
m_NumLenCombinations = deflate64Mode ? kNumLenSymbols64 : kNumLenSymbols32;
|
||||
m_LenStart = deflate64Mode ? kLenStart64 : kLenStart32;
|
||||
m_LenDirectBits = deflate64Mode ? kLenDirectBits64 : kLenDirectBits32;
|
||||
MatchFinder_Construct(&_lzInWindow);
|
||||
}
|
||||
|
||||
HRESULT CCoder::Create()
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
if (m_Values == 0)
|
||||
{
|
||||
m_Values = (CCodeValue *)MyAlloc((kMaxUncompressedBlockSize) * sizeof(CCodeValue));
|
||||
if (m_Values == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (m_Tables == 0)
|
||||
{
|
||||
m_Tables = (CTables *)MyAlloc((kNumTables) * sizeof(CTables));
|
||||
if (m_Tables == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (m_IsMultiPass)
|
||||
{
|
||||
if (m_OnePosMatchesMemory == 0)
|
||||
{
|
||||
m_OnePosMatchesMemory = (UInt16 *)::MidAlloc(kMatchArraySize * sizeof(UInt16));
|
||||
if (m_OnePosMatchesMemory == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_DistanceMemory == 0)
|
||||
{
|
||||
m_DistanceMemory = (UInt16 *)MyAlloc((kMatchMaxLen + 2) * 2 * sizeof(UInt16));
|
||||
if (m_DistanceMemory == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
m_MatchDistances = m_DistanceMemory;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_Created)
|
||||
{
|
||||
_lzInWindow.btMode = 1;
|
||||
_lzInWindow.numHashBytes = 3;
|
||||
if (!MatchFinder_Create(&_lzInWindow,
|
||||
m_Deflate64Mode ? kHistorySize64 : kHistorySize32,
|
||||
kNumOpts + kMaxUncompressedBlockSize,
|
||||
m_NumFastBytes, m_MatchMaxLen - m_NumFastBytes, &g_Alloc))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!m_OutStream.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (m_MatchFinderCycles != 0)
|
||||
_lzInWindow.cutValue = m_MatchFinderCycles;
|
||||
m_Created = true;
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
// ICompressSetEncoderProperties2
|
||||
HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties)
|
||||
{
|
||||
for(UInt32 i = 0; i < numProperties; i++)
|
||||
{
|
||||
const PROPVARIANT &prop = properties[i];
|
||||
switch(propIDs[i])
|
||||
{
|
||||
case NCoderPropID::kNumPasses:
|
||||
if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
m_NumDivPasses = prop.ulVal;
|
||||
if (m_NumDivPasses == 0)
|
||||
m_NumDivPasses = 1;
|
||||
if (m_NumDivPasses == 1)
|
||||
m_NumPasses = 1;
|
||||
else if (m_NumDivPasses <= kNumDivPassesMax)
|
||||
m_NumPasses = 2;
|
||||
else
|
||||
{
|
||||
m_NumPasses = 2 + (m_NumDivPasses - kNumDivPassesMax);
|
||||
m_NumDivPasses = kNumDivPassesMax;
|
||||
}
|
||||
break;
|
||||
case NCoderPropID::kNumFastBytes:
|
||||
if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
m_NumFastBytes = prop.ulVal;
|
||||
if(m_NumFastBytes < kMatchMinLen || m_NumFastBytes > m_MatchMaxLen)
|
||||
return E_INVALIDARG;
|
||||
break;
|
||||
case NCoderPropID::kMatchFinderCycles:
|
||||
{
|
||||
if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
m_MatchFinderCycles = prop.ulVal;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CCoder::Free()
|
||||
{
|
||||
::MidFree(m_OnePosMatchesMemory);
|
||||
m_OnePosMatchesMemory = 0;
|
||||
::MyFree(m_DistanceMemory);
|
||||
m_DistanceMemory = 0;
|
||||
::MyFree(m_Values);
|
||||
m_Values = 0;
|
||||
::MyFree(m_Tables);
|
||||
m_Tables = 0;
|
||||
}
|
||||
|
||||
CCoder::~CCoder()
|
||||
{
|
||||
Free();
|
||||
MatchFinder_Free(&_lzInWindow, &g_Alloc);
|
||||
}
|
||||
|
||||
void CCoder::GetMatches()
|
||||
{
|
||||
if (m_IsMultiPass)
|
||||
{
|
||||
m_MatchDistances = m_OnePosMatchesMemory + m_Pos;
|
||||
if (m_SecondPass)
|
||||
{
|
||||
m_Pos += *m_MatchDistances + 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 distanceTmp[kMatchMaxLen * 2 + 3];
|
||||
|
||||
UInt32 numPairs = Bt3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp);
|
||||
*m_MatchDistances = (UInt16)numPairs;
|
||||
|
||||
if (numPairs > 0)
|
||||
{
|
||||
UInt32 i;
|
||||
for(i = 0; i < numPairs; i += 2)
|
||||
{
|
||||
m_MatchDistances[i + 1] = (UInt16)distanceTmp[i];
|
||||
m_MatchDistances[i + 2] = (UInt16)distanceTmp[i + 1];
|
||||
}
|
||||
UInt32 len = distanceTmp[numPairs - 2];
|
||||
if (len == m_NumFastBytes && m_NumFastBytes != m_MatchMaxLen)
|
||||
{
|
||||
UInt32 numAvail = Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) + 1;
|
||||
const Byte *pby = Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) - 1;
|
||||
UInt32 distance = distanceTmp[numPairs - 1] + 1;
|
||||
if (numAvail > m_MatchMaxLen)
|
||||
numAvail = m_MatchMaxLen;
|
||||
for (; len < numAvail && pby[len] == pby[(size_t)len - distance]; len++);
|
||||
m_MatchDistances[i - 1] = (UInt16)len;
|
||||
}
|
||||
}
|
||||
if (m_IsMultiPass)
|
||||
m_Pos += numPairs + 1;
|
||||
if (!m_SecondPass)
|
||||
m_AdditionalOffset++;
|
||||
}
|
||||
|
||||
void CCoder::MovePos(UInt32 num)
|
||||
{
|
||||
if (!m_SecondPass && num > 0)
|
||||
{
|
||||
Bt3Zip_MatchFinder_Skip(&_lzInWindow, num);
|
||||
m_AdditionalOffset += num;
|
||||
}
|
||||
}
|
||||
|
||||
static const UInt32 kIfinityPrice = 0xFFFFFFF;
|
||||
|
||||
NO_INLINE UInt32 CCoder::Backward(UInt32 &backRes, UInt32 cur)
|
||||
{
|
||||
m_OptimumEndIndex = cur;
|
||||
UInt32 posMem = m_Optimum[cur].PosPrev;
|
||||
UInt16 backMem = m_Optimum[cur].BackPrev;
|
||||
do
|
||||
{
|
||||
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 = (UInt16)cur;
|
||||
cur = posPrev;
|
||||
}
|
||||
while(cur > 0);
|
||||
backRes = m_Optimum[0].BackPrev;
|
||||
m_OptimumCurrentIndex = m_Optimum[0].PosPrev;
|
||||
return m_OptimumCurrentIndex;
|
||||
}
|
||||
|
||||
NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes)
|
||||
{
|
||||
if(m_OptimumEndIndex != 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;
|
||||
}
|
||||
m_OptimumCurrentIndex = m_OptimumEndIndex = 0;
|
||||
|
||||
GetMatches();
|
||||
|
||||
UInt32 numDistancePairs = m_MatchDistances[0];
|
||||
if(numDistancePairs == 0)
|
||||
return 1;
|
||||
|
||||
const UInt16 *matchDistances = m_MatchDistances + 1;
|
||||
UInt32 lenMain = matchDistances[numDistancePairs - 2];
|
||||
|
||||
if(lenMain > m_NumFastBytes)
|
||||
{
|
||||
backRes = matchDistances[numDistancePairs - 1];
|
||||
MovePos(lenMain - 1);
|
||||
return lenMain;
|
||||
}
|
||||
m_Optimum[1].Price = m_LiteralPrices[Inline_MatchFinder_GetIndexByte(&_lzInWindow, 0 - m_AdditionalOffset)];
|
||||
m_Optimum[1].PosPrev = 0;
|
||||
|
||||
m_Optimum[2].Price = kIfinityPrice;
|
||||
m_Optimum[2].PosPrev = 1;
|
||||
|
||||
|
||||
UInt32 offs = 0;
|
||||
for(UInt32 i = kMatchMinLen; i <= lenMain; i++)
|
||||
{
|
||||
UInt32 distance = matchDistances[offs + 1];
|
||||
m_Optimum[i].PosPrev = 0;
|
||||
m_Optimum[i].BackPrev = (UInt16)distance;
|
||||
m_Optimum[i].Price = m_LenPrices[i - kMatchMinLen] + m_PosPrices[GetPosSlot(distance)];
|
||||
if (i == matchDistances[offs])
|
||||
offs += 2;
|
||||
}
|
||||
|
||||
UInt32 cur = 0;
|
||||
UInt32 lenEnd = lenMain;
|
||||
for (;;)
|
||||
{
|
||||
++cur;
|
||||
if(cur == lenEnd || cur == kNumOptsBase || m_Pos >= kMatchArrayLimit)
|
||||
return Backward(backRes, cur);
|
||||
GetMatches();
|
||||
matchDistances = m_MatchDistances + 1;
|
||||
|
||||
UInt32 numDistancePairs = m_MatchDistances[0];
|
||||
UInt32 newLen = 0;
|
||||
if(numDistancePairs != 0)
|
||||
{
|
||||
newLen = matchDistances[numDistancePairs - 2];
|
||||
if(newLen > m_NumFastBytes)
|
||||
{
|
||||
UInt32 len = Backward(backRes, cur);
|
||||
m_Optimum[cur].BackPrev = matchDistances[numDistancePairs - 1];
|
||||
m_OptimumEndIndex = cur + newLen;
|
||||
m_Optimum[cur].PosPrev = (UInt16)m_OptimumEndIndex;
|
||||
MovePos(newLen - 1);
|
||||
return len;
|
||||
}
|
||||
}
|
||||
UInt32 curPrice = m_Optimum[cur].Price;
|
||||
UInt32 curAnd1Price = curPrice + m_LiteralPrices[Inline_MatchFinder_GetIndexByte(&_lzInWindow, cur - m_AdditionalOffset)];
|
||||
COptimal &optimum = m_Optimum[cur + 1];
|
||||
if (curAnd1Price < optimum.Price)
|
||||
{
|
||||
optimum.Price = curAnd1Price;
|
||||
optimum.PosPrev = (UInt16)cur;
|
||||
}
|
||||
if(numDistancePairs == 0)
|
||||
continue;
|
||||
while(lenEnd < cur + newLen)
|
||||
m_Optimum[++lenEnd].Price = kIfinityPrice;
|
||||
offs = 0;
|
||||
UInt32 distance = matchDistances[offs + 1];
|
||||
curPrice += m_PosPrices[GetPosSlot(distance)];
|
||||
for(UInt32 lenTest = kMatchMinLen; ; lenTest++)
|
||||
{
|
||||
UInt32 curAndLenPrice = curPrice + m_LenPrices[lenTest - kMatchMinLen];
|
||||
COptimal &optimum = m_Optimum[cur + lenTest];
|
||||
if (curAndLenPrice < optimum.Price)
|
||||
{
|
||||
optimum.Price = curAndLenPrice;
|
||||
optimum.PosPrev = (UInt16)cur;
|
||||
optimum.BackPrev = (UInt16)distance;
|
||||
}
|
||||
if (lenTest == matchDistances[offs])
|
||||
{
|
||||
offs += 2;
|
||||
if (offs == numDistancePairs)
|
||||
break;
|
||||
curPrice -= m_PosPrices[GetPosSlot(distance)];
|
||||
distance = matchDistances[offs + 1];
|
||||
curPrice += m_PosPrices[GetPosSlot(distance)];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CTables::InitStructures()
|
||||
{
|
||||
UInt32 i;
|
||||
for(i = 0; i < 256; i++)
|
||||
litLenLevels[i] = 8;
|
||||
litLenLevels[i++] = 13;
|
||||
for(;i < kFixedMainTableSize; i++)
|
||||
litLenLevels[i] = 5;
|
||||
for(i = 0; i < kFixedDistTableSize; i++)
|
||||
distLevels[i] = 5;
|
||||
}
|
||||
|
||||
NO_INLINE void CCoder::LevelTableDummy(const Byte *levels, int numLevels, UInt32 *freqs)
|
||||
{
|
||||
int prevLen = 0xFF;
|
||||
int nextLen = levels[0];
|
||||
int count = 0;
|
||||
int maxCount = 7;
|
||||
int minCount = 4;
|
||||
if (nextLen == 0)
|
||||
{
|
||||
maxCount = 138;
|
||||
minCount = 3;
|
||||
}
|
||||
for (int n = 0; n < numLevels; n++)
|
||||
{
|
||||
int curLen = nextLen;
|
||||
nextLen = (n < numLevels - 1) ? levels[n + 1] : 0xFF;
|
||||
count++;
|
||||
if (count < maxCount && curLen == nextLen)
|
||||
continue;
|
||||
|
||||
if (count < minCount)
|
||||
freqs[curLen] += (UInt32)count;
|
||||
else if (curLen != 0)
|
||||
{
|
||||
if (curLen != prevLen)
|
||||
{
|
||||
freqs[curLen]++;
|
||||
count--;
|
||||
}
|
||||
freqs[kTableLevelRepNumber]++;
|
||||
}
|
||||
else if (count <= 10)
|
||||
freqs[kTableLevel0Number]++;
|
||||
else
|
||||
freqs[kTableLevel0Number2]++;
|
||||
|
||||
count = 0;
|
||||
prevLen = curLen;
|
||||
|
||||
if (nextLen == 0)
|
||||
{
|
||||
maxCount = 138;
|
||||
minCount = 3;
|
||||
}
|
||||
else if (curLen == nextLen)
|
||||
{
|
||||
maxCount = 6;
|
||||
minCount = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxCount = 7;
|
||||
minCount = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define WRITE_HF2(codes, lens, i) m_OutStream.WriteBits(codes[i], lens[i])
|
||||
#define WRITE_HF(i) m_OutStream.WriteBits(codes[i], lens[i])
|
||||
|
||||
NO_INLINE void CCoder::LevelTableCode(const Byte *levels, int numLevels, const Byte *lens, const UInt32 *codes)
|
||||
{
|
||||
int prevLen = 0xFF;
|
||||
int nextLen = levels[0];
|
||||
int count = 0;
|
||||
int maxCount = 7;
|
||||
int minCount = 4;
|
||||
if (nextLen == 0)
|
||||
{
|
||||
maxCount = 138;
|
||||
minCount = 3;
|
||||
}
|
||||
for (int n = 0; n < numLevels; n++)
|
||||
{
|
||||
int curLen = nextLen;
|
||||
nextLen = (n < numLevels - 1) ? levels[n + 1] : 0xFF;
|
||||
count++;
|
||||
if (count < maxCount && curLen == nextLen)
|
||||
continue;
|
||||
|
||||
if (count < minCount)
|
||||
for(int i = 0; i < count; i++)
|
||||
WRITE_HF(curLen);
|
||||
else if (curLen != 0)
|
||||
{
|
||||
if (curLen != prevLen)
|
||||
{
|
||||
WRITE_HF(curLen);
|
||||
count--;
|
||||
}
|
||||
WRITE_HF(kTableLevelRepNumber);
|
||||
m_OutStream.WriteBits(count - 3, 2);
|
||||
}
|
||||
else if (count <= 10)
|
||||
{
|
||||
WRITE_HF(kTableLevel0Number);
|
||||
m_OutStream.WriteBits(count - 3, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE_HF(kTableLevel0Number2);
|
||||
m_OutStream.WriteBits(count - 11, 7);
|
||||
}
|
||||
|
||||
count = 0;
|
||||
prevLen = curLen;
|
||||
|
||||
if (nextLen == 0)
|
||||
{
|
||||
maxCount = 138;
|
||||
minCount = 3;
|
||||
}
|
||||
else if (curLen == nextLen)
|
||||
{
|
||||
maxCount = 6;
|
||||
minCount = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxCount = 7;
|
||||
minCount = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NO_INLINE void CCoder::MakeTables()
|
||||
{
|
||||
Huffman_Generate(mainFreqs, mainCodes, m_NewLevels.litLenLevels, kFixedMainTableSize, kMaxCodeBitLength);
|
||||
Huffman_Generate(distFreqs, distCodes, m_NewLevels.distLevels, kDistTableSize64, kMaxCodeBitLength);
|
||||
}
|
||||
|
||||
NO_INLINE UInt32 Huffman_GetPrice(const UInt32 *freqs, const Byte *lens, UInt32 num)
|
||||
{
|
||||
UInt32 price = 0;
|
||||
UInt32 i;
|
||||
for (i = 0; i < num; i++)
|
||||
price += lens[i] * freqs[i];
|
||||
return price;
|
||||
};
|
||||
|
||||
NO_INLINE UInt32 Huffman_GetPrice_Spec(const UInt32 *freqs, const Byte *lens, UInt32 num, const Byte *extraBits, UInt32 extraBase)
|
||||
{
|
||||
return Huffman_GetPrice(freqs, lens, num) +
|
||||
Huffman_GetPrice(freqs + extraBase, extraBits, num - extraBase);
|
||||
}
|
||||
|
||||
NO_INLINE UInt32 CCoder::GetLzBlockPrice() const
|
||||
{
|
||||
return
|
||||
Huffman_GetPrice_Spec(mainFreqs, m_NewLevels.litLenLevels, kFixedMainTableSize, m_LenDirectBits, kSymbolMatch) +
|
||||
Huffman_GetPrice_Spec(distFreqs, m_NewLevels.distLevels, kDistTableSize64, kDistDirectBits, 0);
|
||||
}
|
||||
|
||||
NO_INLINE void CCoder::TryBlock()
|
||||
{
|
||||
memset(mainFreqs, 0, sizeof(mainFreqs));
|
||||
memset(distFreqs, 0, sizeof(distFreqs));
|
||||
|
||||
m_ValueIndex = 0;
|
||||
UInt32 blockSize = BlockSizeRes;
|
||||
BlockSizeRes = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (m_OptimumCurrentIndex == m_OptimumEndIndex)
|
||||
{
|
||||
if (m_Pos >= kMatchArrayLimit || BlockSizeRes >= blockSize || !m_SecondPass &&
|
||||
((Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) == 0) || m_ValueIndex >= m_ValueBlockSize))
|
||||
break;
|
||||
}
|
||||
UInt32 pos;
|
||||
UInt32 len = GetOptimal(pos);
|
||||
CCodeValue &codeValue = m_Values[m_ValueIndex++];
|
||||
if (len >= kMatchMinLen)
|
||||
{
|
||||
UInt32 newLen = len - kMatchMinLen;
|
||||
codeValue.Len = (UInt16)newLen;
|
||||
mainFreqs[kSymbolMatch + g_LenSlots[newLen]]++;
|
||||
codeValue.Pos = (UInt16)pos;
|
||||
distFreqs[GetPosSlot(pos)]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Byte b = Inline_MatchFinder_GetIndexByte(&_lzInWindow, 0 - m_AdditionalOffset);
|
||||
mainFreqs[b]++;
|
||||
codeValue.SetAsLiteral();
|
||||
codeValue.Pos = b;
|
||||
}
|
||||
m_AdditionalOffset -= len;
|
||||
BlockSizeRes += len;
|
||||
}
|
||||
mainFreqs[kSymbolEndOfBlock]++;
|
||||
m_AdditionalOffset += BlockSizeRes;
|
||||
m_SecondPass = true;
|
||||
}
|
||||
|
||||
NO_INLINE void CCoder::SetPrices(const CLevels &levels)
|
||||
{
|
||||
UInt32 i;
|
||||
for(i = 0; i < 256; i++)
|
||||
{
|
||||
Byte price = levels.litLenLevels[i];
|
||||
m_LiteralPrices[i] = ((price != 0) ? price : kNoLiteralStatPrice);
|
||||
}
|
||||
|
||||
for(i = 0; i < m_NumLenCombinations; i++)
|
||||
{
|
||||
UInt32 slot = g_LenSlots[i];
|
||||
Byte price = levels.litLenLevels[kSymbolMatch + slot];
|
||||
m_LenPrices[i] = (Byte)(((price != 0) ? price : kNoLenStatPrice) + m_LenDirectBits[slot]);
|
||||
}
|
||||
|
||||
for(i = 0; i < kDistTableSize64; i++)
|
||||
{
|
||||
Byte price = levels.distLevels[i];
|
||||
m_PosPrices[i] = (Byte)(((price != 0) ? price: kNoPosStatPrice) + kDistDirectBits[i]);
|
||||
}
|
||||
}
|
||||
|
||||
NO_INLINE void Huffman_ReverseBits(UInt32 *codes, const Byte *lens, UInt32 num)
|
||||
{
|
||||
for (UInt32 i = 0; i < num; i++)
|
||||
{
|
||||
UInt32 x = codes[i];
|
||||
x = ((x & 0x5555) << 1) | ((x & 0xAAAA) >> 1);
|
||||
x = ((x & 0x3333) << 2) | ((x & 0xCCCC) >> 2);
|
||||
x = ((x & 0x0F0F) << 4) | ((x & 0xF0F0) >> 4);
|
||||
codes[i] = (((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8)) >> (16 - lens[i]);
|
||||
}
|
||||
}
|
||||
|
||||
NO_INLINE void CCoder::WriteBlock()
|
||||
{
|
||||
Huffman_ReverseBits(mainCodes, m_NewLevels.litLenLevels, kFixedMainTableSize);
|
||||
Huffman_ReverseBits(distCodes, m_NewLevels.distLevels, kDistTableSize64);
|
||||
|
||||
for (UInt32 i = 0; i < m_ValueIndex; i++)
|
||||
{
|
||||
const CCodeValue &codeValue = m_Values[i];
|
||||
if (codeValue.IsLiteral())
|
||||
WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, codeValue.Pos);
|
||||
else
|
||||
{
|
||||
UInt32 len = codeValue.Len;
|
||||
UInt32 lenSlot = g_LenSlots[len];
|
||||
WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, kSymbolMatch + lenSlot);
|
||||
m_OutStream.WriteBits(len - m_LenStart[lenSlot], m_LenDirectBits[lenSlot]);
|
||||
UInt32 dist = codeValue.Pos;
|
||||
UInt32 posSlot = GetPosSlot(dist);
|
||||
WRITE_HF2(distCodes, m_NewLevels.distLevels, posSlot);
|
||||
m_OutStream.WriteBits(dist - kDistStart[posSlot], kDistDirectBits[posSlot]);
|
||||
}
|
||||
}
|
||||
WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, kSymbolEndOfBlock);
|
||||
}
|
||||
|
||||
static UInt32 GetStorePrice(UInt32 blockSize, int bitPosition)
|
||||
{
|
||||
UInt32 price = 0;
|
||||
do
|
||||
{
|
||||
UInt32 nextBitPosition = (bitPosition + kFinalBlockFieldSize + kBlockTypeFieldSize) & 7;
|
||||
int numBitsForAlign = nextBitPosition > 0 ? (8 - nextBitPosition): 0;
|
||||
UInt32 curBlockSize = (blockSize < (1 << 16)) ? blockSize : (1 << 16) - 1;
|
||||
price += kFinalBlockFieldSize + kBlockTypeFieldSize + numBitsForAlign + (2 + 2) * 8 + curBlockSize * 8;
|
||||
bitPosition = 0;
|
||||
blockSize -= curBlockSize;
|
||||
}
|
||||
while(blockSize != 0);
|
||||
return price;
|
||||
}
|
||||
|
||||
void CCoder::WriteStoreBlock(UInt32 blockSize, UInt32 additionalOffset, bool finalBlock)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 curBlockSize = (blockSize < (1 << 16)) ? blockSize : (1 << 16) - 1;
|
||||
blockSize -= curBlockSize;
|
||||
m_OutStream.WriteBits((finalBlock && (blockSize == 0) ? NFinalBlockField::kFinalBlock: NFinalBlockField::kNotFinalBlock), kFinalBlockFieldSize);
|
||||
m_OutStream.WriteBits(NBlockType::kStored, kBlockTypeFieldSize);
|
||||
m_OutStream.FlushByte();
|
||||
m_OutStream.WriteBits((UInt16)curBlockSize, kStoredBlockLengthFieldSize);
|
||||
m_OutStream.WriteBits((UInt16)~curBlockSize, kStoredBlockLengthFieldSize);
|
||||
const Byte *data = Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow)- additionalOffset;
|
||||
for(UInt32 i = 0; i < curBlockSize; i++)
|
||||
m_OutStream.WriteByte(data[i]);
|
||||
additionalOffset -= curBlockSize;
|
||||
}
|
||||
while(blockSize != 0);
|
||||
}
|
||||
|
||||
NO_INLINE UInt32 CCoder::TryDynBlock(int tableIndex, UInt32 numPasses)
|
||||
{
|
||||
CTables &t = m_Tables[tableIndex];
|
||||
BlockSizeRes = t.BlockSizeRes;
|
||||
UInt32 posTemp = t.m_Pos;
|
||||
SetPrices(t);
|
||||
|
||||
for (UInt32 p = 0; p < numPasses; p++)
|
||||
{
|
||||
m_Pos = posTemp;
|
||||
TryBlock();
|
||||
MakeTables();
|
||||
SetPrices(m_NewLevels);
|
||||
}
|
||||
|
||||
(CLevels &)t = m_NewLevels;
|
||||
|
||||
m_NumLitLenLevels = kMainTableSize;
|
||||
while(m_NumLitLenLevels > kNumLitLenCodesMin && m_NewLevels.litLenLevels[m_NumLitLenLevels - 1] == 0)
|
||||
m_NumLitLenLevels--;
|
||||
|
||||
m_NumDistLevels = kDistTableSize64;
|
||||
while(m_NumDistLevels > kNumDistCodesMin && m_NewLevels.distLevels[m_NumDistLevels - 1] == 0)
|
||||
m_NumDistLevels--;
|
||||
|
||||
UInt32 levelFreqs[kLevelTableSize];
|
||||
memset(levelFreqs, 0, sizeof(levelFreqs));
|
||||
|
||||
LevelTableDummy(m_NewLevels.litLenLevels, m_NumLitLenLevels, levelFreqs);
|
||||
LevelTableDummy(m_NewLevels.distLevels, m_NumDistLevels, levelFreqs);
|
||||
|
||||
Huffman_Generate(levelFreqs, levelCodes, levelLens, kLevelTableSize, kMaxLevelBitLength);
|
||||
|
||||
m_NumLevelCodes = kNumLevelCodesMin;
|
||||
for (UInt32 i = 0; i < kLevelTableSize; i++)
|
||||
{
|
||||
Byte level = levelLens[kCodeLengthAlphabetOrder[i]];
|
||||
if (level > 0 && i >= m_NumLevelCodes)
|
||||
m_NumLevelCodes = i + 1;
|
||||
m_LevelLevels[i] = level;
|
||||
}
|
||||
|
||||
return GetLzBlockPrice() +
|
||||
Huffman_GetPrice_Spec(levelFreqs, levelLens, kLevelTableSize, kLevelDirectBits, kTableDirectLevels) +
|
||||
kNumLenCodesFieldSize + kNumDistCodesFieldSize + kNumLevelCodesFieldSize +
|
||||
m_NumLevelCodes * kLevelFieldSize + kFinalBlockFieldSize + kBlockTypeFieldSize;
|
||||
}
|
||||
|
||||
NO_INLINE UInt32 CCoder::TryFixedBlock(int tableIndex)
|
||||
{
|
||||
CTables &t = m_Tables[tableIndex];
|
||||
BlockSizeRes = t.BlockSizeRes;
|
||||
m_Pos = t.m_Pos;
|
||||
m_NewLevels.SetFixedLevels();
|
||||
SetPrices(m_NewLevels);
|
||||
TryBlock();
|
||||
return kFinalBlockFieldSize + kBlockTypeFieldSize + GetLzBlockPrice();
|
||||
}
|
||||
|
||||
NO_INLINE UInt32 CCoder::GetBlockPrice(int tableIndex, int numDivPasses)
|
||||
{
|
||||
CTables &t = m_Tables[tableIndex];
|
||||
t.StaticMode = false;
|
||||
UInt32 price = TryDynBlock(tableIndex, m_NumPasses);
|
||||
t.BlockSizeRes = BlockSizeRes;
|
||||
UInt32 numValues = m_ValueIndex;
|
||||
UInt32 posTemp = m_Pos;
|
||||
UInt32 additionalOffsetEnd = m_AdditionalOffset;
|
||||
|
||||
if (m_CheckStatic && m_ValueIndex <= kFixedHuffmanCodeBlockSizeMax)
|
||||
{
|
||||
const UInt32 fixedPrice = TryFixedBlock(tableIndex);
|
||||
t.StaticMode = (fixedPrice < price);
|
||||
if (t.StaticMode)
|
||||
price = fixedPrice;
|
||||
}
|
||||
|
||||
const UInt32 storePrice = GetStorePrice(BlockSizeRes, 0); // bitPosition
|
||||
t.StoreMode = (storePrice <= price);
|
||||
if (t.StoreMode)
|
||||
price = storePrice;
|
||||
|
||||
t.UseSubBlocks = false;
|
||||
|
||||
if (numDivPasses > 1 && numValues >= kDivideCodeBlockSizeMin)
|
||||
{
|
||||
CTables &t0 = m_Tables[(tableIndex << 1)];
|
||||
(CLevels &)t0 = t;
|
||||
t0.BlockSizeRes = t.BlockSizeRes >> 1;
|
||||
t0.m_Pos = t.m_Pos;
|
||||
UInt32 subPrice = GetBlockPrice((tableIndex << 1), numDivPasses - 1);
|
||||
|
||||
UInt32 blockSize2 = t.BlockSizeRes - t0.BlockSizeRes;
|
||||
if (t0.BlockSizeRes >= kDivideBlockSizeMin && blockSize2 >= kDivideBlockSizeMin)
|
||||
{
|
||||
CTables &t1 = m_Tables[(tableIndex << 1) + 1];
|
||||
(CLevels &)t1 = t;
|
||||
t1.BlockSizeRes = blockSize2;
|
||||
t1.m_Pos = m_Pos;
|
||||
m_AdditionalOffset -= t0.BlockSizeRes;
|
||||
subPrice += GetBlockPrice((tableIndex << 1) + 1, numDivPasses - 1);
|
||||
t.UseSubBlocks = (subPrice < price);
|
||||
if (t.UseSubBlocks)
|
||||
price = subPrice;
|
||||
}
|
||||
}
|
||||
m_AdditionalOffset = additionalOffsetEnd;
|
||||
m_Pos = posTemp;
|
||||
return price;
|
||||
}
|
||||
|
||||
void CCoder::CodeBlock(int tableIndex, bool finalBlock)
|
||||
{
|
||||
CTables &t = m_Tables[tableIndex];
|
||||
if (t.UseSubBlocks)
|
||||
{
|
||||
CodeBlock((tableIndex << 1), false);
|
||||
CodeBlock((tableIndex << 1) + 1, finalBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (t.StoreMode)
|
||||
WriteStoreBlock(t.BlockSizeRes, m_AdditionalOffset, finalBlock);
|
||||
else
|
||||
{
|
||||
m_OutStream.WriteBits((finalBlock ? NFinalBlockField::kFinalBlock: NFinalBlockField::kNotFinalBlock), kFinalBlockFieldSize);
|
||||
if (t.StaticMode)
|
||||
{
|
||||
m_OutStream.WriteBits(NBlockType::kFixedHuffman, kBlockTypeFieldSize);
|
||||
TryFixedBlock(tableIndex);
|
||||
int i;
|
||||
for (i = 0; i < kFixedMainTableSize; i++)
|
||||
mainFreqs[i] = (UInt32)1 << (kNumHuffmanBits - m_NewLevels.litLenLevels[i]);
|
||||
for (i = 0; i < kFixedDistTableSize; i++)
|
||||
distFreqs[i] = (UInt32)1 << (kNumHuffmanBits - m_NewLevels.distLevels[i]);
|
||||
MakeTables();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_NumDivPasses > 1 || m_CheckStatic)
|
||||
TryDynBlock(tableIndex, 1);
|
||||
m_OutStream.WriteBits(NBlockType::kDynamicHuffman, kBlockTypeFieldSize);
|
||||
m_OutStream.WriteBits(m_NumLitLenLevels - kNumLitLenCodesMin, kNumLenCodesFieldSize);
|
||||
m_OutStream.WriteBits(m_NumDistLevels - kNumDistCodesMin, kNumDistCodesFieldSize);
|
||||
m_OutStream.WriteBits(m_NumLevelCodes - kNumLevelCodesMin, kNumLevelCodesFieldSize);
|
||||
|
||||
for (UInt32 i = 0; i < m_NumLevelCodes; i++)
|
||||
m_OutStream.WriteBits(m_LevelLevels[i], kLevelFieldSize);
|
||||
|
||||
Huffman_ReverseBits(levelCodes, levelLens, kLevelTableSize);
|
||||
LevelTableCode(m_NewLevels.litLenLevels, m_NumLitLenLevels, levelLens, levelCodes);
|
||||
LevelTableCode(m_NewLevels.distLevels, m_NumDistLevels, levelLens, levelCodes);
|
||||
}
|
||||
WriteBlock();
|
||||
}
|
||||
m_AdditionalOffset -= t.BlockSizeRes;
|
||||
}
|
||||
}
|
||||
|
||||
HRes Read(void *object, void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
return (HRes)((CSeqInStream *)object)->RealStream->Read(data, size, processedSize);
|
||||
}
|
||||
|
||||
HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 * /* inSize */ , const UInt64 * /* outSize */ ,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
m_CheckStatic = (m_NumPasses != 1 || m_NumDivPasses != 1);
|
||||
m_IsMultiPass = (m_CheckStatic || (m_NumPasses != 1 || m_NumDivPasses != 1));
|
||||
|
||||
RINOK(Create());
|
||||
|
||||
m_ValueBlockSize = (1 << 13) + (1 << 12) * m_NumDivPasses;
|
||||
|
||||
UInt64 nowPos = 0;
|
||||
|
||||
_seqInStream.RealStream = inStream;
|
||||
_seqInStream.SeqInStream.Read = Read;
|
||||
_lzInWindow.stream = &_seqInStream.SeqInStream;
|
||||
|
||||
MatchFinder_Init(&_lzInWindow);
|
||||
m_OutStream.SetStream(outStream);
|
||||
m_OutStream.Init();
|
||||
|
||||
CCoderReleaser coderReleaser(this);
|
||||
|
||||
m_OptimumEndIndex = m_OptimumCurrentIndex = 0;
|
||||
|
||||
CTables &t = m_Tables[1];
|
||||
t.m_Pos = 0;
|
||||
t.InitStructures();
|
||||
|
||||
m_AdditionalOffset = 0;
|
||||
do
|
||||
{
|
||||
t.BlockSizeRes = kBlockUncompressedSizeThreshold;
|
||||
m_SecondPass = false;
|
||||
GetBlockPrice(1, m_NumDivPasses);
|
||||
CodeBlock(1, Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) == 0);
|
||||
nowPos += m_Tables[1].BlockSizeRes;
|
||||
if (progress != NULL)
|
||||
{
|
||||
UInt64 packSize = m_OutStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&nowPos, &packSize));
|
||||
}
|
||||
}
|
||||
while (Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) != 0);
|
||||
if (_lzInWindow.result != SZ_OK)
|
||||
return _lzInWindow.result;
|
||||
return m_OutStream.Flush();
|
||||
}
|
||||
|
||||
HRESULT CCoder::BaseCode(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
catch(const COutBufferException &e) { return e.ErrorCode; }
|
||||
catch(...) { return E_FAIL; }
|
||||
}
|
||||
|
||||
STDMETHODIMP CCOMCoder::Code(ISequentialInStream *inStream,
|
||||
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)
|
||||
{ return BaseSetEncoderProperties2(propIDs, properties, numProperties); }
|
||||
|
||||
STDMETHODIMP CCOMCoder64::Code(ISequentialInStream *inStream,
|
||||
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)
|
||||
{ return BaseSetEncoderProperties2(propIDs, properties, numProperties); }
|
||||
|
||||
}}}
|
||||
|
||||
221
CPP/7zip/Compress/Deflate/DeflateEncoder.h
Executable file
221
CPP/7zip/Compress/Deflate/DeflateEncoder.h
Executable file
@@ -0,0 +1,221 @@
|
||||
// DeflateEncoder.h
|
||||
|
||||
#ifndef __DEFLATE_ENCODER_H
|
||||
#define __DEFLATE_ENCODER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/LSBFEncoder.h"
|
||||
|
||||
#include "DeflateConst.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/Compress/Lz/MatchFinder.h"
|
||||
}
|
||||
|
||||
namespace NCompress {
|
||||
namespace NDeflate {
|
||||
namespace NEncoder {
|
||||
|
||||
struct CCodeValue
|
||||
{
|
||||
UInt16 Len;
|
||||
UInt16 Pos;
|
||||
void SetAsLiteral() { Len = (1 << 15); }
|
||||
bool IsLiteral() const { return ((Len & (1 << 15)) != 0); }
|
||||
};
|
||||
|
||||
struct COptimal
|
||||
{
|
||||
UInt32 Price;
|
||||
UInt16 PosPrev;
|
||||
UInt16 BackPrev;
|
||||
};
|
||||
|
||||
const UInt32 kNumOptsBase = 1 << 12;
|
||||
const UInt32 kNumOpts = kNumOptsBase + kMatchMaxLen;
|
||||
|
||||
class CCoder;
|
||||
|
||||
struct CTables: public CLevels
|
||||
{
|
||||
bool UseSubBlocks;
|
||||
bool StoreMode;
|
||||
bool StaticMode;
|
||||
UInt32 BlockSizeRes;
|
||||
UInt32 m_Pos;
|
||||
void InitStructures();
|
||||
};
|
||||
|
||||
typedef struct _CSeqInStream
|
||||
{
|
||||
ISeqInStream SeqInStream;
|
||||
CMyComPtr<ISequentialInStream> RealStream;
|
||||
} CSeqInStream;
|
||||
|
||||
class CCoder
|
||||
{
|
||||
CMatchFinder _lzInWindow;
|
||||
NStream::NLSBF::CEncoder m_OutStream;
|
||||
|
||||
CSeqInStream _seqInStream;
|
||||
|
||||
public:
|
||||
CCodeValue *m_Values;
|
||||
|
||||
UInt16 *m_MatchDistances;
|
||||
UInt32 m_NumFastBytes;
|
||||
|
||||
UInt16 *m_OnePosMatchesMemory;
|
||||
UInt16 *m_DistanceMemory;
|
||||
|
||||
UInt32 m_Pos;
|
||||
|
||||
int m_NumPasses;
|
||||
int m_NumDivPasses;
|
||||
bool m_CheckStatic;
|
||||
bool m_IsMultiPass;
|
||||
UInt32 m_ValueBlockSize;
|
||||
|
||||
UInt32 m_NumLenCombinations;
|
||||
UInt32 m_MatchMaxLen;
|
||||
const Byte *m_LenStart;
|
||||
const Byte *m_LenDirectBits;
|
||||
|
||||
bool m_Created;
|
||||
bool m_Deflate64Mode;
|
||||
|
||||
Byte m_LevelLevels[kLevelTableSize];
|
||||
int m_NumLitLenLevels;
|
||||
int m_NumDistLevels;
|
||||
UInt32 m_NumLevelCodes;
|
||||
UInt32 m_ValueIndex;
|
||||
|
||||
bool m_SecondPass;
|
||||
UInt32 m_AdditionalOffset;
|
||||
|
||||
UInt32 m_OptimumEndIndex;
|
||||
UInt32 m_OptimumCurrentIndex;
|
||||
|
||||
Byte m_LiteralPrices[256];
|
||||
Byte m_LenPrices[kNumLenSymbolsMax];
|
||||
Byte m_PosPrices[kDistTableSize64];
|
||||
|
||||
CLevels m_NewLevels;
|
||||
UInt32 mainFreqs[kFixedMainTableSize];
|
||||
UInt32 distFreqs[kDistTableSize64];
|
||||
UInt32 mainCodes[kFixedMainTableSize];
|
||||
UInt32 distCodes[kDistTableSize64];
|
||||
UInt32 levelCodes[kLevelTableSize];
|
||||
Byte levelLens[kLevelTableSize];
|
||||
|
||||
UInt32 BlockSizeRes;
|
||||
|
||||
CTables *m_Tables;
|
||||
COptimal m_Optimum[kNumOpts];
|
||||
|
||||
UInt32 m_MatchFinderCycles;
|
||||
// IMatchFinderSetNumPasses *m_SetMfPasses;
|
||||
|
||||
void GetMatches();
|
||||
void MovePos(UInt32 num);
|
||||
UInt32 Backward(UInt32 &backRes, UInt32 cur);
|
||||
UInt32 GetOptimal(UInt32 &backRes);
|
||||
|
||||
void LevelTableDummy(const Byte *levels, int numLevels, UInt32 *freqs);
|
||||
void LevelTableCode(const Byte *levels, int numLevels, const Byte *lens, const UInt32 *codes);
|
||||
|
||||
void MakeTables();
|
||||
UInt32 GetLzBlockPrice() const;
|
||||
void TryBlock();
|
||||
UInt32 TryDynBlock(int tableIndex, UInt32 numPasses);
|
||||
|
||||
UInt32 TryFixedBlock(int tableIndex);
|
||||
|
||||
void SetPrices(const CLevels &levels);
|
||||
void WriteBlock();
|
||||
|
||||
HRESULT Create();
|
||||
void Free();
|
||||
|
||||
void WriteStoreBlock(UInt32 blockSize, UInt32 additionalOffset, bool finalBlock);
|
||||
void WriteTables(bool writeMode, bool finalBlock);
|
||||
|
||||
void WriteBlockData(bool writeMode, bool finalBlock);
|
||||
|
||||
void ReleaseStreams()
|
||||
{
|
||||
_seqInStream.RealStream.Release();
|
||||
m_OutStream.ReleaseStream();
|
||||
}
|
||||
class CCoderReleaser
|
||||
{
|
||||
CCoder *m_Coder;
|
||||
public:
|
||||
CCoderReleaser(CCoder *coder): m_Coder(coder) {}
|
||||
~CCoderReleaser() { m_Coder->ReleaseStreams(); }
|
||||
};
|
||||
friend class CCoderReleaser;
|
||||
|
||||
UInt32 GetBlockPrice(int tableIndex, int numDivPasses);
|
||||
void CodeBlock(int tableIndex, bool finalBlock);
|
||||
|
||||
public:
|
||||
CCoder(bool deflate64Mode = false);
|
||||
~CCoder();
|
||||
|
||||
HRESULT CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
HRESULT BaseCode(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// ICompressSetCoderProperties
|
||||
HRESULT BaseSetEncoderProperties2(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
class CCOMCoder :
|
||||
public ICompressCoder,
|
||||
public ICompressSetCoderProperties,
|
||||
public CMyUnknownImp,
|
||||
public CCoder
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
|
||||
CCOMCoder(): CCoder(false) {};
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
// ICompressSetCoderProperties
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties);
|
||||
};
|
||||
|
||||
class CCOMCoder64 :
|
||||
public ICompressCoder,
|
||||
public ICompressSetCoderProperties,
|
||||
public CMyUnknownImp,
|
||||
public CCoder
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
|
||||
CCOMCoder64(): CCoder(true) {};
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
// ICompressSetCoderProperties
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
|
||||
const PROPVARIANT *properties, UInt32 numProperties);
|
||||
};
|
||||
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
157
CPP/7zip/Compress/Deflate/DllExports.cpp
Executable file
157
CPP/7zip/Compress/Deflate/DllExports.cpp
Executable file
@@ -0,0 +1,157 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
#include "DeflateEncoder.h"
|
||||
#include "DeflateDecoder.h"
|
||||
|
||||
#ifdef CRC_GENERATE_TABLE
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/7zCrc.h"
|
||||
}
|
||||
#endif
|
||||
|
||||
// {23170F69-40C1-278B-0401-080000000000}
|
||||
DEFINE_GUID(CLSID_CCompressDeflateDecoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0401-090000000000}
|
||||
DEFINE_GUID(CLSID_CCompressDeflate64Decoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0401-080000000100}
|
||||
DEFINE_GUID(CLSID_CCompressDeflateEncoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0401-090000000100}
|
||||
DEFINE_GUID(CLSID_CCompressDeflate64Encoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00);
|
||||
|
||||
|
||||
// {23170F69-40C1-278B-0409-010000000000}
|
||||
DEFINE_GUID(CLSID_CCompressDeflateNsisDecoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
if (dwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
#ifdef CRC_GENERATE_TABLE
|
||||
CrcGenerateTable();
|
||||
#endif
|
||||
}
|
||||
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_CCompressDeflateDecoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCompress::NDeflate::NDecoder::CCOMCoder();
|
||||
}
|
||||
else if (*clsid == CLSID_CCompressDeflateNsisDecoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCompress::NDeflate::NDecoder::CNsisCOMCoder();
|
||||
}
|
||||
else if (*clsid == CLSID_CCompressDeflateEncoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCompress::NDeflate::NEncoder::CCOMCoder();
|
||||
}
|
||||
else if (*clsid == CLSID_CCompressDeflate64Decoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCompress::NDeflate::NDecoder::CCOMCoder64();
|
||||
}
|
||||
else if (*clsid == CLSID_CCompressDeflate64Encoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCompress::NDeflate::NEncoder::CCOMCoder64();
|
||||
}
|
||||
else
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
*outObject = coder.Detach();
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct CDeflateMethodItem
|
||||
{
|
||||
char ID[3];
|
||||
const wchar_t *UserName;
|
||||
const GUID *Decoder;
|
||||
const GUID *Encoder;
|
||||
};
|
||||
|
||||
#define METHOD_ITEM(Name, id, UserName) \
|
||||
{ { 0x04, 0x01, id }, UserName, \
|
||||
&CLSID_CCompress ## Name ## Decoder, \
|
||||
&CLSID_CCompress ## Name ## Encoder }
|
||||
|
||||
#define METHOD_ITEM_DE(Name, id1, id2, UserName) \
|
||||
{ { 0x04, id1, id2 }, UserName, \
|
||||
&CLSID_CCompress ## Name ## Decoder, NULL }
|
||||
|
||||
|
||||
static CDeflateMethodItem g_Methods[] =
|
||||
{
|
||||
METHOD_ITEM(Deflate, 0x08, L"Deflate"),
|
||||
METHOD_ITEM(Deflate64, 0x09, L"Deflate64"),
|
||||
METHOD_ITEM_DE(DeflateNsis, 0x09, 0x01, L"DeflateNSIS")
|
||||
};
|
||||
|
||||
STDAPI GetNumberOfMethods(UINT32 *numMethods)
|
||||
{
|
||||
*numMethods = sizeof(g_Methods) / sizeof(g_Methods[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
if (index > sizeof(g_Methods) / sizeof(g_Methods[0]))
|
||||
return E_INVALIDARG;
|
||||
VariantClear((tagVARIANT *)value);
|
||||
const CDeflateMethodItem &method = g_Methods[index];
|
||||
switch(propID)
|
||||
{
|
||||
case NMethodPropID::kID:
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(method.ID,
|
||||
sizeof(method.ID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kName:
|
||||
if ((value->bstrVal = ::SysAllocString(method.UserName)) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kDecoder:
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)method.Decoder, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kEncoder:
|
||||
if (method.Encoder)
|
||||
{
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)method.Encoder, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
3
CPP/7zip/Compress/Deflate/StdAfx.cpp
Executable file
3
CPP/7zip/Compress/Deflate/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
8
CPP/7zip/Compress/Deflate/StdAfx.h
Executable file
8
CPP/7zip/Compress/Deflate/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
63
CPP/7zip/Compress/Deflate/makefile
Executable file
63
CPP/7zip/Compress/Deflate/makefile
Executable file
@@ -0,0 +1,63 @@
|
||||
PROG = Deflate.dll
|
||||
DEF_FILE = ../Codec.def
|
||||
CFLAGS = $(CFLAGS) -I ../../../ -D_ST_MODE
|
||||
LIBS = $(LIBS) oleaut32.lib
|
||||
|
||||
DEFLATE_OBJS = \
|
||||
$O\DllExports.obj \
|
||||
|
||||
DEFLATE_OPT_OBJS = \
|
||||
$O\DeflateDecoder.obj \
|
||||
$O\DeflateEncoder.obj \
|
||||
|
||||
COMMON_OBJS = \
|
||||
$O\Alloc.obj \
|
||||
$O\CRC.obj \
|
||||
|
||||
7ZIP_COMMON_OBJS = \
|
||||
$O\InBuffer.obj \
|
||||
$O\OutBuffer.obj \
|
||||
$O\LSBFDecoder.obj \
|
||||
$O\LSBFEncoder.obj \
|
||||
|
||||
LZ_OBJS = \
|
||||
$O\LZOutWindow.obj \
|
||||
|
||||
C_OBJS = \
|
||||
$O\7zCrc.obj \
|
||||
$O\Sort.obj \
|
||||
|
||||
C_LZ_OBJS = \
|
||||
$O\MatchFinder.obj \
|
||||
|
||||
|
||||
OBJS = \
|
||||
$O\StdAfx.obj \
|
||||
$(DEFLATE_OBJS) \
|
||||
$(DEFLATE_OPT_OBJS) \
|
||||
$(COMMON_OBJS) \
|
||||
$(7ZIP_COMMON_OBJS) \
|
||||
$(LZ_OBJS) \
|
||||
$(C_OBJS) \
|
||||
$(C_LZ_OBJS) \
|
||||
$O\HuffmanEncode.obj \
|
||||
$O\resource.res
|
||||
|
||||
!include "../../../Build.mak"
|
||||
|
||||
$(DEFLATE_OBJS): $(*B).cpp
|
||||
$(COMPL)
|
||||
$(DEFLATE_OPT_OBJS): $(*B).cpp
|
||||
$(COMPL_O2)
|
||||
$(COMMON_OBJS): ../../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(LZ_OBJS): ../LZ/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(C_OBJS): ../../../../C/$(*B).c
|
||||
$(COMPL_O2)
|
||||
$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c
|
||||
$(COMPL_O2)
|
||||
$O\HuffmanEncode.obj: ../../../../C/Compress/Huffman/$(*B).c
|
||||
$(COMPL_O2)
|
||||
3
CPP/7zip/Compress/Deflate/resource.rc
Executable file
3
CPP/7zip/Compress/Deflate/resource.rc
Executable file
@@ -0,0 +1,3 @@
|
||||
#include "../../MyVersionInfo.rc"
|
||||
|
||||
MY_VERSION_INFO_DLL("Deflate Codec", "Deflate")
|
||||
88
CPP/7zip/Compress/Huffman/HuffmanDecoder.h
Executable file
88
CPP/7zip/Compress/Huffman/HuffmanDecoder.h
Executable file
@@ -0,0 +1,88 @@
|
||||
// Compress/HuffmanDecoder.h
|
||||
|
||||
#ifndef __COMPRESS_HUFFMANDECODER_H
|
||||
#define __COMPRESS_HUFFMANDECODER_H
|
||||
|
||||
#include "../../../Common/Types.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NHuffman {
|
||||
|
||||
const int kNumTableBits = 9;
|
||||
|
||||
template <int kNumBitsMax, UInt32 m_NumSymbols>
|
||||
class CDecoder
|
||||
{
|
||||
UInt32 m_Limits[kNumBitsMax + 1]; // m_Limits[i] = value limit for symbols with length = i
|
||||
UInt32 m_Positions[kNumBitsMax + 1]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i
|
||||
UInt32 m_Symbols[m_NumSymbols];
|
||||
Byte m_Lengths[1 << kNumTableBits]; // Table oh length for short codes.
|
||||
|
||||
public:
|
||||
|
||||
bool SetCodeLengths(const Byte *codeLengths)
|
||||
{
|
||||
int lenCounts[kNumBitsMax + 1], tmpPositions[kNumBitsMax + 1];
|
||||
int i;
|
||||
for(i = 1; i <= kNumBitsMax; i++)
|
||||
lenCounts[i] = 0;
|
||||
UInt32 symbol;
|
||||
for (symbol = 0; symbol < m_NumSymbols; symbol++)
|
||||
{
|
||||
int len = codeLengths[symbol];
|
||||
if (len > kNumBitsMax)
|
||||
return false;
|
||||
lenCounts[len]++;
|
||||
m_Symbols[symbol] = 0xFFFFFFFF;
|
||||
}
|
||||
lenCounts[0] = 0;
|
||||
m_Positions[0] = m_Limits[0] = 0;
|
||||
UInt32 startPos = 0;
|
||||
UInt32 index = 0;
|
||||
const UInt32 kMaxValue = (1 << kNumBitsMax);
|
||||
for (i = 1; i <= kNumBitsMax; i++)
|
||||
{
|
||||
startPos += lenCounts[i] << (kNumBitsMax - i);
|
||||
if (startPos > kMaxValue)
|
||||
return false;
|
||||
m_Limits[i] = (i == kNumBitsMax) ? kMaxValue : startPos;
|
||||
m_Positions[i] = m_Positions[i - 1] + lenCounts[i - 1];
|
||||
tmpPositions[i] = m_Positions[i];
|
||||
if(i <= kNumTableBits)
|
||||
{
|
||||
UInt32 limit = (m_Limits[i] >> (kNumBitsMax - kNumTableBits));
|
||||
for (; index < limit; index++)
|
||||
m_Lengths[index] = (Byte)i;
|
||||
}
|
||||
}
|
||||
for (symbol = 0; symbol < m_NumSymbols; symbol++)
|
||||
{
|
||||
int len = codeLengths[symbol];
|
||||
if (len != 0)
|
||||
m_Symbols[tmpPositions[len]++] = symbol;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class TBitDecoder>
|
||||
UInt32 DecodeSymbol(TBitDecoder *bitStream)
|
||||
{
|
||||
int numBits;
|
||||
UInt32 value = bitStream->GetValue(kNumBitsMax);
|
||||
if (value < m_Limits[kNumTableBits])
|
||||
numBits = m_Lengths[value >> (kNumBitsMax - kNumTableBits)];
|
||||
else
|
||||
for (numBits = kNumTableBits + 1; value >= m_Limits[numBits]; numBits++);
|
||||
bitStream->MovePos(numBits);
|
||||
UInt32 index = m_Positions[numBits] +
|
||||
((value - m_Limits[numBits - 1]) >> (kNumBitsMax - numBits));
|
||||
if (index >= m_NumSymbols)
|
||||
// throw CDecoderException(); // test it
|
||||
return 0xFFFFFFFF;
|
||||
return m_Symbols[index];
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
6
CPP/7zip/Compress/Huffman/StdAfx.h
Executable file
6
CPP/7zip/Compress/Huffman/StdAfx.h
Executable file
@@ -0,0 +1,6 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#endif
|
||||
65
CPP/7zip/Compress/Implode/DllExports.cpp
Executable file
65
CPP/7zip/Compress/Implode/DllExports.cpp
Executable file
@@ -0,0 +1,65 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "ImplodeDecoder.h"
|
||||
|
||||
// {23170F69-40C1-278B-0401-060000000000}
|
||||
DEFINE_GUID(CLSID_CCompressImplodeDecoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 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;
|
||||
if (*clsid != CLSID_CCompressImplodeDecoder)
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
if (*iid != IID_ICompressCoder)
|
||||
return E_NOINTERFACE;
|
||||
CMyComPtr<ICompressCoder> coder = (ICompressCoder *)new
|
||||
NCompress::NImplode::NDecoder::CCoder;
|
||||
*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, 0x01, 0x06 };
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
case NMethodPropID::kName:
|
||||
if ((value->bstrVal = ::SysAllocString(L"Implode")) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kDecoder:
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)&CLSID_CCompressImplodeDecoder, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
222
CPP/7zip/Compress/Implode/ImplodeDecoder.cpp
Executable file
222
CPP/7zip/Compress/Implode/ImplodeDecoder.cpp
Executable file
@@ -0,0 +1,222 @@
|
||||
// Implode/Decoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ImplodeDecoder.h"
|
||||
#include "Common/Defs.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NImplode {
|
||||
namespace NDecoder {
|
||||
|
||||
class CException
|
||||
{
|
||||
public:
|
||||
enum ECauseType
|
||||
{
|
||||
kData
|
||||
} m_Cause;
|
||||
CException(ECauseType cause): m_Cause(cause) {}
|
||||
};
|
||||
|
||||
static const int kNumDistanceLowDirectBitsForBigDict = 7;
|
||||
static const int kNumDistanceLowDirectBitsForSmallDict = 6;
|
||||
|
||||
static const int kNumBitsInByte = 8;
|
||||
|
||||
static const int kLevelStructuresNumberFieldSize = kNumBitsInByte;
|
||||
static const int kLevelStructuresNumberAdditionalValue = 1;
|
||||
|
||||
static const int kNumLevelStructureLevelBits = 4;
|
||||
static const int kLevelStructureLevelAdditionalValue = 1;
|
||||
|
||||
static const int kNumLevelStructureRepNumberBits = 4;
|
||||
static const int kLevelStructureRepNumberAdditionalValue = 1;
|
||||
|
||||
|
||||
static const int kLiteralTableSize = (1 << kNumBitsInByte);
|
||||
static const int kDistanceTableSize = 64;
|
||||
static const int kLengthTableSize = 64;
|
||||
|
||||
static const UInt32 kHistorySize =
|
||||
(1 << MyMax(kNumDistanceLowDirectBitsForBigDict,
|
||||
kNumDistanceLowDirectBitsForSmallDict)) *
|
||||
kDistanceTableSize; // = 8 KB;
|
||||
|
||||
static const int kNumAdditionalLengthBits = 8;
|
||||
|
||||
static const UInt32 kMatchMinLenWhenLiteralsOn = 3;
|
||||
static const UInt32 kMatchMinLenWhenLiteralsOff = 2;
|
||||
|
||||
static const UInt32 kMatchMinLenMax = MyMax(kMatchMinLenWhenLiteralsOn,
|
||||
kMatchMinLenWhenLiteralsOff); // 3
|
||||
|
||||
static const UInt32 kMatchMaxLenMax = kMatchMinLenMax +
|
||||
(kLengthTableSize - 1) + (1 << kNumAdditionalLengthBits) - 1; // or 2
|
||||
|
||||
enum
|
||||
{
|
||||
kMatchId = 0,
|
||||
kLiteralId = 1
|
||||
};
|
||||
|
||||
|
||||
CCoder::CCoder():
|
||||
m_LiteralDecoder(kLiteralTableSize),
|
||||
m_LengthDecoder(kLengthTableSize),
|
||||
m_DistanceDecoder(kDistanceTableSize)
|
||||
{
|
||||
}
|
||||
|
||||
void CCoder::ReleaseStreams()
|
||||
{
|
||||
m_OutWindowStream.ReleaseStream();
|
||||
m_InBitStream.ReleaseStream();
|
||||
}
|
||||
|
||||
bool CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder,
|
||||
Byte *levels, int numLevelItems)
|
||||
{
|
||||
int numCodedStructures = m_InBitStream.ReadBits(kNumBitsInByte) +
|
||||
kLevelStructuresNumberAdditionalValue;
|
||||
int currentIndex = 0;
|
||||
for(int i = 0; i < numCodedStructures; i++)
|
||||
{
|
||||
int level = m_InBitStream.ReadBits(kNumLevelStructureLevelBits) +
|
||||
kLevelStructureLevelAdditionalValue;
|
||||
int rep = m_InBitStream.ReadBits(kNumLevelStructureRepNumberBits) +
|
||||
kLevelStructureRepNumberAdditionalValue;
|
||||
if (currentIndex + rep > numLevelItems)
|
||||
throw CException(CException::kData);
|
||||
for(int j = 0; j < rep; j++)
|
||||
levels[currentIndex++] = (Byte)level;
|
||||
}
|
||||
if (currentIndex != numLevelItems)
|
||||
return false;
|
||||
return decoder.SetCodeLengths(levels);
|
||||
}
|
||||
|
||||
|
||||
bool CCoder::ReadTables(void)
|
||||
{
|
||||
if (m_LiteralsOn)
|
||||
{
|
||||
Byte literalLevels[kLiteralTableSize];
|
||||
if (!ReadLevelItems(m_LiteralDecoder, literalLevels, kLiteralTableSize))
|
||||
return false;
|
||||
}
|
||||
|
||||
Byte lengthLevels[kLengthTableSize];
|
||||
if (!ReadLevelItems(m_LengthDecoder, lengthLevels, kLengthTableSize))
|
||||
return false;
|
||||
|
||||
Byte distanceLevels[kDistanceTableSize];
|
||||
return ReadLevelItems(m_DistanceDecoder, distanceLevels, kDistanceTableSize);
|
||||
}
|
||||
|
||||
class CCoderReleaser
|
||||
{
|
||||
CCoder *m_Coder;
|
||||
public:
|
||||
CCoderReleaser(CCoder *coder): m_Coder(coder) {}
|
||||
~CCoderReleaser() { m_Coder->ReleaseStreams(); }
|
||||
};
|
||||
|
||||
STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (!m_InBitStream.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!m_OutWindowStream.Create(kHistorySize))
|
||||
return E_OUTOFMEMORY;
|
||||
if (outSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
UInt64 pos = 0, unPackSize = *outSize;
|
||||
|
||||
m_OutWindowStream.SetStream(outStream);
|
||||
m_OutWindowStream.Init(false);
|
||||
m_InBitStream.SetStream(inStream);
|
||||
m_InBitStream.Init();
|
||||
CCoderReleaser coderReleaser(this);
|
||||
|
||||
if (!ReadTables())
|
||||
return S_FALSE;
|
||||
|
||||
while(pos < unPackSize)
|
||||
{
|
||||
if (progress != NULL && pos % (1 << 16) == 0)
|
||||
{
|
||||
UInt64 packSize = m_InBitStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &pos));
|
||||
}
|
||||
if(m_InBitStream.ReadBits(1) == kMatchId) // match
|
||||
{
|
||||
UInt32 lowDistBits = m_InBitStream.ReadBits(m_NumDistanceLowDirectBits);
|
||||
UInt32 distance = m_DistanceDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (distance >= kDistanceTableSize)
|
||||
return S_FALSE;
|
||||
distance = (distance << m_NumDistanceLowDirectBits) + lowDistBits;
|
||||
UInt32 lengthSymbol = m_LengthDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (lengthSymbol >= kLengthTableSize)
|
||||
return S_FALSE;
|
||||
UInt32 length = lengthSymbol + m_MinMatchLength;
|
||||
if (lengthSymbol == kLengthTableSize - 1) // special symbol = 63
|
||||
length += m_InBitStream.ReadBits(kNumAdditionalLengthBits);
|
||||
while(distance >= pos && length > 0)
|
||||
{
|
||||
m_OutWindowStream.PutByte(0);
|
||||
pos++;
|
||||
length--;
|
||||
}
|
||||
if (length > 0)
|
||||
m_OutWindowStream.CopyBlock(distance, length);
|
||||
pos += length;
|
||||
}
|
||||
else
|
||||
{
|
||||
Byte b;
|
||||
if (m_LiteralsOn)
|
||||
{
|
||||
UInt32 temp = m_LiteralDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (temp >= kLiteralTableSize)
|
||||
return S_FALSE;
|
||||
b = (Byte)temp;
|
||||
}
|
||||
else
|
||||
b = (Byte)m_InBitStream.ReadBits(kNumBitsInByte);
|
||||
m_OutWindowStream.PutByte(b);
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
if (pos > unPackSize)
|
||||
throw CException(CException::kData);
|
||||
return m_OutWindowStream.Flush();
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
catch(const CLZOutWindowException &e) { return e.ErrorCode; }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoder::SetDecoderProperties2(const Byte *data, UInt32 size)
|
||||
{
|
||||
if (size < 1)
|
||||
return E_INVALIDARG;
|
||||
Byte flag = data[0];
|
||||
m_BigDictionaryOn = ((flag & 2) != 0);
|
||||
m_NumDistanceLowDirectBits = m_BigDictionaryOn ?
|
||||
kNumDistanceLowDirectBitsForBigDict:
|
||||
kNumDistanceLowDirectBitsForSmallDict;
|
||||
m_LiteralsOn = ((flag & 4) != 0);
|
||||
m_MinMatchLength = m_LiteralsOn ?
|
||||
kMatchMinLenWhenLiteralsOn :
|
||||
kMatchMinLenWhenLiteralsOff;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}}
|
||||
60
CPP/7zip/Compress/Implode/ImplodeDecoder.h
Executable file
60
CPP/7zip/Compress/Implode/ImplodeDecoder.h
Executable file
@@ -0,0 +1,60 @@
|
||||
// ImplodeDecoder.h
|
||||
|
||||
#ifndef __IMPLODE_DECODER_H
|
||||
#define __IMPLODE_DECODER_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../LZ/LZOutWindow.h"
|
||||
|
||||
#include "ImplodeHuffmanDecoder.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NImplode {
|
||||
namespace NDecoder {
|
||||
|
||||
class CCoder :
|
||||
public ICompressCoder,
|
||||
public ICompressSetDecoderProperties2,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CLZOutWindow m_OutWindowStream;
|
||||
NStream::NLSBF::CDecoder<CInBuffer> m_InBitStream;
|
||||
|
||||
NImplode::NHuffman::CDecoder m_LiteralDecoder;
|
||||
NImplode::NHuffman::CDecoder m_LengthDecoder;
|
||||
NImplode::NHuffman::CDecoder m_DistanceDecoder;
|
||||
|
||||
bool m_BigDictionaryOn;
|
||||
bool m_LiteralsOn;
|
||||
|
||||
int m_NumDistanceLowDirectBits;
|
||||
UInt32 m_MinMatchLength;
|
||||
|
||||
bool ReadLevelItems(NImplode::NHuffman::CDecoder &table, Byte *levels, int numLevelItems);
|
||||
bool ReadTables();
|
||||
void DeCodeLevelTable(Byte *newLevels, int numLevels);
|
||||
public:
|
||||
CCoder();
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
|
||||
|
||||
void ReleaseStreams();
|
||||
HRESULT (Flush)() { return m_OutWindowStream.Flush(); }
|
||||
|
||||
STDMETHOD(CodeReal)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
// ICompressSetDecoderProperties
|
||||
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
89
CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp
Executable file
89
CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp
Executable file
@@ -0,0 +1,89 @@
|
||||
// ImplodeHuffmanDecoder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ImplodeHuffmanDecoder.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NImplode {
|
||||
namespace NHuffman {
|
||||
|
||||
CDecoder::CDecoder(UInt32 numSymbols):
|
||||
m_NumSymbols(numSymbols)
|
||||
{
|
||||
m_Symbols = new UInt32[m_NumSymbols];
|
||||
}
|
||||
|
||||
CDecoder::~CDecoder()
|
||||
{
|
||||
delete []m_Symbols;
|
||||
}
|
||||
|
||||
bool CDecoder::SetCodeLengths(const Byte *codeLengths)
|
||||
{
|
||||
// int lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1];
|
||||
int lenCounts[kNumBitsInLongestCode + 2], tmpPositions[kNumBitsInLongestCode + 1];
|
||||
int i;
|
||||
for(i = 0; i <= kNumBitsInLongestCode; i++)
|
||||
lenCounts[i] = 0;
|
||||
UInt32 symbolIndex;
|
||||
for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++)
|
||||
lenCounts[codeLengths[symbolIndex]]++;
|
||||
// lenCounts[0] = 0;
|
||||
|
||||
// tmpPositions[0] = m_Positions[0] = m_Limitits[0] = 0;
|
||||
m_Limitits[kNumBitsInLongestCode + 1] = 0;
|
||||
m_Positions[kNumBitsInLongestCode + 1] = 0;
|
||||
lenCounts[kNumBitsInLongestCode + 1] = 0;
|
||||
|
||||
|
||||
UInt32 startPos = 0;
|
||||
static const UInt32 kMaxValue = (1 << kNumBitsInLongestCode);
|
||||
|
||||
for (i = kNumBitsInLongestCode; i > 0; i--)
|
||||
{
|
||||
startPos += lenCounts[i] << (kNumBitsInLongestCode - i);
|
||||
if (startPos > kMaxValue)
|
||||
return false;
|
||||
m_Limitits[i] = startPos;
|
||||
m_Positions[i] = m_Positions[i + 1] + lenCounts[i + 1];
|
||||
tmpPositions[i] = m_Positions[i] + lenCounts[i];
|
||||
|
||||
}
|
||||
|
||||
// if _ZIP_MODE do not throw exception for trees containing only one node
|
||||
// #ifndef _ZIP_MODE
|
||||
if (startPos != kMaxValue)
|
||||
return false;
|
||||
// #endif
|
||||
|
||||
for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++)
|
||||
if (codeLengths[symbolIndex] != 0)
|
||||
m_Symbols[--tmpPositions[codeLengths[symbolIndex]]] = symbolIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
UInt32 CDecoder::DecodeSymbol(CInBit *inStream)
|
||||
{
|
||||
UInt32 numBits = 0;
|
||||
UInt32 value = inStream->GetValue(kNumBitsInLongestCode);
|
||||
int i;
|
||||
for(i = kNumBitsInLongestCode; i > 0; i--)
|
||||
{
|
||||
if (value < m_Limitits[i])
|
||||
{
|
||||
numBits = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 0)
|
||||
return 0xFFFFFFFF;
|
||||
inStream->MovePos(numBits);
|
||||
UInt32 index = m_Positions[numBits] +
|
||||
((value - m_Limitits[numBits + 1]) >> (kNumBitsInLongestCode - numBits));
|
||||
if (index >= m_NumSymbols)
|
||||
return 0xFFFFFFFF;
|
||||
return m_Symbols[index];
|
||||
}
|
||||
|
||||
}}}
|
||||
33
CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.h
Executable file
33
CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.h
Executable file
@@ -0,0 +1,33 @@
|
||||
// ImplodeHuffmanDecoder.h
|
||||
|
||||
#ifndef __IMPLODE_HUFFMAN_DECODER_H
|
||||
#define __IMPLODE_HUFFMAN_DECODER_H
|
||||
|
||||
#include "../../Common/LSBFDecoder.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NImplode {
|
||||
namespace NHuffman {
|
||||
|
||||
const int kNumBitsInLongestCode = 16;
|
||||
|
||||
typedef NStream::NLSBF::CDecoder<CInBuffer> CInBit;
|
||||
|
||||
class CDecoder
|
||||
{
|
||||
UInt32 m_Limitits[kNumBitsInLongestCode + 2]; // m_Limitits[i] = value limit for symbols with length = i
|
||||
UInt32 m_Positions[kNumBitsInLongestCode + 2]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i
|
||||
UInt32 m_NumSymbols; // number of symbols in m_Symbols
|
||||
UInt32 *m_Symbols; // symbols: at first with len=1 then 2, ... 15.
|
||||
public:
|
||||
CDecoder(UInt32 numSymbols);
|
||||
~CDecoder();
|
||||
|
||||
bool SetCodeLengths(const Byte *codeLengths);
|
||||
UInt32 DecodeSymbol(CInBit *inStream);
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
3
CPP/7zip/Compress/Implode/StdAfx.cpp
Executable file
3
CPP/7zip/Compress/Implode/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
8
CPP/7zip/Compress/Implode/StdAfx.h
Executable file
8
CPP/7zip/Compress/Implode/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
17
CPP/7zip/Compress/LZ/LZOutWindow.cpp
Executable file
17
CPP/7zip/Compress/LZ/LZOutWindow.cpp
Executable file
@@ -0,0 +1,17 @@
|
||||
// LZOutWindow.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/Alloc.h"
|
||||
#include "LZOutWindow.h"
|
||||
|
||||
void CLZOutWindow::Init(bool solid)
|
||||
{
|
||||
if(!solid)
|
||||
COutBuffer::Init();
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
ErrorCode = S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
56
CPP/7zip/Compress/LZ/LZOutWindow.h
Executable file
56
CPP/7zip/Compress/LZ/LZOutWindow.h
Executable file
@@ -0,0 +1,56 @@
|
||||
// LZOutWindow.h
|
||||
|
||||
#ifndef __LZ_OUT_WINDOW_H
|
||||
#define __LZ_OUT_WINDOW_H
|
||||
|
||||
#include "../../IStream.h"
|
||||
#include "../../Common/OutBuffer.h"
|
||||
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
typedef COutBufferException CLZOutWindowException;
|
||||
#endif
|
||||
|
||||
class CLZOutWindow: public COutBuffer
|
||||
{
|
||||
public:
|
||||
void Init(bool solid = false);
|
||||
|
||||
// distance >= 0, len > 0,
|
||||
bool CopyBlock(UInt32 distance, UInt32 len)
|
||||
{
|
||||
UInt32 pos = _pos - distance - 1;
|
||||
if (distance >= _pos)
|
||||
{
|
||||
if (!_overDict || distance >= _bufferSize)
|
||||
return false;
|
||||
pos += _bufferSize;
|
||||
}
|
||||
do
|
||||
{
|
||||
if (pos == _bufferSize)
|
||||
pos = 0;
|
||||
_buffer[_pos++] = _buffer[pos++];
|
||||
if (_pos == _limitPos)
|
||||
FlushWithCheck();
|
||||
}
|
||||
while(--len != 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PutByte(Byte b)
|
||||
{
|
||||
_buffer[_pos++] = b;
|
||||
if (_pos == _limitPos)
|
||||
FlushWithCheck();
|
||||
}
|
||||
|
||||
Byte GetByte(UInt32 distance) const
|
||||
{
|
||||
UInt32 pos = _pos - distance - 1;
|
||||
if (pos >= _bufferSize)
|
||||
pos += _bufferSize;
|
||||
return _buffer[pos];
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
6
CPP/7zip/Compress/LZ/StdAfx.h
Executable file
6
CPP/7zip/Compress/LZ/StdAfx.h
Executable file
@@ -0,0 +1,6 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#endif
|
||||
109
CPP/7zip/Compress/LZMA/DllExports.cpp
Executable file
109
CPP/7zip/Compress/LZMA/DllExports.cpp
Executable file
@@ -0,0 +1,109 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/MyInitGuid.h"
|
||||
#include "../../../Common/ComTry.h"
|
||||
#ifdef _WIN32
|
||||
#include "../../../Common/Alloc.h"
|
||||
#endif
|
||||
|
||||
#include "LZMAEncoder.h"
|
||||
#include "LZMADecoder.h"
|
||||
|
||||
#ifdef CRC_GENERATE_TABLE
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/7zCrc.h"
|
||||
}
|
||||
#endif
|
||||
|
||||
// {23170F69-40C1-278B-0301-010000000000}
|
||||
DEFINE_GUID(CLSID_CLZMADecoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
// {23170F69-40C1-278B-0301-010000000100}
|
||||
DEFINE_GUID(CLSID_CLZMAEncoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00);
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
if (dwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
// NCompress::NRangeCoder::g_PriceTables.Init();
|
||||
#ifdef CRC_GENERATE_TABLE
|
||||
CrcGenerateTable();
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
SetLargePageSize();
|
||||
#endif
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
|
||||
{
|
||||
// NCompress::NRangeCoder::g_PriceTables.Init();
|
||||
// CCRC::InitTable();
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
int correctInterface = (*iid == IID_ICompressCoder);
|
||||
CMyComPtr<ICompressCoder> coder;
|
||||
if (*clsid == CLSID_CLZMADecoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCompress::NLZMA::CDecoder();
|
||||
}
|
||||
else if (*clsid == CLSID_CLZMAEncoder)
|
||||
{
|
||||
if (!correctInterface)
|
||||
return E_NOINTERFACE;
|
||||
coder = (ICompressCoder *)new NCompress::NLZMA::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[] = { 0x03, 0x01, 0x01 };
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
case NMethodPropID::kName:
|
||||
if ((value->bstrVal = ::SysAllocString(L"LZMA")) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kDecoder:
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)&CLSID_CLZMADecoder, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kEncoder:
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)&CLSID_CLZMAEncoder, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
478
CPP/7zip/Compress/LZMA/LZMA.dsp
Executable file
478
CPP/7zip/Compress/LZMA/LZMA.dsp
Executable file
@@ -0,0 +1,478 @@
|
||||
# Microsoft Developer Studio Project File - Name="LZMA" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=LZMA - 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 "LZMA.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 "LZMA.mak" CFG="LZMA - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "LZMA - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "LZMA - 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)" == "LZMA - 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 "LZMA_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMA_EXPORTS" /D "COMPRESS_MF_MT" /D "_ST_MODE" /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\LZMA.dll" /opt:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none /debug
|
||||
|
||||
!ELSEIF "$(CFG)" == "LZMA - 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 "LZMA_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "../../../" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMA_EXPORTS" /D "COMPRESS_MF_MT" /D "_ST_MODE" /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\LZMA.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "LZMA - Win32 Release"
|
||||
# Name "LZMA - Win32 Debug"
|
||||
# Begin Group "Spec"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Codec.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DllExports.cpp
|
||||
# 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 "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\OutBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\OutBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamUtils.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "RangeCoder"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\RangeCoder\RangeCoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\RangeCoder\RangeCoderBit.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\RangeCoder\RangeCoderBit.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\RangeCoder\RangeCoderBitTree.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\RangeCoder\RangeCoderOpt.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Interface"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\ICoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\MatchFinders\IMatchFinder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\IStream.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "LZ"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Group "BT"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\BinTree\BinTree.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\BinTree\BinTree2.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\BinTree\BinTree3.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\BinTree\BinTree4.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\BinTree\BinTreeBase.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\BinTree\BinTreeD.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\BinTree\BinTreeD4.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\BinTree\BinTreeDMain.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\BinTree\BinTreeMain.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\BinTree\BinTreeR.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\BinTree\BinTreeR4.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\BinTree\BinTreeRMain.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "HC"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\HashChain\HC4.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\HashChain\HCMain.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\IMatchFinder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\LZInWindow.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\LZOutWindow.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\LZ\LZOutWindow.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\AlignedBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\AlignedBuffer.h
|
||||
# End Source File
|
||||
# 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\ComTry.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\CRC.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\CRC.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Defs.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Exception.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\MyCom.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\MyUnknown.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\MyWindows.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 Group "Windows"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Handle.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Synchronization.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Synchronization.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Thread.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "C"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Group "C_Lz"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c
|
||||
|
||||
!IF "$(CFG)" == "LZMA - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "LZMA - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.c
|
||||
|
||||
!IF "$(CFG)" == "LZMA - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "LZMA - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\7zCrc.c
|
||||
|
||||
!IF "$(CFG)" == "LZMA - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "LZMA - Win32 Debug"
|
||||
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\7zCrc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\IStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Threads.c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Threads.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Types.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\LZMA.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\LZMADecoder.cpp
|
||||
|
||||
!IF "$(CFG)" == "LZMA - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "LZMA - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\LZMADecoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\LZMAEncoder.cpp
|
||||
|
||||
!IF "$(CFG)" == "LZMA - Win32 Release"
|
||||
|
||||
# ADD CPP /O2 /FAs
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "LZMA - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\LZMAEncoder.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
CPP/7zip/Compress/LZMA/LZMA.dsw
Executable file
29
CPP/7zip/Compress/LZMA/LZMA.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: "LZMA"=".\LZMA.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user