From bcade589e706aa4b89bbbefffdb5495ac3523880 Mon Sep 17 00:00:00 2001 From: Andrei Volykhin Date: Mon, 16 Jun 2025 15:09:04 +0300 Subject: [PATCH] imagebitmap: Crop bitmap data with formatting (#37397) Follow the ImageBitmap specification and make cropping of the bitmap data to the source rectangle with formatting: https://html.spec.whatwg.org/multipage/#cropped-to-the-source-rectangle-with-formatting For now the next functionality not implemented: - image orientation support (such as EXIF metadata) - color space conversion (image, blob) The convertion from ResizeQuality to "image" FilterType: - pixelated/low/medium/high -> Nearest/Triangle/CatmullRom/Lanczos3 Other browsers use the following sample filtering: - chromium (skia): Nearest/Linear/Linear/CatmullRom - firefox (skia): Lanczos3 Testing: Improvements in the following WPT tests - html/canvas/element/manual/imagebitmap/* Fixes (partially): #34112 Signed-off-by: Andrei Volykhin --- components/pixels/lib.rs | 102 ++++++++- components/pixels/tests/pixels.rs | 60 ++++++ components/script/dom/globalscope.rs | 90 +++++++- components/script/dom/imagebitmap.rs | 196 +++++++++++++++++- components/shared/snapshot/lib.rs | 4 + .../canvas-createImageBitmap-resize.html.ini | 12 -- .../createImageBitmap-bounds.html.ini | 12 -- .../createImageBitmap-drawImage.html.ini | 51 ----- .../createImageBitmap-flipY.html.ini | 51 ----- .../createImageBitmap-invalid-args.html.ini | 15 -- ...reateImageBitmap-premultiplyAlpha.html.ini | 6 +- .../createImageBitmap-sizeOverflow.html.ini | 6 - 12 files changed, 441 insertions(+), 164 deletions(-) create mode 100644 components/pixels/tests/pixels.rs delete mode 100644 tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-bounds.html.ini delete mode 100644 tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-sizeOverflow.html.ini diff --git a/components/pixels/lib.rs b/components/pixels/lib.rs index 3dda4d28bde..8b002e16190 100644 --- a/components/pixels/lib.rs +++ b/components/pixels/lib.rs @@ -10,13 +10,26 @@ use std::{cmp, fmt, vec}; use euclid::default::{Point2D, Rect, Size2D}; use image::codecs::gif::GifDecoder; -use image::{AnimationDecoder as _, ImageFormat}; +use image::imageops::{self, FilterType}; +use image::{AnimationDecoder as _, ImageBuffer, ImageFormat, Rgba}; use ipc_channel::ipc::IpcSharedMemory; use log::debug; use malloc_size_of_derive::MallocSizeOf; use serde::{Deserialize, Serialize}; use webrender_api::ImageKey; +#[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)] +pub enum FilterQuality { + /// No image interpolation (Nearest-neighbor) + None, + /// Low-quality image interpolation (Bilinear) + Low, + /// Medium-quality image interpolation (CatmullRom, Mitchell) + Medium, + /// High-quality image interpolation (Lanczos) + High, +} + #[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)] pub enum PixelFormat { /// Luminance channel only @@ -31,8 +44,8 @@ pub enum PixelFormat { BGRA8, } -// Computes image byte length, returning None if overflow occurred or the total length exceeds -// the maximum image allocation size. +/// Computes image byte length, returning None if overflow occurred or the total length exceeds +/// the maximum image allocation size. pub fn compute_rgba8_byte_length_if_within_limit(width: usize, height: usize) -> Option { // Maximum allowed image allocation size (2^31-1 ~ 2GB). const MAX_IMAGE_BYTE_LENGTH: usize = 2147483647; @@ -45,6 +58,89 @@ pub fn compute_rgba8_byte_length_if_within_limit(width: usize, height: usize) -> .filter(|v| *v <= MAX_IMAGE_BYTE_LENGTH) } +/// Copies the rectangle of the source image to the destination image. +pub fn copy_rgba8_image( + src_size: Size2D, + src_rect: Rect, + src_pixels: &[u8], + dest_size: Size2D, + dest_rect: Rect, + dest_pixels: &mut [u8], +) { + assert!(!src_rect.is_empty()); + assert!(!dest_rect.is_empty()); + assert!(Rect::from_size(src_size).contains_rect(&src_rect)); + assert!(Rect::from_size(dest_size).contains_rect(&dest_rect)); + assert!(src_rect.size == dest_rect.size); + assert_eq!(src_pixels.len() % 4, 0); + assert_eq!(dest_pixels.len() % 4, 0); + + if src_size == dest_size && src_rect == dest_rect { + dest_pixels.copy_from_slice(src_pixels); + return; + } + + let src_first_column_start = src_rect.origin.x as usize * 4; + let src_row_length = src_size.width as usize * 4; + let src_first_row_start = src_rect.origin.y as usize * src_row_length; + + let dest_first_column_start = dest_rect.origin.x as usize * 4; + let dest_row_length = dest_size.width as usize * 4; + let dest_first_row_start = dest_rect.origin.y as usize * dest_row_length; + + let (chunk_length, chunk_count) = ( + src_rect.size.width as usize * 4, + src_rect.size.height as usize, + ); + + for i in 0..chunk_count { + let src = &src_pixels[src_first_row_start + i * src_row_length..][src_first_column_start..] + [..chunk_length]; + let dest = &mut dest_pixels[dest_first_row_start + i * dest_row_length..] + [dest_first_column_start..][..chunk_length]; + dest.copy_from_slice(src); + } +} + +/// Scales the source image to the required size, performing sampling filter algorithm. +pub fn scale_rgba8_image( + size: Size2D, + pixels: &[u8], + required_size: Size2D, + quality: FilterQuality, +) -> Option> { + let filter = match quality { + FilterQuality::None => FilterType::Nearest, + FilterQuality::Low => FilterType::Triangle, + FilterQuality::Medium => FilterType::CatmullRom, + FilterQuality::High => FilterType::Lanczos3, + }; + + let buffer: ImageBuffer, &[u8]> = + ImageBuffer::from_raw(size.width, size.height, pixels)?; + + let scaled_buffer = + imageops::resize(&buffer, required_size.width, required_size.height, filter); + + Some(scaled_buffer.into_vec()) +} + +/// Flips the source image vertically in place. +pub fn flip_y_rgba8_image_inplace(size: Size2D, pixels: &mut [u8]) { + assert_eq!(pixels.len() % 4, 0); + + let row_length = size.width as usize * 4; + let half_height = (size.height / 2) as usize; + + let (left, right) = pixels.split_at_mut(pixels.len() - row_length * half_height); + + for i in 0..half_height { + let top = &mut left[i * row_length..][..row_length]; + let bottom = &mut right[(half_height - i - 1) * row_length..][..row_length]; + top.swap_with_slice(bottom); + } +} + pub fn rgba8_get_rect(pixels: &[u8], size: Size2D, rect: Rect) -> Cow<[u8]> { assert!(!rect.is_empty()); assert!(Rect::from_size(size).contains_rect(&rect)); diff --git a/components/pixels/tests/pixels.rs b/components/pixels/tests/pixels.rs new file mode 100644 index 00000000000..8a953450030 --- /dev/null +++ b/components/pixels/tests/pixels.rs @@ -0,0 +1,60 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use euclid::default::Size2D; +use pixels::flip_y_rgba8_image_inplace; + +const RED: [u8; 4] = [255, 0, 0, 255]; +const GREEN: [u8; 4] = [0, 255, 0, 255]; +const BLUE: [u8; 4] = [0, 0, 255, 255]; +const YELLOW: [u8; 4] = [255, 255, 0, 255]; + +const COLORS: [[u8; 4]; 4] = [RED, GREEN, BLUE, YELLOW]; + +fn create_rgba8_image(number_of_pixels: usize) -> Vec { + (0..number_of_pixels) + .map(|i| COLORS[i % 4]) + .flatten() + .collect() +} + +#[test] +fn test_flip_y_rgba8_image_inplace() { + // | R G | B Y | -> | B Y | R G | + let mut image2x2 = create_rgba8_image(4); + + flip_y_rgba8_image_inplace(Size2D::new(2, 2), &mut image2x2); + + assert_eq!( + &image2x2[0..4], + &BLUE, + "Expected blue color at [0, 0] (image2x2)" + ); + assert_eq!( + &image2x2[12..16], + &GREEN, + "Expected green color at [1, 1] (image2x2)" + ); + + // | R G B | Y R G | B Y R | -> | B Y R | Y R G | R G B | + let mut image3x3 = create_rgba8_image(9); + + flip_y_rgba8_image_inplace(Size2D::new(3, 3), &mut image3x3); + + assert_eq!( + &image3x3[0..4], + &BLUE, + "Expected blue color at [0, 0] (image3x3)" + ); + assert_eq!( + &image3x3[16..20], + &RED, + "Expected red color at [1, 1] (image3x3)" + ); + assert_eq!( + &image3x3[32..36], + &BLUE, + "Expected blue color at [2, 2] (image3x3)" + ); +} diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 20e482c132f..1fc969f163a 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -2970,8 +2970,8 @@ impl GlobalScope { pub(crate) fn create_image_bitmap( &self, image: ImageBitmapSource, - _sx: i32, - _sy: i32, + sx: i32, + sy: i32, sw: Option, sh: Option, options: &ImageBitmapOptions, @@ -3026,8 +3026,8 @@ impl GlobalScope { return p; }; + // TODO: Support vector HTMLImageElement. let Some(img) = img.as_raster_image() else { - // Vector HTMLImageElement are not yet supported. p.reject_error(Error::InvalidState, can_gc); return p; }; @@ -3051,7 +3051,18 @@ impl GlobalScope { IpcSharedMemory::from_bytes(img.first_frame().bytes), ); - let image_bitmap = ImageBitmap::new(self, snapshot, can_gc); + // Step 6.3. Set imageBitmap's bitmap data to a copy of image's media data, + // cropped to the source rectangle with formatting. + let Some(bitmap_data) = + ImageBitmap::crop_and_transform_bitmap_data(snapshot, sx, sy, sw, sh, options) + else { + p.reject_error(Error::InvalidState, can_gc); + return p; + }; + + let image_bitmap = ImageBitmap::new(self, bitmap_data, can_gc); + // Step 6.4. If image is not origin-clean, then set the origin-clean flag + // of imageBitmap's bitmap to false. image_bitmap.set_origin_clean(image.same_origin(GlobalScope::entry().origin())); p.resolve_native(&image_bitmap, can_gc); @@ -3063,6 +3074,8 @@ impl GlobalScope { return p; } + // Step 6.1. If image's networkState attribute is NETWORK_EMPTY, then return + // a promise rejected with an "InvalidStateError" DOMException. if video.is_network_state_empty() { p.reject_error(Error::InvalidState, can_gc); return p; @@ -3074,7 +3087,20 @@ impl GlobalScope { return p; }; - let image_bitmap = ImageBitmap::new(self, snapshot, can_gc); + // Step 6.2. Set imageBitmap's bitmap data to a copy of the frame at the current + // playback position, at the media resource's natural width and natural height + // (i.e., after any aspect-ratio correction has been applied), + // cropped to the source rectangle with formatting. + let Some(bitmap_data) = + ImageBitmap::crop_and_transform_bitmap_data(snapshot, sx, sy, sw, sh, options) + else { + p.reject_error(Error::InvalidState, can_gc); + return p; + }; + + let image_bitmap = ImageBitmap::new(self, bitmap_data, can_gc); + // Step 6.3. If image is not origin-clean, then set the origin-clean flag + // of imageBitmap's bitmap to false. image_bitmap.set_origin_clean(video.origin_is_clean()); p.resolve_native(&image_bitmap, can_gc); @@ -3092,7 +3118,18 @@ impl GlobalScope { return p; }; - let image_bitmap = ImageBitmap::new(self, snapshot, can_gc); + // Step 6.1. Set imageBitmap's bitmap data to a copy of image's bitmap data, + // cropped to the source rectangle with formatting. + let Some(bitmap_data) = + ImageBitmap::crop_and_transform_bitmap_data(snapshot, sx, sy, sw, sh, options) + else { + p.reject_error(Error::InvalidState, can_gc); + return p; + }; + + let image_bitmap = ImageBitmap::new(self, bitmap_data, can_gc); + // Step 6.2. Set the origin-clean flag of the imageBitmap's bitmap to the same value + // as the origin-clean flag of image's bitmap. image_bitmap.set_origin_clean(canvas.origin_is_clean()); p.resolve_native(&image_bitmap, can_gc); @@ -3110,7 +3147,18 @@ impl GlobalScope { return p; }; - let image_bitmap = ImageBitmap::new(self, snapshot, can_gc); + // Step 6.1. Set imageBitmap's bitmap data to a copy of image's bitmap data, + // cropped to the source rectangle with formatting. + let Some(bitmap_data) = + ImageBitmap::crop_and_transform_bitmap_data(snapshot, sx, sy, sw, sh, options) + else { + p.reject_error(Error::InvalidState, can_gc); + return p; + }; + + let image_bitmap = ImageBitmap::new(self, bitmap_data, can_gc); + // Step 6.2. Set the origin-clean flag of imageBitmap's bitmap to the same value + // as the origin-clean flag of image's bitmap. image_bitmap.set_origin_clean(bitmap.origin_is_clean()); p.resolve_native(&image_bitmap, can_gc); @@ -3128,7 +3176,18 @@ impl GlobalScope { return p; }; - let image_bitmap = ImageBitmap::new(self, snapshot, can_gc); + // Step 6.1. Set imageBitmap's bitmap data to a copy of image's bitmap data, + // cropped to the source rectangle with formatting. + let Some(bitmap_data) = + ImageBitmap::crop_and_transform_bitmap_data(snapshot, sx, sy, sw, sh, options) + else { + p.reject_error(Error::InvalidState, can_gc); + return p; + }; + + let image_bitmap = ImageBitmap::new(self, bitmap_data, can_gc); + // Step 6.2. Set the origin-clean flag of the imageBitmap's bitmap to the same value + // as the origin-clean flag of image's bitmap. image_bitmap.set_origin_clean(canvas.origin_is_clean()); p.resolve_native(&image_bitmap, can_gc); @@ -3138,7 +3197,9 @@ impl GlobalScope { p.reject_error(Error::InvalidState, can_gc); }, ImageBitmapSource::ImageData(ref image_data) => { - // + // Step 6.1. Let buffer be image's data attribute value's [[ViewedArrayBuffer]] internal slot. + // Step 6.2. If IsDetachedBuffer(buffer) is true, then return a promise rejected + // with an "InvalidStateError" DOMException. if image_data.is_detached() { p.reject_error(Error::InvalidState, can_gc); return p; @@ -3155,7 +3216,16 @@ impl GlobalScope { image_data.to_shared_memory(), ); - let image_bitmap = ImageBitmap::new(self, snapshot, can_gc); + // Step 6.3. Set imageBitmap's bitmap data to image's image data, + // cropped to the source rectangle with formatting. + let Some(bitmap_data) = + ImageBitmap::crop_and_transform_bitmap_data(snapshot, sx, sy, sw, sh, options) + else { + p.reject_error(Error::InvalidState, can_gc); + return p; + }; + + let image_bitmap = ImageBitmap::new(self, bitmap_data, can_gc); p.resolve_native(&image_bitmap, can_gc); }, diff --git a/components/script/dom/imagebitmap.rs b/components/script/dom/imagebitmap.rs index 0a43bf4f176..992b07fc501 100644 --- a/components/script/dom/imagebitmap.rs +++ b/components/script/dom/imagebitmap.rs @@ -8,10 +8,13 @@ use std::collections::HashMap; use base::id::{ImageBitmapId, ImageBitmapIndex}; use constellation_traits::SerializableImageBitmap; use dom_struct::dom_struct; +use euclid::default::{Point2D, Rect, Size2D}; use snapshot::Snapshot; use crate::dom::bindings::cell::DomRefCell; -use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::ImageBitmapMethods; +use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::{ + ImageBitmapMethods, ImageBitmapOptions, ImageOrientation, PremultiplyAlpha, ResizeQuality, +}; use crate::dom::bindings::reflector::{Reflector, reflect_dom_object}; use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::serializable::Serializable; @@ -71,6 +74,197 @@ impl ImageBitmap { pub(crate) fn is_detached(&self) -> bool { self.bitmap_data.borrow().is_none() } + + /// + pub(crate) fn crop_and_transform_bitmap_data( + input: Snapshot, + mut sx: i32, + mut sy: i32, + sw: Option, + sh: Option, + options: &ImageBitmapOptions, + ) -> Option { + let input_size = input.size().to_i32(); + + // Step 2. If sx, sy, sw and sh are specified, let sourceRectangle be a rectangle whose corners + // are the four points (sx, sy), (sx+sw, sy), (sx+sw, sy+sh), (sx, sy+sh). Otherwise, + // let sourceRectangle be a rectangle whose corners are the four points (0, 0), (width of input, 0), + // (width of input, height of input), (0, height of input). If either sw or sh are negative, + // then the top-left corner of this rectangle will be to the left or above the (sx, sy) point. + let sw = sw.map_or(input_size.width, |width| { + if width < 0 { + sx = sx.saturating_add(width); + width.saturating_abs() + } else { + width + } + }); + + let sh = sh.map_or(input_size.height, |height| { + if height < 0 { + sy = sy.saturating_add(height); + height.saturating_abs() + } else { + height + } + }); + + let source_rect = Rect::new(Point2D::new(sx, sy), Size2D::new(sw, sh)); + + // Whether the byte length of the source bitmap exceeds the supported range. + // In the case the source is too large, we should fail, and that is not defined. + // + let Some(source_byte_length) = pixels::compute_rgba8_byte_length_if_within_limit( + source_rect.size.width as usize, + source_rect.size.height as usize, + ) else { + log::warn!( + "Failed to allocate bitmap of size {:?}, too large", + source_rect.size + ); + return None; + }; + + // Step 3. Let outputWidth be determined as follows: + // Step 4. Let outputHeight be determined as follows: + let output_size = match (options.resizeWidth, options.resizeHeight) { + (Some(width), Some(height)) => Size2D::new(width, height), + (Some(width), None) => { + let height = + source_rect.size.height as f64 * width as f64 / source_rect.size.width as f64; + Size2D::new(width, height.round() as u32) + }, + (None, Some(height)) => { + let width = + source_rect.size.width as f64 * height as f64 / source_rect.size.height as f64; + Size2D::new(width.round() as u32, height) + }, + (None, None) => source_rect.size.to_u32(), + }; + + // Whether the byte length of the output bitmap exceeds the supported range. + // In the case the output is too large, we should fail, and that is not defined. + // + let Some(output_byte_length) = pixels::compute_rgba8_byte_length_if_within_limit( + output_size.width as usize, + output_size.height as usize, + ) else { + log::warn!( + "Failed to allocate bitmap of size {:?}, too large", + output_size + ); + return None; + }; + + // TODO: Take into account the image orientation (such as EXIF metadata). + + // Step 5. Place input on an infinite transparent black grid plane, positioned so that + // its top left corner is at the origin of the plane, with the x-coordinate increasing to the right, + // and the y-coordinate increasing down, and with each pixel in the input image data occupying a cell + // on the plane's grid. + let input_rect = Rect::new(Point2D::zero(), input_size); + + let input_rect_cropped = source_rect + .intersection(&input_rect) + .unwrap_or(Rect::zero()); + + // Early out for empty tranformations. + if input_rect_cropped.is_empty() { + return Some(Snapshot::cleared(output_size)); + } + + // Step 6. Let output be the rectangle on the plane denoted by sourceRectangle. + let mut source: Snapshot = Snapshot::from_vec( + source_rect.size.cast(), + input.format(), + input.alpha_mode(), + vec![0; source_byte_length], + ); + + let source_rect_cropped = Rect::new( + Point2D::new( + input_rect_cropped.origin.x - source_rect.origin.x, + input_rect_cropped.origin.y - source_rect.origin.y, + ), + input_rect_cropped.size, + ); + + pixels::copy_rgba8_image( + input.size(), + input_rect_cropped.cast(), + input.data(), + source.size(), + source_rect_cropped.cast(), + source.data_mut(), + ); + + // Step 7. Scale output to the size specified by outputWidth and outputHeight. + let mut output = if source.size() != output_size { + let quality = match options.resizeQuality { + ResizeQuality::Pixelated => pixels::FilterQuality::None, + ResizeQuality::Low => pixels::FilterQuality::Low, + ResizeQuality::Medium => pixels::FilterQuality::Medium, + ResizeQuality::High => pixels::FilterQuality::High, + }; + + let Some(output_data) = + pixels::scale_rgba8_image(source.size(), source.data(), output_size, quality) + else { + log::warn!( + "Failed to scale the bitmap of size {:?} to required size {:?}", + source.size(), + output_size + ); + return None; + }; + + debug_assert_eq!(output_data.len(), output_byte_length); + + Snapshot::from_vec( + output_size, + source.format(), + source.alpha_mode(), + output_data, + ) + } else { + source + }; + + // Step 8. If the value of the imageOrientation member of options is "flipY", + // output must be flipped vertically, disregarding any image orientation metadata + // of the source (such as EXIF metadata), if any. + if options.imageOrientation == ImageOrientation::FlipY { + pixels::flip_y_rgba8_image_inplace(output.size(), output.data_mut()); + } + + // TODO: Step 9. If image is an img element or a Blob object, let val be the value + // of the colorSpaceConversion member of options, and then run these substeps: + + // Step 10. Let val be the value of premultiplyAlpha member of options, + // and then run these substeps: + // TODO: Preserve the original input pixel format and perform conversion on demand. + match options.premultiplyAlpha { + PremultiplyAlpha::Default | PremultiplyAlpha::Premultiply => { + output.transform( + snapshot::AlphaMode::Transparent { + premultiplied: true, + }, + snapshot::PixelFormat::BGRA, + ); + }, + PremultiplyAlpha::None => { + output.transform( + snapshot::AlphaMode::Transparent { + premultiplied: false, + }, + snapshot::PixelFormat::BGRA, + ); + }, + } + + // Step 11. Return output. + Some(output) + } } impl Serializable for ImageBitmap { diff --git a/components/shared/snapshot/lib.rs b/components/shared/snapshot/lib.rs index 590de3666ad..017e9626541 100644 --- a/components/shared/snapshot/lib.rs +++ b/components/shared/snapshot/lib.rs @@ -195,6 +195,10 @@ impl Snapshot { &self.data } + pub fn data_mut(&mut self) -> &mut [u8] { + &mut self.data + } + /// Convert inner data of snapshot to target format and alpha mode. /// If data is already in target format and alpha mode no work will be done. pub fn transform(&mut self, target_alpha_mode: AlphaMode, target_format: PixelFormat) { diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-resize.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-resize.html.ini index 24a89725c4e..2fcb0feb18b 100644 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-resize.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-resize.html.ini @@ -1,16 +1,4 @@ [canvas-createImageBitmap-resize.html] - [createImageBitmap from an ImageData with resize option.] - expected: FAIL - - [createImageBitmap from a HTMLImageElement with resize option.] - expected: FAIL - - [createImageBitmap from a HTMLCanvasElement with resize option.] - expected: FAIL - - [createImageBitmap from an ImageBitmap with resize option.] - expected: FAIL - [createImageBitmap from a Blob with resize option.] expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-bounds.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-bounds.html.ini deleted file mode 100644 index a15caa7babe..00000000000 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-bounds.html.ini +++ /dev/null @@ -1,12 +0,0 @@ -[createImageBitmap-bounds.html] - [simple clip inside] - expected: FAIL - - [clip outside negative] - expected: FAIL - - [clip outside positive] - expected: FAIL - - [clip inside using negative width and height] - expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html.ini index 0d976c30e4a..19f76dbdc78 100644 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html.ini @@ -1,40 +1,22 @@ [createImageBitmap-drawImage.html] - [createImageBitmap from an OffscreenCanvas resized, and drawImage on the created ImageBitmap] - expected: FAIL - [createImageBitmap from a vector HTMLImageElement resized, and drawImage on the created ImageBitmap] expected: FAIL - [createImageBitmap from a bitmap HTMLImageElement resized, and drawImage on the created ImageBitmap] - expected: FAIL - [createImageBitmap from an HTMLVideoElement, and drawImage on the created ImageBitmap] expected: FAIL [createImageBitmap from an HTMLVideoElement from a data URL scaled down, and drawImage on the created ImageBitmap] expected: FAIL - [createImageBitmap from an ImageData scaled down, and drawImage on the created ImageBitmap] - expected: FAIL - - [createImageBitmap from an OffscreenCanvas scaled down, and drawImage on the created ImageBitmap] - expected: FAIL - [createImageBitmap from a bitmap SVGImageElement, and drawImage on the created ImageBitmap] expected: FAIL [createImageBitmap from a bitmap SVGImageElement resized, and drawImage on the created ImageBitmap] expected: FAIL - [createImageBitmap from an HTMLCanvasElement scaled down, and drawImage on the created ImageBitmap] - expected: FAIL - [createImageBitmap from a vector SVGImageElement, and drawImage on the created ImageBitmap] expected: FAIL - [createImageBitmap from an ImageData scaled up, and drawImage on the created ImageBitmap] - expected: FAIL - [createImageBitmap from an HTMLVideoElement with negative sw/sh, and drawImage on the created ImageBitmap] expected: FAIL @@ -44,18 +26,12 @@ [createImageBitmap from a vector SVGImageElement resized, and drawImage on the created ImageBitmap] expected: FAIL - [createImageBitmap from a bitmap HTMLImageElement scaled up, and drawImage on the created ImageBitmap] - expected: FAIL - [createImageBitmap from a vector SVGImageElement scaled down, and drawImage on the created ImageBitmap] expected: FAIL [createImageBitmap from a vector SVGImageElement with negative sw/sh, and drawImage on the created ImageBitmap] expected: FAIL - [createImageBitmap from a bitmap HTMLImageElement scaled down, and drawImage on the created ImageBitmap] - expected: FAIL - [createImageBitmap from an HTMLVideoElement scaled down, and drawImage on the created ImageBitmap] expected: FAIL @@ -65,9 +41,6 @@ [createImageBitmap from a Blob scaled down, and drawImage on the created ImageBitmap] expected: FAIL - [createImageBitmap from an ImageData resized, and drawImage on the created ImageBitmap] - expected: FAIL - [createImageBitmap from a vector HTMLImageElement scaled down, and drawImage on the created ImageBitmap] expected: FAIL @@ -86,9 +59,6 @@ [createImageBitmap from an HTMLVideoElement scaled up, and drawImage on the created ImageBitmap] expected: FAIL - [createImageBitmap from an HTMLCanvasElement resized, and drawImage on the created ImageBitmap] - expected: FAIL - [createImageBitmap from a Blob, and drawImage on the created ImageBitmap] expected: FAIL @@ -98,27 +68,12 @@ [createImageBitmap from an HTMLVideoElement from a data URL scaled up, and drawImage on the created ImageBitmap] expected: FAIL - [createImageBitmap from an ImageBitmap scaled down, and drawImage on the created ImageBitmap] - expected: FAIL - [createImageBitmap from a Blob with negative sw/sh, and drawImage on the created ImageBitmap] expected: FAIL [createImageBitmap from a bitmap SVGImageElement with negative sw/sh, and drawImage on the created ImageBitmap] expected: FAIL - [createImageBitmap from an ImageBitmap scaled up, and drawImage on the created ImageBitmap] - expected: FAIL - - [createImageBitmap from an ImageBitmap resized, and drawImage on the created ImageBitmap] - expected: FAIL - - [createImageBitmap from an OffscreenCanvas scaled up, and drawImage on the created ImageBitmap] - expected: FAIL - - [createImageBitmap from an HTMLCanvasElement scaled up, and drawImage on the created ImageBitmap] - expected: FAIL - [createImageBitmap from a Blob resized, and drawImage on the created ImageBitmap] expected: FAIL @@ -133,9 +88,3 @@ [createImageBitmap from a vector HTMLImageElement scaled up, and drawImage on the created ImageBitmap] expected: FAIL - - [createImageBitmap from an ImageData, and drawImage on the created ImageBitmap] - expected: FAIL - - [createImageBitmap from an ImageData with negative sw/sh, and drawImage on the created ImageBitmap] - expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-flipY.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-flipY.html.ini index f911aa69e3d..f0cda13cc8a 100644 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-flipY.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-flipY.html.ini @@ -1,16 +1,7 @@ [createImageBitmap-flipY.html] - [createImageBitmap from a vector SVGImageElement imageOrientation: "none", and drawImage on the created ImageBitmap] - expected: NOTRUN - [createImageBitmap from a vector SVGImageElement imageOrientation: "flipY", and drawImage on the created ImageBitmap] expected: FAIL - [createImageBitmap from an HTMLCanvasElement imageOrientation: "none", and drawImage on the created ImageBitmap] - expected: FAIL - - [createImageBitmap from an ImageData imageOrientation: "none", and drawImage on the created ImageBitmap] - expected: NOTRUN - [createImageBitmap from an HTMLVideoElement from a data URL imageOrientation: "flipY", and drawImage on the created ImageBitmap] expected: FAIL @@ -23,33 +14,9 @@ [createImageBitmap from a Blob imageOrientation: "flipY", and drawImage on the created ImageBitmap] expected: FAIL - [createImageBitmap from an HTMLVideoElement imageOrientation: "none", and drawImage on the created ImageBitmap] - expected: FAIL - - [createImageBitmap from an OffscreenCanvas imageOrientation: "none", and drawImage on the created ImageBitmap] - expected: NOTRUN - - [createImageBitmap from a vector HTMLImageElement imageOrientation: "none", and drawImage on the created ImageBitmap] - expected: FAIL - - [createImageBitmap from a Blob imageOrientation: "none", and drawImage on the created ImageBitmap] - expected: NOTRUN - - [createImageBitmap from an HTMLVideoElement from a data URL imageOrientation: "none", and drawImage on the created ImageBitmap] - expected: FAIL - - [createImageBitmap from an ImageBitmap imageOrientation: "none", and drawImage on the created ImageBitmap] - expected: NOTRUN - - [createImageBitmap from a bitmap HTMLImageElement imageOrientation: "none", and drawImage on the created ImageBitmap] - expected: FAIL - [createImageBitmap from a bitmap SVGImageElement imageOrientation: "flipY", and drawImage on the created ImageBitmap] expected: FAIL - [createImageBitmap from a bitmap SVGImageElement imageOrientation: "none", and drawImage on the created ImageBitmap] - expected: TIMEOUT - [createImageBitmap from an HTMLVideoElement imageOrientation: "from-image", and drawImage on the created ImageBitmap] expected: FAIL @@ -67,21 +34,3 @@ [createImageBitmap from a Blob imageOrientation: "from-image", and drawImage on the created ImageBitmap] expected: FAIL - - [createImageBitmap from an HTMLCanvasElement imageOrientation: "flipY", and drawImage on the created ImageBitmap] - expected: FAIL - - [createImageBitmap from a bitmap HTMLImageElement imageOrientation: "flipY", and drawImage on the created ImageBitmap] - expected: FAIL - - [createImageBitmap from an OffscreenCanvas imageOrientation: "flipY", and drawImage on the created ImageBitmap] - expected: FAIL - - [createImageBitmap from an ImageData imageOrientation: "from-image", and drawImage on the created ImageBitmap] - expected: FAIL - - [createImageBitmap from an ImageData imageOrientation: "flipY", and drawImage on the created ImageBitmap] - expected: FAIL - - [createImageBitmap from an ImageBitmap imageOrientation: "flipY", and drawImage on the created ImageBitmap] - expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-invalid-args.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-invalid-args.html.ini index f38b27144ce..36c560ab952 100644 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-invalid-args.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-invalid-args.html.ini @@ -47,20 +47,5 @@ [createImageBitmap with a vector SVGImageElement source and a value between 0 and 1 in resizeWidth] expected: FAIL - [createImageBitmap with an HTMLCanvasElement source and oversized (unallocatable) crop region] - expected: FAIL - - [createImageBitmap with a bitmap HTMLImageElement source and oversized (unallocatable) crop region] - expected: FAIL - - [createImageBitmap with an OffscreenCanvas source and oversized (unallocatable) crop region] - expected: FAIL - - [createImageBitmap with an ImageData source and oversized (unallocatable) crop region] - expected: FAIL - - [createImageBitmap with an ImageBitmap source and oversized (unallocatable) crop region] - expected: FAIL - [createImageBitmap with a bitmap SVGImageElement source and a value between 0 and 1 in resizeWidth] expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-premultiplyAlpha.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-premultiplyAlpha.html.ini index 541c7567bcb..a6e6c78a2ad 100644 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-premultiplyAlpha.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-premultiplyAlpha.html.ini @@ -1,9 +1,9 @@ [createImageBitmap-premultiplyAlpha.html] - [createImageBitmap: from ImageData, unpremultiplied, drawn to canvas] + [createImageBitmap: from Canvas2D, unpremultiplied, drawn to canvas] expected: FAIL - [createImageBitmap: from ImageData, premultiplied, drawn to canvas] + [createImageBitmap: from Canvas2D willReadFrequently:true, unpremultiplied, drawn to canvas] expected: FAIL - [createImageBitmap: from ImageData, default, drawn to canvas] + [createImageBitmap: from Canvas2D willReadFrequently:false, unpremultiplied, drawn to canvas] expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-sizeOverflow.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-sizeOverflow.html.ini deleted file mode 100644 index f4bc8bb6885..00000000000 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-sizeOverflow.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[createImageBitmap-sizeOverflow.html] - [createImageBitmap throws an InvalidStateError error with big imageBitmap scaled up in big height] - expected: FAIL - - [createImageBitmap throws an InvalidStateError error with big imageBitmap scaled up in big width] - expected: FAIL