Page MenuHome

cubicbspline-1203041138.patch

cubicbspline-1203041138.patch

Index: source/blender/makesrna/intern/rna_nodetree.c
===================================================================
--- source/blender/makesrna/intern/rna_nodetree.c (revision 44566)
+++ source/blender/makesrna/intern/rna_nodetree.c (working copy)
@@ -2783,6 +2783,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);
@@ -2830,6 +2831,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 44566)
+++ 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)
{
@@ -310,6 +309,141 @@
}
}
+void prefilter(ImBuf *in, ImBuf *out, unsigned int w, unsigned int h)
+{
+ // Pole of Z-Transform for Cubic Spline.
+ const float Zp = sqrt(3.0f)-2.0f;
+ // AntiPole
+ const float iZp = Zp / (Zp - 1.0f);
+ // Gain to normalize coefficients.
+ const float lambda = (1.0f - Zp) * (1.0f - (1.0f / Zp));
+ // Horizon value of 12 or width, whatever is smaller.
+ const unsigned int horzx = MIN2(12,w);
+ // Horizon value of 12 or height, whatever is smaller.
+ const unsigned int horzy = MIN2(12,h);
+ // Count of floats in an RGBA quad for code legibility.
+ const int sizeRGBA = 4;
+ // Count of floats in an RGB triplet for code legibility.
+ const int sizeRGB = 3;
+ // Count of image pixels.
+ const int sizeImage = w * h * sizeRGBA;
+ // Storage for Zp^x.
+ float Zn = 0;
+ // Storage for the step factor for iteration.
+ int step = 0;
+ // A sum storage triplet (TODO: Consider alpha?).
+ float sum[3] = { 0, 0, 0 };
+ // A previous coefficient storage triplet (TODO: Consider alpha?).
+ float prevcoeff[3] = { 0, 0, 0 };
+
+ float* curcoeff = NULL;
+
+ int curRGB, x, y, n;
+ // A row of float coefficients.
+ float *coeff = out->rect_float;
+
+ if (in == NULL || in->rect_float == NULL || out == NULL ||
+ out->rect_float == NULL || w <= 2 || h <=2)
+ return;
+
+ // Iterate along x.
+ for (y = 0; y < h; y++) {
+ // Initialize the sum to the coefficient at the first pixel on our row.
+ memcpy(sum, &coeff[(y * w * sizeRGBA)], sizeRGBA * sizeof(float));
+ //for (curRGB = 0; curRGB < sizeRGB; curRGB++)
+ // sum[curRGB] = coeff[(y * w * sizeRGBA) + curRGB];
+
+ Zn = Zp;
+
+ // Generate the initial causal.
+ for (n = 0; n < horzx; n++){
+ curcoeff = &coeff[(y * w * sizeRGBA) + (n * sizeRGBA)];
+
+ for (curRGB = 0; curRGB < sizeRGB; curRGB++)
+ sum[curRGB] += Zn * curcoeff[curRGB];
+
+ Zn *= Zp;
+ }
+
+ // Set the initial RGB causal coefficients at the first pixel position.
+ for (curRGB = 0; curRGB < sizeRGB; curRGB++)
+ coeff[(y * w * sizeRGBA) + curRGB] = prevcoeff[curRGB] = lambda * sum[curRGB];
+
+ // Perform the causal recursion along each row. n = 1 skips our
+ // first coefficient above.
+ for (x = 1; x < w; x++)
+ for (curRGB = 0; curRGB < sizeRGB; curRGB++)
+ coeff[(y * w * sizeRGBA) + (x * sizeRGBA) + curRGB] =
+ prevcoeff[curRGB] =
+ (lambda * coeff[(y * w * sizeRGBA) + (x * sizeRGBA) + curRGB]) +
+ (Zp * prevcoeff[curRGB]);
+
+ // Generate the initial anti-causal at the last pixel per row.
+ for (curRGB = 0; curRGB < sizeRGB; curRGB++)
+ coeff[(y * w * sizeRGBA) + ((w - 1) * sizeRGBA) + curRGB] =
+ prevcoeff[curRGB] =
+ iZp * coeff[(y * w * sizeRGBA) + ((w - 1) * sizeRGBA) + curRGB];
+
+ // Perform anti-causal recursion along each row. n = w - 2 skips our
+ // last coefficient above.
+ for (x = w - 2; x >= 0; x--)
+ for (curRGB = 0; curRGB < sizeRGB; curRGB++)
+ coeff[(y * w * sizeRGBA) + (x * sizeRGBA) + curRGB] =
+ prevcoeff[curRGB] = Zp * (prevcoeff[curRGB] -
+ coeff[(y * w * sizeRGBA) + (x * sizeRGBA) + curRGB]);
+ }
+
+ // Iterate along y.
+ for (x = 0; x < w; x++) {
+ // Initialize the sum to the coefficient at the first pixel on our column.
+ memcpy(sum, &coeff[(x * sizeRGBA)], sizeRGBA * sizeof(float));
+ //for (curRGB = 0; curRGB < sizeRGB; curRGB++)
+ // sum[curRGB] = coeff[(x * sizeRGBA) + curRGB];
+
+ Zn = Zp;
+
+ // Generate the initial causal.
+ for (n = 0; n < horzy; n++){
+ curcoeff = &coeff[(x * sizeRGBA) + (n * w * sizeRGBA)];
+
+ for (curRGB = 0; curRGB < sizeRGB; curRGB++)
+ sum[curRGB] += Zn * curcoeff[curRGB];
+
+ Zn *= Zp;
+ }
+
+ // Set the initial RGB causal coefficients at the first pixel position.
+ for (curRGB = 0; curRGB < sizeRGB; curRGB++)
+ coeff[(x * sizeRGBA) + curRGB] = prevcoeff[curRGB] = lambda * sum[curRGB];
+
+ // Perform the causal recursion along each column. n = 1 skips our
+ // first coefficient above.
+ for (y = 1; y < h; y++)
+ for (curRGB = 0; curRGB < sizeRGB; curRGB++)
+ coeff[(x * sizeRGBA) + (y * w * sizeRGBA) + curRGB] =
+ prevcoeff[curRGB] =
+ (lambda * coeff[(x * sizeRGBA) + (y * w * sizeRGBA) + curRGB]) +
+ (Zp * prevcoeff[curRGB]);
+
+ // Generate the initial anti-causal at the last pixel per column.
+ for (curRGB = 0; curRGB < sizeRGB; curRGB++)
+ coeff[(x * sizeRGBA) + ((h - 1) * w * sizeRGBA) + curRGB] =
+ prevcoeff[curRGB] =
+ iZp * coeff[(x * sizeRGBA) + ((h - 1) * w * sizeRGBA) + curRGB];
+
+ // Perform anti-causal recursion along each column. n = w - 2 skips our
+ // last coefficient above.
+ for (y = h - 2; y >= 0; y--)
+ for (curRGB = 0; curRGB < sizeRGB; curRGB++)
+ coeff[(x * sizeRGBA) + (y * w * sizeRGBA) + curRGB] =
+ prevcoeff[curRGB] = Zp * (prevcoeff[curRGB] -
+ coeff[(x * sizeRGBA) + (y * w * sizeRGBA) + curRGB]);
+ }
+
+ // Copy to the out ImBuf.
+ memcpy(out->rect_float, coeff, (w * h * sizeRGB * sizeof(float)));
+}
+
/* 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 44566)
+++ source/blender/imbuf/IMB_imbuf.h (working copy)
@@ -405,6 +405,9 @@
*
* @attention defined in imageprocess.c
*/
+
+void prefilter(struct ImBuf *in, struct ImBuf *out, unsigned int w, unsigned int h);
+
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 44566)
+++ 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_dupImBuf(ibuf);
+ if (fbuf->rect_float)
+ prefilter(ibuf, fbuf, cbuf->x, cbuf->y);
+ }
+ }
+
+ 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
0d/fa/67db964ec94b8a050e31a3badee5

Event Timeline