inffast.pas 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. Unit InfFast;
  2. {
  3. inffast.h and
  4. inffast.c -- process literals and length/distance pairs fast
  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. uses
  13. zbase;
  14. function inflate_fast( bl : cardinal;
  15. bd : cardinal;
  16. tl : pInflate_huft;
  17. td : pInflate_huft;
  18. var s : inflate_blocks_state;
  19. var z : z_stream) : integer;
  20. implementation
  21. uses
  22. infutil;
  23. { Called with number of bytes left to write in window at least 258
  24. (the maximum string length) and number of input bytes available
  25. at least ten. The ten bytes are six bytes for the longest length/
  26. distance pair plus four bytes for overloading the bit buffer. }
  27. function inflate_fast( bl : cardinal;
  28. bd : cardinal;
  29. tl : pInflate_huft;
  30. td : pInflate_huft;
  31. var s : inflate_blocks_state;
  32. var z : z_stream) : integer;
  33. var
  34. t : pInflate_huft; { temporary pointer }
  35. e : cardinal; { extra bits or operation }
  36. b : longint; { bit buffer }
  37. k : cardinal; { bits in bit buffer }
  38. p : Pbyte; { input data pointer }
  39. n : cardinal; { bytes available there }
  40. q : Pbyte; { output window write pointer }
  41. m : cardinal; { bytes to end of window or read pointer }
  42. ml : cardinal; { mask for literal/length tree }
  43. md : cardinal; { mask for distance tree }
  44. c : cardinal; { bytes to copy }
  45. d : cardinal; { distance back to copy from }
  46. r : Pbyte; { copy source pointer }
  47. begin
  48. { load input, output, bit values (macro LOAD) }
  49. p := z.next_in;
  50. n := z.avail_in;
  51. b := s.bitb;
  52. k := s.bitk;
  53. q := s.write;
  54. if ptruint(q) < ptruint(s.read) then
  55. m := cardinal(ptruint(s.read)-ptruint(q)-1)
  56. else
  57. m := cardinal(ptruint(s.zend)-ptruint(q));
  58. { initialize masks }
  59. ml := inflate_mask[bl];
  60. md := inflate_mask[bd];
  61. { do until not enough input or output space for fast loop }
  62. repeat { assume called with (m >= 258) and (n >= 10) }
  63. { get literal/length code }
  64. {GRABBITS(20);} { max bits for literal/length code }
  65. while (k < 20) do
  66. begin
  67. dec(n);
  68. b := b or (longint(p^) shl k);
  69. inc(p);
  70. inc(k, 8);
  71. end;
  72. t := @(huft_ptr(tl)^[cardinal(b) and ml]);
  73. e := t^.exop;
  74. if (e = 0) then
  75. begin
  76. {DUMPBITS(t^.bits);}
  77. b := b shr t^.bits;
  78. dec(k, t^.bits);
  79. {$IFDEF ZLIB_DEBUG}
  80. if (t^.base >= $20) and (t^.base < $7f) then
  81. Tracevv('inflate: * literal '+char(t^.base))
  82. else
  83. Tracevv('inflate: * literal '+ IntToStr(t^.base));
  84. {$ENDIF}
  85. q^ := Byte(t^.base);
  86. inc(q);
  87. dec(m);
  88. continue;
  89. end;
  90. repeat
  91. {DUMPBITS(t^.bits);}
  92. b := b shr t^.bits;
  93. dec(k, t^.bits);
  94. if (e and 16 <> 0) then
  95. begin
  96. { get extra bits for length }
  97. e := e and 15;
  98. c := t^.base + (cardinal(b) and inflate_mask[e]);
  99. {DUMPBITS(e);}
  100. b := b shr e;
  101. dec(k, e);
  102. {$IFDEF ZLIB_DEBUG}
  103. Tracevv('inflate: * length ' + IntToStr(c));
  104. {$ENDIF}
  105. { decode distance base of block to copy }
  106. {GRABBITS(15);} { max bits for distance code }
  107. while (k < 15) do
  108. begin
  109. dec(n);
  110. b := b or (longint(p^) shl k);
  111. inc(p);
  112. inc(k, 8);
  113. end;
  114. t := @huft_ptr(td)^[cardinal(b) and md];
  115. e := t^.exop;
  116. repeat
  117. {DUMPBITS(t^.bits);}
  118. b := b shr t^.bits;
  119. dec(k, t^.bits);
  120. if (e and 16 <> 0) then
  121. begin
  122. { get extra bits to add to distance base }
  123. e := e and 15;
  124. {GRABBITS(e);} { get extra bits (up to 13) }
  125. while (k < e) do
  126. begin
  127. dec(n);
  128. b := b or (longint(p^) shl k);
  129. inc(p);
  130. inc(k, 8);
  131. end;
  132. d := t^.base + (cardinal(b) and inflate_mask[e]);
  133. {DUMPBITS(e);}
  134. b := b shr e;
  135. dec(k, e);
  136. {$IFDEF ZLIB_DEBUG}
  137. Tracevv('inflate: * distance '+IntToStr(d));
  138. {$ENDIF}
  139. { do the copy }
  140. dec(m, c);
  141. if (cardinal(ptruint(q) - ptruint(s.window)) >= d) then { offset before dest }
  142. begin { just copy }
  143. r := q;
  144. dec(r, d);
  145. q^ := r^; inc(q); inc(r); dec(c); { minimum count is three, }
  146. q^ := r^; inc(q); inc(r); dec(c); { so unroll loop a little }
  147. end
  148. else { else offset after destination }
  149. begin
  150. e := d - cardinal(ptruint(q) - ptruint(s.window)); { bytes from offset to end }
  151. r := s.zend;
  152. dec(r, e); { pointer to offset }
  153. if (c > e) then { if source crosses, }
  154. begin
  155. dec(c, e); { copy to end of window }
  156. repeat
  157. q^ := r^;
  158. inc(q);
  159. inc(r);
  160. dec(e);
  161. until (e=0);
  162. r := s.window; { copy rest from start of window }
  163. end;
  164. end;
  165. repeat { copy all or what's left }
  166. q^ := r^;
  167. inc(q);
  168. inc(r);
  169. dec(c);
  170. until (c = 0);
  171. break;
  172. end
  173. else
  174. if (e and 64 = 0) then
  175. begin
  176. inc(t, t^.base + (cardinal(b) and inflate_mask[e]));
  177. e := t^.exop;
  178. end
  179. else
  180. begin
  181. z.msg := 'invalid distance code';
  182. {UNGRAB}
  183. c := z.avail_in-n;
  184. if (k shr 3) < c then
  185. c := k shr 3;
  186. inc(n, c);
  187. dec(p, c);
  188. dec(k, c shl 3);
  189. {UPDATE}
  190. s.bitb := b;
  191. s.bitk := k;
  192. z.avail_in := n;
  193. inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  194. z.next_in := p;
  195. s.write := q;
  196. inflate_fast := Z_DATA_ERROR;
  197. exit;
  198. end;
  199. until FALSE;
  200. break;
  201. end;
  202. if (e and 64 = 0) then
  203. begin
  204. {t += t->base;
  205. e = (t += ((cardinal)b & inflate_mask[e]))->exop;}
  206. inc(t, t^.base + (cardinal(b) and inflate_mask[e]));
  207. e := t^.exop;
  208. if (e = 0) then
  209. begin
  210. {DUMPBITS(t^.bits);}
  211. b := b shr t^.bits;
  212. dec(k, t^.bits);
  213. {$IFDEF ZLIB_DEBUG}
  214. if (t^.base >= $20) and (t^.base < $7f) then
  215. Tracevv('inflate: * literal '+char(t^.base))
  216. else
  217. Tracevv('inflate: * literal '+IntToStr(t^.base));
  218. {$ENDIF}
  219. q^ := Byte(t^.base);
  220. inc(q);
  221. dec(m);
  222. break;
  223. end;
  224. end
  225. else
  226. if (e and 32 <> 0) then
  227. begin
  228. {$IFDEF ZLIB_DEBUG}
  229. Tracevv('inflate: * end of block');
  230. {$ENDIF}
  231. {UNGRAB}
  232. c := z.avail_in-n;
  233. if (k shr 3) < c then
  234. c := k shr 3;
  235. inc(n, c);
  236. dec(p, c);
  237. dec(k, c shl 3);
  238. {UPDATE}
  239. s.bitb := b;
  240. s.bitk := k;
  241. z.avail_in := n;
  242. inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  243. z.next_in := p;
  244. s.write := q;
  245. inflate_fast := Z_STREAM_END;
  246. exit;
  247. end
  248. else
  249. begin
  250. z.msg := 'invalid literal/length code';
  251. {UNGRAB}
  252. c := z.avail_in-n;
  253. if (k shr 3) < c then
  254. c := k shr 3;
  255. inc(n, c);
  256. dec(p, c);
  257. dec(k, c shl 3);
  258. {UPDATE}
  259. s.bitb := b;
  260. s.bitk := k;
  261. z.avail_in := n;
  262. inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  263. z.next_in := p;
  264. s.write := q;
  265. inflate_fast := Z_DATA_ERROR;
  266. exit;
  267. end;
  268. until FALSE;
  269. until (m < 258) or (n < 10);
  270. { not enough input or output--restore pointers and return }
  271. {UNGRAB}
  272. c := z.avail_in-n;
  273. if (k shr 3) < c then
  274. c := k shr 3;
  275. inc(n, c);
  276. dec(p, c);
  277. dec(k, c shl 3);
  278. {UPDATE}
  279. s.bitb := b;
  280. s.bitk := k;
  281. z.avail_in := n;
  282. inc(z.total_in, ptruint(p)-ptruint(z.next_in));
  283. z.next_in := p;
  284. s.write := q;
  285. inflate_fast := Z_OK;
  286. end;
  287. end.