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

📄 unpack.cpp

📁 7Zip软件实现: 七种编码格式的压缩与解压缩功能。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    }  Array<byte> VMCode(Length);  for (int I=0;I<Length;I++)  {    int Ch=PPM.DecodeChar();    if (Ch==-1)      return(false);    VMCode[I]=Ch;  }  return(AddVMCode(FirstByte,&VMCode[0],Length));}bool Unpack::AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize){  BitInput Inp;  Inp.InitBitInput();  memcpy(Inp.InBuf,Code,Min(BitInput::MAX_SIZE,CodeSize));  VM.Init();  uint FiltPos;  if (FirstByte & 0x80)  {    FiltPos=RarVM::ReadData(Inp);    if (FiltPos==0)      InitFilters();    else      FiltPos--;  }  else    FiltPos=LastFilter;  if (FiltPos>Filters.Size() || FiltPos>OldFilterLengths.Size())    return(false);  LastFilter=FiltPos;  bool NewFilter=(FiltPos==Filters.Size());  UnpackFilter *Filter;  if (NewFilter)  {    Filters.Add(1);    Filters[Filters.Size()-1]=Filter=new UnpackFilter;    OldFilterLengths.Add(1);    Filter->ExecCount=0;  }  else  {    Filter=Filters[FiltPos];    Filter->ExecCount++;  }  UnpackFilter *StackFilter=new UnpackFilter;  int EmptyCount=0;  for (int I=0;I<PrgStack.Size();I++)  {    PrgStack[I-EmptyCount]=PrgStack[I];    if (PrgStack[I]==NULL)      EmptyCount++;    if (EmptyCount>0)      PrgStack[I]=NULL;  }  if (EmptyCount==0)  {    PrgStack.Add(1);    EmptyCount=1;  }  int StackPos=PrgStack.Size()-EmptyCount;  PrgStack[StackPos]=StackFilter;  StackFilter->ExecCount=Filter->ExecCount;   uint BlockStart=RarVM::ReadData(Inp);  if (FirstByte & 0x40)    BlockStart+=258;  StackFilter->BlockStart=(BlockStart+UnpPtr)&MAXWINMASK;  if (FirstByte & 0x20)    StackFilter->BlockLength=RarVM::ReadData(Inp);  else    StackFilter->BlockLength=FiltPos<OldFilterLengths.Size() ? OldFilterLengths[FiltPos]:0;  StackFilter->NextWindow=WrPtr!=UnpPtr && ((WrPtr-UnpPtr)&MAXWINMASK)<=BlockStart;//  DebugLog("\nNextWindow: UnpPtr=%08x WrPtr=%08x BlockStart=%08x",UnpPtr,WrPtr,BlockStart);  OldFilterLengths[FiltPos]=StackFilter->BlockLength;  memset(StackFilter->Prg.InitR,0,sizeof(StackFilter->Prg.InitR));  StackFilter->Prg.InitR[3]=VM_GLOBALMEMADDR;  StackFilter->Prg.InitR[4]=StackFilter->BlockLength;  StackFilter->Prg.InitR[5]=StackFilter->ExecCount;  if (FirstByte & 0x10)  {    unsigned int InitMask=Inp.fgetbits()>>9;    Inp.faddbits(7);    for (int I=0;I<7;I++)      if (InitMask & (1<<I))        StackFilter->Prg.InitR[I]=RarVM::ReadData(Inp);  }  if (NewFilter)  {    uint VMCodeSize=RarVM::ReadData(Inp);    if (VMCodeSize>=0x10000 || VMCodeSize==0)      return(false);    Array<byte> VMCode(VMCodeSize);    for (int I=0;I<VMCodeSize;I++)    {      VMCode[I]=Inp.fgetbits()>>8;      Inp.faddbits(8);    }    VM.Prepare(&VMCode[0],VMCodeSize,&Filter->Prg);  }  StackFilter->Prg.AltCmd=&Filter->Prg.Cmd[0];  StackFilter->Prg.CmdCount=Filter->Prg.CmdCount;  int StaticDataSize=Filter->Prg.StaticData.Size();  if (StaticDataSize>0 && StaticDataSize<VM_GLOBALMEMSIZE)  {    StackFilter->Prg.StaticData.Add(StaticDataSize);    memcpy(&StackFilter->Prg.StaticData[0],&Filter->Prg.StaticData[0],StaticDataSize);  }  if (StackFilter->Prg.GlobalData.Size()<VM_FIXEDGLOBALSIZE)  {    StackFilter->Prg.GlobalData.Reset();    StackFilter->Prg.GlobalData.Add(VM_FIXEDGLOBALSIZE);  }  byte *GlobalData=&StackFilter->Prg.GlobalData[0];  for (int I=0;I<7;I++)    VM.SetValue((uint *)&GlobalData[I*4],StackFilter->Prg.InitR[I]);  VM.SetValue((uint *)&GlobalData[0x1c],StackFilter->BlockLength);  VM.SetValue((uint *)&GlobalData[0x20],0);  VM.SetValue((uint *)&GlobalData[0x2c],StackFilter->ExecCount);  memset(&GlobalData[0x30],0,16);  if (FirstByte & 8)  {    uint DataSize=RarVM::ReadData(Inp);    if (DataSize>=0x10000)      return(false);    unsigned int CurSize=StackFilter->Prg.GlobalData.Size();    if (CurSize<DataSize+VM_FIXEDGLOBALSIZE)      StackFilter->Prg.GlobalData.Add(DataSize+VM_FIXEDGLOBALSIZE-CurSize);    byte *GlobalData=&StackFilter->Prg.GlobalData[VM_FIXEDGLOBALSIZE];    for (int I=0;I<DataSize;I++)    {      GlobalData[I]=Inp.fgetbits()>>8;      Inp.faddbits(8);    }  }  return(true);}bool Unpack::UnpReadBuf(){  int DataSize=ReadTop-InAddr;  if (DataSize<0)    return(false);  if (InAddr>BitInput::MAX_SIZE/2)  {    if (DataSize>0)      memmove(InBuf,InBuf+InAddr,DataSize);    InAddr=0;    ReadTop=DataSize;  }  else    DataSize=ReadTop;  int ReadCode=UnpIO->UnpRead(InBuf+DataSize,(BitInput::MAX_SIZE-DataSize)&~0xf);  if (ReadCode>0)    ReadTop+=ReadCode;  ReadBorder=ReadTop-30;  return(ReadCode!=-1);}void Unpack::UnpWriteBuf(){  unsigned int WrittenBorder=WrPtr;  unsigned int WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;  for (int I=0;I<PrgStack.Size();I++)  {    UnpackFilter *flt=PrgStack[I];    if (flt==NULL)      continue;    if (flt->NextWindow)    {      flt->NextWindow=false;      continue;    }    unsigned int BlockStart=flt->BlockStart;    unsigned int BlockLength=flt->BlockLength;    if (((BlockStart-WrittenBorder)&MAXWINMASK)<WriteSize)    {      if (WrittenBorder!=BlockStart)      {        UnpWriteArea(WrittenBorder,BlockStart);        WrittenBorder=BlockStart;        WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;      }      if (BlockLength<=WriteSize)      {        unsigned int BlockEnd=(BlockStart+BlockLength)&MAXWINMASK;        if (BlockStart<BlockEnd || BlockEnd==0)          VM.SetMemory(0,Window+BlockStart,BlockLength);        else        {          unsigned int FirstPartLength=MAXWINSIZE-BlockStart;          VM.SetMemory(0,Window+BlockStart,FirstPartLength);          VM.SetMemory(FirstPartLength,Window,BlockEnd);        }        VM_PreparedProgram *Prg=&flt->Prg;        ExecuteCode(Prg);        byte *FilteredData=Prg->FilteredData;        unsigned int FilteredDataSize=Prg->FilteredDataSize;        delete PrgStack[I];        PrgStack[I]=NULL;        while (I+1<PrgStack.Size())        {          UnpackFilter *NextFilter=PrgStack[I+1];          if (NextFilter==NULL || NextFilter->BlockStart!=BlockStart ||              NextFilter->BlockLength!=FilteredDataSize || NextFilter->NextWindow)            break;          VM.SetMemory(0,FilteredData,FilteredDataSize);          VM_PreparedProgram *NextPrg=&PrgStack[I+1]->Prg;          ExecuteCode(NextPrg);          FilteredData=NextPrg->FilteredData;          FilteredDataSize=NextPrg->FilteredDataSize;          I++;          delete PrgStack[I];          PrgStack[I]=NULL;        }        UnpIO->UnpWrite(FilteredData,FilteredDataSize);        UnpSomeRead=true;        WrittenFileSize+=FilteredDataSize;        WrittenBorder=BlockEnd;        WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;      }      else      {        for (int J=I;J<PrgStack.Size();J++)        {          UnpackFilter *flt=PrgStack[J];          if (flt!=NULL && flt->NextWindow)            flt->NextWindow=false;        }        WrPtr=WrittenBorder;        return;      }    }  }        UnpWriteArea(WrittenBorder,UnpPtr);  WrPtr=UnpPtr;}void Unpack::ExecuteCode(VM_PreparedProgram *Prg){  if (Prg->GlobalData.Size()>0)  {    Prg->InitR[6]=int64to32(WrittenFileSize);    VM.SetValue((uint *)&Prg->GlobalData[0x24],int64to32(WrittenFileSize));    VM.SetValue((uint *)&Prg->GlobalData[0x28],int64to32(WrittenFileSize>>32));    VM.Execute(Prg);  }}void Unpack::UnpWriteArea(unsigned int StartPtr,unsigned int EndPtr){  if (EndPtr!=StartPtr)    UnpSomeRead=true;  if (EndPtr<StartPtr)  {    UnpWriteData(&Window[StartPtr],-StartPtr & MAXWINMASK);    UnpWriteData(Window,EndPtr);    UnpAllBuf=true;  }  else    UnpWriteData(&Window[StartPtr],EndPtr-StartPtr);}void Unpack::UnpWriteData(byte *Data,int Size){  if (WrittenFileSize>=DestUnpSize)    return;  int WriteSize=Size;  Int64 LeftToWrite=DestUnpSize-WrittenFileSize;  if (WriteSize>LeftToWrite)    WriteSize=int64to32(LeftToWrite);  UnpIO->UnpWrite(Data,WriteSize);  WrittenFileSize+=Size;}bool Unpack::ReadTables(){  byte BitLength[BC];  unsigned char Table[HUFF_TABLE_SIZE];  if (InAddr>ReadTop-25)    if (!UnpReadBuf())      return(false);  faddbits((8-InBit)&7);  unsigned int BitField=fgetbits();  if (BitField & 0x8000)  {    UnpBlockType=BLOCK_PPM;    return(PPM.DecodeInit(this,PPMEscChar));  }  UnpBlockType=BLOCK_LZ;    PrevLowDist=0;  LowDistRepCount=0;  if (!(BitField & 0x4000))    memset(UnpOldTable,0,sizeof(UnpOldTable));  faddbits(2);  for (int I=0;I<BC;I++)  {    int Length=(byte)(fgetbits() >> 12);    faddbits(4);    if (Length==15)    {      int ZeroCount=(byte)(fgetbits() >> 12);      faddbits(4);      if (ZeroCount==0)        BitLength[I]=15;      else      {        ZeroCount+=2;        while (ZeroCount-- > 0 && I<sizeof(BitLength)/sizeof(BitLength[0]))          BitLength[I++]=0;        I--;      }    }    else      BitLength[I]=Length;  }  MakeDecodeTables(BitLength,(struct Decode *)&BD,BC);  const int TableSize=HUFF_TABLE_SIZE;  for (int I=0;I<TableSize;)  {    if (InAddr>ReadTop-5)      if (!UnpReadBuf())        return(false);    int Number=DecodeNumber((struct Decode *)&BD);    if (Number<16)    {      Table[I]=(Number+UnpOldTable[I]) & 0xf;      I++;    }    else      if (Number<18)      {        int N;        if (Number==16)        {          N=(fgetbits() >> 13)+3;          faddbits(3);        }        else        {          N=(fgetbits() >> 9)+11;          faddbits(7);        }        while (N-- > 0 && I<TableSize)        {          Table[I]=Table[I-1];          I++;        }      }      else      {        int N;        if (Number==18)        {          N=(fgetbits() >> 13)+3;          faddbits(3);        }        else        {          N=(fgetbits() >> 9)+11;          faddbits(7);        }        while (N-- > 0 && I<TableSize)          Table[I++]=0;      }  }  TablesRead=true;  if (InAddr>ReadTop)    return(false);  MakeDecodeTables(&Table[0],(struct Decode *)&LD,NC);  MakeDecodeTables(&Table[NC],(struct Decode *)&DD,DC);  MakeDecodeTables(&Table[NC+DC],(struct Decode *)&LDD,LDC);  MakeDecodeTables(&Table[NC+DC+LDC],(struct Decode *)&RD,RC);  memcpy(UnpOldTable,Table,sizeof(UnpOldTable));  return(true);}void Unpack::UnpInitData(int Solid){  if (!Solid)  {    TablesRead=false;    memset(OldDist,0,sizeof(OldDist));    OldDistPtr=0;    LastDist=LastLength=0;//    memset(Window,0,MAXWINSIZE);    memset(UnpOldTable,0,sizeof(UnpOldTable));    UnpPtr=WrPtr=0;    PPMEscChar=2;    InitFilters();  }  InitBitInput();  PPMError=false;  WrittenFileSize=0;  ReadTop=0;  ReadBorder=0;#ifndef SFX_MODULE  // Igor Pavlov
  // UnpInitData20(Solid);
#endif}void Unpack::InitFilters(){  OldFilterLengths.Reset();  LastFilter=0;  for (int I=0;I<Filters.Size();I++)    delete Filters[I];  Filters.Reset();  for (int I=0;I<PrgStack.Size();I++)    delete PrgStack[I];  PrgStack.Reset();}void Unpack::MakeDecodeTables(unsigned char *LenTab,struct Decode *Dec,int Size){  int LenCount[16],TmpPos[16],I;  long M,N;  memset(LenCount,0,sizeof(LenCount));  memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));  for (I=0;I<Size;I++)    LenCount[LenTab[I] & 0xF]++;  LenCount[0]=0;  for (TmpPos[0]=Dec->DecodePos[0]=Dec->DecodeLen[0]=0,N=0,I=1;I<16;I++)  {    N=2*(N+LenCount[I]);    M=N<<(15-I);    if (M>0xFFFF)      M=0xFFFF;    Dec->DecodeLen[I]=(unsigned int)M;    TmpPos[I]=Dec->DecodePos[I]=Dec->DecodePos[I-1]+LenCount[I-1];  }  for (I=0;I<Size;I++)    if (LenTab[I]!=0)      Dec->DecodeNum[TmpPos[LenTab[I] & 0xF]++]=I;  Dec->MaxNum=Size;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -