doxygen: prevent GPL license block from being parsed as doxygen comment.
[blender.git] / source / blender / nodes / intern / CMP_nodes / CMP_curves.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2006 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): Bj√∂rn C. Schaefer
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include "../CMP_util.h"
31
32
33 /* **************** CURVE Time  ******************** */
34
35 /* custom1 = sfra, custom2 = efra */
36 static bNodeSocketType cmp_node_time_out[]= {
37         {       SOCK_VALUE, 0, "Fac",   1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f},
38         {       -1, 0, ""       }
39 };
40
41 static void node_composit_exec_curves_time(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
42 {
43         RenderData *rd= data;
44         /* stack order output: fac */
45         float fac= 0.0f;
46         
47         if(node->custom1 < node->custom2)
48                 fac= (rd->cfra - node->custom1)/(float)(node->custom2-node->custom1);
49         
50         fac= curvemapping_evaluateF(node->storage, 0, fac);
51         out[0]->vec[0]= CLAMPIS(fac, 0.0f, 1.0f);
52 }
53
54
55 static void node_composit_init_curves_time(bNode* node)
56 {
57    node->custom1= 1;
58    node->custom2= 250;
59    node->storage= curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
60 }
61
62 void register_node_type_cmp_curve_time(ListBase *lb)
63 {
64         static bNodeType ntype;
65
66         node_type_base(&ntype, CMP_NODE_TIME, "Time", NODE_CLASS_INPUT, NODE_OPTIONS,
67                 NULL, cmp_node_time_out);
68         node_type_size(&ntype, 140, 100, 320);
69         node_type_init(&ntype, node_composit_init_curves_time);
70         node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
71         node_type_exec(&ntype, node_composit_exec_curves_time);
72
73         nodeRegisterType(lb, &ntype);
74 }
75
76
77
78
79 /* **************** CURVE VEC  ******************** */
80 static bNodeSocketType cmp_node_curve_vec_in[]= {
81         {       SOCK_VECTOR, 1, "Vector",       0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
82         {       -1, 0, ""       }
83 };
84
85 static bNodeSocketType cmp_node_curve_vec_out[]= {
86         {       SOCK_VECTOR, 0, "Vector",       0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f},
87         {       -1, 0, ""       }
88 };
89
90 static void node_composit_exec_curve_vec(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
91 {
92         /* stack order input:  vec */
93         /* stack order output: vec */
94         
95         curvemapping_evaluate_premulRGBF(node->storage, out[0]->vec, in[0]->vec);
96 };
97
98 static void node_composit_init_curve_vec(bNode* node)
99 {
100    node->storage= curvemapping_add(3, -1.0f, -1.0f, 1.0f, 1.0f);
101 };
102
103 void register_node_type_cmp_curve_vec(ListBase *lb)
104 {
105         static bNodeType ntype;
106
107         node_type_base(&ntype, CMP_NODE_CURVE_VEC, "Vector Curves", NODE_CLASS_OP_VECTOR, NODE_OPTIONS,
108                 cmp_node_curve_vec_in, cmp_node_curve_vec_out);
109         node_type_size(&ntype, 200, 140, 320);
110         node_type_init(&ntype, node_composit_init_curve_vec);
111         node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
112         node_type_exec(&ntype, node_composit_exec_curve_vec);
113
114         nodeRegisterType(lb, &ntype);
115 }
116
117
118 /* **************** CURVE RGB  ******************** */
119 static bNodeSocketType cmp_node_curve_rgb_in[]= {
120         {       SOCK_VALUE, 1, "Fac",   1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
121         {       SOCK_RGBA, 1, "Image",  0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
122         {       SOCK_RGBA, 1, "Black Level",    0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
123         {       SOCK_RGBA, 1, "White Level",    1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f},
124         {       -1, 0, ""       }
125 };
126
127 static bNodeSocketType cmp_node_curve_rgb_out[]= {
128         {       SOCK_RGBA, 0, "Image",  0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f},
129         {       -1, 0, ""       }
130 };
131
132 static void do_curves(bNode *node, float *out, float *in)
133 {
134         curvemapping_evaluate_premulRGBF(node->storage, out, in);
135         out[3]= in[3];
136 }
137
138 static void do_curves_fac(bNode *node, float *out, float *in, float *fac)
139 {
140         
141         if(*fac>=1.0)
142                 curvemapping_evaluate_premulRGBF(node->storage, out, in);
143         else if(*fac<=0.0) {
144                 VECCOPY(out, in);
145         }
146         else {
147                 float col[4], mfac= 1.0f-*fac;
148                 curvemapping_evaluate_premulRGBF(node->storage, col, in);
149                 out[0]= mfac*in[0] + *fac*col[0];
150                 out[1]= mfac*in[1] + *fac*col[1];
151                 out[2]= mfac*in[2] + *fac*col[2];
152         }
153         out[3]= in[3];
154 }
155
156 static void node_composit_exec_curve_rgb(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
157 {
158         /* stack order input:  fac, image, black level, white level */
159         /* stack order output: image */
160         
161         if(out[0]->hasoutput==0)
162                 return;
163
164         /* input no image? then only color operation */
165         if(in[1]->data==NULL) {
166                 curvemapping_evaluateRGBF(node->storage, out[0]->vec, in[1]->vec);
167         }
168         else {
169                 /* make output size of input image */
170                 CompBuf *cbuf= in[1]->data;
171                 CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
172                 
173                 curvemapping_set_black_white(node->storage, in[2]->vec, in[3]->vec);
174                 
175                 if(in[0]->vec[0] == 1.0)
176                         composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_curves, CB_RGBA);
177                 else
178                         composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_curves_fac, CB_RGBA, CB_VAL);
179                 
180                 out[0]->data= stackbuf;
181         }
182         
183 };
184
185 static void node_composit_init_curve_rgb(bNode* node)
186 {
187    node->storage= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f);
188 };
189
190 void register_node_type_cmp_curve_rgb(ListBase *lb)
191 {
192         static bNodeType ntype;
193
194         node_type_base(&ntype, CMP_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, NODE_OPTIONS,
195                 cmp_node_curve_rgb_in, cmp_node_curve_rgb_out);
196         node_type_size(&ntype, 200, 140, 320);
197         node_type_init(&ntype, node_composit_init_curve_rgb);
198         node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
199         node_type_exec(&ntype, node_composit_exec_curve_rgb);
200
201         nodeRegisterType(lb, &ntype);
202 }
203
204