mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
pixels: Multiply by alpha with less loss of precision (#37503)
Integer color components representation has performance and memory storage benefits but suffers from precision loss after multiple consequence alpha (un)premultiply operations. Rounding any fractional bits (to the nearest integer) during alpha multiplication should reduce the loss of precision. Expensive division will be replaced by multiplication and bits shift. https://research.swtch.com/divmult https://docs.google.com/document/d/1tNrMWShq55rfltcZxAx1N-6f82Dt7MWLDHm-5GQVEnE Other browsers and graphics libraries have the similar approach: - Chromium (Skia): https://github.com/google/skia/blob/main/include/private/base/SkMath.h#L73 - Firefox: https://github.com/mozilla/gecko-dev/blob/master/gfx/2d/Swizzle.cpp#L276 - Servo (Raqote): https://github.com/jrmuizel/sw-composite/blob/master/src/lib.rs#L878 Testing: Improvements in the following WPT test - html/canvas/element/manual/imagebitmap/createImageBitmap-premultiplyAlpha.html Signed-off-by: Andrei Volykhin <andrei.volykhin@gmail.com>
This commit is contained in:
parent
e26532e19b
commit
d8c552f3ab
2 changed files with 5 additions and 10 deletions
|
@ -195,9 +195,13 @@ pub fn rgba8_premultiply_inplace(pixels: &mut [u8]) -> bool {
|
|||
is_opaque
|
||||
}
|
||||
|
||||
/// Returns a*b/255, rounding any fractional bits to nearest integer
|
||||
/// to reduce the loss of precision after multiple consequence alpha
|
||||
/// (un)premultiply operations.
|
||||
#[inline(always)]
|
||||
pub fn multiply_u8_color(a: u8, b: u8) -> u8 {
|
||||
(a as u32 * b as u32 / 255) as u8
|
||||
let c = a as u32 * b as u32 + 128;
|
||||
((c + (c >> 8)) >> 8) as u8
|
||||
}
|
||||
|
||||
pub fn clip(
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
[createImageBitmap-premultiplyAlpha.html]
|
||||
[createImageBitmap: from Canvas2D, unpremultiplied, drawn to canvas]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap: from Canvas2D willReadFrequently:true, unpremultiplied, drawn to canvas]
|
||||
expected: FAIL
|
||||
|
||||
[createImageBitmap: from Canvas2D willReadFrequently:false, unpremultiplied, drawn to canvas]
|
||||
expected: FAIL
|
Loading…
Add table
Add a link
Reference in a new issue