swf: Properly read/write ConvolutionFilters; these contain f32s, not Fixed16s

This commit is contained in:
Moulins 2024-01-23 01:27:22 +01:00 committed by Nathan Adams
parent 659917bff2
commit bd2165bd0f
5 changed files with 27 additions and 32 deletions

View File

@ -8,7 +8,7 @@ use crate::avm1::{Activation, ArrayObject, Error, Object, ScriptObject, TObject,
use crate::context::{GcContext, UpdateContext}; use crate::context::{GcContext, UpdateContext};
use gc_arena::{Collect, GcCell, Mutation}; use gc_arena::{Collect, GcCell, Mutation};
use std::ops::Deref; use std::ops::Deref;
use swf::{Color, ConvolutionFilterFlags, Fixed16}; use swf::{Color, ConvolutionFilterFlags};
#[derive(Clone, Debug, Collect)] #[derive(Clone, Debug, Collect)]
#[collect(require_static)] #[collect(require_static)]
@ -58,14 +58,9 @@ impl From<&ConvolutionFilterData> for swf::ConvolutionFilter {
swf::ConvolutionFilter { swf::ConvolutionFilter {
num_matrix_rows: filter.matrix_y, num_matrix_rows: filter.matrix_y,
num_matrix_cols: filter.matrix_x, num_matrix_cols: filter.matrix_x,
matrix: filter matrix: filter.matrix.clone(),
.matrix divisor: filter.divisor,
.iter() bias: filter.bias,
.copied()
.map(Fixed16::from_f32)
.collect(),
divisor: Fixed16::from_f32(filter.divisor),
bias: Fixed16::from_f32(filter.bias),
default_color: filter.color, default_color: filter.color,
flags, flags,
} }
@ -79,9 +74,9 @@ impl From<swf::ConvolutionFilter> for ConvolutionFilterData {
Self { Self {
matrix_x: filter.num_matrix_cols, matrix_x: filter.num_matrix_cols,
matrix_y: filter.num_matrix_rows, matrix_y: filter.num_matrix_rows,
matrix: filter.matrix.into_iter().map(Fixed16::to_f32).collect(), matrix: filter.matrix,
divisor: filter.divisor.to_f32(), divisor: filter.divisor,
bias: filter.bias.to_f32(), bias: filter.bias,
preserve_alpha, preserve_alpha,
clamp, clamp,
color: filter.default_color, color: filter.default_color,

View File

@ -362,11 +362,11 @@ fn avm2_to_convolution_filter<'gc>(
{ {
if let Some(array) = matrix_object.as_array_storage() { if let Some(array) = matrix_object.as_array_storage() {
for value in array.iter() { for value in array.iter() {
matrix.push(Fixed16::from_f64( matrix.push(
value value
.unwrap_or(Value::Undefined) .unwrap_or(Value::Undefined)
.coerce_to_number(activation)?, .coerce_to_number(activation)? as f32,
)); );
} }
} }
} }
@ -399,11 +399,11 @@ fn avm2_to_convolution_filter<'gc>(
if preserve_alpha { if preserve_alpha {
flags |= ConvolutionFilterFlags::PRESERVE_ALPHA; flags |= ConvolutionFilterFlags::PRESERVE_ALPHA;
} }
matrix.resize((matrix_x * matrix_y) as usize, Fixed16::ZERO); matrix.resize((matrix_x * matrix_y) as usize, 0.0f32);
Ok(Filter::ConvolutionFilter(ConvolutionFilter { Ok(Filter::ConvolutionFilter(ConvolutionFilter {
bias: Fixed16::from_f64(bias), bias: bias as f32,
default_color: Color::from_rgb(color, (alpha * 255.0) as u8), default_color: Color::from_rgb(color, (alpha * 255.0) as u8),
divisor: Fixed16::from_f64(divisor), divisor: divisor as f32,
matrix, matrix,
num_matrix_cols: matrix_x.clamp(0, 255) as u8, num_matrix_cols: matrix_x.clamp(0, 255) as u8,
num_matrix_rows: matrix_y.clamp(0, 255) as u8, num_matrix_rows: matrix_y.clamp(0, 255) as u8,
@ -420,7 +420,7 @@ fn convolution_filter_to_avm2<'gc>(
filter filter
.matrix .matrix
.iter() .iter()
.map(|v| Value::from(v.to_f64())) .map(|v| Value::from(f64::from(*v)))
.collect(), .collect(),
)?; )?;
activation.avm2().classes().convolutionfilter.construct( activation.avm2().classes().convolutionfilter.construct(
@ -429,8 +429,8 @@ fn convolution_filter_to_avm2<'gc>(
filter.num_matrix_cols.into(), filter.num_matrix_cols.into(),
filter.num_matrix_rows.into(), filter.num_matrix_rows.into(),
matrix.into(), matrix.into(),
filter.divisor.to_f64().into(), filter.divisor.into(),
filter.bias.to_f64().into(), filter.bias.into(),
filter.is_preserve_alpha().into(), filter.is_preserve_alpha().into(),
filter.is_clamped().into(), filter.is_clamped().into(),
filter.default_color.to_rgb().into(), filter.default_color.to_rgb().into(),

View File

@ -2155,12 +2155,12 @@ impl<'a> Reader<'a> {
fn read_convolution_filter(&mut self) -> Result<ConvolutionFilter> { fn read_convolution_filter(&mut self) -> Result<ConvolutionFilter> {
let num_matrix_cols = self.read_u8()?; let num_matrix_cols = self.read_u8()?;
let num_matrix_rows = self.read_u8()?; let num_matrix_rows = self.read_u8()?;
let divisor = self.read_fixed16()?; let divisor = self.read_f32()?;
let bias = self.read_fixed16()?; let bias = self.read_f32()?;
let num_entries = num_matrix_cols * num_matrix_rows; let num_entries = num_matrix_cols * num_matrix_rows;
let mut matrix = Vec::with_capacity(num_entries as usize); let mut matrix = Vec::with_capacity(num_entries as usize);
for _ in 0..num_entries { for _ in 0..num_entries {
matrix.push(self.read_fixed16()?); matrix.push(self.read_f32()?);
} }
Ok(ConvolutionFilter { Ok(ConvolutionFilter {
num_matrix_cols, num_matrix_cols,

View File

@ -1,13 +1,13 @@
use crate::{Color, Fixed16}; use crate::Color;
use bitflags::bitflags; use bitflags::bitflags;
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct ConvolutionFilter { pub struct ConvolutionFilter {
pub num_matrix_rows: u8, pub num_matrix_rows: u8,
pub num_matrix_cols: u8, pub num_matrix_cols: u8,
pub matrix: Vec<Fixed16>, pub matrix: Vec<f32>,
pub divisor: Fixed16, pub divisor: f32,
pub bias: Fixed16, pub bias: f32,
pub default_color: Color, pub default_color: Color,
pub flags: ConvolutionFilterFlags, pub flags: ConvolutionFilterFlags,
} }

View File

@ -1849,10 +1849,10 @@ impl<W: Write> Writer<W> {
fn write_convolution_filter(&mut self, filter: &ConvolutionFilter) -> Result<()> { fn write_convolution_filter(&mut self, filter: &ConvolutionFilter) -> Result<()> {
self.write_u8(filter.num_matrix_cols)?; self.write_u8(filter.num_matrix_cols)?;
self.write_u8(filter.num_matrix_rows)?; self.write_u8(filter.num_matrix_rows)?;
self.write_fixed16(filter.divisor)?; self.write_f32(filter.divisor)?;
self.write_fixed16(filter.bias)?; self.write_f32(filter.bias)?;
for val in &filter.matrix { for val in &filter.matrix {
self.write_fixed16(*val)?; self.write_f32(*val)?;
} }
self.write_rgba(&filter.default_color)?; self.write_rgba(&filter.default_color)?;
self.write_u8(filter.flags.bits())?; self.write_u8(filter.flags.bits())?;