summaryrefslogtreecommitdiffstats
path: root/libass/ass_bitmap.c
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@blackbox>2011-06-26 05:44:52 +0200
committerGrigori Goronzy <greg@blackbox>2011-06-26 05:44:52 +0200
commitc13cb222435ff61533a26efcd46c6246ea541dc1 (patch)
treef03ac5753c0b2b790da042655b738aebe9af4a0d /libass/ass_bitmap.c
parent1d3bc3309153410ea8baaa111ee846f289b572a2 (diff)
downloadlibass-c13cb222435ff61533a26efcd46c6246ea541dc1.tar.bz2
libass-c13cb222435ff61533a26efcd46c6246ea541dc1.tar.xz
bitmap: add stride
Add stride support to the basic bitmap type used for low-level rasterization.
Diffstat (limited to 'libass/ass_bitmap.c')
-rw-r--r--libass/ass_bitmap.c80
1 files changed, 44 insertions, 36 deletions
diff --git a/libass/ass_bitmap.c b/libass/ass_bitmap.c
index 949126a..5a2dc80 100644
--- a/libass/ass_bitmap.c
+++ b/libass/ass_bitmap.c
@@ -135,10 +135,12 @@ void ass_synth_done(ASS_SynthPriv *priv)
static Bitmap *alloc_bitmap(int w, int h)
{
Bitmap *bm;
+ unsigned s = w; // XXX: alignment
bm = malloc(sizeof(Bitmap));
- bm->buffer = calloc(w, h);
+ bm->buffer = calloc(s, h);
bm->w = w;
bm->h = h;
+ bm->stride = s;
bm->left = bm->top = 0;
return bm;
}
@@ -155,7 +157,7 @@ static Bitmap *copy_bitmap(const Bitmap *src)
Bitmap *dst = alloc_bitmap(src->w, src->h);
dst->left = src->left;
dst->top = src->top;
- memcpy(dst->buffer, src->buffer, src->w * src->h);
+ memcpy(dst->buffer, src->buffer, src->stride * src->h);
return dst;
}
@@ -194,8 +196,8 @@ Bitmap *outline_to_bitmap(ASS_Library *library, FT_Library ftlib,
bm->top = -bbox.yMax - bord;
bitmap.width = w;
bitmap.rows = h;
- bitmap.pitch = bm->w;
- bitmap.buffer = bm->buffer + bord + bm->w * bord;
+ bitmap.pitch = bm->stride;
+ bitmap.buffer = bm->buffer + bord + bm->stride * bord;
bitmap.num_grays = 256;
bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
@@ -223,16 +225,16 @@ static void fix_outline(Bitmap *bm_g, Bitmap *bm_o)
const int l = bm_o->left > bm_g->left ? bm_o->left : bm_g->left;
const int t = bm_o->top > bm_g->top ? bm_o->top : bm_g->top;
const int r =
- bm_o->left + bm_o->w <
- bm_g->left + bm_g->w ? bm_o->left + bm_o->w : bm_g->left + bm_g->w;
+ bm_o->left + bm_o->stride <
+ bm_g->left + bm_g->stride ? bm_o->left + bm_o->stride : bm_g->left + bm_g->stride;
const int b =
bm_o->top + bm_o->h <
bm_g->top + bm_g->h ? bm_o->top + bm_o->h : bm_g->top + bm_g->h;
unsigned char *g =
- bm_g->buffer + (t - bm_g->top) * bm_g->w + (l - bm_g->left);
+ bm_g->buffer + (t - bm_g->top) * bm_g->stride + (l - bm_g->left);
unsigned char *o =
- bm_o->buffer + (t - bm_o->top) * bm_o->w + (l - bm_o->left);
+ bm_o->buffer + (t - bm_o->top) * bm_o->stride + (l - bm_o->left);
for (y = 0; y < b - t; ++y) {
for (x = 0; x < r - l; ++x) {
@@ -241,8 +243,8 @@ static void fix_outline(Bitmap *bm_g, Bitmap *bm_o)
c_o = o[x];
o[x] = (c_o > c_g) ? c_o - (c_g / 2) : 0;
}
- g += bm_g->w;
- o += bm_o->w;
+ g += bm_g->stride;
+ o += bm_o->stride;
}
}
@@ -250,27 +252,30 @@ static void fix_outline(Bitmap *bm_g, Bitmap *bm_o)
* \brief Shift a bitmap by the fraction of a pixel in x and y direction
* expressed in 26.6 fixed point
*/
-static void shift_bitmap(unsigned char *buf, int w, int h, int shift_x,
- int shift_y)
+static void shift_bitmap(Bitmap *bm, int shift_x, int shift_y)
{
int x, y, b;
+ int w = bm->w;
+ int h = bm->h;
+ int s = bm->stride;
+ unsigned char *buf = bm->buffer;
// Shift in x direction
if (shift_x > 0) {
for (y = 0; y < h; y++) {
for (x = w - 1; x > 0; x--) {
- b = (buf[x + y * w - 1] * shift_x) >> 6;
- buf[x + y * w - 1] -= b;
- buf[x + y * w] += b;
+ b = (buf[x + y * s - 1] * shift_x) >> 6;
+ buf[x + y * s - 1] -= b;
+ buf[x + y * s] += b;
}
}
} else if (shift_x < 0) {
shift_x = -shift_x;
for (y = 0; y < h; y++) {
for (x = 0; x < w - 1; x++) {
- b = (buf[x + y * w + 1] * shift_x) >> 6;
- buf[x + y * w + 1] -= b;
- buf[x + y * w] += b;
+ b = (buf[x + y * s + 1] * shift_x) >> 6;
+ buf[x + y * s + 1] -= b;
+ buf[x + y * s] += b;
}
}
}
@@ -279,18 +284,18 @@ static void shift_bitmap(unsigned char *buf, int w, int h, int shift_x,
if (shift_y > 0) {
for (x = 0; x < w; x++) {
for (y = h - 1; y > 0; y--) {
- b = (buf[x + (y - 1) * w] * shift_y) >> 6;
- buf[x + (y - 1) * w] -= b;
- buf[x + y * w] += b;
+ b = (buf[x + (y - 1) * s] * shift_y) >> 6;
+ buf[x + (y - 1) * s] -= b;
+ buf[x + y * s] += b;
}
}
} else if (shift_y < 0) {
shift_y = -shift_y;
for (x = 0; x < w; x++) {
for (y = 0; y < h - 1; y++) {
- b = (buf[x + (y + 1) * w] * shift_y) >> 6;
- buf[x + (y + 1) * w] -= b;
- buf[x + y * w] += b;
+ b = (buf[x + (y + 1) * s] * shift_y) >> 6;
+ buf[x + (y + 1) * s] -= b;
+ buf[x + y * s] += b;
}
}
}
@@ -421,16 +426,20 @@ static void ass_gauss_blur(unsigned char *buffer, unsigned short *tmp2,
* \brief Blur with [[1,2,1]. [2,4,2], [1,2,1]] kernel
* This blur is the same as the one employed by vsfilter.
*/
-static void be_blur(unsigned char *buf, int w, int h)
+static void be_blur(Bitmap *bm)
{
+ int w = bm->w;
+ int h = bm->h;
+ int s = bm->stride;
+ unsigned char *buf = bm->buffer;
unsigned int x, y;
unsigned int old_sum, new_sum;
for (y = 0; y < h; y++) {
- old_sum = 2 * buf[y * w];
+ old_sum = 2 * buf[y * s];
for (x = 0; x < w - 1; x++) {
- new_sum = buf[y * w + x] + buf[y * w + x + 1];
- buf[y * w + x] = (old_sum + new_sum) >> 2;
+ new_sum = buf[y * s + x] + buf[y * s + x + 1];
+ buf[y * s + x] = (old_sum + new_sum) >> 2;
old_sum = new_sum;
}
}
@@ -438,8 +447,8 @@ static void be_blur(unsigned char *buf, int w, int h)
for (x = 0; x < w; x++) {
old_sum = 2 * buf[x];
for (y = 0; y < h - 1; y++) {
- new_sum = buf[y * w + x] + buf[(y + 1) * w + x];
- buf[y * w + x] = (old_sum + new_sum) >> 2;
+ new_sum = buf[y * s + x] + buf[(y + 1) * s + x];
+ buf[y * s + x] = (old_sum + new_sum) >> 2;
old_sum = new_sum;
}
}
@@ -477,9 +486,9 @@ int outline_to_bitmap3(ASS_Library *library, ASS_SynthPriv *priv_blur,
// Apply box blur (multiple passes, if requested)
while (be--) {
if (*bm_o)
- be_blur((*bm_o)->buffer, (*bm_o)->w, (*bm_o)->h);
+ be_blur(*bm_o);
else
- be_blur((*bm_g)->buffer, (*bm_g)->w, (*bm_g)->h);
+ be_blur(*bm_o);
}
// Apply gaussian blur
@@ -491,12 +500,12 @@ int outline_to_bitmap3(ASS_Library *library, ASS_SynthPriv *priv_blur,
generate_tables(priv_blur, blur_radius);
if (*bm_o)
ass_gauss_blur((*bm_o)->buffer, priv_blur->tmp,
- (*bm_o)->w, (*bm_o)->h, (*bm_o)->w,
+ (*bm_o)->w, (*bm_o)->h, (*bm_o)->stride,
(int *) priv_blur->gt2, priv_blur->g_r,
priv_blur->g_w);
else
ass_gauss_blur((*bm_g)->buffer, priv_blur->tmp,
- (*bm_g)->w, (*bm_g)->h, (*bm_g)->w,
+ (*bm_g)->w, (*bm_g)->h, (*bm_g)->stride,
(int *) priv_blur->gt2, priv_blur->g_r,
priv_blur->g_w);
}
@@ -512,8 +521,7 @@ int outline_to_bitmap3(ASS_Library *library, ASS_SynthPriv *priv_blur,
assert(bm_s);
- shift_bitmap((*bm_s)->buffer, (*bm_s)->w,(*bm_s)->h,
- shadow_offset.x, shadow_offset.y);
+ shift_bitmap(*bm_s, shadow_offset.x, shadow_offset.y);
return 0;
}