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

📄 coder.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  coder.c:		WFA coder toplevel functions * *  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/06/14 20:50:51 $ *  $Author: hafner $ *  $Revision: 5.1 $ *  $State: Exp $ */#define _BSD_SOURCE 1   /* Make sure strdup() is in string.h */#define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */#include "config.h"#include "pnm.h"#include <math.h>#include <ctype.h>#include <string.h>#include "nstring.h"#include "types.h"#include "macros.h"#include "error.h"#include "fiasco.h"#include "cwfa.h"#include "misc.h"#include "control.h"#include "bintree.h"#include "subdivide.h"#include "read.h"#include "write.h"#include "image.h"#include "mwfa.h"#include "list.h"#include "decoder.h"#include "motion.h"#include "wfalib.h"#include "domain-pool.h"#include "coeff.h"#include "coder.h"#include "rpf.h"/*****************************************************************************				global variables  *****************************************************************************/const real_t MAXCOSTS =	1e20;/*****************************************************************************				prototypes  *****************************************************************************/static coding_t *alloc_coder (char const * const *inputname, const c_options_t *options,	     wfa_info_t *wi);static voidfree_coder (coding_t *c);static char *get_input_image_name (char const * const *templptr, unsigned ith_image);static voidvideo_coder (char const * const *image_template, bitfile_t *output,	     wfa_t *wfa, coding_t *c);static void frame_coder (wfa_t *wfa, coding_t *c, bitfile_t *output);static voidprint_statistics (char c, real_t costs, const wfa_t *wfa, const image_t *image,		  const range_t *range);static frame_type_epattern2type (unsigned frame, const char *pattern);/*****************************************************************************				public code  *****************************************************************************/intfiasco_coder (char const * const *inputname, const char *outputname,	      float quality, const fiasco_c_options_t *options)/* *  FIASCO coder. *  Encode image or video frames given by the array of filenames `inputname' *  and write to the outputfile `outputname'. *  If 'inputname' = NULL or *     'inputname [0]' == NULL or *     'inputname [0]' == "-", read standard input. *  If 'outputname' == NULL or "-", write on standard output. *  'quality' defines the approximation quality and is 1 (worst) to 100 (best). * *  Return value: *	1 on success *	0 otherwise */{   try   {      char const * const default_input [] = {"-", NULL};      fiasco_c_options_t *default_options = NULL;      const c_options_t  *cop;      char const * const *template;            /*       *  Check parameters       */      if (!inputname || !inputname [0] || streq (inputname [0], "-"))	 template = default_input;      else	 template = inputname;            if (quality <= 0)      {	 set_error (_("Compression quality has to be positive."));	 return 0;      }      else if (quality >= 100)      {	 warning (_("Quality typically is 1 (worst) to 100 (best).\n"		    "Be prepared for a long running time."));      }      if (options)      {	 cop = cast_c_options ((fiasco_c_options_t *) options);	 if (!cop)	    return 0;      }      else      {	 default_options = fiasco_c_options_new ();	 cop 		 = cast_c_options (default_options);      }   /*    *  Open output stream and initialize WFA    */      {	 bitfile_t *output = open_bitfile (outputname, "FIASCO_DATA",					   WRITE_ACCESS);	 if (!output)	 {	    set_error (_("Can't write outputfile `%s'.\n%s"),		       outputname ? outputname : "<stdout>",		       get_system_error ());	    if (default_options)	       fiasco_c_options_delete (default_options);	    return 0;	 }	 else	 {	    wfa_t    *wfa = alloc_wfa (YES);	    coding_t *c   = alloc_coder (template, cop, wfa->wfainfo);	 	    read_basis (cop->basis_name, wfa);	    append_basis_states (wfa->basis_states, wfa, c);	 	    c->price = 128 * 64 / quality;	 	    video_coder (template, output, wfa, c);	 	    close_bitfile (output);	    free_wfa (wfa);	    free_coder (c);	 	    if (default_options)	       fiasco_c_options_delete (default_options);	 }      }      return 1;   }   catch   {      return 0;   }}/*****************************************************************************				private code  *****************************************************************************/static coding_t *alloc_coder (char const * const *inputname, const c_options_t *options,	     wfa_info_t *wi)/* *  Coder structure constructor. *  Allocate memory for the FIASCO coder structure and *  fill in default values specified by 'options'. * *  Return value: *	pointer to the new coder structure or NULL on error */{   coding_t *c = NULL;      /*    *  Check whether all specified image frames are readable and of same type    */   {      char     *filename;      int   	width, w = 0, height, h = 0;      bool_t	color, c = NO;      unsigned 	n;            for (n = 0; (filename = get_input_image_name (inputname, n)); n++)      {          FILE *file;          xelval maxval;          int format;          if (filename == NULL)              file = stdin;          else              file = pm_openr(filename);          pnm_readpnminit(file, &width, &height, &maxval, &format);          color = (PNM_FORMAT_TYPE(format) == PPM_FORMAT) ? TRUE: FALSE;          pm_close(file);	 if (n)	 {	    if (w != width || h != height || c != color)	    {	       set_error (_("Format of image frame `%s' doesn't match."),			  filename ? filename : "<stdin>");	       return NULL;	    }	 }	 else	 {	    w = width;	    h = height;	    c = color;	 }	 Free (filename);      }      wi->frames = n;      wi->width  = w;      wi->height = h;      wi->color  = c;   }   /*    *  Levels ...    */   {      unsigned lx, ly;            lx = (unsigned) (log2 (wi->width - 1) + 1);      ly = (unsigned) (log2 (wi->height - 1) + 1);            wi->level = max (lx, ly) * 2 - ((ly == lx + 1) ? 1 : 0);   }      c = Calloc (1, sizeof (coding_t));   c->options 	      	   = *options;   c->options.lc_min_level = max (options->lc_min_level, 3);   c->options.lc_max_level = min (options->lc_max_level, wi->level - 1);   c->tiling = alloc_tiling (options->tiling_method,			     options->tiling_exponent, wi->level);   if (wi->frames > 1 && c->tiling->exponent > 0)   {      c->tiling->exponent = 0;      warning (_("Image tiling valid only with still image compression."));   }   if (c->options.lc_max_level >= wi->level - c->tiling->exponent)   {      message ("'max_level' changed from %d to %d due to image tiling level.",	       c->options.lc_max_level, wi->level - c->tiling->exponent - 1);      c->options.lc_max_level = wi->level - c->tiling->exponent - 1;   }      if (c->options.lc_min_level > c->options.lc_max_level)      c->options.lc_min_level = c->options.lc_max_level;      /*    *  p_min_level, p_max_level min and max level for ND/MC prediction    *  [p_min_level, p_max_level] must be a subset of [min_level, max_level] !    */   wi->p_min_level = max (options->p_min_level, c->options.lc_min_level);   wi->p_max_level = min (options->p_max_level, c->options.lc_max_level);   if (wi->p_min_level > wi->p_max_level)      wi->p_min_level = wi->p_max_level;   c->options.images_level = min (c->options.images_level,				  c->options.lc_max_level - 1);      c->products_level  = max (0, ((signed int) c->options.lc_max_level				 - (signed int) c->options.images_level - 1));   c->pixels 	      = Calloc (size_of_level (c->options.lc_max_level),				sizeof (real_t));   c->images_of_state = Calloc (MAXSTATES, sizeof (real_t *));   c->ip_images_state = Calloc (MAXSTATES, sizeof (real_t *));   c->ip_states_state = Calloc (MAXSTATES * MAXLEVEL, sizeof (real_t *));      debug_message ("Imageslevel :%d, Productslevel :%d",		  c->options.images_level, c->products_level);   debug_message ("Memory : (%d + %d + %d * 'states') * 'states' + %d",		  size_of_tree (c->options.images_level) * 4,		  size_of_tree (c->products_level) * 4,		  (c->options.lc_max_level - c->options.images_level),		  size_of_level (c->options.lc_max_level));      /*    *  Domain pools ...    */   c->domain_pool   = NULL;   c->d_domain_pool = NULL;   /*    *  Coefficients model ...    */   c->coeff   = NULL;   c->d_coeff = NULL;   /*    *  Max. number of states and edges    */   wi->max_states   	   = max (min (options->max_states, MAXSTATES), 1);   c->options.max_elements = max (min (options->max_elements, MAXEDGES), 1);   /*    *  Title and comment strings    */   wi->title   = strdup (options->title);   wi->comment = strdup (options->comment);      /*    *  Reduced precision format    */   wi->rpf      = alloc_rpf (options->rpf_mantissa, options->rpf_range);   wi->dc_rpf      = alloc_rpf (options->dc_rpf_mantissa, options->dc_rpf_range);   wi->d_rpf      = alloc_rpf (options->d_rpf_mantissa, options->d_rpf_range);   wi->d_dc_rpf      = alloc_rpf (options->d_dc_rpf_mantissa, options->d_dc_rpf_range);      /*    *  Color image options ...    */   wi->chroma_max_states = max (1, options->chroma_max_states);   /*    *  Set up motion compensation struct.    *  p_min_level, p_max_level are also used for ND prediction    */   wi->search_range   = options->search_range;   wi->fps 	      = options->fps;   wi->half_pixel     = options->half_pixel_prediction;   wi->cross_B_search = options->half_pixel_prediction;   wi->B_as_past_ref  = options->B_as_past_ref;   wi->smoothing      = options->smoothing;      c->mt = alloc_motion (wi);   return c;}static voidfree_coder (coding_t *c)/* *  Coder struct destructor: *  Free memory of 'coder' struct. * *  No return value. * *  Side effects: *	structure 'coder' is discarded. */{   free_tiling (c->tiling);   free_motion (c->mt);      Free (c->pixels);   Free (c->images_of_state);   Free (c->ip_images_state);   Free (c->ip_states_state);   Free (c);}static char *get_input_image_name (char const * const *templptr, unsigned ith_image)/* *  Construct the i-th image-name using templates. *  If the template contains a '[' it must be of the form *  "prefix[start-end{+,-}step]suffix" *  where "{+,-}step" is optional. *  Leading zeros of "start" are significant. * *  Example: *   "image0[12-01-1].pgm" yields image012.pgm, image011.pgm, ..., image001.pgm * *  Return value: *      ptr to name of image 'ith_image' or NULL if ith_image is out of range. */{   while (*templptr)   {      const char *template = *templptr++;      char       *s;      if (!(s = strchr (template, '['))) /* no template, just a filename */      {	 if (ith_image == 0)	    return strdup (template);	 else	    ith_image--;      }      else				/* template parser */      {	 unsigned  n_digits;		/* # of digits in image name no. */	 char 	  *s2;	 char 	  *suffix;		/* characters after template end */	 char  	   prefix [MAXSTRLEN];	/* chars up to the template start */	 unsigned  first;		/* first image number */	 unsigned  last;		/* last image number */	 int  	   image_num;		/* current image number */	 int   	   increment = 1;	 int 	   dummy;	 strcpy (prefix, template);	 prefix [s - template] = '\0';   	 for (s2 = ++s, n_digits = 0; ISDIGIT (*s2); s2++, n_digits++)	    ;	 if (sscanf (s, "%d", &dummy) == 0 || dummy < 0)	    error ("Input name template conversion failure.\n"		   "Check spelling of template.");	 first = (unsigned) dummy;	 	 if (*s2++ != '-')	    error ("Input name template conversion failure.\n"		   "Check spelling of template.");   	 for (s = s2; ISDIGIT (*s2); s2++)	    ;	 if (sscanf (s, "%d", &dummy) == 0 || dummy < 0)	    error ("Input name template conversion failure.\n"		   "Check spelling of template.");	 last = (unsigned) dummy;	 	 if (*s2 == '+' || *s2 == '-') 	 {	    for (s = s2++; ISDIGIT (*s2); s2++)	       ;	    if (sscanf (s, "%d", &increment) == 0)	       error ("Input name template conversion failure.\n"		      "Check spelling of template.");	 } 	 	 if (*s2 != ']')	    error ("Input name template conversion failure.\n"		   "Check spelling of template.");	 suffix = s2 + 1;   	 image_num = first + increment * ith_image;	 if (image_num < 0)	    error ("Input name template conversion failure.\n"		   "Check spelling of template.");	 	 if ((increment >  0 && (unsigned) image_num > last) || 	     (increment <= 0 && (unsigned) image_num < last))	 {	    /* TODO: check this */	    ith_image -= (last - first) / increment + 1;

⌨️ 快捷键说明

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