Added Levels Node (histogram, with mean/std deviation outputs)
authorRobert Holcomb <bob_holcomb@hotmail.com>
Thu, 10 Sep 2009 04:12:22 +0000 (04:12 +0000)
committerRobert Holcomb <bob_holcomb@hotmail.com>
Thu, 10 Sep 2009 04:12:22 +0000 (04:12 +0000)
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

15 files changed:
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/node.c
source/blender/editors/space_node/drawnode.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_nodetree_types.h
source/blender/nodes/CMP_node.h
source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c
source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c
source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c [new file with mode: 0644]
source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c
source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c [new file with mode: 0644]
source/blender/nodes/intern/CMP_nodes/CMP_levels.c [new file with mode: 0644]
source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c
source/blender/nodes/intern/CMP_util.c
source/blender/nodes/intern/CMP_util.h

index 40afa1d..cbb3791 100644 (file)
@@ -25,7 +25,7 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): none yet.
+ * Contributor(s): Bob Holcomb.
  *
  * ***** END GPL LICENSE BLOCK *****
  */
@@ -325,7 +325,7 @@ void                        ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat);
 #define CMP_NODE_COMBYUVA      234
 #define CMP_NODE_DIFF_MATTE    235
 #define CMP_NODE_COLOR_SPILL   236
-#define CMP_NODE_CHROMA                237
+#define CMP_NODE_CHROMA_MATTE  237
 #define CMP_NODE_CHANNEL_MATTE 238
 #define CMP_NODE_FLIP          239
 #define CMP_NODE_SPLITVIEWER   240
@@ -345,6 +345,9 @@ void                        ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat);
 #define CMP_NODE_DBLUR         254
 #define CMP_NODE_BILATERALBLUR  255
 #define CMP_NODE_PREMULKEY  256
+#define CMP_NODE_DIST_MATTE    257
+#define CMP_NODE_VIEW_LEVELS    258
+#define CMP_NODE_COLOR_MATTE 259
 
 #define CMP_NODE_GLARE         301
 #define CMP_NODE_TONEMAP       302
index bd6919d..90ea53d 100644 (file)
@@ -22,7 +22,7 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): none yet.
+ * Contributor(s): Bob Holcomb.
  *
  * ***** END GPL LICENSE BLOCK *****
  */
@@ -2597,7 +2597,7 @@ void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree)
                                if(outsocket_exists(lnode->new_node, lsock->new_sock)) {
                                        lsock->new_sock->ns.data= lsock->ns.data;
                                        lsock->ns.data= NULL;
-                                       lsock->new_sock= NULL;
+                                               lsock->new_sock= NULL;
                                }
                        }
                }
@@ -2932,6 +2932,7 @@ static void registerCompositNodes(ListBase *ntypelist)
        nodeRegisterType(ntypelist, &cmp_node_viewer);
        nodeRegisterType(ntypelist, &cmp_node_splitviewer);
        nodeRegisterType(ntypelist, &cmp_node_output_file);
+       nodeRegisterType(ntypelist, &cmp_node_view_levels);
        
        nodeRegisterType(ntypelist, &cmp_node_curve_rgb);
        nodeRegisterType(ntypelist, &cmp_node_mix_rgb);
@@ -2971,7 +2972,9 @@ static void registerCompositNodes(ListBase *ntypelist)
        nodeRegisterType(ntypelist, &cmp_node_premulkey);
        
        nodeRegisterType(ntypelist, &cmp_node_diff_matte);
-       nodeRegisterType(ntypelist, &cmp_node_chroma);
+       nodeRegisterType(ntypelist, &cmp_node_distance_matte);
+       nodeRegisterType(ntypelist, &cmp_node_chroma_matte);
+       nodeRegisterType(ntypelist, &cmp_node_color_matte);
        nodeRegisterType(ntypelist, &cmp_node_channel_matte);
        nodeRegisterType(ntypelist, &cmp_node_color_spill);
        nodeRegisterType(ntypelist, &cmp_node_luma_matte);
index 7617f32..98de32a 100644 (file)
@@ -22,7 +22,7 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): David Millan Escriva, Juho Vepsäläinen
+ * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Bob Holcomb
  *
  * ***** END GPL LICENSE BLOCK *****
  */
@@ -1647,45 +1647,35 @@ static int node_composit_buts_dilateerode(uiBlock *block, bNodeTree *ntree, bNod
 static int node_composit_buts_diff_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
 {
        if(block) {
-               short sx= (butr->xmax-butr->xmin)/4;
-               short dx= (butr->xmax-butr->xmin)/3;
                NodeChroma *c= node->storage;
                
                uiBlockBeginAlign(block);
-               /*color space selectors*/
-               uiDefButS(block, ROW,B_NODE_EXEC,"RGB",
-                                                       butr->xmin,butr->ymin+60,sx,20,
-                                                       &node->custom1,1,1, 0, 0, "RGB Color Space");
-               uiDefButS(block, ROW,B_NODE_EXEC,"HSV",
-                                                       butr->xmin+sx,butr->ymin+60,sx,20,
-                                                       &node->custom1,1,2, 0, 0, "HSV Color Space");
-               uiDefButS(block, ROW,B_NODE_EXEC,"YUV",
-                                                       butr->xmin+2*sx,butr->ymin+60,sx,20,
-                                                       &node->custom1,1,3, 0, 0, "YUV Color Space");
-                                       uiDefButS(block, ROW,B_NODE_EXEC,"YCC",
-                                                       butr->xmin+3*sx,butr->ymin+60,sx,20,
-                                                       &node->custom1,1,4, 0, 0, "YCbCr Color Space");
-               /*channel tolorences*/
-               uiDefButF(block, NUM, B_NODE_EXEC, " ",
-                                                       butr->xmin, butr->ymin+40, dx, 20,
-                                                       &c->t1, 0.0f, 1.0f, 100, 0, "Channel 1 Tolerance");
-               uiDefButF(block, NUM, B_NODE_EXEC, " ",
-                                                       butr->xmin+dx, butr->ymin+40, dx, 20,
-                                                       &c->t2, 0.0f, 1.0f, 100, 0, "Channel 2 Tolorence");
-               uiDefButF(block, NUM, B_NODE_EXEC, " ",
-                                                       butr->xmin+2*dx, butr->ymin+40, dx, 20,
-                                                       &c->t3, 0.0f, 1.0f, 100, 0, "Channel 3 Tolorence");
-               /*falloff parameters*/
-               /*
-               uiDefButF(block, NUMSLI, B_NODE_EXEC, "Falloff Size ",
+               uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Tolerance: ", 
                        butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20,
-                       &c->fsize, 0.0f, 1.0f, 100, 0, "");
-               */
-               uiDefButF(block, NUMSLI, B_NODE_EXEC, "Falloff: ",
+                       &c->t1, 0.0f, 1.0f, 100, 0, "Color differences below this threshold are keyed.");
+               uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Falloff: ", 
+                       butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
+                       &c->t2, 0.0f, 1.0f, 100, 0, "Color differences below this additional threshold are partially keyed.");
+      uiBlockEndAlign(block);
+       }
+       return 40;
+}
+
+static int node_composit_buts_distance_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+{
+       if(block) {
+               NodeChroma *c= node->storage;
+               
+               uiBlockBeginAlign(block);
+               uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Tolerance: ", 
                        butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20,
-                       &c->fstrength, 0.0f, 1.0f, 100, 0, "");
+                       &c->t1, 0.0f, 1.0f, 100, 0, "Color distances below this threshold are keyed.");
+               uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Falloff: ", 
+                       butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
+                       &c->t2, 0.0f, 1.0f, 100, 0, "Color distances below this additional threshold are partially keyed.");
+       uiBlockEndAlign(block);
        }
-       return 80;
+       return 40;
 }
 
 static int node_composit_buts_color_spill(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
@@ -1717,6 +1707,7 @@ static int node_composit_buts_chroma_matte(uiBlock *block, bNodeTree *ntree, bNo
        if(block) {
                short dx=(butr->xmax-butr->xmin)/2;
                NodeChroma *c= node->storage;
+
                uiBlockBeginAlign(block);
 
                uiDefButF(block, NUMSLI, B_NODE_EXEC, "Acceptance ",
@@ -1736,6 +1727,7 @@ static int node_composit_buts_chroma_matte(uiBlock *block, bNodeTree *ntree, bNo
                uiDefButF(block, NUMSLI, B_NODE_EXEC, "Shadow Adjust ",
                        butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
                        &c->t3, 0.0f, 1.0f, 100, 0, "Adjusts the brightness of any shadows captured");
+               uiBlockEndAlign(block);
 
                if(c->t2 > c->t1)
                        c->t2=c->t1;
@@ -1743,6 +1735,28 @@ static int node_composit_buts_chroma_matte(uiBlock *block, bNodeTree *ntree, bNo
        return 80;
 }
 
+static int node_composit_buts_color_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+{
+       if(block) {
+               NodeChroma *c= node->storage;
+               uiBlockBeginAlign(block);
+
+               uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "H: ",
+                       butr->xmin, butr->ymin+40, butr->xmax-butr->xmin, 20,
+                       &c->t1, 0.0f, 0.25f, 100, 0, "Hue tolerance for colors to be considered a keying color");
+               uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "S: ",
+                       butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20,
+                       &c->t2, 0.0f, 1.0f, 100, 0, "Saturation Tolerance for the color");
+               uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "V: ",
+                       butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
+                       &c->t3, 0.0f, 1.0f, 100, 0, "Value Tolerance for the color");
+
+               uiBlockEndAlign(block);
+       }
+       return 60;
+}
+
+
 static int node_composit_buts_channel_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
 {
        if(block) {
@@ -1977,6 +1991,29 @@ static int node_composit_buts_premulkey(uiBlock *block, bNodeTree *ntree, bNode
        return 20;
 }
 
+static int node_composit_buts_view_levels(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+{
+       if(block) {
+               short sx= (butr->xmax-butr->xmin)/5;
+       
+               /*color space selectors*/
+               uiBlockBeginAlign(block);
+               uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"C",
+                       butr->xmin,butr->ymin,sx,20,&node->custom1,1,1, 0, 0, "Combined RGB");
+               uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"R",
+                       butr->xmin+sx,butr->ymin,sx,20,&node->custom1,1,2, 0, 0, "Red Channel");
+               uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"G",
+                       butr->xmin+2*sx,butr->ymin,sx,20,&node->custom1,1,3, 0, 0, "Green Channel");
+               uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"B",
+                       butr->xmin+3*sx,butr->ymin,sx,20,&node->custom1,1,4, 0, 0, "Blue Channel");
+      uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"L",
+                       butr->xmin+4*sx,butr->ymin,sx,20,&node->custom1,1,5, 0, 0, "Luminenc Channel");
+               uiBlockEndAlign(block);
+       }
+       return 20;
+}
+
+
 /* only once called */
 static void node_composit_set_butfunc(bNodeType *ntype)
 {
@@ -2070,17 +2107,22 @@ static void node_composit_set_butfunc(bNodeType *ntype)
                        break;
                case CMP_NODE_OUTPUT_FILE:
                        ntype->butfunc= node_composit_buts_file_output;
-                       break;
-       
+                       break;  
                case CMP_NODE_DIFF_MATTE:
                        ntype->butfunc=node_composit_buts_diff_matte;
                        break;
+               case CMP_NODE_DIST_MATTE:
+                       ntype->butfunc=node_composit_buts_distance_matte;
+                       break;
                case CMP_NODE_COLOR_SPILL:
                        ntype->butfunc=node_composit_buts_color_spill;
                        break;
-               case CMP_NODE_CHROMA:
+               case CMP_NODE_CHROMA_MATTE:
                        ntype->butfunc=node_composit_buts_chroma_matte;
                        break;
+               case CMP_NODE_COLOR_MATTE:
+                       ntype->butfunc=node_composit_buts_color_matte;
+                       break;
                case CMP_NODE_SCALE:
                        ntype->butfunc= node_composit_buts_scale;
                        break;
@@ -2105,6 +2147,9 @@ static void node_composit_set_butfunc(bNodeType *ntype)
                case CMP_NODE_PREMULKEY:
                        ntype->butfunc= node_composit_buts_premulkey;
                        break;
+      case CMP_NODE_VIEW_LEVELS:
+                       ntype->butfunc=node_composit_buts_view_levels;
+                       break;
                default:
                        ntype->butfunc= NULL;
        }
index b3046ad..3fd358a 100644 (file)
@@ -747,43 +747,63 @@ static void def_cmp_scale(StructRNA *srna)
 static void def_cmp_diff_matte(StructRNA *srna)
 {
        PropertyRNA *prop;
+
+       RNA_def_struct_sdna_from(srna, "NodeChroma", "storage");
+
+       /* TODO: nicer wrapping for tolerances */       
        
-       static EnumPropertyItem color_space_items[] = {
-               {1, "RGB", 0, "RGB",   ""},
-               {2, "HSV", 0, "HSV",   ""},
-               {3, "YUV", 0, "YUV",   ""},
-               {4, "YCC", 0, "YCbCr", ""},
-               {0, NULL, 0, NULL, NULL}
-       };
+       prop = RNA_def_property(srna, "tolerance", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "t1");
+       RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_ui_text(prop, "Tolerance", "Color distances below this threshold are keyed.");
        
-       prop = RNA_def_property(srna, "color_space", PROP_ENUM, PROP_NONE);
-       RNA_def_property_enum_sdna(prop, NULL, "custom1");
-       RNA_def_property_enum_items(prop, color_space_items);
-       RNA_def_property_ui_text(prop, "Color Space", "");
+       prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "t2");
+       RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_ui_text(prop, "Falloff", "Color distances below this additional threshold are partially keyed.");
+}
+
+static void def_cmp_color_matte(StructRNA *srna)
+{
+       PropertyRNA *prop;
        
        RNA_def_struct_sdna_from(srna, "NodeChroma", "storage");
        
        /* TODO: nicer wrapping for tolerances */
        
-       prop = RNA_def_property(srna, "tolerance1", PROP_FLOAT, PROP_NONE);
+       prop = RNA_def_property(srna, "h", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "t1");
        RNA_def_property_range(prop, 0.0f, 1.0f);
-       RNA_def_property_ui_text(prop, "Channel 1 Tolerance", "");
+       RNA_def_property_ui_text(prop, "H", "Hue tolerance for colors to be considered a keying color");
        
-       prop = RNA_def_property(srna, "tolerance2", PROP_FLOAT, PROP_NONE);
+       prop = RNA_def_property(srna, "s", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "t2");
        RNA_def_property_range(prop, 0.0f, 1.0f);
-       RNA_def_property_ui_text(prop, "Channel 2 Tolerance", "");
+       RNA_def_property_ui_text(prop, "S", "Saturation Tolerance for the color");
        
-       prop = RNA_def_property(srna, "tolerance3", PROP_FLOAT, PROP_NONE);
+       prop = RNA_def_property(srna, "v", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "t3");
        RNA_def_property_range(prop, 0.0f, 1.0f);
-       RNA_def_property_ui_text(prop, "Channel 3 Tolerance", "");
+       RNA_def_property_ui_text(prop, "V", "Value Tolerance for the color");
+}
+
+static void def_cmp_distance_matte(StructRNA *srna)
+{
+       PropertyRNA *prop;
+       
+       RNA_def_struct_sdna_from(srna, "NodeChroma", "storage");
+       
+       /* TODO: nicer wrapping for tolerances */
+       
+       prop = RNA_def_property(srna, "tolerance", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "t1");
+       RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_ui_text(prop, "Tolerance", "Color distances below this threshold are keyed.");
        
        prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE);
-       RNA_def_property_float_sdna(prop, NULL, "fstrength");
+       RNA_def_property_float_sdna(prop, NULL, "t2");
        RNA_def_property_range(prop, 0.0f, 1.0f);
-       RNA_def_property_ui_text(prop, "Falloff", "");
+       RNA_def_property_ui_text(prop, "Falloff", "Color distances below this additional threshold are partially keyed.");
 }
 
 static void def_cmp_color_spill(StructRNA *srna)
@@ -810,7 +830,7 @@ static void def_cmp_color_spill(StructRNA *srna)
        RNA_def_property_ui_text(prop, "Amount", "How much the selected channel is affected by");
 }
 
-static void def_cmp_chroma(StructRNA *srna)
+static void def_cmp_chroma_matte(StructRNA *srna)
 {
        PropertyRNA *prop;
        
index 47a7be1..be4f131 100644 (file)
@@ -82,7 +82,7 @@ DefNode( CompositorNode, CMP_NODE_SEPYUVA,        0,                      "SEPYU
 DefNode( CompositorNode, CMP_NODE_COMBYUVA,       0,                      "COMBYUVA",       CombYUVA,         "Combine YUVA",      ""              )
 DefNode( CompositorNode, CMP_NODE_DIFF_MATTE,     def_cmp_diff_matte,     "DIFF_MATTE",     DiffMatte,        "Difference Key",    ""              )
 DefNode( CompositorNode, CMP_NODE_COLOR_SPILL,    def_cmp_color_spill,    "COLOR_SPILL",    ColorSpill,       "Color Spill",       ""              )
-DefNode( CompositorNode, CMP_NODE_CHROMA,         def_cmp_chroma,         "CHROMA",         Chroma,           "Chroma Key",        ""              )
+DefNode( CompositorNode, CMP_NODE_CHROMA_MATTE,   def_cmp_chroma_matte,   "CHROMA_MATTE",   ChromaMatte,      "Chroma Key",        ""              )
 DefNode( CompositorNode, CMP_NODE_CHANNEL_MATTE,  def_cmp_channel_matte,  "CHANNEL_MATTE",  ChannelMatte,     "Channel Key",       ""              )
 DefNode( CompositorNode, CMP_NODE_FLIP,           def_cmp_flip,           "FLIP",           Flip,             "Flip",              ""              )
 DefNode( CompositorNode, CMP_NODE_SPLITVIEWER,    def_cmp_splitviewer,    "SPLITVIEWER",    SplitViewer,      "Split Viewer",      ""              )
@@ -104,6 +104,9 @@ DefNode( CompositorNode, CMP_NODE_PREMULKEY,      def_cmp_premul_key,     "PREMU
 DefNode( CompositorNode, CMP_NODE_GLARE,          def_cmp_glare,          "GLARE",          Glare,            "Glare",             ""              )
 DefNode( CompositorNode, CMP_NODE_TONEMAP,        def_cmp_tonemap,        "TONEMAP",        Tonemap,          "Tonemap",           ""              )
 DefNode( CompositorNode, CMP_NODE_LENSDIST,       def_cmp_lensdist,       "LENSDIST",       Lensdist,         "Lensdist",          ""              )
+DefNode( CompositorNode, CMP_NODE_VIEW_LEVELS,    0,                      "LEVELS",         Levels,           "Levels",            ""              )
+DefNode( CompositorNode, CMP_NODE_COLOR_MATTE,    def_cmp_color_matte,    "COLOR_MATTE",    ColorMatte,       "Color Matte",       ""              )
+DefNode( CompositorNode, CMP_NODE_DIST_MATTE,     def_cmp_distance_matte, "DISTANCE_MATTE", DistanceMatte,    "Distance Matte",    ""              )
                                                                                                                                                    
 DefNode( TextureNode,    TEX_NODE_OUTPUT,         def_tex_output,         "OUTPUT",         Output,           "Output",            ""              )
 DefNode( TextureNode,    TEX_NODE_CHECKER,        0,                      "CHECKER",        Checker,          "Checker",           ""              )
index 020bbde..041bf1c 100644 (file)
@@ -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; 
index d0cc4e5..b0a2531 100644 (file)
@@ -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;
index 6a40018..28b81fe 100644 (file)
@@ -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 (file)
index 0000000..0a4d3fc
--- /dev/null
@@ -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
+};
+
+
index ade2111..68a1bcd 100644 (file)
@@ -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 (file)
index 0000000..921ac86
--- /dev/null
@@ -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 (file)
index 0000000..414c535
--- /dev/null
@@ -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
+       
+};
+
index 9aebd99..350def7 100644 (file)
@@ -22,7 +22,7 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): none yet.
+ * Contributor(s): Bob Holcomb .
  *
  * ***** END GPL LICENSE BLOCK *****
  */
index f980564..b396d55 100644 (file)
@@ -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];
+               }
        }
 }
 
index 19e41f5..2a2dc97 100644 (file)
@@ -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);