summaryrefslogtreecommitdiffstats
path: root/libass/ass_parse.c
diff options
context:
space:
mode:
authorOleg Oshmyan <chortos@inbox.lv>2015-05-23 00:06:40 +0300
committerOleg Oshmyan <chortos@inbox.lv>2015-05-25 00:16:55 +0300
commit36db47b89cd5f4edfb2b02780ff2ddd8022190db (patch)
treea7f90c2fe0c4a103de2894b3587d3738d1518003 /libass/ass_parse.c
parent409ce02b6b9f9147af548cdc46695350af97d801 (diff)
downloadlibass-36db47b89cd5f4edfb2b02780ff2ddd8022190db.tar.bz2
libass-36db47b89cd5f4edfb2b02780ff2ddd8022190db.tar.xz
Parse and animate all colors and alpha values like VSFilter
* Allow exactly one of these prefixes in header values: 0x, 0X, &h, &H. Note that "0x0xFFFFFF" is a correct value, as the first 0x is consumed by the parser and the second by the string-to-number conversion following strtol semantics. * Allow arbitrary numbers of leading & and H (and not h) in any order in override tag values. * Reduce header values modulo 2**32 instead of saturating them to LLONG_MIN/MAX. * Saturate override tag values to INT32_MIN/MAX rather than to LLONG_MIN/MAX. * Don't fiddle with bytes in alpha override tag values. (They can be outside of the 0..255 range.) Also change the byte swapping code to be more sensible. Fixes #80. Fixes #145. Fixes #178. Also fixes our behavior in the case described in https://code.google.com/p/xy-vsfilter/issues/detail?id=80.
Diffstat (limited to 'libass/ass_parse.c')
-rw-r--r--libass/ass_parse.c50
1 files changed, 24 insertions, 26 deletions
diff --git a/libass/ass_parse.c b/libass/ass_parse.c
index a639dc5..d9749fd 100644
--- a/libass/ass_parse.c
+++ b/libass/ass_parse.c
@@ -184,11 +184,11 @@ static void change_color(uint32_t *var, uint32_t new, double pwr)
}
// like change_color, but for alpha component only
-inline void change_alpha(uint32_t *var, uint32_t new, double pwr)
+inline void change_alpha(uint32_t *var, int32_t new, double pwr)
{
*var =
(_r(*var) << 24) + (_g(*var) << 16) + (_b(*var) << 8) +
- (uint32_t) (_a(*var) * (1 - pwr) + _a(new) * pwr);
+ (uint8_t) (_a(*var) * (1 - pwr) + new * pwr);
}
/**
@@ -545,23 +545,20 @@ char *parse_tag(ASS_Renderer *render_priv, char *p, char *end, double pwr)
render_priv->state.family = family;
update_font(render_priv);
} else if (tag("alpha")) {
- uint32_t val;
int i;
- int hex = render_priv->track->track_type == TRACK_TYPE_ASS;
if (nargs) {
- val = string2color(render_priv->library, args->start, hex);
- unsigned char a = val >> 24;
+ int32_t a = parse_alpha_tag(args->start);
for (i = 0; i < 4; ++i)
change_alpha(&render_priv->state.c[i], a, pwr);
} else {
change_alpha(&render_priv->state.c[0],
- render_priv->state.style->PrimaryColour, 1);
+ _a(render_priv->state.style->PrimaryColour), 1);
change_alpha(&render_priv->state.c[1],
- render_priv->state.style->SecondaryColour, 1);
+ _a(render_priv->state.style->SecondaryColour), 1);
change_alpha(&render_priv->state.c[2],
- render_priv->state.style->OutlineColour, 1);
+ _a(render_priv->state.style->OutlineColour), 1);
change_alpha(&render_priv->state.c[3],
- render_priv->state.style->BackColour, 1);
+ _a(render_priv->state.style->BackColour), 1);
}
// FIXME: simplify
} else if (tag("an")) {
@@ -715,10 +712,8 @@ char *parse_tag(ASS_Renderer *render_priv, char *p, char *end, double pwr)
render_priv->state.clip_drawing_mode = 0;
}
} else if (tag("c")) {
- uint32_t val;
- int hex = render_priv->track->track_type == TRACK_TYPE_ASS;
if (nargs) {
- val = string2color(render_priv->library, args->start, hex);
+ uint32_t val = parse_color_tag(args->start);
change_color(&render_priv->state.c[0], val, pwr);
} else
change_color(&render_priv->state.c[0],
@@ -728,39 +723,42 @@ char *parse_tag(ASS_Renderer *render_priv, char *p, char *end, double pwr)
char n = *(p - 2);
int cidx = n - '1';
char cmd = *(p - 1);
- uint32_t val;
- int hex = render_priv->track->track_type == TRACK_TYPE_ASS;
+ int32_t alpha;
+ uint32_t color;
assert((n >= '1') && (n <= '4'));
- if (nargs)
- val = string2color(render_priv->library, args->start, hex);
- else {
+ if (nargs) {
+ if (cmd == 'a')
+ alpha = parse_alpha_tag(args->start);
+ else
+ color = parse_color_tag(args->start);
+ } else {
switch (n) {
case '1':
- val = render_priv->state.style->PrimaryColour;
+ color = render_priv->state.style->PrimaryColour;
break;
case '2':
- val = render_priv->state.style->SecondaryColour;
+ color = render_priv->state.style->SecondaryColour;
break;
case '3':
- val = render_priv->state.style->OutlineColour;
+ color = render_priv->state.style->OutlineColour;
break;
case '4':
- val = render_priv->state.style->BackColour;
+ color = render_priv->state.style->BackColour;
break;
default:
- val = 0;
+ color = 0;
break; // impossible due to assert; avoid compilation warning
}
if (cmd == 'a')
- val <<= 24;
+ alpha = _a(color);
pwr = 1;
}
switch (cmd) {
case 'c':
- change_color(render_priv->state.c + cidx, val, pwr);
+ change_color(render_priv->state.c + cidx, color, pwr);
break;
case 'a':
- change_alpha(render_priv->state.c + cidx, val >> 24, pwr);
+ change_alpha(render_priv->state.c + cidx, alpha, pwr);
break;
default:
ass_msg(render_priv->library, MSGL_WARN, "Bad command: %c%c",