summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--libass/ass_bitmap.c80
-rw-r--r--libass/ass_bitmap.h1
-rw-r--r--libass/ass_render.c16
3 files changed, 53 insertions, 44 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;
}
diff --git a/libass/ass_bitmap.h b/libass/ass_bitmap.h
index d21ea4e..2a46aec 100644
--- a/libass/ass_bitmap.h
+++ b/libass/ass_bitmap.h
@@ -32,6 +32,7 @@ void ass_synth_done(ASS_SynthPriv *priv);
typedef struct {
int left, top;
int w, h; // width, height
+ int stride;
unsigned char *buffer; // w x h buffer
} Bitmap;
diff --git a/libass/ass_render.c b/libass/ass_render.c
index 021bfc4..b036bf2 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -296,18 +296,18 @@ static ASS_Image **render_glyph_i(ASS_Renderer *render_priv,
// split up into left and right for karaoke, if needed
if (lbrk > r[j].x0) {
if (lbrk > r[j].x1) lbrk = r[j].x1;
- img = my_draw_bitmap(bm->buffer + r[j].y0 * bm->w + r[j].x0,
+ img = my_draw_bitmap(bm->buffer + r[j].y0 * bm->stride + r[j].x0,
lbrk - r[j].x0, r[j].y1 - r[j].y0,
- bm->w, dst_x + r[j].x0, dst_y + r[j].y0, color);
+ bm->stride, dst_x + r[j].x0, dst_y + r[j].y0, color);
if (!img) break;
*tail = img;
tail = &img->next;
}
if (lbrk < r[j].x1) {
if (lbrk < r[j].x0) lbrk = r[j].x0;
- img = my_draw_bitmap(bm->buffer + r[j].y0 * bm->w + lbrk,
+ img = my_draw_bitmap(bm->buffer + r[j].y0 * bm->stride + lbrk,
r[j].x1 - lbrk, r[j].y1 - r[j].y0,
- bm->w, dst_x + lbrk, dst_y + r[j].y0, color2);
+ bm->stride, dst_x + lbrk, dst_y + r[j].y0, color2);
if (!img) break;
*tail = img;
tail = &img->next;
@@ -387,8 +387,8 @@ render_glyph(ASS_Renderer *render_priv, Bitmap *bm, int dst_x, int dst_y,
if (brk > b_x0) { // draw left part
if (brk > b_x1)
brk = b_x1;
- img = my_draw_bitmap(bm->buffer + bm->w * b_y0 + b_x0,
- brk - b_x0, b_y1 - b_y0, bm->w,
+ img = my_draw_bitmap(bm->buffer + bm->stride * b_y0 + b_x0,
+ brk - b_x0, b_y1 - b_y0, bm->stride,
dst_x + b_x0, dst_y + b_y0, color);
if (!img) return tail;
*tail = img;
@@ -397,8 +397,8 @@ render_glyph(ASS_Renderer *render_priv, Bitmap *bm, int dst_x, int dst_y,
if (brk < b_x1) { // draw right part
if (brk < b_x0)
brk = b_x0;
- img = my_draw_bitmap(bm->buffer + bm->w * b_y0 + brk,
- b_x1 - brk, b_y1 - b_y0, bm->w,
+ img = my_draw_bitmap(bm->buffer + bm->stride * b_y0 + brk,
+ b_x1 - brk, b_y1 - b_y0, bm->stride,
dst_x + brk, dst_y + b_y0, color2);
if (!img) return tail;
*tail = img;