/** * Open file and check if it is Huffile. * Return NULL if not Huffile or other mistake, else return Huffile *. */ bool isHuffile(char *path) { // 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; } // check for magic number if (header.magic != MAGIC) { hfclose(input); printf("File was not huffed.\n"); return 0; } // 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 0; } // close input hfclose(input); return true; }
int main(int argc, char* argv[]) { // ensure proper usage if (argc != 2) { 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; } // 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; } // determine number of rows to use const int rows = (int) ceil((LAST - FIRST) / (double) COLS); // dump frequencies in a nice table printf("\n"); for (int row = 0; row < rows; row++) { for (int col = 0; col < COLS; col++) { int index = FIRST + row + rows * col; if (index > LAST) { break; } printf("%c %-6d ", index, header.frequencies[index]); } printf("\n"); } printf("\n"); // dump bits contiguously int bit; while ((bit = bread(input)) != EOF) { printf("%d", bit); } printf("\n\n"); // close input hfclose(input); // that's all folks! return 0; }
//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; }
/** * decompress Huffile and print to file. */ bool decompress(char *path1, char *path2) { // open input Huffile* input = hfopen(path1, "r"); if (input == NULL) { printf("Could not open %s for reading.\n", path1); return false; } // read in header Huffeader header; if (hread(&header, input) == false) { hfclose(input); printf("Could not read header.\n"); return false; } // open file for writing FILE *out = fopen(path2, "w"); if (out == NULL) { printf("Could not open %s for writing.\n", path2); return false; } // read bits, crawl the tree and write to out int bit; char ch; Tree *p = f->first->tree; // check single-character file if ( count == 1 ) { ch = p->symbol; if ( fputc(ch, out) == EOF ) { printf("can't write\n"); return false; } return true; } while ((bit = bread(input)) != EOF) { if ( bit == 0 ) { p = p->left; if ( isLeaf(p) ) { ch = p->symbol; if ( fputc(ch, out) == EOF ) { printf("can't write\n"); return false; } p = f->first->tree; } } else if ( bit == 1 ) { p = p->right; if ( isLeaf(p) ) { ch = p->symbol; if ( fputc(ch, out) == EOF ) { printf("can't write\n"); return false; } p = f->first->tree; } } } return true; }
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 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; }
/*! <pre> ******************************************************************************* * Function : hyp_open_file * Arguments : * Returns : * Purpose : Attempts to open a hypothesis file that is associated with the opened * PFM specified by the PFM handle. NULL is returned if the file ".hyp" * could not be found. ******************************************************************************* </pre>*/ HypHead* hyp_open_file( char *list_file_path, NV_INT32 pfmhnd ) { HypHead *hyp; char filename[256]; /* Form the filename for the .hyp file */ if( hyp_form_hyp_filename( list_file_path, filename ) < 0 ) { sprintf( hyp_err_str, "Could not locate information from PFM list file '%s'.", list_file_path ); return NULL; } /* Create HypHead object */ hyp = (HypHead*)calloc(1, sizeof(HypHead)); memset( hyp, 0, sizeof(HypHead) ); /* Try to open hugeio file */ hyp->pfmhnd = pfmhnd; hyp->filehnd = hfopen( filename, "r+b" ); if( hyp->filehnd == -1 ) { hyp->filehnd = hfopen( filename, "rb" ); hyp->readonly = NVTrue; } if( hyp->filehnd == -1 ) { sprintf( hyp_err_str, "Could not load cube hypotheses from PFM file '%s'.", list_file_path ); if (hyp) { free( hyp ); hyp = NULL; } return NULL; } hyp->cube_param = (CubeParam *) calloc (1, sizeof(CubeParam)); /* Read bin header from pfm file */ read_bin_header( pfmhnd, &hyp->bin_header ); /* Create the Cube parameters */ /* hyp->cube_param = cube_init_param( HYP_DEFAULT_IHO_ORDER, hyp->bin_header.bin_size_xy, hyp->bin_header.bin_size_xy ); hyp->hypo_resolve_algo = hyp->cube_param->mthd; hyp->node_capture_percent = hyp->cube_param->capture_dist_scale * 100.0f; */ /* Read the header information from the file */ hyp_read_header( hyp ); /* Check that hyp version is proper */ if( hyp->version < 1.0 || hyp->version > HYP_VERSION ) { sprintf( hyp_err_str, "Hypothesis file had unsupported version '%.2f'. This file may have been created with a newer version of the software.", hyp->version ); if( hyp->cube_param ) free (hyp->cube_param); /* cube_release_param( hyp->cube_param ); */ if (hyp) { free( hyp ); hyp = NULL; } return NULL; } /* Check that hyp size is proper */ if( (hyp->ncols != hyp->bin_header.bin_width) || (hyp->nrows != hyp->bin_header.bin_height) ) { sprintf( hyp_err_str, "Hypothesis file did not match PFM file in size." ); if (hyp->cube_param ) { free (hyp->cube_param); hyp->cube_param = NULL; } /* cube_release_param( hyp->cube_param ); */ if (hyp) { free( hyp ); hyp = NULL; } return NULL; } /* Make sure file size matches expected */ /* hfseek( hyp->filehnd, 0, SEEK_END ); if( hftell( hyp->filehnd ) != hyp->file_size ) { sprintf( hyp_err_str, "Hypothesis file size is not correct. File may have been corrupted." ); free( hyp ); return NULL; }*/ /* Return created HypHead object */ return hyp; }
/*! <pre> ******************************************************************************* * Function : hyp_create_file * Arguments : * Returns : * Purpose : Creates a new hypothesis file with extension ".hyp". Associates the * structure with an open handle to a PFM file. The HYP data structure * built will be the same size as the existing PFM file. The attributes tell * the library where to find information from the PFM file. The horizontal * and vertical error attributes are required, but the others can be disabled * by passing -1. ******************************************************************************* </pre>*/ HypHead* hyp_create_file( char *list_file_path, NV_INT32 pfmhnd, NV_INT32 horizErrorAttr, NV_INT32 vertErrorAttr, NV_INT32 numHyposAttr, NV_INT32 hypoStrengthAttr, NV_INT32 uncertaintyAttr, NV_INT32 customHypoFlag ) { HypHead *hyp; char filename[256], *data; NV_INT32 hnd, i, j, percent, old_percent; /* Form the filename for the .hyp file */ if( hyp_form_hyp_filename( list_file_path, filename ) < 0 ) { fprintf(stderr, "Could not locate information from PFM list file '%s'.", list_file_path ); return NULL; } /* Try to open hugeio file */ hnd = hfopen( filename, "w+b" ); if( hnd == -1 ) { sprintf( hyp_err_str, "Error creating file in '%s'.", filename ); return NULL; } /* Create new object and initialize */ hyp = (HypHead *)calloc(1, sizeof(HypHead)); memset( hyp, 0, sizeof(HypHead) ); hyp->cube_param = (CubeParam *) calloc (1, sizeof(CubeParam)); read_bin_header( pfmhnd, &hyp->bin_header ); hyp->version = HYP_VERSION; hyp->pfmhnd = pfmhnd; hyp->ncols = hyp->bin_header.bin_width; hyp->nrows = hyp->bin_header.bin_height; hyp->filehnd = hnd; hyp->readonly = NVFalse; #ifdef HYP_LITENDIAN hyp->endian = HYP_FTYPE_LITENDIAN; #else hyp->endian = HYP_FTYPE_BIGENDIAN; #endif hyp->vert_error_attr = vertErrorAttr; hyp->horiz_error_attr = horizErrorAttr; hyp->num_hypos_attr = numHyposAttr; hyp->hypo_strength_attr = hypoStrengthAttr; hyp->uncertainty_attr = uncertaintyAttr; hyp->custom_hypo_flag = customHypoFlag; hyp->deleted_ptr = 0; hyp->file_size = HYP_ASCII_HEADER_SIZE + HYP_BINARY_HEADER_SIZE + ((NV_INT64)hyp->ncols * (NV_INT64)hyp->nrows * HYP_NODE_RECORD_SIZE); /* Create the Cube parameters */ /* hyp->cube_param = cube_init_param( HYP_DEFAULT_IHO_ORDER, hyp->bin_header.bin_size_xy, hyp->bin_header.bin_size_xy ); hyp->hypo_resolve_algo = hyp->cube_param->mthd; hyp->node_capture_percent = hyp->cube_param->capture_dist_scale * 100.0f; */ /* Write the header information to the file */ hyp_write_header( hyp ); /* Write empty information for the Nodes */ hfseek( hyp->filehnd, HYP_ASCII_HEADER_SIZE + HYP_BINARY_HEADER_SIZE, SEEK_SET ); data = (char*)malloc( HYP_NODE_RECORD_SIZE ); memset( data, 0, HYP_NODE_RECORD_SIZE ); old_percent = 0; for( i = 0; i < hyp->nrows; i++ ) { /* Write row data */ for( j = 0; j < hyp->ncols; j++ ) { hfwrite( (void*)data, HYP_NODE_RECORD_SIZE, 1, hyp->filehnd ); } /* Update status callback */ percent = (NV_INT32)( ((NV_FLOAT32)i / hyp->nrows) * 100.0 ); if (percent != old_percent) { /* Calls a status callback if register. */ if (hyp_progress_callback) (*hyp_progress_callback) (1, percent); old_percent = percent; } } free( data ); /* Return the created HypHead object */ return hyp; }
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; }