Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Holcomb <bob_holcomb@hotmail.com>2009-09-10 08:12:22 +0400
committerRobert Holcomb <bob_holcomb@hotmail.com>2009-09-10 08:12:22 +0400
commitfa4ee2be849b6236d61e482106ed9e20f20f21de (patch)
tree9c1980eb115d6982da2b321f15b06f4c38dea62c /source/blender/nodes
parentdac27004b863da96c57b071fc0479680e06a9725 (diff)
Added Levels Node (histogram, with mean/std deviation outputs)
Added RGB space distance matte Node Added HSV color matte Node Fixed Image difference matte Node to use image differences instead of RGB space distance Fixed luminance node for low end values being read wrong Fixed CMP_util copy/swap functions not accounting for all channels Fixed UI for difference matte Node Added RNA for new nodes
Diffstat (limited to 'source/blender/nodes')
-rw-r--r--source/blender/nodes/CMP_node.h7
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c4
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c4
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c132
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c174
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c145
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_levels.c337
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c2
-rw-r--r--source/blender/nodes/intern/CMP_util.c26
-rw-r--r--source/blender/nodes/intern/CMP_util.h5
10 files changed, 701 insertions, 135 deletions
diff --git a/source/blender/nodes/CMP_node.h b/source/blender/nodes/CMP_node.h
index 020bbdebfa2..041bf1c8361 100644
--- a/source/blender/nodes/CMP_node.h
+++ b/source/blender/nodes/CMP_node.h
@@ -25,7 +25,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Bob Holcomb.
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -49,6 +49,7 @@ extern bNodeType cmp_node_composite;
extern bNodeType cmp_node_viewer;
extern bNodeType cmp_node_splitviewer;
extern bNodeType cmp_node_output_file;
+extern bNodeType cmp_node_view_levels;
extern bNodeType cmp_node_curve_rgb;
extern bNodeType cmp_node_mix_rgb;
@@ -88,7 +89,9 @@ extern bNodeType cmp_node_combycca;
extern bNodeType cmp_node_premulkey;
extern bNodeType cmp_node_diff_matte;
-extern bNodeType cmp_node_chroma;
+extern bNodeType cmp_node_distance_matte;
+extern bNodeType cmp_node_chroma_matte;
+extern bNodeType cmp_node_color_matte;
extern bNodeType cmp_node_channel_matte;
extern bNodeType cmp_node_color_spill;
extern bNodeType cmp_node_luma_matte;
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c
index d0cc4e5b88d..b0a2531ac1f 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c
@@ -22,7 +22,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Bob Holcomb
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -180,7 +180,7 @@ static void node_composit_init_channel_matte(bNode *node)
{
NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma");
node->storage=c;
- c->t1= 0.0f;
+ c->t1= 1.0f;
c->t2= 0.0f;
c->t3= 0.0f;
c->fsize= 0.0f;
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c
index 6a40018e659..28b81fe9f47 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c
@@ -172,9 +172,9 @@ static void node_composit_init_chroma_matte(bNode *node)
c->fstrength= 1.0f;
};
-bNodeType cmp_node_chroma={
+bNodeType cmp_node_chroma_matte={
/* *next,*prev */ NULL, NULL,
- /* type code */ CMP_NODE_CHROMA,
+ /* type code */ CMP_NODE_CHROMA_MATTE,
/* name */ "Chroma Key",
/* width+range */ 200, 80, 300,
/* class+opts */ NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS,
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c
new file mode 100644
index 00000000000..0a4d3fceff9
--- /dev/null
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c
@@ -0,0 +1,132 @@
+/**
+ * $Id: CMP_colorMatte.c 12931 2007-12-17 18:20:48Z theeth $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Bob Holcomb
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../CMP_util.h"
+
+/* ******************* Color Key ********************************************************** */
+static bNodeSocketType cmp_node_color_in[]={
+ {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ {SOCK_RGBA,1,"Key Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ {-1,0,""}
+};
+
+static bNodeSocketType cmp_node_color_out[]={
+ {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ {SOCK_VALUE,0,"Matte",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ {-1,0,""}
+};
+
+static void do_color_key(bNode *node, float *out, float *in)
+{
+ NodeChroma *c;
+ c=node->storage;
+
+
+ VECCOPY(out, in);
+
+ if(fabs(in[0]-c->key[0]) < c->t1 &&
+ fabs(in[1]-c->key[1]) < c->t2 &&
+ fabs(in[2]-c->key[2]) < c->t3)
+ {
+ out[3]=0.0; /*make transparent*/
+ }
+
+ else { /*pixel is outside key color */
+ out[3]=in[3]; /* make pixel just as transparent as it was before */
+ }
+}
+
+static void node_composit_exec_color_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ CompBuf *cbuf;
+ CompBuf *colorbuf;
+ NodeChroma *c;
+
+ if(in[0]->hasinput==0) return;
+ if(in[0]->data==NULL) return;
+ if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
+
+ cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
+
+ colorbuf= dupalloc_compbuf(cbuf);
+
+ c=node->storage;
+
+ /*convert rgbbuf to hsv*/
+ composit1_pixel_processor(node, colorbuf, cbuf, in[0]->vec, do_rgba_to_hsva, CB_RGBA);
+
+ /*convert key to hsv*/
+ do_rgba_to_hsva(node, c->key, in[1]->vec);
+
+
+ /*per pixel color key*/
+ composit1_pixel_processor(node, colorbuf, colorbuf, in[0]->vec, do_color_key, CB_RGBA);
+
+ /*convert back*/
+ composit1_pixel_processor(node, colorbuf, colorbuf, in[0]->vec, do_hsva_to_rgba, CB_RGBA);
+
+ out[0]->data= colorbuf;
+ if(out[1]->hasoutput)
+ out[1]->data= valbuf_from_rgbabuf(colorbuf, CHAN_A);
+
+ generate_preview(node, colorbuf);
+
+ if(cbuf!=in[0]->data)
+ free_compbuf(cbuf);
+};
+
+static void node_composit_init_color_matte(bNode *node)
+{
+ NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node color");
+ node->storage= c;
+ c->t1= 0.01f;
+ c->t2= 0.1f;
+ c->t3= 0.1f;
+ c->fsize= 0.0f;
+ c->fstrength= 1.0f;
+};
+
+bNodeType cmp_node_color_matte={
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ CMP_NODE_COLOR_MATTE,
+ /* name */ "Color Key",
+ /* width+range */ 200, 80, 300,
+ /* class+opts */ NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS,
+ /* input sock */ cmp_node_color_in,
+ /* output sock */ cmp_node_color_out,
+ /* storage */ "NodeChroma",
+ /* execfunc */ node_composit_exec_color_matte,
+ /* butfunc */ NULL,
+ /* initfunc */ node_composit_init_color_matte,
+ /* freestoragefunc */ node_free_standard_storage,
+ /* copystoragefunc */ node_copy_standard_storage,
+ /* id */ NULL
+};
+
+
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c
index ade2111f246..68a1bcd5471 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c
@@ -22,7 +22,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Bob Holcomb
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -31,8 +31,8 @@
/* ******************* channel Difference Matte ********************************* */
static bNodeSocketType cmp_node_diff_matte_in[]={
- {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- {SOCK_RGBA,1,"Key Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ {SOCK_RGBA,1,"Image 1", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ {SOCK_RGBA,1,"Image 2", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
{-1,0,""}
};
@@ -44,157 +44,85 @@ static bNodeSocketType cmp_node_diff_matte_out[]={
/* note, keyvals is passed on from caller as stack array */
/* might have been nicer as temp struct though... */
-static void do_diff_matte(bNode *node, float *colorbuf, float *inbuf, float *keyvals)
+static void do_diff_matte(bNode *node, float *colorbuf, float *imbuf1, float *imbuf2)
{
NodeChroma *c= (NodeChroma *)node->storage;
- float *keymin= keyvals;
- float *keymax= keyvals+3;
- float *key= keyvals+6;
- float tolerance= keyvals[9];
- float distance, alpha;
+ float tolerence=c->t1;
+ float falloff=c->t2;
+ float difference;
+ float alpha;
- /*process the pixel if it is close to the key or already transparent*/
- if(((colorbuf[0]>keymin[0] && colorbuf[0]<keymax[0]) &&
- (colorbuf[1]>keymin[1] && colorbuf[1]<keymax[1]) &&
- (colorbuf[2]>keymin[2] && colorbuf[2]<keymax[2])) || inbuf[3]<1.0f) {
-
- /*true distance from key*/
- distance= sqrt((colorbuf[0]-key[0])*(colorbuf[0]-key[0])+
- (colorbuf[1]-key[1])*(colorbuf[1]-key[1])+
- (colorbuf[2]-key[2])*(colorbuf[2]-key[2]));
-
- /*is it less transparent than the prevous pixel*/
- alpha= distance/tolerance;
- if(alpha > inbuf[3]) alpha= inbuf[3];
- if(alpha > c->fstrength) alpha= 0.0f;
-
- /*clamp*/
- if (alpha>1.0f) alpha=1.0f;
- if (alpha<0.0f) alpha=0.0f;
-
- /*premultiplied picture*/
- colorbuf[3]= alpha;
+ difference=fabs(imbuf2[0]-imbuf1[0])+
+ fabs(imbuf2[1]-imbuf1[1])+
+ fabs(imbuf2[2]-imbuf1[2]);
+
+ /*average together the distances*/
+ difference=difference/3.0;
+
+ VECCOPY(colorbuf, imbuf1);
+
+ /*make 100% transparent*/
+ if(difference < tolerence){
+ colorbuf[3]=0.0;
}
+ /*in the falloff region, make partially transparent */
+ else if(difference < falloff+tolerence){
+ difference=difference-tolerence;
+ alpha=difference/falloff;
+ /*only change if more transparent than before */
+ if(alpha < imbuf1[3]) {
+ colorbuf[3]=alpha;
+ }
+ else { /* leave as before */
+ colorbuf[3]=imbuf1[3];
+ }
+ }
else {
/*foreground object*/
- colorbuf[3]= inbuf[3];
+ colorbuf[3]= imbuf1[3];
}
}
static void node_composit_exec_diff_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
- /*
- Losely based on the Sequencer chroma key plug-in, but enhanced to work in other color spaces and
- uses a differnt difference function (suggested in forums of vfxtalk.com).
- */
- CompBuf *workbuf;
- CompBuf *inbuf;
+ CompBuf *outbuf;
+ CompBuf *imbuf1;
+ CompBuf *imbuf2;
NodeChroma *c;
- float keyvals[10];
- float *keymin= keyvals;
- float *keymax= keyvals+3;
- float *key= keyvals+6;
- float *tolerance= keyvals+9;
- float t[3];
/*is anything connected?*/
if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
/*must have an image imput*/
if(in[0]->data==NULL) return;
+ if(in[1]->data==NULL) return;
- inbuf=typecheck_compbuf(in[0]->data, CB_RGBA);
+ imbuf1=typecheck_compbuf(in[0]->data, CB_RGBA);
+ imbuf2=typecheck_compbuf(in[1]->data, CB_RGBA);
c=node->storage;
- workbuf=dupalloc_compbuf(inbuf);
-
- /*use the input color*/
- key[0]= in[1]->vec[0];
- key[1]= in[1]->vec[1];
- key[2]= in[1]->vec[2];
-
- /*get the tolerances from the UI*/
- t[0]=c->t1;
- t[1]=c->t2;
- t[2]=c->t3;
-
- /*convert to colorspace*/
- switch(node->custom1) {
- case 1: /*RGB*/
- break;
- case 2: /*HSV*/
- /*convert the key (in place)*/
- rgb_to_hsv(key[0], key[1], key[2], &key[0], &key[1], &key[2]);
- composit1_pixel_processor(node, workbuf, inbuf, in[1]->vec, do_rgba_to_hsva, CB_RGBA);
- break;
- case 3: /*YUV*/
- rgb_to_yuv(key[0], key[1], key[2], &key[0], &key[1], &key[2]);
- composit1_pixel_processor(node, workbuf, inbuf, in[1]->vec, do_rgba_to_yuva, CB_RGBA);
- break;
- case 4: /*YCC*/
- rgb_to_ycc(key[0], key[1], key[2], &key[0], &key[1], &key[2]);
- composit1_pixel_processor(node, workbuf, inbuf, in[1]->vec, do_rgba_to_ycca, CB_RGBA);
- /*account for ycc is on a 0..255 scale*/
- t[0]= c->t1*255.0;
- t[1]= c->t2*255.0;
- t[2]= c->t3*255.0;
- break;
- default:
- break;
- }
-
- /*find min/max tolerances*/
- keymin[0]= key[0]-t[0];
- keymin[1]= key[1]-t[1];
- keymin[2]= key[2]-t[2];
- keymax[0]= key[0]+t[0];
- keymax[1]= key[1]+t[1];
- keymax[2]= key[2]+t[2];
-
- /*tolerance*/
- *tolerance= sqrt((t[0])*(t[0])+
- (t[1])*(t[1])+
- (t[2])*(t[2]));
+ outbuf=dupalloc_compbuf(imbuf1);
/* note, processor gets a keyvals array passed on as buffer constant */
- composit2_pixel_processor(node, workbuf, workbuf, in[0]->vec, NULL, keyvals, do_diff_matte, CB_RGBA, CB_VAL);
+ composit2_pixel_processor(node, outbuf, imbuf1, in[0]->vec, imbuf2, in[1]->vec, do_diff_matte, CB_RGBA, CB_RGBA);
- /*convert back to RGB colorspace*/
- switch(node->custom1) {
- case 1: /*RGB*/
- composit1_pixel_processor(node, workbuf, workbuf, in[1]->vec, do_copy_rgba, CB_RGBA);
- break;
- case 2: /*HSV*/
- composit1_pixel_processor(node, workbuf, workbuf, in[1]->vec, do_hsva_to_rgba, CB_RGBA);
- break;
- case 3: /*YUV*/
- composit1_pixel_processor(node, workbuf, workbuf, in[1]->vec, do_yuva_to_rgba, CB_RGBA);
- break;
- case 4: /*YCC*/
- composit1_pixel_processor(node, workbuf, workbuf, in[1]->vec, do_ycca_to_rgba, CB_RGBA);
- break;
- default:
- break;
- }
-
- out[0]->data=workbuf;
+ out[0]->data=outbuf;
if(out[1]->hasoutput)
- out[1]->data=valbuf_from_rgbabuf(workbuf, CHAN_A);
- generate_preview(node, workbuf);
+ out[1]->data=valbuf_from_rgbabuf(outbuf, CHAN_A);
+ generate_preview(node, outbuf);
+
+ if(imbuf1!=in[0]->data)
+ free_compbuf(imbuf1);
- if(inbuf!=in[0]->data)
- free_compbuf(inbuf);
+ if(imbuf2!=in[1]->data)
+ free_compbuf(imbuf2);
}
static void node_composit_init_diff_matte(bNode *node)
{
NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma");
node->storage= c;
- c->t1= 0.01f;
- c->t2= 0.01f;
- c->t3= 0.01f;
- c->fsize= 0.0f;
- c->fstrength= 0.0f;
- node->custom1= 1; /* RGB */
+ c->t1= 0.1f;
+ c->t2= 0.1f;
}
bNodeType cmp_node_diff_matte={
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c
new file mode 100644
index 00000000000..921ac869cb8
--- /dev/null
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c
@@ -0,0 +1,145 @@
+/**
+ * $Id: CMP_diffMatte.c 12931 2007-12-17 18:20:48Z theeth $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Bob Holcomb
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../CMP_util.h"
+
+/* ******************* channel Distance Matte ********************************* */
+static bNodeSocketType cmp_node_distance_matte_in[]={
+ {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ {SOCK_RGBA,1,"Key Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ {-1,0,""}
+};
+
+static bNodeSocketType cmp_node_distance_matte_out[]={
+ {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ {SOCK_VALUE,0,"Matte",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ {-1,0,""}
+};
+
+/* note, keyvals is passed on from caller as stack array */
+/* might have been nicer as temp struct though... */
+static void do_distance_matte(bNode *node, float *out, float *in)
+{
+ NodeChroma *c= (NodeChroma *)node->storage;
+ float tolerence=c->t1;
+ float falloff=c->t2;
+ float distance;
+ float alpha;
+
+ distance=sqrt((c->key[0]-in[0])*(c->key[0]-in[0]) +
+ (c->key[1]-in[1])*(c->key[1]-in[1]) +
+ (c->key[2]-in[2])*(c->key[2]-in[2]));
+
+ VECCOPY(out, in);
+
+ /*make 100% transparent */
+ if(distance < tolerence) {
+ out[3]=0.0;
+ }
+ /*in the falloff region, make partially transparent */
+ else if(distance < falloff+tolerence){
+ distance=distance-tolerence;
+ alpha=distance/falloff;
+ /*only change if more transparent than before */
+ if(alpha < in[3]) {
+ out[3]=alpha;
+ }
+ else { /* leave as before */
+ out[3]=in[3];
+ }
+ }
+ else {
+ out[3]=in[3];
+ }
+}
+
+static void node_composit_exec_distance_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ /*
+ Losely based on the Sequencer chroma key plug-in, but enhanced to work in other color spaces and
+ uses a differnt difference function (suggested in forums of vfxtalk.com).
+ */
+ CompBuf *workbuf;
+ CompBuf *inbuf;
+ NodeChroma *c;
+
+ /*is anything connected?*/
+ if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
+ /*must have an image imput*/
+ if(in[0]->data==NULL) return;
+
+ inbuf=typecheck_compbuf(in[0]->data, CB_RGBA);
+
+ c=node->storage;
+ workbuf=dupalloc_compbuf(inbuf);
+
+ /*use the input color*/
+ c->key[0]= in[1]->vec[0];
+ c->key[1]= in[1]->vec[1];
+ c->key[2]= in[1]->vec[2];
+
+ /* note, processor gets a keyvals array passed on as buffer constant */
+ composit1_pixel_processor(node, workbuf, workbuf, in[0]->vec, do_distance_matte, CB_RGBA);
+
+
+ out[0]->data=workbuf;
+ if(out[1]->hasoutput)
+ out[1]->data=valbuf_from_rgbabuf(workbuf, CHAN_A);
+ generate_preview(node, workbuf);
+
+ if(inbuf!=in[0]->data)
+ free_compbuf(inbuf);
+}
+
+static void node_composit_init_distance_matte(bNode *node)
+{
+ NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma");
+ node->storage= c;
+ c->t1= 0.1f;
+ c->t2= 0.1f;
+}
+
+bNodeType cmp_node_distance_matte={
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ CMP_NODE_DIST_MATTE,
+ /* name */ "Distance Key",
+ /* width+range */ 200, 80, 250,
+ /* class+opts */ NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS,
+ /* input sock */ cmp_node_distance_matte_in,
+ /* output sock */ cmp_node_distance_matte_out,
+ /* storage */ "NodeChroma",
+ /* execfunc */ node_composit_exec_distance_matte,
+ /* butfunc */ NULL,
+ /* initfunc */ node_composit_init_distance_matte,
+ /* freestoragefunc */ node_free_standard_storage,
+ /* copystoragefunc */ node_copy_standard_storage,
+ /* id */ NULL
+};
+
+
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_levels.c b/source/blender/nodes/intern/CMP_nodes/CMP_levels.c
new file mode 100644
index 00000000000..414c535789e
--- /dev/null
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_levels.c
@@ -0,0 +1,337 @@
+/**
+ * $Id: CMP_levels.c 12931 2007-12-17 18:20:48Z theeth $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Bob Holcomb.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../CMP_util.h"
+
+
+/* **************** LEVELS ******************** */
+static bNodeSocketType cmp_node_view_levels_in[]= {
+ { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static bNodeSocketType cmp_node_view_levels_out[]={
+ {SOCK_VALUE, 0,"Mean",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ {SOCK_VALUE, 0,"Std Dev",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ {-1,0,""}
+};
+
+static void rgb_tobw(float r, float g, float b, float* out)
+{
+ *out= r*0.35f + g*0.45f + b*0.2f;
+}
+
+static void fill_bins(bNode* node, CompBuf* in, int* bins)
+{
+ float value[4];
+ int ivalue;
+ int x,y;
+
+ /*fill bins */
+ for(y=0; y<in->y; y++) {
+ for(x=0; x<in->x; x++) {
+
+ /* get the pixel */
+ qd_getPixel(in, x, y, value);
+
+ if(value[3] > 0.0) { /* don't count transparent pixels */
+ switch(node->custom1) {
+ case 1: { /* all colors */
+ rgb_tobw(value[0],value[1],value[2], &value[0]);
+ value[0]=value[0]*255; /* scale to 0-255 range */
+ ivalue=(int)value[0];
+ break;
+ }
+ case 2: { /* red channel */
+ value[0]=value[0]*255; /* scale to 0-255 range */
+ ivalue=(int)value[0];
+ break;
+ }
+ case 3: { /* green channel */
+ value[1]=value[1]*255; /* scale to 0-255 range */
+ ivalue=(int)value[1];
+ break;
+ }
+ case 4: /*blue channel */
+ {
+ value[2]=value[2]*255; /* scale to 0-255 range */
+ ivalue=(int)value[2];
+ break;
+ }
+ case 5: /* luminence */
+ {
+ rgb_to_yuv(value[0],value[1],value[2], &value[0], &value[1], &value[2]);
+ value[0]=value[0]*255; /* scale to 0-255 range */
+ ivalue=(int)value[0];
+ break;
+ }
+ } /*end switch */
+
+ /*clip*/
+ if(ivalue<0) ivalue=0;
+ if(ivalue>255) ivalue=255;
+
+ /*put in the correct bin*/
+ bins[ivalue]+=1;
+ } /*end if alpha */
+ }
+ }
+}
+
+static float brightness_mean(bNode* node, CompBuf* in)
+{
+ float sum=0.0;
+ int numPixels=0.0;
+ int x,y;
+ float value[4];
+
+ for(x=0; x< in->x; x++) {
+ for(y=0; y < in->y; y++) {
+
+ /* get the pixel */
+ qd_getPixel(in, x, y, value);
+
+ if(value[3] > 0.0) { /* don't count transparent pixels */
+ numPixels++;
+ switch(node->custom1)
+ {
+ case 1:
+ {
+ rgb_tobw(value[0],value[1],value[2], &value[0]);
+ sum+=value[0];
+ break;
+ }
+ case 2:
+ {
+ sum+=value[0];
+ break;
+ }
+ case 3:
+ {
+ sum+=value[1];
+ break;
+ }
+ case 4:
+ {
+ sum+=value[2];
+ break;
+ }
+ case 5:
+ {
+ rgb_to_yuv(value[0],value[1],value[2], &value[0], &value[1], &value[2]);
+ sum+=value[0];
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return sum/numPixels;
+}
+
+static float brightness_standard_deviation(bNode* node, CompBuf* in, float mean)
+{
+ float sum=0.0;
+ int numPixels=0.0;
+ int x,y;
+ float value[4];
+
+ for(x=0; x< in->x; x++) {
+ for(y=0; y < in->y; y++) {
+
+ /* get the pixel */
+ qd_getPixel(in, x, y, value);
+
+ if(value[3] > 0.0) { /* don't count transparent pixels */
+ numPixels++;
+ switch(node->custom1)
+ {
+ case 1:
+ {
+ rgb_tobw(value[0],value[1],value[2], &value[0]);
+ sum+=(value[0]-mean)*(value[0]-mean);
+ break;
+ }
+ case 2:
+ {
+ sum+=value[0];
+ sum+=(value[0]-mean)*(value[0]-mean);
+ break;
+ }
+ case 3:
+ {
+ sum+=value[1];
+ sum+=(value[1]-mean)*(value[1]-mean);
+ break;
+ }
+ case 4:
+ {
+ sum+=value[2];
+ sum+=(value[2]-mean)*(value[2]-mean);
+ break;
+ }
+ case 5:
+ {
+ rgb_to_yuv(value[0],value[1],value[2], &value[0], &value[1], &value[2]);
+ sum+=(value[0]-mean)*(value[0]-mean);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+
+ return sqrt(sum/(float)(numPixels-1));
+}
+
+static void draw_histogram(bNode *node, CompBuf *out, int* bins)
+{
+ int x,y;
+ float color[4];
+ float value;
+ int max;
+
+ /* find max value */
+ max=0;
+ for(x=0; x<256; x++) {
+ if(bins[x]>max) max=bins[x];
+ }
+
+ /*draw histogram in buffer */
+ for(x=0; x<out->x; x++) {
+ for(y=0;y<out->y; y++) {
+
+ /* get normalized value (0..255) */
+ value=((float)bins[x]/(float)max)*255.0;
+
+ if(y < (int)value) { /*if the y value is below the height of the bar for this line then draw with the color */
+ switch (node->custom1) {
+ case 1: { /* draw in black */
+ color[0]=0.0; color[1]=0.0; color[2]=0.0; color[3]=1.0;
+ break;
+ }
+ case 2: { /* draw in red */
+ color[0]=1.0; color[1]=0.0; color[2]=0.0; color[3]=1.0;
+ break;
+ }
+ case 3: { /* draw in green */
+ color[0]=0.0; color[1]=1.0; color[2]=0.0; color[3]=1.0;
+ break;
+ }
+ case 4: { /* draw in blue */
+ color[0]=0.0; color[1]=0.0; color[2]=1.0; color[3]=1.0;
+ break;
+ }
+ case 5: { /* draw in white */
+ color[0]=1.0; color[1]=1.0; color[2]=1.0; color[3]=1.0;
+ break;
+ }
+ }
+ }
+ else{
+ color[0]=0.8; color[1]=0.8; color[2]=0.8; color[3]=1.0;
+ }
+
+ /* set the color */
+ qd_setPixel(out, x, y, color);
+ }
+ }
+}
+
+static void node_composit_exec_view_levels(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ CompBuf* cbuf;
+ CompBuf* histogram;
+ float mean, std_dev;
+ int bins[256];
+ int x;
+
+ if(in[0]->hasinput==0) return;
+ if(in[0]->data==NULL) return;
+
+ histogram=alloc_compbuf(256, 256, CB_RGBA, 1);
+ cbuf=typecheck_compbuf(in[0]->data, CB_RGBA);
+
+ /*initalize bins*/
+ for(x=0; x<256; x++) {
+ bins[x]=0;
+ }
+
+ /*fill bins */
+ fill_bins(node, in[0]->data, bins);
+
+ /* draw the histogram chart */
+ draw_histogram(node, histogram, bins);
+
+ /* calculate the average brightness and contrast */
+ mean=brightness_mean(node, in[0]->data);
+ std_dev=brightness_standard_deviation(node, in[0]->data, mean);
+
+ /* Printf debuging ;)
+ printf("Mean: %f\n", mean);
+ printf("Std Dev: %f\n", std_dev);
+ */
+
+ if(out[0]->hasoutput)
+ out[0]->vec[0]= mean;
+ if(out[1]->hasoutput)
+ out[1]->vec[0]= std_dev;
+
+ generate_preview(node, histogram);
+
+ if(cbuf!=in[0]->data)
+ free_compbuf(cbuf);
+ free_compbuf(histogram);
+}
+
+static void node_composit_init_view_levels(bNode* node)
+{
+ node->custom1=1; /*All channels*/
+}
+
+bNodeType cmp_node_view_levels= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ CMP_NODE_VIEW_LEVELS,
+ /* name */ "Levels",
+ /* widthrange */ 140, 100, 320,
+ /* classopts */ NODE_CLASS_OUTPUT, NODE_OPTIONS|NODE_PREVIEW,
+ /* input sock */ cmp_node_view_levels_in,
+ /* output sock */ cmp_node_view_levels_out,
+ /* storage */ "ImageUser",
+ /* execfunc */ node_composit_exec_view_levels,
+ /* butfunc */ NULL,
+ /* initfunc */ node_composit_init_view_levels,
+ /* freestoragefunc */ node_free_standard_storage,
+ /* copystoragefunc */ node_copy_standard_storage,
+ /* id */ NULL
+
+};
+
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c
index 9aebd999b29..350def76736 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c
@@ -22,7 +22,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Bob Holcomb .
*
* ***** END GPL LICENSE BLOCK *****
*/
diff --git a/source/blender/nodes/intern/CMP_util.c b/source/blender/nodes/intern/CMP_util.c
index f9805645115..b396d5549d7 100644
--- a/source/blender/nodes/intern/CMP_util.c
+++ b/source/blender/nodes/intern/CMP_util.c
@@ -1104,9 +1104,23 @@ void qd_getPixel(CompBuf* src, int x, int y, float* col)
{
if ((x >= 0) && (x < src->x) && (y >= 0) && (y < src->y)) {
float* bc = &src->rect[(x + y*src->x)*src->type];
- col[0] = bc[0], col[1] = bc[1], col[2] = bc[2];
+ switch(src->type){
+ /* these fallthrough to get all the channels */
+ case CB_RGBA: col[3]=bc[3];
+ case CB_VEC3: col[2]=bc[2];
+ case CB_VEC2: col[1]=bc[1];
+ case CB_VAL: col[0]=bc[0];
+ }
+ }
+ else {
+ switch(src->type){
+ /* these fallthrough to get all the channels */
+ case CB_RGBA: col[3]=0.0;
+ case CB_VEC3: col[2]=0.0;
+ case CB_VEC2: col[1]=0.0;
+ case CB_VAL: col[0]=0.0;
+ }
}
- else col[0] = col[1] = col[2] = 0.f;
}
// sets pixel (x, y) to color col
@@ -1114,7 +1128,13 @@ void qd_setPixel(CompBuf* src, int x, int y, float* col)
{
if ((x >= 0) && (x < src->x) && (y >= 0) && (y < src->y)) {
float* bc = &src->rect[(x + y*src->x)*src->type];
- bc[0] = col[0], bc[1] = col[1], bc[2] = col[2];
+ switch(src->type){
+ /* these fallthrough to get all the channels */
+ case CB_RGBA: bc[3]=col[3];
+ case CB_VEC3: bc[2]=col[2];
+ case CB_VEC2: bc[1]=col[1];
+ case CB_VAL: bc[0]=col[0];
+ }
}
}
diff --git a/source/blender/nodes/intern/CMP_util.h b/source/blender/nodes/intern/CMP_util.h
index 19e41f5c118..2a2dc97ed73 100644
--- a/source/blender/nodes/intern/CMP_util.h
+++ b/source/blender/nodes/intern/CMP_util.h
@@ -168,7 +168,7 @@ typedef float fRGB[4];
/* clear color */
#define fRGB_clear(c) { c[0]=c[1]=c[2]=0.f; }
/* copy c2 to c1 */
-#define fRGB_copy(c1, c2) { c1[0]=c2[0]; c1[1]=c2[1]; c1[2]=c2[2]; }
+#define fRGB_copy(c1, c2) { c1[0]=c2[0]; c1[1]=c2[1]; c1[2]=c2[2]; c1[3]=c2[3]; }
/* add c2 to c1 */
#define fRGB_add(c1, c2) { c1[0]+=c2[0]; c1[1]+=c2[1]; c1[2]+=c2[2]; }
/* subtract c2 from c1 */
@@ -186,7 +186,8 @@ typedef float fRGB[4];
/* swap colors c1 & c2 */
#define fRGB_swap(c1, c2) { float _t=c1[0]; c1[0]=c2[0]; c2[0]=_t;\
_t=c1[1]; c1[1]=c2[1]; c2[1]=_t;\
- _t=c1[2]; c1[2]=c2[2]; c2[2]=_t; }
+ _t=c1[2]; c1[2]=c2[2]; c2[2]=_t;\
+ _t=c1[3]; c1[3]=c2[3]; c3[3]=_t;}
void qd_getPixel(CompBuf* src, int x, int y, float* col);
void qd_setPixel(CompBuf* src, int x, int y, float* col);