Imported Upstream version 1.71.0
[platform/upstream/boost.git] / libs / gil / io / test / mandel_view.hpp
1 //
2 // Copyright 2013 Christian Henning
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_IO_TEST_MANDEL_HPP
9 #define BOOST_GIL_IO_TEST_MANDEL_HPP
10
11 #include <boost/gil.hpp>
12
13 using namespace std;
14 using namespace boost;
15 using namespace gil;
16
17 // Models a Unary Function
18 template <typename P>   // Models PixelValueConcept
19 struct mandelbrot_fn
20 {
21     using point_t = boost::gil::point_t;
22     using const_t = mandelbrot_fn;
23     using value_type = P;
24     using reference = value_type;
25     using const_reference = value_type;
26     using argument_type = point_t;
27     using result_type = reference;
28     static constexpr bool is_mutable = false;
29
30     value_type                    _in_color,_out_color;
31     point_t                       _img_size;
32     static const int MAX_ITER=100;        // max number of iterations
33
34     mandelbrot_fn() {}
35     mandelbrot_fn(const point_t& sz, const value_type& in_color, const value_type& out_color) : _in_color(in_color), _out_color(out_color), _img_size(sz) {}
36
37     std::ptrdiff_t width()  { return _img_size.x; }
38     std::ptrdiff_t height() { return _img_size.y; }
39
40     result_type operator()(const point_t& p) const {
41         // normalize the coords to (-2..1, -1.5..1.5)
42         // (actually make y -1.0..2 so it is asymmetric, so we can verify some view factory methods)
43         double t=get_num_iter(point<double>(p.x/(double)_img_size.x*3-2, p.y/(double)_img_size.y*3-1.0f));//1.5f));
44         t=pow(t,0.2);
45
46         value_type ret;
47         for (int k=0; k<num_channels<P>::value; ++k)
48             ret[k]=(typename channel_type<P>::type)(_in_color[k]*t + _out_color[k]*(1-t));
49         return ret;
50     }
51
52 private:
53     double get_num_iter(const point<double>& p) const {
54         point<double> Z(0,0);
55         for (int i=0; i<MAX_ITER; ++i) {
56             Z = point<double>(Z.x*Z.x - Z.y*Z.y + p.x, 2*Z.x*Z.y + p.y);
57             if (Z.x*Z.x + Z.y*Z.y > 4)
58                 return i/(double)MAX_ITER;
59         }
60         return 0;
61     }
62 };
63
64 template< typename Pixel >
65 struct mandel_view
66 {
67     using deref_t = mandelbrot_fn<Pixel>;
68     using locator_t= virtual_2d_locator<deref_t, false>;
69     using my_virt_view_t = image_view<locator_t>;
70     using type = my_virt_view_t;
71 };
72
73 template< typename Pixel >
74 typename mandel_view< Pixel >::type create_mandel_view( unsigned int width
75                                                       , unsigned int height
76                                                       , const Pixel& in
77                                                       , const Pixel& out
78                                                       )
79 {
80     using view_t = typename mandel_view<Pixel>::type;
81     using deref_t = typename mandel_view<Pixel>::deref_t;
82     using locator_t = typename mandel_view<Pixel>::locator_t;
83
84     point_t dims( width, height );
85     return view_t( dims
86                  , locator_t( point_t( 0, 0 )
87                             , point_t( 1, 1 )
88                             , deref_t( dims
89                                      , in
90                                      , out
91                                      )
92                             )
93                  );
94 }
95
96 #endif // BOOST_GIL_IO_TEST_MANDEL_HPP