doxygen: prevent GPL license block from being parsed as doxygen comment.
[blender.git] / source / blender / nodes / intern / CMP_nodes / CMP_sepcombYCCA.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): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include "../CMP_util.h"
31
32
33 /* **************** SEPARATE YCCA ******************** */
34 static bNodeSocketType cmp_node_sepycca_in[]= {
35         {  SOCK_RGBA, 1, "Image",        0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
36         {  -1, 0, ""   }
37 };
38 static bNodeSocketType cmp_node_sepycca_out[]= {
39         {  SOCK_VALUE, 0, "Y",        0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
40         {  SOCK_VALUE, 0, "Cb",       0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
41         {  SOCK_VALUE, 0, "Cr",       0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
42         {  SOCK_VALUE, 0, "A",        0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
43         {  -1, 0, ""   }
44 };
45
46 static void do_sepycca_601(bNode *UNUSED(node), float *out, float *in)
47 {
48         float y, cb, cr;
49         
50         rgb_to_ycc(in[0], in[1], in[2], &y, &cb, &cr, BLI_YCC_ITU_BT601);
51         
52         /*divided by 255 to normalize for viewing in */
53         out[0]= y/255.0;
54         out[1]= cb/255.0;
55         out[2]= cr/255.0;
56         out[3]= in[3];
57 }
58
59 static void do_sepycca_709(bNode *UNUSED(node), float *out, float *in)
60 {
61         float y, cb, cr;
62         
63         rgb_to_ycc(in[0], in[1], in[2], &y, &cb, &cr, BLI_YCC_ITU_BT709);
64         
65         /*divided by 255 to normalize for viewing in */
66         out[0]= y/255.0;
67         out[1]= cb/255.0;
68         out[2]= cr/255.0;
69         out[3]= in[3];
70 }
71
72 static void do_sepycca_jfif(bNode *UNUSED(node), float *out, float *in)
73 {
74         float y, cb, cr;
75         
76         rgb_to_ycc(in[0], in[1], in[2], &y, &cb, &cr, BLI_YCC_JFIF_0_255);
77         
78         /*divided by 255 to normalize for viewing in */
79         out[0]= y/255.0;
80         out[1]= cb/255.0;
81         out[2]= cr/255.0;
82         out[3]= in[3];
83 }
84
85 static void node_composit_exec_sepycca(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
86 {
87         /* input no image? then only color operation */
88         if(in[0]->data==NULL) {
89                 float y, cb, cr;
90         
91                 switch(node->custom1)
92                 {
93                 case 1:
94                         rgb_to_ycc(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &y, &cb, &cr, BLI_YCC_ITU_BT709);
95                         break;
96                 case 2:
97                         rgb_to_ycc(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &y, &cb, &cr, BLI_YCC_JFIF_0_255);
98                         break;
99                 case 0:
100                 default:
101                         rgb_to_ycc(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &y, &cb, &cr, BLI_YCC_ITU_BT601);
102                         break;
103                 }
104         
105                 /*divided by 255 to normalize for viewing in */
106                 out[0]->vec[0] = y/255.0;
107                 out[1]->vec[0] = cb/255.0;
108                 out[2]->vec[0] = cr/255.0;
109                 out[3]->vec[0] = in[0]->vec[3];
110         }
111         else if ((out[0]->hasoutput) || (out[1]->hasoutput) || (out[2]->hasoutput) || (out[3]->hasoutput)) {
112                 /* make copy of buffer so input buffer doesn't get corrupted */
113                 CompBuf *cbuf= dupalloc_compbuf(in[0]->data);
114                 CompBuf *cbuf2=typecheck_compbuf(cbuf, CB_RGBA);
115         
116                 /* convert the RGB stackbuf to an HSV representation */
117                 switch(node->custom1)
118                 {
119                 case 1:
120                         composit1_pixel_processor(node, cbuf2, cbuf2, in[0]->vec, do_sepycca_709, CB_RGBA);
121                         break;
122                 case 2:
123                         composit1_pixel_processor(node, cbuf2, cbuf2, in[0]->vec, do_sepycca_jfif, CB_RGBA);
124                         break;
125                 case 0:
126                 default:
127                         composit1_pixel_processor(node, cbuf2, cbuf2, in[0]->vec, do_sepycca_601, CB_RGBA);
128                         break;
129                 }
130         
131                 /* separate each of those channels */
132                 if(out[0]->hasoutput)
133                         out[0]->data= valbuf_from_rgbabuf(cbuf2, CHAN_R);
134                 if(out[1]->hasoutput)
135                         out[1]->data= valbuf_from_rgbabuf(cbuf2, CHAN_G);
136                 if(out[2]->hasoutput)
137                         out[2]->data= valbuf_from_rgbabuf(cbuf2, CHAN_B);
138                 if(out[3]->hasoutput)
139                         out[3]->data= valbuf_from_rgbabuf(cbuf2, CHAN_A);
140
141                 /*not used anymore */
142                 if(cbuf2!=cbuf)
143                         free_compbuf(cbuf2);
144                 free_compbuf(cbuf);
145         }
146 }
147
148 void register_node_type_cmp_sepycca(ListBase *lb)
149 {
150         static bNodeType ntype;
151
152         node_type_base(&ntype, CMP_NODE_SEPYCCA, "Separate YCbCrA", NODE_CLASS_CONVERTOR, NODE_OPTIONS,
153                 cmp_node_sepycca_in, cmp_node_sepycca_out);
154         node_type_size(&ntype, 80, 40, 140);
155         node_type_exec(&ntype, node_composit_exec_sepycca);
156
157         nodeRegisterType(lb, &ntype);
158 }
159
160
161
162 /* **************** COMBINE YCCA ******************** */
163 static bNodeSocketType cmp_node_combycca_in[]= {
164         {       SOCK_VALUE, 1, "Y",                     0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
165         {       SOCK_VALUE, 1, "Cb",                    0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
166         {       SOCK_VALUE, 1, "Cr",                    0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
167         {       SOCK_VALUE, 1, "A",                     1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
168         {       -1, 0, ""       }
169 };
170 static bNodeSocketType cmp_node_combycca_out[]= {
171         {       SOCK_RGBA, 0, "Image",                  0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
172         {       -1, 0, ""       }
173 };
174
175 static void do_comb_ycca_601(bNode *UNUSED(node), float *out, float *in1, float *in2, float *in3, float *in4)
176 {
177         float r,g,b;
178         float y, cb, cr;
179
180         /*need to un-normalize the data*/
181         y=in1[0]*255;
182         cb=in2[0]*255;
183         cr=in3[0]*255;
184
185         ycc_to_rgb(y,cb,cr, &r, &g, &b, BLI_YCC_ITU_BT601);
186         
187         out[0] = r;
188         out[1] = g;
189         out[2] = b;
190         out[3] = in4[0];
191 }
192
193 static void do_comb_ycca_709(bNode *UNUSED(node), float *out, float *in1, float *in2, float *in3, float *in4)
194 {
195         float r,g,b;
196         float y, cb, cr;
197
198         /*need to un-normalize the data*/
199         y=in1[0]*255;
200         cb=in2[0]*255;
201         cr=in3[0]*255;
202
203         ycc_to_rgb(y,cb,cr, &r, &g, &b, BLI_YCC_ITU_BT709);
204         
205         out[0] = r;
206         out[1] = g;
207         out[2] = b;
208         out[3] = in4[0];
209 }
210
211 static void do_comb_ycca_jfif(bNode *UNUSED(node), float *out, float *in1, float *in2, float *in3, float *in4)
212 {
213         float r,g,b;
214         float y, cb, cr;
215
216         /*need to un-normalize the data*/
217         y=in1[0]*255;
218         cb=in2[0]*255;
219         cr=in3[0]*255;
220
221         ycc_to_rgb(y,cb,cr, &r, &g, &b, BLI_YCC_JFIF_0_255);
222         
223         out[0] = r;
224         out[1] = g;
225         out[2] = b;
226         out[3] = in4[0];
227 }
228
229 static void node_composit_exec_combycca(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
230 {
231         /* stack order out: 1 ycca channels */
232         /* stack order in: 4 value channels */
233         
234         /* input no image? then only color operation */
235         if((in[0]->data==NULL) && (in[1]->data==NULL) && (in[2]->data==NULL) && (in[3]->data==NULL)) {
236                 float y = in[0]->vec[0] * 255;
237                 float cb = in[1]->vec[0] * 255;
238                 float cr = in[2]->vec[0] * 255;
239                 
240                 switch(node->custom1)
241                 {
242                 case 1:
243                         ycc_to_rgb(y, cb, cr, &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2], BLI_YCC_ITU_BT709);
244                         break;
245                 case 2:
246                         ycc_to_rgb(y, cb, cr, &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2], BLI_YCC_JFIF_0_255);
247                         break;
248                 case 0:
249                 default:
250                         ycc_to_rgb(y, cb, cr, &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2], BLI_YCC_ITU_BT601);
251                         break;
252                 }
253                 
254                 out[0]->vec[3] = in[3]->vec[0];
255         }
256         else {
257                 /* make output size of first available input image */
258                 CompBuf *cbuf;
259                 CompBuf *stackbuf;
260
261                 /* allocate a CompBuf the size of the first available input */
262                 if (in[0]->data) cbuf = in[0]->data;
263                 else if (in[1]->data) cbuf = in[1]->data;
264                 else if (in[2]->data) cbuf = in[2]->data;
265                 else cbuf = in[3]->data;
266                 
267                 stackbuf = alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
268                 
269                 
270                 switch(node->custom1)
271                 {
272                 case 1:
273                         composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, 
274                                                   in[2]->data, in[2]->vec, in[3]->data, in[3]->vec, 
275                                                   do_comb_ycca_709, CB_VAL, CB_VAL, CB_VAL, CB_VAL);
276                         break;
277                 
278                 case 2:
279                         composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, 
280                                                   in[2]->data, in[2]->vec, in[3]->data, in[3]->vec, 
281                                                   do_comb_ycca_jfif, CB_VAL, CB_VAL, CB_VAL, CB_VAL);
282                         break;
283                 case 0:
284                 default:
285                         composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, 
286                                                   in[2]->data, in[2]->vec, in[3]->data, in[3]->vec, 
287                                                   do_comb_ycca_601, CB_VAL, CB_VAL, CB_VAL, CB_VAL);
288                         break;
289                 }
290
291                 out[0]->data= stackbuf;
292         }       
293 }
294
295 void register_node_type_cmp_combycca(ListBase *lb)
296 {
297         static bNodeType ntype;
298
299         node_type_base(&ntype, CMP_NODE_COMBYCCA, "Combine YCbCrA", NODE_CLASS_CONVERTOR, NODE_OPTIONS,
300                 cmp_node_combycca_in, cmp_node_combycca_out);
301         node_type_size(&ntype, 80, 40, 140);
302         node_type_exec(&ntype, node_composit_exec_combycca);
303
304         nodeRegisterType(lb, &ntype);
305 }
306
307
308