summaryrefslogtreecommitdiff
path: root/libavcodec/dvdsubdec.c
diff options
context:
space:
mode:
authorShin-ichi Toyama <shin1@wmail.plala.or.jp>2014-11-15 12:42:30 +0900
committerMichael Niedermayer <michaelni@gmx.at>2014-11-15 12:50:39 +0100
commit12630fa821ea4b0daddf768eeb29103774e34033 (patch)
treee4ff2ea4e3c6e13b6745219f4c4195497d1b8536 /libavcodec/dvdsubdec.c
parentb08fd7ea78792c4e0141e2d384b9acd4699bb5cc (diff)
avcodec/dvdsubdec: New option for obtaining global palette from .IFO file (experimental)
Suggested-by: Nicolas George <george@nsup.org> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/dvdsubdec.c')
-rw-r--r--libavcodec/dvdsubdec.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c
index bb28d9e3b7..d165934cc3 100644
--- a/libavcodec/dvdsubdec.c
+++ b/libavcodec/dvdsubdec.c
@@ -28,12 +28,14 @@
#include "libavutil/opt.h"
#include "libavutil/imgutils.h"
#include "libavutil/avstring.h"
+#include "libavutil/bswap.h"
typedef struct DVDSubContext
{
AVClass *class;
uint32_t palette[16];
char *palette_str;
+ char *ifo_str;
int has_palette;
uint8_t colormap[4];
uint8_t alpha[256];
@@ -583,6 +585,57 @@ static void parse_palette(DVDSubContext *ctx, char *p)
}
}
+static int parse_ifo_palette(DVDSubContext *ctx, char *p)
+{
+ FILE *ifo;
+ char ifostr[12];
+ uint32_t sp_pgci, pgci, off_pgc, pgc;
+ uint8_t r, g, b, yuv[65], *buf;
+ int i, y, cb, cr, r_add, g_add, b_add;
+ int ret = 0;
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+
+ ctx->has_palette = 0;
+ if ((ifo = fopen(p, "r")) == NULL) {
+ av_log(ctx, AV_LOG_WARNING, "Unable to open IFO file \"%s\": %s\n", p, strerror(errno));
+ return AVERROR_EOF;
+ }
+ if (fread(ifostr, 12, 1, ifo) != 1 || memcmp(ifostr, "DVDVIDEO-VTS", 12)) {
+ av_log(ctx, AV_LOG_WARNING, "\"%s\" is not a proper IFO file\n", p);
+ ret = AVERROR_INVALIDDATA;
+ goto end;
+ }
+ fseek(ifo, 0xCC, SEEK_SET);
+ if (fread(&sp_pgci, 4, 1, ifo) == 1) {
+ pgci = av_be2ne32(sp_pgci) * 2048;
+ fseek(ifo, pgci + 0x0C, SEEK_SET);
+ if (fread(&off_pgc, 4, 1, ifo) == 1) {
+ pgc = pgci + av_be2ne32(off_pgc);
+ fseek(ifo, pgc + 0xA4, SEEK_SET);
+ if (fread(yuv, 64, 1, ifo) == 1) {
+ buf = yuv;
+ for(i=0; i<16; i++) {
+ y = *++buf;
+ cr = *++buf;
+ cb = *++buf;
+ YUV_TO_RGB1_CCIR(cb, cr);
+ YUV_TO_RGB2_CCIR(r, g, b, y);
+ ctx->palette[i] = (r << 16) + (g << 8) + b;
+ buf++;
+ }
+ ctx->has_palette = 1;
+ }
+ }
+ }
+ if (ctx->has_palette == 0) {
+ av_log(ctx, AV_LOG_WARNING, "Failed to read palette from IFO file \"%s\"\n", p);
+ ret = AVERROR_INVALIDDATA;
+ }
+end:
+ fclose(ifo);
+ return ret;
+}
+
static int dvdsub_parse_extradata(AVCodecContext *avctx)
{
DVDSubContext *ctx = (DVDSubContext*) avctx->priv_data;
@@ -631,6 +684,8 @@ static av_cold int dvdsub_init(AVCodecContext *avctx)
if ((ret = dvdsub_parse_extradata(avctx)) < 0)
return ret;
+ if (ctx->ifo_str)
+ parse_ifo_palette(ctx, ctx->ifo_str);
if (ctx->palette_str)
parse_palette(ctx, ctx->palette_str);
if (ctx->has_palette) {
@@ -656,6 +711,7 @@ static av_cold int dvdsub_close(AVCodecContext *avctx)
#define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
{ "palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SD },
+ { "ifo_palette", "obtain the global palette from .IFO file", OFFSET(ifo_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SD },
{ "forced_subs_only", "Only show forced subtitles", OFFSET(forced_subs_only), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SD},
{ NULL }
};