Toshihiro Shimizu 890ddd
#include <sstream> /* std::ostringstream */</sstream>
Toshihiro Shimizu 890ddd
#include "tfxparam.h"
Toshihiro Shimizu 890ddd
#include "stdfx.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "ino_common.h"
shun-iwasawa 8cac36
#include "globalcontrollablefx.h"
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
shun-iwasawa 8cac36
class ino_hsv_noise final : public GlobalControllableFx {
Shinya Kitaoka 120a6e
  FX_PLUGIN_DECLARATION(ino_hsv_noise)
Shinya Kitaoka 120a6e
  TRasterFxPort m_input;
Shinya Kitaoka 120a6e
  TRasterFxPort m_refer;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TDoubleParamP m_hue;
Shinya Kitaoka 120a6e
  TDoubleParamP m_sat;
Shinya Kitaoka 120a6e
  TDoubleParamP m_val;
Shinya Kitaoka 120a6e
  TDoubleParamP m_mat;
Shinya Kitaoka 120a6e
  TDoubleParamP m_random_seed;
Shinya Kitaoka 120a6e
  TDoubleParamP m_near_blur;
Shinya Kitaoka 120a6e
  TDoubleParamP m_term_effective;
Shinya Kitaoka 120a6e
  TDoubleParamP m_term_center;
Shinya Kitaoka 120a6e
  TIntEnumParamP m_term_type;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TBoolParamP m_anti_alias;
Shinya Kitaoka 120a6e
  TIntEnumParamP m_ref_mode;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ino_hsv_noise()
Shinya Kitaoka 120a6e
      : m_hue(0.025 * ino::param_range())
Shinya Kitaoka 120a6e
      , m_sat(0.0 * ino::param_range())
Shinya Kitaoka 120a6e
      , m_val(0.035 * ino::param_range())
Shinya Kitaoka 120a6e
      , m_mat(0.0 * ino::param_range())
Shinya Kitaoka 120a6e
      , m_random_seed(1)
Shinya Kitaoka 120a6e
      , m_near_blur(1.0 * ino::param_range())
Shinya Kitaoka 120a6e
      , m_term_effective(0.0 * ino::param_range())
Shinya Kitaoka 120a6e
      , m_term_center(ino::param_range() / 2.0)
Shinya Kitaoka 120a6e
      , m_term_type(new TIntEnumParam(0, "Keep Noise"))
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      , m_anti_alias(true)
Shinya Kitaoka 120a6e
      , m_ref_mode(new TIntEnumParam(0, "Red")) {
Shinya Kitaoka 120a6e
    addInputPort("Source", this->m_input);
Shinya Kitaoka 120a6e
    addInputPort("Reference", this->m_refer);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    bindParam(this, "hue", this->m_hue);
Shinya Kitaoka 120a6e
    bindParam(this, "saturation", this->m_sat);
Shinya Kitaoka 120a6e
    bindParam(this, "value", this->m_val);
Shinya Kitaoka 120a6e
    bindParam(this, "alpha", this->m_mat);
Shinya Kitaoka 120a6e
    bindParam(this, "seed", this->m_random_seed);
Shinya Kitaoka 120a6e
    bindParam(this, "nblur", this->m_near_blur);
Shinya Kitaoka 120a6e
    bindParam(this, "effective", this->m_term_effective);
Shinya Kitaoka 120a6e
    bindParam(this, "center", this->m_term_center);
Shinya Kitaoka 120a6e
    bindParam(this, "type", this->m_term_type);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    bindParam(this, "anti_alias", this->m_anti_alias);
Shinya Kitaoka 120a6e
    bindParam(this, "reference", this->m_ref_mode);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    this->m_hue->setValueRange(0.0 * ino::param_range(),
Shinya Kitaoka 120a6e
                               1.0 * ino::param_range());
Shinya Kitaoka 120a6e
    this->m_sat->setValueRange(0.0 * ino::param_range(),
Shinya Kitaoka 120a6e
                               1.0 * ino::param_range());
Shinya Kitaoka 120a6e
    this->m_val->setValueRange(0.0 * ino::param_range(),
Shinya Kitaoka 120a6e
                               1.0 * ino::param_range());
Shinya Kitaoka 120a6e
    this->m_mat->setValueRange(0.0 * ino::param_range(),
Shinya Kitaoka 120a6e
                               1.0 * ino::param_range());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    this->m_random_seed->setValueRange(
Shinya Kitaoka 120a6e
        0, std::numeric_limits<unsigned long="">::max());</unsigned>
Shinya Kitaoka 120a6e
    this->m_near_blur->setValueRange(0.0 * ino::param_range(),
Shinya Kitaoka 120a6e
                                     1.0 * ino::param_range());
Shinya Kitaoka 120a6e
    this->m_term_effective->setValueRange(0.0 * ino::param_range(),
Shinya Kitaoka 120a6e
                                          1.0 * ino::param_range());
Shinya Kitaoka 120a6e
    this->m_term_center->setValueRange(0.0 * ino::param_range(),
Shinya Kitaoka 120a6e
                                       1.0 * ino::param_range());
Shinya Kitaoka 120a6e
    this->m_term_type->addItem(1, "Keep Contrast");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    this->m_ref_mode->addItem(1, "Green");
Shinya Kitaoka 120a6e
    this->m_ref_mode->addItem(2, "Blue");
Shinya Kitaoka 120a6e
    this->m_ref_mode->addItem(3, "Alpha");
Shinya Kitaoka 120a6e
    this->m_ref_mode->addItem(4, "Luminance");
Shinya Kitaoka 120a6e
    this->m_ref_mode->addItem(-1, "Nothing");
shun-iwasawa 481b59
shun-iwasawa 481b59
    enableComputeInFloat(true);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 38fd86
  bool doGetBBox(double frame, TRectD &bBox,
Shinya Kitaoka 38fd86
                 const TRenderSettings &info) override {
Shinya Kitaoka 120a6e
    if (this->m_input.isConnected()) {
Shinya Kitaoka 120a6e
      return this->m_input->doGetBBox(frame, bBox, info);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      bBox = TRectD();
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  bool canHandle(const TRenderSettings &info, double frame) override {
Shinya Kitaoka 120a6e
    // return true;
Shinya Kitaoka 120a6e
    /* trueだと素材がスライドして現れるときノイズパターンが
Shinya Kitaoka 120a6e
    変わってしまう 2013-4-5からtoonz上で変更した */
Shinya Kitaoka 120a6e
    /* でなく、
Shinya Kitaoka 120a6e
    ここでの指定にかかわらず、
Shinya Kitaoka 120a6e
    素材をカメラ範囲で切り取ってるため、
Shinya Kitaoka 120a6e
    スライドで現れるときのノイズパターンは変わってしまう。
Shinya Kitaoka 120a6e
    だたし、移動以外のGeometryがなく、
Shinya Kitaoka 120a6e
    連番の絵でなく一枚の絵を移動するだけのときは、
Shinya Kitaoka 120a6e
    Cashのため(?)ノイズパターンは変化しない。
Shinya Kitaoka 120a6e
    回転にノイズがついてくる。
Shinya Kitaoka 120a6e
    防ぐ方法はtileに素材の位置と大きさ情報があれば...
Shinya Kitaoka 120a6e
    2013-11-08 */
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 38fd86
  void doCompute(TTile &tile, double frame,
Shinya Kitaoka 38fd86
                 const TRenderSettings &rend_sets) override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(ino_hsv_noise, "inohsvNoiseFx");
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
#include "igs_hsv_noise.h"
Shinya Kitaoka 120a6e
namespace {
shun-iwasawa 481b59
void fx_(TRasterP in_ras, const TRasterP refer_ras, const int refer_mode,
Shinya Kitaoka 120a6e
         double hue_range, double sat_range, double val_range, double alp_range,
Shinya Kitaoka 120a6e
         unsigned long random_seed, double near_blur, double effective,
Shinya Kitaoka 120a6e
         double center, int type, const int camera_x, const int camera_y,
Shinya Kitaoka 120a6e
         const int camera_w, const int camera_h, const bool anti_alias_sw) {
shun-iwasawa 481b59
  TRasterGR8P ref_gr8;
shun-iwasawa 481b59
  if ((refer_ras != nullptr) && (0 <= refer_mode)) {
shun-iwasawa 481b59
    ref_gr8 = TRasterGR8P(in_ras->getLy(), in_ras->getLx() * sizeof(float));
shun-iwasawa 481b59
    ref_gr8->lock();
shun-iwasawa 481b59
    ino::ras_to_ref_float_arr(refer_ras,
shun-iwasawa 481b59
                              reinterpret_cast<float *="">(ref_gr8->getRawData()),</float>
shun-iwasawa 481b59
                              refer_mode);
shun-iwasawa 481b59
  }
shun-iwasawa 481b59
Shinya Kitaoka 120a6e
  TRasterGR8P in_gr8(in_ras->getLy(),
shun-iwasawa 481b59
                     in_ras->getLx() * ino::channels() * sizeof(float));
Shinya Kitaoka 120a6e
  in_gr8->lock();
shun-iwasawa 481b59
  ino::ras_to_float_arr(in_ras, ino::channels(),
shun-iwasawa 481b59
                        reinterpret_cast<float *="">(in_gr8->getRawData()));</float>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  igs::hsv_noise::change(
shun-iwasawa 481b59
      reinterpret_cast<float *="">(in_gr8->getRawData()), in_ras->getLy(),</float>
shun-iwasawa 481b59
      in_ras->getLx(),  // Must Not use in_ras->getWrap()
shun-iwasawa 481b59
      ino::channels(),
shun-iwasawa 481b59
      (ref_gr8) ? reinterpret_cast<float *="">(ref_gr8->getRawData()) : nullptr,</float>
shun-iwasawa 481b59
      camera_x, camera_y, camera_w, camera_h, hue_range, sat_range, val_range,
shun-iwasawa 481b59
      alp_range, random_seed, near_blur, effective, center, type, effective,
shun-iwasawa 481b59
      center, type, effective, center, type, anti_alias_sw);
shun-iwasawa 481b59
shun-iwasawa 481b59
  ino::float_arr_to_ras(in_gr8->getRawData(), ino::channels(), in_ras, 0);
Shinya Kitaoka 120a6e
  in_gr8->unlock();
shun-iwasawa 481b59
shun-iwasawa 481b59
  if (ref_gr8) ref_gr8->unlock();
Toshihiro Shimizu 890ddd
}
shun-iwasawa 8cac36
}  // namespace
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Shinya Kitaoka 120a6e
void ino_hsv_noise::doCompute(TTile &tile, double frame,
Shinya Kitaoka 120a6e
                              const TRenderSettings &rend_sets) {
Shinya Kitaoka 120a6e
  /* ------ 接続していなければ処理しない -------------------- */
Shinya Kitaoka 120a6e
  if (!this->m_input.isConnected()) {
Shinya Kitaoka 120a6e
    tile.getRaster()->clear(); /* 塗りつぶしクリア */
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* ------ サポートしていないPixelタイプはエラーを投げる --- */
shun-iwasawa 481b59
  if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster()) &&
shun-iwasawa 481b59
      !((TRasterFP)tile.getRaster())) {
Shinya Kitaoka 120a6e
    throw TRopException("unsupported input pixel type");
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* ------ 動作パラメータを得る ---------------------------- */
Shinya Kitaoka 120a6e
  const double hue_range = this->m_hue->getValue(frame) / ino::param_range();
Shinya Kitaoka 120a6e
  const double sat_range = this->m_sat->getValue(frame) / ino::param_range();
Shinya Kitaoka 120a6e
  const double val_range = this->m_val->getValue(frame) / ino::param_range();
Shinya Kitaoka 120a6e
  const double mat_range = this->m_mat->getValue(frame) / ino::param_range();
Shinya Kitaoka 120a6e
  const unsigned long random_seed =
Shinya Kitaoka 120a6e
      static_cast<unsigned long="">(this->m_random_seed->getValue(frame));</unsigned>
Shinya Kitaoka 120a6e
  const double near_blur =
Shinya Kitaoka 120a6e
      this->m_near_blur->getValue(frame) / ino::param_range() / 2.0;
Shinya Kitaoka 120a6e
  int term_type = -1;
Shinya Kitaoka 120a6e
  switch (this->m_term_type->getValue()) {
Shinya Kitaoka 120a6e
  case 0:
Shinya Kitaoka 120a6e
    term_type = 0;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 1:
Shinya Kitaoka 120a6e
    term_type = 3;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  const double term_center =
Shinya Kitaoka 120a6e
      this->m_term_center->getValue(frame) / ino::param_range();
Shinya Kitaoka 120a6e
  const double term_effective =
Shinya Kitaoka 120a6e
      this->m_term_effective->getValue(frame) / ino::param_range();
Shinya Kitaoka 120a6e
  const bool anti_alias_sw = this->m_anti_alias->getValue();
masafumi-inoue 26f824
  const int refer_mode     = this->m_ref_mode->getValue();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* ------ 画像生成 ---------------------------------------- */
Shinya Kitaoka 120a6e
  this->m_input->compute(tile, frame, rend_sets);
Shinya Kitaoka 120a6e
  /*--- カメラの範囲をノイズを掛ける範囲としておく(余白含ず) -*/
Shinya Kitaoka 120a6e
  int camera_x = 0;
Shinya Kitaoka 120a6e
  int camera_y = 0;
Shinya Kitaoka 120a6e
  int camera_w = static_cast<int>(rend_sets.m_cameraBox.getLx() + 0.5);</int>
Shinya Kitaoka 120a6e
  int camera_h = static_cast<int>(rend_sets.m_cameraBox.getLy() + 0.5);</int>
Shinya Kitaoka 120a6e
  /*--- カメラ範囲外へのmargin付き(たぶん)はノイズ範囲から外す -*/
Shinya Kitaoka 120a6e
  const int margin_w = tile.getRaster()->getLx() - camera_w;
Shinya Kitaoka 120a6e
  const int margin_h = tile.getRaster()->getLy() - camera_h;
Shinya Kitaoka 120a6e
  if ((0 <= margin_h && 0 < margin_w)    /* 横方向のみ余白あり */
Shinya Kitaoka 120a6e
      || (0 < margin_h && 0 <= margin_w) /* 縦方向のみ余白あり */
Shinya Kitaoka 120a6e
      || (0 < margin_h && 0 < margin_w)  /* 縦横両方に余白あり */
shun-iwasawa 8cac36
  ) {
Shinya Kitaoka 120a6e
    /*camera_x = static_cast<int>(ceil((double)margin_w / 2.));</int>
Shinya Kitaoka 120a6e
    camera_y = static_cast<int>(ceil((double)margin_h / 2.));*/</int>
Shinya Kitaoka 120a6e
    camera_x = margin_w / 2;
Shinya Kitaoka 120a6e
    camera_y = margin_h / 2;
Shinya Kitaoka 120a6e
    camera_w = rend_sets.m_cameraBox.getLx();
Shinya Kitaoka 120a6e
    camera_h = rend_sets.m_cameraBox.getLy();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*--- 入力画像がカメラより一部でも小さい
Shinya Kitaoka 120a6e
          (ノイズ範囲指定対応できない-->懸案事項) ------------*/
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    camera_w = tile.getRaster()->getLx();
Shinya Kitaoka 120a6e
    camera_h = tile.getRaster()->getLy();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*------ 参照画像生成 --------------------------------------*/
masafumi-inoue 26f824
  TTile refer_tile;
masafumi-inoue 26f824
  bool refer_sw = false;
Shinya Kitaoka 120a6e
  if (this->m_refer.isConnected()) {
masafumi-inoue 26f824
    refer_sw = true;
Shinya Kitaoka 120a6e
    this->m_refer->allocateAndCompute(
masafumi-inoue 26f824
        refer_tile, tile.m_pos,
Shinya Kitaoka 120a6e
        TDimensionI(/* Pixel単位 */
Shinya Kitaoka 120a6e
                    tile.getRaster()->getLx(), tile.getRaster()->getLy()),
Shinya Kitaoka 120a6e
        tile.getRaster(), frame, rend_sets);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /* ------ (app_begin)log記憶 ------------------------------ */
Shinya Kitaoka 120a6e
  const bool log_sw = ino::log_enable_sw();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (log_sw) {
Shinya Kitaoka 120a6e
    std::ostringstream os;
Shinya Kitaoka 120a6e
    os << "params"
Shinya Kitaoka 120a6e
       << "  h " << hue_range << "  s " << sat_range << "  v " << val_range
Shinya Kitaoka 120a6e
       << "  a " << mat_range << "  seed " << random_seed << "  nblur "
Shinya Kitaoka 120a6e
       << near_blur << "  effective " << term_effective << "  center "
Shinya Kitaoka 120a6e
       << term_center << "  type " << term_type << "  frame " << frame
masafumi-inoue 26f824
       << "  anti_alias " << anti_alias_sw << "  reference " << refer_mode
Shinya Kitaoka 120a6e
       << "  pixbits " << ino::pixel_bits(tile.getRaster()) << "  tile.m_pos "
Shinya Kitaoka 120a6e
       << tile.m_pos << "  tile_getLx " << tile.getRaster()->getLx() << "  y "
Shinya Kitaoka 120a6e
       << tile.getRaster()->getLy() << "  rend_sets.m_cameraBox "
Shinya Kitaoka 120a6e
       << rend_sets.m_cameraBox << "  rend_sets.m_affine " << rend_sets.m_affine
Shinya Kitaoka 120a6e
       << "  camera x " << camera_x << "  y " << camera_y << "  w " << camera_w
Shinya Kitaoka 120a6e
       << "  h " << camera_h;
masafumi-inoue 26f824
    if (refer_sw) {
masafumi-inoue 26f824
      os << "  refer_tile.m_pos " << refer_tile.m_pos << "  refer_tile_getLx "
masafumi-inoue 26f824
         << refer_tile.getRaster()->getLx() << "  y "
masafumi-inoue 26f824
         << refer_tile.getRaster()->getLy();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /* ------ fx処理 ------------------------------------------ */
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    tile.getRaster()->lock();
masafumi-inoue 26f824
    if (refer_tile.getRaster() != nullptr) {
masafumi-inoue 26f824
      refer_tile.getRaster()->lock();
masafumi-inoue 26f824
    }
masafumi-inoue 26f824
    fx_(tile.getRaster(), refer_tile.getRaster(), refer_mode
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        ,
Shinya Kitaoka 120a6e
        hue_range, sat_range, val_range, mat_range, random_seed, near_blur,
Shinya Kitaoka 120a6e
        term_effective, term_center, term_type, camera_x, camera_y, camera_w,
Shinya Kitaoka 120a6e
        camera_h, anti_alias_sw  // --> add_blend_sw, default is true
shun-iwasawa 8cac36
    );
masafumi-inoue 26f824
    if (refer_tile.getRaster() != nullptr) {
masafumi-inoue 26f824
      refer_tile.getRaster()->unlock();
masafumi-inoue 26f824
    }
Shinya Kitaoka 120a6e
    tile.getRaster()->unlock();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /* ------ error処理 --------------------------------------- */
Shinya Kitaoka 120a6e
  catch (std::bad_alloc &e) {
masafumi-inoue 26f824
    if (refer_tile.getRaster() != nullptr) {
masafumi-inoue 26f824
      refer_tile.getRaster()->unlock();
masafumi-inoue 26f824
    }
Shinya Kitaoka 120a6e
    tile.getRaster()->unlock();
Shinya Kitaoka 120a6e
    if (log_sw) {
Shinya Kitaoka 120a6e
      std::string str("std::bad_alloc <");
Shinya Kitaoka 120a6e
      str += e.what();
Shinya Kitaoka 120a6e
      str += '>';
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    throw;
Shinya Kitaoka 120a6e
  } catch (std::exception &e) {
masafumi-inoue 26f824
    if (refer_tile.getRaster() != nullptr) {
masafumi-inoue 26f824
      refer_tile.getRaster()->unlock();
masafumi-inoue 26f824
    }
Shinya Kitaoka 120a6e
    tile.getRaster()->unlock();
Shinya Kitaoka 120a6e
    if (log_sw) {
Shinya Kitaoka 120a6e
      std::string str("exception <");
Shinya Kitaoka 120a6e
      str += e.what();
Shinya Kitaoka 120a6e
      str += '>';
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    throw;
Shinya Kitaoka 120a6e
  } catch (...) {
masafumi-inoue 26f824
    if (refer_tile.getRaster() != nullptr) {
masafumi-inoue 26f824
      refer_tile.getRaster()->unlock();
masafumi-inoue 26f824
    }
Shinya Kitaoka 120a6e
    tile.getRaster()->unlock();
Shinya Kitaoka 120a6e
    if (log_sw) {
Shinya Kitaoka 120a6e
      std::string str("other exception");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    throw;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}