C++ Boost


channel.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2005-2007 Adobe Systems Incorporated
3 
4  Use, modification and distribution are subject to the Boost Software License,
5  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6  http://www.boost.org/LICENSE_1_0.txt).
7 
8  See http://stlab.adobe.com/gil for most recent version including documentation.
9 */
10 
11 /*************************************************************************************************/
12 
13 #ifndef GIL_CHANNEL_HPP
14 #define GIL_CHANNEL_HPP
15 
26 
27 #include <limits>
28 #include <cassert>
29 
30 #include <boost/cstdint.hpp>
31 #include <boost/config.hpp>
32 #include <boost/integer/integer_mask.hpp>
33 #include <boost/type_traits/remove_cv.hpp>
34 
35 #include "gil_config.hpp"
36 #include "utilities.hpp"
37 
38 namespace boost { namespace gil {
39 
40 
55 
56 namespace detail {
57  template <typename T, bool is_class> struct channel_traits_impl;
58 
59  // channel traits for custom class
60  template <typename T>
61  struct channel_traits_impl<T, true> {
62  typedef typename T::value_type value_type;
63  typedef typename T::reference reference;
64  typedef typename T::pointer pointer;
65  typedef typename T::const_reference const_reference;
66  typedef typename T::const_pointer const_pointer;
67  BOOST_STATIC_CONSTANT(bool, is_mutable=T::is_mutable);
68  static value_type min_value() { return T::min_value(); }
69  static value_type max_value() { return T::max_value(); }
70  };
71 
72  // channel traits implementation for built-in integral or floating point channel type
73  template <typename T>
74  struct channel_traits_impl<T, false> {
75  typedef T value_type;
76  typedef T& reference;
77  typedef T* pointer;
78  typedef const T& const_reference;
79  typedef T const* const_pointer;
80  BOOST_STATIC_CONSTANT(bool, is_mutable=true);
81  static value_type min_value() { return (std::numeric_limits<T>::min)(); }
82  static value_type max_value() { return (std::numeric_limits<T>::max)(); }
83  };
84 
85  // channel traits implementation for constant built-in scalar or floating point type
86  template <typename T>
87  struct channel_traits_impl<const T, false> : public channel_traits_impl<T, false> {
88  typedef const T& reference;
89  typedef const T* pointer;
90  BOOST_STATIC_CONSTANT(bool, is_mutable=false);
91  };
92 }
93 
112 template <typename T>
113 struct channel_traits : public detail::channel_traits_impl<T, is_class<T>::value> {};
114 
115 // Channel traits for C++ reference type - remove the reference
116 template <typename T> struct channel_traits< T&> : public channel_traits<T> {};
117 
118 // Channel traits for constant C++ reference type
119 template <typename T> struct channel_traits<const T&> : public channel_traits<T> {
120  typedef typename channel_traits<T>::const_reference reference;
121  typedef typename channel_traits<T>::const_pointer pointer;
122  BOOST_STATIC_CONSTANT(bool, is_mutable=false);
123 };
124 
130 
151 template <typename BaseChannelValue, // base channel (models ChannelValueConcept)
154  typename MinVal, typename MaxVal> // classes with a static apply() function returning the minimum/maximum channel values
157  typedef value_type& reference;
158  typedef value_type* pointer;
159  typedef const value_type& const_reference;
160  typedef const value_type* const_pointer;
161  BOOST_STATIC_CONSTANT(bool, is_mutable=channel_traits<BaseChannelValue>::is_mutable);
162 
163  typedef BaseChannelValue base_channel_t;
164 
165  static value_type min_value() { return MinVal::apply(); }
166  static value_type max_value() { return MaxVal::apply(); }
167 
169  scoped_channel_value(const scoped_channel_value& c) : _value(c._value) {}
170  scoped_channel_value(BaseChannelValue val) : _value(val) {}
171 
172  scoped_channel_value& operator++() { ++_value; return *this; }
173  scoped_channel_value& operator--() { --_value; return *this; }
174 
175  scoped_channel_value operator++(int) { scoped_channel_value tmp=*this; this->operator++(); return tmp; }
176  scoped_channel_value operator--(int) { scoped_channel_value tmp=*this; this->operator--(); return tmp; }
177 
178  template <typename Scalar2> scoped_channel_value& operator+=(Scalar2 v) { _value+=v; return *this; }
179  template <typename Scalar2> scoped_channel_value& operator-=(Scalar2 v) { _value-=v; return *this; }
180  template <typename Scalar2> scoped_channel_value& operator*=(Scalar2 v) { _value*=v; return *this; }
181  template <typename Scalar2> scoped_channel_value& operator/=(Scalar2 v) { _value/=v; return *this; }
182 
183  scoped_channel_value& operator=(BaseChannelValue v) { _value=v; return *this; }
184  operator BaseChannelValue() const { return _value; }
185 private:
186  BaseChannelValue _value;
187 };
188 
189 struct float_zero { static float apply() { return 0.0f; } };
190 struct float_one { static float apply() { return 1.0f; } };
191 
192 
198 
199 // It is necessary for packed channels to have their own value type. They cannot simply use an integral large enough to store the data. Here is why:
200 // - Any operation that requires returning the result by value will otherwise return the built-in integral type, which will have incorrect range
201 // That means that after getting the value of the channel we cannot properly do channel_convert, channel_invert, etc.
202 // - Two channels are declared compatible if they have the same value type. That means that a packed channel is incorrectly declared compatible with an integral type
203 namespace detail {
204  // returns the smallest fast unsigned integral type that has at least NumBits bits
205  template <int NumBits>
206  struct min_fast_uint : public mpl::if_c< (NumBits<=8),
207  uint_least8_t,
208  typename mpl::if_c< (NumBits<=16),
209  uint_least16_t,
210  typename mpl::if_c< (NumBits<=32),
211  uint_least32_t,
212  uintmax_t
213  >::type
214  >::type
215  > {};
216 
217  template <int NumBits>
218  struct num_value_fn : public mpl::if_c< ( NumBits < 32 )
219  , uint32_t
220  , uint64_t
221  > {};
222 
223  template <int NumBits>
224  struct max_value_fn : public mpl::if_c< ( NumBits <= 32 )
225  , uint32_t
226  , uint64_t
227  > {};
228 }
229 
246 template <int NumBits>
249 class packed_channel_value {
250 
251 public:
252  typedef typename detail::min_fast_uint<NumBits>::type integer_t;
253 
254 
255  typedef packed_channel_value value_type;
256  typedef value_type& reference;
257  typedef const value_type& const_reference;
258  typedef value_type* pointer;
259  typedef const value_type* const_pointer;
260 
261  static value_type min_value() { return 0; }
262  static value_type max_value() { return low_bits_mask_t< NumBits >::sig_bits; }
263 
264  BOOST_STATIC_CONSTANT(bool, is_mutable=true);
265 
266  packed_channel_value() {}
267 
268  packed_channel_value(integer_t v) { _value = static_cast< integer_t >( v & low_bits_mask_t<NumBits>::sig_bits_fast ); }
269  template <typename Scalar> packed_channel_value(Scalar v) { _value = packed_channel_value( static_cast< integer_t >( v ) ); }
270 
271  static unsigned int num_bits() { return NumBits; }
272 
273  operator integer_t() const { return _value; }
274 private:
275  integer_t _value;
276 };
277 
278 namespace detail {
279 
280 template <std::size_t K>
281 struct static_copy_bytes {
282  void operator()(const unsigned char* from, unsigned char* to) const {
283  *to = *from;
284  static_copy_bytes<K-1>()(++from,++to);
285  }
286 };
287 
288 template <>
289 struct static_copy_bytes<0> {
290  void operator()(const unsigned char* , unsigned char*) const {}
291 };
292 
293 template <typename Derived, typename BitField, int NumBits, bool Mutable>
294 class packed_channel_reference_base {
295 protected:
296  typedef typename mpl::if_c<Mutable,void*,const void*>::type data_ptr_t;
297 public:
298  data_ptr_t _data_ptr; // void* pointer to the first byte of the bit range
299 
300  typedef packed_channel_value<NumBits> value_type;
301  typedef const Derived reference;
302  typedef value_type* pointer;
303  typedef const value_type* const_pointer;
304  BOOST_STATIC_CONSTANT(int, num_bits=NumBits);
305  BOOST_STATIC_CONSTANT(bool, is_mutable=Mutable);
306 
307  static value_type min_value() { return channel_traits<value_type>::min_value(); }
308  static value_type max_value() { return channel_traits<value_type>::max_value(); }
309 
310  typedef BitField bitfield_t;
311  typedef typename value_type::integer_t integer_t;
312 
313  packed_channel_reference_base(data_ptr_t data_ptr) : _data_ptr(data_ptr) {}
314  packed_channel_reference_base(const packed_channel_reference_base& ref) : _data_ptr(ref._data_ptr) {}
315  const Derived& operator=(integer_t v) const { set(v); return derived(); }
316 
317  const Derived& operator++() const { set(get()+1); return derived(); }
318  const Derived& operator--() const { set(get()-1); return derived(); }
319 
320  Derived operator++(int) const { Derived tmp=derived(); this->operator++(); return tmp; }
321  Derived operator--(int) const { Derived tmp=derived(); this->operator--(); return tmp; }
322 
323  template <typename Scalar2> const Derived& operator+=(Scalar2 v) const { set( static_cast<integer_t>( get() + v )); return derived(); }
324  template <typename Scalar2> const Derived& operator-=(Scalar2 v) const { set( static_cast<integer_t>( get() - v )); return derived(); }
325  template <typename Scalar2> const Derived& operator*=(Scalar2 v) const { set( static_cast<integer_t>( get() * v )); return derived(); }
326  template <typename Scalar2> const Derived& operator/=(Scalar2 v) const { set( static_cast<integer_t>( get() / v )); return derived(); }
327 
328  operator integer_t() const { return get(); }
329  data_ptr_t operator &() const {return _data_ptr;}
330 protected:
331 
332  typedef typename detail::num_value_fn< NumBits >::type num_value_t;
333  typedef typename detail::max_value_fn< NumBits >::type max_value_t;
334 
335  static const num_value_t num_values = static_cast< num_value_t >( 1 ) << NumBits ;
336  static const max_value_t max_val = static_cast< max_value_t >( num_values - 1 );
337 
338 #ifdef GIL_NONWORD_POINTER_ALIGNMENT_SUPPORTED
339  const bitfield_t& get_data() const { return *static_cast<const bitfield_t*>(_data_ptr); }
340  void set_data(const bitfield_t& val) const { *static_cast< bitfield_t*>(_data_ptr) = val; }
341 #else
342  bitfield_t get_data() const {
343  bitfield_t ret;
344  static_copy_bytes<sizeof(bitfield_t) >()(gil_reinterpret_cast_c<const unsigned char*>(_data_ptr),gil_reinterpret_cast<unsigned char*>(&ret));
345  return ret;
346  }
347  void set_data(const bitfield_t& val) const {
348  static_copy_bytes<sizeof(bitfield_t) >()(gil_reinterpret_cast_c<const unsigned char*>(&val),gil_reinterpret_cast<unsigned char*>(_data_ptr));
349  }
350 #endif
351 
352 private:
353  void set(integer_t value) const { // can this be done faster??
354  const integer_t num_values = max_val+1;
355  this->derived().set_unsafe(((value % num_values) + num_values) % num_values);
356  }
357  integer_t get() const { return derived().get(); }
358  const Derived& derived() const { return static_cast<const Derived&>(*this); }
359 };
360 } // namespace detail
361 
378 template <typename BitField, // A type that holds the bits of the pixel from which the channel is referenced. Typically an integral type, like boost::uint16_t
379  int FirstBit, int NumBits,// Defines the sequence of bits in the data value that contain the channel
380  bool Mutable> // true if the reference is mutable
381 class packed_channel_reference;
382 
383 template <typename BitField, // A type that holds the bits of the pixel from which the channel is referenced. Typically an integral type, like boost::uint16_t
384  int NumBits, // Defines the sequence of bits in the data value that contain the channel
385  bool Mutable> // true if the reference is mutable
386 class packed_dynamic_channel_reference;
387 
390 template <typename BitField, int FirstBit, int NumBits>
391 class packed_channel_reference<BitField,FirstBit,NumBits,false>
392  : public detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,false>,BitField,NumBits,false> {
393  typedef detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,false>,BitField,NumBits,false> parent_t;
394  friend class packed_channel_reference<BitField,FirstBit,NumBits,true>;
395 
396  static const BitField channel_mask = static_cast< BitField >( parent_t::max_val ) << FirstBit;
397 
398  void operator=(const packed_channel_reference&);
399 public:
400  typedef const packed_channel_reference<BitField,FirstBit,NumBits,false> const_reference;
401  typedef const packed_channel_reference<BitField,FirstBit,NumBits,true> mutable_reference;
402  typedef typename parent_t::integer_t integer_t;
403 
404  explicit packed_channel_reference(const void* data_ptr) : parent_t(data_ptr) {}
405  packed_channel_reference(const packed_channel_reference& ref) : parent_t(ref._data_ptr) {}
406  packed_channel_reference(const mutable_reference& ref) : parent_t(ref._data_ptr) {}
407 
408  unsigned first_bit() const { return FirstBit; }
409 
410  integer_t get() const { return integer_t((this->get_data()&channel_mask) >> FirstBit); }
411 };
412 
415 template <typename BitField, int FirstBit, int NumBits>
416 class packed_channel_reference<BitField,FirstBit,NumBits,true>
417  : public detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,true>,BitField,NumBits,true> {
418  typedef detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,true>,BitField,NumBits,true> parent_t;
419  friend class packed_channel_reference<BitField,FirstBit,NumBits,false>;
420 
421  static const BitField channel_mask = static_cast< BitField >( parent_t::max_val ) << FirstBit;
422 
423 public:
424  typedef const packed_channel_reference<BitField,FirstBit,NumBits,false> const_reference;
425  typedef const packed_channel_reference<BitField,FirstBit,NumBits,true> mutable_reference;
426  typedef typename parent_t::integer_t integer_t;
427 
428  explicit packed_channel_reference(void* data_ptr) : parent_t(data_ptr) {}
429  packed_channel_reference(const packed_channel_reference& ref) : parent_t(ref._data_ptr) {}
430 
431  const packed_channel_reference& operator=(integer_t value) const { assert(value<=parent_t::max_val); set_unsafe(value); return *this; }
432  const packed_channel_reference& operator=(const mutable_reference& ref) const { set_from_reference(ref.get_data()); return *this; }
433  const packed_channel_reference& operator=(const const_reference& ref) const { set_from_reference(ref.get_data()); return *this; }
434 
435  template <bool Mutable1>
436  const packed_channel_reference& operator=(const packed_dynamic_channel_reference<BitField,NumBits,Mutable1>& ref) const { set_unsafe(ref.get()); return *this; }
437 
438  unsigned first_bit() const { return FirstBit; }
439 
440  integer_t get() const { return integer_t((this->get_data()&channel_mask) >> FirstBit); }
441  void set_unsafe(integer_t value) const { this->set_data((this->get_data() & ~channel_mask) | (( static_cast< BitField >( value )<<FirstBit))); }
442 private:
443  void set_from_reference(const BitField& other_bits) const { this->set_data((this->get_data() & ~channel_mask) | (other_bits & channel_mask)); }
444 };
445 
446 } } // namespace boost::gil
447 
448 namespace std {
449 // We are forced to define swap inside std namespace because on some platforms (Visual Studio 8) STL calls swap qualified.
450 // swap with 'left bias':
451 // - swap between proxy and anything
452 // - swap between value type and proxy
453 // - swap between proxy and proxy
454 
457 template <typename BF, int FB, int NB, bool M, typename R> inline
458 void swap(const boost::gil::packed_channel_reference<BF,FB,NB,M> x, R& y) {
459  boost::gil::swap_proxy<typename boost::gil::packed_channel_reference<BF,FB,NB,M>::value_type>(x,y);
460 }
461 
462 
465 template <typename BF, int FB, int NB, bool M> inline
466 void swap(typename boost::gil::packed_channel_reference<BF,FB,NB,M>::value_type& x, const boost::gil::packed_channel_reference<BF,FB,NB,M> y) {
467  boost::gil::swap_proxy<typename boost::gil::packed_channel_reference<BF,FB,NB,M>::value_type>(x,y);
468 }
469 
470 
473 template <typename BF, int FB, int NB, bool M> inline
474 void swap(const boost::gil::packed_channel_reference<BF,FB,NB,M> x, const boost::gil::packed_channel_reference<BF,FB,NB,M> y) {
475  boost::gil::swap_proxy<typename boost::gil::packed_channel_reference<BF,FB,NB,M>::value_type>(x,y);
476 }
477 } // namespace std
478 
479 namespace boost { namespace gil {
480 
498 template <typename BitField, int NumBits>
502 class packed_dynamic_channel_reference<BitField,NumBits,false>
503  : public detail::packed_channel_reference_base<packed_dynamic_channel_reference<BitField,NumBits,false>,BitField,NumBits,false> {
504  typedef detail::packed_channel_reference_base<packed_dynamic_channel_reference<BitField,NumBits,false>,BitField,NumBits,false> parent_t;
505  friend class packed_dynamic_channel_reference<BitField,NumBits,true>;
506 
507  unsigned _first_bit; // 0..7
508 
509  void operator=(const packed_dynamic_channel_reference&);
510 public:
511  typedef const packed_dynamic_channel_reference<BitField,NumBits,false> const_reference;
512  typedef const packed_dynamic_channel_reference<BitField,NumBits,true> mutable_reference;
513  typedef typename parent_t::integer_t integer_t;
514 
515  packed_dynamic_channel_reference(const void* data_ptr, unsigned first_bit) : parent_t(data_ptr), _first_bit(first_bit) {}
516  packed_dynamic_channel_reference(const const_reference& ref) : parent_t(ref._data_ptr), _first_bit(ref._first_bit) {}
517  packed_dynamic_channel_reference(const mutable_reference& ref) : parent_t(ref._data_ptr), _first_bit(ref._first_bit) {}
518 
519  unsigned first_bit() const { return _first_bit; }
520 
521  integer_t get() const {
522  const BitField channel_mask = static_cast< integer_t >( parent_t::max_val ) <<_first_bit;
523  return static_cast< integer_t >(( this->get_data()&channel_mask ) >> _first_bit );
524  }
525 };
526 
530 template <typename BitField, int NumBits>
531 class packed_dynamic_channel_reference<BitField,NumBits,true>
532  : public detail::packed_channel_reference_base<packed_dynamic_channel_reference<BitField,NumBits,true>,BitField,NumBits,true> {
533  typedef detail::packed_channel_reference_base<packed_dynamic_channel_reference<BitField,NumBits,true>,BitField,NumBits,true> parent_t;
534  friend class packed_dynamic_channel_reference<BitField,NumBits,false>;
535 
536  unsigned _first_bit;
537 
538 public:
541  typedef typename parent_t::integer_t integer_t;
542 
543  packed_dynamic_channel_reference(void* data_ptr, unsigned first_bit) : parent_t(data_ptr), _first_bit(first_bit) {}
544  packed_dynamic_channel_reference(const packed_dynamic_channel_reference& ref) : parent_t(ref._data_ptr), _first_bit(ref._first_bit) {}
545 
546  const packed_dynamic_channel_reference& operator=(integer_t value) const { assert(value<=parent_t::max_val); set_unsafe(value); return *this; }
547  const packed_dynamic_channel_reference& operator=(const mutable_reference& ref) const { set_unsafe(ref.get()); return *this; }
548  const packed_dynamic_channel_reference& operator=(const const_reference& ref) const { set_unsafe(ref.get()); return *this; }
549 
550  template <typename BitField1, int FirstBit1, bool Mutable1>
551  const packed_dynamic_channel_reference& operator=(const packed_channel_reference<BitField1, FirstBit1, NumBits, Mutable1>& ref) const
552  { set_unsafe(ref.get()); return *this; }
553 
554  unsigned first_bit() const { return _first_bit; }
555 
556  integer_t get() const {
557  const BitField channel_mask = static_cast< integer_t >( parent_t::max_val ) << _first_bit;
558  return static_cast< integer_t >(( this->get_data()&channel_mask ) >> _first_bit );
559  }
560 
561  void set_unsafe(integer_t value) const {
562  const BitField channel_mask = static_cast< integer_t >( parent_t::max_val ) << _first_bit;
563  this->set_data((this->get_data() & ~channel_mask) | value<<_first_bit);
564  }
565 };
566 } } // namespace boost::gil
567 
568 namespace std {
569 // We are forced to define swap inside std namespace because on some platforms (Visual Studio 8) STL calls swap qualified.
570 // swap with 'left bias':
571 // - swap between proxy and anything
572 // - swap between value type and proxy
573 // - swap between proxy and proxy
574 
575 
578 template <typename BF, int NB, bool M, typename R> inline
579 void swap(const boost::gil::packed_dynamic_channel_reference<BF,NB,M> x, R& y) {
580  boost::gil::swap_proxy<typename boost::gil::packed_dynamic_channel_reference<BF,NB,M>::value_type>(x,y);
581 }
582 
583 
586 template <typename BF, int NB, bool M> inline
587 void swap(typename boost::gil::packed_dynamic_channel_reference<BF,NB,M>::value_type& x, const boost::gil::packed_dynamic_channel_reference<BF,NB,M> y) {
588  boost::gil::swap_proxy<typename boost::gil::packed_dynamic_channel_reference<BF,NB,M>::value_type>(x,y);
589 }
590 
591 
594 template <typename BF, int NB, bool M> inline
595 void swap(const boost::gil::packed_dynamic_channel_reference<BF,NB,M> x, const boost::gil::packed_dynamic_channel_reference<BF,NB,M> y) {
596  boost::gil::swap_proxy<typename boost::gil::packed_dynamic_channel_reference<BF,NB,M>::value_type>(x,y);
597 }
598 } // namespace std
599 
600 namespace boost { namespace gil {
606 
610 
612 typedef uint8_t bits8;
613 
617 
619 typedef uint16_t bits16;
620 
624 
626 typedef uint32_t bits32;
627 
631 
633 typedef int8_t bits8s;
634 
638 
640 typedef int16_t bits16s;
641 
645 
647 typedef int32_t bits32s;
648 
652 
654 typedef scoped_channel_value<float,float_zero,float_one> bits32f;
655 
656 } } // namespace boost::gil
657 
658 namespace boost {
659 
660 template <int NumBits>
661 struct is_integral<gil::packed_channel_value<NumBits> > : public mpl::true_ {};
662 
663 template <typename BitField, int FirstBit, int NumBits, bool IsMutable>
664 struct is_integral<gil::packed_channel_reference<BitField,FirstBit,NumBits,IsMutable> > : public mpl::true_ {};
665 
666 template <typename BitField, int NumBits, bool IsMutable>
667 struct is_integral<gil::packed_dynamic_channel_reference<BitField,NumBits,IsMutable> > : public mpl::true_ {};
668 
669 template <typename BaseChannelValue, typename MinVal, typename MaxVal>
670 struct is_integral<gil::scoped_channel_value<BaseChannelValue,MinVal,MaxVal> > : public is_integral<BaseChannelValue> {};
671 
672 }
673 
674 // \brief Determines the fundamental type which may be used, e.g., to cast from larger to smaller channel types.
675 namespace boost { namespace gil {
676 template <typename T>
677 struct base_channel_type_impl { typedef T type; };
678 
679 template <int N>
680 struct base_channel_type_impl<packed_channel_value<N> >
681 { typedef typename packed_channel_value<N>::integer_t type; };
682 
683 template <typename B, int F, int N, bool M>
684 struct base_channel_type_impl<packed_channel_reference<B, F, N, M> >
685 { typedef typename packed_channel_reference<B,F,N,M>::integer_t type; };
686 
687 template <typename B, int N, bool M>
688 struct base_channel_type_impl<packed_dynamic_channel_reference<B, N, M> >
689 { typedef typename packed_dynamic_channel_reference<B,N,M>::integer_t type; };
690 
691 template <typename ChannelValue, typename MinV, typename MaxV>
692 struct base_channel_type_impl<scoped_channel_value<ChannelValue, MinV, MaxV> >
693 { typedef ChannelValue type; };
694 
695 template <typename T>
696 struct base_channel_type : base_channel_type_impl<typename remove_cv<T>::type > {};
697 
698 } } //namespace boost::gil
699 
700 #endif
void swap(const boost::gil::packed_dynamic_channel_reference< BF, NB, M > x, const boost::gil::packed_dynamic_channel_reference< BF, NB, M > y)
swap for packed_dynamic_channel_reference
Definition: channel.hpp:595
A channel adaptor that modifies the range of the source channel. Models: ChannelValueConcept.
Definition: channel.hpp:155
Models a constant subbyte channel reference whose bit offset is a runtime parameter. Models ChannelConcept Same as packed_channel_reference, except that the offset is a runtime parameter.
Definition: channel.hpp:502
Traits for channels. Contains the following members:
Definition: channel.hpp:113
GIL configuration file.
Models a mutable subbyte channel reference whose bit offset is a runtime parameter. Models ChannelConcept Same as packed_channel_reference, except that the offset is a runtime parameter.
Definition: channel.hpp:531
Various utilities not specific to the image library. Some are non-standard STL extensions or generic ...