]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/gil/extension/io/targa/detail/write.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / gil / extension / io / targa / detail / write.hpp
1 //
2 // Copyright 2010-2012 Kenneth Riddile, Christian Henning
3 //
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
7 //
8 #ifndef BOOST_GIL_EXTENSION_IO_TARGA_DETAIL_WRITE_HPP
9 #define BOOST_GIL_EXTENSION_IO_TARGA_DETAIL_WRITE_HPP
10
11 #include <boost/gil/extension/io/targa/tags.hpp>
12 #include <boost/gil/extension/io/targa/detail/writer_backend.hpp>
13
14 #include <boost/gil/io/base.hpp>
15 #include <boost/gil/io/device.hpp>
16 #include <boost/gil/io/dynamic_io_new.hpp>
17
18 #include <vector>
19
20 namespace boost { namespace gil {
21
22 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
23 #pragma warning(push)
24 #pragma warning(disable:4512) //assignment operator could not be generated
25 #endif
26
27 namespace detail {
28
29 template < int N > struct get_targa_view_type {};
30 template <> struct get_targa_view_type< 3 > { using type = bgr8_view_t; };
31 template <> struct get_targa_view_type< 4 > { using type = bgra8_view_t; };
32
33 struct targa_write_is_supported
34 {
35 template< typename View >
36 struct apply
37 : public is_write_supported< typename get_pixel_type< View >::type
38 , targa_tag
39 >
40 {};
41 };
42
43 } // detail
44
45 ///
46 /// TARGA Writer
47 ///
48 template< typename Device >
49 class writer< Device
50 , targa_tag
51 >
52 : public writer_backend< Device
53 , targa_tag
54 >
55 {
56 private:
57 using backend_t = writer_backend<Device, targa_tag>;
58
59 public:
60
61 writer( const Device& io_dev
62 , const image_write_info< targa_tag >& info
63 )
64 : backend_t( io_dev
65 , info
66 )
67 {}
68
69 template<typename View>
70 void apply( const View& view )
71 {
72 write( view );
73 }
74
75 private:
76
77 template< typename View >
78 void write( const View& view )
79 {
80 uint8_t bit_depth = static_cast<uint8_t>( num_channels<View>::value * 8 );
81
82 // write the TGA header
83 this->_io_dev.write_uint8( 0 ); // offset
84 this->_io_dev.write_uint8( targa_color_map_type::_rgb );
85 this->_io_dev.write_uint8( targa_image_type::_rgb );
86 this->_io_dev.write_uint16( 0 ); // color map start
87 this->_io_dev.write_uint16( 0 ); // color map length
88 this->_io_dev.write_uint8( 0 ); // color map depth
89 this->_io_dev.write_uint16( 0 ); // x origin
90 this->_io_dev.write_uint16( 0 ); // y origin
91 this->_io_dev.write_uint16( static_cast<uint16_t>( view.width() ) ); // width in pixels
92 this->_io_dev.write_uint16( static_cast<uint16_t>( view.height() ) ); // height in pixels
93 this->_io_dev.write_uint8( bit_depth );
94
95 if( 32 == bit_depth )
96 {
97 this->_io_dev.write_uint8( 8 ); // 8-bit alpha channel descriptor
98 }
99 else
100 {
101 this->_io_dev.write_uint8( 0 );
102 }
103
104 write_image< View
105 , typename detail::get_targa_view_type< num_channels< View >::value >::type
106 >( view );
107 }
108
109
110 template< typename View
111 , typename TGA_View
112 >
113 void write_image( const View& view )
114 {
115 size_t row_size = view.width() * num_channels<View>::value;
116 byte_vector_t buffer( row_size );
117 std::fill( buffer.begin(), buffer.end(), 0 );
118
119
120 TGA_View row = interleaved_view( view.width()
121 , 1
122 , reinterpret_cast<typename TGA_View::value_type*>( &buffer.front() )
123 , row_size
124 );
125
126 for( typename View::y_coord_t y = view.height() - 1; y > -1; --y )
127 {
128 copy_pixels( subimage_view( view
129 , 0
130 , static_cast<int>( y )
131 , static_cast<int>( view.width() )
132 , 1
133 )
134 , row
135 );
136
137 this->_io_dev.write( &buffer.front(), row_size );
138 }
139
140 }
141 };
142
143 ///
144 /// TARGA Dynamic Image Writer
145 ///
146 template< typename Device >
147 class dynamic_image_writer< Device
148 , targa_tag
149 >
150 : public writer< Device
151 , targa_tag
152 >
153 {
154 using parent_t = writer<Device, targa_tag>;
155
156 public:
157
158 dynamic_image_writer( const Device& io_dev
159 , const image_write_info< targa_tag >& info
160 )
161 : parent_t( io_dev
162 , info
163 )
164 {}
165
166 template< typename ...Views >
167 void apply( const any_image_view< Views... >& views )
168 {
169 detail::dynamic_io_fnobj< detail::targa_write_is_supported
170 , parent_t
171 > op( this );
172
173 apply_operation( views, op );
174 }
175 };
176
177 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
178 #pragma warning(pop)
179 #endif
180
181 } // gil
182 } // boost
183
184 #endif