|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "stdfx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tfxparam.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trop.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tdoubleparam.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trasterfx.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* (Daniele)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
NOTE: Current LocalBlurFx is effectively flawed. Following implementation relies on the idea that
|
|
Toshihiro Shimizu |
890ddd |
the blurring filter is separable and therefore appliable on rows and columns, in sequence.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
It actually is not. It can be easily verified applying the fx on a chessboard with a strong
|
|
Toshihiro Shimizu |
890ddd |
blur intensity. The squares will be cast vertically towards blurred regions.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Originally, this was a sub-optimal O(lx * ly * blur) algorithm. The following (still separated)
|
|
Toshihiro Shimizu |
890ddd |
is O(lx * ly) using precomputed sums in an additional line.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
The 'correct' algorithm could be implemented again as O(lx * ly * blur), with additional O(lx * blur)
|
|
Toshihiro Shimizu |
890ddd |
memory usage with precomputed sums along (blur) rows.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Pixels would have to be filtered one by one, but the horizontal filtering per pixel convolution row
|
|
Toshihiro Shimizu |
890ddd |
would take O(1). Thus it would be O(blur) (column filtering) per pixel.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Local namespace stuff
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
struct Sums {
|
|
Shinya Kitaoka |
6a4e01 |
std::unique_ptr<tuint64[]> m_sumsIX_r; //!< m_sumsIX1[i+1] = m_sumsIX1[i] + i * pix.r</tuint64[]>
|
|
Shinya Kitaoka |
6a4e01 |
std::unique_ptr<tuint64[]> m_sumsIX_g;</tuint64[]>
|
|
Shinya Kitaoka |
6a4e01 |
std::unique_ptr<tuint64[]> m_sumsIX_b;</tuint64[]>
|
|
Shinya Kitaoka |
6a4e01 |
std::unique_ptr<tuint64[]> m_sumsIX_m;</tuint64[]>
|
|
Shinya Kitaoka |
6a4e01 |
std::unique_ptr<tuint64[]> m_sumsX_r; //!< m_sumsX[i+1] = m_sumsX[i] + pix.r</tuint64[]>
|
|
Shinya Kitaoka |
6a4e01 |
std::unique_ptr<tuint64[]> m_sumsX_g;</tuint64[]>
|
|
Shinya Kitaoka |
6a4e01 |
std::unique_ptr<tuint64[]> m_sumsX_b;</tuint64[]>
|
|
Shinya Kitaoka |
6a4e01 |
std::unique_ptr<tuint64[]> m_sumsX_m;</tuint64[]>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Sums(int length)
|
|
Shinya Kitaoka |
6a4e01 |
: m_sumsIX_r(new TUINT64[length + 1])
|
|
Shinya Kitaoka |
6a4e01 |
, m_sumsIX_g(new TUINT64[length + 1])
|
|
Shinya Kitaoka |
6a4e01 |
, m_sumsIX_b(new TUINT64[length + 1])
|
|
Shinya Kitaoka |
6a4e01 |
, m_sumsIX_m(new TUINT64[length + 1])
|
|
Shinya Kitaoka |
6a4e01 |
, m_sumsX_r(new TUINT64[length + 1])
|
|
Shinya Kitaoka |
6a4e01 |
, m_sumsX_g(new TUINT64[length + 1])
|
|
Shinya Kitaoka |
6a4e01 |
, m_sumsX_b(new TUINT64[length + 1])
|
|
Shinya Kitaoka |
6a4e01 |
, m_sumsX_m(new TUINT64[length + 1])
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename pix=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
void build(Pix *line, int wrap, int n)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
++n;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_sumsIX_r[0] = m_sumsX_r[0] = 0;
|
|
Toshihiro Shimizu |
890ddd |
m_sumsIX_g[0] = m_sumsX_g[0] = 0;
|
|
Toshihiro Shimizu |
890ddd |
m_sumsIX_b[0] = m_sumsX_b[0] = 0;
|
|
Toshihiro Shimizu |
890ddd |
m_sumsIX_m[0] = m_sumsX_m[0] = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Pix *pix;
|
|
Toshihiro Shimizu |
890ddd |
int i, i_1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (pix = line, i_1 = 0, i = 1; i < n; pix += wrap, i_1 = i++) {
|
|
Toshihiro Shimizu |
890ddd |
m_sumsIX_r[i] = m_sumsIX_r[i_1] + i * pix->r;
|
|
Toshihiro Shimizu |
890ddd |
m_sumsIX_g[i] = m_sumsIX_g[i_1] + i * pix->g;
|
|
Toshihiro Shimizu |
890ddd |
m_sumsIX_b[i] = m_sumsIX_b[i_1] + i * pix->b;
|
|
Toshihiro Shimizu |
890ddd |
m_sumsIX_m[i] = m_sumsIX_m[i_1] + i * pix->m;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_sumsX_r[i] = m_sumsX_r[i_1] + pix->r;
|
|
Toshihiro Shimizu |
890ddd |
m_sumsX_g[i] = m_sumsX_g[i_1] + pix->g;
|
|
Toshihiro Shimizu |
890ddd |
m_sumsX_b[i] = m_sumsX_b[i_1] + pix->b;
|
|
Toshihiro Shimizu |
890ddd |
m_sumsX_m[i] = m_sumsX_m[i_1] + pix->m;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename grey="" pix,="" typename=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
void filterLine(Pix *lineIn, int wrapIn, Grey *lineGr, int wrapGr, Pix *lineOut, int wrapOut, int length,
|
|
Toshihiro Shimizu |
890ddd |
double blurFactor, Sums &sums)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// Build temporary sums
|
|
Toshihiro Shimizu |
890ddd |
sums.build(lineIn, wrapIn, length);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Declare vars
|
|
Toshihiro Shimizu |
890ddd |
double blur, kLeft, kRight, cLeft, cRight;
|
|
Toshihiro Shimizu |
890ddd |
double blurI;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Perform line filtering
|
|
Toshihiro Shimizu |
890ddd |
Pix *pixIn, *pixOut;
|
|
Toshihiro Shimizu |
890ddd |
Grey *pixGr;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int i, iLeft, iRight;
|
|
Toshihiro Shimizu |
890ddd |
++length;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = 1, pixIn = lineIn, pixGr = lineGr, pixOut = lineOut; i < length;
|
|
Toshihiro Shimizu |
890ddd |
++i, pixIn += wrapIn, pixGr += wrapGr, pixOut += wrapOut) {
|
|
Toshihiro Shimizu |
890ddd |
blur = pixGr->value * blurFactor; // A table of factors should be made - since we have a finite
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (blur > 0.0) {
|
|
Toshihiro Shimizu |
890ddd |
blur += 0.5; /*-- 0.5足すのは、注目ピクセルの半径分。例えばBlur0.5は、
|
|
Toshihiro Shimizu |
890ddd |
注目ピクセルの外側0.5ピクセルボケるということなので。
|
|
Toshihiro Shimizu |
890ddd |
--*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
blurI = (double)tfloor(blur);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double amount = blur + (2 * blur - blurI - 1) * blurI;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double dR = 1.0 / amount;
|
|
Toshihiro Shimizu |
890ddd |
double ini = (blur - blurI) / amount;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
kLeft = dR;
|
|
Toshihiro Shimizu |
890ddd |
cLeft = ini - dR * (i - blurI);
|
|
Toshihiro Shimizu |
890ddd |
kRight = -dR;
|
|
Toshihiro Shimizu |
890ddd |
cRight = blur / amount + dR * i;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// NOTE: The normalization factor with blur (not integer) would be:
|
|
Toshihiro Shimizu |
890ddd |
// 1.0 / (1 + 2 * blurI - (blurI / blur) * (blurI + 1)) -- could be done using a factors table
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
iLeft = tmax(i - tfloor(blur) - 1, 0);
|
|
Toshihiro Shimizu |
890ddd |
iRight = tmin(i + tfloor(blur), length - 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
pixOut->r = troundp(
|
|
Toshihiro Shimizu |
890ddd |
kLeft * (sums.m_sumsIX_r[i] - sums.m_sumsIX_r[iLeft]) + kRight * (sums.m_sumsIX_r[iRight] - sums.m_sumsIX_r[i]) +
|
|
Toshihiro Shimizu |
890ddd |
cLeft * (sums.m_sumsX_r[i] - sums.m_sumsX_r[iLeft]) + cRight * (sums.m_sumsX_r[iRight] - sums.m_sumsX_r[i]));
|
|
Toshihiro Shimizu |
890ddd |
pixOut->g = troundp(
|
|
Toshihiro Shimizu |
890ddd |
kLeft * (sums.m_sumsIX_g[i] - sums.m_sumsIX_g[iLeft]) + kRight * (sums.m_sumsIX_g[iRight] - sums.m_sumsIX_g[i]) +
|
|
Toshihiro Shimizu |
890ddd |
cLeft * (sums.m_sumsX_g[i] - sums.m_sumsX_g[iLeft]) + cRight * (sums.m_sumsX_g[iRight] - sums.m_sumsX_g[i]));
|
|
Toshihiro Shimizu |
890ddd |
pixOut->b = troundp(
|
|
Toshihiro Shimizu |
890ddd |
kLeft * (sums.m_sumsIX_b[i] - sums.m_sumsIX_b[iLeft]) + kRight * (sums.m_sumsIX_b[iRight] - sums.m_sumsIX_b[i]) +
|
|
Toshihiro Shimizu |
890ddd |
cLeft * (sums.m_sumsX_b[i] - sums.m_sumsX_b[iLeft]) + cRight * (sums.m_sumsX_b[iRight] - sums.m_sumsX_b[i]));
|
|
Toshihiro Shimizu |
890ddd |
pixOut->m = troundp(
|
|
Toshihiro Shimizu |
890ddd |
kLeft * (sums.m_sumsIX_m[i] - sums.m_sumsIX_m[iLeft]) + kRight * (sums.m_sumsIX_m[iRight] - sums.m_sumsIX_m[i]) +
|
|
Toshihiro Shimizu |
890ddd |
cLeft * (sums.m_sumsX_m[i] - sums.m_sumsX_m[iLeft]) + cRight * (sums.m_sumsX_m[iRight] - sums.m_sumsX_m[i]));
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
*pixOut = *pixIn;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename grey="" pix,="" typename=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
void doLocalBlur(TRasterPT<pix> rin, TRasterPT<pix> rcontrol, TRasterPT<pix> rout,</pix></pix></pix>
|
|
Toshihiro Shimizu |
890ddd |
double blur, const TPoint &displacement)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(rin->getLx() == rcontrol->getLx() && rin->getLy() == rcontrol->getLy());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double blurFactor = blur / Grey::maxChannelValue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int x, y, inLx, inLy, outLx, outLy, wrapIn, wrapOut, wrapC;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inLx = rin->getLx();
|
|
Toshihiro Shimizu |
890ddd |
inLy = rin->getLy();
|
|
Toshihiro Shimizu |
890ddd |
wrapIn = rin->getWrap();
|
|
Toshihiro Shimizu |
890ddd |
outLx = rout->getLx();
|
|
Toshihiro Shimizu |
890ddd |
outLy = rout->getLy();
|
|
Toshihiro Shimizu |
890ddd |
wrapOut = rout->getWrap();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Convert the control raster to grey values (this avoids the overhead of performing the pixel-to-value
|
|
Toshihiro Shimizu |
890ddd |
// conversion twice, once per line filtering)
|
|
Toshihiro Shimizu |
890ddd |
TRasterPT<grey> rcontrolGrey(rcontrol->getLx(), rcontrol->getLy());</grey>
|
|
Toshihiro Shimizu |
890ddd |
TRop::convert(rcontrolGrey, rcontrol);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
wrapC = rcontrolGrey->getWrap();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Pix *lineIn, *bufIn;
|
|
Toshihiro Shimizu |
890ddd |
Grey *lineC, *bufC;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Filter rin. The output filtering is still stored in rin.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
rin->lock();
|
|
Toshihiro Shimizu |
890ddd |
rcontrolGrey->lock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bufIn = rin->pixels(0);
|
|
Toshihiro Shimizu |
890ddd |
bufC = rcontrolGrey->pixels(0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
Sums sums(inLx);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (y = 0, lineIn = bufIn, lineC = bufC; y < inLy;
|
|
Toshihiro Shimizu |
890ddd |
++y, lineIn += wrapIn, lineC += wrapC) {
|
|
Toshihiro Shimizu |
890ddd |
// Filter row
|
|
Toshihiro Shimizu |
890ddd |
filterLine(lineIn, 1, lineC, 1, lineIn, 1, inLx, blurFactor, sums);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
Sums sums(inLy);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (x = 0, lineIn = bufIn, lineC = bufC; x < inLx;
|
|
Toshihiro Shimizu |
890ddd |
++x, ++lineIn, ++lineC) {
|
|
Toshihiro Shimizu |
890ddd |
// Filter column
|
|
Toshihiro Shimizu |
890ddd |
filterLine(lineIn, wrapIn, lineC, wrapC, lineIn, wrapIn, inLy, blurFactor, sums);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
rin->unlock();
|
|
Toshihiro Shimizu |
890ddd |
rcontrolGrey->unlock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Copy the interesting part of rin to rout
|
|
Toshihiro Shimizu |
890ddd |
TRect rectOut(rout->getBounds() - displacement);
|
|
Toshihiro Shimizu |
890ddd |
TRect rectIn(rin->getBounds() + displacement);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRop::copy(rout->extract(rectIn), rin->extract(rectOut));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
} //namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// LocalBlurFx implementation
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class LocalBlurFx : public TStandardRasterFx
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
FX_PLUGIN_DECLARATION(LocalBlurFx)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
protected:
|
|
Toshihiro Shimizu |
890ddd |
TRasterFxPort m_up, m_ref;
|
|
Toshihiro Shimizu |
890ddd |
TDoubleParamP m_value;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
LocalBlurFx()
|
|
Toshihiro Shimizu |
890ddd |
: m_value(20)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_value->setMeasureName("fxLength");
|
|
Toshihiro Shimizu |
890ddd |
addInputPort("Source", m_up);
|
|
Toshihiro Shimizu |
890ddd |
addInputPort("Reference", m_ref);
|
|
Toshihiro Shimizu |
890ddd |
bindParam(this, "value", m_value);
|
|
Toshihiro Shimizu |
890ddd |
m_value->setValueRange(0, (std::numeric_limits<double>::max)());</double>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
~LocalBlurFx() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool canHandle(const TRenderSettings &info, double frame)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return (isAlmostIsotropic(info.m_affine) || m_value->getValue(frame) == 0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_up.isConnected()) {
|
|
Toshihiro Shimizu |
890ddd |
bool ret = m_up->doGetBBox(frame, bBox, info);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double blur = fabs(m_value->getValue(frame));
|
|
Toshihiro Shimizu |
890ddd |
int blurI = tceil(blur);
|
|
Toshihiro Shimizu |
890ddd |
bBox = bBox.enlarge(blurI);
|
|
Toshihiro Shimizu |
890ddd |
|
|
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 enlarge(const TRectD &bbox, TRectD &requestedRect, int blur);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void doDryCompute(TRectD &rect, double frame, const TRenderSettings &info);
|
|
Toshihiro Shimizu |
890ddd |
void doCompute(TTile &tile, double frame, const TRenderSettings &info);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int getMemoryRequirement(const TRectD &rect, double frame, const TRenderSettings &info);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void LocalBlurFx::enlarge(const TRectD &bbox, TRectD &requestedRect, int blur)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// See BlurFx: this is a faithful replica
|
|
Toshihiro Shimizu |
890ddd |
if (bbox.isEmpty() || requestedRect.isEmpty()) {
|
|
Toshihiro Shimizu |
890ddd |
requestedRect.empty();
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD enlargedBBox(bbox.enlarge(blur));
|
|
Toshihiro Shimizu |
890ddd |
TRectD enlargedOut(requestedRect.enlarge(blur));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD originalP00(requestedRect.getP00());
|
|
Toshihiro Shimizu |
890ddd |
requestedRect = (enlargedOut * bbox) + (enlargedBBox * requestedRect);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
requestedRect -= originalP00;
|
|
Toshihiro Shimizu |
890ddd |
requestedRect.x0 = tfloor(requestedRect.x0);
|
|
Toshihiro Shimizu |
890ddd |
requestedRect.y0 = tfloor(requestedRect.y0);
|
|
Toshihiro Shimizu |
890ddd |
requestedRect.x1 = tceil(requestedRect.x1);
|
|
Toshihiro Shimizu |
890ddd |
requestedRect.y1 = tceil(requestedRect.y1);
|
|
Toshihiro Shimizu |
890ddd |
requestedRect += originalP00;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void LocalBlurFx::doDryCompute(TRectD &rectOut, double frame, const TRenderSettings &info)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// Mimics the doCompute() without actual computation.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TTile refTile;
|
|
Toshihiro Shimizu |
890ddd |
bool isUp = m_up.isConnected();
|
|
Toshihiro Shimizu |
890ddd |
bool isDown = m_ref.isConnected();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!isUp)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!isDown) {
|
|
Toshihiro Shimizu |
890ddd |
m_up->dryCompute(rectOut, frame, info);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double blur = fabs(m_value->getValue(frame) * sqrt(fabs(info.m_affine.det())));
|
|
Toshihiro Shimizu |
890ddd |
int blurI = tceil(blur);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD bboxIn;
|
|
Toshihiro Shimizu |
890ddd |
if (!m_up->getBBox(frame, bboxIn, info) || rectOut.isEmpty())
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD rectIn(rectOut);
|
|
Toshihiro Shimizu |
890ddd |
enlarge(bboxIn, rectIn, blurI);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (rectIn.isEmpty())
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_up->dryCompute(rectOut, frame, info);
|
|
Toshihiro Shimizu |
890ddd |
m_ref->dryCompute(rectOut, frame, info);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void LocalBlurFx::doCompute(TTile &tile, double frame, const TRenderSettings &info)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TTile refTile;
|
|
Toshihiro Shimizu |
890ddd |
bool isUp = m_up.isConnected();
|
|
Toshihiro Shimizu |
890ddd |
bool isDown = m_ref.isConnected();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!isUp)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!isDown) {
|
|
Toshihiro Shimizu |
890ddd |
m_up->compute(tile, frame, info);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Generic case
|
|
Toshihiro Shimizu |
890ddd |
assert(isAlmostIsotropic(info.m_affine));
|
|
Toshihiro Shimizu |
890ddd |
double blur = fabs(m_value->getValue(frame) * sqrt(fabs(info.m_affine.det())));
|
|
Toshihiro Shimizu |
890ddd |
int blurI = tceil(blur);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Get the requested tile's geometry
|
|
Toshihiro Shimizu |
890ddd |
TRectD rectOut(tile.m_pos, TDimensionD(tile.getRaster()->getLx(), tile.getRaster()->getLy()));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Retrieve the input interesting geometry - and ensure that something actually has
|
|
Toshihiro Shimizu |
890ddd |
// to be computed
|
|
Toshihiro Shimizu |
890ddd |
TRectD bboxIn;
|
|
Toshihiro Shimizu |
890ddd |
if (!m_up->getBBox(frame, bboxIn, info) || rectOut.isEmpty())
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD rectIn(rectOut);
|
|
Toshihiro Shimizu |
890ddd |
enlarge(bboxIn, rectIn, blurI);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (rectIn.isEmpty())
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Finally, allocate and compute the blur argument
|
|
Toshihiro Shimizu |
890ddd |
TTile tileIn;
|
|
Toshihiro Shimizu |
890ddd |
m_up->allocateAndCompute(
|
|
Toshihiro Shimizu |
890ddd |
tileIn, rectIn.getP00(), TDimension(rectIn.getLx(), rectIn.getLy()),
|
|
Toshihiro Shimizu |
890ddd |
tile.getRaster(), frame, info);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TTile tileRef;
|
|
Toshihiro Shimizu |
890ddd |
m_ref->allocateAndCompute(
|
|
Toshihiro Shimizu |
890ddd |
tileRef, rectIn.getP00(), TDimension(rectIn.getLx(), rectIn.getLy()),
|
|
Toshihiro Shimizu |
890ddd |
tile.getRaster(), frame, info);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Perform Local Blur
|
|
Toshihiro Shimizu |
890ddd |
TRasterP inRas(tileIn.getRaster());
|
|
Toshihiro Shimizu |
890ddd |
TRasterP refRas(tileRef.getRaster());
|
|
Toshihiro Shimizu |
890ddd |
TRasterP outRas(tile.getRaster());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRaster32P in32(inRas);
|
|
Toshihiro Shimizu |
890ddd |
TRaster32P ref32(refRas);
|
|
Toshihiro Shimizu |
890ddd |
TRaster32P out32(outRas);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPoint displacement(convert(rectIn.getP00() - tile.m_pos)); // inTile position relative to (out)tile
|
|
Toshihiro Shimizu |
890ddd |
// The difference already has integer coordinates due to enlarge()
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (in32 && ref32 && out32)
|
|
Toshihiro Shimizu |
890ddd |
doLocalBlur<tpixelrgbm32, tpixelgr8="">(in32, ref32, out32, blur, displacement);</tpixelrgbm32,>
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
TRaster64P in64(inRas);
|
|
Toshihiro Shimizu |
890ddd |
TRaster64P ref64(refRas);
|
|
Toshihiro Shimizu |
890ddd |
TRaster64P out64(outRas);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (in64 && ref64 && out64)
|
|
Toshihiro Shimizu |
890ddd |
doLocalBlur<tpixelrgbm64, tpixelgr16="">(in64, ref64, out64, blur, displacement);</tpixelrgbm64,>
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
throw TException("LocalBlurFx: unsupported raster type");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int LocalBlurFx::getMemoryRequirement(const TRectD &rect, double frame, const TRenderSettings &info)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double blur = fabs(m_value->getValue(frame) * sqrt(fabs(info.m_affine.det())));
|
|
Toshihiro Shimizu |
890ddd |
int blurI = tceil(blur);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return 2 * TRasterFx::memorySize(rect.enlarge(blurI), info.m_bpp);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
FX_PLUGIN_IDENTIFIER(LocalBlurFx, "localBlurFx")
|