]> granicus.if.org Git - libass/commitdiff
bitmap: add stride
authorGrigori Goronzy <greg@blackbox>
Sun, 26 Jun 2011 03:44:52 +0000 (05:44 +0200)
committerGrigori Goronzy <greg@blackbox>
Sun, 26 Jun 2011 03:44:52 +0000 (05:44 +0200)
Add stride support to the basic bitmap type used for low-level
rasterization.

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

index 949126a0892ab060915a1be31cf35bfd9ac6917d..5a2dc80c94754ce76c9f6c4a3253c07c822bca56 100644 (file)
@@ -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;
 }
index d21ea4e7557fd55bcafc811f68a860941007b734..2a46aec447c90589f53505b14eaf58910a708c54 100644 (file)
@@ -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;
 
index 021bfc4c59d8d7304e712bc02f52eb1c0dd77bf4..b036bf2e247416a7215c9b792f564fca1f43337e 100644 (file)
@@ -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;