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; }
static void sseq_compress(mdef_t * m) { hash_table_t *h; s3senid_t **sseq; int32 n_sseq; int32 p, j, k; glist_t g; gnode_t *gn; hash_entry_t *he; k = m->n_emit_state * sizeof(s3senid_t); h = hash_table_new(m->n_phone, HASH_CASE_YES); n_sseq = 0; /* Identify unique senone-sequence IDs. BUG: tmat-id not being considered!! */ for (p = 0; p < m->n_phone; p++) { /* Add senone sequence to hash table */ if ((j = (long) hash_table_enter_bkey(h, (char *) (m->sseq[p]), k, (void *)(long)n_sseq)) == n_sseq) n_sseq++; m->phone[p].ssid = j; } /* Generate compacted sseq table */ sseq = (s3senid_t **) ckd_calloc_2d(n_sseq, m->n_emit_state, sizeof(s3senid_t)); /* freed in mdef_free() */ g = hash_table_tolist(h, &j); assert(j == n_sseq); for (gn = g; gn; gn = gnode_next(gn)) { he = (hash_entry_t *) gnode_ptr(gn); j = (int32)(long)hash_entry_val(he); memcpy(sseq[j], hash_entry_key(he), k); } glist_free(g); /* Free the old, temporary senone sequence table, replace with compacted one */ ckd_free_2d((void **) m->sseq); m->sseq = sseq; m->n_sseq = n_sseq; hash_table_free(h); }
int32 fsg_model_tag_trans_add(fsg_model_t * fsg, int32 from, int32 to, int32 logp, int32 wid) { fsg_link_t *link, *link2; /* Check for transition probability */ if (logp > 0) { E_FATAL("Null transition prob must be <= 1.0 (state %d -> %d)\n", from, to); } /* Self-loop null transitions (with prob <= 1.0) are redundant */ if (from == to) return -1; if (fsg->trans[from].null_trans == NULL) fsg->trans[from].null_trans = hash_table_new(5, HASH_CASE_YES); /* Check for a duplicate link; if found, keep the higher prob */ link = fsg_model_null_trans(fsg, from, to); if (link) { if (link->logs2prob < logp) { link->logs2prob = logp; return 0; } else return -1; } /* Create null transition object */ link = listelem_malloc(fsg->link_alloc); link->from_state = from; link->to_state = to; link->logs2prob = logp; link->wid = -1; link2 = (fsg_link_t *) hash_table_enter_bkey(fsg->trans[from].null_trans, (char const *) &link->to_state, sizeof(link->to_state), link); assert(link == link2); return 1; }
static void huff_code_canonicalize(huff_code_t *hc, huff_node_t *root) { glist_t agenda; uint32 *nextcode; int i, ncw; hc->firstcode =(uint32*) ckd_calloc(hc->maxbits+1, sizeof(*hc->firstcode)); hc->syms = (huff_codeword_t**)ckd_calloc(hc->maxbits+1, sizeof(*hc->syms)); hc->numl =(uint32*) ckd_calloc(hc->maxbits+1, sizeof(*nextcode)); nextcode =(uint32*) ckd_calloc(hc->maxbits+1, sizeof(*nextcode)); /* Traverse the tree, annotating it with the actual bit * lengths, and histogramming them in numl. */ root->nbits = 0; ncw = 0; agenda = glist_add_ptr(0, root); while (agenda) { huff_node_t *node = (huff_node_t*)gnode_ptr(agenda); agenda = gnode_free(agenda, 0); if (node->l) { node->l->nbits = node->nbits + 1; agenda = glist_add_ptr(agenda, node->l); node->r.r->nbits = node->nbits + 1; agenda = glist_add_ptr(agenda, node->r.r); } else { hc->numl[node->nbits]++; ncw++; } } /* Create starting codes and symbol tables for each bit length. */ hc->syms[hc->maxbits] = (huff_codeword_t*)ckd_calloc(hc->numl[hc->maxbits], sizeof(**hc->syms)); for (i = hc->maxbits - 1; i > 0; --i) { hc->firstcode[i] = (hc->firstcode[i+1] + hc->numl[i+1]) / 2; hc->syms[i] = (huff_codeword_t*)ckd_calloc(hc->numl[i], sizeof(**hc->syms)); } memcpy(nextcode, hc->firstcode, (hc->maxbits + 1) * sizeof(*nextcode)); /* Traverse the tree again to produce the codebook itself. */ hc->codewords = hash_table_new(ncw, HASH_CASE_YES); agenda = glist_add_ptr(0, root); while (agenda) { huff_node_t *node = (huff_node_t*)gnode_ptr(agenda); agenda = gnode_free(agenda, 0); if (node->l) { agenda = glist_add_ptr(agenda, node->l); agenda = glist_add_ptr(agenda, node->r.r); } else { /* Initialize codebook entry, which also retains symbol pointer. */ huff_codeword_t *cw; uint32 codeword = nextcode[node->nbits] & ((1 << node->nbits) - 1); cw = hc->syms[node->nbits] + (codeword - hc->firstcode[node->nbits]); cw->nbits = node->nbits; cw->r.sval = node->r.sval; /* Will copy ints too... */ cw->codeword = codeword; if (hc->type == HUFF_CODE_INT) { hash_table_enter_bkey(hc->codewords, (char const *)&cw->r.ival, sizeof(cw->r.ival), (void *)cw); } else { hash_table_enter(hc->codewords, cw->r.sval, (void *)cw); } ++nextcode[node->nbits]; } } ckd_free(nextcode); }