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

📄 pngwutil.c

📁 一套图像处理程序,支持三种图像文件格式,我调试过了,很好用
💻 C
📖 第 1 页 / 共 3 页
字号:
         return;
      }
      /* write the chunk out as it is */
      png_write_chunk(png_ptr, png_tRNS, trans, (png_uint_32)num_trans);
   }
   else if (color_type == PNG_COLOR_TYPE_GRAY)
   {
      /* one 16 bit value */
      png_save_uint_16(buf, tran->gray);
      png_write_chunk(png_ptr, png_tRNS, buf, (png_uint_32)2);
   }
   else if (color_type == PNG_COLOR_TYPE_RGB)
   {
      /* three 16 bit values */
      png_save_uint_16(buf, tran->red);
      png_save_uint_16(buf + 2, tran->green);
      png_save_uint_16(buf + 4, tran->blue);
      png_write_chunk(png_ptr, png_tRNS, buf, (png_uint_32)6);
   }
   else
   {
      png_warning(png_ptr, "Can't write tRNS with and alpha channel");
   }
}
#endif

#if defined(PNG_WRITE_bKGD_SUPPORTED)
/* write the background chunk */
void
png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
{
   png_byte buf[6];

   if (color_type == PNG_COLOR_TYPE_PALETTE)
   {
      if (back->index > png_ptr->num_palette)
      {
         png_warning(png_ptr, "Invalid background palette index");
         return;
      }
      buf[0] = back->index;
      png_write_chunk(png_ptr, png_bKGD, buf, (png_uint_32)1);
   }
   else if (color_type & PNG_COLOR_MASK_COLOR)
   {
      png_save_uint_16(buf, back->red);
      png_save_uint_16(buf + 2, back->green);
      png_save_uint_16(buf + 4, back->blue);
      png_write_chunk(png_ptr, png_bKGD, buf, (png_uint_32)6);
   }
   else
   {
      png_save_uint_16(buf, back->gray);
      png_write_chunk(png_ptr, png_bKGD, buf, (png_uint_32)2);
   }
}
#endif

#if defined(PNG_WRITE_hIST_SUPPORTED)
/* write the histogram */
void
png_write_hIST(png_structp png_ptr, png_uint_16p hist, int number)
{
   int i;
   png_byte buf[3];

   if (number <= 0 || number > png_ptr->num_palette)
   {
      png_warning(png_ptr, "Invalid number of histogram entries specified");
      return;
   }

   png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(number * 2));
   for (i = 0; i < number; i++)
   {
      png_save_uint_16(buf, hist[i]);
      png_write_chunk_data(png_ptr, buf, (png_uint_32)2);
   }
   png_write_chunk_end(png_ptr);
}
#endif

#if defined(PNG_WRITE_tEXt_SUPPORTED)
/* write a tEXt chunk */
void
png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
   png_uint_32 text_len)
{
   int key_len;

   key_len = png_strlen(key);

   if (key_len == 0)
   {
      png_warning(png_ptr, "Invalid text keyword length");
      return;
   }
   else if (key_len > 80)
   {
      png_warning(png_ptr, "Text keyword length restricted to 80 characters\n");
      key[80] = '\0';
      key_len = 80;
   }

   /* make sure we count the 0 after the key */
   png_write_chunk_start(png_ptr, png_tEXt,
      (png_uint_32)(key_len + text_len + 1));
   /* key has an 0 at the end.  How nice */
   png_write_chunk_data(png_ptr, (png_bytep )key, (png_uint_32)(key_len + 1));
   if (text && text_len)
      png_write_chunk_data(png_ptr, (png_bytep )text, (png_uint_32)text_len);
   png_write_chunk_end(png_ptr);
}
#endif

#if defined(PNG_WRITE_zTXt_SUPPORTED)
/* write a compressed chunk */
void
png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
   png_uint_32 text_len, int compression)
{
   int key_len;
   char buf[1];
   int i, ret;
   png_charpp output_ptr = NULL; /* array of pointers to output */
   int num_output_ptr = 0; /* number of output pointers used */
   int max_output_ptr = 0; /* size of output_ptr */

   key_len = png_strlen(key);

   if (key_len == 0)
   {
      png_warning(png_ptr, "Invalid text keyword length");
      return;
   }
   else if (key_len > 80)
   {
      png_warning(png_ptr, "Text keyword length restricted to 80 characters\n");
      key[80] = '\0';
      key_len = 80;
   }

   if (compression != 0)
   {
      png_warning(png_ptr, "Only type 0 compression allowed for text\n");
      compression = 0;
   }

   /* we can't write the chunk until we find out how much data we have,
      which means we need to run the compresser 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
      malloced pointers to be sure. */

   /* 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)
            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 (num_output_ptr >= max_output_ptr)
         {
            png_uint_32 old_max;

            old_max = max_output_ptr;
            max_output_ptr = num_output_ptr + 4;
            if (output_ptr)
            {
               png_charpp old_ptr;

               old_ptr = output_ptr;
               output_ptr = (png_charpp)png_large_malloc(png_ptr,
                  max_output_ptr * sizeof (png_charpp));
               png_memcpy(output_ptr, old_ptr,
                  (png_size_t)(old_max * sizeof (png_charp)));
               png_large_free(png_ptr, old_ptr);
            }
            else
               output_ptr = (png_charpp)png_large_malloc(png_ptr,
                  max_output_ptr * sizeof (png_charp));
         }

         /* save the data */
         output_ptr[num_output_ptr] = png_large_malloc(png_ptr,
            png_ptr->zbuf_size);
         png_memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
            (png_size_t)png_ptr->zbuf_size);
         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 anymore 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 && ret != Z_STREAM_END)
      {
         /* we got an error */
         if (png_ptr->zstream->msg)
            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 && ret == Z_OK)
      {
         /* check to make sure our output array has room */
         if (num_output_ptr >= max_output_ptr)
         {
            png_uint_32 old_max;

            old_max = max_output_ptr;
            max_output_ptr = num_output_ptr + 4;
            if (output_ptr)
            {
               png_charpp old_ptr;

               old_ptr = output_ptr;
               output_ptr = (png_charpp)png_large_malloc(png_ptr,
                  max_output_ptr * sizeof (png_charpp));
               png_memcpy(output_ptr, old_ptr,
                  (png_size_t)(old_max * sizeof (png_charp)));
               png_large_free(png_ptr, old_ptr);
            }
            else
               output_ptr = (png_charpp)png_large_malloc(png_ptr,
                  max_output_ptr * sizeof (png_charp));
         }

         /* save off the data */
         output_ptr[num_output_ptr] = png_large_malloc(png_ptr,
            png_ptr->zbuf_size);
         png_memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
            (png_size_t)png_ptr->zbuf_size);
         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;
      }
   } while (ret != Z_STREAM_END);

   /* text length is number of buffers plus last buffer */
   text_len = png_ptr->zbuf_size * num_output_ptr;
   if (png_ptr->zstream->avail_out < png_ptr->zbuf_size)
      text_len += (png_uint_32)(png_ptr->zbuf_size -
         png_ptr->zstream->avail_out);

   /* write start of chunk */
   png_write_chunk_start(png_ptr, png_zTXt,
      (png_uint_32)(key_len + text_len + 2));
   /* write key */
   png_write_chunk_data(png_ptr, (png_bytep )key, (png_uint_32)(key_len + 1));
   buf[0] = (png_byte)compression;
   /* write compression */
   png_write_chunk_data(png_ptr, (png_bytep )buf, (png_uint_32)1);

   /* write saved output buffers, if any */
   for (i = 0; i < num_output_ptr; i++)
   {
      png_write_chunk_data(png_ptr, (png_bytep )output_ptr[i], png_ptr->zbuf_size);
      png_large_free(png_ptr, output_ptr[i]);
   }
   if (max_output_ptr)
      png_large_free(png_ptr, output_ptr);
   /* write anything left in zbuf */
   if (png_ptr->zstream->avail_out < png_ptr->zbuf_size)
      png_write_chunk_data(png_ptr, png_ptr->zbuf,
         png_ptr->zbuf_size - png_ptr->zstream->avail_out);
   /* close the chunk */
   png_write_chunk_end(png_ptr);

   /* reset zlib for another zTXt or the image data */
   deflateReset(png_ptr->zstream);
}
#endif

#if defined(PNG_WRITE_pHYs_SUPPORTED)
/* write the pHYs chunk */
void
png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
   png_uint_32 y_pixels_per_unit,
   int unit_type)
{
   png_byte buf[9];

   if (unit_type >= PNG_RESOLUTION_LAST)
      png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");

   png_save_uint_32(buf, x_pixels_per_unit);
   png_save_uint_32(buf + 4, y_pixels_per_unit);
   buf[8] = (png_byte)unit_type;

   png_write_chunk(png_ptr, png_pHYs, buf, (png_uint_32)9);
}
#endif

#if defined(PNG_WRITE_oFFs_SUPPORTED)
/* write the oFFs chunk */
void
png_write_oFFs(png_structp png_ptr, png_uint_32 x_offset,
   png_uint_32 y_offset,
   int unit_type)
{
   png_byte buf[9];

   if (unit_type >= PNG_OFFSET_LAST)
      png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");

   png_save_uint_32(buf, x_offset);
   png_save_uint_32(buf + 4, y_offset);
   buf[8] = (png_byte)unit_type;

   png_write_chunk(png_ptr, png_oFFs, buf, (png_uint_32)9);
}
#endif

#if defined(PNG_WRITE_tIME_SUPPORTED)
/* write the tIME chunk.  Use either png_convert_from_struct_tm()
   or png_convert_from_time_t(), or fill in the structure yourself */
void
png_write_tIME(png_structp png_ptr, png_timep mod_time)
{
   png_byte buf[7];

   if (mod_time->month  > 12 || mod_time->month  < 1 ||
       mod_time->day    > 31 || mod_time->day    < 1 ||
       mod_time->hour   > 23 || mod_time->second > 60)
   {
      png_warning(png_ptr, "Invalid time specified for tIME chunk");
      return;
   }

   png_save_uint_16(buf, mod_time->year);
   buf[2] = mod_time->month;
   buf[3] = mod_time->day;
   buf[4] = mod_time->hour;
   buf[5] = mod_time->minute;
   buf[6] = mod_time->second;

   png_write_chunk(png_ptr, png_tIME, buf, (png_uint_32)7);
}
#endif

/* initializes the row writing capability of libpng */
void
png_write_start_row(png_structp png_ptr)
{
   /* set up row buffer */
   png_ptr->row_buf = (png_bytep )png_large_malloc(png_ptr,
      (((png_uint_32)png_ptr->usr_channels *
      (png_uint_32)png_ptr->usr_bit_depth *
      png_ptr->width + 7) >> 3) + 1);
   png_ptr->row_buf[0] = 0;

   /* set up filtering buffer, if using this filter */
   if (png_ptr->do_filter & PNG_FILTER_SUB)
   {
      png_ptr->sub_row = (png_bytep )png_large_malloc(png_ptr,
         png_ptr->rowbytes + 1);
      png_ptr->sub_row[0] = 1;  /* Set the row filter type */
   }

   /* We only need to keep the previous row if we are using one of these */
   if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
   {
     /* set up previous row buffer */
      png_ptr->prev_row = (png_bytep )png_large_malloc(png_ptr,
         (((png_uint_32)png_ptr->usr_channels *
         (png_uint_32)png_ptr->usr_bit_depth *
         png_ptr->width + 7) >> 3) + 1);
      png_memset(png_ptr->prev_row, 0, (((png_uint_32)png_ptr->usr_channels *
         (png_uint_32)png_ptr->usr_bit_depth * png_ptr->width + 7) >> 3) + 1);

      if (png_ptr->do_filter & PNG_FILTER_UP)
      {
         png_ptr->up_row = (png_bytep )png_large_malloc(png_ptr,
            png_ptr->rowbytes + 1);
         png_ptr->up_row[0] = 2;  /* Set the row filter type */
      }

      if (png_ptr->do_filter & PNG_FILTER_AVG)
      {
         png_ptr->avg_row = (png_bytep )png_large_malloc(png_ptr,
            png_ptr->rowbytes + 1);
         png_ptr->avg_row[0] = 3;  /* Set the row filter type */
      }

      if (png_ptr->do_filter & PNG_FILTER_PAETH)
      {
         png_ptr->paeth_row = (png_bytep )png_large_malloc(png_ptr,
            png_ptr->rowbytes + 1);
         png_ptr->paeth_row[0] = 4;  /* Set the row filter type */
      }
   }

   /* if interlaced, we need to set up width and height of pass */
   if (png_ptr->interlaced)
   {
      if (!(png_ptr->transformations & PNG_INTERLACE))
      {
         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
            png_pass_ystart[0]) / png_pass_yinc[0];
         png_ptr->usr_width = (png_ptr->width +
            png_pass_inc[0] - 1 -
            png_pass_start[0]) /
            png_pass_inc[0];
      }
      else
      {
         png_ptr->num_rows = png_ptr->height;
         png_ptr->usr_width = png_ptr->width;
      }
   }
   else
   {
      png_ptr->num_rows = png_ptr->height;
      png_ptr->usr_width = png_ptr->width;
   }
   png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
   png_ptr->zstream->next_out = png_ptr->zbuf;
}

/* Internal use only.   Called when finished processing a row of data */
void
png_write_finish_row(png_structp png_ptr)
{
   int ret;

   /* next row */
   png_ptr->row_number++;

   /* see if we are done */
   if (png_ptr->row_number < png_ptr->num_rows)
      return;

⌨️ 快捷键说明

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