| #include <limits> |
| #include <stdexcept> /* std::domain_error(-) */ |
| #include "igs_motion_wind_pixel.h" |
| |
| namespace { |
| template <class T> |
| const T *ref_pixel_(const T *ref, const int hh, const int ww, const int cc, |
| int xx, int yy) { |
| while (xx < 0) { |
| xx += ww; |
| } |
| while (ww <= xx) { |
| xx -= ww; |
| } |
| while (yy < 0) { |
| yy += hh; |
| } |
| while (hh <= yy) { |
| yy -= hh; |
| } |
| return ref + cc * ww * yy + cc * xx; |
| } |
| template <class T> |
| void pixel_pop_(const T *in, const double div_val, const int cc, double *out) { |
| |
| for (int zz = 0; zz < cc; ++zz) { |
| out[zz] = static_cast<double>(in[zz]) / div_val; |
| } |
| } |
| template <class T> |
| void pixel_push_(const double *in, const double mul_val, const int cc, T *out) { |
| |
| for (int zz = 0; zz < cc; ++zz) { |
| out[zz] = static_cast<T>(in[zz] * mul_val); |
| } |
| } |
| |
| template <class T, class R> |
| void change_template_vert_( |
| T *in, const int ww, const int hh, const int cc, const R *ref, const int rw, |
| const int rh, const int rc |
| //, const int rz |
| , |
| const int ref_mode /* 0=R,1=G,2=B,3=A,4=Luminance,5=Nothing */ |
| , |
| igs::motion_wind::pixel &pix_rend, const bool reverse_sw) { |
| const unsigned int max_val = std::numeric_limits<T>::max(); |
| const double div_val = static_cast<double>(max_val); |
| const double mul_val = div_val + 0.999999; |
| |
| const unsigned int ref_max_val = std::numeric_limits<R>::max(); |
| const double ref_div_val = static_cast<double>(ref_max_val); |
| |
| const int refprev = (reverse_sw) ? 1 : -1; |
| |
| for (int xx = 0; xx < ww; ++xx) { |
| for (int yy = 0; yy < hh; ++yy) { |
| T *next = in; |
| if (reverse_sw) { |
| next += (hh - 1 - yy) * ww * cc + xx * cc; |
| } else { |
| next += yy * ww * cc + xx * cc; |
| } |
| double pixel_in[igs::image::rgba::siz]; |
| pixel_pop_(next, div_val, cc, pixel_in); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| double ref_val = -1.0; |
| if (0 != ref && 0 <= ref_mode && ref_mode <= 4) { |
| ref_val = |
| igs::color::ref_value(ref_pixel_(ref, rh, rw, rc, xx, yy + refprev), |
| rc, ref_max_val, ref_mode); |
| } |
| |
| if (pix_rend.change(xx <= 0, ref_val, cc, pixel_in)) { |
| pixel_push_(pixel_in, mul_val, cc, next); |
| } |
| } |
| } |
| } |
| template <class T, class R> |
| void change_template_hori_( |
| T *in, const int ww, const int hh, const int cc, const R *ref, const int rw, |
| const int rh, const int rc |
| //, const int rz |
| , |
| const int ref_mode /* 0=R,1=G,2=B,3=A,4=Luminance,5=Nothing */ |
| , |
| igs::motion_wind::pixel &pix_rend, const bool reverse_sw) { |
| const unsigned int max_val = std::numeric_limits<T>::max(); |
| const double div_val = static_cast<double>(max_val); |
| const double mul_val = div_val + 0.999999; |
| |
| const unsigned int ref_max_val = std::numeric_limits<R>::max(); |
| const double ref_div_val = static_cast<double>(ref_max_val); |
| |
| const int refprev = (reverse_sw) ? 1 : -1; |
| |
| for (int yy = 0; yy < hh; ++yy) { |
| T *next = in; |
| if (reverse_sw) { |
| next += (ww - 1) * cc; |
| } |
| for (int xx = 0; xx < ww; ++xx) { |
| double pixel_in[igs::image::rgba::siz]; |
| pixel_pop_(next, div_val, cc, pixel_in); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| double ref_val = -1.0; |
| if (0 != ref && 0 <= ref_mode && ref_mode <= 4) { |
| ref_val = |
| igs::color::ref_value(ref_pixel_(ref, rh, rw, rc, xx, yy + refprev), |
| rc, ref_max_val, ref_mode); |
| } |
| |
| if (pix_rend.change(xx <= 0, ref_val, cc, pixel_in)) { |
| pixel_push_(pixel_in, mul_val, cc, next); |
| } |
| |
| if (reverse_sw) { |
| next -= cc; |
| } |
| else { |
| next += cc; |
| } |
| } |
| in += ww * cc; |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #include "igs_motion_wind.h" |
| void igs::motion_wind::change( |
| unsigned char *in |
| |
| , |
| const int hh, const int ww, const int cc, const int bb |
| |
| , |
| const unsigned char *ref |
| |
| , |
| const int rh, const int rw, const int rc, const int rb |
| |
| |
| , |
| const int ref_mode |
| |
| , |
| const int direction |
| , |
| const bool blow_dark_sw |
| , |
| const bool blow_alpha_sw |
| |
| , |
| const unsigned long length_random_seed |
| , |
| const double length_min |
| , |
| const double length_max |
| , |
| const double length_bias |
| , |
| const bool length_ref_sw |
| |
| , |
| const unsigned long force_random_seed |
| , |
| const double force_min |
| , |
| const double force_max |
| , |
| const double force_bias |
| , |
| const bool force_ref_sw |
| |
| , |
| const unsigned long density_random_seed |
| , |
| const double density_min |
| , |
| const double density_max |
| , |
| const double density_bias |
| , |
| const bool density_ref_sw |
| ) { |
| |
| |
| if ((length_max <= 0.0) && (length_min <= 0.0)) { |
| return; |
| } |
| |
| igs::motion_wind::pixel pix_rend( |
| blow_dark_sw, blow_alpha_sw, length_random_seed, length_min, length_max, |
| length_bias, length_ref_sw, force_random_seed, force_min, force_max, |
| force_bias, force_ref_sw, density_random_seed, density_min, density_max, |
| density_bias, density_ref_sw); |
| |
| const int bi = static_cast<int>(bb); |
| const int refbi = static_cast<int>(rb); |
| if (std::numeric_limits<unsigned char>::digits == bi) { |
| if (std::numeric_limits<unsigned short>::digits == refbi) { |
| if ((0 == direction) || (2 == direction)) { |
| change_template_hori_( |
| in, ww, hh, cc, reinterpret_cast<const unsigned short *>(ref), rw, |
| rh, rc |
| |
| , |
| ref_mode, pix_rend, (0 == direction) ? false : true); |
| } else if ((1 == direction) || (3 == direction)) { |
| change_template_vert_( |
| in, ww, hh, cc, reinterpret_cast<const unsigned short *>(ref), rw, |
| rh, rc |
| |
| , |
| ref_mode, pix_rend, (1 == direction) ? false : true); |
| } |
| } else { |
| if ((0 == direction) || (2 == direction)) { |
| change_template_hori_(in, ww, hh, cc, ref, rw, rh, rc |
| |
| , |
| ref_mode, pix_rend, |
| (0 == direction) ? false : true); |
| } else if ((1 == direction) || (3 == direction)) { |
| change_template_vert_(in, ww, hh, cc, ref, rw, rh, rc |
| |
| , |
| ref_mode, pix_rend, |
| (1 == direction) ? false : true); |
| } |
| } |
| } else if (std::numeric_limits<unsigned short>::digits == bi) { |
| if (std::numeric_limits<unsigned short>::digits == refbi) { |
| if ((0 == direction) || (2 == direction)) { |
| change_template_hori_( |
| reinterpret_cast<unsigned short *>(in), ww, hh, cc, |
| reinterpret_cast<const unsigned short *>(ref), rw, rh, rc |
| |
| , |
| ref_mode, pix_rend, (0 == direction) ? false : true); |
| } else if ((1 == direction) || (3 == direction)) { |
| change_template_vert_( |
| reinterpret_cast<unsigned short *>(in), ww, hh, cc, |
| reinterpret_cast<const unsigned short *>(ref), rw, rh, rc |
| |
| , |
| ref_mode, pix_rend, (1 == direction) ? false : true); |
| } |
| } else { |
| if ((0 == direction) || (2 == direction)) { |
| change_template_hori_( |
| reinterpret_cast<unsigned short *>(in), ww, hh, cc, ref, rw, rh, rc |
| |
| , |
| ref_mode, pix_rend, (0 == direction) ? false : true); |
| } else if ((1 == direction) || (3 == direction)) { |
| change_template_vert_( |
| reinterpret_cast<unsigned short *>(in), ww, hh, cc, ref, rw, rh, rc |
| |
| , |
| ref_mode, pix_rend, (1 == direction) ? false : true); |
| } |
| } |
| } else { |
| throw std::domain_error("Bad bits,Not uchar/ushort"); |
| } |
| |
| pix_rend.clear(); |
| } |