infcodes.pas 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. unit infcodes;
  2. { infcodes.c -- process literals and length/distance pairs
  3. Copyright (C) 1995-1998 Mark Adler
  4. Pascal tranlastion
  5. Copyright (C) 1998 by Jacques Nomssi Nzali
  6. For conditions of distribution and use, see copyright notice in readme.txt
  7. }
  8. interface
  9. {$I zconf.inc}
  10. uses
  11. zbase;
  12. function inflate_codes_new (bl : cardinal;
  13. bd : cardinal;
  14. tl : pInflate_huft;
  15. td : pInflate_huft;
  16. var z : z_stream): pInflate_codes_state;
  17. function inflate_codes(var s : inflate_blocks_state;
  18. var z : z_stream;
  19. r : integer) : integer;
  20. procedure inflate_codes_free(var c : pInflate_codes_state;
  21. var z : z_stream);
  22. implementation
  23. uses
  24. infutil, inffast{$IFDEF ZLIB_DEBUG}, SysUtils{$ENDIF};
  25. function inflate_codes_new (bl : cardinal;
  26. bd : cardinal;
  27. tl : pInflate_huft;
  28. td : pInflate_huft;
  29. var z : z_stream): pInflate_codes_state;
  30. var
  31. c : pInflate_codes_state;
  32. begin
  33. new(c);
  34. if c<>nil then
  35. begin
  36. c^.mode := START;
  37. c^.lbits := Byte(bl);
  38. c^.dbits := Byte(bd);
  39. c^.ltree := tl;
  40. c^.dtree := td;
  41. {$IFDEF ZLIB_DEBUG}
  42. Tracev('inflate: codes new');
  43. {$ENDIF}
  44. end;
  45. inflate_codes_new := c;
  46. end;
  47. function inflate_codes(var s : inflate_blocks_state;
  48. var z : z_stream;
  49. r : integer) : integer;
  50. var
  51. j : cardinal; { temporary storage }
  52. t : pInflate_huft; { temporary pointer }
  53. e : cardinal; { extra bits or operation }
  54. b : cardinal; { bit buffer }
  55. k : cardinal; { bits in bit buffer }
  56. p : Pbyte; { input data pointer }
  57. n : cardinal; { bytes available there }
  58. q : Pbyte; { output window write pointer }
  59. m : cardinal; { bytes to end of window or read pointer }
  60. f : Pbyte; { pointer to copy strings from }
  61. var
  62. c : pInflate_codes_state;
  63. begin
  64. c := s.sub.decode.codes; { codes state }
  65. { copy input/output information to locals }
  66. p := z.next_in;
  67. n := z.avail_in;
  68. b := s.bitb;
  69. k := s.bitk;
  70. q := s.write;
  71. if ptruint(q) < ptruint(s.read) then
  72. m := cardinal(ptruint(s.read)-ptruint(q)-1)
  73. else
  74. m := cardinal(ptruint(s.zend)-ptruint(q));
  75. { process input and output based on current state }
  76. while True do
  77. case (c^.mode) of
  78. { waiting for "i:"=input, "o:"=output, "x:"=nothing }
  79. START: { x: set up for LEN }
  80. begin
  81. {$ifndef SLOW}
  82. if (m >= 258) and (n >= 10) then
  83. begin
  84. {UPDATE}
  85. s.bitb := b;
  86. s.bitk := k;
  87. z.avail_in := n;
  88. Inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  89. z.next_in := p;
  90. s.write := q;
  91. r := inflate_fast(c^.lbits, c^.dbits, c^.ltree, c^.dtree, s, z);
  92. {LOAD}
  93. p := z.next_in;
  94. n := z.avail_in;
  95. b := s.bitb;
  96. k := s.bitk;
  97. q := s.write;
  98. if ptruint(q) < ptruint(s.read) then
  99. m := cardinal(ptruint(s.read)-ptruint(q)-1)
  100. else
  101. m := cardinal(ptruint(s.zend)-ptruint(q));
  102. if (r <> Z_OK) then
  103. begin
  104. if (r = Z_STREAM_END) then
  105. c^.mode := WASH
  106. else
  107. c^.mode := BADCODE;
  108. continue; { break for switch-statement in C }
  109. end;
  110. end;
  111. {$endif} { not SLOW }
  112. c^.sub.code.need := c^.lbits;
  113. c^.sub.code.tree := c^.ltree;
  114. c^.mode := LEN; { falltrough }
  115. end;
  116. LEN: { i: get length/literal/eob next }
  117. begin
  118. j := c^.sub.code.need;
  119. {NEEDBITS(j);}
  120. while (k < j) do
  121. begin
  122. {NEEDBYTE;}
  123. if (n <> 0) then
  124. r :=Z_OK
  125. else
  126. begin
  127. {UPDATE}
  128. s.bitb := b;
  129. s.bitk := k;
  130. z.avail_in := n;
  131. Inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  132. z.next_in := p;
  133. s.write := q;
  134. inflate_codes := inflate_flush(s,z,r);
  135. //if this is the last block, there are no bytes left in stream and the block end code follows, finish processing this block
  136. if s.last then
  137. begin
  138. t := c^.sub.code.tree;
  139. { update t (like as in following code), and check, if requested
  140. bits are available }
  141. Inc(t, cardinal(b) and inflate_mask[j]);
  142. if k >= t^.bits then
  143. { now, we can examine t^.exop value }
  144. if t^.exop and 32 <> 0 then
  145. break;
  146. end;
  147. exit;
  148. end;
  149. dec(n);
  150. b := b or (cardinal(p^) shl k);
  151. Inc(p);
  152. Inc(k, 8);
  153. end;
  154. t := c^.sub.code.tree;
  155. Inc(t, cardinal(b) and inflate_mask[j]);
  156. {DUMPBITS(t^.bits);}
  157. b := b shr t^.bits;
  158. dec(k, t^.bits);
  159. e := cardinal(t^.exop);
  160. if (e = 0) then { literal }
  161. begin
  162. c^.sub.lit := t^.base;
  163. {$IFDEF ZLIB_DEBUG}
  164. if (t^.base >= $20) and (t^.base < $7f) then
  165. Tracevv('inflate: literal '+char(t^.base))
  166. else
  167. Tracevv('inflate: literal $'+IntToHex(t^.base, 2));
  168. {$ENDIF}
  169. c^.mode := LIT;
  170. continue; { break switch statement }
  171. end;
  172. if (e and 16 <> 0) then { length }
  173. begin
  174. c^.sub.copy.get := e and 15;
  175. c^.len := t^.base;
  176. c^.mode := LENEXT;
  177. continue; { break C-switch statement }
  178. end;
  179. if (e and 64 = 0) then { next table }
  180. begin
  181. c^.sub.code.need := e;
  182. c^.sub.code.tree := @huft_ptr(t)^[t^.base];
  183. continue; { break C-switch statement }
  184. end;
  185. if (e and 32 <> 0) then { end of block }
  186. begin
  187. {$IFDEF ZLIB_DEBUG}
  188. Tracevv('inflate: end of block');
  189. {$ENDIF}
  190. c^.mode := WASH;
  191. continue; { break C-switch statement }
  192. end;
  193. c^.mode := BADCODE; { invalid code }
  194. z.msg := 'invalid literal/length code';
  195. r := Z_DATA_ERROR;
  196. {UPDATE}
  197. s.bitb := b;
  198. s.bitk := k;
  199. z.avail_in := n;
  200. Inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  201. z.next_in := p;
  202. s.write := q;
  203. inflate_codes := inflate_flush(s,z,r);
  204. exit;
  205. end;
  206. LENEXT: { i: getting length extra (have base) }
  207. begin
  208. j := c^.sub.copy.get;
  209. {NEEDBITS(j);}
  210. while (k < j) do
  211. begin
  212. {NEEDBYTE;}
  213. if (n <> 0) then
  214. r :=Z_OK
  215. else
  216. begin
  217. {UPDATE}
  218. s.bitb := b;
  219. s.bitk := k;
  220. z.avail_in := n;
  221. Inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  222. z.next_in := p;
  223. s.write := q;
  224. inflate_codes := inflate_flush(s,z,r);
  225. exit;
  226. end;
  227. dec(n);
  228. b := b or (cardinal(p^) shl k);
  229. Inc(p);
  230. Inc(k, 8);
  231. end;
  232. Inc(c^.len, cardinal(b and inflate_mask[j]));
  233. {DUMPBITS(j);}
  234. b := b shr j;
  235. dec(k, j);
  236. c^.sub.code.need := c^.dbits;
  237. c^.sub.code.tree := c^.dtree;
  238. {$IFDEF ZLIB_DEBUG}
  239. Tracevv('inflate: length '+IntToStr(c^.len));
  240. {$ENDIF}
  241. c^.mode := DIST;
  242. { falltrough }
  243. end;
  244. DIST: { i: get distance next }
  245. begin
  246. j := c^.sub.code.need;
  247. {NEEDBITS(j);}
  248. while (k < j) do
  249. begin
  250. {NEEDBYTE;}
  251. if (n <> 0) then
  252. r :=Z_OK
  253. else
  254. begin
  255. {UPDATE}
  256. s.bitb := b;
  257. s.bitk := k;
  258. z.avail_in := n;
  259. Inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  260. z.next_in := p;
  261. s.write := q;
  262. inflate_codes := inflate_flush(s,z,r);
  263. exit;
  264. end;
  265. dec(n);
  266. b := b or (cardinal(p^) shl k);
  267. Inc(p);
  268. Inc(k, 8);
  269. end;
  270. t := @huft_ptr(c^.sub.code.tree)^[cardinal(b) and inflate_mask[j]];
  271. {DUMPBITS(t^.bits);}
  272. b := b shr t^.bits;
  273. dec(k, t^.bits);
  274. e := cardinal(t^.exop);
  275. if (e and 16 <> 0) then { distance }
  276. begin
  277. c^.sub.copy.get := e and 15;
  278. c^.sub.copy.dist := t^.base;
  279. c^.mode := DISTEXT;
  280. continue; { break C-switch statement }
  281. end;
  282. if (e and 64 = 0) then { next table }
  283. begin
  284. c^.sub.code.need := e;
  285. c^.sub.code.tree := @huft_ptr(t)^[t^.base];
  286. continue; { break C-switch statement }
  287. end;
  288. c^.mode := BADCODE; { invalid code }
  289. z.msg := 'invalid distance code';
  290. r := Z_DATA_ERROR;
  291. {UPDATE}
  292. s.bitb := b;
  293. s.bitk := k;
  294. z.avail_in := n;
  295. Inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  296. z.next_in := p;
  297. s.write := q;
  298. inflate_codes := inflate_flush(s,z,r);
  299. exit;
  300. end;
  301. DISTEXT: { i: getting distance extra }
  302. begin
  303. j := c^.sub.copy.get;
  304. {NEEDBITS(j);}
  305. while (k < j) do
  306. begin
  307. {NEEDBYTE;}
  308. if (n <> 0) then
  309. r :=Z_OK
  310. else
  311. begin
  312. {UPDATE}
  313. s.bitb := b;
  314. s.bitk := k;
  315. z.avail_in := n;
  316. Inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  317. z.next_in := p;
  318. s.write := q;
  319. inflate_codes := inflate_flush(s,z,r);
  320. exit;
  321. end;
  322. dec(n);
  323. b := b or (cardinal(p^) shl k);
  324. Inc(p);
  325. Inc(k, 8);
  326. end;
  327. Inc(c^.sub.copy.dist, cardinal(b) and inflate_mask[j]);
  328. {DUMPBITS(j);}
  329. b := b shr j;
  330. dec(k, j);
  331. {$IFDEF ZLIB_DEBUG}
  332. Tracevv('inflate: distance '+ IntToStr(c^.sub.copy.dist));
  333. {$ENDIF}
  334. c^.mode := COPY;
  335. { falltrough }
  336. end;
  337. COPY: { o: copying bytes in window, waiting for space }
  338. begin
  339. f := q;
  340. dec(f, c^.sub.copy.dist);
  341. if (cardinal(ptruint(q) - ptruint(s.window)) < c^.sub.copy.dist) then
  342. begin
  343. f := s.zend;
  344. dec(f, c^.sub.copy.dist - cardinal(ptruint(q) - ptruint(s.window)));
  345. end;
  346. while (c^.len <> 0) do
  347. begin
  348. {NEEDOUT}
  349. if (m = 0) then
  350. begin
  351. {WRAP}
  352. if (q = s.zend) and (s.read <> s.window) then
  353. begin
  354. q := s.window;
  355. if ptruint(q) < ptruint(s.read) then
  356. m := cardinal(ptruint(s.read)-ptruint(q)-1)
  357. else
  358. m := cardinal(ptruint(s.zend)-ptruint(q));
  359. end;
  360. if (m = 0) then
  361. begin
  362. {FLUSH}
  363. s.write := q;
  364. r := inflate_flush(s,z,r);
  365. q := s.write;
  366. if ptruint(q) < ptruint(s.read) then
  367. m := cardinal(ptruint(s.read)-ptruint(q)-1)
  368. else
  369. m := cardinal(ptruint(s.zend)-ptruint(q));
  370. {WRAP}
  371. if (q = s.zend) and (s.read <> s.window) then
  372. begin
  373. q := s.window;
  374. if ptruint(q) < ptruint(s.read) then
  375. m := cardinal(ptruint(s.read)-ptruint(q)-1)
  376. else
  377. m := cardinal(ptruint(s.zend)-ptruint(q));
  378. end;
  379. if (m = 0) then
  380. begin
  381. {UPDATE}
  382. s.bitb := b;
  383. s.bitk := k;
  384. z.avail_in := n;
  385. Inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  386. z.next_in := p;
  387. s.write := q;
  388. inflate_codes := inflate_flush(s,z,r);
  389. exit;
  390. end;
  391. end;
  392. end;
  393. r := Z_OK;
  394. {OUTBYTE( *f++)}
  395. q^ := f^;
  396. Inc(q);
  397. Inc(f);
  398. dec(m);
  399. if (f = s.zend) then
  400. f := s.window;
  401. dec(c^.len);
  402. end;
  403. c^.mode := START;
  404. { C-switch break; not needed }
  405. end;
  406. LIT: { o: got literal, waiting for output space }
  407. begin
  408. {NEEDOUT}
  409. if (m = 0) then
  410. begin
  411. {WRAP}
  412. if (q = s.zend) and (s.read <> s.window) then
  413. begin
  414. q := s.window;
  415. if ptruint(q) < ptruint(s.read) then
  416. m := cardinal(ptruint(s.read)-ptruint(q)-1)
  417. else
  418. m := cardinal(ptruint(s.zend)-ptruint(q));
  419. end;
  420. if (m = 0) then
  421. begin
  422. {FLUSH}
  423. s.write := q;
  424. r := inflate_flush(s,z,r);
  425. q := s.write;
  426. if ptruint(q) < ptruint(s.read) then
  427. m := cardinal(ptruint(s.read)-ptruint(q)-1)
  428. else
  429. m := cardinal(ptruint(s.zend)-ptruint(q));
  430. {WRAP}
  431. if (q = s.zend) and (s.read <> s.window) then
  432. begin
  433. q := s.window;
  434. if ptruint(q) < ptruint(s.read) then
  435. m := cardinal(ptruint(s.read)-ptruint(q)-1)
  436. else
  437. m := cardinal(ptruint(s.zend)-ptruint(q));
  438. end;
  439. if (m = 0) then
  440. begin
  441. {UPDATE}
  442. s.bitb := b;
  443. s.bitk := k;
  444. z.avail_in := n;
  445. Inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  446. z.next_in := p;
  447. s.write := q;
  448. inflate_codes := inflate_flush(s,z,r);
  449. exit;
  450. end;
  451. end;
  452. end;
  453. r := Z_OK;
  454. {OUTBYTE(c^.sub.lit);}
  455. q^ := c^.sub.lit;
  456. Inc(q);
  457. dec(m);
  458. c^.mode := START;
  459. {break;}
  460. end;
  461. WASH: { o: got eob, possibly more output }
  462. begin
  463. {$ifdef patch112}
  464. if (k > 7) then { return unused byte, if any }
  465. begin
  466. {$IFDEF ZLIB_DEBUG}
  467. Assert(k < 16, 'inflate_codes grabbed too many bytes');
  468. {$ENDIF}
  469. dec(k, 8);
  470. Inc(n);
  471. dec(p); { can always return one }
  472. end;
  473. {$endif}
  474. {FLUSH}
  475. s.write := q;
  476. r := inflate_flush(s,z,r);
  477. q := s.write;
  478. if ptruint(q) < ptruint(s.read) then
  479. m := cardinal(ptruint(s.read)-ptruint(q)-1)
  480. else
  481. m := cardinal(ptruint(s.zend)-ptruint(q));
  482. if (s.read <> s.write) then
  483. begin
  484. {UPDATE}
  485. s.bitb := b;
  486. s.bitk := k;
  487. z.avail_in := n;
  488. Inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  489. z.next_in := p;
  490. s.write := q;
  491. inflate_codes := inflate_flush(s,z,r);
  492. exit;
  493. end;
  494. c^.mode := ZEND;
  495. { falltrough }
  496. end;
  497. ZEND:
  498. begin
  499. r := Z_STREAM_END;
  500. {UPDATE}
  501. s.bitb := b;
  502. s.bitk := k;
  503. z.avail_in := n;
  504. Inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  505. z.next_in := p;
  506. s.write := q;
  507. inflate_codes := inflate_flush(s,z,r);
  508. exit;
  509. end;
  510. BADCODE: { x: got error }
  511. begin
  512. r := Z_DATA_ERROR;
  513. {UPDATE}
  514. s.bitb := b;
  515. s.bitk := k;
  516. z.avail_in := n;
  517. Inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  518. z.next_in := p;
  519. s.write := q;
  520. inflate_codes := inflate_flush(s,z,r);
  521. exit;
  522. end;
  523. else
  524. begin
  525. r := Z_STREAM_ERROR;
  526. {UPDATE}
  527. s.bitb := b;
  528. s.bitk := k;
  529. z.avail_in := n;
  530. Inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  531. z.next_in := p;
  532. s.write := q;
  533. inflate_codes := inflate_flush(s,z,r);
  534. exit;
  535. end;
  536. end;
  537. {NEED_DUMMY_RETURN - Delphi2+ dumb compilers complain without this }
  538. inflate_codes := Z_STREAM_ERROR;
  539. end;
  540. procedure inflate_codes_free(var c : pInflate_codes_state;
  541. var z : z_stream);
  542. begin
  543. dispose(c);
  544. c := nil;
  545. {$IFDEF ZLIB_DEBUG}
  546. Tracev('inflate: codes free');
  547. {$ENDIF}
  548. end;
  549. end.