Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
* develop:
  docs!: Announce plan to require C++17 after Boost 1.80 (#694)
  feat: Added apply_rasterizer() free function (#695)
  refactor: Ellipse rasterizer according to the comment at (#692)
  refactor: Deprecate apply_operation in favor of variant2::visit for any_image (#656)
  refactor: Replace deprecated libtiff v4.3 typedefs with C99 fixed-size integers (#685)
  fix: Automatic detection of <filesystem> header (#684)
  test: Add tiled TIFF test case to simple_all_formats
  test: Add tests for RGB to HSL (#691)
  refactor: Move RGB to HSL tests to color_convert_rgb.cpp
  refactor: Make with_tolerance reusable across other tests
  chore: Correct include guard
  fix: Add missing #include <array>
  fix: Wrong RGB -> HSL convertion (#505)
  • Loading branch information
mloskot committed Jun 27, 2022
2 parents b1d64ab + 95679b6 commit b29f3da
Show file tree
Hide file tree
Showing 60 changed files with 1,364 additions and 407 deletions.
10 changes: 7 additions & 3 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [1.80.0] - 2022-08-10

NOTICE: We are planning BREAKING switch to C++17 as minimum required C++ language version in one or two releases after Boost 1.80 ([Discussion #676](https://github.com/boostorg/gil/discussions/676))

### Added
- Added `image` constructor from compatible view ([PR #520](https://github.com/boostorg/gil/pull/520))
- Added inverse function for affine `matrix3x2` ([PR #527](https://github.com/boostorg/gil/pull/527))
Expand All @@ -28,6 +30,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 +331,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
10 changes: 3 additions & 7 deletions example/hough_transform_circle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

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

#include <iostream>
#include <limits>
Expand All @@ -33,13 +34,8 @@ int main()

const std::ptrdiff_t circle_radius = 16;
const gil::point_t circle_center = {64, 64};
const auto rasterizer = gil::midpoint_circle_rasterizer{};
std::vector<gil::point_t> circle_points(rasterizer.point_count(circle_radius));
rasterizer(circle_radius, circle_center, circle_points.begin());
for (const auto& point : circle_points)
{
input(point) = std::numeric_limits<gil::uint8_t>::max();
}
const auto rasterizer = gil::midpoint_circle_rasterizer{circle_center, circle_radius};
gil::apply_rasterizer(input, rasterizer, gil::gray8_pixel_t{255});

const auto radius_parameter =
gil::hough_parameter<std::ptrdiff_t>::from_step_count(circle_radius, 3, 3);
Expand Down
18 changes: 6 additions & 12 deletions example/rasterizer_circle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@

#include <boost/gil.hpp>
#include <boost/gil/extension/io/png.hpp>
#include <cmath>
#include <limits>
#include <vector>
#include <boost/gil/extension/rasterization/circle.hpp>

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 All @@ -29,14 +27,10 @@ int main()
gil::gray8_image_t buffer_image(size, size);
auto buffer = gil::view(buffer_image);

const gil::point_t center = {128, 128};
const std::ptrdiff_t radius = 64;
const auto rasterizer = gil::trigonometric_circle_rasterizer{};
std::vector<gil::point_t> circle_points(rasterizer.point_count(radius));
rasterizer(radius, {128, 128}, circle_points.begin());
for (const auto& point : circle_points)
{
buffer(point) = std::numeric_limits<gil::uint8_t>::max();
}
const auto rasterizer = gil::trigonometric_circle_rasterizer{center, radius};
gil::apply_rasterizer(buffer, rasterizer, gil::gray8_pixel_t{255});

gil::write_view("circle.png", buffer, gil::png_tag{});
}
31 changes: 15 additions & 16 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,29 +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{{128, 128}, {100, 50}};
gil::apply_rasterizer(view(gray_buffer_image), gray_ellipse_rasterizer, gil::gray8_pixel_t{128});

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{{128, 128}, {50, 100}};
gil::apply_rasterizer(view(rgb_buffer_image), rgb_ellipse_rasterizer, gil::rgb8_pixel_t{0, 0, 255});

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},
{100, 100}, {160, 160});
auto rgb_ellipse_rasterizer_out_of_bound = gil::midpoint_ellipse_rasterizer{{100, 100}, {160, 160}};
apply_rasterizer(view(rgb_buffer_image_out_of_bound), rgb_ellipse_rasterizer_out_of_bound, gil::rgb8_pixel_t{255, 0, 0});

gil::write_view("rasterized_ellipse_gray.jpg", view(gray_buffer_image), gil::jpeg_tag{});
gil::write_view("rasterized_ellipse_rgb.jpg", view(rgb_buffer_image), gil::jpeg_tag{});
Expand Down
19 changes: 5 additions & 14 deletions example/rasterizer_line.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@

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

#include <limits>
#include <vector>
#include <boost/gil/extension/rasterization/line.hpp>

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 All @@ -28,18 +26,11 @@ const std::ptrdiff_t size = 256;

void line_bresenham(std::ptrdiff_t width, std::ptrdiff_t height, const std::string& output_name)
{
const auto rasterizer = gil::bresenham_line_rasterizer{};
std::vector<gil::point_t> line_points(rasterizer.point_count(width, height));
const auto rasterizer = gil::bresenham_line_rasterizer{{0, 0}, {width - 1, height - 1}};

gil::gray8_image_t image(size, size);
auto view = gil::view(image);

rasterizer({0, 0}, {width - 1, height - 1}, line_points.begin());
for (const auto& point : line_points)
{
view(point) = std::numeric_limits<gil::uint8_t>::max();
}

gil::apply_rasterizer(view, rasterizer, gil::gray8_pixel_t{255});
gil::write_view(output_name, view, gil::png_tag{});
}

Expand Down
Loading

0 comments on commit b29f3da

Please sign in to comment.