Toshihiro Shimizu 890ddd
// #include <iostream></iostream>
Toshihiro Shimizu 890ddd
#include "igs_motion_wind_table.h"
Toshihiro Shimizu 890ddd
#include "igs_motion_wind_pixel.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
igs::motion_wind::pixel::pixel(
Shinya Kitaoka 120a6e
    const bool blow_dark_sw, const bool blow_alpha_sw
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const unsigned long length_random_seed, const double length_min,
Shinya Kitaoka 120a6e
    const double length_max, const double length_bias, const bool length_ref_sw
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const unsigned long force_random_seed, const double force_min,
Shinya Kitaoka 120a6e
    const double force_max, const double force_bias, const bool force_ref_sw
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const unsigned long density_random_seed, const double density_min,
Shinya Kitaoka 120a6e
    const double density_max, const double density_bias,
Shinya Kitaoka 120a6e
    const bool density_ref_sw)
Shinya Kitaoka 120a6e
    : blow_dark_sw_(blow_dark_sw)
Shinya Kitaoka 120a6e
    , blow_alpha_sw_(blow_alpha_sw)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    , length_min_(length_min)
Shinya Kitaoka 120a6e
    , length_max_(length_max)
Shinya Kitaoka 120a6e
    , length_bias_(length_bias)
Shinya Kitaoka 120a6e
    , length_ref_sw_(length_ref_sw)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    , force_min_(force_min)
Shinya Kitaoka 120a6e
    , force_max_(force_max)
Shinya Kitaoka 120a6e
    , force_bias_(force_bias)
Shinya Kitaoka 120a6e
    , force_ref_sw_(force_ref_sw)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    , density_min_(density_min)
Shinya Kitaoka 120a6e
    , density_max_(density_max)
Shinya Kitaoka 120a6e
    , density_bias_(density_bias)
Shinya Kitaoka 120a6e
    , density_ref_sw_(density_ref_sw)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    , key_lightness_(0)
Shinya Kitaoka 120a6e
    , table_len_(0)
Shinya Kitaoka 120a6e
    , table_pos_(0)
Shinya Kitaoka 120a6e
    , table_array_(0) {
Shinya Kitaoka 120a6e
  this->table_.resize(igs::motion_wind::table_size(length_min, length_max));
Shinya Kitaoka 120a6e
  this->length_random_.seed(length_random_seed);
Shinya Kitaoka 120a6e
  this->force_random_.seed(force_random_seed);
Shinya Kitaoka 120a6e
  this->density_random_.seed(density_random_seed);
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
void igs::motion_wind::pixel::clear(void) { this->table_.clear(); }
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
void wind_rgba_(const double key, const double alp, const double ratio,
Shinya Kitaoka 120a6e
                bool &sw, double &tgt) {
Shinya Kitaoka 120a6e
  if (tgt < key) {
Shinya Kitaoka 120a6e
    tgt += ratio * (key - tgt) * alp;
Shinya Kitaoka 120a6e
    tgt = (tgt < 0.0) ? 0.0 : ((1.0 < tgt) ? 1.0 : tgt);  // limit
Shinya Kitaoka 120a6e
    sw  = true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
void wind_rgb_(const double key, const double ratio, bool &sw, double &tgt) {
Shinya Kitaoka 120a6e
  if (tgt < key) {
Shinya Kitaoka 120a6e
    // std::cout << "(R" << ratio << ",K" << key << ",T" << tgt;
Shinya Kitaoka 120a6e
    tgt += ratio * (key - tgt);
Shinya Kitaoka 120a6e
    // std::cout << ">" << tgt << ")\n";
Shinya Kitaoka 120a6e
    tgt = (tgt < 0.0) ? 0.0 : ((1.0 < tgt) ? 1.0 : tgt);  // limit
Shinya Kitaoka 120a6e
    sw  = true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
void wind_a_(const double key /* alpha値 */
Shinya Kitaoka 120a6e
             ,
Shinya Kitaoka 120a6e
             const double ratio, const bool sw, double &tgt /* alpha値 */
Shinya Kitaoka 120a6e
             ) {
Shinya Kitaoka 120a6e
  if ((tgt < key) || sw) {
Shinya Kitaoka 120a6e
    double val = tgt + (ratio * (key - tgt));
Shinya Kitaoka 120a6e
    if (tgt < val) { /* 元より明るいときのみ変化 */
Shinya Kitaoka 120a6e
      tgt = val;
Shinya Kitaoka 120a6e
      tgt = (tgt < 0.0) ? 0.0 : ((1.0 < tgt) ? 1.0 : tgt);  // limit
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
void blow_wind_(/* 風の影響による値の変化 */
Shinya Kitaoka 120a6e
                const int channels, const double *key, const double *tbl_a,
Shinya Kitaoka 120a6e
                const int tbl_p, const bool blow_alpha_sw, double *tgt) {
Shinya Kitaoka 120a6e
  bool sw = false; /* rgb風を実行したか否かを示す */
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (igs::image::rgba::siz == channels) { /* Alphaがある */
Shinya Kitaoka 120a6e
    using namespace igs::image::rgba;
Shinya Kitaoka 120a6e
    if (blow_alpha_sw) { /* Alpha風を実行する */
Shinya Kitaoka 120a6e
                         /* RGB風 */
Shinya Kitaoka 120a6e
      wind_rgb_(key[red], tbl_a[tbl_p], sw, tgt[red]);
Shinya Kitaoka 120a6e
      wind_rgb_(key[gre], tbl_a[tbl_p], sw, tgt[gre]);
Shinya Kitaoka 120a6e
      wind_rgb_(key[blu], tbl_a[tbl_p], sw, tgt[blu]);
Shinya Kitaoka 120a6e
      /* Alpha風 */
Shinya Kitaoka 120a6e
      /* Alpha独自の風と、RGB風の、両方の影響による値の変化 */
Shinya Kitaoka 120a6e
      wind_a_(key[alp], tbl_a[tbl_p], sw, tgt[alp]);
Shinya Kitaoka 120a6e
    } else { /* Alpha風を実行せず、マスク抜きのRGB風を生成 */
Shinya Kitaoka 120a6e
      wind_rgba_(key[red], tgt[alp], tbl_a[tbl_p], sw, tgt[red]);
Shinya Kitaoka 120a6e
      wind_rgba_(key[gre], tgt[alp], tbl_a[tbl_p], sw, tgt[gre]);
Shinya Kitaoka 120a6e
      wind_rgba_(key[blu], tgt[alp], tbl_a[tbl_p], sw, tgt[blu]);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else { /* channel毎に風を生成する */
Shinya Kitaoka 120a6e
    for (int zz = 0; zz < channels; ++zz) {
Shinya Kitaoka 120a6e
      wind_rgb_(key[zz], tbl_a[tbl_p], sw, tgt[zz]);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
void invert_pixel_(const int channels, double *pixel) {
Shinya Kitaoka 120a6e
  if (igs::image::rgba::siz == channels) { /* Alphaがある */
Shinya Kitaoka 120a6e
    using namespace igs::image::rgba;
Shinya Kitaoka 120a6e
    pixel[red] = (1.0 - pixel[red]) * pixel[alp];
Shinya Kitaoka 120a6e
    pixel[gre] = (1.0 - pixel[gre]) * pixel[alp];
Shinya Kitaoka 120a6e
    pixel[blu] = (1.0 - pixel[blu]) * pixel[alp];
Shinya Kitaoka 120a6e
  } else /* Alphaがないなら、ただ白黒反転 */
Shinya Kitaoka 120a6e
      if (igs::image::rgb::siz == channels) {
Shinya Kitaoka 120a6e
    using namespace igs::image::rgb;
Shinya Kitaoka 120a6e
    pixel[red] = 1.0 - pixel[red];
Shinya Kitaoka 120a6e
    pixel[gre] = 1.0 - pixel[gre];
Shinya Kitaoka 120a6e
    pixel[blu] = 1.0 - pixel[blu];
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    for (int zz = 0; zz < channels; ++zz) {
Shinya Kitaoka 120a6e
      pixel[zz] = 1.0 - pixel[zz];
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
void rgb_to_lightness_(const double re, const double gr, const double bl,
Shinya Kitaoka 120a6e
                       double &li) {
Shinya Kitaoka 120a6e
  li = ((re < gr) ? ((gr < bl) ? bl : gr)
Rozhuk Ivan 823a31
                  : (((re < bl) ? bl : re) + ((gr < re) ? ((bl < gr) ? bl : gr)
Rozhuk Ivan 823a31
                                                        : ((bl < re) ? bl : re)))) /
Shinya Kitaoka 120a6e
       2.0;
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
double get_lightness_(const int channels, const double *pixel
Shinya Kitaoka 120a6e
                      // , const bool blow_dark_sw
Shinya Kitaoka 120a6e
                      ) {
Shinya Kitaoka 120a6e
  double lightness;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (igs::image::rgba::siz == channels) {
Shinya Kitaoka 120a6e
    using namespace igs::image::rgba;
Shinya Kitaoka 120a6e
    rgb_to_lightness_(pixel[red], pixel[gre], pixel[blu], lightness);
Shinya Kitaoka 120a6e
  } else if (igs::image::rgb::siz == channels) {
Shinya Kitaoka 120a6e
    using namespace igs::image::rgb;
Shinya Kitaoka 120a6e
    rgb_to_lightness_(pixel[red], pixel[gre], pixel[blu], lightness);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    lightness = pixel[0];
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /* 指定があるなら白黒反転 */
Shinya Kitaoka 120a6e
  // if (blow_dark_sw) { lightness = 1.0 - lightness; }
Shinya Kitaoka 120a6e
  return lightness;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
int igs::motion_wind::pixel::change(
Shinya Kitaoka 120a6e
    const bool key_reset_sw
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    /***, const int ref_channel
Shinya Kitaoka 120a6e
    , const double *ref_pixel***/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double ref_val /* ゼロ以上なら有効値、マイナスなら無効 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int channels, double *pixel_tgt) {
Shinya Kitaoka 120a6e
  /* 指定があるなら白黒反転、
Shinya Kitaoka 120a6e
  このプログラム内ではすべて明るさで処理する */
Shinya Kitaoka 120a6e
  if (this->blow_dark_sw_) {
Shinya Kitaoka 120a6e
    invert_pixel_(channels, pixel_tgt);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* 現位置の明るさを求める */
Shinya Kitaoka 120a6e
  const double crnt_lightness =
Shinya Kitaoka 120a6e
      get_lightness_(channels, pixel_tgt  // , this->blow_dark_sw_
Shinya Kitaoka 120a6e
                     );
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* スキャンラインの始点のではkey pixel値のreset */
Shinya Kitaoka 120a6e
  if (key_reset_sw) {
Shinya Kitaoka 120a6e
    this->key_lightness_ = crnt_lightness;
Shinya Kitaoka 120a6e
    for (int ii = 0; ii < channels; ++ii) {
Shinya Kitaoka 120a6e
      this->pixel_key_[ii] = pixel_tgt[ii];
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* 値がkeyより小さい(山の頂上より小さい)時 */
Shinya Kitaoka 120a6e
  if (crnt_lightness < this->key_lightness_) {
Shinya Kitaoka 120a6e
    /* 風テーブルがゼロなら
Shinya Kitaoka 120a6e
    風データを設定し、風テーブルを設定する */
Shinya Kitaoka 120a6e
    if (0 == this->table_array_) {
Shinya Kitaoka 120a6e
      double length_min   = this->length_min_;
Shinya Kitaoka 120a6e
      double length_max   = this->length_max_;
Shinya Kitaoka 120a6e
      double length_bias  = this->length_bias_;
Shinya Kitaoka 120a6e
      double force_min    = this->force_min_;
Shinya Kitaoka 120a6e
      double force_max    = this->force_max_;
Shinya Kitaoka 120a6e
      double force_bias   = this->force_bias_;
Shinya Kitaoka 120a6e
      double density_min  = this->density_min_;
Shinya Kitaoka 120a6e
      double density_max  = this->density_max_;
Shinya Kitaoka 120a6e
      double density_bias = this->density_bias_;
Toshihiro Shimizu 890ddd
#if 0
Toshihiro Shimizu 890ddd
			double ref_value;
Toshihiro Shimizu 890ddd
			/* 画像から強弱を得る */
Toshihiro Shimizu 890ddd
			if (0 != ref_pixel) {/* 参照画像のRGBAから */
Toshihiro Shimizu 890ddd
				ref_value = ref_pixel[ref_channel];
Toshihiro Shimizu 890ddd
			} else { /* 自画像から強弱を得る */
Toshihiro Shimizu 890ddd
				ref_value = get_lightness_(
Toshihiro Shimizu 890ddd
					channels, pixel_tgt);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
      double ref_value = ref_val;
Shinya Kitaoka 120a6e
      /* 参照画像から取らないときは自画像から強弱を得る */
Shinya Kitaoka 120a6e
      if (ref_value < 0.0) {
Shinya Kitaoka 120a6e
        ref_value = get_lightness_(channels, pixel_tgt);
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (this->length_ref_sw_) {
Shinya Kitaoka 120a6e
        length_min *= ref_value;
Shinya Kitaoka 120a6e
        length_max *= ref_value;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (this->force_ref_sw_) {
Shinya Kitaoka 120a6e
        force_min *= ref_value;
Shinya Kitaoka 120a6e
        force_max *= ref_value;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (this->density_ref_sw_) {
Shinya Kitaoka 120a6e
        density_min *= ref_value;
Shinya Kitaoka 120a6e
        density_max *= ref_value;
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      /* 風データを得る(流れのパターンの更新) */
Shinya Kitaoka 120a6e
      /***std::cout
Shinya Kitaoka 120a6e
<< "lmin " << length_min << "  lmax " << length_max
Shinya Kitaoka 120a6e
<< "\ncmin " << force_min  << "  cmax " << force_max
Shinya Kitaoka 120a6e
<< "\nhmin " << density_min << "  hmax " << density_max
Shinya Kitaoka 120a6e
<< "\n"
Toshihiro Shimizu 890ddd
;***/
Shinya Kitaoka 120a6e
      /* 更新した、風データを、カレントにセットする */
Shinya Kitaoka 120a6e
      this->table_len_ = igs::motion_wind::make_table(
Shinya Kitaoka 120a6e
          this->table_, this->length_random_, this->force_random_,
Shinya Kitaoka 120a6e
          this->density_random_, length_min, length_max, length_bias, force_min,
Shinya Kitaoka 120a6e
          force_max, force_bias, density_min, density_max, density_bias);
Shinya Kitaoka 120a6e
      this->table_array_ = &this->table_.at(0);
Shinya Kitaoka 120a6e
      this->table_pos_   = 1;
Shinya Kitaoka 120a6e
      /***for (int ii=0;ii<this->table_len_;++ii) {</this->
Toshihiro Shimizu 890ddd
std::cout << this->table_array_[ii] << "\n";
Toshihiro Shimizu 890ddd
}***/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      /* 風の中である。
Shinya Kitaoka 120a6e
      風の長さは1かもしれない... */
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    /* 風に影響された値を出力値にいれる */
Shinya Kitaoka 120a6e
    if (this->table_pos_ < this->table_len_) {
Shinya Kitaoka 120a6e
      /* 風の計算 */
Shinya Kitaoka 120a6e
      blow_wind_(channels, this->pixel_key_, this->table_array_,
Shinya Kitaoka 120a6e
                 this->table_pos_, this->blow_alpha_sw_, pixel_tgt);
Shinya Kitaoka 120a6e
      ++this->table_pos_;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      /* 保存すべき値となったので白黒反転を戻す */
Shinya Kitaoka 120a6e
      if (this->blow_dark_sw_) {
Shinya Kitaoka 120a6e
        invert_pixel_(channels, pixel_tgt);
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      return true; /* 風ん中 */
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /*	ここに来たということは、
Shinya Kitaoka 120a6e
          風の外である、
Shinya Kitaoka 120a6e
                  つまり風の影響範囲からはずれたとき、
Shinya Kitaoka 120a6e
                  つまりtable_pos_がtable_len_から外れた、
Shinya Kitaoka 120a6e
          あるいは、
Shinya Kitaoka 120a6e
          値が等しいかkeyより大きい値のとき、
Shinya Kitaoka 120a6e
                  つまりcrnt_lightnessがkey_lightness_以上、
Shinya Kitaoka 120a6e
          なので、現在値をメモリする(keyにいれる)
Shinya Kitaoka 120a6e
  */
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  this->key_lightness_ = crnt_lightness;
Shinya Kitaoka 120a6e
  for (int ii = 0L; ii < channels; ++ii) {
Shinya Kitaoka 120a6e
    this->pixel_key_[ii] = pixel_tgt[ii];
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* 風が途切れたので風テーブルをゼロとする */
Shinya Kitaoka 120a6e
  this->table_array_ = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return false; /* 風の外 */
Toshihiro Shimizu 890ddd
}