summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Oshmyan <chortos@inbox.lv>2013-02-01 23:35:02 +0000
committerGrigori Goronzy <greg@blackbox>2013-03-03 23:17:53 +0100
commit1ae86d2390b3e64b5f6574fa1628461bc403ae14 (patch)
tree9027365853409126cb33d4c64dd907718819219e
parent0e1702ad7a6a827d400c87b7a98aea11e54d2127 (diff)
downloadlibass-1ae86d2390b3e64b5f6574fa1628461bc403ae14.tar.bz2
libass-1ae86d2390b3e64b5f6574fa1628461bc403ae14.tar.xz
Support reading the YCbCr Matrix header
The value is parsed and stored as an enum constant that the consumer can read from ASS_Track. All output images are still plain RGB, and the consumer is expected to perform its own color correction. Supported header values: (TV|PC).(601|709|240M|FCC) and None. If the header is missing, a special compatibility value is used that should be treated as TV.601 if the accompanying video stream is YCbCr and as None otherwise. If the header is present but has an invalid/unknown value, a different special value is substituted.
-rw-r--r--libass/ass.c4
-rw-r--r--libass/ass_types.h13
-rw-r--r--libass/ass_utils.c40
-rw-r--r--libass/ass_utils.h1
4 files changed, 58 insertions, 0 deletions
diff --git a/libass/ass.c b/libass/ass.c
index 678a9a3..576f04b 100644
--- a/libass/ass.c
+++ b/libass/ass.c
@@ -387,6 +387,8 @@ void ass_process_force_style(ASS_Track *track)
track->ScaledBorderAndShadow = parse_bool(token);
else if (!strcasecmp(*fs, "Kerning"))
track->Kerning = parse_bool(token);
+ else if (!strcasecmp(*fs, "YCbCr Matrix"))
+ track->YCbCrMatrix = parse_ycbcr_matrix(token);
dt = strrchr(*fs, '.');
if (dt) {
@@ -574,6 +576,8 @@ static int process_info_line(ASS_Track *track, char *str)
track->ScaledBorderAndShadow = parse_bool(str + 22);
} else if (!strncmp(str, "Kerning:", 8)) {
track->Kerning = parse_bool(str + 8);
+ } else if (!strncmp(str, "YCbCr Matrix:", 13)) {
+ track->YCbCrMatrix = parse_ycbcr_matrix(str + 13);
} else if (!strncmp(str, "Language:", 9)) {
char *p = str + 9;
while (*p && isspace(*p)) p++;
diff --git a/libass/ass_types.h b/libass/ass_types.h
index 677ba96..bc003aa 100644
--- a/libass/ass_types.h
+++ b/libass/ass_types.h
@@ -114,6 +114,19 @@ typedef struct ass_track {
int ScaledBorderAndShadow;
int Kerning;
char *Language;
+ enum {
+ YCBCR_DEFAULT = 0, // TV.601 on YCbCr video, None on RGB video
+ YCBCR_UNKNOWN,
+ YCBCR_NONE, // untouched RGB values
+ YCBCR_BT601_TV,
+ YCBCR_BT601_PC,
+ YCBCR_BT709_TV,
+ YCBCR_BT709_PC,
+ YCBCR_SMPTE240M_TV,
+ YCBCR_SMPTE240M_PC,
+ YCBCR_FCC_TV,
+ YCBCR_FCC_PC
+ } YCbCrMatrix;
int default_style; // index of default style
char *name; // file name in case of external subs, 0 for streams
diff --git a/libass/ass_utils.c b/libass/ass_utils.c
index 222e99a..df7c447 100644
--- a/libass/ass_utils.c
+++ b/libass/ass_utils.c
@@ -122,6 +122,46 @@ char parse_bool(char *str)
return 0;
}
+int parse_ycbcr_matrix(char *str)
+{
+ while (*str == ' ' || *str == '\t')
+ str++;
+ if (*str == '\0')
+ return YCBCR_DEFAULT;
+
+ char *end = str + strlen(str);
+ while (end[-1] == ' ' || end[-1] == '\t')
+ end--;
+
+ // Trim a local copy of the input that we know is safe to
+ // modify. The buffer is larger than any valid string + NUL,
+ // so we can simply chop off the rest of the input.
+ char buffer[16];
+ size_t n = FFMIN(end - str, sizeof buffer - 1);
+ strncpy(buffer, str, n);
+ buffer[n] = '\0';
+
+ if (!strcasecmp(buffer, "none"))
+ return YCBCR_NONE;
+ if (!strcasecmp(buffer, "tv.601"))
+ return YCBCR_BT601_TV;
+ if (!strcasecmp(buffer, "pc.601"))
+ return YCBCR_BT601_PC;
+ if (!strcasecmp(buffer, "tv.709"))
+ return YCBCR_BT709_TV;
+ if (!strcasecmp(buffer, "pc.709"))
+ return YCBCR_BT709_PC;
+ if (!strcasecmp(buffer, "tv.240m"))
+ return YCBCR_SMPTE240M_TV;
+ if (!strcasecmp(buffer, "pc.240m"))
+ return YCBCR_SMPTE240M_PC;
+ if (!strcasecmp(buffer, "tv.fcc"))
+ return YCBCR_FCC_TV;
+ if (!strcasecmp(buffer, "pc.fcc"))
+ return YCBCR_FCC_PC;
+ return YCBCR_UNKNOWN;
+}
+
void ass_msg(ASS_Library *priv, int lvl, char *fmt, ...)
{
va_list va;
diff --git a/libass/ass_utils.h b/libass/ass_utils.h
index a1abde9..2d0c6f9 100644
--- a/libass/ass_utils.h
+++ b/libass/ass_utils.h
@@ -49,6 +49,7 @@ int mystrtou32(char **p, int base, uint32_t *res);
int mystrtod(char **p, double *res);
int strtocolor(ASS_Library *library, char **q, uint32_t *res, int hex);
char parse_bool(char *str);
+int parse_ycbcr_matrix(char *str);
unsigned ass_utf8_get_char(char **str);
void ass_msg(ASS_Library *priv, int lvl, char *fmt, ...);
int lookup_style(ASS_Track *track, char *name);