svn merge ^/trunk/blender -r47325:47381
[blender.git] / source / blender / nodes / composite / nodes / node_composite_dilate.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2006 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/nodes/composite/nodes/node_composite_dilate.c
29  *  \ingroup cmpnodes
30  */
31
32
33 #include "node_composite_util.h"
34
35
36 /* **************** Dilate/Erode ******************** */
37
38 static bNodeSocketTemplate cmp_node_dilateerode_in[]= {
39         {       SOCK_FLOAT, 1, N_("Mask"),              0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR},
40         {       -1, 0, ""       }
41 };
42 static bNodeSocketTemplate cmp_node_dilateerode_out[]= {
43         {       SOCK_FLOAT, 0, N_("Mask")},
44         {       -1, 0, ""       }
45 };
46
47 void node_composite_morpho_dilate(CompBuf *cbuf)
48 {
49         int x, y;
50         float *p, *rectf = cbuf->rect;
51         
52         for (y=0; y < cbuf->y; y++) {
53                 for (x=0; x < cbuf->x-1; x++) {
54                         p = rectf + cbuf->x*y + x;
55                         *p = MAX2(*p, *(p + 1));
56                 }
57         }
58
59         for (y=0; y < cbuf->y; y++) {
60                 for (x=cbuf->x-1; x >= 1; x--) {
61                         p = rectf + cbuf->x*y + x;
62                         *p = MAX2(*p, *(p - 1));
63                 }
64         }
65
66         for (x=0; x < cbuf->x; x++) {
67                 for (y=0; y < cbuf->y-1; y++) {
68                         p = rectf + cbuf->x*y + x;
69                         *p = MAX2(*p, *(p + cbuf->x));
70                 }
71         }
72
73         for (x=0; x < cbuf->x; x++) {
74                 for (y=cbuf->y-1; y >= 1; y--) {
75                         p = rectf + cbuf->x*y + x;
76                         *p = MAX2(*p, *(p - cbuf->x));
77                 }
78         }
79 }
80
81 void node_composite_morpho_erode(CompBuf *cbuf)
82 {
83         int x, y;
84         float *p, *rectf = cbuf->rect;
85         
86         for (y=0; y < cbuf->y; y++) {
87                 for (x=0; x < cbuf->x-1; x++) {
88                         p = rectf + cbuf->x*y + x;
89                         *p = MIN2(*p, *(p + 1));
90                 }
91         }
92
93         for (y=0; y < cbuf->y; y++) {
94                 for (x=cbuf->x-1; x >= 1; x--) {
95                         p = rectf + cbuf->x*y + x;
96                         *p = MIN2(*p, *(p - 1));
97                 }
98         }
99
100         for (x=0; x < cbuf->x; x++) {
101                 for (y=0; y < cbuf->y-1; y++) {
102                         p = rectf + cbuf->x*y + x;
103                         *p = MIN2(*p, *(p + cbuf->x));
104                 }
105         }
106
107         for (x=0; x < cbuf->x; x++) {
108                 for (y=cbuf->y-1; y >= 1; y--) {
109                         p = rectf + cbuf->x*y + x;
110                         *p = MIN2(*p, *(p - cbuf->x));
111                 }
112         }
113         
114 }
115
116 static void node_composit_exec_dilateerode(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
117 {
118         /* stack order in: mask */
119         /* stack order out: mask */
120         if (out[0]->hasoutput==0) 
121                 return;
122         
123         /* input no image? then only color operation */
124         if (in[0]->data==NULL) {
125                 out[0]->vec[0] = out[0]->vec[1] = out[0]->vec[2] = 0.0f;
126                 out[0]->vec[3] = 0.0f;
127         }
128         else {
129                 /* make output size of input image */
130                 CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_VAL);
131                 CompBuf *stackbuf= dupalloc_compbuf(cbuf);
132                 short i;
133                 
134                 if (node->custom2 > 0) { // positive, dilate
135                         for (i = 0; i < node->custom2; i++)
136                                 node_composite_morpho_dilate(stackbuf);
137                 }
138                 else if (node->custom2 < 0) { // negative, erode
139                         for (i = 0; i > node->custom2; i--)
140                                 node_composite_morpho_erode(stackbuf);
141                 }
142                 
143                 if (cbuf!=in[0]->data)
144                         free_compbuf(cbuf);
145                 
146                 out[0]->data= stackbuf;
147         }
148 }
149
150 void register_node_type_cmp_dilateerode(bNodeTreeType *ttype)
151 {
152         static bNodeType ntype;
153         
154         node_type_base(ttype, &ntype, CMP_NODE_DILATEERODE, "Dilate/Erode", NODE_CLASS_OP_FILTER, NODE_OPTIONS);
155         node_type_socket_templates(&ntype, cmp_node_dilateerode_in, cmp_node_dilateerode_out);
156         node_type_size(&ntype, 130, 100, 320);
157         node_type_exec(&ntype, node_composit_exec_dilateerode);
158         
159         nodeRegisterType(ttype, &ntype);
160 }