8 #ifndef BOOST_GIL_IMAGE_VIEW_FACTORY_HPP 9 #define BOOST_GIL_IMAGE_VIEW_FACTORY_HPP 11 #include <boost/gil/color_convert.hpp> 12 #include <boost/gil/dynamic_step.hpp> 13 #include <boost/gil/gray.hpp> 14 #include <boost/gil/image_view.hpp> 15 #include <boost/gil/metafunctions.hpp> 16 #include <boost/gil/point.hpp> 17 #include <boost/gil/detail/mp11.hpp> 19 #include <boost/assert.hpp> 22 #include <type_traits> 36 namespace boost {
namespace gil {
38 struct default_color_converter;
44 template <
typename View>
50 template <
typename View>
56 template <
typename Iterator>
59 Iterator pixels, std::ptrdiff_t rowsize_in_bytes) {
61 return RView(width, height,
typename RView::locator(pixels, rowsize_in_bytes));
66 template <
typename Iterator>
68 std::ptrdiff_t rowsize_in_bytes)
72 return RView(dim,
typename RView::locator(pixels, rowsize_in_bytes));
80 template <
typename View,
bool IsMutable>
struct channel_pointer_type_impl;
82 template <
typename View>
struct channel_pointer_type_impl<View, true> {
83 using type =
typename channel_type<View>::type *;
85 template <
typename View>
struct channel_pointer_type_impl<View, false> {
86 using type =
const typename channel_type<View>::type *;
89 template <
typename View>
struct channel_pointer_type
90 :
public channel_pointer_type_impl<View, view_is_mutable<View>::value> {};
95 template <
typename HomogeneousView>
98 static_assert(std::is_pointer<typename HomogeneousView::x_iterator>::value,
"");
100 return &gil::at_c<0>(
view(0,0));
105 template <
typename HomogeneousView>
108 return dynamic_at_c(
view.row_begin(0),plane_index);
120 template <
typename SrcConstRefP,
typename DstP,
typename CC=default_color_converter >
128 DstP operator()(SrcConstRefP srcP)
const {
137 template <
typename SrcView,
typename CC,
typename DstP,
typename SrcP>
138 struct _color_converted_view_type {
141 using add_ref_t =
typename SrcView::template add_deref<deref_t>;
143 using type =
typename add_ref_t::type;
144 static type make(
const SrcView& sv,CC cc) {
return add_ref_t::make(sv,deref_t(cc));}
148 template <
typename SrcView,
typename CC,
typename DstP>
149 struct _color_converted_view_type<SrcView,CC,DstP,DstP> {
150 using type = SrcView;
151 static type make(
const SrcView& sv,CC) {
return sv;}
158 template <
typename SrcView,
typename DstP,
typename CC=default_color_converter>
162 typename SrcView::value_type> {
169 template <
typename DstP,
typename View,
typename CC>
176 template <
typename DstP,
typename View>
177 inline typename color_converted_view_type<View,DstP>::type
187 template <
typename View>
188 inline typename dynamic_y_step_type<View>::type flipped_up_down_view(
const View& src) {
189 using RView =
typename dynamic_y_step_type<View>::type;
190 return RView(src.dimensions(),
typename RView::xy_locator(src.xy_at(0,src.height()-1),-1));
198 template <
typename View>
199 inline typename dynamic_x_step_type<View>::type flipped_left_right_view(
const View& src) {
200 using RView =
typename dynamic_x_step_type<View>::type;
201 return RView(src.dimensions(),
typename RView::xy_locator(src.xy_at(src.width()-1,0),-1,1));
209 template <
typename View>
210 inline typename dynamic_xy_step_transposed_type<View>::type transposed_view(
const View& src) {
211 using RView =
typename dynamic_xy_step_transposed_type<View>::type;
212 return RView(src.height(),src.width(),
typename RView::xy_locator(src.xy_at(0,0),1,1,
true));
220 template <
typename View>
221 inline typename dynamic_xy_step_transposed_type<View>::type rotated90cw_view(
const View& src) {
222 using RView =
typename dynamic_xy_step_transposed_type<View>::type;
223 return RView(src.height(),src.width(),
typename RView::xy_locator(src.xy_at(0,src.height()-1),-1,1,
true));
231 template <
typename View>
232 inline typename dynamic_xy_step_transposed_type<View>::type rotated90ccw_view(
const View& src) {
233 using RView =
typename dynamic_xy_step_transposed_type<View>::type;
234 return RView(src.height(),src.width(),
typename RView::xy_locator(src.xy_at(src.width()-1,0),1,-1,
true));
242 template <
typename View>
243 inline typename dynamic_xy_step_type<View>::type rotated180_view(
const View& src) {
244 using RView =
typename dynamic_xy_step_type<View>::type;
245 return RView(src.dimensions(),
typename RView::xy_locator(src.xy_at(src.width()-1,src.height()-1),-1,-1));
253 template <
typename View>
254 inline View subimage_view(
256 typename View::point_t
const& topleft,
257 typename View::point_t
const& dimensions)
259 return View(dimensions, src.xy_at(topleft));
263 template <
typename View>
264 inline View subimage_view(View
const& src,
265 typename View::coord_t x_min,
266 typename View::coord_t y_min,
267 typename View::coord_t width,
268 typename View::coord_t height)
270 return View(width, height, src.xy_at(x_min, y_min));
278 template <
typename View>
280 auto subsampled_view(View
const& src,
typename View::coord_t x_step,
typename View::coord_t y_step)
281 ->
typename dynamic_xy_step_type<View>::type
283 BOOST_ASSERT(x_step > 0 && y_step > 0);
284 using view_t =
typename dynamic_xy_step_type<View>::type;
286 (src.width() + (x_step - 1)) / x_step,
287 (src.height() + (y_step - 1)) / y_step,
288 typename view_t::xy_locator(src.xy_at(0,0), x_step, y_step));
292 template <
typename View>
293 inline auto subsampled_view(View
const& src,
typename View::point_t
const& step)
294 ->
typename dynamic_xy_step_type<View>::type
296 return subsampled_view(src, step.x, step.y);
304 template <
typename View,
bool AreChannelsTogether>
struct __nth_channel_view_basic;
308 template <
typename View>
309 struct __nth_channel_view_basic<View,false> {
310 using type =
typename view_type<typename channel_type<View>::type, gray_layout_t,
false,
true, view_is_mutable<View>::value>::type;
312 static type make(
const View& src,
int n) {
313 using locator_t =
typename type::xy_locator;
314 using x_iterator_t =
typename type::x_iterator;
315 using x_iterator_base_t =
typename iterator_adaptor_get_base<x_iterator_t>::type;
316 x_iterator_t sit(x_iterator_base_t(&(src(0,0)[n])),src.pixels().pixel_size());
317 return type(src.dimensions(),locator_t(sit, src.pixels().row_size()));
322 template <
typename View>
323 struct __nth_channel_view_basic<View,true> {
324 using type =
typename view_type<typename channel_type<View>::type, gray_layout_t,
false,
false, view_is_mutable<View>::value>::type;
325 static type make(
const View& src,
int n) {
326 using x_iterator_t =
typename type::x_iterator;
327 return interleaved_view(src.width(),src.height(),(x_iterator_t)&(src(0,0)[n]), src.pixels().row_size());
331 template <
typename View,
bool IsBasic>
struct __nth_channel_view;
334 template <
typename View>
335 struct __nth_channel_view<View,true>
338 using src_x_iterator =
typename View::x_iterator;
342 static constexpr
bool adjacent =
343 !iterator_is_step<src_x_iterator>::value &&
344 (is_planar<src_x_iterator>::value || num_channels<View>::value == 1);
347 using type =
typename __nth_channel_view_basic<View,adjacent>::type;
349 static type make(
const View& src,
int n) {
350 return __nth_channel_view_basic<View,adjacent>::make(src,n);
358 template <
typename SrcP>
362 static constexpr
bool is_mutable =
365 using src_pixel_t =
typename std::remove_reference<SrcP>::type;
367 using const_ref_t =
typename src_pixel_t::const_reference;
373 using argument_type = SrcP;
374 using reference = mp11::mp_if_c<is_mutable, ref_t, value_type>;
375 using result_type = reference;
382 result_type operator()(argument_type srcP)
const {
383 return result_type(srcP[_n]);
387 template <
typename View>
struct __nth_channel_view<View,false> {
390 using AD =
typename View::template add_deref<deref_t>;
392 using type =
typename AD::type;
393 static type make(
const View& src,
int n) {
394 return AD::make(src, deref_t(n));
405 template <
typename View>
409 using VB = detail::__nth_channel_view<View,view_is_basic<View>::value>;
411 using type =
typename VB::type;
412 static type make(
const View& src,
int n) {
return VB::make(src,n); }
417 template <
typename View>
418 typename nth_channel_view_type<View>::type nth_channel_view(
const View& src,
int n) {
433 template <
int K,
typename View,
bool AreChannelsTogether>
struct __kth_channel_view_basic;
437 template <
int K,
typename View>
438 struct __kth_channel_view_basic<K,View,false> {
440 using channel_t =
typename kth_element_type<typename View::value_type,K>::type;
442 using type =
typename view_type<channel_t, gray_layout_t, false, true, view_is_mutable<View>::value>::type;
444 static type make(
const View& src) {
445 using locator_t =
typename type::xy_locator;
446 using x_iterator_t =
typename type::x_iterator;
447 using x_iterator_base_t =
typename iterator_adaptor_get_base<x_iterator_t>::type;
448 x_iterator_t sit(x_iterator_base_t(&gil::at_c<K>(src(0,0))),src.pixels().pixel_size());
449 return type(src.dimensions(),locator_t(sit, src.pixels().row_size()));
454 template <
int K,
typename View>
455 struct __kth_channel_view_basic<K,View,true> {
457 using channel_t =
typename kth_element_type<typename View::value_type, K>::type;
459 using type =
typename view_type<channel_t, gray_layout_t, false, false, view_is_mutable<View>::value>::type;
460 static type make(
const View& src) {
461 using x_iterator_t =
typename type::x_iterator;
462 return interleaved_view(src.width(),src.height(),(x_iterator_t)&gil::at_c<K>(src(0,0)), src.pixels().row_size());
466 template <
int K,
typename View,
bool IsBasic>
struct __kth_channel_view;
469 template <
int K,
typename View>
struct __kth_channel_view<K,View,true>
472 using src_x_iterator =
typename View::x_iterator;
476 static constexpr
bool adjacent =
477 !iterator_is_step<src_x_iterator>::value &&
478 (is_planar<src_x_iterator>::value || num_channels<View>::value == 1);
481 using type =
typename __kth_channel_view_basic<K,View,adjacent>::type;
483 static type make(
const View& src) {
484 return __kth_channel_view_basic<K,View,adjacent>::make(src);
494 template <
int K,
typename SrcP>
497 static constexpr
bool is_mutable =
501 using src_pixel_t =
typename std::remove_reference<SrcP>::type;
502 using channel_t =
typename kth_element_type<src_pixel_t, K>::type;
503 using const_ref_t =
typename src_pixel_t::const_reference;
510 using argument_type = SrcP;
511 using reference = mp11::mp_if_c<is_mutable, ref_t, value_type>;
512 using result_type = reference;
517 result_type operator()(argument_type srcP)
const {
518 return result_type(gil::at_c<K>(srcP));
522 template <
int K,
typename View>
struct __kth_channel_view<K,View,false> {
525 using AD =
typename View::template add_deref<deref_t>;
527 using type =
typename AD::type;
528 static type make(
const View& src) {
529 return AD::make(src, deref_t());
540 template <
int K,
typename View>
544 using VB = detail::__kth_channel_view<K,View,view_is_basic<View>::value>;
546 using type =
typename VB::type;
547 static type make(
const View& src) {
return VB::make(src); }
551 template <
int K,
typename View>
552 typename kth_channel_view_type<K,View>::type kth_channel_view(
const View& src) {
Returns the type of a transposed view that has a dynamic step along both X and Y.
Definition: image_view_factory.hpp:51
A lightweight object that interprets memory as a 2D array of pixels. Models ImageViewConcept,...
Definition: image_view.hpp:53
Represents a pixel value (a container of channels). Models: HomogeneousColorBaseValueConcept,...
Definition: metafunctions.hpp:23
Function object that given a source pixel, returns it converted to a given color space and channel de...
Definition: image_view_factory.hpp:121
Returns the type of a view that has a dynamic step along both X and Y.
Definition: dynamic_step.hpp:27
Given a source image view type View, returns the type of an image view over a single channel of ViewI...
Definition: image_view_factory.hpp:406
Helper base class for pixel dereference adaptors.
Definition: utilities.hpp:106
Function object that returns a grayscale reference of the K-th channel (specified as a template param...
Definition: image_view_factory.hpp:495
Returns the type of a view that does color conversion upon dereferencing its pixels.
Definition: image_view_factory.hpp:159
Determines if the given pixel reference is mutable (i.e. its channels can be changed)
Definition: metafunctions.hpp:228
Definition: image_view_factory.hpp:40
Function object that returns a grayscale reference of the N-th channel of a given reference....
Definition: image_view_factory.hpp:360
detail::channel_pointer_type< HomogeneousView >::type planar_view_get_raw_data(const HomogeneousView &view, int plane_index)
Returns C pointer to the the channels of a given color plane of a planar homogeneous view.
Definition: image_view_factory.hpp:106
auto interleaved_view(point< std::size_t > dim, Iterator pixels, std::ptrdiff_t rowsize_in_bytes) -> typename type_from_x_iterator< Iterator >::view_t
Constructing image views from raw interleaved pixel data.
Definition: image_view_factory.hpp:67
Pixel concept that allows for changing its channels.
Definition: concepts/pixel.hpp:101
Returns the type of a homogeneous pixel reference given the channel type, layout, whether it operates...
Definition: metafunctions.hpp:266
Base template for types that model HasDynamicYStepTypeConcept.
Definition: dynamic_step.hpp:21
detail::channel_pointer_type< HomogeneousView >::type interleaved_view_get_raw_data(const HomogeneousView &view)
Returns C pointer to the the channels of an interleaved homogeneous view.
Definition: image_view_factory.hpp:96
Definition: color_convert.hpp:31
GIL's 2-dimensional view over immutable GIL pixels.
Definition: concepts/image_view.hpp:375
const image< Pixel, IsPlanar, Alloc >::view_t & view(image< Pixel, IsPlanar, Alloc > &img)
Returns the non-constant-pixel view of an image.
Definition: image.hpp:535
Given a model of a pixel, determines whether the model represents a pixel reference (as opposed to pi...
Definition: metafunctions.hpp:216
class for color-converting one pixel to another
Definition: color_convert.hpp:295
Basic views must be over basic locators.
Definition: metafunctions.hpp:129
Given a source image view type View, returns the type of an image view over a given channel of View....
Definition: image_view_factory.hpp:541
2D point both axes of which have the same dimension typeModels: Point2DConcept
Definition: locator.hpp:28