Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "stdfx.h"
Toshihiro Shimizu 890ddd
#include "tfxparam.h"
shun-iwasawa 481b59
// #include "trop.h"
Toshihiro Shimizu 890ddd
#include "tdoubleparam.h"
shun-iwasawa 481b59
// #include "tnotanimatableparam.h"
Toshihiro Shimizu 890ddd
#include "tpixelgr.h"
Toshihiro Shimizu 890ddd
#include "trasterfx.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
enum Status {
Shinya Kitaoka 120a6e
  StatusGood        = 0,
Shinya Kitaoka 120a6e
  OutOfTime         = 1 << 1,  // Non utilizzato
Shinya Kitaoka 120a6e
  Port0NotConnected = 1 << 2,
Shinya Kitaoka 120a6e
  Port1NotConnected = 1 << 3,
Shinya Kitaoka 120a6e
  NoPortsConnected  = Port0NotConnected | Port1NotConnected
Toshihiro Shimizu 890ddd
};
Shinya Kitaoka 120a6e
inline Status operator|(const Status &l, const Status &r) {
Shinya Kitaoka 120a6e
  return Status(((int)l | (int)r));
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
inline int operator&(const Status &l) { return int(l); }
Shinya Kitaoka 120a6e
Status getFxStatus(const TRasterFxPort &port0, const TRasterFxPort &port1) {
shun-iwasawa 481b59
  Status status = StatusGood;
Shinya Kitaoka 120a6e
  if (!port0.isConnected()) status = status | Port0NotConnected;
Shinya Kitaoka 120a6e
  if (!port1.isConnected()) status = status | Port1NotConnected;
Shinya Kitaoka 120a6e
  return status;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*inline*/
Toshihiro Shimizu 890ddd
template <typename p="" q,="" t,="" typename=""></typename>
Shinya Kitaoka 120a6e
void doLocalTransparency(TRasterPT<t> out, TRasterPT<t> src, TRasterPT<t> ref,</t></t></t>
Shinya Kitaoka 120a6e
                         double transp) {
Shinya Kitaoka 120a6e
  out->lock();
Shinya Kitaoka 120a6e
  ref->lock();
Shinya Kitaoka 120a6e
  src->lock();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  T *outRow   = out->pixels();
Shinya Kitaoka 120a6e
  T *refRow   = ref->pixels();
Shinya Kitaoka 120a6e
  T *srcRow   = src->pixels();
Shinya Kitaoka 120a6e
  int outWrap = out->getWrap();
Shinya Kitaoka 120a6e
  int refWrap = ref->getWrap();
Shinya Kitaoka 120a6e
  int srcWrap = src->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  T *outPix  = outRow;
Shinya Kitaoka 120a6e
  T *srcPix  = srcRow;
Shinya Kitaoka 120a6e
  T *refPix  = refRow;
Shinya Kitaoka 120a6e
  T *lastPix = outRow + outWrap * out->getLy();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const int cropVal = T::maxChannelValue;
Shinya Kitaoka 120a6e
  double factor     = transp / (double)cropVal;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (outPix < lastPix) {
Shinya Kitaoka 120a6e
    T *endPix = outPix + out->getLx();
Shinya Kitaoka 120a6e
    while (outPix < endPix) {
Shinya Kitaoka 120a6e
      double local_transp = 1 - (Q::from(*refPix).value) * factor;
Shinya Kitaoka 120a6e
      if (local_transp > 0.0) {
Shinya Kitaoka 120a6e
        int val   = (int)(local_transp * srcPix->r + 0.5);
Shinya Kitaoka 120a6e
        outPix->r = (P)((val < cropVal) ? val : cropVal);
Shinya Kitaoka 120a6e
        val       = (int)(local_transp * srcPix->g + 0.5);
Shinya Kitaoka 120a6e
        outPix->g = (P)((val < cropVal) ? val : cropVal);
Shinya Kitaoka 120a6e
        val       = (int)(local_transp * srcPix->b + 0.5);
Shinya Kitaoka 120a6e
        outPix->b = (P)((val < cropVal) ? val : cropVal);
Shinya Kitaoka 120a6e
        val       = (int)(local_transp * srcPix->m + 0.5);
Shinya Kitaoka 120a6e
        outPix->m = (P)((val < cropVal) ? val : cropVal);
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        outPix->r = outPix->g = outPix->b = outPix->m = 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      ++outPix;
Shinya Kitaoka 120a6e
      ++refPix;
Shinya Kitaoka 120a6e
      ++srcPix;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    srcRow += srcWrap;
Shinya Kitaoka 120a6e
    outRow += outWrap;
Shinya Kitaoka 120a6e
    refRow += refWrap;
Shinya Kitaoka 120a6e
    srcPix = srcRow;
Shinya Kitaoka 120a6e
    outPix = outRow;
Shinya Kitaoka 120a6e
    refPix = refRow;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  out->unlock();
Shinya Kitaoka 120a6e
  ref->unlock();
Shinya Kitaoka 120a6e
  src->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
shun-iwasawa 481b59
template <>
shun-iwasawa 481b59
void doLocalTransparency<tpixelf, float="" tpixelgrf,="">(TRasterFP out,</tpixelf,>
shun-iwasawa 481b59
                                                    TRasterFP src,
shun-iwasawa 481b59
                                                    TRasterFP ref,
shun-iwasawa 481b59
                                                    double transp) {
shun-iwasawa 481b59
  out->lock();
shun-iwasawa 481b59
  ref->lock();
shun-iwasawa 481b59
  src->lock();
shun-iwasawa 481b59
shun-iwasawa 481b59
  TPixelF *outRow = out->pixels();
shun-iwasawa 481b59
  TPixelF *refRow = ref->pixels();
shun-iwasawa 481b59
  TPixelF *srcRow = src->pixels();
shun-iwasawa 481b59
  int outWrap     = out->getWrap();
shun-iwasawa 481b59
  int refWrap     = ref->getWrap();
shun-iwasawa 481b59
  int srcWrap     = src->getWrap();
shun-iwasawa 481b59
shun-iwasawa 481b59
  TPixelF *outPix  = outRow;
shun-iwasawa 481b59
  TPixelF *srcPix  = srcRow;
shun-iwasawa 481b59
  TPixelF *refPix  = refRow;
shun-iwasawa 481b59
  TPixelF *lastPix = outRow + outWrap * out->getLy();
shun-iwasawa 481b59
shun-iwasawa 481b59
  while (outPix < lastPix) {
shun-iwasawa 481b59
    TPixelF *endPix = outPix + out->getLx();
shun-iwasawa 481b59
    while (outPix < endPix) {
shun-iwasawa 481b59
      // clamp 0.f to 1.f in case computing HDR
shun-iwasawa 481b59
      float refv =
shun-iwasawa 481b59
          std::min(1.f, std::max(0.f, (TPixelGRF::from(*refPix).value)));
shun-iwasawa 481b59
      float local_transp = 1.f - refv * transp;
shun-iwasawa 481b59
      if (local_transp > 0.f) {
shun-iwasawa 481b59
        outPix->r = local_transp * srcPix->r;
shun-iwasawa 481b59
        outPix->g = local_transp * srcPix->g;
shun-iwasawa 481b59
        outPix->b = local_transp * srcPix->b;
shun-iwasawa 481b59
        outPix->m = local_transp * srcPix->m;
shun-iwasawa 481b59
      } else {
shun-iwasawa 481b59
        outPix->r = outPix->g = outPix->b = outPix->m = 0.f;
shun-iwasawa 481b59
      }
shun-iwasawa 481b59
      ++outPix;
shun-iwasawa 481b59
      ++refPix;
shun-iwasawa 481b59
      ++srcPix;
shun-iwasawa 481b59
    }
shun-iwasawa 481b59
    srcRow += srcWrap;
shun-iwasawa 481b59
    outRow += outWrap;
shun-iwasawa 481b59
    refRow += refWrap;
shun-iwasawa 481b59
    srcPix = srcRow;
shun-iwasawa 481b59
    outPix = outRow;
shun-iwasawa 481b59
    refPix = refRow;
shun-iwasawa 481b59
  }
shun-iwasawa 481b59
  out->unlock();
shun-iwasawa 481b59
  ref->unlock();
shun-iwasawa 481b59
  src->unlock();
shun-iwasawa 481b59
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline double func(int x, int y, int lx, int ly) {
Shinya Kitaoka 120a6e
  return ((1 + sin(3.14 * x / (0.5 * lx))) * (1 + cos(3.14 * y / (0.5 * ly))));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void drawCheckboard(TRaster32P &raster) {
Shinya Kitaoka 120a6e
  int lx = raster->getLx();
Shinya Kitaoka 120a6e
  int ly = raster->getLy();
Shinya Kitaoka 120a6e
  // int chessSize = 4;
Shinya Kitaoka 120a6e
  int x, y;
Shinya Kitaoka 120a6e
  raster->lock();
Shinya Kitaoka 120a6e
  for (y = 0; y < ly; ++y) {
Shinya Kitaoka 120a6e
    TPixel32 *pix = raster->pixels(y);
Shinya Kitaoka 120a6e
    for (x = 0; x < lx; ++x, ++pix) {
Shinya Kitaoka 120a6e
      pix->r = pix->g = pix->b =
Shinya Kitaoka 120a6e
          troundp(255.0 * func(x, y, lx, ly) / func(lx - 1, ly - 1, lx, ly));
Shinya Kitaoka 120a6e
      pix->m = 255;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  raster->unlock();
Toshihiro Shimizu 890ddd
}
shun-iwasawa 481b59
};  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class LocalTransparencyFx final : public TStandardRasterFx {
Shinya Kitaoka 120a6e
  FX_PLUGIN_DECLARATION(LocalTransparencyFx)
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  TRasterFxPort m_src, m_ref;
Shinya Kitaoka 120a6e
  TDoubleParamP m_value;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  LocalTransparencyFx() : m_value(100) {
Shinya Kitaoka 120a6e
    addInputPort("Source", m_src);
Shinya Kitaoka 120a6e
    addInputPort("Reference", m_ref);
Shinya Kitaoka 120a6e
    bindParam(this, "value", m_value);
Shinya Kitaoka 120a6e
    m_value->setValueRange(0, 100);
shun-iwasawa 481b59
    enableComputeInFloat(true);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  virtual ~LocalTransparencyFx() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 38fd86
  bool doGetBBox(double frame, TRectD &bBox,
Shinya Kitaoka 38fd86
                 const TRenderSettings &info) override {
Shinya Kitaoka 120a6e
    if (m_src.isConnected())
Shinya Kitaoka 120a6e
      return m_src->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 120a6e
Shinya Kitaoka 38fd86
  void doCompute(TTile &tile, double frame,
Shinya Kitaoka 38fd86
                 const TRenderSettings &ri) override {
Shinya Kitaoka 120a6e
    if (!checkBeforeCompute(tile, frame, ri)) return;
Shinya Kitaoka 120a6e
    TTile srcTile;
Shinya Kitaoka 120a6e
    m_src->allocateAndCompute(srcTile, tile.m_pos, tile.getRaster()->getSize(),
Shinya Kitaoka 120a6e
                              tile.getRaster(), frame, ri);
Shinya Kitaoka 120a6e
    // TTile refTile = tile;
Shinya Kitaoka 120a6e
    m_ref->compute(tile, frame, ri);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // TRaster32P ref32 (refTile.getRaster());
Shinya Kitaoka 120a6e
    TRaster32P out32(tile.getRaster());
Shinya Kitaoka 120a6e
    TRaster32P src32(srcTile.getRaster());
shun-iwasawa 481b59
    if (out32 && src32) {
Shinya Kitaoka 120a6e
      doLocalTransparency<tpixelrgbm32, tpixelgr8,="" uchar="">(</tpixelrgbm32,>
Shinya Kitaoka 120a6e
          out32, src32, out32, m_value->getValue(frame) / 100.);
shun-iwasawa 481b59
      return;
Shinya Kitaoka 120a6e
    }
shun-iwasawa 481b59
    // TRaster64P ref64(refTile.getRaster());
shun-iwasawa 481b59
    TRaster64P out64(tile.getRaster());
shun-iwasawa 481b59
    TRaster64P src64(srcTile.getRaster());
shun-iwasawa 481b59
    if (out64 && src64) {
shun-iwasawa 481b59
      doLocalTransparency<tpixelrgbm64, tpixelgr16,="" ushort="">(</tpixelrgbm64,>
shun-iwasawa 481b59
          out64, src64, out64, m_value->getValue(frame) / 100.);
shun-iwasawa 481b59
      return;
shun-iwasawa 481b59
    }
shun-iwasawa 481b59
    TRasterFP outF(tile.getRaster());
shun-iwasawa 481b59
    TRasterFP srcF(srcTile.getRaster());
shun-iwasawa 481b59
    if (outF && srcF) {
shun-iwasawa 481b59
      doLocalTransparency<tpixelf, float="" tpixelgrf,="">(</tpixelf,>
shun-iwasawa 481b59
          outF, srcF, outF, m_value->getValue(frame) / 100.);
shun-iwasawa 481b59
      return;
shun-iwasawa 481b59
    }
shun-iwasawa 481b59
shun-iwasawa 481b59
    throw TException("LocalTransparencyFx: unsupported raster type");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool checkBeforeCompute(TTile &tile, double frame,
Shinya Kitaoka 120a6e
                          const TRenderSettings &info) {
Shinya Kitaoka 120a6e
    Status status = getFxStatus(m_src, m_ref);
Shinya Kitaoka 120a6e
    if ((status & NoPortsConnected) == NoPortsConnected) return false;
Shinya Kitaoka 120a6e
    if ((status & OutOfTime) == OutOfTime) return false;
Shinya Kitaoka 120a6e
    if ((status & Port0NotConnected) == Port0NotConnected) return false;
Shinya Kitaoka 120a6e
    if ((status & Port1NotConnected) == Port1NotConnected) {
Shinya Kitaoka 120a6e
      m_src->compute(tile, frame, info);
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    assert(status == StatusGood);
Shinya Kitaoka 120a6e
    return true;
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 120a6e
Shinya Kitaoka 120a6e
  int getMemoryRequirement(const TRectD &rect, double frame,
Shinya Kitaoka 473e70
                           const TRenderSettings &info) override {
Shinya Kitaoka 120a6e
    return TRasterFx::memorySize(rect, info.m_bpp);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(LocalTransparencyFx, "localTransparencyFx")