⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unpack.c

📁 比zip压缩比率高的rar压缩方法的解压程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/******    *****   ******
 **   **  **   **  **   **      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 + -