commit 1b3aea40ec37c7d9fcce28ebe271ecd895200702
parent a832945746253cae75977ce7daa5a14ad34a3885
Author: nsz <nszabolcs@gmail.com>
Date:   Mon, 20 Apr 2009 20:35:17 +0200
cleanups, gcov
Diffstat:
| Makefile | | | 13 | +++++++++++++ | 
| README | | | 1 | + | 
| inflate.c | | | 87 | ++++++++++++++++++++++++++++++++++--------------------------------------------- | 
3 files changed, 51 insertions(+), 50 deletions(-)
diff --git a/Makefile b/Makefile
@@ -12,3 +12,16 @@ ${OBJ}: Makefile
 	${CC} -c ${CFLAGS} $<
 clean:
 	rm -f ${OBJ} inflate
+
+
+gcov: inflate.c
+	gcc -fprofile-arcs -ftest-coverage -pg ${CFLAGS} $<
+	./a.out test.dat > /dev/null
+	gcov -b $< > /dev/null
+	gprof a.out > $<.gprof
+	gcc ${CFLAGS} $<
+	valgrind -v --leak-check=yes ./a.out > /dev/null 2> a.valgrind
+	grep ERROR a.valgrind >a.err.valgrind
+	grep alloc a.valgrind >a.alloc.valgrind
+	rm a.out *.gcno *.gcda gmon.out
+
diff --git a/README b/README
@@ -5,6 +5,7 @@ source:
 	tinf from ibsensoftware
 	puff from zlib
 	libflate from plan 9
+	halibut/deflate from putty
 
 build:
 	make
diff --git a/inflate.c b/inflate.c
@@ -1,10 +1,12 @@
 /*
 TODO:
-	error check (src len, dst len)
-	fillbits(s, n) -> faster getbits()
+	error check (src len, dst len, hufftree)
 	clever io
 	p9 hufftable
 	int types
+	speedup:
+		fillbits(s, n) -> faster getbits()
+		loop unroll in decode_symbol
 */
 
 typedef unsigned char uchar;
@@ -13,21 +15,17 @@ typedef unsigned int uint;
 typedef unsigned long ulong;
 
 enum {
-	HuffBits =	16,	/* maximum bits in a encoded code */
+	HuffBits =	16,	/* max number of bits in a code */
 	Nlit =		256,	/* number of lit codes */
 	Nlen =		29,	/* number of len codes */
 	Nlitlen =	Nlit + Nlen + 3, /* number of litlen codes + block end + 2 unused */
-	Ndist =		30,	/* number of offset codes */
-	Nclen =		19,	/* number of codelen codes */
-	LenShift =	10	/* code = len<<LenShift|code */
-/*	LitlenBits =	7,*/	/* number of bits in litlen decode table */
-/*	DistBits =	6,*/	/* number of bits in offset decode table */
-/*	ClenBits =	6*/	/* number of bits in code len decode table */
+	Ndist =		30,	/* number of distance codes */
+	Nclen =		19,	/* number of code length codes */
 };
 
 typedef struct {
-	ushort count[HuffBits]; /* code bit len -> count */
-	ushort symbol[Nlitlen]; /* litlen code -> symbol */
+	ushort count[HuffBits]; /* code bit length -> count */
+	ushort symbol[Nlitlen]; /* symbols ordered by code length */
 } HuffTree;
 
 typedef struct {
@@ -46,7 +44,6 @@ typedef struct {
 static HuffTree ltree; /* fixed lit/len tree */
 static HuffTree dtree; /* fixed distance tree */
 
-/* extra bits and base tables for length codes */
 static uchar lenbits[Nlen] = {
 	0,  0,  0,  0,  0,  0,  0,  0,  1,  1,
 	1,  1,  2,  2,  2,  2,  3,  3,  3,  3,
@@ -55,7 +52,6 @@ static uchar lenbits[Nlen] = {
 
 static ushort lenbase[Nlen];
 
-/* extra bits and base tables for distance codes */
 static uchar distbits[Ndist] = {
 	0,  0,  0,  0,  1,  1,  2,  2,  3,  3,
 	4,  4,  5,  5,  6,  6,  7,  7,  8,  8,
@@ -92,15 +88,15 @@ static void init_fixed_trees(void) {
 	ltree.count[9] = 112;
 	for (i = 0; i < 24; i++)
 		ltree.symbol[i] = 256 + i;
-	for (i = 0; i < 144; ++i)
+	for (i = 0; i < 144; i++)
 		ltree.symbol[24 + i] = i;
-	for (i = 0; i < 8; ++i)
+	for (i = 0; i < 8; i++)
 		ltree.symbol[24 + 144 + i] = 280 + i;
-	for (i = 0; i < 112; ++i)
+	for (i = 0; i < 112; i++)
 		ltree.symbol[24 + 144 + 8 + i] = 144 + i;
 
 	dtree.count[5] = Ndist;
-	for (i = 0; i < Ndist; ++i)
+	for (i = 0; i < Ndist; i++)
 		dtree.symbol[i] = i;
 }
 
@@ -121,16 +117,12 @@ static void build_tree(HuffTree *t, const uchar *lens, uint n) {
 		sum += t->count[i];
 	}
 
-	/* create code->symbol translation table (symbols sorted by code) */
+	/* sort symbols by code length */
 	for (i = 0; i < n; i++)
 		if (lens[i])
 			t->symbol[offs[lens[i]]++] = i;
 }
 
-/*
- * decode functions
- */
-
 /* get one bit from s->src stream */
 static uint getbit(FlateStream *s) {
 	uint bit;
@@ -162,10 +154,12 @@ static uint decode_symbol(FlateStream *s, HuffTree *t) {
 
 	/* get bits while code value is above sum */
 	do {
-		cur <<= 1;
-		cur |= getbit(s);
 		len++;
+		if (len >= HuffBits)
+			/* error */;
 		sum += t->count[len];
+		cur <<= 1;
+		cur |= getbit(s);
 		cur -= t->count[len];
 	} while (cur >= 0);
 
@@ -182,7 +176,8 @@ static void decode_trees(FlateStream *s, HuffTree *lt, HuffTree *dt) {
 	nlit = 257 + getbits(s, 5);
 	ndist = 1 + getbits(s, 5);
 	nclen = 4 + getbits(s, 4);
-	/*if (nlit > Nlitlen || ndist > Ndist) */
+	if (nlit > Nlitlen || ndist > Ndist)
+		/* error */;
 
 	/* build code length tree */
 	for (i = 0; i < Nclen; i++)
@@ -212,9 +207,8 @@ static void decode_trees(FlateStream *s, HuffTree *lt, HuffTree *dt) {
 			/* repeat 0 for 11-138 times */
 			for (len = 11 + getbits(s, 7); len; len--)
 				lens[i++] = 0;
-		} else {
-			/* error */
-		}
+		} else
+			/* error */;
 	}
 
 	/* build dynamic trees */
@@ -237,8 +231,8 @@ static int decode_block(FlateStream *s, HuffTree *lt, HuffTree *dt) {
 		if (sym < 256)
 			*s->dst++ = sym;
 		else {
-			int len, dist;
-			int i;
+			uint len, dist;
+			uint i;
 
 			sym -= 257;
 			if (sym >= Nlen)
@@ -257,7 +251,6 @@ static int decode_block(FlateStream *s, HuffTree *lt, HuffTree *dt) {
 	}
 }
 
-/* inflate an uncompressed block of data */
 static int inflate_uncompressed_block(FlateStream *s) {
 	uint len, invlen;
 
@@ -277,20 +270,17 @@ static int inflate_uncompressed_block(FlateStream *s) {
 	return 0;
 }
 
-/* inflate a block of data compressed with fixed huffman trees */
 static int inflate_fixed_block(FlateStream *s) {
 	return decode_block(s, <ree, &dtree);
 }
 
-/* inflate a block of data compressed with dynamic huffman trees */
 static int inflate_dynamic_block(FlateStream *s) {
 	decode_trees(s, &s->ltree, &s->dtree);
 	return decode_block(s, &s->ltree, &s->dtree);
 }
 
-/*
- * extern functions
- */
+
+/* extern functions */
 
 /* initialize global (static) data */
 void inflate_init(void) {
@@ -301,7 +291,7 @@ void inflate_init(void) {
 /* inflate stream from src to dst */
 int inflate(void *dst, uint *dstlen, const void *src, uint srclen) {
 	FlateStream s;
-	uint bfinal;
+	uint final;
 
 	s.src = src;
 	s.nbits = 0;
@@ -309,17 +299,14 @@ int inflate(void *dst, uint *dstlen, const void *src, uint srclen) {
 	s.dstlen = dstlen;
 	*dstlen = 0;
 	do {
-		uint btype;
+		uint blocktype;
 		int res;
 
-		/* read final block flag */
-		bfinal = getbit(&s);
-
-		/* read block type */
-		btype = getbits(&s, 2);
+		final = getbit(&s);
+		blocktype = getbits(&s, 2);
 
 		/* decompress block */
-		switch (btype) {
+		switch (blocktype) {
 		case 0:
 			res = inflate_uncompressed_block(&s);
 			break;
@@ -334,7 +321,7 @@ int inflate(void *dst, uint *dstlen, const void *src, uint srclen) {
 		}
 		if (res != 0)
 			return -1;
-	} while (!bfinal);
+	} while (!final);
 	return 0;
 }
 
@@ -343,7 +330,7 @@ int inflate(void *dst, uint *dstlen, const void *src, uint srclen) {
 #include <stdlib.h>
 
 unsigned char *readall(char *name, uint *len) {
-	ulong size = 1 << 20;
+	ulong size = 1 << 22;
 	uchar *buf;
 	FILE *in;
 
@@ -359,7 +346,7 @@ unsigned char *readall(char *name, uint *len) {
 int main(int argc, char **argv) {
 	int ret;
 	uchar *src;
-	uint srclen, dstlen=1<<16;
+	uint srclen, dstlen=1<<22;
 	uchar *dst;
 
 	if (argc < 2)
@@ -368,10 +355,10 @@ int main(int argc, char **argv) {
 	inflate_init();
 	ret = inflate(dst = malloc(dstlen), &dstlen, src, srclen);
 	if (ret)
-		puts("inflate: error\n");
+		fputs("inflate: error\n", stderr);
 	else
-		printf("inflate: uncompressed %u bytes\n", dstlen);
-	puts((char *)dst);
+		fprintf(stderr, "inflate: uncompressed %u bytes\n", dstlen);
+	fwrite(dst, 1, dstlen, stdout);
 	free(dst);
 	free(src);
 	return ret;