74 changes: 41 additions & 33 deletions unpack20.cpp
Expand Up @@ -13,11 +13,11 @@ void Unpack::Unpack20(bool Solid)
{
static unsigned char LDecode[]={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 unsigned char LBits[]= {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 int DDecode[]={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};
static uint DDecode[]={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};
static unsigned char DBits[]= {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};
static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
static unsigned char SDBits[]= {2,2,3, 4, 5, 6, 6, 6};
unsigned int Bits;
uint Bits;

if (Suspended)
UnpPtr=WrPtr;
Expand All @@ -26,9 +26,8 @@ void Unpack::Unpack20(bool Solid)
UnpInitData(Solid);
if (!UnpReadBuf())
return;
if (!Solid)
if (!ReadTables20())
return;
if ((!Solid || !TablesRead2) && !ReadTables20())
return;
--DestUnpSize;
}

Expand All @@ -47,22 +46,22 @@ void Unpack::Unpack20(bool Solid)
}
if (UnpAudioBlock)
{
int AudioNumber=DecodeNumber(Inp,&MD[UnpCurChannel]);
uint AudioNumber=DecodeNumber(Inp,&MD[UnpCurChannel]);

if (AudioNumber==256)
{
if (!ReadTables20())
break;
continue;
}
Window[UnpPtr++]=DecodeAudio(AudioNumber);
Window[UnpPtr++]=DecodeAudio((int)AudioNumber);
if (++UnpCurChannel==UnpChannels)
UnpCurChannel=0;
--DestUnpSize;
continue;
}

int Number=DecodeNumber(Inp,&BlockTables.LD);
uint Number=DecodeNumber(Inp,&BlockTables.LD);
if (Number<256)
{
Window[UnpPtr++]=(byte)Number;
Expand All @@ -71,15 +70,15 @@ void Unpack::Unpack20(bool Solid)
}
if (Number>269)
{
int Length=LDecode[Number-=270]+3;
uint Length=LDecode[Number-=270]+3;
if ((Bits=LBits[Number])>0)
{
Length+=Inp.getbits()>>(16-Bits);
Inp.addbits(Bits);
}

int DistNumber=DecodeNumber(Inp,&BlockTables.DD);
unsigned int Distance=DDecode[DistNumber]+1;
uint DistNumber=DecodeNumber(Inp,&BlockTables.DD);
uint Distance=DDecode[DistNumber]+1;
if ((Bits=DBits[DistNumber])>0)
{
Distance+=Inp.getbits()>>(16-Bits);
Expand Down Expand Up @@ -109,9 +108,9 @@ void Unpack::Unpack20(bool Solid)
}
if (Number<261)
{
unsigned int Distance=OldDist[(OldDistPtr-(Number-256)) & 3];
int LengthNumber=DecodeNumber(Inp,&BlockTables.RD);
int Length=LDecode[LengthNumber]+2;
uint Distance=OldDist[(OldDistPtr-(Number-256)) & 3];
uint LengthNumber=DecodeNumber(Inp,&BlockTables.RD);
uint Length=LDecode[LengthNumber]+2;
if ((Bits=LBits[LengthNumber])>0)
{
Length+=Inp.getbits()>>(16-Bits);
Expand All @@ -132,7 +131,7 @@ void Unpack::Unpack20(bool Solid)
}
if (Number<270)
{
unsigned int Distance=SDDecode[Number-=261]+1;
uint Distance=SDDecode[Number-=261]+1;
if ((Bits=SDBits[Number])>0)
{
Distance+=Inp.getbits()>>(16-Bits);
Expand Down Expand Up @@ -167,17 +166,17 @@ bool Unpack::ReadTables20()
{
byte BitLength[BC20];
byte Table[MC20*4];
int TableSize,N,I;
if (Inp.InAddr>ReadTop-25)
if (!UnpReadBuf())
return(false);
return false;
uint BitField=Inp.getbits();
UnpAudioBlock=(BitField & 0x8000);
UnpAudioBlock=(BitField & 0x8000)!=0;

if (!(BitField & 0x4000))
memset(UnpOldTable20,0,sizeof(UnpOldTable20));
Inp.addbits(2);

uint TableSize;
if (UnpAudioBlock)
{
UnpChannels=((BitField>>12) & 3)+1;
Expand All @@ -189,19 +188,18 @@ bool Unpack::ReadTables20()
else
TableSize=NC20+DC20+RC20;

for (I=0;I<BC20;I++)
for (uint I=0;I<BC20;I++)
{
BitLength[I]=(byte)(Inp.getbits() >> 12);
Inp.addbits(4);
}
MakeDecodeTables(BitLength,&BlockTables.BD,BC20);
I=0;
while (I<TableSize)
for (uint I=0;I<TableSize;)
{
if (Inp.InAddr>ReadTop-5)
if (!UnpReadBuf())
return false;
int Number=DecodeNumber(Inp,&BlockTables.BD);
uint Number=DecodeNumber(Inp,&BlockTables.BD);
if (Number<16)
{
Table[I]=(Number+UnpOldTable20[I]) & 0xf;
Expand All @@ -210,9 +208,11 @@ bool Unpack::ReadTables20()
else
if (Number==16)
{
N=(Inp.getbits() >> 14)+3;
uint N=(Inp.getbits() >> 14)+3;
Inp.addbits(2);
if (I>0)
if (I==0)
return false; // We cannot have "repeat previous" code at the first position.
else
while (N-- > 0 && I<TableSize)
{
Table[I]=Table[I-1];
Expand All @@ -221,6 +221,7 @@ bool Unpack::ReadTables20()
}
else
{
uint N;
if (Number==17)
{
N=(Inp.getbits() >> 13)+3;
Expand All @@ -235,10 +236,11 @@ bool Unpack::ReadTables20()
Table[I++]=0;
}
}
TablesRead2=true;
if (Inp.InAddr>ReadTop)
return(true);
return true;
if (UnpAudioBlock)
for (I=0;I<UnpChannels;I++)
for (uint I=0;I<UnpChannels;I++)
MakeDecodeTables(&Table[I*MC20],&MD[I],MC20);
else
{
Expand All @@ -247,7 +249,7 @@ bool Unpack::ReadTables20()
MakeDecodeTables(&Table[NC20+DC20],&BlockTables.RD,RC20);
}
memcpy(UnpOldTable20,Table,sizeof(UnpOldTable20));
return(true);
return true;
}


Expand All @@ -269,7 +271,10 @@ void Unpack::UnpInitData20(int Solid)
{
if (!Solid)
{
UnpAudioBlock=UnpChannelDelta=UnpCurChannel=0;
TablesRead2=false;
UnpAudioBlock=false;
UnpChannelDelta=0;
UnpCurChannel=0;
UnpChannels=1;

memset(AudV,0,sizeof(AudV));
Expand All @@ -290,9 +295,12 @@ byte Unpack::DecodeAudio(int Delta)
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;

unsigned int Ch=PCh-Delta;
uint Ch=PCh-Delta;

int D=((signed char)Delta)<<3;
int D=(signed char)Delta;
// Left shift of negative value is undefined behavior in C++,
// 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);
Expand All @@ -311,9 +319,9 @@ byte Unpack::DecodeAudio(int Delta)

if ((V->ByteCount & 0x1F)==0)
{
unsigned int MinDif=V->Dif[0],NumMinDif=0;
uint MinDif=V->Dif[0],NumMinDif=0;
V->Dif[0]=0;
for (int I=1;I<sizeof(V->Dif)/sizeof(V->Dif[0]);I++)
for (uint I=1;I<ASIZE(V->Dif);I++)
{
if (V->Dif[I]<MinDif)
{
Expand Down Expand Up @@ -366,5 +374,5 @@ byte Unpack::DecodeAudio(int Delta)
break;
}
}
return((byte)Ch);
return (byte)Ch;
}
78 changes: 42 additions & 36 deletions unpack30.cpp
Expand Up @@ -42,7 +42,7 @@ void Unpack::Unpack29(bool Solid)
UnpInitData(Solid);
if (!UnpReadBuf30())
return;
if ((!Solid || !TablesRead) && !ReadTables30())
if ((!Solid || !TablesRead3) && !ReadTables30())
return;
}

Expand Down Expand Up @@ -133,23 +133,23 @@ void Unpack::Unpack29(bool Solid)
continue;
}

int Number=DecodeNumber(Inp,&BlockTables.LD);
uint Number=DecodeNumber(Inp,&BlockTables.LD);
if (Number<256)
{
Window[UnpPtr++]=(byte)Number;
continue;
}
if (Number>=271)
{
int Length=LDecode[Number-=271]+3;
uint Length=LDecode[Number-=271]+3;
if ((Bits=LBits[Number])>0)
{
Length+=Inp.getbits()>>(16-Bits);
Inp.addbits(Bits);
}

int DistNumber=DecodeNumber(Inp,&BlockTables.DD);
unsigned int Distance=DDecode[DistNumber]+1;
uint DistNumber=DecodeNumber(Inp,&BlockTables.DD);
uint Distance=DDecode[DistNumber]+1;
if ((Bits=DBits[DistNumber])>0)
{
if (DistNumber>9)
Expand All @@ -166,7 +166,7 @@ void Unpack::Unpack29(bool Solid)
}
else
{
int LowDist=DecodeNumber(Inp,&BlockTables.LDD);
uint LowDist=DecodeNumber(Inp,&BlockTables.LDD);
if (LowDist==16)
{
LowDistRepCount=LOW_DIST_REP_COUNT-1;
Expand All @@ -189,7 +189,7 @@ void Unpack::Unpack29(bool Solid)
if (Distance>=0x2000)
{
Length++;
if (Distance>=0x40000L)
if (Distance>=0x40000)
Length++;
}

Expand Down Expand Up @@ -218,13 +218,13 @@ void Unpack::Unpack29(bool Solid)
}
if (Number<263)
{
int DistNum=Number-259;
unsigned int Distance=OldDist[DistNum];
for (int I=DistNum;I>0;I--)
uint DistNum=Number-259;
uint Distance=OldDist[DistNum];
for (uint I=DistNum;I>0;I--)
OldDist[I]=OldDist[I-1];
OldDist[0]=Distance;

int LengthNumber=DecodeNumber(Inp,&BlockTables.RD);
uint LengthNumber=DecodeNumber(Inp,&BlockTables.RD);
int Length=LDecode[LengthNumber]+2;
if ((Bits=LBits[LengthNumber])>0)
{
Expand All @@ -237,7 +237,7 @@ void Unpack::Unpack29(bool Solid)
}
if (Number<272)
{
unsigned int Distance=SDDecode[Number-=263]+1;
uint Distance=SDDecode[Number-=263]+1;
if ((Bits=SDBits[Number])>0)
{
Distance+=Inp.getbits()>>(16-Bits);
Expand Down Expand Up @@ -274,11 +274,11 @@ bool Unpack::ReadEndOfBlock()
NewTable=(BitField & 0x4000)!=0;
Inp.addbits(2);
}
TablesRead=!NewTable;
TablesRead3=!NewTable;

// Quit immediately if "new file" flag is set. If "new table" flag
// is present, we'll read the table in beginning of next file
// based on 'TablesRead' 'false' value.
// based on 'TablesRead3' 'false' value.
if (NewFile)
return false;
return ReadTables30(); // Quit only if we failed to read tables.
Expand All @@ -290,9 +290,9 @@ bool Unpack::ReadVMCode()
// Entire VM code is guaranteed to fully present in block defined
// by current Huffman table. Compressor checks that VM code does not cross
// Huffman block boundaries.
unsigned int FirstByte=Inp.getbits()>>8;
uint FirstByte=Inp.getbits()>>8;
Inp.addbits(8);
int Length=(FirstByte & 7)+1;
uint Length=(FirstByte & 7)+1;
if (Length==7)
{
Length=(Inp.getbits()>>8)+7;
Expand All @@ -304,8 +304,10 @@ bool Unpack::ReadVMCode()
Length=Inp.getbits();
Inp.addbits(16);
}
if (Length==0)
return false;
Array<byte> VMCode(Length);
for (int I=0;I<Length;I++)
for (uint I=0;I<Length;I++)
{
// Try to read the new buffer if only one byte is left.
// But if we read all bytes except the last, one byte is enough.
Expand All @@ -320,15 +322,15 @@ bool Unpack::ReadVMCode()

bool Unpack::ReadVMCodePPM()
{
unsigned int FirstByte=SafePPMDecodeChar();
uint FirstByte=SafePPMDecodeChar();
if ((int)FirstByte==-1)
return false;
int Length=(FirstByte & 7)+1;
uint Length=(FirstByte & 7)+1;
if (Length==7)
{
int B1=SafePPMDecodeChar();
if (B1==-1)
return(false);
return false;
Length=B1+7;
}
else
Expand All @@ -342,12 +344,14 @@ bool Unpack::ReadVMCodePPM()
return false;
Length=B1*256+B2;
}
if (Length==0)
return false;
Array<byte> VMCode(Length);
for (int I=0;I<Length;I++)
for (uint I=0;I<Length;I++)
{
int Ch=SafePPMDecodeChar();
if (Ch==-1)
return(false);
return false;
VMCode[I]=Ch;
}
return AddVMCode(FirstByte,&VMCode[0],Length);
Expand Down Expand Up @@ -405,7 +409,7 @@ bool Unpack::AddVMCode(uint FirstByte,byte *Code,int CodeSize)
StackFilter->ParentFilter=FiltPos;
}

int EmptyCount=0;
uint EmptyCount=0;
for (uint I=0;I<PrgStack.Size();I++)
{
PrgStack[I-EmptyCount]=PrgStack[I];
Expand All @@ -424,7 +428,7 @@ bool Unpack::AddVMCode(uint FirstByte,byte *Code,int CodeSize)
PrgStack.Add(1);
EmptyCount=1;
}
int StackPos=(int)(PrgStack.Size()-EmptyCount);
size_t StackPos=PrgStack.Size()-EmptyCount;
PrgStack[StackPos]=StackFilter;

uint BlockStart=RarVM::ReadData(VMCodeInp);
Expand Down Expand Up @@ -458,7 +462,7 @@ bool Unpack::AddVMCode(uint FirstByte,byte *Code,int CodeSize)
{
uint InitMask=VMCodeInp.fgetbits()>>9;
VMCodeInp.faddbits(7);
for (int I=0;I<7;I++)
for (uint I=0;I<7;I++)
if (InitMask & (1<<I))
StackFilter->Prg.InitR[I]=RarVM::ReadData(VMCodeInp);
}
Expand Down Expand Up @@ -644,13 +648,13 @@ bool Unpack::ReadTables30()
memset(UnpOldTable,0,sizeof(UnpOldTable));
Inp.faddbits(2);

for (int I=0;I<BC;I++)
for (uint I=0;I<BC;I++)
{
int Length=(byte)(Inp.fgetbits() >> 12);
uint Length=(byte)(Inp.fgetbits() >> 12);
Inp.faddbits(4);
if (Length==15)
{
int ZeroCount=(byte)(Inp.fgetbits() >> 12);
uint ZeroCount=(byte)(Inp.fgetbits() >> 12);
Inp.faddbits(4);
if (ZeroCount==0)
BitLength[I]=15;
Expand All @@ -667,13 +671,13 @@ bool Unpack::ReadTables30()
}
MakeDecodeTables(BitLength,&BlockTables.BD,BC30);

const int TableSize=HUFF_TABLE_SIZE30;
for (int I=0;I<TableSize;)
const uint TableSize=HUFF_TABLE_SIZE30;
for (uint I=0;I<TableSize;)
{
if (Inp.InAddr>ReadTop-5)
if (!UnpReadBuf30())
return(false);
int Number=DecodeNumber(Inp,&BlockTables.BD);
uint Number=DecodeNumber(Inp,&BlockTables.BD);
if (Number<16)
{
Table[I]=(Number+UnpOldTable[I]) & 0xf;
Expand All @@ -682,7 +686,7 @@ bool Unpack::ReadTables30()
else
if (Number<18)
{
int N;
uint N;
if (Number==16)
{
N=(Inp.fgetbits() >> 13)+3;
Expand All @@ -693,7 +697,9 @@ bool Unpack::ReadTables30()
N=(Inp.fgetbits() >> 9)+11;
Inp.faddbits(7);
}
if (I>0)
if (I==0)
return false; // We cannot have "repeat previous" code at the first position.
else
while (N-- > 0 && I<TableSize)
{
Table[I]=Table[I-1];
Expand All @@ -702,7 +708,7 @@ bool Unpack::ReadTables30()
}
else
{
int N;
uint N;
if (Number==18)
{
N=(Inp.fgetbits() >> 13)+3;
Expand All @@ -717,7 +723,7 @@ bool Unpack::ReadTables30()
Table[I++]=0;
}
}
TablesRead=true;
TablesRead3=true;
if (Inp.InAddr>ReadTop)
return false;
MakeDecodeTables(&Table[0],&BlockTables.LD,NC30);
Expand All @@ -733,7 +739,7 @@ void Unpack::UnpInitData30(bool Solid)
{
if (!Solid)
{
TablesRead=false;
TablesRead3=false;
memset(UnpOldTable,0,sizeof(UnpOldTable));
PPMEscChar=2;
UnpBlockType=BLOCK_LZ;
Expand Down
42 changes: 32 additions & 10 deletions unpack50.cpp
Expand Up @@ -7,7 +7,12 @@ void Unpack::Unpack5(bool Solid)
UnpInitData(Solid);
if (!UnpReadBuf())
return;
if (!ReadBlockHeader(Inp,BlockHeader) || !ReadTables(Inp,BlockHeader,BlockTables))

// 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)
return;
}

Expand Down Expand Up @@ -516,6 +521,13 @@ void Unpack::UnpWriteData(byte *Data,size_t Size)
}


void Unpack::UnpInitData50(bool Solid)
{
if (!Solid)
TablesRead5=false;
}


bool Unpack::ReadBlockHeader(BitInput &Inp,UnpackBlockHeader &Header)
{
Header.HeaderSize=0;
Expand Down Expand Up @@ -570,13 +582,13 @@ bool Unpack::ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTable
return false;

byte BitLength[BC];
for (int I=0;I<BC;I++)
for (uint I=0;I<BC;I++)
{
int Length=(byte)(Inp.fgetbits() >> 12);
uint Length=(byte)(Inp.fgetbits() >> 12);
Inp.faddbits(4);
if (Length==15)
{
int ZeroCount=(byte)(Inp.fgetbits() >> 12);
uint ZeroCount=(byte)(Inp.fgetbits() >> 12);
Inp.faddbits(4);
if (ZeroCount==0)
BitLength[I]=15;
Expand All @@ -595,13 +607,13 @@ bool Unpack::ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTable
MakeDecodeTables(BitLength,&Tables.BD,BC);

byte Table[HUFF_TABLE_SIZE];
const int TableSize=HUFF_TABLE_SIZE;
for (int I=0;I<TableSize;)
const uint TableSize=HUFF_TABLE_SIZE;
for (uint I=0;I<TableSize;)
{
if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop-5)
if (!UnpReadBuf())
return false;
int Number=DecodeNumber(Inp,&Tables.BD);
uint Number=DecodeNumber(Inp,&Tables.BD);
if (Number<16)
{
Table[I]=Number;
Expand All @@ -610,7 +622,7 @@ bool Unpack::ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTable
else
if (Number<18)
{
int N;
uint N;
if (Number==16)
{
N=(Inp.fgetbits() >> 13)+3;
Expand All @@ -621,7 +633,16 @@ bool Unpack::ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTable
N=(Inp.fgetbits() >> 9)+11;
Inp.faddbits(7);
}
if (I>0)
if (I==0)
{
// We cannot have "repeat previous" code at the first position.
// Multiple such codes would shift Inp position without changing I,
// which can lead to reading beyond of Inp boundary in mutithreading
// mode, where Inp.ExternalBuffer disables bounds check and we just
// reserve a lot of buffer space to not need such check normally.
return false;
}
else
while (N-- > 0 && I<TableSize)
{
Table[I]=Table[I-1];
Expand All @@ -630,7 +651,7 @@ bool Unpack::ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTable
}
else
{
int N;
uint N;
if (Number==18)
{
N=(Inp.fgetbits() >> 13)+3;
Expand All @@ -645,6 +666,7 @@ bool Unpack::ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTable
Table[I++]=0;
}
}
TablesRead5=true;
if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop)
return false;
MakeDecodeTables(&Table[0],&Tables.LD,NC);
Expand Down
4 changes: 3 additions & 1 deletion unpack50mt.cpp
Expand Up @@ -133,11 +133,13 @@ void Unpack::Unpack5MT(bool Solid)
if (!CurData->HeaderRead)
{
CurData->HeaderRead=true;
if (!ReadBlockHeader(CurData->Inp,CurData->BlockHeader))
if (!ReadBlockHeader(CurData->Inp,CurData->BlockHeader) ||
!CurData->BlockHeader.TablePresent && !TablesRead5)
{
Done=true;
break;
}
TablesRead5=true;
}

// To prevent too high memory use we switch to single threaded mode
Expand Down
2 changes: 1 addition & 1 deletion unpackinline.cpp
Expand Up @@ -120,7 +120,7 @@ _forceinline uint Unpack::DecodeNumber(BitInput &Inp,DecodeTable *Dec)

// Convert the position in the code list to position in alphabet
// and return it.
return(Dec->DecodeNum[Pos]);
return Dec->DecodeNum[Pos];
}


Expand Down
4 changes: 2 additions & 2 deletions version.hpp
@@ -1,6 +1,6 @@
#define RARVER_MAJOR 5
#define RARVER_MINOR 50
#define RARVER_BETA 5
#define RARVER_DAY 2
#define RARVER_BETA 6
#define RARVER_DAY 25
#define RARVER_MONTH 7
#define RARVER_YEAR 2017