commit d695e2aaa37ee9a3f7b05fe5e23cb3c6fbb7d3e2
parent 31fab0436815a7314aee7f320c610ecf6897223f
Author: nsz <nszabolcs@gmail.com>
Date:   Wed, 15 Jul 2009 08:06:46 +0200
deflate += prev match (lazy matching)
Diffstat:
1 file changed, 27 insertions(+), 11 deletions(-)
diff --git a/deflate_simple.c b/deflate_simple.c
@@ -5,7 +5,7 @@
 /*
 TODO:
 	hufflen: parent+heap only
-	match: check backwards, lazy
+	match: check backwards
 	block end: lcount, dcount
 */
 
@@ -351,7 +351,7 @@ static void emitblock(State *s, int blocklen) {
 	for (nclen = Nclen; nclen > 4 && clen[clenorder[nclen-1]] == 0; nclen--);
 
 	/* calc size */
-	uncsize = 3 + 4 + 8*blocklen; /* +byte alignment */
+	uncsize = 3 + 4 + 8*blocklen; /* +byte alignment (8-nbits+3)%8 */
 	fixsize = 3;
 	dynsize = 3 + 5 + 5 + 4;
 	dynsize += 3 * nclen;
@@ -396,10 +396,9 @@ static void emitblock(State *s, int blocklen) {
 		putbits(s, nlit - 257, 5);
 		putbits(s, ndist - 1, 5);
 		putbits(s, nclen - 4, 4);
-		/* clen code lengths */
+		/* huffman code trees */
 		for (i = 0; i < nclen; i++)
 			putbits(s, clen[clenorder[i]], 3);
-		/* code lengths */
 		for (i = 0; i < nc; i++) {
 			c = codes[i];
 			putbits(s, ccode[c], clen[c]);
@@ -542,19 +541,35 @@ int deflate(uchar *src, int len, uchar *dst) {
 	int step;
 	int hash;
 	Match m;
+	Match prevm = {0, 0};
+	uchar prevc = '\0';
 
 	lzinit(&s);
 	newblock(&s, src);
 	s.dst = dst;
 	while (len > 0) {
 		m = getmatch(&s, src, len);
-		if (m.len >= MinMatch) {
-			recordmatch(&s, m);
-			step = m.len;
-		} else {
-			recordlit(&s, *src);
-			step = 1;
-		}
+		if (m.len >= MinMatch)
+			if (m.len <= prevm.len) {
+				recordmatch(&s, prevm);
+				step = prevm.len - 1;
+				prevm.len = 0;
+			} else {
+				if (prevm.len > 0)
+					recordlit(&s, prevc);
+				prevm = m;
+				prevc = *src;
+				step = 1;
+			}
+		else
+			if (prevm.len > 0) {
+				recordmatch(&s, prevm);
+				step = prevm.len - 1;
+				prevm.len = 0;
+			} else {
+				recordlit(&s, *src);
+				step = 1;
+			}
 		while (step > 0) {
 			if (len >= MinMatch) {
 				hash = gethash(src);
@@ -573,6 +588,7 @@ int deflate(uchar *src, int len, uchar *dst) {
 			newblock(&s, src);
 		}
 	}
+
 	if (s.runlen)
 		*s.lzp++ = s.runlen | LzRunlen;
 	s.lastblock = 1;