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

📄 pngrutil.c

📁 Linux下的基于X11的图形开发环境。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* pngrutil.c - utilities to read 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.) * * This file contains routines that are only called from within * libpng itself during the course of reading an image. */#define PNG_INTERNAL#include "png.h"#if defined(_WIN32_WCE)/* strtod() function is not supported on WindowsCE */#  ifdef PNG_FLOATING_POINT_SUPPORTED__inline double strtod(const char *nptr, char **endptr){   double result = 0;   int len;   wchar_t *str, *end;   len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);   str = (wchar_t *)malloc(len * sizeof(wchar_t));   if ( NULL != str )   {      MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);      result = wcstod(str, &end);      len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);      *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);      free(str);   }   return result;}#  endif#endif#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */png_uint_32 /* PRIVATE */png_get_uint_32(png_bytep buf){   png_uint_32 i = ((png_uint_32)(*buf) << 24) +      ((png_uint_32)(*(buf + 1)) << 16) +      ((png_uint_32)(*(buf + 2)) << 8) +      (png_uint_32)(*(buf + 3));   return (i);}#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_oFFs_SUPPORTED)/* Grab a signed 32-bit integer from a buffer in big-endian format.  The * data is stored in the PNG file in two's complement format, and it is * assumed that the machine format for signed integers is the same. */png_int_32 /* PRIVATE */png_get_int_32(png_bytep buf){   png_int_32 i = ((png_int_32)(*buf) << 24) +      ((png_int_32)(*(buf + 1)) << 16) +      ((png_int_32)(*(buf + 2)) << 8) +      (png_int_32)(*(buf + 3));   return (i);}#endif /* PNG_READ_pCAL_SUPPORTED *//* Grab an unsigned 16-bit integer from a buffer in big-endian format. */png_uint_16 /* PRIVATE */png_get_uint_16(png_bytep buf){   png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +      (png_uint_16)(*(buf + 1)));   return (i);}#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED *//* Read data, and (optionally) run it through the CRC. */void /* PRIVATE */png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length){   png_read_data(png_ptr, buf, length);   png_calculate_crc(png_ptr, buf, length);}/* Optionally skip data and then check the CRC.  Depending on whether we   are reading a ancillary or critical chunk, and how the program has set   things up, we may calculate the CRC on the data and print a message.   Returns '1' if there was a CRC error, '0' otherwise. */int /* PRIVATE */png_crc_finish(png_structp png_ptr, png_uint_32 skip){   png_size_t i;   png_size_t istop = png_ptr->zbuf_size;   for (i = (png_size_t)skip; i > istop; i -= istop)   {      png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);   }   if (i)   {      png_crc_read(png_ptr, png_ptr->zbuf, i);   }   if (png_crc_error(png_ptr))   {      if (((png_ptr->chunk_name[0] & 0x20) &&                /* Ancillary */           !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||          (!(png_ptr->chunk_name[0] & 0x20) &&             /* Critical  */          (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))      {         png_chunk_warning(png_ptr, "CRC error");      }      else      {         png_chunk_error(png_ptr, "CRC error");      }      return (1);   }   return (0);}/* Compare the CRC stored in the PNG file with that calculated by libpng from   the data it has read thus far. */int /* PRIVATE */png_crc_error(png_structp png_ptr){   png_byte crc_bytes[4];   png_uint_32 crc;   int need_crc = 1;   if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */   {      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))         need_crc = 0;   }   else                                                    /* critical */   {      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)         need_crc = 0;   }   png_read_data(png_ptr, crc_bytes, 4);   if (need_crc)   {      crc = png_get_uint_32(crc_bytes);      return ((int)(crc != png_ptr->crc));   }   else      return (0);}#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \    defined(PNG_READ_iCCP_SUPPORTED)/* * Decompress trailing data in a chunk.  The assumption is that chunkdata * points at an allocated area holding the contents of a chunk with a * trailing compressed part.  What we get back is an allocated area * holding the original prefix part and an uncompressed version of the * trailing part (the malloc area passed in is freed). */png_charp /* PRIVATE */png_decompress_chunk(png_structp png_ptr, int comp_type,                              png_charp chunkdata, png_size_t chunklength,                              png_size_t prefix_size, png_size_t *newlength){   static char msg[] = "Error decoding compressed text";   png_charp text = NULL;   png_size_t text_size;   if (comp_type == PNG_COMPRESSION_TYPE_BASE)   {      int ret = Z_OK;      png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);      png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);      png_ptr->zstream.next_out = png_ptr->zbuf;      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;      text_size = 0;      text = NULL;      while (png_ptr->zstream.avail_in)      {         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);         if (ret != Z_OK && ret != Z_STREAM_END)         {            if (png_ptr->zstream.msg != NULL)               png_warning(png_ptr, png_ptr->zstream.msg);            else               png_warning(png_ptr, msg);            inflateReset(&png_ptr->zstream);            png_ptr->zstream.avail_in = 0;            if (text ==  NULL)            {               text_size = prefix_size + sizeof(msg) + 1;               text = (png_charp)png_malloc_warn(png_ptr, text_size);               if (text ==  NULL)                 {                    png_free(png_ptr,chunkdata);                    png_error(png_ptr,"Not enough memory to decompress chunk");                 }               png_memcpy(text, chunkdata, prefix_size);            }            text[text_size - 1] = 0x00;            /* Copy what we can of the error message into the text chunk */            text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);            text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);            png_memcpy(text + prefix_size, msg, text_size + 1);            break;         }         if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)         {            if (text == NULL)            {               text_size = prefix_size +                   png_ptr->zbuf_size - png_ptr->zstream.avail_out;               text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);               if (text ==  NULL)                 {                    png_free(png_ptr,chunkdata);                    png_error(png_ptr,"Not enough memory to decompress chunk.");                 }               png_memcpy(text + prefix_size, png_ptr->zbuf,                    text_size - prefix_size);               png_memcpy(text, chunkdata, prefix_size);               *(text + text_size) = 0x00;            }            else            {               png_charp tmp;               tmp = text;               text = (png_charp)png_malloc_warn(png_ptr,                  (png_uint_32)(text_size +                  png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));               if (text == NULL)               {                  png_free(png_ptr, tmp);                  png_free(png_ptr, chunkdata);                  png_error(png_ptr,"Not enough memory to decompress chunk..");               }               png_memcpy(text, tmp, text_size);               png_free(png_ptr, tmp);               png_memcpy(text + text_size, png_ptr->zbuf,                  (png_ptr->zbuf_size - png_ptr->zstream.avail_out));               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;               *(text + text_size) = 0x00;            }            if (ret == Z_STREAM_END)               break;            else            {               png_ptr->zstream.next_out = png_ptr->zbuf;               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;            }         }      }      if (ret != Z_STREAM_END)      {#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)         char umsg[50];         if (ret == Z_BUF_ERROR)            sprintf(umsg,"Buffer error in compressed datastream in %s chunk",                png_ptr->chunk_name);         else if (ret == Z_DATA_ERROR)            sprintf(umsg,"Data error in compressed datastream in %s chunk",                png_ptr->chunk_name);         else            sprintf(umsg,"Incomplete compressed datastream in %s chunk",                png_ptr->chunk_name);         png_warning(png_ptr, umsg);#else         png_warning(png_ptr,            "Incomplete compressed datastream in chunk other than IDAT");#endif         text_size=prefix_size;         if (text ==  NULL)         {            text = (png_charp)png_malloc_warn(png_ptr, text_size+1);            if (text == NULL)              {                png_free(png_ptr, chunkdata);                png_error(png_ptr,"Not enough memory for text.");              }            png_memcpy(text, chunkdata, prefix_size);         }         *(text + text_size) = 0x00;      }      inflateReset(&png_ptr->zstream);      png_ptr->zstream.avail_in = 0;      png_free(png_ptr, chunkdata);      chunkdata = text;      *newlength=text_size;   }   else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */   {#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)      char umsg[50];      sprintf(umsg, "Unknown zTXt compression type %d", comp_type);      png_warning(png_ptr, umsg);#else      png_warning(png_ptr, "Unknown zTXt compression type");#endif      *(chunkdata + prefix_size) = 0x00;      *newlength=prefix_size;   }   return chunkdata;}#endif/* read and check the IDHR chunk */void /* PRIVATE */png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length){   png_byte buf[13];   png_uint_32 width, height;   int bit_depth, color_type, compression_type, filter_type;   int interlace_type;   png_debug(1, "in png_handle_IHDR\n");   if (png_ptr->mode & PNG_HAVE_IHDR)      png_error(png_ptr, "Out of place IHDR");   /* check the length */   if (length != 13)      png_error(png_ptr, "Invalid IHDR chunk");   png_ptr->mode |= PNG_HAVE_IHDR;   png_crc_read(png_ptr, buf, 13);   png_crc_finish(png_ptr, 0);   width = png_get_uint_32(buf);   height = png_get_uint_32(buf + 4);   bit_depth = buf[8];   color_type = buf[9];   compression_type = buf[10];   filter_type = buf[11];   interlace_type = buf[12];   /* set internal variables */   png_ptr->width = width;   png_ptr->height = height;   png_ptr->bit_depth = (png_byte)bit_depth;   png_ptr->interlaced = (png_byte)interlace_type;   png_ptr->color_type = (png_byte)color_type;#if defined(PNG_MNG_FEATURES_SUPPORTED)   png_ptr->filter_type = (png_byte)filter_type;#endif   /* find number of channels */   switch (png_ptr->color_type)   {      case PNG_COLOR_TYPE_GRAY:      case PNG_COLOR_TYPE_PALETTE:         png_ptr->channels = 1;         break;      case PNG_COLOR_TYPE_RGB:         png_ptr->channels = 3;         break;      case PNG_COLOR_TYPE_GRAY_ALPHA:         png_ptr->channels = 2;         break;      case PNG_COLOR_TYPE_RGB_ALPHA:         png_ptr->channels = 4;         break;   }   /* set up other useful info */   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *   png_ptr->channels);   png_ptr->rowbytes = ((png_ptr->width *      (png_uint_32)png_ptr->pixel_depth + 7) >> 3);   png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);   png_debug1(3,"channels = %d\n", png_ptr->channels);   png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,      color_type, interlace_type, compression_type, filter_type);}/* read and check the palette */void /* PRIVATE */png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length){   png_color palette[PNG_MAX_PALETTE_LENGTH];   int num, i;#ifndef PNG_NO_POINTER_INDEXING   png_colorp pal_ptr;#endif   png_debug(1, "in png_handle_PLTE\n");   if (!(png_ptr->mode & PNG_HAVE_IHDR))      png_error(png_ptr, "Missing IHDR before PLTE");   else if (png_ptr->mode & PNG_HAVE_IDAT)   {      png_warning(png_ptr, "Invalid PLTE after IDAT");      png_crc_finish(png_ptr, length);      return;   }   else if (png_ptr->mode & PNG_HAVE_PLTE)      png_error(png_ptr, "Duplicate PLTE chunk");   png_ptr->mode |= PNG_HAVE_PLTE;   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))   {      png_warning(png_ptr,        "Ignoring PLTE chunk in grayscale PNG");      png_crc_finish(png_ptr, length);      return;   }#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)   {      png_crc_finish(png_ptr, length);      return;   }#endif   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)   {      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)      {         png_warning(png_ptr, "Invalid palette chunk");         png_crc_finish(png_ptr, length);         return;      }      else      {         png_error(png_ptr, "Invalid palette chunk");      }   }   num = (int)length / 3;

⌨️ 快捷键说明

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