algorithm.hpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. //
  2. // Copyright 2005-2007 Adobe Systems Incorporated
  3. // Copyright 2022 Marco Langer <langer.m86 at gmail dot com>
  4. //
  5. // Distributed under the Boost Software License, Version 1.0
  6. // See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt
  8. //
  9. #ifndef BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_ALGORITHM_HPP
  10. #define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_ALGORITHM_HPP
  11. #include <boost/gil/extension/dynamic_image/any_image.hpp>
  12. #include <boost/gil/algorithm.hpp>
  13. #include <boost/variant2/variant.hpp>
  14. #include <functional>
  15. #include <utility>
  16. ////////////////////////////////////////////////////////////////////////////////////////
  17. /// \file
  18. /// \brief Some basic STL-style algorithms when applied to runtime type specified image views
  19. /// \author Lubomir Bourdev and Hailin Jin \n
  20. /// Adobe Systems Incorporated
  21. /// \date 2005-2007 \n Last updated on September 24, 2006
  22. ///
  23. ////////////////////////////////////////////////////////////////////////////////////////
  24. namespace boost { namespace gil {
  25. namespace detail {
  26. struct equal_pixels_fn : binary_operation_obj<equal_pixels_fn, bool>
  27. {
  28. template <typename V1, typename V2>
  29. BOOST_FORCEINLINE
  30. bool apply_compatible(V1 const& v1, V2 const& v2) const
  31. {
  32. return equal_pixels(v1, v2);
  33. }
  34. };
  35. } // namespace detail
  36. /// \ingroup ImageViewSTLAlgorithmsEqualPixels
  37. /// \tparam Types Model Boost.MP11-compatible list of models of ImageViewConcept
  38. /// \tparam View Model MutableImageViewConcept
  39. template <typename ...Types, typename View>
  40. auto equal_pixels(any_image_view<Types...> const& src, View const& dst) -> bool
  41. {
  42. return variant2::visit(
  43. std::bind(detail::equal_pixels_fn(), std::placeholders::_1, dst),
  44. src);
  45. }
  46. /// \ingroup ImageViewSTLAlgorithmsEqualPixels
  47. /// \tparam View Model ImageViewConcept
  48. /// \tparam Types Model Boost.MP11-compatible list of models of MutableImageViewConcept
  49. template <typename View, typename ...Types>
  50. auto equal_pixels(View const& src, any_image_view<Types...> const& dst) -> bool
  51. {
  52. return variant2::visit(
  53. std::bind(detail::equal_pixels_fn(), src, std::placeholders::_1),
  54. dst);
  55. }
  56. /// \ingroup ImageViewSTLAlgorithmsEqualPixels
  57. /// \tparam Types1 Model Boost.MP11-compatible list of models of ImageViewConcept
  58. /// \tparam Types2 Model Boost.MP11-compatible list of models of MutableImageViewConcept
  59. template <typename ...Types1, typename ...Types2>
  60. auto equal_pixels(any_image_view<Types1...> const& src, any_image_view<Types2...> const& dst) -> bool
  61. {
  62. return variant2::visit(detail::equal_pixels_fn(), src, dst);
  63. }
  64. namespace detail {
  65. struct copy_pixels_fn : public binary_operation_obj<copy_pixels_fn>
  66. {
  67. template <typename View1, typename View2>
  68. BOOST_FORCEINLINE
  69. void apply_compatible(View1 const& src, View2 const& dst) const
  70. {
  71. copy_pixels(src,dst);
  72. }
  73. };
  74. } // namespace detail
  75. /// \ingroup ImageViewSTLAlgorithmsCopyPixels
  76. /// \tparam Types Model Boost.MP11-compatible list of models of ImageViewConcept
  77. /// \tparam View Model MutableImageViewConcept
  78. template <typename ...Types, typename View>
  79. void copy_pixels(any_image_view<Types...> const& src, View const& dst)
  80. {
  81. variant2::visit(std::bind(detail::copy_pixels_fn(), std::placeholders::_1, dst), src);
  82. }
  83. /// \ingroup ImageViewSTLAlgorithmsCopyPixels
  84. /// \tparam Types Model Boost.MP11-compatible list of models of MutableImageViewConcept
  85. /// \tparam View Model ImageViewConcept
  86. template <typename ...Types, typename View>
  87. void copy_pixels(View const& src, any_image_view<Types...> const& dst)
  88. {
  89. variant2::visit(std::bind(detail::copy_pixels_fn(), src, std::placeholders::_1), dst);
  90. }
  91. /// \ingroup ImageViewSTLAlgorithmsCopyPixels
  92. /// \tparam Types1 Model Boost.MP11-compatible list of models of ImageViewConcept
  93. /// \tparam Types2 Model Boost.MP11-compatible list of models of MutableImageViewConcept
  94. template <typename ...Types1, typename ...Types2>
  95. void copy_pixels(any_image_view<Types1...> const& src, any_image_view<Types2...> const& dst)
  96. {
  97. variant2::visit(detail::copy_pixels_fn(), src, dst);
  98. }
  99. //forward declaration for default_color_converter (see full definition in color_convert.hpp)
  100. struct default_color_converter;
  101. /// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
  102. /// \tparam Types Model Boost.MP11-compatible list of models of ImageViewConcept
  103. /// \tparam View Model MutableImageViewConcept
  104. /// \tparam CC Model ColorConverterConcept
  105. template <typename ...Types, typename View, typename CC>
  106. void copy_and_convert_pixels(any_image_view<Types...> const& src, View const& dst, CC cc)
  107. {
  108. using cc_fn = detail::copy_and_convert_pixels_fn<CC>;
  109. variant2::visit(std::bind(cc_fn{cc}, std::placeholders::_1, dst), src);
  110. }
  111. /// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
  112. /// \tparam Types Model Boost.MP11-compatible list of models of ImageViewConcept
  113. /// \tparam View Model MutableImageViewConcept
  114. template <typename ...Types, typename View>
  115. void copy_and_convert_pixels(any_image_view<Types...> const& src, View const& dst)
  116. {
  117. using cc_fn = detail::copy_and_convert_pixels_fn<default_color_converter>;
  118. variant2::visit(std::bind(cc_fn{}, std::placeholders::_1, dst), src);
  119. }
  120. /// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
  121. /// \tparam View Model ImageViewConcept
  122. /// \tparam Types Model Boost.MP11-compatible list of models of MutableImageViewConcept
  123. /// \tparam CC Model ColorConverterConcept
  124. template <typename View, typename ...Types, typename CC>
  125. void copy_and_convert_pixels(View const& src, any_image_view<Types...> const& dst, CC cc)
  126. {
  127. using cc_fn = detail::copy_and_convert_pixels_fn<CC>;
  128. variant2::visit(std::bind(cc_fn{cc}, src, std::placeholders::_1), dst);
  129. }
  130. /// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
  131. /// \tparam View Model ImageViewConcept
  132. /// \tparam Type Model Boost.MP11-compatible list of models of MutableImageViewConcept
  133. template <typename View, typename ...Types>
  134. void copy_and_convert_pixels(View const& src, any_image_view<Types...> const& dst)
  135. {
  136. using cc_fn = detail::copy_and_convert_pixels_fn<default_color_converter>;
  137. variant2::visit(std::bind(cc_fn{}, src, std::placeholders::_1), dst);
  138. }
  139. /// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
  140. /// \tparam Types1 Model Boost.MP11-compatible list of models of ImageViewConcept
  141. /// \tparam Types2 Model Boost.MP11-compatible list of models of MutableImageViewConcept
  142. /// \tparam CC Model ColorConverterConcept
  143. template <typename ...Types1, typename ...Types2, typename CC>
  144. void copy_and_convert_pixels(
  145. any_image_view<Types1...> const& src,
  146. any_image_view<Types2...> const& dst, CC cc)
  147. {
  148. variant2::visit(detail::copy_and_convert_pixels_fn<CC>(cc), src, dst);
  149. }
  150. /// \ingroup ImageViewSTLAlgorithmsCopyAndConvertPixels
  151. /// \tparam Types1 Model Boost.MP11-compatible list of models of ImageViewConcept
  152. /// \tparam Types2 Model Boost.MP11-compatible list of models of MutableImageViewConcept
  153. template <typename ...Types1, typename ...Types2>
  154. void copy_and_convert_pixels(
  155. any_image_view<Types1...> const& src,
  156. any_image_view<Types2...> const& dst)
  157. {
  158. variant2::visit(
  159. detail::copy_and_convert_pixels_fn<default_color_converter>(), src, dst);
  160. }
  161. namespace detail {
  162. template <bool IsCompatible>
  163. struct fill_pixels_fn1
  164. {
  165. template <typename V, typename Value>
  166. static void apply(V const& src, Value const& val) { fill_pixels(src, val); }
  167. };
  168. // copy_pixels invoked on incompatible images
  169. template <>
  170. struct fill_pixels_fn1<false>
  171. {
  172. template <typename V, typename Value>
  173. static void apply(V const&, Value const&) { throw std::bad_cast();}
  174. };
  175. template <typename Value>
  176. struct fill_pixels_fn
  177. {
  178. fill_pixels_fn(Value const& val) : val_(val) {}
  179. using result_type = void;
  180. template <typename V>
  181. result_type operator()(V const& view) const
  182. {
  183. fill_pixels_fn1
  184. <
  185. pixels_are_compatible
  186. <
  187. typename V::value_type,
  188. Value
  189. >::value
  190. >::apply(view, val_);
  191. }
  192. Value val_;
  193. };
  194. } // namespace detail
  195. /// \ingroup ImageViewSTLAlgorithmsFillPixels
  196. /// \brief fill_pixels for any image view. The pixel to fill with must be compatible with the current view
  197. /// \tparam Types Model Boost.MP11-compatible list of models of MutableImageViewConcept
  198. template <typename ...Types, typename Value>
  199. void fill_pixels(any_image_view<Types...> const& view, Value const& val)
  200. {
  201. variant2::visit(detail::fill_pixels_fn<Value>(val), view);
  202. }
  203. namespace detail {
  204. template <typename F>
  205. struct for_each_pixel_fn
  206. {
  207. for_each_pixel_fn(F&& fun) : fun_(std::move(fun)) {}
  208. template <typename View>
  209. auto operator()(View const& view) -> F
  210. {
  211. return for_each_pixel(view, fun_);
  212. }
  213. F fun_;
  214. };
  215. } // namespace detail
  216. /// \defgroup ImageViewSTLAlgorithmsForEachPixel for_each_pixel
  217. /// \ingroup ImageViewSTLAlgorithms
  218. /// \brief std::for_each for any image views
  219. ///
  220. /// \ingroup ImageViewSTLAlgorithmsForEachPixel
  221. template <typename ...Types, typename F>
  222. auto for_each_pixel(any_image_view<Types...> const& view, F fun) -> F
  223. {
  224. return variant2::visit(detail::for_each_pixel_fn<F>(std::move(fun)), view);
  225. }
  226. }} // namespace boost::gil
  227. #endif