Allink  v0.1
ReadWritePng.cpp
00001 /*
00002  * Copyright 2002-2008 Guillaume Cottenceau.
00003  *
00004  * This software may be freely redistributed under the terms
00005  * of the X11 license.
00006  *
00007  */
00008 
00009 #include <unistd.h>
00010 #include <stdlib.h>
00011 #include <stdio.h>
00012 #include <string.h>
00013 #include <stdarg.h>
00014 
00015 #define PNG_DEBUG 3
00016 #include <png.h>
00017 
00018 void abort_(const char * s, ...)
00019 {
00020   va_list args;
00021   va_start(args, s);
00022   vfprintf(stderr, s, args);
00023   fprintf(stderr, "\n");
00024   va_end(args);
00025   abort();
00026 }
00027 
00028 int x, y;
00029 
00030 png_byte color_type;
00031 png_byte bit_depth;
00032 
00033 png_structp png_ptr;
00034 png_infop info_ptr;
00035 int number_of_passes;
00036 png_bytep * row_pointers;
00037 int width, height;
00038 
00039 void read_png_file(char* file_name)
00040 {
00041   png_byte header[8];   // 8 is the maximum size that can be checked
00042 
00043   /* open file and test for it being a png */
00044   FILE *fp = fopen(file_name, "rb");
00045   if (!fp)
00046     abort_("[read_png_file] File %s could not be opened for reading", file_name);
00047   fread(header, 1, 8, fp);
00048   if (png_sig_cmp(header, 0, 8))
00049     abort_("[read_png_file] File %s is not recognized as a PNG file", file_name);
00050 
00051 
00052   /* initialize stuff */
00053   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
00054    
00055   if (!png_ptr)
00056     abort_("[read_png_file] png_create_read_struct failed");
00057 
00058   info_ptr = png_create_info_struct(png_ptr);
00059   if (!info_ptr)
00060     abort_("[read_png_file] png_create_info_struct failed");
00061 
00062   if (setjmp(png_jmpbuf(png_ptr)))
00063     abort_("[read_png_file] Error during init_io");
00064 
00065   png_init_io(png_ptr, fp);
00066   png_set_sig_bytes(png_ptr, 8);
00067 
00068   png_read_info(png_ptr, info_ptr);
00069 
00070   width = info_ptr->width;
00071   height = info_ptr->height;
00072   color_type = info_ptr->color_type;
00073   bit_depth = info_ptr->bit_depth;
00074 
00075   number_of_passes = png_set_interlace_handling(png_ptr);
00076   png_read_update_info(png_ptr, info_ptr);
00077 
00078   printf("%d %d %d %d\n",width,height,color_type,bit_depth);
00079   /* read file */
00080   if (setjmp(png_jmpbuf(png_ptr)))
00081     abort_("[read_png_file] Error during read_image");
00082 
00083   row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
00084   for (y=0; y<height; y++)
00085     row_pointers[y] = (png_byte*) malloc(info_ptr->rowbytes);
00086 
00087   png_read_image(png_ptr, row_pointers);
00088 
00089   fclose(fp);
00090 }
00091 
00092 
00093 void write_png_file(char* file_name,png_bytep * row_pointers,int ImWidth,int ImHeight)
00094 {
00095   /* create file */
00096   FILE *fp = fopen(file_name, "wb");
00097   if (!fp)
00098     abort_("[write_png_file] File %s could not be opened for writing", file_name);
00099 
00100 
00101   /* initialize stuff */
00102   png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
00103    
00104   if (!png_ptr)
00105     abort_("[write_png_file] png_create_write_struct failed");
00106 
00107   info_ptr = png_create_info_struct(png_ptr);
00108   if (!info_ptr)
00109     abort_("[write_png_file] png_create_info_struct failed");
00110 
00111   if (setjmp(png_jmpbuf(png_ptr)))
00112     abort_("[write_png_file] Error during init_io");
00113 
00114   png_init_io(png_ptr, fp);
00115 
00116 
00117   /* write header */
00118   if (setjmp(png_jmpbuf(png_ptr)))
00119     abort_("[write_png_file] Error during writing header");
00120 
00121   png_set_IHDR(png_ptr, info_ptr, ImWidth, ImHeight,
00122           bit_depth, color_type, PNG_INTERLACE_NONE,
00123           PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
00124 
00125   png_write_info(png_ptr, info_ptr);
00126 
00127 
00128   /* write bytes */
00129   if (setjmp(png_jmpbuf(png_ptr)))
00130     abort_("[write_png_file] Error during writing bytes");
00131 
00132   png_write_image(png_ptr, row_pointers);
00133 
00134 
00135   /* end write */
00136   if (setjmp(png_jmpbuf(png_ptr)))
00137     abort_("[write_png_file] Error during end of write");
00138 
00139   png_write_end(png_ptr, NULL);
00140 
00141   /* cleanup heap allocation */
00142   for (y=0; y<ImHeight; y++)
00143     free(row_pointers[y]);
00144   free(row_pointers);
00145 
00146   fclose(fp);
00147 }
00148 
00149 
00150 void process_file(int height,int width)
00151 {
00152   if (info_ptr->color_type != PNG_COLOR_TYPE_RGBA)
00153     abort_("[process_file] color_type of input file must be PNG_COLOR_TYPE_RGBA (is %d)", info_ptr->color_type);
00154 
00155   for (y=0; y<height; y++) {
00156     png_byte* row = row_pointers[y];
00157     for (x=0; x<width; x++) {
00158       png_byte* ptr = &(row[x*4]);
00159       //printf("Pixel at position [ %d - %d ] has the following RGBA values: %d - %d - %d - %d\n",x, y, ptr[0], ptr[1], ptr[2], ptr[3]);
00160 
00161       /* set red value to 0 and green value to the blue one */
00162       ptr[0] = 0;
00163       ptr[1] = ptr[2];
00164     }
00165   }
00166 
00167 }
00168 
00169 
00170 int main(int argc, char **argv)
00171 {
00172   if (argc != 3)
00173     abort_("Usage: program_name <file_in> <file_out>");
00174 
00175   read_png_file(argv[1]);
00176   process_file(width,height);
00177   write_png_file(argv[2],row_pointers,width,height);
00178 
00179   return 0;
00180 }