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

📄 image.c

📁 linux下将各类格式图片转换工具
💻 C
字号:
/* *  image.c:		Input and output of PNM 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/06/15 17:21:30 $ *  $Author: hafner $ *  $Revision: 5.2 $ *  $State: Exp $ */#include "pnm.h"#include <string.h>#include "types.h"#include "macros.h"#include "error.h"#include "fiasco.h"#include "misc.h"#include "image.h"/*****************************************************************************				prototypes  *****************************************************************************/static voidinit_chroma_tables (void);/*****************************************************************************				local variables  *****************************************************************************/static int *Cr_r_tab = NULL;static int *Cr_g_tab = NULL;static int *Cb_g_tab = NULL;static int *Cb_b_tab = NULL;/*****************************************************************************				public code  *****************************************************************************/fiasco_image_t *fiasco_image_new (const char *filename)/* *  FIASCO image constructor. *  Allocate memory for the FIASCO image structure and *  load the specified image `filename'. The image has to be in *  raw pgm or ppm format. * *  Return value: *	pointer to the new image structure *	or NULL in case of an error */{   try   {      fiasco_image_t *image = Calloc (1, sizeof (fiasco_image_t));      image->private 	= read_image (filename);      image->delete  	= fiasco_image_delete;      image->get_width  = fiasco_image_get_width;      image->get_height = fiasco_image_get_height;      image->is_color  	= fiasco_image_is_color;      return image;   }   catch   {      return NULL;   }}voidfiasco_image_delete (fiasco_image_t *image)/* *  FIASCO image destructor. *  Free memory of FIASCO image struct. * *  No return value. * *  Side effects: *	structure 'image' is discarded. */{   image_t *this = cast_image (image);   if (!this)      return;   try   {      free_image (this);   }   catch   {      return;   }}unsignedfiasco_image_get_width (fiasco_image_t *image){   image_t *this = cast_image (image);   if (!this)      return 0;   else      return this->width;}unsignedfiasco_image_get_height (fiasco_image_t *image){   image_t *this = cast_image (image);   if (!this)      return 0;   else      return this->width;}intfiasco_image_is_color (fiasco_image_t *image){   image_t *this = cast_image (image);   if (!this)      return 0;   else      return this->color;}image_t *cast_image (fiasco_image_t *image)/* *  Cast pointer `image' to type image_t. *  Check whether `image' is a valid object of type image_t. * *  Return value: *	pointer to dfiasco_t struct on success *      NULL otherwise */{   image_t *this = (image_t *) image->private;   if (this)   {      if (!streq (this->id, "IFIASCO"))      {	 set_error (_("Parameter `image' doesn't match required type."));	 return NULL;      }   }   else   {      set_error (_("Parameter `%s' not defined (NULL)."), "image");   }   return this;}image_t *alloc_image (unsigned width, unsigned height, bool_t color, format_e format)/* *  Image constructor: *  Allocate memory for the image_t structure. *  Image size is given by 'width' and 'height'. *  If 'color' == YES then allocate memory for three color bands (Y, Cb, Cr). *  otherwise just allocate memory for a grayscale image. *  'format' specifies whether image pixels of color images *  are stored in 4:4:4 or 4:2:0 format. * *  Return value: *	pointer to the new image structure. */{   image_t *image;   color_e band;   if ((width & 1) || (height & 1))      error ("Width and height of images must be even numbers.");   if (!color)      format = FORMAT_4_4_4;   image         	  = Calloc (1, sizeof (image_t));   image->width  	  = width;   image->height 	  = height;   image->color  	  = color;   image->format 	  = format;   image->reference_count = 1;      strcpy (image->id, "IFIASCO");   for (band = first_band (color); band <= last_band (color); band++)      if (format == FORMAT_4_2_0 && band != Y)	 image->pixels [band] = Calloc ((width * height) >> 2,					sizeof (word_t));      else	 image->pixels [band] = Calloc (width * height, sizeof (word_t));      return image;}image_t *clone_image (image_t *image)/* *  Copy constructor: *  Construct new image by copying the given `image'. * *  Return value: *	pointer to the new image structure. */{   image_t *new = alloc_image (image->width, image->height, image->color,			       image->format);   color_e band;      for (band = first_band (new->color); band <= last_band (new->color); band++)      if (new->format == FORMAT_4_2_0 && band != Y)      {	 memcpy (new->pixels [band], image->pixels [band],		 ((new->width * new->height) >> 2) * sizeof (word_t));      }      else      {	 memcpy (new->pixels [band], image->pixels [band],		 new->width * new->height * sizeof (word_t));      }   return new;}voidfree_image (image_t *image)/* *  Image destructor: *  Free memory of 'image' struct and pixel data. * *  No return value. * *  Side effects: *	structure 'image' is discarded. */{   if (image != NULL)   {      if (--image->reference_count)	 return;			/* image is still referenced */      else      {	 color_e band;	 for (band  = first_band (image->color);	      band <= last_band (image->color); band++)	    if (image->pixels [band])	       Free (image->pixels [band]);	 Free (image);      }   }   else      warning ("Can't free image <NULL>.");}static void read_image_data(image_t * const image, FILE *input, const bool_t color,                const int width, const int height, const xelval maxval,                const int format) {   int row;   int i;      /* Cursor into image->pixels arrays */   xel * xelrow;   /* The following are just the normal rgb -> YCbCr conversion matrix,      except normalization to maxval 4095 (12 bit color) is built in      */   const double coeff_lu_r = +0.2989 / maxval * 4095;   const double coeff_lu_g = +0.5866 / maxval * 4095;   const double coeff_lu_b = +0.1145 / maxval * 4095;   const double coeff_cb_r = -0.1687 / maxval * 4095;   const double coeff_cb_g = -0.3312 / maxval * 4095;   const double coeff_cb_b = +0.5000 / maxval * 4095;   const double coeff_cr_r = +0.5000 / maxval * 4095;   const double coeff_cr_g = -0.4183 / maxval * 4095;   const double coeff_cr_b = -0.0816 / maxval * 4095;   xelrow = pnm_allocrow(width);   i = 0;    for (row = 0; row < height; row++) {       int col;       pnm_readpnmrow(input, xelrow, width, maxval, format);       for (col = 0; col < width; col++) {           if (color) {               image->pixels[Y][i] =                    coeff_lu_r * PPM_GETR(xelrow[col])                    + coeff_lu_g * PPM_GETG(xelrow[col])                   + coeff_lu_b * PPM_GETB(xelrow[col]) - 2048;               image->pixels[Cb][i] =                    coeff_cb_r * PPM_GETR(xelrow[col])                    + coeff_cb_g * PPM_GETG(xelrow[col])                   + coeff_cb_b * PPM_GETB(xelrow[col]);               image->pixels[Cr][i] =                    coeff_cr_r * PPM_GETR(xelrow[col])                    + coeff_cr_g * PPM_GETG(xelrow[col])                   + coeff_cr_b * PPM_GETB(xelrow[col]);               i++;           } else                image->pixels[GRAY][i++] =                   PNM_GET1(xelrow[col]) * 4095 / maxval - 2048;       }   }   free(xelrow);}image_t *read_image (const char *image_name)/* *  Read image 'image_name'. *   *  Return value: *	pointer to the image structure. */{   FILE	    *input;			/* input stream */   image_t  *image;			/* pointer to new image structure */   int  width, height;		/* image size */   xelval   maxval;         /* Maxval of image */   int format;              /* Image's format code */   bool_t    color;			/* color image ? (YES/NO) */   if (image_name == NULL)       input = stdin;   else       input = pm_openr((char*)image_name);   pnm_readpnminit(input, &width, &height, &maxval, &format);   if (PNM_FORMAT_TYPE(format) == PPM_FORMAT)       color = YES;   else       color = NO;   if (width < 32)       pm_error("Image must have a width of at least 32 pixels.");   if (height < 32)       pm_error("Image must have a height of at least 32 pixels.");   image = alloc_image (width, height, color, FORMAT_4_4_4);   read_image_data(image, input, color, width, height, maxval, format);   pm_close(input);      return image;}   voidwrite_image (const char *image_name, const image_t *image)/* *  Write given 'image' data to the file 'image_name'. *   *  No return value. */{   FILE	*output;			/* output stream */   int format;   int row;   int i;     /* Cursor into image->pixel arrays */   xel * xelrow;   unsigned *gray_clip;			/* clipping table */   assert (image && image_name);      if (image->format == FORMAT_4_2_0)   {      warning ("Writing of images in 4:2:0 format not supported.");      return;   }      if (image_name == NULL)       output = stdout;   else if (strcmp(image_name, "-") == 0)       output = stdout;   else       output = pm_openw((char*)image_name);   gray_clip  = init_clipping ();	/* mapping of int -> unsigned */   if (!gray_clip)      error (fiasco_get_error_message ());   init_chroma_tables ();   format = image->color ? PPM_TYPE : PGM_TYPE;      pnm_writepnminit(output, image->width, image->height, 255, format, 0);   xelrow = pnm_allocrow(image->width);   i = 0;   for (row = 0; row < image->height; row++) {       int col;       for (col = 0; col < image->width; col++) {           if (image->color) {               word_t yval, cbval, crval;               yval  = image->pixels[Y][i]  / 16 + 128;               cbval = image->pixels[Cb][i] / 16;               crval = image->pixels[Cr][i] / 16;               PPM_ASSIGN(xelrow[col],                           gray_clip[yval + Cr_r_tab[crval]],                          gray_clip[yval + Cr_g_tab[crval] + Cb_g_tab [cbval]],                          gray_clip[yval + Cb_b_tab[cbval]]);           } else               /* The 16 below should be 4095/255 = 16.0588 */               PNM_ASSIGN1(xelrow[col],                            gray_clip[image->pixels[GRAY][i]/16+128]);           i++;       }       pnm_writepnmrow(output, xelrow,                        image->width, 255, format, 0);   }   pnm_freerow(xelrow);   pm_close(output);}bool_tsame_image_type (const image_t *img1, const image_t *img2)/* *  Check whether the given images 'img1' and `img2' are of the same type. * *  Return value: *	YES	if images 'img1' and `img2' are of the same type *	NO	otherwise. */{   assert (img1 && img2);      return ((img1->width == img2->width)	   && (img1->height == img2->height)	   && (img1->color == img2->color)	   && (img1->format == img2->format));}/*****************************************************************************				private code  *****************************************************************************/static voidinit_chroma_tables (void)/* *  Chroma tables are used to perform fast YCbCr->RGB color space conversion. */{   int crval, cbval, i;   if (Cr_r_tab != NULL || Cr_g_tab != NULL ||       Cb_g_tab != NULL || Cb_b_tab != NULL)      return;   Cr_r_tab = Calloc (768, sizeof (int));   Cr_g_tab = Calloc (768, sizeof (int));   Cb_g_tab = Calloc (768, sizeof (int));   Cb_b_tab = Calloc (768, sizeof (int));   for (i = 256; i < 512; i++)   {      cbval = crval  = i - 128 - 256;      Cr_r_tab[i] =  1.4022 * crval + 0.5;      Cr_g_tab[i] = -0.7145 * crval + 0.5;      Cb_g_tab[i] = -0.3456 * cbval + 0.5;       Cb_b_tab[i] =  1.7710 * cbval + 0.5;   }   for (i = 0; i < 256; i++)   {      Cr_r_tab[i] = Cr_r_tab[256];      Cr_g_tab[i] = Cr_g_tab[256];      Cb_g_tab[i] = Cb_g_tab[256];       Cb_b_tab[i] = Cb_b_tab[256];   }   for (i = 512; i < 768; i++)   {      Cr_r_tab[i] = Cr_r_tab[511];      Cr_g_tab[i] = Cr_g_tab[511];      Cb_g_tab[i] = Cb_g_tab[511];       Cb_b_tab[i] = Cb_b_tab[511];   }   Cr_r_tab += 256 + 128;   Cr_g_tab += 256 + 128;   Cb_g_tab += 256 + 128;   Cb_b_tab += 256 + 128;}

⌨️ 快捷键说明

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