mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-17 04:11:51 -06:00
4.27 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
31e7b924e8
commit
d66cf2fcf3
66
7zip/Compress/Rar20/DllExports.cpp
Executable file
66
7zip/Compress/Rar20/DllExports.cpp
Executable file
@@ -0,0 +1,66 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
#include "Rar20Decoder.h"
|
||||
|
||||
// {23170F69-40C1-278B-0403-020000000000}
|
||||
DEFINE_GUID(CLSID_CCompressRar20Decoder,
|
||||
0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x02, 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_CCompressRar20Decoder)
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
if (*iid != IID_ICompressCoder)
|
||||
return E_NOINTERFACE;
|
||||
CMyComPtr<ICompressCoder> coder = (ICompressCoder *)new
|
||||
NCompress::NRar20::CDecoder;
|
||||
*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, 0x03, 0x02 };
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
case NMethodPropID::kName:
|
||||
if ((value->bstrVal = ::SysAllocString(L"Rar20")) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
case NMethodPropID::kDecoder:
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)&CLSID_CCompressRar20Decoder, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
65
7zip/Compress/Rar20/Rar20Const.h
Executable file
65
7zip/Compress/Rar20/Rar20Const.h
Executable file
@@ -0,0 +1,65 @@
|
||||
// Rar20CoderConst.h
|
||||
// According to unRAR license,
|
||||
// this code may not be used to develop a
|
||||
// RAR (WinRAR) compatible archiver
|
||||
|
||||
#ifndef __RAR20_CONST_H
|
||||
#define __RAR20_CONST_H
|
||||
|
||||
#include "Rar20ExtConst.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRar20 {
|
||||
|
||||
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;
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
319
7zip/Compress/Rar20/Rar20Decoder.cpp
Executable file
319
7zip/Compress/Rar20/Rar20Decoder.cpp
Executable file
@@ -0,0 +1,319 @@
|
||||
// Rar20Decoder.cpp
|
||||
// According to unRAR license,
|
||||
// this code may not be used to develop a
|
||||
// RAR (WinRAR) compatible archiver
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Rar20Decoder.h"
|
||||
#include "Rar20Const.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRar20 {
|
||||
|
||||
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_Predictor.Init();
|
||||
for(int i = 0; i < kNumRepDists; i++)
|
||||
m_RepDists[i] = 0;
|
||||
m_RepDistPtr = 0;
|
||||
m_LastLength = 0;
|
||||
memset(m_LastLevels, 0, kMaxTableSize);
|
||||
}
|
||||
|
||||
#define RIF(x) { if (!(x)) return false; }
|
||||
|
||||
bool CDecoder::ReadTables(void)
|
||||
{
|
||||
Byte levelLevels[kLevelTableSize];
|
||||
Byte newLevels[kMaxTableSize];
|
||||
m_AudioMode = (m_InBitStream.ReadBits(1) == 1);
|
||||
|
||||
if (m_InBitStream.ReadBits(1) == 0)
|
||||
memset(m_LastLevels, 0, kMaxTableSize);
|
||||
int numLevels;
|
||||
if (m_AudioMode)
|
||||
{
|
||||
m_NumChannels = m_InBitStream.ReadBits(2) + 1;
|
||||
if (m_Predictor.CurrentChannel >= m_NumChannels)
|
||||
m_Predictor.CurrentChannel = 0;
|
||||
numLevels = m_NumChannels * kMMTableSize;
|
||||
}
|
||||
else
|
||||
numLevels = kHeapTablesSizesSum;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < kLevelTableSize; i++)
|
||||
levelLevels[i] = Byte(m_InBitStream.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 = m_InBitStream.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 = m_InBitStream.ReadBits(3) + 3;
|
||||
else if (number == kTableLevel0Number2)
|
||||
num = m_InBitStream.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_Predictor.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();
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
while(pos < unPackSize)
|
||||
{
|
||||
if (m_AudioMode)
|
||||
while(pos < unPackSize)
|
||||
{
|
||||
UInt32 symbol = m_MMDecoders[m_Predictor.CurrentChannel].DecodeSymbol(&m_InBitStream);
|
||||
if (symbol == 256)
|
||||
{
|
||||
if (progress != 0)
|
||||
{
|
||||
UInt64 packSize = m_InBitStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &pos));
|
||||
}
|
||||
if (!ReadTables())
|
||||
return S_FALSE;
|
||||
break;
|
||||
}
|
||||
if (symbol >= kMMTableSize)
|
||||
return S_FALSE;
|
||||
Byte byPredict = m_Predictor.Predict();
|
||||
Byte byReal = byPredict - Byte(symbol);
|
||||
m_Predictor.Update(byReal, byPredict);
|
||||
m_OutWindowStream.PutByte(byReal);
|
||||
if (++m_Predictor.CurrentChannel == m_NumChannels)
|
||||
m_Predictor.CurrentChannel = 0;
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
while(pos < unPackSize)
|
||||
{
|
||||
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 S_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 S_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)
|
||||
{
|
||||
if (progress != 0)
|
||||
{
|
||||
UInt64 packSize = m_InBitStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&packSize, &pos));
|
||||
}
|
||||
if (!ReadTables())
|
||||
return S_FALSE;
|
||||
break;
|
||||
}
|
||||
else
|
||||
return S_FALSE;
|
||||
CopyBackBlockOp(distance, length);
|
||||
pos += length;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
}}
|
||||
95
7zip/Compress/Rar20/Rar20Decoder.h
Executable file
95
7zip/Compress/Rar20/Rar20Decoder.h
Executable file
@@ -0,0 +1,95 @@
|
||||
// Rar20Decoder.h
|
||||
// According to unRAR license,
|
||||
// this code may not be used to develop a
|
||||
// RAR (WinRAR) compatible archiver
|
||||
|
||||
#ifndef __RAR20_DECODER_H
|
||||
#define __RAR20_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"
|
||||
|
||||
#include "Rar20Multimedia.h"
|
||||
#include "Rar20Const.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRar20 {
|
||||
|
||||
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::CPredictor m_Predictor;
|
||||
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();
|
||||
bool ReadTables();
|
||||
bool ReadLastTables();
|
||||
void CopyBackBlockOp(UInt32 aDistance, UInt32 aLength)
|
||||
{
|
||||
/*
|
||||
if(m_Position <= aDistance)
|
||||
throw CDecoderException(CDecoderException::kData);
|
||||
*/
|
||||
m_RepDists[m_RepDistPtr++ & 3] = aDistance;
|
||||
m_LastLength = aLength;
|
||||
m_OutWindowStream.CopyBlock(aDistance, aLength);
|
||||
}
|
||||
|
||||
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
|
||||
21
7zip/Compress/Rar20/Rar20ExtConst.h
Executable file
21
7zip/Compress/Rar20/Rar20ExtConst.h
Executable file
@@ -0,0 +1,21 @@
|
||||
// Rar20ExtConst.h
|
||||
// According to unRAR license,
|
||||
// this code may not be used to develop a
|
||||
// RAR (WinRAR) compatible archiver
|
||||
|
||||
#ifndef __RAR20_EXTCONST_H
|
||||
#define __RAR20_EXTCONST_H
|
||||
|
||||
#include "../../../Common/Types.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRar20 {
|
||||
|
||||
const UInt32 kNumRepDists = 4;
|
||||
const UInt32 kDistTableSize = 48;
|
||||
|
||||
const int kMMTableSize = 256 + 1;
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
128
7zip/Compress/Rar20/Rar20Multimedia.cpp
Executable file
128
7zip/Compress/Rar20/Rar20Multimedia.cpp
Executable file
@@ -0,0 +1,128 @@
|
||||
// Rar20Multimedia.cpp
|
||||
// According to unRAR license,
|
||||
// this code may not be used to develop a
|
||||
// RAR (WinRAR) compatible archiver
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Rar20Multimedia.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRar20 {
|
||||
namespace NMultimedia {
|
||||
|
||||
void CAudioVariables::Init()
|
||||
{
|
||||
memset(this, 0, sizeof(CAudioVariables));
|
||||
}
|
||||
|
||||
void CPredictor::Init()
|
||||
{
|
||||
for(int i = 0; i < kNumChanelsMax; i++)
|
||||
m_AudioVariablesArray[i].Init();
|
||||
m_ChannelDelta = 0;
|
||||
CurrentChannel = 0;
|
||||
}
|
||||
|
||||
Byte CPredictor::Predict()
|
||||
{
|
||||
CAudioVariables *v = &m_AudioVariablesArray[CurrentChannel];
|
||||
v->ByteCount++;
|
||||
v->D4 = v->D3;
|
||||
v->D3 = v->D2;
|
||||
v->D2 = v->LastDelta-v->D1;
|
||||
v->D1 = v->LastDelta;
|
||||
int pCh = 8 * v->LastChar +
|
||||
v->K1 * v->D1 +
|
||||
v->K2 * v->D2 +
|
||||
v->K3 * v->D3 +
|
||||
v->K4 * v->D4 +
|
||||
v->K5*m_ChannelDelta;
|
||||
pCh = (pCh >> 3) & 0xFF;
|
||||
return Byte(pCh);
|
||||
}
|
||||
|
||||
void CPredictor::Update(Byte realValue, int predictedValue)
|
||||
{
|
||||
struct CAudioVariables *v = &m_AudioVariablesArray[CurrentChannel];
|
||||
|
||||
int delta = predictedValue - realValue;
|
||||
int i = ((signed char)delta) << 3;
|
||||
|
||||
v->Dif[0] += abs(i);
|
||||
v->Dif[1] += abs(i - v->D1);
|
||||
v->Dif[2] += abs(i + v->D1);
|
||||
v->Dif[3] += abs(i - v->D2);
|
||||
v->Dif[4] += abs(i + v->D2);
|
||||
v->Dif[5] += abs(i - v->D3);
|
||||
v->Dif[6] += abs(i + v->D3);
|
||||
v->Dif[7] += abs(i - v->D4);
|
||||
v->Dif[8] += abs(i + v->D4);
|
||||
v->Dif[9] += abs(i - m_ChannelDelta);
|
||||
v->Dif[10] += abs(i + m_ChannelDelta);
|
||||
|
||||
m_ChannelDelta = v->LastDelta = (signed char)(realValue - v->LastChar);
|
||||
v->LastChar = realValue;
|
||||
|
||||
UInt32 numMinDif, minDif;
|
||||
if ((v->ByteCount & 0x1F)==0)
|
||||
{
|
||||
minDif = v->Dif[0];
|
||||
numMinDif = 0;
|
||||
v->Dif[0] = 0;
|
||||
for (i = 1; i < sizeof(v->Dif) / sizeof(v->Dif[0]); i++)
|
||||
{
|
||||
if (v->Dif[i] < minDif)
|
||||
{
|
||||
minDif = v->Dif[i];
|
||||
numMinDif = i;
|
||||
}
|
||||
v->Dif[i] = 0;
|
||||
}
|
||||
switch(numMinDif)
|
||||
{
|
||||
case 1:
|
||||
if (v->K1 >= -16)
|
||||
v->K1--;
|
||||
break;
|
||||
case 2:
|
||||
if (v->K1 < 16)
|
||||
v->K1++;
|
||||
break;
|
||||
case 3:
|
||||
if (v->K2 >= -16)
|
||||
v->K2--;
|
||||
break;
|
||||
case 4:
|
||||
if (v->K2 < 16)
|
||||
v->K2++;
|
||||
break;
|
||||
case 5:
|
||||
if (v->K3 >= -16)
|
||||
v->K3--;
|
||||
break;
|
||||
case 6:
|
||||
if (v->K3 < 16)
|
||||
v->K3++;
|
||||
break;
|
||||
case 7:
|
||||
if (v->K4 >= -16)
|
||||
v->K4--;
|
||||
break;
|
||||
case 8:
|
||||
if (v->K4 < 16)
|
||||
v->K4++;
|
||||
break;
|
||||
case 9:
|
||||
if (v->K5 >= -16)
|
||||
v->K5--;
|
||||
break;
|
||||
case 10:
|
||||
if (v->K5 < 16)
|
||||
v->K5++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}}}
|
||||
43
7zip/Compress/Rar20/Rar20Multimedia.h
Executable file
43
7zip/Compress/Rar20/Rar20Multimedia.h
Executable file
@@ -0,0 +1,43 @@
|
||||
// Rar20Multimedia.h
|
||||
// According to unRAR license,
|
||||
// this code may not be used to develop a
|
||||
// RAR (WinRAR) compatible archiver
|
||||
|
||||
#ifndef __RAR20_MULTIMEDIA_H
|
||||
#define __RAR20_MULTIMEDIA_H
|
||||
|
||||
#include "../../../Common/Types.h"
|
||||
|
||||
namespace NCompress {
|
||||
namespace NRar20 {
|
||||
namespace NMultimedia {
|
||||
|
||||
struct CAudioVariables
|
||||
{
|
||||
int K1,K2,K3,K4,K5;
|
||||
int D1,D2,D3,D4;
|
||||
int LastDelta;
|
||||
UInt32 Dif[11];
|
||||
UInt32 ByteCount;
|
||||
int LastChar;
|
||||
|
||||
void Init();
|
||||
};
|
||||
|
||||
const int kNumChanelsMax = 4;
|
||||
|
||||
class CPredictor
|
||||
{
|
||||
CAudioVariables m_AudioVariablesArray[kNumChanelsMax];
|
||||
int m_ChannelDelta;
|
||||
public:
|
||||
int CurrentChannel;
|
||||
|
||||
void Init();
|
||||
Byte Predict();
|
||||
void Update(Byte realValue, int predictedValue);
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
3
7zip/Compress/Rar20/StdAfx.cpp
Executable file
3
7zip/Compress/Rar20/StdAfx.cpp
Executable file
@@ -0,0 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
8
7zip/Compress/Rar20/StdAfx.h
Executable file
8
7zip/Compress/Rar20/StdAfx.h
Executable file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user