X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;ds=sidebyside;f=synfig-core%2Ftags%2Fsynfig_0_61_07_rc1%2Fsrc%2Fsynfig%2Fblur.cpp;fp=synfig-core%2Ftags%2Fsynfig_0_61_07_rc1%2Fsrc%2Fsynfig%2Fblur.cpp;h=0000000000000000000000000000000000000000;hb=6fa8f2f38d4b0b35f8539bf94e27ae27015c7689;hp=ec80fd75cd1346d36d90a7eb683c0623b6b271f1;hpb=47fce282611fbba1044921d22ca887f9b53ad91a;p=synfig.git diff --git a/synfig-core/tags/synfig_0_61_07_rc1/src/synfig/blur.cpp b/synfig-core/tags/synfig_0_61_07_rc1/src/synfig/blur.cpp deleted file mode 100644 index ec80fd7..0000000 --- a/synfig-core/tags/synfig_0_61_07_rc1/src/synfig/blur.cpp +++ /dev/null @@ -1,1204 +0,0 @@ -/* === S Y N F I G ========================================================= */ -/*! \file synfig/blur.cpp -** \brief Blur Implementation File -** -** $Id$ -** -** \legal -** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley -** -** This package is free software; you can redistribute it and/or -** modify it under the terms of the GNU General Public License as -** published by the Free Software Foundation; either version 2 of -** the License, or (at your option) any later version. -** -** This package is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** General Public License for more details. -** \endlegal -*/ -/* ========================================================================= */ - -/* === H E A D E R S ======================================================= */ - -#ifdef USING_PCH -# include "pch.h" -#else -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include - -#include "blur.h" - -#include -#include - -#include -#include -#include - -#endif - -/* === U S I N G =========================================================== */ - -using namespace std; -using namespace etl; -using namespace synfig; - -/* === M A C R O S ========================================================= */ - -/* === G L O B A L S ======================================================= */ - -/* === P R O C E D U R E S ================================================= */ - -/* === M E T H O D S ======================================================= */ -Point Blur::operator ()(const Point &pos) const -{ - Point blurpos(pos); - - switch(type) - { - case CROSS: - if(rand()%2) - { - if(size[0]) - blurpos[0]+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) * size[0]; - } - else - { - if(size[1]) - blurpos[1]+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) * size[1]; - } - break; - - case DISC: - { - Angle theta=Angle::rotations((float)rand()/(float)RAND_MAX); - Vector::value_type mag=(float)rand()/(float)RAND_MAX; - Vector vect((float)Angle::cos(theta).get()*mag,(float)Angle::sin(theta).get()*mag); - - blurpos[0]+=vect[0]*size[0]; - blurpos[1]+=vect[1]*size[1]; - } - break; - - case FASTGAUSSIAN: - case GAUSSIAN: - // Not quite a true gaussian blur, - // but the results are close enough for me. - if(size[0]) - { - blurpos[0]+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) * size[0]*3/4; - blurpos[0]+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) * size[0]*3/4; - } - if(size[1]) - { - blurpos[1]+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) * size[1]*3/4; - blurpos[1]+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) * size[1]*3/4; - } - break; - - case BOX: - default: - if(size[0]) - blurpos[0]+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) * size[0]; - if(size[1]) - blurpos[1]+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) * size[1]; - break; - } - - return blurpos; -} - -Point Blur::operator ()(synfig::Real x, synfig::Real y) const -{ - return (*this)(Point(x,y)); -} - -//blur functions to make my life easier - -template -static inline T zero() -{ - return (T)0; -} - -template <> -static inline Color zero() -{ - return Color::alpha(); -} - -template -static void GuassianBlur_2x2(etl::surface &surface) -{ - int x,y; - T Tmp1,Tmp2,SR0; - - T *SC0=new T[surface.get_w()]; - - memcpy(SC0,surface[0],surface.get_w()*sizeof(T)); - - for(y=0;y -static void GuassianBlur_3x3(etl::surface &surface) -{ - int x,y,u,v,w,h; - T Tmp1,Tmp2,SR0,SR1; - - w=surface.get_w(); - h=surface.get_h(); - - T *SC0=new T[w+1]; - T *SC1=new T[w+1]; - - // Setup the row bufers - for(x=0;x=h) - v=h-1; - else - v=y; - - SR0=SR1=surface[y][0]; - for(x=0;x<=w;x++) - { - if(x>=w) - u=w-1; - else - u=x; - - // Row Machine - Tmp1=surface[v][u]; - Tmp2=SR0+Tmp1; - SR0=Tmp1; - Tmp1=SR1+Tmp2; - SR1=Tmp2; - - // Column Machine - Tmp2=SC0[x]+Tmp1; - SC0[x]=Tmp1; - if(y&&x) - surface[y-1][x-1]=(SC1[x]+Tmp2)/16; - SC1[x]=Tmp2; - } - } - - delete [] SC0; - delete [] SC1; -} - -template -inline static void GaussianBlur_5x5_(etl::surface &surface,T *SC0,T *SC1,T *SC2,T *SC3) -{ - int x,y,u,v,w,h; - T Tmp1,Tmp2,SR0,SR1,SR2,SR3; - - w=surface.get_w(); - h=surface.get_h(); - - // Setup the row bufers - for(x=0;x=h) - v=h-1; - else - v=y; - - SR0=SR1=SR2=SR3=0; - SR0=surface[v][0]*1.5; - for(x=0;x=w) - u=w-1; - else - u=x; - - // Row Machine - Tmp1=surface[v][u]; - Tmp2=SR0+Tmp1; - SR0=Tmp1; - Tmp1=SR1+Tmp2; - SR1=Tmp2; - Tmp2=SR2+Tmp1; - SR2=Tmp1; - Tmp1=SR3+Tmp2; - SR3=Tmp2; - - // Column Machine - Tmp2=SC0[x]+Tmp1; - SC0[x]=Tmp1; - Tmp1=SC1[x]+Tmp2; - SC1[x]=Tmp2; - Tmp2=SC2[x]+Tmp1; - SC2[x]=Tmp1; - if(y>1&&x>1) - surface[y-2][x-2]=(SC3[x]+Tmp2)/256; - SC3[x]=Tmp2; - } - } - -} - -template -inline static void GaussianBlur_5x5(etl::surface &surface) -{ - int w=surface.get_w(); - - T *SC0=new T[w+2]; - T *SC1=new T[w+2]; - T *SC2=new T[w+2]; - T *SC3=new T[w+2]; - - GaussianBlur_5x5_(surface,SC0,SC1,SC2,SC3); - - delete [] SC0; - delete [] SC1; - delete [] SC2; - delete [] SC3; -} - -template -static void GuassianBlur_nxn(etl::surface &surface,int n) -{ - int x,y,u,v,w,h; - int half_n=n/2,i; - T inv_divisor=pow(2.0,(n-1)); - T Tmp1,Tmp2; - inv_divisor=1.0/(inv_divisor*inv_divisor); - - w=surface.get_w(); - h=surface.get_h(); - - T SR[n-1]; - T *SC[n-1]; - - for(i=0;i=h) - v=h-1; - else - v=y; - - memset(SR,0,(n-1)*sizeof(T)); - -// SR[0]=surface[v][0]*(2.0-1.9/n); - - for(x=0;x=w) - u=w-1; - else - u=x; - - Tmp1=surface[v][u]; - // Row Machine - for(i=0;i=half_n&&x>=half_n) - surface[y-half_n][x-half_n]=(SC[n-2][x]+Tmp2)*inv_divisor; - SC[n-2][x]=Tmp2; - } - } - - for(i=0;i -static void GuassianBlur_2x1(etl::surface &surface) -{ - int x,y; - AT Tmp1,Tmp2,SR0; - - for(y=0;y -static void GuassianBlur_3x1(etl::surface &surface) -{ - int x,y; - AT Tmp1,Tmp2,SR0,SR1; - - for(y=0;y -static void GuassianBlur_1x2(etl::surface &surface) -{ - int x,y; - AT Tmp1,Tmp2,SR0; - - for(x=0;x(); - for(y=0;y -static void GuassianBlur_1x3(etl::surface &surface) -{ - int x,y; - AT Tmp1,Tmp2,SR0,SR1; - - for(x=0;x2) - { - int x2,y2; - Surface tmp_surface(worksurface); - - for(y=0;y1.0) - continue; - - //cap the pixel indices to inside the surface - int u= x+x2, - v= y+y2; - - if( u < 0 ) u = 0; - if( u >= w ) u = w-1; - - if( v < 0 ) v = 0; - if( v >= h ) v = h-1; - - //accumulate the color, and # of pixels added in - color += tmp_surface[v][u]; - total++; - } - } - - //blend the color with the original color - //if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT) - worksurface[y][x]=color/total; - //else - // worksurface[y][x]=Color::blend(color/total,tmp_surface[y][x],get_amount(),get_blend_method()); - } - if(!blurcall.amount_complete(y,h)) - { - //if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__)); - return false; - } - } - break; - } - - //if we don't qualify for disc blur just use box blur - } - - case Blur::BOX: // B O X ------------------------------------------------------- - { - //horizontal part - //synfig::info("Blur: Starting Box blur (surface valid %d)", (int)surface_valid(worksurface)); - - Surface temp_surface; - temp_surface.set_wh(w,h); - - if(size[0]) - { - int length = halfsizex; - length=std::max(1,length); - - //synfig::info("Blur: hbox blur work -> temp %d", length); - etl::hbox_blur(worksurface.begin(),worksurface.end(),length,temp_surface.begin()); - } - else temp_surface = worksurface; - //synfig::info("Blur: hbox finished"); - - //vertical part - //Surface temp_surface2; - //temp_surface2.set_wh(w,h); - - if(size[1]) - { - int length = halfsizey; - length = std::max(1,length); - - //synfig::info("Blur: vbox blur temp -> work %d",length); - etl::vbox_blur(temp_surface.begin(),temp_surface.end(),length,worksurface.begin()); - } - else worksurface = temp_surface; - //synfig::info("Blur: vbox finished"); - - //blend with the original surface - /*int x,y; - for(y=0;y=4 && bh>=4) - { - etl::gaussian_blur_5x5_(gauss_surface->begin(),gauss_surface->get_w(),gauss_surface->get_h(),SC0,SC1,SC2,SC3); - bw-=4,bh-=4; - } - else - if(bw>=2 && bh>=2) - { - etl::gaussian_blur_3x3(gauss_surface->begin(),gauss_surface->end()); - bw-=2,bh-=2; - } - else - if(bw>=1 && bh>=1) - { - GuassianBlur_2x2(*gauss_surface); - bw--,bh--; - } - - //synfig::warning("Didn't crash yet bi - %d",i++); - } - while(bw) - { - if(!blurcall.amount_complete(max-(bw+bh),max))return false; - if(bw>=2) - { - GuassianBlur_3x1(*gauss_surface); - bw-=2; - } - else - if(bw>=1) - { - GuassianBlur_2x1(*gauss_surface); - bw--; - } - //synfig::warning("Didn't crash yet bi - %d",i++); - } - while(bh) - { - if(!blurcall.amount_complete(max-(bw+bh),max))return false; - if(bh>=2) - { - GuassianBlur_1x3(*gauss_surface); - bh-=2; - } - else - if(bh>=1) - { - GuassianBlur_1x2(*gauss_surface); - bh--; - } - //synfig::warning("Didn't crash yet bi - %d",i++); - } - - delete [] SC0; - delete [] SC1; - delete [] SC2; - delete [] SC3; - - /*if(get_amount()!=1.0 || get_blend_method()!=Color::BLEND_STRAIGHT) - { - int x,y; - for(y=0;yset_wh(renddesc.get_w(),renddesc.get_h()); - out.set_wh(w,h); - - //divide out the alpha - for(y=0;y &surface, - const Vector &resolution, - surface &out) const -{ - int w = surface.get_w(), - h = surface.get_h(); - - if(w == 0 || h == 0 || resolution[0] == 0 || resolution[1] == 0) return false; - - const Real pw = resolution[0]/w, - ph = resolution[1]/h; - - int halfsizex = (int) (abs(size[0]*.5/pw) + 1), - halfsizey = (int) (abs(size[1]*.5/ph) + 1); - int x,y; - - SuperCallback blurcall(cb,0,5000,5000); - - etl::surface worksurface(surface); - - //don't need to premultiply because we are dealing with ONLY alpha - - switch(type) - { - case Blur::DISC: // D I S C ---------------------------------------------------------- - { - int bw = halfsizex; - int bh = halfsizey; - - if(size[0] && size[1] && w*h>2) - { - int x2,y2; - etl::surface tmp_surface(worksurface); - - for(y=0;y1.0) - continue; - - //cap the pixel indices to inside the surface - int u= x+x2, - v= y+y2; - - if( u < 0 ) u = 0; - if( u >= w ) u = w-1; - - if( v < 0 ) v = 0; - if( v >= h ) v = h-1; - - //accumulate the color, and # of pixels added in - a += tmp_surface[v][u]; - total++; - } - } - - //blend the color with the original color - //if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT) - worksurface[y][x]=a/total; - //else - // worksurface[y][x]=Color::blend(color/total,tmp_surface[y][x],get_amount(),get_blend_method()); - } - if(!blurcall.amount_complete(y,h)) - { - //if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__)); - return false; - } - } - break; - } - - //if we don't qualify for disc blur just use box blur - } - - case Blur::BOX: // B O X ------------------------------------------------------- - { - //horizontal part - etl::surface temp_surface; - temp_surface.set_wh(w,h); - - if(size[0]) - { - int length = halfsizex; - length=std::max(1,length); - - etl::hbox_blur(worksurface.begin(),worksurface.end(),length,temp_surface.begin()); - } - else temp_surface = worksurface; - - //vertical part - //etl::surface temp_surface2; - //temp_surface2.set_wh(w,h); - - if(size[1]) - { - int length = halfsizey; - length = std::max(1,length); - etl::vbox_blur(temp_surface.begin(),temp_surface.end(),length,worksurface.begin()); - } - else worksurface = temp_surface; - - //blend with the original surface - /*int x,y; - for(y=0;y temp_surface; - temp_surface.set_wh(w,h); - - //etl::surface temp_surface2; - //temp_surface2.set_wh(w,h); - - //horizontal part - if(size[0]) - { - Real length=abs((float)w/(resolution[0]))*size[0]*0.5+1; - length=std::max(1.0,length); - - //two box blurs produces: 1 2 1 - etl::hbox_blur(worksurface.begin(),w,h,(int)(length*3/4),temp_surface.begin()); - etl::hbox_blur(temp_surface.begin(),w,h,(int)(length*3/4),worksurface.begin()); - } - //else temp_surface2=worksurface; - - //vertical part - if(size[1]) - { - Real length=abs((float)h/(resolution[1]))*size[1]*0.5+1; - length=std::max(1.0,length); - - //two box blurs produces: 1 2 1 on the horizontal 1 2 1 - etl::vbox_blur(worksurface.begin(),w,h,(int)(length*3/4),temp_surface.begin()); - etl::vbox_blur(temp_surface.begin(),w,h,(int)(length*3/4),worksurface.begin()); - } - //else temp_surface2=temp_surface2; - - /*int x,y; - for(y=0;y temp_surface; - temp_surface.set_wh(worksurface.get_w(),worksurface.get_h()); - - if(size[0]) - { - int length = halfsizex; - length = std::max(1,length); - - etl::hbox_blur(worksurface.begin(),worksurface.end(),length,temp_surface.begin()); - } - else temp_surface = worksurface; - - //vertical part - etl::surface temp_surface2; - temp_surface2.set_wh(worksurface.get_w(),worksurface.get_h()); - - if(size[1]) - { - int length = halfsizey; - length = std::max(1,length); - - etl::vbox_blur(worksurface.begin(),worksurface.end(),length,temp_surface2.begin()); - } - else temp_surface2 = worksurface; - - //blend the two together - int x,y; - - for(y=0;y temp_surface; - etl::surface *gauss_surface; - - //if(get_amount()==1.0 && get_blend_method()==Color::BLEND_STRAIGHT) - gauss_surface = &worksurface; - /*else - { - temp_surface = worksurface; - gauss_surface = &temp_surface; - }*/ - - /* Squaring the pw and ph values - is necessary to insure consistant - results when rendered to different - resolutions. - Unfortunately, this automaticly - squares our rendertime. - There has got to be a faster way... - */ - pw=pw*pw; - ph=ph*ph; - - int bw = (int)(abs(pw)*size[0]*GAUSSIAN_ADJUSTMENT+0.5); - int bh = (int)(abs(ph)*size[1]*GAUSSIAN_ADJUSTMENT+0.5); - int max=bw+bh; - - float *SC0=new float[w+2]; - float *SC1=new float[w+2]; - float *SC2=new float[w+2]; - float *SC3=new float[w+2]; - - memset(SC0,0,(w+2)*sizeof(float)); - memset(SC0,0,(w+2)*sizeof(float)); - memset(SC0,0,(w+2)*sizeof(float)); - memset(SC0,0,(w+2)*sizeof(float)); - - //int i = 0; - - while(bw&&bh) - { - if(!blurcall.amount_complete(max-(bw+bh),max))return false; - - if(bw>=4 && bh>=4) - { - etl::gaussian_blur_5x5_(gauss_surface->begin(),gauss_surface->get_w(),gauss_surface->get_h(),SC0,SC1,SC2,SC3); - bw-=4,bh-=4; - } - else - if(bw>=2 && bh>=2) - { - etl::gaussian_blur_3x3(gauss_surface->begin(),gauss_surface->end()); - bw-=2,bh-=2; - } - else - if(bw>=1 && bh>=1) - { - GuassianBlur_2x2(*gauss_surface); - bw--,bh--; - } - } - - while(bw) - { - if(!blurcall.amount_complete(max-(bw+bh),max))return false; - if(bw>=2) - { - GuassianBlur_3x1(*gauss_surface); - bw-=2; - } - else - if(bw>=1) - { - GuassianBlur_2x1(*gauss_surface); - bw--; - } - } - - while(bh) - { - if(!blurcall.amount_complete(max-(bw+bh),max))return false; - if(bh>=2) - { - GuassianBlur_1x3(*gauss_surface); - bh-=2; - } - else - if(bh>=1) - { - GuassianBlur_1x2(*gauss_surface); - bh--; - } - } - - delete [] SC0; - delete [] SC1; - delete [] SC2; - delete [] SC3; - - /*if(get_amount()!=1.0 || get_blend_method()!=Color::BLEND_STRAIGHT) - { - int x,y; - for(y=0;yset_wh(renddesc.get_w(),renddesc.get_h()); - out.set_wh(w,h); - - //divide out the alpha - don't need to cause we rock - out = worksurface; - - //we are FRIGGGIN done.... - blurcall.amount_complete(100,100); - - return true; -} - -/* === E N T R Y P O I N T ================================================= */