static real_t mc_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 prange = *range; unsigned width = width_of_level (range->level); unsigned height = height_of_level (range->level); word_t *mcpe = Calloc (width * height, sizeof (word_t)); /* * If we are at the bottom level of the mc tree: * Fill in the norms table */ if (prange.level == wfa->wfainfo->p_min_level) fill_norms_table (prange.x, prange.y, prange.level, wfa->wfainfo, c->mt); /* * Predict 'range' with motion compensation according to frame type. * MCPE is returned in 'c->mcpe' */ if (c->mt->frame_type == P_FRAME) find_P_frame_mc (mcpe, price, &prange, wfa->wfainfo, c->mt); else find_B_frame_mc (mcpe, price, &prange, wfa->wfainfo, c->mt); costs = (prange.mv_tree_bits + prange.mv_coord_bits) * price; if (costs < max_costs) /* motion vector not too expensive */ { unsigned last_state; /* last WFA state before recursion */ real_t *ipi [MAXSTATES]; /* inner products pointers */ unsigned state; real_t mvt, mvc; c->pixels = Calloc (width * height, sizeof (real_t)); cut_to_bintree (c->pixels, mcpe, width, height, 0, 0, width, height); /* * Approximate MCPE recursively. */ 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)); } mvc = prange.mv_coord_bits; mvt = prange.mv_tree_bits; prange.image = 0; prange.address = 0; prange.tree_bits = 0; prange.matrix_bits = 0; prange.weights_bits = 0; prange.mv_coord_bits = 0; prange.mv_tree_bits = 0; prange.nd_weights_bits = 0; prange.nd_tree_bits = 0; compute_ip_images_state (prange.image, prange.address, prange.level, 1, 0, wfa, c); costs += subdivide (max_costs - costs, band, y_state, &prange, wfa, c, NO, YES); if (costs < max_costs) /* use motion compensation */ { unsigned img, adr; /* temp. values */ img = range->image; adr = range->address; *range = prange; range->image = img; range->address = adr; range->mv_coord_bits = mvc; range->mv_tree_bits = mvt; range->prediction = YES; 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)); costs = (range->tree_bits + range->matrix_bits + range->weights_bits + range->mv_tree_bits + range->mv_coord_bits + range->nd_tree_bits + range->nd_weights_bits) * price + range->err; } 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]; } Free (c->pixels); } else costs = MAXCOSTS; Free (mcpe); return costs; }
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; }
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); } } } } }