Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "stdfx.h"
Toshihiro Shimizu 890ddd
#include "tfxparam.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tparamset.h"
Toshihiro Shimizu 890ddd
#include "tparamuiconcept.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class SpinBlurFx : public TStandardRasterFx
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	FX_PLUGIN_DECLARATION(SpinBlurFx)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterFxPort m_input;
Toshihiro Shimizu 890ddd
	TPointParamP m_point;
Toshihiro Shimizu 890ddd
	TDoubleParamP m_radius;
Toshihiro Shimizu 890ddd
	TDoubleParamP m_blur;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	SpinBlurFx()
Toshihiro Shimizu 890ddd
		: m_point(TPointD(0.0, 0.0)), m_radius(0.0), m_blur(2.0)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_point->getX()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
		m_point->getY()->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
		m_radius->setMeasureName("fxLength");
Toshihiro Shimizu 890ddd
		bindParam(this, "point", m_point);
Toshihiro Shimizu 890ddd
		bindParam(this, "radius", m_radius);
Toshihiro Shimizu 890ddd
		bindParam(this, "blur", m_blur);
Toshihiro Shimizu 890ddd
		addInputPort("Source", m_input);
Toshihiro Shimizu 890ddd
		m_radius->setValueRange(0, (std::numeric_limits<double>::max)());</double>
Toshihiro Shimizu 890ddd
		m_blur->setValueRange(0, (std::numeric_limits<double>::max)());</double>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~SpinBlurFx(){};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getMaxBraid(const TRectD &bBox, double frame, const TAffine &aff = TAffine())
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		double scale = sqrt(fabs(aff.det()));
Toshihiro Shimizu 890ddd
		TPointD point = aff * m_point->getValue(frame);
Toshihiro Shimizu 890ddd
		double radius = m_radius->getValue(frame) * scale;
Toshihiro Shimizu 890ddd
		double blur = 0.001 * m_blur->getValue(frame) / scale;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double intensity = blur * (TConsts::pi / 180);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TPointD p1 = bBox.getP00() - point;
Toshihiro Shimizu 890ddd
		TPointD p2 = bBox.getP01() - point;
Toshihiro Shimizu 890ddd
		TPointD p3 = bBox.getP10() - point;
Toshihiro Shimizu 890ddd
		TPointD p4 = bBox.getP11() - point;
Toshihiro Shimizu 890ddd
		double d1 = p1.x * p1.x + p1.y * p1.y;
Toshihiro Shimizu 890ddd
		double d2 = p2.x * p2.x + p2.y * p2.y;
Toshihiro Shimizu 890ddd
		double d3 = p3.x * p3.x + p3.y * p3.y;
Toshihiro Shimizu 890ddd
		double d4 = p4.x * p4.x + p4.y * p4.y;
Toshihiro Shimizu 890ddd
		double maxD = tmax(tmax(tmax(d3, d4), d2), d1);
Toshihiro Shimizu 890ddd
		double dist = sqrt(maxD);
Toshihiro Shimizu 890ddd
		double blurangle;
Toshihiro Shimizu 890ddd
		if (dist > radius)
Toshihiro Shimizu 890ddd
			blurangle = intensity * ((dist - radius));
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			blurangle = 0;
Toshihiro Shimizu 890ddd
		if (blurangle > TConsts::pi)
Toshihiro Shimizu 890ddd
			blurangle = TConsts::pi;
Toshihiro Shimizu 890ddd
		return tround(4 * blurangle * dist);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void enlarge(
Toshihiro Shimizu 890ddd
		const TRectD &bbox, TRectD &requestedGeom,
Toshihiro Shimizu 890ddd
		const TRenderSettings &ri, double frame);
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
			m_input->doGetBBox(frame, bBox, info);
Toshihiro Shimizu 890ddd
			bBox = bBox.enlarge(getMaxBraid(bBox, frame));
Toshihiro Shimizu 890ddd
			return true;
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
	void doCompute(TTile &tile, double frame, const TRenderSettings &);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getMemoryRequirement(const TRectD &rect, double frame, const TRenderSettings &info);
Toshihiro Shimizu 890ddd
	bool canHandle(const TRenderSettings &info, double frame)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (info.m_isSwatch)
Toshihiro Shimizu 890ddd
			return true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		return m_blur->getValue(frame) == 0 ? true : isAlmostIsotropic(info.m_affine);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void getParamUIs(TParamUIConcept *&concepts, int &length)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		concepts = new TParamUIConcept[length = 2];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		concepts[0].m_type = TParamUIConcept::POINT;
Toshihiro Shimizu 890ddd
		concepts[0].m_label = "Center";
Toshihiro Shimizu 890ddd
		concepts[0].m_params.push_back(m_point);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		concepts[1].m_type = TParamUIConcept::RADIUS;
Toshihiro Shimizu 890ddd
		concepts[1].m_label = "Radius";
Toshihiro Shimizu 890ddd
		concepts[1].m_params.push_back(m_radius);
Toshihiro Shimizu 890ddd
		concepts[1].m_params.push_back(m_point);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
template <typename channel_type,="" int="" max_channel_value="" pixel,="" typename=""></typename>
Toshihiro Shimizu 890ddd
void doSpinBlur(const TRasterPT<pixel> rout, const TRasterPT<pixel> rin, double blur,</pixel></pixel>
Toshihiro Shimizu 890ddd
				double radius, TPointD point)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int maxRange = 0;
Toshihiro Shimizu 890ddd
	int dx = (int)point.x;
Toshihiro Shimizu 890ddd
	int dy = (int)point.y;
Toshihiro Shimizu 890ddd
	int i, j;
Toshihiro Shimizu 890ddd
	int lx = rout->getLx();
Toshihiro Shimizu 890ddd
	int ly = rout->getLy();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int XMAX = rin->getLx() / 2 - dx;
Toshihiro Shimizu 890ddd
	int YMAX = rin->getLy() / 2 - dy;
Toshihiro Shimizu 890ddd
	PIXEL *src_buf, *dst_buf;
Toshihiro Shimizu 890ddd
	double CROP_VAL = (double)MAX_CHANNEL_VALUE;
Toshihiro Shimizu 890ddd
	CHANNEL_TYPE U_CROP_VAL = MAX_CHANNEL_VALUE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double intensity = blur * (TConsts::pi / 180);
Toshihiro Shimizu 890ddd
	int cx = lx / 2 + dx;
Toshihiro Shimizu 890ddd
	int cy = ly / 2 + dy;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int XMIN = -cx;
Toshihiro Shimizu 890ddd
	int YMIN = -cy;
Toshihiro Shimizu 890ddd
	rin->lock();
Toshihiro Shimizu 890ddd
	rout->lock();
Toshihiro Shimizu 890ddd
	for (i = 0; i < ly; i++) {
Toshihiro Shimizu 890ddd
		src_buf = rin->pixels(i);
Toshihiro Shimizu 890ddd
		dst_buf = rout->pixels(i);
Toshihiro Shimizu 890ddd
		for (j = 0; j < lx; j++, src_buf++, dst_buf++) {
Toshihiro Shimizu 890ddd
			double valr = 0, valg = 0, valb = 0, valm = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			double angle = 0, blurangle, dist, ddist = 0, rangeinv = 0, tmpangle = 0;
Toshihiro Shimizu 890ddd
			int ii, vx, vy;
Toshihiro Shimizu 890ddd
			int shiftx, shifty, range = 0;
Toshihiro Shimizu 890ddd
			vx = (int)(j - cx);
Toshihiro Shimizu 890ddd
			vy = (int)(i - cy);
Toshihiro Shimizu 890ddd
			dist = sqrt((double)(vx * vx + vy * vy));
Toshihiro Shimizu 890ddd
			if (dist > radius)
Toshihiro Shimizu 890ddd
				blurangle = intensity * ((dist - radius));
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				blurangle = 0;
Toshihiro Shimizu 890ddd
			if (blurangle > TConsts::pi)
Toshihiro Shimizu 890ddd
				blurangle = TConsts::pi;
Toshihiro Shimizu 890ddd
			range = (int)(4 * blurangle * dist);
Toshihiro Shimizu 890ddd
			if (range >= 1) {
Toshihiro Shimizu 890ddd
				angle = atan2((double)vy, (double)vx) - blurangle;
Toshihiro Shimizu 890ddd
				ddist = 0.5 / dist;
Toshihiro Shimizu 890ddd
				for (ii = 0; ii <= range; ii++) {
Toshihiro Shimizu 890ddd
					tmpangle = angle + ii * (ddist);
Toshihiro Shimizu 890ddd
					shiftx = (int)(dist * cos(tmpangle));
Toshihiro Shimizu 890ddd
					shifty = (int)(dist * sin(tmpangle));
Toshihiro Shimizu 890ddd
					if ((shiftx) < XMIN)
Toshihiro Shimizu 890ddd
						continue; //shiftx=XMIN;
Toshihiro Shimizu 890ddd
					if ((shiftx) >= XMAX)
Toshihiro Shimizu 890ddd
						continue; //=XMAX-1;
Toshihiro Shimizu 890ddd
					if ((shifty) < YMIN)
Toshihiro Shimizu 890ddd
						continue; //=YMIN;
Toshihiro Shimizu 890ddd
					if ((shifty) >= YMAX)
Toshihiro Shimizu 890ddd
						continue; //=YMAX-1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					valr += rin->pixels(0 + shifty + cy)[shiftx + cx].r;
Toshihiro Shimizu 890ddd
					valg += rin->pixels(0 + shifty + cy)[shiftx + cx].g;
Toshihiro Shimizu 890ddd
					valb += rin->pixels(0 + shifty + cy)[shiftx + cx].b;
Toshihiro Shimizu 890ddd
					valm += rin->pixels(0 + shifty + cy)[shiftx + cx].m;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				rangeinv = 1.0 / (range + 1);
Toshihiro Shimizu 890ddd
				valr *= rangeinv;
Toshihiro Shimizu 890ddd
				valg *= rangeinv;
Toshihiro Shimizu 890ddd
				valb *= rangeinv;
Toshihiro Shimizu 890ddd
				valm *= rangeinv;
Toshihiro Shimizu 890ddd
				dst_buf->r = (valr > CROP_VAL) ? U_CROP_VAL : ((valr < 0) ? 0 : (CHANNEL_TYPE)valr);
Toshihiro Shimizu 890ddd
				dst_buf->g = (valg > CROP_VAL) ? U_CROP_VAL : ((valg < 0) ? 0 : (CHANNEL_TYPE)valg);
Toshihiro Shimizu 890ddd
				dst_buf->b = (valb > CROP_VAL) ? U_CROP_VAL : ((valb < 0) ? 0 : (CHANNEL_TYPE)valb);
Toshihiro Shimizu 890ddd
				dst_buf->m = (valm > CROP_VAL) ? U_CROP_VAL : ((valm < 0) ? 0 : (CHANNEL_TYPE)valm);
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				*(dst_buf) = *(src_buf);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	rin->unlock();
Toshihiro Shimizu 890ddd
	rout->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!Calculates the geometry we need for this node computation, given
Toshihiro Shimizu 890ddd
//!the known input data (bbox) and the requested output (requestedGeom).
Toshihiro Shimizu 890ddd
void SpinBlurFx::enlarge(
Toshihiro Shimizu 890ddd
	const TRectD &bbox, TRectD &requestedGeom,
Toshihiro Shimizu 890ddd
	const TRenderSettings &ri, double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRectD enlargedBbox(bbox);
Toshihiro Shimizu 890ddd
	TRectD enlargedGeom(requestedGeom);
Toshihiro Shimizu 890ddd
	TPointD originalP00(requestedGeom.getP00());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double maxRange = getMaxBraid(enlargedBbox, frame, ri.m_affine);
Toshihiro Shimizu 890ddd
	enlargedBbox = enlargedBbox.enlarge(maxRange);
Toshihiro Shimizu 890ddd
	enlargedGeom = enlargedGeom.enlarge(maxRange);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//We are to find out the geometry that is useful for the fx computation.
Toshihiro Shimizu 890ddd
	//There are some rules to follow:
Toshihiro Shimizu 890ddd
	//  a) First, the interesting output we can generate is bounded by both
Toshihiro Shimizu 890ddd
	//     the requestedRect and the blurred bbox (i.e. enlarged by the blur radius).
Toshihiro Shimizu 890ddd
	//  b) Pixels contributing to any output are necessarily part of bbox - and only
Toshihiro Shimizu 890ddd
	//     those which are blurrable into the requestedRect are useful to us
Toshihiro Shimizu 890ddd
	//     (i.e. pixels contained in its enlargement by the blur radius).
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	requestedGeom = (enlargedGeom * bbox) + (enlargedBbox * requestedGeom);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Finally, make sure that the result is coherent with the original P00
Toshihiro Shimizu 890ddd
	requestedGeom -= originalP00;
Toshihiro Shimizu 890ddd
	requestedGeom.x0 = tfloor(requestedGeom.x0);
Toshihiro Shimizu 890ddd
	requestedGeom.y0 = tfloor(requestedGeom.y0);
Toshihiro Shimizu 890ddd
	requestedGeom.x1 = tceil(requestedGeom.x1);
Toshihiro Shimizu 890ddd
	requestedGeom.y1 = tceil(requestedGeom.y1);
Toshihiro Shimizu 890ddd
	requestedGeom += originalP00;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void SpinBlurFx::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
	TRectD rectOut(rectOnOutput);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (canHandle(infoOnOutput, frame))
Toshihiro Shimizu 890ddd
		infoOnInput = infoOnOutput;
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		infoOnInput = infoOnOutput;
Toshihiro Shimizu 890ddd
		infoOnInput.m_affine = TAffine(); // because the affine does not commute
Toshihiro Shimizu 890ddd
		rectOut = infoOnOutput.m_affine.inv() * rectOut;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRectD bbox;
Toshihiro Shimizu 890ddd
	m_input->getBBox(frame, bbox, infoOnInput);
Toshihiro Shimizu 890ddd
	if (bbox == TConsts::infiniteRectD)
Toshihiro Shimizu 890ddd
		bbox = rectOut;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	rectOnInput = rectOut;
Toshihiro Shimizu 890ddd
	enlarge(bbox, rectOnInput, infoOnInput, frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void SpinBlurFx::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
	TPointD point = ri.m_affine * m_point->getValue(frame);
Toshihiro Shimizu 890ddd
	double radius = m_radius->getValue(frame) * scale;
Toshihiro Shimizu 890ddd
	double blur = 0.001 * m_blur->getValue(frame) / scale;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRectD tileRect = convert(tile.getRaster()->getBounds()) + tile.m_pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRectD bBox;
Toshihiro Shimizu 890ddd
	m_input->getBBox(frame, bBox, ri);
Toshihiro Shimizu 890ddd
	if (bBox.isEmpty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (bBox == TConsts::infiniteRectD)
Toshihiro Shimizu 890ddd
		bBox = tileRect;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	enlarge(bBox, tileRect, ri, frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD tileRectCenter = (tileRect.getP00() + tileRect.getP11()) * 0.5;
Toshihiro Shimizu 890ddd
	point -= tileRectCenter;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int rasInLx = tileRect.getLx();
Toshihiro Shimizu 890ddd
	int rasInLy = tileRect.getLy();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRaster32P raster32 = tile.getRaster();
Toshihiro Shimizu 890ddd
	TRaster64P raster64 = tile.getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPoint offset = convert(tile.m_pos - tileRect.getP00());
Toshihiro Shimizu 890ddd
	TTile tileIn;
Toshihiro Shimizu 890ddd
	if (raster32) {
Toshihiro Shimizu 890ddd
		m_input->allocateAndCompute(tileIn, tileRect.getP00(),
Toshihiro Shimizu 890ddd
									TDimension(rasInLx, rasInLy),
Toshihiro Shimizu 890ddd
									raster32, frame, ri);
Toshihiro Shimizu 890ddd
		TRaster32P rin = tileIn.getRaster();
Toshihiro Shimizu 890ddd
		TRaster32P app = raster32->create(rasInLx, rasInLy);
Toshihiro Shimizu 890ddd
		doSpinBlur<tpixel32, 255="" uchar,="">(app, rin, blur, radius, point);</tpixel32,>
Toshihiro Shimizu 890ddd
		raster32->copy(app, -offset);
Toshihiro Shimizu 890ddd
	} else if (raster64) {
Toshihiro Shimizu 890ddd
		TRaster64P raster64 = tile.getRaster();
Toshihiro Shimizu 890ddd
		m_input->allocateAndCompute(tileIn, tileRect.getP00(),
Toshihiro Shimizu 890ddd
									TDimension(rasInLx, rasInLy),
Toshihiro Shimizu 890ddd
									raster64, frame, ri);
Toshihiro Shimizu 890ddd
		TRaster64P rin = tileIn.getRaster();
Toshihiro Shimizu 890ddd
		TRaster64P app = raster64->create(rasInLx, rasInLy);
Toshihiro Shimizu 890ddd
		doSpinBlur<tpixel64, 65535="" ushort,="">(app, rin, blur, radius, point);</tpixel64,>
Toshihiro Shimizu 890ddd
		raster64->copy(app, -offset);
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		throw TException("Brightness&Contrast: unsupported Pixel Type");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* TRectD rectIn = convert(tile.getRaster()->getBounds()) + tile.m_pos;
Toshihiro Shimizu 890ddd
  TPointD rectInCenter=(rectIn.getP00()+rectIn.getP11())*0.5;
Toshihiro Shimizu 890ddd
  //rectIn = rectIn.enlarge(blur);
Toshihiro Shimizu 890ddd
  int rasInLx = tround(rectIn.getLx())+1;
Toshihiro Shimizu 890ddd
  int rasInLy = tround(rectIn.getLy())+1;  
Toshihiro Shimizu 890ddd
  
Toshihiro Shimizu 890ddd
  point-=rectInCenter;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
 
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  TRaster32P raster32 = tile.getRaster();
Toshihiro Shimizu 890ddd
  
Toshihiro Shimizu 890ddd
  
Toshihiro Shimizu 890ddd
  TTile tileIn;
Toshihiro Shimizu 890ddd
  
Toshihiro Shimizu 890ddd
  
Toshihiro Shimizu 890ddd
  if (raster32)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    m_input->allocateAndCompute(tileIn, rectIn.getP00(), 
Toshihiro Shimizu 890ddd
                              TDimension(rasInLx, rasInLy), 
Toshihiro Shimizu 890ddd
                              raster32, frame, ri);
Toshihiro Shimizu 890ddd
    TRaster32P rin=tileIn.getRaster();
Toshihiro Shimizu 890ddd
    doSpinBlur<tpixel32, 255="" uchar,="">(raster32, rin, blur, radius, point);</tpixel32,>
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
  else
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
    TRaster64P raster64 = tile.getRaster();
Toshihiro Shimizu 890ddd
    
Toshihiro Shimizu 890ddd
    m_input->allocateAndCompute(tileIn, rectIn.getP00(), 
Toshihiro Shimizu 890ddd
                              TDimension(rasInLx, rasInLy), 
Toshihiro Shimizu 890ddd
                              raster64, frame, ri);
Toshihiro Shimizu 890ddd
    TRaster64P rin=tileIn.getRaster();
Toshihiro Shimizu 890ddd
    if (raster64)
Toshihiro Shimizu 890ddd
      doSpinBlur<tpixel64, 65535="" ushort,="">(raster64, rin, blur, radius, point);</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
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int SpinBlurFx::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
	TPointD point = info.m_affine * m_point->getValue(frame);
Toshihiro Shimizu 890ddd
	double blur = 0.001 * m_blur->getValue(frame) / scale;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRectD bBox;
Toshihiro Shimizu 890ddd
	m_input->getBBox(frame, bBox, info);
Toshihiro Shimizu 890ddd
	if (bBox.isEmpty())
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (bBox == TConsts::infiniteRectD)
Toshihiro Shimizu 890ddd
		bBox = rect;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRectD tileRect(rect);
Toshihiro Shimizu 890ddd
	enlarge(bBox, tileRect, info, frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return TRasterFx::memorySize(tileRect.enlarge(blur), info.m_bpp);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(SpinBlurFx, "rotationalBlurFx")