/* Libass renderer object. Contents are private. */
typedef struct ass_renderer_s ass_renderer_t;
-/* A linked list of images produced by ass renderer. */
+/*
+ * A linked list of images produced by an ass renderer.
+ *
+ * These images have to be rendered in-order for the correct screen
+ * composition. The libass renderer clips these bitmaps to the frame size.
+ * w/h can be zero, in this case the bitmap should not be rendered at all.
+ * The last bitmap row is not guaranteed to be padded up to stride size,
+ * e.g. in the worst case a bitmap has the size stride * (h - 1) + w.
+ */
typedef struct ass_image_s {
int w, h; // Bitmap width/height
int stride; // Bitmap stride
unsigned char *bitmap; // 1bpp stride*h alpha buffer
+ // Note: the last row may not be padded to
+ // bitmap stride!
uint32_t color; // Bitmap color and alpha, RGBA
int dst_x, dst_y; // Bitmap placement inside the video frame
return tail;
}
+/**
+ * \brief Replace the bitmap buffer in ass_image_t with a copy
+ * \param img ass_image_t to operate on
+ * \return pointer to old bitmap buffer
+ */
+static unsigned char *clone_bitmap_buffer(ass_image_t *img)
+{
+ unsigned char *old_bitmap = img->bitmap;
+ int size = img->stride * (img->h - 1) + img->w;
+ img->bitmap = malloc(size);
+ memcpy(img->bitmap, old_bitmap, size);
+ return old_bitmap;
+}
+
/**
* \brief Calculate overlapping area of two consecutive bitmaps and in case they
* overlap, composite them together
return;
}
// Allocate new bitmaps and copy over data
- a = (*last_tail)->bitmap;
- b = (*tail)->bitmap;
- (*last_tail)->bitmap = malloc(as * ah);
- (*tail)->bitmap = malloc(bs * bh);
- memcpy((*last_tail)->bitmap, a, as * ah);
- memcpy((*tail)->bitmap, b, bs * bh);
+ a = clone_bitmap_buffer(*last_tail);
+ b = clone_bitmap_buffer(*tail);
// Composite overlapping area
for (y = 0; y < h; y++)