File indexing completed on 2025-01-18 09:37:00
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_GIL_EXTENSION_NUMERIC_SAMPLER_HPP
0010 #define BOOST_GIL_EXTENSION_NUMERIC_SAMPLER_HPP
0011
0012 #include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>
0013 #include <boost/gil/pixel_numeric_operations.hpp>
0014
0015 namespace boost { namespace gil {
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 struct nearest_neighbor_sampler {};
0038
0039 template <typename DstP, typename SrcView, typename F>
0040 bool sample(nearest_neighbor_sampler, SrcView const& src, point<F> const& p, DstP& result)
0041 {
0042 typename SrcView::point_t center(iround(p));
0043 if (center.x >= 0 && center.y >= 0 && center.x < src.width() && center.y < src.height())
0044 {
0045 result=src(center.x,center.y);
0046 return true;
0047 }
0048 return false;
0049 }
0050
0051 struct cast_channel_fn {
0052 template <typename SrcChannel, typename DstChannel>
0053 void operator()(const SrcChannel& src, DstChannel& dst) {
0054 using dst_value_t = typename channel_traits<DstChannel>::value_type;
0055 dst = dst_value_t(src);
0056 }
0057 };
0058
0059 template <typename SrcPixel, typename DstPixel>
0060 void cast_pixel(const SrcPixel& src, DstPixel& dst) {
0061 static_for_each(src,dst,cast_channel_fn());
0062 }
0063
0064 namespace detail {
0065
0066 template <typename Weight>
0067 struct add_dst_mul_src_channel {
0068 Weight _w;
0069 add_dst_mul_src_channel(Weight w) : _w(w) {}
0070
0071 template <typename SrcChannel, typename DstChannel>
0072 void operator()(const SrcChannel& src, DstChannel& dst) const {
0073 dst += DstChannel(src*_w);
0074 }
0075 };
0076
0077
0078 template <typename SrcP,typename Weight,typename DstP>
0079 struct add_dst_mul_src {
0080 void operator()(const SrcP& src, Weight weight, DstP& dst) const {
0081 static_for_each(src,dst, add_dst_mul_src_channel<Weight>(weight));
0082
0083
0084
0085
0086
0087 }
0088 };
0089 }
0090
0091
0092
0093
0094 struct bilinear_sampler {};
0095
0096 template <typename DstP, typename SrcView, typename F>
0097 bool sample(bilinear_sampler, SrcView const& src, point<F> const& p, DstP& result)
0098 {
0099 using SrcP = typename SrcView::value_type;
0100 point_t p0(ifloor(p.x), ifloor(p.y));
0101 point<F> frac(p.x-p0.x, p.y-p0.y);
0102
0103 if (p0.x < -1 || p0.y < -1 || p0.x>=src.width() || p0.y>=src.height())
0104 {
0105 return false;
0106 }
0107
0108 pixel<F,devicen_layout_t<num_channels<SrcView>::value> > mp(0);
0109 typename SrcView::xy_locator loc=src.xy_at(p0.x,p0.y);
0110
0111 if (p0.x == -1)
0112 {
0113 if (p0.y == -1)
0114 {
0115
0116 ++loc.y();
0117 detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], 1 ,mp);
0118 }
0119 else if (p0.y+1<src.height())
0120 {
0121
0122 detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], (1-frac.y),mp);
0123 ++loc.y();
0124 detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], frac.y ,mp);
0125 }
0126 else
0127 {
0128
0129 detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], 1 ,mp);
0130 }
0131 }
0132 else if (p0.x+1<src.width())
0133 {
0134 if (p0.y == -1)
0135 {
0136
0137 ++loc.y();
0138 detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.x) ,mp);
0139 detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], frac.x ,mp);
0140 }
0141 else if (p0.y+1<src.height())
0142 {
0143
0144 detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.x)*(1-frac.y),mp);
0145 detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], frac.x *(1-frac.y),mp);
0146 ++loc.y();
0147 detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.x)* frac.y ,mp);
0148 detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], frac.x * frac.y ,mp);
0149 }
0150 else
0151 {
0152
0153 detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.x) ,mp);
0154 detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], frac.x ,mp);
0155 }
0156 }
0157 else
0158 {
0159 if (p0.y == -1)
0160 {
0161
0162 ++loc.y();
0163 detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, 1 ,mp);
0164 }
0165 else if (p0.y+1<src.height())
0166 {
0167
0168 detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.y),mp);
0169 ++loc.y();
0170 detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, frac.y ,mp);
0171 }
0172 else
0173 {
0174
0175 detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, 1 ,mp);
0176 }
0177 }
0178
0179
0180 SrcP src_result;
0181 cast_pixel(mp,src_result);
0182
0183 color_convert(src_result, result);
0184 return true;
0185 }
0186
0187 }}
0188
0189 #endif