diff --git a/libmineziper/include/libmineziper_zip.h b/libmineziper/include/libmineziper_zip.h index 324b495..69462dc 100644 --- a/libmineziper/include/libmineziper_zip.h +++ b/libmineziper/include/libmineziper_zip.h @@ -76,7 +76,7 @@ typedef struct ISH unsigned last_block : 1; unsigned block_type : 2; }; - } + }; } ISH; // Dynamic Huffman Code header for DEFLATE @@ -96,26 +96,21 @@ typedef struct zip EOCD* eocd; } zip; -// Huffman Node and Table -typedef struct HN -{ - unsigned char symbol; - unsigned char code; - unsigned char len; -} HN; - -typedef struct HT -{ - unsigned char size; - HN* nodes; -} HT; - void get_eocd(raw* raw, zip* out); void get_cdh(raw* raw, zip* out); -char* get_encoded_data(zip* in, int n); +char* get_encoded_block(zip* in, int n); void parse_zip(char* filename, zip* out); void deflate(zip* in); + +short decode_length_token(bitstream* bs, int token); +int decode_distance_token(bitstream* bs, int token); + +char* decode_type1_block( + bitstream* bs, + int uncompressed_size, + char* decoded_data); + static const short length_codes[] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258}; @@ -133,7 +128,4 @@ static const char extra_bits_distance_codes[] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; -short decode_length_token(bitstream* bs, int token); -int decode_distance_token(bitstream* bs, int token); - #endif \ No newline at end of file diff --git a/libmineziper/src/libmineziper_zip.c b/libmineziper/src/libmineziper_zip.c index c0aa210..8c76ba0 100644 --- a/libmineziper/src/libmineziper_zip.c +++ b/libmineziper/src/libmineziper_zip.c @@ -2,6 +2,7 @@ #include #include +#include "libmineziper_huffman_tree.h" #include "libmineziper_zip.h" void get_eocd(raw* raw, zip* out) @@ -45,12 +46,49 @@ void get_cdh(raw* raw, zip* out) } } -char* get_encoded_data(zip* in, int n) +char* get_encoded_block(zip* in, int n) { return (char*) (in->lfh[n]) + sizeof(LFH) + in->lfh[n]->filename_length + in->lfh[n]->extra_field_length; } +char* decode_type1_block(bitstream* bs, int uncompressed_size, char* decoded_data) +{ + tree tr = build_default_tree(); + tree tr_dist = build_default_dist_tree(); + + int i = 0, token; + while (i < uncompressed_size && (token = next_token(bs, tr)) != END_OF_BLOCK) + { + if (token < END_OF_BLOCK) + { + printf("token[%d]: 0x%x\n", i, token); + decoded_data[i++] = token; + } + + else + { + int length = decode_length_token(bs, token); + + if ((token = next_token(bs, tr_dist)) == END_OF_BLOCK) + { + printf("[ERROR] Got EndOfBlock when decoding distance token\n"); + exit(1); + } + + int distance = decode_distance_token(bs, token); + + printf("token[%d]: token[-%d] with length %d\n", i, distance, length); + + for (int j = 0; j < length; j++) + { + decoded_data[i] = decoded_data[i - distance]; + i++; + } + } + } +} + short decode_length_token(bitstream* bs, int token) { token -= END_OF_BLOCK + 1; diff --git a/tests/test_decode_fixed_tree.c b/tests/test_decode_fixed_tree.c index c37fef6..235fdbe 100644 --- a/tests/test_decode_fixed_tree.c +++ b/tests/test_decode_fixed_tree.c @@ -1,4 +1,5 @@ #include +#include #include #include "libmineziper.h" @@ -34,7 +35,7 @@ void main() { printf("BLOC %d:\n", k); - unsigned int real_size = zip.lfh[k]->uncompressed_size; + unsigned int uncompressed_size = zip.lfh[k]->uncompressed_size; if (zip.lfh[k]->compressed_size == 0) { @@ -44,7 +45,7 @@ void main() { if (zip.cdh[k]->compression_method == DEFLATE) { - char* data = get_encoded_data(&zip, k); + char* data = get_encoded_block(&zip, k); bitstream bs = init_bitstream(data, 0 /*TODO WWEUWIEUWIEUWI*/, 0); @@ -56,49 +57,15 @@ void main() if (deflate_header.block_type == 1) { - tree tr = build_default_tree(); - tree tr_dist = build_default_dist_tree(); + char* decoded_data = malloc(uncompressed_size); - char* decoded_data = malloc(real_size); - int i = 0; - int token; - while (i < real_size && (token = next_token(&bs, tr)) != END_OF_BLOCK) - { - if (token < END_OF_BLOCK) - { - printf("token[%d]: 0x%x\n", i, token); - decoded_data[i++] = token; - } - - else - { - int length = decode_length_token(&bs, token); - - if ((token = next_token(&bs, tr_dist)) == END_OF_BLOCK) - { - printf("[ERROR] Got EndOfBlock when decoding distance token\n"); - exit(1); - } - - int distance = decode_distance_token(&bs, token); - - printf( - "token[%d]: token[-%d] with length %d\n", - i, - distance, - length); - - for (int j = 0; j < length; j++) - { - decoded_data[i] = decoded_data[i - distance]; - i++; - } - } - } + decode_type1_block(&bs, uncompressed_size, decoded_data); FILE* tmp_file = fopen("/tmp/test.txt", "w"); - fwrite(decoded_data, 1, i, tmp_file); + fwrite(decoded_data, 1, uncompressed_size, tmp_file); fclose(tmp_file); + + free(decoded_data); } else if (deflate_header.block_type == 2) @@ -117,6 +84,7 @@ void main() } } +/* void handle_type2(char* data) { DHCH* dynamic_huffman_code_header = data; @@ -145,4 +113,5 @@ void handle_type2(char* data) { printf("For length %d: %d\n", i, code_length[i].len); } -} \ No newline at end of file +} +*/ \ No newline at end of file