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