///|
/// Integer color-space conversions for export and palette preparation.
pub(all) struct YuvColor {
y : Int
u : Int
v : Int
alpha : Byte
} derive(Eq, Debug)
///|
pub fn YuvColor::luma(self : YuvColor) -> Int {
self.y
}
///|
pub fn YuvColor::chrominance_u(self : YuvColor) -> Int {
self.u
}
///|
pub fn YuvColor::chrominance_v(self : YuvColor) -> Int {
self.v
}
///|
pub fn YuvColor::alpha(self : YuvColor) -> Byte {
self.alpha
}
///|
fn clamp_space_byte(value : Int) -> Byte {
(if value < 0 { 0 } else if value > 255 { 255 } else { value }).to_byte()
}
///|
pub fn Rgba::to_yuv(self : Rgba) -> YuvColor {
let red = self.red().to_int()
let green = self.green().to_int()
let blue = self.blue().to_int()
YuvColor::{
y: (299 * red + 587 * green + 114 * blue) / 1000,
u: (-169 * red - 331 * green + 500 * blue) / 1000,
v: (500 * red - 419 * green - 81 * blue) / 1000,
alpha: self.alpha(),
}
}
///|
pub fn rgba_from_yuv(color : YuvColor) -> Rgba {
let red = color.y + 1402 * color.v / 1000
let green = color.y - 344 * color.u / 1000 - 714 * color.v / 1000
let blue = color.y + 1772 * color.u / 1000
rgba(
clamp_space_byte(red),
clamp_space_byte(green),
clamp_space_byte(blue),
color.alpha,
)
}
///|
/// Convert a canvas through YUV with a configurable chroma subsampling step.
pub fn Canvas::yuv_roundtrip(self : Canvas) -> Canvas {
let result = self.copy()
for i in 0.. Canvas {
let result = self.copy()
for i in 0.. Canvas {
let result = self.copy()
for i in 0.. Canvas {
let result = self.copy()
for i in 0.. Canvas {
let safe = if strength < 0 {
0
} else if strength > 1000 {
1000
} else {
strength
}
let result = self.copy()
for i in 0.. Canvas {
let safe = if bands < 2 { 2 } else if bands > 256 { 256 } else { bands }
let result = self.copy()
for i in 0.. Canvas {
self
.temperature(warmth)
.adjust(
ColorAdjustment::default().contrast(contrast).saturation(contrast / 2),
)
}