///|
/// Bilateral filter: edge-preserving smoothing. Each output pixel is a
/// normalized weighted average of its neighborhood where the weight is the
/// product of a spatial Gaussian (distance) and a range Gaussian (luma
/// difference) — flat regions are smoothed like a blur, while pixels
/// across a strong edge get near-zero weight and the edge stays sharp.
///|
/// Applies the bilateral filter with the given neighborhood `radius`,
/// spatial sigma (pixels) and range sigma (luma steps, 0..255 scale).
/// `radius <= 0` returns a copy; non-positive sigmas are clamped to a
/// small positive value. Alpha is preserved.
pub fn Image::bilateral(
self : Image,
radius : Int,
sigma_space : Double,
sigma_range : Double,
) -> Image {
if radius <= 0 {
return self.copy()
}
let r = if radius > 16 { 16 } else { radius }
let ss = if sigma_space <= 0.0 { 0.1 } else { sigma_space }
let sr = if sigma_range <= 0.0 { 0.1 } else { sigma_range }
// Precompute the guide luma (integer BT.601 weights, like grayscale).
let n = self.pixel_count()
let luma : Array[Int] = Array::make(n, 0)
for p in 0..