123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- #ifndef BOOST_GIL_IMAGE_PROCESSING_SCALING_HPP
- #define BOOST_GIL_IMAGE_PROCESSING_SCALING_HPP
- #include <boost/gil/image_view.hpp>
- #include <boost/gil/rgb.hpp>
- #include <boost/gil/pixel.hpp>
- #include <boost/gil/image_processing/numeric.hpp>
- namespace boost { namespace gil {
- template <typename ImageView>
- void lanczos_at(
- ImageView input_view,
- ImageView output_view,
- typename ImageView::x_coord_t source_x,
- typename ImageView::y_coord_t source_y,
- typename ImageView::x_coord_t target_x,
- typename ImageView::y_coord_t target_y,
- std::ptrdiff_t a)
- {
- using x_coord_t = typename ImageView::x_coord_t;
- using y_coord_t = typename ImageView::y_coord_t;
- using pixel_t = typename std::remove_reference<decltype(std::declval<ImageView>()(0, 0))>::type;
-
- using channel_t = typename std::remove_reference
- <
- decltype(std::declval<pixel_t>().at(std::integral_constant<int, 0>{}))
- >::type;
- pixel_t result_pixel;
- static_transform(result_pixel, result_pixel, [](channel_t) {
- return static_cast<channel_t>(0);
- });
- auto x_zero = static_cast<x_coord_t>(0);
- auto x_one = static_cast<x_coord_t>(1);
- auto y_zero = static_cast<y_coord_t>(0);
- auto y_one = static_cast<y_coord_t>(1);
- for (y_coord_t y_i = (std::max)(source_y - static_cast<y_coord_t>(a) + y_one, y_zero);
- y_i <= (std::min)(source_y + static_cast<y_coord_t>(a), input_view.height() - y_one);
- ++y_i)
- {
- for (x_coord_t x_i = (std::max)(source_x - static_cast<x_coord_t>(a) + x_one, x_zero);
- x_i <= (std::min)(source_x + static_cast<x_coord_t>(a), input_view.width() - x_one);
- ++x_i)
- {
- double lanczos_response = lanczos(source_x - x_i, a) * lanczos(source_y - y_i, a);
- auto op = [lanczos_response](channel_t prev, channel_t next)
- {
- return static_cast<channel_t>(prev + next * lanczos_response);
- };
- static_transform(result_pixel, input_view(source_x, source_y), result_pixel, op);
- }
- }
- output_view(target_x, target_y) = result_pixel;
- }
- template <typename ImageView>
- void scale_lanczos(ImageView input_view, ImageView output_view, std::ptrdiff_t a)
- {
- double scale_x = (static_cast<double>(output_view.width()))
- / static_cast<double>(input_view.width());
- double scale_y = (static_cast<double>(output_view.height()))
- / static_cast<double>(input_view.height());
- using x_coord_t = typename ImageView::x_coord_t;
- using y_coord_t = typename ImageView::y_coord_t;
- for (y_coord_t y = 0; y < output_view.height(); ++y)
- {
- for (x_coord_t x = 0; x < output_view.width(); ++x)
- {
- lanczos_at(input_view, output_view, x / scale_x, y / scale_y, x, y, a);
- }
- }
- }
- }}
- #endif
|