TuttleOFX
1
|
00001 #ifndef _PNG_ADDS_HPP 00002 #define _PNG_ADDS_HPP 00003 00004 #include <stdio.h> 00005 #include <string> 00006 00007 extern "C" { 00008 #include "png.h" 00009 } 00010 00011 #include <boost/static_assert.hpp> 00012 #include <boost/gil/gil_config.hpp> 00013 #include <boost/gil/utilities.hpp> 00014 #include <boost/gil/extension/io/io_error.hpp> 00015 #include <boost/gil/extension/io/png_io_private.hpp> 00016 00017 namespace boost { 00018 namespace gil { 00019 00020 namespace detail { 00021 00022 class png_reader_info : public file_mgr 00023 { 00024 protected: 00025 png_structp _png_ptr; 00026 png_infop _info_ptr; 00027 int bit_depth, color_type, interlace_type; 00028 00029 public: 00030 png_reader_info( const std::string& filename ) : file_mgr( filename.c_str(), "rb" ) { init(); } 00031 00032 void init() 00033 { 00034 char buf[PNG_BYTES_TO_CHECK]; 00035 00036 // read in some of the signature bytes 00037 io_error_if( fread( buf, 1, PNG_BYTES_TO_CHECK, get() ) != detail::PNG_BYTES_TO_CHECK, 00038 "png_check_validity: fail to read file" ); 00039 // compare the first PNG_BYTES_TO_CHECK bytes of the signature. 00040 io_error_if( png_sig_cmp( (png_bytep)buf, (png_size_t)0, detail::PNG_BYTES_TO_CHECK ) != 0, 00041 "png_check_validity: invalid png file" ); 00042 00043 _png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); 00044 io_error_if( _png_ptr == NULL, "png_get_file_size: fail to call png_create_write_struct()" ); 00045 // allocate/initialize the image information data 00046 _info_ptr = png_create_info_struct( _png_ptr ); 00047 if( _info_ptr == NULL ) 00048 { 00049 png_destroy_read_struct( &_png_ptr, png_infopp_NULL, png_infopp_NULL ); 00050 io_error( "png_get_file_size: fail to call png_create_info_struct()" ); 00051 } 00052 if( setjmp( png_jmpbuf( _png_ptr ) ) ) 00053 { 00054 //free all of the memory associated with the png_ptr and info_ptr 00055 png_destroy_read_struct( &_png_ptr, &_info_ptr, png_infopp_NULL ); 00056 io_error( "png_get_file_size: fail to call setjmp()" ); 00057 } 00058 png_init_io( _png_ptr, get() ); 00059 png_set_sig_bytes( _png_ptr, PNG_BYTES_TO_CHECK ); 00060 png_read_info( _png_ptr, _info_ptr ); 00061 if( little_endian() && png_get_bit_depth( _png_ptr, _info_ptr ) > 8 ) 00062 png_set_swap( _png_ptr ); 00063 } 00064 00065 virtual ~png_reader_info() 00066 { 00067 png_destroy_read_struct( &_png_ptr, &_info_ptr, png_infopp_NULL ); 00068 } 00069 00070 void read_header() 00071 { 00072 png_uint_32 width, height; 00073 00074 png_get_IHDR( _png_ptr, _info_ptr, 00075 &width, &height, &bit_depth, &color_type, &interlace_type, 00076 int_p_NULL, int_p_NULL ); 00077 } 00078 00079 int get_bit_depth() { return bit_depth; } 00080 int get_color_type() { return color_type; } 00081 int get_interlace_type() { return interlace_type; } 00082 }; 00083 00084 } 00085 00086 /// \ingroup PNG_IO 00087 /// \brief Returns the precision of the PNG file at the specified location. 00088 /// Throws std::ios_base::failure if the location does not correspond to a valid PNG file 00089 inline size_t png_read_precision( const std::string& filename ) 00090 { 00091 detail::png_reader_info m( filename ); 00092 00093 m.read_header(); 00094 return m.get_bit_depth(); 00095 } 00096 00097 00098 /// \ingroup PNG_IO 00099 /// \brief describes which color/alpha channels are present. 00100 /// PNG_COLOR_TYPE_GRAY (bit depths 1, 2, 4, 8, 16) 00101 /// PNG_COLOR_TYPE_GRAY_ALPHA (bit depths 8, 16) 00102 /// PNG_COLOR_TYPE_PALETTE (bit depths 1, 2, 4, 8) 00103 /// PNG_COLOR_TYPE_RGB (bit_depths 8, 16) 00104 /// PNG_COLOR_TYPE_RGB_ALPHA (bit_depths 8, 16) 00105 /// PNG_COLOR_MASK_PALETTE 00106 /// PNG_COLOR_MASK_COLOR 00107 /// PNG_COLOR_MASK_ALPHA 00108 inline size_t png_read_color_type( const std::string& filename ) 00109 { 00110 detail::png_reader_info m( filename ); 00111 00112 m.read_header(); 00113 return m.get_color_type(); 00114 } 00115 00116 } 00117 } 00118 00119 #endif /* _PNG_ADDS_HPP */ 00120