File indexing completed on 2025-01-18 09:36:57
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_GIL_EXTENSION_IO_JPEG_DETAIL_WRITE_HPP
0009 #define BOOST_GIL_EXTENSION_IO_JPEG_DETAIL_WRITE_HPP
0010
0011 #include <boost/gil/extension/io/jpeg/tags.hpp>
0012 #include <boost/gil/extension/io/jpeg/detail/supported_types.hpp>
0013 #include <boost/gil/extension/io/jpeg/detail/writer_backend.hpp>
0014
0015 #include <boost/gil/io/base.hpp>
0016 #include <boost/gil/io/device.hpp>
0017 #include <boost/gil/io/detail/dynamic.hpp>
0018
0019 #include <vector>
0020
0021 namespace boost { namespace gil {
0022
0023 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0024 #pragma warning(push)
0025 #pragma warning(disable:4512)
0026 #pragma warning(disable:4611)
0027 #endif
0028
0029 namespace detail {
0030
0031 struct jpeg_write_is_supported
0032 {
0033 template< typename View >
0034 struct apply
0035 : public is_write_supported< typename get_pixel_type< View >::type
0036 , jpeg_tag
0037 >
0038 {};
0039 };
0040
0041 }
0042
0043
0044
0045
0046 template< typename Device >
0047 class writer< Device
0048 , jpeg_tag
0049 >
0050 : public writer_backend< Device
0051 , jpeg_tag
0052 >
0053 {
0054 public:
0055
0056 using backend_t = writer_backend<Device, jpeg_tag>;
0057
0058 public:
0059
0060 writer( const Device& io_dev
0061 , const image_write_info< jpeg_tag >& info
0062 )
0063 : backend_t( io_dev
0064 , info
0065 )
0066 {}
0067
0068 template<typename View>
0069 void apply( const View& view )
0070 {
0071 write_rows( view );
0072 }
0073
0074 private:
0075
0076 template<typename View>
0077 void write_rows( const View& view )
0078 {
0079 std::vector< pixel< typename channel_type< View >::type
0080 , layout<typename color_space_type< View >::type >
0081 >
0082 > row_buffer( view.width() );
0083
0084
0085
0086
0087
0088 if( setjmp( this->_mark )) { this->raise_error(); }
0089
0090 using channel_t = typename channel_type<typename View::value_type>::type;
0091
0092 this->get()->image_width = JDIMENSION( view.width() );
0093 this->get()->image_height = JDIMENSION( view.height() );
0094 this->get()->input_components = num_channels<View>::value;
0095 this->get()->in_color_space = detail::jpeg_write_support< channel_t
0096 , typename color_space_type< View >::type
0097 >::_color_space;
0098
0099 jpeg_set_defaults( this->get() );
0100
0101 jpeg_set_quality( this->get()
0102 , this->_info._quality
0103 , TRUE
0104 );
0105
0106
0107 this->get()->dct_method = this->_info._dct_method;
0108
0109
0110
0111 this->get()->density_unit = this->_info._density_unit;
0112 this->get()->X_density = this->_info._x_density;
0113 this->get()->Y_density = this->_info._y_density;
0114
0115
0116
0117 jpeg_start_compress( this->get()
0118 , TRUE
0119 );
0120
0121 JSAMPLE* row_addr = reinterpret_cast< JSAMPLE* >( &row_buffer[0] );
0122
0123 for( int y =0; y != view.height(); ++ y )
0124 {
0125 std::copy( view.row_begin( y )
0126 , view.row_end ( y )
0127 , row_buffer.begin()
0128 );
0129
0130 jpeg_write_scanlines( this->get()
0131 , &row_addr
0132 , 1
0133 );
0134 }
0135
0136 jpeg_finish_compress ( this->get() );
0137 }
0138 };
0139
0140
0141
0142
0143 template< typename Device >
0144 class dynamic_image_writer< Device
0145 , jpeg_tag
0146 >
0147 : public writer< Device
0148 , jpeg_tag
0149 >
0150 {
0151 using parent_t = writer<Device, jpeg_tag>;
0152
0153 public:
0154
0155 dynamic_image_writer( const Device& io_dev
0156 , const image_write_info< jpeg_tag >& info
0157 )
0158 : parent_t( io_dev
0159 , info
0160 )
0161 {}
0162
0163 template< typename ...Views >
0164 void apply( const any_image_view< Views... >& views )
0165 {
0166 detail::dynamic_io_fnobj< detail::jpeg_write_is_supported
0167 , parent_t
0168 > op( this );
0169
0170 variant2::visit( op, views );
0171 }
0172 };
0173
0174 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0175 #pragma warning(pop)
0176 #endif
0177
0178 }
0179 }
0180
0181 #endif