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_level_auto final : public GlobalControllableFx {
Shinya Kitaoka 120a6e
  FX_PLUGIN_DECLARATION(ino_level_auto)
Shinya Kitaoka 120a6e
  TRasterFxPort m_input;
Shinya Kitaoka 120a6e
  TDoubleParamP m_in_min_shift;
Shinya Kitaoka 120a6e
  TDoubleParamP m_in_max_shift;
Shinya Kitaoka 120a6e
  TDoubleParamP m_out_min;
Shinya Kitaoka 120a6e
  TDoubleParamP m_out_max;
Shinya Kitaoka 120a6e
  TDoubleParamP m_gamma;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ino_level_auto()
Shinya Kitaoka 120a6e
      : m_in_min_shift(0.0 * ino::param_range())
Shinya Kitaoka 120a6e
      , m_in_max_shift(0.0 * ino::param_range())
Shinya Kitaoka 120a6e
      , m_out_min(0.0 * ino::param_range())
Shinya Kitaoka 120a6e
      , m_out_max(1.0 * ino::param_range())
Shinya Kitaoka 120a6e
      , m_gamma(1.0 * ino::param_range()) {
Shinya Kitaoka 120a6e
    addInputPort("Source", this->m_input);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    bindParam(this, "in_min_shift", this->m_in_min_shift);
Shinya Kitaoka 120a6e
    bindParam(this, "in_max_shift", this->m_in_max_shift);
Shinya Kitaoka 120a6e
    bindParam(this, "out_min", this->m_out_min);
Shinya Kitaoka 120a6e
    bindParam(this, "out_max", this->m_out_max);
Shinya Kitaoka 120a6e
    bindParam(this, "gamma", this->m_gamma);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    this->m_in_min_shift->setValueRange(-1.0 * ino::param_range(),
Shinya Kitaoka 120a6e
                                        1.0 * ino::param_range());
Shinya Kitaoka 120a6e
    this->m_in_max_shift->setValueRange(-1.0 * ino::param_range(),
Shinya Kitaoka 120a6e
                                        1.0 * ino::param_range());
Shinya Kitaoka 120a6e
    this->m_out_min->setValueRange(0.0 * ino::param_range(),
Shinya Kitaoka 120a6e
                                   1.0 * ino::param_range());
Shinya Kitaoka 120a6e
    this->m_out_max->setValueRange(0.0 * ino::param_range(),
Shinya Kitaoka 120a6e
                                   1.0 * ino::param_range());
Shinya Kitaoka 120a6e
    this->m_gamma->setValueRange(0.1 * ino::param_range(),
Shinya Kitaoka 120a6e
                                 10.0 * ino::param_range()); /* gamma値 */
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 38fd86
  bool canHandle(const TRenderSettings &info, double frame) override {
Shinya Kitaoka 38fd86
    return true;
Shinya Kitaoka 38fd86
  }
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_level_auto, "inoLevelAutoFx");
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
#include "igs_level_auto_in_camera.h"
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
void fx_(TRasterP in_ras, bool *act_sw, double *in_min_shift,
Shinya Kitaoka 120a6e
         double *in_max_shift, double *out_min, double *out_max, double *gamma,
Shinya Kitaoka 120a6e
         const int camera_x, const int camera_y, const int camera_w,
Shinya Kitaoka 120a6e
         const int camera_h) {
Shinya Kitaoka 120a6e
  TRasterGR8P in_gr8(in_ras->getLy(),
Shinya Kitaoka 120a6e
                     in_ras->getLx() * ino::channels() *
Shinya Kitaoka 120a6e
                         ((TRaster64P)in_ras ? sizeof(unsigned short)
Shinya Kitaoka 120a6e
                                             : sizeof(unsigned char)));
Shinya Kitaoka 120a6e
  in_gr8->lock();
Shinya Kitaoka 120a6e
  ino::ras_to_arr(in_ras, ino::channels(), in_gr8->getRawData());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* igs::level_auto::change(-)は今後つかわない2011-07-15 */
Shinya Kitaoka 120a6e
  igs::level_auto_in_camera::change(
Shinya Kitaoka 120a6e
      // in_ras->getRawData() // BGRA
Shinya Kitaoka 120a6e
      in_gr8->getRawData()
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
          ,
Shinya Kitaoka 120a6e
      in_ras->getLy(), in_ras->getLx()  // Must Not use in_ras->getWrap()
Shinya Kitaoka 120a6e
      ,
Shinya Kitaoka 120a6e
      ino::channels(), ino::bits(in_ras)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
                           ,
Shinya Kitaoka 120a6e
      act_sw, in_min_shift, in_max_shift, out_min, out_max, gamma, camera_x,
Shinya Kitaoka 120a6e
      camera_y, camera_w, camera_h);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ino::arr_to_ras(in_gr8->getRawData(), ino::channels(), in_ras, 0);
Shinya Kitaoka 120a6e
  in_gr8->unlock();
Toshihiro Shimizu 890ddd
}
shun-iwasawa 8cac36
}  // namespace
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Shinya Kitaoka 120a6e
void ino_level_auto::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タイプはエラーを投げる --- */
Shinya Kitaoka 120a6e
  if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster())) {
Shinya Kitaoka 120a6e
    throw TRopException("unsupported input pixel type");
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* ------ 動作パラメータを得る ---------------------------- */
Shinya Kitaoka 120a6e
  bool act_sw[4];
Shinya Kitaoka 120a6e
  double in_min_sft[4];
Shinya Kitaoka 120a6e
  double in_max_sft[4];
Shinya Kitaoka 120a6e
  double out_min[4];
Shinya Kitaoka 120a6e
  double out_max[4];
Shinya Kitaoka 120a6e
  double gamma[4];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  act_sw[0] = act_sw[1] = act_sw[2] = act_sw[3] = true;
Shinya Kitaoka 120a6e
  in_min_sft[0] = in_min_sft[1] = in_min_sft[2] = in_min_sft[3] =
Shinya Kitaoka 120a6e
      this->m_in_min_shift->getValue(frame) / ino::param_range();
Shinya Kitaoka 120a6e
  in_max_sft[0] = in_max_sft[1] = in_max_sft[2] = in_max_sft[3] =
Shinya Kitaoka 120a6e
      this->m_in_max_shift->getValue(frame) / ino::param_range();
Shinya Kitaoka 120a6e
  out_min[0] = out_min[1] = out_min[2] = out_min[3] =
Shinya Kitaoka 120a6e
      this->m_out_min->getValue(frame) / ino::param_range();
Shinya Kitaoka 120a6e
  out_max[0] = out_max[1] = out_max[2] = out_max[3] =
Shinya Kitaoka 120a6e
      this->m_out_max->getValue(frame) / ino::param_range();
Shinya Kitaoka 120a6e
  gamma[0] = gamma[1] = gamma[2] = gamma[3] =
Shinya Kitaoka 120a6e
      static_cast<double>(this->m_gamma->getValue(frame) / ino::param_range());</double>
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
  /* ------ (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  act true"
Shinya Kitaoka 120a6e
       << "  in_min_shift " << in_min_sft[0] << "  in_max_shift "
Shinya Kitaoka 120a6e
       << in_max_sft[0] << "  out_min " << out_min[0] << "  out_max "
Shinya Kitaoka 120a6e
       << out_max[0] << "  gamma " << gamma[0] << "  frame " << frame
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;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /* ------ fx処理 ------------------------------------------ */
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    tile.getRaster()->lock();
Shinya Kitaoka 120a6e
    fx_(tile.getRaster(), act_sw, in_min_sft, in_max_sft, out_min, out_max,
Shinya Kitaoka 120a6e
        gamma, camera_x, camera_y, camera_w, camera_h);
Shinya Kitaoka 120a6e
    tile.getRaster()->unlock();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /* ------ error処理 --------------------------------------- */
Shinya Kitaoka 120a6e
  catch (std::bad_alloc &e) {
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) {
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 (...) {
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
}