Skip to content

Commit

Permalink
Add transform_pixels_expr function. Add ExprTraitsBase class.
Browse files Browse the repository at this point in the history
  • Loading branch information
kmhofmann committed Mar 7, 2019
1 parent 5cae75b commit 1662c8a
Show file tree
Hide file tree
Showing 11 changed files with 164 additions and 81 deletions.
3 changes: 3 additions & 0 deletions selene/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,12 @@ target_sources(selene_img_ops PRIVATE
${CMAKE_CURRENT_LIST_DIR}/img_ops/Transformations.hpp
${CMAKE_CURRENT_LIST_DIR}/img_ops/TransformationDirections.hpp
${CMAKE_CURRENT_LIST_DIR}/img_ops/View.hpp
${CMAKE_CURRENT_LIST_DIR}/img_ops/_impl/CropExpr.hpp
${CMAKE_CURRENT_LIST_DIR}/img_ops/_impl/FlipExpr.hpp
${CMAKE_CURRENT_LIST_DIR}/img_ops/_impl/IdentityExpr.hpp
${CMAKE_CURRENT_LIST_DIR}/img_ops/_impl/ImageConversionAlphaExpr.hpp
${CMAKE_CURRENT_LIST_DIR}/img_ops/_impl/ImageConversionExpr.hpp
${CMAKE_CURRENT_LIST_DIR}/img_ops/_impl/TransformExpr.hpp
${CMAKE_CURRENT_LIST_DIR}/img_ops/_impl/TransposeExpr.hpp
)

Expand Down
11 changes: 7 additions & 4 deletions selene/img/typed/_impl/ImageExprTraits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,18 @@ namespace sln::impl {

template <typename Derived> struct ImageExprTraits;

template <typename PixelType_, typename Allocator_>
struct ImageExprTraits<Image<PixelType_, Allocator_>>
struct ExprTraitsBase
{
using PixelType = PixelType_;

constexpr static bool is_view = false;
constexpr static bool is_modifiable = true;
};

template <typename PixelType_, typename Allocator_>
struct ImageExprTraits<Image<PixelType_, Allocator_>> : public ExprTraitsBase
{
using PixelType = PixelType_;
};

template <typename PixelType_, ImageModifiability modifiability_>
struct ImageExprTraits<ImageView<PixelType_, modifiability_>>
{
Expand Down
13 changes: 10 additions & 3 deletions selene/img_ops/Algorithms.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <selene/img/typed/ImageBase.hpp>

#include <selene/img_ops/Allocate.hpp>
#include <selene/img_ops/_impl/TransformExpr.hpp>

namespace sln {

Expand Down Expand Up @@ -77,13 +78,19 @@ void transform_pixels(const ImageBase<DerivedSrc>& img_src, ImageBase<DerivedDst
* @return The destination image.
*/
template <typename PixelTypeDst, typename DerivedSrc, typename UnaryOperation>
Image<PixelTypeDst> transform_pixels(const ImageBase<DerivedSrc>& img_src, UnaryOperation op)
Image<PixelTypeDst> transform_pixels(const ImageBase<DerivedSrc>& img, UnaryOperation op)
{
Image<PixelTypeDst> img_dst({img_src.width(), img_src.height()});
transform_pixels(img_src, img_dst, op);
Image<PixelTypeDst> img_dst({img.width(), img.height()});
transform_pixels(img, img_dst, op);
return img_dst;
}

template <typename DerivedSrc, typename UnaryFunction>
auto transform_pixels_expr(const ImageExpr<DerivedSrc>& img, UnaryFunction func)
{
return impl::TransformExpr<ImageExpr<DerivedSrc>, UnaryFunction>(img, func);
}

/// @}

} // namespace sln
Expand Down
1 change: 1 addition & 0 deletions selene/img_ops/ImageConversions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <selene/img_ops/Clone.hpp>
#include <selene/img_ops/PixelConversions.hpp>
#include <selene/img_ops/_impl/ImageConversionExpr.hpp>
#include <selene/img_ops/_impl/ImageConversionAlphaExpr.hpp>

namespace sln {

Expand Down
3 changes: 1 addition & 2 deletions selene/img_ops/_impl/CropExpr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ template <typename Expr> class CropExpr;

template <typename Expr>
struct ImageExprTraits<CropExpr<Expr>>
: public ExprTraitsBase
{
using PixelType = typename Expr::PixelType;
constexpr static bool is_view = false;
constexpr static bool is_modifiable = true;
};

template <typename Expr>
Expand Down
7 changes: 3 additions & 4 deletions selene/img_ops/_impl/FlipExpr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ template <FlipDirection flip_dir, typename Expr> class FlipExpr;

template <FlipDirection flip_dir, typename Expr>
struct ImageExprTraits<FlipExpr<flip_dir, Expr>>
: public ExprTraitsBase
{
using PixelType = typename Expr::PixelType;
constexpr static bool is_view = false;
constexpr static bool is_modifiable = true;
};

template <FlipDirection flip_dir, typename Expr>
Expand All @@ -33,11 +32,11 @@ class FlipExpr : public ImageExpr<FlipExpr<flip_dir, Expr>>

explicit FlipExpr(const Expr& e) : e_(e) {}

TypedLayout layout() const noexcept { return TypedLayout{this->width(), this->height(), this->stride_bytes()}; }
const TypedLayout& layout() const noexcept { return e_.layout(); }

PixelLength width() const noexcept { return e_.width(); }
PixelLength height() const noexcept { return e_.height(); }
Stride stride_bytes() const noexcept { return Stride{PixelTraits<PixelType>::nr_bytes * this->width()}; }
Stride stride_bytes() const noexcept { return e_.stride_bytes(); }

decltype(auto) operator()(PixelIndex x, PixelIndex y) const noexcept
{
Expand Down
7 changes: 3 additions & 4 deletions selene/img_ops/_impl/IdentityExpr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ template <typename Expr> class IdentityExpr;

template <typename Expr>
struct ImageExprTraits<IdentityExpr<Expr>>
: public ExprTraitsBase
{
using PixelType = typename Expr::PixelType;
constexpr static bool is_view = false;
constexpr static bool is_modifiable = true;
};

template <typename Expr>
Expand All @@ -31,11 +30,11 @@ class IdentityExpr : public ImageExpr<IdentityExpr<Expr>>

explicit IdentityExpr(const Expr& e) : e_(e) {}

TypedLayout layout() const noexcept { return TypedLayout{this->width(), this->height(), this->stride_bytes()}; }
const TypedLayout& layout() const noexcept { return e_.layout(); }

PixelLength width() const noexcept { return e_.width(); }
PixelLength height() const noexcept { return e_.height(); }
Stride stride_bytes() const noexcept { return Stride{PixelTraits<PixelType>::nr_bytes * this->width()}; }
Stride stride_bytes() const noexcept { return e_.stride_bytes(); }

decltype(auto) operator()(PixelIndex x, PixelIndex y) const noexcept
{
Expand Down
75 changes: 75 additions & 0 deletions selene/img_ops/_impl/ImageConversionAlphaExpr.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// This file is part of the `Selene` library.
// Copyright 2017-2019 Michael Hofmann (https://github.com/kmhofmann).
// Distributed under MIT license. See accompanying LICENSE file in the top-level directory.

#ifndef SELENE_IMG_IMPL_IMAGE_CONVERSION_ALPHA_EXPR_HPP
#define SELENE_IMG_IMPL_IMAGE_CONVERSION_ALPHA_EXPR_HPP

/// @file

#include <selene/img/pixel/PixelTraits.hpp>

#include <selene/img/typed/Image.hpp>

#include <selene/img_ops/PixelConversions.hpp>

namespace sln::impl {

template <PixelFormat pixel_format_src,
PixelFormat pixel_format_dst,
typename PixelTypeSrc,
typename PixelTypeDst,
typename ElementType,
typename Expr> class ImageConversionAlphaExpr;

template <PixelFormat pixel_format_src,
PixelFormat pixel_format_dst,
typename PixelTypeSrc,
typename PixelTypeDst,
typename ElementType,
typename Expr>
struct ImageExprTraits<ImageConversionAlphaExpr<pixel_format_src, pixel_format_dst, PixelTypeSrc, PixelTypeDst, ElementType, Expr>>
: public ExprTraitsBase
{
using PixelType = PixelTypeDst;
};

template <PixelFormat pixel_format_src,
PixelFormat pixel_format_dst,
typename PixelTypeSrc,
typename PixelTypeDst,
typename ElementType,
typename Expr>
class ImageConversionAlphaExpr
: public ImageExpr<ImageConversionAlphaExpr<pixel_format_src, pixel_format_dst, PixelTypeSrc, PixelTypeDst, ElementType, Expr>>
{
public:
using PixelType = typename ImageExprTraits<ImageConversionAlphaExpr<pixel_format_src, pixel_format_dst, PixelTypeSrc, PixelTypeDst, ElementType, Expr>>::PixelType;

explicit ImageConversionAlphaExpr(const Expr& e, ElementType alpha) : e_(e), alpha_(alpha) {}

const TypedLayout& layout() const noexcept { return e_.layout(); }

PixelLength width() const noexcept { return e_.width(); }
PixelLength height() const noexcept { return e_.height(); }
Stride stride_bytes() const noexcept { return e_.stride_bytes(); }

decltype(auto) operator()(PixelIndex x, PixelIndex y) const noexcept
{
return PixelConversion<pixel_format_src, pixel_format_dst>::apply(e_(x, y), alpha_);
}

template <typename Allocator = default_bytes_allocator>
decltype(auto) eval() const noexcept
{
return Image<PixelType, Allocator>(*this);
}

private:
const Expr& e_;
ElementType alpha_;
};

} // namespace sln::impl

#endif // SELENE_IMG_IMPL_IMAGE_CONVERSION_ALPHA_EXPR_HPP
65 changes: 3 additions & 62 deletions selene/img_ops/_impl/ImageConversionExpr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ template <PixelFormat pixel_format_src,
typename PixelTypeDst,
typename Expr>
struct ImageExprTraits<ImageConversionExpr<pixel_format_src, pixel_format_dst, PixelTypeSrc, PixelTypeDst, Expr>>
: public ExprTraitsBase
{
using PixelType = PixelTypeDst;
constexpr static bool is_view = false;
constexpr static bool is_modifiable = true;
};

template <PixelFormat pixel_format_src,
Expand All @@ -46,11 +45,11 @@ class ImageConversionExpr

explicit ImageConversionExpr(const Expr& e) : e_(e) {}

TypedLayout layout() const noexcept { return TypedLayout{this->width(), this->height(), this->stride_bytes()}; }
const TypedLayout& layout() const noexcept { return e_.layout(); }

PixelLength width() const noexcept { return e_.width(); }
PixelLength height() const noexcept { return e_.height(); }
Stride stride_bytes() const noexcept { return Stride{PixelTraits<PixelType>::nr_bytes * this->width()}; }
Stride stride_bytes() const noexcept { return e_.stride_bytes(); }

decltype(auto) operator()(PixelIndex x, PixelIndex y) const noexcept
{
Expand All @@ -67,64 +66,6 @@ class ImageConversionExpr
const Expr& e_;
};

// ---

template <PixelFormat pixel_format_src,
PixelFormat pixel_format_dst,
typename PixelTypeSrc,
typename PixelTypeDst,
typename ElementType,
typename Expr> class ImageConversionAlphaExpr;

template <PixelFormat pixel_format_src,
PixelFormat pixel_format_dst,
typename PixelTypeSrc,
typename PixelTypeDst,
typename ElementType,
typename Expr>
struct ImageExprTraits<ImageConversionAlphaExpr<pixel_format_src, pixel_format_dst, PixelTypeSrc, PixelTypeDst, ElementType, Expr>>
{
using PixelType = PixelTypeDst;
constexpr static bool is_view = false;
constexpr static bool is_modifiable = true;
};

template <PixelFormat pixel_format_src,
PixelFormat pixel_format_dst,
typename PixelTypeSrc,
typename PixelTypeDst,
typename ElementType,
typename Expr>
class ImageConversionAlphaExpr
: public ImageExpr<ImageConversionAlphaExpr<pixel_format_src, pixel_format_dst, PixelTypeSrc, PixelTypeDst, ElementType, Expr>>
{
public:
using PixelType = typename ImageExprTraits<ImageConversionAlphaExpr<pixel_format_src, pixel_format_dst, PixelTypeSrc, PixelTypeDst, ElementType, Expr>>::PixelType;

explicit ImageConversionAlphaExpr(const Expr& e, ElementType alpha) : e_(e), alpha_(alpha) {}

TypedLayout layout() const noexcept { return TypedLayout{this->width(), this->height(), this->stride_bytes()}; }

PixelLength width() const noexcept { return e_.width(); }
PixelLength height() const noexcept { return e_.height(); }
Stride stride_bytes() const noexcept { return Stride{PixelTraits<PixelType>::nr_bytes * this->width()}; }

decltype(auto) operator()(PixelIndex x, PixelIndex y) const noexcept
{
return PixelConversion<pixel_format_src, pixel_format_dst>::apply(e_(x, y), alpha_);
}

template <typename Allocator = default_bytes_allocator>
decltype(auto) eval() const noexcept
{
return Image<PixelType, Allocator>(*this);
}

private:
const Expr& e_;
ElementType alpha_;
};

} // namespace sln::impl

#endif // SELENE_IMG_IMPL_IMAGE_CONVERSION_EXPR_HPP
57 changes: 57 additions & 0 deletions selene/img_ops/_impl/TransformExpr.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// This file is part of the `Selene` library.
// Copyright 2017-2019 Michael Hofmann (https://github.com/kmhofmann).
// Distributed under MIT license. See accompanying LICENSE file in the top-level directory.

#ifndef SELENE_IMG_IMPL_TRANSFORM_EXPR_HPP
#define SELENE_IMG_IMPL_TRANSFORM_EXPR_HPP

/// @file

#include <selene/img/pixel/PixelTraits.hpp>

#include <selene/img/typed/Image.hpp>

namespace sln::impl {

template <typename Expr, typename UnaryFunction> class TransformExpr;

template <typename Expr, typename UnaryFunction>
struct ImageExprTraits<TransformExpr<Expr, UnaryFunction>>
: public ExprTraitsBase
{
using PixelType = decltype(std::declval<UnaryFunction>().operator()(typename Expr::PixelType{}));
};

template <typename Expr, typename UnaryFunction>
class TransformExpr : public ImageExpr<TransformExpr<Expr, UnaryFunction>>
{
public:
using PixelType = typename ImageExprTraits<TransformExpr<Expr, UnaryFunction>>::PixelType;

explicit TransformExpr(const Expr& e, const UnaryFunction& func) : e_(e), func_(func) {}

const TypedLayout& layout() const noexcept { return e_.layout(); }

PixelLength width() const noexcept { return e_.width(); }
PixelLength height() const noexcept { return e_.height(); }
Stride stride_bytes() const noexcept { return e_.stride_bytes(); }

decltype(auto) operator()(PixelIndex x, PixelIndex y) const noexcept
{
return func_(e_(x, y));
}

template <typename Allocator = default_bytes_allocator>
decltype(auto) eval() const noexcept
{
return Image<PixelType, Allocator>(*this);
}

private:
const Expr& e_;
const UnaryFunction& func_;
};

} // namespace sln::impl

#endif // SELENE_IMG_IMPL_TRANSFORM_EXPR_HPP
3 changes: 1 addition & 2 deletions selene/img_ops/_impl/TransposeExpr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ template <bool flip_h, bool flip_v, typename Expr> class TransposeExpr;

template <bool flip_h, bool flip_v, typename Expr>
struct ImageExprTraits<TransposeExpr<flip_h, flip_v, Expr>>
: public ExprTraitsBase
{
using PixelType = typename Expr::PixelType;
constexpr static bool is_view = false;
constexpr static bool is_modifiable = true;
};

template <bool flip_h, bool flip_v, typename Expr>
Expand Down

0 comments on commit 1662c8a

Please sign in to comment.