huff_code_t * huff_code_read(FILE *infh) { huff_code_t *hc; uint32 i, j; hc = (huff_code_t*)ckd_calloc(1, sizeof(*hc)); hc->refcount = 1; hc->maxbits = fgetc(infh); hc->type = fgetc(infh); /* Two bytes of padding. */ fgetc(infh); fgetc(infh); /* Allocate stuff. */ hc->firstcode = (uint32*)ckd_calloc(hc->maxbits + 1, sizeof(*hc->firstcode)); hc->numl = (uint32*)ckd_calloc(hc->maxbits + 1, sizeof(*hc->numl)); hc->syms = (huff_codeword_t**)ckd_calloc(hc->maxbits + 1, sizeof(*hc->syms)); /* Read the symbol tables. */ hc->codewords = hash_table_new(hc->maxbits, HASH_CASE_YES); for (i = 1; i <= hc->maxbits; ++i) { if (fread(&hc->firstcode[i], 4, 1, infh) != 1) goto error_out; SWAP_BE_32(&hc->firstcode[i]); if (fread(&hc->numl[i], 4, 1, infh) != 1) goto error_out; SWAP_BE_32(&hc->numl[i]); hc->syms[i] =(huff_codeword_t*) ckd_calloc(hc->numl[i], sizeof(**hc->syms)); for (j = 0; j < hc->numl[i]; ++j) { huff_codeword_t *cw = &hc->syms[i][j]; cw->nbits = i; cw->codeword = hc->firstcode[i] + j; if (hc->type == HUFF_CODE_INT) { if (fread(&cw->r.ival, 4, 1, infh) != 1) goto error_out; SWAP_BE_32(&cw->r.ival); hash_table_enter_bkey(hc->codewords, (char const *)&cw->r.ival, sizeof(cw->r.ival), (void *)cw); } else { size_t len; cw->r.sval = fread_line(infh, &len); cw->r.sval[len-1] = '\0'; hash_table_enter(hc->codewords, cw->r.sval, (void *)cw); } } } return hc; error_out: huff_code_free(hc); return 0; }
huff_code_t * huff_code_build_str(char * const *values, int32 const *frequencies, int nvals) { huff_code_t *hc; huff_node_t *root; heap_t *q; int i; hc = (huff_code_t*)ckd_calloc(1, sizeof(*hc)); hc->refcount = 1; hc->type = HUFF_CODE_STR; /* Initialize the heap with nodes for each symbol. */ q = heap_new(); for (i = 0; i < nvals; ++i) { heap_insert(q, huff_node_new_str(values[i]), frequencies[i]); } /* Now build the tree, which gives us codeword lengths. */ root = huff_code_build_tree(q); heap_destroy(q); if (root == 0 || root->nbits > 32) { E_ERROR("Huffman trees currently limited to 32 bits\n"); huff_node_free_str(root, TRUE); huff_code_free(hc); return 0; } /* Build a canonical codebook. */ hc->maxbits = root->nbits; huff_code_canonicalize(hc, root); /* Tree no longer needed (note we retain pointers to its strings). */ huff_node_free_str(root, FALSE); return hc; }
huff_code_t * huff_code_build_int(int32 const *values, int32 const *frequencies, int nvals) { huff_code_t *hc; huff_node_t *root; heap_t *q; int i; hc = ckd_calloc(1, sizeof(*hc)); hc->refcount = 1; hc->type = HUFF_CODE_INT; /* Initialize the heap with nodes for each symbol. */ q = heap_new(); for (i = 0; i < nvals; ++i) { heap_insert(q, huff_node_new_int(values[i]), frequencies[i]); } /* Now build the tree, which gives us codeword lengths. */ root = huff_code_build_tree(q); heap_destroy(q); if (root == NULL || root->nbits > 64) { E_ERROR("Huffman trees currently limited to 32 bits\n"); huff_node_free_int(root); huff_code_free(hc); return NULL; } /* Build a canonical codebook. */ hc->maxbits = root->nbits; huff_code_canonicalize(hc, root); /* Tree no longer needed. */ huff_node_free_int(root); return hc; }