index 5d79b1c3eba120ad608a851098776d20a7bd953e..76b541ace61029b0ac3d855ccb1e99015b049dbc 100644 (file)
#include <cmath>
#include <complex>
#include <glib.h>
+#include <cstdlib>
#include <limits>
-#include "isnan.h"
+#include "2geom/isnan.h"
#include "display/nr-filter-primitive.h"
#include "display/nr-filter-gaussian.h"
#include "display/nr-filter-types.h"
+#include "display/nr-filter-units.h"
#include "libnr/nr-pixblock.h"
#include "libnr/nr-matrix.h"
+#include "libnr/nr-matrix-fns.h"
#include "util/fixed_point.h"
#include "prefs-utils.h"
// Using the backwards-pass initialization procedure from:
// Boundary Conditions for Young - van Vliet Recursive Filtering
// Bill Triggs, Michael Sdika
-// IEEE Transactions on Signal Processing, Volume 54, Number 5 - may 2006
+// IEEE Transactions on Signal Processing, Volume 54, Number 5 - may 2006
// Number of IIR filter coefficients used. Currently only 3 is supported.
// "Recursive Gaussian Derivative Filters" says this is enough though (and
}
// Type used for IIR filter coefficients (can be 10.21 signed fixed point, see Anisotropic Gaussian Filtering Using Fixed Point Arithmetic, Christoph H. Lampert & Oliver Wirjadi, 2006)
-typedef double IIRValue;
+typedef double IIRValue;
// Type used for FIR filter coefficients (can be 16.16 unsigned fixed point, should have 8 or more bits in the fractional part, the integer part should be capable of storing approximately 20*255)
typedef Inkscape::Util::FixedPoint<unsigned int,16> FIRValue;
template<typename Tt, typename Ts>
static inline Tt round_cast(Ts const& v) {
- static Ts const rndoffset(.5);
- return static_cast<Tt>(v+rndoffset);
+ static Ts const rndoffset(.5);
+ return static_cast<Tt>(v+rndoffset);
}
template<typename Tt, typename Ts>
static inline Tt clip_round_cast(Ts const& v, Tt const minval=std::numeric_limits<Tt>::min(), Tt const maxval=std::numeric_limits<Tt>::max()) {
if ( v < minval ) return minval;
if ( v > maxval ) return maxval;
- return round_cast<Tt>(v);
+ return round_cast<Tt>(v);
}
namespace NR {
// store the result in bufx
dst[dst_disp + byte] = round_cast<PT>(sum);
- // optimization: if there was no variation within this point's neighborhood,
- // skip ahead while we keep seeing the same last_in byte:
+ // optimization: if there was no variation within this point's neighborhood,
+ // skip ahead while we keep seeing the same last_in byte:
// blurring flat color would not change it anyway
if (different_count <= 1) {
int pos = c1 + 1;
@@ -505,10 +508,16 @@ upsample(PT *const dst, int const dstr1, int const dstr2, unsigned int const dn1
}
}
-int FilterGaussian::render(FilterSlot &slot, Matrix const &trans)
+int FilterGaussian::render(FilterSlot &slot, FilterUnits const &units)
{
/* in holds the input pixblock */
NRPixBlock *in = slot.get(_input);
+ if (!in) {
+ g_warning("Missing source image for feGaussianBlur (in=%d)", _input);
+ return 1;
+ }
+
+ Matrix trans = units.get_matrix_primitiveunits2pb();
/* If to either direction, the standard deviation is zero or
* input image is not defined,
// Some common constants
int const width_org = in->area.x1-in->area.x0, height_org = in->area.y1-in->area.y0;
- double const deviation_x_org = _deviation_x * trans.expansionX();
- double const deviation_y_org = _deviation_y * trans.expansionY();
+ double const deviation_x_org = _deviation_x * NR::expansionX(trans);
+ double const deviation_y_org = _deviation_y * NR::expansionY(trans);
int const PC = NR_PIXBLOCK_BPP(in);
// Subsampling constants
void FilterGaussian::area_enlarge(NRRectL &area, Matrix const &trans)
{
- int area_x = _effect_area_scr(_deviation_x * trans.expansionX());
- int area_y = _effect_area_scr(_deviation_y * trans.expansionY());
+ int area_x = _effect_area_scr(_deviation_x * NR::expansionX(trans));
+ int area_y = _effect_area_scr(_deviation_y * NR::expansionY(trans));
// maximum is used because rotations can mix up these directions
// TODO: calculate a more tight-fitting rendering area
int area_max = std::max(area_x, area_y);
void FilterGaussian::set_deviation(double deviation)
{
- if(isFinite(deviation) && deviation >= 0) {
+ if(IS_FINITE(deviation) && deviation >= 0) {
_deviation_x = _deviation_y = deviation;
}
}
void FilterGaussian::set_deviation(double x, double y)
{
- if(isFinite(x) && x >= 0 && isFinite(y) && y >= 0) {
+ if(IS_FINITE(x) && x >= 0 && IS_FINITE(y) && y >= 0) {
_deviation_x = x;
_deviation_y = y;
}