Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / gil / doc / html / _downloads / mandelbrot.cpp
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 #include <boost/gil/image.hpp>
9 #include <boost/gil/typedefs.hpp>
10 #include <boost/gil/extension/io/jpeg.hpp>
11
12 // Example for convolve_rows() and convolve_cols() in the numeric extension
13
14 using namespace boost::gil;
15
16 // Models a Unary Function
17 template <typename P>   // Models PixelValueConcept
18 struct mandelbrot_fn
19 {
20     using point_t = boost::gil::point_t;
21     using const_t = mandelbrot_fn;
22     using value_type = P;
23     using reference = value_type;
24     using const_reference = value_type;
25     using argument_type = point_t;
26     using result_type = reference;
27     static constexpr bool is_mutable =false;
28
29     value_type                    _in_color,_out_color;
30     point_t                       _img_size;
31     static const int MAX_ITER=100;        // max number of iterations
32
33     mandelbrot_fn() {}
34     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) {}
35
36     result_type operator()(const point_t& p) const {
37         // normalize the coords to (-2..1, -1.5..1.5)
38         // (actually make y -1.0..2 so it is asymmetric, so we can verify some view factory methods)
39         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));
40         t=pow(t,0.2);
41
42         value_type ret;
43         for (int k=0; k<num_channels<P>::value; ++k)
44             ret[k]=(typename channel_type<P>::type)(_in_color[k]*t + _out_color[k]*(1-t));
45         return ret;
46     }
47
48 private:
49     double get_num_iter(const point<double>& p) const {
50         point<double> Z(0,0);
51         for (int i=0; i<MAX_ITER; ++i) {
52             Z = point<double>(Z.x*Z.x - Z.y*Z.y + p.x, 2*Z.x*Z.y + p.y);
53             if (Z.x*Z.x + Z.y*Z.y > 4)
54                 return i/(double)MAX_ITER;
55         }
56         return 0;
57     }
58 };
59
60 int main()
61 {
62     using deref_t = mandelbrot_fn<rgb8_pixel_t>;
63     using point_t = deref_t::point_t;
64     using locator_t = virtual_2d_locator<deref_t,false>;
65     using my_virt_view_t = image_view<locator_t>;
66
67     boost::function_requires<PixelLocatorConcept<locator_t>>();
68     gil_function_requires<StepIteratorConcept<locator_t::x_iterator>>();
69
70     point_t dims(200,200);
71     my_virt_view_t mandel(dims, locator_t(point_t(0,0), point_t(1,1), deref_t(dims, rgb8_pixel_t(255,0,255), rgb8_pixel_t(0,255,0))));
72     write_view("out-mandelbrot.jpg",mandel, jpeg_tag{});
73
74     return 0;
75 }