mirror of
https://github.com/boostorg/gil.git
synced 2026-01-19 04:12:11 +00:00
refactor: Switch to trailing return types (#599)
- Trailing return types everywhere - Optionally, return type deduction where sensible (simple and short functions) This is related to introduction of common .clang-format, see https://github.com/boostorg/gil/pull/596#issuecomment-822681523
This commit is contained in:
@@ -89,22 +89,22 @@ struct binary_operation_obj
|
||||
using result_type = Result;
|
||||
|
||||
template <typename V1, typename V2> BOOST_FORCEINLINE
|
||||
result_type operator()(const std::pair<const V1*,const V2*>& p) const {
|
||||
auto operator()(const std::pair<const V1*,const V2*>& p) const -> result_type {
|
||||
return apply(*p.first, *p.second, typename views_are_compatible<V1,V2>::type());
|
||||
}
|
||||
|
||||
template <typename V1, typename V2> BOOST_FORCEINLINE
|
||||
result_type operator()(const V1& v1, const V2& v2) const {
|
||||
auto operator()(const V1& v1, const V2& v2) const -> result_type {
|
||||
return apply(v1, v2, typename views_are_compatible<V1,V2>::type());
|
||||
}
|
||||
|
||||
result_type operator()(const error_t&) const { throw std::bad_cast(); }
|
||||
auto operator()(const error_t&) const -> result_type { throw std::bad_cast(); }
|
||||
private:
|
||||
|
||||
// dispatch from apply overload to a function with distinct name
|
||||
template <typename V1, typename V2>
|
||||
BOOST_FORCEINLINE
|
||||
result_type apply(V1 const& v1, V2 const& v2, std::false_type) const
|
||||
auto apply(V1 const& v1, V2 const& v2, std::false_type) const -> result_type
|
||||
{
|
||||
return ((const Derived*)this)->apply_incompatible(v1, v2);
|
||||
}
|
||||
@@ -112,7 +112,7 @@ private:
|
||||
// dispatch from apply overload to a function with distinct name
|
||||
template <typename V1, typename V2>
|
||||
BOOST_FORCEINLINE
|
||||
result_type apply(V1 const& v1, V2 const& v2, std::true_type) const
|
||||
auto apply(V1 const& v1, V2 const& v2, std::true_type) const -> result_type
|
||||
{
|
||||
return ((const Derived*)this)->apply_compatible(v1, v2);
|
||||
}
|
||||
@@ -120,7 +120,7 @@ private:
|
||||
// function with distinct name - it can be overloaded by subclasses
|
||||
template <typename V1, typename V2>
|
||||
BOOST_FORCEINLINE
|
||||
result_type apply_incompatible(V1 const& /*v1*/, V2 const& /*v2*/) const
|
||||
auto apply_incompatible(V1 const& /*v1*/, V2 const& /*v2*/) const -> result_type
|
||||
{
|
||||
throw std::bad_cast();
|
||||
}
|
||||
@@ -155,9 +155,10 @@ auto copy(
|
||||
/// \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>
|
||||
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) {
|
||||
BOOST_FORCEINLINE
|
||||
auto copy(const boost::gil::pixel<T,CS>* first, const boost::gil::pixel<T,CS>* last,
|
||||
boost::gil::pixel<T,CS>* dst) -> boost::gil::pixel<T,CS>*
|
||||
{
|
||||
return (boost::gil::pixel<T,CS>*)std::copy((unsigned char*)first,(unsigned char*)last, (unsigned char*)dst);
|
||||
}
|
||||
} // namespace std
|
||||
@@ -174,7 +175,8 @@ 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> 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) {
|
||||
auto 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::planar_pixel_iterator<IC2,CS>
|
||||
{
|
||||
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);
|
||||
@@ -250,7 +252,7 @@ struct copier_n<iterator_from_2d<IL>,iterator_from_2d<OL>> {
|
||||
};
|
||||
|
||||
template <typename SrcIterator, typename DstIterator>
|
||||
BOOST_FORCEINLINE DstIterator copy_with_2d_iterators(SrcIterator first, SrcIterator last, DstIterator dst) {
|
||||
BOOST_FORCEINLINE auto copy_with_2d_iterators(SrcIterator first, SrcIterator last, DstIterator dst) -> DstIterator {
|
||||
using src_x_iterator = typename SrcIterator::x_iterator;
|
||||
using dst_x_iterator = typename DstIterator::x_iterator;
|
||||
|
||||
@@ -276,9 +278,11 @@ namespace std {
|
||||
/// \ingroup STLOptimizations
|
||||
/// \brief std::copy(I1,I1,I2) with I1 and I2 being a iterator_from_2d
|
||||
template <typename IL, typename OL>
|
||||
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) {
|
||||
BOOST_FORCEINLINE auto copy1(boost::gil::iterator_from_2d<IL> first, boost::gil::iterator_from_2d<IL> last, boost::gil::iterator_from_2d<OL> dst) -> boost::gil::iterator_from_2d<OL>
|
||||
{
|
||||
return boost::gil::detail::copy_with_2d_iterators(first,last,dst);
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
|
||||
namespace boost { namespace gil {
|
||||
@@ -313,13 +317,13 @@ public:
|
||||
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> BOOST_FORCEINLINE
|
||||
result_type apply_incompatible(const V1& src, const V2& dst) const {
|
||||
auto apply_incompatible(const V1& src, const V2& dst) const -> result_type {
|
||||
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> BOOST_FORCEINLINE
|
||||
result_type apply_compatible(const V1& src, const V2& dst) const {
|
||||
auto apply_compatible(const V1& src, const V2& dst) const -> result_type {
|
||||
copy_pixels(src,dst);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -63,22 +63,22 @@ public:
|
||||
|
||||
/// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference
|
||||
/// We require our own reference because it is registered in iterator_traits
|
||||
reference operator[](difference_type d) const { bit_aligned_pixel_iterator it=*this; it.advance(d); return *it; }
|
||||
auto operator[](difference_type d) const -> reference { bit_aligned_pixel_iterator it=*this; it.advance(d); return *it; }
|
||||
|
||||
reference operator->() const { return **this; }
|
||||
const bit_range_t& bit_range() const { return _bit_range; }
|
||||
bit_range_t& bit_range() { return _bit_range; }
|
||||
auto operator->() const -> reference { return **this; }
|
||||
auto bit_range() const -> bit_range_t const& { return _bit_range; }
|
||||
auto bit_range() -> bit_range_t& { return _bit_range; }
|
||||
private:
|
||||
bit_range_t _bit_range;
|
||||
static constexpr int bit_size = NonAlignedPixelReference::bit_size;
|
||||
|
||||
friend class boost::iterator_core_access;
|
||||
reference dereference() const { return NonAlignedPixelReference(_bit_range); }
|
||||
auto dereference() const -> reference { return NonAlignedPixelReference(_bit_range); }
|
||||
void increment() { ++_bit_range; }
|
||||
void decrement() { --_bit_range; }
|
||||
void advance(difference_type d) { _bit_range.bit_advance(d*bit_size); }
|
||||
|
||||
difference_type distance_to(const bit_aligned_pixel_iterator& it) const { return _bit_range.bit_distance_to(it._bit_range) / bit_size; }
|
||||
auto distance_to(bit_aligned_pixel_iterator const& it) const -> difference_type { return _bit_range.bit_distance_to(it._bit_range) / bit_size; }
|
||||
bool equal(const bit_aligned_pixel_iterator& it) const { return _bit_range==it._bit_range; }
|
||||
};
|
||||
|
||||
@@ -122,12 +122,14 @@ struct byte_to_memunit<bit_aligned_pixel_iterator<NonAlignedPixelReference>>
|
||||
{};
|
||||
|
||||
template <typename NonAlignedPixelReference>
|
||||
inline std::ptrdiff_t memunit_step(const bit_aligned_pixel_iterator<NonAlignedPixelReference>&) {
|
||||
inline auto memunit_step(const bit_aligned_pixel_iterator<NonAlignedPixelReference>&) -> std::ptrdiff_t
|
||||
{
|
||||
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) {
|
||||
inline auto memunit_distance(bit_aligned_pixel_iterator<NonAlignedPixelReference> const& p1, bit_aligned_pixel_iterator<NonAlignedPixelReference> const& p2) -> std::ptrdiff_t
|
||||
{
|
||||
return (p2.bit_range().current_byte() - p1.bit_range().current_byte())*8 + p2.bit_range().bit_offset() - p1.bit_range().bit_offset();
|
||||
}
|
||||
|
||||
@@ -137,14 +139,15 @@ inline void memunit_advance(bit_aligned_pixel_iterator<NonAlignedPixelReference>
|
||||
}
|
||||
|
||||
template <typename NonAlignedPixelReference>
|
||||
inline bit_aligned_pixel_iterator<NonAlignedPixelReference> memunit_advanced(const bit_aligned_pixel_iterator<NonAlignedPixelReference>& p, std::ptrdiff_t diff) {
|
||||
inline auto memunit_advanced(bit_aligned_pixel_iterator<NonAlignedPixelReference> const& p, std::ptrdiff_t diff) -> bit_aligned_pixel_iterator<NonAlignedPixelReference> {
|
||||
bit_aligned_pixel_iterator<NonAlignedPixelReference> ret=p;
|
||||
memunit_advance(ret, diff);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename NonAlignedPixelReference> inline
|
||||
NonAlignedPixelReference memunit_advanced_ref(bit_aligned_pixel_iterator<NonAlignedPixelReference> it, std::ptrdiff_t diff) {
|
||||
auto memunit_advanced_ref(bit_aligned_pixel_iterator<NonAlignedPixelReference> it, std::ptrdiff_t diff) -> NonAlignedPixelReference
|
||||
{
|
||||
return *memunit_advanced(it,diff);
|
||||
}
|
||||
/////////////////////////////
|
||||
@@ -183,11 +186,14 @@ namespace std {
|
||||
// It is important to provide an overload of uninitialized_copy for bit_aligned_pixel_iterator. The default STL implementation calls placement new,
|
||||
// which is not defined for bit_aligned_pixel_iterator.
|
||||
template <typename NonAlignedPixelReference>
|
||||
boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference> uninitialized_copy(boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference> first,
|
||||
boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference> last,
|
||||
boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference> dst) {
|
||||
auto 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)
|
||||
-> boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference>
|
||||
{
|
||||
return std::copy(first,last,dst);
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
||||
@@ -49,18 +49,18 @@ public:
|
||||
BOOST_ASSERT(bit_offset >= 0 && bit_offset < 8);
|
||||
}
|
||||
|
||||
bit_range(const bit_range& br) : _current_byte(br._current_byte), _bit_offset(br._bit_offset) {}
|
||||
bit_range(bit_range const& br) : _current_byte(br._current_byte), _bit_offset(br._bit_offset) {}
|
||||
template <bool M> bit_range(const bit_range<RangeSize,M>& br) : _current_byte(br._current_byte), _bit_offset(br._bit_offset) {}
|
||||
|
||||
bit_range& operator=(const bit_range& br) { _current_byte = br._current_byte; _bit_offset=br._bit_offset; return *this; }
|
||||
bool operator==(const bit_range& br) const { return _current_byte==br._current_byte && _bit_offset==br._bit_offset; }
|
||||
auto operator=(bit_range const& br) -> bit_range& { _current_byte = br._current_byte; _bit_offset=br._bit_offset; return *this; }
|
||||
bool operator==(bit_range const& br) const { return _current_byte==br._current_byte && _bit_offset==br._bit_offset; }
|
||||
|
||||
bit_range& operator++() {
|
||||
auto operator++() -> bit_range& {
|
||||
_current_byte += (_bit_offset+RangeSize) / 8;
|
||||
_bit_offset = (_bit_offset+RangeSize) % 8;
|
||||
return *this;
|
||||
}
|
||||
bit_range& operator--() { bit_advance(-RangeSize); return *this; }
|
||||
auto operator--() -> bit_range& { bit_advance(-RangeSize); return *this; }
|
||||
|
||||
void bit_advance(difference_type num_bits) {
|
||||
int new_offset = int(_bit_offset+num_bits);
|
||||
@@ -71,11 +71,13 @@ public:
|
||||
--_current_byte;
|
||||
}
|
||||
}
|
||||
difference_type bit_distance_to(const bit_range& b) const {
|
||||
|
||||
auto bit_distance_to(bit_range const& b) const -> difference_type
|
||||
{
|
||||
return (b.current_byte() - current_byte())*8 + b.bit_offset()-bit_offset();
|
||||
}
|
||||
byte_t* current_byte() const { return _current_byte; }
|
||||
int bit_offset() const { return _bit_offset; }
|
||||
auto current_byte() const -> byte_t* { return _current_byte; }
|
||||
auto bit_offset() const -> int { return _bit_offset; }
|
||||
};
|
||||
|
||||
/// \defgroup ColorBaseModelNonAlignedPixel bit_aligned_pixel_reference
|
||||
@@ -136,8 +138,10 @@ struct bit_aligned_pixel_reference
|
||||
|
||||
bit_aligned_pixel_reference(){}
|
||||
bit_aligned_pixel_reference(data_ptr_t data_ptr, int bit_offset) : _bit_range(data_ptr, bit_offset) {}
|
||||
explicit bit_aligned_pixel_reference(const bit_range_t& bit_range) : _bit_range(bit_range) {}
|
||||
template <bool IsMutable2> bit_aligned_pixel_reference(const bit_aligned_pixel_reference<BitField,ChannelBitSizes,Layout,IsMutable2>& p) : _bit_range(p._bit_range) {}
|
||||
explicit bit_aligned_pixel_reference(bit_range_t const& bit_range) : _bit_range(bit_range) {}
|
||||
|
||||
template <bool IsMutable2>
|
||||
bit_aligned_pixel_reference(bit_aligned_pixel_reference<BitField,ChannelBitSizes,Layout,IsMutable2> const& p) : _bit_range(p._bit_range) {}
|
||||
|
||||
// Grayscale references can be constructed from the channel reference
|
||||
explicit bit_aligned_pixel_reference(typename kth_element_type<bit_aligned_pixel_reference,0>::type const channel0)
|
||||
@@ -183,11 +187,12 @@ struct bit_aligned_pixel_reference
|
||||
|
||||
auto operator->() const -> bit_aligned_pixel_reference const* { return this; }
|
||||
|
||||
bit_range_t const& bit_range() const { return _bit_range; }
|
||||
auto bit_range() const -> bit_range_t const& { return _bit_range; }
|
||||
|
||||
private:
|
||||
mutable bit_range_t _bit_range;
|
||||
template <typename B, typename C, typename L, bool M> friend struct bit_aligned_pixel_reference;
|
||||
template <typename B, typename C, typename L, bool M>
|
||||
friend struct bit_aligned_pixel_reference;
|
||||
|
||||
template <typename Pixel> static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel,bit_aligned_pixel_reference> >(); }
|
||||
|
||||
@@ -369,7 +374,7 @@ namespace std {
|
||||
// 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) {
|
||||
void swap(boost::gil::bit_aligned_pixel_reference<B,C,L,true> const x, R& y) {
|
||||
boost::gil::swap_proxy<typename boost::gil::bit_aligned_pixel_reference<B,C,L,true>::value_type>(x,y);
|
||||
}
|
||||
|
||||
@@ -381,7 +386,7 @@ void swap(typename boost::gil::bit_aligned_pixel_reference<B,C,L,true>::value_ty
|
||||
|
||||
|
||||
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) {
|
||||
void swap(boost::gil::bit_aligned_pixel_reference<B,C,L,true> const 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -198,16 +198,32 @@ struct scoped_channel_value
|
||||
return *this;
|
||||
}
|
||||
|
||||
scoped_channel_value& operator++() { ++value_; return *this; }
|
||||
scoped_channel_value& operator--() { --value_; return *this; }
|
||||
auto operator++() -> scoped_channel_value& { ++value_; return *this; }
|
||||
auto operator--() -> scoped_channel_value& { --value_; return *this; }
|
||||
|
||||
scoped_channel_value operator++(int) { scoped_channel_value tmp=*this; this->operator++(); return tmp; }
|
||||
scoped_channel_value operator--(int) { scoped_channel_value tmp=*this; this->operator--(); return tmp; }
|
||||
auto operator++(int) -> scoped_channel_value
|
||||
{
|
||||
scoped_channel_value tmp=*this;
|
||||
this->operator++(); return tmp;
|
||||
}
|
||||
|
||||
auto operator--(int) -> scoped_channel_value
|
||||
{
|
||||
scoped_channel_value tmp=*this;
|
||||
this->operator--(); return tmp;
|
||||
}
|
||||
|
||||
template <typename Scalar2> scoped_channel_value& operator+=(Scalar2 v) { value_+=v; return *this; }
|
||||
template <typename Scalar2> scoped_channel_value& operator-=(Scalar2 v) { value_-=v; return *this; }
|
||||
template <typename Scalar2> scoped_channel_value& operator*=(Scalar2 v) { value_*=v; return *this; }
|
||||
template <typename Scalar2> scoped_channel_value& operator/=(Scalar2 v) { value_/=v; return *this; }
|
||||
template <typename Scalar2>
|
||||
auto operator+=(Scalar2 v) -> scoped_channel_value& { value_+=v; return *this; }
|
||||
|
||||
template <typename Scalar2>
|
||||
auto operator-=(Scalar2 v) -> scoped_channel_value& { value_-=v; return *this; }
|
||||
|
||||
template <typename Scalar2>
|
||||
auto operator*=(Scalar2 v) -> scoped_channel_value& { value_*=v; return *this; }
|
||||
|
||||
template <typename Scalar2>
|
||||
auto operator/=(Scalar2 v) -> scoped_channel_value& { value_/=v; return *this; }
|
||||
|
||||
operator BaseChannelValue() const { return value_; }
|
||||
private:
|
||||
@@ -313,7 +329,7 @@ public:
|
||||
value_ = packed_channel_value(static_cast<integer_t>(v));
|
||||
}
|
||||
|
||||
static unsigned int num_bits() { return NumBits; }
|
||||
static auto num_bits() -> unsigned int { return NumBits; }
|
||||
|
||||
operator integer_t() const { return value_; }
|
||||
|
||||
@@ -348,35 +364,69 @@ public:
|
||||
data_ptr_t _data_ptr; // void* pointer to the first byte of the bit range
|
||||
|
||||
using value_type = packed_channel_value<NumBits>;
|
||||
using reference = const Derived;
|
||||
using pointer = value_type *;
|
||||
using const_pointer = const value_type *;
|
||||
using reference = Derived const;
|
||||
using pointer = value_type*;
|
||||
using const_pointer = value_type const*;
|
||||
static constexpr int num_bits = NumBits;
|
||||
static constexpr bool is_mutable = IsMutable;
|
||||
|
||||
static value_type min_value() { return channel_traits<value_type>::min_value(); }
|
||||
static value_type max_value() { return channel_traits<value_type>::max_value(); }
|
||||
static auto min_value() -> value_type { return channel_traits<value_type>::min_value(); }
|
||||
static auto max_value() -> value_type { return channel_traits<value_type>::max_value(); }
|
||||
|
||||
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) {}
|
||||
const Derived& operator=(integer_t v) const { set(v); return derived(); }
|
||||
packed_channel_reference_base(packed_channel_reference_base const& ref) : _data_ptr(ref._data_ptr) {}
|
||||
|
||||
auto operator=(integer_t v) const -> Derived const& { set(v); return derived(); }
|
||||
|
||||
const Derived& operator++() const { set(get()+1); return derived(); }
|
||||
const Derived& operator--() const { set(get()-1); return derived(); }
|
||||
auto operator++() const -> Derived const& { set(get()+1); return derived(); }
|
||||
auto operator--() const -> Derived const& { set(get()-1); return derived(); }
|
||||
|
||||
Derived operator++(int) const { Derived tmp=derived(); this->operator++(); return tmp; }
|
||||
Derived operator--(int) const { Derived tmp=derived(); this->operator--(); return tmp; }
|
||||
auto operator++(int) const -> Derived
|
||||
{
|
||||
Derived tmp=derived();
|
||||
this->operator++(); return tmp;
|
||||
}
|
||||
|
||||
auto operator--(int) const -> Derived
|
||||
{
|
||||
Derived tmp=derived();
|
||||
this->operator--();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
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(); }
|
||||
template <typename Scalar2>
|
||||
auto operator+=(Scalar2 v) const -> Derived const&
|
||||
{
|
||||
set( static_cast<integer_t>( get() + v ));
|
||||
return derived();
|
||||
}
|
||||
|
||||
template <typename Scalar2>
|
||||
auto operator-=(Scalar2 v) const -> Derived const&
|
||||
{
|
||||
set( static_cast<integer_t>( get() - v )); return derived();
|
||||
}
|
||||
|
||||
template <typename Scalar2>
|
||||
auto operator*=(Scalar2 v) const -> Derived const&
|
||||
{
|
||||
set( static_cast<integer_t>( get() * v ));
|
||||
return derived();
|
||||
}
|
||||
|
||||
template <typename Scalar2>
|
||||
auto operator/=(Scalar2 v) const -> Derived const&
|
||||
{
|
||||
set( static_cast<integer_t>( get() / v ));
|
||||
return derived();
|
||||
}
|
||||
|
||||
operator integer_t() const { return get(); }
|
||||
data_ptr_t operator &() const {return _data_ptr;}
|
||||
auto operator&() const -> data_ptr_t {return _data_ptr;}
|
||||
|
||||
protected:
|
||||
|
||||
using num_value_t = typename detail::num_value_fn<NumBits>::type;
|
||||
@@ -389,12 +439,15 @@ protected:
|
||||
const bitfield_t& get_data() const { return *static_cast<const bitfield_t*>(_data_ptr); }
|
||||
void set_data(const bitfield_t& val) const { *static_cast< bitfield_t*>(_data_ptr) = val; }
|
||||
#else
|
||||
bitfield_t get_data() const {
|
||||
auto get_data() const -> bitfield_t
|
||||
{
|
||||
bitfield_t ret;
|
||||
static_copy_bytes<sizeof(bitfield_t) >()(gil_reinterpret_cast_c<const unsigned char*>(_data_ptr),gil_reinterpret_cast<unsigned char*>(&ret));
|
||||
return ret;
|
||||
}
|
||||
void set_data(const bitfield_t& val) const {
|
||||
|
||||
void set_data(bitfield_t const& val) const
|
||||
{
|
||||
static_copy_bytes<sizeof(bitfield_t) >()(gil_reinterpret_cast_c<const unsigned char*>(&val),gil_reinterpret_cast<unsigned char*>(_data_ptr));
|
||||
}
|
||||
#endif
|
||||
@@ -403,8 +456,8 @@ private:
|
||||
void set(integer_t value) const { // can this be done faster??
|
||||
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); }
|
||||
auto get() const -> integer_t { return derived().get(); }
|
||||
auto derived() const -> Derived const& { return static_cast<const Derived&>(*this); }
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
@@ -468,9 +521,9 @@ public:
|
||||
packed_channel_reference(const packed_channel_reference& ref) : parent_t(ref._data_ptr) {}
|
||||
packed_channel_reference(const mutable_reference& ref) : parent_t(ref._data_ptr) {}
|
||||
|
||||
unsigned first_bit() const { return FirstBit; }
|
||||
auto first_bit() const -> unsigned int { return FirstBit; }
|
||||
|
||||
integer_t get() const { return integer_t((this->get_data()&channel_mask) >> FirstBit); }
|
||||
auto get() const -> integer_t { return integer_t((this->get_data()&channel_mask) >> FirstBit); }
|
||||
};
|
||||
|
||||
/// \ingroup PackedChannelReferenceModel
|
||||
@@ -499,16 +552,17 @@ public:
|
||||
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; }
|
||||
auto operator=(mutable_reference const& ref) const -> packed_channel_reference const& { set_from_reference(ref.get_data()); return *this; }
|
||||
auto operator=(const_reference const& ref) const -> packed_channel_reference const& { set_from_reference(ref.get_data()); return *this; }
|
||||
|
||||
template <bool Mutable1>
|
||||
const packed_channel_reference& operator=(const packed_dynamic_channel_reference<BitField,NumBits,Mutable1>& ref) const { set_unsafe(ref.get()); return *this; }
|
||||
auto operator=(packed_dynamic_channel_reference<BitField,NumBits,Mutable1> const& ref) const -> packed_channel_reference const& { set_unsafe(ref.get()); return *this; }
|
||||
|
||||
unsigned first_bit() const { return FirstBit; }
|
||||
auto first_bit() const -> unsigned int { return FirstBit; }
|
||||
|
||||
integer_t get() const { return integer_t((this->get_data()&channel_mask) >> FirstBit); }
|
||||
auto get() const -> integer_t { return integer_t((this->get_data()&channel_mask) >> FirstBit); }
|
||||
void set_unsafe(integer_t value) const { this->set_data((this->get_data() & ~channel_mask) | (( static_cast< BitField >( value )<<FirstBit))); }
|
||||
|
||||
private:
|
||||
void set_from_reference(const BitField& other_bits) const { this->set_data((this->get_data() & ~channel_mask) | (other_bits & channel_mask)); }
|
||||
};
|
||||
@@ -599,13 +653,14 @@ public:
|
||||
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) {}
|
||||
packed_dynamic_channel_reference(const mutable_reference& ref) : parent_t(ref._data_ptr), _first_bit(ref._first_bit) {}
|
||||
packed_dynamic_channel_reference(void const* data_ptr, unsigned first_bit) : parent_t(data_ptr), _first_bit(first_bit) {}
|
||||
packed_dynamic_channel_reference(const_reference const& ref) : parent_t(ref._data_ptr), _first_bit(ref._first_bit) {}
|
||||
packed_dynamic_channel_reference(mutable_reference const& ref) : parent_t(ref._data_ptr), _first_bit(ref._first_bit) {}
|
||||
|
||||
unsigned first_bit() const { return _first_bit; }
|
||||
auto first_bit() const -> unsigned int { return _first_bit; }
|
||||
|
||||
integer_t get() const {
|
||||
auto get() const -> integer_t
|
||||
{
|
||||
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 );
|
||||
}
|
||||
@@ -629,26 +684,30 @@ public:
|
||||
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) {}
|
||||
packed_dynamic_channel_reference(packed_dynamic_channel_reference const& ref) : parent_t(ref._data_ptr), _first_bit(ref._first_bit) {}
|
||||
|
||||
packed_dynamic_channel_reference const& operator=(integer_t value) const
|
||||
auto operator=(integer_t value) const -> packed_dynamic_channel_reference 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; }
|
||||
auto operator=(mutable_reference const& ref) const -> packed_dynamic_channel_reference const& { set_unsafe(ref.get()); return *this; }
|
||||
auto operator=(const_reference const& ref) const -> packed_dynamic_channel_reference const& { set_unsafe(ref.get()); return *this; }
|
||||
|
||||
template <typename BitField1, int FirstBit1, bool Mutable1>
|
||||
const packed_dynamic_channel_reference& operator=(const packed_channel_reference<BitField1, FirstBit1, NumBits, Mutable1>& ref) const
|
||||
{ set_unsafe(ref.get()); return *this; }
|
||||
auto operator=(packed_channel_reference<BitField1, FirstBit1, NumBits, Mutable1> const& ref) const -> packed_dynamic_channel_reference const&
|
||||
{
|
||||
set_unsafe(ref.get());
|
||||
return *this;
|
||||
}
|
||||
|
||||
unsigned first_bit() const { return _first_bit; }
|
||||
auto first_bit() const -> unsigned int { return _first_bit; }
|
||||
|
||||
integer_t get() const {
|
||||
const BitField channel_mask = static_cast< integer_t >( parent_t::max_val ) << _first_bit;
|
||||
auto get() const -> integer_t
|
||||
{
|
||||
BitField const channel_mask = static_cast< integer_t >( parent_t::max_val ) << _first_bit;
|
||||
return static_cast< integer_t >(( this->get_data()&channel_mask ) >> _first_bit );
|
||||
}
|
||||
|
||||
|
||||
@@ -148,13 +148,16 @@ template <typename SrcChannelV, typename DstChannelV, bool SrcIsIntegral, bool D
|
||||
struct channel_converter_unsigned_impl {
|
||||
using argument_type = SrcChannelV;
|
||||
using result_type = DstChannelV;
|
||||
DstChannelV operator()(SrcChannelV src) const {
|
||||
auto operator()(SrcChannelV src) const -> DstChannelV
|
||||
{
|
||||
return DstChannelV(channel_traits<DstChannelV>::min_value() +
|
||||
(src - channel_traits<SrcChannelV>::min_value()) / channel_range<SrcChannelV>() * channel_range<DstChannelV>());
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename C>
|
||||
static double channel_range() {
|
||||
static auto channel_range() -> double
|
||||
{
|
||||
return double(channel_traits<C>::max_value()) - double(channel_traits<C>::min_value());
|
||||
}
|
||||
};
|
||||
@@ -198,7 +201,8 @@ struct channel_converter_unsigned_integral<SrcChannelV,DstChannelV,false>
|
||||
// and the dst max value is divisible by the src max value
|
||||
template <typename SrcChannelV, typename DstChannelV>
|
||||
struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,true,true> {
|
||||
DstChannelV operator()(SrcChannelV src) const {
|
||||
auto operator()(SrcChannelV src) const -> DstChannelV
|
||||
{
|
||||
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);
|
||||
@@ -210,7 +214,8 @@ struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,true,tru
|
||||
// and the src max value is divisible by the dst max value
|
||||
template <typename SrcChannelV, typename DstChannelV>
|
||||
struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,false,true> {
|
||||
DstChannelV operator()(SrcChannelV src) const {
|
||||
auto operator()(SrcChannelV src) const -> DstChannelV
|
||||
{
|
||||
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;
|
||||
@@ -221,7 +226,8 @@ struct channel_converter_unsigned_integral_impl<SrcChannelV,DstChannelV,false,tr
|
||||
// Prevent overflow for the largest integral type
|
||||
template <typename DstChannelV>
|
||||
struct channel_converter_unsigned_integral_impl<uintmax_t,DstChannelV,false,true> {
|
||||
DstChannelV operator()(uintmax_t src) const {
|
||||
auto operator()(uintmax_t src) const -> DstChannelV
|
||||
{
|
||||
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)
|
||||
@@ -259,7 +265,7 @@ struct channel_converter_unsigned_integral_impl<SrcChannelV, DstChannelV, SrcLes
|
||||
template <typename SrcChannelV, typename DstChannelV>
|
||||
struct channel_converter_unsigned_integral_nondivisible<SrcChannelV, DstChannelV, true, false>
|
||||
{
|
||||
DstChannelV operator()(SrcChannelV src) const
|
||||
auto operator()(SrcChannelV src) const -> DstChannelV
|
||||
{
|
||||
using dest_t = typename base_channel_type<DstChannelV>::type;
|
||||
return DstChannelV(
|
||||
@@ -275,7 +281,7 @@ struct channel_converter_unsigned_integral_nondivisible<SrcChannelV, DstChannelV
|
||||
template <typename SrcChannelV, typename DstChannelV>
|
||||
struct channel_converter_unsigned_integral_nondivisible<SrcChannelV, DstChannelV, true, true>
|
||||
{
|
||||
DstChannelV operator()(SrcChannelV src) const
|
||||
auto operator()(SrcChannelV src) const -> DstChannelV
|
||||
{
|
||||
static const double mul
|
||||
= unsigned_integral_max_value<DstChannelV>::value
|
||||
@@ -288,9 +294,10 @@ struct channel_converter_unsigned_integral_nondivisible<SrcChannelV, DstChannelV
|
||||
// the dst max value is less than (or equal to) the src max value,
|
||||
// and the src max value is not divisible by the dst max value
|
||||
template <typename SrcChannelV, typename DstChannelV, bool CannotFit>
|
||||
struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,false,CannotFit> {
|
||||
DstChannelV operator()(SrcChannelV src) const {
|
||||
|
||||
struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,false,CannotFit>
|
||||
{
|
||||
auto operator()(SrcChannelV src) const -> DstChannelV
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -312,7 +319,7 @@ struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,
|
||||
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
|
||||
auto operator()(float32_t x) const -> DstChannelV
|
||||
{
|
||||
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 ));
|
||||
@@ -322,13 +329,13 @@ template <typename DstChannelV> struct channel_converter_unsigned<float32_t,DstC
|
||||
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())); }
|
||||
auto operator()(SrcChannelV x) const -> float32_t { return float32_t(x/float(channel_traits<SrcChannelV>::max_value())); }
|
||||
};
|
||||
|
||||
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; }
|
||||
auto operator()(float32_t x) const -> float32_t { return x; }
|
||||
};
|
||||
|
||||
|
||||
@@ -336,7 +343,8 @@ template <> struct channel_converter_unsigned<float32_t,float32_t> {
|
||||
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 {
|
||||
auto operator()(uint32_t x) const -> float32_t
|
||||
{
|
||||
// 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());
|
||||
@@ -346,7 +354,8 @@ template <> struct channel_converter_unsigned<uint32_t,float32_t> {
|
||||
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 {
|
||||
auto operator()(float32_t x) const -> uint32_t
|
||||
{
|
||||
// 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();
|
||||
@@ -406,7 +415,7 @@ 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 {
|
||||
type operator()(uint8_t val) const {
|
||||
return static_cast<int8_t>(static_cast<int32_t>(val) - 128);
|
||||
}
|
||||
};
|
||||
@@ -437,7 +446,8 @@ template <typename SrcChannelV, typename DstChannelV> // Model ChannelValueConce
|
||||
struct channel_converter {
|
||||
using argument_type = SrcChannelV;
|
||||
using result_type = DstChannelV;
|
||||
DstChannelV operator()(const SrcChannelV& src) const {
|
||||
auto operator()(SrcChannelV const& src) const -> DstChannelV
|
||||
{
|
||||
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>;
|
||||
@@ -448,7 +458,8 @@ struct channel_converter {
|
||||
/// \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 auto channel_convert(SrcChannel const& src) -> typename channel_traits<DstChannel>::value_type
|
||||
{
|
||||
return channel_converter<typename channel_traits<SrcChannel>::value_type,
|
||||
typename channel_traits<DstChannel>::value_type>()(src);
|
||||
}
|
||||
@@ -459,17 +470,26 @@ inline typename channel_traits<DstChannel>::value_type channel_convert(const Src
|
||||
/// on heterogeneous pixels.
|
||||
struct default_channel_converter {
|
||||
template <typename Ch1, typename Ch2>
|
||||
void operator()(const Ch1& src, Ch2& dst) const {
|
||||
void operator()(Ch1 const& src, Ch2& dst) const
|
||||
{
|
||||
dst=channel_convert<Ch2>(src);
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
namespace detail
|
||||
{
|
||||
// fast integer division by 255
|
||||
inline uint32_t div255(uint32_t in) { uint32_t tmp=in+128; return (tmp + (tmp>>8))>>8; }
|
||||
inline auto div255(uint32_t in) -> uint32_t
|
||||
{
|
||||
uint32_t tmp = in + 128;
|
||||
return (tmp + (tmp >> 8)) >> 8;
|
||||
}
|
||||
|
||||
// fast integer divison by 32768
|
||||
inline uint32_t div32768(uint32_t in) { return (in+16384)>>15; }
|
||||
inline auto div32768(uint32_t in) -> uint32_t
|
||||
{
|
||||
return (in + 16384) >> 15;
|
||||
}
|
||||
}
|
||||
|
||||
/// \defgroup ChannelMultiplyAlgorithm channel_multiply
|
||||
@@ -491,7 +511,8 @@ 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 {
|
||||
auto operator()(ChannelValue a, ChannelValue b) const -> ChannelValue
|
||||
{
|
||||
return ChannelValue(static_cast<typename base_channel_type<ChannelValue>::type>(a / double(channel_traits<ChannelValue>::max_value()) * b));
|
||||
}
|
||||
};
|
||||
@@ -501,7 +522,7 @@ 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))); }
|
||||
auto operator()(uint8_t a, uint8_t b) const -> uint8_t { return uint8_t(detail::div255(uint32_t(a) * uint32_t(b))); }
|
||||
};
|
||||
|
||||
/// \brief Specialization of channel_multiply for 16-bit unsigned channels
|
||||
@@ -509,7 +530,7 @@ 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); }
|
||||
auto operator()(uint16_t a, uint16_t b) const -> uint16_t { return uint16_t((uint32_t(a) * uint32_t(b))/65535); }
|
||||
};
|
||||
|
||||
/// \brief Specialization of channel_multiply for float 0..1 channels
|
||||
@@ -517,7 +538,7 @@ 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; }
|
||||
auto operator()(float32_t a, float32_t b) const -> float32_t { return a*b; }
|
||||
};
|
||||
|
||||
/// \brief A function object to multiply two channels. result = a * b / max_value
|
||||
@@ -526,7 +547,8 @@ struct channel_multiplier {
|
||||
using first_argument_type = ChannelValue;
|
||||
using second_argument_type = ChannelValue;
|
||||
using result_type = ChannelValue;
|
||||
ChannelValue operator()(ChannelValue a, ChannelValue b) const {
|
||||
auto operator()(ChannelValue a, ChannelValue b) const -> ChannelValue
|
||||
{
|
||||
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>;
|
||||
@@ -536,7 +558,8 @@ struct channel_multiplier {
|
||||
|
||||
/// \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 auto channel_multiply(Channel a, Channel b) -> typename channel_traits<Channel>::value_type
|
||||
{
|
||||
return channel_multiplier<typename channel_traits<Channel>::value_type>()(a,b);
|
||||
}
|
||||
/// @}
|
||||
@@ -556,8 +579,8 @@ inline typename channel_traits<Channel>::value_type channel_multiply(Channel a,
|
||||
/// \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) {
|
||||
|
||||
inline auto channel_invert(Channel x) -> typename channel_traits<Channel>::value_type
|
||||
{
|
||||
using base_t = typename base_channel_type<Channel>::type;
|
||||
using promoted_t = typename promote_integral<base_t>::type;
|
||||
promoted_t const promoted_x = x;
|
||||
@@ -568,6 +591,6 @@ inline typename channel_traits<Channel>::value_type channel_invert(Channel x) {
|
||||
return inverted_x;
|
||||
}
|
||||
|
||||
} } // namespace boost::gil
|
||||
}} // namespace boost::gil
|
||||
|
||||
#endif
|
||||
|
||||
@@ -40,13 +40,13 @@ 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)
|
||||
inline auto 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)
|
||||
-> typename type_from_x_iterator<planar_pixel_iterator<IC,cmyk_t>>::view_t
|
||||
{
|
||||
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
|
||||
}} // namespace gil
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,7 +34,7 @@ auto semantic_at_c(ColorBase& p)
|
||||
|
||||
|
||||
template <int K, typename ColorBase>
|
||||
typename kth_semantic_element_const_reference_type<ColorBase,K>::type semantic_at_c(const ColorBase& p);
|
||||
auto semantic_at_c(const ColorBase& p) -> typename kth_semantic_element_const_reference_type<ColorBase,K>::type;
|
||||
|
||||
// Forward declare element_reference_type
|
||||
template <typename ColorBase> struct element_reference_type;
|
||||
@@ -178,7 +178,7 @@ struct homogeneous_color_base<Element, Layout, 2>
|
||||
{ return v1_; }
|
||||
|
||||
// Support for planar_pixel_reference operator[]
|
||||
Element at_c_dynamic(std::size_t i) const
|
||||
auto at_c_dynamic(std::size_t i) const -> Element
|
||||
{
|
||||
if (i == 0)
|
||||
return v0_;
|
||||
@@ -277,7 +277,7 @@ struct homogeneous_color_base<Element, Layout, 3>
|
||||
{ return v2_; }
|
||||
|
||||
// Support for planar_pixel_reference operator[]
|
||||
Element at_c_dynamic(std::size_t i) const
|
||||
auto at_c_dynamic(std::size_t i) const -> Element
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
@@ -392,7 +392,7 @@ struct homogeneous_color_base<Element, Layout, 4>
|
||||
{ return v3_; }
|
||||
|
||||
// Support for planar_pixel_reference operator[]
|
||||
Element at_c_dynamic(std::size_t i) const
|
||||
auto at_c_dynamic(std::size_t i) const -> Element
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
@@ -527,7 +527,7 @@ struct homogeneous_color_base<Element, Layout, 5>
|
||||
}
|
||||
|
||||
// Support for planar_pixel_reference operator[]
|
||||
Element at_c_dynamic(std::size_t i) const
|
||||
auto at_c_dynamic(std::size_t i) const -> Element
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
|
||||
@@ -187,14 +187,18 @@ 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>
|
||||
typename color_element_reference_type<ColorBase,Color>::type get_color(ColorBase& cb, Color=Color()) {
|
||||
auto get_color(ColorBase& cb, Color=Color())
|
||||
-> typename color_element_reference_type<ColorBase,Color>::type
|
||||
{
|
||||
return color_element_reference_type<ColorBase,Color>::get(cb);
|
||||
}
|
||||
|
||||
/// \brief Constant accessor to the element associated with a given color name
|
||||
/// \ingroup ColorBaseAlgorithmColor
|
||||
template <typename ColorBase, typename Color>
|
||||
typename color_element_const_reference_type<ColorBase,Color>::type get_color(const ColorBase& cb, Color=Color()) {
|
||||
auto get_color(const ColorBase& cb, Color=Color())
|
||||
-> typename color_element_const_reference_type<ColorBase,Color>::type
|
||||
{
|
||||
return color_element_const_reference_type<ColorBase,Color>::get(cb);
|
||||
}
|
||||
|
||||
@@ -435,36 +439,63 @@ template<> struct element_recursion<0> {
|
||||
};
|
||||
|
||||
// std::min and std::max don't have the mutable overloads...
|
||||
template <typename Q> inline const Q& mutable_min(const Q& x, const Q& y) { return x<y ? x : y; }
|
||||
template <typename Q> inline Q& mutable_min( Q& x, Q& y) { return x<y ? x : y; }
|
||||
template <typename Q> inline const Q& mutable_max(const Q& x, const Q& y) { return x<y ? y : x; }
|
||||
template <typename Q> inline Q& mutable_max( Q& x, Q& y) { return x<y ? y : x; }
|
||||
template <typename Q>
|
||||
inline auto mutable_min(Q const& x, Q const& y) -> Q const& { return x<y ? x : y; }
|
||||
|
||||
template <typename Q>
|
||||
inline auto mutable_min(Q& x, Q& y) -> Q& { return x<y ? x : y; }
|
||||
|
||||
template <typename Q>
|
||||
inline auto mutable_max(Q const& x, Q const& y) -> Q const& { return x<y ? y : x; }
|
||||
|
||||
template <typename Q>
|
||||
inline auto mutable_max(Q& x, Q& y) -> Q& { return x<y ? y : x; }
|
||||
|
||||
|
||||
// compile-time recursion for min/max element
|
||||
template <int N>
|
||||
struct min_max_recur {
|
||||
template <typename P> static typename element_const_reference_type<P>::type max_(const P& p) {
|
||||
struct min_max_recur
|
||||
{
|
||||
template <typename P>
|
||||
static auto max_(P const& p) -> typename element_const_reference_type<P>::type
|
||||
{
|
||||
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) {
|
||||
|
||||
template <typename P>
|
||||
static auto max_(P& p) -> typename element_reference_type<P>::type
|
||||
{
|
||||
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) {
|
||||
|
||||
template <typename P>
|
||||
static auto min_(P const& p) -> typename element_const_reference_type<P>::type
|
||||
{
|
||||
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) {
|
||||
|
||||
template <typename P>
|
||||
static auto min_(P& p) -> typename element_reference_type<P>::type
|
||||
{
|
||||
return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
|
||||
}
|
||||
};
|
||||
|
||||
// termination condition of the compile-time recursion for min/max element
|
||||
template <>
|
||||
struct min_max_recur<1> {
|
||||
template <typename P> static typename element_const_reference_type<P>::type max_(const P& p) { return semantic_at_c<0>(p); }
|
||||
template <typename P> static typename element_reference_type<P>::type max_( P& p) { return semantic_at_c<0>(p); }
|
||||
template <typename P> static typename element_const_reference_type<P>::type min_(const P& p) { return semantic_at_c<0>(p); }
|
||||
template <typename P> static typename element_reference_type<P>::type min_( P& p) { return semantic_at_c<0>(p); }
|
||||
struct min_max_recur<1>
|
||||
{
|
||||
template <typename P>
|
||||
static auto max_(P const& p) -> typename element_const_reference_type<P>::type { return semantic_at_c<0>(p); }
|
||||
|
||||
template <typename P>
|
||||
static auto max_(P& p) -> typename element_reference_type<P>::type { return semantic_at_c<0>(p); }
|
||||
|
||||
template <typename P>
|
||||
static auto min_(P const& p) -> typename element_const_reference_type<P>::type { return semantic_at_c<0>(p); }
|
||||
|
||||
template <typename P>
|
||||
static auto min_(P& p) -> typename element_reference_type<P>::type { return semantic_at_c<0>(p); }
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
@@ -483,19 +514,19 @@ struct min_max_recur<1> {
|
||||
|
||||
template <typename P>
|
||||
BOOST_FORCEINLINE
|
||||
typename element_const_reference_type<P>::type static_max(const P& p) { return detail::min_max_recur<size<P>::value>::max_(p); }
|
||||
auto static_max(P const& p) -> typename element_const_reference_type<P>::type { return detail::min_max_recur<size<P>::value>::max_(p); }
|
||||
|
||||
template <typename P>
|
||||
BOOST_FORCEINLINE
|
||||
typename element_reference_type<P>::type static_max( P& p) { return detail::min_max_recur<size<P>::value>::max_(p); }
|
||||
auto static_max(P& p) -> typename element_reference_type<P>::type { return detail::min_max_recur<size<P>::value>::max_(p); }
|
||||
|
||||
template <typename P>
|
||||
BOOST_FORCEINLINE
|
||||
typename element_const_reference_type<P>::type static_min(const P& p) { return detail::min_max_recur<size<P>::value>::min_(p); }
|
||||
auto static_min(P const& p) -> typename element_const_reference_type<P>::type { return detail::min_max_recur<size<P>::value>::min_(p); }
|
||||
|
||||
template <typename P>
|
||||
BOOST_FORCEINLINE
|
||||
typename element_reference_type<P>::type static_min( P& p) { return detail::min_max_recur<size<P>::value>::min_(p); }
|
||||
auto static_min(P& p) -> typename element_reference_type<P>::type { return detail::min_max_recur<size<P>::value>::min_(p); }
|
||||
/// \}
|
||||
|
||||
/// \defgroup ColorBaseAlgorithmEqual static_equal
|
||||
@@ -515,7 +546,7 @@ typename element_reference_type<P>::type static_min( P& p) { return d
|
||||
|
||||
template <typename P1,typename P2>
|
||||
BOOST_FORCEINLINE
|
||||
bool static_equal(const P1& p1, const P2& p2) { return detail::element_recursion<size<P1>::value>::static_equal(p1,p2); }
|
||||
bool static_equal(P1 const& p1, const P2& p2) { return detail::element_recursion<size<P1>::value>::static_equal(p1,p2); }
|
||||
|
||||
/// \}
|
||||
|
||||
@@ -708,6 +739,6 @@ 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); }
|
||||
///\}
|
||||
|
||||
} } // namespace boost::gil
|
||||
}} // namespace boost::gil
|
||||
|
||||
#endif
|
||||
|
||||
@@ -63,7 +63,8 @@ namespace detail {
|
||||
// The default implementation of to_luminance uses float0..1 as the intermediate channel type
|
||||
template <typename RedChannel, typename GreenChannel, typename BlueChannel, typename GrayChannelValue>
|
||||
struct rgb_to_luminance_fn {
|
||||
GrayChannelValue operator()(const RedChannel& red, const GreenChannel& green, const BlueChannel& blue) const {
|
||||
auto operator()(const RedChannel& red, const GreenChannel& green, const BlueChannel& blue) const -> GrayChannelValue
|
||||
{
|
||||
return channel_convert<GrayChannelValue>(float32_t(
|
||||
channel_convert<float32_t>(red )*0.30f +
|
||||
channel_convert<float32_t>(green)*0.59f +
|
||||
@@ -74,14 +75,16 @@ struct rgb_to_luminance_fn {
|
||||
// performance specialization for unsigned char
|
||||
template <typename GrayChannelValue>
|
||||
struct rgb_to_luminance_fn<uint8_t,uint8_t,uint8_t, GrayChannelValue> {
|
||||
GrayChannelValue operator()(uint8_t red, uint8_t green, uint8_t blue) const {
|
||||
auto operator()(uint8_t red, uint8_t green, uint8_t blue) const -> GrayChannelValue
|
||||
{
|
||||
return channel_convert<GrayChannelValue>(uint8_t(
|
||||
((uint32_t(red )*4915 + uint32_t(green)*9667 + uint32_t(blue )*1802) + 8192) >> 14));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename GrayChannel, typename RedChannel, typename GreenChannel, typename BlueChannel>
|
||||
typename channel_traits<GrayChannel>::value_type rgb_to_luminance(const RedChannel& red, const GreenChannel& green, const BlueChannel& blue) {
|
||||
auto rgb_to_luminance(const RedChannel& red, const GreenChannel& green, const BlueChannel& blue) -> typename channel_traits<GrayChannel>::value_type
|
||||
{
|
||||
return rgb_to_luminance_fn<RedChannel,GreenChannel,BlueChannel,
|
||||
typename channel_traits<GrayChannel>::value_type>()(red,green,blue);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace boost { namespace gil {
|
||||
/// 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;
|
||||
/// point_t const& Image::dimensions() const;
|
||||
/// const const_view_t& const_view(const Image&);
|
||||
/// const view_t& view(Image&);
|
||||
/// };
|
||||
|
||||
@@ -89,14 +89,14 @@ namespace boost { namespace gil {
|
||||
/// iterator View::end() const;
|
||||
/// reverse_iterator View::rbegin() const;
|
||||
/// reverse_iterator View::rend() const;
|
||||
/// iterator View::at(const point_t&);
|
||||
/// iterator View::at(point_t const&);
|
||||
/// 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;
|
||||
/// template <size_t D> View::axis<D>::iterator View::axis_iterator(point_t const&) const;
|
||||
///
|
||||
/// reference operator()(View,const point_t&) const;
|
||||
/// reference operator()(View,point_t const&) const;
|
||||
/// };
|
||||
/// \endcode
|
||||
template <typename View>
|
||||
@@ -196,17 +196,17 @@ struct RandomAccessNDImageViewConcept
|
||||
/// y_coord_t View::height() const;
|
||||
///
|
||||
/// // X-navigation
|
||||
/// x_iterator View::x_at(const point_t&) const;
|
||||
/// x_iterator View::x_at(point_t const&) 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::y_at(point_t const&) 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;
|
||||
/// xy_locator View::xy_at(point_t const&) const;
|
||||
///
|
||||
/// // (x,y) versions of all methods taking point_t
|
||||
/// View::View(x_coord_t,y_coord_t,const locator&);
|
||||
|
||||
@@ -21,7 +21,7 @@ static constexpr std::array<float, 9> dy_sobel = {{1, 2, 1, 0, 0, 0, -1, -2, -1}
|
||||
static constexpr std::array<float, 9> dy_scharr = {{1, 1, 1, 0, 0, 0, -1, -1, -1}};
|
||||
|
||||
template <typename T, typename Allocator>
|
||||
inline detail::kernel_2d<T, Allocator> get_identity_kernel()
|
||||
inline auto get_identity_kernel() -> detail::kernel_2d<T, Allocator>
|
||||
{
|
||||
detail::kernel_2d<T, Allocator> kernel(1, 0, 0);
|
||||
kernel[0] = 1;
|
||||
|
||||
@@ -118,7 +118,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
void recreate(const point_t& dims, unsigned alignment=1)
|
||||
void recreate(point_t const& dims, unsigned alignment=1)
|
||||
{
|
||||
variant2::visit(detail::recreate_image_fnobj(dims, alignment), *this);
|
||||
}
|
||||
|
||||
@@ -99,8 +99,8 @@ inline double minimum_angle_step(point_t dimensions)
|
||||
/// WARNING: do keep in mind IEEE 754 quirks, e.g. no-associativity,
|
||||
/// no-commutativity and precision. Do not expect expressions that are
|
||||
/// mathematically the same to produce the same values
|
||||
inline hough_parameter<double> make_theta_parameter(double approx_angle, double neighborhood,
|
||||
point_t dimensions)
|
||||
inline auto make_theta_parameter(double approx_angle, double neighborhood, point_t dimensions)
|
||||
-> hough_parameter<double>
|
||||
{
|
||||
auto angle_step = minimum_angle_step(dimensions);
|
||||
|
||||
|
||||
@@ -35,9 +35,9 @@ namespace boost { namespace gil {
|
||||
/// accumulator array. The theta parameter is best computed through factory function
|
||||
/// provided in hough_parameter.hpp
|
||||
template <typename InputView, typename OutputView>
|
||||
void hough_line_transform(const InputView& input_view, const OutputView& accumulator_array,
|
||||
const hough_parameter<double>& theta,
|
||||
const hough_parameter<std::ptrdiff_t>& radius)
|
||||
void hough_line_transform(InputView const& input_view, OutputView const& accumulator_array,
|
||||
hough_parameter<double> const& theta,
|
||||
hough_parameter<std::ptrdiff_t> const& radius)
|
||||
{
|
||||
std::ptrdiff_t r_lower_bound = radius.start_point;
|
||||
std::ptrdiff_t r_upper_bound = r_lower_bound + radius.step_size * (radius.step_count - 1);
|
||||
@@ -82,11 +82,11 @@ void hough_line_transform(const InputView& input_view, const OutputView& accumul
|
||||
/// then is translated for every origin (x, y) in x y parameter space. For available
|
||||
/// circle rasterizers, please look at rasterization/circle.hpp
|
||||
template <typename ImageView, typename ForwardIterator, typename Rasterizer>
|
||||
void hough_circle_transform_brute(const ImageView& input,
|
||||
const hough_parameter<std::ptrdiff_t> radius_parameter,
|
||||
const hough_parameter<std::ptrdiff_t> x_parameter,
|
||||
const hough_parameter<std::ptrdiff_t>& y_parameter,
|
||||
ForwardIterator d_first, Rasterizer)
|
||||
void hough_circle_transform_brute(ImageView const& input,
|
||||
hough_parameter<std::ptrdiff_t> const& radius_parameter,
|
||||
hough_parameter<std::ptrdiff_t> const& x_parameter,
|
||||
hough_parameter<std::ptrdiff_t> const& y_parameter,
|
||||
ForwardIterator d_first, Rasterizer rasterizer)
|
||||
{
|
||||
for (std::size_t radius_index = 0; radius_index < radius_parameter.step_count; ++radius_index)
|
||||
{
|
||||
@@ -97,7 +97,7 @@ void hough_circle_transform_brute(const ImageView& input,
|
||||
rasterizer(circle_points.begin());
|
||||
// sort by scanline to improve cache coherence for row major images
|
||||
std::sort(circle_points.begin(), circle_points.end(),
|
||||
[](const point_t& lhs, const point_t& rhs) { return lhs.y < rhs.y; });
|
||||
[](point_t const& lhs, point_t const& rhs) { return lhs.y < rhs.y; });
|
||||
const auto translate = [](std::vector<point_t>& points, point_t offset) {
|
||||
std::transform(points.begin(), points.end(), points.begin(), [offset](point_t point) {
|
||||
return point_t(point.x + offset.x, point.y + offset.y);
|
||||
|
||||
@@ -200,7 +200,7 @@ public:
|
||||
}
|
||||
|
||||
/// Check if image is large enough.
|
||||
void check_image_size( const point_t& img_dim )
|
||||
void check_image_size( point_t const& img_dim )
|
||||
{
|
||||
if( _settings._dim.x > 0 )
|
||||
{
|
||||
|
||||
@@ -136,8 +136,8 @@ struct image_read_settings< bmp_tag > : public 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( point_t const& top_left
|
||||
, point_t const& dim
|
||||
)
|
||||
: image_read_settings_base( top_left
|
||||
, dim
|
||||
|
||||
@@ -189,7 +189,7 @@ public:
|
||||
}
|
||||
|
||||
/// Check if image is large enough.
|
||||
void check_image_size( const point_t& img_dim )
|
||||
void check_image_size( point_t const& img_dim )
|
||||
{
|
||||
if( _settings._dim.x > 0 )
|
||||
{
|
||||
|
||||
@@ -150,8 +150,8 @@ struct image_read_settings< jpeg_tag > : public image_read_settings_base
|
||||
/// \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
|
||||
image_read_settings( point_t const& top_left
|
||||
, point_t const& dim
|
||||
, jpeg_dct_method::type dct_method = jpeg_dct_method::default_value
|
||||
)
|
||||
: image_read_settings_base( top_left
|
||||
|
||||
@@ -601,7 +601,7 @@ public:
|
||||
}
|
||||
|
||||
/// Check if image is large enough.
|
||||
void check_image_size( const point_t& img_dim )
|
||||
void check_image_size( point_t const& img_dim )
|
||||
{
|
||||
if( _settings._dim.x > 0 )
|
||||
{
|
||||
|
||||
@@ -679,8 +679,8 @@ struct image_read_settings< png_tag > : public image_read_settings_base
|
||||
/// \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
|
||||
image_read_settings( point_t const& top_left
|
||||
, point_t const& dim
|
||||
, const bool apply_screen_gamma = false
|
||||
, const png_gamma::type& screen_gamma = 1.0
|
||||
)
|
||||
@@ -715,8 +715,8 @@ struct image_read_settings< png_tag > : public image_read_settings_base
|
||||
, _screen_gamma ( 2 )
|
||||
{}
|
||||
|
||||
image_read_settings( const point_t& top_left
|
||||
, const point_t& dim
|
||||
image_read_settings( point_t const& top_left
|
||||
, point_t const& dim
|
||||
)
|
||||
: image_read_settings_base( top_left
|
||||
, dim
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
}
|
||||
|
||||
/// Check if image is large enough.
|
||||
void check_image_size( const point_t& img_dim )
|
||||
void check_image_size( point_t const& img_dim )
|
||||
{
|
||||
if( _settings._dim.x > 0 )
|
||||
{
|
||||
|
||||
@@ -72,8 +72,8 @@ struct image_read_settings< pnm_tag > : public 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( point_t const& top_left
|
||||
, point_t const& dim
|
||||
)
|
||||
: image_read_settings_base( top_left
|
||||
, dim
|
||||
|
||||
@@ -98,7 +98,7 @@ public:
|
||||
}
|
||||
|
||||
/// Check if image is large enough.
|
||||
void check_image_size( const point_t& img_dim )
|
||||
void check_image_size( point_t const& img_dim )
|
||||
{
|
||||
if( _settings._dim.x > 0 )
|
||||
{
|
||||
|
||||
@@ -182,8 +182,8 @@ struct image_read_settings< raw_tag > : public 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( point_t const& top_left
|
||||
, point_t const& dim
|
||||
)
|
||||
: image_read_settings_base( top_left
|
||||
, dim
|
||||
|
||||
@@ -122,7 +122,7 @@ public:
|
||||
}
|
||||
|
||||
/// Check if image is large enough.
|
||||
void check_image_size( const point_t& img_dim )
|
||||
void check_image_size( point_t const& img_dim )
|
||||
{
|
||||
if( _settings._dim.x > 0 )
|
||||
{
|
||||
|
||||
@@ -143,8 +143,8 @@ struct image_read_settings< targa_tag > : public 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( point_t const& top_left
|
||||
, point_t const& dim
|
||||
)
|
||||
: image_read_settings_base( top_left
|
||||
, dim
|
||||
|
||||
@@ -103,7 +103,7 @@ public:
|
||||
}
|
||||
|
||||
/// Check if image is large enough.
|
||||
void check_image_size( const point_t& img_dim )
|
||||
void check_image_size( point_t const& img_dim )
|
||||
{
|
||||
if( _settings._dim.x > 0 )
|
||||
{
|
||||
|
||||
@@ -279,8 +279,8 @@ struct image_read_settings< tiff_tag > : public image_read_settings_base
|
||||
/// \param top_left Top left coordinate for reading partial image.
|
||||
/// \param dim Dimensions for reading partial image.
|
||||
/// \param directory Defines the page to read in a multipage tiff file.
|
||||
image_read_settings( const point_t& top_left
|
||||
, const point_t& dim
|
||||
image_read_settings( point_t const& top_left
|
||||
, point_t const& dim
|
||||
, const tiff_directory::type& directory = tiff_directory::default_value::value
|
||||
)
|
||||
: image_read_settings_base( top_left
|
||||
|
||||
@@ -100,7 +100,7 @@ struct indexed_image_deref_fn : indexed_image_deref_fn_base< IndicesLoc
|
||||
)
|
||||
{}
|
||||
|
||||
typename base_t::result_type operator()( const point_t& p ) const
|
||||
typename base_t::result_type operator()( point_t const& p ) const
|
||||
{
|
||||
return * this->_palette_loc.xy_at( at_c<0>( *this->_indices_loc.xy_at( p )), 0 );
|
||||
}
|
||||
@@ -166,7 +166,7 @@ public:
|
||||
, _num_colors( 0 )
|
||||
{}
|
||||
|
||||
indexed_image_view( const point_t& dimensions
|
||||
indexed_image_view( point_t const& dimensions
|
||||
, std::size_t num_colors
|
||||
, const Locator& locator
|
||||
)
|
||||
@@ -280,7 +280,7 @@ public:
|
||||
init( point_t( width, height ), num_colors );
|
||||
}
|
||||
|
||||
indexed_image( const point_t& dimensions
|
||||
indexed_image( point_t const& dimensions
|
||||
, const std::size_t num_colors = 1
|
||||
, const std::size_t indices_alignment = 0
|
||||
, const std::size_t palette_alignment = 0
|
||||
@@ -323,7 +323,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
void init( const point_t& dimensions
|
||||
void init( point_t const& dimensions
|
||||
, const std::size_t num_colors
|
||||
)
|
||||
{
|
||||
|
||||
@@ -96,7 +96,7 @@ struct subchroma_image_deref_fn
|
||||
{}
|
||||
|
||||
/// operator()
|
||||
result_type operator()( const point_t& p ) const
|
||||
result_type operator()( point_t const& p ) const
|
||||
{
|
||||
using scaling_factors_t = detail::scaling_factors
|
||||
<
|
||||
@@ -228,9 +228,9 @@ public:
|
||||
{}
|
||||
|
||||
/// constructor
|
||||
subchroma_image_view( const point_t& y_dimensions
|
||||
, const point_t& v_dimensions
|
||||
, const point_t& u_dimensions
|
||||
subchroma_image_view( point_t const& y_dimensions
|
||||
, point_t const& v_dimensions
|
||||
, point_t const& u_dimensions
|
||||
, const Locator& locator
|
||||
)
|
||||
: image_view< Locator >( y_dimensions, locator )
|
||||
@@ -248,9 +248,9 @@ public:
|
||||
point_t v_ssfactors() const { return point_t( get_deref_fn().vx_ssfactor(), get_deref_fn().vx_ssfactor() ); }
|
||||
point_t u_ssfactors() const { return point_t( get_deref_fn().ux_ssfactor(), get_deref_fn().ux_ssfactor() ); }
|
||||
|
||||
const point_t& y_dimension() const { return _y_dimensions; }
|
||||
const point_t& v_dimension() const { return _v_dimensions; }
|
||||
const point_t& u_dimension() const { return _u_dimensions; }
|
||||
point_t const& y_dimension() const { return _y_dimensions; }
|
||||
point_t const& v_dimension() const { return _v_dimensions; }
|
||||
point_t const& u_dimension() const { return _u_dimensions; }
|
||||
|
||||
const plane_locator_t& y_plane() const { return get_deref_fn().y_locator(); }
|
||||
const plane_locator_t& v_plane() const { return get_deref_fn().v_locator(); }
|
||||
|
||||
@@ -45,16 +45,17 @@ namespace detail {
|
||||
/// \ingroup Histogram-Helpers
|
||||
///
|
||||
template <std::size_t Index, typename... T>
|
||||
inline typename std::enable_if<Index == sizeof...(T), void>::type
|
||||
hash_tuple_impl(std::size_t&, std::tuple<T...> const&)
|
||||
inline auto hash_tuple_impl(std::size_t&, std::tuple<T...> const&)
|
||||
-> typename std::enable_if<Index == sizeof...(T), void>::type
|
||||
{
|
||||
// terminating case
|
||||
}
|
||||
|
||||
/// \ingroup Histogram-Helpers
|
||||
///
|
||||
template <std::size_t Index, typename... T>
|
||||
inline typename std::enable_if<Index != sizeof...(T), void>::type
|
||||
hash_tuple_impl(std::size_t& seed, std::tuple<T...> const& t)
|
||||
inline auto hash_tuple_impl(std::size_t& seed, std::tuple<T...> const& t)
|
||||
-> typename std::enable_if<Index != sizeof...(T), void>::type
|
||||
{
|
||||
boost::hash_combine(seed, std::get<Index>(t));
|
||||
hash_tuple_impl<Index + 1>(seed, t);
|
||||
@@ -72,7 +73,7 @@ inline typename std::enable_if<Index != sizeof...(T), void>::type
|
||||
template <typename... T>
|
||||
struct hash_tuple
|
||||
{
|
||||
std::size_t operator()(std::tuple<T...> const& t) const
|
||||
auto operator()(std::tuple<T...> const& t) const -> std::size_t
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
hash_tuple_impl<0>(seed, t);
|
||||
@@ -665,10 +666,10 @@ void fill_histogram(
|
||||
/// #bins * log( #bins ) by sorting the keys and then calculating the cumulative version.
|
||||
///
|
||||
template <typename Container>
|
||||
Container cumulative_histogram(Container const&);
|
||||
auto cumulative_histogram(Container const&) -> Container;
|
||||
|
||||
template <typename... T>
|
||||
histogram<T...> cumulative_histogram(histogram<T...> const& hist)
|
||||
auto cumulative_histogram(histogram<T...> const& hist) -> histogram<T...>
|
||||
{
|
||||
using check_list = boost::mp11::mp_list<boost::has_less<T>...>;
|
||||
static_assert(
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
using x_coord_t = coord_t;
|
||||
using y_coord_t = coord_t;
|
||||
|
||||
const point_t& dimensions() const { return _view.dimensions(); }
|
||||
point_t const& dimensions() const { return _view.dimensions(); }
|
||||
x_coord_t width() const { return _view.width(); }
|
||||
y_coord_t height() const { return _view.height(); }
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
_memory(nullptr), _align_in_bytes(alignment), _alloc(alloc_in), _allocated_bytes( 0 ) {}
|
||||
|
||||
// Create with dimensions and optional initial value and alignment
|
||||
image(const point_t& dimensions,
|
||||
image(point_t const& dimensions,
|
||||
std::size_t alignment=0,
|
||||
const Alloc alloc_in = Alloc()) : _memory(nullptr), _align_in_bytes(alignment), _alloc(alloc_in)
|
||||
, _allocated_bytes( 0 )
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
allocate_and_default_construct(point_t(width,height));
|
||||
}
|
||||
|
||||
image(const point_t& dimensions,
|
||||
image(point_t const& dimensions,
|
||||
const Pixel& p_in,
|
||||
std::size_t alignment = 0,
|
||||
const Alloc alloc_in = Alloc()) : _memory(nullptr), _align_in_bytes(alignment), _alloc(alloc_in)
|
||||
@@ -247,7 +247,7 @@ public:
|
||||
/////////////////////
|
||||
|
||||
// without Allocator
|
||||
void recreate(const point_t& dims, std::size_t alignment = 0)
|
||||
void recreate(point_t const& dims, std::size_t alignment = 0)
|
||||
{
|
||||
if (dims == _view.dimensions() && _align_in_bytes == alignment)
|
||||
return;
|
||||
@@ -272,7 +272,7 @@ public:
|
||||
recreate(point_t(width, height), alignment);
|
||||
}
|
||||
|
||||
void recreate(const point_t& dims, const Pixel& p_in, std::size_t alignment = 0)
|
||||
void recreate(point_t const& dims, const Pixel& p_in, std::size_t alignment = 0)
|
||||
{
|
||||
if (dims == _view.dimensions() && _align_in_bytes == alignment)
|
||||
return;
|
||||
@@ -298,7 +298,7 @@ public:
|
||||
}
|
||||
|
||||
// with Allocator
|
||||
void recreate(const point_t& dims, std::size_t alignment, const Alloc alloc_in)
|
||||
void recreate(point_t const& dims, std::size_t alignment, const Alloc alloc_in)
|
||||
{
|
||||
if (dims == _view.dimensions() && _align_in_bytes == alignment && alloc_in == _alloc)
|
||||
return;
|
||||
@@ -323,7 +323,7 @@ public:
|
||||
recreate(point_t(width, height), alignment, alloc_in);
|
||||
}
|
||||
|
||||
void recreate(const point_t& dims, const Pixel& p_in, std::size_t alignment, const Alloc alloc_in)
|
||||
void recreate(point_t const& dims, const Pixel& p_in, std::size_t alignment, const Alloc alloc_in)
|
||||
{
|
||||
if (dims == _view.dimensions() && _align_in_bytes == alignment && alloc_in == _alloc)
|
||||
return;
|
||||
@@ -369,7 +369,7 @@ private:
|
||||
catch (...) { deallocate(); throw; }
|
||||
}
|
||||
|
||||
void allocate_and_fill(const point_t& dimensions, Pixel const& p_in)
|
||||
void allocate_and_fill(point_t const& dimensions, Pixel const& p_in)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -380,7 +380,7 @@ private:
|
||||
}
|
||||
|
||||
template <typename View>
|
||||
void allocate_and_copy(const point_t& dimensions, View const& v)
|
||||
void allocate_and_copy(point_t const& dimensions, View const& v)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -545,12 +545,17 @@ bool operator!=(const image<Pixel1,IsPlanar1,Alloc1>& im1,const image<Pixel2,IsP
|
||||
/// \ingroup ImageModel
|
||||
|
||||
/// \brief Returns the non-constant-pixel view of an image
|
||||
template <typename Pixel, bool IsPlanar, typename Alloc> inline
|
||||
const typename image<Pixel,IsPlanar,Alloc>::view_t& view(image<Pixel,IsPlanar,Alloc>& img) { return img._view; }
|
||||
template <typename Pixel, bool IsPlanar, typename Alloc>
|
||||
inline auto view(image<Pixel,IsPlanar,Alloc>& img)
|
||||
-> typename image<Pixel,IsPlanar,Alloc>::view_t const&
|
||||
{
|
||||
return img._view;
|
||||
}
|
||||
|
||||
/// \brief Returns the constant-pixel view of an image
|
||||
template <typename Pixel, bool IsPlanar, typename Alloc> inline
|
||||
const typename image<Pixel,IsPlanar,Alloc>::const_view_t const_view(const image<Pixel,IsPlanar,Alloc>& img)
|
||||
template <typename Pixel, bool IsPlanar, typename Alloc>
|
||||
inline auto const_view(const image<Pixel,IsPlanar,Alloc>& img)
|
||||
-> typename image<Pixel,IsPlanar,Alloc>::const_view_t const
|
||||
{
|
||||
return static_cast<const typename image<Pixel,IsPlanar,Alloc>::const_view_t>(img._view);
|
||||
}
|
||||
|
||||
@@ -116,8 +116,7 @@ void clip_and_redistribute(SrcHist const& src_hist, DstHist& dst_hist, double cl
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \fn void non_overlapping_interpolated_clahe
|
||||
/// \ingroup AHE
|
||||
|
||||
@@ -21,9 +21,6 @@
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
|
||||
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
template <typename SrcView, typename DstView>
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
/// Histogram Equalization(HE)
|
||||
/////////////////////////////////////////
|
||||
@@ -42,7 +41,8 @@ namespace boost { namespace gil {
|
||||
/// and returns the color map used for histogram equalization.
|
||||
///
|
||||
template <typename SrcKeyType>
|
||||
std::map<SrcKeyType, SrcKeyType> histogram_equalization(histogram<SrcKeyType> const& src_hist)
|
||||
auto histogram_equalization(histogram<SrcKeyType> const& src_hist)
|
||||
-> std::map<SrcKeyType, SrcKeyType>
|
||||
{
|
||||
histogram<SrcKeyType> dst_hist;
|
||||
return histogram_equalization(src_hist, dst_hist);
|
||||
@@ -59,8 +59,8 @@ std::map<SrcKeyType, SrcKeyType> histogram_equalization(histogram<SrcKeyType> co
|
||||
/// as well as transforming the destination histogram.
|
||||
///
|
||||
template <typename SrcKeyType, typename DstKeyType>
|
||||
std::map<SrcKeyType, DstKeyType>
|
||||
histogram_equalization(histogram<SrcKeyType> const& src_hist, histogram<DstKeyType>& dst_hist)
|
||||
auto histogram_equalization(histogram<SrcKeyType> const& src_hist, histogram<DstKeyType>& dst_hist)
|
||||
-> std::map<SrcKeyType, DstKeyType>
|
||||
{
|
||||
static_assert(
|
||||
std::is_integral<SrcKeyType>::value &&
|
||||
|
||||
@@ -43,8 +43,8 @@ namespace boost { namespace gil {
|
||||
/// reference histogram and returns the color map used for histogram matching.
|
||||
///
|
||||
template <typename SrcKeyType, typename RefKeyType>
|
||||
std::map<SrcKeyType, SrcKeyType>
|
||||
histogram_matching(histogram<SrcKeyType> const& src_hist, histogram<RefKeyType> const& ref_hist)
|
||||
auto histogram_matching(histogram<SrcKeyType> const& src_hist, histogram<RefKeyType> const& ref_hist)
|
||||
-> std::map<SrcKeyType, SrcKeyType>
|
||||
{
|
||||
histogram<SrcKeyType> dst_hist;
|
||||
return histogram_matching(src_hist, ref_hist, dst_hist);
|
||||
@@ -63,10 +63,11 @@ std::map<SrcKeyType, SrcKeyType>
|
||||
/// matching as well as transforming the destination histogram.
|
||||
///
|
||||
template <typename SrcKeyType, typename RefKeyType, typename DstKeyType>
|
||||
std::map<SrcKeyType, DstKeyType> histogram_matching(
|
||||
auto histogram_matching(
|
||||
histogram<SrcKeyType> const& src_hist,
|
||||
histogram<RefKeyType> const& ref_hist,
|
||||
histogram<DstKeyType>& dst_hist)
|
||||
-> std::map<SrcKeyType, DstKeyType>
|
||||
{
|
||||
static_assert(
|
||||
std::is_integral<SrcKeyType>::value &&
|
||||
|
||||
@@ -13,17 +13,14 @@
|
||||
#include <boost/gil/gray.hpp>
|
||||
#include <boost/gil/image_processing/threshold.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace gil
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace boost { namespace gil { namespace detail {
|
||||
|
||||
enum class morphological_operation
|
||||
{
|
||||
dilation,
|
||||
erosion,
|
||||
};
|
||||
|
||||
/// \addtogroup ImageProcessing
|
||||
/// @{
|
||||
|
||||
|
||||
@@ -89,7 +89,8 @@ inline void compute_tensor_entries(
|
||||
/// in which all entries will be equal to
|
||||
/// \code 1 / (dst.size()) \endcode
|
||||
template <typename T = float, typename Allocator = std::allocator<T>>
|
||||
inline detail::kernel_2d<T, Allocator> generate_normalized_mean(std::size_t side_length)
|
||||
inline auto generate_normalized_mean(std::size_t side_length)
|
||||
-> detail::kernel_2d<T, Allocator>
|
||||
{
|
||||
if (side_length % 2 != 1)
|
||||
throw std::invalid_argument("kernel dimensions should be odd and equal");
|
||||
@@ -108,7 +109,8 @@ inline detail::kernel_2d<T, Allocator> generate_normalized_mean(std::size_t side
|
||||
///
|
||||
/// Fills supplied view with 1s (ones)
|
||||
template <typename T = float, typename Allocator = std::allocator<T>>
|
||||
inline detail::kernel_2d<T, Allocator> generate_unnormalized_mean(std::size_t side_length)
|
||||
inline auto generate_unnormalized_mean(std::size_t side_length)
|
||||
-> detail::kernel_2d<T, Allocator>
|
||||
{
|
||||
if (side_length % 2 != 1)
|
||||
throw std::invalid_argument("kernel dimensions should be odd and equal");
|
||||
@@ -127,12 +129,12 @@ inline detail::kernel_2d<T, Allocator> generate_unnormalized_mean(std::size_t si
|
||||
/// Fills supplied view with values taken from Gaussian distribution. See
|
||||
/// https://en.wikipedia.org/wiki/Gaussian_blur
|
||||
template <typename T = float, typename Allocator = std::allocator<T>>
|
||||
inline detail::kernel_2d<T, Allocator> generate_gaussian_kernel(std::size_t side_length, double sigma)
|
||||
inline auto generate_gaussian_kernel(std::size_t side_length, double sigma)
|
||||
-> detail::kernel_2d<T, Allocator>
|
||||
{
|
||||
if (side_length % 2 != 1)
|
||||
throw std::invalid_argument("kernel dimensions should be odd and equal");
|
||||
|
||||
|
||||
const double denominator = 2 * boost::gil::detail::pi * sigma * sigma;
|
||||
auto middle = side_length / 2;
|
||||
std::vector<T, Allocator> values(side_length * side_length);
|
||||
@@ -160,7 +162,8 @@ inline detail::kernel_2d<T, Allocator> generate_gaussian_kernel(std::size_t side
|
||||
/// to obtain the desired degree).
|
||||
/// https://www.researchgate.net/publication/239398674_An_Isotropic_3_3_Image_Gradient_Operator
|
||||
template <typename T = float, typename Allocator = std::allocator<T>>
|
||||
inline detail::kernel_2d<T, Allocator> generate_dx_sobel(unsigned int degree = 1)
|
||||
inline auto generate_dx_sobel(unsigned int degree = 1)
|
||||
-> detail::kernel_2d<T, Allocator>
|
||||
{
|
||||
switch (degree)
|
||||
{
|
||||
@@ -190,7 +193,8 @@ inline detail::kernel_2d<T, Allocator> generate_dx_sobel(unsigned int degree = 1
|
||||
/// to obtain the desired degree).
|
||||
/// https://www.researchgate.net/profile/Hanno_Scharr/publication/220955743_Optimal_Filters_for_Extended_Optical_Flow/links/004635151972eda98f000000/Optimal-Filters-for-Extended-Optical-Flow.pdf
|
||||
template <typename T = float, typename Allocator = std::allocator<T>>
|
||||
inline detail::kernel_2d<T, Allocator> generate_dx_scharr(unsigned int degree = 1)
|
||||
inline auto generate_dx_scharr(unsigned int degree = 1)
|
||||
-> detail::kernel_2d<T, Allocator>
|
||||
{
|
||||
switch (degree)
|
||||
{
|
||||
@@ -220,7 +224,8 @@ inline detail::kernel_2d<T, Allocator> generate_dx_scharr(unsigned int degree =
|
||||
/// to obtain the desired degree).
|
||||
/// https://www.researchgate.net/publication/239398674_An_Isotropic_3_3_Image_Gradient_Operator
|
||||
template <typename T = float, typename Allocator = std::allocator<T>>
|
||||
inline detail::kernel_2d<T, Allocator> generate_dy_sobel(unsigned int degree = 1)
|
||||
inline auto generate_dy_sobel(unsigned int degree = 1)
|
||||
-> detail::kernel_2d<T, Allocator>
|
||||
{
|
||||
switch (degree)
|
||||
{
|
||||
@@ -250,7 +255,8 @@ inline detail::kernel_2d<T, Allocator> generate_dy_sobel(unsigned int degree = 1
|
||||
/// to obtain the desired degree).
|
||||
/// https://www.researchgate.net/profile/Hanno_Scharr/publication/220955743_Optimal_Filters_for_Extended_Optical_Flow/links/004635151972eda98f000000/Optimal-Filters-for-Extended-Optical-Flow.pdf
|
||||
template <typename T = float, typename Allocator = std::allocator<T>>
|
||||
inline detail::kernel_2d<T, Allocator> generate_dy_scharr(unsigned int degree = 1)
|
||||
inline auto generate_dy_scharr(unsigned int degree = 1)
|
||||
-> detail::kernel_2d<T, Allocator>
|
||||
{
|
||||
switch (degree)
|
||||
{
|
||||
|
||||
@@ -54,9 +54,11 @@ struct dynamic_xy_step_transposed_type
|
||||
/// \ingroup ImageViewConstructors
|
||||
/// \brief Constructing image views from raw interleaved pixel data
|
||||
template <typename Iterator>
|
||||
typename type_from_x_iterator<Iterator>::view_t
|
||||
interleaved_view(std::size_t width, std::size_t height,
|
||||
Iterator pixels, std::ptrdiff_t rowsize_in_bytes) {
|
||||
auto interleaved_view(
|
||||
std::size_t width, std::size_t height,
|
||||
Iterator pixels, std::ptrdiff_t rowsize_in_bytes)
|
||||
-> typename type_from_x_iterator<Iterator>::view_t
|
||||
{
|
||||
using RView = typename type_from_x_iterator<Iterator>::view_t;
|
||||
return RView(width, height, typename RView::locator(pixels, rowsize_in_bytes));
|
||||
}
|
||||
@@ -64,8 +66,9 @@ interleaved_view(std::size_t width, std::size_t height,
|
||||
/// \ingroup ImageViewConstructors
|
||||
/// \brief Constructing image views from raw interleaved pixel data
|
||||
template <typename Iterator>
|
||||
auto interleaved_view(point<std::ptrdiff_t> dim, Iterator pixels,
|
||||
std::ptrdiff_t rowsize_in_bytes)
|
||||
auto interleaved_view(
|
||||
point<std::ptrdiff_t> dim, Iterator pixels,
|
||||
std::ptrdiff_t rowsize_in_bytes)
|
||||
-> typename type_from_x_iterator<Iterator>::view_t
|
||||
{
|
||||
using RView = typename type_from_x_iterator<Iterator>::view_t;
|
||||
@@ -77,23 +80,32 @@ auto interleaved_view(point<std::ptrdiff_t> dim, Iterator pixels,
|
||||
/////////////////////////////
|
||||
|
||||
namespace detail {
|
||||
template <typename View, bool IsMutable> struct channel_pointer_type_impl;
|
||||
template <typename View, bool IsMutable>
|
||||
struct channel_pointer_type_impl;
|
||||
|
||||
template <typename View> struct channel_pointer_type_impl<View, true> {
|
||||
using type = typename channel_type<View>::type *;
|
||||
};
|
||||
template <typename View> struct channel_pointer_type_impl<View, false> {
|
||||
using type = const typename channel_type<View>::type *;
|
||||
template <typename View>
|
||||
struct channel_pointer_type_impl<View, true>
|
||||
{
|
||||
using type = typename channel_type<View>::type*;
|
||||
};
|
||||
|
||||
template <typename View> struct channel_pointer_type
|
||||
template <typename View>
|
||||
struct channel_pointer_type_impl<View, false>
|
||||
{
|
||||
using type = const typename channel_type<View>::type*;
|
||||
};
|
||||
|
||||
template <typename View>
|
||||
struct channel_pointer_type
|
||||
: public channel_pointer_type_impl<View, view_is_mutable<View>::value> {};
|
||||
} // namespace detail
|
||||
|
||||
/// \ingroup ImageViewConstructors
|
||||
/// \brief Returns C pointer to the the channels of an interleaved homogeneous view.
|
||||
template <typename HomogeneousView>
|
||||
typename detail::channel_pointer_type<HomogeneousView>::type interleaved_view_get_raw_data(const HomogeneousView& view) {
|
||||
auto interleaved_view_get_raw_data(HomogeneousView const& view)
|
||||
-> typename detail::channel_pointer_type<HomogeneousView>::type
|
||||
{
|
||||
static_assert(!is_planar<HomogeneousView>::value && view_is_basic<HomogeneousView>::value, "");
|
||||
static_assert(std::is_pointer<typename HomogeneousView::x_iterator>::value, "");
|
||||
|
||||
@@ -103,7 +115,9 @@ typename detail::channel_pointer_type<HomogeneousView>::type interleaved_view_ge
|
||||
/// \ingroup ImageViewConstructors
|
||||
/// \brief Returns C pointer to the the channels of a given color plane of a planar homogeneous view.
|
||||
template <typename HomogeneousView>
|
||||
typename detail::channel_pointer_type<HomogeneousView>::type planar_view_get_raw_data(const HomogeneousView& view, int plane_index) {
|
||||
auto planar_view_get_raw_data(HomogeneousView const& view, int plane_index)
|
||||
-> typename detail::channel_pointer_type<HomogeneousView>::type
|
||||
{
|
||||
static_assert(is_planar<HomogeneousView>::value && view_is_basic<HomogeneousView>::value, "");
|
||||
return dynamic_at_c(view.row_begin(0),plane_index);
|
||||
}
|
||||
@@ -167,15 +181,18 @@ struct color_converted_view_type : public detail::_color_converted_view_type<Src
|
||||
/// \ingroup ImageViewTransformationsColorConvert
|
||||
/// \brief view of a different color space with a user defined color-converter
|
||||
template <typename DstP, typename View, typename CC>
|
||||
inline typename color_converted_view_type<View,DstP,CC>::type color_converted_view(const View& src,CC cc) {
|
||||
inline auto color_converted_view(View const& src,CC cc)
|
||||
-> typename color_converted_view_type<View,DstP,CC>::type
|
||||
{
|
||||
return color_converted_view_type<View,DstP,CC>::make(src,cc);
|
||||
}
|
||||
|
||||
/// \ingroup ImageViewTransformationsColorConvert
|
||||
/// \brief overload of generic color_converted_view with the default color-converter
|
||||
template <typename DstP, typename View>
|
||||
inline typename color_converted_view_type<View,DstP>::type
|
||||
color_converted_view(const View& src) {
|
||||
inline auto color_converted_view(View const& src)
|
||||
-> typename color_converted_view_type<View,DstP>::type
|
||||
{
|
||||
return color_converted_view<DstP>(src,default_color_converter());
|
||||
}
|
||||
|
||||
@@ -185,7 +202,9 @@ color_converted_view(const View& src) {
|
||||
|
||||
/// \ingroup ImageViewTransformationsFlipUD
|
||||
template <typename View>
|
||||
inline typename dynamic_y_step_type<View>::type flipped_up_down_view(const View& src) {
|
||||
inline auto flipped_up_down_view(View const& src)
|
||||
-> typename dynamic_y_step_type<View>::type
|
||||
{
|
||||
using RView = typename dynamic_y_step_type<View>::type;
|
||||
return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(0,src.height()-1),-1));
|
||||
}
|
||||
@@ -196,7 +215,9 @@ inline typename dynamic_y_step_type<View>::type flipped_up_down_view(const View&
|
||||
|
||||
/// \ingroup ImageViewTransformationsFlipLR
|
||||
template <typename View>
|
||||
inline typename dynamic_x_step_type<View>::type flipped_left_right_view(const View& src) {
|
||||
inline auto flipped_left_right_view(View const& src)
|
||||
-> typename dynamic_x_step_type<View>::type
|
||||
{
|
||||
using RView = typename dynamic_x_step_type<View>::type;
|
||||
return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(src.width()-1,0),-1,1));
|
||||
}
|
||||
@@ -207,7 +228,9 @@ inline typename dynamic_x_step_type<View>::type flipped_left_right_view(const Vi
|
||||
|
||||
/// \ingroup ImageViewTransformationsTransposed
|
||||
template <typename View>
|
||||
inline typename dynamic_xy_step_transposed_type<View>::type transposed_view(const View& src) {
|
||||
inline auto transposed_view(View const& src)
|
||||
-> typename dynamic_xy_step_transposed_type<View>::type
|
||||
{
|
||||
using RView = typename dynamic_xy_step_transposed_type<View>::type;
|
||||
return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(0,0),1,1,true));
|
||||
}
|
||||
@@ -218,7 +241,9 @@ inline typename dynamic_xy_step_transposed_type<View>::type transposed_view(cons
|
||||
|
||||
/// \ingroup ImageViewTransformations90CW
|
||||
template <typename View>
|
||||
inline typename dynamic_xy_step_transposed_type<View>::type rotated90cw_view(const View& src) {
|
||||
inline auto rotated90cw_view(View const& src)
|
||||
-> typename dynamic_xy_step_transposed_type<View>::type
|
||||
{
|
||||
using RView = typename dynamic_xy_step_transposed_type<View>::type;
|
||||
return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(0,src.height()-1),-1,1,true));
|
||||
}
|
||||
@@ -229,7 +254,9 @@ inline typename dynamic_xy_step_transposed_type<View>::type rotated90cw_view(con
|
||||
|
||||
/// \ingroup ImageViewTransformations90CCW
|
||||
template <typename View>
|
||||
inline typename dynamic_xy_step_transposed_type<View>::type rotated90ccw_view(const View& src) {
|
||||
inline auto rotated90ccw_view(View const& src)
|
||||
-> typename dynamic_xy_step_transposed_type<View>::type
|
||||
{
|
||||
using RView = typename dynamic_xy_step_transposed_type<View>::type;
|
||||
return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(src.width()-1,0),1,-1,true));
|
||||
}
|
||||
@@ -240,7 +267,9 @@ inline typename dynamic_xy_step_transposed_type<View>::type rotated90ccw_view(co
|
||||
|
||||
/// \ingroup ImageViewTransformations180
|
||||
template <typename View>
|
||||
inline typename dynamic_xy_step_type<View>::type rotated180_view(const View& src) {
|
||||
inline auto rotated180_view(View const& src)
|
||||
-> typename dynamic_xy_step_type<View>::type
|
||||
{
|
||||
using RView = typename dynamic_xy_step_type<View>::type;
|
||||
return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(src.width()-1,src.height()-1),-1,-1));
|
||||
}
|
||||
@@ -309,7 +338,7 @@ namespace detail {
|
||||
struct __nth_channel_view_basic<View,false> {
|
||||
using type = typename view_type<typename channel_type<View>::type, gray_layout_t, false, true, view_is_mutable<View>::value>::type;
|
||||
|
||||
static type make(const View& src, int n) {
|
||||
static type make(View const& src, int n) {
|
||||
using locator_t = typename type::xy_locator;
|
||||
using x_iterator_t = typename type::x_iterator;
|
||||
using x_iterator_base_t = typename iterator_adaptor_get_base<x_iterator_t>::type;
|
||||
@@ -322,7 +351,7 @@ namespace detail {
|
||||
template <typename View>
|
||||
struct __nth_channel_view_basic<View,true> {
|
||||
using type = typename view_type<typename channel_type<View>::type, gray_layout_t, false, false, view_is_mutable<View>::value>::type;
|
||||
static type make(const View& src, int n) {
|
||||
static type make(View const& src, int n) {
|
||||
using x_iterator_t = typename type::x_iterator;
|
||||
return interleaved_view(src.width(),src.height(),(x_iterator_t)&(src(0,0)[n]), src.pixels().row_size());
|
||||
}
|
||||
@@ -346,7 +375,7 @@ namespace detail {
|
||||
public:
|
||||
using type = typename __nth_channel_view_basic<View,adjacent>::type;
|
||||
|
||||
static type make(const View& src, int n) {
|
||||
static type make(View const& src, int n) {
|
||||
return __nth_channel_view_basic<View,adjacent>::make(src,n);
|
||||
}
|
||||
};
|
||||
@@ -375,11 +404,13 @@ namespace detail {
|
||||
using result_type = reference;
|
||||
|
||||
nth_channel_deref_fn(int n=0) : _n(n) {}
|
||||
template <typename P> nth_channel_deref_fn(const nth_channel_deref_fn<P>& d) : _n(d._n) {}
|
||||
template <typename P>
|
||||
nth_channel_deref_fn(const nth_channel_deref_fn<P>& d) : _n(d._n) {}
|
||||
|
||||
int _n; // the channel to use
|
||||
|
||||
result_type operator()(argument_type srcP) const {
|
||||
auto operator()(argument_type srcP) const -> result_type
|
||||
{
|
||||
return result_type(srcP[_n]);
|
||||
}
|
||||
};
|
||||
@@ -390,7 +421,7 @@ namespace detail {
|
||||
using AD = typename View::template add_deref<deref_t>;
|
||||
public:
|
||||
using type = typename AD::type;
|
||||
static type make(const View& src, int n) {
|
||||
static type make(View const& src, int n) {
|
||||
return AD::make(src, deref_t(n));
|
||||
}
|
||||
};
|
||||
@@ -409,22 +440,15 @@ private:
|
||||
using VB = detail::__nth_channel_view<View,view_is_basic<View>::value>;
|
||||
public:
|
||||
using type = typename VB::type;
|
||||
static type make(const View& src, int n) { return VB::make(src,n); }
|
||||
static type make(View const& src, int n) { return VB::make(src,n); }
|
||||
};
|
||||
|
||||
|
||||
/// \ingroup ImageViewTransformationsNthChannel
|
||||
template <typename View>
|
||||
typename nth_channel_view_type<View>::type nth_channel_view(const View& src, int n) {
|
||||
typename nth_channel_view_type<View>::type nth_channel_view(View const& src, int n) {
|
||||
return nth_channel_view_type<View>::make(src,n);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// \defgroup ImageViewTransformationsKthChannel kth_channel_view
|
||||
/// \ingroup ImageViewTransformations
|
||||
/// \brief single-channel (grayscale) view of the K-th channel of a given image_view. The channel index is a template parameter
|
||||
@@ -441,7 +465,7 @@ namespace detail {
|
||||
public:
|
||||
using type = typename view_type<channel_t, gray_layout_t, false, true, view_is_mutable<View>::value>::type;
|
||||
|
||||
static type make(const View& src) {
|
||||
static type make(View const& src) {
|
||||
using locator_t = typename type::xy_locator;
|
||||
using x_iterator_t = typename type::x_iterator;
|
||||
using x_iterator_base_t = typename iterator_adaptor_get_base<x_iterator_t>::type;
|
||||
@@ -457,7 +481,7 @@ namespace detail {
|
||||
using channel_t = typename kth_element_type<typename View::value_type, K>::type;
|
||||
public:
|
||||
using type = typename view_type<channel_t, gray_layout_t, false, false, view_is_mutable<View>::value>::type;
|
||||
static type make(const View& src) {
|
||||
static type make(View const& src) {
|
||||
using x_iterator_t = typename type::x_iterator;
|
||||
return interleaved_view(src.width(),src.height(),(x_iterator_t)&gil::at_c<K>(src(0,0)), src.pixels().row_size());
|
||||
}
|
||||
@@ -480,7 +504,7 @@ namespace detail {
|
||||
public:
|
||||
using type = typename __kth_channel_view_basic<K,View,adjacent>::type;
|
||||
|
||||
static type make(const View& src) {
|
||||
static type make(View const& src) {
|
||||
return __kth_channel_view_basic<K,View,adjacent>::make(src);
|
||||
}
|
||||
};
|
||||
@@ -512,7 +536,8 @@ namespace detail {
|
||||
using result_type = reference;
|
||||
|
||||
kth_channel_deref_fn() {}
|
||||
template <typename P> kth_channel_deref_fn(const kth_channel_deref_fn<K,P>&) {}
|
||||
template <typename P>
|
||||
kth_channel_deref_fn(const kth_channel_deref_fn<K,P>&) {}
|
||||
|
||||
result_type operator()(argument_type srcP) const {
|
||||
return result_type(gil::at_c<K>(srcP));
|
||||
@@ -525,7 +550,7 @@ namespace detail {
|
||||
using AD = typename View::template add_deref<deref_t>;
|
||||
public:
|
||||
using type = typename AD::type;
|
||||
static type make(const View& src) {
|
||||
static type make(View const& src) {
|
||||
return AD::make(src, deref_t());
|
||||
}
|
||||
};
|
||||
@@ -544,12 +569,14 @@ private:
|
||||
using VB = detail::__kth_channel_view<K,View,view_is_basic<View>::value>;
|
||||
public:
|
||||
using type = typename VB::type;
|
||||
static type make(const View& src) { return VB::make(src); }
|
||||
static type make(View const& src) { return VB::make(src); }
|
||||
};
|
||||
|
||||
/// \ingroup ImageViewTransformationsKthChannel
|
||||
template <int K, typename View>
|
||||
typename kth_channel_view_type<K,View>::type kth_channel_view(const View& src) {
|
||||
auto kth_channel_view(View const& src)
|
||||
-> typename kth_channel_view_type<K,View>::type
|
||||
{
|
||||
return kth_channel_view_type<K,View>::make(src);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@ protected:
|
||||
, _dim ( 0, 0 )
|
||||
{}
|
||||
|
||||
image_read_settings_base( const point_t& top_left
|
||||
, const point_t& dim
|
||||
image_read_settings_base( point_t const& top_left
|
||||
, point_t const& dim
|
||||
)
|
||||
: _top_left( top_left )
|
||||
, _dim ( dim )
|
||||
@@ -54,8 +54,8 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
void set( const point_t& top_left
|
||||
, const point_t& dim
|
||||
void set( point_t const& top_left
|
||||
, point_t const& dim
|
||||
)
|
||||
{
|
||||
_top_left = top_left;
|
||||
|
||||
@@ -120,8 +120,8 @@ public:
|
||||
)
|
||||
{}
|
||||
|
||||
FILE* get() { return _file.get(); }
|
||||
const FILE* get() const { return _file.get(); }
|
||||
auto get() -> FILE* { return _file.get(); }
|
||||
auto get() const -> FILE const* { return _file.get(); }
|
||||
|
||||
int getc_unchecked()
|
||||
{
|
||||
@@ -140,9 +140,7 @@ public:
|
||||
}
|
||||
|
||||
///@todo: change byte_t* to void*
|
||||
std::size_t read( byte_t* data
|
||||
, std::size_t count
|
||||
)
|
||||
auto read(byte_t* data, std::size_t count) -> std::size_t
|
||||
{
|
||||
std::size_t num_elements = fread( data
|
||||
, 1
|
||||
@@ -162,9 +160,7 @@ public:
|
||||
}
|
||||
|
||||
/// Reads array
|
||||
template< typename T
|
||||
, int N
|
||||
>
|
||||
template< typename T, int N>
|
||||
void read( T (&buf)[N] )
|
||||
{
|
||||
io_error_if( read( buf, N ) < N
|
||||
@@ -201,9 +197,7 @@ public:
|
||||
|
||||
/// Writes number of elements from a buffer
|
||||
template < typename T >
|
||||
std::size_t write( const T* buf
|
||||
, std::size_t count
|
||||
)
|
||||
auto write(T const* buf, std::size_t count) -> std::size_t
|
||||
{
|
||||
std::size_t num_elements = fwrite( buf
|
||||
, buff_item<T>::size
|
||||
|
||||
@@ -39,12 +39,8 @@ auto make_dynamic_image_writer(
|
||||
|
||||
template< typename FormatTag >
|
||||
inline
|
||||
typename get_dynamic_image_writer< std::wstring
|
||||
, FormatTag
|
||||
>::type
|
||||
make_dynamic_image_writer( const std::wstring& file_name
|
||||
, const image_write_info< FormatTag >& info
|
||||
)
|
||||
auto make_dynamic_image_writer(std::wstring const& file_name, image_write_info<FormatTag> const& info)
|
||||
-> typename get_dynamic_image_writer< std::wstring, FormatTag>::type
|
||||
{
|
||||
const char* str = detail::convert_to_native_string( file_name );
|
||||
|
||||
@@ -63,21 +59,13 @@ make_dynamic_image_writer( const std::wstring& file_name
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
|
||||
template< typename FormatTag >
|
||||
template <typename FormatTag>
|
||||
inline
|
||||
typename get_dynamic_image_writer< std::wstring
|
||||
, FormatTag
|
||||
>::type
|
||||
make_dynamic_image_writer( detail::filesystem::path const& path
|
||||
, image_write_info<FormatTag> const& info
|
||||
)
|
||||
auto make_dynamic_image_writer(detail::filesystem::path const& path, image_write_info<FormatTag> const& info)
|
||||
-> typename get_dynamic_image_writer<std::wstring, FormatTag>::type
|
||||
{
|
||||
return make_dynamic_image_writer( path.wstring()
|
||||
, info
|
||||
);
|
||||
return make_dynamic_image_writer(path.wstring(), info);
|
||||
}
|
||||
#endif // BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
|
||||
|
||||
template <typename Device, typename FormatTag>
|
||||
inline
|
||||
@@ -114,36 +102,23 @@ auto make_dynamic_image_writer(String const& file_name, FormatTag const&,
|
||||
return make_dynamic_image_writer(file_name, image_write_info<FormatTag>());
|
||||
}
|
||||
|
||||
template< typename FormatTag >
|
||||
template <typename FormatTag>
|
||||
inline
|
||||
typename get_dynamic_image_writer< std::wstring
|
||||
, FormatTag
|
||||
>::type
|
||||
make_dynamic_image_writer( const std::wstring& file_name
|
||||
, const FormatTag&
|
||||
)
|
||||
auto make_dynamic_image_writer(std::wstring const& file_name, FormatTag const&)
|
||||
-> typename get_dynamic_image_writer<std::wstring, FormatTag>::type
|
||||
{
|
||||
return make_dynamic_image_writer( file_name
|
||||
, image_write_info< FormatTag >()
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
|
||||
template< typename FormatTag >
|
||||
template <typename FormatTag>
|
||||
inline
|
||||
typename get_dynamic_image_writer< std::wstring
|
||||
, FormatTag
|
||||
>::type
|
||||
make_dynamic_image_writer( const filesystem::path& path
|
||||
, const FormatTag&
|
||||
)
|
||||
auto make_dynamic_image_writer(detail::filesystem::path const& path, FormatTag const&)
|
||||
-> typename get_dynamic_image_writer<std::wstring, FormatTag>::type
|
||||
{
|
||||
return make_dynamic_image_writer( path.wstring()
|
||||
, image_write_info< FormatTag >()
|
||||
);
|
||||
return make_dynamic_image_writer(path.wstring(), image_write_info<FormatTag>());
|
||||
}
|
||||
#endif // BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
|
||||
|
||||
|
||||
template <typename Device, typename FormatTag>
|
||||
inline
|
||||
|
||||
@@ -39,18 +39,10 @@ auto make_reader(
|
||||
typename get_reader<String, FormatTag, ConversionPolicy>::type(device, settings);
|
||||
}
|
||||
|
||||
template< typename FormatTag
|
||||
, typename ConversionPolicy
|
||||
>
|
||||
template <typename FormatTag, typename ConversionPolicy>
|
||||
inline
|
||||
typename get_reader< std::wstring
|
||||
, FormatTag
|
||||
, ConversionPolicy
|
||||
>::type
|
||||
make_reader( const std::wstring& file_name
|
||||
, const image_read_settings< FormatTag >& settings
|
||||
, const ConversionPolicy&
|
||||
)
|
||||
auto make_reader(std::wstring const &file_name, image_read_settings<FormatTag> const& settings, ConversionPolicy const&)
|
||||
-> typename get_reader<std::wstring, FormatTag, ConversionPolicy>::type
|
||||
{
|
||||
const char* str = detail::convert_to_native_string( file_name );
|
||||
|
||||
@@ -70,23 +62,12 @@ make_reader( const std::wstring& file_name
|
||||
);
|
||||
}
|
||||
|
||||
template< typename FormatTag
|
||||
, typename ConversionPolicy
|
||||
>
|
||||
template <typename FormatTag, typename ConversionPolicy>
|
||||
inline
|
||||
typename get_reader< std::wstring
|
||||
, FormatTag
|
||||
, ConversionPolicy
|
||||
>::type
|
||||
make_reader( detail::filesystem::path const& path
|
||||
, const image_read_settings< FormatTag >& settings
|
||||
, const ConversionPolicy& cc
|
||||
)
|
||||
auto make_reader(detail::filesystem::path const& path, image_read_settings<FormatTag> const& settings, ConversionPolicy const& cc)
|
||||
-> typename get_reader<std::wstring, FormatTag, ConversionPolicy>::type
|
||||
{
|
||||
return make_reader( path.wstring()
|
||||
, settings
|
||||
, cc
|
||||
);
|
||||
return make_reader(path.wstring(), settings, cc);
|
||||
}
|
||||
|
||||
template <typename Device, typename FormatTag, typename ConversionPolicy>
|
||||
@@ -132,18 +113,10 @@ auto make_reader(
|
||||
return make_reader(file_name, image_read_settings<FormatTag>(), cc);
|
||||
}
|
||||
|
||||
template< typename FormatTag
|
||||
, typename ConversionPolicy
|
||||
>
|
||||
template <typename FormatTag, typename ConversionPolicy>
|
||||
inline
|
||||
typename get_reader< std::wstring
|
||||
, FormatTag
|
||||
, ConversionPolicy
|
||||
>::type
|
||||
make_reader( const std::wstring& file_name
|
||||
, const FormatTag&
|
||||
, const ConversionPolicy& cc
|
||||
)
|
||||
auto make_reader(std::wstring const &file_name, FormatTag const&, ConversionPolicy const& cc)
|
||||
-> typename get_reader<std::wstring, FormatTag, ConversionPolicy>::type
|
||||
{
|
||||
return make_reader( file_name
|
||||
, image_read_settings< FormatTag >()
|
||||
@@ -151,23 +124,12 @@ make_reader( const std::wstring& file_name
|
||||
);
|
||||
}
|
||||
|
||||
template< typename FormatTag
|
||||
, typename ConversionPolicy
|
||||
>
|
||||
template <typename FormatTag, typename ConversionPolicy>
|
||||
inline
|
||||
typename get_reader< std::wstring
|
||||
, FormatTag
|
||||
, ConversionPolicy
|
||||
>::type
|
||||
make_reader( detail::filesystem::path const& path
|
||||
, const FormatTag&
|
||||
, const ConversionPolicy& cc
|
||||
)
|
||||
auto make_reader(detail::filesystem::path const& path, FormatTag const&, ConversionPolicy const& cc)
|
||||
-> typename get_reader<std::wstring, FormatTag, ConversionPolicy>::type
|
||||
{
|
||||
return make_reader( path.wstring()
|
||||
, image_read_settings< FormatTag >()
|
||||
, cc
|
||||
);
|
||||
return make_reader(path.wstring(), image_read_settings<FormatTag>(), cc);
|
||||
}
|
||||
|
||||
template <typename Device, typename FormatTag, typename ConversionPolicy>
|
||||
|
||||
@@ -37,14 +37,10 @@ auto make_scanline_reader(String const& file_name, FormatTag const&,
|
||||
device, image_read_settings<FormatTag>());
|
||||
}
|
||||
|
||||
template< typename FormatTag >
|
||||
template <typename FormatTag>
|
||||
inline
|
||||
typename get_scanline_reader< std::wstring
|
||||
, FormatTag
|
||||
>::type
|
||||
make_scanline_reader( const std::wstring& file_name
|
||||
, FormatTag const&
|
||||
)
|
||||
auto make_scanline_reader(std::wstring const& file_name, FormatTag const&)
|
||||
-> typename get_scanline_reader<std::wstring, FormatTag>::type
|
||||
{
|
||||
const char* str = detail::convert_to_native_string( file_name );
|
||||
|
||||
@@ -63,18 +59,12 @@ make_scanline_reader( const std::wstring& file_name
|
||||
);
|
||||
}
|
||||
|
||||
template< typename FormatTag >
|
||||
template <typename FormatTag>
|
||||
inline
|
||||
typename get_scanline_reader< std::wstring
|
||||
, FormatTag
|
||||
>::type
|
||||
make_scanline_reader( detail::filesystem::path const& path
|
||||
, FormatTag const&
|
||||
)
|
||||
auto make_scanline_reader(detail::filesystem::path const& path, FormatTag const&)
|
||||
-> typename get_scanline_reader<std::wstring, FormatTag>::type
|
||||
{
|
||||
return make_scanline_reader( path.wstring()
|
||||
, image_read_settings< FormatTag >()
|
||||
);
|
||||
return make_scanline_reader(path.wstring(), image_read_settings<FormatTag>());
|
||||
}
|
||||
|
||||
template <typename Device, typename FormatTag>
|
||||
|
||||
@@ -34,14 +34,10 @@ auto make_writer(String const& file_name, image_write_info<FormatTag> const& inf
|
||||
return typename get_writer<String, FormatTag>::type(device, info);
|
||||
}
|
||||
|
||||
template< typename FormatTag >
|
||||
template <typename FormatTag>
|
||||
inline
|
||||
typename get_writer< std::wstring
|
||||
, FormatTag
|
||||
>::type
|
||||
make_writer( const std::wstring& file_name
|
||||
, const image_write_info< FormatTag >& info
|
||||
)
|
||||
auto make_writer(std::wstring const& file_name, image_write_info<FormatTag> const& info)
|
||||
-> typename get_writer<std::wstring, FormatTag>::type
|
||||
{
|
||||
const char* str = detail::convert_to_native_string( file_name );
|
||||
|
||||
@@ -60,18 +56,12 @@ make_writer( const std::wstring& file_name
|
||||
);
|
||||
}
|
||||
|
||||
template< typename FormatTag >
|
||||
template <typename FormatTag>
|
||||
inline
|
||||
typename get_writer< std::wstring
|
||||
, FormatTag
|
||||
>::type
|
||||
make_writer( detail::filesystem::path const& path
|
||||
, const image_write_info< FormatTag >& info
|
||||
)
|
||||
auto make_writer(detail::filesystem::path const& path, image_write_info<FormatTag> const& info)
|
||||
-> typename get_writer<std::wstring, FormatTag>::type
|
||||
{
|
||||
return make_writer( path.wstring()
|
||||
, info
|
||||
);
|
||||
return make_writer(path.wstring(), info);
|
||||
}
|
||||
|
||||
template <typename Device, typename FormatTag>
|
||||
@@ -109,32 +99,22 @@ auto make_writer(String const& file_name, FormatTag const&,
|
||||
return make_writer(file_name, image_write_info<FormatTag>());
|
||||
}
|
||||
|
||||
template< typename FormatTag >
|
||||
template <typename FormatTag>
|
||||
inline
|
||||
typename get_writer< std::wstring
|
||||
, FormatTag
|
||||
>::type
|
||||
make_writer( const std::wstring& file_name
|
||||
, const FormatTag&
|
||||
)
|
||||
auto make_writer(std::wstring const &file_name, FormatTag const&)
|
||||
-> typename get_writer<std::wstring, FormatTag>::type
|
||||
{
|
||||
return make_writer( file_name
|
||||
, image_write_info< FormatTag >()
|
||||
);
|
||||
}
|
||||
|
||||
template< typename FormatTag >
|
||||
template <typename FormatTag>
|
||||
inline
|
||||
typename get_writer< std::wstring
|
||||
, FormatTag
|
||||
>::type
|
||||
make_writer( detail::filesystem::path const& path
|
||||
, const FormatTag& tag
|
||||
)
|
||||
auto make_writer(detail::filesystem::path const& path, FormatTag const& tag)
|
||||
-> typename get_writer<std::wstring, FormatTag>::type
|
||||
{
|
||||
return make_writer( path.wstring()
|
||||
, tag
|
||||
);
|
||||
return make_writer(path.wstring(), tag);
|
||||
}
|
||||
|
||||
template <typename Device, typename FormatTag>
|
||||
|
||||
@@ -21,7 +21,7 @@ template<> struct is_supported_path_spec< std::string > : std::true_type
|
||||
template<> struct is_supported_path_spec< const std::string > : std::true_type {};
|
||||
template<> struct is_supported_path_spec< std::wstring > : std::true_type {};
|
||||
template<> struct is_supported_path_spec< const std::wstring > : std::true_type {};
|
||||
template<> struct is_supported_path_spec< const char* > : std::true_type {};
|
||||
template<> struct is_supported_path_spec< char const* > : std::true_type {};
|
||||
template<> struct is_supported_path_spec< char* > : std::true_type {};
|
||||
template<> struct is_supported_path_spec< const wchar_t* > : std::true_type {};
|
||||
template<> struct is_supported_path_spec< wchar_t* > : std::true_type {};
|
||||
@@ -48,7 +48,7 @@ inline std::string convert_to_string( std::wstring const& s )
|
||||
return std::string( c, c + len );
|
||||
}
|
||||
|
||||
inline std::string convert_to_string( const char* str )
|
||||
inline std::string convert_to_string( char const* str )
|
||||
{
|
||||
return std::string( str );
|
||||
}
|
||||
@@ -63,22 +63,22 @@ inline std::string convert_to_string(filesystem::path const& path)
|
||||
return convert_to_string(path.string());
|
||||
}
|
||||
|
||||
inline const char* convert_to_native_string( char* str )
|
||||
inline char const* convert_to_native_string( char* str )
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
inline const char* convert_to_native_string( const char* str )
|
||||
inline char const* convert_to_native_string( char const* str )
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
inline const char* convert_to_native_string( const std::string& str )
|
||||
inline char const* convert_to_native_string( const std::string& str )
|
||||
{
|
||||
return str.c_str();
|
||||
}
|
||||
|
||||
inline const char* convert_to_native_string( const wchar_t* str )
|
||||
inline char const* convert_to_native_string( const wchar_t* str )
|
||||
{
|
||||
std::size_t len = wcslen( str ) + 1;
|
||||
char* c = new char[len];
|
||||
@@ -87,7 +87,7 @@ inline const char* convert_to_native_string( const wchar_t* str )
|
||||
return c;
|
||||
}
|
||||
|
||||
inline const char* convert_to_native_string( const std::wstring& str )
|
||||
inline char const* convert_to_native_string( std::wstring const& str )
|
||||
{
|
||||
std::size_t len = wcslen( str.c_str() ) + 1;
|
||||
char* c = new char[len];
|
||||
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
void setup( const point_t& /* dim */ )
|
||||
void setup( point_t const& /* dim */ )
|
||||
{
|
||||
//check_coordinates( dim );
|
||||
|
||||
@@ -88,7 +88,7 @@ private:
|
||||
//}
|
||||
}
|
||||
|
||||
void check_coordinates( const point_t& /* dim */ )
|
||||
void check_coordinates( point_t const& /* dim */ )
|
||||
{
|
||||
//using int_t = point_t::value_type;
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ public:
|
||||
|
||||
template <std::size_t D> typename axis<D>::iterator& axis_iterator() { return detail::locator_axis<D,Loc>()(concrete()); }
|
||||
template <std::size_t D> typename axis<D>::iterator const& axis_iterator() const { return detail::locator_axis<D,Loc>()(concrete()); }
|
||||
template <std::size_t D> typename axis<D>::iterator axis_iterator(const point_t& p) const { return detail::locator_axis<D,Loc>()(concrete(),p); }
|
||||
template <std::size_t D> typename axis<D>::iterator axis_iterator(point_t const& p) const { return detail::locator_axis<D,Loc>()(concrete(),p); }
|
||||
|
||||
reference operator()(x_coord_t dx, y_coord_t dy) const { return *x_at(dx,dy); }
|
||||
reference operator[](const difference_type& d) const { return *x_at(d.x,d.y); }
|
||||
@@ -176,8 +176,8 @@ namespace detail {
|
||||
|
||||
inline iterator& operator()( Loc& loc) const { return loc.x(); }
|
||||
inline iterator const& operator()(const Loc& loc) const { return loc.x(); }
|
||||
inline iterator operator()( Loc& loc, const point_t& d) const { return loc.x_at(d); }
|
||||
inline iterator operator()(const Loc& loc, const point_t& d) const { return loc.x_at(d); }
|
||||
inline iterator operator()( Loc& loc, point_t const& d) const { return loc.x_at(d); }
|
||||
inline iterator operator()(const Loc& loc, point_t const& d) const { return loc.x_at(d); }
|
||||
};
|
||||
|
||||
template <typename Loc>
|
||||
@@ -189,8 +189,8 @@ namespace detail {
|
||||
|
||||
inline iterator& operator()( Loc& loc) const { return loc.y(); }
|
||||
inline iterator const& operator()(const Loc& loc) const { return loc.y(); }
|
||||
inline iterator operator()( Loc& loc, const point_t& d) const { return loc.y_at(d); }
|
||||
inline iterator operator()(const Loc& loc, const point_t& d) const { return loc.y_at(d); }
|
||||
inline iterator operator()( Loc& loc, point_t const& d) const { return loc.y_at(d); }
|
||||
inline iterator operator()(const Loc& loc, point_t const& d) const { return loc.y_at(d); }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -121,18 +121,20 @@ struct channel_type<dereference_iterator_adaptor<I,DFn> > : public channel_type<
|
||||
/////////////////////////////
|
||||
|
||||
template <typename Iterator, typename DFn>
|
||||
struct byte_to_memunit<dereference_iterator_adaptor<Iterator,DFn> > : public byte_to_memunit<Iterator> {};
|
||||
struct byte_to_memunit<dereference_iterator_adaptor<Iterator,DFn>> : public byte_to_memunit<Iterator> {};
|
||||
|
||||
template <typename Iterator, typename DFn>
|
||||
inline typename std::iterator_traits<Iterator>::difference_type
|
||||
memunit_step(const dereference_iterator_adaptor<Iterator,DFn>& p) {
|
||||
inline auto memunit_step(dereference_iterator_adaptor<Iterator,DFn> const& p)
|
||||
-> typename std::iterator_traits<Iterator>::difference_type
|
||||
{
|
||||
return memunit_step(p.base());
|
||||
}
|
||||
|
||||
template <typename Iterator, typename DFn>
|
||||
inline typename std::iterator_traits<Iterator>::difference_type
|
||||
memunit_distance(const dereference_iterator_adaptor<Iterator,DFn>& p1,
|
||||
const dereference_iterator_adaptor<Iterator,DFn>& p2) {
|
||||
inline auto memunit_distance(dereference_iterator_adaptor<Iterator,DFn> const& p1,
|
||||
dereference_iterator_adaptor<Iterator,DFn> const& p2)
|
||||
-> typename std::iterator_traits<Iterator>::difference_type
|
||||
{
|
||||
return memunit_distance(p1.base(),p2.base());
|
||||
}
|
||||
|
||||
@@ -143,18 +145,19 @@ inline void memunit_advance(dereference_iterator_adaptor<Iterator,DFn>& p,
|
||||
}
|
||||
|
||||
template <typename Iterator, typename DFn>
|
||||
inline dereference_iterator_adaptor<Iterator,DFn>
|
||||
memunit_advanced(const dereference_iterator_adaptor<Iterator,DFn>& p,
|
||||
typename std::iterator_traits<Iterator>::difference_type diff) {
|
||||
inline auto memunit_advanced(dereference_iterator_adaptor<Iterator,DFn> const& p,
|
||||
typename std::iterator_traits<Iterator>::difference_type diff)
|
||||
-> dereference_iterator_adaptor<Iterator,DFn>
|
||||
{
|
||||
return dereference_iterator_adaptor<Iterator,DFn>(memunit_advanced(p.base(), diff), p.deref_fn());
|
||||
}
|
||||
|
||||
|
||||
template <typename Iterator, typename DFn>
|
||||
inline
|
||||
typename std::iterator_traits<dereference_iterator_adaptor<Iterator,DFn> >::reference
|
||||
memunit_advanced_ref(const dereference_iterator_adaptor<Iterator,DFn>& p,
|
||||
typename std::iterator_traits<Iterator>::difference_type diff) {
|
||||
inline auto memunit_advanced_ref(dereference_iterator_adaptor<Iterator,DFn> const& p,
|
||||
typename std::iterator_traits<Iterator>::difference_type diff)
|
||||
-> typename std::iterator_traits<dereference_iterator_adaptor<Iterator,DFn> >::reference
|
||||
{
|
||||
return *memunit_advanced(p, diff);
|
||||
}
|
||||
|
||||
|
||||
@@ -201,10 +201,16 @@ struct channel_type<planar_pixel_iterator<IC, C>>
|
||||
/////////////////////////////
|
||||
|
||||
template <typename IC, typename C>
|
||||
inline std::ptrdiff_t memunit_step(const planar_pixel_iterator<IC,C>&) { return sizeof(typename std::iterator_traits<IC>::value_type); }
|
||||
inline auto memunit_step(planar_pixel_iterator<IC,C> const&)
|
||||
-> std::ptrdiff_t
|
||||
{
|
||||
return sizeof(typename std::iterator_traits<IC>::value_type);
|
||||
}
|
||||
|
||||
template <typename IC, typename C>
|
||||
inline std::ptrdiff_t memunit_distance(const planar_pixel_iterator<IC,C>& p1, const planar_pixel_iterator<IC,C>& p2) {
|
||||
inline auto memunit_distance(planar_pixel_iterator<IC,C> const& p1, planar_pixel_iterator<IC,C> const& p2)
|
||||
-> std::ptrdiff_t
|
||||
{
|
||||
return memunit_distance(gil::at_c<0>(p1),gil::at_c<0>(p2));
|
||||
}
|
||||
|
||||
@@ -222,15 +228,18 @@ inline void memunit_advance(planar_pixel_iterator<IC,C>& p, std::ptrdiff_t diff)
|
||||
}
|
||||
|
||||
template <typename IC, typename C>
|
||||
inline planar_pixel_iterator<IC,C> memunit_advanced(const planar_pixel_iterator<IC,C>& p, std::ptrdiff_t diff) {
|
||||
inline auto memunit_advanced(planar_pixel_iterator<IC,C> const& p, std::ptrdiff_t diff)
|
||||
-> planar_pixel_iterator<IC,C>
|
||||
{
|
||||
planar_pixel_iterator<IC,C> ret=p;
|
||||
memunit_advance(ret, diff);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename ChannelPtr, typename ColorSpace>
|
||||
inline planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace>
|
||||
memunit_advanced_ref(const planar_pixel_iterator<ChannelPtr,ColorSpace>& ptr, std::ptrdiff_t diff) {
|
||||
inline auto memunit_advanced_ref(planar_pixel_iterator<ChannelPtr,ColorSpace> const& ptr, std::ptrdiff_t diff)
|
||||
-> planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace>
|
||||
{
|
||||
return planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace>(ptr, diff);
|
||||
}
|
||||
|
||||
|
||||
@@ -246,44 +246,44 @@ T& axis_value(point<T>& p)
|
||||
|
||||
/// \ingroup PointAlgorithm
|
||||
template <typename T>
|
||||
inline point<std::ptrdiff_t> iround(point<T> const& p)
|
||||
inline auto iround(point<T> const& p) -> point<std::ptrdiff_t>
|
||||
{
|
||||
static_assert(std::is_integral<T>::value, "T is not integer");
|
||||
return { static_cast<std::ptrdiff_t>(p.x), static_cast<std::ptrdiff_t>(p.y) };
|
||||
}
|
||||
|
||||
/// \ingroup PointAlgorithm
|
||||
inline point<std::ptrdiff_t> iround(point<float> const& p)
|
||||
inline auto iround(point<float> const& p) -> point<std::ptrdiff_t>
|
||||
{
|
||||
return { iround(p.x), iround(p.y) };
|
||||
}
|
||||
|
||||
/// \ingroup PointAlgorithm
|
||||
inline point<std::ptrdiff_t> iround(point<double> const& p)
|
||||
inline auto iround(point<double> const& p) -> point<std::ptrdiff_t>
|
||||
{
|
||||
return { iround(p.x), iround(p.y) };
|
||||
}
|
||||
|
||||
/// \ingroup PointAlgorithm
|
||||
inline point<std::ptrdiff_t> ifloor(point<float> const& p)
|
||||
inline auto ifloor(point<float> const& p) -> point<std::ptrdiff_t>
|
||||
{
|
||||
return { ifloor(p.x), ifloor(p.y) };
|
||||
}
|
||||
|
||||
/// \ingroup PointAlgorithm
|
||||
inline point<std::ptrdiff_t> ifloor(point<double> const& p)
|
||||
inline auto ifloor(point<double> const& p) -> point<std::ptrdiff_t>
|
||||
{
|
||||
return { ifloor(p.x), ifloor(p.y) };
|
||||
}
|
||||
|
||||
/// \ingroup PointAlgorithm
|
||||
inline point<std::ptrdiff_t> iceil(point<float> const& p)
|
||||
inline auto iceil(point<float> const& p) -> point<std::ptrdiff_t>
|
||||
{
|
||||
return { iceil(p.x), iceil(p.y) };
|
||||
}
|
||||
|
||||
/// \ingroup PointAlgorithm
|
||||
inline point<std::ptrdiff_t> iceil(point<double> const& p)
|
||||
inline auto iceil(point<double> const& p) -> point<std::ptrdiff_t>
|
||||
{
|
||||
return { iceil(p.x), iceil(p.y) };
|
||||
}
|
||||
|
||||
@@ -43,20 +43,34 @@ struct position_iterator : public iterator_facade<position_iterator<Deref,Dim>,
|
||||
using point_t = typename Deref::argument_type;
|
||||
|
||||
position_iterator() {}
|
||||
position_iterator(const point_t& p, const point_t& step, const Deref& d) : _p(p), _step(step), _d(d) {}
|
||||
position_iterator(point_t const& p, point_t const& step, Deref const& d) : _p(p), _step(step), _d(d) {}
|
||||
|
||||
position_iterator(const position_iterator& p) : _p(p._p), _step(p._step), _d(p._d) {}
|
||||
template <typename D> position_iterator(const position_iterator<D,Dim>& p) : _p(p._p), _step(p._step), _d(p._d) {}
|
||||
position_iterator& operator=(const position_iterator& p) { _p=p._p; _d=p._d; _step=p._step; return *this; }
|
||||
position_iterator(position_iterator const& p) : _p(p._p), _step(p._step), _d(p._d) {}
|
||||
|
||||
template <typename D>
|
||||
position_iterator(position_iterator<D,Dim> const& p) : _p(p._p), _step(p._step), _d(p._d) {}
|
||||
|
||||
auto operator=(position_iterator const& p) -> position_iterator&
|
||||
{
|
||||
_p=p._p;
|
||||
_d=p._d;
|
||||
_step=p._step;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const point_t& pos() const { return _p; }
|
||||
const point_t& step() const { return _step; }
|
||||
const Deref& deref_fn() const { return _d; }
|
||||
auto pos() const -> point_t const& { return _p; }
|
||||
auto step() const -> point_t const& { return _step; }
|
||||
auto deref_fn() const -> Deref const& { return _d; }
|
||||
|
||||
void set_step(difference_type s) { _step[Dim]=s; }
|
||||
/// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference
|
||||
/// We require our own reference because it is registered in iterator_traits
|
||||
reference operator[](difference_type d) const { point_t p=_p; p[Dim]+=d*_step[Dim]; return _d(p); }
|
||||
auto operator[](difference_type d) const -> reference
|
||||
{
|
||||
point_t p=_p;
|
||||
p[Dim]+=d*_step[Dim];
|
||||
return _d(p);
|
||||
}
|
||||
|
||||
private:
|
||||
point_t _p, _step;
|
||||
|
||||
@@ -98,11 +98,12 @@ private:
|
||||
using add_ref_t = typename SrcView::template add_deref<deref_t>;
|
||||
public:
|
||||
using type = typename add_ref_t::type; // the color converted view type
|
||||
static type make(const SrcView& sv) { return add_ref_t::make(sv, deref_t()); }
|
||||
static type make(SrcView const& sv) { return add_ref_t::make(sv, deref_t()); }
|
||||
};
|
||||
|
||||
template <typename DstP, typename View> inline
|
||||
typename premultiplied_view_type<View,DstP>::type premultiply_view(const View& src)
|
||||
template <typename DstP, typename View>
|
||||
inline auto premultiply_view(View const& src)
|
||||
-> typename premultiplied_view_type<View,DstP>::type
|
||||
{
|
||||
return premultiplied_view_type<View,DstP>::make(src);
|
||||
}
|
||||
|
||||
@@ -42,8 +42,7 @@ using bgr_layout_t = layout<rgb_t, mp11::mp_list_c<int, 2, 1, 0>>;
|
||||
/// \ingroup ImageViewConstructors
|
||||
/// \brief from raw RGB planar data
|
||||
template <typename IC>
|
||||
inline
|
||||
auto planar_rgb_view(
|
||||
inline auto planar_rgb_view(
|
||||
std::size_t width, std::size_t height,
|
||||
IC r, IC g, IC b,
|
||||
std::ptrdiff_t rowsize_in_bytes)
|
||||
|
||||
@@ -39,8 +39,7 @@ using abgr_layout_t = layout<rgba_t, mp11::mp_list_c<int, 3, 2, 1, 0>>;
|
||||
/// \ingroup ImageViewConstructors
|
||||
/// \brief from raw RGBA planar data
|
||||
template <typename ChannelPtr>
|
||||
inline
|
||||
auto planar_rgba_view(std::size_t width, std::size_t height,
|
||||
inline auto planar_rgba_view(std::size_t width, std::size_t height,
|
||||
ChannelPtr r, ChannelPtr g, ChannelPtr b, ChannelPtr a,
|
||||
std::ptrdiff_t rowsize_in_bytes)
|
||||
-> typename type_from_x_iterator<planar_pixel_iterator<ChannelPtr, rgba_t> >::view_t
|
||||
|
||||
@@ -47,9 +47,9 @@ public:
|
||||
using reference = typename std::iterator_traits<Iterator>::reference;
|
||||
|
||||
step_iterator_adaptor() {}
|
||||
step_iterator_adaptor(const Iterator& it, SFn step_fn=SFn()) : parent_t(it), _step_fn(step_fn) {}
|
||||
step_iterator_adaptor(Iterator const& it, SFn step_fn=SFn()) : parent_t(it), _step_fn(step_fn) {}
|
||||
|
||||
difference_type step() const { return _step_fn.step(); }
|
||||
auto step() const -> difference_type { return _step_fn.step(); }
|
||||
|
||||
protected:
|
||||
SFn _step_fn;
|
||||
@@ -59,7 +59,11 @@ private:
|
||||
void increment() { _step_fn.advance(this->base_reference(),1); }
|
||||
void decrement() { _step_fn.advance(this->base_reference(),-1); }
|
||||
void advance(base_difference_type d) { _step_fn.advance(this->base_reference(),d); }
|
||||
difference_type distance_to(const step_iterator_adaptor& it) const { return _step_fn.difference(this->base_reference(),it.base_reference()); }
|
||||
|
||||
auto distance_to(step_iterator_adaptor const& it) const -> difference_type
|
||||
{
|
||||
return _step_fn.difference(this->base_reference(),it.base_reference());
|
||||
}
|
||||
};
|
||||
|
||||
// although iterator_adaptor defines these, the default implementation computes distance and compares for zero.
|
||||
@@ -124,11 +128,15 @@ struct memunit_step_fn {
|
||||
|
||||
memunit_step_fn(difference_type step=memunit_step(Iterator())) : _step(step) {}
|
||||
|
||||
difference_type difference(const Iterator& it1, const Iterator& it2) const { return memunit_distance(it1,it2)/_step; }
|
||||
void advance(Iterator& it, difference_type d) const { memunit_advance(it,d*_step); }
|
||||
difference_type step() const { return _step; }
|
||||
auto difference(Iterator const& it1, Iterator const& it2) const -> difference_type
|
||||
{
|
||||
return memunit_distance(it1,it2)/_step;
|
||||
}
|
||||
|
||||
void advance(Iterator& it, difference_type d) const { memunit_advance(it,d*_step); }
|
||||
auto step() const -> difference_type { return _step; }
|
||||
|
||||
void set_step(std::ptrdiff_t step) { _step=step; }
|
||||
void set_step(std::ptrdiff_t step) { _step=step; }
|
||||
private:
|
||||
BOOST_GIL_CLASS_REQUIRE(Iterator, boost::gil, MemoryBasedIteratorConcept)
|
||||
difference_type _step;
|
||||
@@ -156,12 +164,12 @@ public:
|
||||
|
||||
/// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference
|
||||
/// We require our own reference because it is registered in iterator_traits
|
||||
reference operator[](difference_type d) const { return *(*this+d); }
|
||||
auto operator[](difference_type d) const -> reference { return *(*this+d); }
|
||||
|
||||
void set_step(std::ptrdiff_t memunit_step) { this->_step_fn.set_step(memunit_step); }
|
||||
|
||||
x_iterator& base() { return parent_t::base_reference(); }
|
||||
x_iterator const& base() const { return parent_t::base_reference(); }
|
||||
auto base() -> x_iterator& { return parent_t::base_reference(); }
|
||||
auto base() const -> x_iterator const& { return parent_t::base_reference(); }
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
@@ -215,11 +223,12 @@ template <typename Iterator>
|
||||
struct byte_to_memunit<memory_based_step_iterator<Iterator>> : public byte_to_memunit<Iterator> {};
|
||||
|
||||
template <typename Iterator>
|
||||
inline std::ptrdiff_t memunit_step(const memory_based_step_iterator<Iterator>& p) { return p.step(); }
|
||||
inline auto memunit_step(memory_based_step_iterator<Iterator> const& p) -> std::ptrdiff_t { return p.step(); }
|
||||
|
||||
template <typename Iterator>
|
||||
inline std::ptrdiff_t memunit_distance(const memory_based_step_iterator<Iterator>& p1,
|
||||
const memory_based_step_iterator<Iterator>& p2) {
|
||||
inline auto memunit_distance(memory_based_step_iterator<Iterator> const& p1, memory_based_step_iterator<Iterator> const& p2)
|
||||
-> std::ptrdiff_t
|
||||
{
|
||||
return memunit_distance(p1.base(),p2.base());
|
||||
}
|
||||
|
||||
@@ -230,16 +239,16 @@ inline void memunit_advance(memory_based_step_iterator<Iterator>& p,
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
inline memory_based_step_iterator<Iterator>
|
||||
memunit_advanced(const memory_based_step_iterator<Iterator>& p,
|
||||
std::ptrdiff_t diff) {
|
||||
inline auto memunit_advanced(const memory_based_step_iterator<Iterator>& p, std::ptrdiff_t diff)
|
||||
-> memory_based_step_iterator<Iterator>
|
||||
{
|
||||
return memory_based_step_iterator<Iterator>(memunit_advanced(p.base(), diff),p.step());
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
inline typename std::iterator_traits<Iterator>::reference
|
||||
memunit_advanced_ref(const memory_based_step_iterator<Iterator>& p,
|
||||
std::ptrdiff_t diff) {
|
||||
inline auto memunit_advanced_ref(const memory_based_step_iterator<Iterator>& p, std::ptrdiff_t diff)
|
||||
-> typename std::iterator_traits<Iterator>::reference
|
||||
{
|
||||
return memunit_advanced_ref(p.base(), diff);
|
||||
}
|
||||
|
||||
@@ -259,7 +268,10 @@ struct iterator_add_deref<memory_based_step_iterator<Iterator>,Deref> {
|
||||
|
||||
using type = memory_based_step_iterator<typename iterator_add_deref<Iterator, Deref>::type>;
|
||||
|
||||
static type make(const memory_based_step_iterator<Iterator>& it, const Deref& d) { return type(iterator_add_deref<Iterator, Deref>::make(it.base(),d),it.step()); }
|
||||
static type make(const memory_based_step_iterator<Iterator>& it, const Deref& d)
|
||||
{
|
||||
return type(iterator_add_deref<Iterator, Deref>::make(it.base(),d),it.step());
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -313,7 +325,9 @@ auto make_step_iterator_impl(
|
||||
/// The step iterator can be wrapped inside another iterator. Also, it may not have the
|
||||
/// type memory_based_step_iterator, but it could be a user-provided type.
|
||||
template <typename I> // Models MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept
|
||||
typename dynamic_x_step_type<I>::type make_step_iterator(const I& it, std::ptrdiff_t step) {
|
||||
inline auto make_step_iterator(I const& it, std::ptrdiff_t step)
|
||||
-> typename dynamic_x_step_type<I>::type
|
||||
{
|
||||
return detail::make_step_iterator_impl(it, step, typename is_iterator_adaptor<I>::type());
|
||||
}
|
||||
|
||||
|
||||
@@ -152,15 +152,16 @@ public:
|
||||
// reinterpret_cast is implementation-defined. Static cast is not.
|
||||
template <typename OutPtr, typename In>
|
||||
BOOST_FORCEINLINE
|
||||
OutPtr gil_reinterpret_cast(In* p)
|
||||
auto gil_reinterpret_cast(In* p) -> OutPtr
|
||||
{
|
||||
return static_cast<OutPtr>(static_cast<void*>(p));
|
||||
}
|
||||
|
||||
template <typename OutPtr, typename In> BOOST_FORCEINLINE
|
||||
const OutPtr gil_reinterpret_cast_c(const In* p)
|
||||
template <typename OutPtr, typename In>
|
||||
BOOST_FORCEINLINE
|
||||
auto gil_reinterpret_cast_c(In const* p) -> OutPtr const
|
||||
{
|
||||
return static_cast<const OutPtr>(static_cast<const void*>(p));
|
||||
return static_cast<OutPtr const>(static_cast<void const*>(p));
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
@@ -170,8 +171,8 @@ namespace detail {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class InputIter, class Size, class OutputIter>
|
||||
std::pair<InputIter, OutputIter> _copy_n(InputIter first, Size count,
|
||||
OutputIter result, std::input_iterator_tag)
|
||||
auto _copy_n(InputIter first, Size count, OutputIter result, std::input_iterator_tag)
|
||||
-> std::pair<InputIter, OutputIter>
|
||||
{
|
||||
for ( ; count > 0; --count)
|
||||
{
|
||||
@@ -183,23 +184,23 @@ std::pair<InputIter, OutputIter> _copy_n(InputIter first, Size count,
|
||||
}
|
||||
|
||||
template <class RAIter, class Size, class OutputIter>
|
||||
inline std::pair<RAIter, OutputIter>
|
||||
_copy_n(RAIter first, Size count, OutputIter result, std::random_access_iterator_tag)
|
||||
inline auto _copy_n(RAIter first, Size count, OutputIter result, std::random_access_iterator_tag)
|
||||
-> std::pair<RAIter, OutputIter>
|
||||
{
|
||||
RAIter last = first + count;
|
||||
return std::pair<RAIter, OutputIter>(last, std::copy(first, last, result));
|
||||
}
|
||||
|
||||
template <class InputIter, class Size, class OutputIter>
|
||||
inline std::pair<InputIter, OutputIter>
|
||||
_copy_n(InputIter first, Size count, OutputIter result)
|
||||
inline auto _copy_n(InputIter first, Size count, OutputIter result)
|
||||
-> std::pair<InputIter, OutputIter>
|
||||
{
|
||||
return _copy_n(first, count, result, typename std::iterator_traits<InputIter>::iterator_category());
|
||||
}
|
||||
|
||||
template <class InputIter, class Size, class OutputIter>
|
||||
inline std::pair<InputIter, OutputIter>
|
||||
copy_n(InputIter first, Size count, OutputIter result)
|
||||
inline auto copy_n(InputIter first, Size count, OutputIter result)
|
||||
-> std::pair<InputIter, OutputIter>
|
||||
{
|
||||
return detail::_copy_n(first, count, result);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user