Upgrading win32cpp.

This commit is contained in:
Daniel Önnerby 2008-12-08 14:16:53 +00:00
parent 99de95c93d
commit 46c3d9ff61
129 changed files with 24716 additions and 948 deletions

1106
src/3rdparty/include/boost/crc.hpp vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -0,0 +1,643 @@
/*
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://stlab.adobe.com/gil for most recent version including documentation.
*/
/*************************************************************************************************/
#ifndef GIL_CHANNEL_HPP
#define GIL_CHANNEL_HPP
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Channel utilities
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on May 6, 2007
///
/// Definitions of standard GIL channel models
///
////////////////////////////////////////////////////////////////////////////////////////
#include <limits>
#include <cassert>
#include <boost/cstdint.hpp>
#include "gil_config.hpp"
#include "utilities.hpp"
namespace boost { namespace gil {
///////////////////////////////////////////
//// channel_traits
////
//// \ingroup ChannelModel
//// \class channel_traits
//// \brief defines properties of channels, such as their range and associated types
////
//// The channel traits must be defined for every model of ChannelConcept
//// Default traits are provided. For built-in types the default traits use
//// built-in pointer and reference and the channel range is the physical
//// range of the type. For classes, the default traits forward the associated types
//// and range to the class.
////
///////////////////////////////////////////
namespace detail {
template <typename T, bool is_class> struct channel_traits_impl;
// channel traits for custom class
template <typename T>
struct channel_traits_impl<T, true> {
typedef typename T::value_type value_type;
typedef typename T::reference reference;
typedef typename T::pointer pointer;
typedef typename T::const_reference const_reference;
typedef typename T::const_pointer const_pointer;
BOOST_STATIC_CONSTANT(bool, is_mutable=T::is_mutable);
static value_type min_value() { return T::min_value(); }
static value_type max_value() { return T::max_value(); }
};
// channel traits implementation for built-in integral or floating point channel type
template <typename T>
struct channel_traits_impl<T, false> {
typedef T value_type;
typedef T& reference;
typedef T* pointer;
typedef const T& const_reference;
typedef T const* const_pointer;
BOOST_STATIC_CONSTANT(bool, is_mutable=true);
static value_type min_value() { return (std::numeric_limits<T>::min)(); }
static value_type max_value() { return (std::numeric_limits<T>::max)(); }
};
// channel traits implementation for constant built-in scalar or floating point type
template <typename T>
struct channel_traits_impl<const T, false> : public channel_traits_impl<T, false> {
typedef const T& reference;
typedef const T* pointer;
BOOST_STATIC_CONSTANT(bool, is_mutable=false);
};
}
/**
\ingroup ChannelModel
\brief Traits for channels. Contains the following members:
\code
template <typename Channel>
struct channel_traits {
typedef ... value_type;
typedef ... reference;
typedef ... pointer;
typedef ... const_reference;
typedef ... const_pointer;
static const bool is_mutable;
static value_type min_value();
static value_type max_value();
};
\endcode
*/
template <typename T>
struct channel_traits : public detail::channel_traits_impl<T, is_class<T>::value> {};
// Channel traits for C++ reference type - remove the reference
template <typename T> struct channel_traits< T&> : public channel_traits<T> {};
// Channel traits for constant C++ reference type
template <typename T> struct channel_traits<const T&> : public channel_traits<T> {
typedef typename channel_traits<T>::const_reference reference;
typedef typename channel_traits<T>::const_pointer pointer;
BOOST_STATIC_CONSTANT(bool, is_mutable=false);
};
///////////////////////////////////////////
////
//// scoped_channel_value
////
///////////////////////////////////////////
/**
\defgroup ScopedChannelValue scoped_channel_value
\ingroup ChannelModel
\brief A channel adaptor that modifies the range of the source channel. Models: ChannelValueConcept
Example:
\code
// Create a double channel with range [-0.5 .. 0.5]
struct double_minus_half { static double apply() { return -0.5; } };
struct double_plus_half { static double apply() { return 0.5; } };
typedef scoped_channel_value<double, double_minus_half, double_plus_half> bits64custom_t;
// channel_convert its maximum should map to the maximum
bits64custom_t x = channel_traits<bits64custom_t>::max_value();
assert(x == 0.5);
bits16 y = channel_convert<bits16>(x);
assert(y == 65535);
\endcode
*/
/// \ingroup ScopedChannelValue
/// \brief A channel adaptor that modifies the range of the source channel. Models: ChannelValueConcept
template <typename BaseChannelValue, // base channel (models ChannelValueConcept)
typename MinVal, typename MaxVal> // classes with a static apply() function returning the minimum/maximum channel values
struct scoped_channel_value {
typedef scoped_channel_value value_type;
typedef value_type& reference;
typedef value_type* pointer;
typedef const value_type& const_reference;
typedef const value_type* const_pointer;
BOOST_STATIC_CONSTANT(bool, is_mutable=channel_traits<BaseChannelValue>::is_mutable);
static value_type min_value() { return MinVal::apply(); }
static value_type max_value() { return MaxVal::apply(); }
scoped_channel_value() {}
scoped_channel_value(const scoped_channel_value& c) : _value(c._value) {}
scoped_channel_value(BaseChannelValue val) : _value(val) {}
scoped_channel_value& operator++() { ++_value; return *this; }
scoped_channel_value& operator--() { --_value; return *this; }
scoped_channel_value operator++(int) { scoped_channel_value tmp=*this; this->operator++(); return tmp; }
scoped_channel_value operator--(int) { scoped_channel_value tmp=*this; this->operator--(); return tmp; }
template <typename Scalar2> scoped_channel_value& operator+=(Scalar2 v) { _value+=v; return *this; }
template <typename Scalar2> scoped_channel_value& operator-=(Scalar2 v) { _value-=v; return *this; }
template <typename Scalar2> scoped_channel_value& operator*=(Scalar2 v) { _value*=v; return *this; }
template <typename Scalar2> scoped_channel_value& operator/=(Scalar2 v) { _value/=v; return *this; }
scoped_channel_value& operator=(BaseChannelValue v) { _value=v; return *this; }
operator BaseChannelValue() const { return _value; }
private:
BaseChannelValue _value;
};
struct float_zero { static float apply() { return 0.0f; } };
struct float_one { static float apply() { return 1.0f; } };
///////////////////////////////////////////
////
//// Support for sub-byte channels. These are integral channels whose value is contained in a range of bits inside an integral type
////
///////////////////////////////////////////
// It is necessary for packed channels to have their own value type. They cannot simply use an integral large enough to store the data. Here is why:
// - Any operation that requires returning the result by value will otherwise return the built-in integral type, which will have incorrect range
// That means that after getting the value of the channel we cannot properly do channel_convert, channel_invert, etc.
// - Two channels are declared compatible if they have the same value type. That means that a packed channel is incorrectly declared compatible with an integral type
namespace detail {
// returns the smallest fast unsigned integral type that has at least NumBits bits
template <int NumBits>
struct min_fast_uint : public mpl::if_c< (NumBits<=8),
uint_least8_t,
typename mpl::if_c< (NumBits<=16),
uint_least16_t,
typename mpl::if_c< (NumBits<=32),
uint_least32_t,
uintmax_t
>::type
>::type
> {};
}
/**
\defgroup PackedChannelValueModel packed_channel_value
\ingroup ChannelModel
\brief Represents the value of an unsigned integral channel operating over a bit range. Models: ChannelValueConcept
Example:
\code
// A 4-bit unsigned integral channel.
typedef packed_channel_value<4> bits4;
assert(channel_traits<bits4>::min_value()==0);
assert(channel_traits<bits4>::max_value()==15);
assert(sizeof(bits4)==1);
BOOST_STATIC_ASSERT((boost::is_integral<bits4>::value));
\endcode
*/
/// \ingroup PackedChannelValueModel
/// \brief The value of a subbyte channel. Models: ChannelValueConcept
template <int NumBits>
class packed_channel_value {
static const std::size_t num_values = 1<<NumBits;
public:
typedef typename detail::min_fast_uint<NumBits>::type integer_t;
typedef packed_channel_value value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef value_type* pointer;
typedef const value_type* const_pointer;
static value_type min_value() { return value_type(0); }
static value_type max_value() { return value_type(num_values-1); }
BOOST_STATIC_CONSTANT(bool, is_mutable=true);
packed_channel_value() {}
packed_channel_value(integer_t v) : _value(v % num_values) {}
packed_channel_value(const packed_channel_value& v) : _value(v._value) {}
template <typename Scalar> packed_channel_value(Scalar v) : _value(integer_t(v) % num_values) {} // suppress GCC implicit conversion warnings in channel regression file
operator integer_t() const { return _value; }
private:
integer_t _value;
};
namespace detail {
template <std::size_t K>
struct static_copy_bytes {
void operator()(const unsigned char* from, unsigned char* to) const {
*to = *from;
static_copy_bytes<K-1>()(++from,++to);
}
};
template <>
struct static_copy_bytes<0> {
void operator()(const unsigned char* , unsigned char*) const {}
};
template <typename Derived, typename BitField, int NumBits, bool Mutable>
class packed_channel_reference_base {
protected:
typedef typename mpl::if_c<Mutable,void*,const void*>::type data_ptr_t;
public:
data_ptr_t _data_ptr; // void* pointer to the first byte of the bit range
typedef packed_channel_value<NumBits> value_type;
typedef const Derived reference;
typedef value_type* pointer;
typedef const value_type* const_pointer;
BOOST_STATIC_CONSTANT(int, num_bits=NumBits);
BOOST_STATIC_CONSTANT(bool, is_mutable=Mutable);
static value_type min_value() { return channel_traits<value_type>::min_value(); }
static value_type max_value() { return channel_traits<value_type>::max_value(); }
typedef BitField bitfield_t;
typedef typename value_type::integer_t integer_t;
packed_channel_reference_base(data_ptr_t data_ptr) : _data_ptr(data_ptr) {}
packed_channel_reference_base(const packed_channel_reference_base& ref) : _data_ptr(ref._data_ptr) {}
const Derived& operator=(integer_t v) const { set(v); return derived(); }
const Derived& operator++() const { set(get()+1); return derived(); }
const Derived& operator--() const { set(get()-1); return derived(); }
Derived operator++(int) const { Derived tmp=derived(); this->operator++(); return tmp; }
Derived operator--(int) const { Derived tmp=derived(); this->operator--(); return tmp; }
template <typename Scalar2> const Derived& operator+=(Scalar2 v) const { set(get()+v); return derived(); }
template <typename Scalar2> const Derived& operator-=(Scalar2 v) const { set(get()-v); return derived(); }
template <typename Scalar2> const Derived& operator*=(Scalar2 v) const { set(get()*v); return derived(); }
template <typename Scalar2> const Derived& operator/=(Scalar2 v) const { set(get()/v); return derived(); }
operator integer_t() const { return get(); }
data_ptr_t operator &() const {return _data_ptr;}
protected:
static const integer_t max_val = (1<<NumBits) - 1;
#ifdef GIL_NONWORD_POINTER_ALIGNMENT_SUPPORTED
const bitfield_t& get_data() const { return *static_cast<const bitfield_t*>(_data_ptr); }
void set_data(const bitfield_t& val) const { *static_cast< bitfield_t*>(_data_ptr) = val; }
#else
bitfield_t get_data() const {
bitfield_t ret;
static_copy_bytes<sizeof(bitfield_t) >()(gil_reinterpret_cast_c<const unsigned char*>(_data_ptr),gil_reinterpret_cast<unsigned char*>(&ret));
return ret;
}
void set_data(const bitfield_t& val) const {
static_copy_bytes<sizeof(bitfield_t) >()(gil_reinterpret_cast_c<const unsigned char*>(&val),gil_reinterpret_cast<unsigned char*>(_data_ptr));
}
#endif
private:
void set(integer_t value) const { // can this be done faster??
const integer_t num_values = max_val+1;
this->derived().set_unsafe(((value % num_values) + num_values) % num_values);
}
integer_t get() const { return derived().get(); }
const Derived& derived() const { return static_cast<const Derived&>(*this); }
};
} // namespace detail
/**
\defgroup PackedChannelReferenceModel packed_channel_reference
\ingroup ChannelModel
\brief Represents a reference proxy to a channel operating over a bit range whose offset is fixed at compile time. Models ChannelConcept
Example:
\code
// Reference to a 2-bit channel starting at bit 1 (i.e. the second bit)
typedef const packed_channel_reference<uint16_t,1,2,true> bits2_1_ref_t;
uint16_t data=0;
bits2_1_ref_t channel_ref(&data);
channel_ref = channel_traits<bits2_1_ref_t>::max_value(); // == 3
assert(data == 6); // == 3<<1 == 6
\endcode
*/
template <typename BitField, // A type that holds the bits of the pixel from which the channel is referenced. Typically an integral type, like boost::uint16_t
int FirstBit, int NumBits,// Defines the sequence of bits in the data value that contain the channel
bool Mutable> // true if the reference is mutable
class packed_channel_reference;
template <typename BitField, // A type that holds the bits of the pixel from which the channel is referenced. Typically an integral type, like boost::uint16_t
int NumBits, // Defines the sequence of bits in the data value that contain the channel
bool Mutable> // true if the reference is mutable
class packed_dynamic_channel_reference;
/// \ingroup PackedChannelReferenceModel
/// \brief A constant subbyte channel reference whose bit offset is fixed at compile time. Models ChannelConcept
template <typename BitField, int FirstBit, int NumBits>
class packed_channel_reference<BitField,FirstBit,NumBits,false>
: public detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,false>,BitField,NumBits,false> {
typedef detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,false>,BitField,NumBits,false> parent_t;
friend class packed_channel_reference<BitField,FirstBit,NumBits,true>;
static const BitField channel_mask = parent_t::max_val<<FirstBit;
void operator=(const packed_channel_reference&);
public:
typedef const packed_channel_reference<BitField,FirstBit,NumBits,false> const_reference;
typedef const packed_channel_reference<BitField,FirstBit,NumBits,true> mutable_reference;
typedef typename parent_t::integer_t integer_t;
explicit packed_channel_reference(const void* data_ptr) : parent_t(data_ptr) {}
packed_channel_reference(const packed_channel_reference& ref) : parent_t(ref._data_ptr) {}
packed_channel_reference(const mutable_reference& ref) : parent_t(ref._data_ptr) {}
unsigned first_bit() const { return FirstBit; }
integer_t get() const { return integer_t((this->get_data()&channel_mask) >> FirstBit); }
};
/// \ingroup PackedChannelReferenceModel
/// \brief A mutable subbyte channel reference whose bit offset is fixed at compile time. Models ChannelConcept
template <typename BitField, int FirstBit, int NumBits>
class packed_channel_reference<BitField,FirstBit,NumBits,true>
: public detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,true>,BitField,NumBits,true> {
typedef detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,true>,BitField,NumBits,true> parent_t;
friend class packed_channel_reference<BitField,FirstBit,NumBits,false>;
static const BitField channel_mask = parent_t::max_val<<FirstBit;
public:
typedef const packed_channel_reference<BitField,FirstBit,NumBits,false> const_reference;
typedef const packed_channel_reference<BitField,FirstBit,NumBits,true> mutable_reference;
typedef typename parent_t::integer_t integer_t;
explicit packed_channel_reference(void* data_ptr) : parent_t(data_ptr) {}
packed_channel_reference(const packed_channel_reference& ref) : parent_t(ref._data_ptr) {}
const packed_channel_reference& operator=(integer_t value) const { assert(value<=parent_t::max_val); set_unsafe(value); return *this; }
const packed_channel_reference& operator=(const mutable_reference& ref) const { set_from_reference(ref.get_data()); return *this; }
const packed_channel_reference& operator=(const const_reference& ref) const { set_from_reference(ref.get_data()); return *this; }
template <bool Mutable1>
const packed_channel_reference& operator=(const packed_dynamic_channel_reference<BitField,NumBits,Mutable1>& ref) const { set_unsafe(ref.get()); return *this; }
unsigned first_bit() const { return FirstBit; }
integer_t get() const { return integer_t((this->get_data()&channel_mask) >> FirstBit); }
void set_unsafe(integer_t value) const { this->set_data((this->get_data() & ~channel_mask) | (value<<FirstBit)); }
private:
void set_from_reference(const BitField& other_bits) const { this->set_data((this->get_data() & ~channel_mask) | (other_bits & channel_mask)); }
};
} } // namespace boost::gil
namespace std {
// We are forced to define swap inside std namespace because on some platforms (Visual Studio 8) STL calls swap qualified.
// swap with 'left bias':
// - swap between proxy and anything
// - swap between value type and proxy
// - swap between proxy and proxy
/// \ingroup PackedChannelReferenceModel
/// \brief swap for packed_channel_reference
template <typename BF, int FB, int NB, bool M, typename R> inline
void swap(const boost::gil::packed_channel_reference<BF,FB,NB,M> x, R& y) {
boost::gil::swap_proxy<typename boost::gil::packed_channel_reference<BF,FB,NB,M>::value_type>(x,y);
}
/// \ingroup PackedChannelReferenceModel
/// \brief swap for packed_channel_reference
template <typename BF, int FB, int NB, bool M> inline
void swap(typename boost::gil::packed_channel_reference<BF,FB,NB,M>::value_type& x, const boost::gil::packed_channel_reference<BF,FB,NB,M> y) {
boost::gil::swap_proxy<typename boost::gil::packed_channel_reference<BF,FB,NB,M>::value_type>(x,y);
}
/// \ingroup PackedChannelReferenceModel
/// \brief swap for packed_channel_reference
template <typename BF, int FB, int NB, bool M> inline
void swap(const boost::gil::packed_channel_reference<BF,FB,NB,M> x, const boost::gil::packed_channel_reference<BF,FB,NB,M> y) {
boost::gil::swap_proxy<typename boost::gil::packed_channel_reference<BF,FB,NB,M>::value_type>(x,y);
}
} // namespace std
namespace boost { namespace gil {
/**
\defgroup PackedChannelDynamicReferenceModel packed_dynamic_channel_reference
\ingroup ChannelModel
\brief Represents a reference proxy to a channel operating over a bit range whose offset is specified at run time. Models ChannelConcept
Example:
\code
// Reference to a 2-bit channel whose offset is specified at construction time
typedef const packed_dynamic_channel_reference<uint8_t,2,true> bits2_dynamic_ref_t;
uint16_t data=0;
bits2_dynamic_ref_t channel_ref(&data,1);
channel_ref = channel_traits<bits2_dynamic_ref_t>::max_value(); // == 3
assert(data == 6); // == (3<<1) == 6
\endcode
*/
/// \brief Models a constant subbyte channel reference whose bit offset is a runtime parameter. Models ChannelConcept
/// Same as packed_channel_reference, except that the offset is a runtime parameter
/// \ingroup PackedChannelDynamicReferenceModel
template <typename BitField, int NumBits>
class packed_dynamic_channel_reference<BitField,NumBits,false>
: public detail::packed_channel_reference_base<packed_dynamic_channel_reference<BitField,NumBits,false>,BitField,NumBits,false> {
typedef detail::packed_channel_reference_base<packed_dynamic_channel_reference<BitField,NumBits,false>,BitField,NumBits,false> parent_t;
friend class packed_dynamic_channel_reference<BitField,NumBits,true>;
unsigned _first_bit; // 0..7
void operator=(const packed_dynamic_channel_reference&);
public:
typedef const packed_dynamic_channel_reference<BitField,NumBits,false> const_reference;
typedef const packed_dynamic_channel_reference<BitField,NumBits,true> mutable_reference;
typedef typename parent_t::integer_t integer_t;
packed_dynamic_channel_reference(const void* data_ptr, unsigned first_bit) : parent_t(data_ptr), _first_bit(first_bit) {}
packed_dynamic_channel_reference(const const_reference& ref) : parent_t(ref._data_ptr), _first_bit(ref._first_bit) {}
packed_dynamic_channel_reference(const mutable_reference& ref) : parent_t(ref._data_ptr), _first_bit(ref._first_bit) {}
unsigned first_bit() const { return _first_bit; }
integer_t get() const {
const BitField channel_mask = parent_t::max_val<<_first_bit;
return (this->get_data()&channel_mask) >> _first_bit;
}
};
/// \brief Models a mutable subbyte channel reference whose bit offset is a runtime parameter. Models ChannelConcept
/// Same as packed_channel_reference, except that the offset is a runtime parameter
/// \ingroup PackedChannelDynamicReferenceModel
template <typename BitField, int NumBits>
class packed_dynamic_channel_reference<BitField,NumBits,true>
: public detail::packed_channel_reference_base<packed_dynamic_channel_reference<BitField,NumBits,true>,BitField,NumBits,true> {
typedef detail::packed_channel_reference_base<packed_dynamic_channel_reference<BitField,NumBits,true>,BitField,NumBits,true> parent_t;
friend class packed_dynamic_channel_reference<BitField,NumBits,false>;
unsigned _first_bit;
public:
typedef const packed_dynamic_channel_reference<BitField,NumBits,false> const_reference;
typedef const packed_dynamic_channel_reference<BitField,NumBits,true> mutable_reference;
typedef typename parent_t::integer_t integer_t;
packed_dynamic_channel_reference(void* data_ptr, unsigned first_bit) : parent_t(data_ptr), _first_bit(first_bit) {}
packed_dynamic_channel_reference(const packed_dynamic_channel_reference& ref) : parent_t(ref._data_ptr), _first_bit(ref._first_bit) {}
const packed_dynamic_channel_reference& operator=(integer_t value) const { assert(value<=parent_t::max_val); set_unsafe(value); return *this; }
const packed_dynamic_channel_reference& operator=(const mutable_reference& ref) const { set_unsafe(ref.get()); return *this; }
const packed_dynamic_channel_reference& operator=(const const_reference& ref) const { set_unsafe(ref.get()); return *this; }
template <typename BitField1, int FirstBit1, bool Mutable1>
const packed_dynamic_channel_reference& operator=(const packed_channel_reference<BitField1, FirstBit1, NumBits, Mutable1>& ref) const
{ set_unsafe(ref.get()); return *this; }
unsigned first_bit() const { return _first_bit; }
integer_t get() const {
const BitField channel_mask = parent_t::max_val<<_first_bit;
return (this->get_data()&channel_mask) >> _first_bit;
}
void set_unsafe(integer_t value) const {
const BitField channel_mask = parent_t::max_val<<_first_bit;
this->set_data((this->get_data() & ~channel_mask) | value<<_first_bit);
}
};
} } // namespace boost::gil
namespace std {
// We are forced to define swap inside std namespace because on some platforms (Visual Studio 8) STL calls swap qualified.
// swap with 'left bias':
// - swap between proxy and anything
// - swap between value type and proxy
// - swap between proxy and proxy
/// \ingroup PackedChannelDynamicReferenceModel
/// \brief swap for packed_dynamic_channel_reference
template <typename BF, int NB, bool M, typename R> inline
void swap(const boost::gil::packed_dynamic_channel_reference<BF,NB,M> x, R& y) {
boost::gil::swap_proxy<typename boost::gil::packed_dynamic_channel_reference<BF,NB,M>::value_type>(x,y);
}
/// \ingroup PackedChannelDynamicReferenceModel
/// \brief swap for packed_dynamic_channel_reference
template <typename BF, int NB, bool M> inline
void swap(typename boost::gil::packed_dynamic_channel_reference<BF,NB,M>::value_type& x, const boost::gil::packed_dynamic_channel_reference<BF,NB,M> y) {
boost::gil::swap_proxy<typename boost::gil::packed_dynamic_channel_reference<BF,NB,M>::value_type>(x,y);
}
/// \ingroup PackedChannelDynamicReferenceModel
/// \brief swap for packed_dynamic_channel_reference
template <typename BF, int NB, bool M> inline
void swap(const boost::gil::packed_dynamic_channel_reference<BF,NB,M> x, const boost::gil::packed_dynamic_channel_reference<BF,NB,M> y) {
boost::gil::swap_proxy<typename boost::gil::packed_dynamic_channel_reference<BF,NB,M>::value_type>(x,y);
}
} // namespace std
namespace boost { namespace gil {
///////////////////////////////////////////
////
//// Built-in channel models
////
///////////////////////////////////////////
/// \defgroup bits8 bits8
/// \ingroup ChannelModel
/// \brief 8-bit unsigned integral channel type (typedef from uint8_t). Models ChannelValueConcept
/// \ingroup bits8
typedef uint8_t bits8;
/// \defgroup bits16 bits16
/// \ingroup ChannelModel
/// \brief 16-bit unsigned integral channel type (typedef from uint16_t). Models ChannelValueConcept
/// \ingroup bits16
typedef uint16_t bits16;
/// \defgroup bits32 bits32
/// \ingroup ChannelModel
/// \brief 32-bit unsigned integral channel type (typedef from uint32_t). Models ChannelValueConcept
/// \ingroup bits32
typedef uint32_t bits32;
/// \defgroup bits8s bits8s
/// \ingroup ChannelModel
/// \brief 8-bit signed integral channel type (typedef from int8_t). Models ChannelValueConcept
/// \ingroup bits8s
typedef int8_t bits8s;
/// \defgroup bits16s bits16s
/// \ingroup ChannelModel
/// \brief 16-bit signed integral channel type (typedef from int16_t). Models ChannelValueConcept
/// \ingroup bits16s
typedef int16_t bits16s;
/// \defgroup bits32s bits32s
/// \ingroup ChannelModel
/// \brief 32-bit signed integral channel type (typedef from int32_t). Models ChannelValueConcept
/// \ingroup bits32s
typedef int32_t bits32s;
/// \defgroup bits32f bits32f
/// \ingroup ChannelModel
/// \brief 32-bit floating point channel type with range [0.0f ... 1.0f]. Models ChannelValueConcept
/// \ingroup bits32f
typedef scoped_channel_value<float,float_zero,float_one> bits32f;
} } // namespace boost::gil
namespace boost {
template <int NumBits>
struct is_integral<gil::packed_channel_value<NumBits> > : public mpl::true_ {};
template <typename BitField, int FirstBit, int NumBits, bool IsMutable>
struct is_integral<gil::packed_channel_reference<BitField,FirstBit,NumBits,IsMutable> > : public mpl::true_ {};
template <typename BitField, int NumBits, bool IsMutable>
struct is_integral<gil::packed_dynamic_channel_reference<BitField,NumBits,IsMutable> > : public mpl::true_ {};
template <typename BaseChannelValue, typename MinVal, typename MaxVal>
struct is_integral<gil::scoped_channel_value<BaseChannelValue,MinVal,MaxVal> > : public is_integral<BaseChannelValue> {};
}
#endif

View File

@ -0,0 +1,469 @@
/*
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_CHANNEL_ALGORITHM_HPP
#define GIL_CHANNEL_ALGORITHM_HPP
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Channel algorithms
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on May 6, 2007
///
/// Definitions of standard GIL 8-bit, 16-bit, 32-bit channels
///
////////////////////////////////////////////////////////////////////////////////////////
#include "gil_config.hpp"
#include "channel.hpp"
#include <boost/mpl/less.hpp>
#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/greater.hpp>
#include <boost/type_traits.hpp>
namespace boost { namespace gil {
//#ifdef _MSC_VER
//#pragma warning(push)
//#pragma warning(disable: 4309) // disable truncation of constant value warning (using -1 to get the max value of an integral)
//#endif
namespace detail {
// some forward declarations
template <typename SrcChannelV, typename DstChannelV, bool SrcIsIntegral, bool DstIsIntegral> struct channel_converter_unsigned_impl;
template <typename SrcChannelV, typename DstChannelV, bool SrcIsGreater> struct channel_converter_unsigned_integral;
template <typename SrcChannelV, typename DstChannelV, bool SrcLessThanDst, bool SrcDivisible> struct channel_converter_unsigned_integral_impl;
template <typename SrcChannelV, typename DstChannelV, bool SrcLessThanDst, bool CannotFitInInteger> struct channel_converter_unsigned_integral_nondivisible;
//////////////////////////////////////
//// unsigned_integral_max_value - given an unsigned integral channel type, returns its maximum value as an MPL integral constant
//////////////////////////////////////
template <typename UnsignedIntegralChannel>
struct unsigned_integral_max_value : public mpl::integral_c<UnsignedIntegralChannel,-1> {};
template <>
struct unsigned_integral_max_value<uint8_t> : public mpl::integral_c<uint32_t,0xFF> {};
template <>
struct unsigned_integral_max_value<uint16_t> : public mpl::integral_c<uint32_t,0xFFFF> {};
template <>
struct unsigned_integral_max_value<uint32_t> : public mpl::integral_c<uintmax_t,0xFFFFFFFF> {};
template <int K>
struct unsigned_integral_max_value<packed_channel_value<K> >
: public mpl::integral_c<typename packed_channel_value<K>::integer_t, (1<<K)-1> {};
//////////////////////////////////////
//// unsigned_integral_num_bits - given an unsigned integral channel type, returns the minimum number of bits needed to represent it
//////////////////////////////////////
template <typename UnsignedIntegralChannel>
struct unsigned_integral_num_bits : public mpl::int_<sizeof(UnsignedIntegralChannel)*8> {};
template <int K>
struct unsigned_integral_num_bits<packed_channel_value<K> >
: public mpl::int_<K> {};
} // namespace detail
/**
\defgroup ChannelConvertAlgorithm channel_convert
\brief Converting from one channel type to another
\ingroup ChannelAlgorithm
Conversion is done as a simple linear mapping of one channel range to the other,
such that the minimum/maximum value of the source maps to the minimum/maximum value of the destination.
One implication of this is that the value 0 of signed channels may not be preserved!
When creating new channel models, it is often a good idea to provide specializations for the channel conversion algorithms, for
example, for performance optimizations. If the new model is an integral type that can be signed, it is easier to define the conversion
only for the unsigned type (\p channel_converter_unsigned) and provide specializations of \p detail::channel_convert_to_unsigned
and \p detail::channel_convert_from_unsigned to convert between the signed and unsigned type.
Example:
\code
// bits32f is a floating point channel with range [0.0f ... 1.0f]
bits32f src_channel = channel_traits<bits32f>::max_value();
assert(src_channel == 1);
// bits8 is 8-bit unsigned integral channel (typedef-ed from unsigned char)
bits8 dst_channel = channel_convert<bits8>(src_channel);
assert(dst_channel == 255); // max value goes to max value
\endcode
*/
/**
\defgroup ChannelConvertUnsignedAlgorithm channel_converter_unsigned
\ingroup ChannelConvertAlgorithm
\brief Convert one unsigned/floating point channel to another. Converts both the channel type and range
@{
*/
//////////////////////////////////////
//// channel_converter_unsigned
//////////////////////////////////////
template <typename SrcChannelV, typename DstChannelV> // Model ChannelValueConcept
struct channel_converter_unsigned
: public detail::channel_converter_unsigned_impl<SrcChannelV,DstChannelV,is_integral<SrcChannelV>::value,is_integral<DstChannelV>::value> {};
/// \brief Converting a channel to itself - identity operation
template <typename T> struct channel_converter_unsigned<T,T> : public detail::identity<T> {};
namespace detail {
//////////////////////////////////////
//// channel_converter_unsigned_impl
//////////////////////////////////////
/// \brief This is the default implementation. Performance specializatons are provided
template <typename SrcChannelV, typename DstChannelV, bool SrcIsIntegral, bool DstIsIntegral>
struct channel_converter_unsigned_impl : public std::unary_function<DstChannelV,SrcChannelV> {
DstChannelV operator()(SrcChannelV src) const {
return DstChannelV(channel_traits<DstChannelV>::min_value() +
(src - channel_traits<SrcChannelV>::min_value()) / channel_range<SrcChannelV>() * channel_range<DstChannelV>());
}
private:
template <typename C>
static double channel_range() {
return double(channel_traits<C>::max_value()) - double(channel_traits<C>::min_value());
}
};
// When both the source and the destination are integral channels, perform a faster conversion
template <typename SrcChannelV, typename DstChannelV>
struct channel_converter_unsigned_impl<SrcChannelV,DstChannelV,true,true>
: public channel_converter_unsigned_integral<SrcChannelV,DstChannelV,
mpl::less<unsigned_integral_max_value<SrcChannelV>,unsigned_integral_max_value<DstChannelV> >::value > {};
//////////////////////////////////////
//// channel_converter_unsigned_integral
//////////////////////////////////////
template <typename SrcChannelV, typename DstChannelV>
struct channel_converter_unsigned_integral<SrcChannelV,DstChannelV,true>
: public channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,true,
!(unsigned_integral_max_value<DstChannelV>::value % unsigned_integral_max_value<SrcChannelV>::value) > {};
template <typename SrcChannelV, typename DstChannelV>
struct channel_converter_unsigned_integral<SrcChannelV,DstChannelV,false>
: public channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,false,
!(unsigned_integral_max_value<SrcChannelV>::value % unsigned_integral_max_value<DstChannelV>::value) > {};
//////////////////////////////////////
//// channel_converter_unsigned_integral_impl
//////////////////////////////////////
// Both source and destination are unsigned integral channels,
// the src max value is less than the dst max value,
// and the dst max value is divisible by the src max value
template <typename SrcChannelV, typename DstChannelV>
struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,true,true> {
DstChannelV operator()(SrcChannelV src) const {
typedef typename unsigned_integral_max_value<DstChannelV>::value_type integer_t;
static const integer_t mul = unsigned_integral_max_value<DstChannelV>::value / unsigned_integral_max_value<SrcChannelV>::value;
return DstChannelV(src * mul);
}
};
// Both source and destination are unsigned integral channels,
// the dst max value is less than (or equal to) the src max value,
// and the src max value is divisible by the dst max value
template <typename SrcChannelV, typename DstChannelV>
struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,false,true> {
DstChannelV operator()(SrcChannelV src) const {
typedef typename unsigned_integral_max_value<SrcChannelV>::value_type integer_t;
static const integer_t div = unsigned_integral_max_value<SrcChannelV>::value / unsigned_integral_max_value<DstChannelV>::value;
static const integer_t div2 = div/2;
return DstChannelV((src + div2) / div);
}
};
// Prevent overflow for the largest integral type
template <typename DstChannelV>
struct channel_converter_unsigned_integral_impl<uintmax_t,DstChannelV,false,true> {
DstChannelV operator()(uintmax_t src) const {
static const uintmax_t div = unsigned_integral_max_value<bits32>::value / unsigned_integral_max_value<DstChannelV>::value;
static const uintmax_t div2 = div/2;
if (src > unsigned_integral_max_value<uintmax_t>::value - div2)
return unsigned_integral_max_value<DstChannelV>::value;
return DstChannelV((src + div2) / div);
}
};
// Both source and destination are unsigned integral channels,
// and the dst max value is not divisible by the src max value
// See if you can represent the expression (src * dst_max) / src_max in integral form
template <typename SrcChannelV, typename DstChannelV, bool SrcLessThanDst>
struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,SrcLessThanDst,false>
: public channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,SrcLessThanDst,
mpl::greater<
mpl::plus<unsigned_integral_num_bits<SrcChannelV>,unsigned_integral_num_bits<DstChannelV> >,
unsigned_integral_num_bits<uintmax_t>
>::value> {};
// Both source and destination are unsigned integral channels,
// the src max value is less than the dst max value,
// and the dst max value is not divisible by the src max value
// The expression (src * dst_max) / src_max fits in an integer
template <typename SrcChannelV, typename DstChannelV>
struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,true,false> {
DstChannelV operator()(SrcChannelV src) const {
typedef typename detail::min_fast_uint<unsigned_integral_num_bits<SrcChannelV>::value+unsigned_integral_num_bits<DstChannelV>::value>::type integer_t;
return DstChannelV(integer_t(src * unsigned_integral_max_value<DstChannelV>::value) / unsigned_integral_max_value<SrcChannelV>::value);
}
};
// Both source and destination are unsigned integral channels,
// the src max value is less than the dst max value,
// and the dst max value is not divisible by the src max value
// The expression (src * dst_max) / src_max cannot fit in an integer (overflows). Use a double
template <typename SrcChannelV, typename DstChannelV>
struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,true,true> {
DstChannelV operator()(SrcChannelV src) const {
static const double mul = unsigned_integral_max_value<DstChannelV>::value / double(unsigned_integral_max_value<SrcChannelV>::value);
return DstChannelV(src * mul);
}
};
// Both source and destination are unsigned integral channels,
// the dst max value is less than (or equal to) the src max value,
// and the src max value is not divisible by the dst max value
template <typename SrcChannelV, typename DstChannelV, bool CannotFit>
struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,false,CannotFit> {
DstChannelV operator()(SrcChannelV src) const {
typedef typename unsigned_integral_max_value<SrcChannelV>::value_type integer_t;
static const double div = unsigned_integral_max_value<SrcChannelV>::value / double(unsigned_integral_max_value<DstChannelV>::value);
static const integer_t div2 = integer_t(div/2);
return DstChannelV((src + div2) / div);
}
};
} // namespace detail
/////////////////////////////////////////////////////
/// bits32f conversion
/////////////////////////////////////////////////////
template <typename DstChannelV> struct channel_converter_unsigned<bits32f,DstChannelV> : public std::unary_function<bits32f,DstChannelV> {
DstChannelV operator()(bits32f x) const { return DstChannelV(x*channel_traits<DstChannelV>::max_value()+0.5f); }
};
template <typename SrcChannelV> struct channel_converter_unsigned<SrcChannelV,bits32f> : public std::unary_function<SrcChannelV,bits32f> {
bits32f operator()(SrcChannelV x) const { return bits32f(x/float(channel_traits<SrcChannelV>::max_value())); }
};
template <> struct channel_converter_unsigned<bits32f,bits32f> : public std::unary_function<bits32f,bits32f> {
bits32f operator()(bits32f x) const { return x; }
};
/// \brief 32 bit <-> float channel conversion
template <> struct channel_converter_unsigned<bits32,bits32f> : public std::unary_function<bits32,bits32f> {
bits32f operator()(bits32 x) const {
// unfortunately without an explicit check it is possible to get a round-off error. We must ensure that max_value of bits32 matches max_value of bits32f
if (x>=channel_traits<bits32>::max_value()) return channel_traits<bits32f>::max_value();
return float(x) / float(channel_traits<bits32>::max_value());
}
};
/// \brief 32 bit <-> float channel conversion
template <> struct channel_converter_unsigned<bits32f,bits32> : public std::unary_function<bits32f,bits32> {
bits32 operator()(bits32f x) const {
// unfortunately without an explicit check it is possible to get a round-off error. We must ensure that max_value of bits32 matches max_value of bits32f
if (x>=channel_traits<bits32f>::max_value()) return channel_traits<bits32>::max_value();
return bits32(x * channel_traits<bits32>::max_value() + 0.5f);
}
};
/// @}
namespace detail {
// Converting from signed to unsigned integral channel.
// It is both a unary function, and a metafunction (thus requires the 'type' nested typedef, which equals result_type)
template <typename ChannelValue> // Model ChannelValueConcept
struct channel_convert_to_unsigned : public detail::identity<ChannelValue> {
typedef ChannelValue type;
};
template <> struct channel_convert_to_unsigned<bits8s> : public std::unary_function<bits8s,bits8> {
typedef bits8 type;
type operator()(bits8s val) const { return val+128; }
};
template <> struct channel_convert_to_unsigned<bits16s> : public std::unary_function<bits16s,bits16> {
typedef bits16 type;
type operator()(bits16s val) const { return val+32768; }
};
template <> struct channel_convert_to_unsigned<bits32s> : public std::unary_function<bits32s,bits32> {
typedef bits32 type;
type operator()(bits32s x) const { return static_cast<bits32>(x+(1<<31)); }
};
// Converting from unsigned to signed integral channel
// It is both a unary function, and a metafunction (thus requires the 'type' nested typedef, which equals result_type)
template <typename ChannelValue> // Model ChannelValueConcept
struct channel_convert_from_unsigned : public detail::identity<ChannelValue> {
typedef ChannelValue type;
};
template <> struct channel_convert_from_unsigned<bits8s> : public std::unary_function<bits8,bits8s> {
typedef bits8s type;
type operator()(bits8 val) const { return val-128; }
};
template <> struct channel_convert_from_unsigned<bits16s> : public std::unary_function<bits16,bits16s> {
typedef bits16s type;
type operator()(bits16 val) const { return val-32768; }
};
template <> struct channel_convert_from_unsigned<bits32s> : public std::unary_function<bits32,bits32s> {
typedef bits32s type;
type operator()(bits32 x) const { return static_cast<bits32s>(x-(1<<31)); }
};
} // namespace detail
/// \ingroup ChannelConvertAlgorithm
/// \brief A unary function object converting between channel types
template <typename SrcChannelV, typename DstChannelV> // Model ChannelValueConcept
struct channel_converter : public std::unary_function<SrcChannelV,DstChannelV> {
DstChannelV operator()(SrcChannelV src) const {
typedef detail::channel_convert_to_unsigned<SrcChannelV> to_unsigned;
typedef detail::channel_convert_from_unsigned<DstChannelV> from_unsigned;
typedef channel_converter_unsigned<typename to_unsigned::result_type, typename from_unsigned::argument_type> converter_unsigned;
return from_unsigned()(converter_unsigned()(to_unsigned()(src)));
}
};
/// \ingroup ChannelConvertAlgorithm
/// \brief Converting from one channel type to another.
template <typename DstChannel, typename SrcChannel> // Model ChannelConcept (could be channel references)
inline typename channel_traits<DstChannel>::value_type channel_convert(SrcChannel src) {
return channel_converter<typename channel_traits<SrcChannel>::value_type,
typename channel_traits<DstChannel>::value_type>()(src);
}
/// \ingroup ChannelConvertAlgorithm
/// \brief Same as channel_converter, except it takes the destination channel by reference, which allows
/// us to move the templates from the class level to the method level. This is important when invoking it
/// on heterogeneous pixels.
struct default_channel_converter {
template <typename Ch1, typename Ch2>
void operator()(const Ch1& src, Ch2& dst) const {
dst=channel_convert<Ch2>(src);
}
};
namespace detail {
// fast integer division by 255
inline uint32_t div255(uint32_t in) { uint32_t tmp=in+128; return (tmp + (tmp>>8))>>8; }
// fast integer divison by 32768
inline uint32_t div32768(uint32_t in) { return (in+16384)>>15; }
}
/**
\defgroup ChannelMultiplyAlgorithm channel_multiply
\ingroup ChannelAlgorithm
\brief Multiplying unsigned channel values of the same type. Performs scaled multiplication result = a * b / max_value
Example:
\code
bits8 x=128;
bits8 y=128;
bits8 mul = channel_multiply(x,y);
assert(mul == 64); // 64 = 128 * 128 / 255
\endcode
*/
/// @{
/// \brief This is the default implementation. Performance specializatons are provided
template <typename ChannelValue>
struct channel_multiplier_unsigned : public std::binary_function<ChannelValue,ChannelValue,ChannelValue> {
ChannelValue operator()(ChannelValue a, ChannelValue b) const {
return ChannelValue(a / double(channel_traits<ChannelValue>::max_value()) * b);
}
};
/// \brief Specialization of channel_multiply for 8-bit unsigned channels
template<> struct channel_multiplier_unsigned<bits8> : public std::binary_function<bits8,bits8,bits8> {
bits8 operator()(bits8 a, bits8 b) const { return bits8(detail::div255(uint32_t(a) * uint32_t(b))); }
};
/// \brief Specialization of channel_multiply for 16-bit unsigned channels
template<> struct channel_multiplier_unsigned<bits16> : public std::binary_function<bits16,bits16,bits16> {
bits16 operator()(bits16 a, bits16 b) const { return bits16((uint32_t(a) * uint32_t(b))/65535); }
};
/// \brief Specialization of channel_multiply for float 0..1 channels
template<> struct channel_multiplier_unsigned<bits32f> : public std::binary_function<bits32f,bits32f,bits32f> {
bits32f operator()(bits32f a, bits32f b) const { return a*b; }
};
/// \brief A function object to multiply two channels. result = a * b / max_value
template <typename ChannelValue>
struct channel_multiplier : public std::binary_function<ChannelValue, ChannelValue, ChannelValue> {
ChannelValue operator()(ChannelValue a, ChannelValue b) const {
typedef detail::channel_convert_to_unsigned<ChannelValue> to_unsigned;
typedef detail::channel_convert_from_unsigned<ChannelValue> from_unsigned;
typedef channel_multiplier_unsigned<typename to_unsigned::result_type> multiplier_unsigned;
return from_unsigned()(multiplier_unsigned()(to_unsigned()(a), to_unsigned()(b)));
}
};
/// \brief A function multiplying two channels. result = a * b / max_value
template <typename Channel> // Models ChannelConcept (could be a channel reference)
inline typename channel_traits<Channel>::value_type channel_multiply(Channel a, Channel b) {
return channel_multiplier<typename channel_traits<Channel>::value_type>()(a,b);
}
/// @}
/**
\defgroup ChannelInvertAlgorithm channel_invert
\ingroup ChannelAlgorithm
\brief Returns the inverse of a channel. result = max_value - x + min_value
Example:
\code
// bits8 == uint8_t == unsigned char
bits8 x=255;
bits8 inv = channel_invert(x);
assert(inv == 0);
\endcode
*/
/// \brief Default implementation. Provide overloads for performance
/// \ingroup ChannelInvertAlgorithm channel_invert
template <typename Channel> // Models ChannelConcept (could be a channel reference)
inline typename channel_traits<Channel>::value_type channel_invert(Channel x) {
return channel_traits<Channel>::max_value()-x + channel_traits<Channel>::min_value();
}
//#ifdef _MSC_VER
//#pragma warning(pop)
//#endif
} } // namespace boost::gil
#endif

66
src/3rdparty/include/boost/gil/cmyk.hpp vendored Normal file
View File

@ -0,0 +1,66 @@
/*
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_CMYK_H
#define GIL_CMYK_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Support for CMYK color space and variants
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on October 10, 2007
////////////////////////////////////////////////////////////////////////////////////////
#include <cstddef>
#include "gil_config.hpp"
#include "metafunctions.hpp"
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/vector_c.hpp>
namespace boost { namespace gil {
/// \addtogroup ColorNameModel
/// \{
/// \brief Cyan
struct cyan_t {};
/// \brief Magenta
struct magenta_t {};
/// \brief Yellow
struct yellow_t {};
/// \brief Black
struct black_t {};
/// \}
/// \ingroup ColorSpaceModel
typedef mpl::vector4<cyan_t,magenta_t,yellow_t,black_t> cmyk_t;
/// \ingroup LayoutModel
typedef layout<cmyk_t> cmyk_layout_t;
/// \ingroup ImageViewConstructors
/// \brief from raw CMYK planar data
template <typename IC>
inline typename type_from_x_iterator<planar_pixel_iterator<IC,cmyk_t> >::view_t
planar_cmyk_view(std::size_t width, std::size_t height, IC c, IC m, IC y, IC k, std::ptrdiff_t rowsize_in_bytes) {
typedef typename type_from_x_iterator<planar_pixel_iterator<IC,cmyk_t> >::view_t RView;
return RView(width, height, typename RView::locator(planar_pixel_iterator<IC,cmyk_t>(c,m,y,k), rowsize_in_bytes));
}
} } // namespace gil
#endif

View File

@ -0,0 +1,410 @@
/*
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://stlab.adobe.com/gil for most recent version including documentation.
*/
/*************************************************************************************************/
#ifndef GIL_COLOR_BASE_HPP
#define GIL_COLOR_BASE_HPP
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief pixel class and related utilities
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on May 6, 2007
///
////////////////////////////////////////////////////////////////////////////////////////
#include <cassert>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>
#include "gil_config.hpp"
#include "utilities.hpp"
#include "gil_concept.hpp"
namespace boost { namespace gil {
// Forward-declare
template <typename P> P* memunit_advanced(const P* p, std::ptrdiff_t diff);
// Forward-declare semantic_at_c
template <int K, typename ColorBase>
typename disable_if<is_const<ColorBase>,typename kth_semantic_element_reference_type<ColorBase,K>::type>::type semantic_at_c(ColorBase& p);
template <int K, typename ColorBase>
typename kth_semantic_element_const_reference_type<ColorBase,K>::type semantic_at_c(const ColorBase& p);
// Forward declare element_reference_type
template <typename ColorBase> struct element_reference_type;
template <typename ColorBase> struct element_const_reference_type;
template <typename ColorBase, int K> struct kth_element_type;
template <typename ColorBase, int K> struct kth_element_type<const ColorBase,K> : public kth_element_type<ColorBase,K> {};
template <typename ColorBase, int K> struct kth_element_reference_type;
template <typename ColorBase, int K> struct kth_element_reference_type<const ColorBase,K> : public kth_element_reference_type<ColorBase,K> {};
template <typename ColorBase, int K> struct kth_element_const_reference_type;
template <typename ColorBase, int K> struct kth_element_const_reference_type<const ColorBase,K> : public kth_element_const_reference_type<ColorBase,K> {};
namespace detail {
template <typename DstLayout, typename SrcLayout, int K>
struct mapping_transform
: public mpl::at<typename SrcLayout::channel_mapping_t,
typename detail::type_to_index<typename DstLayout::channel_mapping_t,mpl::integral_c<int,K> >::type
>::type {};
/// \defgroup ColorBaseModelHomogeneous detail::homogeneous_color_base
/// \ingroup ColorBaseModel
/// \brief A homogeneous color base holding one color element. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
/// If the element type models Regular, this class models HomogeneousColorBaseValueConcept.
/// \brief A homogeneous color base holding one color element. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
/// \ingroup ColorBaseModelHomogeneous
template <typename Element, typename Layout>
struct homogeneous_color_base<Element,Layout,1> {
private:
Element _v0;
public:
typedef Layout layout_t;
typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
homogeneous_color_base() {}
homogeneous_color_base(Element v) : _v0(v) {}
// grayscale pixel values are convertible to channel type
operator Element () const { return _v0; }
template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,1>& c) : _v0(at_c<0>(c)) {}
};
/// \brief A homogeneous color base holding two color elements. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
/// \ingroup ColorBaseModelHomogeneous
template <typename Element, typename Layout>
struct homogeneous_color_base<Element,Layout,2> {
private:
Element _v0, _v1;
public:
typedef Layout layout_t;
typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
homogeneous_color_base() {}
explicit homogeneous_color_base(Element v) : _v0(v), _v1(v) {}
homogeneous_color_base(Element v0, Element v1) : _v0(v0), _v1(v1) {}
template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,2>& c) :
_v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
_v1(at_c<mapping_transform<Layout,L2,1>::value>(c)) {}
// Support for l-value reference proxy copy construction
template <typename E2, typename L2> homogeneous_color_base( homogeneous_color_base<E2,L2,2>& c) :
_v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
_v1(at_c<mapping_transform<Layout,L2,1>::value>(c)) {}
// Support for planar_pixel_iterator construction and dereferencing
template <typename P> homogeneous_color_base(P* p,bool) :
_v0(&semantic_at_c<0>(*p)),
_v1(&semantic_at_c<1>(*p)) {}
template <typename Ref> Ref deref() const {
return Ref(*semantic_at_c<0>(*this),
*semantic_at_c<1>(*this)); }
// Support for planar_pixel_reference offset constructor
template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
: _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
_v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)) {}
// Support for planar_pixel_reference operator[]
Element at_c_dynamic(std::size_t i) const {
if (i==0) return _v0;
return _v1;
}
};
/// \brief A homogeneous color base holding three color elements. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
/// \ingroup ColorBaseModelHomogeneous
template <typename Element, typename Layout>
struct homogeneous_color_base<Element,Layout,3> {
private:
Element _v0, _v1, _v2;
public:
typedef Layout layout_t;
typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) { return _v2; }
typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
homogeneous_color_base() {}
explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v) {}
homogeneous_color_base(Element v0, Element v1, Element v2) : _v0(v0), _v1(v1), _v2(v2) {}
template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,3>& c) :
_v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
_v1(at_c<mapping_transform<Layout,L2,1>::value>(c)),
_v2(at_c<mapping_transform<Layout,L2,2>::value>(c)) {}
// Support for l-value reference proxy copy construction
template <typename E2, typename L2> homogeneous_color_base( homogeneous_color_base<E2,L2,3>& c) :
_v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
_v1(at_c<mapping_transform<Layout,L2,1>::value>(c)),
_v2(at_c<mapping_transform<Layout,L2,2>::value>(c)) {}
// Support for planar_pixel_iterator construction and dereferencing
template <typename P> homogeneous_color_base(P* p,bool) :
_v0(&semantic_at_c<0>(*p)),
_v1(&semantic_at_c<1>(*p)),
_v2(&semantic_at_c<2>(*p)) {}
template <typename Ref> Ref deref() const {
return Ref(*semantic_at_c<0>(*this),
*semantic_at_c<1>(*this),
*semantic_at_c<2>(*this)); }
// Support for planar_pixel_reference offset constructor
template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
: _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
_v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
_v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)) {}
// Support for planar_pixel_reference operator[]
Element at_c_dynamic(std::size_t i) const {
switch (i) {
case 0: return _v0;
case 1: return _v1;
}
return _v2;
}
};
/// \brief A homogeneous color base holding four color elements. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
/// \ingroup ColorBaseModelHomogeneous
template <typename Element, typename Layout>
struct homogeneous_color_base<Element,Layout,4> {
private:
Element _v0, _v1, _v2, _v3;
public:
typedef Layout layout_t;
typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) { return _v2; }
typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) { return _v3; }
typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) const { return _v3; }
homogeneous_color_base() {}
explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v), _v3(v) {}
homogeneous_color_base(Element v0, Element v1, Element v2, Element v3) : _v0(v0), _v1(v1), _v2(v2), _v3(v3) {}
template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,4>& c) :
_v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
_v1(at_c<mapping_transform<Layout,L2,1>::value>(c)),
_v2(at_c<mapping_transform<Layout,L2,2>::value>(c)),
_v3(at_c<mapping_transform<Layout,L2,3>::value>(c)) {}
// Support for l-value reference proxy copy construction
template <typename E2, typename L2> homogeneous_color_base( homogeneous_color_base<E2,L2,4>& c) :
_v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
_v1(at_c<mapping_transform<Layout,L2,1>::value>(c)),
_v2(at_c<mapping_transform<Layout,L2,2>::value>(c)),
_v3(at_c<mapping_transform<Layout,L2,3>::value>(c)) {}
// Support for planar_pixel_iterator construction and dereferencing
template <typename P> homogeneous_color_base(P* p,bool) :
_v0(&semantic_at_c<0>(*p)),
_v1(&semantic_at_c<1>(*p)),
_v2(&semantic_at_c<2>(*p)),
_v3(&semantic_at_c<3>(*p)) {}
template <typename Ref> Ref deref() const {
return Ref(*semantic_at_c<0>(*this),
*semantic_at_c<1>(*this),
*semantic_at_c<2>(*this),
*semantic_at_c<3>(*this)); }
// Support for planar_pixel_reference offset constructor
template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
: _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
_v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
_v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)),
_v3(*memunit_advanced(semantic_at_c<3>(ptr),diff)) {}
// Support for planar_pixel_reference operator[]
Element at_c_dynamic(std::size_t i) const {
switch (i) {
case 0: return _v0;
case 1: return _v1;
case 2: return _v2;
}
return _v3;
}
};
/// \brief A homogeneous color base holding five color elements. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
/// \ingroup ColorBaseModelHomogeneous
template <typename Element, typename Layout>
struct homogeneous_color_base<Element,Layout,5> {
private:
Element _v0, _v1, _v2, _v3, _v4;
public:
typedef Layout layout_t;
typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) { return _v2; }
typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) { return _v3; }
typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) const { return _v3; }
typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<4>) { return _v4; }
typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<4>) const { return _v4; }
homogeneous_color_base() {}
explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v), _v3(v), _v4(v) {}
homogeneous_color_base(Element v0, Element v1, Element v2, Element v3, Element v4) : _v0(v0), _v1(v1), _v2(v2), _v3(v3), _v4(v4) {}
template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,5>& c) :
_v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
_v1(at_c<mapping_transform<Layout,L2,1>::value>(c)),
_v2(at_c<mapping_transform<Layout,L2,2>::value>(c)),
_v3(at_c<mapping_transform<Layout,L2,3>::value>(c)),
_v4(at_c<mapping_transform<Layout,L2,4>::value>(c)) {}
// Support for l-value reference proxy copy construction
template <typename E2, typename L2> homogeneous_color_base( homogeneous_color_base<E2,L2,5>& c) :
_v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
_v1(at_c<mapping_transform<Layout,L2,1>::value>(c)),
_v2(at_c<mapping_transform<Layout,L2,2>::value>(c)),
_v3(at_c<mapping_transform<Layout,L2,3>::value>(c)),
_v4(at_c<mapping_transform<Layout,L2,4>::value>(c)) {}
// Support for planar_pixel_iterator construction and dereferencing
template <typename P> homogeneous_color_base(P* p,bool) :
_v0(&semantic_at_c<0>(*p)),
_v1(&semantic_at_c<1>(*p)),
_v2(&semantic_at_c<2>(*p)),
_v3(&semantic_at_c<3>(*p)),
_v4(&semantic_at_c<4>(*p)) {}
template <typename Ref> Ref deref() const {
return Ref(*semantic_at_c<0>(*this),
*semantic_at_c<1>(*this),
*semantic_at_c<2>(*this),
*semantic_at_c<3>(*this),
*semantic_at_c<4>(*this)); }
// Support for planar_pixel_reference offset constructor
template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
: _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
_v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
_v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)),
_v3(*memunit_advanced(semantic_at_c<3>(ptr),diff)),
_v4(*memunit_advanced(semantic_at_c<4>(ptr),diff)) {}
// Support for planar_pixel_reference operator[]
Element at_c_dynamic(std::size_t i) const {
switch (i) {
case 0: return _v0;
case 1: return _v1;
case 2: return _v2;
case 3: return _v3;
}
return _v4;
}
};
// The following way of casting adjacent channels (the contents of color_base) into an array appears to be unsafe
// -- there is no guarantee that the compiler won't add any padding between adjacent channels.
// Note, however, that GIL _must_ be compiled with compiler settings ensuring there is no padding in the color base structs.
// This is because the color base structs must model the interleaved organization in memory. In other words, the client may
// have existing RGB image in the form "RGBRGBRGB..." and we must be able to represent it with an array of RGB color bases (i.e. RGB pixels)
// with no padding. We have tested with char/int/float/double channels on gcc and VC and have so far discovered no problem.
// We have even tried using strange channels consisting of short + char (3 bytes). With the default 4-byte alignment on VC, the size
// of this channel is padded to 4 bytes, so an RGB pixel of it will be 4x3=12 bytes. The code below will still work properly.
// However, the client must nevertheless ensure that proper compiler settings are used for their compiler and their channel types.
template <typename Element, typename Layout, int K>
typename element_reference_type<homogeneous_color_base<Element,Layout,K> >::type
dynamic_at_c(homogeneous_color_base<Element,Layout,K>& cb, std::size_t i) {
assert(i<K);
return (gil_reinterpret_cast<Element*>(&cb))[i];
}
template <typename Element, typename Layout, int K>
typename element_const_reference_type<homogeneous_color_base<Element,Layout,K> >::type
dynamic_at_c(const homogeneous_color_base<Element,Layout,K>& cb, std::size_t i) {
assert(i<K);
return (gil_reinterpret_cast_c<const Element*>(&cb))[i];
}
template <typename Element, typename Layout, int K>
typename element_reference_type<homogeneous_color_base<Element&,Layout,K> >::type
dynamic_at_c(const homogeneous_color_base<Element&,Layout,K>& cb, std::size_t i) {
assert(i<K);
return cb.at_c_dynamic(i);
}
template <typename Element, typename Layout, int K>
typename element_const_reference_type<homogeneous_color_base<const Element&,Layout,K> >::type
dynamic_at_c(const homogeneous_color_base<const Element&,Layout,K>& cb, std::size_t i) {
assert(i<K);
return cb.at_c_dynamic(i);
}
} // namespace detail
template <typename Element, typename Layout, int K1, int K>
struct kth_element_type<detail::homogeneous_color_base<Element,Layout,K1>, K> {
typedef Element type;
};
template <typename Element, typename Layout, int K1, int K>
struct kth_element_reference_type<detail::homogeneous_color_base<Element,Layout,K1>, K> : public add_reference<Element> {};
template <typename Element, typename Layout, int K1, int K>
struct kth_element_const_reference_type<detail::homogeneous_color_base<Element,Layout,K1>, K> : public add_reference<typename add_const<Element>::type> {};
/// \brief Provides mutable access to the K-th element, in physical order
/// \ingroup ColorBaseModelHomogeneous
template <int K, typename E, typename L, int N> inline
typename add_reference<E>::type
at_c( detail::homogeneous_color_base<E,L,N>& p) { return p.at(mpl::int_<K>()); }
/// \brief Provides constant access to the K-th element, in physical order
/// \ingroup ColorBaseModelHomogeneous
template <int K, typename E, typename L, int N> inline
typename add_reference<typename add_const<E>::type>::type
at_c(const detail::homogeneous_color_base<E,L,N>& p) { return p.at(mpl::int_<K>()); }
namespace detail {
struct swap_fn {
template <typename T> void operator()(T& x, T& y) const {
using std::swap;
swap(x,y);
}
};
}
template <typename E, typename L, int N> inline
void swap(detail::homogeneous_color_base<E,L,N>& x, detail::homogeneous_color_base<E,L,N>& y) {
static_for_each(x,y,detail::swap_fn());
}
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,696 @@
/*
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_BASE_ALGORITHM_HPP
#define GIL_COLOR_BASE_ALGORITHM_HPP
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief pixel related algorithms
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on February 16, 2007
///
////////////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/at.hpp>
#include "gil_config.hpp"
#include "gil_concept.hpp"
#include "utilities.hpp"
namespace boost { namespace gil {
///////////////////////////////////////
///
/// size: Semantic channel size
///
///////////////////////////////////////
/**
\defgroup ColorBaseAlgorithmSize size
\ingroup ColorBaseAlgorithm
\brief Returns an MPL integral type specifying the number of elements in a color base
Example:
\code
BOOST_STATIC_ASSERT((size<rgb8_pixel_t>::value == 3));
BOOST_STATIC_ASSERT((size<cmyk8_planar_ptr_t>::value == 4));
\endcode
*/
/// \brief Returns an MPL integral type specifying the number of elements in a color base
/// \ingroup ColorBaseAlgorithmSize
template <typename ColorBase>
struct size : public mpl::size<typename ColorBase::layout_t::color_space_t> {};
///////////////////////////////////////
///
/// semantic_at_c: Semantic channel accessors
///
///////////////////////////////////////
/**
\defgroup ColorBaseAlgorithmSemanticAtC kth_semantic_element_type, kth_semantic_element_reference_type, kth_semantic_element_const_reference_type, semantic_at_c
\ingroup ColorBaseAlgorithm
\brief Support for accessing the elements of a color base by semantic index
The semantic index of an element is the index of its color in the color space. Semantic indexing allows for proper pairing of elements of color bases
independent on their layout. For example, red is the first semantic element of a color base regardless of whether it has an RGB layout or a BGR layout.
All GIL color base algorithms taking multiple color bases use semantic indexing to access their elements.
Example:
\code
// 16-bit BGR pixel, 4 bits for the blue, 3 bits for the green, 2 bits for the red channel and 7 unused bits
typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,4,3,2>, bgr_layout_t>::type bgr432_pixel_t;
// A reference to its red channel. Although the red channel is the third, its semantic index is 0 in the RGB color space
typedef kth_semantic_element_reference_type<bgr432_pixel_t, 0>::type red_channel_reference_t;
// Initialize the pixel to black
bgr432_pixel_t red_pixel(0,0,0);
// Set the red channel to 100%
red_channel_reference_t red_channel = semantic_at_c<0>(red_pixel);
red_channel = channel_traits<red_channel_reference_t>::max_value();
\endcode
*/
/// \brief Specifies the type of the K-th semantic element of a color base
/// \ingroup ColorBaseAlgorithmSemanticAtC
template <typename ColorBase, int K> struct kth_semantic_element_type {
BOOST_STATIC_CONSTANT(int, semantic_index = (mpl::at_c<typename ColorBase::layout_t::channel_mapping_t,K>::type::value));
typedef typename kth_element_type<ColorBase, semantic_index>::type type;
};
/// \brief Specifies the return type of the mutable semantic_at_c<K>(color_base);
/// \ingroup ColorBaseAlgorithmSemanticAtC
template <typename ColorBase, int K> struct kth_semantic_element_reference_type {
BOOST_STATIC_CONSTANT(int, semantic_index = (mpl::at_c<typename ColorBase::layout_t::channel_mapping_t,K>::type::value));
typedef typename kth_element_reference_type<ColorBase,semantic_index>::type type;
static type get(ColorBase& cb) { return at_c<semantic_index>(cb); }
};
/// \brief Specifies the return type of the constant semantic_at_c<K>(color_base);
/// \ingroup ColorBaseAlgorithmSemanticAtC
template <typename ColorBase, int K> struct kth_semantic_element_const_reference_type {
BOOST_STATIC_CONSTANT(int, semantic_index = (mpl::at_c<typename ColorBase::layout_t::channel_mapping_t,K>::type::value));
typedef typename kth_element_const_reference_type<ColorBase,semantic_index>::type type;
static type get(const ColorBase& cb) { return at_c<semantic_index>(cb); }
};
/// \brief A mutable accessor to the K-th semantic element of a color base
/// \ingroup ColorBaseAlgorithmSemanticAtC
template <int K, typename ColorBase> inline
typename disable_if<is_const<ColorBase>,typename kth_semantic_element_reference_type<ColorBase,K>::type>::type
semantic_at_c(ColorBase& p) {
return kth_semantic_element_reference_type<ColorBase,K>::get(p);
}
/// \brief A constant accessor to the K-th semantic element of a color base
/// \ingroup ColorBaseAlgorithmSemanticAtC
template <int K, typename ColorBase> inline
typename kth_semantic_element_const_reference_type<ColorBase,K>::type
semantic_at_c(const ColorBase& p) {
return kth_semantic_element_const_reference_type<ColorBase,K>::get(p);
}
///////////////////////////////////////
///
/// get_color: Named channel accessors
///
///////////////////////////////////////
/**
\defgroup ColorBaseAlgorithmColor color_element_type, color_element_reference_type, color_element_const_reference_type, get_color, contains_color
\ingroup ColorBaseAlgorithm
\brief Support for accessing the elements of a color base by color name
Example: A function that takes a generic pixel containing a red channel and sets it to 100%:
\code
template <typename Pixel>
void set_red_to_max(Pixel& pixel) {
boost::function_requires<MutablePixelConcept<Pixel> >();
BOOST_STATIC_ASSERT((contains_color<Pixel, red_t>::value));
typedef typename color_element_type<Pixel, red_t>::type red_channel_t;
get_color(pixel, red_t()) = channel_traits<red_channel_t>::max_value();
}
\endcode
*/
/// \brief A predicate metafunction determining whether a given color base contains a given color
/// \ingroup ColorBaseAlgorithmColor
template <typename ColorBase, typename Color>
struct contains_color : public mpl::contains<typename ColorBase::layout_t::color_space_t,Color> {};
template <typename ColorBase, typename Color>
struct color_index_type : public detail::type_to_index<typename ColorBase::layout_t::color_space_t,Color> {};
/// \brief Specifies the type of the element associated with a given color tag
/// \ingroup ColorBaseAlgorithmColor
template <typename ColorBase, typename Color>
struct color_element_type : public kth_semantic_element_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
/// \brief Specifies the return type of the mutable element accessor by color name, get_color(color_base, Color());
/// \ingroup ColorBaseAlgorithmColor
template <typename ColorBase, typename Color>
struct color_element_reference_type : public kth_semantic_element_reference_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
/// \brief Specifies the return type of the constant element accessor by color name, get_color(color_base, Color());
/// \ingroup ColorBaseAlgorithmColor
template <typename ColorBase, typename Color>
struct color_element_const_reference_type : public kth_semantic_element_const_reference_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
/// \brief Mutable accessor to the element associated with a given color name
/// \ingroup ColorBaseAlgorithmColor
template <typename ColorBase, typename Color>
typename color_element_reference_type<ColorBase,Color>::type get_color(ColorBase& cb, Color=Color()) {
return color_element_reference_type<ColorBase,Color>::get(cb);
}
/// \brief Constant accessor to the element associated with a given color name
/// \ingroup ColorBaseAlgorithmColor
template <typename ColorBase, typename Color>
typename color_element_const_reference_type<ColorBase,Color>::type get_color(const ColorBase& cb, Color=Color()) {
return color_element_const_reference_type<ColorBase,Color>::get(cb);
}
///////////////////////////////////////
///
/// element_type, element_reference_type, element_const_reference_type: Support for homogeneous color bases
///
///////////////////////////////////////
/**
\defgroup ColorBaseAlgorithmHomogeneous element_type, element_reference_type, element_const_reference_type
\ingroup ColorBaseAlgorithm
\brief Types for homogeneous color bases
Example:
\code
typedef element_type<rgb8c_planar_ptr_t>::type element_t;
BOOST_STATIC_ASSERT((boost::is_same<element_t, const bits8*>::value));
\endcode
*/
/// \brief Specifies the element type of a homogeneous color base
/// \ingroup ColorBaseAlgorithmHomogeneous
template <typename ColorBase>
struct element_type : public kth_element_type<ColorBase, 0> {};
/// \brief Specifies the return type of the mutable element accessor at_c of a homogeneous color base
/// \ingroup ColorBaseAlgorithmHomogeneous
template <typename ColorBase>
struct element_reference_type : public kth_element_reference_type<ColorBase, 0> {};
/// \brief Specifies the return type of the constant element accessor at_c of a homogeneous color base
/// \ingroup ColorBaseAlgorithmHomogeneous
template <typename ColorBase>
struct element_const_reference_type : public kth_element_const_reference_type<ColorBase, 0> {};
namespace detail {
// compile-time recursion for per-element operations on color bases
template <int N>
struct element_recursion {
//static_equal
template <typename P1,typename P2>
static bool static_equal(const P1& p1, const P2& p2) {
return element_recursion<N-1>::static_equal(p1,p2) &&
semantic_at_c<N-1>(p1)==semantic_at_c<N-1>(p2);
}
//static_copy
template <typename P1,typename P2>
static void static_copy(const P1& p1, P2& p2) {
element_recursion<N-1>::static_copy(p1,p2);
semantic_at_c<N-1>(p2)=semantic_at_c<N-1>(p1);
}
//static_fill
template <typename P,typename T2>
static void static_fill(P& p, T2 v) {
element_recursion<N-1>::static_fill(p,v);
semantic_at_c<N-1>(p)=v;
}
//static_generate
template <typename Dst,typename Op>
static void static_generate(Dst& dst, Op op) {
element_recursion<N-1>::static_generate(dst,op);
semantic_at_c<N-1>(dst)=op();
}
//static_for_each with one source
template <typename P1,typename Op>
static Op static_for_each(P1& p1, Op op) {
Op op2(element_recursion<N-1>::static_for_each(p1,op));
op2(semantic_at_c<N-1>(p1));
return op2;
}
template <typename P1,typename Op>
static Op static_for_each(const P1& p1, Op op) {
Op op2(element_recursion<N-1>::static_for_each(p1,op));
op2(semantic_at_c<N-1>(p1));
return op2;
}
//static_for_each with two sources
template <typename P1,typename P2,typename Op>
static Op static_for_each(P1& p1, P2& p2, Op op) {
Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
return op2;
}
template <typename P1,typename P2,typename Op>
static Op static_for_each(P1& p1, const P2& p2, Op op) {
Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
return op2;
}
template <typename P1,typename P2,typename Op>
static Op static_for_each(const P1& p1, P2& p2, Op op) {
Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
return op2;
}
template <typename P1,typename P2,typename Op>
static Op static_for_each(const P1& p1, const P2& p2, Op op) {
Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
return op2;
}
//static_for_each with three sources
template <typename P1,typename P2,typename P3,typename Op>
static Op static_for_each(P1& p1, P2& p2, P3& p3, Op op) {
Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
return op2;
}
template <typename P1,typename P2,typename P3,typename Op>
static Op static_for_each(P1& p1, P2& p2, const P3& p3, Op op) {
Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
return op2;
}
template <typename P1,typename P2,typename P3,typename Op>
static Op static_for_each(P1& p1, const P2& p2, P3& p3, Op op) {
Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
return op2;
}
template <typename P1,typename P2,typename P3,typename Op>
static Op static_for_each(P1& p1, const P2& p2, const P3& p3, Op op) {
Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
return op2;
}
template <typename P1,typename P2,typename P3,typename Op>
static Op static_for_each(const P1& p1, P2& p2, P3& p3, Op op) {
Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
return op2;
}
template <typename P1,typename P2,typename P3,typename Op>
static Op static_for_each(const P1& p1, P2& p2, const P3& p3, Op op) {
Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
return op2;
}
template <typename P1,typename P2,typename P3,typename Op>
static Op static_for_each(const P1& p1, const P2& p2, P3& p3, Op op) {
Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
return op2;
}
template <typename P1,typename P2,typename P3,typename Op>
static Op static_for_each(const P1& p1, const P2& p2, const P3& p3, Op op) {
Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
return op2;
}
//static_transform with one source
template <typename P1,typename Dst,typename Op>
static Op static_transform(P1& src, Dst& dst, Op op) {
Op op2(element_recursion<N-1>::static_transform(src,dst,op));
semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src));
return op2;
}
template <typename P1,typename Dst,typename Op>
static Op static_transform(const P1& src, Dst& dst, Op op) {
Op op2(element_recursion<N-1>::static_transform(src,dst,op));
semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src));
return op2;
}
//static_transform with two sources
template <typename P1,typename P2,typename Dst,typename Op>
static Op static_transform(P1& src1, P2& src2, Dst& dst, Op op) {
Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
return op2;
}
template <typename P1,typename P2,typename Dst,typename Op>
static Op static_transform(P1& src1, const P2& src2, Dst& dst, Op op) {
Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
return op2;
}
template <typename P1,typename P2,typename Dst,typename Op>
static Op static_transform(const P1& src1, P2& src2, Dst& dst, Op op) {
Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
return op2;
}
template <typename P1,typename P2,typename Dst,typename Op>
static Op static_transform(const P1& src1, const P2& src2, Dst& dst, Op op) {
Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
return op2;
}
};
// Termination condition of the compile-time recursion for element operations on a color base
template<> struct element_recursion<0> {
//static_equal
template <typename P1,typename P2>
static bool static_equal(const P1&, const P2&) { return true; }
//static_copy
template <typename P1,typename P2>
static void static_copy(const P1&, const P2&) {}
//static_fill
template <typename P, typename T2>
static void static_fill(const P&, T2) {}
//static_generate
template <typename Dst,typename Op>
static void static_generate(const Dst&,Op){}
//static_for_each with one source
template <typename P1,typename Op>
static Op static_for_each(const P1&,Op op){return op;}
//static_for_each with two sources
template <typename P1,typename P2,typename Op>
static Op static_for_each(const P1&,const P2&,Op op){return op;}
//static_for_each with three sources
template <typename P1,typename P2,typename P3,typename Op>
static Op static_for_each(const P1&,const P2&,const P3&,Op op){return op;}
//static_transform with one source
template <typename P1,typename Dst,typename Op>
static Op static_transform(const P1&,const Dst&,Op op){return op;}
//static_transform with two sources
template <typename P1,typename P2,typename Dst,typename Op>
static Op static_transform(const P1&,const P2&,const Dst&,Op op){return op;}
};
// std::min and std::max don't have the mutable overloads...
template <typename Q> inline const Q& mutable_min(const Q& x, const Q& y) { return x<y ? x : y; }
template <typename Q> inline Q& mutable_min( Q& x, Q& y) { return x<y ? x : y; }
template <typename Q> inline const Q& mutable_max(const Q& x, const Q& y) { return x<y ? y : x; }
template <typename Q> inline Q& mutable_max( Q& x, Q& y) { return x<y ? y : x; }
// compile-time recursion for min/max element
template <int N>
struct min_max_recur {
template <typename P> static typename element_const_reference_type<P>::type max_(const P& p) {
return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
}
template <typename P> static typename element_reference_type<P>::type max_( P& p) {
return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
}
template <typename P> static typename element_const_reference_type<P>::type min_(const P& p) {
return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
}
template <typename P> static typename element_reference_type<P>::type min_( P& p) {
return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
}
};
// termination condition of the compile-time recursion for min/max element
template <>
struct min_max_recur<1> {
template <typename P> static typename element_const_reference_type<P>::type max_(const P& p) { return semantic_at_c<0>(p); }
template <typename P> static typename element_reference_type<P>::type max_( P& p) { return semantic_at_c<0>(p); }
template <typename P> static typename element_const_reference_type<P>::type min_(const P& p) { return semantic_at_c<0>(p); }
template <typename P> static typename element_reference_type<P>::type min_( P& p) { return semantic_at_c<0>(p); }
};
} // namespace detail
/**
\defgroup ColorBaseAlgorithmMinMax static_min, static_max
\ingroup ColorBaseAlgorithm
\brief Equivalents to std::min_element and std::max_element for homogeneous color bases
Example:
\code
rgb8_pixel_t pixel(10,20,30);
assert(pixel[2] == 30);
static_max(pixel) = static_min(pixel);
assert(pixel[2] == 10);
\endcode
\{
*/
template <typename P>
GIL_FORCEINLINE
typename element_const_reference_type<P>::type static_max(const P& p) { return detail::min_max_recur<size<P>::value>::max_(p); }
template <typename P>
GIL_FORCEINLINE
typename element_reference_type<P>::type static_max( P& p) { return detail::min_max_recur<size<P>::value>::max_(p); }
template <typename P>
GIL_FORCEINLINE
typename element_const_reference_type<P>::type static_min(const P& p) { return detail::min_max_recur<size<P>::value>::min_(p); }
template <typename P>
GIL_FORCEINLINE
typename element_reference_type<P>::type static_min( P& p) { return detail::min_max_recur<size<P>::value>::min_(p); }
/// \}
/**
\defgroup ColorBaseAlgorithmEqual static_equal
\ingroup ColorBaseAlgorithm
\brief Equivalent to std::equal. Pairs the elements semantically
Example:
\code
rgb8_pixel_t rgb_red(255,0,0);
bgr8_pixel_t bgr_red(0,0,255);
assert(rgb_red[0]==255 && bgr_red[0]==0);
assert(static_equal(rgb_red,bgr_red));
assert(rgb_red==bgr_red); // operator== invokes static_equal
\endcode
\{
*/
template <typename P1,typename P2>
GIL_FORCEINLINE
bool static_equal(const P1& p1, const P2& p2) { return detail::element_recursion<size<P1>::value>::static_equal(p1,p2); }
/// \}
/**
\defgroup ColorBaseAlgorithmCopy static_copy
\ingroup ColorBaseAlgorithm
\brief Equivalent to std::copy. Pairs the elements semantically
Example:
\code
rgb8_pixel_t rgb_red(255,0,0);
bgr8_pixel_t bgr_red;
static_copy(rgb_red, bgr_red); // same as bgr_red = rgb_red
assert(rgb_red[0] == 255 && bgr_red[0] == 0);
assert(rgb_red == bgr_red);
\endcode
\{
*/
template <typename Src,typename Dst>
GIL_FORCEINLINE
void static_copy(const Src& src, Dst& dst) { detail::element_recursion<size<Dst>::value>::static_copy(src,dst); }
/// \}
/**
\defgroup ColorBaseAlgorithmFill static_fill
\ingroup ColorBaseAlgorithm
\brief Equivalent to std::fill.
Example:
\code
rgb8_pixel_t p;
static_fill(p, 10);
assert(p == rgb8_pixel_t(10,10,10));
\endcode
\{
*/
template <typename P,typename V>
GIL_FORCEINLINE
void static_fill(P& p, const V& v) { detail::element_recursion<size<P>::value>::static_fill(p,v); }
/// \}
/**
\defgroup ColorBaseAlgorithmGenerate static_generate
\ingroup ColorBaseAlgorithm
\brief Equivalent to std::generate.
Example: Set each channel of a pixel to its semantic index. The channels must be assignable from an integer.
\code
struct consecutive_fn {
int& _current;
consecutive_fn(int& start) : _current(start) {}
int operator()() { return _current++; }
};
rgb8_pixel_t p;
int start=0;
static_generate(p, consecutive_fn(start));
assert(p == rgb8_pixel_t(0,1,2));
\endcode
\{
*/
template <typename P1,typename Op>
GIL_FORCEINLINE
void static_generate(P1& dst,Op op) { detail::element_recursion<size<P1>::value>::static_generate(dst,op); }
/// \}
/**
\defgroup ColorBaseAlgorithmTransform static_transform
\ingroup ColorBaseAlgorithm
\brief Equivalent to std::transform. Pairs the elements semantically
Example: Write a generic function that adds two pixels into a homogeneous result pixel.
\code
template <typename Result>
struct my_plus {
template <typename T1, typename T2>
Result operator()(T1 f1, T2 f2) const { return f1+f2; }
};
template <typename Pixel1, typename Pixel2, typename Pixel3>
void sum_channels(const Pixel1& p1, const Pixel2& p2, Pixel3& result) {
typedef typename channel_type<Pixel3>::type result_channel_t;
static_transform(p1,p2,result,my_plus<result_channel_t>());
}
rgb8_pixel_t p1(1,2,3);
bgr8_pixel_t p2(3,2,1);
rgb8_pixel_t result;
sum_channels(p1,p2,result);
assert(result == rgb8_pixel_t(2,4,6));
\endcode
\{
*/
//static_transform with one source
template <typename Src,typename Dst,typename Op>
GIL_FORCEINLINE
Op static_transform(Src& src,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
template <typename Src,typename Dst,typename Op>
GIL_FORCEINLINE
Op static_transform(const Src& src,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
//static_transform with two sources
template <typename P2,typename P3,typename Dst,typename Op>
GIL_FORCEINLINE
Op static_transform(P2& p2,P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
template <typename P2,typename P3,typename Dst,typename Op>
GIL_FORCEINLINE
Op static_transform(P2& p2,const P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
template <typename P2,typename P3,typename Dst,typename Op>
GIL_FORCEINLINE
Op static_transform(const P2& p2,P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
template <typename P2,typename P3,typename Dst,typename Op>
GIL_FORCEINLINE
Op static_transform(const P2& p2,const P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
/// \}
/**
\defgroup ColorBaseAlgorithmForEach static_for_each
\ingroup ColorBaseAlgorithm
\brief Equivalent to std::for_each. Pairs the elements semantically
Example: Use static_for_each to increment a planar pixel iterator
\code
struct increment {
template <typename Incrementable>
void operator()(Incrementable& x) const { ++x; }
};
template <typename ColorBase>
void increment_elements(ColorBase& cb) {
static_for_each(cb, increment());
}
bits8 red[2], green[2], blue[2];
rgb8c_planar_ptr_t p1(red,green,blue);
rgb8c_planar_ptr_t p2=p1;
increment_elements(p1);
++p2;
assert(p1 == p2);
\endcode
\{
*/
//static_for_each with one source
template <typename P1,typename Op>
GIL_FORCEINLINE
Op static_for_each( P1& p1, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
template <typename P1,typename Op>
GIL_FORCEINLINE
Op static_for_each(const P1& p1, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
//static_for_each with two sources
template <typename P1,typename P2,typename Op>
GIL_FORCEINLINE
Op static_for_each(P1& p1, P2& p2, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
template <typename P1,typename P2,typename Op>
GIL_FORCEINLINE
Op static_for_each(P1& p1,const P2& p2, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
template <typename P1,typename P2,typename Op>
GIL_FORCEINLINE
Op static_for_each(const P1& p1, P2& p2, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
template <typename P1,typename P2,typename Op>
GIL_FORCEINLINE
Op static_for_each(const P1& p1,const P2& p2, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
//static_for_each with three sources
template <typename P1,typename P2,typename P3,typename Op>
GIL_FORCEINLINE
Op static_for_each(P1& p1,P2& p2,P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
template <typename P1,typename P2,typename P3,typename Op>
GIL_FORCEINLINE
Op static_for_each(P1& p1,P2& p2,const P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
template <typename P1,typename P2,typename P3,typename Op>
GIL_FORCEINLINE
Op static_for_each(P1& p1,const P2& p2,P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
template <typename P1,typename P2,typename P3,typename Op>
GIL_FORCEINLINE
Op static_for_each(P1& p1,const P2& p2,const P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
template <typename P1,typename P2,typename P3,typename Op>
GIL_FORCEINLINE
Op static_for_each(const P1& p1,P2& p2,P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
template <typename P1,typename P2,typename P3,typename Op>
GIL_FORCEINLINE
Op static_for_each(const P1& p1,P2& p2,const P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
template <typename P1,typename P2,typename P3,typename Op>
GIL_FORCEINLINE
Op static_for_each(const P1& p1,const P2& p2,P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
template <typename P1,typename P2,typename P3,typename Op>
GIL_FORCEINLINE
Op static_for_each(const P1& p1,const P2& p2,const P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
///\}
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,314 @@
/*
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;
get_color(dst,red_t()) =
channel_convert<typename color_element_type<P2,red_t>::type>(
channel_invert<T1>(
(std::min)(channel_traits<T1>::max_value(),
T1(get_color(src,cyan_t())*channel_invert(get_color(src,black_t()))+get_color(src,black_t())))));
get_color(dst,green_t())=
channel_convert<typename color_element_type<P2,green_t>::type>(
channel_invert<T1>(
(std::min)(channel_traits<T1>::max_value(),
T1(get_color(src,magenta_t())*channel_invert(get_color(src,black_t()))+get_color(src,black_t())))));
get_color(dst,blue_t()) =
channel_convert<typename color_element_type<P2,blue_t>::type>(
channel_invert<T1>(
(std::min)(channel_traits<T1>::max_value(),
T1(get_color(src,yellow_t())*channel_invert(get_color(src,black_t()))+get_color(src,black_t())))));
}
};
/// \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

View File

@ -0,0 +1,77 @@
/*
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_DEPRECATED_HPP
#define GIL_DEPRECATED_HPP
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Deprecated names
/// This file is provided as a courtesy to ease upgrading GIL client code.
/// Please make sure your code compiles when this file is not included.
///
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on February 12, 2007
///
////////////////////////////////////////////////////////////////////////////////////////
#define planar_ptr planar_pixel_iterator
#define planar_ref planar_pixel_reference
#define membased_2d_locator memory_based_2d_locator
#define pixel_step_iterator memory_based_step_iterator
#define pixel_image_iterator iterator_from_2d
#define equal_channels static_equal
#define copy_channels static_copy
#define fill_channels static_fill
#define generate_channels static_generate
#define for_each_channel static_for_each
#define transform_channels static_transform
#define max_channel static_max
#define min_channel static_min
#define semantic_channel semantic_at_c
template <typename Img>
void resize_clobber_image(Img& img, const typename Img::point_t& new_dims) {
img.recreate(new_dims);
}
template <typename Img>
void resize_clobber_image(Img& img, const typename Img::x_coord_t& width, const typename Img::y_coord_t& height) {
img.recreate(width,height);
}
template <typename T> typename T::x_coord_t get_width(const T& a) { return a.width(); }
template <typename T> typename T::y_coord_t get_height(const T& a) { return a.height(); }
template <typename T> typename T::point_t get_dimensions(const T& a) { return a.dimensions(); }
template <typename T> std::size_t get_num_channels(const T& a) { return a.num_channels(); }
#define GIL boost::gil
#define ADOBE_GIL_NAMESPACE_BEGIN namespace boost { namespace gil {
#define ADOBE_GIL_NAMESPACE_END } }
#define ByteAdvancableIteratorConcept MemoryBasedIteratorConcept
#define byte_advance memunit_advance
#define byte_advanced memunit_advanced
#define byte_step memunit_step
#define byte_distance memunit_distance
#define byte_addressable_step_iterator memory_based_step_iterator
#define byte_addressable_2d_locator memory_based_2d_locator
// These are members of memory-based locators
//#define row_bytes row_size // commented out because row_bytes is commonly used
#define pix_bytestep pixel_size
#endif

View File

@ -0,0 +1,100 @@
/*
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://stlab.adobe.com/gil for most recent version including documentation.
*/
/*************************************************************************************************/
#ifndef GIL_DEVICE_N_H
#define GIL_DEVICE_N_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Support for color space of N channels and variants
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on October 10, 2007
////////////////////////////////////////////////////////////////////////////////////////
#include <cstddef>
#include "gil_config.hpp"
#include <boost/type_traits.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/vector_c.hpp>
namespace boost { namespace gil {
/// \brief unnamed color
/// \ingroup ColorNameModel
template <int N> struct devicen_color_t {};
template <int N> struct devicen_t;
/// \brief unnamed color space of one channel
/// \ingroup ColorSpaceModel
template <> struct devicen_t<1> : public mpl::vector1<devicen_color_t<0> > {};
/// \brief unnamed color space of two channels
/// \ingroup ColorSpaceModel
template <> struct devicen_t<2> : public mpl::vector2<devicen_color_t<0>, devicen_color_t<1> > {};
/// \brief unnamed color space of three channels
/// \ingroup ColorSpaceModel
template <> struct devicen_t<3> : public mpl::vector3<devicen_color_t<0>, devicen_color_t<1>, devicen_color_t<2> > {};
/// \brief unnamed color space of four channels
/// \ingroup ColorSpaceModel
template <> struct devicen_t<4> : public mpl::vector4<devicen_color_t<0>, devicen_color_t<1>, devicen_color_t<2>, devicen_color_t<3> > {};
/// \brief unnamed color space of five channels
/// \ingroup ColorSpaceModel
template <> struct devicen_t<5> : public mpl::vector5<devicen_color_t<0>, devicen_color_t<1>, devicen_color_t<2>, devicen_color_t<3>, devicen_color_t<4> > {};
/// \brief unnamed color layout of up to five channels
/// \ingroup LayoutModel
template <int N> struct devicen_layout_t : public layout<devicen_t<N> > {};
/// \ingroup ImageViewConstructors
/// \brief from 2-channel planar data
template <typename IC>
inline typename type_from_x_iterator<planar_pixel_iterator<IC,devicen_t<2> > >::view_t
planar_devicen_view(std::size_t width, std::size_t height, IC c0, IC c1, std::ptrdiff_t rowsize_in_bytes) {
typedef typename type_from_x_iterator<planar_pixel_iterator<IC,devicen_t<2> > >::view_t view_t;
return view_t(width, height, typename view_t::locator(typename view_t::x_iterator(c0,c1), rowsize_in_bytes));
}
/// \ingroup ImageViewConstructors
/// \brief from 3-channel planar data
template <typename IC>
inline typename type_from_x_iterator<planar_pixel_iterator<IC,devicen_t<3> > >::view_t
planar_devicen_view(std::size_t width, std::size_t height, IC c0, IC c1, IC c2, std::ptrdiff_t rowsize_in_bytes) {
typedef typename type_from_x_iterator<planar_pixel_iterator<IC,devicen_t<3> > >::view_t view_t;
return view_t(width, height, typename view_t::locator(typename view_t::x_iterator(c0,c1,c2), rowsize_in_bytes));
}
/// \ingroup ImageViewConstructors
/// \brief from 4-channel planar data
template <typename IC>
inline typename type_from_x_iterator<planar_pixel_iterator<IC,devicen_t<4> > >::view_t
planar_devicen_view(std::size_t width, std::size_t height, IC c0, IC c1, IC c2, IC c3, std::ptrdiff_t rowsize_in_bytes) {
typedef typename type_from_x_iterator<planar_pixel_iterator<IC,devicen_t<4> > >::view_t view_t;
return view_t(width, height, typename view_t::locator(typename view_t::x_iterator(c0,c1,c2,c3), rowsize_in_bytes));
}
/// \ingroup ImageViewConstructors
/// \brief from 5-channel planar data
template <typename IC>
inline typename type_from_x_iterator<planar_pixel_iterator<IC,devicen_t<5> > >::view_t
planar_devicen_view(std::size_t width, std::size_t height, IC c0, IC c1, IC c2, IC c3, IC c4, std::ptrdiff_t rowsize_in_bytes) {
typedef typename type_from_x_iterator<planar_pixel_iterator<IC,devicen_t<5> > >::view_t view_t;
return view_t(width, height, typename view_t::locator(typename view_t::x_iterator(c0,c1,c2,c3,c4), rowsize_in_bytes));
}
} } // namespace boost::gil
#endif

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,162 @@
/*
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_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; \
} \
};
#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;
mutable 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;
mutable 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,212 @@
/*
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> struct color_converted_view_fn {
typedef Result result_type;
template <typename View> result_type operator()(const View& src) const { return result_type(color_converted_view<DstP>(src)); }
};
} // 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,194 @@
/*
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; }
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

View File

@ -0,0 +1,79 @@
/*
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_IO_H
#define GIL_DYNAMIC_IO_H
/// \file
/// \brief Generic io functions for dealing with dynamic images
//
/// \author Hailin Jin and Lubomir Bourdev \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated May 30, 2006
#include <boost/mpl/at.hpp>
#include <boost/mpl/size.hpp>
#include "../../gil_config.hpp"
#include "../dynamic_image/any_image.hpp"
namespace boost { namespace gil {
namespace detail {
template <long N>
struct construct_matched_t {
template <typename Images,typename Pred>
static bool apply(any_image<Images>& im,Pred pred) {
if (pred.template apply<typename mpl::at_c<Images,N-1>::type>()) {
typename mpl::at_c<Images,N-1>::type x;
im.move_in(x);
return true;
} else return construct_matched_t<N-1>::apply(im,pred);
}
};
template <>
struct construct_matched_t<0> {
template <typename Images,typename Pred>
static bool apply(any_image<Images>&,Pred) {return false;}
};
// A function object that can be passed to apply_operation.
// Given a predicate IsSupported taking a view type and returning an MPL boolean,
// calls the apply method of OpClass with the view if the given view IsSupported, or throws an exception otherwise
template <typename IsSupported, typename OpClass>
class dynamic_io_fnobj {
OpClass* _op;
template <typename View>
void apply(const View& view,mpl::true_ ) {_op->apply(view);}
template <typename View>
void apply(const View& view,mpl::false_) {io_error("dynamic_io: unsupported view type for the given file format");}
public:
dynamic_io_fnobj(OpClass* op) : _op(op) {}
typedef void result_type;
template <typename View>
void operator()(const View& view) {apply(view,typename IsSupported::template apply<View>::type());}
};
} // namespace detail
/// \brief Within the any_image, constructs an image with the given dimensions
/// and a type that satisfies the given predicate
template <typename Images,typename Pred>
inline bool construct_matched(any_image<Images>& im,Pred pred) {
return detail::construct_matched_t<mpl::size<Images>::value>::apply(im,pred);
}
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,51 @@
/*
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_IO_ERROR_H
#define GIL_IO_ERROR_H
/// \file
/// \brief Handle input-output errors
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on May 30, 2006
#include <ios>
#include "../../gil_config.hpp"
#include <boost/shared_ptr.hpp>
namespace boost { namespace gil {
inline void io_error(const char* descr) { throw std::ios_base::failure(descr); }
inline void io_error_if(bool expr, const char* descr="") { if (expr) io_error(descr); }
namespace detail {
class file_mgr {
protected:
shared_ptr<FILE> _fp;
struct null_deleter { void operator()(void const*) const {} };
file_mgr(FILE* file) : _fp(file, null_deleter()) {}
file_mgr(const char* filename, const char* flags) {
FILE* fp;
io_error_if((fp=fopen(filename,flags))==NULL, "file_mgr: failed to open file");
_fp=shared_ptr<FILE>(fp,fclose);
}
public:
FILE* get() { return _fp.get(); }
};
}
} } // 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_JPEG_DYNAMIC_IO_H
#define GIL_JPEG_DYNAMIC_IO_H
/// \file
/// \brief Support for reading and writing JPEG files
/// Requires libjpeg
///
/// \author Hailin Jin and Lubomir Bourdev \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated June 10, 2006
#include <stdio.h>
#include <string>
#include <boost/mpl/bool.hpp>
#include <boost/shared_ptr.hpp>
#include "../dynamic_image/dynamic_image_all.hpp"
#include "io_error.hpp"
#include "jpeg_io.hpp"
#include "jpeg_io_private.hpp"
#include "dynamic_io.hpp"
namespace boost { namespace gil {
namespace detail {
struct jpeg_write_is_supported {
template<typename View> struct apply
: public mpl::bool_<jpeg_write_support<View>::is_supported> {};
};
class jpeg_writer_dynamic : public jpeg_writer {
int _quality;
public:
jpeg_writer_dynamic(FILE* file, int quality=100) : jpeg_writer(file) , _quality(quality) {}
jpeg_writer_dynamic(const char* filename, int quality=100) : jpeg_writer(filename), _quality(quality) {}
template <typename Views>
void write_view(const any_image_view<Views>& runtime_view) {
dynamic_io_fnobj<jpeg_write_is_supported, jpeg_writer> op(this);
apply_operation(runtime_view,op);
}
};
class jpeg_type_format_checker {
J_COLOR_SPACE _color_type;
public:
jpeg_type_format_checker(J_COLOR_SPACE color_type_in) :
_color_type(color_type_in) {}
template <typename Image>
bool apply() {
return jpeg_read_support<typename Image::view_t>::color_type==_color_type;
}
};
struct jpeg_read_is_supported {
template<typename View> struct apply
: public mpl::bool_<jpeg_read_support<View>::is_supported> {};
};
class jpeg_reader_dynamic : public jpeg_reader {
public:
jpeg_reader_dynamic(FILE* file) : jpeg_reader(file) {}
jpeg_reader_dynamic(const char* filename) : jpeg_reader(filename){}
template <typename Images>
void read_image(any_image<Images>& im) {
if (!construct_matched(im,detail::jpeg_type_format_checker(_cinfo.out_color_space))) {
io_error("jpeg_reader_dynamic::read_image(): no matching image type between those of the given any_image and that of the file");
} else {
im.recreate(get_dimensions());
dynamic_io_fnobj<jpeg_read_is_supported, jpeg_reader> op(this);
apply_operation(view(im),op);
}
}
};
} // namespace detail
/// \ingroup JPEG_IO
/// \brief reads a JPEG image into a run-time instantiated image
/// Opens the given JPEG file name, selects the first type in Images whose color space and channel are compatible to those of the image file
/// and creates a new image of that type with the dimensions specified by the image file.
/// Throws std::ios_base::failure if none of the types in Images are compatible with the type on disk.
template <typename Images>
inline void jpeg_read_image(const char* filename,any_image<Images>& im) {
detail::jpeg_reader_dynamic m(filename);
m.read_image(im);
}
/// \ingroup JPEG_IO
/// \brief reads a JPEG image into a run-time instantiated image
template <typename Images>
inline void jpeg_read_image(const std::string& filename,any_image<Images>& im) {
jpeg_read_image(filename.c_str(),im);
}
/// \ingroup JPEG_IO
/// \brief Saves the currently instantiated view to a jpeg file specified by the given jpeg image file name.
/// Throws std::ios_base::failure if the currently instantiated view type is not supported for writing by the I/O extension
/// or if it fails to create the file.
template <typename Views>
inline void jpeg_write_view(const char* filename,const any_image_view<Views>& runtime_view) {
detail::jpeg_writer_dynamic m(filename);
m.write_view(runtime_view);
}
/// \ingroup JPEG_IO
/// \brief Saves the currently instantiated view to a jpeg file specified by the given jpeg image file name.
template <typename Views>
inline void jpeg_write_view(const std::string& filename,const any_image_view<Views>& runtime_view) {
jpeg_write_view(filename.c_str(),runtime_view);
}
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,202 @@
/*
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_JPEG_IO_H
#define GIL_JPEG_IO_H
/// \file
/// \brief Support for reading and writing JPEG files
/// Requires libjpeg
/// \author Hailin Jin and Lubomir Bourdev \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated September 24, 2006
#include <cstdio>
#include <algorithm>
#include <string>
#include <boost/static_assert.hpp>
#include <boost/shared_ptr.hpp>
extern "C" {
#include <jpeglib.h>
}
#include "io_error.hpp"
#include "jpeg_io_private.hpp"
namespace boost { namespace gil {
/// \ingroup JPEG_IO
/// \brief Determines whether the given view type is supported for reading
template <typename View>
struct jpeg_read_support {
BOOST_STATIC_CONSTANT(bool,is_supported=
(detail::jpeg_read_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::is_supported));
BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=
(detail::jpeg_read_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::color_type));
BOOST_STATIC_CONSTANT(bool, value=is_supported);
};
/// \ingroup JPEG_IO
/// \brief Returns the width and height of the JPEG file at the specified location.
/// Throws std::ios_base::failure if the location does not correspond to a valid JPEG file
inline point2<std::ptrdiff_t> jpeg_read_dimensions(const char* filename) {
detail::jpeg_reader m(filename);
return m.get_dimensions();
}
/// \ingroup JPEG_IO
/// \brief Returns the width and height of the JPEG file at the specified location.
/// Throws std::ios_base::failure if the location does not correspond to a valid JPEG file
inline point2<std::ptrdiff_t> jpeg_read_dimensions(const std::string& filename) {
return jpeg_read_dimensions(filename.c_str());
}
/// \ingroup JPEG_IO
/// \brief Loads the image specified by the given jpeg image file name into the given view.
/// Triggers a compile assert if the view color space and channel depth are not supported by the JPEG library or by the I/O extension.
/// Throws std::ios_base::failure if the file is not a valid JPEG file, or if its color space or channel depth are not
/// compatible with the ones specified by View, or if its dimensions don't match the ones of the view.
template <typename View>
inline void jpeg_read_view(const char* filename,const View& view) {
BOOST_STATIC_ASSERT(jpeg_read_support<View>::is_supported);
detail::jpeg_reader m(filename);
m.apply(view);
}
/// \ingroup JPEG_IO
/// \brief Loads the image specified by the given jpeg image file name into the given view.
template <typename View>
inline void jpeg_read_view(const std::string& filename,const View& view) {
jpeg_read_view(filename.c_str(),view);
}
/// \ingroup JPEG_IO
/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, and loads the pixels into it.
/// Triggers a compile assert if the image color space or channel depth are not supported by the JPEG library or by the I/O extension.
/// Throws std::ios_base::failure if the file is not a valid JPEG file, or if its color space or channel depth are not
/// compatible with the ones specified by Image
template <typename Image>
inline void jpeg_read_image(const char* filename,Image& im) {
BOOST_STATIC_ASSERT(jpeg_read_support<typename Image::view_t>::is_supported);
detail::jpeg_reader m(filename);
m.read_image(im);
}
/// \ingroup JPEG_IO
/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, and loads the pixels into it.
template <typename Image>
inline void jpeg_read_image(const std::string& filename,Image& im) {
jpeg_read_image(filename.c_str(),im);
}
/// \ingroup JPEG_IO
/// \brief Loads and color-converts the image specified by the given jpeg image file name into the given view.
/// Throws std::ios_base::failure if the file is not a valid JPEG file, or if its dimensions don't match the ones of the view.
template <typename View,typename CC>
inline void jpeg_read_and_convert_view(const char* filename,const View& view,CC cc) {
detail::jpeg_reader_color_convert<CC> m(filename,cc);
m.apply(view);
}
/// \ingroup JPEG_IO
/// \brief Loads and color-converts the image specified by the given jpeg image file name into the given view.
/// Throws std::ios_base::failure if the file is not a valid JPEG file, or if its dimensions don't match the ones of the view.
template <typename View>
inline void jpeg_read_and_convert_view(const char* filename,const View& view) {
detail::jpeg_reader_color_convert<default_color_converter> m(filename,default_color_converter());
m.apply(view);
}
/// \ingroup JPEG_IO
/// \brief Loads and color-converts the image specified by the given jpeg image file name into the given view.
template <typename View,typename CC>
inline void jpeg_read_and_convert_view(const std::string& filename,const View& view,CC cc) {
jpeg_read_and_convert_view(filename.c_str(),view);
}
/// \ingroup JPEG_IO
/// \brief Loads and color-converts the image specified by the given jpeg image file name into the given view.
template <typename View>
inline void jpeg_read_and_convert_view(const std::string& filename,const View& view) {
jpeg_read_and_convert_view(filename.c_str(),view);
}
/// \ingroup JPEG_IO
/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, loads and color-converts the pixels into it.
/// Throws std::ios_base::failure if the file is not a valid JPEG file
template <typename Image,typename CC>
inline void jpeg_read_and_convert_image(const char* filename,Image& im,CC cc) {
detail::jpeg_reader_color_convert<CC> m(filename,cc);
m.read_image(im);
}
/// \ingroup JPEG_IO
/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, loads and color-converts the pixels into it.
/// Throws std::ios_base::failure if the file is not a valid JPEG file
template <typename Image>
inline void jpeg_read_and_convert_image(const char* filename,Image& im) {
detail::jpeg_reader_color_convert<default_color_converter> m(filename,default_color_converter());
m.read_image(im);
}
/// \ingroup JPEG_IO
/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, loads and color-converts the pixels into it.
template <typename Image,typename CC>
inline void jpeg_read_and_convert_image(const std::string& filename,Image& im,CC cc) {
jpeg_read_and_convert_image(filename.c_str(),im);
}
/// \ingroup JPEG_IO
/// \brief Allocates a new image whose dimensions are determined by the given jpeg image file, loads and color-converts the pixels into it.
template <typename Image>
inline void jpeg_read_and_convert_image(const std::string& filename,Image& im) {
jpeg_read_and_convert_image(filename.c_str(),im);
}
/// \ingroup JPEG_IO
/// \brief Determines whether the given view type is supported for writing
template <typename View>
struct jpeg_write_support {
BOOST_STATIC_CONSTANT(bool,is_supported=
(detail::jpeg_write_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::is_supported));
BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=
(detail::jpeg_write_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::color_type));
BOOST_STATIC_CONSTANT(bool, value=is_supported);
};
/// \ingroup JPEG_IO
/// \brief Saves the view to a jpeg file specified by the given jpeg image file name.
/// Triggers a compile assert if the view color space and channel depth are not supported by the JPEG library or by the I/O extension.
/// Throws std::ios_base::failure if it fails to create the file.
template <typename View>
inline void jpeg_write_view(const char* filename,const View& view,int quality=100) {
BOOST_STATIC_ASSERT(jpeg_write_support<View>::is_supported);
detail::jpeg_writer m(filename);
m.apply(view,quality);
}
/// \ingroup JPEG_IO
/// \brief Saves the view to a jpeg file specified by the given jpeg image file name.
template <typename View>
inline void jpeg_write_view(const std::string& filename,const View& view,int quality=100) {
jpeg_write_view(filename.c_str(),view,quality);
}
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,225 @@
/*
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_JPEG_IO_PRIVATE_H
#define GIL_JPEG_IO_PRIVATE_H
/// \file
/// \brief Internal support for reading and writing JPEG files
/// \author Hailin Jin and Lubomir Bourdev \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated September 24, 2006
#include <stdio.h>
#include <boost/static_assert.hpp>
#include <vector>
#include "../../gil_all.hpp"
#include "io_error.hpp"
namespace boost { namespace gil {
namespace detail {
// lbourdev: What is the advantage of having channel and colorspace together? Are there cases where they are interrelated?
template <typename Channel,typename ColorSpace>
struct jpeg_read_support_private {
BOOST_STATIC_CONSTANT(bool,is_supported=false);
BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_UNKNOWN);
};
template <>
struct jpeg_read_support_private<bits8,gray_t> {
BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_GRAYSCALE);
};
template <>
struct jpeg_read_support_private<bits8,rgb_t> {
BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_RGB);
};
template <>
struct jpeg_read_support_private<bits8,cmyk_t> {
BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_CMYK);
};
template <typename Channel,typename ColorSpace>
struct jpeg_write_support_private {
BOOST_STATIC_CONSTANT(bool,is_supported=false);
BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_UNKNOWN);
};
template <>
struct jpeg_write_support_private<bits8,gray_t> {
BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_GRAYSCALE);
};
template <>
struct jpeg_write_support_private<bits8,rgb_t> {
BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_RGB);
};
template <>
struct jpeg_write_support_private<bits8,cmyk_t> {
BOOST_STATIC_ASSERT(BITS_IN_JSAMPLE==8);
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(J_COLOR_SPACE,color_type=JCS_CMYK);
};
class jpeg_reader : public file_mgr {
protected:
jpeg_decompress_struct _cinfo;
jpeg_error_mgr _jerr;
void init() {
_cinfo.err=jpeg_std_error(&_jerr);
jpeg_create_decompress(&_cinfo);
jpeg_stdio_src(&_cinfo,_fp.get());
jpeg_read_header(&_cinfo,TRUE);
}
public:
jpeg_reader(FILE* file) : file_mgr(file) { init(); }
jpeg_reader(const char* filename) : file_mgr(filename, "rb") { init(); }
~jpeg_reader() { jpeg_destroy_decompress(&_cinfo); }
template <typename View>
void apply(const View& view) {
jpeg_start_decompress(&_cinfo); // lbourdev: Can this return an error? You need to check and throw. Check all other library methods that can return an error state...
io_error_if(_cinfo.data_precision!=8,"jpeg_reader::apply(): this image file is not supported");
io_error_if(_cinfo.out_color_space!=jpeg_read_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::color_type,
"jpeg_reader::apply(): input view type does not match the image file");
io_error_if(view.dimensions() != get_dimensions(), "jpeg_reader::apply(): input view dimensions do not match the image file");
std::vector<pixel<bits8,layout<typename color_space_type<View>::type> > > row(view.width());
JSAMPLE* row_address=(JSAMPLE*)&row.front();
for(int y=0;y<view.height();++y) {
io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
"jpeg_reader::apply(): fail to read JPEG file");
std::copy(row.begin(),row.end(),view.row_begin(y));
}
jpeg_finish_decompress(&_cinfo);
}
template <typename Image>
void read_image(Image& im) {
im.recreate(get_dimensions());
apply(view(im));
}
point2<std::ptrdiff_t> get_dimensions() const {
return point2<std::ptrdiff_t>(_cinfo.image_width,_cinfo.image_height);
}
};
// This code will be simplified...
template <typename CC>
class jpeg_reader_color_convert : public jpeg_reader {
private:
CC _cc;
public:
jpeg_reader_color_convert(FILE* file,CC cc_in) : jpeg_reader(file),_cc(cc_in) {}
jpeg_reader_color_convert(FILE* file) : jpeg_reader(file) {}
jpeg_reader_color_convert(const char* filename,CC cc_in) : jpeg_reader(filename),_cc(cc_in) {}
jpeg_reader_color_convert(const char* filename) : jpeg_reader(filename) {}
template <typename View>
void apply(const View& view) {
jpeg_start_decompress(&_cinfo); // lbourdev: Can this return an error? You need to check and throw. Check all other library methods that can return an error state...
io_error_if(_cinfo.data_precision!=8,"jpeg_reader_color_covert::apply(): this image file is not supported");
io_error_if(view.dimensions() != get_dimensions(), "jpeg_reader_color_covert::apply(): input view dimensions don't match the image file");
switch (_cinfo.out_color_space) {
case JCS_GRAYSCALE: {
std::vector<gray8_pixel_t> row(view.width());
JSAMPLE* row_address=(JSAMPLE*)&row.front();
for(int y=0;y<view.height();++y) {
io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
"jpeg_reader_color_covert::apply(): fail to read JPEG file");
std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<gray8_ref_t, typename View::value_type,CC>(_cc));
}
break;
}
case JCS_RGB: {
std::vector<rgb8_pixel_t> row(view.width());
JSAMPLE* row_address=(JSAMPLE*)&row.front();
for(int y=0;y<view.height();++y) {
io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
"jpeg_reader_color_covert::apply(): fail to read JPEG file");
std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgb8_ref_t, typename View::value_type,CC>(_cc));
}
break;
}
case JCS_CMYK: {
std::vector<cmyk8_pixel_t> row(view.width());
JSAMPLE* row_address=(JSAMPLE*)&row.front();
for(int y=0;y<view.height();++y) {
io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
"jpeg_reader_color_covert::apply(): fail to read JPEG file");
std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<cmyk8_ref_t, typename View::value_type,CC>(_cc));
}
break;
}
default:
io_error("jpeg_reader_color_covert::apply(): unknown color type");
}
jpeg_finish_decompress(&_cinfo);
}
template <typename Image>
void read_image(Image& im) {
im.recreate(get_dimensions());
apply(view(im));
}
};
class jpeg_writer : public file_mgr {
jpeg_compress_struct _cinfo;
jpeg_error_mgr _jerr;
void init() {
_cinfo.err=jpeg_std_error(&_jerr);
jpeg_create_compress(&_cinfo);
jpeg_stdio_dest(&_cinfo,_fp.get());
}
public:
jpeg_writer(FILE* file) : file_mgr(file) { init(); }
jpeg_writer(const char* filename) : file_mgr(filename, "wb") { init(); }
~jpeg_writer() { jpeg_destroy_compress(&_cinfo); }
template <typename View>
void apply(const View& view,int quality=100) {
_cinfo.image_width = (JDIMENSION)view.width();
_cinfo.image_height = (JDIMENSION)view.height();
_cinfo.input_components=num_channels<View>::value;
_cinfo.in_color_space = jpeg_write_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::color_type;
jpeg_set_defaults(&_cinfo);
jpeg_set_quality(&_cinfo, quality, TRUE);
jpeg_start_compress(&_cinfo, TRUE);
std::vector<pixel<bits8,layout<typename color_space_type<View>::type> > > row(view.width());
JSAMPLE* row_address=(JSAMPLE*)&row.front();
for (int y=0;y<view.height(); ++y) {
std::copy(view.row_begin(y),view.row_end(y),row.begin());
io_error_if(jpeg_write_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1) != 1,
"jpeg_writer::apply(): fail to write file");
}
jpeg_finish_compress(&_cinfo);
}
};
} // namespace detail
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,141 @@
/*
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_PNG_DYNAMIC_IO_H
#define GIL_PNG_DYNAMIC_IO_H
/// \file
/// \brief Support for reading and writing PNG files
/// Requires libpng and zlib!
///
/// \author Hailin Jin and Lubomir Bourdev \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated June 10, 2006
//
// We are currently providing the following functions:
// template <typename Images> void png_read_image(const char*,any_image<Images>&)
// template <typename Images> void png_read_image(FILE*,any_image<Images>&,std::size_t)
// template <typename Views> void png_write_view(const char*,const any_image_view<View>&)
// template <typename Views> void png_write_view(FILE*,const any_image_view<View>&)
#include <string>
#include <stdio.h>
#include <boost/mpl/bool.hpp>
#include <boost/shared_ptr.hpp>
#include "../dynamic_image/dynamic_image_all.hpp"
#include "io_error.hpp"
#include "png_io.hpp"
#include "png_io_private.hpp"
#include "dynamic_io.hpp"
namespace boost { namespace gil {
namespace detail {
struct png_write_is_supported {
template<typename View> struct apply
: public mpl::bool_<png_write_support<View>::is_supported> {};
};
class png_writer_dynamic : public png_writer {
public:
png_writer_dynamic(FILE* file ) : png_writer(file) {}
png_writer_dynamic(const char* filename) : png_writer(filename){}
template <typename Views>
void write_view(const any_image_view<Views>& runtime_view) {
dynamic_io_fnobj<png_write_is_supported, png_writer> op(this);
apply_operation(runtime_view,op);
}
};
class png_type_format_checker {
int _bit_depth;
int _color_type;
public:
png_type_format_checker(int bit_depth_in,int color_type_in) :
_bit_depth(bit_depth_in),_color_type(color_type_in) {}
template <typename Image>
bool apply() {
return png_read_support<typename Image::view_t>::bit_depth==_bit_depth &&
png_read_support<typename Image::view_t>::color_type==_color_type;
}
};
struct png_read_is_supported {
template<typename View> struct apply
: public mpl::bool_<png_read_support<View>::is_supported> {};
};
class png_reader_dynamic : public png_reader {
public:
png_reader_dynamic(FILE* file) : png_reader(file) {}
png_reader_dynamic(const char* filename) : png_reader(filename){}
template <typename Images>
void read_image(any_image<Images>& im) {
png_uint_32 width, height;
int bit_depth, color_type, interlace_type;
png_get_IHDR(_png_ptr, _info_ptr,
&width, &height,&bit_depth,&color_type,&interlace_type,
int_p_NULL, int_p_NULL);
if (!construct_matched(im,png_type_format_checker(bit_depth,color_type))) {
io_error("png_reader_dynamic::read_image(): no matching image type between those of the given any_image and that of the file");
} else {
im.recreate(width,height);
dynamic_io_fnobj<png_read_is_supported, png_reader> op(this);
apply_operation(view(im),op);
}
}
};
} // namespace detail
/// \ingroup PNG_IO
/// \brief reads a PNG image into a run-time instantiated image
/// Opens the given png file name, selects the first type in Images whose color space and channel are compatible to those of the image file
/// and creates a new image of that type with the dimensions specified by the image file.
/// Throws std::ios_base::failure if none of the types in Images are compatible with the type on disk.
template <typename Images>
inline void png_read_image(const char* filename,any_image<Images>& im) {
detail::png_reader_dynamic m(filename);
m.read_image(im);
}
/// \ingroup PNG_IO
/// \brief reads a PNG image into a run-time instantiated image
template <typename Images>
inline void png_read_image(const std::string& filename,any_image<Images>& im) {
png_read_image(filename.c_str(),im);
}
/// \ingroup PNG_IO
/// \brief Saves the currently instantiated view to a png file specified by the given png image file name.
/// Throws std::ios_base::failure if the currently instantiated view type is not supported for writing by the I/O extension
/// or if it fails to create the file.
template <typename Views>
inline void png_write_view(const char* filename,const any_image_view<Views>& runtime_view) {
detail::png_writer_dynamic m(filename);
m.write_view(runtime_view);
}
/// \ingroup PNG_IO
/// \brief Saves the currently instantiated view to a png file specified by the given png image file name.
template <typename Views>
inline void png_write_view(const std::string& filename,const any_image_view<Views>& runtime_view) {
png_write_view(filename.c_str(),runtime_view);
}
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,214 @@
/*
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_PNG_IO_H
#define GIL_PNG_IO_H
/// \file
/// \brief Support for reading and writing PNG files
/// Requires libpng and zlib!
//
// We are currently providing the following functions:
// point2<std::ptrdiff_t> png_read_dimensions(const char*)
// template <typename View> void png_read_view(const char*,const View&)
// template <typename View> void png_read_image(const char*,image<View>&)
// template <typename View> void png_write_view(const char*,const View&)
// template <typename View> struct png_read_support;
// template <typename View> struct png_write_support;
//
/// \author Hailin Jin and Lubomir Bourdev \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated September 24, 2006
#include <stdio.h>
#include <string>
extern "C" {
#include "png.h"
}
#include <boost/static_assert.hpp>
#include "../../gil_config.hpp"
#include "../../utilities.hpp"
#include "io_error.hpp"
#include "png_io_private.hpp"
namespace boost { namespace gil {
/// \ingroup PNG_IO
/// \brief Returns the width and height of the PNG file at the specified location.
/// Throws std::ios_base::failure if the location does not correspond to a valid PNG file
inline point2<std::ptrdiff_t> png_read_dimensions(const char *filename) {
detail::png_reader m(filename);
return m.get_dimensions();
}
/// \ingroup PNG_IO
/// \brief Returns the width and height of the PNG file at the specified location.
/// Throws std::ios_base::failure if the location does not correspond to a valid PNG file
inline point2<std::ptrdiff_t> png_read_dimensions(const std::string& filename) {
return png_read_dimensions(filename.c_str());
}
/// \ingroup PNG_IO
/// \brief Determines whether the given view type is supported for reading
template <typename View>
struct png_read_support {
BOOST_STATIC_CONSTANT(bool,is_supported=
(detail::png_read_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::is_supported));
BOOST_STATIC_CONSTANT(int,bit_depth=
(detail::png_read_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::bit_depth));
BOOST_STATIC_CONSTANT(int,color_type=
(detail::png_read_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::color_type));
BOOST_STATIC_CONSTANT(bool, value=is_supported);
};
/// \ingroup PNG_IO
/// \brief Loads the image specified by the given png image file name into the given view.
/// Triggers a compile assert if the view color space and channel depth are not supported by the PNG library or by the I/O extension.
/// Throws std::ios_base::failure if the file is not a valid PNG file, or if its color space or channel depth are not
/// compatible with the ones specified by View, or if its dimensions don't match the ones of the view.
template <typename View>
inline void png_read_view(const char* filename,const View& view) {
BOOST_STATIC_ASSERT(png_read_support<View>::is_supported);
detail::png_reader m(filename);
m.apply(view);
}
/// \ingroup PNG_IO
/// \brief Loads the image specified by the given png image file name into the given view.
template <typename View>
inline void png_read_view(const std::string& filename,const View& view) {
png_read_view(filename.c_str(),view);
}
/// \ingroup PNG_IO
/// \brief Allocates a new image whose dimensions are determined by the given png image file, and loads the pixels into it.
/// Triggers a compile assert if the image color space or channel depth are not supported by the PNG library or by the I/O extension.
/// Throws std::ios_base::failure if the file is not a valid PNG file, or if its color space or channel depth are not
/// compatible with the ones specified by Image
template <typename Image>
inline void png_read_image(const char* filename,Image& im) {
BOOST_STATIC_ASSERT(png_read_support<typename Image::view_t>::is_supported);
detail::png_reader m(filename);
m.read_image(im);
}
/// \ingroup PNG_IO
/// \brief Allocates a new image whose dimensions are determined by the given png image file, and loads the pixels into it.
template <typename Image>
inline void png_read_image(const std::string& filename,Image& im) {
png_read_image(filename.c_str(),im);
}
/// \ingroup PNG_IO
/// \brief Loads the image specified by the given png image file name and color-converts it into the given view.
/// Throws std::ios_base::failure if the file is not a valid PNG file, or if its dimensions don't match the ones of the view.
template <typename View,typename CC>
inline void png_read_and_convert_view(const char* filename,const View& view,CC cc) {
detail::png_reader_color_convert<CC> m(filename,cc);
m.apply(view);
}
/// \ingroup PNG_IO
/// \brief Loads the image specified by the given png image file name and color-converts it into the given view.
/// Throws std::ios_base::failure if the file is not a valid PNG file, or if its dimensions don't match the ones of the view.
template <typename View>
inline void png_read_and_convert_view(const char* filename,const View& view) {
detail::png_reader_color_convert<default_color_converter> m(filename,default_color_converter());
m.apply(view);
}
/// \ingroup PNG_IO
/// \brief Loads the image specified by the given png image file name and color-converts it into the given view.
template <typename View,typename CC>
inline void png_read_and_convert_view(const std::string& filename,const View& view,CC cc) {
png_read_and_convert_view(filename.c_str(),view,cc);
}
/// \ingroup PNG_IO
/// \brief Loads the image specified by the given png image file name and color-converts it into the given view.
template <typename View>
inline void png_read_and_convert_view(const std::string& filename,const View& view) {
png_read_and_convert_view(filename.c_str(),view);
}
/// \ingroup PNG_IO
/// \brief Allocates a new image whose dimensions are determined by the given png image file, loads and color-converts the pixels into it.
/// Throws std::ios_base::failure if the file is not a valid PNG file
template <typename Image,typename CC>
inline void png_read_and_convert_image(const char* filename,Image& im,CC cc) {
detail::png_reader_color_convert<CC> m(filename,cc);
m.read_image(im);
}
/// \ingroup PNG_IO
/// \brief Allocates a new image whose dimensions are determined by the given png image file, loads and color-converts the pixels into it.
/// Throws std::ios_base::failure if the file is not a valid PNG file
template <typename Image>
inline void png_read_and_convert_image(const char* filename,Image& im) {
detail::png_reader_color_convert<default_color_converter> m(filename,default_color_converter());
m.read_image(im);
}
/// \ingroup PNG_IO
/// \brief Allocates a new image whose dimensions are determined by the given png image file, loads and color-converts the pixels into it.
template <typename Image,typename CC>
inline void png_read_and_convert_image(const std::string& filename,Image& im,CC cc) {
png_read_and_convert_image(filename.c_str(),im,cc);
}
/// \ingroup PNG_IO
/// \brief Allocates a new image whose dimensions are determined by the given png image file, loads and color-converts the pixels into it.
template <typename Image>
inline void png_read_and_convert_image(const std::string& filename,Image& im) {
png_read_and_convert_image(filename.c_str(),im);
}
/// \ingroup PNG_IO
/// \brief Determines whether the given view type is supported for writing
template <typename View>
struct png_write_support {
BOOST_STATIC_CONSTANT(bool,is_supported=
(detail::png_write_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::is_supported));
BOOST_STATIC_CONSTANT(int,bit_depth=
(detail::png_write_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::bit_depth));
BOOST_STATIC_CONSTANT(int,color_type=
(detail::png_write_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::color_type));
BOOST_STATIC_CONSTANT(bool, value=is_supported);
};
/// \ingroup PNG_IO
/// \brief Saves the view to a png file specified by the given png image file name.
/// Triggers a compile assert if the view color space and channel depth are not supported by the PNG library or by the I/O extension.
/// Throws std::ios_base::failure if it fails to create the file.
template <typename View>
inline void png_write_view(const char* filename,const View& view) {
BOOST_STATIC_ASSERT(png_write_support<View>::is_supported);
detail::png_writer m(filename);
m.apply(view);
}
/// \ingroup PNG_IO
/// \brief Saves the view to a png file specified by the given png image file name.
template <typename View>
inline void png_write_view(const std::string& filename,const View& view) {
png_write_view(filename.c_str(),view);
}
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,359 @@
/*
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://stlab.adobe.com/gil for most recent version including documentation.
*/
/*************************************************************************************************/
#ifndef GIL_PNG_IO_PRIVATE_H
#define GIL_PNG_IO_PRIVATE_H
/// \file
/// \brief Internal support for reading and writing PNG files
/// \author Hailin Jin and Lubomir Bourdev \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated August 14, 2007
#include <algorithm>
#include <vector>
#include <boost/static_assert.hpp>
#include "../../gil_all.hpp"
#include "io_error.hpp"
namespace boost { namespace gil {
namespace detail {
static const std::size_t PNG_BYTES_TO_CHECK = 4;
// lbourdev: These can be greatly simplified, for example:
template <typename Cs> struct png_color_type {BOOST_STATIC_CONSTANT(int,color_type=0);};
template<> struct png_color_type<gray_t> { BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY); };
template<> struct png_color_type<rgb_t> { BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB); };
template<> struct png_color_type<rgba_t> { BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA); };
template <typename Channel,typename ColorSpace> struct png_is_supported {BOOST_STATIC_CONSTANT(bool,value=false);};
template <> struct png_is_supported<bits8,gray_t> {BOOST_STATIC_CONSTANT(bool,value=true);};
template <> struct png_is_supported<bits8,rgb_t> {BOOST_STATIC_CONSTANT(bool,value=true);};
template <> struct png_is_supported<bits8,rgba_t> {BOOST_STATIC_CONSTANT(bool,value=true);};
template <> struct png_is_supported<bits16,gray_t> {BOOST_STATIC_CONSTANT(bool,value=true);};
template <> struct png_is_supported<bits16,rgb_t> {BOOST_STATIC_CONSTANT(bool,value=true);};
template <> struct png_is_supported<bits16,rgba_t> {BOOST_STATIC_CONSTANT(bool,value=true);};
template <typename Channel> struct png_bit_depth {BOOST_STATIC_CONSTANT(int,bit_depth=sizeof(Channel)*8);};
template <typename Channel,typename ColorSpace>
struct png_read_support_private {
BOOST_STATIC_CONSTANT(bool,is_supported=false);
BOOST_STATIC_CONSTANT(int,bit_depth=0);
BOOST_STATIC_CONSTANT(int,color_type=0);
};
template <>
struct png_read_support_private<bits8,gray_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=8);
BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY);
};
template <>
struct png_read_support_private<bits8,rgb_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=8);
BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB);
};
template <>
struct png_read_support_private<bits8,rgba_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=8);
BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA);
};
template <>
struct png_read_support_private<bits16,gray_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=16);
BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY);
};
template <>
struct png_read_support_private<bits16,rgb_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=16);
BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB);
};
template <>
struct png_read_support_private<bits16,rgba_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=16);
BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA);
};
template <typename Channel,typename ColorSpace>
struct png_write_support_private {
BOOST_STATIC_CONSTANT(bool,is_supported=false);
BOOST_STATIC_CONSTANT(int,bit_depth=0);
BOOST_STATIC_CONSTANT(int,color_type=0);
};
template <>
struct png_write_support_private<bits8,gray_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=8);
BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY);
};
template <>
struct png_write_support_private<bits8,rgb_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=8);
BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB);
};
template <>
struct png_write_support_private<bits8,rgba_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=8);
BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA);
};
template <>
struct png_write_support_private<bits16,gray_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=16);
BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY);
};
template <>
struct png_write_support_private<bits16,rgb_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=16);
BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB);
};
template <>
struct png_write_support_private<bits16,rgba_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=16);
BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA);
};
class png_reader : public file_mgr {
protected:
png_structp _png_ptr;
png_infop _info_ptr;
void init() {
char buf[PNG_BYTES_TO_CHECK];
// read in some of the signature bytes
io_error_if(fread(buf, 1, PNG_BYTES_TO_CHECK, get()) != detail::PNG_BYTES_TO_CHECK,
"png_check_validity: fail to read file");
// compare the first PNG_BYTES_TO_CHECK bytes of the signature.
io_error_if(png_sig_cmp((png_bytep)buf, (png_size_t)0, detail::PNG_BYTES_TO_CHECK)!=0,
"png_check_validity: invalid png file");
_png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
io_error_if(_png_ptr==NULL,"png_get_file_size: fail to call png_create_write_struct()");
// allocate/initialize the image information data
_info_ptr = png_create_info_struct(_png_ptr);
if (_info_ptr == NULL) {
png_destroy_read_struct(&_png_ptr,png_infopp_NULL,png_infopp_NULL);
io_error("png_get_file_size: fail to call png_create_info_struct()");
}
if (setjmp(png_jmpbuf(_png_ptr))) {
//free all of the memory associated with the png_ptr and info_ptr
png_destroy_read_struct(&_png_ptr, &_info_ptr, png_infopp_NULL);
io_error("png_get_file_size: fail to call setjmp()");
}
png_init_io(_png_ptr, get());
png_set_sig_bytes(_png_ptr,PNG_BYTES_TO_CHECK);
png_read_info(_png_ptr, _info_ptr);
if (little_endian() && png_get_bit_depth(_png_ptr,_info_ptr)>8)
png_set_swap(_png_ptr);
}
public:
png_reader(FILE* file ) : file_mgr(file) { init(); }
png_reader(const char* filename) : file_mgr(filename, "rb") { init(); }
~png_reader() {
png_destroy_read_struct(&_png_ptr,&_info_ptr,png_infopp_NULL);
}
point2<std::ptrdiff_t> get_dimensions() {
return point2<std::ptrdiff_t>(png_get_image_width(_png_ptr,_info_ptr),
png_get_image_height(_png_ptr,_info_ptr));
}
template <typename View>
void apply(const View& view) {
png_uint_32 width, height;
int bit_depth, color_type, interlace_type;
png_get_IHDR(_png_ptr, _info_ptr,
&width, &height,&bit_depth,&color_type,&interlace_type,
int_p_NULL, int_p_NULL);
io_error_if(((png_uint_32)view.width()!=width || (png_uint_32)view.height()!= height),
"png_read_view: input view size does not match PNG file size");
if(png_read_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::bit_depth!=bit_depth ||
png_read_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::color_type!=color_type)
io_error("png_read_view: input view type is incompatible with the image type");
std::vector<pixel<typename channel_type<View>::type,
layout<typename color_space_type<View>::type> > > row(width);
for(png_uint_32 y=0;y<height;++y) {
png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
std::copy(row.begin(),row.end(),view.row_begin(y));
}
png_read_end(_png_ptr,NULL);
}
template <typename Image>
void read_image(Image& im) {
im.recreate(get_dimensions());
apply(view(im));
}
};
// This code will be simplified...
template <typename CC>
class png_reader_color_convert : public png_reader {
private:
CC _cc;
public:
png_reader_color_convert(FILE* file ,CC cc_in) : png_reader(file),_cc(cc_in) {}
png_reader_color_convert(FILE* file ) : png_reader(file) {}
png_reader_color_convert(const char* filename,CC cc_in) : png_reader(filename),_cc(cc_in) {}
png_reader_color_convert(const char* filename) : png_reader(filename) {}
template <typename View>
void apply(const View& view) {
png_uint_32 width, height;
int bit_depth, color_type, interlace_type;
png_get_IHDR(_png_ptr, _info_ptr,
&width, &height,&bit_depth,&color_type,&interlace_type,
int_p_NULL, int_p_NULL);
io_error_if(((png_uint_32)view.width()!=width || (png_uint_32)view.height()!= height),
"png_reader_color_convert::apply(): input view size does not match PNG file size");
switch (color_type) {
case PNG_COLOR_TYPE_GRAY:
switch (bit_depth) {
case 8: {
std::vector<gray8_pixel_t> row(width);
for(png_uint_32 y=0;y<height;++y) {
png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<gray8_ref_t,typename View::value_type,CC>(_cc));
}
break;
}
case 16: {
std::vector<gray16_pixel_t> row(width);
for(png_uint_32 y=0;y<height;++y) {
png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<gray16_ref_t,typename View::value_type,CC>(_cc));
}
break;
}
default: io_error("png_reader_color_convert::apply(): unknown combination of color type and bit depth");
}
break;
case PNG_COLOR_TYPE_RGB:
switch (bit_depth) {
case 8: {
std::vector<rgb8_pixel_t> row(width);
for(png_uint_32 y=0;y<height;++y) {
png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgb8_ref_t,typename View::value_type,CC>(_cc));
}
break;
}
case 16: {
std::vector<rgb16_pixel_t> row(width);
for(png_uint_32 y=0;y<height;++y) {
png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgb16_ref_t,typename View::value_type,CC>(_cc));
}
break;
}
default: io_error("png_reader_color_convert::apply(): unknown combination of color type and bit depth");
}
break;
case PNG_COLOR_TYPE_RGBA:
switch (bit_depth) {
case 8: {
std::vector<rgba8_pixel_t> row(width);
for(png_uint_32 y=0;y<height;++y) {
png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgba8_ref_t,typename View::value_type,CC>(_cc));
}
break;
}
case 16: {
std::vector<rgba16_pixel_t> row(width);
for(png_uint_32 y=0;y<height;++y) {
png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgba16_ref_t,typename View::value_type,CC>(_cc));
}
break;
}
default: io_error("png_reader_color_convert::apply(): unknown combination of color type and bit depth");
}
break;
default: io_error("png_reader_color_convert::apply(): unknown color type");
}
png_read_end(_png_ptr,NULL);
}
template <typename Image>
void read_image(Image& im) {
im.recreate(get_dimensions());
apply(view(im));
}
};
class png_writer : public file_mgr {
protected:
png_structp _png_ptr;
png_infop _info_ptr;
void init() {
_png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
io_error_if(!_png_ptr,"png_write_initialize: fail to call png_create_write_struct()");
_info_ptr = png_create_info_struct(_png_ptr);
if (!_info_ptr) {
png_destroy_write_struct(&_png_ptr,png_infopp_NULL);
io_error("png_write_initialize: fail to call png_create_info_struct()");
}
if (setjmp(png_jmpbuf(_png_ptr))) {
png_destroy_write_struct(&_png_ptr, &_info_ptr);
io_error("png_write_initialize: fail to call setjmp(png_jmpbuf())");
}
png_init_io(_png_ptr,get());
}
public:
png_writer(FILE* file ) : file_mgr(file) { init(); }
png_writer(const char* filename) : file_mgr(filename, "wb") { init(); }
~png_writer() {
png_destroy_write_struct(&_png_ptr,&_info_ptr);
}
template <typename View>
void apply(const View& view) {
png_set_IHDR(_png_ptr, _info_ptr, view.width(), view.height(),
png_write_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::bit_depth,
png_write_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::color_type,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
png_write_info(_png_ptr,_info_ptr);
if (little_endian() &&
png_write_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::bit_depth>8)
png_set_swap(_png_ptr);
std::vector<pixel<typename channel_type<View>::type,
layout<typename color_space_type<View>::type> > > row(view.width());
for(int y=0;y<view.height();++y) {
std::copy(view.row_begin(y),view.row_end(y),row.begin());
png_write_row(_png_ptr,(png_bytep)&row.front());
}
png_write_end(_png_ptr,_info_ptr);
}
};
} // namespace detail
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,135 @@
/*
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_TIFF_DYNAMIC_IO_H
#define GIL_TIFF_DYNAMIC_IO_H
/// \file
/// \brief Support for reading and writing TIFF files
/// Requires libtiff!
/// \author Hailin Jin and Lubomir Bourdev \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated June 10, 2006
//
// We are currently providing the following functions:
// template <typename Images> void tiff_read_image(const char*,any_image<Images>)
// template <typename Views> void tiff_write_view(const char*,any_image_view<Views>)
//
#include <string>
#include <boost/mpl/bool.hpp>
#include "../dynamic_image/dynamic_image_all.hpp"
#include "io_error.hpp"
#include "tiff_io.hpp"
#include "dynamic_io.hpp"
namespace boost { namespace gil {
namespace detail {
struct tiff_write_is_supported {
template<typename View> struct apply
: public mpl::bool_<tiff_write_support<View>::is_supported> {};
};
class tiff_writer_dynamic : public tiff_writer {
public:
typedef void result_type;
tiff_writer_dynamic(const char* filename) : tiff_writer(filename) {}
template <typename Views>
void write_view(const any_image_view<Views>& runtime_view) {
dynamic_io_fnobj<tiff_write_is_supported, tiff_writer> op(this);
apply_operation(runtime_view,op);
}
};
class tiff_type_format_checker {
int _bit_depth;
int _color_type;
public:
tiff_type_format_checker(int bit_depth_in,int color_type_in) :
_bit_depth(bit_depth_in),_color_type(color_type_in) {}
template <typename Image>
bool apply() {
return tiff_read_support<typename Image::view_t>::bit_depth==_bit_depth &&
tiff_read_support<typename Image::view_t>::color_type==_color_type;
}
};
struct tiff_read_is_supported {
template<typename View> struct apply
: public mpl::bool_<tiff_read_support<View>::is_supported> {};
};
class tiff_reader_dynamic : public tiff_reader {
public:
tiff_reader_dynamic(const char* filename) : tiff_reader(filename) {}
template <typename Images>
void read_image(any_image<Images>& im) {
int width,height;
unsigned short bps,photometric;
TIFFGetField(_tp,TIFFTAG_IMAGEWIDTH,&width);
TIFFGetField(_tp,TIFFTAG_IMAGELENGTH,&height);
TIFFGetField(_tp,TIFFTAG_BITSPERSAMPLE,&bps);
TIFFGetField(_tp,TIFFTAG_PHOTOMETRIC,&photometric);
if (!construct_matched(im,tiff_type_format_checker(bps,photometric))) {
io_error("tiff_reader_dynamic::read_image(): no matching image type between those of the given any_image and that of the file");
} else {
im.recreate(width,height);
dynamic_io_fnobj<tiff_read_is_supported, tiff_reader> op(this);
apply_operation(view(im),op);
}
}
};
} // namespace detail
/// \ingroup TIFF_IO
/// \brief reads a TIFF image into a run-time instantiated image
/// Opens the given tiff file name, selects the first type in Images whose color space and channel are compatible to those of the image file
/// and creates a new image of that type with the dimensions specified by the image file.
/// Throws std::ios_base::failure if none of the types in Images are compatible with the type on disk.
template <typename Images>
inline void tiff_read_image(const char* filename,any_image<Images>& im) {
detail::tiff_reader_dynamic m(filename);
m.read_image(im);
}
/// \ingroup TIFF_IO
/// \brief reads a TIFF image into a run-time instantiated image
template <typename Images>
inline void tiff_read_image(const std::string& filename,any_image<Images>& im) {
tiff_read_image(filename.c_str(),im);
}
/// \ingroup TIFF_IO
/// \brief Saves the currently instantiated view to a tiff file specified by the given tiff image file name.
/// Throws std::ios_base::failure if the currently instantiated view type is not supported for writing by the I/O extension
/// or if it fails to create the file.
template <typename Views>
inline void tiff_write_view(const char* filename,const any_image_view<Views>& runtime_view) {
detail::tiff_writer_dynamic m(filename);
m.write_view(runtime_view);
}
/// \ingroup TIFF_IO
/// \brief Saves the currently instantiated view to a tiff file specified by the given tiff image file name.
template <typename Views>
inline void tiff_write_view(const std::string& filename,const any_image_view<Views>& runtime_view) {
tiff_write_view(filename.c_str(),runtime_view);
}
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,491 @@
/*
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_TIFF_IO_H
#define GIL_TIFF_IO_H
/// \file
/// \brief Support for reading and writing TIFF files
/// Requires libtiff!
/// \author Hailin Jin and Lubomir Bourdev \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated September 24, 2006
#include <vector>
#include <string>
#include <algorithm>
#include <boost/static_assert.hpp>
#include <tiffio.h>
#include "../../gil_all.hpp"
#include "io_error.hpp"
namespace boost { namespace gil {
namespace detail {
template <typename Channel,typename ColorSpace>
struct tiff_read_support_private {
BOOST_STATIC_CONSTANT(bool,is_supported=false);
BOOST_STATIC_CONSTANT(int,bit_depth=0);
BOOST_STATIC_CONSTANT(int,color_type=0);
};
template <>
struct tiff_read_support_private<bits8,gray_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=8);
BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
};
template <>
struct tiff_read_support_private<bits8,rgb_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=8);
BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
};
template <>
struct tiff_read_support_private<bits16,gray_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=16);
BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
};
template <>
struct tiff_read_support_private<bits16,rgb_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=16);
BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
};
template <>
struct tiff_read_support_private<bits32f,gray_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=32);
BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
};
template <>
struct tiff_read_support_private<bits32f,rgb_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=32);
BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
};
template <typename Channel,typename ColorSpace>
struct tiff_write_support_private {
BOOST_STATIC_CONSTANT(bool,is_supported=false);
BOOST_STATIC_CONSTANT(int,bit_depth=0);
BOOST_STATIC_CONSTANT(int,color_type=0);
};
template <>
struct tiff_write_support_private<bits8,gray_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=8);
BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
};
template <>
struct tiff_write_support_private<bits8,rgb_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=8);
BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
};
template <>
struct tiff_write_support_private<bits16,gray_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=16);
BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
};
template <>
struct tiff_write_support_private<bits16,rgb_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=16);
BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
};
template <>
struct tiff_write_support_private<bits32f,gray_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=32);
BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_MINISBLACK);
};
template <>
struct tiff_write_support_private<bits32f,rgb_t> {
BOOST_STATIC_CONSTANT(bool,is_supported=true);
BOOST_STATIC_CONSTANT(int,bit_depth=32);
BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
};
class tiff_reader {
protected:
TIFF *_tp;
public:
tiff_reader(const char* filename) {
io_error_if((_tp=TIFFOpen(filename,"r"))==NULL,
"tiff_reader: fail to open file");
}
~tiff_reader() { TIFFClose(_tp); }
template <typename View>
void apply(const View& view) {
unsigned short bps,photometric;
point2<std::ptrdiff_t> dims=get_dimensions();
io_error_if(TIFFGetField(_tp,TIFFTAG_BITSPERSAMPLE,&bps)!=1);
io_error_if(TIFFGetField(_tp,TIFFTAG_PHOTOMETRIC,&photometric)!=1);
io_error_if(dims!=view.dimensions(),
"tiff_read_view: input view size does not match TIFF file size");
io_error_if(tiff_read_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::bit_depth!=bps ||
tiff_read_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::color_type!=photometric,
"tiff_read_view: input view type is incompatible with the image type");
std::size_t element_size=sizeof(pixel<typename channel_type<View>::type,
layout<typename color_space_type<View>::type> >);
std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
(std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
std::vector<pixel<typename channel_type<View>::type,
layout<typename color_space_type<View>::type> > > row(size_to_allocate);
for (int y=0;y<view.height();++y) {
io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
std::copy(row.begin(),row.begin()+view.width(),view.row_begin(y));
}
}
point2<std::ptrdiff_t> get_dimensions() {
int w,h;
io_error_if(TIFFGetField(_tp,TIFFTAG_IMAGEWIDTH, &w)!=1);
io_error_if(TIFFGetField(_tp,TIFFTAG_IMAGELENGTH,&h)!=1);
return point2<std::ptrdiff_t>(w,h);
}
template <typename Image>
void read_image(Image& im) {
im.recreate(get_dimensions());
apply(view(im));
}
};
// This code will be simplified...
template <typename CC>
class tiff_reader_color_convert : public tiff_reader {
private:
CC _cc;
public:
tiff_reader_color_convert(const char* filename) :
tiff_reader(filename) {}
tiff_reader_color_convert(const char* filename,CC cc_in) :
tiff_reader(filename),_cc(cc_in) {}
template <typename View>
void apply(const View& view) {
point2<std::ptrdiff_t> dims=get_dimensions();
unsigned short bps,photometric;
io_error_if(TIFFGetField(_tp,TIFFTAG_BITSPERSAMPLE,&bps)!=1);
io_error_if(TIFFGetField(_tp,TIFFTAG_PHOTOMETRIC,&photometric)!=1);
io_error_if(dims!=view.dimensions(),
"tiff_reader_color_convert::apply(): input view size does not match TIFF file size");
switch (photometric) {
case PHOTOMETRIC_MINISBLACK: {
switch (bps) {
case 8: {
std::size_t element_size=sizeof(gray8_pixel_t);
std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
(std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
std::vector<gray8_pixel_t> row(size_to_allocate);
for (int y=0;y<view.height();++y) {
io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
color_convert_deref_fn<gray8_ref_t,typename View::value_type,CC>(_cc));
}
break;
}
case 16: {
std::size_t element_size=sizeof(gray16_pixel_t);
std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
(std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
std::vector<gray16_pixel_t> row(size_to_allocate);
for (int y=0;y<view.height();++y) {
io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
color_convert_deref_fn<gray16_ref_t,typename View::value_type,CC>(_cc));
}
break;
}
case 32: {
std::size_t element_size=sizeof(gray32f_pixel_t);
std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
(std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
std::vector<gray32f_pixel_t> row(size_to_allocate);
for (int y=0;y<view.height();++y) {
io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
color_convert_deref_fn<gray32f_ref_t,typename View::value_type,CC>(_cc));
}
break;
}
default:
io_error("tiff_reader_color_convert::apply(): unknown combination of color type and bit depth");
}
break;
}
case PHOTOMETRIC_RGB: {
switch (bps) {
case 8: {
std::size_t element_size=sizeof(rgb8_pixel_t);
std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
(std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
std::vector<rgb8_pixel_t> row(size_to_allocate);
for (int y=0;y<view.height();++y) {
io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
color_convert_deref_fn<rgb8_ref_t,typename View::value_type,CC>(_cc));
}
break;
}
case 16: {
std::size_t element_size=sizeof(rgb16_pixel_t);
std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
(std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
std::vector<rgb16_pixel_t> row(size_to_allocate);
for (int y=0;y<view.height();++y) {
io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
color_convert_deref_fn<rgb16_ref_t,typename View::value_type,CC>(_cc));
}
break;
}
case 32: {
std::size_t element_size=sizeof(rgb32f_pixel_t);
std::size_t size_to_allocate = (std::max)((std::size_t)view.width(),
(std::size_t)(TIFFScanlineSize(_tp)+element_size-1)/element_size);
std::vector<rgb32f_pixel_t> row(size_to_allocate);
for (int y=0;y<view.height();++y) {
io_error_if(TIFFReadScanline(_tp,&row.front(), y)!=1);
std::transform(row.begin(),row.begin()+view.width(),view.row_begin(y),
color_convert_deref_fn<rgb32f_ref_t,typename View::value_type,CC>(_cc));
}
break;
}
default:
io_error("tiff_reader_color_convert::apply(): unknown combination of color type and bit depth");
}
break;
}
default: {
// reads an image in incompatible format via TIFFReadRGBAImage
rgba8_image_t rgbaImg(dims);
io_error_if(!TIFFReadRGBAImage(_tp, dims.x, dims.y, (uint32*)&gil::view(rgbaImg)(0,0), 0),
"tiff_reader_color_convert::unsupported image format");
copy_and_convert_pixels(flipped_up_down_view(const_view(rgbaImg)), view, _cc);
}
}
}
template <typename Image>
void read_image(Image& im) {
im.recreate(get_dimensions());
apply(view(im));
}
};
class tiff_writer {
protected:
TIFF* _tp;
public:
tiff_writer(const char *filename) {
io_error_if((_tp=TIFFOpen(filename,"w"))==NULL,
"tiff_writer: fail to open file");
}
~tiff_writer() {TIFFClose(_tp);}
template <typename View>
void apply(const View& view) {
io_error_if(TIFFSetField(_tp,TIFFTAG_IMAGELENGTH, view.height())!=1);
io_error_if(TIFFSetField(_tp,TIFFTAG_IMAGEWIDTH, view.width())!=1);
io_error_if(TIFFSetField(_tp,TIFFTAG_PHOTOMETRIC, tiff_write_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::color_type)!=1);
io_error_if(TIFFSetField(_tp,TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE)!=1);
io_error_if(TIFFSetField(_tp,TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)!=1);
io_error_if(TIFFSetField(_tp,TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT)!=1);
io_error_if(TIFFSetField(_tp,TIFFTAG_SAMPLESPERPIXEL,num_channels<View>::value)!=1);
io_error_if(TIFFSetField(_tp,TIFFTAG_BITSPERSAMPLE, tiff_write_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::bit_depth)!=1);
io_error_if(TIFFSetField(_tp,TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(_tp, 0))!=1);
std::vector<pixel<typename channel_type<View>::type,
layout<typename color_space_type<View>::type> > > row(view.width());
for (int y=0;y<view.height();++y) {
std::copy(view.row_begin(y),view.row_end(y),row.begin());
io_error_if(TIFFWriteScanline(_tp,&row.front(),y,0)!=1,
"tiff_write_view: fail to write file");
}
}
};
} // namespace detail
/// \ingroup TIFF_IO
/// \brief Determines whether the given view type is supported for reading
template <typename View>
struct tiff_read_support {
BOOST_STATIC_CONSTANT(bool,is_supported=
(detail::tiff_read_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::is_supported));
BOOST_STATIC_CONSTANT(int,bit_depth=
(detail::tiff_read_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::bit_depth));
BOOST_STATIC_CONSTANT(int,color_type=
(detail::tiff_read_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::color_type));
};
/// \ingroup TIFF_IO
/// \brief Returns the width and height of the TIFF file at the specified location.
/// Throws std::ios_base::failure if the location does not correspond to a valid TIFF file
inline point2<std::ptrdiff_t> tiff_read_dimensions(const char* filename) {
detail::tiff_reader m(filename);
return m.get_dimensions();
}
/// \ingroup TIFF_IO
/// \brief Returns the width and height of the TIFF file at the specified location.
/// Throws std::ios_base::failure if the location does not correspond to a valid TIFF file
inline point2<std::ptrdiff_t> tiff_read_dimensions(const std::string& filename) {
return tiff_read_dimensions(filename.c_str());
}
/// \ingroup TIFF_IO
/// \brief Loads the image specified by the given tiff image file name into the given view.
/// Triggers a compile assert if the view color space and channel depth are not supported by the TIFF library or by the I/O extension.
/// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its color space or channel depth are not
/// compatible with the ones specified by View, or if its dimensions don't match the ones of the view.
template <typename View>
inline void tiff_read_view(const char* filename,const View& view) {
BOOST_STATIC_ASSERT(tiff_read_support<View>::is_supported);
detail::tiff_reader m(filename);
m.apply(view);
}
/// \ingroup TIFF_IO
/// \brief Loads the image specified by the given tiff image file name into the given view.
template <typename View>
inline void tiff_read_view(const std::string& filename,const View& view) {
tiff_read_view(filename.c_str(),view);
}
/// \ingroup TIFF_IO
/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, and loads the pixels into it.
/// Triggers a compile assert if the image color space or channel depth are not supported by the TIFF library or by the I/O extension.
/// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its color space or channel depth are not
/// compatible with the ones specified by Image
template <typename Image>
void tiff_read_image(const char* filename,Image& im) {
BOOST_STATIC_ASSERT(tiff_read_support<typename Image::view_t>::is_supported);
detail::tiff_reader m(filename);
m.read_image(im);
}
/// \ingroup TIFF_IO
/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, and loads the pixels into it.
template <typename Image>
inline void tiff_read_image(const std::string& filename,Image& im) {
tiff_read_image(filename.c_str(),im);
}
/// \ingroup TIFF_IO
/// \brief Loads and color-converts the image specified by the given tiff image file name into the given view.
/// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its dimensions don't match the ones of the view.
template <typename View,typename CC>
inline void tiff_read_and_convert_view(const char* filename,const View& view,CC cc) {
detail::tiff_reader_color_convert<CC> m(filename,cc);
m.apply(view);
}
/// \ingroup TIFF_IO
/// \brief Loads and color-converts the image specified by the given tiff image file name into the given view.
/// Throws std::ios_base::failure if the file is not a valid TIFF file, or if its dimensions don't match the ones of the view.
template <typename View>
inline void tiff_read_and_convert_view(const char* filename,const View& view) {
detail::tiff_reader_color_convert<default_color_converter> m(filename,default_color_converter());
m.apply(view);
}
/// \ingroup TIFF_IO
/// \brief Loads and color-converts the image specified by the given tiff image file name into the given view.
template <typename View,typename CC>
inline void tiff_read_and_convert_view(const std::string& filename,const View& view,CC cc) {
tiff_read_and_convert_view(filename.c_str(),view,cc);
}
/// \ingroup TIFF_IO
/// \brief Loads and color-converts the image specified by the given tiff image file name into the given view.
template <typename View>
inline void tiff_read_and_convert_view(const std::string& filename,const View& view) {
tiff_read_and_convert_view(filename.c_str(),view);
}
/// \ingroup TIFF_IO
/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it.
/// Throws std::ios_base::failure if the file is not a valid TIFF file
template <typename Image,typename CC>
void tiff_read_and_convert_image(const char* filename,Image& im,CC cc) {
detail::tiff_reader_color_convert<CC> m(filename,cc);
m.read_image(im);
}
/// \ingroup TIFF_IO
/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it.
/// Throws std::ios_base::failure if the file is not a valid TIFF file
template <typename Image>
void tiff_read_and_convert_image(const char* filename,Image& im) {
detail::tiff_reader_color_convert<default_color_converter> m(filename,default_color_converter());
m.read_image(im);
}
/// \ingroup TIFF_IO
/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it.
template <typename Image,typename CC>
inline void tiff_read_and_convert_image(const std::string& filename,Image& im,CC cc) {
tiff_read_and_convert_image(filename.c_str(),im,cc);
}
/// \ingroup TIFF_IO
/// \brief Allocates a new image whose dimensions are determined by the given tiff image file, loads and color-converts the pixels into it.
template <typename Image>
inline void tiff_read_and_convert_image(const std::string& filename,Image& im) {
tiff_read_and_convert_image(filename.c_str(),im);
}
/// \ingroup TIFF_IO
/// \brief Determines whether the given view type is supported for writing
template <typename View>
struct tiff_write_support {
BOOST_STATIC_CONSTANT(bool,is_supported=
(detail::tiff_write_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::is_supported));
BOOST_STATIC_CONSTANT(int,bit_depth=
(detail::tiff_write_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::bit_depth));
BOOST_STATIC_CONSTANT(int,color_type=
(detail::tiff_write_support_private<typename channel_type<View>::type,
typename color_space_type<View>::type>::color_type));
BOOST_STATIC_CONSTANT(bool, value=is_supported);
};
/// \ingroup TIFF_IO
/// \brief Saves the view to a tiff file specified by the given tiff image file name.
/// Triggers a compile assert if the view color space and channel depth are not supported by the TIFF library or by the I/O extension.
/// Throws std::ios_base::failure if it fails to create the file.
template <typename View>
inline void tiff_write_view(const char* filename,const View& view) {
BOOST_STATIC_ASSERT(tiff_write_support<View>::is_supported);
detail::tiff_writer m(filename);
m.apply(view);
}
/// \ingroup TIFF_IO
/// \brief Saves the view to a tiff file specified by the given tiff image file name.
template <typename View>
inline void tiff_write_view(const std::string& filename,const View& view) {
tiff_write_view(filename.c_str(),view);
}
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,46 @@
/*
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_ALL_HPP
#define GIL_ALL_HPP
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Includes all GIL files for convenience
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
///
///
////////////////////////////////////////////////////////////////////////////////////////
#include "gil_config.hpp"
#include "channel_algorithm.hpp"
#include "algorithm.hpp"
#include "pixel.hpp"
#include "packed_pixel.hpp"
#include "planar_pixel_reference.hpp"
#include "planar_pixel_iterator.hpp"
#include "pixel_iterator_adaptor.hpp"
#include "step_iterator.hpp"
#include "iterator_from_2d.hpp"
#include "image.hpp"
#include "image_view_factory.hpp"
#include "typedefs.hpp"
#include "metafunctions.hpp"
#include "color_convert.hpp"
#include "device_n.hpp"
#include "virtual_locator.hpp"
#include "bit_aligned_pixel_iterator.hpp"
// Uncomment this line to help in porting your code from an older version of GIL
//#include "deprecated.hpp"
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
/*
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_CONFIG_HPP
#define GIL_CONFIG_HPP
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief GIL configuration file
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
///
////////////////////////////////////////////////////////////////////////////////////////
#include <boost/config.hpp>
#define GIL_VERSION "2.1.2"
#ifdef _DEBUG
# define GIL_FORCEINLINE inline
#else
#ifdef NDEBUG
#if defined(_MSC_VER)
# define GIL_FORCEINLINE __forceinline
#elif defined(__GNUC__) && __GNUC__ > 3
# define GIL_FORCEINLINE inline __attribute__ ((always_inline))
#else
# define GIL_FORCEINLINE inline
#endif
#else
# define GIL_FORCEINLINE inline
#endif
#endif
// Enable GIL_NONWORD_POINTER_ALIGNMENT_SUPPORTED if your platform supports dereferencing on non-word memory boundary.
// Enabling the flag results in performance improvement
#if !defined(__hpux) && !defined(sun) && !defined(__sun) && !defined(__osf__)
#define GIL_NONWORD_POINTER_ALIGNMENT_SUPPORTED
#endif
#endif

45
src/3rdparty/include/boost/gil/gray.hpp vendored Normal file
View File

@ -0,0 +1,45 @@
/*
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_GRAY_H
#define GIL_GRAY_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Support for grayscale color space and variants
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on March 8, 2006
////////////////////////////////////////////////////////////////////////////////////////
#include "gil_config.hpp"
#include "utilities.hpp"
#include <boost/type_traits.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/vector_c.hpp>
namespace boost { namespace gil {
/// \ingroup ColorNameModel
/// \brief Gray
struct gray_color_t {};
/// \ingroup ColorSpaceModel
typedef mpl::vector1<gray_color_t> gray_t;
/// \ingroup LayoutModel
typedef layout<gray_t> gray_layout_t;
} } // namespace boost::gil
#endif

288
src/3rdparty/include/boost/gil/image.hpp vendored Normal file
View File

@ -0,0 +1,288 @@
/*
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, 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>());
default_construct_pixels(_view);
} catch(...) { 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 {
std::size_t size_in_units = get_row_size_in_memunits(dimensions.x)*dimensions.y;
if (IsPlanar)
size_in_units = size_in_units*num_channels<view_t>::value;
// return the size rounded up to the nearest byte
return (size_in_units + byte_to_memunit<typename view_t::x_iterator>::value - 1) / byte_to_memunit<typename view_t::x_iterator>::value
+ (_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

View File

@ -0,0 +1,223 @@
/*
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_VIEW_H
#define GIL_IMAGE_VIEW_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief image view class
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on February 12, 2007
///
////////////////////////////////////////////////////////////////////////////////////////
#include <cstddef>
#include <iterator>
#include "gil_config.hpp"
#include "iterator_from_2d.hpp"
//#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 {
////////////////////////////////////////////////////////////////////////////////////////
/// \class image_view
/// \ingroup ImageViewModel PixelBasedModel
/// \brief A lightweight object that interprets memory as a 2D array of pixels. Models ImageViewConcept,PixelBasedConcept,HasDynamicXStepTypeConcept,HasDynamicYStepTypeConcept,HasTransposedTypeConcept
///
/// Image view consists of a pixel 2D locator (defining the mechanism for navigating in 2D)
/// and the image dimensions.
///
/// Image views to images are what ranges are to STL containers. They are lightweight objects,
/// that don't own the pixels. It is the user's responsibility that the underlying data remains
/// valid for the lifetime of the image view.
///
/// Similar to iterators and ranges, constness of views does not extend to constness of pixels.
/// A const \p image_view does not allow changing its location in memory (resizing, moving) but does
/// not prevent one from changing the pixels. The latter requires an image view whose value_type
/// is const.
///
/// Images have interfaces consistent with STL 1D random access containers, so they can be used
/// directly in STL algorithms like:
/// \code
/// std::fill(img.begin(), img.end(), red_pixel);
/// \endcode
///
/// In addition, horizontal, vertical and 2D random access iterators are provided.
///
/// Note also that \p image_view does not require that its element type be a pixel. It could be
/// instantiated with a locator whose \p value_type models only \p Regular. In this case the image
/// view models the weaker RandomAccess2DImageViewConcept, and does not model PixelBasedConcept.
/// Many generic algorithms don't require the elements to be pixels.
///
////////////////////////////////////////////////////////////////////////////////////////
template <typename Loc> // Models 2D Pixel Locator
class image_view {
public:
// typedefs required by ConstRandomAccessNDImageViewConcept
static const std::size_t num_dimensions=2;
typedef typename Loc::value_type value_type;
typedef typename Loc::reference reference; // result of dereferencing
typedef typename Loc::coord_t coord_t; // 1D difference type (same for all dimensions)
typedef coord_t difference_type; // result of operator-(1d_iterator,1d_iterator)
typedef typename Loc::point_t point_t;
typedef Loc locator;
typedef image_view<typename Loc::const_t> const_t; // same as this type, but over const values
template <std::size_t D> struct axis {
typedef typename Loc::template axis<D>::coord_t coord_t; // difference_type along each dimension
typedef typename Loc::template axis<D>::iterator iterator; // 1D iterator type along each dimension
};
typedef iterator_from_2d<Loc> iterator; // 1D iterator type for each pixel left-to-right inside top-to-bottom
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::size_t size_type;
// typedefs required by ConstRandomAccess2DImageViewConcept
typedef locator xy_locator;
typedef typename xy_locator::x_iterator x_iterator; // pixel iterator along a row
typedef typename xy_locator::y_iterator y_iterator; // pixel iterator along a column
typedef typename xy_locator::x_coord_t x_coord_t;
typedef typename xy_locator::y_coord_t y_coord_t;
template <typename Deref> struct add_deref {
typedef image_view<typename Loc::template add_deref<Deref>::type> type;
static type make(const image_view<Loc>& iv, const Deref& d) { return type(iv.dimensions(), Loc::template add_deref<Deref>::make(iv.pixels(),d)); }
};
image_view() : _dimensions(0,0) {}
template <typename View> image_view(const View& iv) : _dimensions(iv.dimensions()), _pixels(iv.pixels()) {}
template <typename L2> image_view(const point_t& sz , const L2& loc) : _dimensions(sz), _pixels(loc) {}
template <typename L2> image_view(coord_t width, coord_t height, const L2& loc) : _dimensions(x_coord_t(width),y_coord_t(height)), _pixels(loc) {}
template <typename View> image_view& operator=(const View& iv) { _pixels=iv.pixels(); _dimensions=iv.dimensions(); return *this; }
image_view& operator=(const image_view& iv) { _pixels=iv.pixels(); _dimensions=iv.dimensions(); return *this; }
template <typename View> bool operator==(const View& v) const { return pixels()==v.pixels() && dimensions()==v.dimensions(); }
template <typename View> bool operator!=(const View& v) const { return !(*this==v); }
template <typename L2> friend void swap(image_view<L2>& x, image_view<L2>& y);
const point_t& dimensions() const { return _dimensions; }
const locator& pixels() const { return _pixels; }
x_coord_t width() const { return dimensions().x; }
y_coord_t height() const { return dimensions().y; }
std::size_t num_channels() const { return gil::num_channels<value_type>::value; }
bool is_1d_traversable() const { return _pixels.is_1d_traversable(width()); }
//\{@
/// \name 1D navigation
size_type size() const { return width()*height(); }
iterator begin() const { return iterator(_pixels,_dimensions.x); }
iterator end() const { return begin()+(difference_type)size(); } // potential performance problem!
reverse_iterator rbegin() const { return reverse_iterator(end()); }
reverse_iterator rend() const { return reverse_iterator(begin()); }
reference operator[](difference_type i) const { return begin()[i]; } // potential performance problem!
iterator at(difference_type i)const { return begin()+i; }
iterator at(const point_t& p) const { return begin()+p.y*width()+p.x; }
iterator at(x_coord_t x, y_coord_t y)const { return begin()+y*width()+x; }
//\}@
//\{@
/// \name 2-D navigation
reference operator()(const point_t& p) const { return _pixels(p.x,p.y); }
reference operator()(x_coord_t x, y_coord_t y)const { return _pixels(x,y); }
template <std::size_t D> typename axis<D>::iterator axis_iterator(const point_t& p) const { return _pixels.axis_iterator<D>(p); }
xy_locator xy_at(x_coord_t x, y_coord_t y) const { return _pixels+point_t(x_coord_t(x),y_coord_t(y)); }
locator xy_at(const point_t& p) const { return _pixels+p; }
//\}@
//\{@
/// \name X navigation
x_iterator x_at(x_coord_t x, y_coord_t y) const { return _pixels.x_at(x,y); }
x_iterator x_at(const point_t& p) const { return _pixels.x_at(p); }
x_iterator row_begin(y_coord_t y) const { return x_at(0,y); }
x_iterator row_end(y_coord_t y) const { return x_at(width(),y); }
//\}@
//\{@
/// \name Y navigation
y_iterator y_at(x_coord_t x, y_coord_t y) const { return xy_at(x,y).y(); }
y_iterator y_at(const point_t& p) const { return xy_at(p).y(); }
y_iterator col_begin(x_coord_t x) const { return y_at(x,0); }
y_iterator col_end(x_coord_t x) const { return y_at(x,height()); }
//\}@
private:
template <typename L2> friend class image_view;
point_t _dimensions;
xy_locator _pixels;
};
template <typename L2>
inline void swap(image_view<L2>& x, image_view<L2>& y) {
using std::swap;
swap(x._dimensions,y._dimensions);
swap(x._pixels, y._pixels); // TODO: Extend further
}
/////////////////////////////
// PixelBasedConcept
/////////////////////////////
template <typename L>
struct channel_type<image_view<L> > : public channel_type<L> {};
template <typename L>
struct color_space_type<image_view<L> > : public color_space_type<L> {};
template <typename L>
struct channel_mapping_type<image_view<L> > : public channel_mapping_type<L> {};
template <typename L>
struct is_planar<image_view<L> > : public is_planar<L> {};
/////////////////////////////
// HasDynamicXStepTypeConcept
/////////////////////////////
template <typename L>
struct dynamic_x_step_type<image_view<L> > {
typedef image_view<typename dynamic_x_step_type<L>::type> type;
};
/////////////////////////////
// HasDynamicYStepTypeConcept
/////////////////////////////
template <typename L>
struct dynamic_y_step_type<image_view<L> > {
typedef image_view<typename dynamic_y_step_type<L>::type> type;
};
/////////////////////////////
// HasTransposedTypeConcept
/////////////////////////////
template <typename L>
struct transposed_type<image_view<L> > {
typedef image_view<typename transposed_type<L>::type> type;
};
} } // namespace boost::gil
//#ifdef _MSC_VER
//#pragma warning(pop)
//#endif
#endif

View File

@ -0,0 +1,537 @@
/*
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_VIEW_FACTORY_HPP
#define GIL_IMAGE_VIEW_FACTORY_HPP
/*!
/// \file
/// \brief Methods for constructing image views from raw data or other image views
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on March 9, 2007
/// Methods for creating shallow image views from raw pixel data or from other image views -
/// flipping horizontally or vertically, axis-aligned rotation, a subimage, subsampled
/// or n-th channel image view. Derived image views are shallow copies and are fast to construct.
*/
#include <cassert>
#include <cstddef>
#include "gil_config.hpp"
#include "metafunctions.hpp"
#include "gray.hpp"
#include "color_convert.hpp"
/// \defgroup ImageViewConstructors Image View From Raw Data
/// \ingroup ImageViewAlgorithm
/// \brief Methods for constructing image views from raw data and for getting raw data from views
/// \defgroup ImageViewTransformations Image View Transformations
/// \ingroup ImageViewAlgorithm
/// \brief Methods for constructing one image view from another
namespace boost { namespace gil {
struct default_color_converter;
template <typename T> struct dynamic_x_step_type;
template <typename T> struct dynamic_y_step_type;
template <typename T> struct transposed_type;
/// \brief Returns the type of a view that has a dynamic step along both X and Y
/// \ingroup ImageViewTransformations
template <typename View>
struct dynamic_xy_step_type : public dynamic_y_step_type<typename dynamic_x_step_type<View>::type> {};
/// \brief Returns the type of a transposed view that has a dynamic step along both X and Y
/// \ingroup ImageViewTransformations
template <typename View>
struct dynamic_xy_step_transposed_type : public dynamic_xy_step_type<typename transposed_type<View>::type> {};
/// \ingroup ImageViewConstructors
/// \brief Constructing image views from raw interleaved pixel data
template <typename Iterator>
typename type_from_x_iterator<Iterator>::view_t
interleaved_view(std::size_t width, std::size_t height,
Iterator pixels, std::ptrdiff_t rowsize_in_bytes) {
typedef typename type_from_x_iterator<Iterator>::view_t RView;
return RView(width, height, typename RView::locator(pixels, rowsize_in_bytes));
}
/// \ingroup ImageViewConstructors
/// \brief Constructing image views from raw interleaved pixel data
template <typename Iterator>
typename type_from_x_iterator<Iterator>::view_t
interleaved_view(point2<std::size_t> dim,
Iterator pixels, std::ptrdiff_t rowsize_in_bytes) {
typedef typename type_from_x_iterator<Iterator>::view_t RView;
return RView(dim, typename RView::locator(pixels, rowsize_in_bytes));
}
/////////////////////////////
// interleaved_view_get_raw_data, planar_view_get_raw_data - return pointers to the raw data (the channels) of a basic homogeneous view.
/////////////////////////////
namespace detail {
template <typename View, bool IsMutable> struct channel_pointer_type_impl;
template <typename View> struct channel_pointer_type_impl<View, true> {
typedef typename channel_type<View>::type* type;
};
template <typename View> struct channel_pointer_type_impl<View, false> {
typedef const typename channel_type<View>::type* type;
};
template <typename View> struct channel_pointer_type
: public channel_pointer_type_impl<View, view_is_mutable<View>::value> {};
} // namespace detail
/// \ingroup ImageViewConstructors
/// \brief Returns C pointer to the the channels of an interleaved homogeneous view.
template <typename HomogeneousView>
typename detail::channel_pointer_type<HomogeneousView>::type interleaved_view_get_raw_data(const HomogeneousView& view) {
BOOST_STATIC_ASSERT((!is_planar<HomogeneousView>::value && view_is_basic<HomogeneousView>::value));
BOOST_STATIC_ASSERT((boost::is_pointer<typename HomogeneousView::x_iterator>::value));
return &at_c<0>(view(0,0));
}
/// \ingroup ImageViewConstructors
/// \brief Returns C pointer to the the channels of a given color plane of a planar homogeneous view.
template <typename HomogeneousView>
typename detail::channel_pointer_type<HomogeneousView>::type planar_view_get_raw_data(const HomogeneousView& view, int plane_index) {
BOOST_STATIC_ASSERT((is_planar<HomogeneousView>::value && view_is_basic<HomogeneousView>::value));
return dynamic_at_c(view.row_begin(0),plane_index);
}
/// \defgroup ImageViewTransformationsColorConvert color_converted_view
/// \ingroup ImageViewTransformations
/// \brief Color converted view of another view
/// \ingroup ImageViewTransformationsColorConvert PixelDereferenceAdaptorModel
/// \brief Function object that given a source pixel, returns it converted to a given color space and channel depth. Models: PixelDereferenceAdaptorConcept
///
/// Useful in constructing a color converted view over a given image view
template <typename SrcConstRefP, typename DstP, typename CC=default_color_converter > // const_reference to the source pixel and destination pixel value
class color_convert_deref_fn : public deref_base<color_convert_deref_fn<SrcConstRefP,DstP,CC>, DstP, DstP, const DstP&, SrcConstRefP, DstP, false> {
private:
CC _cc; // color-converter
public:
color_convert_deref_fn() {}
color_convert_deref_fn(CC cc_in) : _cc(cc_in) {}
DstP operator()(SrcConstRefP srcP) const {
DstP dstP;
_cc(srcP,dstP);
return dstP;
}
};
namespace detail {
// Add color converter upon dereferencing
template <typename SrcView, typename CC, typename DstP, typename SrcP>
struct _color_converted_view_type {
private:
typedef color_convert_deref_fn<typename SrcView::const_t::reference,DstP,CC> deref_t;
typedef typename SrcView::template add_deref<deref_t> add_ref_t;
public:
typedef typename add_ref_t::type type;
static type make(const SrcView& sv,CC cc) {return add_ref_t::make(sv,deref_t(cc));}
};
// If the Src view has the same pixel type as the target, there is no need for color conversion
template <typename SrcView, typename CC, typename DstP>
struct _color_converted_view_type<SrcView,CC,DstP,DstP> {
typedef SrcView type;
static type make(const SrcView& sv,CC) {return sv;}
};
} // namespace detail
/// \brief Returns the type of a view that does color conversion upon dereferencing its pixels
/// \ingroup ImageViewTransformationsColorConvert
template <typename SrcView, typename DstP, typename CC=default_color_converter>
struct color_converted_view_type : public detail::_color_converted_view_type<SrcView,
CC,
DstP,
typename SrcView::value_type> {
GIL_CLASS_REQUIRE(DstP, boost::gil, MutablePixelConcept)//why does it have to be mutable???
};
/// \ingroup ImageViewTransformationsColorConvert
/// \brief view of a different color space with a user defined color-converter
template <typename DstP, typename View, typename CC>
inline typename color_converted_view_type<View,DstP,CC>::type color_converted_view(const View& src,CC cc) {
return color_converted_view_type<View,DstP,CC>::make(src,cc);
}
/// \ingroup ImageViewTransformationsColorConvert
/// \brief overload of generic color_converted_view with the default color-converter
template <typename DstP, typename View>
inline typename color_converted_view_type<View,DstP>::type
color_converted_view(const View& src) {
return color_converted_view<DstP>(src,default_color_converter());
}
/// \defgroup ImageViewTransformationsFlipUD flipped_up_down_view
/// \ingroup ImageViewTransformations
/// \brief view of a view flipped up-to-down
/// \ingroup ImageViewTransformationsFlipUD
template <typename View>
inline typename dynamic_y_step_type<View>::type flipped_up_down_view(const View& src) {
typedef typename dynamic_y_step_type<View>::type RView;
return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(0,src.height()-1),-1));
}
/// \defgroup ImageViewTransformationsFlipLR flipped_left_right_view
/// \ingroup ImageViewTransformations
/// \brief view of a view flipped left-to-right
/// \ingroup ImageViewTransformationsFlipLR
template <typename View>
inline typename dynamic_x_step_type<View>::type flipped_left_right_view(const View& src) {
typedef typename dynamic_x_step_type<View>::type RView;
return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(src.width()-1,0),-1,1));
}
/// \defgroup ImageViewTransformationsTransposed transposed_view
/// \ingroup ImageViewTransformations
/// \brief view of a view transposed
/// \ingroup ImageViewTransformationsTransposed
template <typename View>
inline typename dynamic_xy_step_transposed_type<View>::type transposed_view(const View& src) {
typedef typename dynamic_xy_step_transposed_type<View>::type RView;
return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(0,0),1,1,true));
}
/// \defgroup ImageViewTransformations90CW rotated90cw_view
/// \ingroup ImageViewTransformations
/// \brief view of a view rotated 90 degrees clockwise
/// \ingroup ImageViewTransformations90CW
template <typename View>
inline typename dynamic_xy_step_transposed_type<View>::type rotated90cw_view(const View& src) {
typedef typename dynamic_xy_step_transposed_type<View>::type RView;
return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(0,src.height()-1),-1,1,true));
}
/// \defgroup ImageViewTransformations90CCW rotated90ccw_view
/// \ingroup ImageViewTransformations
/// \brief view of a view rotated 90 degrees counter-clockwise
/// \ingroup ImageViewTransformations90CCW
template <typename View>
inline typename dynamic_xy_step_transposed_type<View>::type rotated90ccw_view(const View& src) {
typedef typename dynamic_xy_step_transposed_type<View>::type RView;
return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(src.width()-1,0),1,-1,true));
}
/// \defgroup ImageViewTransformations180 rotated180_view
/// \ingroup ImageViewTransformations
/// \brief view of a view rotated 180 degrees
/// \ingroup ImageViewTransformations180
template <typename View>
inline typename dynamic_xy_step_type<View>::type rotated180_view(const View& src) {
typedef typename dynamic_xy_step_type<View>::type RView;
return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(src.width()-1,src.height()-1),-1,-1));
}
/// \defgroup ImageViewTransformationsSubimage subimage_view
/// \ingroup ImageViewTransformations
/// \brief view of an axis-aligned rectangular area within an image_view
/// \ingroup ImageViewTransformationsSubimage
template <typename View>
inline View subimage_view(const View& src, const typename View::point_t& topleft, const typename View::point_t& dimensions) {
return View(dimensions,src.xy_at(topleft));
}
/// \ingroup ImageViewTransformationsSubimage
template <typename View>
inline View subimage_view(const View& src, int xMin, int yMin, int width, int height) {
return View(width,height,src.xy_at(xMin,yMin));
}
/// \defgroup ImageViewTransformationsSubsampled subsampled_view
/// \ingroup ImageViewTransformations
/// \brief view of a subsampled version of an image_view, stepping over a number of channels in X and number of rows in Y
/// \ingroup ImageViewTransformationsSubsampled
template <typename View>
inline typename dynamic_xy_step_type<View>::type subsampled_view(const View& src, typename View::coord_t xStep, typename View::coord_t yStep) {
assert(xStep>0 && yStep>0);
typedef typename dynamic_xy_step_type<View>::type RView;
return RView((src.width()+(xStep-1))/xStep,(src.height()+(yStep-1))/yStep,
typename RView::xy_locator(src.xy_at(0,0),xStep,yStep));
}
/// \ingroup ImageViewTransformationsSubsampled
template <typename View>
inline typename dynamic_xy_step_type<View>::type subsampled_view(const View& src, const typename View::point_t& step) {
return subsampled_view(src,step.x,step.y);
}
/// \defgroup ImageViewTransformationsNthChannel nth_channel_view
/// \ingroup ImageViewTransformations
/// \brief single-channel (grayscale) view of the N-th channel of a given image_view
namespace detail {
template <typename View, bool AreChannelsTogether> struct __nth_channel_view_basic;
// nth_channel_view when the channels are not adjacent in memory. This can happen for multi-channel interleaved images
// or images with a step
template <typename View>
struct __nth_channel_view_basic<View,false> {
typedef typename view_type<typename channel_type<View>::type, gray_layout_t, false, true, view_is_mutable<View>::value>::type type;
static type make(const View& src, int n) {
typedef typename type::xy_locator locator_t;
typedef typename type::x_iterator x_iterator_t;
typedef typename iterator_adaptor_get_base<x_iterator_t>::type x_iterator_base_t;
x_iterator_t sit(x_iterator_base_t(&(src(0,0)[n])),src.pixels().pixel_size());
return type(src.dimensions(),locator_t(sit, src.pixels().row_size()));
}
};
// nth_channel_view when the channels are together in memory (true for simple grayscale or planar images)
template <typename View>
struct __nth_channel_view_basic<View,true> {
typedef typename view_type<typename channel_type<View>::type, gray_layout_t, false, false, view_is_mutable<View>::value>::type type;
static type make(const View& src, int n) {
typedef typename type::x_iterator x_iterator_t;
return interleaved_view(src.width(),src.height(),(x_iterator_t)&(src(0,0)[n]), src.pixels().row_size());
}
};
template <typename View, bool IsBasic> struct __nth_channel_view;
// For basic (memory-based) views dispatch to __nth_channel_view_basic
template <typename View> struct __nth_channel_view<View,true> {
private:
typedef typename View::x_iterator src_x_iterator;
// Determines whether the channels of a given pixel iterator are adjacent in memory.
// Planar and grayscale iterators have channels adjacent in memory, whereas multi-channel interleaved and iterators with non-fundamental step do not.
BOOST_STATIC_CONSTANT(bool, adjacent=
!iterator_is_step<src_x_iterator>::value &&
(is_planar<src_x_iterator>::value ||
num_channels<View>::value==1));
public:
typedef typename __nth_channel_view_basic<View,adjacent>::type type;
static type make(const View& src, int n) {
return __nth_channel_view_basic<View,adjacent>::make(src,n);
}
};
/// \brief Function object that returns a grayscale reference of the N-th channel of a given reference. Models: PixelDereferenceAdaptorConcept.
/// \ingroup PixelDereferenceAdaptorModel
///
/// If the input is a pixel value or constant reference, the function object is immutable. Otherwise it is mutable (and returns non-const reference to the n-th channel)
template <typename SrcP> // SrcP is a reference to PixelConcept (could be pixel value or const/non-const reference)
// Examples: pixel<T,L>, pixel<T,L>&, const pixel<T,L>&, planar_pixel_reference<T&,L>, planar_pixel_reference<const T&,L>
struct nth_channel_deref_fn {
BOOST_STATIC_CONSTANT(bool, is_mutable=pixel_is_reference<SrcP>::value && pixel_reference_is_mutable<SrcP>::value);
private:
typedef typename remove_reference<SrcP>::type src_pixel_t;
typedef typename channel_type<src_pixel_t>::type channel_t;
typedef typename src_pixel_t::const_reference const_ref_t;
typedef typename pixel_reference_type<channel_t,gray_layout_t,false,is_mutable>::type ref_t;
public:
typedef nth_channel_deref_fn<const_ref_t> const_t;
typedef typename pixel_value_type<channel_t,gray_layout_t>::type value_type;
typedef typename pixel_reference_type<channel_t,gray_layout_t,false,false>::type const_reference;
typedef SrcP argument_type;
typedef typename mpl::if_c<is_mutable, ref_t, value_type>::type reference;
typedef reference result_type;
nth_channel_deref_fn(int n=0) : _n(n) {}
template <typename P> nth_channel_deref_fn(const nth_channel_deref_fn<P>& d) : _n(d._n) {}
int _n; // the channel to use
result_type operator()(argument_type srcP) const {
return result_type(srcP[_n]);
}
};
template <typename View> struct __nth_channel_view<View,false> {
private:
typedef nth_channel_deref_fn<typename View::reference> deref_t;
typedef typename View::template add_deref<deref_t> AD;
public:
typedef typename AD::type type;
static type make(const View& src, int n) {
return AD::make(src, deref_t(n));
}
};
} // namespace detail
/// \brief Given a source image view type View, returns the type of an image view over a single channel of View
/// \ingroup ImageViewTransformationsNthChannel
///
/// If the channels in the source view are adjacent in memory (such as planar non-step view or single-channel view) then the
/// return view is a single-channel non-step view.
/// If the channels are non-adjacent (interleaved and/or step view) then the return view is a single-channel step view.
template <typename View>
struct nth_channel_view_type {
private:
GIL_CLASS_REQUIRE(View, boost::gil, ImageViewConcept)
typedef detail::__nth_channel_view<View,view_is_basic<View>::value> VB;
public:
typedef typename VB::type type;
static type make(const View& src, int n) { return VB::make(src,n); }
};
/// \ingroup ImageViewTransformationsNthChannel
template <typename View>
typename nth_channel_view_type<View>::type nth_channel_view(const View& src, int n) {
return nth_channel_view_type<View>::make(src,n);
}
/// \defgroup ImageViewTransformationsKthChannel kth_channel_view
/// \ingroup ImageViewTransformations
/// \brief single-channel (grayscale) view of the K-th channel of a given image_view. The channel index is a template parameter
namespace detail {
template <int K, typename View, bool AreChannelsTogether> struct __kth_channel_view_basic;
// kth_channel_view when the channels are not adjacent in memory. This can happen for multi-channel interleaved images
// or images with a step
template <int K, typename View>
struct __kth_channel_view_basic<K,View,false> {
private:
typedef typename kth_element_type<typename View::value_type,K>::type channel_t;
public:
typedef typename view_type<channel_t, gray_layout_t, false, true, view_is_mutable<View>::value>::type type;
static type make(const View& src) {
typedef typename type::xy_locator locator_t;
typedef typename type::x_iterator x_iterator_t;
typedef typename iterator_adaptor_get_base<x_iterator_t>::type x_iterator_base_t;
x_iterator_t sit(x_iterator_base_t(&at_c<K>(src(0,0))),src.pixels().pixel_size());
return type(src.dimensions(),locator_t(sit, src.pixels().row_size()));
}
};
// kth_channel_view when the channels are together in memory (true for simple grayscale or planar images)
template <int K, typename View>
struct __kth_channel_view_basic<K,View,true> {
private:
typedef typename kth_element_type<typename View::value_type, K>::type channel_t;
public:
typedef typename view_type<channel_t, gray_layout_t, false, false, view_is_mutable<View>::value>::type type;
static type make(const View& src) {
typedef typename type::x_iterator x_iterator_t;
return interleaved_view(src.width(),src.height(),(x_iterator_t)&at_c<K>(src(0,0)), src.pixels().row_size());
}
};
template <int K, typename View, bool IsBasic> struct __kth_channel_view;
// For basic (memory-based) views dispatch to __kth_channel_view_basic
template <int K, typename View> struct __kth_channel_view<K,View,true> {
private:
typedef typename View::x_iterator src_x_iterator;
// Determines whether the channels of a given pixel iterator are adjacent in memory.
// Planar and grayscale iterators have channels adjacent in memory, whereas multi-channel interleaved and iterators with non-fundamental step do not.
BOOST_STATIC_CONSTANT(bool, adjacent=
!iterator_is_step<src_x_iterator>::value &&
(is_planar<src_x_iterator>::value ||
num_channels<View>::value==1));
public:
typedef typename __kth_channel_view_basic<K,View,adjacent>::type type;
static type make(const View& src) {
return __kth_channel_view_basic<K,View,adjacent>::make(src);
}
};
/// \brief Function object that returns a grayscale reference of the K-th channel (specified as a template parameter) of a given reference. Models: PixelDereferenceAdaptorConcept.
/// \ingroup PixelDereferenceAdaptorModel
///
/// If the input is a pixel value or constant reference, the function object is immutable. Otherwise it is mutable (and returns non-const reference to the k-th channel)
template <int K, typename SrcP> // SrcP is a reference to PixelConcept (could be pixel value or const/non-const reference)
// Examples: pixel<T,L>, pixel<T,L>&, const pixel<T,L>&, planar_pixel_reference<T&,L>, planar_pixel_reference<const T&,L>
struct kth_channel_deref_fn {
BOOST_STATIC_CONSTANT(bool, is_mutable=pixel_is_reference<SrcP>::value && pixel_reference_is_mutable<SrcP>::value);
private:
typedef typename remove_reference<SrcP>::type src_pixel_t;
typedef typename kth_element_type<src_pixel_t, K>::type channel_t;
typedef typename src_pixel_t::const_reference const_ref_t;
typedef typename pixel_reference_type<channel_t,gray_layout_t,false,is_mutable>::type ref_t;
public:
typedef kth_channel_deref_fn<K,const_ref_t> const_t;
typedef typename pixel_value_type<channel_t,gray_layout_t>::type value_type;
typedef typename pixel_reference_type<channel_t,gray_layout_t,false,false>::type const_reference;
typedef SrcP argument_type;
typedef typename mpl::if_c<is_mutable, ref_t, value_type>::type reference;
typedef reference result_type;
kth_channel_deref_fn() {}
template <typename P> kth_channel_deref_fn(const kth_channel_deref_fn<K,P>&) {}
result_type operator()(argument_type srcP) const {
return result_type(at_c<K>(srcP));
}
};
template <int K, typename View> struct __kth_channel_view<K,View,false> {
private:
typedef kth_channel_deref_fn<K,typename View::reference> deref_t;
typedef typename View::template add_deref<deref_t> AD;
public:
typedef typename AD::type type;
static type make(const View& src) {
return AD::make(src, deref_t());
}
};
} // namespace detail
/// \brief Given a source image view type View, returns the type of an image view over a given channel of View.
/// \ingroup ImageViewTransformationsKthChannel
///
/// If the channels in the source view are adjacent in memory (such as planar non-step view or single-channel view) then the
/// return view is a single-channel non-step view.
/// If the channels are non-adjacent (interleaved and/or step view) then the return view is a single-channel step view.
template <int K, typename View>
struct kth_channel_view_type {
private:
GIL_CLASS_REQUIRE(View, boost::gil, ImageViewConcept)
typedef detail::__kth_channel_view<K,View,view_is_basic<View>::value> VB;
public:
typedef typename VB::type type;
static type make(const View& src) { return VB::make(src); }
};
/// \ingroup ImageViewTransformationsKthChannel
template <int K, typename View>
typename kth_channel_view_type<K,View>::type kth_channel_view(const View& src) {
return kth_channel_view_type<K,View>::make(src);
}
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,175 @@
/*
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_ITERATOR_FROM_2D_H
#define GIL_ITERATOR_FROM_2D_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief pixel step iterator, pixel image iterator and pixel dereference iterator
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on September 18, 2007
///
////////////////////////////////////////////////////////////////////////////////////////
#include <cassert>
#include <boost/iterator/iterator_facade.hpp>
#include "gil_concept.hpp"
#include "gil_config.hpp"
#include "pixel_iterator.hpp"
#include "locator.hpp"
namespace boost { namespace gil {
////////////////////////////////////////////////////////////////////////////////////////
///
/// ITERATOR FROM 2D ADAPTOR
///
////////////////////////////////////////////////////////////////////////////////////////
/// \defgroup PixelIteratorModelFromLocator iterator_from_2d
/// \ingroup PixelIteratorModel
/// \brief An iterator over two-dimensional locator. Useful for iterating over the pixels of an image view. Models PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept
/// \ingroup PixelIteratorModelFromLocator PixelBasedModel
/// \brief Provides 1D random-access navigation to the pixels of the image. Models: PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept
///
/// Pixels are traversed from the top to the bottom row and from the left to the right
/// within each row
template <typename Loc2> // Models PixelLocatorConcept
class iterator_from_2d : public iterator_facade<iterator_from_2d<Loc2>,
typename Loc2::value_type,
random_access_traversal_tag,
typename Loc2::reference,
typename Loc2::coord_t> {
GIL_CLASS_REQUIRE(Loc2, boost::gil, PixelLocatorConcept)
public:
typedef iterator_facade<iterator_from_2d<Loc2>,
typename Loc2::value_type,
random_access_traversal_tag,
typename Loc2::reference,
typename Loc2::coord_t> parent_t;
typedef typename parent_t::reference reference;
typedef typename parent_t::difference_type difference_type;
typedef typename Loc2::x_iterator x_iterator;
typedef typename Loc2::point_t point_t;
std::ptrdiff_t width() const { return _width; } // number of pixels per image row
std::ptrdiff_t x_pos() const { return _coords.x; } // current x position
std::ptrdiff_t y_pos() const { return _coords.y; } // current y position
/// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference
/// We require our own reference because it is registered in iterator_traits
reference operator[](difference_type d) const { return *(*this+d); }
bool is_1d_traversable() const { return _p.is_1d_traversable(width()); } // is there no gap at the end of each row?
x_iterator& x() { return _p.x(); }
iterator_from_2d(){}
iterator_from_2d(const Loc2& p, std::ptrdiff_t width, std::ptrdiff_t x=0, std::ptrdiff_t y=0) : _coords(x,y), _width(width), _p(p) {}
iterator_from_2d(const iterator_from_2d& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
template <typename Loc> iterator_from_2d(const iterator_from_2d<Loc>& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
private:
template <typename Loc> friend class iterator_from_2d;
friend class boost::iterator_core_access;
reference dereference() const { return *_p; }
void increment() {
++_coords.x;
++_p.x();
if (_coords.x>=_width) {
_coords.x=0;
++_coords.y;
_p+=point_t(-_width,1);
}
}
void decrement() {
--_coords.x;
--_p.x();
if (_coords.x<0) {
_coords.x=_width-1;
--_coords.y;
_p+=point_t(_width,-1);
}
}
GIL_FORCEINLINE void advance(difference_type d) {
if (_width==0) return; // unfortunately we need to check for that. Default-constructed images have width of 0 and the code below will throw if executed.
point_t delta;
if (_coords.x+d>=0) { // not going back to a previous row?
delta.x=(_coords.x+(std::ptrdiff_t)d)%_width - _coords.x;
delta.y=(_coords.x+(std::ptrdiff_t)d)/_width;
} else {
delta.x=(_coords.x+(std::ptrdiff_t)d*(1-_width))%_width -_coords.x;
delta.y=-(_width-_coords.x-(std::ptrdiff_t)d-1)/_width;
}
_p+=delta;
_coords.x+=delta.x;
_coords.y+=delta.y;
}
difference_type distance_to(const iterator_from_2d& it) const {
if (_width==0) return 0;
return (it.y_pos()-_coords.y)*_width + (it.x_pos()-_coords.x);
}
bool equal(const iterator_from_2d& it) const {
assert(_width==it.width()); // they must belong to the same image
return _coords==it._coords && _p==it._p;
}
point2<std::ptrdiff_t> _coords;
std::ptrdiff_t _width;
Loc2 _p;
};
template <typename Loc> // Models PixelLocatorConcept
struct const_iterator_type<iterator_from_2d<Loc> > {
typedef iterator_from_2d<typename Loc::const_t> type;
};
template <typename Loc> // Models PixelLocatorConcept
struct iterator_is_mutable<iterator_from_2d<Loc> > : public iterator_is_mutable<typename Loc::x_iterator> {};
/////////////////////////////
// HasDynamicXStepTypeConcept
/////////////////////////////
template <typename Loc>
struct dynamic_x_step_type<iterator_from_2d<Loc> > {
typedef iterator_from_2d<typename dynamic_x_step_type<Loc>::type> type;
};
/////////////////////////////
// PixelBasedConcept
/////////////////////////////
template <typename Loc> // Models PixelLocatorConcept
struct color_space_type<iterator_from_2d<Loc> > : public color_space_type<Loc> {};
template <typename Loc> // Models PixelLocatorConcept
struct channel_mapping_type<iterator_from_2d<Loc> > : public channel_mapping_type<Loc> {};
template <typename Loc> // Models PixelLocatorConcept
struct is_planar<iterator_from_2d<Loc> > : public is_planar<Loc> {};
template <typename Loc> // Models PixelLocatorConcept
struct channel_type<iterator_from_2d<Loc> > : public channel_type<Loc> {};
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,362 @@
/*
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?
// 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

View File

@ -0,0 +1,494 @@
/*
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_METAFUNCTIONS_HPP
#define GIL_METAFUNCTIONS_HPP
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief metafunctions that construct types or return type properties
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
///
/// \date 2005-2007 \n Last updated on February 6, 2007
///
////////////////////////////////////////////////////////////////////////////////////////
#include <iterator>
#include <boost/mpl/accumulate.hpp>
#include <boost/mpl/back.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/pop_back.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits.hpp>
#include "gil_config.hpp"
#include "gil_concept.hpp"
#include "channel.hpp"
namespace boost { namespace gil {
// forward declarations
template <typename T, typename L> struct pixel;
template <typename BitField,typename ChannelRefVec,typename Layout> struct packed_pixel;
template <typename T, typename C> struct planar_pixel_reference;
template <typename IC, typename C> struct planar_pixel_iterator;
template <typename I> class memory_based_step_iterator;
template <typename I> class memory_based_2d_locator;
template <typename L> class image_view;
template <typename Pixel, bool IsPlanar, typename Alloc> class image;
template <typename T> struct channel_type;
template <typename T> struct color_space_type;
template <typename T> struct channel_mapping_type;
template <typename It> struct is_iterator_adaptor;
template <typename It> struct iterator_adaptor_get_base;
template <typename BitField, typename ChannelBitSizes, typename Layout, bool IsMutable> struct bit_aligned_pixel_reference;
//////////////////////////////////////////////////
///
/// TYPE ANALYSIS METAFUNCTIONS
/// Predicate metafunctions determining properties of GIL types
///
//////////////////////////////////////////////////
/// \defgroup GILIsBasic xxx_is_basic
/// \ingroup TypeAnalysis
/// \brief Determines if GIL constructs are basic.
/// Basic constructs are the ones that can be generated with the type
/// factory methods pixel_reference_type, iterator_type, locator_type, view_type and image_type
/// They can be mutable/immutable, planar/interleaved, step/nonstep. They must use GIL-provided models.
/// \brief Determines if a given pixel reference is basic
/// Basic references must use gil::pixel& (if interleaved), gil::planar_pixel_reference (if planar). They must use the standard constness rules.
/// \ingroup GILIsBasic
template <typename PixelRef> struct pixel_reference_is_basic : public mpl::false_ {};
template <typename T, typename L> struct pixel_reference_is_basic< pixel<T,L>&> : public mpl::true_ {};
template <typename T, typename L> struct pixel_reference_is_basic<const pixel<T,L>&> : public mpl::true_ {};
template <typename TR, typename Cs> struct pixel_reference_is_basic<planar_pixel_reference<TR,Cs> > : public mpl::true_ {};
template <typename TR, typename Cs> struct pixel_reference_is_basic<const planar_pixel_reference<TR,Cs> > : public mpl::true_ {};
/// \brief Determines if a given pixel iterator is basic
/// Basic iterators must use gil::pixel (if interleaved), gil::planar_pixel_iterator (if planar) and gil::memory_based_step_iterator (if step). They must use the standard constness rules.
/// \ingroup GILIsBasic
template <typename Iterator>
struct iterator_is_basic : public mpl::false_ {};
template <typename T, typename L> // mutable interleaved
struct iterator_is_basic< pixel<T,L>* > : public mpl::true_ {};
template <typename T, typename L> // immutable interleaved
struct iterator_is_basic<const pixel<T,L>* > : public mpl::true_ {};
template <typename T, typename Cs> // mutable planar
struct iterator_is_basic<planar_pixel_iterator< T*,Cs> > : public mpl::true_ {};
template <typename T, typename Cs> // immutable planar
struct iterator_is_basic<planar_pixel_iterator<const T*,Cs> > : public mpl::true_ {};
template <typename T, typename L> // mutable interleaved step
struct iterator_is_basic<memory_based_step_iterator< pixel<T,L>*> > : public mpl::true_ {};
template <typename T, typename L> // immutable interleaved step
struct iterator_is_basic<memory_based_step_iterator<const pixel<T,L>*> > : public mpl::true_ {};
template <typename T, typename Cs> // mutable planar step
struct iterator_is_basic<memory_based_step_iterator<planar_pixel_iterator< T*,Cs> > > : public mpl::true_ {};
template <typename T, typename Cs> // immutable planar step
struct iterator_is_basic<memory_based_step_iterator<planar_pixel_iterator<const T*,Cs> > > : public mpl::true_ {};
/// \ingroup GILIsBasic
/// \brief Determines if a given locator is basic. A basic locator is memory-based and has basic x_iterator and y_iterator
template <typename Loc> struct locator_is_basic : public mpl::false_ {};
template <typename Iterator> struct locator_is_basic<memory_based_2d_locator<memory_based_step_iterator<Iterator> > > : public iterator_is_basic<Iterator> {};
/// \ingroup GILIsBasic
/// \brief Basic views must be over basic locators
template <typename View> struct view_is_basic : public mpl::false_ {};
template <typename Loc> struct view_is_basic<image_view<Loc> > : public locator_is_basic<Loc> {};
/// \ingroup GILIsBasic
/// \brief Basic images must use basic views and std::allocator of char
template <typename Img> struct image_is_basic : public mpl::false_ {};
template <typename Pixel, bool IsPlanar, typename Alloc> struct image_is_basic<image<Pixel,IsPlanar,Alloc> > : public mpl::true_ {};
/// \defgroup GILIsStep xxx_is_step
/// \ingroup TypeAnalysis
/// \brief Determines if the given iterator/locator/view has a step that could be set dynamically
template <typename I> struct iterator_is_step;
namespace detail {
template <typename It, bool IsBase, bool EqualsStepType> struct iterator_is_step_impl;
// iterator that has the same type as its dynamic_x_step_type must be a step iterator
template <typename It, bool IsBase> struct iterator_is_step_impl<It,IsBase,true> : public mpl::true_{};
// base iterator can never be a step iterator
template <typename It> struct iterator_is_step_impl<It,true,false> : public mpl::false_{};
// for an iterator adaptor, see if its base is step
template <typename It> struct iterator_is_step_impl<It,false,false>
: public iterator_is_step<typename iterator_adaptor_get_base<It>::type>{};
}
/// \ingroup GILIsStep
/// \brief Determines if the given iterator has a step that could be set dynamically
template <typename I> struct iterator_is_step
: public detail::iterator_is_step_impl<I,
!is_iterator_adaptor<I>::type::value,
is_same<I,typename dynamic_x_step_type<I>::type>::value >{};
/// \ingroup GILIsStep
/// \brief Determines if the given locator has a horizontal step that could be set dynamically
template <typename L> struct locator_is_step_in_x : public iterator_is_step<typename L::x_iterator> {};
/// \ingroup GILIsStep
/// \brief Determines if the given locator has a vertical step that could be set dynamically
template <typename L> struct locator_is_step_in_y : public iterator_is_step<typename L::y_iterator> {};
/// \ingroup GILIsStep
/// \brief Determines if the given view has a horizontal step that could be set dynamically
template <typename V> struct view_is_step_in_x : public locator_is_step_in_x<typename V::xy_locator> {};
/// \ingroup GILIsStep
/// \brief Determines if the given view has a vertical step that could be set dynamically
template <typename V> struct view_is_step_in_y : public locator_is_step_in_y<typename V::xy_locator> {};
/// \brief Determines whether the given pixel reference is a proxy class or a native C++ reference
/// \ingroup TypeAnalysis
template <typename PixelReference>
struct pixel_reference_is_proxy
: public mpl::not_<is_same<typename remove_const_and_reference<PixelReference>::type,
typename remove_const_and_reference<PixelReference>::type::value_type> > {};
/// \brief Given a model of a pixel, determines whether the model represents a pixel reference (as opposed to pixel value)
/// \ingroup TypeAnalysis
template <typename Pixel>
struct pixel_is_reference : public mpl::or_<is_reference<Pixel>, pixel_reference_is_proxy<Pixel> > {};
/// \defgroup GILIsMutable xxx_is_mutable
/// \ingroup TypeAnalysis
/// \brief Determines if the given pixel reference/iterator/locator/view is mutable (i.e. its pixels can be changed)
/// \ingroup GILIsMutable
/// \brief Determines if the given pixel reference is mutable (i.e. its channels can be changed)
///
/// Note that built-in C++ references obey the const qualifier but reference proxy classes do not.
template <typename R> struct pixel_reference_is_mutable : public mpl::bool_<remove_reference<R>::type::is_mutable> {};
template <typename R> struct pixel_reference_is_mutable<const R&>
: public mpl::and_<pixel_reference_is_proxy<R>, pixel_reference_is_mutable<R> > {};
/// \ingroup GILIsMutable
/// \brief Determines if the given locator is mutable (i.e. its pixels can be changed)
template <typename L> struct locator_is_mutable : public iterator_is_mutable<typename L::x_iterator> {};
/// \ingroup GILIsMutable
/// \brief Determines if the given view is mutable (i.e. its pixels can be changed)
template <typename V> struct view_is_mutable : public iterator_is_mutable<typename V::x_iterator> {};
//////////////////////////////////////////////////
///
/// TYPE FACTORY METAFUNCTIONS
/// Metafunctions returning GIL types from other GIL types
///
//////////////////////////////////////////////////
/// \defgroup TypeFactoryFromElements xxx_type
/// \ingroup TypeFactory
/// \brief Returns the type of a homogeneous GIL construct given its elements (channel, layout, whether it is planar, step, mutable, etc.)
/// \defgroup TypeFactoryFromPixel xxx_type_from_pixel
/// \ingroup TypeFactory
/// \brief Returns the type of a GIL construct given its pixel type, whether it is planar, step, mutable, etc.
/// \defgroup TypeFactoryDerived derived_xxx_type
/// \ingroup TypeFactory
/// \brief Returns the type of a homogeneous GIL construct given a related construct by changing some of its properties
/// \ingroup TypeFactoryFromElements
/// \brief Returns the type of a homogeneous pixel reference given the channel type, layout, whether it operates on planar data and whether it is mutable
template <typename T, typename L, bool IsPlanar=false, bool IsMutable=true> struct pixel_reference_type{};
template <typename T, typename L> struct pixel_reference_type<T,L,false,true > { typedef pixel<T,L>& type; };
template <typename T, typename L> struct pixel_reference_type<T,L,false,false> { typedef const pixel<T,L>& type; };
template <typename T, typename L> struct pixel_reference_type<T,L,true,true> { typedef const planar_pixel_reference<typename channel_traits<T>::reference,typename color_space_type<L>::type> type; }; // TODO: Assert M=identity
template <typename T, typename L> struct pixel_reference_type<T,L,true,false> { typedef const planar_pixel_reference<typename channel_traits<T>::const_reference,typename color_space_type<L>::type> type; };// TODO: Assert M=identity
/// \ingroup TypeFactoryFromPixel
/// \brief Returns the type of a pixel iterator given the pixel type, whether it operates on planar data, whether it is a step iterator, and whether it is mutable
template <typename Pixel, bool IsPlanar=false, bool IsStep=false, bool IsMutable=true> struct iterator_type_from_pixel{};
template <typename Pixel> struct iterator_type_from_pixel<Pixel,false,false,true > { typedef Pixel* type; };
template <typename Pixel> struct iterator_type_from_pixel<Pixel,false,false,false> { typedef const Pixel* type; };
template <typename Pixel> struct iterator_type_from_pixel<Pixel,true,false,true> {
typedef planar_pixel_iterator<typename channel_traits<typename channel_type<Pixel>::type>::pointer,typename color_space_type<Pixel>::type> type;
};
template <typename Pixel> struct iterator_type_from_pixel<Pixel,true,false,false> {
typedef planar_pixel_iterator<typename channel_traits<typename channel_type<Pixel>::type>::const_pointer,typename color_space_type<Pixel>::type> type;
};
template <typename Pixel, bool IsPlanar, bool IsMutable> struct iterator_type_from_pixel<Pixel,IsPlanar,true,IsMutable> {
typedef memory_based_step_iterator<typename iterator_type_from_pixel<Pixel,IsPlanar,false,IsMutable>::type> type;
};
/// \ingroup TypeFactoryFromElements
/// \brief Returns the type of a homogeneous iterator given the channel type, layout, whether it operates on planar data, whether it is a step iterator, and whether it is mutable
template <typename T, typename L, bool IsPlanar=false, bool IsStep=false, bool IsMutable=true> struct iterator_type{};
template <typename T, typename L> struct iterator_type<T,L,false,false,true > { typedef pixel<T,L>* type; };
template <typename T, typename L> struct iterator_type<T,L,false,false,false> { typedef const pixel<T,L>* type; };
template <typename T, typename L> struct iterator_type<T,L,true,false,true> { typedef planar_pixel_iterator<T*,typename L::color_space_t> type; }; // TODO: Assert M=identity
template <typename T, typename L> struct iterator_type<T,L,true,false,false> { typedef planar_pixel_iterator<const T*,typename L::color_space_t> type; }; // TODO: Assert M=identity
template <typename T, typename L, bool IsPlanar, bool IsMutable> struct iterator_type<T,L,IsPlanar,true,IsMutable> {
typedef memory_based_step_iterator<typename iterator_type<T,L,IsPlanar,false,IsMutable>::type> type;
};
/// \brief Given a pixel iterator defining access to pixels along a row, returns the types of the corresponding built-in step_iterator, xy_locator, image_view
/// \ingroup TypeFactory
template <typename XIterator>
struct type_from_x_iterator {
typedef memory_based_step_iterator<XIterator> step_iterator_t;
typedef memory_based_2d_locator<step_iterator_t> xy_locator_t;
typedef image_view<xy_locator_t> view_t;
};
namespace detail {
template <typename BitField, typename FirstBit, typename NumBits>
struct packed_channel_reference_type {
typedef const packed_channel_reference<BitField,FirstBit::value,NumBits::value,true> type;
};
template <typename BitField, typename ChannelBitSizesVector>
class packed_channel_references_vector_type {
// If ChannelBitSizesVector is mpl::vector<int,7,7,2>
// Then first_bits_vector will be mpl::vector<int,0,7,14,16>
typedef typename mpl::accumulate<ChannelBitSizesVector, mpl::vector1<mpl::int_<0> >,
mpl::push_back<mpl::_1, mpl::plus<mpl::back<mpl::_1>, mpl::_2> > >::type first_bits_vector;
public:
typedef typename mpl::transform<typename mpl::pop_back<first_bits_vector>::type, ChannelBitSizesVector,
packed_channel_reference_type<BitField, mpl::_1,mpl::_2> >::type type;
};
}
/// \ingroup TypeFactoryFromElements
/// \brief Returns the type of a packed pixel given its bitfield type, the bit size of its channels and its layout.
///
/// A packed pixel has channels that cover bit ranges but itself is byte aligned. RGB565 pixel is an example.
///
/// The size of ChannelBitSizeVector must equal the number of channels in the given layout
/// The sum of bit sizes for all channels must be less than or equal to the number of bits in BitField (and cannot exceed 64).
/// If it is less than the number of bits in BitField, the last bits will be unused.
template <typename BitField, typename ChannelBitSizeVector, typename Layout>
struct packed_pixel_type {
typedef packed_pixel<BitField, typename detail::packed_channel_references_vector_type<BitField,ChannelBitSizeVector>::type, Layout> type;
};
/// \defgroup TypeFactoryPacked packed_image_type,bit_aligned_image_type
/// \ingroup TypeFactoryFromElements
/// \brief Returns the type of an image whose channels are not byte-aligned.
///
/// A packed image is an image whose pixels are byte aligned, such as "rgb565". <br>
/// A bit-aligned image is an image whose pixels are not byte aligned, such as "rgb222". <br>
///
/// The sum of the bit sizes of all channels cannot exceed 64.
/// \ingroup TypeFactoryPacked
/// \brief Returns the type of an interleaved packed image: an image whose channels may not be byte-aligned, but whose pixels are byte aligned.
template <typename BitField, typename ChannelBitSizeVector, typename Layout, typename Alloc=std::allocator<unsigned char> >
struct packed_image_type {
typedef image<typename packed_pixel_type<BitField,ChannelBitSizeVector,Layout>::type,false,Alloc> type;
};
/// \ingroup TypeFactoryPacked
/// \brief Returns the type of a single-channel image given its bitfield type, the bit size of its channel and its layout
template <typename BitField, unsigned Size1, typename Layout, typename Alloc=std::allocator<unsigned char> >
struct packed_image1_type : public packed_image_type<BitField, mpl::vector1_c<unsigned, Size1>, Layout, Alloc> {};
/// \ingroup TypeFactoryPacked
/// \brief Returns the type of a two channel image given its bitfield type, the bit size of its channels and its layout
template <typename BitField, unsigned Size1, unsigned Size2, typename Layout, typename Alloc=std::allocator<unsigned char> >
struct packed_image2_type : public packed_image_type<BitField, mpl::vector2_c<unsigned, Size1, Size2>, Layout, Alloc> {};
/// \ingroup TypeFactoryPacked
/// \brief Returns the type of a three channel image given its bitfield type, the bit size of its channels and its layout
template <typename BitField, unsigned Size1, unsigned Size2, unsigned Size3, typename Layout, typename Alloc=std::allocator<unsigned char> >
struct packed_image3_type : public packed_image_type<BitField, mpl::vector3_c<unsigned, Size1, Size2, Size3>, Layout, Alloc> {};
/// \ingroup TypeFactoryPacked
/// \brief Returns the type of a four channel image given its bitfield type, the bit size of its channels and its layout
template <typename BitField, unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, typename Layout, typename Alloc=std::allocator<unsigned char> >
struct packed_image4_type : public packed_image_type<BitField, mpl::vector4_c<unsigned, Size1, Size2, Size3, Size4>, Layout, Alloc> {};
/// \ingroup TypeFactoryPacked
/// \brief Returns the type of a five channel image given its bitfield type, the bit size of its channels and its layout
template <typename BitField, unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, unsigned Size5, typename Layout, typename Alloc=std::allocator<unsigned char> >
struct packed_image5_type : public packed_image_type<BitField, mpl::vector5_c<unsigned, Size1, Size2, Size3, Size4, Size5>, Layout, Alloc> {};
/// \ingroup TypeFactoryPacked
/// \brief Returns the type of a packed image whose pixels may not be byte aligned. For example, an "rgb222" image is bit-aligned because its pixel spans six bits.
///
/// Note that the alignment parameter in the constructor of bit-aligned images is in bit units. For example, if you want to construct a bit-aligned
/// image whose rows are byte-aligned, use 8 as the alignment parameter, not 1.
template <typename ChannelBitSizeVector, typename Layout, typename Alloc=std::allocator<unsigned char> >
struct bit_aligned_image_type {
private:
BOOST_STATIC_CONSTANT(int, bit_size = (mpl::accumulate<ChannelBitSizeVector, mpl::int_<0>, mpl::plus<mpl::_1, mpl::_2> >::type::value));
typedef typename detail::min_fast_uint<bit_size+7>::type bitfield_t;
typedef const bit_aligned_pixel_reference<bitfield_t, ChannelBitSizeVector, Layout, true> bit_alignedref_t;
public:
typedef image<bit_alignedref_t,false,Alloc> type;
};
/// \ingroup TypeFactoryPacked
/// \brief Returns the type of a single-channel bit-aligned image given the bit size of its channel and its layout
template <unsigned Size1, typename Layout, typename Alloc=std::allocator<unsigned char> >
struct bit_aligned_image1_type : public bit_aligned_image_type<mpl::vector1_c<unsigned, Size1>, Layout, Alloc> {};
/// \ingroup TypeFactoryPacked
/// \brief Returns the type of a two channel bit-aligned image given the bit size of its channels and its layout
template <unsigned Size1, unsigned Size2, typename Layout, typename Alloc=std::allocator<unsigned char> >
struct bit_aligned_image2_type : public bit_aligned_image_type<mpl::vector2_c<unsigned, Size1, Size2>, Layout, Alloc> {};
/// \ingroup TypeFactoryPacked
/// \brief Returns the type of a three channel bit-aligned image given the bit size of its channels and its layout
template <unsigned Size1, unsigned Size2, unsigned Size3, typename Layout, typename Alloc=std::allocator<unsigned char> >
struct bit_aligned_image3_type : public bit_aligned_image_type<mpl::vector3_c<unsigned, Size1, Size2, Size3>, Layout, Alloc> {};
/// \ingroup TypeFactoryPacked
/// \brief Returns the type of a four channel bit-aligned image given the bit size of its channels and its layout
template <unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, typename Layout, typename Alloc=std::allocator<unsigned char> >
struct bit_aligned_image4_type : public bit_aligned_image_type<mpl::vector4_c<unsigned, Size1, Size2, Size3, Size4>, Layout, Alloc> {};
/// \ingroup TypeFactoryPacked
/// \brief Returns the type of a five channel bit-aligned image given the bit size of its channels and its layout
template <unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, unsigned Size5, typename Layout, typename Alloc=std::allocator<unsigned char> >
struct bit_aligned_image5_type : public bit_aligned_image_type<mpl::vector5_c<unsigned, Size1, Size2, Size3, Size4, Size5>, Layout, Alloc> {};
/// \ingroup TypeFactoryFromElements
/// \brief Returns the type of a homogeneous pixel given the channel type and layout
template <typename Channel, typename Layout>
struct pixel_value_type {
typedef pixel<Channel,Layout> type; // by default use gil::pixel. Specializations are provided for
};
// Specializations for packed channels
template <typename BitField, int NumBits, bool IsMutable, typename Layout>
struct pixel_value_type< packed_dynamic_channel_reference<BitField,NumBits,IsMutable>,Layout> :
public packed_pixel_type<BitField, mpl::vector1_c<unsigned,NumBits>, Layout> {};
template <typename BitField, int NumBits, bool IsMutable, typename Layout>
struct pixel_value_type<const packed_dynamic_channel_reference<BitField,NumBits,IsMutable>,Layout> :
public packed_pixel_type<BitField, mpl::vector1_c<unsigned,NumBits>, Layout> {};
template <typename BitField, int FirstBit, int NumBits, bool IsMutable, typename Layout>
struct pixel_value_type< packed_channel_reference<BitField,FirstBit,NumBits,IsMutable>,Layout> :
public packed_pixel_type<BitField, mpl::vector1_c<unsigned,NumBits>, Layout> {};
template <typename BitField, int FirstBit, int NumBits, bool IsMutable, typename Layout>
struct pixel_value_type<const packed_channel_reference<BitField,FirstBit,NumBits,IsMutable>,Layout> :
public packed_pixel_type<BitField, mpl::vector1_c<unsigned,NumBits>, Layout> {};
template <int NumBits, typename Layout>
struct pixel_value_type<packed_channel_value<NumBits>,Layout> :
public packed_pixel_type<typename detail::min_fast_uint<NumBits>::type, mpl::vector1_c<unsigned,NumBits>, Layout> {};
/// \ingroup TypeFactoryFromElements
/// \brief Returns the type of a homogeneous locator given the channel type, layout, whether it operates on planar data and whether it has a step horizontally
template <typename T, typename L, bool IsPlanar=false, bool IsStepX=false, bool IsMutable=true>
struct locator_type {
typedef typename type_from_x_iterator<typename iterator_type<T,L,IsPlanar,IsStepX,IsMutable>::type>::xy_locator_type type;
};
/// \ingroup TypeFactoryFromElements
/// \brief Returns the type of a homogeneous view given the channel type, layout, whether it operates on planar data and whether it has a step horizontally
template <typename T, typename L, bool IsPlanar=false, bool IsStepX=false, bool IsMutable=true>
struct view_type {
typedef typename type_from_x_iterator<typename iterator_type<T,L,IsPlanar,IsStepX,IsMutable>::type>::view_t type;
};
/// \ingroup TypeFactoryFromElements
/// \brief Returns the type of a homogeneous image given the channel type, layout, and whether it operates on planar data
template <typename T, typename L, bool IsPlanar=false, typename Alloc=std::allocator<unsigned char> >
struct image_type {
typedef image<pixel<T,L>, IsPlanar, Alloc> type;
};
/// \ingroup TypeFactoryFromPixel
/// \brief Returns the type of a view the pixel type, whether it operates on planar data and whether it has a step horizontally
template <typename Pixel, bool IsPlanar=false, bool IsStepX=false, bool IsMutable=true>
struct view_type_from_pixel {
typedef typename type_from_x_iterator<typename iterator_type_from_pixel<Pixel,IsPlanar,IsStepX,IsMutable>::type>::view_t type;
};
/// \brief Constructs a pixel reference type from a source pixel reference type by changing some of the properties.
/// \ingroup TypeFactoryDerived
/// Use use_default for the properties of the source view that you want to keep
template <typename Ref, typename T=use_default, typename L=use_default, typename IsPlanar=use_default, typename IsMutable=use_default>
class derived_pixel_reference_type {
typedef typename remove_reference<Ref>::type pixel_t;
typedef typename mpl::if_<is_same<T, use_default>, typename channel_type<pixel_t>::type, T >::type channel_t;
typedef typename mpl::if_<is_same<L, use_default>,
layout<typename color_space_type<pixel_t>::type, typename channel_mapping_type<pixel_t>::type>, L>::type layout_t;
static const bool mut =mpl::if_<is_same<IsMutable,use_default>, pixel_reference_is_mutable<Ref>, IsMutable>::type::value;
static const bool planar=mpl::if_<is_same<IsPlanar,use_default>, is_planar<pixel_t>, IsPlanar>::type::value;
public:
typedef typename pixel_reference_type<channel_t, layout_t, planar, mut>::type type;
};
/// \brief Constructs a pixel iterator type from a source pixel iterator type by changing some of the properties.
/// \ingroup TypeFactoryDerived
/// Use use_default for the properties of the source view that you want to keep
template <typename Iterator, typename T=use_default, typename L=use_default, typename IsPlanar=use_default, typename IsStep=use_default, typename IsMutable=use_default>
class derived_iterator_type {
typedef typename mpl::if_<is_same<T ,use_default>, typename channel_type<Iterator>::type, T >::type channel_t;
typedef typename mpl::if_<is_same<L,use_default>,
layout<typename color_space_type<Iterator>::type, typename channel_mapping_type<Iterator>::type>, L>::type layout_t;
static const bool mut =mpl::if_<is_same<IsMutable,use_default>, iterator_is_mutable<Iterator>, IsMutable>::type::value;
static const bool planar=mpl::if_<is_same<IsPlanar,use_default>, is_planar<Iterator>, IsPlanar>::type::value;
static const bool step =mpl::if_<is_same<IsStep ,use_default>, iterator_is_step<Iterator>, IsStep>::type::value;
public:
typedef typename iterator_type<channel_t, layout_t, planar, step, mut>::type type;
};
/// \brief Constructs an image view type from a source view type by changing some of the properties.
/// \ingroup TypeFactoryDerived
/// Use use_default for the properties of the source view that you want to keep
template <typename View, typename T=use_default, typename L=use_default, typename IsPlanar=use_default, typename StepX=use_default, typename IsMutable=use_default>
class derived_view_type {
typedef typename mpl::if_<is_same<T ,use_default>, typename channel_type<View>::type, T>::type channel_t;
typedef typename mpl::if_<is_same<L,use_default>,
layout<typename color_space_type<View>::type, typename channel_mapping_type<View>::type>, L>::type layout_t;
static const bool mut =mpl::if_<is_same<IsMutable,use_default>, view_is_mutable<View>, IsMutable>::type::value;
static const bool planar=mpl::if_<is_same<IsPlanar,use_default>, is_planar<View>, IsPlanar>::type::value;
static const bool step =mpl::if_<is_same<StepX ,use_default>, view_is_step_in_x<View>,StepX>::type::value;
public:
typedef typename view_type<channel_t, layout_t, planar, step, mut>::type type;
};
/// \brief Constructs a homogeneous image type from a source image type by changing some of the properties.
/// \ingroup TypeFactoryDerived
/// Use use_default for the properties of the source image that you want to keep
template <typename Image, typename T=use_default, typename L=use_default, typename IsPlanar=use_default>
class derived_image_type {
typedef typename mpl::if_<is_same<T ,use_default>, typename channel_type<Image>::type, T >::type channel_t;
typedef typename mpl::if_<is_same<L,use_default>,
layout<typename color_space_type<Image>::type, typename channel_mapping_type<Image>::type>, L>::type layout_t;
static const bool planar=mpl::if_<is_same<IsPlanar,use_default>, is_planar<Image>, IsPlanar>::type::value;
public:
typedef typename image_type<channel_t, layout_t, planar>::type type;
};
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,193 @@
/*
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_PACKED_PIXEL_H
#define GIL_PACKED_PIXEL_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief A model of a heterogeneous pixel whose channels are bit ranges. For example 16-bit RGB in '565' format
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on September 28, 2006
///
////////////////////////////////////////////////////////////////////////////////////////
#include <functional>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/front.hpp>
#include "gil_config.hpp"
#include "pixel.hpp"
namespace boost { namespace gil {
/// \defgroup ColorBaseModelPackedPixel packed_pixel
/// \ingroup ColorBaseModel
/// \brief A heterogeneous color base whose elements are reference proxies to channels in a pixel. Models ColorBaseValueConcept. This class is used to model packed pixels, such as 16-bit packed RGB.
/**
\defgroup PixelModelPackedPixel packed_pixel
\ingroup PixelModel
\brief A heterogeneous pixel used to represent packed pixels with non-byte-aligned channels. Models PixelValueConcept
Example:
\code
typedef packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,5,6,5>, rgb_layout_t>::type rgb565_pixel_t;
BOOST_STATIC_ASSERT((sizeof(rgb565_pixel_t)==2));
rgb565_pixel_t r565;
get_color(r565,red_t()) = 31;
get_color(r565,green_t()) = 63;
get_color(r565,blue_t()) = 31;
assert(r565 == rgb565_pixel_t((uint16_t)0xFFFF));
\endcode
*/
/// \ingroup ColorBaseModelPackedPixel PixelModelPackedPixel PixelBasedModel
/// \brief Heterogeneous pixel value whose channel references can be constructed from the pixel bitfield and their index. Models ColorBaseValueConcept, PixelValueConcept, PixelBasedConcept
/// Typical use for this is a model of a packed pixel (like 565 RGB)
template <typename BitField, // A type that holds the bits of the pixel. Typically an integral type, like boost::uint16_t
typename ChannelRefVec, // An MPL vector whose elements are packed channels. They must be constructible from BitField. GIL uses packed_channel_reference
typename Layout> // Layout defining the color space and ordering of the channels. Example value: rgb_layout_t
struct packed_pixel {
BitField _bitfield;
typedef Layout layout_t;
typedef packed_pixel value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
BOOST_STATIC_CONSTANT(bool, is_mutable = channel_traits<typename mpl::front<ChannelRefVec>::type>::is_mutable);
packed_pixel(){}
explicit packed_pixel(const BitField& bitfield) : _bitfield(bitfield) {}
// Construct from another compatible pixel type
packed_pixel(const packed_pixel& p) : _bitfield(p._bitfield) {}
template <typename P> packed_pixel(const P& p, typename enable_if_c<is_pixel<P>::value>::type* d=0) { check_compatible<P>(); static_copy(p,*this); }
packed_pixel(int chan0, int chan1) : _bitfield(0) {
BOOST_STATIC_ASSERT((num_channels<packed_pixel>::value==2));
at_c<0>(*this)=chan0; at_c<1>(*this)=chan1;
}
packed_pixel(int chan0, int chan1, int chan2) : _bitfield(0) {
BOOST_STATIC_ASSERT((num_channels<packed_pixel>::value==3));
at_c<0>(*this)=chan0; at_c<1>(*this)=chan1; at_c<2>(*this)=chan2;
}
packed_pixel(int chan0, int chan1, int chan2, int chan3) : _bitfield(0) {
BOOST_STATIC_ASSERT((num_channels<packed_pixel>::value==4));
at_c<0>(*this)=chan0; at_c<1>(*this)=chan1; at_c<2>(*this)=chan2; at_c<2>(*this)=chan3;
}
packed_pixel(int chan0, int chan1, int chan2, int chan3, int chan4) : _bitfield(0) {
BOOST_STATIC_ASSERT((num_channels<packed_pixel>::value==5));
at_c<0>(*this)=chan0; at_c<1>(*this)=chan1; at_c<2>(*this)=chan2; at_c<2>(*this)=chan3; at_c<3>(*this)=chan4;
}
packed_pixel& operator=(const packed_pixel& p) { _bitfield=p._bitfield; return *this; }
template <typename P> packed_pixel& operator=(const P& p) { assign(p, mpl::bool_<is_pixel<P>::value>()); return *this; }
template <typename P> bool operator==(const P& p) const { return equal(p, mpl::bool_<is_pixel<P>::value>()); }
template <typename P> bool operator!=(const P& p) const { return !(*this==p); }
private:
template <typename Pixel> static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel,packed_pixel> >(); }
template <typename Pixel> void assign(const Pixel& p, mpl::true_) { check_compatible<Pixel>(); static_copy(p,*this); }
template <typename Pixel> bool equal(const Pixel& p, mpl::true_) const { check_compatible<Pixel>(); return static_equal(*this,p); }
// Support for assignment/equality comparison of a channel with a grayscale pixel
static void check_gray() { BOOST_STATIC_ASSERT((is_same<typename Layout::color_space_t, gray_t>::value)); }
template <typename Channel> void assign(const Channel& chan, mpl::false_) { check_gray(); at_c<0>(*this)=chan; }
template <typename Channel> bool equal (const Channel& chan, mpl::false_) const { check_gray(); return at_c<0>(*this)==chan; }
public:
packed_pixel& operator= (int chan) { check_gray(); at_c<0>(*this)=chan; return *this; }
bool operator==(int chan) const { check_gray(); return at_c<0>(*this)==chan; }
};
/////////////////////////////
// ColorBasedConcept
/////////////////////////////
template <typename BitField, typename ChannelRefVec, typename Layout, int K>
struct kth_element_type<packed_pixel<BitField,ChannelRefVec,Layout>,K> : public mpl::at_c<ChannelRefVec,K> {};
template <typename BitField, typename ChannelRefVec, typename Layout, int K>
struct kth_element_reference_type<packed_pixel<BitField,ChannelRefVec,Layout>,K> : public mpl::at_c<ChannelRefVec,K> {};
template <typename BitField, typename ChannelRefVec, typename Layout, int K>
struct kth_element_const_reference_type<packed_pixel<BitField,ChannelRefVec,Layout>,K> {
typedef typename channel_traits<typename mpl::at_c<ChannelRefVec,K>::type>::const_reference type;
};
template <int K, typename P, typename C, typename L> inline
typename kth_element_reference_type<packed_pixel<P,C,L>, K>::type
at_c(packed_pixel<P,C,L>& p) {
return typename kth_element_reference_type<packed_pixel<P,C,L>, K>::type(&p._bitfield);
}
template <int K, typename P, typename C, typename L> inline
typename kth_element_const_reference_type<packed_pixel<P,C,L>, K>::type
at_c(const packed_pixel<P,C,L>& p) {
return typename kth_element_const_reference_type<packed_pixel<P,C,L>, K>::type(&p._bitfield);
}
/////////////////////////////
// PixelConcept
/////////////////////////////
// Metafunction predicate that flags packed_pixel as a model of PixelConcept. Required by PixelConcept
template <typename BitField, typename ChannelRefVec, typename Layout>
struct is_pixel<packed_pixel<BitField,ChannelRefVec,Layout> > : public mpl::true_{};
/////////////////////////////
// PixelBasedConcept
/////////////////////////////
template <typename P, typename C, typename Layout>
struct color_space_type<packed_pixel<P,C,Layout> > {
typedef typename Layout::color_space_t type;
};
template <typename P, typename C, typename Layout>
struct channel_mapping_type<packed_pixel<P,C,Layout> > {
typedef typename Layout::channel_mapping_t type;
};
template <typename P, typename C, typename Layout>
struct is_planar<packed_pixel<P,C,Layout> > : mpl::false_ {};
////////////////////////////////////////////////////////////////////////////////
///
/// Support for interleaved iterators over packed pixel
///
////////////////////////////////////////////////////////////////////////////////
/// \defgroup PixelIteratorModelPackedInterleavedPtr Pointer to packed_pixel<P,CR,Layout>
/// \ingroup PixelIteratorModel
/// \brief Iterators over interleaved pixels.
/// The pointer packed_pixel<P,CR,Layout>* is used as an iterator over interleaved pixels of packed format. Models PixelIteratorConcept, HasDynamicXStepTypeConcept, MemoryBasedIteratorConcept
template <typename P, typename C, typename L>
struct iterator_is_mutable<packed_pixel<P,C,L>*> : public mpl::bool_<packed_pixel<P,C,L>::is_mutable> {};
template <typename P, typename C, typename L>
struct iterator_is_mutable<const packed_pixel<P,C,L>*> : public mpl::false_ {};
} } // namespace boost::gil
namespace boost {
template <typename P, typename C, typename L>
struct has_trivial_constructor<gil::packed_pixel<P,C,L> > : public has_trivial_constructor<P> {};
}
#endif

212
src/3rdparty/include/boost/gil/pixel.hpp vendored Normal file
View File

@ -0,0 +1,212 @@
/*
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_PIXEL_H
#define GIL_PIXEL_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief pixel class and related utilities
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on September 28, 2006
///
////////////////////////////////////////////////////////////////////////////////////////
#include <functional>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/front.hpp>
#include <boost/type_traits.hpp>
#include "gil_config.hpp"
#include "color_base.hpp"
#include "gil_concept.hpp"
#include "channel.hpp"
#include "metafunctions.hpp"
#include "utilities.hpp"
#include "color_base_algorithm.hpp"
namespace boost { namespace gil {
// Forward-declare gray_t
struct gray_color_t;
typedef mpl::vector1<gray_color_t> gray_t;
template <typename PixelBased> struct color_space_type;
template <typename PixelBased> struct channel_mapping_type;
template <typename PixelBased> struct channel_type;
template <typename PixelBased> struct is_planar;
template <typename PixelBased> struct color_space_type<const PixelBased> : public color_space_type<PixelBased> {};
template <typename PixelBased> struct channel_mapping_type<const PixelBased> : public channel_mapping_type<PixelBased> {};
template <typename PixelBased> struct channel_type<const PixelBased> : public channel_type<PixelBased> {};
template <typename PixelBased> struct is_planar<const PixelBased> : public is_planar<PixelBased> {};
template <typename T> struct is_pixel : public mpl::false_{};
template <typename T> struct is_pixel<const T> : public is_pixel<T> {};
/// \ingroup PixelBasedAlgorithm
/// \brief Returns the number of channels of a pixel-based GIL construct
template <typename PixelBased>
struct num_channels : public mpl::size<typename color_space_type<PixelBased>::type> {};
/**
\addtogroup PixelBasedAlgorithm
Example:
\code
BOOST_STATIC_ASSERT((num_channels<rgb8_view_t>::value==3));
BOOST_STATIC_ASSERT((num_channels<cmyk16_planar_ptr_t>::value==4));
BOOST_STATIC_ASSERT((is_planar<rgb16_planar_image_t>::value));
BOOST_STATIC_ASSERT((is_same<color_space_type<rgb8_planar_ref_t>::type, rgb_t>::value));
BOOST_STATIC_ASSERT((is_same<channel_mapping_type<cmyk8_pixel_t>::type,
channel_mapping_type<rgba8_pixel_t>::type>::value));
BOOST_STATIC_ASSERT((is_same<channel_type<bgr8_pixel_t>::type, bits8>::value));
\endcode
*/
/// \defgroup ColorBaseModelPixel pixel
/// \ingroup ColorBaseModel
/// \brief A homogeneous color base whose element is a channel value. Models HomogeneousColorBaseValueConcept
/// \defgroup PixelModelPixel pixel
/// \ingroup PixelModel
/// \brief A homogeneous pixel value. Models HomogeneousPixelValueConcept
/// \ingroup PixelModelPixel ColorBaseModelPixel PixelBasedModel
/// \brief Represents a pixel value (a container of channels). Models: HomogeneousColorBaseValueConcept, PixelValueConcept, HomogeneousPixelBasedConcept
///
/// A pixel is a set of channels defining the color at a given point in an image. Conceptually, a pixel is little more than a color base whose elements
/// model \p ChannelConcept. The class \p pixel defines a simple, homogeneous pixel value. It is used to store
/// the value of a color. The built-in C++ references to \p pixel, \p pixel& and \p const \p pixel& are used to represent a reference to a pixel
/// inside an interleaved image view (a view in which all channels are together in memory). Similarly, built-in pointer types \p pixel* and \p const \p pixel*
/// are used as the standard iterator over a row of interleaved homogeneous pixels.
///
/// Since \p pixel inherits the properties of color base, assigning, equality comparison and copy-construcion are allowed between compatible pixels.
/// This means that an 8-bit RGB pixel may be assigned to an 8-bit BGR pixel, or to an 8-bit planar reference. The channels are properly paired semantically.
///
/// The single-channel (grayscale) instantiation of the class pixel, (i.e. \p pixel<T,gray_layout_t>) is also convertible to/from a channel value.
/// This allows grayscale pixels to be used in simpler expressions like *gray_pix1 = *gray_pix2 instead of more complicated at_c<0>(gray_pix1) = at_c<0>(gray_pix2)
/// or get_color<gray_color_t>(gray_pix1) = get_color<gray_color_t>(gray_pix2)
template <typename ChannelValue, typename Layout> // = mpl::range_c<int,0,ColorSpace::size> >
struct pixel : public detail::homogeneous_color_base<ChannelValue,Layout,mpl::size<typename Layout::color_space_t>::value> {
private:
typedef ChannelValue channel_t;
typedef detail::homogeneous_color_base<ChannelValue,Layout,mpl::size<typename Layout::color_space_t>::value> parent_t;
public:
typedef pixel value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
BOOST_STATIC_CONSTANT(bool, is_mutable = channel_traits<channel_t>::is_mutable);
pixel(){}
explicit pixel(channel_t v) : parent_t(v) {} // sets all channels to v
pixel(channel_t v0, channel_t v1) : parent_t(v0,v1) {}
pixel(channel_t v0, channel_t v1, channel_t v2) : parent_t(v0,v1,v2) {}
pixel(channel_t v0, channel_t v1, channel_t v2, channel_t v3) : parent_t(v0,v1,v2,v3) {}
pixel(channel_t v0, channel_t v1, channel_t v2, channel_t v3, channel_t v4) : parent_t(v0,v1,v2,v3,v4) {}
pixel(channel_t v0, channel_t v1, channel_t v2, channel_t v3, channel_t v4, channel_t v5) : parent_t(v0,v1,v2,v3,v4,v5) {}
pixel(const pixel& p) : parent_t(p) {}
pixel& operator=(const pixel& p) { static_copy(p,*this); return *this; }
// Construct from another compatible pixel type
template <typename Pixel> pixel(const Pixel& p, typename enable_if_c<is_pixel<Pixel>::value>::type* dummy = 0) : parent_t(p) {
check_compatible<Pixel>();
}
template <typename P> pixel& operator=(const P& p) { assign(p, mpl::bool_<is_pixel<P>::value>()); return *this; }
template <typename P> bool operator==(const P& p) const { return equal(p, mpl::bool_<is_pixel<P>::value>()); }
template <typename P> bool operator!=(const P& p) const { return !(*this==p); }
// homogeneous pixels have operator[]
typename channel_traits<channel_t>::reference operator[](std::size_t i) { return dynamic_at_c(*this,i); }
typename channel_traits<channel_t>::const_reference operator[](std::size_t i) const { return dynamic_at_c(*this,i); }
private:
template <typename Pixel> void assign(const Pixel& p, mpl::true_) { check_compatible<Pixel>(); static_copy(p,*this); }
template <typename Pixel> bool equal(const Pixel& p, mpl::true_) const { check_compatible<Pixel>(); return static_equal(*this,p); }
template <typename Pixel> void check_compatible() const { gil_function_requires<PixelsCompatibleConcept<Pixel,pixel> >(); }
// Support for assignment/equality comparison of a channel with a grayscale pixel
private:
static void check_gray() { BOOST_STATIC_ASSERT((is_same<typename Layout::color_space_t, gray_t>::value)); }
template <typename Channel> void assign(const Channel& chan, mpl::false_) { check_gray(); at_c<0>(*this)=chan; }
template <typename Channel> bool equal (const Channel& chan, mpl::false_) const { check_gray(); return at_c<0>(*this)==chan; }
public:
pixel& operator= (channel_t chan) { check_gray(); at_c<0>(*this)=chan; return *this; }
bool operator==(channel_t chan) const { check_gray(); return at_c<0>(*this)==chan; }
};
/////////////////////////////
// ColorBasedConcept
/////////////////////////////
template <typename ChannelValue, typename Layout, int K>
struct kth_element_type<pixel<ChannelValue,Layout>, K> {
typedef ChannelValue type;
};
template <typename ChannelValue, typename Layout, int K>
struct kth_element_reference_type<pixel<ChannelValue,Layout>, K> {
typedef typename channel_traits<ChannelValue>::reference type;
};
template <typename ChannelValue, typename Layout, int K>
struct kth_element_reference_type<const pixel<ChannelValue,Layout>, K> {
typedef typename channel_traits<ChannelValue>::const_reference type;
};
template <typename ChannelValue, typename Layout, int K>
struct kth_element_const_reference_type<pixel<ChannelValue,Layout>, K> {
typedef typename channel_traits<ChannelValue>::const_reference type;
};
/////////////////////////////
// PixelConcept
/////////////////////////////
template <typename ChannelValue, typename Layout>
struct is_pixel<pixel<ChannelValue,Layout> > : public mpl::true_{};
/////////////////////////////
// HomogeneousPixelBasedConcept
/////////////////////////////
template <typename ChannelValue, typename Layout>
struct color_space_type<pixel<ChannelValue,Layout> > {
typedef typename Layout::color_space_t type;
};
template <typename ChannelValue, typename Layout>
struct channel_mapping_type<pixel<ChannelValue,Layout> > {
typedef typename Layout::channel_mapping_t type;
};
template <typename ChannelValue, typename Layout>
struct is_planar<pixel<ChannelValue,Layout> > : public mpl::false_ {};
template <typename ChannelValue, typename Layout>
struct channel_type<pixel<ChannelValue,Layout> > {
typedef ChannelValue type;
};
} } // namespace boost::gil
namespace boost {
template <typename ChannelValue, typename Layout>
struct has_trivial_constructor<gil::pixel<ChannelValue,Layout> > : public has_trivial_constructor<ChannelValue> {};
}
#endif

View File

@ -0,0 +1,156 @@
/*
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_PIXEL_ITERATOR_H
#define GIL_PIXEL_ITERATOR_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief pixel iterator support
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n May 16, 2006
///
////////////////////////////////////////////////////////////////////////////////////////
#include <cassert>
#include <iterator>
#include "gil_config.hpp"
#include "gil_concept.hpp"
#include "utilities.hpp"
#include "pixel.hpp"
namespace boost { namespace gil {
//forwarded declaration (as this file is included in step_iterator.hpp)
template <typename Iterator>
class memory_based_step_iterator;
template <typename Iterator> struct dynamic_x_step_type;
/// \brief metafunction predicate determining whether the given iterator is a plain one or an adaptor over another iterator.
/// Examples of adaptors are the step iterator and the dereference iterator adaptor.
template <typename It>
struct is_iterator_adaptor : public mpl::false_{};
/// \brief returns the base iterator for a given iterator adaptor. Provide an specialization when introducing new iterator adaptors
template <typename It>
struct iterator_adaptor_get_base;
/// \brief Changes the base iterator of an iterator adaptor. Provide an specialization when introducing new iterator adaptors
template <typename It, typename NewBaseIt>
struct iterator_adaptor_rebind;
/// \brief Returns the type of an iterator just like the input iterator, except operating over immutable values
template <typename It>
struct const_iterator_type;
// The default implementation when the iterator is a C pointer is to use the standard constness semantics
template <typename T> struct const_iterator_type< T*> { typedef const T* type; };
template <typename T> struct const_iterator_type<const T*> { typedef const T* type; };
/// \brief Metafunction predicate returning whether the given iterator allows for changing its values
/// \ingroup GILIsMutable
template <typename It>
struct iterator_is_mutable{};
// The default implementation when the iterator is a C pointer is to use the standard constness semantics
template <typename T> struct iterator_is_mutable< T*> : public mpl::true_{};
template <typename T> struct iterator_is_mutable<const T*> : public mpl::false_{};
/// \defgroup PixelIteratorModelInterleavedPtr C pointer to a pixel
/// \ingroup PixelIteratorModel
/// \brief Iterators over interleaved pixels.
/// A C pointer to a model of PixelValueConcept is used as an iterator over interleaved pixels. Models PixelIteratorConcept, HomogeneousPixelBasedConcept, HasDynamicXStepTypeConcept, MemoryBasedIteratorConcept
/////////////////////////////
// HasDynamicXStepTypeConcept
/////////////////////////////
/// \ingroup PixelIteratorModelInterleavedPtr
template <typename Pixel>
struct dynamic_x_step_type<Pixel*> {
typedef memory_based_step_iterator<Pixel*> type;
};
/// \ingroup PixelIteratorModelInterleavedPtr
template <typename Pixel>
struct dynamic_x_step_type<const Pixel*> {
typedef memory_based_step_iterator<const Pixel*> type;
};
/////////////////////////////
// PixelBasedConcept
/////////////////////////////
template <typename Pixel> struct color_space_type< Pixel*> : public color_space_type<Pixel> {};
template <typename Pixel> struct color_space_type<const Pixel*> : public color_space_type<Pixel> {};
template <typename Pixel> struct channel_mapping_type< Pixel*> : public channel_mapping_type<Pixel> {};
template <typename Pixel> struct channel_mapping_type<const Pixel*> : public channel_mapping_type<Pixel> {};
template <typename Pixel> struct is_planar< Pixel*> : public is_planar<Pixel> {};
template <typename Pixel> struct is_planar<const Pixel*> : public is_planar<Pixel> {};
/////////////////////////////
// HomogeneousPixelBasedConcept
/////////////////////////////
template <typename Pixel> struct channel_type<Pixel*> : public channel_type<Pixel> {};
template <typename Pixel> struct channel_type<const Pixel*> : public channel_type<Pixel> {};
////////////////////////////////////////////////////////////////////////////////////////
///
/// Support for pixel iterator movement measured in memory units (bytes or bits) as opposed to pixel type. \n
/// Necessary to handle image row alignment and channel plane alignment.
///
////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////
// MemoryBasedIteratorConcept
/////////////////////////////
template <typename T>
struct byte_to_memunit : public mpl::int_<1> {};
template <typename P>
inline std::ptrdiff_t memunit_step(const P*) { return sizeof(P); }
template <typename P>
inline std::ptrdiff_t memunit_distance(const P* p1, const P* p2) {
return (gil_reinterpret_cast_c<const unsigned char*>(p2)-gil_reinterpret_cast_c<const unsigned char*>(p1));
}
template <typename P>
inline void memunit_advance(P* &p, std::ptrdiff_t diff) {
p=(P*)((unsigned char*)(p)+diff);
}
template <typename P>
inline P* memunit_advanced(const P* p, std::ptrdiff_t diff) {
return (P*)((char*)(p)+diff);
}
// memunit_advanced_ref
// (shortcut to advancing a pointer by a given number of memunits and taking the reference in case the compiler is not smart enough)
template <typename P>
inline P& memunit_advanced_ref(P* p, std::ptrdiff_t diff) {
return *memunit_advanced(p,diff);
}
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,208 @@
/*
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_PIXEL_ITERATOR_ADAPTOR_H
#define GIL_PIXEL_ITERATOR_ADAPTOR_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief pixel step iterator, pixel image iterator and pixel dereference iterator
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on February 16, 2007
///
////////////////////////////////////////////////////////////////////////////////////////
#include <iterator>
#include <boost/iterator/iterator_facade.hpp>
#include "gil_config.hpp"
#include "gil_concept.hpp"
#include "pixel_iterator.hpp"
namespace boost { namespace gil {
/// \defgroup PixelIteratorModelDerefPtr dereference_iterator_adaptor
/// \ingroup PixelIteratorModel
/// \brief An iterator that invokes a provided function object upon dereference. Models: IteratorAdaptorConcept, PixelIteratorConcept
/// \ingroup PixelIteratorModelDerefPtr PixelBasedModel
/// \brief An adaptor over an existing iterator that provides for custom filter on dereferencing the object. Models: IteratorAdaptorConcept, PixelIteratorConcept
template <typename Iterator, // Models Iterator
typename DFn> // Models Returns the result of dereferencing a given iterator of type Iterator
class dereference_iterator_adaptor : public iterator_adaptor<dereference_iterator_adaptor<Iterator,DFn>,
Iterator,
typename DFn::value_type,
use_default,
typename DFn::reference,
use_default> {
DFn _deref_fn;
public:
typedef iterator_adaptor<dereference_iterator_adaptor<Iterator,DFn>,
Iterator,
typename DFn::value_type,
use_default,
typename DFn::reference,
use_default> parent_t;
typedef typename DFn::result_type reference;
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
typedef DFn dereference_fn;
dereference_iterator_adaptor() {}
template <typename Iterator1>
dereference_iterator_adaptor(const dereference_iterator_adaptor<Iterator1,DFn>& dit) : parent_t(dit.base()), _deref_fn(dit._deref_fn) {}
dereference_iterator_adaptor(Iterator it, DFn deref_fn=DFn()) : parent_t(it), _deref_fn(deref_fn) {}
template <typename Iterator1, typename DFn1>
dereference_iterator_adaptor(const dereference_iterator_adaptor<Iterator1,DFn1>& it) : parent_t(it.base()), _deref_fn(it._deref_fn) {}
/// For some reason operator[] provided by iterator_facade returns a custom class that is convertible to reference
/// We require our own reference because it is registered in iterator_traits
reference operator[](difference_type d) const { return *(*this+d);}
// although iterator_adaptor defines these, the default implementation computes distance and compares for zero.
// it is often faster to just apply the relation operator to the base
bool operator> (const dereference_iterator_adaptor& p) const { return this->base_reference()> p.base_reference(); }
bool operator< (const dereference_iterator_adaptor& p) const { return this->base_reference()< p.base_reference(); }
bool operator>=(const dereference_iterator_adaptor& p) const { return this->base_reference()>=p.base_reference(); }
bool operator<=(const dereference_iterator_adaptor& p) const { return this->base_reference()<=p.base_reference(); }
bool operator==(const dereference_iterator_adaptor& p) const { return this->base_reference()==p.base_reference(); }
bool operator!=(const dereference_iterator_adaptor& p) const { return this->base_reference()!=p.base_reference(); }
Iterator& base() { return this->base_reference(); }
const Iterator& base() const { return this->base_reference(); }
const DFn& deref_fn() const { return _deref_fn; }
private:
template <typename Iterator1, typename DFn1>
friend class dereference_iterator_adaptor;
friend class boost::iterator_core_access;
reference dereference() const { return _deref_fn(*(this->base_reference())); }
};
template <typename I, typename DFn>
struct const_iterator_type<dereference_iterator_adaptor<I,DFn> > {
typedef dereference_iterator_adaptor<typename const_iterator_type<I>::type,typename DFn::const_t> type;
};
template <typename I, typename DFn>
struct iterator_is_mutable<dereference_iterator_adaptor<I,DFn> > : public mpl::bool_<DFn::is_mutable> {};
template <typename I, typename DFn>
struct is_iterator_adaptor<dereference_iterator_adaptor<I,DFn> > : public mpl::true_{};
template <typename I, typename DFn>
struct iterator_adaptor_get_base<dereference_iterator_adaptor<I,DFn> > {
typedef I type;
};
template <typename I, typename DFn, typename NewBaseIterator>
struct iterator_adaptor_rebind<dereference_iterator_adaptor<I,DFn>,NewBaseIterator> {
typedef dereference_iterator_adaptor<NewBaseIterator,DFn> type;
};
/////////////////////////////
// PixelBasedConcept
/////////////////////////////
template <typename I, typename DFn>
struct color_space_type<dereference_iterator_adaptor<I,DFn> > : public color_space_type<typename DFn::value_type> {};
template <typename I, typename DFn>
struct channel_mapping_type<dereference_iterator_adaptor<I,DFn> > : public channel_mapping_type<typename DFn::value_type> {};
template <typename I, typename DFn>
struct is_planar<dereference_iterator_adaptor<I,DFn> > : public is_planar<typename DFn::value_type> {};
template <typename I, typename DFn>
struct channel_type<dereference_iterator_adaptor<I,DFn> > : public channel_type<typename DFn::value_type> {};
/////////////////////////////
// MemoryBasedIteratorConcept
/////////////////////////////
template <typename Iterator, typename DFn>
struct byte_to_memunit<dereference_iterator_adaptor<Iterator,DFn> > : public byte_to_memunit<Iterator> {};
template <typename Iterator, typename DFn>
inline typename std::iterator_traits<Iterator>::difference_type
memunit_step(const dereference_iterator_adaptor<Iterator,DFn>& p) {
return memunit_step(p.base());
}
template <typename Iterator, typename DFn>
inline typename std::iterator_traits<Iterator>::difference_type
memunit_distance(const dereference_iterator_adaptor<Iterator,DFn>& p1,
const dereference_iterator_adaptor<Iterator,DFn>& p2) {
return memunit_distance(p1.base(),p2.base());
}
template <typename Iterator, typename DFn>
inline void memunit_advance(dereference_iterator_adaptor<Iterator,DFn>& p,
typename std::iterator_traits<Iterator>::difference_type diff) {
memunit_advance(p.base(), diff);
}
template <typename Iterator, typename DFn>
inline dereference_iterator_adaptor<Iterator,DFn>
memunit_advanced(const dereference_iterator_adaptor<Iterator,DFn>& p,
typename std::iterator_traits<Iterator>::difference_type diff) {
return dereference_iterator_adaptor<Iterator,DFn>(memunit_advanced(p.base(), diff), p.deref_fn());
}
template <typename Iterator, typename DFn>
inline
typename std::iterator_traits<dereference_iterator_adaptor<Iterator,DFn> >::reference
memunit_advanced_ref(const dereference_iterator_adaptor<Iterator,DFn>& p,
typename std::iterator_traits<Iterator>::difference_type diff) {
return *memunit_advanced(p, diff);
}
/////////////////////////////
// HasDynamicXStepTypeConcept
/////////////////////////////
template <typename Iterator, typename DFn>
struct dynamic_x_step_type<dereference_iterator_adaptor<Iterator,DFn> > {
typedef dereference_iterator_adaptor<typename dynamic_x_step_type<Iterator>::type,DFn> type;
};
/// \brief Returns the type (and creates an instance) of an iterator that invokes the given dereference adaptor upon dereferencing
/// \ingroup PixelIteratorModelDerefPtr
template <typename Iterator, typename Deref>
struct iterator_add_deref {
GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept)
typedef dereference_iterator_adaptor<Iterator, Deref> type;
static type make(const Iterator& it, const Deref& d) { return type(it,d); }
};
/// \ingroup PixelIteratorModelDerefPtr
/// \brief For dereference iterator adaptors, compose the new function object after the old one
template <typename Iterator, typename PREV_DEREF, typename Deref>
struct iterator_add_deref<dereference_iterator_adaptor<Iterator, PREV_DEREF>,Deref> {
// GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept)
typedef dereference_iterator_adaptor<Iterator, deref_compose<Deref,PREV_DEREF> > type;
static type make(const dereference_iterator_adaptor<Iterator, PREV_DEREF>& it, const Deref& d) {
return type(it.base(),deref_compose<Deref,PREV_DEREF>(d,it.deref_fn()));
}
};
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,227 @@
/*
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_PLANAR_PTR_H
#define GIL_PLANAR_PTR_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief planar pixel pointer class
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on February 12, 2007
///
////////////////////////////////////////////////////////////////////////////////////////
#include <cassert>
#include <iterator>
#include <boost/iterator/iterator_facade.hpp>
#include "gil_config.hpp"
#include "pixel.hpp"
#include "step_iterator.hpp"
namespace boost { namespace gil {
//forward declaration (as this file is included in planar_pixel_reference.hpp)
template <typename ChannelReference, typename ColorSpace>
struct planar_pixel_reference;
/// \defgroup ColorBaseModelPlanarPtr planar_pixel_iterator
/// \ingroup ColorBaseModel
/// \brief A homogeneous color base whose element is a channel iterator. Models HomogeneousColorBaseValueConcept
/// This class is used as an iterator to a planar pixel.
/// \defgroup PixelIteratorModelPlanarPtr planar_pixel_iterator
/// \ingroup PixelIteratorModel
/// \brief An iterator over planar pixels. Models PixelIteratorConcept, HomogeneousPixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept
////////////////////////////////////////////////////////////////////////////////////////
/// \brief An iterator over planar pixels. Models HomogeneousColorBaseConcept, PixelIteratorConcept, HomogeneousPixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept
///
/// Planar pixels have channel data that is not consecutive in memory.
/// To abstract this we use classes to represent references and pointers to planar pixels.
///
/// \ingroup PixelIteratorModelPlanarPtr ColorBaseModelPlanarPtr PixelBasedModel
template <typename ChannelPtr, typename ColorSpace>
struct planar_pixel_iterator : public iterator_facade<planar_pixel_iterator<ChannelPtr,ColorSpace>,
pixel<typename std::iterator_traits<ChannelPtr>::value_type,layout<ColorSpace> >,
random_access_traversal_tag,
const planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace> >,
public detail::homogeneous_color_base<ChannelPtr,layout<ColorSpace>,mpl::size<ColorSpace>::value > {
private:
typedef iterator_facade<planar_pixel_iterator<ChannelPtr,ColorSpace>,
pixel<typename std::iterator_traits<ChannelPtr>::value_type,layout<ColorSpace> >,
random_access_traversal_tag,
const planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace> > parent_t;
typedef detail::homogeneous_color_base<ChannelPtr,layout<ColorSpace>,mpl::size<ColorSpace>::value> color_base_parent_t;
typedef typename std::iterator_traits<ChannelPtr>::value_type channel_t;
public:
typedef typename parent_t::value_type value_type;
typedef typename parent_t::reference reference;
typedef typename parent_t::difference_type difference_type;
planar_pixel_iterator() : color_base_parent_t(0) {}
planar_pixel_iterator(bool) {} // constructor that does not fill with zero (for performance)
planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1) : color_base_parent_t(v0,v1) {}
planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1, const ChannelPtr& v2) : color_base_parent_t(v0,v1,v2) {}
planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1, const ChannelPtr& v2, const ChannelPtr& v3) : color_base_parent_t(v0,v1,v2,v3) {}
planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1, const ChannelPtr& v2, const ChannelPtr& v3, const ChannelPtr& v4) : color_base_parent_t(v0,v1,v2,v3,v4) {}
template <typename IC1,typename C1>
planar_pixel_iterator(const planar_pixel_iterator<IC1,C1>& ptr) : color_base_parent_t(ptr) {}
/// Copy constructor and operator= from pointers to compatible planar pixels or planar pixel references.
/// That allow constructs like pointer = &value or pointer = &reference
/// Since we should not override operator& that's the best we can do.
template <typename P>
planar_pixel_iterator(P* pix) : color_base_parent_t(pix, true) {
function_requires<PixelsCompatibleConcept<P,value_type> >();
}
struct address_of { template <typename T> T* operator()(T& t) { return &t; } };
template <typename P>
planar_pixel_iterator& operator=(P* pix) {
function_requires<PixelsCompatibleConcept<P,value_type> >();
static_transform(*pix,*this, address_of());
// PERFORMANCE_CHECK: Compare to this:
//this->template semantic_at_c<0>()=&pix->template semantic_at_c<0>();
//this->template semantic_at_c<1>()=&pix->template semantic_at_c<1>();
//this->template semantic_at_c<2>()=&pix->template semantic_at_c<2>();
return *this;
}
/// For some reason operator[] provided by iterator_facade returns a custom class that is convertible to reference
/// We require our own reference because it is registered in iterator_traits
reference operator[](difference_type d) const { return memunit_advanced_ref(*this,d*sizeof(channel_t));}
reference operator->() const { return **this; }
// PERFORMANCE_CHECK: Remove?
bool operator< (const planar_pixel_iterator& ptr) const { return at_c<0>(*this)< at_c<0>(ptr); }
bool operator!=(const planar_pixel_iterator& ptr) const { return at_c<0>(*this)!=at_c<0>(ptr); }
private:
friend class boost::iterator_core_access;
void increment() { static_transform(*this,*this,detail::inc<ChannelPtr>()); }
void decrement() { static_transform(*this,*this,detail::dec<ChannelPtr>()); }
void advance(ptrdiff_t d) { static_transform(*this,*this,std::bind2nd(detail::plus_asymmetric<ChannelPtr,ptrdiff_t>(),d)); }
reference dereference() const { return this->template deref<reference>(); }
ptrdiff_t distance_to(const planar_pixel_iterator& it) const { return at_c<0>(it)-at_c<0>(*this); }
bool equal(const planar_pixel_iterator& it) const { return at_c<0>(*this)==at_c<0>(it); }
};
namespace detail {
template <typename IC> struct channel_iterator_is_mutable : public mpl::true_ {};
template <typename T> struct channel_iterator_is_mutable<const T*> : public mpl::false_ {};
}
template <typename IC, typename C>
struct const_iterator_type<planar_pixel_iterator<IC,C> > {
private:
typedef typename std::iterator_traits<IC>::value_type channel_t;
public:
typedef planar_pixel_iterator<typename channel_traits<channel_t>::const_pointer,C> type;
};
// The default implementation when the iterator is a C pointer is to use the standard constness semantics
template <typename IC, typename C>
struct iterator_is_mutable<planar_pixel_iterator<IC,C> > : public detail::channel_iterator_is_mutable<IC> {};
/////////////////////////////
// ColorBasedConcept
/////////////////////////////
template <typename IC, typename C, int K>
struct kth_element_type<planar_pixel_iterator<IC,C>, K> {
typedef IC type;
};
template <typename IC, typename C, int K>
struct kth_element_reference_type<planar_pixel_iterator<IC,C>, K> : public add_reference<IC> {};
template <typename IC, typename C, int K>
struct kth_element_const_reference_type<planar_pixel_iterator<IC,C>, K> : public add_reference<typename add_const<IC>::type> {};
/////////////////////////////
// HomogeneousPixelBasedConcept
/////////////////////////////
template <typename IC, typename C>
struct color_space_type<planar_pixel_iterator<IC,C> > {
typedef C type;
};
template <typename IC, typename C>
struct channel_mapping_type<planar_pixel_iterator<IC,C> > : public channel_mapping_type<typename planar_pixel_iterator<IC,C>::value_type> {};
template <typename IC, typename C>
struct is_planar<planar_pixel_iterator<IC,C> > : public mpl::true_ {};
template <typename IC, typename C>
struct channel_type<planar_pixel_iterator<IC,C> > {
typedef typename std::iterator_traits<IC>::value_type type;
};
/////////////////////////////
// MemoryBasedIteratorConcept
/////////////////////////////
template <typename IC, typename C>
inline std::ptrdiff_t memunit_step(const planar_pixel_iterator<IC,C>&) { return sizeof(typename std::iterator_traits<IC>::value_type); }
template <typename IC, typename C>
inline std::ptrdiff_t memunit_distance(const planar_pixel_iterator<IC,C>& p1, const planar_pixel_iterator<IC,C>& p2) {
return memunit_distance(at_c<0>(p1),at_c<0>(p2));
}
template <typename IC>
struct memunit_advance_fn {
memunit_advance_fn(std::ptrdiff_t diff) : _diff(diff) {}
IC operator()(const IC& p) const { return memunit_advanced(p,_diff); }
std::ptrdiff_t _diff;
};
template <typename IC, typename C>
inline void memunit_advance(planar_pixel_iterator<IC,C>& p, std::ptrdiff_t diff) {
static_transform(p, p, memunit_advance_fn<IC>(diff));
}
template <typename IC, typename C>
inline planar_pixel_iterator<IC,C> memunit_advanced(const planar_pixel_iterator<IC,C>& p, std::ptrdiff_t diff) {
planar_pixel_iterator<IC,C> ret=p;
memunit_advance(ret, diff);
return ret;
}
template <typename ChannelPtr, typename ColorSpace>
inline planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace>
memunit_advanced_ref(const planar_pixel_iterator<ChannelPtr,ColorSpace>& ptr, std::ptrdiff_t diff) {
return planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace>(ptr, diff);
}
/////////////////////////////
// HasDynamicXStepTypeConcept
/////////////////////////////
template <typename IC, typename C>
struct dynamic_x_step_type<planar_pixel_iterator<IC,C> > {
typedef memory_based_step_iterator<planar_pixel_iterator<IC,C> > type;
};
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,186 @@
/*
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://stlab.adobe.com/gil for most recent version including documentation.
*/
/*************************************************************************************************/
#ifndef GIL_PLANAR_REF_H
#define GIL_PLANAR_REF_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief planar pixel reference class
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on September 28, 2006
///
////////////////////////////////////////////////////////////////////////////////////////
#include <boost/mpl/range_c.hpp>
#include "gil_config.hpp"
#include "gil_concept.hpp"
#include "color_base.hpp"
#include "channel.hpp"
#include "pixel.hpp"
#include "planar_pixel_iterator.hpp"
namespace boost { namespace gil {
/// \defgroup ColorBaseModelPlanarRef planar_pixel_reference
/// \ingroup ColorBaseModel
/// \brief A homogeneous color base whose element is a channel reference. Models HomogeneousColorBaseConcept, HomogeneousPixelConcept.
/// This class is used as a reference proxy to a planar pixel.
/// \defgroup PixelModelPlanarRef planar_pixel_reference
/// \ingroup PixelModel
/// \brief A reference proxy to a planar pixel. Models HomogeneousColorBaseConcept, HomogeneousPixelConcept.
/// \ingroup PixelModelPlanarRef ColorBaseModelPlanarRef PixelBasedModel
/// \brief A reference proxy to a planar pixel. Models: HomogeneousColorBaseConcept, HomogeneousPixelConcept
///
/// A reference to a planar pixel is a proxy class containing references to each of the corresponding channels.
///
template <typename ChannelReference, typename ColorSpace> // ChannelReference is a channel reference (const or mutable)
struct planar_pixel_reference
: public detail::homogeneous_color_base<ChannelReference,layout<ColorSpace>,mpl::size<ColorSpace>::value> {
typedef detail::homogeneous_color_base<ChannelReference,layout<ColorSpace>,mpl::size<ColorSpace>::value> parent_t;
private:
// These three are only defined for homogeneous pixels
typedef typename channel_traits<ChannelReference>::value_type channel_t;
typedef typename channel_traits<ChannelReference>::const_reference channel_const_reference;
public:
BOOST_STATIC_CONSTANT(bool, is_mutable = channel_traits<ChannelReference>::is_mutable);
typedef pixel<channel_t,layout<ColorSpace> > value_type;
typedef planar_pixel_reference reference;
typedef planar_pixel_reference<channel_const_reference,ColorSpace> const_reference;
planar_pixel_reference(ChannelReference v0, ChannelReference v1) : parent_t(v0,v1) {}
planar_pixel_reference(ChannelReference v0, ChannelReference v1, ChannelReference v2) : parent_t(v0,v1,v2) {}
planar_pixel_reference(ChannelReference v0, ChannelReference v1, ChannelReference v2, ChannelReference v3) : parent_t(v0,v1,v2,v3) {}
planar_pixel_reference(ChannelReference v0, ChannelReference v1, ChannelReference v2, ChannelReference v3, ChannelReference v4) : parent_t(v0,v1,v2,v3,v4) {}
planar_pixel_reference(ChannelReference v0, ChannelReference v1, ChannelReference v2, ChannelReference v3, ChannelReference v4, ChannelReference v5) : parent_t(v0,v1,v2,v3,v4,v5) {}
template <typename P> planar_pixel_reference(const P& p) : parent_t(p) { check_compatible<P>();}
// PERFORMANCE_CHECK: Is this constructor necessary?
template <typename ChannelV, typename Mapping>
planar_pixel_reference(pixel<ChannelV,layout<ColorSpace,Mapping> >& p) : parent_t(p) { check_compatible<pixel<ChannelV,layout<ColorSpace,Mapping> > >();}
// Construct at offset from a given location
template <typename ChannelPtr> planar_pixel_reference(const planar_pixel_iterator<ChannelPtr,ColorSpace>& p, std::ptrdiff_t diff) : parent_t(p,diff) {}
const planar_pixel_reference& operator=(const planar_pixel_reference& p) const { static_copy(p,*this); return *this; }
template <typename P> const planar_pixel_reference& operator=(const P& p) const { check_compatible<P>(); static_copy(p,*this); return *this; }
template <typename P> bool operator==(const P& p) const { check_compatible<P>(); return static_equal(*this,p); }
template <typename P> bool operator!=(const P& p) const { return !(*this==p); }
ChannelReference operator[](std::size_t i) const { return this->at_c_dynamic(i); }
const planar_pixel_reference* operator->() const { return this; }
private:
template <typename Pixel> static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel,planar_pixel_reference> >(); }
};
/////////////////////////////
// ColorBasedConcept
/////////////////////////////
template <typename ChannelReference, typename ColorSpace, int K>
struct kth_element_type<planar_pixel_reference<ChannelReference,ColorSpace>, K> {
typedef ChannelReference type;
};
template <typename ChannelReference, typename ColorSpace, int K>
struct kth_element_reference_type<planar_pixel_reference<ChannelReference,ColorSpace>, K> {
typedef ChannelReference type;
};
template <typename ChannelReference, typename ColorSpace, int K>
struct kth_element_const_reference_type<planar_pixel_reference<ChannelReference,ColorSpace>, K>
: public add_reference<typename add_const<ChannelReference>::type>
{
// typedef typename channel_traits<ChannelReference>::const_reference type;
};
/////////////////////////////
// PixelConcept
/////////////////////////////
/// \brief Metafunction predicate that flags planar_pixel_reference as a model of PixelConcept. Required by PixelConcept
/// \ingroup PixelModelPlanarRef
template <typename ChannelReference, typename ColorSpace>
struct is_pixel< planar_pixel_reference<ChannelReference,ColorSpace> > : public mpl::true_{};
/////////////////////////////
// HomogeneousPixelBasedConcept
/////////////////////////////
/// \brief Specifies the color space type of a planar pixel reference. Required by PixelBasedConcept
/// \ingroup PixelModelPlanarRef
template <typename ChannelReference, typename ColorSpace>
struct color_space_type<planar_pixel_reference<ChannelReference,ColorSpace> > {
typedef ColorSpace type;
};
/// \brief Specifies the color space type of a planar pixel reference. Required by PixelBasedConcept
/// \ingroup PixelModelPlanarRef
template <typename ChannelReference, typename ColorSpace>
struct channel_mapping_type<planar_pixel_reference<ChannelReference,ColorSpace> > {
typedef typename layout<ColorSpace>::channel_mapping_t type;
};
/// \brief Specifies that planar_pixel_reference represents a planar construct. Required by PixelBasedConcept
/// \ingroup PixelModelPlanarRef
template <typename ChannelReference, typename ColorSpace>
struct is_planar<planar_pixel_reference<ChannelReference,ColorSpace> > : mpl::true_ {};
/// \brief Specifies the color space type of a planar pixel reference. Required by HomogeneousPixelBasedConcept
/// \ingroup PixelModelPlanarRef
template <typename ChannelReference, typename ColorSpace>
struct channel_type<planar_pixel_reference<ChannelReference,ColorSpace> > {
typedef typename channel_traits<ChannelReference>::value_type type;
};
} } // namespace boost::gil
namespace std {
// We are forced to define swap inside std namespace because on some platforms (Visual Studio 8) STL calls swap qualified.
// swap with 'left bias':
// - swap between proxy and anything
// - swap between value type and proxy
// - swap between proxy and proxy
// Having three overloads allows us to swap between different (but compatible) models of PixelConcept
/// \brief swap for planar_pixel_reference
/// \ingroup PixelModelPlanarRef
template <typename CR, typename CS, typename R> inline
void swap(const boost::gil::planar_pixel_reference<CR,CS> x, R& y) {
boost::gil::swap_proxy<typename boost::gil::planar_pixel_reference<CR,CS>::value_type>(x,y);
}
/// \brief swap for planar_pixel_reference
/// \ingroup PixelModelPlanarRef
template <typename CR, typename CS> inline
void swap(typename boost::gil::planar_pixel_reference<CR,CS>::value_type& x, const boost::gil::planar_pixel_reference<CR,CS> y) {
boost::gil::swap_proxy<typename boost::gil::planar_pixel_reference<CR,CS>::value_type>(x,y);
}
/// \brief swap for planar_pixel_reference
/// \ingroup PixelModelPlanarRef
template <typename CR, typename CS> inline
void swap(const boost::gil::planar_pixel_reference<CR,CS> x, const boost::gil::planar_pixel_reference<CR,CS> y) {
boost::gil::swap_proxy<typename boost::gil::planar_pixel_reference<CR,CS>::value_type>(x,y);
}
} // namespace std
#endif

View File

@ -0,0 +1,121 @@
/*
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_POSITION_ITERATOR_HPP
#define GIL_POSITION_ITERATOR_HPP
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Locator for virtual image views
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on February 12, 2007
///
////////////////////////////////////////////////////////////////////////////////////////
#include <boost/iterator/iterator_facade.hpp>
#include "locator.hpp"
namespace boost { namespace gil {
/// \defgroup PixelIteratorModelVirtual position_iterator
/// \ingroup PixelIteratorModel
/// \brief An iterator that remembers its current X,Y position and invokes a function object with it upon dereferencing. Models PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept. Used to create virtual image views.
/// \brief An iterator that remembers its current X,Y position and invokes a function object with it upon dereferencing. Models PixelIteratorConcept. Used to create virtual image views.
/// Models: StepIteratorConcept, PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept
/// \ingroup PixelIteratorModelVirtual PixelBasedModel
template <typename Deref, // A function object that given a point returns a pixel reference. Models PixelDereferenceAdaptorConcept
int Dim> // the dimension to advance along
struct position_iterator : public iterator_facade<position_iterator<Deref,Dim>,
typename Deref::value_type,
random_access_traversal_tag,
typename Deref::reference,
typename Deref::argument_type::template axis<Dim>::coord_t> {
typedef iterator_facade<position_iterator<Deref,Dim>,
typename Deref::value_type,
random_access_traversal_tag,
typename Deref::reference,
typename Deref::argument_type::template axis<Dim>::coord_t> parent_t;
typedef typename parent_t::difference_type difference_type;
typedef typename parent_t::reference reference;
typedef typename Deref::argument_type point_t;
position_iterator() {}
position_iterator(const point_t& p, const point_t& step, const Deref& d) : _p(p), _step(step), _d(d) {}
position_iterator(const position_iterator& p) : _p(p._p), _step(p._step), _d(p._d) {}
template <typename D> position_iterator(const position_iterator<D,Dim>& p) : _p(p._p), _step(p._step), _d(p._d) {}
position_iterator& operator=(const position_iterator& p) { _p=p._p; _d=p._d; _step=p._step; return *this; }
const point_t& pos() const { return _p; }
const point_t& step() const { return _step; }
const Deref& deref_fn() const { return _d; }
void set_step(difference_type s) { _step[Dim]=s; }
/// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference
/// We require our own reference because it is registered in iterator_traits
reference operator[](difference_type d) const { point_t p=_p; p[Dim]+=d*_step[Dim]; return _d(p); }
private:
point_t _p, _step;
Deref _d;
template <typename DE, int DI> friend struct position_iterator;
friend class boost::iterator_core_access;
reference dereference() const { return _d(_p); }
void increment() { _p[Dim]+=_step[Dim]; }
void decrement() { _p[Dim]-=_step[Dim]; }
void advance(difference_type d) { _p[Dim]+=d*_step[Dim]; }
difference_type distance_to(const position_iterator& it) const { return (it._p[Dim]-_p[Dim])/_step[Dim]; }
bool equal(const position_iterator& it) const { return _p==it._p; }
};
template <typename Deref,int Dim>
struct const_iterator_type<position_iterator<Deref,Dim> > {
typedef position_iterator<typename Deref::const_t,Dim> type;
};
template <typename Deref,int Dim>
struct iterator_is_mutable<position_iterator<Deref,Dim> > : public mpl::bool_<Deref::is_mutable> {
};
/////////////////////////////
// PixelBasedConcept
/////////////////////////////
template <typename Deref,int Dim>
struct color_space_type<position_iterator<Deref,Dim> > : public color_space_type<typename Deref::value_type> {};
template <typename Deref,int Dim>
struct channel_mapping_type<position_iterator<Deref,Dim> > : public channel_mapping_type<typename Deref::value_type> {};
template <typename Deref,int Dim>
struct is_planar<position_iterator<Deref,Dim> > : public mpl::false_ {};
template <typename Deref,int Dim>
struct channel_type<position_iterator<Deref,Dim> > : public channel_type<typename Deref::value_type> {};
/////////////////////////////
// HasDynamicXStepTypeConcept
/////////////////////////////
template <typename Deref,int Dim>
struct dynamic_x_step_type<position_iterator<Deref,Dim> > {
typedef position_iterator<Deref,Dim> type;
};
} } // namespace boost::gil
#endif

70
src/3rdparty/include/boost/gil/rgb.hpp vendored Normal file
View File

@ -0,0 +1,70 @@
/*
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_RGB_H
#define GIL_RGB_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Support for RGB color space and variants
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on October 10, 2007
////////////////////////////////////////////////////////////////////////////////////////
#include <cstddef>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/vector_c.hpp>
#include "gil_config.hpp"
#include "metafunctions.hpp"
#include "planar_pixel_iterator.hpp"
namespace boost { namespace gil {
/// \addtogroup ColorNameModel
/// \{
/// \brief Red
struct red_t {};
/// \brief Green
struct green_t {};
/// \brief Blue
struct blue_t {};
/// \}
/// \ingroup ColorSpaceModel
typedef mpl::vector3<red_t,green_t,blue_t> rgb_t;
/// \ingroup LayoutModel
typedef layout<rgb_t> rgb_layout_t;
/// \ingroup LayoutModel
typedef layout<rgb_t, mpl::vector3_c<int,2,1,0> > bgr_layout_t;
/// \ingroup ImageViewConstructors
/// \brief from raw RGB planar data
template <typename IC>
inline
typename type_from_x_iterator<planar_pixel_iterator<IC,rgb_t> >::view_t
planar_rgb_view(std::size_t width, std::size_t height,
IC r, IC g, IC b,
std::ptrdiff_t rowsize_in_bytes) {
typedef typename type_from_x_iterator<planar_pixel_iterator<IC,rgb_t> >::view_t RView;
return RView(width, height,
typename RView::locator(planar_pixel_iterator<IC,rgb_t>(r,g,b),
rowsize_in_bytes));
}
} } // namespace boost::gil
#endif

63
src/3rdparty/include/boost/gil/rgba.hpp vendored Normal file
View File

@ -0,0 +1,63 @@
/*
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_RGBA_H
#define GIL_RGBA_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Support for RGBA color space and variants
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on October 10, 2007
////////////////////////////////////////////////////////////////////////////////////////
#include <cstddef>
#include "gil_config.hpp"
#include <boost/mpl/contains.hpp>
#include "rgb.hpp"
#include "planar_pixel_iterator.hpp"
namespace boost { namespace gil {
/// \ingroup ColorNameModel
/// \brief Alpha
struct alpha_t {};
/// \ingroup ColorSpaceModel
typedef mpl::vector4<red_t,green_t,blue_t,alpha_t> rgba_t;
/// \ingroup LayoutModel
typedef layout<rgba_t> rgba_layout_t;
/// \ingroup LayoutModel
typedef layout<rgba_t, mpl::vector4_c<int,2,1,0,3> > bgra_layout_t;
/// \ingroup LayoutModel
typedef layout<rgba_t, mpl::vector4_c<int,1,2,3,0> > argb_layout_t;
/// \ingroup LayoutModel
typedef layout<rgba_t, mpl::vector4_c<int,3,2,1,0> > abgr_layout_t;
/// \ingroup ImageViewConstructors
/// \brief from raw RGBA planar data
template <typename IC>
inline
typename type_from_x_iterator<planar_pixel_iterator<IC,rgba_t> >::view_t
planar_rgba_view(std::size_t width, std::size_t height,
IC r, IC g, IC b, IC a,
std::ptrdiff_t rowsize_in_bytes) {
typedef typename type_from_x_iterator<planar_pixel_iterator<IC,rgba_t> >::view_t RView;
return RView(width, height,
typename RView::locator(planar_pixel_iterator<IC,rgba_t>(r,g,b,a),
rowsize_in_bytes));
}
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,320 @@
/*
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_STEP_ITERATOR_H
#define GIL_STEP_ITERATOR_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief pixel step iterator
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on September 18, 2007
///
////////////////////////////////////////////////////////////////////////////////////////
#include <cstddef>
#include <iterator>
#include <boost/iterator/iterator_facade.hpp>
#include "gil_config.hpp"
#include "utilities.hpp"
#include "pixel_iterator.hpp"
#include "pixel_iterator_adaptor.hpp"
namespace boost { namespace gil {
/// \defgroup PixelIteratorModelStepPtr step iterators
/// \ingroup PixelIteratorModel
/// \brief Iterators that allow for specifying the step between two adjacent values
namespace detail {
/// \ingroup PixelIteratorModelStepPtr
/// \brief An adaptor over an existing iterator that changes the step unit
///
/// (i.e. distance(it,it+1)) by a given predicate. Instead of calling base's
/// operators ++, --, +=, -=, etc. the adaptor is using the passed policy object SFn
/// for advancing and for computing the distance between iterators.
template <typename Derived, // type of the derived class
typename Iterator, // Models Iterator
typename SFn> // A policy object that can compute the distance between two iterators of type Iterator
// and can advance an iterator of type Iterator a given number of Iterator's units
class step_iterator_adaptor : public iterator_adaptor<Derived, Iterator, use_default, use_default, use_default, typename SFn::difference_type> {
public:
typedef iterator_adaptor<Derived, Iterator, use_default, use_default, use_default, typename SFn::difference_type> parent_t;
typedef typename std::iterator_traits<Iterator>::difference_type base_difference_type;
typedef typename SFn::difference_type difference_type;
typedef typename std::iterator_traits<Iterator>::reference reference;
step_iterator_adaptor() {}
step_iterator_adaptor(const Iterator& it, SFn step_fn=SFn()) : parent_t(it), _step_fn(step_fn) {}
difference_type step() const { return _step_fn.step(); }
protected:
SFn _step_fn;
private:
friend class boost::iterator_core_access;
void increment() { _step_fn.advance(this->base_reference(),1); }
void decrement() { _step_fn.advance(this->base_reference(),-1); }
void advance(base_difference_type d) { _step_fn.advance(this->base_reference(),d); }
difference_type distance_to(const step_iterator_adaptor& it) const { return _step_fn.difference(this->base_reference(),it.base_reference()); }
};
// although iterator_adaptor defines these, the default implementation computes distance and compares for zero.
// it is often faster to just apply the relation operator to the base
template <typename D,typename Iterator,typename SFn> inline
bool operator>(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
return p1.step()>0 ? p1.base()> p2.base() : p1.base()< p2.base();
}
template <typename D,typename Iterator,typename SFn> inline
bool operator<(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
return p1.step()>0 ? p1.base()< p2.base() : p1.base()> p2.base();
}
template <typename D,typename Iterator,typename SFn> inline
bool operator>=(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
return p1.step()>0 ? p1.base()>=p2.base() : p1.base()<=p2.base();
}
template <typename D,typename Iterator,typename SFn> inline
bool operator<=(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
return p1.step()>0 ? p1.base()<=p2.base() : p1.base()>=p2.base();
}
template <typename D,typename Iterator,typename SFn> inline
bool operator==(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
return p1.base()==p2.base();
}
template <typename D,typename Iterator,typename SFn> inline
bool operator!=(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
return p1.base()!=p2.base();
}
} // namespace detail
////////////////////////////////////////////////////////////////////////////////////////
/// MEMORY-BASED STEP ITERATOR
////////////////////////////////////////////////////////////////////////////////////////
/// \class memory_based_step_iterator
/// \ingroup PixelIteratorModelStepPtr PixelBasedModel
/// \brief Iterator with dynamically specified step in memory units (bytes or bits). Models StepIteratorConcept, IteratorAdaptorConcept, MemoryBasedIteratorConcept, PixelIteratorConcept, HasDynamicXStepTypeConcept
///
/// A refinement of step_iterator_adaptor that uses a dynamic parameter for the step
/// which is specified in memory units, such as bytes or bits
///
/// Pixel step iterators are used to provide iteration over non-adjacent pixels.
/// Common use is a vertical traversal, where the step is the row stride.
///
/// Another application is as a sub-channel view. For example, a red intensity image over
/// interleaved RGB data would use a step iterator adaptor with step sizeof(channel_t)*3
/// In the latter example the step size could be fixed at compile time for efficiency.
/// Compile-time fixed step can be implemented by providing a step function object that takes the step as a template
////////////////////////////////////////////////////////////////////////////////////////
/// \ingroup PixelIteratorModelStepPtr
/// \brief function object that returns the memory unit distance between two iterators and advances a given iterator a given number of mem units (bytes or bits)
template <typename Iterator>
struct memunit_step_fn {
typedef std::ptrdiff_t difference_type;
memunit_step_fn(difference_type step=memunit_step(Iterator())) : _step(step) {}
difference_type difference(const Iterator& it1, const Iterator& it2) const { return memunit_distance(it1,it2)/_step; }
void advance(Iterator& it, difference_type d) const { memunit_advance(it,d*_step); }
difference_type step() const { return _step; }
void set_step(std::ptrdiff_t step) { _step=step; }
private:
GIL_CLASS_REQUIRE(Iterator, boost::gil, MemoryBasedIteratorConcept)
difference_type _step;
};
template <typename Iterator>
class memory_based_step_iterator : public detail::step_iterator_adaptor<memory_based_step_iterator<Iterator>,
Iterator,
memunit_step_fn<Iterator> > {
GIL_CLASS_REQUIRE(Iterator, boost::gil, MemoryBasedIteratorConcept)
public:
typedef detail::step_iterator_adaptor<memory_based_step_iterator<Iterator>,
Iterator,
memunit_step_fn<Iterator> > parent_t;
typedef typename parent_t::reference reference;
typedef typename parent_t::difference_type difference_type;
typedef Iterator x_iterator;
memory_based_step_iterator() : parent_t(Iterator()) {}
memory_based_step_iterator(Iterator it, std::ptrdiff_t memunit_step) : parent_t(it, memunit_step_fn<Iterator>(memunit_step)) {}
template <typename I2>
memory_based_step_iterator(const memory_based_step_iterator<I2>& it)
: parent_t(it.base(), memunit_step_fn<Iterator>(it.step())) {}
/// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference
/// We require our own reference because it is registered in iterator_traits
reference operator[](difference_type d) const { return *(*this+d); }
void set_step(std::ptrdiff_t memunit_step) { this->_step_fn.set_step(memunit_step); }
x_iterator& base() { return parent_t::base_reference(); }
x_iterator const& base() const { return parent_t::base_reference(); }
};
template <typename Iterator>
struct const_iterator_type<memory_based_step_iterator<Iterator> > {
typedef memory_based_step_iterator<typename const_iterator_type<Iterator>::type> type;
};
template <typename Iterator>
struct iterator_is_mutable<memory_based_step_iterator<Iterator> > : public iterator_is_mutable<Iterator> {};
/////////////////////////////
// IteratorAdaptorConcept
/////////////////////////////
template <typename Iterator>
struct is_iterator_adaptor<memory_based_step_iterator<Iterator> > : public mpl::true_{};
template <typename Iterator>
struct iterator_adaptor_get_base<memory_based_step_iterator<Iterator> > {
typedef Iterator type;
};
template <typename Iterator, typename NewBaseIterator>
struct iterator_adaptor_rebind<memory_based_step_iterator<Iterator>,NewBaseIterator> {
typedef memory_based_step_iterator<NewBaseIterator> type;
};
/////////////////////////////
// PixelBasedConcept
/////////////////////////////
template <typename Iterator>
struct color_space_type<memory_based_step_iterator<Iterator> > : public color_space_type<Iterator> {};
template <typename Iterator>
struct channel_mapping_type<memory_based_step_iterator<Iterator> > : public channel_mapping_type<Iterator> {};
template <typename Iterator>
struct is_planar<memory_based_step_iterator<Iterator> > : public is_planar<Iterator> {};
template <typename Iterator>
struct channel_type<memory_based_step_iterator<Iterator> > : public channel_type<Iterator> {};
/////////////////////////////
// MemoryBasedIteratorConcept
/////////////////////////////
template <typename Iterator>
struct byte_to_memunit<memory_based_step_iterator<Iterator> > : public byte_to_memunit<Iterator> {};
template <typename Iterator>
inline std::ptrdiff_t memunit_step(const memory_based_step_iterator<Iterator>& p) { return p.step(); }
template <typename Iterator>
inline std::ptrdiff_t memunit_distance(const memory_based_step_iterator<Iterator>& p1,
const memory_based_step_iterator<Iterator>& p2) {
return memunit_distance(p1.base(),p2.base());
}
template <typename Iterator>
inline void memunit_advance(memory_based_step_iterator<Iterator>& p,
std::ptrdiff_t diff) {
memunit_advance(p.base(), diff);
}
template <typename Iterator>
inline memory_based_step_iterator<Iterator>
memunit_advanced(const memory_based_step_iterator<Iterator>& p,
std::ptrdiff_t diff) {
return memory_based_step_iterator<Iterator>(memunit_advanced(p.base(), diff),p.step());
}
template <typename Iterator>
inline typename std::iterator_traits<Iterator>::reference
memunit_advanced_ref(const memory_based_step_iterator<Iterator>& p,
std::ptrdiff_t diff) {
return memunit_advanced_ref(p.base(), diff);
}
/////////////////////////////
// HasDynamicXStepTypeConcept
/////////////////////////////
template <typename Iterator>
struct dynamic_x_step_type<memory_based_step_iterator<Iterator> > {
typedef memory_based_step_iterator<Iterator> type;
};
// For step iterators, pass the function object to the base
template <typename Iterator, typename Deref>
struct iterator_add_deref<memory_based_step_iterator<Iterator>,Deref> {
GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept)
typedef memory_based_step_iterator<typename iterator_add_deref<Iterator, Deref>::type> type;
static type make(const memory_based_step_iterator<Iterator>& it, const Deref& d) { return type(iterator_add_deref<Iterator, Deref>::make(it.base(),d),it.step()); }
};
////////////////////////////////////////////////////////////////////////////////////////
/// make_step_iterator
////////////////////////////////////////////////////////////////////////////////////////
template <typename I> typename dynamic_x_step_type<I>::type make_step_iterator(const I& it, std::ptrdiff_t step);
namespace detail {
// if the iterator is a plain base iterator (non-adaptor), wraps it in memory_based_step_iterator
template <typename I>
typename dynamic_x_step_type<I>::type make_step_iterator_impl(const I& it, std::ptrdiff_t step, mpl::false_) {
return memory_based_step_iterator<I>(it, step);
}
// If the iterator is compound, put the step in its base
template <typename I>
typename dynamic_x_step_type<I>::type make_step_iterator_impl(const I& it, std::ptrdiff_t step, mpl::true_) {
return make_step_iterator(it.base(), step);
}
// If the iterator is memory_based_step_iterator, change the step
template <typename BaseIt>
memory_based_step_iterator<BaseIt> make_step_iterator_impl(const memory_based_step_iterator<BaseIt>& it, std::ptrdiff_t step, mpl::true_) {
return memory_based_step_iterator<BaseIt>(it.base(), step);
}
}
/// \brief Constructs a step iterator from a base iterator and a step.
///
/// To construct a step iterator from a given iterator Iterator and a given step, if Iterator does not
/// already have a dynamic step, we wrap it in a memory_based_step_iterator. Otherwise we
/// do a compile-time traversal of the chain of iterator adaptors to locate the step iterator
/// and then set it step to the new one.
///
/// The step iterator of Iterator is not always memory_based_step_iterator<Iterator>. For example, Iterator may
/// already be a memory_based_step_iterator, in which case it will be inefficient to stack them;
/// we can obtain the same result by multiplying their steps. Note that for Iterator to be a
/// step iterator it does not necessarily have to have the form memory_based_step_iterator<J>.
/// The step iterator can be wrapped inside another iterator. Also, it may not have the
/// type memory_based_step_iterator, but it could be a user-provided type.
template <typename I> // Models MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept
typename dynamic_x_step_type<I>::type make_step_iterator(const I& it, std::ptrdiff_t step) {
return detail::make_step_iterator_impl(it, step, typename is_iterator_adaptor<I>::type());
}
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,196 @@
/*
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_TYPEDEFS_H
#define GIL_TYPEDEFS_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Useful typedefs
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on March 8, 2006
///
////////////////////////////////////////////////////////////////////////////////////////
#include "gil_config.hpp"
#include <boost/cstdint.hpp>
#include "gray.hpp"
#include "rgb.hpp"
#include "rgba.hpp"
#include "cmyk.hpp"
#include "device_n.hpp"
#include <memory>
// CS = 'bgr' LAYOUT='bgr_layout_t'
#define GIL_DEFINE_BASE_TYPEDEFS_INTERNAL(T,CS,LAYOUT) \
template <typename, typename> struct pixel; \
template <typename, typename> struct planar_pixel_reference; \
template <typename, typename> struct planar_pixel_iterator; \
template <typename> class memory_based_step_iterator; \
template <typename> class point2; \
template <typename> class memory_based_2d_locator; \
template <typename> class image_view; \
template <typename, bool, typename> class image; \
typedef pixel<bits##T, LAYOUT > CS##T##_pixel_t; \
typedef const pixel<bits##T, LAYOUT > CS##T##c_pixel_t; \
typedef pixel<bits##T, LAYOUT >& CS##T##_ref_t; \
typedef const pixel<bits##T, LAYOUT >& CS##T##c_ref_t; \
typedef CS##T##_pixel_t* CS##T##_ptr_t; \
typedef CS##T##c_pixel_t* CS##T##c_ptr_t; \
typedef memory_based_step_iterator<CS##T##_ptr_t> CS##T##_step_ptr_t; \
typedef memory_based_step_iterator<CS##T##c_ptr_t> CS##T##c_step_ptr_t; \
typedef memory_based_2d_locator<memory_based_step_iterator<CS##T##_ptr_t> > CS##T##_loc_t; \
typedef memory_based_2d_locator<memory_based_step_iterator<CS##T##c_ptr_t> > CS##T##c_loc_t; \
typedef memory_based_2d_locator<memory_based_step_iterator<CS##T##_step_ptr_t> > CS##T##_step_loc_t; \
typedef memory_based_2d_locator<memory_based_step_iterator<CS##T##c_step_ptr_t> > CS##T##c_step_loc_t; \
typedef image_view<CS##T##_loc_t> CS##T##_view_t; \
typedef image_view<CS##T##c_loc_t> CS##T##c_view_t; \
typedef image_view<CS##T##_step_loc_t> CS##T##_step_view_t; \
typedef image_view<CS##T##c_step_loc_t> CS##T##c_step_view_t; \
typedef image<CS##T##_pixel_t,false,std::allocator<unsigned char> > CS##T##_image_t;
// CS = 'bgr' CS_FULL = 'rgb_t' LAYOUT='bgr_layout_t'
#define GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(T,CS,CS_FULL,LAYOUT) \
GIL_DEFINE_BASE_TYPEDEFS_INTERNAL(T,CS,LAYOUT) \
typedef planar_pixel_reference<bits##T&,CS_FULL > CS##T##_planar_ref_t; \
typedef planar_pixel_reference<const bits##T&,CS_FULL > CS##T##c_planar_ref_t; \
typedef planar_pixel_iterator<bits##T*,CS_FULL > CS##T##_planar_ptr_t; \
typedef planar_pixel_iterator<const bits##T*,CS_FULL > CS##T##c_planar_ptr_t; \
typedef memory_based_step_iterator<CS##T##_planar_ptr_t> CS##T##_planar_step_ptr_t; \
typedef memory_based_step_iterator<CS##T##c_planar_ptr_t> CS##T##c_planar_step_ptr_t; \
typedef memory_based_2d_locator<memory_based_step_iterator<CS##T##_planar_ptr_t> > CS##T##_planar_loc_t; \
typedef memory_based_2d_locator<memory_based_step_iterator<CS##T##c_planar_ptr_t> > CS##T##c_planar_loc_t; \
typedef memory_based_2d_locator<memory_based_step_iterator<CS##T##_planar_step_ptr_t> > CS##T##_planar_step_loc_t; \
typedef memory_based_2d_locator<memory_based_step_iterator<CS##T##c_planar_step_ptr_t> > CS##T##c_planar_step_loc_t; \
typedef image_view<CS##T##_planar_loc_t> CS##T##_planar_view_t; \
typedef image_view<CS##T##c_planar_loc_t> CS##T##c_planar_view_t; \
typedef image_view<CS##T##_planar_step_loc_t> CS##T##_planar_step_view_t; \
typedef image_view<CS##T##c_planar_step_loc_t> CS##T##c_planar_step_view_t;\
typedef image<CS##T##_pixel_t,true,std::allocator<unsigned char> > CS##T##_planar_image_t;
#define GIL_DEFINE_BASE_TYPEDEFS(T,CS) \
GIL_DEFINE_BASE_TYPEDEFS_INTERNAL(T,CS,CS##_layout_t)
#define GIL_DEFINE_ALL_TYPEDEFS(T,CS) \
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(T,CS,CS##_t,CS##_layout_t)
namespace boost { namespace gil {
// forward declarations
template <typename B, typename Mn, typename Mx> struct scoped_channel_value;
struct float_zero;
struct float_one;
typedef scoped_channel_value<float,float_zero,float_one> bits32f;
typedef uint8_t bits8;
typedef uint16_t bits16;
typedef uint32_t bits32;
typedef int8_t bits8s;
typedef int16_t bits16s;
typedef int32_t bits32s;
GIL_DEFINE_BASE_TYPEDEFS(8, gray)
GIL_DEFINE_BASE_TYPEDEFS(8s, gray)
GIL_DEFINE_BASE_TYPEDEFS(16, gray)
GIL_DEFINE_BASE_TYPEDEFS(16s,gray)
GIL_DEFINE_BASE_TYPEDEFS(32 ,gray)
GIL_DEFINE_BASE_TYPEDEFS(32s,gray)
GIL_DEFINE_BASE_TYPEDEFS(32f,gray)
GIL_DEFINE_BASE_TYPEDEFS(8, bgr)
GIL_DEFINE_BASE_TYPEDEFS(8s, bgr)
GIL_DEFINE_BASE_TYPEDEFS(16, bgr)
GIL_DEFINE_BASE_TYPEDEFS(16s,bgr)
GIL_DEFINE_BASE_TYPEDEFS(32 ,bgr)
GIL_DEFINE_BASE_TYPEDEFS(32s,bgr)
GIL_DEFINE_BASE_TYPEDEFS(32f,bgr)
GIL_DEFINE_BASE_TYPEDEFS(8, argb)
GIL_DEFINE_BASE_TYPEDEFS(8s, argb)
GIL_DEFINE_BASE_TYPEDEFS(16, argb)
GIL_DEFINE_BASE_TYPEDEFS(16s,argb)
GIL_DEFINE_BASE_TYPEDEFS(32, argb)
GIL_DEFINE_BASE_TYPEDEFS(32s,argb)
GIL_DEFINE_BASE_TYPEDEFS(32f,argb)
GIL_DEFINE_BASE_TYPEDEFS(8, abgr)
GIL_DEFINE_BASE_TYPEDEFS(8s, abgr)
GIL_DEFINE_BASE_TYPEDEFS(16, abgr)
GIL_DEFINE_BASE_TYPEDEFS(16s,abgr)
GIL_DEFINE_BASE_TYPEDEFS(32 ,abgr)
GIL_DEFINE_BASE_TYPEDEFS(32s,abgr)
GIL_DEFINE_BASE_TYPEDEFS(32f,abgr)
GIL_DEFINE_BASE_TYPEDEFS(8, bgra)
GIL_DEFINE_BASE_TYPEDEFS(8s, bgra)
GIL_DEFINE_BASE_TYPEDEFS(16, bgra)
GIL_DEFINE_BASE_TYPEDEFS(16s,bgra)
GIL_DEFINE_BASE_TYPEDEFS(32 ,bgra)
GIL_DEFINE_BASE_TYPEDEFS(32s,bgra)
GIL_DEFINE_BASE_TYPEDEFS(32f,bgra)
GIL_DEFINE_ALL_TYPEDEFS(8, rgb)
GIL_DEFINE_ALL_TYPEDEFS(8s, rgb)
GIL_DEFINE_ALL_TYPEDEFS(16, rgb)
GIL_DEFINE_ALL_TYPEDEFS(16s,rgb)
GIL_DEFINE_ALL_TYPEDEFS(32 ,rgb)
GIL_DEFINE_ALL_TYPEDEFS(32s,rgb)
GIL_DEFINE_ALL_TYPEDEFS(32f,rgb)
GIL_DEFINE_ALL_TYPEDEFS(8, rgba)
GIL_DEFINE_ALL_TYPEDEFS(8s, rgba)
GIL_DEFINE_ALL_TYPEDEFS(16, rgba)
GIL_DEFINE_ALL_TYPEDEFS(16s,rgba)
GIL_DEFINE_ALL_TYPEDEFS(32 ,rgba)
GIL_DEFINE_ALL_TYPEDEFS(32s,rgba)
GIL_DEFINE_ALL_TYPEDEFS(32f,rgba)
GIL_DEFINE_ALL_TYPEDEFS(8, cmyk)
GIL_DEFINE_ALL_TYPEDEFS(8s, cmyk)
GIL_DEFINE_ALL_TYPEDEFS(16, cmyk)
GIL_DEFINE_ALL_TYPEDEFS(16s,cmyk)
GIL_DEFINE_ALL_TYPEDEFS(32 ,cmyk)
GIL_DEFINE_ALL_TYPEDEFS(32s,cmyk)
GIL_DEFINE_ALL_TYPEDEFS(32f,cmyk)
template <int N> struct devicen_t;
template <int N> struct devicen_layout_t;
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(8, dev2n, devicen_t<2>, devicen_layout_t<2>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(8s, dev2n, devicen_t<2>, devicen_layout_t<2>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(16, dev2n, devicen_t<2>, devicen_layout_t<2>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(16s,dev2n, devicen_t<2>, devicen_layout_t<2>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32 ,dev2n, devicen_t<2>, devicen_layout_t<2>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32s,dev2n, devicen_t<2>, devicen_layout_t<2>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32f,dev2n, devicen_t<2>, devicen_layout_t<2>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(8, dev3n, devicen_t<3>, devicen_layout_t<3>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(8s, dev3n, devicen_t<3>, devicen_layout_t<3>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(16, dev3n, devicen_t<3>, devicen_layout_t<3>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(16s,dev3n, devicen_t<3>, devicen_layout_t<3>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32 ,dev3n, devicen_t<3>, devicen_layout_t<3>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32s,dev3n, devicen_t<3>, devicen_layout_t<3>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32f,dev3n, devicen_t<3>, devicen_layout_t<3>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(8, dev4n, devicen_t<4>, devicen_layout_t<4>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(8s, dev4n, devicen_t<4>, devicen_layout_t<4>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(16, dev4n, devicen_t<4>, devicen_layout_t<4>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(16s,dev4n, devicen_t<4>, devicen_layout_t<4>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32 ,dev4n, devicen_t<4>, devicen_layout_t<4>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32s,dev4n, devicen_t<4>, devicen_layout_t<4>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32f,dev4n, devicen_t<4>, devicen_layout_t<4>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(8, dev5n, devicen_t<5>, devicen_layout_t<5>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(8s, dev5n, devicen_t<5>, devicen_layout_t<5>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(16, dev5n, devicen_t<5>, devicen_layout_t<5>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(16s,dev5n, devicen_t<5>, devicen_layout_t<5>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32 ,dev5n, devicen_t<5>, devicen_layout_t<5>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32s,dev5n, devicen_t<5>, devicen_layout_t<5>)
GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(32f,dev5n, devicen_t<5>, devicen_layout_t<5>)
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,331 @@
/*
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 <cmath>
#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) {}
~point2() {}
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

View File

@ -0,0 +1,136 @@
/*
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_VIRTUAL_LOCATOR_HPP
#define GIL_VIRTUAL_LOCATOR_HPP
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Locator for virtual image views
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on February 12, 2007
///
////////////////////////////////////////////////////////////////////////////////////////
#include <boost/iterator/iterator_facade.hpp>
#include "position_iterator.hpp"
namespace boost { namespace gil {
/// \brief A 2D locator over a virtual image. Upon dereferencing, invokes a given function object passing it its coordinates. Models: PixelLocatorConcept, HasDynamicXStepTypeConcept, HasDynamicYStepTypeConcept, HasTransposedTypeConcept
/// \ingroup PixelLocatorModel PixelBasedModel
///
template <typename Deref, bool IsTransposed> // A function object that given a point returns a reference. Models PixelDereferenceAdaptorConcept
class virtual_2d_locator : public pixel_2d_locator_base<virtual_2d_locator<Deref,IsTransposed>, position_iterator<Deref,IsTransposed>, position_iterator<Deref,1-IsTransposed> > {
typedef virtual_2d_locator<Deref,IsTransposed> this_t;
public:
typedef pixel_2d_locator_base<virtual_2d_locator<Deref,IsTransposed>, position_iterator<Deref,IsTransposed>, position_iterator<Deref,1-IsTransposed> > parent_t;
typedef virtual_2d_locator<typename Deref::const_t,IsTransposed> const_t;
typedef Deref deref_fn_t;
typedef typename parent_t::point_t point_t;
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;
template <typename NewDeref> struct add_deref {
typedef virtual_2d_locator<deref_compose<NewDeref,Deref>,IsTransposed > type;
static type make(const virtual_2d_locator<Deref,IsTransposed>& loc, const NewDeref& nderef) {
return type(loc.pos(), loc.step(), deref_compose<NewDeref,Deref>(nderef,loc.deref_fn()));
}
};
virtual_2d_locator(const point_t& p=point_t(0,0), const point_t& step=point_t(1,1), const deref_fn_t& d=deref_fn_t()) : _p(p,step,d) {}
template <typename D, bool TR> virtual_2d_locator(const virtual_2d_locator<D,TR>& loc, coord_t y_step)
: _p(loc.pos(), point_t(loc.step().x,loc.step().y*y_step), loc.deref_fn()) {}
template <typename D, bool TR> virtual_2d_locator(const virtual_2d_locator<D,TR>& loc, coord_t x_step, coord_t y_step, bool transpose=false)
: _p(loc.pos(), transpose ?
point_t(loc.step().x*y_step,loc.step().y*x_step) :
point_t(loc.step().x*x_step,loc.step().y*y_step), loc.deref_fn()) { assert(transpose==(IsTransposed!=TR));}
template <typename D, bool TR> virtual_2d_locator(const virtual_2d_locator<D,TR>& pl) : _p(pl._p) {}
virtual_2d_locator(const virtual_2d_locator& pl) : _p(pl._p) {}
bool operator==(const this_t& p) const { return _p==p._p; }
x_iterator& x() { return *gil_reinterpret_cast<x_iterator*>(this); }
y_iterator& y() { return _p; }
x_iterator const& x() const { return *gil_reinterpret_cast_c<x_iterator const*>(this); }
y_iterator const& y() const { return _p; }
// Returns the y distance between two x_iterators given the difference of their x positions
y_coord_t y_distance_to(const this_t& it2, x_coord_t xDiff) const { return (it2.pos()[1-IsTransposed] - pos()[1-IsTransposed])/step()[1-IsTransposed]; }
bool is_1d_traversable(x_coord_t) const { return false; } // is there no gap at the end of each row? I.e. can we use x_iterator to visit every pixel instead of nested loops?
// Methods specific for virtual 2D locator
const point_t& pos() const { return _p.pos(); }
const point_t& step() const { return _p.step(); }
const deref_fn_t& deref_fn() const { return _p.deref_fn(); }
private:
template <typename D, bool TR> friend class virtual_2d_locator;
y_iterator _p; // contains the current position, the step and the dereference object
};
/////////////////////////////
// PixelBasedConcept
/////////////////////////////
template <typename D, bool TR>
struct channel_type<virtual_2d_locator<D,TR> > : public channel_type<typename virtual_2d_locator<D,TR>::parent_t> {
};
template <typename D, bool TR>
struct color_space_type<virtual_2d_locator<D,TR> > : public color_space_type<typename virtual_2d_locator<D,TR>::parent_t> {
};
template <typename D, bool TR>
struct channel_mapping_type<virtual_2d_locator<D,TR> > : public channel_mapping_type<typename virtual_2d_locator<D,TR>::parent_t> {
};
template <typename D, bool TR>
struct is_planar<virtual_2d_locator<D,TR> > : public is_planar<typename virtual_2d_locator<D,TR>::parent_t> {
};
/////////////////////////////
// HasDynamicXStepTypeConcept
/////////////////////////////
template <typename D, bool TR>
struct dynamic_x_step_type<virtual_2d_locator<D,TR> > {
typedef virtual_2d_locator<D,TR> type;
};
/////////////////////////////
// HasDynamicYStepTypeConcept
/////////////////////////////
template <typename D, bool TR>
struct dynamic_y_step_type<virtual_2d_locator<D,TR> > {
typedef virtual_2d_locator<D,TR> type;
};
/////////////////////////////
// HasTransposedTypeConcept
/////////////////////////////
template <typename D, bool IsTransposed>
struct transposed_type<virtual_2d_locator<D,IsTransposed> > {
typedef virtual_2d_locator<D,1-IsTransposed> type;
};
} } // namespace boost::gil
#endif

View File

@ -0,0 +1,284 @@
// (C) Copyright Jeremy Siek 2002.
// Distributed under 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)
#ifndef BOOST_ITERATOR_CONCEPTS_HPP
#define BOOST_ITERATOR_CONCEPTS_HPP
#include <boost/concept_check.hpp>
#include <boost/iterator/iterator_categories.hpp>
// Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems.
#include <boost/detail/iterator.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <boost/static_assert.hpp>
// Use boost/limits to work around missing limits headers on some compilers
#include <boost/limits.hpp>
#include <boost/config.hpp>
#include <algorithm>
#include <boost/concept/detail/concept_def.hpp>
namespace boost_concepts
{
// Used a different namespace here (instead of "boost") so that the
// concept descriptions do not take for granted the names in
// namespace boost.
//===========================================================================
// Iterator Access Concepts
BOOST_concept(ReadableIterator,(Iterator))
: boost::Assignable<Iterator>
, boost::CopyConstructible<Iterator>
{
typedef BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type value_type;
typedef BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference reference;
BOOST_CONCEPT_USAGE(ReadableIterator)
{
value_type v = *i;
boost::ignore_unused_variable_warning(v);
}
private:
Iterator i;
};
template <
typename Iterator
, typename ValueType = BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type
>
struct WritableIterator
: boost::CopyConstructible<Iterator>
{
BOOST_CONCEPT_USAGE(WritableIterator)
{
*i = v;
}
private:
ValueType v;
Iterator i;
};
template <
typename Iterator
, typename ValueType = BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type
>
struct WritableIteratorConcept : WritableIterator<Iterator,ValueType> {};
BOOST_concept(SwappableIterator,(Iterator))
{
BOOST_CONCEPT_USAGE(SwappableIterator)
{
std::iter_swap(i1, i2);
}
private:
Iterator i1;
Iterator i2;
};
BOOST_concept(LvalueIterator,(Iterator))
{
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
BOOST_CONCEPT_USAGE(LvalueIterator)
{
value_type& r = const_cast<value_type&>(*i);
boost::ignore_unused_variable_warning(r);
}
private:
Iterator i;
};
//===========================================================================
// Iterator Traversal Concepts
BOOST_concept(IncrementableIterator,(Iterator))
: boost::Assignable<Iterator>
, boost::CopyConstructible<Iterator>
{
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
BOOST_CONCEPT_ASSERT((
boost::Convertible<
traversal_category
, boost::incrementable_traversal_tag
>));
BOOST_CONCEPT_USAGE(IncrementableIterator)
{
++i;
(void)i++;
}
private:
Iterator i;
};
BOOST_concept(SinglePassIterator,(Iterator))
: IncrementableIterator<Iterator>
, boost::EqualityComparable<Iterator>
{
BOOST_CONCEPT_ASSERT((
boost::Convertible<
BOOST_DEDUCED_TYPENAME SinglePassIterator::traversal_category
, boost::single_pass_traversal_tag
> ));
};
BOOST_concept(ForwardTraversal,(Iterator))
: SinglePassIterator<Iterator>
, boost::DefaultConstructible<Iterator>
{
typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type;
BOOST_MPL_ASSERT((boost::is_integral<difference_type>));
BOOST_MPL_ASSERT_RELATION(std::numeric_limits<difference_type>::is_signed, ==, true);
BOOST_CONCEPT_ASSERT((
boost::Convertible<
BOOST_DEDUCED_TYPENAME ForwardTraversal::traversal_category
, boost::forward_traversal_tag
> ));
};
BOOST_concept(BidirectionalTraversal,(Iterator))
: ForwardTraversal<Iterator>
{
BOOST_CONCEPT_ASSERT((
boost::Convertible<
BOOST_DEDUCED_TYPENAME BidirectionalTraversal::traversal_category
, boost::bidirectional_traversal_tag
> ));
BOOST_CONCEPT_USAGE(BidirectionalTraversal)
{
--i;
(void)i--;
}
private:
Iterator i;
};
BOOST_concept(RandomAccessTraversal,(Iterator))
: BidirectionalTraversal<Iterator>
{
BOOST_CONCEPT_ASSERT((
boost::Convertible<
BOOST_DEDUCED_TYPENAME RandomAccessTraversal::traversal_category
, boost::random_access_traversal_tag
> ));
BOOST_CONCEPT_USAGE(RandomAccessTraversal)
{
i += n;
i = i + n;
i = n + i;
i -= n;
i = i - n;
n = i - j;
}
private:
typename BidirectionalTraversal<Iterator>::difference_type n;
Iterator i, j;
};
//===========================================================================
// Iterator Interoperability
namespace detail
{
template <typename Iterator1, typename Iterator2>
void interop_single_pass_constraints(Iterator1 const& i1, Iterator2 const& i2)
{
bool b;
b = i1 == i2;
b = i1 != i2;
b = i2 == i1;
b = i2 != i1;
boost::ignore_unused_variable_warning(b);
}
template <typename Iterator1, typename Iterator2>
void interop_rand_access_constraints(
Iterator1 const& i1, Iterator2 const& i2,
boost::random_access_traversal_tag, boost::random_access_traversal_tag)
{
bool b;
typename boost::detail::iterator_traits<Iterator2>::difference_type n;
b = i1 < i2;
b = i1 <= i2;
b = i1 > i2;
b = i1 >= i2;
n = i1 - i2;
b = i2 < i1;
b = i2 <= i1;
b = i2 > i1;
b = i2 >= i1;
n = i2 - i1;
boost::ignore_unused_variable_warning(b);
boost::ignore_unused_variable_warning(n);
}
template <typename Iterator1, typename Iterator2>
void interop_rand_access_constraints(
Iterator1 const&, Iterator2 const&,
boost::single_pass_traversal_tag, boost::single_pass_traversal_tag)
{ }
} // namespace detail
BOOST_concept(InteroperableIterator,(Iterator)(ConstIterator))
{
private:
typedef typename boost::detail::pure_traversal_tag<
typename boost::iterator_traversal<
Iterator
>::type
>::type traversal_category;
typedef typename boost::detail::pure_traversal_tag<
typename boost::iterator_traversal<
ConstIterator
>::type
>::type const_traversal_category;
public:
BOOST_CONCEPT_ASSERT((SinglePassIterator<Iterator>));
BOOST_CONCEPT_ASSERT((SinglePassIterator<ConstIterator>));
BOOST_CONCEPT_USAGE(InteroperableIterator)
{
detail::interop_single_pass_constraints(i, ci);
detail::interop_rand_access_constraints(i, ci, traversal_category(), const_traversal_category());
ci = i;
}
private:
Iterator i;
ConstIterator ci;
};
} // namespace boost_concepts
#include <boost/concept/detail/concept_undef.hpp>
#endif // BOOST_ITERATOR_CONCEPTS_HPP

View File

@ -0,0 +1,39 @@
#ifndef BOOST_MPL_ACCUMULATE_HPP_INCLUDED
#define BOOST_MPL_ACCUMULATE_HPP_INCLUDED
// Copyright Aleksey Gurtovoy 2001-2004
// Copyright David Abrahams 2001-2002
//
// Distributed under 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://www.boost.org/libs/mpl for documentation.
// $Source$
// $Date: 2005-01-19 10:20:21 -0500 (Wed, 19 Jan 2005) $
// $Revision: 26742 $
#include <boost/mpl/fold.hpp>
#include <boost/mpl/aux_/na_spec.hpp>
#include <boost/mpl/aux_/lambda_support.hpp>
namespace boost { namespace mpl {
template<
typename BOOST_MPL_AUX_NA_PARAM(Sequence)
, typename BOOST_MPL_AUX_NA_PARAM(State)
, typename BOOST_MPL_AUX_NA_PARAM(ForwardOp)
>
struct accumulate
: fold<Sequence,State,ForwardOp>
{
BOOST_MPL_AUX_LAMBDA_SUPPORT(3,accumulate,(Sequence,State,ForwardOp))
};
BOOST_MPL_AUX_NA_SPEC(3, accumulate)
}}
#endif // BOOST_MPL_ACCUMULATE_HPP_INCLUDED

View File

@ -0,0 +1,31 @@
#ifndef BOOST_MPL_AUX_RANGE_C_O1_SIZE_HPP_INCLUDED
#define BOOST_MPL_AUX_RANGE_C_O1_SIZE_HPP_INCLUDED
// Copyright Aleksey Gurtovoy 2000-2004
//
// Distributed under 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://www.boost.org/libs/mpl for documentation.
// $Source$
// $Date: 2004-09-02 11:41:37 -0400 (Thu, 02 Sep 2004) $
// $Revision: 24874 $
#include <boost/mpl/O1_size_fwd.hpp>
#include <boost/mpl/aux_/range_c/size.hpp>
#include <boost/mpl/aux_/range_c/tag.hpp>
namespace boost { namespace mpl {
template<>
struct O1_size_impl< aux::half_open_range_tag >
: size_impl< aux::half_open_range_tag >
{
};
}}
#endif // BOOST_MPL_AUX_RANGE_C_O1_SIZE_HPP_INCLUDED

View File

@ -0,0 +1,34 @@
#ifndef BOOST_MPL_AUX_RANGE_C_BACK_HPP_INCLUDED
#define BOOST_MPL_AUX_RANGE_C_BACK_HPP_INCLUDED
// Copyright Aleksey Gurtovoy 2000-2004
//
// Distributed under 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://www.boost.org/libs/mpl for documentation.
// $Source$
// $Date: 2004-09-02 11:41:37 -0400 (Thu, 02 Sep 2004) $
// $Revision: 24874 $
#include <boost/mpl/back_fwd.hpp>
#include <boost/mpl/prior.hpp>
#include <boost/mpl/aux_/range_c/tag.hpp>
namespace boost { namespace mpl {
template<>
struct back_impl< aux::half_open_range_tag >
{
template< typename Range > struct apply
{
typedef typename prior< typename Range::finish >::type type;
};
};
}}
#endif // BOOST_MPL_AUX_RANGE_C_BACK_HPP_INCLUDED

View File

@ -0,0 +1,37 @@
#ifndef BOOST_MPL_AUX_RANGE_C_EMPTY_HPP_INCLUDED
#define BOOST_MPL_AUX_RANGE_C_EMPTY_HPP_INCLUDED
// Copyright Aleksey Gurtovoy 2000-2004
//
// Distributed under 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://www.boost.org/libs/mpl for documentation.
// $Source$
// $Date: 2004-09-02 11:41:37 -0400 (Thu, 02 Sep 2004) $
// $Revision: 24874 $
#include <boost/mpl/empty_fwd.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/aux_/range_c/tag.hpp>
namespace boost { namespace mpl {
template<>
struct empty_impl< aux::half_open_range_tag >
{
template< typename Range > struct apply
: equal_to<
typename Range::start
, typename Range::finish
>
{
};
};
}}
#endif // BOOST_MPL_AUX_RANGE_C_EMPTY_HPP_INCLUDED

View File

@ -0,0 +1,33 @@
#ifndef BOOST_MPL_AUX_RANGE_C_FRONT_HPP_INCLUDED
#define BOOST_MPL_AUX_RANGE_C_FRONT_HPP_INCLUDED
// Copyright Aleksey Gurtovoy 2000-2004
//
// Distributed under 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://www.boost.org/libs/mpl for documentation.
// $Source$
// $Date: 2004-09-02 11:41:37 -0400 (Thu, 02 Sep 2004) $
// $Revision: 24874 $
#include <boost/mpl/front_fwd.hpp>
#include <boost/mpl/aux_/range_c/tag.hpp>
namespace boost { namespace mpl {
template<>
struct front_impl< aux::half_open_range_tag >
{
template< typename Range > struct apply
{
typedef typename Range::start type;
};
};
}}
#endif // BOOST_MPL_AUX_RANGE_C_FRONT_HPP_INCLUDED

View File

@ -0,0 +1,106 @@
#ifndef BOOST_MPL_AUX_RANGE_C_ITERATOR_HPP_INCLUDED
#define BOOST_MPL_AUX_RANGE_C_ITERATOR_HPP_INCLUDED
// Copyright Aleksey Gurtovoy 2000-2004
//
// Distributed under 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://www.boost.org/libs/mpl for documentation.
// $Source$
// $Date: 2004-12-20 12:52:43 -0500 (Mon, 20 Dec 2004) $
// $Revision: 26558 $
#include <boost/mpl/iterator_tags.hpp>
#include <boost/mpl/advance_fwd.hpp>
#include <boost/mpl/distance_fwd.hpp>
#include <boost/mpl/next_prior.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/minus.hpp>
#include <boost/mpl/aux_/value_wknd.hpp>
#include <boost/mpl/aux_/config/ctps.hpp>
namespace boost { namespace mpl {
// theoretically will work on any discrete numeric type
template< typename N > struct r_iter
{
typedef aux::r_iter_tag tag;
typedef random_access_iterator_tag category;
typedef N type;
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
typedef r_iter< typename mpl::next<N>::type > next;
typedef r_iter< typename mpl::prior<N>::type > prior;
#endif
};
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template<
typename N
>
struct next< r_iter<N> >
{
typedef r_iter< typename mpl::next<N>::type > type;
};
template<
typename N
>
struct prior< r_iter<N> >
{
typedef r_iter< typename mpl::prior<N>::type > type;
};
#endif
template<> struct advance_impl<aux::r_iter_tag>
{
template< typename Iter, typename Dist > struct apply
{
typedef typename deref<Iter>::type n_;
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
typedef typename plus_impl<integral_c_tag,integral_c_tag>
::template apply<n_,Dist>::type m_;
#else
typedef typename plus<n_,Dist>::type m_;
#endif
// agurt, 10/nov/04: to be generic, the code have to do something along
// the lines below...
//
// typedef typename apply_wrap1<
// numeric_cast< typename m_::tag, typename n_::tag >
// , m_
// >::type result_;
//
// ... meanwhile:
typedef integral_c<
typename aux::value_type_wknd<n_>::type
, BOOST_MPL_AUX_VALUE_WKND(m_)::value
> result_;
typedef r_iter<result_> type;
};
};
template<> struct distance_impl<aux::r_iter_tag>
{
template< typename Iter1, typename Iter2 > struct apply
: minus<
typename Iter2::type
, typename Iter1::type
>
{
};
};
}}
#endif // BOOST_MPL_AUX_RANGE_C_ITERATOR_HPP_INCLUDED

View File

@ -0,0 +1,37 @@
#ifndef BOOST_MPL_AUX_RANGE_C_SIZE_HPP_INCLUDED
#define BOOST_MPL_AUX_RANGE_C_SIZE_HPP_INCLUDED
// Copyright Aleksey Gurtovoy 2000-2004
//
// Distributed under 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://www.boost.org/libs/mpl for documentation.
// $Source$
// $Date: 2004-09-02 11:41:37 -0400 (Thu, 02 Sep 2004) $
// $Revision: 24874 $
#include <boost/mpl/size_fwd.hpp>
#include <boost/mpl/minus.hpp>
#include <boost/mpl/aux_/range_c/tag.hpp>
namespace boost { namespace mpl {
template<>
struct size_impl< aux::half_open_range_tag >
{
template< typename Range > struct apply
: minus<
typename Range::finish
, typename Range::start
>
{
};
};
}}
#endif // BOOST_MPL_AUX_RANGE_C_SIZE_HPP_INCLUDED

View File

@ -0,0 +1,24 @@
#ifndef BOOST_MPL_AUX_RANGE_C_TAG_HPP_INCLUDED
#define BOOST_MPL_AUX_RANGE_C_TAG_HPP_INCLUDED
// Copyright Aleksey Gurtovoy 2000-2004
//
// Distributed under 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://www.boost.org/libs/mpl for documentation.
// $Source$
// $Date: 2004-11-27 20:39:23 -0500 (Sat, 27 Nov 2004) $
// $Revision: 26324 $
namespace boost { namespace mpl { namespace aux {
struct half_open_range_tag;
struct r_iter_tag;
}}}
#endif // BOOST_MPL_AUX_RANGE_C_TAG_HPP_INCLUDED

19
src/3rdparty/include/boost/mpl/max.hpp vendored Normal file
View File

@ -0,0 +1,19 @@
#ifndef BOOST_MPL_MAX_HPP_INCLUDED
#define BOOST_MPL_MAX_HPP_INCLUDED
// Copyright Aleksey Gurtovoy 2004
//
// Distributed under 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://www.boost.org/libs/mpl for documentation.
// $Source$
// $Date: 2004-11-27 20:58:27 -0500 (Sat, 27 Nov 2004) $
// $Revision: 26325 $
#include <boost/mpl/min_max.hpp>
#endif // BOOST_MPL_MAX_HPP_INCLUDED

View File

@ -0,0 +1,48 @@
#ifndef BOOST_MPL_RANGE_C_HPP_INCLUDED
#define BOOST_MPL_RANGE_C_HPP_INCLUDED
// Copyright Aleksey Gurtovoy 2000-2004
//
// Distributed under 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://www.boost.org/libs/mpl for documentation.
// $Source$
// $Date: 2004-11-27 20:58:27 -0500 (Sat, 27 Nov 2004) $
// $Revision: 26325 $
#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/aux_/range_c/front.hpp>
#include <boost/mpl/aux_/range_c/back.hpp>
#include <boost/mpl/aux_/range_c/size.hpp>
#include <boost/mpl/aux_/range_c/O1_size.hpp>
#include <boost/mpl/aux_/range_c/empty.hpp>
#include <boost/mpl/aux_/range_c/iterator.hpp>
#include <boost/mpl/aux_/range_c/tag.hpp>
namespace boost { namespace mpl {
template<
typename T
, T Start
, T Finish
>
struct range_c
{
typedef aux::half_open_range_tag tag;
typedef T value_type;
typedef range_c type;
typedef integral_c<T,Start> start;
typedef integral_c<T,Finish> finish;
typedef r_iter<start> begin;
typedef r_iter<finish> end;
};
}}
#endif // BOOST_MPL_RANGE_C_HPP_INCLUDED

View File

@ -0,0 +1,60 @@
#ifndef BOOST_MPL_VECTOR_C_HPP_INCLUDED
#define BOOST_MPL_VECTOR_C_HPP_INCLUDED
// Copyright Aleksey Gurtovoy 2000-2004
//
// Distributed under 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://www.boost.org/libs/mpl for documentation.
// $Source$
// $Date: 2004-11-27 20:58:27 -0500 (Sat, 27 Nov 2004) $
// $Revision: 26325 $
#if !defined(BOOST_MPL_PREPROCESSING_MODE)
# include <boost/mpl/limits/vector.hpp>
# include <boost/mpl/aux_/nttp_decl.hpp>
# include <boost/mpl/aux_/config/preprocessor.hpp>
# include <boost/preprocessor/inc.hpp>
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/stringize.hpp>
#if !defined(BOOST_NEEDS_TOKEN_PASTING_OP_FOR_TOKENS_JUXTAPOSING)
# define AUX778076_VECTOR_C_HEADER \
BOOST_PP_CAT(BOOST_PP_CAT(vector,BOOST_MPL_LIMIT_VECTOR_SIZE),_c).hpp \
/**/
#else
# define AUX778076_VECTOR_C_HEADER \
BOOST_PP_CAT(BOOST_PP_CAT(vector,BOOST_MPL_LIMIT_VECTOR_SIZE),_c)##.hpp \
/**/
#endif
# include BOOST_PP_STRINGIZE(boost/mpl/vector/AUX778076_VECTOR_C_HEADER)
# undef AUX778076_VECTOR_C_HEADER
# include <climits>
#endif
#include <boost/mpl/aux_/config/use_preprocessed.hpp>
#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
&& !defined(BOOST_MPL_PREPROCESSING_MODE)
# define BOOST_MPL_PREPROCESSED_HEADER vector_c.hpp
# include <boost/mpl/aux_/include_preprocessed.hpp>
#else
# include <boost/mpl/limits/vector.hpp>
# define AUX778076_SEQUENCE_NAME vector_c
# define AUX778076_SEQUENCE_LIMIT BOOST_MPL_LIMIT_VECTOR_SIZE
# define AUX778076_SEQUENCE_NAME_N(n) BOOST_PP_CAT(BOOST_PP_CAT(vector,n),_c)
# define AUX778076_SEQUENCE_INTEGRAL_WRAPPER
# include <boost/mpl/aux_/sequence_wrapper.hpp>
#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
#endif // BOOST_MPL_VECTOR_C_HPP_INCLUDED

3592
src/3rdparty/include/png.h vendored Normal file

File diff suppressed because it is too large Load Diff

1481
src/3rdparty/include/pngconf.h vendored Normal file

File diff suppressed because it is too large Load Diff

332
src/3rdparty/include/zconf.h vendored Normal file
View File

@ -0,0 +1,332 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#ifndef ZCONF_H
#define ZCONF_H
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
*/
#ifdef Z_PREFIX
# define deflateInit_ z_deflateInit_
# define deflate z_deflate
# define deflateEnd z_deflateEnd
# define inflateInit_ z_inflateInit_
# define inflate z_inflate
# define inflateEnd z_inflateEnd
# define deflateInit2_ z_deflateInit2_
# define deflateSetDictionary z_deflateSetDictionary
# define deflateCopy z_deflateCopy
# define deflateReset z_deflateReset
# define deflateParams z_deflateParams
# define deflateBound z_deflateBound
# define deflatePrime z_deflatePrime
# define inflateInit2_ z_inflateInit2_
# define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateCopy z_inflateCopy
# define inflateReset z_inflateReset
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
# define compress z_compress
# define compress2 z_compress2
# define compressBound z_compressBound
# define uncompress z_uncompress
# define adler32 z_adler32
# define crc32 z_crc32
# define get_crc_table z_get_crc_table
# define zError z_zError
# define alloc_func z_alloc_func
# define free_func z_free_func
# define in_func z_in_func
# define out_func z_out_func
# define Byte z_Byte
# define uInt z_uInt
# define uLong z_uLong
# define Bytef z_Bytef
# define charf z_charf
# define intf z_intf
# define uIntf z_uIntf
# define uLongf z_uLongf
# define voidpf z_voidpf
# define voidp z_voidp
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
# define OS2
#endif
#if defined(_WINDOWS) && !defined(WINDOWS)
# define WINDOWS
#endif
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
# ifndef WIN32
# define WIN32
# endif
#endif
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
# ifndef SYS16BIT
# define SYS16BIT
# endif
# endif
#endif
/*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int).
*/
#ifdef SYS16BIT
# define MAXSEG_64K
#endif
#ifdef MSDOS
# define UNALIGNED_OK
#endif
#ifdef __STDC_VERSION__
# ifndef STDC
# define STDC
# endif
# if __STDC_VERSION__ >= 199901L
# ifndef STDC99
# define STDC99
# endif
# endif
#endif
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
# define STDC
#endif
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
# define STDC
#endif
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
# define STDC
#endif
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
# define STDC
#endif
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
# define STDC
#endif
#ifndef STDC
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const /* note: need a more gentle solution here */
# endif
#endif
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL
#endif
/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K
# define MAX_MEM_LEVEL 8
# else
# define MAX_MEM_LEVEL 9
# endif
#endif
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
* created by gzip. (Files created by minigzip can still be extracted by
* gzip.)
*/
#ifndef MAX_WBITS
# define MAX_WBITS 15 /* 32K LZ77 window */
#endif
/* The memory requirements for deflate are (in bytes):
(1 << (windowBits+2)) + (1 << (memLevel+9))
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
plus a few kilobytes for small objects. For example, if you want to reduce
the default memory requirements from 256K to 128K, compile with
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
Of course this will generally degrade compression (there's no free lunch).
The memory requirements for inflate are (in bytes) 1 << windowBits
that is, 32K for windowBits=15 (default value) plus a few kilobytes
for small objects.
*/
/* Type declarations */
#ifndef OF /* function prototypes */
# ifdef STDC
# define OF(args) args
# else
# define OF(args) ()
# endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty.
*/
#ifdef SYS16BIT
# if defined(M_I86SM) || defined(M_I86MM)
/* MSC small or medium model */
# define SMALL_MEDIUM
# ifdef _MSC_VER
# define FAR _far
# else
# define FAR far
# endif
# endif
# if (defined(__SMALL__) || defined(__MEDIUM__))
/* Turbo C small or medium model */
# define SMALL_MEDIUM
# ifdef __BORLANDC__
# define FAR _far
# else
# define FAR far
# endif
# endif
#endif
#if defined(WINDOWS) || defined(WIN32)
/* If building or using zlib as a DLL, define ZLIB_DLL.
* This is not mandatory, but it offers a little performance increase.
*/
# ifdef ZLIB_DLL
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
# ifdef ZLIB_INTERNAL
# define ZEXTERN extern __declspec(dllexport)
# else
# define ZEXTERN extern __declspec(dllimport)
# endif
# endif
# endif /* ZLIB_DLL */
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
* define ZLIB_WINAPI.
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
*/
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif
#endif
#if defined (__BEOS__)
# ifdef ZLIB_DLL
# ifdef ZLIB_INTERNAL
# define ZEXPORT __declspec(dllexport)
# define ZEXPORTVA __declspec(dllexport)
# else
# define ZEXPORT __declspec(dllimport)
# define ZEXPORTVA __declspec(dllimport)
# endif
# endif
#endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef ZEXPORT
# define ZEXPORT
#endif
#ifndef ZEXPORTVA
# define ZEXPORTVA
#endif
#ifndef FAR
# define FAR
#endif
#if !defined(__MACTYPES__)
typedef unsigned char Byte; /* 8 bits */
#endif
typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */
#ifdef SMALL_MEDIUM
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
# define Bytef Byte FAR
#else
typedef Byte FAR Bytef;
#endif
typedef char FAR charf;
typedef int FAR intf;
typedef uInt FAR uIntf;
typedef uLong FAR uLongf;
#ifdef STDC
typedef void const *voidpc;
typedef void FAR *voidpf;
typedef void *voidp;
#else
typedef Byte const *voidpc;
typedef Byte FAR *voidpf;
typedef Byte *voidp;
#endif
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
# include <sys/types.h> /* for off_t */
# include <unistd.h> /* for SEEK_* and off_t */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# define z_off_t off_t
#endif
#ifndef SEEK_SET
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
#endif
#ifndef z_off_t
# define z_off_t long
#endif
#if defined(__OS400__)
# define NO_vsnprintf
#endif
#if defined(__MVS__)
# define NO_vsnprintf
# ifdef FAR
# undef FAR
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__)
# pragma map(deflateInit_,"DEIN")
# pragma map(deflateInit2_,"DEIN2")
# pragma map(deflateEnd,"DEEND")
# pragma map(deflateBound,"DEBND")
# pragma map(inflateInit_,"ININ")
# pragma map(inflateInit2_,"ININ2")
# pragma map(inflateEnd,"INEND")
# pragma map(inflateSync,"INSY")
# pragma map(inflateSetDictionary,"INSEDI")
# pragma map(compressBound,"CMBND")
# pragma map(inflate_table,"INTABL")
# pragma map(inflate_fast,"INFA")
# pragma map(inflate_copyright,"INCOPY")
#endif
#endif /* ZCONF_H */

1357
src/3rdparty/include/zlib.h vendored Normal file

File diff suppressed because it is too large Load Diff

BIN
src/3rdparty/lib/libpng.lib vendored Normal file

Binary file not shown.

BIN
src/3rdparty/lib/libpngd.lib vendored Normal file

Binary file not shown.

BIN
src/3rdparty/lib/zlib.lib vendored Normal file

Binary file not shown.

BIN
src/3rdparty/lib/zlibd.lib vendored Normal file

Binary file not shown.

View File

@ -260,7 +260,7 @@ int Connection::LastInsertedId(){
///This will set all the initial PRAGMAS
//////////////////////////////////////////
void Connection::Initialize(unsigned int cache){
sqlite3_enable_shared_cache(1);
// sqlite3_enable_shared_cache(1);
sqlite3_busy_timeout(this->connection,10000);
sqlite3_exec(this->connection,"PRAGMA synchronous=OFF",NULL,NULL,NULL); // Not a critical DB. Sync set to OFF
@ -373,7 +373,7 @@ void Connection::Maintenance(bool init){
}
int Connection::StepStatement(sqlite3_stmt *stmt){
int waitCount(100);
/* int waitCount(100);
int error(0);
do{
error = sqlite3_step(stmt);
@ -382,6 +382,6 @@ int Connection::StepStatement(sqlite3_stmt *stmt){
waitCount--;
}
}while(error==SQLITE_LOCKED && waitCount>0);
return error;
*/
return sqlite3_step(stmt);
}

View File

@ -2,7 +2,7 @@
//
// License Agreement:
//
// The following are Copyright © 2007, Casey Langen
// The following are Copyright 2007, Casey Langen
//
// Sources and Binaries of: mC2, win32cpp
//
@ -42,7 +42,7 @@
#include <win32cpp/ListView.hpp>
#include <win32cpp/Splitter.hpp>
#include <win32cpp/BarLayout.hpp>
#include <win32cpp/LinearLayout.hpp>
//////////////////////////////////////////////////////////////////////////////
@ -56,7 +56,7 @@ using namespace musik::cube;
void BrowseView::OnCreated()
{
this->filterViewLayout = new BarLayout(BarColumnLayout);
this->filterViewLayout = new LinearLayout(win32cpp::HorizontalLayout,win32cpp::LayoutFillFill);
this->tracklistView = new TracklistView();
mainVSplitter = new Splitter(
@ -76,6 +76,7 @@ void BrowseView::OnCreated()
void BrowseView::AddMetadataFilter(const uistring& metadataKey)
{
ListView* listView = new ListView();
listView->SetLayoutFlags(win32cpp::LayoutFillFill);
this->filterViews.push_back(listView);
this->filterKeyMap[listView] = metadataKey;

View File

@ -2,7 +2,7 @@
//
// License Agreement:
//
// The following are Copyright © 2007, Casey Langen
// The following are Copyright 2007, Casey Langen
//
// Sources and Binaries of: mC2, win32cpp
//
@ -43,7 +43,7 @@
namespace win32cpp{
class ListView;
class Splitter;
class BarLayout;
class LinearLayout;
}
namespace musik{ namespace cube{
class TracklistView;
@ -74,7 +74,7 @@ protected: void AddMetadataFilter(const uistring& metadataKey);
protected: typedef std::vector<ListView*> FilterViewList;
protected: typedef std::map<ListView*, uistring> FilterToMetadataKeyMap;
protected: BarLayout* filterViewLayout;
protected: LinearLayout* filterViewLayout;
protected: TracklistView* tracklistView;
protected: FilterViewList filterViews;
protected: FilterToMetadataKeyMap filterKeyMap;

View File

@ -52,20 +52,13 @@ using namespace musik::cube;
/*dtor*/ LibraryWindowView::~LibraryWindowView()
{
// make sure not to delete any SourcesItem views, and also
// automatically delete the defaultView.
// this->SetView(this->defaultView);
}
void LibraryWindowView::OnCreated()
{
this->SetPadding(0);
}
/*
void SourcesView::OnCreated()
{
// add main splitter as the top level window's main window
this->splitter = this->AddChild(
new Splitter(SplitColumn, this->listView, this->defaultView));
this->splitter->SetAnchorSize(125);
}
void SourcesView::OnListViewCreated(Window* window)
{
typedef ListView::Column Column;

View File

@ -65,21 +65,7 @@ public: friend class LibraryWindowController;
public: /*ctor*/ LibraryWindowView();
public: /*dtor*/ ~LibraryWindowView();
/*
protected: void SetView(Window* newView); // used by SourcesController
protected: void OnListViewCreated(Window* window);
protected: void OnListViewResized(Window* window, Size size);
protected: void OnListViewThemeChanged(Window* window);
protected: void OnListViewHotRowChanged(ListView* listView, int rowIndex);
protected: void UpdateListViewBkgndColor();
protected: virtual void OnCreated();
protected: ListView* listView;
protected: ListView::ColumnRef mainColumn;
protected: int lastHotRowIndex;
protected: Window* defaultView;
protected: Splitter* splitter;*/
};
//////////////////////////////////////////////////////////////////////////////

View File

@ -129,18 +129,19 @@ void MainWindowController::OnMainWindowCreated(Window* window)
LibraryWindowView* libraryView = new LibraryWindowView();
this->libraryController = new LibraryWindowController(*libraryView);
// Create a Frame that suround everything
this->clientView = this->mainWindow.AddChild(new Frame(0,4));
this->clientView->SetLayoutFlags(win32cpp::LayoutFillFill);
// the main splitter
Splitter* transportSplitter = this->mainWindow.AddChild(
Splitter* transportSplitter = this->clientView->AddChild(
new Splitter(SplitRow, libraryView, transportView));
// set initial sizes
transportSplitter->Resize(clientSize);
transportSplitter->SetAnchor(AnchorBottom);
transportSplitter->SetAnchorSize(TransportViewHeight);
transportSplitter->SetSizable(false);
this->clientView = transportSplitter;
this->mainWindow.Resized.connect(this, &MainWindowController::OnResize);
this->mainWindow.Destroyed.connect(this, &MainWindowController::OnDestroyed);
}

View File

@ -45,6 +45,7 @@ namespace win32cpp{
class TabView;
class Window;
class TopLevelWindow;
class Frame;
}
namespace musik { namespace cube {
class SourcesController;
@ -80,7 +81,7 @@ protected: void OnDestroyed(Window* window);
protected: void OnFileExit(MenuItemRef menuItem);
protected: TopLevelWindow& mainWindow;
protected: Splitter* clientView;
protected: win32cpp::Frame* clientView;
protected: LibraryWindowController* libraryController;
protected: TransportController* transportController;

View File

@ -2,7 +2,7 @@
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
// The following are Copyright 2007, mC2 Team
//
// Sources and Binaries of: mC2, win32cpp
//
@ -66,6 +66,7 @@ using namespace musik::cube;
void SettingsController::OnViewCreated(Window* window)
{
this->settingsView.SetLayoutFlags(win32cpp::LayoutFillFill);
this->settingsView.addPathButton->Pressed.connect(this,&SettingsController::OnAddPath);
this->settingsView.removePathButton->Pressed.connect(this,&SettingsController::OnRemovePath);

View File

@ -2,7 +2,7 @@
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
// The following are Copyright 2007, mC2 Team
//
// Sources and Binaries of: mC2, win32cpp
//
@ -111,6 +111,7 @@ public:
/*ctor*/ SettingsView::SettingsView()
{
this->SetLayoutFlags(win32cpp::LayoutFillFill);
}
@ -128,10 +129,10 @@ void SettingsView::OnPressTestCheckbox(CheckBox* CheckBox , int state)
void SettingsView::OnCreated()
{
LinearLayout* mainLayout = new LinearLayout(LinearRowLayout);
LinearLayout* pathLayout = new LinearLayout(LinearColumnLayout);
LinearLayout* pathButtonsLayout = new LinearLayout(LinearRowLayout);
LinearLayout* libraryStatusLayout = new LinearLayout(LinearColumnLayout);
LinearLayout* mainLayout = new LinearLayout(VerticalLayout,win32cpp::LayoutFillWrap);
LinearLayout* pathLayout = new LinearLayout(HorizontalLayout);
LinearLayout* pathButtonsLayout = new LinearLayout(VerticalLayout);
LinearLayout* libraryStatusLayout = new LinearLayout(HorizontalLayout);
// Library status
@ -145,14 +146,15 @@ void SettingsView::OnCreated()
// Path list
this->pathList = pathLayout->AddChild(new ListView());
/* win32cpp::ListView::ColumnRef pathColumn = ListView::Column::Create(_T("Path"),1000);
win32cpp::ListView::ColumnRef pathColumn = ListView::Column::Create(_T("Path"),1000);
this->pathList->AddColumn(pathColumn);
this->pathList->SetScrollBarVisibility(win32cpp::ScrollBar::HorizontalScrollBar,false);
*/
pathLayout->SetSizeConstraints(LayoutFillParent,120);
pathLayout->SetFlexibleChild(this->pathList);
pathLayout->SetDefaultChildFill(true);
pathLayout->SetDefaultChildAlignment(ChildAlignRight);
this->pathList->SetLayoutFlags(win32cpp::LayoutFillWrap);
// pathLayout->SetLayoutFlags(win32cpp::LayoutFillFill);
this->pathList->SetLayoutFlags(win32cpp::LayoutFillFill);
this->pathList->SetLayoutAlignment(win32cpp::LayoutAlignRight);
// pathButtons layout
@ -163,18 +165,16 @@ void SettingsView::OnCreated()
this->addPathButton->Resize(90, 24);
this->removePathButton->Resize(90, 24);
pathButtonsLayout->SetDefaultChildFill(false);
pathButtonsLayout->SetDefaultChildAlignment(ChildAlignMiddle);
pathButtonsLayout->SetSizeConstraints(90,LayoutFillParent);
pathLayout->AddChild(pathButtonsLayout);
// Add to the layout
mainLayout->AddChild(new Frame(libraryStatusLayout,FramePadding(20,20,20,0)));
mainLayout->AddChild(new Frame(pathLayout,FramePadding(20,20,0,20)));
win32cpp::Frame *statusFrame = mainLayout->AddChild(new Frame(libraryStatusLayout,FramePadding(20,20,20,0)));
win32cpp::Frame *syncpathFrame = mainLayout->AddChild(new Frame(pathLayout,FramePadding(20,20,0,20)));
syncpathFrame->SetLayoutFlags(win32cpp::LayoutFillFill);
// test CheckBox
CheckBox* c = new CheckBox(_T("Test 1"));
/* CheckBox* c = new CheckBox(_T("Test 1"));
mainLayout->AddChild(c);
c->Check();
c->Pressed.connect(this, &SettingsView::OnPressTestCheckbox);
@ -233,7 +233,7 @@ void SettingsView::OnCreated()
mainLayout->AddChild(cb);
cb->SetModel(cb_testmodel);
cb->Select(2);
*/
this->AddChild(mainLayout);
}

View File

@ -2,7 +2,7 @@
//
// License Agreement:
//
// The following are Copyright © 2007, Casey Langen
// The following are Copyright 2007, Casey Langen
//
// Sources and Binaries of: mC2, win32cpp
//
@ -170,21 +170,7 @@ void TracklistController::OnColumnSort(ListView *listView,ColumnRef column){
TracklistModel* model = (TracklistModel*)this->model.get();
if(tracklistColumn && model){
// what to sort by
/* std::list<std::string> sortList;
sortList.push_back(tracklistColumn->metaKey);
this->sortQuery.SortByMetaKeys(sortList);
*/
model->tracklist->SortTracks(tracklistColumn->metaKey);
// Add the tracks to sort
/* this->sortQuery.AddTracks(*(model->tracklist));
musik::core::LibraryPtr library( model->tracklist->Library());
if(library){
library->AddQuery(this->sortQuery,musik::core::Query::CancelSimilar);
}
this->sortQuery.ClearTracks();*/
}
}

View File

@ -2,7 +2,7 @@
//
// License Agreement:
//
// The following are Copyright © 2007, Casey Langen
// The following are Copyright 2007, Casey Langen
//
// Sources and Binaries of: mC2, win32cpp
//
@ -47,7 +47,7 @@ using namespace musik::cube;
//////////////////////////////////////////////////////////////////////////////
/*ctor*/ TracklistInfoView::TracklistInfoView()
: base(LinearColumnLayout)
: base(HorizontalLayout)
{
}

View File

@ -2,7 +2,7 @@
//
// License Agreement:
//
// The following are Copyright © 2007, Casey Langen
// The following are Copyright 2007, Casey Langen
//
// Sources and Binaries of: mC2, win32cpp
//
@ -49,7 +49,7 @@ using namespace musik::cube;
//////////////////////////////////////////////////////////////////////////////
/*ctor*/ TracklistView::TracklistView()
: base(LinearRowLayout)
: base(VerticalLayout,win32cpp::LayoutFillFill)
, listView(NULL)
, infoView(NULL)
{
@ -58,13 +58,10 @@ using namespace musik::cube;
void TracklistView::OnCreated()
{
this->infoView = this->AddChild(new TracklistInfoView());
//this->listView = this->AddChild(new ListView());
this->infoView->SetLayoutAlignment(win32cpp::LayoutAlignCenter);
// BUG: Workaround of a bug in win32cpp. Create the listView in a Frame instead
this->listView = new ListView();
Frame* listViewFrame = this->AddChild(new Frame(this->listView));
listViewFrame->SetLayoutFlags(win32cpp::LayoutFillFill);
this->SetChildAlignment(this->infoView, ChildAlignCenter);
this->SetChildFill(this->infoView, false);
this->SetFlexibleChild(listViewFrame);
}

View File

@ -2,7 +2,7 @@
//
// License Agreement:
//
// The following are Copyright © 2007, Casey Langen
// The following are Copyright 2007, Casey Langen
//
// Sources and Binaries of: mC2, win32cpp
//
@ -57,13 +57,13 @@ using namespace musik::cube;
void TransportView::OnCreated()
{
// main layout
LinearLayout* mainLayout = new LinearLayout(LinearRowLayout);
LinearLayout* topRowLayout = new LinearLayout(LinearColumnLayout);
LinearLayout* bottomRowLayout = new LinearLayout(LinearColumnLayout);
LinearLayout* mainLayout = new LinearLayout(VerticalLayout);
LinearLayout* topRowLayout = new LinearLayout(HorizontalLayout);
LinearLayout* bottomRowLayout = new LinearLayout(HorizontalLayout);
// top row layout
topRowLayout->SetDefaultChildFill(false);
topRowLayout->SetDefaultChildAlignment(ChildAlignMiddle);
// topRowLayout->SetDefaultChildFill(false);
// topRowLayout->SetDefaultChildAlignment(ChildAlignMiddle);
this->prevButton = topRowLayout->AddChild(new Button(_(_T("Prev"))));
this->playButton = topRowLayout->AddChild(new Button(_(_T("Play"))));
@ -79,7 +79,9 @@ void TransportView::OnCreated()
FontRef boldFont(Font::Create());
boldFont->SetBold(true);
//
LinearLayout* nowPlayingLayout = new LinearLayout(LinearColumnLayout);
LinearLayout* nowPlayingLayout = new LinearLayout(HorizontalLayout);
nowPlayingLayout->SetLayoutFlags(win32cpp::LayoutFillFill);
nowPlayingLayout->SetLayoutAlignment(win32cpp::LayoutAlignMiddle);
//
uistring nowPlayingCaption = _(_T("Now playing"));
nowPlayingCaption += _T(" ");
@ -96,26 +98,25 @@ void TransportView::OnCreated()
//
Frame* nowPlayingFrame = topRowLayout->AddChild(
new Frame(nowPlayingLayout, FramePadding(6, 0, 0, 0)));
topRowLayout->SetChildFill(nowPlayingFrame, false);
topRowLayout->SetChildAlignment(nowPlayingFrame, ChildAlignCenter);
topRowLayout->SetFlexibleChild(nowPlayingFrame);
nowPlayingFrame->SetLayoutFlags(win32cpp::LayoutFillFill);
this->volumeSlider = topRowLayout->AddChild(new Trackbar());
this->volumeSlider->Resize(100, 28);
// bottom row layout
this->timeElapsedLabel = bottomRowLayout->AddChild(new Label(_T("0:00")));
this->timeElapsedLabel->SetLayoutAlignment(win32cpp::LayoutAlignMiddle);
this->playbackSlider = bottomRowLayout->AddChild(new Trackbar(0, 10000));
this->playbackSlider->SetLayoutFlags(win32cpp::LayoutFillFill);
this->timeDurationLabel = bottomRowLayout->AddChild(new Label(_T("0:00")));
//
this->playbackSlider->Resize(100, 20);
this->timeDurationLabel->SetLayoutAlignment(win32cpp::LayoutAlignMiddle);
bottomRowLayout->SetFlexibleChild(playbackSlider);
bottomRowLayout->SetDefaultChildFill(false);
bottomRowLayout->SetDefaultChildAlignment(ChildAlignMiddle);
// put it all together!
mainLayout->AddChild(new Frame(topRowLayout, FramePadding(4, 0, 2, 0)));
mainLayout->AddChild(new Frame(bottomRowLayout, FramePadding(6, 6, 0, 0)));
win32cpp::Frame *topRowFrame = mainLayout->AddChild(new Frame(topRowLayout, FramePadding(4, 0, 2, 0)));
topRowFrame->SetLayoutFlags(win32cpp::LayoutFillFill);
win32cpp::Frame *bottomRowFrame = mainLayout->AddChild(new Frame(bottomRowLayout, FramePadding(6, 6, 0, 0)));
bottomRowFrame->SetLayoutFlags(win32cpp::LayoutFillFill);
this->AddChild(mainLayout);
}

View File

@ -2,7 +2,7 @@
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
// The following are Copyright 2007, mC2 Team
//
// Sources and Binaries of: mC2, win32cpp
//
@ -42,7 +42,6 @@
#include <win32cpp/Label.hpp>
#include <win32cpp/Button.hpp>
#include <win32cpp/LinearLayout.hpp>
#include <win32cpp/BarLayout.hpp>
#include <win32cpp/EditView.hpp>
//////////////////////////////////////////////////////////////////////////////
@ -64,17 +63,17 @@ void AddLibraryView::OnCreated()
boldFont->SetBold(true);
// Top Row layout
LinearLayout* topRowLayout = new LinearLayout(LinearRowLayout);
topRowLayout->SetDefaultChildFill(false);
topRowLayout->SetDefaultChildAlignment(win32cpp::ChildAlignMiddle);
LinearLayout* topRowLayout = new LinearLayout(VerticalLayout);
// topRowLayout->SetDefaultChildFill(false);
// topRowLayout->SetDefaultChildAlignment(win32cpp::ChildAlignMiddle);
Label *label;
Size labelSize(80,0);
// Size labelSize(80,0);
// First rows column layout
LinearLayout* firstColumnLayout = new LinearLayout(LinearColumnLayout);
firstColumnLayout->SetDefaultChildFill(false);
firstColumnLayout->SetDefaultChildAlignment(win32cpp::ChildAlignCenter);
LinearLayout* firstColumnLayout = new LinearLayout(HorizontalLayout);
// firstColumnLayout->SetDefaultChildFill(false);
// firstColumnLayout->SetDefaultChildAlignment(win32cpp::ChildAlignCenter);
label = firstColumnLayout->AddChild(new Label(_T("Add Library")));
label->SetFont(boldFont);
@ -82,11 +81,11 @@ void AddLibraryView::OnCreated()
// Second rows column layout
LinearLayout* secondColumnLayout = new LinearLayout(LinearColumnLayout);
secondColumnLayout->SetDefaultChildAlignment(win32cpp::ChildAlignTop);
LinearLayout* secondColumnLayout = new LinearLayout(HorizontalLayout);
// secondColumnLayout->SetDefaultChildAlignment(win32cpp::ChildAlignTop);
label = secondColumnLayout->AddChild(new Label(_T("Library name:") ));
label->Resize(labelSize);
// label->Resize(labelSize);
this->name = secondColumnLayout->AddChild(new EditView(160,20 ));
topRowLayout->AddChild(secondColumnLayout);
@ -94,41 +93,41 @@ void AddLibraryView::OnCreated()
// Third rows column layout
if(this->type==musik::core::LibraryFactory::Remote){
LinearLayout* row;
row = new LinearLayout(LinearColumnLayout);
row = new LinearLayout(HorizontalLayout);
label = row->AddChild(new Label(_T("Remote host:") ));
label->Resize(labelSize);
// label->Resize(labelSize);
this->remoteHost = row->AddChild(new EditView(160,20 ));
topRowLayout->AddChild(row);
row = new LinearLayout(LinearColumnLayout);
row = new LinearLayout(HorizontalLayout);
label = row->AddChild(new Label(_T("Remote port:") ));
label->Resize(labelSize);
// label->Resize(labelSize);
this->remotePort = row->AddChild(new EditView(100,20 ));
this->remotePort->SetCaption(uistring(_T("10543")));
topRowLayout->AddChild(row);
row = new LinearLayout(LinearColumnLayout);
row = new LinearLayout(HorizontalLayout);
label = row->AddChild(new Label(_T("Username:") ));
label->Resize(labelSize);
// label->Resize(labelSize);
this->username = row->AddChild(new EditView(160,20 ));
topRowLayout->AddChild(row);
row = new LinearLayout(LinearColumnLayout);
row = new LinearLayout(HorizontalLayout);
label = row->AddChild(new Label(_T("Password:") ));
label->Resize(labelSize);
// label->Resize(labelSize);
this->password = row->AddChild(new EditView(160,20 ));
topRowLayout->AddChild(row);
}
// Last rows column layout
LinearLayout* bottomButtonLayout = new LinearLayout(LinearColumnLayout);
bottomButtonLayout->SetDefaultChildFill(false);
LinearLayout* bottomButtonLayout = new LinearLayout(HorizontalLayout);
// bottomButtonLayout->SetDefaultChildFill(false);
this->cancelButton = bottomButtonLayout->AddChild(new Button(_T("Cancel")));
this->okButton = bottomButtonLayout->AddChild(new Button(_T("OK")));
this->cancelButton->Resize(60,20);
this->okButton->Resize(60,20);
topRowLayout->AddChild(bottomButtonLayout);
topRowLayout->SetChildAlignment(bottomButtonLayout,ChildAlignRight);
// topRowLayout->SetChildAlignment(bottomButtonLayout,ChildAlignRight);

View File

@ -43,7 +43,6 @@
#include <win32cpp/Label.hpp>
#include <win32cpp/Button.hpp>
#include <win32cpp/LinearLayout.hpp>
#include <win32cpp/BarLayout.hpp>
#include <win32cpp/EditView.hpp>
// GDI+ for loading the image

View File

@ -2,7 +2,7 @@
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
// The following are Copyright 2007, mC2 Team
//
// All rights reserved.
//
@ -42,7 +42,6 @@
#include <win32cpp/Label.hpp>
#include <win32cpp/Button.hpp>
#include <win32cpp/LinearLayout.hpp>
#include <win32cpp/BarLayout.hpp>
#include <win32cpp/EditView.hpp>
//////////////////////////////////////////////////////////////////////////////
@ -63,17 +62,17 @@ void NewPlaylistView::OnCreated()
boldFont->SetBold(true);
// Top Row layout
LinearLayout* topRowLayout = new LinearLayout(LinearRowLayout);
topRowLayout->SetDefaultChildFill(false);
topRowLayout->SetDefaultChildAlignment(win32cpp::ChildAlignMiddle);
LinearLayout* topRowLayout = new LinearLayout(VerticalLayout);
// topRowLayout->SetDefaultChildFill(false);
// topRowLayout->SetDefaultChildAlignment(win32cpp::ChildAlignMiddle);
Label *label;
Size labelSize(80,0);
// First rows column layout
LinearLayout* firstColumnLayout = new LinearLayout(LinearColumnLayout);
firstColumnLayout->SetDefaultChildFill(false);
firstColumnLayout->SetDefaultChildAlignment(win32cpp::ChildAlignCenter);
LinearLayout* firstColumnLayout = new LinearLayout(HorizontalLayout);
// firstColumnLayout->SetDefaultChildFill(false);
// firstColumnLayout->SetDefaultChildAlignment(win32cpp::ChildAlignCenter);
label = firstColumnLayout->AddChild(new Label(_T("New Playlist")));
label->SetFont(boldFont);
@ -81,8 +80,8 @@ void NewPlaylistView::OnCreated()
// Second rows column layout
LinearLayout* secondColumnLayout = new LinearLayout(LinearColumnLayout);
secondColumnLayout->SetDefaultChildAlignment(win32cpp::ChildAlignTop);
LinearLayout* secondColumnLayout = new LinearLayout(HorizontalLayout);
// secondColumnLayout->SetDefaultChildAlignment(win32cpp::ChildAlignTop);
label = secondColumnLayout->AddChild(new Label(_T("Name:") ));
label->Resize(labelSize);
@ -92,14 +91,14 @@ void NewPlaylistView::OnCreated()
// Last rows column layout
LinearLayout* bottomButtonLayout = new LinearLayout(LinearColumnLayout);
bottomButtonLayout->SetDefaultChildFill(false);
LinearLayout* bottomButtonLayout = new LinearLayout(HorizontalLayout);
// bottomButtonLayout->SetDefaultChildFill(false);
this->cancelButton = bottomButtonLayout->AddChild(new Button(_T("Cancel")));
this->okButton = bottomButtonLayout->AddChild(new Button(_T("OK")));
this->cancelButton->Resize(60,20);
this->okButton->Resize(60,20);
topRowLayout->AddChild(bottomButtonLayout);
topRowLayout->SetChildAlignment(bottomButtonLayout,ChildAlignRight);
// topRowLayout->SetChildAlignment(bottomButtonLayout,ChildAlignRight);

View File

@ -2,7 +2,7 @@
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 team
// The following are Copyright 2007, mC2 team
//
// All rights reserved.
//
@ -122,12 +122,13 @@ void ConnectedUsersController::OnMainWindowCreated(Window* window)
// Create the layout
this->mainFrame = new win32cpp::Frame(NULL,win32cpp::FramePadding(10));
win32cpp::LinearLayout *mainRowLayout = new win32cpp::LinearLayout(win32cpp::LinearRowLayout);
this->mainFrame->SetLayoutFlags(win32cpp::LayoutFillFill);
win32cpp::LinearLayout *mainRowLayout = new win32cpp::LinearLayout(win32cpp::VerticalLayout,win32cpp::LayoutFillFill);
mainRowLayout->SetSpacing(10);
mainRowLayout->SetDefaultChildFill(false);
// First a "Status" of the server
win32cpp::LinearLayout *statusColumnLayout = mainRowLayout->AddChild( new win32cpp::LinearLayout(win32cpp::LinearColumnLayout) );
win32cpp::LinearLayout *statusColumnLayout = mainRowLayout->AddChild( new win32cpp::LinearLayout(win32cpp::HorizontalLayout) );
win32cpp::Label *statusHeader = new win32cpp::Label(_T("Server status "));
statusHeader->SetFont(boldFont);
statusColumnLayout->AddChild( statusHeader );
@ -135,8 +136,7 @@ void ConnectedUsersController::OnMainWindowCreated(Window* window)
// Second a TabView for the settings
win32cpp::ListView *usersList = mainRowLayout->AddChild( new win32cpp::ListView() );
mainRowLayout->SetChildFill(usersList,true);
mainRowLayout->SetFlexibleChild(usersList);
usersList->SetLayoutFlags(win32cpp::LayoutFillFill);
this->listViewController = new musik::server::ConnectedUsersListController(*usersList,this);

View File

@ -99,20 +99,26 @@ void MainWindowController::OnMainWindowCreated(Window* window)
// Create the layout
this->mainFrame = new win32cpp::Frame(NULL,win32cpp::FramePadding(4));
this->mainFrame->SetLayoutFlags(win32cpp::LayoutFillFill);
// Second a TabView for the settings
win32cpp::TabView *tabs = this->mainFrame->AddChild( new win32cpp::TabView() );
tabs->SetPadding(0);
// Syncpath tab
SyncpathView *synpathView = tabs->AddTab(uistring(_T("Sync paths")), new SyncpathView());
synpathView->SetLayoutFlags(win32cpp::LayoutFillFill);
this->syncpathController = new SyncpathController(*synpathView,&this->server->indexer);
// Users tab
users::UsersView *usersView = tabs->AddTab(uistring(_T("Users")), new users::UsersView());
usersView->SetLayoutFlags(win32cpp::LayoutFillFill);
this->usersController = new users::UsersController(*usersView,this->server.get());
// Settings tab
Frame *settingsView = tabs->AddTab(uistring(_T("Settings")), new Frame());
settingsView->SetLayoutFlags(win32cpp::LayoutFillFill);
this->mainWindow.AddChild(mainFrame);

View File

@ -2,7 +2,7 @@
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
// The following are Copyright 2007, mC2 Team
//
// Sources and Binaries of: mC2, win32cpp
//
@ -58,16 +58,13 @@ SyncpathView::SyncpathView()
void SyncpathView::OnCreated()
{
LinearLayout* pathLayout = new LinearLayout(LinearColumnLayout);
LinearLayout* pathButtonsLayout = new LinearLayout(LinearRowLayout);
LinearLayout* pathLayout = new LinearLayout(HorizontalLayout,win32cpp::LayoutFillFill);
LinearLayout* pathButtonsLayout = new LinearLayout(VerticalLayout);
// Path ListView
this->pathList = pathLayout->AddChild(new ListView());
pathLayout->SetDefaultChildFill(true);
// pathLayout->SetSizeConstraints(LayoutFillParent,120);
pathLayout->SetFlexibleChild(this->pathList);
this->pathList->SetLayoutFlags(win32cpp::LayoutFillFill);
// pathButtons layout
@ -77,14 +74,10 @@ void SyncpathView::OnCreated()
this->addPathButton->Resize(90, 24);
this->removePathButton->Resize(90, 24);
pathButtonsLayout->SetDefaultChildFill(false);
pathButtonsLayout->SetDefaultChildAlignment(ChildAlignMiddle);
pathButtonsLayout->SetSizeConstraints(90,LayoutFillParent);
pathLayout->AddChild(pathButtonsLayout);
// Add to the layout
this->AddChild(new Frame(pathLayout,FramePadding(20)));
win32cpp::Frame *paddingFrame = this->AddChild(new Frame(pathLayout,FramePadding(20)));
paddingFrame->SetLayoutFlags(win32cpp::LayoutFillFill);
}

View File

@ -2,7 +2,7 @@
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
// The following are Copyright 2007, mC2 Team
//
// Sources and Binaries of: mC2, win32cpp
//
@ -43,7 +43,6 @@
#include <win32cpp/Label.hpp>
#include <win32cpp/Button.hpp>
#include <win32cpp/LinearLayout.hpp>
#include <win32cpp/BarLayout.hpp>
#include <win32cpp/EditView.hpp>
//////////////////////////////////////////////////////////////////////////////
@ -64,14 +63,14 @@ void EditUserView::OnCreated()
boldFont->SetBold(true);
// Top Row layout
LinearLayout* topRowLayout = new LinearLayout(LinearRowLayout);
topRowLayout->SetDefaultChildFill(false);
topRowLayout->SetDefaultChildAlignment(win32cpp::ChildAlignMiddle);
LinearLayout* topRowLayout = new LinearLayout(VerticalLayout);
// topRowLayout->SetDefaultChildFill(false);
// topRowLayout->SetDefaultChildAlignment(win32cpp::ChildAlignMiddle);
// First rows column layout
LinearLayout* firstColumnLayout = new LinearLayout(LinearColumnLayout);
firstColumnLayout->SetDefaultChildFill(false);
firstColumnLayout->SetDefaultChildAlignment(win32cpp::ChildAlignCenter);
LinearLayout* firstColumnLayout = new LinearLayout(HorizontalLayout);
// firstColumnLayout->SetDefaultChildFill(false);
// firstColumnLayout->SetDefaultChildAlignment(win32cpp::ChildAlignCenter);
Label* title = firstColumnLayout->AddChild(new Label(_T("Add user")));
title->SetFont(boldFont);
@ -82,21 +81,21 @@ void EditUserView::OnCreated()
Label* label;
// Username
row = new LinearLayout(LinearColumnLayout);
row = new LinearLayout(HorizontalLayout);
label = row->AddChild(new Label(_T("Username:") ));
label->Resize(Size(80,0));
this->username = row->AddChild(new EditView(160,20 ));
topRowLayout->AddChild(row);
// Password
row = new LinearLayout(LinearColumnLayout);
row = new LinearLayout(HorizontalLayout);
label = row->AddChild(new Label(_T("Password:") ));
label->Resize(Size(80,0));
this->password = row->AddChild(new EditView(160,20 ));
topRowLayout->AddChild(row);
// Nickname
row = new LinearLayout(LinearColumnLayout);
row = new LinearLayout(HorizontalLayout);
label = row->AddChild(new Label(_T("Nickname:") ));
label->Resize(Size(80,0));
this->nickname = row->AddChild(new EditView(160,20 ));
@ -104,14 +103,14 @@ void EditUserView::OnCreated()
// Last rows column layout
LinearLayout* bottomButtonLayout = new LinearLayout(LinearColumnLayout);
bottomButtonLayout->SetDefaultChildFill(false);
LinearLayout* bottomButtonLayout = new LinearLayout(HorizontalLayout);
// bottomButtonLayout->SetDefaultChildFill(false);
this->cancelButton = bottomButtonLayout->AddChild(new Button(_T("Cancel")));
this->okButton = bottomButtonLayout->AddChild(new Button(_T("OK")));
this->cancelButton->Resize(60,20);
this->okButton->Resize(60,20);
topRowLayout->AddChild(bottomButtonLayout);
topRowLayout->SetChildAlignment(bottomButtonLayout,ChildAlignRight);
// topRowLayout->SetChildAlignment(bottomButtonLayout,ChildAlignRight);
this->AddChild(topRowLayout);

View File

@ -2,7 +2,7 @@
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
// The following are Copyright 2007, mC2 Team
//
// Sources and Binaries of: mC2, win32cpp
//
@ -58,17 +58,12 @@ UsersView::UsersView()
void UsersView::OnCreated()
{
LinearLayout* pathLayout = new LinearLayout(LinearColumnLayout);
LinearLayout* pathButtonsLayout = new LinearLayout(LinearRowLayout);
LinearLayout* pathLayout = new LinearLayout(HorizontalLayout,win32cpp::LayoutFillFill);
LinearLayout* pathButtonsLayout = new LinearLayout(VerticalLayout);
// Path ListView
this->usersList = pathLayout->AddChild(new ListView());
pathLayout->SetDefaultChildFill(true);
// pathLayout->SetSizeConstraints(LayoutFillParent,120);
pathLayout->SetFlexibleChild(this->usersList);
this->usersList->SetLayoutFlags(win32cpp::LayoutFillFill);
// pathButtons layout
this->addUserButton = pathButtonsLayout->AddChild(new Button(_T("Add user")));
@ -77,14 +72,11 @@ void UsersView::OnCreated()
this->addUserButton->Resize(90, 24);
this->removeUserButton->Resize(90, 24);
pathButtonsLayout->SetDefaultChildFill(false);
pathButtonsLayout->SetDefaultChildAlignment(ChildAlignMiddle);
pathButtonsLayout->SetSizeConstraints(90,LayoutFillParent);
pathLayout->AddChild(pathButtonsLayout);
// Add to the layout
this->AddChild(new Frame(pathLayout,FramePadding(20)));
win32cpp::Frame *paddingFrame = this->AddChild(new Frame(pathLayout,FramePadding(20)));
paddingFrame->SetLayoutFlags(win32cpp::LayoutFillFill);
}

View File

@ -1,214 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2007, Casey Langen
//
// Sources and Binaries of: mC2, win32cpp
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#include <pch.hpp>
#include <win32cpp/BarLayout.hpp>
#include <win32cpp/RedrawLock.hpp>
#include <algorithm>
//////////////////////////////////////////////////////////////////////////////
using namespace win32cpp;
//////////////////////////////////////////////////////////////////////////////
///\brief
///Constructor.
///
///\param orientation
///A win32cpp::BarLayoutOrientation.
/*ctor*/ BarLayout::BarLayout(BarLayoutOrientation orientation)
: Panel()
, orientation(orientation)
, spacing(4)
, childIsResizing(false)
, constraints(LayoutFillParent, LayoutFillParent)
{
}
///\brief
///Sets the amount spacing between children, in pixels.
///
///\param spacing
///The amount of spacing, in pixels.
void BarLayout::SetSpacing(int spacing)
{
if (this->spacing == spacing)
{
return;
}
this->spacing = spacing;
this->Layout();
}
///\brief
///Returns the amount of spacing between children (in pixels)
int BarLayout::Spacing() const
{
return this->spacing;
}
void BarLayout::OnChildAdded(Window* newChild)
{
newChild->Resized.connect(this, &BarLayout::OnChildResized);
this->Layout();
}
void BarLayout::OnChildRemoved(Window* oldChild)
{
oldChild->Resized.disconnect(this);
this->Layout();
}
void BarLayout::OnChildResized(Window* window, Size newSize)
{
if ( ! this->childIsResizing)
{
this->Layout();
}
}
inline void BarLayout::ThrowIfNotChild(Window* child)
{
WindowList::iterator it =
std::find(this->childWindows.begin(), this->childWindows.end(), child);
if (it == this->childWindows.end())
{
throw InvalidChildWindowException();
}
}
void BarLayout::OnResized(const Size& newSize)
{
this->Layout();
}
void BarLayout::SetSizeConstraints(int width , int height)
{
constraints.width = width;
constraints.height = height;
this->Layout();
}
void BarLayout::Layout()
{
if ( ! this->childWindows.size())
{
return;
}
RedrawLock stopRedraw(this);
// calculate the total available size
Size layoutSize = this->WindowSize();
//
if ((this->constraints.width == LayoutFillParent)
|| (this->constraints.height == LayoutFillParent))
{
Window* parent = this->Parent();
if ( ! parent)
{
return;
}
Size parentSize = parent->WindowSize();
this->constraints.width == LayoutFillParent
? layoutSize.width = parentSize.width : 0;
this->constraints.height == LayoutFillParent
? layoutSize.height = parentSize.height : 0;
}
// calculate the size for each child
bool isColumnLayout = (this->orientation == BarColumnLayout);
Size childSize;
int childCount = (int) this->childWindows.size();
int spacing = this->spacing;
//
if (isColumnLayout)
{
// column layout means height is always the same
childSize.height = layoutSize.height;
childSize.width = (layoutSize.width - ((childCount - 1) * spacing)) / childCount;
}
else
{
// row layout means width is always the same
childSize.width = layoutSize.width;
childSize.height = (layoutSize.height - ((childCount - 1) * spacing)) / childCount;
}
// iterate over all the children and lay them out!
int currentPosition = 0;
WindowList::iterator it = this->childWindows.begin();
WindowList::iterator end = this->childWindows.end();
for ( ; it != end; it++)
{
Window* current = (*it);
this->childIsResizing = true;
// last child may have a slightly different size due to integer
// rounding errors in the childSize calculations above.
if ((it + 1) == end)
{
if (isColumnLayout) childSize.width = (layoutSize.width - currentPosition);
else childSize.height = (layoutSize.height - currentPosition);
}
// resize
current->Resize(childSize);
// reposition
Point location(
isColumnLayout ? currentPosition : 0,
isColumnLayout ? 0 : currentPosition);
current->MoveTo(location);
this->childIsResizing = false;
currentPosition += isColumnLayout ? childSize.width : childSize.height;
currentPosition += spacing;
}
}

View File

@ -51,8 +51,8 @@ using namespace win32cpp;
///
///\param caption
///The caption that will be drawn on the button.
/*ctor*/ Button::Button(const uichar* caption)
: base()
/*ctor*/ Button::Button(const uichar* caption, LayoutFlags layoutFlags)
: base(layoutFlags)
, caption(caption)
{
}

View File

@ -68,7 +68,7 @@ public: // events
ButtonPressedEvent Pressed;
public: // constructors
/*ctor*/ Button(const uichar* caption = _T(""));
/*ctor*/ Button(const uichar* caption = _T(""), LayoutFlags = LayoutWrapWrap);
protected: // methods
virtual HWND Create(Window* parent);

View File

@ -51,8 +51,8 @@ using namespace win32cpp;
///
///\param caption
///The caption that beside the checkbox
/*ctor*/ CheckBox::CheckBox(const uichar* caption, int style)
: base()
/*ctor*/ CheckBox::CheckBox(const uichar* caption, LayoutFlags layoutFlags, int style)
: base(layoutFlags)
, caption(caption)
, style(style)
{
@ -73,7 +73,7 @@ HWND CheckBox::Create(Window* parent)
0, // X
0, // Y
64, // Width
32, // Height
28, // Height
parent->Handle(), // Parent
NULL, // Menu
hInstance, // Instance

Some files were not shown because too many files have changed in this diff Show More