IPNG.c
资源名称:ilib [点击查看]
上传用户:changbiao
上传日期:2007-01-13
资源大小:141k
文件大小:5k
源码类别:

图片显示

开发平台:

C/C++

  1. /*
  2.  * IPNG.c
  3.  *
  4.  * Image library
  5.  *
  6.  * Description:
  7.  * Implementation of read and write for PNG.
  8.  * Requires PNG library available at:
  9.  * http://www.cdrom.com/pub/png/pngcode.html
  10.  *
  11.  * Comments:
  12.  * Still need to implement 8-bit colormap support. (Currently
  13.  * all images are written out as truecolor which makes them a little
  14.  * larger.)
  15.  * Transparency, Alpha channels and interlacing are not yet
  16.  * supported when writing files.
  17.  *
  18.  * History:
  19.  *  01-Apr-00 Jim Winstead jimw@trainedmonkey.com
  20.  *  Fixed PNG output
  21.  * 19-Jul-99 Craig Knudsen cknudsen@radix.net
  22.  * Created
  23.  *
  24.  ****************************************************************************/
  25. #ifdef HAVE_PNGLIB
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <ctype.h>
  29. #include <memory.h>
  30. #include <png.h>
  31. #include "Ilib.h"
  32. #include "IlibP.h"
  33. IError _IWritePNG ( fp, image, options )
  34. FILE *fp;
  35. IImageP *image;
  36. IOptions options;
  37. {
  38.   png_structp png_ptr;
  39.   png_infop info_ptr;
  40.   png_text comment;
  41.   int row;
  42.   png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
  43.     (png_voidp) NULL, (png_error_ptr) NULL, (png_error_ptr) NULL );
  44.   if ( png_ptr == NULL )
  45.     return IPNGError;
  46.   info_ptr = png_create_info_struct ( png_ptr );
  47.   if ( setjmp ( png_ptr->jmpbuf ) )
  48.     return IPNGError;
  49.   png_init_io ( png_ptr, fp );
  50.   /* TODO: convert to 8-bit palette image instead of always using
  51.   ** full-color images.
  52.   */
  53.   /* set header info -- the 8 means 8 bits per color, not 8 bits per pixel */
  54.   png_set_IHDR ( png_ptr, info_ptr, image->width, image->height,
  55.     8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
  56.     PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE );
  57.   /* set comment */
  58.   if ( image->comments != NULL ) {
  59.     comment.compression = PNG_TEXT_COMPRESSION_NONE;
  60.     comment.key = "Comment";
  61.     comment.text = image->comments;
  62.     png_set_text ( png_ptr, info_ptr, &comment, 1 );
  63.   }
  64.   /* write header */
  65.   png_write_info ( png_ptr, info_ptr );
  66.   /* let libpng take care of bit-depth conversions */
  67.   /*png_set_packing ( png_ptr );*/
  68.   /* write out image, one row at a time
  69.   ** we have to convert to PNG's 16-bit format.
  70.   */
  71.   for ( row = 0; row < image->height; row++ ) {
  72.     png_write_row ( png_ptr, (image->data + image->width * row * 3));
  73.   }
  74.   png_write_end ( png_ptr, info_ptr );
  75.   fflush ( fp );
  76.   png_destroy_write_struct ( &png_ptr, (png_infopp)NULL );
  77.   return ( INoError );
  78. }
  79. IError _IReadPNG ( fp, options, image_return )
  80. FILE *fp;
  81. IOptions options;
  82. IImageP **image_return;
  83. {
  84.   IImageP *image = NULL;
  85.   png_structp png_ptr;
  86.   png_infop info_ptr;
  87.   png_uint_32 width, height;
  88.   int bit_depth, color_type, interlace_type, row;
  89.   png_bytep row_pointer;
  90.   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
  91.     (png_voidp) NULL, (png_error_ptr) NULL, (png_error_ptr) NULL );
  92.   if ( png_ptr == NULL )
  93.     return IPNGError;
  94.   /* Allocate/initialize the memory for image information.  REQUIRED. */
  95.   info_ptr = png_create_info_struct ( png_ptr );
  96.   if ( info_ptr == NULL ) {
  97.     png_destroy_read_struct ( &png_ptr, (png_infopp)NULL, (png_infopp)NULL );
  98.     return ( IPNGError );
  99.   }
  100.  
  101.   /* setup default error handling */
  102.   if ( setjmp ( png_ptr->jmpbuf ) ) {
  103.     /* Free all of the memory associated with the png_ptr and info_ptr */
  104.     png_destroy_read_struct ( &png_ptr, &info_ptr, (png_infopp)NULL );
  105.     return ( IPNGError );
  106.   }
  107.   png_init_io ( png_ptr, fp );
  108.   /* read header */
  109.   png_read_info ( png_ptr, info_ptr );
  110.   png_get_IHDR ( png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
  111.     &interlace_type, NULL, NULL );
  112.   image = (IImageP *) ICreateImage ( width, height, IOPTION_NONE );
  113.   /* Expand paletted colors into true RGB triplets */
  114.   if ( color_type == PNG_COLOR_TYPE_PALETTE )
  115.     png_set_expand ( png_ptr );
  116.   /* Strip alpha bytes from the input data without combining with the
  117.   ** background (not recommended).
  118.   */
  119.   png_set_strip_alpha ( png_ptr );
  120.   /* Read the image one line at a time.  That way we don't have to
  121.   ** malloc two images.
  122.   */
  123.   row_pointer = (png_bytep) png_malloc ( png_ptr,
  124.       png_get_rowbytes ( png_ptr, info_ptr ) );
  125.   row_pointer = (png_bytep) malloc ( image->width * 3 );
  126.   for ( row = 0; row < height; row++ ) {
  127.     png_read_rows ( png_ptr, &row_pointer, NULL, 1 );
  128.     memcpy ( image->data + ( row * image->width * 3 ),
  129.       row_pointer, ( image->width * 3 ) );
  130.   }
  131.   free ( row_pointer );
  132.   /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
  133.   png_read_end ( png_ptr, info_ptr );
  134.   /* clean up */
  135.   png_destroy_read_struct ( &png_ptr, &info_ptr, (png_infopp)NULL );
  136.   *image_return = image;
  137.   return ( INoError );
  138. }
  139. #endif /* HAVE_PNGLIB */