Blender V2.61 - r43446
|
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): Bob Holcomb, Xavier Thomas 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00034 #include "node_composite_util.h" 00035 00036 #define avg(a,b) ((a+b)/2) 00037 00038 /* ******************* Color Spill Supression ********************************* */ 00039 static bNodeSocketTemplate cmp_node_color_spill_in[]={ 00040 {SOCK_RGBA,1,"Image", 1.0f, 1.0f, 1.0f, 1.0f}, 00041 {SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, 00042 {-1,0,""} 00043 }; 00044 00045 static bNodeSocketTemplate cmp_node_color_spill_out[]={ 00046 {SOCK_RGBA,0,"Image"}, 00047 {-1,0,""} 00048 }; 00049 00050 static void do_simple_spillmap_red(bNode *node, float* out, float *in) 00051 { 00052 NodeColorspill *ncs; 00053 ncs=node->storage; 00054 out[0]=in[0]-( ncs->limscale * in[ncs->limchan] ); 00055 } 00056 00057 static void do_simple_spillmap_red_fac(bNode *node, float* out, float *in, float *fac) 00058 { 00059 NodeColorspill *ncs; 00060 ncs=node->storage; 00061 00062 out[0] = *fac * (in[0]-( ncs->limscale * in[ncs->limchan])); 00063 } 00064 00065 static void do_simple_spillmap_green(bNode *node, float* out, float *in) 00066 { 00067 NodeColorspill *ncs; 00068 ncs=node->storage; 00069 out[0]=in[1]-( ncs->limscale * in[ncs->limchan] ); 00070 } 00071 00072 static void do_simple_spillmap_green_fac(bNode *node, float* out, float *in, float *fac) 00073 { 00074 NodeColorspill *ncs; 00075 ncs=node->storage; 00076 00077 out[0] = *fac * (in[1]-( ncs->limscale * in[ncs->limchan])); 00078 } 00079 00080 static void do_simple_spillmap_blue(bNode *node, float* out, float *in) 00081 { 00082 NodeColorspill *ncs; 00083 ncs=node->storage; 00084 out[0]=in[2]-( ncs->limscale * in[ncs->limchan] ); 00085 } 00086 00087 static void do_simple_spillmap_blue_fac(bNode *node, float* out, float *in, float *fac) 00088 { 00089 NodeColorspill *ncs; 00090 ncs=node->storage; 00091 00092 out[0] = *fac * (in[2]-( ncs->limscale * in[ncs->limchan])); 00093 } 00094 00095 static void do_average_spillmap_red(bNode *node, float* out, float *in) 00096 { 00097 NodeColorspill *ncs; 00098 ncs=node->storage; 00099 out[0]=in[0]-(ncs->limscale * avg(in[1], in[2]) ); 00100 } 00101 00102 static void do_average_spillmap_red_fac(bNode *node, float* out, float *in, float *fac) 00103 { 00104 NodeColorspill *ncs; 00105 ncs=node->storage; 00106 00107 out[0] = *fac * (in[0]-(ncs->limscale * avg(in[1], in[2]) )); 00108 } 00109 00110 static void do_average_spillmap_green(bNode *node, float* out, float *in) 00111 { 00112 NodeColorspill *ncs; 00113 ncs=node->storage; 00114 out[0]=in[1]-(ncs->limscale * avg(in[0], in[2]) ); 00115 } 00116 00117 static void do_average_spillmap_green_fac(bNode *node, float* out, float *in, float *fac) 00118 { 00119 NodeColorspill *ncs; 00120 ncs=node->storage; 00121 00122 out[0] = *fac * (in[0]-(ncs->limscale * avg(in[0], in[2]) )); 00123 } 00124 00125 static void do_average_spillmap_blue(bNode *node, float* out, float *in) 00126 { 00127 NodeColorspill *ncs; 00128 ncs=node->storage; 00129 out[0]=in[2]-(ncs->limscale * avg(in[0], in[1]) ); 00130 } 00131 00132 static void do_average_spillmap_blue_fac(bNode *node, float* out, float *in, float *fac) 00133 { 00134 NodeColorspill *ncs; 00135 ncs=node->storage; 00136 00137 out[0] = *fac * (in[0]-(ncs->limscale * avg(in[0], in[1]) )); 00138 } 00139 00140 static void do_apply_spillmap_red(bNode *node, float* out, float *in, float *map) 00141 { 00142 NodeColorspill *ncs; 00143 ncs=node->storage; 00144 if(map[0]>0) { 00145 out[0]=in[0]-(ncs->uspillr*map[0]); 00146 out[1]=in[1]+(ncs->uspillg*map[0]); 00147 out[2]=in[2]+(ncs->uspillb*map[0]); 00148 } 00149 else { 00150 out[0]=in[0]; 00151 out[1]=in[1]; 00152 out[2]=in[2]; 00153 } 00154 } 00155 00156 static void do_apply_spillmap_green(bNode *node, float* out, float *in, float *map) 00157 { 00158 NodeColorspill *ncs; 00159 ncs=node->storage; 00160 if(map[0]>0) { 00161 out[0]=in[0]+(ncs->uspillr*map[0]); 00162 out[1]=in[1]-(ncs->uspillg*map[0]); 00163 out[2]=in[2]+(ncs->uspillb*map[0]); 00164 } 00165 else { 00166 out[0]=in[0]; 00167 out[1]=in[1]; 00168 out[2]=in[2]; 00169 } 00170 } 00171 00172 static void do_apply_spillmap_blue(bNode *node, float* out, float *in, float *map) 00173 { 00174 NodeColorspill *ncs; 00175 ncs=node->storage; 00176 if(map[0]>0) { 00177 out[0]=in[0]+(ncs->uspillr*map[0]); 00178 out[1]=in[1]+(ncs->uspillg*map[0]); 00179 out[2]=in[2]-(ncs->uspillb*map[0]); 00180 } 00181 else { 00182 out[0]=in[0]; 00183 out[1]=in[1]; 00184 out[2]=in[2]; 00185 } 00186 } 00187 00188 static void node_composit_exec_color_spill(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) 00189 { 00190 /* Originally based on the information from the book "The Art and Science of Digital Composition" and 00191 * discussions from vfxtalk.com .*/ 00192 CompBuf *cbuf; 00193 /* CompBuf *mask; */ /* UNUSED */ 00194 CompBuf *rgbbuf; 00195 CompBuf *spillmap; 00196 NodeColorspill *ncs; 00197 ncs=node->storage; 00198 00199 /* early out for missing connections */ 00200 if(out[0]->hasoutput==0 ) return; 00201 if(in[0]->hasinput==0) return; 00202 if(in[0]->data==NULL) return; 00203 00204 cbuf=typecheck_compbuf(in[0]->data, CB_RGBA); 00205 /* mask= */ /* UNUSED */ typecheck_compbuf(in[1]->data, CB_VAL); 00206 spillmap=alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); 00207 rgbbuf=dupalloc_compbuf(cbuf); 00208 00209 switch(node->custom1) 00210 { 00211 case 1: /*red spill*/ 00212 { 00213 switch(node->custom2) 00214 { 00215 case 0: /* simple limit */ 00216 { 00217 if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) { 00218 composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_simple_spillmap_red, CB_RGBA); 00219 } else { 00220 composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_simple_spillmap_red_fac, CB_RGBA, CB_VAL); 00221 } 00222 break; 00223 } 00224 case 1: /* average limit */ 00225 { 00226 if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) { 00227 composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_average_spillmap_red, CB_RGBA); 00228 } else { 00229 composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_average_spillmap_red_fac, CB_RGBA, CB_VAL); 00230 } 00231 break; 00232 } 00233 } 00234 if(ncs->unspill==0) { 00235 ncs->uspillr=1.0f; 00236 ncs->uspillg=0.0f; 00237 ncs->uspillb=0.0f; 00238 } 00239 composit2_pixel_processor(node, rgbbuf, cbuf, in[0]->vec, spillmap, NULL, do_apply_spillmap_red, CB_RGBA, CB_VAL); 00240 break; 00241 } 00242 case 2: /*green spill*/ 00243 { 00244 switch(node->custom2) 00245 { 00246 case 0: /* simple limit */ 00247 { 00248 if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) { 00249 composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_simple_spillmap_green, CB_RGBA); 00250 } else { 00251 composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_simple_spillmap_green_fac, CB_RGBA, CB_VAL); 00252 } 00253 break; 00254 } 00255 case 1: /* average limit */ 00256 { 00257 if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) { 00258 composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_average_spillmap_green, CB_RGBA); 00259 } else { 00260 composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_average_spillmap_green_fac, CB_RGBA, CB_VAL); 00261 } 00262 break; 00263 } 00264 } 00265 if(ncs->unspill==0) { 00266 ncs->uspillr=0.0f; 00267 ncs->uspillg=1.0f; 00268 ncs->uspillb=0.0f; 00269 } 00270 composit2_pixel_processor(node, rgbbuf, cbuf, in[0]->vec, spillmap, NULL, do_apply_spillmap_green, CB_RGBA, CB_VAL); 00271 break; 00272 } 00273 case 3: /*blue spill*/ 00274 { 00275 switch(node->custom2) 00276 { 00277 case 0: /* simple limit */ 00278 { 00279 if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) { 00280 composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_simple_spillmap_blue, CB_RGBA); 00281 } else { 00282 composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_simple_spillmap_blue_fac, CB_RGBA, CB_VAL); 00283 } 00284 break; 00285 } 00286 case 1: /* average limit */ 00287 { 00288 if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) { 00289 composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_average_spillmap_blue, CB_RGBA); 00290 } else { 00291 composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_average_spillmap_blue_fac, CB_RGBA, CB_VAL); 00292 } 00293 break; 00294 } 00295 } 00296 if(ncs->unspill==0) { 00297 ncs->uspillr=0.0f; 00298 ncs->uspillg=0.0f; 00299 ncs->uspillb=1.0f; 00300 } 00301 composit2_pixel_processor(node, rgbbuf, cbuf, in[0]->vec, spillmap, NULL, do_apply_spillmap_blue, CB_RGBA, CB_VAL); 00302 break; 00303 } 00304 default: 00305 break; 00306 } 00307 00308 out[0]->data=rgbbuf; 00309 00310 if(cbuf!=in[0]->data) 00311 free_compbuf(cbuf); 00312 00313 free_compbuf(spillmap); 00314 } 00315 00316 static void node_composit_init_color_spill(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) 00317 { 00318 NodeColorspill *ncs= MEM_callocN(sizeof(NodeColorspill), "node colorspill"); 00319 node->storage=ncs; 00320 node->custom1= 2; /* green channel */ 00321 node->custom2= 0; /* simple limit algo*/ 00322 ncs->limchan= 0; /* limit by red */ 00323 ncs->limscale= 1.0f; /* limit scaling factor */ 00324 ncs->unspill=0; /* do not use unspill */ 00325 } 00326 00327 void register_node_type_cmp_color_spill(bNodeTreeType *ttype) 00328 { 00329 static bNodeType ntype; 00330 00331 node_type_base(ttype, &ntype, CMP_NODE_COLOR_SPILL, "Color Spill", NODE_CLASS_MATTE, NODE_OPTIONS); 00332 node_type_socket_templates(&ntype, cmp_node_color_spill_in, cmp_node_color_spill_out); 00333 node_type_size(&ntype, 140, 80, 200); 00334 node_type_init(&ntype, node_composit_init_color_spill); 00335 node_type_storage(&ntype, "NodeColorspill", node_free_standard_storage, node_copy_standard_storage); 00336 node_type_exec(&ntype, node_composit_exec_color_spill); 00337 00338 nodeRegisterType(ttype, &ntype); 00339 }