diff --git a/src/nvimage/Filter.cpp b/src/nvimage/Filter.cpp index e650a21..db06d80 100644 --- a/src/nvimage/Filter.cpp +++ b/src/nvimage/Filter.cpp @@ -283,7 +283,6 @@ void GaussianFilter::setParameters(float variance) -/// Ctor. Kernel1::Kernel1(const Filter & f, int iscale, int samples/*= 32*/) { nvDebugCheck(iscale > 1); @@ -312,13 +311,12 @@ Kernel1::Kernel1(const Filter & f, int iscale, int samples/*= 32*/) } } -/// Dtor. Kernel1::~Kernel1() { delete m_data; } -/// Print the kernel for debugging purposes. +// Print the kernel for debugging purposes. void Kernel1::debugPrint() { for (int i = 0; i < m_windowSize; i++) { @@ -328,13 +326,18 @@ void Kernel1::debugPrint() -/// Ctor. Kernel2::Kernel2(uint ws) : m_windowSize(ws) { m_data = new float[m_windowSize * m_windowSize]; } -/// Copy ctor. +Kernel2::Kernel2(uint ws, const float * data) : m_windowSize(ws) +{ + m_data = new float[m_windowSize * m_windowSize]; + + memcpy(m_data, data, sizeof(float) * m_windowSize * m_windowSize); +} + Kernel2::Kernel2(const Kernel2 & k) : m_windowSize(k.m_windowSize) { m_data = new float[m_windowSize * m_windowSize]; @@ -344,13 +347,12 @@ Kernel2::Kernel2(const Kernel2 & k) : m_windowSize(k.m_windowSize) } -/// Dtor. Kernel2::~Kernel2() { delete m_data; } -/// Normalize the filter. +// Normalize the filter. void Kernel2::normalize() { float total = 0.0f; @@ -364,7 +366,7 @@ void Kernel2::normalize() } } -/// Transpose the kernel. +// Transpose the kernel. void Kernel2::transpose() { for(uint i = 0; i < m_windowSize; i++) { @@ -374,7 +376,7 @@ void Kernel2::transpose() } } -/// Init laplacian filter, usually used for sharpening. +// Init laplacian filter, usually used for sharpening. void Kernel2::initLaplacian() { nvDebugCheck(m_windowSize == 3); @@ -392,7 +394,7 @@ void Kernel2::initLaplacian() } -/// Init simple edge detection filter. +// Init simple edge detection filter. void Kernel2::initEdgeDetection() { nvCheck(m_windowSize == 3); @@ -401,7 +403,7 @@ void Kernel2::initEdgeDetection() m_data[6] = 0; m_data[7] = 0; m_data[8] = 0; } -/// Init sobel filter. +// Init sobel filter. void Kernel2::initSobel() { if (m_windowSize == 3) @@ -460,7 +462,7 @@ void Kernel2::initSobel() } } -/// Init prewitt filter. +// Init prewitt filter. void Kernel2::initPrewitt() { if (m_windowSize == 3) @@ -486,7 +488,7 @@ void Kernel2::initPrewitt() } } -/// Init blended sobel filter. +// Init blended sobel filter. void Kernel2::initBlendedSobel(const Vector4 & scale) { nvCheck(m_windowSize == 9); @@ -609,7 +611,7 @@ PolyphaseKernel::~PolyphaseKernel() } -/// Print the kernel for debugging purposes. +// Print the kernel for debugging purposes. void PolyphaseKernel::debugPrint() const { for (uint i = 0; i < m_length; i++) diff --git a/src/nvimage/Filter.h b/src/nvimage/Filter.h index bb9ca7d..6ced86b 100644 --- a/src/nvimage/Filter.h +++ b/src/nvimage/Filter.h @@ -166,6 +166,7 @@ namespace nv { public: Kernel2(uint width); + Kernel2(uint width, const float * data); Kernel2(const Kernel2 & k); ~Kernel2(); diff --git a/src/nvimage/FloatImage.cpp b/src/nvimage/FloatImage.cpp index b25c7d6..f61c9e7 100644 --- a/src/nvimage/FloatImage.cpp +++ b/src/nvimage/FloatImage.cpp @@ -943,6 +943,26 @@ FloatImage * FloatImage::resize(const Filter & filter, uint w, uint h, uint d, W } +void FloatImage::convolve(const Kernel2 & k, uint c, WrapMode wm) +{ + AutoPtr tmpImage = clone(); + + uint w = m_width; + uint h = m_height; + uint d = m_depth; + + for (uint z = 0; z < d; z++) + { + for (uint y = 0; y < h; y++) + { + for (uint x = 0; x < w; x++) + { + pixel(c, x, y, 0) = tmpImage->applyKernelXY(&k, x, y, z, c, wm); + } + } + } +} + /// Apply 2D kernel at the given coordinates and return result. float FloatImage::applyKernelXY(const Kernel2 * k, int x, int y, int z, uint c, WrapMode wm) const diff --git a/src/nvimage/FloatImage.h b/src/nvimage/FloatImage.h index 712d1c6..608b440 100644 --- a/src/nvimage/FloatImage.h +++ b/src/nvimage/FloatImage.h @@ -81,6 +81,7 @@ namespace nv NVIMAGE_API FloatImage * resize(const Filter & filter, uint w, uint h, WrapMode wm, uint alpha) const; NVIMAGE_API FloatImage * resize(const Filter & filter, uint w, uint h, uint d, WrapMode wm, uint alpha) const; + NVIMAGE_API void convolve(const Kernel2 & k, uint c, WrapMode wm); //NVIMAGE_API FloatImage * downSample(const Kernel1 & filter, WrapMode wm) const; //NVIMAGE_API FloatImage * downSample(const Kernel1 & filter, uint w, uint h, WrapMode wm) const; diff --git a/src/nvtt/TexImage.cpp b/src/nvtt/TexImage.cpp index b753ef1..884f9c4 100644 --- a/src/nvtt/TexImage.cpp +++ b/src/nvtt/TexImage.cpp @@ -1490,6 +1490,16 @@ void TexImage::abs(int channel) } } +void TexImage::convolve(int channel, int kernelSize, float * kernelData) +{ + if (m->image == NULL) return; + + detach(); + + Kernel2 k(kernelSize, kernelData); + m->image->convolve(k, channel, (FloatImage::WrapMode)m->wrapMode); +} + /* void TexImage::blockLuminanceScale(float scale) { diff --git a/src/nvtt/nvtt.h b/src/nvtt/nvtt.h index ef13771..709bf48 100644 --- a/src/nvtt/nvtt.h +++ b/src/nvtt/nvtt.h @@ -471,6 +471,7 @@ namespace nvtt NVTT_API void toLUVW(float range = 1.0f); NVTT_API void fromLUVW(float range = 1.0f); NVTT_API void abs(int channel); + NVTT_API void convolve(int channel, int kernelSize, float * kernelData); //NVTT_API void blockLuminanceScale(float scale);