static void expand (void) { Exp * e, * old; int idx, j; nexps += maxwidth; old = exps; sexps = nexps; exps = calloc (nexps, sizeof *exps); for (idx = 1; idx <= maxwidth; idx++) { exps[idx].ref = idx; exps[idx].oldref = idx; exps[idx].cut = 0; exps[idx].oldcut = 0; exps[idx].idx = 0; exps[idx].op = strdup ("zero"); exps[idx].width = idx; exps[idx].childs = 0; exps[idx].name = 0; } memcpy (exps + maxwidth + 1, old + 1, (nexps - maxwidth - 1) * sizeof *exps); for (idx = maxwidth + 1; idx < nexps; idx++) { e = exps + idx; if (!e->ref) continue; assert (e->ref == idx - maxwidth); e->ref += maxwidth; for (j = 0; j < e->childs; j++) if (ischild (e, j)) { if (e->child[j] < 0) e->child[j] -= maxwidth; else e->child[j] += maxwidth; } } free (old); msg (1, "added %d zeroes", maxwidth); }
static void dfs (int idx) { Exp * e; int i; idx = abs (idx); assert (0 < idx); assert (idx < nexps); e = exps + idx; if (e->idx) return; for (i = 0; i < 3; i++) if (ischild (e, i)) dfs (deref (e->child[i])); e->idx = ++rexps; }
static real_t nd_prediction (real_t max_costs, real_t price, unsigned band, int y_state, range_t *range, wfa_t *wfa, coding_t *c) { real_t costs; /* current approximation costs */ range_t lrange = *range; /* * Predict 'range' with DC component approximation */ { real_t x = get_ip_image_state (range->image, range->address, range->level, 0, c); real_t y = get_ip_state_state (0, 0, range->level, c); real_t w = btor (rtob (x / y, c->coeff->dc_rpf), c->coeff->dc_rpf); word_t s [2] = {0, -1}; lrange.into [0] = 0; lrange.into [1] = NO_EDGE; lrange.weight [0] = w; lrange.mv_coord_bits = 0; lrange.mv_tree_bits = 0; lrange.nd_tree_bits = tree_bits (LEAF, lrange.level, &c->p_tree); lrange.nd_weights_bits = 0; lrange.tree_bits = 0; lrange.matrix_bits = 0; lrange.weights_bits = c->coeff->bits (&w, s, range->level, c->coeff); } costs = price * (lrange.weights_bits + lrange.nd_tree_bits); /* * Recursive aproximation of difference image */ if (costs < max_costs) { unsigned state; range_t rrange; /* range: recursive subdivision */ unsigned last_state; /* last WFA state before recursion */ real_t *ipi [MAXSTATES]; /* inner products pointers */ unsigned width = width_of_level (range->level); unsigned height = height_of_level (range->level); real_t *pixels; /* * Generate difference image original - approximation */ { unsigned n; real_t *src, *dst; /* pointers to image data */ real_t w = - lrange.weight [0] * c->images_of_state [0][0]; src = c->pixels + range->address * size_of_level (range->level); dst = c->pixels = pixels = Calloc (width * height, sizeof (real_t)); for (n = width * height; n; n--) *dst++ = *src++ + w; } /* * Approximate difference recursively. */ rrange = *range; rrange.tree_bits = 0; rrange.matrix_bits = 0; rrange.weights_bits = 0; rrange.mv_coord_bits = 0; rrange.mv_tree_bits = 0; rrange.nd_tree_bits = 0; rrange.nd_weights_bits = 0; rrange.image = 0; rrange.address = 0; last_state = wfa->states - 1; for (state = 0; state <= last_state; state++) if (need_image (state, wfa)) { ipi [state] = c->ip_images_state[state]; c->ip_images_state[state] = Calloc (size_of_tree (c->products_level), sizeof (real_t)); } compute_ip_images_state (rrange.image, rrange.address, rrange.level, 1, 0, wfa, c); costs += subdivide (max_costs - costs, band, y_state, &rrange, wfa, c, NO, YES); Free (pixels); if (costs < max_costs && ischild (rrange.tree)) /* use prediction */ { unsigned img, adr; unsigned edge; img = range->image; adr = range->address; *range = rrange; range->image = img; range->address = adr; range->nd_tree_bits += lrange.nd_tree_bits; range->nd_weights_bits += lrange.weights_bits; for (edge = 0; isedge (lrange.into [edge]); edge++) { range->into [edge] = lrange.into [edge]; range->weight [edge] = lrange.weight [edge]; } range->into [edge] = NO_EDGE; range->prediction = edge; for (state = last_state + 1; state < wfa->states; state++) if (need_image (state, wfa)) memset (c->ip_images_state [state], 0, size_of_tree (c->products_level) * sizeof (real_t)); } else costs = MAXCOSTS; for (state = 0; state <= last_state; state++) if (need_image (state, wfa)) { Free (c->ip_images_state [state]); c->ip_images_state [state] = ipi [state]; } } else costs = MAXCOSTS; return costs; }
static void print (void) { FILE * file = fopen (tmp, "w"); int i, j, lit, count; Exp * e, ** sorted; if (!file) die ("can not write to '%s'", tmp); count = 0; for (i = 1; i < nexps; i++) { e = exps + i; if (!e->ref) continue; if (!e->idx) continue; count++; } sorted = malloc (count * sizeof * sorted); j = 0; for (i = 1; i < nexps; i++) { e = exps + i; if (!e->ref) continue; if (!e->idx) continue; sorted[j++] = e; } assert (j == count); if (!nosort) qsort (sorted, count, sizeof *sorted, cmp_by_idx); for (i = 0; i < count; i++) { e = sorted[i]; if (!e->ref) continue; if (!e->idx) continue; if (e->cut) { fprintf (file, "%d var %d\n", e->idx, e->width); } else { fprintf (file, "%d %s %d", e->idx, e->op, e->width); if (isarrayop (e->op)) fprintf (file, " %d", e->addrwidth); for (j = 0; j < e->childs; j++) { lit = e->child[j]; fprintf (file, " %d", ischild (e, j) ? deidx (lit) : lit); } if (e->name) fprintf (file, " %s", e->name); fputc ('\n', file); } } fclose (file); free (sorted); }
void compute_ip_images_state (unsigned image, unsigned address, unsigned level, unsigned n, unsigned from, const wfa_t *wfa, coding_t *c) /* * Compute the inner products between all states * 'from', ... , 'wfa->max_states' and the range images 'image' * (and childs) up to given level. * * No return value. * * Side effects: * inner product tables 'c->ip_images_states' are updated */ { if (level > c->options.images_level) { unsigned state, label; if (level > c->options.images_level + 1) /* recursive computation */ compute_ip_images_state (MAXLABELS * image + 1, address * MAXLABELS, level - 1, MAXLABELS * n, from, wfa, c); /* * Compute inner product <f, Phi_i> */ for (label = 0; label < MAXLABELS; label++) for (state = from; state < wfa->states; state++) if (need_image (state, wfa)) { unsigned edge, count; int domain; real_t *dst, *src; if (ischild (domain = wfa->tree [state][label])) { if (level > c->options.images_level + 1) { dst = c->ip_images_state [state] + image; src = c->ip_images_state [domain] + image * MAXLABELS + label + 1; for (count = n; count; count--, src += MAXLABELS) *dst++ += *src; } else { unsigned newadr = address * MAXLABELS + label; dst = c->ip_images_state [state] + image; for (count = n; count; count--, newadr += MAXLABELS) *dst++ += standard_ip_image_state (newadr, level - 1, domain, c); } } for (edge = 0; isedge (domain = wfa->into [state][label][edge]); edge++) { real_t weight = wfa->weight [state][label][edge]; if (level > c->options.images_level + 1) { dst = c->ip_images_state [state] + image; src = c->ip_images_state [domain] + image * MAXLABELS + label + 1; for (count = n; count; count--, src += MAXLABELS) *dst++ += *src * weight; } else { unsigned newadr = address * MAXLABELS + label; dst = c->ip_images_state [state] + image; for (count = n; count; count--, newadr += MAXLABELS) *dst++ += weight * standard_ip_image_state (newadr, level - 1, domain, c); } } } } }
void compute_ip_states_state (unsigned from, unsigned to, const wfa_t *wfa, coding_t *c) /* * Computes the inner products between the current state 'state1' and the * old states 0,...,'state1'-1 * * No return value. * * Side effects: * inner product tables 'c->ip_states_state' are computed. */ { unsigned level; unsigned state1, state2; /* * Compute inner product <Phi_state1, Phi_state2> */ for (level = c->options.images_level + 1; level <= c->options.lc_max_level; level++) for (state1 = from; state1 <= to; state1++) for (state2 = 0; state2 <= state1; state2++) if (need_image (state2, wfa)) { unsigned label; real_t ip = 0; for (label = 0; label < MAXLABELS; label++) { int domain1, domain2; unsigned edge1, edge2; real_t sum, weight2; if (ischild (domain1 = wfa->tree [state1][label])) { sum = 0; if (ischild (domain2 = wfa->tree [state2][label])) sum = get_ip_state_state (domain1, domain2, level - 1, c); for (edge2 = 0; isedge (domain2 = wfa->into [state2][label][edge2]); edge2++) { weight2 = wfa->weight [state2][label][edge2]; sum += weight2 * get_ip_state_state (domain1, domain2, level - 1, c); } ip += sum; } for (edge1 = 0; isedge (domain1 = wfa->into [state1][label][edge1]); edge1++) { real_t weight1 = wfa->weight [state1][label][edge1]; sum = 0; if (ischild (domain2 = wfa->tree [state2][label])) sum = get_ip_state_state (domain1, domain2, level - 1, c); for (edge2 = 0; isedge (domain2 = wfa->into [state2][label][edge2]); edge2++) { weight2 = wfa->weight [state2][label][edge2]; sum += weight2 * get_ip_state_state (domain1, domain2, level - 1, c); } ip += weight1 * sum; } } c->ip_states_state [state1][level][state2] = ip; } }
static unsigned decode_nd_tree (wfa_t *wfa, bitfile_t *input) /* * Read 'wfa' prediction tree of given 'input' stream. * * No return value. * * Side effects: * 'wfa->into' is filled with the decoded values */ { lqueue_t *queue; /* queue of states */ int next, state; /* state and its current child */ unsigned total = 0; /* total number of predicted states */ u_word_t sum0, sum1; /* Probability model */ u_word_t code; /* The present input code value */ u_word_t low; /* Start of the current code range */ u_word_t high; /* End of the current code range */ /* * Initialize arithmetic decoder */ code = get_bits (input, 16); low = 0; high = 0xffff; sum0 = 1; sum1 = 11; queue = alloc_queue (sizeof (int)); state = wfa->root_state; queue_append (queue, &state); /* * Traverse the WFA tree in breadth first order (using a queue). */ while (queue_remove (queue, &next)) { unsigned label; if (wfa->level_of_state [next] > wfa->wfainfo->p_max_level + 1) { /* * Nondetermismn is not allowed at levels larger than * 'wfa->wfainfo->p_max_level'. */ for (label = 0; label < MAXLABELS; label++) if (ischild (state = wfa->tree [next][label])) queue_append (queue, &state); /* continue with childs */ } else if (wfa->level_of_state [next] > wfa->wfainfo->p_min_level) { for (label = 0; label < MAXLABELS; label++) if (ischild (state = wfa->tree [next][label])) { unsigned count; /* Current interval count */ unsigned range; /* Current interval range */ count = (((code - low) + 1) * sum1 - 1) / ((high - low) + 1); if (count < sum0) { /* * Decode a '0' symbol * First, the range is expanded to account for the * symbol removal. */ range = (high - low) + 1; high = low + (u_word_t) ((range * sum0) / sum1 - 1 ); RESCALE_INPUT_INTERVAL; /* * Update the frequency counts */ sum0++; sum1++; if (sum1 > 50) /* scale the symbol frequencies */ { sum0 >>= 1; sum1 >>= 1; if (!sum0) sum0 = 1; if (sum0 >= sum1) sum1 = sum0 + 1; } if (wfa->level_of_state [state] > wfa->wfainfo->p_min_level) queue_append (queue, &state); } else { /* * Decode a '1' symbol * First, the range is expanded to account for the * symbol removal. */ range = (high - low) + 1; high = low + (u_word_t) ((range * sum1) / sum1 - 1); low = low + (u_word_t) ((range * sum0) / sum1); RESCALE_INPUT_INTERVAL; /* * Update the frequency counts */ sum1++; if (sum1 > 50) /* scale the symbol frequencies */ { sum0 >>= 1; sum1 >>= 1; if (!sum0) sum0 = 1; if (sum0 >= sum1) sum1 = sum0 + 1; } append_edge (next, 0, -1, label, wfa); total++; }