Boost GIL


row_buffer_helper.hpp
1 //
2 // Copyright 2007-2008 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_IO_ROW_BUFFER_HELPER_HPP
9 #define BOOST_GIL_IO_ROW_BUFFER_HELPER_HPP
10 
11 // TODO: Shall we move toolbox to core?
12 #include <boost/gil/extension/toolbox/metafunctions/is_bit_aligned.hpp>
13 #include <boost/gil/extension/toolbox/metafunctions/is_homogeneous.hpp>
14 #include <boost/gil/extension/toolbox/metafunctions/pixel_bit_size.hpp>
15 
16 #include <boost/gil/io/typedefs.hpp>
17 
18 #include <boost/mpl/and.hpp>
19 
20 #include <cstddef>
21 #include <type_traits>
22 #include <vector>
23 
24 namespace boost { namespace gil { namespace detail {
25 
26 template< typename Pixel
27  , typename DummyT = void
28  >
29 struct row_buffer_helper
30 {
31  using element_t = Pixel;
32  using buffer_t = std::vector<element_t>;
33  using iterator_t = typename buffer_t::iterator;
34 
35  row_buffer_helper( std::size_t width
36  , bool
37  )
38  : _row_buffer( width )
39  {}
40 
41  element_t* data() { return &_row_buffer[0]; }
42 
43  iterator_t begin() { return _row_buffer.begin(); }
44  iterator_t end() { return _row_buffer.end(); }
45 
46  buffer_t& buffer() { return _row_buffer; }
47 
48 private:
49 
50  buffer_t _row_buffer;
51 };
52 
53 template <typename Pixel>
54 struct row_buffer_helper
55 <
56  Pixel,
57  typename std::enable_if
58  <
59  is_bit_aligned<Pixel>::value
60  >::type
61 >
62 {
63  using element_t = byte_t;
64  using buffer_t = std::vector<element_t>;
65  using pixel_type = Pixel;
66  using iterator_t = bit_aligned_pixel_iterator<pixel_type>;
67 
68  row_buffer_helper(std::size_t width, bool in_bytes)
69  : _c{( width * pixel_bit_size< pixel_type >::value) >> 3}
70  , _r{width * pixel_bit_size< pixel_type >::value - (_c << 3)}
71  {
72  if (in_bytes)
73  {
74  _row_buffer.resize(width);
75  }
76  else
77  {
78  // add one byte if there are remaining bits
79  _row_buffer.resize(_c + (_r != 0));
80  }
81  }
82 
83  element_t* data() { return &_row_buffer[0]; }
84 
85  iterator_t begin() { return iterator_t( &_row_buffer.front(),0 ); }
86  iterator_t end() { return _r == 0 ? iterator_t( &_row_buffer.back() + 1, 0 )
87  : iterator_t( &_row_buffer.back() , (int) _r );
88  }
89 
90  buffer_t& buffer() { return _row_buffer; }
91 
92 private:
93 
94  // For instance 25 pixels of rgb2 type would be:
95  // overall 25 pixels * 3 channels * 2 bits/channel = 150 bits
96  // c = 18 bytes
97  // r = 6 bits
98 
99  std::size_t _c; // number of full bytes
100  std::size_t _r; // number of remaining bits
101 
102  buffer_t _row_buffer;
103 };
104 
105 template<typename Pixel>
106 struct row_buffer_helper
107 <
108  Pixel,
109  typename std::enable_if
110  <
111  mpl::and_
112  <
113  typename is_bit_aligned<Pixel>::type,
114  typename is_homogeneous<Pixel>::type
115  >::value
116  >
117 >
118 {
119  using element_t = byte_t;
120  using buffer_t = std::vector<element_t>;
121  using pixel_type = Pixel;
122  using iterator_t = bit_aligned_pixel_iterator<pixel_type>;
123 
124  row_buffer_helper( std::size_t width
125  , bool in_bytes
126  )
127  : _c( ( width
128  * num_channels< pixel_type >::value
129  * channel_type< pixel_type >::type::num_bits
130  )
131  >> 3
132  )
133 
134  , _r( width
135  * num_channels< pixel_type >::value
136  * channel_type< pixel_type >::type::num_bits
137  - ( _c << 3 )
138  )
139  {
140  if( in_bytes )
141  {
142  _row_buffer.resize( width );
143  }
144  else
145  {
146  // add one byte if there are remaining bits
147  _row_buffer.resize( _c + ( _r!=0 ));
148  }
149  }
150 
151  element_t* data() { return &_row_buffer[0]; }
152 
153  iterator_t begin() { return iterator_t( &_row_buffer.front(),0 ); }
154  iterator_t end() { return _r == 0 ? iterator_t( &_row_buffer.back() + 1, 0 )
155  : iterator_t( &_row_buffer.back() , (int) _r );
156  }
157 
158  buffer_t& buffer() { return _row_buffer; }
159 
160 private:
161 
162  // For instance 25 pixels of rgb2 type would be:
163  // overall 25 pixels * 3 channels * 2 bits/channel = 150 bits
164  // c = 18 bytes
165  // r = 6 bits
166 
167  std::size_t _c; // number of full bytes
168  std::size_t _r; // number of remaining bits
169 
170  buffer_t _row_buffer;
171 };
172 
173 template <typename View, typename D = void>
174 struct row_buffer_helper_view : row_buffer_helper<typename View::value_type>
175 {
176  row_buffer_helper_view(std::size_t width, bool in_bytes)
177  : row_buffer_helper<typename View::value_type>(width, in_bytes)
178  {}
179 };
180 
181 template <typename View>
182 struct row_buffer_helper_view
183 <
184  View,
185  typename std::enable_if
186  <
187  is_bit_aligned<typename View::value_type>::value
188  >::type
189 > : row_buffer_helper<typename View::reference>
190 {
191  row_buffer_helper_view(std::size_t width, bool in_bytes)
192  : row_buffer_helper<typename View::reference>(width, in_bytes)
193  {}
194 };
195 
196 } // namespace detail
197 } // namespace gil
198 } // namespace boost
199 
200 #endif
Definition: algorithm.hpp:30
Definition: algorithm.hpp:127