mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 12:07:03 -06:00
4.44 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
804edc5756
commit
d9666cf046
91
CPP/7zip/Compress/Rar/DllExports.cpp
Executable file
91
CPP/7zip/Compress/Rar/DllExports.cpp
Executable file
@@ -0,0 +1,91 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
#include "Rar1Decoder.h"
|
||||
#include "Rar2Decoder.h"
|
||||
#include "Rar3Decoder.h"
|
||||
// #include "Rar29Decoder.h"
|
||||
|
||||
#define RarClassId(ver) CLSID_CCompressRar ## ver ## Decoder
|
||||
|
||||
#define MyClassRar(ver) DEFINE_GUID(RarClassId(ver), \
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, ver, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
MyClassRar(1);
|
||||
MyClassRar(2);
|
||||
MyClassRar(3);
|
||||
|
||||
#define CreateCoder(ver) if (*clsid == RarClassId(ver)) \
|
||||
{ if (!correctInterface) return E_NOINTERFACE; \
|
||||
coder = (ICompressCoder *)new NCompress::NRar ## ver::CDecoder; }
|
||||
|
||||
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;
|
||||
CreateCoder(1) else
|
||||
CreateCoder(2) else
|
||||
CreateCoder(3) else
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
*outObject = coder.Detach();
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct CRarMethodItem
|
||||
{
|
||||
char ID[3];
|
||||
const wchar_t *UserName;
|
||||
const GUID *Decoder;
|
||||
};
|
||||
|
||||
static CRarMethodItem g_Methods[] =
|
||||
{
|
||||
{ { 0x04, 0x03, 0x01 }, L"Rar15", &RarClassId(1) },
|
||||
{ { 0x04, 0x03, 0x02 }, L"Rar20", &RarClassId(2) },
|
||||
{ { 0x04, 0x03, 0x03 }, L"Rar29", &RarClassId(3) }
|
||||
};
|
||||
|
||||
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 CRarMethodItem &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;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
485
CPP/7zip/Compress/Rar/Rar1Decoder.cpp
Executable file
485
CPP/7zip/Compress/Rar/Rar1Decoder.cpp
Executable file
@@ -0,0 +1,485 @@
|
||||
// Rar1Decoder.cpp
|
||||
// According to unRAR license,
|
||||
// this code may not be used to develop a
|
||||
// RAR (WinRAR) compatible archiver
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Rar1Decoder.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRar1 {
|
||||
|
||||
static UInt32 PosL1[]={0,0,0,2,3,5,7,11,16,20,24,32,32, 256};
|
||||
static UInt32 PosL2[]={0,0,0,0,5,7,9,13,18,22,26,34,36, 256};
|
||||
static UInt32 PosHf0[]={0,0,0,0,0,8,16,24,33,33,33,33,33, 257};
|
||||
static UInt32 PosHf1[]={0,0,0,0,0,0,4,44,60,76,80,80,127, 257};
|
||||
static UInt32 PosHf2[]={0,0,0,0,0,0,2,7,53,117,233, 257,0};
|
||||
static UInt32 PosHf3[]={0,0,0,0,0,0,0,2,16,218,251, 257,0};
|
||||
static UInt32 PosHf4[]={0,0,0,0,0,0,0,0,0,255, 257,0,0};
|
||||
|
||||
static const UInt32 kHistorySize = (1 << 16);
|
||||
|
||||
class CCoderReleaser
|
||||
{
|
||||
CDecoder *m_Coder;
|
||||
public:
|
||||
CCoderReleaser(CDecoder *coder): m_Coder(coder) {}
|
||||
~CCoderReleaser() { m_Coder->ReleaseStreams(); }
|
||||
};
|
||||
|
||||
CDecoder::CDecoder(): m_IsSolid(false) { }
|
||||
|
||||
void CDecoder::InitStructures()
|
||||
{
|
||||
for(int i = 0; i < kNumRepDists; i++)
|
||||
m_RepDists[i] = 0;
|
||||
m_RepDistPtr = 0;
|
||||
LastLength = 0;
|
||||
LastDist = 0;
|
||||
}
|
||||
|
||||
UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); }
|
||||
|
||||
HRESULT CDecoder::CopyBlock(UInt32 distance, UInt32 len)
|
||||
{
|
||||
m_UnpackSize -= len;
|
||||
return m_OutWindowStream.CopyBlock(distance, len) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
|
||||
UInt32 CDecoder::DecodeNum(const UInt32 *posTab)
|
||||
{
|
||||
UInt32 startPos = 2;
|
||||
UInt32 num = m_InBitStream.GetValue(12);
|
||||
for (;;)
|
||||
{
|
||||
UInt32 cur = (posTab[startPos + 1] - posTab[startPos]) << (12 - startPos);
|
||||
if (num < cur)
|
||||
break;
|
||||
startPos++;
|
||||
num -= cur;
|
||||
}
|
||||
m_InBitStream.MovePos(startPos);
|
||||
return((num >> (12 - startPos)) + posTab[startPos]);
|
||||
}
|
||||
|
||||
static Byte kShortLen1[] = {1,3,4,4,5,6,7,8,8,4,4,5,6,6 };
|
||||
static Byte kShortLen1a[] = {1,4,4,4,5,6,7,8,8,4,4,5,6,6,4 };
|
||||
static Byte kShortLen2[] = {2,3,3,3,4,4,5,6,6,4,4,5,6,6 };
|
||||
static Byte kShortLen2a[] = {2,3,3,4,4,4,5,6,6,4,4,5,6,6,4 };
|
||||
static UInt32 kShortXor1[] = {0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0};
|
||||
static UInt32 kShortXor2[] = {0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0};
|
||||
|
||||
HRESULT CDecoder::ShortLZ()
|
||||
{
|
||||
UInt32 len, saveLen, dist;
|
||||
int distancePlace;
|
||||
Byte *kShortLen;
|
||||
const UInt32 *kShortXor;
|
||||
NumHuf = 0;
|
||||
|
||||
if (LCount == 2)
|
||||
{
|
||||
if (ReadBits(1))
|
||||
return CopyBlock(LastDist, LastLength);
|
||||
LCount = 0;
|
||||
}
|
||||
|
||||
UInt32 bitField = m_InBitStream.GetValue(8);
|
||||
|
||||
if (AvrLn1 < 37)
|
||||
{
|
||||
kShortLen = Buf60 ? kShortLen1a : kShortLen1;
|
||||
kShortXor = kShortXor1;
|
||||
}
|
||||
else
|
||||
{
|
||||
kShortLen = Buf60 ? kShortLen2a : kShortLen2;
|
||||
kShortXor = kShortXor2;
|
||||
}
|
||||
|
||||
for (len = 0; ((bitField ^ kShortXor[len]) & (~(0xff >> kShortLen[len]))) != 0; len++);
|
||||
m_InBitStream.MovePos(kShortLen[len]);
|
||||
|
||||
if (len >= 9)
|
||||
{
|
||||
if (len == 9)
|
||||
{
|
||||
LCount++;
|
||||
return CopyBlock(LastDist, LastLength);
|
||||
}
|
||||
if (len == 14)
|
||||
{
|
||||
LCount = 0;
|
||||
len = DecodeNum(PosL2) + 5;
|
||||
dist = 0x8000 + ReadBits(15) - 1;
|
||||
LastLength = len;
|
||||
LastDist = dist;
|
||||
return CopyBlock(dist, len);
|
||||
}
|
||||
|
||||
LCount = 0;
|
||||
saveLen = len;
|
||||
dist = m_RepDists[(m_RepDistPtr - (len - 9)) & 3];
|
||||
len = DecodeNum(PosL1) + 2;
|
||||
if (len == 0x101 && saveLen == 10)
|
||||
{
|
||||
Buf60 ^= 1;
|
||||
return S_OK;
|
||||
}
|
||||
if (dist >= 256)
|
||||
len++;
|
||||
if (dist >= MaxDist3 - 1)
|
||||
len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCount = 0;
|
||||
AvrLn1 += len;
|
||||
AvrLn1 -= AvrLn1 >> 4;
|
||||
|
||||
distancePlace = DecodeNum(PosHf2) & 0xff;
|
||||
dist = ChSetA[distancePlace];
|
||||
if (--distancePlace != -1)
|
||||
{
|
||||
PlaceA[dist]--;
|
||||
UInt32 lastDistance = ChSetA[distancePlace];
|
||||
PlaceA[lastDistance]++;
|
||||
ChSetA[distancePlace + 1] = lastDistance;
|
||||
ChSetA[distancePlace] = dist;
|
||||
}
|
||||
len += 2;
|
||||
}
|
||||
m_RepDists[m_RepDistPtr++] = dist;
|
||||
m_RepDistPtr &= 3;
|
||||
LastLength = len;
|
||||
LastDist = dist;
|
||||
return CopyBlock(dist, len);
|
||||
}
|
||||
|
||||
|
||||
HRESULT CDecoder::LongLZ()
|
||||
{
|
||||
UInt32 len;
|
||||
UInt32 dist;
|
||||
UInt32 distancePlace, newDistancePlace;
|
||||
UInt32 oldAvr2, oldAvr3;
|
||||
|
||||
NumHuf = 0;
|
||||
Nlzb += 16;
|
||||
if (Nlzb > 0xff)
|
||||
{
|
||||
Nlzb = 0x90;
|
||||
Nhfb >>= 1;
|
||||
}
|
||||
oldAvr2=AvrLn2;
|
||||
|
||||
if (AvrLn2 >= 122)
|
||||
len = DecodeNum(PosL2);
|
||||
else if (AvrLn2 >= 64)
|
||||
len = DecodeNum(PosL1);
|
||||
else
|
||||
{
|
||||
UInt32 bitField = m_InBitStream.GetValue(16);
|
||||
if (bitField < 0x100)
|
||||
{
|
||||
len = bitField;
|
||||
m_InBitStream.MovePos(16);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (len = 0; ((bitField << len) & 0x8000) == 0; len++)
|
||||
;
|
||||
m_InBitStream.MovePos(len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
AvrLn2 += len;
|
||||
AvrLn2 -= AvrLn2 >> 5;
|
||||
|
||||
if (AvrPlcB > 0x28ff)
|
||||
distancePlace = DecodeNum(PosHf2);
|
||||
else if (AvrPlcB > 0x6ff)
|
||||
distancePlace = DecodeNum(PosHf1);
|
||||
else
|
||||
distancePlace = DecodeNum(PosHf0);
|
||||
|
||||
AvrPlcB += distancePlace;
|
||||
AvrPlcB -= AvrPlcB >> 8;
|
||||
for (;;)
|
||||
{
|
||||
dist = ChSetB[distancePlace & 0xff];
|
||||
newDistancePlace = NToPlB[dist++ & 0xff]++;
|
||||
if (!(dist & 0xff))
|
||||
CorrHuff(ChSetB,NToPlB);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
ChSetB[distancePlace] = ChSetB[newDistancePlace];
|
||||
ChSetB[newDistancePlace] = dist;
|
||||
|
||||
dist = ((dist & 0xff00) >> 1) | ReadBits(7);
|
||||
|
||||
oldAvr3 = AvrLn3;
|
||||
if (len != 1 && len != 4)
|
||||
if (len == 0 && dist <= MaxDist3)
|
||||
{
|
||||
AvrLn3++;
|
||||
AvrLn3 -= AvrLn3 >> 8;
|
||||
}
|
||||
else
|
||||
if (AvrLn3 > 0)
|
||||
AvrLn3--;
|
||||
len += 3;
|
||||
if (dist >= MaxDist3)
|
||||
len++;
|
||||
if (dist <= 256)
|
||||
len += 8;
|
||||
if (oldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && oldAvr2 < 0x40)
|
||||
MaxDist3 = 0x7f00;
|
||||
else
|
||||
MaxDist3 = 0x2001;
|
||||
m_RepDists[m_RepDistPtr++] = --dist;
|
||||
m_RepDistPtr &= 3;
|
||||
LastLength = len;
|
||||
LastDist = dist;
|
||||
return CopyBlock(dist, len);
|
||||
}
|
||||
|
||||
|
||||
HRESULT CDecoder::HuffDecode()
|
||||
{
|
||||
UInt32 curByte, newBytePlace;
|
||||
UInt32 len;
|
||||
UInt32 dist;
|
||||
int bytePlace;
|
||||
|
||||
if (AvrPlc > 0x75ff) bytePlace = DecodeNum(PosHf4);
|
||||
else if (AvrPlc > 0x5dff) bytePlace = DecodeNum(PosHf3);
|
||||
else if (AvrPlc > 0x35ff) bytePlace = DecodeNum(PosHf2);
|
||||
else if (AvrPlc > 0x0dff) bytePlace = DecodeNum(PosHf1);
|
||||
else bytePlace = DecodeNum(PosHf0);
|
||||
if (StMode)
|
||||
{
|
||||
if (--bytePlace == -1)
|
||||
{
|
||||
if (ReadBits(1))
|
||||
{
|
||||
NumHuf = StMode = 0;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = (ReadBits(1)) ? 4 : 3;
|
||||
dist = DecodeNum(PosHf2);
|
||||
dist = (dist << 5) | ReadBits(5);
|
||||
return CopyBlock(dist - 1, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (NumHuf++ >= 16 && FlagsCnt == 0)
|
||||
StMode = 1;
|
||||
bytePlace &= 0xff;
|
||||
AvrPlc += bytePlace;
|
||||
AvrPlc -= AvrPlc >> 8;
|
||||
Nhfb+=16;
|
||||
if (Nhfb > 0xff)
|
||||
{
|
||||
Nhfb=0x90;
|
||||
Nlzb >>= 1;
|
||||
}
|
||||
|
||||
m_UnpackSize --;
|
||||
m_OutWindowStream.PutByte((Byte)(ChSet[bytePlace] >> 8));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
curByte = ChSet[bytePlace];
|
||||
newBytePlace = NToPl[curByte++ & 0xff]++;
|
||||
if ((curByte & 0xff) > 0xa1)
|
||||
CorrHuff(ChSet, NToPl);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
ChSet[bytePlace] = ChSet[newBytePlace];
|
||||
ChSet[newBytePlace] = curByte;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
void CDecoder::GetFlagsBuf()
|
||||
{
|
||||
UInt32 flags, newFlagsPlace;
|
||||
UInt32 flagsPlace = DecodeNum(PosHf2);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
flags = ChSetC[flagsPlace];
|
||||
FlagBuf = flags >> 8;
|
||||
newFlagsPlace = NToPlC[flags++ & 0xff]++;
|
||||
if ((flags & 0xff) != 0)
|
||||
break;
|
||||
CorrHuff(ChSetC, NToPlC);
|
||||
}
|
||||
|
||||
ChSetC[flagsPlace] = ChSetC[newFlagsPlace];
|
||||
ChSetC[newFlagsPlace] = flags;
|
||||
}
|
||||
|
||||
void CDecoder::InitData()
|
||||
{
|
||||
if (!m_IsSolid)
|
||||
{
|
||||
AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0;
|
||||
AvrPlc = 0x3500;
|
||||
MaxDist3 = 0x2001;
|
||||
Nhfb = Nlzb = 0x80;
|
||||
}
|
||||
FlagsCnt = 0;
|
||||
FlagBuf = 0;
|
||||
StMode = 0;
|
||||
LCount = 0;
|
||||
}
|
||||
|
||||
void CDecoder::CorrHuff(UInt32 *CharSet,UInt32 *NumToPlace)
|
||||
{
|
||||
int i;
|
||||
for (i = 7; i >= 0; i--)
|
||||
for (int j = 0; j < 32; j++, CharSet++)
|
||||
*CharSet = (*CharSet & ~0xff) | i;
|
||||
memset(NumToPlace, 0, sizeof(NToPl));
|
||||
for (i = 6; i >= 0; i--)
|
||||
NumToPlace[i] = (7 - i) * 32;
|
||||
}
|
||||
|
||||
void CDecoder::InitHuff()
|
||||
{
|
||||
for (UInt32 i = 0; i < 256; i++)
|
||||
{
|
||||
Place[i] = PlaceA[i] = PlaceB[i] = i;
|
||||
PlaceC[i] = (~i + 1) & 0xff;
|
||||
ChSet[i] = ChSetB[i] = i << 8;
|
||||
ChSetA[i] = i;
|
||||
ChSetC[i] = ((~i + 1) & 0xff) << 8;
|
||||
}
|
||||
memset(NToPl, 0, sizeof(NToPl));
|
||||
memset(NToPlB, 0, sizeof(NToPlB));
|
||||
memset(NToPlC, 0, sizeof(NToPlC));
|
||||
CorrHuff(ChSetB, NToPlB);
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo * /* progress */)
|
||||
{
|
||||
if (inSize == NULL || outSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!m_OutWindowStream.Create(kHistorySize))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!m_InBitStream.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
m_UnpackSize = (Int64)*outSize;
|
||||
m_OutWindowStream.SetStream(outStream);
|
||||
m_OutWindowStream.Init(m_IsSolid);
|
||||
m_InBitStream.SetStream(inStream);
|
||||
m_InBitStream.Init();
|
||||
|
||||
CCoderReleaser coderReleaser(this);
|
||||
InitData();
|
||||
if (!m_IsSolid)
|
||||
{
|
||||
InitStructures();
|
||||
InitHuff();
|
||||
}
|
||||
if (m_UnpackSize > 0)
|
||||
{
|
||||
GetFlagsBuf();
|
||||
FlagsCnt = 8;
|
||||
}
|
||||
|
||||
while (m_UnpackSize > 0)
|
||||
{
|
||||
if (StMode)
|
||||
{
|
||||
RINOK(HuffDecode());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (--FlagsCnt < 0)
|
||||
{
|
||||
GetFlagsBuf();
|
||||
FlagsCnt=7;
|
||||
}
|
||||
|
||||
if (FlagBuf & 0x80)
|
||||
{
|
||||
FlagBuf <<= 1;
|
||||
if (Nlzb > Nhfb)
|
||||
{
|
||||
RINOK(LongLZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(HuffDecode());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FlagBuf <<= 1;
|
||||
if (--FlagsCnt < 0)
|
||||
{
|
||||
GetFlagsBuf();
|
||||
FlagsCnt = 7;
|
||||
}
|
||||
if (FlagBuf & 0x80)
|
||||
{
|
||||
FlagBuf <<= 1;
|
||||
if (Nlzb > Nhfb)
|
||||
{
|
||||
RINOK(HuffDecode());
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(LongLZ());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FlagBuf <<= 1;
|
||||
RINOK(ShortLZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_UnpackSize < 0)
|
||||
return S_FALSE;
|
||||
return m_OutWindowStream.Flush();
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try
|
||||
{
|
||||
HRESULT res = CodeReal(inStream, outStream, inSize, outSize, progress);
|
||||
m_OutWindowStream.Flush();
|
||||
return res;
|
||||
}
|
||||
catch(const CLZOutWindowException &e) { m_OutWindowStream.Flush(); return e.ErrorCode; }
|
||||
catch(...) { m_OutWindowStream.Flush(); return S_FALSE; }
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
|
||||
{
|
||||
if (size < 1)
|
||||
return E_INVALIDARG;
|
||||
m_IsSolid = (data[0] != 0);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
90
CPP/7zip/Compress/Rar/Rar1Decoder.h
Executable file
90
CPP/7zip/Compress/Rar/Rar1Decoder.h
Executable file
@@ -0,0 +1,90 @@
|
||||
// Rar15Decoder.h
|
||||
// According to unRAR license,
|
||||
// this code may not be used to develop a
|
||||
// RAR (WinRAR) compatible archiver
|
||||
|
||||
#ifndef __RAR10_DECODER_H
|
||||
#define __RAR10_DECODER_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/MSBFDecoder.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
|
||||
#include "../LZ/LZOutWindow.h"
|
||||
#include "../Huffman/HuffmanDecoder.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRar1 {
|
||||
|
||||
const UInt32 kNumRepDists = 4;
|
||||
|
||||
typedef NStream::NMSBF::CDecoder<CInBuffer> CBitDecoder;
|
||||
|
||||
class CDecoder :
|
||||
public ICompressCoder,
|
||||
public ICompressSetDecoderProperties2,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
CLZOutWindow m_OutWindowStream;
|
||||
CBitDecoder m_InBitStream;
|
||||
|
||||
UInt32 m_RepDists[kNumRepDists];
|
||||
UInt32 m_RepDistPtr;
|
||||
|
||||
UInt32 LastDist;
|
||||
UInt32 LastLength;
|
||||
|
||||
Int64 m_UnpackSize;
|
||||
bool m_IsSolid;
|
||||
|
||||
UInt32 ReadBits(int numBits);
|
||||
HRESULT CopyBlock(UInt32 distance, UInt32 len);
|
||||
|
||||
UInt32 DecodeNum(const UInt32 *posTab);
|
||||
HRESULT ShortLZ();
|
||||
HRESULT LongLZ();
|
||||
HRESULT HuffDecode();
|
||||
void GetFlagsBuf();
|
||||
void InitData();
|
||||
void InitHuff();
|
||||
void CorrHuff(UInt32 *CharSet, UInt32 *NumToPlace);
|
||||
void OldUnpWriteBuf();
|
||||
|
||||
UInt32 ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256];
|
||||
UInt32 Place[256],PlaceA[256],PlaceB[256],PlaceC[256];
|
||||
UInt32 NToPl[256],NToPlB[256],NToPlC[256];
|
||||
UInt32 FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3;
|
||||
int Buf60,NumHuf,StMode,LCount,FlagsCnt;
|
||||
UInt32 Nhfb,Nlzb,MaxDist3;
|
||||
|
||||
void InitStructures();
|
||||
|
||||
public:
|
||||
CDecoder();
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
|
||||
|
||||
void ReleaseStreams()
|
||||
{
|
||||
m_OutWindowStream.ReleaseStream();
|
||||
m_InBitStream.ReleaseStream();
|
||||
}
|
||||
|
||||
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(SetDecoderProperties2)(const Byte *data, UInt32 size);
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
297
CPP/7zip/Compress/Rar/Rar29.dsp
Executable file
297
CPP/7zip/Compress/Rar/Rar29.dsp
Executable file
@@ -0,0 +1,297 @@
|
||||
# Microsoft Developer Studio Project File - Name="Rar29" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=Rar29 - 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 "Rar29.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 "Rar29.mak" CFG="Rar29 - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Rar29 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "Rar29 - 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)" == "Rar29 - 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 "RAR29_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAR29_EXPORTS" /D "SILENT" /D "NOCRYPT" /D "NOVOLUME" /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\Rar29.dll" /opt:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "Rar29 - 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 "RAR29_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 "RAR29_EXPORTS" /D "SILENT" /D "NOCRYPT" /D "NOVOLUME" /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\Rar29.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "Rar29 - Win32 Release"
|
||||
# Name "Rar29 - 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 "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\MSBFDecoder.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 "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 "Huffman"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Huffman\HuffmanDecoder.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
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Vector.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Vector.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Rar3"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\PPMD\PPMDContext.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\PPMD\PPMDDecode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\PPMD\PPMDSubAlloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\PPMD\PPMDType.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Rar1Decoder.cpp
|
||||
|
||||
!IF "$(CFG)" == "Rar29 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Rar1Decoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Rar2Decoder.cpp
|
||||
|
||||
!IF "$(CFG)" == "Rar29 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Rar2Decoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Rar3Decoder.cpp
|
||||
|
||||
!IF "$(CFG)" == "Rar29 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Rar3Decoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Rar3Vm.cpp
|
||||
|
||||
!IF "$(CFG)" == "Rar29 - Win32 Release"
|
||||
|
||||
# ADD CPP /O2
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
|
||||
!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Rar3Vm.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
29
CPP/7zip/Compress/Rar/Rar29.dsw
Executable file
29
CPP/7zip/Compress/Rar/Rar29.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: "Rar29"=.\Rar29.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
401
CPP/7zip/Compress/Rar/Rar2Decoder.cpp
Executable file
401
CPP/7zip/Compress/Rar/Rar2Decoder.cpp
Executable file
@@ -0,0 +1,401 @@
|
||||
// Rar2Decoder.cpp
|
||||
// According to unRAR license,
|
||||
// this code may not be used to develop a
|
||||
// RAR (WinRAR) compatible archiver
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Rar2Decoder.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRar2 {
|
||||
|
||||
namespace NMultimedia {
|
||||
|
||||
Byte CFilter::Decode(int &channelDelta, Byte deltaByte)
|
||||
{
|
||||
D4 = D3;
|
||||
D3 = D2;
|
||||
D2 = LastDelta - D1;
|
||||
D1 = LastDelta;
|
||||
int predictedValue = ((8 * LastChar + K1 * D1 + K2 * D2 + K3 * D3 + K4 * D4 + K5 * channelDelta) >> 3);
|
||||
|
||||
Byte realValue = (Byte)(predictedValue - deltaByte);
|
||||
int i = ((int)(signed char)deltaByte) << 3;
|
||||
|
||||
Dif[0] += abs(i);
|
||||
Dif[1] += abs(i - D1);
|
||||
Dif[2] += abs(i + D1);
|
||||
Dif[3] += abs(i - D2);
|
||||
Dif[4] += abs(i + D2);
|
||||
Dif[5] += abs(i - D3);
|
||||
Dif[6] += abs(i + D3);
|
||||
Dif[7] += abs(i - D4);
|
||||
Dif[8] += abs(i + D4);
|
||||
Dif[9] += abs(i - channelDelta);
|
||||
Dif[10] += abs(i + channelDelta);
|
||||
|
||||
channelDelta = LastDelta = (signed char)(realValue - LastChar);
|
||||
LastChar = realValue;
|
||||
|
||||
if (((++ByteCount) & 0x1F) == 0)
|
||||
{
|
||||
UInt32 minDif = Dif[0];
|
||||
UInt32 numMinDif = 0;
|
||||
Dif[0] = 0;
|
||||
for (i = 1; i < sizeof(Dif) / sizeof(Dif[0]); i++)
|
||||
{
|
||||
if (Dif[i] < minDif)
|
||||
{
|
||||
minDif = Dif[i];
|
||||
numMinDif = i;
|
||||
}
|
||||
Dif[i] = 0;
|
||||
}
|
||||
switch(numMinDif)
|
||||
{
|
||||
case 1: if (K1 >= -16) K1--; break;
|
||||
case 2: if (K1 < 16) K1++; break;
|
||||
case 3: if (K2 >= -16) K2--; break;
|
||||
case 4: if (K2 < 16) K2++; break;
|
||||
case 5: if (K3 >= -16) K3--; break;
|
||||
case 6: if (K3 < 16) K3++; break;
|
||||
case 7: if (K4 >= -16) K4--; break;
|
||||
case 8: if (K4 < 16) K4++; break;
|
||||
case 9: if (K5 >= -16) K5--; break;
|
||||
case 10:if (K5 < 16) K5++; break;
|
||||
}
|
||||
}
|
||||
return realValue;
|
||||
}
|
||||
}
|
||||
|
||||
class CException
|
||||
{
|
||||
public:
|
||||
enum ECauseType
|
||||
{
|
||||
kData
|
||||
} Cause;
|
||||
CException(ECauseType cause): Cause(cause) {}
|
||||
};
|
||||
|
||||
static const char *kNumberErrorMessage = "Number error";
|
||||
|
||||
static const UInt32 kHistorySize = 1 << 20;
|
||||
|
||||
static const int kNumStats = 11;
|
||||
|
||||
static const UInt32 kWindowReservSize = (1 << 22) + 256;
|
||||
|
||||
CDecoder::CDecoder():
|
||||
m_IsSolid(false)
|
||||
{
|
||||
}
|
||||
|
||||
void CDecoder::InitStructures()
|
||||
{
|
||||
m_MmFilter.Init();
|
||||
for(int i = 0; i < kNumRepDists; i++)
|
||||
m_RepDists[i] = 0;
|
||||
m_RepDistPtr = 0;
|
||||
m_LastLength = 0;
|
||||
memset(m_LastLevels, 0, kMaxTableSize);
|
||||
}
|
||||
|
||||
UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); }
|
||||
|
||||
#define RIF(x) { if (!(x)) return false; }
|
||||
|
||||
bool CDecoder::ReadTables(void)
|
||||
{
|
||||
Byte levelLevels[kLevelTableSize];
|
||||
Byte newLevels[kMaxTableSize];
|
||||
m_AudioMode = (ReadBits(1) == 1);
|
||||
|
||||
if (ReadBits(1) == 0)
|
||||
memset(m_LastLevels, 0, kMaxTableSize);
|
||||
int numLevels;
|
||||
if (m_AudioMode)
|
||||
{
|
||||
m_NumChannels = ReadBits(2) + 1;
|
||||
if (m_MmFilter.CurrentChannel >= m_NumChannels)
|
||||
m_MmFilter.CurrentChannel = 0;
|
||||
numLevels = m_NumChannels * kMMTableSize;
|
||||
}
|
||||
else
|
||||
numLevels = kHeapTablesSizesSum;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < kLevelTableSize; i++)
|
||||
levelLevels[i] = (Byte)ReadBits(4);
|
||||
RIF(m_LevelDecoder.SetCodeLengths(levelLevels));
|
||||
i = 0;
|
||||
while (i < numLevels)
|
||||
{
|
||||
UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number < kTableDirectLevels)
|
||||
{
|
||||
newLevels[i] = (Byte)((number + m_LastLevels[i]) & kLevelMask);
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (number == kTableLevelRepNumber)
|
||||
{
|
||||
int t = ReadBits(2) + 3;
|
||||
for (int reps = t; reps > 0 && i < numLevels ; reps--, i++)
|
||||
newLevels[i] = newLevels[i - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
int num;
|
||||
if (number == kTableLevel0Number)
|
||||
num = ReadBits(3) + 3;
|
||||
else if (number == kTableLevel0Number2)
|
||||
num = ReadBits(7) + 11;
|
||||
else
|
||||
return false;
|
||||
for (;num > 0 && i < numLevels; num--)
|
||||
newLevels[i++] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_AudioMode)
|
||||
for (i = 0; i < m_NumChannels; i++)
|
||||
{
|
||||
RIF(m_MMDecoders[i].SetCodeLengths(&newLevels[i * kMMTableSize]));
|
||||
}
|
||||
else
|
||||
{
|
||||
RIF(m_MainDecoder.SetCodeLengths(&newLevels[0]));
|
||||
RIF(m_DistDecoder.SetCodeLengths(&newLevels[kMainTableSize]));
|
||||
RIF(m_LenDecoder.SetCodeLengths(&newLevels[kMainTableSize + kDistTableSize]));
|
||||
}
|
||||
memcpy(m_LastLevels, newLevels, kMaxTableSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDecoder::ReadLastTables()
|
||||
{
|
||||
// it differs a little from pure RAR sources;
|
||||
// UInt64 ttt = m_InBitStream.GetProcessedSize() + 2;
|
||||
// + 2 works for: return 0xFF; in CInBuffer::ReadByte.
|
||||
if (m_InBitStream.GetProcessedSize() + 7 <= m_PackSize) // test it: probably incorrect;
|
||||
// if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect;
|
||||
if (m_AudioMode)
|
||||
{
|
||||
UInt32 symbol = m_MMDecoders[m_MmFilter.CurrentChannel].DecodeSymbol(&m_InBitStream);
|
||||
if (symbol == 256)
|
||||
return ReadTables();
|
||||
if (symbol >= kMMTableSize)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number == kReadTableNumber)
|
||||
return ReadTables();
|
||||
if (number >= kMainTableSize)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class CCoderReleaser
|
||||
{
|
||||
CDecoder *m_Coder;
|
||||
public:
|
||||
CCoderReleaser(CDecoder *coder): m_Coder(coder) {}
|
||||
~CCoderReleaser()
|
||||
{
|
||||
m_Coder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
|
||||
bool CDecoder::DecodeMm(UInt32 pos)
|
||||
{
|
||||
while (pos-- > 0)
|
||||
{
|
||||
UInt32 symbol = m_MMDecoders[m_MmFilter.CurrentChannel].DecodeSymbol(&m_InBitStream);
|
||||
if (symbol == 256)
|
||||
return true;
|
||||
if (symbol >= kMMTableSize)
|
||||
return false;
|
||||
/*
|
||||
Byte byPredict = m_Predictor.Predict();
|
||||
Byte byReal = (Byte)(byPredict - (Byte)symbol);
|
||||
m_Predictor.Update(byReal, byPredict);
|
||||
*/
|
||||
Byte byReal = m_MmFilter.Decode((Byte)symbol);
|
||||
m_OutWindowStream.PutByte(byReal);
|
||||
if (++m_MmFilter.CurrentChannel == m_NumChannels)
|
||||
m_MmFilter.CurrentChannel = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDecoder::DecodeLz(Int32 pos)
|
||||
{
|
||||
while (pos > 0)
|
||||
{
|
||||
UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
|
||||
UInt32 length, distance;
|
||||
if (number < 256)
|
||||
{
|
||||
m_OutWindowStream.PutByte(Byte(number));
|
||||
pos--;
|
||||
continue;
|
||||
}
|
||||
else if (number >= kMatchNumber)
|
||||
{
|
||||
number -= kMatchNumber;
|
||||
length = kNormalMatchMinLen + UInt32(kLenStart[number]) +
|
||||
m_InBitStream.ReadBits(kLenDirectBits[number]);
|
||||
number = m_DistDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number >= kDistTableSize)
|
||||
return false;
|
||||
distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]);
|
||||
if (distance >= kDistLimit3)
|
||||
{
|
||||
length += 2 - ((distance - kDistLimit4) >> 31);
|
||||
// length++;
|
||||
// if (distance >= kDistLimit4)
|
||||
// length++;
|
||||
}
|
||||
}
|
||||
else if (number == kRepBothNumber)
|
||||
{
|
||||
length = m_LastLength;
|
||||
distance = m_RepDists[(m_RepDistPtr + 4 - 1) & 3];
|
||||
}
|
||||
else if (number < kLen2Number)
|
||||
{
|
||||
distance = m_RepDists[(m_RepDistPtr - (number - kRepNumber + 1)) & 3];
|
||||
number = m_LenDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number >= kLenTableSize)
|
||||
return false;
|
||||
length = 2 + kLenStart[number] + m_InBitStream.ReadBits(kLenDirectBits[number]);
|
||||
if (distance >= kDistLimit2)
|
||||
{
|
||||
length++;
|
||||
if (distance >= kDistLimit3)
|
||||
{
|
||||
length += 2 - ((distance - kDistLimit4) >> 31);
|
||||
// length++;
|
||||
// if (distance >= kDistLimit4)
|
||||
// length++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (number < kReadTableNumber)
|
||||
{
|
||||
number -= kLen2Number;
|
||||
distance = kLen2DistStarts[number] +
|
||||
m_InBitStream.ReadBits(kLen2DistDirectBits[number]);
|
||||
length = 2;
|
||||
}
|
||||
else if (number == kReadTableNumber)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
m_RepDists[m_RepDistPtr++ & 3] = distance;
|
||||
m_LastLength = length;
|
||||
if (!m_OutWindowStream.CopyBlock(distance, length))
|
||||
return false;
|
||||
pos -= length;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (inSize == NULL || outSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!m_OutWindowStream.Create(kHistorySize))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!m_InBitStream.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
m_PackSize = *inSize;
|
||||
|
||||
UInt64 pos = 0, unPackSize = *outSize;
|
||||
|
||||
m_OutWindowStream.SetStream(outStream);
|
||||
m_OutWindowStream.Init(m_IsSolid);
|
||||
m_InBitStream.SetStream(inStream);
|
||||
m_InBitStream.Init();
|
||||
|
||||
CCoderReleaser coderReleaser(this);
|
||||
if (!m_IsSolid)
|
||||
{
|
||||
InitStructures();
|
||||
if (unPackSize == 0)
|
||||
{
|
||||
if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect;
|
||||
if (!ReadTables())
|
||||
return S_FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
if (!ReadTables())
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
UInt64 startPos = m_OutWindowStream.GetProcessedSize();
|
||||
while(pos < unPackSize)
|
||||
{
|
||||
UInt32 blockSize = 1 << 20;
|
||||
if (blockSize > unPackSize - pos)
|
||||
blockSize = (UInt32)(unPackSize - pos);
|
||||
UInt64 blockStartPos = m_OutWindowStream.GetProcessedSize();
|
||||
if (m_AudioMode)
|
||||
{
|
||||
if (!DecodeMm(blockSize))
|
||||
return S_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!DecodeLz((Int32)blockSize))
|
||||
return S_FALSE;
|
||||
}
|
||||
UInt64 globalPos = m_OutWindowStream.GetProcessedSize();
|
||||
pos = globalPos - blockStartPos;
|
||||
if (pos < blockSize)
|
||||
if (!ReadTables())
|
||||
return S_FALSE;
|
||||
pos = globalPos - startPos;
|
||||
if (progress != 0)
|
||||
{
|
||||
UInt64 packSize = m_InBitStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &pos));
|
||||
}
|
||||
}
|
||||
if (pos > unPackSize)
|
||||
throw CException(CException::kData);
|
||||
|
||||
if (!ReadLastTables())
|
||||
return S_FALSE;
|
||||
return m_OutWindowStream.Flush();
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
catch(const CLZOutWindowException &e) { return e.ErrorCode; }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
|
||||
{
|
||||
if (size < 1)
|
||||
return E_INVALIDARG;
|
||||
m_IsSolid = (data[0] != 0);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
176
CPP/7zip/Compress/Rar/Rar2Decoder.h
Executable file
176
CPP/7zip/Compress/Rar/Rar2Decoder.h
Executable file
@@ -0,0 +1,176 @@
|
||||
// Rar2Decoder.h
|
||||
// According to unRAR license,
|
||||
// this code may not be used to develop a
|
||||
// RAR (WinRAR) compatible archiver
|
||||
|
||||
#ifndef __RAR2DECODER_H
|
||||
#define __RAR2DECODER_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/MSBFDecoder.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
|
||||
#include "../LZ/LZOutWindow.h"
|
||||
#include "../Huffman/HuffmanDecoder.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRar2 {
|
||||
|
||||
const UInt32 kNumRepDists = 4;
|
||||
const UInt32 kDistTableSize = 48;
|
||||
|
||||
const int kMMTableSize = 256 + 1;
|
||||
|
||||
const UInt32 kMainTableSize = 298;
|
||||
const UInt32 kLenTableSize = 28;
|
||||
|
||||
const UInt32 kDistTableStart = kMainTableSize;
|
||||
const UInt32 kLenTableStart = kDistTableStart + kDistTableSize;
|
||||
|
||||
const UInt32 kHeapTablesSizesSum = kMainTableSize + kDistTableSize + kLenTableSize;
|
||||
|
||||
const UInt32 kLevelTableSize = 19;
|
||||
|
||||
const UInt32 kMMTablesSizesSum = kMMTableSize * 4;
|
||||
|
||||
const UInt32 kMaxTableSize = kMMTablesSizesSum;
|
||||
|
||||
const UInt32 kTableDirectLevels = 16;
|
||||
const UInt32 kTableLevelRepNumber = kTableDirectLevels;
|
||||
const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1;
|
||||
const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1;
|
||||
|
||||
const UInt32 kLevelMask = 0xF;
|
||||
|
||||
|
||||
const UInt32 kRepBothNumber = 256;
|
||||
const UInt32 kRepNumber = kRepBothNumber + 1;
|
||||
const UInt32 kLen2Number = kRepNumber + 4;
|
||||
|
||||
const UInt32 kLen2NumNumbers = 8;
|
||||
const UInt32 kReadTableNumber = kLen2Number + kLen2NumNumbers;
|
||||
const UInt32 kMatchNumber = kReadTableNumber + 1;
|
||||
|
||||
const Byte kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
|
||||
const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
|
||||
|
||||
const UInt32 kDistStart[kDistTableSize] = {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,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040};
|
||||
const Byte kDistDirectBits[kDistTableSize] = {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, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
|
||||
|
||||
const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
|
||||
|
||||
const Byte kLen2DistStarts[kLen2NumNumbers]={0,4,8,16,32,64,128,192};
|
||||
const Byte kLen2DistDirectBits[kLen2NumNumbers]={2,2,3, 4, 5, 6, 6, 6};
|
||||
|
||||
const UInt32 kDistLimit2 = 0x101 - 1;
|
||||
const UInt32 kDistLimit3 = 0x2000 - 1;
|
||||
const UInt32 kDistLimit4 = 0x40000 - 1;
|
||||
|
||||
const UInt32 kMatchMaxLen = 255 + 2;
|
||||
const UInt32 kMatchMaxLenMax = 255 + 5;
|
||||
const UInt32 kNormalMatchMinLen = 3;
|
||||
|
||||
namespace NMultimedia {
|
||||
|
||||
struct CFilter
|
||||
{
|
||||
int K1,K2,K3,K4,K5;
|
||||
int D1,D2,D3,D4;
|
||||
int LastDelta;
|
||||
UInt32 Dif[11];
|
||||
UInt32 ByteCount;
|
||||
int LastChar;
|
||||
|
||||
Byte Decode(int &channelDelta, Byte delta);
|
||||
|
||||
void Init() { memset(this, 0, sizeof(*this)); }
|
||||
|
||||
};
|
||||
|
||||
const int kNumChanelsMax = 4;
|
||||
|
||||
class CFilter2
|
||||
{
|
||||
public:
|
||||
CFilter m_Filters[kNumChanelsMax];
|
||||
int m_ChannelDelta;
|
||||
int CurrentChannel;
|
||||
|
||||
void Init() { memset(this, 0, sizeof(*this)); }
|
||||
Byte Decode(Byte delta)
|
||||
{
|
||||
return m_Filters[CurrentChannel].Decode(m_ChannelDelta, delta);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef NStream::NMSBF::CDecoder<CInBuffer> CBitDecoder;
|
||||
|
||||
const int kNumHuffmanBits = 15;
|
||||
|
||||
class CDecoder :
|
||||
public ICompressCoder,
|
||||
public ICompressSetDecoderProperties2,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CLZOutWindow m_OutWindowStream;
|
||||
CBitDecoder m_InBitStream;
|
||||
NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder;
|
||||
NHuffman::CDecoder<kNumHuffmanBits, kDistTableSize> m_DistDecoder;
|
||||
NHuffman::CDecoder<kNumHuffmanBits, kLenTableSize> m_LenDecoder;
|
||||
NHuffman::CDecoder<kNumHuffmanBits, kMMTableSize> m_MMDecoders[NMultimedia::kNumChanelsMax];
|
||||
NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
|
||||
|
||||
bool m_AudioMode;
|
||||
|
||||
NMultimedia::CFilter2 m_MmFilter;
|
||||
int m_NumChannels;
|
||||
|
||||
UInt32 m_RepDists[kNumRepDists];
|
||||
UInt32 m_RepDistPtr;
|
||||
|
||||
UInt32 m_LastLength;
|
||||
|
||||
Byte m_LastLevels[kMaxTableSize];
|
||||
|
||||
UInt64 m_PackSize;
|
||||
bool m_IsSolid;
|
||||
|
||||
void InitStructures();
|
||||
UInt32 ReadBits(int numBits);
|
||||
bool ReadTables();
|
||||
bool ReadLastTables();
|
||||
|
||||
bool DecodeMm(UInt32 pos);
|
||||
bool DecodeLz(Int32 pos);
|
||||
|
||||
public:
|
||||
CDecoder();
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
|
||||
|
||||
void ReleaseStreams()
|
||||
{
|
||||
m_OutWindowStream.ReleaseStream();
|
||||
m_InBitStream.ReleaseStream();
|
||||
}
|
||||
|
||||
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(SetDecoderProperties2)(const Byte *data, UInt32 size);
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
832
CPP/7zip/Compress/Rar/Rar3Decoder.cpp
Executable file
832
CPP/7zip/Compress/Rar/Rar3Decoder.cpp
Executable file
@@ -0,0 +1,832 @@
|
||||
// Rar3Decoder.cpp
|
||||
// According to unRAR license,
|
||||
// this code may not be used to develop a
|
||||
// RAR (WinRAR) compatible archiver
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Rar3Decoder.h"
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRar3 {
|
||||
|
||||
static const UInt32 kNumAlignReps = 15;
|
||||
|
||||
static const UInt32 kSymbolReadTable = 256;
|
||||
static const UInt32 kSymbolRep = 259;
|
||||
static const UInt32 kSymbolLen2 = kSymbolRep + kNumReps;
|
||||
|
||||
static const Byte kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
|
||||
static const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
|
||||
|
||||
static const Byte kDistDirectBits[kDistTableSize] =
|
||||
{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,15,15,
|
||||
16,16,16,16,16,16,16,16,16,16,16,16,16,16,
|
||||
18,18,18,18,18,18,18,18,18,18,18,18};
|
||||
|
||||
static const Byte kLevelDirectBits[kLevelTableSize] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
|
||||
|
||||
static const Byte kLen2DistStarts[kNumLen2Symbols]={0,4,8,16,32,64,128,192};
|
||||
static const Byte kLen2DistDirectBits[kNumLen2Symbols]={2,2,3, 4, 5, 6, 6, 6};
|
||||
|
||||
static const UInt32 kDistLimit3 = 0x2000 - 2;
|
||||
static const UInt32 kDistLimit4 = 0x40000 - 2;
|
||||
|
||||
static const UInt32 kNormalMatchMinLen = 3;
|
||||
|
||||
static const UInt32 kVmDataSizeMax = 1 << 16;
|
||||
static const UInt32 kVmCodeSizeMax = 1 << 16;
|
||||
|
||||
CDecoder::CDecoder():
|
||||
_window(0),
|
||||
_winPos(0),
|
||||
_wrPtr(0),
|
||||
_lzSize(0),
|
||||
_writtenFileSize(0),
|
||||
_vmData(0),
|
||||
_vmCode(0),
|
||||
m_IsSolid(false)
|
||||
{
|
||||
}
|
||||
|
||||
CDecoder::~CDecoder()
|
||||
{
|
||||
InitFilters();
|
||||
if (_vmData)
|
||||
::MidFree(_vmData);
|
||||
}
|
||||
|
||||
HRESULT CDecoder::WriteDataToStream(const Byte *data, UInt32 size)
|
||||
{
|
||||
UInt32 processedSize;
|
||||
HRESULT res = WriteStream(_outStream, data, size, &processedSize);
|
||||
if (res == S_OK && processedSize != size)
|
||||
res = E_FAIL;
|
||||
return res;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::WriteData(const Byte *data, UInt32 size)
|
||||
{
|
||||
HRESULT res = S_OK;
|
||||
if (_writtenFileSize < _unpackSize)
|
||||
{
|
||||
UInt32 curSize = size;
|
||||
UInt64 remain = _unpackSize - _writtenFileSize;
|
||||
if (remain < curSize)
|
||||
curSize = (UInt32)remain;
|
||||
res = WriteDataToStream(data, curSize);
|
||||
}
|
||||
_writtenFileSize += size;
|
||||
return res;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::WriteArea(UInt32 startPtr, UInt32 endPtr)
|
||||
{
|
||||
if (startPtr <= endPtr)
|
||||
return WriteData(_window + startPtr, endPtr - startPtr);
|
||||
RINOK(WriteData(_window + startPtr, kWindowSize - startPtr));
|
||||
return WriteData(_window, endPtr);
|
||||
}
|
||||
|
||||
void CDecoder::ExecuteFilter(int tempFilterIndex, NVm::CBlockRef &outBlockRef)
|
||||
{
|
||||
CTempFilter *tempFilter = _tempFilters[tempFilterIndex];
|
||||
tempFilter->InitR[6] = (UInt32)_writtenFileSize;
|
||||
NVm::SetValue32(&tempFilter->GlobalData[0x24], (UInt32)_writtenFileSize);
|
||||
NVm::SetValue32(&tempFilter->GlobalData[0x28], (UInt32)(_writtenFileSize >> 32));
|
||||
CFilter *filter = _filters[tempFilter->FilterIndex];
|
||||
_vm.Execute(filter, tempFilter, outBlockRef, filter->GlobalData);
|
||||
delete tempFilter;
|
||||
_tempFilters[tempFilterIndex] = 0;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::WriteBuf()
|
||||
{
|
||||
UInt32 writtenBorder = _wrPtr;
|
||||
UInt32 writeSize = (_winPos - writtenBorder) & kWindowMask;
|
||||
for (int i = 0; i < _tempFilters.Size(); i++)
|
||||
{
|
||||
CTempFilter *filter = _tempFilters[i];
|
||||
if (filter == NULL)
|
||||
continue;
|
||||
if (filter->NextWindow)
|
||||
{
|
||||
filter->NextWindow = false;
|
||||
continue;
|
||||
}
|
||||
UInt32 blockStart = filter->BlockStart;
|
||||
UInt32 blockSize = filter->BlockSize;
|
||||
if (((blockStart - writtenBorder) & kWindowMask) < writeSize)
|
||||
{
|
||||
if (writtenBorder != blockStart)
|
||||
{
|
||||
RINOK(WriteArea(writtenBorder, blockStart));
|
||||
writtenBorder = blockStart;
|
||||
writeSize = (_winPos - writtenBorder) & kWindowMask;
|
||||
}
|
||||
if (blockSize <= writeSize)
|
||||
{
|
||||
UInt32 blockEnd = (blockStart + blockSize) & kWindowMask;
|
||||
if (blockStart < blockEnd || blockEnd == 0)
|
||||
_vm.SetMemory(0, _window + blockStart, blockSize);
|
||||
else
|
||||
{
|
||||
UInt32 tailSize = kWindowSize - blockStart;
|
||||
_vm.SetMemory(0, _window + blockStart, tailSize);
|
||||
_vm.SetMemory(tailSize, _window, blockEnd);
|
||||
}
|
||||
NVm::CBlockRef outBlockRef;
|
||||
ExecuteFilter(i, outBlockRef);
|
||||
while (i + 1 < _tempFilters.Size())
|
||||
{
|
||||
CTempFilter *nextFilter = _tempFilters[i + 1];
|
||||
if (nextFilter == NULL || nextFilter->BlockStart != blockStart ||
|
||||
nextFilter->BlockSize != outBlockRef.Size || nextFilter->NextWindow)
|
||||
break;
|
||||
_vm.SetMemory(0, _vm.GetDataPointer(outBlockRef.Offset), outBlockRef.Size);
|
||||
ExecuteFilter(++i, outBlockRef);
|
||||
}
|
||||
WriteDataToStream(_vm.GetDataPointer(outBlockRef.Offset), outBlockRef.Size);
|
||||
_writtenFileSize += outBlockRef.Size;
|
||||
writtenBorder = blockEnd;
|
||||
writeSize = (_winPos - writtenBorder) & kWindowMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = i; j < _tempFilters.Size(); j++)
|
||||
{
|
||||
CTempFilter *filter = _tempFilters[j];
|
||||
if (filter != NULL && filter->NextWindow)
|
||||
filter->NextWindow = false;
|
||||
}
|
||||
_wrPtr = writtenBorder;
|
||||
return S_OK; // check it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_wrPtr = _winPos;
|
||||
return WriteArea(writtenBorder, _winPos);
|
||||
}
|
||||
|
||||
void CDecoder::InitFilters()
|
||||
{
|
||||
_lastFilter = 0;
|
||||
int i;
|
||||
for (i = 0; i < _tempFilters.Size(); i++)
|
||||
delete _tempFilters[i];
|
||||
_tempFilters.Clear();
|
||||
for (i = 0; i < _filters.Size(); i++)
|
||||
delete _filters[i];
|
||||
_filters.Clear();
|
||||
}
|
||||
|
||||
bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize)
|
||||
{
|
||||
CMemBitDecoder inp;
|
||||
inp.Init(_vmData, codeSize);
|
||||
|
||||
UInt32 filterIndex;
|
||||
if (firstByte & 0x80)
|
||||
{
|
||||
filterIndex = NVm::ReadEncodedUInt32(inp);
|
||||
if (filterIndex == 0)
|
||||
InitFilters();
|
||||
else
|
||||
filterIndex--;
|
||||
}
|
||||
else
|
||||
filterIndex = _lastFilter;
|
||||
if (filterIndex > (UInt32)_filters.Size())
|
||||
return false;
|
||||
_lastFilter = filterIndex;
|
||||
bool newFilter = (filterIndex == (UInt32)_filters.Size());
|
||||
|
||||
CFilter *filter;
|
||||
if (newFilter)
|
||||
{
|
||||
// check if too many filters
|
||||
if (filterIndex > 1024)
|
||||
return false;
|
||||
filter = new CFilter;
|
||||
_filters.Add(filter);
|
||||
}
|
||||
else
|
||||
{
|
||||
filter = _filters[filterIndex];
|
||||
filter->ExecCount++;
|
||||
}
|
||||
|
||||
int numEmptyItems = 0;
|
||||
int i;
|
||||
for (i = 0; i < _tempFilters.Size(); i++)
|
||||
{
|
||||
_tempFilters[i - numEmptyItems] = _tempFilters[i];
|
||||
if (_tempFilters[i] == NULL)
|
||||
numEmptyItems++;
|
||||
if (numEmptyItems > 0)
|
||||
_tempFilters[i] = NULL;
|
||||
}
|
||||
if (numEmptyItems == 0)
|
||||
{
|
||||
_tempFilters.Add(NULL);
|
||||
numEmptyItems = 1;
|
||||
}
|
||||
CTempFilter *tempFilter = new CTempFilter;
|
||||
_tempFilters[_tempFilters.Size() - numEmptyItems] = tempFilter;
|
||||
tempFilter->FilterIndex = filterIndex;
|
||||
tempFilter->ExecCount = filter->ExecCount;
|
||||
|
||||
UInt32 blockStart = NVm::ReadEncodedUInt32(inp);
|
||||
if (firstByte & 0x40)
|
||||
blockStart += 258;
|
||||
tempFilter->BlockStart = (blockStart + _winPos) & kWindowMask;
|
||||
if (firstByte & 0x20)
|
||||
filter->BlockSize = NVm::ReadEncodedUInt32(inp);
|
||||
tempFilter->BlockSize = filter->BlockSize;
|
||||
tempFilter->NextWindow = _wrPtr != _winPos && ((_wrPtr - _winPos) & kWindowMask) <= blockStart;
|
||||
|
||||
memset(tempFilter->InitR, 0, sizeof(tempFilter->InitR));
|
||||
tempFilter->InitR[3] = NVm::kGlobalOffset;
|
||||
tempFilter->InitR[4] = tempFilter->BlockSize;
|
||||
tempFilter->InitR[5] = tempFilter->ExecCount;
|
||||
if (firstByte & 0x10)
|
||||
{
|
||||
UInt32 initMask = inp.ReadBits(NVm::kNumGpRegs);
|
||||
for (int i = 0; i < NVm::kNumGpRegs; i++)
|
||||
if (initMask & (1 << i))
|
||||
tempFilter->InitR[i] = NVm::ReadEncodedUInt32(inp);
|
||||
}
|
||||
if (newFilter)
|
||||
{
|
||||
UInt32 vmCodeSize = NVm::ReadEncodedUInt32(inp);
|
||||
if (vmCodeSize >= kVmCodeSizeMax || vmCodeSize == 0)
|
||||
return false;
|
||||
for (UInt32 i = 0; i < vmCodeSize; i++)
|
||||
_vmCode[i] = (Byte)inp.ReadBits(8);
|
||||
_vm.PrepareProgram(_vmCode, vmCodeSize, filter);
|
||||
}
|
||||
|
||||
tempFilter->AllocateEmptyFixedGlobal();
|
||||
|
||||
Byte *globalData = &tempFilter->GlobalData[0];
|
||||
for (i = 0; i < NVm::kNumGpRegs; i++)
|
||||
NVm::SetValue32(&globalData[i * 4], tempFilter->InitR[i]);
|
||||
NVm::SetValue32(&globalData[NVm::NGlobalOffset::kBlockSize], tempFilter->BlockSize);
|
||||
NVm::SetValue32(&globalData[NVm::NGlobalOffset::kBlockPos], 0); // It was commented. why?
|
||||
NVm::SetValue32(&globalData[NVm::NGlobalOffset::kExecCount], tempFilter->ExecCount);
|
||||
|
||||
if (firstByte & 8)
|
||||
{
|
||||
UInt32 dataSize = NVm::ReadEncodedUInt32(inp);
|
||||
if (dataSize > NVm::kGlobalSize - NVm::kFixedGlobalSize)
|
||||
return false;
|
||||
CRecordVector<Byte> &globalData = tempFilter->GlobalData;
|
||||
int requredSize = (int)(dataSize + NVm::kFixedGlobalSize);
|
||||
if (globalData.Size() < requredSize)
|
||||
{
|
||||
globalData.Reserve(requredSize);
|
||||
for (; globalData.Size() < requredSize; i++)
|
||||
globalData.Add(0);
|
||||
}
|
||||
for (UInt32 i = 0; i < dataSize; i++)
|
||||
globalData[NVm::kFixedGlobalSize + i] = (Byte)inp.ReadBits(8);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDecoder::ReadVmCodeLZ()
|
||||
{
|
||||
UInt32 firstByte = m_InBitStream.ReadBits(8);
|
||||
UInt32 length = (firstByte & 7) + 1;
|
||||
if (length == 7)
|
||||
length = m_InBitStream.ReadBits(8) + 7;
|
||||
else if (length == 8)
|
||||
length = m_InBitStream.ReadBits(16);
|
||||
if (length > kVmDataSizeMax)
|
||||
return false;
|
||||
for (UInt32 i = 0; i < length; i++)
|
||||
_vmData[i] = (Byte)m_InBitStream.ReadBits(8);
|
||||
return AddVmCode(firstByte, length);
|
||||
}
|
||||
|
||||
bool CDecoder::ReadVmCodePPM()
|
||||
{
|
||||
int firstByte = DecodePpmSymbol();
|
||||
if (firstByte == -1)
|
||||
return false;
|
||||
UInt32 length = (firstByte & 7) + 1;
|
||||
if (length == 7)
|
||||
{
|
||||
int b1 = DecodePpmSymbol();
|
||||
if (b1 == -1)
|
||||
return false;
|
||||
length = b1 + 7;
|
||||
}
|
||||
else if (length == 8)
|
||||
{
|
||||
int b1 = DecodePpmSymbol();
|
||||
if (b1 == -1)
|
||||
return false;
|
||||
int b2 = DecodePpmSymbol();
|
||||
if (b2 == -1)
|
||||
return false;
|
||||
length = b1 * 256 + b2;
|
||||
}
|
||||
if (length > kVmDataSizeMax)
|
||||
return false;
|
||||
for (UInt32 i = 0; i < length; i++)
|
||||
{
|
||||
int b = DecodePpmSymbol();
|
||||
if (b == -1)
|
||||
return false;
|
||||
_vmData[i] = (Byte)b;
|
||||
}
|
||||
return AddVmCode(firstByte, length);
|
||||
}
|
||||
|
||||
#define RIF(x) { if (!(x)) return S_FALSE; }
|
||||
|
||||
UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); }
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// PPM
|
||||
|
||||
HRESULT CDecoder::InitPPM()
|
||||
{
|
||||
Byte maxOrder = (Byte)ReadBits(7);
|
||||
|
||||
bool reset = ((maxOrder & 0x20) != 0);
|
||||
int maxMB = 0;
|
||||
if (reset)
|
||||
maxMB = (Byte)ReadBits(8);
|
||||
else
|
||||
{
|
||||
if (_ppm.SubAllocator.GetSubAllocatorSize()== 0)
|
||||
return S_FALSE;
|
||||
}
|
||||
if (maxOrder & 0x40)
|
||||
PpmEscChar = (Byte)ReadBits(8);
|
||||
m_InBitStream.InitRangeCoder();
|
||||
/*
|
||||
if (m_InBitStream.m_BitPos != 0)
|
||||
return S_FALSE;
|
||||
*/
|
||||
if (reset)
|
||||
{
|
||||
maxOrder = (maxOrder & 0x1F) + 1;
|
||||
if (maxOrder > 16)
|
||||
maxOrder = 16 + (maxOrder - 16) * 3;
|
||||
if (maxOrder == 1)
|
||||
{
|
||||
// SubAlloc.StopSubAllocator();
|
||||
_ppm.SubAllocator.StopSubAllocator();
|
||||
return S_FALSE;
|
||||
}
|
||||
// SubAlloc.StartSubAllocator(MaxMB+1);
|
||||
// StartModelRare(maxOrder);
|
||||
|
||||
if (!_ppm.SubAllocator.StartSubAllocator((maxMB + 1) << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
_ppm.MaxOrder = 0;
|
||||
_ppm.StartModelRare(maxOrder);
|
||||
|
||||
}
|
||||
// return (minContext != NULL);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
int CDecoder::DecodePpmSymbol() { return _ppm.DecodeSymbol(&m_InBitStream); }
|
||||
|
||||
HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing)
|
||||
{
|
||||
keepDecompressing = false;
|
||||
do
|
||||
{
|
||||
if (((_wrPtr - _winPos) & kWindowMask) < 260 && _wrPtr != _winPos)
|
||||
{
|
||||
RINOK(WriteBuf());
|
||||
if (_writtenFileSize > _unpackSize)
|
||||
return S_OK;
|
||||
}
|
||||
int c = DecodePpmSymbol();
|
||||
if (c == -1)
|
||||
{
|
||||
// Original code sets PPMError=true here and then it returns S_OK. Why ???
|
||||
// return S_OK;
|
||||
return S_FALSE;
|
||||
}
|
||||
if (c == PpmEscChar)
|
||||
{
|
||||
int nextCh = DecodePpmSymbol();
|
||||
if (nextCh == 0)
|
||||
return ReadTables(keepDecompressing);
|
||||
if (nextCh == 2 || nextCh == -1)
|
||||
return S_OK;
|
||||
if (nextCh == 3)
|
||||
{
|
||||
if (!ReadVmCodePPM())
|
||||
return S_FALSE;
|
||||
continue;
|
||||
}
|
||||
if (nextCh == 4 || nextCh == 5)
|
||||
{
|
||||
UInt32 distance = 0;
|
||||
UInt32 length = 4;
|
||||
if (nextCh == 4)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
int c = DecodePpmSymbol();
|
||||
if (c == -1)
|
||||
return S_OK;
|
||||
distance = (distance << 8) + (Byte)c;
|
||||
}
|
||||
distance++;
|
||||
length += 28;
|
||||
}
|
||||
int c = DecodePpmSymbol();
|
||||
if (c == -1)
|
||||
return S_OK;
|
||||
length += c;
|
||||
if (distance >= _lzSize)
|
||||
return S_FALSE;
|
||||
CopyBlock(distance, length);
|
||||
num -= (Int32)length;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
PutByte((Byte)c);
|
||||
num--;
|
||||
}
|
||||
while (num >= 0);
|
||||
keepDecompressing = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// LZ
|
||||
|
||||
HRESULT CDecoder::ReadTables(bool &keepDecompressing)
|
||||
{
|
||||
keepDecompressing = true;
|
||||
ReadBits((8 - m_InBitStream.GetBitPosition()) & 7);
|
||||
if (ReadBits(1) != 0)
|
||||
{
|
||||
_lzMode = false;
|
||||
return InitPPM();
|
||||
}
|
||||
|
||||
_lzMode = true;
|
||||
PrevAlignBits = 0;
|
||||
PrevAlignCount = 0;
|
||||
|
||||
Byte levelLevels[kLevelTableSize];
|
||||
Byte newLevels[kTablesSizesSum];
|
||||
|
||||
if (ReadBits(1) == 0)
|
||||
memset(m_LastLevels, 0, kTablesSizesSum);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < kLevelTableSize; i++)
|
||||
{
|
||||
UInt32 length = ReadBits(4);
|
||||
if (length == 15)
|
||||
{
|
||||
UInt32 zeroCount = ReadBits(4);
|
||||
if (zeroCount != 0)
|
||||
{
|
||||
zeroCount += 2;
|
||||
while (zeroCount-- > 0 && i < kLevelTableSize)
|
||||
levelLevels[i++]=0;
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
levelLevels[i] = (Byte)length;
|
||||
}
|
||||
RIF(m_LevelDecoder.SetCodeLengths(levelLevels));
|
||||
i = 0;
|
||||
while (i < kTablesSizesSum)
|
||||
{
|
||||
UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number < 16)
|
||||
{
|
||||
newLevels[i] = Byte((number + m_LastLevels[i]) & 15);
|
||||
i++;
|
||||
}
|
||||
else if (number > kLevelTableSize)
|
||||
return S_FALSE;
|
||||
else
|
||||
{
|
||||
int num;
|
||||
if (((number - 16) & 1) == 0)
|
||||
num = ReadBits(3) + 3;
|
||||
else
|
||||
num = ReadBits(7) + 11;
|
||||
if (number < 18)
|
||||
{
|
||||
if (i == 0)
|
||||
return S_FALSE;
|
||||
for (; num > 0 && i < kTablesSizesSum; num--, i++)
|
||||
newLevels[i] = newLevels[i - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; num > 0 && i < kTablesSizesSum; num--)
|
||||
newLevels[i++] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
TablesRead = true;
|
||||
|
||||
// original code has check here:
|
||||
/*
|
||||
if (InAddr > ReadTop)
|
||||
{
|
||||
keepDecompressing = false;
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
RIF(m_MainDecoder.SetCodeLengths(&newLevels[0]));
|
||||
RIF(m_DistDecoder.SetCodeLengths(&newLevels[kMainTableSize]));
|
||||
RIF(m_AlignDecoder.SetCodeLengths(&newLevels[kMainTableSize + kDistTableSize]));
|
||||
RIF(m_LenDecoder.SetCodeLengths(&newLevels[kMainTableSize + kDistTableSize + kAlignTableSize]));
|
||||
|
||||
memcpy(m_LastLevels, newLevels, kTablesSizesSum);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
class CCoderReleaser
|
||||
{
|
||||
CDecoder *m_Coder;
|
||||
public:
|
||||
CCoderReleaser(CDecoder *coder): m_Coder(coder) {}
|
||||
~CCoderReleaser()
|
||||
{
|
||||
// m_Coder->m_OutWindowStream.Flush();
|
||||
m_Coder->ReleaseStreams();
|
||||
}
|
||||
};
|
||||
|
||||
HRESULT CDecoder::ReadEndOfBlock(bool &keepDecompressing)
|
||||
{
|
||||
if (ReadBits(1) != 0)
|
||||
{
|
||||
// old file
|
||||
TablesRead = false;
|
||||
return ReadTables(keepDecompressing);
|
||||
}
|
||||
// new file
|
||||
keepDecompressing = false;
|
||||
TablesRead = (ReadBits(1) == 0);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
UInt32 kDistStart[kDistTableSize];
|
||||
|
||||
class CDistInit
|
||||
{
|
||||
public:
|
||||
CDistInit() { Init(); }
|
||||
void Init()
|
||||
{
|
||||
UInt32 start = 0;
|
||||
for (UInt32 i = 0; i < kDistTableSize; i++)
|
||||
{
|
||||
kDistStart[i] = start;
|
||||
start += (1 << kDistDirectBits[i]);
|
||||
}
|
||||
}
|
||||
} g_DistInit;
|
||||
|
||||
HRESULT CDecoder::DecodeLZ(bool &keepDecompressing)
|
||||
{
|
||||
UInt32 rep0 = _reps[0];
|
||||
UInt32 rep1 = _reps[1];
|
||||
UInt32 rep2 = _reps[2];
|
||||
UInt32 rep3 = _reps[3];
|
||||
UInt32 length = _lastLength;
|
||||
for (;;)
|
||||
{
|
||||
if (((_wrPtr - _winPos) & kWindowMask) < 260 && _wrPtr != _winPos)
|
||||
{
|
||||
RINOK(WriteBuf());
|
||||
if (_writtenFileSize > _unpackSize)
|
||||
return S_OK;
|
||||
}
|
||||
UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number < 256)
|
||||
{
|
||||
PutByte(Byte(number));
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (number == kSymbolReadTable)
|
||||
{
|
||||
RINOK(ReadEndOfBlock(keepDecompressing));
|
||||
break;
|
||||
}
|
||||
else if (number == 257)
|
||||
{
|
||||
if (!ReadVmCodeLZ())
|
||||
return S_FALSE;
|
||||
continue;
|
||||
}
|
||||
else if (number == 258)
|
||||
{
|
||||
}
|
||||
else if (number < kSymbolRep + 4)
|
||||
{
|
||||
if (number != kSymbolRep)
|
||||
{
|
||||
UInt32 distance;
|
||||
if (number == kSymbolRep + 1)
|
||||
distance = rep1;
|
||||
else
|
||||
{
|
||||
if (number == kSymbolRep + 2)
|
||||
distance = rep2;
|
||||
else
|
||||
{
|
||||
distance = rep3;
|
||||
rep3 = rep2;
|
||||
}
|
||||
rep2 = rep1;
|
||||
}
|
||||
rep1 = rep0;
|
||||
rep0 = distance;
|
||||
}
|
||||
|
||||
UInt32 number = m_LenDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number >= kLenTableSize)
|
||||
return S_FALSE;
|
||||
length = 2 + kLenStart[number] + m_InBitStream.ReadBits(kLenDirectBits[number]);
|
||||
}
|
||||
else
|
||||
{
|
||||
rep3 = rep2;
|
||||
rep2 = rep1;
|
||||
rep1 = rep0;
|
||||
if (number < 271)
|
||||
{
|
||||
number -= 263;
|
||||
rep0 = kLen2DistStarts[number] + m_InBitStream.ReadBits(kLen2DistDirectBits[number]);
|
||||
length = 2;
|
||||
}
|
||||
else if (number < 299)
|
||||
{
|
||||
number -= 271;
|
||||
length = kNormalMatchMinLen + (UInt32)kLenStart[number] + m_InBitStream.ReadBits(kLenDirectBits[number]);
|
||||
UInt32 number = m_DistDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number >= kDistTableSize)
|
||||
return S_FALSE;
|
||||
rep0 = kDistStart[number];
|
||||
int numBits = kDistDirectBits[number];
|
||||
if (number >= (kNumAlignBits * 2) + 2)
|
||||
{
|
||||
if (numBits > kNumAlignBits)
|
||||
rep0 += (m_InBitStream.ReadBits(numBits - kNumAlignBits) << kNumAlignBits);
|
||||
if (PrevAlignCount > 0)
|
||||
{
|
||||
PrevAlignCount--;
|
||||
rep0 += PrevAlignBits;
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 number = m_AlignDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (number < (1 << kNumAlignBits))
|
||||
{
|
||||
rep0 += number;
|
||||
PrevAlignBits = number;
|
||||
}
|
||||
else if (number == (1 << kNumAlignBits))
|
||||
{
|
||||
PrevAlignCount = kNumAlignReps;
|
||||
rep0 += PrevAlignBits;
|
||||
}
|
||||
else
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
rep0 += m_InBitStream.ReadBits(numBits);
|
||||
length += ((kDistLimit4 - rep0) >> 31) + ((kDistLimit3 - rep0) >> 31);
|
||||
}
|
||||
else
|
||||
return S_FALSE;
|
||||
}
|
||||
if (rep0 >= _lzSize)
|
||||
return S_FALSE;
|
||||
CopyBlock(rep0, length);
|
||||
}
|
||||
_reps[0] = rep0;
|
||||
_reps[1] = rep1;
|
||||
_reps[2] = rep2;
|
||||
_reps[3] = rep3;
|
||||
_lastLength = length;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
|
||||
{
|
||||
_writtenFileSize = 0;
|
||||
if (!m_IsSolid)
|
||||
{
|
||||
_lzSize = 0;
|
||||
_winPos = 0;
|
||||
_wrPtr = 0;
|
||||
for (int i = 0; i < kNumReps; i++)
|
||||
_reps[i] = 0;
|
||||
_lastLength = 0;
|
||||
memset(m_LastLevels, 0, kTablesSizesSum);
|
||||
TablesRead = false;
|
||||
PpmEscChar = 2;
|
||||
InitFilters();
|
||||
}
|
||||
if (!m_IsSolid || !TablesRead)
|
||||
{
|
||||
bool keepDecompressing;
|
||||
RINOK(ReadTables(keepDecompressing));
|
||||
if (!keepDecompressing)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
bool keepDecompressing;
|
||||
if (_lzMode)
|
||||
{
|
||||
RINOK(DecodeLZ(keepDecompressing))
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(DecodePPM(1 << 18, keepDecompressing))
|
||||
}
|
||||
UInt64 packSize = m_InBitStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize));
|
||||
if (!keepDecompressing)
|
||||
break;
|
||||
}
|
||||
RINOK(WriteBuf());
|
||||
if (_writtenFileSize < _unpackSize)
|
||||
return S_FALSE;
|
||||
// return m_OutWindowStream.Flush();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (inSize == NULL || outSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (_vmData == 0)
|
||||
{
|
||||
_vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax);
|
||||
if (_vmData == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
_vmCode = _vmData + kVmDataSizeMax;
|
||||
}
|
||||
|
||||
if (_window == 0)
|
||||
{
|
||||
_window = (Byte *)::MidAlloc(kWindowSize);
|
||||
if (_window == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (!m_InBitStream.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!_vm.Create())
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
||||
m_InBitStream.SetStream(inStream);
|
||||
m_InBitStream.Init();
|
||||
_outStream = outStream;
|
||||
|
||||
CCoderReleaser coderReleaser(this);
|
||||
_unpackSize = *outSize;
|
||||
return CodeReal(progress);
|
||||
}
|
||||
catch(...) { return S_FALSE; }
|
||||
// CNewException is possible here. But probably CNewException is caused
|
||||
// by error in data stream.
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
|
||||
{
|
||||
if (size < 1)
|
||||
return E_INVALIDARG;
|
||||
m_IsSolid = (data[0] != 0);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
294
CPP/7zip/Compress/Rar/Rar3Decoder.h
Executable file
294
CPP/7zip/Compress/Rar/Rar3Decoder.h
Executable file
@@ -0,0 +1,294 @@
|
||||
// Rar3Decoder.h
|
||||
// According to unRAR license,
|
||||
// this code may not be used to develop a
|
||||
// RAR (WinRAR) compatible archiver
|
||||
|
||||
#ifndef __RAR3DECODER_H
|
||||
#define __RAR3DECODER_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/MSBFDecoder.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
|
||||
// #include "../LZ/LZOutWindow.h"
|
||||
#include "../Huffman/HuffmanDecoder.h"
|
||||
#include "../PPMD/PPMDDecode.h"
|
||||
#include "Rar3Vm.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRar3 {
|
||||
|
||||
const UInt32 kWindowSize = 1 << 22;
|
||||
const UInt32 kWindowMask = (kWindowSize - 1);
|
||||
|
||||
const UInt32 kNumReps = 4;
|
||||
const UInt32 kNumLen2Symbols = 8;
|
||||
const UInt32 kLenTableSize = 28;
|
||||
const UInt32 kMainTableSize = 256 + 1 + 1 + 1 + kNumReps + kNumLen2Symbols + kLenTableSize;
|
||||
const UInt32 kDistTableSize = 60;
|
||||
|
||||
const int kNumAlignBits = 4;
|
||||
const UInt32 kAlignTableSize = (1 << kNumAlignBits) + 1;
|
||||
|
||||
const UInt32 kLevelTableSize = 20;
|
||||
|
||||
const UInt32 kTablesSizesSum = kMainTableSize + kDistTableSize + kAlignTableSize + kLenTableSize;
|
||||
|
||||
template<class TInByte>
|
||||
class CBitDecoder2
|
||||
{
|
||||
UInt32 m_Value;
|
||||
public:
|
||||
UInt32 m_BitPos;
|
||||
TInByte m_Stream;
|
||||
bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
|
||||
void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);}
|
||||
void ReleaseStream() { m_Stream.ReleaseStream();}
|
||||
|
||||
void Init()
|
||||
{
|
||||
m_Stream.Init();
|
||||
m_BitPos = 0;
|
||||
m_Value = 0;
|
||||
// m_BitPos = kNumBigValueBits;
|
||||
// Normalize();
|
||||
}
|
||||
|
||||
UInt64 GetProcessedSize() const
|
||||
{ return m_Stream.GetProcessedSize() - (m_BitPos) / 8; }
|
||||
UInt32 GetBitPosition() const { return ((8 - m_BitPos) & 7); }
|
||||
|
||||
/*
|
||||
void Normalize()
|
||||
{
|
||||
for (;m_BitPos >= 8; m_BitPos -= 8)
|
||||
m_Value = (m_Value << 8) | m_Stream.ReadByte();
|
||||
}
|
||||
*/
|
||||
|
||||
UInt32 GetValue(UInt32 numBits)
|
||||
{
|
||||
// return (m_Value << m_BitPos) >> (kNumBigValueBits - numBits);
|
||||
// return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - numBits);
|
||||
if (m_BitPos < numBits)
|
||||
{
|
||||
m_BitPos += 8;
|
||||
m_Value = (m_Value << 8) | m_Stream.ReadByte();
|
||||
if (m_BitPos < numBits)
|
||||
{
|
||||
m_BitPos += 8;
|
||||
m_Value = (m_Value << 8) | m_Stream.ReadByte();
|
||||
}
|
||||
}
|
||||
return m_Value >> (m_BitPos - numBits);
|
||||
}
|
||||
|
||||
void MovePos(UInt32 numBits)
|
||||
{
|
||||
m_BitPos -= numBits;
|
||||
m_Value = m_Value & ((1 << m_BitPos) - 1);
|
||||
}
|
||||
|
||||
UInt32 ReadBits(UInt32 numBits)
|
||||
{
|
||||
UInt32 res = GetValue(numBits);
|
||||
MovePos(numBits);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
typedef CBitDecoder2<CInBuffer> CBitDecoder;
|
||||
|
||||
const int kNumTopBits = 24;
|
||||
const UInt32 kTopValue = (1 << kNumTopBits);
|
||||
const UInt32 kBot = (1 << 15);
|
||||
|
||||
class CRangeDecoder:public NPPMD::CRangeDecoderVirt, public CBitDecoder
|
||||
{
|
||||
public:
|
||||
UInt32 Range;
|
||||
UInt32 Low;
|
||||
UInt32 Code;
|
||||
|
||||
void Normalize()
|
||||
{
|
||||
while ((Low ^ (Low + Range)) < kTopValue ||
|
||||
Range < kBot && ((Range = (0 - Low) & (kBot - 1)), 1))
|
||||
{
|
||||
Code = (Code << 8) | m_Stream.ReadByte();
|
||||
Range <<= 8;
|
||||
Low <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
void InitRangeCoder()
|
||||
{
|
||||
Code = 0;
|
||||
Low = 0;
|
||||
Range = 0xFFFFFFFF;
|
||||
for(int i = 0; i < 4; i++)
|
||||
Code = (Code << 8) | ReadBits(8);
|
||||
}
|
||||
|
||||
virtual UInt32 GetThreshold(UInt32 total)
|
||||
{
|
||||
return (Code - Low) / ( Range /= total);
|
||||
}
|
||||
|
||||
virtual void Decode(UInt32 start, UInt32 size)
|
||||
{
|
||||
Low += start * Range;
|
||||
Range *= size;
|
||||
Normalize();
|
||||
}
|
||||
|
||||
virtual UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
|
||||
{
|
||||
if (((Code - Low) / (Range >>= numTotalBits)) < size0)
|
||||
{
|
||||
Decode(0, size0);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Decode(size0, (1 << numTotalBits) - size0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// UInt64 GetProcessedSizeRangeCoder() {return Stream.GetProcessedSize(); }
|
||||
};
|
||||
|
||||
|
||||
struct CFilter: public NVm::CProgram
|
||||
{
|
||||
CRecordVector<Byte> GlobalData;
|
||||
UInt32 BlockStart;
|
||||
UInt32 BlockSize;
|
||||
UInt32 ExecCount;
|
||||
CFilter(): BlockStart(0), BlockSize(0), ExecCount(0) {}
|
||||
};
|
||||
|
||||
struct CTempFilter: public NVm::CProgramInitState
|
||||
{
|
||||
UInt32 BlockStart;
|
||||
UInt32 BlockSize;
|
||||
UInt32 ExecCount;
|
||||
bool NextWindow;
|
||||
|
||||
UInt32 FilterIndex;
|
||||
};
|
||||
|
||||
const int kNumHuffmanBits = 15;
|
||||
|
||||
class CDecoder:
|
||||
public ICompressCoder,
|
||||
public ICompressSetDecoderProperties2,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CRangeDecoder m_InBitStream;
|
||||
Byte *_window;
|
||||
UInt32 _winPos;
|
||||
UInt32 _wrPtr;
|
||||
UInt64 _lzSize;
|
||||
UInt64 _unpackSize;
|
||||
UInt64 _writtenFileSize; // if it's > _unpackSize, then _unpackSize only written
|
||||
CMyComPtr<ISequentialOutStream> _outStream;
|
||||
NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder;
|
||||
NHuffman::CDecoder<kNumHuffmanBits, kDistTableSize> m_DistDecoder;
|
||||
NHuffman::CDecoder<kNumHuffmanBits, kAlignTableSize> m_AlignDecoder;
|
||||
NHuffman::CDecoder<kNumHuffmanBits, kLenTableSize> m_LenDecoder;
|
||||
NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
|
||||
|
||||
UInt32 _reps[kNumReps];
|
||||
UInt32 _lastLength;
|
||||
|
||||
Byte m_LastLevels[kTablesSizesSum];
|
||||
|
||||
Byte *_vmData;
|
||||
Byte *_vmCode;
|
||||
NVm::CVm _vm;
|
||||
CRecordVector<CFilter *> _filters;
|
||||
CRecordVector<CTempFilter *> _tempFilters;
|
||||
UInt32 _lastFilter;
|
||||
|
||||
bool m_IsSolid;
|
||||
|
||||
bool _lzMode;
|
||||
|
||||
UInt32 PrevAlignBits;
|
||||
UInt32 PrevAlignCount;
|
||||
|
||||
bool TablesRead;
|
||||
|
||||
NPPMD::CDecodeInfo _ppm;
|
||||
int PpmEscChar;
|
||||
|
||||
HRESULT WriteDataToStream(const Byte *data, UInt32 size);
|
||||
HRESULT WriteData(const Byte *data, UInt32 size);
|
||||
HRESULT WriteArea(UInt32 startPtr, UInt32 endPtr);
|
||||
void ExecuteFilter(int tempFilterIndex, NVm::CBlockRef &outBlockRef);
|
||||
HRESULT WriteBuf();
|
||||
|
||||
void InitFilters();
|
||||
bool AddVmCode(UInt32 firstByte, UInt32 codeSize);
|
||||
bool ReadVmCodeLZ();
|
||||
bool ReadVmCodePPM();
|
||||
|
||||
UInt32 ReadBits(int numBits);
|
||||
|
||||
HRESULT InitPPM();
|
||||
int DecodePpmSymbol();
|
||||
HRESULT DecodePPM(Int32 num, bool &keepDecompressing);
|
||||
|
||||
HRESULT ReadTables(bool &keepDecompressing);
|
||||
HRESULT ReadEndOfBlock(bool &keepDecompressing);
|
||||
HRESULT DecodeLZ(bool &keepDecompressing);
|
||||
HRESULT CodeReal(ICompressProgressInfo *progress);
|
||||
public:
|
||||
CDecoder();
|
||||
~CDecoder();
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
|
||||
|
||||
void ReleaseStreams()
|
||||
{
|
||||
_outStream.Release();
|
||||
m_InBitStream.ReleaseStream();
|
||||
}
|
||||
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
|
||||
|
||||
void CopyBlock(UInt32 distance, UInt32 len)
|
||||
{
|
||||
_lzSize += len;
|
||||
UInt32 pos = (_winPos - distance - 1) & kWindowMask;
|
||||
do
|
||||
{
|
||||
_window[_winPos] = _window[pos];
|
||||
_winPos = (_winPos + 1) & kWindowMask;
|
||||
pos = (pos + 1) & kWindowMask;
|
||||
}
|
||||
while(--len != 0);
|
||||
}
|
||||
|
||||
void PutByte(Byte b)
|
||||
{
|
||||
_window[_winPos] = b;
|
||||
_winPos = (_winPos + 1) & kWindowMask;
|
||||
_lzSize++;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
1089
CPP/7zip/Compress/Rar/Rar3Vm.cpp
Executable file
1089
CPP/7zip/Compress/Rar/Rar3Vm.cpp
Executable file
File diff suppressed because it is too large
Load Diff
219
CPP/7zip/Compress/Rar/Rar3Vm.h
Executable file
219
CPP/7zip/Compress/Rar/Rar3Vm.h
Executable file
@@ -0,0 +1,219 @@
|
||||
// Rar3Vm.h
|
||||
// According to unRAR license,
|
||||
// this code may not be used to develop a
|
||||
// RAR (WinRAR) compatible archiver
|
||||
|
||||
#ifndef __RAR3VM_H
|
||||
#define __RAR3VM_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Common/Vector.h"
|
||||
|
||||
#define RARVM_STANDARD_FILTERS
|
||||
#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__) // || defined(_M_IA64) || defined(__ia64__)
|
||||
// Define RARVM_LITTLE_ENDIAN_UNALIGN, if CPU is LITTLE_ENDIAN and if it supports
|
||||
// unaligned 32-bit memory accesses.
|
||||
// It's for speed optimization, if you are not sure, just don't define it.
|
||||
#define RARVM_LITTLE_ENDIAN_UNALIGN
|
||||
#endif
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRar3 {
|
||||
|
||||
class CMemBitDecoder
|
||||
{
|
||||
const Byte *_data;
|
||||
UInt32 _bitSize;
|
||||
UInt32 _bitPos;
|
||||
public:
|
||||
void Init(const Byte *data, UInt32 byteSize)
|
||||
{
|
||||
_data = data;
|
||||
_bitSize = (byteSize << 3);
|
||||
_bitPos = 0;
|
||||
}
|
||||
UInt32 ReadBits(int numBits);
|
||||
UInt32 ReadBit();
|
||||
bool Avail() const { return (_bitPos < _bitSize); }
|
||||
};
|
||||
|
||||
namespace NVm {
|
||||
|
||||
inline UInt32 GetValue32(const void *addr)
|
||||
{
|
||||
#ifdef RARVM_LITTLE_ENDIAN_UNALIGN
|
||||
return *(const UInt32 *)addr;
|
||||
#else
|
||||
const Byte *b = (const Byte *)addr;
|
||||
return UInt32((UInt32)b[0]|((UInt32)b[1]<<8)|((UInt32)b[2]<<16)|((UInt32)b[3]<<24));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void SetValue32(void *addr, UInt32 value)
|
||||
{
|
||||
#ifdef RARVM_LITTLE_ENDIAN_UNALIGN
|
||||
*(UInt32 *)addr = value;
|
||||
#else
|
||||
((Byte *)addr)[0] = (Byte)value;
|
||||
((Byte *)addr)[1] = (Byte)(value >> 8);
|
||||
((Byte *)addr)[2] = (Byte)(value >> 16);
|
||||
((Byte *)addr)[3] = (Byte)(value >> 24);
|
||||
#endif
|
||||
}
|
||||
|
||||
UInt32 ReadEncodedUInt32(CMemBitDecoder &inp);
|
||||
|
||||
const int kNumRegBits = 3;
|
||||
const UInt32 kNumRegs = 1 << kNumRegBits;
|
||||
const UInt32 kNumGpRegs = kNumRegs - 1;
|
||||
|
||||
const UInt32 kSpaceSize = 0x40000;
|
||||
const UInt32 kSpaceMask = kSpaceSize -1;
|
||||
const UInt32 kGlobalOffset = 0x3C000;
|
||||
const UInt32 kGlobalSize = 0x2000;
|
||||
const UInt32 kFixedGlobalSize = 64;
|
||||
|
||||
namespace NGlobalOffset
|
||||
{
|
||||
const UInt32 kBlockSize = 0x1C;
|
||||
const UInt32 kBlockPos = 0x20;
|
||||
const UInt32 kExecCount = 0x2C;
|
||||
const UInt32 kGlobalMemOutSize = 0x30;
|
||||
};
|
||||
|
||||
enum ECommand
|
||||
{
|
||||
CMD_MOV, CMD_CMP, CMD_ADD, CMD_SUB, CMD_JZ, CMD_JNZ, CMD_INC, CMD_DEC,
|
||||
CMD_JMP, CMD_XOR, CMD_AND, CMD_OR, CMD_TEST, CMD_JS, CMD_JNS, CMD_JB,
|
||||
CMD_JBE, CMD_JA, CMD_JAE, CMD_PUSH, CMD_POP, CMD_CALL, CMD_RET, CMD_NOT,
|
||||
CMD_SHL, CMD_SHR, CMD_SAR, CMD_NEG, CMD_PUSHA,CMD_POPA, CMD_PUSHF,CMD_POPF,
|
||||
CMD_MOVZX,CMD_MOVSX,CMD_XCHG, CMD_MUL, CMD_DIV, CMD_ADC, CMD_SBB, CMD_PRINT,
|
||||
|
||||
CMD_MOVB, CMD_CMPB, CMD_ADDB, CMD_SUBB, CMD_INCB, CMD_DECB,
|
||||
CMD_XORB, CMD_ANDB, CMD_ORB, CMD_TESTB,CMD_NEGB,
|
||||
CMD_SHLB, CMD_SHRB, CMD_SARB, CMD_MULB
|
||||
};
|
||||
|
||||
enum EOpType {OP_TYPE_REG, OP_TYPE_INT, OP_TYPE_REGMEM, OP_TYPE_NONE};
|
||||
|
||||
// Addr in COperand object can link (point) to CVm object!!!
|
||||
|
||||
struct COperand
|
||||
{
|
||||
EOpType Type;
|
||||
UInt32 Data;
|
||||
UInt32 Base;
|
||||
COperand(): Type(OP_TYPE_NONE), Data(0), Base(0) {}
|
||||
};
|
||||
|
||||
struct CCommand
|
||||
{
|
||||
ECommand OpCode;
|
||||
bool ByteMode;
|
||||
COperand Op1, Op2;
|
||||
};
|
||||
|
||||
struct CBlockRef
|
||||
{
|
||||
UInt32 Offset;
|
||||
UInt32 Size;
|
||||
};
|
||||
|
||||
struct CProgram
|
||||
{
|
||||
CRecordVector<CCommand> Commands;
|
||||
#ifdef RARVM_STANDARD_FILTERS
|
||||
int StandardFilterIndex;
|
||||
#endif
|
||||
CRecordVector<Byte> StaticData;
|
||||
};
|
||||
|
||||
struct CProgramInitState
|
||||
{
|
||||
UInt32 InitR[kNumGpRegs];
|
||||
CRecordVector<Byte> GlobalData;
|
||||
|
||||
void AllocateEmptyFixedGlobal()
|
||||
{
|
||||
GlobalData.Clear();
|
||||
GlobalData.Reserve(NVm::kFixedGlobalSize);
|
||||
for (UInt32 i = 0; i < NVm::kFixedGlobalSize; i++)
|
||||
GlobalData.Add(0);
|
||||
}
|
||||
};
|
||||
|
||||
class CVm
|
||||
{
|
||||
static UInt32 GetValue(bool byteMode, const void *addr)
|
||||
{
|
||||
if (byteMode)
|
||||
return(*(const Byte *)addr);
|
||||
else
|
||||
{
|
||||
#ifdef RARVM_LITTLE_ENDIAN_UNALIGN
|
||||
return *(const UInt32 *)addr;
|
||||
#else
|
||||
const Byte *b = (const Byte *)addr;
|
||||
return UInt32((UInt32)b[0]|((UInt32)b[1]<<8)|((UInt32)b[2]<<16)|((UInt32)b[3]<<24));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void SetValue(bool byteMode, void *addr, UInt32 value)
|
||||
{
|
||||
if (byteMode)
|
||||
*(Byte *)addr = (Byte)value;
|
||||
else
|
||||
{
|
||||
#ifdef RARVM_LITTLE_ENDIAN_UNALIGN
|
||||
*(UInt32 *)addr = value;
|
||||
#else
|
||||
((Byte *)addr)[0] = (Byte)value;
|
||||
((Byte *)addr)[1] = (Byte)(value >> 8);
|
||||
((Byte *)addr)[2] = (Byte)(value >> 16);
|
||||
((Byte *)addr)[3] = (Byte)(value >> 24);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 GetFixedGlobalValue32(UInt32 globalOffset) { return GetValue(false, &Mem[kGlobalOffset + globalOffset]); }
|
||||
|
||||
void SetBlockSize(UInt32 v) { SetValue(&Mem[kGlobalOffset + NGlobalOffset::kBlockSize], v); }
|
||||
void SetBlockPos(UInt32 v) { SetValue(&Mem[kGlobalOffset + NGlobalOffset::kBlockPos], v); }
|
||||
public:
|
||||
static void SetValue(void *addr, UInt32 value) { SetValue(false, addr, value); }
|
||||
private:
|
||||
UInt32 GetOperand32(const COperand *op) const;
|
||||
void SetOperand32(const COperand *op, UInt32 val);
|
||||
Byte GetOperand8(const COperand *op) const;
|
||||
void SetOperand8(const COperand *op, Byte val);
|
||||
UInt32 GetOperand(bool byteMode, const COperand *op) const;
|
||||
void SetOperand(bool byteMode, const COperand *op, UInt32 val);
|
||||
|
||||
void DecodeArg(CMemBitDecoder &inp, COperand &op, bool byteMode);
|
||||
|
||||
bool ExecuteCode(const CProgram *prg);
|
||||
|
||||
#ifdef RARVM_STANDARD_FILTERS
|
||||
void ExecuteStandardFilter(int filterIndex);
|
||||
#endif
|
||||
|
||||
Byte *Mem;
|
||||
UInt32 R[kNumRegs + 1]; // R[kNumRegs] = 0 always (speed optimization)
|
||||
UInt32 Flags;
|
||||
void ReadVmProgram(const Byte *code, UInt32 codeSize, CProgram *prg);
|
||||
public:
|
||||
CVm();
|
||||
~CVm();
|
||||
bool Create();
|
||||
void PrepareProgram(const Byte *code, UInt32 codeSize, CProgram *prg);
|
||||
void SetMemory(UInt32 pos, const Byte *data, UInt32 dataSize);
|
||||
bool Execute(CProgram *prg, const CProgramInitState *initState,
|
||||
CBlockRef &outBlockRef, CRecordVector<Byte> &outGlobalData);
|
||||
const Byte *GetDataPointer(UInt32 offset) const { return Mem + offset; }
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
}}}
|
||||
3
CPP/7zip/Compress/Rar/StdAfx.cpp
Executable file
3
CPP/7zip/Compress/Rar/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
8
CPP/7zip/Compress/Rar/StdAfx.h
Executable file
8
CPP/7zip/Compress/Rar/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
49
CPP/7zip/Compress/Rar/makefile
Executable file
49
CPP/7zip/Compress/Rar/makefile
Executable file
@@ -0,0 +1,49 @@
|
||||
PROG = Rar29.dll
|
||||
DEF_FILE = ../Codec.def
|
||||
CFLAGS = $(CFLAGS) -I ../../../
|
||||
LIBS = $(LIBS) oleaut32.lib
|
||||
|
||||
RAR29_OBJS = \
|
||||
$O\DllExports.obj \
|
||||
|
||||
RAR29_OPT_OBJS = \
|
||||
$O\Rar1Decoder.obj \
|
||||
$O\Rar2Decoder.obj \
|
||||
$O\Rar3Decoder.obj \
|
||||
$O\Rar3Vm.obj \
|
||||
|
||||
COMMON_OBJS = \
|
||||
$O\Alloc.obj \
|
||||
$O\CRC.obj \
|
||||
$O\Vector.obj \
|
||||
|
||||
7ZIP_COMMON_OBJS = \
|
||||
$O\InBuffer.obj \
|
||||
$O\OutBuffer.obj \
|
||||
$O\StreamUtils.obj \
|
||||
|
||||
LZ_OBJS = \
|
||||
$O\LZOutWindow.obj \
|
||||
|
||||
|
||||
OBJS = \
|
||||
$O\StdAfx.obj \
|
||||
$(RAR29_OBJS) \
|
||||
$(RAR29_OPT_OBJS) \
|
||||
$(COMMON_OBJS) \
|
||||
$(7ZIP_COMMON_OBJS) \
|
||||
$(LZ_OBJS) \
|
||||
$O\resource.res
|
||||
|
||||
!include "../../../Build.mak"
|
||||
|
||||
$(RAR29_OBJS): $(*B).cpp
|
||||
$(COMPL)
|
||||
$(RAR29_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)
|
||||
3
CPP/7zip/Compress/Rar/resource.rc
Executable file
3
CPP/7zip/Compress/Rar/resource.rc
Executable file
@@ -0,0 +1,3 @@
|
||||
#include "../../MyVersionInfo.rc"
|
||||
|
||||
MY_VERSION_INFO_DLL("Rar29 Codec", "Rar29")
|
||||
Reference in New Issue
Block a user