summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Oshmyan <chortos@inbox.lv>2013-11-08 19:25:20 +0000
committerOleg Oshmyan <chortos@inbox.lv>2013-12-12 19:48:55 +0200
commit2792757cc3a1c92c4d20042ac926481d946d7771 (patch)
tree0e6bcc6e5d74bf406e1a62dfaf9e35d484499ad7
parentde3f0e7572fb927d10857d4177ef58be2c9b3dbc (diff)
downloadlibass-2792757cc3a1c92c4d20042ac926481d946d7771.tar.bz2
libass-2792757cc3a1c92c4d20042ac926481d946d7771.tar.xz
Improve blur quality: use volume 65536 and initialize left column
-rw-r--r--libass/ass_bitmap.c70
1 files changed, 34 insertions, 36 deletions
diff --git a/libass/ass_bitmap.c b/libass/ass_bitmap.c
index 0ad1647..4c6bd14 100644
--- a/libass/ass_bitmap.c
+++ b/libass/ass_bitmap.c
@@ -30,7 +30,7 @@
struct ass_synth_priv {
int tmp_w, tmp_h;
- unsigned short *tmp;
+ unsigned *tmp;
int g_r;
int g_w;
@@ -41,7 +41,6 @@ struct ass_synth_priv {
double radius;
};
-static const unsigned int maxcolor = 255;
static const unsigned base = 256;
static int generate_tables(ASS_SynthPriv *priv, double radius)
@@ -68,7 +67,7 @@ static int generate_tables(ASS_SynthPriv *priv, double radius)
}
if (priv->g_r) {
- // gaussian curve with volume = 256
+ // gaussian curve with volume = 65536
for (volume_diff = 10000000; volume_diff > 0.0000001;
volume_diff *= 0.5) {
volume_factor += volume_diff;
@@ -79,7 +78,7 @@ static int generate_tables(ASS_SynthPriv *priv, double radius)
volume_factor + .5);
volume += priv->g[i];
}
- if (volume > 256)
+ if (volume > 65536)
volume_factor -= volume_diff;
}
volume = 0;
@@ -114,7 +113,7 @@ static void resize_tmp(ASS_SynthPriv *priv, int w, int h)
while (priv->tmp_h < h)
priv->tmp_h *= 2;
free(priv->tmp);
- priv->tmp = malloc((priv->tmp_w + 1) * priv->tmp_h * sizeof(short));
+ priv->tmp = malloc((priv->tmp_w + 1) * priv->tmp_h * sizeof(unsigned));
}
ASS_SynthPriv *ass_synth_init(double radius)
@@ -302,24 +301,25 @@ static void shift_bitmap(Bitmap *bm, int shift_x, int shift_y)
/*
* Gaussian blur. An fast pure C implementation from MPlayer.
*/
-static void ass_gauss_blur(unsigned char *buffer, unsigned short *tmp2,
- int width, int height, int stride, int *m2,
- int r, int mwidth)
+static void ass_gauss_blur(unsigned char *buffer, unsigned *tmp2,
+ int width, int height, int stride,
+ unsigned *m2, int r, int mwidth)
{
int x, y;
unsigned char *s = buffer;
- unsigned short *t = tmp2 + 1;
+ unsigned *t = tmp2 + 1;
for (y = 0; y < height; y++) {
- memset(t - 1, 0, (width + 1) * sizeof(short));
+ memset(t - 1, 0, (width + 1) * sizeof(unsigned));
+ t[-1] = 32768;
for (x = 0; x < r; x++) {
const int src = s[x];
if (src) {
- register unsigned short *dstp = t + x - r;
+ register unsigned *dstp = t + x - r;
int mx;
- unsigned *m3 = (unsigned *) (m2 + src * mwidth);
+ unsigned *m3 = m2 + src * mwidth;
for (mx = r - x; mx < mwidth; mx++) {
dstp[mx] += m3[mx];
}
@@ -329,9 +329,9 @@ static void ass_gauss_blur(unsigned char *buffer, unsigned short *tmp2,
for (; x < width - r; x++) {
const int src = s[x];
if (src) {
- register unsigned short *dstp = t + x - r;
+ register unsigned *dstp = t + x - r;
int mx;
- unsigned *m3 = (unsigned *) (m2 + src * mwidth);
+ unsigned *m3 = m2 + src * mwidth;
for (mx = 0; mx < mwidth; mx++) {
dstp[mx] += m3[mx];
}
@@ -341,10 +341,10 @@ static void ass_gauss_blur(unsigned char *buffer, unsigned short *tmp2,
for (; x < width; x++) {
const int src = s[x];
if (src) {
- register unsigned short *dstp = t + x - r;
+ register unsigned *dstp = t + x - r;
int mx;
const int x2 = r + width - x;
- unsigned *m3 = (unsigned *) (m2 + src * mwidth);
+ unsigned *m3 = m2 + src * mwidth;
for (mx = 0; mx < x2; mx++) {
dstp[mx] += m3[mx];
}
@@ -358,15 +358,15 @@ static void ass_gauss_blur(unsigned char *buffer, unsigned short *tmp2,
t = tmp2;
for (x = 0; x < width; x++) {
for (y = 0; y < r; y++) {
- unsigned short *srcp = t + y * (width + 1) + 1;
+ unsigned *srcp = t + y * (width + 1) + 1;
int src = *srcp;
if (src) {
- register unsigned short *dstp = srcp - 1 + width + 1;
- const int src2 = (src + 128) >> 8;
- unsigned *m3 = (unsigned *) (m2 + src2 * mwidth);
+ register unsigned *dstp = srcp - 1 + width + 1;
+ const int src2 = (src + 32768) >> 16;
+ unsigned *m3 = m2 + src2 * mwidth;
int mx;
- *srcp = 128;
+ *srcp = 32768;
for (mx = r - 1; mx < mwidth; mx++) {
*dstp += m3[mx];
dstp += width + 1;
@@ -374,15 +374,15 @@ static void ass_gauss_blur(unsigned char *buffer, unsigned short *tmp2,
}
}
for (; y < height - r; y++) {
- unsigned short *srcp = t + y * (width + 1) + 1;
+ unsigned *srcp = t + y * (width + 1) + 1;
int src = *srcp;
if (src) {
- register unsigned short *dstp = srcp - 1 - r * (width + 1);
- const int src2 = (src + 128) >> 8;
- unsigned *m3 = (unsigned *) (m2 + src2 * mwidth);
+ register unsigned *dstp = srcp - 1 - r * (width + 1);
+ const int src2 = (src + 32768) >> 16;
+ unsigned *m3 = m2 + src2 * mwidth;
int mx;
- *srcp = 128;
+ *srcp = 32768;
for (mx = 0; mx < mwidth; mx++) {
*dstp += m3[mx];
dstp += width + 1;
@@ -390,16 +390,16 @@ static void ass_gauss_blur(unsigned char *buffer, unsigned short *tmp2,
}
}
for (; y < height; y++) {
- unsigned short *srcp = t + y * (width + 1) + 1;
+ unsigned *srcp = t + y * (width + 1) + 1;
int src = *srcp;
if (src) {
const int y2 = r + height - y;
- register unsigned short *dstp = srcp - 1 - r * (width + 1);
- const int src2 = (src + 128) >> 8;
- unsigned *m3 = (unsigned *) (m2 + src2 * mwidth);
+ register unsigned *dstp = srcp - 1 - r * (width + 1);
+ const int src2 = (src + 32768) >> 16;
+ unsigned *m3 = m2 + src2 * mwidth;
int mx;
- *srcp = 128;
+ *srcp = 32768;
for (mx = 0; mx < y2; mx++) {
*dstp += m3[mx];
dstp += width + 1;
@@ -413,7 +413,7 @@ static void ass_gauss_blur(unsigned char *buffer, unsigned short *tmp2,
s = buffer;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
- s[x] = t[x] >> 8;
+ s[x] = t[x] >> 16;
}
s += stride;
t += width + 1;
@@ -499,13 +499,11 @@ int outline_to_bitmap3(ASS_Library *library, ASS_SynthPriv *priv_blur,
if (*bm_o)
ass_gauss_blur((*bm_o)->buffer, priv_blur->tmp,
(*bm_o)->w, (*bm_o)->h, (*bm_o)->stride,
- (int *) priv_blur->gt2, priv_blur->g_r,
- priv_blur->g_w);
+ 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,
- (int *) priv_blur->gt2, priv_blur->g_r,
- priv_blur->g_w);
+ priv_blur->gt2, priv_blur->g_r, priv_blur->g_w);
}
// Create shadow and fix outline as needed