zinflate.pas 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. unit zinflate;
  2. { inflate.c -- zlib interface to inflate modules
  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, infblock, infutil;
  12. function inflateInit(var z : z_stream) : integer;
  13. { Initializes the internal stream state for decompression.
  14. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
  15. enough memory, Z_VERSION_ERROR if the zlib library version is incompatible
  16. with the version assumed by the caller. msg is set to null if there is no
  17. error message. inflateInit does not perform any decompression: this will be
  18. done by inflate(). }
  19. function inflateInit_(z : z_streamp;
  20. const version : string;
  21. stream_size : integer) : integer;
  22. function inflateInit2_(var z: z_stream;
  23. w : integer;
  24. const version : string;
  25. stream_size : integer) : integer;
  26. function inflateInit2(var z: z_stream;
  27. windowBits : integer) : integer;
  28. {
  29. This is another version of inflateInit with an extra parameter.
  30. The windowBits parameter is the base two logarithm of the maximum window
  31. size (the size of the history buffer). It should be in the range 8..15 for
  32. this version of the library. The default value is 15 if inflateInit is used
  33. instead. If a compressed stream with a larger window size is given as
  34. input, inflate() will return with the error code Z_DATA_ERROR instead of
  35. trying to allocate a larger window.
  36. inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
  37. memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
  38. memLevel). msg is set to null if there is no error message. inflateInit2
  39. does not perform any decompression apart from reading the zlib header if
  40. present: this will be done by inflate(). (So next_in and avail_in may be
  41. modified, but next_out and avail_out are unchanged.)
  42. }
  43. function inflateEnd(var z : z_stream) : integer;
  44. {
  45. All dynamically allocated data structures for this stream are freed.
  46. This function discards any unprocessed input and does not flush any
  47. pending output.
  48. inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
  49. was inconsistent. In the error case, msg may be set but then points to a
  50. static string (which must not be deallocated).
  51. }
  52. function inflateReset(var z : z_stream) : integer;
  53. {
  54. This function is equivalent to inflateEnd followed by inflateInit,
  55. but does not free and reallocate all the internal decompression state.
  56. The stream will keep attributes that may have been set by inflateInit2.
  57. inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
  58. stream state was inconsistent (such as getmem or state being NULL).
  59. }
  60. function inflate(var z : z_stream;
  61. f : integer) : integer;
  62. {
  63. inflate decompresses as much data as possible, and stops when the input
  64. buffer becomes empty or the output buffer becomes full. It may introduce
  65. some output latency (reading input without producing any output)
  66. except when forced to flush.
  67. The detailed semantics are as follows. inflate performs one or both of the
  68. following actions:
  69. - Decompress more input starting at next_in and update next_in and avail_in
  70. accordingly. If not all input can be processed (because there is not
  71. enough room in the output buffer), next_in is updated and processing
  72. will resume at this point for the next call of inflate().
  73. - Provide more output starting at next_out and update next_out and avail_out
  74. accordingly. inflate() provides as much output as possible, until there
  75. is no more input data or no more space in the output buffer (see below
  76. about the flush parameter).
  77. Before the call of inflate(), the application should ensure that at least
  78. one of the actions is possible, by providing more input and/or consuming
  79. more output, and updating the next_* and avail_* values accordingly.
  80. The application can consume the uncompressed output when it wants, for
  81. example when the output buffer is full (avail_out == 0), or after each
  82. call of inflate(). If inflate returns Z_OK and with zero avail_out, it
  83. must be called again after making room in the output buffer because there
  84. might be more output pending.
  85. If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
  86. output as possible to the output buffer. The flushing behavior of inflate is
  87. not specified for values of the flush parameter other than Z_SYNC_FLUSH
  88. and Z_FINISH, but the current implementation actually flushes as much output
  89. as possible anyway.
  90. inflate() should normally be called until it returns Z_STREAM_END or an
  91. error. However if all decompression is to be performed in a single step
  92. (a single call of inflate), the parameter flush should be set to
  93. Z_FINISH. In this case all pending input is processed and all pending
  94. output is flushed; avail_out must be large enough to hold all the
  95. uncompressed data. (The size of the uncompressed data may have been saved
  96. by the compressor for this purpose.) The next operation on this stream must
  97. be inflateEnd to deallocate the decompression state. The use of Z_FINISH
  98. is never required, but can be used to inform inflate that a faster routine
  99. may be used for the single inflate() call.
  100. If a preset dictionary is needed at this point (see inflateSetDictionary
  101. below), inflate sets strm-adler to the adler32 checksum of the
  102. dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
  103. it sets strm->adler to the adler32 checksum of all output produced
  104. so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
  105. an error code as described below. At the end of the stream, inflate()
  106. checks that its computed adler32 checksum is equal to that saved by the
  107. compressor and returns Z_STREAM_END only if the checksum is correct.
  108. inflate() returns Z_OK if some progress has been made (more input processed
  109. or more output produced), Z_STREAM_END if the end of the compressed data has
  110. been reached and all uncompressed output has been produced, Z_NEED_DICT if a
  111. preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
  112. corrupted (input stream not conforming to the zlib format or incorrect
  113. adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
  114. (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
  115. enough memory, Z_BUF_ERROR if no progress is possible or if there was not
  116. enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
  117. case, the application may then call inflateSync to look for a good
  118. compression block.
  119. }
  120. function inflateSetDictionary(var z : z_stream;
  121. dictionary : Pbyte; {const array of byte}
  122. dictLength : cardinal) : integer;
  123. {
  124. Initializes the decompression dictionary from the given uncompressed byte
  125. sequence. This function must be called immediately after a call of inflate
  126. if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
  127. can be determined from the Adler32 value returned by this call of
  128. inflate. The compressor and decompressor must use exactly the same
  129. dictionary (see deflateSetDictionary).
  130. inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
  131. parameter is invalid (such as NULL dictionary) or the stream state is
  132. inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
  133. expected one (incorrect Adler32 value). inflateSetDictionary does not
  134. perform any decompression: this will be done by subsequent calls of
  135. inflate().
  136. }
  137. function inflateSync(var z : z_stream) : integer;
  138. {
  139. Skips invalid compressed data until a full flush point (see above the
  140. description of deflate with Z_FULL_FLUSH) can be found, or until all
  141. available input is skipped. No output is provided.
  142. inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
  143. if no more input was provided, Z_DATA_ERROR if no flush point has been found,
  144. or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
  145. case, the application may save the current current value of total_in which
  146. indicates where valid compressed data was found. In the error case, the
  147. application may repeatedly call inflateSync, providing more input each time,
  148. until success or end of the input data.
  149. }
  150. function inflateSyncPoint(var z : z_stream) : integer;
  151. implementation
  152. uses
  153. adler;
  154. function inflateReset(var z : z_stream) : integer;
  155. begin
  156. if z.state=nil then
  157. begin
  158. inflateReset := Z_STREAM_ERROR;
  159. exit;
  160. end;
  161. z.total_out := 0;
  162. z.total_in := 0;
  163. z.msg := '';
  164. if z.state^.nowrap then
  165. z.state^.mode := BLOCKS
  166. else
  167. z.state^.mode := METHOD;
  168. inflate_blocks_reset(z.state^.blocks^, z, nil);
  169. {$IFDEF ZLIB_DEBUG}
  170. Tracev('inflate: reset');
  171. {$ENDIF}
  172. inflateReset := Z_OK;
  173. end;
  174. function inflateEnd(var z : z_stream) : integer;
  175. begin
  176. if z.state=nil then
  177. begin
  178. inflateEnd := Z_STREAM_ERROR;
  179. exit;
  180. end;
  181. if z.state^.blocks<>nil then
  182. inflate_blocks_free(z.state^.blocks, z);
  183. dispose(z.state);
  184. z.state := nil;
  185. {$IFDEF ZLIB_DEBUG}
  186. Tracev('inflate: end');
  187. {$ENDIF}
  188. inflateEnd := Z_OK;
  189. end;
  190. function inflateInit2_(var z: z_stream;
  191. w : integer;
  192. const version : string;
  193. stream_size : integer) : integer;
  194. begin
  195. if (version = '') or (version[1] <> ZLIB_VERSION[1]) or
  196. (stream_size <> sizeof(z_stream)) then
  197. begin
  198. inflateInit2_ := Z_VERSION_ERROR;
  199. exit;
  200. end;
  201. { initialize state }
  202. { SetLength(strm.msg, 255); }
  203. z.msg := '';
  204. new(z.state);
  205. if z.state=nil then
  206. begin
  207. inflateInit2_ := Z_MEM_ERROR;
  208. exit;
  209. end;
  210. z.state^.blocks := nil;
  211. { handle undocumented nowrap option (no zlib header or check) }
  212. z.state^.nowrap := FALSE;
  213. if (w < 0) then
  214. begin
  215. w := - w;
  216. z.state^.nowrap := TRUE;
  217. end;
  218. { set window size }
  219. if (w < 8) or (w > 15) then
  220. begin
  221. inflateEnd(z);
  222. inflateInit2_ := Z_STREAM_ERROR;
  223. exit;
  224. end;
  225. z.state^.wbits := cardinal(w);
  226. { create inflate_blocks state }
  227. if z.state^.nowrap then
  228. z.state^.blocks := inflate_blocks_new(z, nil, cardinal(1) shl w)
  229. else
  230. z.state^.blocks := inflate_blocks_new(z, @adler32, cardinal(1) shl w);
  231. if z.state^.blocks=nil then
  232. begin
  233. inflateEnd(z);
  234. inflateInit2_ := Z_MEM_ERROR;
  235. exit;
  236. end;
  237. {$IFDEF ZLIB_DEBUG}
  238. Tracev('inflate: allocated');
  239. {$ENDIF}
  240. { reset state }
  241. inflateReset(z);
  242. inflateInit2_ := Z_OK;
  243. end;
  244. function inflateInit2(var z: z_stream; windowBits : integer) : integer;
  245. begin
  246. inflateInit2 := inflateInit2_(z, windowBits, ZLIB_VERSION, sizeof(z_stream));
  247. end;
  248. function inflateInit(var z : z_stream) : integer;
  249. { inflateInit is a macro to allow checking the zlib version
  250. and the compiler's view of z_stream: }
  251. begin
  252. inflateInit := inflateInit2_(z, DEF_WBITS, ZLIB_VERSION, sizeof(z_stream));
  253. end;
  254. function inflateInit_(z : z_streamp;
  255. const version : string;
  256. stream_size : integer) : integer;
  257. begin
  258. { initialize state }
  259. if z=nil then
  260. inflateInit_ := Z_STREAM_ERROR
  261. else
  262. inflateInit_ := inflateInit2_(z^, DEF_WBITS, version, stream_size);
  263. end;
  264. function inflate(var z : z_stream;
  265. f : integer) : integer;
  266. var
  267. r : integer;
  268. b : cardinal;
  269. begin
  270. if (z.state=nil) or (z.next_in=nil) then
  271. begin
  272. inflate := Z_STREAM_ERROR;
  273. exit;
  274. end;
  275. if f = Z_FINISH then
  276. f := Z_BUF_ERROR
  277. else
  278. f := Z_OK;
  279. r := Z_BUF_ERROR;
  280. while True do
  281. case (z.state^.mode) of
  282. BLOCKS:
  283. begin
  284. r := inflate_blocks(z.state^.blocks^, z, r);
  285. if (r = Z_DATA_ERROR) then
  286. begin
  287. z.state^.mode := BAD;
  288. z.state^.sub.marker := 0; { can try inflateSync }
  289. continue; { break C-switch }
  290. end;
  291. if (r = Z_OK) then
  292. r := f;
  293. if (r <> Z_STREAM_END) then
  294. begin
  295. inflate := r;
  296. exit;
  297. end;
  298. r := f;
  299. inflate_blocks_reset(z.state^.blocks^, z, @z.state^.sub.check.was);
  300. if (z.state^.nowrap) then
  301. begin
  302. z.state^.mode := DONE;
  303. continue; { break C-switch }
  304. end;
  305. z.state^.mode := CHECK4; { falltrough }
  306. end;
  307. CHECK4:
  308. begin
  309. {NEEDBYTE}
  310. if (z.avail_in = 0) then
  311. begin
  312. inflate := r;
  313. exit;
  314. end;
  315. r := f;
  316. {z.state^.sub.check.need := cardinal(NEXTBYTE(z)) shl 24;}
  317. dec(z.avail_in);
  318. inc(z.total_in);
  319. z.state^.sub.check.need := cardinal(z.next_in^) shl 24;
  320. inc(z.next_in);
  321. z.state^.mode := CHECK3; { falltrough }
  322. end;
  323. CHECK3:
  324. begin
  325. {NEEDBYTE}
  326. if (z.avail_in = 0) then
  327. begin
  328. inflate := r;
  329. exit;
  330. end;
  331. r := f;
  332. {inc( z.state^.sub.check.need, cardinal(NEXTBYTE(z)) shl 16);}
  333. dec(z.avail_in);
  334. inc(z.total_in);
  335. inc(z.state^.sub.check.need, cardinal(z.next_in^) shl 16);
  336. inc(z.next_in);
  337. z.state^.mode := CHECK2; { falltrough }
  338. end;
  339. CHECK2:
  340. begin
  341. {NEEDBYTE}
  342. if (z.avail_in = 0) then
  343. begin
  344. inflate := r;
  345. exit;
  346. end;
  347. r := f;
  348. {inc( z.state^.sub.check.need, cardinal(NEXTBYTE(z)) shl 8);}
  349. dec(z.avail_in);
  350. inc(z.total_in);
  351. inc(z.state^.sub.check.need, cardinal(z.next_in^) shl 8);
  352. inc(z.next_in);
  353. z.state^.mode := CHECK1; { falltrough }
  354. end;
  355. CHECK1:
  356. begin
  357. {NEEDBYTE}
  358. if (z.avail_in = 0) then
  359. begin
  360. inflate := r;
  361. exit;
  362. end;
  363. r := f;
  364. {inc( z.state^.sub.check.need, cardinal(NEXTBYTE(z)) );}
  365. dec(z.avail_in);
  366. inc(z.total_in);
  367. inc(z.state^.sub.check.need, cardinal(z.next_in^) );
  368. inc(z.next_in);
  369. if (z.state^.sub.check.was <> z.state^.sub.check.need) then
  370. begin
  371. z.state^.mode := BAD;
  372. z.msg := 'incorrect data check';
  373. z.state^.sub.marker := 5; { can't try inflateSync }
  374. continue; { break C-switch }
  375. end;
  376. {$IFDEF ZLIB_DEBUG}
  377. Tracev('inflate: zlib check ok');
  378. {$ENDIF}
  379. z.state^.mode := DONE; { falltrough }
  380. end;
  381. DONE:
  382. begin
  383. inflate := Z_STREAM_END;
  384. exit;
  385. end;
  386. METHOD:
  387. begin
  388. {NEEDBYTE}
  389. if (z.avail_in = 0) then
  390. begin
  391. inflate := r;
  392. exit;
  393. end;
  394. r := f; {}
  395. {z.state^.sub.method := NEXTBYTE(z);}
  396. dec(z.avail_in);
  397. inc(z.total_in);
  398. z.state^.sub.method := z.next_in^;
  399. inc(z.next_in);
  400. if ((z.state^.sub.method and $0f) <> Z_DEFLATED) then
  401. begin
  402. z.state^.mode := BAD;
  403. z.msg := 'unknown compression method';
  404. z.state^.sub.marker := 5; { can't try inflateSync }
  405. continue; { break C-switch }
  406. end;
  407. if ((z.state^.sub.method shr 4) + 8 > z.state^.wbits) then
  408. begin
  409. z.state^.mode := BAD;
  410. z.msg := 'invalid window size';
  411. z.state^.sub.marker := 5; { can't try inflateSync }
  412. continue; { break C-switch }
  413. end;
  414. z.state^.mode := FLAG;
  415. { fall trough }
  416. end;
  417. FLAG:
  418. begin
  419. {NEEDBYTE}
  420. if (z.avail_in = 0) then
  421. begin
  422. inflate := r;
  423. exit;
  424. end;
  425. r := f; {}
  426. {b := NEXTBYTE(z);}
  427. dec(z.avail_in);
  428. inc(z.total_in);
  429. b := z.next_in^;
  430. inc(z.next_in);
  431. if (((z.state^.sub.method shl 8) + b) mod 31) <> 0 then {% mod ?}
  432. begin
  433. z.state^.mode := BAD;
  434. z.msg := 'incorrect header check';
  435. z.state^.sub.marker := 5; { can't try inflateSync }
  436. continue; { break C-switch }
  437. end;
  438. {$IFDEF ZLIB_DEBUG}
  439. Tracev('inflate: zlib header ok');
  440. {$ENDIF}
  441. if ((b and PRESET_DICT) = 0) then
  442. begin
  443. z.state^.mode := BLOCKS;
  444. continue; { break C-switch }
  445. end;
  446. z.state^.mode := DICT4;
  447. { falltrough }
  448. end;
  449. DICT4:
  450. begin
  451. if (z.avail_in = 0) then
  452. begin
  453. inflate := r;
  454. exit;
  455. end;
  456. r := f;
  457. {z.state^.sub.check.need := cardinal(NEXTBYTE(z)) shl 24;}
  458. dec(z.avail_in);
  459. inc(z.total_in);
  460. z.state^.sub.check.need := cardinal(z.next_in^) shl 24;
  461. inc(z.next_in);
  462. z.state^.mode := DICT3; { falltrough }
  463. end;
  464. DICT3:
  465. begin
  466. if (z.avail_in = 0) then
  467. begin
  468. inflate := r;
  469. exit;
  470. end;
  471. r := f;
  472. {inc(z.state^.sub.check.need, cardinal(NEXTBYTE(z)) shl 16);}
  473. dec(z.avail_in);
  474. inc(z.total_in);
  475. inc(z.state^.sub.check.need, cardinal(z.next_in^) shl 16);
  476. inc(z.next_in);
  477. z.state^.mode := DICT2; { falltrough }
  478. end;
  479. DICT2:
  480. begin
  481. if (z.avail_in = 0) then
  482. begin
  483. inflate := r;
  484. exit;
  485. end;
  486. r := f;
  487. {inc(z.state^.sub.check.need, cardinal(NEXTBYTE(z)) shl 8);}
  488. dec(z.avail_in);
  489. inc(z.total_in);
  490. inc(z.state^.sub.check.need, cardinal(z.next_in^) shl 8);
  491. inc(z.next_in);
  492. z.state^.mode := DICT1; { falltrough }
  493. end;
  494. DICT1:
  495. begin
  496. if (z.avail_in = 0) then
  497. begin
  498. inflate := r;
  499. exit;
  500. end;
  501. { r := f; --- wird niemals benutzt }
  502. {inc(z.state^.sub.check.need, cardinal(NEXTBYTE(z)) );}
  503. dec(z.avail_in);
  504. inc(z.total_in);
  505. inc(z.state^.sub.check.need, cardinal(z.next_in^) );
  506. inc(z.next_in);
  507. z.adler := z.state^.sub.check.need;
  508. z.state^.mode := DICT0;
  509. inflate := Z_NEED_DICT;
  510. exit;
  511. end;
  512. DICT0:
  513. begin
  514. z.state^.mode := BAD;
  515. z.msg := 'need dictionary';
  516. z.state^.sub.marker := 0; { can try inflateSync }
  517. inflate := Z_STREAM_ERROR;
  518. exit;
  519. end;
  520. BAD:
  521. begin
  522. inflate := Z_DATA_ERROR;
  523. exit;
  524. end;
  525. else
  526. begin
  527. inflate := Z_STREAM_ERROR;
  528. exit;
  529. end;
  530. end;
  531. {$ifdef NEED_DUMMY_result}
  532. result := Z_STREAM_ERROR; { Some dumb compilers complain without this }
  533. {$endif}
  534. end;
  535. function inflateSetDictionary(var z : z_stream;
  536. dictionary : Pbyte; {const array of byte}
  537. dictLength : cardinal) : integer;
  538. var
  539. length : cardinal;
  540. begin
  541. length := dictLength;
  542. if (z.state=nil) or (z.state^.mode<>DICT0) then
  543. begin
  544. inflateSetDictionary := Z_STREAM_ERROR;
  545. exit;
  546. end;
  547. if (adler32(1, dictionary, dictLength) <> z.adler) then
  548. begin
  549. inflateSetDictionary := Z_DATA_ERROR;
  550. exit;
  551. end;
  552. z.adler := 1;
  553. if (length >= (1 shl z.state^.wbits)) then
  554. begin
  555. length := (1 shl z.state^.wbits)-1;
  556. inc( dictionary, dictLength - length);
  557. end;
  558. inflate_set_dictionary(z.state^.blocks^, dictionary^, length);
  559. z.state^.mode := BLOCKS;
  560. inflateSetDictionary := Z_OK;
  561. end;
  562. function inflateSync(var z : z_stream) : integer;
  563. const
  564. mark : packed array[0..3] of byte = (0, 0, $ff, $ff);
  565. var
  566. n : cardinal; { number of bytes to look at }
  567. p : Pbyte; { pointer to bytes }
  568. m : cardinal; { number of marker bytes found in a row }
  569. r, w : cardinal; { temporaries to save total_in and total_out }
  570. begin
  571. { set up }
  572. if z.state=nil then
  573. begin
  574. inflateSync := Z_STREAM_ERROR;
  575. exit;
  576. end;
  577. if (z.state^.mode <> BAD) then
  578. begin
  579. z.state^.mode := BAD;
  580. z.state^.sub.marker := 0;
  581. end;
  582. n := z.avail_in;
  583. if (n = 0) then
  584. begin
  585. inflateSync := Z_BUF_ERROR;
  586. exit;
  587. end;
  588. p := z.next_in;
  589. m := z.state^.sub.marker;
  590. { search }
  591. while (n <> 0) and (m < 4) do
  592. begin
  593. if (p^ = mark[m]) then
  594. inc(m)
  595. else
  596. if (p^ <> 0) then
  597. m := 0
  598. else
  599. m := 4 - m;
  600. inc(p);
  601. dec(n);
  602. end;
  603. { restore }
  604. inc(z.total_in, ptruint(p) - ptruint(z.next_in));
  605. z.next_in := p;
  606. z.avail_in := n;
  607. z.state^.sub.marker := m;
  608. { return no joy or set up to restart on a new block }
  609. if (m <> 4) then
  610. begin
  611. inflateSync := Z_DATA_ERROR;
  612. exit;
  613. end;
  614. r := z.total_in;
  615. w := z.total_out;
  616. inflateReset(z);
  617. z.total_in := r;
  618. z.total_out := w;
  619. z.state^.mode := BLOCKS;
  620. inflateSync := Z_OK;
  621. end;
  622. {
  623. returns true if inflate is currently at the end of a block generated
  624. by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
  625. implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
  626. but removes the length bytes of the resulting empty stored block. When
  627. decompressing, PPP checks that at the end of input packet, inflate is
  628. waiting for these length bytes.
  629. }
  630. function inflateSyncPoint(var z : z_stream) : integer;
  631. begin
  632. if (z.state = nil) or (z.state^.blocks = nil) then
  633. begin
  634. inflateSyncPoint := Z_STREAM_ERROR;
  635. exit;
  636. end;
  637. inflateSyncPoint := inflate_blocks_sync_point(z.state^.blocks^);
  638. end;
  639. end.