00001 #include <esg/texture/TexturePNG.h>
00002 #include <png.h>
00003
00004 using namespace esg;
00005
00006 #define PNG_BYTES_TO_CHECK 4
00007 TexturePNG::TexturePNG(const char* path)
00008 {
00009
00010 FILE *fp = fopen(path, "rb");
00011 if (!fp) {
00012 fprintf(stderr,"TexturePNG::TexturePNG(): Unable to open file `%s'\n", path);
00013 return;
00014 }
00015
00016
00017 png_byte buf [PNG_BYTES_TO_CHECK];
00018 if (fread(buf, 1, PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK) {
00019 fprintf(stderr,"TexturePNG::TexturePNG(): Unable to read file `%s'\n", path);
00020 return;
00021 }
00022
00023
00024
00025 if (png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK)) {
00026 fprintf(stderr,"TexturePNG::TexturePNG(): File `%s' is not in PNG format\n", path);
00027 return;
00028 }
00029
00030
00031 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
00032 NULL, NULL, NULL);
00033 if (!png_ptr) {
00034 fclose(fp);
00035 fprintf(stderr,"TexturePNG::TexturePNG(): Error in PNG structure initialization\n");
00036 return;
00037 }
00038
00039
00040 png_infop info_ptr = png_create_info_struct(png_ptr);
00041 if (!info_ptr)
00042 {
00043 fclose(fp);
00044 png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
00045 fprintf(stderr,"TexturePNG::TexturePNG(): Error in PNG info initialization\n");
00046 return;
00047 }
00048
00049
00050
00051
00052
00053
00054 if (setjmp(png_jmpbuf(png_ptr))) {
00055
00056 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
00057 fclose(fp);
00058
00059 fprintf(stderr,"TexturePNG::TexturePNG(): Error in PNG error handling\n");
00060 return;
00061 }
00062
00063
00064 png_init_io(png_ptr, fp);
00065
00066
00067 png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 png_read_png(png_ptr, info_ptr,
00078 PNG_TRANSFORM_STRIP_16|PNG_TRANSFORM_PACKING|PNG_TRANSFORM_EXPAND,
00079 NULL);
00080
00081
00082
00083
00084
00085
00086
00087
00088 png_bytepp row_pointers = png_get_rows(png_ptr, info_ptr);
00089
00090 _allocate_texture(png_get_image_width(png_ptr, info_ptr),
00091 png_get_image_height(png_ptr, info_ptr));
00092
00093 for (register unsigned i = 0; i < _height; i++)
00094 for (register unsigned j = 0; j < _width; j++)
00095 _texture[i][j].set((float)row_pointers[i][3*j+0]/(float)0xFF,
00096 (float)row_pointers[i][3*j+1]/(float)0xFF,
00097 (float)row_pointers[i][3*j+2]/(float)0xFF);
00098
00099
00100 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
00101
00102
00103 fclose(fp);
00104 }
00105 #undef PNG_BYTES_TO_CHECK