static void init_frequencies(SymbolFrequencies *pSF) { memset(*pSF, 0, sizeof(SymbolFrequencies)); #if 0 unsigned int i; for(i = 0; i < MAX_SYMBOLS; ++i) { unsigned char uc = (unsigned char)i; (*pSF)[i] = new_leaf_node(uc); } #endif }
static unsigned int get_symfreq(symfreq *sf, FILE *in) { int c; unsigned int tot = 0; /* 初始化频率表 */ init_freq(sf); /* 计算文件中每个符号的出现次数 */ while ((c = fgetc(in)) != EOF) { unsigned char uc = c; if (!(*sf)[uc]) (*sf)[uc] = new_leaf_node(uc); ++(*sf)[uc]->count; ++tot; } return tot; }
static unsigned int get_symbol_frequencies(SymbolFrequencies *pSF, FILE *in) { int c; unsigned int total_count = 0; /* Set all frequencies to 0. */ init_frequencies(pSF); /* Count the frequency of each symbol in the input file. */ while((c = fgetc(in)) != EOF) { unsigned char uc = c; if(!(*pSF)[uc]) (*pSF)[uc] = new_leaf_node(uc); ++(*pSF)[uc]->count; ++total_count; } return total_count; }
static unsigned int get_symbol_frequencies_from_memory(SymbolFrequencies *pSF, const unsigned char *bufin, unsigned int bufinlen) { unsigned int i; unsigned int total_count = 0; /* Set all frequencies to 0. */ init_frequencies(pSF); /* Count the frequency of each symbol in the input file. */ for(i = 0; i < bufinlen; ++i) { unsigned char uc = bufin[i]; if(!(*pSF)[uc]) (*pSF)[uc] = new_leaf_node(uc); ++(*pSF)[uc]->count; ++total_count; } return total_count; }
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; }
/* * 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; }
/* 读入编码表,返回构建的 Huffman 树 */ static node *read_code_table(FILE *in, unsigned int *pdb) { node *root = new_node(0, NULL, NULL); uint32_t count; /* 读入符号数 */ if (fread(&count, sizeof(count), 1, in) != 1) { free_tree(root); return NULL; } count = ntohl(count); /* 读入当前分支编码数 */ if (fread(pdb, sizeof(*pdb), 1, in) != 1) { free_tree(root); return NULL; } *pdb = ntohl(*pdb); /* 读入符号表 */ while (count-- > 0) { int c; unsigned int c_bit; unsigned char symbol; unsigned char len; unsigned char lbytes; unsigned char *bytes; node *p = root; if ((c = fgetc(in)) == EOF) { free_tree(root); return NULL; } symbol = (unsigned char) c; if ((c = fgetc(in)) == EOF) { free_tree(root); return NULL; } len = (unsigned char) c; lbytes = (unsigned char) bit_len_byte(len); bytes = (unsigned char *) malloc(lbytes); if (fread(bytes, 1, lbytes, in) != lbytes) { free(bytes); free_tree(root); return NULL; } /* 依据当前位加入 Huffman 树 */ for (c_bit = 0; c_bit < len; ++c_bit) { if (get_bit(bytes, c_bit)) { if (p->one == NULL) { p->one = c_bit == (unsigned char) (len - 1) ? new_leaf_node(symbol) : new_node(0, NULL, NULL); p->one->parent = p; } p = p->one; } else { if (p->zero == NULL) { p->zero = c_bit == (unsigned char) (len - 1) ? new_leaf_node(symbol) : new_node(0, NULL, NULL); p->zero->parent = p; } p = p->zero; } } free(bytes); } return root; }