Page Menu
Home
Search
Configure Global Search
Log In
Files
F19169
cubicbspline20121004.patch
Public
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Authored By
Troy Sobotka (sobotka)
Nov 13 2013, 4:14 PM
Size
11 KB
Subscribers
None
cubicbspline20121004.patch
View Options
Index: source/blender/compositor/intern/COM_SocketReader.h
===================================================================
--- source/blender/compositor/intern/COM_SocketReader.h (revision 51011)
+++ source/blender/compositor/intern/COM_SocketReader.h (working copy)
@@ -32,7 +32,8 @@
typedef enum PixelSampler {
COM_PS_NEAREST = 0,
COM_PS_BILINEAR = 1,
- COM_PS_BICUBIC = 2
+ COM_PS_BICUBIC = 2,
+ COM_PS_CUBICBSPLINEPREFILTER = 3
} PixelSampler;
class MemoryBuffer;
Index: source/blender/compositor/operations/COM_ImageOperation.h
===================================================================
--- source/blender/compositor/operations/COM_ImageOperation.h (revision 51011)
+++ source/blender/compositor/operations/COM_ImageOperation.h (working copy)
@@ -40,6 +40,7 @@
class BaseImageOperation : public NodeOperation {
protected:
ImBuf *m_buffer;
+ ImBuf *m_secondaryBuffer;
Image *m_image;
ImageUser *m_imageUser;
float *m_imageBuffer;
@@ -65,14 +66,17 @@
void setImageUser(ImageUser *imageuser) { this->m_imageUser = imageuser; }
void setFramenumber(int framenumber) { this->m_framenumber = framenumber; }
+
+ void initSecondaryBuffer(int buffer_type);
};
class ImageOperation : public BaseImageOperation {
+protected:
public:
/**
* Constructor
*/
ImageOperation();
- void executePixel(float output[4], float x, float y, PixelSampler sampler);
+ void executePixel(float output[4], float x, float y, PixelSampler sampler);
};
class ImageAlphaOperation : public BaseImageOperation {
public:
Index: source/blender/compositor/operations/COM_MultilayerImageOperation.cpp
===================================================================
--- source/blender/compositor/operations/COM_MultilayerImageOperation.cpp (revision 51011)
+++ source/blender/compositor/operations/COM_MultilayerImageOperation.cpp (working copy)
@@ -62,6 +62,13 @@
case COM_PS_BICUBIC:
bicubic_interpolation_color(this->m_buffer, NULL, output, x, y);
break;
+ case COM_PS_CUBICBSPLINEPREFILTER:
+ lockMutex();
+ if (this->m_secondaryBuffer == NULL) {
+ BaseImageOperation::initSecondaryBuffer(BT_CUBICBSPLINEPREFILTER);
+ }
+ unlockMutex();
+ bicubic_interpolation_color(this->m_secondaryBuffer, NULL, output, x, y);
}
}
else {
Index: source/blender/compositor/operations/COM_ImageOperation.cpp
===================================================================
--- source/blender/compositor/operations/COM_ImageOperation.cpp (revision 51011)
+++ source/blender/compositor/operations/COM_ImageOperation.cpp (working copy)
@@ -40,6 +40,7 @@
{
this->m_image = NULL;
this->m_buffer = NULL;
+ this->m_secondaryBuffer = NULL;
this->m_imageBuffer = NULL;
this->m_imageUser = NULL;
this->m_imagewidth = 0;
@@ -80,6 +81,7 @@
void BaseImageOperation::initExecution()
{
ImBuf *stackbuf = getImBuf();
+ this->initMutex();
this->m_buffer = stackbuf;
if (stackbuf) {
this->m_imageBuffer = stackbuf->rect_float;
@@ -92,7 +94,12 @@
void BaseImageOperation::deinitExecution()
{
+ this->deinitMutex();
this->m_imageBuffer = NULL;
+ if (this->m_secondaryBuffer) {
+ IMB_freeImBuf(m_secondaryBuffer);
+ m_secondaryBuffer = NULL;
+ }
}
void BaseImageOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
@@ -108,6 +115,20 @@
}
}
+/* Must be located in BaseImageOperation to avoid code duplication */
+void BaseImageOperation::initSecondaryBuffer(int buffer_type)
+{
+ switch (buffer_type) {
+ case BT_DUPLICATE:
+ this->m_secondaryBuffer = IMB_dupImBuf(this->m_buffer);
+ break;
+ case BT_CUBICBSPLINEPREFILTER:
+ this->m_secondaryBuffer = IMB_dupImBuf(this->m_buffer);
+ create_prefilter(this->m_buffer, this->m_secondaryBuffer);
+ break;
+ }
+}
+
void ImageOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
{
if (this->m_imageBuffer == NULL || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) {
@@ -124,6 +145,13 @@
case COM_PS_BICUBIC:
bicubic_interpolation_color(this->m_buffer, NULL, output, x, y);
break;
+ case COM_PS_CUBICBSPLINEPREFILTER:
+ lockMutex();
+ if (this->m_secondaryBuffer == NULL) {
+ BaseImageOperation::initSecondaryBuffer(BT_CUBICBSPLINEPREFILTER);
+ }
+ unlockMutex();
+ bicubic_interpolation_color(this->m_secondaryBuffer, NULL, output, x, y);
}
}
}
@@ -147,6 +175,13 @@
case COM_PS_BICUBIC:
bicubic_interpolation_color(this->m_buffer, NULL, tempcolor, x, y);
break;
+ case COM_PS_CUBICBSPLINEPREFILTER:
+ lockMutex();
+ if (this->m_secondaryBuffer == NULL) {
+ BaseImageOperation::initSecondaryBuffer(BT_CUBICBSPLINEPREFILTER);
+ }
+ unlockMutex();
+ bicubic_interpolation_color(this->m_secondaryBuffer, NULL, output, x, y);
}
output[0] = tempcolor[3];
}
Index: source/blender/makesrna/intern/rna_nodetree.c
===================================================================
--- source/blender/makesrna/intern/rna_nodetree.c (revision 51011)
+++ source/blender/makesrna/intern/rna_nodetree.c (working copy)
@@ -137,6 +137,7 @@
{0, "NEAREST", 0, "Nearest", ""},
{1, "BILINEAR", 0, "Bilinear", ""},
{2, "BICUBIC", 0, "Bicubic", ""},
+ {3, "CUBICBSPLINEPREFILTER", 0, "Cubic B Spline with Prefilter", ""},
{0, NULL, 0, NULL, NULL}
};
Index: source/blender/imbuf/intern/imageprocess.c
===================================================================
--- source/blender/imbuf/intern/imageprocess.c (revision 51011)
+++ source/blender/imbuf/intern/imageprocess.c (working copy)
@@ -47,6 +47,7 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include <math.h>
+#include <string.h>
/* Only this one is used liberally here, and in imbuf */
void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
@@ -461,6 +462,117 @@
neareast_interpolation_color(in, outI, outF, x, y);
}
+/*********************** CubicBSpline Prefilter ****************************/
+/* This function creates a prefilter in the frequency domain. It can be
+ viewed as a compliment to a traditional bicubic filter. */
+
+void create_prefilter(ImBuf *in, ImBuf *out)
+{
+ int x, y;
+
+ // A row of float coefficients.
+ float *coeff = out->rect_float;
+
+ if (in == NULL || in->rect_float == NULL || out == NULL ||
+ out->rect_float == NULL || in->x <= 2 || in->y <=2)
+ return;
+
+ // Initialize
+ memcpy(coeff, in->rect_float, in->x * in->y * 4 * sizeof(float));
+
+ // X Recursion
+ for(y = 0; y < in->y; y++)
+ prefilter_doRecursion(&coeff[y * in->x * 4], in->x, 4);
+ // Y Recursion
+ for(x = 0; x < in->x; x++)
+ prefilter_doRecursion(&coeff[x * 4], in->y, in->x * 4);
+
+ // Copy to the out ImBuf.
+ memcpy(out->rect_float, coeff, (in->x * in->y * 4 * sizeof(float)));
+}
+
+// Get the initial causual coefficient for a given run of floats at stride count
+// of floats.
+void prefilter_initInitialCausal(float *coeffIn, float *sum, unsigned int length, unsigned int stride)
+{
+ const float Zp = sqrt(3.0f)-2.0f;
+ const float lambda = (1.0f - Zp) * (1.0f - 1.0f / Zp);
+ unsigned int count = 0, horizon = MIN2(12, length) * 4;
+ float Zn = Zp;
+
+ sum[0] = coeffIn[0]; // R
+ sum[1] = coeffIn[1]; // G
+ sum[2] = coeffIn[2]; // B
+ sum[3] = coeffIn[3]; // A
+
+ for (count = 0; count < horizon; count += stride) {
+ sum[0] += Zn * coeffIn[count]; // R
+ sum[1] += Zn * coeffIn[count+1]; // G
+ sum[2] += Zn * coeffIn[count+2]; // B
+ sum[3] += Zn * coeffIn[count+3]; // A
+
+ Zn *= Zp;
+ }
+
+ coeffIn[0] = (lambda * sum[0]); // R
+ coeffIn[1] = (lambda * sum[1]); // G
+ coeffIn[2] = (lambda * sum[2]); // B
+ coeffIn[3] = (lambda * sum[3]); // A
+}
+
+// Set the initial anti-causual coefficient at the end of the given run of
+// floats at stride count of floats.
+void prefilter_initInitialAntiCausal(float *coeffIn)
+{
+ const float Zp = sqrt(3.0f)-2.0f;
+ const float iZp = (Zp / (Zp - 1.0f));
+
+ coeffIn[0] = iZp * coeffIn[0]; //R
+ coeffIn[1] = iZp * coeffIn[1]; //G
+ coeffIn[2] = iZp * coeffIn[2]; //B
+ coeffIn[3] = iZp * coeffIn[3]; //A
+}
+
+
+void prefilter_doRecursion(float *coeffIn, unsigned int length, unsigned int stride)
+{
+ const float Zp = sqrt(3.0f)-2.0f;
+ const float lambda = (1.0f - Zp) * (1.0f - 1.0f / Zp);
+ float prevcoeff[4] = { 0, 0, 0, 0 };
+ float sum[4] = { 0, 0, 0, 0 };
+ int count = 0;
+ unsigned int total_floats = length * 4;
+
+ prefilter_initInitialCausal(coeffIn, sum, length, 4);
+
+ prevcoeff[0] = coeffIn[0]; // R
+ prevcoeff[1] = coeffIn[1]; // G
+ prevcoeff[2] = coeffIn[2]; // B
+ prevcoeff[3] = coeffIn[3]; // A
+
+ for (count = (1 * stride); count < total_floats; count += stride) {
+ coeffIn[count] = prevcoeff[0] = (lambda * coeffIn[count]) + (Zp * prevcoeff[0]); // R
+ coeffIn[count + 1] = prevcoeff[1] = (lambda * coeffIn[count + 1]) + (Zp * prevcoeff[1]); // G
+ coeffIn[count + 2] = prevcoeff[2] = (lambda * coeffIn[count + 2]) + (Zp * prevcoeff[2]); // B
+ coeffIn[count + 3] = prevcoeff[3] = (lambda * coeffIn[count + 3]) + (Zp * prevcoeff[3]); // A
+ }
+
+ count -= stride;
+ prefilter_initInitialAntiCausal(&coeffIn[count]);
+
+ prevcoeff[0] = coeffIn[count]; // R
+ prevcoeff[1] = coeffIn[count + 1]; // G
+ prevcoeff[2] = coeffIn[count + 2]; // B
+ prevcoeff[3] = coeffIn[count + 3]; // A
+
+ for (count -= stride; count >= 0; count -= stride) {
+ coeffIn[count] = prevcoeff[0] = Zp * (prevcoeff[0] - coeffIn[count]); // R
+ coeffIn[count + 1] = prevcoeff[1] = Zp * (prevcoeff[1] - coeffIn[count + 1]); // G
+ coeffIn[count + 2] = prevcoeff[2] = Zp * (prevcoeff[2] - coeffIn[count + 2]); // B
+ coeffIn[count + 3] = prevcoeff[3] = Zp * (prevcoeff[3] - coeffIn[count + 3]); // A
+ }
+}
+
/*********************** Threaded image processing *************************/
void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_customdata,
Index: source/blender/imbuf/IMB_imbuf.h
===================================================================
--- source/blender/imbuf/IMB_imbuf.h (revision 51011)
+++ source/blender/imbuf/IMB_imbuf.h (working copy)
@@ -416,6 +416,20 @@
void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
/**
+ * Establish the prefilter algorithm at lowest level to be adopted
+ * by other areas of Blender such as MIPmaps.
+ */
+
+/* Buffer Types */
+#define BT_DUPLICATE 0
+#define BT_CUBICBSPLINEPREFILTER 1
+
+void prefilter_initInitialCausal(float *coeffIn, float *sum, unsigned int length, unsigned int stride);
+void prefilter_initInitialAntiCausal(float *coeffIn);
+void prefilter_doRecursion(float *coeffIn, unsigned int length, unsigned int stride);
+void create_prefilter(struct ImBuf *in, struct ImBuf *out);
+
+/**
*
* \attention defined in readimage.c
*/
File Metadata
Details
Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
13/57/464e58a5d76ac1aa02ddc4ef3116
Event Timeline
Log In to Comment