TexturePNG.cc

Go to the documentation of this file.
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     /* Open the prospective PNG file. */
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     /* Read in some of the signature bytes */
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     /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature.
00024        Proceed if they match */
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     /* Create and initialize the png_struct. REQUIRED */
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     /* Allocate/initialize the memory for image information. REQUIRED. */
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     /* Set error handling if you are using the setjmp/longjmp method (this is
00050      * the normal method of doing things with libpng).  REQUIRED unless you
00051      * set up your own error handlers in the png_create_read_struct() earlier.
00052      */
00053 
00054     if (setjmp(png_jmpbuf(png_ptr))) {
00055         /* Free all of the memory associated with the png_ptr and info_ptr */
00056         png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
00057         fclose(fp);
00058         /* If we get here, we had a problem reading the file */
00059         fprintf(stderr,"TexturePNG::TexturePNG(): Error in PNG error handling\n");
00060         return;
00061     }
00062 
00063     /* Set up the input control if you are using standard C streams. REQUIRED*/
00064     png_init_io(png_ptr, fp);
00065 
00066     /* We have already read some of the signature */
00067     png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);
00068 
00069     /*
00070      * If you have enough memory to read in the entire image at once,
00071      * and you need to specify only transforms that can be controlled
00072      * with one of the PNG_TRANSFORM_* bits (this presently excludes
00073      * dithering, filling, setting background, and doing gamma
00074      * adjustment), then you can read the entire image (including
00075      * pixels) into the info structure with this call:
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      * At this point you have read the entire image
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     /* clean up after the read, and free any memory allocated - REQUIRED */
00100     png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
00101 
00102     /* close the file */
00103     fclose(fp);
00104 }
00105 #undef PNG_BYTES_TO_CHECK

Generated on Wed Jun 28 12:24:32 2006 for esg by  doxygen 1.4.6