Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into stl-interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
mloskot committed Jun 26, 2022
2 parents bb63229 + adddbec commit 104a589
Show file tree
Hide file tree
Showing 40 changed files with 899 additions and 221 deletions.
8 changes: 5 additions & 3 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
support at least C++14 are considered unsupported as of now.
- BREAKING: `any_color_converted_view()` is deprecated and will be removed in the next release.
Use `color_converted_view()` instead, which provides the same feature.
- BREAKING: `apply_operation` for `any_image` is deprecated and will be removed in the next release.
Use `variant2::visit` instead, which provides the same feature.
- documentation: Display that GIL is a header-only library
- Moved numeric extension to core ([PR #573](https://github.com/boostorg/gil/pull/573))
- Added support for C++17's `<filesystem>` ([PR #636](https://github.com/boostorg/gil/pull/636)).
Expand Down Expand Up @@ -327,18 +329,18 @@ linked PDF documents with detailed changes.

### Changed
- Updated the design guide and tutorial, updated syntax of concepts to the latest concepts proposal.
- In `image`, `image_view`, `any_image`, `any_image_view`:
- In `image`, `image_view`, `any_image`, `any_image_view`:
There are no longer global functions `get_width()`, `get_height()`, `get_dimensions()`, `num_channels()`.
Use methods `width()`, `height()`, `dimensions()` instead.
- In models of pixel, pixel iterator, pixel locator, image view and image:
- In models of pixel, pixel iterator, pixel locator, image view and image:
There used to be different ways of getting to a pixel, channel, color space, etc. of an image view,
pixel, locator, iterator and image (e.g. traits, member typedefs).
Now all pixel-based GIL constructs (pixels, pixel iterators, locators, image views and images) model
`PixelBasedConcept`, which means they provide the following metafunctions: `color_space_type`, `channel_mapping_type`, `is_planar`, `num_channels`
and for homogeneous constructs we also have: `channel_type`.
To get the pixel type or pixel reference/const reference type of an image, image view, locator
and pixel, use member typedefs `value_type`, `reference` and `const_reference`.
- In `locator`, `image`, `image_view`, `any_image` and `any_image_view`:
- In `locator`, `image`, `image_view`, `any_image` and `any_image_view`:
Removed `dynamic_x_step_t`, `dynamic_y_step_t`, `dynamic_xy_step_t` and `dynamic_xy_step_transposed_t`
as member typedefs of locators and image views.
Instead, there are separate concepts `HasDynamicXStepTypeConcept`, `HasDynamicYStepTypeConcept`,
Expand Down
16 changes: 8 additions & 8 deletions doc/design/dynamic_image.rst
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ GIL ``any_image_view`` and ``any_image`` are subclasses of ``variant``:
y_coord_t height() const;
};
Operations are invoked on variants via ``apply_operation`` passing a
Operations are invoked on variants via ``variant2::visit`` passing a
function object to perform the operation. The code for every allowed
type in the variant is instantiated and the appropriate instantiation
is selected via a switch statement. Since image view algorithms
Expand All @@ -129,7 +129,7 @@ pixels. There is no "any_pixel" or "any_pixel_iterator" in GIL. Such
constructs could be provided via the ``variant`` mechanism, but doing
so would result in inefficient algorithms, since the type resolution
would have to be performed per pixel. Image-level algorithms should be
implemented via ``apply_operation``. That said, many common operations
implemented via ``variant2::visit``. That said, many common operations
are shared between the static and dynamic types. In addition, all of
the image view transformations and many STL-like image view algorithms
have overloads operating on ``any_image_view``, as illustrated with
Expand Down Expand Up @@ -180,25 +180,25 @@ implemented:
template <typename View>
typename dynamic_xy_step_type<View>::type rotated180_view(const View& src) { ... }
namespace detail
{
namespace detail {
// the function, wrapped inside a function object
template <typename Result> struct rotated180_view_fn
{
typedef Result result_type;
template <typename View> result_type operator()(const View& src) const
{
{
return result_type(rotated180_view(src));
}
};
}
// overloading of the function using variant. Takes and returns run-time bound view.
// The returned view has a dynamic step
template <typename ViewTypes> inline // Models MPL Random Access Container of models of ImageViewConcept
typename dynamic_xy_step_type<any_image_view<ViewTypes> >::type rotated180_view(const any_image_view<ViewTypes>& src)
template <typename ...ViewTypes> inline
typename dynamic_xy_step_type<any_image_view<ViewTypes...>>::type rotated180_view(const any_image_view<ViewTypes...>& src)
{
return apply_operation(src,detail::rotated180_view_fn<typename dynamic_xy_step_type<any_image_view<ViewTypes> >::type>());
using result_view_t = typename dynamic_xy_step_type<any_image_view<ViewTypes...>>::type;
return variant2::visit(detail::rotated180_view_fn<result_view_t>(), src);
}
Variants should be used with caution (especially algorithms that take
Expand Down
14 changes: 7 additions & 7 deletions doc/tutorial/gradient.rst
Original file line number Diff line number Diff line change
Expand Up @@ -870,22 +870,22 @@ source view:
};
The second step is to provide an overload of ``x_luminosity_gradient`` that
takes image view variant and calls GIL's ``apply_operation`` passing it the
takes image view variant and calls ``variant2::visit`` passing it the
function object:

.. code-block:: cpp
template <typename SrcViews, typename DstView>
void x_luminosity_gradient(const any_image_view<SrcViews>& src, const DstView& dst)
template <typename ...SrcViews, typename DstView>
void x_luminosity_gradient(const any_image_view<SrcViews...>& src, const DstView& dst)
{
apply_operation(src, x_gradient_obj<DstView>(dst));
variant2::visit(x_gradient_obj<DstView>(dst), src);
}
``any_image_view<SrcViews>`` is the image view variant. It is
templated over ``SrcViews``, an enumeration of all possible view types
``any_image_view<SrcViews...>`` is the image view variant. It is
templated over ``SrcViews...``, an enumeration of all possible view types
the variant can take. ``src`` contains inside an index of the
currently instantiated type, as well as a block of memory containing
the instance. ``apply_operation`` goes through a switch statement
the instance. ``variant2::visit`` goes through a switch statement
over the index, each case of which casts the memory to the correct
view type and invokes the function object with it. Invoking an
algorithm on a variant has the overhead of one switch
Expand Down
5 changes: 3 additions & 2 deletions example/rasterizer_circle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@

#include <boost/gil.hpp>
#include <boost/gil/extension/io/png.hpp>

#include <cmath>
#include <limits>
#include <vector>

namespace gil = boost::gil;

// Demonstrates the use of a rasterizer to generate an image of a circle
// The various rasterizers available are defined in include/boost/gil/rasterization/circle.hpp,
// include/boost/gil/rasterization/ellipse.hpp and include/boost/gil/rasterization/line.hpp
// The various rasterizers available are defined in include/boost/gil/extension/rasterization/circle.hpp,
// include/boost/gil/extension/rasterization/ellipse.hpp and include/boost/gil/extension/rasterization/line.hpp
// This example uses a trigonometric rasterizer; GIL also offers the rasterizer midpoint_circle_rasterizer,
// which implements the Midpoint algorithm.
// See also:
Expand Down
30 changes: 15 additions & 15 deletions example/rasterizer_ellipse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
// http://www.boost.org/LICENSE_1_0.txt)
//

#include <boost/gil/extension/io/jpeg.hpp>
#include <boost/gil.hpp>
#include <boost/gil/extension/io/jpeg.hpp>

namespace gil = boost::gil;

// Demonstrates the use of a rasterizer to generate an image of an ellipse
// The various rasterizers available are defined in include/boost/gil/rasterization/circle.hpp,
// include/boost/gil/rasterization/ellipse.hpp and include/boost/gil/rasterization/line.hpp
// The various rasterizers available are defined in include/boost/gil/extension/rasterization/circle.hpp,
// include/boost/gil/extension/rasterization/ellipse.hpp and include/boost/gil/extension/rasterization/line.hpp
// The rasterizer used is a generalisation of the midpoint algorithm often used for drawing circle.
// This examples also shows how to create images with various pixel depth, as well as the behaviour
// in case of the rasterization of a curve that doesn't fit in a view.
Expand All @@ -25,28 +25,28 @@ namespace gil = boost::gil;
int main()
{
// Syntax for usage :-
// auto rasterizer = gil::midpoint_elliptical_rasterizer{};
// rasterizer(img_view, colour, center, semi-axes_length);
// auto rasterizer = gil::midpoint_ellipse_rasterizer{};
// rasterizer(img_view, pixel, center, semi-axes_length);
// Where
// img_view : gil view of the image on which ellipse is to be drawn.
// colour : Vector containing channel intensity values for img_view. Number of colours
// provided must be equal to the number of channels present in img_view.
// center : Array containing positive integer x co-ordinate and y co-ordinate of the center
// pixel : Pixel value for the elliptical curve to be drawn. Pixel's type must be compatible to the
// pixel type of the image view.
// center : Point containing positive integer x co-ordinate and y co-ordinate of the center
// respectively.
// semi-axes_length : Array containing positive integer lengths of horizontal semi-axis
// semi-axes_length : Point containing positive integer lengths of horizontal semi-axis
// and vertical semi-axis respectively.

gil::gray8_image_t gray_buffer_image(256, 256);
auto gray_elliptical_rasterizer = gil::midpoint_elliptical_rasterizer{};
gray_elliptical_rasterizer(view(gray_buffer_image), {128}, {128, 128}, {100, 50});
auto gray_ellipse_rasterizer = gil::midpoint_ellipse_rasterizer{};
gray_ellipse_rasterizer(view(gray_buffer_image), gil::gray8_pixel_t{128}, {128, 128}, {100, 50});

gil::rgb8_image_t rgb_buffer_image(256, 256);
auto rgb_elliptical_rasterizer = gil::midpoint_elliptical_rasterizer{};
rgb_elliptical_rasterizer(view(rgb_buffer_image), {0, 0, 255}, {128, 128}, {50, 100});
auto rgb_ellipse_rasterizer = gil::midpoint_ellipse_rasterizer{};
rgb_ellipse_rasterizer(view(rgb_buffer_image), gil::rgb8_pixel_t{0, 0, 255}, {128, 128}, {50, 100});

gil::rgb8_image_t rgb_buffer_image_out_of_bound(256, 256);
auto rgb_elliptical_rasterizer_out_of_bound = gil::midpoint_elliptical_rasterizer{};
rgb_elliptical_rasterizer_out_of_bound(view(rgb_buffer_image_out_of_bound), {255, 0, 0},
auto rgb_ellipse_rasterizer_out_of_bound = gil::midpoint_ellipse_rasterizer{};
rgb_ellipse_rasterizer_out_of_bound(view(rgb_buffer_image_out_of_bound), gil::rgb8_pixel_t{255, 0, 0},
{100, 100}, {160, 160});

gil::write_view("rasterized_ellipse_gray.jpg", view(gray_buffer_image), gil::jpeg_tag{});
Expand Down
4 changes: 2 additions & 2 deletions example/rasterizer_line.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
namespace gil = boost::gil;

// Demonstrates the use of a rasterizer to generate an image of a line
// The various rasterizers available are defined in include/boost/gil/rasterization/circle.hpp,
// include/boost/gil/rasterization/ellipse.hpp and include/boost/gil/rasterization/line.hpp
// The various rasterizers available are defined in include/boost/gil/extension/rasterization/circle.hpp,
// include/boost/gil/extension/rasterization/ellipse.hpp and include/boost/gil/extension/rasterization/line.hpp
// The rasterizer used implements the Bresenham's line algorithm.
// Multiple images are created, all of the same size, but with areas of different sizes passed to the rasterizer, resulting in different lines.
// See also:
Expand Down
52 changes: 28 additions & 24 deletions include/boost/gil/extension/dynamic_image/algorithm.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
// Copyright 2022 Marco Langer <langer.m86 at gmail dot com>
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
Expand All @@ -12,7 +13,10 @@

#include <boost/gil/algorithm.hpp>

#include <boost/variant2/variant.hpp>

#include <functional>
#include <utility>

////////////////////////////////////////////////////////////////////////////////////////
/// \file
Expand Down Expand Up @@ -43,31 +47,31 @@ struct equal_pixels_fn : binary_operation_obj<equal_pixels_fn, bool>
/// \tparam Types Model Boost.MP11-compatible list of models of ImageViewConcept
/// \tparam View Model MutableImageViewConcept
template <typename ...Types, typename View>
bool equal_pixels(any_image_view<Types...> const& src, View const& dst)
auto equal_pixels(any_image_view<Types...> const& src, View const& dst) -> bool
{
return apply_operation(
src,
std::bind(detail::equal_pixels_fn(), std::placeholders::_1, dst));
return variant2::visit(
std::bind(detail::equal_pixels_fn(), std::placeholders::_1, dst),
src);
}

/// \ingroup ImageViewSTLAlgorithmsEqualPixels
/// \tparam View Model ImageViewConcept
/// \tparam Types Model Boost.MP11-compatible list of models of MutableImageViewConcept
template <typename View, typename ...Types>
bool equal_pixels(View const& src, any_image_view<Types...> const& dst)
auto equal_pixels(View const& src, any_image_view<Types...> const& dst) -> bool
{
return apply_operation(
dst,
std::bind(detail::equal_pixels_fn(), src, std::placeholders::_1));
return variant2::visit(
std::bind(detail::equal_pixels_fn(), src, std::placeholders::_1),
dst);
}

/// \ingroup ImageViewSTLAlgorithmsEqualPixels
/// \tparam Types1 Model Boost.MP11-compatible list of models of ImageViewConcept
/// \tparam Types2 Model Boost.MP11-compatible list of models of MutableImageViewConcept
template <typename ...Types1, typename ...Types2>
bool equal_pixels(any_image_view<Types1...> const& src, any_image_view<Types2...> const& dst)
auto equal_pixels(any_image_view<Types1...> const& src, any_image_view<Types2...> const& dst) -> bool
{
return apply_operation(src, dst, detail::equal_pixels_fn());
return variant2::visit(detail::equal_pixels_fn(), src, dst);
}

namespace detail {
Expand All @@ -90,7 +94,7 @@ struct copy_pixels_fn : public binary_operation_obj<copy_pixels_fn>
template <typename ...Types, typename View>
void copy_pixels(any_image_view<Types...> const& src, View const& dst)
{
apply_operation(src, std::bind(detail::copy_pixels_fn(), std::placeholders::_1, dst));
variant2::visit(std::bind(detail::copy_pixels_fn(), std::placeholders::_1, dst), src);
}

/// \ingroup ImageViewSTLAlgorithmsCopyPixels
Expand All @@ -99,7 +103,7 @@ void copy_pixels(any_image_view<Types...> const& src, View const& dst)
template <typename ...Types, typename View>
void copy_pixels(View const& src, any_image_view<Types...> const& dst)
{
apply_operation(dst, std::bind(detail::copy_pixels_fn(), src, std::placeholders::_1));
variant2::visit(std::bind(detail::copy_pixels_fn(), src, std::placeholders::_1), dst);
}

/// \ingroup ImageViewSTLAlgorithmsCopyPixels
Expand All @@ -108,7 +112,7 @@ void copy_pixels(View const& src, any_image_view<Types...> const& dst)
template <typename ...Types1, typename ...Types2>
void copy_pixels(any_image_view<Types1...> const& src, any_image_view<Types2...> const& dst)
{
apply_operation(src, dst, detail::copy_pixels_fn());
variant2::visit(detail::copy_pixels_fn(), src, dst);
}

//forward declaration for default_color_converter (see full definition in color_convert.hpp)
Expand All @@ -122,7 +126,7 @@ template <typename ...Types, typename View, typename CC>
void copy_and_convert_pixels(any_image_view<Types...> const& src, View const& dst, CC cc)
{
using cc_fn = detail::copy_and_convert_pixels_fn<CC>;
apply_operation(src, std::bind(cc_fn{cc}, std::placeholders::_1, dst));
variant2::visit(std::bind(cc_fn{cc}, std::placeholders::_1, dst), src);
}

/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
Expand All @@ -132,7 +136,7 @@ template <typename ...Types, typename View>
void copy_and_convert_pixels(any_image_view<Types...> const& src, View const& dst)
{
using cc_fn = detail::copy_and_convert_pixels_fn<default_color_converter>;
apply_operation(src, std::bind(cc_fn{}, std::placeholders::_1, dst));
variant2::visit(std::bind(cc_fn{}, std::placeholders::_1, dst), src);
}

/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
Expand All @@ -143,7 +147,7 @@ template <typename View, typename ...Types, typename CC>
void copy_and_convert_pixels(View const& src, any_image_view<Types...> const& dst, CC cc)
{
using cc_fn = detail::copy_and_convert_pixels_fn<CC>;
apply_operation(dst, std::bind(cc_fn{cc}, src, std::placeholders::_1));
variant2::visit(std::bind(cc_fn{cc}, src, std::placeholders::_1), dst);
}

/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
Expand All @@ -153,7 +157,7 @@ template <typename View, typename ...Types>
void copy_and_convert_pixels(View const& src, any_image_view<Types...> const& dst)
{
using cc_fn = detail::copy_and_convert_pixels_fn<default_color_converter>;
apply_operation(dst, std::bind(cc_fn{}, src, std::placeholders::_1));
variant2::visit(std::bind(cc_fn{}, src, std::placeholders::_1), dst);
}

/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
Expand All @@ -165,7 +169,7 @@ void copy_and_convert_pixels(
any_image_view<Types1...> const& src,
any_image_view<Types2...> const& dst, CC cc)
{
apply_operation(src, dst, detail::copy_and_convert_pixels_fn<CC>(cc));
variant2::visit(detail::copy_and_convert_pixels_fn<CC>(cc), src, dst);
}

/// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
Expand All @@ -176,8 +180,8 @@ void copy_and_convert_pixels(
any_image_view<Types1...> const& src,
any_image_view<Types2...> const& dst)
{
apply_operation(src, dst,
detail::copy_and_convert_pixels_fn<default_color_converter>());
variant2::visit(
detail::copy_and_convert_pixels_fn<default_color_converter>(), src, dst);
}

namespace detail {
Expand All @@ -186,15 +190,15 @@ template <bool IsCompatible>
struct fill_pixels_fn1
{
template <typename V, typename Value>
static void apply(V const &src, Value const &val) { fill_pixels(src, val); }
static void apply(V const& src, Value const& val) { fill_pixels(src, val); }
};

// copy_pixels invoked on incompatible images
template <>
struct fill_pixels_fn1<false>
{
template <typename V, typename Value>
static void apply(V const &, Value const &) { throw std::bad_cast();}
static void apply(V const&, Value const&) { throw std::bad_cast();}
};

template <typename Value>
Expand Down Expand Up @@ -227,7 +231,7 @@ struct fill_pixels_fn
template <typename ...Types, typename Value>
void fill_pixels(any_image_view<Types...> const& view, Value const& val)
{
apply_operation(view, detail::fill_pixels_fn<Value>(val));
variant2::visit(detail::fill_pixels_fn<Value>(val), view);
}

namespace detail {
Expand All @@ -236,7 +240,7 @@ template <typename F>
struct for_each_pixel_fn
{
for_each_pixel_fn(F&& fun) : fun_(std::move(fun)) {}

template <typename View>
auto operator()(View const& view) -> F
{
Expand Down
Loading

0 comments on commit 104a589

Please sign in to comment.