Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //
0002 // Copyright 2010-2012 Kenneth Riddile, Christian Henning
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_TARGA_DETAIL_WRITE_HPP
0009 #define BOOST_GIL_EXTENSION_IO_TARGA_DETAIL_WRITE_HPP
0010 
0011 #include <boost/gil/extension/io/targa/tags.hpp>
0012 #include <boost/gil/extension/io/targa/detail/writer_backend.hpp>
0013 
0014 #include <boost/gil/io/base.hpp>
0015 #include <boost/gil/io/device.hpp>
0016 #include <boost/gil/io/detail/dynamic.hpp>
0017 
0018 #include <vector>
0019 
0020 namespace boost { namespace gil {
0021 
0022 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0023 #pragma warning(push)
0024 #pragma warning(disable:4512) //assignment operator could not be generated
0025 #endif
0026 
0027 namespace detail {
0028 
0029 template < int N > struct get_targa_view_type {};
0030 template <> struct get_targa_view_type< 3 > { using type = bgr8_view_t; };
0031 template <> struct get_targa_view_type< 4 > { using type = bgra8_view_t; };
0032 
0033 struct targa_write_is_supported
0034 {
0035     template< typename View >
0036     struct apply
0037         : public is_write_supported< typename get_pixel_type< View >::type
0038                                    , targa_tag
0039                                    >
0040     {};
0041 };
0042 
0043 } // detail
0044 
0045 ///
0046 /// TARGA Writer
0047 ///
0048 template< typename Device >
0049 class writer< Device
0050             , targa_tag
0051             >
0052     : public writer_backend< Device
0053                            , targa_tag
0054                            >
0055 {
0056 private:
0057     using backend_t = writer_backend<Device, targa_tag>;
0058 
0059 public:
0060 
0061     writer( const Device&                        io_dev
0062           , const image_write_info< targa_tag >& info
0063           )
0064     : backend_t( io_dev
0065                , info
0066                )
0067     {}
0068 
0069     template<typename View>
0070     void apply( const View& view )
0071     {
0072         write( view );
0073     }
0074 
0075 private:
0076 
0077     template< typename View >
0078     void write( const View& view )
0079     {
0080         uint8_t bit_depth = static_cast<uint8_t>( num_channels<View>::value * 8 );
0081 
0082         // write the TGA header
0083         this->_io_dev.write_uint8( 0 ); // offset
0084         this->_io_dev.write_uint8( targa_color_map_type::_rgb );
0085         this->_io_dev.write_uint8( targa_image_type::_rgb );
0086         this->_io_dev.write_uint16( 0 ); // color map start
0087         this->_io_dev.write_uint16( 0 ); // color map length
0088         this->_io_dev.write_uint8( 0 ); // color map depth
0089         this->_io_dev.write_uint16( 0 ); // x origin
0090         this->_io_dev.write_uint16( 0 ); // y origin
0091         this->_io_dev.write_uint16( static_cast<uint16_t>( view.width() ) ); // width in pixels
0092         this->_io_dev.write_uint16( static_cast<uint16_t>( view.height() ) ); // height in pixels
0093         this->_io_dev.write_uint8( bit_depth );
0094 
0095         if( 32 == bit_depth )
0096         {
0097             this->_io_dev.write_uint8( 8 ); // 8-bit alpha channel descriptor
0098         }
0099         else
0100         {
0101             this->_io_dev.write_uint8( 0 );
0102         }
0103 
0104         write_image< View
0105                    , typename detail::get_targa_view_type< num_channels< View >::value >::type
0106                    >( view );
0107     }
0108 
0109 
0110     template< typename View
0111             , typename TGA_View
0112             >
0113     void write_image( const View& view )
0114     {
0115         size_t row_size = view.width() * num_channels<View>::value;
0116         byte_vector_t buffer( row_size );
0117         std::fill( buffer.begin(), buffer.end(), 0 );
0118 
0119 
0120         TGA_View row = interleaved_view( view.width()
0121                                        , 1
0122                                        , reinterpret_cast<typename TGA_View::value_type*>( &buffer.front() )
0123                                        , row_size
0124                                        );
0125 
0126         for( typename View::y_coord_t y = view.height() - 1; y > -1; --y )
0127         {
0128             copy_pixels( subimage_view( view
0129                                       , 0
0130                                       , static_cast<int>( y )
0131                                       , static_cast<int>( view.width() )
0132                                       , 1
0133                                       )
0134                        , row
0135                        );
0136 
0137             this->_io_dev.write( &buffer.front(), row_size );
0138         }
0139 
0140     }
0141 };
0142 
0143 ///
0144 /// TARGA Dynamic Image Writer
0145 ///
0146 template< typename Device >
0147 class dynamic_image_writer< Device
0148                           , targa_tag
0149                           >
0150     : public writer< Device
0151                    , targa_tag
0152                    >
0153 {
0154     using parent_t = writer<Device, targa_tag>;
0155 
0156 public:
0157 
0158     dynamic_image_writer( const Device&                        io_dev
0159                         , const image_write_info< targa_tag >& info
0160                         )
0161     : parent_t( io_dev
0162               , info
0163               )
0164     {}
0165 
0166     template< typename ...Views >
0167     void apply( const any_image_view< Views... >& views )
0168     {
0169         detail::dynamic_io_fnobj< detail::targa_write_is_supported
0170                                 , parent_t
0171                                 > op( this );
0172 
0173         variant2::visit( op, views );
0174     }
0175 };
0176 
0177 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0178 #pragma warning(pop)
0179 #endif
0180 
0181 } // gil
0182 } // boost
0183 
0184 #endif