📄 subdivide.c
字号:
if (c->options.progress_meter != FIASCO_PROGRESS_NONE) { if (c->options.progress_meter == FIASCO_PROGRESS_PERCENT) { unsigned new_percent; /* new status of progress meter */ new_percent = (child[label].global_address + 1) * 100.0 / (1 << (wfa->wfainfo->level - child[label].level)); if (new_percent > percent) { percent = new_percent; info ("%3d%% \r", percent); } } else if (c->options.progress_meter == FIASCO_PROGRESS_BAR) { unsigned new_percent; /* new status of progress meter */ new_percent = (child[label].global_address + 1) * 50.0 / (1 << (wfa->wfainfo->level - child[label].level)); for (; new_percent > percent; percent++) { info ("#"); } } } /* * If costs of subdivision exceed costs of linear combination * then abort recursion. */ if (subdivide_costs >= min (lincomb_costs, max_costs)) { subdivide_costs = MAXCOSTS; break; } rrange.err += child [label].err; rrange.tree_bits += child [label].tree_bits; rrange.matrix_bits += child [label].matrix_bits; rrange.weights_bits += child [label].weights_bits; rrange.mv_tree_bits += child [label].mv_tree_bits; rrange.mv_coord_bits += child [label].mv_coord_bits; rrange.nd_weights_bits += child [label].nd_weights_bits; rrange.nd_tree_bits += child [label].nd_tree_bits; tree_update (ischild (child [label].tree) ? CHILD : LEAF, child [label].level, &c->tree); tree_update (child [label].prediction ? LEAF : CHILD, child [label].level, &c->p_tree); } } else subdivide_costs = MAXCOSTS; /* * Third alternative of range approximation: * Predict range via motion compensation or nondeterminism and * approximate delta image. */ if (try_mc || try_nd) /* try prediction */ { real_t prediction_costs; /* Costs arising from approx. the current range with prediction */ prediction_costs = predict_range (min (min (lincomb_costs, subdivide_costs), max_costs), price, range, wfa, c, band, y_state, states, &tree_model, &p_tree_model, domain_model, d_domain_model, coeff_model, d_coeff_model); if (prediction_costs < MAXCOSTS) /* prediction has smallest costs */ { c->domain_pool->model_free (domain_model); c->d_domain_pool->model_free (d_domain_model); c->domain_pool->model_free (lc_domain_model); c->d_domain_pool->model_free (lc_d_domain_model); c->coeff->model_free (coeff_model); c->d_coeff->model_free (d_coeff_model); c->coeff->model_free (lc_coeff_model); c->d_coeff->model_free (lc_d_coeff_model); return prediction_costs; } } if (lincomb_costs >= MAXCOSTS && subdivide_costs >= MAXCOSTS) { /* * Return MAXCOSTS if neither a linear combination nor a recursive * subdivision yield costs less than 'max_costs' */ c->domain_pool->model_free (c->domain_pool->model); c->d_domain_pool->model_free (c->d_domain_pool->model); c->domain_pool->model_free (lc_domain_model); c->d_domain_pool->model_free (lc_d_domain_model); c->coeff->model_free (c->coeff->model); c->d_coeff->model_free (c->d_coeff->model); c->coeff->model_free (lc_coeff_model); c->d_coeff->model_free (lc_d_coeff_model); c->domain_pool->model = domain_model; c->d_domain_pool->model = d_domain_model; c->coeff->model = coeff_model; c->d_coeff->model = d_coeff_model; c->tree = tree_model; c->p_tree = p_tree_model; if (wfa->states != states) remove_states (states, wfa); return MAXCOSTS; } else if (lincomb_costs < subdivide_costs) { /* * Use the linear combination: The factors of the linear combination * are stored already in 'range', so revert the probability models * only. */ c->domain_pool->model_free (c->domain_pool->model); c->d_domain_pool->model_free (c->d_domain_pool->model); c->domain_pool->model_free (domain_model); c->d_domain_pool->model_free (d_domain_model); c->coeff->model_free (c->coeff->model); c->d_coeff->model_free (c->d_coeff->model); c->coeff->model_free (coeff_model); c->d_coeff->model_free (d_coeff_model); c->domain_pool->model = lc_domain_model; c->d_domain_pool->model = lc_d_domain_model; c->coeff->model = lc_coeff_model; c->d_coeff->model = lc_d_coeff_model; c->tree = tree_model; c->p_tree = p_tree_model; *range = lrange; if (wfa->states != states) remove_states (states, wfa); return lincomb_costs; } else { /* * Use the recursive subdivision: Generate a new state with transitions * given in child[]. * Don't use state in linear combinations in any of the following cases: * - if color component is Cb or Cr * - if level of state > tiling level * - if state is (partially) outside image geometry */ if (band > Y || (c->tiling->exponent && rrange.level > wfa->wfainfo->level - c->tiling->exponent) || (range->x + width_of_level (range->level) > c->mt->original->width) || (range->y + height_of_level (range->level) > c->mt->original->height)) init_new_state (YES, delta, &rrange, child, new_y_state, wfa, c); else init_new_state (NO, delta, &rrange, child, new_y_state, wfa, c); *range = rrange; c->domain_pool->model_free (domain_model); c->d_domain_pool->model_free (d_domain_model); c->domain_pool->model_free (lc_domain_model); c->d_domain_pool->model_free (lc_d_domain_model); c->coeff->model_free (coeff_model); c->d_coeff->model_free (d_coeff_model); c->coeff->model_free (lc_coeff_model); c->d_coeff->model_free (lc_d_coeff_model); return subdivide_costs; }}voidcut_to_bintree (real_t *dst, const word_t *src, unsigned src_width, unsigned src_height, unsigned x0, unsigned y0, unsigned width, unsigned height)/* * Cut region ('x0', 'y0', 'width', 'height') of the pixel array 'src'. * Size of image is given by 'src_width' x 'src_height'. * 'dst' pixels are converted to bintree order and real format. * * No return value. * * Side effects: * 'dst []' is filled with corresponding region. */{ const unsigned mask01 = 0x555555; /* binary ...010101010101 */ const unsigned mask10 = 0xaaaaaa; /* binary ...101010101010 */ const unsigned mask01plus1 = mask01 + 1; /* binary ...010101010110 */ const unsigned mask10plus1 = mask10 + 1; /* binary ...101010101011 */ unsigned x, y; /* pixel coordinates */ unsigned xmask, ymask; /* address conversion */ if (width != height && width != (height >> 1)) error ("Bintree cutting requires special type of images."); ymask = 0; for (y = y0; y < y0 + height; y++, ymask = (ymask + mask10plus1) & mask01) { xmask = 0; for (x = x0; x < x0 + width; x++, xmask = (xmask + mask01plus1) & mask10) { if (y >= src_height || x >= src_width) dst [xmask | ymask] = 0; else dst [xmask | ymask] = src [y * src_width + x] / 16; } }}/***************************************************************************** private code *****************************************************************************/static voidinit_new_state (bool_t auxiliary_state, bool_t delta, range_t *range, const range_t *child, const int *y_state, wfa_t *wfa, coding_t *c)/* * Initializes a new state with all parameters needed for the encoding step. * If flag 'auxiliary_state' is set then don't insert state into domain pools. * If flag 'delta' is set then state represents a delta image (prediction via * nondeterminism or motion compensation). * 'range' the current range image, * 'child []' the left and right childs of 'range'. * * No return value. * * Side effects: * New state is appended to 'wfa' (and also its inner products and images * are computed and stored in 'c') */{ unsigned label; bool_t state_is_domain = NO; if (!auxiliary_state) { if (!delta || c->options.delta_domains) state_is_domain = c->domain_pool->append (wfa->states, range->level, wfa, c->domain_pool->model); if (delta || c->options.normal_domains) state_is_domain = c->d_domain_pool->append (wfa->states, range->level, wfa, c->d_domain_pool->model) || state_is_domain; } else state_is_domain = NO; range->into [0] = NO_EDGE; range->tree = wfa->states; for (label = 0; label < MAXLABELS; label++) { wfa->tree [wfa->states][label] = child [label].tree; wfa->y_state [wfa->states][label] = y_state [label]; wfa->mv_tree [wfa->states][label] = child [label].mv; wfa->x [wfa->states][label] = child [label].x; wfa->y [wfa->states][label] = child [label].y; wfa->prediction [wfa->states][label] = child [label].prediction; append_transitions (wfa->states, label, child [label].weight, child [label].into, wfa); } wfa->delta_state [wfa->states] = delta; if (range->err < 0) warning ("Negative image norm: %f, %f", child [0].err, child [1].err);/* state_is_domain = YES; */ append_state (!state_is_domain, compute_final_distribution (wfa->states, wfa), range->level, wfa, c);}static voidinit_range (range_t *range, const image_t *image, unsigned band, const wfa_t *wfa, coding_t *c)/* * Read a new 'range' of the image 'image_name' (current color component * is 'band') and compute the new inner product arrays. * * No return value. * * Side effects: * 'c->pixels' are filled with pixel values of image block * 'c->ip_images_state' are computed with respect to new image block * 'range->address' and 'range->image' are initialized with zero */{ unsigned state; /* * Clear already computed products */ for (state = 0; 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)); cut_to_bintree (c->pixels, image->pixels [band], image->width, image->height, range->x, range->y, width_of_level (range->level), height_of_level (range->level)); range->address = range->image = 0; compute_ip_images_state (0, 0, range->level, 1, 0, wfa, c);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -