Skip to content

Commit 29a1825

Browse files
committed
Alpha check precision
1 parent 982b074 commit 29a1825

File tree

1 file changed

+28
-7
lines changed

1 file changed

+28
-7
lines changed

src/pal.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,9 @@ impl f_pixel {
116116
return RGBA::new(0, 0, 0, 0);
117117
}
118118

119-
let r = (LIQ_WEIGHT_A / LIQ_WEIGHT_R) * self.r / self.a;
120-
let g = (LIQ_WEIGHT_A / LIQ_WEIGHT_G) * self.g / self.a;
121-
let b = (LIQ_WEIGHT_A / LIQ_WEIGHT_B) * self.b / self.a;
122-
let a = (256. / LIQ_WEIGHT_A) * self.a;
119+
let r = (LIQ_WEIGHT_A as f64 / LIQ_WEIGHT_R as f64) as f32 * self.r / self.a;
120+
let g = (LIQ_WEIGHT_A as f64 / LIQ_WEIGHT_G as f64) as f32 * self.g / self.a;
121+
let b = (LIQ_WEIGHT_A as f64 / LIQ_WEIGHT_B as f64) as f32 * self.b / self.a;
123122

124123
let gamma = (gamma / INTERNAL_GAMMA) as f32;
125124
debug_assert!(gamma.is_finite());
@@ -129,7 +128,7 @@ impl f_pixel {
129128
r: (r.powf(gamma) * 256.) as u8,
130129
g: (g.powf(gamma) * 256.) as u8,
131130
b: (b.powf(gamma) * 256.) as u8,
132-
a: a as u8,
131+
a: (self.a * (256. / LIQ_WEIGHT_A as f64) as f32) as u8,
133132
}
134133
}
135134

@@ -145,12 +144,12 @@ impl f_pixel {
145144

146145
#[inline]
147146
pub(crate) fn is_fully_transparent(self) -> bool {
148-
self.a < 1. / 256. * LIQ_WEIGHT_A
147+
self.a < (1. / 255. * LIQ_WEIGHT_A as f64) as f32
149148
}
150149

151150
#[inline]
152151
pub(crate) fn is_fully_opaque(self) -> bool {
153-
self.a >= 255. / 256. * LIQ_WEIGHT_A
152+
self.a >= (255. / 256. * LIQ_WEIGHT_A as f64) as f32
154153
}
155154
}
156155

@@ -431,6 +430,28 @@ fn diff_test() {
431430
assert!(c.diff(&b) < c.diff(&d));
432431
}
433432

433+
#[test]
434+
fn alpha_test() {
435+
let gamma = gamma_lut(0.45455);
436+
for (start, end) in [
437+
(RGBA::new(0,0,0,0), RGBA::new(0,0,0,2)),
438+
(RGBA::new(0,0,0,253), RGBA::new(0,0,0,255))
439+
] {
440+
let start = f_pixel::from_rgba(&gamma, start).a as f64;
441+
let end = f_pixel::from_rgba(&gamma, end).a as f64;
442+
let range = end - start;
443+
for i in 0..1000 {
444+
let a = (start + ((i as f64) / 1000. * range)) as f32;
445+
for a in [a, a.next_up(), a.next_down(), a+1e-6, a-1e-6] {
446+
let px = f_pixel(ARGBF {a, g: 0., b: 0., r: 0.});
447+
let rgb = px.to_rgb(0.45455);
448+
assert_eq!(rgb.a == 0, px.is_fully_transparent(), "not trns!? {px:?}, {rgb:?} {} {}", a / LIQ_WEIGHT_A, a / LIQ_WEIGHT_A * 255.);
449+
assert_eq!(rgb.a == 255, px.is_fully_opaque(), "not opaque?! {px:?}, {rgb:?} {} {} {}", a / LIQ_WEIGHT_A, a / LIQ_WEIGHT_A * 255., a / LIQ_WEIGHT_A * 256.);
450+
}
451+
}
452+
}
453+
}
454+
434455
#[test]
435456
fn pal_test() {
436457
let mut p = PalF::new();

0 commit comments

Comments
 (0)