infcodes.pas 16 KB

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