diff options
author | wm4 <wm4@nowhere> | 2014-11-13 20:51:51 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-11-13 20:55:57 +0100 |
commit | 901c5bf00abbe738a5665662e6a3b44f91c4d6d4 (patch) | |
tree | 8ccbb0829f41b32c39c5a2e39708e8cf418e597a /libass/ass_bitmap.c | |
parent | db3d5b69c250e719b07363d43ca26a49821d08c0 (diff) | |
download | libass-901c5bf00abbe738a5665662e6a3b44f91c4d6d4.tar.bz2 libass-901c5bf00abbe738a5665662e6a3b44f91c4d6d4.tar.xz |
Move apply_blur() to ass_bitmap.c
Put all code into one place, which makes it easier to follow.
Diffstat (limited to 'libass/ass_bitmap.c')
-rw-r--r-- | libass/ass_bitmap.c | 94 |
1 files changed, 92 insertions, 2 deletions
diff --git a/libass/ass_bitmap.c b/libass/ass_bitmap.c index 98ed556..2fbca79 100644 --- a/libass/ass_bitmap.c +++ b/libass/ass_bitmap.c @@ -32,9 +32,29 @@ #include "ass_bitmap.h" #include "ass_render.h" +#if (defined(__i386__) || defined(__x86_64__)) && CONFIG_ASM +#include "x86/be_blur.h" +#endif + static const unsigned base = 256; -int generate_tables(ASS_SynthPriv *priv, double radius) +struct ass_synth_priv { + int tmp_w, tmp_h; + void *tmp; + + int g_r; + int g_w; + + double *g0; + unsigned *g; + unsigned *gt2; + + double radius; + + BEBlurFunc be_blur_func; +}; + +static int generate_tables(ASS_SynthPriv *priv, double radius) { double A = log(1.0 / base) / (radius * radius * 2); int mx, i; @@ -101,7 +121,7 @@ int generate_tables(ASS_SynthPriv *priv, double radius) return 0; } -void resize_tmp(ASS_SynthPriv *priv, int w, int h) +static void resize_tmp(ASS_SynthPriv *priv, int w, int h) { if (priv->tmp_w >= w && priv->tmp_h >= h) return; @@ -118,6 +138,66 @@ void resize_tmp(ASS_SynthPriv *priv, int w, int h) ass_aligned_alloc(32, (priv->tmp_w + 1) * priv->tmp_h * sizeof(unsigned)); } +void ass_synth_blur(ASS_SynthPriv *priv_blur, int opaque_box, int be, + double blur_radius, Bitmap *bm_g, Bitmap *bm_o) +{ + if(blur_radius > 0.0 || be){ + if (bm_o) + resize_tmp(priv_blur, bm_o->w, bm_o->h); + if (!bm_o || opaque_box) + resize_tmp(priv_blur, bm_g->w, bm_g->h); + } + + // Apply box blur (multiple passes, if requested) + if (be) { + uint16_t* tmp = priv_blur->tmp; + if (bm_o) { + unsigned passes = be; + unsigned w = bm_o->w; + unsigned h = bm_o->h; + unsigned stride = bm_o->stride; + unsigned char *buf = bm_o->buffer; + if(w && h){ + while(passes--){ + memset(tmp, 0, stride * 2); + if(w < 16){ + be_blur_c(buf, w, h, stride, tmp); + }else{ + priv_blur->be_blur_func(buf, w, h, stride, tmp); + } + } + } + } + if (!bm_o || opaque_box) { + unsigned passes = be; + unsigned w = bm_g->w; + unsigned h = bm_g->h; + unsigned stride = bm_g->stride; + unsigned char *buf = bm_g->buffer; + if(w && h){ + while(passes--){ + memset(tmp, 0, stride * 2); + priv_blur->be_blur_func(buf, w, h, stride, tmp); + } + } + } + } + + // Apply gaussian blur + if (blur_radius > 0.0 && generate_tables(priv_blur, blur_radius) >= 0) { + if (bm_o) + ass_gauss_blur(bm_o->buffer, priv_blur->tmp, + bm_o->w, bm_o->h, bm_o->stride, + priv_blur->gt2, priv_blur->g_r, + priv_blur->g_w); + if (!bm_o || opaque_box) + ass_gauss_blur(bm_g->buffer, priv_blur->tmp, + bm_g->w, bm_g->h, bm_g->stride, + priv_blur->gt2, priv_blur->g_r, + priv_blur->g_w); + } +} + ASS_SynthPriv *ass_synth_init(double radius) { ASS_SynthPriv *priv = calloc(1, sizeof(ASS_SynthPriv)); @@ -125,6 +205,16 @@ ASS_SynthPriv *ass_synth_init(double radius) free(priv); priv = NULL; } + #if (defined(__i386__) || defined(__x86_64__)) && CONFIG_ASM + int avx2 = has_avx2(); + #ifdef __x86_64__ + priv->be_blur_func = avx2 ? ass_be_blur_avx2 : ass_be_blur_sse2; + #else + priv->be_blur_func = be_blur_c; + #endif + #else + priv->be_blur_func = be_blur_c; + #endif return priv; } |