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/intern/CMP_nodes/CMP_levels.c
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/intern/CMP_nodes/CMP_levels.c')
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_levels.c337
1 files changed, 337 insertions, 0 deletions
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
+
+};
+