unpack30.cpp 19 KB

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