Blender  V2.59
CMP_blur.c
Go to the documentation of this file.
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