00001
00008 #ifndef __LIBPNG_HELPERS__
00009 #define __LIBPNG_HELPERS__
00010
00011 #include <png.h>
00012 #include <cstdio>
00013 #include <iostream>
00014 #include <fstream>
00015
00016 #define PNG_BYTES_TO_CHECK 8
00017
00018 using namespace std;
00019
00020
00021 int check_if_png(const char *file_name, FILE **fp)
00022 {
00023 png_byte buf[PNG_BYTES_TO_CHECK];
00024
00025
00026 if ((*fp = fopen(file_name, "rb")) == NULL)
00027 return 0;
00028
00029
00030 if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK)
00031 return 0;
00032
00033
00034
00035
00036 bool res = (!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK));
00037 fclose(*fp);
00038 return res;
00039 }
00040
00041 void read_png(const char* file_name,
00042 unsigned char*& buffer,
00043 int& width,
00044 int& height,
00045 int& channels,
00046 int& bit_depth,
00047 int& color_type,
00048 bool flip_vert)
00049
00050 {
00051 png_structp png_ptr;
00052 png_infop info_ptr;
00053
00054
00055 FILE *fp;
00056 bool check=check_if_png(file_name,&fp);
00057
00058 if (!check)
00059 {
00060 std::cerr << "This is not a PNG file !!" << endl;
00061 exit(1);
00062 }
00063
00064 fp=fopen(file_name, "rb");
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
00077 NULL, NULL, NULL);
00078
00079 if (png_ptr == NULL)
00080 {
00081 fclose(fp);
00082 std::cerr << "Error initializing png_ptr !" << endl;
00083 exit(1);
00084 }
00085
00086
00087 info_ptr = png_create_info_struct(png_ptr);
00088 if (info_ptr == NULL)
00089 {
00090 fclose(fp);
00091 png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
00092 std::cerr << "Error initializing info_ptr !" << endl;
00093 exit(1);
00094 }
00095
00096
00097
00098
00099
00100
00101 if (setjmp(png_jmpbuf(png_ptr)))
00102 {
00103
00104 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
00105 fclose(fp);
00106
00107 std::cerr << "Error initializing png_ptr !" << endl;
00108 exit(1);
00109 }
00110
00111 png_init_io(png_ptr, fp);
00112
00113
00114 png_set_sig_bytes(png_ptr,0);
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL);
00125
00126 width = png_get_image_width(png_ptr,
00127 info_ptr);
00128 height = png_get_image_height(png_ptr,
00129 info_ptr);
00130 channels = png_get_channels(png_ptr,
00131 info_ptr);
00132 bit_depth = png_get_bit_depth(png_ptr,info_ptr);
00133 color_type = png_get_color_type(png_ptr,info_ptr);
00134 png_uint_32 valid = 0;
00135 png_get_valid(png_ptr,info_ptr,valid);
00136
00137 png_bytep* row_pointers=(png_bytep*)malloc(height*sizeof(png_bytep));
00138 row_pointers=png_get_rows(png_ptr, info_ptr);
00139
00140
00141 const int c=width*channels*bit_depth/8;
00142 buffer=(unsigned char*)malloc(sizeof(unsigned char)*channels*width*height*bit_depth/8);
00143
00144 if (!flip_vert)
00145 {
00146 for (int y=0;y<height;++y)
00147 memcpy((void*)&(buffer[y*c]),(void*)(row_pointers[y]),c);
00148 }
00149 else
00150 {
00151 for (int y=0;y<height;++y)
00152 memcpy((void*)&(buffer[(height-1-y)*c]),(void*)(row_pointers[y]),c);
00153 }
00154
00155 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
00156 fclose(fp);
00157 }
00158
00159
00160
00161
00173 void write_png(const char *file_name, unsigned char* buffer,
00174 int width, int height, int channels,
00175 int bit_depth, png_uint_32 color_type,
00176 bool flip_vert)
00177 {
00178 FILE *fp;
00179 png_structp png_ptr;
00180 png_infop info_ptr;
00181
00182
00183
00184 fp = fopen(file_name, "wb");
00185 if (fp == NULL)
00186 {
00187 std::cerr << "Error opening file " << endl;
00188 }
00189
00190
00191
00192
00193
00194
00195
00196 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
00197 NULL,NULL,NULL);
00198
00199 if (png_ptr == NULL)
00200 {
00201 fclose(fp);
00202 std::cerr << "Error allocating png_ptr !!" << endl;
00203 exit(1);
00204 }
00205
00206
00207 info_ptr = png_create_info_struct(png_ptr);
00208 if (info_ptr == NULL)
00209 {
00210 fclose(fp);
00211 png_destroy_write_struct(&png_ptr, png_infopp_NULL);
00212 std::cerr << "Error allocating info ptr !!" << endl;
00213 exit(1);
00214 }
00215
00216
00217
00218
00219 if (setjmp(png_jmpbuf(png_ptr)))
00220 {
00221
00222 fclose(fp);
00223 png_destroy_write_struct(&png_ptr, &info_ptr);
00224 exit(1);
00225 }
00226
00227 png_init_io(png_ptr, fp);
00228
00229 png_set_IHDR(png_ptr, info_ptr, (png_uint_32)width, (png_uint_32) height,
00230 (png_byte) bit_depth, (png_byte) color_type, PNG_INTERLACE_NONE,
00231 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT );
00232
00233
00234
00235 png_bytep row_pointers[height];
00236 const int c=width*channels*bit_depth/8;
00237 if (!flip_vert)
00238 {
00239 for (int y=0;y<height;++y)
00240 {
00241 row_pointers[y]=(png_bytep) &(buffer[y*c]);
00242 }
00243 }
00244 else
00245 {
00246 for (int y=0;y<height;++y)
00247 {
00248 row_pointers[height-1-y]=(png_bytep) &(buffer[y*c]);
00249 }
00250 }
00251
00252
00253 png_set_rows(png_ptr, info_ptr, row_pointers);
00254 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL);
00255
00256 png_destroy_write_struct(&png_ptr, &info_ptr);
00257 fclose(fp);
00258 }
00259
00260 #endif