|
Blender
V2.59
|
00001 /* 00002 * $Id: CMP_colorSpill.c 36276 2011-04-21 15:53:30Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2006 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): Bob Holcomb, Xavier Thomas 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00036 #include "../CMP_util.h" 00037 00038 #define avg(a,b) ((a+b)/2) 00039 00040 /* ******************* Color Spill Supression ********************************* */ 00041 static bNodeSocketType cmp_node_color_spill_in[]={ 00042 {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, 00043 {SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, 00044 {-1,0,""} 00045 }; 00046 00047 static bNodeSocketType cmp_node_color_spill_out[]={ 00048 {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, 00049 {-1,0,""} 00050 }; 00051 00052 static void do_simple_spillmap_red(bNode *node, float* out, float *in) 00053 { 00054 NodeColorspill *ncs; 00055 ncs=node->storage; 00056 out[0]=in[0]-( ncs->limscale * in[ncs->limchan] ); 00057 } 00058 00059 static void do_simple_spillmap_red_fac(bNode *node, float* out, float *in, float *fac) 00060 { 00061 NodeColorspill *ncs; 00062 ncs=node->storage; 00063 00064 out[0] = *fac * (in[0]-( ncs->limscale * in[ncs->limchan])); 00065 } 00066 00067 static void do_simple_spillmap_green(bNode *node, float* out, float *in) 00068 { 00069 NodeColorspill *ncs; 00070 ncs=node->storage; 00071 out[0]=in[1]-( ncs->limscale * in[ncs->limchan] ); 00072 } 00073 00074 static void do_simple_spillmap_green_fac(bNode *node, float* out, float *in, float *fac) 00075 { 00076 NodeColorspill *ncs; 00077 ncs=node->storage; 00078 00079 out[0] = *fac * (in[1]-( ncs->limscale * in[ncs->limchan])); 00080 } 00081 00082 static void do_simple_spillmap_blue(bNode *node, float* out, float *in) 00083 { 00084 NodeColorspill *ncs; 00085 ncs=node->storage; 00086 out[0]=in[2]-( ncs->limscale * in[ncs->limchan] ); 00087 } 00088 00089 static void do_simple_spillmap_blue_fac(bNode *node, float* out, float *in, float *fac) 00090 { 00091 NodeColorspill *ncs; 00092 ncs=node->storage; 00093 00094 out[0] = *fac * (in[2]-( ncs->limscale * in[ncs->limchan])); 00095 } 00096 00097 static void do_average_spillmap_red(bNode *node, float* out, float *in) 00098 { 00099 NodeColorspill *ncs; 00100 ncs=node->storage; 00101 out[0]=in[0]-(ncs->limscale * avg(in[1], in[2]) ); 00102 } 00103 00104 static void do_average_spillmap_red_fac(bNode *node, float* out, float *in, float *fac) 00105 { 00106 NodeColorspill *ncs; 00107 ncs=node->storage; 00108 00109 out[0] = *fac * (in[0]-(ncs->limscale * avg(in[1], in[2]) )); 00110 } 00111 00112 static void do_average_spillmap_green(bNode *node, float* out, float *in) 00113 { 00114 NodeColorspill *ncs; 00115 ncs=node->storage; 00116 out[0]=in[1]-(ncs->limscale * avg(in[0], in[2]) ); 00117 } 00118 00119 static void do_average_spillmap_green_fac(bNode *node, float* out, float *in, float *fac) 00120 { 00121 NodeColorspill *ncs; 00122 ncs=node->storage; 00123 00124 out[0] = *fac * (in[0]-(ncs->limscale * avg(in[0], in[2]) )); 00125 } 00126 00127 static void do_average_spillmap_blue(bNode *node, float* out, float *in) 00128 { 00129 NodeColorspill *ncs; 00130 ncs=node->storage; 00131 out[0]=in[2]-(ncs->limscale * avg(in[0], in[1]) ); 00132 } 00133 00134 static void do_average_spillmap_blue_fac(bNode *node, float* out, float *in, float *fac) 00135 { 00136 NodeColorspill *ncs; 00137 ncs=node->storage; 00138 00139 out[0] = *fac * (in[0]-(ncs->limscale * avg(in[0], in[1]) )); 00140 } 00141 00142 static void do_apply_spillmap_red(bNode *node, float* out, float *in, float *map) 00143 { 00144 NodeColorspill *ncs; 00145 ncs=node->storage; 00146 if(map[0]>0) { 00147 out[0]=in[0]-(ncs->uspillr*map[0]); 00148 out[1]=in[1]+(ncs->uspillg*map[0]); 00149 out[2]=in[2]+(ncs->uspillb*map[0]); 00150 } 00151 else { 00152 out[0]=in[0]; 00153 out[1]=in[1]; 00154 out[2]=in[2]; 00155 } 00156 } 00157 00158 static void do_apply_spillmap_green(bNode *node, float* out, float *in, float *map) 00159 { 00160 NodeColorspill *ncs; 00161 ncs=node->storage; 00162 if(map[0]>0) { 00163 out[0]=in[0]+(ncs->uspillr*map[0]); 00164 out[1]=in[1]-(ncs->uspillg*map[0]); 00165 out[2]=in[2]+(ncs->uspillb*map[0]); 00166 } 00167 else { 00168 out[0]=in[0]; 00169 out[1]=in[1]; 00170 out[2]=in[2]; 00171 } 00172 } 00173 00174 static void do_apply_spillmap_blue(bNode *node, float* out, float *in, float *map) 00175 { 00176 NodeColorspill *ncs; 00177 ncs=node->storage; 00178 if(map[0]>0) { 00179 out[0]=in[0]+(ncs->uspillr*map[0]); 00180 out[1]=in[1]+(ncs->uspillg*map[0]); 00181 out[2]=in[2]-(ncs->uspillb*map[0]); 00182 } 00183 else { 00184 out[0]=in[0]; 00185 out[1]=in[1]; 00186 out[2]=in[2]; 00187 } 00188 } 00189 00190 static void node_composit_exec_color_spill(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) 00191 { 00192 /* Originally based on the information from the book "The Art and Science of Digital Composition" and 00193 * discussions from vfxtalk.com .*/ 00194 CompBuf *cbuf; 00195 CompBuf *mask; 00196 CompBuf *rgbbuf; 00197 CompBuf *spillmap; 00198 NodeColorspill *ncs; 00199 ncs=node->storage; 00200 00201 /* early out for missing connections */ 00202 if(out[0]->hasoutput==0 ) return; 00203 if(in[0]->hasinput==0) return; 00204 if(in[0]->data==NULL) return; 00205 00206 cbuf=typecheck_compbuf(in[0]->data, CB_RGBA); 00207 mask=typecheck_compbuf(in[1]->data, CB_VAL); 00208 spillmap=alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); 00209 rgbbuf=dupalloc_compbuf(cbuf); 00210 00211 switch(node->custom1) 00212 { 00213 case 1: /*red spill*/ 00214 { 00215 switch(node->custom2) 00216 { 00217 case 0: /* simple limit */ 00218 { 00219 if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) { 00220 composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_simple_spillmap_red, CB_RGBA); 00221 } else { 00222 composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_simple_spillmap_red_fac, CB_RGBA, CB_VAL); 00223 } 00224 break; 00225 } 00226 case 1: /* average limit */ 00227 { 00228 if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) { 00229 composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_average_spillmap_red, CB_RGBA); 00230 } else { 00231 composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_average_spillmap_red_fac, CB_RGBA, CB_VAL); 00232 } 00233 break; 00234 } 00235 } 00236 if(ncs->unspill==0) { 00237 ncs->uspillr=1.0f; 00238 ncs->uspillg=0.0f; 00239 ncs->uspillb=0.0f; 00240 } 00241 composit2_pixel_processor(node, rgbbuf, cbuf, in[0]->vec, spillmap, NULL, do_apply_spillmap_red, CB_RGBA, CB_VAL); 00242 break; 00243 } 00244 case 2: /*green spill*/ 00245 { 00246 switch(node->custom2) 00247 { 00248 case 0: /* simple limit */ 00249 { 00250 if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) { 00251 composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_simple_spillmap_green, CB_RGBA); 00252 } else { 00253 composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_simple_spillmap_green_fac, CB_RGBA, CB_VAL); 00254 } 00255 break; 00256 } 00257 case 1: /* average limit */ 00258 { 00259 if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) { 00260 composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_average_spillmap_green, CB_RGBA); 00261 } else { 00262 composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_average_spillmap_green_fac, CB_RGBA, CB_VAL); 00263 } 00264 break; 00265 } 00266 } 00267 if(ncs->unspill==0) { 00268 ncs->uspillr=0.0f; 00269 ncs->uspillg=1.0f; 00270 ncs->uspillb=0.0f; 00271 } 00272 composit2_pixel_processor(node, rgbbuf, cbuf, in[0]->vec, spillmap, NULL, do_apply_spillmap_green, CB_RGBA, CB_VAL); 00273 break; 00274 } 00275 case 3: /*blue spill*/ 00276 { 00277 switch(node->custom2) 00278 { 00279 case 0: /* simple limit */ 00280 { 00281 if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) { 00282 composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_simple_spillmap_blue, CB_RGBA); 00283 } else { 00284 composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_simple_spillmap_blue_fac, CB_RGBA, CB_VAL); 00285 } 00286 break; 00287 } 00288 case 1: /* average limit */ 00289 { 00290 if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) { 00291 composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_average_spillmap_blue, CB_RGBA); 00292 } else { 00293 composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_average_spillmap_blue_fac, CB_RGBA, CB_VAL); 00294 } 00295 break; 00296 } 00297 } 00298 if(ncs->unspill==0) { 00299 ncs->uspillr=0.0f; 00300 ncs->uspillg=0.0f; 00301 ncs->uspillb=1.0f; 00302 } 00303 composit2_pixel_processor(node, rgbbuf, cbuf, in[0]->vec, spillmap, NULL, do_apply_spillmap_blue, CB_RGBA, CB_VAL); 00304 break; 00305 } 00306 default: 00307 break; 00308 } 00309 00310 out[0]->data=rgbbuf; 00311 00312 if(cbuf!=in[0]->data) 00313 free_compbuf(cbuf); 00314 00315 free_compbuf(spillmap); 00316 } 00317 00318 static void node_composit_init_color_spill(bNode *node) 00319 { 00320 NodeColorspill *ncs= MEM_callocN(sizeof(NodeColorspill), "node colorspill"); 00321 node->storage=ncs; 00322 node->custom1= 2; /* green channel */ 00323 node->custom2= 0; /* simple limit algo*/ 00324 ncs->limchan= 0; /* limit by red */ 00325 ncs->limscale= 1.0f; /* limit scaling factor */ 00326 ncs->unspill=0; /* do not use unspill */ 00327 } 00328 00329 void register_node_type_cmp_color_spill(ListBase *lb) 00330 { 00331 static bNodeType ntype; 00332 00333 node_type_base(&ntype, CMP_NODE_COLOR_SPILL, "Color Spill", NODE_CLASS_MATTE, NODE_OPTIONS, 00334 cmp_node_color_spill_in, cmp_node_color_spill_out); 00335 node_type_size(&ntype, 140, 80, 200); 00336 node_type_init(&ntype, node_composit_init_color_spill); 00337 node_type_storage(&ntype, "NodeColorspill", node_free_standard_storage, node_copy_standard_storage); 00338 node_type_exec(&ntype, node_composit_exec_color_spill); 00339 00340 nodeRegisterType(lb, &ntype); 00341 }