diff --git a/huffman.c b/huffman.c index 5098f56..eb56fe1 100644 --- a/huffman.c +++ b/huffman.c @@ -1,11 +1,10 @@ #include "huffman.h" -#include #include #include -static int -find_smallest (struct huffman_node **nodes, int count, int different) +static uint64_t +find_smallest (struct huffman_node **nodes, uint64_t count, int different) { // 'real' weights will always be positive. int smallest = -1; @@ -26,9 +25,9 @@ find_smallest (struct huffman_node **nodes, int count, int different) } static void -shift_nodes (struct huffman_node **nodes, int count, int start) +shift_nodes (struct huffman_node **nodes, uint64_t count, uint64_t start) { - int i; + uint64_t i; for (i = start; i + 1 < count; i++) { nodes[i] = nodes[i + 1]; } @@ -37,7 +36,7 @@ shift_nodes (struct huffman_node **nodes, int count, int start) struct huffman_node * -huffman_build_tree(void **values, int count) +huffman_build_tree(void **values, uint64_t count) { int i; struct huffman_node **nodes; diff --git a/huffman.h b/huffman.h index 1f5cc25..be6fddd 100644 --- a/huffman.h +++ b/huffman.h @@ -1,4 +1,5 @@ #include +#include struct huffman_node { int weight; @@ -7,7 +8,7 @@ struct huffman_node { struct huffman_node *right; }; -struct huffman_node *huffman_build_tree(void **values, int count); +struct huffman_node *huffman_build_tree(void **values, uint64_t count); void *huffman_lookup (struct huffman_node *tree, unsigned char *bits, int *bits_read, bool print); diff --git a/unpack.c b/unpack.c index fbe71b1..a0f79b0 100644 --- a/unpack.c +++ b/unpack.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -140,16 +141,37 @@ load_content_sets(FILE *stream, struct node **list, int *node_count, unsigned char count; fread(&count, sizeof (unsigned char), 1, stream); + uint64_t big_count; + + if (count & 0x80) { + unsigned short count_bytes = count & 0x7F; + unsigned char *size_buf = malloc (sizeof (char *) * + count_bytes); + fread (size_buf, sizeof (char), count_bytes, stream); + + printf ("found count: %hd\n", count_bytes); + printf ("%hd\n", (unsigned short) size_buf[0]); + printf ("%hd\n", size_buf[1]); + + big_count = 0; + int offset = sizeof (uint64_t ) - count_bytes; + + memcpy (((void *) &big_count) + offset, size_buf, count_bytes); + big_count = be64toh (big_count); + } else { + big_count = count; + } + if (stats) { printf ("node stats:\n"); - printf ("\tnumber of nodes: %hd\n", count); + printf ("\tnumber of nodes: %lu\n", big_count); } else if (raw) { - printf ("Nodes (%d entries):\n", count); + printf ("Nodes (%lu entries):\n", big_count); } - nodes = malloc (sizeof (struct node *) * (unsigned short) count); - for (i = 0; i < (unsigned short) count; i++) { + nodes = malloc (sizeof (struct node *) * big_count); + for (i = 0; i < big_count; i++) { nodes[i] = malloc (sizeof (struct node)); } @@ -165,10 +187,10 @@ load_content_sets(FILE *stream, struct node **list, int *node_count, */ struct huffman_node *tree = huffman_build_tree ((void **) nodes + 1, - (unsigned short) count - 1); + big_count - 1); int bits_read = 0; - for (i = 0; i < count; i++) { + for (i = 0; i < big_count; i++) { struct node *node = nodes[i]; node->count = 0;