diff options
author | David Schleef <ds@schleef.org> | 2005-04-28 07:30:58 +0000 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2005-04-28 07:30:58 +0000 |
commit | eb6ae36041277cde75b484d3e0fc35277f83a52a (patch) | |
tree | c46dbe683554f5d014926ff45074ba9006024274 /examples/huffman/huffman.c | |
parent | d580485d8c617dd469d127cc1bdbdc99f076d3e3 (diff) | |
download | liboil-eb6ae36041277cde75b484d3e0fc35277f83a52a.tar.gz |
Add an example huffman (variable code length) decoder
* configure.ac:
* examples/Makefile.am:
* examples/huffman/Makefile.am:
* examples/huffman/huffman.c: (huffman_new), (huffman_add_code),
(huffman_decode_iterate), (huffman_decode_ref):
* examples/huffman/huffman.h:
* examples/huffman/huffman_test.c: (main):
Diffstat (limited to 'examples/huffman/huffman.c')
-rw-r--r-- | examples/huffman/huffman.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/examples/huffman/huffman.c b/examples/huffman/huffman.c new file mode 100644 index 0000000..b1eee26 --- /dev/null +++ b/examples/huffman/huffman.c @@ -0,0 +1,84 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "huffman.h" + + + +Huffman * +huffman_new (void) +{ + Huffman *huff; + + huff = malloc (sizeof (Huffman)); + memset (huff, 0, sizeof(Huffman)); + + return huff; +} + + +void +huffman_add_code (Huffman *huff, unsigned int code, int n_bits, + int value) +{ + huff->codes = realloc(huff->codes, + sizeof(HuffmanCode) * (huff->n_codes + 1)); + huff->codes[huff->n_codes].value = value; + huff->codes[huff->n_codes].code = code << (32 - n_bits); + huff->codes[huff->n_codes].mask = 0xffffffff << (32 - n_bits); + huff->codes[huff->n_codes].n_bits = n_bits; + + huff->n_codes++; +} + + +void huffman_decode_iterate (Huffman *huff) +{ + unsigned int bits; + int i; + + if (huff->state == HUFF_NEED_BYTE) { + huff->state_bits = (huff->state_bits << 8) | huff->next_byte; + huff->state_n_bits += 8; + } + + bits = huff->state_bits << (32 - huff->state_n_bits); + + for(i=0;i<huff->n_codes;i++){ + if (huff->codes[i].n_bits <= huff->state_n_bits && + huff->codes[i].code == (bits & huff->codes[i].mask)) { + huff->out_value = huff->codes[i].value; + break; + } + } + if (i == huff->n_codes) { + huff->state = HUFF_NEED_BYTE; + } else { + huff->state = HUFF_OK; + } + +} + +void huffman_decode_ref (Huffman *huff, int *dest, unsigned char *src, int n) +{ + int i; + + i = 0; + while(n>0 || huff->state == HUFF_OK){ + printf("STATE %d\n", huff->state); + if (huff->state == HUFF_NEED_BYTE) { + printf("pushing byte %02x\n", *src); + huff->next_byte = *src; + src++; + n--; + } + huffman_decode_iterate (huff); + if (huff->state == HUFF_OK) { + printf("got value %d\n", huff->out_value); + dest[i] = huff->out_value; + } + } +} + |