📄 wfalib.c
字号:
memcpy (dst->x, src->x, src->states * MAXLABELS * sizeof (word_t)); memcpy (dst->y, src->y, src->states * MAXLABELS * sizeof (word_t)); memcpy (dst->y_state, src->y_state, src->states * MAXLABELS * sizeof (word_t)); memcpy (dst->into, src->into, src->states * MAXLABELS * (MAXEDGES + 1) * sizeof (word_t)); memcpy (dst->weight, src->weight, src->states * MAXLABELS * (MAXEDGES + 1) * sizeof (real_t)); memcpy (dst->int_weight, src->int_weight, src->states * MAXLABELS * (MAXEDGES + 1) * sizeof (word_t)); memcpy (dst->prediction, src->prediction, src->states * MAXLABELS * sizeof (byte_t)); if (dst->y_column) memcpy (dst->y_column, src->y_column, src->states * MAXLABELS * sizeof (byte_t));}voidlocate_subimage (unsigned orig_level, unsigned level, unsigned bintree, unsigned *x, unsigned *y, unsigned *width, unsigned *height)/* * Compute pixel coordinates of the subimage which 'bintree' address is given. * The level of the original image is 'orig_level' and the level of the * subimage is 'level'. * * No return value. * * Side effects: * '*x', '*y' coordinates of the upper left corner * '*width', '*height' size of image */{ /* * Compute coordinates of the subimage */ *x = *y = 0; /* start at NW corner */ *width = width_of_level (level); *height = height_of_level (level); if (level > orig_level) { error ("size of tile must be less or equal than image size."); return; } else if (bintree >= (unsigned) (1 << (orig_level - level))) { error ("address out of bounds."); return; } else if (level < orig_level) { unsigned mask; /* mask for bintree -> xy conversion */ bool_t hor; /* 1 next subdivision is horizontal 0 next subdivision is vertical */ unsigned l = orig_level - 1; /* current level */ hor = orig_level % 2; /* start with vertival subdivision for square image and vice versa */ for (mask = 1 << (orig_level - level - 1); mask; mask >>= 1, hor = !hor) { if (bintree & mask) /* change coordinates */ { if (hor) /* horizontal subdivision */ *y += height_of_level (l); else /* vertical subdivision */ *x += width_of_level (l); } l--; } }}voidcompute_spiral (int *vorder, unsigned image_width, unsigned image_height, unsigned tiling_exp, bool_t inc_spiral)/* * Compute image tiling with spiral order. * 'inc_spiral' specifies whether the spiral starts in the middle * of the image (TRUE) or at the border (FALSE). * 'image_width'x'image_height' define the size of the image. * The image is split into 'tiling->exp' tiles. * * No return value. * * Side effects: * vorder[] is filled with tiling permutation */{ unsigned x, y; /* current position */ unsigned xmin, xmax, ymin, ymax; /* boundaries for current line */ unsigned width, height; /* offset for each tile */ unsigned lx, ly, level; /* level x and y */ unsigned tiles; /* total number of tiles */ unsigned address; /* bintree address */ lx = log2 (image_width - 1) + 1; ly = log2 (image_height - 1) + 1; level = max (lx, ly) * 2 - ((ly == lx + 1) ? 1 : 0); tiles = 1 << tiling_exp; /* Number of image tiles */ width = width_of_level (level - tiling_exp); height = height_of_level (level - tiling_exp); for (address = 0; address < tiles; address++) { unsigned x0, y0, width, height; locate_subimage (level, level - tiling_exp, address, &x0, &y0, &width, &height); vorder [address] = (x0 < image_width && y0 < image_height) ? 0 : -1; } xmin = 0; xmax = width_of_level (level); ymin = 0; ymax = height_of_level (level); address = 0; /* * 1234 * CDE5 Traverse image in spiral order * BGF6 starting at the top left corner * A987 */ while (TRUE) { for (x = xmin, y = ymin; x < xmax; x += width) /* W>E */ { while (vorder [address] == -1) address++; if (x < image_width && y < image_height) /* valid range */ vorder [address++] = xy_to_address (x, y, level, tiling_exp); while (address < tiles && vorder [address] == -1) address++; } ymin += height; if (address >= tiles) break; for (x = xmax - width, y = ymin; y < ymax; y += height) /* N>S */ { while (vorder [address] == -1) address++; if (x <= image_width && y <= image_height) /* valid range */ vorder [address++] = xy_to_address (x, y, level, tiling_exp); while (address < tiles && vorder [address] == -1) address++; } xmax -= width; if (address >= tiles) break; for (x = xmax - width, y = ymax - width; x >= xmin; x -= width) /* E<W */ { while (vorder [address] == -1) address++; if (x <= image_width && y <= image_height) /* valid range */ vorder [address++] = xy_to_address (x, y, level, tiling_exp); while (address < tiles && vorder [address] == -1) address++; } ymax -= height; if (address >= tiles) break; for (x = xmin, y = ymax - height; y >= ymin; y -= height) /* S>N */ { while (vorder [address] == -1) address++; if (x <= image_width && y <= image_height) /* valid range */ vorder [address++] = xy_to_address (x, y, level, tiling_exp); while (address < tiles && vorder [address] == -1) address++; } xmin += width; if (address >= tiles) break; } if (inc_spiral) { int i = 0, j = tiles - 1; while (i < j) { int tmp; while (vorder [i] == -1) i++; while (vorder [j] == -1) j--; tmp = vorder [i]; vorder [i] = vorder [j]; vorder [j] = tmp; i++; j--; } } /* * Print tiling info */ { unsigned number; for (number = 0, address = 0; address < tiles; address++) if (vorder [address] != -1) debug_message ("number %d: address %d", number++, vorder [address]); }}bool_tfind_range (unsigned x, unsigned y, unsigned band, const wfa_t *wfa, unsigned *range_state, unsigned *range_label)/* * Find a range ('*range_state', '*range_label') that contains * pixel ('x', 'y') in the iven color 'band'. * * Return value: * TRUE on success, or FALSE if there is no such range * * Side effects: * '*range_state' and '*range_label' are modified on success. */{ unsigned state, label; unsigned first_state, last_state; bool_t success = NO; first_state = wfa->basis_states; last_state = wfa->states; if (wfa->wfainfo->color) switch (band) { case Y: first_state = wfa->basis_states; last_state = wfa->tree [wfa->tree [wfa->root_state][0]][0]; break; case Cb: first_state = wfa->tree [wfa->tree [wfa->root_state][0]][0] + 1; last_state = wfa->tree [wfa->tree [wfa->root_state][0]][1]; break; case Cr: first_state = wfa->tree [wfa->tree [wfa->root_state][0]][1] + 1; last_state = wfa->states; break; default: error ("unknown color component."); } for (state = first_state; state < last_state; state++) for (label = 0; label < MAXLABELS; label++) if (isrange (wfa->tree [state][label])) if (x >= wfa->x [state][label] && y >= wfa->y [state][label] && x < (unsigned) (wfa->x [state][label] + width_of_level (wfa->level_of_state [state] - 1)) && y < (unsigned) (wfa->y [state][label] + height_of_level (wfa->level_of_state [state] - 1))) { success = YES; *range_state = state; *range_label = label; return success; } return success;}voidsort_ranges (unsigned state, unsigned *domain, range_sort_t *rs, const wfa_t *wfa)/* * Generate list of ranges in coder order. * 'state' is the current state of the call tree while 'domain' is the * index of the last added WFA state. * * Side effects: * 'domain' is incremented after recursion returns * 'rs' is filled accordingly * * No return value. */{ unsigned label; for (label = 0; label < MAXLABELS; label++) { if (isrange (wfa->tree [state][label])) rs->range_subdivided [rs->range_no] = NO; else { sort_ranges (wfa->tree [state][label], domain, rs, wfa); rs->range_subdivided [rs->range_no] = YES; } rs->range_state [rs->range_no] = state; rs->range_label [rs->range_no] = label; rs->range_max_domain [rs->range_no] = *domain; while (!usedomain (rs->range_max_domain [rs->range_no], wfa)) rs->range_max_domain [rs->range_no]--; if (label == 1 || !rs->range_subdivided [rs->range_no]) rs->range_no++; } (*domain)++;}bool_tlocate_delta_images (wfa_t *wfa)/* * Locate all WFA states that are part of a delta approximation. * I.e., these states are assigned to ranges that have been predicted * via MC or ND. * * Return value: * TRUE at least one state is part of a delta approximation * FALSE no delta approximations in this WFA * * Side effects: * 'wfa->delta [state][label]' is set accordingly. */{ unsigned state, label; bool_t delta = NO; for (state = wfa->root_state; state >= wfa->basis_states; state--) wfa->delta_state [state] = NO; for (state = wfa->root_state; state >= wfa->basis_states; state--) for (label = 0; label < MAXLABELS; label++) if (ischild (wfa->tree [state][label])) if (wfa->mv_tree [state][label].type != NONE || isedge (wfa->into [state][label][0]) || wfa->delta_state [state]) { delta = YES; wfa->delta_state [wfa->tree [state][label]] = YES; } return delta;}/***************************************************************************** private code ******************************************************************************/static unsignedxy_to_address (unsigned x, unsigned y, unsigned level, unsigned n)/* * Compute bintree address of subimage at coordinates ('x', 'y'). * Size of original image is determined by 'level'. * 'n' specifies number of iterations. * * Return value: * address of subimage */ { unsigned address = 0; while (n--) { address <<= 1; if (--level % 2) { if (x & width_of_level (level)) address++; } else { if (y & height_of_level (level)) address++; } } return address;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -