"Fossies" - the Fresh Open Source Software Archive

Member "unrar/unpack50.cpp" (4 May 2022, 19147 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 "unpack50.cpp" see the Fossies "Dox" file reference documentation.

    1 void Unpack::Unpack5(bool Solid)
    2 {
    3   FileExtracted=true;
    4 
    5   if (!Suspended)
    6   {
    7     UnpInitData(Solid);
    8     if (!UnpReadBuf())
    9       return;
   10 
   11     // Check TablesRead5 to be sure that we read tables at least once
   12     // regardless of current block header TablePresent flag.
   13     // So we can safefly use these tables below.
   14     if (!ReadBlockHeader(Inp,BlockHeader) ||
   15         !ReadTables(Inp,BlockHeader,BlockTables) || !TablesRead5)
   16       return;
   17   }
   18 
   19   while (true)
   20   {
   21     UnpPtr&=MaxWinMask;
   22 
   23     if (Inp.InAddr>=ReadBorder)
   24     {
   25       bool FileDone=false;
   26 
   27       // We use 'while', because for empty block containing only Huffman table,
   28       // we'll be on the block border once again just after reading the table.
   29       while (Inp.InAddr>BlockHeader.BlockStart+BlockHeader.BlockSize-1 || 
   30              Inp.InAddr==BlockHeader.BlockStart+BlockHeader.BlockSize-1 && 
   31              Inp.InBit>=BlockHeader.BlockBitSize)
   32       {
   33         if (BlockHeader.LastBlockInFile)
   34         {
   35           FileDone=true;
   36           break;
   37         }
   38         if (!ReadBlockHeader(Inp,BlockHeader) || !ReadTables(Inp,BlockHeader,BlockTables))
   39           return;
   40       }
   41       if (FileDone || !UnpReadBuf())
   42         break;
   43     }
   44 
   45     if (((WriteBorder-UnpPtr) & MaxWinMask)<MAX_INC_LZ_MATCH && WriteBorder!=UnpPtr)
   46     {
   47       UnpWriteBuf();
   48       if (WrittenFileSize>DestUnpSize)
   49         return;
   50       if (Suspended)
   51       {
   52         FileExtracted=false;
   53         return;
   54       }
   55     }
   56 
   57     uint MainSlot=DecodeNumber(Inp,&BlockTables.LD);
   58     if (MainSlot<256)
   59     {
   60       if (Fragmented)
   61         FragWindow[UnpPtr++]=(byte)MainSlot;
   62       else
   63         Window[UnpPtr++]=(byte)MainSlot;
   64       continue;
   65     }
   66     if (MainSlot>=262)
   67     {
   68       uint Length=SlotToLength(Inp,MainSlot-262);
   69 
   70       uint DBits,Distance=1,DistSlot=DecodeNumber(Inp,&BlockTables.DD);
   71       if (DistSlot<4)
   72       {
   73         DBits=0;
   74         Distance+=DistSlot;
   75       }
   76       else
   77       {
   78         DBits=DistSlot/2 - 1;
   79         Distance+=(2 | (DistSlot & 1)) << DBits;
   80       }
   81 
   82       if (DBits>0)
   83       {
   84         if (DBits>=4)
   85         {
   86           if (DBits>4)
   87           {
   88             Distance+=((Inp.getbits32()>>(36-DBits))<<4);
   89             Inp.addbits(DBits-4);
   90           }
   91           uint LowDist=DecodeNumber(Inp,&BlockTables.LDD);
   92           Distance+=LowDist;
   93         }
   94         else
   95         {
   96           Distance+=Inp.getbits32()>>(32-DBits);
   97           Inp.addbits(DBits);
   98         }
   99       }
  100 
  101       if (Distance>0x100)
  102       {
  103         Length++;
  104         if (Distance>0x2000)
  105         {
  106           Length++;
  107           if (Distance>0x40000)
  108             Length++;
  109         }
  110       }
  111 
  112       InsertOldDist(Distance);
  113       LastLength=Length;
  114       if (Fragmented)
  115         FragWindow.CopyString(Length,Distance,UnpPtr,MaxWinMask);
  116       else
  117         CopyString(Length,Distance);
  118       continue;
  119     }
  120     if (MainSlot==256)
  121     {
  122       UnpackFilter Filter;
  123       if (!ReadFilter(Inp,Filter) || !AddFilter(Filter))
  124         break;
  125       continue;
  126     }
  127     if (MainSlot==257)
  128     {
  129       if (LastLength!=0)
  130         if (Fragmented)
  131           FragWindow.CopyString(LastLength,OldDist[0],UnpPtr,MaxWinMask);
  132         else
  133           CopyString(LastLength,OldDist[0]);
  134       continue;
  135     }
  136     if (MainSlot<262)
  137     {
  138       uint DistNum=MainSlot-258;
  139       uint Distance=OldDist[DistNum];
  140       for (uint I=DistNum;I>0;I--)
  141         OldDist[I]=OldDist[I-1];
  142       OldDist[0]=Distance;
  143 
  144       uint LengthSlot=DecodeNumber(Inp,&BlockTables.RD);
  145       uint Length=SlotToLength(Inp,LengthSlot);
  146       LastLength=Length;
  147       if (Fragmented)
  148         FragWindow.CopyString(Length,Distance,UnpPtr,MaxWinMask);
  149       else
  150         CopyString(Length,Distance);
  151       continue;
  152     }
  153   }
  154   UnpWriteBuf();
  155 }
  156 
  157 
  158 uint Unpack::ReadFilterData(BitInput &Inp)
  159 {
  160   uint ByteCount=(Inp.fgetbits()>>14)+1;
  161   Inp.addbits(2);
  162 
  163   uint Data=0;
  164   for (uint I=0;I<ByteCount;I++)
  165   {
  166     Data+=(Inp.fgetbits()>>8)<<(I*8);
  167     Inp.addbits(8);
  168   }
  169   return Data;
  170 }
  171 
  172 
  173 bool Unpack::ReadFilter(BitInput &Inp,UnpackFilter &Filter)
  174 {
  175   if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop-16)
  176     if (!UnpReadBuf())
  177       return false;
  178 
  179   Filter.BlockStart=ReadFilterData(Inp);
  180   Filter.BlockLength=ReadFilterData(Inp);
  181   if (Filter.BlockLength>MAX_FILTER_BLOCK_SIZE)
  182     Filter.BlockLength=0;
  183 
  184   Filter.Type=Inp.fgetbits()>>13;
  185   Inp.faddbits(3);
  186 
  187   if (Filter.Type==FILTER_DELTA)
  188   {
  189     Filter.Channels=(Inp.fgetbits()>>11)+1;
  190     Inp.faddbits(5);
  191   }
  192 
  193   return true;
  194 }
  195 
  196 
  197 bool Unpack::AddFilter(UnpackFilter &Filter)
  198 {
  199   if (Filters.Size()>=MAX_UNPACK_FILTERS)
  200   {
  201     UnpWriteBuf(); // Write data, apply and flush filters.
  202     if (Filters.Size()>=MAX_UNPACK_FILTERS)
  203       InitFilters(); // Still too many filters, prevent excessive memory use.
  204   }
  205 
  206   // If distance to filter start is that large that due to circular dictionary
  207   // mode now it points to old not written yet data, then we set 'NextWindow'
  208   // flag and process this filter only after processing that older data.
  209   Filter.NextWindow=WrPtr!=UnpPtr && ((WrPtr-UnpPtr)&MaxWinMask)<=Filter.BlockStart;
  210 
  211   Filter.BlockStart=uint((Filter.BlockStart+UnpPtr)&MaxWinMask);
  212   Filters.Push(Filter);
  213   return true;
  214 }
  215 
  216 
  217 bool Unpack::UnpReadBuf()
  218 {
  219   int DataSize=ReadTop-Inp.InAddr; // Data left to process.
  220   if (DataSize<0)
  221     return false;
  222   BlockHeader.BlockSize-=Inp.InAddr-BlockHeader.BlockStart;
  223   if (Inp.InAddr>BitInput::MAX_SIZE/2)
  224   {
  225     // If we already processed more than half of buffer, let's move
  226     // remaining data into beginning to free more space for new data
  227     // and ensure that calling function does not cross the buffer border
  228     // even if we did not read anything here. Also it ensures that read size
  229     // is not less than CRYPT_BLOCK_SIZE, so we can align it without risk
  230     // to make it zero.
  231     if (DataSize>0)
  232       memmove(Inp.InBuf,Inp.InBuf+Inp.InAddr,DataSize);
  233     Inp.InAddr=0;
  234     ReadTop=DataSize;
  235   }
  236   else
  237     DataSize=ReadTop;
  238   int ReadCode=0;
  239   if (BitInput::MAX_SIZE!=DataSize)
  240     ReadCode=UnpIO->UnpRead(Inp.InBuf+DataSize,BitInput::MAX_SIZE-DataSize);
  241   if (ReadCode>0) // Can be also -1.
  242     ReadTop+=ReadCode;
  243   ReadBorder=ReadTop-30;
  244   BlockHeader.BlockStart=Inp.InAddr;
  245   if (BlockHeader.BlockSize!=-1) // '-1' means not defined yet.
  246   {
  247     // We may need to quit from main extraction loop and read new block header
  248     // and trees earlier than data in input buffer ends.
  249     ReadBorder=Min(ReadBorder,BlockHeader.BlockStart+BlockHeader.BlockSize-1);
  250   }
  251   return ReadCode!=-1;
  252 }
  253 
  254 
  255 void Unpack::UnpWriteBuf()
  256 {
  257   size_t WrittenBorder=WrPtr;
  258   size_t FullWriteSize=(UnpPtr-WrittenBorder)&MaxWinMask;
  259   size_t WriteSizeLeft=FullWriteSize;
  260   bool NotAllFiltersProcessed=false;
  261   for (size_t I=0;I<Filters.Size();I++)
  262   {
  263     // Here we apply filters to data which we need to write.
  264     // We always copy data to another memory block before processing.
  265     // We cannot process them just in place in Window buffer, because
  266     // these data can be used for future string matches, so we must
  267     // preserve them in original form.
  268 
  269     UnpackFilter *flt=&Filters[I];
  270     if (flt->Type==FILTER_NONE)
  271       continue;
  272     if (flt->NextWindow)
  273     {
  274       // Here we skip filters which have block start in current data range
  275       // due to address wrap around in circular dictionary, but actually
  276       // belong to next dictionary block. If such filter start position
  277       // is included to current write range, then we reset 'NextWindow' flag.
  278       // In fact we can reset it even without such check, because current
  279       // implementation seems to guarantee 'NextWindow' flag reset after
  280       // buffer writing for all existing filters. But let's keep this check
  281       // just in case. Compressor guarantees that distance between
  282       // filter block start and filter storing position cannot exceed
  283       // the dictionary size. So if we covered the filter block start with
  284       // our write here, we can safely assume that filter is applicable
  285       // to next block on no further wrap arounds is possible.
  286       if (((flt->BlockStart-WrPtr)&MaxWinMask)<=FullWriteSize)
  287         flt->NextWindow=false;
  288       continue;
  289     }
  290     uint BlockStart=flt->BlockStart;
  291     uint BlockLength=flt->BlockLength;
  292     if (((BlockStart-WrittenBorder)&MaxWinMask)<WriteSizeLeft)
  293     {
  294       if (WrittenBorder!=BlockStart)
  295       {
  296         UnpWriteArea(WrittenBorder,BlockStart);
  297         WrittenBorder=BlockStart;
  298         WriteSizeLeft=(UnpPtr-WrittenBorder)&MaxWinMask;
  299       }
  300       if (BlockLength<=WriteSizeLeft)
  301       {
  302         if (BlockLength>0) // We set it to 0 also for invalid filters.
  303         {
  304           uint BlockEnd=(BlockStart+BlockLength)&MaxWinMask;
  305 
  306           FilterSrcMemory.Alloc(BlockLength);
  307           byte *Mem=&FilterSrcMemory[0];
  308           if (BlockStart<BlockEnd || BlockEnd==0)
  309           {
  310             if (Fragmented)
  311               FragWindow.CopyData(Mem,BlockStart,BlockLength);
  312             else
  313               memcpy(Mem,Window+BlockStart,BlockLength);
  314           }
  315           else
  316           {
  317             size_t FirstPartLength=size_t(MaxWinSize-BlockStart);
  318             if (Fragmented)
  319             {
  320               FragWindow.CopyData(Mem,BlockStart,FirstPartLength);
  321               FragWindow.CopyData(Mem+FirstPartLength,0,BlockEnd);
  322             }
  323             else
  324             {
  325               memcpy(Mem,Window+BlockStart,FirstPartLength);
  326               memcpy(Mem+FirstPartLength,Window,BlockEnd);
  327             }
  328           }
  329 
  330           byte *OutMem=ApplyFilter(Mem,BlockLength,flt);
  331 
  332           Filters[I].Type=FILTER_NONE;
  333 
  334           if (OutMem!=NULL)
  335             UnpIO->UnpWrite(OutMem,BlockLength);
  336 
  337           UnpSomeRead=true;
  338           WrittenFileSize+=BlockLength;
  339           WrittenBorder=BlockEnd;
  340           WriteSizeLeft=(UnpPtr-WrittenBorder)&MaxWinMask;
  341         }
  342       }
  343       else
  344       {
  345         // Current filter intersects the window write border, so we adjust
  346         // the window border to process this filter next time, not now.
  347         WrPtr=WrittenBorder;
  348 
  349         // Since Filter start position can only increase, we quit processing
  350         // all following filters for this data block and reset 'NextWindow'
  351         // flag for them.
  352         for (size_t J=I;J<Filters.Size();J++)
  353         {
  354           UnpackFilter *flt=&Filters[J];
  355           if (flt->Type!=FILTER_NONE)
  356             flt->NextWindow=false;
  357         }
  358 
  359         // Do not write data left after current filter now.
  360         NotAllFiltersProcessed=true;
  361         break;
  362       }
  363     }
  364   }
  365 
  366   // Remove processed filters from queue.
  367   size_t EmptyCount=0;
  368   for (size_t I=0;I<Filters.Size();I++)
  369   {
  370     if (EmptyCount>0)
  371       Filters[I-EmptyCount]=Filters[I];
  372     if (Filters[I].Type==FILTER_NONE)
  373       EmptyCount++;
  374   }
  375   if (EmptyCount>0)
  376     Filters.Alloc(Filters.Size()-EmptyCount);
  377 
  378   if (!NotAllFiltersProcessed) // Only if all filters are processed.
  379   {
  380     // Write data left after last filter.
  381     UnpWriteArea(WrittenBorder,UnpPtr);
  382     WrPtr=UnpPtr;
  383   }
  384 
  385   // We prefer to write data in blocks not exceeding UNPACK_MAX_WRITE
  386   // instead of potentially huge MaxWinSize blocks. It also allows us
  387   // to keep the size of Filters array reasonable.
  388   WriteBorder=(UnpPtr+Min(MaxWinSize,UNPACK_MAX_WRITE))&MaxWinMask;
  389 
  390   // Choose the nearest among WriteBorder and WrPtr actual written border.
  391   // If border is equal to UnpPtr, it means that we have MaxWinSize data ahead.
  392   if (WriteBorder==UnpPtr || 
  393       WrPtr!=UnpPtr && ((WrPtr-UnpPtr)&MaxWinMask)<((WriteBorder-UnpPtr)&MaxWinMask))
  394     WriteBorder=WrPtr;
  395 }
  396 
  397 
  398 byte* Unpack::ApplyFilter(byte *Data,uint DataSize,UnpackFilter *Flt)
  399 {
  400   byte *SrcData=Data;
  401   switch(Flt->Type)
  402   {
  403     case FILTER_E8:
  404     case FILTER_E8E9:
  405       {
  406         uint FileOffset=(uint)WrittenFileSize;
  407 
  408         const uint FileSize=0x1000000;
  409         byte CmpByte2=Flt->Type==FILTER_E8E9 ? 0xe9:0xe8;
  410         // DataSize is unsigned, so we use "CurPos+4" and not "DataSize-4"
  411         // to avoid overflow for DataSize<4.
  412         for (uint CurPos=0;CurPos+4<DataSize;)
  413         {
  414           byte CurByte=*(Data++);
  415           CurPos++;
  416           if (CurByte==0xe8 || CurByte==CmpByte2)
  417           {
  418             uint Offset=(CurPos+FileOffset)%FileSize;
  419             uint Addr=RawGet4(Data);
  420 
  421             // We check 0x80000000 bit instead of '< 0' comparison
  422             // not assuming int32 presence or uint size and endianness.
  423             if ((Addr & 0x80000000)!=0)              // Addr<0
  424             {
  425               if (((Addr+Offset) & 0x80000000)==0)   // Addr+Offset>=0
  426                 RawPut4(Addr+FileSize,Data);
  427             }
  428             else
  429               if (((Addr-FileSize) & 0x80000000)!=0) // Addr<FileSize
  430                 RawPut4(Addr-Offset,Data);
  431 
  432             Data+=4;
  433             CurPos+=4;
  434           }
  435         }
  436       }
  437       return SrcData;
  438     case FILTER_ARM:
  439       // 2019-11-15: we turned off ARM filter by default when compressing,
  440       // mostly because it is inefficient for modern 64 bit ARM binaries.
  441       // It was turned on by default in 5.0 - 5.80b3 , so we still need it
  442       // here for compatibility with some of previously created archives.
  443       {
  444         uint FileOffset=(uint)WrittenFileSize;
  445         // DataSize is unsigned, so we use "CurPos+3" and not "DataSize-3"
  446         // to avoid overflow for DataSize<3.
  447         for (uint CurPos=0;CurPos+3<DataSize;CurPos+=4)
  448         {
  449           byte *D=Data+CurPos;
  450           if (D[3]==0xeb) // BL command with '1110' (Always) condition.
  451           {
  452             uint Offset=D[0]+uint(D[1])*0x100+uint(D[2])*0x10000;
  453             Offset-=(FileOffset+CurPos)/4;
  454             D[0]=(byte)Offset;
  455             D[1]=(byte)(Offset>>8);
  456             D[2]=(byte)(Offset>>16);
  457           }
  458         }
  459       }
  460       return SrcData;
  461     case FILTER_DELTA:
  462       {
  463         // Unlike RAR3, we do not need to reject excessive channel
  464         // values here, since RAR5 uses only 5 bits to store channel.
  465         uint Channels=Flt->Channels,SrcPos=0;
  466 
  467         FilterDstMemory.Alloc(DataSize);
  468         byte *DstData=&FilterDstMemory[0];
  469 
  470         // Bytes from same channels are grouped to continual data blocks,
  471         // so we need to place them back to their interleaving positions.
  472         for (uint CurChannel=0;CurChannel<Channels;CurChannel++)
  473         {
  474           byte PrevByte=0;
  475           for (uint DestPos=CurChannel;DestPos<DataSize;DestPos+=Channels)
  476             DstData[DestPos]=(PrevByte-=Data[SrcPos++]);
  477         }
  478         return DstData;
  479       }
  480 
  481   }
  482   return NULL;
  483 }
  484 
  485 
  486 void Unpack::UnpWriteArea(size_t StartPtr,size_t EndPtr)
  487 {
  488   if (EndPtr!=StartPtr)
  489     UnpSomeRead=true;
  490   if (EndPtr<StartPtr)
  491     UnpAllBuf=true;
  492 
  493   if (Fragmented)
  494   {
  495     size_t SizeToWrite=(EndPtr-StartPtr) & MaxWinMask;
  496     while (SizeToWrite>0)
  497     {
  498       size_t BlockSize=FragWindow.GetBlockSize(StartPtr,SizeToWrite);
  499       UnpWriteData(&FragWindow[StartPtr],BlockSize);
  500       SizeToWrite-=BlockSize;
  501       StartPtr=(StartPtr+BlockSize) & MaxWinMask;
  502     }
  503   }
  504   else
  505     if (EndPtr<StartPtr)
  506     {
  507       UnpWriteData(Window+StartPtr,MaxWinSize-StartPtr);
  508       UnpWriteData(Window,EndPtr);
  509     }
  510     else
  511       UnpWriteData(Window+StartPtr,EndPtr-StartPtr);
  512 }
  513 
  514 
  515 void Unpack::UnpWriteData(byte *Data,size_t Size)
  516 {
  517   if (WrittenFileSize>=DestUnpSize)
  518     return;
  519   size_t WriteSize=Size;
  520   int64 LeftToWrite=DestUnpSize-WrittenFileSize;
  521   if ((int64)WriteSize>LeftToWrite)
  522     WriteSize=(size_t)LeftToWrite;
  523   UnpIO->UnpWrite(Data,WriteSize);
  524   WrittenFileSize+=Size;
  525 }
  526 
  527 
  528 void Unpack::UnpInitData50(bool Solid)
  529 {
  530   if (!Solid)
  531     TablesRead5=false;
  532 }
  533 
  534 
  535 bool Unpack::ReadBlockHeader(BitInput &Inp,UnpackBlockHeader &Header)
  536 {
  537   Header.HeaderSize=0;
  538 
  539   if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop-7)
  540     if (!UnpReadBuf())
  541       return false;
  542   Inp.faddbits((8-Inp.InBit)&7);
  543 
  544   byte BlockFlags=Inp.fgetbits()>>8;
  545   Inp.faddbits(8);
  546   uint ByteCount=((BlockFlags>>3)&3)+1; // Block size byte count.
  547 
  548   if (ByteCount==4)
  549     return false;
  550 
  551   Header.HeaderSize=2+ByteCount;
  552 
  553   Header.BlockBitSize=(BlockFlags&7)+1;
  554 
  555   byte SavedCheckSum=Inp.fgetbits()>>8;
  556   Inp.faddbits(8);
  557 
  558   int BlockSize=0;
  559   for (uint I=0;I<ByteCount;I++)
  560   {
  561     BlockSize+=(Inp.fgetbits()>>8)<<(I*8);
  562     Inp.addbits(8);
  563   }
  564 
  565   Header.BlockSize=BlockSize;
  566   byte CheckSum=byte(0x5a^BlockFlags^BlockSize^(BlockSize>>8)^(BlockSize>>16));
  567   if (CheckSum!=SavedCheckSum)
  568     return false;
  569 
  570   Header.BlockStart=Inp.InAddr;
  571   ReadBorder=Min(ReadBorder,Header.BlockStart+Header.BlockSize-1);
  572 
  573   Header.LastBlockInFile=(BlockFlags & 0x40)!=0;
  574   Header.TablePresent=(BlockFlags & 0x80)!=0;
  575   return true;
  576 }
  577 
  578 
  579 bool Unpack::ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTables &Tables)
  580 {
  581   if (!Header.TablePresent)
  582     return true;
  583 
  584   if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop-25)
  585     if (!UnpReadBuf())
  586       return false;
  587 
  588   byte BitLength[BC];
  589   for (uint I=0;I<BC;I++)
  590   {
  591     uint Length=(byte)(Inp.fgetbits() >> 12);
  592     Inp.faddbits(4);
  593     if (Length==15)
  594     {
  595       uint ZeroCount=(byte)(Inp.fgetbits() >> 12);
  596       Inp.faddbits(4);
  597       if (ZeroCount==0)
  598         BitLength[I]=15;
  599       else
  600       {
  601         ZeroCount+=2;
  602         while (ZeroCount-- > 0 && I<ASIZE(BitLength))
  603           BitLength[I++]=0;
  604         I--;
  605       }
  606     }
  607     else
  608       BitLength[I]=Length;
  609   }
  610 
  611   MakeDecodeTables(BitLength,&Tables.BD,BC);
  612 
  613   byte Table[HUFF_TABLE_SIZE];
  614   const uint TableSize=HUFF_TABLE_SIZE;
  615   for (uint I=0;I<TableSize;)
  616   {
  617     if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop-5)
  618       if (!UnpReadBuf())
  619         return false;
  620     uint Number=DecodeNumber(Inp,&Tables.BD);
  621     if (Number<16)
  622     {
  623       Table[I]=Number;
  624       I++;
  625     }
  626     else
  627       if (Number<18)
  628       {
  629         uint N;
  630         if (Number==16)
  631         {
  632           N=(Inp.fgetbits() >> 13)+3;
  633           Inp.faddbits(3);
  634         }
  635         else
  636         {
  637           N=(Inp.fgetbits() >> 9)+11;
  638           Inp.faddbits(7);
  639         }
  640         if (I==0)
  641         {
  642           // We cannot have "repeat previous" code at the first position.
  643           // Multiple such codes would shift Inp position without changing I,
  644           // which can lead to reading beyond of Inp boundary in mutithreading
  645           // mode, where Inp.ExternalBuffer disables bounds check and we just
  646           // reserve a lot of buffer space to not need such check normally.
  647           return false;
  648         }
  649         else
  650           while (N-- > 0 && I<TableSize)
  651           {
  652             Table[I]=Table[I-1];
  653             I++;
  654           }
  655       }
  656       else
  657       {
  658         uint N;
  659         if (Number==18)
  660         {
  661           N=(Inp.fgetbits() >> 13)+3;
  662           Inp.faddbits(3);
  663         }
  664         else
  665         {
  666           N=(Inp.fgetbits() >> 9)+11;
  667           Inp.faddbits(7);
  668         }
  669         while (N-- > 0 && I<TableSize)
  670           Table[I++]=0;
  671       }
  672   }
  673   TablesRead5=true;
  674   if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop)
  675     return false;
  676   MakeDecodeTables(&Table[0],&Tables.LD,NC);
  677   MakeDecodeTables(&Table[NC],&Tables.DD,DC);
  678   MakeDecodeTables(&Table[NC+DC],&Tables.LDD,LDC);
  679   MakeDecodeTables(&Table[NC+DC+LDC],&Tables.RD,RC);
  680   return true;
  681 }
  682 
  683 
  684 void Unpack::InitFilters()
  685 {
  686   Filters.SoftReset();
  687 }