diff options
-rw-r--r-- | libass/ass.c | 4 | ||||
-rw-r--r-- | libass/ass_types.h | 13 | ||||
-rw-r--r-- | libass/ass_utils.c | 40 | ||||
-rw-r--r-- | libass/ass_utils.h | 1 |
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); |