1
0

unpack50.cpp 19 KB

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