1
0

unpack20.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. #include "rar.hpp"
  2. void Unpack::CopyString20(uint Length,uint Distance)
  3. {
  4. LastDist=OldDist[OldDistPtr++]=Distance;
  5. OldDistPtr = OldDistPtr & 3; // Needed if RAR 1.5 file is called after RAR 2.0.
  6. LastLength=Length;
  7. DestUnpSize-=Length;
  8. CopyString(Length,Distance);
  9. }
  10. void Unpack::Unpack20(bool Solid)
  11. {
  12. 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};
  13. 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};
  14. static uint DDecode[]={0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040};
  15. static unsigned char DBits[]= {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
  16. static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
  17. static unsigned char SDBits[]= {2,2,3, 4, 5, 6, 6, 6};
  18. uint Bits;
  19. if (Suspended)
  20. UnpPtr=WrPtr;
  21. else
  22. {
  23. UnpInitData(Solid);
  24. if (!UnpReadBuf())
  25. return;
  26. if ((!Solid || !TablesRead2) && !ReadTables20())
  27. return;
  28. --DestUnpSize;
  29. }
  30. while (DestUnpSize>=0)
  31. {
  32. UnpPtr&=MaxWinMask;
  33. if (Inp.InAddr>ReadTop-30)
  34. if (!UnpReadBuf())
  35. break;
  36. if (((WrPtr-UnpPtr) & MaxWinMask)<270 && WrPtr!=UnpPtr)
  37. {
  38. UnpWriteBuf20();
  39. if (Suspended)
  40. return;
  41. }
  42. if (UnpAudioBlock)
  43. {
  44. uint AudioNumber=DecodeNumber(Inp,&MD[UnpCurChannel]);
  45. if (AudioNumber==256)
  46. {
  47. if (!ReadTables20())
  48. break;
  49. continue;
  50. }
  51. Window[UnpPtr++]=DecodeAudio((int)AudioNumber);
  52. if (++UnpCurChannel==UnpChannels)
  53. UnpCurChannel=0;
  54. --DestUnpSize;
  55. continue;
  56. }
  57. uint Number=DecodeNumber(Inp,&BlockTables.LD);
  58. if (Number<256)
  59. {
  60. Window[UnpPtr++]=(byte)Number;
  61. --DestUnpSize;
  62. continue;
  63. }
  64. if (Number>269)
  65. {
  66. uint Length=LDecode[Number-=270]+3;
  67. if ((Bits=LBits[Number])>0)
  68. {
  69. Length+=Inp.getbits()>>(16-Bits);
  70. Inp.addbits(Bits);
  71. }
  72. uint DistNumber=DecodeNumber(Inp,&BlockTables.DD);
  73. uint Distance=DDecode[DistNumber]+1;
  74. if ((Bits=DBits[DistNumber])>0)
  75. {
  76. Distance+=Inp.getbits()>>(16-Bits);
  77. Inp.addbits(Bits);
  78. }
  79. if (Distance>=0x2000)
  80. {
  81. Length++;
  82. if (Distance>=0x40000L)
  83. Length++;
  84. }
  85. CopyString20(Length,Distance);
  86. continue;
  87. }
  88. if (Number==269)
  89. {
  90. if (!ReadTables20())
  91. break;
  92. continue;
  93. }
  94. if (Number==256)
  95. {
  96. CopyString20(LastLength,LastDist);
  97. continue;
  98. }
  99. if (Number<261)
  100. {
  101. uint Distance=OldDist[(OldDistPtr-(Number-256)) & 3];
  102. uint LengthNumber=DecodeNumber(Inp,&BlockTables.RD);
  103. uint Length=LDecode[LengthNumber]+2;
  104. if ((Bits=LBits[LengthNumber])>0)
  105. {
  106. Length+=Inp.getbits()>>(16-Bits);
  107. Inp.addbits(Bits);
  108. }
  109. if (Distance>=0x101)
  110. {
  111. Length++;
  112. if (Distance>=0x2000)
  113. {
  114. Length++;
  115. if (Distance>=0x40000)
  116. Length++;
  117. }
  118. }
  119. CopyString20(Length,Distance);
  120. continue;
  121. }
  122. if (Number<270)
  123. {
  124. uint Distance=SDDecode[Number-=261]+1;
  125. if ((Bits=SDBits[Number])>0)
  126. {
  127. Distance+=Inp.getbits()>>(16-Bits);
  128. Inp.addbits(Bits);
  129. }
  130. CopyString20(2,Distance);
  131. continue;
  132. }
  133. }
  134. ReadLastTables();
  135. UnpWriteBuf20();
  136. }
  137. void Unpack::UnpWriteBuf20()
  138. {
  139. if (UnpPtr!=WrPtr)
  140. UnpSomeRead=true;
  141. if (UnpPtr<WrPtr)
  142. {
  143. UnpIO->UnpWrite(&Window[WrPtr],-(int)WrPtr & MaxWinMask);
  144. UnpIO->UnpWrite(Window,UnpPtr);
  145. UnpAllBuf=true;
  146. }
  147. else
  148. UnpIO->UnpWrite(&Window[WrPtr],UnpPtr-WrPtr);
  149. WrPtr=UnpPtr;
  150. }
  151. bool Unpack::ReadTables20()
  152. {
  153. byte BitLength[BC20];
  154. byte Table[MC20*4];
  155. if (Inp.InAddr>ReadTop-25)
  156. if (!UnpReadBuf())
  157. return false;
  158. uint BitField=Inp.getbits();
  159. UnpAudioBlock=(BitField & 0x8000)!=0;
  160. if (!(BitField & 0x4000))
  161. memset(UnpOldTable20,0,sizeof(UnpOldTable20));
  162. Inp.addbits(2);
  163. uint TableSize;
  164. if (UnpAudioBlock)
  165. {
  166. UnpChannels=((BitField>>12) & 3)+1;
  167. if (UnpCurChannel>=UnpChannels)
  168. UnpCurChannel=0;
  169. Inp.addbits(2);
  170. TableSize=MC20*UnpChannels;
  171. }
  172. else
  173. TableSize=NC20+DC20+RC20;
  174. for (uint I=0;I<BC20;I++)
  175. {
  176. BitLength[I]=(byte)(Inp.getbits() >> 12);
  177. Inp.addbits(4);
  178. }
  179. MakeDecodeTables(BitLength,&BlockTables.BD,BC20);
  180. for (uint I=0;I<TableSize;)
  181. {
  182. if (Inp.InAddr>ReadTop-5)
  183. if (!UnpReadBuf())
  184. return false;
  185. uint Number=DecodeNumber(Inp,&BlockTables.BD);
  186. if (Number<16)
  187. {
  188. Table[I]=(Number+UnpOldTable20[I]) & 0xf;
  189. I++;
  190. }
  191. else
  192. if (Number==16)
  193. {
  194. uint N=(Inp.getbits() >> 14)+3;
  195. Inp.addbits(2);
  196. if (I==0)
  197. return false; // We cannot have "repeat previous" code at the first position.
  198. else
  199. while (N-- > 0 && I<TableSize)
  200. {
  201. Table[I]=Table[I-1];
  202. I++;
  203. }
  204. }
  205. else
  206. {
  207. uint N;
  208. if (Number==17)
  209. {
  210. N=(Inp.getbits() >> 13)+3;
  211. Inp.addbits(3);
  212. }
  213. else
  214. {
  215. N=(Inp.getbits() >> 9)+11;
  216. Inp.addbits(7);
  217. }
  218. while (N-- > 0 && I<TableSize)
  219. Table[I++]=0;
  220. }
  221. }
  222. TablesRead2=true;
  223. if (Inp.InAddr>ReadTop)
  224. return true;
  225. if (UnpAudioBlock)
  226. for (uint I=0;I<UnpChannels;I++)
  227. MakeDecodeTables(&Table[I*MC20],&MD[I],MC20);
  228. else
  229. {
  230. MakeDecodeTables(&Table[0],&BlockTables.LD,NC20);
  231. MakeDecodeTables(&Table[NC20],&BlockTables.DD,DC20);
  232. MakeDecodeTables(&Table[NC20+DC20],&BlockTables.RD,RC20);
  233. }
  234. memcpy(UnpOldTable20,Table,TableSize);
  235. return true;
  236. }
  237. void Unpack::ReadLastTables()
  238. {
  239. if (ReadTop>=Inp.InAddr+5)
  240. if (UnpAudioBlock)
  241. {
  242. if (DecodeNumber(Inp,&MD[UnpCurChannel])==256)
  243. ReadTables20();
  244. }
  245. else
  246. if (DecodeNumber(Inp,&BlockTables.LD)==269)
  247. ReadTables20();
  248. }
  249. void Unpack::UnpInitData20(int Solid)
  250. {
  251. if (!Solid)
  252. {
  253. TablesRead2=false;
  254. UnpAudioBlock=false;
  255. UnpChannelDelta=0;
  256. UnpCurChannel=0;
  257. UnpChannels=1;
  258. memset(AudV,0,sizeof(AudV));
  259. memset(UnpOldTable20,0,sizeof(UnpOldTable20));
  260. memset(MD,0,sizeof(MD));
  261. }
  262. }
  263. byte Unpack::DecodeAudio(int Delta)
  264. {
  265. struct AudioVariables *V=&AudV[UnpCurChannel];
  266. V->ByteCount++;
  267. V->D4=V->D3;
  268. V->D3=V->D2;
  269. V->D2=V->LastDelta-V->D1;
  270. V->D1=V->LastDelta;
  271. int PCh=8*V->LastChar+V->K1*V->D1+V->K2*V->D2+V->K3*V->D3+V->K4*V->D4+V->K5*UnpChannelDelta;
  272. PCh=(PCh>>3) & 0xFF;
  273. uint Ch=PCh-Delta;
  274. int D=(signed char)Delta;
  275. // Left shift of negative value is undefined behavior in C++,
  276. // so we cast it to unsigned to follow the standard.
  277. D=(uint)D<<3;
  278. V->Dif[0]+=abs(D);
  279. V->Dif[1]+=abs(D-V->D1);
  280. V->Dif[2]+=abs(D+V->D1);
  281. V->Dif[3]+=abs(D-V->D2);
  282. V->Dif[4]+=abs(D+V->D2);
  283. V->Dif[5]+=abs(D-V->D3);
  284. V->Dif[6]+=abs(D+V->D3);
  285. V->Dif[7]+=abs(D-V->D4);
  286. V->Dif[8]+=abs(D+V->D4);
  287. V->Dif[9]+=abs(D-UnpChannelDelta);
  288. V->Dif[10]+=abs(D+UnpChannelDelta);
  289. UnpChannelDelta=V->LastDelta=(signed char)(Ch-V->LastChar);
  290. V->LastChar=Ch;
  291. if ((V->ByteCount & 0x1F)==0)
  292. {
  293. uint MinDif=V->Dif[0],NumMinDif=0;
  294. V->Dif[0]=0;
  295. for (uint I=1;I<ASIZE(V->Dif);I++)
  296. {
  297. if (V->Dif[I]<MinDif)
  298. {
  299. MinDif=V->Dif[I];
  300. NumMinDif=I;
  301. }
  302. V->Dif[I]=0;
  303. }
  304. switch(NumMinDif)
  305. {
  306. case 1:
  307. if (V->K1>=-16)
  308. V->K1--;
  309. break;
  310. case 2:
  311. if (V->K1<16)
  312. V->K1++;
  313. break;
  314. case 3:
  315. if (V->K2>=-16)
  316. V->K2--;
  317. break;
  318. case 4:
  319. if (V->K2<16)
  320. V->K2++;
  321. break;
  322. case 5:
  323. if (V->K3>=-16)
  324. V->K3--;
  325. break;
  326. case 6:
  327. if (V->K3<16)
  328. V->K3++;
  329. break;
  330. case 7:
  331. if (V->K4>=-16)
  332. V->K4--;
  333. break;
  334. case 8:
  335. if (V->K4<16)
  336. V->K4++;
  337. break;
  338. case 9:
  339. if (V->K5>=-16)
  340. V->K5--;
  341. break;
  342. case 10:
  343. if (V->K5<16)
  344. V->K5++;
  345. break;
  346. }
  347. }
  348. return (byte)Ch;
  349. }