ndimage_pixel.hpp 3.34 KB
Newer Older
1
#ifndef MLN_CORE_IMAGE_NDIMAGE_PIXEL_HPP
Michaël Roynard's avatar
Michaël Roynard committed
2
#define MLN_CORE_IMAGE_NDIMAGE_PIXEL_HPP
3

Michaël Roynard's avatar
Michaël Roynard committed
4
#include <mln/core/image/ndimage.hpp>
5 6 7 8

namespace mln
{

Edwin Carlinet's avatar
Edwin Carlinet committed
9 10 11 12 13 14 15 16 17
  /// \brief Pixel type definition of nd-images
  template <class T, unsigned dim, class E>
  struct ndimage_pixel;

  /******************************************/
  /****          Implementation          ****/
  /******************************************/

  namespace details
18 19
  {

Edwin Carlinet's avatar
Edwin Carlinet committed
20 21
    template <typename T, unsigned dim>
    struct ndimage_pixel_base;
22

Edwin Carlinet's avatar
Edwin Carlinet committed
23 24 25 26 27 28 29 30
    template <typename T>
    struct ndimage_pixel_base<T, 0>
    {
      using value_type = std::remove_const_t<T>;
      using reference = T&;
      using distance_type = std::ptrdiff_t;
      using size_type = unsigned;
      using pointer_type = T*;
31

Edwin Carlinet's avatar
Edwin Carlinet committed
32
      ndimage_pixel_base() = default;
33

Edwin Carlinet's avatar
Edwin Carlinet committed
34
      ndimage_pixel_base(T* ptr) : m_ptr(ptr) {}
35

36
      template <class U>
Michaël Roynard's avatar
Michaël Roynard committed
37
      ndimage_pixel_base(const ndimage_pixel_base<U, 0>& other) : m_ptr(other.m_ptr), m_index(other.m_index)
Edwin Carlinet's avatar
Edwin Carlinet committed
38 39
      {
      }
40

Edwin Carlinet's avatar
Edwin Carlinet committed
41 42
      reference val() const { return m_ptr[m_index]; }
      size_type index() const { return static_cast<size_type>(m_index); }
43

Edwin Carlinet's avatar
Edwin Carlinet committed
44 45 46
    protected:
      template <typename, unsigned>
      friend struct ndimage_pixel_base;
47

Edwin Carlinet's avatar
Edwin Carlinet committed
48 49 50 51 52 53 54 55 56 57 58 59 60 61
      template <typename, unsigned, typename>
      friend struct mln::ndimage_base;

      std::nullptr_t get_offset() const { return nullptr; }
      int get_index() const { return m_index; }
      int& get_index() { return m_index; }

    private:
      T* m_ptr;
      int m_index;
    };

    template <unsigned dim>
    struct ndimage_pixel_base<void, dim>
62
    {
Edwin Carlinet's avatar
Edwin Carlinet committed
63 64
      using site_type = mln::point<short, dim>;
      using point_type = site_type;
65

Edwin Carlinet's avatar
Edwin Carlinet committed
66 67
      site_type point() const { return m_point; }
      site_type site() const { return m_point; }
68

Edwin Carlinet's avatar
Edwin Carlinet committed
69 70 71
    protected:
      template <typename, unsigned, typename>
      friend struct mln::ndimage_base;
Edwin Carlinet's avatar
Edwin Carlinet committed
72

Edwin Carlinet's avatar
Edwin Carlinet committed
73
      auto& get_point() { return m_point; }
Michaël Roynard's avatar
Michaël Roynard committed
74
      auto get_point() const { return m_point; }
75

Edwin Carlinet's avatar
Edwin Carlinet committed
76 77 78
    private:
      mln::point<int, dim> m_point;
    };
79

Edwin Carlinet's avatar
Edwin Carlinet committed
80
    template <typename T, unsigned dim>
81
    struct ndimage_pixel_base : ndimage_pixel_base<void, dim>, ndimage_pixel_base<T, 0>
Edwin Carlinet's avatar
Edwin Carlinet committed
82 83
    {
      friend struct internal::iterator_core_access;
84

85
      ndimage_pixel_base() = default;
Michaël Roynard's avatar
Michaël Roynard committed
86
      ndimage_pixel_base(T* ptr) : ndimage_pixel_base<T, 0>(ptr) {}
87 88 89 90 91 92

      template <class U>
      ndimage_pixel_base(const ndimage_pixel_base<U, dim>& other)
          : ndimage_pixel_base<void, dim>(other), ndimage_pixel_base<T, 0>(other)
      {
      }
Edwin Carlinet's avatar
Edwin Carlinet committed
93
    };
94 95
  }

Edwin Carlinet's avatar
Edwin Carlinet committed
96 97
  template <class T, unsigned dim, class I>
  struct ndimage_pixel : details::ndimage_pixel_base<T, dim>, Pixel<ndimage_pixel<T, dim, I>>
edwin.carlinet's avatar
edwin.carlinet committed
98
  {
Edwin Carlinet's avatar
Edwin Carlinet committed
99
    typedef I image_type;
edwin.carlinet's avatar
edwin.carlinet committed
100

Edwin Carlinet's avatar
Edwin Carlinet committed
101 102
    ndimage_pixel() = default;

103
    ndimage_pixel(image_type* ima, T* ptr = nullptr) : details::ndimage_pixel_base<T, dim>(ptr), m_ima(ima) {}
Edwin Carlinet's avatar
Edwin Carlinet committed
104 105 106 107

    /// \brief Copy / copy conversion constructor
    template <class U, class J, typename = std::enable_if_t<std::is_convertible<U*, T*>::value>>
    ndimage_pixel(const ndimage_pixel<U, dim, J>& pix)
Michaël Roynard's avatar
Michaël Roynard committed
108 109
        : details::ndimage_pixel_base<T, dim>(static_cast<const details::ndimage_pixel_base<U, dim>&>(pix)),
          m_ima(pix.m_ima)
Edwin Carlinet's avatar
Edwin Carlinet committed
110 111 112 113 114 115 116 117 118 119 120 121 122 123
    {
    }

    image_type& image() const { return *m_ima; }

  private:
    template <class, unsigned, class>
    friend struct ndimage_pixel;

    template <class, unsigned, class>
    friend struct ndimage_base;

    image_type* m_ima;
  };
124 125 126
}

#endif