]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
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_RESAMPLE_HPP | |
9 | #define BOOST_GIL_EXTENSION_NUMERIC_RESAMPLE_HPP | |
10 | ||
11 | #include <boost/gil/extension/numeric/affine.hpp> | |
12 | #include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp> | |
13 | ||
14 | #include <algorithm> | |
15 | #include <functional> | |
16 | ||
17 | namespace boost { namespace gil { | |
18 | ||
19 | // Support for generic image resampling | |
20 | // NOTE: The code is for example use only. It is not optimized for performance | |
21 | ||
22 | /////////////////////////////////////////////////////////////////////////// | |
23 | //// | |
24 | //// resample_pixels: set each pixel in the destination view as the result of a sampling function over the transformed coordinates of the source view | |
25 | //// | |
26 | /////////////////////////////////////////////////////////////////////////// | |
27 | ||
28 | template <typename MapFn> struct mapping_traits {}; | |
29 | ||
30 | /// \brief Set each pixel in the destination view as the result of a sampling function over the transformed coordinates of the source view | |
31 | /// \ingroup ImageAlgorithms | |
32 | /// | |
33 | /// The provided implementation works for 2D image views only | |
34 | template <typename Sampler, // Models SamplerConcept | |
35 | typename SrcView, // Models RandomAccess2DImageViewConcept | |
36 | typename DstView, // Models MutableRandomAccess2DImageViewConcept | |
37 | typename MapFn> // Models MappingFunctionConcept | |
38 | void resample_pixels(const SrcView& src_view, const DstView& dst_view, const MapFn& dst_to_src, Sampler sampler=Sampler()) | |
39 | { | |
40 | typename DstView::point_t dst_dims=dst_view.dimensions(); | |
41 | typename DstView::point_t dst_p; | |
42 | ||
43 | for (dst_p.y=0; dst_p.y<dst_dims.y; ++dst_p.y) { | |
44 | typename DstView::x_iterator xit = dst_view.row_begin(dst_p.y); | |
45 | for (dst_p.x=0; dst_p.x<dst_dims.x; ++dst_p.x) { | |
46 | sample(sampler, src_view, transform(dst_to_src, dst_p), xit[dst_p.x]); | |
47 | } | |
48 | } | |
49 | } | |
50 | ||
51 | /////////////////////////////////////////////////////////////////////////// | |
52 | //// | |
53 | //// resample_pixels when one or both image views are run-time instantiated. | |
54 | //// | |
55 | /////////////////////////////////////////////////////////////////////////// | |
56 | ||
57 | namespace detail { | |
58 | template <typename Sampler, typename MapFn> | |
59 | struct resample_pixels_fn : public binary_operation_obj<resample_pixels_fn<Sampler,MapFn> > { | |
60 | MapFn _dst_to_src; | |
61 | Sampler _sampler; | |
62 | resample_pixels_fn(const MapFn& dst_to_src, const Sampler& sampler) : _dst_to_src(dst_to_src), _sampler(sampler) {} | |
63 | ||
64 | template <typename SrcView, typename DstView> BOOST_FORCEINLINE void apply_compatible(const SrcView& src, const DstView& dst) const { | |
65 | resample_pixels(src, dst, _dst_to_src, _sampler); | |
66 | } | |
67 | }; | |
68 | } | |
69 | ||
70 | /// \brief resample_pixels when the source is run-time specified | |
71 | /// If invoked on incompatible views, throws std::bad_cast() | |
72 | /// \ingroup ImageAlgorithms | |
20effc67 TL |
73 | template <typename Sampler, typename ...Types1, typename V2, typename MapFn> |
74 | void resample_pixels(const any_image_view<Types1...>& src, const V2& dst, const MapFn& dst_to_src, Sampler sampler=Sampler()) | |
92f5a8d4 TL |
75 | { |
76 | apply_operation(src, std::bind( | |
77 | detail::resample_pixels_fn<Sampler, MapFn>(dst_to_src, sampler), | |
78 | std::placeholders::_1, | |
79 | dst)); | |
80 | } | |
81 | ||
82 | /// \brief resample_pixels when the destination is run-time specified | |
83 | /// If invoked on incompatible views, throws std::bad_cast() | |
84 | /// \ingroup ImageAlgorithms | |
20effc67 TL |
85 | template <typename Sampler, typename V1, typename ...Types2, typename MapFn> |
86 | void resample_pixels(const V1& src, const any_image_view<Types2...>& dst, const MapFn& dst_to_src, Sampler sampler=Sampler()) | |
92f5a8d4 TL |
87 | { |
88 | using namespace std::placeholders; | |
89 | apply_operation(dst, std::bind( | |
90 | detail::resample_pixels_fn<Sampler, MapFn>(dst_to_src, sampler), | |
91 | src, | |
92 | std::placeholders::_1)); | |
93 | } | |
94 | ||
95 | /// \brief resample_pixels when both the source and the destination are run-time specified | |
96 | /// If invoked on incompatible views, throws std::bad_cast() | |
97 | /// \ingroup ImageAlgorithms | |
20effc67 TL |
98 | template <typename Sampler, typename ...SrcTypes, typename ...DstTypes, typename MapFn> |
99 | void resample_pixels(const any_image_view<SrcTypes...>& src, const any_image_view<DstTypes...>& dst, const MapFn& dst_to_src, Sampler sampler=Sampler()) { | |
92f5a8d4 TL |
100 | apply_operation(src,dst,detail::resample_pixels_fn<Sampler,MapFn>(dst_to_src,sampler)); |
101 | } | |
102 | ||
103 | /////////////////////////////////////////////////////////////////////////// | |
104 | //// | |
105 | //// resample_subimage: copy into the destination a rotated rectangular region from the source, rescaling it to fit into the destination | |
106 | //// | |
107 | /////////////////////////////////////////////////////////////////////////// | |
108 | ||
109 | // Extract into dst the rotated bounds [src_min..src_max] rotated at 'angle' from the source view 'src' | |
110 | // The source coordinates are in the coordinate space of the source image | |
111 | // Note that the views could also be variants (i.e. any_image_view) | |
112 | template <typename Sampler, typename SrcMetaView, typename DstMetaView> | |
113 | void resample_subimage(const SrcMetaView& src, const DstMetaView& dst, | |
114 | double src_min_x, double src_min_y, | |
115 | double src_max_x, double src_max_y, | |
116 | double angle, const Sampler& sampler=Sampler()) { | |
117 | double src_width = std::max<double>(src_max_x - src_min_x - 1,1); | |
118 | double src_height = std::max<double>(src_max_y - src_min_y - 1,1); | |
119 | double dst_width = std::max<double>((double)(dst.width()-1),1); | |
120 | double dst_height = std::max<double>((double)(dst.height()-1),1); | |
121 | ||
122 | matrix3x2<double> mat = | |
123 | matrix3x2<double>::get_translate(-dst_width/2.0, -dst_height/2.0) * | |
124 | matrix3x2<double>::get_scale(src_width / dst_width, src_height / dst_height)* | |
125 | matrix3x2<double>::get_rotate(-angle)* | |
126 | matrix3x2<double>::get_translate(src_min_x + src_width/2.0, src_min_y + src_height/2.0); | |
127 | resample_pixels(src,dst,mat,sampler); | |
128 | } | |
129 | ||
130 | /////////////////////////////////////////////////////////////////////////// | |
131 | //// | |
132 | //// resize_view: Copy the source view into the destination, scaling to fit | |
133 | //// | |
134 | /////////////////////////////////////////////////////////////////////////// | |
135 | ||
136 | template <typename Sampler, typename SrcMetaView, typename DstMetaView> | |
137 | void resize_view(const SrcMetaView& src, const DstMetaView& dst, const Sampler& sampler=Sampler()) { | |
138 | resample_subimage(src,dst,0.0,0.0,(double)src.width(),(double)src.height(),0.0,sampler); | |
139 | } | |
140 | ||
141 | } } // namespace boost::gil | |
142 | ||
143 | #endif // BOOST_GIL_EXTENSION_NUMERIC_RESAMPLE_HPP |