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

📄 gd_png.c

📁 Linux/Unix下的绘图函数库(Graphic Drawing Library)
💻 C
📖 第 1 页 / 共 2 页
字号:
    }#ifdef DEBUG  if (!im->trueColor)    {      for (i = num_palette; i < gdMaxColors; ++i)	{	  if (!open[i])	    {	      fprintf (stderr,		       "gd-png warning: image data references out-of-range"		       " color index (%d)\n", i);	    }	}    }#endif  if (palette_allocated)    gdFree (palette);  gdFree (image_data);  gdFree (row_pointers);  return im;}BGD_DECLARE(void) gdImagePngEx (gdImagePtr im, FILE * outFile, int level){  gdIOCtx *out = gdNewFileCtx (outFile);  gdImagePngCtxEx (im, out, level);  out->gd_free (out);}BGD_DECLARE(void) gdImagePng (gdImagePtr im, FILE * outFile){  gdIOCtx *out = gdNewFileCtx (outFile);  gdImagePngCtxEx (im, out, -1);  out->gd_free (out);}BGD_DECLARE(void *) gdImagePngPtr (gdImagePtr im, int *size){  void *rv;  gdIOCtx *out = gdNewDynamicCtx (2048, NULL);  gdImagePngCtxEx (im, out, -1);  rv = gdDPExtractData (out, size);  out->gd_free (out);  return rv;}BGD_DECLARE(void *) gdImagePngPtrEx (gdImagePtr im, int *size, int level){  void *rv;  gdIOCtx *out = gdNewDynamicCtx (2048, NULL);  gdImagePngCtxEx (im, out, level);  rv = gdDPExtractData (out, size);  out->gd_free (out);  return rv;}BGD_DECLARE(void) gdImagePngCtx (gdImagePtr im, gdIOCtx * outfile){  /* 2.0.13: 'return' here was an error, thanks to Kevin Smith */  gdImagePngCtxEx (im, outfile, -1);}/* This routine is based in part on code from Dale Lutz (Safe Software Inc.) *  and in part on demo code from Chapter 15 of "PNG: The Definitive Guide" *  (http://www.cdrom.com/pub/png/pngbook.html). */BGD_DECLARE(void) gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level){  int i, j, bit_depth = 0, interlace_type;  int width = im->sx;  int height = im->sy;  int colors = im->colorsTotal;  int *open = im->open;  int mapping[gdMaxColors];	/* mapping[gd_index] == png_index */  png_byte trans_values[256];  png_color_16 trans_rgb_value;  png_color palette[gdMaxColors];  png_structp png_ptr;  png_infop info_ptr;  volatile int transparent = im->transparent;  volatile int remap = FALSE;#ifndef PNG_SETJMP_NOT_SUPPORTED  png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING,				     &gdPngJmpbufStruct, gdPngErrorHandler,				     NULL);#else  png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);#endif  if (png_ptr == NULL)    {      fprintf (stderr, "gd-png error: cannot allocate libpng main struct\n");      return;    }  info_ptr = png_create_info_struct (png_ptr);  if (info_ptr == NULL)    {      fprintf (stderr, "gd-png error: cannot allocate libpng info struct\n");      png_destroy_write_struct (&png_ptr, (png_infopp) NULL);      return;    }#ifndef PNG_SETJMP_NOT_SUPPORTED  if (setjmp (gdPngJmpbufStruct.jmpbuf))    {      fprintf (stderr, "gd-png error: setjmp returns error condition\n");      png_destroy_write_struct (&png_ptr, &info_ptr);      return;    }#endif  png_set_write_fn (png_ptr, (void *) outfile, gdPngWriteData,		    gdPngFlushData);  /* This is best for palette images, and libpng defaults to it for     palette images anyway, so we don't need to do it explicitly.     What to ideally do for truecolor images depends, alas, on the image.     gd is intentionally imperfect and doesn't spend a lot of time     fussing with such things. */  /* Faster if this is uncommented, but may produce larger truecolor files.     Wait for gdImagePngCtxEx. */#if 0  png_set_filter (png_ptr, 0, PNG_FILTER_NONE);#endif  /* 2.0.12: this is finally a parameter */  png_set_compression_level (png_ptr, level);  /* can set this to a smaller value without compromising compression if all   * image data is 16K or less; will save some decoder memory [min == 8] *//*  png_set_compression_window_bits(png_ptr, 15);  */  if (!im->trueColor)    {      if (transparent >= im->colorsTotal ||	  (transparent >= 0 && open[transparent]))	transparent = -1;    }  if (!im->trueColor)    {      for (i = 0; i < gdMaxColors; ++i)	mapping[i] = -1;    }  if (!im->trueColor)    {      /* count actual number of colors used (colorsTotal == high-water mark) */      colors = 0;      for (i = 0; i < im->colorsTotal; ++i)	{	  if (!open[i])	    {	      mapping[i] = colors;	      ++colors;	    }	}      if (colors < im->colorsTotal)	{	  remap = TRUE;	}      if (colors <= 2)	bit_depth = 1;      else if (colors <= 4)	bit_depth = 2;      else if (colors <= 16)	bit_depth = 4;      else	bit_depth = 8;    }  interlace_type = im->interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE;  if (im->trueColor)    {      if (im->saveAlphaFlag)	{	  png_set_IHDR (png_ptr, info_ptr, width, height, 8,			PNG_COLOR_TYPE_RGB_ALPHA, interlace_type,			PNG_COMPRESSION_TYPE_DEFAULT,			PNG_FILTER_TYPE_DEFAULT);	}      else	{	  png_set_IHDR (png_ptr, info_ptr, width, height, 8,			PNG_COLOR_TYPE_RGB, interlace_type,			PNG_COMPRESSION_TYPE_DEFAULT,			PNG_FILTER_TYPE_DEFAULT);	}    }  else    {      png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth,		    PNG_COLOR_TYPE_PALETTE, interlace_type,		    PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);    }  if (im->trueColor && (!im->saveAlphaFlag) && (transparent >= 0))    {      /* 2.0.9: fixed by Thomas Winzig */      trans_rgb_value.red = gdTrueColorGetRed (im->transparent);      trans_rgb_value.green = gdTrueColorGetGreen (im->transparent);      trans_rgb_value.blue = gdTrueColorGetBlue (im->transparent);      png_set_tRNS (png_ptr, info_ptr, 0, 0, &trans_rgb_value);    }  if (!im->trueColor)    {      /* Oy veh. Remap the PNG palette to put the          entries with interesting alpha channel         values first. This minimizes the size         of the tRNS chunk and thus the size         of the PNG file as a whole. */      int tc = 0;      int i;      int j;      int k;      for (i = 0; (i < im->colorsTotal); i++)	{	  if ((!im->open[i]) && (im->alpha[i] != gdAlphaOpaque))	    {	      tc++;	    }	}      if (tc)	{#if 0	  for (i = 0; (i < im->colorsTotal); i++)	    {	      trans_values[i] = 255 -		((im->alpha[i] << 1) + (im->alpha[i] >> 6));	    }	  png_set_tRNS (png_ptr, info_ptr, trans_values, 256, NULL);#endif	  if (!remap)	    {	      remap = TRUE;	    }	  /* (Semi-)transparent indexes come up from the bottom	     of the list of real colors; opaque	     indexes come down from the top */	  j = 0;	  k = colors - 1;	  for (i = 0; (i < im->colorsTotal); i++)	    {	      if (!im->open[i])		{		  if (im->alpha[i] != gdAlphaOpaque)		    {		      /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */		      trans_values[j] = 255 -			((im->alpha[i] << 1) + (im->alpha[i] >> 6));		      mapping[i] = j++;		    }		  else		    {		      mapping[i] = k--;		    }		}	    }	  png_set_tRNS (png_ptr, info_ptr, trans_values, tc, NULL);	}    }  /* convert palette to libpng layout */  if (!im->trueColor)    {      if (remap)	for (i = 0; i < im->colorsTotal; ++i)	  {	    if (mapping[i] < 0)	      continue;	    palette[mapping[i]].red = im->red[i];	    palette[mapping[i]].green = im->green[i];	    palette[mapping[i]].blue = im->blue[i];	  }      else	for (i = 0; i < colors; ++i)	  {	    palette[i].red = im->red[i];	    palette[i].green = im->green[i];	    palette[i].blue = im->blue[i];	  }      png_set_PLTE (png_ptr, info_ptr, palette, colors);    }  /* write out the PNG header info (everything up to first IDAT) */  png_write_info (png_ptr, info_ptr);  /* make sure < 8-bit images are packed into pixels as tightly as possible */  png_set_packing (png_ptr);  /* This code allocates a set of row buffers and copies the gd image data   * into them only in the case that remapping is necessary; in gd 1.3 and   * later, the im->pixels array is laid out identically to libpng's row   * pointers and can be passed to png_write_image() function directly.   * The remapping case could be accomplished with less memory for non-   * interlaced images, but interlacing causes some serious complications. */  if (im->trueColor)    {      /* performance optimizations by Phong Tran */      int channels = im->saveAlphaFlag ? 4 : 3;      /* Our little 7-bit alpha channel trick costs us a bit here. */      png_bytep *row_pointers;      unsigned char *pOutputRow;      int **ptpixels = im->tpixels;      int *pThisRow;      unsigned char a;      int thisPixel;      png_bytep *prow_pointers;      int saveAlphaFlag = im->saveAlphaFlag;      if (overflow2(sizeof (png_bytep), height)) {        return;      }       row_pointers = gdMalloc (sizeof (png_bytep) * height);      if (row_pointers == NULL)	{	  fprintf (stderr, "gd-png error: unable to allocate row_pointers\n");          /* 2.0.29: return was missing */          return;	}      prow_pointers = row_pointers;      for (j = 0; j < height; ++j)	{          if (overflow2(width, channels) || ((*prow_pointers =	       (png_bytep) gdMalloc (width * channels)) == NULL))	    {	      fprintf (stderr, "gd-png error: unable to allocate rows\n");	      for (i = 0; i < j; ++i)		gdFree (row_pointers[i]);              /* 2.0.29: memory leak TBB */              free(row_pointers);	      return;	    }	  pOutputRow = *prow_pointers++;	  pThisRow = *ptpixels++;	  for (i = 0; i < width; ++i)	    {	      thisPixel = *pThisRow++;	      *pOutputRow++ = gdTrueColorGetRed (thisPixel);	      *pOutputRow++ = gdTrueColorGetGreen (thisPixel);	      *pOutputRow++ = gdTrueColorGetBlue (thisPixel);	      if (saveAlphaFlag)		{		  /* convert the 7-bit alpha channel to an 8-bit alpha channel.		     We do a little bit-flipping magic, repeating the MSB		     as the LSB, to ensure that 0 maps to 0 and		     127 maps to 255. We also have to invert to match		     PNG's convention in which 255 is opaque. */		  a = gdTrueColorGetAlpha (thisPixel);		  /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */		  *pOutputRow++ = 255 - ((a << 1) + (a >> 6));		}	    }	}      png_write_image (png_ptr, row_pointers);      png_write_end (png_ptr, info_ptr);      for (j = 0; j < height; ++j)	gdFree (row_pointers[j]);      gdFree (row_pointers);    }  else    {      if (remap)	{	  png_bytep *row_pointers;          if (overflow2(sizeof (png_bytep), height)) {            return;          }	  row_pointers = gdMalloc (sizeof (png_bytep) * height);	  if (row_pointers == NULL)	    {	      fprintf (stderr,		       "gd-png error: unable to allocate row_pointers\n");              /* TBB: return missing */              return;	    }	  for (j = 0; j < height; ++j)	    {	      if ((row_pointers[j] = (png_bytep) gdMalloc (width)) == NULL)		{		  fprintf (stderr, "gd-png error: unable to allocate rows\n");		  for (i = 0; i < j; ++i)		    gdFree (row_pointers[i]);                  /* TBB: memory leak */		  gdFree (row_pointers);		  return;		}	      for (i = 0; i < width; ++i)		row_pointers[j][i] = mapping[im->pixels[j][i]];	    }	  png_write_image (png_ptr, row_pointers);	  png_write_end (png_ptr, info_ptr);	  for (j = 0; j < height; ++j)	    gdFree (row_pointers[j]);	  gdFree (row_pointers);	}      else	{	  png_write_image (png_ptr, im->pixels);	  png_write_end (png_ptr, info_ptr);	}    }  /* 1.6.3: maybe we should give that memory BACK! TBB */  png_destroy_write_struct (&png_ptr, &info_ptr);}#endif /* HAVE_LIBPNG */

⌨️ 快捷键说明

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