#include "libavutil/colorspace.h"
#include "libavutil/opt.h"
#include "libavutil/imgutils.h"
-#include "libavutil/avstring.h"
#include "libavutil/bswap.h"
typedef struct DVDSubContext
uint8_t buf[0x10000];
int buf_size;
int forced_subs_only;
+ uint8_t used_color[256];
#ifdef DEBUG
int sub_id;
#endif
{
int len;
int has_run = get_bits1(gb);
- if (get_bits1(gb))
- *color = get_bits(gb, 8);
- else
- *color = get_bits(gb, 2);
+ *color = get_bits(gb, 2 + 6*get_bits1(gb));
if (has_run) {
if (get_bits1(gb)) {
len = get_bits(gb, 7);
return len;
}
-static int decode_rle(uint8_t *bitmap, int linesize, int w, int h,
+static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, uint8_t used_color[256],
const uint8_t *buf, int start, int buf_size, int is_8bit)
{
GetBitContext gb;
len = decode_run_8bit(&gb, &color);
else
len = decode_run_2bit(&gb, &color);
+ if (len != INT_MAX && len > w - x)
+ return AVERROR_INVALIDDATA;
len = FFMIN(len, w - x);
memset(d + x, color, len);
+ used_color[color] = 1;
x += len;
if (x >= w) {
y++;
h = 0;
if (w > 0 && h > 1) {
reset_rects(sub_header);
-
+ memset(ctx->used_color, 0, sizeof(ctx->used_color));
sub_header->rects = av_mallocz(sizeof(*sub_header->rects));
if (!sub_header->rects)
goto fail;
bitmap = sub_header->rects[0]->data[0] = av_malloc(w * h);
if (!bitmap)
goto fail;
- if (decode_rle(bitmap, w * 2, w, (h + 1) / 2,
+ if (decode_rle(bitmap, w * 2, w, (h + 1) / 2, ctx->used_color,
buf, offset1, buf_size, is_8bit) < 0)
goto fail;
- if (decode_rle(bitmap + w, w * 2, w, h / 2,
+ if (decode_rle(bitmap + w, w * 2, w, h / 2, ctx->used_color,
buf, offset2, buf_size, is_8bit) < 0)
goto fail;
sub_header->rects[0]->data[1] = av_mallocz(AVPALETTE_SIZE);
sub_header->rects[0]->type = SUBTITLE_BITMAP;
sub_header->rects[0]->linesize[0] = w;
sub_header->rects[0]->flags = is_menu ? AV_SUBTITLE_FLAG_FORCED : 0;
-
-#if FF_API_AVPICTURE
-FF_DISABLE_DEPRECATION_WARNINGS
- for (i = 0; i < 4; i++) {
- sub_header->rects[0]->pict.data[i] = sub_header->rects[0]->data[i];
- sub_header->rects[0]->pict.linesize[i] = sub_header->rects[0]->linesize[i];
- }
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
}
}
if (next_cmd_pos < cmd_pos) {
}
/* return 0 if empty rectangle, 1 if non empty */
-static int find_smallest_bounding_rectangle(AVSubtitle *s)
+static int find_smallest_bounding_rectangle(DVDSubContext *ctx, AVSubtitle *s)
{
uint8_t transp_color[256] = { 0 };
int y1, y2, x1, x2, y, w, h, i;
uint8_t *bitmap;
+ int transparent = 1;
if (s->num_rects == 0 || !s->rects || s->rects[0]->w <= 0 || s->rects[0]->h <= 0)
return 0;
for(i = 0; i < s->rects[0]->nb_colors; i++) {
- if ((((uint32_t *)s->rects[0]->data[1])[i] >> 24) == 0)
+ if ((((uint32_t *)s->rects[0]->data[1])[i] >> 24) == 0) {
transp_color[i] = 1;
+ } else if (ctx->used_color[i])
+ transparent = 0;
}
+ if (transparent)
+ return 0;
y1 = 0;
while (y1 < s->rects[0]->h && is_transp(s->rects[0]->data[0] + y1 * s->rects[0]->linesize[0],
1, s->rects[0]->w, transp_color))
s->rects[0]->x += x1;
s->rects[0]->y += y1;
-#if FF_API_AVPICTURE
-FF_DISABLE_DEPRECATION_WARNINGS
- for (i = 0; i < 4; i++) {
- s->rects[0]->pict.data[i] = s->rects[0]->data[i];
- s->rects[0]->pict.linesize[i] = s->rects[0]->linesize[i];
- }
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
return 1;
}
}
if (is_menu < 0) {
+ ctx->buf_size = 0;
no_subtitle:
reset_rects(sub);
*data_size = 0;
return buf_size;
}
- if (!is_menu && find_smallest_bounding_rectangle(sub) == 0)
+ if (!is_menu && find_smallest_bounding_rectangle(ctx, sub) == 0)
goto no_subtitle;
if (ctx->forced_subs_only && !(sub->rects[0]->flags & AV_SUBTITLE_FLAG_FORCED))
return buf_size;
}
-static void parse_palette(DVDSubContext *ctx, char *p)
-{
- int i;
-
- ctx->has_palette = 1;
- for(i=0;i<16;i++) {
- ctx->palette[i] = strtoul(p, &p, 16);
- while(*p == ',' || av_isspace(*p))
- p++;
- }
-}
-
static int parse_ifo_palette(DVDSubContext *ctx, char *p)
{
FILE *ifo;
break;
if (strncmp("palette:", data, 8) == 0) {
- parse_palette(ctx, data + 8);
+ ctx->has_palette = 1;
+ ff_dvdsub_parse_palette(ctx->palette, data + 8);
} else if (strncmp("size:", data, 5) == 0) {
int w, h;
if (sscanf(data + 5, "%dx%d", &w, &h) == 2) {
if (ctx->ifo_str)
parse_ifo_palette(ctx, ctx->ifo_str);
- if (ctx->palette_str)
- parse_palette(ctx, ctx->palette_str);
+ if (ctx->palette_str) {
+ ctx->has_palette = 1;
+ ff_dvdsub_parse_palette(ctx->palette, ctx->palette_str);
+ }
if (ctx->has_palette) {
int i;
av_log(avctx, AV_LOG_DEBUG, "palette:");
.version = LIBAVUTIL_VERSION_INT,
};
-AVCodec ff_dvdsub_decoder = {
+const AVCodec ff_dvdsub_decoder = {
.name = "dvdsub",
.long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"),
.type = AVMEDIA_TYPE_SUBTITLE,