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(
bit_range const& br) : _current_byte(br._current_byte), _bit_offset(br._bit_offset) {}
55 auto operator=(
bit_range const& br) ->
bit_range& { _current_byte = br._current_byte; _bit_offset=br._bit_offset;
return *
this; }
56 bool operator==(
bit_range const& 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 auto operator--() ->
bit_range& { 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;
75 auto bit_distance_to(
bit_range const& b)
const -> difference_type
77 return (b.current_byte() - current_byte())*8 + b.bit_offset()-bit_offset();
79 auto current_byte()
const -> byte_t* {
return _current_byte; }
80 auto bit_offset()
const ->
int {
return _bit_offset; }
116 template <
typename BitField,
typename ChannelBitSizes,
typename Layout,
bool IsMutable>
117 struct bit_aligned_pixel_reference
119 static constexpr
int bit_size =
123 std::integral_constant<int, 0>,
128 using bitfield_t = BitField;
129 using data_ptr_t = mp11::mp_if_c<IsMutable, unsigned char*, const unsigned char*>;
131 using layout_t = Layout;
134 using reference =
const bit_aligned_pixel_reference<BitField, ChannelBitSizes, Layout, IsMutable>;
135 using const_reference = bit_aligned_pixel_reference<BitField,ChannelBitSizes,Layout,false>
const;
137 static constexpr
bool is_mutable = IsMutable;
139 bit_aligned_pixel_reference(){}
140 bit_aligned_pixel_reference(data_ptr_t data_ptr,
int bit_offset) : _bit_range(data_ptr, bit_offset) {}
141 explicit bit_aligned_pixel_reference(bit_range_t
const& bit_range) : _bit_range(bit_range) {}
143 template <
bool IsMutable2>
144 bit_aligned_pixel_reference(bit_aligned_pixel_reference<BitField,ChannelBitSizes,Layout,IsMutable2>
const& p) : _bit_range(p._bit_range) {}
147 explicit bit_aligned_pixel_reference(
typename kth_element_type<bit_aligned_pixel_reference,0>::type
const channel0)
148 : _bit_range(static_cast<data_ptr_t>(&channel0), channel0.first_bit())
150 static_assert(num_channels<bit_aligned_pixel_reference>::value == 1,
"");
154 bit_aligned_pixel_reference(bit_aligned_pixel_reference
const& p)
155 : _bit_range(p._bit_range) {}
158 template <
typename BF,
typename CR>
159 bit_aligned_pixel_reference(packed_pixel<BF, CR, Layout>& p)
160 : _bit_range(static_cast<data_ptr_t>(&gil::
at_c<0>(p)), gil::
at_c<0>(p).first_bit())
162 check_compatible<packed_pixel<BF, CR, Layout>>();
165 auto operator=(bit_aligned_pixel_reference
const& p)
const
166 -> bit_aligned_pixel_reference
const&
168 static_copy(p, *
this);
172 template <
typename P>
173 auto operator=(P
const& p)
const -> bit_aligned_pixel_reference
const&
175 assign(p, is_pixel<P>());
179 template <
typename P>
180 bool operator==(P
const& p)
const
182 return equal(p, is_pixel<P>());
185 template <
typename P>
186 bool operator!=(P
const& p)
const {
return !(*
this==p); }
188 auto operator->() const -> bit_aligned_pixel_reference const* {
return this; }
190 auto bit_range() const -> bit_range_t const& {
return _bit_range; }
193 mutable bit_range_t _bit_range;
194 template <
typename B,
typename C,
typename L,
bool M>
195 friend struct bit_aligned_pixel_reference;
197 template <
typename Pixel>
static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel,bit_aligned_pixel_reference> >(); }
199 template <
typename Pixel>
200 void assign(Pixel
const& p, std::true_type)
const
202 check_compatible<Pixel>();
203 static_copy(p, *
this);
206 template <
typename Pixel>
207 bool equal(Pixel
const& p, std::true_type)
const
209 check_compatible<Pixel>();
210 return static_equal(*
this, p);
214 static void check_gray()
216 static_assert(std::is_same<typename Layout::color_space_t, gray_t>::value,
"");
219 template <
typename Channel>
220 void assign(Channel
const& channel, std::false_type)
const
223 gil::at_c<0>(*
this) = channel;
226 template <
typename Channel>
227 bool equal (Channel
const& channel, std::false_type)
const
230 return gil::at_c<0>(*
this) == channel;
238 template <
typename BitField,
typename ChannelBitSizes,
typename L,
bool IsMutable,
int K>
239 struct kth_element_type
241 bit_aligned_pixel_reference<BitField, ChannelBitSizes, L, IsMutable>,
245 using type = packed_dynamic_channel_reference
248 mp11::mp_at_c<ChannelBitSizes, K>::value,
253 template <
typename B,
typename C,
typename L,
bool M,
int K>
254 struct kth_element_reference_type<bit_aligned_pixel_reference<B,C,L,M>, K>
255 :
public kth_element_type<bit_aligned_pixel_reference<B,C,L,M>, K> {};
257 template <
typename B,
typename C,
typename L,
bool M,
int K>
258 struct kth_element_const_reference_type<bit_aligned_pixel_reference<B,C,L,M>, K>
259 :
public kth_element_type<bit_aligned_pixel_reference<B,C,L,M>, K> {};
264 template <
typename IntegralVector,
int K>
268 sum_k<IntegralVector, K - 1>,
269 typename mp11::mp_at_c<IntegralVector, K - 1>::type
273 template <
typename IntegralVector>
274 struct sum_k<IntegralVector, 0> : std::integral_constant<int, 0> {};
279 template <
int K,
typename BitField,
typename ChannelBitSizes,
typename L,
bool IsMutable>
281 auto at_c(
const bit_aligned_pixel_reference<BitField, ChannelBitSizes, L, IsMutable>& p)
282 ->
typename kth_element_reference_type<bit_aligned_pixel_reference<BitField, ChannelBitSizes, L, IsMutable>, K>::type
284 using pixel_t = bit_aligned_pixel_reference<BitField, ChannelBitSizes, L, IsMutable>;
285 using channel_t =
typename kth_element_reference_type<pixel_t, K>::type;
286 using bit_range_t =
typename pixel_t::bit_range_t;
288 bit_range_t bit_range(p.bit_range());
289 bit_range.bit_advance(detail::sum_k<ChannelBitSizes, K>::value);
291 return channel_t(bit_range.current_byte(), bit_range.bit_offset());
299 template <
typename B,
typename C,
typename L,
bool M>
300 struct is_pixel<bit_aligned_pixel_reference<B, C, L, M> > : std::true_type {};
306 template <
typename B,
typename C,
typename L,
bool M>
307 struct color_space_type<bit_aligned_pixel_reference<B, C, L, M>>
309 using type =
typename L::color_space_t;
312 template <
typename B,
typename C,
typename L,
bool M>
313 struct channel_mapping_type<bit_aligned_pixel_reference<B, C, L, M>>
315 using type =
typename L::channel_mapping_t;
318 template <
typename B,
typename C,
typename L,
bool M>
319 struct is_planar<bit_aligned_pixel_reference<B, C, L, M>> : std::false_type {};
326 template <
typename BitField,
int NumBits,
typename Layout>
327 struct pixel_reference_type
329 packed_dynamic_channel_reference<BitField, NumBits, false> const,
334 using channel_bit_sizes_t = mp11::mp_repeat
336 mp11::mp_list<std::integral_constant<unsigned, NumBits>>,
337 mp11::mp_size<typename Layout::color_space_t>
342 bit_aligned_pixel_reference<BitField, channel_bit_sizes_t, Layout, false>;
347 template <
typename BitField,
int NumBits,
typename Layout>
348 struct pixel_reference_type
350 packed_dynamic_channel_reference<BitField, NumBits, true> const,
355 using channel_bit_sizes_t = mp11::mp_repeat
357 mp11::mp_list<std::integral_constant<unsigned, NumBits>>,
358 mp11::mp_size<typename Layout::color_space_t>
362 using type = bit_aligned_pixel_reference<BitField, channel_bit_sizes_t, Layout, true>;
376 template <
typename B,
typename C,
typename L,
typename R>
inline
377 void swap(boost::gil::bit_aligned_pixel_reference<B,C,L,true>
const x, R& y) {
378 boost::gil::swap_proxy<typename boost::gil::bit_aligned_pixel_reference<B,C,L,true>::value_type>(x,y);
382 template <
typename B,
typename C,
typename L>
inline
383 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) {
384 boost::gil::swap_proxy<typename boost::gil::bit_aligned_pixel_reference<B,C,L,true>::value_type>(x,y);
388 template <
typename B,
typename C,
typename L>
inline
389 void swap(boost::gil::bit_aligned_pixel_reference<B,C,L,true>
const x,
const boost::gil::bit_aligned_pixel_reference<B,C,L,true> y) {
390 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
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:632
void swap(boost::gil::packed_channel_reference< BF, FB, NB, M > const x, R &y)
swap for packed_channel_reference
Definition: channel.hpp:583
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:1087
defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
Definition: algorithm.hpp:36
Heterogeneous pixel value whose channel references can be constructed from the pixel bitfield and the...
Definition: packed_pixel.hpp:50