#include #include struct node{ struct node* children[256]; unsigned char size; unsigned char character; unsigned char pos; //Not used in encoding struct node* parent; }; typedef struct node* node; void compress(FILE* in, FILE* out); void decompress(FILE* in, FILE* out); int main(int argc, char* argv[]){ if(argc < 4){ printf("Choose option and files!\n"); printf("Options:\n\tc for compress\n\td for decompress\n"); return 0; } FILE* in = fopen(argv[2], "r"); FILE* out = fopen(argv[3], "w"); if(argv[1][0] == 'c'){ compress(in, out); } else{ decompress(in, out); } fclose(in); fclose(out); } node create_node(unsigned char character, unsigned char pos){ node new = malloc(sizeof(struct node)); new->character = character; new->pos = pos; new->size = 0; return new; } node find_parent_enc(node root, unsigned char character){ for(int i = 0; i < root->size; i++){ if(root->children[i]->character == character){ return root->children[i]; } } return NULL; } void recursive_free(node tree){ if(tree != NULL){ for(int i = 0; i < tree->size; i++){ recursive_free(tree->children[i]); } free(tree); } } void free_tree(node tree){ for(int i = 0; i < tree->size; i++){ recursive_free(tree->children[i]); } tree->size = 0; } void enc_write(unsigned char pos, char character, FILE* out){ fputc(pos, out); fputc(character, out); } void compress(FILE* in, FILE* out){ node root = create_node(0, 0); unsigned char pos = 1; unsigned char character; node parent = root; while(fread(&character, 1, 1, in) > 0){ node parent_copy = parent; parent = find_parent_enc(parent_copy, character); if(parent == NULL){ node new = create_node(character, pos); parent_copy->children[parent_copy->size] = new; enc_write(parent_copy->pos, parent_copy->children[parent_copy->size]->character, out); parent_copy->size += 1; pos++; if(pos >= 255){ pos = 1; free_tree(root); } parent = root; } } if(parent != root){ fputc(parent->pos, out); } free_tree(root); free(root); } node find_parent_dec(unsigned char pos, node tree){ if(pos == 0 || tree == NULL){ return NULL; } else if(tree->pos == pos){ return tree; } for(int i = 0; i < tree->size; i++){ node child = find_parent_dec(pos, tree->children[i]); if(child != NULL){ return child; } } return NULL; } void dec_write(node element, FILE* out){ if(element->parent != NULL){ dec_write(element->parent, out); fputc(element->character, out); } } void decompress(FILE* in, FILE* out){ int res = 0; node root = create_node(0, 0); unsigned short pos = 1; unsigned char character; unsigned char parent_pos; while(fread(&parent_pos, 1, 1, in) > 0 && fread(&character, 1, 1, in) > 0){ node parent = find_parent_dec(parent_pos, root); if(parent == NULL){ parent = root; } node new = create_node(character, pos); pos++; new->parent = parent; parent->children[parent->size] = new; parent->size += 1; parent_pos = 0; dec_write(new, out); if(pos >= 255){ free_tree(root); res++; pos = 1; } } if(parent_pos != 0){ node last = find_parent_dec(parent_pos, root); dec_write(last, out); } free_tree(root); free(root); }