Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:57

0001 //
0002 // Copyright 2007-2008 Christian Henning, Andreas Pokorny, Lubomir Bourdev
0003 //
0004 // Distributed under the Boost Software License, Version 1.0
0005 // See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt
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) //assignment operator could not be generated
0026 #pragma warning(disable:4611) //interaction between '_setjmp' and C++ object destruction is non-portable
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 } // detail
0042 
0043 ///
0044 /// JPEG Writer
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         // In case of an error we'll jump back to here and fire an exception.
0085         // @todo Is the buffer above cleaned up when the exception is thrown?
0086         //       The strategy right now is to allocate necessary memory before
0087         //       the setjmp.
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         // Needs to be done after jpeg_set_defaults() since it's overridding this value back to slow.
0107         this->get()->dct_method = this->_info._dct_method;
0108 
0109 
0110         // set the pixel dimensions
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         // done reading header information
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 /// JPEG Dyamic Image Writer
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 } // gil
0179 } // boost
0180 
0181 #endif