9 #ifndef BOOST_GIL_BIT_ALIGNED_PIXEL_REFERENCE_HPP 10 #define BOOST_GIL_BIT_ALIGNED_PIXEL_REFERENCE_HPP 12 #include <boost/gil/pixel.hpp> 13 #include <boost/gil/channel.hpp> 14 #include <boost/gil/detail/mp11.hpp> 16 #include <boost/assert.hpp> 17 #include <boost/config.hpp> 20 #include <type_traits> 22 namespace boost {
namespace gil {
33 template <
int RangeSize,
bool IsMutable>
36 using byte_t = mp11::mp_if_c<IsMutable, unsigned char, unsigned char const>;
37 using difference_type = std::ptrdiff_t;
38 template <
int RS,
bool M>
friend class bit_range;
40 byte_t* _current_byte;
44 bit_range() : _current_byte(
nullptr), _bit_offset(0) {}
45 bit_range(byte_t* current_byte,
int bit_offset)
46 : _current_byte(current_byte)
47 , _bit_offset(bit_offset)
49 BOOST_ASSERT(bit_offset >= 0 && bit_offset < 8);
52 bit_range(
const bit_range& br) : _current_byte(br._current_byte), _bit_offset(br._bit_offset) {}
55 bit_range& operator=(
const bit_range& br) { _current_byte = br._current_byte; _bit_offset=br._bit_offset;
return *
this; }
56 bool operator==(
const bit_range& br)
const {
return _current_byte==br._current_byte && _bit_offset==br._bit_offset; }
59 _current_byte += (_bit_offset+RangeSize) / 8;
60 _bit_offset = (_bit_offset+RangeSize) % 8;
63 bit_range& operator--() { bit_advance(-RangeSize);
return *
this; }
65 void bit_advance(difference_type num_bits) {
66 int new_offset = int(_bit_offset+num_bits);
67 _current_byte += new_offset / 8;
68 _bit_offset = new_offset % 8;
74 difference_type bit_distance_to(
const bit_range& b)
const {
75 return (b.current_byte() - current_byte())*8 + b.bit_offset()-bit_offset();
77 byte_t* current_byte()
const {
return _current_byte; }
78 int bit_offset()
const {
return _bit_offset; }
114 template <
typename BitField,
typename ChannelBitSizes,
typename Layout,
bool IsMutable>
115 struct bit_aligned_pixel_reference
117 static constexpr
int bit_size =
121 std::integral_constant<int, 0>,
126 using bitfield_t = BitField;
127 using data_ptr_t = mp11::mp_if_c<IsMutable, unsigned char*, const unsigned char*>;
129 using layout_t = Layout;
132 using reference =
const bit_aligned_pixel_reference<BitField, ChannelBitSizes, Layout, IsMutable>;
133 using const_reference = bit_aligned_pixel_reference<BitField,ChannelBitSizes,Layout,false>
const;
135 static constexpr
bool is_mutable = IsMutable;
137 bit_aligned_pixel_reference(){}
138 bit_aligned_pixel_reference(data_ptr_t data_ptr,
int bit_offset) : _bit_range(data_ptr, bit_offset) {}
139 explicit bit_aligned_pixel_reference(
const bit_range_t& bit_range) : _bit_range(bit_range) {}
140 template <
bool IsMutable2> bit_aligned_pixel_reference(
const bit_aligned_pixel_reference<BitField,ChannelBitSizes,Layout,IsMutable2>& p) : _bit_range(p._bit_range) {}
143 explicit bit_aligned_pixel_reference(
typename kth_element_type<bit_aligned_pixel_reference,0>::type
const channel0)
144 : _bit_range(static_cast<data_ptr_t>(&channel0), channel0.first_bit())
146 static_assert(num_channels<bit_aligned_pixel_reference>::value == 1,
"");
150 bit_aligned_pixel_reference(bit_aligned_pixel_reference
const& p)
151 : _bit_range(p._bit_range) {}
154 template <
typename BF,
typename CR>
155 bit_aligned_pixel_reference(packed_pixel<BF, CR, Layout>& p)
156 : _bit_range(static_cast<data_ptr_t>(&gil::
at_c<0>(p)), gil::
at_c<0>(p).first_bit())
158 check_compatible<packed_pixel<BF, CR, Layout>>();
161 auto operator=(bit_aligned_pixel_reference
const& p)
const 162 -> bit_aligned_pixel_reference
const&
164 static_copy(p, *
this);
168 template <
typename P>
169 auto operator=(P
const& p)
const -> bit_aligned_pixel_reference
const&
171 assign(p, is_pixel<P>());
175 template <
typename P>
176 bool operator==(P
const& p)
const 178 return equal(p, is_pixel<P>());
181 template <
typename P>
182 bool operator!=(P
const& p)
const {
return !(*
this==p); }
184 auto operator->() const -> bit_aligned_pixel_reference const* {
return this; }
186 bit_range_t
const& bit_range()
const {
return _bit_range; }
189 mutable bit_range_t _bit_range;
190 template <
typename B,
typename C,
typename L,
bool M>
friend struct bit_aligned_pixel_reference;
192 template <
typename Pixel>
static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel,bit_aligned_pixel_reference> >(); }
194 template <
typename Pixel>
195 void assign(Pixel
const& p, std::true_type)
const 197 check_compatible<Pixel>();
198 static_copy(p, *
this);
201 template <
typename Pixel>
202 bool equal(Pixel
const& p, std::true_type)
const 204 check_compatible<Pixel>();
205 return static_equal(*
this, p);
209 static void check_gray()
211 static_assert(std::is_same<typename Layout::color_space_t, gray_t>::value,
"");
214 template <
typename Channel>
215 void assign(Channel
const& channel, std::false_type)
const 218 gil::at_c<0>(*
this) = channel;
221 template <
typename Channel>
222 bool equal (Channel
const& channel, std::false_type)
const 225 return gil::at_c<0>(*
this) == channel;
233 template <
typename BitField,
typename ChannelBitSizes,
typename L,
bool IsMutable,
int K>
234 struct kth_element_type
236 bit_aligned_pixel_reference<BitField, ChannelBitSizes, L, IsMutable>,
240 using type = packed_dynamic_channel_reference
243 mp11::mp_at_c<ChannelBitSizes, K>::value,
248 template <
typename B,
typename C,
typename L,
bool M,
int K>
249 struct kth_element_reference_type<bit_aligned_pixel_reference<B,C,L,M>, K>
250 :
public kth_element_type<bit_aligned_pixel_reference<B,C,L,M>, K> {};
252 template <
typename B,
typename C,
typename L,
bool M,
int K>
253 struct kth_element_const_reference_type<bit_aligned_pixel_reference<B,C,L,M>, K>
254 :
public kth_element_type<bit_aligned_pixel_reference<B,C,L,M>, K> {};
259 template <
typename IntegralVector,
int K>
263 sum_k<IntegralVector, K - 1>,
264 typename mp11::mp_at_c<IntegralVector, K - 1>::type
268 template <
typename IntegralVector>
269 struct sum_k<IntegralVector, 0> : std::integral_constant<int, 0> {};
274 template <
int K,
typename BitField,
typename ChannelBitSizes,
typename L,
bool IsMutable>
276 auto at_c(
const bit_aligned_pixel_reference<BitField, ChannelBitSizes, L, IsMutable>& p)
277 ->
typename kth_element_reference_type<bit_aligned_pixel_reference<BitField, ChannelBitSizes, L, IsMutable>, K>::type
279 using pixel_t = bit_aligned_pixel_reference<BitField, ChannelBitSizes, L, IsMutable>;
280 using channel_t =
typename kth_element_reference_type<pixel_t, K>::type;
281 using bit_range_t =
typename pixel_t::bit_range_t;
283 bit_range_t bit_range(p.bit_range());
284 bit_range.bit_advance(detail::sum_k<ChannelBitSizes, K>::value);
286 return channel_t(bit_range.current_byte(), bit_range.bit_offset());
294 template <
typename B,
typename C,
typename L,
bool M>
295 struct is_pixel<bit_aligned_pixel_reference<B, C, L, M> > : std::true_type {};
301 template <
typename B,
typename C,
typename L,
bool M>
302 struct color_space_type<bit_aligned_pixel_reference<B, C, L, M>>
304 using type =
typename L::color_space_t;
307 template <
typename B,
typename C,
typename L,
bool M>
308 struct channel_mapping_type<bit_aligned_pixel_reference<B, C, L, M>>
310 using type =
typename L::channel_mapping_t;
313 template <
typename B,
typename C,
typename L,
bool M>
314 struct is_planar<bit_aligned_pixel_reference<B, C, L, M>> : std::false_type {};
321 template <
typename BitField,
int NumBits,
typename Layout>
322 struct pixel_reference_type
324 packed_dynamic_channel_reference<BitField, NumBits, false> const,
329 using channel_bit_sizes_t = mp11::mp_repeat
331 mp11::mp_list<std::integral_constant<unsigned, NumBits>>,
332 mp11::mp_size<typename Layout::color_space_t>
337 bit_aligned_pixel_reference<BitField, channel_bit_sizes_t, Layout, false>;
342 template <
typename BitField,
int NumBits,
typename Layout>
343 struct pixel_reference_type
345 packed_dynamic_channel_reference<BitField, NumBits, true> const,
350 using channel_bit_sizes_t = mp11::mp_repeat
352 mp11::mp_list<std::integral_constant<unsigned, NumBits>>,
353 mp11::mp_size<typename Layout::color_space_t>
357 using type = bit_aligned_pixel_reference<BitField, channel_bit_sizes_t, Layout, true>;
371 template <
typename B,
typename C,
typename L,
typename R>
inline 372 void swap(
const boost::gil::bit_aligned_pixel_reference<B,C,L,true> x, R& y) {
373 boost::gil::swap_proxy<typename boost::gil::bit_aligned_pixel_reference<B,C,L,true>::value_type>(x,y);
377 template <
typename B,
typename C,
typename L>
inline 378 void swap(
typename boost::gil::bit_aligned_pixel_reference<B,C,L,true>::value_type& x,
const boost::gil::bit_aligned_pixel_reference<B,C,L,true> y) {
379 boost::gil::swap_proxy<typename boost::gil::bit_aligned_pixel_reference<B,C,L,true>::value_type>(x,y);
383 template <
typename B,
typename C,
typename L>
inline 384 void swap(
const boost::gil::bit_aligned_pixel_reference<B,C,L,true> x,
const boost::gil::bit_aligned_pixel_reference<B,C,L,true> y) {
385 boost::gil::swap_proxy<typename boost::gil::bit_aligned_pixel_reference<B,C,L,true>::value_type>(x,y);
Definition: bit_aligned_pixel_reference.hpp:34
BOOST_FORCEINLINE bool equal(boost::gil::iterator_from_2d< Loc1 > first, boost::gil::iterator_from_2d< Loc1 > last, boost::gil::iterator_from_2d< Loc2 > first2)
std::equal(I1,I1,I2) with I1 and I2 being a iterator_from_2d
Definition: algorithm.hpp:1029
void swap(boost::gil::packed_channel_reference< BF, FB, NB, M > const x, R &y)
swap for packed_channel_reference
Definition: channel.hpp:529
auto at_c(detail::homogeneous_color_base< E, L, N > &p) -> typename std::add_lvalue_reference< E >::type
Provides mutable access to the K-th element, in physical order.
Definition: color_base.hpp:597
Heterogeneous pixel value whose channel references can be constructed from the pixel bitfield and the...
Definition: metafunctions.hpp:24