infcodes.pas 15 KB

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