diff options
Diffstat (limited to 'converter/other/fiasco/codec/mwfa.c')
-rw-r--r-- | converter/other/fiasco/codec/mwfa.c | 888 |
1 files changed, 444 insertions, 444 deletions
diff --git a/converter/other/fiasco/codec/mwfa.c b/converter/other/fiasco/codec/mwfa.c index 0be08a4f..f83f2d00 100644 --- a/converter/other/fiasco/codec/mwfa.c +++ b/converter/other/fiasco/codec/mwfa.c @@ -1,9 +1,9 @@ /* - * mwfa.c: Initialization of MWFA coder + * mwfa.c: Initialization of MWFA coder + * + * Written by: Michael Unger + * Ullrich Hafner * - * Written by: Michael Unger - * Ullrich Hafner - * * This file is part of FIASCO (Fractal Image And Sequence COdec) * Copyright (C) 1994-2000 Ullrich Hafner */ @@ -38,33 +38,33 @@ static const unsigned local_range = 6; /***************************************************************************** - prototypes - + prototypes + *****************************************************************************/ static void get_mcpe (word_t *mcpe, const image_t *original, - unsigned x0, unsigned y0, unsigned width, unsigned height, - const word_t *mcblock1, const word_t *mcblock2); + unsigned x0, unsigned y0, unsigned width, unsigned height, + const word_t *mcblock1, const word_t *mcblock2); static real_t mcpe_norm (const image_t *original, unsigned x0, unsigned y0, unsigned width, - unsigned height, const word_t *mcblock1, const word_t *mcblock2); -static real_t + unsigned height, const word_t *mcblock1, const word_t *mcblock2); +static real_t find_best_mv (real_t price, const image_t *original, const image_t *reference, - unsigned x0, unsigned y0, unsigned width, unsigned height, - real_t *bits, int *mx, int *my, const real_t *mc_norms, - const wfa_info_t *wi, const motion_t *mt); + unsigned x0, unsigned y0, unsigned width, unsigned height, + real_t *bits, int *mx, int *my, const real_t *mc_norms, + const wfa_info_t *wi, const motion_t *mt); static real_t find_second_mv (real_t price, const image_t *original, - const image_t *reference, const word_t *mcblock1, - unsigned xr, unsigned yr, unsigned width, unsigned height, - real_t *bits, int *mx, int *my, const wfa_info_t *wi, - const motion_t *mt); + const image_t *reference, const word_t *mcblock1, + unsigned xr, unsigned yr, unsigned width, unsigned height, + real_t *bits, int *mx, int *my, const wfa_info_t *wi, + const motion_t *mt); /***************************************************************************** - public code - + public code + *****************************************************************************/ motion_t * @@ -75,32 +75,32 @@ alloc_motion (const wfa_info_t *wi) * fill in default values specified by 'wi'. * * Return value: - * pointer to the new option structure or NULL on error + * pointer to the new option structure or NULL on error */ { - int dx; /* motion vector coordinate */ + int dx; /* motion vector coordinate */ unsigned level; unsigned range_size = wi->half_pixel - ? square (wi->search_range) - : square (2 * wi->search_range); + ? square (wi->search_range) + : square (2 * wi->search_range); motion_t *mt = Calloc (1, sizeof (motion_t)); - + mt->original = NULL; mt->past = NULL; mt->future = NULL; - mt->xbits = Calloc (2 * wi->search_range, sizeof (real_t)); - mt->ybits = Calloc (2 * wi->search_range, sizeof (real_t)); + mt->xbits = Calloc (2 * wi->search_range, sizeof (real_t)); + mt->ybits = Calloc (2 * wi->search_range, sizeof (real_t)); for (dx = -wi->search_range; dx < (int) wi->search_range; dx++) { mt->xbits [dx + wi->search_range] - = mt->ybits [dx + wi->search_range] - = mv_code_table [dx + wi->search_range][1]; + = mt->ybits [dx + wi->search_range] + = mv_code_table [dx + wi->search_range][1]; } - + mt->mc_forward_norms = Calloc (MAXLEVEL, sizeof (real_t *)); mt->mc_backward_norms = Calloc (MAXLEVEL, sizeof (real_t *)); - + for (level = wi->p_min_level; level <= wi->p_max_level; level++) { mt->mc_forward_norms [level] = Calloc (range_size, sizeof (real_t)); @@ -119,7 +119,7 @@ free_motion (motion_t *mt) * No return value. * * Side effects: - * structure 'motion' is discarded. + * structure 'motion' is discarded. */ { unsigned level; @@ -129,9 +129,9 @@ free_motion (motion_t *mt) for (level = 0; level < MAXLEVEL; level++) { if (mt->mc_forward_norms [level]) - Free (mt->mc_forward_norms [level]); + Free (mt->mc_forward_norms [level]); if (mt->mc_backward_norms [level]) - Free (mt->mc_backward_norms [level]); + Free (mt->mc_backward_norms [level]); } Free (mt->mc_forward_norms); Free (mt->mc_backward_norms); @@ -140,7 +140,7 @@ free_motion (motion_t *mt) void subtract_mc (image_t *image, const image_t *past, const image_t *future, - const wfa_t *wfa) + const wfa_t *wfa) /* * Subtract motion compensation from chrom channels of 'image'. * Reference frames are given by 'past' and 'future'. @@ -150,135 +150,135 @@ subtract_mc (image_t *image, const image_t *past, const image_t *future, { unsigned state, label; word_t *mcblock1 = Calloc (size_of_level (wfa->wfainfo->p_max_level), - sizeof (word_t)); + sizeof (word_t)); word_t *mcblock2 = Calloc (size_of_level (wfa->wfainfo->p_max_level), - sizeof (word_t)); + sizeof (word_t)); for (state = wfa->basis_states; state < wfa->states; state++) for (label = 0; label < MAXLABELS; label++) - if (wfa->mv_tree [state][label].type != NONE) - { - color_e band; /* current color band */ - unsigned width, height; /* size of mcblock */ - unsigned offset; /* remaining pixels in original */ - - width = width_of_level (wfa->level_of_state [state] - 1); - height = height_of_level (wfa->level_of_state [state] - 1); - offset = image->width - width; - - switch (wfa->mv_tree [state][label].type) - { - case FORWARD: - for (band = first_band (image->color) + 1; - band <= last_band (image->color); band++) - { - unsigned y; /* row of block */ - word_t *mc1; /* pixel in MC block 1 */ - word_t *orig; /* pixel in original image */ - - extract_mc_block (mcblock1, width, height, - past->pixels [band], past->width, - wfa->wfainfo->half_pixel, - wfa->x [state][label], - wfa->y [state][label], - (wfa->mv_tree [state][label].fx / 2) - * 2, - (wfa->mv_tree [state][label].fy / 2) - * 2); - mc1 = mcblock1; - orig = image->pixels [band] + wfa->x [state][label] - + wfa->y [state][label] * image->width; - - for (y = height; y; y--) - { - unsigned x; /* column of block */ - - for (x = width; x; x--) - *orig++ -= *mc1++; - - orig += offset; - } - } - break; - case BACKWARD: - for (band = first_band (image->color) + 1; - band <= last_band (image->color); band++) - { - unsigned y; /* row of block */ - word_t *mc1; /* pixel in MC block 1 */ - word_t *orig; /* pixel in original image */ - - extract_mc_block (mcblock1, width, height, - future->pixels [band], future->width, - wfa->wfainfo->half_pixel, - wfa->x [state][label], - wfa->y [state][label], - (wfa->mv_tree [state][label].bx / 2) - * 2, - (wfa->mv_tree [state][label].by / 2) - * 2); - mc1 = mcblock1; - orig = image->pixels [band] + wfa->x [state][label] - + wfa->y [state][label] * image->width; - - for (y = height; y; y--) - { - unsigned x; /* column of block */ - - for (x = width; x; x--) - *orig++ -= *mc1++; - - orig += offset; - } - } - break; - case INTERPOLATED: - for (band = first_band (image->color) + 1; - band <= last_band (image->color); band++) - { - unsigned y; /* row of block */ - word_t *mc1; /* pixel in MC block 1 */ - word_t *mc2; /* pixel in MC block 2 */ - word_t *orig; /* pixel in original image */ - - extract_mc_block (mcblock1, width, height, - past->pixels [band], past->width, - wfa->wfainfo->half_pixel, - wfa->x [state][label], - wfa->y [state][label], - (wfa->mv_tree[state][label].fx / 2) - * 2, - (wfa->mv_tree[state][label].fy / 2) - * 2); - extract_mc_block (mcblock2, width, height, - future->pixels [band], future->width, - wfa->wfainfo->half_pixel, - wfa->x [state][label], - wfa->y [state][label], - (wfa->mv_tree[state][label].bx / 2) - * 2, - (wfa->mv_tree[state][label].by / 2) - * 2); - mc1 = mcblock1; - mc2 = mcblock2; - orig = image->pixels [band] + wfa->x [state][label] - + wfa->y [state][label] * image->width; - - for (y = height; y; y--) - { - unsigned x; /* column of block */ - - for (x = width; x; x--) - *orig++ -= (*mc1++ + *mc2++) / 2; - - orig += offset; - } - } - break; - default: - break; - } - } + if (wfa->mv_tree [state][label].type != NONE) + { + color_e band; /* current color band */ + unsigned width, height; /* size of mcblock */ + unsigned offset; /* remaining pixels in original */ + + width = width_of_level (wfa->level_of_state [state] - 1); + height = height_of_level (wfa->level_of_state [state] - 1); + offset = image->width - width; + + switch (wfa->mv_tree [state][label].type) + { + case FORWARD: + for (band = first_band (image->color) + 1; + band <= last_band (image->color); band++) + { + unsigned y; /* row of block */ + word_t *mc1; /* pixel in MC block 1 */ + word_t *orig; /* pixel in original image */ + + extract_mc_block (mcblock1, width, height, + past->pixels [band], past->width, + wfa->wfainfo->half_pixel, + wfa->x [state][label], + wfa->y [state][label], + (wfa->mv_tree [state][label].fx / 2) + * 2, + (wfa->mv_tree [state][label].fy / 2) + * 2); + mc1 = mcblock1; + orig = image->pixels [band] + wfa->x [state][label] + + wfa->y [state][label] * image->width; + + for (y = height; y; y--) + { + unsigned x; /* column of block */ + + for (x = width; x; x--) + *orig++ -= *mc1++; + + orig += offset; + } + } + break; + case BACKWARD: + for (band = first_band (image->color) + 1; + band <= last_band (image->color); band++) + { + unsigned y; /* row of block */ + word_t *mc1; /* pixel in MC block 1 */ + word_t *orig; /* pixel in original image */ + + extract_mc_block (mcblock1, width, height, + future->pixels [band], future->width, + wfa->wfainfo->half_pixel, + wfa->x [state][label], + wfa->y [state][label], + (wfa->mv_tree [state][label].bx / 2) + * 2, + (wfa->mv_tree [state][label].by / 2) + * 2); + mc1 = mcblock1; + orig = image->pixels [band] + wfa->x [state][label] + + wfa->y [state][label] * image->width; + + for (y = height; y; y--) + { + unsigned x; /* column of block */ + + for (x = width; x; x--) + *orig++ -= *mc1++; + + orig += offset; + } + } + break; + case INTERPOLATED: + for (band = first_band (image->color) + 1; + band <= last_band (image->color); band++) + { + unsigned y; /* row of block */ + word_t *mc1; /* pixel in MC block 1 */ + word_t *mc2; /* pixel in MC block 2 */ + word_t *orig; /* pixel in original image */ + + extract_mc_block (mcblock1, width, height, + past->pixels [band], past->width, + wfa->wfainfo->half_pixel, + wfa->x [state][label], + wfa->y [state][label], + (wfa->mv_tree[state][label].fx / 2) + * 2, + (wfa->mv_tree[state][label].fy / 2) + * 2); + extract_mc_block (mcblock2, width, height, + future->pixels [band], future->width, + wfa->wfainfo->half_pixel, + wfa->x [state][label], + wfa->y [state][label], + (wfa->mv_tree[state][label].bx / 2) + * 2, + (wfa->mv_tree[state][label].by / 2) + * 2); + mc1 = mcblock1; + mc2 = mcblock2; + orig = image->pixels [band] + wfa->x [state][label] + + wfa->y [state][label] * image->width; + + for (y = height; y; y--) + { + unsigned x; /* column of block */ + + for (x = width; x; x--) + *orig++ -= (*mc1++ + *mc2++) / 2; + + orig += offset; + } + } + break; + default: + break; + } + } Free (mcblock1); Free (mcblock2); @@ -286,7 +286,7 @@ subtract_mc (image_t *image, const image_t *past, const image_t *future, void find_P_frame_mc (word_t *mcpe, real_t price, range_t *range, - const wfa_info_t *wi, const motion_t *mt) + const wfa_info_t *wi, const motion_t *mt) /* * Determine best motion vector for P-frame. * @@ -301,7 +301,7 @@ find_P_frame_mc (word_t *mcpe, real_t price, range_t *range, unsigned width = width_of_level (range->level); unsigned height = height_of_level (range->level); word_t *mcblock = Calloc (width * height, sizeof (word_t)); - + range->mv_tree_bits = 1; range->mv.type = FORWARD; @@ -309,24 +309,24 @@ find_P_frame_mc (word_t *mcpe, real_t price, range_t *range, * Find best matching forward prediction */ find_best_mv (price, mt->original, mt->past, range->x, range->y, - width, height, &range->mv_coord_bits, &range->mv.fx, - &range->mv.fy, mt->mc_forward_norms [range->level], wi, mt); + width, height, &range->mv_coord_bits, &range->mv.fx, + &range->mv.fy, mt->mc_forward_norms [range->level], wi, mt); /* * Compute MCPE */ extract_mc_block (mcblock, width, height, mt->past->pixels [GRAY], - mt->past->width, wi->half_pixel, range->x, range->y, - range->mv.fx, range->mv.fy); + mt->past->width, wi->half_pixel, range->x, range->y, + range->mv.fx, range->mv.fy); get_mcpe (mcpe, mt->original, range->x, range->y, width, height, - mcblock, NULL); + mcblock, NULL); Free (mcblock); } void find_B_frame_mc (word_t *mcpe, real_t price, range_t *range, - const wfa_info_t *wi, const motion_t *mt) + const wfa_info_t *wi, const motion_t *mt) /* * Determines best motion compensation for B-frame. * Steps: @@ -338,104 +338,104 @@ find_B_frame_mc (word_t *mcpe, real_t price, range_t *range, * FORWARD 000 * BACKWARD 001 * INTERPOLATED 01 - * + * * Return values: * range->mvt_bits (# of mv-tree bits) * range->mvxybits (# of bits for vector components) * mt->mcpe (MCPE in scan-order) */ { - mc_type_e mctype; /* type of motion compensation */ - real_t forward_costs; /* costs of FORWARD mc */ - real_t backward_costs; /* costs of BACKWARD mc */ - real_t interp_costs; /* costs of INTERPOLATED mc */ - real_t forward_bits; /* bits for FORWARD mc */ - real_t backward_bits; /* bits for BACKWARD mc */ - real_t interp_bits; /* bits for INTERPOLATED mc */ - int fx, fy; /* coordinates FORWARD mc */ - int bx, by; /* coordinates BACKWARD mc */ - int ifx, ify; /* coordinates forw. INTERPOLATED mc */ - int ibx, iby; /* coordinates back. INTERPOLATED mc */ + mc_type_e mctype; /* type of motion compensation */ + real_t forward_costs; /* costs of FORWARD mc */ + real_t backward_costs; /* costs of BACKWARD mc */ + real_t interp_costs; /* costs of INTERPOLATED mc */ + real_t forward_bits; /* bits for FORWARD mc */ + real_t backward_bits; /* bits for BACKWARD mc */ + real_t interp_bits; /* bits for INTERPOLATED mc */ + int fx, fy; /* coordinates FORWARD mc */ + int bx, by; /* coordinates BACKWARD mc */ + int ifx, ify; /* coordinates forw. INTERPOLATED mc */ + int ibx, iby; /* coordinates back. INTERPOLATED mc */ unsigned width = width_of_level (range->level); unsigned height = height_of_level (range->level); word_t *mcblock1 = Calloc (width * height, sizeof (word_t)); word_t *mcblock2 = Calloc (width * height, sizeof (word_t)); - + /* * Forward interpolation: use past frame as reference */ forward_costs = find_best_mv (price, mt->original, mt->past, - range->x, range->y, width, height, - &forward_bits, &fx, &fy, - mt->mc_forward_norms [range->level], wi, mt) - + 3 * price; /* code 000 */ + range->x, range->y, width, height, + &forward_bits, &fx, &fy, + mt->mc_forward_norms [range->level], wi, mt) + + 3 * price; /* code 000 */ /* * Backward interpolation: use future frame as reference */ backward_costs = find_best_mv (price, mt->original, mt->future, - range->x, range->y, width, height, - &backward_bits, &bx, &by, - mt->mc_backward_norms [range->level], wi, mt) - + 3 * price; /* code 001 */ + range->x, range->y, width, height, + &backward_bits, &bx, &by, + mt->mc_backward_norms [range->level], wi, mt) + + 3 * price; /* code 001 */ /* * Bidirectional interpolation: use both past and future frame as reference */ - if (wi->cross_B_search) + if (wi->cross_B_search) { - real_t icosts1; /* costs interpolation alternative 1 */ - real_t icosts2; /* costs interpolation alternative 2 */ - real_t ibackward_bits; /* additional bits alternative 1 */ - real_t iforward_bits; /* additional bits alternative 1 */ - + real_t icosts1; /* costs interpolation alternative 1 */ + real_t icosts2; /* costs interpolation alternative 2 */ + real_t ibackward_bits; /* additional bits alternative 1 */ + real_t iforward_bits; /* additional bits alternative 1 */ + /* * Alternative 1: keep forward mv and vary backward mv locally */ extract_mc_block (mcblock1, width, height, mt->past->pixels [GRAY], - mt->past->width, wi->half_pixel, - range->x, range->y, fx, fy); + mt->past->width, wi->half_pixel, + range->x, range->y, fx, fy); - ibx = bx; /* start with backward coordinates */ + ibx = bx; /* start with backward coordinates */ iby = by; icosts1 = find_second_mv (price, mt->original, mt->future, - mcblock1, range->x, range->y, width, height, - &ibackward_bits, &ibx, &iby, wi, mt) - + (forward_bits + 2) * price; /* code 01 */ + mcblock1, range->x, range->y, width, height, + &ibackward_bits, &ibx, &iby, wi, mt) + + (forward_bits + 2) * price; /* code 01 */ /* * Alternative 2: Keep backward mv and vary forward mv locally */ extract_mc_block (mcblock1, width, height, mt->future->pixels [GRAY], - mt->future->width, wi->half_pixel, - range->x, range->y, bx, by); + mt->future->width, wi->half_pixel, + range->x, range->y, bx, by); ifx = fx; ify = fy; icosts2 = find_second_mv (price, mt->original, mt->past, - mcblock1, range->x, range->y, width, height, - &iforward_bits, &ifx, &ify, wi, mt) - + (backward_bits + 2) * price; /* code 01 */ - + mcblock1, range->x, range->y, width, height, + &iforward_bits, &ifx, &ify, wi, mt) + + (backward_bits + 2) * price; /* code 01 */ + /* * Choose best alternative */ if (icosts1 < icosts2) { - ifx = fx; - ify = fy; - interp_bits = forward_bits + ibackward_bits; - interp_costs = icosts1; + ifx = fx; + ify = fy; + interp_bits = forward_bits + ibackward_bits; + interp_costs = icosts1; } else { - ibx = bx; - iby = by; - interp_bits = iforward_bits + backward_bits; - interp_costs = icosts2; + ibx = bx; + iby = by; + interp_bits = iforward_bits + backward_bits; + interp_costs = icosts2; } } - else /* local exhaustive search */ + else /* local exhaustive search */ { /* * Keep forward and backward mv because of time constraints @@ -448,14 +448,14 @@ find_B_frame_mc (word_t *mcpe, real_t price, range_t *range, interp_bits = forward_bits + backward_bits; extract_mc_block (mcblock1, width, height, mt->past->pixels [GRAY], - mt->past->width, wi->half_pixel, - range->x, range->y, fx, fy); + mt->past->width, wi->half_pixel, + range->x, range->y, fx, fy); extract_mc_block (mcblock2, width, height, mt->future->pixels [GRAY], - mt->future->width, wi->half_pixel, - range->x, range->y, bx, by); + mt->future->width, wi->half_pixel, + range->x, range->y, bx, by); interp_costs = mcpe_norm (mt->original, range->x, range->y, - width, height, mcblock1, mcblock2) - + (interp_bits + 2) * price; /* code 01 */ + width, height, mcblock1, mcblock2) + + (interp_bits + 2) * price; /* code 01 */ } /* @@ -464,63 +464,63 @@ find_B_frame_mc (word_t *mcpe, real_t price, range_t *range, if (forward_costs <= interp_costs) { if (forward_costs <= backward_costs) - mctype = FORWARD; + mctype = FORWARD; else - mctype = BACKWARD; + mctype = BACKWARD; } else { if (backward_costs <= interp_costs) - mctype = BACKWARD; + mctype = BACKWARD; else - mctype = INTERPOLATED; + mctype = INTERPOLATED; } switch (mctype) { case FORWARD: - range->mv_tree_bits = 3; - range->mv_coord_bits = forward_bits; - range->mv.type = FORWARD; - range->mv.fx = fx; - range->mv.fy = fy; - extract_mc_block (mcblock1, width, height, mt->past->pixels [GRAY], - mt->past->width, wi->half_pixel, - range->x, range->y, range->mv.fx, range->mv.fy); - get_mcpe (mcpe, mt->original, range->x, range->y, width, height, - mcblock1, NULL); - break; + range->mv_tree_bits = 3; + range->mv_coord_bits = forward_bits; + range->mv.type = FORWARD; + range->mv.fx = fx; + range->mv.fy = fy; + extract_mc_block (mcblock1, width, height, mt->past->pixels [GRAY], + mt->past->width, wi->half_pixel, + range->x, range->y, range->mv.fx, range->mv.fy); + get_mcpe (mcpe, mt->original, range->x, range->y, width, height, + mcblock1, NULL); + break; case BACKWARD: - range->mv_tree_bits = 3; - range->mv_coord_bits = backward_bits; - range->mv.type = BACKWARD; - range->mv.bx = bx; - range->mv.by = by; - extract_mc_block (mcblock1, width, height, mt->future->pixels [GRAY], - mt->future->width, wi->half_pixel, - range->x, range->y, range->mv.bx, range->mv.by); - get_mcpe (mcpe, mt->original, range->x, range->y, width, height, - mcblock1, NULL); - break; + range->mv_tree_bits = 3; + range->mv_coord_bits = backward_bits; + range->mv.type = BACKWARD; + range->mv.bx = bx; + range->mv.by = by; + extract_mc_block (mcblock1, width, height, mt->future->pixels [GRAY], + mt->future->width, wi->half_pixel, + range->x, range->y, range->mv.bx, range->mv.by); + get_mcpe (mcpe, mt->original, range->x, range->y, width, height, + mcblock1, NULL); + break; case INTERPOLATED: - range->mv_tree_bits = 2; - range->mv_coord_bits = interp_bits; - range->mv.type = INTERPOLATED; - range->mv.fx = ifx; - range->mv.fy = ify; - range->mv.bx = ibx; - range->mv.by = iby; - extract_mc_block (mcblock1, width, height, mt->past->pixels [GRAY], - mt->past->width, wi->half_pixel, - range->x, range->y, range->mv.fx, range->mv.fy); - extract_mc_block (mcblock2, width, height, mt->future->pixels [GRAY], - mt->future->width, wi->half_pixel, - range->x, range->y, range->mv.bx, range->mv.by); - get_mcpe (mcpe, mt->original, range->x, range->y, width, height, - mcblock1, mcblock2); - break; + range->mv_tree_bits = 2; + range->mv_coord_bits = interp_bits; + range->mv.type = INTERPOLATED; + range->mv.fx = ifx; + range->mv.fy = ify; + range->mv.bx = ibx; + range->mv.by = iby; + extract_mc_block (mcblock1, width, height, mt->past->pixels [GRAY], + mt->past->width, wi->half_pixel, + range->x, range->y, range->mv.fx, range->mv.fy); + extract_mc_block (mcblock2, width, height, mt->future->pixels [GRAY], + mt->future->width, wi->half_pixel, + range->x, range->y, range->mv.bx, range->mv.by); + get_mcpe (mcpe, mt->original, range->x, range->y, width, height, + mcblock1, mcblock2); + break; default: - break; + break; } Free (mcblock1); @@ -529,7 +529,7 @@ find_B_frame_mc (word_t *mcpe, real_t price, range_t *range, void fill_norms_table (unsigned x0, unsigned y0, unsigned level, - const wfa_info_t *wi, motion_t *mt) + const wfa_info_t *wi, motion_t *mt) /* * Compute norms of difference images for all possible displacements * in 'mc_forward_norm' and 'mc_backward_norm'. @@ -537,50 +537,50 @@ fill_norms_table (unsigned x0, unsigned y0, unsigned level, * No return value. * * Side effects: - * 'mt->mc_backward_norms' are computed - * 'mt->mc_forward_norms' are computed + * 'mt->mc_backward_norms' are computed + * 'mt->mc_forward_norms' are computed */ { - int mx, my; /* coordinates of motion vector */ - unsigned sr; /* mv search range +-'sr' pixels */ - unsigned index = 0; /* index of motion vector */ + int mx, my; /* coordinates of motion vector */ + unsigned sr; /* mv search range +-'sr' pixels */ + unsigned index = 0; /* index of motion vector */ unsigned width = width_of_level (level); unsigned height = height_of_level (level); word_t *mcblock = Calloc (width * height, sizeof (word_t)); sr = wi->half_pixel ? wi->search_range / 2 : wi->search_range; - + for (my = -sr; my < (int) sr; my++) for (mx = -sr; mx < (int) sr; mx++, index++) { - if ((int) x0 + mx < 0 || /* block outside visible area */ - x0 + mx + width > mt->original->width || - (int) y0 + my < 0 || - y0 + my + height > mt->original->height) - { - mt->mc_forward_norms [level][index] = 0.0; - mt->mc_backward_norms [level][index] = 0.0; - } - else - { - extract_mc_block (mcblock, width, height, mt->past->pixels [GRAY], - mt->past->width, wi->half_pixel, - x0, y0, mx, my); - mt->mc_forward_norms [level][index] - = mcpe_norm (mt->original, x0, y0, width, height, - mcblock, NULL); - - if (mt->frame_type == B_FRAME) - { - extract_mc_block (mcblock, width, height, - mt->future->pixels [GRAY], - mt->future->width, wi->half_pixel, - x0, y0, mx, my); - mt->mc_backward_norms[level][index] - = mcpe_norm (mt->original, x0, y0, width, height, - mcblock, NULL); - } - } + if ((int) x0 + mx < 0 || /* block outside visible area */ + x0 + mx + width > mt->original->width || + (int) y0 + my < 0 || + y0 + my + height > mt->original->height) + { + mt->mc_forward_norms [level][index] = 0.0; + mt->mc_backward_norms [level][index] = 0.0; + } + else + { + extract_mc_block (mcblock, width, height, mt->past->pixels [GRAY], + mt->past->width, wi->half_pixel, + x0, y0, mx, my); + mt->mc_forward_norms [level][index] + = mcpe_norm (mt->original, x0, y0, width, height, + mcblock, NULL); + + if (mt->frame_type == B_FRAME) + { + extract_mc_block (mcblock, width, height, + mt->future->pixels [GRAY], + mt->future->width, wi->half_pixel, + x0, y0, mx, my); + mt->mc_backward_norms[level][index] + = mcpe_norm (mt->original, x0, y0, width, height, + mcblock, NULL); + } + } } Free (mcblock); @@ -588,14 +588,14 @@ fill_norms_table (unsigned x0, unsigned y0, unsigned level, /***************************************************************************** - private code - + private code + *****************************************************************************/ static void get_mcpe (word_t *mcpe, const image_t *original, unsigned x0, unsigned y0, - unsigned width, unsigned height, const word_t *mcblock1, - const word_t *mcblock2) + unsigned width, unsigned height, const word_t *mcblock1, + const word_t *mcblock2) /* * Compute MCPE image 'original' - reference. The reference is either * composed of 'mcblock1' or of ('mcblock1' + 'mcblock2') / 2 (if @@ -605,44 +605,44 @@ get_mcpe (word_t *mcpe, const image_t *original, unsigned x0, unsigned y0, * No return value. * * Side effects: - * 'mcpe []' is filled with the delta image + * 'mcpe []' is filled with the delta image */ { - const word_t *oblock; /* pointer to original image */ + const word_t *oblock; /* pointer to original image */ assert (mcpe); - + oblock = original->pixels [GRAY] + y0 * original->width + x0; - if (mcblock2 != NULL) /* interpolated prediction */ + if (mcblock2 != NULL) /* interpolated prediction */ { - unsigned x, y; /* current coordinates */ - - for (y = height; y; y--) + unsigned x, y; /* current coordinates */ + + for (y = height; y; y--) { - for (x = width; x; x--) - *mcpe++ = *oblock++ - (*mcblock1++ + *mcblock2++) / 2; + for (x = width; x; x--) + *mcpe++ = *oblock++ - (*mcblock1++ + *mcblock2++) / 2; - oblock += original->width - width; + oblock += original->width - width; } } - else /* forward or backward prediction */ + else /* forward or backward prediction */ { - unsigned x, y; /* current coordinates */ - - for (y = height; y; y--) + unsigned x, y; /* current coordinates */ + + for (y = height; y; y--) { - for (x = width; x; x--) - *mcpe++ = *oblock++ - *mcblock1++; - - oblock += original->width - width; + for (x = width; x; x--) + *mcpe++ = *oblock++ - *mcblock1++; + + oblock += original->width - width; } } } static real_t mcpe_norm (const image_t *original, unsigned x0, unsigned y0, unsigned width, - unsigned height, const word_t *mcblock1, const word_t *mcblock2) + unsigned height, const word_t *mcblock1, const word_t *mcblock2) /* * Compute norm of motion compensation prediction error. * Coordinates of 'original' block are given by ('x0', 'y0') @@ -650,79 +650,79 @@ mcpe_norm (const image_t *original, unsigned x0, unsigned y0, unsigned width, * Reference blocks are stored in 'mcimage1' and 'mcimage2'. * * Return value: - * square of norm of difference image + * square of norm of difference image */ { unsigned n; real_t norm = 0; word_t *mcpe = Calloc (width * height, sizeof (word_t)); word_t *ptr = mcpe; - + get_mcpe (mcpe, original, x0, y0, width, height, mcblock1, mcblock2); - for (n = height * width; n; n--, ptr++) + for (n = height * width; n; n--, ptr++) norm += square (*ptr / 16); - + Free (mcpe); - + return norm; } -static real_t +static real_t find_best_mv (real_t price, const image_t *original, const image_t *reference, - unsigned x0, unsigned y0, unsigned width, unsigned height, - real_t *bits, int *mx, int *my, const real_t *mc_norms, - const wfa_info_t *wi, const motion_t *mt) + unsigned x0, unsigned y0, unsigned width, unsigned height, + real_t *bits, int *mx, int *my, const real_t *mc_norms, + const wfa_info_t *wi, const motion_t *mt) /* * Find best matching motion vector in image 'reference' to predict * the block ('x0', 'y0') of size 'width'x'height in image 'original'. * * Return values: - * prediction costs + * prediction costs * * Side effects: - * 'mx', 'my' coordinates of motion vector - * 'bits' number of bits to encode mv + * 'mx', 'my' coordinates of motion vector + * 'bits' number of bits to encode mv */ { - unsigned sr; /* mv search range +/- 'sr' pixels */ - unsigned index; /* index of motion vector */ - int x, y; /* coordinates of motion vector */ - real_t costs; /* costs arising if mv is chosen */ - real_t mincosts = MAXCOSTS; /* best costs so far */ - unsigned bitshift; /* half_pixel coordinates multiplier */ - + unsigned sr; /* mv search range +/- 'sr' pixels */ + unsigned index; /* index of motion vector */ + int x, y; /* coordinates of motion vector */ + real_t costs; /* costs arising if mv is chosen */ + real_t mincosts = MAXCOSTS; /* best costs so far */ + unsigned bitshift; /* half_pixel coordinates multiplier */ + *mx = *my = 0; /* * Find best fitting motion vector: * Use exhaustive search in the interval x,y +- sr (no halfpixel accuracy) - * or x,y +- sr/2 (halfpixel accuracy) + * or x,y +- sr/2 (halfpixel accuracy) */ - sr = wi->half_pixel ? wi->search_range / 2 : wi->search_range; - bitshift = (wi->half_pixel ? 2 : 1); /* bit0 reserved for halfpixel pred. */ - + sr = wi->half_pixel ? wi->search_range / 2 : wi->search_range; + bitshift = (wi->half_pixel ? 2 : 1); /* bit0 reserved for halfpixel pred. */ + for (index = 0, y = -sr; y < (int) sr; y++) for (x = -sr; x < (int) sr; x++, index++) - if ((int) x0 + x >= 0 && (int) y0 + y >= 0 && - x0 + x + width <= original->width && - y0 + y + height <= original->height) - { - /* - * Block is inside visible area. - * Compare current costs with 'mincosts' - */ - costs = mc_norms [index] - + (mt->xbits [(x + sr) * bitshift] - + mt->ybits [(y + sr) * bitshift]) * price; - - if (costs < mincosts) - { - mincosts = costs; - *mx = x * bitshift; - *my = y * bitshift; - } - } + if ((int) x0 + x >= 0 && (int) y0 + y >= 0 && + x0 + x + width <= original->width && + y0 + y + height <= original->height) + { + /* + * Block is inside visible area. + * Compare current costs with 'mincosts' + */ + costs = mc_norms [index] + + (mt->xbits [(x + sr) * bitshift] + + mt->ybits [(y + sr) * bitshift]) * price; + + if (costs < mincosts) + { + mincosts = costs; + *mx = x * bitshift; + *my = y * bitshift; + } + } /* * Halfpixel prediction: @@ -730,53 +730,53 @@ find_best_mv (real_t price, const image_t *original, const image_t *reference, */ if (wi->half_pixel) { - int rx, ry; /* halfpixel refinement */ - unsigned bestrx, bestry; /* coordinates of best mv */ + int rx, ry; /* halfpixel refinement */ + unsigned bestrx, bestry; /* coordinates of best mv */ word_t *mcblock = Calloc (width * height, sizeof (word_t)); - + bestrx = bestry = 0; for (rx = -1; rx <= 1; rx++) - for (ry = -1; ry <= 1; ry++) - { - /* - * Check if the new motion vector is in allowed area - */ - if (rx == 0 && ry == 0) /* already tested */ - continue; - if ((int) x0 + (*mx / 2) + rx < 0 || /* outside visible area */ - x0 + (*mx / 2) + rx + width > original->width || - (int) y0 + (*my / 2) + ry < 0 || - y0 + (*my / 2) + ry + height > original->height) - continue; - if (*mx + rx < (int) -sr || *mx + rx >= (int) sr || - *my + ry < (int) -sr || *my + ry >= (int) sr) - continue; /* out of bounds */ - - /* - * Compute costs of new motion compensation - */ - extract_mc_block (mcblock, width, height, - reference->pixels [GRAY], - reference->width, wi->half_pixel, - x0, y0, *mx + rx, *my + ry); - costs = mcpe_norm (mt->original, x0, y0, width, height, mcblock, - NULL) - + (mt->xbits [*mx + rx + sr * bitshift] - + mt->ybits [*my + ry + sr * bitshift]) * price; - if (costs < mincosts) - { - bestrx = rx; - bestry = ry; - mincosts = costs; - } - } + for (ry = -1; ry <= 1; ry++) + { + /* + * Check if the new motion vector is in allowed area + */ + if (rx == 0 && ry == 0) /* already tested */ + continue; + if ((int) x0 + (*mx / 2) + rx < 0 || /* outside visible area */ + x0 + (*mx / 2) + rx + width > original->width || + (int) y0 + (*my / 2) + ry < 0 || + y0 + (*my / 2) + ry + height > original->height) + continue; + if (*mx + rx < (int) -sr || *mx + rx >= (int) sr || + *my + ry < (int) -sr || *my + ry >= (int) sr) + continue; /* out of bounds */ + + /* + * Compute costs of new motion compensation + */ + extract_mc_block (mcblock, width, height, + reference->pixels [GRAY], + reference->width, wi->half_pixel, + x0, y0, *mx + rx, *my + ry); + costs = mcpe_norm (mt->original, x0, y0, width, height, mcblock, + NULL) + + (mt->xbits [*mx + rx + sr * bitshift] + + mt->ybits [*my + ry + sr * bitshift]) * price; + if (costs < mincosts) + { + bestrx = rx; + bestry = ry; + mincosts = costs; + } + } *mx += bestrx; *my += bestry; Free (mcblock); } /* halfpixel */ - + *bits = mt->xbits [*mx + sr * bitshift] + mt->ybits [*my + sr * bitshift]; return mincosts; @@ -784,28 +784,28 @@ find_best_mv (real_t price, const image_t *original, const image_t *reference, static real_t find_second_mv (real_t price, const image_t *original, - const image_t *reference, const word_t *mcblock1, - unsigned xr, unsigned yr, unsigned width, unsigned height, - real_t *bits, int *mx, int *my, const wfa_info_t *wi, - const motion_t *mt) + const image_t *reference, const word_t *mcblock1, + unsigned xr, unsigned yr, unsigned width, unsigned height, + real_t *bits, int *mx, int *my, const wfa_info_t *wi, + const motion_t *mt) /* * Search local area (*mx,*my) for best additional mv. * Overwrite mt->tmpblock. * TODO check sr = search_range * * Return values: - * prediction costs + * prediction costs * * Side effects: - * 'mx','my' coordinates of mv - * 'bits' number of bits to encode mv + * 'mx','my' coordinates of mv + * 'bits' number of bits to encode mv */ { - real_t mincosts = MAXCOSTS; /* best costs so far */ - unsigned sr; /* MV search range +/- 'sr' pixels */ - int x, y; /* coordinates of motion vector */ - int y0, y1, x0, x1; /* start/end coord. of search range */ - unsigned bitshift; /* half_pixel coordinates multiplier */ + real_t mincosts = MAXCOSTS; /* best costs so far */ + unsigned sr; /* MV search range +/- 'sr' pixels */ + int x, y; /* coordinates of motion vector */ + int y0, y1, x0, x1; /* start/end coord. of search range */ + unsigned bitshift; /* half_pixel coordinates multiplier */ word_t *mcblock2 = Calloc (width * height, sizeof (word_t)); sr = wi->search_range; @@ -817,40 +817,40 @@ find_second_mv (real_t price, const image_t *original, *mx = *my = 0; - bitshift = (wi->half_pixel ? 2 : 1); /* bit0 reserved for halfpixel pred. */ + bitshift = (wi->half_pixel ? 2 : 1); /* bit0 reserved for halfpixel pred. */ + - for (y = y0; y < y1; y++) for (x = x0; x < x1; x++) { - real_t costs; /* costs arising if mv is chosen */ - - /* - * Test each mv ('x', 'y') in the given search range: - * Get the new motion compensation image from 'reference' and compute - * the norm of the motion compensation prediction error - * 'original' - 0.5 * ('firstmc' + 'reference') - */ - if ((int) (xr * bitshift) + x < 0 || /* outside visible area */ - xr * bitshift + x > (original->width - width) * bitshift || - (int) (yr * bitshift) + y < 0 || - yr * bitshift + y > (original->height - height) * bitshift) - continue; - - extract_mc_block (mcblock2, width, height, - reference->pixels [GRAY], reference->width, - wi->half_pixel, x0, y0, x, y); - - costs = mcpe_norm (mt->original, x0, y0, width, height, - mcblock1, mcblock2) - + (mt->xbits [x + sr] + mt->ybits [y + sr]) * price; - - if (costs < mincosts) - { - mincosts = costs; - *mx = x; - *my = y; - } + real_t costs; /* costs arising if mv is chosen */ + + /* + * Test each mv ('x', 'y') in the given search range: + * Get the new motion compensation image from 'reference' and compute + * the norm of the motion compensation prediction error + * 'original' - 0.5 * ('firstmc' + 'reference') + */ + if ((int) (xr * bitshift) + x < 0 || /* outside visible area */ + xr * bitshift + x > (original->width - width) * bitshift || + (int) (yr * bitshift) + y < 0 || + yr * bitshift + y > (original->height - height) * bitshift) + continue; + + extract_mc_block (mcblock2, width, height, + reference->pixels [GRAY], reference->width, + wi->half_pixel, x0, y0, x, y); + + costs = mcpe_norm (mt->original, x0, y0, width, height, + mcblock1, mcblock2) + + (mt->xbits [x + sr] + mt->ybits [y + sr]) * price; + + if (costs < mincosts) + { + mincosts = costs; + *mx = x; + *my = y; + } } *bits = mt->xbits [*mx + sr] + mt->ybits [*my + sr]; |