|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* prediction.c: Range image prediction with MC or ND
|
|
Packit |
78deda |
*
|
|
Packit |
78deda |
* Written by: Ullrich Hafner
|
|
Packit |
78deda |
* Michael Unger
|
|
Packit |
78deda |
*
|
|
Packit |
78deda |
* This file is part of FIASCO (Fractal Image And Sequence COdec)
|
|
Packit |
78deda |
* Copyright (C) 1994-2000 Ullrich Hafner
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* $Date: 2000/06/14 20:50:51 $
|
|
Packit |
78deda |
* $Author: hafner $
|
|
Packit |
78deda |
* $Revision: 5.1 $
|
|
Packit |
78deda |
* $State: Exp $
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
|
|
Packit |
78deda |
#include "config.h"
|
|
Packit |
78deda |
|
|
Packit |
78deda |
#include <string.h>
|
|
Packit |
78deda |
|
|
Packit |
78deda |
#include "types.h"
|
|
Packit |
78deda |
#include "macros.h"
|
|
Packit |
78deda |
#include "error.h"
|
|
Packit |
78deda |
|
|
Packit |
78deda |
#include "cwfa.h"
|
|
Packit |
78deda |
#include "ip.h"
|
|
Packit |
78deda |
#include "control.h"
|
|
Packit |
78deda |
#include "misc.h"
|
|
Packit |
78deda |
#include "subdivide.h"
|
|
Packit |
78deda |
#include "bintree.h"
|
|
Packit |
78deda |
#include "domain-pool.h"
|
|
Packit |
78deda |
#include "approx.h"
|
|
Packit |
78deda |
#include "wfalib.h"
|
|
Packit |
78deda |
#include "mwfa.h"
|
|
Packit |
78deda |
#include "prediction.h"
|
|
Packit |
78deda |
|
|
Packit |
78deda |
#include "decoder.h"
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/*****************************************************************************
|
|
Packit |
78deda |
|
|
Packit |
78deda |
local variables
|
|
Packit |
78deda |
|
|
Packit |
78deda |
*****************************************************************************/
|
|
Packit |
78deda |
|
|
Packit |
78deda |
typedef struct state_data
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
real_t final_distribution;
|
|
Packit |
78deda |
byte_t level_of_state;
|
|
Packit |
78deda |
byte_t domain_type;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
real_t *images_of_state;
|
|
Packit |
78deda |
real_t *inner_products;
|
|
Packit |
78deda |
real_t *ip_states_state [MAXLEVEL];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
word_t tree [MAXLABELS];
|
|
Packit |
78deda |
mv_t mv_tree [MAXLABELS];
|
|
Packit |
78deda |
word_t y_state [MAXLABELS];
|
|
Packit |
78deda |
byte_t y_column [MAXLABELS];
|
|
Packit |
78deda |
byte_t prediction [MAXLABELS];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
u_word_t x [MAXLABELS];
|
|
Packit |
78deda |
u_word_t y [MAXLABELS];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
real_t weight [MAXLABELS][MAXEDGES + 1];
|
|
Packit |
78deda |
word_t int_weight [MAXLABELS][MAXEDGES + 1];
|
|
Packit |
78deda |
word_t into [MAXLABELS][MAXEDGES + 1];
|
|
Packit |
78deda |
} state_data_t;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/*****************************************************************************
|
|
Packit |
78deda |
|
|
Packit |
78deda |
prototypes
|
|
Packit |
78deda |
|
|
Packit |
78deda |
*****************************************************************************/
|
|
Packit |
78deda |
|
|
Packit |
78deda |
static real_t
|
|
Packit |
78deda |
nd_prediction (real_t max_costs, real_t price, unsigned band, int y_state,
|
|
Packit |
78deda |
range_t *range, wfa_t *wfa, coding_t *c);
|
|
Packit |
78deda |
static real_t
|
|
Packit |
78deda |
mc_prediction (real_t max_costs, real_t price, unsigned band, int y_state,
|
|
Packit |
78deda |
range_t *range, wfa_t *wfa, coding_t *c);
|
|
Packit |
78deda |
static state_data_t *
|
|
Packit |
78deda |
store_state_data (unsigned from, unsigned to, unsigned max_level,
|
|
Packit |
78deda |
wfa_t *wfa, coding_t *c);
|
|
Packit |
78deda |
static void
|
|
Packit |
78deda |
restore_state_data (unsigned from, unsigned to, unsigned max_level,
|
|
Packit |
78deda |
state_data_t *data, wfa_t *wfa, coding_t *c);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/*****************************************************************************
|
|
Packit |
78deda |
|
|
Packit |
78deda |
public code
|
|
Packit |
78deda |
|
|
Packit |
78deda |
*****************************************************************************/
|
|
Packit |
78deda |
|
|
Packit |
78deda |
real_t
|
|
Packit |
78deda |
predict_range (real_t max_costs, real_t price, range_t *range, wfa_t *wfa,
|
|
Packit |
78deda |
coding_t *c, unsigned band, int y_state, unsigned states,
|
|
Packit |
78deda |
const tree_t *tree_model, const tree_t *p_tree_model,
|
|
Packit |
78deda |
const void *domain_model, const void *d_domain_model,
|
|
Packit |
78deda |
const void *coeff_model, const void *d_coeff_model)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
unsigned state; /* counter */
|
|
Packit |
78deda |
void *rec_domain_model; /* domain model after recursion */
|
|
Packit |
78deda |
void *rec_d_domain_model; /* p domain model after recursion */
|
|
Packit |
78deda |
void *rec_coeff_model; /* coeff model after recursion */
|
|
Packit |
78deda |
void *rec_d_coeff_model; /* d coeff model after recursion */
|
|
Packit |
78deda |
tree_t rec_tree_model; /* tree_model after '' */
|
|
Packit |
78deda |
tree_t rec_p_tree_model; /* p_tree_model after '' */
|
|
Packit |
78deda |
unsigned rec_states; /* wfa->states after '' */
|
|
Packit |
78deda |
real_t *rec_pixels; /* c->pixels after '' */
|
|
Packit |
78deda |
state_data_t *rec_state_data; /* state_data struct after '' */
|
|
Packit |
78deda |
real_t costs; /* current approximation costs */
|
|
Packit |
78deda |
unsigned level; /* counter */
|
|
Packit |
78deda |
state_data_t *sd; /* pointer to state_data field */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* Store WFA data from state 'lc_states' to 'wfa->states' - 1 and
|
|
Packit |
78deda |
* current state of probability models.
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
rec_domain_model = c->domain_pool->model;
|
|
Packit |
78deda |
rec_d_domain_model = c->d_domain_pool->model;
|
|
Packit |
78deda |
rec_coeff_model = c->coeff->model;
|
|
Packit |
78deda |
rec_d_coeff_model = c->d_coeff->model;
|
|
Packit |
78deda |
rec_tree_model = c->tree;
|
|
Packit |
78deda |
rec_p_tree_model = c->p_tree;
|
|
Packit |
78deda |
rec_states = wfa->states;
|
|
Packit |
78deda |
rec_pixels = c->pixels;
|
|
Packit |
78deda |
rec_state_data = store_state_data (states, rec_states - 1,
|
|
Packit |
78deda |
c->options.lc_max_level, wfa, c);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* Restore probability models to the state before the recursive subdivision
|
|
Packit |
78deda |
* has been started.
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
wfa->states = states;
|
|
Packit |
78deda |
c->tree = *tree_model;
|
|
Packit |
78deda |
c->p_tree = *p_tree_model;
|
|
Packit |
78deda |
c->domain_pool->model = c->domain_pool->model_duplicate (domain_model);
|
|
Packit |
78deda |
c->d_domain_pool->model = c->d_domain_pool->model_duplicate (d_domain_model);
|
|
Packit |
78deda |
c->coeff->model = c->coeff->model_duplicate (c->coeff, coeff_model);
|
|
Packit |
78deda |
c->d_coeff->model = c->d_coeff->model_duplicate (c->d_coeff,
|
|
Packit |
78deda |
d_coeff_model);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (c->mt->frame_type == I_FRAME)
|
|
Packit |
78deda |
costs = nd_prediction (max_costs, price, band, y_state, range, wfa, c);
|
|
Packit |
78deda |
else
|
|
Packit |
78deda |
costs = mc_prediction (max_costs, price, band, y_state, range, wfa, c);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
c->pixels = rec_pixels;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (costs < MAXCOSTS)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* Free the memory used by the state_data struct
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
for (state = states; state < rec_states; state++)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
sd = &rec_state_data [state - states];
|
|
Packit |
78deda |
for (level = c->options.images_level + 1;
|
|
Packit |
78deda |
level <= c->options.lc_max_level; level++)
|
|
Packit |
78deda |
if (sd->ip_states_state [level] != NULL)
|
|
Packit |
78deda |
Free (sd->ip_states_state [level]);
|
|
Packit |
78deda |
if (sd->images_of_state != NULL)
|
|
Packit |
78deda |
Free (sd->images_of_state);
|
|
Packit |
78deda |
if (sd->inner_products != NULL)
|
|
Packit |
78deda |
Free (sd->inner_products);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
if (states < rec_states)
|
|
Packit |
78deda |
Free (rec_state_data);
|
|
Packit |
78deda |
c->domain_pool->model_free (rec_domain_model);
|
|
Packit |
78deda |
c->d_domain_pool->model_free (rec_d_domain_model);
|
|
Packit |
78deda |
c->coeff->model_free (rec_coeff_model);
|
|
Packit |
78deda |
c->d_coeff->model_free (rec_d_coeff_model);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
costs = (range->tree_bits + range->matrix_bits + range->weights_bits
|
|
Packit |
78deda |
+ range->mv_tree_bits + range->mv_coord_bits
|
|
Packit |
78deda |
+ range->nd_tree_bits + range->nd_weights_bits) * price
|
|
Packit |
78deda |
+ range->err;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
else
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* Restore WFA to state before function was called
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
c->domain_pool->model_free (c->domain_pool->model);
|
|
Packit |
78deda |
c->d_domain_pool->model_free (c->d_domain_pool->model);
|
|
Packit |
78deda |
c->coeff->model_free (c->coeff->model);
|
|
Packit |
78deda |
c->d_coeff->model_free (c->d_coeff->model);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
c->domain_pool->model = rec_domain_model;
|
|
Packit |
78deda |
c->d_domain_pool->model = rec_d_domain_model;
|
|
Packit |
78deda |
c->coeff->model = rec_coeff_model;
|
|
Packit |
78deda |
c->d_coeff->model = rec_d_coeff_model;
|
|
Packit |
78deda |
c->tree = rec_tree_model;
|
|
Packit |
78deda |
c->p_tree = rec_p_tree_model;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
range->prediction = NO;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (wfa->states != states)
|
|
Packit |
78deda |
remove_states (states, wfa);
|
|
Packit |
78deda |
restore_state_data (states, rec_states - 1, c->options.lc_max_level,
|
|
Packit |
78deda |
rec_state_data, wfa, c);
|
|
Packit |
78deda |
costs = MAXCOSTS;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
return costs;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
void
|
|
Packit |
78deda |
clear_norms_table (unsigned level, const wfa_info_t *wi, motion_t *mt)
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* Clear norms arrays.
|
|
Packit |
78deda |
*
|
|
Packit |
78deda |
* No return value.
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
unsigned range_size = wi->half_pixel
|
|
Packit |
78deda |
? square (wi->search_range)
|
|
Packit |
78deda |
: square (2 * wi->search_range);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (level > wi->p_min_level)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
memset (mt->mc_forward_norms [level], 0, range_size * sizeof(real_t));
|
|
Packit |
78deda |
memset (mt->mc_backward_norms [level], 0, range_size * sizeof(real_t));
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
void
|
|
Packit |
78deda |
update_norms_table (unsigned level, const wfa_info_t *wi, motion_t *mt)
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* Norms table of levels larger than the bottom level are computed
|
|
Packit |
78deda |
* by summing up previously calculated displacement costs of lower levels.
|
|
Packit |
78deda |
*
|
|
Packit |
78deda |
* No return value.
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
unsigned range_size = wi->half_pixel
|
|
Packit |
78deda |
? square (wi->search_range)
|
|
Packit |
78deda |
: square (2 * wi->search_range);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (level > wi->p_min_level)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
unsigned index; /* index of motion vector */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (index = 0; index < range_size; index++)
|
|
Packit |
78deda |
mt->mc_forward_norms [level][index]
|
|
Packit |
78deda |
+= mt->mc_forward_norms [level - 1][index];
|
|
Packit |
78deda |
if (mt->frame_type == B_FRAME)
|
|
Packit |
78deda |
for (index = 0; index < range_size; index++)
|
|
Packit |
78deda |
mt->mc_backward_norms [level][index]
|
|
Packit |
78deda |
+= mt->mc_backward_norms [level - 1][index];
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/*****************************************************************************
|
|
Packit |
78deda |
|
|
Packit |
78deda |
private code
|
|
Packit |
78deda |
|
|
Packit |
78deda |
*****************************************************************************/
|
|
Packit |
78deda |
|
|
Packit |
78deda |
static real_t
|
|
Packit |
78deda |
mc_prediction (real_t max_costs, real_t price, unsigned band, int y_state,
|
|
Packit |
78deda |
range_t *range, wfa_t *wfa, coding_t *c)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
real_t costs; /* current approximation costs */
|
|
Packit |
78deda |
range_t prange = *range;
|
|
Packit |
78deda |
unsigned width = width_of_level (range->level);
|
|
Packit |
78deda |
unsigned height = height_of_level (range->level);
|
|
Packit |
78deda |
word_t *mcpe = Calloc (width * height, sizeof (word_t));
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* If we are at the bottom level of the mc tree:
|
|
Packit |
78deda |
* Fill in the norms table
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
if (prange.level == wfa->wfainfo->p_min_level)
|
|
Packit |
78deda |
fill_norms_table (prange.x, prange.y, prange.level, wfa->wfainfo, c->mt);
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* Predict 'range' with motion compensation according to frame type.
|
|
Packit |
78deda |
* MCPE is returned in 'c->mcpe'
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
if (c->mt->frame_type == P_FRAME)
|
|
Packit |
78deda |
find_P_frame_mc (mcpe, price, &prange, wfa->wfainfo, c->mt);
|
|
Packit |
78deda |
else
|
|
Packit |
78deda |
find_B_frame_mc (mcpe, price, &prange, wfa->wfainfo, c->mt);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
costs = (prange.mv_tree_bits + prange.mv_coord_bits) * price;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (costs < max_costs) /* motion vector not too expensive */
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
unsigned last_state; /* last WFA state before recursion */
|
|
Packit |
78deda |
real_t *ipi [MAXSTATES]; /* inner products pointers */
|
|
Packit |
78deda |
unsigned state;
|
|
Packit |
78deda |
real_t mvt, mvc;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
c->pixels = Calloc (width * height, sizeof (real_t));
|
|
Packit |
78deda |
cut_to_bintree (c->pixels, mcpe, width, height, 0, 0, width, height);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* Approximate MCPE recursively.
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
last_state = wfa->states - 1;
|
|
Packit |
78deda |
for (state = 0; state <= last_state; state++)
|
|
Packit |
78deda |
if (need_image (state, wfa))
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
ipi [state] = c->ip_images_state[state];
|
|
Packit |
78deda |
c->ip_images_state[state]
|
|
Packit |
78deda |
= Calloc (size_of_tree (c->products_level), sizeof (real_t));
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
mvc = prange.mv_coord_bits;
|
|
Packit |
78deda |
mvt = prange.mv_tree_bits;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
prange.image = 0;
|
|
Packit |
78deda |
prange.address = 0;
|
|
Packit |
78deda |
prange.tree_bits = 0;
|
|
Packit |
78deda |
prange.matrix_bits = 0;
|
|
Packit |
78deda |
prange.weights_bits = 0;
|
|
Packit |
78deda |
prange.mv_coord_bits = 0;
|
|
Packit |
78deda |
prange.mv_tree_bits = 0;
|
|
Packit |
78deda |
prange.nd_weights_bits = 0;
|
|
Packit |
78deda |
prange.nd_tree_bits = 0;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
compute_ip_images_state (prange.image, prange.address, prange.level,
|
|
Packit |
78deda |
1, 0, wfa, c);
|
|
Packit |
78deda |
costs += subdivide (max_costs - costs, band, y_state, &prange,
|
|
Packit |
78deda |
wfa, c, NO, YES);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (costs < max_costs) /* use motion compensation */
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
unsigned img, adr; /* temp. values */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
img = range->image;
|
|
Packit |
78deda |
adr = range->address;
|
|
Packit |
78deda |
*range = prange;
|
|
Packit |
78deda |
range->image = img;
|
|
Packit |
78deda |
range->address = adr;
|
|
Packit |
78deda |
range->mv_coord_bits = mvc;
|
|
Packit |
78deda |
range->mv_tree_bits = mvt;
|
|
Packit |
78deda |
range->prediction = YES;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (state = last_state + 1; state < wfa->states; state++)
|
|
Packit |
78deda |
if (need_image (state, wfa))
|
|
Packit |
78deda |
memset (c->ip_images_state [state], 0,
|
|
Packit |
78deda |
size_of_tree (c->products_level) * sizeof (real_t));
|
|
Packit |
78deda |
|
|
Packit |
78deda |
costs = (range->tree_bits + range->matrix_bits + range->weights_bits
|
|
Packit |
78deda |
+ range->mv_tree_bits + range->mv_coord_bits
|
|
Packit |
78deda |
+ range->nd_tree_bits + range->nd_weights_bits) * price
|
|
Packit |
78deda |
+ range->err;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
else
|
|
Packit |
78deda |
costs = MAXCOSTS;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (state = 0; state <= last_state; state++)
|
|
Packit |
78deda |
if (need_image (state, wfa))
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
Free (c->ip_images_state[state]);
|
|
Packit |
78deda |
c->ip_images_state[state] = ipi [state];
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
Free (c->pixels);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
else
|
|
Packit |
78deda |
costs = MAXCOSTS;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
Free (mcpe);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
return costs;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
static real_t
|
|
Packit |
78deda |
nd_prediction (real_t max_costs, real_t price, unsigned band, int y_state,
|
|
Packit |
78deda |
range_t *range, wfa_t *wfa, coding_t *c)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
real_t costs; /* current approximation costs */
|
|
Packit |
78deda |
range_t lrange = *range;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* Predict 'range' with DC component approximation
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
real_t x = get_ip_image_state (range->image, range->address,
|
|
Packit |
78deda |
range->level, 0, c);
|
|
Packit |
78deda |
real_t y = get_ip_state_state (0, 0, range->level, c);
|
|
Packit |
78deda |
real_t w = btor (rtob (x / y, c->coeff->dc_rpf), c->coeff->dc_rpf);
|
|
Packit |
78deda |
word_t s [2] = {0, -1};
|
|
Packit |
78deda |
|
|
Packit |
78deda |
lrange.into [0] = 0;
|
|
Packit |
78deda |
lrange.into [1] = NO_EDGE;
|
|
Packit |
78deda |
lrange.weight [0] = w;
|
|
Packit |
78deda |
lrange.mv_coord_bits = 0;
|
|
Packit |
78deda |
lrange.mv_tree_bits = 0;
|
|
Packit |
78deda |
lrange.nd_tree_bits = tree_bits (LEAF, lrange.level, &c->p_tree);
|
|
Packit |
78deda |
lrange.nd_weights_bits = 0;
|
|
Packit |
78deda |
lrange.tree_bits = 0;
|
|
Packit |
78deda |
lrange.matrix_bits = 0;
|
|
Packit |
78deda |
lrange.weights_bits = c->coeff->bits (&w, s, range->level, c->coeff);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
costs = price * (lrange.weights_bits + lrange.nd_tree_bits);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* Recursive aproximation of difference image
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
if (costs < max_costs)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
unsigned state;
|
|
Packit |
78deda |
range_t rrange; /* range: recursive subdivision */
|
|
Packit |
78deda |
unsigned last_state; /* last WFA state before recursion */
|
|
Packit |
78deda |
real_t *ipi [MAXSTATES]; /* inner products pointers */
|
|
Packit |
78deda |
unsigned width = width_of_level (range->level);
|
|
Packit |
78deda |
unsigned height = height_of_level (range->level);
|
|
Packit |
78deda |
real_t *pixels;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* Generate difference image original - approximation
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
unsigned n;
|
|
Packit |
78deda |
real_t *src, *dst; /* pointers to image data */
|
|
Packit |
78deda |
real_t w = - lrange.weight [0] * c->images_of_state [0][0];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
src = c->pixels + range->address * size_of_level (range->level);
|
|
Packit |
78deda |
dst = c->pixels = pixels = Calloc (width * height, sizeof (real_t));
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (n = width * height; n; n--)
|
|
Packit |
78deda |
*dst++ = *src++ + w;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* Approximate difference recursively.
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
rrange = *range;
|
|
Packit |
78deda |
rrange.tree_bits = 0;
|
|
Packit |
78deda |
rrange.matrix_bits = 0;
|
|
Packit |
78deda |
rrange.weights_bits = 0;
|
|
Packit |
78deda |
rrange.mv_coord_bits = 0;
|
|
Packit |
78deda |
rrange.mv_tree_bits = 0;
|
|
Packit |
78deda |
rrange.nd_tree_bits = 0;
|
|
Packit |
78deda |
rrange.nd_weights_bits = 0;
|
|
Packit |
78deda |
rrange.image = 0;
|
|
Packit |
78deda |
rrange.address = 0;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
last_state = wfa->states - 1;
|
|
Packit |
78deda |
for (state = 0; state <= last_state; state++)
|
|
Packit |
78deda |
if (need_image (state, wfa))
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
ipi [state] = c->ip_images_state[state];
|
|
Packit |
78deda |
c->ip_images_state[state]
|
|
Packit |
78deda |
= Calloc (size_of_tree (c->products_level), sizeof (real_t));
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
compute_ip_images_state (rrange.image, rrange.address, rrange.level,
|
|
Packit |
78deda |
1, 0, wfa, c);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
costs += subdivide (max_costs - costs, band, y_state, &rrange, wfa, c,
|
|
Packit |
78deda |
NO, YES);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
Free (pixels);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (costs < max_costs && ischild (rrange.tree)) /* use prediction */
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
unsigned img, adr;
|
|
Packit |
78deda |
unsigned edge;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
img = range->image;
|
|
Packit |
78deda |
adr = range->address;
|
|
Packit |
78deda |
*range = rrange;
|
|
Packit |
78deda |
range->image = img;
|
|
Packit |
78deda |
range->address = adr;
|
|
Packit |
78deda |
range->nd_tree_bits += lrange.nd_tree_bits;
|
|
Packit |
78deda |
range->nd_weights_bits += lrange.weights_bits;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (edge = 0; isedge (lrange.into [edge]); edge++)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
range->into [edge] = lrange.into [edge];
|
|
Packit |
78deda |
range->weight [edge] = lrange.weight [edge];
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
range->into [edge] = NO_EDGE;
|
|
Packit |
78deda |
range->prediction = edge;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (state = last_state + 1; state < wfa->states; state++)
|
|
Packit |
78deda |
if (need_image (state, wfa))
|
|
Packit |
78deda |
memset (c->ip_images_state [state], 0,
|
|
Packit |
78deda |
size_of_tree (c->products_level) * sizeof (real_t));
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
else
|
|
Packit |
78deda |
costs = MAXCOSTS;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (state = 0; state <= last_state; state++)
|
|
Packit |
78deda |
if (need_image (state, wfa))
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
Free (c->ip_images_state [state]);
|
|
Packit |
78deda |
c->ip_images_state [state] = ipi [state];
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
else
|
|
Packit |
78deda |
costs = MAXCOSTS;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
return costs;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
static state_data_t *
|
|
Packit |
78deda |
store_state_data (unsigned from, unsigned to, unsigned max_level,
|
|
Packit |
78deda |
wfa_t *wfa, coding_t *c)
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* Save and remove all states starting from state 'from'.
|
|
Packit |
78deda |
*
|
|
Packit |
78deda |
* Return value:
|
|
Packit |
78deda |
* pointer to array of state_data structs
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
state_data_t *data; /* array of savestates */
|
|
Packit |
78deda |
state_data_t *sd; /* pointer to current savestates */
|
|
Packit |
78deda |
unsigned state, label, level;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (to < from)
|
|
Packit |
78deda |
return NULL; /* nothing to do */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
data = Calloc (to - from + 1, sizeof (state_data_t));
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (state = from; state <= to; state++)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
sd = &data [state - from];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
sd->final_distribution = wfa->final_distribution [state];
|
|
Packit |
78deda |
sd->level_of_state = wfa->level_of_state [state];
|
|
Packit |
78deda |
sd->domain_type = wfa->domain_type [state];
|
|
Packit |
78deda |
sd->images_of_state = c->images_of_state [state];
|
|
Packit |
78deda |
sd->inner_products = c->ip_images_state [state];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
wfa->domain_type [state] = 0;
|
|
Packit |
78deda |
c->images_of_state [state] = NULL;
|
|
Packit |
78deda |
c->ip_images_state [state] = NULL;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (label = 0; label < MAXLABELS; label++)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
sd->tree [label] = wfa->tree [state][label];
|
|
Packit |
78deda |
sd->y_state [label] = wfa->y_state [state][label];
|
|
Packit |
78deda |
sd->y_column [label] = wfa->y_column [state][label];
|
|
Packit |
78deda |
sd->mv_tree [label] = wfa->mv_tree [state][label];
|
|
Packit |
78deda |
sd->x [label] = wfa->x [state][label];
|
|
Packit |
78deda |
sd->y [label] = wfa->y [state][label];
|
|
Packit |
78deda |
sd->prediction [label] = wfa->prediction [state][label];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
memcpy (sd->weight [label], wfa->weight [state][label],
|
|
Packit |
78deda |
sizeof (real_t) * (MAXEDGES + 1));
|
|
Packit |
78deda |
memcpy (sd->int_weight [label], wfa->int_weight [state][label],
|
|
Packit |
78deda |
sizeof (word_t) * (MAXEDGES + 1));
|
|
Packit |
78deda |
memcpy (sd->into [label], wfa->into [state][label],
|
|
Packit |
78deda |
sizeof (word_t) * (MAXEDGES + 1));
|
|
Packit |
78deda |
|
|
Packit |
78deda |
wfa->into [state][label][0] = NO_EDGE;
|
|
Packit |
78deda |
wfa->tree [state][label] = RANGE;
|
|
Packit |
78deda |
wfa->y_state [state][label] = RANGE;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
for (level = c->options.images_level + 1; level <= max_level;
|
|
Packit |
78deda |
level++)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
sd->ip_states_state [level] = c->ip_states_state [state][level];
|
|
Packit |
78deda |
c->ip_states_state [state][level] = NULL;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
return data;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
static void
|
|
Packit |
78deda |
restore_state_data (unsigned from, unsigned to, unsigned max_level,
|
|
Packit |
78deda |
state_data_t *data, wfa_t *wfa, coding_t *c)
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* Restore all state data starting from state 'from'.
|
|
Packit |
78deda |
*
|
|
Packit |
78deda |
* No return value.
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
state_data_t *sd; /* pointer to state_data item */
|
|
Packit |
78deda |
unsigned state, label, level;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (to < from)
|
|
Packit |
78deda |
return; /* nothing to do */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (state = from; state <= to; state++)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
sd = &data [state - from];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
wfa->final_distribution [state] = sd->final_distribution;
|
|
Packit |
78deda |
wfa->level_of_state [state] = sd->level_of_state;
|
|
Packit |
78deda |
wfa->domain_type [state] = sd->domain_type;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (c->images_of_state [state] != NULL)
|
|
Packit |
78deda |
Free (c->images_of_state [state]);
|
|
Packit |
78deda |
c->images_of_state [state] = sd->images_of_state;
|
|
Packit |
78deda |
if (c->ip_images_state [state] != NULL)
|
|
Packit |
78deda |
Free (c->ip_images_state [state]);
|
|
Packit |
78deda |
c->ip_images_state [state] = sd->inner_products;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (label = 0; label < MAXLABELS; label++)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
wfa->tree [state][label] = sd->tree [label];
|
|
Packit |
78deda |
wfa->y_state [state][label] = sd->y_state [label];
|
|
Packit |
78deda |
wfa->y_column [state][label] = sd->y_column [label];
|
|
Packit |
78deda |
wfa->mv_tree [state][label] = sd->mv_tree [label];
|
|
Packit |
78deda |
wfa->x [state][label] = sd->x [label];
|
|
Packit |
78deda |
wfa->y [state][label] = sd->y [label];
|
|
Packit |
78deda |
wfa->prediction [state][label] = sd->prediction [label];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
memcpy (wfa->weight [state][label], sd->weight [label],
|
|
Packit |
78deda |
sizeof(real_t) * (MAXEDGES + 1));
|
|
Packit |
78deda |
memcpy (wfa->int_weight [state][label], sd->int_weight [label],
|
|
Packit |
78deda |
sizeof(word_t) * (MAXEDGES + 1));
|
|
Packit |
78deda |
memcpy (wfa->into [state][label], sd->into [label],
|
|
Packit |
78deda |
sizeof(word_t) * (MAXEDGES + 1));
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
for (level = c->options.images_level + 1; level <= max_level;
|
|
Packit |
78deda |
level++)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
if (c->ip_states_state [state][level] != NULL)
|
|
Packit |
78deda |
Free (c->ip_states_state [state][level]);
|
|
Packit |
78deda |
c->ip_states_state [state][level] = sd->ip_states_state [level];
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
Free (data);
|
|
Packit |
78deda |
wfa->states = to + 1;
|
|
Packit |
78deda |
}
|