📄 unpack.c
字号:
}
Length+=2;
D->OldDist[D->OldDistNum++] = ++Distance;
D->OldDistNum = D->OldDistNum & 3;
D->LastLen=Length;
D->LastDist=Distance;
CopyString(Distance,Length);
return;
}
void LongLZ()
{
UWORD LengthCode,Length;
UWORD Distance,DistancePlace,NewDistancePlace;
UWORD oldav2,oldav3;
D->NumHuf=0;
D->Nlzb+=16;
if (D->Nlzb > 0xff)
{
D->Nlzb=0x90;
D->Nhfb >>= 1;
}
oldav2=D->AvrLn2;
if (D->AvrLn2 >= 122)
{
Length=T->ECDLN2[GetField() >> 4];
AddBit(T->NCDLN2[Length]);
}
else
if (D->AvrLn2 >= 64)
{
Length=T->ECDLN1[GetField() >> 4];
AddBit(T->NCDLN1[Length]);
}
else
{
LengthCode=GetField();
if (LengthCode < 0x100)
{
Length=LengthCode;
AddBit(16);
}
else
{
Length=T->ECDLN0[LengthCode >> 8];
AddBit(T->NCDLN0[Length]);
}
}
D->AvrLn2 += Length;
D->AvrLn2 -= D->AvrLn2 >> 5;
if (D->AvrPlcB > 0x28ff)
{
DistancePlace=T->ECODE2[GetField() >> 6];
AddBit(T->NCODE2[DistancePlace]);
}
else
if (D->AvrPlcB > 0x6ff)
{
DistancePlace=T->ECODE1[GetField() >> 4];
AddBit(T->NCODE1[DistancePlace]);
}
else
{
DistancePlace=T->ECODE0[GetField() >> 4];
AddBit(T->NCODE0[DistancePlace]);
}
D->AvrPlcB += DistancePlace;
D->AvrPlcB -= D->AvrPlcB >> 8;
while (1)
{
Distance = D->ChSetB[DistancePlace];
NewDistancePlace = D->NToPlB[Distance++ & 0xff]++;
if (!(Distance & 0xff))
{
Distance-=0x100;
CorrHuff(D->ChSetB,D->NToPlB);
}
else
break;
}
D->ChSetB[DistancePlace]=D->ChSetB[NewDistancePlace];
D->ChSetB[NewDistancePlace]=Distance;
Distance=((UWORD)((Distance & ~0xff) | (GetField() >> 8))) >> 1;
AddBit(7);
oldav3=D->AvrLn3;
if (Length!=1 && Length!=4)
if (Length==0 && Distance <= D->MaxDist3)
{
D->AvrLn3++;
D->AvrLn3 -= D->AvrLn3 >> 8;
}
else
if (D->AvrLn3 > 0)
D->AvrLn3--;
Length+=3;
if (Distance >= D->MaxDist3)
Length++;
if (Distance <= 256)
Length+=8;
if (oldav3 > 0xb0 || D->AvrPlc >= 0x2a00 && oldav2 < 0x40)
D->MaxDist3=0x7f00;
else
D->MaxDist3=0x2001;
D->OldDist[D->OldDistNum++]=Distance;
D->OldDistNum = D->OldDistNum & 3;
D->LastLen=Length;
D->LastDist=Distance;
CopyString(Distance,Length);
}
void HuffDecode()
{
UWORD CurByte,BytePlace,NewBytePlace;
UWORD Length,Distance,Code;
Code=GetField();
if (D->AvrPlc > 0x75ff)
{
BytePlace=T->ECODE4[Code>>6];
if (D->StMode && BytePlace==0 && Code > 0xfff)
BytePlace=0x100;
AddBit(T->NCODE4[BytePlace]);
}
else
if (D->AvrPlc > 0x5dff)
{
BytePlace=T->ECODE3[Code>>6];
if (D->StMode && BytePlace==0 && Code > 0xfff)
BytePlace=0x100;
AddBit(T->NCODE3[BytePlace]);
}
else
if (D->AvrPlc > 0x35ff)
{
BytePlace=T->ECODE2[Code>>6];
if (D->StMode && BytePlace==0 && Code > 0xfff)
BytePlace=0x100;
AddBit(T->NCODE2[BytePlace]);
}
else
if (D->AvrPlc > 0x0dff)
{
BytePlace=T->ECODE1[Code>>4];
if (D->StMode && BytePlace==0 && Code > 0xfff)
BytePlace=0x100;
AddBit(T->NCODE1[BytePlace]);
}
else
{
BytePlace=T->ECODE0[Code>>4];
if (D->StMode && BytePlace==0 && Code > 0xfff)
BytePlace=0x100;
AddBit(T->NCODE0[BytePlace]);
}
if (D->StMode)
{
if (--BytePlace==0xFFFF)
{
Code=GetField();
AddBit(1);
if (Code >= 0x8000)
{
D->NumHuf=D->StMode=0;
return;
}
else
{
Length = (Code & 0x4000) ? 4 : 3;
Distance= T->ECODE2[(Code >> 4) & 0x3ff];
AddBit(T->NCODE2[Distance]+1);
Distance = (Distance << 5) | (GetField() >> 11);
AddBit(5);
CopyString(Distance,Length);
return;
}
}
}
else
if (D->NumHuf++ >= 16 && FlagsCnt==0)
D->StMode=1;
D->AvrPlc += BytePlace;
D->AvrPlc -= D->AvrPlc >> 8;
D->Nhfb+=16;
if (D->Nhfb > 0xff)
{
D->Nhfb=0x90;
D->Nlzb >>= 1;
}
UnpBuf[OutAdr++]=(UBYTE)(D->ChSet[BytePlace]>>8);
DestUnpSize--;
while (1)
{
CurByte=D->ChSet[BytePlace];
NewBytePlace=D->NToPl[CurByte++ & 0xff]++;
if ((CurByte & 0xff) > 0xa1)
CorrHuff(D->ChSet,D->NToPl);
else
break;
}
D->ChSet[BytePlace]=D->ChSet[NewBytePlace];
D->ChSet[NewBytePlace]=CurByte;
}
int UnpWriteBuf()
{
if (OutAdr<D->WrAddr)
{
if (UnpWriteFn((UBYTE *)(UnpBuf+D->WrAddr),(UWORD)-D->WrAddr)==-1 ||
UnpWriteFn((UBYTE *)UnpBuf,(UWORD)OutAdr)==-1)
return(-1);
}
else
if (UnpWriteFn((UBYTE *)(UnpBuf+D->WrAddr),(UWORD)(OutAdr-D->WrAddr))==-1)
return(-1);
D->WrAddr=OutAdr;
return(0);
}
int UnpReadBuf(NumBuf)
int NumBuf;
{
int ReadCode;
if (NumBuf==FIRST)
ReadCode=UnpReadFn(PackBuf,SIZE_PBUF);
else
{
memcpy(PackBuf,PackBuf+InAdr,(UWORD)(SIZE_PBUF-InAdr));
ReadCode=UnpReadFn(PackBuf+SIZE_PBUF-InAdr,(UWORD)InAdr);
}
InAdr=0;
if (ReadCode==-1)
return(-1);
return(0);
}
void GetFlagsBuf()
{
UWORD Flags,FlagsPlace,NewFlagsPlace;
FlagsPlace=T->ECODE2[GetField() >> 6];
AddBit(T->NCODE2[FlagsPlace]);
while (1)
{
Flags=D->ChSetC[FlagsPlace];
FlagBuf=(UBYTE)(Flags >> 8);
NewFlagsPlace=D->NToPlC[Flags++ & 0xff]++;
if ((Flags & 0xff) == 0)
{
Flags-=0x100;
CorrHuff(D->ChSetC,D->NToPlC);
}
else
break;
}
D->ChSetC[FlagsPlace]=D->ChSetC[NewFlagsPlace];
D->ChSetC[NewFlagsPlace]=Flags;
}
void UnpInitData(Solid)
int Solid;
{
if (!Solid)
{
memset(D,0,sizeof(struct UnpData));
D->AvrPlc=0x3500;
D->MaxDist3=0x2001;
D->Nhfb=D->Nlzb=0x80;
}
FlagsCnt=0;
FlagBuf=0;
InAdr=0;
NumBit=0;
D->StMode=0;
LCount=0;
}
void InitHuff()
{
UWORD I;
for (I=0;I<256;I++)
{
D->Place[I]=D->PlaceA[I]=D->PlaceB[I]=(UBYTE)I;
D->PlaceC[I]=(UBYTE)(~I+1);
D->ChSet[I]=D->ChSetB[I]=I<<8;
D->ChSetA[I]=(UBYTE)I;
D->ChSetC[I]=(~I+1)<<8;
}
memset(D->NToPl,0,sizeof(D->NToPl));
memset(D->NToPlB,0,sizeof(D->NToPlB));
memset(D->NToPlC,0,sizeof(D->NToPlC));
CorrHuff(D->ChSetB,D->NToPlB);
}
void CorrHuff(CharSet,NumToPlace)
UWORD *CharSet;
UBYTE *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(D->NToPl));
for (I=6;I>=0;I--)
NumToPlace[I]=(7-I)*32;
}
void CreateEncTbl(UnpMem)
HPBYTE UnpMem;
{
T=(struct DecodeTables *)(UnpMem+0x10000L+sizeof(struct UnpData));
CreateOneTbl(hcdsh1,T->ECDSH1,T->NCDSH1,8);
CreateOneTbl(hcdsh2,T->ECDSH2,T->NCDSH2,8);
CreateOneTbl(hcdsh3,T->ECDSH3,T->NCDSH3,8);
CreateOneTbl(hcdsh4,T->ECDSH4,T->NCDSH4,8);
CreateOneTbl(hcdln0,T->ECDLN0,T->NCDLN0,8);
CreateOneTbl(hcdln1,T->ECDLN1,T->NCDLN1,4);
CreateOneTbl(hcdln2,T->ECDLN2,T->NCDLN2,4);
CreateOneTbl(hcode0,T->ECODE0,T->NCODE0,4);
CreateOneTbl(hcode1,T->ECODE1,T->NCODE1,4);
CreateOneTbl(hcode2,T->ECODE2,T->NCODE2,6);
CreateOneTbl(hcode3,T->ECODE3,T->NCODE3,6);
CreateOneTbl(hcode4,T->ECODE4,T->NCODE4,6);
}
void CreateOneTbl(hcd,ecd,ncd,ShiftCount)
UWORD *hcd;
UBYTE *ecd;
UBYTE *ncd;
UBYTE ShiftCount;
{
UWORD I,MaxCode,Code;
for (I=0; hcd[I]; I++)
{
ncd[I]=(UBYTE)(hcd[I] & 0xf);
Code=hcd[I] >> ShiftCount;
MaxCode=1 << (16-ShiftCount-(UBYTE)(hcd[I] & 0xf));
while (MaxCode--)
ecd[Code++]=(UBYTE)I;
}
}
void MakeTbl()
{
UWORD I,J,K,Code;
UWORD *OutTab;
for (I=0;I<sizeof(MakeTab)/sizeof(MakeTab[0]);I++)
{
OutTab=MakeTab[I].Table;
for (Code=J=0;J<12;J++)
for (Code<<=1,K=0;K<MakeTab[I].HuffCodeCount[J];K++)
*(OutTab++)=(Code++ << (4+11-J)) | (J + 1);
*OutTab=0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -