More progress with polyphase filters.

This commit is contained in:
castano
2007-11-28 10:34:40 +00:00
parent fef6466c1c
commit c772a00b8f
3 changed files with 177 additions and 141 deletions

View File

@ -203,47 +203,62 @@ static Filter s_filter_array[] = {
{filter_kaiser, 1.0f}, // Kaiser {filter_kaiser, 1.0f}, // Kaiser
}; };
inline static float sampleFilter(Filter::Function func, float x, float scale, int samples)
{
float sum = 0;
for(int s = 0; s < samples; s++)
{
sum += func((x + (float(s) + 0.5f) * (1.0f / float(samples))) * scale);
}
return sum;
}
} // namespace } // namespace
/// Ctor. /// Ctor.
Kernel1::Kernel1(uint width) : w(width) Kernel1::Kernel1(uint ws) : m_windowSize(ws)
{ {
data = new float[w]; m_data = new float[m_windowSize];
} }
/// Copy ctor. /// Copy ctor.
Kernel1::Kernel1(const Kernel1 & k) : w(k.w) Kernel1::Kernel1(const Kernel1 & k) : m_windowSize(k.m_windowSize)
{ {
data = new float[w]; m_data = new float[m_windowSize];
for(uint i = 0; i < w; i++) { for(uint i = 0; i < m_windowSize; i++) {
data[i] = k.data[i]; m_data[i] = k.m_data[i];
} }
} }
/// Dtor. /// Dtor.
Kernel1::~Kernel1() Kernel1::~Kernel1()
{ {
delete data; delete m_data;
} }
/// Normalize the filter. /// Normalize the filter.
void Kernel1::normalize() void Kernel1::normalize()
{ {
float total = 0.0f; float total = 0.0f;
for(uint i = 0; i < w; i++) { for(uint i = 0; i < m_windowSize; i++) {
total += data[i]; total += m_data[i];
} }
float inv = 1.0f / total; float inv = 1.0f / total;
for(uint i = 0; i < w; i++) { for(uint i = 0; i < m_windowSize; i++) {
data[i] *= inv; m_data[i] *= inv;
} }
} }
/// Init 1D Box filter. /// Init 1D filter.
void Kernel1::initFilter(Filter::Enum f, int samples /*= 1*/) void Kernel1::initFilter(Filter::Enum f, int samples /*= 1*/)
{ {
nvDebugCheck(f < Filter::Num); nvDebugCheck(f < Filter::Num);
@ -252,21 +267,12 @@ void Kernel1::initFilter(Filter::Enum f, int samples /*= 1*/)
float (* filter_function)(float) = s_filter_array[f].function; float (* filter_function)(float) = s_filter_array[f].function;
const float support = s_filter_array[f].support; const float support = s_filter_array[f].support;
const float half_width = float(w) / 2; const float halfWindowSize = float(m_windowSize) / 2.0f;
const float offset = -half_width; const float scale = support / halfWindowSize;
const float s_scale = 1.0f / float(samples);
const float x_scale = support / half_width;
for(uint i = 0; i < w; i++) for(uint i = 0; i < m_windowSize; i++)
{ {
float sum = 0; m_data[i] = sampleFilter(filter_function, i - halfWindowSize, scale, samples);
for(int s = 0; s < samples; s++)
{
float x = i + offset + (s + 0.5f) * s_scale;
sum += filter_function(x * x_scale);
}
data[i] = sum;
} }
normalize(); normalize();
@ -276,13 +282,12 @@ void Kernel1::initFilter(Filter::Enum f, int samples /*= 1*/)
/// Init 1D sinc filter. /// Init 1D sinc filter.
void Kernel1::initSinc(float stretch /*= 1*/) void Kernel1::initSinc(float stretch /*= 1*/)
{ {
const float half_width = float(w) / 2; const float halfWindowSize = float(m_windowSize) / 2;
const float offset = -half_width;
const float nudge = 0.5f; const float nudge = 0.5f;
for(uint i = 0; i < w; i++) { for(uint i = 0; i < m_windowSize; i++) {
const float x = (i + offset) + nudge; const float x = (i - halfWindowSize) + nudge;
data[i] = sincf(PI * x * stretch); m_data[i] = sincf(PI * x * stretch);
} }
normalize(); normalize();
@ -292,25 +297,24 @@ void Kernel1::initSinc(float stretch /*= 1*/)
/// Init 1D Kaiser-windowed sinc filter. /// Init 1D Kaiser-windowed sinc filter.
void Kernel1::initKaiser(float alpha /*= 4*/, float stretch /*= 0.5*/, int samples/*= 1*/) void Kernel1::initKaiser(float alpha /*= 4*/, float stretch /*= 0.5*/, int samples/*= 1*/)
{ {
const float half_width = float(w) / 2; const float halfWindowSize = float(m_windowSize) / 2;
const float offset = -half_width;
const float s_scale = 1.0f / float(samples); const float s_scale = 1.0f / float(samples);
const float x_scale = 1.0f / half_width; const float x_scale = 1.0f / halfWindowSize;
for(uint i = 0; i < w; i++) for(uint i = 0; i < m_windowSize; i++)
{ {
float sum = 0; float sum = 0;
for(int s = 0; s < samples; s++) for(int s = 0; s < samples; s++)
{ {
float x = i + offset + (s + 0.5f) * s_scale; float x = i - halfWindowSize + (s + 0.5f) * s_scale;
const float sinc_value = sincf(PI * x * stretch); const float sinc_value = sincf(PI * x * stretch);
const float window_value = filter_kaiser(x * x_scale, alpha); // @@ should the window be streched? I don't think so. const float window_value = filter_kaiser(x * x_scale, alpha); // @@ should the window be streched? I don't think so.
sum += sinc_value * window_value; sum += sinc_value * window_value;
} }
data[i] = sum; m_data[i] = sum;
} }
normalize(); normalize();
@ -320,13 +324,12 @@ void Kernel1::initKaiser(float alpha /*= 4*/, float stretch /*= 0.5*/, int sampl
/// Init 1D Mitchell filter. /// Init 1D Mitchell filter.
void Kernel1::initMitchell(float b, float c) void Kernel1::initMitchell(float b, float c)
{ {
const float half_width = float(w) / 2; const float halfWindowSize = float(m_windowSize) / 2;
const float offset = -half_width;
const float nudge = 0.5f; const float nudge = 0.5f;
for(uint i = 0; i < w; i++) { for (uint i = 0; i < m_windowSize; i++) {
const float x = (i + offset) + nudge; const float x = (i - halfWindowSize) + nudge;
data[i] = filter_mitchell(x / half_width, b, c); m_data[i] = filter_mitchell(x / halfWindowSize, b, c);
} }
normalize(); normalize();
@ -336,25 +339,25 @@ void Kernel1::initMitchell(float b, float c)
/// Print the kernel for debugging purposes. /// Print the kernel for debugging purposes.
void Kernel1::debugPrint() void Kernel1::debugPrint()
{ {
for(uint i = 0; i < w; i++) { for (uint i = 0; i < m_windowSize; i++) {
nvDebug("%d: %f\n", i, data[i]); nvDebug("%d: %f\n", i, m_data[i]);
} }
} }
/// Ctor. /// Ctor.
Kernel2::Kernel2(uint width) : w(width) Kernel2::Kernel2(uint ws) : m_windowSize(ws)
{ {
data = new float[w*w]; m_data = new float[m_windowSize * m_windowSize];
} }
/// Copy ctor. /// Copy ctor.
Kernel2::Kernel2(const Kernel2 & k) : w(k.w) Kernel2::Kernel2(const Kernel2 & k) : m_windowSize(k.m_windowSize)
{ {
data = new float[w*w]; m_data = new float[m_windowSize * m_windowSize];
for(uint i = 0; i < w*w; i++) { for (uint i = 0; i < m_windowSize * m_windowSize; i++) {
data[i] = k.data[i]; m_data[i] = k.m_data[i];
} }
} }
@ -362,29 +365,29 @@ Kernel2::Kernel2(const Kernel2 & k) : w(k.w)
/// Dtor. /// Dtor.
Kernel2::~Kernel2() Kernel2::~Kernel2()
{ {
delete data; delete m_data;
} }
/// Normalize the filter. /// Normalize the filter.
void Kernel2::normalize() void Kernel2::normalize()
{ {
float total = 0.0f; float total = 0.0f;
for(uint i = 0; i < w*w; i++) { for(uint i = 0; i < m_windowSize*m_windowSize; i++) {
total += fabs(data[i]); total += fabs(m_data[i]);
} }
float inv = 1.0f / total; float inv = 1.0f / total;
for(uint i = 0; i < w*w; i++) { for(uint i = 0; i < m_windowSize*m_windowSize; i++) {
data[i] *= inv; m_data[i] *= inv;
} }
} }
/// Transpose the kernel. /// Transpose the kernel.
void Kernel2::transpose() void Kernel2::transpose()
{ {
for(uint i = 0; i < w; i++) { for(uint i = 0; i < m_windowSize; i++) {
for(uint j = i+1; j < w; j++) { for(uint j = i+1; j < m_windowSize; j++) {
swap(data[i*w + j], data[j*w + i]); swap(m_data[i*m_windowSize + j], m_data[j*m_windowSize + i]);
} }
} }
} }
@ -392,40 +395,40 @@ void Kernel2::transpose()
/// Init laplacian filter, usually used for sharpening. /// Init laplacian filter, usually used for sharpening.
void Kernel2::initLaplacian() void Kernel2::initLaplacian()
{ {
nvDebugCheck(w == 3); nvDebugCheck(m_windowSize == 3);
// data[0] = -1; data[1] = -1; data[2] = -1; // m_data[0] = -1; m_data[1] = -1; m_data[2] = -1;
// data[3] = -1; data[4] = +8; data[5] = -1; // m_data[3] = -1; m_data[4] = +8; m_data[5] = -1;
// data[6] = -1; data[7] = -1; data[8] = -1; // m_data[6] = -1; m_data[7] = -1; m_data[8] = -1;
data[0] = +0; data[1] = -1; data[2] = +0; m_data[0] = +0; m_data[1] = -1; m_data[2] = +0;
data[3] = -1; data[4] = +4; data[5] = -1; m_data[3] = -1; m_data[4] = +4; m_data[5] = -1;
data[6] = +0; data[7] = -1; data[8] = +0; m_data[6] = +0; m_data[7] = -1; m_data[8] = +0;
// data[0] = +1; data[1] = -2; data[2] = +1; // m_data[0] = +1; m_data[1] = -2; m_data[2] = +1;
// data[3] = -2; data[4] = +4; data[5] = -2; // m_data[3] = -2; m_data[4] = +4; m_data[5] = -2;
// data[6] = +1; data[7] = -2; data[8] = +1; // m_data[6] = +1; m_data[7] = -2; m_data[8] = +1;
} }
/// Init simple edge detection filter. /// Init simple edge detection filter.
void Kernel2::initEdgeDetection() void Kernel2::initEdgeDetection()
{ {
nvCheck(w == 3); nvCheck(m_windowSize == 3);
data[0] = 0; data[1] = 0; data[2] = 0; m_data[0] = 0; m_data[1] = 0; m_data[2] = 0;
data[3] = -1; data[4] = 0; data[5] = 1; m_data[3] =-1; m_data[4] = 0; m_data[5] = 1;
data[6] = 0; data[7] = 0; data[8] = 0; m_data[6] = 0; m_data[7] = 0; m_data[8] = 0;
} }
/// Init sobel filter. /// Init sobel filter.
void Kernel2::initSobel() void Kernel2::initSobel()
{ {
if (w == 3) if (m_windowSize == 3)
{ {
data[0] = -1; data[1] = 0; data[2] = 1; m_data[0] = -1; m_data[1] = 0; m_data[2] = 1;
data[3] = -2; data[4] = 0; data[5] = 2; m_data[3] = -2; m_data[4] = 0; m_data[5] = 2;
data[6] = -1; data[7] = 0; data[8] = 1; m_data[6] = -1; m_data[7] = 0; m_data[8] = 1;
} }
else if (w == 5) else if (m_windowSize == 5)
{ {
float elements[] = { float elements[] = {
-1, -2, 0, 2, 1, -1, -2, 0, 2, 1,
@ -436,10 +439,10 @@ void Kernel2::initSobel()
}; };
for (int i = 0; i < 5*5; i++) { for (int i = 0; i < 5*5; i++) {
data[i] = elements[i]; m_data[i] = elements[i];
} }
} }
else if (w == 7) else if (m_windowSize == 7)
{ {
float elements[] = { float elements[] = {
-1, -2, -3, 0, 3, 2, 1, -1, -2, -3, 0, 3, 2, 1,
@ -452,10 +455,10 @@ void Kernel2::initSobel()
}; };
for (int i = 0; i < 7*7; i++) { for (int i = 0; i < 7*7; i++) {
data[i] = elements[i]; m_data[i] = elements[i];
} }
} }
else if (w == 9) else if (m_windowSize == 9)
{ {
float elements[] = { float elements[] = {
-1, -2, -3, -4, 0, 4, 3, 2, 1, -1, -2, -3, -4, 0, 4, 3, 2, 1,
@ -470,7 +473,7 @@ void Kernel2::initSobel()
}; };
for (int i = 0; i < 9*9; i++) { for (int i = 0; i < 9*9; i++) {
data[i] = elements[i]; m_data[i] = elements[i];
} }
} }
} }
@ -478,13 +481,13 @@ void Kernel2::initSobel()
/// Init prewitt filter. /// Init prewitt filter.
void Kernel2::initPrewitt() void Kernel2::initPrewitt()
{ {
if (w == 3) if (m_windowSize == 3)
{ {
data[0] = -1; data[1] = 0; data[2] = -1; m_data[0] = -1; m_data[1] = 0; m_data[2] = -1;
data[3] = -1; data[4] = 0; data[5] = -1; m_data[3] = -1; m_data[4] = 0; m_data[5] = -1;
data[6] = -1; data[7] = 0; data[8] = -1; m_data[6] = -1; m_data[7] = 0; m_data[8] = -1;
} }
else if (w == 5) else if (m_windowSize == 5)
{ {
// @@ Is this correct? // @@ Is this correct?
float elements[] = { float elements[] = {
@ -496,7 +499,7 @@ void Kernel2::initPrewitt()
}; };
for (int i = 0; i < 5*5; i++) { for (int i = 0; i < 5*5; i++) {
data[i] = elements[i]; m_data[i] = elements[i];
} }
} }
} }
@ -504,7 +507,7 @@ void Kernel2::initPrewitt()
/// Init blended sobel filter. /// Init blended sobel filter.
void Kernel2::initBlendedSobel(const Vector4 & scale) void Kernel2::initBlendedSobel(const Vector4 & scale)
{ {
nvCheck(w == 9); nvCheck(m_windowSize == 9);
{ {
const float elements[] = { const float elements[] = {
@ -520,7 +523,7 @@ void Kernel2::initBlendedSobel(const Vector4 & scale)
}; };
for (int i = 0; i < 9*9; i++) { for (int i = 0; i < 9*9; i++) {
data[i] = elements[i] * scale.w(); m_data[i] = elements[i] * scale.w();
} }
} }
{ {
@ -536,7 +539,7 @@ void Kernel2::initBlendedSobel(const Vector4 & scale)
for (int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
for (int e = 0; e < 7; e++) { for (int e = 0; e < 7; e++) {
data[i * 9 + e + 1] += elements[i * 7 + e] * scale.z(); m_data[i * 9 + e + 1] += elements[i * 7 + e] * scale.z();
} }
} }
} }
@ -551,7 +554,7 @@ void Kernel2::initBlendedSobel(const Vector4 & scale)
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
for (int e = 0; e < 5; e++) { for (int e = 0; e < 5; e++) {
data[i * 9 + e + 2] += elements[i * 5 + e] * scale.y(); m_data[i * 9 + e + 2] += elements[i * 5 + e] * scale.y();
} }
} }
} }
@ -564,7 +567,7 @@ void Kernel2::initBlendedSobel(const Vector4 & scale)
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
for (int e = 0; e < 3; e++) { for (int e = 0; e < 3; e++) {
data[i * 9 + e + 3] += elements[i * 3 + e] * scale.x(); m_data[i * 9 + e + 3] += elements[i * 3 + e] * scale.x();
} }
} }
} }
@ -582,6 +585,7 @@ static bool isMonoPhase(float w)
} }
PolyphaseKernel::PolyphaseKernel(float w, uint l) : PolyphaseKernel::PolyphaseKernel(float w, uint l) :
m_width(w), m_width(w),
m_size(ceilf(w) + 1), m_size(ceilf(w) + 1),
@ -605,42 +609,70 @@ PolyphaseKernel::~PolyphaseKernel()
delete [] m_data; delete [] m_data;
} }
/* @@ Should we precompute left & right?
// scale factor
double dScale = double(uDstSize) / double(uSrcSize);
if(dScale < 1.0) {
// minification
dWidth = dFilterWidth / dScale;
dFScale = dScale;
} else {
// magnification
dWidth= dFilterWidth;
}
// window size is the number of sampled pixels
m_WindowSize = 2 * (int)ceil(dWidth) + 1;
m_LineLength = uDstSize;
// offset for discrete to continuous coordinate conversion
double dOffset = (0.5 / dScale) - 0.5;
for(u = 0; u < m_LineLength; u++) {
// scan through line of contributions
double dCenter = (double)u / dScale + dOffset; // reverse mapping
// find the significant edge points that affect the pixel
int iLeft = MAX (0, (int)floor (dCenter - dWidth));
int iRight = MIN ((int)ceil (dCenter + dWidth), int(uSrcSize) - 1);
...
}
*/
void PolyphaseKernel::initFilter(Filter::Enum f, int samples/*= 1*/) void PolyphaseKernel::initFilter(Filter::Enum f, int samples/*= 1*/)
{ {
nvCheck(f < Filter::Num); nvCheck(f < Filter::Num);
nvDebug("Init Filter:\n");
nvDebug(" width = %f\n", m_width);
float (* filter_function)(float) = s_filter_array[f].function; float (* filter_function)(float) = s_filter_array[f].function;
const float support = s_filter_array[f].support; const float support = s_filter_array[f].support;
const float half_width = m_width / 2; const float half_width = m_width / 2;
const float offset = -half_width; const float scale = support / half_width;
const float s_scale = 1.0f / float(samples);
const float x_scale = support / half_width;
for (uint j = 0; j < m_length; j++) for (uint j = 0; j < m_length; j++)
{ {
const float phase = frac(m_width * j); const float phase = frac(m_width * j);
const float offset = half_width + phase;
nvDebug("%d: ", j);
float total = 0.0f; float total = 0.0f;
for (uint i = 0; i < m_size; i++) for (uint i = 0; i < m_size; i++)
{ {
const float x = i + offset - phase; float sample = sampleFilter(filter_function, i - offset, scale, samples);
float sum = 0; nvDebug("(%5.3f | %d) ", sample, j + i - m_size/2);
for(int s = 0; s < samples; s++)
{ m_data[j * m_size + i] = sample;
const float xx = x + (s + 0.5f) * s_scale; total += sample;
sum += filter_function(xx * x_scale);
}
m_data[j * m_size + i] = sum;
total += sum;
} }
nvDebug("\n");
// normalize weights.
for (uint i = 0; i < m_size; i++) for (uint i = 0; i < m_size; i++)
{ {
m_data[j * m_size + i] /= total; m_data[j * m_size + i] /= total;

View File

@ -26,7 +26,9 @@ namespace nv
Num Num
}; };
float (*function)(float x); typedef float (* Function)(float);
Function function;
float support; float support;
}; };
@ -35,18 +37,18 @@ namespace nv
class Kernel1 class Kernel1
{ {
public: public:
NVIMAGE_API Kernel1(uint width); NVIMAGE_API Kernel1(uint windowSize);
NVIMAGE_API Kernel1(const Kernel1 & k); NVIMAGE_API Kernel1(const Kernel1 & k);
NVIMAGE_API ~Kernel1(); NVIMAGE_API ~Kernel1();
NVIMAGE_API void normalize(); NVIMAGE_API void normalize();
float valueAt(uint x) const { float valueAt(uint x) const {
return data[x]; return m_data[x];
} }
uint width() const { uint windowSize() const {
return w; return m_windowSize;
} }
NVIMAGE_API void initFilter(Filter::Enum filter, int samples = 1); NVIMAGE_API void initFilter(Filter::Enum filter, int samples = 1);
@ -57,8 +59,8 @@ namespace nv
NVIMAGE_API void debugPrint(); NVIMAGE_API void debugPrint();
private: private:
const uint w; const uint m_windowSize;
float * data; float * m_data;
}; };
@ -74,11 +76,11 @@ namespace nv
NVIMAGE_API void transpose(); NVIMAGE_API void transpose();
float valueAt(uint x, uint y) const { float valueAt(uint x, uint y) const {
return data[y * w + x]; return m_data[y * m_windowSize + x];
} }
uint width() const { uint windowSize() const {
return w; return m_windowSize;
} }
NVIMAGE_API void initLaplacian(); NVIMAGE_API void initLaplacian();
@ -89,8 +91,8 @@ namespace nv
NVIMAGE_API void initBlendedSobel(const Vector4 & scale); NVIMAGE_API void initBlendedSobel(const Vector4 & scale);
private: private:
const uint w; const uint m_windowSize;
float * data; float * m_data;
}; };
/// A 1D polyphase kernel /// A 1D polyphase kernel
@ -109,7 +111,7 @@ namespace nv
return m_width; return m_width;
} }
uint size() const { uint windowSize() const {
return m_size; return m_size;
} }

View File

@ -549,7 +549,7 @@ FloatImage * FloatImage::downSample(const Kernel1 & kernel, WrapMode wm) const
/// Downsample applying a 1D kernel separately in each dimension. /// Downsample applying a 1D kernel separately in each dimension.
FloatImage * FloatImage::downSample(const Kernel1 & kernel, uint w, uint h, WrapMode wm) const FloatImage * FloatImage::downSample(const Kernel1 & kernel, uint w, uint h, WrapMode wm) const
{ {
nvCheck(!(kernel.width() & 1)); // Make sure that kernel m_width is even. nvCheck(!(kernel.windowSize() & 1)); // Make sure that kernel m_width is even.
AutoPtr<FloatImage> tmp_image( new FloatImage() ); AutoPtr<FloatImage> tmp_image( new FloatImage() );
tmp_image->allocate(m_componentNum, w, m_height); tmp_image->allocate(m_componentNum, w, m_height);
@ -611,6 +611,9 @@ FloatImage * FloatImage::downSample(uint w, uint h, WrapMode wm) const
xkernel.debugPrint(); xkernel.debugPrint();
// @@ Select fastest filtering order:
// w * m_height <= h * m_width -> XY, else -> YX
AutoPtr<FloatImage> tmp_image( new FloatImage() ); AutoPtr<FloatImage> tmp_image( new FloatImage() );
tmp_image->allocate(m_componentNum, w, m_height); tmp_image->allocate(m_componentNum, w, m_height);
@ -620,7 +623,7 @@ FloatImage * FloatImage::downSample(uint w, uint h, WrapMode wm) const
Array<float> tmp_column(h); Array<float> tmp_column(h);
tmp_column.resize(h); tmp_column.resize(h);
for(uint c = 0; c < m_componentNum; c++) for (uint c = 0; c < m_componentNum; c++)
{ {
float * tmp_channel = tmp_image->channel(c); float * tmp_channel = tmp_image->channel(c);
@ -630,7 +633,7 @@ FloatImage * FloatImage::downSample(uint w, uint h, WrapMode wm) const
float * dst_channel = dst_image->channel(c); float * dst_channel = dst_image->channel(c);
for(uint x = 0; x < w; x++) { for (uint x = 0; x < w; x++) {
tmp_image->applyKernelVertical(&ykernel, yscale, x, c, wm, tmp_column.unsecureBuffer()); tmp_image->applyKernelVertical(&ykernel, yscale, x, c, wm, tmp_column.unsecureBuffer());
for(uint y = 0; y < h; y++) { for(uint y = 0; y < h; y++) {
@ -639,7 +642,6 @@ FloatImage * FloatImage::downSample(uint w, uint h, WrapMode wm) const
} }
} }
//return tmp_image.release();
return dst_image.release(); return dst_image.release();
} }
@ -650,17 +652,17 @@ float FloatImage::applyKernel(const Kernel2 * k, int x, int y, int c, WrapMode w
{ {
nvDebugCheck(k != NULL); nvDebugCheck(k != NULL);
const uint kernelWidth = k->width(); const uint kernelWindow = k->windowSize();
const int kernelOffset = int(kernelWidth / 2) - 1; const int kernelOffset = int(kernelWindow / 2) - 1;
const float * channel = this->channel(c); const float * channel = this->channel(c);
float sum = 0.0f; float sum = 0.0f;
for(uint i = 0; i < kernelWidth; i++) for (uint i = 0; i < kernelWindow; i++)
{ {
const int src_y = int(y + i) - kernelOffset; const int src_y = int(y + i) - kernelOffset;
for(uint e = 0; e < kernelWidth; e++) for (uint e = 0; e < kernelWindow; e++)
{ {
const int src_x = int(x + e) - kernelOffset; const int src_x = int(x + e) - kernelOffset;
@ -679,13 +681,13 @@ float FloatImage::applyKernelVertical(const Kernel1 * k, int x, int y, int c, Wr
{ {
nvDebugCheck(k != NULL); nvDebugCheck(k != NULL);
const uint kernelWidth = k->width(); const uint kernelWindow = k->windowSize();
const int kernelOffset = int(kernelWidth / 2) - 1; const int kernelOffset = int(kernelWindow / 2) - 1;
const float * channel = this->channel(c); const float * channel = this->channel(c);
float sum = 0.0f; float sum = 0.0f;
for(uint i = 0; i < kernelWidth; i++) for (uint i = 0; i < kernelWindow; i++)
{ {
const int src_y = int(y + i) - kernelOffset; const int src_y = int(y + i) - kernelOffset;
const int idx = this->index(x, src_y, wm); const int idx = this->index(x, src_y, wm);
@ -701,13 +703,13 @@ float FloatImage::applyKernelHorizontal(const Kernel1 * k, int x, int y, int c,
{ {
nvDebugCheck(k != NULL); nvDebugCheck(k != NULL);
const uint kernelWidth = k->width(); const uint kernelWindow = k->windowSize();
const int kernelOffset = int(kernelWidth / 2) - 1; const int kernelOffset = int(kernelWindow / 2) - 1;
const float * channel = this->channel(c); const float * channel = this->channel(c);
float sum = 0.0f; float sum = 0.0f;
for(uint e = 0; e < kernelWidth; e++) for (uint e = 0; e < kernelWindow; e++)
{ {
const int src_x = int(x + e) - kernelOffset; const int src_x = int(x + e) - kernelOffset;
const int idx = this->index(src_x, y, wm); const int idx = this->index(src_x, y, wm);
@ -725,9 +727,9 @@ void FloatImage::applyKernelVertical(const PolyphaseKernel * k, float scale, int
nvDebugCheck(k != NULL); nvDebugCheck(k != NULL);
const float kernelWidth = k->width(); const float kernelWidth = k->width();
const float kernelOffset = scale * 0.5f; const float kernelOffset = kernelWidth * 0.5f;
const int kernelLength = k->length(); const int kernelLength = k->length();
const int kernelWindow = k->size(); const int kernelWindow = k->windowSize();
const float * channel = this->channel(c); const float * channel = this->channel(c);
@ -752,9 +754,9 @@ void FloatImage::applyKernelHorizontal(const PolyphaseKernel * k, float scale, i
nvDebugCheck(k != NULL); nvDebugCheck(k != NULL);
const float kernelWidth = k->width(); const float kernelWidth = k->width();
const float kernelOffset = scale * 0.5f; const float kernelOffset = kernelWidth * 0.5f;
const int kernelLength = k->length(); const int kernelLength = k->length();
const int kernelWindow = k->size(); const int kernelWindow = k->windowSize();
const float * channel = this->channel(c); const float * channel = this->channel(c);