void OldUnpack(UBYTE *UnpAddr,int Solid); void ShortLZ(void); void LongLZ(void); void HuffDecode(void); void GetFlagsBuf(void); void OldUnpInitData(int Solid); void InitHuff(void); void CorrHuff(unsigned int *CharSet,unsigned int *NumToPlace); void OldCopyString(unsigned int Distance,unsigned int Length); unsigned int DecodeNum(int Num,unsigned int StartPos,unsigned int *DecTab, unsigned int *PosTab); unsigned int FlagBuf; int LCount; int FlagsCnt; unsigned int ChSet[256]; unsigned int Place[256]; unsigned int NToPl[256]; unsigned int ChSetA[256]; unsigned int PlaceA[256]; unsigned int ChSetB[256]; unsigned int PlaceB[256]; unsigned int NToPlB[256]; unsigned int ChSetC[256]; unsigned int PlaceC[256]; unsigned int NToPlC[256]; unsigned int AvrPlc; unsigned int AvrPlcB; unsigned int AvrLn1; unsigned int AvrLn2; unsigned int AvrLn3; int NumHuf; int StMode; unsigned int Nhfb,Nlzb; unsigned int MaxDist3; int Buf60; static unsigned int ShortLen1[]={1,3,4,4,5,6,7,8,8,4,4,5,6,6,4,0}; static unsigned int ShortXor1[]={0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe, 0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0}; static unsigned int ShortLen2[]={2,3,3,3,4,4,5,6,6,4,4,5,6,6,4,0}; static unsigned int ShortXor2[]={0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8, 0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0}; #define STARTL1 2 static unsigned int DecL1[]={0x8000,0xa000,0xc000,0xd000,0xe000,0xea00, 0xee00,0xf000,0xf200,0xf200,0xffff}; static unsigned int PosL1[]={0,0,0,2,3,5,7,11,16,20,24,32,32}; #define STARTL2 3 static unsigned int DecL2[]={0xa000,0xc000,0xd000,0xe000,0xea00,0xee00, 0xf000,0xf200,0xf240,0xffff}; static unsigned int PosL2[]={0,0,0,0,5,7,9,13,18,22,26,34,36}; #define STARTHF0 4 static unsigned int DecHf0[]={0x8000,0xc000,0xe000,0xf200,0xf200,0xf200, 0xf200,0xf200,0xffff}; static unsigned int PosHf0[]={0,0,0,0,0,8,16,24,33,33,33,33,33}; #define STARTHF1 5 static unsigned int DecHf1[]={0x2000,0xc000,0xe000,0xf000,0xf200,0xf200, 0xf7e0,0xffff}; static unsigned int PosHf1[]={0,0,0,0,0,0,4,44,60,76,80,80,127}; #define STARTHF2 5 static unsigned int DecHf2[]={0x1000,0x2400,0x8000,0xc000,0xfa00,0xffff, 0xffff,0xffff}; static unsigned int PosHf2[]={0,0,0,0,0,0,2,7,53,117,233,0,0}; #define STARTHF3 6 static unsigned int DecHf3[]={0x800,0x2400,0xee00,0xfe80,0xffff,0xffff, 0xffff}; static unsigned int PosHf3[]={0,0,0,0,0,0,0,2,16,218,251,0,0}; #define STARTHF4 8 static unsigned int DecHf4[]={0xff00,0xffff,0xffff,0xffff,0xffff,0xffff}; static unsigned int PosHf4[]={0,0,0,0,0,0,0,0,0,255,0,0,0}; void OldUnpack(UBYTE *UnpAddr,int Solid) { int SetStMode; UnpBuf=UnpAddr; if (Solid==0x1000) { Solid=0; SetStMode=1; } else SetStMode=0; if (Suspend) UnpPtr=WrPtr; else { UnpInitData(Solid); OldUnpInitData(Solid); UnpReadBuf(1); if (!Solid) { InitHuff(); UnpPtr=0; } else UnpPtr=WrPtr; DestUnpSize--; } if (SetStMode) StMode=1; else if (DestUnpSize>=0) { GetFlagsBuf(); FlagsCnt=8; } while (DestUnpSize>=0) { UnpPtr&=MAXWINMASK; if (InAddr>sizeof(InBuf)-30) UnpReadBuf(0); if (((WrPtr-UnpPtr) & MAXWINMASK)<270 && WrPtr!=UnpPtr) { UnpWriteBuf(); if (Suspend) return; } if (StMode) { HuffDecode(); continue; } if (--FlagsCnt < 0) { GetFlagsBuf(); FlagsCnt=7; } if (FlagBuf & 0x80) { FlagBuf<<=1; if (Nlzb > Nhfb) LongLZ(); else HuffDecode(); } else { FlagBuf<<=1; if (--FlagsCnt < 0) { GetFlagsBuf(); FlagsCnt=7; } if (FlagBuf & 0x80) { FlagBuf<<=1; if (Nlzb > Nhfb) HuffDecode(); else LongLZ(); } else { FlagBuf<<=1; ShortLZ(); } } } UnpWriteBuf(); } void ShortLZ(void) { unsigned int Length,SaveLength; unsigned int LastDistance; unsigned int Distance; int DistancePlace; NumHuf=0; GetBits(); if (LCount==2) { AddBits(1); if (BitField >= 0x8000) { OldCopyString((unsigned int)LastDist,LastLength); return; } BitField <<= 1; LCount=0; } BitField>>=8; ShortLen1[1]=ShortLen2[3]=Buf60+3; if (AvrLn1<37) { for (Length=0;;Length++) if (((BitField^ShortXor1[Length]) & (~(0xff>>ShortLen1[Length])))==0) break; AddBits(ShortLen1[Length]); } else { for (Length=0;;Length++) if (((BitField^ShortXor2[Length]) & (~(0xff>>ShortLen2[Length])))==0) break; AddBits(ShortLen2[Length]); } if (Length >= 9) { if (Length == 9) { LCount++; OldCopyString((unsigned int)LastDist,LastLength); return; } if (Length == 14) { LCount=0; GetBits(); Length=DecodeNum(BitField,STARTL2,DecL2,PosL2)+5; GetBits(); Distance=(BitField>>1) | 0x8000; AddBits(15); LastLength=Length; LastDist=Distance; OldCopyString(Distance,Length); return; } LCount=0; SaveLength=Length; Distance=OldDist[(OldDistPtr-(Length-9)) & 3]; GetBits(); Length=DecodeNum(BitField,STARTL1,DecL1,PosL1)+2; if (Length==0x101 && SaveLength==10) { Buf60 ^= 1; return; } if (Distance > 256) Length++; if (Distance >= MaxDist3) Length++; OldDist[OldDistPtr++]=Distance; OldDistPtr = OldDistPtr & 3; LastLength=Length; LastDist=Distance; OldCopyString(Distance,Length); return; } LCount=0; AvrLn1 += Length; AvrLn1 -= AvrLn1 >> 4; GetBits(); DistancePlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2); Distance=ChSetA[DistancePlace]; if (--DistancePlace != -1) { PlaceA[Distance]--; LastDistance=ChSetA[DistancePlace]; PlaceA[LastDistance]++; ChSetA[DistancePlace+1]=LastDistance; ChSetA[DistancePlace]=Distance; } Length+=2; OldDist[OldDistPtr++] = ++Distance; OldDistPtr = OldDistPtr & 3; LastLength=Length; LastDist=Distance; OldCopyString(Distance,Length); return; } void LongLZ(void) { unsigned int Length; unsigned int Distance; unsigned int DistancePlace,NewDistancePlace; unsigned int OldAvr2,OldAvr3; NumHuf=0; Nlzb+=16; if (Nlzb > 0xff) { Nlzb=0x90; Nhfb >>= 1; } OldAvr2=AvrLn2; GetBits(); if (AvrLn2 >= 122) Length=DecodeNum(BitField,STARTL2,DecL2,PosL2); else if (AvrLn2 >= 64) Length=DecodeNum(BitField,STARTL1,DecL1,PosL1); else if (BitField < 0x100) { Length=BitField; AddBits(16); } else { for (Length=0;((BitField<> 5; GetBits(); if (AvrPlcB > 0x28ff) DistancePlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2); else if (AvrPlcB > 0x6ff) DistancePlace=DecodeNum(BitField,STARTHF1,DecHf1,PosHf1); else DistancePlace=DecodeNum(BitField,STARTHF0,DecHf0,PosHf0); AvrPlcB += DistancePlace; AvrPlcB -= AvrPlcB >> 8; while (1) { Distance = ChSetB[DistancePlace]; NewDistancePlace = NToPlB[Distance++ & 0xff]++; if (!(Distance & 0xff)) CorrHuff(ChSetB,NToPlB); else break; } ChSetB[DistancePlace]=ChSetB[NewDistancePlace]; ChSetB[NewDistancePlace]=Distance; GetBits(); Distance=((UWORD)((Distance & 0xff00) | (BitField >> 8))) >> 1; AddBits(7); OldAvr3=AvrLn3; if (Length!=1 && Length!=4) if (Length==0 && Distance <= MaxDist3) { AvrLn3++; AvrLn3 -= AvrLn3 >> 8; } else if (AvrLn3 > 0) AvrLn3--; Length+=3; if (Distance >= MaxDist3) Length++; if (Distance <= 256) Length+=8; if (OldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && OldAvr2 < 0x40) MaxDist3=0x7f00; else MaxDist3=0x2001; OldDist[OldDistPtr++]=Distance; OldDistPtr = OldDistPtr & 3; LastLength=Length; LastDist=Distance; OldCopyString(Distance,Length); } void HuffDecode(void) { unsigned int CurByte,NewBytePlace; unsigned int Length; unsigned int Distance; int BytePlace; GetBits(); if (AvrPlc > 0x75ff) BytePlace=DecodeNum(BitField,STARTHF4,DecHf4,PosHf4); else if (AvrPlc > 0x5dff) BytePlace=DecodeNum(BitField,STARTHF3,DecHf3,PosHf3); else if (AvrPlc > 0x35ff) BytePlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2); else if (AvrPlc > 0x0dff) BytePlace=DecodeNum(BitField,STARTHF1,DecHf1,PosHf1); else BytePlace=DecodeNum(BitField,STARTHF0,DecHf0,PosHf0); if (StMode) { if (BytePlace==0 && BitField > 0xfff) BytePlace=0x100; if (--BytePlace==-1) { GetBits(); AddBits(1); if (BitField & 0x8000) { NumHuf=StMode=0; return; } else { Length = (BitField & 0x4000) ? 4 : 3; AddBits(1); GetBits(); Distance=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2); GetBits(); Distance = (Distance << 5) | (BitField >> 11); AddBits(5); OldCopyString(Distance,Length); return; } } } else if (NumHuf++ >= 16 && FlagsCnt==0) StMode=1; AvrPlc += BytePlace; AvrPlc -= AvrPlc >> 8; Nhfb+=16; if (Nhfb > 0xff) { Nhfb=0x90; Nlzb >>= 1; } UnpBuf[UnpPtr++]=(UBYTE)(ChSet[BytePlace]>>8); DestUnpSize--; while (1) { CurByte=ChSet[BytePlace]; NewBytePlace=NToPl[CurByte++ & 0xff]++; if ((CurByte & 0xff) > 0xa1) CorrHuff(ChSet,NToPl); else break; } ChSet[BytePlace]=ChSet[NewBytePlace]; ChSet[NewBytePlace]=CurByte; } void GetFlagsBuf(void) { unsigned int Flags,FlagsPlace,NewFlagsPlace; GetBits(); FlagsPlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2); while (1) { Flags=ChSetC[FlagsPlace]; FlagBuf=Flags>>8; NewFlagsPlace=NToPlC[Flags++ & 0xff]++; if ((Flags & 0xff) == 0) CorrHuff(ChSetC,NToPlC); else break; } ChSetC[FlagsPlace]=ChSetC[NewFlagsPlace]; ChSetC[NewFlagsPlace]=Flags; } void OldUnpInitData(int Solid) { if (!Solid) { AvrPlcB=AvrLn1=AvrLn2=AvrLn3=NumHuf=Buf60=0; AvrPlc=0x3500; MaxDist3=0x2001; Nhfb=Nlzb=0x80; } FlagsCnt=0; FlagBuf=0; StMode=0; LCount=0; } void InitHuff(void) { unsigned int I; for (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); } void CorrHuff(unsigned int *CharSet,unsigned int *NumToPlace) { int I,J; for (I=7;I>=0;I--) for (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 OldCopyString(unsigned int Distance,unsigned int Length) { DestUnpSize-=Length; while (Length--) { UnpBuf[UnpPtr]=UnpBuf[(UnpPtr-Distance) & MAXWINMASK]; UnpPtr=(UnpPtr+1) & MAXWINMASK; } } unsigned int DecodeNum(int Num,unsigned int StartPos,unsigned int *DecTab, unsigned int *PosTab) { int I; for (Num&=0xfff0,I=0;DecTab[I]<=Num;I++) StartPos++; AddBits(StartPos); return(((Num-(I ? DecTab[I-1]:0))>>(16-StartPos))+PosTab[StartPos]); }