kernel.hpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. //
  2. // Copyright 2005-2007 Adobe Systems Incorporated
  3. //
  4. // Distributed under the Boost Software License, Version 1.0
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. //
  8. #ifndef BOOST_GIL_EXTENSION_NUMERIC_KERNEL_HPP
  9. #define BOOST_GIL_EXTENSION_NUMERIC_KERNEL_HPP
  10. #include <boost/gil/utilities.hpp>
  11. #include <boost/assert.hpp>
  12. #include <algorithm>
  13. #include <array>
  14. #include <cstddef>
  15. #include <memory>
  16. #include <vector>
  17. namespace boost { namespace gil {
  18. // Definitions of 1D fixed-size and variable-size kernels and related operations
  19. namespace detail {
  20. /// \brief kernel adaptor for one-dimensional cores
  21. /// Core needs to provide size(),begin(),end(),operator[],
  22. /// value_type,iterator,const_iterator,reference,const_reference
  23. template <typename Core>
  24. class kernel_1d_adaptor : public Core {
  25. private:
  26. std::size_t _center;
  27. public:
  28. kernel_1d_adaptor() : _center(0) {}
  29. explicit kernel_1d_adaptor(std::size_t center_in)
  30. : _center(center_in)
  31. {
  32. BOOST_ASSERT(_center < this->size());
  33. }
  34. kernel_1d_adaptor(std::size_t size_in, std::size_t center_in)
  35. : Core(size_in)
  36. , _center(center_in)
  37. {
  38. BOOST_ASSERT(_center < this->size());
  39. }
  40. kernel_1d_adaptor(kernel_1d_adaptor const& k_in) : Core(k_in), _center(k_in._center) {}
  41. kernel_1d_adaptor& operator=(const kernel_1d_adaptor& k_in) {
  42. Core::operator=(k_in);
  43. _center=k_in._center;
  44. return *this;
  45. }
  46. std::size_t left_size() const
  47. {
  48. BOOST_ASSERT(_center < this->size());
  49. return _center;
  50. }
  51. std::size_t right_size() const
  52. {
  53. BOOST_ASSERT(_center < this->size());
  54. return this->size() - _center - 1;
  55. }
  56. std::size_t& center() {return _center;}
  57. const std::size_t& center() const {return _center;}
  58. };
  59. } // namespace detail
  60. /// \brief variable-size kernel
  61. template <typename T, typename Alloc = std::allocator<T> >
  62. class kernel_1d : public detail::kernel_1d_adaptor<std::vector<T,Alloc>>
  63. {
  64. using parent_t = detail::kernel_1d_adaptor<std::vector<T,Alloc>>;
  65. public:
  66. kernel_1d() {}
  67. kernel_1d(std::size_t size_in,std::size_t center_in) : parent_t(size_in,center_in) {}
  68. template <typename FwdIterator>
  69. kernel_1d(FwdIterator elements, std::size_t size_in, std::size_t center_in) : parent_t(size_in,center_in) {
  70. detail::copy_n(elements,size_in,this->begin());
  71. }
  72. kernel_1d(const kernel_1d& k_in) : parent_t(k_in) {}
  73. };
  74. /// \brief static-size kernel
  75. template <typename T,std::size_t Size>
  76. class kernel_1d_fixed : public detail::kernel_1d_adaptor<std::array<T,Size>>
  77. {
  78. using parent_t = detail::kernel_1d_adaptor<std::array<T,Size>>;
  79. public:
  80. kernel_1d_fixed() {}
  81. explicit kernel_1d_fixed(std::size_t center_in) : parent_t(center_in) {}
  82. template <typename FwdIterator>
  83. explicit kernel_1d_fixed(FwdIterator elements, std::size_t center_in) : parent_t(center_in) {
  84. detail::copy_n(elements,Size,this->begin());
  85. }
  86. kernel_1d_fixed(const kernel_1d_fixed& k_in) : parent_t(k_in) {}
  87. };
  88. /// \brief reverse a kernel
  89. template <typename Kernel>
  90. inline Kernel reverse_kernel(const Kernel& kernel) {
  91. Kernel result(kernel);
  92. result.center()=kernel.right_size();
  93. std::reverse(result.begin(), result.end());
  94. return result;
  95. }
  96. }} // namespace boost::gil
  97. #endif