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