1
0

unpack15.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. #define STARTL1 2
  2. static unsigned int DecL1[]={0x8000,0xa000,0xc000,0xd000,0xe000,0xea00,
  3. 0xee00,0xf000,0xf200,0xf200,0xffff};
  4. static unsigned int PosL1[]={0,0,0,2,3,5,7,11,16,20,24,32,32};
  5. #define STARTL2 3
  6. static unsigned int DecL2[]={0xa000,0xc000,0xd000,0xe000,0xea00,0xee00,
  7. 0xf000,0xf200,0xf240,0xffff};
  8. static unsigned int PosL2[]={0,0,0,0,5,7,9,13,18,22,26,34,36};
  9. #define STARTHF0 4
  10. static unsigned int DecHf0[]={0x8000,0xc000,0xe000,0xf200,0xf200,0xf200,
  11. 0xf200,0xf200,0xffff};
  12. static unsigned int PosHf0[]={0,0,0,0,0,8,16,24,33,33,33,33,33};
  13. #define STARTHF1 5
  14. static unsigned int DecHf1[]={0x2000,0xc000,0xe000,0xf000,0xf200,0xf200,
  15. 0xf7e0,0xffff};
  16. static unsigned int PosHf1[]={0,0,0,0,0,0,4,44,60,76,80,80,127};
  17. #define STARTHF2 5
  18. static unsigned int DecHf2[]={0x1000,0x2400,0x8000,0xc000,0xfa00,0xffff,
  19. 0xffff,0xffff};
  20. static unsigned int PosHf2[]={0,0,0,0,0,0,2,7,53,117,233,0,0};
  21. #define STARTHF3 6
  22. static unsigned int DecHf3[]={0x800,0x2400,0xee00,0xfe80,0xffff,0xffff,
  23. 0xffff};
  24. static unsigned int PosHf3[]={0,0,0,0,0,0,0,2,16,218,251,0,0};
  25. #define STARTHF4 8
  26. static unsigned int DecHf4[]={0xff00,0xffff,0xffff,0xffff,0xffff,0xffff};
  27. static unsigned int PosHf4[]={0,0,0,0,0,0,0,0,0,255,0,0,0};
  28. void Unpack::Unpack15(bool Solid)
  29. {
  30. UnpInitData(Solid);
  31. UnpInitData15(Solid);
  32. UnpReadBuf();
  33. if (!Solid)
  34. {
  35. InitHuff();
  36. UnpPtr=0;
  37. }
  38. else
  39. UnpPtr=WrPtr;
  40. --DestUnpSize;
  41. if (DestUnpSize>=0)
  42. {
  43. GetFlagsBuf();
  44. FlagsCnt=8;
  45. }
  46. while (DestUnpSize>=0)
  47. {
  48. UnpPtr&=MaxWinMask;
  49. if (Inp.InAddr>ReadTop-30 && !UnpReadBuf())
  50. break;
  51. if (((WrPtr-UnpPtr) & MaxWinMask)<270 && WrPtr!=UnpPtr)
  52. UnpWriteBuf20();
  53. if (StMode)
  54. {
  55. HuffDecode();
  56. continue;
  57. }
  58. if (--FlagsCnt < 0)
  59. {
  60. GetFlagsBuf();
  61. FlagsCnt=7;
  62. }
  63. if (FlagBuf & 0x80)
  64. {
  65. FlagBuf<<=1;
  66. if (Nlzb > Nhfb)
  67. LongLZ();
  68. else
  69. HuffDecode();
  70. }
  71. else
  72. {
  73. FlagBuf<<=1;
  74. if (--FlagsCnt < 0)
  75. {
  76. GetFlagsBuf();
  77. FlagsCnt=7;
  78. }
  79. if (FlagBuf & 0x80)
  80. {
  81. FlagBuf<<=1;
  82. if (Nlzb > Nhfb)
  83. HuffDecode();
  84. else
  85. LongLZ();
  86. }
  87. else
  88. {
  89. FlagBuf<<=1;
  90. ShortLZ();
  91. }
  92. }
  93. }
  94. UnpWriteBuf20();
  95. }
  96. #define GetShortLen1(pos) ((pos)==1 ? Buf60+3:ShortLen1[pos])
  97. #define GetShortLen2(pos) ((pos)==3 ? Buf60+3:ShortLen2[pos])
  98. void Unpack::ShortLZ()
  99. {
  100. static unsigned int ShortLen1[]={1,3,4,4,5,6,7,8,8,4,4,5,6,6,4,0};
  101. static unsigned int ShortXor1[]={0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,
  102. 0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0};
  103. static unsigned int ShortLen2[]={2,3,3,3,4,4,5,6,6,4,4,5,6,6,4,0};
  104. static unsigned int ShortXor2[]={0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,
  105. 0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0};
  106. unsigned int Length,SaveLength;
  107. unsigned int LastDistance;
  108. unsigned int Distance;
  109. int DistancePlace;
  110. NumHuf=0;
  111. unsigned int BitField=Inp.fgetbits();
  112. if (LCount==2)
  113. {
  114. Inp.faddbits(1);
  115. if (BitField >= 0x8000)
  116. {
  117. CopyString15((unsigned int)LastDist,LastLength);
  118. return;
  119. }
  120. BitField <<= 1;
  121. LCount=0;
  122. }
  123. BitField>>=8;
  124. // not thread safe, replaced by GetShortLen1 and GetShortLen2 macro
  125. // ShortLen1[1]=ShortLen2[3]=Buf60+3;
  126. if (AvrLn1<37)
  127. {
  128. for (Length=0;;Length++)
  129. if (((BitField^ShortXor1[Length]) & (~(0xff>>GetShortLen1(Length))))==0)
  130. break;
  131. Inp.faddbits(GetShortLen1(Length));
  132. }
  133. else
  134. {
  135. for (Length=0;;Length++)
  136. if (((BitField^ShortXor2[Length]) & (~(0xff>>GetShortLen2(Length))))==0)
  137. break;
  138. Inp.faddbits(GetShortLen2(Length));
  139. }
  140. if (Length >= 9)
  141. {
  142. if (Length == 9)
  143. {
  144. LCount++;
  145. CopyString15((unsigned int)LastDist,LastLength);
  146. return;
  147. }
  148. if (Length == 14)
  149. {
  150. LCount=0;
  151. Length=DecodeNum(Inp.fgetbits(),STARTL2,DecL2,PosL2)+5;
  152. Distance=(Inp.fgetbits()>>1) | 0x8000;
  153. Inp.faddbits(15);
  154. LastLength=Length;
  155. LastDist=Distance;
  156. CopyString15(Distance,Length);
  157. return;
  158. }
  159. LCount=0;
  160. SaveLength=Length;
  161. Distance=OldDist[(OldDistPtr-(Length-9)) & 3];
  162. Length=DecodeNum(Inp.fgetbits(),STARTL1,DecL1,PosL1)+2;
  163. if (Length==0x101 && SaveLength==10)
  164. {
  165. Buf60 ^= 1;
  166. return;
  167. }
  168. if (Distance > 256)
  169. Length++;
  170. if (Distance >= MaxDist3)
  171. Length++;
  172. OldDist[OldDistPtr++]=Distance;
  173. OldDistPtr = OldDistPtr & 3;
  174. LastLength=Length;
  175. LastDist=Distance;
  176. CopyString15(Distance,Length);
  177. return;
  178. }
  179. LCount=0;
  180. AvrLn1 += Length;
  181. AvrLn1 -= AvrLn1 >> 4;
  182. DistancePlace=DecodeNum(Inp.fgetbits(),STARTHF2,DecHf2,PosHf2) & 0xff;
  183. Distance=ChSetA[DistancePlace];
  184. if (--DistancePlace != -1)
  185. {
  186. LastDistance=ChSetA[DistancePlace];
  187. ChSetA[DistancePlace+1]=LastDistance;
  188. ChSetA[DistancePlace]=Distance;
  189. }
  190. Length+=2;
  191. OldDist[OldDistPtr++] = ++Distance;
  192. OldDistPtr = OldDistPtr & 3;
  193. LastLength=Length;
  194. LastDist=Distance;
  195. CopyString15(Distance,Length);
  196. }
  197. void Unpack::LongLZ()
  198. {
  199. unsigned int Length;
  200. unsigned int Distance;
  201. unsigned int DistancePlace,NewDistancePlace;
  202. unsigned int OldAvr2,OldAvr3;
  203. NumHuf=0;
  204. Nlzb+=16;
  205. if (Nlzb > 0xff)
  206. {
  207. Nlzb=0x90;
  208. Nhfb >>= 1;
  209. }
  210. OldAvr2=AvrLn2;
  211. unsigned int BitField=Inp.fgetbits();
  212. if (AvrLn2 >= 122)
  213. Length=DecodeNum(BitField,STARTL2,DecL2,PosL2);
  214. else
  215. if (AvrLn2 >= 64)
  216. Length=DecodeNum(BitField,STARTL1,DecL1,PosL1);
  217. else
  218. if (BitField < 0x100)
  219. {
  220. Length=BitField;
  221. Inp.faddbits(16);
  222. }
  223. else
  224. {
  225. for (Length=0;((BitField<<Length)&0x8000)==0;Length++)
  226. ;
  227. Inp.faddbits(Length+1);
  228. }
  229. AvrLn2 += Length;
  230. AvrLn2 -= AvrLn2 >> 5;
  231. BitField=Inp.fgetbits();
  232. if (AvrPlcB > 0x28ff)
  233. DistancePlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2);
  234. else
  235. if (AvrPlcB > 0x6ff)
  236. DistancePlace=DecodeNum(BitField,STARTHF1,DecHf1,PosHf1);
  237. else
  238. DistancePlace=DecodeNum(BitField,STARTHF0,DecHf0,PosHf0);
  239. AvrPlcB += DistancePlace;
  240. AvrPlcB -= AvrPlcB >> 8;
  241. while (1)
  242. {
  243. Distance = ChSetB[DistancePlace & 0xff];
  244. NewDistancePlace = NToPlB[Distance++ & 0xff]++;
  245. if (!(Distance & 0xff))
  246. CorrHuff(ChSetB,NToPlB);
  247. else
  248. break;
  249. }
  250. ChSetB[DistancePlace & 0xff]=ChSetB[NewDistancePlace];
  251. ChSetB[NewDistancePlace]=Distance;
  252. Distance=((Distance & 0xff00) | (Inp.fgetbits() >> 8)) >> 1;
  253. Inp.faddbits(7);
  254. OldAvr3=AvrLn3;
  255. if (Length!=1 && Length!=4)
  256. if (Length==0 && Distance <= MaxDist3)
  257. {
  258. AvrLn3++;
  259. AvrLn3 -= AvrLn3 >> 8;
  260. }
  261. else
  262. if (AvrLn3 > 0)
  263. AvrLn3--;
  264. Length+=3;
  265. if (Distance >= MaxDist3)
  266. Length++;
  267. if (Distance <= 256)
  268. Length+=8;
  269. if (OldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && OldAvr2 < 0x40)
  270. MaxDist3=0x7f00;
  271. else
  272. MaxDist3=0x2001;
  273. OldDist[OldDistPtr++]=Distance;
  274. OldDistPtr = OldDistPtr & 3;
  275. LastLength=Length;
  276. LastDist=Distance;
  277. CopyString15(Distance,Length);
  278. }
  279. void Unpack::HuffDecode()
  280. {
  281. unsigned int CurByte,NewBytePlace;
  282. unsigned int Length;
  283. unsigned int Distance;
  284. int BytePlace;
  285. unsigned int BitField=Inp.fgetbits();
  286. if (AvrPlc > 0x75ff)
  287. BytePlace=DecodeNum(BitField,STARTHF4,DecHf4,PosHf4);
  288. else
  289. if (AvrPlc > 0x5dff)
  290. BytePlace=DecodeNum(BitField,STARTHF3,DecHf3,PosHf3);
  291. else
  292. if (AvrPlc > 0x35ff)
  293. BytePlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2);
  294. else
  295. if (AvrPlc > 0x0dff)
  296. BytePlace=DecodeNum(BitField,STARTHF1,DecHf1,PosHf1);
  297. else
  298. BytePlace=DecodeNum(BitField,STARTHF0,DecHf0,PosHf0);
  299. BytePlace&=0xff;
  300. if (StMode)
  301. {
  302. if (BytePlace==0 && BitField > 0xfff)
  303. BytePlace=0x100;
  304. if (--BytePlace==-1)
  305. {
  306. BitField=Inp.fgetbits();
  307. Inp.faddbits(1);
  308. if (BitField & 0x8000)
  309. {
  310. NumHuf=StMode=0;
  311. return;
  312. }
  313. else
  314. {
  315. Length = (BitField & 0x4000) ? 4 : 3;
  316. Inp.faddbits(1);
  317. Distance=DecodeNum(Inp.fgetbits(),STARTHF2,DecHf2,PosHf2);
  318. Distance = (Distance << 5) | (Inp.fgetbits() >> 11);
  319. Inp.faddbits(5);
  320. CopyString15(Distance,Length);
  321. return;
  322. }
  323. }
  324. }
  325. else
  326. if (NumHuf++ >= 16 && FlagsCnt==0)
  327. StMode=1;
  328. AvrPlc += BytePlace;
  329. AvrPlc -= AvrPlc >> 8;
  330. Nhfb+=16;
  331. if (Nhfb > 0xff)
  332. {
  333. Nhfb=0x90;
  334. Nlzb >>= 1;
  335. }
  336. Window[UnpPtr++]=(byte)(ChSet[BytePlace]>>8);
  337. --DestUnpSize;
  338. while (1)
  339. {
  340. CurByte=ChSet[BytePlace];
  341. NewBytePlace=NToPl[CurByte++ & 0xff]++;
  342. if ((CurByte & 0xff) > 0xa1)
  343. CorrHuff(ChSet,NToPl);
  344. else
  345. break;
  346. }
  347. ChSet[BytePlace]=ChSet[NewBytePlace];
  348. ChSet[NewBytePlace]=CurByte;
  349. }
  350. void Unpack::GetFlagsBuf()
  351. {
  352. unsigned int Flags,NewFlagsPlace;
  353. unsigned int FlagsPlace=DecodeNum(Inp.fgetbits(),STARTHF2,DecHf2,PosHf2);
  354. // Our Huffman table stores 257 items and needs all them in other parts
  355. // of code such as when StMode is on, so the first item is control item.
  356. // While normally we do not use the last item to code the flags byte here,
  357. // we need to check for value 256 when unpacking in case we unpack
  358. // a corrupt archive.
  359. if (FlagsPlace>=sizeof(ChSetC)/sizeof(ChSetC[0]))
  360. return;
  361. while (1)
  362. {
  363. Flags=ChSetC[FlagsPlace];
  364. FlagBuf=Flags>>8;
  365. NewFlagsPlace=NToPlC[Flags++ & 0xff]++;
  366. if ((Flags & 0xff) != 0)
  367. break;
  368. CorrHuff(ChSetC,NToPlC);
  369. }
  370. ChSetC[FlagsPlace]=ChSetC[NewFlagsPlace];
  371. ChSetC[NewFlagsPlace]=Flags;
  372. }
  373. void Unpack::UnpInitData15(int Solid)
  374. {
  375. if (!Solid)
  376. {
  377. AvrPlcB=AvrLn1=AvrLn2=AvrLn3=NumHuf=Buf60=0;
  378. AvrPlc=0x3500;
  379. MaxDist3=0x2001;
  380. Nhfb=Nlzb=0x80;
  381. }
  382. FlagsCnt=0;
  383. FlagBuf=0;
  384. StMode=0;
  385. LCount=0;
  386. ReadTop=0;
  387. }
  388. void Unpack::InitHuff()
  389. {
  390. for (unsigned int I=0;I<256;I++)
  391. {
  392. ChSet[I]=ChSetB[I]=I<<8;
  393. ChSetA[I]=I;
  394. ChSetC[I]=((~I+1) & 0xff)<<8;
  395. }
  396. memset(NToPl,0,sizeof(NToPl));
  397. memset(NToPlB,0,sizeof(NToPlB));
  398. memset(NToPlC,0,sizeof(NToPlC));
  399. CorrHuff(ChSetB,NToPlB);
  400. }
  401. void Unpack::CorrHuff(ushort *CharSet,byte *NumToPlace)
  402. {
  403. int I,J;
  404. for (I=7;I>=0;I--)
  405. for (J=0;J<32;J++,CharSet++)
  406. *CharSet=(*CharSet & ~0xff) | I;
  407. memset(NumToPlace,0,sizeof(NToPl));
  408. for (I=6;I>=0;I--)
  409. NumToPlace[I]=(7-I)*32;
  410. }
  411. void Unpack::CopyString15(uint Distance,uint Length)
  412. {
  413. DestUnpSize-=Length;
  414. while (Length--)
  415. {
  416. Window[UnpPtr]=Window[(UnpPtr-Distance) & MaxWinMask];
  417. UnpPtr=(UnpPtr+1) & MaxWinMask;
  418. }
  419. }
  420. uint Unpack::DecodeNum(uint Num,uint StartPos,uint *DecTab,uint *PosTab)
  421. {
  422. int I;
  423. for (Num&=0xfff0,I=0;DecTab[I]<=Num;I++)
  424. StartPos++;
  425. Inp.faddbits(StartPos);
  426. return(((Num-(I ? DecTab[I-1]:0))>>(16-StartPos))+PosTab[StartPos]);
  427. }