| #pragma once |
| |
| #ifndef igs_maxmin_getput_h |
| #define igs_maxmin_getput_h |
| |
| #include <vector> |
| #include <limits> /* std::numeric_limits<->::max() |
| --> (std::numeric_limits<->::max)() */ |
| #include "igs_ifx_common.h" // igs::color::ref_value(-) |
| |
| namespace { |
| |
| template <class T> |
| const T *csl_top_clamped_in_h_(const T *top, const int height, const int width, |
| const int channels, const int yy) { |
| if (height <= yy) { |
| return top + (channels * width * (height - 1)); |
| } else if (yy < 0) { |
| return top; |
| } |
| return top + (channels * width * yy); |
| } |
| template <class T> |
| T *sl_out_clamped_in_h_(T *out, const int height, const int width, |
| const int channels, const int yy) { |
| if (height <= yy) { |
| return out + (channels * width * (height - 1)); |
| } else if (yy < 0) { |
| return out; |
| } |
| return out + (channels * width * yy); |
| } |
| |
| template <class T> |
| void paint_margin_(const int margin, std::vector<T> &track) { |
| int xx; |
| |
| for (xx = 0; xx < margin; ++xx) { |
| track.at(xx) = track.at(margin); |
| } |
| |
| for (xx = 0; xx < margin; ++xx) { |
| track.at(track.size() - 1 - xx) = track.at(track.size() - 1 - margin); |
| } |
| } |
| |
| template <class T> |
| void inn_to_track_(const T *sl, const int width, const int channels, |
| const double div_val, const int margin, |
| std::vector<double> &track) { |
| for (int xx = 0; xx < width; ++xx) { |
| track.at(margin + xx) = sl[xx * channels] / div_val; |
| } |
| } |
| |
| template <class T> |
| void inn_to_result_( |
| const T *inn, const int height, const int width, const int channels, |
| const int yy, const int zz, const double div_val, |
| std::vector<double> &result |
| ) { |
| const T *ss = csl_top_clamped_in_h_(inn, height, width, channels, yy) + zz; |
| for (int xx = 0; xx < width; ++xx) { |
| result.at(xx) = ss[xx * channels] / div_val; |
| } |
| } |
| |
| void alpha_ref_init_one_(const int width, std::vector<double> &alpha_ref) { |
| for (int xx = 0; xx < width; ++xx) { |
| alpha_ref.at(xx) = 1.0; |
| } |
| } |
| |
| template <class RT> |
| void alpha_ref_mul_ref_(const RT *ref, const int height, const int width, |
| const int channels, const int yy, const int ref_mode, |
| std::vector<double> &alpha_ref) { |
| const int r_max = (std::numeric_limits<RT>::max)(); |
| const RT *rr = csl_top_clamped_in_h_(ref, height, width, channels, yy); |
| for (int xx = 0; xx < width; ++xx) { |
| alpha_ref.at(xx) *= |
| igs::color::ref_value(&rr[xx * channels], channels, r_max, ref_mode); |
| } |
| } |
| |
| |
| template <class T> |
| void alpha_ref_mul_alpha_(const T *out, const int height, const int width, |
| const int channels, const int yy, |
| const double div_val, |
| std::vector<double> &alpha_ref) { |
| const T *dd = csl_top_clamped_in_h_(out, height, width, channels, yy) + 3; |
| for (int xx = 0; xx < width; ++xx) { |
| alpha_ref.at(xx) *= dd[xx * channels] / div_val; |
| } |
| } |
| } |
| |
| namespace igs { |
| namespace maxmin { |
| namespace getput { |
| |
| |
| |
| |
| |
| template <class IT, class RT> |
| void get_first( |
| const IT *inn |
| , |
| const IT *out |
| , |
| const int hh, const int ww, const int ch, |
| const RT *ref |
| , |
| const int ref_mode |
| , |
| const int yy, const int zz, const int margin, const bool add_blend_sw, |
| std::vector<std::vector<double>> &tracks |
| , |
| std::vector<double> &alpha_ref |
| , |
| std::vector<double> &result |
| ) { |
| const int t_max = (std::numeric_limits<IT>::max)(); |
| const double div_val = static_cast<double>(t_max); |
| |
| |
| int ii = margin * 2; |
| for (int yp = -margin + yy; yp <= margin + yy; ++yp, --ii) { |
| const IT *sl = csl_top_clamped_in_h_(inn, hh, ww, ch, yp) + zz; |
| inn_to_track_(sl, ww, ch, div_val, margin, tracks.at(ii)); |
| paint_margin_(margin, tracks.at(ii)); |
| } |
| inn_to_result_(inn, hh, ww, ch, yy, zz, div_val, result); |
| if (alpha_ref.size() <= 0) { |
| return; |
| } |
| alpha_ref_init_one_(ww, alpha_ref); |
| if (ref != 0) { |
| alpha_ref_mul_ref_(ref, hh, ww, ch, yy, ref_mode, alpha_ref); |
| } |
| if (ch < 4) { |
| return; |
| } |
| if (add_blend_sw) { |
| alpha_ref_mul_alpha_(out, hh, ww, ch, yy, div_val, alpha_ref); |
| } |
| } |
| |
| template <class IT, class RT> |
| void get_next(const IT *inn |
| , |
| const IT *out |
| , |
| const int hh, const int ww, const int ch, |
| const RT *ref |
| , |
| const int ref_mode |
| , |
| const int yy, const int zz, const int margin, |
| const bool add_blend_sw, |
| std::vector<std::vector<double>> &tracks |
| , |
| std::vector<double> &alpha_ref |
| , |
| std::vector<double> &result |
| ) { |
| const int t_max = (std::numeric_limits<IT>::max)(); |
| const double div_val = static_cast<double>(t_max); |
| |
| const IT *sl = csl_top_clamped_in_h_(inn, hh, ww, ch, yy + margin) + zz; |
| inn_to_track_(sl, ww, ch, div_val, margin, tracks.at(0)); |
| paint_margin_(margin, tracks.at(0)); |
| |
| inn_to_result_(inn, hh, ww, ch, yy, zz, div_val, result); |
| if (alpha_ref.size() <= 0) { |
| return; |
| } |
| alpha_ref_init_one_(ww, alpha_ref); |
| if (ref != 0) { |
| alpha_ref_mul_ref_(ref, hh, ww, ch, yy, ref_mode, alpha_ref); |
| } |
| if (ch < 4) { |
| return; |
| } |
| if (add_blend_sw) { |
| alpha_ref_mul_alpha_(out, hh, ww, ch, yy, div_val, alpha_ref); |
| } |
| } |
| template <class T> |
| void copy(const T *inn, const int hh, const int ww, const int ch, const int yy, |
| const int zz, T *out) { |
| const T *ss = csl_top_clamped_in_h_(inn, hh, ww, ch, yy) + zz; |
| T *dd = sl_out_clamped_in_h_(out, hh, ww, ch, yy) + zz; |
| for (int xx = 0; xx < ww; ++xx) { |
| dd[ch * xx] = ss[ch * xx]; |
| } |
| } |
| template <class T> |
| void put(const std::vector<double> &result, const int hh, const int ww, |
| const int ch, const int yy, const int zz, T *out) { |
| const int t_max = (std::numeric_limits<T>::max)(); |
| const double mul_val = static_cast<double>(t_max) + 0.999999; |
| T *dd = sl_out_clamped_in_h_(out, hh, ww, ch, yy) + zz; |
| for (int xx = 0; xx < ww; ++xx) { |
| dd[ch * xx] = static_cast<T>(result.at(xx) * mul_val); |
| |
| } |
| |
| } |
| } |
| } |
| } |
| #endif /* !igs_maxmin_getput_h */ |