update boost on linux
This commit is contained in:
@@ -1,46 +1,31 @@
|
||||
/*
|
||||
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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_ALGORITHM_HPP
|
||||
#define BOOST_GIL_ALGORITHM_HPP
|
||||
|
||||
See http://opensource.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
#include <boost/gil/bit_aligned_pixel_iterator.hpp>
|
||||
#include <boost/gil/color_base_algorithm.hpp>
|
||||
#include <boost/gil/concepts.hpp>
|
||||
#include <boost/gil/image_view.hpp>
|
||||
#include <boost/gil/image_view_factory.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#ifndef GIL_ALGORITHM_HPP
|
||||
#define GIL_ALGORITHM_HPP
|
||||
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include "gil_config.hpp"
|
||||
#include "gil_concept.hpp"
|
||||
#include "color_base_algorithm.hpp"
|
||||
#include "image_view.hpp"
|
||||
#include "image_view_factory.hpp"
|
||||
#include "bit_aligned_pixel_iterator.hpp"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \file
|
||||
/// \brief Some basic STL-style algorithms when applied to image views
|
||||
/// \author Lubomir Bourdev and Hailin Jin \n
|
||||
/// Adobe Systems Incorporated
|
||||
/// \date 2005-2008 \n Last updated on March 12, 2008
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//#ifdef _MSC_VER
|
||||
//#pragma warning(push)
|
||||
//#pragma warning(disable : 4244) // conversion from 'gil::image<V,Alloc>::coord_t' to 'int', possible loss of data (visual studio compiler doesn't realize that the two types are the same)
|
||||
//#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
@@ -77,10 +62,9 @@ struct error_t {};
|
||||
/// is overloaded to perform \p std::copy for each of the planes. \p std::copy over bitwise-copiable pixels results in
|
||||
/// std::copy over unsigned char, which STL typically implements via \p memmove.
|
||||
///
|
||||
/// As a result \p copy_pixels may result in a single call to \p memmove for interleaved 1D-traversable views,
|
||||
/// As a result \p copy_pixels may result in a single call to \p memmove for interleaved 1D-traversable views,
|
||||
/// or one per each plane of planar 1D-traversable views, or one per each row of interleaved non-1D-traversable images, etc.
|
||||
|
||||
|
||||
/// \defgroup STLOptimizations Performance overloads of STL algorithms
|
||||
/// \ingroup ImageViewAlgorithm
|
||||
/// \brief overloads of STL algorithms allowing more efficient implementation when used with GIL constructs
|
||||
@@ -95,14 +79,14 @@ struct error_t {};
|
||||
/// is not required and the default throws std::bad_cast.
|
||||
template <typename Derived, typename Result=void>
|
||||
struct binary_operation_obj {
|
||||
typedef Result result_type;
|
||||
using result_type = Result;
|
||||
|
||||
template <typename V1, typename V2> GIL_FORCEINLINE
|
||||
template <typename V1, typename V2> BOOST_FORCEINLINE
|
||||
result_type operator()(const std::pair<const V1*,const V2*>& p) const {
|
||||
return apply(*p.first, *p.second, typename views_are_compatible<V1,V2>::type());
|
||||
}
|
||||
|
||||
template <typename V1, typename V2> GIL_FORCEINLINE
|
||||
template <typename V1, typename V2> BOOST_FORCEINLINE
|
||||
result_type operator()(const V1& v1, const V2& v2) const {
|
||||
return apply(v1, v2, typename views_are_compatible<V1,V2>::type());
|
||||
}
|
||||
@@ -112,19 +96,19 @@ private:
|
||||
|
||||
// dispatch from apply overload to a function with distinct name
|
||||
template <typename V1, typename V2>
|
||||
GIL_FORCEINLINE result_type apply(const V1& v1, const V2& v2, mpl::false_) const {
|
||||
BOOST_FORCEINLINE result_type apply(const V1& v1, const V2& v2, mpl::false_) const {
|
||||
return ((const Derived*)this)->apply_incompatible(v1,v2);
|
||||
}
|
||||
|
||||
// dispatch from apply overload to a function with distinct name
|
||||
template <typename V1, typename V2>
|
||||
GIL_FORCEINLINE result_type apply(const V1& v1, const V2& v2, mpl::true_) const {
|
||||
BOOST_FORCEINLINE result_type apply(const V1& v1, const V2& v2, mpl::true_) const {
|
||||
return ((const Derived*)this)->apply_compatible(v1,v2);
|
||||
}
|
||||
|
||||
// function with distinct name - it can be overloaded by subclasses
|
||||
template <typename V1, typename V2>
|
||||
GIL_FORCEINLINE result_type apply_incompatible(const V1& v1, const V2& v2) const {
|
||||
BOOST_FORCEINLINE result_type apply_incompatible(const V1&, const V2&) const {
|
||||
throw std::bad_cast();
|
||||
}
|
||||
};
|
||||
@@ -141,30 +125,29 @@ private:
|
||||
/// \brief std::copy for image views
|
||||
|
||||
namespace std {
|
||||
|
||||
/// \ingroup STLOptimizations
|
||||
/// \brief Copy when both src and dst are interleaved and of the same type can be just memmove
|
||||
template<typename T, typename Cs>
|
||||
GIL_FORCEINLINE boost::gil::pixel<T,Cs>*
|
||||
copy(boost::gil::pixel<T,Cs>* first, boost::gil::pixel<T,Cs>* last,
|
||||
boost::gil::pixel<T,Cs>* dst) {
|
||||
template<typename T, typename Cs>
|
||||
BOOST_FORCEINLINE boost::gil::pixel<T,Cs>*
|
||||
copy(boost::gil::pixel<T,Cs>* first, boost::gil::pixel<T,Cs>* last,
|
||||
boost::gil::pixel<T,Cs>* dst) {
|
||||
return (boost::gil::pixel<T,Cs>*)std::copy((unsigned char*)first,(unsigned char*)last, (unsigned char*)dst);
|
||||
}
|
||||
|
||||
/// \ingroup STLOptimizations
|
||||
/// \brief Copy when both src and dst are interleaved and of the same type can be just memmove
|
||||
template<typename T, typename Cs>
|
||||
GIL_FORCEINLINE boost::gil::pixel<T,Cs>*
|
||||
copy(const boost::gil::pixel<T,Cs>* first, const boost::gil::pixel<T,Cs>* last,
|
||||
boost::gil::pixel<T,Cs>* dst) {
|
||||
template<typename T, typename Cs>
|
||||
BOOST_FORCEINLINE boost::gil::pixel<T,Cs>*
|
||||
copy(const boost::gil::pixel<T,Cs>* first, const boost::gil::pixel<T,Cs>* last,
|
||||
boost::gil::pixel<T,Cs>* dst) {
|
||||
return (boost::gil::pixel<T,Cs>*)std::copy((unsigned char*)first,(unsigned char*)last, (unsigned char*)dst);
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
namespace boost { namespace gil {
|
||||
namespace detail {
|
||||
template <typename I, typename O> struct copy_fn {
|
||||
GIL_FORCEINLINE I operator()(I first, I last, O dst) const { return std::copy(first,last,dst); }
|
||||
template <typename I, typename O> struct copy_fn {
|
||||
BOOST_FORCEINLINE I operator()(I first, I last, O dst) const { return std::copy(first,last,dst); }
|
||||
};
|
||||
} // namespace detail
|
||||
} } // namespace boost::gil
|
||||
@@ -172,8 +155,8 @@ template <typename I, typename O> struct copy_fn {
|
||||
namespace std {
|
||||
/// \ingroup STLOptimizations
|
||||
/// \brief Copy when both src and dst are planar pointers is copy for each channel
|
||||
template<typename Cs, typename IC1, typename IC2> GIL_FORCEINLINE
|
||||
boost::gil::planar_pixel_iterator<IC2,Cs> copy(boost::gil::planar_pixel_iterator<IC1,Cs> first, boost::gil::planar_pixel_iterator<IC1,Cs> last, boost::gil::planar_pixel_iterator<IC2,Cs> dst) {
|
||||
template<typename Cs, typename IC1, typename IC2> BOOST_FORCEINLINE
|
||||
boost::gil::planar_pixel_iterator<IC2,Cs> copy(boost::gil::planar_pixel_iterator<IC1,Cs> first, boost::gil::planar_pixel_iterator<IC1,Cs> last, boost::gil::planar_pixel_iterator<IC2,Cs> dst) {
|
||||
boost::gil::gil_function_requires<boost::gil::ChannelsCompatibleConcept<typename std::iterator_traits<IC1>::value_type,typename std::iterator_traits<IC2>::value_type> >();
|
||||
static_for_each(first,last,dst,boost::gil::detail::copy_fn<IC1,IC2>());
|
||||
return dst+(last-first);
|
||||
@@ -186,18 +169,17 @@ namespace detail {
|
||||
/// \ingroup CopyPixels
|
||||
template <typename I, typename O>
|
||||
struct copier_n {
|
||||
GIL_FORCEINLINE void operator()(I src, typename std::iterator_traits<I>::difference_type n, O dst) const { std::copy(src,src+n, dst); }
|
||||
BOOST_FORCEINLINE void operator()(I src, typename std::iterator_traits<I>::difference_type n, O dst) const { std::copy(src,src+n, dst); }
|
||||
};
|
||||
|
||||
/// Source range is delimited by image iterators
|
||||
template <typename IL, typename O> // IL Models ConstPixelLocatorConcept, O Models PixelIteratorConcept
|
||||
struct copier_n<iterator_from_2d<IL>,O> {
|
||||
typedef typename std::iterator_traits<iterator_from_2d<IL> >::difference_type diff_t;
|
||||
GIL_FORCEINLINE void operator()(iterator_from_2d<IL> src, diff_t n, O dst) const {
|
||||
using diff_t = typename std::iterator_traits<iterator_from_2d<IL> >::difference_type;
|
||||
BOOST_FORCEINLINE void operator()(iterator_from_2d<IL> src, diff_t n, O dst) const {
|
||||
gil_function_requires<PixelLocatorConcept<IL> >();
|
||||
gil_function_requires<MutablePixelIteratorConcept<O> >();
|
||||
while (n>0) {
|
||||
typedef typename iterator_from_2d<IL>::difference_type diff_t;
|
||||
diff_t l=src.width()-src.x_pos();
|
||||
diff_t numToCopy=(n<l ? n:l);
|
||||
detail::copy_n(src.x(), numToCopy, dst);
|
||||
@@ -211,8 +193,8 @@ struct copier_n<iterator_from_2d<IL>,O> {
|
||||
/// Destination range is delimited by image iterators
|
||||
template <typename I, typename OL> // I Models ConstPixelIteratorConcept, OL Models PixelLocatorConcept
|
||||
struct copier_n<I,iterator_from_2d<OL> > {
|
||||
typedef typename std::iterator_traits<I>::difference_type diff_t;
|
||||
GIL_FORCEINLINE void operator()(I src, diff_t n, iterator_from_2d<OL> dst) const {
|
||||
using diff_t = typename std::iterator_traits<I>::difference_type;
|
||||
BOOST_FORCEINLINE void operator()(I src, diff_t n, iterator_from_2d<OL> dst) const {
|
||||
gil_function_requires<PixelIteratorConcept<I> >();
|
||||
gil_function_requires<MutablePixelLocatorConcept<OL> >();
|
||||
while (n>0) {
|
||||
@@ -229,8 +211,8 @@ struct copier_n<I,iterator_from_2d<OL> > {
|
||||
/// Both source and destination ranges are delimited by image iterators
|
||||
template <typename IL, typename OL>
|
||||
struct copier_n<iterator_from_2d<IL>,iterator_from_2d<OL> > {
|
||||
typedef typename iterator_from_2d<IL>::difference_type diff_t;
|
||||
GIL_FORCEINLINE void operator()(iterator_from_2d<IL> src, diff_t n, iterator_from_2d<OL> dst) const {
|
||||
using diff_t = typename iterator_from_2d<IL>::difference_type;
|
||||
BOOST_FORCEINLINE void operator()(iterator_from_2d<IL> src, diff_t n, iterator_from_2d<OL> dst) const {
|
||||
gil_function_requires<PixelLocatorConcept<IL> >();
|
||||
gil_function_requires<MutablePixelLocatorConcept<OL> >();
|
||||
if (src.x_pos()!=dst.x_pos() || src.width()!=dst.width()) {
|
||||
@@ -250,9 +232,9 @@ struct copier_n<iterator_from_2d<IL>,iterator_from_2d<OL> > {
|
||||
};
|
||||
|
||||
template <typename SrcIterator, typename DstIterator>
|
||||
GIL_FORCEINLINE DstIterator copy_with_2d_iterators(SrcIterator first, SrcIterator last, DstIterator dst) {
|
||||
typedef typename SrcIterator::x_iterator src_x_iterator;
|
||||
typedef typename DstIterator::x_iterator dst_x_iterator;
|
||||
BOOST_FORCEINLINE DstIterator copy_with_2d_iterators(SrcIterator first, SrcIterator last, DstIterator dst) {
|
||||
using src_x_iterator = typename SrcIterator::x_iterator;
|
||||
using dst_x_iterator = typename DstIterator::x_iterator;
|
||||
|
||||
typename SrcIterator::difference_type n = last - first;
|
||||
|
||||
@@ -269,7 +251,6 @@ GIL_FORCEINLINE DstIterator copy_with_2d_iterators(SrcIterator first, SrcIterato
|
||||
}
|
||||
return dst+n;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} } // namespace boost::gil
|
||||
|
||||
@@ -277,20 +258,18 @@ namespace std {
|
||||
/// \ingroup STLOptimizations
|
||||
/// \brief std::copy(I1,I1,I2) with I1 and I2 being a iterator_from_2d
|
||||
template <typename IL, typename OL>
|
||||
GIL_FORCEINLINE boost::gil::iterator_from_2d<OL> copy1(boost::gil::iterator_from_2d<IL> first, boost::gil::iterator_from_2d<IL> last, boost::gil::iterator_from_2d<OL> dst) {
|
||||
BOOST_FORCEINLINE boost::gil::iterator_from_2d<OL> copy1(boost::gil::iterator_from_2d<IL> first, boost::gil::iterator_from_2d<IL> last, boost::gil::iterator_from_2d<OL> dst) {
|
||||
return boost::gil::detail::copy_with_2d_iterators(first,last,dst);
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
|
||||
/// \ingroup ImageViewSTLAlgorithmsCopyPixels
|
||||
/// \brief std::copy for image views
|
||||
template <typename View1, typename View2> GIL_FORCEINLINE
|
||||
void copy_pixels(const View1& src, const View2& dst) {
|
||||
assert(src.dimensions()==dst.dimensions());
|
||||
template <typename View1, typename View2> BOOST_FORCEINLINE
|
||||
void copy_pixels(const View1& src, const View2& dst)
|
||||
{
|
||||
BOOST_ASSERT(src.dimensions() == dst.dimensions());
|
||||
detail::copy_with_2d_iterators(src.begin(),src.end(),dst.begin());
|
||||
}
|
||||
|
||||
@@ -312,17 +291,17 @@ class copy_and_convert_pixels_fn : public binary_operation_obj<copy_and_convert_
|
||||
private:
|
||||
CC _cc;
|
||||
public:
|
||||
typedef typename binary_operation_obj<copy_and_convert_pixels_fn<CC> >::result_type result_type;
|
||||
using result_type = typename binary_operation_obj<copy_and_convert_pixels_fn<default_color_converter> >::result_type;
|
||||
copy_and_convert_pixels_fn() {}
|
||||
copy_and_convert_pixels_fn(CC cc_in) : _cc(cc_in) {}
|
||||
// when the two color spaces are incompatible, a color conversion is performed
|
||||
template <typename V1, typename V2> GIL_FORCEINLINE
|
||||
template <typename V1, typename V2> BOOST_FORCEINLINE
|
||||
result_type apply_incompatible(const V1& src, const V2& dst) const {
|
||||
copy_pixels(color_converted_view<typename V2::value_type>(src,_cc),dst);
|
||||
}
|
||||
|
||||
// If the two color spaces are compatible, copy_and_convert is just copy
|
||||
template <typename V1, typename V2> GIL_FORCEINLINE
|
||||
template <typename V1, typename V2> BOOST_FORCEINLINE
|
||||
result_type apply_compatible(const V1& src, const V2& dst) const {
|
||||
copy_pixels(src,dst);
|
||||
}
|
||||
@@ -330,9 +309,9 @@ public:
|
||||
} // namespace detail
|
||||
|
||||
/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
|
||||
template <typename V1, typename V2,typename CC>
|
||||
GIL_FORCEINLINE
|
||||
void copy_and_convert_pixels(const V1& src, const V2& dst,CC cc) {
|
||||
template <typename V1, typename V2,typename CC>
|
||||
BOOST_FORCEINLINE
|
||||
void copy_and_convert_pixels(const V1& src, const V2& dst,CC cc) {
|
||||
detail::copy_and_convert_pixels_fn<CC> ccp(cc);
|
||||
ccp(src,dst);
|
||||
}
|
||||
@@ -340,13 +319,12 @@ void copy_and_convert_pixels(const V1& src, const V2& dst,CC cc) {
|
||||
struct default_color_converter;
|
||||
|
||||
/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
|
||||
template <typename View1, typename View2>
|
||||
GIL_FORCEINLINE
|
||||
void copy_and_convert_pixels(const View1& src, const View2& dst) {
|
||||
template <typename View1, typename View2>
|
||||
BOOST_FORCEINLINE
|
||||
void copy_and_convert_pixels(const View1& src, const View2& dst) {
|
||||
detail::copy_and_convert_pixels_fn<default_color_converter> ccp;
|
||||
ccp(src,dst);
|
||||
}
|
||||
|
||||
} } // namespace boost::gil
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -359,14 +337,13 @@ void copy_and_convert_pixels(const View1& src, const View2& dst) {
|
||||
/// \ingroup ImageViewSTLAlgorithms
|
||||
/// \brief std::fill for image views
|
||||
|
||||
|
||||
namespace std {
|
||||
/// \ingroup STLOptimizations
|
||||
/// \brief std::fill(I,I,V) with I being a iterator_from_2d
|
||||
///
|
||||
/// Invoked when one calls std::fill(I,I,V) with I being a iterator_from_2d (which is
|
||||
/// a 1D iterator over the pixels in an image). For contiguous images (i.e. images that have
|
||||
/// no alignment gap at the end of each row) it is more efficient to use the underlying
|
||||
/// no alignment gap at the end of each row) it is more efficient to use the underlying
|
||||
/// pixel iterator that does not check for the end of rows. For non-contiguous images fill
|
||||
/// resolves to fill of each row using the underlying pixel iterator, which is still faster
|
||||
template <typename IL, typename V>
|
||||
@@ -379,16 +356,15 @@ void fill(boost::gil::iterator_from_2d<IL> first, boost::gil::iterator_from_2d<I
|
||||
std::ptrdiff_t n=last-first;
|
||||
while (n>0) {
|
||||
std::ptrdiff_t numToDo=std::min<const std::ptrdiff_t>(n,(std::ptrdiff_t)(first.width()-first.x_pos()));
|
||||
fill_n(first.x(), numToDo, val);
|
||||
std::fill_n(first.x(), numToDo, val);
|
||||
first+=numToDo;
|
||||
n-=numToDo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
namespace detail {
|
||||
/// struct to do std::fill
|
||||
struct std_fill_t {
|
||||
@@ -399,13 +375,13 @@ struct std_fill_t {
|
||||
};
|
||||
/// std::fill for planar iterators
|
||||
template <typename It, typename P>
|
||||
GIL_FORCEINLINE
|
||||
BOOST_FORCEINLINE
|
||||
void fill_aux(It first, It last, const P& p, mpl::true_) {
|
||||
static_for_each(first,last,p,std_fill_t());
|
||||
}
|
||||
/// std::fill for interleaved iterators
|
||||
template <typename It, typename P>
|
||||
GIL_FORCEINLINE
|
||||
BOOST_FORCEINLINE
|
||||
void fill_aux(It first, It last, const P& p,mpl::false_) {
|
||||
std::fill(first,last,p);
|
||||
}
|
||||
@@ -413,10 +389,10 @@ void fill_aux(It first, It last, const P& p,mpl::false_) {
|
||||
|
||||
/// \ingroup ImageViewSTLAlgorithmsFillPixels
|
||||
/// \brief std::fill for image views
|
||||
template <typename View, typename Value> GIL_FORCEINLINE
|
||||
template <typename View, typename Value> BOOST_FORCEINLINE
|
||||
void fill_pixels(const View& img_view, const Value& val) {
|
||||
if (img_view.is_1d_traversable())
|
||||
detail::fill_aux(img_view.begin().x(), img_view.end().x(),
|
||||
detail::fill_aux(img_view.begin().x(), img_view.end().x(),
|
||||
val,is_planar<View>());
|
||||
else
|
||||
for (std::ptrdiff_t y=0; y<img_view.height(); ++y)
|
||||
@@ -434,52 +410,76 @@ void fill_pixels(const View& img_view, const Value& val) {
|
||||
/// \ingroup ImageViewSTLAlgorithms
|
||||
/// \brief invokes the destructor on every pixel of an image view
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename It> GIL_FORCEINLINE
|
||||
void destruct_range_impl(It first, It last, mpl::true_) {
|
||||
typedef typename std::iterator_traits<It>::value_type value_t;
|
||||
if (boost::has_trivial_destructor<value_t>::value)
|
||||
return;
|
||||
while (first!=last) {
|
||||
template <typename Iterator>
|
||||
BOOST_FORCEINLINE
|
||||
void destruct_range_impl(Iterator first, Iterator last,
|
||||
typename std::enable_if
|
||||
<
|
||||
mpl::and_
|
||||
<
|
||||
is_pointer<Iterator>,
|
||||
mpl::not_<std::is_trivially_destructible<typename std::iterator_traits<Iterator>::value_type>>
|
||||
>::value
|
||||
>::type* /*ptr*/ = 0)
|
||||
{
|
||||
while (first != last)
|
||||
{
|
||||
first->~value_t();
|
||||
++first;
|
||||
}
|
||||
}
|
||||
template <typename It> GIL_FORCEINLINE
|
||||
void destruct_range_impl(It, It, mpl::false_) {}
|
||||
|
||||
template <typename It> GIL_FORCEINLINE
|
||||
void destruct_range(It first, It last) {
|
||||
destruct_range_impl(first,last,typename is_pointer<It>::type());
|
||||
template <typename Iterator>
|
||||
BOOST_FORCEINLINE
|
||||
void destruct_range_impl(Iterator /*first*/, Iterator /*last*/,
|
||||
typename std::enable_if
|
||||
<
|
||||
mpl::or_
|
||||
<
|
||||
mpl::not_<is_pointer<Iterator>>,
|
||||
std::is_trivially_destructible<typename std::iterator_traits<Iterator>::value_type>
|
||||
>::value
|
||||
>::type* /* ptr */ = nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
struct std_destruct_t {
|
||||
template <typename It> void operator()(It first, It last) const { destruct_range(first,last); }
|
||||
template <typename Iterator>
|
||||
BOOST_FORCEINLINE
|
||||
void destruct_range(Iterator first, Iterator last)
|
||||
{
|
||||
destruct_range_impl(first, last);
|
||||
}
|
||||
|
||||
struct std_destruct_t
|
||||
{
|
||||
template <typename Iterator>
|
||||
void operator()(Iterator first, Iterator last) const
|
||||
{
|
||||
destruct_range(first,last);
|
||||
}
|
||||
};
|
||||
|
||||
/// destruct for planar iterators
|
||||
template <typename It>
|
||||
GIL_FORCEINLINE
|
||||
BOOST_FORCEINLINE
|
||||
void destruct_aux(It first, It last, mpl::true_) {
|
||||
static_for_each(first,last,std_destruct_t());
|
||||
}
|
||||
/// destruct for interleaved iterators
|
||||
template <typename It>
|
||||
GIL_FORCEINLINE
|
||||
BOOST_FORCEINLINE
|
||||
void destruct_aux(It first, It last, mpl::false_) {
|
||||
destruct_range(first,last);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \ingroup ImageViewSTLAlgorithmsDestructPixels
|
||||
/// \brief Invokes the in-place destructor on every pixel of the view
|
||||
template <typename View> GIL_FORCEINLINE
|
||||
template <typename View> BOOST_FORCEINLINE
|
||||
void destruct_pixels(const View& img_view) {
|
||||
if (img_view.is_1d_traversable())
|
||||
detail::destruct_aux(img_view.begin().x(), img_view.end().x(),
|
||||
if (img_view.is_1d_traversable())
|
||||
detail::destruct_aux(img_view.begin().x(), img_view.end().x(),
|
||||
is_planar<View>());
|
||||
else
|
||||
for (std::ptrdiff_t y=0; y<img_view.height(); ++y)
|
||||
@@ -497,20 +497,18 @@ void destruct_pixels(const View& img_view) {
|
||||
/// \ingroup ImageViewSTLAlgorithms
|
||||
/// \brief std::uninitialized_fill for image views
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
/// std::uninitialized_fill for planar iterators
|
||||
/// If an exception is thrown destructs any in-place copy-constructed objects
|
||||
template <typename It, typename P>
|
||||
GIL_FORCEINLINE
|
||||
BOOST_FORCEINLINE
|
||||
void uninitialized_fill_aux(It first, It last,
|
||||
const P& p, mpl::true_) {
|
||||
int channel=0;
|
||||
try {
|
||||
typedef typename std::iterator_traits<It>::value_type pixel_t;
|
||||
using pixel_t = typename std::iterator_traits<It>::value_type;
|
||||
while (channel < num_channels<pixel_t>::value) {
|
||||
std::uninitialized_fill(dynamic_at_c(first,channel), dynamic_at_c(last,channel),
|
||||
std::uninitialized_fill(dynamic_at_c(first,channel), dynamic_at_c(last,channel),
|
||||
dynamic_at_c(p,channel));
|
||||
++channel;
|
||||
}
|
||||
@@ -524,25 +522,24 @@ void uninitialized_fill_aux(It first, It last,
|
||||
/// std::uninitialized_fill for interleaved iterators
|
||||
/// If an exception is thrown destructs any in-place copy-constructed objects
|
||||
template <typename It, typename P>
|
||||
GIL_FORCEINLINE
|
||||
BOOST_FORCEINLINE
|
||||
void uninitialized_fill_aux(It first, It last,
|
||||
const P& p,mpl::false_) {
|
||||
std::uninitialized_fill(first,last,p);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \ingroup ImageViewSTLAlgorithmsUninitializedFillPixels
|
||||
/// \brief std::uninitialized_fill for image views.
|
||||
/// Does not support planar heterogeneous views.
|
||||
/// If an exception is thrown destructs any in-place copy-constructed pixels
|
||||
template <typename View, typename Value>
|
||||
template <typename View, typename Value>
|
||||
void uninitialized_fill_pixels(const View& img_view, const Value& val) {
|
||||
if (img_view.is_1d_traversable())
|
||||
detail::uninitialized_fill_aux(img_view.begin().x(), img_view.end().x(),
|
||||
if (img_view.is_1d_traversable())
|
||||
detail::uninitialized_fill_aux(img_view.begin().x(), img_view.end().x(),
|
||||
val,is_planar<View>());
|
||||
else {
|
||||
typename View::y_coord_t y;
|
||||
typename View::y_coord_t y = 0;
|
||||
try {
|
||||
for (y=0; y<img_view.height(); ++y)
|
||||
detail::uninitialized_fill_aux(img_view.row_begin(y),img_view.row_end(y),
|
||||
@@ -566,10 +563,9 @@ void uninitialized_fill_pixels(const View& img_view, const Value& val) {
|
||||
/// \brief invokes the default constructor on every pixel of an image view
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename It> GIL_FORCEINLINE
|
||||
template <typename It> BOOST_FORCEINLINE
|
||||
void default_construct_range_impl(It first, It last, mpl::true_) {
|
||||
typedef typename std::iterator_traits<It>::value_type value_t;
|
||||
using value_t = typename std::iterator_traits<It>::value_type;
|
||||
It first1=first;
|
||||
try {
|
||||
while (first!=last) {
|
||||
@@ -582,19 +578,19 @@ void default_construct_range_impl(It first, It last, mpl::true_) {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename It> GIL_FORCEINLINE
|
||||
template <typename It> BOOST_FORCEINLINE
|
||||
void default_construct_range_impl(It, It, mpl::false_) {}
|
||||
|
||||
template <typename It> GIL_FORCEINLINE
|
||||
template <typename It> BOOST_FORCEINLINE
|
||||
void default_construct_range(It first, It last) { default_construct_range_impl(first, last, typename is_pointer<It>::type()); }
|
||||
|
||||
/// uninitialized_default_construct for planar iterators
|
||||
template <typename It>
|
||||
GIL_FORCEINLINE
|
||||
BOOST_FORCEINLINE
|
||||
void default_construct_aux(It first, It last, mpl::true_) {
|
||||
int channel=0;
|
||||
try {
|
||||
typedef typename std::iterator_traits<It>::value_type pixel_t;
|
||||
using pixel_t = typename std::iterator_traits<It>::value_type;
|
||||
while (channel < num_channels<pixel_t>::value) {
|
||||
default_construct_range(dynamic_at_c(first,channel), dynamic_at_c(last,channel));
|
||||
++channel;
|
||||
@@ -608,7 +604,7 @@ void default_construct_aux(It first, It last, mpl::true_) {
|
||||
|
||||
/// uninitialized_default_construct for interleaved iterators
|
||||
template <typename It>
|
||||
GIL_FORCEINLINE
|
||||
BOOST_FORCEINLINE
|
||||
void default_construct_aux(It first, It last, mpl::false_) {
|
||||
default_construct_range(first,last);
|
||||
}
|
||||
@@ -617,34 +613,64 @@ template <typename View, bool IsPlanar>
|
||||
struct has_trivial_pixel_constructor : public boost::has_trivial_constructor<typename View::value_type> {};
|
||||
template <typename View>
|
||||
struct has_trivial_pixel_constructor<View, true> : public boost::has_trivial_constructor<typename channel_type<View>::type> {};
|
||||
} // namespace detail
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename View, bool IsTriviallyConstructible>
|
||||
BOOST_FORCEINLINE
|
||||
void default_construct_pixels_impl(
|
||||
View const& img_view,
|
||||
std::enable_if<!IsTriviallyConstructible>* /* ptr */ = nullptr)
|
||||
{
|
||||
if( img_view.is_1d_traversable() )
|
||||
{
|
||||
detail::default_construct_aux( img_view.begin().x()
|
||||
, img_view.end().x()
|
||||
, is_planar<View>()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
typename View::y_coord_t y = 0;
|
||||
try
|
||||
{
|
||||
for( y = 0; y < img_view.height(); ++y )
|
||||
{
|
||||
detail::default_construct_aux( img_view.row_begin( y )
|
||||
,img_view.row_end( y )
|
||||
, is_planar<View>()
|
||||
);
|
||||
}
|
||||
} catch(...)
|
||||
{
|
||||
for (typename View::y_coord_t y0 = 0; y0 < y; ++y0 )
|
||||
{
|
||||
detail::destruct_aux( img_view.row_begin(y0)
|
||||
, img_view.row_end(y0)
|
||||
, is_planar<View>()
|
||||
);
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
/// \ingroup ImageViewSTLAlgorithmsDefaultConstructPixels
|
||||
/// \brief Invokes the in-place default constructor on every pixel of the (uninitialized) view.
|
||||
/// Does not support planar heterogeneous views.
|
||||
/// If an exception is thrown destructs any in-place default-constructed pixels
|
||||
template <typename View>
|
||||
template <typename View>
|
||||
void default_construct_pixels(const View& img_view) {
|
||||
if (detail::has_trivial_pixel_constructor<View, is_planar<View>::value>::value)
|
||||
return;
|
||||
|
||||
if (img_view.is_1d_traversable())
|
||||
detail::default_construct_aux(img_view.begin().x(), img_view.end().x(), is_planar<View>());
|
||||
else {
|
||||
typename View::y_coord_t y;
|
||||
try {
|
||||
for (y=0; y<img_view.height(); ++y)
|
||||
detail::default_construct_aux(img_view.row_begin(y),img_view.row_end(y), is_planar<View>());
|
||||
} catch(...) {
|
||||
for (typename View::y_coord_t y0=0; y0<y; ++y0)
|
||||
detail::destruct_aux(img_view.row_begin(y0),img_view.row_end(y0), is_planar<View>());
|
||||
throw;
|
||||
}
|
||||
}
|
||||
detail::default_construct_pixels_impl< View
|
||||
, detail::has_trivial_pixel_constructor< View
|
||||
, is_planar< View >::value
|
||||
>::value
|
||||
>( img_view );
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// uninitialized_copy_pixels
|
||||
@@ -656,15 +682,14 @@ void default_construct_pixels(const View& img_view) {
|
||||
/// \brief std::uninitialized_copy for image views
|
||||
|
||||
namespace detail {
|
||||
|
||||
/// std::uninitialized_copy for pairs of planar iterators
|
||||
template <typename It1, typename It2>
|
||||
GIL_FORCEINLINE
|
||||
BOOST_FORCEINLINE
|
||||
void uninitialized_copy_aux(It1 first1, It1 last1,
|
||||
It2 first2, mpl::true_) {
|
||||
int channel=0;
|
||||
try {
|
||||
typedef typename std::iterator_traits<It1>::value_type pixel_t;
|
||||
using pixel_t = typename std::iterator_traits<It1>::value_type;
|
||||
while (channel < num_channels<pixel_t>::value) {
|
||||
std::uninitialized_copy(dynamic_at_c(first1,channel), dynamic_at_c(last1,channel), dynamic_at_c(first2,channel));
|
||||
++channel;
|
||||
@@ -679,7 +704,7 @@ void uninitialized_copy_aux(It1 first1, It1 last1,
|
||||
}
|
||||
/// std::uninitialized_copy for interleaved or mixed iterators
|
||||
template <typename It1, typename It2>
|
||||
GIL_FORCEINLINE
|
||||
BOOST_FORCEINLINE
|
||||
void uninitialized_copy_aux(It1 first1, It1 last1,
|
||||
It2 first2,mpl::false_) {
|
||||
std::uninitialized_copy(first1,last1,first2);
|
||||
@@ -690,16 +715,16 @@ void uninitialized_copy_aux(It1 first1, It1 last1,
|
||||
/// \brief std::uninitialized_copy for image views.
|
||||
/// Does not support planar heterogeneous views.
|
||||
/// If an exception is thrown destructs any in-place copy-constructed objects
|
||||
template <typename View1, typename View2>
|
||||
template <typename View1, typename View2>
|
||||
void uninitialized_copy_pixels(const View1& view1, const View2& view2) {
|
||||
typedef mpl::bool_<is_planar<View1>::value && is_planar<View2>::value> is_planar;
|
||||
assert(view1.dimensions()==view2.dimensions());
|
||||
using is_planar = mpl::bool_<is_planar<View1>::value && is_planar<View2>::value>;
|
||||
BOOST_ASSERT(view1.dimensions() == view2.dimensions());
|
||||
if (view1.is_1d_traversable() && view2.is_1d_traversable())
|
||||
detail::uninitialized_copy_aux(view1.begin().x(), view1.end().x(),
|
||||
view2.begin().x(),
|
||||
detail::uninitialized_copy_aux(view1.begin().x(), view1.end().x(),
|
||||
view2.begin().x(),
|
||||
is_planar());
|
||||
else {
|
||||
typename View1::y_coord_t y;
|
||||
typename View1::y_coord_t y = 0;
|
||||
try {
|
||||
for (y=0; y<view1.height(); ++y)
|
||||
detail::uninitialized_copy_aux(view1.row_begin(y), view1.row_end(y),
|
||||
@@ -723,9 +748,9 @@ void uninitialized_copy_pixels(const View1& view1, const View2& view2) {
|
||||
/// \ingroup ImageViewSTLAlgorithms
|
||||
/// \brief std::for_each for image views
|
||||
///
|
||||
/// For contiguous images (i.e. images that have no alignment gap at the end of each row) it is
|
||||
/// more efficient to use the underlying pixel iterator that does not check for the end of rows.
|
||||
/// For non-contiguous images for_each_pixel resolves to for_each of each row using the underlying
|
||||
/// For contiguous images (i.e. images that have no alignment gap at the end of each row) it is
|
||||
/// more efficient to use the underlying pixel iterator that does not check for the end of rows.
|
||||
/// For non-contiguous images for_each_pixel resolves to for_each of each row using the underlying
|
||||
/// pixel iterator, which is still faster
|
||||
|
||||
/// \ingroup ImageViewSTLAlgorithmsForEachPixel
|
||||
@@ -735,7 +760,7 @@ F for_each_pixel(const V& img, F fun) {
|
||||
return std::for_each(img.begin().x(), img.end().x(), fun);
|
||||
} else {
|
||||
for (std::ptrdiff_t y=0; y<img.height(); ++y)
|
||||
fun = std::for_each(img.row_begin(y),img.row_end(y),fun);
|
||||
std::for_each(img.row_begin(y),img.row_end(y),fun);
|
||||
return fun;
|
||||
}
|
||||
}
|
||||
@@ -756,7 +781,6 @@ F for_each_pixel_position(const View& img, F fun) {
|
||||
return fun;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// generate_pixels
|
||||
@@ -789,20 +813,19 @@ void generate_pixels(const View& v, F fun) {
|
||||
/// \ingroup ImageViewSTLAlgorithms
|
||||
/// \brief std::equal for image views
|
||||
|
||||
template <typename I1, typename I2> GIL_FORCEINLINE bool equal_n(I1 i1, std::ptrdiff_t n, I2 i2);
|
||||
template <typename I1, typename I2> BOOST_FORCEINLINE bool equal_n(I1 i1, std::ptrdiff_t n, I2 i2);
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename I1, typename I2>
|
||||
struct equal_n_fn {
|
||||
GIL_FORCEINLINE bool operator()(I1 i1, std::ptrdiff_t n, I2 i2) const { return std::equal(i1,i1+n, i2); }
|
||||
BOOST_FORCEINLINE bool operator()(I1 i1, std::ptrdiff_t n, I2 i2) const { return std::equal(i1,i1+n, i2); }
|
||||
};
|
||||
|
||||
/// Equal when both ranges are interleaved and of the same type.
|
||||
/// Equal when both ranges are interleaved and of the same type.
|
||||
/// GIL pixels are bitwise comparable, so memcmp is used. User-defined pixels that are not bitwise comparable need to provide an overload
|
||||
template<typename T, typename Cs>
|
||||
struct equal_n_fn<const pixel<T,Cs>*, const pixel<T,Cs>*> {
|
||||
GIL_FORCEINLINE bool operator()(const pixel<T,Cs>* i1, std::ptrdiff_t n, const pixel<T,Cs>* i2) const {
|
||||
BOOST_FORCEINLINE bool operator()(const pixel<T,Cs>* i1, std::ptrdiff_t n, const pixel<T,Cs>* i2) const {
|
||||
return memcmp(i1, i2, n*sizeof(pixel<T,Cs>))==0;
|
||||
}
|
||||
};
|
||||
@@ -814,8 +837,8 @@ struct equal_n_fn<pixel<T,Cs>*, pixel<T,Cs>*> : equal_n_fn<const pixel<T,Cs>*, c
|
||||
/// User-defined channels that are not bitwise comparable need to provide an overload
|
||||
template<typename IC, typename Cs>
|
||||
struct equal_n_fn<planar_pixel_iterator<IC,Cs>, planar_pixel_iterator<IC,Cs> > {
|
||||
GIL_FORCEINLINE bool operator()(const planar_pixel_iterator<IC,Cs> i1, std::ptrdiff_t n, const planar_pixel_iterator<IC,Cs> i2) const {
|
||||
ptrdiff_t numBytes=n*sizeof(typename std::iterator_traits<IC>::value_type);
|
||||
BOOST_FORCEINLINE bool operator()(const planar_pixel_iterator<IC,Cs> i1, std::ptrdiff_t n, const planar_pixel_iterator<IC,Cs> i2) const {
|
||||
std::ptrdiff_t numBytes=n*sizeof(typename std::iterator_traits<IC>::value_type);
|
||||
|
||||
for (std::ptrdiff_t i=0; i<mpl::size<Cs>::value; ++i)
|
||||
if (memcmp(dynamic_at_c(i1,i), dynamic_at_c(i2,i), numBytes)!=0)
|
||||
@@ -824,11 +847,10 @@ struct equal_n_fn<planar_pixel_iterator<IC,Cs>, planar_pixel_iterator<IC,Cs> > {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Source range is delimited by image iterators
|
||||
template <typename Loc, typename I2> // IL Models ConstPixelLocatorConcept, O Models PixelIteratorConcept
|
||||
struct equal_n_fn<boost::gil::iterator_from_2d<Loc>,I2> {
|
||||
GIL_FORCEINLINE bool operator()(boost::gil::iterator_from_2d<Loc> i1, std::ptrdiff_t n, I2 i2) const {
|
||||
BOOST_FORCEINLINE bool operator()(boost::gil::iterator_from_2d<Loc> i1, std::ptrdiff_t n, I2 i2) const {
|
||||
gil_function_requires<boost::gil::PixelLocatorConcept<Loc> >();
|
||||
gil_function_requires<boost::gil::PixelIteratorConcept<I2> >();
|
||||
while (n>0) {
|
||||
@@ -846,7 +868,7 @@ struct equal_n_fn<boost::gil::iterator_from_2d<Loc>,I2> {
|
||||
/// Destination range is delimited by image iterators
|
||||
template <typename I1, typename Loc> // I Models PixelIteratorConcept, OL Models PixelLocatorConcept
|
||||
struct equal_n_fn<I1,boost::gil::iterator_from_2d<Loc> > {
|
||||
GIL_FORCEINLINE bool operator()(I1 i1, std::ptrdiff_t n, boost::gil::iterator_from_2d<Loc> i2) const {
|
||||
BOOST_FORCEINLINE bool operator()(I1 i1, std::ptrdiff_t n, boost::gil::iterator_from_2d<Loc> i2) const {
|
||||
gil_function_requires<boost::gil::PixelIteratorConcept<I1> >();
|
||||
gil_function_requires<boost::gil::PixelLocatorConcept<Loc> >();
|
||||
while (n>0) {
|
||||
@@ -864,7 +886,7 @@ struct equal_n_fn<I1,boost::gil::iterator_from_2d<Loc> > {
|
||||
/// Both source and destination ranges are delimited by image iterators
|
||||
template <typename Loc1, typename Loc2>
|
||||
struct equal_n_fn<boost::gil::iterator_from_2d<Loc1>,boost::gil::iterator_from_2d<Loc2> > {
|
||||
GIL_FORCEINLINE bool operator()(boost::gil::iterator_from_2d<Loc1> i1, std::ptrdiff_t n, boost::gil::iterator_from_2d<Loc2> i2) const {
|
||||
BOOST_FORCEINLINE bool operator()(boost::gil::iterator_from_2d<Loc1> i1, std::ptrdiff_t n, boost::gil::iterator_from_2d<Loc2> i2) const {
|
||||
gil_function_requires<boost::gil::PixelLocatorConcept<Loc1> >();
|
||||
gil_function_requires<boost::gil::PixelLocatorConcept<Loc2> >();
|
||||
if (i1.x_pos()!=i2.x_pos() || i1.width()!=i2.width()) {
|
||||
@@ -885,7 +907,7 @@ struct equal_n_fn<boost::gil::iterator_from_2d<Loc1>,boost::gil::iterator_from_2
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <typename I1, typename I2> GIL_FORCEINLINE
|
||||
template <typename I1, typename I2> BOOST_FORCEINLINE
|
||||
bool equal_n(I1 i1, std::ptrdiff_t n, I2 i2) {
|
||||
return detail::equal_n_fn<I1,I2>()(i1,n,i2);
|
||||
}
|
||||
@@ -896,14 +918,14 @@ namespace std {
|
||||
/// \brief std::equal(I1,I1,I2) with I1 and I2 being a iterator_from_2d
|
||||
///
|
||||
/// Invoked when one calls std::equal(I1,I1,I2) with I1 and I2 being a iterator_from_2d (which is
|
||||
/// a 1D iterator over the pixels in an image). Attempts to demote the source and destination
|
||||
/// a 1D iterator over the pixels in an image). Attempts to demote the source and destination
|
||||
/// iterators to simpler/faster types if the corresponding range is contiguous.
|
||||
/// For contiguous images (i.e. images that have
|
||||
/// no alignment gap at the end of each row) it is more efficient to use the underlying
|
||||
/// no alignment gap at the end of each row) it is more efficient to use the underlying
|
||||
/// pixel iterator that does not check for the end of rows. If the underlying pixel iterator
|
||||
/// happens to be a fundamental planar/interleaved pointer, the call may further resolve
|
||||
/// to memcmp. Otherwise it resolves to copying each row using the underlying pixel iterator
|
||||
template <typename Loc1, typename Loc2> GIL_FORCEINLINE
|
||||
template <typename Loc1, typename Loc2> BOOST_FORCEINLINE
|
||||
bool equal(boost::gil::iterator_from_2d<Loc1> first, boost::gil::iterator_from_2d<Loc1> last, boost::gil::iterator_from_2d<Loc2> first2) {
|
||||
boost::gil::gil_function_requires<boost::gil::PixelLocatorConcept<Loc1> >();
|
||||
boost::gil::gil_function_requires<boost::gil::PixelLocatorConcept<Loc2> >();
|
||||
@@ -923,12 +945,11 @@ bool equal(boost::gil::iterator_from_2d<Loc1> first, boost::gil::iterator_from_2
|
||||
} // namespace std
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \ingroup ImageViewSTLAlgorithmsEqualPixels
|
||||
/// \brief std::equal for image views
|
||||
template <typename View1, typename View2> GIL_FORCEINLINE
|
||||
template <typename View1, typename View2> BOOST_FORCEINLINE
|
||||
bool equal_pixels(const View1& v1, const View2& v2) {
|
||||
assert(v1.dimensions()==v2.dimensions());
|
||||
BOOST_ASSERT(v1.dimensions() == v2.dimensions());
|
||||
return std::equal(v1.begin(),v1.end(),v2.begin()); // std::equal has overloads with GIL iterators for optimal performance
|
||||
}
|
||||
|
||||
@@ -944,9 +965,9 @@ bool equal_pixels(const View1& v1, const View2& v2) {
|
||||
|
||||
/// \ingroup ImageViewSTLAlgorithmsTransformPixels
|
||||
/// \brief std::transform for image views
|
||||
template <typename View1, typename View2, typename F> GIL_FORCEINLINE
|
||||
template <typename View1, typename View2, typename F> BOOST_FORCEINLINE
|
||||
F transform_pixels(const View1& src,const View2& dst, F fun) {
|
||||
assert(src.dimensions()==dst.dimensions());
|
||||
BOOST_ASSERT(src.dimensions() == dst.dimensions());
|
||||
for (std::ptrdiff_t y=0; y<src.height(); ++y) {
|
||||
typename View1::x_iterator srcIt=src.row_begin(y);
|
||||
typename View2::x_iterator dstIt=dst.row_begin(y);
|
||||
@@ -958,7 +979,7 @@ F transform_pixels(const View1& src,const View2& dst, F fun) {
|
||||
|
||||
/// \ingroup ImageViewSTLAlgorithmsTransformPixels
|
||||
/// \brief transform_pixels with two sources
|
||||
template <typename View1, typename View2, typename View3, typename F> GIL_FORCEINLINE
|
||||
template <typename View1, typename View2, typename View3, typename F> BOOST_FORCEINLINE
|
||||
F transform_pixels(const View1& src1, const View2& src2,const View3& dst, F fun) {
|
||||
for (std::ptrdiff_t y=0; y<dst.height(); ++y) {
|
||||
typename View1::x_iterator srcIt1=src1.row_begin(y);
|
||||
@@ -972,13 +993,13 @@ F transform_pixels(const View1& src1, const View2& src2,const View3& dst, F fun)
|
||||
|
||||
/// \defgroup ImageViewSTLAlgorithmsTransformPixelPositions transform_pixel_positions
|
||||
/// \ingroup ImageViewSTLAlgorithms
|
||||
/// \brief adobe::transform_positions for image views (passes locators, instead of pixel references, to the function object)
|
||||
/// \brief adobe::transform_positions for image views (passes locators, instead of pixel references, to the function object)
|
||||
|
||||
/// \ingroup ImageViewSTLAlgorithmsTransformPixelPositions
|
||||
/// \brief Like transform_pixels but passes to the function object pixel locators instead of pixel references
|
||||
template <typename View1, typename View2, typename F> GIL_FORCEINLINE
|
||||
template <typename View1, typename View2, typename F> BOOST_FORCEINLINE
|
||||
F transform_pixel_positions(const View1& src,const View2& dst, F fun) {
|
||||
assert(src.dimensions()==dst.dimensions());
|
||||
BOOST_ASSERT(src.dimensions() == dst.dimensions());
|
||||
typename View1::xy_locator loc=src.xy_at(0,0);
|
||||
for (std::ptrdiff_t y=0; y<src.height(); ++y) {
|
||||
typename View2::x_iterator dstIt=dst.row_begin(y);
|
||||
@@ -991,10 +1012,10 @@ F transform_pixel_positions(const View1& src,const View2& dst, F fun) {
|
||||
|
||||
/// \ingroup ImageViewSTLAlgorithmsTransformPixelPositions
|
||||
/// \brief transform_pixel_positions with two sources
|
||||
template <typename View1, typename View2, typename View3, typename F> GIL_FORCEINLINE
|
||||
template <typename View1, typename View2, typename View3, typename F> BOOST_FORCEINLINE
|
||||
F transform_pixel_positions(const View1& src1,const View2& src2,const View3& dst, F fun) {
|
||||
assert(src1.dimensions()==dst.dimensions());
|
||||
assert(src2.dimensions()==dst.dimensions());
|
||||
BOOST_ASSERT(src1.dimensions() == dst.dimensions());
|
||||
BOOST_ASSERT(src2.dimensions() == dst.dimensions());
|
||||
typename View1::xy_locator loc1=src1.xy_at(0,0);
|
||||
typename View2::xy_locator loc2=src2.xy_at(0,0);
|
||||
for (std::ptrdiff_t y=0; y<src1.height(); ++y) {
|
||||
@@ -1006,11 +1027,6 @@ F transform_pixel_positions(const View1& src1,const View2& src2,const View3& dst
|
||||
}
|
||||
return fun;
|
||||
}
|
||||
|
||||
} } // namespace boost::gil
|
||||
|
||||
//#ifdef _MSC_VER
|
||||
//#pragma warning(pop)
|
||||
//#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,35 +1,26 @@
|
||||
/*
|
||||
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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_BIT_ALIGNED_PIXEL_ITERATOR_HPP
|
||||
#define BOOST_GIL_BIT_ALIGNED_PIXEL_ITERATOR_HPP
|
||||
|
||||
See http://opensource.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
#include <boost/gil/bit_aligned_pixel_reference.hpp>
|
||||
#include <boost/gil/pixel_iterator.hpp>
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#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 <boost/config.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
|
||||
#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 {
|
||||
|
||||
/// A model of a heterogeneous pixel that is not byte aligned.
|
||||
/// Examples are bitmap (1-bit pixels) or 6-bit RGB (222).
|
||||
|
||||
/// \defgroup PixelIteratorNonAlignedPixelIterator bit_aligned_pixel_iterator
|
||||
/// \ingroup PixelIteratorModel
|
||||
/// \brief An iterator over non-byte-aligned pixels. Models PixelIteratorConcept, PixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept
|
||||
@@ -38,7 +29,7 @@ namespace boost { namespace gil {
|
||||
/// \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>
|
||||
@@ -48,17 +39,17 @@ struct bit_aligned_pixel_iterator : public iterator_facade<bit_aligned_pixel_ite
|
||||
const NonAlignedPixelReference,
|
||||
typename NonAlignedPixelReference::bit_range_t::difference_type> {
|
||||
private:
|
||||
typedef iterator_facade<bit_aligned_pixel_iterator<NonAlignedPixelReference>,
|
||||
using parent_t = iterator_facade<bit_aligned_pixel_iterator<NonAlignedPixelReference>,
|
||||
typename NonAlignedPixelReference::value_type,
|
||||
std::random_access_iterator_tag,
|
||||
const NonAlignedPixelReference,
|
||||
typename NonAlignedPixelReference::bit_range_t::difference_type> parent_t;
|
||||
typename NonAlignedPixelReference::bit_range_t::difference_type>;
|
||||
template <typename Ref> friend struct bit_aligned_pixel_iterator;
|
||||
|
||||
typedef typename NonAlignedPixelReference::bit_range_t bit_range_t;
|
||||
using bit_range_t = typename NonAlignedPixelReference::bit_range_t;
|
||||
public:
|
||||
typedef typename parent_t::difference_type difference_type;
|
||||
typedef typename parent_t::reference reference;
|
||||
using difference_type = typename parent_t::difference_type;
|
||||
using reference = typename parent_t::reference;
|
||||
|
||||
bit_aligned_pixel_iterator() {}
|
||||
bit_aligned_pixel_iterator(const bit_aligned_pixel_iterator& p) : _bit_range(p._bit_range) {}
|
||||
@@ -78,7 +69,7 @@ public:
|
||||
bit_range_t& bit_range() { return _bit_range; }
|
||||
private:
|
||||
bit_range_t _bit_range;
|
||||
BOOST_STATIC_CONSTANT(int, bit_size = NonAlignedPixelReference::bit_size);
|
||||
static constexpr int bit_size = NonAlignedPixelReference::bit_size;
|
||||
|
||||
friend class boost::iterator_core_access;
|
||||
reference dereference() const { return NonAlignedPixelReference(_bit_range); }
|
||||
@@ -90,15 +81,15 @@ private:
|
||||
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 const_iterator_type<bit_aligned_pixel_iterator<NonAlignedPixelReference> > {
|
||||
using type = bit_aligned_pixel_iterator<typename NonAlignedPixelReference::const_reference>;
|
||||
};
|
||||
|
||||
template <typename NonAlignedPixelReference>
|
||||
template <typename NonAlignedPixelReference>
|
||||
struct iterator_is_mutable<bit_aligned_pixel_iterator<NonAlignedPixelReference> > : public mpl::bool_<NonAlignedPixelReference::is_mutable> {};
|
||||
|
||||
template <typename NonAlignedPixelReference>
|
||||
template <typename NonAlignedPixelReference>
|
||||
struct is_iterator_adaptor<bit_aligned_pixel_iterator<NonAlignedPixelReference> > : public mpl::false_ {};
|
||||
|
||||
/////////////////////////////
|
||||
@@ -122,17 +113,17 @@ 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;
|
||||
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();
|
||||
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) {
|
||||
inline void memunit_advance(bit_aligned_pixel_iterator<NonAlignedPixelReference>& p, std::ptrdiff_t diff) {
|
||||
p.bit_range().bit_advance(diff);
|
||||
}
|
||||
|
||||
@@ -153,7 +144,7 @@ NonAlignedPixelReference memunit_advanced_ref(bit_aligned_pixel_iterator<NonAlig
|
||||
|
||||
template <typename NonAlignedPixelReference>
|
||||
struct dynamic_x_step_type<bit_aligned_pixel_iterator<NonAlignedPixelReference> > {
|
||||
typedef memory_based_step_iterator<bit_aligned_pixel_iterator<NonAlignedPixelReference> > type;
|
||||
using type = memory_based_step_iterator<bit_aligned_pixel_iterator<NonAlignedPixelReference> >;
|
||||
};
|
||||
|
||||
/////////////////////////////
|
||||
@@ -161,13 +152,15 @@ struct dynamic_x_step_type<bit_aligned_pixel_iterator<NonAlignedPixelReference>
|
||||
/////////////////////////////
|
||||
|
||||
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;
|
||||
struct iterator_type_from_pixel<const bit_aligned_pixel_reference<B,C,L,M>,false,false,false>
|
||||
{
|
||||
using type = bit_aligned_pixel_iterator<bit_aligned_pixel_reference<B,C,L,false>> ;
|
||||
};
|
||||
|
||||
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;
|
||||
struct iterator_type_from_pixel<const bit_aligned_pixel_reference<B,C,L,M>,false,false,true>
|
||||
{
|
||||
using type = bit_aligned_pixel_iterator<bit_aligned_pixel_reference<B,C,L,true>>;
|
||||
};
|
||||
|
||||
template <typename B, typename C, typename L, bool M, bool IsPlanar, bool IsStep, bool IsMutable>
|
||||
@@ -179,9 +172,9 @@ struct iterator_type_from_pixel<bit_aligned_pixel_reference<B,C,L,M>,IsPlanar,Is
|
||||
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.
|
||||
// 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> 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);
|
||||
|
||||
@@ -1,28 +1,18 @@
|
||||
/*
|
||||
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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_BIT_ALIGNED_PIXEL_REFERENCE_HPP
|
||||
#define BOOST_GIL_BIT_ALIGNED_PIXEL_REFERENCE_HPP
|
||||
|
||||
See http://stlab.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
#include <boost/gil/pixel.hpp>
|
||||
#include <boost/gil/channel.hpp>
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#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/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/mpl/accumulate.hpp>
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
@@ -30,31 +20,39 @@
|
||||
#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"
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// A model of a heterogeneous pixel that is not byte aligned.
|
||||
/// Examples are bitmap (1-bit pixels) or 6-bit RGB (222).
|
||||
|
||||
/////////////////////////////
|
||||
// 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;
|
||||
using byte_t = typename mpl::if_c<Mutable,unsigned char,const unsigned char>::type;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
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() : _current_byte(nullptr), _bit_offset(0) {}
|
||||
bit_range(byte_t* current_byte, int bit_offset)
|
||||
: _current_byte(current_byte)
|
||||
, _bit_offset(bit_offset)
|
||||
{
|
||||
BOOST_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) {}
|
||||
@@ -85,53 +83,61 @@ public:
|
||||
int bit_offset() const { return _bit_offset; }
|
||||
};
|
||||
|
||||
|
||||
/// \defgroup ColorBaseModelNonAlignedPixel bit_aligned_pixel_reference
|
||||
/// \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
|
||||
*/
|
||||
///
|
||||
/// \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)
|
||||
/// using rgb123_ref_t = bit_aligned_pixel_reference<unsigned char, mpl::vector3_c<int,1,2,3>, rgb_layout_t, true> const;
|
||||
///
|
||||
/// // 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;
|
||||
///
|
||||
/// \tparam BitField
|
||||
/// \tparam ChannelBitSizes MPL integral vector defining the number of bits for each channel. For example, for 565RGB, vector_c<int,5,6,5>
|
||||
/// \tparam Layout
|
||||
/// \tparam IsMutable
|
||||
template <typename BitField, typename ChannelBitSizes, typename Layout, bool IsMutable>
|
||||
struct bit_aligned_pixel_reference
|
||||
{
|
||||
static constexpr int bit_size =
|
||||
mpl::accumulate
|
||||
<
|
||||
ChannelBitSizes,
|
||||
mpl::int_<0>,
|
||||
mpl::plus<mpl::_1, mpl::_2>
|
||||
>::type::value;
|
||||
|
||||
typedef Layout layout_t;
|
||||
using bit_range_t = boost::gil::bit_range<bit_size,IsMutable>;
|
||||
using bitfield_t = BitField;
|
||||
using data_ptr_t =typename mpl::if_c<IsMutable,unsigned char*,const unsigned char*>::type;
|
||||
|
||||
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;
|
||||
using layout_t = Layout;
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, is_mutable = IsMutable);
|
||||
using value_type = typename packed_pixel_type<bitfield_t,ChannelBitSizes,Layout>::type;
|
||||
using reference = const bit_aligned_pixel_reference<BitField, ChannelBitSizes, Layout, IsMutable>;
|
||||
using const_reference = bit_aligned_pixel_reference<BitField,ChannelBitSizes,Layout,false> const;
|
||||
|
||||
static constexpr 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) {}
|
||||
@@ -139,8 +145,10 @@ struct bit_aligned_pixel_reference {
|
||||
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));
|
||||
explicit bit_aligned_pixel_reference(typename kth_element_type<bit_aligned_pixel_reference,0>::type const channel0)
|
||||
: _bit_range(static_cast<data_ptr_t>(&channel0), channel0.first_bit())
|
||||
{
|
||||
static_assert(num_channels<bit_aligned_pixel_reference>::value == 1, "");
|
||||
}
|
||||
|
||||
// Construct from another compatible pixel type
|
||||
@@ -150,9 +158,9 @@ struct bit_aligned_pixel_reference {
|
||||
}
|
||||
|
||||
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> 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 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; }
|
||||
@@ -164,11 +172,15 @@ private:
|
||||
|
||||
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); }
|
||||
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)); }
|
||||
static void check_gray()
|
||||
{
|
||||
static_assert(std::is_same<typename Layout::color_space_t, gray_t>::value, "");
|
||||
}
|
||||
|
||||
template <typename Channel> void assign(const Channel& chan, mpl::false_) const { check_gray(); gil::at_c<0>(*this)=chan; }
|
||||
template <typename Channel> bool equal (const Channel& chan, mpl::false_) const { check_gray(); return gil::at_c<0>(*this)==chan; }
|
||||
};
|
||||
@@ -177,24 +189,24 @@ private:
|
||||
// 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 BitField, typename ChannelBitSizes, typename L, bool IsMutable, int K>
|
||||
struct kth_element_type<bit_aligned_pixel_reference<BitField,ChannelBitSizes,L,IsMutable>, K>
|
||||
{
|
||||
using type = packed_dynamic_channel_reference<BitField, mpl::at_c<ChannelBitSizes,K>::type::value, IsMutable> const;
|
||||
};
|
||||
|
||||
template <typename B, typename C, typename L, bool M, int K>
|
||||
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>
|
||||
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>
|
||||
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> {};
|
||||
@@ -203,15 +215,16 @@ namespace detail {
|
||||
// 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;
|
||||
at_c(const bit_aligned_pixel_reference<BitField,ChannelBitSizes,L,Mutable>& p)
|
||||
{
|
||||
using pixel_t = bit_aligned_pixel_reference<BitField,ChannelBitSizes,L,Mutable>;
|
||||
using channel_t = typename kth_element_reference_type<pixel_t,K>::type;
|
||||
using bit_range_t = typename pixel_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());
|
||||
return channel_t(bit_range.current_byte(), bit_range.bit_offset());
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
@@ -219,7 +232,7 @@ at_c(const bit_aligned_pixel_reference<BitField,ChannelBitSizes,L,Mutable>& p) {
|
||||
/////////////////////////////
|
||||
|
||||
/// 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>
|
||||
template <typename B, typename C, typename L, bool M>
|
||||
struct is_pixel<bit_aligned_pixel_reference<B,C,L,M> > : public mpl::true_{};
|
||||
|
||||
/////////////////////////////
|
||||
@@ -228,16 +241,16 @@ struct is_pixel<bit_aligned_pixel_reference<B,C,L,M> > : public mpl::true_{};
|
||||
|
||||
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;
|
||||
};
|
||||
using type = typename L::color_space_t;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
using type = typename L::channel_mapping_t;
|
||||
};
|
||||
|
||||
template <typename B, typename C, typename L, bool M>
|
||||
struct is_planar<bit_aligned_pixel_reference<B,C,L,M> > : mpl::false_ {};
|
||||
struct is_planar<bit_aligned_pixel_reference<B,C,L,M> > : mpl::false_ {};
|
||||
|
||||
/////////////////////////////
|
||||
// pixel_reference_type
|
||||
@@ -247,56 +260,58 @@ 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;
|
||||
using type = mpl::vector0<>;
|
||||
};
|
||||
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> {
|
||||
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;
|
||||
using size_t = typename mpl::size<typename Layout::color_space_t>::type;
|
||||
using channel_bit_sizes_t = typename detail::k_copies<size_t::value,mpl::integral_c<unsigned,NumBits> >::type;
|
||||
public:
|
||||
typedef bit_aligned_pixel_reference<BitField, channel_bit_sizes_t, Layout, false> type;
|
||||
using type = bit_aligned_pixel_reference<BitField, channel_bit_sizes_t, Layout, false>;
|
||||
};
|
||||
|
||||
// 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> {
|
||||
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;
|
||||
using size_t = typename mpl::size<typename Layout::color_space_t>::type;
|
||||
using channel_bit_sizes_t = typename detail::k_copies<size_t::value,mpl::integral_c<unsigned,NumBits>>::type;
|
||||
public:
|
||||
typedef bit_aligned_pixel_reference<BitField, channel_bit_sizes_t, Layout, true> type;
|
||||
using type = bit_aligned_pixel_reference<BitField, channel_bit_sizes_t, Layout, true>;
|
||||
};
|
||||
|
||||
} } // 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 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);
|
||||
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);
|
||||
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);
|
||||
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
|
||||
|
||||
@@ -1,88 +1,108 @@
|
||||
/*
|
||||
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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CHANNEL_HPP
|
||||
#define BOOST_GIL_CHANNEL_HPP
|
||||
|
||||
See http://stlab.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
#include <boost/gil/utilities.hpp>
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#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 <boost/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
#include <boost/integer/integer_mask.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <cassert>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include "gil_config.hpp"
|
||||
#include "utilities.hpp"
|
||||
|
||||
#ifdef BOOST_GIL_DOXYGEN_ONLY
|
||||
/// \def BOOST_GIL_CONFIG_HAS_UNALIGNED_ACCESS
|
||||
/// \brief Define to allow unaligned memory access for models of packed channel value.
|
||||
/// Theoretically (or historically?) on platforms which support dereferencing on
|
||||
/// non-word memory boundary, unaligned access may result in performance improvement.
|
||||
/// \warning Unfortunately, this optimization may be a C/C++ strict aliasing rules
|
||||
/// violation, if accessed data buffer has effective type that cannot be aliased
|
||||
/// without leading to undefined behaviour.
|
||||
#define BOOST_GIL_CONFIG_HAS_UNALIGNED_ACCESS
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_GIL_CONFIG_HAS_UNALIGNED_ACCESS
|
||||
#if defined(sun) || defined(__sun) || \ // SunOS
|
||||
defined(__osf__) || defined(__osf) || \ // Tru64
|
||||
defined(_hpux) || defined(hpux) || \ // HP-UX
|
||||
defined(__arm__) || defined(__ARM_ARCH) || \ // ARM
|
||||
defined(_AIX) // AIX
|
||||
#error Unaligned access strictly disabled for some UNIX platforms or ARM architecture
|
||||
#elif defined(__i386__) || defined(__x86_64__) || defined(__vax__)
|
||||
// The check for little-endian architectures that tolerate unaligned memory
|
||||
// accesses is just an optimization. Nothing will break if it fails to detect
|
||||
// a suitable architecture.
|
||||
//
|
||||
// Unfortunately, this optimization may be a C/C++ strict aliasing rules violation
|
||||
// if accessed data buffer has effective type that cannot be aliased
|
||||
// without leading to undefined behaviour.
|
||||
BOOST_PRAGMA_MESSAGE("CAUTION: Unaligned access tolerated on little-endian may cause undefined behaviour")
|
||||
#else
|
||||
#error Unaligned access disabled for unknown platforms and architectures
|
||||
#endif
|
||||
#endif // defined(BOOST_GIL_CONFIG_HAS_UNALIGNED_ACCESS)
|
||||
|
||||
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
|
||||
//// 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>
|
||||
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);
|
||||
using value_type = typename T::value_type;
|
||||
using reference = typename T::reference;
|
||||
using pointer = typename T::pointer;
|
||||
using const_reference = typename T::const_reference;
|
||||
using const_pointer = typename T::const_pointer;
|
||||
static constexpr 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>
|
||||
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);
|
||||
using value_type = T;
|
||||
using reference = T&;
|
||||
using pointer = T*;
|
||||
using const_reference = T const&;
|
||||
using const_pointer = T const*;
|
||||
static constexpr 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>
|
||||
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);
|
||||
using reference = const T &;
|
||||
using pointer = const T *;
|
||||
static constexpr bool is_mutable = false;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -92,12 +112,12 @@ namespace detail {
|
||||
\code
|
||||
template <typename Channel>
|
||||
struct channel_traits {
|
||||
typedef ... value_type;
|
||||
typedef ... reference;
|
||||
typedef ... pointer;
|
||||
typedef ... const_reference;
|
||||
typedef ... const_pointer;
|
||||
|
||||
using value_type = ...;
|
||||
using reference = ...;
|
||||
using pointer = ...;
|
||||
using const_reference = ...;
|
||||
using const_pointer = ...;
|
||||
|
||||
static const bool is_mutable;
|
||||
static value_type min_value();
|
||||
static value_type max_value();
|
||||
@@ -108,13 +128,15 @@ 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> {};
|
||||
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);
|
||||
template <typename T>
|
||||
struct channel_traits<T const&> : public channel_traits<T>
|
||||
{
|
||||
using reference = typename channel_traits<T>::const_reference;
|
||||
using pointer = typename channel_traits<T>::const_pointer;
|
||||
static constexpr bool is_mutable = false;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////
|
||||
@@ -123,39 +145,40 @@ template <typename T> struct channel_traits<const T&> : public channel_traits<T>
|
||||
////
|
||||
///////////////////////////////////////////
|
||||
|
||||
/**
|
||||
\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
|
||||
*/
|
||||
/// \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; } };
|
||||
/// using bits64custom_t = scoped_channel_value<double, double_minus_half, double_plus_half>;
|
||||
///
|
||||
/// // channel_convert its maximum should map to the maximum
|
||||
/// bits64custom_t x = channel_traits<bits64custom_t>::max_value();
|
||||
/// assert(x == 0.5);
|
||||
/// uint16_t y = channel_convert<uint16_t>(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);
|
||||
/// \tparam BaseChannelValue base channel (models ChannelValueConcept)
|
||||
/// \tparam MinVal class with a static apply() function returning the minimum channel values
|
||||
/// \tparam MaxVal class with a static apply() function returning the maximum channel values
|
||||
template <typename BaseChannelValue, typename MinVal, typename MaxVal>
|
||||
struct scoped_channel_value
|
||||
{
|
||||
using value_type = scoped_channel_value<BaseChannelValue, MinVal, MaxVal>;
|
||||
using reference = value_type&;
|
||||
using pointer = value_type*;
|
||||
using const_reference = value_type const&;
|
||||
using const_pointer = value_type const*;
|
||||
static constexpr bool is_mutable = channel_traits<BaseChannelValue>::is_mutable;
|
||||
|
||||
typedef BaseChannelValue base_channel_t;
|
||||
using base_channel_t = BaseChannelValue;
|
||||
|
||||
static value_type min_value() { return MinVal::apply(); }
|
||||
static value_type max_value() { return MaxVal::apply(); }
|
||||
@@ -181,9 +204,17 @@ private:
|
||||
BaseChannelValue _value;
|
||||
};
|
||||
|
||||
struct float_zero { static float apply() { return 0.0f; } };
|
||||
struct float_one { static float apply() { return 1.0f; } };
|
||||
template <typename T>
|
||||
struct float_point_zero
|
||||
{
|
||||
static constexpr T apply() { return 0.0f; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct float_point_one
|
||||
{
|
||||
static constexpr T apply() { return 1.0f; }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////
|
||||
////
|
||||
@@ -198,12 +229,12 @@ struct float_one { static float apply() { return 1.0f; } };
|
||||
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,
|
||||
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
|
||||
@@ -222,52 +253,45 @@ namespace detail {
|
||||
> {};
|
||||
}
|
||||
|
||||
/**
|
||||
\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
|
||||
*/
|
||||
/// \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.
|
||||
/// using bits4 = packed_channel_value<4>;
|
||||
///
|
||||
/// assert(channel_traits<bits4>::min_value()==0);
|
||||
/// assert(channel_traits<bits4>::max_value()==15);
|
||||
/// assert(sizeof(bits4)==1);
|
||||
/// 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 {
|
||||
|
||||
typedef typename detail::num_value_fn< NumBits >::type num_value_t;
|
||||
static const num_value_t num_values = static_cast< num_value_t >( 1 ) << NumBits ;
|
||||
|
||||
public:
|
||||
typedef typename detail::min_fast_uint<NumBits>::type integer_t;
|
||||
using integer_t = typename detail::min_fast_uint<NumBits>::type;
|
||||
|
||||
using value_type = packed_channel_value<NumBits>;
|
||||
using reference = value_type&;
|
||||
using const_reference = value_type const&;
|
||||
using pointer = value_type*;
|
||||
using const_pointer = value_type const*;
|
||||
static constexpr bool is_mutable = true;
|
||||
|
||||
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);
|
||||
static value_type min_value() { return 0; }
|
||||
static value_type max_value() { return low_bits_mask_t< NumBits >::sig_bits; }
|
||||
|
||||
packed_channel_value() {}
|
||||
packed_channel_value(integer_t v) { _value = static_cast< integer_t >( v % num_values ); }
|
||||
packed_channel_value(const packed_channel_value& v) : _value(v._value) {}
|
||||
template <typename Scalar> packed_channel_value(Scalar v) { _value = static_cast< integer_t >( v ) % num_values; }
|
||||
packed_channel_value(integer_t v) { _value = static_cast< integer_t >( v & low_bits_mask_t<NumBits>::sig_bits_fast ); }
|
||||
template <typename Scalar>
|
||||
packed_channel_value(Scalar v) { _value = packed_channel_value( static_cast< integer_t >( v ) ); }
|
||||
|
||||
static unsigned int num_bits() { return NumBits; }
|
||||
|
||||
|
||||
operator integer_t() const { return _value; }
|
||||
private:
|
||||
integer_t _value;
|
||||
@@ -291,22 +315,22 @@ struct static_copy_bytes<0> {
|
||||
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;
|
||||
using data_ptr_t = typename mpl::if_c<Mutable,void*,const void*>::type;
|
||||
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);
|
||||
using value_type = packed_channel_value<NumBits>;
|
||||
using reference = const Derived;
|
||||
using pointer = value_type *;
|
||||
using const_pointer = const value_type *;
|
||||
static constexpr int num_bits = NumBits;
|
||||
static constexpr 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;
|
||||
using bitfield_t = BitField;
|
||||
using integer_t = typename value_type::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) {}
|
||||
@@ -318,22 +342,22 @@ public:
|
||||
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(); }
|
||||
template <typename Scalar2> const Derived& operator+=(Scalar2 v) const { set( static_cast<integer_t>( get() + v )); return derived(); }
|
||||
template <typename Scalar2> const Derived& operator-=(Scalar2 v) const { set( static_cast<integer_t>( get() - v )); return derived(); }
|
||||
template <typename Scalar2> const Derived& operator*=(Scalar2 v) const { set( static_cast<integer_t>( get() * v )); return derived(); }
|
||||
template <typename Scalar2> const Derived& operator/=(Scalar2 v) const { set( static_cast<integer_t>( get() / v )); return derived(); }
|
||||
|
||||
operator integer_t() const { return get(); }
|
||||
data_ptr_t operator &() const {return _data_ptr;}
|
||||
protected:
|
||||
|
||||
typedef typename detail::num_value_fn< NumBits >::type num_value_t;
|
||||
typedef typename detail::max_value_fn< NumBits >::type max_value_t;
|
||||
|
||||
using num_value_t = typename detail::num_value_fn<NumBits>::type;
|
||||
using max_value_t = typename detail::max_value_fn<NumBits>::type;
|
||||
|
||||
static const num_value_t num_values = static_cast< num_value_t >( 1 ) << NumBits ;
|
||||
static const max_value_t max_val = static_cast< max_value_t >( num_values - 1 );
|
||||
|
||||
#ifdef GIL_NONWORD_POINTER_ALIGNMENT_SUPPORTED
|
||||
|
||||
#if defined(BOOST_GIL_CONFIG_HAS_UNALIGNED_ACCESS)
|
||||
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
|
||||
@@ -349,55 +373,53 @@ protected:
|
||||
|
||||
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);
|
||||
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;
|
||||
/// \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)
|
||||
/// using bits2_1_ref_t = packed_channel_reference<uint16_t,1,2,true> const;
|
||||
///
|
||||
/// 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
|
||||
|
||||
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
|
||||
template <typename BitField, // A type that holds the bits of the pixel from which the channel is referenced. Typically an integral type, like std::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
|
||||
template <typename BitField, // A type that holds the bits of the pixel from which the channel is referenced. Typically an integral type, like std::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;
|
||||
class packed_channel_reference<BitField,FirstBit,NumBits,false>
|
||||
: public detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,false>,BitField,NumBits,false>
|
||||
{
|
||||
using parent_t = detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,false>,BitField,NumBits,false>;
|
||||
friend class packed_channel_reference<BitField,FirstBit,NumBits,true>;
|
||||
|
||||
static const BitField channel_mask = static_cast< BitField >( 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;
|
||||
using const_reference = packed_channel_reference<BitField,FirstBit,NumBits,false> const;
|
||||
using mutable_reference = packed_channel_reference<BitField,FirstBit,NumBits,true> const;
|
||||
using integer_t = typename parent_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) {}
|
||||
@@ -411,22 +433,29 @@ public:
|
||||
/// \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;
|
||||
class packed_channel_reference<BitField,FirstBit,NumBits,true>
|
||||
: public detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,true>,BitField,NumBits,true>
|
||||
{
|
||||
using parent_t = detail::packed_channel_reference_base<packed_channel_reference<BitField,FirstBit,NumBits,true>,BitField,NumBits,true>;
|
||||
friend class packed_channel_reference<BitField,FirstBit,NumBits,false>;
|
||||
|
||||
static const BitField channel_mask = static_cast< BitField >( 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;
|
||||
using const_reference = packed_channel_reference<BitField,FirstBit,NumBits,false> const;
|
||||
using mutable_reference = packed_channel_reference<BitField,FirstBit,NumBits,true> const;
|
||||
using integer_t = typename parent_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; }
|
||||
packed_channel_reference const& operator=(integer_t value) const
|
||||
{
|
||||
BOOST_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; }
|
||||
|
||||
@@ -445,7 +474,7 @@ private:
|
||||
|
||||
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 with 'left bias':
|
||||
// - swap between proxy and anything
|
||||
// - swap between value type and proxy
|
||||
// - swap between proxy and proxy
|
||||
@@ -453,62 +482,60 @@ namespace std {
|
||||
/// \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);
|
||||
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);
|
||||
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);
|
||||
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
|
||||
*/
|
||||
/// \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
|
||||
/// using bits2_dynamic_ref_t = packed_dynamic_channel_reference<uint8_t,2,true> const;
|
||||
///
|
||||
/// 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>
|
||||
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;
|
||||
: public detail::packed_channel_reference_base<packed_dynamic_channel_reference<BitField,NumBits,false>,BitField,NumBits,false>
|
||||
{
|
||||
using parent_t = detail::packed_channel_reference_base<packed_dynamic_channel_reference<BitField,NumBits,false>,BitField,NumBits,false>;
|
||||
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;
|
||||
using const_reference = packed_dynamic_channel_reference<BitField,NumBits,false> const;
|
||||
using mutable_reference = packed_dynamic_channel_reference<BitField,NumBits,true> const;
|
||||
using integer_t = typename parent_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) {}
|
||||
@@ -516,7 +543,7 @@ public:
|
||||
|
||||
unsigned first_bit() const { return _first_bit; }
|
||||
|
||||
integer_t get() const {
|
||||
integer_t get() const {
|
||||
const BitField channel_mask = static_cast< integer_t >( parent_t::max_val ) <<_first_bit;
|
||||
return static_cast< integer_t >(( this->get_data()&channel_mask ) >> _first_bit );
|
||||
}
|
||||
@@ -525,47 +552,54 @@ public:
|
||||
/// \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>
|
||||
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;
|
||||
: public detail::packed_channel_reference_base<packed_dynamic_channel_reference<BitField,NumBits,true>,BitField,NumBits,true>
|
||||
{
|
||||
using parent_t = detail::packed_channel_reference_base<packed_dynamic_channel_reference<BitField,NumBits,true>,BitField,NumBits,true>;
|
||||
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;
|
||||
using const_reference = packed_dynamic_channel_reference<BitField,NumBits,false> const;
|
||||
using mutable_reference = packed_dynamic_channel_reference<BitField,NumBits,true> const;
|
||||
using integer_t = typename parent_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; }
|
||||
packed_dynamic_channel_reference const& operator=(integer_t value) const
|
||||
{
|
||||
BOOST_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
|
||||
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 {
|
||||
integer_t get() const {
|
||||
const BitField channel_mask = static_cast< integer_t >( parent_t::max_val ) << _first_bit;
|
||||
return static_cast< integer_t >(( this->get_data()&channel_mask ) >> _first_bit );
|
||||
}
|
||||
|
||||
void set_unsafe(integer_t value) const {
|
||||
void set_unsafe(integer_t value) const {
|
||||
const BitField channel_mask = static_cast< integer_t >( parent_t::max_val ) << _first_bit;
|
||||
this->set_data((this->get_data() & ~channel_mask) | value<<_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 with 'left bias':
|
||||
// - swap between proxy and anything
|
||||
// - swap between value type and proxy
|
||||
// - swap between proxy and proxy
|
||||
@@ -574,85 +608,26 @@ namespace std {
|
||||
/// \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);
|
||||
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);
|
||||
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);
|
||||
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>
|
||||
@@ -664,9 +639,39 @@ struct is_integral<gil::packed_channel_reference<BitField,FirstBit,NumBits,IsMut
|
||||
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>
|
||||
template <typename BaseChannelValue, typename MinVal, typename MaxVal>
|
||||
struct is_integral<gil::scoped_channel_value<BaseChannelValue,MinVal,MaxVal> > : public is_integral<BaseChannelValue> {};
|
||||
|
||||
}
|
||||
} // namespace boost
|
||||
|
||||
// \brief Determines the fundamental type which may be used, e.g., to cast from larger to smaller channel types.
|
||||
namespace boost { namespace gil {
|
||||
template <typename T>
|
||||
struct base_channel_type_impl { using type = T; };
|
||||
|
||||
template <int N>
|
||||
struct base_channel_type_impl<packed_channel_value<N> >
|
||||
{ using type = typename packed_channel_value<N>::integer_t; };
|
||||
|
||||
template <typename B, int F, int N, bool M>
|
||||
struct base_channel_type_impl<packed_channel_reference<B, F, N, M> >
|
||||
{
|
||||
using type = typename packed_channel_reference<B,F,N,M>::integer_t;
|
||||
};
|
||||
|
||||
template <typename B, int N, bool M>
|
||||
struct base_channel_type_impl<packed_dynamic_channel_reference<B, N, M> >
|
||||
{
|
||||
using type = typename packed_dynamic_channel_reference<B,N,M>::integer_t;
|
||||
};
|
||||
|
||||
template <typename ChannelValue, typename MinV, typename MaxV>
|
||||
struct base_channel_type_impl<scoped_channel_value<ChannelValue, MinV, MaxV> >
|
||||
{ using type = ChannelValue; };
|
||||
|
||||
template <typename T>
|
||||
struct base_channel_type : base_channel_type_impl<typename remove_cv<T>::type > {};
|
||||
|
||||
}} //namespace boost::gil
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,41 +1,25 @@
|
||||
/*
|
||||
Copyright 2005-2007 Adobe Systems Incorporated
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_GIL_CHANNEL_ALGORITHM_HPP
|
||||
#define BOOST_GIL_GIL_CHANNEL_ALGORITHM_HPP
|
||||
|
||||
See http://opensource.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#include <boost/gil/channel.hpp>
|
||||
#include <boost/gil/promote_integral.hpp>
|
||||
#include <boost/gil/typedefs.hpp>
|
||||
|
||||
#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 {
|
||||
#include <limits>
|
||||
|
||||
//#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 boost { namespace gil {
|
||||
|
||||
namespace detail {
|
||||
|
||||
@@ -51,7 +35,7 @@ template <typename SrcChannelV, typename DstChannelV, bool SrcLessThanDst, bool
|
||||
|
||||
|
||||
template <typename UnsignedIntegralChannel>
|
||||
struct unsigned_integral_max_value : public mpl::integral_c<UnsignedIntegralChannel,-1> {};
|
||||
struct unsigned_integral_max_value : public mpl::integral_c<UnsignedIntegralChannel,std::numeric_limits<UnsignedIntegralChannel>::max()> {};
|
||||
|
||||
template <>
|
||||
struct unsigned_integral_max_value<uint8_t> : public mpl::integral_c<uint32_t,0xFF> {};
|
||||
@@ -63,7 +47,9 @@ struct unsigned_integral_max_value<uint32_t> : public mpl::integral_c<uintmax_t,
|
||||
|
||||
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> {};
|
||||
: public mpl::integral_c<typename packed_channel_value<K>::integer_t, (uint64_t(1)<<K)-1> {};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////
|
||||
//// unsigned_integral_num_bits - given an unsigned integral channel type, returns the minimum number of bits needed to represent it
|
||||
@@ -78,33 +64,32 @@ struct unsigned_integral_num_bits<packed_channel_value<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
|
||||
/// // float32_t is a floating point channel with range [0.0f ... 1.0f]
|
||||
/// float32_t src_channel = channel_traits<float32_t>::max_value();
|
||||
/// assert(src_channel == 1);
|
||||
///
|
||||
/// // uint8_t is 8-bit unsigned integral channel (aliased from unsigned char)
|
||||
/// uint8_t dst_channel = channel_convert<uint8_t>(src_channel);
|
||||
/// assert(dst_channel == 255); // max value goes to max value
|
||||
/// \endcode
|
||||
|
||||
|
||||
/**
|
||||
\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
|
||||
@@ -131,11 +116,13 @@ namespace detail {
|
||||
//////////////////////////////////////
|
||||
|
||||
/// \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 {
|
||||
template <typename SrcChannelV, typename DstChannelV, bool SrcIsIntegral, bool DstIsIntegral>
|
||||
struct channel_converter_unsigned_impl {
|
||||
using argument_type = SrcChannelV;
|
||||
using result_type = DstChannelV;
|
||||
DstChannelV operator()(SrcChannelV src) const {
|
||||
return DstChannelV(channel_traits<DstChannelV>::min_value() +
|
||||
(src - channel_traits<SrcChannelV>::min_value()) / channel_range<SrcChannelV>() * channel_range<DstChannelV>());
|
||||
(src - channel_traits<SrcChannelV>::min_value()) / channel_range<SrcChannelV>() * channel_range<DstChannelV>());
|
||||
}
|
||||
private:
|
||||
template <typename C>
|
||||
@@ -145,7 +132,7 @@ private:
|
||||
};
|
||||
|
||||
// When both the source and the destination are integral channels, perform a faster conversion
|
||||
template <typename SrcChannelV, typename DstChannelV>
|
||||
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 > {};
|
||||
@@ -155,12 +142,12 @@ struct channel_converter_unsigned_impl<SrcChannelV,DstChannelV,true,true>
|
||||
//// channel_converter_unsigned_integral
|
||||
//////////////////////////////////////
|
||||
|
||||
template <typename SrcChannelV, typename DstChannelV>
|
||||
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>
|
||||
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) > {};
|
||||
@@ -170,25 +157,25 @@ struct channel_converter_unsigned_integral<SrcChannelV,DstChannelV,false>
|
||||
//// channel_converter_unsigned_integral_impl
|
||||
//////////////////////////////////////
|
||||
|
||||
// Both source and destination are unsigned integral channels,
|
||||
// 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>
|
||||
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;
|
||||
DstChannelV operator()(SrcChannelV src) const {
|
||||
using integer_t = typename unsigned_integral_max_value<DstChannelV>::value_type;
|
||||
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,
|
||||
// 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>
|
||||
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;
|
||||
DstChannelV operator()(SrcChannelV src) const {
|
||||
using integer_t = typename unsigned_integral_max_value<SrcChannelV>::value_type;
|
||||
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);
|
||||
@@ -196,10 +183,10 @@ struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,false,tr
|
||||
};
|
||||
|
||||
// Prevent overflow for the largest integral type
|
||||
template <typename DstChannelV>
|
||||
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;
|
||||
DstChannelV operator()(uintmax_t src) const {
|
||||
static const uintmax_t div = unsigned_integral_max_value<uint32_t>::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;
|
||||
@@ -207,11 +194,11 @@ struct channel_converter_unsigned_integral_impl<uintmax_t,DstChannelV,false,true
|
||||
}
|
||||
};
|
||||
|
||||
// Both source and destination are unsigned integral channels,
|
||||
// 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>
|
||||
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> >,
|
||||
@@ -219,23 +206,23 @@ struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,SrcLessT
|
||||
>::value> {};
|
||||
|
||||
|
||||
// Both source and destination are unsigned integral channels,
|
||||
// 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>
|
||||
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);
|
||||
using dest_t = typename base_channel_type<DstChannelV>::type;
|
||||
return DstChannelV(static_cast<dest_t>( src * unsigned_integral_max_value<DstChannelV>::value) / unsigned_integral_max_value<SrcChannelV>::value);
|
||||
}
|
||||
};
|
||||
|
||||
// Both source and destination are unsigned integral channels,
|
||||
// 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>
|
||||
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);
|
||||
@@ -243,17 +230,17 @@ struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,
|
||||
}
|
||||
};
|
||||
|
||||
// Both source and destination are unsigned integral channels,
|
||||
// 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>
|
||||
template <typename SrcChannelV, typename DstChannelV, bool CannotFit>
|
||||
struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,false,CannotFit> {
|
||||
DstChannelV operator()(SrcChannelV src) const {
|
||||
DstChannelV operator()(SrcChannelV src) const {
|
||||
|
||||
typedef typename detail::unsigned_integral_max_value< SrcChannelV >::value_type src_integer_t;
|
||||
typedef typename detail::unsigned_integral_max_value< DstChannelV >::value_type dst_integer_t;
|
||||
using src_integer_t = typename detail::unsigned_integral_max_value<SrcChannelV>::value_type;
|
||||
using dst_integer_t = typename detail::unsigned_integral_max_value<DstChannelV>::value_type;
|
||||
|
||||
static const double div = unsigned_integral_max_value<SrcChannelV>::value
|
||||
static const double div = unsigned_integral_max_value<SrcChannelV>::value
|
||||
/ static_cast< double >( unsigned_integral_max_value<DstChannelV>::value );
|
||||
|
||||
static const src_integer_t div2 = static_cast< src_integer_t >( div / 2.0 );
|
||||
@@ -265,89 +252,127 @@ struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,
|
||||
} // namespace detail
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/// bits32f conversion
|
||||
/// float32_t conversion
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
template <typename DstChannelV> struct channel_converter_unsigned<bits32f,DstChannelV> : public std::unary_function<bits32f,DstChannelV> {
|
||||
DstChannelV operator()(bits32f x) const
|
||||
template <typename DstChannelV> struct channel_converter_unsigned<float32_t,DstChannelV> {
|
||||
using argument_type = float32_t;
|
||||
using result_type = DstChannelV;
|
||||
DstChannelV operator()(float32_t x) const
|
||||
{
|
||||
typedef typename detail::unsigned_integral_max_value< DstChannelV >::value_type dst_integer_t;
|
||||
using dst_integer_t = typename detail::unsigned_integral_max_value<DstChannelV>::value_type;
|
||||
return DstChannelV( static_cast< dst_integer_t >(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 <typename SrcChannelV> struct channel_converter_unsigned<SrcChannelV,float32_t> {
|
||||
using argument_type = float32_t;
|
||||
using result_type = SrcChannelV;
|
||||
float32_t operator()(SrcChannelV x) const { return float32_t(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; }
|
||||
template <> struct channel_converter_unsigned<float32_t,float32_t> {
|
||||
using argument_type = float32_t;
|
||||
using result_type = float32_t;
|
||||
float32_t operator()(float32_t 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());
|
||||
template <> struct channel_converter_unsigned<uint32_t,float32_t> {
|
||||
using argument_type = uint32_t;
|
||||
using result_type = float32_t;
|
||||
float32_t operator()(uint32_t x) const {
|
||||
// unfortunately without an explicit check it is possible to get a round-off error. We must ensure that max_value of uint32_t matches max_value of float32_t
|
||||
if (x>=channel_traits<uint32_t>::max_value()) return channel_traits<float32_t>::max_value();
|
||||
return float(x) / float(channel_traits<uint32_t>::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);
|
||||
template <> struct channel_converter_unsigned<float32_t,uint32_t> {
|
||||
using argument_type = float32_t;
|
||||
using result_type = uint32_t;
|
||||
uint32_t operator()(float32_t x) const {
|
||||
// unfortunately without an explicit check it is possible to get a round-off error. We must ensure that max_value of uint32_t matches max_value of float32_t
|
||||
if (x>=channel_traits<float32_t>::max_value())
|
||||
return channel_traits<uint32_t>::max_value();
|
||||
|
||||
auto const max_value = channel_traits<uint32_t>::max_value();
|
||||
auto const result = x * static_cast<float32_t::base_channel_t>(max_value) + 0.5f;
|
||||
return static_cast<uint32_t>(result);
|
||||
}
|
||||
};
|
||||
|
||||
/// @}
|
||||
/// @}
|
||||
|
||||
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)
|
||||
// Converting from signed to unsigned integral channel.
|
||||
// It is both a unary function, and a metafunction (thus requires the 'type' nested alias, which equals result_type)
|
||||
template <typename ChannelValue> // Model ChannelValueConcept
|
||||
struct channel_convert_to_unsigned : public detail::identity<ChannelValue> {
|
||||
typedef ChannelValue type;
|
||||
using type = ChannelValue;
|
||||
};
|
||||
|
||||
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<int8_t> {
|
||||
using argument_type = int8_t;
|
||||
using result_type = uint8_t;
|
||||
using type = uint8_t;
|
||||
type operator()(int8_t val) const {
|
||||
return static_cast<uint8_t>(static_cast<uint32_t>(val) + 128u);
|
||||
}
|
||||
};
|
||||
|
||||
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<int16_t> {
|
||||
using argument_type = int16_t;
|
||||
using result_type = uint16_t;
|
||||
using type = uint16_t;
|
||||
type operator()(int16_t val) const {
|
||||
return static_cast<uint16_t>(static_cast<uint32_t>(val) + 32768u);
|
||||
}
|
||||
};
|
||||
|
||||
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)); }
|
||||
template <> struct channel_convert_to_unsigned<int32_t> {
|
||||
using argument_type = int32_t;
|
||||
using result_type = uint32_t;
|
||||
using type = uint32_t;
|
||||
type operator()(int32_t val) const {
|
||||
return static_cast<uint32_t>(val)+(1u<<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)
|
||||
// It is both a unary function, and a metafunction (thus requires the 'type' nested alias, which equals result_type)
|
||||
template <typename ChannelValue> // Model ChannelValueConcept
|
||||
struct channel_convert_from_unsigned : public detail::identity<ChannelValue> {
|
||||
typedef ChannelValue type;
|
||||
using type = ChannelValue;
|
||||
};
|
||||
|
||||
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<int8_t> {
|
||||
using argument_type = uint8_t;
|
||||
using result_type = int8_t;
|
||||
using type = int8_t;
|
||||
type operator()(uint8_t val) const {
|
||||
return static_cast<int8_t>(static_cast<int32_t>(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<int16_t> {
|
||||
using argument_type = uint16_t;
|
||||
using result_type = int16_t;
|
||||
using type = int16_t;
|
||||
type operator()(uint16_t val) const {
|
||||
return static_cast<int16_t>(static_cast<int32_t>(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)); }
|
||||
template <> struct channel_convert_from_unsigned<int32_t> {
|
||||
using argument_type = uint32_t;
|
||||
using result_type = int32_t;
|
||||
using type = int32_t;
|
||||
type operator()(uint32_t val) const {
|
||||
return static_cast<int32_t>(val - (1u<<31));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
@@ -355,25 +380,27 @@ template <> struct channel_convert_from_unsigned<bits32s> : public std::unary_fu
|
||||
/// \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> {
|
||||
struct channel_converter {
|
||||
using argument_type = SrcChannelV;
|
||||
using result_type = DstChannelV;
|
||||
DstChannelV operator()(const 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)));
|
||||
using to_unsigned = detail::channel_convert_to_unsigned<SrcChannelV>;
|
||||
using from_unsigned = detail::channel_convert_from_unsigned<DstChannelV>;
|
||||
using converter_unsigned = channel_converter_unsigned<typename to_unsigned::result_type, typename from_unsigned::argument_type>;
|
||||
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(const SrcChannel& src) {
|
||||
inline typename channel_traits<DstChannel>::value_type channel_convert(const SrcChannel& src) {
|
||||
return channel_converter<typename channel_traits<SrcChannel>::value_type,
|
||||
typename channel_traits<DstChannel>::value_type>()(src);
|
||||
typename channel_traits<DstChannel>::value_type>()(src);
|
||||
}
|
||||
|
||||
/// \ingroup ChannelConvertAlgorithm
|
||||
/// \brief Same as channel_converter, except it takes the destination channel by reference, which allows
|
||||
/// \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 {
|
||||
@@ -391,86 +418,101 @@ namespace detail {
|
||||
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
|
||||
*/
|
||||
/// \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
|
||||
/// uint8_t x=128;
|
||||
/// uint8_t y=128;
|
||||
/// uint8_t 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> {
|
||||
struct channel_multiplier_unsigned {
|
||||
using first_argument_type = ChannelValue;
|
||||
using second_argument_type = ChannelValue;
|
||||
using result_type = ChannelValue;
|
||||
ChannelValue operator()(ChannelValue a, ChannelValue b) const {
|
||||
return ChannelValue(a / double(channel_traits<ChannelValue>::max_value()) * b);
|
||||
return ChannelValue(static_cast<typename base_channel_type<ChannelValue>::type>(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))); }
|
||||
template<> struct channel_multiplier_unsigned<uint8_t> {
|
||||
using first_argument_type = uint8_t;
|
||||
using second_argument_type = uint8_t;
|
||||
using result_type = uint8_t;
|
||||
uint8_t operator()(uint8_t a, uint8_t b) const { return uint8_t(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); }
|
||||
template<> struct channel_multiplier_unsigned<uint16_t> {
|
||||
using first_argument_type = uint16_t;
|
||||
using second_argument_type = uint16_t;
|
||||
using result_type = uint16_t;
|
||||
uint16_t operator()(uint16_t a, uint16_t b) const { return uint16_t((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; }
|
||||
template<> struct channel_multiplier_unsigned<float32_t> {
|
||||
using first_argument_type = float32_t;
|
||||
using second_argument_type = float32_t;
|
||||
using result_type = float32_t;
|
||||
float32_t operator()(float32_t a, float32_t 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> {
|
||||
struct channel_multiplier {
|
||||
using first_argument_type = ChannelValue;
|
||||
using second_argument_type = ChannelValue;
|
||||
using result_type = 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)));
|
||||
using to_unsigned = detail::channel_convert_to_unsigned<ChannelValue>;
|
||||
using from_unsigned = detail::channel_convert_from_unsigned<ChannelValue>;
|
||||
using multiplier_unsigned = channel_multiplier_unsigned<typename to_unsigned::result_type>;
|
||||
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) {
|
||||
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
|
||||
*/
|
||||
/// \defgroup ChannelInvertAlgorithm channel_invert
|
||||
/// \ingroup ChannelAlgorithm
|
||||
/// \brief Returns the inverse of a channel. result = max_value - x + min_value
|
||||
///
|
||||
/// Example:
|
||||
/// \code
|
||||
/// // uint8_t == uint8_t == unsigned char
|
||||
/// uint8_t x=255;
|
||||
/// uint8_t 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();
|
||||
}
|
||||
inline typename channel_traits<Channel>::value_type channel_invert(Channel x) {
|
||||
|
||||
//#ifdef _MSC_VER
|
||||
//#pragma warning(pop)
|
||||
//#endif
|
||||
using base_t = typename base_channel_type<Channel>::type;
|
||||
using promoted_t = typename promote_integral<base_t>::type;
|
||||
promoted_t const promoted_x = x;
|
||||
promoted_t const promoted_max = channel_traits<Channel>::max_value();
|
||||
promoted_t const promoted_min = channel_traits<Channel>::min_value();
|
||||
promoted_t const promoted_inverted_x = promoted_max - promoted_x + promoted_min;
|
||||
auto const inverted_x = static_cast<base_t>(promoted_inverted_x);
|
||||
return inverted_x;
|
||||
}
|
||||
|
||||
} } // namespace boost::gil
|
||||
|
||||
|
||||
@@ -1,64 +1,52 @@
|
||||
/*
|
||||
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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CMYK_HPP
|
||||
#define BOOST_GIL_CMYK_HPP
|
||||
|
||||
See http://opensource.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
#include <boost/gil/metafunctions.hpp>
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#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 {
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \addtogroup ColorNameModel
|
||||
/// \{
|
||||
|
||||
/// \brief Cyan
|
||||
struct cyan_t {};
|
||||
struct cyan_t {};
|
||||
|
||||
/// \brief Magenta
|
||||
struct magenta_t {};
|
||||
|
||||
/// \brief Yellow
|
||||
struct yellow_t {};
|
||||
struct yellow_t {};
|
||||
|
||||
/// \brief Black
|
||||
struct black_t {};
|
||||
/// \}
|
||||
|
||||
/// \ingroup ColorSpaceModel
|
||||
typedef mpl::vector4<cyan_t,magenta_t,yellow_t,black_t> cmyk_t;
|
||||
using cmyk_t = mpl::vector4<cyan_t,magenta_t,yellow_t,black_t>;
|
||||
|
||||
/// \ingroup LayoutModel
|
||||
typedef layout<cmyk_t> cmyk_layout_t;
|
||||
using cmyk_layout_t = layout<cmyk_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));
|
||||
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)
|
||||
{
|
||||
using view_t = typename type_from_x_iterator<planar_pixel_iterator<IC,cmyk_t> >::view_t;
|
||||
return view_t(width, height, typename view_t::locator(planar_pixel_iterator<IC,cmyk_t>(c,m,y,k), rowsize_in_bytes));
|
||||
}
|
||||
|
||||
} } // namespace gil
|
||||
|
||||
@@ -1,37 +1,22 @@
|
||||
/*
|
||||
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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_COLOR_BASE_HPP
|
||||
#define BOOST_GIL_COLOR_BASE_HPP
|
||||
|
||||
See http://stlab.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
#include <boost/gil/utilities.hpp>
|
||||
#include <boost/gil/concepts.hpp>
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#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/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#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 {
|
||||
|
||||
@@ -40,7 +25,14 @@ 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);
|
||||
auto semantic_at_c(ColorBase& p)
|
||||
-> typename std::enable_if
|
||||
<
|
||||
!std::is_const<ColorBase>::value,
|
||||
typename kth_semantic_element_reference_type<ColorBase, K>::type
|
||||
>::type;
|
||||
|
||||
|
||||
template <int K, typename ColorBase>
|
||||
typename kth_semantic_element_const_reference_type<ColorBase,K>::type semantic_at_c(const ColorBase& p);
|
||||
|
||||
@@ -57,16 +49,20 @@ template <typename ColorBase, int K> struct kth_element_const_reference_type<con
|
||||
namespace detail {
|
||||
|
||||
template <typename DstLayout, typename SrcLayout, int K>
|
||||
struct mapping_transform
|
||||
: public mpl::at<typename SrcLayout::channel_mapping_t,
|
||||
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
|
||||
/// \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.
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
/// \brief A homogeneous color base holding one color element. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
|
||||
/// \ingroup ColorBaseModelHomogeneous
|
||||
@@ -75,17 +71,17 @@ struct homogeneous_color_base<Element,Layout,1> {
|
||||
private:
|
||||
Element _v0;
|
||||
public:
|
||||
typedef Layout layout_t;
|
||||
using layout_t = Layout;
|
||||
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)) {}
|
||||
template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,1>& c) : _v0(gil::at_c<0>(c)) {}
|
||||
};
|
||||
|
||||
|
||||
@@ -96,7 +92,7 @@ struct homogeneous_color_base<Element,Layout,2> {
|
||||
private:
|
||||
Element _v0, _v1;
|
||||
public:
|
||||
typedef Layout layout_t;
|
||||
using layout_t = Layout;
|
||||
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; }
|
||||
@@ -106,25 +102,25 @@ public:
|
||||
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)) {}
|
||||
template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,2>& c) :
|
||||
_v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
|
||||
_v1(gil::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)) {}
|
||||
template <typename E2, typename L2> homogeneous_color_base( homogeneous_color_base<E2,L2,2>& c) :
|
||||
_v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
|
||||
_v1(gil::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)),
|
||||
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),
|
||||
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)
|
||||
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)) {}
|
||||
|
||||
@@ -142,7 +138,7 @@ struct homogeneous_color_base<Element,Layout,3> {
|
||||
private:
|
||||
Element _v0, _v1, _v2;
|
||||
public:
|
||||
typedef Layout layout_t;
|
||||
using layout_t = Layout;
|
||||
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; }
|
||||
@@ -154,29 +150,29 @@ public:
|
||||
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(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
|
||||
_v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)),
|
||||
template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,3>& c) :
|
||||
_v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
|
||||
_v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)),
|
||||
_v2(gil::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(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
|
||||
_v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)),
|
||||
template <typename E2, typename L2> homogeneous_color_base( homogeneous_color_base<E2,L2,3>& c) :
|
||||
_v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
|
||||
_v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)),
|
||||
_v2(gil::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)),
|
||||
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),
|
||||
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)
|
||||
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)) {}
|
||||
@@ -198,7 +194,7 @@ struct homogeneous_color_base<Element,Layout,4> {
|
||||
private:
|
||||
Element _v0, _v1, _v2, _v3;
|
||||
public:
|
||||
typedef Layout layout_t;
|
||||
using layout_t = Layout;
|
||||
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; }
|
||||
@@ -212,33 +208,33 @@ public:
|
||||
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)) {}
|
||||
_v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
|
||||
_v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)),
|
||||
_v2(gil::at_c<mapping_transform<Layout,L2,2>::value>(c)),
|
||||
_v3(gil::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)) {}
|
||||
template <typename E2, typename L2> homogeneous_color_base( homogeneous_color_base<E2,L2,4>& c) :
|
||||
_v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
|
||||
_v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)),
|
||||
_v2(gil::at_c<mapping_transform<Layout,L2,2>::value>(c)),
|
||||
_v3(gil::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)),
|
||||
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),
|
||||
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)
|
||||
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)),
|
||||
@@ -262,7 +258,7 @@ struct homogeneous_color_base<Element,Layout,5> {
|
||||
private:
|
||||
Element _v0, _v1, _v2, _v3, _v4;
|
||||
public:
|
||||
typedef Layout layout_t;
|
||||
using layout_t = Layout;
|
||||
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; }
|
||||
@@ -278,37 +274,37 @@ public:
|
||||
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)) {}
|
||||
_v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
|
||||
_v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)),
|
||||
_v2(gil::at_c<mapping_transform<Layout,L2,2>::value>(c)),
|
||||
_v3(gil::at_c<mapping_transform<Layout,L2,3>::value>(c)),
|
||||
_v4(gil::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)) {}
|
||||
template <typename E2, typename L2> homogeneous_color_base( homogeneous_color_base<E2,L2,5>& c) :
|
||||
_v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
|
||||
_v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)),
|
||||
_v2(gil::at_c<mapping_transform<Layout,L2,2>::value>(c)),
|
||||
_v3(gil::at_c<mapping_transform<Layout,L2,3>::value>(c)),
|
||||
_v4(gil::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)),
|
||||
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),
|
||||
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)
|
||||
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)),
|
||||
@@ -327,6 +323,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// 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.
|
||||
@@ -338,45 +338,46 @@ public:
|
||||
// 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);
|
||||
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)
|
||||
{
|
||||
BOOST_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
|
||||
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);
|
||||
BOOST_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
|
||||
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);
|
||||
BOOST_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
|
||||
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);
|
||||
BOOST_ASSERT(i < K);
|
||||
return cb.at_c_dynamic(i);
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Element, typename Layout, int K1, int K>
|
||||
template <typename Element, typename Layout, int K1, int K>
|
||||
struct kth_element_type<detail::homogeneous_color_base<Element,Layout,K1>, K> {
|
||||
typedef Element type;
|
||||
using type = Element;
|
||||
};
|
||||
|
||||
template <typename Element, typename Layout, int K1, int K>
|
||||
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>
|
||||
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
|
||||
@@ -400,7 +401,7 @@ namespace detail {
|
||||
};
|
||||
}
|
||||
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) {
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,39 +1,27 @@
|
||||
/*
|
||||
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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_COLOR_BASE_ALGORITHM_HPP
|
||||
#define BOOST_GIL_COLOR_BASE_ALGORITHM_HPP
|
||||
|
||||
See http://opensource.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
#include <boost/gil/concepts.hpp>
|
||||
#include <boost/gil/utilities.hpp>
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#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 <boost/config.hpp>
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/mpl/contains.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#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"
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
///
|
||||
/// size: Semantic channel size
|
||||
@@ -47,8 +35,8 @@ namespace boost { namespace gil {
|
||||
|
||||
Example:
|
||||
\code
|
||||
BOOST_STATIC_ASSERT((size<rgb8_pixel_t>::value == 3));
|
||||
BOOST_STATIC_ASSERT((size<cmyk8_planar_ptr_t>::value == 4));
|
||||
static_assert(size<rgb8_pixel_t>::value == 3, "");
|
||||
static_assert(size<cmyk8_planar_ptr_t>::value == 4, "");
|
||||
\endcode
|
||||
*/
|
||||
|
||||
@@ -75,57 +63,80 @@ All GIL color base algorithms taking multiple color bases use semantic indexing
|
||||
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;
|
||||
using bgr432_pixel_t = packed_pixel_type<uint16_t, mpl::vector3_c<unsigned,4,3,2>, bgr_layout_t>::type;
|
||||
|
||||
// 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;
|
||||
using red_channel_reference_t = kth_semantic_element_reference_type<bgr432_pixel_t, 0>::type;
|
||||
|
||||
// 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();
|
||||
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;
|
||||
template <typename ColorBase, int K>
|
||||
struct kth_semantic_element_type
|
||||
{
|
||||
using channel_mapping_t = typename ColorBase::layout_t::channel_mapping_t;
|
||||
static_assert(K < mpl::size<channel_mapping_t>::value,
|
||||
"K index should be less than size of channel_mapping_t sequence");
|
||||
|
||||
static constexpr int semantic_index = mpl::at_c<channel_mapping_t, K>::type::value;
|
||||
using type = typename kth_element_type<ColorBase, semantic_index>::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 gil::at_c<semantic_index>(cb); }
|
||||
template <typename ColorBase, int K>
|
||||
struct kth_semantic_element_reference_type
|
||||
{
|
||||
using channel_mapping_t = typename ColorBase::layout_t::channel_mapping_t;
|
||||
static_assert(K < mpl::size<channel_mapping_t>::value,
|
||||
"K index should be less than size of channel_mapping_t sequence");
|
||||
|
||||
static constexpr int semantic_index = mpl::at_c<channel_mapping_t, K>::type::value;
|
||||
using type = typename kth_element_reference_type<ColorBase, semantic_index>::type;
|
||||
static type get(ColorBase& cb) { return gil::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 gil::at_c<semantic_index>(cb); }
|
||||
template <typename ColorBase, int K> struct kth_semantic_element_const_reference_type
|
||||
{
|
||||
using channel_mapping_t = typename ColorBase::layout_t::channel_mapping_t;
|
||||
static_assert(K < mpl::size<channel_mapping_t>::value,
|
||||
"K index should be less than size of channel_mapping_t sequence");
|
||||
|
||||
static constexpr int semantic_index = mpl::at_c<channel_mapping_t, K>::type::value;
|
||||
using type = typename kth_element_const_reference_type<ColorBase,semantic_index>::type;
|
||||
static type get(const ColorBase& cb) { return gil::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);
|
||||
template <int K, typename ColorBase>
|
||||
inline
|
||||
auto semantic_at_c(ColorBase& p)
|
||||
-> typename std::enable_if
|
||||
<
|
||||
!std::is_const<ColorBase>::value,
|
||||
typename kth_semantic_element_reference_type<ColorBase, K>::type
|
||||
>::type
|
||||
{
|
||||
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);
|
||||
semantic_at_c(const ColorBase& p) {
|
||||
return kth_semantic_element_const_reference_type<ColorBase,K>::get(p);
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
@@ -145,10 +156,10 @@ Example: A function that takes a generic pixel containing a red channel and sets
|
||||
template <typename Pixel>
|
||||
void set_red_to_max(Pixel& pixel) {
|
||||
boost::function_requires<MutablePixelConcept<Pixel> >();
|
||||
BOOST_STATIC_ASSERT((contains_color<Pixel, red_t>::value));
|
||||
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();
|
||||
using red_channel_t = typename color_element_type<Pixel, red_t>::type;
|
||||
get_color(pixel, red_t()) = channel_traits<red_channel_t>::max_value();
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
@@ -178,14 +189,14 @@ struct color_element_const_reference_type : public kth_semantic_element_const_re
|
||||
|
||||
/// \brief Mutable accessor to the element associated with a given color name
|
||||
/// \ingroup ColorBaseAlgorithmColor
|
||||
template <typename ColorBase, typename Color>
|
||||
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>
|
||||
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);
|
||||
}
|
||||
@@ -203,8 +214,8 @@ typename color_element_const_reference_type<ColorBase,Color>::type get_color(con
|
||||
|
||||
Example:
|
||||
\code
|
||||
typedef element_type<rgb8c_planar_ptr_t>::type element_t;
|
||||
BOOST_STATIC_ASSERT((boost::is_same<element_t, const bits8*>::value));
|
||||
using element_t = element_type<rgb8c_planar_ptr_t>::type;
|
||||
static_assert(std::is_same<element_t, const uint8_t*>::value, "");
|
||||
\endcode
|
||||
*/
|
||||
/// \brief Specifies the element type of a homogeneous color base
|
||||
@@ -227,64 +238,80 @@ namespace detail {
|
||||
|
||||
// compile-time recursion for per-element operations on color bases
|
||||
template <int N>
|
||||
struct element_recursion {
|
||||
//static_equal
|
||||
struct element_recursion
|
||||
{
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
#endif
|
||||
|
||||
template <typename P1,typename P2>
|
||||
static bool static_equal(const P1& p1, const P2& 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);
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
//static_for_each with one source
|
||||
template <typename P1,typename Op>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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));
|
||||
@@ -340,13 +367,13 @@ struct element_recursion {
|
||||
return op2;
|
||||
}
|
||||
//static_transform with one source
|
||||
template <typename P1,typename Dst,typename Op>
|
||||
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>
|
||||
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));
|
||||
@@ -422,16 +449,16 @@ 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
|
||||
@@ -444,250 +471,236 @@ struct min_max_recur<1> {
|
||||
};
|
||||
} // 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
|
||||
\{
|
||||
*/
|
||||
/// \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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
\{
|
||||
*/
|
||||
/// \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
|
||||
BOOST_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
|
||||
\{
|
||||
*/
|
||||
/// \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
|
||||
BOOST_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.
|
||||
/// \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
|
||||
/// \{
|
||||
|
||||
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
|
||||
BOOST_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
|
||||
|
||||
\{
|
||||
*/
|
||||
/// \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
|
||||
BOOST_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
|
||||
\{
|
||||
*/
|
||||
/// \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) {
|
||||
/// using result_channel_t = typename channel_type<Pixel3>::type;
|
||||
/// 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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
\{
|
||||
*/
|
||||
/// \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());
|
||||
/// }
|
||||
///
|
||||
/// uint8_t 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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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
|
||||
BOOST_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); }
|
||||
///\}
|
||||
|
||||
|
||||
@@ -1,53 +1,41 @@
|
||||
/*
|
||||
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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_COLOR_CONVERT_HPP
|
||||
#define BOOST_GIL_COLOR_CONVERT_HPP
|
||||
|
||||
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 <boost/gil/channel_algorithm.hpp>
|
||||
#include <boost/gil/cmyk.hpp>
|
||||
#include <boost/gil/color_base_algorithm.hpp>
|
||||
#include <boost/gil/gray.hpp>
|
||||
#include <boost/gil/metafunctions.hpp>
|
||||
#include <boost/gil/pixel.hpp>
|
||||
#include <boost/gil/rgb.hpp>
|
||||
#include <boost/gil/rgba.hpp>
|
||||
#include <boost/gil/utilities.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#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 {
|
||||
|
||||
/// Support for fast and simple color conversion.
|
||||
/// Accurate color conversion using color profiles can be supplied separately in a dedicated module.
|
||||
|
||||
// Forward-declare
|
||||
template <typename P> struct channel_type;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
///
|
||||
/// COLOR SPACE CONVERSION
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// \ingroup ColorConvert
|
||||
/// \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 {};
|
||||
@@ -70,10 +58,10 @@ namespace detail {
|
||||
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) );
|
||||
return channel_convert<GrayChannelValue>(float32_t(
|
||||
channel_convert<float32_t>(red )*0.30f +
|
||||
channel_convert<float32_t>(green)*0.59f +
|
||||
channel_convert<float32_t>(blue )*0.11f) );
|
||||
}
|
||||
};
|
||||
|
||||
@@ -132,7 +120,7 @@ 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()) =
|
||||
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())
|
||||
);
|
||||
@@ -151,7 +139,7 @@ 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;
|
||||
using T2 = typename channel_type<P2>::type;
|
||||
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
|
||||
@@ -180,22 +168,22 @@ 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;
|
||||
using T1 = typename channel_type<P1>::type;
|
||||
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())))));
|
||||
(std::min)(channel_traits<T1>::max_value(),
|
||||
T1(channel_multiply(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())))));
|
||||
(std::min)(channel_traits<T1>::max_value(),
|
||||
T1(channel_multiply(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())))));
|
||||
(std::min)(channel_traits<T1>::max_value(),
|
||||
T1(channel_multiply(get_color(src,yellow_t()),channel_invert(get_color(src,black_t())))+get_color(src,black_t())))));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -209,32 +197,32 @@ 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_convert<typename color_element_type<P2,gray_color_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,cyan_t()),
|
||||
get_color(src,magenta_t()),
|
||||
get_color(src,yellow_t())
|
||||
)
|
||||
),
|
||||
),
|
||||
channel_invert(get_color(src,black_t()))));
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template <typename Pixel>
|
||||
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>
|
||||
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>
|
||||
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>());
|
||||
}
|
||||
@@ -246,7 +234,7 @@ 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;
|
||||
using T2 = typename channel_type<P2>::type;
|
||||
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());
|
||||
@@ -260,16 +248,16 @@ struct default_color_converter_impl<C1,rgba_t> {
|
||||
/// \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.
|
||||
/// 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;
|
||||
using T1 = typename channel_type<P1>::type;
|
||||
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())),
|
||||
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);
|
||||
}
|
||||
@@ -293,9 +281,9 @@ struct default_color_converter_impl<rgba_t,rgba_t> {
|
||||
/// \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;
|
||||
void operator()(const SrcP& src,DstP& dst) const {
|
||||
using SrcColorSpace = typename color_space_type<SrcP>::type;
|
||||
using DstColorSpace = typename color_space_type<DstP>::type;
|
||||
default_color_converter_impl<SrcColorSpace,DstColorSpace>()(src,dst);
|
||||
}
|
||||
};
|
||||
|
||||
26
linx64/include/boost/gil/concepts.hpp
Normal file
26
linx64/include/boost/gil/concepts.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_HPP
|
||||
#define BOOST_GIL_CONCEPTS_HPP
|
||||
|
||||
// TODO: Remove and prefer individual includes from boost/gil/concepts/*.hpp?
|
||||
|
||||
#include <boost/gil/concepts/channel.hpp>
|
||||
#include <boost/gil/concepts/color.hpp>
|
||||
#include <boost/gil/concepts/color_base.hpp>
|
||||
#include <boost/gil/concepts/concept_check.hpp>
|
||||
#include <boost/gil/concepts/image.hpp>
|
||||
#include <boost/gil/concepts/image_view.hpp>
|
||||
#include <boost/gil/concepts/pixel.hpp>
|
||||
#include <boost/gil/concepts/pixel_based.hpp>
|
||||
#include <boost/gil/concepts/pixel_dereference.hpp>
|
||||
#include <boost/gil/concepts/pixel_iterator.hpp>
|
||||
#include <boost/gil/concepts/pixel_locator.hpp>
|
||||
#include <boost/gil/concepts/point.hpp>
|
||||
|
||||
#endif
|
||||
195
linx64/include/boost/gil/concepts/basic.hpp
Normal file
195
linx64/include/boost/gil/concepts/basic.hpp
Normal file
@@ -0,0 +1,195 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_BASIC_HPP
|
||||
#define BOOST_GIL_CONCEPTS_BASIC_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
|
||||
#pragma clang diagnostic ignored "-Wuninitialized"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#pragma GCC diagnostic ignored "-Wuninitialized"
|
||||
#endif
|
||||
|
||||
#include <boost/gil/concepts/concept_check.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility> // std::swap
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \brief Concept of default construction requirement.
|
||||
/// \code
|
||||
/// auto concept DefaultConstructible<typename T>
|
||||
/// {
|
||||
/// T::T();
|
||||
/// };
|
||||
/// \endcode
|
||||
/// \ingroup BasicConcepts
|
||||
///
|
||||
template <typename T>
|
||||
struct DefaultConstructible
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
function_requires<boost::DefaultConstructibleConcept<T>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Concept of copy construction requirement.
|
||||
/// \code
|
||||
/// auto concept CopyConstructible<typename T>
|
||||
/// {
|
||||
/// T::T(T);
|
||||
/// T::~T();
|
||||
/// };
|
||||
/// \endcode
|
||||
/// \ingroup BasicConcepts
|
||||
///
|
||||
template <typename T>
|
||||
struct CopyConstructible
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
function_requires<boost::CopyConstructibleConcept<T>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Concept of copy assignment requirement.
|
||||
/// \code
|
||||
/// auto concept Assignable<typename T, typename U = T>
|
||||
/// {
|
||||
/// typename result_type;
|
||||
/// result_type operator=(T&, U);
|
||||
/// };
|
||||
/// \endcode
|
||||
/// \ingroup BasicConcepts
|
||||
///
|
||||
template <typename T>
|
||||
struct Assignable
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
function_requires<boost::AssignableConcept<T>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Concept of == and != comparability requirement.
|
||||
/// \code
|
||||
/// auto concept EqualityComparable<typename T, typename U = T>
|
||||
/// {
|
||||
/// bool operator==(T x, T y);
|
||||
/// bool operator!=(T x, T y) { return !(x==y); }
|
||||
/// };
|
||||
/// \endcode
|
||||
/// \ingroup BasicConcepts
|
||||
///
|
||||
template <typename T>
|
||||
struct EqualityComparable
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
function_requires<boost::EqualityComparableConcept<T>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Concept of swap operation requirement.
|
||||
/// \code
|
||||
/// auto concept Swappable<typename T>
|
||||
/// {
|
||||
/// void swap(T&,T&);
|
||||
/// };
|
||||
/// \endcode
|
||||
/// \ingroup BasicConcepts
|
||||
///
|
||||
template <typename T>
|
||||
struct Swappable
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
using std::swap;
|
||||
swap(x,y);
|
||||
}
|
||||
T x,y;
|
||||
};
|
||||
|
||||
/// \brief Concept for type regularity requirement.
|
||||
/// \code
|
||||
/// auto concept Regular<typename T>
|
||||
/// : DefaultConstructible<T>
|
||||
/// , CopyConstructible<T>
|
||||
/// , EqualityComparable<T>
|
||||
/// , Assignable<T>
|
||||
/// , Swappable<T>
|
||||
/// {};
|
||||
/// \endcode
|
||||
/// \ingroup BasicConcepts
|
||||
///
|
||||
template <typename T>
|
||||
struct Regular
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires< boost::DefaultConstructibleConcept<T>>();
|
||||
gil_function_requires< boost::CopyConstructibleConcept<T>>();
|
||||
gil_function_requires< boost::EqualityComparableConcept<T>>(); // ==, !=
|
||||
gil_function_requires< boost::AssignableConcept<T>>();
|
||||
gil_function_requires< Swappable<T>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Concept for type as metafunction requirement.
|
||||
/// \code
|
||||
/// auto concept Metafunction<typename T>
|
||||
/// {
|
||||
/// typename type;
|
||||
/// };
|
||||
/// \endcode
|
||||
/// \ingroup BasicConcepts
|
||||
///
|
||||
template <typename T>
|
||||
struct Metafunction
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
using type = typename T::type;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Concept of types equivalence requirement.
|
||||
/// \code
|
||||
/// auto concept SameType<typename T, typename U>; // unspecified
|
||||
/// \endcode
|
||||
/// \ingroup BasicConcepts
|
||||
///
|
||||
template <typename T, typename U>
|
||||
struct SameType
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
static_assert(std::is_same<T, U>::value, "");
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
214
linx64/include/boost/gil/concepts/channel.hpp
Normal file
214
linx64/include/boost/gil/concepts/channel.hpp
Normal file
@@ -0,0 +1,214 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_CHANNEL_HPP
|
||||
#define BOOST_GIL_CONCEPTS_CHANNEL_HPP
|
||||
|
||||
#include <boost/gil/concepts/basic.hpp>
|
||||
#include <boost/gil/concepts/concept_check.hpp>
|
||||
#include <boost/gil/concepts/fwd.hpp>
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
|
||||
#include <utility> // std::swap
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
// Forward declarations
|
||||
template <typename T>
|
||||
struct channel_traits;
|
||||
|
||||
template <typename DstT, typename SrcT>
|
||||
auto channel_convert(SrcT const& val)
|
||||
-> typename channel_traits<DstT>::value_type;
|
||||
|
||||
/// \ingroup ChannelConcept
|
||||
/// \brief A channel is the building block of a color.
|
||||
/// Color is defined as a mixture of primary colors and a channel defines
|
||||
/// the degree to which each primary color is used in the mixture.
|
||||
///
|
||||
/// For example, in the RGB color space, using 8-bit unsigned channels,
|
||||
/// the color red is defined as [255 0 0], which means maximum of Red,
|
||||
/// and no Green and Blue.
|
||||
///
|
||||
/// Built-in scalar types, such as \p int and \p float, are valid GIL channels.
|
||||
/// In more complex scenarios, channels may be represented as bit ranges or
|
||||
/// even individual bits.
|
||||
/// In such cases special classes are needed to represent the value and
|
||||
/// reference to a channel.
|
||||
///
|
||||
/// Channels have a traits class, \p channel_traits, which defines their
|
||||
/// associated types as well as their operating ranges.
|
||||
///
|
||||
/// \code
|
||||
/// concept ChannelConcept<typename T> : EqualityComparable<T>
|
||||
/// {
|
||||
/// typename value_type = T; // use channel_traits<T>::value_type to access it
|
||||
/// typename reference = T&; // use channel_traits<T>::reference to access it
|
||||
/// typename pointer = T*; // use channel_traits<T>::pointer to access it
|
||||
/// typename const_reference = const T&; // use channel_traits<T>::const_reference to access it
|
||||
/// typename const_pointer = const T*; // use channel_traits<T>::const_pointer to access it
|
||||
/// static const bool is_mutable; // use channel_traits<T>::is_mutable to access it
|
||||
///
|
||||
/// static T min_value(); // use channel_traits<T>::min_value to access it
|
||||
/// static T max_value(); // use channel_traits<T>::min_value to access it
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename T>
|
||||
struct ChannelConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<boost::EqualityComparableConcept<T>>();
|
||||
|
||||
using v = typename channel_traits<T>::value_type;
|
||||
using r = typename channel_traits<T>::reference;
|
||||
using p = typename channel_traits<T>::pointer;
|
||||
using cr = typename channel_traits<T>::const_reference;
|
||||
using cp = typename channel_traits<T>::const_pointer;
|
||||
|
||||
channel_traits<T>::min_value();
|
||||
channel_traits<T>::max_value();
|
||||
}
|
||||
|
||||
T c;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
/// \tparam T models ChannelConcept
|
||||
template <typename T>
|
||||
struct ChannelIsMutableConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
c1 = c2;
|
||||
using std::swap;
|
||||
swap(c1, c2);
|
||||
}
|
||||
T c1;
|
||||
T c2;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \brief A channel that allows for modifying its value
|
||||
/// \code
|
||||
/// concept MutableChannelConcept<ChannelConcept T> : Assignable<T>, Swappable<T> {};
|
||||
/// \endcode
|
||||
/// \ingroup ChannelConcept
|
||||
template <typename T>
|
||||
struct MutableChannelConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<ChannelConcept<T>>();
|
||||
gil_function_requires<detail::ChannelIsMutableConcept<T>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A channel that supports default construction.
|
||||
/// \code
|
||||
/// concept ChannelValueConcept<ChannelConcept T> : Regular<T> {};
|
||||
/// \endcode
|
||||
/// \ingroup ChannelConcept
|
||||
template <typename T>
|
||||
struct ChannelValueConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<ChannelConcept<T>>();
|
||||
gil_function_requires<Regular<T>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Predicate metafunction returning whether two channels are compatible
|
||||
///
|
||||
/// Channels are considered compatible if their value types
|
||||
/// (ignoring constness and references) are the same.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// \code
|
||||
/// static_assert(channels_are_compatible<uint8_t, const uint8_t&>::value, "");
|
||||
/// \endcode
|
||||
/// \ingroup ChannelAlgorithm
|
||||
template <typename T1, typename T2> // Models GIL Pixel
|
||||
struct channels_are_compatible
|
||||
: is_same
|
||||
<
|
||||
typename channel_traits<T1>::value_type,
|
||||
typename channel_traits<T2>::value_type
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
/// \brief Channels are compatible if their associated value types (ignoring constness and references) are the same
|
||||
///
|
||||
/// \code
|
||||
/// concept ChannelsCompatibleConcept<ChannelConcept T1, ChannelConcept T2>
|
||||
/// {
|
||||
/// where SameType<T1::value_type, T2::value_type>;
|
||||
/// };
|
||||
/// \endcode
|
||||
/// \ingroup ChannelConcept
|
||||
template <typename Channel1, typename Channel2>
|
||||
struct ChannelsCompatibleConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
static_assert(channels_are_compatible<Channel1, Channel2>::value, "");
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A channel is convertible to another one if the \p channel_convert algorithm is defined for the two channels.
|
||||
///
|
||||
/// Convertibility is non-symmetric and implies that one channel can be
|
||||
/// converted to another. Conversion is explicit and often lossy operation.
|
||||
///
|
||||
/// concept ChannelConvertibleConcept<ChannelConcept SrcChannel, ChannelValueConcept DstChannel>
|
||||
/// {
|
||||
/// DstChannel channel_convert(const SrcChannel&);
|
||||
/// };
|
||||
/// \endcode
|
||||
/// \ingroup ChannelConcept
|
||||
template <typename SrcChannel, typename DstChannel>
|
||||
struct ChannelConvertibleConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<ChannelConcept<SrcChannel>>();
|
||||
gil_function_requires<MutableChannelConcept<DstChannel>>();
|
||||
dst = channel_convert<DstChannel, SrcChannel>(src);
|
||||
ignore_unused_variable_warning(dst);
|
||||
}
|
||||
SrcChannel src;
|
||||
DstChannel dst;
|
||||
};
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
100
linx64/include/boost/gil/concepts/color.hpp
Normal file
100
linx64/include/boost/gil/concepts/color.hpp
Normal file
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_COLOR_HPP
|
||||
#define BOOST_GIL_CONCEPTS_COLOR_HPP
|
||||
|
||||
#include <boost/gil/concepts/concept_check.hpp>
|
||||
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \ingroup ColorSpaceAndLayoutConcept
|
||||
/// \brief Color space type concept
|
||||
/// \code
|
||||
/// concept ColorSpaceConcept<MPLRandomAccessSequence CS>
|
||||
/// {
|
||||
/// // An MPL Random Access Sequence, whose elements are color tags
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename CS>
|
||||
struct ColorSpaceConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
// An MPL Random Access Sequence, whose elements are color tags
|
||||
|
||||
// TODO: Is this incomplete?
|
||||
}
|
||||
};
|
||||
|
||||
// Models ColorSpaceConcept
|
||||
template <typename CS1, typename CS2>
|
||||
struct color_spaces_are_compatible : is_same<CS1, CS2>
|
||||
{
|
||||
};
|
||||
|
||||
/// \ingroup ColorSpaceAndLayoutConcept
|
||||
/// \brief Two color spaces are compatible if they are the same
|
||||
/// \code
|
||||
/// concept ColorSpacesCompatibleConcept<ColorSpaceConcept CS1, ColorSpaceConcept CS2>
|
||||
/// {
|
||||
/// where SameType<CS1, CS2>;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename CS1, typename CS2>
|
||||
struct ColorSpacesCompatibleConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
static_assert(color_spaces_are_compatible<CS1, CS2>::value, "");
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup ColorSpaceAndLayoutConcept
|
||||
/// \brief Channel mapping concept
|
||||
/// \code
|
||||
/// concept ChannelMappingConcept<MPLRandomAccessSequence CM>
|
||||
/// {
|
||||
/// // An MPL Random Access Sequence, whose elements
|
||||
/// // model MPLIntegralConstant representing a permutation
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename CM>
|
||||
struct ChannelMappingConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
// An MPL Random Access Sequence, whose elements model
|
||||
// MPLIntegralConstant representing a permutation.
|
||||
|
||||
// TODO: Is this incomplete?
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
325
linx64/include/boost/gil/concepts/color_base.hpp
Normal file
325
linx64/include/boost/gil/concepts/color_base.hpp
Normal file
@@ -0,0 +1,325 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_COLOR_BASE_HPP
|
||||
#define BOOST_GIL_CONCEPTS_COLOR_BASE_HPP
|
||||
|
||||
#include <boost/gil/concepts/basic.hpp>
|
||||
#include <boost/gil/concepts/color.hpp>
|
||||
#include <boost/gil/concepts/concept_check.hpp>
|
||||
#include <boost/gil/concepts/fwd.hpp>
|
||||
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
// Forward declarations of at_c
|
||||
namespace detail {
|
||||
|
||||
template <typename Element, typename Layout, int K>
|
||||
struct homogeneous_color_base;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <int K, typename E, typename L, int N>
|
||||
auto at_c(detail::homogeneous_color_base<E, L, N>& p)
|
||||
-> typename add_reference<E>::type;
|
||||
|
||||
template <int K, typename E, typename L, int N>
|
||||
auto at_c(detail::homogeneous_color_base<E, L, N> const& p)
|
||||
-> typename add_reference<typename add_const<E>::type>::type;
|
||||
|
||||
template <typename P, typename C, typename L>
|
||||
struct packed_pixel;
|
||||
|
||||
template <int K, typename P, typename C, typename L>
|
||||
auto at_c(packed_pixel<P, C, L>& p)
|
||||
-> typename kth_element_reference_type<packed_pixel<P, C, L>, K>::type;
|
||||
|
||||
template <int K, typename P, typename C, typename L>
|
||||
auto at_c(packed_pixel<P, C, L> const& p)
|
||||
-> typename kth_element_const_reference_type<packed_pixel<P, C, L>, K>::type;
|
||||
|
||||
template <typename B, typename C, typename L, bool M>
|
||||
struct bit_aligned_pixel_reference;
|
||||
|
||||
template <int K, typename B, typename C, typename L, bool M>
|
||||
inline auto at_c(bit_aligned_pixel_reference<B, C, L, M> const& p)
|
||||
-> typename kth_element_reference_type
|
||||
<
|
||||
bit_aligned_pixel_reference<B, C, L, M>,
|
||||
K
|
||||
>::type;
|
||||
|
||||
// Forward declarations of semantic_at_c
|
||||
template <int K, typename ColorBase>
|
||||
auto semantic_at_c(ColorBase& p)
|
||||
-> typename std::enable_if
|
||||
<
|
||||
!std::is_const<ColorBase>::value,
|
||||
typename kth_semantic_element_reference_type<ColorBase, K>::type
|
||||
>::type;
|
||||
|
||||
template <int K, typename ColorBase>
|
||||
auto semantic_at_c(ColorBase const& p)
|
||||
-> typename kth_semantic_element_const_reference_type<ColorBase, K>::type;
|
||||
|
||||
/// \ingroup ColorBaseConcept
|
||||
/// \brief A color base is a container of color elements (such as channels, channel references or channel pointers).
|
||||
///
|
||||
/// The most common use of color base is in the implementation of a pixel,
|
||||
/// in which case the color elements are channel values. The color base concept,
|
||||
/// however, can be used in other scenarios. For example, a planar pixel has
|
||||
/// channels that are not contiguous in memory. Its reference is a proxy class
|
||||
/// that uses a color base whose elements are channel references. Its iterator
|
||||
/// uses a color base whose elements are channel iterators.
|
||||
///
|
||||
/// A color base must have an associated layout (which consists of a color space,
|
||||
/// as well as an ordering of the channels).
|
||||
/// There are two ways to index the elements of a color base: A physical index
|
||||
/// corresponds to the way they are ordered in memory, and a semantic index
|
||||
/// corresponds to the way the elements are ordered in their color space.
|
||||
/// For example, in the RGB color space the elements are ordered as
|
||||
/// {red_t, green_t, blue_t}. For a color base with a BGR layout, the first element
|
||||
/// in physical ordering is the blue element, whereas the first semantic element
|
||||
/// is the red one.
|
||||
/// Models of \p ColorBaseConcept are required to provide the \p at_c<K>(ColorBase)
|
||||
/// function, which allows for accessing the elements based on their physical order.
|
||||
/// GIL provides a \p semantic_at_c<K>(ColorBase) function (described later)
|
||||
/// which can operate on any model of ColorBaseConcept and returns the corresponding
|
||||
/// semantic element.
|
||||
///
|
||||
/// \code
|
||||
/// concept ColorBaseConcept<typename T> : CopyConstructible<T>, EqualityComparable<T>
|
||||
/// {
|
||||
/// // a GIL layout (the color space and element permutation)
|
||||
/// typename layout_t;
|
||||
///
|
||||
/// // The type of K-th element
|
||||
/// template <int K>
|
||||
/// struct kth_element_type;
|
||||
/// where Metafunction<kth_element_type>;
|
||||
///
|
||||
/// // The result of at_c
|
||||
/// template <int K>
|
||||
/// struct kth_element_const_reference_type;
|
||||
/// where Metafunction<kth_element_const_reference_type>;
|
||||
///
|
||||
/// template <int K>
|
||||
/// kth_element_const_reference_type<T,K>::type at_c(T);
|
||||
///
|
||||
/// // Copy-constructible and equality comparable with other compatible color bases
|
||||
/// template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
|
||||
/// T::T(T2);
|
||||
/// template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
|
||||
/// bool operator==(const T&, const T2&);
|
||||
/// template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
|
||||
/// bool operator!=(const T&, const T2&);
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename ColorBase>
|
||||
struct ColorBaseConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<CopyConstructible<ColorBase>>();
|
||||
gil_function_requires<EqualityComparable<ColorBase>>();
|
||||
|
||||
using color_space_t = typename ColorBase::layout_t::color_space_t;
|
||||
gil_function_requires<ColorSpaceConcept<color_space_t>>();
|
||||
|
||||
using channel_mapping_t = typename ColorBase::layout_t::channel_mapping_t;
|
||||
// TODO: channel_mapping_t must be an MPL RandomAccessSequence
|
||||
|
||||
static const int num_elements = size<ColorBase>::value;
|
||||
|
||||
using TN = typename kth_element_type<ColorBase, num_elements - 1>::type;
|
||||
using RN = typename kth_element_const_reference_type<ColorBase, num_elements - 1>::type;
|
||||
|
||||
RN r = gil::at_c<num_elements - 1>(cb);
|
||||
ignore_unused_variable_warning(r);
|
||||
|
||||
// functions that work for every pixel (no need to require them)
|
||||
semantic_at_c<0>(cb);
|
||||
semantic_at_c<num_elements-1>(cb);
|
||||
// also static_max(cb), static_min(cb), static_fill(cb,value),
|
||||
// and all variations of static_for_each(), static_generate(), static_transform()
|
||||
}
|
||||
ColorBase cb;
|
||||
};
|
||||
|
||||
/// \ingroup ColorBaseConcept
|
||||
/// \brief Color base which allows for modifying its elements
|
||||
/// \code
|
||||
/// concept MutableColorBaseConcept<ColorBaseConcept T> : Assignable<T>, Swappable<T>
|
||||
/// {
|
||||
/// template <int K>
|
||||
/// struct kth_element_reference_type; where Metafunction<kth_element_reference_type>;
|
||||
///
|
||||
/// template <int K>
|
||||
/// kth_element_reference_type<kth_element_type<T,K>::type>::type at_c(T);
|
||||
///
|
||||
/// template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
|
||||
/// T& operator=(T&, const T2&);
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename ColorBase>
|
||||
struct MutableColorBaseConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<ColorBaseConcept<ColorBase>>();
|
||||
gil_function_requires<Assignable<ColorBase>>();
|
||||
gil_function_requires<Swappable<ColorBase>>();
|
||||
|
||||
using R0 = typename kth_element_reference_type<ColorBase, 0>::type;
|
||||
|
||||
R0 r = gil::at_c<0>(cb);
|
||||
gil::at_c<0>(cb) = r;
|
||||
}
|
||||
ColorBase cb;
|
||||
};
|
||||
|
||||
/// \ingroup ColorBaseConcept
|
||||
/// \brief Color base that also has a default-constructor. Refines Regular
|
||||
/// \code
|
||||
/// concept ColorBaseValueConcept<typename T> : MutableColorBaseConcept<T>, Regular<T>
|
||||
/// {
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename ColorBase>
|
||||
struct ColorBaseValueConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<MutableColorBaseConcept<ColorBase>>();
|
||||
gil_function_requires<Regular<ColorBase>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup ColorBaseConcept
|
||||
/// \brief Color base whose elements all have the same type
|
||||
/// \code
|
||||
/// concept HomogeneousColorBaseConcept<ColorBaseConcept CB>
|
||||
/// {
|
||||
/// // For all K in [0 ... size<C1>::value-1):
|
||||
/// // where SameType<kth_element_type<CB,K>::type, kth_element_type<CB,K+1>::type>;
|
||||
/// kth_element_const_reference_type<CB,0>::type dynamic_at_c(CB const&, std::size_t n) const;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename ColorBase>
|
||||
struct HomogeneousColorBaseConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<ColorBaseConcept<ColorBase>>();
|
||||
|
||||
static const int num_elements = size<ColorBase>::value;
|
||||
|
||||
using T0 = typename kth_element_type<ColorBase, 0>::type;
|
||||
using TN = typename kth_element_type<ColorBase, num_elements - 1>::type;
|
||||
|
||||
static_assert(is_same<T0, TN>::value, ""); // better than nothing
|
||||
|
||||
using R0 = typename kth_element_const_reference_type<ColorBase, 0>::type;
|
||||
R0 r = dynamic_at_c(cb, 0);
|
||||
}
|
||||
ColorBase cb;
|
||||
};
|
||||
|
||||
/// \ingroup ColorBaseConcept
|
||||
/// \brief Homogeneous color base that allows for modifying its elements
|
||||
/// \code
|
||||
/// concept MutableHomogeneousColorBaseConcept<ColorBaseConcept CB>
|
||||
/// : HomogeneousColorBaseConcept<CB>
|
||||
/// {
|
||||
/// kth_element_reference_type<CB, 0>::type dynamic_at_c(CB&, std::size_t n);
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename ColorBase>
|
||||
struct MutableHomogeneousColorBaseConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<ColorBaseConcept<ColorBase>>();
|
||||
gil_function_requires<HomogeneousColorBaseConcept<ColorBase>>();
|
||||
using R0 = typename kth_element_reference_type<ColorBase, 0>::type;
|
||||
R0 r = dynamic_at_c(cb, 0);
|
||||
dynamic_at_c(cb, 0) = dynamic_at_c(cb, 0);
|
||||
}
|
||||
ColorBase cb;
|
||||
};
|
||||
|
||||
/// \ingroup ColorBaseConcept
|
||||
/// \brief Homogeneous color base that also has a default constructor.
|
||||
/// Refines Regular.
|
||||
///
|
||||
/// \code
|
||||
/// concept HomogeneousColorBaseValueConcept<typename T>
|
||||
/// : MutableHomogeneousColorBaseConcept<T>, Regular<T>
|
||||
/// {
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename ColorBase>
|
||||
struct HomogeneousColorBaseValueConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<MutableHomogeneousColorBaseConcept<ColorBase>>();
|
||||
gil_function_requires<Regular<ColorBase>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup ColorBaseConcept
|
||||
/// \brief Two color bases are compatible if they have the same color space and their elements are compatible, semantic-pairwise.
|
||||
/// \code
|
||||
/// concept ColorBasesCompatibleConcept<ColorBaseConcept C1, ColorBaseConcept C2>
|
||||
/// {
|
||||
/// where SameType<C1::layout_t::color_space_t, C2::layout_t::color_space_t>;
|
||||
/// // also, for all K in [0 ... size<C1>::value):
|
||||
/// // where Convertible<kth_semantic_element_type<C1,K>::type, kth_semantic_element_type<C2,K>::type>;
|
||||
/// // where Convertible<kth_semantic_element_type<C2,K>::type, kth_semantic_element_type<C1,K>::type>;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename ColorBase1, typename ColorBase2>
|
||||
struct ColorBasesCompatibleConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
static_assert(is_same
|
||||
<
|
||||
typename ColorBase1::layout_t::color_space_t,
|
||||
typename ColorBase2::layout_t::color_space_t
|
||||
>::value, "");
|
||||
|
||||
// using e1 = typename kth_semantic_element_type<ColorBase1,0>::type;
|
||||
// using e2 = typename kth_semantic_element_type<ColorBase2,0>::type;
|
||||
// "e1 is convertible to e2"
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
57
linx64/include/boost/gil/concepts/concept_check.hpp
Normal file
57
linx64/include/boost/gil/concepts/concept_check.hpp
Normal file
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_CONCEPTS_CHECK_HPP
|
||||
#define BOOST_GIL_CONCEPTS_CONCEPTS_CHECK_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wfloat-equal"
|
||||
#pragma clang diagnostic ignored "-Wuninitialized"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
#pragma GCC diagnostic ignored "-Wuninitialized"
|
||||
#endif
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
// TODO: Document BOOST_GIL_USE_CONCEPT_CHECK here
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
// TODO: What is GIL_CLASS_REQUIRE for; Why not use BOOST_CLASS_REQUIRE?
|
||||
// TODO: What is gil_function_requires for; Why not function_requires?
|
||||
|
||||
#ifdef BOOST_GIL_USE_CONCEPT_CHECK
|
||||
#define GIL_CLASS_REQUIRE(type_var, ns, concept) \
|
||||
BOOST_CLASS_REQUIRE(type_var, ns, concept);
|
||||
|
||||
template <typename Concept>
|
||||
void gil_function_requires() { function_requires<Concept>(); }
|
||||
#else
|
||||
#define GIL_CLASS_REQUIRE(type_var, ns, concept)
|
||||
|
||||
template <typename C>
|
||||
void gil_function_requires() {}
|
||||
#endif
|
||||
|
||||
}} // namespace boost::gil:
|
||||
|
||||
#endif
|
||||
23
linx64/include/boost/gil/concepts/detail/type_traits.hpp
Normal file
23
linx64/include/boost/gil/concepts/detail/type_traits.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_DETAIL_TYPE_TRAITS_HPP
|
||||
#define BOOST_GIL_CONCEPTS_DETAIL_TYPE_TRAITS_HPP
|
||||
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct remove_const_and_reference
|
||||
: ::boost::remove_const<typename ::boost::remove_reference<T>::type>
|
||||
{
|
||||
};
|
||||
|
||||
}}} // namespace boost::gil::detail
|
||||
|
||||
#endif
|
||||
19
linx64/include/boost/gil/concepts/detail/utility.hpp
Normal file
19
linx64/include/boost/gil/concepts/detail/utility.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_DETAIL_UTILITY_HPP
|
||||
#define BOOST_GIL_CONCEPTS_DETAIL_UTILITY_HPP
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
// TODO: Remove, replace with ignore_unised?
|
||||
template <typename T>
|
||||
void initialize_it(T&) {}
|
||||
|
||||
}}} // namespace boost::gil::detail
|
||||
|
||||
#endif
|
||||
77
linx64/include/boost/gil/concepts/dynamic_step.hpp
Normal file
77
linx64/include/boost/gil/concepts/dynamic_step.hpp
Normal file
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_DYNAMIC_STEP_HPP
|
||||
#define BOOST_GIL_CONCEPTS_DYNAMIC_STEP_HPP
|
||||
|
||||
#include <boost/gil/concepts/fwd.hpp>
|
||||
#include <boost/gil/concepts/concept_check.hpp>
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \ingroup PixelIteratorConcept
|
||||
/// \brief Concept for iterators, locators and views that can define a type just like the given
|
||||
/// iterator, locator or view, except it supports runtime specified step along the X navigation.
|
||||
///
|
||||
/// \code
|
||||
/// concept HasDynamicXStepTypeConcept<typename T>
|
||||
/// {
|
||||
/// typename dynamic_x_step_type<T>;
|
||||
/// where Metafunction<dynamic_x_step_type<T> >;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename T>
|
||||
struct HasDynamicXStepTypeConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
using type = typename dynamic_x_step_type<T>::type;
|
||||
ignore_unused_variable_warning(type{});
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup PixelLocatorConcept
|
||||
/// \brief Concept for locators and views that can define a type just like the given locator or view,
|
||||
/// except it supports runtime specified step along the Y navigation
|
||||
/// \code
|
||||
/// concept HasDynamicYStepTypeConcept<typename T>
|
||||
/// {
|
||||
/// typename dynamic_y_step_type<T>;
|
||||
/// where Metafunction<dynamic_y_step_type<T> >;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename T>
|
||||
struct HasDynamicYStepTypeConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
using type = typename dynamic_y_step_type<T>::type;
|
||||
ignore_unused_variable_warning(type{});
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
36
linx64/include/boost/gil/concepts/fwd.hpp
Normal file
36
linx64/include/boost/gil/concepts/fwd.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_FWD_HPP
|
||||
#define BOOST_GIL_CONCEPTS_FWD_HPP
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
// Forward declarations used by concepts
|
||||
|
||||
template <typename ColorBase, int K> struct kth_element_type;
|
||||
template <typename ColorBase, int K> struct kth_element_reference_type;
|
||||
template <typename ColorBase, int K> struct kth_element_const_reference_type;
|
||||
template <typename ColorBase, int K> struct kth_semantic_element_reference_type;
|
||||
template <typename ColorBase, int K> struct kth_semantic_element_const_reference_type;
|
||||
template <typename ColorBase> struct size;
|
||||
template <typename ColorBase> struct element_type;
|
||||
|
||||
template <typename T> struct is_pixel;
|
||||
template <typename T> struct is_planar;
|
||||
template <typename T> struct channel_type;
|
||||
template <typename T> struct color_space_type;
|
||||
template <typename T> struct channel_mapping_type;
|
||||
template <typename T> struct num_channels;
|
||||
|
||||
template <typename T> struct dynamic_x_step_type;
|
||||
template <typename T> struct dynamic_y_step_type;
|
||||
template <typename T> struct transposed_type;
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#endif
|
||||
167
linx64/include/boost/gil/concepts/image.hpp
Normal file
167
linx64/include/boost/gil/concepts/image.hpp
Normal file
@@ -0,0 +1,167 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_IMAGE_HPP
|
||||
#define BOOST_GIL_CONCEPTS_IMAGE_HPP
|
||||
|
||||
#include <boost/gil/concepts/basic.hpp>
|
||||
#include <boost/gil/concepts/concept_check.hpp>
|
||||
#include <boost/gil/concepts/fwd.hpp>
|
||||
#include <boost/gil/concepts/image_view.hpp>
|
||||
#include <boost/gil/concepts/point.hpp>
|
||||
|
||||
#include <boost/mpl/size.hpp>
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \ingroup ImageConcept
|
||||
/// \brief N-dimensional container of values
|
||||
///
|
||||
/// \code
|
||||
/// concept RandomAccessNDImageConcept<typename Image> : Regular<Image>
|
||||
/// {
|
||||
/// typename view_t; where MutableRandomAccessNDImageViewConcept<view_t>;
|
||||
/// typename const_view_t = view_t::const_t;
|
||||
/// typename point_t = view_t::point_t;
|
||||
/// typename value_type = view_t::value_type;
|
||||
/// typename allocator_type;
|
||||
///
|
||||
/// Image::Image(point_t dims, std::size_t alignment=1);
|
||||
/// Image::Image(point_t dims, value_type fill_value, std::size_t alignment);
|
||||
///
|
||||
/// void Image::recreate(point_t new_dims, std::size_t alignment=1);
|
||||
/// void Image::recreate(point_t new_dims, value_type fill_value, std::size_t alignment);
|
||||
///
|
||||
/// const point_t& Image::dimensions() const;
|
||||
/// const const_view_t& const_view(const Image&);
|
||||
/// const view_t& view(Image&);
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename Image>
|
||||
struct RandomAccessNDImageConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<Regular<Image>>();
|
||||
|
||||
using view_t = typename Image::view_t;
|
||||
gil_function_requires<MutableRandomAccessNDImageViewConcept<view_t>>();
|
||||
|
||||
using const_view_t = typename Image::const_view_t;
|
||||
using pixel_t = typename Image::value_type;
|
||||
using point_t = typename Image::point_t;
|
||||
gil_function_requires<PointNDConcept<point_t>>();
|
||||
|
||||
const_view_t cv = const_view(image);
|
||||
ignore_unused_variable_warning(cv);
|
||||
view_t v = view(image);
|
||||
ignore_unused_variable_warning(v);
|
||||
|
||||
pixel_t fill_value;
|
||||
point_t pt = image.dimensions();
|
||||
Image image1(pt);
|
||||
Image image2(pt, 1);
|
||||
Image image3(pt, fill_value, 1);
|
||||
image.recreate(pt);
|
||||
image.recreate(pt, 1);
|
||||
image.recreate(pt, fill_value, 1);
|
||||
}
|
||||
Image image;
|
||||
};
|
||||
|
||||
|
||||
/// \ingroup ImageConcept
|
||||
/// \brief 2-dimensional container of values
|
||||
///
|
||||
/// \code
|
||||
/// concept RandomAccess2DImageConcept<RandomAccessNDImageConcept Image>
|
||||
/// {
|
||||
/// typename x_coord_t = const_view_t::x_coord_t;
|
||||
/// typename y_coord_t = const_view_t::y_coord_t;
|
||||
///
|
||||
/// Image::Image(x_coord_t width, y_coord_t height, std::size_t alignment=1);
|
||||
/// Image::Image(x_coord_t width, y_coord_t height, value_type fill_value, std::size_t alignment);
|
||||
///
|
||||
/// x_coord_t Image::width() const;
|
||||
/// y_coord_t Image::height() const;
|
||||
///
|
||||
/// void Image::recreate(x_coord_t width, y_coord_t height, std::size_t alignment=1);
|
||||
/// void Image::recreate(x_coord_t width, y_coord_t height, value_type fill_value, std::size_t alignment);
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename Image>
|
||||
struct RandomAccess2DImageConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<RandomAccessNDImageConcept<Image>>();
|
||||
using x_coord_t = typename Image::x_coord_t;
|
||||
using y_coord_t = typename Image::y_coord_t;
|
||||
using value_t = typename Image::value_type;
|
||||
|
||||
gil_function_requires<MutableRandomAccess2DImageViewConcept<typename Image::view_t>>();
|
||||
|
||||
x_coord_t w=image.width();
|
||||
y_coord_t h=image.height();
|
||||
value_t fill_value;
|
||||
Image im1(w,h);
|
||||
Image im2(w,h,1);
|
||||
Image im3(w,h,fill_value,1);
|
||||
image.recreate(w,h);
|
||||
image.recreate(w,h,1);
|
||||
image.recreate(w,h,fill_value,1);
|
||||
}
|
||||
Image image;
|
||||
};
|
||||
|
||||
/// \ingroup ImageConcept
|
||||
/// \brief 2-dimensional image whose value type models PixelValueConcept
|
||||
///
|
||||
/// \code
|
||||
/// concept ImageConcept<RandomAccess2DImageConcept Image>
|
||||
/// {
|
||||
/// where MutableImageViewConcept<view_t>;
|
||||
/// typename coord_t = view_t::coord_t;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename Image>
|
||||
struct ImageConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<RandomAccess2DImageConcept<Image>>();
|
||||
gil_function_requires<MutableImageViewConcept<typename Image::view_t>>();
|
||||
using coord_t = typename Image::coord_t;
|
||||
static_assert(num_channels<Image>::value == mpl::size<typename color_space_type<Image>::type>::value, "");
|
||||
|
||||
static_assert(is_same<coord_t, typename Image::x_coord_t>::value, "");
|
||||
static_assert(is_same<coord_t, typename Image::y_coord_t>::value, "");
|
||||
}
|
||||
Image image;
|
||||
};
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
555
linx64/include/boost/gil/concepts/image_view.hpp
Normal file
555
linx64/include/boost/gil/concepts/image_view.hpp
Normal file
@@ -0,0 +1,555 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_IMAGE_VIEW_HPP
|
||||
#define BOOST_GIL_CONCEPTS_IMAGE_VIEW_HPP
|
||||
|
||||
#include <boost/gil/concepts/basic.hpp>
|
||||
#include <boost/gil/concepts/concept_check.hpp>
|
||||
#include <boost/gil/concepts/fwd.hpp>
|
||||
#include <boost/gil/concepts/pixel.hpp>
|
||||
#include <boost/gil/concepts/pixel_dereference.hpp>
|
||||
#include <boost/gil/concepts/pixel_iterator.hpp>
|
||||
#include <boost/gil/concepts/pixel_locator.hpp>
|
||||
#include <boost/gil/concepts/point.hpp>
|
||||
#include <boost/gil/concepts/detail/utility.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \defgroup ImageViewNDConcept ImageViewNDLocatorConcept
|
||||
/// \ingroup ImageViewConcept
|
||||
/// \brief N-dimensional range
|
||||
|
||||
/// \defgroup ImageView2DConcept ImageView2DConcept
|
||||
/// \ingroup ImageViewConcept
|
||||
/// \brief 2-dimensional range
|
||||
|
||||
/// \defgroup PixelImageViewConcept ImageViewConcept
|
||||
/// \ingroup ImageViewConcept
|
||||
/// \brief 2-dimensional range over pixel data
|
||||
|
||||
/// \ingroup ImageViewNDConcept
|
||||
/// \brief N-dimensional view over immutable values
|
||||
///
|
||||
/// \code
|
||||
/// concept RandomAccessNDImageViewConcept<Regular View>
|
||||
/// {
|
||||
/// typename value_type;
|
||||
/// typename reference; // result of dereferencing
|
||||
/// typename difference_type; // result of operator-(iterator,iterator) (1-dimensional!)
|
||||
/// typename const_t; where RandomAccessNDImageViewConcept<View>; // same as View, but over immutable values
|
||||
/// typename point_t; where PointNDConcept<point_t>; // N-dimensional point
|
||||
/// typename locator; where RandomAccessNDLocatorConcept<locator>; // N-dimensional locator.
|
||||
/// typename iterator; where RandomAccessTraversalConcept<iterator>; // 1-dimensional iterator over all values
|
||||
/// typename reverse_iterator; where RandomAccessTraversalConcept<reverse_iterator>;
|
||||
/// typename size_type; // the return value of size()
|
||||
///
|
||||
/// // Equivalent to RandomAccessNDLocatorConcept::axis
|
||||
/// template <size_t D> struct axis {
|
||||
/// typename coord_t = point_t::axis<D>::coord_t;
|
||||
/// typename iterator; where RandomAccessTraversalConcept<iterator>; // iterator along D-th axis.
|
||||
/// where SameType<coord_t, iterator::difference_type>;
|
||||
/// where SameType<iterator::value_type,value_type>;
|
||||
/// };
|
||||
///
|
||||
/// // Defines the type of a view similar to this type, except it invokes Deref upon dereferencing
|
||||
/// template <PixelDereferenceAdaptorConcept Deref> struct add_deref {
|
||||
/// typename type; where RandomAccessNDImageViewConcept<type>;
|
||||
/// static type make(const View& v, const Deref& deref);
|
||||
/// };
|
||||
///
|
||||
/// static const size_t num_dimensions = point_t::num_dimensions;
|
||||
///
|
||||
/// // Create from a locator at the top-left corner and dimensions
|
||||
/// View::View(const locator&, const point_type&);
|
||||
///
|
||||
/// size_type View::size() const; // total number of elements
|
||||
/// reference operator[](View, const difference_type&) const; // 1-dimensional reference
|
||||
/// iterator View::begin() const;
|
||||
/// iterator View::end() const;
|
||||
/// reverse_iterator View::rbegin() const;
|
||||
/// reverse_iterator View::rend() const;
|
||||
/// iterator View::at(const point_t&);
|
||||
/// point_t View::dimensions() const; // number of elements along each dimension
|
||||
/// bool View::is_1d_traversable() const; // can an iterator over the first dimension visit each value? I.e. are there gaps between values?
|
||||
///
|
||||
/// // iterator along a given dimension starting at a given point
|
||||
/// template <size_t D> View::axis<D>::iterator View::axis_iterator(const point_t&) const;
|
||||
///
|
||||
/// reference operator()(View,const point_t&) const;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename View>
|
||||
struct RandomAccessNDImageViewConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<Regular<View>>();
|
||||
|
||||
using value_type = typename View::value_type;
|
||||
using reference = typename View::reference; // result of dereferencing
|
||||
using pointer = typename View::pointer;
|
||||
using difference_type = typename View::difference_type; // result of operator-(1d_iterator,1d_iterator)
|
||||
using const_t = typename View::const_t; // same as this type, but over const values
|
||||
using point_t = typename View::point_t; // N-dimensional point
|
||||
using locator = typename View::locator; // N-dimensional locator
|
||||
using iterator = typename View::iterator;
|
||||
using const_iterator = typename View::const_iterator;
|
||||
using reverse_iterator = typename View::reverse_iterator;
|
||||
using size_type = typename View::size_type;
|
||||
static const std::size_t N=View::num_dimensions;
|
||||
|
||||
gil_function_requires<RandomAccessNDLocatorConcept<locator>>();
|
||||
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<iterator>>();
|
||||
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<reverse_iterator>>();
|
||||
|
||||
using first_it_type = typename View::template axis<0>::iterator;
|
||||
using last_it_type = typename View::template axis<N-1>::iterator;
|
||||
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type>>();
|
||||
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type>>();
|
||||
|
||||
// static_assert(typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value, "");
|
||||
// static_assert(typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value, "");
|
||||
|
||||
// point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator
|
||||
gil_function_requires<PointNDConcept<point_t>>();
|
||||
static_assert(point_t::num_dimensions == N, "");
|
||||
static_assert(is_same
|
||||
<
|
||||
typename std::iterator_traits<first_it_type>::difference_type,
|
||||
typename point_t::template axis<0>::coord_t
|
||||
>::value, "");
|
||||
static_assert(is_same
|
||||
<
|
||||
typename std::iterator_traits<last_it_type>::difference_type,
|
||||
typename point_t::template axis<N-1>::coord_t
|
||||
>::value, "");
|
||||
|
||||
point_t p;
|
||||
locator lc;
|
||||
iterator it;
|
||||
reverse_iterator rit;
|
||||
difference_type d; detail::initialize_it(d); ignore_unused_variable_warning(d);
|
||||
|
||||
View(p,lc); // view must be constructible from a locator and a point
|
||||
|
||||
p = view.dimensions();
|
||||
lc = view.pixels();
|
||||
size_type sz = view.size(); ignore_unused_variable_warning(sz);
|
||||
bool is_contiguous = view.is_1d_traversable();
|
||||
ignore_unused_variable_warning(is_contiguous);
|
||||
|
||||
it = view.begin();
|
||||
it = view.end();
|
||||
rit = view.rbegin();
|
||||
rit = view.rend();
|
||||
|
||||
reference r1 = view[d]; ignore_unused_variable_warning(r1); // 1D access
|
||||
reference r2 = view(p); ignore_unused_variable_warning(r2); // 2D access
|
||||
|
||||
// get 1-D iterator of any dimension at a given pixel location
|
||||
first_it_type fi = view.template axis_iterator<0>(p);
|
||||
ignore_unused_variable_warning(fi);
|
||||
last_it_type li = view.template axis_iterator<N-1>(p);
|
||||
ignore_unused_variable_warning(li);
|
||||
|
||||
using deref_t = PixelDereferenceAdaptorArchetype<typename View::value_type>;
|
||||
using dtype = typename View::template add_deref<deref_t>::type;
|
||||
}
|
||||
View view;
|
||||
};
|
||||
|
||||
/// \ingroup ImageView2DConcept
|
||||
/// \brief 2-dimensional view over immutable values
|
||||
///
|
||||
/// \code
|
||||
/// concept RandomAccess2DImageViewConcept<RandomAccessNDImageViewConcept View> {
|
||||
/// where num_dimensions==2;
|
||||
///
|
||||
/// typename x_iterator = axis<0>::iterator;
|
||||
/// typename y_iterator = axis<1>::iterator;
|
||||
/// typename x_coord_t = axis<0>::coord_t;
|
||||
/// typename y_coord_t = axis<1>::coord_t;
|
||||
/// typename xy_locator = locator;
|
||||
///
|
||||
/// x_coord_t View::width() const;
|
||||
/// y_coord_t View::height() const;
|
||||
///
|
||||
/// // X-navigation
|
||||
/// x_iterator View::x_at(const point_t&) const;
|
||||
/// x_iterator View::row_begin(y_coord_t) const;
|
||||
/// x_iterator View::row_end (y_coord_t) const;
|
||||
///
|
||||
/// // Y-navigation
|
||||
/// y_iterator View::y_at(const point_t&) const;
|
||||
/// y_iterator View::col_begin(x_coord_t) const;
|
||||
/// y_iterator View::col_end (x_coord_t) const;
|
||||
///
|
||||
/// // navigating in 2D
|
||||
/// xy_locator View::xy_at(const point_t&) const;
|
||||
///
|
||||
/// // (x,y) versions of all methods taking point_t
|
||||
/// View::View(x_coord_t,y_coord_t,const locator&);
|
||||
/// iterator View::at(x_coord_t,y_coord_t) const;
|
||||
/// reference operator()(View,x_coord_t,y_coord_t) const;
|
||||
/// xy_locator View::xy_at(x_coord_t,y_coord_t) const;
|
||||
/// x_iterator View::x_at(x_coord_t,y_coord_t) const;
|
||||
/// y_iterator View::y_at(x_coord_t,y_coord_t) const;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename View>
|
||||
struct RandomAccess2DImageViewConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<RandomAccessNDImageViewConcept<View>>();
|
||||
static_assert(View::num_dimensions == 2, "");
|
||||
|
||||
// TODO: This executes the requirements for RandomAccessNDLocatorConcept again. Fix it to improve compile time
|
||||
gil_function_requires<RandomAccess2DLocatorConcept<typename View::locator>>();
|
||||
|
||||
using dynamic_x_step_t = typename dynamic_x_step_type<View>::type;
|
||||
using dynamic_y_step_t = typename dynamic_y_step_type<View>::type;
|
||||
using transposed_t = typename transposed_type<View>::type;
|
||||
using x_iterator = typename View::x_iterator;
|
||||
using y_iterator = typename View::y_iterator;
|
||||
using x_coord_t = typename View::x_coord_t;
|
||||
using y_coord_t = typename View::y_coord_t;
|
||||
using xy_locator = typename View::xy_locator;
|
||||
|
||||
x_coord_t xd = 0; ignore_unused_variable_warning(xd);
|
||||
y_coord_t yd = 0; ignore_unused_variable_warning(yd);
|
||||
x_iterator xit;
|
||||
y_iterator yit;
|
||||
typename View::point_t d;
|
||||
|
||||
View(xd, yd, xy_locator()); // constructible with width, height, 2d_locator
|
||||
|
||||
xy_locator lc = view.xy_at(xd, yd);
|
||||
lc = view.xy_at(d);
|
||||
|
||||
typename View::reference r = view(xd, yd);
|
||||
ignore_unused_variable_warning(r);
|
||||
xd = view.width();
|
||||
yd = view.height();
|
||||
|
||||
xit = view.x_at(d);
|
||||
xit = view.x_at(xd,yd);
|
||||
xit = view.row_begin(xd);
|
||||
xit = view.row_end(xd);
|
||||
|
||||
yit = view.y_at(d);
|
||||
yit = view.y_at(xd,yd);
|
||||
yit = view.col_begin(xd);
|
||||
yit = view.col_end(xd);
|
||||
}
|
||||
View view;
|
||||
};
|
||||
|
||||
/// \brief GIL view as Collection.
|
||||
///
|
||||
/// \see https://www.boost.org/libs/utility/Collection.html
|
||||
///
|
||||
template <typename View>
|
||||
struct CollectionImageViewConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
using value_type = typename View::value_type;
|
||||
using iterator = typename View::iterator;
|
||||
using const_iterator = typename View::const_iterator;
|
||||
using reference = typename View::reference;
|
||||
using const_reference = typename View::const_reference;
|
||||
using pointer = typename View::pointer;
|
||||
using difference_type = typename View::difference_type;
|
||||
using size_type= typename View::size_type;
|
||||
|
||||
iterator i;
|
||||
i = view1.begin();
|
||||
i = view2.end();
|
||||
|
||||
const_iterator ci;
|
||||
ci = view1.begin();
|
||||
ci = view2.end();
|
||||
|
||||
size_type s;
|
||||
s = view1.size();
|
||||
s = view2.size();
|
||||
ignore_unused_variable_warning(s);
|
||||
|
||||
view1.empty();
|
||||
|
||||
view1.swap(view2);
|
||||
}
|
||||
View view1;
|
||||
View view2;
|
||||
};
|
||||
|
||||
/// \brief GIL view as ForwardCollection.
|
||||
///
|
||||
/// \see https://www.boost.org/libs/utility/Collection.html
|
||||
///
|
||||
template <typename View>
|
||||
struct ForwardCollectionImageViewConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<CollectionImageViewConcept<View>>();
|
||||
|
||||
using reference = typename View::reference;
|
||||
using const_reference = typename View::const_reference;
|
||||
|
||||
reference r = view.front();
|
||||
ignore_unused_variable_warning(r);
|
||||
|
||||
const_reference cr = view.front();
|
||||
ignore_unused_variable_warning(cr);
|
||||
}
|
||||
View view;
|
||||
};
|
||||
|
||||
/// \brief GIL view as ReversibleCollection.
|
||||
///
|
||||
/// \see https://www.boost.org/libs/utility/Collection.html
|
||||
///
|
||||
template <typename View>
|
||||
struct ReversibleCollectionImageViewConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<CollectionImageViewConcept<View>>();
|
||||
|
||||
using reverse_iterator = typename View::reverse_iterator;
|
||||
using reference = typename View::reference;
|
||||
using const_reference = typename View::const_reference;
|
||||
|
||||
reverse_iterator i;
|
||||
i = view.rbegin();
|
||||
i = view.rend();
|
||||
|
||||
reference r = view.back();
|
||||
ignore_unused_variable_warning(r);
|
||||
|
||||
const_reference cr = view.back();
|
||||
ignore_unused_variable_warning(cr);
|
||||
}
|
||||
View view;
|
||||
};
|
||||
|
||||
/// \ingroup PixelImageViewConcept
|
||||
/// \brief GIL's 2-dimensional view over immutable GIL pixels
|
||||
/// \code
|
||||
/// concept ImageViewConcept<RandomAccess2DImageViewConcept View>
|
||||
/// {
|
||||
/// where PixelValueConcept<value_type>;
|
||||
/// where PixelIteratorConcept<x_iterator>;
|
||||
/// where PixelIteratorConcept<y_iterator>;
|
||||
/// where x_coord_t == y_coord_t;
|
||||
///
|
||||
/// typename coord_t = x_coord_t;
|
||||
///
|
||||
/// std::size_t View::num_channels() const;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename View>
|
||||
struct ImageViewConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<RandomAccess2DImageViewConcept<View>>();
|
||||
|
||||
// TODO: This executes the requirements for RandomAccess2DLocatorConcept again. Fix it to improve compile time
|
||||
gil_function_requires<PixelLocatorConcept<typename View::xy_locator>>();
|
||||
|
||||
static_assert(is_same<typename View::x_coord_t, typename View::y_coord_t>::value, "");
|
||||
|
||||
using coord_t = typename View::coord_t; // 1D difference type (same for all dimensions)
|
||||
std::size_t num_chan = view.num_channels(); ignore_unused_variable_warning(num_chan);
|
||||
}
|
||||
View view;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
/// \tparam View Models RandomAccessNDImageViewConcept
|
||||
template <typename View>
|
||||
struct RandomAccessNDImageViewIsMutableConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<typename View::locator>>();
|
||||
|
||||
gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::iterator>>();
|
||||
|
||||
gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
|
||||
<
|
||||
typename View::reverse_iterator
|
||||
>>();
|
||||
|
||||
gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
|
||||
<
|
||||
typename View::template axis<0>::iterator
|
||||
>>();
|
||||
|
||||
gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
|
||||
<
|
||||
typename View::template axis<View::num_dimensions - 1>::iterator
|
||||
>>();
|
||||
|
||||
typename View::difference_type diff;
|
||||
initialize_it(diff);
|
||||
ignore_unused_variable_warning(diff);
|
||||
|
||||
typename View::point_t pt;
|
||||
typename View::value_type v;
|
||||
initialize_it(v);
|
||||
|
||||
view[diff] = v;
|
||||
view(pt) = v;
|
||||
}
|
||||
View view;
|
||||
};
|
||||
|
||||
/// \tparam View Models RandomAccessNDImageViewConcept
|
||||
template <typename View>
|
||||
struct RandomAccess2DImageViewIsMutableConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View>>();
|
||||
typename View::x_coord_t xd = 0; ignore_unused_variable_warning(xd);
|
||||
typename View::y_coord_t yd = 0; ignore_unused_variable_warning(yd);
|
||||
typename View::value_type v; initialize_it(v);
|
||||
view(xd, yd) = v;
|
||||
}
|
||||
View view;
|
||||
};
|
||||
|
||||
/// \tparam View Models ImageViewConcept
|
||||
template <typename View>
|
||||
struct PixelImageViewIsMutableConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View>>();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \ingroup ImageViewNDConcept
|
||||
/// \brief N-dimensional view over mutable values
|
||||
///
|
||||
/// \code
|
||||
/// concept MutableRandomAccessNDImageViewConcept<RandomAccessNDImageViewConcept View>
|
||||
/// {
|
||||
/// where Mutable<reference>;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename View>
|
||||
struct MutableRandomAccessNDImageViewConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<RandomAccessNDImageViewConcept<View>>();
|
||||
gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup ImageView2DConcept
|
||||
/// \brief 2-dimensional view over mutable values
|
||||
///
|
||||
/// \code
|
||||
/// concept MutableRandomAccess2DImageViewConcept<RandomAccess2DImageViewConcept View>
|
||||
/// : MutableRandomAccessNDImageViewConcept<View> {};
|
||||
/// \endcode
|
||||
template <typename View>
|
||||
struct MutableRandomAccess2DImageViewConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<RandomAccess2DImageViewConcept<View>>();
|
||||
gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup PixelImageViewConcept
|
||||
/// \brief GIL's 2-dimensional view over mutable GIL pixels
|
||||
///
|
||||
/// \code
|
||||
/// concept MutableImageViewConcept<ImageViewConcept View>
|
||||
/// : MutableRandomAccess2DImageViewConcept<View> {};
|
||||
/// \endcode
|
||||
template <typename View>
|
||||
struct MutableImageViewConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<ImageViewConcept<View>>();
|
||||
gil_function_requires<detail::PixelImageViewIsMutableConcept<View>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Returns whether two views are compatible
|
||||
///
|
||||
/// Views are compatible if their pixels are compatible.
|
||||
/// Compatible views can be assigned and copy constructed from one another.
|
||||
///
|
||||
/// \tparam V1 Models ImageViewConcept
|
||||
/// \tparam V2 Models ImageViewConcept
|
||||
///
|
||||
template <typename V1, typename V2>
|
||||
struct views_are_compatible
|
||||
: pixels_are_compatible<typename V1::value_type, typename V2::value_type>
|
||||
{
|
||||
};
|
||||
|
||||
/// \ingroup ImageViewConcept
|
||||
/// \brief Views are compatible if they have the same color spaces and compatible channel values.
|
||||
///
|
||||
/// Constness and layout are not important for compatibility.
|
||||
///
|
||||
/// \code
|
||||
/// concept ViewsCompatibleConcept<ImageViewConcept V1, ImageViewConcept V2>
|
||||
/// {
|
||||
/// where PixelsCompatibleConcept<V1::value_type, P2::value_type>;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename V1, typename V2>
|
||||
struct ViewsCompatibleConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
static_assert(views_are_compatible<V1, V2>::value, "");
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
305
linx64/include/boost/gil/concepts/pixel.hpp
Normal file
305
linx64/include/boost/gil/concepts/pixel.hpp
Normal file
@@ -0,0 +1,305 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_PIXEL_HPP
|
||||
#define BOOST_GIL_CONCEPTS_PIXEL_HPP
|
||||
|
||||
#include <boost/gil/concepts/basic.hpp>
|
||||
#include <boost/gil/concepts/channel.hpp>
|
||||
#include <boost/gil/concepts/color.hpp>
|
||||
#include <boost/gil/concepts/color_base.hpp>
|
||||
#include <boost/gil/concepts/concept_check.hpp>
|
||||
#include <boost/gil/concepts/fwd.hpp>
|
||||
#include <boost/gil/concepts/pixel_based.hpp>
|
||||
#include <boost/gil/concepts/detail/type_traits.hpp>
|
||||
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \brief Pixel concept - A color base whose elements are channels
|
||||
/// \ingroup PixelConcept
|
||||
/// \code
|
||||
/// concept PixelConcept<typename P> : ColorBaseConcept<P>, PixelBasedConcept<P>
|
||||
/// {
|
||||
/// where is_pixel<P>::value == true;
|
||||
/// // where for each K [0..size<P>::value - 1]:
|
||||
/// // ChannelConcept<kth_element_type<P, K>>;
|
||||
///
|
||||
/// typename P::value_type;
|
||||
/// where PixelValueConcept<value_type>;
|
||||
/// typename P::reference;
|
||||
/// where PixelConcept<reference>;
|
||||
/// typename P::const_reference;
|
||||
/// where PixelConcept<const_reference>;
|
||||
/// static const bool P::is_mutable;
|
||||
///
|
||||
/// template <PixelConcept P2> where { PixelConcept<P, P2> }
|
||||
/// P::P(P2);
|
||||
/// template <PixelConcept P2> where { PixelConcept<P, P2> }
|
||||
/// bool operator==(const P&, const P2&);
|
||||
/// template <PixelConcept P2> where { PixelConcept<P, P2> }
|
||||
/// bool operator!=(const P&, const P2&);
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename P>
|
||||
struct PixelConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<ColorBaseConcept<P>>();
|
||||
gil_function_requires<PixelBasedConcept<P>>();
|
||||
|
||||
static_assert(is_pixel<P>::value, "");
|
||||
static const bool is_mutable = P::is_mutable;
|
||||
ignore_unused_variable_warning(is_mutable);
|
||||
|
||||
using value_type = typename P::value_type;
|
||||
// TODO: Is the cyclic dependency intentional? --mloskot
|
||||
// gil_function_requires<PixelValueConcept<value_type>>();
|
||||
|
||||
using reference = typename P::reference;
|
||||
gil_function_requires<PixelConcept
|
||||
<
|
||||
typename detail::remove_const_and_reference<reference>::type
|
||||
>>();
|
||||
|
||||
using const_reference = typename P::const_reference;
|
||||
gil_function_requires<PixelConcept
|
||||
<
|
||||
typename detail::remove_const_and_reference<const_reference>::type
|
||||
>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Pixel concept that allows for changing its channels
|
||||
/// \ingroup PixelConcept
|
||||
/// \code
|
||||
/// concept MutablePixelConcept<PixelConcept P> : MutableColorBaseConcept<P>
|
||||
/// {
|
||||
/// where is_mutable==true;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename P>
|
||||
struct MutablePixelConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<PixelConcept<P>>();
|
||||
static_assert(P::is_mutable, "");
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Homogeneous pixel concept
|
||||
/// \ingroup PixelConcept
|
||||
/// \code
|
||||
/// concept HomogeneousPixelConcept<PixelConcept P>
|
||||
/// : HomogeneousColorBaseConcept<P>, HomogeneousPixelBasedConcept<P>
|
||||
/// {
|
||||
/// P::template element_const_reference_type<P>::type operator[](P p, std::size_t i) const
|
||||
/// {
|
||||
/// return dynamic_at_c(p,i);
|
||||
/// }
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename P>
|
||||
struct HomogeneousPixelConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<PixelConcept<P>>();
|
||||
gil_function_requires<HomogeneousColorBaseConcept<P>>();
|
||||
gil_function_requires<HomogeneousPixelBasedConcept<P>>();
|
||||
p[0];
|
||||
}
|
||||
P p;
|
||||
};
|
||||
|
||||
/// \brief Homogeneous pixel concept that allows for changing its channels
|
||||
/// \ingroup PixelConcept
|
||||
/// \code
|
||||
/// concept MutableHomogeneousPixelConcept<HomogeneousPixelConcept P>
|
||||
/// : MutableHomogeneousColorBaseConcept<P>
|
||||
/// {
|
||||
/// P::template element_reference_type<P>::type operator[](P p, std::size_t i)
|
||||
/// {
|
||||
/// return dynamic_at_c(p, i);
|
||||
/// }
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename P>
|
||||
struct MutableHomogeneousPixelConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<HomogeneousPixelConcept<P>>();
|
||||
gil_function_requires<MutableHomogeneousColorBaseConcept<P>>();
|
||||
p[0] = v;
|
||||
v = p[0];
|
||||
}
|
||||
typename P::template element_type<P>::type v;
|
||||
P p;
|
||||
};
|
||||
|
||||
/// \brief Pixel concept that is a Regular type
|
||||
/// \ingroup PixelConcept
|
||||
/// \code
|
||||
/// concept PixelValueConcept<PixelConcept P> : Regular<P>
|
||||
/// {
|
||||
/// where SameType<value_type,P>;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename P>
|
||||
struct PixelValueConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<PixelConcept<P>>();
|
||||
gil_function_requires<Regular<P>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Homogeneous pixel concept that is a Regular type
|
||||
/// \ingroup PixelConcept
|
||||
/// \code
|
||||
/// concept HomogeneousPixelValueConcept<HomogeneousPixelConcept P> : Regular<P>
|
||||
/// {
|
||||
/// where SameType<value_type,P>;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename P>
|
||||
struct HomogeneousPixelValueConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<HomogeneousPixelConcept<P>>();
|
||||
gil_function_requires<Regular<P>>();
|
||||
static_assert(is_same<P, typename P::value_type>::value, "");
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename P1, typename P2, int K>
|
||||
struct channels_are_pairwise_compatible
|
||||
: public
|
||||
mpl::and_
|
||||
<
|
||||
channels_are_pairwise_compatible<P1, P2, K - 1>,
|
||||
channels_are_compatible
|
||||
<
|
||||
typename kth_semantic_element_reference_type<P1, K>::type,
|
||||
typename kth_semantic_element_reference_type<P2, K>::type
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename P1, typename P2>
|
||||
struct channels_are_pairwise_compatible<P1, P2, -1>
|
||||
: public mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \ingroup PixelAlgorithm
|
||||
/// \brief Returns whether two pixels are compatible
|
||||
/// Pixels are compatible if their channels and color space types are compatible.
|
||||
/// Compatible pixels can be assigned and copy constructed from one another.
|
||||
/// \tparam P1 Models PixelConcept
|
||||
/// \tparam P2 Models PixelConcept
|
||||
template <typename P1, typename P2>
|
||||
struct pixels_are_compatible
|
||||
: public
|
||||
mpl::and_
|
||||
<
|
||||
typename color_spaces_are_compatible
|
||||
<
|
||||
typename color_space_type<P1>::type,
|
||||
typename color_space_type<P2>::type
|
||||
>::type,
|
||||
detail::channels_are_pairwise_compatible
|
||||
<
|
||||
P1, P2, num_channels<P1>::value - 1
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
/// \ingroup PixelConcept
|
||||
/// \brief Concept for pixel compatibility
|
||||
/// Pixels are compatible if their channels and color space types are compatible.
|
||||
/// Compatible pixels can be assigned and copy constructed from one another.
|
||||
/// \tparam P1 Models PixelConcept
|
||||
/// \tparam P2 Models PixelConcept
|
||||
/// \code
|
||||
/// concept PixelsCompatibleConcept<PixelConcept P1, PixelConcept P2>
|
||||
/// : ColorBasesCompatibleConcept<P1,P2> {
|
||||
/// // where for each K [0..size<P1>::value):
|
||||
/// // ChannelsCompatibleConcept<kth_semantic_element_type<P1,K>::type, kth_semantic_element_type<P2,K>::type>;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename P1, typename P2>
|
||||
struct PixelsCompatibleConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
static_assert(pixels_are_compatible<P1, P2>::value, "");
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup PixelConcept
|
||||
/// \brief Pixel convertible concept
|
||||
/// Convertibility is non-symmetric and implies that one pixel
|
||||
/// can be converted to another, approximating the color.
|
||||
/// Conversion is explicit and sometimes lossy.
|
||||
/// \code
|
||||
/// template <PixelConcept SrcPixel, MutablePixelConcept DstPixel>
|
||||
/// concept PixelConvertibleConcept
|
||||
/// {
|
||||
/// void color_convert(const SrcPixel&, DstPixel&);
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename SrcP, typename DstP>
|
||||
struct PixelConvertibleConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<PixelConcept<SrcP>>();
|
||||
gil_function_requires<MutablePixelConcept<DstP>>();
|
||||
color_convert(src, dst);
|
||||
}
|
||||
SrcP src;
|
||||
DstP dst;
|
||||
};
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
103
linx64/include/boost/gil/concepts/pixel_based.hpp
Normal file
103
linx64/include/boost/gil/concepts/pixel_based.hpp
Normal file
@@ -0,0 +1,103 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_PIXEL_BASED_HPP
|
||||
#define BOOST_GIL_CONCEPTS_PIXEL_BASED_HPP
|
||||
|
||||
#include <boost/gil/concepts/basic.hpp>
|
||||
#include <boost/gil/concepts/channel.hpp>
|
||||
#include <boost/gil/concepts/color.hpp>
|
||||
#include <boost/gil/concepts/concept_check.hpp>
|
||||
#include <boost/gil/concepts/fwd.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \ingroup PixelBasedConcept
|
||||
/// \brief Concept for all pixel-based GIL constructs.
|
||||
///
|
||||
/// Pixel-based constructs include pixels, iterators, locators, views and
|
||||
/// images whose value type is a pixel.
|
||||
///
|
||||
/// \code
|
||||
/// concept PixelBasedConcept<typename T>
|
||||
/// {
|
||||
/// typename color_space_type<T>;
|
||||
/// where Metafunction<color_space_type<T> >;
|
||||
/// where ColorSpaceConcept<color_space_type<T>::type>;
|
||||
/// typename channel_mapping_type<T>;
|
||||
/// where Metafunction<channel_mapping_type<T> >;
|
||||
/// where ChannelMappingConcept<channel_mapping_type<T>::type>;
|
||||
/// typename is_planar<T>;
|
||||
/// where Metafunction<is_planar<T> >;
|
||||
/// where SameType<is_planar<T>::type, bool>;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename P>
|
||||
struct PixelBasedConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
using color_space_t = typename color_space_type<P>::type;
|
||||
gil_function_requires<ColorSpaceConcept<color_space_t>>();
|
||||
|
||||
using channel_mapping_t = typename channel_mapping_type<P>::type ;
|
||||
gil_function_requires<ChannelMappingConcept<channel_mapping_t>>();
|
||||
|
||||
static const bool planar = is_planar<P>::value;
|
||||
ignore_unused_variable_warning(planar);
|
||||
|
||||
// This is not part of the concept, but should still work
|
||||
static const std::size_t nc = num_channels<P>::value;
|
||||
ignore_unused_variable_warning(nc);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Concept for homogeneous pixel-based GIL constructs
|
||||
/// \ingroup PixelBasedConcept
|
||||
/// \code
|
||||
/// concept HomogeneousPixelBasedConcept<PixelBasedConcept T>
|
||||
/// {
|
||||
/// typename channel_type<T>;
|
||||
/// where Metafunction<channel_type<T>>;
|
||||
/// where ChannelConcept<channel_type<T>::type>;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename P>
|
||||
struct HomogeneousPixelBasedConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<PixelBasedConcept<P>>();
|
||||
|
||||
using channel_t = typename channel_type<P>::type;
|
||||
gil_function_requires<ChannelConcept<channel_t>>();
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
114
linx64/include/boost/gil/concepts/pixel_dereference.hpp
Normal file
114
linx64/include/boost/gil/concepts/pixel_dereference.hpp
Normal file
@@ -0,0 +1,114 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_PIXEL_DEREFERENCE_HPP
|
||||
#define BOOST_GIL_CONCEPTS_PIXEL_DEREFERENCE_HPP
|
||||
|
||||
#include <boost/gil/concepts/basic.hpp>
|
||||
#include <boost/gil/concepts/concept_check.hpp>
|
||||
#include <boost/gil/concepts/fwd.hpp>
|
||||
#include <boost/gil/concepts/pixel.hpp>
|
||||
#include <boost/gil/concepts/detail/type_traits.hpp>
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \ingroup PixelDereferenceAdaptorConcept
|
||||
/// \brief Represents a unary function object that can be invoked upon dereferencing a pixel iterator.
|
||||
///
|
||||
/// This can perform an arbitrary computation, such as color conversion or table lookup.
|
||||
/// \code
|
||||
/// concept PixelDereferenceAdaptorConcept<boost::UnaryFunctionConcept D>
|
||||
/// : DefaultConstructibleConcept<D>, CopyConstructibleConcept<D>, AssignableConcept<D>
|
||||
/// {
|
||||
/// typename const_t; where PixelDereferenceAdaptorConcept<const_t>;
|
||||
/// typename value_type; where PixelValueConcept<value_type>;
|
||||
/// typename reference; // may be mutable
|
||||
/// typename const_reference; // must not be mutable
|
||||
/// static const bool D::is_mutable;
|
||||
///
|
||||
/// where Convertible<value_type,result_type>;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename D>
|
||||
struct PixelDereferenceAdaptorConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires
|
||||
<
|
||||
boost::UnaryFunctionConcept
|
||||
<
|
||||
D,
|
||||
typename detail::remove_const_and_reference<typename D::result_type>::type,
|
||||
typename D::argument_type
|
||||
>
|
||||
>();
|
||||
gil_function_requires<boost::DefaultConstructibleConcept<D>>();
|
||||
gil_function_requires<boost::CopyConstructibleConcept<D>>();
|
||||
gil_function_requires<boost::AssignableConcept<D>>();
|
||||
|
||||
gil_function_requires<PixelConcept
|
||||
<
|
||||
typename detail::remove_const_and_reference<typename D::result_type>::type
|
||||
>>();
|
||||
|
||||
using const_t = typename D::const_t;
|
||||
gil_function_requires<PixelDereferenceAdaptorConcept<const_t>>();
|
||||
|
||||
using value_type = typename D::value_type;
|
||||
gil_function_requires<PixelValueConcept<value_type>>();
|
||||
|
||||
// TODO: Should this be concept-checked after "if you remove const and reference"? --mloskot
|
||||
using reference = typename D::reference; // == PixelConcept (if you remove const and reference)
|
||||
using const_reference = typename D::const_reference; // == PixelConcept (if you remove const and reference)
|
||||
|
||||
bool const is_mutable = D::is_mutable;
|
||||
ignore_unused_variable_warning(is_mutable);
|
||||
}
|
||||
D d;
|
||||
};
|
||||
|
||||
template <typename P>
|
||||
struct PixelDereferenceAdaptorArchetype
|
||||
{
|
||||
using argument_type = P;
|
||||
using result_type = P;
|
||||
using const_t = PixelDereferenceAdaptorArchetype;
|
||||
using value_type = typename remove_reference<P>::type;
|
||||
using reference = typename add_reference<P>::type;
|
||||
using const_reference = reference;
|
||||
|
||||
static const bool is_mutable = false;
|
||||
P operator()(P) const { throw; }
|
||||
};
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
360
linx64/include/boost/gil/concepts/pixel_iterator.hpp
Normal file
360
linx64/include/boost/gil/concepts/pixel_iterator.hpp
Normal file
@@ -0,0 +1,360 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_PIXEL_ITERATOR_HPP
|
||||
#define BOOST_GIL_CONCEPTS_PIXEL_ITERATOR_HPP
|
||||
|
||||
#include <boost/gil/concepts/channel.hpp>
|
||||
#include <boost/gil/concepts/color.hpp>
|
||||
#include <boost/gil/concepts/concept_check.hpp>
|
||||
#include <boost/gil/concepts/fwd.hpp>
|
||||
#include <boost/gil/concepts/pixel.hpp>
|
||||
#include <boost/gil/concepts/pixel_based.hpp>
|
||||
|
||||
#include <boost/iterator/iterator_concepts.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
// Forward declarations
|
||||
template <typename It> struct const_iterator_type;
|
||||
template <typename It> struct iterator_is_mutable;
|
||||
template <typename It> struct is_iterator_adaptor;
|
||||
template <typename It, typename NewBaseIt> struct iterator_adaptor_rebind;
|
||||
template <typename It> struct iterator_adaptor_get_base;
|
||||
|
||||
// These iterator mutability concepts are taken from Boost concept_check.hpp.
|
||||
// Isolating mutability to result in faster compile time
|
||||
namespace detail {
|
||||
|
||||
// Preconditions: TT Models boost_concepts::ForwardTraversalConcept
|
||||
template <class TT>
|
||||
struct ForwardIteratorIsMutableConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
auto const tmp = *i;
|
||||
*i++ = tmp; // require postincrement and assignment
|
||||
}
|
||||
TT i;
|
||||
};
|
||||
|
||||
// Preconditions: TT Models boost::BidirectionalIteratorConcept
|
||||
template <class TT>
|
||||
struct BidirectionalIteratorIsMutableConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires< ForwardIteratorIsMutableConcept<TT>>();
|
||||
auto const tmp = *i;
|
||||
*i-- = tmp; // require postdecrement and assignment
|
||||
}
|
||||
TT i;
|
||||
};
|
||||
|
||||
// Preconditions: TT Models boost_concepts::RandomAccessTraversalConcept
|
||||
template <class TT>
|
||||
struct RandomAccessIteratorIsMutableConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<BidirectionalIteratorIsMutableConcept<TT>>();
|
||||
|
||||
typename std::iterator_traits<TT>::difference_type n = 0;
|
||||
ignore_unused_variable_warning(n);
|
||||
i[n] = *i; // require element access and assignment
|
||||
}
|
||||
TT i;
|
||||
};
|
||||
|
||||
// Iterators that can be used as the base of memory_based_step_iterator require some additional functions
|
||||
// \tparam Iterator Models boost_concepts::RandomAccessTraversalConcept
|
||||
template <typename Iterator>
|
||||
struct RandomAccessIteratorIsMemoryBasedConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
std::ptrdiff_t bs = memunit_step(it);
|
||||
ignore_unused_variable_warning(bs);
|
||||
|
||||
it = memunit_advanced(it, 3);
|
||||
std::ptrdiff_t bd = memunit_distance(it, it);
|
||||
ignore_unused_variable_warning(bd);
|
||||
|
||||
memunit_advance(it,3);
|
||||
// for performace you may also provide a customized implementation of memunit_advanced_ref
|
||||
}
|
||||
Iterator it;
|
||||
};
|
||||
|
||||
/// \tparam Iterator Models PixelIteratorConcept
|
||||
template <typename Iterator>
|
||||
struct PixelIteratorIsMutableConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<Iterator>>();
|
||||
|
||||
using ref_t = typename remove_reference
|
||||
<
|
||||
typename std::iterator_traits<Iterator>::reference
|
||||
>::type;
|
||||
using channel_t = typename element_type<ref_t>::type;
|
||||
gil_function_requires<detail::ChannelIsMutableConcept<channel_t>>();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \ingroup PixelLocatorConcept
|
||||
/// \brief Concept for locators and views that can define a type just like the given locator or view, except X and Y is swapped
|
||||
/// \code
|
||||
/// concept HasTransposedTypeConcept<typename T>
|
||||
/// {
|
||||
/// typename transposed_type<T>;
|
||||
/// where Metafunction<transposed_type<T> >;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename T>
|
||||
struct HasTransposedTypeConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
using type = typename transposed_type<T>::type;
|
||||
ignore_unused_variable_warning(type{});
|
||||
}
|
||||
};
|
||||
|
||||
/// \defgroup PixelIteratorConceptPixelIterator PixelIteratorConcept
|
||||
/// \ingroup PixelIteratorConcept
|
||||
/// \brief STL iterator over pixels
|
||||
|
||||
/// \ingroup PixelIteratorConceptPixelIterator
|
||||
/// \brief An STL random access traversal iterator over a model of PixelConcept.
|
||||
///
|
||||
/// GIL's iterators must also provide the following metafunctions:
|
||||
/// - \p const_iterator_type<Iterator>: Returns a read-only equivalent of \p Iterator
|
||||
/// - \p iterator_is_mutable<Iterator>: Returns whether the given iterator is read-only or mutable
|
||||
/// - \p is_iterator_adaptor<Iterator>: Returns whether the given iterator is an adaptor over another iterator. See IteratorAdaptorConcept for additional requirements of adaptors.
|
||||
///
|
||||
/// \code
|
||||
/// concept PixelIteratorConcept<typename Iterator>
|
||||
/// : boost_concepts::RandomAccessTraversalConcept<Iterator>, PixelBasedConcept<Iterator>
|
||||
/// {
|
||||
/// where PixelValueConcept<value_type>;
|
||||
/// typename const_iterator_type<It>::type;
|
||||
/// where PixelIteratorConcept<const_iterator_type<It>::type>;
|
||||
/// static const bool iterator_is_mutable<It>::value;
|
||||
/// static const bool is_iterator_adaptor<It>::value; // is it an iterator adaptor
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename Iterator>
|
||||
struct PixelIteratorConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<Iterator>>();
|
||||
gil_function_requires<PixelBasedConcept<Iterator>>();
|
||||
|
||||
using value_type = typename std::iterator_traits<Iterator>::value_type;
|
||||
gil_function_requires<PixelValueConcept<value_type>>();
|
||||
|
||||
using const_t = typename const_iterator_type<Iterator>::type;
|
||||
static bool const is_mutable = iterator_is_mutable<Iterator>::value;
|
||||
ignore_unused_variable_warning(is_mutable);
|
||||
|
||||
// immutable iterator must be constructible from (possibly mutable) iterator
|
||||
const_t const_it(it);
|
||||
ignore_unused_variable_warning(const_it);
|
||||
|
||||
check_base(typename is_iterator_adaptor<Iterator>::type());
|
||||
}
|
||||
|
||||
void check_base(mpl::false_) {}
|
||||
|
||||
void check_base(mpl::true_)
|
||||
{
|
||||
using base_t = typename iterator_adaptor_get_base<Iterator>::type;
|
||||
gil_function_requires<PixelIteratorConcept<base_t>>();
|
||||
}
|
||||
|
||||
Iterator it;
|
||||
};
|
||||
|
||||
/// \brief Pixel iterator that allows for changing its pixel
|
||||
/// \ingroup PixelIteratorConceptPixelIterator
|
||||
/// \code
|
||||
/// concept MutablePixelIteratorConcept<PixelIteratorConcept Iterator>
|
||||
/// : MutableRandomAccessIteratorConcept<Iterator> {};
|
||||
/// \endcode
|
||||
template <typename Iterator>
|
||||
struct MutablePixelIteratorConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<PixelIteratorConcept<Iterator>>();
|
||||
gil_function_requires<detail::PixelIteratorIsMutableConcept<Iterator>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \defgroup PixelIteratorConceptStepIterator StepIteratorConcept
|
||||
/// \ingroup PixelIteratorConcept
|
||||
/// \brief Iterator that advances by a specified step
|
||||
|
||||
/// \ingroup PixelIteratorConceptStepIterator
|
||||
/// \brief Concept of a random-access iterator that can be advanced in memory units (bytes or bits)
|
||||
/// \code
|
||||
/// concept MemoryBasedIteratorConcept<boost_concepts::RandomAccessTraversalConcept Iterator>
|
||||
/// {
|
||||
/// typename byte_to_memunit<Iterator>; where metafunction<byte_to_memunit<Iterator> >;
|
||||
/// std::ptrdiff_t memunit_step(const Iterator&);
|
||||
/// std::ptrdiff_t memunit_distance(const Iterator& , const Iterator&);
|
||||
/// void memunit_advance(Iterator&, std::ptrdiff_t diff);
|
||||
/// Iterator memunit_advanced(const Iterator& p, std::ptrdiff_t diff) { Iterator tmp; memunit_advance(tmp,diff); return tmp; }
|
||||
/// Iterator::reference memunit_advanced_ref(const Iterator& p, std::ptrdiff_t diff) { return *memunit_advanced(p,diff); }
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename Iterator>
|
||||
struct MemoryBasedIteratorConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<Iterator>>();
|
||||
gil_function_requires<detail::RandomAccessIteratorIsMemoryBasedConcept<Iterator>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup PixelIteratorConceptStepIterator
|
||||
/// \brief Step iterator concept
|
||||
///
|
||||
/// Step iterators are iterators that have a set_step method
|
||||
/// \code
|
||||
/// concept StepIteratorConcept<boost_concepts::ForwardTraversalConcept Iterator>
|
||||
/// {
|
||||
/// template <Integral D>
|
||||
/// void Iterator::set_step(D step);
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename Iterator>
|
||||
struct StepIteratorConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<boost_concepts::ForwardTraversalConcept<Iterator>>();
|
||||
it.set_step(0);
|
||||
}
|
||||
Iterator it;
|
||||
};
|
||||
|
||||
|
||||
/// \ingroup PixelIteratorConceptStepIterator
|
||||
/// \brief Step iterator that allows for modifying its current value
|
||||
/// \code
|
||||
/// concept MutableStepIteratorConcept<Mutable_ForwardIteratorConcept Iterator>
|
||||
/// : StepIteratorConcept<Iterator> {};
|
||||
/// \endcode
|
||||
template <typename Iterator>
|
||||
struct MutableStepIteratorConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<StepIteratorConcept<Iterator>>();
|
||||
gil_function_requires<detail::ForwardIteratorIsMutableConcept<Iterator>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \defgroup PixelIteratorConceptIteratorAdaptor IteratorAdaptorConcept
|
||||
/// \ingroup PixelIteratorConcept
|
||||
/// \brief Adaptor over another iterator
|
||||
|
||||
/// \ingroup PixelIteratorConceptIteratorAdaptor
|
||||
/// \brief Iterator adaptor is a forward iterator adapting another forward iterator.
|
||||
///
|
||||
/// In addition to GIL iterator requirements,
|
||||
/// GIL iterator adaptors must provide the following metafunctions:
|
||||
/// - \p is_iterator_adaptor<Iterator>: Returns \p mpl::true_
|
||||
/// - \p iterator_adaptor_get_base<Iterator>: Returns the base iterator type
|
||||
/// - \p iterator_adaptor_rebind<Iterator,NewBase>: Replaces the base iterator with the new one
|
||||
///
|
||||
/// The adaptee can be obtained from the iterator via the "base()" method.
|
||||
///
|
||||
/// \code
|
||||
/// concept IteratorAdaptorConcept<boost_concepts::ForwardTraversalConcept Iterator>
|
||||
/// {
|
||||
/// where SameType<is_iterator_adaptor<Iterator>::type, mpl::true_>;
|
||||
///
|
||||
/// typename iterator_adaptor_get_base<Iterator>;
|
||||
/// where Metafunction<iterator_adaptor_get_base<Iterator> >;
|
||||
/// where boost_concepts::ForwardTraversalConcept<iterator_adaptor_get_base<Iterator>::type>;
|
||||
///
|
||||
/// typename another_iterator;
|
||||
/// typename iterator_adaptor_rebind<Iterator,another_iterator>::type;
|
||||
/// where boost_concepts::ForwardTraversalConcept<another_iterator>;
|
||||
/// where IteratorAdaptorConcept<iterator_adaptor_rebind<Iterator,another_iterator>::type>;
|
||||
///
|
||||
/// const iterator_adaptor_get_base<Iterator>::type& Iterator::base() const;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename Iterator>
|
||||
struct IteratorAdaptorConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<boost_concepts::ForwardTraversalConcept<Iterator>>();
|
||||
|
||||
using base_t = typename iterator_adaptor_get_base<Iterator>::type;
|
||||
gil_function_requires<boost_concepts::ForwardTraversalConcept<base_t>>();
|
||||
|
||||
static_assert(is_iterator_adaptor<Iterator>::value, "");
|
||||
using rebind_t = typename iterator_adaptor_rebind<Iterator, void*>::type;
|
||||
|
||||
base_t base = it.base();
|
||||
ignore_unused_variable_warning(base);
|
||||
}
|
||||
Iterator it;
|
||||
};
|
||||
|
||||
/// \brief Iterator adaptor that is mutable
|
||||
/// \ingroup PixelIteratorConceptIteratorAdaptor
|
||||
/// \code
|
||||
/// concept MutableIteratorAdaptorConcept<Mutable_ForwardIteratorConcept Iterator>
|
||||
/// : IteratorAdaptorConcept<Iterator> {};
|
||||
/// \endcode
|
||||
template <typename Iterator>
|
||||
struct MutableIteratorAdaptorConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<IteratorAdaptorConcept<Iterator>>();
|
||||
gil_function_requires<detail::ForwardIteratorIsMutableConcept<Iterator>>();
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
408
linx64/include/boost/gil/concepts/pixel_locator.hpp
Normal file
408
linx64/include/boost/gil/concepts/pixel_locator.hpp
Normal file
@@ -0,0 +1,408 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_PIXEL_LOCATOR_HPP
|
||||
#define BOOST_GIL_CONCEPTS_PIXEL_LOCATOR_HPP
|
||||
|
||||
#include <boost/gil/concepts/basic.hpp>
|
||||
#include <boost/gil/concepts/concept_check.hpp>
|
||||
#include <boost/gil/concepts/fwd.hpp>
|
||||
#include <boost/gil/concepts/pixel_dereference.hpp>
|
||||
#include <boost/gil/concepts/pixel_iterator.hpp>
|
||||
#include <boost/gil/concepts/point.hpp>
|
||||
#include <boost/gil/concepts/detail/utility.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \defgroup LocatorNDConcept RandomAccessNDLocatorConcept
|
||||
/// \ingroup PixelLocatorConcept
|
||||
/// \brief N-dimensional locator
|
||||
|
||||
/// \defgroup Locator2DConcept RandomAccess2DLocatorConcept
|
||||
/// \ingroup PixelLocatorConcept
|
||||
/// \brief 2-dimensional locator
|
||||
|
||||
/// \defgroup PixelLocator2DConcept PixelLocatorConcept
|
||||
/// \ingroup PixelLocatorConcept
|
||||
/// \brief 2-dimensional locator over pixel data
|
||||
|
||||
/// \ingroup LocatorNDConcept
|
||||
/// \brief N-dimensional locator over immutable values
|
||||
///
|
||||
/// \code
|
||||
/// concept RandomAccessNDLocatorConcept<Regular Loc>
|
||||
/// {
|
||||
/// typename value_type; // value over which the locator navigates
|
||||
/// typename reference; // result of dereferencing
|
||||
/// typename difference_type; where PointNDConcept<difference_type>; // return value of operator-.
|
||||
/// typename const_t; // same as Loc, but operating over immutable values
|
||||
/// typename cached_location_t; // type to store relative location (for efficient repeated access)
|
||||
/// typename point_t = difference_type;
|
||||
///
|
||||
/// static const size_t num_dimensions; // dimensionality of the locator
|
||||
/// where num_dimensions = point_t::num_dimensions;
|
||||
///
|
||||
/// // The difference_type and iterator type along each dimension. The iterators may only differ in
|
||||
/// // difference_type. Their value_type must be the same as Loc::value_type
|
||||
/// template <size_t D>
|
||||
/// struct axis
|
||||
/// {
|
||||
/// typename coord_t = point_t::axis<D>::coord_t;
|
||||
/// typename iterator; where RandomAccessTraversalConcept<iterator>; // iterator along D-th axis.
|
||||
/// where iterator::value_type == value_type;
|
||||
/// };
|
||||
///
|
||||
/// // Defines the type of a locator similar to this type, except it invokes Deref upon dereferencing
|
||||
/// template <PixelDereferenceAdaptorConcept Deref>
|
||||
/// struct add_deref
|
||||
/// {
|
||||
/// typename type;
|
||||
/// where RandomAccessNDLocatorConcept<type>;
|
||||
/// static type make(const Loc& loc, const Deref& deref);
|
||||
/// };
|
||||
///
|
||||
/// Loc& operator+=(Loc&, const difference_type&);
|
||||
/// Loc& operator-=(Loc&, const difference_type&);
|
||||
/// Loc operator+(const Loc&, const difference_type&);
|
||||
/// Loc operator-(const Loc&, const difference_type&);
|
||||
///
|
||||
/// reference operator*(const Loc&);
|
||||
/// reference operator[](const Loc&, const difference_type&);
|
||||
///
|
||||
/// // Storing relative location for faster repeated access and accessing it
|
||||
/// cached_location_t Loc::cache_location(const difference_type&) const;
|
||||
/// reference operator[](const Loc&,const cached_location_t&);
|
||||
///
|
||||
/// // Accessing iterators along a given dimension at the current location or at a given offset
|
||||
/// template <size_t D> axis<D>::iterator& Loc::axis_iterator();
|
||||
/// template <size_t D> axis<D>::iterator const& Loc::axis_iterator() const;
|
||||
/// template <size_t D> axis<D>::iterator Loc::axis_iterator(const difference_type&) const;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename Loc>
|
||||
struct RandomAccessNDLocatorConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<Regular<Loc>>();
|
||||
|
||||
// TODO: Should these be concept-checked instead of ignored? --mloskot
|
||||
|
||||
using value_type = typename Loc::value_type;
|
||||
ignore_unused_variable_warning(value_type{});
|
||||
|
||||
// result of dereferencing
|
||||
using reference = typename Loc::reference;
|
||||
//ignore_unused_variable_warning(reference{});
|
||||
|
||||
// result of operator-(pixel_locator, pixel_locator)
|
||||
using difference_type = typename Loc::difference_type;
|
||||
ignore_unused_variable_warning(difference_type{});
|
||||
|
||||
// type used to store relative location (to allow for more efficient repeated access)
|
||||
using cached_location_t = typename Loc::cached_location_t;
|
||||
ignore_unused_variable_warning(cached_location_t{});
|
||||
|
||||
// same as this type, but over const values
|
||||
using const_t = typename Loc::const_t;
|
||||
ignore_unused_variable_warning(const_t{});
|
||||
|
||||
// same as difference_type
|
||||
using point_t = typename Loc::point_t;
|
||||
ignore_unused_variable_warning(point_t{});
|
||||
|
||||
static std::size_t const N = Loc::num_dimensions; ignore_unused_variable_warning(N);
|
||||
|
||||
using first_it_type = typename Loc::template axis<0>::iterator;
|
||||
using last_it_type = typename Loc::template axis<N-1>::iterator;
|
||||
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type>>();
|
||||
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type>>();
|
||||
|
||||
// point_t must be an N-dimensional point, each dimension of which must
|
||||
// have the same type as difference_type of the corresponding iterator
|
||||
gil_function_requires<PointNDConcept<point_t>>();
|
||||
static_assert(point_t::num_dimensions == N, "");
|
||||
static_assert(is_same
|
||||
<
|
||||
typename std::iterator_traits<first_it_type>::difference_type,
|
||||
typename point_t::template axis<0>::coord_t
|
||||
>::value, "");
|
||||
static_assert(is_same
|
||||
<
|
||||
typename std::iterator_traits<last_it_type>::difference_type,
|
||||
typename point_t::template axis<N-1>::coord_t
|
||||
>::value, "");
|
||||
|
||||
difference_type d;
|
||||
loc += d;
|
||||
loc -= d;
|
||||
loc = loc + d;
|
||||
loc = loc - d;
|
||||
reference r1 = loc[d]; ignore_unused_variable_warning(r1);
|
||||
reference r2 = *loc; ignore_unused_variable_warning(r2);
|
||||
cached_location_t cl = loc.cache_location(d); ignore_unused_variable_warning(cl);
|
||||
reference r3 = loc[d]; ignore_unused_variable_warning(r3);
|
||||
|
||||
first_it_type fi = loc.template axis_iterator<0>();
|
||||
fi = loc.template axis_iterator<0>(d);
|
||||
last_it_type li = loc.template axis_iterator<N-1>();
|
||||
li = loc.template axis_iterator<N-1>(d);
|
||||
|
||||
using deref_t = PixelDereferenceAdaptorArchetype<typename Loc::value_type>;
|
||||
using dtype = typename Loc::template add_deref<deref_t>::type;
|
||||
// TODO: infinite recursion - FIXME?
|
||||
//gil_function_requires<RandomAccessNDLocatorConcept<dtype>>();
|
||||
}
|
||||
Loc loc;
|
||||
};
|
||||
|
||||
/// \ingroup Locator2DConcept
|
||||
/// \brief 2-dimensional locator over immutable values
|
||||
///
|
||||
/// \code
|
||||
/// concept RandomAccess2DLocatorConcept<RandomAccessNDLocatorConcept Loc>
|
||||
/// {
|
||||
/// where num_dimensions==2;
|
||||
/// where Point2DConcept<point_t>;
|
||||
///
|
||||
/// typename x_iterator = axis<0>::iterator;
|
||||
/// typename y_iterator = axis<1>::iterator;
|
||||
/// typename x_coord_t = axis<0>::coord_t;
|
||||
/// typename y_coord_t = axis<1>::coord_t;
|
||||
///
|
||||
/// // Only available to locators that have dynamic step in Y
|
||||
/// //Loc::Loc(const Loc& loc, y_coord_t);
|
||||
///
|
||||
/// // Only available to locators that have dynamic step in X and Y
|
||||
/// //Loc::Loc(const Loc& loc, x_coord_t, y_coord_t, bool transposed=false);
|
||||
///
|
||||
/// x_iterator& Loc::x();
|
||||
/// x_iterator const& Loc::x() const;
|
||||
/// y_iterator& Loc::y();
|
||||
/// y_iterator const& Loc::y() const;
|
||||
///
|
||||
/// x_iterator Loc::x_at(const difference_type&) const;
|
||||
/// y_iterator Loc::y_at(const difference_type&) const;
|
||||
/// Loc Loc::xy_at(const difference_type&) const;
|
||||
///
|
||||
/// // x/y versions of all methods that can take difference type
|
||||
/// x_iterator Loc::x_at(x_coord_t, y_coord_t) const;
|
||||
/// y_iterator Loc::y_at(x_coord_t, y_coord_t) const;
|
||||
/// Loc Loc::xy_at(x_coord_t, y_coord_t) const;
|
||||
/// reference operator()(const Loc&, x_coord_t, y_coord_t);
|
||||
/// cached_location_t Loc::cache_location(x_coord_t, y_coord_t) const;
|
||||
///
|
||||
/// bool Loc::is_1d_traversable(x_coord_t width) const;
|
||||
/// y_coord_t Loc::y_distance_to(const Loc& loc2, x_coord_t x_diff) const;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename Loc>
|
||||
struct RandomAccess2DLocatorConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<RandomAccessNDLocatorConcept<Loc>>();
|
||||
static_assert(Loc::num_dimensions == 2, "");
|
||||
|
||||
using dynamic_x_step_t = typename dynamic_x_step_type<Loc>::type;
|
||||
using dynamic_y_step_t = typename dynamic_y_step_type<Loc>::type;
|
||||
using transposed_t = typename transposed_type<Loc>::type;
|
||||
|
||||
using cached_location_t = typename Loc::cached_location_t;
|
||||
gil_function_requires<Point2DConcept<typename Loc::point_t>>();
|
||||
|
||||
using x_iterator = typename Loc::x_iterator;
|
||||
using y_iterator = typename Loc::y_iterator;
|
||||
using x_coord_t = typename Loc::x_coord_t;
|
||||
using y_coord_t = typename Loc::y_coord_t;
|
||||
|
||||
x_coord_t xd = 0; ignore_unused_variable_warning(xd);
|
||||
y_coord_t yd = 0; ignore_unused_variable_warning(yd);
|
||||
|
||||
typename Loc::difference_type d;
|
||||
typename Loc::reference r=loc(xd,yd); ignore_unused_variable_warning(r);
|
||||
|
||||
dynamic_x_step_t loc2(dynamic_x_step_t(), yd);
|
||||
dynamic_x_step_t loc3(dynamic_x_step_t(), xd, yd);
|
||||
|
||||
using dynamic_xy_step_transposed_t = typename dynamic_y_step_type
|
||||
<
|
||||
typename dynamic_x_step_type<transposed_t>::type
|
||||
>::type;
|
||||
dynamic_xy_step_transposed_t loc4(loc, xd,yd,true);
|
||||
|
||||
bool is_contiguous = loc.is_1d_traversable(xd);
|
||||
ignore_unused_variable_warning(is_contiguous);
|
||||
|
||||
loc.y_distance_to(loc, xd);
|
||||
|
||||
loc = loc.xy_at(d);
|
||||
loc = loc.xy_at(xd, yd);
|
||||
|
||||
x_iterator xit = loc.x_at(d);
|
||||
xit = loc.x_at(xd, yd);
|
||||
xit = loc.x();
|
||||
|
||||
y_iterator yit = loc.y_at(d);
|
||||
yit = loc.y_at(xd, yd);
|
||||
yit = loc.y();
|
||||
|
||||
cached_location_t cl = loc.cache_location(xd, yd);
|
||||
ignore_unused_variable_warning(cl);
|
||||
}
|
||||
Loc loc;
|
||||
};
|
||||
|
||||
/// \ingroup PixelLocator2DConcept
|
||||
/// \brief GIL's 2-dimensional locator over immutable GIL pixels
|
||||
/// \code
|
||||
/// concept PixelLocatorConcept<RandomAccess2DLocatorConcept Loc>
|
||||
/// {
|
||||
/// where PixelValueConcept<value_type>;
|
||||
/// where PixelIteratorConcept<x_iterator>;
|
||||
/// where PixelIteratorConcept<y_iterator>;
|
||||
/// where x_coord_t == y_coord_t;
|
||||
///
|
||||
/// typename coord_t = x_coord_t;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename Loc>
|
||||
struct PixelLocatorConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<RandomAccess2DLocatorConcept<Loc>>();
|
||||
gil_function_requires<PixelIteratorConcept<typename Loc::x_iterator>>();
|
||||
gil_function_requires<PixelIteratorConcept<typename Loc::y_iterator>>();
|
||||
using coord_t = typename Loc::coord_t;
|
||||
static_assert(is_same<typename Loc::x_coord_t, typename Loc::y_coord_t>::value, "");
|
||||
}
|
||||
Loc loc;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
/// \tparam Loc Models RandomAccessNDLocatorConcept
|
||||
template <typename Loc>
|
||||
struct RandomAccessNDLocatorIsMutableConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
|
||||
<
|
||||
typename Loc::template axis<0>::iterator
|
||||
>>();
|
||||
gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
|
||||
<
|
||||
typename Loc::template axis<Loc::num_dimensions-1>::iterator
|
||||
>>();
|
||||
|
||||
typename Loc::difference_type d; initialize_it(d);
|
||||
typename Loc::value_type v; initialize_it(v);
|
||||
typename Loc::cached_location_t cl = loc.cache_location(d);
|
||||
*loc = v;
|
||||
loc[d] = v;
|
||||
loc[cl] = v;
|
||||
}
|
||||
Loc loc;
|
||||
};
|
||||
|
||||
// \tparam Loc Models RandomAccess2DLocatorConcept
|
||||
template <typename Loc>
|
||||
struct RandomAccess2DLocatorIsMutableConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc>>();
|
||||
typename Loc::x_coord_t xd = 0; ignore_unused_variable_warning(xd);
|
||||
typename Loc::y_coord_t yd = 0; ignore_unused_variable_warning(yd);
|
||||
typename Loc::value_type v; initialize_it(v);
|
||||
loc(xd, yd) = v;
|
||||
}
|
||||
Loc loc;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \ingroup LocatorNDConcept
|
||||
/// \brief N-dimensional locator over mutable pixels
|
||||
///
|
||||
/// \code
|
||||
/// concept MutableRandomAccessNDLocatorConcept<RandomAccessNDLocatorConcept Loc>
|
||||
/// {
|
||||
/// where Mutable<reference>;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename Loc>
|
||||
struct MutableRandomAccessNDLocatorConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<RandomAccessNDLocatorConcept<Loc>>();
|
||||
gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup Locator2DConcept
|
||||
/// \brief 2-dimensional locator over mutable pixels
|
||||
///
|
||||
/// \code
|
||||
/// concept MutableRandomAccess2DLocatorConcept<RandomAccess2DLocatorConcept Loc>
|
||||
/// : MutableRandomAccessNDLocatorConcept<Loc> {};
|
||||
/// \endcode
|
||||
template <typename Loc>
|
||||
struct MutableRandomAccess2DLocatorConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<RandomAccess2DLocatorConcept<Loc>>();
|
||||
gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc>>();
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup PixelLocator2DConcept
|
||||
/// \brief GIL's 2-dimensional locator over mutable GIL pixels
|
||||
///
|
||||
/// \code
|
||||
/// concept MutablePixelLocatorConcept<PixelLocatorConcept Loc>
|
||||
/// : MutableRandomAccess2DLocatorConcept<Loc> {};
|
||||
/// \endcode
|
||||
template <typename Loc>
|
||||
struct MutablePixelLocatorConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<PixelLocatorConcept<Loc>>();
|
||||
gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc>>();
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
124
linx64/include/boost/gil/concepts/point.hpp
Normal file
124
linx64/include/boost/gil/concepts/point.hpp
Normal file
@@ -0,0 +1,124 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_CONCEPTS_POINT_HPP
|
||||
#define BOOST_GIL_CONCEPTS_POINT_HPP
|
||||
|
||||
#include <boost/gil/concepts/basic.hpp>
|
||||
#include <boost/gil/concepts/concept_check.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
// Forward declarations
|
||||
template <typename T>
|
||||
class point;
|
||||
|
||||
template <std::size_t K, typename T>
|
||||
T const& axis_value(point<T> const& p);
|
||||
|
||||
template <std::size_t K, typename T>
|
||||
T& axis_value(point<T>& p);
|
||||
|
||||
/// \brief N-dimensional point concept
|
||||
/// \code
|
||||
/// concept PointNDConcept<typename T> : Regular<T>
|
||||
/// {
|
||||
/// // the type of a coordinate along each axis
|
||||
/// template <size_t K>
|
||||
/// struct axis; where Metafunction<axis>;
|
||||
///
|
||||
/// const size_t num_dimensions;
|
||||
///
|
||||
/// // accessor/modifier of the value of each axis.
|
||||
///
|
||||
/// template <size_t K>
|
||||
/// typename axis<K>::type const& T::axis_value() const;
|
||||
///
|
||||
/// template <size_t K>
|
||||
/// typename axis<K>::type& T::axis_value();
|
||||
/// };
|
||||
/// \endcode
|
||||
/// \ingroup PointConcept
|
||||
///
|
||||
template <typename P>
|
||||
struct PointNDConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<Regular<P>>();
|
||||
|
||||
using value_type = typename P::value_type;
|
||||
ignore_unused_variable_warning(value_type{});
|
||||
|
||||
static const std::size_t N = P::num_dimensions;
|
||||
ignore_unused_variable_warning(N);
|
||||
using FT = typename P::template axis<0>::coord_t;
|
||||
using LT = typename P::template axis<N - 1>::coord_t;
|
||||
FT ft = gil::axis_value<0>(point);
|
||||
axis_value<0>(point) = ft;
|
||||
LT lt = axis_value<N - 1>(point);
|
||||
axis_value<N - 1>(point) = lt;
|
||||
|
||||
//value_type v=point[0];
|
||||
//ignore_unused_variable_warning(v);
|
||||
}
|
||||
P point;
|
||||
};
|
||||
|
||||
/// \brief 2-dimensional point concept
|
||||
/// \code
|
||||
/// concept Point2DConcept<typename T> : PointNDConcept<T>
|
||||
/// {
|
||||
/// where num_dimensions == 2;
|
||||
/// where SameType<axis<0>::type, axis<1>::type>;
|
||||
///
|
||||
/// typename value_type = axis<0>::type;
|
||||
///
|
||||
/// value_type const& operator[](T const&, size_t i);
|
||||
/// value_type& operator[](T&, size_t i);
|
||||
///
|
||||
/// value_type x,y;
|
||||
/// };
|
||||
/// \endcode
|
||||
/// \ingroup PointConcept
|
||||
///
|
||||
template <typename P>
|
||||
struct Point2DConcept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
gil_function_requires<PointNDConcept<P>>();
|
||||
static_assert(P::num_dimensions == 2, "");
|
||||
point.x = point.y;
|
||||
point[0] = point[1];
|
||||
}
|
||||
P point;
|
||||
};
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,32 +1,18 @@
|
||||
/*
|
||||
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
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_DEPRECATED_HPP
|
||||
#define BOOST_GIL_DEPRECATED_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
/// 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.
|
||||
|
||||
#define planar_ptr planar_pixel_iterator
|
||||
#define planar_ref planar_pixel_reference
|
||||
#define membased_2d_locator memory_based_2d_locator
|
||||
|
||||
@@ -1,33 +1,22 @@
|
||||
/*
|
||||
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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_DEVICE_N_HPP
|
||||
#define BOOST_GIL_DEVICE_N_HPP
|
||||
|
||||
See http://stlab.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#include <boost/gil/metafunctions.hpp>
|
||||
#include <boost/gil/utilities.hpp>
|
||||
|
||||
#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-2009 \n Last updated on February 20, 2009
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <cstddef>
|
||||
#include "gil_config.hpp"
|
||||
#include "utilities.hpp"
|
||||
#include "metafunctions.hpp"
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/mpl/range_c.hpp>
|
||||
#include <boost/mpl/vector_c.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
@@ -64,36 +53,40 @@ 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;
|
||||
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)
|
||||
{
|
||||
using view_t = typename type_from_x_iterator<planar_pixel_iterator<IC,devicen_t<2>>>::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;
|
||||
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)
|
||||
{
|
||||
using view_t = typename type_from_x_iterator<planar_pixel_iterator<IC,devicen_t<3>>>::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;
|
||||
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)
|
||||
{
|
||||
using view_t = typename type_from_x_iterator<planar_pixel_iterator<IC,devicen_t<4>>>::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;
|
||||
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)
|
||||
{
|
||||
using view_t = typename type_from_x_iterator<planar_pixel_iterator<IC,devicen_t<5>>>::view_t;
|
||||
return view_t(width, height, typename view_t::locator(typename view_t::x_iterator(c0,c1,c2,c3,c4), rowsize_in_bytes));
|
||||
}
|
||||
|
||||
|
||||
31
linx64/include/boost/gil/dynamic_step.hpp
Normal file
31
linx64/include/boost/gil/dynamic_step.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_DYNAMIC_STEP_HPP
|
||||
#define BOOST_GIL_DYNAMIC_STEP_HPP
|
||||
|
||||
#include <boost/gil/concepts/dynamic_step.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// Base template for types that model HasDynamicXStepTypeConcept.
|
||||
template <typename IteratorOrLocatorOrView>
|
||||
struct dynamic_x_step_type;
|
||||
|
||||
/// Base template for types that model HasDynamicYStepTypeConcept.
|
||||
template <typename LocatorOrView>
|
||||
struct dynamic_y_step_type;
|
||||
|
||||
/// Base template for types that model both, HasDynamicXStepTypeConcept and HasDynamicYStepTypeConcept.
|
||||
///
|
||||
/// \todo TODO: Is Locator allowed or practical to occur?
|
||||
template <typename View>
|
||||
struct dynamic_xy_step_type;
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#endif
|
||||
@@ -1,23 +1,21 @@
|
||||
/*
|
||||
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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_EXTENSION_DYNAMIC_IMAGE_ALGORITHM_HPP
|
||||
#define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_ALGORITHM_HPP
|
||||
|
||||
See http://opensource.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#include <boost/gil/extension/dynamic_image/any_image.hpp>
|
||||
|
||||
#ifndef GIL_DYNAMICIMAGE_ALGORITHM_HPP
|
||||
#define GIL_DYNAMICIMAGE_ALGORITHM_HPP
|
||||
#include <boost/gil/algorithm.hpp>
|
||||
|
||||
#include "../../algorithm.hpp"
|
||||
#include "any_image.hpp"
|
||||
#include <boost/bind.hpp>
|
||||
#include <functional>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \file
|
||||
/// \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
|
||||
@@ -28,146 +26,210 @@
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
struct equal_pixels_fn : binary_operation_obj<equal_pixels_fn, bool>
|
||||
{
|
||||
template <typename V1, typename V2>
|
||||
BOOST_FORCEINLINE
|
||||
bool apply_compatible(V1 const& v1, V2 const& 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));
|
||||
/// \tparam Types Model MPL Random Access Container of models of ImageViewConcept
|
||||
/// \tparam View Model MutableImageViewConcept
|
||||
template <typename Types, typename View>
|
||||
bool equal_pixels(any_image_view<Types> const& src, View const& dst)
|
||||
{
|
||||
return apply_operation(
|
||||
src,
|
||||
std::bind(detail::equal_pixels_fn(), std::placeholders::_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));
|
||||
/// \tparam View Model ImageViewConcept
|
||||
/// \tparam Types Model MPL Random Access Container of models of MutableImageViewConcept
|
||||
template <typename View, typename Types>
|
||||
bool equal_pixels(View const& src, any_image_view<Types> const& dst)
|
||||
{
|
||||
return apply_operation(
|
||||
dst,
|
||||
std::bind(detail::equal_pixels_fn(), src, std::placeholders::_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());
|
||||
/// \tparam Types1 Model MPL Random Access Container of models of ImageViewConcept
|
||||
/// \tparam Types2 Model MPL Random Access Container of models of MutableImageViewConcept
|
||||
template <typename Types1, typename Types2>
|
||||
bool equal_pixels(any_image_view<Types1> const& src, any_image_view<Types2> const& 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);
|
||||
}
|
||||
};
|
||||
|
||||
struct copy_pixels_fn : public binary_operation_obj<copy_pixels_fn>
|
||||
{
|
||||
template <typename View1, typename View2>
|
||||
BOOST_FORCEINLINE
|
||||
void apply_compatible(View1 const& src, View2 const& dst) const
|
||||
{
|
||||
copy_pixels(src,dst);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \ingroup ImageViewSTLAlgorithmsCopyPixels
|
||||
/// \tparam Types Model MPL Random Access Container of models of ImageViewConcept
|
||||
/// \tparam View Model MutableImageViewConcept
|
||||
template <typename Types, typename View>
|
||||
void copy_pixels(any_image_view<Types> const& src, View const& dst)
|
||||
{
|
||||
apply_operation(src, std::bind(detail::copy_pixels_fn(), std::placeholders::_1, 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));
|
||||
/// \tparam Types Model MPL Random Access Container of models of MutableImageViewConcept
|
||||
/// \tparam View Model ImageViewConcept
|
||||
template <typename Types, typename View>
|
||||
void copy_pixels(View const& src, any_image_view<Types> const& dst)
|
||||
{
|
||||
apply_operation(dst, std::bind(detail::copy_pixels_fn(), src, std::placeholders::_1));
|
||||
}
|
||||
|
||||
/// \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));
|
||||
/// \tparam Types1 Model MPL Random Access Container of models of ImageViewConcept
|
||||
/// \tparam Types2 Model MPL Random Access Container of models of MutableImageViewConcept
|
||||
template <typename Types1, typename Types2>
|
||||
void copy_pixels(any_image_view<Types1> const& src, any_image_view<Types2> const& dst)
|
||||
{
|
||||
apply_operation(src, dst, detail::copy_pixels_fn());
|
||||
}
|
||||
|
||||
/// \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));
|
||||
/// \tparam Types Model MPL Random Access Container of models of ImageViewConcept
|
||||
/// \tparam View Model MutableImageViewConcept
|
||||
/// \tparam CC Model ColorConverterConcept
|
||||
template <typename Types, typename View, typename CC>
|
||||
void copy_and_convert_pixels(any_image_view<Types> const& src, View const& dst, CC cc)
|
||||
{
|
||||
using cc_fn = detail::copy_and_convert_pixels_fn<CC>;
|
||||
apply_operation(src, std::bind(cc_fn{cc}, std::placeholders::_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));
|
||||
/// \tparam Types Model MPL Random Access Container of models of ImageViewConcept
|
||||
/// \tparam View Model MutableImageViewConcept
|
||||
template <typename Types, typename View>
|
||||
void copy_and_convert_pixels(any_image_view<Types> const& src, View const& dst)
|
||||
{
|
||||
using cc_fn = detail::copy_and_convert_pixels_fn<default_color_converter>;
|
||||
apply_operation(src, std::bind(cc_fn{}, std::placeholders::_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));
|
||||
/// \tparam View Model ImageViewConcept
|
||||
/// \tparam Types Model MPL Random Access Container of models of MutableImageViewConcept
|
||||
/// \tparam CC Model ColorConverterConcept
|
||||
template <typename View, typename Types, typename CC>
|
||||
void copy_and_convert_pixels(View const& src, any_image_view<Types> const& dst, CC cc)
|
||||
{
|
||||
using cc_fn = detail::copy_and_convert_pixels_fn<CC>;
|
||||
apply_operation(dst, std::bind(cc_fn{cc}, src, std::placeholders::_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));
|
||||
/// \tparam View Model ImageViewConcept
|
||||
/// \tparam Type Model MPL Random Access Container of models of MutableImageViewConcept
|
||||
template <typename View, typename Types>
|
||||
void copy_and_convert_pixels(View const& src, any_image_view<Types> const& dst)
|
||||
{
|
||||
using cc_fn = detail::copy_and_convert_pixels_fn<default_color_converter>;
|
||||
apply_operation(dst, std::bind(cc_fn{}, src, std::placeholders::_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));
|
||||
/// \tparam Types1 Model MPL Random Access Container of models of ImageViewConcept
|
||||
/// \tparam Types2 Model MPL Random Access Container of models of MutableImageViewConcept
|
||||
/// \tparam CC Model ColorConverterConcept
|
||||
template <typename Types1, typename Types2, typename CC>
|
||||
void copy_and_convert_pixels(
|
||||
any_image_view<Types1> const& src,
|
||||
any_image_view<Types2> const& 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>());
|
||||
/// \tparam Types1 Model MPL Random Access Container of models of ImageViewConcept
|
||||
/// \tparam Types2 Model MPL Random Access Container of models of MutableImageViewConcept
|
||||
template <typename Types1, typename Types2>
|
||||
void copy_and_convert_pixels(
|
||||
any_image_view<Types1> const& src,
|
||||
any_image_view<Types2> const& 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); }
|
||||
|
||||
template <bool IsCompatible>
|
||||
struct fill_pixels_fn1
|
||||
{
|
||||
template <typename V, typename Value>
|
||||
static void apply(V const &src, Value const &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 <>
|
||||
struct fill_pixels_fn1<false>
|
||||
{
|
||||
template <typename V, typename Value>
|
||||
static void apply(V const &, Value const &) { throw std::bad_cast();}
|
||||
};
|
||||
|
||||
template <typename Value>
|
||||
struct fill_pixels_fn {
|
||||
fill_pixels_fn(const Value& val) : _val(val) {}
|
||||
struct fill_pixels_fn
|
||||
{
|
||||
fill_pixels_fn(Value const& 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);
|
||||
using result_type = void;
|
||||
template <typename V>
|
||||
result_type operator()(V const& view) const
|
||||
{
|
||||
fill_pixels_fn1
|
||||
<
|
||||
pixels_are_compatible
|
||||
<
|
||||
typename V::value_type,
|
||||
Value
|
||||
>::value
|
||||
>::apply(view, val_);
|
||||
}
|
||||
Value _val;
|
||||
|
||||
Value val_;
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \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));
|
||||
/// \tparam Types Model MPL Random Access Container of models of MutableImageViewConcept
|
||||
template <typename Types, typename Value>
|
||||
void fill_pixels(any_image_view<Types> const& view, Value const& val)
|
||||
{
|
||||
apply_operation(view, detail::fill_pixels_fn<Value>(val));
|
||||
}
|
||||
|
||||
|
||||
} } // namespace boost::gil
|
||||
}} // namespace boost::gil
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,61 +1,54 @@
|
||||
/*
|
||||
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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_EXTENSION_DYNAMIC_IMAGE_ANY_IMAGE_HPP
|
||||
#define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_ANY_IMAGE_HPP
|
||||
|
||||
See http://opensource.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#include <boost/gil/extension/dynamic_image/any_image_view.hpp>
|
||||
#include <boost/gil/extension/dynamic_image/apply_operation.hpp>
|
||||
|
||||
#ifndef GIL_DYNAMICIMAGE_ANY_IMAGE_HPP
|
||||
#define GIL_DYNAMICIMAGE_ANY_IMAGE_HPP
|
||||
#include <boost/gil/image.hpp>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \file
|
||||
/// \brief Support for run-time instantiated images and image views
|
||||
/// \author Lubomir Bourdev and Hailin Jin \n
|
||||
/// Adobe Systems Incorporated
|
||||
///
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#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
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
namespace detail {
|
||||
template <typename T> struct get_view_t { typedef typename T::view_t type; };
|
||||
template <typename T> struct get_view_t { using type = typename T::view_t; };
|
||||
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 T> struct get_const_view_t { using type = typename T::const_view_t; };
|
||||
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;
|
||||
struct recreate_image_fnobj
|
||||
{
|
||||
using result_type = void;
|
||||
point<std::ptrdiff_t> const& _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); }
|
||||
recreate_image_fnobj(point<std::ptrdiff_t> const& 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;
|
||||
using result_type = AnyView;
|
||||
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;
|
||||
using result_type = AnyConstView;
|
||||
template <typename Image> result_type operator()(const Image& img) const { return result_type(const_view(img)); }
|
||||
};
|
||||
}
|
||||
@@ -63,33 +56,42 @@ namespace detail {
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \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.
|
||||
/// Some of the requirements of ImageConcept, such as the \p value_type alias 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;
|
||||
class any_image : public make_variant_over<ImageTypes>::type {
|
||||
using parent_t = typename make_variant_over<ImageTypes>::type;
|
||||
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;
|
||||
using const_view_t = any_image_view<typename detail::images_get_const_views_t<ImageTypes>::type>;
|
||||
using view_t = any_image_view<typename detail::images_get_views_t<ImageTypes>::type>;
|
||||
using x_coord_t = std::ptrdiff_t;
|
||||
using y_coord_t = std::ptrdiff_t;
|
||||
using point_t = point<std::ptrdiff_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 Types> any_image(const any_image<Types>& v) : parent_t((const typename make_variant_over<Types>::type&)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;}
|
||||
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;}
|
||||
template <typename Types> any_image& operator=(const any_image<Types>& v) { parent_t::operator=((const typename make_variant_over<Types>::type&)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); }
|
||||
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({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()); }
|
||||
@@ -104,22 +106,22 @@ public:
|
||||
/// \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) {
|
||||
template <typename Types> BOOST_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) {
|
||||
template <typename Types> BOOST_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
|
||||
}} // namespace boost::gil
|
||||
|
||||
//#ifdef _MSC_VER
|
||||
//#pragma warning(pop)
|
||||
//#endif
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,48 +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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_EXTENSION_DYNAMIC_IMAGE_ANY_IMAGE_VIEW_HPP
|
||||
#define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_ANY_IMAGE_VIEW_HPP
|
||||
|
||||
See http://opensource.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
#include <boost/gil/dynamic_step.hpp>
|
||||
#include <boost/gil/image.hpp>
|
||||
#include <boost/gil/image_view.hpp>
|
||||
#include <boost/gil/point.hpp>
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#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"
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
namespace detail {
|
||||
template <typename View> struct get_const_t { typedef typename View::const_t type; };
|
||||
template <typename View> struct get_const_t { using type = typename View::const_t; };
|
||||
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; }
|
||||
|
||||
// works for both image_view and image
|
||||
struct any_type_get_num_channels
|
||||
{
|
||||
using result_type = int;
|
||||
template <typename T>
|
||||
result_type operator()(const T&) 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(); }
|
||||
|
||||
// works for both image_view and image
|
||||
struct any_type_get_dimensions
|
||||
{
|
||||
using result_type = point<std::ptrdiff_t>;
|
||||
template <typename T>
|
||||
result_type operator()(const T& v) const { return v.dimensions(); }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -54,27 +51,29 @@ namespace detail {
|
||||
///
|
||||
/// 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.
|
||||
/// Some of the requirements of ImageViewConcept, such as the \p value_type alias 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;
|
||||
class any_image_view : public make_variant_over<ImageViewTypes>::type {
|
||||
using parent_t = typename make_variant_over<ImageViewTypes>::type;
|
||||
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;
|
||||
using const_t = any_image_view<typename detail::views_get_const_t<ImageViewTypes>::type>;
|
||||
using x_coord_t = std::ptrdiff_t;
|
||||
using y_coord_t = std::ptrdiff_t;
|
||||
using point_t = point<std::ptrdiff_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 Types> any_image_view(const any_image_view<Types>& v) : parent_t((const typename make_variant_over<Types>::type&)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;}
|
||||
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;}
|
||||
template <typename Types> any_image_view& operator=(const any_image_view<Types>& v) { parent_t::operator=((const typename make_variant_over<Types>::type&)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()); }
|
||||
@@ -87,8 +86,9 @@ public:
|
||||
/////////////////////////////
|
||||
|
||||
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;
|
||||
struct dynamic_x_step_type<any_image_view<IVTypes>>
|
||||
{
|
||||
using type = any_image_view<typename mpl::transform<IVTypes, dynamic_x_step_type<mpl::_1>>::type>;
|
||||
};
|
||||
|
||||
/////////////////////////////
|
||||
@@ -96,20 +96,23 @@ struct dynamic_x_step_type<any_image_view<IVTypes> > {
|
||||
/////////////////////////////
|
||||
|
||||
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;
|
||||
struct dynamic_y_step_type<any_image_view<IVTypes>>
|
||||
{
|
||||
using type = any_image_view<typename mpl::transform<IVTypes, dynamic_y_step_type<mpl::_1>>::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;
|
||||
struct dynamic_xy_step_type<any_image_view<IVTypes>>
|
||||
{
|
||||
using type = any_image_view<typename mpl::transform<IVTypes, dynamic_xy_step_type<mpl::_1>>::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;
|
||||
struct dynamic_xy_step_transposed_type<any_image_view<IVTypes>>
|
||||
{
|
||||
using type = any_image_view<typename mpl::transform<IVTypes, dynamic_xy_step_transposed_type<mpl::_1>>::type>;
|
||||
};
|
||||
|
||||
} } // namespace boost::gil
|
||||
}} // namespace boost::gil
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,61 +1,71 @@
|
||||
/*
|
||||
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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_EXTENSION_DYNAMIC_IMAGE_APPLY_OPERATION_HPP
|
||||
#define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_APPLY_OPERATION_HPP
|
||||
|
||||
See http://opensource.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
|
||||
/*************************************************************************************************/
|
||||
#ifdef BOOST_GIL_DOXYGEN_ONLY
|
||||
#undef BOOST_GIL_REDUCE_CODE_BLOAT
|
||||
#endif
|
||||
|
||||
#ifndef GIL_APPLY_OPERATION_HPP
|
||||
#define GIL_APPLY_OPERATION_HPP
|
||||
// Implements apply_operation for variants.
|
||||
// Optionally performs type reduction.
|
||||
#ifdef BOOST_GIL_REDUCE_CODE_BLOAT
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \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 <boost/gil/extension/dynamic_image/reduce.hpp>
|
||||
|
||||
#include "apply_operation_base.hpp"
|
||||
#include "variant.hpp"
|
||||
|
||||
#ifndef GIL_REDUCE_CODE_BLOAT
|
||||
#else
|
||||
|
||||
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);
|
||||
template <typename Types, typename UnaryOp>
|
||||
BOOST_FORCEINLINE
|
||||
auto apply_operation(variant<Types>& arg, UnaryOp op)
|
||||
#if defined(BOOST_NO_CXX14_DECLTYPE_AUTO) || defined(BOOST_NO_CXX11_DECLTYPE_N3276)
|
||||
-> typename UnaryOp::result_type
|
||||
#endif
|
||||
{
|
||||
return apply_visitor(op, arg);
|
||||
}
|
||||
|
||||
/// \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);
|
||||
template <typename Types, typename UnaryOp>
|
||||
BOOST_FORCEINLINE
|
||||
auto apply_operation(variant<Types> const& arg, UnaryOp op)
|
||||
#if defined(BOOST_NO_CXX14_DECLTYPE_AUTO) || defined(BOOST_NO_CXX11_DECLTYPE_N3276)
|
||||
-> typename UnaryOp::result_type
|
||||
#endif
|
||||
{
|
||||
return apply_visitor(op, arg);
|
||||
}
|
||||
|
||||
/// \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);
|
||||
template <typename Types1, typename Types2, typename BinaryOp>
|
||||
BOOST_FORCEINLINE
|
||||
auto apply_operation(
|
||||
variant<Types1> const& arg1,
|
||||
variant<Types2> const& arg2,
|
||||
BinaryOp op)
|
||||
#if defined(BOOST_NO_CXX14_DECLTYPE_AUTO) || defined(BOOST_NO_CXX11_DECLTYPE_N3276)
|
||||
-> typename BinaryOp::result_type
|
||||
#endif
|
||||
{
|
||||
return apply_visitor(
|
||||
op, arg1, arg2);
|
||||
}
|
||||
|
||||
} } // namespace boost::gil
|
||||
}} // namespace boost::gil
|
||||
|
||||
#else
|
||||
|
||||
#include "reduce.hpp"
|
||||
|
||||
#endif
|
||||
#endif // defined(BOOST_GIL_REDUCE_CODE_BLOAT)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,185 +0,0 @@
|
||||
/*
|
||||
Copyright 2005-2007 Adobe Systems Incorporated
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
|
||||
See http://opensource.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#ifndef GIL_APPLY_OPERATION_BASE_HPP
|
||||
#define GIL_APPLY_OPERATION_BASE_HPP
|
||||
|
||||
#include "../../gil_config.hpp"
|
||||
#include "../../utilities.hpp"
|
||||
#include <boost/mpl/begin.hpp>
|
||||
#include <boost/mpl/next.hpp>
|
||||
#include <boost/mpl/deref.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/preprocessor/repeat.hpp>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \file
|
||||
/// \brief Given an object with run-time specified type (denoted as an array of Bits, dynamic index, and a static set of Types) and a generic operation,
|
||||
/// casts the object to its appropriate type and applies the operation
|
||||
/// \author Lubomir Bourdev and Hailin Jin \n
|
||||
/// Adobe Systems Incorporated
|
||||
/// \date 2005-2007 \n Last updated on November 6, 2007
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/*
|
||||
GENERATE_APPLY_FWD_OPS generates for every N functions that look like this (for N==2):
|
||||
|
||||
template <> struct apply_operation_fwd_fn<3> {
|
||||
template <typename Types, typename Bits, typename UnaryOp>
|
||||
typename UnaryOp::result_type apply(Bits& bits, std::size_t index, UnaryOp op) const {
|
||||
typedef typename mpl::begin<Types>::type T0;
|
||||
typedef typename mpl::next<T0>::type T1;
|
||||
typedef typename mpl::next<T1>::type T2;
|
||||
switch (index) {
|
||||
case 0: return op(reinterpret_cast<typename mpl::deref<T0>::type&>(bits));
|
||||
case 1: return op(reinterpret_cast<typename mpl::deref<T1>::type&>(bits));
|
||||
case 2: return op(reinterpret_cast<typename mpl::deref<T2>::type&>(bits));
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
template <typename Types, typename Bits, typename UnaryOp>
|
||||
typename UnaryOp::result_type applyc(const Bits& bits, std::size_t index, UnaryOp op) const {
|
||||
typedef typename mpl::begin<Types>::type T0;
|
||||
typedef typename mpl::next<T0>::type T1;
|
||||
typedef typename mpl::next<T1>::type T2;
|
||||
switch (index) {
|
||||
case 0: return op(reinterpret_cast<const typename mpl::deref<T0>::type&>(bits));
|
||||
case 1: return op(reinterpret_cast<const typename mpl::deref<T1>::type&>(bits));
|
||||
case 2: return op(reinterpret_cast<const typename mpl::deref<T2>::type&>(bits));
|
||||
}
|
||||
throw;
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
#define GIL_FWD_TYPEDEFS(z, N, text) T##N; typedef typename mpl::next<T##N>::type
|
||||
#define GIL_FWD_CASE(z, N, SUM) case N: return op(*gil_reinterpret_cast<typename mpl::deref<T##N>::type*>(&bits));
|
||||
#define GIL_FWD_CONST_CASE(z, N, SUM) case N: return op(*gil_reinterpret_cast_c<const typename mpl::deref<T##N>::type*>(&bits));
|
||||
|
||||
#define GIL_FWD_CASE_WITH_INFO(z, N, SUM) case N: return op(*gil_reinterpret_cast<typename mpl::deref<T##N>::type*>(&bits), info);
|
||||
#define GIL_FWD_CONST_CASE_WITH_INFO(z, N, SUM) case N: return op(*gil_reinterpret_cast_c<const typename mpl::deref<T##N>::type*>(&bits), info);
|
||||
|
||||
#define GIL_APPLY_FWD_OP(z, N, text) \
|
||||
template <> struct apply_operation_fwd_fn<BOOST_PP_ADD(N,1)> { \
|
||||
template <typename Types, typename Bits, typename UnaryOp> \
|
||||
typename UnaryOp::result_type apply(Bits& bits, std::size_t index, UnaryOp op) const { \
|
||||
typedef typename mpl::begin<Types>::type \
|
||||
BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \
|
||||
T##N; \
|
||||
switch (index) { \
|
||||
BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CASE, BOOST_PP_EMPTY) \
|
||||
} \
|
||||
throw; \
|
||||
} \
|
||||
template <typename Types, typename Bits, typename UnaryOp> \
|
||||
typename UnaryOp::result_type applyc(const Bits& bits, std::size_t index, UnaryOp op) const { \
|
||||
typedef typename mpl::begin<Types>::type \
|
||||
BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \
|
||||
T##N; \
|
||||
switch (index) { \
|
||||
BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CONST_CASE,BOOST_PP_EMPTY) \
|
||||
} \
|
||||
throw; \
|
||||
} \
|
||||
template <typename Types, typename Info, typename Bits, typename UnaryOp> \
|
||||
typename UnaryOp::result_type apply(Bits& bits, std::size_t index, const Info& info, UnaryOp op) const { \
|
||||
typedef typename mpl::begin<Types>::type \
|
||||
BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \
|
||||
T##N; \
|
||||
switch (index) { \
|
||||
BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CASE_WITH_INFO, BOOST_PP_EMPTY) \
|
||||
} \
|
||||
throw; \
|
||||
} \
|
||||
template <typename Types, typename Bits, typename Info, typename UnaryOp> \
|
||||
typename UnaryOp::result_type applyc(const Bits& bits, std::size_t index, const Info& info, UnaryOp op) const { \
|
||||
typedef typename mpl::begin<Types>::type \
|
||||
BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \
|
||||
T##N; \
|
||||
switch (index) { \
|
||||
BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CONST_CASE_WITH_INFO,BOOST_PP_EMPTY) \
|
||||
} \
|
||||
throw; \
|
||||
} \
|
||||
};
|
||||
|
||||
#define GIL_GENERATE_APPLY_FWD_OPS(N) BOOST_PP_REPEAT(N, GIL_APPLY_FWD_OP, BOOST_PP_EMPTY)
|
||||
|
||||
namespace detail {
|
||||
template <std::size_t N> struct apply_operation_fwd_fn {};
|
||||
|
||||
// Create specializations of apply_operation_fn for each N 0..100
|
||||
GIL_GENERATE_APPLY_FWD_OPS(99)
|
||||
} // namespace detail
|
||||
|
||||
// unary application
|
||||
template <typename Types, typename Bits, typename Op>
|
||||
typename Op::result_type GIL_FORCEINLINE apply_operation_basec(const Bits& bits, std::size_t index, Op op) {
|
||||
return detail::apply_operation_fwd_fn<mpl::size<Types>::value>().template applyc<Types>(bits,index,op);
|
||||
}
|
||||
|
||||
// unary application
|
||||
template <typename Types, typename Bits, typename Op>
|
||||
typename Op::result_type GIL_FORCEINLINE apply_operation_base( Bits& bits, std::size_t index, Op op) {
|
||||
return detail::apply_operation_fwd_fn<mpl::size<Types>::value>().template apply<Types>(bits,index,op);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <typename T2, typename Op>
|
||||
struct reduce_bind1 {
|
||||
const T2& _t2;
|
||||
Op& _op;
|
||||
|
||||
typedef typename Op::result_type result_type;
|
||||
|
||||
reduce_bind1(const T2& t2, Op& op) : _t2(t2), _op(op) {}
|
||||
|
||||
template <typename T1> GIL_FORCEINLINE result_type operator()(const T1& t1) { return _op(t1, _t2); }
|
||||
};
|
||||
|
||||
template <typename Types1, typename Bits1, typename Op>
|
||||
struct reduce_bind2 {
|
||||
const Bits1& _bits1;
|
||||
std::size_t _index1;
|
||||
Op& _op;
|
||||
|
||||
typedef typename Op::result_type result_type;
|
||||
|
||||
reduce_bind2(const Bits1& bits1, std::size_t index1, Op& op) : _bits1(bits1), _index1(index1), _op(op) {}
|
||||
|
||||
template <typename T2> GIL_FORCEINLINE result_type operator()(const T2& t2) {
|
||||
return apply_operation_basec<Types1>(_bits1, _index1, reduce_bind1<T2,Op>(t2, _op));
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
// Binary application by applying on each dimension separately
|
||||
template <typename Types1, typename Types2, typename Bits1, typename Bits2, typename Op>
|
||||
static typename Op::result_type GIL_FORCEINLINE apply_operation_base(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
|
||||
return apply_operation_basec<Types2>(bits2,index2,detail::reduce_bind2<Types1,Bits1,Op>(bits1,index1,op));
|
||||
}
|
||||
|
||||
#undef GIL_FWD_TYPEDEFS
|
||||
#undef GIL_FWD_CASE
|
||||
#undef GIL_FWD_CONST_CASE
|
||||
#undef GIL_APPLY_FWD_OP
|
||||
#undef GIL_GENERATE_APPLY_FWD_OPS
|
||||
#undef BHS
|
||||
|
||||
} } // namespace boost::gil
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,36 +1,22 @@
|
||||
/*
|
||||
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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_EXTENSION_DYNAMIC_IMAGE_DYNAMIC_AT_C_HPP
|
||||
#define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_DYNAMIC_AT_C_HPP
|
||||
|
||||
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
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#include <stdexcept>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
// Constructs for static-to-dynamic integer convesion
|
||||
|
||||
#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
|
||||
|
||||
@@ -69,7 +55,7 @@ namespace detail {
|
||||
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);
|
||||
case 1: return at_c_fn<GIL_DYNAMIC_AT_C_LIMIT ,REM >::template apply<IntTypes,ValueType>(index - GIL_DYNAMIC_AT_C_LIMIT);
|
||||
};
|
||||
throw;
|
||||
}
|
||||
@@ -84,7 +70,7 @@ namespace detail {
|
||||
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);
|
||||
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;
|
||||
}
|
||||
@@ -99,8 +85,8 @@ namespace detail {
|
||||
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);
|
||||
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;
|
||||
}
|
||||
@@ -115,16 +101,16 @@ namespace detail {
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename IntTypes, typename ValueType> inline
|
||||
ValueType at_c(std::size_t index) {
|
||||
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
|
||||
}} // namespace boost::gil
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,32 +1,17 @@
|
||||
/*
|
||||
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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_EXTENSION_DYNAMIC_IMAGE_DYNAMIC_IMAGE_ALL_HPP
|
||||
#define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_DYNAMIC_IMAGE_ALL_HPP
|
||||
|
||||
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"
|
||||
#include <boost/gil/extension/dynamic_image/algorithm.hpp>
|
||||
#include <boost/gil/extension/dynamic_image/any_image.hpp>
|
||||
#include <boost/gil/extension/dynamic_image/apply_operation.hpp>
|
||||
#include <boost/gil/extension/dynamic_image/image_view_factory.hpp>
|
||||
#include <boost/gil.hpp> // FIXME: Include what you use!
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,77 +1,91 @@
|
||||
/*
|
||||
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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_EXTENSION_DYNAMIC_IMAGE_IMAGE_VIEW_FACTORY_HPP
|
||||
#define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_IMAGE_VIEW_FACTORY_HPP
|
||||
|
||||
See http://opensource.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
#include <boost/gil/extension/dynamic_image/any_image_view.hpp>
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#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"
|
||||
#include <boost/gil/dynamic_step.hpp>
|
||||
#include <boost/gil/image_view_factory.hpp>
|
||||
#include <boost/gil/point.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
// Methods for constructing any image views from other any image views
|
||||
// Extends image view factory to runtime type-specified views (any_image_view)
|
||||
|
||||
namespace detail {
|
||||
template <typename Result> struct flipped_up_down_view_fn {
|
||||
typedef Result result_type;
|
||||
using result_type = Result;
|
||||
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;
|
||||
using result_type = Result;
|
||||
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;
|
||||
using result_type = Result;
|
||||
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;
|
||||
using result_type = Result;
|
||||
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;
|
||||
using result_type = Result;
|
||||
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;
|
||||
using result_type = Result;
|
||||
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 subimage_view_fn
|
||||
{
|
||||
using result_type = Result;
|
||||
subimage_view_fn(point_t const& topleft, point_t const& dimensions)
|
||||
: _topleft(topleft), _size2(dimensions)
|
||||
{}
|
||||
|
||||
template <typename View>
|
||||
result_type operator()(const View& src) const
|
||||
{
|
||||
return result_type(subimage_view(src,_topleft,_size2));
|
||||
}
|
||||
|
||||
point_t _topleft;
|
||||
point_t _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 subsampled_view_fn
|
||||
{
|
||||
using result_type = Result;
|
||||
subsampled_view_fn(point_t const& step) : _step(step) {}
|
||||
|
||||
template <typename View>
|
||||
result_type operator()(const View& src) const
|
||||
{
|
||||
return result_type(subsampled_view(src,_step));
|
||||
}
|
||||
|
||||
point_t _step;
|
||||
};
|
||||
|
||||
template <typename Result> struct nth_channel_view_fn {
|
||||
typedef Result result_type;
|
||||
using result_type = Result;
|
||||
nth_channel_view_fn(int n) : _n(n) {}
|
||||
int _n;
|
||||
template <typename View> result_type operator()(const View& src) const { return result_type(nth_channel_view(src,_n)); }
|
||||
};
|
||||
template <typename DstP, typename Result, typename CC = default_color_converter> struct color_converted_view_fn {
|
||||
typedef Result result_type;
|
||||
using result_type = Result;
|
||||
color_converted_view_fn(CC cc = CC()): _cc(cc) {}
|
||||
|
||||
template <typename View> result_type operator()(const View& src) const { return result_type(color_converted_view<DstP>(src, _cc)); }
|
||||
@@ -84,66 +98,90 @@ template <typename DstP, typename Result, typename CC = default_color_converter>
|
||||
|
||||
/// \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>());
|
||||
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>());
|
||||
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>());
|
||||
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>());
|
||||
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>());
|
||||
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>());
|
||||
/// Models MPL Random Access Container of models of ImageViewConcept
|
||||
template <typename ViewTypes>
|
||||
inline auto rotated180_view(const any_image_view<ViewTypes>& src)
|
||||
-> typename dynamic_xy_step_type<any_image_view<ViewTypes>>::type
|
||||
{
|
||||
using step_type = typename dynamic_xy_step_type<any_image_view<ViewTypes>>::type;
|
||||
return apply_operation(src, detail::rotated180_view_fn<step_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));
|
||||
/// // Models MPL Random Access Container of models of ImageViewConcept
|
||||
template <typename ViewTypes>
|
||||
inline auto subimage_view(any_image_view<ViewTypes> const& src,
|
||||
point_t const& topleft, point_t const& dimensions)
|
||||
-> any_image_view<ViewTypes>
|
||||
{
|
||||
using subimage_view_fn = detail::subimage_view_fn<any_image_view<ViewTypes>>;
|
||||
return apply_operation(src, subimage_view_fn(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)));
|
||||
/// Models MPL Random Access Container of models of ImageViewConcept
|
||||
template <typename ViewTypes>
|
||||
inline auto subimage_view(any_image_view<ViewTypes> const& src,
|
||||
int xMin, int yMin, int width, int height)
|
||||
-> any_image_view<ViewTypes>
|
||||
{
|
||||
using subimage_view_fn = detail::subimage_view_fn<any_image_view<ViewTypes>>;
|
||||
return apply_operation(src, subimage_view_fn(point_t(xMin, yMin),point_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));
|
||||
/// Models MPL Random Access Container of models of ImageViewConcept
|
||||
template <typename ViewTypes>
|
||||
inline auto subsampled_view(any_image_view<ViewTypes> const& src, point_t const& step)
|
||||
-> typename dynamic_xy_step_type<any_image_view<ViewTypes>>::type
|
||||
{
|
||||
using step_type = typename dynamic_xy_step_type<any_image_view<ViewTypes>>::type;
|
||||
using subsampled_view = detail::subsampled_view_fn<step_type>;
|
||||
return apply_operation(src, subsampled_view(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)));
|
||||
/// Models MPL Random Access Container of models of ImageViewConcept
|
||||
template <typename ViewTypes>
|
||||
inline auto subsampled_view(any_image_view<ViewTypes> const& src, int xStep, int yStep)
|
||||
-> typename dynamic_xy_step_type<any_image_view<ViewTypes>>::type
|
||||
{
|
||||
using step_type = typename dynamic_xy_step_type<any_image_view<ViewTypes>>::type;
|
||||
using subsampled_view_fn = detail::subsampled_view_fn<step_type>;
|
||||
return apply_operation(src, subsampled_view_fn(point_t(xStep, yStep)));
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <typename View> struct get_nthchannel_type { typedef typename nth_channel_view_type<View>::type type; };
|
||||
template <typename View> struct get_nthchannel_type { using type = typename nth_channel_view_type<View>::type; };
|
||||
template <typename Views> struct views_get_nthchannel_type : public mpl::transform<Views, get_nthchannel_type<mpl::_1> > {};
|
||||
}
|
||||
|
||||
@@ -151,13 +189,13 @@ namespace detail {
|
||||
/// \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;
|
||||
using type = any_image_view<typename detail::views_get_nthchannel_type<ViewTypes>::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));
|
||||
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 {
|
||||
@@ -168,29 +206,31 @@ namespace detail {
|
||||
/// \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;
|
||||
struct color_converted_view_type<any_image_view<ViewTypes>,DstP,CC>
|
||||
{
|
||||
using type = any_image_view<typename detail::views_get_ccv_type<ViewTypes, DstP, CC>::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 >());
|
||||
typename color_converted_view_type<any_image_view<ViewTypes>, DstP, CC>::type color_converted_view(const any_image_view<ViewTypes>& src, 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;
|
||||
struct color_converted_view_type<any_image_view<ViewTypes>,DstP>
|
||||
{
|
||||
using type = any_image_view<typename detail::views_get_ccv_type<ViewTypes, DstP, default_color_converter>::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 >());
|
||||
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 >());
|
||||
}
|
||||
|
||||
|
||||
@@ -198,16 +238,16 @@ typename color_converted_view_type<any_image_view<ViewTypes>, DstP>::type color_
|
||||
/// \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 >());
|
||||
typename color_converted_view_type<any_image_view<ViewTypes>, DstP, CC>::type any_color_converted_view(const any_image_view<ViewTypes>& src, 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 >());
|
||||
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 >());
|
||||
}
|
||||
|
||||
/// \}
|
||||
|
||||
@@ -1,50 +1,41 @@
|
||||
/*
|
||||
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).
|
||||
//
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated
|
||||
//
|
||||
// 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_GIL_EXTENSION_DYNAMIC_IMAGE_GIL_REDUCE_HPP
|
||||
#define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_GIL_REDUCE_HPP
|
||||
|
||||
See http://opensource.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifdef BOOST_GIL_DOXYGEN_ONLY
|
||||
#undef BOOST_GIL_REDUCE_CODE_BLOAT
|
||||
#endif
|
||||
|
||||
#ifndef GIL_REDUCE_HPP
|
||||
#define GIL_REDUCE_HPP
|
||||
#ifdef BOOST_GIL_REDUCE_CODE_BLOAT
|
||||
|
||||
#include <boost/gil/extension/dynamic_image/dynamic_at_c.hpp>
|
||||
|
||||
#include <boost/gil/metafunctions.hpp>
|
||||
#include <boost/gil/typedefs.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/insert.hpp>
|
||||
#include <boost/mpl/insert_range.hpp>
|
||||
#include <boost/mpl/long.hpp>
|
||||
#include <boost/mpl/logical.hpp>
|
||||
#include <boost/mpl/range_c.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/vector_c.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 {
|
||||
|
||||
// Constructs for static-to-dynamic integer convesion
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
/// 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
|
||||
@@ -58,14 +49,16 @@ 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;
|
||||
struct at_c<mapping_vector<SrcTypes,DstTypes>, K>
|
||||
{
|
||||
static const std::size_t value=size<DstTypes>::value - order<DstTypes, typename gil::at_c<SrcTypes,K>::type>::type::value +1;
|
||||
using type = size_t<value>;
|
||||
};
|
||||
|
||||
template <typename SrcTypes, typename DstTypes>
|
||||
struct size<mapping_vector<SrcTypes,DstTypes> > {
|
||||
typedef typename size<SrcTypes>::type type;
|
||||
struct size<mapping_vector<SrcTypes,DstTypes>>
|
||||
{
|
||||
using type = typename size<SrcTypes>::type;
|
||||
static const std::size_t value=type::value;
|
||||
};
|
||||
|
||||
@@ -74,7 +67,7 @@ struct size<mapping_vector<SrcTypes,DstTypes> > {
|
||||
///
|
||||
/// 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;
|
||||
/// mpl::copy<SET, mpl::back_inserter<mpl::vector<>>>::type;
|
||||
/// It works when SET is mpl::vector, but not when SET is mpl::set...
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
@@ -82,27 +75,30 @@ 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;
|
||||
using T = typename deref<SFirst>::type;
|
||||
using next = typename next<SFirst>::type;
|
||||
using rest = typename copy_to_vector_impl<next, NLeft-1>::type;
|
||||
public:
|
||||
typedef typename push_front<rest, T>::type type;
|
||||
using type = typename push_front<rest, T>::type;
|
||||
};
|
||||
|
||||
template <typename SFirst>
|
||||
struct copy_to_vector_impl<SFirst,1> {
|
||||
typedef vector<typename deref<SFirst>::type> type;
|
||||
template <typename SFirst>
|
||||
struct copy_to_vector_impl<SFirst,1>
|
||||
{
|
||||
using type = vector<typename deref<SFirst>::type>;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Src>
|
||||
struct copy_to_vector {
|
||||
typedef typename detail::copy_to_vector_impl<typename begin<Src>::type, size<Src>::value>::type type;
|
||||
struct copy_to_vector
|
||||
{
|
||||
using type = typename detail::copy_to_vector_impl<typename begin<Src>::type, size<Src>::value>::type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct copy_to_vector<set<> > {
|
||||
typedef vector0<> type;
|
||||
struct copy_to_vector<set<>>
|
||||
{
|
||||
using type = vector0<>;
|
||||
};
|
||||
|
||||
} } // boost::mpl
|
||||
@@ -111,7 +107,7 @@ 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
|
||||
@@ -122,7 +118,7 @@ namespace boost { namespace gil {
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
///
|
||||
///
|
||||
/// \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)
|
||||
@@ -133,46 +129,48 @@ namespace boost { namespace gil {
|
||||
|
||||
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;
|
||||
using reduced_t = typename mpl::transform<Types, detail::reduce<Op, mpl::_1> >::type;
|
||||
using unique_t = typename mpl::copy<reduced_t, mpl::inserter<mpl::set<>, mpl::insert<mpl::_1,mpl::_2>>>::type;
|
||||
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;
|
||||
struct unary_reduce : public unary_reduce_impl<Types,Op>
|
||||
{
|
||||
using reduced_t = typename unary_reduce_impl<Types,Op>::reduced_t;
|
||||
using unique_t = typename unary_reduce_impl<Types,Op>::unique_t;
|
||||
|
||||
static unsigned short inline map_index(std::size_t index) {
|
||||
typedef typename mpl::mapping_vector<reduced_t, unique_t> indices_t;
|
||||
static unsigned short inline map_index(std::size_t index)
|
||||
{
|
||||
using indices_t = typename mpl::mapping_vector<reduced_t, unique_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) {
|
||||
template <typename Bits> BOOST_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) {
|
||||
template <typename Bits> BOOST_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;
|
||||
using unique_t = typename unary_reduce_impl<Types,Op>::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) {
|
||||
template <typename Bits> BOOST_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) {
|
||||
template <typename Bits> BOOST_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
|
||||
@@ -186,28 +184,30 @@ struct unary_reduce<Types,Op,true> : public unary_reduce_impl<Types,Op> {
|
||||
|
||||
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;
|
||||
template <typename Vec2> struct apply
|
||||
{
|
||||
using type = std::pair<const typename mpl::at_c<Vec2,0>::type*, const typename mpl::at_c<Vec2,1>::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 {
|
||||
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;
|
||||
using vec1_types = typename mpl::copy_to_vector<typename Unary1::unique_t>::type;
|
||||
using vec2_types = typename mpl::copy_to_vector<typename Unary2::unique_t>::type;
|
||||
|
||||
using BIN_TYPES = mpl::cross_vector<mpl::vector2<vec1_types, vec2_types>, pair_generator>;
|
||||
using bin_reduced_t = unary_reduce<BIN_TYPES,Op>;
|
||||
|
||||
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;
|
||||
using unique_t = typename bin_reduced_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) {
|
||||
@@ -228,15 +228,16 @@ namespace detail {
|
||||
|
||||
|
||||
template <typename Types1, typename Types2, typename Op>
|
||||
struct binary_reduce {
|
||||
struct binary_reduce
|
||||
{
|
||||
//private:
|
||||
typedef unary_reduce<Types1,Op> unary1_t;
|
||||
typedef unary_reduce<Types2,Op> unary2_t;
|
||||
using unary1_t = unary_reduce<Types1,Op>;
|
||||
using unary2_t = unary_reduce<Types2,Op>;
|
||||
|
||||
static const std::size_t CROSS_SIZE = mpl::size<typename unary1_t::unique_t>::value *
|
||||
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;
|
||||
using impl = detail::binary_reduce_impl<unary1_t,unary2_t,Op, (CROSS_SIZE>GIL_BINARY_REDUCE_LIMIT)>;
|
||||
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) {
|
||||
@@ -245,17 +246,17 @@ public:
|
||||
};
|
||||
|
||||
template <typename Types, typename UnaryOp>
|
||||
GIL_FORCEINLINE typename UnaryOp::result_type apply_operation(variant<Types>& arg, UnaryOp op) {
|
||||
BOOST_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) {
|
||||
BOOST_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) {
|
||||
BOOST_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);
|
||||
}
|
||||
|
||||
@@ -268,19 +269,19 @@ namespace boost { namespace mpl {
|
||||
///////////////////////////////////////////////////////
|
||||
/// \brief Represents the virtual cross-product of the types generated from VecOfVecs.
|
||||
/// \ingroup CrossVector
|
||||
/// INPUT:
|
||||
/// 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,
|
||||
/// Traversal, random-access, etc, is defined, but mutable operations,
|
||||
/// such as push_back and pop_front are not supported
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
@@ -290,8 +291,9 @@ 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;
|
||||
struct cross_iterator
|
||||
{
|
||||
using category = mpl::random_access_iterator_tag;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
@@ -301,43 +303,48 @@ struct cross_iterator {
|
||||
/// \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
|
||||
/// 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> > {
|
||||
struct deref<cross_iterator<VecOfVecs,TypeGen,K>>
|
||||
{
|
||||
private:
|
||||
typedef typename detail::select_subvector_c<VecOfVecs, K>::type DerefTypes;
|
||||
using DerefTypes = typename detail::select_subvector_c<VecOfVecs, K>::type;
|
||||
public:
|
||||
typedef typename TypeGen::template apply<DerefTypes>::type type;
|
||||
using type = typename TypeGen::template apply<DerefTypes>::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;
|
||||
struct next<cross_iterator<VecOfVecs,TypeGen,K>>
|
||||
{
|
||||
using type = cross_iterator<VecOfVecs,TypeGen,K+1>;
|
||||
};
|
||||
|
||||
/// \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;
|
||||
struct prior<cross_iterator<VecOfVecs,TypeGen,K>>
|
||||
{
|
||||
using type = cross_iterator<VecOfVecs,TypeGen,K-1>;
|
||||
};
|
||||
|
||||
/// \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;
|
||||
struct advance<cross_iterator<VecOfVecs,TypeGen,K>, Distance>
|
||||
{
|
||||
using type = cross_iterator<VecOfVecs,TypeGen,K+Distance::value>;
|
||||
};
|
||||
|
||||
/// \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;
|
||||
struct distance<cross_iterator<VecOfVecs,TypeGen,K1>, cross_iterator<VecOfVecs,TypeGen,K2>>
|
||||
{
|
||||
using type = size_t<K2-K1>;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
@@ -346,80 +353,88 @@ struct distance<cross_iterator<VecOfVecs,TypeGen,K1>, cross_iterator<VecOfVecs,T
|
||||
/// \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;
|
||||
struct size<cross_vector<VecOfVecs,TypeGen>>
|
||||
{
|
||||
using type = typename fold<VecOfVecs, size_t<1>, times<_1, size<_2>>>::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;
|
||||
struct empty<cross_vector<VecOfVecs,TypeGen>> {
|
||||
using type = typename empty<VecOfVecs>::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> {
|
||||
struct at<cross_vector<VecOfVecs,TypeGen>, K>
|
||||
{
|
||||
private:
|
||||
typedef cross_iterator<VecOfVecs,TypeGen,K::value> KthIterator;
|
||||
using KthIterator = cross_iterator<VecOfVecs,TypeGen,K::value>;
|
||||
public:
|
||||
typedef typename deref<KthIterator>::type type;
|
||||
using type = typename deref<KthIterator>::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;
|
||||
struct begin<cross_vector<VecOfVecs,TypeGen>>
|
||||
{
|
||||
using type = cross_iterator<VecOfVecs,TypeGen,0>;
|
||||
};
|
||||
|
||||
/// \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> > {
|
||||
struct end<cross_vector<VecOfVecs,TypeGen>>
|
||||
{
|
||||
private:
|
||||
typedef cross_vector<VecOfVecs,TypeGen> this_t;
|
||||
using this_t = cross_vector<VecOfVecs,TypeGen>;
|
||||
public:
|
||||
typedef cross_iterator<VecOfVecs,TypeGen,size<this_t>::value> type;
|
||||
using type = cross_iterator<VecOfVecs,TypeGen,size<this_t>::value>;
|
||||
};
|
||||
|
||||
/// \brief Returns the first element of a cross vector
|
||||
/// \ingroup CrossVector
|
||||
template <typename VecOfVecs, typename TypeGen>
|
||||
struct front<cross_vector<VecOfVecs,TypeGen> > {
|
||||
struct front<cross_vector<VecOfVecs,TypeGen>> {
|
||||
private:
|
||||
typedef cross_vector<VecOfVecs,TypeGen> this_t;
|
||||
using this_t = cross_vector<VecOfVecs,TypeGen>;
|
||||
public:
|
||||
typedef typename deref<typename begin<this_t>::type>::type type;
|
||||
using type = typename deref<typename begin<this_t>::type>::type;
|
||||
};
|
||||
|
||||
/// \brief Returns the last element of a cross vector
|
||||
/// \ingroup CrossVector
|
||||
template <typename VecOfVecs, typename TypeGen>
|
||||
struct back<cross_vector<VecOfVecs,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;
|
||||
using this_t = cross_vector<VecOfVecs,TypeGen>;
|
||||
using size = typename size<this_t>::type;
|
||||
using last_index = typename minus<size, size_t<1>>::type;
|
||||
public:
|
||||
typedef typename at<this_t, last_index>::type type;
|
||||
using type = typename at<this_t, last_index>::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;
|
||||
struct transform<cross_vector<VecOfVecs,TypeGen>, OPP>
|
||||
{
|
||||
using Op = typename lambda<OPP>::type;
|
||||
struct adapter
|
||||
{
|
||||
template <typename Elements>
|
||||
struct apply
|
||||
{
|
||||
using orig_t = typename TypeGen::template apply<Elements>::type;
|
||||
using type = typename Op::template apply<orig_t>::type;
|
||||
};
|
||||
};
|
||||
typedef cross_vector<VecOfVecs, adapter > type;
|
||||
using type = cross_vector<VecOfVecs, adapter>;
|
||||
};
|
||||
|
||||
} } // boost::mpl
|
||||
@@ -443,8 +458,9 @@ namespace detail {
|
||||
////
|
||||
////////////////////////////////////////////////////////
|
||||
template <typename Op, typename T>
|
||||
struct reduce {
|
||||
typedef T type;
|
||||
struct reduce
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
@@ -455,14 +471,15 @@ namespace detail {
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
template <typename Op, typename View, bool IsBasic>
|
||||
struct reduce_view_basic {
|
||||
typedef View type;
|
||||
struct reduce_view_basic
|
||||
{
|
||||
using type = View;
|
||||
};
|
||||
|
||||
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> {};
|
||||
|
||||
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.
|
||||
@@ -471,12 +488,13 @@ namespace detail {
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
template <typename Op, typename Img, bool IsBasic>
|
||||
struct reduce_image_basic {
|
||||
typedef Img type;
|
||||
struct reduce_image_basic
|
||||
{
|
||||
using type = Img;
|
||||
};
|
||||
|
||||
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 > {};
|
||||
struct reduce<Op, image<V,Alloc>> : public reduce_image_basic<Op,image<V,Alloc>,image_is_basic<image<V,Alloc>>::value > {};
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
////
|
||||
@@ -486,14 +504,15 @@ namespace detail {
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
template <typename Op, typename V1, typename V2, bool AreBasic>
|
||||
struct reduce_views_basic {
|
||||
typedef std::pair<const V1*, const V2*> type;
|
||||
struct reduce_views_basic
|
||||
{
|
||||
using type = std::pair<const V1*, const V2*>;
|
||||
};
|
||||
|
||||
template <typename Op, typename L1, typename L2>
|
||||
struct reduce<Op, std::pair<const image_view<L1>*, const image_view<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 >
|
||||
mpl::and_<view_is_basic<image_view<L1>>, view_is_basic<image_view<L2>>>::value >
|
||||
{};
|
||||
|
||||
|
||||
@@ -503,32 +522,33 @@ namespace detail {
|
||||
////
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
template <typename Cs>
|
||||
struct reduce_color_space {
|
||||
typedef Cs type;
|
||||
template <typename CS>
|
||||
struct reduce_color_space
|
||||
{
|
||||
using type = CS;
|
||||
};
|
||||
|
||||
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; };
|
||||
template <> struct reduce_color_space<lab_t> { using type = rgb_t; };
|
||||
template <> struct reduce_color_space<hsb_t> { using type = rgb_t; };
|
||||
template <> struct reduce_color_space<cmyk_t> { using type = rgba_t; };
|
||||
|
||||
/*
|
||||
////////////////////////////////////////////////////////
|
||||
////
|
||||
//// Color space binary reduce operation. Given a source and destination color spaces,
|
||||
//// 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>
|
||||
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;
|
||||
using last = typename mpl::back<Vec>::type;
|
||||
using rest = typename mpl::pop_back<Vec>::type;
|
||||
static const int value = type_vec_to_integer_impl<rest, Basis, VecSize-1>::value * Basis + last::value;
|
||||
};
|
||||
|
||||
template <typename Vec, int Basis>
|
||||
template <typename Vec, int Basis>
|
||||
struct type_vec_to_integer_impl<Vec,Basis,0> {
|
||||
static const int value=0;
|
||||
};
|
||||
@@ -542,86 +562,87 @@ namespace detail {
|
||||
// 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;
|
||||
using first_t = SrcColorSpace;
|
||||
using second_t = DstColorSpace;
|
||||
};
|
||||
|
||||
// 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;
|
||||
using first_t = rgb_t;
|
||||
using second_t = rgb_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;
|
||||
using first_t = rgb_t;
|
||||
using second_t = bgr_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;
|
||||
using first_t = rgba_t;
|
||||
using second_t = rgba_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;
|
||||
using first_t = rgba_t;
|
||||
using second_t = abgr_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;
|
||||
using first_t = rgba_t;
|
||||
using second_t = argb_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;
|
||||
using first_t = rgba_t;
|
||||
using second_t = bgra_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;
|
||||
using first_t = argb_t;
|
||||
using second_t = rgba_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;
|
||||
using first_t = argb_t;
|
||||
using second_t = abgr_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;
|
||||
using src_order_t = typename channel_order<SrcColorSpace>::type;
|
||||
using dst_order_t = typename channel_order<DstColorSpace>::type;
|
||||
using mapping = typename mpl::transform<src_order_t, type_to_index<dst_order_t,mpl::_1>>::type;
|
||||
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;
|
||||
|
||||
using _first_t = typename reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,mapping_val>::first_t;
|
||||
using _second_t = typename reduce_color_spaces_impl<SrcColorSpace,DstColorSpace,mapping_val>::second_t;
|
||||
using swap_t = typename mpl::and_<color_space_is_base<DstColorSpace>, mpl::not_< color_space_is_base<_second_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;
|
||||
using first_t = typename mpl::if_<swap_t, _second_t, _first_t>::type;
|
||||
using second_t = typename mpl::if_<swap_t, _first_t, _second_t>::type;
|
||||
};
|
||||
*/
|
||||
// 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;
|
||||
struct reduce_color_layouts
|
||||
{
|
||||
using first_t = SrcLayout;
|
||||
using second_t = DstLayout;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
@@ -637,38 +658,40 @@ namespace detail {
|
||||
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;
|
||||
using color_space_t = typename reduce_color_space<typename View::color_space_t>::type color_space_t; // reduce the color space
|
||||
using layout_t = layout<color_space_t, typename View::channel_mapping_t>;
|
||||
public:
|
||||
typedef typename derived_view_type<View, use_default, layout_t, use_default, use_default, mpl::true_>::type type;
|
||||
using type = typename derived_view_type<View, use_default, layout_t, use_default, use_default, mpl::true_>::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;
|
||||
template <typename V1, typename V2, bool Compatible>
|
||||
struct reduce_copy_pixop_compat
|
||||
{
|
||||
using type = error_t;
|
||||
};
|
||||
|
||||
// For compatible basic views, reduce their color spaces based on their channel mapping.
|
||||
|
||||
// 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;
|
||||
struct reduce_copy_pixop_compat<V1,V2,true>
|
||||
{
|
||||
using layout1 = layout<typename V1::color_space_t, typename V1::channel_mapping_t>;
|
||||
using layout2 = layout<typename V2::color_space_t, typename V2::channel_mapping_t>;
|
||||
|
||||
typedef typename reduce_color_layouts<layout1,layout2>::first_t L1;
|
||||
typedef typename reduce_color_layouts<layout1,layout2>::second_t L2;
|
||||
using L1 = typename reduce_color_layouts<layout1,layout2>::first_t;
|
||||
using L2 = typename reduce_color_layouts<layout1,layout2>::second_t;
|
||||
|
||||
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;
|
||||
using DV1 = typename derived_view_type<V1, use_default, L1, use_default, use_default, use_default, mpl::false_>::type;
|
||||
using DV2 = typename derived_view_type<V2, use_default, L2, use_default, use_default, use_default, mpl::true_ >::type;
|
||||
|
||||
using type = std::pair<const DV1*, const DV2*>;
|
||||
};
|
||||
|
||||
|
||||
// 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 > {
|
||||
: public reduce_copy_pixop_compat<V1, V2, mpl::and_<views_are_compatible<V1,V2>, view_is_mutable<V2>>::value > {
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
@@ -678,32 +701,52 @@ namespace detail {
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
struct destructor_op;
|
||||
template <typename View> struct reduce_view_basic<destructor_op,View,true> { typedef gray8_view_t type; };
|
||||
template <typename View>
|
||||
struct reduce_view_basic<destructor_op,View,true>
|
||||
{
|
||||
using type = gray8_view_t;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
////
|
||||
//// 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; };
|
||||
|
||||
template <typename View>
|
||||
struct reduce_view_basic<any_type_get_dimensions,View,true>
|
||||
{
|
||||
using type = gray8_view_t;
|
||||
};
|
||||
|
||||
template <typename Img>
|
||||
struct reduce_image_basic<any_type_get_dimensions,Img,true>
|
||||
{
|
||||
using type = gray8_image_t;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
////
|
||||
//// 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 View>
|
||||
struct reduce_view_basic<any_type_get_num_channels,View,true>
|
||||
{
|
||||
using color_space_t = typename View::color_space_t::base;
|
||||
using type = typename view_type<uint8_t,typename reduce_color_space<color_space_t>::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;
|
||||
|
||||
template <typename Img>
|
||||
struct reduce_image_basic<any_type_get_num_channels,Img,true>
|
||||
{
|
||||
using color_space_t = typename Img::color_space_t::base;
|
||||
using type = typename image_type<uint8_t,typename reduce_color_space<color_space_t>::type>::type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
@@ -711,13 +754,13 @@ namespace detail {
|
||||
//// 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>
|
||||
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>
|
||||
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> {};
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
@@ -727,29 +770,30 @@ namespace detail {
|
||||
////
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
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>
|
||||
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;
|
||||
template <typename CC, typename V1, typename V2, bool AreBasic>
|
||||
struct reduce_views_basic<copy_and_convert_pixels_fn<CC>, V1, V2, AreBasic>
|
||||
{
|
||||
using Same = is_same<typename V1::pixel_t, typename V2::pixel_t>;
|
||||
|
||||
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;
|
||||
using CsR = reduce_color_space<typename V1::color_space_t::base>;
|
||||
using Cs1 = typename mpl::if_<Same, typename CsR::type, typename V1::color_space_t>::type;
|
||||
using Cs2 = typename mpl::if_<Same, typename CsR::type, typename V2::color_space_t>::type;
|
||||
|
||||
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;
|
||||
using DV1 = typename derived_view_type<V1, use_default, layout<Cs1, typename V1::channel_mapping_t>, use_default, use_default, mpl::false_>::type;
|
||||
using DV2 = typename derived_view_type<V2, use_default, layout<Cs2, typename V2::channel_mapping_t>, use_default, use_default, mpl::true_ >::type;
|
||||
|
||||
using type = std::pair<const DV1*, const DV2*>;
|
||||
};
|
||||
|
||||
|
||||
@@ -757,33 +801,32 @@ namespace detail {
|
||||
//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)
|
||||
//std::bind(gil::detail::copy_pixels_fn(), std::placeholders::_1, dst)
|
||||
//std::bind(gil::detail::copy_pixels_fn(), src, std::placeholders::_1)
|
||||
|
||||
//std::bind(detail::copy_and_convert_pixels_fn(), std::placeholders::_1, dst)
|
||||
//std::bind(detail::copy_and_convert_pixels_fn(), src, std::placeholders::_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_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::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::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
|
||||
}} // namespace boost::gil
|
||||
|
||||
#endif // defined(BOOST_GIL_REDUCE_CODE_BLOAT)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
Copyright 2005-2007 Adobe Systems Incorporated
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
|
||||
See http://opensource.adobe.com/gil for most recent version including documentation.
|
||||
*/
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#ifndef GIL_DYNAMICIMAGE_VARIANT_HPP
|
||||
#define GIL_DYNAMICIMAGE_VARIANT_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \file
|
||||
/// \brief Support for run-time instantiated types
|
||||
/// \author Lubomir Bourdev and Hailin Jin \n
|
||||
/// Adobe Systems Incorporated
|
||||
/// \date 2005-2007 \n Last updated on September 18, 2007
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "../../gil_config.hpp"
|
||||
#include "../../utilities.hpp"
|
||||
#include <cstddef>
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <typeinfo>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <boost/mpl/transform.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/mpl/sizeof.hpp>
|
||||
#include <boost/mpl/max.hpp>
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/mpl/fold.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
namespace detail {
|
||||
template <typename Types, typename T> struct type_to_index;
|
||||
template <typename Op, typename T> struct reduce;
|
||||
struct destructor_op {
|
||||
typedef void result_type;
|
||||
template <typename T> result_type operator()(const T& t) const { t.~T(); }
|
||||
};
|
||||
template <typename T, typename Bits> void copy_construct_in_place(const T& t, Bits& bits);
|
||||
template <typename Bits> struct copy_construct_in_place_fn;
|
||||
}
|
||||
/**
|
||||
\brief Represents a concrete instance of a run-time specified type from a set of types
|
||||
\class variant
|
||||
\ingroup Variant
|
||||
|
||||
A concept is typically modeled by a collection of different types. They may be instantiations
|
||||
of a templated type with different template parameters or even completely unrelated types.
|
||||
|
||||
We call the type with which the concept is instantiated in a given place in the code "the concrete type".
|
||||
The concrete type must be chosen at compile time, which sometimes is a severe limitation.
|
||||
Consider, for example, having an image concept modeled by an image class templated over the color space.
|
||||
It would be difficult to write a function that reads an image from file preserving its native color space, since the
|
||||
type of the return value is only available at run time. It would be difficult to store images of different color
|
||||
spaces in the same container or apply operations on them uniformly.
|
||||
|
||||
The variant class addresses this deficiency. It allows for run-time instantiation of a class from a given set of allowed classes
|
||||
specified at compile time. For example, the set of allowed classes may include 8-bit and 16-bit RGB and CMYK images. Such a variant
|
||||
can be constructed with rgb8_image_t and then assigned a cmyk16_image_t.
|
||||
|
||||
The variant has a templated constructor, which allows us to construct it with any concrete type instantiation. It can also perform a generic
|
||||
operation on the concrete type via a call to apply_operation. The operation must be provided as a function object whose application
|
||||
operator has a single parameter which can be instantiated with any of the allowed types of the variant.
|
||||
|
||||
variant breaks down the instantiated type into a non-templated underlying base type and a unique instantiation
|
||||
type identifier. In the most common implementation the concrete instantiation in stored 'in-place' - in 'bits_t'.
|
||||
bits_t contains sufficient space to fit the largest of the instantiated objects.
|
||||
|
||||
GIL's variant is similar to boost::variant in spirit (hence we borrow the name from there) but it differs in several ways from the current boost
|
||||
implementation. Most notably, it does not take a variable number of template parameters but a single parameter defining the type enumeration. As
|
||||
such it can be used more effectively in generic code.
|
||||
|
||||
The Types parameter specifies the set of allowable types. It models MPL Random Access Container
|
||||
*/
|
||||
|
||||
template <typename Types> // models MPL Random Access Container
|
||||
class variant {
|
||||
// size in bytes of the largest type in Types
|
||||
static const std::size_t MAX_SIZE = mpl::fold<Types, mpl::size_t<0>, mpl::max<mpl::_1, mpl::sizeof_<mpl::_2> > >::type::value;
|
||||
static const std::size_t NUM_TYPES = mpl::size<Types>::value;
|
||||
public:
|
||||
typedef Types types_t;
|
||||
|
||||
typedef struct { char data[MAX_SIZE]; } base_t; // empty space equal to the size of the largest type in Types
|
||||
|
||||
// Default constructor - default construct the first type
|
||||
variant() : _index(0) { new(&_bits) typename mpl::at_c<Types,0>::type(); }
|
||||
virtual ~variant() { apply_operation(*this, detail::destructor_op()); }
|
||||
|
||||
// Throws std::bad_cast if T is not in Types
|
||||
template <typename T> explicit variant(const T& obj){ _index=type_id<T>(); if (_index==NUM_TYPES) throw std::bad_cast(); detail::copy_construct_in_place(obj, _bits); }
|
||||
|
||||
// When doSwap is true, swaps obj with the contents of the variant. obj will contain default-constructed instance after the call
|
||||
template <typename T> explicit variant(T& obj, bool do_swap);
|
||||
|
||||
template <typename T> variant& operator=(const T& obj) { variant tmp(obj); swap(*this,tmp); return *this; }
|
||||
variant& operator=(const variant& v) { variant tmp(v ); swap(*this,tmp); return *this; }
|
||||
|
||||
variant(const variant& v) : _index(v._index) { apply_operation(v, detail::copy_construct_in_place_fn<base_t>(_bits)); }
|
||||
template <typename T> void move_in(T& obj) { variant tmp(obj, true); swap(*this,tmp); }
|
||||
|
||||
template <typename TS> friend bool operator==(const variant<TS>& x, const variant<TS>& y);
|
||||
template <typename TS> friend bool operator!=(const variant<TS>& x, const variant<TS>& y);
|
||||
|
||||
template <typename T> static bool has_type() { return type_id<T>()!=NUM_TYPES; }
|
||||
|
||||
template <typename T> const T& _dynamic_cast() const { if (!current_type_is<T>()) throw std::bad_cast(); return *gil_reinterpret_cast_c<const T*>(&_bits); }
|
||||
template <typename T> T& _dynamic_cast() { if (!current_type_is<T>()) throw std::bad_cast(); return *gil_reinterpret_cast < T*>(&_bits); }
|
||||
|
||||
template <typename T> bool current_type_is() const { return type_id<T>()==_index; }
|
||||
|
||||
base_t bits() const { return _bits; }
|
||||
std::size_t index() const { return _index; }
|
||||
|
||||
private:
|
||||
template <typename T> static std::size_t type_id() { return detail::type_to_index<Types,T>::value; }
|
||||
|
||||
template <typename Cs> friend void swap(variant<Cs>& x, variant<Cs>& y);
|
||||
template <typename Types2, typename UnaryOp> friend typename UnaryOp::result_type apply_operation(variant<Types2>& var, UnaryOp op);
|
||||
template <typename Types2, typename UnaryOp> friend typename UnaryOp::result_type apply_operation(const variant<Types2>& var, UnaryOp op);
|
||||
template <typename Types1, typename Types2, typename BinaryOp> friend typename BinaryOp::result_type apply_operation(const variant<Types1>& arg1, const variant<Types2>& arg2, BinaryOp op);
|
||||
|
||||
base_t _bits;
|
||||
std::size_t _index;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T, typename Bits>
|
||||
void copy_construct_in_place(const T& t, Bits& bits) {
|
||||
T& b=*gil_reinterpret_cast<T*>(&bits);
|
||||
new(&b)T(t); // default-construct
|
||||
}
|
||||
|
||||
template <typename Bits>
|
||||
struct copy_construct_in_place_fn {
|
||||
typedef void result_type;
|
||||
Bits& _dst;
|
||||
copy_construct_in_place_fn(Bits& dst) : _dst(dst) {}
|
||||
|
||||
template <typename T> void operator()(const T& src) const { copy_construct_in_place(src,_dst); }
|
||||
};
|
||||
|
||||
template <typename Bits>
|
||||
struct equal_to_fn {
|
||||
const Bits& _dst;
|
||||
equal_to_fn(const Bits& dst) : _dst(dst) {}
|
||||
|
||||
typedef bool result_type;
|
||||
template <typename T> result_type operator()(const T& x) const {
|
||||
return x==*gil_reinterpret_cast_c<const T*>(&_dst);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// When doSwap is true, swaps obj with the contents of the variant. obj will contain default-constructed instance after the call
|
||||
template <typename Types>
|
||||
template <typename T> variant<Types>::variant(T& obj, bool do_swap) {
|
||||
_index=type_id<T>();
|
||||
if (_index==NUM_TYPES) throw std::bad_cast();
|
||||
|
||||
if (do_swap) {
|
||||
new(&_bits) T(); // default construct
|
||||
swap(obj, *gil_reinterpret_cast<T*>(&_bits));
|
||||
} else
|
||||
detail::copy_construct_in_place(const_cast<const T&>(obj), _bits);
|
||||
}
|
||||
|
||||
template <typename Types>
|
||||
void swap(variant<Types>& x, variant<Types>& y) {
|
||||
std::swap(x._bits,y._bits);
|
||||
std::swap(x._index, y._index);
|
||||
}
|
||||
|
||||
template <typename Types>
|
||||
inline bool operator==(const variant<Types>& x, const variant<Types>& y) {
|
||||
return x._index==y._index && apply_operation(x,detail::equal_to_fn<typename variant<Types>::base_t>(y._bits));
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
inline bool operator!=(const variant<C>& x, const variant<C>& y) {
|
||||
return !(x==y);
|
||||
}
|
||||
|
||||
} } // namespace boost::gil
|
||||
|
||||
#endif
|
||||
14
linx64/include/boost/gil/extension/io/bmp.hpp
Normal file
14
linx64/include/boost/gil/extension/io/bmp.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// Copyright 2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_BMP_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/read.hpp>
|
||||
#include <boost/gil/extension/io/bmp/write.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// Copyright 2009 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_BMP_DETAIL_IS_ALLOWED_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_DETAIL_IS_ALLOWED_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/tags.hpp>
|
||||
#include <boost/gil/channel.hpp>
|
||||
|
||||
#include <boost/mpl/bool_fwd.hpp>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
template< typename View >
|
||||
bool is_allowed( const image_read_info< bmp_tag >& info
|
||||
, mpl::true_ // is read_and_no_convert
|
||||
)
|
||||
{
|
||||
bmp_bits_per_pixel::type src_bits_per_pixel = 0;
|
||||
|
||||
switch( info._bits_per_pixel )
|
||||
{
|
||||
case 1:
|
||||
case 4:
|
||||
case 8:
|
||||
{
|
||||
if( info._header_size == bmp_header_size::_win32_info_size
|
||||
&& info._compression != bmp_compression::_rle8
|
||||
&& info._compression != bmp_compression::_rle4
|
||||
)
|
||||
{
|
||||
src_bits_per_pixel = 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
src_bits_per_pixel = 24;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 15:
|
||||
case 16:
|
||||
{
|
||||
src_bits_per_pixel = 24;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
src_bits_per_pixel = info._bits_per_pixel;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
io_error( "Pixel size not supported." );
|
||||
}
|
||||
}
|
||||
|
||||
using channel_t = typename channel_traits<typename element_type<typename View::value_type>::type>::value_type;
|
||||
bmp_bits_per_pixel::type dst_bits_per_pixel = detail::unsigned_integral_num_bits< channel_t >::value
|
||||
* num_channels< View >::value;
|
||||
|
||||
return ( dst_bits_per_pixel == src_bits_per_pixel );
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
bool is_allowed( const image_read_info< bmp_tag >& /* info */
|
||||
, mpl::false_ // is read_and_convert
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
743
linx64/include/boost/gil/extension/io/bmp/detail/read.hpp
Normal file
743
linx64/include/boost/gil/extension/io/bmp/detail/read.hpp
Normal file
@@ -0,0 +1,743 @@
|
||||
//
|
||||
// Copyright 2012 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_BMP_DETAIL_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_DETAIL_READ_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/detail/is_allowed.hpp>
|
||||
#include <boost/gil/extension/io/bmp/detail/reader_backend.hpp>
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/bit_operations.hpp>
|
||||
#include <boost/gil/io/conversion_policies.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/dynamic_io_new.hpp>
|
||||
#include <boost/gil/io/reader_base.hpp>
|
||||
#include <boost/gil/io/row_buffer_helper.hpp>
|
||||
#include <boost/gil/io/typedefs.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
///
|
||||
/// BMP Reader
|
||||
///
|
||||
template< typename Device
|
||||
, typename ConversionPolicy
|
||||
>
|
||||
class reader< Device
|
||||
, bmp_tag
|
||||
, ConversionPolicy
|
||||
>
|
||||
: public reader_base< bmp_tag
|
||||
, ConversionPolicy
|
||||
>
|
||||
, public reader_backend< Device
|
||||
, bmp_tag
|
||||
>
|
||||
{
|
||||
private:
|
||||
|
||||
using this_t = reader<Device, bmp_tag, ConversionPolicy>;
|
||||
using cc_t = typename ConversionPolicy::color_converter_type;
|
||||
|
||||
public:
|
||||
|
||||
using backend_t = reader_backend< Device, bmp_tag>;
|
||||
|
||||
public:
|
||||
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
reader( const Device& io_dev
|
||||
, const image_read_settings< bmp_tag >& settings
|
||||
)
|
||||
: backend_t( io_dev
|
||||
, settings
|
||||
)
|
||||
, _pitch( 0 )
|
||||
{}
|
||||
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
reader( const Device& io_dev
|
||||
, const ConversionPolicy& cc
|
||||
, const image_read_settings< bmp_tag >& settings
|
||||
)
|
||||
: reader_base< bmp_tag
|
||||
, ConversionPolicy
|
||||
>( cc )
|
||||
, backend_t( io_dev
|
||||
, settings
|
||||
)
|
||||
, _pitch( 0 )
|
||||
{}
|
||||
|
||||
|
||||
/// Read image.
|
||||
template< typename View >
|
||||
void apply( const View& dst_view )
|
||||
{
|
||||
if( this->_info._valid == false )
|
||||
{
|
||||
io_error( "Image header was not read." );
|
||||
}
|
||||
|
||||
using is_read_and_convert_t = typename is_same
|
||||
<
|
||||
ConversionPolicy,
|
||||
detail::read_and_no_convert
|
||||
>::type;
|
||||
|
||||
io_error_if( !detail::is_allowed< View >( this->_info
|
||||
, is_read_and_convert_t()
|
||||
)
|
||||
, "Image types aren't compatible."
|
||||
);
|
||||
|
||||
// the row pitch must be multiple 4 bytes
|
||||
if( this->_info._bits_per_pixel < 8 )
|
||||
{
|
||||
_pitch = static_cast<long>((( this->_info._width * this->_info._bits_per_pixel ) + 7 ) >> 3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
_pitch = static_cast<long>( this->_info._width * (( this->_info._bits_per_pixel + 7 ) >> 3 ));
|
||||
}
|
||||
|
||||
_pitch = (_pitch + 3) & ~3;
|
||||
|
||||
switch( this->_info._bits_per_pixel )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgba8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_palette_image
|
||||
<
|
||||
gray1_image_t::view_t,
|
||||
detail::mirror_bits<byte_vector_t, std::true_type>
|
||||
>(dst_view);
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
switch ( this->_info._compression )
|
||||
{
|
||||
case bmp_compression::_rle4:
|
||||
{
|
||||
///@todo How can we determine that?
|
||||
this->_scanline_length = 0;
|
||||
|
||||
read_palette_image_rle( dst_view );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case bmp_compression::_rgb:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgba8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_palette_image
|
||||
<
|
||||
gray4_image_t::view_t,
|
||||
detail::swap_half_bytes<byte_vector_t, std::true_type>
|
||||
>(dst_view);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
io_error( "Unsupported compression mode in BMP file." );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 8:
|
||||
{
|
||||
switch ( this->_info._compression )
|
||||
{
|
||||
case bmp_compression::_rle8:
|
||||
{
|
||||
///@todo How can we determine that?
|
||||
this->_scanline_length = 0;
|
||||
|
||||
read_palette_image_rle( dst_view );
|
||||
break;
|
||||
}
|
||||
|
||||
case bmp_compression::_rgb:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgba8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_palette_image< gray8_image_t::view_t
|
||||
, detail::do_nothing< std::vector< gray8_pixel_t > >
|
||||
> ( dst_view );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
io_error( "Unsupported compression mode in BMP file." );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 15: case 16:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgb8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_data_15( dst_view );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 24:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgb8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_data< bgr8_view_t >( dst_view );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 32:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgba8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_data< bgra8_view_t >( dst_view );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
long get_offset( std::ptrdiff_t pos )
|
||||
{
|
||||
if( this->_info._height > 0 )
|
||||
{
|
||||
// the image is upside down
|
||||
return static_cast<long>( ( this->_info._offset
|
||||
+ ( this->_info._height - 1 - pos ) * _pitch
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<long>( ( this->_info._offset
|
||||
+ pos * _pitch
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
template< typename View_Src
|
||||
, typename Byte_Manipulator
|
||||
, typename View_Dst
|
||||
>
|
||||
void read_palette_image( const View_Dst& view )
|
||||
{
|
||||
this->read_palette();
|
||||
|
||||
using rh_t = detail::row_buffer_helper_view<View_Src>;
|
||||
using it_t = typename rh_t::iterator_t;
|
||||
|
||||
rh_t rh( _pitch, true );
|
||||
|
||||
// we have to swap bits
|
||||
Byte_Manipulator byte_manipulator;
|
||||
|
||||
for( std::ptrdiff_t y = 0
|
||||
; y < this->_settings._dim.y
|
||||
; ++y
|
||||
)
|
||||
{
|
||||
this->_io_dev.seek( get_offset( y + this->_settings._top_left.y ));
|
||||
|
||||
this->_io_dev.read( reinterpret_cast< byte_t* >( rh.data() )
|
||||
, _pitch
|
||||
);
|
||||
|
||||
byte_manipulator( rh.buffer() );
|
||||
|
||||
typename View_Dst::x_iterator dst_it = view.row_begin( y );
|
||||
|
||||
it_t it = rh.begin() + this->_settings._top_left.x;
|
||||
it_t end = it + this->_settings._dim.x;
|
||||
|
||||
for( ; it != end; ++it, ++dst_it )
|
||||
{
|
||||
unsigned char c = get_color( *it, gray_color_t() );
|
||||
*dst_it = this->_palette[ c ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
void read_data_15( const View& view )
|
||||
{
|
||||
byte_vector_t row( _pitch );
|
||||
|
||||
// read the color masks
|
||||
if( this->_info._compression == bmp_compression::_bitfield )
|
||||
{
|
||||
this->_mask.red.mask = this->_io_dev.read_uint32();
|
||||
this->_mask.green.mask = this->_io_dev.read_uint32();
|
||||
this->_mask.blue.mask = this->_io_dev.read_uint32();
|
||||
|
||||
this->_mask.red.width = detail::count_ones( this->_mask.red.mask );
|
||||
this->_mask.green.width = detail::count_ones( this->_mask.green.mask );
|
||||
this->_mask.blue.width = detail::count_ones( this->_mask.blue.mask );
|
||||
|
||||
this->_mask.red.shift = detail::trailing_zeros( this->_mask.red.mask );
|
||||
this->_mask.green.shift = detail::trailing_zeros( this->_mask.green.mask );
|
||||
this->_mask.blue.shift = detail::trailing_zeros( this->_mask.blue.mask );
|
||||
}
|
||||
else if( this->_info._compression == bmp_compression::_rgb )
|
||||
{
|
||||
switch( this->_info._bits_per_pixel )
|
||||
{
|
||||
case 15:
|
||||
case 16:
|
||||
{
|
||||
this->_mask.red.mask = 0x007C00; this->_mask.red.width = 5; this->_mask.red.shift = 10;
|
||||
this->_mask.green.mask = 0x0003E0; this->_mask.green.width = 5; this->_mask.green.shift = 5;
|
||||
this->_mask.blue.mask = 0x00001F; this->_mask.blue.width = 5; this->_mask.blue.shift = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
this->_mask.red.mask = 0xFF0000; this->_mask.red.width = 8; this->_mask.red.shift = 16;
|
||||
this->_mask.green.mask = 0x00FF00; this->_mask.green.width = 8; this->_mask.green.shift = 8;
|
||||
this->_mask.blue.mask = 0x0000FF; this->_mask.blue.width = 8; this->_mask.blue.shift = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
io_error( "bmp_reader::apply(): unsupported BMP compression" );
|
||||
}
|
||||
|
||||
using image_t = rgb8_image_t;
|
||||
using it_t = typename image_t::view_t::x_iterator;
|
||||
|
||||
for( std::ptrdiff_t y = 0
|
||||
; y < this->_settings._dim.y
|
||||
; ++y
|
||||
)
|
||||
{
|
||||
this->_io_dev.seek( get_offset( y + this->_settings._top_left.y ));
|
||||
|
||||
this->_io_dev.read( &row.front()
|
||||
, row.size()
|
||||
);
|
||||
|
||||
image_t img_row( this->_info._width, 1 );
|
||||
image_t::view_t v = gil::view( img_row );
|
||||
it_t it = v.row_begin( 0 );
|
||||
|
||||
it_t beg = v.row_begin( 0 ) + this->_settings._top_left.x;
|
||||
it_t end = beg + this->_settings._dim.x;
|
||||
|
||||
byte_t* src = &row.front();
|
||||
for( int32_t i = 0 ; i < this->_info._width; ++i, src += 2 )
|
||||
{
|
||||
int p = ( src[1] << 8 ) | src[0];
|
||||
|
||||
int r = ((p & this->_mask.red.mask) >> this->_mask.red.shift) << (8 - this->_mask.red.width);
|
||||
int g = ((p & this->_mask.green.mask) >> this->_mask.green.shift) << (8 - this->_mask.green.width);
|
||||
int b = ((p & this->_mask.blue.mask) >> this->_mask.blue.shift) << (8 - this->_mask.blue.width);
|
||||
|
||||
get_color( it[i], red_t() ) = static_cast< byte_t >( r );
|
||||
get_color( it[i], green_t() ) = static_cast< byte_t >( g );
|
||||
get_color( it[i], blue_t() ) = static_cast< byte_t >( b );
|
||||
}
|
||||
|
||||
this->_cc_policy.read( beg
|
||||
, end
|
||||
, view.row_begin( y )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 8-8-8 BGR
|
||||
// 8-8-8-8 BGRA
|
||||
template< typename View_Src
|
||||
, typename View_Dst
|
||||
>
|
||||
void read_data( const View_Dst& view )
|
||||
{
|
||||
byte_vector_t row( _pitch );
|
||||
|
||||
View_Src v = interleaved_view( this->_info._width
|
||||
, 1
|
||||
, (typename View_Src::value_type*) &row.front()
|
||||
, this->_info._width * num_channels< View_Src >::value
|
||||
);
|
||||
|
||||
typename View_Src::x_iterator beg = v.row_begin( 0 ) + this->_settings._top_left.x;
|
||||
typename View_Src::x_iterator end = beg + this->_settings._dim.x;
|
||||
|
||||
for( std::ptrdiff_t y = 0
|
||||
; y < this->_settings._dim.y
|
||||
; ++y
|
||||
)
|
||||
{
|
||||
this->_io_dev.seek( get_offset( y + this->_settings._top_left.y ));
|
||||
|
||||
this->_io_dev.read( &row.front()
|
||||
, row.size()
|
||||
);
|
||||
|
||||
this->_cc_policy.read( beg
|
||||
, end
|
||||
, view.row_begin( y )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
template< typename Buffer
|
||||
, typename View
|
||||
>
|
||||
void copy_row_if_needed( const Buffer& buf
|
||||
, const View& view
|
||||
, std::ptrdiff_t y
|
||||
)
|
||||
{
|
||||
if( y >= this->_settings._top_left.y
|
||||
&& y < this->_settings._dim.y
|
||||
)
|
||||
{
|
||||
typename Buffer::const_iterator beg = buf.begin() + this->_settings._top_left.x;
|
||||
typename Buffer::const_iterator end = beg + this->_settings._dim.x;
|
||||
|
||||
std::copy( beg
|
||||
, end
|
||||
, view.row_begin( y )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
template< typename View_Dst >
|
||||
void read_palette_image_rle( const View_Dst& view )
|
||||
{
|
||||
BOOST_ASSERT(
|
||||
this->_info._compression == bmp_compression::_rle4 ||
|
||||
this->_info._compression == bmp_compression::_rle8);
|
||||
|
||||
this->read_palette();
|
||||
|
||||
// jump to start of rle4 data
|
||||
this->_io_dev.seek( this->_info._offset );
|
||||
|
||||
// we need to know the stream position for padding purposes
|
||||
std::size_t stream_pos = this->_info._offset;
|
||||
|
||||
using Buf_type = std::vector<rgba8_pixel_t>;
|
||||
Buf_type buf( this->_settings._dim.x );
|
||||
Buf_type::iterator dst_it = buf.begin();
|
||||
Buf_type::iterator dst_end = buf.end();
|
||||
|
||||
// If height is positive, the bitmap is a bottom-up DIB.
|
||||
// If height is negative, the bitmap is a top-down DIB.
|
||||
// The origin of a bottom-up DIB is the bottom left corner of the bitmap image,
|
||||
// which is the first pixel of the first row of bitmap data.
|
||||
// The origin of a top-down DIB is also the bottom left corner of the bitmap image,
|
||||
// but in this case the bottom left corner is the first pixel of the last row of bitmap data.
|
||||
// - "Programming Windows", 5th Ed. by Charles Petzold explains Windows docs ambiguities.
|
||||
std::ptrdiff_t ybeg = 0;
|
||||
std::ptrdiff_t yend = this->_settings._dim.y;
|
||||
std::ptrdiff_t yinc = 1;
|
||||
if( this->_info._height > 0 )
|
||||
{
|
||||
ybeg = this->_settings._dim.y - 1;
|
||||
yend = -1;
|
||||
yinc = -1;
|
||||
}
|
||||
|
||||
std::ptrdiff_t y = ybeg;
|
||||
bool finished = false;
|
||||
|
||||
while ( !finished )
|
||||
{
|
||||
std::ptrdiff_t count = this->_io_dev.read_uint8();
|
||||
std::ptrdiff_t second = this->_io_dev.read_uint8();
|
||||
stream_pos += 2;
|
||||
|
||||
if ( count )
|
||||
{
|
||||
// encoded mode
|
||||
|
||||
// clamp to boundary
|
||||
if( count > dst_end - dst_it )
|
||||
{
|
||||
count = dst_end - dst_it;
|
||||
}
|
||||
|
||||
if( this->_info._compression == bmp_compression::_rle4 )
|
||||
{
|
||||
std::ptrdiff_t cs[2] = { second >> 4, second & 0x0f };
|
||||
|
||||
for( int i = 0; i < count; ++i )
|
||||
{
|
||||
*dst_it++ = this->_palette[ cs[i & 1] ];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int i = 0; i < count; ++i )
|
||||
{
|
||||
*dst_it++ = this->_palette[ second ];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( second )
|
||||
{
|
||||
case 0: // end of row
|
||||
{
|
||||
copy_row_if_needed( buf, view, y );
|
||||
|
||||
y += yinc;
|
||||
if( y == yend )
|
||||
{
|
||||
finished = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_it = buf.begin();
|
||||
dst_end = buf.end();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: // end of bitmap
|
||||
{
|
||||
copy_row_if_needed( buf, view, y );
|
||||
finished = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: // offset coordinates
|
||||
{
|
||||
std::ptrdiff_t dx = this->_io_dev.read_uint8();
|
||||
std::ptrdiff_t dy = this->_io_dev.read_uint8() * yinc;
|
||||
stream_pos += 2;
|
||||
|
||||
if( dy )
|
||||
{
|
||||
copy_row_if_needed( buf, view, y );
|
||||
}
|
||||
|
||||
std::ptrdiff_t x = dst_it - buf.begin();
|
||||
x += dx;
|
||||
|
||||
if( x > this->_info._width )
|
||||
{
|
||||
io_error( "Mangled BMP file." );
|
||||
}
|
||||
|
||||
y += dy;
|
||||
if( yinc > 0 ? y > yend : y < yend )
|
||||
{
|
||||
io_error( "Mangled BMP file." );
|
||||
}
|
||||
|
||||
dst_it = buf.begin() + x;
|
||||
dst_end = buf.end();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: // absolute mode
|
||||
{
|
||||
count = second;
|
||||
|
||||
// clamp to boundary
|
||||
if( count > dst_end - dst_it )
|
||||
{
|
||||
count = dst_end - dst_it;
|
||||
}
|
||||
|
||||
if ( this->_info._compression == bmp_compression::_rle4 )
|
||||
{
|
||||
for( int i = 0; i < count; ++i )
|
||||
{
|
||||
uint8_t packed_indices = this->_io_dev.read_uint8();
|
||||
++stream_pos;
|
||||
|
||||
*dst_it++ = this->_palette[ packed_indices >> 4 ];
|
||||
if( ++i == second )
|
||||
break;
|
||||
|
||||
*dst_it++ = this->_palette[ packed_indices & 0x0f ];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int i = 0; i < count; ++i )
|
||||
{
|
||||
uint8_t c = this->_io_dev.read_uint8();
|
||||
++stream_pos;
|
||||
*dst_it++ = this->_palette[ c ];
|
||||
}
|
||||
}
|
||||
|
||||
// pad to word boundary
|
||||
if( ( stream_pos - get_offset( 0 )) & 1 )
|
||||
{
|
||||
this->_io_dev.seek( 1, SEEK_CUR );
|
||||
++stream_pos;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::size_t _pitch;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
class bmp_type_format_checker
|
||||
{
|
||||
public:
|
||||
|
||||
bmp_type_format_checker( const bmp_bits_per_pixel::type& bpp )
|
||||
: _bpp( bpp )
|
||||
{}
|
||||
|
||||
template< typename Image >
|
||||
bool apply()
|
||||
{
|
||||
if( _bpp < 32 )
|
||||
{
|
||||
return pixels_are_compatible< typename Image::value_type, rgb8_pixel_t >::value
|
||||
? true
|
||||
: false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pixels_are_compatible< typename Image::value_type, rgba8_pixel_t >::value
|
||||
? true
|
||||
: false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// to avoid C4512
|
||||
bmp_type_format_checker& operator=( const bmp_type_format_checker& ) { return *this; }
|
||||
|
||||
private:
|
||||
|
||||
const bmp_bits_per_pixel::type _bpp;
|
||||
};
|
||||
|
||||
struct bmp_read_is_supported
|
||||
{
|
||||
template< typename View >
|
||||
struct apply : public is_read_supported< typename get_pixel_type< View >::type
|
||||
, bmp_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///
|
||||
/// BMP Dynamic Reader
|
||||
///
|
||||
template< typename Device >
|
||||
class dynamic_image_reader< Device
|
||||
, bmp_tag
|
||||
>
|
||||
: public reader< Device
|
||||
, bmp_tag
|
||||
, detail::read_and_no_convert
|
||||
>
|
||||
{
|
||||
using parent_t = reader<Device, bmp_tag, detail::read_and_no_convert>;
|
||||
|
||||
public:
|
||||
|
||||
dynamic_image_reader( const Device& io_dev
|
||||
, const image_read_settings< bmp_tag >& settings
|
||||
)
|
||||
: parent_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename Images >
|
||||
void apply( any_image< Images >& images )
|
||||
{
|
||||
detail::bmp_type_format_checker format_checker( this->_info._bits_per_pixel );
|
||||
|
||||
if( !construct_matched( images
|
||||
, format_checker
|
||||
))
|
||||
{
|
||||
io_error( "No matching image type between those of the given any_image and that of the file" );
|
||||
}
|
||||
else
|
||||
{
|
||||
this->init_image( images
|
||||
, this->_settings
|
||||
);
|
||||
|
||||
detail::dynamic_io_fnobj< detail::bmp_read_is_supported
|
||||
, parent_t
|
||||
> op( this );
|
||||
|
||||
apply_operation( view( images )
|
||||
, op
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // gil
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,247 @@
|
||||
//
|
||||
// Copyright 2012 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_BMP_DETAIL_READER_BACKEND_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_DETAIL_READER_BACKEND_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/tags.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
/// Color channel mask
|
||||
struct bit_field
|
||||
{
|
||||
unsigned int mask; // Bit mask at corresponding position
|
||||
unsigned int width; // Bit width of the mask
|
||||
unsigned int shift; // Bit position from right to left
|
||||
};
|
||||
|
||||
/// BMP color masks
|
||||
struct color_mask
|
||||
{
|
||||
bit_field red; // Red bits
|
||||
bit_field green; // Green bits
|
||||
bit_field blue; // Blue bits
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// BMP Backend
|
||||
///
|
||||
template< typename Device >
|
||||
struct reader_backend< Device
|
||||
, bmp_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using format_tag_t = bmp_tag;
|
||||
|
||||
public:
|
||||
|
||||
reader_backend( const Device& io_dev
|
||||
, const image_read_settings< bmp_tag >& settings
|
||||
)
|
||||
: _io_dev ( io_dev )
|
||||
, _settings( settings )
|
||||
, _info()
|
||||
, _scanline_length( 0 )
|
||||
, _palette()
|
||||
{
|
||||
read_header();
|
||||
|
||||
if( _settings._dim.x == 0 )
|
||||
{
|
||||
_settings._dim.x = _info._width;
|
||||
}
|
||||
|
||||
if( _settings._dim.y == 0 )
|
||||
{
|
||||
_settings._dim.y = _info._height;
|
||||
}
|
||||
}
|
||||
|
||||
void read_header()
|
||||
{
|
||||
// the magic number used to identify the BMP file:
|
||||
// 0x42 0x4D (ASCII code points for B and M)
|
||||
if( _io_dev.read_uint16() == 0x424D )
|
||||
{
|
||||
io_error( "Wrong magic number for bmp file." );
|
||||
}
|
||||
|
||||
// the size of the BMP file in bytes
|
||||
_io_dev.read_uint32();
|
||||
|
||||
// reserved; actual value depends on the application that creates the image
|
||||
_io_dev.read_uint16();
|
||||
// reserved; actual value depends on the application that creates the image
|
||||
_io_dev.read_uint16();
|
||||
|
||||
_info._offset = _io_dev.read_uint32();
|
||||
|
||||
|
||||
// bitmap information
|
||||
|
||||
// the size of this header ( 40 bytes )
|
||||
_info._header_size = _io_dev.read_uint32();
|
||||
|
||||
if( _info._header_size == bmp_header_size::_win32_info_size )
|
||||
{
|
||||
_info._width = _io_dev.read_uint32();
|
||||
_info._height = _io_dev.read_uint32();
|
||||
|
||||
if (_info._height < 0)
|
||||
{
|
||||
_info._height = -_info._height;
|
||||
_info._top_down = true;
|
||||
}
|
||||
|
||||
// the number of color planes being used. Must be set to 1.
|
||||
_io_dev.read_uint16();
|
||||
|
||||
_info._bits_per_pixel = _io_dev.read_uint16();
|
||||
|
||||
_info._compression = _io_dev.read_uint32();
|
||||
|
||||
_info._image_size = _io_dev.read_uint32();
|
||||
|
||||
_info._horizontal_resolution = _io_dev.read_uint32();
|
||||
_info._vertical_resolution = _io_dev.read_uint32();
|
||||
|
||||
_info._num_colors = _io_dev.read_uint32();
|
||||
_info._num_important_colors = _io_dev.read_uint32();
|
||||
|
||||
}
|
||||
else if( _info._header_size == bmp_header_size::_os2_info_size )
|
||||
{
|
||||
_info._width = static_cast< bmp_image_width::type >( _io_dev.read_uint16() );
|
||||
_info._height = static_cast< bmp_image_height::type >( _io_dev.read_uint16() );
|
||||
|
||||
// the number of color planes being used. Must be set to 1.
|
||||
_io_dev.read_uint16();
|
||||
|
||||
_info._bits_per_pixel = _io_dev.read_uint16();
|
||||
|
||||
_info._compression = bmp_compression::_rgb;
|
||||
|
||||
// not used
|
||||
_info._image_size = 0;
|
||||
_info._horizontal_resolution = 0;
|
||||
_info._vertical_resolution = 0;
|
||||
_info._num_colors = 0;
|
||||
_info._num_important_colors = 0;
|
||||
}
|
||||
else if (_info._header_size > bmp_header_size::_win32_info_size)
|
||||
{
|
||||
// could be v4 or v5
|
||||
// see MSDN: Bitmap Header Types ( BITMAPV4HEADER or BITMAPV5HEADER )
|
||||
|
||||
_info._width = _io_dev.read_uint32();
|
||||
_info._height = _io_dev.read_uint32();
|
||||
|
||||
// the number of color planes being used. Must be set to 1.
|
||||
_io_dev.read_uint16();
|
||||
|
||||
_info._bits_per_pixel = _io_dev.read_uint16();
|
||||
|
||||
_info._compression = _io_dev.read_uint32();
|
||||
|
||||
_info._image_size = _io_dev.read_uint32();
|
||||
|
||||
_info._horizontal_resolution = _io_dev.read_uint32();
|
||||
_info._vertical_resolution = _io_dev.read_uint32();
|
||||
|
||||
_info._num_colors = _io_dev.read_uint32();
|
||||
_info._num_important_colors = _io_dev.read_uint32();
|
||||
}
|
||||
else
|
||||
{
|
||||
io_error( "Invalid BMP info header." );
|
||||
}
|
||||
|
||||
_info._valid = true;
|
||||
}
|
||||
|
||||
void read_palette()
|
||||
{
|
||||
int entries = this->_info._num_colors;
|
||||
|
||||
if( entries == 0 )
|
||||
{
|
||||
entries = 1u << this->_info._bits_per_pixel;
|
||||
}
|
||||
|
||||
_palette.resize( entries, rgba8_pixel_t(0, 0, 0, 0));
|
||||
|
||||
for( int i = 0; i < entries; ++i )
|
||||
{
|
||||
get_color( _palette[i], blue_t() ) = _io_dev.read_uint8();
|
||||
get_color( _palette[i], green_t() ) = _io_dev.read_uint8();
|
||||
get_color( _palette[i], red_t() ) = _io_dev.read_uint8();
|
||||
|
||||
// there are 4 entries when windows header
|
||||
// but 3 for os2 header
|
||||
if( _info._header_size == bmp_header_size::_win32_info_size )
|
||||
{
|
||||
_io_dev.read_uint8();
|
||||
}
|
||||
|
||||
} // for
|
||||
}
|
||||
|
||||
/// Check if image is large enough.
|
||||
void check_image_size( const point_t& img_dim )
|
||||
{
|
||||
if( _settings._dim.x > 0 )
|
||||
{
|
||||
if( img_dim.x < _settings._dim.x ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if( img_dim.x < _info._width ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
|
||||
|
||||
if( _settings._dim.y > 0 )
|
||||
{
|
||||
if( img_dim.y < _settings._dim.y ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if( img_dim.y < _info._height ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Device _io_dev;
|
||||
|
||||
image_read_settings< bmp_tag > _settings;
|
||||
image_read_info< bmp_tag > _info;
|
||||
|
||||
std::size_t _scanline_length;
|
||||
|
||||
///@todo make it an image.
|
||||
std::vector< rgba8_pixel_t > _palette;
|
||||
|
||||
color_mask _mask;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,414 @@
|
||||
//
|
||||
// Copyright 2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_BMP_DETAIL_SCANLINE_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_DETAIL_SCANLINE_READ_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/detail/is_allowed.hpp>
|
||||
#include <boost/gil/extension/io/bmp/detail/reader_backend.hpp>
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/bit_operations.hpp>
|
||||
#include <boost/gil/io/conversion_policies.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/reader_base.hpp>
|
||||
#include <boost/gil/io/row_buffer_helper.hpp>
|
||||
#include <boost/gil/io/scanline_read_iterator.hpp>
|
||||
#include <boost/gil/io/typedefs.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
///
|
||||
/// BMP Scanline Reader
|
||||
///
|
||||
template< typename Device >
|
||||
class scanline_reader< Device
|
||||
, bmp_tag
|
||||
>
|
||||
: public reader_backend< Device
|
||||
, bmp_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using tag_t = bmp_tag;
|
||||
using backend_t = reader_backend<Device, tag_t>;
|
||||
using this_t = scanline_reader<Device, tag_t>;
|
||||
using iterator_t = scanline_read_iterator<this_t>;
|
||||
|
||||
public:
|
||||
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
scanline_reader( Device& device
|
||||
, const image_read_settings< bmp_tag >& settings
|
||||
)
|
||||
: backend_t( device
|
||||
, settings
|
||||
)
|
||||
|
||||
, _pitch( 0 )
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
/// Read part of image defined by View and return the data.
|
||||
void read( byte_t* dst, int pos )
|
||||
{
|
||||
// jump to scanline
|
||||
long offset = 0;
|
||||
|
||||
if( this->_info._height > 0 )
|
||||
{
|
||||
// the image is upside down
|
||||
offset = this->_info._offset
|
||||
+ ( this->_info._height - 1 - pos ) * this->_pitch;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = this->_info._offset
|
||||
+ pos * _pitch;
|
||||
}
|
||||
|
||||
this->_io_dev.seek( offset );
|
||||
|
||||
|
||||
// read data
|
||||
_read_function(this, dst);
|
||||
}
|
||||
|
||||
/// Skip over a scanline.
|
||||
void skip( byte_t*, int )
|
||||
{
|
||||
// nothing to do.
|
||||
}
|
||||
|
||||
iterator_t begin() { return iterator_t( *this ); }
|
||||
iterator_t end() { return iterator_t( *this, this->_info._height ); }
|
||||
|
||||
private:
|
||||
|
||||
void initialize()
|
||||
{
|
||||
if( this->_info._bits_per_pixel < 8 )
|
||||
{
|
||||
_pitch = (( this->_info._width * this->_info._bits_per_pixel ) + 7 ) >> 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
_pitch = this->_info._width * (( this->_info._bits_per_pixel + 7 ) >> 3);
|
||||
}
|
||||
|
||||
_pitch = (_pitch + 3) & ~3;
|
||||
|
||||
//
|
||||
|
||||
switch( this->_info._bits_per_pixel )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgba8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_palette();
|
||||
_buffer.resize( _pitch );
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_1_bit_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
switch( this->_info._compression )
|
||||
{
|
||||
case bmp_compression::_rle4:
|
||||
{
|
||||
io_error( "Cannot read run-length encoded images in iterator mode. Try to read as whole image." );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case bmp_compression::_rgb :
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgba8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_palette();
|
||||
_buffer.resize( _pitch );
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_4_bits_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
io_error( "Unsupported compression mode in BMP file." );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 8:
|
||||
{
|
||||
switch( this->_info._compression )
|
||||
{
|
||||
case bmp_compression::_rle8:
|
||||
{
|
||||
io_error( "Cannot read run-length encoded images in iterator mode. Try to read as whole image." );
|
||||
|
||||
break;
|
||||
}
|
||||
case bmp_compression::_rgb:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgba8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
read_palette();
|
||||
_buffer.resize( _pitch );
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_8_bits_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: { io_error( "Unsupported compression mode in BMP file." ); break; }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 15:
|
||||
case 16:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgb8_view_t >::value + 3 ) & ~3;
|
||||
|
||||
_buffer.resize( _pitch );
|
||||
|
||||
if( this->_info._compression == bmp_compression::_bitfield )
|
||||
{
|
||||
this->_mask.red.mask = this->_io_dev.read_uint32();
|
||||
this->_mask.green.mask = this->_io_dev.read_uint32();
|
||||
this->_mask.blue.mask = this->_io_dev.read_uint32();
|
||||
|
||||
this->_mask.red.width = detail::count_ones( this->_mask.red.mask );
|
||||
this->_mask.green.width = detail::count_ones( this->_mask.green.mask );
|
||||
this->_mask.blue.width = detail::count_ones( this->_mask.blue.mask );
|
||||
|
||||
this->_mask.red.shift = detail::trailing_zeros( this->_mask.red.mask );
|
||||
this->_mask.green.shift = detail::trailing_zeros( this->_mask.green.mask );
|
||||
this->_mask.blue.shift = detail::trailing_zeros( this->_mask.blue.mask );
|
||||
}
|
||||
else if( this->_info._compression == bmp_compression::_rgb )
|
||||
{
|
||||
switch( this->_info._bits_per_pixel )
|
||||
{
|
||||
case 15:
|
||||
case 16:
|
||||
{
|
||||
this->_mask.red.mask = 0x007C00; this->_mask.red.width = 5; this->_mask.red.shift = 10;
|
||||
this->_mask.green.mask = 0x0003E0; this->_mask.green.width = 5; this->_mask.green.shift = 5;
|
||||
this->_mask.blue.mask = 0x00001F; this->_mask.blue.width = 5; this->_mask.blue.shift = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
this->_mask.red.mask = 0xFF0000; this->_mask.red.width = 8; this->_mask.red.shift = 16;
|
||||
this->_mask.green.mask = 0x00FF00; this->_mask.green.width = 8; this->_mask.green.shift = 8;
|
||||
this->_mask.blue.mask = 0x0000FF; this->_mask.blue.width = 8; this->_mask.blue.shift = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
io_error( "Unsupported BMP compression." );
|
||||
}
|
||||
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_15_bits_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 24:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgb8_view_t >::value + 3 ) & ~3;
|
||||
_read_function = std::mem_fn(&this_t::read_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 32:
|
||||
{
|
||||
this->_scanline_length = ( this->_info._width * num_channels< rgba8_view_t >::value + 3 ) & ~3;
|
||||
_read_function = std::mem_fn(&this_t::read_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
io_error( "Unsupported bits per pixel." );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void read_palette()
|
||||
{
|
||||
if( this->_palette.size() > 0 )
|
||||
{
|
||||
// palette has been read already.
|
||||
return;
|
||||
}
|
||||
|
||||
int entries = this->_info._num_colors;
|
||||
|
||||
if( entries == 0 )
|
||||
{
|
||||
entries = 1u << this->_info._bits_per_pixel;
|
||||
}
|
||||
|
||||
this->_palette.resize( entries, rgba8_pixel_t(0,0,0,0) );
|
||||
|
||||
for( int i = 0; i < entries; ++i )
|
||||
{
|
||||
get_color( this->_palette[i], blue_t() ) = this->_io_dev.read_uint8();
|
||||
get_color( this->_palette[i], green_t() ) = this->_io_dev.read_uint8();
|
||||
get_color( this->_palette[i], red_t() ) = this->_io_dev.read_uint8();
|
||||
|
||||
// there are 4 entries when windows header
|
||||
// but 3 for os2 header
|
||||
if( this->_info._header_size == bmp_header_size::_win32_info_size )
|
||||
{
|
||||
this->_io_dev.read_uint8();
|
||||
}
|
||||
|
||||
} // for
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
void read_bit_row( byte_t* dst )
|
||||
{
|
||||
using src_view_t = View;
|
||||
using dst_view_t = rgba8_image_t::view_t;
|
||||
|
||||
src_view_t src_view = interleaved_view( this->_info._width
|
||||
, 1
|
||||
, (typename src_view_t::x_iterator) &_buffer.front()
|
||||
, this->_pitch
|
||||
);
|
||||
|
||||
dst_view_t dst_view = interleaved_view( this->_info._width
|
||||
, 1
|
||||
, (typename dst_view_t::value_type*) dst
|
||||
, num_channels< dst_view_t >::value * this->_info._width
|
||||
);
|
||||
|
||||
|
||||
typename src_view_t::x_iterator src_it = src_view.row_begin( 0 );
|
||||
typename dst_view_t::x_iterator dst_it = dst_view.row_begin( 0 );
|
||||
|
||||
for( dst_view_t::x_coord_t i = 0
|
||||
; i < this->_info._width
|
||||
; ++i, src_it++, dst_it++
|
||||
)
|
||||
{
|
||||
unsigned char c = get_color( *src_it, gray_color_t() );
|
||||
*dst_it = this->_palette[c];
|
||||
}
|
||||
}
|
||||
|
||||
// Read 1 bit image. The colors are encoded by an index.
|
||||
void read_1_bit_row( byte_t* dst )
|
||||
{
|
||||
this->_io_dev.read( &_buffer.front(), _pitch );
|
||||
_mirror_bits( _buffer );
|
||||
|
||||
read_bit_row< gray1_image_t::view_t >( dst );
|
||||
}
|
||||
|
||||
// Read 4 bits image. The colors are encoded by an index.
|
||||
void read_4_bits_row( byte_t* dst )
|
||||
{
|
||||
this->_io_dev.read( &_buffer.front(), _pitch );
|
||||
_swap_half_bytes( _buffer );
|
||||
|
||||
read_bit_row< gray4_image_t::view_t >( dst );
|
||||
}
|
||||
|
||||
/// Read 8 bits image. The colors are encoded by an index.
|
||||
void read_8_bits_row( byte_t* dst )
|
||||
{
|
||||
this->_io_dev.read( &_buffer.front(), _pitch );
|
||||
|
||||
read_bit_row< gray8_image_t::view_t >( dst );
|
||||
}
|
||||
|
||||
/// Read 15 or 16 bits image.
|
||||
void read_15_bits_row( byte_t* dst )
|
||||
{
|
||||
using dst_view_t = rgb8_view_t;
|
||||
|
||||
dst_view_t dst_view = interleaved_view( this->_info._width
|
||||
, 1
|
||||
, (typename dst_view_t::value_type*) dst
|
||||
, this->_pitch
|
||||
);
|
||||
|
||||
typename dst_view_t::x_iterator dst_it = dst_view.row_begin( 0 );
|
||||
|
||||
//
|
||||
byte_t* src = &_buffer.front();
|
||||
this->_io_dev.read( src, _pitch );
|
||||
|
||||
for( dst_view_t::x_coord_t i = 0
|
||||
; i < this->_info._width
|
||||
; ++i, src += 2
|
||||
)
|
||||
{
|
||||
int p = ( src[1] << 8 ) | src[0];
|
||||
|
||||
int r = ((p & this->_mask.red.mask) >> this->_mask.red.shift) << (8 - this->_mask.red.width);
|
||||
int g = ((p & this->_mask.green.mask) >> this->_mask.green.shift) << (8 - this->_mask.green.width);
|
||||
int b = ((p & this->_mask.blue.mask) >> this->_mask.blue.shift) << (8 - this->_mask.blue.width);
|
||||
|
||||
get_color( dst_it[i], red_t() ) = static_cast< byte_t >( r );
|
||||
get_color( dst_it[i], green_t() ) = static_cast< byte_t >( g );
|
||||
get_color( dst_it[i], blue_t() ) = static_cast< byte_t >( b );
|
||||
}
|
||||
}
|
||||
|
||||
void read_row( byte_t* dst )
|
||||
{
|
||||
this->_io_dev.read( dst, _pitch );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// the row pitch must be multiple of 4 bytes
|
||||
int _pitch;
|
||||
|
||||
std::vector<byte_t> _buffer;
|
||||
detail::mirror_bits <std::vector<byte_t>, std::true_type> _mirror_bits;
|
||||
detail::swap_half_bytes<std::vector<byte_t>, std::true_type> _swap_half_bytes;
|
||||
|
||||
std::function<void(this_t*, byte_t*)> _read_function;
|
||||
};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,140 @@
|
||||
//
|
||||
// Copyright 2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_BMP_DETAIL_SUPPORTED_TYPES_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_DETAIL_SUPPORTED_TYPES_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/tags.hpp>
|
||||
|
||||
#include <boost/gil/bit_aligned_pixel_reference.hpp>
|
||||
#include <boost/gil/channel.hpp>
|
||||
#include <boost/gil/color_base.hpp>
|
||||
#include <boost/gil/packed_pixel.hpp>
|
||||
#include <boost/gil/io/base.hpp>
|
||||
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
// Read support
|
||||
|
||||
template< typename Channel
|
||||
, typename ColorSpace
|
||||
>
|
||||
struct bmp_read_support : read_support_false
|
||||
{
|
||||
static const bmp_bits_per_pixel::type bpp = 0;
|
||||
};
|
||||
|
||||
template< typename BitField
|
||||
, bool Mutable
|
||||
>
|
||||
struct bmp_read_support< packed_dynamic_channel_reference< BitField
|
||||
, 1
|
||||
, Mutable
|
||||
>
|
||||
, gray_t
|
||||
> : read_support_true
|
||||
{
|
||||
static const bmp_bits_per_pixel::type bpp = 1;
|
||||
};
|
||||
|
||||
template< typename BitField
|
||||
, bool Mutable
|
||||
>
|
||||
struct bmp_read_support< packed_dynamic_channel_reference< BitField
|
||||
, 4
|
||||
, Mutable
|
||||
>
|
||||
, gray_t
|
||||
> : read_support_true
|
||||
{
|
||||
static const bmp_bits_per_pixel::type bpp = 4;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct bmp_read_support<uint8_t
|
||||
, gray_t
|
||||
> : read_support_true
|
||||
{
|
||||
static const bmp_bits_per_pixel::type bpp = 8;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<>
|
||||
struct bmp_read_support<uint8_t
|
||||
, rgb_t
|
||||
> : read_support_true
|
||||
{
|
||||
static const bmp_bits_per_pixel::type bpp = 24;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct bmp_read_support<uint8_t
|
||||
, rgba_t
|
||||
> : read_support_true
|
||||
{
|
||||
static const bmp_bits_per_pixel::type bpp = 32;
|
||||
};
|
||||
|
||||
|
||||
// Write support
|
||||
|
||||
template< typename Channel
|
||||
, typename ColorSpace
|
||||
>
|
||||
struct bmp_write_support : write_support_false
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct bmp_write_support<uint8_t
|
||||
, rgb_t
|
||||
> : write_support_true {};
|
||||
|
||||
template<>
|
||||
struct bmp_write_support<uint8_t
|
||||
, rgba_t
|
||||
> : write_support_true {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template< typename Pixel >
|
||||
struct is_read_supported< Pixel
|
||||
, bmp_tag
|
||||
>
|
||||
: mpl::bool_< detail::bmp_read_support< typename channel_type< Pixel >::type
|
||||
, typename color_space_type< Pixel >::type
|
||||
>::is_supported
|
||||
>
|
||||
{
|
||||
using parent_t = detail::bmp_read_support
|
||||
<
|
||||
typename channel_type<Pixel>::type,
|
||||
typename color_space_type<Pixel>::type
|
||||
>;
|
||||
|
||||
static const typename bmp_bits_per_pixel::type bpp = parent_t::bpp;
|
||||
};
|
||||
|
||||
template< typename Pixel >
|
||||
struct is_write_supported< Pixel
|
||||
, bmp_tag
|
||||
>
|
||||
: mpl::bool_< detail::bmp_write_support< typename channel_type< Pixel >::type
|
||||
, typename color_space_type< Pixel >::type
|
||||
>::is_supported
|
||||
> {};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
217
linx64/include/boost/gil/extension/io/bmp/detail/write.hpp
Normal file
217
linx64/include/boost/gil/extension/io/bmp/detail/write.hpp
Normal file
@@ -0,0 +1,217 @@
|
||||
//
|
||||
// Copyright 2012 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_BMP_DETAIL_WRITE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_DETAIL_WRITE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/tags.hpp>
|
||||
#include <boost/gil/extension/io/bmp/detail/writer_backend.hpp>
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/dynamic_io_new.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct bmp_write_is_supported
|
||||
{
|
||||
template< typename View >
|
||||
struct apply
|
||||
: public is_write_supported< typename get_pixel_type< View >::type
|
||||
, bmp_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
template < int N > struct get_bgr_cs {};
|
||||
template <> struct get_bgr_cs< 1 > { using type = gray8_view_t; };
|
||||
template <> struct get_bgr_cs< 3 > { using type = bgr8_view_t; };
|
||||
template <> struct get_bgr_cs< 4 > { using type = bgra8_view_t; };
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///
|
||||
/// BMP Writer
|
||||
///
|
||||
template< typename Device >
|
||||
class writer< Device
|
||||
, bmp_tag
|
||||
>
|
||||
: public writer_backend< Device
|
||||
, bmp_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
writer( const Device& io_dev
|
||||
, const image_write_info< bmp_tag >& info
|
||||
)
|
||||
: backend_t( io_dev
|
||||
, info
|
||||
)
|
||||
{}
|
||||
|
||||
template<typename View>
|
||||
void apply( const View& view )
|
||||
{
|
||||
write( view );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
using backend_t = writer_backend<Device, bmp_tag>;
|
||||
|
||||
template< typename View >
|
||||
void write( const View& view )
|
||||
{
|
||||
// using channel_t = typename channel_type<
|
||||
// typename get_pixel_type<View>::type>::type;
|
||||
|
||||
// using color_space_t = typename color_space_type<View>::type;
|
||||
|
||||
// check if supported
|
||||
/*
|
||||
/// todo
|
||||
if( bmp_read_write_support_private<channel_t, color_space_t>::channel != 8)
|
||||
{
|
||||
io_error("Input view type is incompatible with the image type");
|
||||
}
|
||||
*/
|
||||
|
||||
// compute the file size
|
||||
int bpp = num_channels< View >::value * 8;
|
||||
int entries = 0;
|
||||
|
||||
/*
|
||||
/// @todo: Not supported for now. bit_aligned_images refer to indexed images
|
||||
/// in this context.
|
||||
if( bpp <= 8 )
|
||||
{
|
||||
entries = 1u << bpp;
|
||||
}
|
||||
*/
|
||||
|
||||
std::size_t spn = ( view.width() * num_channels< View >::value + 3 ) & ~3;
|
||||
std::size_t ofs = bmp_header_size::_size
|
||||
+ bmp_header_size::_win32_info_size
|
||||
+ entries * 4;
|
||||
|
||||
std::size_t siz = ofs + spn * view.height();
|
||||
|
||||
// write the BMP file header
|
||||
this->_io_dev.write_uint16( bmp_signature );
|
||||
this->_io_dev.write_uint32( (uint32_t) siz );
|
||||
this->_io_dev.write_uint16( 0 );
|
||||
this->_io_dev.write_uint16( 0 );
|
||||
this->_io_dev.write_uint32( (uint32_t) ofs );
|
||||
|
||||
// writes Windows information header
|
||||
this->_io_dev.write_uint32( bmp_header_size::_win32_info_size );
|
||||
this->_io_dev.write_uint32( static_cast< uint32_t >( view.width() ));
|
||||
this->_io_dev.write_uint32( static_cast< uint32_t >( view.height() ));
|
||||
this->_io_dev.write_uint16( 1 );
|
||||
this->_io_dev.write_uint16( static_cast< uint16_t >( bpp ));
|
||||
this->_io_dev.write_uint32( bmp_compression::_rgb );
|
||||
this->_io_dev.write_uint32( 0 );
|
||||
this->_io_dev.write_uint32( 0 );
|
||||
this->_io_dev.write_uint32( 0 );
|
||||
this->_io_dev.write_uint32( entries );
|
||||
this->_io_dev.write_uint32( 0 );
|
||||
|
||||
write_image< View
|
||||
, typename detail::get_bgr_cs< num_channels< View >::value >::type
|
||||
>( view, spn );
|
||||
}
|
||||
|
||||
|
||||
template< typename View
|
||||
, typename BMP_View
|
||||
>
|
||||
void write_image( const View& view
|
||||
, const std::size_t spn
|
||||
)
|
||||
{
|
||||
byte_vector_t buffer( spn );
|
||||
std::fill( buffer.begin(), buffer.end(), 0 );
|
||||
|
||||
|
||||
BMP_View row = interleaved_view( view.width()
|
||||
, 1
|
||||
, (typename BMP_View::value_type*) &buffer.front()
|
||||
, spn
|
||||
);
|
||||
|
||||
for( typename View::y_coord_t y = view.height() - 1; y > -1; --y )
|
||||
{
|
||||
copy_pixels( subimage_view( view
|
||||
, 0
|
||||
, (int) y
|
||||
, (int) view.width()
|
||||
, 1
|
||||
)
|
||||
, row
|
||||
);
|
||||
|
||||
this->_io_dev.write( &buffer.front(), spn );
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// BMP Dynamic Image Writer
|
||||
///
|
||||
template< typename Device >
|
||||
class dynamic_image_writer< Device
|
||||
, bmp_tag
|
||||
>
|
||||
: public writer< Device
|
||||
, bmp_tag
|
||||
>
|
||||
{
|
||||
using parent_t = writer<Device, bmp_tag>;
|
||||
|
||||
public:
|
||||
|
||||
dynamic_image_writer( const Device& io_dev
|
||||
, const image_write_info< bmp_tag >& info
|
||||
)
|
||||
: parent_t( io_dev
|
||||
, info
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename Views >
|
||||
void apply( const any_image_view< Views >& views )
|
||||
{
|
||||
detail::dynamic_io_fnobj< detail::bmp_write_is_supported
|
||||
, parent_t
|
||||
> op( this );
|
||||
|
||||
apply_operation( views
|
||||
, op
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // gil
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// Copyright 2012 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_BMP_DETAIL_WRITER_BACKEND_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_DETAIL_WRITER_BACKEND_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/tags.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
///
|
||||
/// BMP Writer Backend
|
||||
///
|
||||
template< typename Device >
|
||||
struct writer_backend< Device
|
||||
, bmp_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using format_tag_t = bmp_tag;
|
||||
|
||||
public:
|
||||
|
||||
writer_backend( const Device& io_dev
|
||||
, const image_write_info< bmp_tag >& info
|
||||
)
|
||||
: _io_dev( io_dev )
|
||||
, _info ( info )
|
||||
{}
|
||||
|
||||
public:
|
||||
|
||||
Device _io_dev;
|
||||
|
||||
image_write_info< bmp_tag > _info;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
160
linx64/include/boost/gil/extension/io/bmp/old.hpp
Normal file
160
linx64/include/boost/gil/extension/io/bmp/old.hpp
Normal file
@@ -0,0 +1,160 @@
|
||||
//
|
||||
// Copyright 2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_BMP_OLD_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_OLD_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \ingroup BMP_IO
|
||||
/// \brief Returns the width and height of the BMP file at the specified location.
|
||||
/// Throws std::ios_base::failure if the location does not correspond to a valid BMP file
|
||||
template<typename String>
|
||||
inline point_t bmp_read_dimensions(String const& filename)
|
||||
{
|
||||
using backend_t = typename get_reader_backend<String, bmp_tag>::type;
|
||||
backend_t backend = read_image_info(filename, bmp_tag());
|
||||
return { backend._info._width, backend._info._height };
|
||||
}
|
||||
|
||||
/// \ingroup BMP_IO
|
||||
/// \brief Loads the image specified by the given bmp image file name into the given view.
|
||||
/// Triggers a compile assert if the view color space and channel depth are not supported by the BMP library or by the I/O extension.
|
||||
/// Throws std::ios_base::failure if the file is not a valid BMP 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 String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void bmp_read_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
read_view( filename
|
||||
, view
|
||||
, bmp_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup BMP_IO
|
||||
/// \brief Allocates a new image whose dimensions are determined by the given bmp 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 BMP library or by the I/O extension.
|
||||
/// Throws std::ios_base::failure if the file is not a valid BMP file, or if its color space or channel depth are not
|
||||
/// compatible with the ones specified by Image
|
||||
template< typename String
|
||||
, typename Image
|
||||
>
|
||||
inline
|
||||
void bmp_read_image( const String& filename
|
||||
, Image& img
|
||||
)
|
||||
{
|
||||
read_image( filename
|
||||
, img
|
||||
, bmp_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup BMP_IO
|
||||
/// \brief Loads and color-converts the image specified by the given bmp image file name into the given view.
|
||||
/// Throws std::ios_base::failure if the file is not a valid BMP file, or if its dimensions don't match the ones of the view.
|
||||
template< typename String
|
||||
, typename View
|
||||
, typename CC
|
||||
>
|
||||
inline
|
||||
void bmp_read_and_convert_view( const String& filename
|
||||
, const View& view
|
||||
, CC cc
|
||||
)
|
||||
{
|
||||
read_and_convert_view( filename
|
||||
, view
|
||||
, cc
|
||||
, bmp_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup BMP_IO
|
||||
/// \brief Loads and color-converts the image specified by the given bmp image file name into the given view.
|
||||
/// Throws std::ios_base::failure if the file is not a valid BMP file, or if its dimensions don't match the ones of the view.
|
||||
template< typename String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void bmp_read_and_convert_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
read_and_convert_view( filename
|
||||
, view
|
||||
, bmp_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup BMP_IO
|
||||
/// \brief Allocates a new image whose dimensions are determined by the given bmp image file, loads and color-converts the pixels into it.
|
||||
/// Throws std::ios_base::failure if the file is not a valid BMP file
|
||||
template< typename String
|
||||
, typename Image
|
||||
, typename CC
|
||||
>
|
||||
inline
|
||||
void bmp_read_and_convert_image( const String& filename
|
||||
, Image& img
|
||||
, CC cc
|
||||
)
|
||||
{
|
||||
read_and_convert_image( filename
|
||||
, img
|
||||
, cc
|
||||
, bmp_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup BMP_IO
|
||||
/// \brief Allocates a new image whose dimensions are determined by the given bmp image file, loads and color-converts the pixels into it.
|
||||
/// Throws std::ios_base::failure if the file is not a valid BMP file
|
||||
template< typename String
|
||||
, typename Image
|
||||
>
|
||||
inline
|
||||
void bmp_read_and_convert_image( const String filename
|
||||
, Image& img
|
||||
)
|
||||
{
|
||||
read_and_convert_image( filename
|
||||
, img
|
||||
, bmp_tag()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/// \ingroup BMP_IO
|
||||
/// \brief Saves the view to a bmp file specified by the given bmp image file name.
|
||||
/// Triggers a compile assert if the view color space and channel depth are not supported by the BMP library or by the I/O extension.
|
||||
/// Throws std::ios_base::failure if it fails to create the file.
|
||||
template< typename String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void bmp_write_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
write_view( filename
|
||||
, view
|
||||
, bmp_tag()
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
30
linx64/include/boost/gil/extension/io/bmp/read.hpp
Normal file
30
linx64/include/boost/gil/extension/io/bmp/read.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// Copyright 2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_BMP_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_READ_HPP
|
||||
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_READ_ENABLED // TODO: Document, explain, review
|
||||
|
||||
#include <boost/gil/extension/io/bmp/tags.hpp>
|
||||
#include <boost/gil/extension/io/bmp/detail/read.hpp>
|
||||
#include <boost/gil/extension/io/bmp/detail/scanline_read.hpp>
|
||||
#include <boost/gil/extension/io/bmp/detail/supported_types.hpp>
|
||||
|
||||
#include <boost/gil/io/get_reader.hpp>
|
||||
#include <boost/gil/io/make_backend.hpp>
|
||||
#include <boost/gil/io/make_dynamic_image_reader.hpp>
|
||||
#include <boost/gil/io/make_reader.hpp>
|
||||
#include <boost/gil/io/make_scanline_reader.hpp>
|
||||
#include <boost/gil/io/read_and_convert_image.hpp>
|
||||
#include <boost/gil/io/read_and_convert_view.hpp>
|
||||
#include <boost/gil/io/read_image.hpp>
|
||||
#include <boost/gil/io/read_image_info.hpp>
|
||||
#include <boost/gil/io/read_view.hpp>
|
||||
#include <boost/gil/io/scanline_read_iterator.hpp>
|
||||
|
||||
#endif
|
||||
159
linx64/include/boost/gil/extension/io/bmp/tags.hpp
Normal file
159
linx64/include/boost/gil/extension/io/bmp/tags.hpp
Normal file
@@ -0,0 +1,159 @@
|
||||
//
|
||||
// Copyright 2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_BMP_TAGS_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_TAGS_HPP
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// Defines bmp tag.
|
||||
struct bmp_tag : format_tag {};
|
||||
|
||||
/// See http://en.wikipedia.org/wiki/BMP_file_format#BMP_File_Header for reference.
|
||||
|
||||
/// Defines type for offset value.
|
||||
struct bmp_offset : property_base< uint32_t > {};
|
||||
|
||||
/// Defines type for header sizes.
|
||||
struct bmp_header_size : property_base< uint32_t >
|
||||
{
|
||||
static const type _size = 14; /// Constant size for bmp file header size.
|
||||
static const type _win32_info_size = 40; /// Constant size for win32 bmp info header size.
|
||||
static const type _os2_info_size = 12; /// Constant size for os2 bmp info header size.
|
||||
};
|
||||
|
||||
/// Defines type for image width property.
|
||||
struct bmp_image_width : property_base< int32_t > {};
|
||||
|
||||
/// Defines type for image height property.
|
||||
struct bmp_image_height : property_base< int32_t > {};
|
||||
|
||||
/// Defines type for bits per pixels property.
|
||||
struct bmp_bits_per_pixel : property_base< uint16_t > {};
|
||||
|
||||
/// Defines type for compression property.
|
||||
struct bmp_compression : property_base< uint32_t >
|
||||
{
|
||||
static const type _rgb = 0; /// RGB without compression
|
||||
static const type _rle8 = 1; /// 8 bit index with RLE compression
|
||||
static const type _rle4 = 2; /// 4 bit index with RLE compression
|
||||
static const type _bitfield = 3; /// 16 or 32 bit fields without compression
|
||||
};
|
||||
|
||||
/// Defines type for image size property.
|
||||
struct bmp_image_size : property_base< uint32_t > {};
|
||||
|
||||
/// Defines type for horizontal resolution property.
|
||||
struct bmp_horizontal_resolution : property_base< int32_t > {};
|
||||
|
||||
/// Defines type for vertical resolution property.
|
||||
struct bmp_vertical_resolution : property_base< int32_t > {};
|
||||
|
||||
/// Defines type for number of colors property.
|
||||
struct bmp_num_colors : property_base< uint32_t > {};
|
||||
|
||||
/// Defines type for important number of colors property.
|
||||
struct bmp_num_important_colors : property_base< uint32_t > {};
|
||||
|
||||
/// if height is negative then image is stored top-down instead of bottom-up.
|
||||
struct bmp_top_down : property_base< bool > {};
|
||||
|
||||
static const uint32_t bmp_signature = 0x4D42; /// Constant signature for bmp file format.
|
||||
|
||||
/// Read information for bmp images.
|
||||
///
|
||||
/// The structure is returned when using read_image_info.
|
||||
template<>
|
||||
struct image_read_info< bmp_tag >
|
||||
{
|
||||
/// Default contructor.
|
||||
image_read_info< bmp_tag >()
|
||||
: _top_down(false)
|
||||
, _valid( false )
|
||||
{}
|
||||
|
||||
/// The offset, i.e. starting address, of the byte where the bitmap data can be found.
|
||||
bmp_offset::type _offset;
|
||||
|
||||
/// The size of this header:
|
||||
/// - 40 bytes for Windows V3 header
|
||||
/// - 12 bytes for OS/2 V1 header
|
||||
bmp_header_size::type _header_size;
|
||||
|
||||
/// The bitmap width in pixels ( signed integer ).
|
||||
bmp_image_width::type _width;
|
||||
|
||||
/// The bitmap height in pixels ( signed integer ).
|
||||
bmp_image_height::type _height;
|
||||
|
||||
/// The number of bits per pixel, which is the color depth of the image.
|
||||
/// Typical values are 1, 4, 8, 16, 24 and 32.
|
||||
bmp_bits_per_pixel::type _bits_per_pixel;
|
||||
|
||||
/// The compression method being used. See above for a list of possible values.
|
||||
bmp_compression::type _compression;
|
||||
|
||||
/// The image size. This is the size of the raw bitmap data (see below),
|
||||
/// and should not be confused with the file size.
|
||||
bmp_image_size::type _image_size;
|
||||
|
||||
/// The horizontal resolution of the image. (pixel per meter, signed integer)
|
||||
bmp_horizontal_resolution::type _horizontal_resolution;
|
||||
|
||||
/// The vertical resolution of the image. (pixel per meter, signed integer)
|
||||
bmp_vertical_resolution::type _vertical_resolution;
|
||||
|
||||
/// The number of colors in the color palette, or 0 to default to 2^n - 1.
|
||||
bmp_num_colors::type _num_colors;
|
||||
|
||||
/// The number of important colors used, or 0 when every color is important;
|
||||
/// generally ignored.
|
||||
bmp_num_important_colors::type _num_important_colors;
|
||||
|
||||
bmp_top_down::type _top_down;
|
||||
|
||||
/// Used internaly to identify is the header has been read.
|
||||
bool _valid;
|
||||
};
|
||||
|
||||
/// Read settings for bmp images.
|
||||
///
|
||||
/// The structure can be used for all read_xxx functions, except read_image_info.
|
||||
template<>
|
||||
struct image_read_settings< bmp_tag > : public image_read_settings_base
|
||||
{
|
||||
/// Default constructor
|
||||
image_read_settings()
|
||||
: image_read_settings_base()
|
||||
{}
|
||||
|
||||
/// Constructor
|
||||
/// \param top_left Top left coordinate for reading partial image.
|
||||
/// \param dim Dimensions for reading partial image.
|
||||
image_read_settings( const point_t& top_left
|
||||
, const point_t& dim
|
||||
)
|
||||
: image_read_settings_base( top_left
|
||||
, dim
|
||||
)
|
||||
{}
|
||||
};
|
||||
|
||||
/// Write information for bmp images.
|
||||
///
|
||||
/// The structure can be used for write_view() function.
|
||||
template<>
|
||||
struct image_write_info< bmp_tag >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
19
linx64/include/boost/gil/extension/io/bmp/write.hpp
Normal file
19
linx64/include/boost/gil/extension/io/bmp/write.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright 2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_BMP_WRITE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_BMP_WRITE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/bmp/tags.hpp>
|
||||
#include <boost/gil/extension/io/bmp/detail/supported_types.hpp>
|
||||
#include <boost/gil/extension/io/bmp/detail/write.hpp>
|
||||
|
||||
#include <boost/gil/io/make_writer.hpp>
|
||||
#include <boost/gil/io/make_dynamic_image_writer.hpp>
|
||||
#include <boost/gil/io/write_view.hpp>
|
||||
|
||||
#endif
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
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
|
||||
14
linx64/include/boost/gil/extension/io/jpeg.hpp
Normal file
14
linx64/include/boost/gil/extension/io/jpeg.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_JPEG_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_JPEG_HPP
|
||||
|
||||
#include <boost/gil/extension/io/jpeg/read.hpp>
|
||||
#include <boost/gil/extension/io/jpeg/write.hpp>
|
||||
|
||||
#endif
|
||||
38
linx64/include/boost/gil/extension/io/jpeg/detail/base.hpp
Normal file
38
linx64/include/boost/gil/extension/io/jpeg/detail/base.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// Copyright 2010 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_JPEG_DETAIL_BASE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_JPEG_DETAIL_BASE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/jpeg/tags.hpp>
|
||||
|
||||
#include <csetjmp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4324) //structure was padded due to __declspec(align())
|
||||
#endif
|
||||
|
||||
class jpeg_io_base
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
jpeg_error_mgr _jerr;
|
||||
jmp_buf _mark;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// Copyright 2009 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_JPEG_DETAIL_IS_ALLOWED_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_JPEG_DETAIL_IS_ALLOWED_HPP
|
||||
|
||||
#include <boost/gil/extension/io/jpeg/tags.hpp>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
template< typename View >
|
||||
bool is_allowed( const image_read_info< jpeg_tag >& info
|
||||
, mpl::true_ // is read_and_no_convert
|
||||
)
|
||||
{
|
||||
if( info._color_space == JCS_YCbCr )
|
||||
{
|
||||
// We read JCS_YCbCr files as rgb.
|
||||
return ( is_read_supported< typename View::value_type
|
||||
, jpeg_tag
|
||||
>::_color_space == JCS_RGB );
|
||||
}
|
||||
|
||||
return ( is_read_supported< typename View::value_type
|
||||
, jpeg_tag
|
||||
>::_color_space == info._color_space );
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
bool is_allowed( const image_read_info< jpeg_tag >& /* info */
|
||||
, mpl::false_ // is read_and_convert
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
316
linx64/include/boost/gil/extension/io/jpeg/detail/read.hpp
Normal file
316
linx64/include/boost/gil/extension/io/jpeg/detail/read.hpp
Normal file
@@ -0,0 +1,316 @@
|
||||
//
|
||||
// Copyright 2007-2012 Christian Henning, Andreas Pokorny, Lubomir Bourdev
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_JPEG_DETAIL_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_JPEG_DETAIL_READ_HPP
|
||||
|
||||
#include <boost/gil/extension/io/jpeg/tags.hpp>
|
||||
#include <boost/gil/extension/io/jpeg/detail/base.hpp>
|
||||
#include <boost/gil/extension/io/jpeg/detail/is_allowed.hpp>
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/conversion_policies.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/dynamic_io_new.hpp>
|
||||
#include <boost/gil/io/reader_base.hpp>
|
||||
#include <boost/gil/io/typedefs.hpp>
|
||||
|
||||
#include <csetjmp>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#pragma warning(disable:4611) //interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#endif
|
||||
|
||||
///
|
||||
/// JPEG Reader
|
||||
///
|
||||
template< typename Device
|
||||
, typename ConversionPolicy
|
||||
>
|
||||
class reader< Device
|
||||
, jpeg_tag
|
||||
, ConversionPolicy
|
||||
>
|
||||
: public reader_base< jpeg_tag
|
||||
, ConversionPolicy
|
||||
>
|
||||
, public reader_backend< Device
|
||||
, jpeg_tag
|
||||
>
|
||||
{
|
||||
private:
|
||||
|
||||
using this_t = reader<Device, jpeg_tag, ConversionPolicy>;
|
||||
using cc_t = typename ConversionPolicy::color_converter_type;
|
||||
|
||||
public:
|
||||
|
||||
using backend_t = reader_backend<Device, jpeg_tag>;
|
||||
|
||||
public:
|
||||
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
reader( const Device& io_dev
|
||||
, const image_read_settings< jpeg_tag >& settings
|
||||
)
|
||||
: reader_base< jpeg_tag
|
||||
, ConversionPolicy
|
||||
>()
|
||||
|
||||
, backend_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
reader( const Device& io_dev
|
||||
, const typename ConversionPolicy::color_converter_type& cc
|
||||
, const image_read_settings< jpeg_tag >& settings
|
||||
)
|
||||
: reader_base< jpeg_tag
|
||||
, ConversionPolicy
|
||||
>( cc )
|
||||
, backend_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
template<typename View>
|
||||
void apply( const View& view )
|
||||
{
|
||||
// Fire exception in case of error.
|
||||
if( setjmp( this->_mark ))
|
||||
{
|
||||
this->raise_error();
|
||||
}
|
||||
|
||||
this->get()->dct_method = this->_settings._dct_method;
|
||||
|
||||
using is_read_and_convert_t = typename is_same
|
||||
<
|
||||
ConversionPolicy,
|
||||
detail::read_and_no_convert
|
||||
>::type;
|
||||
|
||||
io_error_if( !detail::is_allowed< View >( this->_info
|
||||
, is_read_and_convert_t()
|
||||
)
|
||||
, "Image types aren't compatible."
|
||||
);
|
||||
|
||||
if( jpeg_start_decompress( this->get() ) == false )
|
||||
{
|
||||
io_error( "Cannot start decompression." );
|
||||
}
|
||||
|
||||
switch( this->_info._color_space )
|
||||
{
|
||||
case JCS_GRAYSCALE:
|
||||
{
|
||||
this->_scanline_length = this->_info._width;
|
||||
read_rows< gray8_pixel_t >( view );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case JCS_RGB:
|
||||
//!\todo add Y'CbCr? We loose image quality when reading JCS_YCbCr as JCS_RGB
|
||||
case JCS_YCbCr:
|
||||
{
|
||||
this->_scanline_length = this->_info._width * num_channels< rgb8_view_t >::value;
|
||||
|
||||
read_rows< rgb8_pixel_t >( view );
|
||||
break;
|
||||
}
|
||||
|
||||
case JCS_CMYK:
|
||||
//!\todo add Y'CbCrK? We loose image quality when reading JCS_YCCK as JCS_CMYK
|
||||
case JCS_YCCK:
|
||||
{
|
||||
this->get()->out_color_space = JCS_CMYK;
|
||||
this->_scanline_length = this->_info._width * num_channels< cmyk8_view_t >::value;
|
||||
|
||||
read_rows< cmyk8_pixel_t >( view );
|
||||
|
||||
break;
|
||||
}
|
||||
default: { io_error( "Unsupported jpeg color space." ); }
|
||||
}
|
||||
|
||||
jpeg_finish_decompress ( this->get() );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template< typename ImagePixel
|
||||
, typename View
|
||||
>
|
||||
void read_rows( const View& view )
|
||||
{
|
||||
using buffer_t = std::vector<ImagePixel>;
|
||||
buffer_t buffer( this->_info._width );
|
||||
|
||||
// In case of an error we'll jump back to here and fire an exception.
|
||||
// @todo Is the buffer above cleaned up when the exception is thrown?
|
||||
// The strategy right now is to allocate necessary memory before
|
||||
// the setjmp.
|
||||
if( setjmp( this->_mark ))
|
||||
{
|
||||
this->raise_error();
|
||||
}
|
||||
|
||||
|
||||
JSAMPLE *row_adr = reinterpret_cast< JSAMPLE* >( &buffer[0] );
|
||||
|
||||
//Skip scanlines if necessary.
|
||||
for( int y = 0; y < this->_settings._top_left.y; ++y )
|
||||
{
|
||||
io_error_if( jpeg_read_scanlines( this->get()
|
||||
, &row_adr
|
||||
, 1
|
||||
) !=1
|
||||
, "jpeg_read_scanlines: fail to read JPEG file"
|
||||
);
|
||||
}
|
||||
|
||||
// Read data.
|
||||
for( int y = 0; y < view.height(); ++y )
|
||||
{
|
||||
io_error_if( jpeg_read_scanlines( this->get()
|
||||
, &row_adr
|
||||
, 1
|
||||
) != 1
|
||||
, "jpeg_read_scanlines: fail to read JPEG file"
|
||||
);
|
||||
|
||||
typename buffer_t::iterator beg = buffer.begin() + this->_settings._top_left.x;
|
||||
typename buffer_t::iterator end = beg + this->_settings._dim.x;
|
||||
|
||||
this->_cc_policy.read( beg
|
||||
, end
|
||||
, view.row_begin( y )
|
||||
);
|
||||
}
|
||||
|
||||
//@todo: There might be a better way to do that.
|
||||
while( this->get()->output_scanline < this->get()->image_height )
|
||||
{
|
||||
io_error_if( jpeg_read_scanlines( this->get()
|
||||
, &row_adr
|
||||
, 1
|
||||
) !=1
|
||||
, "jpeg_read_scanlines: fail to read JPEG file"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct jpeg_type_format_checker
|
||||
{
|
||||
jpeg_type_format_checker( jpeg_color_space::type color_space )
|
||||
: _color_space( color_space )
|
||||
{}
|
||||
|
||||
template< typename Image >
|
||||
bool apply()
|
||||
{
|
||||
return is_read_supported< typename get_pixel_type< typename Image::view_t >::type
|
||||
, jpeg_tag
|
||||
>::_color_space == _color_space;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
jpeg_color_space::type _color_space;
|
||||
};
|
||||
|
||||
struct jpeg_read_is_supported
|
||||
{
|
||||
template< typename View >
|
||||
struct apply : public is_read_supported< typename get_pixel_type< View >::type
|
||||
, jpeg_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///
|
||||
/// JPEG Dynamic Reader
|
||||
///
|
||||
template< typename Device >
|
||||
class dynamic_image_reader< Device
|
||||
, jpeg_tag
|
||||
>
|
||||
: public reader< Device
|
||||
, jpeg_tag
|
||||
, detail::read_and_no_convert
|
||||
>
|
||||
{
|
||||
using parent_t = reader<Device, jpeg_tag, detail::read_and_no_convert>;
|
||||
|
||||
public:
|
||||
|
||||
dynamic_image_reader( const Device& io_dev
|
||||
, const image_read_settings< jpeg_tag >& settings
|
||||
)
|
||||
: parent_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename Images >
|
||||
void apply( any_image< Images >& images )
|
||||
{
|
||||
detail::jpeg_type_format_checker format_checker( this->_info._color_space != JCS_YCbCr
|
||||
? this->_info._color_space
|
||||
: JCS_RGB
|
||||
);
|
||||
|
||||
if( !construct_matched( images
|
||||
, format_checker
|
||||
))
|
||||
{
|
||||
io_error( "No matching image type between those of the given any_image and that of the file" );
|
||||
}
|
||||
else
|
||||
{
|
||||
this->init_image( images
|
||||
, this->_settings
|
||||
);
|
||||
|
||||
detail::dynamic_io_fnobj< detail::jpeg_read_is_supported
|
||||
, parent_t
|
||||
> op( this );
|
||||
|
||||
apply_operation( view( images )
|
||||
, op
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // gil
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,320 @@
|
||||
//
|
||||
// Copyright 2012 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_JPEG_DETAIL_READER_BACKEND_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_JPEG_DETAIL_READER_BACKEND_HPP
|
||||
|
||||
#include <boost/gil/extension/io/jpeg/tags.hpp>
|
||||
#include <boost/gil/extension/io/jpeg/detail/base.hpp>
|
||||
|
||||
#include <csetjmp>
|
||||
#include <memory>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#pragma warning(disable:4611) //interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
///
|
||||
/// Wrapper for libjpeg's decompress object. Implements value semantics.
|
||||
///
|
||||
struct jpeg_decompress_wrapper
|
||||
{
|
||||
protected:
|
||||
|
||||
using jpeg_decompress_ptr_t = std::shared_ptr<jpeg_decompress_struct> ;
|
||||
|
||||
protected:
|
||||
|
||||
///
|
||||
/// Default Constructor
|
||||
///
|
||||
jpeg_decompress_wrapper()
|
||||
: _jpeg_decompress_ptr( new jpeg_decompress_struct()
|
||||
, jpeg_decompress_deleter
|
||||
)
|
||||
{}
|
||||
|
||||
jpeg_decompress_struct* get() { return _jpeg_decompress_ptr.get(); }
|
||||
const jpeg_decompress_struct* get() const { return _jpeg_decompress_ptr.get(); }
|
||||
|
||||
private:
|
||||
|
||||
static void jpeg_decompress_deleter( jpeg_decompress_struct* jpeg_decompress_ptr )
|
||||
{
|
||||
if( jpeg_decompress_ptr )
|
||||
{
|
||||
jpeg_destroy_decompress( jpeg_decompress_ptr );
|
||||
|
||||
delete jpeg_decompress_ptr;
|
||||
jpeg_decompress_ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
jpeg_decompress_ptr_t _jpeg_decompress_ptr;
|
||||
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///
|
||||
/// JPEG Backend
|
||||
///
|
||||
template< typename Device >
|
||||
struct reader_backend< Device
|
||||
, jpeg_tag
|
||||
>
|
||||
: public jpeg_io_base
|
||||
, public detail::jpeg_decompress_wrapper
|
||||
{
|
||||
public:
|
||||
|
||||
using format_tag_t = jpeg_tag;
|
||||
|
||||
public:
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
reader_backend( const Device& io_dev
|
||||
, const image_read_settings< jpeg_tag >& settings
|
||||
)
|
||||
: _io_dev( io_dev )
|
||||
, _settings( settings )
|
||||
, _info()
|
||||
|
||||
, _scanline_length( 0 )
|
||||
{
|
||||
get()->err = jpeg_std_error( &_jerr );
|
||||
get()->client_data = this;
|
||||
|
||||
// Error exit handler: does not return to caller.
|
||||
_jerr.error_exit = &reader_backend::error_exit;
|
||||
|
||||
if( setjmp( _mark ))
|
||||
{
|
||||
raise_error();
|
||||
}
|
||||
|
||||
_src._jsrc.bytes_in_buffer = 0;
|
||||
_src._jsrc.next_input_byte = buffer_;
|
||||
_src._jsrc.init_source = reinterpret_cast< void(*) ( j_decompress_ptr )>( &reader_backend< Device, jpeg_tag >::init_device );
|
||||
_src._jsrc.fill_input_buffer = reinterpret_cast< boolean(*)( j_decompress_ptr )>( &reader_backend< Device, jpeg_tag >::fill_buffer );
|
||||
_src._jsrc.skip_input_data = reinterpret_cast< void(*) ( j_decompress_ptr
|
||||
, long num_bytes
|
||||
) >( &reader_backend< Device, jpeg_tag >::skip_input_data );
|
||||
_src._jsrc.term_source = reinterpret_cast< void(*) ( j_decompress_ptr ) >( &reader_backend< Device, jpeg_tag >::close_device );
|
||||
_src._jsrc.resync_to_restart = jpeg_resync_to_restart;
|
||||
_src._this = this;
|
||||
|
||||
jpeg_create_decompress( get() );
|
||||
|
||||
get()->src = &_src._jsrc;
|
||||
|
||||
jpeg_read_header( get()
|
||||
, TRUE
|
||||
);
|
||||
|
||||
io_error_if( get()->data_precision != 8
|
||||
, "Image file is not supported."
|
||||
);
|
||||
|
||||
//
|
||||
read_header();
|
||||
|
||||
//
|
||||
if( _settings._dim.x == 0 )
|
||||
{
|
||||
_settings._dim.x = _info._width;
|
||||
}
|
||||
|
||||
if( _settings._dim.y == 0 )
|
||||
{
|
||||
_settings._dim.y = _info._height;
|
||||
}
|
||||
}
|
||||
|
||||
/// Read image header.
|
||||
void read_header()
|
||||
{
|
||||
_info._width = get()->image_width;
|
||||
_info._height = get()->image_height;
|
||||
_info._num_components = get()->num_components;
|
||||
_info._color_space = get()->jpeg_color_space;
|
||||
_info._data_precision = get()->data_precision;
|
||||
|
||||
_info._density_unit = get()->density_unit;
|
||||
_info._x_density = get()->X_density;
|
||||
_info._y_density = get()->Y_density;
|
||||
|
||||
// obtain real world dimensions
|
||||
// taken from https://bitbucket.org/edd/jpegxx/src/ea2492a1a4a6/src/read.cpp#cl-62
|
||||
|
||||
jpeg_calc_output_dimensions( get() );
|
||||
|
||||
double units_conversion = 0;
|
||||
if (get()->density_unit == 1) // dots per inch
|
||||
{
|
||||
units_conversion = 25.4; // millimeters in an inch
|
||||
}
|
||||
else if (get()->density_unit == 2) // dots per cm
|
||||
{
|
||||
units_conversion = 10; // millimeters in a centimeter
|
||||
}
|
||||
|
||||
_info._pixel_width_mm = get()->X_density ? (get()->output_width / double(get()->X_density)) * units_conversion : 0;
|
||||
_info._pixel_height_mm = get()->Y_density ? (get()->output_height / double(get()->Y_density)) * units_conversion : 0;
|
||||
}
|
||||
|
||||
/// Return image read settings.
|
||||
const image_read_settings< jpeg_tag >& get_settings()
|
||||
{
|
||||
return _settings;
|
||||
}
|
||||
|
||||
/// Return image header info.
|
||||
const image_read_info< jpeg_tag >& get_info()
|
||||
{
|
||||
return _info;
|
||||
}
|
||||
|
||||
/// Check if image is large enough.
|
||||
void check_image_size( const point_t& img_dim )
|
||||
{
|
||||
if( _settings._dim.x > 0 )
|
||||
{
|
||||
if( img_dim.x < _settings._dim.x ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (jpeg_image_width::type) img_dim.x < _info._width ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
|
||||
|
||||
if( _settings._dim.y > 0 )
|
||||
{
|
||||
if( img_dim.y < _settings._dim.y ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (jpeg_image_height::type) img_dim.y < _info._height ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
// Taken from jerror.c
|
||||
/*
|
||||
* Error exit handler: must not return to caller.
|
||||
*
|
||||
* Applications may override this if they want to get control back after
|
||||
* an error. Typically one would longjmp somewhere instead of exiting.
|
||||
* The setjmp buffer can be made a private field within an expanded error
|
||||
* handler object. Note that the info needed to generate an error message
|
||||
* is stored in the error object, so you can generate the message now or
|
||||
* later, at your convenience.
|
||||
* You should make sure that the JPEG object is cleaned up (with jpeg_abort
|
||||
* or jpeg_destroy) at some point.
|
||||
*/
|
||||
static void error_exit( j_common_ptr cinfo )
|
||||
{
|
||||
reader_backend< Device, jpeg_tag >* mgr = reinterpret_cast< reader_backend< Device, jpeg_tag >* >( cinfo->client_data );
|
||||
|
||||
longjmp( mgr->_mark, 1 );
|
||||
}
|
||||
|
||||
void raise_error()
|
||||
{
|
||||
// we clean up in the destructor
|
||||
|
||||
io_error( "jpeg is invalid." );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// See jdatasrc.c for default implementation for the following static member functions.
|
||||
|
||||
static void init_device( jpeg_decompress_struct* cinfo )
|
||||
{
|
||||
gil_jpeg_source_mgr* src = reinterpret_cast< gil_jpeg_source_mgr* >( cinfo->src );
|
||||
src->_jsrc.bytes_in_buffer = 0;
|
||||
src->_jsrc.next_input_byte = src->_this->buffer_;
|
||||
}
|
||||
|
||||
static boolean fill_buffer( jpeg_decompress_struct* cinfo )
|
||||
{
|
||||
gil_jpeg_source_mgr* src = reinterpret_cast< gil_jpeg_source_mgr* >( cinfo->src );
|
||||
size_t count = src->_this->_io_dev.read(src->_this->buffer_, sizeof(src->_this->buffer_) );
|
||||
|
||||
if( count <= 0 )
|
||||
{
|
||||
// libjpeg does that: adding an EOF marker
|
||||
src->_this->buffer_[0] = (JOCTET) 0xFF;
|
||||
src->_this->buffer_[1] = (JOCTET) JPEG_EOI;
|
||||
count = 2;
|
||||
}
|
||||
|
||||
src->_jsrc.next_input_byte = src->_this->buffer_;
|
||||
src->_jsrc.bytes_in_buffer = count;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void skip_input_data( jpeg_decompress_struct * cinfo, long num_bytes )
|
||||
{
|
||||
gil_jpeg_source_mgr* src = reinterpret_cast< gil_jpeg_source_mgr* >( cinfo->src );
|
||||
|
||||
if( num_bytes > 0 )
|
||||
{
|
||||
while( num_bytes > long( src->_jsrc.bytes_in_buffer ))
|
||||
{
|
||||
num_bytes -= (long) src->_jsrc.bytes_in_buffer;
|
||||
fill_buffer( cinfo );
|
||||
}
|
||||
|
||||
src->_jsrc.next_input_byte += num_bytes;
|
||||
src->_jsrc.bytes_in_buffer -= num_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
static void close_device( jpeg_decompress_struct* ) {}
|
||||
|
||||
public:
|
||||
|
||||
Device _io_dev;
|
||||
|
||||
image_read_settings< jpeg_tag > _settings;
|
||||
image_read_info< jpeg_tag > _info;
|
||||
|
||||
std::size_t _scanline_length;
|
||||
|
||||
struct gil_jpeg_source_mgr
|
||||
{
|
||||
jpeg_source_mgr _jsrc;
|
||||
reader_backend* _this;
|
||||
};
|
||||
|
||||
gil_jpeg_source_mgr _src;
|
||||
|
||||
// libjpeg default is 4096 - see jdatasrc.c
|
||||
JOCTET buffer_[4096];
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,152 @@
|
||||
//
|
||||
// Copyright 2007-2012 Christian Henning, Andreas Pokorny, Lubomir Bourdev
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_JPEG_DETAIL_SCANLINE_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_JPEG_DETAIL_SCANLINE_READ_HPP
|
||||
|
||||
|
||||
#include <boost/gil/extension/io/jpeg/detail/base.hpp>
|
||||
#include <boost/gil/extension/io/jpeg/detail/is_allowed.hpp>
|
||||
#include <boost/gil/extension/io/jpeg/detail/reader_backend.hpp>
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/conversion_policies.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/reader_base.hpp>
|
||||
#include <boost/gil/io/scanline_read_iterator.hpp>
|
||||
#include <boost/gil/io/typedefs.hpp>
|
||||
|
||||
#include <csetjmp>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4611) //interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#endif
|
||||
|
||||
///
|
||||
/// JPEG Scanline Reader
|
||||
///
|
||||
template< typename Device >
|
||||
class scanline_reader< Device
|
||||
, jpeg_tag
|
||||
>
|
||||
: public reader_backend< Device
|
||||
, jpeg_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using tag_t = jpeg_tag;
|
||||
using backend_t = reader_backend<Device, tag_t>;
|
||||
using this_t = scanline_reader<Device, tag_t>;
|
||||
using iterator_t = scanline_read_iterator<this_t>;
|
||||
|
||||
public:
|
||||
scanline_reader( Device& device
|
||||
, const image_read_settings< jpeg_tag >& settings
|
||||
)
|
||||
: reader_backend< Device
|
||||
, jpeg_tag
|
||||
>( device
|
||||
, settings
|
||||
)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
void read( byte_t* dst
|
||||
, int
|
||||
)
|
||||
{
|
||||
// Fire exception in case of error.
|
||||
if( setjmp( this->_mark )) { this->raise_error(); }
|
||||
|
||||
// read data
|
||||
read_scanline( dst );
|
||||
}
|
||||
|
||||
/// Skip over a scanline.
|
||||
void skip( byte_t* dst, int )
|
||||
{
|
||||
// Fire exception in case of error.
|
||||
if( setjmp( this->_mark )) { this->raise_error(); }
|
||||
|
||||
// read data
|
||||
read_scanline( dst );
|
||||
}
|
||||
|
||||
iterator_t begin() { return iterator_t( *this ); }
|
||||
iterator_t end() { return iterator_t( *this, this->_info._height ); }
|
||||
|
||||
private:
|
||||
|
||||
void initialize()
|
||||
{
|
||||
this->get()->dct_method = this->_settings._dct_method;
|
||||
|
||||
io_error_if( jpeg_start_decompress( this->get() ) == false
|
||||
, "Cannot start decompression." );
|
||||
|
||||
switch( this->_info._color_space )
|
||||
{
|
||||
case JCS_GRAYSCALE:
|
||||
{
|
||||
this->_scanline_length = this->_info._width;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case JCS_RGB:
|
||||
//!\todo add Y'CbCr? We loose image quality when reading JCS_YCbCr as JCS_RGB
|
||||
case JCS_YCbCr:
|
||||
{
|
||||
this->_scanline_length = this->_info._width * num_channels< rgb8_view_t >::value;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case JCS_CMYK:
|
||||
//!\todo add Y'CbCrK? We loose image quality when reading JCS_YCCK as JCS_CMYK
|
||||
case JCS_YCCK:
|
||||
{
|
||||
this->get()->out_color_space = JCS_CMYK;
|
||||
this->_scanline_length = this->_info._width * num_channels< cmyk8_view_t >::value;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: { io_error( "Unsupported jpeg color space." ); }
|
||||
}
|
||||
}
|
||||
|
||||
void read_scanline( byte_t* dst )
|
||||
{
|
||||
JSAMPLE *row_adr = reinterpret_cast< JSAMPLE* >( dst );
|
||||
|
||||
// Read data.
|
||||
io_error_if( jpeg_read_scanlines( this->get()
|
||||
, &row_adr
|
||||
, 1
|
||||
) != 1
|
||||
, "jpeg_read_scanlines: fail to read JPEG file"
|
||||
);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,112 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning, Andreas Pokorny, Lubomir Bourdev
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_JPEG_DETAIL_SUPPORTED_TYPES_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_JPEG_DETAIL_SUPPORTED_TYPES_HPP
|
||||
|
||||
#include <boost/gil/extension/io/jpeg/tags.hpp>
|
||||
|
||||
#include <boost/gil/channel.hpp>
|
||||
#include <boost/gil/color_base.hpp>
|
||||
|
||||
#include <boost/mpl/bool_fwd.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
// Read support
|
||||
|
||||
template< jpeg_color_space::type ColorSpace >
|
||||
struct jpeg_rw_support_base
|
||||
{
|
||||
static const jpeg_color_space::type _color_space = ColorSpace;
|
||||
};
|
||||
|
||||
template< typename Channel
|
||||
, typename ColorSpace
|
||||
>
|
||||
struct jpeg_read_support : read_support_false
|
||||
, jpeg_rw_support_base< JCS_UNKNOWN > {};
|
||||
|
||||
template<>
|
||||
struct jpeg_read_support<uint8_t
|
||||
, rgb_t
|
||||
> : read_support_true
|
||||
, jpeg_rw_support_base< JCS_RGB > {};
|
||||
|
||||
template<>
|
||||
struct jpeg_read_support<uint8_t
|
||||
, cmyk_t
|
||||
> : read_support_true
|
||||
, jpeg_rw_support_base< JCS_CMYK > {};
|
||||
|
||||
template<>
|
||||
struct jpeg_read_support<uint8_t
|
||||
, gray_t
|
||||
> : read_support_true
|
||||
, jpeg_rw_support_base< JCS_GRAYSCALE > {};
|
||||
|
||||
// Write support
|
||||
|
||||
template< typename Channel
|
||||
, typename ColorSpace
|
||||
>
|
||||
struct jpeg_write_support : write_support_false
|
||||
, jpeg_rw_support_base< JCS_UNKNOWN > {};
|
||||
|
||||
template<>
|
||||
struct jpeg_write_support<uint8_t
|
||||
, gray_t
|
||||
> : write_support_true
|
||||
, jpeg_rw_support_base< JCS_GRAYSCALE > {};
|
||||
|
||||
template<>
|
||||
struct jpeg_write_support<uint8_t
|
||||
, rgb_t
|
||||
> : write_support_true
|
||||
, jpeg_rw_support_base< JCS_RGB > {};
|
||||
|
||||
template<>
|
||||
struct jpeg_write_support<uint8_t
|
||||
, cmyk_t
|
||||
> : write_support_true
|
||||
, jpeg_rw_support_base< JCS_CMYK > {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template< typename Pixel >
|
||||
struct is_read_supported< Pixel
|
||||
, jpeg_tag
|
||||
>
|
||||
: mpl::bool_< detail::jpeg_read_support< typename channel_type< Pixel >::type
|
||||
, typename color_space_type< Pixel >::type
|
||||
>::is_supported
|
||||
>
|
||||
{
|
||||
using parent_t = detail::jpeg_read_support
|
||||
<
|
||||
typename channel_type<Pixel>::type,
|
||||
typename color_space_type<Pixel>::type
|
||||
>;
|
||||
|
||||
static const typename jpeg_color_space::type _color_space = parent_t::_color_space;
|
||||
};
|
||||
|
||||
template< typename Pixel >
|
||||
struct is_write_supported< Pixel
|
||||
, jpeg_tag
|
||||
>
|
||||
: mpl::bool_< detail::jpeg_write_support< typename channel_type< Pixel >::type
|
||||
, typename color_space_type< Pixel >::type
|
||||
>::is_supported
|
||||
>
|
||||
{};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
179
linx64/include/boost/gil/extension/io/jpeg/detail/write.hpp
Normal file
179
linx64/include/boost/gil/extension/io/jpeg/detail/write.hpp
Normal file
@@ -0,0 +1,179 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning, Andreas Pokorny, Lubomir Bourdev
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_JPEG_DETAIL_WRITE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_JPEG_DETAIL_WRITE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/jpeg/tags.hpp>
|
||||
#include <boost/gil/extension/io/jpeg/detail/supported_types.hpp>
|
||||
#include <boost/gil/extension/io/jpeg/detail/writer_backend.hpp>
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/dynamic_io_new.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#pragma warning(disable:4611) //interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct jpeg_write_is_supported
|
||||
{
|
||||
template< typename View >
|
||||
struct apply
|
||||
: public is_write_supported< typename get_pixel_type< View >::type
|
||||
, jpeg_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
||||
///
|
||||
/// JPEG Writer
|
||||
///
|
||||
template< typename Device >
|
||||
class writer< Device
|
||||
, jpeg_tag
|
||||
>
|
||||
: public writer_backend< Device
|
||||
, jpeg_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using backend_t = writer_backend<Device, jpeg_tag>;
|
||||
|
||||
public:
|
||||
|
||||
writer( const Device& io_dev
|
||||
, const image_write_info< jpeg_tag >& info
|
||||
)
|
||||
: backend_t( io_dev
|
||||
, info
|
||||
)
|
||||
{}
|
||||
|
||||
template<typename View>
|
||||
void apply( const View& view )
|
||||
{
|
||||
write_rows( view );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<typename View>
|
||||
void write_rows( const View& view )
|
||||
{
|
||||
std::vector< pixel< typename channel_type< View >::type
|
||||
, layout<typename color_space_type< View >::type >
|
||||
>
|
||||
> row_buffer( view.width() );
|
||||
|
||||
// In case of an error we'll jump back to here and fire an exception.
|
||||
// @todo Is the buffer above cleaned up when the exception is thrown?
|
||||
// The strategy right now is to allocate necessary memory before
|
||||
// the setjmp.
|
||||
if( setjmp( this->_mark )) { this->raise_error(); }
|
||||
|
||||
using channel_t = typename channel_type<typename View::value_type>::type;
|
||||
|
||||
this->get()->image_width = JDIMENSION( view.width() );
|
||||
this->get()->image_height = JDIMENSION( view.height() );
|
||||
this->get()->input_components = num_channels<View>::value;
|
||||
this->get()->in_color_space = detail::jpeg_write_support< channel_t
|
||||
, typename color_space_type< View >::type
|
||||
>::_color_space;
|
||||
|
||||
jpeg_set_defaults( this->get() );
|
||||
|
||||
jpeg_set_quality( this->get()
|
||||
, this->_info._quality
|
||||
, TRUE
|
||||
);
|
||||
|
||||
// Needs to be done after jpeg_set_defaults() since it's overridding this value back to slow.
|
||||
this->get()->dct_method = this->_info._dct_method;
|
||||
|
||||
|
||||
// set the pixel dimensions
|
||||
this->get()->density_unit = this->_info._density_unit;
|
||||
this->get()->X_density = this->_info._x_density;
|
||||
this->get()->Y_density = this->_info._y_density;
|
||||
|
||||
// done reading header information
|
||||
|
||||
jpeg_start_compress( this->get()
|
||||
, TRUE
|
||||
);
|
||||
|
||||
JSAMPLE* row_addr = reinterpret_cast< JSAMPLE* >( &row_buffer[0] );
|
||||
|
||||
for( int y =0; y != view.height(); ++ y )
|
||||
{
|
||||
std::copy( view.row_begin( y )
|
||||
, view.row_end ( y )
|
||||
, row_buffer.begin()
|
||||
);
|
||||
|
||||
jpeg_write_scanlines( this->get()
|
||||
, &row_addr
|
||||
, 1
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// JPEG Dyamic Image Writer
|
||||
///
|
||||
template< typename Device >
|
||||
class dynamic_image_writer< Device
|
||||
, jpeg_tag
|
||||
>
|
||||
: public writer< Device
|
||||
, jpeg_tag
|
||||
>
|
||||
{
|
||||
using parent_t = writer<Device, jpeg_tag>;
|
||||
|
||||
public:
|
||||
|
||||
dynamic_image_writer( const Device& io_dev
|
||||
, const image_write_info< jpeg_tag >& info
|
||||
)
|
||||
: parent_t( io_dev
|
||||
, info
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename Views >
|
||||
void apply( const any_image_view< Views >& views )
|
||||
{
|
||||
detail::dynamic_io_fnobj< detail::jpeg_write_is_supported
|
||||
, parent_t
|
||||
> op( this );
|
||||
|
||||
apply_operation( views, op );
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // gil
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,192 @@
|
||||
//
|
||||
// Copyright 2012 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_JPEG_DETAIL_WRITER_BACKEND_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_JPEG_DETAIL_WRITER_BACKEND_HPP
|
||||
|
||||
#include <boost/gil/extension/io/jpeg/tags.hpp>
|
||||
#include <boost/gil/extension/io/jpeg/detail/base.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#pragma warning(disable:4611) //interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
///
|
||||
/// Wrapper for libjpeg's compress object. Implements value semantics.
|
||||
///
|
||||
struct jpeg_compress_wrapper
|
||||
{
|
||||
protected:
|
||||
|
||||
using jpeg_compress_ptr_t = std::shared_ptr<jpeg_compress_struct>;
|
||||
|
||||
protected:
|
||||
|
||||
///
|
||||
/// Default Constructor
|
||||
///
|
||||
jpeg_compress_wrapper()
|
||||
: _jpeg_compress_ptr( new jpeg_compress_struct()
|
||||
, jpeg_compress_deleter
|
||||
)
|
||||
{}
|
||||
|
||||
jpeg_compress_struct* get() { return _jpeg_compress_ptr.get(); }
|
||||
const jpeg_compress_struct* get() const { return _jpeg_compress_ptr.get(); }
|
||||
|
||||
private:
|
||||
|
||||
static void jpeg_compress_deleter( jpeg_compress_struct* jpeg_compress_ptr )
|
||||
{
|
||||
if( jpeg_compress_ptr )
|
||||
{
|
||||
jpeg_destroy_compress( jpeg_compress_ptr );
|
||||
|
||||
delete jpeg_compress_ptr;
|
||||
jpeg_compress_ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
jpeg_compress_ptr_t _jpeg_compress_ptr;
|
||||
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///
|
||||
/// JPEG Writer Backend
|
||||
///
|
||||
template< typename Device >
|
||||
struct writer_backend< Device
|
||||
, jpeg_tag
|
||||
>
|
||||
: public jpeg_io_base
|
||||
, public detail::jpeg_compress_wrapper
|
||||
{
|
||||
public:
|
||||
|
||||
using format_tag_t = jpeg_tag;
|
||||
|
||||
public:
|
||||
///
|
||||
/// Constructor
|
||||
///
|
||||
writer_backend( const Device& io_dev
|
||||
, const image_write_info< jpeg_tag >& info
|
||||
)
|
||||
: _io_dev( io_dev )
|
||||
, _info( info )
|
||||
{
|
||||
get()->err = jpeg_std_error( &_jerr );
|
||||
get()->client_data = this;
|
||||
|
||||
// Error exit handler: does not return to caller.
|
||||
_jerr.error_exit = &writer_backend< Device, jpeg_tag >::error_exit;
|
||||
|
||||
// Fire exception in case of error.
|
||||
if( setjmp( _mark )) { raise_error(); }
|
||||
|
||||
_dest._jdest.free_in_buffer = sizeof( buffer );
|
||||
_dest._jdest.next_output_byte = buffer;
|
||||
_dest._jdest.init_destination = reinterpret_cast< void(*) ( j_compress_ptr ) >( &writer_backend< Device, jpeg_tag >::init_device );
|
||||
_dest._jdest.empty_output_buffer = reinterpret_cast< boolean(*)( j_compress_ptr ) >( &writer_backend< Device, jpeg_tag >::empty_buffer );
|
||||
_dest._jdest.term_destination = reinterpret_cast< void(*) ( j_compress_ptr ) >( &writer_backend< Device, jpeg_tag >::close_device );
|
||||
_dest._this = this;
|
||||
|
||||
jpeg_create_compress( get() );
|
||||
get()->dest = &_dest._jdest;
|
||||
}
|
||||
|
||||
~writer_backend()
|
||||
{
|
||||
jpeg_finish_compress ( get() );
|
||||
jpeg_destroy_compress( get() );
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
struct gil_jpeg_destination_mgr
|
||||
{
|
||||
jpeg_destination_mgr _jdest;
|
||||
writer_backend< Device
|
||||
, jpeg_tag
|
||||
>* _this;
|
||||
};
|
||||
|
||||
static void init_device( jpeg_compress_struct* cinfo )
|
||||
{
|
||||
gil_jpeg_destination_mgr* dest = reinterpret_cast< gil_jpeg_destination_mgr* >( cinfo->dest );
|
||||
|
||||
dest->_jdest.free_in_buffer = sizeof( dest->_this->buffer );
|
||||
dest->_jdest.next_output_byte = dest->_this->buffer;
|
||||
}
|
||||
|
||||
static boolean empty_buffer( jpeg_compress_struct* cinfo )
|
||||
{
|
||||
gil_jpeg_destination_mgr* dest = reinterpret_cast< gil_jpeg_destination_mgr* >( cinfo->dest );
|
||||
|
||||
dest->_this->_io_dev.write( dest->_this->buffer
|
||||
, buffer_size
|
||||
);
|
||||
|
||||
writer_backend<Device,jpeg_tag>::init_device( cinfo );
|
||||
return static_cast<boolean>(TRUE);
|
||||
}
|
||||
|
||||
static void close_device( jpeg_compress_struct* cinfo )
|
||||
{
|
||||
writer_backend< Device
|
||||
, jpeg_tag
|
||||
>::empty_buffer( cinfo );
|
||||
|
||||
gil_jpeg_destination_mgr* dest = reinterpret_cast< gil_jpeg_destination_mgr* >( cinfo->dest );
|
||||
|
||||
dest->_this->_io_dev.flush();
|
||||
}
|
||||
|
||||
void raise_error()
|
||||
{
|
||||
io_error( "Cannot write jpeg file." );
|
||||
}
|
||||
|
||||
static void error_exit( j_common_ptr cinfo )
|
||||
{
|
||||
writer_backend< Device, jpeg_tag >* mgr = reinterpret_cast< writer_backend< Device, jpeg_tag >* >( cinfo->client_data );
|
||||
|
||||
longjmp( mgr->_mark, 1 );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Device _io_dev;
|
||||
|
||||
image_write_info< jpeg_tag > _info;
|
||||
|
||||
gil_jpeg_destination_mgr _dest;
|
||||
|
||||
static const unsigned int buffer_size = 1024;
|
||||
JOCTET buffer[buffer_size];
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
161
linx64/include/boost/gil/extension/io/jpeg/old.hpp
Normal file
161
linx64/include/boost/gil/extension/io/jpeg/old.hpp
Normal file
@@ -0,0 +1,161 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_JPEG_OLD_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_JPEG_OLD_HPP
|
||||
|
||||
#include <boost/gil/extension/io/jpeg.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \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
|
||||
template<typename String>
|
||||
inline point_t jpeg_read_dimensions(String const& filename)
|
||||
{
|
||||
using backend_t = typename get_reader_backend<String, jpeg_tag>::type;
|
||||
backend_t backend = read_image_info(filename, jpeg_tag());
|
||||
return { backend._info._width, backend._info._height };
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void jpeg_read_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
read_view( filename
|
||||
, view
|
||||
, jpeg_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename Image
|
||||
>
|
||||
inline
|
||||
void jpeg_read_image( const String& filename
|
||||
, Image& img
|
||||
)
|
||||
{
|
||||
read_image( filename
|
||||
, img
|
||||
, jpeg_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename View
|
||||
, typename CC
|
||||
>
|
||||
inline
|
||||
void jpeg_read_and_convert_view( const String& filename
|
||||
, const View& view
|
||||
, CC cc
|
||||
)
|
||||
{
|
||||
read_and_convert_view( filename
|
||||
, view
|
||||
, cc
|
||||
, jpeg_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void jpeg_read_and_convert_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
read_and_convert_view( filename
|
||||
, view
|
||||
, jpeg_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename Image
|
||||
, typename CC
|
||||
>
|
||||
inline
|
||||
void jpeg_read_and_convert_image( const String& filename
|
||||
, Image& img
|
||||
, CC cc
|
||||
)
|
||||
{
|
||||
read_and_convert_image( filename
|
||||
, img
|
||||
, cc
|
||||
, jpeg_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename Image
|
||||
>
|
||||
inline
|
||||
void jpeg_read_and_convert_image( const String filename
|
||||
, Image& img
|
||||
)
|
||||
{
|
||||
read_and_convert_image( filename
|
||||
, img
|
||||
, jpeg_tag()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/// \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 String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void jpeg_write_view( const String& filename
|
||||
, const View& view
|
||||
, int quality = jpeg_quality::default_value
|
||||
)
|
||||
{
|
||||
write_view( filename
|
||||
, view
|
||||
, image_write_info< jpeg_tag >( quality )
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
30
linx64/include/boost/gil/extension/io/jpeg/read.hpp
Normal file
30
linx64/include/boost/gil/extension/io/jpeg/read.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_JPEG_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_JPEG_READ_HPP
|
||||
|
||||
#define BOOST_GIL_EXTENSION_IO_JPEG_READ_ENABLED // TODO: Document, explain, review
|
||||
|
||||
#include <boost/gil/extension/io/jpeg/tags.hpp>
|
||||
#include <boost/gil/extension/io/jpeg/detail/read.hpp>
|
||||
#include <boost/gil/extension/io/jpeg/detail/scanline_read.hpp>
|
||||
#include <boost/gil/extension/io/jpeg/detail/supported_types.hpp>
|
||||
|
||||
#include <boost/gil/io/get_reader.hpp>
|
||||
#include <boost/gil/io/make_backend.hpp>
|
||||
#include <boost/gil/io/make_dynamic_image_reader.hpp>
|
||||
#include <boost/gil/io/make_reader.hpp>
|
||||
#include <boost/gil/io/make_scanline_reader.hpp>
|
||||
#include <boost/gil/io/read_and_convert_image.hpp>
|
||||
#include <boost/gil/io/read_and_convert_view.hpp>
|
||||
#include <boost/gil/io/read_image.hpp>
|
||||
#include <boost/gil/io/read_image_info.hpp>
|
||||
#include <boost/gil/io/read_view.hpp>
|
||||
#include <boost/gil/io/scanline_read_iterator.hpp>
|
||||
|
||||
#endif
|
||||
231
linx64/include/boost/gil/extension/io/jpeg/tags.hpp
Normal file
231
linx64/include/boost/gil/extension/io/jpeg/tags.hpp
Normal file
@@ -0,0 +1,231 @@
|
||||
//
|
||||
// Copyright 2007-2012 Christian Henning, Andreas Pokorny, Lubomir Bourdev
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_JPEG_TAGS_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_JPEG_TAGS_HPP
|
||||
|
||||
// taken from jpegxx - https://bitbucket.org/edd/jpegxx/src/ea2492a1a4a6/src/ijg_headers.hpp
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_JPEG_C_LIB_COMPILED_AS_CPLUSPLUS
|
||||
extern "C" {
|
||||
#else
|
||||
// DONT_USE_EXTERN_C introduced in v7 of the IJG library.
|
||||
// By default the v7 IJG headers check for __cplusplus being defined and
|
||||
// wrap the content in an 'extern "C"' block if it's present.
|
||||
// When DONT_USE_EXTERN_C is defined, this wrapping is not performed.
|
||||
#ifndef DONT_USE_EXTERN_C
|
||||
#define DONT_USE_EXTERN_C 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <cstdio> // jpeglib doesn't know about FILE
|
||||
|
||||
#include <jerror.h>
|
||||
#include <jpeglib.h>
|
||||
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_JPEG_C_LIB_COMPILED_AS_CPLUSPLUS
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// Defines jpeg tag.
|
||||
struct jpeg_tag : format_tag {};
|
||||
|
||||
/// see http://en.wikipedia.org/wiki/JPEG for reference
|
||||
|
||||
/// Defines type for image width property.
|
||||
struct jpeg_image_width : property_base< JDIMENSION > {};
|
||||
|
||||
/// Defines type for image height property.
|
||||
struct jpeg_image_height : property_base< JDIMENSION > {};
|
||||
|
||||
/// Defines type for number of components property.
|
||||
struct jpeg_num_components : property_base< int > {};
|
||||
|
||||
/// Defines type for color space property.
|
||||
struct jpeg_color_space : property_base< J_COLOR_SPACE > {};
|
||||
|
||||
/// Defines type for jpeg quality property.
|
||||
struct jpeg_quality : property_base< int >
|
||||
{
|
||||
static const type default_value = 100;
|
||||
};
|
||||
|
||||
/// Defines type for data precision property.
|
||||
struct jpeg_data_precision : property_base< int > {};
|
||||
|
||||
/// JFIF code for pixel size units
|
||||
struct jpeg_density_unit : property_base< UINT8 >
|
||||
{
|
||||
static const type default_value = 0;
|
||||
};
|
||||
|
||||
/// pixel density
|
||||
struct jpeg_pixel_density : property_base< UINT16 >
|
||||
{
|
||||
static const type default_value = 0;
|
||||
};
|
||||
|
||||
/// Defines type for dct ( discrete cosine transformation ) method property.
|
||||
struct jpeg_dct_method : property_base< J_DCT_METHOD >
|
||||
{
|
||||
static const type slow = JDCT_ISLOW;
|
||||
static const type fast = JDCT_IFAST;
|
||||
static const type floating_pt = JDCT_FLOAT;
|
||||
static const type fastest = JDCT_FASTEST;
|
||||
|
||||
static const type default_value = slow;
|
||||
};
|
||||
|
||||
/// Read information for jpeg images.
|
||||
///
|
||||
/// The structure is returned when using read_image_info.
|
||||
template<>
|
||||
struct image_read_info< jpeg_tag >
|
||||
{
|
||||
image_read_info()
|
||||
: _width ( 0 )
|
||||
, _height( 0 )
|
||||
|
||||
, _num_components( 0 )
|
||||
|
||||
, _color_space( J_COLOR_SPACE( 0 ))
|
||||
|
||||
, _data_precision( 0 )
|
||||
|
||||
, _density_unit ( 0 )
|
||||
, _x_density ( 0 )
|
||||
, _y_density ( 0 )
|
||||
|
||||
, _pixel_width_mm ( 0.0 )
|
||||
, _pixel_height_mm( 0.0 )
|
||||
{}
|
||||
|
||||
/// The image width.
|
||||
jpeg_image_width::type _width;
|
||||
|
||||
/// The image height.
|
||||
jpeg_image_height::type _height;
|
||||
|
||||
/// The number of channels.
|
||||
jpeg_num_components::type _num_components;
|
||||
|
||||
/// The color space.
|
||||
jpeg_color_space::type _color_space;
|
||||
|
||||
/// The width of channel.
|
||||
/// I believe this number is always 8 in the case libjpeg is built with 8.
|
||||
/// see: http://www.asmail.be/msg0055405033.html
|
||||
jpeg_data_precision::type _data_precision;
|
||||
|
||||
/// Density conversion unit.
|
||||
jpeg_density_unit::type _density_unit;
|
||||
jpeg_pixel_density::type _x_density;
|
||||
jpeg_pixel_density::type _y_density;
|
||||
|
||||
/// Real-world dimensions
|
||||
double _pixel_width_mm;
|
||||
double _pixel_height_mm;
|
||||
};
|
||||
|
||||
/// Read settings for jpeg images.
|
||||
///
|
||||
/// The structure can be used for all read_xxx functions, except read_image_info.
|
||||
template<>
|
||||
struct image_read_settings< jpeg_tag > : public image_read_settings_base
|
||||
{
|
||||
/// Default constructor
|
||||
image_read_settings<jpeg_tag>()
|
||||
: image_read_settings_base()
|
||||
, _dct_method( jpeg_dct_method::default_value )
|
||||
{}
|
||||
|
||||
/// Constructor
|
||||
/// \param top_left Top left coordinate for reading partial image.
|
||||
/// \param dim Dimensions for reading partial image.
|
||||
/// \param dct_method Specifies dct method.
|
||||
image_read_settings( const point_t& top_left
|
||||
, const point_t& dim
|
||||
, jpeg_dct_method::type dct_method = jpeg_dct_method::default_value
|
||||
)
|
||||
: image_read_settings_base( top_left
|
||||
, dim
|
||||
)
|
||||
, _dct_method( dct_method )
|
||||
{}
|
||||
|
||||
/// The dct ( discrete cosine transformation ) method.
|
||||
jpeg_dct_method::type _dct_method;
|
||||
};
|
||||
|
||||
/// Write information for jpeg images.
|
||||
///
|
||||
/// The structure can be used for write_view() function.
|
||||
template<>
|
||||
struct image_write_info< jpeg_tag >
|
||||
{
|
||||
/// Constructor
|
||||
/// \param quality Defines the jpeg quality.
|
||||
/// \param dct_method Defines the DCT method.
|
||||
/// \param density_unit Defines the density unit.
|
||||
/// \param x_density Defines the x density.
|
||||
/// \param y_density Defines the y density.
|
||||
image_write_info( const jpeg_quality::type quality = jpeg_quality::default_value
|
||||
, const jpeg_dct_method::type dct_method = jpeg_dct_method::default_value
|
||||
, const jpeg_density_unit::type density_unit = jpeg_density_unit::default_value
|
||||
, const jpeg_pixel_density::type x_density = jpeg_pixel_density::default_value
|
||||
, const jpeg_pixel_density::type y_density = jpeg_pixel_density::default_value
|
||||
)
|
||||
: _quality ( quality )
|
||||
, _dct_method( dct_method )
|
||||
|
||||
, _density_unit( density_unit )
|
||||
, _x_density ( x_density )
|
||||
, _y_density ( y_density )
|
||||
{}
|
||||
|
||||
/// The jpeg quality.
|
||||
jpeg_quality::type _quality;
|
||||
|
||||
/// The dct ( discrete cosine transformation ) method.
|
||||
jpeg_dct_method::type _dct_method;
|
||||
|
||||
/// Density conversion unit.
|
||||
jpeg_density_unit::type _density_unit;
|
||||
|
||||
/// Pixel density dimensions.
|
||||
jpeg_pixel_density::type _x_density;
|
||||
jpeg_pixel_density::type _y_density;
|
||||
|
||||
/// Sets the pixel dimensions.
|
||||
void set_pixel_dimensions( int image_width // in pixels
|
||||
, int image_height // in pixels
|
||||
, double pixel_width // in mm
|
||||
, double pixel_height // in mm
|
||||
)
|
||||
{
|
||||
_density_unit = 2; // dots per cm
|
||||
|
||||
_x_density = round( image_width / ( pixel_width / 10 ));
|
||||
_y_density = round( image_height / ( pixel_height / 10 ));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
UINT16 round( double d )
|
||||
{
|
||||
return static_cast< UINT16 >( d + 0.5 );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
19
linx64/include/boost/gil/extension/io/jpeg/write.hpp
Normal file
19
linx64/include/boost/gil/extension/io/jpeg/write.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_JPEG_WRITE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_JPEG_WRITE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/jpeg/tags.hpp>
|
||||
#include <boost/gil/extension/io/jpeg/detail/supported_types.hpp>
|
||||
#include <boost/gil/extension/io/jpeg/detail/write.hpp>
|
||||
|
||||
#include <boost/gil/io/make_writer.hpp>
|
||||
#include <boost/gil/io/make_dynamic_image_writer.hpp>
|
||||
#include <boost/gil/io/write_view.hpp>
|
||||
|
||||
#endif
|
||||
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
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
|
||||
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
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
|
||||
@@ -1,226 +0,0 @@
|
||||
/*
|
||||
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"
|
||||
#include <jpeglib.h>
|
||||
|
||||
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
|
||||
14
linx64/include/boost/gil/extension/io/png.hpp
Normal file
14
linx64/include/boost/gil/extension/io/png.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNG_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNG_HPP
|
||||
|
||||
#include <boost/gil/extension/io/png/read.hpp>
|
||||
#include <boost/gil/extension/io/png/write.hpp>
|
||||
|
||||
#endif
|
||||
102
linx64/include/boost/gil/extension/io/png/detail/base.hpp
Normal file
102
linx64/include/boost/gil/extension/io/png/detail/base.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
//
|
||||
// Copyright 2012 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNG_DETAIL_BASE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNG_DETAIL_BASE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/png/tags.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
struct png_ptr_wrapper
|
||||
{
|
||||
png_ptr_wrapper()
|
||||
: _struct( nullptr )
|
||||
, _info ( nullptr )
|
||||
{}
|
||||
|
||||
png_structp _struct;
|
||||
png_infop _info;
|
||||
};
|
||||
|
||||
///
|
||||
/// Wrapper for libpng's png_struct and png_info object. Implements value semantics.
|
||||
///
|
||||
struct png_struct_info_wrapper
|
||||
{
|
||||
protected:
|
||||
|
||||
using png_ptr_t = std::shared_ptr<png_ptr_wrapper>;
|
||||
|
||||
protected:
|
||||
|
||||
///
|
||||
/// Default Constructor
|
||||
///
|
||||
png_struct_info_wrapper( bool read = true )
|
||||
: _png_ptr( new png_ptr_wrapper()
|
||||
, ( ( read ) ? png_ptr_read_deleter : png_ptr_write_deleter )
|
||||
)
|
||||
{}
|
||||
|
||||
png_ptr_wrapper* get() { return _png_ptr.get(); }
|
||||
png_ptr_wrapper const* get() const { return _png_ptr.get(); }
|
||||
|
||||
png_struct* get_struct() { return get()->_struct; }
|
||||
png_struct const* get_struct() const { return get()->_struct; }
|
||||
|
||||
png_info* get_info() { return get()->_info; }
|
||||
png_info const* get_info() const { return get()->_info; }
|
||||
|
||||
private:
|
||||
|
||||
static void png_ptr_read_deleter( png_ptr_wrapper* png_ptr )
|
||||
{
|
||||
if( png_ptr )
|
||||
{
|
||||
BOOST_ASSERT(png_ptr->_struct && png_ptr->_info);
|
||||
|
||||
png_destroy_read_struct( &png_ptr->_struct
|
||||
, &png_ptr->_info
|
||||
, nullptr
|
||||
);
|
||||
|
||||
delete png_ptr;
|
||||
png_ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static void png_ptr_write_deleter( png_ptr_wrapper* png_ptr )
|
||||
{
|
||||
if( png_ptr )
|
||||
{
|
||||
BOOST_ASSERT(png_ptr->_struct && png_ptr->_info);
|
||||
|
||||
png_destroy_write_struct( &png_ptr->_struct
|
||||
, &png_ptr->_info
|
||||
);
|
||||
|
||||
delete png_ptr;
|
||||
png_ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
png_ptr_t _png_ptr;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// Copyright 2008 Christian Henning, Lubomir Bourdev
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNG_DETAIL_IS_ALLOWED_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNG_DETAIL_IS_ALLOWED_HPP
|
||||
|
||||
#include <boost/gil/extension/io/png/tags.hpp>
|
||||
|
||||
#include <boost/mpl/bool_fwd.hpp>
|
||||
#include <boost/mpl/for_each.hpp>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
template< typename View >
|
||||
bool is_allowed( const image_read_info< png_tag >& info
|
||||
, mpl::true_ // is read_and_no_convert
|
||||
)
|
||||
{
|
||||
using pixel_t = typename get_pixel_type<View>::type;
|
||||
|
||||
using channel_t = typename channel_traits<typename element_type<pixel_t>::type>::value_type;
|
||||
|
||||
const png_num_channels::type dst_num_channels = num_channels< pixel_t >::value;
|
||||
const png_bitdepth::type dst_bit_depth = detail::unsigned_integral_num_bits< channel_t >::value;
|
||||
|
||||
return dst_num_channels == info._num_channels
|
||||
&& dst_bit_depth == info._bit_depth;
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
bool is_allowed( const image_read_info< png_tag >& /* info */
|
||||
, mpl::false_ // is read_and_convert
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
434
linx64/include/boost/gil/extension/io/png/detail/read.hpp
Normal file
434
linx64/include/boost/gil/extension/io/png/detail/read.hpp
Normal file
@@ -0,0 +1,434 @@
|
||||
//
|
||||
// Copyright 2007-2012 Christian Henning, Andreas Pokorny, Lubomir Bourdev
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNG_DETAIL_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNG_DETAIL_READ_HPP
|
||||
|
||||
#include <boost/gil/extension/io/png/tags.hpp>
|
||||
#include <boost/gil/extension/io/png/detail/reader_backend.hpp>
|
||||
#include <boost/gil/extension/io/png/detail/is_allowed.hpp>
|
||||
|
||||
#include <boost/gil.hpp> // FIXME: Include what you use!
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/conversion_policies.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/dynamic_io_new.hpp>
|
||||
#include <boost/gil/io/reader_base.hpp>
|
||||
#include <boost/gil/io/row_buffer_helper.hpp>
|
||||
#include <boost/gil/io/typedefs.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
///
|
||||
/// PNG Reader
|
||||
///
|
||||
template< typename Device
|
||||
, typename ConversionPolicy
|
||||
>
|
||||
class reader< Device
|
||||
, png_tag
|
||||
, ConversionPolicy
|
||||
>
|
||||
: public reader_base< png_tag
|
||||
, ConversionPolicy >
|
||||
, public reader_backend< Device
|
||||
, png_tag
|
||||
>
|
||||
{
|
||||
private:
|
||||
|
||||
using this_t = reader<Device, png_tag, ConversionPolicy>;
|
||||
using cc_t = typename ConversionPolicy::color_converter_type;
|
||||
|
||||
public:
|
||||
|
||||
using backend_t = reader_backend<Device, png_tag>;
|
||||
|
||||
public:
|
||||
|
||||
reader( const Device& io_dev
|
||||
, const image_read_settings< png_tag >& settings
|
||||
)
|
||||
: reader_base< png_tag
|
||||
, ConversionPolicy
|
||||
>()
|
||||
, backend_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
reader( const Device& io_dev
|
||||
, const typename ConversionPolicy::color_converter_type& cc
|
||||
, const image_read_settings< png_tag >& settings
|
||||
)
|
||||
: reader_base< png_tag
|
||||
, ConversionPolicy
|
||||
>( cc )
|
||||
, backend_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename View >
|
||||
void apply( const View& view )
|
||||
{
|
||||
// The info structures are filled at this point.
|
||||
|
||||
// Now it's time for some transformations.
|
||||
|
||||
if( little_endian() )
|
||||
{
|
||||
if( this->_info._bit_depth == 16 )
|
||||
{
|
||||
// Swap bytes of 16 bit files to least significant byte first.
|
||||
png_set_swap( this->get_struct() );
|
||||
}
|
||||
|
||||
if( this->_info._bit_depth < 8 )
|
||||
{
|
||||
// swap bits of 1, 2, 4 bit packed pixel formats
|
||||
png_set_packswap( this->get_struct() );
|
||||
}
|
||||
}
|
||||
|
||||
if( this->_info._color_type == PNG_COLOR_TYPE_PALETTE )
|
||||
{
|
||||
png_set_palette_to_rgb( this->get_struct() );
|
||||
}
|
||||
|
||||
if( png_get_valid( this->get_struct(), this->get_info(), PNG_INFO_tRNS ) )
|
||||
{
|
||||
png_set_tRNS_to_alpha( this->get_struct() );
|
||||
}
|
||||
|
||||
// Tell libpng to handle the gamma conversion for you. The final call
|
||||
// is a good guess for PC generated images, but it should be configurable
|
||||
// by the user at run time by the user. It is strongly suggested that
|
||||
// your application support gamma correction.
|
||||
if( this->_settings._apply_screen_gamma )
|
||||
{
|
||||
// png_set_gamma will change the image data!
|
||||
|
||||
#ifdef BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
png_set_gamma( this->get_struct()
|
||||
, this->_settings._screen_gamma
|
||||
, this->_info._file_gamma
|
||||
);
|
||||
#else
|
||||
png_set_gamma( this->get_struct()
|
||||
, this->_settings._screen_gamma
|
||||
, this->_info._file_gamma
|
||||
);
|
||||
#endif // BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
}
|
||||
|
||||
// Turn on interlace handling. REQUIRED if you are not using
|
||||
// png_read_image(). To see how to handle interlacing passes,
|
||||
// see the png_read_row() method below:
|
||||
this->_number_passes = png_set_interlace_handling( this->get_struct() );
|
||||
|
||||
|
||||
// The above transformation might have changed the bit_depth and color type.
|
||||
png_read_update_info( this->get_struct()
|
||||
, this->get_info()
|
||||
);
|
||||
|
||||
this->_info._bit_depth = png_get_bit_depth( this->get_struct()
|
||||
, this->get_info()
|
||||
);
|
||||
|
||||
this->_info._num_channels = png_get_channels( this->get_struct()
|
||||
, this->get_info()
|
||||
);
|
||||
|
||||
this->_info._color_type = png_get_color_type( this->get_struct()
|
||||
, this->get_info()
|
||||
);
|
||||
|
||||
this->_scanline_length = png_get_rowbytes( this->get_struct()
|
||||
, this->get_info()
|
||||
);
|
||||
|
||||
switch( this->_info._color_type )
|
||||
{
|
||||
case PNG_COLOR_TYPE_GRAY:
|
||||
{
|
||||
switch( this->_info._bit_depth )
|
||||
{
|
||||
case 1: read_rows< gray1_image_t::view_t::reference >( view ); break;
|
||||
case 2: read_rows< gray2_image_t::view_t::reference >( view ); break;
|
||||
case 4: read_rows< gray4_image_t::view_t::reference >( view ); break;
|
||||
case 8: read_rows< gray8_pixel_t >( view ); break;
|
||||
case 16: read_rows< gray16_pixel_t >( view ); break;
|
||||
default: io_error( "png_reader::read_data(): unknown combination of color type and bit depth" );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case PNG_COLOR_TYPE_GA:
|
||||
{
|
||||
#ifdef BOOST_GIL_IO_ENABLE_GRAY_ALPHA
|
||||
switch( this->_info._bit_depth )
|
||||
{
|
||||
case 8: read_rows< gray_alpha8_pixel_t > ( view ); break;
|
||||
case 16: read_rows< gray_alpha16_pixel_t >( view ); break;
|
||||
default: io_error( "png_reader::read_data(): unknown combination of color type and bit depth" );
|
||||
}
|
||||
#else
|
||||
io_error( "gray_alpha isn't enabled. Use ENABLE_GRAY_ALPHA when building application." );
|
||||
#endif // BOOST_GIL_IO_ENABLE_GRAY_ALPHA
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case PNG_COLOR_TYPE_RGB:
|
||||
{
|
||||
switch( this->_info._bit_depth )
|
||||
{
|
||||
case 8: read_rows< rgb8_pixel_t > ( view ); break;
|
||||
case 16: read_rows< rgb16_pixel_t >( view ); break;
|
||||
default: io_error( "png_reader::read_data(): unknown combination of color type and bit depth" );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case PNG_COLOR_TYPE_RGBA:
|
||||
{
|
||||
switch( this->_info._bit_depth )
|
||||
{
|
||||
case 8: read_rows< rgba8_pixel_t > ( view ); break;
|
||||
case 16: read_rows< rgba16_pixel_t >( view ); break;
|
||||
default: io_error( "png_reader_color_convert::read_data(): unknown combination of color type and bit depth" );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default: io_error( "png_reader_color_convert::read_data(): unknown color type" );
|
||||
}
|
||||
|
||||
// read rest of file, and get additional chunks in info_ptr
|
||||
png_read_end( this->get_struct()
|
||||
, nullptr
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template< typename ImagePixel
|
||||
, typename View
|
||||
>
|
||||
void read_rows( const View& view )
|
||||
{
|
||||
using row_buffer_helper_t = detail::row_buffer_helper_view<ImagePixel>;
|
||||
|
||||
using it_t = typename row_buffer_helper_t::iterator_t;
|
||||
|
||||
using is_read_and_convert_t = typename is_same
|
||||
<
|
||||
ConversionPolicy,
|
||||
detail::read_and_no_convert
|
||||
>::type;
|
||||
|
||||
io_error_if( !detail::is_allowed< View >( this->_info
|
||||
, is_read_and_convert_t()
|
||||
)
|
||||
, "Image types aren't compatible."
|
||||
);
|
||||
|
||||
std::size_t rowbytes = png_get_rowbytes( this->get_struct()
|
||||
, this->get_info()
|
||||
);
|
||||
|
||||
row_buffer_helper_t buffer( rowbytes
|
||||
, true
|
||||
);
|
||||
|
||||
png_bytep row_ptr = (png_bytep)( &( buffer.data()[0]));
|
||||
|
||||
for( std::size_t pass = 0; pass < this->_number_passes; pass++ )
|
||||
{
|
||||
if( pass == this->_number_passes - 1 )
|
||||
{
|
||||
// skip lines if necessary
|
||||
for( std::ptrdiff_t y = 0; y < this->_settings._top_left.y; ++y )
|
||||
{
|
||||
// Read the image using the "sparkle" effect.
|
||||
png_read_rows( this->get_struct()
|
||||
, &row_ptr
|
||||
, nullptr
|
||||
, 1
|
||||
);
|
||||
}
|
||||
|
||||
for( std::ptrdiff_t y = 0
|
||||
; y < this->_settings._dim.y
|
||||
; ++y
|
||||
)
|
||||
{
|
||||
// Read the image using the "sparkle" effect.
|
||||
png_read_rows( this->get_struct()
|
||||
, &row_ptr
|
||||
, nullptr
|
||||
, 1
|
||||
);
|
||||
|
||||
it_t first = buffer.begin() + this->_settings._top_left.x;
|
||||
it_t last = first + this->_settings._dim.x; // one after last element
|
||||
|
||||
this->_cc_policy.read( first
|
||||
, last
|
||||
, view.row_begin( y ));
|
||||
}
|
||||
|
||||
// Read the rest of the image. libpng needs that.
|
||||
std::ptrdiff_t remaining_rows = static_cast< std::ptrdiff_t >( this->_info._height )
|
||||
- this->_settings._top_left.y
|
||||
- this->_settings._dim.y;
|
||||
for( std::ptrdiff_t y = 0
|
||||
; y < remaining_rows
|
||||
; ++y
|
||||
)
|
||||
{
|
||||
// Read the image using the "sparkle" effect.
|
||||
png_read_rows( this->get_struct()
|
||||
, &row_ptr
|
||||
, nullptr
|
||||
, 1
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int y = 0; y < view.height(); ++y )
|
||||
{
|
||||
// Read the image using the "sparkle" effect.
|
||||
png_read_rows( this->get_struct()
|
||||
, &row_ptr
|
||||
, nullptr
|
||||
, 1
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct png_type_format_checker
|
||||
{
|
||||
png_type_format_checker( png_bitdepth::type bit_depth
|
||||
, png_color_type::type color_type
|
||||
)
|
||||
: _bit_depth ( bit_depth )
|
||||
, _color_type( color_type )
|
||||
{}
|
||||
|
||||
template< typename Image >
|
||||
bool apply()
|
||||
{
|
||||
using is_supported_t = is_read_supported
|
||||
<
|
||||
typename get_pixel_type<typename Image::view_t>::type,
|
||||
png_tag
|
||||
>;
|
||||
|
||||
return is_supported_t::_bit_depth == _bit_depth
|
||||
&& is_supported_t::_color_type == _color_type;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
png_bitdepth::type _bit_depth;
|
||||
png_color_type::type _color_type;
|
||||
};
|
||||
|
||||
struct png_read_is_supported
|
||||
{
|
||||
template< typename View >
|
||||
struct apply : public is_read_supported< typename get_pixel_type< View >::type
|
||||
, png_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
///
|
||||
/// PNG Dynamic Image Reader
|
||||
///
|
||||
template< typename Device
|
||||
>
|
||||
class dynamic_image_reader< Device
|
||||
, png_tag
|
||||
>
|
||||
: public reader< Device
|
||||
, png_tag
|
||||
, detail::read_and_no_convert
|
||||
>
|
||||
{
|
||||
using parent_t = reader
|
||||
<
|
||||
Device,
|
||||
png_tag,
|
||||
detail::read_and_no_convert
|
||||
>;
|
||||
|
||||
public:
|
||||
|
||||
dynamic_image_reader( const Device& io_dev
|
||||
, const image_read_settings< png_tag >& settings
|
||||
)
|
||||
: parent_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename Images >
|
||||
void apply( any_image< Images >& images )
|
||||
{
|
||||
detail::png_type_format_checker format_checker( this->_info._bit_depth
|
||||
, this->_info._color_type
|
||||
);
|
||||
|
||||
if( !construct_matched( images
|
||||
, format_checker
|
||||
))
|
||||
{
|
||||
io_error( "No matching image type between those of the given any_image and that of the file" );
|
||||
}
|
||||
else
|
||||
{
|
||||
this->init_image( images
|
||||
, this->_settings
|
||||
);
|
||||
|
||||
detail::dynamic_io_fnobj< detail::png_read_is_supported
|
||||
, parent_t
|
||||
> op( this );
|
||||
|
||||
apply_operation( view( images )
|
||||
, op
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,678 @@
|
||||
//
|
||||
// Copyright 2012 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_DETAIL_READER_BACKEND_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_DETAIL_READER_BACKEND_HPP
|
||||
|
||||
#include <boost/gil/extension/io/png/tags.hpp>
|
||||
#include <boost/gil/extension/io/png/detail/base.hpp>
|
||||
#include <boost/gil/extension/io/png/detail/supported_types.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#pragma warning(disable:4611) //interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#endif
|
||||
|
||||
///
|
||||
/// PNG Backend
|
||||
///
|
||||
template<typename Device >
|
||||
struct reader_backend< Device
|
||||
, png_tag
|
||||
>
|
||||
: public detail::png_struct_info_wrapper
|
||||
{
|
||||
public:
|
||||
|
||||
using format_tag_t = png_tag;
|
||||
using this_t = reader_backend<Device, png_tag>;
|
||||
|
||||
public:
|
||||
|
||||
reader_backend( const Device& io_dev
|
||||
, const image_read_settings< png_tag >& settings
|
||||
)
|
||||
: _io_dev( io_dev )
|
||||
|
||||
, _settings( settings )
|
||||
, _info()
|
||||
, _scanline_length( 0 )
|
||||
|
||||
, _number_passes( 0 )
|
||||
{
|
||||
read_header();
|
||||
|
||||
if( _settings._dim.x == 0 )
|
||||
{
|
||||
_settings._dim.x = _info._width;
|
||||
}
|
||||
|
||||
if( _settings._dim.y == 0 )
|
||||
{
|
||||
_settings._dim.y = _info._height;
|
||||
}
|
||||
}
|
||||
|
||||
void read_header()
|
||||
{
|
||||
using boost::gil::detail::PNG_BYTES_TO_CHECK;
|
||||
|
||||
// check the file's first few bytes
|
||||
byte_t buf[PNG_BYTES_TO_CHECK];
|
||||
|
||||
io_error_if( _io_dev.read( buf
|
||||
, PNG_BYTES_TO_CHECK
|
||||
) != PNG_BYTES_TO_CHECK
|
||||
, "png_check_validity: failed to read image"
|
||||
);
|
||||
|
||||
io_error_if( png_sig_cmp( png_bytep(buf)
|
||||
, png_size_t(0)
|
||||
, PNG_BYTES_TO_CHECK
|
||||
) != 0
|
||||
, "png_check_validity: invalid png image"
|
||||
);
|
||||
|
||||
// Create and initialize the png_struct with the desired error handler
|
||||
// functions. If you want to use the default stderr and longjump method,
|
||||
// you can supply NULL for the last three parameters. We also supply the
|
||||
// the compiler header file version, so that we know if the application
|
||||
// was compiled with a compatible version of the library. REQUIRED
|
||||
get()->_struct = png_create_read_struct( PNG_LIBPNG_VER_STRING
|
||||
, nullptr // user_error_ptr
|
||||
, nullptr // user_error_fn
|
||||
, nullptr // user_warning_fn
|
||||
);
|
||||
|
||||
io_error_if( get()->_struct == nullptr
|
||||
, "png_reader: fail to call png_create_write_struct()"
|
||||
);
|
||||
|
||||
png_uint_32 user_chunk_data[4];
|
||||
user_chunk_data[0] = 0;
|
||||
user_chunk_data[1] = 0;
|
||||
user_chunk_data[2] = 0;
|
||||
user_chunk_data[3] = 0;
|
||||
png_set_read_user_chunk_fn( get_struct()
|
||||
, user_chunk_data
|
||||
, this_t::read_user_chunk_callback
|
||||
);
|
||||
|
||||
// Allocate/initialize the memory for image information. REQUIRED.
|
||||
get()->_info = png_create_info_struct( get_struct() );
|
||||
|
||||
if( get_info() == nullptr )
|
||||
{
|
||||
png_destroy_read_struct( &get()->_struct
|
||||
, nullptr
|
||||
, nullptr
|
||||
);
|
||||
|
||||
io_error( "png_reader: fail to call png_create_info_struct()" );
|
||||
}
|
||||
|
||||
// Set error handling if you are using the setjmp/longjmp method (this is
|
||||
// the normal method of doing things with libpng). REQUIRED unless you
|
||||
// set up your own error handlers in the png_create_read_struct() earlier.
|
||||
if( setjmp( png_jmpbuf( get_struct() )))
|
||||
{
|
||||
//free all of the memory associated with the png_ptr and info_ptr
|
||||
png_destroy_read_struct( &get()->_struct
|
||||
, &get()->_info
|
||||
, nullptr
|
||||
);
|
||||
|
||||
io_error( "png is invalid" );
|
||||
}
|
||||
|
||||
png_set_read_fn( get_struct()
|
||||
, static_cast< png_voidp >( &this->_io_dev )
|
||||
, this_t::read_data
|
||||
);
|
||||
|
||||
// Set up a callback function that will be
|
||||
// called after each row has been read, which you can use to control
|
||||
// a progress meter or the like.
|
||||
png_set_read_status_fn( get_struct()
|
||||
, this_t::read_row_callback
|
||||
);
|
||||
|
||||
// Set up a callback which implements user defined transformation.
|
||||
// @todo
|
||||
png_set_read_user_transform_fn( get_struct()
|
||||
, png_user_transform_ptr( nullptr )
|
||||
);
|
||||
|
||||
png_set_keep_unknown_chunks( get_struct()
|
||||
, PNG_HANDLE_CHUNK_ALWAYS
|
||||
, nullptr
|
||||
, 0
|
||||
);
|
||||
|
||||
|
||||
// Make sure we read the signature.
|
||||
// @todo make it an option
|
||||
png_set_sig_bytes( get_struct()
|
||||
, PNG_BYTES_TO_CHECK
|
||||
);
|
||||
|
||||
// The call to png_read_info() gives us all of the information from the
|
||||
// PNG file before the first IDAT (image data chunk). REQUIRED
|
||||
png_read_info( get_struct()
|
||||
, get_info()
|
||||
);
|
||||
|
||||
///
|
||||
/// Start reading the image information
|
||||
///
|
||||
|
||||
// get PNG_IHDR chunk information from png_info structure
|
||||
png_get_IHDR( get_struct()
|
||||
, get_info()
|
||||
, &this->_info._width
|
||||
, &this->_info._height
|
||||
, &this->_info._bit_depth
|
||||
, &this->_info._color_type
|
||||
, &this->_info._interlace_method
|
||||
, &this->_info._compression_method
|
||||
, &this->_info._filter_method
|
||||
);
|
||||
|
||||
// get number of color channels in image
|
||||
this->_info._num_channels = png_get_channels( get_struct()
|
||||
, get_info()
|
||||
);
|
||||
|
||||
#ifdef BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
|
||||
// Get CIE chromacities and referenced white point
|
||||
if( this->_settings._read_cie_chromacities )
|
||||
{
|
||||
this->_info._valid_cie_colors = png_get_cHRM( get_struct()
|
||||
, get_info()
|
||||
, &this->_info._white_x, &this->_info._white_y
|
||||
, &this->_info._red_x, &this->_info._red_y
|
||||
, &this->_info._green_x, &this->_info._green_y
|
||||
, &this->_info._blue_x, &this->_info._blue_y
|
||||
);
|
||||
}
|
||||
|
||||
// get the gamma value
|
||||
if( this->_settings._read_file_gamma )
|
||||
{
|
||||
this->_info._valid_file_gamma = png_get_gAMA( get_struct()
|
||||
, get_info()
|
||||
, &this->_info._file_gamma
|
||||
);
|
||||
|
||||
if( this->_info._valid_file_gamma == false )
|
||||
{
|
||||
this->_info._file_gamma = 1.0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
// Get CIE chromacities and referenced white point
|
||||
if( this->_settings._read_cie_chromacities )
|
||||
{
|
||||
this->_info._valid_cie_colors = png_get_cHRM_fixed( get_struct()
|
||||
, get_info()
|
||||
, &this->_info._white_x, &this->_info._white_y
|
||||
, &this->_info._red_x, &this->_info._red_y
|
||||
, &this->_info._green_x, &this->_info._green_y
|
||||
, &this->_info._blue_x, &this->_info._blue_y
|
||||
);
|
||||
}
|
||||
|
||||
// get the gamma value
|
||||
if( this->_settings._read_file_gamma )
|
||||
{
|
||||
this->_info._valid_file_gamma = png_get_gAMA_fixed( get_struct()
|
||||
, get_info()
|
||||
, &this->_info._file_gamma
|
||||
);
|
||||
|
||||
if( this->_info._valid_file_gamma == false )
|
||||
{
|
||||
this->_info._file_gamma = 1;
|
||||
}
|
||||
}
|
||||
#endif // BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
|
||||
// get the embedded ICC profile data
|
||||
if( this->_settings._read_icc_profile )
|
||||
{
|
||||
#if PNG_LIBPNG_VER_MINOR >= 5
|
||||
png_charp icc_name = png_charp( nullptr );
|
||||
png_bytep profile = png_bytep( nullptr );
|
||||
|
||||
this->_info._valid_icc_profile = png_get_iCCP( get_struct()
|
||||
, get_info()
|
||||
, &icc_name
|
||||
, &this->_info._iccp_compression_type
|
||||
, &profile
|
||||
, &this->_info._profile_length
|
||||
);
|
||||
#else
|
||||
png_charp icc_name = png_charp( NULL );
|
||||
png_charp profile = png_charp( NULL );
|
||||
|
||||
this->_info._valid_icc_profile = png_get_iCCP( get_struct()
|
||||
, get_info()
|
||||
, &icc_name
|
||||
, &this->_info._iccp_compression_type
|
||||
, &profile
|
||||
, &this->_info._profile_length
|
||||
);
|
||||
#endif
|
||||
if( icc_name )
|
||||
{
|
||||
this->_info._icc_name.append( icc_name
|
||||
, std::strlen( icc_name )
|
||||
);
|
||||
}
|
||||
|
||||
if( this->_info._profile_length != 0 )
|
||||
{
|
||||
std:: copy_n (profile, this->_info._profile_length, std:: back_inserter (this->_info._profile));
|
||||
}
|
||||
}
|
||||
|
||||
// get the rendering intent
|
||||
if( this->_settings._read_intent )
|
||||
{
|
||||
this->_info._valid_intent = png_get_sRGB( get_struct()
|
||||
, get_info()
|
||||
, &this->_info._intent
|
||||
);
|
||||
}
|
||||
|
||||
// get image palette information from png_info structure
|
||||
if( this->_settings._read_palette )
|
||||
{
|
||||
png_colorp palette = png_colorp( nullptr );
|
||||
|
||||
this->_info._valid_palette = png_get_PLTE( get_struct()
|
||||
, get_info()
|
||||
, &palette
|
||||
, &this->_info._num_palette
|
||||
);
|
||||
|
||||
if( this->_info._num_palette > 0 )
|
||||
{
|
||||
this->_info._palette.resize( this->_info._num_palette );
|
||||
std::copy( palette
|
||||
, palette + this->_info._num_palette
|
||||
, &this->_info._palette.front()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// get background color
|
||||
if( this->_settings._read_background )
|
||||
{
|
||||
png_color_16p background = png_color_16p( nullptr );
|
||||
|
||||
this->_info._valid_background = png_get_bKGD( get_struct()
|
||||
, get_info()
|
||||
, &background
|
||||
);
|
||||
if( background )
|
||||
{
|
||||
this->_info._background = *background;
|
||||
}
|
||||
}
|
||||
|
||||
// get the histogram
|
||||
if( this->_settings._read_histogram )
|
||||
{
|
||||
png_uint_16p histogram = png_uint_16p( nullptr );
|
||||
|
||||
this->_info._valid_histogram = png_get_hIST( get_struct()
|
||||
, get_info()
|
||||
, &histogram
|
||||
);
|
||||
|
||||
if( histogram )
|
||||
{
|
||||
// the number of values is set by the number of colors inside
|
||||
// the palette.
|
||||
if( this->_settings._read_palette == false )
|
||||
{
|
||||
png_colorp palette = png_colorp( nullptr );
|
||||
png_get_PLTE( get_struct()
|
||||
, get_info()
|
||||
, &palette
|
||||
, &this->_info._num_palette
|
||||
);
|
||||
}
|
||||
|
||||
std::copy( histogram
|
||||
, histogram + this->_info._num_palette
|
||||
, &this->_info._histogram.front()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// get screen offsets for the given image
|
||||
if( this->_settings._read_screen_offsets )
|
||||
{
|
||||
this->_info._valid_offset = png_get_oFFs( get_struct()
|
||||
, get_info()
|
||||
, &this->_info._offset_x
|
||||
, &this->_info._offset_y
|
||||
, &this->_info._off_unit_type
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// get pixel calibration settings
|
||||
if( this->_settings._read_pixel_calibration )
|
||||
{
|
||||
png_charp purpose = png_charp ( nullptr );
|
||||
png_charp units = png_charp ( nullptr );
|
||||
png_charpp params = png_charpp( nullptr );
|
||||
|
||||
this->_info._valid_pixel_calibration = png_get_pCAL( get_struct()
|
||||
, get_info()
|
||||
, &purpose
|
||||
, &this->_info._X0
|
||||
, &this->_info._X1
|
||||
, &this->_info._cal_type
|
||||
, &this->_info._num_params
|
||||
, &units
|
||||
, ¶ms
|
||||
);
|
||||
if( purpose )
|
||||
{
|
||||
this->_info._purpose.append( purpose
|
||||
, std::strlen( purpose )
|
||||
);
|
||||
}
|
||||
|
||||
if( units )
|
||||
{
|
||||
this->_info._units.append( units
|
||||
, std::strlen( units )
|
||||
);
|
||||
}
|
||||
|
||||
if( this->_info._num_params > 0 )
|
||||
{
|
||||
this->_info._params.resize( this->_info._num_params );
|
||||
|
||||
for( png_CAL_nparam::type i = 0
|
||||
; i < this->_info._num_params
|
||||
; ++i
|
||||
)
|
||||
{
|
||||
this->_info._params[i].append( params[i]
|
||||
, std::strlen( params[i] )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get the physical resolution
|
||||
if( this->_settings._read_physical_resolution )
|
||||
{
|
||||
this->_info._valid_resolution = png_get_pHYs( get_struct()
|
||||
, get_info()
|
||||
, &this->_info._res_x
|
||||
, &this->_info._res_y
|
||||
, &this->_info._phy_unit_type
|
||||
);
|
||||
}
|
||||
|
||||
// get the image resolution in pixels per meter.
|
||||
if( this->_settings._read_pixels_per_meter )
|
||||
{
|
||||
this->_info._pixels_per_meter = png_get_pixels_per_meter( get_struct()
|
||||
, get_info()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// get number of significant bits for each color channel
|
||||
if( this->_settings._read_number_of_significant_bits )
|
||||
{
|
||||
png_color_8p sig_bits = png_color_8p( nullptr );
|
||||
|
||||
this->_info._valid_significant_bits = png_get_sBIT( get_struct()
|
||||
, get_info()
|
||||
, &sig_bits
|
||||
);
|
||||
|
||||
// @todo Is there one or more colors?
|
||||
if( sig_bits )
|
||||
{
|
||||
this->_info._sig_bits = *sig_bits;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BOOST_GIL_IO_PNG_1_4_OR_LOWER
|
||||
|
||||
#ifdef BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
|
||||
// get physical scale settings
|
||||
if( this->_settings._read_scale_factors )
|
||||
{
|
||||
this->_info._valid_scale_factors = png_get_sCAL( get_struct()
|
||||
, get_info()
|
||||
, &this->_info._scale_unit
|
||||
, &this->_info._scale_width
|
||||
, &this->_info._scale_height
|
||||
);
|
||||
}
|
||||
#else
|
||||
#ifdef BOOST_GIL_IO_PNG_FIXED_POINT_SUPPORTED
|
||||
if( this->_settings._read_scale_factors )
|
||||
{
|
||||
this->_info._valid_scale_factors = png_get_sCAL_fixed( get_struct()
|
||||
, get_info()
|
||||
, &this->_info._scale_unit
|
||||
, &this->_info._scale_width
|
||||
, &this->_info._scale_height
|
||||
);
|
||||
}
|
||||
#else
|
||||
if( this->_settings._read_scale_factors )
|
||||
{
|
||||
png_charp scale_width = nullptr;
|
||||
png_charp scale_height = nullptr;
|
||||
|
||||
this->_info._valid_scale_factors = png_get_sCAL_s(
|
||||
get_struct(), get_info(), &this->_info._scale_unit, &scale_width, &scale_height);
|
||||
|
||||
if (this->_info._valid_scale_factors)
|
||||
{
|
||||
if( scale_width )
|
||||
{
|
||||
this->_info._scale_width.append( scale_width
|
||||
, std::strlen( scale_width )
|
||||
);
|
||||
}
|
||||
|
||||
if( scale_height )
|
||||
{
|
||||
this->_info._scale_height.append( scale_height
|
||||
, std::strlen( scale_height )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // BOOST_GIL_IO_PNG_FIXED_POINT_SUPPORTED
|
||||
#endif // BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
#endif // BOOST_GIL_IO_PNG_1_4_OR_LOWER
|
||||
|
||||
// get comments information from png_info structure
|
||||
if( this->_settings._read_comments )
|
||||
{
|
||||
png_textp text = png_textp( nullptr );
|
||||
|
||||
this->_info._valid_text = png_get_text( get_struct()
|
||||
, get_info()
|
||||
, &text
|
||||
, &this->_info._num_text
|
||||
);
|
||||
|
||||
if( this->_info._num_text > 0 )
|
||||
{
|
||||
this->_info._text.resize( this->_info._num_text );
|
||||
|
||||
for( png_num_text::type i = 0
|
||||
; i < this->_info._num_text
|
||||
; ++i
|
||||
)
|
||||
{
|
||||
this->_info._text[i]._compression = text[i].compression;
|
||||
this->_info._text[i]._key.append( text[i].key
|
||||
, std::strlen( text[i].key )
|
||||
);
|
||||
|
||||
this->_info._text[i]._text.append( text[i].text
|
||||
, std::strlen( text[i].text )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get last modification time
|
||||
if( this->_settings._read_last_modification_time )
|
||||
{
|
||||
png_timep mod_time = png_timep( nullptr );
|
||||
this->_info._valid_modification_time = png_get_tIME( get_struct()
|
||||
, get_info()
|
||||
, &mod_time
|
||||
);
|
||||
if( mod_time )
|
||||
{
|
||||
this->_info._mod_time = *mod_time;
|
||||
}
|
||||
}
|
||||
|
||||
// get transparency data
|
||||
if( this->_settings._read_transparency_data )
|
||||
{
|
||||
png_bytep trans = png_bytep ( nullptr );
|
||||
png_color_16p trans_values = png_color_16p( nullptr );
|
||||
|
||||
this->_info._valid_transparency_factors = png_get_tRNS( get_struct()
|
||||
, get_info()
|
||||
, &trans
|
||||
, &this->_info._num_trans
|
||||
, &trans_values
|
||||
);
|
||||
|
||||
if( trans )
|
||||
{
|
||||
//@todo What to do, here? How do I know the length of the "trans" array?
|
||||
}
|
||||
|
||||
if( this->_info._num_trans )
|
||||
{
|
||||
this->_info._trans_values.resize( this->_info._num_trans );
|
||||
std::copy( trans_values
|
||||
, trans_values + this->_info._num_trans
|
||||
, &this->_info._trans_values.front()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// @todo One day!
|
||||
/*
|
||||
if( false )
|
||||
{
|
||||
png_unknown_chunkp unknowns = png_unknown_chunkp( NULL );
|
||||
int num_unknowns = static_cast< int >( png_get_unknown_chunks( get_struct()
|
||||
, get_info()
|
||||
, &unknowns
|
||||
)
|
||||
);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/// Check if image is large enough.
|
||||
void check_image_size( const point_t& img_dim )
|
||||
{
|
||||
if( _settings._dim.x > 0 )
|
||||
{
|
||||
if( img_dim.x < _settings._dim.x ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if( img_dim.x < _info._width ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
|
||||
|
||||
if( _settings._dim.y > 0 )
|
||||
{
|
||||
if( img_dim.y < _settings._dim.y ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if( img_dim.y < _info._height ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
static void read_data( png_structp png_ptr
|
||||
, png_bytep data
|
||||
, png_size_t length
|
||||
)
|
||||
{
|
||||
static_cast<Device*>(png_get_io_ptr(png_ptr) )->read( data
|
||||
, length );
|
||||
}
|
||||
|
||||
static void flush( png_structp png_ptr )
|
||||
{
|
||||
static_cast<Device*>(png_get_io_ptr(png_ptr) )->flush();
|
||||
}
|
||||
|
||||
|
||||
static int read_user_chunk_callback( png_struct* /* png_ptr */
|
||||
, png_unknown_chunkp /* chunk */
|
||||
)
|
||||
{
|
||||
// @todo
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void read_row_callback( png_structp /* png_ptr */
|
||||
, png_uint_32 /* row_number */
|
||||
, int /* pass */
|
||||
)
|
||||
{
|
||||
// @todo
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Device _io_dev;
|
||||
|
||||
image_read_settings< png_tag > _settings;
|
||||
image_read_info < png_tag > _info;
|
||||
|
||||
std::size_t _scanline_length;
|
||||
|
||||
std::size_t _number_passes;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,167 @@
|
||||
//
|
||||
// Copyright 2007-2012 Christian Henning, Andreas Pokorny, Lubomir Bourdev
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNG_DETAIL_SCANLINE_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNG_DETAIL_SCANLINE_READ_HPP
|
||||
|
||||
#include <boost/gil/extension/io/png/detail/is_allowed.hpp>
|
||||
#include <boost/gil/extension/io/png/detail/reader_backend.hpp>
|
||||
|
||||
#include <boost/gil.hpp> // FIXME: Include what you use!
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/conversion_policies.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/reader_base.hpp>
|
||||
#include <boost/gil/io/row_buffer_helper.hpp>
|
||||
#include <boost/gil/io/scanline_read_iterator.hpp>
|
||||
#include <boost/gil/io/typedefs.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
///
|
||||
/// PNG Reader
|
||||
///
|
||||
template< typename Device >
|
||||
class scanline_reader< Device
|
||||
, png_tag
|
||||
>
|
||||
: public reader_backend< Device
|
||||
, png_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using tag_t = png_tag;
|
||||
using backend_t = reader_backend<Device, tag_t>;
|
||||
using this_t = scanline_reader<Device, tag_t>;
|
||||
using iterator_t = scanline_read_iterator<this_t>;
|
||||
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
scanline_reader( const Device& io_dev
|
||||
, const image_read_settings< png_tag >& settings
|
||||
)
|
||||
: reader_backend< Device
|
||||
, png_tag
|
||||
>( io_dev
|
||||
, settings
|
||||
)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
void read( byte_t* dst
|
||||
, int
|
||||
)
|
||||
{
|
||||
read_scanline( dst );
|
||||
}
|
||||
|
||||
/// Skip over a scanline.
|
||||
void skip( byte_t* dst, int )
|
||||
{
|
||||
read_scanline( dst );
|
||||
}
|
||||
|
||||
iterator_t begin() { return iterator_t( *this ); }
|
||||
iterator_t end() { return iterator_t( *this, this->_info._height ); }
|
||||
|
||||
private:
|
||||
|
||||
void initialize()
|
||||
{
|
||||
// Now it's time for some transformations.
|
||||
|
||||
if( little_endian() )
|
||||
{
|
||||
if( this->_info._bit_depth == 16 )
|
||||
{
|
||||
// Swap bytes of 16 bit files to least significant byte first.
|
||||
png_set_swap( this->get()->_struct );
|
||||
}
|
||||
|
||||
if( this->_info._bit_depth < 8 )
|
||||
{
|
||||
// swap bits of 1, 2, 4 bit packed pixel formats
|
||||
png_set_packswap( this->get()->_struct );
|
||||
}
|
||||
}
|
||||
|
||||
if( this->_info._color_type == PNG_COLOR_TYPE_PALETTE )
|
||||
{
|
||||
png_set_palette_to_rgb( this->get()->_struct );
|
||||
}
|
||||
|
||||
if( this->_info._num_trans > 0 )
|
||||
{
|
||||
png_set_tRNS_to_alpha( this->get()->_struct );
|
||||
}
|
||||
|
||||
// Tell libpng to handle the gamma conversion for you. The final call
|
||||
// is a good guess for PC generated images, but it should be configurable
|
||||
// by the user at run time by the user. It is strongly suggested that
|
||||
// your application support gamma correction.
|
||||
if( this->_settings._apply_screen_gamma )
|
||||
{
|
||||
// png_set_gamma will change the image data!
|
||||
|
||||
#ifdef BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
png_set_gamma( this->get()->_struct
|
||||
, this->_settings._screen_gamma
|
||||
, this->_info._file_gamma
|
||||
);
|
||||
#else
|
||||
png_set_gamma( this->get()->_struct
|
||||
, this->_settings._screen_gamma
|
||||
, this->_info._file_gamma
|
||||
);
|
||||
#endif // BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
}
|
||||
|
||||
// Interlaced images are not supported.
|
||||
this->_number_passes = png_set_interlace_handling( this->get()->_struct );
|
||||
io_error_if( this->_number_passes != 1
|
||||
, "scanline_read_iterator cannot read interlaced png images."
|
||||
);
|
||||
|
||||
|
||||
// The above transformation might have changed the bit_depth and color type.
|
||||
png_read_update_info( this->get()->_struct
|
||||
, this->get()->_info
|
||||
);
|
||||
|
||||
this->_info._bit_depth = png_get_bit_depth( this->get()->_struct
|
||||
, this->get()->_info
|
||||
);
|
||||
|
||||
this->_info._num_channels = png_get_channels( this->get()->_struct
|
||||
, this->get()->_info
|
||||
);
|
||||
|
||||
this->_info._color_type = png_get_color_type( this->get()->_struct
|
||||
, this->get()->_info
|
||||
);
|
||||
|
||||
this->_scanline_length = png_get_rowbytes( this->get()->_struct
|
||||
, this->get()->_info
|
||||
);
|
||||
}
|
||||
|
||||
void read_scanline( byte_t* dst )
|
||||
{
|
||||
png_read_row( this->get()->_struct
|
||||
, dst
|
||||
, NULL
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,362 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning, Andreas Pokorny, Lubomir Bourdev
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNG_DETAIL_SUPPORTED_TYPES_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNG_DETAIL_SUPPORTED_TYPES_HPP
|
||||
|
||||
#include <boost/gil/extension/io/png/tags.hpp>
|
||||
|
||||
#ifdef BOOST_GIL_IO_ENABLE_GRAY_ALPHA
|
||||
#include <boost/gil/extension/toolbox/color_spaces/gray_alpha.hpp>
|
||||
#endif // BOOST_GIL_IO_ENABLE_GRAY_ALPHA
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
static const size_t PNG_BYTES_TO_CHECK = 4;
|
||||
|
||||
// Read support
|
||||
template< png_bitdepth::type BitDepth
|
||||
, png_color_type::type ColorType
|
||||
>
|
||||
struct png_rw_support_base
|
||||
{
|
||||
static const png_bitdepth::type _bit_depth = BitDepth;
|
||||
static const png_color_type::type _color_type = ColorType;
|
||||
};
|
||||
|
||||
template< typename Channel
|
||||
, typename ColorSpace
|
||||
>
|
||||
struct png_read_support : read_support_false
|
||||
, png_rw_support_base< 1
|
||||
, PNG_COLOR_TYPE_GRAY
|
||||
> {};
|
||||
|
||||
template< typename BitField
|
||||
, bool Mutable
|
||||
>
|
||||
struct png_read_support< packed_dynamic_channel_reference< BitField
|
||||
, 1
|
||||
, Mutable
|
||||
>
|
||||
, gray_t
|
||||
> : read_support_true
|
||||
, png_rw_support_base< 1
|
||||
, PNG_COLOR_TYPE_GRAY
|
||||
> {};
|
||||
|
||||
template< typename BitField
|
||||
, bool Mutable
|
||||
>
|
||||
struct png_read_support< packed_dynamic_channel_reference< BitField
|
||||
, 2
|
||||
, Mutable
|
||||
>
|
||||
, gray_t
|
||||
> : read_support_true
|
||||
, png_rw_support_base< 2
|
||||
, PNG_COLOR_TYPE_GRAY
|
||||
> {};
|
||||
|
||||
template< typename BitField
|
||||
, bool Mutable
|
||||
>
|
||||
struct png_read_support< packed_dynamic_channel_reference< BitField
|
||||
, 4
|
||||
, Mutable
|
||||
>
|
||||
, gray_t
|
||||
> : read_support_true
|
||||
, png_rw_support_base< 4
|
||||
, PNG_COLOR_TYPE_GRAY
|
||||
> {};
|
||||
|
||||
template<>
|
||||
struct png_read_support<uint8_t
|
||||
, gray_t
|
||||
> : read_support_true
|
||||
, png_rw_support_base< 8
|
||||
, PNG_COLOR_TYPE_GRAY
|
||||
> {};
|
||||
|
||||
#ifdef BOOST_GIL_IO_ENABLE_GRAY_ALPHA
|
||||
template<>
|
||||
struct png_read_support<uint8_t
|
||||
, gray_alpha_t
|
||||
> : read_support_true
|
||||
, png_rw_support_base< 8
|
||||
, PNG_COLOR_TYPE_GA
|
||||
> {};
|
||||
#endif // BOOST_GIL_IO_ENABLE_GRAY_ALPHA
|
||||
|
||||
template<>
|
||||
struct png_read_support<uint8_t
|
||||
, rgb_t
|
||||
> : read_support_true
|
||||
, png_rw_support_base< 8
|
||||
, PNG_COLOR_TYPE_RGB
|
||||
> {};
|
||||
|
||||
template<>
|
||||
struct png_read_support<uint8_t
|
||||
, rgba_t
|
||||
> : read_support_true
|
||||
, png_rw_support_base< 8
|
||||
, PNG_COLOR_TYPE_RGBA
|
||||
> {};
|
||||
|
||||
template<>
|
||||
struct png_read_support<uint16_t
|
||||
, gray_t
|
||||
> : read_support_true
|
||||
, png_rw_support_base< 16
|
||||
, PNG_COLOR_TYPE_GRAY
|
||||
> {};
|
||||
|
||||
template<>
|
||||
struct png_read_support<uint16_t
|
||||
, rgb_t
|
||||
> : read_support_true
|
||||
, png_rw_support_base< 16
|
||||
, PNG_COLOR_TYPE_RGB
|
||||
> {};
|
||||
|
||||
template<>
|
||||
struct png_read_support<uint16_t
|
||||
, rgba_t
|
||||
> : read_support_true
|
||||
, png_rw_support_base< 16
|
||||
, PNG_COLOR_TYPE_RGBA
|
||||
> {};
|
||||
|
||||
#ifdef BOOST_GIL_IO_ENABLE_GRAY_ALPHA
|
||||
template<>
|
||||
struct png_read_support<uint16_t
|
||||
, gray_alpha_t
|
||||
> : read_support_true
|
||||
, png_rw_support_base< 16
|
||||
, PNG_COLOR_TYPE_GA
|
||||
> {};
|
||||
#endif // BOOST_GIL_IO_ENABLE_GRAY_ALPHA
|
||||
|
||||
// Write support
|
||||
|
||||
template< typename Channel
|
||||
, typename ColorSpace
|
||||
>
|
||||
struct png_write_support : write_support_false
|
||||
, png_rw_support_base< 1
|
||||
, PNG_COLOR_TYPE_GRAY
|
||||
> {};
|
||||
|
||||
template< typename BitField
|
||||
, bool Mutable
|
||||
>
|
||||
struct png_write_support< packed_dynamic_channel_reference< BitField
|
||||
, 1
|
||||
, Mutable
|
||||
>
|
||||
, gray_t
|
||||
> : write_support_true
|
||||
, png_rw_support_base< 1
|
||||
, PNG_COLOR_TYPE_GRAY
|
||||
>
|
||||
{};
|
||||
|
||||
template< typename BitField
|
||||
, bool Mutable
|
||||
>
|
||||
struct png_write_support< packed_dynamic_channel_reference< BitField
|
||||
, 1
|
||||
, Mutable
|
||||
> const
|
||||
, gray_t
|
||||
> : write_support_true
|
||||
, png_rw_support_base< 1
|
||||
, PNG_COLOR_TYPE_GRAY
|
||||
>
|
||||
{};
|
||||
|
||||
template< typename BitField
|
||||
, bool Mutable
|
||||
>
|
||||
struct png_write_support< packed_dynamic_channel_reference< BitField
|
||||
, 2
|
||||
, Mutable
|
||||
>
|
||||
, gray_t
|
||||
> : write_support_true
|
||||
, png_rw_support_base< 2
|
||||
, PNG_COLOR_TYPE_GRAY
|
||||
>
|
||||
{};
|
||||
|
||||
template< typename BitField
|
||||
, bool Mutable
|
||||
>
|
||||
struct png_write_support< packed_dynamic_channel_reference< BitField
|
||||
, 2
|
||||
, Mutable
|
||||
> const
|
||||
, gray_t
|
||||
> : write_support_true
|
||||
, png_rw_support_base< 2
|
||||
, PNG_COLOR_TYPE_GRAY
|
||||
>
|
||||
{};
|
||||
|
||||
template< typename BitField
|
||||
, bool Mutable
|
||||
>
|
||||
struct png_write_support< packed_dynamic_channel_reference< BitField
|
||||
, 4
|
||||
, Mutable
|
||||
>
|
||||
, gray_t
|
||||
> : write_support_true
|
||||
, png_rw_support_base< 4
|
||||
, PNG_COLOR_TYPE_GRAY
|
||||
>
|
||||
{};
|
||||
|
||||
template< typename BitField
|
||||
, bool Mutable
|
||||
>
|
||||
struct png_write_support< packed_dynamic_channel_reference< BitField
|
||||
, 4
|
||||
, Mutable
|
||||
> const
|
||||
, gray_t
|
||||
> : write_support_true
|
||||
, png_rw_support_base< 4
|
||||
, PNG_COLOR_TYPE_GRAY
|
||||
>
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct png_write_support<uint8_t
|
||||
, gray_t
|
||||
> : write_support_true
|
||||
, png_rw_support_base< 8
|
||||
, PNG_COLOR_TYPE_GRAY
|
||||
>
|
||||
{};
|
||||
|
||||
#ifdef BOOST_GIL_IO_ENABLE_GRAY_ALPHA
|
||||
template<>
|
||||
struct png_write_support<uint8_t
|
||||
, gray_alpha_t
|
||||
> : write_support_true
|
||||
, png_rw_support_base< 8
|
||||
, PNG_COLOR_TYPE_GA
|
||||
>
|
||||
{};
|
||||
#endif // BOOST_GIL_IO_ENABLE_GRAY_ALPHA
|
||||
|
||||
template<>
|
||||
struct png_write_support<uint8_t
|
||||
, rgb_t
|
||||
> : write_support_true
|
||||
, png_rw_support_base< 8
|
||||
, PNG_COLOR_TYPE_RGB
|
||||
>
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct png_write_support<uint8_t
|
||||
, rgba_t
|
||||
> : write_support_true
|
||||
, png_rw_support_base< 8
|
||||
, PNG_COLOR_TYPE_RGBA
|
||||
>
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct png_write_support<uint16_t
|
||||
, gray_t
|
||||
> : write_support_true
|
||||
, png_rw_support_base< 16
|
||||
, PNG_COLOR_TYPE_GRAY
|
||||
>
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct png_write_support<uint16_t
|
||||
, rgb_t
|
||||
> : write_support_true
|
||||
, png_rw_support_base< 16
|
||||
, PNG_COLOR_TYPE_RGB
|
||||
>
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct png_write_support<uint16_t
|
||||
, rgba_t
|
||||
> : write_support_true
|
||||
, png_rw_support_base< 16
|
||||
, PNG_COLOR_TYPE_RGBA
|
||||
>
|
||||
{};
|
||||
|
||||
#ifdef BOOST_GIL_IO_ENABLE_GRAY_ALPHA
|
||||
template<>
|
||||
struct png_write_support<uint16_t
|
||||
, gray_alpha_t
|
||||
> : write_support_true
|
||||
, png_rw_support_base< 16
|
||||
, PNG_COLOR_TYPE_GA
|
||||
>
|
||||
{};
|
||||
#endif // BOOST_GIL_IO_ENABLE_GRAY_ALPHA
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template< typename Pixel >
|
||||
struct is_read_supported< Pixel
|
||||
, png_tag
|
||||
>
|
||||
: mpl::bool_< detail::png_read_support< typename channel_type< Pixel >::type
|
||||
, typename color_space_type< Pixel >::type
|
||||
>::is_supported
|
||||
>
|
||||
{
|
||||
using parent_t = detail::png_read_support
|
||||
<
|
||||
typename channel_type<Pixel>::type,
|
||||
typename color_space_type<Pixel>::type
|
||||
>;
|
||||
|
||||
static const png_bitdepth::type _bit_depth = parent_t::_bit_depth;
|
||||
static const png_color_type::type _color_type = parent_t::_color_type;
|
||||
};
|
||||
|
||||
template< typename Pixel >
|
||||
struct is_write_supported< Pixel
|
||||
, png_tag
|
||||
>
|
||||
: mpl::bool_< detail::png_write_support< typename channel_type< Pixel >::type
|
||||
, typename color_space_type< Pixel >::type
|
||||
>::is_supported
|
||||
>
|
||||
{
|
||||
using parent_t = detail::png_write_support
|
||||
<
|
||||
typename channel_type<Pixel>::type,
|
||||
typename color_space_type<Pixel>::type
|
||||
>;
|
||||
|
||||
static const png_bitdepth::type _bit_depth = parent_t::_bit_depth;
|
||||
static const png_color_type::type _color_type = parent_t::_color_type;
|
||||
};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
239
linx64/include/boost/gil/extension/io/png/detail/write.hpp
Normal file
239
linx64/include/boost/gil/extension/io/png/detail/write.hpp
Normal file
@@ -0,0 +1,239 @@
|
||||
//
|
||||
// Copyright 2007-2012 Christian Henning, Andreas Pokorny, Lubomir Bourdev
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNG_DETAIL_WRITE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNG_DETAIL_WRITE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/png/detail/writer_backend.hpp>
|
||||
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/dynamic_io_new.hpp>
|
||||
#include <boost/gil/io/row_buffer_helper.hpp>
|
||||
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/equal_to.hpp>
|
||||
#include <boost/mpl/less.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct png_write_is_supported
|
||||
{
|
||||
template< typename View >
|
||||
struct apply
|
||||
: public is_write_supported< typename get_pixel_type< View >::type
|
||||
, png_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///
|
||||
/// PNG Writer
|
||||
///
|
||||
template< typename Device >
|
||||
class writer< Device
|
||||
, png_tag
|
||||
>
|
||||
: public writer_backend< Device
|
||||
, png_tag
|
||||
>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
using backend_t = writer_backend<Device, png_tag>;
|
||||
|
||||
writer( const Device& io_dev
|
||||
, const image_write_info< png_tag >& info
|
||||
)
|
||||
: backend_t( io_dev
|
||||
, info
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
template< typename View >
|
||||
void apply( const View& view )
|
||||
{
|
||||
io_error_if( view.width() == 0 && view.height() == 0
|
||||
, "png format cannot handle empty views."
|
||||
);
|
||||
|
||||
this->write_header( view );
|
||||
|
||||
write_view( view
|
||||
, typename is_bit_aligned< typename View::value_type >::type()
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<typename View>
|
||||
void write_view( const View& view
|
||||
, mpl::false_ // is bit aligned
|
||||
)
|
||||
{
|
||||
using pixel_t = typename get_pixel_type<View>::type;
|
||||
|
||||
using png_rw_info = detail::png_write_support
|
||||
<
|
||||
typename channel_type<pixel_t>::type,
|
||||
typename color_space_type<pixel_t>::type
|
||||
>;
|
||||
|
||||
if( little_endian() )
|
||||
{
|
||||
set_swap< png_rw_info >();
|
||||
}
|
||||
|
||||
std::vector< pixel< typename channel_type< View >::type
|
||||
, layout<typename color_space_type< View >::type >
|
||||
>
|
||||
> row_buffer( view.width() );
|
||||
|
||||
for( int y = 0; y != view.height(); ++ y)
|
||||
{
|
||||
std::copy( view.row_begin( y )
|
||||
, view.row_end ( y )
|
||||
, row_buffer.begin()
|
||||
);
|
||||
|
||||
png_write_row( this->get_struct()
|
||||
, reinterpret_cast< png_bytep >( row_buffer.data() )
|
||||
);
|
||||
}
|
||||
|
||||
png_write_end( this->get_struct()
|
||||
, this->get_info()
|
||||
);
|
||||
}
|
||||
|
||||
template<typename View>
|
||||
void write_view( const View& view
|
||||
, mpl::true_ // is bit aligned
|
||||
)
|
||||
{
|
||||
using png_rw_info = detail::png_write_support
|
||||
<
|
||||
typename kth_semantic_element_type<typename View::value_type, 0>::type,
|
||||
typename color_space_type<View>::type
|
||||
>;
|
||||
|
||||
if (little_endian() )
|
||||
{
|
||||
set_swap< png_rw_info >();
|
||||
}
|
||||
|
||||
detail::row_buffer_helper_view< View > row_buffer( view.width()
|
||||
, false
|
||||
);
|
||||
|
||||
for( int y = 0; y != view.height(); ++y )
|
||||
{
|
||||
std::copy( view.row_begin( y )
|
||||
, view.row_end ( y )
|
||||
, row_buffer.begin()
|
||||
);
|
||||
|
||||
png_write_row( this->get_struct()
|
||||
, reinterpret_cast< png_bytep >( row_buffer.data() )
|
||||
);
|
||||
}
|
||||
|
||||
png_free_data( this->get_struct()
|
||||
, this->get_info()
|
||||
, PNG_FREE_UNKN
|
||||
, -1
|
||||
);
|
||||
|
||||
png_write_end( this->get_struct()
|
||||
, this->get_info()
|
||||
);
|
||||
}
|
||||
|
||||
template< typename Info > struct is_less_than_eight : mpl::less< mpl::int_< Info::_bit_depth >, mpl::int_< 8 > > {};
|
||||
template< typename Info > struct is_equal_to_sixteen : mpl::equal_to< mpl::int_< Info::_bit_depth >, mpl::int_< 16 > > {};
|
||||
|
||||
template <typename Info>
|
||||
void set_swap(typename std::enable_if<is_less_than_eight<Info>::value>::type* /*ptr*/ = 0)
|
||||
{
|
||||
png_set_packswap(this->get_struct());
|
||||
}
|
||||
|
||||
template <typename Info>
|
||||
void set_swap(typename std::enable_if<is_equal_to_sixteen<Info>::value>::type* /*ptr*/ = 0)
|
||||
{
|
||||
png_set_swap(this->get_struct());
|
||||
}
|
||||
|
||||
template <typename Info>
|
||||
void set_swap(
|
||||
typename std::enable_if
|
||||
<
|
||||
mpl::and_
|
||||
<
|
||||
mpl::not_<is_less_than_eight<Info>>,
|
||||
mpl::not_<is_equal_to_sixteen<Info>>
|
||||
>::value
|
||||
>::type* /*ptr*/ = nullptr)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// PNG Dynamic Image Writer
|
||||
///
|
||||
template< typename Device >
|
||||
class dynamic_image_writer< Device
|
||||
, png_tag
|
||||
>
|
||||
: public writer< Device
|
||||
, png_tag
|
||||
>
|
||||
{
|
||||
using parent_t = writer<Device, png_tag>;
|
||||
|
||||
public:
|
||||
|
||||
dynamic_image_writer( const Device& io_dev
|
||||
, const image_write_info< png_tag >& info
|
||||
)
|
||||
: parent_t( io_dev
|
||||
, info
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename Views >
|
||||
void apply( const any_image_view< Views >& views )
|
||||
{
|
||||
detail::dynamic_io_fnobj< detail::png_write_is_supported
|
||||
, parent_t
|
||||
> op( this );
|
||||
|
||||
apply_operation( views, op );
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,502 @@
|
||||
//
|
||||
// Copyright 2012 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNG_DETAIL_WRITER_BACKEND_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNG_DETAIL_WRITER_BACKEND_HPP
|
||||
|
||||
#include <boost/gil/extension/io/png/tags.hpp>
|
||||
#include <boost/gil/extension/io/png/detail/base.hpp>
|
||||
#include <boost/gil/extension/io/png/detail/supported_types.hpp>
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/typedefs.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#pragma warning(disable:4611) //interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#endif
|
||||
|
||||
///
|
||||
/// PNG Writer Backend
|
||||
///
|
||||
template< typename Device >
|
||||
struct writer_backend< Device
|
||||
, png_tag
|
||||
>
|
||||
: public detail::png_struct_info_wrapper
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
using this_t = writer_backend<Device, png_tag>;
|
||||
|
||||
public:
|
||||
|
||||
using format_tag_t = png_tag;
|
||||
|
||||
///
|
||||
/// Constructor
|
||||
///
|
||||
writer_backend( const Device& io_dev
|
||||
, const image_write_info< png_tag >& info
|
||||
)
|
||||
: png_struct_info_wrapper( false )
|
||||
, _io_dev( io_dev )
|
||||
, _info( info )
|
||||
{
|
||||
// Create and initialize the png_struct with the desired error handler
|
||||
// functions. If you want to use the default stderr and longjump method,
|
||||
// you can supply NULL for the last three parameters. We also check that
|
||||
// the library version is compatible with the one used at compile time,
|
||||
// in case we are using dynamically linked libraries. REQUIRED.
|
||||
get()->_struct = png_create_write_struct( PNG_LIBPNG_VER_STRING
|
||||
, nullptr // user_error_ptr
|
||||
, nullptr // user_error_fn
|
||||
, nullptr // user_warning_fn
|
||||
);
|
||||
|
||||
io_error_if( get_struct() == nullptr
|
||||
, "png_writer: fail to call png_create_write_struct()"
|
||||
);
|
||||
|
||||
// Allocate/initialize the image information data. REQUIRED
|
||||
get()->_info = png_create_info_struct( get_struct() );
|
||||
|
||||
if( get_info() == nullptr )
|
||||
{
|
||||
png_destroy_write_struct( &get()->_struct
|
||||
, nullptr
|
||||
);
|
||||
|
||||
io_error( "png_writer: fail to call png_create_info_struct()" );
|
||||
}
|
||||
|
||||
// Set error handling. REQUIRED if you aren't supplying your own
|
||||
// error handling functions in the png_create_write_struct() call.
|
||||
if( setjmp( png_jmpbuf( get_struct() )))
|
||||
{
|
||||
//free all of the memory associated with the png_ptr and info_ptr
|
||||
png_destroy_write_struct( &get()->_struct
|
||||
, &get()->_info
|
||||
);
|
||||
|
||||
io_error( "png_writer: fail to call setjmp()" );
|
||||
}
|
||||
|
||||
init_io( get_struct() );
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
template< typename View >
|
||||
void write_header( const View& view )
|
||||
{
|
||||
using png_rw_info_t = detail::png_write_support
|
||||
<
|
||||
typename channel_type<typename get_pixel_type<View>::type>::type,
|
||||
typename color_space_type<View>::type
|
||||
>;
|
||||
|
||||
// Set the image information here. Width and height are up to 2^31,
|
||||
// bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
|
||||
// the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
|
||||
// PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
|
||||
// or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
|
||||
// PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
|
||||
// currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
|
||||
png_set_IHDR( get_struct()
|
||||
, get_info()
|
||||
, static_cast< png_image_width::type >( view.width() )
|
||||
, static_cast< png_image_height::type >( view.height() )
|
||||
, static_cast< png_bitdepth::type >( png_rw_info_t::_bit_depth )
|
||||
, static_cast< png_color_type::type >( png_rw_info_t::_color_type )
|
||||
, _info._interlace_method
|
||||
, _info._compression_type
|
||||
, _info._filter_method
|
||||
);
|
||||
|
||||
#ifdef BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
if( _info._valid_cie_colors )
|
||||
{
|
||||
png_set_cHRM( get_struct()
|
||||
, get_info()
|
||||
, _info._white_x
|
||||
, _info._white_y
|
||||
, _info._red_x
|
||||
, _info._red_y
|
||||
, _info._green_x
|
||||
, _info._green_y
|
||||
, _info._blue_x
|
||||
, _info._blue_y
|
||||
);
|
||||
}
|
||||
|
||||
if( _info._valid_file_gamma )
|
||||
{
|
||||
png_set_gAMA( get_struct()
|
||||
, get_info()
|
||||
, _info._file_gamma
|
||||
);
|
||||
}
|
||||
#else
|
||||
if( _info._valid_cie_colors )
|
||||
{
|
||||
png_set_cHRM_fixed( get_struct()
|
||||
, get_info()
|
||||
, _info._white_x
|
||||
, _info._white_y
|
||||
, _info._red_x
|
||||
, _info._red_y
|
||||
, _info._green_x
|
||||
, _info._green_y
|
||||
, _info._blue_x
|
||||
, _info._blue_y
|
||||
);
|
||||
}
|
||||
|
||||
if( _info._valid_file_gamma )
|
||||
{
|
||||
png_set_gAMA_fixed( get_struct()
|
||||
, get_info()
|
||||
, _info._file_gamma
|
||||
);
|
||||
}
|
||||
#endif // BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
|
||||
if( _info._valid_icc_profile )
|
||||
{
|
||||
#if PNG_LIBPNG_VER_MINOR >= 5
|
||||
png_set_iCCP( get_struct()
|
||||
, get_info()
|
||||
, const_cast< png_charp >( _info._icc_name.c_str() )
|
||||
, _info._iccp_compression_type
|
||||
, reinterpret_cast< png_const_bytep >( & (_info._profile.front ()) )
|
||||
, _info._profile_length
|
||||
);
|
||||
#else
|
||||
png_set_iCCP( get_struct()
|
||||
, get_info()
|
||||
, const_cast< png_charp >( _info._icc_name.c_str() )
|
||||
, _info._iccp_compression_type
|
||||
, const_cast< png_charp >( & (_info._profile.front()) )
|
||||
, _info._profile_length
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
if( _info._valid_intent )
|
||||
{
|
||||
png_set_sRGB( get_struct()
|
||||
, get_info()
|
||||
, _info._intent
|
||||
);
|
||||
}
|
||||
|
||||
if( _info._valid_palette )
|
||||
{
|
||||
png_set_PLTE( get_struct()
|
||||
, get_info()
|
||||
, const_cast< png_colorp >( &_info._palette.front() )
|
||||
, _info._num_palette
|
||||
);
|
||||
}
|
||||
|
||||
if( _info._valid_background )
|
||||
{
|
||||
png_set_bKGD( get_struct()
|
||||
, get_info()
|
||||
, const_cast< png_color_16p >( &_info._background )
|
||||
);
|
||||
}
|
||||
|
||||
if( _info._valid_histogram )
|
||||
{
|
||||
png_set_hIST( get_struct()
|
||||
, get_info()
|
||||
, const_cast< png_uint_16p >( &_info._histogram.front() )
|
||||
);
|
||||
}
|
||||
|
||||
if( _info._valid_offset )
|
||||
{
|
||||
png_set_oFFs( get_struct()
|
||||
, get_info()
|
||||
, _info._offset_x
|
||||
, _info._offset_y
|
||||
, _info._off_unit_type
|
||||
);
|
||||
}
|
||||
|
||||
if( _info._valid_pixel_calibration )
|
||||
{
|
||||
std::vector< const char* > params( _info._num_params );
|
||||
for( std::size_t i = 0; i < params.size(); ++i )
|
||||
{
|
||||
params[i] = _info._params[ i ].c_str();
|
||||
}
|
||||
|
||||
png_set_pCAL( get_struct()
|
||||
, get_info()
|
||||
, const_cast< png_charp >( _info._purpose.c_str() )
|
||||
, _info._X0
|
||||
, _info._X1
|
||||
, _info._cal_type
|
||||
, _info._num_params
|
||||
, const_cast< png_charp >( _info._units.c_str() )
|
||||
, const_cast< png_charpp >( ¶ms.front() )
|
||||
);
|
||||
}
|
||||
|
||||
if( _info._valid_resolution )
|
||||
{
|
||||
png_set_pHYs( get_struct()
|
||||
, get_info()
|
||||
, _info._res_x
|
||||
, _info._res_y
|
||||
, _info._phy_unit_type
|
||||
);
|
||||
}
|
||||
|
||||
if( _info._valid_significant_bits )
|
||||
{
|
||||
png_set_sBIT( get_struct()
|
||||
, get_info()
|
||||
, const_cast< png_color_8p >( &_info._sig_bits )
|
||||
);
|
||||
}
|
||||
|
||||
#ifndef BOOST_GIL_IO_PNG_1_4_OR_LOWER
|
||||
|
||||
#ifdef BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
if( _info._valid_scale_factors )
|
||||
{
|
||||
png_set_sCAL( get_struct()
|
||||
, get_info()
|
||||
, this->_info._scale_unit
|
||||
, this->_info._scale_width
|
||||
, this->_info._scale_height
|
||||
);
|
||||
}
|
||||
#else
|
||||
#ifdef BOOST_GIL_IO_PNG_FIXED_POINT_SUPPORTED
|
||||
if( _info._valid_scale_factors )
|
||||
{
|
||||
png_set_sCAL_fixed( get_struct()
|
||||
, get_info()
|
||||
, this->_info._scale_unit
|
||||
, this->_info._scale_width
|
||||
, this->_info._scale_height
|
||||
);
|
||||
}
|
||||
#else
|
||||
if( _info._valid_scale_factors )
|
||||
{
|
||||
png_set_sCAL_s( get_struct()
|
||||
, get_info()
|
||||
, this->_info._scale_unit
|
||||
, const_cast< png_charp >( this->_info._scale_width.c_str() )
|
||||
, const_cast< png_charp >( this->_info._scale_height.c_str() )
|
||||
);
|
||||
}
|
||||
|
||||
#endif // BOOST_GIL_IO_PNG_FIXED_POINT_SUPPORTED
|
||||
#endif // BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
#endif // BOOST_GIL_IO_PNG_1_4_OR_LOWER
|
||||
|
||||
if( _info._valid_text )
|
||||
{
|
||||
std::vector< png_text > texts( _info._num_text );
|
||||
for( std::size_t i = 0; i < texts.size(); ++i )
|
||||
{
|
||||
png_text pt;
|
||||
pt.compression = _info._text[i]._compression;
|
||||
pt.key = const_cast< png_charp >( this->_info._text[i]._key.c_str() );
|
||||
pt.text = const_cast< png_charp >( this->_info._text[i]._text.c_str() );
|
||||
pt.text_length = _info._text[i]._text.length();
|
||||
|
||||
texts[i] = pt;
|
||||
}
|
||||
|
||||
png_set_text( get_struct()
|
||||
, get_info()
|
||||
, &texts.front()
|
||||
, _info._num_text
|
||||
);
|
||||
}
|
||||
|
||||
if( _info._valid_modification_time )
|
||||
{
|
||||
png_set_tIME( get_struct()
|
||||
, get_info()
|
||||
, const_cast< png_timep >( &_info._mod_time )
|
||||
);
|
||||
}
|
||||
|
||||
if( _info._valid_transparency_factors )
|
||||
{
|
||||
int sample_max = ( 1u << _info._bit_depth );
|
||||
|
||||
/* libpng doesn't reject a tRNS chunk with out-of-range samples */
|
||||
if( !( ( _info._color_type == PNG_COLOR_TYPE_GRAY
|
||||
&& (int) _info._trans_values[0].gray > sample_max
|
||||
)
|
||||
|| ( _info._color_type == PNG_COLOR_TYPE_RGB
|
||||
&&( (int) _info._trans_values[0].red > sample_max
|
||||
|| (int) _info._trans_values[0].green > sample_max
|
||||
|| (int) _info._trans_values[0].blue > sample_max
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
//@todo Fix that once reading transparency values works
|
||||
/*
|
||||
png_set_tRNS( get_struct()
|
||||
, get_info()
|
||||
, trans
|
||||
, num_trans
|
||||
, trans_values
|
||||
);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
// Compression Levels - valid values are [0,9]
|
||||
png_set_compression_level( get_struct()
|
||||
, _info._compression_level
|
||||
);
|
||||
|
||||
png_set_compression_mem_level( get_struct()
|
||||
, _info._compression_mem_level
|
||||
);
|
||||
|
||||
png_set_compression_strategy( get_struct()
|
||||
, _info._compression_strategy
|
||||
);
|
||||
|
||||
png_set_compression_window_bits( get_struct()
|
||||
, _info._compression_window_bits
|
||||
);
|
||||
|
||||
png_set_compression_method( get_struct()
|
||||
, _info._compression_method
|
||||
);
|
||||
|
||||
png_set_compression_buffer_size( get_struct()
|
||||
, _info._compression_buffer_size
|
||||
);
|
||||
|
||||
#ifdef BOOST_GIL_IO_PNG_DITHERING_SUPPORTED
|
||||
// Dithering
|
||||
if( _info._set_dithering )
|
||||
{
|
||||
png_set_dither( get_struct()
|
||||
, &_info._dithering_palette.front()
|
||||
, _info._dithering_num_palette
|
||||
, _info._dithering_maximum_colors
|
||||
, &_info._dithering_histogram.front()
|
||||
, _info._full_dither
|
||||
);
|
||||
}
|
||||
#endif // BOOST_GIL_IO_PNG_DITHERING_SUPPORTED
|
||||
|
||||
// Filter
|
||||
if( _info._set_filter )
|
||||
{
|
||||
png_set_filter( get_struct()
|
||||
, 0
|
||||
, _info._filter
|
||||
);
|
||||
}
|
||||
|
||||
// Invert Mono
|
||||
if( _info._invert_mono )
|
||||
{
|
||||
png_set_invert_mono( get_struct() );
|
||||
}
|
||||
|
||||
// True Bits
|
||||
if( _info._set_true_bits )
|
||||
{
|
||||
png_set_sBIT( get_struct()
|
||||
, get_info()
|
||||
, &_info._true_bits.front()
|
||||
);
|
||||
}
|
||||
|
||||
// sRGB Intent
|
||||
if( _info._set_srgb_intent )
|
||||
{
|
||||
png_set_sRGB( get_struct()
|
||||
, get_info()
|
||||
, _info._srgb_intent
|
||||
);
|
||||
}
|
||||
|
||||
// Strip Alpha
|
||||
if( _info._strip_alpha )
|
||||
{
|
||||
png_set_strip_alpha( get_struct() );
|
||||
}
|
||||
|
||||
// Swap Alpha
|
||||
if( _info._swap_alpha )
|
||||
{
|
||||
png_set_swap_alpha( get_struct() );
|
||||
}
|
||||
|
||||
|
||||
png_write_info( get_struct()
|
||||
, get_info()
|
||||
);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
static void write_data( png_structp png_ptr
|
||||
, png_bytep data
|
||||
, png_size_t length
|
||||
)
|
||||
{
|
||||
static_cast< Device* >( png_get_io_ptr( png_ptr ))->write( data
|
||||
, length );
|
||||
}
|
||||
|
||||
static void flush( png_structp png_ptr )
|
||||
{
|
||||
static_cast< Device* >(png_get_io_ptr(png_ptr) )->flush();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void init_io( png_structp png_ptr )
|
||||
{
|
||||
png_set_write_fn( png_ptr
|
||||
, static_cast< void* > ( &this->_io_dev )
|
||||
, static_cast< png_rw_ptr > ( &this_t::write_data )
|
||||
, static_cast< png_flush_ptr >( &this_t::flush )
|
||||
);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Device _io_dev;
|
||||
|
||||
image_write_info< png_tag > _info;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
159
linx64/include/boost/gil/extension/io/png/old.hpp
Normal file
159
linx64/include/boost/gil/extension/io/png/old.hpp
Normal file
@@ -0,0 +1,159 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNG_OLD_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNG_OLD_HPP
|
||||
|
||||
#include <boost/gil/extension/io/png.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
|
||||
template<typename String>
|
||||
inline point_t png_read_dimensions(String const& filename)
|
||||
{
|
||||
using backend_t = typename get_reader_backend<String, png_tag>::type;
|
||||
backend_t backend = read_image_info(filename, png_tag());
|
||||
return { backend._info._width, backend._info._height };
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void png_read_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
read_view( filename
|
||||
, view
|
||||
, png_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename Image
|
||||
>
|
||||
inline
|
||||
void png_read_image( const String& filename
|
||||
, Image& img
|
||||
)
|
||||
{
|
||||
read_image( filename
|
||||
, img
|
||||
, png_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename View
|
||||
, typename CC
|
||||
>
|
||||
inline
|
||||
void png_read_and_convert_view( const String& filename
|
||||
, const View& view
|
||||
, CC cc
|
||||
)
|
||||
{
|
||||
read_and_convert_view( filename
|
||||
, view
|
||||
, cc
|
||||
, png_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void png_read_and_convert_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
read_and_convert_view( filename
|
||||
, view
|
||||
, png_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename Image
|
||||
, typename CC
|
||||
>
|
||||
inline
|
||||
void png_read_and_convert_image( const String& filename
|
||||
, Image& img
|
||||
, CC cc
|
||||
)
|
||||
{
|
||||
read_and_convert_image( filename
|
||||
, img
|
||||
, cc
|
||||
, png_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename Image
|
||||
>
|
||||
inline
|
||||
void png_read_and_convert_image( const String filename
|
||||
, Image& img
|
||||
)
|
||||
{
|
||||
read_and_convert_image( filename
|
||||
, img
|
||||
, png_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \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 String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void png_write_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
write_view( filename
|
||||
, view
|
||||
, png_tag()
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
30
linx64/include/boost/gil/extension/io/png/read.hpp
Normal file
30
linx64/include/boost/gil/extension/io/png/read.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNG_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNG_READ_HPP
|
||||
|
||||
#define BOOST_GIL_EXTENSION_IO_PNG_READ_ENABLED // TODO: Document, explain, review
|
||||
|
||||
#include <boost/gil/extension/io/png/tags.hpp>
|
||||
#include <boost/gil/extension/io/png/detail/read.hpp>
|
||||
#include <boost/gil/extension/io/png/detail/scanline_read.hpp>
|
||||
#include <boost/gil/extension/io/png/detail/supported_types.hpp>
|
||||
|
||||
#include <boost/gil/io/get_reader.hpp>
|
||||
#include <boost/gil/io/make_backend.hpp>
|
||||
#include <boost/gil/io/make_dynamic_image_reader.hpp>
|
||||
#include <boost/gil/io/make_reader.hpp>
|
||||
#include <boost/gil/io/make_scanline_reader.hpp>
|
||||
#include <boost/gil/io/read_and_convert_image.hpp>
|
||||
#include <boost/gil/io/read_and_convert_view.hpp>
|
||||
#include <boost/gil/io/read_image.hpp>
|
||||
#include <boost/gil/io/read_image_info.hpp>
|
||||
#include <boost/gil/io/read_view.hpp>
|
||||
#include <boost/gil/io/scanline_read_iterator.hpp>
|
||||
|
||||
#endif
|
||||
833
linx64/include/boost/gil/extension/io/png/tags.hpp
Normal file
833
linx64/include/boost/gil/extension/io/png/tags.hpp
Normal file
@@ -0,0 +1,833 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning, Andreas Pokorny, Lubomir Bourdev
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNG_TAGS_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNG_TAGS_HPP
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
#ifdef BOOST_GIL_IO_PNG_FIXED_POINT_SUPPORTED
|
||||
# error "Cannot set both symbols"
|
||||
#endif // BOOST_GIL_IO_PNG_FIXED_POINT_SUPPORTED
|
||||
#endif // BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_PNG_C_LIB_COMPILED_AS_CPLUSPLUS
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <png.h>
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_PNG_C_LIB_COMPILED_AS_CPLUSPLUS
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_ZLIB_C_LIB_COMPILED_AS_CPLUSPLUS
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <zlib.h>
|
||||
#ifndef BOOST_GIL_EXTENSION_IO_ZLIB_C_LIB_COMPILED_AS_CPLUSPLUS
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PNG_LIBPNG_VER_MAJOR == 1
|
||||
#if PNG_LIBPNG_VER_MINOR <= 4
|
||||
#define BOOST_GIL_IO_PNG_1_4_OR_LOWER
|
||||
#endif // PNG_LIBPNG_VER_MAJOR == 1
|
||||
#endif // PNG_LIBPNG_VER_MINOR <= 4
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// Defines png tag.
|
||||
struct png_tag : format_tag {};
|
||||
|
||||
/// see http://en.wikipedia.org/wiki/Portable_Network_Graphics for reference
|
||||
|
||||
/// Defines type for image width property.
|
||||
struct png_image_width : property_base< png_uint_32 > {};
|
||||
|
||||
/// Defines type for image height property.
|
||||
struct png_image_height : property_base< png_uint_32 > {};
|
||||
|
||||
/// Defines type for interlace method property.
|
||||
struct png_interlace_method : property_base< int > {};
|
||||
|
||||
/// Defines type for filter method property.
|
||||
struct png_filter_method : property_base< int > {};
|
||||
|
||||
/// Defines type for bit depth method property.
|
||||
struct png_bitdepth : property_base< int > {};
|
||||
|
||||
/// Defines type for bit depth method property.
|
||||
struct png_color_type : property_base< int > {};
|
||||
|
||||
/// Defines type for number of channels property.
|
||||
struct png_num_channels : property_base< png_byte > {};
|
||||
|
||||
#ifdef BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
|
||||
/// Defines type for CIE chromacities property.
|
||||
struct png_chromacities_type : property_base< double > {};
|
||||
|
||||
/// Defines type for gamma correction property.
|
||||
struct png_gamma : property_base< double > {};
|
||||
|
||||
/// Defines type for physical scale unit property.
|
||||
struct png_unit : property_base< int > {};
|
||||
|
||||
/// Defines type for physical scale property.
|
||||
struct png_scale : property_base< double > {};
|
||||
|
||||
#else
|
||||
/// Defines type for CIE chromacities property.
|
||||
struct png_chromacities_type : property_base< png_fixed_point > {};
|
||||
|
||||
/// Defines type for gamma correction property.
|
||||
struct png_gamma : property_base< png_fixed_point > {};
|
||||
|
||||
/// Defines type for physical scale unit property.
|
||||
struct png_unit : property_base< int > {};
|
||||
|
||||
#ifdef BOOST_GIL_IO_PNG_FIXED_POINT_SUPPORTED
|
||||
/// Defines type for physical scale property.
|
||||
struct png_scale : property_base< png_fixed_point > {};
|
||||
#else
|
||||
/// Defines type for physical scale property.
|
||||
struct png_scale : property_base< std::string > {};
|
||||
#endif // BOOST_GIL_IO_PNG_FIXED_POINT_SUPPORTED
|
||||
|
||||
#endif // BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
|
||||
/// Returns image resolution in pixels per meter, from pHYs chunk data.
|
||||
struct png_pixels_per_meter : property_base< png_uint_32 > {};
|
||||
|
||||
/// Defines type for ICC profile name property.
|
||||
struct png_ICC_name : property_base< std::string > {};
|
||||
/// Defines type for ICC profile property.
|
||||
#if PNG_LIBPNG_VER_MINOR >= 5
|
||||
struct png_ICC_profile : property_base< std:: vector <uint8_t> > {};
|
||||
#else
|
||||
struct png_ICC_profile : property_base< std:: vector <char> > {};
|
||||
#endif
|
||||
/// Defines type for ICC profile length property.
|
||||
struct png_ICC_profile_length : property_base< png_uint_32 > {};
|
||||
/// Defines type for ICC compression property.
|
||||
struct png_ICC_compression_type : property_base< int > {};
|
||||
|
||||
/// Defines type for rendering intent property.
|
||||
struct png_intent : property_base< int > {};
|
||||
|
||||
/// Defines type for color palette property.
|
||||
struct png_color_palette : property_base< std::vector< png_color > > {};
|
||||
/// Defines type for number of colors property.
|
||||
struct png_num_palette : property_base< int > {};
|
||||
|
||||
/// Defines type for background property.
|
||||
struct png_background : property_base< png_color_16 > {};
|
||||
|
||||
/// Defines type for histogram property.
|
||||
struct png_histrogram : property_base< std::vector< png_uint_16 > > {};
|
||||
|
||||
/// Defines type for screen offset property.
|
||||
struct png_offset : property_base< png_int_32 > {};
|
||||
/// Defines type for screen offset type property.
|
||||
struct png_offset_type : property_base< int > {};
|
||||
|
||||
/// Defines type pixel calibration for property.
|
||||
struct png_CAL : property_base< std::string > {};
|
||||
/// Defines type for pixel calibration parameters property.
|
||||
struct png_CAL_params : property_base< std::vector< std::string > > {};
|
||||
/// Defines type for pixel calibration x property.
|
||||
struct png_CAL_X : property_base< png_int_32 > {};
|
||||
/// Defines type for pixel calibration type property.
|
||||
struct png_CAL_type : property_base< int > {};
|
||||
/// Defines type for number of pixel calibration properties.
|
||||
struct png_CAL_nparam : property_base< int > {};
|
||||
|
||||
/// Defines type for physical resolution property.
|
||||
struct png_resolution : property_base< png_uint_32 > {};
|
||||
/// Defines type for physical resolution unit property.
|
||||
struct png_unit_type : property_base< int > {};
|
||||
|
||||
/// Defines type for significant bits property.
|
||||
struct png_significant_bits : property_base< png_color_8 > {};
|
||||
|
||||
/// Helper structure for reading text property.
|
||||
struct gil_io_png_text
|
||||
{
|
||||
/// Compression type
|
||||
int _compression;
|
||||
// Key
|
||||
std::string _key;
|
||||
/// Text
|
||||
std::string _text;
|
||||
};
|
||||
|
||||
/// Defines type for text property.
|
||||
struct png_text_ : property_base< std::vector< gil_io_png_text > > {};
|
||||
/// Defines type for number of text property.
|
||||
struct png_num_text : property_base< int > {};
|
||||
|
||||
/// Defines type for modification time property.
|
||||
struct png_mod_time : property_base< png_time > {};
|
||||
|
||||
/// Defines type for transparency data property.
|
||||
struct png_trans : property_base< std::vector< png_byte > > {};
|
||||
/// Defines type for number of transparency data property.
|
||||
struct png_num_trans : property_base< int > {};
|
||||
/// Defines type for transparency data values property.
|
||||
struct png_trans_values : property_base< std::vector< png_color_16 > > {};
|
||||
|
||||
/// Defines type for png function return type.
|
||||
struct png_return_value : property_base< png_uint_32 > {};
|
||||
|
||||
////////////////////////
|
||||
// Write properties
|
||||
////////////////////////
|
||||
|
||||
// relates to info_ptr->compression_type
|
||||
struct png_compression_type : property_base< png_byte >
|
||||
{
|
||||
static const type default_value = PNG_COMPRESSION_TYPE_BASE;
|
||||
};
|
||||
|
||||
// compression level - default values taken from libpng manual.
|
||||
// Look for png_set_compression_level
|
||||
struct png_compression_level : property_base< int >
|
||||
{
|
||||
static const type default_value = 3;
|
||||
};
|
||||
|
||||
struct png_compression_mem_level : property_base< int >
|
||||
{
|
||||
static const type default_value = MAX_MEM_LEVEL;
|
||||
};
|
||||
|
||||
struct png_compression_strategy : property_base< int >
|
||||
{
|
||||
static const type default_value = Z_DEFAULT_STRATEGY;
|
||||
};
|
||||
|
||||
struct png_compression_window_bits : property_base< int >
|
||||
{
|
||||
static const type default_value = 9;
|
||||
};
|
||||
|
||||
struct png_compression_method : property_base< int >
|
||||
{
|
||||
static const type default_value = 8;
|
||||
};
|
||||
|
||||
struct png_compression_buffer_size : property_base< int >
|
||||
{
|
||||
static const type default_value = 8192;
|
||||
};
|
||||
|
||||
// dithering
|
||||
struct png_dithering_palette : property_base< std::vector< png_color > >
|
||||
{};
|
||||
|
||||
struct png_dithering_num_palette : property_base< int >
|
||||
{
|
||||
static const type default_value = 0;
|
||||
};
|
||||
|
||||
struct png_dithering_maximum_colors : property_base< int >
|
||||
{
|
||||
static const type default_value = 0;
|
||||
};
|
||||
|
||||
struct png_dithering_histogram : property_base< std::vector< png_uint_16 > >
|
||||
{};
|
||||
|
||||
struct png_full_dither : property_base< int >
|
||||
{
|
||||
static const type default_value = 0;
|
||||
};
|
||||
|
||||
// filter
|
||||
struct png_filter : property_base< int >
|
||||
{
|
||||
static const type default_value = 0;
|
||||
};
|
||||
|
||||
// invert mono
|
||||
struct png_invert_mono : property_base< bool >
|
||||
{
|
||||
static const type default_value = false;
|
||||
};
|
||||
|
||||
// true bits
|
||||
struct png_true_bits : property_base< std::vector< png_color_8 > >
|
||||
{};
|
||||
|
||||
// sRGB Intent
|
||||
struct png_srgb_intent : property_base< int >
|
||||
{
|
||||
static const type default_value = 0;
|
||||
};
|
||||
|
||||
// strip alpha
|
||||
struct png_strip_alpha : property_base< bool >
|
||||
{
|
||||
static const type default_value = false;
|
||||
};
|
||||
|
||||
struct png_swap_alpha : property_base< bool >
|
||||
{
|
||||
static const type default_value = false;
|
||||
};
|
||||
|
||||
|
||||
/// PNG info base class. Containing all header information both for reading and writing.
|
||||
///
|
||||
/// This base structure was created to avoid code doubling.
|
||||
struct png_info_base
|
||||
{
|
||||
/// Default constructor
|
||||
png_info_base()
|
||||
: _width ( 0 )
|
||||
, _height( 0 )
|
||||
|
||||
, _bit_depth ( 0 )
|
||||
, _color_type ( 0 )
|
||||
, _interlace_method ( PNG_INTERLACE_NONE )
|
||||
, _compression_method( PNG_COMPRESSION_TYPE_DEFAULT )
|
||||
, _filter_method ( PNG_FILTER_TYPE_DEFAULT )
|
||||
|
||||
, _num_channels( 0 )
|
||||
|
||||
#ifdef BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
, _valid_cie_colors( 0 )
|
||||
, _white_x ( 0.0 )
|
||||
, _white_y ( 0.0 )
|
||||
, _red_x ( 0.0 )
|
||||
, _red_y ( 0.0 )
|
||||
, _green_x ( 0.0 )
|
||||
, _green_y ( 0.0 )
|
||||
, _blue_x ( 0.0 )
|
||||
, _blue_y ( 0.0 )
|
||||
|
||||
, _valid_file_gamma( 0 )
|
||||
, _file_gamma ( 1.0 )
|
||||
#else
|
||||
, _valid_cie_colors( 0 )
|
||||
, _white_x ( 0 )
|
||||
, _white_y ( 0 )
|
||||
, _red_x ( 0 )
|
||||
, _red_y ( 0 )
|
||||
, _green_x ( 0 )
|
||||
, _green_y ( 0 )
|
||||
, _blue_x ( 0 )
|
||||
, _blue_y ( 0 )
|
||||
|
||||
, _valid_file_gamma( 0 )
|
||||
, _file_gamma ( 1 )
|
||||
#endif // BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
|
||||
, _valid_icc_profile ( 0 )
|
||||
, _icc_name ( )
|
||||
, _iccp_compression_type( PNG_COMPRESSION_TYPE_BASE )
|
||||
, _profile ( )
|
||||
, _profile_length ( 0 )
|
||||
|
||||
, _valid_intent( 0 )
|
||||
, _intent ( 0 )
|
||||
|
||||
, _valid_palette( 0 )
|
||||
, _palette ( )
|
||||
, _num_palette ( 0 )
|
||||
|
||||
, _valid_background( 0 )
|
||||
, _background ( )
|
||||
|
||||
, _valid_histogram( 0 )
|
||||
, _histogram ( )
|
||||
|
||||
, _valid_offset ( 0 )
|
||||
, _offset_x ( 0 )
|
||||
, _offset_y ( 0 )
|
||||
, _off_unit_type( PNG_OFFSET_PIXEL )
|
||||
|
||||
, _valid_pixel_calibration( 0 )
|
||||
, _purpose ( )
|
||||
, _X0 ( 0 )
|
||||
, _X1 ( 0 )
|
||||
, _cal_type ( 0 )
|
||||
, _num_params ( 0 )
|
||||
, _units ( )
|
||||
, _params ( )
|
||||
|
||||
, _valid_resolution( 0 )
|
||||
, _res_x ( 0 )
|
||||
, _res_y ( 0 )
|
||||
, _phy_unit_type ( PNG_RESOLUTION_UNKNOWN )
|
||||
|
||||
, _pixels_per_meter( 0 )
|
||||
|
||||
, _valid_significant_bits( 0 )
|
||||
, _sig_bits ( )
|
||||
|
||||
, _valid_scale_factors( 0 )
|
||||
, _scale_unit ( PNG_SCALE_UNKNOWN )
|
||||
#ifdef BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
, _scale_width ( 0.0 )
|
||||
, _scale_height( 0.0 )
|
||||
#else
|
||||
#ifdef BOOST_GIL_IO_PNG_FIXED_POINT_SUPPORTED
|
||||
, _scale_width ( 0 )
|
||||
, _scale_height( 0 )
|
||||
#else
|
||||
, _scale_width ()
|
||||
, _scale_height()
|
||||
#endif // BOOST_GIL_IO_PNG_FIXED_POINT_SUPPORTED
|
||||
#endif // BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
|
||||
, _valid_text( 0 )
|
||||
, _text ( )
|
||||
, _num_text ( 0 )
|
||||
|
||||
, _valid_modification_time( 0 )
|
||||
, _mod_time ( )
|
||||
|
||||
, _valid_transparency_factors( 0 )
|
||||
, _trans ( )
|
||||
, _num_trans ( 0 )
|
||||
, _trans_values ( )
|
||||
{}
|
||||
|
||||
/// The image width.
|
||||
png_image_width::type _width;
|
||||
/// The image height.
|
||||
png_image_height::type _height;
|
||||
|
||||
/// The bit depth per channel.
|
||||
png_bitdepth::type _bit_depth;
|
||||
/// The color space type.
|
||||
png_color_type::type _color_type;
|
||||
/// The interlace methos.
|
||||
png_interlace_method::type _interlace_method;
|
||||
/// The compression method.
|
||||
png_compression_method::type _compression_method;
|
||||
/// The filer method.
|
||||
png_filter_method::type _filter_method;
|
||||
|
||||
/// The number of channels.
|
||||
png_num_channels::type _num_channels;
|
||||
|
||||
// CIE chromacities
|
||||
/// The return value when reading CIE chromacities.
|
||||
png_return_value::type _valid_cie_colors;
|
||||
/// The white x value.
|
||||
png_chromacities_type::type _white_x;
|
||||
/// The white y value.
|
||||
png_chromacities_type::type _white_y;
|
||||
/// The red x value.
|
||||
png_chromacities_type::type _red_x;
|
||||
/// The red y value.
|
||||
png_chromacities_type::type _red_y;
|
||||
/// The green x value.
|
||||
png_chromacities_type::type _green_x;
|
||||
/// The green y value.
|
||||
png_chromacities_type::type _green_y;
|
||||
/// The blue x value.
|
||||
png_chromacities_type::type _blue_x;
|
||||
/// The blue y value.
|
||||
png_chromacities_type::type _blue_y;
|
||||
|
||||
// Gamma Value
|
||||
/// The return value when reading gamma value.
|
||||
png_return_value::type _valid_file_gamma;
|
||||
/// The file gamma value.
|
||||
png_gamma::type _file_gamma;
|
||||
|
||||
// Embedded ICC profile
|
||||
/// The return value when reading ICC profile.
|
||||
png_return_value::type _valid_icc_profile;
|
||||
/// The ICC name.
|
||||
png_ICC_name::type _icc_name;
|
||||
/// The icc compression type.
|
||||
png_ICC_compression_type::type _iccp_compression_type;
|
||||
/// The ICC profile.
|
||||
png_ICC_profile::type _profile;
|
||||
/// The ICC profile length.
|
||||
png_ICC_profile_length::type _profile_length;
|
||||
|
||||
// Rendering intent
|
||||
/// The return value when reading rendering intent.
|
||||
png_return_value::type _valid_intent;
|
||||
/// The rendering intent value.
|
||||
png_intent::type _intent;
|
||||
|
||||
// Image palette
|
||||
/// The return value when reading image palette.
|
||||
png_return_value::type _valid_palette;
|
||||
/// The color palette.
|
||||
png_color_palette::type _palette;
|
||||
/// The number of colors in the palettes.
|
||||
png_num_palette::type _num_palette;
|
||||
|
||||
// Background
|
||||
/// The return value when reading background.
|
||||
png_return_value::type _valid_background;
|
||||
/// The background color.
|
||||
png_background::type _background;
|
||||
|
||||
// Histogram
|
||||
/// The return value when reading histogram.
|
||||
png_return_value::type _valid_histogram;
|
||||
/// The histogram.
|
||||
png_histrogram::type _histogram;
|
||||
|
||||
// Screen offsets
|
||||
/// The return value when reading screen offsets.
|
||||
png_return_value::type _valid_offset;
|
||||
/// The x offset.
|
||||
png_offset::type _offset_x;
|
||||
/// The y offset.
|
||||
png_offset::type _offset_y;
|
||||
/// The offset unit.
|
||||
png_offset_type::type _off_unit_type;
|
||||
|
||||
// Pixel Calibration
|
||||
/// The return value when reading pixel calibration.
|
||||
png_return_value::type _valid_pixel_calibration;
|
||||
/// The purpose.
|
||||
png_CAL::type _purpose;
|
||||
/// The x_0 value.
|
||||
png_CAL_X::type _X0;
|
||||
/// The x_1 value.
|
||||
png_CAL_X::type _X1;
|
||||
/// The calibration type.
|
||||
png_CAL_type::type _cal_type;
|
||||
/// The number of calibration parameters.
|
||||
png_CAL_nparam::type _num_params;
|
||||
/// The calibration unit type.
|
||||
png_CAL::type _units;
|
||||
/// The calibration parameters.
|
||||
png_CAL_params::type _params;
|
||||
|
||||
// Physical resolution
|
||||
/// The return value when reading physical resolution properties.
|
||||
png_return_value::type _valid_resolution;
|
||||
/// The x physical resolution.
|
||||
png_resolution::type _res_x;
|
||||
/// The y physical resolution.
|
||||
png_resolution::type _res_y;
|
||||
/// The physical resolution unit.
|
||||
png_unit_type::type _phy_unit_type;
|
||||
|
||||
/// The Image resolution in pixels per meter.
|
||||
png_pixels_per_meter::type _pixels_per_meter;
|
||||
|
||||
// Number of significant bits
|
||||
/// The return value when reading significant bits.
|
||||
png_return_value::type _valid_significant_bits;
|
||||
/// The significant bits.
|
||||
png_significant_bits::type _sig_bits;
|
||||
|
||||
// Scale Factors
|
||||
/// The return value when reading scale factors.
|
||||
png_return_value::type _valid_scale_factors;
|
||||
/// The scaling unit.
|
||||
png_unit::type _scale_unit;
|
||||
/// The scaling width.
|
||||
png_scale::type _scale_width;
|
||||
/// The scaling height.
|
||||
png_scale::type _scale_height;
|
||||
|
||||
// Comments information
|
||||
/// The return value when reading image comments.
|
||||
png_return_value::type _valid_text;
|
||||
/// The comments.
|
||||
png_text_::type _text;
|
||||
/// The number of comments.
|
||||
png_num_text::type _num_text;
|
||||
|
||||
// Last modification time
|
||||
/// The return value when reading modification time.
|
||||
png_return_value::type _valid_modification_time;
|
||||
/// The modification time.
|
||||
png_mod_time::type _mod_time;
|
||||
|
||||
// Transparency data
|
||||
/// The return value when reading transparency data.
|
||||
png_return_value::type _valid_transparency_factors;
|
||||
/// The transparency data.
|
||||
png_trans::type _trans;
|
||||
/// The number of transparency data.
|
||||
png_num_trans::type _num_trans;
|
||||
/// The transparency data values.
|
||||
png_trans_values::type _trans_values;
|
||||
};
|
||||
|
||||
/// Read information for png images.
|
||||
///
|
||||
/// The structure is returned when using read_image_info.
|
||||
template<>
|
||||
struct image_read_info< png_tag > : public png_info_base
|
||||
{
|
||||
/// Default constructor.
|
||||
image_read_info< png_tag >()
|
||||
: png_info_base()
|
||||
{}
|
||||
};
|
||||
|
||||
/// PNG settings base class.
|
||||
///
|
||||
/// This base structure was created to avoid code doubling.
|
||||
struct png_read_settings_base
|
||||
{
|
||||
/// Default Constructor.
|
||||
png_read_settings_base()
|
||||
{
|
||||
_read_cie_chromacities = false;
|
||||
_read_file_gamma = false;
|
||||
_read_icc_profile = false;
|
||||
_read_intent = false;
|
||||
_read_palette = false;
|
||||
_read_background = false;
|
||||
_read_histogram = false;
|
||||
_read_screen_offsets = false;
|
||||
_read_pixel_calibration = false;
|
||||
_read_physical_resolution = false;
|
||||
_read_pixels_per_meter = false;
|
||||
_read_number_of_significant_bits = false;
|
||||
_read_scale_factors = false;
|
||||
_read_comments = false;
|
||||
_read_last_modification_time = false;
|
||||
_read_transparency_data = false;
|
||||
}
|
||||
|
||||
/// Helper function to enabling reading all png properties.
|
||||
void set_read_members_true()
|
||||
{
|
||||
_read_cie_chromacities = true;
|
||||
_read_file_gamma = true;
|
||||
_read_icc_profile = true;
|
||||
_read_intent = true;
|
||||
_read_palette = true;
|
||||
_read_background = true;
|
||||
_read_histogram = true;
|
||||
_read_screen_offsets = true;
|
||||
_read_pixel_calibration = true;
|
||||
_read_physical_resolution = true;
|
||||
_read_pixels_per_meter = true;
|
||||
_read_number_of_significant_bits = true;
|
||||
_read_scale_factors = true;
|
||||
_read_comments = true;
|
||||
_read_last_modification_time = true;
|
||||
_read_transparency_data = true;
|
||||
}
|
||||
|
||||
/// Enable reading CIE chromacities.
|
||||
bool _read_cie_chromacities;
|
||||
/// Enable reading file gamma.
|
||||
bool _read_file_gamma;
|
||||
/// Enable reading ICC profile.
|
||||
bool _read_icc_profile;
|
||||
/// Enable reading rendering intent.
|
||||
bool _read_intent;
|
||||
/// Enable reading color palette.
|
||||
bool _read_palette;
|
||||
/// Enable reading background color.
|
||||
bool _read_background;
|
||||
/// Enable reading histogram.
|
||||
bool _read_histogram;
|
||||
/// Enable reading screen offsets.
|
||||
bool _read_screen_offsets;
|
||||
/// Enable reading pixel calibration.
|
||||
bool _read_pixel_calibration;
|
||||
/// Enable reading physical resolution.
|
||||
bool _read_physical_resolution;
|
||||
/// Enable reading pixels per meter information.
|
||||
bool _read_pixels_per_meter;
|
||||
/// Enable reading significant bits.
|
||||
bool _read_number_of_significant_bits;
|
||||
/// Enable reading scaling factors.
|
||||
bool _read_scale_factors;
|
||||
/// Enable reading comments.
|
||||
bool _read_comments;
|
||||
/// Enable reading modification time.
|
||||
bool _read_last_modification_time;
|
||||
/// Enable reading transparency data.
|
||||
bool _read_transparency_data;
|
||||
};
|
||||
|
||||
#ifdef BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
|
||||
|
||||
/// Read settings for png images.
|
||||
///
|
||||
/// The structure can be used for all read_xxx functions, except read_image_info.
|
||||
template<>
|
||||
struct image_read_settings< png_tag > : public image_read_settings_base
|
||||
, public png_read_settings_base
|
||||
{
|
||||
/// Default Constructor
|
||||
image_read_settings< png_tag >()
|
||||
: image_read_settings_base()
|
||||
, png_read_settings_base()
|
||||
, _screen_gamma( 1.0 )
|
||||
{}
|
||||
|
||||
/// Constructor
|
||||
/// \param top_left Top left coordinate for reading partial image.
|
||||
/// \param dim Dimensions for reading partial image.
|
||||
/// \param gamma Screen gamma value.
|
||||
image_read_settings( const point_t& top_left
|
||||
, const point_t& dim
|
||||
, const bool apply_screen_gamma = false
|
||||
, const png_gamma::type& screen_gamma = 1.0
|
||||
)
|
||||
: image_read_settings_base( top_left
|
||||
, dim
|
||||
)
|
||||
, png_read_settings_base()
|
||||
, _apply_screen_gamma( apply_screen_gamma )
|
||||
, _screen_gamma( screen_gamma )
|
||||
{}
|
||||
|
||||
/// Apply screen gamma value.
|
||||
bool _apply_screen_gamma;
|
||||
/// The screen gamma value.
|
||||
png_gamma::type _screen_gamma;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
/// Read settings for png images.
|
||||
///
|
||||
/// The structure can be used for all read_xxx functions, except read_image_info.
|
||||
template<>
|
||||
struct image_read_settings< png_tag > : public image_read_settings_base
|
||||
, public png_read_settings_base
|
||||
{
|
||||
/// Default Constructor.
|
||||
image_read_settings< png_tag >()
|
||||
: image_read_settings_base()
|
||||
, png_read_settings_base()
|
||||
, _apply_screen_gamma( false )
|
||||
, _screen_gamma ( 2 )
|
||||
{}
|
||||
|
||||
image_read_settings( const point_t& top_left
|
||||
, const point_t& dim
|
||||
)
|
||||
: image_read_settings_base( top_left
|
||||
, dim
|
||||
)
|
||||
, png_read_settings_base()
|
||||
, _apply_screen_gamma( false )
|
||||
, _screen_gamma ( 2 )
|
||||
{}
|
||||
|
||||
/// Apply screen gamma value.
|
||||
bool _apply_screen_gamma;
|
||||
/// The screen gamma value.
|
||||
png_gamma::type _screen_gamma;
|
||||
};
|
||||
#endif
|
||||
|
||||
/// Write information for png images.
|
||||
///
|
||||
/// The structure can be used for write_view() function.
|
||||
template<>
|
||||
struct image_write_info< png_tag > : public png_info_base
|
||||
{
|
||||
image_write_info( const png_compression_type::type compression_type = png_compression_type::default_value
|
||||
, const png_compression_level::type compression_level = png_compression_level::default_value
|
||||
, const png_compression_mem_level::type compression_mem_level = png_compression_mem_level::default_value
|
||||
, const png_compression_strategy::type compression_strategy = png_compression_strategy::default_value
|
||||
, const png_compression_window_bits::type compression_window_bits = png_compression_window_bits::default_value
|
||||
, const png_compression_method::type compression_method = png_compression_method::default_value
|
||||
, const png_compression_buffer_size::type compression_buffer_size = png_compression_buffer_size::default_value
|
||||
, const png_dithering_num_palette::type num_palette = png_dithering_num_palette::default_value
|
||||
, const png_dithering_maximum_colors::type maximum_colors = png_dithering_maximum_colors::default_value
|
||||
, const png_full_dither::type full_dither = png_full_dither::default_value
|
||||
, const png_filter::type filter = png_filter::default_value
|
||||
, const png_invert_mono::type invert_mono = png_invert_mono::default_value
|
||||
, const png_srgb_intent::type srgb_intent = png_srgb_intent::default_value
|
||||
, const png_strip_alpha::type strip_alpha = png_strip_alpha::default_value
|
||||
, const png_swap_alpha::type swap_alpha = png_swap_alpha::default_value
|
||||
)
|
||||
: png_info_base()
|
||||
, _compression_type( compression_type )
|
||||
, _compression_level( compression_level )
|
||||
, _compression_mem_level( compression_mem_level )
|
||||
, _compression_strategy( compression_strategy )
|
||||
, _compression_window_bits( compression_window_bits )
|
||||
, _compression_method( compression_method )
|
||||
, _compression_buffer_size( compression_buffer_size )
|
||||
|
||||
, _set_dithering( false )
|
||||
, _dithering_palette()
|
||||
, _dithering_num_palette( num_palette )
|
||||
, _dithering_maximum_colors( maximum_colors )
|
||||
, _dithering_histogram()
|
||||
, _full_dither( full_dither )
|
||||
|
||||
, _set_filter( false )
|
||||
, _filter( filter )
|
||||
|
||||
, _invert_mono( invert_mono )
|
||||
|
||||
, _set_true_bits( false )
|
||||
, _true_bits()
|
||||
|
||||
, _set_srgb_intent( false )
|
||||
, _srgb_intent( srgb_intent )
|
||||
|
||||
, _strip_alpha( strip_alpha )
|
||||
|
||||
, _swap_alpha( swap_alpha )
|
||||
{}
|
||||
|
||||
// compression stuff
|
||||
png_compression_type::type _compression_type;
|
||||
png_compression_level::type _compression_level;
|
||||
png_compression_mem_level::type _compression_mem_level;
|
||||
png_compression_strategy::type _compression_strategy;
|
||||
png_compression_window_bits::type _compression_window_bits;
|
||||
png_compression_method::type _compression_method;
|
||||
png_compression_buffer_size::type _compression_buffer_size;
|
||||
|
||||
// png_set_dither
|
||||
bool _set_dithering;
|
||||
png_dithering_palette::type _dithering_palette;
|
||||
png_dithering_num_palette::type _dithering_num_palette;
|
||||
png_dithering_maximum_colors::type _dithering_maximum_colors;
|
||||
png_dithering_histogram::type _dithering_histogram;
|
||||
png_full_dither::type _full_dither;
|
||||
|
||||
//png_set_filter
|
||||
bool _set_filter;
|
||||
png_filter::type _filter;
|
||||
|
||||
// png_set_invert_mono
|
||||
png_invert_mono::type _invert_mono;
|
||||
|
||||
// png_set_sBIT
|
||||
bool _set_true_bits;
|
||||
png_true_bits::type _true_bits;
|
||||
|
||||
// png_set_sRGB
|
||||
bool _set_srgb_intent;
|
||||
png_srgb_intent::type _srgb_intent;
|
||||
|
||||
// png_set_strip_alpha
|
||||
png_strip_alpha::type _strip_alpha;
|
||||
|
||||
// png_set_swap_alpha
|
||||
png_swap_alpha::type _swap_alpha;
|
||||
|
||||
};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
19
linx64/include/boost/gil/extension/io/png/write.hpp
Normal file
19
linx64/include/boost/gil/extension/io/png/write.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright 2007-2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNG_WRITE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNG_WRITE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/png/tags.hpp>
|
||||
#include <boost/gil/extension/io/png/detail/supported_types.hpp>
|
||||
#include <boost/gil/extension/io/png/detail/write.hpp>
|
||||
|
||||
#include <boost/gil/io/make_dynamic_image_writer.hpp>
|
||||
#include <boost/gil/io/make_writer.hpp>
|
||||
#include <boost/gil/io/write_view.hpp>
|
||||
|
||||
#endif
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
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,
|
||||
NULL, 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
|
||||
@@ -1,214 +0,0 @@
|
||||
/*
|
||||
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
|
||||
@@ -1,360 +0,0 @@
|
||||
/*
|
||||
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"
|
||||
#include <png.h>
|
||||
|
||||
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,NULL,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, 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,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,
|
||||
NULL, 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,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
|
||||
14
linx64/include/boost/gil/extension/io/pnm.hpp
Normal file
14
linx64/include/boost/gil/extension/io/pnm.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// Copyright 2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNM_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/read.hpp>
|
||||
#include <boost/gil/extension/io/pnm/write.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// Copyright 2009 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNM_DETAIL_IS_ALLOWED_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_DETAIL_IS_ALLOWED_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/tags.hpp>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
template< typename View >
|
||||
bool is_allowed( const image_read_info< pnm_tag >& info
|
||||
, mpl::true_ // is read_and_no_convert
|
||||
)
|
||||
{
|
||||
pnm_image_type::type asc_type = is_read_supported< typename get_pixel_type< View >::type
|
||||
, pnm_tag
|
||||
>::_asc_type;
|
||||
|
||||
pnm_image_type::type bin_type = is_read_supported< typename get_pixel_type< View >::type
|
||||
, pnm_tag
|
||||
>::_bin_type;
|
||||
if( info._type == pnm_image_type::mono_asc_t::value )
|
||||
{
|
||||
// ascii mono images are read gray8_image_t
|
||||
return ( asc_type == pnm_image_type::gray_asc_t::value );
|
||||
}
|
||||
|
||||
|
||||
return ( asc_type == info._type
|
||||
|| bin_type == info._type
|
||||
);
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
bool is_allowed( const image_read_info< pnm_tag >& /* info */
|
||||
, mpl::false_ // is read_and_convert
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
458
linx64/include/boost/gil/extension/io/pnm/detail/read.hpp
Normal file
458
linx64/include/boost/gil/extension/io/pnm/detail/read.hpp
Normal file
@@ -0,0 +1,458 @@
|
||||
//
|
||||
// Copyright 2012 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNM_DETAIL_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_DETAIL_READ_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/tags.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/reader_backend.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/is_allowed.hpp>
|
||||
|
||||
#include <boost/gil.hpp> // FIXME: Include what you use!
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/bit_operations.hpp>
|
||||
#include <boost/gil/io/conversion_policies.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/dynamic_io_new.hpp>
|
||||
#include <boost/gil/io/reader_base.hpp>
|
||||
#include <boost/gil/io/row_buffer_helper.hpp>
|
||||
#include <boost/gil/io/typedefs.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
///
|
||||
/// PNM Reader
|
||||
///
|
||||
template< typename Device
|
||||
, typename ConversionPolicy
|
||||
>
|
||||
class reader< Device
|
||||
, pnm_tag
|
||||
, ConversionPolicy
|
||||
>
|
||||
: public reader_base< pnm_tag
|
||||
, ConversionPolicy
|
||||
>
|
||||
, public reader_backend< Device
|
||||
, pnm_tag
|
||||
>
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
using this_t = reader<Device, pnm_tag, ConversionPolicy>;
|
||||
using cc_t = typename ConversionPolicy::color_converter_type;
|
||||
|
||||
public:
|
||||
|
||||
using backend_t = reader_backend<Device, pnm_tag>;
|
||||
|
||||
reader( const Device& io_dev
|
||||
, const image_read_settings< pnm_tag >& settings
|
||||
)
|
||||
: reader_base< pnm_tag
|
||||
, ConversionPolicy
|
||||
>()
|
||||
, backend_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
reader( const Device& io_dev
|
||||
, const cc_t& cc
|
||||
, const image_read_settings< pnm_tag >& settings
|
||||
)
|
||||
: reader_base< pnm_tag
|
||||
, ConversionPolicy
|
||||
>( cc )
|
||||
, backend_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
template<typename View>
|
||||
void apply( const View& view )
|
||||
{
|
||||
using is_read_and_convert_t = typename is_same
|
||||
<
|
||||
ConversionPolicy,
|
||||
detail::read_and_no_convert
|
||||
>::type;
|
||||
|
||||
io_error_if( !detail::is_allowed< View >( this->_info
|
||||
, is_read_and_convert_t()
|
||||
)
|
||||
, "Image types aren't compatible."
|
||||
);
|
||||
|
||||
switch( this->_info._type )
|
||||
{
|
||||
// reading mono text is reading grayscale but with only two values
|
||||
case pnm_image_type::mono_asc_t::value:
|
||||
case pnm_image_type::gray_asc_t::value:
|
||||
{
|
||||
this->_scanline_length = this->_info._width;
|
||||
|
||||
read_text_data< gray8_view_t >( view );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case pnm_image_type::color_asc_t::value:
|
||||
{
|
||||
this->_scanline_length = this->_info._width * num_channels< rgb8_view_t >::value;
|
||||
|
||||
read_text_data< rgb8_view_t >( view );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case pnm_image_type::mono_bin_t::value:
|
||||
{
|
||||
//gray1_image_t
|
||||
this->_scanline_length = ( this->_info._width + 7 ) >> 3;
|
||||
|
||||
read_bin_data< gray1_image_t::view_t >( view );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case pnm_image_type::gray_bin_t::value:
|
||||
{
|
||||
// gray8_image_t
|
||||
this->_scanline_length = this->_info._width;
|
||||
|
||||
read_bin_data< gray8_view_t >( view );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case pnm_image_type::color_bin_t::value:
|
||||
{
|
||||
// rgb8_image_t
|
||||
this->_scanline_length = this->_info._width * num_channels< rgb8_view_t >::value;
|
||||
|
||||
read_bin_data< rgb8_view_t >( view );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template< typename View_Src
|
||||
, typename View_Dst
|
||||
>
|
||||
void read_text_data( const View_Dst& dst )
|
||||
{
|
||||
using y_t = typename View_Dst::y_coord_t;
|
||||
|
||||
byte_vector_t row( this->_scanline_length );
|
||||
|
||||
//Skip scanlines if necessary.
|
||||
for( int y = 0; y < this->_settings._top_left.y; ++y )
|
||||
{
|
||||
read_text_row< View_Src >( dst, row, y, false );
|
||||
}
|
||||
|
||||
for( y_t y = 0; y < dst.height(); ++y )
|
||||
{
|
||||
read_text_row< View_Src >( dst, row, y, true );
|
||||
}
|
||||
}
|
||||
|
||||
template< typename View_Src
|
||||
, typename View_Dst
|
||||
>
|
||||
void read_text_row( const View_Dst& dst
|
||||
, byte_vector_t& row
|
||||
, typename View_Dst::y_coord_t y
|
||||
, bool process
|
||||
)
|
||||
{
|
||||
View_Src src = interleaved_view( this->_info._width
|
||||
, 1
|
||||
, (typename View_Src::value_type*) &row.front()
|
||||
, this->_scanline_length
|
||||
);
|
||||
|
||||
for( uint32_t x = 0; x < this->_scanline_length; ++x )
|
||||
{
|
||||
for( uint32_t k = 0; ; )
|
||||
{
|
||||
int ch = this->_io_dev.getc_unchecked();
|
||||
|
||||
if( isdigit( ch ))
|
||||
{
|
||||
buf[ k++ ] = static_cast< char >( ch );
|
||||
}
|
||||
else if( k )
|
||||
{
|
||||
buf[ k ] = 0;
|
||||
break;
|
||||
}
|
||||
else if( ch == EOF || !isspace( ch ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( process )
|
||||
{
|
||||
int value = atoi( buf );
|
||||
|
||||
if( this->_info._max_value == 1 )
|
||||
{
|
||||
using channel_t = typename channel_type<typename get_pixel_type<View_Dst>::type>::type;
|
||||
|
||||
// for pnm format 0 is white
|
||||
row[x] = ( value != 0 )
|
||||
? typename channel_traits< channel_t >::value_type( 0 )
|
||||
: channel_traits< channel_t >::max_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
row[x] = static_cast< byte_t >( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( process )
|
||||
{
|
||||
// We are reading a gray1_image like a gray8_image but the two pixel_t
|
||||
// aren't compatible. Though, read_and_no_convert::read(...) wont work.
|
||||
copy_data< View_Dst
|
||||
, View_Src >( dst
|
||||
, src
|
||||
, y
|
||||
, typename is_same< View_Dst
|
||||
, gray1_image_t::view_t
|
||||
>::type()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
template< typename View_Dst
|
||||
, typename View_Src
|
||||
>
|
||||
void copy_data( const View_Dst& dst
|
||||
, const View_Src& src
|
||||
, typename View_Dst::y_coord_t y
|
||||
, mpl::true_ // is gray1_view
|
||||
)
|
||||
{
|
||||
if( this->_info._max_value == 1 )
|
||||
{
|
||||
typename View_Dst::x_iterator it = dst.row_begin( y );
|
||||
|
||||
for( typename View_Dst::x_coord_t x = 0
|
||||
; x < dst.width()
|
||||
; ++x
|
||||
)
|
||||
{
|
||||
it[x] = src[x];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
copy_data( dst
|
||||
, src
|
||||
, y
|
||||
, mpl::false_()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
template< typename View_Dst
|
||||
, typename View_Src
|
||||
>
|
||||
void copy_data( const View_Dst& view
|
||||
, const View_Src& src
|
||||
, typename View_Dst::y_coord_t y
|
||||
, mpl::false_ // is gray1_view
|
||||
)
|
||||
{
|
||||
typename View_Src::x_iterator beg = src.row_begin( 0 ) + this->_settings._top_left.x;
|
||||
typename View_Src::x_iterator end = beg + this->_settings._dim.x;
|
||||
|
||||
this->_cc_policy.read( beg
|
||||
, end
|
||||
, view.row_begin( y )
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template< typename View_Src
|
||||
, typename View_Dst
|
||||
>
|
||||
void read_bin_data( const View_Dst& view )
|
||||
{
|
||||
using y_t = typename View_Dst::y_coord_t;
|
||||
using is_bit_aligned_t = typename is_bit_aligned<typename View_Src::value_type>::type;
|
||||
|
||||
using rh_t = detail::row_buffer_helper_view<View_Src>;
|
||||
rh_t rh( this->_scanline_length, true );
|
||||
|
||||
typename rh_t::iterator_t beg = rh.begin() + this->_settings._top_left.x;
|
||||
typename rh_t::iterator_t end = beg + this->_settings._dim.x;
|
||||
|
||||
// For bit_aligned images we need to negate all bytes in the row_buffer
|
||||
// to make sure that 0 is black and 255 is white.
|
||||
detail::negate_bits
|
||||
<
|
||||
typename rh_t::buffer_t,
|
||||
std::integral_constant<bool, is_bit_aligned_t::value> // TODO: Simplify after MPL removal
|
||||
> neg;
|
||||
|
||||
detail::swap_half_bytes
|
||||
<
|
||||
typename rh_t::buffer_t,
|
||||
std::integral_constant<bool, is_bit_aligned_t::value> // TODO: Simplify after MPL removal
|
||||
> swhb;
|
||||
|
||||
//Skip scanlines if necessary.
|
||||
for( y_t y = 0; y < this->_settings._top_left.y; ++y )
|
||||
{
|
||||
this->_io_dev.read( reinterpret_cast< byte_t* >( rh.data() )
|
||||
, this->_scanline_length
|
||||
);
|
||||
}
|
||||
|
||||
for( y_t y = 0; y < view.height(); ++y )
|
||||
{
|
||||
this->_io_dev.read( reinterpret_cast< byte_t* >( rh.data() )
|
||||
, this->_scanline_length
|
||||
);
|
||||
|
||||
neg( rh.buffer() );
|
||||
swhb( rh.buffer() );
|
||||
|
||||
this->_cc_policy.read( beg
|
||||
, end
|
||||
, view.row_begin( y )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
char buf[16];
|
||||
|
||||
};
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct pnm_type_format_checker
|
||||
{
|
||||
pnm_type_format_checker( pnm_image_type::type type )
|
||||
: _type( type )
|
||||
{}
|
||||
|
||||
template< typename Image >
|
||||
bool apply()
|
||||
{
|
||||
using is_supported_t = is_read_supported
|
||||
<
|
||||
typename get_pixel_type<typename Image::view_t>::type,
|
||||
pnm_tag
|
||||
>;
|
||||
|
||||
return is_supported_t::_asc_type == _type
|
||||
|| is_supported_t::_bin_type == _type;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
pnm_image_type::type _type;
|
||||
};
|
||||
|
||||
struct pnm_read_is_supported
|
||||
{
|
||||
template< typename View >
|
||||
struct apply : public is_read_supported< typename get_pixel_type< View >::type
|
||||
, pnm_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///
|
||||
/// PNM Dynamic Image Reader
|
||||
///
|
||||
template< typename Device
|
||||
>
|
||||
class dynamic_image_reader< Device
|
||||
, pnm_tag
|
||||
>
|
||||
: public reader< Device
|
||||
, pnm_tag
|
||||
, detail::read_and_no_convert
|
||||
>
|
||||
{
|
||||
using parent_t = reader
|
||||
<
|
||||
Device,
|
||||
pnm_tag,
|
||||
detail::read_and_no_convert
|
||||
>;
|
||||
|
||||
public:
|
||||
|
||||
dynamic_image_reader( const Device& io_dev
|
||||
, const image_read_settings< pnm_tag >& settings
|
||||
)
|
||||
: parent_t( io_dev
|
||||
, settings
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename Images >
|
||||
void apply( any_image< Images >& images )
|
||||
{
|
||||
detail::pnm_type_format_checker format_checker( this->_info._type );
|
||||
|
||||
if( !construct_matched( images
|
||||
, format_checker
|
||||
))
|
||||
{
|
||||
io_error( "No matching image type between those of the given any_image and that of the file" );
|
||||
}
|
||||
else
|
||||
{
|
||||
this->init_image( images
|
||||
, this->_settings
|
||||
);
|
||||
|
||||
detail::dynamic_io_fnobj< detail::pnm_read_is_supported
|
||||
, parent_t
|
||||
> op( this );
|
||||
|
||||
apply_operation( view( images )
|
||||
, op
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // gil
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,181 @@
|
||||
//
|
||||
// Copyright 2012 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNM_DETAIL_READER_BACKEND_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_DETAIL_READER_BACKEND_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/tags.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
///
|
||||
/// PNM Backend
|
||||
///
|
||||
template< typename Device >
|
||||
struct reader_backend< Device
|
||||
, pnm_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using format_tag_t = pnm_tag;
|
||||
|
||||
public:
|
||||
|
||||
reader_backend( const Device& io_dev
|
||||
, const image_read_settings< pnm_tag >& settings
|
||||
)
|
||||
: _io_dev ( io_dev )
|
||||
, _settings( settings )
|
||||
, _info()
|
||||
|
||||
, _scanline_length( 0 )
|
||||
{
|
||||
read_header();
|
||||
|
||||
if( _settings._dim.x == 0 )
|
||||
{
|
||||
_settings._dim.x = _info._width;
|
||||
}
|
||||
|
||||
if( _settings._dim.y == 0 )
|
||||
{
|
||||
_settings._dim.y = _info._height;
|
||||
}
|
||||
}
|
||||
|
||||
void read_header()
|
||||
{
|
||||
// read signature
|
||||
io_error_if( read_char() != 'P', "Invalid PNM signature" );
|
||||
|
||||
_info._type = read_char() - '0';
|
||||
|
||||
io_error_if( _info._type < pnm_image_type::mono_asc_t::value || _info._type > pnm_image_type::color_bin_t::value
|
||||
, "Invalid PNM file (supports P1 to P6)"
|
||||
);
|
||||
|
||||
_info._width = read_int();
|
||||
_info._height = read_int();
|
||||
|
||||
if( _info._type == pnm_image_type::mono_asc_t::value || _info._type == pnm_image_type::mono_bin_t::value )
|
||||
{
|
||||
_info._max_value = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_info._max_value = read_int();
|
||||
|
||||
io_error_if( _info._max_value > 255
|
||||
, "Unsupported PNM format (supports maximum value 255)"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if image is large enough.
|
||||
void check_image_size( const point_t& img_dim )
|
||||
{
|
||||
if( _settings._dim.x > 0 )
|
||||
{
|
||||
if( img_dim.x < _settings._dim.x ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if( img_dim.x < _info._width ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
|
||||
|
||||
if( _settings._dim.y > 0 )
|
||||
{
|
||||
if( img_dim.y < _settings._dim.y ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if( img_dim.y < _info._height ) { io_error( "Supplied image is too small" ); }
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Read a character and skip a comment if necessary.
|
||||
char read_char()
|
||||
{
|
||||
char ch;
|
||||
|
||||
if(( ch = _io_dev.getc() ) == '#' )
|
||||
{
|
||||
// skip comment to EOL
|
||||
do
|
||||
{
|
||||
ch = _io_dev.getc();
|
||||
}
|
||||
while (ch != '\n' && ch != '\r');
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
unsigned int read_int()
|
||||
{
|
||||
char ch;
|
||||
|
||||
// skip whitespaces, tabs, and new lines
|
||||
do
|
||||
{
|
||||
ch = read_char();
|
||||
}
|
||||
while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
|
||||
|
||||
if( ch < '0' || ch > '9' )
|
||||
{
|
||||
io_error( "Unexpected characters reading decimal digits" );
|
||||
}
|
||||
|
||||
unsigned val = 0;
|
||||
|
||||
do
|
||||
{
|
||||
unsigned dig = ch - '0';
|
||||
|
||||
if( val > INT_MAX / 10 - dig )
|
||||
{
|
||||
io_error( "Integer too large" );
|
||||
}
|
||||
|
||||
val = val * 10 + dig;
|
||||
|
||||
ch = read_char();
|
||||
}
|
||||
while( '0' <= ch && ch <= '9' );
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Device _io_dev;
|
||||
|
||||
image_read_settings< pnm_tag > _settings;
|
||||
image_read_info< pnm_tag > _info;
|
||||
|
||||
std::size_t _scanline_length;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,246 @@
|
||||
//
|
||||
// Copyright 2012 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNM_DETAIL_SCANLINE_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_DETAIL_SCANLINE_READ_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/detail/is_allowed.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/reader_backend.hpp>
|
||||
|
||||
#include <boost/gil.hpp> // FIXME: Include what you use!
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/bit_operations.hpp>
|
||||
#include <boost/gil/io/conversion_policies.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/reader_base.hpp>
|
||||
#include <boost/gil/io/row_buffer_helper.hpp>
|
||||
#include <boost/gil/io/scanline_read_iterator.hpp>
|
||||
#include <boost/gil/io/typedefs.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
///
|
||||
/// PNM Reader
|
||||
///
|
||||
template< typename Device >
|
||||
class scanline_reader< Device
|
||||
, pnm_tag
|
||||
>
|
||||
: public reader_backend< Device
|
||||
, pnm_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using tag_t = pnm_tag;
|
||||
using backend_t = reader_backend<Device, tag_t>;
|
||||
using this_t = scanline_reader<Device, tag_t>;
|
||||
using iterator_t = scanline_read_iterator<this_t>;
|
||||
|
||||
public:
|
||||
scanline_reader( Device& device
|
||||
, const image_read_settings< pnm_tag >& settings
|
||||
)
|
||||
: backend_t( device
|
||||
, settings
|
||||
)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
/// Read part of image defined by View and return the data.
|
||||
void read( byte_t* dst
|
||||
, int
|
||||
)
|
||||
{
|
||||
_read_function( this, dst );
|
||||
}
|
||||
|
||||
/// Skip over a scanline.
|
||||
void skip( byte_t*, int )
|
||||
{
|
||||
_skip_function( this );
|
||||
}
|
||||
|
||||
iterator_t begin() { return iterator_t( *this ); }
|
||||
iterator_t end() { return iterator_t( *this, this->_info._height ); }
|
||||
|
||||
private:
|
||||
|
||||
void initialize()
|
||||
{
|
||||
switch( this->_info._type )
|
||||
{
|
||||
// reading mono text is reading grayscale but with only two values
|
||||
case pnm_image_type::mono_asc_t::value:
|
||||
case pnm_image_type::gray_asc_t::value:
|
||||
{
|
||||
this->_scanline_length = this->_info._width;
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_text_row);
|
||||
_skip_function = std::mem_fn(&this_t::skip_text_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case pnm_image_type::color_asc_t::value:
|
||||
{
|
||||
this->_scanline_length = this->_info._width * num_channels< rgb8_view_t >::value;
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_text_row);
|
||||
_skip_function = std::mem_fn(&this_t::skip_text_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case pnm_image_type::mono_bin_t::value:
|
||||
{
|
||||
//gray1_image_t
|
||||
this->_scanline_length = ( this->_info._width + 7 ) >> 3;
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_binary_bit_row);
|
||||
_skip_function = std::mem_fn(&this_t::skip_binary_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case pnm_image_type::gray_bin_t::value:
|
||||
{
|
||||
// gray8_image_t
|
||||
this->_scanline_length = this->_info._width;
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_binary_byte_row);
|
||||
_skip_function = std::mem_fn(&this_t::skip_binary_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case pnm_image_type::color_bin_t::value:
|
||||
{
|
||||
// rgb8_image_t
|
||||
this->_scanline_length = this->_info._width * num_channels< rgb8_view_t >::value;
|
||||
|
||||
_read_function = std::mem_fn(&this_t::read_binary_byte_row);
|
||||
_skip_function = std::mem_fn(&this_t::skip_binary_row);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: { io_error( "Unsupported pnm file." ); break; }
|
||||
}
|
||||
}
|
||||
|
||||
void read_text_row( byte_t* dst )
|
||||
{
|
||||
for( std::size_t x = 0; x < this->_scanline_length; ++x )
|
||||
{
|
||||
for( uint32_t k = 0; ; )
|
||||
{
|
||||
int ch = this->_io_dev.getc_unchecked();
|
||||
|
||||
if( isdigit( ch ))
|
||||
{
|
||||
_text_buffer[ k++ ] = static_cast< char >( ch );
|
||||
}
|
||||
else if( k )
|
||||
{
|
||||
_text_buffer[ k ] = 0;
|
||||
break;
|
||||
}
|
||||
else if( ch == EOF || !isspace( ch ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int value = atoi( _text_buffer );
|
||||
|
||||
if( this->_info._max_value == 1 )
|
||||
{
|
||||
// for pnm format 0 is white
|
||||
dst[x] = ( value != 0 )
|
||||
? 0
|
||||
: 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[x] = static_cast< byte_t >( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void skip_text_row()
|
||||
{
|
||||
for( std::size_t x = 0; x < this->_scanline_length; ++x )
|
||||
{
|
||||
for( uint32_t k = 0; ; )
|
||||
{
|
||||
int ch = this->_io_dev.getc_unchecked();
|
||||
|
||||
if( isdigit( ch ))
|
||||
{
|
||||
k++;
|
||||
}
|
||||
else if( k )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if( ch == EOF || !isspace( ch ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void read_binary_bit_row( byte_t* dst )
|
||||
{
|
||||
this->_io_dev.read( dst
|
||||
, this->_scanline_length
|
||||
);
|
||||
|
||||
_negate_bits ( dst, this->_scanline_length );
|
||||
_swap_half_bytes( dst, this->_scanline_length );
|
||||
|
||||
}
|
||||
|
||||
void read_binary_byte_row( byte_t* dst )
|
||||
{
|
||||
this->_io_dev.read( dst
|
||||
, this->_scanline_length
|
||||
);
|
||||
}
|
||||
|
||||
void skip_binary_row()
|
||||
{
|
||||
this->_io_dev.seek( static_cast<long>( this->_scanline_length ), SEEK_CUR );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
char _text_buffer[16];
|
||||
|
||||
// For bit_aligned images we need to negate all bytes in the row_buffer
|
||||
// to make sure that 0 is black and 255 is white.
|
||||
detail::negate_bits<std::vector<byte_t>, std::true_type> _negate_bits;
|
||||
detail::swap_half_bytes<std::vector<byte_t>, std::true_type> _swap_half_bytes;
|
||||
|
||||
std::function<void(this_t*, byte_t*)> _read_function;
|
||||
std::function<void(this_t*)> _skip_function;
|
||||
};
|
||||
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,139 @@
|
||||
//
|
||||
// Copyright 2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNM_DETAIL_SUPPORTED_TYPES_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_DETAIL_SUPPORTED_TYPES_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/tags.hpp>
|
||||
|
||||
#include <boost/gil/channel.hpp>
|
||||
#include <boost/gil/color_base.hpp>
|
||||
#include <boost/gil/io/base.hpp>
|
||||
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
// Read Support
|
||||
|
||||
template< pnm_image_type::type ASCII_Type
|
||||
, pnm_image_type::type Binary_Type
|
||||
>
|
||||
struct pnm_rw_support_base
|
||||
{
|
||||
static const pnm_image_type::type _asc_type = ASCII_Type;
|
||||
static const pnm_image_type::type _bin_type = Binary_Type;
|
||||
};
|
||||
|
||||
template< typename Channel
|
||||
, typename ColorSpace
|
||||
>
|
||||
struct pnm_read_support : read_support_false
|
||||
, pnm_rw_support_base< 0
|
||||
, 0
|
||||
> {};
|
||||
|
||||
template< typename BitField, bool Mutable >
|
||||
struct pnm_read_support< packed_dynamic_channel_reference< BitField
|
||||
, 1
|
||||
, Mutable
|
||||
>
|
||||
, gray_t
|
||||
> : read_support_true
|
||||
, pnm_rw_support_base< pnm_image_type::mono_asc_t::value
|
||||
, pnm_image_type::mono_bin_t::value
|
||||
> {};
|
||||
|
||||
template<>
|
||||
struct pnm_read_support<uint8_t
|
||||
, gray_t
|
||||
> : read_support_true
|
||||
, pnm_rw_support_base< pnm_image_type::gray_asc_t::value
|
||||
, pnm_image_type::gray_bin_t::value
|
||||
> {};
|
||||
|
||||
|
||||
template<>
|
||||
struct pnm_read_support<uint8_t
|
||||
, rgb_t
|
||||
> : read_support_true
|
||||
, pnm_rw_support_base< pnm_image_type::color_asc_t::value
|
||||
, pnm_image_type::color_bin_t::value
|
||||
> {};
|
||||
|
||||
// Write support
|
||||
|
||||
template< typename Channel
|
||||
, typename ColorSpace
|
||||
>
|
||||
struct pnm_write_support : write_support_false
|
||||
{};
|
||||
|
||||
template< typename BitField, bool Mutable >
|
||||
struct pnm_write_support< packed_dynamic_channel_reference< BitField
|
||||
, 1
|
||||
, Mutable
|
||||
>
|
||||
, gray_t
|
||||
> : write_support_true
|
||||
, pnm_rw_support_base< pnm_image_type::mono_asc_t::value
|
||||
, pnm_image_type::mono_bin_t::value
|
||||
> {};
|
||||
|
||||
|
||||
template<>
|
||||
struct pnm_write_support<uint8_t
|
||||
, gray_t
|
||||
> : write_support_true
|
||||
, pnm_rw_support_base< pnm_image_type::gray_asc_t::value
|
||||
, pnm_image_type::gray_bin_t::value
|
||||
> {};
|
||||
|
||||
|
||||
template<>
|
||||
struct pnm_write_support<uint8_t
|
||||
, rgb_t
|
||||
> : write_support_true
|
||||
, pnm_rw_support_base< pnm_image_type::color_asc_t::value
|
||||
, pnm_image_type::color_bin_t::value
|
||||
> {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template< typename Pixel >
|
||||
struct is_read_supported< Pixel
|
||||
, pnm_tag
|
||||
>
|
||||
: mpl::bool_< detail::pnm_read_support< typename channel_type < Pixel >::type
|
||||
, typename color_space_type< Pixel >::type
|
||||
>::is_supported
|
||||
>
|
||||
{
|
||||
using parent_t = detail::pnm_read_support
|
||||
<
|
||||
typename channel_type<Pixel>::type,
|
||||
typename color_space_type<Pixel>::type
|
||||
>;
|
||||
|
||||
static const pnm_image_type::type _asc_type = parent_t::_asc_type;
|
||||
static const pnm_image_type::type _bin_type = parent_t::_bin_type;
|
||||
};
|
||||
|
||||
template< typename Pixel >
|
||||
struct is_write_supported< Pixel
|
||||
, pnm_tag
|
||||
>
|
||||
: mpl::bool_< detail::pnm_write_support< typename channel_type < Pixel >::type
|
||||
, typename color_space_type< Pixel >::type
|
||||
>::is_supported
|
||||
> {};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
241
linx64/include/boost/gil/extension/io/pnm/detail/write.hpp
Normal file
241
linx64/include/boost/gil/extension/io/pnm/detail/write.hpp
Normal file
@@ -0,0 +1,241 @@
|
||||
//
|
||||
// Copyright 2012 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNM_DETAIL_WRITE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_DETAIL_WRITE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/tags.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/writer_backend.hpp>
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/bit_operations.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
#include <boost/gil/io/dynamic_io_new.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct pnm_write_is_supported
|
||||
{
|
||||
template< typename View >
|
||||
struct apply
|
||||
: public is_write_supported< typename get_pixel_type< View >::type
|
||||
, pnm_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///
|
||||
/// PNM Writer
|
||||
///
|
||||
template< typename Device >
|
||||
class writer< Device
|
||||
, pnm_tag
|
||||
>
|
||||
: public writer_backend< Device
|
||||
, pnm_tag
|
||||
>
|
||||
{
|
||||
private:
|
||||
using backend_t = writer_backend<Device, pnm_tag>;
|
||||
|
||||
public:
|
||||
|
||||
writer( const Device& io_dev
|
||||
, const image_write_info< pnm_tag >& info
|
||||
)
|
||||
: backend_t( io_dev
|
||||
, info
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename View >
|
||||
void apply( const View& view )
|
||||
{
|
||||
using pixel_t = typename get_pixel_type<View>::type;
|
||||
|
||||
std::size_t width = view.width();
|
||||
std::size_t height = view.height();
|
||||
|
||||
std::size_t chn = num_channels< View >::value;
|
||||
std::size_t pitch = chn * width;
|
||||
|
||||
unsigned int type = get_type< num_channels< View >::value >( is_bit_aligned< pixel_t >() );
|
||||
|
||||
// write header
|
||||
|
||||
// Add a white space at each string so read_int() can decide when a numbers ends.
|
||||
|
||||
std::string str( "P" );
|
||||
str += std::to_string( type ) + std::string( " " );
|
||||
this->_io_dev.print_line( str );
|
||||
|
||||
str.clear();
|
||||
str += std::to_string( width ) + std::string( " " );
|
||||
this->_io_dev.print_line( str );
|
||||
|
||||
str.clear();
|
||||
str += std::to_string( height ) + std::string( " " );
|
||||
this->_io_dev.print_line( str );
|
||||
|
||||
if( type != pnm_image_type::mono_bin_t::value )
|
||||
{
|
||||
this->_io_dev.print_line( "255 ");
|
||||
}
|
||||
|
||||
// write data
|
||||
write_data( view
|
||||
, pitch
|
||||
, typename is_bit_aligned< pixel_t >::type()
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template< int Channels >
|
||||
unsigned int get_type( mpl::true_ /* is_bit_aligned */ )
|
||||
{
|
||||
return boost::mpl::if_c< Channels == 1
|
||||
, pnm_image_type::mono_bin_t
|
||||
, pnm_image_type::color_bin_t
|
||||
>::type::value;
|
||||
}
|
||||
|
||||
template< int Channels >
|
||||
unsigned int get_type( mpl::false_ /* is_bit_aligned */ )
|
||||
{
|
||||
return boost::mpl::if_c< Channels == 1
|
||||
, pnm_image_type::gray_bin_t
|
||||
, pnm_image_type::color_bin_t
|
||||
>::type::value;
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
void write_data( const View& src
|
||||
, std::size_t pitch
|
||||
, const mpl::true_& // bit_aligned
|
||||
)
|
||||
{
|
||||
static_assert(is_same<View, typename gray1_image_t::view_t>::value, "");
|
||||
|
||||
byte_vector_t row( pitch / 8 );
|
||||
|
||||
using x_it_t = typename View::x_iterator;
|
||||
x_it_t row_it = x_it_t( &( *row.begin() ));
|
||||
|
||||
detail::negate_bits<byte_vector_t, std::true_type> negate;
|
||||
detail::mirror_bits<byte_vector_t, std::true_type> mirror;
|
||||
for (typename View::y_coord_t y = 0; y < src.height(); ++y)
|
||||
{
|
||||
std::copy(src.row_begin(y), src.row_end(y), row_it);
|
||||
|
||||
mirror(row);
|
||||
negate(row);
|
||||
|
||||
this->_io_dev.write(&row.front(), pitch / 8);
|
||||
}
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
void write_data( const View& src
|
||||
, std::size_t pitch
|
||||
, const mpl::false_& // bit_aligned
|
||||
)
|
||||
{
|
||||
std::vector< pixel< typename channel_type< View >::type
|
||||
, layout<typename color_space_type< View >::type >
|
||||
>
|
||||
> buf( src.width() );
|
||||
|
||||
// using pixel_t = typename View::value_type;
|
||||
// using view_t = typename view_type_from_pixel< pixel_t >::type;
|
||||
|
||||
//view_t row = interleaved_view( src.width()
|
||||
// , 1
|
||||
// , reinterpret_cast< pixel_t* >( &buf.front() )
|
||||
// , pitch
|
||||
// );
|
||||
|
||||
byte_t* row_addr = reinterpret_cast< byte_t* >( &buf.front() );
|
||||
|
||||
for( typename View::y_coord_t y = 0
|
||||
; y < src.height()
|
||||
; ++y
|
||||
)
|
||||
{
|
||||
//copy_pixels( subimage_view( src
|
||||
// , 0
|
||||
// , (int) y
|
||||
// , (int) src.width()
|
||||
// , 1
|
||||
// )
|
||||
// , row
|
||||
// );
|
||||
|
||||
std::copy( src.row_begin( y )
|
||||
, src.row_end ( y )
|
||||
, buf.begin()
|
||||
);
|
||||
|
||||
this->_io_dev.write( row_addr, pitch );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// PNM Writer
|
||||
///
|
||||
template< typename Device >
|
||||
class dynamic_image_writer< Device
|
||||
, pnm_tag
|
||||
>
|
||||
: public writer< Device
|
||||
, pnm_tag
|
||||
>
|
||||
{
|
||||
using parent_t = writer<Device, pnm_tag>;
|
||||
|
||||
public:
|
||||
|
||||
dynamic_image_writer( const Device& io_dev
|
||||
, const image_write_info< pnm_tag >& info
|
||||
)
|
||||
: parent_t( io_dev
|
||||
, info
|
||||
)
|
||||
{}
|
||||
|
||||
template< typename Views >
|
||||
void apply( const any_image_view< Views >& views )
|
||||
{
|
||||
detail::dynamic_io_fnobj< detail::pnm_write_is_supported
|
||||
, parent_t
|
||||
> op( this );
|
||||
|
||||
apply_operation( views, op );
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // gil
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// Copyright 2012 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNM_DETAIL_WRITER_BACKEND_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_DETAIL_WRITER_BACKEND_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/tags.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
///
|
||||
/// PNM Writer Backend
|
||||
///
|
||||
template< typename Device >
|
||||
struct writer_backend< Device
|
||||
, pnm_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
|
||||
using format_tag_t = pnm_tag;
|
||||
|
||||
public:
|
||||
|
||||
writer_backend( const Device& io_dev
|
||||
, const image_write_info< pnm_tag >& info
|
||||
)
|
||||
: _io_dev( io_dev )
|
||||
, _info( info )
|
||||
{}
|
||||
|
||||
public:
|
||||
|
||||
Device _io_dev;
|
||||
|
||||
image_write_info< pnm_tag > _info;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
160
linx64/include/boost/gil/extension/io/pnm/old.hpp
Normal file
160
linx64/include/boost/gil/extension/io/pnm/old.hpp
Normal file
@@ -0,0 +1,160 @@
|
||||
//
|
||||
// Copyright 2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNM_OLD_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_OLD_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// \ingroup PNM_IO
|
||||
/// \brief Returns the width and height of the PNM file at the specified location.
|
||||
/// Throws std::ios_base::failure if the location does not correspond to a valid PNM file
|
||||
template<typename String>
|
||||
inline point_t pnm_read_dimensions(String const& filename)
|
||||
{
|
||||
using backend_t = typename get_reader_backend<String, pnm_tag>::type;
|
||||
backend_t backend = read_image_info(filename, pnm_tag());
|
||||
return { backend._info._width, backend._info._height };
|
||||
}
|
||||
|
||||
/// \ingroup PNM_IO
|
||||
/// \brief Loads the image specified by the given pnm image file name into the given view.
|
||||
/// Triggers a compile assert if the view color space and channel depth are not supported by the PNM library or by the I/O extension.
|
||||
/// Throws std::ios_base::failure if the file is not a valid PNM 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 String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void pnm_read_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
read_view( filename
|
||||
, view
|
||||
, pnm_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup PNM_IO
|
||||
/// \brief Allocates a new image whose dimensions are determined by the given pnm 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 PNM library or by the I/O extension.
|
||||
/// Throws std::ios_base::failure if the file is not a valid PNM file, or if its color space or channel depth are not
|
||||
/// compatible with the ones specified by Image
|
||||
template< typename String
|
||||
, typename Image
|
||||
>
|
||||
inline
|
||||
void pnm_read_image( const String& filename
|
||||
, Image& img
|
||||
)
|
||||
{
|
||||
read_image( filename
|
||||
, img
|
||||
, pnm_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup PNM_IO
|
||||
/// \brief Loads and color-converts the image specified by the given pnm image file name into the given view.
|
||||
/// Throws std::ios_base::failure if the file is not a valid PNM file, or if its dimensions don't match the ones of the view.
|
||||
template< typename String
|
||||
, typename View
|
||||
, typename CC
|
||||
>
|
||||
inline
|
||||
void pnm_read_and_convert_view( const String& filename
|
||||
, const View& view
|
||||
, CC cc
|
||||
)
|
||||
{
|
||||
read_and_convert_view( filename
|
||||
, view
|
||||
, cc
|
||||
, pnm_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup PNM_IO
|
||||
/// \brief Loads and color-converts the image specified by the given pnm image file name into the given view.
|
||||
/// Throws std::ios_base::failure if the file is not a valid PNM file, or if its dimensions don't match the ones of the view.
|
||||
template< typename String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void pnm_read_and_convert_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
read_and_convert_view( filename
|
||||
, view
|
||||
, pnm_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup PNM_IO
|
||||
/// \brief Allocates a new image whose dimensions are determined by the given pnm image file, loads and color-converts the pixels into it.
|
||||
/// Throws std::ios_base::failure if the file is not a valid PNM file
|
||||
template< typename String
|
||||
, typename Image
|
||||
, typename CC
|
||||
>
|
||||
inline
|
||||
void pnm_read_and_convert_image( const String& filename
|
||||
, Image& img
|
||||
, CC cc
|
||||
)
|
||||
{
|
||||
read_and_convert_image( filename
|
||||
, img
|
||||
, cc
|
||||
, pnm_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/// \ingroup PNM_IO
|
||||
/// \brief Allocates a new image whose dimensions are determined by the given pnm image file, loads and color-converts the pixels into it.
|
||||
/// Throws std::ios_base::failure if the file is not a valid PNM file
|
||||
template< typename String
|
||||
, typename Image
|
||||
>
|
||||
inline
|
||||
void pnm_read_and_convert_image( const String filename
|
||||
, Image& img
|
||||
)
|
||||
{
|
||||
read_and_convert_image( filename
|
||||
, img
|
||||
, pnm_tag()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/// \ingroup PNM_IO
|
||||
/// \brief Saves the view to a pnm file specified by the given pnm image file name.
|
||||
/// Triggers a compile assert if the view color space and channel depth are not supported by the PNM library or by the I/O extension.
|
||||
/// Throws std::ios_base::failure if it fails to create the file.
|
||||
template< typename String
|
||||
, typename View
|
||||
>
|
||||
inline
|
||||
void pnm_write_view( const String& filename
|
||||
, const View& view
|
||||
)
|
||||
{
|
||||
write_view( filename
|
||||
, view
|
||||
, pnm_tag()
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
28
linx64/include/boost/gil/extension/io/pnm/read.hpp
Normal file
28
linx64/include/boost/gil/extension/io/pnm/read.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Copyright 2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNM_READ_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_READ_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/tags.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/supported_types.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/read.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/scanline_read.hpp>
|
||||
|
||||
#include <boost/gil/io/get_reader.hpp>
|
||||
#include <boost/gil/io/make_backend.hpp>
|
||||
#include <boost/gil/io/make_dynamic_image_reader.hpp>
|
||||
#include <boost/gil/io/make_reader.hpp>
|
||||
#include <boost/gil/io/make_scanline_reader.hpp>
|
||||
#include <boost/gil/io/read_and_convert_image.hpp>
|
||||
#include <boost/gil/io/read_and_convert_view.hpp>
|
||||
#include <boost/gil/io/read_image.hpp>
|
||||
#include <boost/gil/io/read_image_info.hpp>
|
||||
#include <boost/gil/io/read_view.hpp>
|
||||
#include <boost/gil/io/scanline_read_iterator.hpp>
|
||||
|
||||
#endif
|
||||
95
linx64/include/boost/gil/extension/io/pnm/tags.hpp
Normal file
95
linx64/include/boost/gil/extension/io/pnm/tags.hpp
Normal file
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// Copyright 2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNM_TAGS_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_TAGS_HPP
|
||||
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_READ_ENABLED // TODO: Document, explain, review
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
|
||||
#include <boost/mpl/integral_c.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
/// Defines pnm tag.
|
||||
struct pnm_tag : format_tag {};
|
||||
|
||||
/// see http://en.wikipedia.org/wiki/Portable_Bitmap_File_Format for reference
|
||||
|
||||
/// Defines type for image type property.
|
||||
struct pnm_image_type : property_base< uint32_t >
|
||||
{
|
||||
using mono_asc_t = boost::mpl::integral_c<type, 1>;
|
||||
using gray_asc_t = boost::mpl::integral_c<type, 2>;
|
||||
using color_asc_t = boost::mpl::integral_c<type, 3>;
|
||||
|
||||
using mono_bin_t = boost::mpl::integral_c<type, 4>;
|
||||
using gray_bin_t = boost::mpl::integral_c<type, 5>;
|
||||
using color_bin_t = boost::mpl::integral_c<type, 6>;
|
||||
};
|
||||
|
||||
/// Defines type for image width property.
|
||||
struct pnm_image_width : property_base< uint32_t > {};
|
||||
|
||||
/// Defines type for image height property.
|
||||
struct pnm_image_height : property_base< uint32_t > {};
|
||||
|
||||
/// Defines type for image max value property.
|
||||
struct pnm_image_max_value : property_base< uint32_t > {};
|
||||
|
||||
/// Read information for pnm images.
|
||||
///
|
||||
/// The structure is returned when using read_image_info.
|
||||
template<>
|
||||
struct image_read_info< pnm_tag >
|
||||
{
|
||||
/// The image type.
|
||||
pnm_image_type::type _type;
|
||||
/// The image width.
|
||||
pnm_image_width::type _width;
|
||||
/// The image height.
|
||||
pnm_image_height::type _height;
|
||||
/// The image max value.
|
||||
pnm_image_max_value::type _max_value;
|
||||
};
|
||||
|
||||
/// Read settings for pnm images.
|
||||
///
|
||||
/// The structure can be used for all read_xxx functions, except read_image_info.
|
||||
template<>
|
||||
struct image_read_settings< pnm_tag > : public image_read_settings_base
|
||||
{
|
||||
/// Default constructor
|
||||
image_read_settings< pnm_tag >()
|
||||
: image_read_settings_base()
|
||||
{}
|
||||
|
||||
/// Constructor
|
||||
/// \param top_left Top left coordinate for reading partial image.
|
||||
/// \param dim Dimensions for reading partial image.
|
||||
image_read_settings( const point_t& top_left
|
||||
, const point_t& dim
|
||||
)
|
||||
: image_read_settings_base( top_left
|
||||
, dim
|
||||
)
|
||||
{}
|
||||
};
|
||||
|
||||
/// Write information for pnm images.
|
||||
///
|
||||
/// The structure can be used for write_view() function.
|
||||
template<>
|
||||
struct image_write_info< pnm_tag >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
19
linx64/include/boost/gil/extension/io/pnm/write.hpp
Normal file
19
linx64/include/boost/gil/extension/io/pnm/write.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright 2008 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_PNM_WRITE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_PNM_WRITE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/pnm/tags.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/supported_types.hpp>
|
||||
#include <boost/gil/extension/io/pnm/detail/write.hpp>
|
||||
|
||||
#include <boost/gil/io/make_dynamic_image_writer.hpp>
|
||||
#include <boost/gil/io/make_writer.hpp>
|
||||
#include <boost/gil/io/write_view.hpp>
|
||||
|
||||
#endif
|
||||
13
linx64/include/boost/gil/extension/io/raw.hpp
Normal file
13
linx64/include/boost/gil/extension/io/raw.hpp
Normal file
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// Copyright 2013 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_RAW_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_RAW_HPP
|
||||
|
||||
#include <boost/gil/extension/io/raw/read.hpp>
|
||||
|
||||
#endif
|
||||
134
linx64/include/boost/gil/extension/io/raw/detail/device.hpp
Normal file
134
linx64/include/boost/gil/extension/io/raw/detail/device.hpp
Normal file
@@ -0,0 +1,134 @@
|
||||
//
|
||||
// Copyright 2012 Olivier Tournaire
|
||||
// Copyright 2007 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_RAW_DETAIL_DEVICE_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_RAW_DETAIL_DEVICE_HPP
|
||||
|
||||
#include <boost/gil/extension/io/raw/tags.hpp>
|
||||
|
||||
#include <boost/gil/io/base.hpp>
|
||||
#include <boost/gil/io/device.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
class raw_device_base
|
||||
{
|
||||
public:
|
||||
|
||||
///
|
||||
/// Constructor
|
||||
///
|
||||
raw_device_base()
|
||||
: _processor_ptr( new LibRaw )
|
||||
{}
|
||||
|
||||
// iparams getters
|
||||
std::string get_camera_manufacturer() { return std::string(_processor_ptr.get()->imgdata.idata.make); }
|
||||
std::string get_camera_model() { return std::string(_processor_ptr.get()->imgdata.idata.model); }
|
||||
unsigned get_raw_count() { return _processor_ptr.get()->imgdata.idata.raw_count; }
|
||||
unsigned get_dng_version() { return _processor_ptr.get()->imgdata.idata.dng_version; }
|
||||
int get_colors() { return _processor_ptr.get()->imgdata.idata.colors; }
|
||||
unsigned get_filters() { return _processor_ptr.get()->imgdata.idata.filters; }
|
||||
std::string get_cdesc() { return std::string(_processor_ptr.get()->imgdata.idata.cdesc); }
|
||||
|
||||
// image_sizes getters
|
||||
unsigned short get_raw_width() { return _processor_ptr.get()->imgdata.sizes.raw_width; }
|
||||
unsigned short get_raw_height() { return _processor_ptr.get()->imgdata.sizes.raw_height; }
|
||||
unsigned short get_image_width() { return _processor_ptr.get()->imgdata.sizes.width; }
|
||||
unsigned short get_image_height() { return _processor_ptr.get()->imgdata.sizes.height; }
|
||||
unsigned short get_top_margin() { return _processor_ptr.get()->imgdata.sizes.top_margin; }
|
||||
unsigned short get_left_margin() { return _processor_ptr.get()->imgdata.sizes.left_margin; }
|
||||
unsigned short get_iwidth() { return _processor_ptr.get()->imgdata.sizes.iwidth; }
|
||||
unsigned short get_iheight() { return _processor_ptr.get()->imgdata.sizes.iheight; }
|
||||
double get_pixel_aspect() { return _processor_ptr.get()->imgdata.sizes.pixel_aspect; }
|
||||
int get_flip() { return _processor_ptr.get()->imgdata.sizes.flip; }
|
||||
|
||||
// colordata getters
|
||||
// TODO
|
||||
|
||||
// imgother getters
|
||||
float get_iso_speed() { return _processor_ptr.get()->imgdata.other.iso_speed; }
|
||||
float get_shutter() { return _processor_ptr.get()->imgdata.other.shutter; }
|
||||
float get_aperture() { return _processor_ptr.get()->imgdata.other.aperture; }
|
||||
float get_focal_len() { return _processor_ptr.get()->imgdata.other.focal_len; }
|
||||
time_t get_timestamp() { return _processor_ptr.get()->imgdata.other.timestamp; }
|
||||
unsigned int get_shot_order() { return _processor_ptr.get()->imgdata.other.shot_order; }
|
||||
unsigned* get_gpsdata() { return _processor_ptr.get()->imgdata.other.gpsdata; }
|
||||
std::string get_desc() { return std::string(_processor_ptr.get()->imgdata.other.desc); }
|
||||
std::string get_artist() { return std::string(_processor_ptr.get()->imgdata.other.artist); }
|
||||
|
||||
std::string get_version() { return std::string(_processor_ptr.get()->version()); }
|
||||
std::string get_unpack_function_name() { return std::string(_processor_ptr.get()->unpack_function_name()); }
|
||||
|
||||
void get_mem_image_format(int *widthp, int *heightp, int *colorsp, int *bpp) { _processor_ptr.get()->get_mem_image_format(widthp, heightp, colorsp, bpp); }
|
||||
|
||||
int unpack() { return _processor_ptr.get()->unpack(); }
|
||||
int dcraw_process() { return _processor_ptr.get()->dcraw_process(); }
|
||||
libraw_processed_image_t* dcraw_make_mem_image(int* error_code=nullptr) { return _processor_ptr.get()->dcraw_make_mem_image(error_code); }
|
||||
|
||||
protected:
|
||||
|
||||
using libraw_ptr_t = std::shared_ptr<LibRaw>;
|
||||
libraw_ptr_t _processor_ptr;
|
||||
};
|
||||
|
||||
/*!
|
||||
*
|
||||
* file_stream_device specialization for raw images
|
||||
*/
|
||||
template<>
|
||||
class file_stream_device< raw_tag > : public raw_device_base
|
||||
{
|
||||
public:
|
||||
|
||||
struct read_tag {};
|
||||
|
||||
///
|
||||
/// Constructor
|
||||
///
|
||||
file_stream_device( std::string const& file_name
|
||||
, read_tag = read_tag()
|
||||
)
|
||||
{
|
||||
io_error_if( _processor_ptr.get()->open_file( file_name.c_str() ) != LIBRAW_SUCCESS
|
||||
, "file_stream_device: failed to open file"
|
||||
);
|
||||
}
|
||||
|
||||
///
|
||||
/// Constructor
|
||||
///
|
||||
file_stream_device( const char* file_name
|
||||
, read_tag = read_tag()
|
||||
)
|
||||
{
|
||||
io_error_if( _processor_ptr.get()->open_file( file_name ) != LIBRAW_SUCCESS
|
||||
, "file_stream_device: failed to open file"
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename FormatTag >
|
||||
struct is_adaptable_input_device< FormatTag
|
||||
, LibRaw
|
||||
, void
|
||||
>
|
||||
: mpl::true_
|
||||
{
|
||||
using device_type = file_stream_device<FormatTag>;
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// Copyright 2009 Christian Henning
|
||||
//
|
||||
// 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_GIL_EXTENSION_IO_RAW_DETAIL_IS_ALLOWED_HPP
|
||||
#define BOOST_GIL_EXTENSION_IO_RAW_DETAIL_IS_ALLOWED_HPP
|
||||
|
||||
#include <boost/gil/extension/io/raw/tags.hpp>
|
||||
#include <boost/gil/io/base.hpp>
|
||||
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
template< typename View >
|
||||
bool is_allowed( const image_read_info< raw_tag >& info
|
||||
, mpl::true_ // is read_and_no_convert
|
||||
)
|
||||
{
|
||||
using pixel_t = typename get_pixel_type<View>::type;
|
||||
using num_channel_t = typename num_channels<pixel_t>::value_type;
|
||||
using channel_t = typename channel_traits<typename element_type<typename View::value_type>::type>::value_type;
|
||||
|
||||
const num_channel_t dst_samples_per_pixel = num_channels< pixel_t >::value;
|
||||
const unsigned int dst_bits_per_pixel = detail::unsigned_integral_num_bits< channel_t >::value;
|
||||
const bool is_type_signed = boost::is_signed< channel_t >::value;
|
||||
|
||||
return( dst_samples_per_pixel == info._samples_per_pixel &&
|
||||
dst_bits_per_pixel == static_cast<unsigned int>(info._bits_per_pixel) &&
|
||||
!is_type_signed );
|
||||
}
|
||||
|
||||
template< typename View >
|
||||
bool is_allowed( const image_read_info< raw_tag >& /* info */
|
||||
, mpl::false_ // is read_and_convert
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace gil
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user