TuttleOFX  1
png_adds.hpp
Go to the documentation of this file.
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