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

📄 pngwutil.c

📁 Linux下的基于X11的图形开发环境。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* pngwutil.c - utilities to write a PNG file * * libpng 1.2.5 - October 3, 2002 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */#define PNG_INTERNAL#include "png.h"#ifdef PNG_WRITE_SUPPORTED/* Place a 32-bit number into a buffer in PNG byte order.  We work * with unsigned numbers for convenience, although one supported * ancillary chunk uses signed (two's complement) numbers. */void /* PRIVATE */png_save_uint_32(png_bytep buf, png_uint_32 i){   buf[0] = (png_byte)((i >> 24) & 0xff);   buf[1] = (png_byte)((i >> 16) & 0xff);   buf[2] = (png_byte)((i >> 8) & 0xff);   buf[3] = (png_byte)(i & 0xff);}#if defined(PNG_WRITE_pCAL_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)/* The png_save_int_32 function assumes integers are stored in two's * complement format.  If this isn't the case, then this routine needs to * be modified to write data in two's complement format. */void /* PRIVATE */png_save_int_32(png_bytep buf, png_int_32 i){   buf[0] = (png_byte)((i >> 24) & 0xff);   buf[1] = (png_byte)((i >> 16) & 0xff);   buf[2] = (png_byte)((i >> 8) & 0xff);   buf[3] = (png_byte)(i & 0xff);}#endif/* Place a 16-bit number into a buffer in PNG byte order. * The parameter is declared unsigned int, not png_uint_16, * just to avoid potential problems on pre-ANSI C compilers. */void /* PRIVATE */png_save_uint_16(png_bytep buf, unsigned int i){   buf[0] = (png_byte)((i >> 8) & 0xff);   buf[1] = (png_byte)(i & 0xff);}/* Write a PNG chunk all at once.  The type is an array of ASCII characters * representing the chunk name.  The array must be at least 4 bytes in * length, and does not need to be null terminated.  To be safe, pass the * pre-defined chunk names here, and if you need a new one, define it * where the others are defined.  The length is the length of the data. * All the data must be present.  If that is not possible, use the * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() * functions instead. */void PNGAPIpng_write_chunk(png_structp png_ptr, png_bytep chunk_name,   png_bytep data, png_size_t length){   png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length);   png_write_chunk_data(png_ptr, data, length);   png_write_chunk_end(png_ptr);}/* Write the start of a PNG chunk.  The type is the chunk type. * The total_length is the sum of the lengths of all the data you will be * passing in png_write_chunk_data(). */void PNGAPIpng_write_chunk_start(png_structp png_ptr, png_bytep chunk_name,   png_uint_32 length){   png_byte buf[4];   png_debug2(0, "Writing %s chunk (%lu bytes)\n", chunk_name, length);   /* write the length */   png_save_uint_32(buf, length);   png_write_data(png_ptr, buf, (png_size_t)4);   /* write the chunk name */   png_write_data(png_ptr, chunk_name, (png_size_t)4);   /* reset the crc and run it over the chunk name */   png_reset_crc(png_ptr);   png_calculate_crc(png_ptr, chunk_name, (png_size_t)4);}/* Write the data of a PNG chunk started with png_write_chunk_start(). * Note that multiple calls to this function are allowed, and that the * sum of the lengths from these calls *must* add up to the total_length * given to png_write_chunk_start(). */void PNGAPIpng_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length){   /* write the data, and run the CRC over it */   if (data != NULL && length > 0)   {      png_calculate_crc(png_ptr, data, length);      png_write_data(png_ptr, data, length);   }}/* Finish a chunk started with png_write_chunk_start(). */void PNGAPIpng_write_chunk_end(png_structp png_ptr){   png_byte buf[4];   /* write the crc */   png_save_uint_32(buf, png_ptr->crc);   png_write_data(png_ptr, buf, (png_size_t)4);}/* Simple function to write the signature.  If we have already written * the magic bytes of the signature, or more likely, the PNG stream is * being embedded into another stream and doesn't need its own signature, * we should call png_set_sig_bytes() to tell libpng how many of the * bytes have already been written. */void /* PRIVATE */png_write_sig(png_structp png_ptr){   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};   /* write the rest of the 8 byte signature */   png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],      (png_size_t)8 - png_ptr->sig_bytes);   if(png_ptr->sig_bytes < 3)      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;}#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED)/* * This pair of functions encapsulates the operation of (a) compressing a * text string, and (b) issuing it later as a series of chunk data writes. * The compression_state structure is shared context for these functions * set up by the caller in order to make the whole mess thread-safe. */typedef struct{    char *input;   /* the uncompressed input data */    int input_len;   /* its length */    int num_output_ptr; /* number of output pointers used */    int max_output_ptr; /* size of output_ptr */    png_charpp output_ptr; /* array of pointers to output */} compression_state;/* compress given text into storage in the png_ptr structure */static int /* PRIVATE */png_text_compress(png_structp png_ptr,        png_charp text, png_size_t text_len, int compression,        compression_state *comp){   int ret;   comp->num_output_ptr = comp->max_output_ptr = 0;   comp->output_ptr = NULL;   comp->input = NULL;   /* we may just want to pass the text right through */   if (compression == PNG_TEXT_COMPRESSION_NONE)   {       comp->input = text;       comp->input_len = text_len;       return((int)text_len);   }   if (compression >= PNG_TEXT_COMPRESSION_LAST)   {#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)      char msg[50];      sprintf(msg, "Unknown compression type %d", compression);      png_warning(png_ptr, msg);#else      png_warning(png_ptr, "Unknown compression type");#endif   }   /* We can't write the chunk until we find out how much data we have,    * which means we need to run the compressor first and save the    * output.  This shouldn't be a problem, as the vast majority of    * comments should be reasonable, but we will set up an array of    * malloc'd pointers to be sure.    *    * If we knew the application was well behaved, we could simplify this    * greatly by assuming we can always malloc an output buffer large    * enough to hold the compressed text ((1001 * text_len / 1000) + 12)    * and malloc this directly.  The only time this would be a bad idea is    * if we can't malloc more than 64K and we have 64K of random input    * data, or if the input string is incredibly large (although this    * wouldn't cause a failure, just a slowdown due to swapping).    */   /* set up the compression buffers */   png_ptr->zstream.avail_in = (uInt)text_len;   png_ptr->zstream.next_in = (Bytef *)text;   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;   png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;   /* this is the same compression loop as in png_write_row() */   do   {      /* compress the data */      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);      if (ret != Z_OK)      {         /* error */         if (png_ptr->zstream.msg != NULL)            png_error(png_ptr, png_ptr->zstream.msg);         else            png_error(png_ptr, "zlib error");      }      /* check to see if we need more room */      if (!png_ptr->zstream.avail_out && png_ptr->zstream.avail_in)      {         /* make sure the output array has room */         if (comp->num_output_ptr >= comp->max_output_ptr)         {            int old_max;            old_max = comp->max_output_ptr;            comp->max_output_ptr = comp->num_output_ptr + 4;            if (comp->output_ptr != NULL)            {               png_charpp old_ptr;               old_ptr = comp->output_ptr;               comp->output_ptr = (png_charpp)png_malloc(png_ptr,                  (png_uint_32)(comp->max_output_ptr * sizeof (png_charpp)));               png_memcpy(comp->output_ptr, old_ptr, old_max                  * sizeof (png_charp));               png_free(png_ptr, old_ptr);            }            else               comp->output_ptr = (png_charpp)png_malloc(png_ptr,                  (png_uint_32)(comp->max_output_ptr * sizeof (png_charp)));         }         /* save the data */         comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr,            (png_uint_32)png_ptr->zbuf_size);         png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,            png_ptr->zbuf_size);         comp->num_output_ptr++;         /* and reset the buffer */         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;         png_ptr->zstream.next_out = png_ptr->zbuf;      }   /* continue until we don't have any more to compress */   } while (png_ptr->zstream.avail_in);   /* finish the compression */   do   {      /* tell zlib we are finished */      ret = deflate(&png_ptr->zstream, Z_FINISH);      if (ret == Z_OK)      {         /* check to see if we need more room */         if (!(png_ptr->zstream.avail_out))         {            /* check to make sure our output array has room */            if (comp->num_output_ptr >= comp->max_output_ptr)            {               int old_max;               old_max = comp->max_output_ptr;               comp->max_output_ptr = comp->num_output_ptr + 4;               if (comp->output_ptr != NULL)               {                  png_charpp old_ptr;                  old_ptr = comp->output_ptr;                  /* This could be optimized to realloc() */                  comp->output_ptr = (png_charpp)png_malloc(png_ptr,                     (png_uint_32)(comp->max_output_ptr * sizeof (png_charpp)));                  png_memcpy(comp->output_ptr, old_ptr,                     old_max * sizeof (png_charp));                  png_free(png_ptr, old_ptr);               }               else                  comp->output_ptr = (png_charpp)png_malloc(png_ptr,                     (png_uint_32)(comp->max_output_ptr * sizeof (png_charp)));            }            /* save off the data */            comp->output_ptr[comp->num_output_ptr] =               (png_charp)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size);            png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,               png_ptr->zbuf_size);            comp->num_output_ptr++;            /* and reset the buffer pointers */            png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;            png_ptr->zstream.next_out = png_ptr->zbuf;         }      }      else if (ret != Z_STREAM_END)      {         /* we got an error */         if (png_ptr->zstream.msg != NULL)            png_error(png_ptr, png_ptr->zstream.msg);         else            png_error(png_ptr, "zlib error");      }   } while (ret != Z_STREAM_END);   /* text length is number of buffers plus last buffer */   text_len = png_ptr->zbuf_size * comp->num_output_ptr;   if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)      text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;   return((int)text_len);}/* ship the compressed text out via chunk writes */static void /* PRIVATE */png_write_compressed_data_out(png_structp png_ptr, compression_state *comp){   int i;   /* handle the no-compression case */   if (comp->input)   {       png_write_chunk_data(png_ptr, (png_bytep)comp->input,                            (png_size_t)comp->input_len);       return;   }   /* write saved output buffers, if any */   for (i = 0; i < comp->num_output_ptr; i++)   {      png_write_chunk_data(png_ptr,(png_bytep)comp->output_ptr[i],         png_ptr->zbuf_size);      png_free(png_ptr, comp->output_ptr[i]);      comp->output_ptr[i]=NULL;   }   if (comp->max_output_ptr != 0)      png_free(png_ptr, comp->output_ptr);      comp->output_ptr=NULL;   /* write anything left in zbuf */   if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)      png_write_chunk_data(png_ptr, png_ptr->zbuf,         png_ptr->zbuf_size - png_ptr->zstream.avail_out);   /* reset zlib for another zTXt/iTXt or the image data */   deflateReset(&png_ptr->zstream);}#endif/* Write the IHDR chunk, and update the png_struct with the necessary * information.  Note that the rest of this code depends upon this * information being correct. */void /* PRIVATE */png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,   int bit_depth, int color_type, int compression_type, int filter_type,   int interlace_type){#ifdef PNG_USE_LOCAL_ARRAYS   PNG_IHDR;#endif   png_byte buf[13]; /* buffer to store the IHDR info */   png_debug(1, "in png_write_IHDR\n");   /* Check that we have valid input data from the application info */   switch (color_type)   {      case PNG_COLOR_TYPE_GRAY:         switch (bit_depth)         {            case 1:            case 2:            case 4:            case 8:            case 16: png_ptr->channels = 1; break;            default: png_error(png_ptr,"Invalid bit depth for grayscale image");         }         break;      case PNG_COLOR_TYPE_RGB:         if (bit_depth != 8 && bit_depth != 16)            png_error(png_ptr, "Invalid bit depth for RGB image");         png_ptr->channels = 3;         break;      case PNG_COLOR_TYPE_PALETTE:         switch (bit_depth)         {            case 1:            case 2:            case 4:            case 8: png_ptr->channels = 1; break;            default: png_error(png_ptr, "Invalid bit depth for paletted image");         }         break;      case PNG_COLOR_TYPE_GRAY_ALPHA:         if (bit_depth != 8 && bit_depth != 16)            png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");         png_ptr->channels = 2;         break;      case PNG_COLOR_TYPE_RGB_ALPHA:         if (bit_depth != 8 && bit_depth != 16)            png_error(png_ptr, "Invalid bit depth for RGBA image");         png_ptr->channels = 4;         break;      default:         png_error(png_ptr, "Invalid image color type specified");   }   if (compression_type != PNG_COMPRESSION_TYPE_BASE)   {

⌨️ 快捷键说明

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