File indexing completed on 2025-01-18 09:36:59
0001
0002
0003
0004
0005
0006
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)
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 }
0044
0045
0046
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
0083 this->_io_dev.write_uint8( 0 );
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 );
0087 this->_io_dev.write_uint16( 0 );
0088 this->_io_dev.write_uint8( 0 );
0089 this->_io_dev.write_uint16( 0 );
0090 this->_io_dev.write_uint16( 0 );
0091 this->_io_dev.write_uint16( static_cast<uint16_t>( view.width() ) );
0092 this->_io_dev.write_uint16( static_cast<uint16_t>( view.height() ) );
0093 this->_io_dev.write_uint8( bit_depth );
0094
0095 if( 32 == bit_depth )
0096 {
0097 this->_io_dev.write_uint8( 8 );
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
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 }
0182 }
0183
0184 #endif