summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);