Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r65343 - in sandbox/gil/boost/gil/extension/io2: . detail
From: dsaritz_at_[hidden]
Date: 2010-09-07 15:12:53


Author: psiha
Date: 2010-09-07 15:12:51 EDT (Tue, 07 Sep 2010)
New Revision: 65343
URL: http://svn.boost.org/trac/boost/changeset/65343

Log:
Added the detail/shared.hpp header (currently contains only the BOOST_GIL_THROW_THROUGH_C_SUPPORTED macro definition).

Added BOOST_GIL_THROW_THROUGH_C_SUPPORTED support to the LibPNG backend.
Removed some comented out code.
Added custom error, warning, read and write functions/callbacks that together with the added support for PNG_NO_STDIO, PNG_NO_ERROR_TEXT and PNG_NO_WARNINGS enabled the removal of stdio-printf family of functions from the binary.
Added:
   sandbox/gil/boost/gil/extension/io2/detail/shared.hpp (contents, props changed)
Text files modified:
   sandbox/gil/boost/gil/extension/io2/libpng_image.hpp | 191 ++++++++++++++++++++++++++++-----------
   1 files changed, 134 insertions(+), 57 deletions(-)

Added: sandbox/gil/boost/gil/extension/io2/detail/shared.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/extension/io2/detail/shared.hpp 2010-09-07 15:12:51 EDT (Tue, 07 Sep 2010)
@@ -0,0 +1,45 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \file shared.hpp
+/// ----------------
+///
+/// Common functionality for all GIL::IO backends.
+///
+/// Copyright (c) Domagoj Saric 2010.
+///
+/// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
+/// (See accompanying file LICENSE_1_0.txt or copy at
+/// http://www.boost.org/LICENSE_1_0.txt)
+///
+/// For more information, see http://www.boost.org
+///
+////////////////////////////////////////////////////////////////////////////////
+//------------------------------------------------------------------------------
+#pragma once
+#ifndef shared_hpp__DA4F9174_EBAA_43E8_BEDD_A273BBA88CE7
+#define shared_hpp__DA4F9174_EBAA_43E8_BEDD_A273BBA88CE7
+//------------------------------------------------------------------------------
+namespace boost
+{
+//------------------------------------------------------------------------------
+namespace gil
+{
+//------------------------------------------------------------------------------
+namespace detail
+{
+//------------------------------------------------------------------------------
+
+#ifndef BOOST_GIL_THROW_THROUGH_C_SUPPORTED
+ #ifdef _MSC_VER
+ #define BOOST_GIL_THROW_THROUGH_C_SUPPORTED
+ #endif
+#endif
+
+//------------------------------------------------------------------------------
+} // namespace detail
+//------------------------------------------------------------------------------
+} // namespace gil
+//------------------------------------------------------------------------------
+} // namespace boost
+//------------------------------------------------------------------------------
+#endif // shared_hpp

Modified: sandbox/gil/boost/gil/extension/io2/libpng_image.hpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/libpng_image.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/libpng_image.hpp 2010-09-07 15:12:51 EDT (Tue, 07 Sep 2010)
@@ -20,10 +20,13 @@
 #include "formatted_image.hpp"
 #include "detail/io_error.hpp"
 #include "detail/libx_shared.hpp"
+#include "detail/shared.hpp"
 
 #include "png.h"
 
-#include <csetjmp>
+#ifndef BOOST_GIL_THROW_THROUGH_C_SUPPORTED
+ #include <csetjmp>
+#endif // BOOST_GIL_THROW_THROUGH_C_SUPPORTED
 #include <cstdlib>
 //------------------------------------------------------------------------------
 namespace boost
@@ -70,36 +73,8 @@
> libpng_supported_pixel_formats;
 
 
-
 typedef generic_vertical_roi libpng_roi;
 
-//...zzz...
-//class scoped_read_png_ptr
-//{
-//public:
-// scoped_read_png_ptr()
-// :
-// p_png_( ::png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ) )
-// {}
-// ~scoped_read_png_ptr()
-// {
-// ::png_destroy_read_struct( p_png_, NULL, NULL );
-// }
-//
-//private:
-// png_structp const p_png_;
-//};
-//
-//class scoped_png_info_ptr
-//{
-//public:
-// scoped_png_ptr( png_structp const p_png_ )
-//private:
-// ;
-// png_infop const p_info_;
-//};
-
-
 
 struct libpng_view_data_t
 {
@@ -152,6 +127,53 @@
     BOOST_STATIC_CONSTANT( bool , builtin_conversion = true );
 };
 
+
+
+inline void throw_libpng_error()
+{
+ boost::gil::detail::io_error( "LibPNG failure" );
+}
+
+
+inline void PNGAPI png_error_function( png_structp const png_ptr, png_const_charp const /*error_message*/ )
+{
+ #ifdef BOOST_GIL_THROW_THROUGH_C_SUPPORTED
+ throw_libpng_error();
+ boost::ignore_unused_variable_warning( png_ptr );
+ #else
+ longjmp( png_ptr->jmpbuf, 1 );
+ #endif // BOOST_GIL_THROW_THROUGH_C_SUPPORTED
+}
+
+
+inline void PNGAPI png_warning_function( png_structp, png_const_charp )
+{
+}
+
+//...zzz...this will blow-up at link-time when included in multiple .cpps unless it gets moved into a separate module...
+#ifdef PNG_NO_ERROR_TEXT
+ extern "C" void PNGAPI png_error( png_structp const png_ptr, png_const_charp const error_message )
+ {
+ png_error_function( png_ptr, error_message );
+ }
+
+ extern "C" void PNGAPI png_chunk_error( png_structp const png_ptr, png_const_charp const error_message )
+ {
+ png_error( png_ptr, error_message );
+ }
+#endif // PNG_NO_ERROR_TEXT
+
+#ifdef PNG_NO_WARNINGS
+ extern "C" void PNGAPI png_warning( png_structp const png_ptr, png_const_charp const error_message )
+ {
+ png_warning_function( png_ptr, error_message );
+ }
+
+ extern "C" void PNGAPI png_chunk_warning( png_structp const png_ptr, png_const_charp const error_message )
+ {
+ png_warning_function( png_ptr, error_message );
+ }
+#endif // PNG_NO_WARNINGS
 //------------------------------------------------------------------------------
 } // namespace detail
 
@@ -213,18 +235,52 @@
         return number_of_channels() * bit_depth() / 8;
     }
 
+private:
+ static void PNGAPI png_read_data( png_structp const png_ptr, png_bytep const data, png_size_t const length )
+ {
+ BOOST_ASSERT( png_ptr );
+
+ png_size_t const read_size
+ (
+ static_cast<png_size_t>( std::fread( data, 1, length, static_cast<FILE *>( png_ptr->io_ptr ) ) )
+ );
+
+ if ( read_size != length )
+ detail::png_error_function( png_ptr, "Read Error" );
+ }
+
+ static void PNGAPI png_write_data( png_structp const png_ptr, png_bytep const data, png_size_t const length )
+ {
+ BOOST_ASSERT( png_ptr );
+
+ png_size_t const written_size
+ (
+ static_cast<png_size_t>( std::fwrite( data, 1, length, static_cast<FILE *>( png_ptr->io_ptr ) ) )
+ );
+
+ if ( written_size != length )
+ detail::png_error_function( png_ptr, "Write Error" );
+ }
+
+ //static void png_flush_data( png_structp const png_ptr);
+
 public: /// \ingroup Construction
     explicit libpng_image( FILE & file )
         :
- p_png_ ( ::png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ) ),
- p_info_( ::png_create_info_struct( p_png_ ) )
+ p_png_ ( ::png_create_read_struct_2( PNG_LIBPNG_VER_STRING, NULL, &detail::png_error_function, &detail::png_warning_function, NULL, NULL, NULL ) ),
+ p_info_( ::png_create_info_struct ( p_png_ ) )
     {
         /// \todo Replace this manual logic with proper RAII guards.
         /// (03.09.2010.) (Domagoj Saric)
         if ( !p_png_ || !p_info_ )
             cleanup_and_throw_libpng_error();
 
- ::png_init_io( &png_object(), &file );
+ #ifdef PNG_NO_STDIO
+ ::png_set_read_fn( &png_object(), &file, &png_read_data );
+ #else
+ ::png_init_io( &png_object(), &file );
+ #endif
+ //..zzz...png_set_write_fn(png_structp write_ptr, voidp write_io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn);
 
         init();
     }
@@ -252,13 +308,15 @@
     friend class base_t;
 
     template <class MyView, class TargetView, class Converter>
- void generic_convert_to_prepared_view( TargetView const & view, Converter const & converter ) const
+ void generic_convert_to_prepared_view( TargetView const & view, Converter const & converter ) const throw(...)
     {
         std::size_t const row_length ( ::png_get_rowbytes( &png_object(), &info_object() ) );
- scoped_ptr<png_byte> const p_row_buffer( new png_byte[ row_length ] );
+ scoped_ptr<png_byte> const p_row_buffer( new png_byte[ row_length ] );
 
- if ( setjmp( error_handler_target() ) )
- throw_libpng_error();
+ #ifndef BOOST_GIL_THROW_THROUGH_C_SUPPORTED
+ if ( setjmp( error_handler_target() ) )
+ detail::throw_libpng_error();
+ #endif // BOOST_GIL_THROW_THROUGH_C_SUPPORTED
 
         unsigned int number_of_passes( ::png_set_interlace_handling( &png_object() ) );
         __assume( ( number_of_passes == 1 ) || ( number_of_passes == 7 ) );
@@ -273,7 +331,7 @@
         unsigned int const rows_to_read( detail::original_view( view ).dimensions().y );
         for ( unsigned int row_index( 0 ); row_index < rows_to_read; ++row_index )
         {
- ::png_read_row( &png_object(), p_row, NULL );
+ read_row( p_row );
 
             typedef typename MyView::value_type pixel_t;
 
@@ -340,10 +398,12 @@
         raw_copy_to_prepared_view( view_data );
     }
 
- void raw_copy_to_prepared_view( detail::libpng_view_data_t const view_data ) const
+ void raw_copy_to_prepared_view( detail::libpng_view_data_t const view_data ) const throw(...)
     {
- if ( setjmp( error_handler_target() ) )
- throw_libpng_error();
+ #ifndef BOOST_GIL_THROW_THROUGH_C_SUPPORTED
+ if ( setjmp( error_handler_target() ) )
+ detail::throw_libpng_error();
+ #endif // BOOST_GIL_THROW_THROUGH_C_SUPPORTED
 
         unsigned int number_of_passes( ::png_set_interlace_handling( &png_object() ) );
         __assume( ( number_of_passes == 1 ) || ( number_of_passes == 7 ) );
@@ -356,43 +416,52 @@
             png_byte const * const p_end( p_row + ( view_data.height_ * view_data.stride_ ) );
             while ( p_row < p_end )
             {
- ::png_read_row( &png_object(), p_row, NULL );
+ read_row( p_row );
                 memunit_advance( p_row, view_data.stride_ );
             }
         }
     }
 
 private:
- jmp_buf & error_handler_target() const { return png_object().jmpbuf; }
+ #ifndef BOOST_GIL_THROW_THROUGH_C_SUPPORTED
+ jmp_buf & error_handler_target() const { return png_object().jmpbuf; }
+ #endif // BOOST_GIL_THROW_THROUGH_C_SUPPORTED
 
- __declspec( noreturn )
- static void throw_libpng_error()
- {
- detail::io_error( "LibPNG failure" );
- }
-
- __declspec( noreturn )
     void cleanup_and_throw_libpng_error()
     {
         destroy_read_struct();
- throw_libpng_error ();
+ detail::throw_libpng_error();
     }
 
- void init()
+ void init() throw(...)
     {
- if ( setjmp( error_handler_target() ) )
- cleanup_and_throw_libpng_error();
+ #ifdef BOOST_GIL_THROW_THROUGH_C_SUPPORTED
+ try
+ {
+ #else
+ if ( setjmp( error_handler_target() ) )
+ cleanup_and_throw_libpng_error();
+ #endif // BOOST_GIL_THROW_THROUGH_C_SUPPORTED
+
+ ::png_read_info( &png_object(), &info_object() );
+ if ( little_endian() )
+ ::png_set_swap( &png_object() );
 
- ::png_read_info( &png_object(), &info_object() );
- if ( little_endian() )
- ::png_set_swap( &png_object() );
+ #ifdef BOOST_GIL_THROW_THROUGH_C_SUPPORTED
+ }
+ catch(...)
+ {
+ destroy_read_struct();
+ throw;
+ }
+ #endif // BOOST_GIL_THROW_THROUGH_C_SUPPORTED
     }
 
     void skip_rows( unsigned int number_of_rows_to_skip ) const
     {
         while ( number_of_rows_to_skip-- )
         {
- ::png_read_row( &png_object(), NULL, NULL );
+ read_row( NULL );
         }
     }
 
@@ -401,6 +470,14 @@
 
     void destroy_read_struct() { ::png_destroy_read_struct( &p_png_, &p_info_, NULL ); }
 
+ void read_row( png_byte * const p_row ) const
+ #ifdef BOOST_GIL_THROW_THROUGH_C_SUPPORTED
+ throw(...)
+ #endif // BOOST_GIL_THROW_THROUGH_C_SUPPORTED
+ {
+ ::png_read_row( &png_object(), p_row, NULL );
+ }
+
     png_struct & png_object() const
     {
         png_struct & png( *p_png_ );


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk