From 98ce792a5b0454462e56e09b3e356afd3722a360 Mon Sep 17 00:00:00 2001 From: Nathan Adams Date: Thu, 20 Jul 2023 13:07:16 +0200 Subject: [PATCH] avm1: Implement BitmapData.applyFilter() --- core/src/avm1/globals/bitmap_data.rs | 69 +++++++++++++++++- .../expected.png | Bin 0 -> 1084 bytes .../output.txt | 0 .../test.fla | Bin 0 -> 5279 bytes .../test.swf | Bin 0 -> 751 bytes .../test.toml | 7 ++ 6 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 tests/tests/swfs/avm1/bitmapdata_applyfilter_colormatrix/expected.png create mode 100644 tests/tests/swfs/avm1/bitmapdata_applyfilter_colormatrix/output.txt create mode 100644 tests/tests/swfs/avm1/bitmapdata_applyfilter_colormatrix/test.fla create mode 100644 tests/tests/swfs/avm1/bitmapdata_applyfilter_colormatrix/test.swf create mode 100644 tests/tests/swfs/avm1/bitmapdata_applyfilter_colormatrix/test.toml diff --git a/core/src/avm1/globals/bitmap_data.rs b/core/src/avm1/globals/bitmap_data.rs index 43e7c8a60..b164509f5 100644 --- a/core/src/avm1/globals/bitmap_data.rs +++ b/core/src/avm1/globals/bitmap_data.rs @@ -2,6 +2,7 @@ use super::matrix::object_to_matrix; use crate::avm1::function::{Executable, FunctionObject}; +use crate::avm1::globals::bitmap_filter; use crate::avm1::globals::color_transform::ColorTransformObject; use crate::avm1::object::NativeObject; use crate::avm1::property_decl::{define_properties_on, Declaration}; @@ -571,10 +572,72 @@ fn draw<'gc>( fn apply_filter<'gc>( activation: &mut Activation<'_, 'gc>, - _this: Object<'gc>, - _args: &[Value<'gc>], + this: Object<'gc>, + args: &[Value<'gc>], ) -> Result, Error<'gc>> { - avm1_stub!(activation, "BitmapData", "applyFilter"); + if let NativeObject::BitmapData(bitmap_data) = this.native() { + if !bitmap_data.disposed() { + let source = args + .get(0) + .unwrap_or(&Value::Undefined) + .coerce_to_object(activation); + let source = if let NativeObject::BitmapData(source_bitmap) = source.native() { + source_bitmap + } else { + tracing::warn!( + "Invalid bitmapdata source for apply_filter: got {:?}", + source + ); + return Ok((-1).into()); + }; + + let source_rect = args + .get(1) + .unwrap_or(&Value::Undefined) + .coerce_to_object(activation); + + let src_min_x = source_rect + .get("x", activation)? + .coerce_to_f64(activation)? as u32; + let src_min_y = source_rect + .get("y", activation)? + .coerce_to_f64(activation)? as u32; + let src_width = source_rect + .get("width", activation)? + .coerce_to_f64(activation)? as u32; + let src_height = source_rect + .get("height", activation)? + .coerce_to_f64(activation)? as u32; + + let dest_point = args + .get(2) + .unwrap_or(&Value::Undefined) + .coerce_to_object(activation); + + let dest_x = dest_point.get("x", activation)?.coerce_to_f64(activation)? as u32; + let dest_y = dest_point.get("y", activation)?.coerce_to_f64(activation)? as u32; + + let filter_object = args + .get(3) + .unwrap_or(&Value::Undefined) + .coerce_to_object(activation); + let filter = bitmap_filter::avm1_to_filter(filter_object, &mut activation.context); + + if let Some(filter) = filter { + operations::apply_filter( + &mut activation.context, + bitmap_data, + source, + (src_min_x, src_min_y), + (src_width, src_height), + (dest_x, dest_y), + filter, + ); + return Ok(0.into()); + } + } + } + Ok((-1).into()) } diff --git a/tests/tests/swfs/avm1/bitmapdata_applyfilter_colormatrix/expected.png b/tests/tests/swfs/avm1/bitmapdata_applyfilter_colormatrix/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..04af8049652959db83aa918dd8fce323819aeb41 GIT binary patch literal 1084 zcmeAS@N?(olHy`uVBq!ia0vp^(?FPm4M^HB7CvHNU}5%jaSW+oeEWcLf{N!P6;Gk= zRWom;0XwS?QBh zJE{J7OzG8n9j)-#uk!t;Lc{+aUtDxG^#8{dAYq$P;n6S|O%RmihI$r$SJqG8*Gatv PmI@4>u6{1-oD!M<+)-Ca literal 0 HcmV?d00001 diff --git a/tests/tests/swfs/avm1/bitmapdata_applyfilter_colormatrix/output.txt b/tests/tests/swfs/avm1/bitmapdata_applyfilter_colormatrix/output.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/tests/swfs/avm1/bitmapdata_applyfilter_colormatrix/test.fla b/tests/tests/swfs/avm1/bitmapdata_applyfilter_colormatrix/test.fla new file mode 100644 index 0000000000000000000000000000000000000000..f07f66dbc18d668a5ecbc05bbd8b0cdb4fc9a722 GIT binary patch literal 5279 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 literal 0 HcmV?d00001 diff --git a/tests/tests/swfs/avm1/bitmapdata_applyfilter_colormatrix/test.swf b/tests/tests/swfs/avm1/bitmapdata_applyfilter_colormatrix/test.swf new file mode 100644 index 0000000000000000000000000000000000000000..672bbe2abee2c434ba5999e2680e4eadfdc02276 GIT binary patch literal 751 zcmV8?XbVYm@#5Gs{?F%g{_#v7c6?a-0q`;f z=Cf@8`11VQDnK=`yGF-sgA#_I;R7En9nCz+nQ1RLEywp+mf(@UF>ltDMdw!P_|`s zY2YGWL%#123q?R_RA7B-eIB962sj{jST&3FfQZ&tIjv5%z=W^@o(SjhJhTiR{o*kc@d7Cts>VxmZhZM3wq)+p(f zW{+ntcb_AE{H?hk*2mhnyu;RTn6| z(vmg3)HD^PQa(_Q%H@5nRod4Y>WsPsF{>2^`{=VZMXLP$%3)zStiKTnl)gFz8`^f=B#4>Gd(=CiZzBtN@EG)O3A5Zqo~b8xHXS zagMD1gaBRQa2zBz1`X=appAGyMy<)49;PmQq{QP8U`s4P&%qF#NaI8hzJ@HUk3ao7 z0{D5kmdb?UK%E3}rb0Hg8>S(fK8fPWX*Jw}?CLrsS9UFayWR;m#B?S-pUQNq;U+8* ziU_-51}5UwcskqJ3BN;jV