Blender V2.61 - r43446

node_composite_sepcombYCCA.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version. 
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2006 Blender Foundation.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include "node_composite_util.h"
00034 
00035 
00036 /* **************** SEPARATE YCCA ******************** */
00037 static bNodeSocketTemplate cmp_node_sepycca_in[]= {
00038     {  SOCK_RGBA, 1, "Image",        1.0f, 1.0f, 1.0f, 1.0f},
00039     {  -1, 0, ""   }
00040 };
00041 static bNodeSocketTemplate cmp_node_sepycca_out[]= {
00042     {  SOCK_FLOAT, 0, "Y"},
00043     {  SOCK_FLOAT, 0, "Cb"},
00044     {  SOCK_FLOAT, 0, "Cr"},
00045     {  SOCK_FLOAT, 0, "A"},
00046     {  -1, 0, ""   }
00047 };
00048 
00049 static void do_sepycca_601(bNode *UNUSED(node), float *out, float *in)
00050 {
00051     float y, cb, cr;
00052     
00053     rgb_to_ycc(in[0], in[1], in[2], &y, &cb, &cr, BLI_YCC_ITU_BT601);
00054     
00055     /*divided by 255 to normalize for viewing in */
00056     out[0]=  y/255.0f;
00057     out[1]= cb/255.0f;
00058     out[2]= cr/255.0f;
00059     out[3]= in[3];
00060 }
00061 
00062 static void do_sepycca_709(bNode *UNUSED(node), float *out, float *in)
00063 {
00064     float y, cb, cr;
00065     
00066     rgb_to_ycc(in[0], in[1], in[2], &y, &cb, &cr, BLI_YCC_ITU_BT709);
00067     
00068     /*divided by 255 to normalize for viewing in */
00069     out[0]=  y/255.0f;
00070     out[1]= cb/255.0f;
00071     out[2]= cr/255.0f;
00072     out[3]= in[3];
00073 }
00074 
00075 static void do_sepycca_jfif(bNode *UNUSED(node), float *out, float *in)
00076 {
00077     float y, cb, cr;
00078     
00079     rgb_to_ycc(in[0], in[1], in[2], &y, &cb, &cr, BLI_YCC_JFIF_0_255);
00080     
00081     /*divided by 255 to normalize for viewing in */
00082     out[0]=  y/255.0f;
00083     out[1]= cb/255.0f;
00084     out[2]= cr/255.0f;
00085     out[3]= in[3];
00086 }
00087 
00088 static void node_composit_exec_sepycca(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
00089 {
00090     /* input no image? then only color operation */
00091     if(in[0]->data==NULL) {
00092         float y, cb, cr;
00093     
00094         switch(node->custom1)
00095         {
00096         case 1:
00097             rgb_to_ycc(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &y, &cb, &cr, BLI_YCC_ITU_BT709);
00098             break;
00099         case 2:
00100             rgb_to_ycc(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &y, &cb, &cr, BLI_YCC_JFIF_0_255);
00101             break;
00102         case 0:
00103         default:
00104             rgb_to_ycc(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &y, &cb, &cr, BLI_YCC_ITU_BT601);
00105             break;
00106         }
00107     
00108         /*divided by 255 to normalize for viewing in */
00109         out[0]->vec[0] =  y/255.0f;
00110         out[1]->vec[0] = cb/255.0f;
00111         out[2]->vec[0] = cr/255.0f;
00112         out[3]->vec[0] = in[0]->vec[3];
00113     }
00114     else if ((out[0]->hasoutput) || (out[1]->hasoutput) || (out[2]->hasoutput) || (out[3]->hasoutput)) {
00115         /* make copy of buffer so input buffer doesn't get corrupted */
00116         CompBuf *cbuf= dupalloc_compbuf(in[0]->data);
00117         CompBuf *cbuf2=typecheck_compbuf(cbuf, CB_RGBA);
00118     
00119         /* convert the RGB stackbuf to an HSV representation */
00120         switch(node->custom1)
00121         {
00122         case 1:
00123             composit1_pixel_processor(node, cbuf2, cbuf2, in[0]->vec, do_sepycca_709, CB_RGBA);
00124             break;
00125         case 2:
00126             composit1_pixel_processor(node, cbuf2, cbuf2, in[0]->vec, do_sepycca_jfif, CB_RGBA);
00127             break;
00128         case 0:
00129         default:
00130             composit1_pixel_processor(node, cbuf2, cbuf2, in[0]->vec, do_sepycca_601, CB_RGBA);
00131             break;
00132         }
00133     
00134         /* separate each of those channels */
00135         if(out[0]->hasoutput)
00136             out[0]->data= valbuf_from_rgbabuf(cbuf2, CHAN_R);
00137         if(out[1]->hasoutput)
00138             out[1]->data= valbuf_from_rgbabuf(cbuf2, CHAN_G);
00139         if(out[2]->hasoutput)
00140             out[2]->data= valbuf_from_rgbabuf(cbuf2, CHAN_B);
00141         if(out[3]->hasoutput)
00142             out[3]->data= valbuf_from_rgbabuf(cbuf2, CHAN_A);
00143 
00144         /*not used anymore */
00145         if(cbuf2!=cbuf)
00146             free_compbuf(cbuf2);
00147         free_compbuf(cbuf);
00148     }
00149 }
00150 
00151 void register_node_type_cmp_sepycca(bNodeTreeType *ttype)
00152 {
00153     static bNodeType ntype;
00154 
00155     node_type_base(ttype, &ntype, CMP_NODE_SEPYCCA, "Separate YCbCrA", NODE_CLASS_CONVERTOR, NODE_OPTIONS);
00156     node_type_socket_templates(&ntype, cmp_node_sepycca_in, cmp_node_sepycca_out);
00157     node_type_size(&ntype, 80, 40, 140);
00158     node_type_exec(&ntype, node_composit_exec_sepycca);
00159 
00160     nodeRegisterType(ttype, &ntype);
00161 }
00162 
00163 
00164 
00165 /* **************** COMBINE YCCA ******************** */
00166 static bNodeSocketTemplate cmp_node_combycca_in[]= {
00167     {   SOCK_FLOAT, 1, "Y",         0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
00168     {   SOCK_FLOAT, 1, "Cb",            0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
00169     {   SOCK_FLOAT, 1, "Cr",            0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
00170     {   SOCK_FLOAT, 1, "A",         1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
00171     {   -1, 0, ""   }
00172 };
00173 static bNodeSocketTemplate cmp_node_combycca_out[]= {
00174     {   SOCK_RGBA, 0, "Image"},
00175     {   -1, 0, ""   }
00176 };
00177 
00178 static void do_comb_ycca_601(bNode *UNUSED(node), float *out, float *in1, float *in2, float *in3, float *in4)
00179 {
00180     float r,g,b;
00181     float y, cb, cr;
00182 
00183     /*need to un-normalize the data*/
00184     y=in1[0]*255;
00185     cb=in2[0]*255;
00186     cr=in3[0]*255;
00187 
00188     ycc_to_rgb(y,cb,cr, &r, &g, &b, BLI_YCC_ITU_BT601);
00189     
00190     out[0] = r;
00191     out[1] = g;
00192     out[2] = b;
00193     out[3] = in4[0];
00194 }
00195 
00196 static void do_comb_ycca_709(bNode *UNUSED(node), float *out, float *in1, float *in2, float *in3, float *in4)
00197 {
00198     float r,g,b;
00199     float y, cb, cr;
00200 
00201     /*need to un-normalize the data*/
00202     y=in1[0]*255;
00203     cb=in2[0]*255;
00204     cr=in3[0]*255;
00205 
00206     ycc_to_rgb(y,cb,cr, &r, &g, &b, BLI_YCC_ITU_BT709);
00207     
00208     out[0] = r;
00209     out[1] = g;
00210     out[2] = b;
00211     out[3] = in4[0];
00212 }
00213 
00214 static void do_comb_ycca_jfif(bNode *UNUSED(node), float *out, float *in1, float *in2, float *in3, float *in4)
00215 {
00216     float r,g,b;
00217     float y, cb, cr;
00218 
00219     /*need to un-normalize the data*/
00220     y=in1[0]*255;
00221     cb=in2[0]*255;
00222     cr=in3[0]*255;
00223 
00224     ycc_to_rgb(y,cb,cr, &r, &g, &b, BLI_YCC_JFIF_0_255);
00225     
00226     out[0] = r;
00227     out[1] = g;
00228     out[2] = b;
00229     out[3] = in4[0];
00230 }
00231 
00232 static void node_composit_exec_combycca(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
00233 {
00234     /* stack order out: 1 ycca channels */
00235     /* stack order in: 4 value channels */
00236     
00237     /* input no image? then only color operation */
00238     if((in[0]->data==NULL) && (in[1]->data==NULL) && (in[2]->data==NULL) && (in[3]->data==NULL)) {
00239         float y = in[0]->vec[0] * 255;
00240         float cb = in[1]->vec[0] * 255;
00241         float cr = in[2]->vec[0] * 255;
00242         
00243         switch(node->custom1)
00244         {
00245         case 1:
00246             ycc_to_rgb(y, cb, cr, &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2], BLI_YCC_ITU_BT709);
00247             break;
00248         case 2:
00249             ycc_to_rgb(y, cb, cr, &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2], BLI_YCC_JFIF_0_255);
00250             break;
00251         case 0:
00252         default:
00253             ycc_to_rgb(y, cb, cr, &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2], BLI_YCC_ITU_BT601);
00254             break;
00255         }
00256         
00257         out[0]->vec[3] = in[3]->vec[0];
00258     }
00259     else {
00260         /* make output size of first available input image */
00261         CompBuf *cbuf;
00262         CompBuf *stackbuf;
00263 
00264         /* allocate a CompBuf the size of the first available input */
00265         if (in[0]->data) cbuf = in[0]->data;
00266         else if (in[1]->data) cbuf = in[1]->data;
00267         else if (in[2]->data) cbuf = in[2]->data;
00268         else cbuf = in[3]->data;
00269         
00270         stackbuf = alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
00271         
00272         
00273         switch(node->custom1)
00274         {
00275         case 1:
00276             composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, 
00277                                       in[2]->data, in[2]->vec, in[3]->data, in[3]->vec, 
00278                                       do_comb_ycca_709, CB_VAL, CB_VAL, CB_VAL, CB_VAL);
00279             break;
00280         
00281         case 2:
00282             composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, 
00283                                       in[2]->data, in[2]->vec, in[3]->data, in[3]->vec, 
00284                                       do_comb_ycca_jfif, CB_VAL, CB_VAL, CB_VAL, CB_VAL);
00285             break;
00286         case 0:
00287         default:
00288             composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, 
00289                                       in[2]->data, in[2]->vec, in[3]->data, in[3]->vec, 
00290                                       do_comb_ycca_601, CB_VAL, CB_VAL, CB_VAL, CB_VAL);
00291             break;
00292         }
00293 
00294         out[0]->data= stackbuf;
00295     }   
00296 }
00297 
00298 void register_node_type_cmp_combycca(bNodeTreeType *ttype)
00299 {
00300     static bNodeType ntype;
00301 
00302     node_type_base(ttype, &ntype, CMP_NODE_COMBYCCA, "Combine YCbCrA", NODE_CLASS_CONVERTOR, NODE_OPTIONS);
00303     node_type_socket_templates(&ntype, cmp_node_combycca_in, cmp_node_combycca_out);
00304     node_type_size(&ntype, 80, 40, 140);
00305     node_type_exec(&ntype, node_composit_exec_combycca);
00306 
00307     nodeRegisterType(ttype, &ntype);
00308 }