2 // Copyright 2007-2012 Christian Henning, Andreas Pokorny, Lubomir Bourdev
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
8 #ifndef BOOST_GIL_EXTENSION_IO_PNG_DETAIL_WRITE_HPP
9 #define BOOST_GIL_EXTENSION_IO_PNG_DETAIL_WRITE_HPP
11 #include <boost/gil/extension/io/png/detail/writer_backend.hpp>
13 #include <boost/gil/io/device.hpp>
14 #include <boost/gil/io/dynamic_io_new.hpp>
15 #include <boost/gil/io/row_buffer_helper.hpp>
16 #include <boost/gil/detail/mp11.hpp>
18 #include <type_traits>
20 namespace boost { namespace gil {
22 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
24 #pragma warning(disable:4512) //assignment operator could not be generated
29 struct png_write_is_supported
31 template< typename View >
33 : public is_write_supported< typename get_pixel_type< View >::type
44 template< typename Device >
48 : public writer_backend< Device
55 using backend_t = writer_backend<Device, png_tag>;
57 writer( const Device& io_dev
58 , const image_write_info< png_tag >& info
66 template< typename View >
67 void apply( const View& view )
69 io_error_if( view.width() == 0 && view.height() == 0
70 , "png format cannot handle empty views."
73 this->write_header( view );
76 , typename is_bit_aligned< typename View::value_type >::type()
82 template<typename View>
83 void write_view( const View& view
84 , std::false_type // is bit aligned
87 using pixel_t = typename get_pixel_type<View>::type;
89 using png_rw_info = detail::png_write_support
91 typename channel_type<pixel_t>::type,
92 typename color_space_type<pixel_t>::type
97 set_swap< png_rw_info >();
100 std::vector< pixel< typename channel_type< View >::type
101 , layout<typename color_space_type< View >::type >
103 > row_buffer( view.width() );
105 for( int y = 0; y != view.height(); ++ y)
107 std::copy( view.row_begin( y )
112 png_write_row( this->get_struct()
113 , reinterpret_cast< png_bytep >( row_buffer.data() )
117 png_write_end( this->get_struct()
122 template<typename View>
123 void write_view( const View& view
124 , std::true_type // is bit aligned
127 using png_rw_info = detail::png_write_support
129 typename kth_semantic_element_type<typename View::value_type, 0>::type,
130 typename color_space_type<View>::type
133 if (little_endian() )
135 set_swap< png_rw_info >();
138 detail::row_buffer_helper_view< View > row_buffer( view.width()
142 for( int y = 0; y != view.height(); ++y )
144 std::copy( view.row_begin( y )
149 png_write_row( this->get_struct()
150 , reinterpret_cast< png_bytep >( row_buffer.data() )
154 png_free_data( this->get_struct()
160 png_write_end( this->get_struct()
165 template<typename Info>
166 struct is_less_than_eight : mp11::mp_less
168 std::integral_constant<int, Info::_bit_depth>,
169 std::integral_constant<int, 8>
173 template<typename Info>
174 struct is_equal_to_sixteen : mp11::mp_less
176 std::integral_constant<int, Info::_bit_depth>,
177 std::integral_constant<int, 16>
181 template <typename Info>
182 void set_swap(typename std::enable_if<is_less_than_eight<Info>::value>::type* /*ptr*/ = 0)
184 png_set_packswap(this->get_struct());
187 template <typename Info>
188 void set_swap(typename std::enable_if<is_equal_to_sixteen<Info>::value>::type* /*ptr*/ = 0)
190 png_set_swap(this->get_struct());
193 template <typename Info>
195 typename std::enable_if
199 mp11::mp_not<is_less_than_eight<Info>>,
200 mp11::mp_not<is_equal_to_sixteen<Info>>
202 >::type* /*ptr*/ = nullptr)
208 /// PNG Dynamic Image Writer
210 template< typename Device >
211 class dynamic_image_writer< Device
214 : public writer< Device
218 using parent_t = writer<Device, png_tag>;
222 dynamic_image_writer( const Device& io_dev
223 , const image_write_info< png_tag >& info
230 template< typename Views >
231 void apply( const any_image_view< Views >& views )
233 detail::dynamic_io_fnobj< detail::png_write_is_supported
237 apply_operation( views, op );
241 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)