summaryrefslogtreecommitdiffstats
path: root/libvo/bitmap_packer.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvo/bitmap_packer.c')
-rw-r--r--libvo/bitmap_packer.c48
1 files changed, 40 insertions, 8 deletions
diff --git a/libvo/bitmap_packer.c b/libvo/bitmap_packer.c
index 2ae8a1eee0..eedc2e2242 100644
--- a/libvo/bitmap_packer.c
+++ b/libvo/bitmap_packer.c
@@ -28,6 +28,7 @@
#include "mp_msg.h"
#include "mpcommon.h"
#include "sub/ass_mp.h"
+#include "sub/dec_sub.h"
#define HEIGHT_SORT_BITS 4
@@ -55,7 +56,7 @@ static int size_index(int s)
* free rectangle with corners (13, 20)-(w, 50) is filled recursively.
*/
static int pack_rectangles(struct pos *in, struct pos *out, int num_rects,
- int w, int h, int *scratch)
+ int w, int h, int *scratch, int *used_width)
{
int bins[16 << HEIGHT_SORT_BITS];
int sizes[16 << HEIGHT_SORT_BITS] = { 0 };
@@ -100,11 +101,12 @@ static int pack_rectangles(struct pos *in, struct pos *out, int num_rects,
s.x = right;
maxy = FFMAX(maxy, bottom);
}
+ *used_width = FFMAX(*used_width, s.x);
if (maxy > 0)
s.bottom = maxy;
}
}
- return num_rects ? -1 : 0;
+ return num_rects ? -1 : y;
}
int packer_pack(struct bitmap_packer *packer)
@@ -115,7 +117,7 @@ int packer_pack(struct bitmap_packer *packer)
struct pos *in = packer->in;
int xmax = 0, ymax = 0;
for (int i = 0; i < packer->count; i++) {
- if (in[i].x == 0 || in[i].y == 0)
+ if (in[i].x <= packer->padding || in[i].y <= packer->padding)
in[i] = (struct pos){0, 0};
if (in[i].x < 0 || in [i].x > 65535 || in[i].y < 0 || in[i].y > 65535) {
mp_msg(MSGT_VO, MSGL_FATAL, "Invalid OSD / subtitle bitmap size\n");
@@ -124,20 +126,33 @@ int packer_pack(struct bitmap_packer *packer)
xmax = FFMAX(xmax, in[i].x);
ymax = FFMAX(ymax, in[i].y);
}
+ xmax = FFMAX(0, xmax - packer->padding);
+ ymax = FFMAX(0, ymax - packer->padding);
if (xmax > packer->w)
packer->w = 1 << av_log2(xmax - 1) + 1;
if (ymax > packer->h)
packer->h = 1 << av_log2(ymax - 1) + 1;
while (1) {
- if (pack_rectangles(in, packer->result, packer->count, packer->w,
- packer->h, packer->scratch) >= 0)
+ int used_width = 0;
+ int y = pack_rectangles(in, packer->result, packer->count,
+ packer->w + packer->padding,
+ packer->h + packer->padding,
+ packer->scratch, &used_width);
+ if (y >= 0) {
+ // No padding at edges
+ packer->used_width = FFMIN(used_width, packer->w);
+ packer->used_height = FFMIN(y, packer->h);
return packer->w != w_orig || packer->h != h_orig;
+ }
if (packer->w <= packer->h && packer->w != packer->w_max)
packer->w = FFMIN(packer->w * 2, packer->w_max);
else if (packer->h != packer->h_max)
packer->h = FFMIN(packer->h * 2, packer->h_max);
- else
+ else {
+ packer->w = w_orig;
+ packer->h = h_orig;
return -1;
+ }
}
}
@@ -156,8 +171,8 @@ void packer_set_size(struct bitmap_packer *packer, int size)
packer->asize + 16);
}
-int packer_pack_from_assimg(struct bitmap_packer *packer,
- struct ass_image *imglist)
+static int packer_pack_from_assimg(struct bitmap_packer *packer,
+ struct ass_image *imglist)
{
int count = 0;
struct ass_image *img = imglist;
@@ -172,3 +187,20 @@ int packer_pack_from_assimg(struct bitmap_packer *packer,
packer->count = count;
return packer_pack(packer);
}
+
+int packer_pack_from_subbitmaps(struct bitmap_packer *packer,
+ struct sub_bitmaps *b, int padding_pixels)
+{
+ packer->padding = 0;
+ packer->count = 0;
+ if (b->type == SUBBITMAP_EMPTY)
+ return 0;
+ if (b->type == SUBBITMAP_LIBASS)
+ return packer_pack_from_assimg(packer, b->imgs);
+ packer->padding = padding_pixels;
+ packer_set_size(packer, b->part_count);
+ int a = packer->padding;
+ for (int i = 0; i < b->part_count; i++)
+ packer->in[i] = (struct pos){b->parts[i].w + a, b->parts[i].h + a};
+ return packer_pack(packer);
+}