X-Git-Url: https://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fboxblur.C;fp=cinelerra-5.1%2Fcinelerra%2Fboxblur.C;h=07d7d6733fb01e294f142df9c276572347827ca1;hb=7ffa6954689f14a41a3bae7a0fdb3f2abeaa9679;hp=0000000000000000000000000000000000000000;hpb=6cf1b80d50c6b458241a0d43487fb8519c575c97;p=goodguy%2Fcinelerra.git diff --git a/cinelerra-5.1/cinelerra/boxblur.C b/cinelerra-5.1/cinelerra/boxblur.C new file mode 100644 index 00000000..07d7d673 --- /dev/null +++ b/cinelerra-5.1/cinelerra/boxblur.C @@ -0,0 +1,210 @@ +#include "boxblur.h" +// from ffmpeg vf_boxblur + +template static inline +void blurt(dst_t *dst, int dst_step, src_t *src, int src_step, + int len, int radius, float s) +{ + const int length = radius*2 + 1; + const int inv = s * ((1<<16) + length/2)/length; + int x, n, sum = src[radius*src_step]; + + for( x=0; x>16; + } + n = len - radius; + for( ; x>16; + } + for ( ; x>16; + } +} +// specialize const float *src +template static inline +void blurt(dst_t *dst, int dst_step, const float *src, int src_step, + int len, int radius, float s) +{ + const float length = radius*2 + 1; + const float inv = s / length; + int x, n; + float sum = src[radius*src_step]; + for( x=0; x static inline +void blur_power(dst_t *dst, int dst_step, src_t *src, int src_step, + int len, int radius, int power, float s) +{ + dst_t atemp[len], btemp[len]; + dst_t *a = atemp, *b = btemp; + blurt(a, 1, src, src_step, len, radius, s); + while( power-- > 2 ) { + blurt(b, 1, (const dst_t*)a, 1, len, radius, 1); + dst_t *t = a; a = b; b = t; + } + if( power > 1 ) + blurt(dst, dst_step, (const dst_t*)a, 1, len, radius, 1); + else + for( int i = 0; i +void BoxBlurUnit::blurt_package(LoadPackage *package) +{ + BoxBlur *box_blur = (BoxBlur *)server; + src_t *src_data = (src_t *)box_blur->src_data; + dst_t *dst_data = (dst_t *)box_blur->dst_data; + int radius = box_blur->radius; + int power = box_blur->power; + int vlen = box_blur->vlen; + int c0 = box_blur->c0, c1 = box_blur->c1; + int src_ustep = box_blur->src_ustep; + int dst_ustep = box_blur->dst_ustep; + int src_vstep = box_blur->src_vstep; + int dst_vstep = box_blur->dst_vstep; + BoxBlurPackage *pkg = (BoxBlurPackage*)package; + int u1 = pkg->u1, u2 = pkg->u2; + float s = 1.; + if( sizeof(src_t) != sizeof(dst_t) ) { + switch( sizeof(dst_t) ) { + case 1: s = sizeof(src_t)==2 ? 1/256. : 255.; break; + case 2: s = sizeof(src_t)==1 ? 256. : 65535.; break; + case 4: s = sizeof(src_t)==1 ? 1/256. : 1/65535.; break; + } + } + for( int u=u1; usrc_bpp, dst_bpp = box_blur->dst_bpp; + switch( src_bpp ) { + case 1: switch( dst_bpp ) { + case 1: blurt_package(package); break; + case 2: blurt_package(package); break; + case 4: blurt_package(package); break; + } + break; + case 2: switch( dst_bpp ) { + case 1: blurt_package(package); break; + case 2: blurt_package(package); break; + case 4: blurt_package(package); break; + } + break; + case 4: switch( dst_bpp ) { + case 1: blurt_package(package); break; + case 2: blurt_package(package); break; + case 4: blurt_package(package); break; + } + break; + } +} + +BoxBlur::BoxBlur(int cpus) + : LoadServer(cpus, cpus) +{ +} +BoxBlur::~BoxBlur() +{ +} + +LoadClient* BoxBlur::new_client() { return new BoxBlurUnit(this); } +LoadPackage* BoxBlur::new_package() { return new BoxBlurPackage(); } + +void BoxBlur::init_packages() +{ + int u = 0; + for( int i=0,n=LoadServer::get_total_packages(); iu1 = u; + pkg->u2 = u = (++i * ulen) / n; + } +} + +//dst can equal src, requires geom(dst)==geom(src) +//uv: 0=hblur, 1=vblur; comp: -1=rgb,0=r,1=g,2=b +void BoxBlur::process(VFrame *dst, VFrame *src, int uv, + int radius, int power, int comp) +{ + this->radius = radius; + this->power = power; + this->uv = uv; + int src_w = src->get_w(), src_h = src->get_h(); + ulen = !uv ? src_h : src_w; + vlen = !uv ? src_w : src_h; + c0 = comp<0 ? 0 : comp; + c1 = comp<0 ? 2 : comp; + src_data = src->get_data(); + dst_data = dst->get_data(); + int src_pixsz = BC_CModels::calculate_pixelsize(src->get_color_model()); + int src_comps = BC_CModels::components(src->get_color_model()); + src_bpp = src_pixsz / src_comps; + int dst_pixsz = BC_CModels::calculate_pixelsize(dst->get_color_model()); + int dst_comps = BC_CModels::components(dst->get_color_model()); + dst_bpp = dst_pixsz / dst_comps; + int dst_linsz = dst->get_bytes_per_line() / dst_bpp; + int src_linsz = src->get_bytes_per_line() / src_bpp; + src_ustep = !uv ? src_linsz : src_comps; + dst_ustep = !uv ? dst_linsz: dst_comps; + src_vstep = !uv ? src_comps : src_linsz; + dst_vstep = !uv ? dst_comps : dst_linsz; + + process_packages(); +} + +void BoxBlur::hblur(VFrame *dst, VFrame *src, int radius, int power, int comp) +{ + process(dst, src, 0, radius, power, comp); +} +void BoxBlur::vblur(VFrame *dst, VFrame *src, int radius, int power, int comp) +{ + process(dst, src, 1, radius, power, comp); +} +void BoxBlur::blur(VFrame *dst, VFrame *src, int radius, int power, int comp) +{ + process(dst, src, 0, radius, power, comp); + process(dst, dst, 1, radius, power, comp); +} +