Updated LC2 patch:
Code:
--- deflate.c.org	2010-02-28 01:07:26.000000000 +0800
+++ deflate.c	2010-03-28 12:04:04.985125000 +0800
@@ -138,11 +138,11 @@
 /* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
 /* 5 */ {8,   16, 32,   32, deflate_slow},
 /* 6 */ {8,   16, 128, 128, deflate_slow},
 /* 7 */ {8,   32, 128, 256, deflate_slow},
 /* 8 */ {32, 128, 258, 1024, deflate_slow},
-/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+/* 9 */ {32, 258, 258, 8192, deflate_fast}}; /* max compression */
 #endif
 
 /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
  * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
  * meaning.
@@ -1554,11 +1554,49 @@
              * of window index 0 (in particular we have to avoid a match
              * of the string with itself at the start of the input file).
              */
             s->match_length = longest_match (s, hash_head);
             /* longest_match() sets match_start */
+            if ((s->level == 9) && (s->match_length == MIN_MATCH) && ((s->strstart-s->match_start) > (1 << 14))){
+                s->match_length = 0; /* discard a small match, if it too distant */
+            }
         }
+
+        /* a small HACK written in 5 minutes
+        TODO: write more clever implementation
+        */
+        if (s->match_length >= MIN_MATCH && s->level == 9) {
+          int tmp_strstart = s->strstart; /* store global variables */
+          int tmp_match_start = s->match_start;
+          int dist = s->strstart-s->match_start;
+          int next_len;
+          int next_dist;
+          unsigned hash = s->ins_h;
+          int i;
+
+          /* lazy matching with 2 byte lookahead */
+          for (i = 0; i < 2; i++) {
+            UPDATE_HASH(s, hash, s->window[(++s->strstart) + MIN_MATCH-1]);
+
+            next_len = longest_match (s, s->head[hash]); /* get match length and distance */
+            next_dist = s->strstart-s->match_start;
+
+            /* check for a better match,
+            also check the distance of the followed match */
+            if ((next_len > ((s->match_length + 1) + i)) 
+              || ((next_len > (s->match_length + i)) && ((next_dist >> 3) < dist))) {
+
+              s->match_length = 0; /* discard current match */
+              break;
+            }
+          }
+
+          s->strstart = tmp_strstart; /* restore values */
+          s->match_start = tmp_match_start;
+        }
+		/* End of hack */
+
         if (s->match_length >= MIN_MATCH) {
             check_match(s, s->strstart, s->match_start, s->match_length);
 
             _tr_tally_dist(s, s->strstart - s->match_start,
                            s->match_length - MIN_MATCH, bflush);