From e55955084f66971f6a268e0d0641da1f132fa979 Mon Sep 17 00:00:00 2001 From: Oleg Oshmyan Date: Mon, 9 Feb 2015 15:18:44 +0200 Subject: Add enough padding for \be to avoid clipping To avoid making bitmaps unnecessarily large, use just the necessary amount of padding for the given \be value. --- libass/ass_bitmap.c | 29 +++++++++++++++++++++++++++++ libass/ass_bitmap.h | 1 + libass/ass_render.c | 2 +- 3 files changed, 31 insertions(+), 1 deletion(-) (limited to 'libass') diff --git a/libass/ass_bitmap.c b/libass/ass_bitmap.c index 5f0991d..286f904 100644 --- a/libass/ass_bitmap.c +++ b/libass/ass_bitmap.c @@ -749,6 +749,35 @@ void be_blur_post(uint8_t *buf, intptr_t w, intptr_t h, intptr_t stride) } } +/* + * To find these values, simulate blur on the border between two + * half-planes, one zero-filled (background) and the other filled + * with the maximum supported value (foreground). Keep incrementing + * the \be argument. The necessary padding is the distance by which + * the blurred foreground image extends beyond the original border + * and into the background. Initially it increases along with \be, + * but very soon it grinds to a halt. At some point, the blurred + * image actually reaches a stationary point and stays unchanged + * forever after, simply _shifting_ by one pixel for each \be + * step--moving in the direction of the non-zero half-plane and + * thus decreasing the necessary padding (although the large + * padding is still needed for intermediate results). In practice, + * images are finite rather than infinite like half-planes, but + * this can only decrease the required padding. Half-planes filled + * with extreme values are the theoretical limit of the worst case. + * Make sure to use the right pixel value range in the simulation! + */ +int be_padding(int be) +{ + if (be <= 3) + return be; + if (be <= 7) + return 4; + if (be <= 123) + return 5; + return FFMAX(128 - be, 0); +} + int outline_to_bitmap2(ASS_Renderer *render_priv, ASS_Outline *outline, ASS_Outline *border, Bitmap **bm_g, Bitmap **bm_o) diff --git a/libass/ass_bitmap.h b/libass/ass_bitmap.h index 5014f51..901adc7 100644 --- a/libass/ass_bitmap.h +++ b/libass/ass_bitmap.h @@ -69,6 +69,7 @@ void ass_free_bitmap(Bitmap *bm); void ass_gauss_blur(unsigned char *buffer, unsigned *tmp2, int width, int height, int stride, unsigned *m2, int r, int mwidth); +int be_padding(int be); void be_blur_c(uint8_t *buf, intptr_t w, intptr_t h, intptr_t stride, uint16_t *tmp); diff --git a/libass/ass_render.c b/libass/ass_render.c index 6140788..a02bcab 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -2257,7 +2257,7 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv, continue; } - int bbord = info->filter.be > 0 ? sqrt(2 * info->filter.be) : 0; + int bbord = be_padding(info->filter.be); int gbord = info->filter.blur > 0.0 ? FFMIN(info->filter.blur + 1, INT_MAX) : 0; int bord = FFMAX(bbord, gbord); -- cgit v1.2.3