]> granicus.if.org Git - libass/commitdiff
Add enough padding for \be to avoid clipping
authorOleg Oshmyan <chortos@inbox.lv>
Mon, 9 Feb 2015 13:18:44 +0000 (15:18 +0200)
committerOleg Oshmyan <chortos@inbox.lv>
Tue, 10 Feb 2015 02:42:35 +0000 (04:42 +0200)
To avoid making bitmaps unnecessarily large, use just
the necessary amount of padding for the given \be value.

libass/ass_bitmap.c
libass/ass_bitmap.h
libass/ass_render.c

index 5f0991d619ca20c5908c6956963d8f3589f5d3ad..286f904f8abd5d799e3288f0d3b83ba84761f5c9 100644 (file)
@@ -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)
index 5014f51a660a2e6fb8f610d22a06e642c74f6936..901adc707c4f53da3aaa516a25963881cf4e2a09 100644 (file)
@@ -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);
index 614078800621a78b2892e6f739896c5d71b6461f..a02bcab1bea43df05ed92ccc7f163df256ffbc76 100644 (file)
@@ -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);