Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tfxparam.h"
Toshihiro Shimizu 890ddd
#include "stdfx.h"
Toshihiro Shimizu 890ddd
#include "tspectrumparam.h"
Toshihiro Shimizu 890ddd
#include "tpixelutils.h"
Toshihiro Shimizu 890ddd
#include "tparamuiconcept.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
inline void pixelConvert(TPixel32 &dst, const TPixel32 &src) { dst = src; }
Shinya Kitaoka 120a6e
inline void pixelConvert(TPixel64 &dst, const TPixel32 &src) {
Shinya Kitaoka 120a6e
  dst = toPixel64(src);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
}  // namespace
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
class FourPointsGradientFx : public TStandardZeraryFx {
Shinya Kitaoka 120a6e
  FX_PLUGIN_DECLARATION(FourPointsGradientFx)
Shinya Kitaoka 120a6e
  TSpectrumParamP m_colors;
Shinya Kitaoka 120a6e
  TPointParamP m_point1;
Shinya Kitaoka 120a6e
  TPointParamP m_point2;
Shinya Kitaoka 120a6e
  TPointParamP m_point3;
Shinya Kitaoka 120a6e
  TPointParamP m_point4;
Shinya Kitaoka 120a6e
  TPixelParamP m_color1;
Shinya Kitaoka 120a6e
  TPixelParamP m_color2;
Shinya Kitaoka 120a6e
  TPixelParamP m_color3;
Shinya Kitaoka 120a6e
  TPixelParamP m_color4;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  FourPointsGradientFx()
Shinya Kitaoka 120a6e
      : m_point1(TPointD(200.0, 200.0))
Shinya Kitaoka 120a6e
      , m_point2(TPointD(-200.0, 200.0))
Shinya Kitaoka 120a6e
      , m_point3(TPointD(-200.0, -200.0))
Shinya Kitaoka 120a6e
      , m_point4(TPointD(200.0, -200.0))
Shinya Kitaoka 120a6e
      , m_color1(TPixel32::Red)
Shinya Kitaoka 120a6e
      , m_color2(TPixel32::Green)
Shinya Kitaoka 120a6e
      , m_color3(TPixel32::Blue)
Shinya Kitaoka 120a6e
      , m_color4(TPixel32::Yellow) {
Shinya Kitaoka 120a6e
    m_point1->getX()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
    m_point1->getY()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
    m_point2->getX()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
    m_point2->getY()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
    m_point3->getX()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
    m_point3->getY()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
    m_point4->getX()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
    m_point4->getY()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
    /*
Shinya Kitaoka 120a6e
bindParam(this,"point1", m_point1);
Shinya Kitaoka 120a6e
bindParam(this,"point2", m_point2);
Shinya Kitaoka 120a6e
bindParam(this,"point3", m_point3);
Shinya Kitaoka 120a6e
bindParam(this,"point4", m_point4);
Shinya Kitaoka 120a6e
bindParam(this,"color_1", m_color1);
Shinya Kitaoka 120a6e
bindParam(this,"color_2", m_color2);
Shinya Kitaoka 120a6e
bindParam(this,"color_3", m_color3);
Shinya Kitaoka 120a6e
bindParam(this,"color_4", m_color4);
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
    bindParam(this, "Point_1", m_point1);
Shinya Kitaoka 120a6e
    bindParam(this, "Color_1", m_color1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    bindParam(this, "Point_2", m_point2);
Shinya Kitaoka 120a6e
    bindParam(this, "Color_2", m_color2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    bindParam(this, "Point_3", m_point3);
Shinya Kitaoka 120a6e
    bindParam(this, "Color_3", m_color3);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    bindParam(this, "Point_4", m_point4);
Shinya Kitaoka 120a6e
    bindParam(this, "Color_4", m_color4);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  ~FourPointsGradientFx(){};
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool doGetBBox(double, TRectD &bbox, const TRenderSettings &info) {
Shinya Kitaoka 120a6e
    bbox = TConsts::infiniteRectD;
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
  void doCompute(TTile &tile, double frame, const TRenderSettings &ri);
Shinya Kitaoka 120a6e
  bool canHandle(const TRenderSettings &info, double frame) { return true; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void getParamUIs(TParamUIConcept *&concepts, int &length) {
Shinya Kitaoka 120a6e
    concepts = new TParamUIConcept[length = 4];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    concepts[0].m_type  = TParamUIConcept::POINT;
Shinya Kitaoka 120a6e
    concepts[0].m_label = "Point 1";
Shinya Kitaoka 120a6e
    concepts[0].m_params.push_back(m_point1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    concepts[1].m_type  = TParamUIConcept::POINT;
Shinya Kitaoka 120a6e
    concepts[1].m_label = "Point 2";
Shinya Kitaoka 120a6e
    concepts[1].m_params.push_back(m_point2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    concepts[2].m_type  = TParamUIConcept::POINT;
Shinya Kitaoka 120a6e
    concepts[2].m_label = "Point 3";
Shinya Kitaoka 120a6e
    concepts[2].m_params.push_back(m_point3);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    concepts[3].m_type  = TParamUIConcept::POINT;
Shinya Kitaoka 120a6e
    concepts[3].m_label = "Point 4";
Shinya Kitaoka 120a6e
    concepts[3].m_params.push_back(m_point4);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename channel_type="" pixel,="" typename=""></typename>
Shinya Kitaoka 120a6e
void doFourPointsGradient(const TRasterPT<pixel> &ras, TPointD tilepos,</pixel>
Shinya Kitaoka 120a6e
                          TPointD pos1, TPointD pos2, TPointD pos3,
Shinya Kitaoka 120a6e
                          TPointD pos4, TPixel32 ccol1, TPixel32 ccol2,
Shinya Kitaoka 120a6e
                          TPixel32 ccol3, TPixel32 ccol4) {
Shinya Kitaoka 120a6e
  PIXEL col1, col2, col3, col4;
Shinya Kitaoka 120a6e
  pixelConvert(col1, ccol1);
Shinya Kitaoka 120a6e
  pixelConvert(col2, ccol2);
Shinya Kitaoka 120a6e
  pixelConvert(col3, ccol3);
Shinya Kitaoka 120a6e
  pixelConvert(col4, ccol4);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int j;
Shinya Kitaoka 120a6e
  ras->lock();
Shinya Kitaoka 120a6e
  for (j = 0; j < ras->getLy(); j++) {
Shinya Kitaoka 120a6e
    TPointD pos = tilepos;
Shinya Kitaoka 120a6e
    pos.y += 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 d1 = sqrt((pos1.x - pos.x) * (pos1.x - pos.x) +
Shinya Kitaoka 120a6e
                       (pos1.y - pos.y) * (pos1.y - pos.y));
Shinya Kitaoka 120a6e
      if (!d1) {
Shinya Kitaoka 120a6e
        *pix = col1;
Shinya Kitaoka 120a6e
        pos.x += 1;
Shinya Kitaoka 120a6e
        ++pix;
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      double d2 = sqrt((pos2.x - pos.x) * (pos2.x - pos.x) +
Shinya Kitaoka 120a6e
                       (pos2.y - pos.y) * (pos2.y - pos.y));
Shinya Kitaoka 120a6e
      if (!d2) {
Shinya Kitaoka 120a6e
        *pix = col2;
Shinya Kitaoka 120a6e
        pos.x += 1;
Shinya Kitaoka 120a6e
        ++pix;
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      double d3 = sqrt((pos3.x - pos.x) * (pos3.x - pos.x) +
Shinya Kitaoka 120a6e
                       (pos3.y - pos.y) * (pos3.y - pos.y));
Shinya Kitaoka 120a6e
      if (!d3) {
Shinya Kitaoka 120a6e
        *pix = col3;
Shinya Kitaoka 120a6e
        pos.x += 1;
Shinya Kitaoka 120a6e
        ++pix;
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      double d4 = sqrt((pos4.x - pos.x) * (pos4.x - pos.x) +
Shinya Kitaoka 120a6e
                       (pos4.y - pos.y) * (pos4.y - pos.y));
Shinya Kitaoka 120a6e
      if (!d4) {
Shinya Kitaoka 120a6e
        *pix = col4;
Shinya Kitaoka 120a6e
        pos.x += 1;
Shinya Kitaoka 120a6e
        ++pix;
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      double dtotal = 1 / d1 + 1 / d2 + 1 / d3 + 1 / d4;
Shinya Kitaoka 120a6e
      pix->r        = (CHANNEL_TYPE)(
Shinya Kitaoka 120a6e
          ((1 / d1) / dtotal) * col1.r + ((1 / d2) / dtotal) * col2.r +
Shinya Kitaoka 120a6e
          ((1 / d3) / dtotal) * col3.r + ((1 / d4) / dtotal) * col4.r);
Shinya Kitaoka 120a6e
      pix->g = (CHANNEL_TYPE)(
Shinya Kitaoka 120a6e
          ((1 / d1) / dtotal) * col1.g + ((1 / d2) / dtotal) * col2.g +
Shinya Kitaoka 120a6e
          ((1 / d3) / dtotal) * col3.g + ((1 / d4) / dtotal) * col4.g);
Shinya Kitaoka 120a6e
      pix->b = (CHANNEL_TYPE)(
Shinya Kitaoka 120a6e
          ((1 / d1) / dtotal) * col1.b + ((1 / d2) / dtotal) * col2.b +
Shinya Kitaoka 120a6e
          ((1 / d3) / dtotal) * col3.b + ((1 / d4) / dtotal) * col4.b);
Shinya Kitaoka 120a6e
      pix->m = (CHANNEL_TYPE)(
Shinya Kitaoka 120a6e
          ((1 / d1) / dtotal) * col1.m + ((1 / d2) / dtotal) * col2.m +
Shinya Kitaoka 120a6e
          ((1 / d3) / dtotal) * col3.m + ((1 / d4) / dtotal) * col4.m);
Shinya Kitaoka 120a6e
      pos.x += 1.0;
Shinya Kitaoka 120a6e
      ++pix;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  ras->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FourPointsGradientFx::doCompute(TTile &tile, double frame,
Shinya Kitaoka 120a6e
                                     const TRenderSettings &ri) {
Shinya Kitaoka 120a6e
  TPointD pos1  = m_point1->getValue(frame) * (1.0 / ri.m_shrinkX);
Shinya Kitaoka 120a6e
  TPointD pos2  = m_point2->getValue(frame) * (1.0 / ri.m_shrinkX);
Shinya Kitaoka 120a6e
  TPointD pos3  = m_point3->getValue(frame) * (1.0 / ri.m_shrinkX);
Shinya Kitaoka 120a6e
  TPointD pos4  = m_point4->getValue(frame) * (1.0 / ri.m_shrinkX);
Shinya Kitaoka 120a6e
  pos1          = ri.m_affine * pos1;
Shinya Kitaoka 120a6e
  pos2          = ri.m_affine * pos2;
Shinya Kitaoka 120a6e
  pos3          = ri.m_affine * pos3;
Shinya Kitaoka 120a6e
  pos4          = ri.m_affine * pos4;
Shinya Kitaoka 120a6e
  TPixel32 col1 = m_color1->getPremultipliedValue(frame);
Shinya Kitaoka 120a6e
  TPixel32 col2 = m_color2->getPremultipliedValue(frame);
Shinya Kitaoka 120a6e
  TPixel32 col3 = m_color3->getPremultipliedValue(frame);
Shinya Kitaoka 120a6e
  TPixel32 col4 = m_color4->getPremultipliedValue(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD pos         = tile.m_pos;
Shinya Kitaoka 120a6e
  TRaster32P raster32 = tile.getRaster();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (raster32)
Shinya Kitaoka 120a6e
    doFourPointsGradient<tpixel32, uchar="">(raster32, pos, pos1, pos2, pos3, pos4,</tpixel32,>
Shinya Kitaoka 120a6e
                                          col1, col2, col3, col4);
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    TRaster64P raster64 = tile.getRaster();
Shinya Kitaoka 120a6e
    if (raster64)
Shinya Kitaoka 120a6e
      doFourPointsGradient<tpixel64, ushort="">(raster64, pos, pos1, pos2, pos3,</tpixel64,>
Shinya Kitaoka 120a6e
                                             pos4, col1, col2, col3, col4);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      throw TException("Brightness&Contrast: unsupported Pixel Type");
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(FourPointsGradientFx, "fourPointsGradientFx");