Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
shun-iwasawa 481b59
// #include "trop.h"
Toshihiro Shimizu 890ddd
#include "tfxparam.h"
Toshihiro Shimizu 890ddd
#include <math.h></math.h>
Toshihiro Shimizu 890ddd
#include "stdfx.h"
Toshihiro Shimizu 890ddd
#include "hsvutil.h"
shun-iwasawa 8cac36
#include "globalcontrollablefx.h"
Toshihiro Shimizu 890ddd
shun-iwasawa 8cac36
class HSVKeyFx final : public GlobalControllableFx {
Shinya Kitaoka 120a6e
  FX_PLUGIN_DECLARATION(HSVKeyFx)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterFxPort m_input;
Shinya Kitaoka 120a6e
  TDoubleParamP m_h;
Shinya Kitaoka 120a6e
  TDoubleParamP m_s;
Shinya Kitaoka 120a6e
  TDoubleParamP m_v;
Shinya Kitaoka 120a6e
  TDoubleParamP m_hrange;
Shinya Kitaoka 120a6e
  TDoubleParamP m_srange;
Shinya Kitaoka 120a6e
  TDoubleParamP m_vrange;
Shinya Kitaoka 120a6e
  TBoolParamP m_gender;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  HSVKeyFx()
Shinya Kitaoka 120a6e
      : m_h(0.0)
Shinya Kitaoka 120a6e
      , m_s(0.0)
Shinya Kitaoka 120a6e
      , m_v(0.0)
Shinya Kitaoka 120a6e
      , m_hrange(0.0)
Shinya Kitaoka 120a6e
      , m_srange(0.0)
Shinya Kitaoka 120a6e
      , m_vrange(0.0)
Shinya Kitaoka 120a6e
      , m_gender(false) {
Shinya Kitaoka 120a6e
    bindParam(this, "h", m_h);
Shinya Kitaoka 120a6e
    bindParam(this, "s", m_s);
Shinya Kitaoka 120a6e
    bindParam(this, "v", m_v);
Shinya Kitaoka 120a6e
    bindParam(this, "h_range", m_hrange);
Shinya Kitaoka 120a6e
    bindParam(this, "s_range", m_srange);
Shinya Kitaoka 120a6e
    bindParam(this, "v_range", m_vrange);
Shinya Kitaoka 120a6e
    bindParam(this, "invert", m_gender);
Shinya Kitaoka 120a6e
    m_h->setValueRange(0.0, 360.0);
Shinya Kitaoka 120a6e
    m_s->setValueRange(0.0, 1.0);
Shinya Kitaoka 120a6e
    m_v->setValueRange(0.0, 1.0);
Shinya Kitaoka 120a6e
    m_hrange->setValueRange(0.0, 360.0);
Shinya Kitaoka 120a6e
    m_srange->setValueRange(0.0, 1.0);
Shinya Kitaoka 120a6e
    m_vrange->setValueRange(0.0, 1.0);
Shinya Kitaoka 120a6e
    addInputPort("Source", m_input);
shun-iwasawa 481b59
    enableComputeInFloat(true);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~HSVKeyFx(){};
Shinya Kitaoka 120a6e
Shinya Kitaoka 38fd86
  bool doGetBBox(double frame, TRectD &bBox,
Shinya Kitaoka 38fd86
                 const TRenderSettings &info) override {
Shinya Kitaoka 120a6e
    if (m_input.isConnected()) {
Shinya Kitaoka 120a6e
      m_input->doGetBBox(frame, bBox, info);
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void doCompute(TTile &tile, double frame, const TRenderSettings &) override;
Shinya Kitaoka 120a6e
Shinya Kitaoka 38fd86
  bool canHandle(const TRenderSettings &info, double frame) override {
Shinya Kitaoka 38fd86
    return true;
Shinya Kitaoka 38fd86
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixel=""></typename>
Toshihiro Shimizu 890ddd
void doHSVKey(const TRasterPT<pixel> &ras, double lowH, double highH,</pixel>
Shinya Kitaoka 120a6e
              double lowS, double highS, double lowV, double highV,
Shinya Kitaoka 120a6e
              bool gender) {
Shinya Kitaoka 120a6e
  double aux = (double)PIXEL::maxChannelValue;
Shinya Kitaoka 120a6e
  int j;
Shinya Kitaoka 120a6e
  ras->lock();
Shinya Kitaoka 120a6e
  for (j = 0; j < ras->getLy(); j++) {
Shinya Kitaoka 120a6e
    PIXEL *pix    = ras->pixels(j);
Shinya Kitaoka 120a6e
    PIXEL *endPix = pix + ras->getLx();
Shinya Kitaoka 120a6e
    while (pix < endPix) {
Shinya Kitaoka 120a6e
      double h, s, v;
Shinya Kitaoka 120a6e
      OLDRGB2HSV(pix->r / aux, pix->g / aux, pix->b / aux, &h, &s, &v);
Shinya Kitaoka 120a6e
      bool condition = h >= lowH && h <= highH && s >= lowS && s <= highS &&
Shinya Kitaoka 120a6e
                       v >= lowV && v <= highV;
Shinya Kitaoka 120a6e
      if (condition != gender) *pix = PIXEL::Transparent;
Shinya Kitaoka 120a6e
      pix++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  ras->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void HSVKeyFx::doCompute(TTile &tile, double frame, const TRenderSettings &ri) {
Shinya Kitaoka 120a6e
  if (!m_input.isConnected()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_input->compute(tile, frame, ri);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double h_ref = m_h->getValue(frame);
Shinya Kitaoka 120a6e
  double s_ref = m_s->getValue(frame);
Shinya Kitaoka 120a6e
  double v_ref = m_v->getValue(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double h_range = m_hrange->getValue(frame);
Shinya Kitaoka 120a6e
  double s_range = m_srange->getValue(frame);
Shinya Kitaoka 120a6e
  double v_range = m_vrange->getValue(frame);
Shinya Kitaoka 120a6e
  bool gender    = (int)m_gender->getValue();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double lowH  = std::max(0.0, h_ref - h_range);
Shinya Kitaoka 120a6e
  double highH = std::min(360.0, h_ref + h_range);
Shinya Kitaoka 120a6e
  double lowS  = std::max(0.0, s_ref - s_range);
Shinya Kitaoka 120a6e
  double highS = std::min(1.0, s_ref + s_range);
Shinya Kitaoka 120a6e
  double lowV  = std::max(0.0, v_ref - v_range);
Shinya Kitaoka 120a6e
  double highV = std::min(1.0, v_ref + v_range);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster32P raster32 = tile.getRaster();
shun-iwasawa 481b59
  TRaster64P raster64 = tile.getRaster();
shun-iwasawa 481b59
  TRasterFP rasterF   = tile.getRaster();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (raster32)
Shinya Kitaoka 120a6e
    doHSVKey<tpixel32>(raster32, lowH, highH, lowS, highS, lowV, highV, gender);</tpixel32>
shun-iwasawa 481b59
  else if (raster64)
shun-iwasawa 481b59
    doHSVKey<tpixel64>(raster64, lowH, highH, lowS, highS, lowV, highV, gender);</tpixel64>
shun-iwasawa 481b59
  else if (rasterF)
shun-iwasawa 481b59
    doHSVKey<tpixelf>(rasterF, lowH, highH, lowS, highS, lowV, highV, gender);</tpixelf>
shun-iwasawa 481b59
  else
shun-iwasawa 481b59
    throw TException("HSVKey: unsupported Pixel Type");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(HSVKeyFx, "hsvKeyFx")