inffast.pas 8.7 KB

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