$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r65879 - sandbox/gil/boost/gil
From: dsaritz_at_[hidden]
Date: 2010-10-10 12:42:08
Author: psiha
Date: 2010-10-10 12:42:02 EDT (Sun, 10 Oct 2010)
New Revision: 65879
URL: http://svn.boost.org/trac/boost/changeset/65879
Log:
Adding base GIL files (from the trunk) with various local optimizations.
Added:
   sandbox/gil/boost/gil/algorithm.hpp   (contents, props changed)
   sandbox/gil/boost/gil/color_convert.hpp   (contents, props changed)
   sandbox/gil/boost/gil/image.hpp   (contents, props changed)
   sandbox/gil/boost/gil/locator.hpp   (contents, props changed)
   sandbox/gil/boost/gil/utilities.hpp   (contents, props changed)
Added: sandbox/gil/boost/gil/algorithm.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/algorithm.hpp	2010-10-10 12:42:02 EDT (Sun, 10 Oct 2010)
@@ -0,0 +1,1029 @@
+/*
+    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_ALGORITHM_HPP
+#define GIL_ALGORITHM_HPP
+
+#include <cassert>
+#include <cstddef>
+#include <cstring>
+#include <algorithm>
+#include <iterator>
+#include <memory>
+#include <typeinfo>
+#include "gil_config.hpp"
+#include "gil_concept.hpp"
+#include "color_base_algorithm.hpp"
+#include "image_view.hpp"
+#include "image_view_factory.hpp"
+#include "bit_aligned_pixel_iterator.hpp"
+
+////////////////////////////////////////////////////////////////////////////////////////
+/// \file               
+/// \brief Some basic STL-style algorithms when applied to image views
+/// \author Lubomir Bourdev and Hailin Jin \n
+///         Adobe Systems Incorporated
+/// \date   2005-2008 \n Last updated on March 12, 2008
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+//#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)
+//#endif
+
+namespace boost { namespace gil {
+
+//forward declarations
+template <typename ChannelPtr, typename ColorSpace>
+struct planar_pixel_iterator;
+template <typename Iterator>
+class memory_based_step_iterator;
+template <typename StepIterator>
+class memory_based_2d_locator;
+
+// a tag denoting incompatible arguments
+struct error_t {};
+
+/// \defgroup ImageViewSTLAlgorithms STL-like Algorithms
+/// \ingroup ImageViewAlgorithm
+/// \brief Image view-equivalents of STL algorithms
+///
+/// Image views provide 1D iteration of their pixels via \p begin() and \p end() methods,
+/// which makes it possible to use STL algorithms with them. However, using nested loops
+/// over X and Y is in many cases more efficient. The algorithms in this section resemble
+/// STL algorithms, but they abstract away the nested loops and take views (as opposed to ranges) as input.
+///
+/// Most algorithms check whether the image views are 1D-traversable. A 1D-traversable image view has no gaps
+/// at the end of the rows. In other words, if an x_iterator of that view is advanced past the last pixel in a row
+/// it will move to the first pixel of the next row. When image views are 1D-traversable, the algorithms use
+/// a single loop and run more efficiently. If one or more of the input views are not 1D-traversable, the algorithms
+/// fall-back to an X-loop nested inside a Y-loop.
+///
+/// The algorithms typically delegate the work to their corresponding STL algorithms. For example, \p copy_pixels calls
+/// \p std::copy either for each row, or, when the images are 1D-traversable, once for all pixels.
+///
+/// In addition, overloads are sometimes provided for the STL algorithms. For example, std::copy for planar iterators
+/// is overloaded to perform \p std::copy for each of the planes. \p std::copy over bitwise-copiable pixels results in
+/// std::copy over unsigned char, which STL typically implements via \p memmove.
+///
+/// As a result \p copy_pixels may result in a single call to \p memmove for interleaved 1D-traversable views, 
+/// or one per each plane of planar 1D-traversable views, or one per each row of interleaved non-1D-traversable images, etc.
+
+
+/// \defgroup STLOptimizations  Performance overloads of STL algorithms
+/// \ingroup ImageViewAlgorithm
+/// \brief overloads of STL algorithms allowing more efficient implementation when used with GIL constructs
+
+/// \brief A generic binary operation on views
+/// \ingroup ImageViewSTLAlgorithms
+///
+/// Use this class as a convenience superclass when defining an operation for any image views.
+/// Many operations have different behavior when the two views are compatible. This class checks
+/// for compatibility and invokes apply_compatible(V1,V2) or apply_incompatible(V1,V2) of the subclass.
+/// You must provide apply_compatible(V1,V2) method in your subclass, but apply_incompatible(V1,V2)
+/// is not required and the default throws std::bad_cast.
+template <typename Derived, typename Result=void>
+struct binary_operation_obj {
+    typedef Result result_type;
+
+    template <typename V1, typename V2> GIL_FORCEINLINE
+    result_type operator()(const std::pair<const V1*,const V2*>& p) const {
+        return apply(*p.first, *p.second, typename views_are_compatible<V1,V2>::type());
+    }
+
+    template <typename V1, typename V2> GIL_FORCEINLINE
+    result_type operator()(const V1& v1, const V2& v2) const {
+        return apply(v1, v2, typename views_are_compatible<V1,V2>::type());
+    }
+
+    result_type operator()(const error_t&) const { throw std::bad_cast(); }
+private:
+
+    // dispatch from apply overload to a function with distinct name
+    template <typename V1, typename V2>
+    GIL_FORCEINLINE result_type apply(const V1& v1, const V2& v2, mpl::false_) const {
+        return ((const Derived*)this)->apply_incompatible(v1,v2);
+    }
+
+    // dispatch from apply overload to a function with distinct name
+    template <typename V1, typename V2>
+    GIL_FORCEINLINE result_type apply(const V1& v1, const V2& v2, mpl::true_) const {
+        return ((const Derived*)this)->apply_compatible(v1,v2);
+    }
+
+    // function with distinct name - it can be overloaded by subclasses
+    template <typename V1, typename V2>
+    GIL_FORCEINLINE result_type apply_incompatible(const V1& v1, const V2& v2) const {
+        throw std::bad_cast();
+    }
+};
+} }  // namespace boost::gil
+
+//////////////////////////////////////////////////////////////////////////////////////
+///
+/// std::copy and gil::copy_pixels
+///
+//////////////////////////////////////////////////////////////////////////////////////
+
+/// \defgroup ImageViewSTLAlgorithmsCopyPixels copy_pixels
+/// \ingroup ImageViewSTLAlgorithms
+/// \brief std::copy for image views
+
+namespace std {
+
+/// \ingroup STLOptimizations
+/// \brief Copy when both src and dst are interleaved and of the same type can be just memmove
+template<typename T, typename Cs> 
+GIL_FORCEINLINE boost::gil::pixel<T,Cs>* 
+copy(boost::gil::pixel<T,Cs>* first, boost::gil::pixel<T,Cs>* last, 
+     boost::gil::pixel<T,Cs>* dst) { 
+    return (boost::gil::pixel<T,Cs>*)std::copy((unsigned char*)first,(unsigned char*)last, (unsigned char*)dst);
+}
+
+/// \ingroup STLOptimizations
+/// \brief Copy when both src and dst are interleaved and of the same type can be just memmove
+template<typename T, typename Cs> 
+GIL_FORCEINLINE boost::gil::pixel<T,Cs>* 
+copy(const boost::gil::pixel<T,Cs>* first, const boost::gil::pixel<T,Cs>* last, 
+     boost::gil::pixel<T,Cs>* dst) { 
+    return (boost::gil::pixel<T,Cs>*)std::copy((unsigned char*)first,(unsigned char*)last, (unsigned char*)dst);
+}
+} // namespace std
+
+namespace boost { namespace gil {
+namespace detail {
+template <typename I, typename O> struct copy_fn { 
+    GIL_FORCEINLINE I operator()(I first, I last, O dst) const { return std::copy(first,last,dst); } 
+};
+} // namespace detail
+} }  // namespace boost::gil
+
+namespace std {
+/// \ingroup STLOptimizations
+/// \brief Copy when both src and dst are planar pointers is copy for each channel
+template<typename Cs, typename IC1, typename IC2> GIL_FORCEINLINE
+boost::gil::planar_pixel_iterator<IC2,Cs> copy(boost::gil::planar_pixel_iterator<IC1,Cs> first, boost::gil::planar_pixel_iterator<IC1,Cs> last, boost::gil::planar_pixel_iterator<IC2,Cs> dst) { 
+    boost::gil::gil_function_requires<boost::gil::ChannelsCompatibleConcept<typename std::iterator_traits<IC1>::value_type,typename std::iterator_traits<IC2>::value_type> >();
+    static_for_each(first,last,dst,boost::gil::detail::copy_fn<IC1,IC2>());
+    return dst+(last-first);
+}
+} // namespace std
+
+namespace boost { namespace gil {
+namespace detail {
+/// Does a copy-n. If the inputs contain image iterators, performs a copy at each row using the row iterators
+/// \ingroup CopyPixels
+template <typename I, typename O>
+struct copier_n {
+    GIL_FORCEINLINE void operator()(I src, typename std::iterator_traits<I>::difference_type n, O dst) const { std::copy(src,src+n, dst); }
+};
+
+/// Source range is delimited by image iterators
+template <typename IL, typename O>  // IL Models ConstPixelLocatorConcept, O Models PixelIteratorConcept
+struct copier_n<iterator_from_2d<IL>,O> {
+    typedef typename std::iterator_traits<iterator_from_2d<IL> >::difference_type diff_t;
+    GIL_FORCEINLINE void operator()(iterator_from_2d<IL> src, diff_t n, O dst) const {
+        gil_function_requires<PixelLocatorConcept<IL> >();
+        gil_function_requires<MutablePixelIteratorConcept<O> >();
+        while (n>0) {
+            typedef typename iterator_from_2d<IL>::difference_type diff_t;
+            diff_t l=src.width()-src.x_pos();
+            diff_t numToCopy=(n<l ? n:l);
+            detail::copy_n(src.x(), numToCopy, dst);
+            dst+=numToCopy;
+            src+=numToCopy;
+            n-=numToCopy;
+        }
+    }
+};
+
+/// Destination range is delimited by image iterators
+template <typename I, typename OL> // I Models ConstPixelIteratorConcept, OL Models PixelLocatorConcept
+struct copier_n<I,iterator_from_2d<OL> > {
+    typedef typename std::iterator_traits<I>::difference_type diff_t;
+    GIL_FORCEINLINE void operator()(I src, diff_t n, iterator_from_2d<OL> dst) const {
+        gil_function_requires<PixelIteratorConcept<I> >();
+        gil_function_requires<MutablePixelLocatorConcept<OL> >();
+        while (n>0) {
+            diff_t l=dst.width()-dst.x_pos();
+            diff_t numToCopy=(n<l ? n:l);
+            detail::copy_n(src, numToCopy, dst.x());
+            dst+=numToCopy;
+            src+=numToCopy;
+            n-=numToCopy;
+        }
+    }
+};
+
+/// Both source and destination ranges are delimited by image iterators
+template <typename IL, typename OL>
+struct copier_n<iterator_from_2d<IL>,iterator_from_2d<OL> > {
+   typedef typename iterator_from_2d<IL>::difference_type diff_t;
+   GIL_FORCEINLINE void operator()(iterator_from_2d<IL> src, diff_t n, iterator_from_2d<OL> dst) const {
+        gil_function_requires<PixelLocatorConcept<IL> >();
+        gil_function_requires<MutablePixelLocatorConcept<OL> >();
+        if (src.x_pos()!=dst.x_pos() || src.width()!=dst.width()) {
+            while(n-->0) {
+                *dst++=*src++;
+            }
+        }
+        while (n>0) {
+            diff_t l=dst.width()-dst.x_pos();
+            diff_t numToCopy=(n<l ? n : l);
+            detail::copy_n(src.x(), numToCopy, dst.x());
+            dst+=numToCopy;
+            src+=numToCopy;
+            n-=numToCopy;
+        }
+    }
+};
+
+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())
+            copier_n<src_x_iterator,dst_x_iterator>()(first.x(),n, dst.x());
+        else
+            copier_n<src_x_iterator,DstIterator >()(first.x(),n, dst);
+    } else {
+        if (dst.is_1d_traversable())
+            copier_n<SrcIterator,dst_x_iterator>()(first,n, dst.x());
+        else
+            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 {
+
+
+/// \ingroup ImageViewSTLAlgorithmsCopyPixels
+/// \brief std::copy for image views
+template <typename View1, typename View2> GIL_FORCEINLINE
+void copy_pixels(const View1& src, const View2& dst) { 
+    assert(src.dimensions()==dst.dimensions());
+    detail::copy_with_2d_iterators(src.begin(),src.end(),dst.begin());
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+///
+/// copy_and_convert_pixels
+///
+//////////////////////////////////////////////////////////////////////////////////////
+
+/// \defgroup ImageViewSTLAlgorithmsCopyAndConvertPixels copy_and_convert_pixels
+/// \ingroup ImageViewSTLAlgorithms
+/// \brief copies src view into dst view, color converting if necessary.
+///
+/// Versions taking static and runtime views are provided. Versions taking user-defined color convered are provided.
+
+namespace detail {
+template <typename CC>
+class copy_and_convert_pixels_fn : public binary_operation_obj<copy_and_convert_pixels_fn<CC> > {
+private:
+    CC _cc;
+public:
+    typedef typename binary_operation_obj<copy_and_convert_pixels_fn<CC> >::result_type result_type;
+    copy_and_convert_pixels_fn() {}
+    copy_and_convert_pixels_fn(CC cc_in) : _cc(cc_in) {}
+   // when the two color spaces are incompatible, a color conversion is performed
+    template <typename V1, typename V2> GIL_FORCEINLINE 
+    result_type apply_incompatible(const V1& src, const V2& dst) const {
+        copy_pixels(color_converted_view<typename V2::value_type>(src,_cc),dst);
+    }
+
+    // If the two color spaces are compatible, copy_and_convert is just copy
+    template <typename V1, typename V2> GIL_FORCEINLINE 
+    result_type apply_compatible(const V1& src, const V2& dst) const {
+         copy_pixels(src,dst);
+    }
+};
+} // namespace detail
+
+/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
+template <typename V1, typename V2,typename CC> 
+GIL_FORCEINLINE 
+void copy_and_convert_pixels(const V1& src, const V2& dst,CC cc) { 
+    detail::copy_and_convert_pixels_fn<CC> ccp(cc);
+    ccp(src,dst);
+}
+
+struct default_color_converter;
+
+/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
+template <typename View1, typename View2> 
+GIL_FORCEINLINE 
+void copy_and_convert_pixels(const View1& src, const View2& dst) { 
+    detail::copy_and_convert_pixels_fn<default_color_converter> ccp;
+    ccp(src,dst);
+}
+
+} }  // namespace boost::gil
+
+//////////////////////////////////////////////////////////////////////////////////////
+//
+// std::fill and gil::fill_pixels
+//
+//////////////////////////////////////////////////////////////////////////////////////
+
+/// \defgroup ImageViewSTLAlgorithmsFillPixels fill_pixels
+/// \ingroup ImageViewSTLAlgorithms
+/// \brief std::fill for image views
+
+
+namespace std {
+/// \ingroup STLOptimizations
+/// \brief std::fill(I,I,V) with I being a iterator_from_2d
+///
+/// Invoked when one calls std::fill(I,I,V) with I being a iterator_from_2d (which is
+/// a 1D iterator over the pixels in an image). For contiguous images (i.e. images that have
+/// no alignment gap at the end of each row) it is more efficient to use the underlying 
+/// pixel iterator that does not check for the end of rows. For non-contiguous images fill
+/// resolves to fill of each row using the underlying pixel iterator, which is still faster
+template <typename IL, typename V>
+void fill(boost::gil::iterator_from_2d<IL> first, boost::gil::iterator_from_2d<IL> last, const V& val) {
+    boost::gil::gil_function_requires<boost::gil::MutablePixelLocatorConcept<IL> >();
+    if (first.is_1d_traversable()) {
+        std::fill(first.x(), last.x(), val);
+    } else {
+        // fill row by row
+        std::ptrdiff_t n=last-first;
+        while (n>0) {
+            std::ptrdiff_t numToDo=std::min<const std::ptrdiff_t>(n,(std::ptrdiff_t)(first.width()-first.x_pos()));
+            fill_n(first.x(), numToDo, val);
+            first+=numToDo;
+            n-=numToDo;
+        }
+    }
+} 
+} // namespace std
+
+namespace boost { namespace gil {
+
+namespace detail {
+/// struct to do std::fill
+struct std_fill_t {
+    template <typename It, typename P>
+    void operator()(It first, It last, const P& p_in) {
+        std::fill(first,last,p_in);
+    }
+};
+/// std::fill for planar iterators
+template <typename It, typename P>
+GIL_FORCEINLINE 
+void fill_aux(It first, It last, const P& p, mpl::true_) {
+    static_for_each(first,last,p,std_fill_t());
+}
+/// std::fill for interleaved iterators
+template <typename It, typename P>
+GIL_FORCEINLINE 
+void fill_aux(It first, It last, const P& p,mpl::false_) {
+    std::fill(first,last,p);
+}
+} // namespace detail
+
+/// \ingroup ImageViewSTLAlgorithmsFillPixels
+/// \brief std::fill for image views
+template <typename View, typename Value> GIL_FORCEINLINE 
+void fill_pixels(const View& img_view, const Value& val) {
+    if (img_view.is_1d_traversable())
+        detail::fill_aux(img_view.begin().x(), img_view.end().x(), 
+                 val,is_planar<View>());
+    else
+        for (std::ptrdiff_t y=0; y<img_view.height(); ++y)
+            detail::fill_aux(img_view.row_begin(y),img_view.row_end(y),
+                     val,is_planar<View>());
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+///
+/// destruct_pixels
+///
+//////////////////////////////////////////////////////////////////////////////////////
+
+/// \defgroup ImageViewSTLAlgorithmsDestructPixels destruct_pixels
+/// \ingroup ImageViewSTLAlgorithms
+/// \brief invokes the destructor on every pixel of an image view
+
+
+namespace detail {
+
+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;
+    while (first!=last) {
+        first->~value_t();
+        ++first;
+    }
+}
+template <typename It> GIL_FORCEINLINE
+void destruct_range_impl(It, It, 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); }
+};
+
+/// destruct for planar iterators
+template <typename It>
+GIL_FORCEINLINE 
+void destruct_aux(It first, It last, mpl::true_) {
+    static_for_each(first,last,std_destruct_t());
+}
+/// destruct for interleaved iterators
+template <typename It>
+GIL_FORCEINLINE 
+void destruct_aux(It first, It last, mpl::false_) {
+    destruct_range(first,last);
+}
+
+} // namespace detail
+
+/// \ingroup ImageViewSTLAlgorithmsDestructPixels
+/// \brief Invokes the in-place destructor on every pixel of the view
+template <typename View> GIL_FORCEINLINE 
+void destruct_pixels(const View& img_view) {
+    // Implementation note:
+    //    The 'skip' in/through destruct_aux() is not enough as MSVC++ 10 still
+    // generates code for the bloated img_view.end() call.
+    //                                        (10.10.2010.) (Domagoj Saric)
+    if ( view_is_basic<View>::value )
+        return;
+    if (img_view.is_1d_traversable()) 
+        detail::destruct_aux(img_view.begin().x(), img_view.end().x(), 
+                                       is_planar<View>());
+    else
+        for (std::ptrdiff_t y=0; y<img_view.height(); ++y)
+            detail::destruct_aux(img_view.row_begin(y),img_view.row_end(y),
+                                           is_planar<View>());
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+///
+/// uninitialized_fill_pixels
+///
+//////////////////////////////////////////////////////////////////////////////////////
+
+/// \defgroup ImageViewSTLAlgorithmsUninitializedFillPixels uninitialized_fill_pixels
+/// \ingroup ImageViewSTLAlgorithms
+/// \brief std::uninitialized_fill for image views
+
+
+namespace detail {
+
+/// std::uninitialized_fill for planar iterators
+/// If an exception is thrown destructs any in-place copy-constructed objects
+template <typename It, typename P>
+GIL_FORCEINLINE 
+void uninitialized_fill_aux(It first, It last,
+                            const P& p, mpl::true_) {
+    int channel=0;
+    try {
+        typedef typename std::iterator_traits<It>::value_type pixel_t;
+        while (channel < num_channels<pixel_t>::value) {
+            std::uninitialized_fill(dynamic_at_c(first,channel), dynamic_at_c(last,channel), 
+                                    dynamic_at_c(p,channel));
+            ++channel;
+        }
+    } catch (...) {
+        for (int c=0; c<channel; ++c)
+            destruct_range(dynamic_at_c(first,c), dynamic_at_c(last,c));
+        throw;
+    }
+}
+
+/// std::uninitialized_fill for interleaved iterators
+/// If an exception is thrown destructs any in-place copy-constructed objects
+template <typename It, typename P>
+GIL_FORCEINLINE 
+void uninitialized_fill_aux(It first, It last,
+                            const P& p,mpl::false_) {
+    std::uninitialized_fill(first,last,p);
+}
+
+} // namespace detail
+
+/// \ingroup ImageViewSTLAlgorithmsUninitializedFillPixels
+/// \brief std::uninitialized_fill for image views.
+/// Does not support planar heterogeneous views.
+/// If an exception is thrown destructs any in-place copy-constructed pixels
+template <typename View, typename Value> 
+void uninitialized_fill_pixels(const View& img_view, const Value& val) {
+    if (img_view.is_1d_traversable()) 
+        detail::uninitialized_fill_aux(img_view.begin().x(), img_view.end().x(), 
+                                       val,is_planar<View>());
+    else {
+        typename View::y_coord_t y;
+        try {
+            for (y=0; y<img_view.height(); ++y)
+                detail::uninitialized_fill_aux(img_view.row_begin(y),img_view.row_end(y),
+                                               val,is_planar<View>());
+        } catch(...) {
+            for (typename View::y_coord_t y0=0; y0<y; ++y0)
+                detail::destruct_aux(img_view.row_begin(y0),img_view.row_end(y0), is_planar<View>());
+            throw;
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+///
+/// default_construct_pixels
+///
+//////////////////////////////////////////////////////////////////////////////////////
+
+/// \defgroup ImageViewSTLAlgorithmsDefaultConstructPixels default_construct_pixels
+/// \ingroup ImageViewSTLAlgorithms
+/// \brief invokes the default constructor on every pixel of an image view
+
+namespace detail {
+
+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;
+    It first1=first;
+    try {
+        while (first!=last) {
+            new (first) value_t();
+            ++first;
+        }
+    } catch (...) {
+        destruct_range(first1,first);
+        throw;
+    }
+}
+
+template <typename It> GIL_FORCEINLINE 
+void default_construct_range_impl(It, It, 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>
+GIL_FORCEINLINE 
+void default_construct_aux(It first, It last, mpl::true_) {
+    int channel=0;
+    try {
+        typedef typename std::iterator_traits<It>::value_type pixel_t;
+        while (channel < num_channels<pixel_t>::value) {
+            default_construct_range(dynamic_at_c(first,channel), dynamic_at_c(last,channel));
+            ++channel;
+        }
+    } catch (...) {
+        for (int c=0; c<channel; ++c)
+            destruct_range(dynamic_at_c(first,c), dynamic_at_c(last,c));
+        throw;
+    }
+}
+
+/// uninitialized_default_construct for interleaved iterators
+template <typename It>
+GIL_FORCEINLINE 
+void default_construct_aux(It first, It last, mpl::false_) {
+    default_construct_range(first,last);
+}
+
+template <typename View, bool IsPlanar>
+struct has_trivial_pixel_constructor : public boost::has_trivial_constructor<typename View::value_type> {};
+template <typename View>
+struct has_trivial_pixel_constructor<View, true> : public boost::has_trivial_constructor<typename channel_type<View>::type> {};
+
+} // namespace detail
+
+/// \ingroup ImageViewSTLAlgorithmsDefaultConstructPixels
+/// \brief Invokes the in-place default constructor on every pixel of the (uninitialized) view.
+/// Does not support planar heterogeneous views.
+/// If an exception is thrown destructs any in-place default-constructed pixels
+template <typename View> 
+void default_construct_pixels(const View& img_view) {
+    if (detail::has_trivial_pixel_constructor<View, is_planar<View>::value>::value)
+        return;
+
+    if (img_view.is_1d_traversable()) 
+        detail::default_construct_aux(img_view.begin().x(), img_view.end().x(), is_planar<View>());
+    else {
+        typename View::y_coord_t y;
+        try {
+            for (y=0; y<img_view.height(); ++y)
+                detail::default_construct_aux(img_view.row_begin(y),img_view.row_end(y), is_planar<View>());
+        } catch(...) {
+            for (typename View::y_coord_t y0=0; y0<y; ++y0)
+                detail::destruct_aux(img_view.row_begin(y0),img_view.row_end(y0), is_planar<View>());
+            throw;
+        }
+    }
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////
+///
+/// uninitialized_copy_pixels
+///
+//////////////////////////////////////////////////////////////////////////////////////
+
+/// \defgroup ImageViewSTLAlgorithmsUninitializedCopyPixels uninitialized_copy_pixels
+/// \ingroup ImageViewSTLAlgorithms
+/// \brief std::uninitialized_copy for image views
+
+namespace detail {
+
+/// std::uninitialized_copy for pairs of planar iterators
+template <typename It1, typename It2>
+GIL_FORCEINLINE 
+void uninitialized_copy_aux(It1 first1, It1 last1,
+                            It2 first2, mpl::true_) {
+    int channel=0;
+    try {
+        typedef typename std::iterator_traits<It1>::value_type pixel_t;
+        while (channel < num_channels<pixel_t>::value) {
+            std::uninitialized_copy(dynamic_at_c(first1,channel), dynamic_at_c(last1,channel), dynamic_at_c(first2,channel));
+            ++channel;
+        }
+    } catch (...) {
+        It2 last2=first2;
+        std::advance(last2, std::distance(first1,last1));
+        for (int c=0; c<channel; ++c)
+            destruct_range(dynamic_at_c(first2,c), dynamic_at_c(last2,c));
+        throw;
+    }
+}
+/// std::uninitialized_copy for interleaved or mixed iterators
+template <typename It1, typename It2>
+GIL_FORCEINLINE 
+void uninitialized_copy_aux(It1 first1, It1 last1,
+                            It2 first2,mpl::false_) {
+    std::uninitialized_copy(first1,last1,first2);
+}
+} // namespace detail
+
+/// \ingroup ImageViewSTLAlgorithmsUninitializedCopyPixels
+/// \brief std::uninitialized_copy for image views.
+/// Does not support planar heterogeneous views.
+/// If an exception is thrown destructs any in-place copy-constructed objects
+template <typename View1, typename View2> 
+void uninitialized_copy_pixels(const View1& view1, const View2& view2) {
+    typedef mpl::bool_<is_planar<View1>::value && is_planar<View2>::value> is_planar;  
+    assert(view1.dimensions()==view2.dimensions());
+    if (view1.is_1d_traversable() && view2.is_1d_traversable())
+        detail::uninitialized_copy_aux(view1.begin().x(), view1.end().x(), 
+                                       view2.begin().x(), 
+                                       is_planar());
+    else {
+        typename View1::y_coord_t y;
+        try {
+            for (y=0; y<view1.height(); ++y)
+                detail::uninitialized_copy_aux(view1.row_begin(y), view1.row_end(y),
+                                               view2.row_begin(y),
+                                               is_planar());
+        } catch(...) {
+            for (typename View1::y_coord_t y0=0; y0<y; ++y0)
+                detail::destruct_aux(view2.row_begin(y0),view2.row_end(y0), is_planar());
+            throw;
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+///
+/// for_each_pixel
+///
+//////////////////////////////////////////////////////////////////////////////////////
+
+/// \defgroup ImageViewSTLAlgorithmsForEachPixel for_each_pixel
+/// \ingroup ImageViewSTLAlgorithms
+/// \brief std::for_each for image views
+///
+/// For contiguous images (i.e. images that have no alignment gap at the end of each row) it is 
+/// more efficient to use the underlying pixel iterator that does not check for the end of rows. 
+/// For non-contiguous images for_each_pixel resolves to for_each of each row using the underlying 
+/// pixel iterator, which is still faster
+
+/// \ingroup ImageViewSTLAlgorithmsForEachPixel
+template <typename V, typename F>
+F for_each_pixel(const V& img, F fun) {
+    typename V::x_iterator       begin( img.x_at( 0, 0            ) );
+    typename V::x_iterator const end  ( img.x_at( 0, img.height() ) );
+    if ( img.is_1d_traversable() ) {
+        return std::for_each( begin, end, fun );
+    } else {
+        typename V::y_iterator current_row_end( img.col_begin( img.width() ) );
+        while ( begin != end )
+        {
+            fun = std::for_each( begin, current_row_end.base(), fun );
+            memunit_advance( begin, current_row_end.step() );
+            ++current_row_end;
+        }
+        return fun;
+    }
+}
+
+/// \defgroup ImageViewSTLAlgorithmsForEachPixelPosition for_each_pixel_position
+/// \ingroup ImageViewSTLAlgorithms
+/// \brief adobe::for_each_position for image views (passes locators, instead of pixel references, to the function object)
+
+/// \ingroup ImageViewSTLAlgorithmsForEachPixelPosition
+template <typename View, typename F>
+F for_each_pixel_position(const View& img, F fun) {
+    typename View::xy_locator loc=img.xy_at(0,0);
+    for (std::ptrdiff_t y=0; y<img.height(); ++y) {
+        for (std::ptrdiff_t x=0; x<img.width(); ++x, ++loc.x())
+            fun(loc);
+        loc.x()-=img.width(); ++loc.y();
+    }
+    return fun;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////
+///
+/// generate_pixels
+///
+//////////////////////////////////////////////////////////////////////////////////////
+
+/// \defgroup ImageViewSTLAlgorithmsGeneratePixels generate_pixels
+/// \ingroup ImageViewSTLAlgorithms
+/// \brief std::generate for image views
+
+/// \ingroup ImageViewSTLAlgorithmsGeneratePixels
+/// \brief std::generate for image views
+template <typename View, typename F>
+void generate_pixels(const View& v, F fun) {
+    if (v.is_1d_traversable()) {
+        std::generate(v.begin().x(), v.end().x(), fun);
+    } else {
+        for (std::ptrdiff_t y=0; y<v.height(); ++y)
+            std::generate(v.row_begin(y),v.row_end(y),fun);
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+///
+/// std::equal and gil::equal_pixels for GIL constructs
+///
+//////////////////////////////////////////////////////////////////////////////////////
+
+/// \defgroup ImageViewSTLAlgorithmsEqualPixels equal_pixels
+/// \ingroup ImageViewSTLAlgorithms
+/// \brief std::equal for image views
+
+template <typename I1, typename I2> GIL_FORCEINLINE bool equal_n(I1 i1, std::ptrdiff_t n, I2 i2);
+
+namespace detail {
+
+template <typename I1, typename I2>
+struct equal_n_fn {
+    GIL_FORCEINLINE bool operator()(I1 i1, std::ptrdiff_t n, I2 i2) const { return std::equal(i1,i1+n, i2); }
+};
+
+/// Equal when both ranges are interleaved and of the same type. 
+/// GIL pixels are bitwise comparable, so memcmp is used. User-defined pixels that are not bitwise comparable need to provide an overload
+template<typename T, typename Cs>
+struct equal_n_fn<const pixel<T,Cs>*, const pixel<T,Cs>*> {
+    GIL_FORCEINLINE bool operator()(const pixel<T,Cs>* i1, std::ptrdiff_t n, const pixel<T,Cs>* i2) const { 
+        return memcmp(i1, i2, n*sizeof(pixel<T,Cs>))==0;
+    }
+};
+template<typename T, typename Cs>
+struct equal_n_fn<pixel<T,Cs>*, pixel<T,Cs>*> : equal_n_fn<const pixel<T,Cs>*, const pixel<T,Cs>*> {};
+
+/// EqualPixels
+/// Equal when both ranges are planar pointers of the same type. memcmp is invoked for each channel plane
+///  User-defined channels that are not bitwise comparable need to provide an overload
+template<typename IC, typename Cs>
+struct equal_n_fn<planar_pixel_iterator<IC,Cs>, planar_pixel_iterator<IC,Cs> > {
+    GIL_FORCEINLINE bool operator()(const planar_pixel_iterator<IC,Cs> i1, std::ptrdiff_t n, const planar_pixel_iterator<IC,Cs> i2) const { 
+        ptrdiff_t numBytes=n*sizeof(typename std::iterator_traits<IC>::value_type);
+
+        for (std::ptrdiff_t i=0; i<mpl::size<Cs>::value; ++i)
+            if (memcmp(dynamic_at_c(i1,i), dynamic_at_c(i2,i), numBytes)!=0)
+                return false;
+        return true;
+    }
+};
+
+
+/// Source range is delimited by image iterators
+template <typename Loc, typename I2>  // IL Models ConstPixelLocatorConcept, O Models PixelIteratorConcept
+struct equal_n_fn<boost::gil::iterator_from_2d<Loc>,I2> {
+    GIL_FORCEINLINE bool operator()(boost::gil::iterator_from_2d<Loc> i1, std::ptrdiff_t n, I2 i2) const {
+        gil_function_requires<boost::gil::PixelLocatorConcept<Loc> >();
+        gil_function_requires<boost::gil::PixelIteratorConcept<I2> >();
+        while (n>0) {
+            std::ptrdiff_t num=std::min<const std::ptrdiff_t>(n, i1.width()-i1.x_pos());
+            if (!equal_n(i1.x(), num, i2))
+                return false;
+            i1+=num;
+            i2+=num;
+            n-=num;
+        }
+        return true;
+    }
+};
+
+/// Destination range is delimited by image iterators
+template <typename I1, typename Loc> // I Models PixelIteratorConcept, OL Models PixelLocatorConcept
+struct equal_n_fn<I1,boost::gil::iterator_from_2d<Loc> > {
+    GIL_FORCEINLINE bool operator()(I1 i1, std::ptrdiff_t n, boost::gil::iterator_from_2d<Loc> i2) const {
+        gil_function_requires<boost::gil::PixelIteratorConcept<I1> >();
+        gil_function_requires<boost::gil::PixelLocatorConcept<Loc> >();
+        while (n>0) {
+            std::ptrdiff_t num=std::min<const std::ptrdiff_t>(n,i2.width()-i2.x_pos());
+            if (!equal_n(i1, num, i2.x()))
+                return false;
+            i1+=num;
+            i2+=num;
+            n-=num;
+        }
+        return true;
+    }
+};
+
+/// Both source and destination ranges are delimited by image iterators
+template <typename Loc1, typename Loc2>
+struct equal_n_fn<boost::gil::iterator_from_2d<Loc1>,boost::gil::iterator_from_2d<Loc2> > {
+   GIL_FORCEINLINE bool operator()(boost::gil::iterator_from_2d<Loc1> i1, std::ptrdiff_t n, boost::gil::iterator_from_2d<Loc2> i2) const {
+        gil_function_requires<boost::gil::PixelLocatorConcept<Loc1> >();
+        gil_function_requires<boost::gil::PixelLocatorConcept<Loc2> >();
+        if (i1.x_pos()!=i2.x_pos() || i1.width()!=i2.width()) {
+            while(n-->0) {
+                if (*i1++!=*i2++) return false;
+            }
+        }
+        while (n>0) {
+            std::ptrdiff_t num=std::min<const std::ptrdiff_t>(n,i2.width()-i2.x_pos());
+            if (!equal_n(i1.x(), num, i2.x()))
+                return false;
+            i1+=num;
+            i2+=num;
+            n-=num;
+        }
+        return true;
+    }
+};
+} // namespace detail
+
+template <typename I1, typename I2> GIL_FORCEINLINE
+bool equal_n(I1 i1, std::ptrdiff_t n, I2 i2) {
+    return detail::equal_n_fn<I1,I2>()(i1,n,i2);
+}
+} }  // namespace boost::gil
+
+namespace std {
+/// \ingroup STLOptimizations
+/// \brief  std::equal(I1,I1,I2) with I1 and I2 being a iterator_from_2d
+///
+/// Invoked when one calls std::equal(I1,I1,I2) with I1 and I2 being a iterator_from_2d (which is
+/// a 1D iterator over the pixels in an image). Attempts to demote the source and destination 
+/// iterators to simpler/faster types if the corresponding range is contiguous.
+/// For contiguous images (i.e. images that have
+/// no alignment gap at the end of each row) it is more efficient to use the underlying 
+/// pixel iterator that does not check for the end of rows. If the underlying pixel iterator
+/// happens to be a fundamental planar/interleaved pointer, the call may further resolve
+/// to memcmp. Otherwise it resolves to copying each row using the underlying pixel iterator
+template <typename Loc1, typename Loc2> GIL_FORCEINLINE 
+bool equal(boost::gil::iterator_from_2d<Loc1> first, boost::gil::iterator_from_2d<Loc1> last, boost::gil::iterator_from_2d<Loc2> first2) {
+    boost::gil::gil_function_requires<boost::gil::PixelLocatorConcept<Loc1> >();
+    boost::gil::gil_function_requires<boost::gil::PixelLocatorConcept<Loc2> >();
+    std::ptrdiff_t n=last-first;
+    if (first.is_1d_traversable()) {
+        if (first2.is_1d_traversable())
+            return boost::gil::detail::equal_n_fn<typename Loc1::x_iterator,typename Loc2::x_iterator>()(first.x(),n, first2.x());
+        else
+            return boost::gil::detail::equal_n_fn<typename Loc1::x_iterator,boost::gil::iterator_from_2d<Loc2> >()(first.x(),n, first2);
+    } else {
+        if (first2.is_1d_traversable())
+            return boost::gil::detail::equal_n_fn<boost::gil::iterator_from_2d<Loc1>,typename Loc2::x_iterator>()(first,n, first2.x());
+        else
+            return boost::gil::detail::equal_n_fn<boost::gil::iterator_from_2d<Loc1>,boost::gil::iterator_from_2d<Loc2> >()(first,n,first2);
+    }
+}
+} // namespace std
+
+namespace boost { namespace gil {
+
+/// \ingroup ImageViewSTLAlgorithmsEqualPixels
+/// \brief std::equal for image views
+template <typename View1, typename View2> GIL_FORCEINLINE 
+bool equal_pixels(const View1& v1, const View2& v2) {
+    assert(v1.dimensions()==v2.dimensions());
+    return std::equal(v1.begin(),v1.end(),v2.begin()); // std::equal has overloads with GIL iterators for optimal performance
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+///
+/// transform_pixels
+///
+//////////////////////////////////////////////////////////////////////////////////////
+
+/// \defgroup ImageViewSTLAlgorithmsTransformPixels transform_pixels
+/// \ingroup ImageViewSTLAlgorithms
+/// \brief std::transform for image views
+
+/// \ingroup ImageViewSTLAlgorithmsTransformPixels
+/// \brief std::transform for image views
+template <typename View1, typename View2, typename F> GIL_FORCEINLINE 
+F transform_pixels(const View1& src,const View2& dst, F fun) {
+    assert(src.dimensions()==dst.dimensions());
+    for (std::ptrdiff_t y=0; y<src.height(); ++y) {
+        typename View1::x_iterator srcIt=src.row_begin(y);
+        typename View2::x_iterator dstIt=dst.row_begin(y);
+        for (std::ptrdiff_t x=0; x<src.width(); ++x)
+            dstIt[x]=fun(srcIt[x]);
+    }
+    return fun;
+}
+
+/// \ingroup ImageViewSTLAlgorithmsTransformPixels
+/// \brief transform_pixels with two sources
+template <typename View1, typename View2, typename View3, typename F> GIL_FORCEINLINE 
+F transform_pixels(const View1& src1, const View2& src2,const View3& dst, F fun) {
+    for (std::ptrdiff_t y=0; y<dst.height(); ++y) {
+        typename View1::x_iterator srcIt1=src1.row_begin(y);
+        typename View2::x_iterator srcIt2=src2.row_begin(y);
+        typename View3::x_iterator dstIt=dst.row_begin(y);
+        for (std::ptrdiff_t x=0; x<dst.width(); ++x)
+            dstIt[x]=fun(srcIt1[x],srcIt2[x]);
+    }
+    return fun;
+}
+
+/// \defgroup ImageViewSTLAlgorithmsTransformPixelPositions transform_pixel_positions
+/// \ingroup ImageViewSTLAlgorithms
+/// \brief adobe::transform_positions for image views (passes locators, instead of pixel references, to the function object) 
+
+/// \ingroup ImageViewSTLAlgorithmsTransformPixelPositions
+/// \brief Like transform_pixels but passes to the function object pixel locators instead of pixel references
+template <typename View1, typename View2, typename F> GIL_FORCEINLINE 
+F transform_pixel_positions(const View1& src,const View2& dst, F fun) {
+    assert(src.dimensions()==dst.dimensions());
+    typename View1::xy_locator loc=src.xy_at(0,0);
+    for (std::ptrdiff_t y=0; y<src.height(); ++y) {
+        typename View2::x_iterator dstIt=dst.row_begin(y);
+        for (std::ptrdiff_t x=0; x<src.width(); ++x, ++loc.x())
+            dstIt[x]=fun(loc);
+        loc.x()-=src.width(); ++loc.y();
+    }
+    return fun;
+}
+
+/// \ingroup ImageViewSTLAlgorithmsTransformPixelPositions
+/// \brief transform_pixel_positions with two sources
+template <typename View1, typename View2, typename View3, typename F> GIL_FORCEINLINE 
+F transform_pixel_positions(const View1& src1,const View2& src2,const View3& dst, F fun) {
+    assert(src1.dimensions()==dst.dimensions());
+    assert(src2.dimensions()==dst.dimensions());
+    typename View1::xy_locator loc1=src1.xy_at(0,0);
+    typename View2::xy_locator loc2=src2.xy_at(0,0);
+    for (std::ptrdiff_t y=0; y<src1.height(); ++y) {
+        typename View3::x_iterator dstIt=dst.row_begin(y);
+        for (std::ptrdiff_t x=0; x<src1.width(); ++x, ++loc1.x(), ++loc2.x())
+            dstIt[x]=fun(loc1,loc2);
+        loc1.x()-=src1.width(); ++loc1.y();
+        loc2.x()-=src2.width(); ++loc2.y();
+    }
+    return fun;
+}
+
+} }  // namespace boost::gil
+
+//#ifdef _MSC_VER
+//#pragma warning(pop)
+//#endif
+
+#endif
Added: sandbox/gil/boost/gil/color_convert.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/color_convert.hpp	2010-10-10 12:42:02 EDT (Sun, 10 Oct 2010)
@@ -0,0 +1,321 @@
+/*
+    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_COLOR_CONVERT_HPP
+#define GIL_COLOR_CONVERT_HPP
+
+////////////////////////////////////////////////////////////////////////////////////////
+/// \file               
+/// \brief GIL default color space conversions
+/// \author Lubomir Bourdev and Hailin Jin \n
+///         Adobe Systems Incorporated
+/// \date   2005-2007 \n Last updated on January 30, 2007
+///
+/// Support for fast and simple color conversion. Accurate color conversion using color
+/// profiles can be supplied separately in a dedicated module
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+#include <functional>
+#include "gil_config.hpp"
+#include "channel_algorithm.hpp"
+#include "pixel.hpp"
+#include "gray.hpp"
+#include "rgb.hpp"
+#include "rgba.hpp"
+#include "cmyk.hpp"
+#include "metafunctions.hpp"
+#include "utilities.hpp"
+#include "color_base_algorithm.hpp"
+
+namespace boost { namespace gil {
+
+// Forward-declare
+template <typename P> struct channel_type;
+
+////////////////////////////////////////////////////////////////////////////////////////
+///                 
+///                 COLOR SPACE CONVERSION
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+/// \ingroup ColorConvert 
+/// \brief Color Convertion function object. To be specialized for every src/dst color space
+template <typename C1, typename C2>
+struct default_color_converter_impl {};
+
+/// \ingroup ColorConvert
+/// \brief When the color space is the same, color convertion performs channel depth conversion
+template <typename C>
+struct default_color_converter_impl<C,C> {
+    template <typename P1, typename P2>
+    void operator()(const P1& src, P2& dst) const {
+        static_for_each(src,dst,default_channel_converter());
+    }
+};
+
+namespace detail {
+
+/// red * .3 + green * .59 + blue * .11 + .5
+
+// The default implementation of to_luminance uses float0..1 as the intermediate channel type
+template <typename RedChannel, typename GreenChannel, typename BlueChannel, typename GrayChannelValue>
+struct rgb_to_luminance_fn {
+    GrayChannelValue operator()(const RedChannel& red, const GreenChannel& green, const BlueChannel& blue) const {
+        return channel_convert<GrayChannelValue>( bits32f(
+            channel_convert<bits32f>(red  )*0.30f + 
+            channel_convert<bits32f>(green)*0.59f + 
+            channel_convert<bits32f>(blue )*0.11f) );
+    }
+};
+
+// performance specialization for unsigned char
+template <typename GrayChannelValue>
+struct rgb_to_luminance_fn<uint8_t,uint8_t,uint8_t, GrayChannelValue> {
+    GrayChannelValue operator()(uint8_t red, uint8_t green, uint8_t blue) const {
+        return channel_convert<GrayChannelValue>(uint8_t(
+            ((uint32_t(red  )*4915 + uint32_t(green)*9667 + uint32_t(blue )*1802) + 8192) >> 14));
+    }
+};
+
+template <typename GrayChannel, typename RedChannel, typename GreenChannel, typename BlueChannel>
+typename channel_traits<GrayChannel>::value_type rgb_to_luminance(const RedChannel& red, const GreenChannel& green, const BlueChannel& blue) {
+    return rgb_to_luminance_fn<RedChannel,GreenChannel,BlueChannel,
+                               typename channel_traits<GrayChannel>::value_type>()(red,green,blue);
+}
+
+}   // namespace detail
+
+/// \ingroup ColorConvert
+/// \brief Gray to RGB
+template <>
+struct default_color_converter_impl<gray_t,rgb_t> {
+    template <typename P1, typename P2>
+    void operator()(const P1& src, P2& dst) const {
+        get_color(dst,red_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<P2, green_t>::type>(get_color(src,gray_color_t()));
+        get_color(dst,blue_t()) =
+            channel_convert<typename color_element_type<P2, blue_t >::type>(get_color(src,gray_color_t()));
+    }
+};
+
+/// \ingroup ColorConvert
+/// \brief Gray to CMYK
+template <>
+struct default_color_converter_impl<gray_t,cmyk_t> {
+    template <typename P1, typename P2>
+    void operator()(const P1& src, P2& dst) const {
+        get_color(dst,cyan_t())=
+            channel_traits<typename color_element_type<P2, cyan_t   >::type>::min_value();
+        get_color(dst,magenta_t())=
+            channel_traits<typename color_element_type<P2, magenta_t>::type>::min_value();
+        get_color(dst,yellow_t())=
+            channel_traits<typename color_element_type<P2, yellow_t >::type>::min_value();
+        get_color(dst,black_t())=
+            channel_convert<typename color_element_type<P2, black_t >::type>(get_color(src,gray_color_t()));
+    }
+};
+
+/// \ingroup ColorConvert
+/// \brief RGB to Gray
+template <>
+struct default_color_converter_impl<rgb_t,gray_t> {
+    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<P2,gray_color_t>::type>(
+                get_color(src,red_t()), get_color(src,green_t()), get_color(src,blue_t())
+            );
+    }
+};
+
+
+/// \ingroup ColorConvert
+/// \brief RGB to CMYK (not the fastest code in the world)
+///
+/// k = min(1 - r, 1 - g, 1 - b)
+/// c = (1 - r - k) / (1 - k)
+/// m = (1 - g - k) / (1 - k)
+/// y = (1 - b - k) / (1 - k)
+template <>
+struct default_color_converter_impl<rgb_t,cmyk_t> {
+    template <typename P1, typename P2>
+    void operator()(const P1& src, P2& dst) const {
+        typedef typename channel_type<P2>::type T2;
+        get_color(dst,cyan_t())    = channel_invert(channel_convert<T2>(get_color(src,red_t())));          // c = 1 - r
+        get_color(dst,magenta_t()) = channel_invert(channel_convert<T2>(get_color(src,green_t())));        // m = 1 - g
+        get_color(dst,yellow_t())  = channel_invert(channel_convert<T2>(get_color(src,blue_t())));         // y = 1 - b
+        get_color(dst,black_t())   = (std::min)(get_color(dst,cyan_t()),
+                                                (std::min)(get_color(dst,magenta_t()),
+                                                           get_color(dst,yellow_t())));   // k = minimum(c, m, y)
+        T2 x = channel_traits<T2>::max_value()-get_color(dst,black_t());                  // x = 1 - k
+        if (x>0.0001f) {
+            float x1 = channel_traits<T2>::max_value()/float(x);
+            get_color(dst,cyan_t())    = (T2)((get_color(dst,cyan_t())    - get_color(dst,black_t()))*x1);                // c = (c - k) / x
+            get_color(dst,magenta_t()) = (T2)((get_color(dst,magenta_t()) - get_color(dst,black_t()))*x1);                // m = (m - k) / x
+            get_color(dst,yellow_t())  = (T2)((get_color(dst,yellow_t())  - get_color(dst,black_t()))*x1);                // y = (y - k) / x
+        } else {
+            get_color(dst,cyan_t())=get_color(dst,magenta_t())=get_color(dst,yellow_t())=0;
+        }
+    }
+};
+
+/// \ingroup ColorConvert
+/// \brief CMYK to RGB (not the fastest code in the world)
+///
+/// r = 1 - min(1, c*(1-k)+k)
+/// g = 1 - min(1, m*(1-k)+k)
+/// b = 1 - min(1, y*(1-k)+k)
+template <>
+struct default_color_converter_impl<cmyk_t,rgb_t> {
+    template <typename P1, typename P2>
+    void operator()(const P1& src, P2& dst) const {
+        typedef typename channel_type<P1>::type T1;
+        typedef typename mpl::if_
+            <
+                is_integral<T1>,
+                typename detail::min_fast_uint<sizeof( T1 ) * 8 + 1>::type,
+                T1
+            >::type T1_AUX;
+        get_color(dst,red_t())  =
+            channel_convert<typename color_element_type<P2,red_t>::type>
+            (
+                //channel_invert(T1(get_color(src,cyan_t())*channel_invert(get_color(src,black_t()))/channel_traits<T1>::max_value() + get_color(src,black_t())))
+                T1(channel_invert(get_color(src,cyan_t()))*channel_invert(get_color(src,black_t()))/channel_traits<T1>::max_value())
+            );
+        get_color(dst,green_t())=
+            channel_convert<typename color_element_type<P2,green_t>::type>(
+                //channel_invert(T1(get_color(src,magenta_t())*channel_invert(get_color(src,black_t()))/channel_traits<T1>::max_value() + get_color(src,black_t())))
+                T1(channel_invert(get_color(src,magenta_t()))*channel_invert(get_color(src,black_t()))/channel_traits<T1>::max_value())
+                );
+        get_color(dst,blue_t()) =
+            channel_convert<typename color_element_type<P2,blue_t>::type>(
+                //channel_invert(T1(get_color(src,yellow_t())*channel_invert(get_color(src,black_t()))/channel_traits<T1>::max_value() + get_color(src,black_t())))
+                T1(channel_invert(get_color(src,yellow_t()))*channel_invert(get_color(src,black_t()))/channel_traits<T1>::max_value())
+                );
+    }
+};
+
+
+/// \ingroup ColorConvert
+/// \brief CMYK to Gray
+///
+/// gray = (1 - 0.212c - 0.715m - 0.0722y) * (1 - k)
+template <>
+struct default_color_converter_impl<cmyk_t,gray_t> {
+    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<P2,gray_t>::type>(
+                channel_multiply(
+                    channel_invert(
+                       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())
+                       )
+                    ), 
+                    channel_invert(get_color(src,black_t()))));
+    }
+};
+
+namespace detail {
+template <typename Pixel> 
+typename channel_type<Pixel>::type alpha_or_max_impl(const Pixel& p, mpl::true_) {
+    return get_color(p,alpha_t());
+}
+template <typename Pixel> 
+typename channel_type<Pixel>::type alpha_or_max_impl(const Pixel&  , mpl::false_) {
+    return channel_traits<typename channel_type<Pixel>::type>::max_value();
+}
+} // namespace detail
+
+// Returns max_value if the pixel has no alpha channel. Otherwise returns the alpha.
+template <typename Pixel> 
+typename channel_type<Pixel>::type alpha_or_max(const Pixel& p) {
+    return detail::alpha_or_max_impl(p, mpl::contains<typename color_space_type<Pixel>::type,alpha_t>());
+}
+
+
+/// \ingroup ColorConvert
+/// \brief Converting any pixel type to RGBA. Note: Supports homogeneous pixels only.
+template <typename C1>
+struct default_color_converter_impl<C1,rgba_t> {
+    template <typename P1, typename P2>
+    void operator()(const P1& src, P2& dst) const {
+        typedef typename channel_type<P2>::type T2;
+        pixel<T2,rgb_layout_t> tmp;
+        default_color_converter_impl<C1,rgb_t>()(src,tmp);
+        get_color(dst,red_t())  =get_color(tmp,red_t());
+        get_color(dst,green_t())=get_color(tmp,green_t());
+        get_color(dst,blue_t()) =get_color(tmp,blue_t());
+        get_color(dst,alpha_t())=channel_convert<T2>(alpha_or_max(src));
+    }
+};
+
+/// \ingroup ColorConvert
+///  \brief Converting RGBA to any pixel type. Note: Supports homogeneous pixels only.
+///
+/// Done by multiplying the alpha to get to RGB, then converting the RGB to the target pixel type
+/// Note: This may be slower if the compiler doesn't optimize out constructing/destructing a temporary RGB pixel. 
+///       Consider rewriting if performance is an issue
+template <typename C2>
+struct default_color_converter_impl<rgba_t,C2> {
+    template <typename P1, typename P2>
+    void operator()(const P1& src, P2& dst) const {
+        typedef typename channel_type<P1>::type T1;
+        default_color_converter_impl<rgb_t,C2>()(
+            pixel<T1,rgb_layout_t>(channel_multiply(get_color(src,red_t()),  get_color(src,alpha_t())), 
+                                   channel_multiply(get_color(src,green_t()),get_color(src,alpha_t())), 
+                                   channel_multiply(get_color(src,blue_t()), get_color(src,alpha_t())))
+            ,dst);
+    }
+};
+
+/// \ingroup ColorConvert
+/// \brief Unfortunately RGBA to RGBA must be explicitly provided - otherwise we get ambiguous specialization error.
+template <>
+struct default_color_converter_impl<rgba_t,rgba_t> {
+    template <typename P1, typename P2>
+    void operator()(const P1& src, P2& dst) const {
+        static_for_each(src,dst,default_channel_converter());
+    }
+};
+
+/// @defgroup ColorConvert Color Space Converion
+/// \ingroup ColorSpaces
+/// \brief Support for conversion between pixels of different color spaces and channel depths
+
+/// \ingroup PixelAlgorithm ColorConvert
+/// \brief class for color-converting one pixel to another
+struct default_color_converter {
+    template <typename SrcP, typename DstP>
+    void operator()(const SrcP& src,DstP& dst) const { 
+        typedef typename color_space_type<SrcP>::type SrcColorSpace;
+        typedef typename color_space_type<DstP>::type DstColorSpace;
+        default_color_converter_impl<SrcColorSpace,DstColorSpace>()(src,dst);
+    }
+};
+
+/// \ingroup PixelAlgorithm
+/// \brief helper function for converting one pixel to another using GIL default color-converters
+///     where ScrP models HomogeneousPixelConcept
+///           DstP models HomogeneousPixelValueConcept
+template <typename SrcP, typename DstP>
+inline void color_convert(const SrcP& src, DstP& dst) {
+    default_color_converter()(src,dst);
+}
+
+} }  // namespace boost::gil
+
+#endif
Added: sandbox/gil/boost/gil/image.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/image.hpp	2010-10-10 12:42:02 EDT (Sun, 10 Oct 2010)
@@ -0,0 +1,312 @@
+/*
+    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_IMAGE_H
+#define GIL_IMAGE_H
+
+////////////////////////////////////////////////////////////////////////////////////////
+/// \file               
+/// \brief Templated image
+/// \author Lubomir Bourdev and Hailin Jin \n
+///         Adobe Systems Incorporated
+/// \date 2005-2007 \n Last updated on February 12, 2007
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+#include <cstddef>
+#include <memory>
+#include "gil_config.hpp"
+#include "image_view.hpp"
+#include "metafunctions.hpp"
+#include "algorithm.hpp"
+
+namespace boost { namespace gil {
+
+//#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)
+//#endif
+
+////////////////////////////////////////////////////////////////////////////////////////
+/// \ingroup ImageModel PixelBasedModel
+/// \brief container interface over image view. Models ImageConcept, PixelBasedConcept
+/// 
+/// A 2D container whose elements are pixels. It is templated over the pixel type, a boolean
+/// indicating whether it should be planar, and an optional allocator.
+///
+/// Note that its element type does not have to be a pixel. \p image can be instantiated with any Regular element, 
+/// in which case it models the weaker RandomAccess2DImageConcept and does not model PixelBasedConcept
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+template< typename Pixel, bool IsPlanar = false, typename Alloc=std::allocator<unsigned char> >    
+class image {
+public:
+    typedef typename Alloc::template rebind<unsigned char>::other allocator_type;
+    typedef typename view_type_from_pixel<Pixel, IsPlanar>::type view_t;
+    typedef typename view_t::const_t                 const_view_t;
+    typedef typename view_t::point_t                 point_t;
+    typedef typename view_t::coord_t                 coord_t;
+    typedef typename view_t::value_type              value_type;
+    typedef coord_t                                  x_coord_t;
+    typedef coord_t                                  y_coord_t;
+
+    const point_t&          dimensions()            const { return _view.dimensions(); }
+    x_coord_t               width()                 const { return _view.width(); }
+    y_coord_t               height()                const { return _view.height(); }
+
+    explicit image(std::size_t alignment=0,
+                   const Alloc alloc_in = Alloc()) : 
+        _memory(0), _align_in_bytes(alignment), _alloc(alloc_in) {}
+
+    // Create with dimensions and optional initial value and alignment
+    image(const point_t& dimensions,
+          std::size_t alignment=0,
+          const Alloc alloc_in = Alloc()) : _memory(0), _align_in_bytes(alignment), _alloc(alloc_in) {
+        allocate_and_default_construct(dimensions);
+    }
+    image(x_coord_t width, y_coord_t height,
+          std::size_t alignment=0,
+          const Alloc alloc_in = Alloc()) : _memory(0), _align_in_bytes(alignment), _alloc(alloc_in) {
+        allocate_and_default_construct(point_t(width,height));
+    }
+    image(const point_t& dimensions, 
+          const Pixel& p_in,
+          std::size_t alignment,
+          const Alloc alloc_in = Alloc())  :
+        _memory(0), _align_in_bytes(alignment), _alloc(alloc_in) {
+        allocate_and_fill(dimensions, p_in);
+    }
+    image(x_coord_t width, y_coord_t height,
+          const Pixel& p_in,
+          std::size_t alignment,
+          const Alloc alloc_in = Alloc())  :
+        _memory(0), _align_in_bytes(alignment), _alloc(alloc_in) {
+        allocate_and_fill(point_t(width,height),p_in);
+    }
+
+    image(const image& img) :
+        _memory(0), _align_in_bytes(img._align_in_bytes), _alloc(img._alloc) {
+        allocate_and_copy(img.dimensions(),img._view);
+    }
+
+    template <typename P2, bool IP2, typename Alloc2>
+    image(const image<P2,IP2,Alloc2>& img) : 
+        _memory(0), _align_in_bytes(img._align_in_bytes), _alloc(img._alloc) {
+       allocate_and_copy(img.dimensions(),img._view);
+    }
+    image& operator=(const image& img) {
+        if (dimensions() == img.dimensions())
+            copy_pixels(img._view,_view);
+        else {
+            image tmp(img);
+            swap(tmp);
+        }
+        return *this;
+    }
+
+    template <typename Img>
+    image& operator=(const Img& img) {
+        if (dimensions() == img.dimensions())
+            copy_pixels(img._view,_view);
+        else {
+            image tmp(img);
+            swap(tmp);
+        }
+        return *this;
+    }
+
+    ~image() {
+        destruct_pixels(_view);
+        deallocate(_view.dimensions());
+    }
+
+    Alloc&       allocator() { return _alloc; }
+    Alloc const& allocator() const { return _alloc; }
+
+    void swap(image& img) { // required by MutableContainerConcept
+        using std::swap;
+        swap(_align_in_bytes, img._align_in_bytes);
+        swap(_memory,         img._memory);
+        swap(_view,           img._view); 
+        swap(_alloc,          img._alloc);
+    }    
+
+    void recreate(const point_t& dims, std::size_t alignment=0, const Alloc alloc_in = Alloc()) {
+        if (dims!=_view.dimensions() || _align_in_bytes!=alignment || alloc_in!=_alloc) {
+            image tmp(dims, alignment, alloc_in);
+            swap(tmp);
+        }
+    }
+    void recreate(x_coord_t width, y_coord_t height, std::size_t alignment=0, const Alloc alloc_in = Alloc()) {
+        recreate(point_t(width,height),alignment,alloc_in);
+    }
+    void recreate(const point_t& dims, 
+                  const Pixel& p_in, std::size_t alignment, const Alloc alloc_in = Alloc()) {
+        if (dims!=_view.dimensions() || _align_in_bytes!=alignment || alloc_in!=_alloc) {
+            image tmp(dims, p_in, alignment, alloc_in);
+            swap(tmp);
+        }
+    }
+    void recreate(x_coord_t width, y_coord_t height, 
+                  const Pixel& p_in, std::size_t alignment, const Alloc alloc_in = Alloc()) {
+        recreate(point_t(width,height),p_in,alignment,alloc_in);
+    }
+
+    view_t       _view;      // contains pointer to the pixels, the image size and ways to navigate pixels
+private:
+    unsigned char* _memory;
+    std::size_t    _align_in_bytes;
+    allocator_type _alloc;
+
+    void allocate_and_default_construct(const point_t& dimensions) { 
+        try {
+            allocate_(dimensions,mpl::bool_<IsPlanar>());
+            // Implementation note:
+            //    The 'skip' in/through default_construct_pixels() is not enough
+            // as MSVC++ 10 is unable to inline functions with try-catch blocks.
+            //                                (10.10.2010.) (Domagoj Saric)
+            if (!detail::has_trivial_pixel_constructor<view_t, is_planar<view_t>::value>::value)
+                default_construct_pixels(_view);
+        } catch(...) {
+            __assume
+            (
+                !view_is_basic<view_t>                                                  ::value &&
+                !detail::has_trivial_pixel_constructor<view_t, is_planar<view_t>::value>::value
+            );
+            deallocate(dimensions);
+            throw;
+        }
+    }
+
+    void allocate_and_fill(const point_t& dimensions, const Pixel& p_in) { 
+        try {
+            allocate_(dimensions,mpl::bool_<IsPlanar>());
+            uninitialized_fill_pixels(_view, p_in);
+        } catch(...) { deallocate(dimensions); throw; }
+    }
+
+    template <typename View>
+    void allocate_and_copy(const point_t& dimensions, const View& v) { 
+        try {
+            allocate_(dimensions,mpl::bool_<IsPlanar>());
+            uninitialized_copy_pixels(v,_view);
+        } catch(...) { deallocate(dimensions); throw; }
+    }
+
+    void deallocate(const point_t& dimensions) { 
+        if (_memory) _alloc.deallocate(_memory, total_allocated_size_in_bytes(dimensions));
+    }
+
+    std::size_t total_allocated_size_in_bytes(const point_t& dimensions) const {
+
+        typedef typename view_t::x_iterator x_iterator; 
+
+        // when value_type is a non-pixel, like int or float, num_channels< ... > doesn't work.
+        const std::size_t _channels_in_image = mpl::eval_if< is_pixel< value_type >
+                                                           , num_channels< view_t >
+                                                           , mpl::int_< 1 > 
+														   >::type::value;
+
+        std::size_t size_in_units = get_row_size_in_memunits(dimensions.x)*dimensions.y;
+
+        if (IsPlanar)
+            size_in_units = size_in_units * _channels_in_image ;
+
+        // return the size rounded up to the nearest byte
+        return ( size_in_units + byte_to_memunit< x_iterator >::value - 1 ) 
+            / byte_to_memunit<x_iterator>::value 
+            + ( _align_in_bytes > 0 ? _align_in_bytes - 1 : 0 ); // add extra padding in case we need to align the first image pixel
+    }
+
+    std::size_t get_row_size_in_memunits(x_coord_t width) const {   // number of units per row
+        std::size_t size_in_memunits = width*memunit_step(typename view_t::x_iterator());
+        if (_align_in_bytes>0) {
+            std::size_t alignment_in_memunits=_align_in_bytes*byte_to_memunit<typename view_t::x_iterator>::value;
+            return align(size_in_memunits, alignment_in_memunits);
+        }
+        return size_in_memunits;
+    }
+    
+    void allocate_(const point_t& dimensions, mpl::false_) {  // if it throws and _memory!=0 the client must deallocate _memory
+        _memory=_alloc.allocate(total_allocated_size_in_bytes(dimensions));
+        unsigned char* tmp=(_align_in_bytes>0) ? (unsigned char*)align((std::size_t)_memory,_align_in_bytes) : _memory;
+        _view=view_t(dimensions,typename view_t::locator(typename view_t::x_iterator(tmp),get_row_size_in_memunits(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_size=get_row_size_in_memunits(dimensions.x);
+        std::size_t plane_size=row_size*dimensions.y;
+        _memory=_alloc.allocate(total_allocated_size_in_bytes(dimensions));
+        unsigned char* tmp=(_align_in_bytes>0) ? (unsigned char*)align((std::size_t)_memory,_align_in_bytes) : _memory;
+        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;
+            memunit_advance(dynamic_at_c(first,i), plane_size*i);
+        }
+        _view=view_t(dimensions, typename view_t::locator(first, row_size));
+    }
+};
+
+template <typename Pixel, bool IsPlanar, typename Alloc>
+void swap(image<Pixel, IsPlanar, Alloc>& im1,image<Pixel, IsPlanar, Alloc>& im2) {
+    im1.swap(im2); 
+}
+
+template <typename Pixel1, bool IsPlanar1, typename Alloc1, typename Pixel2, bool IsPlanar2, typename Alloc2>
+bool operator==(const image<Pixel1,IsPlanar1,Alloc1>& im1,const image<Pixel2,IsPlanar2,Alloc2>& im2) {
+    if ((void*)(&im1)==(void*)(&im2)) return true;
+    if (const_view(im1).dimensions()!=const_view(im2).dimensions()) return false;
+    return equal_pixels(const_view(im1),const_view(im2));
+}
+template <typename Pixel1, bool IsPlanar1, typename Alloc1, typename Pixel2, bool IsPlanar2, typename Alloc2>
+bool operator!=(const image<Pixel1,IsPlanar1,Alloc1>& im1,const image<Pixel2,IsPlanar2,Alloc2>& im2) {return !(im1==im2);}
+
+///@{
+/// \name view, const_view
+/// \brief Get an image view from an image
+
+/// \ingroup ImageModel
+
+/// \brief Returns the non-constant-pixel view of an image
+template <typename Pixel, bool IsPlanar, typename Alloc> inline 
+const typename image<Pixel,IsPlanar,Alloc>::view_t& view(image<Pixel,IsPlanar,Alloc>& img) { return img._view; }
+
+/// \brief Returns the constant-pixel view of an image
+template <typename Pixel, bool IsPlanar, typename Alloc> inline 
+const typename image<Pixel,IsPlanar,Alloc>::const_view_t const_view(const image<Pixel,IsPlanar,Alloc>& img) { 
+    return static_cast<const typename image<Pixel,IsPlanar,Alloc>::const_view_t>(img._view); 
+}
+///@}
+
+/////////////////////////////
+//  PixelBasedConcept
+/////////////////////////////
+
+template <typename Pixel, bool IsPlanar, typename Alloc>
+struct channel_type<image<Pixel,IsPlanar,Alloc> > : public channel_type<Pixel> {}; 
+
+template <typename Pixel, bool IsPlanar, typename Alloc>
+struct color_space_type<image<Pixel,IsPlanar,Alloc> >  : public color_space_type<Pixel> {};
+
+template <typename Pixel, bool IsPlanar, typename Alloc>
+struct channel_mapping_type<image<Pixel,IsPlanar,Alloc> > : public channel_mapping_type<Pixel> {};
+
+template <typename Pixel, bool IsPlanar, typename Alloc>
+struct is_planar<image<Pixel,IsPlanar,Alloc> > : public mpl::bool_<IsPlanar> {};
+
+//#ifdef _MSC_VER
+//#pragma warning(pop)
+//#endif
+
+} }  // namespace boost::gil
+
+#endif
Added: sandbox/gil/boost/gil/locator.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/locator.hpp	2010-10-10 12:42:02 EDT (Sun, 10 Oct 2010)
@@ -0,0 +1,395 @@
+/*
+    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_LOCATOR_H
+#define GIL_LOCATOR_H
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+/// \file               
+/// \brief pixel 2D locator
+/// \author Lubomir Bourdev and Hailin Jin \n
+///         Adobe Systems Incorporated
+/// \date   2005-2007 \n September 20, 2006
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+#include <cstddef>
+#include <cassert>
+#include "pixel_iterator.hpp"
+
+////////////////////////////////////////////////////////////////////////////////////////
+///                 Pixel 2D LOCATOR
+////////////////////////////////////////////////////////////////////////////////////////
+
+
+namespace boost { namespace gil {
+
+//forward declarations
+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 {
+    // helper class specialized for each axis of pixel_2d_locator
+    template <std::size_t D, typename Loc>  class locator_axis;
+}
+template <typename T> struct dynamic_x_step_type;
+template <typename T> struct dynamic_y_step_type;
+
+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
+template <typename T> struct transposed_type {
+    typedef T type;
+};
+
+/// \class pixel_2d_locator_base
+/// \brief base class for models of PixelLocatorConcept
+/// \ingroup PixelLocatorModel PixelBasedModel
+///
+/// Pixel locator is similar to a pixel iterator, but allows for 2D navigation of pixels within an image view. 
+/// It has a 2D difference_type and supports random access operations like:
+/// \code
+///     difference_type offset2(2,3);
+///     locator+=offset2;
+///     locator[offset2]=my_pixel;
+/// \endcode
+///
+/// In addition, each coordinate acts as a random-access iterator that can be modified separately:
+/// "++locator.x()" or "locator.y()+=10" thereby moving the locator horizontally or vertically.
+///
+/// It is called a locator because it doesn't implement the complete interface of a random access iterator.
+/// For example, increment and decrement operations don't make sense (no way to specify dimension).
+/// 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 memory_based_2d_locator and a virtual
+/// locator, \p virtual_2d_locator.
+/// The minimum functionality a subclass must provide is this:
+/// \code
+/// class my_locator : public pixel_2d_locator_base<my_locator, ..., ...> {  // supply the types for x-iterator and y-iterator
+///        typedef ... const_t;                      // read-only locator
+///
+///        template <typename Deref> struct add_deref {
+///            typedef ... type;                     // locator that invokes the Deref dereference object upon pixel access
+///            static type make(const my_locator& loc, const Deref& d);
+///        };
+///
+///        my_locator();
+///        my_locator(const my_locator& pl);
+///
+///        // constructors with dynamic step in y (and x). Only valid for locators with dynamic steps
+///        my_locator(const my_locator& loc, coord_t y_step);
+///        my_locator(const my_locator& loc, coord_t x_step, coord_t y_step, bool transpose);
+///
+///        bool              operator==(const my_locator& p) const;
+///
+///        // return _references_ to horizontal/vertical iterators. Advancing them moves this locator
+///        x_iterator&       x();
+///        y_iterator&       y();
+///        x_iterator const& x() const;
+///        y_iterator const& y() const;
+///
+///        // return the vertical distance to another locator. Some models need the horizontal distance to compute it
+///        y_coord_t         y_distance_to(const my_locator& loc2, x_coord_t xDiff) const;
+///
+///        // return true iff incrementing an x-iterator located at the last column will position it at the first 
+///        // column of the next row. Some models need the image width to determine that.
+///        bool              is_1d_traversable(x_coord_t width) const;
+/// };
+/// \endcode
+///
+/// Models may choose to override some of the functions in the base class with more efficient versions.
+///
+
+template <typename Loc, typename XIterator, typename YIterator>    // The concrete subclass, the X-iterator and the Y-iterator
+class pixel_2d_locator_base {
+public:
+    typedef XIterator           x_iterator;
+    typedef YIterator           y_iterator;
+
+    // typedefs required by ConstRandomAccessNDLocatorConcept
+    static const std::size_t num_dimensions=2;
+    typedef typename std::iterator_traits<x_iterator>::value_type       value_type;
+    typedef typename std::iterator_traits<x_iterator>::reference        reference;    // result of dereferencing
+    typedef typename std::iterator_traits<x_iterator>::difference_type  coord_t;      // 1D difference type (same for all dimensions)
+    typedef point2<coord_t>                                             difference_type; // result of operator-(locator,locator)
+    typedef difference_type                                             point_t;
+    template <std::size_t D> struct axis {
+        typedef typename detail::locator_axis<D,Loc>::coord_t           coord_t;
+        typedef typename detail::locator_axis<D,Loc>::iterator          iterator;
+    };
+
+// typedefs required by ConstRandomAccess2DLocatorConcept
+    typedef typename point_t::template axis<0>::coord_t                 x_coord_t;
+    typedef typename point_t::template axis<1>::coord_t                 y_coord_t;
+
+    bool              operator!=(const Loc& p)          const { return !(concrete()==p); }
+
+    x_iterator        x_at(x_coord_t dx, y_coord_t dy)  const { Loc tmp=concrete(); tmp+=point_t(dx,dy); return tmp.x(); }
+    x_iterator        x_at(const difference_type& d)    const { Loc tmp=concrete(); tmp+=d;              return tmp.x(); }
+    y_iterator        y_at(x_coord_t dx, y_coord_t dy)  const { Loc tmp=concrete(); tmp+=point_t(dx,dy); return tmp.y(); }
+    y_iterator        y_at(const difference_type& d)    const { Loc tmp=concrete(); tmp+=d;              return tmp.y(); }
+    Loc               xy_at(x_coord_t dx, y_coord_t dy) const { Loc tmp=concrete(); tmp+=point_t(dx,dy); return tmp; }
+    Loc               xy_at(const difference_type& d)   const { Loc tmp=concrete(); tmp+=d;              return tmp; }
+
+    template <std::size_t D> typename axis<D>::iterator&       axis_iterator()                       { return detail::locator_axis<D,Loc>()(concrete()); }
+    template <std::size_t D> typename axis<D>::iterator const& axis_iterator()                 const { return detail::locator_axis<D,Loc>()(concrete()); }
+    template <std::size_t D> typename axis<D>::iterator        axis_iterator(const point_t& p) const { return detail::locator_axis<D,Loc>()(concrete(),p); }
+
+    reference         operator()(x_coord_t dx, y_coord_t dy) const { return *x_at(dx,dy); }
+    reference         operator[](const difference_type& d)   const { return *x_at(d.x,d.y); }
+
+    reference         operator*()                            const { return *concrete().x(); }
+
+    Loc&              operator+=(const difference_type& d)         { concrete().x()+=d.x; concrete().y()+=d.y; return concrete(); }
+    Loc&              operator-=(const difference_type& d)         { concrete().x()-=d.x; concrete().y()-=d.y; return concrete(); }
+    
+    Loc               operator+(const difference_type& d)    const { return xy_at(d); }
+    Loc               operator-(const difference_type& d)    const { return xy_at(-d); }
+
+    // Some locators can cache 2D coordinates for faster subsequent access. By default there is no caching
+    typedef difference_type    cached_location_t;    
+    cached_location_t cache_location(const difference_type& d)  const { return d; }
+    cached_location_t cache_location(x_coord_t dx, y_coord_t dy)const { return difference_type(dx,dy); }
+
+private:
+    Loc&              concrete()       { return (Loc&)*this; }
+    const Loc&        concrete() const { return (const Loc&)*this; }
+
+    template <typename X> friend class pixel_2d_locator;
+};
+
+// helper classes for each axis of pixel_2d_locator_base
+namespace detail {
+    template <typename Loc> 
+    class locator_axis<0,Loc> {
+        typedef typename Loc::point_t                       point_t;
+    public:
+        typedef typename point_t::template axis<0>::coord_t coord_t;
+        typedef typename Loc::x_iterator                    iterator;
+
+        inline iterator&        operator()(      Loc& loc)                   const { return loc.x(); }
+        inline iterator  const& operator()(const Loc& loc)                   const { return loc.x(); }
+        inline iterator         operator()(      Loc& loc, const point_t& d) const { return loc.x_at(d); }
+        inline iterator         operator()(const Loc& loc, const point_t& d) const { return loc.x_at(d); }
+    };
+
+    template <typename Loc> 
+    class locator_axis<1,Loc> {
+        typedef typename Loc::point_t                       point_t;
+    public:
+        typedef typename point_t::template axis<1>::coord_t coord_t;
+        typedef typename Loc::y_iterator                    iterator;
+
+        inline iterator&        operator()(      Loc& loc)               const { return loc.y(); }
+        inline iterator const&  operator()(const Loc& loc)               const { return loc.y(); }
+        inline iterator     operator()(      Loc& loc, const point_t& d) const { return loc.y_at(d); }
+        inline iterator     operator()(const Loc& loc, const point_t& d) const { return loc.y_at(d); }
+    };
+}
+
+template <typename Loc, typename XIt, typename YIt>
+struct channel_type<pixel_2d_locator_base<Loc,XIt,YIt> > : public channel_type<XIt> {};
+
+template <typename Loc, typename XIt, typename YIt>
+struct color_space_type<pixel_2d_locator_base<Loc,XIt,YIt> > : public color_space_type<XIt> {};
+
+template <typename Loc, typename XIt, typename YIt>
+struct channel_mapping_type<pixel_2d_locator_base<Loc,XIt,YIt> > : public channel_mapping_type<XIt> {};
+
+template <typename Loc, typename XIt, typename YIt>
+struct is_planar<pixel_2d_locator_base<Loc,XIt,YIt> > : public is_planar<XIt> {};
+
+/// \class memory_based_2d_locator
+/// \brief Memory-based pixel locator. Models: PixelLocatorConcept,HasDynamicXStepTypeConcept,HasDynamicYStepTypeConcept,HasTransposedTypeConcept
+/// \ingroup PixelLocatorModel PixelBasedModel
+///
+/// The class takes a step iterator as a parameter. The step iterator provides navigation along the vertical axis
+/// while its base iterator provides horizontal navigation.
+///
+/// Each instantiation is optimal in terms of size and efficiency.
+/// For example, xy locator over interleaved rgb image results in a step iterator consisting of 
+/// one std::ptrdiff_t for the row size and one native pointer (8 bytes total). ++locator.x() resolves to pointer 
+/// increment. At the other extreme, a 2D navigation of the even pixels of a planar CMYK image results in a step 
+/// iterator consisting of one std::ptrdiff_t for the doubled row size, and one step iterator consisting of 
+/// 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 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 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<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;
+    typedef typename parent_t::y_coord_t        y_coord_t;
+    typedef typename parent_t::x_iterator       x_iterator;
+    typedef typename parent_t::y_iterator       y_iterator;
+    typedef typename parent_t::difference_type  difference_type;
+    typedef typename parent_t::reference        reference;
+
+    template <typename Deref> struct add_deref {
+        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)); 
+        }
+    };
+
+    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; }
+
+    x_iterator const&     x()                          const { return _p.base(); }
+    y_iterator const&     y()                          const { return _p; }
+    x_iterator&           x()                                { return _p.base(); }
+    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 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 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_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_size()-pixel_size()*width==0; }   // is there no gap at the end of each row?
+    bool                   is_1d_traversable( x_coord_t const width )   const
+    {
+        /// \todo The ** case might not be safe for algorithms that expect an
+        /// exact number of elements/iterations or are not stable for all input
+        /// values (that might happen at the padding tail at the end of rows) so
+        /// this must be reconsidered and reimplemented.
+        ///                                   (10.10.2010.) (Domagoj Saric)
+        bool const compile_time_detection
+        (
+            ( pixel_size()                    == 1 ) ||
+            ( pixel_size() % sizeof( void * ) == 0 ) ||
+            ( // ...**...
+                ( pixel_size() % 2 == 0                ) &&
+                ( pixel_size()      < sizeof( void * ) )
+            )
+        );
+
+        // Use unsigned division and use 32/16 division to avoid the
+        // unnecessary cdq x86 instruction.
+        //( static_cast<unsigned int>( row_size() * 8 ) % static_cast<unsigned short>( pixel_size() * 8 ) == 0 )
+        bool const run_time_detection
+        (
+            (
+                static_cast<unsigned int  >( row_size  () )
+                    -
+                static_cast<unsigned short>( pixel_size() )
+                    *
+                static_cast<unsigned int  >( width        )
+            ) == 0
+        );
+
+        return compile_time_detection || run_time_detection;
+    }
+
+    // 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=memunit_distance(x(),p2.x())-pixel_size()*xDiff;
+        assert(( rowDiff % row_size())==0);
+        return rowDiff / row_size();
+    }
+
+private:
+    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;
+};
+
+/////////////////////////////
+//  PixelBasedConcept
+/////////////////////////////
+
+template <typename SI>
+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<memory_based_2d_locator<SI> > : public channel_mapping_type<typename memory_based_2d_locator<SI>::parent_t> {
+};
+
+template <typename SI>
+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<memory_based_2d_locator<SI> > : public channel_type<typename memory_based_2d_locator<SI>::parent_t> {
+};
+
+/////////////////////////////
+//  HasDynamicXStepTypeConcept
+/////////////////////////////
+
+// 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<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 memory_based_2d_locator<dynamic_step_base_t> type;
+};
+
+/////////////////////////////
+//  HasDynamicYStepTypeConcept
+/////////////////////////////
+
+template <typename SI>
+struct dynamic_y_step_type<memory_based_2d_locator<SI> > {
+    typedef memory_based_2d_locator<SI> type;
+};
+
+} }  // namespace boost::gil
+
+#endif
Added: sandbox/gil/boost/gil/utilities.hpp
==============================================================================
--- (empty file)
+++ sandbox/gil/boost/gil/utilities.hpp	2010-10-10 12:42:02 EDT (Sun, 10 Oct 2010)
@@ -0,0 +1,333 @@
+/*
+    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_UTILITIES_H
+#define GIL_UTILITIES_H
+
+#include "gil_config.hpp"
+#include <functional>
+#include <boost/config/no_tr1/cmath.hpp>
+#include <cstddef>
+#include <algorithm>
+#include <utility>
+#include <iterator>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/distance.hpp>
+#include <boost/mpl/begin.hpp>
+#include <boost/mpl/find.hpp>
+#include <boost/mpl/range_c.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+
+////////////////////////////////////////////////////////////////////////////////////////
+/// \file               
+/// \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 September 18, 2007
+///
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+namespace boost { namespace gil {
+
+/**
+\addtogroup PointModel
+
+Example:
+\code
+point2<std::ptrdiff_t> 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
+///
+/// \brief 2D point both axes of which have the same dimension type
+/// \ingroup PointModel
+/// Models: Point2DConcept
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+template <typename T>
+class point2 {
+public:
+    typedef T value_type;
+    template <std::size_t D> struct axis { typedef value_type coord_t; };
+    static const std::size_t num_dimensions=2;
+
+    point2()                : x(0),     y(0)    {}
+    point2(T newX, T newY)  : x(newX),  y(newY) {}
+    point2(const point2& p) : x(p.x), y(p.y) {}
+    #ifndef BOOST_MSVC
+        ~point2() {} // This creates (fake) EH states which bug the MSVC++ optimizer...
+    #endif // BOOST_MSVC
+
+    point2& operator=(const point2& p)            { x=p.x; y=p.y; return *this; }
+
+    point2        operator<<(std::ptrdiff_t shift)         const   { return point2(x<<shift,y<<shift); }
+    point2        operator>>(std::ptrdiff_t shift)         const   { return point2(x>>shift,y>>shift); }
+    point2& operator+=(const point2& p)           { x+=p.x; y+=p.y; return *this; }
+    point2& operator-=(const point2& p)           { x-=p.x; y-=p.y; return *this; }
+    point2& operator/=(double t)                  { x/=t; y/=t; return *this; }
+
+    const T& operator[](std::size_t i)          const   { return this->*mem_array[i]; }
+          T& operator[](std::size_t i)                  { return this->*mem_array[i]; }
+
+    T x,y;
+private:
+    // this static array of pointers to member variables makes operator[] safe and doesn't seem to exhibit any performance penalty
+    static T point2<T>::* const mem_array[num_dimensions];
+};
+
+template <typename T>
+T point2<T>::* const point2<T>::mem_array[point2<T>::num_dimensions] = { &point2<T>::x, &point2<T>::y };
+
+/// \ingroup PointModel
+template <typename T> GIL_FORCEINLINE
+bool operator==(const point2<T>& p1, const point2<T>& p2) { return (p1.x==p2.x && p1.y==p2.y); }
+/// \ingroup PointModel
+template <typename T> GIL_FORCEINLINE
+bool operator!=(const point2<T>& p1, const point2<T>& p2) { return  p1.x!=p2.x || p1.y!=p2.y; }
+/// \ingroup PointModel
+template <typename T> GIL_FORCEINLINE
+point2<T> operator+(const point2<T>& p1, const point2<T>& p2) { return point2<T>(p1.x+p2.x,p1.y+p2.y); }
+/// \ingroup PointModel
+template <typename T> GIL_FORCEINLINE
+point2<T> operator-(const point2<T>& p) { return point2<T>(-p.x,-p.y); }
+/// \ingroup PointModel
+template <typename T> GIL_FORCEINLINE
+point2<T> operator-(const point2<T>& p1, const point2<T>& p2) { return point2<T>(p1.x-p2.x,p1.y-p2.y); }
+/// \ingroup PointModel
+template <typename T> GIL_FORCEINLINE
+point2<double> operator/(const point2<T>& p, double t)      { return t==0 ? point2<double>(0,0):point2<double>(p.x/t,p.y/t); }
+/// \ingroup PointModel
+template <typename T> GIL_FORCEINLINE
+point2<T> operator*(const point2<T>& p, std::ptrdiff_t t)      { return point2<T>(p.x*t,p.y*t); }
+/// \ingroup PointModel
+template <typename T> GIL_FORCEINLINE
+point2<T> operator*(std::ptrdiff_t t, const point2<T>& p)      { return point2<T>(p.x*t,p.y*t); }
+
+/// \ingroup PointModel
+template <std::size_t K, typename T> GIL_FORCEINLINE
+const T& axis_value(const point2<T>& p) { return p[K]; }
+
+/// \ingroup PointModel
+template <std::size_t K, typename T> GIL_FORCEINLINE
+      T& axis_value(      point2<T>& p) { return p[K]; }
+
+////////////////////////////////////////////////////////////////////////////////////////
+///
+///  Rounding of real numbers / points to integers / integer points
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+inline std::ptrdiff_t iround(float x ) { return static_cast<std::ptrdiff_t>(x + (x < 0.0f ? -0.5f : 0.5f)); }
+inline std::ptrdiff_t iround(double x) { return static_cast<std::ptrdiff_t>(x + (x < 0.0 ? -0.5 : 0.5)); }
+inline std::ptrdiff_t ifloor(float x ) { return static_cast<std::ptrdiff_t>(std::floor(x)); }
+inline std::ptrdiff_t ifloor(double x) { return static_cast<std::ptrdiff_t>(std::floor(x)); }
+inline std::ptrdiff_t iceil(float x )  { return static_cast<std::ptrdiff_t>(std::ceil(x)); }
+inline std::ptrdiff_t iceil(double x)  { return static_cast<std::ptrdiff_t>(std::ceil(x)); }
+
+/**
+\addtogroup PointAlgorithm
+
+Example:
+\code
+assert(iround(point2<double>(3.1, 3.9)) == point2<std::ptrdiff_t>(3,4));
+\endcode
+*/
+
+/// \ingroup PointAlgorithm
+inline point2<std::ptrdiff_t> iround(const point2<float >& p)  { return point2<std::ptrdiff_t>(iround(p.x),iround(p.y)); }
+/// \ingroup PointAlgorithm
+inline point2<std::ptrdiff_t> iround(const point2<double>& p)  { return point2<std::ptrdiff_t>(iround(p.x),iround(p.y)); }
+/// \ingroup PointAlgorithm
+inline point2<std::ptrdiff_t> ifloor(const point2<float >& p)  { return point2<std::ptrdiff_t>(ifloor(p.x),ifloor(p.y)); }
+/// \ingroup PointAlgorithm
+inline point2<std::ptrdiff_t> ifloor(const point2<double>& p)  { return point2<std::ptrdiff_t>(ifloor(p.x),ifloor(p.y)); }
+/// \ingroup PointAlgorithm
+inline point2<std::ptrdiff_t> iceil (const point2<float >& p)  { return point2<std::ptrdiff_t>(iceil(p.x), iceil(p.y)); }
+/// \ingroup PointAlgorithm
+inline point2<std::ptrdiff_t> iceil (const point2<double>& p)  { return point2<std::ptrdiff_t>(iceil(p.x), iceil(p.y)); }
+
+////////////////////////////////////////////////////////////////////////////////////////
+///
+///  computing size with alignment
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+template <typename T> 
+inline T align(T val, std::size_t alignment) { 
+    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 : 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 typename D2::argument_type   argument_type;
+    typedef typename D1::result_type     result_type;
+
+    deref_compose() {}
+    deref_compose(const D1& x, const D2& y) : _fn1(x), _fn2(y) {}
+    deref_compose(const deref_compose& dc)  : _fn1(dc._fn1), _fn2(dc._fn2) {}
+    template <typename _D1, typename _D2> deref_compose(const deref_compose<_D1,_D2>& dc) : _fn1(dc._fn1), _fn2(dc._fn2) {}
+
+    result_type operator()(argument_type x) const { return _fn1(_fn2(x)); }
+    result_type operator()(argument_type x)       { return _fn1(_fn2(x)); }
+};
+
+// reinterpret_cast is implementation-defined. Static cast is not.
+template <typename OutPtr, typename In> GIL_FORCEINLINE
+      OutPtr gil_reinterpret_cast(      In* p) { return static_cast<OutPtr>(static_cast<void*>(p)); }
+
+template <typename OutPtr, typename In> GIL_FORCEINLINE
+const OutPtr gil_reinterpret_cast_c(const In* p) { return static_cast<const OutPtr>(static_cast<const void*>(p)); }
+
+namespace detail {
+
+////////////////////////////////////////////////////////////////////////////////////////
+///
+///  \brief copy_n taken from SGI STL.
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+template <class InputIter, class Size, class OutputIter>
+std::pair<InputIter, OutputIter> _copy_n(InputIter first, Size count,
+                                         OutputIter result,
+                                         std::input_iterator_tag) {
+   for ( ; count > 0; --count) {
+      *result = *first;
+      ++first;
+      ++result;
+   }
+   return std::pair<InputIter, OutputIter>(first, result);
+}
+
+template <class RAIter, class Size, class OutputIter>
+inline std::pair<RAIter, OutputIter>
+_copy_n(RAIter first, Size count, OutputIter result, std::random_access_iterator_tag) {
+   RAIter last = first + count;
+   return std::pair<RAIter, OutputIter>(last, std::copy(first, last, result));
+}
+
+template <class InputIter, class Size, class OutputIter>
+inline std::pair<InputIter, OutputIter>
+_copy_n(InputIter first, Size count, OutputIter result) {
+   return _copy_n(first, count, result, typename std::iterator_traits<InputIter>::iterator_category());
+}
+
+template <class InputIter, class Size, class OutputIter>
+inline std::pair<InputIter, OutputIter>
+copy_n(InputIter first, Size count, OutputIter result) {
+    return detail::_copy_n(first, count, result);
+}
+
+/// \brief identity taken from SGI STL.
+template <typename T> 
+struct identity : public std::unary_function<T,T> {
+    const T& operator()(const T& val) const { return val; }
+};
+
+/*************************************************************************************************/
+
+/// \brief plus function object whose arguments may be of different type.
+template <typename T1, typename T2>
+struct plus_asymmetric : public std::binary_function<T1,T2,T1> {
+    T1 operator()(T1 f1, T2 f2) const {
+        return f1+f2;
+    }
+};
+
+/*************************************************************************************************/
+
+/// \brief operator++ wrapped in a function object
+template <typename T>
+struct inc : public std::unary_function<T,T> {
+    T operator()(T x) const { return ++x; }
+};
+
+/*************************************************************************************************/
+
+/// \brief operator-- wrapped in a function object
+template <typename T>
+struct dec : public std::unary_function<T,T> {
+    T operator()(T x) const { return --x; }
+};
+
+/// \brief Returns the index corresponding to the first occurrance of a given given type in 
+//         a given MPL RandomAccessSequence (or size if the type is not present)
+template <typename Types, typename T>
+struct type_to_index 
+    : public mpl::distance<typename mpl::begin<Types>::type, 
+                                  typename mpl::find<Types,T>::type>::type {};
+} // namespace detail
+
+
+
+/// \ingroup ColorSpaceAndLayoutModel
+/// \brief Represents a color space and ordering of channels in memory
+template <typename ColorSpace, typename ChannelMapping = mpl::range_c<int,0,mpl::size<ColorSpace>::value> >
+struct layout {
+    typedef ColorSpace      color_space_t;
+    typedef ChannelMapping  channel_mapping_t;
+};
+
+/// \brief A version of swap that also works with reference proxy objects
+template <typename Value, typename T1, typename T2> // where value_type<T1>  == value_type<T2> == Value
+void swap_proxy(T1& left, T2& right) {
+    Value tmp = left;
+    left = right;
+    right = tmp;
+}
+
+/// \brief Run-time detection of whether the underlying architecture is little endian
+inline bool little_endian() {
+    short tester = 0x0001;
+    return  *(char*)&tester!=0;
+}
+/// \brief Run-time detection of whether the underlying architecture is big endian
+inline bool big_endian() {
+    return !little_endian();
+}
+
+} }  // namespace boost::gil
+
+#endif