Update pixels::unmultiply_inplace to support RB swap and use it in canvas_state (#35313)

* update unmultiply_inplace to handle reversed RGB

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>

* Reuse unmultiply_inplace instead of manual compute; remove unused

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
This commit is contained in:
Euclid Ye 2025-02-06 13:02:49 +08:00 committed by GitHub
parent cb7688314b
commit 0de6d1bc3a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 13 additions and 4116 deletions

View file

@ -2785,7 +2785,7 @@ fn prepare_pixels(
}, },
Some(AlphaTreatment::Unmultiply) => { Some(AlphaTreatment::Unmultiply) => {
assert!(pixel_format.is_some()); assert!(pixel_format.is_some());
unmultiply_inplace(pixels.to_mut()); unmultiply_inplace::<false>(pixels.to_mut());
}, },
None => {}, None => {},
} }

View file

@ -20,7 +20,7 @@ fn bench(c: &mut Criterion) {
c.bench_function("unmultiply_inplace", move |b| { c.bench_function("unmultiply_inplace", move |b| {
b.iter_batched( b.iter_batched(
|| data.clone(), || data.clone(),
|mut data| pixels::unmultiply_inplace(&mut data), |mut data| pixels::unmultiply_inplace::<false>(&mut data),
BatchSize::SmallInput, BatchSize::SmallInput,
) )
}); });

View file

@ -197,7 +197,7 @@ pub fn detect_image_format(buffer: &[u8]) -> Result<ImageFormat, &str> {
} }
} }
pub fn unmultiply_inplace(pixels: &mut [u8]) { pub fn unmultiply_inplace<const SWAP_RB: bool>(pixels: &mut [u8]) {
for rgba in pixels.chunks_mut(4) { for rgba in pixels.chunks_mut(4) {
let a = rgba[3] as u32; let a = rgba[3] as u32;
let mut b = rgba[2] as u32; let mut b = rgba[2] as u32;
@ -209,11 +209,17 @@ pub fn unmultiply_inplace(pixels: &mut [u8]) {
g = g * 255 / a; g = g * 255 / a;
b = b * 255 / a; b = b * 255 / a;
if SWAP_RB {
rgba[2] = r as u8;
rgba[1] = g as u8;
rgba[0] = b as u8;
} else {
rgba[2] = b as u8; rgba[2] = b as u8;
rgba[1] = g as u8; rgba[1] = g as u8;
rgba[0] = r as u8; rgba[0] = r as u8;
} }
} }
}
} }
fn is_gif(buffer: &[u8]) -> bool { fn is_gif(buffer: &[u8]) -> bool {

View file

@ -58,7 +58,6 @@ use crate::dom::offscreencanvas::{OffscreenCanvas, OffscreenCanvasContext};
use crate::dom::paintworkletglobalscope::PaintWorkletGlobalScope; use crate::dom::paintworkletglobalscope::PaintWorkletGlobalScope;
use crate::dom::textmetrics::TextMetrics; use crate::dom::textmetrics::TextMetrics;
use crate::script_runtime::CanGc; use crate::script_runtime::CanGc;
use crate::unpremultiplytable::UNPREMULTIPLY_TABLE;
#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)] #[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
#[derive(Clone, JSTraceable, MallocSizeOf)] #[derive(Clone, JSTraceable, MallocSizeOf)]
@ -320,12 +319,7 @@ impl CanvasState {
self.send_canvas_2d_msg(Canvas2dMsg::GetImageData(rect, canvas_size, sender)); self.send_canvas_2d_msg(Canvas2dMsg::GetImageData(rect, canvas_size, sender));
let mut pixels = receiver.recv().unwrap().to_vec(); let mut pixels = receiver.recv().unwrap().to_vec();
for chunk in pixels.chunks_mut(4) { pixels::unmultiply_inplace::<true>(&mut pixels);
let b = chunk[0];
chunk[0] = UNPREMULTIPLY_TABLE[256 * (chunk[3] as usize) + chunk[2] as usize];
chunk[1] = UNPREMULTIPLY_TABLE[256 * (chunk[3] as usize) + chunk[1] as usize];
chunk[2] = UNPREMULTIPLY_TABLE[256 * (chunk[3] as usize) + b as usize];
}
pixels pixels
} }

View file

@ -67,7 +67,6 @@ pub mod test;
#[allow(dead_code)] #[allow(dead_code)]
pub mod textinput; pub mod textinput;
mod timers; mod timers;
mod unpremultiplytable;
mod webdriver_handlers; mod webdriver_handlers;
mod window_named_properties; mod window_named_properties;

File diff suppressed because it is too large Load diff