123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- #ifndef BOOST_GIL_EXTENSION_NUMERIC_SAMPLER_HPP
- #define BOOST_GIL_EXTENSION_NUMERIC_SAMPLER_HPP
- #include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>
- #include <boost/gil/pixel_numeric_operations.hpp>
- namespace boost { namespace gil {
- struct nearest_neighbor_sampler {};
- template <typename DstP, typename SrcView, typename F>
- bool sample(nearest_neighbor_sampler, SrcView const& src, point<F> const& p, DstP& result)
- {
- typename SrcView::point_t center(iround(p));
- if (center.x >= 0 && center.y >= 0 && center.x < src.width() && center.y < src.height())
- {
- result=src(center.x,center.y);
- return true;
- }
- return false;
- }
- struct cast_channel_fn {
- template <typename SrcChannel, typename DstChannel>
- void operator()(const SrcChannel& src, DstChannel& dst) {
- using dst_value_t = typename channel_traits<DstChannel>::value_type;
- dst = dst_value_t(src);
- }
- };
- template <typename SrcPixel, typename DstPixel>
- void cast_pixel(const SrcPixel& src, DstPixel& dst) {
- static_for_each(src,dst,cast_channel_fn());
- }
- namespace detail {
- template <typename Weight>
- struct add_dst_mul_src_channel {
- Weight _w;
- add_dst_mul_src_channel(Weight w) : _w(w) {}
- template <typename SrcChannel, typename DstChannel>
- void operator()(const SrcChannel& src, DstChannel& dst) const {
- dst += DstChannel(src*_w);
- }
- };
- template <typename SrcP,typename Weight,typename DstP>
- struct add_dst_mul_src {
- void operator()(const SrcP& src, Weight weight, DstP& dst) const {
- static_for_each(src,dst, add_dst_mul_src_channel<Weight>(weight));
- }
- };
- }
- struct bilinear_sampler {};
- template <typename DstP, typename SrcView, typename F>
- bool sample(bilinear_sampler, SrcView const& src, point<F> const& p, DstP& result)
- {
- using SrcP = typename SrcView::value_type;
- point_t p0(ifloor(p.x), ifloor(p.y));
- point<F> frac(p.x-p0.x, p.y-p0.y);
- if (p0.x < -1 || p0.y < -1 || p0.x>=src.width() || p0.y>=src.height())
- {
- return false;
- }
- pixel<F,devicen_layout_t<num_channels<SrcView>::value> > mp(0);
- typename SrcView::xy_locator loc=src.xy_at(p0.x,p0.y);
- if (p0.x == -1)
- {
- if (p0.y == -1)
- {
-
- ++loc.y();
- detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], 1 ,mp);
- }
- else if (p0.y+1<src.height())
- {
-
- detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], (1-frac.y),mp);
- ++loc.y();
- detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], frac.y ,mp);
- }
- else
- {
-
- detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], 1 ,mp);
- }
- }
- else if (p0.x+1<src.width())
- {
- if (p0.y == -1)
- {
-
- ++loc.y();
- detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.x) ,mp);
- detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], frac.x ,mp);
- }
- else if (p0.y+1<src.height())
- {
-
- detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.x)*(1-frac.y),mp);
- 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);
- ++loc.y();
- detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.x)* frac.y ,mp);
- detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], frac.x * frac.y ,mp);
- }
- else
- {
-
- detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.x) ,mp);
- detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], frac.x ,mp);
- }
- }
- else
- {
- if (p0.y == -1)
- {
-
- ++loc.y();
- detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, 1 ,mp);
- }
- else if (p0.y+1<src.height())
- {
-
- detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.y),mp);
- ++loc.y();
- detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, frac.y ,mp);
- }
- else
- {
-
- detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, 1 ,mp);
- }
- }
-
- SrcP src_result;
- cast_pixel(mp,src_result);
- color_convert(src_result, result);
- return true;
- }
- }}
- #endif
|