00001 /* 00002 This file is part of magpar. 00003 00004 Copyright (C) 2002-2010 Werner Scholz 00005 00006 www: http://www.magpar.net/ 00007 email: magpar(at)magpar.net 00008 00009 magpar is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 2 of the License, or 00012 (at your option) any later version. 00013 00014 magpar is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with magpar; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 */ 00023 00024 static char const Id[] = "$Id: writepng.c 2987 2010-03-01 17:45:38Z scholz $\n\n"; 00025 static char const Td[] = "$Today: " __FILE__ " " __DATE__ " " __TIME__ " $\n\n"; 00026 00027 00028 #include "writepng.h" 00029 00030 /* for getpwuid 00031 EXTERN_C_BEGIN 00032 #include <pwd.h> 00033 #include <sys/types.h> 00034 #include <unistd.h> 00035 EXTERN_C_END 00036 */ 00037 00038 00039 int WritePNGfile(char *file_name, int width, int height, png_bytepp image, char *desc) 00040 { 00041 FILE *fp; 00042 png_structp png_ptr; 00043 png_infop info_ptr; 00044 png_text text_ptr[3]; 00045 int bit_depth=8; 00046 png_color_16 vtrans_values; 00047 00048 /* 00049 struct passwd *t_passwd; 00050 */ 00051 00052 MagparFunctionInfoBegin; 00053 00054 int rank,size; 00055 ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); 00056 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 00057 00058 if (rank) { 00059 MagparFunctionInfoReturn(0); 00060 } 00061 00062 /* code template taken from example.c supplied with libpng */ 00063 00064 /* open the file */ 00065 fp = fopen(file_name, "wb"); 00066 if (fp == NULL) 00067 return (1); 00068 00069 /* Create and initialize the png_struct with the desired error handler 00070 * functions. If you want to use the default stderr and longjump method, 00071 * you can supply NULL for the last three parameters. We also check that 00072 * the library version is compatible with the one used at compile time, 00073 * in case we are using dynamically linked libraries. REQUIRED. 00074 */ 00075 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 00076 NULL, NULL, NULL); 00077 00078 if (png_ptr == NULL) 00079 { 00080 fclose(fp); 00081 return (1); 00082 } 00083 00084 /* Allocate/initialize the image information data. REQUIRED */ 00085 info_ptr = png_create_info_struct(png_ptr); 00086 if (info_ptr == NULL) 00087 { 00088 fclose(fp); 00089 png_destroy_write_struct(&png_ptr, NULL); 00090 return (1); 00091 } 00092 00093 /* Set error handling. REQUIRED if you aren't supplying your own 00094 * error handling functions in the png_create_write_struct() call. 00095 */ 00096 if (setjmp(png_jmpbuf(png_ptr))) 00097 { 00098 /* If we get here, we had a problem reading the file */ 00099 fclose(fp); 00100 png_destroy_write_struct(&png_ptr, &info_ptr); 00101 return (1); 00102 } 00103 00104 /* One of the following I/O initialization functions is REQUIRED */ 00105 /* set up the output control if you are using standard C streams */ 00106 png_init_io(png_ptr, fp); 00107 00108 /* This is the hard way */ 00109 00110 /* Set the image information here. Width and height are up to 2^31, 00111 * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on 00112 * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, 00113 * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, 00114 * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or 00115 * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST 00116 * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED 00117 */ 00118 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_RGB, 00119 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 00120 00121 00122 /* 00123 t_passwd=getpwuid(geteuid()); 00124 */ 00125 /* Optionally write comments into the image */ 00126 text_ptr[0].key = (png_charp)"Title"; 00127 text_ptr[0].text = file_name; 00128 text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE; 00129 text_ptr[1].key = (png_charp)"Author"; 00130 text_ptr[1].text = (png_charp)"unknown"; 00131 /* 00132 text_ptr[1].text = t_passwd->pw_name; 00133 */ 00134 text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE; 00135 text_ptr[2].key = (char*)"Description"; 00136 text_ptr[2].text = desc; 00137 text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt; 00138 png_set_text(png_ptr, info_ptr, text_ptr, 3); 00139 00140 /* other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs, */ 00141 /* note that if sRGB is present the gAMA and cHRM chunks must be ignored 00142 * on read and must be written in accordance with the sRGB profile */ 00143 00144 vtrans_values.red= 255; 00145 vtrans_values.green=255; 00146 vtrans_values.blue= 255; 00147 png_set_tRNS(png_ptr, info_ptr, NULL, 1, &vtrans_values); 00148 00149 /* Write the file header information. REQUIRED */ 00150 png_write_info(png_ptr, info_ptr); 00151 00152 /* If you want, you can write the info in two steps, in case you need to 00153 * write your private chunk ahead of PLTE: 00154 * 00155 * png_write_info_before_PLTE(write_ptr, write_info_ptr); 00156 * write_my_chunk(); 00157 * png_write_info(png_ptr, info_ptr); 00158 * 00159 * However, given the level of known- and unknown-chunk support in 1.1.0 00160 * and up, this should no longer be necessary. 00161 */ 00162 00163 /* Once we write out the header, the compression type on the text 00164 * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or 00165 * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again 00166 * at the end. 00167 */ 00168 00169 /* set up the transformations you want. Note that these are 00170 * all optional. Only call them if you want them. 00171 */ 00172 00173 /* The easiest way to write the image (you may have a different memory 00174 * layout, however, so choose what fits your needs best). You need to 00175 * use the first method if you aren't handling interlacing yourself. 00176 */ 00177 00178 /* One of the following output methods is REQUIRED */ 00179 png_write_image(png_ptr, image); 00180 00181 /* You can write optional chunks like tEXt, zTXt, and tIME at the end 00182 * as well. Shouldn't be necessary in 1.1.0 and up as all the public 00183 * chunks are supported and you can use png_set_unknown_chunks() to 00184 * register unknown chunks into the info structure to be written out. 00185 */ 00186 00187 /* It is REQUIRED to call this to finish writing the rest of the file */ 00188 png_write_end(png_ptr, info_ptr); 00189 00190 /* clean up after the write, and free any memory allocated */ 00191 png_destroy_write_struct(&png_ptr, &info_ptr); 00192 00193 /* close the file */ 00194 fclose(fp); 00195 00196 00197 MagparFunctionInfoReturn(0); 00198 } 00199