⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subdivide.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  subdivide.c:	Recursive subdivision of range images * *  Written by:		Ullrich Hafner *		 *  This file is part of FIASCO (獸籸actal 獻籱age 獳籲d 玈籩quence 獵O籨ec) *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> *//* *  $Date: 2000/07/15 17:59:31 $ *  $Author: hafner $ *  $Revision: 5.4 $ *  $State: Exp $ */#include "config.h"#if HAVE_STRING_H#	include <string.h>#else /* not HAVE_STRING_H */#	include <strings.h>#endif /* not HAVE_STRING_H */#include "types.h"#include "macros.h"#include "error.h"#include "image.h"#include "cwfa.h"#include "approx.h"#include "ip.h"#include "bintree.h"#include "control.h"#include "prediction.h"#include "domain-pool.h"#include "mwfa.h"#include "misc.h"#include "subdivide.h"#include "list.h"#include "coeff.h"#include "wfalib.h"/*****************************************************************************				prototypes*****************************************************************************/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);static voidinit_range (range_t *range, const image_t *image, unsigned band,	    const wfa_t *wfa, coding_t *c);/*****************************************************************************				public code  *****************************************************************************/real_t subdivide (real_t max_costs, unsigned band, int y_state, range_t *range,	   wfa_t *wfa, coding_t *c, bool_t prediction, bool_t delta)/* *  Subdivide the current 'range' recursively and decide whether *  a linear combination, a recursive subdivision, or a prediction is *  the best choice of approximation. *  'band' is the current color band, 'y_state' is the corresponding *  state of the Y color component (color image compression only). *  If 'prediction' is TRUE then also test motion compensation or *  nondeterministic approximation. *  If 'delta' is TRUE then current range is already predicted. *   *  Return value: *	costs of the best approximation or MAXCOSTS if costs exceed 'max_costs' * *  Side effects: *	'range'	factors and costs of linear combination are modified *      'wfa'	new transitions and prediction coefficients are added *	'c'	pixels and inner products are updated */{   real_t    subdivide_costs;        /* Costs arising from approx. the current				       range with two childs */   real_t    lincomb_costs;          /* Costs arising from approx. the current				       range with a linear combination */   int	     new_y_state [MAXLABELS];	/* Corresponding state of Y */   real_t    price;			/* Approximation costs multiplier */   bool_t    try_mc;			/* YES: try MC prediction */   bool_t    try_nd;			/* YES: try ND prediction */   unsigned  states;			/* Number of states before the					   recursive subdivision starts */   void     *domain_model;		/* copy of domain pool model */         void     *d_domain_model;		/* copy of delta domain pool model */   void     *lc_domain_model;		/* copy of domain pool model */   void     *lc_d_domain_model;		/* copy of delta domain pool model */   void	    *coeff_model;	        /* copy of coefficients model */   void	    *d_coeff_model;		/* copy of delta coefficients model */   void	    *lc_coeff_model;	        /* copy of coefficients model */   void	    *lc_d_coeff_model;		/* copy of delta coefficients model */   tree_t    tree_model;		/* copy of tree model */   tree_t    p_tree_model;		/* copy of pred. tree model */   range_t   lrange;			/* range of lin. comb. approx. */   range_t   rrange;			/* range of recursive approx. */   range_t   child [MAXLABELS];		/* new childs of the current range */   static unsigned percent = 0;		/* status of progress meter */   if (wfa->wfainfo->level == range->level)      percent = 0;      range->into [0] = NO_EDGE;		/* default approximation: empty */   range->tree     = RANGE;   if (range->level < 3)		/* Don't process small ranges */      return MAXCOSTS;	   /*    *  If image permutation (tiling) is performed and the tiling level    *  is reached then get coordinates of the new block.    */   if (c->tiling->exponent       && range->level == wfa->wfainfo->level - c->tiling->exponent)   {      unsigned width, height;		/* size of range (dummies)*/            if (c->tiling->vorder [range->global_address] < 0)	 return 0;			/* nothing to do */      else	 locate_subimage (wfa->wfainfo->level, range->level,			  c->tiling->vorder [range->global_address],			  &range->x, &range->y, &width, &height);   }   if (range->x >= c->mt->original->width ||       range->y >= c->mt->original->height)      return 0;				/* range is not visible */   /*    *  Check whether prediction is allowed or not    *  mc == motion compensation, nd == nondeterminism    */   try_mc = (prediction && c->mt->frame_type != I_FRAME				     && range->level >= wfa->wfainfo->p_min_level	     && range->level <= wfa->wfainfo->p_max_level	     && (range->x + width_of_level (range->level)		 <= c->mt->original->width)	     && (range->y + height_of_level (range->level)		 <= c->mt->original->height));   try_nd = (prediction && c->mt->frame_type == I_FRAME	     && range->level >= wfa->wfainfo->p_min_level	     && range->level <= wfa->wfainfo->p_max_level);   if (try_mc)      clear_norms_table (range->level, wfa->wfainfo, c->mt);      /*    *  Check if current range must be initialized. I.e. range pixels must    *  be copied from entire image to bintree pixel buffer. Moreover,    *  all inner products tables must be initialized.    */   if (range->level == c->options.lc_max_level)	      init_range (range, c->mt->original, band, wfa, c);      price = c->price;   if (band != Y)			      price *= c->options.chroma_decrease; /* less quality for chroma bands */   /*    *  Compute childs of corresponding state in Y band    */   if (band != Y)			/* Cb and Cr bands only */   {      unsigned label;      for (label = 0; label < MAXLABELS; label++)	 if (ischild (y_state))	    new_y_state [label] = wfa->tree [y_state][label];	 else	    new_y_state [label] = RANGE;   }   else      new_y_state [0] = new_y_state [1] = RANGE;      /*    *  Store contents of all models that may get modified during recursion    */   domain_model   = c->domain_pool->model_duplicate (c->domain_pool->model);   d_domain_model = c->d_domain_pool->model_duplicate (c->d_domain_pool->model);   coeff_model    = c->coeff->model_duplicate (c->coeff, c->coeff->model);   d_coeff_model  = c->d_coeff->model_duplicate (c->d_coeff, c->d_coeff->model);   tree_model     = c->tree;   p_tree_model   = c->p_tree;   states         = wfa->states;	      /*    *  First alternative of range approximation:    *  Compute costs of linear combination.    */   if (range->level <= c->options.lc_max_level) /* range is small enough */   {      lrange                 = *range;      lrange.tree            = RANGE;      lrange.tree_bits       = tree_bits (LEAF, lrange.level, &c->tree);      lrange.matrix_bits     = 0;      lrange.weights_bits    = 0;      lrange.mv_tree_bits    = try_mc ? 1 : 0; /* mc allowed but not used */      lrange.mv_coord_bits   = 0;      lrange.nd_tree_bits    = 0;	      lrange.nd_weights_bits = 0;	      lrange.prediction	     = NO;            lincomb_costs	 = approximate_range (max_costs, price, c->options.max_elements,			      y_state, &lrange,			      (delta ? c->d_domain_pool : c->domain_pool),			      (delta ? c->d_coeff : c->coeff), wfa, c);   }   else      lincomb_costs = MAXCOSTS;		   /*    *  Store contents of models that have been modified    *  by approximate_range () above ...    */   lc_domain_model   = c->domain_pool->model;   lc_d_domain_model = c->d_domain_pool->model;   lc_coeff_model    = c->coeff->model;   lc_d_coeff_model  = c->d_coeff->model;   /*    *  ... and restore them with values before lc    */   c->domain_pool->model   = c->domain_pool->model_duplicate (domain_model);   c->d_domain_pool->model = c->d_domain_pool->model_duplicate (d_domain_model);   c->coeff->model         = c->coeff->model_duplicate (c->coeff, coeff_model);   c->d_coeff->model       = c->d_coeff->model_duplicate (c->d_coeff,							  d_coeff_model);      /*    *  Second alternative of range approximation:    *  Compute costs of recursive subdivision.    */   if (range->level > c->options.lc_min_level) /* range is large enough */   {      unsigned label;            memset (&child [0], 0, 2 * sizeof (range_t)); /* initialize childs */      /*       *  Initialize a new range for recursive approximation       */      rrange                 = *range;      rrange.tree_bits       = tree_bits (CHILD, rrange.level, &c->tree);      rrange.matrix_bits     = 0;      rrange.weights_bits    = 0;      rrange.err             = 0;      rrange.mv_tree_bits    = try_mc ? 1 : 0;	/* mc allowed but not used */      rrange.mv_coord_bits   = 0;      rrange.nd_tree_bits    = try_nd ?			       tree_bits (CHILD, lrange.level, &c->p_tree): 0;      rrange.nd_weights_bits = 0;	      rrange.prediction	     = NO;      /*       *  Initialize the cost function and subdivide the current range.       *  Every child is approximated by a recursive call of subdivide()       */      subdivide_costs = (rrange.tree_bits + rrange.weights_bits			 + rrange.matrix_bits + rrange.mv_tree_bits			 + rrange.mv_coord_bits + rrange.nd_tree_bits			 + rrange.nd_weights_bits) * price;            for (label = 0; label < MAXLABELS; label++)       {	 real_t remaining_costs;	/* upper limit for next recursion */	 	 child[label].image          = rrange.image * MAXLABELS + label + 1;	 child[label].address        = rrange.address * MAXLABELS + label;	 child[label].global_address = rrange.global_address * MAXLABELS				       + label;	 child[label].level          = rrange.level - 1;	 child[label].x	= rrange.level & 1			  ? rrange.x			  : (rrange.x			     + label * width_of_level (rrange.level - 1));	 child[label].y = rrange.level & 1			  ? (rrange.y			     + label * height_of_level (rrange.level - 1))			  : rrange.y;	 	 /* 	  *  If neccessary compute the inner products of the new states	  *  (generated during the recursive approximation of child [0])	  */	 if (label && rrange.level <= c->options.lc_max_level)	    compute_ip_images_state (child[label].image, child[label].address,				     child[label].level, 1, states, wfa, c);	 /*	  *  Call subdivide() for both childs. 	  *  Abort the recursion if 'subdivide_costs' exceed 'lincomb_costs'	  *  or 'max_costs'.	  */	 remaining_costs = min (lincomb_costs, max_costs) - subdivide_costs;	 if (remaining_costs > 0)	/* still a way for improvement */	 {	    subdivide_costs += subdivide (remaining_costs, band,					  new_y_state [label], &child [label],					  wfa, c, prediction, delta);	 }	 else if (try_mc && child[label].level >= wfa->wfainfo->p_min_level)	 {	    fill_norms_table (child[label].x, child[label].y,			      child[label].level, wfa->wfainfo, c->mt);	 }	 	 if (try_mc)	    update_norms_table (rrange.level, wfa->wfainfo, c->mt);	 	 /*	  *  Update of progress meter	  */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -