Page MenuHome

cubicbspline-1203071506.patch

cubicbspline-1203071506.patch

Index: source/blender/makesrna/intern/rna_nodetree.c
===================================================================
--- source/blender/makesrna/intern/rna_nodetree.c (revision 44721)
+++ source/blender/makesrna/intern/rna_nodetree.c (working copy)
@@ -2732,6 +2732,7 @@
{0, "NEAREST", 0, "Nearest", ""},
{1, "BILINEAR", 0, "Bilinear", ""},
{2, "BICUBIC", 0, "Bicubic", ""},
+ {3, "CUBICBSPLINE", 0, "Cubic B-Spline with Prefilter"},
{0, NULL, 0, NULL, NULL}};
prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE);
@@ -2779,6 +2780,7 @@
{0, "NEAREST", 0, "Nearest", ""},
{1, "BILINEAR", 0, "Bilinear", ""},
{2, "BICUBIC", 0, "Bicubic", ""},
+ {3, "CUBICBSPLINE", 0, "Cubic B-Spline with Prefilter"},
{0, NULL, 0, NULL, NULL}};
prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE);
Index: source/blender/imbuf/intern/imageprocess.c
===================================================================
--- source/blender/imbuf/intern/imageprocess.c (revision 44721)
+++ source/blender/imbuf/intern/imageprocess.c (working copy)
@@ -41,15 +41,14 @@
*/
#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "math.h"
+#include "BLI_utildefines.h"
-/* This define should be relocated to a global header some where Kent Mein
-I stole it from util.h in the plugins api */
-#define MAX2(x,y) ( (x)>(y) ? (x) : (y) )
-
/* Only this one is used liberally here, and in imbuf */
void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
{
@@ -153,11 +152,11 @@
for(n= -1; n<= 2; n++){
x1= i+n;
- if (x1>0 && x1 < in->x) {
+ if (x1>=0 && x1 < in->x) {
wx = P(n-a);
for(m= -1; m<= 2; m++){
y1= j+m;
- if (y1>0 && y1<in->y) {
+ if (y1>=0 && y1<in->y) {
/* normally we could do this */
/* w = P(n-a) * P(b-m); */
/* except that would call P() 16 times per pixel therefor pow() 64 times, better precalc these */
@@ -180,9 +179,9 @@
}
}
}
- }
+ }
-/* Done with optimized part */
+/* Done with optimized part */
#if 0
/* older, slower function, works the same as above */
@@ -190,15 +189,15 @@
for(m= -1; m<= 2; m++){
x1= i+n;
y1= j+m;
- if (x1>0 && x1 < in->x && y1>0 && y1<in->y) {
- if (do_float) {
+ if (x1>=0 && x1 < in->x && y1>=0 && y1<in->y) {
+ if (outF) {
dataF= in->rect_float + in->x * y1 * 4 + 4*x1;
outR+= dataF[0] * P(n-a) * P(b-m);
outG+= dataF[1] * P(n-a) * P(b-m);
outB+= dataF[2] * P(n-a) * P(b-m);
outA+= dataF[3] * P(n-a) * P(b-m);
}
- if (do_rect) {
+ if (outI) {
dataI= (unsigned char*)in->rect + in->x * y1 * 4 + 4*x1;
outR+= dataI[0] * P(n-a) * P(b-m);
outG+= dataI[1] * P(n-a) * P(b-m);
@@ -310,6 +309,114 @@
}
}
+void 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
+ }
+}
+
+
/* function assumes out to be zero'ed, only does RGBA */
/* BILINEAR INTERPOLATION */
Index: source/blender/imbuf/IMB_imbuf.h
===================================================================
--- source/blender/imbuf/IMB_imbuf.h (revision 44721)
+++ source/blender/imbuf/IMB_imbuf.h (working copy)
@@ -404,6 +404,12 @@
*
* \attention defined in imageprocess.c
*/
+
+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 prefilter(struct ImBuf *in, struct ImBuf *out);
+
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Index: source/blender/nodes/composite/nodes/node_composite_transform.c
===================================================================
--- source/blender/nodes/composite/nodes/node_composite_transform.c (revision 44721)
+++ source/blender/nodes/composite/nodes/node_composite_transform.c (working copy)
@@ -51,7 +51,7 @@
CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float angle, float scale, int filter_type)
{
CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1);
- ImBuf *ibuf, *obuf;
+ ImBuf *ibuf = NULL, *obuf = NULL,*fbuf = NULL;
float mat[4][4], lmat[4][4], rmat[4][4], smat[4][4], cmat[4][4], icmat[4][4];
float svec[3]= {scale, scale, scale}, loc[2]= {x, y};
@@ -59,7 +59,7 @@
unit_m4(lmat);
unit_m4(smat);
unit_m4(cmat);
-
+
/* image center as rotation center */
cmat[3][0]= (float)cbuf->x/2.0f;
cmat[3][1]= (float)cbuf->y/2.0f;
@@ -73,16 +73,24 @@
mul_serie_m4(mat, lmat, cmat, rmat, smat, icmat, NULL, NULL, NULL);
invert_m4(mat);
-
+
ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
obuf= IMB_allocImBuf(stackbuf->x, stackbuf->y, 32, 0);
- if(ibuf && obuf) {
+ if (ibuf && obuf) {
+ ibuf->rect_float= cbuf->rect;
+ obuf->rect_float= stackbuf->rect;
+
+ if (filter_type == 3) {
+ fbuf = IMB_allocImBuf(cbuf->x, cbuf->y, 32, IB_rectfloat);
+ if (fbuf)
+ prefilter(ibuf, fbuf);
+ }
+ }
+
+ if(ibuf && obuf && (fbuf || (filter_type != 3)) ) {
int i, j;
- ibuf->rect_float= cbuf->rect;
- obuf->rect_float= stackbuf->rect;
-
for(j=0; j<cbuf->y; j++) {
for(i=0; i<cbuf->x;i++) {
float vec[3]= {i, j, 0};
@@ -99,10 +107,15 @@
case 2:
bicubic_interpolation(ibuf, obuf, vec[0], vec[1], i, j);
break;
+ case 3:
+ bicubic_interpolation(fbuf, obuf, vec[0], vec[1], i, j);
+ break;
}
}
}
-
+
+ if (fbuf)
+ IMB_freeImBuf(fbuf);
IMB_freeImBuf(ibuf);
IMB_freeImBuf(obuf);
}

File Metadata

Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
55/79/dd4bd9b988cfe488b6617bcaca42

Event Timeline