Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

726 lines
27 KiB

  1. /* DEC/CMS REPLACEMENT HISTORY, Element DEFLATE.C */
  2. /* *1 14-NOV-1996 10:26:16 ANIGBOGU "[113914]Data compression functions using the deflate algorithm" */
  3. /* DEC/CMS REPLACEMENT HISTORY, Element DEFLATE.C */
  4. /* PRIVATE FILE
  5. ******************************************************************************
  6. **
  7. ** (c) Copyright Schlumberg.er Technology Cop., unpublished work, created 1996.
  8. **
  9. ** This computer program includes Confidential, Proprietary Information and is
  10. ** a Trade Secret of Schlumberger Technology Corp. All use, disclosure, and/or
  11. ** reproduction is prohibited unless authorized in writing by Schlumberger.
  12. ** All Rights Reserved.
  13. **
  14. ******************************************************************************
  15. **
  16. ** compress/deflate.c
  17. **
  18. ** PURPOSE
  19. **
  20. ** Compress data using the def.lation algorithm.
  21. ** Identify new text as repetitions of old text within a fixed-
  22. ** length sliding window trailing behind the new text.
  23. **
  24. ** DISCUSSION
  25. **
  26. ** The "deflation" process depends on being able to identify portions
  27. ** of the input data which are identical to earlier input (within a
  28. ** sliding window trailing behind the input currently being processed).
  29. **
  30. ** The most straightforward technique turns out to be the fastest for
  31. ** most input files: try all possible matches and select the longest.
  32. ** The key feature of this algorithm is that insertions into the string
  33. ** dictionary are very simple and thus fast, and deletions are avoided
  34. ** completely. Insertions are performed at each input character, whereas
  35. ** string matches are performed only when the previous match ends. So it
  36. ** is preferable to spend more time in matches to allow very fast string
  37. ** insertions and avoid deletions. The matching algorithm for small
  38. ** strings is inspired from that of Rabin & Karp. A brute force approach
  39. ** is used to find longer strings when a small match has been found.
  40. ** A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
  41. ** (by Leonid Broukhis).
  42. ** A previous version of this file used a more sophisticated algorithm
  43. ** (by Fiala and Greene) which is guaranteed to run in linear amortized
  44. ** time, but has a larger average cost, uses more memory and is patented.
  45. ** However the F&G algorithm may be faster for some highly redundant
  46. ** data if the parameter MaxChainLength (described below) is too large.
  47. **
  48. ** ACKNOWLEDGEMENTS
  49. **
  50. ** The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
  51. ** I found it in 'freeze' written by Leonid Broukhis.
  52. **
  53. ** REFERENCES
  54. **
  55. ** APPNOTE.TXT documentation file in PKZIP 1.93a distribution.
  56. **
  57. ** A description of the Rabin and .Karp algorithm is given in the book
  58. ** "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
  59. **
  60. ** Fiala,E.R., and Greene,D.H.
  61. ** Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
  62. **
  63. ** INTERFACE
  64. **
  65. ** int InitLongestMatch(int PackLevel, unsigned short *flags, DeflateParam_t
  66. ** *Defl, LocalDef_t *Deflt, CompParam_t *Comp)
  67. ** Initialize the "longest match" routines for a new buffer
  68. **
  69. ** unsigned long Deflate(int Level, LocalBits_t *Bits, DeflateParam_t *Defl,
  70. ** LocalDef_t *Deflt, CompParam_t *Comp)
  71. ** Processes a new input buffer and return its compressed length. Sets
  72. ** the compressed length, crc, deflate flags and internal buffer
  73. ** attributes.
  74. ** AUTHOR
  75. **
  76. ** J. C. Anigbogu
  77. ** Austin Systems Center
  78. ** Nov 1996
  79. **
  80. ******************************************************************************
  81. */
  82. #include "comppriv.h"
  83. /* ===========================================================================
  84. * Configuration parameters
  85. */
  86. #ifndef HASH_BITS
  87. #define HASH_BITS 15
  88. #endif
  89. #define HASH_SIZE (unsigned int)(1<<HASH_BITS)
  90. #define HASH_MASK (HASH_SIZE-1)
  91. #define WMASK (WSIZE-1)
  92. /* HASH_SIZE and WSIZE must be powers of two */
  93. #define NIL 0
  94. /* Tail of hash chains */
  95. #define FAST 4
  96. #define SLOW 2
  97. /* speed options for the general purpose bit flag */
  98. #ifndef TOO_FAR
  99. #define TOO_FAR 4096
  100. #endif
  101. /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
  102. /* ===========================================================================
  103. * Local data used by the "longest match" routines.
  104. */
  105. typedef unsigned short Pos;
  106. typedef unsigned int IPos;
  107. /* A Pos is an index in the character window. We use short instead of int to
  108. * save space in the various tables. IPos is used only for parameter passing.
  109. */
  110. /* unsigned char Window[2L*WSIZE]; */
  111. /* Sliding window. Input bytes are read into the second half of the window,
  112. * and moved to the first half later to keep a dictionary of at least WSIZE
  113. * bytes. With this organization, matches are limited to a distance of
  114. * WSIZE-MAX_MATCH bytes, but this ensures that IO is always
  115. * performed with a length multiple of the block size.
  116. */
  117. /* Pos HashLink[WSIZE]; */
  118. /* Link to older string with same hash index. To limit the size of this
  119. * array to 64K, this link is maintained only for the last 32K strings.
  120. * An index in this array is thus a window index modulo 32K.
  121. */
  122. /* Pos head[1<<HASH_BITS]; */
  123. /* Heads of the hash chains or NIL. */
  124. #define H_SHIFT ((HASH_BITS+MIN_MATCH-1)/MIN_MATCH)
  125. /* Number of bits by which ins_h and del_h must be shifted at each
  126. * input step. It must be such that after MIN_MATCH steps, the oldest
  127. * byte no longer takes part in the hash key, that is:
  128. * H_SHIFT * MIN_MATCH >= HASH_BITS
  129. */
  130. typedef struct Configuration
  131. {
  132. unsigned short GoodLength; /* reduce lazy search above this match length */
  133. unsigned short MaxLazy; /* do not perform lazy search above this match length */
  134. unsigned short NiceLength; /* quit search above this match length */
  135. unsigned short MaxChain;
  136. } Configuration_t;
  137. static Configuration_t ConfigTable[10] =
  138. {
  139. /* good lazy nice chain */
  140. /* 0 */
  141. {
  142. 0, 0, 0, 0
  143. }, /* store only */
  144. /* 1 */
  145. {
  146. 4, 4, 8, 4
  147. }, /* maximum speed, no lazy matches */
  148. /* 2 */
  149. {
  150. 4, 5, 16, 8
  151. },
  152. /* 3 */
  153. {
  154. 4, 6, 32, 32
  155. },
  156. /* 4 */
  157. {
  158. 4, 4, 16, 16
  159. }, /* lazy matches */
  160. /* 5 */
  161. {
  162. 8, 16, 32, 32
  163. },
  164. /* 6 */
  165. {
  166. 8, 16, 128, 128
  167. },
  168. /* 7 */
  169. {
  170. 8, 32, 128, 256
  171. },
  172. /* 8 */
  173. {
  174. 32, 128, 258, 1024
  175. },
  176. /* 9 */
  177. {
  178. 32, 258, 258, 4096
  179. }
  180. }; /* maximum compression */
  181. /* Note: the Deflate() code requires max_lazy >= MIN_ATCH and max_chain >= 4
  182. * For DeflateFast() (levels <= 3) good is ignored and lazy has a different
  183. * meaning.
  184. */
  185. /* ===========================================================================
  186. * Prototypes for local functions.
  187. */
  188. static void FillWindow(DeflateParam_t *Defl, LocalDef_t *Deflt,
  189. CompParam_t *Comp);
  190. static unsigned long DeflateFast(int Level, LocalBits_t *Bits, DeflateParam_t *Defl,
  191. LocalDef_t *Deflt, CompParam_t *Comp);
  192. int LongestMatch(IPos CurMatch, DeflateParam_t *Defl, CompParam_t *Comp);
  193. /* ===========================================================================
  194. * Update a hash value with the given input byte
  195. * IN assertion: all calls to to UPDATE_HASH are made with consecutive
  196. * input characters, so that a running hash key can be computed from the
  197. * previous key instead of complete recalculation each time.
  198. */
  199. #define UPDATE_HASH(h,c) (h = (((h)<<H_SHIFT) ^ (c)) & HASH_MASK)
  200. /* ===========================================================================
  201. * Insert string s in the dictionary and set match_head to the previous head
  202. * of the hash chain (the most recent string with same hash key). Return
  203. * the previous length of the hash chain.
  204. * IN assertion: all calls to to INSERT_STRING are made with consecutive
  205. * input characters and the first MIN_MATCH bytes of String are valid
  206. * (except for the last MIN_MATCH-1 bytes of the input file).
  207. */
  208. #define INSERT_STRING(s, MatchHead, h, Window, HashLink, Head) \
  209. (UPDATE_HASH(h, Window[(int)(s) + MIN_MATCH-1]), \
  210. HashLink[(int)(s) & WMASK] = Head[h], \
  211. MatchHead = (unsigned int)Head[h], \
  212. Head[h] = (unsigned short)(s))
  213. /* ===========================================================================
  214. * Initialize the "longest match" routines for new data
  215. */
  216. CompressStatus_t
  217. InitLongestMatch(
  218. int PackLevel, /* 0: store, 1: best speed, 9: best compression */
  219. unsigned short *Flags, /* general purpose bit flag */
  220. DeflateParam_t *Defl,
  221. LocalDef_t *Deflt,
  222. CompParam_t *Comp
  223. )
  224. {
  225. unsigned int Counter;
  226. if (PackLevel < 1 || PackLevel > 9)
  227. return BAD_COMPRESSION_LEVEL;
  228. Deflt->CompLevel = PackLevel;
  229. /* Initialize the hash table. */
  230. memzero((char *)(Comp->HashLink+WSIZE), HASH_SIZE*sizeof(*(Comp->HashLink+WSIZE)));
  231. /* HashLink will be initialized on the fly */
  232. /* Set the default configuration parameters: */
  233. Defl->MaxLazyMatch = ConfigTable[PackLevel].MaxLazy;
  234. Defl->GoodMatch = ConfigTable[PackLevel].GoodLength;
  235. Defl->NiceMatch = ConfigTable[PackLevel].NiceLength;
  236. Defl->MaxChainLength = ConfigTable[PackLevel].MaxChain;
  237. Defl->MatchStart = WSIZE;
  238. if (PackLevel == 1)
  239. *Flags |= FAST;
  240. else if (PackLevel == 9)
  241. *Flags |= SLOW;
  242. /* ??? reduce MaxChainLength for binary data */
  243. Defl->StringStart = 0;
  244. Defl->BlockStart = 0L;
  245. Defl->PrevLength = 0;
  246. Defl->MatchStart = 0;
  247. Deflt->Lookahead = (unsigned int)ReadBuffer((char *)Comp->Window,
  248. (unsigned int)(sizeof(int) <= 2 ? WSIZE : 2*WSIZE), Comp);
  249. if (Deflt->Lookahead == 0 || Deflt->Lookahead == (unsigned int)EOF)
  250. {
  251. Deflt->EndOfInput = 1;
  252. Deflt->Lookahead = 0;
  253. return COMPRESS_OK;
  254. }
  255. Deflt->EndOfInput = 0;
  256. /* Make sure that we always have enough lookahead. */
  257. while (Deflt->Lookahead < MIN_LOOKAHEAD && !Deflt->EndOfInput)
  258. FillWindow(Defl, Deflt, Comp);
  259. Deflt->HashIndex = 0;
  260. for (Counter=0; Counter<MIN_MATCH-1; Counter++)
  261. UPDATE_HASH(Deflt->HashIndex, Comp->Window[Counter]);
  262. /* If Lookahead < MIN_MATCH, Deflt->HashIndex is garbage, but this is
  263. * not important since only literal bytes will be emitted.
  264. */
  265. return COMPRESS_OK;
  266. }
  267. /* ===========================================================================
  268. * Set match_start to the longest match starting at the given string and
  269. * return its length. Matches shorter or equal to PrevLength are discarded,
  270. * in which case the result is equal to PrevLength and MatchStart is
  271. * garbage.
  272. * IN assertions: CurMatch is the head of the hash chain for the current
  273. * string (StringStart) and its distance is <= MAX_DIST, and PrevLength >= 1
  274. */
  275. int
  276. LongestMatch(
  277. IPos CurMatch, /* current match */
  278. DeflateParam_t *Defl,
  279. CompParam_t *Comp
  280. )
  281. {
  282. unsigned int ChainLength = Defl->MaxChainLength; /* max hash chain length */
  283. unsigned char *Scan = Comp->Window + Defl->StringStart; /* current string */
  284. unsigned char *Match; /* matched string */
  285. int Length; /* length of current match */
  286. int BestLength = (int)Defl->PrevLength; /* best match length so far */
  287. IPos Limit = Defl->StringStart > (IPos)MAX_DIST ? Defl->StringStart - (IPos)MAX_DIST : NIL;
  288. /* Stop when CurMatch becomes <= Limit. To simplify the code,
  289. * we prevent matches with the string of window index 0.
  290. */
  291. /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
  292. * It is easy to get rid of this optimization if necessary.
  293. */
  294. #if HASH_BITS < 8 || MAX_MATCH != 258
  295. error: Code too clever
  296. #endif
  297. unsigned char *Strend = Comp->Window + Defl->StringStart + MAX_MATCH;
  298. unsigned char ScanEnd1 = Scan[BestLength-1];
  299. unsigned char ScanEnd = Scan[BestLength];
  300. /* Do not waste too much time if we already have a good match: */
  301. if (Defl->PrevLength >= Defl->GoodMatch)
  302. {
  303. ChainLength >>= 2;
  304. }
  305. Assert(Defl->StringStart <= Comp->WindowSize - MIN_LOOKAHEAD, "insufficient lookahead");
  306. do
  307. {
  308. Assert(CurMatch < Defl->StringStart, "no future");
  309. Match = Comp->Window + CurMatch;
  310. /* Skip to next match if the match length cannot increase
  311. * or if the match length is less than 2:
  312. */
  313. if (Match[BestLength] != ScanEnd || Match[BestLength-1] != ScanEnd1 ||
  314. *Match != *Scan || *++Match != Scan[1])
  315. continue;
  316. /* The check at BestLength-1 can be removed because it will be made
  317. * again later. (This heuristic is not always a win.)
  318. * It is not necessary to compare Scan[2] and Match[2] since they
  319. * are always equal when the other bytes match, given that
  320. * the hash keys are equal and that HASH_BITS >= 8.
  321. */
  322. Scan += 2;
  323. Match++;
  324. /* We check for insufficient lookahead only every 8th comparison;
  325. * the 256th check will be made at StringStart+258.
  326. */
  327. do
  328. {
  329. } while (*++Scan == *++Match && *++Scan == *++Match &&
  330. *++Scan == *++Match && *++Scan == *++Match &&
  331. *++Scan == *++Match && *++Scan == *++Match &&
  332. *++Scan == *++Match && *++Scan == *++Match &&
  333. Scan < Strend);
  334. Length = MAX_MATCH - (int)(Strend - Scan);
  335. Scan = Strend - MAX_MATCH;
  336. if (Length > BestLength)
  337. {
  338. Defl->MatchStart = CurMatch;
  339. BestLength = Length;
  340. if (Length >= Defl->NiceMatch)
  341. break;
  342. ScanEnd1 = Scan[BestLength-1];
  343. ScanEnd = Scan[BestLength];
  344. }
  345. } while ((CurMatch = Comp->HashLink[CurMatch & WMASK]) > Limit
  346. && --ChainLength != 0);
  347. return BestLength;
  348. }
  349. /* ===========================================================================
  350. * Fill the window when the Lookahead becomes insufficient.
  351. * Updates StringStart and Lookahead, and sets EndOfInput if end of input buffer.
  352. * IN assertion: Lookahead < MIN_LOOKAHEAD && StringStart + Lookahead > 0
  353. * OUT assertions: at least one byte has been read, or EndOfInput is set;
  354. * buffer reads are performed for at least two bytes
  355. */
  356. static void
  357. FillWindow(
  358. DeflateParam_t *Defl,
  359. LocalDef_t *Deflt,
  360. CompParam_t *Comp
  361. )
  362. {
  363. unsigned int Tmp1, Tmp2;
  364. unsigned int More = (unsigned int)(Comp->WindowSize -
  365. (unsigned long)Deflt->Lookahead -
  366. (unsigned long)Defl->StringStart);
  367. /* Amount of free space at the end of the window. */
  368. /* If the window is almost full and there is insufficient lookahead,
  369. * move the upper half to the lower one to make room in the upper half.
  370. */
  371. if (More == (unsigned int)EOF)
  372. {
  373. /* Very unlikely, but possible on 16 bit machine if StringStart == 0
  374. * and lookahead == 1 (input done one byte at a time)
  375. */
  376. More--;
  377. }
  378. else if (Defl->StringStart >= (unsigned int)(WSIZE+MAX_DIST))
  379. {
  380. /* By the IN assertion, the window is not empty so we can't confuse
  381. * More == 0 with More == 64K on a 16 bit machine.
  382. */
  383. Assert(Comp->WindowSize == (unsigned long)(2*WSIZE), "no sliding");
  384. memcpy((char *)Comp->Window, (char *)Comp->Window+WSIZE, WSIZE);
  385. Defl->MatchStart -= (unsigned int)WSIZE;
  386. Defl->StringStart -= (unsigned int)WSIZE;
  387. /* we now have StringStart >= MAX_DIST: */
  388. Defl->BlockStart -= (long) WSIZE;
  389. for (Tmp1 = 0; Tmp1 < (unsigned int)HASH_SIZE; Tmp1++)
  390. {
  391. Tmp2 = (Comp->HashLink+WSIZE)[Tmp1];
  392. (Comp->HashLink+WSIZE)[Tmp1] = (Pos)(Tmp2 >= (unsigned int)WSIZE ?
  393. Tmp2-(unsigned int)WSIZE : NIL);
  394. }
  395. for (Tmp1 = 0; Tmp1 < WSIZE; Tmp1++)
  396. {
  397. Tmp2 = Comp->HashLink[Tmp1];
  398. Comp->HashLink[Tmp1] = (Pos)(Tmp2 >= WSIZE ? Tmp2-WSIZE : NIL);
  399. /* If n is not on any hash chain, HashLink[n] is garbage but
  400. * its value will never be used.
  401. */
  402. }
  403. More += (unsigned int)WSIZE;
  404. }
  405. /* At this point, more >= 2 */
  406. if (!Deflt->EndOfInput)
  407. {
  408. Tmp1 = (unsigned int)ReadBuffer((char*)Comp->Window + Defl->StringStart +
  409. Deflt->Lookahead, More, Comp);
  410. if (Tmp1 == 0 || Tmp1 == (unsigned int)EOF)
  411. Deflt->EndOfInput = 1;
  412. else
  413. Deflt->Lookahead += Tmp1;
  414. }
  415. }
  416. /* ===========================================================================
  417. * Flush the current block, with given end-of-file flag.
  418. * IN assertion: StringStart is set to the end of the current match.
  419. */
  420. #define FLUSH_BLOCK(Eof, Bits, Defl, Comp) \
  421. FlushBlock(Defl->BlockStart >= 0L ? (char *)&Comp->Window[(unsigned int)Defl->BlockStart] : \
  422. (char *)NULL, (unsigned long)((long)Defl->StringStart - Defl->BlockStart), \
  423. Eof, Bits, Comp)
  424. /* ===========================================================================
  425. * Processes a new input buffer and return its compressed length. This
  426. * function does not perform lazy evaluation of matches and inserts
  427. * new strings in the dictionary only for umatched strings or for short
  428. * matches. It is used only for the fast compression options.
  429. */
  430. static unsigned long
  431. DeflateFast(
  432. int Level,
  433. LocalBits_t *Bits,
  434. DeflateParam_t *Defl,
  435. LocalDef_t *Deflt,
  436. CompParam_t *Comp
  437. )
  438. {
  439. IPos HashHead; /* head of the hash chain */
  440. int Flush; /* set if current block must be flushed */
  441. unsigned int MatchLength = 0; /* length of best match */
  442. Defl->PrevLength = MIN_MATCH-1;
  443. while (Deflt->Lookahead != 0)
  444. {
  445. /* Insert the string Window[StringStart .. StringStart+2] in the
  446. * dictionary, and set hash_head to the head of the hash chain:
  447. */
  448. INSERT_STRING(Defl->StringStart, HashHead, Deflt->HashIndex, Comp->Window,
  449. Comp->HashLink, (Comp->HashLink + WSIZE));
  450. /* Find the longest match, discarding those <= PrevLength.
  451. * At this point we have always MatchLength < MIN_MATCH
  452. */
  453. if (HashHead != NIL && Defl->StringStart - HashHead <= MAX_DIST)
  454. {
  455. /* To simplify the code, we prevent matches with the string
  456. * of window index 0 (in particular we have to avoid a match
  457. * of the string with itself at the start of the input buffer).
  458. */
  459. MatchLength = (unsigned int)LongestMatch(HashHead, Defl, Comp);
  460. /* longest_match() sets match_start */
  461. if (MatchLength > Deflt->Lookahead)
  462. MatchLength = Deflt->Lookahead;
  463. }
  464. if (MatchLength >= MIN_MATCH)
  465. {
  466. Flush = TallyFrequencies((int)(Defl->StringStart-Defl->MatchStart),
  467. (int)MatchLength - MIN_MATCH, Level, Defl, Comp);
  468. Deflt->Lookahead -= MatchLength;
  469. /* Insert new strings in the hash table only if the match length
  470. * is not greater than this length. This saves time but degrades
  471. * compression. MaxLazyMatch is used only for compression levels <= 3.
  472. */
  473. if (MatchLength <= Defl->MaxLazyMatch)
  474. {
  475. MatchLength--; /* string at StringStart already in hash table */
  476. do
  477. {
  478. Defl->StringStart++;
  479. INSERT_STRING(Defl->StringStart, HashHead, Deflt->HashIndex,
  480. Comp->Window, Comp->HashLink,
  481. (Comp->HashLink + WSIZE));
  482. /* StringStart never exceeds WSIZE-MAX_MATCH, so there are
  483. * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
  484. * these bytes are garbage, but it does not matter since
  485. * the next lookahead bytes will be emitted as literals.
  486. */
  487. } while (--MatchLength != 0);
  488. Defl->StringStart++;
  489. }
  490. else
  491. {
  492. Defl->StringStart += MatchLength;
  493. MatchLength = 0;
  494. Deflt->HashIndex = Comp->Window[Defl->StringStart];
  495. UPDATE_HASH(Deflt->HashIndex, Comp->Window[Defl->StringStart+1]);
  496. #if MIN_MATCH != 3
  497. Call UPDATE_HASH() MIN_MATCH-3 more times
  498. #endif
  499. }
  500. }
  501. else
  502. {
  503. /* No match, output a literal byte */
  504. Flush = TallyFrequencies(0, Comp->Window[Defl->StringStart], Level, Defl, Comp);
  505. Deflt->Lookahead--;
  506. Defl->StringStart++;
  507. }
  508. if (Flush)
  509. {
  510. (void)FLUSH_BLOCK(0, Bits, Defl, Comp);
  511. Defl->BlockStart = (long)Defl->StringStart;
  512. }
  513. /* Make sure that we always have enough lookahead, except
  514. * at the end of the input buffer. We need MAX_MATCH bytes
  515. * for the next match, pls MIN_MATCH bytes to insert the
  516. * string following the next match.
  517. */
  518. while (Deflt->Lookahead < MIN_LOOKAHEAD && !Deflt->EndOfInput)
  519. FillWindow(Defl, Deflt, Comp);
  520. }
  521. return FLUSH_BLOCK(1, Bits, Defl, Comp); /* end of buffer (eof) */
  522. }
  523. /* ===========================================================================
  524. * Same as above, but achieves better compression. We use a lazy
  525. * evaluation for matches: a match is finally adopted only if there is
  526. * no beter match at the next window position.
  527. */
  528. unsigned long
  529. Deflate(
  530. int Level,
  531. LocalBits_t *Bits,
  532. DeflateParam_t *Defl,
  533. LocalDef_t *Deflt,
  534. CompParam_t *Comp
  535. )
  536. {
  537. IPos HashHead; /* head of hash chain */
  538. IPos PrevMatch; /* previous match */
  539. int Flush; /* set if current block must be flushed */
  540. int MatchAvailable = 0; /* set if previous match exists */
  541. unsigned int MatchLength = MIN_MATCH-1; /* length of best match */
  542. if (Deflt->CompLevel <= 3)
  543. return DeflateFast(Level, Bits, Defl, Deflt, Comp); /* optimized for speed */
  544. /* Process the input block. */
  545. while (Deflt->Lookahead != 0)
  546. {
  547. /* Insert the string Window[StringStart .. StringStart+2] in the
  548. * dictionary, and set hash_head to the head of the hash chain:
  549. */
  550. INSERT_STRING(Defl->StringStart, HashHead, Deflt->HashIndex,
  551. Comp->Window, Comp->HashLink, (Comp->HashLink + WSIZE));
  552. /* Find the longest match, discarding those<= PrevLength.
  553. */
  554. Defl->PrevLength = MatchLength;
  555. PrevMatch = Defl->MatchStart;
  556. MatchLength = MIN_MATCH-1;
  557. if (HashHead != NIL && Defl->PrevLength < Defl->MaxLazyMatch &&
  558. Defl->StringStart - HashHead <= MAX_DIST)
  559. {
  560. /* To simplify the code, we prevent matches with the string
  561. * of window index 0 (in particular we have to avoid a match
  562. * of the string with itself at the start of the input buffer).
  563. */
  564. MatchLength = (unsigned int)LongestMatch(HashHead, Defl, Comp);
  565. /* LongestMatch() sets MatchStart */
  566. if (MatchLength > Deflt->Lookahead)
  567. MatchLength = Deflt->Lookahead;
  568. /* Ignore a length 3 match if it is too distant: */
  569. if (MatchLength == MIN_MATCH &&
  570. Defl->StringStart - Defl->MatchStart > TOO_FAR)
  571. {
  572. /* If prev_match is also MIN_MATCH, match_start is garbage
  573. * but we will ignore the current match anyway.
  574. */
  575. MatchLength--;
  576. }
  577. }
  578. /* If there was a match at the previous step and the current
  579. * match is not better, output the previous match:
  580. */
  581. if (Defl->PrevLength >= MIN_MATCH && MatchLength <= Defl->PrevLength)
  582. {
  583. Flush = TallyFrequencies((int)(Defl->StringStart - 1 - PrevMatch),
  584. (int)((int)Defl->PrevLength - MIN_MATCH),
  585. Level, Defl, Comp);
  586. /* Insert in hash table all strings up to the end of the match.
  587. * StringStart-1 and StringStart are already inserted.
  588. */
  589. Deflt->Lookahead -= Defl->PrevLength-1;
  590. Defl->PrevLength -= 2;
  591. do
  592. {
  593. Defl->StringStart++;
  594. INSERT_STRING(Defl->StringStart, HashHead, Deflt->HashIndex,
  595. Comp->Window, Comp->HashLink, (Comp->HashLink + WSIZE));
  596. /* StringStart never exceeds WSIZE-MAX_MATCH, so there are
  597. * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
  598. * these bytes are garbage, but it does not matter since the
  599. * next lookahead bytes will always be emitted as literals.
  600. */
  601. } while (--Defl->PrevLength != 0);
  602. MatchAvailable = 0;
  603. MatchLength = MIN_MATCH-1;
  604. Defl->StringStart++;
  605. if (Flush)
  606. {
  607. (void)FLUSH_BLOCK(0, Bits, Defl, Comp);
  608. Defl->BlockStart = (long)Defl->StringStart;
  609. }
  610. }
  611. else if (MatchAvailable)
  612. {
  613. /* If there was no match at the previous position, output a
  614. * single literal. If there was a match but the current match
  615. * is longer, truncate the previous match to a single literal.
  616. */
  617. if (TallyFrequencies(0, Comp->Window[Defl->StringStart-1], Level, Defl, Comp))
  618. {
  619. (void)FLUSH_BLOCK(0, Bits, Defl, Comp);
  620. Defl->BlockStart = (long)Defl->StringStart;
  621. }
  622. Defl->StringStart++;
  623. Deflt->Lookahead--;
  624. }
  625. else
  626. {
  627. /* There is no previous match to compare with, wait for
  628. * the next step to decide.
  629. */
  630. MatchAvailable = 1;
  631. Defl->StringStart++;
  632. Deflt->Lookahead--;
  633. }
  634. Assert (Defl->StringStart <= Comp->BytesIn && Deflt->Lookahead
  635. <= Comp->BytesIn, "a bit too far");
  636. /* Make sure that we always have enough lookahead, except
  637. * at the end of the input buffer. We need MAX_MATCH bytes
  638. * for the next match, plus MIN_MATCH bytes to insert the
  639. * string following the next match.
  640. */
  641. while (Deflt->Lookahead < MIN_LOOKAHEAD && !Deflt->EndOfInput)
  642. FillWindow(Defl, Deflt, Comp);
  643. }
  644. if (MatchAvailable)
  645. (void)TallyFrequencies(0, Comp->Window[Defl->StringStart-1], Level, Defl, Comp);
  646. return FLUSH_BLOCK(1, Bits, Defl, Comp); /* end of buffer (eof) */
  647. }