📄 unpack.c
字号:
/****** ***** ******
** ** ** ** ** ** unRAR utility version 1.01
****** ******* ****** ~~~~~~~~~~~~~~~~~~~~~~~~~~~
** ** ** ** ** ** FREE portable version
** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~
Unpacking algorithm procedures
YOU DO NOT NEED TO CHANGE THERE ANYTHING.
*/
void MakeTbl(); /* Makes Huffman table */
void AddBit(); /* Shift buffer pointer to NBits */
void CopyString(); /* string copy */
void ShortLZ(); /* unpacks short, near and special LZ codes */
void LongLZ(); /* unpacks long and far LZ codes */
void HuffDecode(); /* Huffman decoding */
int UnpWriteBuf(); /* writes output buffer */
int UnpReadBuf(); /* reads output buffer */
void GetFlagsBuf(); /* gets flag byte */
void UnpInitData(); /* reset initial data */
void InitHuff(); /* initializing Huffman tables */
void CorrHuff(); /* Huffman table correction in case of overflow */
void CreateEncTbl(); /* create decoding tables */
void CreateOneTbl(); /* subfunction of previous */
int unpack(); /* unpacking procedure itself */
#define SUSPEND 1
#define SIZE_PBUF 0x2000
#define FIRST 1
#define NEXT 2
#define UNP_MEMORY 0x10010L+sizeof(struct UnpData)+ \
sizeof(struct DecodeTables)+SIZE_PBUF
UWORD hcdsh1[]={ 0x0001,0xa003,0xd004,0xe004,0xf005,0xf806,0xfc07,0xfe08,
0xff08,0xc004,0x8004,0x9005,0x9806,0x9c06,0 };
UWORD hcdsh2[]={ 0x0002,0x4003,0x6003,0xa003,0xd004,0xe004,0xf005,0xf806,
0xfc06,0xc004,0x8004,0x9005,0x9806,0x9c06,0 };
UWORD hcdsh3[]={ 0x0001,0xa004,0xd004,0xe004,0xf005,0xf806,0xfc07,0xfe08,
0xff08,0xc004,0x8004,0x9005,0x9806,0x9c06,0xb004,0 };
UWORD hcdsh4[]={ 0x0002,0x4003,0x6003,0xa004,0xd004,0xe004,0xf005,0xf806,
0xfc06,0xc004,0x8004,0x9005,0x9806,0x9c06,0xb004,0 };
UWORD hcdln0[]={ 0x8001,0x4002,0x2003,0x1004,0x0805,0x0406,0x0207,0x0108,
0x0008,0 };
UWORD hcdln1[258],hcdln2[258];
UWORD hcode0[258],hcode1[258],hcode2[258],hcode3[258],hcode4[258];
struct MakeHuffTabs
{
UWORD *Table;
UBYTE HuffCodeCount[12];
} MakeTab[]={
{hcdln1,{0 ,2 ,1 ,2 ,2 ,4 ,5 ,4 ,4 ,8 ,0 ,224}},
{hcdln2,{0 ,0 ,5 ,2 ,2 ,4 ,5 ,4 ,4 ,8 ,2 ,220}},
{hcode0,{0 ,0 ,0 ,8 ,8 ,8 ,9 ,0 ,0 ,0 ,0 ,224}},
{hcode1,{0 ,0 ,0 ,0 ,4 ,40 ,16 ,16 ,4 ,0 ,47 ,130}},
{hcode2,{0 ,0 ,0 ,0 ,2 ,5 ,46 ,64 ,116 ,24 ,0 ,0 }},
{hcode3,{0 ,0 ,0 ,0 ,0 ,2 ,14 ,202 ,33 ,6 ,0 ,0 }},
{hcode4,{0 ,0 ,0 ,0 ,0 ,0 ,0 ,255 ,2 ,0 ,0 ,0 }}};
SDWORD DestUnpSize=0;
UBYTE FlagBuf;
UWORD InAdr,OutAdr;
unsigned int Suspend=0;
unsigned int NumBit;
unsigned int LCount;
int FlagsCnt;
struct UnpData
{
UWORD ChSet[256];
UBYTE Place[256];
UBYTE NToPl[256];
UBYTE ChSetA[256];
UBYTE PlaceA[256];
UWORD ChSetB[256];
UBYTE PlaceB[256];
UBYTE NToPlB[256];
UWORD ChSetC[256];
UBYTE PlaceC[256];
UBYTE NToPlC[256];
UWORD AvrPlc;
UWORD AvrPlcB;
UWORD AvrLn1;
UWORD AvrLn2;
UWORD AvrLn3;
UBYTE NumHuf;
UBYTE StMode;
UWORD Nhfb;
UWORD Nlzb;
UWORD MaxDist3;
UBYTE Buf60;
UWORD WrAddr;
UWORD SomeRd;
UWORD UnpAllBuf;
UWORD LastDist;
UWORD LastLen;
UWORD OldDist[4];
UWORD OldDistNum;
} *D;
struct DecodeTables
{
UBYTE ECDSH1[256];
UBYTE ECDSH2[256];
UBYTE ECDSH3[256];
UBYTE ECDSH4[256];
UBYTE ECDLN0[256];
UBYTE ECDLN1[4096];
UBYTE ECDLN2[4096];
UBYTE ECODE0[4096];
UBYTE ECODE1[4096];
UBYTE ECODE2[1024];
UBYTE ECODE3[1024];
UBYTE ECODE4[1024];
UBYTE NCDSH1[16];
UBYTE NCDSH2[16];
UBYTE NCDSH3[16];
UBYTE NCDSH4[16];
UBYTE NCDLN0[256];
UBYTE NCDLN1[256];
UBYTE NCDLN2[256];
UBYTE NCODE0[257];
UBYTE NCODE1[257];
UBYTE NCODE2[257];
UBYTE NCODE3[257];
UBYTE NCODE4[257];
} *T;
UBYTE *PackBuf;
HPBYTE UnpBuf;
int (* UnpReadFn)();
int (* UnpWriteFn)();
#define GetField() ((UWORD)((((UDWORD)PackBuf[InAdr] << 16) | \
((UWORD)PackBuf[InAdr+1] << 8) | PackBuf[InAdr+2]) \
>> (8-NumBit)))
void AddBit(NBits)
unsigned int NBits;
{
InAdr += (NumBit+NBits) >> 3;
NumBit = (NumBit+NBits) & 7;
}
void CopyString(Distance,Length)
UWORD Distance;
unsigned int Length;
{
DestUnpSize-=Length;
while (Length--)
{
UnpBuf[OutAdr]=UnpBuf[(UWORD)(OutAdr-Distance)];
OutAdr++;
}
}
int unpack(UnpMem,UnpRead,UnpWrite,Solid)
HPBYTE UnpMem;
int (* UnpRead)();
int (* UnpWrite)();
int Solid;
{
UnpReadFn=UnpRead;
UnpWriteFn=UnpWrite;
UnpBuf=(UBYTE *)UnpMem;
PackBuf=(UBYTE *)(UnpMem+0x10000L+sizeof(struct UnpData)+sizeof(struct DecodeTables));
D=(struct UnpData *)(UnpMem+0x10000L);
if (Suspend)
OutAdr=D->WrAddr;
else
{
UnpInitData(Solid);
if (!Solid)
{
InitHuff();
memset(UnpBuf,0,0x8000);
memset(UnpBuf+0x8000,0,0x8000);
OutAdr=0;
}
else
OutAdr=D->WrAddr;
if (--DestUnpSize < 0)
return(0);
if (UnpReadBuf(FIRST)==-1)
return(-1);
GetFlagsBuf();
FlagsCnt=8;
}
while (DestUnpSize>=0)
{
if (InAdr >= SIZE_PBUF-12)
if (UnpReadBuf(NEXT)==-1)
return(-1);
if ((UWORD)(D->WrAddr - OutAdr) < 0x110 && D->WrAddr!=OutAdr)
{
if (UnpWriteBuf()==-1)
return(-1);
if (Suspend)
return(0);
}
if (D->StMode)
{
HuffDecode();
continue;
}
if (--FlagsCnt < 0)
{
GetFlagsBuf();
FlagsCnt=7;
}
if (FlagBuf >= 0x80)
{
FlagBuf<<=1;
if (D->Nlzb > D->Nhfb)
LongLZ();
else
HuffDecode();
}
else
{
FlagBuf<<=1;
if (--FlagsCnt < 0)
{
GetFlagsBuf();
FlagsCnt=7;
}
if (FlagBuf >= 0x80)
{
FlagBuf<<=1;
if (D->Nlzb > D->Nhfb)
HuffDecode();
else
LongLZ();
}
else
{
FlagBuf<<=1;
ShortLZ();
}
}
}
if (UnpWriteBuf()==-1)
return(-1);
return(0);
}
void ShortLZ()
{
UWORD LengthCode,SaveLength;
UBYTE LastDistance;
UWORD Distance,DistancePlace,Length;
D->NumHuf=0;
LengthCode=GetField();
if (LCount==2)
{
AddBit(1);
if (LengthCode >= 0x8000)
{
CopyString(D->LastDist,D->LastLen);
return;
}
LengthCode <<= 1;
LCount=0;
}
LengthCode >>= 8;
if (D->Buf60==0)
if (D->AvrLn1<37)
{
Length=T->ECDSH1[LengthCode];
AddBit(T->NCDSH1[Length]);
}
else
{
Length=T->ECDSH2[LengthCode];
AddBit(T->NCDSH2[Length]);
}
else
if (D->AvrLn1<37)
{
Length=T->ECDSH3[LengthCode];
AddBit(T->NCDSH3[Length]);
}
else
{
Length=T->ECDSH4[LengthCode];
AddBit(T->NCDSH4[Length]);
}
if (Length >= 9)
{
if (Length == 9)
{
LCount++;
CopyString(D->LastDist,D->LastLen);
return;
}
if (Length == 14)
{
LCount=0;
Length=T->ECDLN2[GetField() >> 4];
AddBit(T->NCDLN2[Length]);
Length+=5;
Distance=(GetField() >> 1) | 0x8000;
AddBit(15);
D->LastLen=Length;
D->LastDist=Distance;
CopyString(Distance,Length);
return;
}
LCount=0;
SaveLength=Length;
Distance=D->OldDist[(D->OldDistNum-(Length-9)) & 3];
Length=T->ECDLN1[GetField() >> 4];
AddBit(T->NCDLN1[Length]);
Length+=2;
if (Length==0x101 && SaveLength==10)
{
D->Buf60 ^= 1;
return;
}
if (Distance > 256)
Length++;
if (Distance > D->MaxDist3)
Length++;
D->OldDist[D->OldDistNum++]=Distance;
D->OldDistNum = D->OldDistNum & 3;
D->LastLen=Length;
D->LastDist=Distance;
CopyString(Distance,Length);
return;
}
LCount=0;
D->AvrLn1 += Length;
D->AvrLn1 -= D->AvrLn1 >> 4;
DistancePlace=T->ECODE2[GetField() >> 6];
AddBit(T->NCODE2[DistancePlace]);
Distance=D->ChSetA[DistancePlace];
if (--DistancePlace != 0xFFFF)
{
D->PlaceA[Distance]--;
LastDistance=D->ChSetA[DistancePlace];
D->PlaceA[LastDistance]++;
D->ChSetA[DistancePlace+1]=LastDistance;
D->ChSetA[DistancePlace]=(UBYTE)Distance;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -