Boost logo

Boost-Commit :

From: lbourdev_at_[hidden]
Date: 2007-09-17 04:12:23


Author: lbourdev
Date: 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
New Revision: 39339
URL: http://svn.boost.org/trac/boost/changeset/39339

Log:
GIL 2.0 to 2.1 (see http://opensource.adobe.com/gil/gil2.1_changes.pdf). GIL 2.1 to 2.1.1 (see http://sourceforge.net/forum/forum.php?thread_id=1824588&forum_id=648138)
Added:
   trunk/boost/gil/bit_aligned_pixel_iterator.hpp (contents, props changed)
   trunk/boost/gil/bit_aligned_pixel_reference.hpp (contents, props changed)
Text files modified:
   trunk/boost/gil/algorithm.hpp | 87 ++++++----
   trunk/boost/gil/channel.hpp | 280 +++++++++++++++++++++++---------
   trunk/boost/gil/channel_algorithm.hpp | 336 ++++++++++++++++++++++++++++++---------
   trunk/boost/gil/color_base.hpp | 78 +++++----
   trunk/boost/gil/color_base_algorithm.hpp | 281 ++++++++++++++++++++++++++-------
   trunk/boost/gil/color_convert.hpp | 28 +-
   trunk/boost/gil/deprecated.hpp | 16 +
   trunk/boost/gil/gil_all.hpp | 1
   trunk/boost/gil/gil_concept.hpp | 104 +++++++-----
   trunk/boost/gil/gil_config.hpp | 2
   trunk/boost/gil/image.hpp | 39 ++--
   trunk/boost/gil/image_view_factory.hpp | 94 +++++++---
   trunk/boost/gil/iterator_from_2d.hpp | 46 ++--
   trunk/boost/gil/locator.hpp | 101 ++++++-----
   trunk/boost/gil/metafunctions.hpp | 202 +++++++++++++++++++++--
   trunk/boost/gil/packed_pixel.hpp | 202 ++++++++++++-----------
   trunk/boost/gil/pixel.hpp | 46 +++++
   trunk/boost/gil/pixel_iterator.hpp | 74 +++----
   trunk/boost/gil/pixel_iterator_adaptor.hpp | 35 ++-
   trunk/boost/gil/planar_pixel_iterator.hpp | 50 +++--
   trunk/boost/gil/planar_pixel_reference.hpp | 29 +++
   trunk/boost/gil/position_iterator.hpp | 2
   trunk/boost/gil/step_iterator.hpp | 128 +++++++-------
   trunk/boost/gil/typedefs.hpp | 28 +-
   trunk/boost/gil/utilities.hpp | 46 ++++
   trunk/libs/gil/example/Makefile | 10
   trunk/libs/gil/example/convolution.cpp | 56 ++++++
   trunk/libs/gil/example/dynamic_image.cpp | 12 +
   trunk/libs/gil/example/histogram.cpp | 12 +
   trunk/libs/gil/example/interleaved_ptr.cpp | 16 +
   trunk/libs/gil/example/interleaved_ptr.hpp | 31 ++-
   trunk/libs/gil/example/interleaved_ref.hpp | 33 +++
   trunk/libs/gil/example/packed_pixel.cpp | 52 ++++-
   trunk/libs/gil/example/resize.cpp | 17 ++
   trunk/libs/gil/example/x_gradient.cpp | 12 +
   trunk/libs/gil/test/Makefile | 12 +
   trunk/libs/gil/test/channel.cpp | 59 +++---
   trunk/libs/gil/test/gil_reference_checksums.txt | 47 ++++-
   trunk/libs/gil/test/image.cpp | 67 +++++--
   trunk/libs/gil/test/performance.cpp | 18 +
   trunk/libs/gil/test/pixel.cpp | 59 ++++--
   trunk/libs/gil/test/pixel_iterator.cpp | 65 +++++-
   42 files changed, 2011 insertions(+), 902 deletions(-)

Modified: trunk/boost/gil/algorithm.hpp
==============================================================================
--- trunk/boost/gil/algorithm.hpp (original)
+++ trunk/boost/gil/algorithm.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -24,6 +24,7 @@
 #include "color_base_algorithm.hpp"
 #include "image_view.hpp"
 #include "image_view_factory.hpp"
+#include "bit_aligned_pixel_iterator.hpp"
 
 ////////////////////////////////////////////////////////////////////////////////////////
 /// \file
@@ -45,9 +46,9 @@
 template <typename ChannelPtr, typename ColorSpace>
 struct planar_pixel_iterator;
 template <typename Iterator>
-class byte_addressable_step_iterator;
+class memory_based_step_iterator;
 template <typename StepIterator>
-class byte_addressable_2d_locator;
+class memory_based_2d_locator;
 
 // a tag denoting incompatible arguments
 struct error_t {};
@@ -245,31 +246,39 @@
         }
     }
 };
-} // namespace detail
-} } // namespace boost::gil
 
-namespace std {
-/// \ingroup STLOptimizations
-/// \brief std::copy(I1,I1,I2) with I1 and I2 being a iterator_from_2d
-template <typename IL, typename OL>
-GIL_FORCEINLINE boost::gil::iterator_from_2d<OL> copy(boost::gil::iterator_from_2d<IL> first, boost::gil::iterator_from_2d<IL> last, boost::gil::iterator_from_2d<OL> dst) {
- boost::gil::gil_function_requires<boost::gil::PixelLocatorConcept<IL> >();
- boost::gil::gil_function_requires<boost::gil::MutablePixelLocatorConcept<OL> >();
- typedef typename boost::gil::iterator_from_2d<IL>::difference_type diff_t;
- diff_t n=diff_t(last-first);
+template <typename SrcIterator, typename DstIterator>
+GIL_FORCEINLINE DstIterator copy_with_2d_iterators(SrcIterator first, SrcIterator last, DstIterator dst) {
+ typedef typename SrcIterator::x_iterator src_x_iterator;
+ typedef typename DstIterator::x_iterator dst_x_iterator;
+
+ typename SrcIterator::difference_type n = last - first;
+
     if (first.is_1d_traversable()) {
         if (dst.is_1d_traversable())
- boost::gil::detail::copier_n<typename IL::x_iterator,typename OL::x_iterator>()(first.x(),n, dst.x());
+ copier_n<src_x_iterator,dst_x_iterator>()(first.x(),n, dst.x());
         else
- boost::gil::detail::copier_n<typename IL::x_iterator,boost::gil::iterator_from_2d<OL> >()(first.x(),n, dst);
+ copier_n<src_x_iterator,DstIterator >()(first.x(),n, dst);
     } else {
         if (dst.is_1d_traversable())
- boost::gil::detail::copier_n<boost::gil::iterator_from_2d<IL>,typename OL::x_iterator>()(first,n, dst.x());
+ copier_n<SrcIterator,dst_x_iterator>()(first,n, dst.x());
         else
- boost::gil::detail::copier_n<boost::gil::iterator_from_2d<IL>,boost::gil::iterator_from_2d<OL> >()(first,n,dst);
+ copier_n<SrcIterator,DstIterator>()(first,n,dst);
     }
     return dst+n;
 }
+
+} // namespace detail
+} } // namespace boost::gil
+
+namespace std {
+/// \ingroup STLOptimizations
+/// \brief std::copy(I1,I1,I2) with I1 and I2 being a iterator_from_2d
+template <typename IL, typename OL>
+GIL_FORCEINLINE boost::gil::iterator_from_2d<OL> copy1(boost::gil::iterator_from_2d<IL> first, boost::gil::iterator_from_2d<IL> last, boost::gil::iterator_from_2d<OL> dst) {
+ return boost::gil::detail::copy_with_2d_iterators(first,last,dst);
+}
+
 } // namespace std
 
 namespace boost { namespace gil {
@@ -280,7 +289,7 @@
 template <typename View1, typename View2> GIL_FORCEINLINE
 void copy_pixels(const View1& src, const View2& dst) {
     assert(src.dimensions()==dst.dimensions());
- std::copy(src.begin(),src.end(),dst.begin()); // std::copy will choose the optimal method (see stl_override.h)
+ detail::copy_with_2d_iterators(src.begin(),src.end(),dst.begin());
 }
 
 //////////////////////////////////////////////////////////////////////////////////////
@@ -426,8 +435,8 @@
 
 namespace detail {
 
-template <typename It>
-void destruct_range(It first, It last) {
+template <typename It> GIL_FORCEINLINE
+void destruct_range_impl(It first, It last, mpl::true_) {
     typedef typename std::iterator_traits<It>::value_type value_t;
     if (boost::has_trivial_destructor<value_t>::value)
         return;
@@ -436,6 +445,13 @@
         ++first;
     }
 }
+template <typename It> GIL_FORCEINLINE
+void destruct_range_impl(It first, It last, mpl::false_) {}
+
+template <typename It> GIL_FORCEINLINE
+void destruct_range(It first, It last) {
+ destruct_range_impl(first,last,typename is_pointer<It>::type());
+}
 
 struct std_destruct_t {
     template <typename It> void operator()(It first, It last) const { destruct_range(first,last); }
@@ -549,25 +565,26 @@
 
 namespace detail {
 
-template <typename It>
-GIL_FORCEINLINE
-void default_construct_range(It first, It last) {
+template <typename It> GIL_FORCEINLINE
+void default_construct_range_impl(It first, It last, mpl::true_) {
     typedef typename std::iterator_traits<It>::value_type value_t;
- if (boost::is_pointer<It>::value) {
- It first1=first;
- try {
- while (first!=last) {
- new (first) value_t();
- ++first;
- }
- } catch (...) {
- destruct_range(first1,first);
- throw;
+ It first1=first;
+ try {
+ while (first!=last) {
+ new (first) value_t();
+ ++first;
         }
- } else
- std::uninitialized_fill(first,last,value_t());
+ } catch (...) {
+ destruct_range(first1,first);
+ throw;
+ }
 }
 
+template <typename It> GIL_FORCEINLINE
+void default_construct_range_impl(It first, It last, mpl::false_) {}
+
+template <typename It> GIL_FORCEINLINE
+void default_construct_range(It first, It last) { default_construct_range_impl(first, last, typename is_pointer<It>::type()); }
 
 /// uninitialized_default_construct for planar iterators
 template <typename It>

Added: trunk/boost/gil/bit_aligned_pixel_iterator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/gil/bit_aligned_pixel_iterator.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -0,0 +1,190 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
+#ifndef GIL_BIT_ALIGNED_PIXEL_ITERATOR_HPP
+#define GIL_BIT_ALIGNED_PIXEL_ITERATOR_HPP
+
+////////////////////////////////////////////////////////////////////////////////////////
+/// \file
+/// \brief A model of a heterogeneous pixel that is not byte aligned. Examples are bitmap (1-bit pixels) or 6-bit RGB (222)
+/// \author Lubomir Bourdev and Hailin Jin \n
+/// Adobe Systems Incorporated
+/// \date 2005-2007 \n Last updated on September 28, 2006
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+#include <functional>
+#include <boost/iterator/iterator_facade.hpp>
+#include "gil_config.hpp"
+#include "bit_aligned_pixel_reference.hpp"
+
+namespace boost { namespace gil {
+
+/// \defgroup PixelIteratorNonAlignedPixelIterator bit_aligned_pixel_iterator
+/// \ingroup PixelIteratorModel
+/// \brief An iterator over non-byte-aligned pixels. Models PixelIteratorConcept, PixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept
+
+////////////////////////////////////////////////////////////////////////////////////////
+/// \brief An iterator over non-byte-aligned pixels. Models PixelIteratorConcept, PixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept
+///
+/// An iterator over pixels that correspond to non-byte-aligned bit ranges. Examples of such pixels are single bit grayscale pixel, or a 6-bit RGB 222 pixel.
+///
+/// \ingroup PixelIteratorNonAlignedPixelIterator PixelBasedModel
+
+template <typename NonAlignedPixelReference>
+struct bit_aligned_pixel_iterator : public iterator_facade<bit_aligned_pixel_iterator<NonAlignedPixelReference>,
+ typename NonAlignedPixelReference::value_type,
+ random_access_traversal_tag,
+ const NonAlignedPixelReference,
+ typename NonAlignedPixelReference::bit_range_t::difference_type> {
+private:
+ typedef iterator_facade<bit_aligned_pixel_iterator<NonAlignedPixelReference>,
+ typename NonAlignedPixelReference::value_type,
+ random_access_traversal_tag,
+ const NonAlignedPixelReference,
+ typename NonAlignedPixelReference::bit_range_t::difference_type> parent_t;
+ template <typename Ref> friend struct bit_aligned_pixel_iterator;
+
+ typedef typename NonAlignedPixelReference::bit_range_t bit_range_t;
+public:
+ typedef typename parent_t::difference_type difference_type;
+ typedef typename parent_t::reference reference;
+
+ bit_aligned_pixel_iterator() {}
+ bit_aligned_pixel_iterator(const bit_aligned_pixel_iterator& p) : _bit_range(p._bit_range) {}
+ bit_aligned_pixel_iterator& operator=(const bit_aligned_pixel_iterator& p) { _bit_range=p._bit_range; return *this; }
+
+ template <typename Ref> bit_aligned_pixel_iterator(const bit_aligned_pixel_iterator<Ref>& p) : _bit_range(p._bit_range) {}
+
+ bit_aligned_pixel_iterator(reference* ref) : _bit_range(ref->bit_range()) {}
+ explicit bit_aligned_pixel_iterator(typename bit_range_t::byte_t* data, int bit_offset=0) : _bit_range(data,bit_offset) {}
+
+ /// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference
+ /// We require our own reference because it is registered in iterator_traits
+ reference operator[](difference_type d) const { bit_aligned_pixel_iterator it=*this; it.advance(d); return *it; }
+
+ reference operator->() const { return **this; }
+ const bit_range_t& bit_range() const { return _bit_range; }
+ bit_range_t& bit_range() { return _bit_range; }
+private:
+ bit_range_t _bit_range;
+ BOOST_STATIC_CONSTANT(int, bit_size = NonAlignedPixelReference::bit_size);
+
+ friend class boost::iterator_core_access;
+ reference dereference() const { return NonAlignedPixelReference(_bit_range); }
+ void increment() { ++_bit_range; }
+ void decrement() { --_bit_range; }
+ void advance(difference_type d) { _bit_range.bit_advance(d*bit_size); }
+
+ difference_type distance_to(const bit_aligned_pixel_iterator& it) const { return _bit_range.bit_distance_to(it._bit_range) / bit_size; }
+ bool equal(const bit_aligned_pixel_iterator& it) const { return _bit_range==it._bit_range; }
+};
+
+template <typename NonAlignedPixelReference>
+struct const_iterator_type<bit_aligned_pixel_iterator<NonAlignedPixelReference> > {
+ typedef bit_aligned_pixel_iterator<typename NonAlignedPixelReference::const_reference> type;
+};
+
+template <typename NonAlignedPixelReference>
+struct iterator_is_mutable<bit_aligned_pixel_iterator<NonAlignedPixelReference> > : public mpl::bool_<NonAlignedPixelReference::is_mutable> {};
+
+template <typename NonAlignedPixelReference>
+struct is_iterator_adaptor<bit_aligned_pixel_iterator<NonAlignedPixelReference> > : public mpl::false_ {};
+
+/////////////////////////////
+// PixelBasedConcept
+/////////////////////////////
+
+template <typename NonAlignedPixelReference>
+struct color_space_type<bit_aligned_pixel_iterator<NonAlignedPixelReference> > : public color_space_type<NonAlignedPixelReference> {};
+
+template <typename NonAlignedPixelReference>
+struct channel_mapping_type<bit_aligned_pixel_iterator<NonAlignedPixelReference> > : public channel_mapping_type<NonAlignedPixelReference> {};
+
+template <typename NonAlignedPixelReference>
+struct is_planar<bit_aligned_pixel_iterator<NonAlignedPixelReference> > : public is_planar<NonAlignedPixelReference> {}; // == false
+
+/////////////////////////////
+// MemoryBasedIteratorConcept
+/////////////////////////////
+
+template <typename NonAlignedPixelReference>
+struct byte_to_memunit<bit_aligned_pixel_iterator<NonAlignedPixelReference> > : public mpl::int_<8> {};
+
+template <typename NonAlignedPixelReference>
+inline std::ptrdiff_t memunit_step(const bit_aligned_pixel_iterator<NonAlignedPixelReference>&) {
+ return NonAlignedPixelReference::bit_size;
+}
+
+template <typename NonAlignedPixelReference>
+inline std::ptrdiff_t memunit_distance(const bit_aligned_pixel_iterator<NonAlignedPixelReference>& p1, const bit_aligned_pixel_iterator<NonAlignedPixelReference>& p2) {
+ return (p2.bit_range().current_byte() - p1.bit_range().current_byte())*8 + p2.bit_range().bit_offset() - p1.bit_range().bit_offset();
+}
+
+template <typename NonAlignedPixelReference>
+inline void memunit_advance(bit_aligned_pixel_iterator<NonAlignedPixelReference>& p, std::ptrdiff_t diff) {
+ p.bit_range().bit_advance(diff);
+}
+
+template <typename NonAlignedPixelReference>
+inline bit_aligned_pixel_iterator<NonAlignedPixelReference> memunit_advanced(const bit_aligned_pixel_iterator<NonAlignedPixelReference>& p, std::ptrdiff_t diff) {
+ bit_aligned_pixel_iterator<NonAlignedPixelReference> ret=p;
+ memunit_advance(ret, diff);
+ return ret;
+}
+
+template <typename NonAlignedPixelReference> inline
+NonAlignedPixelReference memunit_advanced_ref(bit_aligned_pixel_iterator<NonAlignedPixelReference> it, std::ptrdiff_t diff) {
+ return *memunit_advanced(it,diff);
+}
+/////////////////////////////
+// HasDynamicXStepTypeConcept
+/////////////////////////////
+
+template <typename NonAlignedPixelReference>
+struct dynamic_x_step_type<bit_aligned_pixel_iterator<NonAlignedPixelReference> > {
+ typedef memory_based_step_iterator<bit_aligned_pixel_iterator<NonAlignedPixelReference> > type;
+};
+
+/////////////////////////////
+// iterator_type_from_pixel
+/////////////////////////////
+
+template <typename C, typename L, bool M>
+struct iterator_type_from_pixel<const bit_aligned_pixel_reference<C,L,M>,false,false,false> {
+ typedef bit_aligned_pixel_iterator<bit_aligned_pixel_reference<C,L,false> > type;
+};
+
+template <typename C, typename L, bool M>
+struct iterator_type_from_pixel<const bit_aligned_pixel_reference<C,L,M>,false,false,true> {
+ typedef bit_aligned_pixel_iterator<bit_aligned_pixel_reference<C,L,true> > type;
+};
+
+template <typename C, typename L, bool M, bool IsPlanar, bool IsStep, bool IsMutable>
+struct iterator_type_from_pixel<bit_aligned_pixel_reference<C,L,M>,IsPlanar,IsStep,IsMutable>
+ : public iterator_type_from_pixel<const bit_aligned_pixel_reference<C,L,M>,IsPlanar,IsStep,IsMutable> {};
+
+} } // namespace boost::gil
+
+namespace std {
+
+// It is important to provide an overload of uninitialized_copy for bit_aligned_pixel_iterator. The default STL implementation calls placement new,
+// which is not defined for bit_aligned_pixel_iterator.
+template <typename NonAlignedPixelReference>
+boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference> uninitialized_copy(boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference> first,
+ boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference> last,
+ boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference> dst) {
+ return std::copy(first,last,dst);
+}
+
+} // namespace std
+#endif

Added: trunk/boost/gil/bit_aligned_pixel_reference.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/gil/bit_aligned_pixel_reference.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -0,0 +1,297 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
+#ifndef GIL_BIT_ALIGNED_PIXEL_REFERENCE_HPP
+#define GIL_BIT_ALIGNED_PIXEL_REFERENCE_HPP
+
+////////////////////////////////////////////////////////////////////////////////////////
+/// \file
+/// \brief A model of a heterogeneous pixel that is not byte aligned. Examples are bitmap (1-bit pixels) or 6-bit RGB (222)
+/// \author Lubomir Bourdev and Hailin Jin \n
+/// Adobe Systems Incorporated
+/// \date 2005-2007 \n Last updated on September 28, 2006
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+#include <functional>
+#include <boost/mpl/accumulate.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/plus.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/mpl/vector.hpp>
+#include "gil_config.hpp"
+#include "pixel.hpp"
+#include "channel.hpp"
+
+namespace boost { namespace gil {
+
+/////////////////////////////
+// bit_range
+//
+// Represents a range of bits that can span multiple consecutive bytes. The range has a size fixed at compile time, but the offset is specified at run time.
+/////////////////////////////
+
+template <int RangeSize, bool Mutable>
+class bit_range {
+public:
+ typedef typename mpl::if_c<Mutable,unsigned char,const unsigned char>::type byte_t;
+ typedef std::ptrdiff_t difference_type;
+ template <int RS, bool M> friend class bit_range;
+private:
+ byte_t* _current_byte; // the starting byte of the bit range
+ int _bit_offset; // offset from the beginning of the current byte. 0<=_bit_offset<=7
+
+public:
+ bit_range() : _current_byte(NULL), _bit_offset(0) {}
+ bit_range(byte_t* current_byte, int bit_offset) : _current_byte(current_byte), _bit_offset(bit_offset) { assert(bit_offset>=0 && bit_offset<8); }
+
+ bit_range(const bit_range& br) : _current_byte(br._current_byte), _bit_offset(br._bit_offset) {}
+ template <bool M> bit_range(const bit_range<RangeSize,M>& br) : _current_byte(br._current_byte), _bit_offset(br._bit_offset) {}
+
+ bit_range& operator=(const bit_range& br) { _current_byte = br._current_byte; _bit_offset=br._bit_offset; return *this; }
+ bool operator==(const bit_range& br) const { return _current_byte==br._current_byte && _bit_offset==br._bit_offset; }
+
+ bit_range& operator++() {
+ _current_byte += (_bit_offset+RangeSize) / 8;
+ _bit_offset = (_bit_offset+RangeSize) % 8;
+ return *this;
+ }
+ bit_range& operator--() { bit_advance(-RangeSize); return *this; }
+
+ void bit_advance(difference_type num_bits) {
+ int new_offset = int(_bit_offset+num_bits);
+ _current_byte += new_offset / 8;
+ _bit_offset = new_offset % 8;
+ if (_bit_offset<0) {
+ _bit_offset+=8;
+ --_current_byte;
+ }
+ }
+ difference_type bit_distance_to(const bit_range& b) const {
+ return (b.current_byte() - current_byte())*8 + b.bit_offset()-bit_offset();
+ }
+ byte_t* current_byte() const { return _current_byte; }
+ int bit_offset() const { return _bit_offset; }
+};
+
+
+/// \defgroup ColorBaseModelNonAlignedPixel bit_aligned_pixel_reference
+/// \ingroup ColorBaseModel
+/// \brief A heterogeneous color base representing pixel that may not be byte aligned, i.e. it may correspond to a bit range that does not start/end at a byte boundary. Models ColorBaseConcept.
+
+/**
+\defgroup PixelModelNonAlignedPixel bit_aligned_pixel_reference
+\ingroup PixelModel
+\brief A heterogeneous pixel reference used to represent non-byte-aligned pixels. Models PixelConcept
+
+Example:
+\code
+unsigned char data=0;
+
+// A mutable reference to a 6-bit BGR pixel in "123" format (1 bit for red, 2 bits for green, 3 bits for blue)
+typedef const bit_aligned_pixel_reference<mpl::vector3_c<int,1,2,3>, rgb_layout_t, true> rgb123_ref_t;
+
+// create the pixel reference at bit offset 2
+// (i.e. red = [2], green = [3,4], blue = [5,6,7] bits)
+rgb123_ref_t ref(&data, 2);
+get_color(ref, red_t()) = 1;
+assert(data == 0x04);
+get_color(ref, green_t()) = 3;
+assert(data == 0x1C);
+get_color(ref, blue_t()) = 7;
+assert(data == 0xFC);
+\endcode
+*/
+/// \ingroup ColorBaseModelNonAlignedPixel PixelModelNonAlignedPixel PixelBasedModel
+/// \brief Heterogeneous pixel reference corresponding to non-byte-aligned bit range. Models ColorBaseConcept, PixelConcept, PixelBasedConcept
+template <typename ChannelBitSizes, // MPL integral vector defining the number of bits for each channel. For example, for 565RGB, vector_c<int,5,6,5>
+ typename Layout,
+ bool IsMutable>
+struct bit_aligned_pixel_reference {
+ BOOST_STATIC_CONSTANT(int, bit_size = (mpl::accumulate<ChannelBitSizes, mpl::int_<0>, mpl::plus<mpl::_1, mpl::_2> >::type::value));
+ typedef bit_range<bit_size,IsMutable> bit_range_t;
+ typedef typename detail::min_fast_uint<bit_size>::type bitfield_t;
+ typedef typename mpl::if_c<IsMutable,unsigned char*,const unsigned char*>::type data_ptr_t;
+
+ typedef Layout layout_t;
+
+ typedef typename packed_pixel_type<bitfield_t,ChannelBitSizes,Layout>::type value_type;
+ typedef const bit_aligned_pixel_reference reference;
+ typedef const bit_aligned_pixel_reference<ChannelBitSizes,Layout,false> const_reference;
+
+ BOOST_STATIC_CONSTANT(bool, is_mutable = IsMutable);
+
+ bit_aligned_pixel_reference(){}
+ bit_aligned_pixel_reference(data_ptr_t data_ptr, int bit_offset) : _bit_range(data_ptr, bit_offset) {}
+ explicit bit_aligned_pixel_reference(const bit_range_t& bit_range) : _bit_range(bit_range) {}
+ template <bool IsMutable2> bit_aligned_pixel_reference(const bit_aligned_pixel_reference<ChannelBitSizes,Layout,IsMutable2>& p) : _bit_range(p._bit_range) {}
+
+ // Grayscale references can be constructed from the channel reference
+ 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()) {
+ BOOST_STATIC_ASSERT((num_channels<bit_aligned_pixel_reference>::value==1));
+ }
+
+ // Construct from another compatible pixel type
+ bit_aligned_pixel_reference(const bit_aligned_pixel_reference& p) : _bit_range(p._bit_range) {}
+ template <typename BF, typename CR> bit_aligned_pixel_reference(packed_pixel<BF,CR,Layout>& p) : _bit_range(static_cast<data_ptr_t>(&at_c<0>(p)), at_c<0>(p).first_bit()) {
+ check_compatible<packed_pixel<BF,CR,Layout> >();
+ }
+
+ template <typename P> const bit_aligned_pixel_reference& operator=(const P& p) const { check_compatible<P>(); static_copy(p,*this); return *this; }
+ const bit_aligned_pixel_reference& operator=(const bit_aligned_pixel_reference& p) const { static_copy(p,*this); return *this; }
+
+ template <typename P> bool operator==(const P& p) const { check_compatible<P>(); return static_equal(*this,p); }
+ template <typename P> bool operator!=(const P& p) const { return !(*this==p); }
+
+ const bit_aligned_pixel_reference* operator->() const { return this; }
+
+ const bit_range_t& bit_range() const { return _bit_range; }
+private:
+ mutable bit_range_t _bit_range;
+ template <typename C, typename L, bool M> friend struct bit_aligned_pixel_reference;
+
+ template <typename Pixel> static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel,bit_aligned_pixel_reference> >(); }
+};
+
+/////////////////////////////
+// ColorBasedConcept
+/////////////////////////////
+
+template <typename ChannelBitSizes, typename L, bool IsMutable, int K>
+struct kth_element_type<bit_aligned_pixel_reference<ChannelBitSizes,L,IsMutable>, K> {
+private:
+ typedef typename bit_aligned_pixel_reference<ChannelBitSizes,L,IsMutable>::bitfield_t bitfield_t;
+public:
+ typedef const packed_dynamic_channel_reference<bitfield_t, mpl::at_c<ChannelBitSizes,K>::type::value, IsMutable> type;
+};
+
+template <typename C, typename L, bool M, int K>
+struct kth_element_reference_type<bit_aligned_pixel_reference<C,L,M>, K>
+ : public kth_element_type<bit_aligned_pixel_reference<C,L,M>, K> {};
+
+template <typename C, typename L, bool M, int K>
+struct kth_element_const_reference_type<bit_aligned_pixel_reference<C,L,M>, K>
+ : public kth_element_type<bit_aligned_pixel_reference<C,L,M>, K> {};
+
+
+namespace detail {
+ // returns sum of IntegralVector[0] ... IntegralVector[K-1]
+ template <typename IntegralVector, int K>
+ struct sum_k : public mpl::plus<sum_k<IntegralVector,K-1>, typename mpl::at_c<IntegralVector,K-1>::type > {};
+
+ template <typename IntegralVector> struct sum_k<IntegralVector,0> : public mpl::int_<0> {};
+}
+
+// at_c required by MutableColorBaseConcept
+template <int K, typename ChannelBitSizes, typename L, bool Mutable> inline
+typename kth_element_reference_type<bit_aligned_pixel_reference<ChannelBitSizes,L,Mutable>,K>::type
+at_c(const bit_aligned_pixel_reference<ChannelBitSizes,L,Mutable>& p) {
+ typedef bit_aligned_pixel_reference<ChannelBitSizes,L,Mutable> pixel_t;
+ typedef typename kth_element_reference_type<pixel_t,K>::type channel_t;
+ typedef typename pixel_t::bit_range_t bit_range_t;
+
+ bit_range_t bit_range(p.bit_range());
+ bit_range.bit_advance(detail::sum_k<ChannelBitSizes,K>::value);
+
+ return channel_t(bit_range.current_byte(), bit_range.bit_offset());
+}
+
+/////////////////////////////
+// PixelConcept
+/////////////////////////////
+
+/// Metafunction predicate that flags bit_aligned_pixel_reference as a model of PixelConcept. Required by PixelConcept
+template <typename C, typename L, bool M>
+struct is_pixel<bit_aligned_pixel_reference<C,L,M> > : public mpl::true_{};
+
+/////////////////////////////
+// PixelBasedConcept
+/////////////////////////////
+
+template <typename C, typename L, bool M>
+struct color_space_type<bit_aligned_pixel_reference<C,L,M> > {
+ typedef typename L::color_space_t type;
+};
+
+template <typename C, typename L, bool M>
+struct channel_mapping_type<bit_aligned_pixel_reference<C,L,M> > {
+ typedef typename L::channel_mapping_t type;
+};
+
+template <typename C, typename L, bool M>
+struct is_planar<bit_aligned_pixel_reference<C,L,M> > : mpl::false_ {};
+
+/////////////////////////////
+// pixel_reference_type
+/////////////////////////////
+
+namespace detail {
+ // returns a vector containing K copies of the type T
+ template <unsigned K, typename T> struct k_copies;
+ template <typename T> struct k_copies<0,T> {
+ typedef mpl::vector0<> type;
+ };
+ template <unsigned K, typename T> struct k_copies : public mpl::push_back<typename k_copies<K-1,T>::type, T> {};
+}
+
+// Constructs a homogeneous bit_aligned_pixel_reference given a channel reference
+// Note: BitField must be the same type as pixel_reference_type<...>::type::bitfield_t, but it is too complicated to ensure this
+template <typename BitField, int NumBits, typename Layout>
+struct pixel_reference_type<const packed_dynamic_channel_reference<BitField,NumBits,false>, Layout, false, false> {
+private:
+ typedef typename mpl::size<typename Layout::color_space_t>::type size_t;
+ typedef typename detail::k_copies<size_t::value,mpl::integral_c<unsigned,NumBits> >::type channel_bit_sizes_t;
+public:
+ typedef bit_aligned_pixel_reference<channel_bit_sizes_t, Layout, false> type;
+};
+
+// Same but for the mutable case. We cannot combine the mutable and read-only cases because this triggers ambiguity
+// Note: BitField must be the same type as pixel_reference_type<...>::type::bitfield_t, but it is too complicated to ensure this
+template <typename BitField, int NumBits, typename Layout>
+struct pixel_reference_type<const packed_dynamic_channel_reference<BitField,NumBits,true>, Layout, false, true> {
+private:
+ typedef typename mpl::size<typename Layout::color_space_t>::type size_t;
+ typedef typename detail::k_copies<size_t::value,mpl::integral_c<unsigned,NumBits> >::type channel_bit_sizes_t;
+public:
+ typedef bit_aligned_pixel_reference<channel_bit_sizes_t, Layout, true> type;
+};
+
+} } // namespace boost::gil
+
+namespace std {
+// We are forced to define swap inside std namespace because on some platforms (Visual Studio 8) STL calls swap qualified.
+// swap with 'left bias':
+// - swap between proxy and anything
+// - swap between value type and proxy
+// - swap between proxy and proxy
+// Having three overloads allows us to swap between different (but compatible) models of PixelConcept
+
+template <typename C, typename L, typename R> inline
+void swap(boost::gil::bit_aligned_pixel_reference<C,L,true> x, R& y) {
+ boost::gil::swap_proxy<typename boost::gil::bit_aligned_pixel_reference<C,L,true>::value_type>(x,y);
+}
+
+
+template <typename C, typename L> inline
+void swap(typename boost::gil::bit_aligned_pixel_reference<C,L,true>::value_type& x, boost::gil::bit_aligned_pixel_reference<C,L,true> y) {
+ boost::gil::swap_proxy<typename boost::gil::bit_aligned_pixel_reference<C,L,true>::value_type>(x,y);
+}
+
+
+template <typename C, typename L> inline
+void swap(boost::gil::bit_aligned_pixel_reference<C,L,true> x, boost::gil::bit_aligned_pixel_reference<C,L,true> y) {
+ boost::gil::swap_proxy<typename boost::gil::bit_aligned_pixel_reference<C,L,true>::value_type>(x,y);
+}
+} // namespace std
+#endif

Modified: trunk/boost/gil/channel.hpp
==============================================================================
--- trunk/boost/gil/channel.hpp (original)
+++ trunk/boost/gil/channel.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -51,8 +51,7 @@
 namespace detail {
     template <typename T, bool is_class> struct channel_traits_impl;
 
- /// \brief channel traits for custom class
- /// \ingroup ChannelModel
+ // channel traits for custom class
     template <typename T>
     struct channel_traits_impl<T, true> {
         typedef typename T::value_type value_type;
@@ -65,8 +64,7 @@
         static value_type max_value() { return T::max_value(); }
     };
 
- /// \brief channel traits implementation for built-in scalar or floating point channel type
- /// \ingroup ChannelModel
+ // channel traits implementation for built-in integral or floating point channel type
     template <typename T>
     struct channel_traits_impl<T, false> {
         typedef T value_type;
@@ -79,8 +77,7 @@
         static value_type max_value() { return (std::numeric_limits<T>::max)(); }
     };
 
- /// \brief channel traits implementation for constant built-in scalar or floating point type
- /// \ingroup ChannelModel
+ // channel traits implementation for constant built-in scalar or floating point type
     template <typename T>
     struct channel_traits_impl<const T, false> : public channel_traits_impl<T, false> {
         typedef const T& reference;
@@ -89,15 +86,31 @@
     };
 }
 
+/**
+\ingroup ChannelModel
+\brief Traits for channels. Contains the following members:
+\code
+template <typename Channel>
+struct channel_traits {
+ typedef ... value_type;
+ typedef ... reference;
+ typedef ... pointer;
+ typedef ... const_reference;
+ typedef ... const_pointer;
+
+ static const bool is_mutable;
+ static value_type min_value();
+ static value_type max_value();
+};
+\endcode
+*/
 template <typename T>
 struct channel_traits : public detail::channel_traits_impl<T, is_class<T>::value> {};
 
-/// \ingroup ChannelModel
-/// \brief Channel traits for C++ reference type - remove the reference
+// Channel traits for C++ reference type - remove the reference
 template <typename T> struct channel_traits< T&> : public channel_traits<T> {};
 
-/// \ingroup ChannelModel
-/// \brief Channel traits for constant C++ reference type
+// Channel traits for constant C++ reference type
 template <typename T> struct channel_traits<const T&> : public channel_traits<T> {
     typedef typename channel_traits<T>::const_reference reference;
     typedef typename channel_traits<T>::const_pointer pointer;
@@ -110,9 +123,25 @@
 ////
 ///////////////////////////////////////////
 
-/// \defgroup ScopedChannelValue scoped_channel_value
-/// \ingroup ChannelModel
-/// \brief A channel adaptor that modifies the range of the source channel. Models: ChannelValueConcept
+/**
+\defgroup ScopedChannelValue scoped_channel_value
+\ingroup ChannelModel
+\brief A channel adaptor that modifies the range of the source channel. Models: ChannelValueConcept
+
+Example:
+\code
+// Create a double channel with range [-0.5 .. 0.5]
+struct double_minus_half { static double apply() { return -0.5; } };
+struct double_plus_half { static double apply() { return 0.5; } };
+typedef scoped_channel_value<double, double_minus_half, double_plus_half> bits64custom_t;
+
+// channel_convert its maximum should map to the maximum
+bits64custom_t x = channel_traits<bits64custom_t>::max_value();
+assert(x == 0.5);
+bits16 y = channel_convert<bits16>(x);
+assert(y == 65535);
+\endcode
+*/
 
 /// \ingroup ScopedChannelValue
 /// \brief A channel adaptor that modifies the range of the source channel. Models: ChannelValueConcept
@@ -167,14 +196,33 @@
 namespace detail {
     // returns the smallest fast unsigned integral type that has at least NumBits bits
     template <int NumBits>
- struct min_fast_uint : public mpl::if_c< (NumBits<8),
+ struct min_fast_uint : public mpl::if_c< (NumBits<=8),
             uint_least8_t,
- typename mpl::if_c< (NumBits<16), uint_least16_t,
- uint_least32_t>::type > {};
+ typename mpl::if_c< (NumBits<=16),
+ uint_least16_t,
+ typename mpl::if_c< (NumBits<=32),
+ uint_least32_t,
+ uintmax_t
+ >::type
+ >::type
+ > {};
 }
-/// \defgroup PackedChannelValueModel packed_channel_value
-/// \ingroup ChannelModel
-/// \brief Represents the value of an unsigned integral channel operating over a bit range. Models: ChannelValueConcept
+
+/**
+\defgroup PackedChannelValueModel packed_channel_value
+\ingroup ChannelModel
+\brief Represents the value of an unsigned integral channel operating over a bit range. Models: ChannelValueConcept
+Example:
+\code
+// A 4-bit unsigned integral channel.
+typedef packed_channel_value<4> bits4;
+
+assert(channel_traits<bits4>::min_value()==0);
+assert(channel_traits<bits4>::max_value()==15);
+assert(sizeof(bits4)==1);
+BOOST_STATIC_ASSERT((boost::is_integral<bits4>::value));
+\endcode
+*/
 
 /// \ingroup PackedChannelValueModel
 /// \brief The value of a subbyte channel. Models: ChannelValueConcept
@@ -208,24 +256,25 @@
 template <typename Derived, typename BitField, int NumBits, bool Mutable>
 class packed_channel_reference_base {
 protected:
- typedef typename mpl::if_c<Mutable,BitField&,const BitField&>::type data_ref_t;
- data_ref_t _data;
-
- static const BitField max_val = (1<<NumBits) - 1;
+ typedef typename mpl::if_c<Mutable,void*,const void*>::type data_ptr_t;
 public:
+ data_ptr_t _data_ptr; // void* pointer to the first byte of the bit range
+
     typedef packed_channel_value<NumBits> value_type;
     typedef const Derived reference;
     typedef value_type* pointer;
     typedef const value_type* const_pointer;
+ BOOST_STATIC_CONSTANT(int, num_bits=NumBits);
     BOOST_STATIC_CONSTANT(bool, is_mutable=Mutable);
 
     static value_type min_value() { return channel_traits<value_type>::min_value(); }
     static value_type max_value() { return channel_traits<value_type>::max_value(); }
 
+ typedef BitField bitfield_t;
     typedef typename value_type::integer_t integer_t;
 
- packed_channel_reference_base(data_ref_t data) : _data(data) {}
- packed_channel_reference_base(const packed_channel_reference_base& ref) : _data(ref._data) {}
+ packed_channel_reference_base(data_ptr_t data_ptr) : _data_ptr(data_ptr) {}
+ packed_channel_reference_base(const packed_channel_reference_base& ref) : _data_ptr(ref._data_ptr) {}
     const Derived& operator=(integer_t v) const { set(v); return derived(); }
 
     const Derived& operator++() const { set(get()+1); return derived(); }
@@ -240,7 +289,11 @@
     template <typename Scalar2> const Derived& operator/=(Scalar2 v) const { set(get()/v); return derived(); }
 
     operator integer_t() const { return get(); }
- BitField* operator &() const {return &_data;}
+ data_ptr_t operator &() const {return _data_ptr;}
+protected:
+ static const integer_t max_val = (1<<NumBits) - 1;
+ const bitfield_t& const_data() const { return *static_cast<const bitfield_t*>(_data_ptr); }
+ bitfield_t& data() const { return *static_cast< bitfield_t*>(_data_ptr); }
 private:
     void set(integer_t value) const { // can this be done faster??
         const integer_t num_values = max_val+1;
@@ -251,34 +304,54 @@
 };
 } // namespace detail
 
-/// \defgroup PackedChannelReferenceModel packed_channel_reference
-/// \ingroup ChannelModel
-/// \brief Represents a reference proxy to a channel operating over a bit range whose offset is fixed at compile time. Models ChannelConcept
+/**
+\defgroup PackedChannelReferenceModel packed_channel_reference
+\ingroup ChannelModel
+\brief Represents a reference proxy to a channel operating over a bit range whose offset is fixed at compile time. Models ChannelConcept
+Example:
+\code
+// Reference to a 2-bit channel starting at bit 1 (i.e. the second bit)
+typedef const packed_channel_reference<uint16_t,1,2,true> bits2_1_ref_t;
+
+uint16_t data=0;
+bits2_1_ref_t channel_ref(&data);
+channel_ref = channel_traits<bits2_1_ref_t>::max_value(); // == 3
+assert(data == 6); // == 3<<1 == 6
+\endcode
+*/
 
-template <typename BitField, // An integral type (the data type containing the bits of interest). Models unsigned integer
+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
           int FirstBit, int NumBits,// Defines the sequence of bits in the data value that contain the channel
           bool Mutable> // true if the reference is mutable
 class packed_channel_reference;
 
+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
+ int NumBits, // Defines the sequence of bits in the data value that contain the channel
+ bool Mutable> // true if the reference is mutable
+class packed_dynamic_channel_reference;
+
 /// \ingroup PackedChannelReferenceModel
 /// \brief A constant subbyte channel reference whose bit offset is fixed at compile time. Models ChannelConcept
 template <typename BitField, int FirstBit, int NumBits>
 class packed_channel_reference<BitField,FirstBit,NumBits,false>
    : public detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,false>,BitField,NumBits,false> {
     typedef detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,false>,BitField,NumBits,false> parent_t;
- static const BitField channel_mask = parent_t::max_val<<FirstBit;
- typedef typename parent_t::integer_t integer_t;
-
- typedef packed_channel_reference<BitField,FirstBit,NumBits,true> mutable_reference;
     friend class packed_channel_reference<BitField,FirstBit,NumBits,true>;
+
+ static const BitField channel_mask = parent_t::max_val<<FirstBit;
+ void operator=(const packed_channel_reference&);
 public:
- typedef const packed_channel_reference const_reference;
+ typedef const packed_channel_reference<BitField,FirstBit,NumBits,false> const_reference;
+ typedef const packed_channel_reference<BitField,FirstBit,NumBits,true> mutable_reference;
+ typedef typename parent_t::integer_t integer_t;
+
+ explicit packed_channel_reference(const void* data_ptr) : parent_t(data_ptr) {}
+ packed_channel_reference(const packed_channel_reference& ref) : parent_t(ref._data_ptr) {}
+ packed_channel_reference(const mutable_reference& ref) : parent_t(ref._data_ptr) {}
 
- explicit packed_channel_reference(const BitField& data) : parent_t(data) {}
- packed_channel_reference(const packed_channel_reference& ref) : parent_t(ref._data) {}
- packed_channel_reference(const mutable_reference& ref) : parent_t(ref._data) {}
+ unsigned first_bit() const { return FirstBit; }
 
- integer_t get() const { return (this->_data&(parent_t::max_val<<FirstBit)) >> FirstBit; }
+ integer_t get() const { return integer_t((this->const_data()&channel_mask) >> FirstBit); }
 };
 
 /// \ingroup PackedChannelReferenceModel
@@ -287,24 +360,30 @@
 class packed_channel_reference<BitField,FirstBit,NumBits,true>
    : public detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,true>,BitField,NumBits,true> {
     typedef detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,true>,BitField,NumBits,true> parent_t;
- static const BitField channel_mask = parent_t::max_val<<FirstBit;
-
- typedef typename parent_t::integer_t integer_t;
     friend class packed_channel_reference<BitField,FirstBit,NumBits,false>;
+
+ static const BitField channel_mask = parent_t::max_val<<FirstBit;
 public:
- typedef packed_channel_reference<BitField,FirstBit,NumBits,false> const_reference;
+ typedef const packed_channel_reference<BitField,FirstBit,NumBits,false> const_reference;
+ typedef const packed_channel_reference<BitField,FirstBit,NumBits,true> mutable_reference;
+ typedef typename parent_t::integer_t integer_t;
 
- explicit packed_channel_reference(BitField& data) : parent_t(data) {}
- packed_channel_reference(const packed_channel_reference& ref) : parent_t(ref._data) {}
+ explicit packed_channel_reference(void* data_ptr) : parent_t(data_ptr) {}
+ packed_channel_reference(const packed_channel_reference& ref) : parent_t(ref._data_ptr) {}
 
     const packed_channel_reference& operator=(integer_t value) const { assert(value<=parent_t::max_val); set_unsafe(value); return *this; }
- const packed_channel_reference& operator=(const packed_channel_reference& ref) const { set_from_reference(ref._data); return *this; }
- const packed_channel_reference& operator=(const const_reference& ref) const { set_from_reference(ref._data); return *this; }
+ const packed_channel_reference& operator=(const mutable_reference& ref) const { set_from_reference(ref.data()); return *this; }
+ const packed_channel_reference& operator=(const const_reference& ref) const { set_from_reference(ref.const_data()); return *this; }
+
+ template <bool Mutable1>
+ const packed_channel_reference& operator=(const packed_dynamic_channel_reference<BitField,NumBits,Mutable1>& ref) const { set_unsafe(ref.get()); return *this; }
 
- integer_t get() const { return (this->_data&channel_mask) >> FirstBit; }
- void set_unsafe(integer_t value) const { this->_data = (this->_data & ~channel_mask) | (value<<FirstBit); }
+ unsigned first_bit() const { return FirstBit; }
+
+ integer_t get() const { return integer_t((this->const_data()&channel_mask) >> FirstBit); }
+ void set_unsafe(integer_t value) const { this->data() = (this->const_data() & ~channel_mask) | (value<<FirstBit); }
 private:
- void set_from_reference(const BitField& data) const { this->_data = (this->_data & ~channel_mask) | (data & channel_mask); }
+ void set_from_reference(const BitField& other_bits) const { this->data() = (this->const_data() & ~channel_mask) | (other_bits & channel_mask); }
 };
 
 } } // namespace boost::gil
@@ -342,16 +421,22 @@
 
 namespace boost { namespace gil {
 
-
-
-/// \defgroup PackedChannelDynamicReferenceModel packed_dynamic_channel_reference
-/// \ingroup ChannelModel
-/// \brief Represents a reference proxy to a channel operating over a bit range whose offset is specified at run time. Models ChannelConcept
-
-template <typename BitField, // An integral type (the data type containing the bits of interest). Models unsigned integer
- int NumBits, // Defines the sequence of bits in the data value that contain the channel
- bool Mutable> // true if the reference is mutable
-class packed_dynamic_channel_reference;
+/**
+\defgroup PackedChannelDynamicReferenceModel packed_dynamic_channel_reference
+\ingroup ChannelModel
+\brief Represents a reference proxy to a channel operating over a bit range whose offset is specified at run time. Models ChannelConcept
+
+Example:
+\code
+// Reference to a 2-bit channel whose offset is specified at construction time
+typedef const packed_dynamic_channel_reference<uint8_t,2,true> bits2_dynamic_ref_t;
+
+uint16_t data=0;
+bits2_dynamic_ref_t channel_ref(&data,1);
+channel_ref = channel_traits<bits2_dynamic_ref_t>::max_value(); // == 3
+assert(data == 6); // == (3<<1) == 6
+\endcode
+*/
 
 /// \brief 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
@@ -360,20 +445,25 @@
 class packed_dynamic_channel_reference<BitField,NumBits,false>
    : public detail::packed_channel_reference_base<packed_dynamic_channel_reference<BitField,NumBits,false>,BitField,NumBits,false> {
     typedef detail::packed_channel_reference_base<packed_dynamic_channel_reference<BitField,NumBits,false>,BitField,NumBits,false> parent_t;
- int _first_bit;
+ friend class packed_dynamic_channel_reference<BitField,NumBits,true>;
 
- typedef packed_dynamic_channel_reference<BitField,NumBits,true> mutable_reference;
- typedef typename parent_t::integer_t integer_t;
+ unsigned _first_bit; // 0..7
+
+ void operator=(const packed_dynamic_channel_reference&);
 public:
- typedef packed_dynamic_channel_reference<BitField,NumBits,false> const_reference;
+ typedef const packed_dynamic_channel_reference<BitField,NumBits,false> const_reference;
+ typedef const packed_dynamic_channel_reference<BitField,NumBits,true> mutable_reference;
+ typedef typename parent_t::integer_t integer_t;
+
+ packed_dynamic_channel_reference(const void* data_ptr, unsigned first_bit) : parent_t(data_ptr), _first_bit(first_bit) {}
+ packed_dynamic_channel_reference(const const_reference& ref) : parent_t(ref._data_ptr), _first_bit(ref._first_bit) {}
+ packed_dynamic_channel_reference(const mutable_reference& ref) : parent_t(ref._data_ptr), _first_bit(ref._first_bit) {}
 
- packed_dynamic_channel_reference(typename parent_t::data_ref_t data, int first_bit) : parent_t(data), _first_bit(first_bit) {}
- packed_dynamic_channel_reference(const packed_dynamic_channel_reference& ref) : parent_t(ref._data), _first_bit(ref._first_bit) {}
- packed_dynamic_channel_reference(const mutable_reference& ref) : parent_t(ref._data), _first_bit(ref._first_bit) {}
+ unsigned first_bit() const { return _first_bit; }
 
     integer_t get() const {
         const BitField channel_mask = parent_t::max_val<<_first_bit;
- return (this->_data&channel_mask) >> _first_bit;
+ return (this->const_data()&channel_mask) >> _first_bit;
     }
 };
 
@@ -384,26 +474,35 @@
 class packed_dynamic_channel_reference<BitField,NumBits,true>
    : public detail::packed_channel_reference_base<packed_dynamic_channel_reference<BitField,NumBits,true>,BitField,NumBits,true> {
     typedef detail::packed_channel_reference_base<packed_dynamic_channel_reference<BitField,NumBits,true>,BitField,NumBits,true> parent_t;
- int _first_bit;
+ friend class packed_dynamic_channel_reference<BitField,NumBits,false>;
+
+ unsigned _first_bit;
 
- typedef typename parent_t::integer_t integer_t;
 public:
- typedef packed_dynamic_channel_reference<BitField,NumBits,false> const_reference;
+ typedef const packed_dynamic_channel_reference<BitField,NumBits,false> const_reference;
+ typedef const packed_dynamic_channel_reference<BitField,NumBits,true> mutable_reference;
+ typedef typename parent_t::integer_t integer_t;
 
- packed_dynamic_channel_reference(typename parent_t::data_ref_t data, int first_bit) : parent_t(data), _first_bit(first_bit) {}
- packed_dynamic_channel_reference(const packed_dynamic_channel_reference& ref) : parent_t(ref._data), _first_bit(ref._first_bit) {}
+ packed_dynamic_channel_reference(void* data_ptr, unsigned first_bit) : parent_t((((char*)data_ptr)+first_bit/8)), _first_bit(first_bit%8) {}
+ packed_dynamic_channel_reference(const packed_dynamic_channel_reference& ref) : parent_t(ref._data_ptr), _first_bit(ref._first_bit) {}
 
     const packed_dynamic_channel_reference& operator=(integer_t value) const { assert(value<=parent_t::max_val); set_unsafe(value); return *this; }
- const packed_dynamic_channel_reference& operator=(const packed_dynamic_channel_reference& ref) const { set_unsafe(ref.get()); return *this; }
- const packed_dynamic_channel_reference& operator=(const const_reference& ref) const { set_unsafe(ref.get()); return *this; }
+ const packed_dynamic_channel_reference& operator=(const mutable_reference& ref) const { set_unsafe(ref.get()); return *this; }
+ const packed_dynamic_channel_reference& operator=(const const_reference& ref) const { set_unsafe(ref.get()); return *this; }
+
+ template <typename BitField1, int FirstBit1, bool Mutable1>
+ const packed_dynamic_channel_reference& operator=(const packed_channel_reference<BitField1, FirstBit1, NumBits, Mutable1>& ref) const
+ { set_unsafe(ref.get()); return *this; }
+
+ unsigned first_bit() const { return _first_bit; }
 
     integer_t get() const {
         const BitField channel_mask = parent_t::max_val<<_first_bit;
- return (this->_data&channel_mask) >> _first_bit;
+ return (this->const_data()&channel_mask) >> _first_bit;
     }
     void set_unsafe(integer_t value) const {
         const BitField channel_mask = parent_t::max_val<<_first_bit;
- this->_data = (this->_data & ~channel_mask) | value<<_first_bit;
+ this->data() = (this->const_data() & ~channel_mask) | value<<_first_bit;
     }
 };
 } } // namespace boost::gil
@@ -449,42 +548,42 @@
 
 /// \defgroup bits8 bits8
 /// \ingroup ChannelModel
-/// \brief 8-bit unsigned integral channel type. Models ChannelValueConcept
+/// \brief 8-bit unsigned integral channel type (typedef from uint8_t). Models ChannelValueConcept
 
 /// \ingroup bits8
 typedef uint8_t bits8;
 
 /// \defgroup bits16 bits16
 /// \ingroup ChannelModel
-/// \brief 16-bit unsigned integral channel type. Models ChannelValueConcept
+/// \brief 16-bit unsigned integral channel type (typedef from uint16_t). Models ChannelValueConcept
 
 /// \ingroup bits16
 typedef uint16_t bits16;
 
 /// \defgroup bits32 bits32
 /// \ingroup ChannelModel
-/// \brief 32-bit unsigned integral channel type. Models ChannelValueConcept
+/// \brief 32-bit unsigned integral channel type (typedef from uint32_t). Models ChannelValueConcept
 
 /// \ingroup bits32
 typedef uint32_t bits32;
 
 /// \defgroup bits8s bits8s
 /// \ingroup ChannelModel
-/// \brief 8-bit signed integral channel type. Models ChannelValueConcept
+/// \brief 8-bit signed integral channel type (typedef from int8_t). Models ChannelValueConcept
 
 /// \ingroup bits8s
 typedef int8_t bits8s;
 
 /// \defgroup bits16s bits16s
 /// \ingroup ChannelModel
-/// \brief 16-bit signed integral channel type. Models ChannelValueConcept
+/// \brief 16-bit signed integral channel type (typedef from int16_t). Models ChannelValueConcept
 
 /// \ingroup bits16s
 typedef int16_t bits16s;
 
 /// \defgroup bits32s bits32s
 /// \ingroup ChannelModel
-/// \brief 32-bit signed integral channel type. Models ChannelValueConcept
+/// \brief 32-bit signed integral channel type (typedef from int32_t). Models ChannelValueConcept
 
 /// \ingroup bits32s
 typedef int32_t bits32s;
@@ -498,5 +597,20 @@
 
 } } // namespace boost::gil
 
+namespace boost {
+
+template <int NumBits>
+struct is_integral<gil::packed_channel_value<NumBits> > : public mpl::true_ {};
+
+template <typename BitField, int FirstBit, int NumBits, bool IsMutable>
+struct is_integral<gil::packed_channel_reference<BitField,FirstBit,NumBits,IsMutable> > : public mpl::true_ {};
+
+template <typename BitField, int NumBits, bool IsMutable>
+struct is_integral<gil::packed_dynamic_channel_reference<BitField,NumBits,IsMutable> > : public mpl::true_ {};
+
+template <typename BaseChannelValue, typename MinVal, typename MaxVal>
+struct is_integral<gil::scoped_channel_value<BaseChannelValue,MinVal,MaxVal> > : public is_integral<BaseChannelValue> {};
+
+}
 
 #endif

Modified: trunk/boost/gil/channel_algorithm.hpp
==============================================================================
--- trunk/boost/gil/channel_algorithm.hpp (original)
+++ trunk/boost/gil/channel_algorithm.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -25,9 +25,59 @@
 
 #include "gil_config.hpp"
 #include "channel.hpp"
+#include <boost/mpl/less.hpp>
+#include <boost/mpl/integral_c.hpp>
+#include <boost/mpl/greater.hpp>
+#include <boost/type_traits.hpp>
 
 namespace boost { namespace gil {
 
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4309) // disable truncation of constant value warning (using -1 to get the max value of an integral)
+#endif
+
+namespace detail {
+
+// some forward declarations
+template <typename SrcChannelV, typename DstChannelV, bool SrcIsIntegral, bool DstIsIntegral> struct channel_converter_unsigned_impl;
+template <typename SrcChannelV, typename DstChannelV, bool SrcIsGreater> struct channel_converter_unsigned_integral;
+template <typename SrcChannelV, typename DstChannelV, bool SrcLessThanDst, bool SrcDivisible> struct channel_converter_unsigned_integral_impl;
+template <typename SrcChannelV, typename DstChannelV, bool SrcLessThanDst, bool CannotFitInInteger> struct channel_converter_unsigned_integral_nondivisible;
+
+//////////////////////////////////////
+//// unsigned_integral_max_value - given an unsigned integral channel type, returns its maximum value as an MPL integral constant
+//////////////////////////////////////
+
+
+template <typename UnsignedIntegralChannel>
+struct unsigned_integral_max_value : public mpl::integral_c<UnsignedIntegralChannel,-1> {};
+
+template <>
+struct unsigned_integral_max_value<uint8_t> : public mpl::integral_c<uint32_t,0xFF> {};
+template <>
+struct unsigned_integral_max_value<uint16_t> : public mpl::integral_c<uint32_t,0xFFFF> {};
+template <>
+struct unsigned_integral_max_value<uint32_t> : public mpl::integral_c<uintmax_t,0xFFFFFFFF> {};
+
+
+template <int K>
+struct unsigned_integral_max_value<packed_channel_value<K> >
+ : public mpl::integral_c<typename packed_channel_value<K>::integer_t, (1<<K)-1> {};
+
+//////////////////////////////////////
+//// unsigned_integral_num_bits - given an unsigned integral channel type, returns the minimum number of bits needed to represent it
+//////////////////////////////////////
+
+template <typename UnsignedIntegralChannel>
+struct unsigned_integral_num_bits : public mpl::int_<sizeof(UnsignedIntegralChannel)*8> {};
+
+template <int K>
+struct unsigned_integral_num_bits<packed_channel_value<K> >
+ : public mpl::int_<K> {};
+
+} // namespace detail
+
 /**
 \defgroup ChannelConvertAlgorithm channel_convert
 \brief Converting from one channel type to another
@@ -39,8 +89,19 @@
 
 When creating new channel models, it is often a good idea to provide specializations for the channel conversion algorithms, for
 example, for performance optimizations. If the new model is an integral type that can be signed, it is easier to define the conversion
-only for the unsigned type (\p channel_converter_unsigned) and provide specializations of \p channel_convert_to_unsigned and \p channel_convert_to_signed
-to convert between the signed and unsigned type.
+only for the unsigned type (\p channel_converter_unsigned) and provide specializations of \p detail::channel_convert_to_unsigned
+and \p detail::channel_convert_from_unsigned to convert between the signed and unsigned type.
+
+Example:
+\code
+// bits32f is a floating point channel with range [0.0f ... 1.0f]
+bits32f src_channel = channel_traits<bits32f>::max_value();
+assert(src_channel == 1);
+
+// bits8 is 8-bit unsigned integral channel (typedef-ed from unsigned char)
+bits8 dst_channel = channel_convert<bits8>(src_channel);
+assert(dst_channel == 255); // max value goes to max value
+\endcode
 */
 
 /**
@@ -50,11 +111,31 @@
  @{
  */
 
-/// \brief This is the default implementation. Performance specializatons are provided
+//////////////////////////////////////
+//// channel_converter_unsigned
+//////////////////////////////////////
+
 template <typename SrcChannelV, typename DstChannelV> // Model ChannelValueConcept
-struct channel_converter_unsigned : public std::unary_function<DstChannelV,SrcChannelV> {
+struct channel_converter_unsigned
+ : public detail::channel_converter_unsigned_impl<SrcChannelV,DstChannelV,is_integral<SrcChannelV>::value,is_integral<DstChannelV>::value> {};
+
+
+/// \brief Converting a channel to itself - identity operation
+template <typename T> struct channel_converter_unsigned<T,T> : public detail::identity<T> {};
+
+
+namespace detail {
+
+//////////////////////////////////////
+//// channel_converter_unsigned_impl
+//////////////////////////////////////
+
+/// \brief This is the default implementation. Performance specializatons are provided
+template <typename SrcChannelV, typename DstChannelV, bool SrcIsIntegral, bool DstIsIntegral>
+struct channel_converter_unsigned_impl : public std::unary_function<DstChannelV,SrcChannelV> {
     DstChannelV operator()(SrcChannelV src) const {
- return DstChannelV(src / channel_range<SrcChannelV>() * channel_range<DstChannelV>());
+ return DstChannelV(channel_traits<DstChannelV>::min_value() +
+ (src - channel_traits<SrcChannelV>::min_value()) / channel_range<SrcChannelV>() * channel_range<DstChannelV>());
     }
 private:
     template <typename C>
@@ -63,54 +144,139 @@
     }
 };
 
-/// \brief Converting a channel to itself - identity operation
-template <typename T> struct channel_converter_unsigned<T,T> : public detail::identity<T> {};
-
-/// \brief 8 bit <-> 16 bit channel conversion
-template <> struct channel_converter_unsigned<bits16,bits8> : public std::unary_function<bits16,bits8> {
- bits8 operator()(bits16 x) const { return static_cast<bits8>(x/257); }
-};
-/// \brief 8 bit <-> 16 bit channel conversion
-template <> struct channel_converter_unsigned<bits8,bits16> : public std::unary_function<bits8,bits16> {
- bits16 operator()(bits8 x) const { return static_cast<bits16>(x*257); }
+// When both the source and the destination are integral channels, perform a faster conversion
+template <typename SrcChannelV, typename DstChannelV>
+struct channel_converter_unsigned_impl<SrcChannelV,DstChannelV,true,true>
+ : public channel_converter_unsigned_integral<SrcChannelV,DstChannelV,
+ mpl::less<unsigned_integral_max_value<SrcChannelV>,unsigned_integral_max_value<DstChannelV> >::value > {};
+
+
+//////////////////////////////////////
+//// channel_converter_unsigned_integral
+//////////////////////////////////////
+
+template <typename SrcChannelV, typename DstChannelV>
+struct channel_converter_unsigned_integral<SrcChannelV,DstChannelV,true>
+ : public channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,true,
+ !(unsigned_integral_max_value<DstChannelV>::value % unsigned_integral_max_value<SrcChannelV>::value) > {};
+
+template <typename SrcChannelV, typename DstChannelV>
+struct channel_converter_unsigned_integral<SrcChannelV,DstChannelV,false>
+ : public channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,false,
+ !(unsigned_integral_max_value<SrcChannelV>::value % unsigned_integral_max_value<DstChannelV>::value) > {};
+
+
+//////////////////////////////////////
+//// channel_converter_unsigned_integral_impl
+//////////////////////////////////////
+
+// Both source and destination are unsigned integral channels,
+// the src max value is less than the dst max value,
+// and the dst max value is divisible by the src max value
+template <typename SrcChannelV, typename DstChannelV>
+struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,true,true> {
+ DstChannelV operator()(SrcChannelV src) const {
+ typedef typename unsigned_integral_max_value<DstChannelV>::value_type integer_t;
+ static const integer_t mul = unsigned_integral_max_value<DstChannelV>::value / unsigned_integral_max_value<SrcChannelV>::value;
+ return DstChannelV(src * mul);
+ }
 };
 
-/// \brief 8 bit <-> 32 bit channel conversion
-template <> struct channel_converter_unsigned<bits32,bits8> : public std::unary_function<bits32,bits8> {
- bits8 operator()(bits32 x) const { return static_cast<bits8>(x/16843009); }
+// Both source and destination are unsigned integral channels,
+// the dst max value is less than (or equal to) the src max value,
+// and the src max value is divisible by the dst max value
+template <typename SrcChannelV, typename DstChannelV>
+struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,false,true> {
+ DstChannelV operator()(SrcChannelV src) const {
+ typedef typename unsigned_integral_max_value<SrcChannelV>::value_type integer_t;
+ static const integer_t div = unsigned_integral_max_value<SrcChannelV>::value / unsigned_integral_max_value<DstChannelV>::value;
+ static const integer_t div2 = div/2;
+ return DstChannelV((src + div2) / div);
+ }
 };
-/// \brief 8 bit <-> 32 bit channel conversion
-template <> struct channel_converter_unsigned<bits8,bits32> : public std::unary_function<bits8,bits32> {
- bits32 operator()(bits8 x) const { return static_cast<bits32>(x*16843009); }
+
+// Prevent overflow for the largest integral type
+template <typename DstChannelV>
+struct channel_converter_unsigned_integral_impl<uintmax_t,DstChannelV,false,true> {
+ DstChannelV operator()(uintmax_t src) const {
+ static const uintmax_t div = unsigned_integral_max_value<bits32>::value / unsigned_integral_max_value<DstChannelV>::value;
+ static const uintmax_t div2 = div/2;
+ if (src > unsigned_integral_max_value<uintmax_t>::value - div2)
+ return unsigned_integral_max_value<DstChannelV>::value;
+ return DstChannelV((src + div2) / div);
+ }
 };
 
-/// \brief 8 bit <-> float0..1 channel conversion
-template <> struct channel_converter_unsigned<bits32f,bits8> : public std::unary_function<bits32f,bits8> {
- bits8 operator()(bits32f x) const { return static_cast<bits8>(x*255+0.5f); }
+// Both source and destination are unsigned integral channels,
+// and the dst max value is not divisible by the src max value
+// See if you can represent the expression (src * dst_max) / src_max in integral form
+template <typename SrcChannelV, typename DstChannelV, bool SrcLessThanDst>
+struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,SrcLessThanDst,false>
+ : public channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,SrcLessThanDst,
+ mpl::greater<
+ mpl::plus<unsigned_integral_num_bits<SrcChannelV>,unsigned_integral_num_bits<DstChannelV> >,
+ unsigned_integral_num_bits<uintmax_t>
+ >::value> {};
+
+
+// Both source and destination are unsigned integral channels,
+// the src max value is less than the dst max value,
+// and the dst max value is not divisible by the src max value
+// The expression (src * dst_max) / src_max fits in an integer
+template <typename SrcChannelV, typename DstChannelV>
+struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,true,false> {
+ DstChannelV operator()(SrcChannelV src) const {
+ typedef typename detail::min_fast_uint<unsigned_integral_num_bits<SrcChannelV>::value+unsigned_integral_num_bits<DstChannelV>::value>::type integer_t;
+ return DstChannelV(integer_t(src * unsigned_integral_max_value<DstChannelV>::value) / unsigned_integral_max_value<SrcChannelV>::value);
+ }
 };
-/// \brief 8 bit <-> float0..1 channel conversion
-template <> struct channel_converter_unsigned<bits8,bits32f> : public std::unary_function<bits8,bits32f> {
- bits32f operator()(bits8 x) const { return static_cast<bits32f>(x/255.0f); }
+
+// Both source and destination are unsigned integral channels,
+// the src max value is less than the dst max value,
+// and the dst max value is not divisible by the src max value
+// The expression (src * dst_max) / src_max cannot fit in an integer (overflows). Use a double
+template <typename SrcChannelV, typename DstChannelV>
+struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,true,true> {
+ DstChannelV operator()(SrcChannelV src) const {
+ static const double mul = unsigned_integral_max_value<DstChannelV>::value / double(unsigned_integral_max_value<SrcChannelV>::value);
+ return DstChannelV(src * mul);
+ }
 };
 
-/// \brief 16 bit <-> float0..1 channel conversion
-template <> struct channel_converter_unsigned<bits32f,bits16> : public std::unary_function<bits32f,bits16> {
- bits16 operator()(bits32f x) const { return static_cast<bits16>(x*65535+0.5f); }
+
+// Both source and destination are unsigned integral channels,
+// the dst max value is less than (or equal to) the src max value,
+// and the src max value is not divisible by the dst max value
+template <typename SrcChannelV, typename DstChannelV, bool CannotFit>
+struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,false,CannotFit> {
+ DstChannelV operator()(SrcChannelV src) const {
+ typedef typename unsigned_integral_max_value<SrcChannelV>::value_type integer_t;
+
+ static const double div = unsigned_integral_max_value<SrcChannelV>::value / double(unsigned_integral_max_value<DstChannelV>::value);
+ static const integer_t div2 = integer_t(div/2);
+ return DstChannelV((src + div2) / div);
+ }
 };
-/// \brief 16 bit <-> float0..1 channel conversion
-template <> struct channel_converter_unsigned<bits16,bits32f> : public std::unary_function<bits16,bits32f> {
- bits32f operator()(bits16 x) const { return static_cast<bits32f>(x/65535.0f); }
+
+} // namespace detail
+
+/////////////////////////////////////////////////////
+/// bits32f conversion
+/////////////////////////////////////////////////////
+
+template <typename DstChannelV> struct channel_converter_unsigned<bits32f,DstChannelV> : public std::unary_function<bits32f,DstChannelV> {
+ DstChannelV operator()(bits32f x) const { return DstChannelV(x*channel_traits<DstChannelV>::max_value()+0.5f); }
 };
 
-/// \brief 16 bit <-> 32 bit channel conversion
-template <> struct channel_converter_unsigned<bits32,bits16> : public std::unary_function<bits32,bits16> {
- bits16 operator()(bits32 x) const { return static_cast<bits16>(x/65537); }
+template <typename SrcChannelV> struct channel_converter_unsigned<SrcChannelV,bits32f> : public std::unary_function<SrcChannelV,bits32f> {
+ bits32f operator()(SrcChannelV x) const { return bits32f(x/float(channel_traits<SrcChannelV>::max_value())); }
 };
-/// \brief 16 bit <-> 32 bit channel conversion
-template <> struct channel_converter_unsigned<bits16,bits32> : public std::unary_function<bits16,bits32> {
- bits32 operator()(bits16 x) const { return static_cast<bits32>(x*65537); }
+
+template <> struct channel_converter_unsigned<bits32f,bits32f> : public std::unary_function<bits32f,bits32f> {
+ bits32f operator()(bits32f x) const { return x; }
 };
 
+
 /// \brief 32 bit <-> float channel conversion
 template <> struct channel_converter_unsigned<bits32,bits32f> : public std::unary_function<bits32,bits32f> {
     bits32f operator()(bits32 x) const {
@@ -127,85 +293,66 @@
         return bits32(x * channel_traits<bits32>::max_value() + 0.5f);
     }
 };
-/// @}
 
-/**
-\defgroup ChannelConvertToUnsignedAlgorithm channel_convert_to_unsigned
-\brief Convert signed channel to unsigned. By default it is an identity operation. Specializations are provided for signed integral channels
-\ingroup ChannelConvertAlgorithm
-
-@{
-*/
+/// @}
 
-/// \brief Converting from signed to unsigned integral channel.
-/// It is both a unary function, and a metafunction (thus requires the 'type' nested typedef, which equals result_type)
+namespace detail {
+// Converting from signed to unsigned integral channel.
+// It is both a unary function, and a metafunction (thus requires the 'type' nested typedef, which equals result_type)
 template <typename ChannelValue> // Model ChannelValueConcept
 struct channel_convert_to_unsigned : public detail::identity<ChannelValue> {
     typedef ChannelValue type;
 };
 
-/// \brief Converting from 8-bit signed to 8-bit unsigned integral channel
 template <> struct channel_convert_to_unsigned<bits8s> : public std::unary_function<bits8s,bits8> {
     typedef bits8 type;
     type operator()(bits8s val) const { return val+128; }
 };
 
-/// \brief Converting from 16-bit signed to 16-bit unsigned integral channel
 template <> struct channel_convert_to_unsigned<bits16s> : public std::unary_function<bits16s,bits16> {
     typedef bits16 type;
     type operator()(bits16s val) const { return val+32768; }
 };
 
-/// \brief Converting from 32-bit signed to 32-bit unsigned integral channel
 template <> struct channel_convert_to_unsigned<bits32s> : public std::unary_function<bits32s,bits32> {
     typedef bits32 type;
     type operator()(bits32s x) const { return static_cast<bits32>(x+(1<<31)); }
 };
-/// @}
 
-/**
-\defgroup ChannelConvertToSignedAlgorithm channel_convert_to_signed
-\brief Convert unsigned channel to signed. By default it is an identity operation. Specializations are provided for signed integral channels
-\ingroup ChannelConvertAlgorithm
-
-@{
-*/
 
-/// \brief Converting from unsigned to signed integral channel
-/// It is both a unary function, and a metafunction (thus requires the 'type' nested typedef, which equals result_type)
+// Converting from unsigned to signed integral channel
+// It is both a unary function, and a metafunction (thus requires the 'type' nested typedef, which equals result_type)
 template <typename ChannelValue> // Model ChannelValueConcept
-struct channel_convert_to_signed : public detail::identity<ChannelValue> {
+struct channel_convert_from_unsigned : public detail::identity<ChannelValue> {
     typedef ChannelValue type;
 };
 
-/// \brief Converting from 8-bit unsigned to 8-bit signed integral channel
-template <> struct channel_convert_to_signed<bits8s> : public std::unary_function<bits8,bits8s> {
+template <> struct channel_convert_from_unsigned<bits8s> : public std::unary_function<bits8,bits8s> {
     typedef bits8s type;
     type operator()(bits8 val) const { return val-128; }
 };
 
-/// \brief Converting from 16-bit unsigned to 16-bit signed integral channel
-template <> struct channel_convert_to_signed<bits16s> : public std::unary_function<bits16,bits16s> {
+template <> struct channel_convert_from_unsigned<bits16s> : public std::unary_function<bits16,bits16s> {
     typedef bits16s type;
     type operator()(bits16 val) const { return val-32768; }
 };
 
-/// \brief Converting from 32-bit unsigned to 32-bit signed integral channel
-template <> struct channel_convert_to_signed<bits32s> : public std::unary_function<bits32,bits32s> {
+template <> struct channel_convert_from_unsigned<bits32s> : public std::unary_function<bits32,bits32s> {
     typedef bits32s type;
     type operator()(bits32 x) const { return static_cast<bits32s>(x-(1<<31)); }
 };
-/// @}
+
+} // namespace detail
 
 /// \ingroup ChannelConvertAlgorithm
 /// \brief A unary function object converting between channel types
 template <typename SrcChannelV, typename DstChannelV> // Model ChannelValueConcept
 struct channel_converter : public std::unary_function<SrcChannelV,DstChannelV> {
     DstChannelV operator()(SrcChannelV src) const {
- typedef channel_convert_to_unsigned<SrcChannelV> to_unsigned;
- typedef channel_convert_to_signed<DstChannelV> to_signed;
- typedef channel_converter_unsigned<typename to_unsigned::result_type, typename to_signed::argument_type> converter_unsigned;
- return to_signed()(converter_unsigned()(to_unsigned()(src)));
+ typedef detail::channel_convert_to_unsigned<SrcChannelV> to_unsigned;
+ typedef detail::channel_convert_from_unsigned<DstChannelV> from_unsigned;
+ typedef channel_converter_unsigned<typename to_unsigned::result_type, typename from_unsigned::argument_type> converter_unsigned;
+ return from_unsigned()(converter_unsigned()(to_unsigned()(src)));
     }
 };
 
@@ -236,9 +383,19 @@
     inline uint32_t div32768(uint32_t in) { return (in+16384)>>15; }
 }
 
-/// \defgroup ChannelMultiplyAlgorithm channel_multiply
-/// \ingroup ChannelAlgorithm
-/// \brief Multiplying unsigned channel values of the same type. Performs scaled multiplication result = a * b / max_value
+/**
+\defgroup ChannelMultiplyAlgorithm channel_multiply
+\ingroup ChannelAlgorithm
+\brief Multiplying unsigned channel values of the same type. Performs scaled multiplication result = a * b / max_value
+
+Example:
+\code
+bits8 x=128;
+bits8 y=128;
+bits8 mul = channel_multiply(x,y);
+assert(mul == 64); // 64 = 128 * 128 / 255
+\endcode
+*/
 /// @{
 
 /// \brief This is the default implementation. Performance specializatons are provided
@@ -268,10 +425,10 @@
 template <typename ChannelValue>
 struct channel_multiplier : public std::binary_function<ChannelValue, ChannelValue, ChannelValue> {
     ChannelValue operator()(ChannelValue a, ChannelValue b) const {
- typedef channel_convert_to_unsigned<ChannelValue> to_unsigned;
- typedef channel_convert_to_signed<ChannelValue> to_signed;
+ typedef detail::channel_convert_to_unsigned<ChannelValue> to_unsigned;
+ typedef detail::channel_convert_from_unsigned<ChannelValue> from_unsigned;
         typedef channel_multiplier_unsigned<typename to_unsigned::result_type> multiplier_unsigned;
- return to_signed()(multiplier_unsigned()(to_unsigned()(a), to_unsigned()(b)));
+ return from_unsigned()(multiplier_unsigned()(to_unsigned()(a), to_unsigned()(b)));
     }
 };
 
@@ -282,9 +439,19 @@
 }
 /// @}
 
-/// \defgroup ChannelInvertAlgorithm channel_invert
-/// \ingroup ChannelAlgorithm
-/// \brief Returns the inverse of a channel. result = max_value - x + min_value
+/**
+\defgroup ChannelInvertAlgorithm channel_invert
+\ingroup ChannelAlgorithm
+\brief Returns the inverse of a channel. result = max_value - x + min_value
+
+Example:
+\code
+// bits8 == uint8_t == unsigned char
+bits8 x=255;
+bits8 inv = channel_invert(x);
+assert(inv == 0);
+\endcode
+*/
 
 /// \brief Default implementation. Provide overloads for performance
 /// \ingroup ChannelInvertAlgorithm channel_invert
@@ -293,6 +460,9 @@
     return channel_traits<Channel>::max_value()-x + channel_traits<Channel>::min_value();
 }
 
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
 
 } } // namespace boost::gil
 

Modified: trunk/boost/gil/color_base.hpp
==============================================================================
--- trunk/boost/gil/color_base.hpp (original)
+++ trunk/boost/gil/color_base.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -44,6 +44,12 @@
 // Forward declare element_reference_type
 template <typename ColorBase> struct element_reference_type;
 template <typename ColorBase> struct element_const_reference_type;
+template <typename ColorBase, int K> struct kth_element_type;
+template <typename ColorBase, int K> struct kth_element_type<const ColorBase,K> : public kth_element_type<ColorBase,K> {};
+template <typename ColorBase, int K> struct kth_element_reference_type;
+template <typename ColorBase, int K> struct kth_element_reference_type<const ColorBase,K> : public kth_element_reference_type<ColorBase,K> {};
+template <typename ColorBase, int K> struct kth_element_const_reference_type;
+template <typename ColorBase, int K> struct kth_element_const_reference_type<const ColorBase,K> : public kth_element_const_reference_type<ColorBase,K> {};
 
 namespace detail {
 
@@ -59,25 +65,14 @@
 /// If the element type models Regular, this class models HomogeneousColorBaseValueConcept.
 
 
-template <typename Element, typename Layout>
-struct homogeneous_color_base_impl {
- typedef Layout layout_t;
-
- template <int K> struct kth_element_type { typedef Element type; };
- template <int K> struct kth_element_reference_type : public add_reference<Element> {};
- template <int K> struct kth_element_const_reference_type : public add_reference<typename add_const<Element>::type> {};
-};
-
-
-template <typename Element, typename Layout, int K> struct homogeneous_color_base;
-
 /// \brief A homogeneous color base holding one color element. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
 /// \ingroup ColorBaseModelHomogeneous
 template <typename Element, typename Layout>
-struct homogeneous_color_base<Element,Layout,1> : public homogeneous_color_base_impl<Element,Layout> {
+struct homogeneous_color_base<Element,Layout,1> {
 private:
     Element _v0;
 public:
+ typedef Layout layout_t;
     typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
 
@@ -94,10 +89,11 @@
 /// \brief A homogeneous color base holding two color elements. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
 /// \ingroup ColorBaseModelHomogeneous
 template <typename Element, typename Layout>
-struct homogeneous_color_base<Element,Layout,2> : public homogeneous_color_base_impl<Element,Layout> {
+struct homogeneous_color_base<Element,Layout,2> {
 private:
     Element _v0, _v1;
 public:
+ typedef Layout layout_t;
     typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
     typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
@@ -126,8 +122,8 @@
 
     // Support for planar_pixel_reference offset constructor
     template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
- : _v0(*byte_advanced(semantic_at_c<0>(ptr),diff)),
- _v1(*byte_advanced(semantic_at_c<1>(ptr),diff)) {}
+ : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
+ _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)) {}
 
     // Support for planar_pixel_reference operator[]
     Element at_c_dynamic(size_t i) const {
@@ -139,10 +135,11 @@
 /// \brief A homogeneous color base holding three color elements. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
 /// \ingroup ColorBaseModelHomogeneous
 template <typename Element, typename Layout>
-struct homogeneous_color_base<Element,Layout,3> : public homogeneous_color_base_impl<Element,Layout> {
+struct homogeneous_color_base<Element,Layout,3> {
 private:
     Element _v0, _v1, _v2;
 public:
+ typedef Layout layout_t;
     typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
     typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
@@ -177,9 +174,9 @@
 
     // Support for planar_pixel_reference offset constructor
     template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
- : _v0(*byte_advanced(semantic_at_c<0>(ptr),diff)),
- _v1(*byte_advanced(semantic_at_c<1>(ptr),diff)),
- _v2(*byte_advanced(semantic_at_c<2>(ptr),diff)) {}
+ : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
+ _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
+ _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)) {}
 
     // Support for planar_pixel_reference operator[]
     Element at_c_dynamic(size_t i) const {
@@ -194,10 +191,11 @@
 /// \brief A homogeneous color base holding four color elements. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
 /// \ingroup ColorBaseModelHomogeneous
 template <typename Element, typename Layout>
-struct homogeneous_color_base<Element,Layout,4> : public homogeneous_color_base_impl<Element,Layout> {
+struct homogeneous_color_base<Element,Layout,4> {
 private:
     Element _v0, _v1, _v2, _v3;
 public:
+ typedef Layout layout_t;
     typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
     typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
@@ -238,10 +236,10 @@
 
     // Support for planar_pixel_reference offset constructor
     template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
- : _v0(*byte_advanced(semantic_at_c<0>(ptr),diff)),
- _v1(*byte_advanced(semantic_at_c<1>(ptr),diff)),
- _v2(*byte_advanced(semantic_at_c<2>(ptr),diff)),
- _v3(*byte_advanced(semantic_at_c<3>(ptr),diff)) {}
+ : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
+ _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
+ _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)),
+ _v3(*memunit_advanced(semantic_at_c<3>(ptr),diff)) {}
 
     // Support for planar_pixel_reference operator[]
     Element at_c_dynamic(size_t i) const {
@@ -257,10 +255,11 @@
 /// \brief A homogeneous color base holding five color elements. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
 /// \ingroup ColorBaseModelHomogeneous
 template <typename Element, typename Layout>
-struct homogeneous_color_base<Element,Layout,5> : public homogeneous_color_base_impl<Element,Layout> {
+struct homogeneous_color_base<Element,Layout,5> {
 private:
     Element _v0, _v1, _v2, _v3, _v4;
 public:
+ typedef Layout layout_t;
     typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
     typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
@@ -307,11 +306,11 @@
 
     // Support for planar_pixel_reference offset constructor
     template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
- : _v0(*byte_advanced(semantic_at_c<0>(ptr),diff)),
- _v1(*byte_advanced(semantic_at_c<1>(ptr),diff)),
- _v2(*byte_advanced(semantic_at_c<2>(ptr),diff)),
- _v3(*byte_advanced(semantic_at_c<3>(ptr),diff)),
- _v4(*byte_advanced(semantic_at_c<4>(ptr),diff)) {}
+ : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
+ _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
+ _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)),
+ _v3(*memunit_advanced(semantic_at_c<3>(ptr),diff)),
+ _v4(*memunit_advanced(semantic_at_c<4>(ptr),diff)) {}
 
     // Support for planar_pixel_reference operator[]
     Element at_c_dynamic(size_t i) const {
@@ -366,17 +365,28 @@
 
 } // namespace detail
 
+template <typename Element, typename Layout, int K1, int K>
+struct kth_element_type<detail::homogeneous_color_base<Element,Layout,K1>, K> {
+ typedef Element type;
+};
+
+template <typename Element, typename Layout, int K1, int K>
+struct kth_element_reference_type<detail::homogeneous_color_base<Element,Layout,K1>, K> : public add_reference<Element> {};
+
+template <typename Element, typename Layout, int K1, int K>
+struct kth_element_const_reference_type<detail::homogeneous_color_base<Element,Layout,K1>, K> : public add_reference<typename add_const<Element>::type> {};
+
 /// \brief Provides mutable access to the K-th element, in physical order
 /// \ingroup ColorBaseModelHomogeneous
 template <int K, typename E, typename L, int N> inline
 typename add_reference<E>::type
-at_c( detail::homogeneous_color_base<E,L,N>& p) { return p.at(mpl::int_<K>()); };
+at_c( detail::homogeneous_color_base<E,L,N>& p) { return p.at(mpl::int_<K>()); }
 
 /// \brief Provides constant access to the K-th element, in physical order
 /// \ingroup ColorBaseModelHomogeneous
 template <int K, typename E, typename L, int N> inline
 typename add_reference<typename add_const<E>::type>::type
-at_c(const detail::homogeneous_color_base<E,L,N>& p) { return p.at(mpl::int_<K>()); };
+at_c(const detail::homogeneous_color_base<E,L,N>& p) { return p.at(mpl::int_<K>()); }
 
 namespace detail {
     struct swap_fn {
@@ -389,7 +399,7 @@
 template <typename E, typename L, int N> inline
 void swap(detail::homogeneous_color_base<E,L,N>& x, detail::homogeneous_color_base<E,L,N>& y) {
     static_for_each(x,y,detail::swap_fn());
-};
+}
 
 
 } } // namespace boost::gil

Modified: trunk/boost/gil/color_base_algorithm.hpp
==============================================================================
--- trunk/boost/gil/color_base_algorithm.hpp (original)
+++ trunk/boost/gil/color_base_algorithm.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -40,9 +40,17 @@
 ///
 ///////////////////////////////////////
 
-/// \defgroup ColorBaseAlgorithmSize size
-/// \ingroup ColorBaseAlgorithm
-/// \brief Returns an MPL integral type specifying the number of elements in a color base
+/**
+\defgroup ColorBaseAlgorithmSize size
+\ingroup ColorBaseAlgorithm
+\brief Returns an MPL integral type specifying the number of elements in a color base
+
+Example:
+\code
+BOOST_STATIC_ASSERT((size<rgb8_pixel_t>::value == 3));
+BOOST_STATIC_ASSERT((size<cmyk8_planar_ptr_t>::value == 4));
+\endcode
+*/
 
 /// \brief Returns an MPL integral type specifying the number of elements in a color base
 /// \ingroup ColorBaseAlgorithmSize
@@ -55,25 +63,44 @@
 ///
 ///////////////////////////////////////
 
-/// \defgroup ColorBaseAlgorithmSemanticAtC kth_semantic_element_type, kth_semantic_element_reference_type, kth_semantic_element_const_reference_type, semantic_at_c
-/// \ingroup ColorBaseAlgorithm
-/// \brief Support for accessing the elements of a color base by semantic index
-/// The semantic index of an element is the index of its color in the color space. Semantic indexing allows for proper pairing of elements of color bases
-/// independent on their layout. For example, red is the first semantic element of a color base regardless of whether it has an RGB layout or a BGR layout.
-/// All GIL color base algorithms taking multiple color bases use semantic indexing to access their elements.
+/**
+\defgroup ColorBaseAlgorithmSemanticAtC kth_semantic_element_type, kth_semantic_element_reference_type, kth_semantic_element_const_reference_type, semantic_at_c
+\ingroup ColorBaseAlgorithm
+\brief Support for accessing the elements of a color base by semantic index
+
+The semantic index of an element is the index of its color in the color space. Semantic indexing allows for proper pairing of elements of color bases
+independent on their layout. For example, red is the first semantic element of a color base regardless of whether it has an RGB layout or a BGR layout.
+All GIL color base algorithms taking multiple color bases use semantic indexing to access their elements.
+
+Example:
+\code
+// 16-bit BGR pixel, 4 bits for the blue, 3 bits for the green, 2 bits for the red channel and 7 unused bits
+typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,4,3,2>, bgr_layout_t>::type bgr432_pixel_t;
+
+// A reference to its red channel. Although the red channel is the third, its semantic index is 0 in the RGB color space
+typedef kth_semantic_element_reference_type<bgr432_pixel_t, 0>::type red_channel_reference_t;
+
+// Initialize the pixel to black
+bgr432_pixel_t red_pixel(0,0,0);
+
+// Set the red channel to 100%
+red_channel_reference_t red_channel = semantic_at_c<0>(red_pixel);
+red_channel = channel_traits<red_channel_reference_t>::max_value();
 
+\endcode
+*/
 /// \brief Specifies the type of the K-th semantic element of a color base
 /// \ingroup ColorBaseAlgorithmSemanticAtC
 template <typename ColorBase, int K> struct kth_semantic_element_type {
     BOOST_STATIC_CONSTANT(int, semantic_index = (mpl::at_c<typename ColorBase::layout_t::channel_mapping_t,K>::type::value));
- typedef typename ColorBase::template kth_element_type<semantic_index>::type type;
+ typedef typename kth_element_type<ColorBase, semantic_index>::type type;
 };
 
 /// \brief Specifies the return type of the mutable semantic_at_c<K>(color_base);
 /// \ingroup ColorBaseAlgorithmSemanticAtC
 template <typename ColorBase, int K> struct kth_semantic_element_reference_type {
     BOOST_STATIC_CONSTANT(int, semantic_index = (mpl::at_c<typename ColorBase::layout_t::channel_mapping_t,K>::type::value));
- typedef typename ColorBase::template kth_element_reference_type<semantic_index>::type type;
+ typedef typename kth_element_reference_type<ColorBase,semantic_index>::type type;
     static type get(ColorBase& cb) { return at_c<semantic_index>(cb); }
 };
 
@@ -81,7 +108,7 @@
 /// \ingroup ColorBaseAlgorithmSemanticAtC
 template <typename ColorBase, int K> struct kth_semantic_element_const_reference_type {
     BOOST_STATIC_CONSTANT(int, semantic_index = (mpl::at_c<typename ColorBase::layout_t::channel_mapping_t,K>::type::value));
- typedef typename ColorBase::template kth_element_const_reference_type<semantic_index>::type type;
+ typedef typename kth_element_const_reference_type<ColorBase,semantic_index>::type type;
     static type get(const ColorBase& cb) { return at_c<semantic_index>(cb); }
 };
 
@@ -91,7 +118,7 @@
 typename disable_if<is_const<ColorBase>,typename kth_semantic_element_reference_type<ColorBase,K>::type>::type
 semantic_at_c(ColorBase& p) {
     return kth_semantic_element_reference_type<ColorBase,K>::get(p);
-};
+}
 
 /// \brief A constant accessor to the K-th semantic element of a color base
 /// \ingroup ColorBaseAlgorithmSemanticAtC
@@ -99,7 +126,7 @@
 typename kth_semantic_element_const_reference_type<ColorBase,K>::type
 semantic_at_c(const ColorBase& p) {
     return kth_semantic_element_const_reference_type<ColorBase,K>::get(p);
-};
+}
 
 ///////////////////////////////////////
 ///
@@ -107,40 +134,60 @@
 ///
 ///////////////////////////////////////
 
-/// \defgroup ColorBaseAlgorithmColor color_element_type, color_element_reference_type, color_element_const_reference_type, get_color
-/// \ingroup ColorBaseAlgorithm
-/// \brief Support for accessing the elements of a color base by color name
+/**
+\defgroup ColorBaseAlgorithmColor color_element_type, color_element_reference_type, color_element_const_reference_type, get_color, contains_color
+\ingroup ColorBaseAlgorithm
+\brief Support for accessing the elements of a color base by color name
+
+Example: A function that takes a generic pixel containing a red channel and sets it to 100%:
+
+\code
+template <typename Pixel>
+void set_red_to_max(Pixel& pixel) {
+ boost::function_requires<MutablePixelConcept<Pixel> >();
+ BOOST_STATIC_ASSERT((contains_color<Pixel, red_t>::value));
+
+ typedef typename color_element_type<Pixel, red_t>::type red_channel_t;
+ get_color(pixel, red_t()) = channel_traits<red_channel_t>::max_value();
+}
+\endcode
+*/
+
+/// \brief A predicate metafunction determining whether a given color base contains a given color
+/// \ingroup ColorBaseAlgorithmColor
+template <typename ColorBase, typename Color>
+struct contains_color : public mpl::contains<typename ColorBase::layout_t::color_space_t,Color> {};
 
 template <typename ColorBase, typename Color>
 struct color_index_type : public detail::type_to_index<typename ColorBase::layout_t::color_space_t,Color> {};
 
 /// \brief Specifies the type of the element associated with a given color tag
 /// \ingroup ColorBaseAlgorithmColor
-template <typename Color, typename ColorBase>
+template <typename ColorBase, typename Color>
 struct color_element_type : public kth_semantic_element_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
 
 /// \brief Specifies the return type of the mutable element accessor by color name, get_color(color_base, Color());
 /// \ingroup ColorBaseAlgorithmColor
-template <typename Color, typename ColorBase>
+template <typename ColorBase, typename Color>
 struct color_element_reference_type : public kth_semantic_element_reference_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
 
 /// \brief Specifies the return type of the constant element accessor by color name, get_color(color_base, Color());
 /// \ingroup ColorBaseAlgorithmColor
-template <typename Color, typename ColorBase>
+template <typename ColorBase, typename Color>
 struct color_element_const_reference_type : public kth_semantic_element_const_reference_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
 
 /// \brief Mutable accessor to the element associated with a given color name
 /// \ingroup ColorBaseAlgorithmColor
-template <typename CB, typename Color>
-typename color_element_reference_type<Color,CB>::type get_color(CB& cb, Color=Color()) {
- return color_element_reference_type<Color,CB>::get(cb);
+template <typename ColorBase, typename Color>
+typename color_element_reference_type<ColorBase,Color>::type get_color(ColorBase& cb, Color=Color()) {
+ return color_element_reference_type<ColorBase,Color>::get(cb);
 }
 
 /// \brief Constant accessor to the element associated with a given color name
 /// \ingroup ColorBaseAlgorithmColor
-template <typename CB, typename Color>
-typename color_element_const_reference_type<Color,CB>::type get_color(const CB& cb, Color=Color()) {
- return color_element_const_reference_type<Color,CB>::get(cb);
+template <typename ColorBase, typename Color>
+typename color_element_const_reference_type<ColorBase,Color>::type get_color(const ColorBase& cb, Color=Color()) {
+ return color_element_const_reference_type<ColorBase,Color>::get(cb);
 }
 
 ///////////////////////////////////////
@@ -149,24 +196,31 @@
 ///
 ///////////////////////////////////////
 
-/// \defgroup ColorBaseAlgorithmHomogeneous element_type, element_reference_type, element_const_reference_type
-/// \ingroup ColorBaseAlgorithm
-/// \brief Types for homogeneous color bases
-
+/**
+\defgroup ColorBaseAlgorithmHomogeneous element_type, element_reference_type, element_const_reference_type
+\ingroup ColorBaseAlgorithm
+\brief Types for homogeneous color bases
+
+Example:
+\code
+typedef element_type<rgb8c_planar_ptr_t>::type element_t;
+BOOST_STATIC_ASSERT((boost::is_same<element_t, const bits8*>::value));
+\endcode
+*/
 /// \brief Specifies the element type of a homogeneous color base
 /// \ingroup ColorBaseAlgorithmHomogeneous
 template <typename ColorBase>
-struct element_type : public ColorBase::template kth_element_type<0> {};
+struct element_type : public kth_element_type<ColorBase, 0> {};
 
 /// \brief Specifies the return type of the mutable element accessor at_c of a homogeneous color base
 /// \ingroup ColorBaseAlgorithmHomogeneous
 template <typename ColorBase>
-struct element_reference_type : public ColorBase::template kth_element_reference_type<0> {};
+struct element_reference_type : public kth_element_reference_type<ColorBase, 0> {};
 
 /// \brief Specifies the return type of the constant element accessor at_c of a homogeneous color base
 /// \ingroup ColorBaseAlgorithmHomogeneous
 template <typename ColorBase>
-struct element_const_reference_type : public ColorBase::template kth_element_const_reference_type<0> {};
+struct element_const_reference_type : public kth_element_const_reference_type<ColorBase, 0> {};
 
 
 namespace detail {
@@ -391,10 +445,20 @@
 } // namespace detail
 
 
-/// \defgroup ColorBaseAlgorithmMinMax static_min, static_max
-/// \ingroup ColorBaseAlgorithm
-/// \brief Equivalents to std::min_element and std::max_element for homogeneous color bases
-/// \{
+/**
+\defgroup ColorBaseAlgorithmMinMax static_min, static_max
+\ingroup ColorBaseAlgorithm
+\brief Equivalents to std::min_element and std::max_element for homogeneous color bases
+
+Example:
+\code
+rgb8_pixel_t pixel(10,20,30);
+assert(pixel[2] == 30);
+static_max(pixel) = static_min(pixel);
+assert(pixel[2] == 10);
+\endcode
+\{
+*/
 
 template <typename P>
 GIL_FORCEINLINE
@@ -413,10 +477,22 @@
 typename element_reference_type<P>::type static_min( P& p) { return detail::min_max_recur<size<P>::value>::min_(p); }
 /// \}
 
-/// \defgroup ColorBaseAlgorithmEqual static_equal
-/// \ingroup ColorBaseAlgorithm
-/// \brief Equivalent to std::equal. Pairs the elements semantically
-/// \{
+/**
+\defgroup ColorBaseAlgorithmEqual static_equal
+\ingroup ColorBaseAlgorithm
+\brief Equivalent to std::equal. Pairs the elements semantically
+
+Example:
+\code
+rgb8_pixel_t rgb_red(255,0,0);
+bgr8_pixel_t bgr_red(0,0,255);
+assert(rgb_red[0]==255 && bgr_red[0]==0);
+
+assert(static_equal(rgb_red,bgr_red));
+assert(rgb_red==bgr_red); // operator== invokes static_equal
+\endcode
+\{
+*/
 
 template <typename P1,typename P2>
 GIL_FORCEINLINE
@@ -424,10 +500,22 @@
 
 /// \}
 
-/// \defgroup ColorBaseAlgorithmCopy static_copy
-/// \ingroup ColorBaseAlgorithm
-/// \brief Equivalent to std::copy. Pairs the elements semantically
-/// \{
+/**
+\defgroup ColorBaseAlgorithmCopy static_copy
+\ingroup ColorBaseAlgorithm
+\brief Equivalent to std::copy. Pairs the elements semantically
+
+Example:
+\code
+rgb8_pixel_t rgb_red(255,0,0);
+bgr8_pixel_t bgr_red;
+static_copy(rgb_red, bgr_red); // same as bgr_red = rgb_red
+
+assert(rgb_red[0] == 255 && bgr_red[0] == 0);
+assert(rgb_red == bgr_red);
+\endcode
+\{
+*/
 
 template <typename Src,typename Dst>
 GIL_FORCEINLINE
@@ -435,30 +523,77 @@
 
 /// \}
 
-/// \defgroup ColorBaseAlgorithmFill static_fill
-/// \ingroup ColorBaseAlgorithm
-/// \brief Equivalent to std::fill.
-/// \{
-
+/**
+\defgroup ColorBaseAlgorithmFill static_fill
+\ingroup ColorBaseAlgorithm
+\brief Equivalent to std::fill.
+
+Example:
+\code
+rgb8_pixel_t p;
+static_fill(p, 10);
+assert(p == rgb8_pixel_t(10,10,10));
+\endcode
+\{
+*/
 template <typename P,typename V>
 GIL_FORCEINLINE
 void static_fill(P& p, const V& v) { detail::element_recursion<size<P>::value>::static_fill(p,v); }
 /// \}
 
-/// \defgroup ColorBaseAlgorithmGenerate static_generate
-/// \ingroup ColorBaseAlgorithm
-/// \brief Equivalent to std::generate.
-/// \{
+/**
+\defgroup ColorBaseAlgorithmGenerate static_generate
+\ingroup ColorBaseAlgorithm
+\brief Equivalent to std::generate.
+
+Example: Set each channel of a pixel to its semantic index. The channels must be assignable from an integer.
+\code
+struct consecutive_fn {
+ int& _current;
+ consecutive_fn(int& start) : _current(start) {}
+ int operator()() { return _current++; }
+};
+rgb8_pixel_t p;
+int start=0;
+static_generate(p, consecutive_fn(start));
+assert(p == rgb8_pixel_t(0,1,2));
+\endcode
+
+\{
+*/
 
 template <typename P1,typename Op>
 GIL_FORCEINLINE
 void static_generate(P1& dst,Op op) { detail::element_recursion<size<P1>::value>::static_generate(dst,op); }
 /// \}
 
-/// \defgroup ColorBaseAlgorithmTransform static_transform
-/// \ingroup ColorBaseAlgorithm
-/// \brief Equivalent to std::transform. Pairs the elements semantically
-/// \{
+/**
+\defgroup ColorBaseAlgorithmTransform static_transform
+\ingroup ColorBaseAlgorithm
+\brief Equivalent to std::transform. Pairs the elements semantically
+
+Example: Write a generic function that adds two pixels into a homogeneous result pixel.
+\code
+template <typename Result>
+struct my_plus {
+ template <typename T1, typename T2>
+ Result operator()(T1 f1, T2 f2) const { return f1+f2; }
+};
+
+template <typename Pixel1, typename Pixel2, typename Pixel3>
+void sum_channels(const Pixel1& p1, const Pixel2& p2, Pixel3& result) {
+ typedef typename channel_type<Pixel3>::type result_channel_t;
+ static_transform(p1,p2,result,my_plus<result_channel_t>());
+}
+
+rgb8_pixel_t p1(1,2,3);
+bgr8_pixel_t p2(3,2,1);
+rgb8_pixel_t result;
+sum_channels(p1,p2,result);
+assert(result == rgb8_pixel_t(2,4,6));
+\endcode
+\{
+*/
 
 //static_transform with one source
 template <typename Src,typename Dst,typename Op>
@@ -482,10 +617,32 @@
 Op static_transform(const P2& p2,const P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
 /// \}
 
-/// \defgroup ColorBaseAlgorithmForEach static_for_each
-/// \ingroup ColorBaseAlgorithm
-/// \brief Equivalent to std::for_each. Pairs the elements semantically
-/// \{
+/**
+\defgroup ColorBaseAlgorithmForEach static_for_each
+\ingroup ColorBaseAlgorithm
+\brief Equivalent to std::for_each. Pairs the elements semantically
+
+Example: Use static_for_each to increment a planar pixel iterator
+\code
+struct increment {
+ template <typename Incrementable>
+ void operator()(Incrementable& x) const { ++x; }
+};
+
+template <typename ColorBase>
+void increment_elements(ColorBase& cb) {
+ static_for_each(cb, increment());
+}
+
+bits8 red[2], green[2], blue[2];
+rgb8c_planar_ptr_t p1(red,green,blue);
+rgb8c_planar_ptr_t p2=p1;
+increment_elements(p1);
+++p2;
+assert(p1 == p2);
+\endcode
+\{
+*/
 
 //static_for_each with one source
 template <typename P1,typename Op>

Modified: trunk/boost/gil/color_convert.hpp
==============================================================================
--- trunk/boost/gil/color_convert.hpp (original)
+++ trunk/boost/gil/color_convert.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -102,11 +102,11 @@
     template <typename P1, typename P2>
     void operator()(const P1& src, P2& dst) const {
         get_color(dst,red_t()) =
- channel_convert<typename color_element_type<red_t, P2>::type>(get_color(src,gray_color_t()));
+ channel_convert<typename color_element_type<P2, red_t >::type>(get_color(src,gray_color_t()));
         get_color(dst,green_t())=
- channel_convert<typename color_element_type<green_t,P2>::type>(get_color(src,gray_color_t()));
+ channel_convert<typename color_element_type<P2, green_t>::type>(get_color(src,gray_color_t()));
         get_color(dst,blue_t()) =
- channel_convert<typename color_element_type<blue_t, P2>::type>(get_color(src,gray_color_t()));
+ channel_convert<typename color_element_type<P2, blue_t >::type>(get_color(src,gray_color_t()));
     }
 };
 
@@ -117,13 +117,13 @@
     template <typename P1, typename P2>
     void operator()(const P1& src, P2& dst) const {
         get_color(dst,cyan_t())=
- channel_traits<typename color_element_type<cyan_t, P2>::type>::min_value();
+ channel_traits<typename color_element_type<P2, cyan_t >::type>::min_value();
         get_color(dst,magenta_t())=
- channel_traits<typename color_element_type<magenta_t,P2>::type>::min_value();
+ channel_traits<typename color_element_type<P2, magenta_t>::type>::min_value();
         get_color(dst,yellow_t())=
- channel_traits<typename color_element_type<yellow_t, P2>::type>::min_value();
+ channel_traits<typename color_element_type<P2, yellow_t >::type>::min_value();
         get_color(dst,black_t())=
- channel_convert<typename color_element_type<black_t, P2>::type>(get_color(src,gray_color_t()));
+ channel_convert<typename color_element_type<P2, black_t >::type>(get_color(src,gray_color_t()));
     }
 };
 
@@ -134,7 +134,7 @@
     template <typename P1, typename P2>
     void operator()(const P1& src, P2& dst) const {
         get_color(dst,gray_color_t()) =
- detail::rgb_to_luminance<typename color_element_type<gray_color_t,P2>::type>(
+ detail::rgb_to_luminance<typename color_element_type<P2,gray_color_t>::type>(
                 get_color(src,red_t()), get_color(src,green_t()), get_color(src,blue_t())
             );
     }
@@ -183,17 +183,17 @@
     void operator()(const P1& src, P2& dst) const {
         typedef typename channel_type<P1>::type T1;
         get_color(dst,red_t()) =
- channel_convert<typename color_element_type<red_t,P2>::type>(
+ channel_convert<typename color_element_type<P2,red_t>::type>(
                 channel_invert<T1>(
                     (std::min)(channel_traits<T1>::max_value(),
                              T1(get_color(src,cyan_t())*channel_invert(get_color(src,black_t()))+get_color(src,black_t())))));
         get_color(dst,green_t())=
- channel_convert<typename color_element_type<green_t,P2>::type>(
+ channel_convert<typename color_element_type<P2,green_t>::type>(
                 channel_invert<T1>(
                     (std::min)(channel_traits<T1>::max_value(),
                              T1(get_color(src,magenta_t())*channel_invert(get_color(src,black_t()))+get_color(src,black_t())))));
         get_color(dst,blue_t()) =
- channel_convert<typename color_element_type<blue_t,P2>::type>(
+ channel_convert<typename color_element_type<P2,blue_t>::type>(
                 channel_invert<T1>(
                     (std::min)(channel_traits<T1>::max_value(),
                              T1(get_color(src,yellow_t())*channel_invert(get_color(src,black_t()))+get_color(src,black_t())))));
@@ -210,10 +210,10 @@
     template <typename P1, typename P2>
     void operator()(const P1& src, P2& dst) const {
         get_color(dst,gray_color_t())=
- channel_convert<typename color_element_type<gray_t,P2>::type>(
+ channel_convert<typename color_element_type<P2,gray_t>::type>(
                 channel_multiply(
                     channel_invert(
- detail::rgb_to_luminance<typename color_element_type<black_t,P1>::type>(
+ detail::rgb_to_luminance<typename color_element_type<P1,black_t>::type>(
                             get_color(src,cyan_t()),
                             get_color(src,magenta_t()),
                             get_color(src,yellow_t())
@@ -308,7 +308,7 @@
 template <typename SrcP, typename DstP>
 inline void color_convert(const SrcP& src, DstP& dst) {
     default_color_converter()(src,dst);
-};
+}
 
 } } // namespace boost::gil
 

Modified: trunk/boost/gil/deprecated.hpp
==============================================================================
--- trunk/boost/gil/deprecated.hpp (original)
+++ trunk/boost/gil/deprecated.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -27,8 +27,8 @@
 
 #define planar_ptr planar_pixel_iterator
 #define planar_ref planar_pixel_reference
-#define membased_2d_locator byte_addressable_2d_locator
-#define pixel_step_iterator byte_addressable_step_iterator
+#define membased_2d_locator memory_based_2d_locator
+#define pixel_step_iterator memory_based_step_iterator
 #define pixel_image_iterator iterator_from_2d
 
 #define equal_channels static_equal
@@ -61,5 +61,17 @@
 #define ADOBE_GIL_NAMESPACE_BEGIN namespace boost { namespace gil {
 #define ADOBE_GIL_NAMESPACE_END } }
 
+#define ByteAdvancableIteratorConcept MemoryBasedIteratorConcept
+#define byte_advance memunit_advance
+#define byte_advanced memunit_advanced
+#define byte_step memunit_step
+#define byte_distance memunit_distance
+
+#define byte_addressable_step_iterator memory_based_step_iterator
+#define byte_addressable_2d_locator memory_based_2d_locator
+
+// These are members of memory-based locators
+//#define row_bytes row_size // commented out because row_bytes is commonly used
+#define pix_bytestep pixel_size
 
 #endif

Modified: trunk/boost/gil/gil_all.hpp
==============================================================================
--- trunk/boost/gil/gil_all.hpp (original)
+++ trunk/boost/gil/gil_all.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -39,6 +39,7 @@
 #include "color_convert.hpp"
 #include "device_n.hpp"
 #include "virtual_locator.hpp"
+#include "bit_aligned_pixel_iterator.hpp"
 // Uncomment this line to help in porting your code from an older version of GIL
 //#include "deprecated.hpp"
 

Modified: trunk/boost/gil/gil_concept.hpp
==============================================================================
--- trunk/boost/gil/gil_concept.hpp (original)
+++ trunk/boost/gil/gil_concept.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -39,6 +39,9 @@
 template <typename T> class point2;
 template <std::size_t K, typename T> const T& axis_value(const point2<T>& p);
 template <std::size_t K, typename T> T& axis_value( point2<T>& p);
+template <typename ColorBase, int K> struct kth_element_type;
+template <typename ColorBase, int K> struct kth_element_reference_type;
+template <typename ColorBase, int K> struct kth_element_const_reference_type;
 template <typename ColorBase, int K> struct kth_semantic_element_reference_type;
 template <typename ColorBase, int K> struct kth_semantic_element_const_reference_type;
 template <typename ColorBase> struct size;
@@ -65,14 +68,20 @@
 typename add_reference<typename add_const<E>::type>::type at_c(const detail::homogeneous_color_base<E,L,N>& p);
 
 #if !defined(_MSC_VER) || _MSC_VER > 1310
-template <typename P, typename C, typename L> struct heterogeneous_packed_pixel;
+template <typename P, typename C, typename L> struct packed_pixel;
 template <int K, typename P, typename C, typename L>
-typename heterogeneous_packed_pixel<P,C,L>::template kth_element_reference_type<K>::type
-at_c(heterogeneous_packed_pixel<P,C,L>& p);
+typename kth_element_reference_type<packed_pixel<P,C,L>, K>::type
+at_c(packed_pixel<P,C,L>& p);
 
 template <int K, typename P, typename C, typename L>
-typename heterogeneous_packed_pixel<P,C,L>::template kth_element_const_reference_type<K>::type
-at_c(const heterogeneous_packed_pixel<P,C,L>& p);
+typename kth_element_const_reference_type<packed_pixel<P,C,L>,K>::type
+at_c(const packed_pixel<P,C,L>& p);
+
+template <typename C, typename L, bool M> struct bit_aligned_pixel_reference;
+
+template <int K, typename C, typename L, bool M> inline
+typename kth_element_reference_type<bit_aligned_pixel_reference<C,L,M>, K>::type
+at_c(const bit_aligned_pixel_reference<C,L,M>& p);
 #endif
 
 // Forward-declare semantic_at_c
@@ -91,10 +100,10 @@
 } // namespace detail
 
 template <typename T>
-struct remove_const_and_reference : public remove_reference<typename remove_const<T>::type> {};
+struct remove_const_and_reference : public remove_const<typename remove_reference<T>::type> {};
 
 #ifdef BOOST_GIL_USE_CONCEPT_CHECK
- #define GIL_CLASS_REQUIRE(type_var, ns, concept) BOOST_CLASS_REQUIRE(type_var, ns, concept)
+ #define GIL_CLASS_REQUIRE(type_var, ns, concept) BOOST_CLASS_REQUIRE(type_var, ns, concept);
     template <typename C> void gil_function_requires() { function_requires<C>(); }
 #else
     #define GIL_CLASS_REQUIRE(T,NS,C)
@@ -227,14 +236,13 @@
     }
 };
 ////////////////////////////////////////////////////////////////////////////////////////
-///
+//
 // POINT CONCEPTS
-///
+//
 ////////////////////////////////////////////////////////////////////////////////////////
 
 /// \brief N-dimensional point concept
 /// \ingroup PointConcept
-
 /**
 \code
 concept PointNDConcept<typename T> : Regular<T> {
@@ -337,9 +345,9 @@
 } // namespace detail
 
 ////////////////////////////////////////////////////////////////////////////////////////
-///
-/// COLOR SPACE CONCEPTS
-///
+//
+// COLOR SPACE CONCEPTS
+//
 ////////////////////////////////////////////////////////////////////////////////////////
 
 /// \brief Color space type concept
@@ -488,9 +496,16 @@
 
 
 /// \brief Predicate metafunction returning whether two channels are compatible
+/// \ingroup ChannelAlgorithm
 ///
-/// Channels are considered compatible if their value types (ignoring constness and references) are the same
-/// \ingroup ChannelModel
+/// Channels are considered compatible if their value types (ignoring constness and references) are the same.
+/**
+Example:
+
+\code
+BOOST_STATIC_ASSERT((channels_are_compatible<bits8, const bits8&>::value));
+\endcode
+*/
 template <typename T1, typename T2> // Models GIL Pixel
 struct channels_are_compatible
     : public is_same<typename channel_traits<T1>::value_type, typename channel_traits<T2>::value_type> {};
@@ -599,8 +614,8 @@
 
         static const std::size_t num_elements = size<ColorBase>::value;
 
- typedef typename ColorBase::template kth_element_type<num_elements-1>::type TN;
- typedef typename ColorBase::template kth_element_const_reference_type<num_elements-1>::type CR;
+ typedef typename kth_element_type<ColorBase,num_elements-1>::type TN;
+ typedef typename kth_element_const_reference_type<ColorBase,num_elements-1>::type CR;
 
 #if !defined(_MSC_VER) || _MSC_VER > 1310
         CR cr=at_c<num_elements-1>(cb); ignore_unused_variable_warning(cr);
@@ -623,7 +638,7 @@
 concept MutableColorBaseConcept<ColorBaseConcept T> : Assignable<T>, Swappable<T> {
     template <int K> struct kth_element_reference_type; where Metafunction<kth_element_reference_type>;
 
- template <int K> kth_element_reference_type<kth_element_type<K>::type>::type at_c(T);
+ template <int K> kth_element_reference_type<kth_element_type<T,K>::type>::type at_c(T);
     
     template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
         T& operator=(T&, const T2&);
@@ -637,7 +652,7 @@
         gil_function_requires< Assignable<ColorBase> >();
         gil_function_requires< Swappable<ColorBase> >();
 
- typedef typename ColorBase::template kth_element_reference_type<0>::type CR;
+ typedef typename kth_element_reference_type<ColorBase, 0>::type CR;
 
 #if !defined(_MSC_VER) || _MSC_VER > 1310
         CR r=at_c<0>(cb);
@@ -670,8 +685,8 @@
 \code
 concept HomogeneousColorBaseConcept<ColorBaseConcept CB> {
     // For all K in [0 ... size<C1>::value-1):
- // where SameType<kth_element_type<K>::type, kth_element_type<K+1>::type>;
- kth_element_const_reference_type<0>::type dynamic_at_c(const CB&, std::size_t n) const;
+ // where SameType<kth_element_type<CB,K>::type, kth_element_type<CB,K+1>::type>;
+ kth_element_const_reference_type<CB,0>::type dynamic_at_c(const CB&, std::size_t n) const;
 };
 \endcode
 */
@@ -683,11 +698,11 @@
 
         static const std::size_t num_elements = size<ColorBase>::value;
 
- typedef typename ColorBase::template kth_element_type<0>::type T0;
- typedef typename ColorBase::template kth_element_type<num_elements-1>::type TN;
+ typedef typename kth_element_type<ColorBase,0>::type T0;
+ typedef typename kth_element_type<ColorBase,num_elements-1>::type TN;
 
         BOOST_STATIC_ASSERT((is_same<T0,TN>::value)); // better than nothing
- typedef typename ColorBase::template kth_element_const_reference_type<0>::type CR0;
+ typedef typename kth_element_const_reference_type<ColorBase,0>::type CR0;
         CR0 e0=dynamic_at_c(cb,0);
     }
     ColorBase cb;
@@ -699,7 +714,7 @@
 
 \code
 concept MutableHomogeneousColorBaseConcept<ColorBaseConcept CB> : HomogeneousColorBaseConcept<CB> {
- kth_element_reference_type<0>::type dynamic_at_c(CB&, std::size_t n);
+ kth_element_reference_type<CB,0>::type dynamic_at_c(CB&, std::size_t n);
 };
 \endcode
 */
@@ -709,7 +724,7 @@
     void constraints() {
         gil_function_requires< ColorBaseConcept<ColorBase> >();
         gil_function_requires< HomogeneousColorBaseConcept<ColorBase> >();
- typedef typename ColorBase::template kth_element_reference_type<0>::type R0;
+ typedef typename kth_element_reference_type<ColorBase, 0>::type R0;
         R0 x=dynamic_at_c(cb,0);
         dynamic_at_c(cb,0) = dynamic_at_c(cb,0);
     }
@@ -848,7 +863,7 @@
 concept PixelConcept<typename P> : ColorBaseConcept<P>, PixelBasedConcept<P> {
     where is_pixel<P>::type::value==true;
     // where for each K [0..size<P>::value-1]:
- // ChannelConcept<kth_element_type<K> >;
+ // ChannelConcept<kth_element_type<P,K> >;
         
     typename P::value_type; where PixelValueConcept<value_type>;
     typename P::reference; where PixelConcept<reference>;
@@ -990,7 +1005,7 @@
 /// \brief Returns whether two pixels are compatible
 ///
 /// Pixels are compatible if their channels and color space types are compatible. Compatible pixels can be assigned and copy constructed from one another.
-/// \ingroup PixelModel
+/// \ingroup PixelAlgorithm
 template <typename P1, typename P2> // Models GIL Pixel
 struct pixels_are_compatible
     : public mpl::and_<typename color_spaces_are_compatible<typename color_space_type<P1>::type,
@@ -1232,15 +1247,15 @@
 };
 
 namespace detail {
- // Iterators that can be used as the base of byte_addressable_step_iterator require some additional functions
+ // Iterators that can be used as the base of memory_based_step_iterator require some additional functions
     template <typename Iterator> // Preconditions: Iterator Models boost_concepts::RandomAccessTraversalConcept
- struct RandomAccessIteratorIsByteAdvanceableConcept {
+ struct RandomAccessIteratorIsMemoryBasedConcept {
         void constraints() {
- std::ptrdiff_t bs=byte_step(it); ignore_unused_variable_warning(bs);
- it=byte_advanced(it,3);
- std::ptrdiff_t bd=byte_distance(it,it); ignore_unused_variable_warning(bd);
- byte_advance(it,3);
- // for performace you may also provide a customized implementation of byte_advanced_ref
+ std::ptrdiff_t bs=memunit_step(it); ignore_unused_variable_warning(bs);
+ it=memunit_advanced(it,3);
+ std::ptrdiff_t bd=memunit_distance(it,it); ignore_unused_variable_warning(bd);
+ memunit_advance(it,3);
+ // for performace you may also provide a customized implementation of memunit_advanced_ref
         }
         Iterator it;
     };
@@ -1250,24 +1265,25 @@
 /// \ingroup PixelIteratorConcept
 /// \brief Iterator that advances by a specified step
 
-/// \brief Concept of a random-access iterator that can be advanced in bytes
+/// \brief Concept of a random-access iterator that can be advanced in memory units (bytes or bits)
 /// \ingroup PixelIteratorConceptStepIterator
 /**
 \code
-concept ByteAdvanceableIteratorConcept<boost_concepts::RandomAccessTraversalConcept Iterator> {
- std::ptrdiff_t byte_step(const Iterator&);
- std::ptrdiff_t byte_distance(const Iterator& , const Iterator&);
- void byte_advance(Iterator&, std::ptrdiff_t byteDiff);
- Iterator byte_advanced(const Iterator& p, std::ptrdiff_t byteDiff) { Iterator tmp; byte_advance(tmp,pyteDiff); return tmp; }
- Iterator::reference byte_advanced_ref(const Iterator& p, std::ptrdiff_t byteDiff) { return *byte_advanced(p,byteDiff); }
+concept MemoryBasedIteratorConcept<boost_concepts::RandomAccessTraversalConcept Iterator> {
+ typename byte_to_memunit<Iterator>; where metafunction<byte_to_memunit<Iterator> >;
+ std::ptrdiff_t memunit_step(const Iterator&);
+ std::ptrdiff_t memunit_distance(const Iterator& , const Iterator&);
+ void memunit_advance(Iterator&, std::ptrdiff_t diff);
+ Iterator memunit_advanced(const Iterator& p, std::ptrdiff_t diff) { Iterator tmp; memunit_advance(tmp,diff); return tmp; }
+ Iterator::reference memunit_advanced_ref(const Iterator& p, std::ptrdiff_t diff) { return *memunit_advanced(p,diff); }
 };
 \endcode
 */
 template <typename Iterator>
-struct ByteAdvanceableIteratorConcept {
+struct MemoryBasedIteratorConcept {
     void constraints() {
         gil_function_requires<boost_concepts::RandomAccessTraversalConcept<Iterator> >();
- gil_function_requires<detail::RandomAccessIteratorIsByteAdvanceableConcept<Iterator> >();
+ gil_function_requires<detail::RandomAccessIteratorIsMemoryBasedConcept<Iterator> >();
     }
 };
 

Modified: trunk/boost/gil/gil_config.hpp
==============================================================================
--- trunk/boost/gil/gil_config.hpp (original)
+++ trunk/boost/gil/gil_config.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -23,7 +23,7 @@
 
 #include <boost/config.hpp>
 
-#define GIL_VERSION 2.0
+#define GIL_VERSION "2.1.1"
 
 #ifdef _DEBUG
 # define GIL_FORCEINLINE inline

Modified: trunk/boost/gil/image.hpp
==============================================================================
--- trunk/boost/gil/image.hpp (original)
+++ trunk/boost/gil/image.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -188,39 +188,44 @@
     }
 
     void deallocate(const point_t& dimensions) {
- if (_memory) _alloc.deallocate(_memory, total_allocated_size(dimensions));
+ if (_memory) _alloc.deallocate(_memory, total_allocated_size_in_bytes(dimensions));
     }
 
- std::size_t total_allocated_size(const point_t& dimensions) const {
- return _total_allocated_size(dimensions, mpl::bool_<IsPlanar>());
+ std::size_t total_allocated_size_in_bytes(const point_t& dimensions) const {
+ std::size_t size_in_units = _total_allocated_size(dimensions, mpl::bool_<IsPlanar>());
+ // return the size rounded up to the nearest byte
+ return (size_in_units + byte_to_memunit<typename view_t::x_iterator>::value - 1) / byte_to_memunit<typename view_t::x_iterator>::value;
+ }
+
+ std::size_t get_row_size(x_coord_t width) const { // number of units per row
+ return align(width*memunit_step(typename view_t::x_iterator()),_align);
     }
 
     std::size_t _total_allocated_size(const point_t& dimensions,mpl::false_) const {
- std::size_t row_bytes=align(dimensions.x*sizeof(value_type),_align);
- return row_bytes*dimensions.y+_align-1;
+ return get_row_size(dimensions.x)*dimensions.y+_align-1;
     }
     std::size_t _total_allocated_size(const point_t& dimensions,mpl::true_) const {
- std::size_t row_bytes=align(dimensions.x*sizeof(typename channel_type<view_t>::type),_align);
- std::size_t plane_bytes=row_bytes*dimensions.y;
- return plane_bytes*num_channels<view_t>::value+_align-1;
+ std::size_t plane_size=get_row_size(dimensions.x)*dimensions.y;
+ return plane_size*num_channels<view_t>::value+_align-1;
     }
 
     
     void allocate_(const point_t& dimensions, mpl::false_) { // if it throws and _memory!=0 the client must deallocate _memory
- std::size_t row_bytes=align(dimensions.x*sizeof(value_type),_align);
- _memory=_alloc.allocate(total_allocated_size(dimensions));
+ _memory=_alloc.allocate(total_allocated_size_in_bytes(dimensions));
         unsigned char* tmp=(unsigned char*)align((std::size_t)_memory,_align);
- _view=view_t(dimensions,typename view_t::locator(typename view_t::x_iterator(tmp),row_bytes));
+ _view=view_t(dimensions,typename view_t::locator(typename view_t::x_iterator(tmp),get_row_size(dimensions.x)));
     }
     void allocate_(const point_t& dimensions, mpl::true_) { // if it throws and _memory!=0 the client must deallocate _memory
- std::size_t row_bytes=align(dimensions.x*sizeof(typename channel_type<view_t>::type),_align);
- std::size_t plane_bytes=row_bytes*dimensions.y;
- _memory=_alloc.allocate(total_allocated_size(dimensions));
+ std::size_t row_size=get_row_size(dimensions.x);
+ std::size_t plane_size=row_size*dimensions.y;
+ _memory=_alloc.allocate(total_allocated_size_in_bytes(dimensions));
         unsigned char* tmp=(unsigned char*)align((std::size_t)_memory,_align);
         typename view_t::x_iterator first;
- for (int i=0; i<num_channels<view_t>::value; ++i)
- dynamic_at_c(first,i) = (typename channel_type<view_t>::type*)(tmp + plane_bytes*i);
- _view=view_t(dimensions, typename view_t::locator(first, dimensions.x*sizeof(typename channel_type<view_t>::type)));
+ for (int i=0; i<num_channels<view_t>::value; ++i) {
+ dynamic_at_c(first,i) = (typename channel_type<view_t>::type*)tmp;
+ memunit_advance(dynamic_at_c(first,i), plane_size*i);
+ }
+ _view=view_t(dimensions, typename view_t::locator(first, row_size));
     }
 };
 

Modified: trunk/boost/gil/image_view_factory.hpp
==============================================================================
--- trunk/boost/gil/image_view_factory.hpp (original)
+++ trunk/boost/gil/image_view_factory.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -31,9 +31,9 @@
 #include "gray.hpp"
 #include "color_convert.hpp"
 
-/// \defgroup ImageViewConstructors Image View Constructors
+/// \defgroup ImageViewConstructors Image View From Raw Data
 /// \ingroup ImageViewAlgorithm
-/// \brief Methods for constructing image views from raw data
+/// \brief Methods for constructing image views from raw data and for getting raw data from views
 
 /// \defgroup ImageViewTransformations Image View Transformations
 /// \ingroup ImageViewAlgorithm
@@ -77,6 +77,42 @@
     return RView(dim, typename RView::locator(pixels, rowsize_in_bytes));
 }
 
+/////////////////////////////
+// interleaved_view_get_raw_data, planar_view_get_raw_data - return pointers to the raw data (the channels) of a basic homogeneous view.
+/////////////////////////////
+
+namespace detail {
+ template <typename View, bool IsMutable> struct channel_pointer_type_impl;
+
+ template <typename View> struct channel_pointer_type_impl<View, true> {
+ typedef typename channel_type<View>::type* type;
+ };
+ template <typename View> struct channel_pointer_type_impl<View, false> {
+ typedef const typename channel_type<View>::type* type;
+ };
+
+ template <typename View> struct channel_pointer_type
+ : public channel_pointer_type_impl<View, view_is_mutable<View>::value> {};
+};
+
+/// \ingroup ImageViewConstructors
+/// \brief Returns C pointer to the the channels of an interleaved homogeneous view.
+template <typename HomogeneousView>
+typename detail::channel_pointer_type<HomogeneousView>::type interleaved_view_get_raw_data(const HomogeneousView& view) {
+ BOOST_STATIC_ASSERT((!is_planar<HomogeneousView>::value && view_is_basic<HomogeneousView>::value));
+ BOOST_STATIC_ASSERT((boost::is_pointer<typename HomogeneousView::x_iterator>::value));
+
+ return &at_c<0>(view(0,0));
+}
+
+/// \ingroup ImageViewConstructors
+/// \brief Returns C pointer to the the channels of a given color plane of a planar homogeneous view.
+template <typename HomogeneousView>
+typename detail::channel_pointer_type<HomogeneousView>::type planar_view_get_raw_data(const HomogeneousView& view, int plane_index) {
+ BOOST_STATIC_ASSERT((is_planar<HomogeneousView>::value && view_is_basic<HomogeneousView>::value));
+ return dynamic_at_c(view.row_begin(0),plane_index);
+}
+
 
 /// \defgroup ImageViewTransformationsColorConvert color_converted_view
 /// \ingroup ImageViewTransformations
@@ -87,23 +123,15 @@
 ///
 /// Useful in constructing a color converted view over a given image view
 template <typename SrcConstRefP, typename DstP, typename CC=default_color_converter > // const_reference to the source pixel and destination pixel value
-class color_convert_deref_fn {
+class color_convert_deref_fn : public deref_base<color_convert_deref_fn<SrcConstRefP,DstP,CC>, DstP, DstP, const DstP&, SrcConstRefP, DstP, false> {
 private:
     CC _cc; // color-converter
 public:
- typedef color_convert_deref_fn const_t;
- typedef DstP value_type;
- typedef value_type reference; // read-only dereferencing
- typedef const value_type& const_reference;
- typedef SrcConstRefP argument_type;
- typedef reference result_type;
- BOOST_STATIC_CONSTANT(bool, is_mutable=false);
-
     color_convert_deref_fn() {}
     color_convert_deref_fn(CC cc_in) : _cc(cc_in) {}
 
- result_type operator()(argument_type srcP) const {
- result_type dstP;
+ DstP operator()(SrcConstRefP srcP) const {
+ DstP dstP;
         _cc(srcP,dstP);
         return dstP;
     }
@@ -137,7 +165,7 @@
                                                                              CC,
                                                                              DstP,
                                                                              typename SrcView::value_type> {
- GIL_CLASS_REQUIRE(DstP, boost::gil, MutablePixelConcept);//why does it have to be mutable???
+ GIL_CLASS_REQUIRE(DstP, boost::gil, MutablePixelConcept)//why does it have to be mutable???
 };
 
 
@@ -274,8 +302,8 @@
             typedef typename type::xy_locator locator_t;
             typedef typename type::x_iterator x_iterator_t;
             typedef typename iterator_adaptor_get_base<x_iterator_t>::type x_iterator_base_t;
- x_iterator_t sit(x_iterator_base_t(&(src(0,0)[n])),src.pixels().pix_bytestep());
- return type(src.dimensions(),locator_t(sit, src.pixels().row_bytes()));
+ x_iterator_t sit(x_iterator_base_t(&(src(0,0)[n])),src.pixels().pixel_size());
+ return type(src.dimensions(),locator_t(sit, src.pixels().row_size()));
         }
     };
 
@@ -285,7 +313,7 @@
         typedef typename view_type<typename channel_type<View>::type, gray_layout_t, false, false, view_is_mutable<View>::value>::type type;
         static type make(const View& src, int n) {
             typedef typename type::x_iterator x_iterator_t;
- return interleaved_view(src.width(),src.height(),(x_iterator_t)&(src(0,0)[n]), src.pixels().row_bytes());
+ return interleaved_view(src.width(),src.height(),(x_iterator_t)&(src(0,0)[n]), src.pixels().row_size());
         }
     };
 
@@ -317,19 +345,19 @@
     template <typename SrcP> // SrcP is a reference to PixelConcept (could be pixel value or const/non-const reference)
                                     // Examples: pixel<T,L>, pixel<T,L>&, const pixel<T,L>&, planar_pixel_reference<T&,L>, planar_pixel_reference<const T&,L>
     struct nth_channel_deref_fn {
- BOOST_STATIC_CONSTANT(bool, is_mutable=is_pixel_reference<SrcP>::value && pixel_reference_is_mutable<SrcP>::value);
+ BOOST_STATIC_CONSTANT(bool, is_mutable=pixel_is_reference<SrcP>::value && pixel_reference_is_mutable<SrcP>::value);
     private:
         typedef typename remove_reference<SrcP>::type src_pixel_t;
         typedef typename channel_type<src_pixel_t>::type channel_t;
         typedef typename src_pixel_t::const_reference const_ref_t;
         typedef typename pixel_reference_type<channel_t,gray_layout_t,false,is_mutable>::type ref_t;
     public:
- typedef nth_channel_deref_fn<const_ref_t> const_t;
- typedef pixel<channel_t,gray_layout_t> value_type;
+ typedef nth_channel_deref_fn<const_ref_t> const_t;
+ typedef typename pixel_value_type<channel_t,gray_layout_t>::type value_type;
         typedef typename pixel_reference_type<channel_t,gray_layout_t,false,false>::type const_reference;
- typedef SrcP argument_type;
- typedef typename mpl::if_c<is_mutable, ref_t, value_type>::type reference;
- typedef reference result_type;
+ typedef SrcP argument_type;
+ typedef typename mpl::if_c<is_mutable, ref_t, value_type>::type reference;
+ typedef reference result_type;
 
         nth_channel_deref_fn(int n=0) : _n(n) {}
         template <typename P> nth_channel_deref_fn(const nth_channel_deref_fn<P>& d) : _n(d._n) {}
@@ -362,7 +390,7 @@
 template <typename View>
 struct nth_channel_view_type {
 private:
- GIL_CLASS_REQUIRE(View, boost::gil, ImageViewConcept);
+ GIL_CLASS_REQUIRE(View, boost::gil, ImageViewConcept)
     typedef detail::__nth_channel_view<View,view_is_basic<View>::value> VB;
 public:
     typedef typename VB::type type;
@@ -394,7 +422,7 @@
     template <int K, typename View>
     struct __kth_channel_view_basic<K,View,false> {
     private:
- typedef typename View::value_type::template kth_element_type<K>::type channel_t;
+ typedef typename kth_element_type<typename View::value_type,K>::type channel_t;
     public:
         typedef typename view_type<channel_t, gray_layout_t, false, true, view_is_mutable<View>::value>::type type;
 
@@ -402,8 +430,8 @@
             typedef typename type::xy_locator locator_t;
             typedef typename type::x_iterator x_iterator_t;
             typedef typename iterator_adaptor_get_base<x_iterator_t>::type x_iterator_base_t;
- x_iterator_t sit(x_iterator_base_t(&at_c<K>(src(0,0))),src.pixels().pix_bytestep());
- return type(src.dimensions(),locator_t(sit, src.pixels().row_bytes()));
+ x_iterator_t sit(x_iterator_base_t(&at_c<K>(src(0,0))),src.pixels().pixel_size());
+ return type(src.dimensions(),locator_t(sit, src.pixels().row_size()));
         }
     };
 
@@ -411,12 +439,12 @@
     template <int K, typename View>
     struct __kth_channel_view_basic<K,View,true> {
     private:
- typedef typename View::value_type::template kth_element_type<K>::type channel_t;
+ typedef typename kth_element_type<typename View::value_type, K>::type channel_t;
     public:
         typedef typename view_type<channel_t, gray_layout_t, false, false, view_is_mutable<View>::value>::type type;
         static type make(const View& src) {
             typedef typename type::x_iterator x_iterator_t;
- return interleaved_view(src.width(),src.height(),(x_iterator_t)&at_c<K>(src(0,0)), src.pixels().row_bytes());
+ return interleaved_view(src.width(),src.height(),(x_iterator_t)&at_c<K>(src(0,0)), src.pixels().row_size());
         }
     };
 
@@ -448,15 +476,15 @@
     template <int K, typename SrcP> // SrcP is a reference to PixelConcept (could be pixel value or const/non-const reference)
                                     // Examples: pixel<T,L>, pixel<T,L>&, const pixel<T,L>&, planar_pixel_reference<T&,L>, planar_pixel_reference<const T&,L>
     struct kth_channel_deref_fn {
- BOOST_STATIC_CONSTANT(bool, is_mutable=is_pixel_reference<SrcP>::value && pixel_reference_is_mutable<SrcP>::value);
+ BOOST_STATIC_CONSTANT(bool, is_mutable=pixel_is_reference<SrcP>::value && pixel_reference_is_mutable<SrcP>::value);
     private:
         typedef typename remove_reference<SrcP>::type src_pixel_t;
- typedef typename src_pixel_t::template kth_element_type<K>::type channel_t;
+ typedef typename kth_element_type<src_pixel_t, K>::type channel_t;
         typedef typename src_pixel_t::const_reference const_ref_t;
         typedef typename pixel_reference_type<channel_t,gray_layout_t,false,is_mutable>::type ref_t;
     public:
         typedef kth_channel_deref_fn<K,const_ref_t> const_t;
- typedef pixel<channel_t,gray_layout_t> value_type;
+ typedef typename pixel_value_type<channel_t,gray_layout_t>::type value_type;
         typedef typename pixel_reference_type<channel_t,gray_layout_t,false,false>::type const_reference;
         typedef SrcP argument_type;
         typedef typename mpl::if_c<is_mutable, ref_t, value_type>::type reference;
@@ -491,7 +519,7 @@
 template <int K, typename View>
 struct kth_channel_view_type {
 private:
- GIL_CLASS_REQUIRE(View, boost::gil, ImageViewConcept);
+ GIL_CLASS_REQUIRE(View, boost::gil, ImageViewConcept)
     typedef detail::__kth_channel_view<K,View,view_is_basic<View>::value> VB;
 public:
     typedef typename VB::type type;

Modified: trunk/boost/gil/iterator_from_2d.hpp
==============================================================================
--- trunk/boost/gil/iterator_from_2d.hpp (original)
+++ trunk/boost/gil/iterator_from_2d.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -54,7 +54,7 @@
                                                 random_access_traversal_tag,
                                                 typename Loc2::reference,
                                                 typename Loc2::coord_t> {
- GIL_CLASS_REQUIRE(Loc2, boost::gil, PixelLocatorConcept);
+ GIL_CLASS_REQUIRE(Loc2, boost::gil, PixelLocatorConcept)
 public:
     typedef iterator_facade<iterator_from_2d<Loc2>,
                             typename Loc2::value_type,
@@ -67,7 +67,8 @@
     typedef typename Loc2::point_t point_t;
 
     int width() const { return _width; } // number of pixels per image row
- int x_pos() const { return _x; } // current x position
+ int x_pos() const { return _coords.x; } // current x position
+ int y_pos() const { return _coords.y; } // current y position
 
     /// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference
     /// We require our own reference because it is registered in iterator_traits
@@ -77,27 +78,29 @@
     x_iterator& x() { return _p.x(); }
 
     iterator_from_2d(){}
- iterator_from_2d(const Loc2& p, int width, int x=0) : _x(x), _width(width), _p(p) {}
- iterator_from_2d(const iterator_from_2d& pit) : _x(pit._x), _width(pit._width), _p(pit._p) {}
- template <typename Loc> iterator_from_2d(const iterator_from_2d<Loc>& pit) : _x(pit._x), _width(pit._width), _p(pit._p) {}
+ iterator_from_2d(const Loc2& p, int width, int x=0, int y=0) : _coords(x,y), _width(width), _p(p) {}
+ iterator_from_2d(const iterator_from_2d& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
+ template <typename Loc> iterator_from_2d(const iterator_from_2d<Loc>& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
 
 private:
     template <typename Loc> friend class iterator_from_2d;
     friend class boost::iterator_core_access;
     reference dereference() const { return *_p; }
     void increment() {
- ++_x;
+ ++_coords.x;
         ++_p.x();
- if (_x>=_width) {
- _x=0;
+ if (_coords.x>=_width) {
+ _coords.x=0;
+ ++_coords.y;
             _p+=point_t(-_width,1);
         }
     }
     void decrement() {
- --_x;
+ --_coords.x;
         --_p.x();
- if (_x<0) {
- _x=_width-1;
+ if (_coords.x<0) {
+ _coords.x=_width-1;
+ --_coords.y;
             _p+=point_t(_width,-1);
         }
     }
@@ -105,29 +108,30 @@
     GIL_FORCEINLINE void advance(difference_type d) {
         if (_width==0) return; // unfortunately we need to check for that. Default-constructed images have width of 0 and the code below will throw if executed.
         point_t delta;
- if (_x+d>=0) { // not going back to a previous row?
- delta.x=(_x+(int)d)%_width - _x;
- delta.y=(_x+(int)d)/_width;
+ if (_coords.x+d>=0) { // not going back to a previous row?
+ delta.x=(_coords.x+(int)d)%_width - _coords.x;
+ delta.y=(_coords.x+(int)d)/_width;
         } else {
- delta.x=(_x+(int)d*(1-_width))%_width -_x;
- delta.y=-(_width-_x-(int)d-1)/_width;
+ delta.x=(_coords.x+(int)d*(1-_width))%_width -_coords.x;
+ delta.y=-(_width-_coords.x-(int)d-1)/_width;
         }
         _p+=delta;
- _x+=delta.x;
+ _coords.x+=delta.x;
+ _coords.y+=delta.y;
     }
 
     difference_type distance_to(const iterator_from_2d& it) const {
         if (_width==0) return 0;
- int xd=it.x_pos()-_x;
- return _p.y_distance_to(it._p,xd)*_width+xd;
+ return (it.y_pos()-_coords.y)*_width + (it.x_pos()-_coords.x);
     }
 
     bool equal(const iterator_from_2d& it) const {
         assert(_width==it.width()); // they must belong to the same image
- return _p==it._p;
+ return _coords==it._coords && _p==it._p;
     }
 
- int _x,_width;
+ point2<int> _coords;
+ int _width;
     Loc2 _p;
 };
 

Modified: trunk/boost/gil/locator.hpp
==============================================================================
--- trunk/boost/gil/locator.hpp (original)
+++ trunk/boost/gil/locator.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -35,9 +35,9 @@
 namespace boost { namespace gil {
 
 //forward declarations
-template <typename P> ptrdiff_t byte_step(const P*);
-template <typename P> P* byte_advanced(const P* p, ptrdiff_t byteDiff);
-template <typename P> P& byte_advanced_ref(P* p, ptrdiff_t byteDiff);
+template <typename P> ptrdiff_t memunit_step(const P*);
+template <typename P> P* memunit_advanced(const P* p, ptrdiff_t diff);
+template <typename P> P& memunit_advanced_ref(P* p, ptrdiff_t diff);
 template <typename Iterator, typename D> struct iterator_add_deref;
 template <typename T> class point2;
 namespace detail {
@@ -50,6 +50,7 @@
 template <typename T> struct channel_type;
 template <typename T> struct color_space_type;
 template <typename T> struct channel_mapping_type;
+template <typename T> struct is_planar;
 template <typename T> struct num_channels;
 
 // The type of a locator or a view that has X and Y swapped. By default it is the same
@@ -77,7 +78,7 @@
 /// Also 2D difference between two locators cannot be computed without knowledge of the X position within the image.
 ///
 /// This base class provides most of the methods and typedefs needed to create a model of a locator. GIL provides two
-/// locator models as subclasses of \p pixel_2d_locator_base. A memory-based locator, \p byte_addressable_2d_locator and a virtual
+/// locator models as subclasses of \p pixel_2d_locator_base. A memory-based locator, \p memory_based_2d_locator and a virtual
 /// locator, \p virtual_2d_locator.
 /// The minimum functionality a subclass must provide is this:
 /// \code
@@ -215,7 +216,7 @@
 template <typename Loc, typename XIt, typename YIt>
 struct is_planar<pixel_2d_locator_base<Loc,XIt,YIt> > : public is_planar<XIt> {};
 
-/// \class byte_addressable_2d_locator
+/// \class memory_based_2d_locator
 /// \brief Memory-based pixel locator. Models: PixelLocatorConcept,HasDynamicXStepTypeConcept,HasDynamicYStepTypeConcept,HasTransposedTypeConcept
 /// \ingroup PixelLocatorModel PixelBasedModel
 ///
@@ -230,19 +231,19 @@
 /// one std::ptrdiff_t for the horizontal step of two and a CMYK planar_pixel_iterator consisting of 4 pointers (24 bytes).
 /// In this case ++locator.x() results in four native pointer additions.
 ///
-/// Note also that \p byte_addressable_2d_locator does not require that its element type be a pixel. It could be
+/// Note also that \p memory_based_2d_locator does not require that its element type be a pixel. It could be
 /// instantiated with an iterator whose \p value_type models only \p Regular. In this case the locator
 /// models the weaker RandomAccess2DLocatorConcept, and does not model PixelBasedConcept.
 /// Many generic algorithms don't require the elements to be pixels.
 ////////////////////////////////////////////////////////////////////////////////////////
 
 template <typename StepIterator>
-class byte_addressable_2d_locator : public pixel_2d_locator_base<byte_addressable_2d_locator<StepIterator>, typename iterator_adaptor_get_base<StepIterator>::type, StepIterator> {
- typedef byte_addressable_2d_locator<StepIterator> this_t;
- GIL_CLASS_REQUIRE(StepIterator, boost::gil, StepIteratorConcept);
+class memory_based_2d_locator : public pixel_2d_locator_base<memory_based_2d_locator<StepIterator>, typename iterator_adaptor_get_base<StepIterator>::type, StepIterator> {
+ typedef memory_based_2d_locator<StepIterator> this_t;
+ GIL_CLASS_REQUIRE(StepIterator, boost::gil, StepIteratorConcept)
 public:
- typedef pixel_2d_locator_base<byte_addressable_2d_locator<StepIterator>, typename iterator_adaptor_get_base<StepIterator>::type, StepIterator> parent_t;
- typedef byte_addressable_2d_locator<typename const_iterator_type<StepIterator>::type> const_t; // same as this type, but over const values
+ typedef pixel_2d_locator_base<memory_based_2d_locator<StepIterator>, typename iterator_adaptor_get_base<StepIterator>::type, StepIterator> parent_t;
+ typedef memory_based_2d_locator<typename const_iterator_type<StepIterator>::type> const_t; // same as this type, but over const values
 
     typedef typename parent_t::coord_t coord_t;
     typedef typename parent_t::x_coord_t x_coord_t;
@@ -253,22 +254,22 @@
     typedef typename parent_t::reference reference;
 
     template <typename Deref> struct add_deref {
- typedef byte_addressable_2d_locator<typename iterator_add_deref<StepIterator,Deref>::type> type;
- static type make(const byte_addressable_2d_locator<StepIterator>& loc, const Deref& nderef) {
+ typedef memory_based_2d_locator<typename iterator_add_deref<StepIterator,Deref>::type> type;
+ static type make(const memory_based_2d_locator<StepIterator>& loc, const Deref& nderef) {
             return type(iterator_add_deref<StepIterator,Deref>::make(loc.y(),nderef));
         }
     };
 
- byte_addressable_2d_locator() {}
- byte_addressable_2d_locator(const StepIterator& yit) : _p(yit) {}
- template <typename SI> byte_addressable_2d_locator(const byte_addressable_2d_locator<SI>& loc, coord_t y_step) : _p(loc.x(), loc.row_bytes()*y_step) {}
- template <typename SI> byte_addressable_2d_locator(const byte_addressable_2d_locator<SI>& loc, coord_t x_step, coord_t y_step, bool transpose=false)
- : _p(make_step_iterator(loc.x(),(transpose ? loc.row_bytes() : loc.pix_bytestep())*x_step),
- (transpose ? loc.pix_bytestep() : loc.row_bytes())*y_step ) {}
-
- byte_addressable_2d_locator(x_iterator xit, std::ptrdiff_t row_bytes) : _p(xit,row_bytes) {}
- template <typename X> byte_addressable_2d_locator(const byte_addressable_2d_locator<X>& pl) : _p(pl._p) {}
- byte_addressable_2d_locator(const byte_addressable_2d_locator& pl) : _p(pl._p) {}
+ memory_based_2d_locator() {}
+ memory_based_2d_locator(const StepIterator& yit) : _p(yit) {}
+ template <typename SI> memory_based_2d_locator(const memory_based_2d_locator<SI>& loc, coord_t y_step) : _p(loc.x(), loc.row_size()*y_step) {}
+ template <typename SI> memory_based_2d_locator(const memory_based_2d_locator<SI>& loc, coord_t x_step, coord_t y_step, bool transpose=false)
+ : _p(make_step_iterator(loc.x(),(transpose ? loc.row_size() : loc.pixel_size())*x_step),
+ (transpose ? loc.pixel_size() : loc.row_size())*y_step ) {}
+
+ memory_based_2d_locator(x_iterator xit, std::ptrdiff_t row_bytes) : _p(xit,row_bytes) {}
+ template <typename X> memory_based_2d_locator(const memory_based_2d_locator<X>& pl) : _p(pl._p) {}
+ memory_based_2d_locator(const memory_based_2d_locator& pl) : _p(pl._p) {}
 
     bool operator==(const this_t& p) const { return _p==p._p; }
 
@@ -278,37 +279,37 @@
     y_iterator& y() { return _p; }
 
     // These are faster versions of functions already provided in the superclass
- x_iterator x_at (x_coord_t dx, y_coord_t dy) const { return byte_advanced(x(), byte_offset(dx,dy)); }
- x_iterator x_at (const difference_type& d) const { return byte_advanced(x(), byte_offset(d.x,d.y)); }
- this_t xy_at (x_coord_t dx, y_coord_t dy) const { return this_t(x_at( dx , dy ), row_bytes()); }
- this_t xy_at (const difference_type& d) const { return this_t(x_at( d.x, d.y), row_bytes()); }
- reference operator()(x_coord_t dx, y_coord_t dy) const { return byte_advanced_ref(x(),byte_offset(dx,dy)); }
- reference operator[](const difference_type& d) const { return byte_advanced_ref(x(),byte_offset(d.x,d.y)); }
- this_t& operator+=(const difference_type& d) { byte_advance(x(),byte_offset(d.x,d.y)); return *this; }
- this_t& operator-=(const difference_type& d) { byte_advance(x(),byte_offset(-d.x,-d.y)); return *this; }
+ x_iterator x_at (x_coord_t dx, y_coord_t dy) const { return memunit_advanced(x(), offset(dx,dy)); }
+ x_iterator x_at (const difference_type& d) const { return memunit_advanced(x(), offset(d.x,d.y)); }
+ this_t xy_at (x_coord_t dx, y_coord_t dy) const { return this_t(x_at( dx , dy ), row_size()); }
+ this_t xy_at (const difference_type& d) const { return this_t(x_at( d.x, d.y), row_size()); }
+ reference operator()(x_coord_t dx, y_coord_t dy) const { return memunit_advanced_ref(x(),offset(dx,dy)); }
+ reference operator[](const difference_type& d) const { return memunit_advanced_ref(x(),offset(d.x,d.y)); }
+ this_t& operator+=(const difference_type& d) { memunit_advance(x(),offset(d.x,d.y)); return *this; }
+ this_t& operator-=(const difference_type& d) { memunit_advance(x(),offset(-d.x,-d.y)); return *this; }
 
     // Memory-based locators can have 1D caching of 2D relative coordinates
     typedef std::ptrdiff_t cached_location_t; // type used to store relative location (to allow for more efficient repeated access)
- cached_location_t cache_location(const difference_type& d) const { return byte_offset(d.x,d.y); }
- cached_location_t cache_location(x_coord_t dx, y_coord_t dy)const { return byte_offset(dx,dy); }
- reference operator[](const cached_location_t& loc) const { return byte_advanced_ref(x(),loc); }
+ cached_location_t cache_location(const difference_type& d) const { return offset(d.x,d.y); }
+ cached_location_t cache_location(x_coord_t dx, y_coord_t dy)const { return offset(dx,dy); }
+ reference operator[](const cached_location_t& loc) const { return memunit_advanced_ref(x(),loc); }
 
     // Only make sense for memory-based locators
- std::ptrdiff_t row_bytes() const { return byte_step(y()); } // row bytes
- std::ptrdiff_t pix_bytestep() const { return byte_step(x()); } // distance in bytes between adjacent pixels on the same row
+ std::ptrdiff_t row_size() const { return memunit_step(y()); } // distance in mem units (bytes or bits) between adjacent rows
+ std::ptrdiff_t pixel_size() const { return memunit_step(x()); } // distance in mem units (bytes or bits) between adjacent pixels on the same row
 
- bool is_1d_traversable(x_coord_t width) const { return row_bytes()-pix_bytestep()*width==0; } // is there no gap at the end of each row?
+ bool is_1d_traversable(x_coord_t width) const { return row_size()-pixel_size()*width==0; } // is there no gap at the end of each row?
 
     // Returns the vertical distance (it2.y-it1.y) between two x_iterators given the difference of their x positions
     std::ptrdiff_t y_distance_to(const this_t& p2, x_coord_t xDiff) const {
- std::ptrdiff_t rowDiff=byte_distance(x(),p2.x())-pix_bytestep()*xDiff;
- assert(( rowDiff % row_bytes())==0);
- return rowDiff / row_bytes();
+ std::ptrdiff_t rowDiff=memunit_distance(x(),p2.x())-pixel_size()*xDiff;
+ assert(( rowDiff % row_size())==0);
+ return rowDiff / row_size();
     }
 
 private:
- template <typename X> friend class byte_addressable_2d_locator;
- std::ptrdiff_t byte_offset(x_coord_t x, y_coord_t y) const { return y*row_bytes() + x*pix_bytestep(); }
+ template <typename X> friend class memory_based_2d_locator;
+ std::ptrdiff_t offset(x_coord_t x, y_coord_t y) const { return y*row_size() + x*pixel_size(); }
     StepIterator _p;
 };
 
@@ -317,19 +318,19 @@
 /////////////////////////////
 
 template <typename SI>
-struct color_space_type<byte_addressable_2d_locator<SI> > : public color_space_type<typename byte_addressable_2d_locator<SI>::parent_t> {
+struct color_space_type<memory_based_2d_locator<SI> > : public color_space_type<typename memory_based_2d_locator<SI>::parent_t> {
 };
 
 template <typename SI>
-struct channel_mapping_type<byte_addressable_2d_locator<SI> > : public channel_mapping_type<typename byte_addressable_2d_locator<SI>::parent_t> {
+struct channel_mapping_type<memory_based_2d_locator<SI> > : public channel_mapping_type<typename memory_based_2d_locator<SI>::parent_t> {
 };
 
 template <typename SI>
-struct is_planar<byte_addressable_2d_locator<SI> > : public is_planar<typename byte_addressable_2d_locator<SI>::parent_t> {
+struct is_planar<memory_based_2d_locator<SI> > : public is_planar<typename memory_based_2d_locator<SI>::parent_t> {
 };
 
 template <typename SI>
-struct channel_type<byte_addressable_2d_locator<SI> > : public channel_type<typename byte_addressable_2d_locator<SI>::parent_t> {
+struct channel_type<memory_based_2d_locator<SI> > : public channel_type<typename memory_based_2d_locator<SI>::parent_t> {
 };
 
 /////////////////////////////
@@ -338,13 +339,13 @@
 
 // Take the base iterator of SI (which is typically a step iterator) and change it to have a step in x
 template <typename SI>
-struct dynamic_x_step_type<byte_addressable_2d_locator<SI> > {
+struct dynamic_x_step_type<memory_based_2d_locator<SI> > {
 private:
     typedef typename iterator_adaptor_get_base<SI>::type base_iterator_t;
     typedef typename dynamic_x_step_type<base_iterator_t>::type base_iterator_step_t;
     typedef typename iterator_adaptor_rebind<SI, base_iterator_step_t>::type dynamic_step_base_t;
 public:
- typedef byte_addressable_2d_locator<dynamic_step_base_t> type;
+ typedef memory_based_2d_locator<dynamic_step_base_t> type;
 };
 
 /////////////////////////////
@@ -352,8 +353,8 @@
 /////////////////////////////
 
 template <typename SI>
-struct dynamic_y_step_type<byte_addressable_2d_locator<SI> > {
- typedef byte_addressable_2d_locator<SI> type;
+struct dynamic_y_step_type<memory_based_2d_locator<SI> > {
+ typedef memory_based_2d_locator<SI> type;
 };
 
 } } // namespace boost::gil

Modified: trunk/boost/gil/metafunctions.hpp
==============================================================================
--- trunk/boost/gil/metafunctions.hpp (original)
+++ trunk/boost/gil/metafunctions.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -24,20 +24,28 @@
 ////////////////////////////////////////////////////////////////////////////////////////
 
 #include <iterator>
-#include <boost/mpl/if.hpp>
+#include <boost/mpl/accumulate.hpp>
+#include <boost/mpl/back.hpp>
 #include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/pop_back.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/mpl/transform.hpp>
+#include <boost/mpl/vector.hpp>
 #include <boost/type_traits.hpp>
 #include "gil_config.hpp"
 #include "gil_concept.hpp"
+#include "channel.hpp"
 
 namespace boost { namespace gil {
 
 // forward declarations
 template <typename T, typename L> struct pixel;
+template <typename BitField,typename ChannelRefVec,typename Layout> struct packed_pixel;
 template <typename T, typename C> struct planar_pixel_reference;
 template <typename IC, typename C> struct planar_pixel_iterator;
-template <typename I> class byte_addressable_step_iterator;
-template <typename I> class byte_addressable_2d_locator;
+template <typename I> class memory_based_step_iterator;
+template <typename I> class memory_based_2d_locator;
 template <typename L> class image_view;
 template <typename Pixel, bool IsPlanar, typename Alloc> class image;
 template <typename T> struct channel_type;
@@ -45,7 +53,7 @@
 template <typename T> struct channel_mapping_type;
 template <typename It> struct is_iterator_adaptor;
 template <typename It> struct iterator_adaptor_get_base;
-
+template <typename ChannelBitSizes, typename Layout, bool IsMutable> struct bit_aligned_pixel_reference;
 
 //////////////////////////////////////////////////
 ///
@@ -73,7 +81,7 @@
 
 
 /// \brief Determines if a given pixel iterator is basic
-/// Basic iterators must use gil::pixel (if interleaved), gil::planar_pixel_iterator (if planar) and gil::byte_addressable_step_iterator (if step). They must use the standard constness rules.
+/// Basic iterators must use gil::pixel (if interleaved), gil::planar_pixel_iterator (if planar) and gil::memory_based_step_iterator (if step). They must use the standard constness rules.
 /// \ingroup GILIsBasic
 template <typename Iterator>
 struct iterator_is_basic : public mpl::false_ {};
@@ -86,19 +94,19 @@
 template <typename T, typename Cs> // immutable planar
 struct iterator_is_basic<planar_pixel_iterator<const T*,Cs> > : public mpl::true_ {};
 template <typename T, typename L> // mutable interleaved step
-struct iterator_is_basic<byte_addressable_step_iterator< pixel<T,L>*> > : public mpl::true_ {};
+struct iterator_is_basic<memory_based_step_iterator< pixel<T,L>*> > : public mpl::true_ {};
 template <typename T, typename L> // immutable interleaved step
-struct iterator_is_basic<byte_addressable_step_iterator<const pixel<T,L>*> > : public mpl::true_ {};
+struct iterator_is_basic<memory_based_step_iterator<const pixel<T,L>*> > : public mpl::true_ {};
 template <typename T, typename Cs> // mutable planar step
-struct iterator_is_basic<byte_addressable_step_iterator<planar_pixel_iterator< T*,Cs> > > : public mpl::true_ {};
+struct iterator_is_basic<memory_based_step_iterator<planar_pixel_iterator< T*,Cs> > > : public mpl::true_ {};
 template <typename T, typename Cs> // immutable planar step
-struct iterator_is_basic<byte_addressable_step_iterator<planar_pixel_iterator<const T*,Cs> > > : public mpl::true_ {};
+struct iterator_is_basic<memory_based_step_iterator<planar_pixel_iterator<const T*,Cs> > > : public mpl::true_ {};
 
 
 /// \ingroup GILIsBasic
 /// \brief Determines if a given locator is basic. A basic locator is memory-based and has basic x_iterator and y_iterator
 template <typename Loc> struct locator_is_basic : public mpl::false_ {};
-template <typename Iterator> struct locator_is_basic<byte_addressable_2d_locator<byte_addressable_step_iterator<Iterator> > > : public iterator_is_basic<Iterator> {};
+template <typename Iterator> struct locator_is_basic<memory_based_2d_locator<memory_based_step_iterator<Iterator> > > : public iterator_is_basic<Iterator> {};
 
 /// \ingroup GILIsBasic
 /// \brief Basic views must be over basic locators
@@ -152,6 +160,18 @@
 /// \brief Determines if the given view has a vertical step that could be set dynamically
 template <typename V> struct view_is_step_in_y : public locator_is_step_in_y<typename V::xy_locator> {};
 
+/// \brief Determines whether the given pixel reference is a proxy class or a native C++ reference
+/// \ingroup TypeAnalysis
+template <typename PixelReference>
+struct pixel_reference_is_proxy
+ : public mpl::not_<is_same<typename remove_const_and_reference<PixelReference>::type,
+ typename remove_const_and_reference<PixelReference>::type::value_type> > {};
+
+/// \brief Given a model of a pixel, determines whether the model represents a pixel reference (as opposed to pixel value)
+/// \ingroup TypeAnalysis
+template <typename Pixel>
+struct pixel_is_reference : public mpl::or_<is_reference<Pixel>, pixel_reference_is_proxy<Pixel> > {};
+
 /// \defgroup GILIsMutable xxx_is_mutable
 /// \ingroup TypeAnalysis
 /// \brief Determines if the given pixel reference/iterator/locator/view is mutable (i.e. its pixels can be changed)
@@ -160,11 +180,9 @@
 /// \brief Determines if the given pixel reference is mutable (i.e. its channels can be changed)
 ///
 /// Note that built-in C++ references obey the const qualifier but reference proxy classes do not.
-template <typename R> struct pixel_reference_is_mutable : public mpl::bool_<remove_reference<R>::type::is_mutable> {};
-template <typename T, typename L> struct pixel_reference_is_mutable< pixel<T,L>&> : public mpl::true_ {};
-template <typename T, typename L> struct pixel_reference_is_mutable<const pixel<T,L>&> : public mpl::false_ {};
-template <typename TR, typename Cs> struct pixel_reference_is_mutable< planar_pixel_reference<TR,Cs> > : public mpl::bool_< channel_traits<TR>::is_mutable > {};
-template <typename TR, typename Cs> struct pixel_reference_is_mutable<const planar_pixel_reference<TR,Cs> > : public mpl::bool_< channel_traits<TR>::is_mutable > {};
+template <typename R> struct pixel_reference_is_mutable : public mpl::bool_<remove_reference<R>::type::is_mutable> {};
+template <typename R> struct pixel_reference_is_mutable<const R&>
+ : public mpl::and_<pixel_reference_is_proxy<R>, pixel_reference_is_mutable<R> > {};
 
 /// \ingroup GILIsMutable
 /// \brief Determines if the given locator is mutable (i.e. its pixels can be changed)
@@ -174,10 +192,6 @@
 template <typename V> struct view_is_mutable : public iterator_is_mutable<typename V::x_iterator> {};
 
 
-/// \brief Determines if the given object is a GIL pixel reference (as opposed to a pixel value or anything else). Custom models of references must provide specializations.
-/// \ingroup TypeAnalysis
-template <typename R> struct is_pixel_reference : public pixel_reference_is_basic<R> {};
-
 //////////////////////////////////////////////////
 ///
 /// TYPE FACTORY METAFUNCTIONS
@@ -216,6 +230,9 @@
 template <typename Pixel> struct iterator_type_from_pixel<Pixel,true,false,false> {
     typedef planar_pixel_iterator<typename channel_traits<typename channel_type<Pixel>::type>::const_pointer,typename color_space_type<Pixel>::type> type;
 };
+template <typename Pixel, bool IsPlanar, bool IsMutable> struct iterator_type_from_pixel<Pixel,IsPlanar,true,IsMutable> {
+ typedef memory_based_step_iterator<typename iterator_type_from_pixel<Pixel,IsPlanar,false,IsMutable>::type> type;
+};
 
 /// \ingroup TypeFactoryFromElements
 /// \brief Returns the type of a homogeneous iterator given the channel type, layout, whether it operates on planar data, whether it is a step iterator, and whether it is mutable
@@ -225,18 +242,159 @@
 template <typename T, typename L> struct iterator_type<T,L,true,false,true> { typedef planar_pixel_iterator<T*,typename L::color_space_t> type; }; // TODO: Assert M=identity
 template <typename T, typename L> struct iterator_type<T,L,true,false,false> { typedef planar_pixel_iterator<const T*,typename L::color_space_t> type; }; // TODO: Assert M=identity
 template <typename T, typename L, bool IsPlanar, bool IsMutable> struct iterator_type<T,L,IsPlanar,true,IsMutable> {
- typedef byte_addressable_step_iterator<typename iterator_type<T,L,IsPlanar,false,IsMutable>::type> type;
+ typedef memory_based_step_iterator<typename iterator_type<T,L,IsPlanar,false,IsMutable>::type> type;
 };
 
 /// \brief Given a pixel iterator defining access to pixels along a row, returns the types of the corresponding built-in step_iterator, xy_locator, image_view
 /// \ingroup TypeFactory
 template <typename XIterator>
 struct type_from_x_iterator {
- typedef byte_addressable_step_iterator<XIterator> step_iterator_t;
- typedef byte_addressable_2d_locator<step_iterator_t> xy_locator_t;
+ typedef memory_based_step_iterator<XIterator> step_iterator_t;
+ typedef memory_based_2d_locator<step_iterator_t> xy_locator_t;
     typedef image_view<xy_locator_t> view_t;
 };
 
+namespace detail {
+ template <typename BitField, typename FirstBit, typename NumBits>
+ struct packed_channel_reference_type {
+ typedef const packed_channel_reference<BitField,FirstBit::value,NumBits::value,true> type;
+ };
+
+ template <typename BitField, typename ChannelBitSizesVector>
+ class packed_channel_references_vector_type {
+ // If ChannelBitSizesVector is mpl::vector<int,7,7,2>
+ // Then first_bits_vector will be mpl::vector<int,0,7,14,16>
+ typedef typename mpl::accumulate<ChannelBitSizesVector, mpl::vector1<mpl::int_<0> >,
+ mpl::push_back<mpl::_1, mpl::plus<mpl::back<mpl::_1>, mpl::_2> > >::type first_bits_vector;
+ public:
+ typedef typename mpl::transform<typename mpl::pop_back<first_bits_vector>::type, ChannelBitSizesVector,
+ packed_channel_reference_type<BitField, mpl::_1,mpl::_2> >::type type;
+ };
+
+}
+
+/// \ingroup TypeFactoryFromElements
+/// \brief Returns the type of a packed pixel given its bitfield type, the bit size of its channels and its layout.
+///
+/// A packed pixel has channels that cover bit ranges but itself is byte aligned. RGB565 pixel is an example.
+///
+/// The size of ChannelBitSizeVector must equal the number of channels in the given layout
+/// The sum of bit sizes for all channels must be less than or equal to the number of bits in BitField (and cannot exceed 64).
+/// If it is less than the number of bits in BitField, the last bits will be unused.
+template <typename BitField, typename ChannelBitSizeVector, typename Layout>
+struct packed_pixel_type {
+ typedef packed_pixel<BitField, typename detail::packed_channel_references_vector_type<BitField,ChannelBitSizeVector>::type, Layout> type;
+};
+
+/// \defgroup TypeFactoryPacked packed_image_type,bit_aligned_image_type
+/// \ingroup TypeFactoryFromElements
+/// \brief Returns the type of an image whose channels are not byte-aligned.
+///
+/// A packed image is an image whose pixels are byte aligned, such as "rgb565". <br>
+/// A bit-aligned image is an image whose pixels are not byte aligned, such as "rgb222". <br>
+///
+/// The sum of the bit sizes of all channels cannot exceed 64.
+
+/// \ingroup TypeFactoryPacked
+/// \brief Returns the type of an interleaved packed image: an image whose channels may not be byte-aligned, but whose pixels are byte aligned.
+template <typename BitField, typename ChannelBitSizeVector, typename Layout, typename Alloc=std::allocator<unsigned char> >
+struct packed_image_type {
+ typedef image<typename packed_pixel_type<BitField,ChannelBitSizeVector,Layout>::type,false,Alloc> type;
+};
+
+/// \ingroup TypeFactoryPacked
+/// \brief Returns the type of a single-channel image given its bitfield type, the bit size of its channel and its layout
+template <typename BitField, unsigned Size1, typename Layout, typename Alloc=std::allocator<unsigned char> >
+struct packed_image1_type : public packed_image_type<BitField, mpl::vector1_c<unsigned, Size1>, Layout, Alloc> {};
+
+/// \ingroup TypeFactoryPacked
+/// \brief Returns the type of a two channel image given its bitfield type, the bit size of its channels and its layout
+template <typename BitField, unsigned Size1, unsigned Size2, typename Layout, typename Alloc=std::allocator<unsigned char> >
+struct packed_image2_type : public packed_image_type<BitField, mpl::vector2_c<unsigned, Size1, Size2>, Layout, Alloc> {};
+
+/// \ingroup TypeFactoryPacked
+/// \brief Returns the type of a three channel image given its bitfield type, the bit size of its channels and its layout
+template <typename BitField, unsigned Size1, unsigned Size2, unsigned Size3, typename Layout, typename Alloc=std::allocator<unsigned char> >
+struct packed_image3_type : public packed_image_type<BitField, mpl::vector3_c<unsigned, Size1, Size2, Size3>, Layout, Alloc> {};
+
+/// \ingroup TypeFactoryPacked
+/// \brief Returns the type of a four channel image given its bitfield type, the bit size of its channels and its layout
+template <typename BitField, unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, typename Layout, typename Alloc=std::allocator<unsigned char> >
+struct packed_image4_type : public packed_image_type<BitField, mpl::vector4_c<unsigned, Size1, Size2, Size3, Size4>, Layout, Alloc> {};
+
+/// \ingroup TypeFactoryPacked
+/// \brief Returns the type of a five channel image given its bitfield type, the bit size of its channels and its layout
+template <typename BitField, unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, unsigned Size5, typename Layout, typename Alloc=std::allocator<unsigned char> >
+struct packed_image5_type : public packed_image_type<BitField, mpl::vector5_c<unsigned, Size1, Size2, Size3, Size4, Size5>, Layout, Alloc> {};
+
+
+/// \ingroup TypeFactoryPacked
+/// \brief Returns the type of a packed image whose pixels may not be byte aligned. For example, an "rgb222" image is bit-aligned because its pixel spans six bits.
+///
+/// Note that the alignment parameter in the constructor of bit-aligned images is in bit units. For example, if you want to construct a bit-aligned
+/// image whose rows are byte-aligned, use 8 as the alignment parameter, not 1.
+
+template <typename ChannelBitSizeVector, typename Layout, typename Alloc=std::allocator<unsigned char> >
+struct bit_aligned_image_type {
+private:
+ typedef const bit_aligned_pixel_reference<ChannelBitSizeVector, Layout, true> bit_alignedref_t;
+public:
+ typedef image<bit_alignedref_t,false,Alloc> type;
+};
+
+/// \ingroup TypeFactoryPacked
+/// \brief Returns the type of a single-channel bit-aligned image given the bit size of its channel and its layout
+template <unsigned Size1, typename Layout, typename Alloc=std::allocator<unsigned char> >
+struct bit_aligned_image1_type : public bit_aligned_image_type<mpl::vector1_c<unsigned, Size1>, Layout, Alloc> {};
+
+/// \ingroup TypeFactoryPacked
+/// \brief Returns the type of a two channel bit-aligned image given the bit size of its channels and its layout
+template <unsigned Size1, unsigned Size2, typename Layout, typename Alloc=std::allocator<unsigned char> >
+struct bit_aligned_image2_type : public bit_aligned_image_type<mpl::vector2_c<unsigned, Size1, Size2>, Layout, Alloc> {};
+
+/// \ingroup TypeFactoryPacked
+/// \brief Returns the type of a three channel bit-aligned image given the bit size of its channels and its layout
+template <unsigned Size1, unsigned Size2, unsigned Size3, typename Layout, typename Alloc=std::allocator<unsigned char> >
+struct bit_aligned_image3_type : public bit_aligned_image_type<mpl::vector3_c<unsigned, Size1, Size2, Size3>, Layout, Alloc> {};
+
+/// \ingroup TypeFactoryPacked
+/// \brief Returns the type of a four channel bit-aligned image given the bit size of its channels and its layout
+template <unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, typename Layout, typename Alloc=std::allocator<unsigned char> >
+struct bit_aligned_image4_type : public bit_aligned_image_type<mpl::vector4_c<unsigned, Size1, Size2, Size3, Size4>, Layout, Alloc> {};
+
+/// \ingroup TypeFactoryPacked
+/// \brief Returns the type of a five channel bit-aligned image given the bit size of its channels and its layout
+template <unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, unsigned Size5, typename Layout, typename Alloc=std::allocator<unsigned char> >
+struct bit_aligned_image5_type : public bit_aligned_image_type<mpl::vector5_c<unsigned, Size1, Size2, Size3, Size4, Size5>, Layout, Alloc> {};
+
+
+
+/// \ingroup TypeFactoryFromElements
+/// \brief Returns the type of a homogeneous pixel given the channel type and layout
+template <typename Channel, typename Layout>
+struct pixel_value_type {
+ typedef pixel<Channel,Layout> type; // by default use gil::pixel. Specializations are provided for
+};
+
+// Specializations for packed channels
+template <typename BitField, int NumBits, bool IsMutable, typename Layout>
+struct pixel_value_type< packed_dynamic_channel_reference<BitField,NumBits,IsMutable>,Layout> :
+ public packed_pixel_type<BitField, mpl::vector1_c<unsigned,NumBits>, Layout> {};
+template <typename BitField, int NumBits, bool IsMutable, typename Layout>
+struct pixel_value_type<const packed_dynamic_channel_reference<BitField,NumBits,IsMutable>,Layout> :
+ public packed_pixel_type<BitField, mpl::vector1_c<unsigned,NumBits>, Layout> {};
+
+template <typename BitField, int FirstBit, int NumBits, bool IsMutable, typename Layout>
+struct pixel_value_type< packed_channel_reference<BitField,FirstBit,NumBits,IsMutable>,Layout> :
+ public packed_pixel_type<BitField, mpl::vector1_c<unsigned,NumBits>, Layout> {};
+template <typename BitField, int FirstBit, int NumBits, bool IsMutable, typename Layout>
+struct pixel_value_type<const packed_channel_reference<BitField,FirstBit,NumBits,IsMutable>,Layout> :
+ public packed_pixel_type<BitField, mpl::vector1_c<unsigned,NumBits>, Layout> {};
+
+template <int NumBits, typename Layout>
+struct pixel_value_type<packed_channel_value<NumBits>,Layout> :
+ public packed_pixel_type<typename detail::min_fast_uint<NumBits>::type, mpl::vector1_c<unsigned,NumBits>, Layout> {};
+
 
 /// \ingroup TypeFactoryFromElements
 /// \brief Returns the type of a homogeneous locator given the channel type, layout, whether it operates on planar data and whether it has a step horizontally

Modified: trunk/boost/gil/packed_pixel.hpp
==============================================================================
--- trunk/boost/gil/packed_pixel.hpp (original)
+++ trunk/boost/gil/packed_pixel.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -31,91 +31,140 @@
 
 namespace boost { namespace gil {
 
-/// \defgroup ColorBaseModelPackedPixel heterogeneous_packed_pixel
+/// \defgroup ColorBaseModelPackedPixel packed_pixel
 /// \ingroup ColorBaseModel
 /// \brief A heterogeneous color base whose elements are reference proxies to channels in a pixel. Models ColorBaseValueConcept. This class is used to model packed pixels, such as 16-bit packed RGB.
 
-/// \defgroup PixelModelPackedPixel heterogeneous_packed_pixel
-/// \ingroup PixelModel
-/// \brief A heterogeneous pixel used to represent packed pixels with non-byte-aligned channels. Models PixelValueConcept
+/**
+\defgroup PixelModelPackedPixel packed_pixel
+\ingroup PixelModel
+\brief A heterogeneous pixel used to represent packed pixels with non-byte-aligned channels. Models PixelValueConcept
+
+Example:
+\code
+typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,6,5>, rgb_layout_t>::type rgb565_pixel_t;
+BOOST_STATIC_ASSERT((sizeof(rgb565_pixel_t)==2));
+
+rgb565_pixel_t r565;
+get_color(r565,red_t()) = 31;
+get_color(r565,green_t()) = 63;
+get_color(r565,blue_t()) = 31;
+assert(r565 == rgb565_pixel_t((uint16_t)0xFFFF));
+\endcode
+*/
 
 /// \ingroup ColorBaseModelPackedPixel PixelModelPackedPixel PixelBasedModel
-/// \brief Heterogeneous pixel value whose channel references can be constructed from the pixel data and their index. Models ColorBaseValueConcept, PixelValueConcept, PixelBasedConcept
+/// \brief Heterogeneous pixel value whose channel references can be constructed from the pixel bitfield and their index. Models ColorBaseValueConcept, PixelValueConcept, PixelBasedConcept
 /// Typical use for this is a model of a packed pixel (like 565 RGB)
-template <typename PixelData, typename ChannelRefVec, typename Layout>
-struct heterogeneous_packed_pixel {
- PixelData _data;
-
- // required by ColorBaseConcept, MutableColorBaseConcept
- typedef Layout layout_t;
- template <int K> struct kth_element_type : public mpl::at_c<ChannelRefVec,K> {};
- template <int K> struct kth_element_reference_type : public mpl::at_c<ChannelRefVec,K> {};
- template <int K> struct kth_element_const_reference_type {
- typedef typename channel_traits<typename mpl::at_c<ChannelRefVec,K>::type>::const_reference type;
- };
-
- typedef heterogeneous_packed_pixel value_type;
- typedef value_type& reference;
- typedef const value_type& const_reference;
+template <typename BitField, // A type that holds the bits of the pixel. Typically an integral type, like boost::uint16_t
+ typename ChannelRefVec, // An MPL vector whose elements are packed channels. They must be constructible from BitField. GIL uses packed_channel_reference
+ typename Layout> // Layout defining the color space and ordering of the channels. Example value: rgb_layout_t
+struct packed_pixel {
+ BitField _bitfield;
+
+ typedef Layout layout_t;
+ typedef packed_pixel value_type;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
 
     BOOST_STATIC_CONSTANT(bool, is_mutable = channel_traits<typename mpl::front<ChannelRefVec>::type>::is_mutable);
 
- heterogeneous_packed_pixel(){}
- heterogeneous_packed_pixel(const PixelData& data) : _data(data) {}
+ packed_pixel(){}
+ explicit packed_pixel(const BitField& bitfield) : _bitfield(bitfield) {}
 
     // Construct from another compatible pixel type
- heterogeneous_packed_pixel(const heterogeneous_packed_pixel& p) : _data(p._data) {}
- template <typename P> heterogeneous_packed_pixel(const P& p) { check_compatible<P>(); static_copy(p,*this); }
+ packed_pixel(const packed_pixel& p) : _bitfield(p._bitfield) {}
+ template <typename P> packed_pixel(const P& p, typename enable_if_c<is_pixel<P>::value>::type* d=0) { check_compatible<P>(); static_copy(p,*this); }
+ packed_pixel(int chan0, int chan1) : _bitfield(0) {
+ BOOST_STATIC_ASSERT((num_channels<packed_pixel>::value==2));
+ at_c<0>(*this)=chan0; at_c<1>(*this)=chan1;
+ }
+ packed_pixel(int chan0, int chan1, int chan2) : _bitfield(0) {
+ BOOST_STATIC_ASSERT((num_channels<packed_pixel>::value==3));
+ at_c<0>(*this)=chan0; at_c<1>(*this)=chan1; at_c<2>(*this)=chan2;
+ }
+ packed_pixel(int chan0, int chan1, int chan2, int chan3) : _bitfield(0) {
+ BOOST_STATIC_ASSERT((num_channels<packed_pixel>::value==4));
+ at_c<0>(*this)=chan0; at_c<1>(*this)=chan1; at_c<2>(*this)=chan2; at_c<2>(*this)=chan3;
+ }
+ packed_pixel(int chan0, int chan1, int chan2, int chan3, int chan4) : _bitfield(0) {
+ BOOST_STATIC_ASSERT((num_channels<packed_pixel>::value==5));
+ at_c<0>(*this)=chan0; at_c<1>(*this)=chan1; at_c<2>(*this)=chan2; at_c<2>(*this)=chan3; at_c<3>(*this)=chan4;
+ }
 
- template <typename P> heterogeneous_packed_pixel& operator=(const P& p) { check_compatible<P>(); static_copy(p,*this); return *this; }
- heterogeneous_packed_pixel& operator=(const heterogeneous_packed_pixel& p) { _data=p._data; return *this; }
+ packed_pixel& operator=(const packed_pixel& p) { _bitfield=p._bitfield; return *this; }
 
- template <typename P> bool operator==(const P& p) const { check_compatible<P>(); return static_equal(*this,p); }
- template <typename P> bool operator!=(const P& p) const { return !(*this==p); }
+ template <typename P> packed_pixel& operator=(const P& p) { assign(p, mpl::bool_<is_pixel<P>::value>()); return *this; }
+ template <typename P> bool operator==(const P& p) const { return equal(p, mpl::bool_<is_pixel<P>::value>()); }
+
+ template <typename P> bool operator!=(const P& p) const { return !(*this==p); }
 
 private:
- template <typename Pixel> static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel,heterogeneous_packed_pixel> >(); }
+ template <typename Pixel> static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel,packed_pixel> >(); }
+ template <typename Pixel> void assign(const Pixel& p, mpl::true_) { check_compatible<Pixel>(); static_copy(p,*this); }
+ template <typename Pixel> bool equal(const Pixel& p, mpl::true_) const { check_compatible<Pixel>(); return static_equal(*this,p); }
+
+// Support for assignment/equality comparison of a channel with a grayscale pixel
+ static void check_gray() { BOOST_STATIC_ASSERT((is_same<typename Layout::color_space_t, gray_t>::value)); }
+ template <typename Channel> void assign(const Channel& chan, mpl::false_) { check_gray(); at_c<0>(*this)=chan; }
+ template <typename Channel> bool equal (const Channel& chan, mpl::false_) const { check_gray(); return at_c<0>(*this)==chan; }
+public:
+ packed_pixel& operator= (int chan) { check_gray(); at_c<0>(*this)=chan; return *this; }
+ bool operator==(int chan) const { check_gray(); return at_c<0>(*this)==chan; }
 };
 
-/// \brief Metafunction predicate that flags heterogeneous_packed_pixel as a model of PixelConcept. Required by PixelConcept
-/// \ingroup PixelModelPackedPixel
-template <typename PixelData, typename ChannelRefVec, typename Layout>
-struct is_pixel<heterogeneous_packed_pixel<PixelData,ChannelRefVec,Layout> > : public mpl::true_{};
+/////////////////////////////
+// ColorBasedConcept
+/////////////////////////////
+
+template <typename BitField, typename ChannelRefVec, typename Layout, int K>
+struct kth_element_type<packed_pixel<BitField,ChannelRefVec,Layout>,K> : public mpl::at_c<ChannelRefVec,K> {};
+
+template <typename BitField, typename ChannelRefVec, typename Layout, int K>
+struct kth_element_reference_type<packed_pixel<BitField,ChannelRefVec,Layout>,K> : public mpl::at_c<ChannelRefVec,K> {};
+
+template <typename BitField, typename ChannelRefVec, typename Layout, int K>
+struct kth_element_const_reference_type<packed_pixel<BitField,ChannelRefVec,Layout>,K> {
+ typedef typename channel_traits<typename mpl::at_c<ChannelRefVec,K>::type>::const_reference type;
+};
 
-/// \brief mutable at_c required by MutableColorBaseConcept
-/// \ingroup ColorBaseModelPackedPixel
 template <int K, typename P, typename C, typename L> inline
-typename heterogeneous_packed_pixel<P,C,L>::template kth_element_reference_type<K>::type
-at_c(heterogeneous_packed_pixel<P,C,L>& p) {
- return typename heterogeneous_packed_pixel<P,C,L>::template kth_element_reference_type<K>::type(p._data);
+typename kth_element_reference_type<packed_pixel<P,C,L>, K>::type
+at_c(packed_pixel<P,C,L>& p) {
+ return typename kth_element_reference_type<packed_pixel<P,C,L>, K>::type(&p._bitfield);
 }
 
-/// \brief constant at_c required by ColorBaseConcept
-/// \ingroup ColorBaseModelPackedPixel
 template <int K, typename P, typename C, typename L> inline
-typename heterogeneous_packed_pixel<P,C,L>::template kth_element_const_reference_type<K>::type
-at_c(const heterogeneous_packed_pixel<P,C,L>& p) {
- return typename heterogeneous_packed_pixel<P,C,L>::template kth_element_const_reference_type<K>::type(p._data);
+typename kth_element_const_reference_type<packed_pixel<P,C,L>, K>::type
+at_c(const packed_pixel<P,C,L>& p) {
+ return typename kth_element_const_reference_type<packed_pixel<P,C,L>, K>::type(&p._bitfield);
 }
 
-/// \brief Specifies the color space type of a heterogeneous packed pixel. Required by PixelBasedConcept
-/// \ingroup PixelModelPackedPixel
+/////////////////////////////
+// PixelConcept
+/////////////////////////////
+
+// Metafunction predicate that flags packed_pixel as a model of PixelConcept. Required by PixelConcept
+template <typename BitField, typename ChannelRefVec, typename Layout>
+struct is_pixel<packed_pixel<BitField,ChannelRefVec,Layout> > : public mpl::true_{};
+
+/////////////////////////////
+// PixelBasedConcept
+/////////////////////////////
+
 template <typename P, typename C, typename Layout>
-struct color_space_type<heterogeneous_packed_pixel<P,C,Layout> > {
+struct color_space_type<packed_pixel<P,C,Layout> > {
     typedef typename Layout::color_space_t type;
 };
 
-/// \brief Specifies the channel mapping of a heterogeneous packed pixel. Required by PixelBasedConcept
-/// \ingroup PixelModelPackedPixel
 template <typename P, typename C, typename Layout>
-struct channel_mapping_type<heterogeneous_packed_pixel<P,C,Layout> > {
+struct channel_mapping_type<packed_pixel<P,C,Layout> > {
     typedef typename Layout::channel_mapping_t type;
 };
 
-/// \brief Specifies that the heterogeneous packed pixel is not planar. Required by PixelBasedConcept
-/// \ingroup PixelModelPackedPixel
 template <typename P, typename C, typename Layout>
-struct is_planar<heterogeneous_packed_pixel<P,C,Layout> > : mpl::false_ {};
+struct is_planar<packed_pixel<P,C,Layout> > : mpl::false_ {};
+
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
@@ -123,61 +172,22 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 
-/// \defgroup PixelIteratorModelPackedInterleavedPtr Pointer to heterogeneous_packed_pixel<P,CR,Layout>
+/// \defgroup PixelIteratorModelPackedInterleavedPtr Pointer to packed_pixel<P,CR,Layout>
 /// \ingroup PixelIteratorModel
 /// \brief Iterators over interleaved pixels.
-/// The pointer heterogeneous_packed_pixel<P,CR,Layout>* is used as an iterator over interleaved pixels of packed format. Models PixelIteratorConcept, HasDynamicXStepTypeConcept, ByteAdvanceableIteratorConcept
+/// The pointer packed_pixel<P,CR,Layout>* is used as an iterator over interleaved pixels of packed format. Models PixelIteratorConcept, HasDynamicXStepTypeConcept, MemoryBasedIteratorConcept
 
 template <typename P, typename C, typename L>
-struct iterator_is_mutable<heterogeneous_packed_pixel<P,C,L>*> : public mpl::bool_<heterogeneous_packed_pixel<P,C,L>::is_mutable> {};
+struct iterator_is_mutable<packed_pixel<P,C,L>*> : public mpl::bool_<packed_pixel<P,C,L>::is_mutable> {};
 template <typename P, typename C, typename L>
-struct iterator_is_mutable<const heterogeneous_packed_pixel<P,C,L>*> : public mpl::false_ {};
-
-/////////////////////////////
-// HasDynamicXStepTypeConcept
-/////////////////////////////
-
-/// \ingroup PixelIteratorModelPackedInterleavedPtr
-template <typename P, typename C, typename L>
-struct dynamic_x_step_type<heterogeneous_packed_pixel<P,C,L>*> {
- typedef byte_addressable_step_iterator<heterogeneous_packed_pixel<P,C,L>*> type;
-};
-
-/// \ingroup PixelIteratorModelPackedInterleavedPtr
-template <typename P, typename C, typename L>
-struct dynamic_x_step_type<const heterogeneous_packed_pixel<P,C,L>*> {
- typedef byte_addressable_step_iterator<const heterogeneous_packed_pixel<P,C,L>*> type;
-};
-
-
-/////////////////////////////
-// PixelBasedConcept
-/////////////////////////////
-
-template <typename P, typename C, typename L>
-struct color_space_type<heterogeneous_packed_pixel<P,C,L>*> : public color_space_type<heterogeneous_packed_pixel<P,C,L> > {};
-
-template <typename P, typename C, typename L>
-struct channel_mapping_type<heterogeneous_packed_pixel<P,C,L>*> : public channel_mapping_type<heterogeneous_packed_pixel<P,C,L> > {};
-
-template <typename P, typename C, typename L>
-struct is_planar<heterogeneous_packed_pixel<P,C,L>*> : public is_planar<heterogeneous_packed_pixel<P,C,L> > {};
-
-
-template <typename P, typename C, typename L>
-struct color_space_type<const heterogeneous_packed_pixel<P,C,L>*> : public color_space_type<heterogeneous_packed_pixel<P,C,L> > {};
-
-template <typename P, typename C, typename L>
-struct channel_mapping_type<const heterogeneous_packed_pixel<P,C,L>*> : public channel_mapping_type<heterogeneous_packed_pixel<P,C,L> > {};
+struct iterator_is_mutable<const packed_pixel<P,C,L>*> : public mpl::false_ {};
 
-template <typename P, typename C, typename L>
-struct is_planar<const heterogeneous_packed_pixel<P,C,L>*> : public is_planar<heterogeneous_packed_pixel<P,C,L> > {};
 
 
 } } // namespace boost::gil
 
 namespace boost {
     template <typename P, typename C, typename L>
- struct has_trivial_constructor<gil::heterogeneous_packed_pixel<P,C,L> > : public has_trivial_constructor<P> {};
+ struct has_trivial_constructor<gil::packed_pixel<P,C,L> > : public has_trivial_constructor<P> {};
 }
 #endif

Modified: trunk/boost/gil/pixel.hpp
==============================================================================
--- trunk/boost/gil/pixel.hpp (original)
+++ trunk/boost/gil/pixel.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -58,6 +58,22 @@
 template <typename PixelBased>
 struct num_channels : public mpl::size<typename color_space_type<PixelBased>::type> {};
 
+/**
+\addtogroup PixelBasedAlgorithm
+
+Example:
+\code
+BOOST_STATIC_ASSERT((num_channels<rgb8_view_t>::value==3));
+BOOST_STATIC_ASSERT((num_channels<cmyk16_planar_ptr_t>::value==4));
+
+BOOST_STATIC_ASSERT((is_planar<rgb16_planar_image_t>::value));
+BOOST_STATIC_ASSERT((is_same<color_space_type<rgb8_planar_ref_t>::type, rgb_t>::value));
+BOOST_STATIC_ASSERT((is_same<channel_mapping_type<cmyk8_pixel_t>::type,
+ channel_mapping_type<rgba8_pixel_t>::type>::value));
+BOOST_STATIC_ASSERT((is_same<channel_type<bgr8_pixel_t>::type, bits8>::value));
+\endcode
+*/
+
 /// \defgroup ColorBaseModelPixel pixel
 /// \ingroup ColorBaseModel
 /// \brief A homogeneous color base whose element is a channel value. Models HomogeneousColorBaseValueConcept
@@ -134,8 +150,34 @@
     bool operator==(channel_t chan) const { check_gray(); return at_c<0>(*this)==chan; }
 };
 
-/// \brief Metafunction predicate that flags pixel as a model of PixelConcept. Required by PixelConcept
-/// \ingroup PixelModelPixel
+/////////////////////////////
+// ColorBasedConcept
+/////////////////////////////
+
+template <typename ChannelValue, typename Layout, int K>
+struct kth_element_type<pixel<ChannelValue,Layout>, K> {
+ typedef ChannelValue type;
+};
+
+template <typename ChannelValue, typename Layout, int K>
+struct kth_element_reference_type<pixel<ChannelValue,Layout>, K> {
+ typedef typename channel_traits<ChannelValue>::reference type;
+};
+
+template <typename ChannelValue, typename Layout, int K>
+struct kth_element_reference_type<const pixel<ChannelValue,Layout>, K> {
+ typedef typename channel_traits<ChannelValue>::const_reference type;
+};
+
+template <typename ChannelValue, typename Layout, int K>
+struct kth_element_const_reference_type<pixel<ChannelValue,Layout>, K> {
+ typedef typename channel_traits<ChannelValue>::const_reference type;
+};
+
+/////////////////////////////
+// PixelConcept
+/////////////////////////////
+
 template <typename ChannelValue, typename Layout>
 struct is_pixel<pixel<ChannelValue,Layout> > : public mpl::true_{};
 

Modified: trunk/boost/gil/pixel_iterator.hpp
==============================================================================
--- trunk/boost/gil/pixel_iterator.hpp (original)
+++ trunk/boost/gil/pixel_iterator.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -32,7 +32,7 @@
 
 //forwarded declaration (as this file is included in step_iterator.hpp)
 template <typename Iterator>
-class byte_addressable_step_iterator;
+class memory_based_step_iterator;
 
 template <typename Iterator> struct dynamic_x_step_type;
 
@@ -66,10 +66,10 @@
 template <typename T> struct iterator_is_mutable< T*> : public mpl::true_{};
 template <typename T> struct iterator_is_mutable<const T*> : public mpl::false_{};
 
-/// \defgroup PixelIteratorModelInterleavedPtr Pointer to pixel<ChannelValue,Layout>
+/// \defgroup PixelIteratorModelInterleavedPtr C pointer to a pixel
 /// \ingroup PixelIteratorModel
 /// \brief Iterators over interleaved pixels.
-/// The pointer pixel<ChannelValue,Layout>* is used as an iterator over interleaved pixels. Models PixelIteratorConcept, HomogeneousPixelBasedConcept, HasDynamicXStepTypeConcept, ByteAdvanceableIteratorConcept
+/// A C pointer to a model of PixelValueConcept is used as an iterator over interleaved pixels. Models PixelIteratorConcept, HomogeneousPixelBasedConcept, HasDynamicXStepTypeConcept, MemoryBasedIteratorConcept
 
 
 
@@ -78,15 +78,15 @@
 /////////////////////////////
 
 /// \ingroup PixelIteratorModelInterleavedPtr
-template <typename T, typename L>
-struct dynamic_x_step_type<pixel<T,L>*> {
- typedef byte_addressable_step_iterator<pixel<T,L>*> type;
+template <typename Pixel>
+struct dynamic_x_step_type<Pixel*> {
+ typedef memory_based_step_iterator<Pixel*> type;
 };
 
 /// \ingroup PixelIteratorModelInterleavedPtr
-template <typename T, typename L>
-struct dynamic_x_step_type<const pixel<T,L>*> {
- typedef byte_addressable_step_iterator<const pixel<T,L>*> type;
+template <typename Pixel>
+struct dynamic_x_step_type<const Pixel*> {
+ typedef memory_based_step_iterator<const Pixel*> type;
 };
 
 
@@ -94,71 +94,63 @@
 // PixelBasedConcept
 /////////////////////////////
 
-template <typename T, typename L>
-struct color_space_type<pixel<T,L>*> {
- typedef typename L::color_space_t type;
-};
+template <typename Pixel> struct color_space_type< Pixel*> : public color_space_type<Pixel> {};
+template <typename Pixel> struct color_space_type<const Pixel*> : public color_space_type<Pixel> {};
 
-template <typename T, typename L>
-struct channel_mapping_type<pixel<T,L>*> {
- typedef typename L::channel_mapping_t type;
-};
+template <typename Pixel> struct channel_mapping_type< Pixel*> : public channel_mapping_type<Pixel> {};
+template <typename Pixel> struct channel_mapping_type<const Pixel*> : public channel_mapping_type<Pixel> {};
 
-template <typename T, typename L>
-struct is_planar<pixel<T,L>*> : public mpl::false_ {};
+template <typename Pixel> struct is_planar< Pixel*> : public is_planar<Pixel> {};
+template <typename Pixel> struct is_planar<const Pixel*> : public is_planar<Pixel> {};
 
 /////////////////////////////
 // HomogeneousPixelBasedConcept
 /////////////////////////////
 
-template <typename T, typename L>
-struct channel_type<pixel<T,L>*> {
- typedef T type;
-};
-
-template <typename T, typename L> struct color_space_type<const pixel<T,L>*> : public color_space_type<pixel<T,L>*> {};
-template <typename T, typename L> struct channel_mapping_type<const pixel<T,L>*> : public channel_mapping_type<pixel<T,L>*> {};
-template <typename T, typename L> struct is_planar<const pixel<T,L>*> : public is_planar<pixel<T,L>*> {};
-template <typename T, typename L> struct channel_type<const pixel<T,L>*> : public channel_type<pixel<T,L>*> {};
+template <typename Pixel> struct channel_type<Pixel*> : public channel_type<Pixel> {};
+template <typename Pixel> struct channel_type<const Pixel*> : public channel_type<Pixel> {};
 
 ////////////////////////////////////////////////////////////////////////////////////////
 ///
-/// Support for pixel iterator movement measured in raw bytes (as opposed to pixel type). \n
+/// Support for pixel iterator movement measured in memory units (bytes or bits) as opposed to pixel type. \n
 /// Necessary to handle image row alignment and channel plane alignment.
 ///
 ////////////////////////////////////////////////////////////////////////////////////////
 
 /////////////////////////////
-// ByteAdvanceableIteratorConcept
+// MemoryBasedIteratorConcept
 /////////////////////////////
 
+template <typename T>
+struct byte_to_memunit : public mpl::int_<1> {};
+
 template <typename P>
-inline std::ptrdiff_t byte_step(const P*) { return sizeof(P); }
+inline std::ptrdiff_t memunit_step(const P*) { return sizeof(P); }
 
 template <typename P>
-inline std::ptrdiff_t byte_distance(const P* p1, const P* p2) {
+inline std::ptrdiff_t memunit_distance(const P* p1, const P* p2) {
     return (gil_reinterpret_cast_c<const unsigned char*>(p2)-gil_reinterpret_cast_c<const unsigned char*>(p1));
 }
 
-template <typename P> P* byte_advanced(const P* p, std::ptrdiff_t byteDiff);
+template <typename P> P* memunit_advanced(const P* p, std::ptrdiff_t diff);
 
 template <typename P>
-inline void byte_advance(P* &p, std::ptrdiff_t byteDiff) {
- p=(P*)((unsigned char*)(p)+byteDiff);
+inline void memunit_advance(P* &p, std::ptrdiff_t diff) {
+ p=(P*)((unsigned char*)(p)+diff);
 }
 
 template <typename P>
-inline P* byte_advanced(const P* p, std::ptrdiff_t byteDiff) {
- return (P*)((unsigned char*)(p)+byteDiff);
+inline P* memunit_advanced(const P* p, std::ptrdiff_t diff) {
+ return (P*)((unsigned char*)(p)+diff);
 }
 
 
-// byte_advanced_ref
-// (shortcut to advancing a pointer by a given number of bytes and taking the reference in case the compiler is not smart enough)
+// memunit_advanced_ref
+// (shortcut to advancing a pointer by a given number of memunits and taking the reference in case the compiler is not smart enough)
 
 template <typename P>
-inline P& byte_advanced_ref(P* p, std::ptrdiff_t byteDiff) {
- return *byte_advanced(p,byteDiff);
+inline P& memunit_advanced_ref(P* p, std::ptrdiff_t diff) {
+ return *memunit_advanced(p,diff);
 }
 
 } } // namespace boost::gil

Modified: trunk/boost/gil/pixel_iterator_adaptor.hpp
==============================================================================
--- trunk/boost/gil/pixel_iterator_adaptor.hpp (original)
+++ trunk/boost/gil/pixel_iterator_adaptor.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -129,42 +129,45 @@
 
 
 /////////////////////////////
-// ByteAdvanceableIteratorConcept
+// MemoryBasedIteratorConcept
 /////////////////////////////
 
 template <typename Iterator, typename DFn>
+struct byte_to_memunit<dereference_iterator_adaptor<Iterator,DFn> > : public byte_to_memunit<Iterator> {};
+
+template <typename Iterator, typename DFn>
 inline typename std::iterator_traits<Iterator>::difference_type
-byte_step(const dereference_iterator_adaptor<Iterator,DFn>& p) {
- return byte_step(p.base());
+memunit_step(const dereference_iterator_adaptor<Iterator,DFn>& p) {
+ return memunit_step(p.base());
 }
 
 template <typename Iterator, typename DFn>
 inline typename std::iterator_traits<Iterator>::difference_type
-byte_distance(const dereference_iterator_adaptor<Iterator,DFn>& p1,
+memunit_distance(const dereference_iterator_adaptor<Iterator,DFn>& p1,
               const dereference_iterator_adaptor<Iterator,DFn>& p2) {
- return byte_distance(p1.base(),p2.base());
+ return memunit_distance(p1.base(),p2.base());
 }
 
 template <typename Iterator, typename DFn>
-inline void byte_advance(dereference_iterator_adaptor<Iterator,DFn>& p,
- typename std::iterator_traits<Iterator>::difference_type byteDiff) {
- byte_advance(p.base(), byteDiff);
+inline void memunit_advance(dereference_iterator_adaptor<Iterator,DFn>& p,
+ typename std::iterator_traits<Iterator>::difference_type diff) {
+ memunit_advance(p.base(), diff);
 }
 
 template <typename Iterator, typename DFn>
 inline dereference_iterator_adaptor<Iterator,DFn>
-byte_advanced(const dereference_iterator_adaptor<Iterator,DFn>& p,
- typename std::iterator_traits<Iterator>::difference_type byteDiff) {
- return dereference_iterator_adaptor<Iterator,DFn>(byte_advanced(p.base(), byteDiff), p.deref_fn());
+memunit_advanced(const dereference_iterator_adaptor<Iterator,DFn>& p,
+ typename std::iterator_traits<Iterator>::difference_type diff) {
+ return dereference_iterator_adaptor<Iterator,DFn>(memunit_advanced(p.base(), diff), p.deref_fn());
 }
 
 
 template <typename Iterator, typename DFn>
 inline
 typename std::iterator_traits<dereference_iterator_adaptor<Iterator,DFn> >::reference
-byte_advanced_ref(const dereference_iterator_adaptor<Iterator,DFn>& p,
- typename std::iterator_traits<Iterator>::difference_type byteDiff) {
- return *byte_advanced(p, byteDiff);
+memunit_advanced_ref(const dereference_iterator_adaptor<Iterator,DFn>& p,
+ typename std::iterator_traits<Iterator>::difference_type diff) {
+ return *memunit_advanced(p, diff);
 }
 
 /////////////////////////////
@@ -180,7 +183,7 @@
 /// \ingroup PixelIteratorModelDerefPtr
 template <typename Iterator, typename Deref>
 struct iterator_add_deref {
- GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept);
+ GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept)
 
     typedef dereference_iterator_adaptor<Iterator, Deref> type;
 
@@ -191,7 +194,7 @@
 /// \brief For dereference iterator adaptors, compose the new function object after the old one
 template <typename Iterator, typename PREV_DEREF, typename Deref>
 struct iterator_add_deref<dereference_iterator_adaptor<Iterator, PREV_DEREF>,Deref> {
- GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept);
+// GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept)
 
     typedef dereference_iterator_adaptor<Iterator, deref_compose<Deref,PREV_DEREF> > type;
 

Modified: trunk/boost/gil/planar_pixel_iterator.hpp
==============================================================================
--- trunk/boost/gil/planar_pixel_iterator.hpp (original)
+++ trunk/boost/gil/planar_pixel_iterator.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -42,10 +42,10 @@
 
 /// \defgroup PixelIteratorModelPlanarPtr planar_pixel_iterator
 /// \ingroup PixelIteratorModel
-/// \brief An iterator over planar pixels. Models PixelIteratorConcept, HomogeneousPixelBasedConcept, ByteAdvanceableIteratorConcept, HasDynamicXStepTypeConcept
+/// \brief An iterator over planar pixels. Models PixelIteratorConcept, HomogeneousPixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept
 
 ////////////////////////////////////////////////////////////////////////////////////////
-/// \brief An iterator over planar pixels. Models HomogeneousColorBaseConcept, PixelIteratorConcept, HomogeneousPixelBasedConcept, ByteAdvanceableIteratorConcept, HasDynamicXStepTypeConcept
+/// \brief An iterator over planar pixels. Models HomogeneousColorBaseConcept, PixelIteratorConcept, HomogeneousPixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept
 ///
 /// Planar pixels have channel data that is not consecutive in memory.
 /// To abstract this we use classes to represent references and pointers to planar pixels.
@@ -104,7 +104,7 @@
 
     /// For some reason operator[] provided by iterator_facade returns a custom class that is convertible to reference
     /// We require our own reference because it is registered in iterator_traits
- reference operator[](difference_type d) const { return byte_advanced_ref(*this,d*sizeof(channel_t));}
+ reference operator[](difference_type d) const { return memunit_advanced_ref(*this,d*sizeof(channel_t));}
 
     reference operator->() const { return **this; }
 
@@ -141,6 +141,21 @@
 struct iterator_is_mutable<planar_pixel_iterator<IC,C> > : public detail::channel_iterator_is_mutable<IC> {};
 
 /////////////////////////////
+// ColorBasedConcept
+/////////////////////////////
+
+template <typename IC, typename C, int K>
+struct kth_element_type<planar_pixel_iterator<IC,C>, K> {
+ typedef IC type;
+};
+
+template <typename IC, typename C, int K>
+struct kth_element_reference_type<planar_pixel_iterator<IC,C>, K> : public add_reference<IC> {};
+
+template <typename IC, typename C, int K>
+struct kth_element_const_reference_type<planar_pixel_iterator<IC,C>, K> : public add_reference<typename add_const<IC>::type> {};
+
+/////////////////////////////
 // HomogeneousPixelBasedConcept
 /////////////////////////////
 
@@ -161,41 +176,40 @@
 };
 
 /////////////////////////////
-// ByteAdvanceableIteratorConcept
+// MemoryBasedIteratorConcept
 /////////////////////////////
 
 template <typename IC, typename C>
-inline std::ptrdiff_t byte_step(const planar_pixel_iterator<IC,C>&) { return sizeof(typename std::iterator_traits<IC>::value_type); }
+inline std::ptrdiff_t memunit_step(const planar_pixel_iterator<IC,C>&) { return sizeof(typename std::iterator_traits<IC>::value_type); }
 
 template <typename IC, typename C>
-inline std::ptrdiff_t byte_distance(const planar_pixel_iterator<IC,C>& p1, const planar_pixel_iterator<IC,C>& p2) {
- return byte_distance(at_c<0>(p1),at_c<0>(p2));
+inline std::ptrdiff_t memunit_distance(const planar_pixel_iterator<IC,C>& p1, const planar_pixel_iterator<IC,C>& p2) {
+ return memunit_distance(at_c<0>(p1),at_c<0>(p2));
 }
 
 template <typename IC>
-struct byte_advance_fn {
- byte_advance_fn(std::ptrdiff_t byte_diff) : _byte_diff(byte_diff) {}
- IC operator()(const IC& p) const { return byte_advanced(p,_byte_diff); }
+struct memunit_advance_fn {
+ memunit_advance_fn(std::ptrdiff_t diff) : _diff(diff) {}
+ IC operator()(const IC& p) const { return memunit_advanced(p,_diff); }
 
- std::ptrdiff_t _byte_diff;
+ std::ptrdiff_t _diff;
 };
 
 template <typename IC, typename C>
-inline void byte_advance(planar_pixel_iterator<IC,C>& p, std::ptrdiff_t byte_diff) {
- static_transform(p, p, byte_advance_fn<IC>(byte_diff));
+inline void memunit_advance(planar_pixel_iterator<IC,C>& p, std::ptrdiff_t diff) {
+ static_transform(p, p, memunit_advance_fn<IC>(diff));
 }
 
 template <typename IC, typename C>
-inline planar_pixel_iterator<IC,C> byte_advanced(const planar_pixel_iterator<IC,C>& p, std::ptrdiff_t byteDiff) {
+inline planar_pixel_iterator<IC,C> memunit_advanced(const planar_pixel_iterator<IC,C>& p, std::ptrdiff_t diff) {
     planar_pixel_iterator<IC,C> ret=p;
- byte_advance(ret, byteDiff);
+ memunit_advance(ret, diff);
     return ret;
 }
 
-// Advancing a planar pixel iterator by a given number of bytes and taking the reference
 template <typename ChannelPtr, typename ColorSpace>
 inline planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace>
- byte_advanced_ref(const planar_pixel_iterator<ChannelPtr,ColorSpace>& ptr, std::ptrdiff_t diff) {
+ memunit_advanced_ref(const planar_pixel_iterator<ChannelPtr,ColorSpace>& ptr, std::ptrdiff_t diff) {
     return planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace>(ptr, diff);
 }
 
@@ -205,7 +219,7 @@
 
 template <typename IC, typename C>
 struct dynamic_x_step_type<planar_pixel_iterator<IC,C> > {
- typedef byte_addressable_step_iterator<planar_pixel_iterator<IC,C> > type;
+ typedef memory_based_step_iterator<planar_pixel_iterator<IC,C> > type;
 };
 
 } } // namespace boost::gil

Modified: trunk/boost/gil/planar_pixel_reference.hpp
==============================================================================
--- trunk/boost/gil/planar_pixel_reference.hpp (original)
+++ trunk/boost/gil/planar_pixel_reference.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -89,11 +89,40 @@
     template <typename Pixel> static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel,planar_pixel_reference> >(); }
 };
 
+/////////////////////////////
+// ColorBasedConcept
+/////////////////////////////
+
+template <typename ChannelReference, typename ColorSpace, int K>
+struct kth_element_type<planar_pixel_reference<ChannelReference,ColorSpace>, K> {
+ typedef ChannelReference type;
+};
+
+template <typename ChannelReference, typename ColorSpace, int K>
+struct kth_element_reference_type<planar_pixel_reference<ChannelReference,ColorSpace>, K> {
+ typedef ChannelReference type;
+};
+
+template <typename ChannelReference, typename ColorSpace, int K>
+struct kth_element_const_reference_type<planar_pixel_reference<ChannelReference,ColorSpace>, K>
+ : public add_reference<typename add_const<ChannelReference>::type>
+{
+// typedef typename channel_traits<ChannelReference>::const_reference type;
+};
+
+/////////////////////////////
+// PixelConcept
+/////////////////////////////
+
 /// \brief Metafunction predicate that flags planar_pixel_reference as a model of PixelConcept. Required by PixelConcept
 /// \ingroup PixelModelPlanarRef
 template <typename ChannelReference, typename ColorSpace>
 struct is_pixel< planar_pixel_reference<ChannelReference,ColorSpace> > : public mpl::true_{};
 
+/////////////////////////////
+// HomogeneousPixelBasedConcept
+/////////////////////////////
+
 /// \brief Specifies the color space type of a planar pixel reference. Required by PixelBasedConcept
 /// \ingroup PixelModelPlanarRef
 template <typename ChannelReference, typename ColorSpace>

Modified: trunk/boost/gil/position_iterator.hpp
==============================================================================
--- trunk/boost/gil/position_iterator.hpp (original)
+++ trunk/boost/gil/position_iterator.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -78,7 +78,7 @@
     void decrement() { _p[Dim]-=_step[Dim]; }
     void advance(difference_type d) { _p[Dim]+=d*_step[Dim]; }
 
- ptrdiff_t distance_to(const position_iterator& it) const { return (it._p[Dim]-_p[Dim])/_step[Dim]; }
+ difference_type distance_to(const position_iterator& it) const { return (it._p[Dim]-_p[Dim])/_step[Dim]; }
     bool equal(const position_iterator& it) const { return _p==it._p; }
 };
 

Modified: trunk/boost/gil/step_iterator.hpp
==============================================================================
--- trunk/boost/gil/step_iterator.hpp (original)
+++ trunk/boost/gil/step_iterator.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -108,15 +108,15 @@
 } // namespace detail
 
 ////////////////////////////////////////////////////////////////////////////////////////
-/// BYTE-ADDRESSABLE STEP ITERATOR
+/// MEMORY-BASED STEP ITERATOR
 ////////////////////////////////////////////////////////////////////////////////////////
 
-/// \class byte_addressable_step_iterator
+/// \class memory_based_step_iterator
 /// \ingroup PixelIteratorModelStepPtr PixelBasedModel
-/// \brief Iterator with dynamically specified step in bytes. Models StepIteratorConcept, IteratorAdaptorConcept, ByteAdvanceableIteratorConcept, PixelIteratorConcept, HasDynamicXStepTypeConcept
+/// \brief Iterator with dynamically specified step in memory units (bytes or bits). Models StepIteratorConcept, IteratorAdaptorConcept, MemoryBasedIteratorConcept, PixelIteratorConcept, HasDynamicXStepTypeConcept
 ///
 /// A refinement of step_iterator_adaptor that uses a dynamic parameter for the step
-/// which is specified in bytes
+/// which is specified in memory units, such as bytes or bits
 ///
 /// Pixel step iterators are used to provide iteration over non-adjacent pixels.
 /// Common use is a vertical traversal, where the step is the row stride.
@@ -128,59 +128,59 @@
 ////////////////////////////////////////////////////////////////////////////////////////
 
 /// \ingroup PixelIteratorModelStepPtr
-/// \brief function object that returns the byte distance between two iterators and advances a given iterator a given number of bytes
+/// \brief function object that returns the memory unit distance between two iterators and advances a given iterator a given number of mem units (bytes or bits)
 template <typename Iterator>
-struct byte_step_fn {
+struct memunit_step_fn {
     typedef std::ptrdiff_t difference_type;
 
- byte_step_fn(difference_type step=byte_step(Iterator())) : _step(step) {}
+ memunit_step_fn(difference_type step=memunit_step(Iterator())) : _step(step) {}
 
- difference_type difference(const Iterator& it1, const Iterator& it2) const { return byte_distance(it1,it2)/_step; }
- void advance(Iterator& it, difference_type d) const { byte_advance(it,d*_step); }
- difference_type step() const { return _step; }
+ difference_type difference(const Iterator& it1, const Iterator& it2) const { return memunit_distance(it1,it2)/_step; }
+ void advance(Iterator& it, difference_type d) const { memunit_advance(it,d*_step); }
+ difference_type step() const { return _step; }
 
     void set_step(std::ptrdiff_t step) { _step=step; }
 private:
- GIL_CLASS_REQUIRE(Iterator, boost::gil, ByteAdvanceableIteratorConcept);
+ GIL_CLASS_REQUIRE(Iterator, boost::gil, MemoryBasedIteratorConcept);
     difference_type _step;
 };
 
 template <typename Iterator>
-class byte_addressable_step_iterator : public detail::step_iterator_adaptor<byte_addressable_step_iterator<Iterator>,
+class memory_based_step_iterator : public detail::step_iterator_adaptor<memory_based_step_iterator<Iterator>,
                                                                             Iterator,
- byte_step_fn<Iterator> > {
- GIL_CLASS_REQUIRE(Iterator, boost::gil, ByteAdvanceableIteratorConcept);
+ memunit_step_fn<Iterator> > {
+ GIL_CLASS_REQUIRE(Iterator, boost::gil, MemoryBasedIteratorConcept);
 public:
- typedef detail::step_iterator_adaptor<byte_addressable_step_iterator<Iterator>,
+ typedef detail::step_iterator_adaptor<memory_based_step_iterator<Iterator>,
                                           Iterator,
- byte_step_fn<Iterator> > parent_t;
+ memunit_step_fn<Iterator> > parent_t;
     typedef typename parent_t::reference reference;
     typedef typename parent_t::difference_type difference_type;
     typedef Iterator x_iterator;
 
- byte_addressable_step_iterator() : parent_t(Iterator()) {}
- byte_addressable_step_iterator(Iterator it, std::ptrdiff_t byte_step) : parent_t(it, byte_step_fn<Iterator>(byte_step)) {}
+ memory_based_step_iterator() : parent_t(Iterator()) {}
+ memory_based_step_iterator(Iterator it, std::ptrdiff_t memunit_step) : parent_t(it, memunit_step_fn<Iterator>(memunit_step)) {}
     template <typename I2>
- byte_addressable_step_iterator(const byte_addressable_step_iterator<I2>& it)
- : parent_t(it.base(), byte_step_fn<Iterator>(it.step())) {}
+ memory_based_step_iterator(const memory_based_step_iterator<I2>& it)
+ : parent_t(it.base(), memunit_step_fn<Iterator>(it.step())) {}
 
     /// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference
     /// We require our own reference because it is registered in iterator_traits
     reference operator[](difference_type d) const { return *(*this+d); }
 
- void set_step(std::ptrdiff_t byte_step) { this->_step_fn.set_step(byte_step); }
+ void set_step(std::ptrdiff_t memunit_step) { this->_step_fn.set_step(memunit_step); }
 
     x_iterator& base() { return parent_t::base_reference(); }
     x_iterator const& base() const { return parent_t::base_reference(); }
 };
 
 template <typename Iterator>
-struct const_iterator_type<byte_addressable_step_iterator<Iterator> > {
- typedef byte_addressable_step_iterator<typename const_iterator_type<Iterator>::type> type;
+struct const_iterator_type<memory_based_step_iterator<Iterator> > {
+ typedef memory_based_step_iterator<typename const_iterator_type<Iterator>::type> type;
 };
 
 template <typename Iterator>
-struct iterator_is_mutable<byte_addressable_step_iterator<Iterator> > : public iterator_is_mutable<Iterator> {};
+struct iterator_is_mutable<memory_based_step_iterator<Iterator> > : public iterator_is_mutable<Iterator> {};
 
 
 /////////////////////////////
@@ -188,16 +188,16 @@
 /////////////////////////////
 
 template <typename Iterator>
-struct is_iterator_adaptor<byte_addressable_step_iterator<Iterator> > : public mpl::true_{};
+struct is_iterator_adaptor<memory_based_step_iterator<Iterator> > : public mpl::true_{};
 
 template <typename Iterator>
-struct iterator_adaptor_get_base<byte_addressable_step_iterator<Iterator> > {
+struct iterator_adaptor_get_base<memory_based_step_iterator<Iterator> > {
     typedef Iterator type;
 };
 
 template <typename Iterator, typename NewBaseIterator>
-struct iterator_adaptor_rebind<byte_addressable_step_iterator<Iterator>,NewBaseIterator> {
- typedef byte_addressable_step_iterator<NewBaseIterator> type;
+struct iterator_adaptor_rebind<memory_based_step_iterator<Iterator>,NewBaseIterator> {
+ typedef memory_based_step_iterator<NewBaseIterator> type;
 };
 
 /////////////////////////////
@@ -205,48 +205,50 @@
 /////////////////////////////
 
 template <typename Iterator>
-struct color_space_type<byte_addressable_step_iterator<Iterator> > : public color_space_type<Iterator> {};
+struct color_space_type<memory_based_step_iterator<Iterator> > : public color_space_type<Iterator> {};
 
 template <typename Iterator>
-struct channel_mapping_type<byte_addressable_step_iterator<Iterator> > : public channel_mapping_type<Iterator> {};
+struct channel_mapping_type<memory_based_step_iterator<Iterator> > : public channel_mapping_type<Iterator> {};
 
 template <typename Iterator>
-struct is_planar<byte_addressable_step_iterator<Iterator> > : public is_planar<Iterator> {};
+struct is_planar<memory_based_step_iterator<Iterator> > : public is_planar<Iterator> {};
 
 template <typename Iterator>
-struct channel_type<byte_addressable_step_iterator<Iterator> > : public channel_type<Iterator> {};
+struct channel_type<memory_based_step_iterator<Iterator> > : public channel_type<Iterator> {};
 
 /////////////////////////////
-// ByteAdvanceableIteratorConcept
+// MemoryBasedIteratorConcept
 /////////////////////////////
+template <typename Iterator>
+struct byte_to_memunit<memory_based_step_iterator<Iterator> > : public byte_to_memunit<Iterator> {};
 
 template <typename Iterator>
-inline std::ptrdiff_t byte_step(const byte_addressable_step_iterator<Iterator>& p) { return p.step(); }
+inline std::ptrdiff_t memunit_step(const memory_based_step_iterator<Iterator>& p) { return p.step(); }
 
 template <typename Iterator>
-inline std::ptrdiff_t byte_distance(const byte_addressable_step_iterator<Iterator>& p1,
- const byte_addressable_step_iterator<Iterator>& p2) {
- return byte_distance(p1.base(),p2.base());
+inline std::ptrdiff_t memunit_distance(const memory_based_step_iterator<Iterator>& p1,
+ const memory_based_step_iterator<Iterator>& p2) {
+ return memunit_distance(p1.base(),p2.base());
 }
 
 template <typename Iterator>
-inline void byte_advance(byte_addressable_step_iterator<Iterator>& p,
- std::ptrdiff_t byteDiff) {
- byte_advance(p.base(), byteDiff);
+inline void memunit_advance(memory_based_step_iterator<Iterator>& p,
+ std::ptrdiff_t diff) {
+ memunit_advance(p.base(), diff);
 }
 
 template <typename Iterator>
-inline byte_addressable_step_iterator<Iterator>
-byte_advanced(const byte_addressable_step_iterator<Iterator>& p,
- std::ptrdiff_t byteDiff) {
- return byte_addressable_step_iterator<Iterator>(byte_advanced(p.base(), byteDiff),p.step());
+inline memory_based_step_iterator<Iterator>
+memunit_advanced(const memory_based_step_iterator<Iterator>& p,
+ std::ptrdiff_t diff) {
+ return memory_based_step_iterator<Iterator>(memunit_advanced(p.base(), diff),p.step());
 }
 
 template <typename Iterator>
 inline typename std::iterator_traits<Iterator>::reference
-byte_advanced_ref(const byte_addressable_step_iterator<Iterator>& p,
- std::ptrdiff_t byteDiff) {
- return byte_advanced_ref(p.base(), byteDiff);
+memunit_advanced_ref(const memory_based_step_iterator<Iterator>& p,
+ std::ptrdiff_t diff) {
+ return memunit_advanced_ref(p.base(), diff);
 }
 
 /////////////////////////////
@@ -254,18 +256,18 @@
 /////////////////////////////
 
 template <typename Iterator>
-struct dynamic_x_step_type<byte_addressable_step_iterator<Iterator> > {
- typedef byte_addressable_step_iterator<Iterator> type;
+struct dynamic_x_step_type<memory_based_step_iterator<Iterator> > {
+ typedef memory_based_step_iterator<Iterator> type;
 };
 
 // For step iterators, pass the function object to the base
 template <typename Iterator, typename Deref>
-struct iterator_add_deref<byte_addressable_step_iterator<Iterator>,Deref> {
+struct iterator_add_deref<memory_based_step_iterator<Iterator>,Deref> {
     GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept);
 
- typedef byte_addressable_step_iterator<typename iterator_add_deref<Iterator, Deref>::type> type;
+ typedef memory_based_step_iterator<typename iterator_add_deref<Iterator, Deref>::type> type;
 
- static type make(const byte_addressable_step_iterator<Iterator>& it, const Deref& d) { return type(iterator_add_deref<Iterator, Deref>::make(it.base(),d),it.step()); }
+ static type make(const memory_based_step_iterator<Iterator>& it, const Deref& d) { return type(iterator_add_deref<Iterator, Deref>::make(it.base(),d),it.step()); }
 };
 
 ////////////////////////////////////////////////////////////////////////////////////////
@@ -276,10 +278,10 @@
 
 namespace detail {
 
-// if the iterator is a plain base iterator (non-adaptor), wraps it in byte_addressable_step_iterator
+// if the iterator is a plain base iterator (non-adaptor), wraps it in memory_based_step_iterator
 template <typename I>
 typename dynamic_x_step_type<I>::type make_step_iterator_impl(const I& it, std::ptrdiff_t step, mpl::false_) {
- return byte_addressable_step_iterator<I>(it, step);
+ return memory_based_step_iterator<I>(it, step);
 }
 
 // If the iterator is compound, put the step in its base
@@ -288,27 +290,27 @@
     return make_step_iterator(it.base(), step);
 }
 
-// If the iterator is byte_addressable_step_iterator, change the step
+// If the iterator is memory_based_step_iterator, change the step
 template <typename BaseIt>
-byte_addressable_step_iterator<BaseIt> make_step_iterator_impl(const byte_addressable_step_iterator<BaseIt>& it, std::ptrdiff_t step, mpl::true_) {
- return byte_addressable_step_iterator<BaseIt>(it.base(), step);
+memory_based_step_iterator<BaseIt> make_step_iterator_impl(const memory_based_step_iterator<BaseIt>& it, std::ptrdiff_t step, mpl::true_) {
+ return memory_based_step_iterator<BaseIt>(it.base(), step);
 }
 }
 
 /// \brief Constructs a step iterator from a base iterator and a step.
 ///
 /// To construct a step iterator from a given iterator Iterator and a given step, if Iterator does not
-/// already have a dynamic step, we wrap it in a byte_addressable_step_iterator. Otherwise we
+/// already have a dynamic step, we wrap it in a memory_based_step_iterator. Otherwise we
 /// do a compile-time traversal of the chain of iterator adaptors to locate the step iterator
 /// and then set it step to the new one.
 ///
-/// The step iterator of Iterator is not always byte_addressable_step_iterator<Iterator>. For example, Iterator may
-/// already be a byte_addressable_step_iterator, in which case it will be inefficient to stack them;
+/// The step iterator of Iterator is not always memory_based_step_iterator<Iterator>. For example, Iterator may
+/// already be a memory_based_step_iterator, in which case it will be inefficient to stack them;
 /// we can obtain the same result by multiplying their steps. Note that for Iterator to be a
-/// step iterator it does not necessarily have to have the form byte_addressable_step_iterator<J>.
+/// step iterator it does not necessarily have to have the form memory_based_step_iterator<J>.
 /// The step iterator can be wrapped inside another iterator. Also, it may not have the
-/// type byte_addressable_step_iterator, but it could be a user-provided type.
-template <typename I> // Models ByteAdvanceableIteratorConcept, HasDynamicXStepTypeConcept
+/// type memory_based_step_iterator, but it could be a user-provided type.
+template <typename I> // Models MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept
 typename dynamic_x_step_type<I>::type make_step_iterator(const I& it, std::ptrdiff_t step) {
     return detail::make_step_iterator_impl(it, step, typename is_iterator_adaptor<I>::type());
 }

Modified: trunk/boost/gil/typedefs.hpp
==============================================================================
--- trunk/boost/gil/typedefs.hpp (original)
+++ trunk/boost/gil/typedefs.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -36,9 +36,9 @@
     template <typename, typename> struct pixel; \
     template <typename, typename> struct planar_pixel_reference; \
     template <typename, typename> struct planar_pixel_iterator; \
- template <typename> class byte_addressable_step_iterator; \
+ template <typename> class memory_based_step_iterator; \
     template <typename> class point2; \
- template <typename> class byte_addressable_2d_locator; \
+ template <typename> class memory_based_2d_locator; \
     template <typename> class image_view; \
     template <typename, bool, typename> class image; \
     typedef pixel<bits##T, LAYOUT > CS##T##_pixel_t; \
@@ -47,12 +47,12 @@
     typedef const pixel<bits##T, LAYOUT >& CS##T##c_ref_t; \
     typedef CS##T##_pixel_t* CS##T##_ptr_t; \
     typedef CS##T##c_pixel_t* CS##T##c_ptr_t; \
- typedef byte_addressable_step_iterator<CS##T##_ptr_t> CS##T##_step_ptr_t; \
- typedef byte_addressable_step_iterator<CS##T##c_ptr_t> CS##T##c_step_ptr_t; \
- typedef byte_addressable_2d_locator<byte_addressable_step_iterator<CS##T##_ptr_t> > CS##T##_loc_t; \
- typedef byte_addressable_2d_locator<byte_addressable_step_iterator<CS##T##c_ptr_t> > CS##T##c_loc_t; \
- typedef byte_addressable_2d_locator<byte_addressable_step_iterator<CS##T##_step_ptr_t> > CS##T##_step_loc_t; \
- typedef byte_addressable_2d_locator<byte_addressable_step_iterator<CS##T##c_step_ptr_t> > CS##T##c_step_loc_t; \
+ typedef memory_based_step_iterator<CS##T##_ptr_t> CS##T##_step_ptr_t; \
+ typedef memory_based_step_iterator<CS##T##c_ptr_t> CS##T##c_step_ptr_t; \
+ typedef memory_based_2d_locator<memory_based_step_iterator<CS##T##_ptr_t> > CS##T##_loc_t; \
+ typedef memory_based_2d_locator<memory_based_step_iterator<CS##T##c_ptr_t> > CS##T##c_loc_t; \
+ typedef memory_based_2d_locator<memory_based_step_iterator<CS##T##_step_ptr_t> > CS##T##_step_loc_t; \
+ typedef memory_based_2d_locator<memory_based_step_iterator<CS##T##c_step_ptr_t> > CS##T##c_step_loc_t; \
     typedef image_view<CS##T##_loc_t> CS##T##_view_t; \
     typedef image_view<CS##T##c_loc_t> CS##T##c_view_t; \
     typedef image_view<CS##T##_step_loc_t> CS##T##_step_view_t; \
@@ -66,12 +66,12 @@
     typedef planar_pixel_reference<const bits##T&,CS_FULL > CS##T##c_planar_ref_t; \
     typedef planar_pixel_iterator<bits##T*,CS_FULL > CS##T##_planar_ptr_t; \
     typedef planar_pixel_iterator<const bits##T*,CS_FULL > CS##T##c_planar_ptr_t; \
- typedef byte_addressable_step_iterator<CS##T##_planar_ptr_t> CS##T##_planar_step_ptr_t; \
- typedef byte_addressable_step_iterator<CS##T##c_planar_ptr_t> CS##T##c_planar_step_ptr_t; \
- typedef byte_addressable_2d_locator<byte_addressable_step_iterator<CS##T##_planar_ptr_t> > CS##T##_planar_loc_t; \
- typedef byte_addressable_2d_locator<byte_addressable_step_iterator<CS##T##c_planar_ptr_t> > CS##T##c_planar_loc_t; \
- typedef byte_addressable_2d_locator<byte_addressable_step_iterator<CS##T##_planar_step_ptr_t> > CS##T##_planar_step_loc_t; \
- typedef byte_addressable_2d_locator<byte_addressable_step_iterator<CS##T##c_planar_step_ptr_t> > CS##T##c_planar_step_loc_t; \
+ typedef memory_based_step_iterator<CS##T##_planar_ptr_t> CS##T##_planar_step_ptr_t; \
+ typedef memory_based_step_iterator<CS##T##c_planar_ptr_t> CS##T##c_planar_step_ptr_t; \
+ typedef memory_based_2d_locator<memory_based_step_iterator<CS##T##_planar_ptr_t> > CS##T##_planar_loc_t; \
+ typedef memory_based_2d_locator<memory_based_step_iterator<CS##T##c_planar_ptr_t> > CS##T##c_planar_loc_t; \
+ typedef memory_based_2d_locator<memory_based_step_iterator<CS##T##_planar_step_ptr_t> > CS##T##_planar_step_loc_t; \
+ typedef memory_based_2d_locator<memory_based_step_iterator<CS##T##c_planar_step_ptr_t> > CS##T##c_planar_step_loc_t; \
     typedef image_view<CS##T##_planar_loc_t> CS##T##_planar_view_t; \
     typedef image_view<CS##T##c_planar_loc_t> CS##T##c_planar_view_t; \
     typedef image_view<CS##T##_planar_step_loc_t> CS##T##_planar_step_view_t; \

Modified: trunk/boost/gil/utilities.hpp
==============================================================================
--- trunk/boost/gil/utilities.hpp (original)
+++ trunk/boost/gil/utilities.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -32,12 +32,25 @@
 /// \brief Various utilities not specific to the image library. Some are non-standard STL extensions or generic iterator adaptors
 /// \author Lubomir Bourdev and Hailin Jin \n
 /// Adobe Systems Incorporated
+/// \date 2005-2007 \n Last updated on August 14, 2007
 ///
 ///
 ////////////////////////////////////////////////////////////////////////////////////////
 
 namespace boost { namespace gil {
 
+/**
+\addtogroup PointModel
+
+Example:
+\code
+point2<int> p(3,2);
+assert((p[0] == p.x) && (p[1] == p.y));
+assert(axis_value<0>(p) == 3);
+assert(axis_value<1>(p) == 2);
+\endcode
+*/
+
 ////////////////////////////////////////////////////////////////////////////////////////
 // CLASS point2
 ///
@@ -125,6 +138,15 @@
 inline int iceil(float x ) { return static_cast<int>(std::ceil(x)); }
 inline int iceil(double x) { return static_cast<int>(std::ceil(x)); }
 
+/**
+\addtogroup PointAlgorithm
+
+Example:
+\code
+assert(iround(point2<double>(3.1, 3.9)) == point2<int>(3,4));
+\endcode
+*/
+
 /// \ingroup PointAlgorithm
 inline point2<int> iround(const point2<float >& p) { return point2<int>(iround(p.x),iround(p.y)); }
 /// \ingroup PointAlgorithm
@@ -149,22 +171,34 @@
     return val+(alignment - val%alignment)%alignment;
 }
 
+/// \brief Helper base class for pixel dereference adaptors.
+/// \ingroup PixelDereferenceAdaptorModel
+///
+template <typename ConstT, typename Value, typename Reference, typename ConstReference,
+ typename ArgType, typename ResultType, bool IsMutable>
+struct deref_base : public std::unary_function<ArgType, ResultType> {
+ typedef ConstT const_t;
+ typedef Value value_type;
+ typedef Reference reference;
+ typedef ConstReference const_reference;
+ BOOST_STATIC_CONSTANT(bool, is_mutable = IsMutable);
+};
+
 /// \brief Composes two dereference function objects. Similar to std::unary_compose but needs to pull some typedefs from the component types. Models: PixelDereferenceAdaptorConcept
 /// \ingroup PixelDereferenceAdaptorModel
 ///
 template <typename D1, typename D2>
-class deref_compose {
+class deref_compose : public deref_base<
+ deref_compose<typename D1::const_t, typename D2::const_t>,
+ typename D1::value_type, typename D1::reference, typename D1::const_reference,
+ typename D2::argument_type, typename D1::result_type, D1::is_mutable && D2::is_mutable>
+{
 public:
     D1 _fn1;
     D2 _fn2;
 
- typedef deref_compose<typename D1::const_t, typename D2::const_t> const_t;
- typedef typename D1::value_type value_type;
- typedef typename D1::reference reference;
- typedef typename D1::const_reference const_reference;
     typedef typename D2::argument_type argument_type;
     typedef typename D1::result_type result_type;
- BOOST_STATIC_CONSTANT(bool, is_mutable=D1::is_mutable && D2::is_mutable);
 
     deref_compose() {}
     deref_compose(const D1& x, const D2& y) : _fn1(x), _fn2(y) {}

Modified: trunk/libs/gil/example/Makefile
==============================================================================
--- trunk/libs/gil/example/Makefile (original)
+++ trunk/libs/gil/example/Makefile 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -1,9 +1,11 @@
+.SUFFIXES: .cpp
+#CXX=/usr/local/gcc-411/bin/g++
 CXX=g++
 CXX_FLAGS=-Wall -O2 -DNDEBUG -DBOOST_GIL_USE_CONCEPT_CHECK
 
-BOOST_INCLUDE_PATH=-I../../..
-LIBJPEG_INCLUDE_PATH=-I../../../boost/gil/lib/libjpeg
-LIBJPEG_LIB_PATH=-L../../../boost/gil/lib/libjpeg
+BOOST_INCLUDE_PATH=-I../../.. -I../../../../boost_libraries
+LIBJPEG_INCLUDE_PATH=-I../../../../lib/libjpeg
+LIBJPEG_LIB_PATH=-L../../../../lib/libjpeg
 
 all: resize affine convolution mandelbrot x_gradient histogram dynamic_image interleaved_ptr packed_pixel
 .cpp.o:
@@ -11,7 +13,7 @@
 clean:
         -rm -f *.o *.exe
         -rm -f out-affine.jpg out-resize.jpg out-convolution.jpg out-convolution2.jpg out-mandelbrot.jpg
- -rm -f out-interleaved_ptr.jpg out-x_gradient.jpg out-histogram.txt out-packed_pixel.jpg out-dynamic_image.jpg
+ -rm -f out-interleaved_ptr.jpg out-x_gradient.jpg out-histogram.txt out-packed_pixel_bgr772.jpg out-packed_pixel_gray1.jpg out-dynamic_image.jpg
 resize: resize.o
         ${CXX} -o resize ${CXX_FLAGS} resize.o ${LIBJPEG_LIB_PATH} -ljpeg
 affine: affine.o

Modified: trunk/libs/gil/example/convolution.cpp
==============================================================================
--- trunk/libs/gil/example/convolution.cpp (original)
+++ trunk/libs/gil/example/convolution.cpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -1,3 +1,20 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
+///////////////////////
+//// NOTE: This sample file uses the numeric extension, which does not come with the Boost distribution.
+//// You may download it from http://opensource.adobe.com/gil
+///////////////////////
+
 /// \file
 /// \brief Test file for convolve_rows() and convolve_cols() in the numeric extension
 /// \author Lubomir Bourdev and Hailin Jin
@@ -18,17 +35,48 @@
     // Convolve the rows and the columns of the image with a fixed kernel
     rgb8_image_t convolved(img);
 
- float gaussian[]={0.00022923296f,0.0059770769f,0.060597949f,0.24173197f,0.38292751f,
- 0.24173197f,0.060597949f,0.0059770769f,0.00022923296f};
+ // radius-1 Gaussian kernel, size 9
+ float gaussian_1[]={0.00022923296f,0.0059770769f,0.060597949f,0.24173197f,0.38292751f,
+ 0.24173197f,0.060597949f,0.0059770769f,0.00022923296f};
+ /*
+ // radius-2 Gaussian kernel, size 15
+ float gaussian_2[]={
+ 0.00048869418f,0.0024031631f,0.0092463447f,
+ 0.027839607f,0.065602221f,0.12099898f,0.17469721f,
+ 0.19744757f,
+ 0.17469721f,0.12099898f,0.065602221f,0.027839607f,
+ 0.0092463447f,0.0024031631f,0.00048869418f
+ };
+ //radius-3 Gaussian kernel, size 23
+ float gaussian_3[]={
+ 0.00016944126f,0.00053842377f,0.0015324751f,0.0039068931f,
+ 0.0089216027f,0.018248675f,0.033434924f,0.054872241f,
+ 0.080666073f,0.10622258f,0.12529446f,
+ 0.13238440f,
+ 0.12529446f,0.10622258f,0.080666073f,
+ 0.054872241f,0.033434924f,0.018248675f,0.0089216027f,
+ 0.0039068931f,0.0015324751f,0.00053842377f,0.00016944126f
+ };
+ //radius-4 Gaussian kernel, size 29
+ float gaussian_4[]={
+ 0.00022466264f,0.00052009715f,0.0011314391f,0.0023129794f,
+ 0.0044433107f,0.0080211498f,0.013606987f,0.021691186f,
+ 0.032493830f,0.045742013f,0.060509924f,0.075220309f,
+ 0.087870099f,0.096459411f,0.099505201f,0.096459411f,0.087870099f,
+ 0.075220309f,0.060509924f,0.045742013f,0.032493830f,
+ 0.021691186f,0.013606987f,0.0080211498f,0.0044433107f,
+ 0.0023129794f,0.0011314391f,0.00052009715f,0.00022466264f,
+ };
+ */
 
- kernel_1d_fixed<float,9> kernel(gaussian,4);
+ kernel_1d_fixed<float,9> kernel(gaussian_1,4);
 
     convolve_rows_fixed<rgb32f_pixel_t>(const_view(convolved),kernel,view(convolved));
     convolve_cols_fixed<rgb32f_pixel_t>(const_view(convolved),kernel,view(convolved));
     jpeg_write_view("out-convolution.jpg", view(convolved));
 
     // This is how to use a resizable kernel
- kernel_1d<float> kernel2(gaussian,9,4);
+ kernel_1d<float> kernel2(gaussian_1,9,4);
     convolve_rows<rgb32f_pixel_t>(const_view(img),kernel2,view(img));
     convolve_cols<rgb32f_pixel_t>(const_view(img),kernel2,view(img));
     jpeg_write_view("out-convolution2.jpg", view(img));

Modified: trunk/libs/gil/example/dynamic_image.cpp
==============================================================================
--- trunk/libs/gil/example/dynamic_image.cpp (original)
+++ trunk/libs/gil/example/dynamic_image.cpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -1,3 +1,15 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
 /// \file
 /// \brief Test file for using dynamic images
 /// \author Lubomir Bourdev and Hailin Jin

Modified: trunk/libs/gil/example/histogram.cpp
==============================================================================
--- trunk/libs/gil/example/histogram.cpp (original)
+++ trunk/libs/gil/example/histogram.cpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -1,3 +1,15 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
 /// \file
 /// \brief Example file to demonstrate a way to compute histogram
 /// \author Lubomir Bourdev and Hailin Jin

Modified: trunk/libs/gil/example/interleaved_ptr.cpp
==============================================================================
--- trunk/libs/gil/example/interleaved_ptr.cpp (original)
+++ trunk/libs/gil/example/interleaved_ptr.cpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -1,3 +1,15 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
 /// \file
 /// \brief Example file to demonstrate how to create a model of a pixel iterator
 /// \author Lubomir Bourdev and Hailin Jin
@@ -32,7 +44,7 @@
 
     boost::function_requires<MutablePixelIteratorConcept<rgb8_interleaved_ptr> >();
     boost::function_requires<PixelIteratorConcept<rgb8c_interleaved_ptr> >();
- boost::function_requires<ByteAdvanceableIteratorConcept<byte_addressable_step_iterator<rgb8_interleaved_ptr> > >();
+ boost::function_requires<MemoryBasedIteratorConcept<memory_based_step_iterator<rgb8_interleaved_ptr> > >();
 
     boost::function_requires<MutablePixelConcept<rgb8_interleaved_ptr::value_type> >();
     boost::function_requires<PixelConcept<rgb8c_interleaved_ptr::value_type> >();
@@ -51,7 +63,7 @@
 
     // Construct a view from it, without casting it to rgb8_pixel_t*
     rgb8_interleaved_view_t src_view=interleaved_view(img.width(),img.height(),rgb8_interleaved_ptr(raw_ptr),
- view(img).pixels().row_bytes());
+ view(img).pixels().row_size());
 
     // Apply view transformations and algorithms on it
     jpeg_write_view("out-interleaved_ptr.jpg",nth_channel_view(flipped_up_down_view(src_view),1));

Modified: trunk/libs/gil/example/interleaved_ptr.hpp
==============================================================================
--- trunk/libs/gil/example/interleaved_ptr.hpp (original)
+++ trunk/libs/gil/example/interleaved_ptr.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -1,8 +1,13 @@
 /*
     Copyright 2005-2007 Adobe Systems Incorporated
- Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
- or a copy at http://opensource.adobe.com/licenses.html)
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
 */
+
 /*************************************************************************************************/
 
 ////////////////////////////////////////////////////////////////////////////////////////
@@ -69,7 +74,7 @@
 
     /// For some reason operator[] provided by boost::iterator_facade returns a custom class that is convertible to reference
     /// We require our own reference because it is registered in iterator_traits
- reference operator[](difference_type d) const { return byte_advanced_ref(*this,d*sizeof(channel_t));}
+ reference operator[](difference_type d) const { return memunit_advanced_ref(*this,d*sizeof(channel_t));}
 
     // Put this for every iterator whose reference is a proxy type
     reference operator->() const { return **this; }
@@ -152,32 +157,32 @@
 /////////////////////////////
 
 template <typename ChannelPtr, typename Layout>
-inline std::ptrdiff_t byte_step(const interleaved_ptr<ChannelPtr,Layout>&) {
+inline std::ptrdiff_t memunit_step(const interleaved_ptr<ChannelPtr,Layout>&) {
     return sizeof(typename std::iterator_traits<ChannelPtr>::value_type)* // size of each channel in bytes
            interleaved_ptr<ChannelPtr,Layout>::num_channels; // times the number of channels
 }
 
 template <typename ChannelPtr, typename Layout>
-inline std::ptrdiff_t byte_distance(const interleaved_ptr<ChannelPtr,Layout>& p1, const interleaved_ptr<ChannelPtr,Layout>& p2) {
- return byte_distance(p1.channels(),p2.channels());
+inline std::ptrdiff_t memunit_distance(const interleaved_ptr<ChannelPtr,Layout>& p1, const interleaved_ptr<ChannelPtr,Layout>& p2) {
+ return memunit_distance(p1.channels(),p2.channels());
 }
 
 template <typename ChannelPtr, typename Layout>
-inline void byte_advance(interleaved_ptr<ChannelPtr,Layout>& p, std::ptrdiff_t byte_diff) {
- byte_advance(p.channels(), byte_diff);
+inline void memunit_advance(interleaved_ptr<ChannelPtr,Layout>& p, std::ptrdiff_t diff) {
+ memunit_advance(p.channels(), diff);
 }
 
 template <typename ChannelPtr, typename Layout>
-inline interleaved_ptr<ChannelPtr,Layout> byte_advanced(const interleaved_ptr<ChannelPtr,Layout>& p, std::ptrdiff_t byteDiff) {
+inline interleaved_ptr<ChannelPtr,Layout> memunit_advanced(const interleaved_ptr<ChannelPtr,Layout>& p, std::ptrdiff_t diff) {
     interleaved_ptr<ChannelPtr,Layout> ret=p;
- byte_advance(ret, byteDiff);
+ memunit_advance(ret, diff);
     return ret;
 }
 
 template <typename ChannelPtr, typename Layout>
-inline typename interleaved_ptr<ChannelPtr,Layout>::reference byte_advanced_ref(const interleaved_ptr<ChannelPtr,Layout>& p, std::ptrdiff_t byteDiff) {
+inline typename interleaved_ptr<ChannelPtr,Layout>::reference memunit_advanced_ref(const interleaved_ptr<ChannelPtr,Layout>& p, std::ptrdiff_t diff) {
     interleaved_ptr<ChannelPtr,Layout> ret=p;
- byte_advance(ret, byteDiff);
+ memunit_advance(ret, diff);
     return *ret;
 }
 
@@ -187,7 +192,7 @@
 
 template <typename ChannelPtr, typename Layout>
 struct dynamic_x_step_type<interleaved_ptr<ChannelPtr,Layout> > {
- typedef byte_addressable_step_iterator<interleaved_ptr<ChannelPtr,Layout> > type;
+ typedef memory_based_step_iterator<interleaved_ptr<ChannelPtr,Layout> > type;
 };
 
 } } // namespace boost::gil

Modified: trunk/libs/gil/example/interleaved_ref.hpp
==============================================================================
--- trunk/libs/gil/example/interleaved_ref.hpp (original)
+++ trunk/libs/gil/example/interleaved_ref.hpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -1,10 +1,16 @@
 /*
     Copyright 2005-2007 Adobe Systems Incorporated
- Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
- or a copy at http://opensource.adobe.com/licenses.html)
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
 */
+
 /*************************************************************************************************/
 
+
 ////////////////////////////////////////////////////////////////////////////////////////
 /// \file
 /// \brief Example on how to create a new model of a pixel reference
@@ -53,10 +59,6 @@
 // Required by ColorBaseConcept
     typedef Layout layout_t;
 
- // Type of each channel, and the result of constant and mutable at_c<K>(*this);
- template <int K> struct kth_element_type { typedef channel_t type; };
- template <int K> struct kth_element_const_reference_type { typedef channel_reference_t type; };
-
     // Copy construction from a compatible type. The copy constructor of references is shallow. The channels themselves are not copied.
     interleaved_ref(const interleaved_ref& p) : _channels(p._channels) {}
     template <typename P> interleaved_ref(const P& p) : _channels(p._channels) { check_compatible<P>(); }
@@ -65,7 +67,6 @@
     template <typename P> bool operator!=(const P& p) const { return !(*this==p); }
 
 // Required by MutableColorBaseConcept
- template <int K> struct kth_element_reference_type { typedef channel_reference_t type; };
     
     // Assignment from a compatible type
     const interleaved_ref& operator=(const interleaved_ref& p) const { static_copy(p,*this); return *this; }
@@ -91,6 +92,24 @@
 };
 
 // Required by ColorBaseConcept
+template <typename ChannelReference, typename Layout, int K>
+struct kth_element_type<interleaved_ref<ChannelReference,Layout>,K> {
+ typedef ChannelReference type;
+};
+
+template <typename ChannelReference, typename Layout, int K>
+struct kth_element_reference_type<interleaved_ref<ChannelReference,Layout>,K> {
+ typedef ChannelReference type;
+};
+
+template <typename ChannelReference, typename Layout, int K>
+struct kth_element_const_reference_type<interleaved_ref<ChannelReference,Layout>,K> {
+ typedef ChannelReference type;
+// typedef typename channel_traits<ChannelReference>::const_reference type;
+};
+
+
+// Required by ColorBaseConcept
 template <int K, typename ChannelReference, typename Layout>
 typename element_reference_type<interleaved_ref<ChannelReference,Layout> >::type
 at_c(const interleaved_ref<ChannelReference,Layout>& p) { return p[K]; };

Modified: trunk/libs/gil/example/packed_pixel.cpp
==============================================================================
--- trunk/libs/gil/example/packed_pixel.cpp (original)
+++ trunk/libs/gil/example/packed_pixel.cpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -1,3 +1,15 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
 /// \file
 /// \brief Example file to show how to deal with packed pixels
 /// \author Lubomir Bourdev and Hailin Jin
@@ -12,6 +24,12 @@
 /// We read a regular 8-bit RGB image, convert it to packed BGR772, convert it back to 8-bit RGB and save it to a file.
 /// Since the red channel is only two bits the color loss should be observable in the result
 ///
+/// This test file also demonstrates how to use bit-aligned images - these are images whose pixels themselves are not byte aligned.
+/// For example, an rgb222 image has a pixel whose size is 6 bits. Bit-aligned images are more complicated than packed images. They
+/// require a special proxy class to represent pixel reference and pixel iterator (packed images use C++ reference and C pointer respectively).
+/// The alignment parameter in the constructor of bit-aligned images is in bit units. For example, if you want your bit-aligned image to have 4-byte
+/// alignment of its rows use alignment of 32, not 4.
+///
 /// To demonstrate that image view transformations work on packed images, we save the result transposed.
 
 #include <algorithm>
@@ -20,27 +38,31 @@
 using namespace boost;
 using namespace boost::gil;
 
-
-// define a bgr772 image
-typedef const packed_channel_reference<boost::uint16_t, 0,7,true> bgr772_channel0_t;
-typedef const packed_channel_reference<boost::uint16_t, 7,7,true> bgr772_channel1_t;
-typedef const packed_channel_reference<boost::uint16_t,14,2,true> bgr772_channel2_t;
-typedef heterogeneous_packed_pixel<uint16_t,
- mpl::vector3<bgr772_channel0_t,bgr772_channel1_t,bgr772_channel2_t>, bgr_layout_t> bgr772_pixel_t;
-typedef image<bgr772_pixel_t,false> bgr772_image_t;
-
 int main() {
- boost::function_requires<PixelValueConcept<bgr772_pixel_t> >();
- BOOST_STATIC_ASSERT((sizeof(bgr772_pixel_t)==2));
-
     bgr8_image_t img;
     jpeg_read_image("test.jpg",img);
 
- bgr772_image_t img_packed1(img.dimensions());
- copy_and_convert_pixels(const_view(img),view(img_packed1));
+ ////////////////////////////////
+ // define a bgr772 image. It is a "packed" image - its channels are not byte-aligned, but its pixels are.
+ ////////////////////////////////
+
+ typedef packed_image3_type<uint16_t, 7,7,2, bgr_layout_t>::type bgr772_image_t;
+ bgr772_image_t bgr772_img(img.dimensions());
+ copy_and_convert_pixels(const_view(img),view(bgr772_img));
+
+ // Save the result. JPEG I/O does not support the packed pixel format, so convert it back to 8-bit RGB
+ jpeg_write_view("out-packed_pixel_bgr772.jpg",color_converted_view<bgr8_pixel_t>(transposed_view(const_view(bgr772_img))));
+
+ ////////////////////////////////
+ // define a gray1 image (one-bit per pixel). It is a "bit-aligned" image - its pixels are not byte aligned.
+ ////////////////////////////////
+
+ typedef bit_aligned_image1_type<1, gray_layout_t>::type gray1_image_t;
+ gray1_image_t gray1_img(img.dimensions());
+ copy_and_convert_pixels(const_view(img),view(gray1_img));
 
     // Save the result. JPEG I/O does not support the packed pixel format, so convert it back to 8-bit RGB
- jpeg_write_view("out-packed_pixel.jpg",color_converted_view<bgr8_pixel_t>(transposed_view(const_view(img_packed1))));
+ jpeg_write_view("out-packed_pixel_gray1.jpg",color_converted_view<gray8_pixel_t>(transposed_view(const_view(gray1_img))));
 
     return 0;
 }

Modified: trunk/libs/gil/example/resize.cpp
==============================================================================
--- trunk/libs/gil/example/resize.cpp (original)
+++ trunk/libs/gil/example/resize.cpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -1,8 +1,25 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
 /// \file
 /// \brief Test file for resize_view() in the numeric extension
 /// \author Lubomir Bourdev and Hailin Jin
 /// \date February 27, 2007
 
+///////////////////////
+//// NOTE: This sample file uses the numeric extension, which does not come with the Boost distribution.
+//// You may download it from http://opensource.adobe.com/gil
+///////////////////////
+
 #include <boost/gil/image.hpp>
 #include <boost/gil/typedefs.hpp>
 #include <boost/gil/extension/io/jpeg_io.hpp>

Modified: trunk/libs/gil/example/x_gradient.cpp
==============================================================================
--- trunk/libs/gil/example/x_gradient.cpp (original)
+++ trunk/libs/gil/example/x_gradient.cpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -1,3 +1,15 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
 /// \file
 /// \brief Example file to demonstrate a way to compute gradients along x-axis
 /// \author Lubomir Bourdev and Hailin Jin

Modified: trunk/libs/gil/test/Makefile
==============================================================================
--- trunk/libs/gil/test/Makefile (original)
+++ trunk/libs/gil/test/Makefile 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -7,15 +7,25 @@
 CXX_FLAGS=-Wall -DBOOST_GIL_USE_CONCEPT_CHECK #-DNDEBUG
 CXX_CHECKSUM_FLAGS=-Wall -DBOOST_GIL_NO_IO -DBOOST_GIL_USE_CONCEPT_CHECK #-DNDEBUG
 
-BOOST_INCLUDE_PATH=-I../../..
+BOOST_INCLUDE_PATH=-I../../.. -I../../../../boost_libraries
+LIBJPEG_INCLUDE_PATH=-I../../../../lib/libjpeg
+LIBJPEG_LIB_PATH=-L../../../../lib/libjpeg
+LIBTIFF_INCLUDE_PATH=-I../../../../lib/libtiff
+LIBTIFF_LIB_PATH=-L../../../../lib/libtiff
+LIBPNG_INCLUDE_PATH=-I../../../../lib/libpng
+LIBPNG_LIB_PATH=-L../../../../lib/libpng
+LIBZ_LIB_PATH=-L../../../../lib/zlib
 ALL_OBJECTS=main.o channel.o pixel.o pixel_iterator.o image.o image_io.o sample_image.o
 
 all: performance checksum
 .cpp.o:
+# ${CXX} ${CXX_FLAGS} ${BOOST_INCLUDE_PATH} ${LIBJPEG_INCLUDE_PATH} ${LIBTIFF_INCLUDE_PATH} ${LIBPNG_INCLUDE_PATH} -c $<
         ${CXX} ${CXX_CHECKSUM_FLAGS} ${BOOST_INCLUDE_PATH} -c $<
 clean:
         -rm -f *.o *.exe
 performance: performance.o
         ${CXX} -o performance ${CXX_FLAGS} performance.o
+test: ${ALL_OBJECTS}
+ ${CXX} -o test ${CXX_FLAGS} ${ALL_OBJECTS} ${LIBJPEG_LIB_PATH} -ljpeg ${LIBTIFF_LIB_PATH} -ltiff ${LIBPNG_LIB_PATH} -lpng ${LIBZ_LIB_PATH} -lz
 checksum: ${ALL_OBJECTS}
         ${CXX} -o test ${CXX_CHECKSUM_FLAGS} ${ALL_OBJECTS}

Modified: trunk/libs/gil/test/channel.cpp
==============================================================================
--- trunk/libs/gil/test/channel.cpp (original)
+++ trunk/libs/gil/test/channel.cpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -179,16 +179,17 @@
 };
 
 // For subbyte channel references we need to store the bit buffers somewhere
-template <typename ChannelSubbyteRef, typename BitBuffer, typename ChannelMutableRef = ChannelSubbyteRef>
+template <typename ChannelSubbyteRef, typename ChannelMutableRef = ChannelSubbyteRef>
 class packed_reference_core {
 protected:
     typedef ChannelSubbyteRef channel_t;
+ typedef typename channel_t::integer_t integer_t;
     channel_t _min_v, _max_v;
 
- BitBuffer _min_buf, _max_buf;
+ integer_t _min_buf, _max_buf;
 
- packed_reference_core() : _min_v(_min_buf), _max_v(_max_buf) {
- ChannelMutableRef b1(_min_buf), b2(_max_buf);
+ packed_reference_core() : _min_v(&_min_buf), _max_v(&_max_buf) {
+ ChannelMutableRef b1(&_min_buf), b2(&_max_buf);
         b1 = channel_traits<channel_t>::min_value();
         b2 = channel_traits<channel_t>::max_value();
 
@@ -196,16 +197,16 @@
     }
 };
 
-template <typename ChannelSubbyteRef, typename BitBuffer, typename ChannelMutableRef = ChannelSubbyteRef>
+template <typename ChannelSubbyteRef, typename ChannelMutableRef = ChannelSubbyteRef>
 class packed_dynamic_reference_core {
 protected:
     typedef ChannelSubbyteRef channel_t;
     channel_t _min_v, _max_v;
 
- BitBuffer _min_buf, _max_buf;
+ typename channel_t::integer_t _min_buf, _max_buf;
 
- packed_dynamic_reference_core(int first_bit1=1, int first_bit2=2) : _min_v(_min_buf,first_bit1), _max_v(_max_buf,first_bit2) {
- ChannelMutableRef b1(_min_buf,1), b2(_max_buf,2);
+ packed_dynamic_reference_core(int first_bit1=1, int first_bit2=2) : _min_v(&_min_buf,first_bit1), _max_v(&_max_buf,first_bit2) {
+ ChannelMutableRef b1(&_min_buf,1), b2(&_max_buf,2);
         b1 = channel_traits<channel_t>::min_value();
         b2 = channel_traits<channel_t>::max_value();
 
@@ -224,24 +225,24 @@
     do_test<reference_core<ChannelRef> >().test_all();
 }
 
-template <typename ChannelSubbyteRef, typename BitBuffer>
+template <typename ChannelSubbyteRef>
 void test_packed_channel_reference() {
- do_test<packed_reference_core<ChannelSubbyteRef,BitBuffer,ChannelSubbyteRef> >().test_all();
+ do_test<packed_reference_core<ChannelSubbyteRef,ChannelSubbyteRef> >().test_all();
 }
 
-template <typename ChannelSubbyteRef, typename BitBuffer, typename MutableRef>
+template <typename ChannelSubbyteRef, typename MutableRef>
 void test_const_packed_channel_reference() {
- do_test<packed_reference_core<ChannelSubbyteRef,BitBuffer,MutableRef> >().test_all();
+ do_test<packed_reference_core<ChannelSubbyteRef,MutableRef> >().test_all();
 }
 
-template <typename ChannelSubbyteRef, typename BitBuffer>
+template <typename ChannelSubbyteRef>
 void test_packed_dynamic_channel_reference() {
- do_test<packed_dynamic_reference_core<ChannelSubbyteRef,BitBuffer,ChannelSubbyteRef> >().test_all();
+ do_test<packed_dynamic_reference_core<ChannelSubbyteRef,ChannelSubbyteRef> >().test_all();
 }
 
-template <typename ChannelSubbyteRef, typename BitBuffer, typename MutableRef>
+template <typename ChannelSubbyteRef, typename MutableRef>
 void test_const_packed_dynamic_channel_reference() {
- do_test<packed_dynamic_reference_core<ChannelSubbyteRef,BitBuffer,MutableRef> >().test_all();
+ do_test<packed_dynamic_reference_core<ChannelSubbyteRef,MutableRef> >().test_all();
 }
 
 template <typename ChannelValue>
@@ -304,38 +305,38 @@
 void test_packed_channel_reference() {
     typedef packed_channel_reference<boost::uint16_t, 0,5,true> channel16_0_5_reference_t;
     typedef packed_channel_reference<boost::uint16_t, 5,6,true> channel16_5_6_reference_t;
- typedef packed_channel_reference<boost::uint16_t,11,5,true> channel16_11_5_reference_t;
+ typedef packed_channel_reference<boost::uint16_t, 11,5,true> channel16_11_5_reference_t;
 
     boost::uint16_t data=0;
- channel16_0_5_reference_t channel1(data);
- channel16_5_6_reference_t channel2(data);
- channel16_11_5_reference_t channel3(data);
+ channel16_0_5_reference_t channel1(&data);
+ channel16_5_6_reference_t channel2(&data);
+ channel16_11_5_reference_t channel3(&data);
 
     channel1=channel_traits<channel16_0_5_reference_t>::max_value();
     channel2=channel_traits<channel16_5_6_reference_t>::max_value();
     channel3=channel_traits<channel16_11_5_reference_t>::max_value();
     error_if(data!=65535);
 
- test_packed_channel_reference<channel16_0_5_reference_t,boost::uint16_t>();
- test_packed_channel_reference<channel16_5_6_reference_t,boost::uint16_t>();
- test_packed_channel_reference<channel16_11_5_reference_t,boost::uint16_t>();
+ test_packed_channel_reference<channel16_0_5_reference_t>();
+ test_packed_channel_reference<channel16_5_6_reference_t>();
+ test_packed_channel_reference<channel16_11_5_reference_t>();
 }
 
 void test_packed_dynamic_channel_reference() {
- typedef packed_dynamic_channel_reference<boost::uint16_t, 5,true> channel16_5_reference_t;
- typedef packed_dynamic_channel_reference<boost::uint16_t, 6,true> channel16_6_reference_t;
+ typedef packed_dynamic_channel_reference<boost::uint16_t,5,true> channel16_5_reference_t;
+ typedef packed_dynamic_channel_reference<boost::uint16_t,6,true> channel16_6_reference_t;
 
     boost::uint16_t data=0;
- channel16_5_reference_t channel1(data,0);
- channel16_6_reference_t channel2(data,5);
- channel16_5_reference_t channel3(data,11);
+ channel16_5_reference_t channel1(&data,0);
+ channel16_6_reference_t channel2(&data,5);
+ channel16_5_reference_t channel3(&data,11);
 
     channel1=channel_traits<channel16_5_reference_t>::max_value();
     channel2=channel_traits<channel16_6_reference_t>::max_value();
     channel3=channel_traits<channel16_5_reference_t>::max_value();
     error_if(data!=65535);
 
- test_packed_dynamic_channel_reference<channel16_5_reference_t,boost::uint16_t>();
+ test_packed_dynamic_channel_reference<channel16_5_reference_t>();
 }
 
 void test_channel() {

Modified: trunk/libs/gil/test/gil_reference_checksums.txt
==============================================================================
--- trunk/libs/gil/test/gil_reference_checksums.txt (original)
+++ trunk/libs/gil/test/gil_reference_checksums.txt 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -1,7 +1,23 @@
+bgr121_basic_red_x 7f6e24e7
+bgr121_basic_white_x e4aaa1d3
+bgr121_histogram_histogram ca580192
+bgr121_views_0th_k_channel daa9f7e3
+bgr121_views_90ccw c64d6d20
+bgr121_views_90cw 8565efd8
+bgr121_views_cropped 43305e15
+bgr121_views_flipped_lr 2d68e448
+bgr121_views_flipped_ud 8f7f7d00
+bgr121_views_gray8 bbabe219
+bgr121_views_my_gray8 3086d22f
+bgr121_views_original 7e5bb87d
+bgr121_views_rot180 68f37202
+bgr121_views_subsampled ac6ca178
+bgr121_views_transpose da2ff80
 bgr8_basic_red_x 7f6e24e7
 bgr8_basic_white_x e4aaa1d3
-bgr8_histogram_histogram 7b256ba4
-bgr8_views_0th_channel 4638e58d
+bgr8_histogram_histogram badcdd58
+bgr8_views_0th_k_channel 4638e58d
+bgr8_views_0th_n_channel 4638e58d
 bgr8_views_90ccw 8c4980e5
 bgr8_views_90cw e4c69665
 bgr8_views_cropped ff56b05e
@@ -13,7 +29,8 @@
 bgr8_views_rot180 150f1206
 bgr8_views_subsampled 92439ee7
 bgr8_views_transpose c9a890a0
-color_converted_0th_channel 3817178f
+color_converted_0th_k_channel 3817178f
+color_converted_0th_n_channel 3817178f
 color_converted_90ccw dc403b3
 color_converted_90cw c6fc34de
 color_converted_cropped 666252a
@@ -32,8 +49,9 @@
 dynamic_subimage_subsampled180rot 4055263a
 gray8_basic_red_x ab461c6a
 gray8_basic_white_x be81c274
-gray8_histogram_histogram 7b256ba4
-gray8_views_0th_channel 3817178f
+gray8_histogram_histogram badcdd58
+gray8_views_0th_k_channel 3817178f
+gray8_views_0th_n_channel 3817178f
 gray8_views_90ccw dc403b3
 gray8_views_90cw c6fc34de
 gray8_views_cropped 666252a
@@ -46,11 +64,11 @@
 gray8_views_subsampled 28286169
 gray8_views_transpose 366b8392
 mandelLuminosityGradient 4ebf3906
-packed565 175358bb
 planarrgb8_basic_red_x 7f6e24e7
 planarrgb8_basic_white_x e4aaa1d3
-planarrgb8_histogram_histogram 7b256ba4
-planarrgb8_views_0th_channel 1f48996f
+planarrgb8_histogram_histogram badcdd58
+planarrgb8_views_0th_k_channel 1f48996f
+planarrgb8_views_0th_n_channel 1f48996f
 planarrgb8_views_90ccw 8c4980e5
 planarrgb8_views_90cw e4c69665
 planarrgb8_views_cropped ff56b05e
@@ -64,8 +82,9 @@
 planarrgb8_views_transpose c9a890a0
 rgb8_basic_red_x 7f6e24e7
 rgb8_basic_white_x e4aaa1d3
-rgb8_histogram_histogram 7b256ba4
-rgb8_views_0th_channel 1f48996f
+rgb8_histogram_histogram badcdd58
+rgb8_views_0th_k_channel 1f48996f
+rgb8_views_0th_n_channel 1f48996f
 rgb8_views_90ccw 8c4980e5
 rgb8_views_90cw e4c69665
 rgb8_views_cropped ff56b05e
@@ -77,7 +96,8 @@
 rgb8_views_rot180 150f1206
 rgb8_views_subsampled 92439ee7
 rgb8_views_transpose c9a890a0
-subsampled_0th_channel 2c19afc1
+subsampled_0th_k_channel 2c19afc1
+subsampled_0th_n_channel 2c19afc1
 subsampled_90ccw d4649279
 subsampled_90cw e74f0f0e
 subsampled_cropped a5f07581
@@ -89,14 +109,15 @@
 subsampled_rot180 6059029b
 subsampled_subsampled 59aef23b
 subsampled_transpose ec4b368a
-virtual_0th_channel 79bca658
+virtual_0th_k_channel 79bca658
+virtual_0th_n_channel 79bca658
 virtual_90ccw 965db1f7
 virtual_90cw a81d80e3
 virtual_cropped ffb4af2c
 virtual_flipped_lr 9d1478c2
 virtual_flipped_ud 18dc9b78
 virtual_gray8 962f6f6f
-virtual_histogram 7b256ba4
+virtual_histogram 8deb06eb
 virtual_my_gray8 150bb50d
 virtual_original 927686d4
 virtual_rot180 4dee193e

Modified: trunk/libs/gil/test/image.cpp
==============================================================================
--- trunk/libs/gil/test/image.cpp (original)
+++ trunk/libs/gil/test/image.cpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -10,6 +10,12 @@
 // image_test.cpp :
 //
 
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4244) // conversion from 'gil::image<V,Alloc>::coord_t' to 'int', possible loss of data (visual studio compiler doesn't realize that the two types are the same)
+#pragma warning(disable : 4503) // decorated name length exceeded, name was truncated
+#endif
+
 #include <string>
 #include <vector>
 #include <iostream>
@@ -18,7 +24,6 @@
 #include <boost/lambda/bind.hpp>
 #include <boost/mpl/vector.hpp>
 #include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>
-
 #include <boost/crc.hpp>
 #include <fstream>
 
@@ -76,7 +81,7 @@
 // Models a Unary Function
 template <typename P> // Models PixelValueConcept
 struct mandelbrot_fn {
- typedef point2<ptrdiff_t> point_t;
+ typedef point2<std::ptrdiff_t> point_t;
 
     typedef mandelbrot_fn const_t;
     typedef P value_type;
@@ -128,8 +133,16 @@
     }
 }
 
+// A quick test whether a view is homogeneous
 
+template <typename Pixel>
+struct pixel_is_homogeneous : public mpl::true_ {};
 
+template <typename P, typename C, typename L>
+struct pixel_is_homogeneous<packed_pixel<P,C,L> > : public mpl::false_ {};
+
+template <typename View>
+struct view_is_homogeneous : public pixel_is_homogeneous<typename View::value_type> {};
 
 
 ////////////////////////////////////////////////////
@@ -155,6 +168,8 @@
 private:
     template <typename Img> void basic_test(const string& prefix);
     template <typename View> void view_transformations_test(const View& img_view, const string& prefix);
+ template <typename View> void homogeneous_view_transformations_test(const View& img_view, const string& prefix, mpl::true_);
+ template <typename View> void homogeneous_view_transformations_test(const View& img_view, const string& prefix, mpl::false_) {}
     template <typename View> void histogram_test(const View& img_view, const string& prefix);
     void virtual_view_test();
     void packed_image_test();
@@ -224,10 +239,10 @@
 void image_test::histogram_test(const View& img_view, const string& prefix) {
 // vector<int> histogram(255,0);
 // get_hist(cropped,histogram.begin());
- bits32s histogram[256];
+ unsigned char histogram[256];
     fill(histogram,histogram+256,0);
     get_hist(img_view,histogram);
- gray32sc_view_t hist_view=interleaved_view(256,1,(const gray32s_pixel_t*)histogram,256);
+ gray8c_view_t hist_view=interleaved_view(256,1,(const gray8_pixel_t*)histogram,256);
     check_view(hist_view,prefix+"histogram");
 }
 
@@ -245,9 +260,14 @@
     check_view(rotated90ccw_view(img_view),prefix+"90ccw");
     check_view(flipped_up_down_view(img_view),prefix+"flipped_ud");
     check_view(flipped_left_right_view(img_view),prefix+"flipped_lr");
- check_view(subsampled_view(img_view,typename View::point_t(2,1)),prefix+"subsampled");
- check_view(nth_channel_view(img_view,0),prefix+"0th_channel");
- check_view(kth_channel_view<0>(img_view),prefix+"0th_channel");
+ check_view(subsampled_view(img_view,typename View::point_t(2,1)),prefix+"subsampled");
+ check_view(kth_channel_view<0>(img_view),prefix+"0th_k_channel");
+ homogeneous_view_transformations_test(img_view, prefix, view_is_homogeneous<View>());
+}
+
+template <typename View>
+void image_test::homogeneous_view_transformations_test(const View& img_view, const string& prefix, mpl::true_) {
+ check_view(nth_channel_view(img_view,0),prefix+"0th_n_channel");
 }
 
 
@@ -273,15 +293,7 @@
 }
 
 void image_test::packed_image_test() {
- // define an rgb565 pixel
- typedef const packed_channel_reference<boost::uint16_t, 0,5,true> rgb565_channel0_t;
- typedef const packed_channel_reference<boost::uint16_t, 5,6,true> rgb565_channel1_t;
- typedef const packed_channel_reference<boost::uint16_t,11,5,true> rgb565_channel2_t;
-
- typedef heterogeneous_packed_pixel<uint16_t,
- mpl::vector3<rgb565_channel0_t,rgb565_channel1_t,rgb565_channel2_t>, rgb_layout_t> rgb565_pixel_t;
-
- typedef image<rgb565_pixel_t,false> rgb565_image_t;
+ typedef packed_image3_type<uint16_t, 5,6,5, rgb_layout_t>::type rgb565_image_t;
 
     rgb565_image_t img565(sample_view.dimensions());
     copy_and_convert_pixels(sample_view, view(img565));
@@ -328,6 +340,10 @@
     image_all_test<rgb8_planar_image_t>("planarrgb8_");
     image_all_test<gray8_image_t>("gray8_");
 
+ typedef const bit_aligned_pixel_reference<mpl::vector3_c<int,1,2,1>, bgr_layout_t, true> bgr121_ref_t;
+ typedef image<bgr121_ref_t,false> bgr121_image_t;
+ image_all_test<bgr121_image_t>("bgr121_");
+
     // TODO: Remove?
     view_transformations_test(subsampled_view(sample_view,point2<ptrdiff_t>(1,2)),"subsampled_");
     view_transformations_test(color_converted_view<gray8_pixel_t>(sample_view),"color_converted_");
@@ -504,6 +520,21 @@
     BOOST_STATIC_ASSERT((boost::is_same<derived_view_type<cmyk8c_planar_step_view_t>::type, cmyk8c_planar_step_view_t>::value));
     BOOST_STATIC_ASSERT((boost::is_same<derived_view_type<cmyk8c_planar_step_view_t, bits16, rgb_layout_t>::type, rgb16c_planar_step_view_t>::value));
     BOOST_STATIC_ASSERT((boost::is_same<derived_view_type<cmyk8c_planar_step_view_t, use_default, rgb_layout_t, mpl::false_, use_default, mpl::false_>::type, rgb8c_step_view_t>::value));
+
+ // test view get raw data (mostly compile-time test)
+ {
+ rgb8_image_t rgb8(100,100);
+ unsigned char* data=interleaved_view_get_raw_data(view(rgb8));
+ const unsigned char* cdata=interleaved_view_get_raw_data(const_view(rgb8));
+ error_if(data!=cdata);
+ }
+
+ {
+ rgb16s_planar_image_t rgb8(100,100);
+ short* data=planar_view_get_raw_data(view(rgb8),1);
+ const short* cdata=planar_view_get_raw_data(const_view(rgb8),1);
+ error_if(data!=cdata);
+ }
 }
 
 #ifdef BOOST_GIL_NO_IO
@@ -528,7 +559,9 @@
     static_checks();
 }
 
-
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
 
 
 

Modified: trunk/libs/gil/test/performance.cpp
==============================================================================
--- trunk/libs/gil/test/performance.cpp (original)
+++ trunk/libs/gil/test/performance.cpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -1,3 +1,15 @@
+/*
+ Copyright 2005-2007 Adobe Systems Incorporated
+
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+
+ See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+/*************************************************************************************************/
+
 /// \file
 /// \brief GIL performance test suite
 /// \date 2007 \n Last updated on February 12, 2007
@@ -47,9 +59,9 @@
 std::size_t width=1000, height=400;
 
 // macros for standard GIL views
-#define RGB_VIEW(T) image_view<byte_addressable_2d_locator<byte_addressable_step_iterator<pixel<T,rgb_layout_t>*> > >
-#define BGR_VIEW(T) image_view<byte_addressable_2d_locator<byte_addressable_step_iterator<pixel<T,bgr_layout_t>*> > >
-#define RGB_PLANAR_VIEW(T) image_view<byte_addressable_2d_locator<byte_addressable_step_iterator<planar_pixel_iterator<T*,rgb_t> > > >
+#define RGB_VIEW(T) image_view<memory_based_2d_locator<memory_based_step_iterator<pixel<T,rgb_layout_t>*> > >
+#define BGR_VIEW(T) image_view<memory_based_2d_locator<memory_based_step_iterator<pixel<T,bgr_layout_t>*> > >
+#define RGB_PLANAR_VIEW(T) image_view<memory_based_2d_locator<memory_based_step_iterator<planar_pixel_iterator<T*,rgb_t> > > >
 
 template <typename View, typename P>
 struct fill_gil_t {

Modified: trunk/libs/gil/test/pixel.cpp
==============================================================================
--- trunk/libs/gil/test/pixel.cpp (original)
+++ trunk/libs/gil/test/pixel.cpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -28,6 +28,8 @@
 #include <boost/gil/channel_algorithm.hpp>
 #include <boost/gil/color_convert.hpp>
 #include <boost/gil/gil_concept.hpp>
+#include <boost/gil/metafunctions.hpp>
+#include <boost/gil/bit_aligned_pixel_reference.hpp>
 
 // Testing pixel references and values, pixel operations, color conversion
 
@@ -239,34 +241,24 @@
    for_each<representative_pixels_t>(ccv1());
 }
 
-void test_packed_pixel() {
- // define an rgb565 pixel
- typedef const packed_channel_reference<boost::uint16_t, 0,5,true> rgb565_channel0_t;
- typedef const packed_channel_reference<boost::uint16_t, 5,6,true> rgb565_channel1_t;
- typedef const packed_channel_reference<boost::uint16_t,11,5,true> rgb565_channel2_t;
+void test_packed_pixel() {
+ typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,6,5>, rgb_layout_t>::type rgb565_pixel_t;
 
- typedef heterogeneous_packed_pixel<uint16_t,
- mpl::vector3<rgb565_channel0_t,rgb565_channel1_t,rgb565_channel2_t>, rgb_layout_t> rgb565_pixel_t;
     boost::function_requires<PixelValueConcept<rgb565_pixel_t> >();
     BOOST_STATIC_ASSERT((sizeof(rgb565_pixel_t)==2));
 
     // define a bgr556 pixel
- typedef const packed_channel_reference<boost::uint16_t, 0,5,true> bgr556_channel0_t;
- typedef const packed_channel_reference<boost::uint16_t, 5,6,true> bgr556_channel1_t;
- typedef const packed_channel_reference<boost::uint16_t,11,5,true> bgr556_channel2_t;
-
- typedef heterogeneous_packed_pixel<uint16_t,
- mpl::vector3<bgr556_channel0_t,bgr556_channel1_t,bgr556_channel2_t>, bgr_layout_t> bgr556_pixel_t;
- boost::function_requires<PixelValueConcept<rgb565_pixel_t> >();
+ typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,6,5>, bgr_layout_t>::type bgr556_pixel_t;
+ boost::function_requires<PixelValueConcept<bgr556_pixel_t> >();
 
     // Create a zero packed pixel and a full regular unpacked pixel.
     rgb565_pixel_t r565;//((uint16_t)0);
     rgb8_pixel_t rgb_full(255,255,255);
 
     // Convert all channels of the unpacked pixel to the packed one & assert the packed one is full
- get_color(r565,red_t()) = channel_convert<rgb565_channel0_t>(get_color(rgb_full,red_t()));
- get_color(r565,green_t()) = channel_convert<rgb565_channel1_t>(get_color(rgb_full,green_t()));
- get_color(r565,blue_t()) = channel_convert<rgb565_channel2_t>(get_color(rgb_full,blue_t()));
+ get_color(r565,red_t()) = channel_convert<kth_element_type<rgb565_pixel_t, 0>::type>(get_color(rgb_full,red_t()));
+ get_color(r565,green_t()) = channel_convert<kth_element_type<rgb565_pixel_t, 1>::type>(get_color(rgb_full,green_t()));
+ get_color(r565,blue_t()) = channel_convert<kth_element_type<rgb565_pixel_t, 2>::type>(get_color(rgb_full,blue_t()));
     error_if(r565 != rgb565_pixel_t((uint16_t)65535));
     
     // rgb565 is compatible with bgr556. Test interoperability
@@ -274,9 +266,36 @@
 
     do_basic_test<value_core<rgb565_pixel_t,0>, value_core<bgr556_pixel_t,1> >(r565).test_heterogeneous();
 
- // Color conversion works, but there are warnings
- // color_convert(r565,rgb_full);
- // color_convert(rgb_full,r565);
+ color_convert(r565,rgb_full);
+ color_convert(rgb_full,r565);
+
+ // Test bit-aligned pixel reference
+ typedef const bit_aligned_pixel_reference<boost::mpl::vector3_c<int,1,2,1>, bgr_layout_t, true> bgr121_ref_t;
+ typedef const bit_aligned_pixel_reference<boost::mpl::vector3_c<int,1,2,1>, rgb_layout_t, true> rgb121_ref_t;
+ typedef rgb121_ref_t::value_type rgb121_pixel_t;
+ rgb121_pixel_t p121;
+ do_basic_test<reference_core<bgr121_ref_t,0>, reference_core<rgb121_ref_t,1> >(p121).test_heterogeneous();
+ do_basic_test<value_core<rgb121_pixel_t,0>, reference_core<rgb121_ref_t,1> >(p121).test_heterogeneous();
+
+ BOOST_STATIC_ASSERT((pixel_reference_is_proxy<rgb8_planar_ref_t>::value));
+ BOOST_STATIC_ASSERT((pixel_reference_is_proxy<bgr121_ref_t>::value));
+
+ BOOST_STATIC_ASSERT(!(pixel_reference_is_proxy<rgb8_pixel_t>::value));
+ BOOST_STATIC_ASSERT(!(pixel_reference_is_proxy<rgb8_pixel_t&>::value));
+ BOOST_STATIC_ASSERT(!(pixel_reference_is_proxy<const rgb8_pixel_t&>::value));
+
+ BOOST_STATIC_ASSERT( (pixel_reference_is_mutable< rgb8_pixel_t&>::value));
+ BOOST_STATIC_ASSERT(!(pixel_reference_is_mutable<const rgb8_pixel_t&>::value));
+
+ BOOST_STATIC_ASSERT((pixel_reference_is_mutable<const rgb8_planar_ref_t&>::value));
+ BOOST_STATIC_ASSERT((pixel_reference_is_mutable< rgb8_planar_ref_t >::value));
+
+ BOOST_STATIC_ASSERT(!(pixel_reference_is_mutable<const rgb8c_planar_ref_t&>::value));
+ BOOST_STATIC_ASSERT(!(pixel_reference_is_mutable< rgb8c_planar_ref_t >::value));
+
+ BOOST_STATIC_ASSERT( (pixel_reference_is_mutable<bgr121_ref_t>::value));
+ BOOST_STATIC_ASSERT(!(pixel_reference_is_mutable<bgr121_ref_t::const_reference>::value));
+
 }
 
 void test_pixel() {

Modified: trunk/libs/gil/test/pixel_iterator.cpp
==============================================================================
--- trunk/libs/gil/test/pixel_iterator.cpp (original)
+++ trunk/libs/gil/test/pixel_iterator.cpp 2007-09-17 04:12:19 EDT (Mon, 17 Sep 2007)
@@ -16,10 +16,13 @@
 #include <boost/gil/pixel_iterator.hpp>
 #include <boost/gil/pixel_iterator_adaptor.hpp>
 #include <boost/gil/planar_pixel_iterator.hpp>
+#include <boost/gil/bit_aligned_pixel_iterator.hpp>
+#include <boost/gil/packed_pixel.hpp>
 #include <boost/gil/iterator_from_2d.hpp>
 #include <boost/gil/step_iterator.hpp>
 #include <boost/gil/typedefs.hpp>
 #include <boost/gil/color_convert.hpp>
+#include <boost/mpl/vector.hpp>
 
 using namespace boost::gil;
 using namespace std;
@@ -38,7 +41,15 @@
     boost::function_requires<MutableStepIteratorConcept<cmyk8_planar_step_ptr_t> >();
     boost::function_requires<StepIteratorConcept<gray8c_step_ptr_t> >();
 
- boost::function_requires<MutablePixelLocatorConcept<byte_addressable_2d_locator<rgb8_step_ptr_t> > >();
+ boost::function_requires<MutablePixelLocatorConcept<memory_based_2d_locator<rgb8_step_ptr_t> > >();
+
+ typedef const bit_aligned_pixel_reference<boost::mpl::vector3_c<int,1,2,1>, bgr_layout_t, true> bgr121_ref_t;
+ typedef bit_aligned_pixel_iterator<bgr121_ref_t> bgr121_ptr_t;
+
+ boost::function_requires<MutablePixelIteratorConcept<bgr121_ptr_t> >();
+ boost::function_requires<PixelBasedConcept<bgr121_ptr_t> >();
+ boost::function_requires<MemoryBasedIteratorConcept<bgr121_ptr_t> >();
+ boost::function_requires<HasDynamicXStepTypeConcept<bgr121_ptr_t> >();
 
 // TEST dynamic_step_t
     BOOST_STATIC_ASSERT(( boost::is_same<cmyk16_step_ptr_t,dynamic_x_step_type<cmyk16_step_ptr_t>::type>::value ));
@@ -69,10 +80,32 @@
     BOOST_STATIC_ASSERT(iterator_is_step< rgb2gray_step_ptr1 >::value);
     BOOST_STATIC_ASSERT(( boost::is_same< rgb2gray_step_ptr1, dynamic_x_step_type<rgb2gray_step_ptr1>::type >::value));
 
- typedef byte_addressable_step_iterator<dereference_iterator_adaptor<rgb8_ptr_t, ccv_rgb_g_fn> > rgb2gray_step_ptr2;
+ typedef memory_based_step_iterator<dereference_iterator_adaptor<rgb8_ptr_t, ccv_rgb_g_fn> > rgb2gray_step_ptr2;
     BOOST_STATIC_ASSERT(iterator_is_step< rgb2gray_step_ptr2 >::value);
     BOOST_STATIC_ASSERT(( boost::is_same< rgb2gray_step_ptr2, dynamic_x_step_type<rgb2gray_step_ptr2>::type >::value));
     make_step_iterator(rgb2gray_step_ptr2(),2);
+
+// bit_aligned iterators test
+
+ // Mutable reference to a BGR232 pixel
+ typedef const bit_aligned_pixel_reference<boost::mpl::vector3_c<unsigned,2,3,2>, bgr_layout_t, true> bgr232_ref_t;
+
+ // A mutable iterator over BGR232 pixels
+ typedef bit_aligned_pixel_iterator<bgr232_ref_t> bgr232_ptr_t;
+
+ // BGR232 pixel value. It is a packed_pixel of size 1 byte. (The last bit is unused)
+ typedef std::iterator_traits<bgr232_ptr_t>::value_type bgr232_pixel_t;
+ BOOST_STATIC_ASSERT((sizeof(bgr232_pixel_t)==1));
+
+ bgr232_pixel_t red(0,0,3); // = 0RRGGGBB, = 01100000
+
+ // a buffer of 7 bytes fits exactly 8 BGR232 pixels.
+ unsigned char pix_buffer[7];
+ std::fill(pix_buffer,pix_buffer+7,0);
+ bgr232_ptr_t pix_it(&pix_buffer[0],0); // start at bit 0 of the first pixel
+ for (int i=0; i<8; ++i) {
+ *pix_it++ = red;
+ }
 }
 
 // TODO: Make better tests. Use some code from below.
@@ -91,17 +124,17 @@
     rgba8_pixel_t rgba8;
 
     rgb8_ptr_t ptr1=&rgb8;
- byte_advance(ptr1, 3);
- const rgb8_ptr_t ptr2=byte_advanced(ptr1,10);
+ memunit_advance(ptr1, 3);
+ const rgb8_ptr_t ptr2=memunit_advanced(ptr1,10);
 
- byte_distance(ptr1,ptr2);
- const rgb8_pixel_t& ref=byte_advanced_ref(ptr1,10); ignore_unused_variable_warning(ref);
+ memunit_distance(ptr1,ptr2);
+ const rgb8_pixel_t& ref=memunit_advanced_ref(ptr1,10); ignore_unused_variable_warning(ref);
 
     rgb8_planar_ptr_t planarPtr1(&rgb8);
     rgb8_planar_ptr_t planarPtr2(&rgb8);
- byte_advance(planarPtr1,10);
- byte_distance(planarPtr1,planarPtr2);
- rgb8_planar_ptr_t planarPtr3=byte_advanced(planarPtr1,10);
+ memunit_advance(planarPtr1,10);
+ memunit_distance(planarPtr1,planarPtr2);
+ rgb8_planar_ptr_t planarPtr3=memunit_advanced(planarPtr1,10);
 
 // planarPtr2=&rgba8;
 
@@ -112,7 +145,7 @@
 
     assert(*(planarPtr1+5)==planarPtr1[5]);
 
- rgb8_planar_ref_t planarRef=byte_advanced_ref(planarPtr1,10);
+ rgb8_planar_ref_t planarRef=memunit_advanced_ref(planarPtr1,10);
 
     rgb8_step_ptr_t stepIt(&rgb8,5);
     stepIt++;
@@ -122,7 +155,7 @@
     rgb8_step_ptr_t stepIt3(&rgb8,5);
 
     rgb8_pixel_t& ref1=stepIt3[5];
-// bool v=boost::is_POD<iterator_traits<byte_addressable_step_iterator<rgb8_ptr_t> >::value_type>::value;
+// bool v=boost::is_POD<iterator_traits<memory_based_step_iterator<rgb8_ptr_t> >::value_type>::value;
 // v=boost::is_POD<rgb8_pixel_t>::value;
 // v=boost::is_POD<int>::value;
 
@@ -177,12 +210,12 @@
 
 
 
- // byte_addressable_step_iterator<rgb8_pixel_t> stepIt3Err=stepIt+10; // error: non-const from const iterator
+ // memory_based_step_iterator<rgb8_pixel_t> stepIt3Err=stepIt+10; // error: non-const from const iterator
 
- byte_addressable_2d_locator<rgb8_step_ptr_t> xy_locator(ptr,27);
+ memory_based_2d_locator<rgb8_step_ptr_t> xy_locator(ptr,27);
 
     xy_locator.x()++;
-// byte_addressable_step_iterator<rgb8_pixel_t>& yit=xy_locator.y();
+// memory_based_step_iterator<rgb8_pixel_t>& yit=xy_locator.y();
     xy_locator.y()++;
     xy_locator+=point2<std::ptrdiff_t>(3,4);
     // *xy_locator=(xy_locator(-1,0)+xy_locator(0,1))/2;
@@ -252,7 +285,7 @@
     *rgb8_pptr=rgb8;
     *rgb8_pptr=crgb8;
 
- byte_advance(rgb8_pptr,3);
- byte_advance(rgb8_pptr,-3);
+ memunit_advance(rgb8_pptr,3);
+ memunit_advance(rgb8_pptr,-3);
 }
 */


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk