#include "lzw.h" #include "utils.h" #include #include #include #include #define READ_BUFFER_SIZE 4096 #define DECOMPRESS_BUFFER_SIZE 4096 uint8_t read_buffer[READ_BUFFER_SIZE], decompress_buffer[DECOMPRESS_BUFFER_SIZE]; int decompress_file(char* filename) { char* outfilename; FILE *fp, *outfp; int i; unsigned int ifnlen, ofnlen; struct lzw_ctx* lzw; unsigned long int copied_bytes = 0; size_t read_available, read_consumed, decompress_consumed; lzw = (struct lzw_ctx*)malloc(sizeof(struct lzw_ctx)); if (lzw == NULL) return 0; lzw_init(lzw); fp = fopen(filename, "rb"); if (fp == NULL) { perror("fopen()"); return -1; } ifnlen = strlen(filename); ofnlen = ifnlen + 5; outfilename = (char*)malloc(ofnlen); strlcpy(outfilename, filename, ofnlen); for (i = ifnlen - 1; i > 0 && outfilename[i] != '/'; i--) if (outfilename[i] == '.') { outfilename[i] = '\0'; break; } if (strcmp(filename, outfilename) == 0) strlcat(outfilename, ".out", ofnlen); printf("Writing to %s\n", outfilename); outfp = fopen(outfilename, "wb"); if (outfp == NULL) { perror("fopen()"); free(outfilename); return -1; } read_available = read_consumed = decompress_consumed = 0; while (1) { if (read_consumed >= read_available) { read_available = fread(read_buffer, 1, READ_BUFFER_SIZE, fp); read_consumed = 0; } if (decompress_consumed >= DECOMPRESS_BUFFER_SIZE || ((lzw->eos != 0 || read_available == 0) && decompress_consumed > 0)) { fwrite(decompress_buffer, 1, decompress_consumed, outfp); copied_bytes += decompress_consumed; decompress_consumed = 0; } if (lzw->eos || read_available == 0) break; lzw_decompress(lzw, read_buffer, read_available, &read_consumed, decompress_buffer, DECOMPRESS_BUFFER_SIZE, &decompress_consumed); } free(outfilename); fclose(outfp); fclose(fp); printf("Extracted %lu bytes", copied_bytes); return 0; } int main(int argc, char* argv[]) { int i; for (i = 1; i < argc; i++) { printf("Decompressing %s\n", argv[i]); decompress_file(argv[i]); } return EXIT_SUCCESS; }