Toshihiro Shimizu 890ddd
#include <limits></limits>
Toshihiro Shimizu 890ddd
#include <stdexcept> /* std::domain_error(-) */</stdexcept>
Toshihiro Shimizu 890ddd
#include "igs_motion_wind_pixel.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka 120a6e
const T *ref_pixel_(const T *ref, const int hh, const int ww, const int cc,
Shinya Kitaoka 120a6e
                    int xx, int yy) {
Shinya Kitaoka 120a6e
  while (xx < 0) {
Shinya Kitaoka 120a6e
    xx += ww;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  while (ww <= xx) {
Shinya Kitaoka 120a6e
    xx -= ww;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  while (yy < 0) {
Shinya Kitaoka 120a6e
    yy += hh;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  while (hh <= yy) {
Shinya Kitaoka 120a6e
    yy -= hh;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return ref + cc * ww * yy + cc * xx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka 120a6e
void pixel_pop_(const T *in, const double div_val, const int cc, double *out) {
Shinya Kitaoka 120a6e
  /* 正規化し取り出し */
Shinya Kitaoka 120a6e
  for (int zz = 0; zz < cc; ++zz) {
Shinya Kitaoka 120a6e
    out[zz] = static_cast<double>(in[zz]) / div_val;</double>
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka 120a6e
void pixel_push_(const double *in, const double mul_val, const int cc, T *out) {
Shinya Kitaoka 120a6e
  /* 値が変化したら格納する */
Shinya Kitaoka 120a6e
  for (int zz = 0; zz < cc; ++zz) {
Shinya Kitaoka 120a6e
    out[zz] = static_cast<t>(in[zz] * mul_val);</t>
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
template <class class="" r="" t,=""></class>
Toshihiro Shimizu 890ddd
void change_template_vert_(
Shinya Kitaoka 120a6e
    T *in, const int ww, const int hh, const int cc, const R *ref, const int rw,
Shinya Kitaoka 120a6e
    const int rh, const int rc
Shinya Kitaoka 120a6e
    //, const int rz
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int ref_mode /* 0=R,1=G,2=B,3=A,4=Luminance,5=Nothing */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    igs::motion_wind::pixel &pix_rend, const bool reverse_sw) {
Shinya Kitaoka 120a6e
  const unsigned int max_val = std::numeric_limits<t>::max();</t>
Shinya Kitaoka 120a6e
  const double div_val       = static_cast<double>(max_val);</double>
Shinya Kitaoka 120a6e
  const double mul_val       = div_val + 0.999999;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const unsigned int ref_max_val = std::numeric_limits<r>::max();</r>
Shinya Kitaoka 120a6e
  const double ref_div_val       = static_cast<double>(ref_max_val);</double>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const int refprev = (reverse_sw) ? 1 : -1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int xx = 0; xx < ww; ++xx) {
Shinya Kitaoka 120a6e
    for (int yy = 0; yy < hh; ++yy) {
Shinya Kitaoka 120a6e
      T *next = in;
Shinya Kitaoka 120a6e
      if (reverse_sw) { /* 上から */
Shinya Kitaoka 120a6e
        next += (hh - 1 - yy) * ww * cc + xx * cc;
Shinya Kitaoka 120a6e
      } else { /* 下から */
Shinya Kitaoka 120a6e
        next += yy * ww * cc + xx * cc;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      double pixel_in[igs::image::rgba::siz];
Shinya Kitaoka 120a6e
      pixel_pop_(next, div_val, cc, pixel_in);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      /****double pixel_ref[igs::image::rgba::siz];
Shinya Kitaoka 120a6e
double *rp_p = 0;
Shinya Kitaoka 120a6e
if (0 != ref) {
Shinya Kitaoka 120a6e
      pixel_pop_(
Shinya Kitaoka 120a6e
              ref_pixel_(ref,rh,rw,rc,xx,yy+refprev)
Shinya Kitaoka 120a6e
              , ref_div_val, rc, pixel_ref);
Shinya Kitaoka 120a6e
      rp_p = pixel_ref;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
if (pix_rend.change(xx <= 0, rz, rp_p, cc, pixel_in)) {
Shinya Kitaoka 120a6e
      pixel_push_(pixel_in,mul_val,cc,next);
Shinya Kitaoka 120a6e
} ***/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      double ref_val = -1.0;
Shinya Kitaoka 120a6e
      if (0 != ref && 0 <= ref_mode && ref_mode <= 4) {
Shinya Kitaoka 120a6e
        ref_val =
Shinya Kitaoka 120a6e
            igs::color::ref_value(ref_pixel_(ref, rh, rw, rc, xx, yy + refprev),
Shinya Kitaoka 120a6e
                                  rc, ref_max_val, ref_mode);
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (pix_rend.change(xx <= 0, ref_val, cc, pixel_in)) {
Shinya Kitaoka 120a6e
        pixel_push_(pixel_in, mul_val, cc, next);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
template <class class="" r="" t,=""></class>
Toshihiro Shimizu 890ddd
void change_template_hori_(
Shinya Kitaoka 120a6e
    T *in, const int ww, const int hh, const int cc, const R *ref, const int rw,
Shinya Kitaoka 120a6e
    const int rh, const int rc
Shinya Kitaoka 120a6e
    //, const int rz
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int ref_mode /* 0=R,1=G,2=B,3=A,4=Luminance,5=Nothing */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    igs::motion_wind::pixel &pix_rend, const bool reverse_sw) {
Shinya Kitaoka 120a6e
  const unsigned int max_val = std::numeric_limits<t>::max();</t>
Shinya Kitaoka 120a6e
  const double div_val       = static_cast<double>(max_val);</double>
Shinya Kitaoka 120a6e
  const double mul_val       = div_val + 0.999999;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const unsigned int ref_max_val = std::numeric_limits<r>::max();</r>
Shinya Kitaoka 120a6e
  const double ref_div_val       = static_cast<double>(ref_max_val);</double>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const int refprev = (reverse_sw) ? 1 : -1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int yy = 0; yy < hh; ++yy) {
Shinya Kitaoka 120a6e
    T *next = in; /* 左から */
Shinya Kitaoka 120a6e
    if (reverse_sw) {
Shinya Kitaoka 120a6e
      next += (ww - 1) * cc;
Shinya Kitaoka 120a6e
    } /* 右から */
Shinya Kitaoka 120a6e
    for (int xx = 0; xx < ww; ++xx) {
Shinya Kitaoka 120a6e
      double pixel_in[igs::image::rgba::siz];
Shinya Kitaoka 120a6e
      pixel_pop_(next, div_val, cc, pixel_in);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      /***double pixel_ref[igs::image::rgba::siz];
Shinya Kitaoka 120a6e
double *rp_p = 0;
Shinya Kitaoka 120a6e
if (0 != ref) {
Shinya Kitaoka 120a6e
      pixel_pop_(
Shinya Kitaoka 120a6e
              ref_pixel_(ref,rh,rw,rc,xx+refprev,yy)
Shinya Kitaoka 120a6e
              , ref_div_val, rc, pixel_ref);
Shinya Kitaoka 120a6e
      rp_p = pixel_ref;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
if (pix_rend.change(xx <= 0, rz, rp_p, cc, pixel_in)) {
Shinya Kitaoka 120a6e
      pixel_push_(pixel_in,mul_val,cc,next);
Shinya Kitaoka 120a6e
}***/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      double ref_val = -1.0;
Shinya Kitaoka 120a6e
      if (0 != ref && 0 <= ref_mode && ref_mode <= 4) {
Shinya Kitaoka 120a6e
        ref_val =
Shinya Kitaoka 120a6e
            igs::color::ref_value(ref_pixel_(ref, rh, rw, rc, xx, yy + refprev),
Shinya Kitaoka 120a6e
                                  rc, ref_max_val, ref_mode);
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (pix_rend.change(xx <= 0, ref_val, cc, pixel_in)) {
Shinya Kitaoka 120a6e
        pixel_push_(pixel_in, mul_val, cc, next);
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (reverse_sw) {
Shinya Kitaoka 120a6e
        next -= cc;
Shinya Kitaoka 120a6e
      } /* 右から左 */
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        next += cc;
Shinya Kitaoka 120a6e
      } /* 左から右 */
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    in += ww * cc; /* 下から上 */
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*-------------------------------------------------------
Shinya Kitaoka 120a6e
        Parameter
Shinya Kitaoka 120a6e
        方向			left-bottom is origin.
Shinya Kitaoka 120a6e
                0	:   0 : left to right
Shinya Kitaoka 120a6e
                1	:  90 : bottom to top
Shinya Kitaoka 120a6e
                2	: 180 : right to left
Shinya Kitaoka 120a6e
                3	: 270 : top to bottom
Shinya Kitaoka 120a6e
        暗い風へ変更するスイッチ
Shinya Kitaoka 120a6e
                true	: blow dark
Shinya Kitaoka 120a6e
                false	: blow light
Shinya Kitaoka 120a6e
        アルファにも風吹くスイッチ
Shinya Kitaoka 120a6e
                true	: blow alpha
Shinya Kitaoka 120a6e
                false	: not blow alpha
Shinya Kitaoka 120a6e
        風長さ(ランダム初期種)		1(0...)
Shinya Kitaoka 120a6e
        風長さ(最小値)			0(0...)
Shinya Kitaoka 120a6e
        風長さ(最大値)			18(0...)
Shinya Kitaoka 120a6e
        風長さ(最大最小のかたより値)	0.0(-1.0...0.0...1.0)
Shinya Kitaoka 120a6e
        風長さ(参照スイッチ)		false(true/false)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        風曲線(ランダム初期種)		1(0...)
Shinya Kitaoka 120a6e
        風曲線(最小値)			0(0...)
Shinya Kitaoka 120a6e
        風曲線(最大値)			1(0...)
Shinya Kitaoka 120a6e
        風曲線(最大最小のかたより値)	0.0(-1.0...0.0...1.0)
Shinya Kitaoka 120a6e
        風曲線(参照スイッチ)		false(true/false)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        風高さ(ランダム初期種)		1(0...)
Shinya Kitaoka 120a6e
        風高さ(最小値)			0(0...)
Shinya Kitaoka 120a6e
        風高さ(最大値)			1(0...)
Shinya Kitaoka 120a6e
        風高さ(最大最小のかたより値)	0.0(-1.0...0.0...1.0)
Shinya Kitaoka 120a6e
        風高さ(参照スイッチ)		false(true/false)
Toshihiro Shimizu 890ddd
-------------------------------------------------------*/
Toshihiro Shimizu 890ddd
#include "igs_motion_wind.h"
Toshihiro Shimizu 890ddd
void igs::motion_wind::change(
Shinya Kitaoka 120a6e
    unsigned char *in
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int hh, const int ww, const int cc, const int bb
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const unsigned char *ref
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int rh, const int rw, const int rc, const int rb
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    //, const int rz
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int ref_mode /* 0=R,1=G,2=B,3=A,4=Luminance,5=Nothing */
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int direction  // 0(0(LtoR),1(BtoT),2(RtoL),3(TtoB))
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const bool blow_dark_sw  // false(false,true)
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const bool blow_alpha_sw  // true(false,true)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const unsigned long length_random_seed  // 0(0...)
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double length_min  // 0.0...
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double length_max  // 18.0...
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double length_bias  // 1.0(0.0<...1.0...)
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const bool length_ref_sw  // false(false,true)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const unsigned long force_random_seed  // 0(0...)
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double force_min  // 0.0...
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double force_max  // 1.0...
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double force_bias  // 1.0(0.0<...1.0...)
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const bool force_ref_sw  // false(false,true)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const unsigned long density_random_seed  // 0(0...)
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double density_min  // 0.0...
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double density_max  // 1.0...
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double density_bias  // 1.0(0.0<...1.0...)
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const bool density_ref_sw  // false(false,true)
Shinya Kitaoka 120a6e
    ) {
Shinya Kitaoka 120a6e
  /* ユーザーによるノーアクションの指定、つまりゼロ長
Shinya Kitaoka 120a6e
  の時は処理せず終る */
Shinya Kitaoka 120a6e
  if ((length_max <= 0.0) && (length_min <= 0.0)) {
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  //------------
Shinya Kitaoka 120a6e
  igs::motion_wind::pixel pix_rend(
Shinya Kitaoka 120a6e
      blow_dark_sw, blow_alpha_sw, length_random_seed, length_min, length_max,
Shinya Kitaoka 120a6e
      length_bias, length_ref_sw, force_random_seed, force_min, force_max,
Shinya Kitaoka 120a6e
      force_bias, force_ref_sw, density_random_seed, density_min, density_max,
Shinya Kitaoka 120a6e
      density_bias, density_ref_sw);
Shinya Kitaoka 120a6e
  //------------
Shinya Kitaoka 120a6e
  const int bi    = static_cast<int>(bb);</int>
Shinya Kitaoka 120a6e
  const int refbi = static_cast<int>(rb);</int>
Shinya Kitaoka 120a6e
  if (std::numeric_limits<unsigned char="">::digits == bi) {</unsigned>
Shinya Kitaoka 120a6e
    if (std::numeric_limits<unsigned short="">::digits == refbi) {</unsigned>
Shinya Kitaoka 120a6e
      if ((0 == direction) || (2 == direction)) {
Shinya Kitaoka 120a6e
        change_template_hori_(
Shinya Kitaoka 120a6e
            in, ww, hh, cc, reinterpret_cast<const *="" short="" unsigned="">(ref), rw,</const>
Shinya Kitaoka 120a6e
            rh, rc
Shinya Kitaoka 120a6e
            //,rz
Shinya Kitaoka 120a6e
            ,
Shinya Kitaoka 120a6e
            ref_mode, pix_rend, (0 == direction) ? false : true);
Shinya Kitaoka 120a6e
      } else if ((1 == direction) || (3 == direction)) {
Shinya Kitaoka 120a6e
        change_template_vert_(
Shinya Kitaoka 120a6e
            in, ww, hh, cc, reinterpret_cast<const *="" short="" unsigned="">(ref), rw,</const>
Shinya Kitaoka 120a6e
            rh, rc
Shinya Kitaoka 120a6e
            //,rz
Shinya Kitaoka 120a6e
            ,
Shinya Kitaoka 120a6e
            ref_mode, pix_rend, (1 == direction) ? false : true);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else { /* refbi is 8(uchar) or other(0...) */
Shinya Kitaoka 120a6e
      if ((0 == direction) || (2 == direction)) {
Shinya Kitaoka 120a6e
        change_template_hori_(in, ww, hh, cc, ref, rw, rh, rc
Shinya Kitaoka 120a6e
                              //,rz
Shinya Kitaoka 120a6e
                              ,
Shinya Kitaoka 120a6e
                              ref_mode, pix_rend,
Shinya Kitaoka 120a6e
                              (0 == direction) ? false : true);
Shinya Kitaoka 120a6e
      } else if ((1 == direction) || (3 == direction)) {
Shinya Kitaoka 120a6e
        change_template_vert_(in, ww, hh, cc, ref, rw, rh, rc
Shinya Kitaoka 120a6e
                              //,rz
Shinya Kitaoka 120a6e
                              ,
Shinya Kitaoka 120a6e
                              ref_mode, pix_rend,
Shinya Kitaoka 120a6e
                              (1 == direction) ? false : true);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else if (std::numeric_limits<unsigned short="">::digits == bi) {</unsigned>
Shinya Kitaoka 120a6e
    if (std::numeric_limits<unsigned short="">::digits == refbi) {</unsigned>
Shinya Kitaoka 120a6e
      if ((0 == direction) || (2 == direction)) {
Shinya Kitaoka 120a6e
        change_template_hori_(
Shinya Kitaoka 120a6e
            reinterpret_cast<unsigned *="" short="">(in), ww, hh, cc,</unsigned>
Shinya Kitaoka 120a6e
            reinterpret_cast<const *="" short="" unsigned="">(ref), rw, rh, rc</const>
Shinya Kitaoka 120a6e
            //,rz
Shinya Kitaoka 120a6e
            ,
Shinya Kitaoka 120a6e
            ref_mode, pix_rend, (0 == direction) ? false : true);
Shinya Kitaoka 120a6e
      } else if ((1 == direction) || (3 == direction)) {
Shinya Kitaoka 120a6e
        change_template_vert_(
Shinya Kitaoka 120a6e
            reinterpret_cast<unsigned *="" short="">(in), ww, hh, cc,</unsigned>
Shinya Kitaoka 120a6e
            reinterpret_cast<const *="" short="" unsigned="">(ref), rw, rh, rc</const>
Shinya Kitaoka 120a6e
            //,rz
Shinya Kitaoka 120a6e
            ,
Shinya Kitaoka 120a6e
            ref_mode, pix_rend, (1 == direction) ? false : true);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else { /* refbi is 8(uchar) or other(0...) */
Shinya Kitaoka 120a6e
      if ((0 == direction) || (2 == direction)) {
Shinya Kitaoka 120a6e
        change_template_hori_(
Shinya Kitaoka 120a6e
            reinterpret_cast<unsigned *="" short="">(in), ww, hh, cc, ref, rw, rh, rc</unsigned>
Shinya Kitaoka 120a6e
            //,rz
Shinya Kitaoka 120a6e
            ,
Shinya Kitaoka 120a6e
            ref_mode, pix_rend, (0 == direction) ? false : true);
Shinya Kitaoka 120a6e
      } else if ((1 == direction) || (3 == direction)) {
Shinya Kitaoka 120a6e
        change_template_vert_(
Shinya Kitaoka 120a6e
            reinterpret_cast<unsigned *="" short="">(in), ww, hh, cc, ref, rw, rh, rc</unsigned>
Shinya Kitaoka 120a6e
            //,rz
Shinya Kitaoka 120a6e
            ,
Shinya Kitaoka 120a6e
            ref_mode, pix_rend, (1 == direction) ? false : true);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    throw std::domain_error("Bad bits,Not uchar/ushort");
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  pix_rend.clear();
Toshihiro Shimizu 890ddd
}