| 115 | |
| 116 | #[inline] |
| 117 | pub(crate) fn to_rgb(self, gamma: f64) -> RGBA { |
| 118 | if self.a < MIN_OPAQUE_A { |
| 119 | return RGBA::new(0, 0, 0, 0); |
| 120 | } |
| 121 | |
| 122 | let r = (LIQ_WEIGHT_A / LIQ_WEIGHT_R) * self.r / self.a; |
| 123 | let g = (LIQ_WEIGHT_A / LIQ_WEIGHT_G) * self.g / self.a; |
| 124 | let b = (LIQ_WEIGHT_A / LIQ_WEIGHT_B) * self.b / self.a; |
| 125 | let a = (256. / LIQ_WEIGHT_A) * self.a; |
| 126 | |
| 127 | let gamma = (gamma / INTERNAL_GAMMA) as f32; |
| 128 | debug_assert!(gamma.is_finite()); |
| 129 | |
| 130 | // 256, because numbers are in range 1..255.9999… rounded down |
| 131 | RGBA { |
| 132 | r: (r.powf(gamma) * 256.) as u8, |
| 133 | g: (g.powf(gamma) * 256.) as u8, |
| 134 | b: (b.powf(gamma) * 256.) as u8, |
| 135 | a: a as u8, |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | pub fn from_rgba(gamma_lut: &[f32; 256], px: RGBA) -> Self { |
| 140 | let a = f32::from(px.a) / 255.; |