|
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")
|