8 #ifndef BOOST_GIL_BIT_ALIGNED_PIXEL_REFERENCE_HPP
9 #define BOOST_GIL_BIT_ALIGNED_PIXEL_REFERENCE_HPP
11 #include <boost/gil/pixel.hpp>
12 #include <boost/gil/channel.hpp>
14 #include <boost/config.hpp>
15 #include <boost/mpl/accumulate.hpp>
16 #include <boost/mpl/at.hpp>
17 #include <boost/mpl/bool.hpp>
18 #include <boost/mpl/if.hpp>
19 #include <boost/mpl/plus.hpp>
20 #include <boost/mpl/push_back.hpp>
21 #include <boost/mpl/vector.hpp>
25 namespace boost {
namespace gil {
36 template <
int RangeSize,
bool Mutable>
39 typedef typename mpl::if_c<Mutable,unsigned char,const unsigned char>::type byte_t;
40 typedef std::ptrdiff_t difference_type;
41 template <
int RS,
bool M>
friend class bit_range;
43 byte_t* _current_byte;
47 bit_range() : _current_byte(NULL), _bit_offset(0) {}
48 bit_range(byte_t* current_byte,
int bit_offset) : _current_byte(current_byte), _bit_offset(bit_offset) { assert(bit_offset>=0 && bit_offset<8); }
50 bit_range(
const bit_range& br) : _current_byte(br._current_byte), _bit_offset(br._bit_offset) {}
53 bit_range& operator=(
const bit_range& br) { _current_byte = br._current_byte; _bit_offset=br._bit_offset;
return *
this; }
54 bool operator==(
const bit_range& br)
const {
return _current_byte==br._current_byte && _bit_offset==br._bit_offset; }
56 bit_range& operator++() {
57 _current_byte += (_bit_offset+RangeSize) / 8;
58 _bit_offset = (_bit_offset+RangeSize) % 8;
61 bit_range& operator--() { bit_advance(-RangeSize);
return *
this; }
63 void bit_advance(difference_type num_bits) {
64 int new_offset = int(_bit_offset+num_bits);
65 _current_byte += new_offset / 8;
66 _bit_offset = new_offset % 8;
72 difference_type bit_distance_to(
const bit_range& b)
const {
73 return (b.current_byte() - current_byte())*8 + b.bit_offset()-bit_offset();
75 byte_t* current_byte()
const {
return _current_byte; }
76 int bit_offset()
const {
return _bit_offset; }
107 template <
typename BitField,
110 typename ChannelBitSizes,
114 BOOST_STATIC_CONSTANT(
int, bit_size = (mpl::accumulate<ChannelBitSizes, mpl::int_<0>, mpl::plus<mpl::_1, mpl::_2> >::type::value));
116 typedef BitField bitfield_t;
117 typedef typename mpl::if_c<IsMutable,unsigned char*,const unsigned char*>::type data_ptr_t;
119 typedef Layout layout_t;
125 BOOST_STATIC_CONSTANT(
bool, is_mutable = IsMutable);
133 explicit bit_aligned_pixel_reference(
const typename kth_element_type<bit_aligned_pixel_reference,0>::type channel0) : _bit_range(static_cast<data_ptr_t>(&channel0), channel0.first_bit()) {
138 bit_aligned_pixel_reference(
const bit_aligned_pixel_reference& p) : _bit_range(p._bit_range) {}
139 template <
typename BF,
typename CR> bit_aligned_pixel_reference(
packed_pixel<BF,CR,Layout>& p) : _bit_range(static_cast<data_ptr_t>(&gil::at_c<0>(p)), gil::at_c<0>(p).first_bit()) {
140 check_compatible<packed_pixel<BF,CR,Layout> >();
143 const bit_aligned_pixel_reference& operator=(
const bit_aligned_pixel_reference& p)
const { static_copy(p,*
this);
return *
this; }
144 template <
typename P>
const bit_aligned_pixel_reference& operator=(
const P& p)
const { assign(p, mpl::bool_<is_pixel<P>::value>());
return *
this; }
146 template <
typename P>
bool operator==(
const P& p)
const {
return equal(p, mpl::bool_<is_pixel<P>::value>()); }
147 template <
typename P>
bool operator!=(
const P& p)
const {
return !(*
this==p); }
149 const bit_aligned_pixel_reference* operator->()
const {
return this; }
151 const bit_range_t& bit_range()
const {
return _bit_range; }
154 template <
typename B,
typename C,
typename L,
bool M>
friend struct bit_aligned_pixel_reference;
156 template <
typename Pixel>
static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel,bit_aligned_pixel_reference> >(); }
158 template <
typename Pixel>
void assign(
const Pixel& p, mpl::true_)
const { check_compatible<Pixel>(); static_copy(p,*
this); }
159 template <
typename Pixel>
bool equal(
const Pixel& p, mpl::true_)
const { check_compatible<Pixel>();
return static_equal(*
this,p); }
162 static void check_gray() { BOOST_STATIC_ASSERT((is_same<typename Layout::color_space_t, gray_t>::value)); }
163 template <
typename Channel>
void assign(
const Channel& chan, mpl::false_)
const { check_gray(); gil::at_c<0>(*this)=chan; }
164 template <
typename Channel>
bool equal (
const Channel& chan, mpl::false_)
const { check_gray();
return gil::at_c<0>(*this)==chan; }
171 template <
typename BitField,
typename ChannelBitSizes,
typename L,
bool IsMutable,
int K>
174 typedef const packed_dynamic_channel_reference<BitField, mpl::at_c<ChannelBitSizes,K>::type::value, IsMutable> type;
177 template <
typename B,
typename C,
typename L,
bool M,
int K>
178 struct kth_element_reference_type<bit_aligned_pixel_reference<B,C,L,M>, K>
179 :
public kth_element_type<bit_aligned_pixel_reference<B,C,L,M>, K> {};
181 template <
typename B,
typename C,
typename L,
bool M,
int K>
182 struct kth_element_const_reference_type<bit_aligned_pixel_reference<B,C,L,M>, K>
183 :
public kth_element_type<bit_aligned_pixel_reference<B,C,L,M>, K> {};
188 template <
typename IntegralVector,
int K>
189 struct sum_k :
public mpl::plus<sum_k<IntegralVector,K-1>, typename mpl::at_c<IntegralVector,K-1>::type > {};
191 template <
typename IntegralVector>
struct sum_k<IntegralVector,0> :
public mpl::int_<0> {};
195 template <
int K,
typename BitField,
typename ChannelBitSizes,
typename L,
bool Mutable>
inline
196 typename kth_element_reference_type<bit_aligned_pixel_reference<BitField,ChannelBitSizes,L,Mutable>,K>::type
197 at_c(
const bit_aligned_pixel_reference<BitField,ChannelBitSizes,L,Mutable>& p) {
198 typedef bit_aligned_pixel_reference<BitField,ChannelBitSizes,L,Mutable> pixel_t;
199 typedef typename kth_element_reference_type<pixel_t,K>::type channel_t;
200 typedef typename pixel_t::bit_range_t bit_range_t;
202 bit_range_t bit_range(p.bit_range());
203 bit_range.bit_advance(detail::sum_k<ChannelBitSizes,K>::value);
205 return channel_t(bit_range.current_byte(), bit_range.bit_offset());
213 template <
typename B,
typename C,
typename L,
bool M>
220 template <
typename B,
typename C,
typename L,
bool M>
222 typedef typename L::color_space_t type;
225 template <
typename B,
typename C,
typename L,
bool M>
226 struct channel_mapping_type<bit_aligned_pixel_reference<B,C,L,M> > {
227 typedef typename L::channel_mapping_t type;
230 template <
typename B,
typename C,
typename L,
bool M>
231 struct is_planar<bit_aligned_pixel_reference<B,C,L,M> > : mpl::false_ {};
239 template <
unsigned K,
typename T>
struct k_copies;
240 template <
typename T>
struct k_copies<0,T> {
241 typedef mpl::vector0<> type;
243 template <
unsigned K,
typename T>
struct k_copies :
public mpl::push_back<typename k_copies<K-1,T>::type, T> {};
247 template <
typename BitField,
int NumBits,
typename Layout>
248 struct pixel_reference_type<const packed_dynamic_channel_reference<BitField,NumBits,false>, Layout, false, false> {
250 typedef typename mpl::size<typename Layout::color_space_t>::type size_t;
251 typedef typename detail::k_copies<size_t::value,mpl::integral_c<unsigned,NumBits> >::type channel_bit_sizes_t;
253 typedef bit_aligned_pixel_reference<BitField, channel_bit_sizes_t, Layout, false> type;
257 template <
typename BitField,
int NumBits,
typename Layout>
258 struct pixel_reference_type<const packed_dynamic_channel_reference<BitField,NumBits,true>, Layout, false, true> {
260 typedef typename mpl::size<typename Layout::color_space_t>::type size_t;
261 typedef typename detail::k_copies<size_t::value,mpl::integral_c<unsigned,NumBits> >::type channel_bit_sizes_t;
263 typedef bit_aligned_pixel_reference<BitField, channel_bit_sizes_t, Layout, true> type;
276 template <
typename B,
typename C,
typename L,
typename R>
inline
278 boost::gil::swap_proxy<typename boost::gil::bit_aligned_pixel_reference<B,C,L,true>::value_type>(x,y);
282 template <
typename B,
typename C,
typename L>
inline
284 boost::gil::swap_proxy<typename boost::gil::bit_aligned_pixel_reference<B,C,L,true>::value_type>(x,y);
288 template <
typename B,
typename C,
typename L>
inline
290 boost::gil::swap_proxy<typename boost::gil::bit_aligned_pixel_reference<B,C,L,true>::value_type>(x,y);
void swap(const boost::gil::packed_channel_reference< BF, FB, NB, M > x, R &y)
swap for packed_channel_reference
Definition: channel.hpp:480
Heterogeneous pixel reference corresponding to non-byte-aligned bit range. Models ColorBaseConcept...
Definition: bit_aligned_pixel_reference.hpp:113
add_reference< E >::type at_c(detail::homogeneous_color_base< E, L, N > &p)
Provides mutable access to the K-th element, in physical order.
Definition: color_base.hpp:381
Definition: bit_aligned_pixel_reference.hpp:37
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:915
Heterogeneous pixel value whose channel references can be constructed from the pixel bitfield and the...
Definition: concepts.hpp:73
Returns the number of channels of a pixel-based GIL construct.
Definition: concepts.hpp:56