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