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): Campbell Barton, Alfredo de Greef, David Millan Escriva, 00024 * Juho Vepsäläinen 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include "node_composite_util.h" 00035 00036 /* **************** BLUR ******************** */ 00037 static bNodeSocketTemplate cmp_node_blur_in[]= { 00038 { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, 00039 { SOCK_FLOAT, 1, "Size", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, 00040 { -1, 0, "" } 00041 }; 00042 static bNodeSocketTemplate cmp_node_blur_out[]= { 00043 { SOCK_RGBA, 0, "Image"}, 00044 { -1, 0, "" } 00045 }; 00046 00047 static float *make_gausstab(int filtertype, int rad) 00048 { 00049 float *gausstab, sum, val; 00050 int i, n; 00051 00052 n = 2 * rad + 1; 00053 00054 gausstab = (float *) MEM_mallocN(n * sizeof(float), "gauss"); 00055 00056 sum = 0.0f; 00057 for (i = -rad; i <= rad; i++) { 00058 val= RE_filter_value(filtertype, (float)i/(float)rad); 00059 sum += val; 00060 gausstab[i+rad] = val; 00061 } 00062 00063 sum= 1.0f/sum; 00064 for(i=0; i<n; i++) 00065 gausstab[i]*= sum; 00066 00067 return gausstab; 00068 } 00069 00070 static float *make_bloomtab(int rad) 00071 { 00072 float *bloomtab, val; 00073 int i, n; 00074 00075 n = 2 * rad + 1; 00076 00077 bloomtab = (float *) MEM_mallocN(n * sizeof(float), "bloom"); 00078 00079 for (i = -rad; i <= rad; i++) { 00080 val = powf(1.0f - fabsf((float)i)/((float)rad), 4.0f); 00081 bloomtab[i+rad] = val; 00082 } 00083 00084 return bloomtab; 00085 } 00086 00087 /* both input images of same type, either 4 or 1 channel */ 00088 static void blur_single_image(bNode *node, CompBuf *new, CompBuf *img, float scale) 00089 { 00090 NodeBlurData *nbd= node->storage; 00091 CompBuf *work; 00092 register float sum, val; 00093 float rval, gval, bval, aval; 00094 float *gausstab, *gausstabcent; 00095 int rad, imgx= img->x, imgy= img->y; 00096 int x, y, pix= img->type; 00097 int i, bigstep; 00098 float *src, *dest; 00099 00100 /* helper image */ 00101 work= alloc_compbuf(imgx, imgy, img->type, 1); /* allocs */ 00102 00103 /* horizontal */ 00104 if(nbd->sizex == 0) { 00105 memcpy(work->rect, img->rect, sizeof(float) * img->type * imgx * imgy); 00106 } 00107 else { 00108 rad = scale*(float)nbd->sizex; 00109 if(rad>imgx/2) 00110 rad= imgx/2; 00111 else if(rad<1) 00112 rad= 1; 00113 00114 gausstab= make_gausstab(nbd->filtertype, rad); 00115 gausstabcent= gausstab+rad; 00116 00117 for (y = 0; y < imgy; y++) { 00118 float *srcd= img->rect + pix*(y*img->x); 00119 00120 dest = work->rect + pix*(y * img->x); 00121 00122 for (x = 0; x < imgx ; x++) { 00123 int minr= x-rad<0?-x:-rad; 00124 int maxr= x+rad>imgx?imgx-x:rad; 00125 00126 src= srcd + pix*(x+minr); 00127 00128 sum= gval = rval= bval= aval= 0.0f; 00129 for (i= minr; i < maxr; i++) { 00130 val= gausstabcent[i]; 00131 sum+= val; 00132 rval += val * (*src++); 00133 if(pix==4) { 00134 gval += val * (*src++); 00135 bval += val * (*src++); 00136 aval += val * (*src++); 00137 } 00138 } 00139 sum= 1.0f/sum; 00140 *dest++ = rval*sum; 00141 if(pix==4) { 00142 *dest++ = gval*sum; 00143 *dest++ = bval*sum; 00144 *dest++ = aval*sum; 00145 } 00146 } 00147 if(node->exec & NODE_BREAK) 00148 break; 00149 } 00150 00151 /* vertical */ 00152 MEM_freeN(gausstab); 00153 } 00154 00155 if(nbd->sizey == 0) { 00156 memcpy(new->rect, work->rect, sizeof(float) * img->type * imgx * imgy); 00157 } 00158 else { 00159 rad = scale*(float)nbd->sizey; 00160 if(rad>imgy/2) 00161 rad= imgy/2; 00162 else if(rad<1) 00163 rad= 1; 00164 00165 gausstab= make_gausstab(nbd->filtertype, rad); 00166 gausstabcent= gausstab+rad; 00167 00168 bigstep = pix*imgx; 00169 for (x = 0; x < imgx; x++) { 00170 float *srcd= work->rect + pix*x; 00171 00172 dest = new->rect + pix*x; 00173 00174 for (y = 0; y < imgy ; y++) { 00175 int minr= y-rad<0?-y:-rad; 00176 int maxr= y+rad>imgy?imgy-y:rad; 00177 00178 src= srcd + bigstep*(y+minr); 00179 00180 sum= gval = rval= bval= aval= 0.0f; 00181 for (i= minr; i < maxr; i++) { 00182 val= gausstabcent[i]; 00183 sum+= val; 00184 rval += val * src[0]; 00185 if(pix==4) { 00186 gval += val * src[1]; 00187 bval += val * src[2]; 00188 aval += val * src[3]; 00189 } 00190 src += bigstep; 00191 } 00192 sum= 1.0f/sum; 00193 dest[0] = rval*sum; 00194 if(pix==4) { 00195 dest[1] = gval*sum; 00196 dest[2] = bval*sum; 00197 dest[3] = aval*sum; 00198 } 00199 dest+= bigstep; 00200 } 00201 if(node->exec & NODE_BREAK) 00202 break; 00203 } 00204 MEM_freeN(gausstab); 00205 } 00206 00207 free_compbuf(work); 00208 } 00209 00210 /* reference has to be mapped 0-1, and equal in size */ 00211 static void bloom_with_reference(CompBuf *new, CompBuf *img, CompBuf *UNUSED(ref), float UNUSED(fac), NodeBlurData *nbd) 00212 { 00213 CompBuf *wbuf; 00214 register float val; 00215 float radxf, radyf; 00216 float **maintabs; 00217 float *gausstabx, *gausstabcenty; 00218 float *gausstaby, *gausstabcentx; 00219 int radx, rady, imgx= img->x, imgy= img->y; 00220 int x, y; 00221 int i, j; 00222 float *src, *dest, *wb; 00223 00224 wbuf= alloc_compbuf(imgx, imgy, CB_VAL, 1); 00225 00226 /* horizontal */ 00227 radx = (float)nbd->sizex; 00228 if(radx>imgx/2) 00229 radx= imgx/2; 00230 else if(radx<1) 00231 radx= 1; 00232 00233 /* vertical */ 00234 rady = (float)nbd->sizey; 00235 if(rady>imgy/2) 00236 rady= imgy/2; 00237 else if(rady<1) 00238 rady= 1; 00239 00240 x= MAX2(radx, rady); 00241 maintabs= MEM_mallocN(x*sizeof(void *), "gauss array"); 00242 for(i= 0; i<x; i++) 00243 maintabs[i]= make_bloomtab(i+1); 00244 00245 /* vars to store before we go */ 00246 // refd= ref->rect; 00247 src= img->rect; 00248 00249 radxf= (float)radx; 00250 radyf= (float)rady; 00251 00252 for (y = 0; y < imgy; y++) { 00253 for (x = 0; x < imgx ; x++, src+=4) {//, refd++) { 00254 00255 // int refradx= (int)(refd[0]*radxf); 00256 // int refrady= (int)(refd[0]*radyf); 00257 00258 int refradx= (int)(radxf*0.3f*src[3]*(src[0]+src[1]+src[2])); 00259 int refrady= (int)(radyf*0.3f*src[3]*(src[0]+src[1]+src[2])); 00260 00261 if(refradx>radx) refradx= radx; 00262 else if(refradx<1) refradx= 1; 00263 if(refrady>rady) refrady= rady; 00264 else if(refrady<1) refrady= 1; 00265 00266 if(refradx==1 && refrady==1) { 00267 wb= wbuf->rect + ( y*imgx + x); 00268 dest= new->rect + 4*( y*imgx + x); 00269 wb[0]+= 1.0f; 00270 dest[0] += src[0]; 00271 dest[1] += src[1]; 00272 dest[2] += src[2]; 00273 dest[3] += src[3]; 00274 } 00275 else { 00276 int minxr= x-refradx<0?-x:-refradx; 00277 int maxxr= x+refradx>imgx?imgx-x:refradx; 00278 int minyr= y-refrady<0?-y:-refrady; 00279 int maxyr= y+refrady>imgy?imgy-y:refrady; 00280 00281 float *destd= new->rect + 4*( (y + minyr)*imgx + x + minxr); 00282 float *wbufd= wbuf->rect + ( (y + minyr)*imgx + x + minxr); 00283 00284 gausstabx= maintabs[refradx-1]; 00285 gausstabcentx= gausstabx+refradx; 00286 gausstaby= maintabs[refrady-1]; 00287 gausstabcenty= gausstaby+refrady; 00288 00289 for (i= minyr; i < maxyr; i++, destd+= 4*imgx, wbufd+= imgx) { 00290 dest= destd; 00291 wb= wbufd; 00292 for (j= minxr; j < maxxr; j++, dest+=4, wb++) { 00293 00294 val= gausstabcenty[i]*gausstabcentx[j]; 00295 wb[0]+= val; 00296 dest[0] += val * src[0]; 00297 dest[1] += val * src[1]; 00298 dest[2] += val * src[2]; 00299 dest[3] += val * src[3]; 00300 } 00301 } 00302 } 00303 } 00304 } 00305 00306 x= imgx*imgy; 00307 dest= new->rect; 00308 wb= wbuf->rect; 00309 while(x--) { 00310 val= 1.0f/wb[0]; 00311 dest[0]*= val; 00312 dest[1]*= val; 00313 dest[2]*= val; 00314 dest[3]*= val; 00315 wb++; 00316 dest+= 4; 00317 } 00318 00319 free_compbuf(wbuf); 00320 00321 x= MAX2(radx, rady); 00322 for(i= 0; i<x; i++) 00323 MEM_freeN(maintabs[i]); 00324 MEM_freeN(maintabs); 00325 00326 } 00327 00328 #if 0 00329 static float hexagon_filter(float fi, float fj) 00330 { 00331 fi= fabs(fi); 00332 fj= fabs(fj); 00333 00334 if(fj>0.33f) { 00335 fj= (fj-0.33f)/0.66f; 00336 if(fi+fj>1.0f) 00337 return 0.0f; 00338 else 00339 return 1.0f; 00340 } 00341 else return 1.0f; 00342 } 00343 #endif 00344 00345 /* uses full filter, no horizontal/vertical optimize possible */ 00346 /* both images same type, either 1 or 4 channels */ 00347 static void bokeh_single_image(bNode *node, CompBuf *new, CompBuf *img, float fac) 00348 { 00349 NodeBlurData *nbd= node->storage; 00350 register float val; 00351 float radxf, radyf; 00352 float *gausstab, *dgauss; 00353 int radx, rady, imgx= img->x, imgy= img->y; 00354 int x, y, pix= img->type; 00355 int i, j, n; 00356 float *src= NULL, *dest, *srcd= NULL; 00357 00358 /* horizontal */ 00359 radxf = fac*(float)nbd->sizex; 00360 if(radxf>imgx/2.0f) 00361 radxf= imgx/2.0f; 00362 else if(radxf<1.0f) 00363 radxf= 1.0f; 00364 00365 /* vertical */ 00366 radyf = fac*(float)nbd->sizey; 00367 if(radyf>imgy/2.0f) 00368 radyf= imgy/2.0f; 00369 else if(radyf<1.0f) 00370 radyf= 1.0f; 00371 00372 radx= ceil(radxf); 00373 rady= ceil(radyf); 00374 00375 n = (2*radx+1)*(2*rady+1); 00376 00377 /* create a full filter image */ 00378 gausstab= MEM_mallocN(sizeof(float)*n, "filter tab"); 00379 dgauss= gausstab; 00380 val= 0.0f; 00381 for(j=-rady; j<=rady; j++) { 00382 for(i=-radx; i<=radx; i++, dgauss++) { 00383 float fj= (float)j/radyf; 00384 float fi= (float)i/radxf; 00385 float dist= sqrt(fj*fj + fi*fi); 00386 00387 //*dgauss= hexagon_filter(fi, fj); 00388 *dgauss= RE_filter_value(nbd->filtertype, dist); 00389 00390 val+= *dgauss; 00391 } 00392 } 00393 00394 if(val!=0.0f) { 00395 val= 1.0f/val; 00396 for(j= n -1; j>=0; j--) 00397 gausstab[j]*= val; 00398 } 00399 else gausstab[4]= 1.0f; 00400 00401 for (y = -rady+1; y < imgy+rady-1; y++) { 00402 00403 if(y<=0) srcd= img->rect; 00404 else if(y<imgy) srcd+= pix*imgx; 00405 else srcd= img->rect + pix*(imgy-1)*imgx; 00406 00407 for (x = -radx+1; x < imgx+radx-1 ; x++) { 00408 int minxr= x-radx<0?-x:-radx; 00409 int maxxr= x+radx>=imgx?imgx-x-1:radx; 00410 int minyr= y-rady<0?-y:-rady; 00411 int maxyr= y+rady>imgy-1?imgy-y-1:rady; 00412 00413 float *destd= new->rect + pix*( (y + minyr)*imgx + x + minxr); 00414 float *dgausd= gausstab + (minyr+rady)*(2*radx+1) + minxr+radx; 00415 00416 if(x<=0) src= srcd; 00417 else if(x<imgx) src+= pix; 00418 else src= srcd + pix*(imgx-1); 00419 00420 for (i= minyr; i <=maxyr; i++, destd+= pix*imgx, dgausd+= 2*radx + 1) { 00421 dest= destd; 00422 dgauss= dgausd; 00423 for (j= minxr; j <=maxxr; j++, dest+=pix, dgauss++) { 00424 val= *dgauss; 00425 if(val!=0.0f) { 00426 dest[0] += val * src[0]; 00427 if(pix>1) { 00428 dest[1] += val * src[1]; 00429 dest[2] += val * src[2]; 00430 dest[3] += val * src[3]; 00431 } 00432 } 00433 } 00434 } 00435 } 00436 if(node->exec & NODE_BREAK) 00437 break; 00438 } 00439 00440 MEM_freeN(gausstab); 00441 } 00442 00443 00444 /* reference has to be mapped 0-1, and equal in size */ 00445 static void blur_with_reference(bNode *node, CompBuf *new, CompBuf *img, CompBuf *ref) 00446 { 00447 NodeBlurData *nbd= node->storage; 00448 CompBuf *blurbuf, *ref_use; 00449 register float sum, val; 00450 float rval, gval, bval, aval, radxf, radyf; 00451 float **maintabs; 00452 float *gausstabx, *gausstabcenty; 00453 float *gausstaby, *gausstabcentx; 00454 int radx, rady, imgx= img->x, imgy= img->y; 00455 int x, y, pix= img->type; 00456 int i, j; 00457 float *src, *dest, *refd, *blurd; 00458 float defcol[4] = {1.0f, 1.0f, 1.0f, 1.0f}; /* default color for compbuf_get_pixel */ 00459 float proccol[4]; /* local color if compbuf is procedural */ 00460 int refradx, refrady; 00461 00462 if(ref->x!=img->x || ref->y!=img->y) 00463 return; 00464 00465 ref_use= typecheck_compbuf(ref, CB_VAL); 00466 00467 /* trick is; we blur the reference image... but only works with clipped values*/ 00468 blurbuf= alloc_compbuf(imgx, imgy, CB_VAL, 1); 00469 blurbuf->xof= ref_use->xof; 00470 blurbuf->yof= ref_use->yof; 00471 blurd= blurbuf->rect; 00472 refd= ref_use->rect; 00473 for(x= imgx*imgy; x>0; x--, refd++, blurd++) { 00474 if(refd[0]<0.0f) blurd[0]= 0.0f; 00475 else if(refd[0]>1.0f) blurd[0]= 1.0f; 00476 else blurd[0]= refd[0]; 00477 } 00478 00479 blur_single_image(node, blurbuf, blurbuf, 1.0f); 00480 00481 /* horizontal */ 00482 radx = (float)nbd->sizex; 00483 if(radx>imgx/2) 00484 radx= imgx/2; 00485 else if(radx<1) 00486 radx= 1; 00487 00488 /* vertical */ 00489 rady = (float)nbd->sizey; 00490 if(rady>imgy/2) 00491 rady= imgy/2; 00492 else if(rady<1) 00493 rady= 1; 00494 00495 x= MAX2(radx, rady); 00496 maintabs= MEM_mallocN(x*sizeof(void *), "gauss array"); 00497 for(i= 0; i<x; i++) 00498 maintabs[i]= make_gausstab(nbd->filtertype, i+1); 00499 00500 dest= new->rect; 00501 radxf= (float)radx; 00502 radyf= (float)rady; 00503 00504 for (y = 0; y < imgy; y++) { 00505 for (x = 0; x < imgx ; x++, dest+=pix) { 00506 refd= compbuf_get_pixel(blurbuf, defcol, proccol, x-blurbuf->xrad, y-blurbuf->yrad, blurbuf->xrad, blurbuf->yrad); 00507 refradx= (int)(refd[0]*radxf); 00508 refrady= (int)(refd[0]*radyf); 00509 00510 if(refradx>radx) refradx= radx; 00511 else if(refradx<1) refradx= 1; 00512 if(refrady>rady) refrady= rady; 00513 else if(refrady<1) refrady= 1; 00514 00515 if(refradx==1 && refrady==1) { 00516 src= img->rect + pix*( y*imgx + x); 00517 if(pix==1) 00518 dest[0]= src[0]; 00519 else 00520 copy_v4_v4(dest, src); 00521 } 00522 else { 00523 int minxr= x-refradx<0?-x:-refradx; 00524 int maxxr= x+refradx>imgx?imgx-x:refradx; 00525 int minyr= y-refrady<0?-y:-refrady; 00526 int maxyr= y+refrady>imgy?imgy-y:refrady; 00527 00528 float *srcd= img->rect + pix*( (y + minyr)*imgx + x + minxr); 00529 00530 gausstabx= maintabs[refradx-1]; 00531 gausstabcentx= gausstabx+refradx; 00532 gausstaby= maintabs[refrady-1]; 00533 gausstabcenty= gausstaby+refrady; 00534 00535 sum= gval = rval= bval= aval= 0.0f; 00536 00537 for (i= minyr; i < maxyr; i++, srcd+= pix*imgx) { 00538 src= srcd; 00539 for (j= minxr; j < maxxr; j++, src+=pix) { 00540 00541 val= gausstabcenty[i]*gausstabcentx[j]; 00542 sum+= val; 00543 rval += val * src[0]; 00544 if(pix>1) { 00545 gval += val * src[1]; 00546 bval += val * src[2]; 00547 aval += val * src[3]; 00548 } 00549 } 00550 } 00551 sum= 1.0f/sum; 00552 dest[0] = rval*sum; 00553 if(pix>1) { 00554 dest[1] = gval*sum; 00555 dest[2] = bval*sum; 00556 dest[3] = aval*sum; 00557 } 00558 } 00559 } 00560 if(node->exec & NODE_BREAK) 00561 break; 00562 } 00563 00564 free_compbuf(blurbuf); 00565 00566 x= MAX2(radx, rady); 00567 for(i= 0; i<x; i++) 00568 MEM_freeN(maintabs[i]); 00569 MEM_freeN(maintabs); 00570 00571 if(ref_use!=ref) 00572 free_compbuf(ref_use); 00573 } 00574 00575 static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bNodeStack **out) 00576 { 00577 CompBuf *new, *img= in[0]->data; 00578 NodeBlurData *nbd= node->storage; 00579 00580 if(img==NULL) return; 00581 00582 /* store image in size that is needed for absolute/relative conversions on ui level */ 00583 nbd->image_in_width= img->x; 00584 nbd->image_in_height= img->y; 00585 00586 if(out[0]->hasoutput==0) return; 00587 00588 if(nbd->relative) { 00589 if (nbd->aspect==CMP_NODE_BLUR_ASPECT_NONE) { 00590 nbd->sizex= (int)(nbd->percentx*0.01f*nbd->image_in_width); 00591 nbd->sizey= (int)(nbd->percenty*0.01f*nbd->image_in_height); 00592 } 00593 else if (nbd->aspect==CMP_NODE_BLUR_ASPECT_Y) { 00594 nbd->sizex= (int)(nbd->percentx*0.01f*nbd->image_in_width); 00595 nbd->sizey= (int)(nbd->percenty*0.01f*nbd->image_in_width); 00596 } 00597 else if (nbd->aspect==CMP_NODE_BLUR_ASPECT_X) { 00598 nbd->sizex= (int)(nbd->percentx*0.01f*nbd->image_in_height); 00599 nbd->sizey= (int)(nbd->percenty*0.01f*nbd->image_in_height); 00600 } 00601 } 00602 00603 if (nbd->sizex==0 && nbd->sizey==0) { 00604 new= pass_on_compbuf(img); 00605 out[0]->data= new; 00606 } 00607 else if (nbd->filtertype == R_FILTER_FAST_GAUSS) { 00608 CompBuf *new, *img = in[0]->data; 00609 // TODO: can this be mapped with reference, too? 00610 const float sx = ((float)nbd->sizex*in[1]->vec[0])/2.0f, sy = ((float)nbd->sizey*in[1]->vec[0])/2.0f; 00611 int c; 00612 00613 if ((img==NULL) || (out[0]->hasoutput==0)) return; 00614 00615 if (img->type == CB_VEC2) 00616 new = typecheck_compbuf(img, CB_VAL); 00617 else if (img->type == CB_VEC3) 00618 new = typecheck_compbuf(img, CB_RGBA); 00619 else 00620 new = dupalloc_compbuf(img); 00621 00622 if ((sx == sy) && (sx > 0.f)) { 00623 for (c=0; c<new->type; ++c) 00624 IIR_gauss(new, sx, c, 3); 00625 } 00626 else { 00627 if (sx > 0.f) { 00628 for (c=0; c<new->type; ++c) 00629 IIR_gauss(new, sx, c, 1); 00630 } 00631 if (sy > 0.f) { 00632 for (c=0; c<new->type; ++c) 00633 IIR_gauss(new, sy, c, 2); 00634 } 00635 } 00636 out[0]->data = new; 00637 00638 } else { 00639 /* All non fast gauss blur methods */ 00640 if(img->type==CB_VEC2 || img->type==CB_VEC3) { 00641 img= typecheck_compbuf(in[0]->data, CB_RGBA); 00642 } 00643 00644 /* if fac input, we do it different */ 00645 if(in[1]->data) { 00646 CompBuf *gammabuf; 00647 00648 /* make output size of input image */ 00649 new= alloc_compbuf(img->x, img->y, img->type, 1); /* allocs */ 00650 00651 /* accept image offsets from other nodes */ 00652 new->xof = img->xof; 00653 new->yof = img->yof; 00654 00655 if(nbd->gamma) { 00656 gammabuf= dupalloc_compbuf(img); 00657 gamma_correct_compbuf(gammabuf, 0); 00658 } 00659 else gammabuf= img; 00660 00661 blur_with_reference(node, new, gammabuf, in[1]->data); 00662 00663 if(nbd->gamma) { 00664 gamma_correct_compbuf(new, 1); 00665 free_compbuf(gammabuf); 00666 } 00667 if(node->exec & NODE_BREAK) { 00668 free_compbuf(new); 00669 new= NULL; 00670 } 00671 out[0]->data= new; 00672 } 00673 else { 00674 00675 if(in[1]->vec[0]<=0.001f) { /* time node inputs can be a tiny value */ 00676 new= pass_on_compbuf(img); 00677 } 00678 else { 00679 CompBuf *gammabuf; 00680 00681 /* make output size of input image */ 00682 new= alloc_compbuf(img->x, img->y, img->type, 1); /* allocs */ 00683 00684 /* accept image offsets from other nodes */ 00685 new->xof = img->xof; 00686 new->yof = img->yof; 00687 00688 if(nbd->gamma) { 00689 gammabuf= dupalloc_compbuf(img); 00690 gamma_correct_compbuf(gammabuf, 0); 00691 } 00692 else gammabuf= img; 00693 00694 if(nbd->bokeh) 00695 bokeh_single_image(node, new, gammabuf, in[1]->vec[0]); 00696 else if(1) 00697 blur_single_image(node, new, gammabuf, in[1]->vec[0]); 00698 else /* bloom experimental... */ 00699 bloom_with_reference(new, gammabuf, NULL, in[1]->vec[0], nbd); 00700 00701 if(nbd->gamma) { 00702 gamma_correct_compbuf(new, 1); 00703 free_compbuf(gammabuf); 00704 } 00705 if(node->exec & NODE_BREAK) { 00706 free_compbuf(new); 00707 new= NULL; 00708 } 00709 } 00710 out[0]->data= new; 00711 } 00712 if(img!=in[0]->data) 00713 free_compbuf(img); 00714 } 00715 00716 generate_preview(data, node, out[0]->data); 00717 } 00718 00719 static void node_composit_init_blur(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) 00720 { 00721 node->storage= MEM_callocN(sizeof(NodeBlurData), "node blur data"); 00722 } 00723 00724 void register_node_type_cmp_blur(bNodeTreeType *ttype) 00725 { 00726 static bNodeType ntype; 00727 00728 node_type_base(ttype, &ntype, CMP_NODE_BLUR, "Blur", NODE_CLASS_OP_FILTER, NODE_PREVIEW|NODE_OPTIONS); 00729 node_type_socket_templates(&ntype, cmp_node_blur_in, cmp_node_blur_out); 00730 node_type_size(&ntype, 120, 80, 200); 00731 node_type_init(&ntype, node_composit_init_blur); 00732 node_type_storage(&ntype, "NodeBlurData", node_free_standard_storage, node_copy_standard_storage); 00733 node_type_exec(&ntype, node_composit_exec_blur); 00734 00735 nodeRegisterType(ttype, &ntype); 00736 }