write_png.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:7k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * Dump an Image to a Portable Network Graphics (PNG) file
  3.  ****************************************************************************
  4.   Copyright (C) 2004 VideoLAN
  5.   Author: Rocky Bernstein
  6.  
  7.   This program is free software; you can redistribute it and/or modify
  8.   it under the terms of the GNU General Public License as published by
  9.   the Free Software Foundation; either version 2 of the License, or
  10.   (at your option) any later version.
  11.  
  12.   This program is distributed in the hope that it will be useful,
  13.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.   GNU General Public License for more details.
  16.  
  17.   You should have received a copy of the GNU General Public License
  18.   along with this program; if not, write to the Free Software
  19.   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  20.  *****************************************************************************/
  21. #include "config.h"
  22. #ifdef HAVE_LIBPNG
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include "write_png.h"
  26. #include <setjmp.h>
  27. typedef void (*snapshot_messenger_t)(char *message);
  28. #define _(x) x
  29. /*
  30.  *   Error functions for use as callbacks by the png libraries
  31.  */
  32. void error_msg(char *message) 
  33. {
  34.   printf("error: %sn", message);
  35. }
  36. void warning_msg(char *message) 
  37. {
  38.   printf("warning: %sn", message);
  39. }
  40. static snapshot_messenger_t error_msg_cb = error_msg;
  41. static snapshot_messenger_t warning_msg_cb  = warning_msg;
  42. static void 
  43. user_error_fn(png_structp png_ptr, png_const_charp error_msg)
  44. {
  45.   if(error_msg_cb) {
  46.     char uerror[4096]; 
  47.     memset(&uerror, 0, sizeof(uerror));
  48.     sprintf(uerror, _("Error: %sn"), error_msg);
  49.     error_msg_cb(uerror);
  50.   }
  51. }
  52. static void 
  53. user_warning_fn(png_structp png_ptr, png_const_charp warning_msg)
  54. {
  55.   if(error_msg_cb) {
  56.     char uerror[4096];
  57.     
  58.     memset(&uerror, 0, sizeof(uerror));
  59.     sprintf(uerror, _("Error: %sn"), warning_msg);
  60.     warning_msg_cb(uerror);
  61.   }
  62. }
  63. /* 
  64.    Dump an image to a Portable Network Graphics (PNG) file. File_name
  65.    is where the file goes, i_height and i_width are the height and
  66.    width in pixels of the image. The data for the image is stored as a
  67.    linear array of one byte for each of red, green, and blue
  68.    components of an RGB pixel. Thus row[i] will begin at rgb_image +
  69.    i*(i_width*3) and the blue pixel at image[i][0] would be rgb_image +
  70.    i*(i_width*3) + 1.
  71.    
  72.  */
  73. void 
  74. write_png(const char *file_name, png_uint_32 i_height, png_uint_32 i_width,
  75.   void *rgb_image, /*in*/ png_text *text_ptr, int i_text_count )
  76. {
  77.   FILE *fp;
  78.   png_structp png_ptr;
  79.   png_infop info_ptr;
  80.   png_color_8 sig_bit;
  81.   png_bytep *row_pointers;
  82.   unsigned int i,j;
  83.   /* open the file */
  84.   fp = fopen(file_name, "wb");
  85.   if (fp == NULL)
  86.     return;
  87.   
  88.   /* Create and initialize the png_struct with the desired error handler
  89.    * functions.  If you want to use the default stderr and longjump method,
  90.    * you can supply NULL for the last three parameters.  We also check that
  91.    * the library version is compatible with the one used at compile time,
  92.    * in case we are using dynamically linked libraries.  REQUIRED.
  93.    */
  94.   png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp) NULL,
  95.     user_error_fn, user_warning_fn);
  96.   
  97.   if (png_ptr == NULL)
  98.     {
  99.       fclose(fp);
  100.       return;
  101.     }
  102.   
  103.   /* Allocate/initialize the image information data.  REQUIRED */
  104.   info_ptr = png_create_info_struct(png_ptr);
  105.   if (info_ptr == NULL)
  106.     {
  107.       fclose(fp);
  108.       png_destroy_write_struct(&png_ptr,  (png_infopp)NULL);
  109.       return;
  110.     }
  111.   
  112.   /* Set error handling.  REQUIRED if you aren't supplying your own
  113.    * error handling functions in the png_create_write_struct() call.
  114.    */
  115.   if (setjmp(png_ptr->jmpbuf))
  116.     {
  117.       /* If we get here, we had a problem writing the file */
  118.       fclose(fp);
  119.       png_destroy_write_struct(&png_ptr,  (png_infopp) &info_ptr);
  120.       return;
  121.    }
  122.    /* Set up the output control using standard C streams. This
  123.       is required. */
  124.    png_init_io(png_ptr, fp);
  125.    /* Set the image information here.  i_width and i_height are up to 2^31,
  126.     * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
  127.     * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
  128.     * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
  129.     * or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
  130.     * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
  131.     * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
  132.     */
  133.    png_set_IHDR(png_ptr, info_ptr, i_width, i_height, 8, PNG_COLOR_TYPE_RGB,
  134. PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, 
  135. PNG_FILTER_TYPE_BASE);
  136.    /* For color images: */
  137.    sig_bit.red   = 8;
  138.    sig_bit.green = 8;
  139.    sig_bit.blue  = 8;
  140.    if (text_ptr)
  141.      png_set_text(png_ptr, info_ptr, text_ptr, i_text_count);
  142.    /* Write the file header information.  REQUIRED */
  143.    png_write_info(png_ptr, info_ptr);
  144.    /* Once we write out the header, the compression type on the text
  145.     * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or
  146.     * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again
  147.     * at the end.
  148.     */
  149.    /* Shift the pixels up to a legal bit depth and fill in
  150.     * as appropriate to correctly scale the image.
  151.     */
  152.    png_set_shift(png_ptr, &sig_bit);
  153.    /* pack pixels into bytes */
  154.    png_set_packing(png_ptr);
  155.    row_pointers = png_malloc(png_ptr, i_height*sizeof(png_bytep *));
  156.    for (i=0, j=0; i<i_height; i++, j+=i_width*3) {
  157.      row_pointers[i] = rgb_image + j; 
  158.    }
  159.    
  160.    png_set_rows   (png_ptr, info_ptr, row_pointers);
  161.    png_write_image(png_ptr, row_pointers);
  162.    /* You can write optional chunks like tEXt, zTXt, and tIME at the end
  163.     * as well.
  164.     */
  165.    /* It is REQUIRED to call this to finish writing the rest of the file */
  166.    png_write_end(png_ptr, info_ptr);
  167.    /* if you allocated any text comments, free them here */
  168.    /* free image data if allocated. */
  169.    /* clean up after the write, and free any memory allocated */
  170.    png_destroy_info_struct(png_ptr, &info_ptr);
  171.    /* clean up after the write, and free any memory allocated */
  172.    png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
  173.    fclose(fp);
  174.    return;
  175. }
  176. #ifdef STANDALONE
  177. int
  178. main(int argc, char **argv) 
  179. {
  180.   char image_data[3*16 * 3*16 * 3];
  181.   int i,j,k,l,m;
  182.   char r,g,b,t, or,og,ob;
  183.   or=0x00; og=0xFF; ob=0x0;
  184.   m=0;
  185.   for (i=0; i<3; i++) {
  186.     t=or; or=og; og=ob; ob=t;
  187.     for (j=0; j<16; j++) {
  188.       r=or; g=og; b=ob;
  189.       for (k=0; k<3; k++) {
  190. for (l=0; l<16; l++) {
  191.   image_data[m++]=r;
  192.   image_data[m++]=g;
  193.   image_data[m++]=b;
  194. }
  195. t=r; r=g; g=b; b=t;
  196.       }
  197.     }
  198.   }
  199.   
  200.   write_png("/tmp/pngtest.png", 3*16, 3*16, (void *) image_data) ;
  201.   return 0;
  202. }
  203. #endif /*STANDALONE*/
  204. #endif /*HAVE_LIBPNG*/