File indexing completed on 2025-12-16 09:51:52
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_GIL_IMAGE_PROCESSING_SCALING_HPP
0009 #define BOOST_GIL_IMAGE_PROCESSING_SCALING_HPP
0010
0011 #include <boost/gil/image_view.hpp>
0012 #include <boost/gil/rgb.hpp>
0013 #include <boost/gil/pixel.hpp>
0014 #include <boost/gil/image_processing/numeric.hpp>
0015
0016 namespace boost { namespace gil {
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 template <typename ImageView>
0037 void lanczos_at(
0038 ImageView input_view,
0039 ImageView output_view,
0040 typename ImageView::x_coord_t source_x,
0041 typename ImageView::y_coord_t source_y,
0042 typename ImageView::x_coord_t target_x,
0043 typename ImageView::y_coord_t target_y,
0044 std::ptrdiff_t a)
0045 {
0046 using x_coord_t = typename ImageView::x_coord_t;
0047 using y_coord_t = typename ImageView::y_coord_t;
0048 using pixel_t = typename std::remove_reference<decltype(std::declval<ImageView>()(0, 0))>::type;
0049
0050
0051 using channel_t = typename std::remove_reference
0052 <
0053 decltype(std::declval<pixel_t>().at(std::integral_constant<int, 0>{}))
0054 >::type;
0055
0056 pixel_t result_pixel;
0057 static_transform(result_pixel, result_pixel, [](channel_t) {
0058 return static_cast<channel_t>(0);
0059 });
0060 auto x_zero = static_cast<x_coord_t>(0);
0061 auto x_one = static_cast<x_coord_t>(1);
0062 auto y_zero = static_cast<y_coord_t>(0);
0063 auto y_one = static_cast<y_coord_t>(1);
0064
0065 for (y_coord_t y_i = (std::max)(source_y - static_cast<y_coord_t>(a) + y_one, y_zero);
0066 y_i <= (std::min)(source_y + static_cast<y_coord_t>(a), input_view.height() - y_one);
0067 ++y_i)
0068 {
0069 for (x_coord_t x_i = (std::max)(source_x - static_cast<x_coord_t>(a) + x_one, x_zero);
0070 x_i <= (std::min)(source_x + static_cast<x_coord_t>(a), input_view.width() - x_one);
0071 ++x_i)
0072 {
0073 double lanczos_response = lanczos(source_x - x_i, a) * lanczos(source_y - y_i, a);
0074 auto op = [lanczos_response](channel_t prev, channel_t next)
0075 {
0076 return static_cast<channel_t>(prev + next * lanczos_response);
0077 };
0078 static_transform(result_pixel, input_view(source_x, source_y), result_pixel, op);
0079 }
0080 }
0081
0082 output_view(target_x, target_y) = result_pixel;
0083 }
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 template <typename ImageView>
0095 void scale_lanczos(ImageView input_view, ImageView output_view, std::ptrdiff_t a)
0096 {
0097 double scale_x = (static_cast<double>(output_view.width()))
0098 / static_cast<double>(input_view.width());
0099 double scale_y = (static_cast<double>(output_view.height()))
0100 / static_cast<double>(input_view.height());
0101
0102 using x_coord_t = typename ImageView::x_coord_t;
0103 using y_coord_t = typename ImageView::y_coord_t;
0104 for (y_coord_t y = 0; y < output_view.height(); ++y)
0105 {
0106 for (x_coord_t x = 0; x < output_view.width(); ++x)
0107 {
0108 lanczos_at(input_view, output_view, x / scale_x, y / scale_y, x, y, a);
0109 }
0110 }
0111 }
0112
0113 }}
0114
0115 #endif