mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-22 23:15:20 +00:00
rar5: wip
This commit is contained in:
@@ -11,6 +11,13 @@ namespace SharpCompress.Compressors.Rar.UnpackV2017
|
||||
private Stream readStream;
|
||||
private Stream writeStream;
|
||||
|
||||
private void _UnpackCtor() {
|
||||
BlockTables.Init();
|
||||
for (int i = 0; i < this.AudV.Length; i++) {
|
||||
this.AudV[i] = new AudioVariables();
|
||||
}
|
||||
}
|
||||
|
||||
public void DoUnpack(FileHeader fileHeader, Stream readStream, Stream writeStream)
|
||||
{
|
||||
// as of 12/2017 .NET limits array indexing to using a signed integer
|
||||
|
||||
@@ -71,7 +71,7 @@ void Unpack20(bool Solid)
|
||||
}
|
||||
if (UnpAudioBlock)
|
||||
{
|
||||
uint AudioNumber=DecodeNumber(Inp,&MD[UnpCurChannel]);
|
||||
uint AudioNumber=DecodeNumber(Inp,MD[UnpCurChannel]);
|
||||
|
||||
if (AudioNumber==256)
|
||||
{
|
||||
@@ -86,7 +86,7 @@ void Unpack20(bool Solid)
|
||||
continue;
|
||||
}
|
||||
|
||||
uint Number=DecodeNumber(Inp,&BlockTables.LD);
|
||||
uint Number=DecodeNumber(Inp,BlockTables.LD);
|
||||
if (Number<256)
|
||||
{
|
||||
Window[UnpPtr++]=(byte)Number;
|
||||
@@ -102,7 +102,7 @@ void Unpack20(bool Solid)
|
||||
Inp.addbits(Bits);
|
||||
}
|
||||
|
||||
uint DistNumber=DecodeNumber(Inp,&BlockTables.DD);
|
||||
uint DistNumber=DecodeNumber(Inp,BlockTables.DD);
|
||||
uint Distance=DDecode[DistNumber]+1;
|
||||
if ((Bits=DBits[DistNumber])>0)
|
||||
{
|
||||
@@ -134,7 +134,7 @@ void Unpack20(bool Solid)
|
||||
if (Number<261)
|
||||
{
|
||||
uint Distance=OldDist[(OldDistPtr-(Number-256)) & 3];
|
||||
uint LengthNumber=DecodeNumber(Inp,&BlockTables.RD);
|
||||
uint LengthNumber=DecodeNumber(Inp,BlockTables.RD);
|
||||
uint Length=LDecode[LengthNumber]+2;
|
||||
if ((Bits=LBits[LengthNumber])>0)
|
||||
{
|
||||
@@ -197,7 +197,7 @@ bool ReadTables20()
|
||||
uint BitField=Inp.getbits();
|
||||
UnpAudioBlock=(BitField & 0x8000)!=0;
|
||||
|
||||
if (!(BitField & 0x4000))
|
||||
if ((BitField & 0x4000) != 0)
|
||||
Utility.Memset(UnpOldTable20,0,UnpOldTable20.Length);
|
||||
Inp.addbits(2);
|
||||
|
||||
@@ -218,13 +218,13 @@ bool ReadTables20()
|
||||
BitLength[I]=(byte)(Inp.getbits() >> 12);
|
||||
Inp.addbits(4);
|
||||
}
|
||||
MakeDecodeTables(BitLength,&BlockTables.BD,BC20);
|
||||
MakeDecodeTables(BitLength,BlockTables.BD,BC20);
|
||||
for (uint I=0;I<TableSize;)
|
||||
{
|
||||
if (Inp.InAddr>ReadTop-5)
|
||||
if (!UnpReadBuf())
|
||||
return false;
|
||||
uint Number=DecodeNumber(Inp,&BlockTables.BD);
|
||||
uint Number=DecodeNumber(Inp,BlockTables.BD);
|
||||
if (Number<16)
|
||||
{
|
||||
Table[I]=(Number+UnpOldTable20[I]) & 0xf;
|
||||
@@ -269,9 +269,9 @@ bool ReadTables20()
|
||||
MakeDecodeTables(&Table[I*MC20],&MD[I],MC20);
|
||||
else
|
||||
{
|
||||
MakeDecodeTables(&Table[0],&BlockTables.LD,NC20);
|
||||
MakeDecodeTables(&Table[NC20],&BlockTables.DD,DC20);
|
||||
MakeDecodeTables(&Table[NC20+DC20],&BlockTables.RD,RC20);
|
||||
MakeDecodeTables(&Table[0],BlockTables.LD,NC20);
|
||||
MakeDecodeTables(&Table[NC20],BlockTables.DD,DC20);
|
||||
MakeDecodeTables(&Table[NC20+DC20],BlockTables.RD,RC20);
|
||||
}
|
||||
memcpy(UnpOldTable20,Table,sizeof(UnpOldTable20));
|
||||
return true;
|
||||
@@ -283,11 +283,11 @@ void ReadLastTables()
|
||||
if (ReadTop>=Inp.InAddr+5)
|
||||
if (UnpAudioBlock)
|
||||
{
|
||||
if (DecodeNumber(Inp,&MD[UnpCurChannel])==256)
|
||||
if (DecodeNumber(Inp,MD[UnpCurChannel])==256)
|
||||
ReadTables20();
|
||||
}
|
||||
else
|
||||
if (DecodeNumber(Inp,&BlockTables.LD)==269)
|
||||
if (DecodeNumber(Inp,BlockTables.LD)==269)
|
||||
ReadTables20();
|
||||
}
|
||||
|
||||
@@ -311,13 +311,13 @@ void UnpInitData20(bool Solid)
|
||||
|
||||
byte DecodeAudio(int Delta)
|
||||
{
|
||||
struct AudioVariables *V=&AudV[UnpCurChannel];
|
||||
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*UnpChannelDelta;
|
||||
AudioVariables V=AudV[UnpCurChannel];
|
||||
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*UnpChannelDelta;
|
||||
PCh=(PCh>>3) & 0xFF;
|
||||
|
||||
uint Ch=PCh-Delta;
|
||||
@@ -327,75 +327,75 @@ byte DecodeAudio(int Delta)
|
||||
// so we cast it to unsigned to follow the standard.
|
||||
D=(uint)D<<3;
|
||||
|
||||
V->Dif[0]+=abs(D);
|
||||
V->Dif[1]+=abs(D-V->D1);
|
||||
V->Dif[2]+=abs(D+V->D1);
|
||||
V->Dif[3]+=abs(D-V->D2);
|
||||
V->Dif[4]+=abs(D+V->D2);
|
||||
V->Dif[5]+=abs(D-V->D3);
|
||||
V->Dif[6]+=abs(D+V->D3);
|
||||
V->Dif[7]+=abs(D-V->D4);
|
||||
V->Dif[8]+=abs(D+V->D4);
|
||||
V->Dif[9]+=abs(D-UnpChannelDelta);
|
||||
V->Dif[10]+=abs(D+UnpChannelDelta);
|
||||
V.Dif[0]+=Math.Abs(D);
|
||||
V.Dif[1]+=Math.Abs(D-V.D1);
|
||||
V.Dif[2]+=Math.Abs(D+V.D1);
|
||||
V.Dif[3]+=Math.Abs(D-V.D2);
|
||||
V.Dif[4]+=Math.Abs(D+V.D2);
|
||||
V.Dif[5]+=Math.Abs(D-V.D3);
|
||||
V.Dif[6]+=Math.Abs(D+V.D3);
|
||||
V.Dif[7]+=Math.Abs(D-V.D4);
|
||||
V.Dif[8]+=Math.Abs(D+V.D4);
|
||||
V.Dif[9]+=Math.Abs(D-UnpChannelDelta);
|
||||
V.Dif[10]+=Math.Abs(D+UnpChannelDelta);
|
||||
|
||||
UnpChannelDelta=V->LastDelta=(sbyte)(Ch-V->LastChar);
|
||||
V->LastChar=Ch;
|
||||
UnpChannelDelta=V.LastDelta=(sbyte)(Ch-V.LastChar);
|
||||
V.LastChar=Ch;
|
||||
|
||||
if ((V->ByteCount & 0x1F)==0)
|
||||
if ((V.ByteCount & 0x1F)==0)
|
||||
{
|
||||
uint MinDif=V->Dif[0],NumMinDif=0;
|
||||
V->Dif[0]=0;
|
||||
for (uint I=1;I<ASIZE(V->Dif);I++)
|
||||
uint MinDif=V.Dif[0],NumMinDif=0;
|
||||
V.Dif[0]=0;
|
||||
for (uint I=1;I<V.Dif.Length;I++)
|
||||
{
|
||||
if (V->Dif[I]<MinDif)
|
||||
if (V.Dif[I]<MinDif)
|
||||
{
|
||||
MinDif=V->Dif[I];
|
||||
MinDif=V.Dif[I];
|
||||
NumMinDif=I;
|
||||
}
|
||||
V->Dif[I]=0;
|
||||
V.Dif[I]=0;
|
||||
}
|
||||
switch(NumMinDif)
|
||||
{
|
||||
case 1:
|
||||
if (V->K1>=-16)
|
||||
V->K1--;
|
||||
if (V.K1>=-16)
|
||||
V.K1--;
|
||||
break;
|
||||
case 2:
|
||||
if (V->K1<16)
|
||||
V->K1++;
|
||||
if (V.K1<16)
|
||||
V.K1++;
|
||||
break;
|
||||
case 3:
|
||||
if (V->K2>=-16)
|
||||
V->K2--;
|
||||
if (V.K2>=-16)
|
||||
V.K2--;
|
||||
break;
|
||||
case 4:
|
||||
if (V->K2<16)
|
||||
V->K2++;
|
||||
if (V.K2<16)
|
||||
V.K2++;
|
||||
break;
|
||||
case 5:
|
||||
if (V->K3>=-16)
|
||||
V->K3--;
|
||||
if (V.K3>=-16)
|
||||
V.K3--;
|
||||
break;
|
||||
case 6:
|
||||
if (V->K3<16)
|
||||
V->K3++;
|
||||
if (V.K3<16)
|
||||
V.K3++;
|
||||
break;
|
||||
case 7:
|
||||
if (V->K4>=-16)
|
||||
V->K4--;
|
||||
if (V.K4>=-16)
|
||||
V.K4--;
|
||||
break;
|
||||
case 8:
|
||||
if (V->K4<16)
|
||||
V->K4++;
|
||||
if (V.K4<16)
|
||||
V.K4++;
|
||||
break;
|
||||
case 9:
|
||||
if (V->K5>=-16)
|
||||
V->K5--;
|
||||
if (V.K5>=-16)
|
||||
V.K5--;
|
||||
break;
|
||||
case 10:
|
||||
if (V->K5<16)
|
||||
V->K5++;
|
||||
if (V.K5<16)
|
||||
V.K5++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ void Unpack29(bool Solid)
|
||||
continue;
|
||||
}
|
||||
|
||||
uint Number=DecodeNumber(Inp,&BlockTables.LD);
|
||||
uint Number=DecodeNumber(Inp,BlockTables.LD);
|
||||
if (Number<256)
|
||||
{
|
||||
Window[UnpPtr++]=(byte)Number;
|
||||
@@ -174,7 +174,7 @@ void Unpack29(bool Solid)
|
||||
Inp.addbits(Bits);
|
||||
}
|
||||
|
||||
uint DistNumber=DecodeNumber(Inp,&BlockTables.DD);
|
||||
uint DistNumber=DecodeNumber(Inp,BlockTables.DD);
|
||||
uint Distance=DDecode[DistNumber]+1;
|
||||
if ((Bits=DBits[DistNumber])>0)
|
||||
{
|
||||
@@ -192,7 +192,7 @@ void Unpack29(bool Solid)
|
||||
}
|
||||
else
|
||||
{
|
||||
uint LowDist=DecodeNumber(Inp,&BlockTables.LDD);
|
||||
uint LowDist=DecodeNumber(Inp,BlockTables.LDD);
|
||||
if (LowDist==16)
|
||||
{
|
||||
LowDistRepCount=LOW_DIST_REP_COUNT-1;
|
||||
@@ -250,7 +250,7 @@ void Unpack29(bool Solid)
|
||||
OldDist[I]=OldDist[I-1];
|
||||
OldDist[0]=Distance;
|
||||
|
||||
uint LengthNumber=DecodeNumber(Inp,&BlockTables.RD);
|
||||
uint LengthNumber=DecodeNumber(Inp,BlockTables.RD);
|
||||
int Length=LDecode[LengthNumber]+2;
|
||||
if ((Bits=LBits[LengthNumber])>0)
|
||||
{
|
||||
@@ -703,7 +703,7 @@ bool ReadTables30()
|
||||
if (Inp.InAddr>ReadTop-5)
|
||||
if (!UnpReadBuf30())
|
||||
return(false);
|
||||
uint Number=DecodeNumber(Inp,&BlockTables.BD);
|
||||
uint Number=DecodeNumber(Inp,BlockTables.BD);
|
||||
if (Number<16)
|
||||
{
|
||||
Table[I]=(Number+UnpOldTable[I]) & 0xf;
|
||||
|
||||
@@ -11,10 +11,6 @@ using size_t = System.UInt64;
|
||||
using int64 = System.Int64;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static SharpCompress.Compressors.Rar.UnpackV2017.PackDef;
|
||||
using static SharpCompress.Compressors.Rar.UnpackV2017.UnpackGlobal;
|
||||
|
||||
@@ -35,8 +31,8 @@ void Unpack5(bool Solid)
|
||||
// Check TablesRead5 to be sure that we read tables at least once
|
||||
// regardless of current block header TablePresent flag.
|
||||
// So we can safefly use these tables below.
|
||||
if (!ReadBlockHeader(Inp,BlockHeader) ||
|
||||
!ReadTables(Inp,BlockHeader,BlockTables) || !TablesRead5)
|
||||
if (!ReadBlockHeader(Inp,ref BlockHeader) ||
|
||||
!ReadTables(Inp,ref BlockHeader, ref BlockTables) || !TablesRead5)
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,7 +55,7 @@ void Unpack5(bool Solid)
|
||||
FileDone=true;
|
||||
break;
|
||||
}
|
||||
if (!ReadBlockHeader(Inp,BlockHeader) || !ReadTables(Inp,BlockHeader,BlockTables))
|
||||
if (!ReadBlockHeader(Inp,ref BlockHeader) || !ReadTables(Inp, ref BlockHeader, ref BlockTables))
|
||||
return;
|
||||
}
|
||||
if (FileDone || !UnpReadBuf())
|
||||
@@ -78,7 +74,7 @@ void Unpack5(bool Solid)
|
||||
}
|
||||
}
|
||||
|
||||
uint MainSlot=DecodeNumber(Inp,&BlockTables.LD);
|
||||
uint MainSlot=DecodeNumber(Inp,BlockTables.LD);
|
||||
if (MainSlot<256)
|
||||
{
|
||||
if (Fragmented)
|
||||
@@ -91,7 +87,7 @@ void Unpack5(bool Solid)
|
||||
{
|
||||
uint Length=SlotToLength(Inp,MainSlot-262);
|
||||
|
||||
uint DBits,Distance=1,DistSlot=DecodeNumber(Inp,&BlockTables.DD);
|
||||
uint DBits,Distance=1,DistSlot=DecodeNumber(Inp,BlockTables.DD);
|
||||
if (DistSlot<4)
|
||||
{
|
||||
DBits=0;
|
||||
@@ -112,7 +108,7 @@ void Unpack5(bool Solid)
|
||||
Distance+=((Inp.getbits32()>>(36-DBits))<<4);
|
||||
Inp.addbits(DBits-4);
|
||||
}
|
||||
uint LowDist=DecodeNumber(Inp,&BlockTables.LDD);
|
||||
uint LowDist=DecodeNumber(Inp,BlockTables.LDD);
|
||||
Distance+=LowDist;
|
||||
}
|
||||
else
|
||||
@@ -165,7 +161,7 @@ void Unpack5(bool Solid)
|
||||
OldDist[I]=OldDist[I-1];
|
||||
OldDist[0]=Distance;
|
||||
|
||||
uint LengthSlot=DecodeNumber(Inp,&BlockTables.RD);
|
||||
uint LengthSlot=DecodeNumber(Inp,BlockTables.RD);
|
||||
uint Length=SlotToLength(Inp,LengthSlot);
|
||||
LastLength=Length;
|
||||
if (Fragmented)
|
||||
@@ -232,7 +228,7 @@ bool AddFilter(UnpackFilter Filter)
|
||||
// flag and process this filter only after processing that older data.
|
||||
Filter.NextWindow=WrPtr!=UnpPtr && ((WrPtr-UnpPtr)&MaxWinMask)<=Filter.BlockStart;
|
||||
|
||||
Filter.BlockStart=uint((Filter.BlockStart+UnpPtr)&MaxWinMask);
|
||||
Filter.BlockStart=(uint)((Filter.BlockStart+UnpPtr)&MaxWinMask);
|
||||
Filters.Push(Filter);
|
||||
return true;
|
||||
}
|
||||
@@ -282,7 +278,9 @@ void UnpWriteBuf()
|
||||
size_t FullWriteSize=(UnpPtr-WrittenBorder)&MaxWinMask;
|
||||
size_t WriteSizeLeft=FullWriteSize;
|
||||
bool NotAllFiltersProcessed=false;
|
||||
for (size_t I=0;I<Filters.Count;I++)
|
||||
//for (size_t I=0;I<Filters.Count;I++)
|
||||
// sharpcompress: size_t -> int
|
||||
for (int I=0;I<Filters.Count;I++)
|
||||
{
|
||||
// Here we apply filters to data which we need to write.
|
||||
// We always copy data to another memory block before processing.
|
||||
@@ -373,11 +371,13 @@ void UnpWriteBuf()
|
||||
// Since Filter start position can only increase, we quit processing
|
||||
// all following filters for this data block and reset 'NextWindow'
|
||||
// flag for them.
|
||||
for (size_t J=I;J<Filters.Count;J++)
|
||||
//for (size_t J=I;J<Filters.Count;J++)
|
||||
// sharpcompress: size_t -> int
|
||||
for (int J=I;J<Filters.Count;J++)
|
||||
{
|
||||
UnpackFilter flt=Filters[J];
|
||||
if (flt.Type!=FILTER_NONE)
|
||||
flt.NextWindow=false;
|
||||
UnpackFilter _flt=Filters[J];
|
||||
if (_flt.Type!=FILTER_NONE)
|
||||
_flt.NextWindow=false;
|
||||
}
|
||||
|
||||
// Do not write data left after current filter now.
|
||||
@@ -469,7 +469,7 @@ byte* ApplyFilter(byte *Data,uint DataSize,UnpackFilter Flt)
|
||||
byte *D=Data+CurPos;
|
||||
if (D[3]==0xeb) // BL command with '1110' (Always) condition.
|
||||
{
|
||||
uint Offset=D[0]+uint(D[1])*0x100+uint(D[2])*0x10000;
|
||||
uint Offset=D[0]+(uint)(D[1])*0x100+(uint)(D[2])*0x10000;
|
||||
Offset-=(FileOffset+CurPos)/4;
|
||||
D[0]=(byte)Offset;
|
||||
D[1]=(byte)(Offset>>8);
|
||||
@@ -552,7 +552,7 @@ void UnpInitData50(bool Solid)
|
||||
}
|
||||
|
||||
|
||||
bool ReadBlockHeader(BitInput Inp,UnpackBlockHeader &Header)
|
||||
bool ReadBlockHeader(BitInput Inp,ref UnpackBlockHeader Header)
|
||||
{
|
||||
Header.HeaderSize=0;
|
||||
|
||||
@@ -583,12 +583,12 @@ bool ReadBlockHeader(BitInput Inp,UnpackBlockHeader &Header)
|
||||
}
|
||||
|
||||
Header.BlockSize=BlockSize;
|
||||
byte CheckSum=byte(0x5a^BlockFlags^BlockSize^(BlockSize>>8)^(BlockSize>>16));
|
||||
byte CheckSum=(byte)(0x5a^BlockFlags^BlockSize^(BlockSize>>8)^(BlockSize>>16));
|
||||
if (CheckSum!=SavedCheckSum)
|
||||
return false;
|
||||
|
||||
Header.BlockStart=Inp.InAddr;
|
||||
ReadBorder=Min(ReadBorder,Header.BlockStart+Header.BlockSize-1);
|
||||
ReadBorder=Math.Min(ReadBorder,Header.BlockStart+Header.BlockSize-1);
|
||||
|
||||
Header.LastBlockInFile=(BlockFlags & 0x40)!=0;
|
||||
Header.TablePresent=(BlockFlags & 0x80)!=0;
|
||||
@@ -596,7 +596,7 @@ bool ReadBlockHeader(BitInput Inp,UnpackBlockHeader &Header)
|
||||
}
|
||||
|
||||
|
||||
bool ReadTables(BitInput Inp,UnpackBlockHeader &Header,UnpackBlockTables &Tables)
|
||||
bool ReadTables(BitInput Inp,ref UnpackBlockHeader Header, ref UnpackBlockTables Tables)
|
||||
{
|
||||
if (!Header.TablePresent)
|
||||
return true;
|
||||
@@ -605,7 +605,7 @@ bool ReadTables(BitInput Inp,UnpackBlockHeader &Header,UnpackBlockTables &Tables
|
||||
if (!UnpReadBuf())
|
||||
return false;
|
||||
|
||||
byte BitLength[BC];
|
||||
byte[] BitLength = new byte[BC];
|
||||
for (uint I=0;I<BC;I++)
|
||||
{
|
||||
uint Length=(byte)(Inp.fgetbits() >> 12);
|
||||
@@ -619,7 +619,7 @@ bool ReadTables(BitInput Inp,UnpackBlockHeader &Header,UnpackBlockTables &Tables
|
||||
else
|
||||
{
|
||||
ZeroCount+=2;
|
||||
while (ZeroCount-- > 0 && I<ASIZE(BitLength))
|
||||
while (ZeroCount-- > 0 && I<BitLength.Length)
|
||||
BitLength[I++]=0;
|
||||
I--;
|
||||
}
|
||||
@@ -628,16 +628,16 @@ bool ReadTables(BitInput Inp,UnpackBlockHeader &Header,UnpackBlockTables &Tables
|
||||
BitLength[I]=Length;
|
||||
}
|
||||
|
||||
MakeDecodeTables(BitLength,&Tables.BD,BC);
|
||||
MakeDecodeTables(BitLength,Tables.BD,BC);
|
||||
|
||||
byte Table[HUFF_TABLE_SIZE];
|
||||
byte[] Table = new byte[HUFF_TABLE_SIZE];
|
||||
const uint TableSize=HUFF_TABLE_SIZE;
|
||||
for (uint I=0;I<TableSize;)
|
||||
{
|
||||
if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop-5)
|
||||
if (!UnpReadBuf())
|
||||
return false;
|
||||
uint Number=DecodeNumber(Inp,&Tables.BD);
|
||||
uint Number=DecodeNumber(Inp,Tables.BD);
|
||||
if (Number<16)
|
||||
{
|
||||
Table[I]=Number;
|
||||
@@ -693,10 +693,10 @@ bool ReadTables(BitInput Inp,UnpackBlockHeader &Header,UnpackBlockTables &Tables
|
||||
TablesRead5=true;
|
||||
if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop)
|
||||
return false;
|
||||
MakeDecodeTables(&Table[0],&Tables.LD,NC);
|
||||
MakeDecodeTables(&Table[NC],&Tables.DD,DC);
|
||||
MakeDecodeTables(&Table[NC+DC],&Tables.LDD,LDC);
|
||||
MakeDecodeTables(&Table[NC+DC+LDC],&Tables.RD,RC);
|
||||
MakeDecodeTables(&Table[0],Tables.LD,NC);
|
||||
MakeDecodeTables(&Table[NC],Tables.DD,DC);
|
||||
MakeDecodeTables(&Table[NC+DC],Tables.LDD,LDC);
|
||||
MakeDecodeTables(&Table[NC+DC+LDC],Tables.RD,RC);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ public Unpack(/* ComprDataIO *DataIO */)
|
||||
//:Inp(true),VMCodeInp(true)
|
||||
: base(true)
|
||||
{
|
||||
_UnpackCtor();
|
||||
|
||||
UnpIO=DataIO;
|
||||
Window=null;
|
||||
Fragmented=false;
|
||||
@@ -227,14 +229,14 @@ void UnpInitData(bool Solid)
|
||||
// LengthTable contains the length in bits for every element of alphabet.
|
||||
// Dec is the structure to decode Huffman code/
|
||||
// Size is size of length table and DecodeNum field in Dec structure,
|
||||
void MakeDecodeTables(byte *LengthTable,DecodeTable *Dec,uint Size)
|
||||
void MakeDecodeTables(byte *LengthTable,DecodeTable Dec,uint Size)
|
||||
{
|
||||
// Size of alphabet and DecodePos array.
|
||||
Dec->MaxNum=Size;
|
||||
Dec.MaxNum=Size;
|
||||
|
||||
// Calculate how many entries for every bit length in LengthTable we have.
|
||||
uint LengthCount[16];
|
||||
memset(LengthCount,0,sizeof(LengthCount));
|
||||
uint[] LengthCount = new uint[16];
|
||||
//memset(LengthCount,0,sizeof(LengthCount));
|
||||
for (size_t I=0;I<Size;I++)
|
||||
LengthCount[LengthTable[I] & 0xf]++;
|
||||
|
||||
@@ -245,10 +247,10 @@ void MakeDecodeTables(byte *LengthTable,DecodeTable *Dec,uint Size)
|
||||
memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));
|
||||
|
||||
// Initialize not really used entry for zero length code.
|
||||
Dec->DecodePos[0]=0;
|
||||
Dec.DecodePos[0]=0;
|
||||
|
||||
// Start code for bit length 1 is 0.
|
||||
Dec->DecodeLen[0]=0;
|
||||
Dec.DecodeLen[0]=0;
|
||||
|
||||
// Right aligned upper limit code for current bit length.
|
||||
uint UpperLimit=0;
|
||||
@@ -265,17 +267,17 @@ void MakeDecodeTables(byte *LengthTable,DecodeTable *Dec,uint Size)
|
||||
UpperLimit*=2;
|
||||
|
||||
// Store the left aligned upper limit code.
|
||||
Dec->DecodeLen[I]=(uint)LeftAligned;
|
||||
Dec.DecodeLen[I]=(uint)LeftAligned;
|
||||
|
||||
// Every item of this array contains the sum of all preceding items.
|
||||
// So it contains the start position in code list for every bit length.
|
||||
Dec->DecodePos[I]=Dec->DecodePos[I-1]+LengthCount[I-1];
|
||||
Dec.DecodePos[I]=Dec.DecodePos[I-1]+LengthCount[I-1];
|
||||
}
|
||||
|
||||
// Prepare the copy of DecodePos. We'll modify this copy below,
|
||||
// so we cannot use the original DecodePos.
|
||||
uint CopyDecodePos[ASIZE(Dec->DecodePos)];
|
||||
memcpy(CopyDecodePos,Dec->DecodePos,sizeof(CopyDecodePos));
|
||||
uint[] CopyDecodePos = new uint[Dec.DecodePos.Length];
|
||||
//memcpy(CopyDecodePos,Dec->DecodePos,sizeof(CopyDecodePos));
|
||||
|
||||
// For every bit length in the bit length table and so for every item
|
||||
// of alphabet.
|
||||
@@ -291,7 +293,7 @@ void MakeDecodeTables(byte *LengthTable,DecodeTable *Dec,uint Size)
|
||||
|
||||
// Prepare the decode table, so this position in code list will be
|
||||
// decoded to current alphabet item number.
|
||||
Dec->DecodeNum[LastPos]=(ushort)I;
|
||||
Dec.DecodeNum[LastPos]=(ushort)I;
|
||||
|
||||
// We'll use next position number for this bit length next time.
|
||||
// So we pass through the entire range of positions available
|
||||
|
||||
@@ -103,22 +103,22 @@ void CopyString(uint Length,uint Distance)
|
||||
}
|
||||
|
||||
|
||||
uint DecodeNumber(BitInput Inp,DecodeTable *Dec)
|
||||
uint DecodeNumber(BitInput Inp,DecodeTable Dec)
|
||||
{
|
||||
// Left aligned 15 bit length raw bit field.
|
||||
uint BitField=Inp.getbits() & 0xfffe;
|
||||
|
||||
if (BitField<Dec->DecodeLen[Dec->QuickBits])
|
||||
if (BitField<Dec.DecodeLen[Dec.QuickBits])
|
||||
{
|
||||
uint Code=BitField>>(16-Dec->QuickBits);
|
||||
Inp.addbits(Dec->QuickLen[Code]);
|
||||
return Dec->QuickNum[Code];
|
||||
uint Code=BitField>>(16-Dec.QuickBits);
|
||||
Inp.addbits(Dec.QuickLen[Code]);
|
||||
return Dec.QuickNum[Code];
|
||||
}
|
||||
|
||||
// Detect the real bit length for current code.
|
||||
uint Bits=15;
|
||||
for (uint I=Dec->QuickBits+1;I<15;I++)
|
||||
if (BitField<Dec->DecodeLen[I])
|
||||
for (uint I=Dec.QuickBits+1;I<15;I++)
|
||||
if (BitField<Dec.DecodeLen[I])
|
||||
{
|
||||
Bits=I;
|
||||
break;
|
||||
@@ -127,7 +127,7 @@ uint DecodeNumber(BitInput Inp,DecodeTable *Dec)
|
||||
Inp.addbits(Bits);
|
||||
|
||||
// Calculate the distance from the start code for current bit length.
|
||||
uint Dist=BitField-Dec->DecodeLen[Bits-1];
|
||||
uint Dist=BitField-Dec.DecodeLen[Bits-1];
|
||||
|
||||
// Start codes are left aligned, but we need the normal right aligned
|
||||
// number. So we shift the distance to the right.
|
||||
@@ -136,15 +136,15 @@ uint DecodeNumber(BitInput Inp,DecodeTable *Dec)
|
||||
// Now we can calculate the position in the code list. It is the sum
|
||||
// of first position for current bit length and right aligned distance
|
||||
// between our bit field and start code for current bit length.
|
||||
uint Pos=Dec->DecodePos[Bits]+Dist;
|
||||
uint Pos=Dec.DecodePos[Bits]+Dist;
|
||||
|
||||
// Out of bounds safety check required for damaged archives.
|
||||
if (Pos>=Dec->MaxNum)
|
||||
if (Pos>=Dec.MaxNum)
|
||||
Pos=0;
|
||||
|
||||
// Convert the position in the code list to position in alphabet
|
||||
// and return it.
|
||||
return Dec->DecodeNum[Pos];
|
||||
return Dec.DecodeNum[Pos];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,11 +10,7 @@ using size_t = System.UInt64;
|
||||
#endif
|
||||
using int64 = System.Int64;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static SharpCompress.Compressors.Rar.UnpackV2017.PackDef;
|
||||
using static SharpCompress.Compressors.Rar.UnpackV2017.UnpackGlobal;
|
||||
|
||||
@@ -55,32 +51,32 @@ public const int UNPACK_MAX_WRITE =0x400000;
|
||||
sealed class DecodeTable
|
||||
{
|
||||
// Real size of DecodeNum table.
|
||||
uint MaxNum;
|
||||
public uint MaxNum;
|
||||
|
||||
// Left aligned start and upper limit codes defining code space
|
||||
// ranges for bit lengths. DecodeLen[BitLength-1] defines the start of
|
||||
// range for bit length and DecodeLen[BitLength] defines next code
|
||||
// after the end of range or in other words the upper limit code
|
||||
// for specified bit length.
|
||||
readonly uint[] DecodeLen = new uint[16];
|
||||
public readonly uint[] DecodeLen = new uint[16];
|
||||
|
||||
// Every item of this array contains the sum of all preceding items.
|
||||
// So it contains the start position in code list for every bit length.
|
||||
readonly uint[] DecodePos = new uint[16];
|
||||
public readonly uint[] DecodePos = new uint[16];
|
||||
|
||||
// Number of compressed bits processed in quick mode.
|
||||
// Must not exceed MAX_QUICK_DECODE_BITS.
|
||||
uint QuickBits;
|
||||
public uint QuickBits;
|
||||
|
||||
// Translates compressed bits (up to QuickBits length)
|
||||
// to bit length in quick mode.
|
||||
readonly byte[] QuickLen = new byte[1<<MAX_QUICK_DECODE_BITS];
|
||||
public readonly byte[] QuickLen = new byte[1<<MAX_QUICK_DECODE_BITS];
|
||||
|
||||
// Translates compressed bits (up to QuickBits length)
|
||||
// to position in alphabet in quick mode.
|
||||
// 'ushort' saves some memory and even provides a little speed gain
|
||||
// comparting to 'uint' here.
|
||||
readonly ushort[] QuickNum = new ushort[1<<MAX_QUICK_DECODE_BITS];
|
||||
public readonly ushort[] QuickNum = new ushort[1<<MAX_QUICK_DECODE_BITS];
|
||||
|
||||
// Translate the position in code list to position in alphabet.
|
||||
// We do not allocate it dynamically to avoid performance overhead
|
||||
@@ -90,7 +86,7 @@ sealed class DecodeTable
|
||||
// for QuickLen based translation.
|
||||
// 'ushort' saves some memory and even provides a little speed gain
|
||||
// comparting to 'uint' here.
|
||||
readonly ushort[] DecodeNum = new ushort[LARGEST_TABLE_SIZE];
|
||||
public readonly ushort[] DecodeNum = new ushort[LARGEST_TABLE_SIZE];
|
||||
};
|
||||
|
||||
|
||||
@@ -112,6 +108,14 @@ struct UnpackBlockTables
|
||||
public DecodeTable LDD; // Decode lower bits of distances.
|
||||
public DecodeTable RD; // Decode repeating distances.
|
||||
public DecodeTable BD; // Decode bit lengths in Huffman table.
|
||||
|
||||
public void Init() {
|
||||
this.LD = new DecodeTable();
|
||||
this.DD = new DecodeTable();
|
||||
this.LDD = new DecodeTable();
|
||||
this.RD = new DecodeTable();
|
||||
this.BD = new DecodeTable();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -193,14 +197,14 @@ class UnpackFilter30
|
||||
};
|
||||
|
||||
|
||||
struct AudioVariables // For RAR 2.0 archives only.
|
||||
class AudioVariables // For RAR 2.0 archives only.
|
||||
{
|
||||
int K1,K2,K3,K4,K5;
|
||||
int D1,D2,D3,D4;
|
||||
int LastDelta;
|
||||
uint Dif[11];
|
||||
uint ByteCount;
|
||||
int LastChar;
|
||||
public int K1,K2,K3,K4,K5;
|
||||
public int D1,D2,D3,D4;
|
||||
public int LastDelta;
|
||||
public readonly uint[] Dif = new uint[11];
|
||||
public uint ByteCount;
|
||||
public int LastChar;
|
||||
};
|
||||
|
||||
|
||||
@@ -250,7 +254,7 @@ internal partial class Unpack
|
||||
//bool AddFilter();
|
||||
//void InitFilters();
|
||||
|
||||
ComprDataIO *UnpIO;
|
||||
//ComprDataIO *UnpIO;
|
||||
//BitInput Inp;
|
||||
BitInput Inp { get { return this; } } // hopefully this gets inlined
|
||||
|
||||
@@ -321,8 +325,8 @@ internal partial class Unpack
|
||||
//void CopyString15(uint Distance,uint Length);
|
||||
//uint DecodeNum(uint Num,uint StartPos,uint *DecTab,uint *PosTab);
|
||||
|
||||
ushort ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256];
|
||||
byte NToPl[256],NToPlB[256],NToPlC[256];
|
||||
readonly ushort[] ChSet = new ushort[256],ChSetA = new ushort[256],ChSetB = new ushort[256],ChSetC = new ushort[256];
|
||||
readonly byte[] NToPl = new byte[256],NToPlB = new byte[256],NToPlC = new byte[256];
|
||||
uint FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3;
|
||||
int Buf60,NumHuf,StMode,LCount,FlagsCnt;
|
||||
uint Nhfb,Nlzb,MaxDist3;
|
||||
@@ -331,7 +335,7 @@ internal partial class Unpack
|
||||
/***************************** Unpack v 2.0 *********************************/
|
||||
//void Unpack20(bool Solid);
|
||||
|
||||
DecodeTable MD[4]; // Decode multimedia data, up to 4 channels.
|
||||
readonly DecodeTable[] MD = new DecodeTable[4]; // Decode multimedia data, up to 4 channels.
|
||||
|
||||
readonly byte[] UnpOldTable20 = new byte[MC20*4];
|
||||
bool UnpAudioBlock;
|
||||
@@ -343,7 +347,7 @@ internal partial class Unpack
|
||||
//void UnpInitData20(int Solid);
|
||||
//void ReadLastTables();
|
||||
//byte DecodeAudio(int Delta);
|
||||
struct AudioVariables AudV[4];
|
||||
AudioVariables[] AudV = new AudioVariables[4];
|
||||
/***************************** Unpack v 2.0 *********************************/
|
||||
|
||||
/***************************** Unpack v 3.0 *********************************/
|
||||
@@ -424,10 +428,8 @@ internal partial class Unpack
|
||||
UnpReadBuf();
|
||||
return(Inp.InBuf[Inp.InAddr++]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user