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

📄 decoder.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  decode.c:		Decoding of an image represented by a WFA * *  Written by:		Ullrich Hafner *			Michael Unger *		 *  This file is part of FIASCO (獸籸actal 獻籱age 獳籲d 玈籩quence 獵O籨ec) *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> */ /* *  $Date: 2000/10/22 10:44:48 $ *  $Author: hafner $ *  $Revision: 5.3 $ *  $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 "wfa.h"#include "image.h"#include "misc.h"#include "motion.h"#include "read.h"#include "wfalib.h"#include "decoder.h"/*****************************************************************************				prototypes  *****************************************************************************/static voidcompute_state_images (unsigned frame_level, word_t **simg,		      const u_word_t *offset, const wfa_t *wfa);static voidfree_state_images (unsigned max_level, bool_t color, word_t **state_image,		   u_word_t *offset, const unsigned *root_state,		   unsigned range_state, format_e format, const wfa_t *wfa);static voidalloc_state_images (word_t ***images, u_word_t **offsets, const image_t *frame,		    const unsigned *root_state, unsigned range_state,		    unsigned max_level, format_e format, const wfa_t *wfa);static voidcompute_actual_size (unsigned luminance_root,		     unsigned *width, unsigned *height, const wfa_t *wfa);static voidenlarge_image (int enlarge_factor, format_e format, unsigned y_root,	       wfa_t *wfa);static word_t *duplicate_state_image (const word_t *domain, unsigned offset, unsigned level);/*****************************************************************************				public code  *****************************************************************************/video_t *alloc_video (bool_t store_wfa)/* *  Video struct constructor: *  Initialize video structure and allocate memory for current, past *  and future WFA if flag 'store_wfa' is TRUE. * *  Return value: *	pointer to the new video structure */{   video_t *video = Calloc (1, sizeof (video_t));      video->future_display = -1;   video->display        = 0;   video->future = video->sfuture = video->past		 = video->frame   = video->sframe = NULL;   if (store_wfa)   {      video->wfa        = alloc_wfa (NO);      video->wfa_past   = alloc_wfa (NO);      video->wfa_future = alloc_wfa (NO);   }   else      video->wfa = video->wfa_past = video->wfa_future = NULL;   return video;}voidfree_video (video_t *video)/* *  Video struct destructor: *  Free memory of given 'video' struct. * *  No return value. * *  Side effects: *	'video' struct is discarded. */{   if (video->past)      free_image (video->past);   if (video->future)      free_image (video->future);   if (video->sfuture)      free_image (video->sfuture);   if (video->frame)      free_image (video->frame);   if (video->sframe)      free_image (video->sframe);   if (video->wfa)      free_wfa (video->wfa);   if (video->wfa_past)      free_wfa (video->wfa_past);   if (video->wfa_future)      free_wfa (video->wfa_future);   Free (video);}image_t *get_next_frame (bool_t store_wfa, int enlarge_factor,		int smoothing, const char *reference_frame,		format_e format, video_t *video, dectimer_t *timer,		wfa_t *orig_wfa, bitfile_t *input)/* *  Get next frame of the WFA 'video' from stream 'input'. *  'orig_wfa' is the constant part of the WFA used by all frames. *  Depending on values of 'enlarge_factor' and 'smoothing' enlarge and *  smooth image, respectively.  *  If 'store_wfa' is TRUE, then store WFA structure of reference frames *  (used by analysis tool xwfa). *  If 'reference_frame' is not NULL, then load image 'reference_frame' *  from disk. *  'format' gives the color format to be used (either 4:2:0 or 4:4:4). *  If 'timer' is not NULL, then accumulate running time statistics.  * *  Return value: *	pointer to decoded frame * *  Side effects: *	'video' and 'timer' struct are modified. */{   image_t *frame 			  = NULL; /* current frame */   image_t *sframe 			  = NULL; /* current smoothed frame */   bool_t   current_frame_is_future_frame = NO;   if (video->future_display == video->display)	    {      /*       *  Future frame is already computed since it has been used       *  as reference frame. So just return the stored frame.       */      if (video->frame) /* discard current frame */	 free_image (video->frame);      video->frame  = video->future;      video->future = NULL;      if (video->sframe) /* discard current (smoothed) frame */	 free_image (video->sframe);      video->sframe  = video->sfuture;      video->sfuture = NULL;      if (store_wfa)	 copy_wfa (video->wfa, video->wfa_future);      video->display++;      if (!store_wfa)	 video->wfa = NULL;   }   else   {      do				/* compute next frame(s) */      {	 unsigned      frame_number;	/* current frame number */	 clock_t       ptimer;	 unsigned int  stop_timer [3];	 wfa_t	      *tmp_wfa = NULL;	 	 if (!store_wfa)	    video->wfa = orig_wfa;	 else	 {	    tmp_wfa = alloc_wfa (NO);	    copy_wfa (tmp_wfa, video->wfa);	    copy_wfa (video->wfa, orig_wfa);	 }   	 /*	  *  First step: read WFA from disk	  */	 prg_timer (&ptimer, START);	 frame_number = read_next_wfa (video->wfa, input);	 stop_timer [0] = prg_timer (&ptimer, STOP);	 if (timer)	 {	    timer->input [video->wfa->frame_type] += stop_timer [0];	    timer->frames [video->wfa->frame_type]++;	 }      	 /*	  *  Read reference frame from disk if required	  *  (i.e., 1st frame is of type B or P)	  */	 if (video->display == 0 && video->wfa->frame_type != I_FRAME)	 {	    if (!reference_frame)	       error ("First frame is %c-frame but no "		      "reference frame is given.",		      video->wfa->frame_type == B_FRAME ? 'B' : 'P');	    video->frame  = read_image (reference_frame);	    video->sframe = NULL;	 }   	 /*	  *  Depending on current frame type update past and future frames	  */	 if (video->wfa->frame_type == I_FRAME)	 {	    if (video->past)		/* discard past frame */	       free_image (video->past);	    video->past = NULL;	    if (video->future)		/* discard future frame */	       free_image (video->future);	    video->future = NULL;	    if (video->sfuture)		/* discard (smoothed) future frame */	       free_image (video->sfuture);	    video->sfuture = NULL;	    if (video->frame)		/* discard current frame */	       free_image (video->frame);	    video->frame = NULL;	    if (video->sframe)		/* discard current (smoothed) frame */	       free_image (video->sframe);	    video->sframe = NULL;	 }	 else if (video->wfa->frame_type == P_FRAME)	 {	    if (video->past)		/* discard past frame */	       free_image (video->past);	    video->past = video->frame;	/* past <- current frame */	    video->frame = NULL;	    if (video->sframe)		/* discard current (smoothed) frame */	       free_image (video->sframe);	    video->sframe = NULL;	    if (store_wfa)	       copy_wfa (video->wfa_past, tmp_wfa);	    if (video->future)		/* discard future frame */	       free_image (video->future);	    video->future = NULL;	    if (video->sfuture)		/* discard (smoothed) future frame */	       free_image (video->sfuture);	    video->sfuture = NULL;	 }	 else				/* B_FRAME */	 {	    if (current_frame_is_future_frame)	    {	       if (video->future)	/* discard future frame */		  free_image (video->future);	       video->future = frame;	/* future <- current frame */	       if (video->sfuture)	/* discard (smoothed) future frame */		  free_image (video->sfuture);	       video->sfuture = sframe;	/* future <- current (smoothed) */	       if (store_wfa)		  copy_wfa (video->wfa_future, tmp_wfa);	       if (video->frame)	/* discard current frame */		  free_image (video->frame);	       video->frame = NULL;	       if (video->sframe)	/* discard current (smoothed) frame */		  free_image (video->sframe);	       video->sframe = NULL;	       frame  = NULL;	       sframe = NULL;	    }	    else	    {	       if (video->wfa->wfainfo->B_as_past_ref == YES)	       {		  if (video->past)	/* discard past frame */		     free_image (video->past);		  video->past  = video->frame; /* past <- current frame */		  video->frame = NULL;		  if (video->sframe)	/* discard current (smoothed) frame */		     free_image (video->sframe);		  video->sframe = NULL;		  if (store_wfa)		     copy_wfa (video->wfa_past, tmp_wfa);	       }	       else	       {		  if (video->frame)	/* discard current */		     free_image (video->frame);		  video->frame = NULL;		  if (video->sframe)	/* discard current (smoothed) frame */		     free_image (video->sframe);		  video->sframe = NULL;	       }	    }	 }	 if (tmp_wfa)	    free_wfa (tmp_wfa);	 	 current_frame_is_future_frame = NO;	 /*	  *  Second step: decode image	  *  Optionally enlarge image if specified by option 'enlarge_factor'.	  */	 {	    unsigned orig_width, orig_height;	    stop_timer [0] = stop_timer [1] = stop_timer [2] = 0;	 	    enlarge_image (enlarge_factor, format,			   (video->wfa->wfainfo->color			    && format == FORMAT_4_2_0)			   ? video->wfa->tree [video->wfa->tree [video->wfa->root_state][0]][0] : -1, video->wfa);	    if (enlarge_factor > 0)	    {	       orig_width  = video->wfa->wfainfo->width  << enlarge_factor;	       orig_height = video->wfa->wfainfo->height << enlarge_factor; 	    }	    else	    { 	       orig_width  = video->wfa->wfainfo->width  >> - enlarge_factor;	       orig_height = video->wfa->wfainfo->height >> - enlarge_factor;	       if (orig_width & 1)		  orig_width++;	       if (orig_height & 1)		  orig_height++;	    }	 	    frame = decode_image (orig_width, orig_height, format,				  timer != NULL ? stop_timer : NULL,				  video->wfa);	    if (timer)	    {	       timer->preprocessing [video->wfa->frame_type] += stop_timer [0];	       timer->decoder [video->wfa->frame_type]       += stop_timer [1];	       timer->cleanup [video->wfa->frame_type]       += stop_timer [2];	    }	 }	 /*	  *  Third step: restore motion compensation	  */	 if (video->wfa->frame_type != I_FRAME)	 {	    prg_timer (&ptimer, START);	    restore_mc (enlarge_factor, frame, video->past, video->future,			video->wfa);	    stop_timer [0] = prg_timer (&ptimer, STOP);	    if (timer)	       timer->motion [video->wfa->frame_type] += stop_timer [0];	 }	 /*	  *  Fourth step: smooth image along partitioning borders	  */	 prg_timer (&ptimer, START);	 if (smoothing < 0)	/* smoothing not changed by user */	    smoothing = video->wfa->wfainfo->smoothing;	 if (smoothing > 0 && smoothing <= 100)	 {	    sframe = clone_image (frame);	    smooth_image (smoothing, video->wfa, sframe);	 }	 else	    sframe = NULL;	 	 stop_timer [0] = prg_timer (&ptimer, STOP);	 if (timer)	    timer->smooth [video->wfa->frame_type] += stop_timer [0];	 if (frame_number == video->display)	 {	    video->display++;	    video->frame  = frame;	    video->sframe = sframe;	    frame         = NULL;	    sframe        = NULL;	 }	 else if (frame_number > video->display)	 {	    video->future_display 	  = frame_number;	    current_frame_is_future_frame = YES;	 }      	 if (!store_wfa)	    remove_states (video->wfa->basis_states, video->wfa);      } while (!video->frame);      if (!store_wfa)	 video->wfa = NULL;   }      return video->sframe ? video->sframe : video->frame;}image_t *decode_image (unsigned orig_width, unsigned orig_height, format_e format,	      unsigned *dec_timer, const wfa_t *wfa)/* *  Compute image which is represented by the given 'wfa'. *  'orig_width'x'orig_height' gives the resolution of the image at *  coding time. Use 4:2:0 subsampling or 4:4:4 'format' for color images. *  If 'dec_timer' is given, accumulate running time statistics.  *   *  Return value: *	pointer to decoded image * *  Side effects: *	'*dectimer' is changed if 'dectimer' != NULL. */{   unsigned   root_state [3];		/* root of bintree for each band */   unsigned   width, height;		/* computed image size */   image_t   *frame;			/* regenerated frame */   word_t   **images;			/* pointer to array of pointers					   to state images */   u_word_t  *offsets;			/* pointer to array of state image					   offsets */   unsigned   max_level;		/* max. level of state with approx. */   unsigned   state;   clock_t    ptimer;   prg_timer (&ptimer, START);   /*    *  Compute root of bintree for each color band    */   if (wfa->wfainfo->color)   {      root_state [Y]  = wfa->tree [wfa->tree [wfa->root_state][0]][0];      root_state [Cb] = wfa->tree [wfa->tree [wfa->root_state][0]][1];      root_state [Cr] = wfa->tree [wfa->tree [wfa->root_state][1]][0];   }   else      root_state [GRAY] = wfa->root_state;   /*    *  Compute maximum level of a linear combination    */   for (max_level = 0, state = wfa->basis_states; state < wfa->states; state++)      if (isedge (wfa->into [state][0][0]) || isedge (wfa->into [state][1][0]))	 max_level = max (max_level, wfa->level_of_state [state]);      /*    *  Allocate frame buffer for decoded image    */   compute_actual_size (format == FORMAT_4_2_0 ? root_state [Y] : MAXSTATES,			&width, &height, wfa);   width  = max (width, orig_width);   height = max (height, orig_height);   frame = alloc_image (width, height, wfa->wfainfo->color, format);      /*    *  Allocate buffers for intermediate state images    */   if (wfa->wfainfo->color)   {      wfa->level_of_state [wfa->root_state]               = 128;      wfa->level_of_state [wfa->tree[wfa->root_state][0]] = 128;      wfa->level_of_state [wfa->tree[wfa->root_state][1]] = 128;   }   alloc_state_images (&images, &offsets, frame, root_state, 0, max_level, 		       format, wfa);   if (dec_timer)      dec_timer [0] += prg_timer (&ptimer, STOP);   /*    *  Decode all state images, forming the complete image.    */   prg_timer (&ptimer, START);   compute_state_images (max_level, images, offsets, wfa);   if (dec_timer)      dec_timer [1] += prg_timer (&ptimer, STOP);   /*    *  Cleanup buffers used for intermediate state images    */   prg_timer (&ptimer, START);   free_state_images (max_level, frame->color, images, offsets, root_state, 0,		      format, wfa);      /*    *  Crop decoded image if the image size differs.    */   if (orig_width != width || orig_height != height)   {      frame->height = orig_height;	      frame->width  = orig_width;	      if (orig_width != width)		      {

⌨️ 快捷键说明

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