diff --git a/aamp/aamp.py b/aamp/aamp.py index a9616f8..29ba86e 100644 --- a/aamp/aamp.py +++ b/aamp/aamp.py @@ -110,7 +110,11 @@ def _parse_param(self, offset: int) -> typing.Tuple[int, typing.Any]: or param_type == ParameterType.Curve2 \ or param_type == ParameterType.Curve3 \ or param_type == ParameterType.Curve4: - raise NotImplementedError('Curve parameters are not supported') + num_curves = self._get_param_data_size(offset) // 0x80 + value = Curve() + for i in range(num_curves): + value.v.extend(get_u32(self._data, data_offset + 0x80*i + 4*x) for x in range(2)) + value.v.extend(get_f32(self._data, data_offset + 0x80*i + 8 + 4*x) for x in range(30)) elif param_type == ParameterType.Quat: # Quat parameters receive additional processing after being loaded: diff --git a/aamp/parameters.py b/aamp/parameters.py index 7c56d9e..3887842 100644 --- a/aamp/parameters.py +++ b/aamp/parameters.py @@ -141,6 +141,11 @@ def __init__(self, a=0.0, b=0.0, c=0.0, d=0.0) -> None: def __repr__(self) -> str: return f'Quat({self.a},{self.b},{self.c},{self.d})' +class Curve: + __slots__ = ['v'] + def __init__(self, v=None) -> None: + self.v = v if v else [] + def value_to_bytes(v: typing.Any) -> typing.Tuple[ParameterType, bytes]: if isinstance(v, bool): return (ParameterType.Bool, u32(v)) @@ -160,6 +165,16 @@ def value_to_bytes(v: typing.Any) -> typing.Tuple[ParameterType, bytes]: return (ParameterType.Color, f32(v.r) + f32(v.g) + f32(v.b) + f32(v.a)) if isinstance(v, Quat): return (ParameterType.Quat, f32(v.a) + f32(v.b) + f32(v.c) + f32(v.d)) + if isinstance(v, Curve): + buf = b'' + for item in v.v: + if isinstance(item, int): + buf += u32(item) + elif isinstance(item, float): + buf += f32(item) + else: + raise ValueError('Invalid item in curve parameter') + return (ParameterType(ParameterType.Curve1 + (len(buf) // 0x80) - 1), buf) if isinstance(v, String32): return (ParameterType.String32, string(v)) if isinstance(v, String64): diff --git a/aamp/yaml_util.py b/aamp/yaml_util.py index 4696d78..dadfb4e 100644 --- a/aamp/yaml_util.py +++ b/aamp/yaml_util.py @@ -138,6 +138,7 @@ def register_representers(dumper) -> None: yaml.add_representer(Vec4, lambda d, data: d.represent_sequence('!vec4', _fields(data), flow_style=True), Dumper=dumper) yaml.add_representer(Color, lambda d, data: d.represent_sequence('!color', _fields(data), flow_style=True), Dumper=dumper) yaml.add_representer(Quat, lambda d, data: d.represent_sequence('!quat', _fields(data), flow_style=True), Dumper=dumper) + yaml.add_representer(Curve, lambda d, data: d.represent_sequence('!curve', data.v, flow_style=True), Dumper=dumper) yaml.add_representer(String32, lambda d, data: d.represent_scalar('!str32', str(data)), Dumper=dumper) yaml.add_representer(String64, lambda d, data: d.represent_scalar('!str64', str(data)), Dumper=dumper) yaml.add_representer(String256, lambda d, data: d.represent_scalar('!str256', str(data)), Dumper=dumper) @@ -152,6 +153,7 @@ def register_constructors(loader) -> None: yaml.add_constructor('!vec4', lambda l, node: Vec4(*l.construct_sequence(node)), Loader=loader) yaml.add_constructor('!color', lambda l, node: Color(*l.construct_sequence(node)), Loader=loader) yaml.add_constructor('!quat', lambda l, node: Quat(*l.construct_sequence(node)), Loader=loader) + yaml.add_constructor('!curve', lambda l, node: Curve(*l.construct_sequence(node)), Loader=loader) yaml.add_constructor('!str32', lambda l, node: String32(l.construct_yaml_str(node)), Loader=loader) yaml.add_constructor('!str64', lambda l, node: String64(l.construct_yaml_str(node)), Loader=loader) yaml.add_constructor('!str256', lambda l, node: String256(l.construct_yaml_str(node)), Loader=loader)