summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libass/ass_bitmap.c94
-rw-r--r--libass/ass_bitmap.h20
-rw-r--r--libass/ass_render.c74
-rw-r--r--libass/ass_render.h1
4 files changed, 100 insertions, 89 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;
}
diff --git a/libass/ass_bitmap.h b/libass/ass_bitmap.h
index 852cb0b..82a2159 100644
--- a/libass/ass_bitmap.h
+++ b/libass/ass_bitmap.h
@@ -24,19 +24,7 @@
#include "ass.h"
-typedef 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;
-} ASS_SynthPriv;
+typedef struct ass_synth_priv ASS_SynthPriv;
ASS_SynthPriv *ass_synth_init(double);
void ass_synth_done(ASS_SynthPriv *priv);
@@ -52,6 +40,10 @@ Bitmap *outline_to_bitmap(ASS_Renderer *render_priv,
FT_Outline *outline, int bord);
Bitmap *alloc_bitmap(int w, int h);
+
+void ass_synth_blur(ASS_SynthPriv *priv_blur, int opaque_box, int be,
+ double blur_radius, Bitmap *bm_g, Bitmap *bm_o);
+
/**
* \brief perform glyph rendering
* \param glyph original glyph
@@ -86,8 +78,6 @@ void mul_bitmaps_c(uint8_t *dst, intptr_t dst_stride,
intptr_t w, intptr_t h);
void shift_bitmap(Bitmap *bm, int shift_x, int shift_y);
void fix_outline(Bitmap *bm_g, Bitmap *bm_o);
-void resize_tmp(ASS_SynthPriv *priv, int w, int h);
-int generate_tables(ASS_SynthPriv *priv, double radius);
Bitmap *copy_bitmap(const Bitmap *src);
#endif /* LIBASS_BITMAP_H */
diff --git a/libass/ass_render.c b/libass/ass_render.c
index cde8ef4..27ea418 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -36,7 +36,6 @@
#if (defined(__i386__) || defined(__x86_64__)) && CONFIG_ASM
#include "x86/blend_bitmaps.h"
-#include "x86/be_blur.h"
#include "x86/rasterizer.h"
#endif // ASM
@@ -76,11 +75,9 @@ ASS_Renderer *ass_renderer_init(ASS_Library *library)
priv->add_bitmaps_func = avx2 ? ass_add_bitmaps_avx2 :
(sse2 ? ass_add_bitmaps_sse2 : ass_add_bitmaps_x86);
#ifdef __x86_64__
- priv->be_blur_func = avx2 ? ass_be_blur_avx2 : ass_be_blur_sse2;
priv->mul_bitmaps_func = avx2 ? ass_mul_bitmaps_avx2 : ass_mul_bitmaps_sse2;
priv->sub_bitmaps_func = avx2 ? ass_sub_bitmaps_avx2 : ass_sub_bitmaps_sse2;
#else
- priv->be_blur_func = be_blur_c;
priv->mul_bitmaps_func = mul_bitmaps_c;
priv->sub_bitmaps_func = ass_sub_bitmaps_x86;
#endif
@@ -88,7 +85,6 @@ ASS_Renderer *ass_renderer_init(ASS_Library *library)
priv->add_bitmaps_func = add_bitmaps_c;
priv->sub_bitmaps_func = sub_bitmaps_c;
priv->mul_bitmaps_func = mul_bitmaps_c;
- priv->be_blur_func = be_blur_c;
#endif
#if CONFIG_RASTERIZER
@@ -1796,72 +1792,6 @@ static int is_new_bm_run(GlyphInfo *info, GlyphInfo *last)
return 0;
}
-static void apply_blur(CombinedBitmapInfo *info, ASS_Renderer *render_priv)
-{
- int be = info->be;
- double blur_radius = info->blur * render_priv->blur_scale * 2;
- ASS_SynthPriv *priv_blur = render_priv->synth_priv;
- Bitmap *bm_g = info->bm;
- Bitmap *bm_o = info->bm_o;
- int border_style = info->border_style;
-
- if(blur_radius > 0.0 || be){
- if (bm_o)
- resize_tmp(priv_blur, bm_o->w, bm_o->h);
- if (!bm_o || border_style == 3)
- 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{
- render_priv->be_blur_func(buf, w, h, stride, tmp);
- }
- }
- }
- }
- if (!bm_o || border_style == 3) {
- 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);
- render_priv->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 || border_style == 3)
- 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);
- }
-}
-
static void make_shadow_bitmap(CombinedBitmapInfo *info, ASS_Renderer *render_priv)
{
// VSFilter compatibility: invisible fill and no border?
@@ -2607,7 +2537,9 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
CompositeHashValue chv;
CombinedBitmapInfo *info = &combined_info[i];
if(info->bm || info->bm_o){
- apply_blur(info, render_priv);
+ ass_synth_blur(render_priv->synth_priv, info->border_style == 3,
+ info->be, info->blur * render_priv->blur_scale * 2,
+ info->bm, info->bm_o);
make_shadow_bitmap(info, render_priv);
}
diff --git a/libass/ass_render.h b/libass/ass_render.h
index ea630aa..1e5fa54 100644
--- a/libass/ass_render.h
+++ b/libass/ass_render.h
@@ -363,7 +363,6 @@ struct ass_renderer {
BitmapBlendFunc add_bitmaps_func;
BitmapBlendFunc sub_bitmaps_func;
BitmapMulFunc mul_bitmaps_func;
- BEBlurFunc be_blur_func;
FreeList *free_head;
FreeList *free_tail;