void free_huffman_tree(struct Node *root) { if(root == NULL) return; free_huffman_tree(root->left); free_huffman_tree(root->right); free(root); }
static void free_huffman_tree(struct huffman_node* node) { if (node == NULL) return; else if (node->type == NODE_LEAF) { free(node); } else { free_huffman_tree(node->v.tree.bit_0); free_huffman_tree(node->v.tree.bit_1); free(node); } }
static void free_huffman_tree(huffman_node *subtree) { if(subtree == NULL) return; if(!subtree->isLeaf) { free_huffman_tree(subtree->zero); free_huffman_tree(subtree->one); } free(subtree); }
int huffman_decode_file(FILE *in, FILE *out) { huffman_node *root, *p; int c; unsigned int data_count; /* Read the Huffman code table. */ root = read_code_table(in, &data_count); if(!root) return 1; /* Decode the file. */ p = root; while(data_count > 0 && (c = fgetc(in)) != EOF) { unsigned char byte = (unsigned char)c; unsigned char mask = 1; while(data_count > 0 && mask) { p = byte & mask ? p->one : p->zero; mask <<= 1; if(p->isLeaf) { fputc(p->symbol, out); p = root; --data_count; } } } free_huffman_tree(root); return 0; }
/* * huffman_encode_file huffman encodes in to out. */ int huffman_encode_file(FILE *in, FILE *out) { SymbolFrequencies sf; SymbolEncoder *se; huffman_node *root = NULL; int rc; unsigned int symbol_count; /* Get the frequency of each symbol in the input file. */ symbol_count = get_symbol_frequencies(&sf, in); /* Build an optimal table from the symbolCount. */ se = calculate_huffman_codes(&sf); root = sf[0]; /* Scan the file again and, using the table previously built, encode it into the output file. */ rewind(in); rc = write_code_table(out, se, symbol_count); if(rc == 0) rc = do_file_encode(in, out, se); /* Free the Huffman tree. */ free_huffman_tree(root); free_encoder(se); return rc; }
/** * Traverse the Huffman tree and free all the malloced nodes. */ PUBLIC void free_huffman_tree (node_t *tree) { // do not free leaf nodes, as they are not allocated with malloc. if (tree->left == NULL && tree->right == NULL) return; // first free the left and right branches, if they exist. if (tree->left != NULL) free_huffman_tree (tree->left); if (tree->right != NULL) free_huffman_tree (tree->right); // now free the node itself. free (tree); }
int main(int argc, char **argv) { char buf[MAX_INPUT_LEN], enc[LEN*2]; while(scanf("%s", buf) != EOF) { memset(enc, 0, sizeof(enc)); init(buf, strlen(buf)); struct Node *root = build_huffman_tree(); find_char_encoding(root, 0, enc); free_huffman_tree(root); } }
int huffman_decode_memory(const unsigned char *bufin, unsigned int bufinlen, unsigned char **pbufout, unsigned int *pbufoutlen) { huffman_node *root, *p; unsigned int data_count; unsigned int i = 0; unsigned char *buf; unsigned int bufcur = 0; /* Ensure the arguments are valid. */ if(!pbufout || !pbufoutlen) return 1; /* Read the Huffman code table. */ root = read_code_table_from_memory(bufin, bufinlen, &i, &data_count); if(!root) return 1; buf = (unsigned char*)malloc(data_count); /* Decode the memory. */ p = root; for(; i < bufinlen && data_count > 0; ++i) { unsigned char byte = bufin[i]; unsigned char mask = 1; while(data_count > 0 && mask) { p = byte & mask ? p->one : p->zero; mask <<= 1; if(p->isLeaf) { buf[bufcur++] = p->symbol; p = root; --data_count; } } } free_huffman_tree(root); *pbufout = buf; *pbufoutlen = bufcur; return 0; }
int huffman_encode_memory(const unsigned char *bufin, unsigned int bufinlen, unsigned char **pbufout, unsigned int *pbufoutlen) { SymbolFrequencies sf; SymbolEncoder *se; huffman_node *root = NULL; int rc; unsigned int symbol_count; buf_cache cache; /* Ensure the arguments are valid. */ if(!pbufout || !pbufoutlen) return 1; if(init_cache(&cache, CACHE_SIZE, pbufout, pbufoutlen)) return 1; /* Get the frequency of each symbol in the input memory. */ symbol_count = get_symbol_frequencies_from_memory(&sf, bufin, bufinlen); /* Build an optimal table from the symbolCount. */ se = calculate_huffman_codes(&sf); root = sf[0]; /* Scan the memory again and, using the table previously built, encode it into the output memory. */ rc = write_code_table_to_memory(&cache, se, symbol_count); if(rc == 0) rc = do_memory_encode(&cache, bufin, bufinlen, se); /* Flush the cache. */ flush_cache(&cache); /* Free the Huffman tree. */ free_huffman_tree(root); free_encoder(se); free_cache(&cache); return rc; }
static struct huffman_node* build_huffman_tree(struct huffman_frequency* frequencies, unsigned int total_frequencies, int* error) { unsigned int counter = 0; struct huffman_node* built_tree; built_tree = build_huffman_tree_(0, 0, frequencies, total_frequencies, &counter, error); if (built_tree != NULL) { if (total_frequencies > total_leaf_nodes(built_tree)) { *error = HUFFMAN_ORPHANED_LEAF; free_huffman_tree(built_tree); return NULL; } else { return built_tree; } } else { return NULL; } }
static huffman_node* read_code_table_from_memory(const unsigned char* bufin, unsigned int bufinlen, unsigned int *pindex, uint32_t *pDataBytes) { huffman_node *root = new_nonleaf_node(0, NULL, NULL); uint32_t count; /* Read the number of entries. (it is stored in network byte order). */ if(memread(bufin, bufinlen, pindex, &count, sizeof(count))) { free_huffman_tree(root); return NULL; } count = ntohl(count); /* Read the number of data bytes this encoding represents. */ if(memread(bufin, bufinlen, pindex, pDataBytes, sizeof(*pDataBytes))) { free_huffman_tree(root); return NULL; } *pDataBytes = ntohl(*pDataBytes); /* Read the entries. */ while(count-- > 0) { unsigned int curbit; unsigned char symbol; unsigned char numbits; unsigned char numbytes; unsigned char *bytes; huffman_node *p = root; if(memread(bufin, bufinlen, pindex, &symbol, sizeof(symbol))) { free_huffman_tree(root); return NULL; } if(memread(bufin, bufinlen, pindex, &numbits, sizeof(numbits))) { free_huffman_tree(root); return NULL; } numbytes = (unsigned char)numbytes_from_numbits(numbits); bytes = (unsigned char*)malloc(numbytes); if(memread(bufin, bufinlen, pindex, bytes, numbytes)) { free(bytes); free_huffman_tree(root); return NULL; } /* * Add the entry to the Huffman tree. The value * of the current bit is used switch between * zero and one child nodes in the tree. New nodes * are added as needed in the tree. */ for(curbit = 0; curbit < numbits; ++curbit) { if(get_bit(bytes, curbit)) { if(p->one == NULL) { p->one = curbit == (unsigned char)(numbits - 1) ? new_leaf_node(symbol) : new_nonleaf_node(0, NULL, NULL); p->one->parent = p; } p = p->one; } else { if(p->zero == NULL) { p->zero = curbit == (unsigned char)(numbits - 1) ? new_leaf_node(symbol) : new_nonleaf_node(0, NULL, NULL); p->zero->parent = p; } p = p->zero; } } free(bytes); } return root; }
static struct huffman_node* build_huffman_tree_(unsigned int bits, unsigned int length, struct huffman_frequency* frequencies, unsigned int total_frequencies, unsigned int* counter, int* error) { unsigned int i; unsigned int j; struct huffman_node* node = malloc(sizeof(struct huffman_node)); unsigned int max_frequency_length = 0; /*go through the list of frequency values*/ for (i = 0; i < total_frequencies; i++) { /*if our bits and length value is found, generate a new leaf node from that frequency so long as it is unique in the list*/ if ((frequencies[i].bits == bits) && (frequencies[i].length == length)) { /*check for duplicates*/ for (j = i + 1; j < total_frequencies; j++) { if ((frequencies[j].bits == bits) && (frequencies[j].length == length)) { *error = HUFFMAN_DUPLICATE_LEAF; free(node); return NULL; } } node->type = NODE_LEAF; node->v.leaf = frequencies[i].value; return node; } else { max_frequency_length = MAX(max_frequency_length, frequencies[i].length); } } if (length > max_frequency_length) { /*we've walked outside of the set of possible frequencies which indicates the tree is missing a leaf node*/ *error = HUFFMAN_MISSING_LEAF; free(node); return NULL; } /*otherwise, generate a new tree node whose leaf nodes are generated recursively*/ node->type = NODE_TREE; node->v.tree.id = *counter; node->v.tree.bit_0 = NULL; node->v.tree.bit_1 = NULL; (*counter) += 1; if ((node->v.tree.bit_0 = build_huffman_tree_(bits << 1, length + 1, frequencies, total_frequencies, counter, error)) == NULL) goto error; if ((node->v.tree.bit_1 = build_huffman_tree_((bits << 1) | 1, length + 1, frequencies, total_frequencies, counter, error)) == NULL) goto error; return node; error: free_huffman_tree(node->v.tree.bit_0); free_huffman_tree(node->v.tree.bit_1); free(node); return NULL; }
/* * read_code_table builds a Huffman tree from the code * in the in file. This function returns NULL on error. * The returned value should be freed with free_huffman_tree. */ static huffman_node* read_code_table(FILE* in, unsigned int *pDataBytes) { huffman_node *root = new_nonleaf_node(0, NULL, NULL); unsigned int count; /* Read the number of entries. (it is stored in network byte order). */ if(fread(&count, sizeof(count), 1, in) != 1) { free_huffman_tree(root); return NULL; } count = ntohl(count); /* Read the number of data bytes this encoding represents. */ if(fread(pDataBytes, sizeof(*pDataBytes), 1, in) != 1) { free_huffman_tree(root); return NULL; } *pDataBytes = ntohl(*pDataBytes); /* Read the entries. */ while(count-- > 0) { int c; unsigned int curbit; unsigned char symbol; unsigned char numbits; unsigned char numbytes; unsigned char *bytes; huffman_node *p = root; if((c = fgetc(in)) == EOF) { free_huffman_tree(root); return NULL; } symbol = (unsigned char)c; if((c = fgetc(in)) == EOF) { free_huffman_tree(root); return NULL; } numbits = (unsigned char)c; numbytes = (unsigned char)numbytes_from_numbits(numbits); bytes = (unsigned char*)malloc(numbytes); if(fread(bytes, 1, numbytes, in) != numbytes) { free(bytes); free_huffman_tree(root); return NULL; } /* * Add the entry to the Huffman tree. The value * of the current bit is used switch between * zero and one child nodes in the tree. New nodes * are added as needed in the tree. */ for(curbit = 0; curbit < numbits; ++curbit) { if(get_bit(bytes, curbit)) { if(p->one == NULL) { p->one = curbit == (unsigned char)(numbits - 1) ? new_leaf_node(symbol) : new_nonleaf_node(0, NULL, NULL); p->one->parent = p; } p = p->one; } else { if(p->zero == NULL) { p->zero = curbit == (unsigned char)(numbits - 1) ? new_leaf_node(symbol) : new_nonleaf_node(0, NULL, NULL); p->zero->parent = p; } p = p->zero; } } free(bytes); } return root; }