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