//main int main (int argc, char* argv[]) { //keep frequencies in array for (int i = 0; i < SYMBOLS; i++) frequencies[i] = 0; //make sure user inputs two arguments if (argc != 3) { printf("You must enter %s input output\n", argv[0]); return 1; } //open input FILE *fp = fopen(argv[1],"r" ); if (fp == NULL) { printf("Could not open souce file: %s\n", argv[1]); return 1; } //open output Huffile *outfile = hfopen(argv[2], "w"); if (outfile == NULL) { printf("Could not open destination file: %s\n", argv[2]); return 1; } //create a forest Forest *myForest = mkforest(); if (myForest == NULL) { printf("The forest could not be created :(\n"); return 1; } //read each character from source file for (int c = fgetc(fp); c!= EOF; c = fgetc(fp)) { //printf("%c", c); //increment frequencies for char frequencies[c]++; //increment checksum checksum_counter++; } //make and plant trees in sorted order for (int i = 0; i < SYMBOLS; i++) { if (frequencies[i] != 0) { //make the tree Tree *tempTree = mktree(); tempTree->symbol = i; tempTree->frequency = frequencies[i]; tempTree->left = NULL; tempTree->right = NULL; //plant tree in forest if (plant(myForest, tempTree) == false) printf("Could not plant tree %c\n", i); } } //build the huffman tree while (myForest->first->tree->frequency < checksum_counter) { //make the tree Tree *tempTree = mktree(); tempTree->symbol = 0x00; tempTree->left = pick(myForest); tempTree->right = pick(myForest); if (tempTree->right != NULL) tempTree->frequency = tempTree->left->frequency + tempTree->right->frequency; else tempTree->frequency = tempTree->left->frequency; //plant tree in forest if (plant(myForest, tempTree) == false) printf("Could not plant parent tree\n"); } //create encoding of each character for (int i = 0; i < SYMBOLS; i++) { if (frequencies[i] != 0) { //create a temporary array to store the encoded value char temp[256]; for (int j = 0; j < 256; j++) temp[j] = '9'; encode(myForest->first->tree, i, 0, "", &temp[0]); //copy temp to encoded strncpy(encoded[i], temp, strlen(temp)); //printf("temp: %s\n", temp); //printf("encoded: %c, hops: %s ", i, encoded[i]); } } //create huffeader header Huffeader *header = malloc(sizeof(Huffeader)); header->magic = MAGIC; for (int i = 0; i < SYMBOLS; i++) header->frequencies[i] = frequencies[i]; header->checksum = checksum_counter; //write header hwrite(header, outfile); //move to beginning of source file rewind(fp); //keep track of how many bits we use int bit_count = 0; //read file per character, lookup frequency, and write to outfile for (int c = fgetc(fp); c!= EOF; c = fgetc(fp)) { for (int i = 0; i < strlen(encoded[c]); i++) { bit_count++; int bit = 0; //write each bit if (encoded[c][i] == '0') bit = 0; else if (encoded[c][i] == '1') bit = 1; bool write_output = bwrite(bit, outfile); if (write_output == false) printf("Error bwriting: %c\n", encoded[c][i]); //printf("%c bit_count: %d\n", encoded[c][i], bit_count); } //printf("%s", encoded[c]); } //figure out how many bits in second to last byte are used int bits_used = 0; if (bit_count <= 8) bits_used = bit_count; else bits_used = (bit_count % 8); //write trailing bits for (int i = 8 - bits_used; i > 1; i--) { //printf("0\n"); bool write_output = bwrite(0, outfile); if (write_output == false) printf("Error bwriting: %c\n", '0'); } //cleanup outfile->ith = bits_used; free(header); rmforest(myForest); hfclose(outfile); fclose(fp); return 0; }
int main(int argc, char* argv[]) { // ensure proper usage if (argc != 3) { printf("Usage: %s input output\n", argv[0]); return 1; } // open input Huffile* input = hfopen(argv[1], "r"); if (input == NULL) { printf("Could not open %s for reading.\n", argv[1]); return 1; } // open outfile FILE* outfile = fopen(argv[2], "w"); // read in header Huffeader header; if (hread(&header, input) == false) { hfclose(input); printf("Could not read header.\n"); return 1; } // check for magic number if (header.magic != MAGIC) { hfclose(input); printf("File was not huffed.\n"); return 1; } // check checksum int checksum = header.checksum; for (int i = 0; i < SYMBOLS; i++) { checksum -= header.frequencies[i]; } if (checksum != 0) { hfclose(input); printf("File was not huffed.\n"); return 1; } // make forest Forest* forest = mkforest(); // search for symbols that are non-zero frequency for (int i = 0; i < SYMBOLS; i++) { // make and plant the trees in the forest if (header.frequencies[i] >= 1) { Tree* newTree = mktree(); newTree->frequency = header.frequencies[i]; newTree->symbol = i; newTree->left = NULL; newTree->right = NULL; plant(forest, newTree); } } // run loop until there is only one tree left bool done = false; while (!done) { // pick smallest tree Tree* a = pick(forest); // pick second smallest tree Tree* b = pick(forest); // if there is only one tree left in the forest, a is the huffman tree if (b == NULL) { done = true; root = a; } // if two trees were succesfully picked else { // combine the two trees by calling the combine function Tree* combinedTree = combine(a, b); // plant combined tree back in forest plant(forest, combinedTree); } } // write message to file int bit; Tree* cursor = root; while ((bit = bread(input)) != EOF) { // if bit == 0 -> go left if (bit == 0) { cursor = cursor->left; } // if bit == 1 -> go right else if (bit == 1) { cursor = cursor->right; } // when you find a leaf if ((cursor->right == NULL) && (cursor->left == NULL)) { // print the leaf fprintf(outfile, "%c", cursor->symbol); // reset the cursor to root for the next iteration cursor = root; } } // free root rmtree(root); // close forest rmforest(forest); // close input hfclose(input); // close outfile fclose(outfile); // that's all folks! return 0; }
int main(int argc, char* argv[]) { // ensure proper usage if (argc != 3) { printf("Usage: %s input output\n", argv[0]); return 1; } // open input Huffile* input = hfopen(argv[1], "r"); if (input == NULL) { printf("Could not open %s for reading.\n", argv[1]); return 1; } // read in header Huffeader header; if (hread(&header, input) == false) { hfclose(input); printf("Could not read header.\n"); return 1; } // check for magic number if (header.magic != MAGIC) { hfclose(input); printf("File was not huffed.\n"); return 1; } // check checksum int checksum = header.checksum; for (int i = 0; i < SYMBOLS; i++) { checksum -= header.frequencies[i]; } if (checksum != 0) { hfclose(input); printf("File was not huffed.\n"); return 1; } int index; Forest* f1 = mkforest(); for(index = 0; index<SYMBOLS;index++) { if(header.frequencies[index] != 0) { Tree* t1 = mktree(); t1->symbol = (char)index; t1->frequency = header.frequencies[index]; plant(f1,t1); } } while(true) { Tree* temp1 = pick(f1); Tree* temp2 = pick(f1); if(temp2 != NULL) { Tree* new_tree = mktree(); new_tree->left = temp1; new_tree->right = temp2; new_tree->frequency = temp1->frequency + temp2->frequency; plant(f1,new_tree); } else { plant(f1,temp1); break; } } Tree* huffman_tree = pick(f1); int bit; Tree* temp = huffman_tree; FILE *output = fopen(argv[2],"w"); while ((bit = bread(input)) != EOF) { if(bit == 1) { temp = temp->right; if(temp->right == NULL && temp->left ==NULL) { fprintf(output,"%c",temp->symbol); temp = huffman_tree; } } else { temp = temp->left; if(temp->right == NULL && temp->left ==NULL) { fprintf(output,"%c",temp->symbol); temp = huffman_tree; } } } // close input hfclose(input); return 0; }
bool createForest(char *path) { // create empty forest f = mkforest(); // open input Huffile* input = hfopen(path, "r"); if (input == NULL) { printf("Could not open %s for reading.\n", path); return 0; } // read in header Huffeader header; if (hread(&header, input) == false) { hfclose(input); printf("Could not read header.\n"); return 0; } // read symbols and freq from header, create and plant trees in forest for (int i = 0; i < SYMBOLS; i++) { if ( header.frequencies[i] != 0 ) { Tree *t = mktree(); t->symbol = i; t->frequency = header.frequencies[i]; plant(f, t); count++; } } // join trees as siblings for (int i = 0; i < count - 1; i++) { Tree *t = mktree(); t->left = pick(f); t->right = pick(f); t->frequency = t->left->frequency + t->right->frequency; plant(f, t); } // close input hfclose(input); return true; }
int main(int argc, char* argv[]) { // ensure proper usage if (argc != 3) { printf("Usage: %s input\n", argv[0]); return 1; } // open input Huffile* input = hfopen(argv[1], "r"); if (input == NULL) { printf("Could not open %s for reading.\n", argv[1]); return 1; } // open outfile FILE* outfile = fopen(argv[2], "w"); if (outfile == NULL) { fclose(outfile); fprintf(stderr, "Could not create outfile.\n"); return 2; } // read in header Huffeader header; if (hread(&header, input) == false) { hfclose(input); printf("Could not read header.\n"); return 1; } // check for magic number if (header.magic != MAGIC) { hfclose(input); printf("File was not huffed.\n"); return 1; } // check checksum int checksum = header.checksum; for (int i = 0; i < SYMBOLS; i++) { checksum -= header.frequencies[i]; } if (checksum != 0) { hfclose(input); printf("File was not huffed.\n"); return 1; } // make forest Forest* forest = mkforest(); // read in huffeader frequencies for (int i = 0; i < SYMBOLS; i++) { // ignore 0 frequencies if (header.frequencies[i] > 0) { // make new tree for every non-zero frequency occurance Tree* new_tree = mktree(); new_tree->symbol = i; new_tree->frequency = header.frequencies[i]; new_tree->left = NULL; new_tree->right = NULL; // plant every non-zero frequency tree in forest plant(forest, new_tree); } } // run loop until there is only one tree left bool done = false; while (!done) { // pick smallest tree from forest Tree* a = pick(forest); // pick second smallest tree from forest Tree* b = pick(forest); // if there is no second tree in forest... if (b == NULL) { // break loop done = true; // set root to tree 'a' (last remaining) tree root = a; } // else there are at least two remaining trees in the forest else { // combine the two trees into a parent tree Tree* parent_tree = combine(a, b); // plant combined tree in forest plant(forest, parent_tree); } } // write message to outfile int bit; Tree* ptr_location = root; while ((bit = bread(input)) != EOF) { // if bit is 0, go left, else go right if (bit == 0) ptr_location = ptr_location->left; // if bit is 1, go right if (bit == 1) ptr_location = ptr_location->right; // leaf is found when both branchs are NULL if ((ptr_location->left == NULL) && (ptr_location->right == NULL)) { // write leaf's symbol to outfile fprintf(outfile, "%c", ptr_location->symbol); // reset pointer location to root for next iteration of tree ptr_location = root; } } // free root rmtree(root); // close forest rmforest(forest); // close input & outfile hfclose(input); fclose(outfile); // that's all folks! return 0; }