Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:51:52

0001 //
0002 // Copyright 2019 Olzhas Zhumabek <anonymous.from.applecity@gmail.com>
0003 //
0004 // Use, modification and distribution are subject to the Boost Software License,
0005 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt)
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 /// \defgroup ScalingAlgorithms
0019 /// \brief Algorthims suitable for rescaling
0020 ///
0021 /// These algorithms are used to improve image quality after image resizing is made.
0022 ///
0023 /// \defgroup DownScalingAlgorithms
0024 /// \ingroup ScalingAlgorithms
0025 /// \brief Algorthims suitable for downscaling
0026 ///
0027 /// These algorithms provide best results when used for downscaling. Using for upscaling will
0028 /// probably provide less than good results.
0029 ///
0030 /// \brief a single step of lanczos downscaling
0031 /// \ingroup DownScalingAlgorithms
0032 ///
0033 /// Use this algorithm to scale down source image into a smaller image with reasonable quality.
0034 /// Do note that having a look at the output once is a good idea, since it might have ringing
0035 /// artifacts.
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     // C++11 doesn't allow auto in lambdas
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 /// \brief Complete Lanczos algorithm
0086 /// \ingroup DownScalingAlgorithms
0087 ///
0088 /// This algorithm does full pass over resulting image and convolves pixels from
0089 /// original image. Do note that it might be a good idea to have a look at test
0090 /// output as there might be ringing artifacts.
0091 /// Based on wikipedia article:
0092 /// https://en.wikipedia.org/wiki/Lanczos_resampling
0093 /// with standardinzed cardinal sin (sinc)
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 }} // namespace boost::gil
0114 
0115 #endif