flate

deflate implementation
git clone git://git.suckless.org/flate
Log | Files | Refs | README

commit 8c0e33a192944d350098d5470a05ae72bc725c1f
parent ee5ae6647276d80f78cfa2d2110f11695c39bb3d
Author: nsz <nszabolcs@gmail.com>
Date:   Sun,  7 Jun 2009 21:57:40 +0200

separate decode_symbol_long
Diffstat:
Makefile | 2+-
inflate.c | 89++++++++++++++++++++++++++++++++++++++++---------------------------------------
2 files changed, 46 insertions(+), 45 deletions(-)

diff --git a/Makefile b/Makefile @@ -20,7 +20,7 @@ clean: prof: inflate.c - gcc -fprofile-arcs -ftest-coverage -pg -g -Wall $< + gcc -O3 -fprofile-arcs -ftest-coverage -pg -g -Wall $< cat a.dat | ./a.out > /dev/null gcov -b $< > /dev/null gprof a.out > $<.gprof diff --git a/inflate.c b/inflate.c @@ -1,5 +1,4 @@ #include <stdlib.h> -#include <string.h> typedef unsigned char uchar; typedef unsigned short ushort; @@ -197,6 +196,10 @@ static int build_huff(Huff *huff, uchar *lens, uint n, uint nbits) { table[code].sym = i << 1; code = revinc(code, nbits); } +/* +for (i = 0; i < CodeBits - nbits - 1; i++) + count[i] = count[i + nbits + 1]; +*/ return 0; } @@ -239,6 +242,46 @@ static uint getbits(State *s, int n) { return k; } +/* decode symbol bitwise if code is longer than huffbits */ +static uint decode_symbol_long(State *s, Huff *huff, uint bits, uint nbits, int cur) { + int sum = huff->sum; + uint huffbits = huff->nbits; + ushort *count = huff->count + huffbits + 1; + + /* get bits if we are near the end */ + if (s->src + 2 >= s->srcend) { + while (nbits < CodeBits - 1 && s->src < s->srcend) { + bits |= *s->src++ << nbits; + nbits += 8; + } + s->bits = bits; + s->nbits = nbits; + } + bits >>= huffbits; + nbits -= huffbits; + for (;;) { + if (!nbits--) { + if (s->src == s->srcend) + return FlateNeedInput; + bits = *s->src++; + nbits = 7; + } + cur |= bits & 1; + bits >>= 1; + sum += *count; + cur -= *count; + if (cur < 0) + break; + cur <<= 1; + count++; + if (count == huff->count + CodeBits) + return FlateError; + } + s->bits = bits; + s->nbits = nbits; + return huff->symbol[sum + cur]; +} + /* decode a symbol from stream with huff code */ static uint decode_symbol(State *s, Huff *huff) { uint huffbits = huff->nbits; @@ -282,51 +325,9 @@ static uint decode_symbol(State *s, Huff *huff) { return entry.sym; } else if (entry.len == 0) return FlateError; - /* code is longer than huffbits: bitwise decode the rest */ - { - int cur = entry.sym; - int sum = huff->sum; - /* TODO: count[0..huffbits] is never needed */ - ushort *count = huff->count + huffbits + 1; - int needinput = 0; - - /* save bits if we are near the end */ - if (s->src + 2 >= s->srcend) { - while (nbits < CodeBits - 1 && s->src < s->srcend) { - bits |= *s->src++ << nbits; - nbits += 8; - } - s->bits = bits; - s->nbits = nbits; - needinput = 1; - } - bits >>= huffbits; - nbits -= huffbits; - for (;;) { - if (!nbits--) { - if (needinput) - return FlateNeedInput; - bits = *s->src++; - nbits = 7; - } - cur |= bits & 1; - bits >>= 1; - sum += *count; - cur -= *count; - if (cur < 0) - break; - cur <<= 1; - count++; - if (count == huff->count + CodeBits) - return FlateError; - } - s->bits = bits; - s->nbits = nbits; - return huff->symbol[sum + cur]; - } + return decode_symbol_long(s, huff, bits, nbits, entry.sym); } - /* decode a block of data from stream with trees */ static int decode_block(State *s, Huff *lhuff, Huff *dhuff) { uchar *win = s->win;