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

📄 unpack.c

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