swf_parser/complete/
gradient.rs1use crate::streaming::basic_data_types::{parse_s_rgb8, parse_straight_s_rgba8};
2use nom::number::complete::le_u8 as parse_u8;
3use nom::IResult as NomResult;
4use swf_types as swf;
5
6#[allow(unused_variables)]
7pub fn parse_color_stop(input: &[u8], with_alpha: bool) -> NomResult<&[u8], swf::ColorStop> {
8 use nom::combinator::map;
9
10 let (input, ratio) = parse_u8(input)?;
11 let (input, color) = if with_alpha {
12 parse_straight_s_rgba8(input)?
13 } else {
14 map(parse_s_rgb8, |c| swf::StraightSRgba8 {
15 r: c.r,
16 g: c.g,
17 b: c.b,
18 a: 255,
19 })(input)?
20 };
21
22 Ok((input, swf::ColorStop { ratio, color }))
23}
24
25pub fn parse_gradient(input: &[u8], with_alpha: bool) -> NomResult<&[u8], swf::Gradient> {
26 let (input, flags) = parse_u8(input)?;
27 let spread_code = flags >> 6;
28 let color_space_code = (flags & ((1 << 6) - 1)) >> 4;
29 let color_count = flags & ((1 << 4) - 1);
30
31 let spread = match spread_code {
32 0 => swf::GradientSpread::Pad,
33 1 => swf::GradientSpread::Reflect,
34 2 => swf::GradientSpread::Repeat,
35 _ => return Err(nom::Err::Error(nom::error::Error::new(input, nom::error::ErrorKind::Switch))),
36 };
37
38 let color_space = match color_space_code {
39 0 => swf::ColorSpace::SRgb,
40 1 => swf::ColorSpace::LinearRgb,
41 _ => return Err(nom::Err::Error(nom::error::Error::new(input, nom::error::ErrorKind::Switch))),
42 };
43
44 let (input, colors) = nom::multi::count(|i| parse_color_stop(i, with_alpha), color_count as usize)(input)?;
45
46 Ok((
47 input,
48 swf::Gradient {
49 spread,
50 color_space,
51 colors,
52 },
53 ))
54}
55
56#[allow(unused_variables)]
57pub fn parse_morph_color_stop(input: &[u8], with_alpha: bool) -> NomResult<&[u8], swf::MorphColorStop> {
58 let (input, start) = parse_color_stop(input, with_alpha)?;
59 let (input, end) = parse_color_stop(input, with_alpha)?;
60
61 Ok((
62 input,
63 swf::MorphColorStop {
64 ratio: start.ratio,
65 color: start.color,
66 morph_ratio: end.ratio,
67 morph_color: end.color,
68 },
69 ))
70}
71
72#[allow(unused_variables)]
73pub fn parse_morph_gradient(input: &[u8], with_alpha: bool) -> NomResult<&[u8], swf::MorphGradient> {
74 let (input, flags) = parse_u8(input)?;
75 let spread_code = flags >> 6;
76 let color_space_code = (flags & ((1 << 6) - 1)) >> 4;
77 let color_count = flags & ((1 << 4) - 1);
78
79 let spread = match spread_code {
80 0 => swf::GradientSpread::Pad,
81 1 => swf::GradientSpread::Reflect,
82 2 => swf::GradientSpread::Repeat,
83 _ => return Err(nom::Err::Error(nom::error::Error::new(input, nom::error::ErrorKind::Switch))),
84 };
85
86 let color_space = match color_space_code {
87 0 => swf::ColorSpace::SRgb,
88 1 => swf::ColorSpace::LinearRgb,
89 _ => return Err(nom::Err::Error(nom::error::Error::new(input, nom::error::ErrorKind::Switch))),
90 };
91
92 let (input, colors) = nom::multi::count(|i| parse_morph_color_stop(i, with_alpha), color_count as usize)(input)?;
93
94 Ok((
95 input,
96 swf::MorphGradient {
97 spread,
98 color_space,
99 colors,
100 },
101 ))
102}