"Fossies" - the Fresh Open Source Software Archive

Member "unrar/unpack30.cpp" (4 May 2022, 19729 Bytes) of package /linux/misc/unrarsrc-6.1.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "unpack30.cpp" see the Fossies "Dox" file reference documentation.

    1 // We use it instead of direct PPM.DecodeChar call to be sure that
    2 // we reset PPM structures in case of corrupt data. It is important,
    3 // because these structures can be invalid after PPM.DecodeChar returned -1.
    4 inline int Unpack::SafePPMDecodeChar()
    5 {
    6   int Ch=PPM.DecodeChar();
    7   if (Ch==-1)              // Corrupt PPM data found.
    8   {
    9     PPM.CleanUp();         // Reset possibly corrupt PPM data structures.
   10     UnpBlockType=BLOCK_LZ; // Set faster and more fail proof LZ mode.
   11   }
   12   return(Ch);
   13 }
   14 
   15 
   16 void Unpack::Unpack29(bool Solid)
   17 {
   18   static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
   19   static unsigned char LBits[]=  {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,  4,  5,  5,  5,  5};
   20   static int DDecode[DC];
   21   static byte DBits[DC];
   22   static int DBitLengthCounts[]= {4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,14,0,12};
   23   static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
   24   static unsigned char SDBits[]=  {2,2,3, 4, 5, 6,  6,  6};
   25   unsigned int Bits;
   26 
   27   if (DDecode[1]==0)
   28   {
   29     int Dist=0,BitLength=0,Slot=0;
   30     for (int I=0;I<ASIZE(DBitLengthCounts);I++,BitLength++)
   31       for (int J=0;J<DBitLengthCounts[I];J++,Slot++,Dist+=(1<<BitLength))
   32       {
   33         DDecode[Slot]=Dist;
   34         DBits[Slot]=BitLength;
   35       }
   36   }
   37 
   38   FileExtracted=true;
   39 
   40   if (!Suspended)
   41   {
   42     UnpInitData(Solid);
   43     if (!UnpReadBuf30())
   44       return;
   45     if ((!Solid || !TablesRead3) && !ReadTables30())
   46       return;
   47   }
   48 
   49   while (true)
   50   {
   51     UnpPtr&=MaxWinMask;
   52 
   53     if (Inp.InAddr>ReadBorder)
   54     {
   55       if (!UnpReadBuf30())
   56         break;
   57     }
   58     if (((WrPtr-UnpPtr) & MaxWinMask)<260 && WrPtr!=UnpPtr)
   59     {
   60       UnpWriteBuf30();
   61       if (WrittenFileSize>DestUnpSize)
   62         return;
   63       if (Suspended)
   64       {
   65         FileExtracted=false;
   66         return;
   67       }
   68     }
   69     if (UnpBlockType==BLOCK_PPM)
   70     {
   71       // Here speed is critical, so we do not use SafePPMDecodeChar,
   72       // because sometimes even the inline function can introduce
   73       // some additional penalty.
   74       int Ch=PPM.DecodeChar();
   75       if (Ch==-1)              // Corrupt PPM data found.
   76       {
   77         PPM.CleanUp();         // Reset possibly corrupt PPM data structures.
   78         UnpBlockType=BLOCK_LZ; // Set faster and more fail proof LZ mode.
   79         break;
   80       }
   81       if (Ch==PPMEscChar)
   82       {
   83         int NextCh=SafePPMDecodeChar();
   84         if (NextCh==0)  // End of PPM encoding.
   85         {
   86           if (!ReadTables30())
   87             break;
   88           continue;
   89         }
   90         if (NextCh==-1) // Corrupt PPM data found.
   91           break;
   92         if (NextCh==2)  // End of file in PPM mode.
   93           break;
   94         if (NextCh==3)  // Read VM code.
   95         {
   96           if (!ReadVMCodePPM())
   97             break;
   98           continue;
   99         }
  100         if (NextCh==4) // LZ inside of PPM.
  101         {
  102           unsigned int Distance=0,Length;
  103           bool Failed=false;
  104           for (int I=0;I<4 && !Failed;I++)
  105           {
  106             int Ch=SafePPMDecodeChar();
  107             if (Ch==-1)
  108               Failed=true;
  109             else
  110               if (I==3)
  111                 Length=(byte)Ch;
  112               else
  113                 Distance=(Distance<<8)+(byte)Ch;
  114           }
  115           if (Failed)
  116             break;
  117 
  118           CopyString(Length+32,Distance+2);
  119           continue;
  120         }
  121         if (NextCh==5) // One byte distance match (RLE) inside of PPM.
  122         {
  123           int Length=SafePPMDecodeChar();
  124           if (Length==-1)
  125             break;
  126           CopyString(Length+4,1);
  127           continue;
  128         }
  129         // If we are here, NextCh must be 1, what means that current byte
  130         // is equal to our 'escape' byte, so we just store it to Window.
  131       }
  132       Window[UnpPtr++]=Ch;
  133       continue;
  134     }
  135 
  136     uint Number=DecodeNumber(Inp,&BlockTables.LD);
  137     if (Number<256)
  138     {
  139       Window[UnpPtr++]=(byte)Number;
  140       continue;
  141     }
  142     if (Number>=271)
  143     {
  144       uint Length=LDecode[Number-=271]+3;
  145       if ((Bits=LBits[Number])>0)
  146       {
  147         Length+=Inp.getbits()>>(16-Bits);
  148         Inp.addbits(Bits);
  149       }
  150 
  151       uint DistNumber=DecodeNumber(Inp,&BlockTables.DD);
  152       uint Distance=DDecode[DistNumber]+1;
  153       if ((Bits=DBits[DistNumber])>0)
  154       {
  155         if (DistNumber>9)
  156         {
  157           if (Bits>4)
  158           {
  159             Distance+=((Inp.getbits()>>(20-Bits))<<4);
  160             Inp.addbits(Bits-4);
  161           }
  162           if (LowDistRepCount>0)
  163           {
  164             LowDistRepCount--;
  165             Distance+=PrevLowDist;
  166           }
  167           else
  168           {
  169             uint LowDist=DecodeNumber(Inp,&BlockTables.LDD);
  170             if (LowDist==16)
  171             {
  172               LowDistRepCount=LOW_DIST_REP_COUNT-1;
  173               Distance+=PrevLowDist;
  174             }
  175             else
  176             {
  177               Distance+=LowDist;
  178               PrevLowDist=LowDist;
  179             }
  180           }
  181         }
  182         else
  183         {
  184           Distance+=Inp.getbits()>>(16-Bits);
  185           Inp.addbits(Bits);
  186         }
  187       }
  188 
  189       if (Distance>=0x2000)
  190       {
  191         Length++;
  192         if (Distance>=0x40000)
  193           Length++;
  194       }
  195 
  196       InsertOldDist(Distance);
  197       LastLength=Length;
  198       CopyString(Length,Distance);
  199       continue;
  200     }
  201     if (Number==256)
  202     {
  203       if (!ReadEndOfBlock())
  204         break;
  205       continue;
  206     }
  207     if (Number==257)
  208     {
  209       if (!ReadVMCode())
  210         break;
  211       continue;
  212     }
  213     if (Number==258)
  214     {
  215       if (LastLength!=0)
  216         CopyString(LastLength,OldDist[0]);
  217       continue;
  218     }
  219     if (Number<263)
  220     {
  221       uint DistNum=Number-259;
  222       uint Distance=OldDist[DistNum];
  223       for (uint I=DistNum;I>0;I--)
  224         OldDist[I]=OldDist[I-1];
  225       OldDist[0]=Distance;
  226 
  227       uint LengthNumber=DecodeNumber(Inp,&BlockTables.RD);
  228       int Length=LDecode[LengthNumber]+2;
  229       if ((Bits=LBits[LengthNumber])>0)
  230       {
  231         Length+=Inp.getbits()>>(16-Bits);
  232         Inp.addbits(Bits);
  233       }
  234       LastLength=Length;
  235       CopyString(Length,Distance);
  236       continue;
  237     }
  238     if (Number<272)
  239     {
  240       uint Distance=SDDecode[Number-=263]+1;
  241       if ((Bits=SDBits[Number])>0)
  242       {
  243         Distance+=Inp.getbits()>>(16-Bits);
  244         Inp.addbits(Bits);
  245       }
  246       InsertOldDist(Distance);
  247       LastLength=2;
  248       CopyString(2,Distance);
  249       continue;
  250     }
  251   }
  252   UnpWriteBuf30();
  253 }
  254 
  255 
  256 // Return 'false' to quit unpacking the current file or 'true' to continue.
  257 bool Unpack::ReadEndOfBlock()
  258 {
  259   uint BitField=Inp.getbits();
  260   bool NewTable,NewFile=false;
  261 
  262   // "1"  - no new file, new table just here.
  263   // "00" - new file,    no new table.
  264   // "01" - new file,    new table (in beginning of next file).
  265   
  266   if ((BitField & 0x8000)!=0)
  267   {
  268     NewTable=true;
  269     Inp.addbits(1);
  270   }
  271   else
  272   {
  273     NewFile=true;
  274     NewTable=(BitField & 0x4000)!=0;
  275     Inp.addbits(2);
  276   }
  277   TablesRead3=!NewTable;
  278 
  279   // Quit immediately if "new file" flag is set. If "new table" flag
  280   // is present, we'll read the table in beginning of next file
  281   // based on 'TablesRead3' 'false' value.
  282   if (NewFile)
  283     return false;
  284   return ReadTables30(); // Quit only if we failed to read tables.
  285 }
  286 
  287 
  288 bool Unpack::ReadVMCode()
  289 {
  290   // Entire VM code is guaranteed to fully present in block defined 
  291   // by current Huffman table. Compressor checks that VM code does not cross
  292   // Huffman block boundaries.
  293   uint FirstByte=Inp.getbits()>>8;
  294   Inp.addbits(8);
  295   uint Length=(FirstByte & 7)+1;
  296   if (Length==7)
  297   {
  298     Length=(Inp.getbits()>>8)+7;
  299     Inp.addbits(8);
  300   }
  301   else
  302     if (Length==8)
  303     {
  304       Length=Inp.getbits();
  305       Inp.addbits(16);
  306     }
  307   if (Length==0)
  308     return false;
  309   Array<byte> VMCode(Length);
  310   for (uint I=0;I<Length;I++)
  311   {
  312     // Try to read the new buffer if only one byte is left.
  313     // But if we read all bytes except the last, one byte is enough.
  314     if (Inp.InAddr>=ReadTop-1 && !UnpReadBuf30() && I<Length-1)
  315       return false;
  316     VMCode[I]=Inp.getbits()>>8;
  317     Inp.addbits(8);
  318   }
  319   return AddVMCode(FirstByte,&VMCode[0],Length);
  320 }
  321 
  322 
  323 bool Unpack::ReadVMCodePPM()
  324 {
  325   uint FirstByte=SafePPMDecodeChar();
  326   if ((int)FirstByte==-1)
  327     return false;
  328   uint Length=(FirstByte & 7)+1;
  329   if (Length==7)
  330   {
  331     int B1=SafePPMDecodeChar();
  332     if (B1==-1)
  333       return false;
  334     Length=B1+7;
  335   }
  336   else
  337     if (Length==8)
  338     {
  339       int B1=SafePPMDecodeChar();
  340       if (B1==-1)
  341         return false;
  342       int B2=SafePPMDecodeChar();
  343       if (B2==-1)
  344         return false;
  345       Length=B1*256+B2;
  346     }
  347   if (Length==0)
  348     return false;
  349   Array<byte> VMCode(Length);
  350   for (uint I=0;I<Length;I++)
  351   {
  352     int Ch=SafePPMDecodeChar();
  353     if (Ch==-1)
  354       return false;
  355     VMCode[I]=Ch;
  356   }
  357   return AddVMCode(FirstByte,&VMCode[0],Length);
  358 }
  359 
  360 
  361 bool Unpack::AddVMCode(uint FirstByte,byte *Code,uint CodeSize)
  362 {
  363   VMCodeInp.InitBitInput();
  364   memcpy(VMCodeInp.InBuf,Code,Min(BitInput::MAX_SIZE,CodeSize));
  365   VM.Init();
  366 
  367   uint FiltPos;
  368   if ((FirstByte & 0x80)!=0)
  369   {
  370     FiltPos=RarVM::ReadData(VMCodeInp);
  371     if (FiltPos==0)
  372       InitFilters30(false);
  373     else
  374       FiltPos--;
  375   }
  376   else
  377     FiltPos=LastFilter; // Use the same filter as last time.
  378 
  379   if (FiltPos>Filters30.Size() || FiltPos>OldFilterLengths.Size())
  380     return false;
  381   LastFilter=FiltPos;
  382   bool NewFilter=(FiltPos==Filters30.Size());
  383 
  384   UnpackFilter30 *StackFilter=new UnpackFilter30; // New filter for PrgStack.
  385 
  386   UnpackFilter30 *Filter;
  387   if (NewFilter) // New filter code, never used before since VM reset.
  388   {
  389     if (FiltPos>MAX3_UNPACK_FILTERS)
  390     {
  391       // Too many different filters, corrupt archive.
  392       delete StackFilter;
  393       return false;
  394     }
  395 
  396     Filters30.Add(1);
  397     Filters30[Filters30.Size()-1]=Filter=new UnpackFilter30;
  398     StackFilter->ParentFilter=(uint)(Filters30.Size()-1);
  399 
  400     // Reserve one item to store the data block length of our new filter 
  401     // entry. We'll set it to real block length below, after reading it.
  402     // But we need to initialize it now, because when processing corrupt
  403     // data, we can access this item even before we set it to real value.
  404     OldFilterLengths.Push(0);
  405   }
  406   else  // Filter was used in the past.
  407   {
  408     Filter=Filters30[FiltPos];
  409     StackFilter->ParentFilter=FiltPos;
  410   }
  411 
  412   uint EmptyCount=0;
  413   for (uint I=0;I<PrgStack.Size();I++)
  414   {
  415     PrgStack[I-EmptyCount]=PrgStack[I];
  416     if (PrgStack[I]==NULL)
  417       EmptyCount++;
  418     if (EmptyCount>0)
  419       PrgStack[I]=NULL;
  420   }
  421   if (EmptyCount==0)
  422   {
  423     if (PrgStack.Size()>MAX3_UNPACK_FILTERS)
  424     {
  425       delete StackFilter;
  426       return false;
  427     }
  428     PrgStack.Add(1);
  429     EmptyCount=1;
  430   }
  431   size_t StackPos=PrgStack.Size()-EmptyCount;
  432   PrgStack[StackPos]=StackFilter;
  433  
  434   uint BlockStart=RarVM::ReadData(VMCodeInp);
  435   if ((FirstByte & 0x40)!=0)
  436     BlockStart+=258;
  437   StackFilter->BlockStart=(uint)((BlockStart+UnpPtr)&MaxWinMask);
  438   if ((FirstByte & 0x20)!=0)
  439   {
  440     StackFilter->BlockLength=RarVM::ReadData(VMCodeInp);
  441 
  442     // Store the last data block length for current filter.
  443     OldFilterLengths[FiltPos]=StackFilter->BlockLength;
  444   }
  445   else
  446   {
  447     // Set the data block size to same value as the previous block size
  448     // for same filter. It is possible for corrupt data to access a new 
  449     // and not filled yet item of OldFilterLengths array here. This is why
  450     // we set new OldFilterLengths items to zero above.
  451     StackFilter->BlockLength=FiltPos<OldFilterLengths.Size() ? OldFilterLengths[FiltPos]:0;
  452   }
  453 
  454   StackFilter->NextWindow=WrPtr!=UnpPtr && ((WrPtr-UnpPtr)&MaxWinMask)<=BlockStart;
  455 
  456 //  DebugLog("\nNextWindow: UnpPtr=%08x WrPtr=%08x BlockStart=%08x",UnpPtr,WrPtr,BlockStart);
  457 
  458   memset(StackFilter->Prg.InitR,0,sizeof(StackFilter->Prg.InitR));
  459   StackFilter->Prg.InitR[4]=StackFilter->BlockLength;
  460 
  461   if ((FirstByte & 0x10)!=0) // Set registers to optional parameters if any.
  462   {
  463     uint InitMask=VMCodeInp.fgetbits()>>9;
  464     VMCodeInp.faddbits(7);
  465     for (uint I=0;I<7;I++)
  466       if (InitMask & (1<<I))
  467         StackFilter->Prg.InitR[I]=RarVM::ReadData(VMCodeInp);
  468   }
  469 
  470   if (NewFilter)
  471   {
  472     uint VMCodeSize=RarVM::ReadData(VMCodeInp);
  473     if (VMCodeSize>=0x10000 || VMCodeSize==0 || VMCodeInp.InAddr+VMCodeSize>CodeSize)
  474       return false;
  475     Array<byte> VMCode(VMCodeSize);
  476     for (uint I=0;I<VMCodeSize;I++)
  477     {
  478       if (VMCodeInp.Overflow(3))
  479         return false;
  480       VMCode[I]=VMCodeInp.fgetbits()>>8;
  481       VMCodeInp.faddbits(8);
  482     }
  483     VM.Prepare(&VMCode[0],VMCodeSize,&Filter->Prg);
  484   }
  485   StackFilter->Prg.Type=Filter->Prg.Type;
  486 
  487   return true;
  488 }
  489 
  490 
  491 bool Unpack::UnpReadBuf30()
  492 {
  493   int DataSize=ReadTop-Inp.InAddr; // Data left to process.
  494   if (DataSize<0)
  495     return false;
  496   if (Inp.InAddr>BitInput::MAX_SIZE/2)
  497   {
  498     // If we already processed more than half of buffer, let's move
  499     // remaining data into beginning to free more space for new data
  500     // and ensure that calling function does not cross the buffer border
  501     // even if we did not read anything here. Also it ensures that read size
  502     // is not less than CRYPT_BLOCK_SIZE, so we can align it without risk
  503     // to make it zero.
  504     if (DataSize>0)
  505       memmove(Inp.InBuf,Inp.InBuf+Inp.InAddr,DataSize);
  506     Inp.InAddr=0;
  507     ReadTop=DataSize;
  508   }
  509   else
  510     DataSize=ReadTop;
  511   int ReadCode=UnpIO->UnpRead(Inp.InBuf+DataSize,BitInput::MAX_SIZE-DataSize);
  512   if (ReadCode>0)
  513     ReadTop+=ReadCode;
  514   ReadBorder=ReadTop-30;
  515   return ReadCode!=-1;
  516 }
  517 
  518 
  519 void Unpack::UnpWriteBuf30()
  520 {
  521   uint WrittenBorder=(uint)WrPtr;
  522   uint WriteSize=(uint)((UnpPtr-WrittenBorder)&MaxWinMask);
  523   for (size_t I=0;I<PrgStack.Size();I++)
  524   {
  525     // Here we apply filters to data which we need to write.
  526     // We always copy data to virtual machine memory before processing.
  527     // We cannot process them just in place in Window buffer, because
  528     // these data can be used for future string matches, so we must
  529     // preserve them in original form.
  530 
  531     UnpackFilter30 *flt=PrgStack[I];
  532     if (flt==NULL)
  533       continue;
  534     if (flt->NextWindow)
  535     {
  536       flt->NextWindow=false;
  537       continue;
  538     }
  539     unsigned int BlockStart=flt->BlockStart;
  540     unsigned int BlockLength=flt->BlockLength;
  541     if (((BlockStart-WrittenBorder)&MaxWinMask)<WriteSize)
  542     {
  543       if (WrittenBorder!=BlockStart)
  544       {
  545         UnpWriteArea(WrittenBorder,BlockStart);
  546         WrittenBorder=BlockStart;
  547         WriteSize=(uint)((UnpPtr-WrittenBorder)&MaxWinMask);
  548       }
  549       if (BlockLength<=WriteSize)
  550       {
  551         uint BlockEnd=(BlockStart+BlockLength)&MaxWinMask;
  552         if (BlockStart<BlockEnd || BlockEnd==0)
  553           VM.SetMemory(0,Window+BlockStart,BlockLength);
  554         else
  555         {
  556           uint FirstPartLength=uint(MaxWinSize-BlockStart);
  557           VM.SetMemory(0,Window+BlockStart,FirstPartLength);
  558           VM.SetMemory(FirstPartLength,Window,BlockEnd);
  559         }
  560 
  561         VM_PreparedProgram *ParentPrg=&Filters30[flt->ParentFilter]->Prg;
  562         VM_PreparedProgram *Prg=&flt->Prg;
  563 
  564         ExecuteCode(Prg);
  565 
  566         byte *FilteredData=Prg->FilteredData;
  567         unsigned int FilteredDataSize=Prg->FilteredDataSize;
  568 
  569         delete PrgStack[I];
  570         PrgStack[I]=NULL;
  571         while (I+1<PrgStack.Size())
  572         {
  573           UnpackFilter30 *NextFilter=PrgStack[I+1];
  574           // It is required to check NextWindow here.
  575           if (NextFilter==NULL || NextFilter->BlockStart!=BlockStart ||
  576               NextFilter->BlockLength!=FilteredDataSize || NextFilter->NextWindow)
  577             break;
  578 
  579           // Apply several filters to same data block.
  580 
  581           VM.SetMemory(0,FilteredData,FilteredDataSize);
  582 
  583           VM_PreparedProgram *ParentPrg=&Filters30[NextFilter->ParentFilter]->Prg;
  584           VM_PreparedProgram *NextPrg=&NextFilter->Prg;
  585 
  586           ExecuteCode(NextPrg);
  587 
  588           FilteredData=NextPrg->FilteredData;
  589           FilteredDataSize=NextPrg->FilteredDataSize;
  590           I++;
  591           delete PrgStack[I];
  592           PrgStack[I]=NULL;
  593         }
  594         UnpIO->UnpWrite(FilteredData,FilteredDataSize);
  595         UnpSomeRead=true;
  596         WrittenFileSize+=FilteredDataSize;
  597         WrittenBorder=BlockEnd;
  598         WriteSize=uint((UnpPtr-WrittenBorder)&MaxWinMask);
  599       }
  600       else
  601       {
  602         // Current filter intersects the window write border, so we adjust
  603         // the window border to process this filter next time, not now.
  604         for (size_t J=I;J<PrgStack.Size();J++)
  605         {
  606           UnpackFilter30 *flt=PrgStack[J];
  607           if (flt!=NULL && flt->NextWindow)
  608             flt->NextWindow=false;
  609         }
  610         WrPtr=WrittenBorder;
  611         return;
  612       }
  613     }
  614   }
  615       
  616   UnpWriteArea(WrittenBorder,UnpPtr);
  617   WrPtr=UnpPtr;
  618 }
  619 
  620 
  621 void Unpack::ExecuteCode(VM_PreparedProgram *Prg)
  622 {
  623   Prg->InitR[6]=(uint)WrittenFileSize;
  624   VM.Execute(Prg);
  625 }
  626 
  627 
  628 bool Unpack::ReadTables30()
  629 {
  630   byte BitLength[BC];
  631   byte Table[HUFF_TABLE_SIZE30];
  632   if (Inp.InAddr>ReadTop-25)
  633     if (!UnpReadBuf30())
  634       return(false);
  635   Inp.faddbits((8-Inp.InBit)&7);
  636   uint BitField=Inp.fgetbits();
  637   if (BitField & 0x8000)
  638   {
  639     UnpBlockType=BLOCK_PPM;
  640     return(PPM.DecodeInit(this,PPMEscChar));
  641   }
  642   UnpBlockType=BLOCK_LZ;
  643   
  644   PrevLowDist=0;
  645   LowDistRepCount=0;
  646 
  647   if (!(BitField & 0x4000))
  648     memset(UnpOldTable,0,sizeof(UnpOldTable));
  649   Inp.faddbits(2);
  650 
  651   for (uint I=0;I<BC;I++)
  652   {
  653     uint Length=(byte)(Inp.fgetbits() >> 12);
  654     Inp.faddbits(4);
  655     if (Length==15)
  656     {
  657       uint ZeroCount=(byte)(Inp.fgetbits() >> 12);
  658       Inp.faddbits(4);
  659       if (ZeroCount==0)
  660         BitLength[I]=15;
  661       else
  662       {
  663         ZeroCount+=2;
  664         while (ZeroCount-- > 0 && I<ASIZE(BitLength))
  665           BitLength[I++]=0;
  666         I--;
  667       }
  668     }
  669     else
  670       BitLength[I]=Length;
  671   }
  672   MakeDecodeTables(BitLength,&BlockTables.BD,BC30);
  673 
  674   const uint TableSize=HUFF_TABLE_SIZE30;
  675   for (uint I=0;I<TableSize;)
  676   {
  677     if (Inp.InAddr>ReadTop-5)
  678       if (!UnpReadBuf30())
  679         return(false);
  680     uint Number=DecodeNumber(Inp,&BlockTables.BD);
  681     if (Number<16)
  682     {
  683       Table[I]=(Number+UnpOldTable[I]) & 0xf;
  684       I++;
  685     }
  686     else
  687       if (Number<18)
  688       {
  689         uint N;
  690         if (Number==16)
  691         {
  692           N=(Inp.fgetbits() >> 13)+3;
  693           Inp.faddbits(3);
  694         }
  695         else
  696         {
  697           N=(Inp.fgetbits() >> 9)+11;
  698           Inp.faddbits(7);
  699         }
  700         if (I==0)
  701           return false; // We cannot have "repeat previous" code at the first position.
  702         else
  703           while (N-- > 0 && I<TableSize)
  704           {
  705             Table[I]=Table[I-1];
  706             I++;
  707           }
  708       }
  709       else
  710       {
  711         uint N;
  712         if (Number==18)
  713         {
  714           N=(Inp.fgetbits() >> 13)+3;
  715           Inp.faddbits(3);
  716         }
  717         else
  718         {
  719           N=(Inp.fgetbits() >> 9)+11;
  720           Inp.faddbits(7);
  721         }
  722         while (N-- > 0 && I<TableSize)
  723           Table[I++]=0;
  724       }
  725   }
  726   TablesRead3=true;
  727   if (Inp.InAddr>ReadTop)
  728     return false;
  729   MakeDecodeTables(&Table[0],&BlockTables.LD,NC30);
  730   MakeDecodeTables(&Table[NC30],&BlockTables.DD,DC30);
  731   MakeDecodeTables(&Table[NC30+DC30],&BlockTables.LDD,LDC30);
  732   MakeDecodeTables(&Table[NC30+DC30+LDC30],&BlockTables.RD,RC30);
  733   memcpy(UnpOldTable,Table,sizeof(UnpOldTable));
  734   return true;
  735 }
  736 
  737 
  738 void Unpack::UnpInitData30(bool Solid)
  739 {
  740   if (!Solid)
  741   {
  742     TablesRead3=false;
  743     memset(UnpOldTable,0,sizeof(UnpOldTable));
  744     PPMEscChar=2;
  745     UnpBlockType=BLOCK_LZ;
  746   }
  747   InitFilters30(Solid);
  748 }
  749 
  750 
  751 void Unpack::InitFilters30(bool Solid)
  752 {
  753   if (!Solid)
  754   {
  755     OldFilterLengths.SoftReset();
  756     LastFilter=0;
  757 
  758     for (size_t I=0;I<Filters30.Size();I++)
  759       delete Filters30[I];
  760     Filters30.SoftReset();
  761   }
  762   for (size_t I=0;I<PrgStack.Size();I++)
  763     delete PrgStack[I];
  764   PrgStack.SoftReset();
  765 }