Page Menu
Home
Search
Configure Global Search
Log In
Files
F19161
cubicbspline1203011902.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
10 KB
Subscribers
None
cubicbspline1203011902.patch
View Options
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,13 @@
*/
#include <stdlib.h>
+#include <stdio.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 +308,152 @@
}
}
+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;
+
+ // Initialize our coefficients to our image base.
+ //for (y = 0; y < h; y++)
+ // for (x = 0; x < w; x++)
+ // Initialize with alpha (sizeRGBA), despite it not being used.
+ // for (curRGB = 0; curRGB < sizeRGBA; curRGB++)
+ // coeff[(y * w * sizeRGBA) + (x * sizeRGBA) + curRGB] =
+ // in->rect_float[(y * w * sizeRGBA) + (x * sizeRGBA) + curRGB];
+
+ // Iterate along x.
+ for (y = 0; y < h; y++) {
+ // Initialize the sum to the coefficient at the first pixel on our row.
+ 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 row.
+ 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 row. 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 row.
+ 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 row. n = w - 2 skips our
+ // last coefficient above.
+ for (y = h - 2; y >= 0; y--)
+ for (curRGB = 0; curRGB < sizeRGB; curRGB++)
+ coeff[(x * sizeRGBA) + (h * y * sizeRGBA) + curRGB] =
+ prevcoeff[curRGB] = Zp * (prevcoeff[curRGB] -
+ coeff[(x * sizeRGBA) + (h * y * sizeRGBA) + curRGB]);
+ }
+
+ // Copy to the out ImBuf.
+ for (y = 0; y < h; y++)
+ for (x = 0; x < w; x++)
+ // Copy with alpha (sizeRGBA).
+ for (curRGB = 0; curRGB < sizeRGBA; curRGB++)
+ out->rect_float[(y * w * sizeRGBA) + (x * sizeRGBA) + curRGB] =
+ coeff[(y * w * sizeRGBA) + (x * sizeRGBA) + curRGB];
+}
+
/* 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,25 @@
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) && ibuf && obuf) {
+ 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,13 +108,19 @@
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;
}
}
}
-
+
IMB_freeImBuf(ibuf);
IMB_freeImBuf(obuf);
}
+
+ if (fbuf)
+ IMB_freeImBuf(fbuf);
/* pass on output and free */
return stackbuf;
File Metadata
Details
Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
52/e3/08b44f551843d9171929e1f6b18d
Event Timeline
Log In to Comment