Added boost header

This commit is contained in:
Christophe Riccio
2012-01-08 01:26:07 +00:00
parent 9c3faaca40
commit c7d752cdf8
8946 changed files with 1732316 additions and 0 deletions

View File

@@ -0,0 +1,173 @@
/*
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_DYNAMICIMAGE_ALGORITHM_HPP
#define GIL_DYNAMICIMAGE_ALGORITHM_HPP
#include "../../algorithm.hpp"
#include "any_image.hpp"
#include <boost/bind.hpp>
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Some basic STL-style algorithms when applied to runtime type specified image views
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on September 24, 2006
///
////////////////////////////////////////////////////////////////////////////////////////
namespace boost { namespace gil {
namespace detail {
struct equal_pixels_fn : public binary_operation_obj<equal_pixels_fn,bool> {
template <typename V1, typename V2>
GIL_FORCEINLINE bool apply_compatible(const V1& v1, const V2& v2) const {
return equal_pixels(v1,v2);
}
};
} // namespace detail
/// \ingroup ImageViewSTLAlgorithmsEqualPixels
template <typename Types1, // Model MPL Random Access Container of models of ImageViewConcept
typename View2> // Model MutableImageViewConcept
bool equal_pixels(const any_image_view<Types1>& src, const View2& dst) {
return apply_operation(src,boost::bind(detail::equal_pixels_fn(), _1, dst));
}
/// \ingroup ImageViewSTLAlgorithmsEqualPixels
template <typename View1, // Model ImageViewConcept
typename Types2> // Model MPL Random Access Container of models of MutableImageViewConcept
bool equal_pixels(const View1& src, const any_image_view<Types2>& dst) {
return apply_operation(dst,boost::bind(detail::equal_pixels_fn(), src, _1));
}
/// \ingroup ImageViewSTLAlgorithmsEqualPixels
template <typename Types1, // Model MPL Random Access Container of models of ImageViewConcept
typename Types2> // Model MPL Random Access Container of models of MutableImageViewConcept
bool equal_pixels(const any_image_view<Types1>& src, const any_image_view<Types2>& dst) {
return apply_operation(src,dst,detail::equal_pixels_fn());
}
namespace detail {
struct copy_pixels_fn : public binary_operation_obj<copy_pixels_fn> {
template <typename View1, typename View2>
GIL_FORCEINLINE void apply_compatible(const View1& src, const View2& dst) const {
copy_pixels(src,dst);
}
};
}
/// \ingroup ImageViewSTLAlgorithmsCopyPixels
template <typename Types1, // Model MPL Random Access Container of models of ImageViewConcept
typename View2> // Model MutableImageViewConcept
void copy_pixels(const any_image_view<Types1>& src, const View2& dst) {
apply_operation(src,boost::bind(detail::copy_pixels_fn(), _1, dst));
}
/// \ingroup ImageViewSTLAlgorithmsCopyPixels
template <typename View1, // Model ImageViewConcept
typename Types2> // Model MPL Random Access Container of models of MutableImageViewConcept
void copy_pixels(const View1& src, const any_image_view<Types2>& dst) {
apply_operation(dst,boost::bind(detail::copy_pixels_fn(), src, _1));
}
/// \ingroup ImageViewSTLAlgorithmsCopyPixels
template <typename Types1, // Model MPL Random Access Container of models of ImageViewConcept
typename Types2> // Model MPL Random Access Container of models of MutableImageViewConcept
void copy_pixels(const any_image_view<Types1>& src, const any_image_view<Types2>& dst) {
apply_operation(src,dst,detail::copy_pixels_fn());
}
//forward declaration for default_color_converter (see full definition in color_convert.hpp)
struct default_color_converter;
/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
template <typename Types1, // Model MPL Random Access Container of models of ImageViewConcept
typename View2, // Model MutableImageViewConcept
typename CC> // Model ColorConverterConcept
void copy_and_convert_pixels(const any_image_view<Types1>& src, const View2& dst, CC cc) {
apply_operation(src,boost::bind(detail::copy_and_convert_pixels_fn<CC>(cc), _1, dst));
}
/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
template <typename Types1, // Model MPL Random Access Container of models of ImageViewConcept
typename View2> // Model MutableImageViewConcept
void copy_and_convert_pixels(const any_image_view<Types1>& src, const View2& dst) {
apply_operation(src,boost::bind(detail::copy_and_convert_pixels_fn<default_color_converter>(), _1, dst));
}
/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
template <typename View1, // Model ImageViewConcept
typename Types2, // Model MPL Random Access Container of models of MutableImageViewConcept
typename CC> // Model ColorConverterConcept
void copy_and_convert_pixels(const View1& src, const any_image_view<Types2>& dst, CC cc) {
apply_operation(dst,boost::bind(detail::copy_and_convert_pixels_fn<CC>(cc), src, _1));
}
/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
template <typename View1, // Model ImageViewConcept
typename Types2> // Model MPL Random Access Container of models of MutableImageViewConcept
void copy_and_convert_pixels(const View1& src, const any_image_view<Types2>& dst) {
apply_operation(dst,boost::bind(detail::copy_and_convert_pixels_fn<default_color_converter>(), src, _1));
}
/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
template <typename Types1, // Model MPL Random Access Container of models of ImageViewConcept
typename Types2, // Model MPL Random Access Container of models of MutableImageViewConcept
typename CC> // Model ColorConverterConcept
void copy_and_convert_pixels(const any_image_view<Types1>& src, const any_image_view<Types2>& dst, CC cc) {
apply_operation(src,dst,detail::copy_and_convert_pixels_fn<CC>(cc));
}
/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
template <typename Types1, // Model MPL Random Access Container of models of ImageViewConcept
typename Types2> // Model MPL Random Access Container of models of MutableImageViewConcept
void copy_and_convert_pixels(const any_image_view<Types1>& src, const any_image_view<Types2>& dst) {
apply_operation(src,dst,detail::copy_and_convert_pixels_fn<default_color_converter>());
}
namespace detail {
template <bool COMPATIBLE> struct fill_pixels_fn1 {
template <typename V, typename Value> static void apply(const V& src, const Value& val) { fill_pixels(src,val); }
};
// copy_pixels invoked on incompatible images
template <> struct fill_pixels_fn1<false> {
template <typename V, typename Value> static void apply(const V& src, const Value& val) { throw std::bad_cast();}
};
template <typename Value>
struct fill_pixels_fn {
fill_pixels_fn(const Value& val) : _val(val) {}
typedef void result_type;
template <typename V> result_type operator()(const V& img_view) const {
fill_pixels_fn1<pixels_are_compatible<typename V::value_type, Value>::value>::apply(img_view,_val);
}
Value _val;
};
}
/// \ingroup ImageViewSTLAlgorithmsFillPixels
/// \brief fill_pixels for any image view. The pixel to fill with must be compatible with the current view
template <typename Types, // Model MPL Random Access Container of models of MutableImageViewConcept
typename Value>
void fill_pixels(const any_image_view<Types>& img_view, const Value& val) {
apply_operation(img_view,detail::fill_pixels_fn<Value>(val));
}
} } // namespace boost::gil
#endif

View File

@@ -0,0 +1,125 @@
/*
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_DYNAMICIMAGE_ANY_IMAGE_HPP
#define GIL_DYNAMICIMAGE_ANY_IMAGE_HPP
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Support for run-time instantiated images and image views
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
///
///
////////////////////////////////////////////////////////////////////////////////////////
#include "any_image_view.hpp"
#include "../../image.hpp"
//#ifdef _MSC_VER
//#pragma warning(push)
//#pragma warning(disable : 4244) // conversion from 'std::ptrdiff_t' to 'int', possible loss of data. even if we static-assert the two types are the same (on visual studio 8)
//#endif
namespace boost { namespace gil {
namespace detail {
template <typename T> struct get_view_t { typedef typename T::view_t type; };
template <typename Images> struct images_get_views_t : public mpl::transform<Images, get_view_t<mpl::_1> > {};
template <typename T> struct get_const_view_t { typedef typename T::const_view_t type; };
template <typename Images> struct images_get_const_views_t : public mpl::transform<Images, get_const_view_t<mpl::_1> > {};
struct recreate_image_fnobj {
typedef void result_type;
const point2<std::ptrdiff_t>& _dimensions;
unsigned _alignment;
recreate_image_fnobj(const point2<std::ptrdiff_t>& dims, unsigned alignment) : _dimensions(dims), _alignment(alignment) {}
template <typename Image> result_type operator()(Image& img) const { img.recreate(_dimensions,_alignment); }
};
template <typename AnyView> // Models AnyViewConcept
struct any_image_get_view {
typedef AnyView result_type;
template <typename Image> result_type operator()( Image& img) const { return result_type(view(img)); }
};
template <typename AnyConstView> // Models AnyConstViewConcept
struct any_image_get_const_view {
typedef AnyConstView result_type;
template <typename Image> result_type operator()(const Image& img) const { return result_type(const_view(img)); }
};
}
////////////////////////////////////////////////////////////////////////////////////////
/// \ingroup ImageModel
/// \brief Represents a run-time specified image. Note it does NOT model ImageConcept
///
/// Represents an image whose type (color space, layout, planar/interleaved organization, etc) can be specified at run time.
/// It is the runtime equivalent of \p image.
/// Some of the requirements of ImageConcept, such as the \p value_type typedef cannot be fulfilled, since the language does not allow runtime type specification.
/// Other requirements, such as access to the pixels, would be inefficient to provide. Thus \p any_image does not fully model ImageConcept.
/// In particular, its \p view and \p const_view methods return \p any_image_view, which does not fully model ImageViewConcept. See \p any_image_view for more.
////////////////////////////////////////////////////////////////////////////////////////
template <typename ImageTypes>
class any_image : public variant<ImageTypes> {
typedef variant<ImageTypes> parent_t;
public:
typedef any_image_view<typename detail::images_get_const_views_t<ImageTypes>::type> const_view_t;
typedef any_image_view<typename detail::images_get_views_t<ImageTypes>::type> view_t;
typedef std::ptrdiff_t x_coord_t;
typedef std::ptrdiff_t y_coord_t;
typedef point2<std::ptrdiff_t> point_t;
any_image() : parent_t() {}
template <typename T> explicit any_image(const T& obj) : parent_t(obj) {}
template <typename T> explicit any_image(T& obj, bool do_swap) : parent_t(obj,do_swap) {}
any_image(const any_image& v) : parent_t((const parent_t&)v) {}
template <typename T> any_image& operator=(const T& obj) { parent_t::operator=(obj); return *this; }
any_image& operator=(const any_image& v) { parent_t::operator=((const parent_t&)v); return *this;}
void recreate(const point_t& dims, unsigned alignment=1) { apply_operation(*this,detail::recreate_image_fnobj(dims,alignment)); }
void recreate(x_coord_t width, y_coord_t height, unsigned alignment=1) { recreate(point2<std::ptrdiff_t>(width,height),alignment); }
std::size_t num_channels() const { return apply_operation(*this, detail::any_type_get_num_channels()); }
point_t dimensions() const { return apply_operation(*this, detail::any_type_get_dimensions()); }
x_coord_t width() const { return dimensions().x; }
y_coord_t height() const { return dimensions().y; }
};
///@{
/// \name view, const_view
/// \brief Get an image view from a run-time instantiated image
/// \ingroup ImageModel
/// \brief Returns the non-constant-pixel view of any image. The returned view is any view.
template <typename Types> GIL_FORCEINLINE // Models ImageVectorConcept
typename any_image<Types>::view_t view(any_image<Types>& anyImage) {
return apply_operation(anyImage, detail::any_image_get_view<typename any_image<Types>::view_t>());
}
/// \brief Returns the constant-pixel view of any image. The returned view is any view.
template <typename Types> GIL_FORCEINLINE // Models ImageVectorConcept
typename any_image<Types>::const_view_t const_view(const any_image<Types>& anyImage) {
return apply_operation(anyImage, detail::any_image_get_const_view<typename any_image<Types>::const_view_t>());
}
///@}
} } // namespace boost::gil
//#ifdef _MSC_VER
//#pragma warning(pop)
//#endif
#endif

View File

@@ -0,0 +1,115 @@
/*
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_DYNAMICIMAGE_ANY_IMAGEVIEW_HPP
#define GIL_DYNAMICIMAGE_ANY_IMAGEVIEW_HPP
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Support for run-time instantiated image view
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
///
///
////////////////////////////////////////////////////////////////////////////////////////
#include "variant.hpp"
#include "../../image_view.hpp"
#include "../../image.hpp"
namespace boost { namespace gil {
namespace detail {
template <typename View> struct get_const_t { typedef typename View::const_t type; };
template <typename Views> struct views_get_const_t : public mpl::transform<Views, get_const_t<mpl::_1> > {};
}
template <typename View> struct dynamic_xy_step_type;
template <typename View> struct dynamic_xy_step_transposed_type;
namespace detail {
struct any_type_get_num_channels { // works for both image_view and image
typedef int result_type;
template <typename T> result_type operator()(const T& v) const { return num_channels<T>::value; }
};
struct any_type_get_dimensions { // works for both image_view and image
typedef point2<std::ptrdiff_t> result_type;
template <typename T> result_type operator()(const T& v) const { return v.dimensions(); }
};
}
////////////////////////////////////////////////////////////////////////////////////////
/// CLASS any_image_view
///
/// \ingroup ImageViewModel
/// \brief Represents a run-time specified image view. Models HasDynamicXStepTypeConcept, HasDynamicYStepTypeConcept, Note that this class does NOT model ImageViewConcept
///
/// Represents a view whose type (color space, layout, planar/interleaved organization, etc) can be specified at run time.
/// It is the runtime equivalent of \p image_view.
/// Some of the requirements of ImageViewConcept, such as the \p value_type typedef cannot be fulfilled, since the language does not allow runtime type specification.
/// Other requirements, such as access to the pixels, would be inefficient to provide. Thus \p any_image_view does not fully model ImageViewConcept.
/// However, many algorithms provide overloads taking runtime specified views and thus in many cases \p any_image_view can be used in places taking a view.
///
/// To perform an algorithm on any_image_view, put the algorithm in a function object and invoke it by calling \p apply_operation(runtime_view, algorithm_fn);
////////////////////////////////////////////////////////////////////////////////////////
template <typename ImageViewTypes>
class any_image_view : public variant<ImageViewTypes> {
typedef variant<ImageViewTypes> parent_t;
public:
typedef any_image_view<typename detail::views_get_const_t<ImageViewTypes>::type> const_t;
typedef std::ptrdiff_t x_coord_t;
typedef std::ptrdiff_t y_coord_t;
typedef point2<std::ptrdiff_t> point_t;
any_image_view() : parent_t() {}
template <typename T> explicit any_image_view(const T& obj) : parent_t(obj) {}
any_image_view(const any_image_view& v) : parent_t((const parent_t&)v) {}
template <typename T> any_image_view& operator=(const T& obj) { parent_t::operator=(obj); return *this; }
any_image_view& operator=(const any_image_view& v) { parent_t::operator=((const parent_t&)v); return *this;}
std::size_t num_channels() const { return apply_operation(*this, detail::any_type_get_num_channels()); }
point_t dimensions() const { return apply_operation(*this, detail::any_type_get_dimensions()); }
x_coord_t width() const { return dimensions().x; }
y_coord_t height() const { return dimensions().y; }
};
/////////////////////////////
// HasDynamicXStepTypeConcept
/////////////////////////////
template <typename IVTypes>
struct dynamic_x_step_type<any_image_view<IVTypes> > {
typedef any_image_view<typename mpl::transform<IVTypes, dynamic_x_step_type<mpl::_1> >::type> type;
};
/////////////////////////////
// HasDynamicYStepTypeConcept
/////////////////////////////
template <typename IVTypes>
struct dynamic_y_step_type<any_image_view<IVTypes> > {
typedef any_image_view<typename mpl::transform<IVTypes, dynamic_y_step_type<mpl::_1> >::type> type;
};
template <typename IVTypes>
struct dynamic_xy_step_type<any_image_view<IVTypes> > {
typedef any_image_view<typename mpl::transform<IVTypes, dynamic_xy_step_type<mpl::_1> >::type> type;
};
template <typename IVTypes>
struct dynamic_xy_step_transposed_type<any_image_view<IVTypes> > {
typedef any_image_view<typename mpl::transform<IVTypes, dynamic_xy_step_transposed_type<mpl::_1> >::type> type;
};
} } // namespace boost::gil
#endif

View File

@@ -0,0 +1,61 @@
/*
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_APPLY_OPERATION_HPP
#define GIL_APPLY_OPERATION_HPP
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Implements apply_operation for variants. Optionally performs type reduction
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on May 4, 2006
///
////////////////////////////////////////////////////////////////////////////////////////
#include "apply_operation_base.hpp"
#include "variant.hpp"
#ifndef GIL_REDUCE_CODE_BLOAT
namespace boost { namespace gil {
/// \ingroup Variant
/// \brief Invokes a generic mutable operation (represented as a unary function object) on a variant
template <typename Types, typename UnaryOp> GIL_FORCEINLINE
typename UnaryOp::result_type apply_operation(variant<Types>& arg, UnaryOp op) {
return apply_operation_base<Types>(arg._bits, arg._index ,op);
}
/// \ingroup Variant
/// \brief Invokes a generic constant operation (represented as a unary function object) on a variant
template <typename Types, typename UnaryOp> GIL_FORCEINLINE
typename UnaryOp::result_type apply_operation(const variant<Types>& arg, UnaryOp op) {
return apply_operation_basec<Types>(arg._bits, arg._index ,op);
}
/// \ingroup Variant
/// \brief Invokes a generic constant operation (represented as a binary function object) on two variants
template <typename Types1, typename Types2, typename BinaryOp> GIL_FORCEINLINE
typename BinaryOp::result_type apply_operation(const variant<Types1>& arg1, const variant<Types2>& arg2, BinaryOp op) {
return apply_operation_base<Types1,Types2>(arg1._bits, arg1._index, arg2._bits, arg2._index, op);
}
} } // namespace boost::gil
#else
#include "reduce.hpp"
#endif
#endif

View File

@@ -0,0 +1,185 @@
/*
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_APPLY_OPERATION_BASE_HPP
#define GIL_APPLY_OPERATION_BASE_HPP
#include "../../gil_config.hpp"
#include "../../utilities.hpp"
#include <boost/mpl/begin.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/size.hpp>
#include <boost/preprocessor/repeat.hpp>
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Given an object with run-time specified type (denoted as an array of Bits, dynamic index, and a static set of Types) and a generic operation,
/// casts the object to its appropriate type and applies the operation
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on November 6, 2007
///
////////////////////////////////////////////////////////////////////////////////////////
namespace boost { namespace gil {
/*
GENERATE_APPLY_FWD_OPS generates for every N functions that look like this (for N==2):
template <> struct apply_operation_fwd_fn<3> {
template <typename Types, typename Bits, typename UnaryOp>
typename UnaryOp::result_type apply(Bits& bits, std::size_t index, UnaryOp op) const {
typedef typename mpl::begin<Types>::type T0;
typedef typename mpl::next<T0>::type T1;
typedef typename mpl::next<T1>::type T2;
switch (index) {
case 0: return op(reinterpret_cast<typename mpl::deref<T0>::type&>(bits));
case 1: return op(reinterpret_cast<typename mpl::deref<T1>::type&>(bits));
case 2: return op(reinterpret_cast<typename mpl::deref<T2>::type&>(bits));
}
throw;
}
template <typename Types, typename Bits, typename UnaryOp>
typename UnaryOp::result_type applyc(const Bits& bits, std::size_t index, UnaryOp op) const {
typedef typename mpl::begin<Types>::type T0;
typedef typename mpl::next<T0>::type T1;
typedef typename mpl::next<T1>::type T2;
switch (index) {
case 0: return op(reinterpret_cast<const typename mpl::deref<T0>::type&>(bits));
case 1: return op(reinterpret_cast<const typename mpl::deref<T1>::type&>(bits));
case 2: return op(reinterpret_cast<const typename mpl::deref<T2>::type&>(bits));
}
throw;
}
};
*/
#define GIL_FWD_TYPEDEFS(z, N, text) T##N; typedef typename mpl::next<T##N>::type
#define GIL_FWD_CASE(z, N, SUM) case N: return op(*gil_reinterpret_cast<typename mpl::deref<T##N>::type*>(&bits));
#define GIL_FWD_CONST_CASE(z, N, SUM) case N: return op(*gil_reinterpret_cast_c<const typename mpl::deref<T##N>::type*>(&bits));
#define GIL_FWD_CASE_WITH_INFO(z, N, SUM) case N: return op(*gil_reinterpret_cast<typename mpl::deref<T##N>::type*>(&bits), info);
#define GIL_FWD_CONST_CASE_WITH_INFO(z, N, SUM) case N: return op(*gil_reinterpret_cast_c<const typename mpl::deref<T##N>::type*>(&bits), info);
#define GIL_APPLY_FWD_OP(z, N, text) \
template <> struct apply_operation_fwd_fn<BOOST_PP_ADD(N,1)> { \
template <typename Types, typename Bits, typename UnaryOp> \
typename UnaryOp::result_type apply(Bits& bits, std::size_t index, UnaryOp op) const { \
typedef typename mpl::begin<Types>::type \
BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \
T##N; \
switch (index) { \
BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CASE, BOOST_PP_EMPTY) \
} \
throw; \
} \
template <typename Types, typename Bits, typename UnaryOp> \
typename UnaryOp::result_type applyc(const Bits& bits, std::size_t index, UnaryOp op) const { \
typedef typename mpl::begin<Types>::type \
BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \
T##N; \
switch (index) { \
BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CONST_CASE,BOOST_PP_EMPTY) \
} \
throw; \
} \
template <typename Types, typename Info, typename Bits, typename UnaryOp> \
typename UnaryOp::result_type apply(Bits& bits, std::size_t index, const Info& info, UnaryOp op) const { \
typedef typename mpl::begin<Types>::type \
BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \
T##N; \
switch (index) { \
BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CASE_WITH_INFO, BOOST_PP_EMPTY) \
} \
throw; \
} \
template <typename Types, typename Bits, typename Info, typename UnaryOp> \
typename UnaryOp::result_type applyc(const Bits& bits, std::size_t index, const Info& info, UnaryOp op) const { \
typedef typename mpl::begin<Types>::type \
BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \
T##N; \
switch (index) { \
BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CONST_CASE_WITH_INFO,BOOST_PP_EMPTY) \
} \
throw; \
} \
};
#define GIL_GENERATE_APPLY_FWD_OPS(N) BOOST_PP_REPEAT(N, GIL_APPLY_FWD_OP, BOOST_PP_EMPTY)
namespace detail {
template <std::size_t N> struct apply_operation_fwd_fn {};
// Create specializations of apply_operation_fn for each N 0..100
GIL_GENERATE_APPLY_FWD_OPS(99)
} // namespace detail
// unary application
template <typename Types, typename Bits, typename Op>
typename Op::result_type GIL_FORCEINLINE apply_operation_basec(const Bits& bits, std::size_t index, Op op) {
return detail::apply_operation_fwd_fn<mpl::size<Types>::value>().template applyc<Types>(bits,index,op);
}
// unary application
template <typename Types, typename Bits, typename Op>
typename Op::result_type GIL_FORCEINLINE apply_operation_base( Bits& bits, std::size_t index, Op op) {
return detail::apply_operation_fwd_fn<mpl::size<Types>::value>().template apply<Types>(bits,index,op);
}
namespace detail {
template <typename T2, typename Op>
struct reduce_bind1 {
const T2& _t2;
Op& _op;
typedef typename Op::result_type result_type;
reduce_bind1(const T2& t2, Op& op) : _t2(t2), _op(op) {}
template <typename T1> GIL_FORCEINLINE result_type operator()(const T1& t1) { return _op(t1, _t2); }
};
template <typename Types1, typename Bits1, typename Op>
struct reduce_bind2 {
const Bits1& _bits1;
std::size_t _index1;
Op& _op;
typedef typename Op::result_type result_type;
reduce_bind2(const Bits1& bits1, std::size_t index1, Op& op) : _bits1(bits1), _index1(index1), _op(op) {}
template <typename T2> GIL_FORCEINLINE result_type operator()(const T2& t2) {
return apply_operation_basec<Types1>(_bits1, _index1, reduce_bind1<T2,Op>(t2, _op));
}
};
} // namespace detail
// Binary application by applying on each dimension separately
template <typename Types1, typename Types2, typename Bits1, typename Bits2, typename Op>
static typename Op::result_type GIL_FORCEINLINE apply_operation_base(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
return apply_operation_basec<Types2>(bits2,index2,detail::reduce_bind2<Types1,Bits1,Op>(bits1,index1,op));
}
#undef GIL_FWD_TYPEDEFS
#undef GIL_FWD_CASE
#undef GIL_FWD_CONST_CASE
#undef GIL_APPLY_FWD_OP
#undef GIL_GENERATE_APPLY_FWD_OPS
#undef BHS
} } // namespace boost::gil
#endif

View File

@@ -0,0 +1,130 @@
/*
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_DYNAMIC_AT_C_HPP
#define GIL_DYNAMIC_AT_C_HPP
#include "../../gil_config.hpp"
#include <cassert>
#include <stdexcept>
#include <boost/mpl/at.hpp>
#include <boost/mpl/size.hpp>
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Constructs for static-to-dynamic integer convesion
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on May 4, 2006
///
////////////////////////////////////////////////////////////////////////////////////////
namespace boost { namespace gil {
#define GIL_AT_C_VALUE(z, N, text) mpl::at_c<IntTypes,S+N>::type::value,
#define GIL_DYNAMIC_AT_C_LIMIT 226 // size of the maximum vector to handle
#define GIL_AT_C_LOOKUP(z, NUM, text) \
template<std::size_t S> \
struct at_c_fn<S,NUM> { \
template <typename IntTypes, typename ValueType> inline \
static ValueType apply(std::size_t index) { \
static ValueType table[] = { \
BOOST_PP_REPEAT(NUM, GIL_AT_C_VALUE, BOOST_PP_EMPTY) \
}; \
return table[index]; \
} \
};
namespace detail {
namespace at_c {
template <std::size_t START, std::size_t NUM> struct at_c_fn;
BOOST_PP_REPEAT(GIL_DYNAMIC_AT_C_LIMIT, GIL_AT_C_LOOKUP, BOOST_PP_EMPTY)
template <std::size_t QUOT> struct at_c_impl;
template <>
struct at_c_impl<0> {
template <typename IntTypes, typename ValueType> inline
static ValueType apply(std::size_t index) {
return at_c_fn<0,mpl::size<IntTypes>::value>::template apply<IntTypes,ValueType>(index);
}
};
template <>
struct at_c_impl<1> {
template <typename IntTypes, typename ValueType> inline
static ValueType apply(std::size_t index) {
const std::size_t SIZE=mpl::size<IntTypes>::value;
const std::size_t REM = SIZE % GIL_DYNAMIC_AT_C_LIMIT;
switch (index / GIL_DYNAMIC_AT_C_LIMIT) {
case 0: return at_c_fn<0 ,GIL_DYNAMIC_AT_C_LIMIT-1>::template apply<IntTypes,ValueType>(index);
case 1: return at_c_fn<GIL_DYNAMIC_AT_C_LIMIT ,REM >::template apply<IntTypes,ValueType>(index - GIL_DYNAMIC_AT_C_LIMIT);
};
throw;
}
};
template <>
struct at_c_impl<2> {
template <typename IntTypes, typename ValueType> inline
static ValueType apply(std::size_t index) {
const std::size_t SIZE=mpl::size<IntTypes>::value;
const std::size_t REM = SIZE % GIL_DYNAMIC_AT_C_LIMIT;
switch (index / GIL_DYNAMIC_AT_C_LIMIT) {
case 0: return at_c_fn<0 ,GIL_DYNAMIC_AT_C_LIMIT-1>::template apply<IntTypes,ValueType>(index);
case 1: return at_c_fn<GIL_DYNAMIC_AT_C_LIMIT ,GIL_DYNAMIC_AT_C_LIMIT-1>::template apply<IntTypes,ValueType>(index - GIL_DYNAMIC_AT_C_LIMIT);
case 2: return at_c_fn<GIL_DYNAMIC_AT_C_LIMIT*2,REM >::template apply<IntTypes,ValueType>(index - GIL_DYNAMIC_AT_C_LIMIT*2);
};
throw;
}
};
template <>
struct at_c_impl<3> {
template <typename IntTypes, typename ValueType> inline
static ValueType apply(std::size_t index) {
const std::size_t SIZE=mpl::size<IntTypes>::value;
const std::size_t REM = SIZE % GIL_DYNAMIC_AT_C_LIMIT;
switch (index / GIL_DYNAMIC_AT_C_LIMIT) {
case 0: return at_c_fn<0 ,GIL_DYNAMIC_AT_C_LIMIT-1>::template apply<IntTypes,ValueType>(index);
case 1: return at_c_fn<GIL_DYNAMIC_AT_C_LIMIT ,GIL_DYNAMIC_AT_C_LIMIT-1>::template apply<IntTypes,ValueType>(index - GIL_DYNAMIC_AT_C_LIMIT);
case 2: return at_c_fn<GIL_DYNAMIC_AT_C_LIMIT*2,GIL_DYNAMIC_AT_C_LIMIT-1>::template apply<IntTypes,ValueType>(index - GIL_DYNAMIC_AT_C_LIMIT*2);
case 3: return at_c_fn<GIL_DYNAMIC_AT_C_LIMIT*3,REM >::template apply<IntTypes,ValueType>(index - GIL_DYNAMIC_AT_C_LIMIT*3);
};
throw;
}
};
}
}
////////////////////////////////////////////////////////////////////////////////////
///
/// \brief Given an MPL Random Access Sequence and a dynamic index n, returns the value of the n-th element
/// It constructs a lookup table at compile time
///
////////////////////////////////////////////////////////////////////////////////////
template <typename IntTypes, typename ValueType> inline
ValueType at_c(std::size_t index) {
const std::size_t Size=mpl::size<IntTypes>::value;
return detail::at_c::at_c_impl<Size/GIL_DYNAMIC_AT_C_LIMIT>::template apply<IntTypes,ValueType>(index);
}
#undef GIL_AT_C_VALUE
#undef GIL_DYNAMIC_AT_C_LIMIT
#undef GIL_AT_C_LOOKUP
} } // namespace boost::gil
#endif

View File

@@ -0,0 +1,32 @@
/*
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_DYNAMICIMAGE_ALL_HPP
#define GIL_DYNAMICIMAGE_ALL_HPP
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Includes all of the GIL dynamic image extension files, for convenience
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on May 8, 2006
///
////////////////////////////////////////////////////////////////////////////////////////
#include "../../gil_all.hpp"
#include "algorithm.hpp"
#include "any_image.hpp"
#include "apply_operation.hpp"
#include "variant.hpp"
#include "image_view_factory.hpp"
#endif

View File

@@ -0,0 +1,217 @@
/*
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_DYNAMICIMAGE_IMAGE_VIEWS_HPP
#define GIL_DYNAMICIMAGE_IMAGE_VIEWS_HPP
/*!
/// \file
/// \brief Methods for constructing any image views from other any image views
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on January 31, 2007
/// Extends image view factory to runtime type-specified views (any_image_view)
*/
#include "any_image_view.hpp"
#include "../../image_view_factory.hpp"
namespace boost { namespace gil {
namespace detail {
template <typename Result> struct flipped_up_down_view_fn {
typedef Result result_type;
template <typename View> result_type operator()(const View& src) const { return result_type(flipped_up_down_view(src)); }
};
template <typename Result> struct flipped_left_right_view_fn {
typedef Result result_type;
template <typename View> result_type operator()(const View& src) const { return result_type(flipped_left_right_view(src)); }
};
template <typename Result> struct rotated90cw_view_fn {
typedef Result result_type;
template <typename View> result_type operator()(const View& src) const { return result_type(rotated90cw_view(src)); }
};
template <typename Result> struct rotated90ccw_view_fn {
typedef Result result_type;
template <typename View> result_type operator()(const View& src) const { return result_type(rotated90ccw_view(src)); }
};
template <typename Result> struct tranposed_view_fn {
typedef Result result_type;
template <typename View> result_type operator()(const View& src) const { return result_type(tranposed_view(src)); }
};
template <typename Result> struct rotated180_view_fn {
typedef Result result_type;
template <typename View> result_type operator()(const View& src) const { return result_type(rotated180_view(src)); }
};
template <typename Result> struct subimage_view_fn {
typedef Result result_type;
subimage_view_fn(const point2<std::ptrdiff_t>& topleft, const point2<std::ptrdiff_t>& dimensions) : _topleft(topleft), _size2(dimensions) {}
point2<std::ptrdiff_t> _topleft,_size2;
template <typename View> result_type operator()(const View& src) const { return result_type(subimage_view(src,_topleft,_size2)); }
};
template <typename Result> struct subsampled_view_fn {
typedef Result result_type;
subsampled_view_fn(const point2<std::ptrdiff_t>& step) : _step(step) {}
point2<std::ptrdiff_t> _step;
template <typename View> result_type operator()(const View& src) const { return result_type(subsampled_view(src,_step)); }
};
template <typename Result> struct nth_channel_view_fn {
typedef Result result_type;
nth_channel_view_fn(int n) : _n(n) {}
int _n;
template <typename View> result_type operator()(const View& src) const { return result_type(nth_channel_view(src,_n)); }
};
template <typename DstP, typename Result, typename CC = default_color_converter> struct color_converted_view_fn {
typedef Result result_type;
color_converted_view_fn(CC cc = CC()): _cc(cc) {}
template <typename View> result_type operator()(const View& src) const { return result_type(color_converted_view<DstP>(src, _cc)); }
private:
CC _cc;
};
} // namespace detail
/// \ingroup ImageViewTransformationsFlipUD
template <typename ViewTypes> inline // Models MPL Random Access Container of models of ImageViewConcept
typename dynamic_y_step_type<any_image_view<ViewTypes> >::type flipped_up_down_view(const any_image_view<ViewTypes>& src) {
return apply_operation(src,detail::flipped_up_down_view_fn<typename dynamic_y_step_type<any_image_view<ViewTypes> >::type>());
}
/// \ingroup ImageViewTransformationsFlipLR
template <typename ViewTypes> inline // Models MPL Random Access Container of models of ImageViewConcept
typename dynamic_x_step_type<any_image_view<ViewTypes> >::type flipped_left_right_view(const any_image_view<ViewTypes>& src) {
return apply_operation(src,detail::flipped_left_right_view_fn<typename dynamic_x_step_type<any_image_view<ViewTypes> >::type>());
}
/// \ingroup ImageViewTransformationsTransposed
template <typename ViewTypes> inline // Models MPL Random Access Container of models of ImageViewConcept
typename dynamic_xy_step_transposed_type<any_image_view<ViewTypes> >::type transposed_view(const any_image_view<ViewTypes>& src) {
return apply_operation(src,detail::tranposed_view_fn<typename dynamic_xy_step_transposed_type<any_image_view<ViewTypes> >::type>());
}
/// \ingroup ImageViewTransformations90CW
template <typename ViewTypes> inline // Models MPL Random Access Container of models of ImageViewConcept
typename dynamic_xy_step_transposed_type<any_image_view<ViewTypes> >::type rotated90cw_view(const any_image_view<ViewTypes>& src) {
return apply_operation(src,detail::rotated90cw_view_fn<typename dynamic_xy_step_transposed_type<any_image_view<ViewTypes> >::type>());
}
/// \ingroup ImageViewTransformations90CCW
template <typename ViewTypes> inline // Models MPL Random Access Container of models of ImageViewConcept
typename dynamic_xy_step_transposed_type<any_image_view<ViewTypes> >::type rotated90ccw_view(const any_image_view<ViewTypes>& src) {
return apply_operation(src,detail::rotated90ccw_view_fn<typename dynamic_xy_step_transposed_type<any_image_view<ViewTypes> >::type>());
}
/// \ingroup ImageViewTransformations180
template <typename ViewTypes> inline // Models MPL Random Access Container of models of ImageViewConcept
typename dynamic_xy_step_type<any_image_view<ViewTypes> >::type rotated180_view(const any_image_view<ViewTypes>& src) {
return apply_operation(src,detail::rotated180_view_fn<typename dynamic_xy_step_type<any_image_view<ViewTypes> >::type>());
}
/// \ingroup ImageViewTransformationsSubimage
template <typename ViewTypes> inline // Models MPL Random Access Container of models of ImageViewConcept
any_image_view<ViewTypes> subimage_view(const any_image_view<ViewTypes>& src, const point2<std::ptrdiff_t>& topleft, const point2<std::ptrdiff_t>& dimensions) {
return apply_operation(src,detail::subimage_view_fn<any_image_view<ViewTypes> >(topleft,dimensions));
}
/// \ingroup ImageViewTransformationsSubimage
template <typename ViewTypes> inline // Models MPL Random Access Container of models of ImageViewConcept
any_image_view<ViewTypes> subimage_view(const any_image_view<ViewTypes>& src, int xMin, int yMin, int width, int height) {
return apply_operation(src,detail::subimage_view_fn<any_image_view<ViewTypes> >(point2<std::ptrdiff_t>(xMin,yMin),point2<std::ptrdiff_t>(width,height)));
}
/// \ingroup ImageViewTransformationsSubsampled
template <typename ViewTypes> inline // Models MPL Random Access Container of models of ImageViewConcept
typename dynamic_xy_step_type<any_image_view<ViewTypes> >::type subsampled_view(const any_image_view<ViewTypes>& src, const point2<std::ptrdiff_t>& step) {
return apply_operation(src,detail::subsampled_view_fn<typename dynamic_xy_step_type<any_image_view<ViewTypes> >::type>(step));
}
/// \ingroup ImageViewTransformationsSubsampled
template <typename ViewTypes> inline // Models MPL Random Access Container of models of ImageViewConcept
typename dynamic_xy_step_type<any_image_view<ViewTypes> >::type subsampled_view(const any_image_view<ViewTypes>& src, int xStep, int yStep) {
return apply_operation(src,detail::subsampled_view_fn<typename dynamic_xy_step_type<any_image_view<ViewTypes> >::type>(point2<std::ptrdiff_t>(xStep,yStep)));
}
namespace detail {
template <typename View> struct get_nthchannel_type { typedef typename nth_channel_view_type<View>::type type; };
template <typename Views> struct views_get_nthchannel_type : public mpl::transform<Views, get_nthchannel_type<mpl::_1> > {};
}
/// \ingroup ImageViewTransformationsNthChannel
/// \brief Given a runtime source image view, returns the type of a runtime image view over a single channel of the source view
template <typename ViewTypes>
struct nth_channel_view_type<any_image_view<ViewTypes> > {
typedef any_image_view<typename detail::views_get_nthchannel_type<ViewTypes>::type> type;
};
/// \ingroup ImageViewTransformationsNthChannel
template <typename ViewTypes> inline // Models MPL Random Access Container of models of ImageViewConcept
typename nth_channel_view_type<any_image_view<ViewTypes> >::type nth_channel_view(const any_image_view<ViewTypes>& src, int n) {
return apply_operation(src,detail::nth_channel_view_fn<typename nth_channel_view_type<any_image_view<ViewTypes> >::type>(n));
}
namespace detail {
template <typename View, typename DstP, typename CC> struct get_ccv_type : public color_converted_view_type<View, DstP, CC> {};
template <typename Views, typename DstP, typename CC> struct views_get_ccv_type : public mpl::transform<Views, get_ccv_type<mpl::_1,DstP,CC> > {};
}
/// \ingroup ImageViewTransformationsColorConvert
/// \brief Returns the type of a runtime-specified view, color-converted to a given pixel type with user specified color converter
template <typename ViewTypes, typename DstP, typename CC>
struct color_converted_view_type<any_image_view<ViewTypes>,DstP,CC> {
typedef any_image_view<typename detail::views_get_ccv_type<ViewTypes, DstP, CC>::type> type;
};
/// \ingroup ImageViewTransformationsColorConvert
/// \brief overload of generic color_converted_view with user defined color-converter
template <typename DstP, typename ViewTypes, typename CC> inline // Models MPL Random Access Container of models of ImageViewConcept
typename color_converted_view_type<any_image_view<ViewTypes>, DstP, CC>::type color_converted_view(const any_image_view<ViewTypes>& src,CC cc) {
return apply_operation(src,detail::color_converted_view_fn<DstP,typename color_converted_view_type<any_image_view<ViewTypes>, DstP, CC>::type >());
}
/// \ingroup ImageViewTransformationsColorConvert
/// \brief Returns the type of a runtime-specified view, color-converted to a given pixel type with the default coor converter
template <typename ViewTypes, typename DstP>
struct color_converted_view_type<any_image_view<ViewTypes>,DstP> {
typedef any_image_view<typename detail::views_get_ccv_type<ViewTypes, DstP, default_color_converter>::type> type;
};
/// \ingroup ImageViewTransformationsColorConvert
/// \brief overload of generic color_converted_view with the default color-converter
template <typename DstP, typename ViewTypes> inline // Models MPL Random Access Container of models of ImageViewConcept
typename color_converted_view_type<any_image_view<ViewTypes>, DstP>::type color_converted_view(const any_image_view<ViewTypes>& src) {
return apply_operation(src,detail::color_converted_view_fn<DstP,typename color_converted_view_type<any_image_view<ViewTypes>, DstP>::type >());
}
/// \ingroup ImageViewTransformationsColorConvert
/// \brief overload of generic color_converted_view with user defined color-converter
/// These are workarounds for GCC 3.4, which thinks color_converted_view is ambiguous with the same method for templated views (in gil/image_view_factory.hpp)
template <typename DstP, typename ViewTypes, typename CC> inline // Models MPL Random Access Container of models of ImageViewConcept
typename color_converted_view_type<any_image_view<ViewTypes>, DstP, CC>::type any_color_converted_view(const any_image_view<ViewTypes>& src,CC cc) {
return apply_operation(src,detail::color_converted_view_fn<DstP,typename color_converted_view_type<any_image_view<ViewTypes>, DstP, CC>::type >());
}
/// \ingroup ImageViewTransformationsColorConvert
/// \brief overload of generic color_converted_view with the default color-converter
/// These are workarounds for GCC 3.4, which thinks color_converted_view is ambiguous with the same method for templated views (in gil/image_view_factory.hpp)
template <typename DstP, typename ViewTypes> inline // Models MPL Random Access Container of models of ImageViewConcept
typename color_converted_view_type<any_image_view<ViewTypes>, DstP>::type any_color_converted_view(const any_image_view<ViewTypes>& src) {
return apply_operation(src,detail::color_converted_view_fn<DstP,typename color_converted_view_type<any_image_view<ViewTypes>, DstP>::type >());
}
/// \}
} } // namespace boost::gil
#endif

View File

@@ -0,0 +1,789 @@
/*
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_REDUCE_HPP
#define GIL_REDUCE_HPP
#include <boost/mpl/insert_range.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/back.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/long.hpp>
#include <boost/mpl/logical.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/transform.hpp>
#include "../../metafunctions.hpp"
#include "../../typedefs.hpp"
#include "dynamic_at_c.hpp"
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Constructs for static-to-dynamic integer convesion
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on May 4, 2006
///
////////////////////////////////////////////////////////////////////////////////////////
#ifdef GIL_REDUCE_CODE_BLOAT
// Max number of cases in the cross-expension of binary operation for it to be reduced as unary
#define GIL_BINARY_REDUCE_LIMIT 226
namespace boost { namespace mpl {
///////////////////////////////////////////////////////
/// Mapping vector - represents the mapping of one type vector to another
/// It is not a full-blown MPL Random Access Type sequence; just has at_c and size implemented
///
/// SrcTypes, DstTypes: MPL Random Access Type Sequences
///
/// Implements size and at_c to behave as if this is an MPL vector of integers
///////////////////////////////////////////////////////
template <typename SrcTypes, typename DstTypes>
struct mapping_vector {};
template <typename SrcTypes, typename DstTypes, long K>
struct at_c<mapping_vector<SrcTypes,DstTypes>, K> {
static const std::size_t value=size<DstTypes>::value - order<DstTypes, typename at_c<SrcTypes,K>::type>::type::value +1;
typedef size_t<value> type;
};
template <typename SrcTypes, typename DstTypes>
struct size<mapping_vector<SrcTypes,DstTypes> > {
typedef typename size<SrcTypes>::type type;
static const std::size_t value=type::value;
};
///////////////////////////////////////////////////////
/// copy_to_vector - copies a sequence (mpl::set) to vector.
///
/// Temporary solution because I couldn't get mpl::copy to do this.
/// This is what I tried:
/// mpl::copy<SET, mpl::back_inserter<mpl::vector<> > >::type;
/// It works when SET is mpl::vector, but not when SET is mpl::set...
///////////////////////////////////////////////////////
namespace detail {
template <typename SFirst, std::size_t NLeft>
struct copy_to_vector_impl {
private:
typedef typename deref<SFirst>::type T;
typedef typename next<SFirst>::type next;
typedef typename copy_to_vector_impl<next, NLeft-1>::type rest;
public:
typedef typename push_front<rest, T>::type type;
};
template <typename SFirst>
struct copy_to_vector_impl<SFirst,1> {
typedef vector<typename deref<SFirst>::type> type;
};
}
template <typename Src>
struct copy_to_vector {
typedef typename detail::copy_to_vector_impl<typename begin<Src>::type, size<Src>::value>::type type;
};
template <>
struct copy_to_vector<set<> > {
typedef vector0<> type;
};
} } // boost::mpl
namespace boost { namespace gil {
///////////////////////////////////////////////////////
///
/// unary_reduce, binary_reduce - given an MPL Random Access Sequence,
/// dynamically specified index to that container, the bits of an instance of the corresponding type and
/// a generic operation, invokes the operation on the given type
///
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
///
/// \brief Unary reduce.
///
/// Given a set of types and an operation, reduces each type in the set (to reduced_t), then removes duplicates (to unique_t)
/// To apply the operation, first constructs a lookup table that maps each element from Types to its place in unique_t and uses it to map
/// the index to anther index (in map_index). Then invokes apply_operation_base on the unique types with the new index.
///
///////////////////////////////////////////////////////
template <typename Types, typename Op>
struct unary_reduce_impl {
typedef typename mpl::transform<Types, detail::reduce<Op, mpl::_1> >::type reduced_t;
typedef typename mpl::copy<reduced_t, mpl::inserter<mpl::set<>, mpl::insert<mpl::_1,mpl::_2> > >::type unique_t;
static const bool is_single=mpl::size<unique_t>::value==1;
};
template <typename Types, typename Op, bool IsSingle=unary_reduce_impl<Types,Op>::is_single>
struct unary_reduce : public unary_reduce_impl<Types,Op> {
typedef typename unary_reduce_impl<Types,Op>::reduced_t reduced_t;
typedef typename unary_reduce_impl<Types,Op>::unique_t unique_t;
static unsigned short inline map_index(std::size_t index) {
typedef typename mpl::mapping_vector<reduced_t, unique_t> indices_t;
return gil::at_c<indices_t, unsigned short>(index);
}
template <typename Bits> GIL_FORCEINLINE static typename Op::result_type applyc(const Bits& bits, std::size_t index, Op op) {
return apply_operation_basec<unique_t>(bits,map_index(index),op);
}
template <typename Bits> GIL_FORCEINLINE static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) {
return apply_operation_base<unique_t>(bits,map_index(index),op);
}
};
template <typename Types, typename Op>
struct unary_reduce<Types,Op,true> : public unary_reduce_impl<Types,Op> {
typedef typename unary_reduce_impl<Types,Op>::unique_t unique_t;
static unsigned short inline map_index(std::size_t index) { return 0; }
template <typename Bits> GIL_FORCEINLINE static typename Op::result_type applyc(const Bits& bits, std::size_t index, Op op) {
return op(*gil_reinterpret_cast_c<const typename mpl::front<unique_t>::type*>(&bits));
}
template <typename Bits> GIL_FORCEINLINE static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) {
return op(*gil_reinterpret_cast<typename mpl::front<unique_t>::type*>(&bits));
}
};
///////////////////////////////////////////////////////
///
/// \brief Binary reduce.
///
/// Given two sets of types, Types1 and Types2, first performs unary reduction on each. Then checks if the product of their sizes is above
/// the GIL_BINARY_REDUCE_LIMIT limit. If so, the operation is too complex to be binary-reduced and uses a specialization of binary_reduce_impl
/// to simply call the binary apply_operation_base (which performs two nested 1D apply operations)
/// If the operation is not too complex, uses the other specialization of binary_reduce_impl to create a cross-product of the input types
/// and performs unary reduction on the result (bin_reduced_t). To apply the binary operation, it simply invokes a unary apply_operation_base
/// on the reduced cross-product types
///
///////////////////////////////////////////////////////
namespace detail {
struct pair_generator {
template <typename Vec2> struct apply {
typedef std::pair<const typename mpl::at_c<Vec2,0>::type*, const typename mpl::at_c<Vec2,1>::type*> type;
};
};
// When the types are not too large, applies reduce on their cross product
template <typename Unary1, typename Unary2, typename Op, bool IsComplex>
struct binary_reduce_impl {
//private:
typedef typename mpl::copy_to_vector<typename Unary1::unique_t>::type vec1_types;
typedef typename mpl::copy_to_vector<typename Unary2::unique_t>::type vec2_types;
typedef mpl::cross_vector<mpl::vector2<vec1_types, vec2_types>, pair_generator> BIN_TYPES;
typedef unary_reduce<BIN_TYPES,Op> bin_reduced_t;
static unsigned short inline map_index(std::size_t index1, std::size_t index2) {
unsigned short r1=Unary1::map_index(index1);
unsigned short r2=Unary2::map_index(index2);
return bin_reduced_t::map_index(r2*mpl::size<vec1_types>::value + r1);
}
public:
typedef typename bin_reduced_t::unique_t unique_t;
template <typename Bits1, typename Bits2>
static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
std::pair<const void*,const void*> pr(&bits1, &bits2);
return apply_operation_basec<unique_t>(pr, map_index(index1,index2),op);
}
};
// When the types are large performs a double-dispatch. Binary reduction is not done.
template <typename Unary1, typename Unary2, typename Op>
struct binary_reduce_impl<Unary1,Unary2,Op,true> {
template <typename Bits1, typename Bits2>
static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
return apply_operation_base<Unary1::unique_t,Unary2::unique_t>(bits1, index1, bits2, index2, op);
}
};
}
template <typename Types1, typename Types2, typename Op>
struct binary_reduce {
//private:
typedef unary_reduce<Types1,Op> unary1_t;
typedef unary_reduce<Types2,Op> unary2_t;
static const std::size_t CROSS_SIZE = mpl::size<typename unary1_t::unique_t>::value *
mpl::size<typename unary2_t::unique_t>::value;
typedef detail::binary_reduce_impl<unary1_t,unary2_t,Op, (CROSS_SIZE>GIL_BINARY_REDUCE_LIMIT)> impl;
public:
template <typename Bits1, typename Bits2>
static typename Op::result_type inline apply(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
return impl::apply(bits1,index1,bits2,index2,op);
}
};
template <typename Types, typename UnaryOp>
GIL_FORCEINLINE typename UnaryOp::result_type apply_operation(variant<Types>& arg, UnaryOp op) {
return unary_reduce<Types,UnaryOp>::template apply(arg._bits, arg._index ,op);
}
template <typename Types, typename UnaryOp>
GIL_FORCEINLINE typename UnaryOp::result_type apply_operation(const variant<Types>& arg, UnaryOp op) {
return unary_reduce<Types,UnaryOp>::template applyc(arg._bits, arg._index ,op);
}
template <typename Types1, typename Types2, typename BinaryOp>
GIL_FORCEINLINE typename BinaryOp::result_type apply_operation(const variant<Types1>& arg1, const variant<Types2>& arg2, BinaryOp op) {
return binary_reduce<Types1,Types2,BinaryOp>::template apply(arg1._bits, arg1._index, arg2._bits, arg2._index, op);
}
#undef GIL_BINARY_REDUCE_LIMIT
} } // namespace gil
namespace boost { namespace mpl {
///////////////////////////////////////////////////////
/// \brief Represents the virtual cross-product of the types generated from VecOfVecs.
/// \ingroup CrossVector
/// INPUT:
/// VecOfVecs - a vector of vector types. For example [ [A1,A2,A3], [B1,B2], [C1,C2,C3,C4] ]
/// Each element must be a non-empty mpl vector
/// TypeGen - a metafunction that generates a type from a vector of types, each of which can be
/// selected from the corresponding vector in VecOfVecs. For example, [A1, B2, C4]
///
/// Represents the virtual cross-product of the types generated from VecOfVecs.
/// For example, [ TypeGen[A1,B1,C1], TypeGen[A2,B1,C1], TypeGen[A3,B1,C1],
/// TypeGen[A1,B2,C1], TypeGen[A2,B2,C1], TypeGen[A3,B2,C1],
/// TypeGen[A1,B1,C2], TypeGen[A2,B1,C2], TypeGen[A3,B1,C2], ... ]
///
/// Models an immutable MPL Random Access Sequence
/// Traversal, random-access, etc, is defined, but mutable operations,
/// such as push_back and pop_front are not supported
///////////////////////////////////////////////////////
template <typename VecOfVecs, typename TypeGen>
struct cross_vector {};
/// \brief Iterator of cross_vector
/// \ingroup CrossVectorIterator
template <typename VecOfVecs, typename TypeGen, std::size_t K>
struct cross_iterator {
typedef mpl::random_access_iterator_tag category;
};
///////////////////////////////////////////////////////
/// Implementation of the iterator functions of cross vector
///////////////////////////////////////////////////////
/// \brief Dereferences a cross-vector iterator
/// \ingroup CrossVectorIterator
/// Creates a vector of the sizes of each type vector in VecOfVecs, then uses it as a basis
/// to represent the iterator's position K as a vector of indices. Extracts the corresponding type of
/// each input vector and passes the element types to the type generation function, which returns the dereferenced type
template <typename VecOfVecs, typename TypeGen, std::size_t K>
struct deref<cross_iterator<VecOfVecs,TypeGen,K> > {
private:
typedef typename detail::select_subvector_c<VecOfVecs, K>::type DerefTypes;
public:
typedef typename TypeGen::template apply<DerefTypes>::type type;
};
/// \brief Increments a cross-vector iterator.
/// \ingroup CrossVectorIterator
template <typename VecOfVecs, typename TypeGen, std::size_t K>
struct next<cross_iterator<VecOfVecs,TypeGen,K> > {
typedef cross_iterator<VecOfVecs,TypeGen,K+1> type;
};
/// \brief Decrements a cross-vector iterator.
/// \ingroup CrossVectorIterator
template <typename VecOfVecs, typename TypeGen, std::size_t K>
struct prior<cross_iterator<VecOfVecs,TypeGen,K> > {
typedef cross_iterator<VecOfVecs,TypeGen,K-1> type;
};
/// \brief Advances a cross-vector iterator.
/// \ingroup CrossVectorIterator
template <typename VecOfVecs, typename TypeGen, std::size_t K, typename Distance>
struct advance<cross_iterator<VecOfVecs,TypeGen,K>, Distance > {
typedef cross_iterator<VecOfVecs,TypeGen,K+Distance::value> type;
};
/// \brief Computes the distance between two cross-vector iterator-s.
/// \ingroup CrossVectorIterator
// (shortened the names of the template arguments - otherwise doxygen cannot parse this...)
template <typename VecOfVecs, typename TypeGen, std::size_t K1, std::size_t K2>
struct distance<cross_iterator<VecOfVecs,TypeGen,K1>, cross_iterator<VecOfVecs,TypeGen,K2> > {
typedef size_t<K2-K1> type;
};
///////////////////////////////////////////////////////
/// Implementation of cross vector
///////////////////////////////////////////////////////
/// \brief Computes the size of a cross vector as the product of the sizes of all vectors in VecOfVecs
/// \ingroup CrossVector
template <typename VecOfVecs, typename TypeGen>
struct size<cross_vector<VecOfVecs,TypeGen> > {
typedef typename fold<VecOfVecs, size_t<1>, times<_1, size<_2> > >::type type;
static const std::size_t value=type::value;
};
/// \brief Determines whether a cross vector is empty
/// \ingroup CrossVector
template <typename VecOfVecs, typename TypeGen>
struct empty<cross_vector<VecOfVecs,TypeGen> > {
typedef typename empty<VecOfVecs>::type type;
};
/// \brief Returns the K-th element of a cross vector
/// \ingroup CrossVector
template <typename VecOfVecs, typename TypeGen, typename K>
struct at<cross_vector<VecOfVecs,TypeGen>, K> {
private:
typedef cross_iterator<VecOfVecs,TypeGen,K::value> KthIterator;
public:
typedef typename deref<KthIterator>::type type;
};
/// \brief Returns an iterator to the first element of a cross vector
/// \ingroup CrossVector
template <typename VecOfVecs, typename TypeGen>
struct begin<cross_vector<VecOfVecs,TypeGen> > {
typedef cross_iterator<VecOfVecs,TypeGen,0> type;
};
/// \brief Returns an iterator to the last element of a cross vector
/// \ingroup CrossVector
template <typename VecOfVecs, typename TypeGen>
struct end<cross_vector<VecOfVecs,TypeGen> > {
private:
typedef cross_vector<VecOfVecs,TypeGen> this_t;
public:
typedef cross_iterator<VecOfVecs,TypeGen,size<this_t>::value> type;
};
/// \brief Returns the first element of a cross vector
/// \ingroup CrossVector
template <typename VecOfVecs, typename TypeGen>
struct front<cross_vector<VecOfVecs,TypeGen> > {
private:
typedef cross_vector<VecOfVecs,TypeGen> this_t;
public:
typedef typename deref<typename begin<this_t>::type>::type type;
};
/// \brief Returns the last element of a cross vector
/// \ingroup CrossVector
template <typename VecOfVecs, typename TypeGen>
struct back<cross_vector<VecOfVecs,TypeGen> > {
private:
typedef cross_vector<VecOfVecs,TypeGen> this_t;
typedef typename size<this_t>::type size;
typedef typename minus<size, size_t<1> >::type last_index;
public:
typedef typename at<this_t, last_index>::type type;
};
/// \brief Transforms the elements of a cross vector
/// \ingroup CrossVector
template <typename VecOfVecs, typename TypeGen, typename OPP>
struct transform<cross_vector<VecOfVecs,TypeGen>, OPP > {
typedef typename lambda<OPP>::type Op;
struct adapter {
template <typename Elements>
struct apply {
typedef typename TypeGen::template apply<Elements>::type orig_t;
typedef typename Op::template apply<orig_t>::type type;
};
};
typedef cross_vector<VecOfVecs, adapter > type;
};
} } // boost::mpl
namespace boost { namespace gil {
template <typename Types, typename T> struct type_to_index;
template <typename V> struct view_is_basic;
struct rgb_t;
struct lab_t;
struct hsb_t;
struct cmyk_t;
struct rgba_t;
struct error_t;
namespace detail {
////////////////////////////////////////////////////////
////
//// Generic reduce operation
////
////////////////////////////////////////////////////////
template <typename Op, typename T>
struct reduce {
typedef T type;
};
////////////////////////////////////////////////////////
////
//// Unary reduce_view operation. Splits into basic and non-basic views.
//// Algorithm-specific reduce should specialize for basic views
////
////////////////////////////////////////////////////////
template <typename Op, typename View, bool IsBasic>
struct reduce_view_basic {
typedef View type;
};
template <typename Op, typename Loc>
struct reduce<Op, image_view<Loc> >
: public reduce_view_basic<Op,image_view<Loc>,view_is_basic<image_view<Loc> >::value> {};
////////////////////////////////////////////////////////
////
//// Unary reduce_image operation. Splits into basic and non-basic images.
//// Algorithm-specific reduce should specialize for basic images
////
////////////////////////////////////////////////////////
template <typename Op, typename Img, bool IsBasic>
struct reduce_image_basic {
typedef Img type;
};
template <typename Op, typename V, typename Alloc>
struct reduce<Op, image<V,Alloc> > : public reduce_image_basic<Op,image<V,Alloc>,image_is_basic<image<V,Alloc> >::value > {};
////////////////////////////////////////////////////////
////
//// Binary reduce_view operation. Splits into basic and non-basic views.
//// Algorithm-specific reduce should specialize for basic views
////
////////////////////////////////////////////////////////
template <typename Op, typename V1, typename V2, bool AreBasic>
struct reduce_views_basic {
typedef std::pair<const V1*, const V2*> type;
};
template <typename Op, typename L1, typename L2>
struct reduce<Op, std::pair<const image_view<L1>*, const image_view<L2>*> >
: public reduce_views_basic<Op,image_view<L1>,image_view<L2>,
mpl::and_<view_is_basic<image_view<L1> >, view_is_basic<image_view<L2> > >::value >
{};
////////////////////////////////////////////////////////
////
//// Color space unary reduce operation. Reduce a color space to a base with the same number of channels
////
////////////////////////////////////////////////////////
template <typename Cs>
struct reduce_color_space {
typedef Cs type;
};
template <> struct reduce_color_space<lab_t> { typedef rgb_t type; };
template <> struct reduce_color_space<hsb_t> { typedef rgb_t type; };
template <> struct reduce_color_space<cmyk_t> { typedef rgba_t type; };
/*
////////////////////////////////////////////////////////
////
//// Color space binary reduce operation. Given a source and destination color spaces,
//// returns a reduced source and destination color spaces that have the same mapping of channels
////
//// Precondition: The two color spaces must be compatible (i.e. must have the same set of channels)
////////////////////////////////////////////////////////
template <typename Vec, int Basis, int VecSize>
struct type_vec_to_integer_impl {
typedef typename mpl::back<Vec>::type last;
typedef typename mpl::pop_back<Vec>::type rest;
static const int value = type_vec_to_integer_impl<rest, Basis, VecSize-1>::value * Basis + last::value;
};
template <typename Vec, int Basis>
struct type_vec_to_integer_impl<Vec,Basis,0> {
static const int value=0;
};
template <typename Vec, int Basis=10>
struct type_vec_to_integer {
static const int value = type_vec_to_integer_impl<Vec,Basis, mpl::size<Vec>::value>::value;
};
// Given two color spaces and the mapping of the channels between them, returns the reduced pair of color spaces
// The default version performs no reduction
template <typename SrcColorSpace, typename DstColorSpace, int Mapping>
struct reduce_color_spaces_impl {
typedef SrcColorSpace first_t;
typedef DstColorSpace second_t;
};
// 012: RGB-RGB, bgr-bgr, lab-lab, hsb-hsb
template <typename SrcColorSpace, typename DstColorSpace>
struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,12> {
typedef rgb_t first_t;
typedef rgb_t second_t;
};
// 210: RGB-bgr, bgr-RGB
template <typename SrcColorSpace, typename DstColorSpace>
struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,210> {
typedef rgb_t first_t;
typedef bgr_t second_t;
};
// 0123: RGBA-RGBA, bgra-bgra, argb-argb, abgr-abgr cmyk-cmyk
template <typename SrcColorSpace, typename DstColorSpace>
struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,123> {
typedef rgba_t first_t;
typedef rgba_t second_t;
};
// 3210: RGBA-abgr, bgra-argb, argb-bgra, abgr-RGBA
template <typename SrcColorSpace, typename DstColorSpace>
struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,3210> {
typedef rgba_t first_t;
typedef abgr_t second_t;
};
// 1230: RGBA-argb, bgra-abgr
template <typename SrcColorSpace, typename DstColorSpace>
struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,1230> {
typedef rgba_t first_t;
typedef argb_t second_t;
};
// 2103: RGBA-bgra, bgra-RGBA (uses subclass to ensure that base color space is not reduced to derived)
template <typename SrcColorSpace, typename DstColorSpace>
struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,2103> {
typedef rgba_t first_t;
typedef bgra_t second_t;
};
// 3012: argb-RGBA, abgr-bgra
template <typename SrcColorSpace, typename DstColorSpace>
struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,3012> {
typedef argb_t first_t;
typedef rgba_t second_t;
};
// 0321: argb-abgr, abgr-argb
template <typename SrcColorSpace, typename DstColorSpace>
struct reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,321> {
typedef argb_t first_t;
typedef abgr_t second_t;
};
template <typename SrcColorSpace, typename DstColorSpace>
struct reduce_color_spaces {
typedef typename channel_order<SrcColorSpace>::type src_order_t;
typedef typename channel_order<DstColorSpace>::type dst_order_t;
typedef typename mpl::transform<src_order_t, type_to_index<dst_order_t,mpl::_1> >::type mapping;
static const int mapping_val = type_vec_to_integer<mapping>::value;
typedef typename reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,mapping_val>::first_t _first_t;
typedef typename reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,mapping_val>::second_t _second_t;
typedef typename mpl::and_<color_space_is_base<DstColorSpace>, mpl::not_< color_space_is_base<_second_t> > > swap_t;
public:
typedef typename mpl::if_<swap_t, _second_t, _first_t>::type first_t;
typedef typename mpl::if_<swap_t, _first_t, _second_t>::type second_t;
};
*/
// TODO: Use the old code for reduce_color_spaces above to do color layout reduction
template <typename SrcLayout, typename DstLayout>
struct reduce_color_layouts {
typedef SrcLayout first_t;
typedef DstLayout second_t;
};
////////////////////////////////////////////////////////
////
//// Reduce for copy_pixels
////
////////////////////////////////////////////////////////
struct copy_pixels_fn;
/*
// 1D reduce for copy_pixels reduces the channel to mutable and the color space to its base with same dimensions
template <typename View>
struct reduce_view_basic<copy_pixels_fn,View,true> {
private:
typedef typename reduce_color_space<typename View::color_space_t>::type Cs; // reduce the color space
typedef layout<Cs, typename View::channel_mapping_t> layout_t;
public:
typedef typename derived_view_type<View, use_default, layout_t, use_default, use_default, mpl::true_>::type type;
};
*/
// Incompatible views cannot be used in copy_pixels - will throw std::bad_cast
template <typename V1, typename V2, bool Compatible>
struct reduce_copy_pixop_compat {
typedef error_t type;
};
// For compatible basic views, reduce their color spaces based on their channel mapping.
// Make the source immutable and the destination mutable (they should already be that way)
template <typename V1, typename V2>
struct reduce_copy_pixop_compat<V1,V2,true> {
typedef layout<typename V1::color_space_t, typename V1::channel_mapping_t> layout1;
typedef layout<typename V2::color_space_t, typename V2::channel_mapping_t> layout2;
typedef typename reduce_color_layouts<layout1,layout2>::first_t L1;
typedef typename reduce_color_layouts<layout1,layout2>::second_t L2;
typedef typename derived_view_type<V1, use_default, L1, use_default, use_default, use_default, mpl::false_>::type DV1;
typedef typename derived_view_type<V2, use_default, L2, use_default, use_default, use_default, mpl::true_ >::type DV2;
typedef std::pair<const DV1*, const DV2*> type;
};
// The general 2D version branches into compatible and incompatible views
template <typename V1, typename V2>
struct reduce_views_basic<copy_pixels_fn, V1, V2, true>
: public reduce_copy_pixop_compat<V1, V2, mpl::and_<views_are_compatible<V1,V2>, view_is_mutable<V2> >::value > {
};
////////////////////////////////////////////////////////
////
//// Reduce for variant destructor (basic views have no destructor)
////
////////////////////////////////////////////////////////
struct destructor_op;
template <typename View> struct reduce_view_basic<destructor_op,View,true> { typedef gray8_view_t type; };
////////////////////////////////////////////////////////
////
//// Reduce for get_dimensions (basic views and images have the same structure and the dimensions are contained at the beginning)
////
////////////////////////////////////////////////////////
struct any_type_get_dimensions;
template <typename View> struct reduce_view_basic<any_type_get_dimensions,View,true> { typedef gray8_view_t type; };
template <typename Img> struct reduce_image_basic<any_type_get_dimensions,Img,true> { typedef gray8_image_t type; };
////////////////////////////////////////////////////////
////
//// Reduce for get_num_channels (only color space matters)
////
////////////////////////////////////////////////////////
struct any_type_get_num_channels;
template <typename View> struct reduce_view_basic<any_type_get_num_channels,View,true> {
typedef typename View::color_space_t::base Cs;
typedef typename view_type<bits8,typename reduce_color_space<Cs>::type>::type type;
};
template <typename Img> struct reduce_image_basic<any_type_get_num_channels,Img,true> {
typedef typename Img::color_space_t::base Cs;
typedef typename image_type<bits8,typename reduce_color_space<Cs>::type>::type type;
};
////////////////////////////////////////////////////////
////
//// Reduce for resample_pixels (same as copy_pixels)
////
////////////////////////////////////////////////////////
template <typename Sampler, typename MapFn> struct resample_pixels_fn;
template <typename S, typename M, typename V, bool IsBasic>
struct reduce_view_basic<resample_pixels_fn<S,M>, V, IsBasic> : public reduce_view_basic<copy_pixels_fn, V, IsBasic> {};
template <typename S, typename M, typename V1, typename V2, bool IsBasic>
struct reduce_views_basic<resample_pixels_fn<S,M>, V1, V2, IsBasic> : public reduce_views_basic<copy_pixels_fn, V1, V2, IsBasic> {};
////////////////////////////////////////////////////////
////
//// Reduce for copy_and_convert_pixels
//// (the only reduction could be made when views are compatible and have the same mapping, planarity and stepness)
////
////////////////////////////////////////////////////////
template <typename CC> class copy_and_convert_pixels_fn;
// the only thing for 1D reduce is making them all mutable...
template <typename CC, typename View, bool IsBasic>
struct reduce_view_basic<copy_and_convert_pixels_fn<CC>, View, IsBasic>
: public derived_view_type<View, use_default, use_default, use_default, use_default, mpl::true_> {
};
// For 2D reduce, if they have the same channels and color spaces (i.e. the same pixels) then copy_and_convert is just copy.
// In this case, reduce their common color space. In general make the first immutable and the second mutable
template <typename CC, typename V1, typename V2, bool AreBasic>
struct reduce_views_basic<copy_and_convert_pixels_fn<CC>, V1, V2, AreBasic> {
typedef is_same<typename V1::pixel_t, typename V2::pixel_t> Same;
typedef reduce_color_space<typename V1::color_space_t::base> CsR;
typedef typename mpl::if_<Same, typename CsR::type, typename V1::color_space_t>::type Cs1;
typedef typename mpl::if_<Same, typename CsR::type, typename V2::color_space_t>::type Cs2;
typedef typename derived_view_type<V1, use_default, layout<Cs1, typename V1::channel_mapping_t>, use_default, use_default, mpl::false_>::type DV1;
typedef typename derived_view_type<V2, use_default, layout<Cs2, typename V2::channel_mapping_t>, use_default, use_default, mpl::true_ >::type DV2;
typedef std::pair<const DV1*, const DV2*> type;
};
//integral_image_generator
//resize_clobber_image_fnobj
//image_default_construct_fnobj
//fill_converted_pixels_fn
//bind(gil::detail::copy_pixels_fn(), _1, dst)
//bind(gil::detail::copy_pixels_fn(), src,_1)
//bind(detail::copy_and_convert_pixels_fn(), _1, dst)
//bind(detail::copy_and_convert_pixels_fn(), src, _1)
//gil::detail::fill_pixels_fn<Value>(val)
//detail::copy_construct_in_place_fn<base_t>
//detail::equal_to_fn<typename variant<Types>::base_t>
//detail::any_image_get_view<typename any_image<Types>::view_t>
//detail::any_image_get_const_view<typename any_image<Types>::view_t>
//detail::flipped_up_down_view_fn<any_image_view<ViewTypes> >
//detail::flipped_left_right_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
//detail::tranposed_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
//detail::rotated90cw_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
//detail::rotated90ccw_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
//detail::rotated180_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
//detail::subimage_view_fn<any_image_view<ViewTypes> >
//detail::subsampled_view_fn<typename any_image_view<ViewTypes>::dynamic_step_t>
//detail::nth_channel_view_fn<typename nth_channel_view_type<any_image_view<ViewTypes> >
//detail::color_converted_view_fn<DstP,typename color_convert_view_type<any_image_view<ViewTypes>, DstP>::type >
}
} } // namespace boost::gil
#endif // GIL_REDUCE_CODE_BLOAT
#endif

View File

@@ -0,0 +1,197 @@
/*
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_DYNAMICIMAGE_VARIANT_HPP
#define GIL_DYNAMICIMAGE_VARIANT_HPP
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Support for run-time instantiated types
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on September 18, 2007
///
////////////////////////////////////////////////////////////////////////////////////////
#include "../../gil_config.hpp"
#include "../../utilities.hpp"
#include <cstddef>
#include <cassert>
#include <algorithm>
#include <typeinfo>
#include <boost/bind.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/sizeof.hpp>
#include <boost/mpl/max.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/fold.hpp>
namespace boost { namespace gil {
namespace detail {
template <typename Types, typename T> struct type_to_index;
template <typename Op, typename T> struct reduce;
struct destructor_op {
typedef void result_type;
template <typename T> result_type operator()(const T& t) const { t.~T(); }
};
template <typename T, typename Bits> void copy_construct_in_place(const T& t, Bits& bits);
template <typename Bits> struct copy_construct_in_place_fn;
}
/**
\brief Represents a concrete instance of a run-time specified type from a set of types
\class variant
\ingroup Variant
A concept is typically modeled by a collection of different types. They may be instantiations
of a templated type with different template parameters or even completely unrelated types.
We call the type with which the concept is instantiated in a given place in the code "the concrete type".
The concrete type must be chosen at compile time, which sometimes is a severe limitation.
Consider, for example, having an image concept modeled by an image class templated over the color space.
It would be difficult to write a function that reads an image from file preserving its native color space, since the
type of the return value is only available at run time. It would be difficult to store images of different color
spaces in the same container or apply operations on them uniformly.
The variant class addresses this deficiency. It allows for run-time instantiation of a class from a given set of allowed classes
specified at compile time. For example, the set of allowed classes may include 8-bit and 16-bit RGB and CMYK images. Such a variant
can be constructed with rgb8_image_t and then assigned a cmyk16_image_t.
The variant has a templated constructor, which allows us to construct it with any concrete type instantiation. It can also perform a generic
operation on the concrete type via a call to apply_operation. The operation must be provided as a function object whose application
operator has a single parameter which can be instantiated with any of the allowed types of the variant.
variant breaks down the instantiated type into a non-templated underlying base type and a unique instantiation
type identifier. In the most common implementation the concrete instantiation in stored 'in-place' - in 'bits_t'.
bits_t contains sufficient space to fit the largest of the instantiated objects.
GIL's variant is similar to boost::variant in spirit (hence we borrow the name from there) but it differs in several ways from the current boost
implementation. Most notably, it does not take a variable number of template parameters but a single parameter defining the type enumeration. As
such it can be used more effectively in generic code.
The Types parameter specifies the set of allowable types. It models MPL Random Access Container
*/
template <typename Types> // models MPL Random Access Container
class variant {
// size in bytes of the largest type in Types
static const std::size_t MAX_SIZE = mpl::fold<Types, mpl::size_t<0>, mpl::max<mpl::_1, mpl::sizeof_<mpl::_2> > >::type::value;
static const std::size_t NUM_TYPES = mpl::size<Types>::value;
public:
typedef Types types_t;
typedef struct { char data[MAX_SIZE]; } base_t; // empty space equal to the size of the largest type in Types
// Default constructor - default construct the first type
variant() : _index(0) { new(&_bits) typename mpl::at_c<Types,0>::type(); }
virtual ~variant() { apply_operation(*this, detail::destructor_op()); }
// Throws std::bad_cast if T is not in Types
template <typename T> explicit variant(const T& obj){ _index=type_id<T>(); if (_index==NUM_TYPES) throw std::bad_cast(); detail::copy_construct_in_place(obj, _bits); }
// When doSwap is true, swaps obj with the contents of the variant. obj will contain default-constructed instance after the call
template <typename T> explicit variant(T& obj, bool do_swap);
template <typename T> variant& operator=(const T& obj) { variant tmp(obj); swap(*this,tmp); return *this; }
variant& operator=(const variant& v) { variant tmp(v ); swap(*this,tmp); return *this; }
variant(const variant& v) : _index(v._index) { apply_operation(v, detail::copy_construct_in_place_fn<base_t>(_bits)); }
template <typename T> void move_in(T& obj) { variant tmp(obj, true); swap(*this,tmp); }
template <typename TS> friend bool operator==(const variant<TS>& x, const variant<TS>& y);
template <typename TS> friend bool operator!=(const variant<TS>& x, const variant<TS>& y);
template <typename T> static bool has_type() { return type_id<T>()!=NUM_TYPES; }
template <typename T> const T& _dynamic_cast() const { if (!current_type_is<T>()) throw std::bad_cast(); return *gil_reinterpret_cast_c<const T*>(&_bits); }
template <typename T> T& _dynamic_cast() { if (!current_type_is<T>()) throw std::bad_cast(); return *gil_reinterpret_cast < T*>(&_bits); }
template <typename T> bool current_type_is() const { return type_id<T>()==_index; }
base_t bits() const { return _bits; }
std::size_t index() const { return _index; }
private:
template <typename T> static std::size_t type_id() { return detail::type_to_index<Types,T>::value; }
template <typename Cs> friend void swap(variant<Cs>& x, variant<Cs>& y);
template <typename Types2, typename UnaryOp> friend typename UnaryOp::result_type apply_operation(variant<Types2>& var, UnaryOp op);
template <typename Types2, typename UnaryOp> friend typename UnaryOp::result_type apply_operation(const variant<Types2>& var, UnaryOp op);
template <typename Types1, typename Types2, typename BinaryOp> friend typename BinaryOp::result_type apply_operation(const variant<Types1>& arg1, const variant<Types2>& arg2, BinaryOp op);
base_t _bits;
std::size_t _index;
};
namespace detail {
template <typename T, typename Bits>
void copy_construct_in_place(const T& t, Bits& bits) {
T& b=*gil_reinterpret_cast<T*>(&bits);
new(&b)T(t); // default-construct
}
template <typename Bits>
struct copy_construct_in_place_fn {
typedef void result_type;
Bits& _dst;
copy_construct_in_place_fn(Bits& dst) : _dst(dst) {}
template <typename T> void operator()(const T& src) const { copy_construct_in_place(src,_dst); }
};
template <typename Bits>
struct equal_to_fn {
const Bits& _dst;
equal_to_fn(const Bits& dst) : _dst(dst) {}
typedef bool result_type;
template <typename T> result_type operator()(const T& x) const {
return x==*gil_reinterpret_cast_c<const T*>(&_dst);
}
};
}
// When doSwap is true, swaps obj with the contents of the variant. obj will contain default-constructed instance after the call
template <typename Types>
template <typename T> variant<Types>::variant(T& obj, bool do_swap) {
_index=type_id<T>();
if (_index==NUM_TYPES) throw std::bad_cast();
if (do_swap) {
new(&_bits) T(); // default construct
swap(obj, *gil_reinterpret_cast<T*>(&_bits));
} else
detail::copy_construct_in_place(const_cast<const T&>(obj), _bits);
}
template <typename Types>
void swap(variant<Types>& x, variant<Types>& y) {
std::swap(x._bits,y._bits);
std::swap(x._index, y._index);
}
template <typename Types>
inline bool operator==(const variant<Types>& x, const variant<Types>& y) {
return x._index==y._index && apply_operation(x,detail::equal_to_fn<typename variant<Types>::base_t>(y._bits));
}
template <typename C>
inline bool operator!=(const variant<C>& x, const variant<C>& y) {
return !(x==y);
}
} } // namespace boost::gil
#endif