|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "stdfx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tfxparam.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tpixelgr.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class ColorEmbossFx final : public TStandardRasterFx {
|
|
Shinya Kitaoka |
120a6e |
FX_PLUGIN_DECLARATION(ColorEmbossFx)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRasterFxPort m_input;
|
|
Shinya Kitaoka |
120a6e |
TRasterFxPort m_controller;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_intensity;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_elevation;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_direction;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_radius;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
ColorEmbossFx()
|
|
Shinya Kitaoka |
120a6e |
: m_intensity(0.5), m_elevation(45.0), m_direction(90.0), m_radius(1.0) {
|
|
Shinya Kitaoka |
120a6e |
m_radius->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "intensity", m_intensity);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "elevation", m_elevation);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "direction", m_direction);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "radius", m_radius);
|
|
Shinya Kitaoka |
120a6e |
addInputPort("Source", m_input);
|
|
Shinya Kitaoka |
120a6e |
addInputPort("Controller", m_controller);
|
|
Shinya Kitaoka |
120a6e |
m_intensity->setValueRange(0.0, 1.0, 0.1);
|
|
Shinya Kitaoka |
120a6e |
m_elevation->setValueRange(0.0, 360.0);
|
|
Shinya Kitaoka |
120a6e |
m_direction->setValueRange(0.0, 360.0);
|
|
Shinya Kitaoka |
120a6e |
m_radius->setValueRange(0.0, 10.0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
~ColorEmbossFx(){};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
d1f6c4 |
bool doGetBBox(double frame, TRectD &bBox,
|
|
Shinya Kitaoka |
d1f6c4 |
const TRenderSettings &info) override {
|
|
Shinya Kitaoka |
120a6e |
if (m_input.isConnected()) {
|
|
Shinya Kitaoka |
120a6e |
bool ret = m_input->doGetBBox(frame, bBox, info);
|
|
Shinya Kitaoka |
120a6e |
return ret;
|
|
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 |
120a6e |
void transform(double frame, int port, const TRectD &rectOnOutput,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &infoOnOutput, TRectD &rectOnInput,
|
|
Michał Janiszewski |
d37dbb |
TRenderSettings &infoOnInput) override;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int getMemoryRequirement(const TRectD &rect, double frame,
|
|
Michał Janiszewski |
d37dbb |
const TRenderSettings &info) override;
|
|
Michał Janiszewski |
d37dbb |
void doCompute(TTile &tile, double frame, const TRenderSettings &ri) override;
|
|
Michał Janiszewski |
d37dbb |
bool canHandle(const TRenderSettings &info, double frame) override {
|
|
Shinya Kitaoka |
120a6e |
return (isAlmostIsotropic(info.m_affine));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
template <typename channel_type="" pixel,="" pixelgray,="" typename=""></typename>
|
|
Shinya Kitaoka |
120a6e |
void doColorEmboss(TRasterPT<pixel> ras, TRasterPT<pixel> srcraster,</pixel></pixel>
|
|
Shinya Kitaoka |
120a6e |
TRasterPT<pixel> ctrraster, double azimuth, double elevation,</pixel>
|
|
Shinya Kitaoka |
120a6e |
double intensity, double radius) {
|
|
Shinya Kitaoka |
120a6e |
double Lx = cos(azimuth) * cos(elevation) * PIXEL::maxChannelValue;
|
|
Shinya Kitaoka |
120a6e |
double Ly = sin(azimuth) * cos(elevation) * PIXEL::maxChannelValue;
|
|
Shinya Kitaoka |
120a6e |
double Lz = sin(elevation) * PIXEL::maxChannelValue;
|
|
Shinya Kitaoka |
120a6e |
double Nz = (6 * PIXEL::maxChannelValue) * (1 - intensity);
|
|
Shinya Kitaoka |
120a6e |
double Nz2 = Nz * Nz;
|
|
Shinya Kitaoka |
120a6e |
double background = Lz;
|
|
Shinya Kitaoka |
120a6e |
double NdotL;
|
|
Shinya Kitaoka |
120a6e |
int j, m, n;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int border = radius + 1;
|
|
Shinya Kitaoka |
120a6e |
double borderFracMult = radius - (int)radius;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int wrap = srcraster->getWrap();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double nsbuffer, ewbuffer;
|
|
Shinya Kitaoka |
120a6e |
double nsFracbuffer, ewFracbuffer;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ras->lock();
|
|
Shinya Kitaoka |
120a6e |
srcraster->lock();
|
|
Shinya Kitaoka |
120a6e |
ctrraster->lock();
|
|
Shinya Kitaoka |
120a6e |
for (j = border; j < srcraster->getLy() - border; j++) {
|
|
Shinya Kitaoka |
120a6e |
PIXEL *pixout = ras->pixels(j - border);
|
|
Shinya Kitaoka |
120a6e |
PIXEL *pix = srcraster->pixels(j) + border;
|
|
Shinya Kitaoka |
120a6e |
PIXEL *ctrpix = ctrraster->pixels(j) + border;
|
|
Shinya Kitaoka |
120a6e |
PIXEL *endPixout = pixout + ras->getLx();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (pixout < endPixout) {
|
|
Shinya Kitaoka |
120a6e |
double val, emboss;
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
nsbuffer = 0;
|
|
Shinya Kitaoka |
120a6e |
ewbuffer = 0;
|
|
Shinya Kitaoka |
120a6e |
for (m = 1; m < border; m++)
|
|
Shinya Kitaoka |
120a6e |
for (n = -m; n <= m; n++) {
|
|
Shinya Kitaoka |
120a6e |
nsbuffer += PIXELGRAY::from(*(ctrpix + m * wrap + n)).value;
|
|
Shinya Kitaoka |
120a6e |
nsbuffer -= PIXELGRAY::from(*(ctrpix - m * wrap + n)).value;
|
|
Shinya Kitaoka |
120a6e |
ewbuffer += PIXELGRAY::from(*(ctrpix + n * wrap + m)).value;
|
|
Shinya Kitaoka |
120a6e |
ewbuffer -= PIXELGRAY::from(*(ctrpix + n * wrap - m)).value;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
nsFracbuffer = 0;
|
|
Shinya Kitaoka |
120a6e |
ewFracbuffer = 0;
|
|
Shinya Kitaoka |
120a6e |
for (n = -m; n <= m; n++) {
|
|
Shinya Kitaoka |
120a6e |
nsFracbuffer += PIXELGRAY::from(*(ctrpix + m * wrap + n)).value;
|
|
Shinya Kitaoka |
120a6e |
nsFracbuffer -= PIXELGRAY::from(*(ctrpix - m * wrap + n)).value;
|
|
Shinya Kitaoka |
120a6e |
ewFracbuffer += PIXELGRAY::from(*(ctrpix + n * wrap + m)).value;
|
|
Shinya Kitaoka |
120a6e |
ewFracbuffer -= PIXELGRAY::from(*(ctrpix + n * wrap - m)).value;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
nsbuffer += nsFracbuffer * borderFracMult;
|
|
Shinya Kitaoka |
120a6e |
ewbuffer += ewFracbuffer * borderFracMult;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
double Nx = ewbuffer;
|
|
Shinya Kitaoka |
120a6e |
double Ny = nsbuffer;
|
|
Shinya Kitaoka |
120a6e |
Nx = Nx / radius;
|
|
Shinya Kitaoka |
120a6e |
Ny = Ny / radius;
|
|
Shinya Kitaoka |
120a6e |
// val= 127+sinsin*nordsud(pix, wrap)+coscos*eastwest(pix, wrap);
|
|
Shinya Kitaoka |
120a6e |
if (Nx == 0 && Ny == 0)
|
|
Shinya Kitaoka |
120a6e |
emboss = background;
|
|
Shinya Kitaoka |
120a6e |
else if ((NdotL = Nx * Lx + Ny * Ly + Nz * Lz) < 0)
|
|
Shinya Kitaoka |
120a6e |
emboss = 0;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
emboss = NdotL / sqrt(Nx * Nx + Ny * Ny + Nz2);
|
|
Shinya Kitaoka |
120a6e |
val = emboss * pix->r / PIXEL::maxChannelValue;
|
|
Shinya Kitaoka |
120a6e |
(pixout)->r = (val < PIXEL::maxChannelValue)
|
|
Shinya Kitaoka |
120a6e |
? (val > 0 ? (CHANNEL_TYPE)val : 0)
|
|
Shinya Kitaoka |
120a6e |
: PIXEL::maxChannelValue;
|
|
Shinya Kitaoka |
120a6e |
val = emboss * pix->g / PIXEL::maxChannelValue;
|
|
Shinya Kitaoka |
120a6e |
(pixout)->g = (val < PIXEL::maxChannelValue)
|
|
Shinya Kitaoka |
120a6e |
? (val > 0 ? (CHANNEL_TYPE)val : 0)
|
|
Shinya Kitaoka |
120a6e |
: PIXEL::maxChannelValue;
|
|
Shinya Kitaoka |
120a6e |
val = emboss * pix->b / PIXEL::maxChannelValue;
|
|
Shinya Kitaoka |
120a6e |
(pixout)->b = (val < PIXEL::maxChannelValue)
|
|
Shinya Kitaoka |
120a6e |
? (val > 0 ? (CHANNEL_TYPE)val : 0)
|
|
Shinya Kitaoka |
120a6e |
: PIXEL::maxChannelValue;
|
|
Shinya Kitaoka |
120a6e |
(pixout)->m = (pix)->m;
|
|
Rozhuk Ivan |
823a31 |
pix++;
|
|
Rozhuk Ivan |
823a31 |
pixout++;
|
|
Rozhuk Ivan |
823a31 |
ctrpix++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
ras->unlock();
|
|
Shinya Kitaoka |
120a6e |
srcraster->unlock();
|
|
Shinya Kitaoka |
120a6e |
ctrraster->unlock();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ColorEmbossFx::transform(double frame, int port,
|
|
Shinya Kitaoka |
120a6e |
const TRectD &rectOnOutput,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &infoOnOutput,
|
|
Shinya Kitaoka |
120a6e |
TRectD &rectOnInput,
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings &infoOnInput) {
|
|
Shinya Kitaoka |
120a6e |
infoOnInput = infoOnOutput;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double scale = sqrt(fabs(infoOnOutput.m_affine.det()));
|
|
Shinya Kitaoka |
120a6e |
double radius = m_radius->getValue(frame) * scale;
|
|
Shinya Kitaoka |
120a6e |
int border = radius + 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
rectOnInput = rectOnOutput.enlarge(border);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ColorEmbossFx::doCompute(TTile &tile, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &ri) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_input.isConnected()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double scale = sqrt(fabs(ri.m_affine.det()));
|
|
Shinya Kitaoka |
120a6e |
double radius = m_radius->getValue(frame) * scale;
|
|
Shinya Kitaoka |
120a6e |
double direction = m_direction->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
double elevation = (m_elevation->getValue(frame)) * M_PI_180;
|
|
Shinya Kitaoka |
120a6e |
double intensity = m_intensity->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
double azimuth = direction * M_PI_180;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int border = radius + 1;
|
|
Shinya Kitaoka |
120a6e |
TRasterP srcRas =
|
|
Shinya Kitaoka |
120a6e |
tile.getRaster()->create(tile.getRaster()->getLx() + border * 2,
|
|
Shinya Kitaoka |
120a6e |
tile.getRaster()->getLy() + border * 2);
|
|
Shinya Kitaoka |
120a6e |
// TRaster32P srcRas(tile.getRaster()->getLx() + border*2,
|
|
Shinya Kitaoka |
120a6e |
// tile.getRaster()->getLy() + border*2);
|
|
Shinya Kitaoka |
120a6e |
TTile srcTile(srcRas, tile.m_pos - TPointD(border, border));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TTile ctrTile;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_input->compute(srcTile, frame, ri);
|
|
Shinya Kitaoka |
120a6e |
if (!m_controller.isConnected()) {
|
|
Shinya Kitaoka |
120a6e |
ctrTile.m_pos = srcTile.m_pos;
|
|
Shinya Kitaoka |
120a6e |
ctrTile.setRaster(srcTile.getRaster());
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
ctrTile.m_pos = tile.m_pos - TPointD(border, border);
|
|
Shinya Kitaoka |
120a6e |
ctrTile.setRaster(
|
|
Shinya Kitaoka |
120a6e |
tile.getRaster()->create(tile.getRaster()->getLx() + border * 2,
|
|
Shinya Kitaoka |
120a6e |
tile.getRaster()->getLy() + border * 2));
|
|
Shinya Kitaoka |
120a6e |
m_controller->allocateAndCompute(ctrTile, ctrTile.m_pos,
|
|
Shinya Kitaoka |
120a6e |
ctrTile.getRaster()->getSize(),
|
|
Shinya Kitaoka |
120a6e |
ctrTile.getRaster(), frame, ri);
|
|
Shinya Kitaoka |
120a6e |
// m_controller->compute(ctrTile,frame,ri);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
TRaster32P raster32 = tile.getRaster();
|
|
Shinya Kitaoka |
120a6e |
TRaster32P srcraster32 = srcTile.getRaster();
|
|
Shinya Kitaoka |
120a6e |
TRaster32P ctrraster32 = ctrTile.getRaster();
|
|
Shinya Kitaoka |
120a6e |
if (raster32)
|
|
Shinya Kitaoka |
120a6e |
doColorEmboss<tpixel32, tpixelgr8,="" uchar="">(raster32, srcraster32,</tpixel32,>
|
|
Shinya Kitaoka |
120a6e |
ctrraster32, azimuth, elevation,
|
|
Shinya Kitaoka |
120a6e |
intensity, radius);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
TRaster64P raster64 = tile.getRaster();
|
|
Shinya Kitaoka |
120a6e |
TRaster64P srcraster64 = srcTile.getRaster();
|
|
Shinya Kitaoka |
120a6e |
TRaster64P ctrraster64 = ctrTile.getRaster();
|
|
Shinya Kitaoka |
120a6e |
if (raster64)
|
|
Shinya Kitaoka |
120a6e |
doColorEmboss<tpixel64, tpixelgr16,="" ushort="">(raster64, srcraster64,</tpixel64,>
|
|
Shinya Kitaoka |
120a6e |
ctrraster64, azimuth,
|
|
Shinya Kitaoka |
120a6e |
elevation, intensity, radius);
|
|
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 |
//------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int ColorEmbossFx::getMemoryRequirement(const TRectD &rect, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
double scale = sqrt(fabs(info.m_affine.det()));
|
|
Shinya Kitaoka |
120a6e |
double radius = m_radius->getValue(frame) * scale;
|
|
Shinya Kitaoka |
120a6e |
int border = radius + 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return TRasterFx::memorySize(rect.enlarge(border), info.m_bpp);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
FX_PLUGIN_IDENTIFIER(ColorEmbossFx, "colorEmbossFx");
|