diff --git a/crates/trace/src/lib.rs b/crates/trace/src/lib.rs index 00aec1b7..923f9e2a 100644 --- a/crates/trace/src/lib.rs +++ b/crates/trace/src/lib.rs @@ -12,6 +12,9 @@ //! colours: the blends that anti-aliasing and blur leave along edges take none of it, colours that //! noise made of one colour are merged, and a blend pixel goes to one of the two colours it lies //! between (see `quantize`). +//! A continuous-tone image (a photo) is first smoothed within its tones, edges kept (see +//! `smooth`): otherwise its noise decides, pixel by pixel, which of two neighbouring tones a +//! pixel gets, and every such pixel is a speck. //! 2. **Remove noise**: 4-connected same-colour components smaller than `noise` pixels are merged //! into their most common neighbouring colour. //! 3. **Follow boundaries**: for each colour layer, the pixel-crack edges between inside and @@ -41,6 +44,7 @@ mod fit; mod logo; mod mosaic; mod quantize; +mod smooth; mod subpixel; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -457,6 +461,9 @@ pub fn trace_within(img: &Raster, params: &TraceParams, max_anchors: usize) -> R if params.mode == Mode::Logo { return logo::trace_logo(img, params, max_anchors); } + // A photo is traced from a copy with its noise smoothed away (see `smooth`). + let smoothed = (params.mode != Mode::BlackAndWhite && quantize::continuous_tone(img)).then(|| smooth::smoothed(img)); + let img = smoothed.as_ref().unwrap_or(img); let mut q = quantize(img, params); denoise(&mut q.labels, w, h, params.noise as usize); // Pixel count per palette entry. @@ -469,6 +476,19 @@ pub fn trace_within(img: &Raster, params: &TraceParams, max_anchors: usize) -> R // Layers bottom → top: largest area first. let mut order: Vec = (0..q.palette.len()).filter(|&i| counts[i] > 0).collect(); order.sort_by(|a, b| counts[*b].cmp(&counts[*a]).then(a.cmp(b))); + if params.method == Method::Overlapping { + // Stacked layers go by lightness instead, from the largest colour's end of the scale: each + // layer reaches under all those above it, so where two colours meet, every layer between + // them in the stack ends on that same edge and shows through its anti-aliasing. Neighbours + // in a picture are mostly neighbours in tone, and in this order they are neighbours in the + // stack too (by area, an unrelated colour's edge would shine through as a hairline). + let light = |i: usize| q.palette.get(i).map_or(0, |c| u32::from(c[0]) * 299 + u32::from(c[1]) * 587 + u32::from(c[2]) * 114); + let first = order.first().copied(); + order.sort_by(|a, b| light(*a).cmp(&light(*b)).then(a.cmp(b))); + if first.is_some_and(|f| order.iter().position(|&i| i == f).is_some_and(|at| at * 2 >= order.len())) { + order.reverse(); + } + } let mut rank = vec![usize::MAX; q.palette.len()]; for (r, &i) in order.iter().enumerate() { rank[i] = r; @@ -538,6 +558,11 @@ struct Layers<'a> { } impl Layers<'_> { + /// Ignore White: white is no part of any layer (stacked layers reach under the layers above + /// them, and must not reach under white that is left out). + fn ignored(&self, label: u16) -> bool { + self.params.ignore_white && self.q.palette.get(label as usize).is_some_and(|c| is_white(*c)) + } /// How far the edge lies from a crack between two pixels, towards the outside one (−0.5 to 0.5). /// /// Each pixel of the column across the crack is read as a blend of the tones on its two sides @@ -649,7 +674,7 @@ impl Layers<'_> { .map(|(i, &l)| { l != TRANSPARENT && !thin.get(i).copied().unwrap_or(false) - && if overlapping { self.rank.get(l as usize).is_some_and(|&lr| lr >= r) } else { l as usize == ci } + && if overlapping { self.rank.get(l as usize).is_some_and(|&lr| lr >= r) && !self.ignored(l) } else { l as usize == ci } }) .collect(); // Without Fills, areas are outlined with a 1 px stroke. diff --git a/crates/trace/src/quantize.rs b/crates/trace/src/quantize.rs index b3daa4d1..476a212e 100644 --- a/crates/trace/src/quantize.rs +++ b/crates/trace/src/quantize.rs @@ -305,6 +305,35 @@ fn settled(mut q: Quantized, img: &Raster, own: &[bool]) -> Quantized { if changed { compact(q.labels, q.palette) } else { q } } +/// Whether `img` is continuous tone (a photo, a gradient) rather than flat art, however noisy +/// or unevenly lit (a scan): whether eight colours leave much of it unsaid. Flat art is a few +/// colours and what noise and lighting make of them, and eight colours come within a few levels +/// of every pixel; a photo's tones spread all through its range, and eight colours stay far from +/// most of them (more than 6 levels, and more than a tenth of how far a single colour stays). +pub(crate) fn continuous_tone(img: &Raster) -> bool { + let hk = HistKey::new(img); + let mut bins = vec![Bin::default(); 1 << 15]; + for p in img.rgba.as_chunks::<4>().0 { + if p[3] >= 128 { + bins[hk.key(p[0], p[1], p[2])].add(p); + } + } + let used: Vec = bins.iter().enumerate().filter(|(_, b)| b.n > 0).map(|(i, b)| (i, b.mean(), b.n as f64)).collect(); + // The root-mean-square distance (levels) from the pixels to the nearest of `k` colours. + let unsaid = |k: usize| { + let colors = centers(&median_cut(&used, k, 0.0)); + let (mut sum, mut n) = (0.0, 0.0); + for (_, c, weight) in &used { + let d2 = colors.iter().map(|m| (0..3).map(|ch| (m[ch] - c[ch]).powi(2)).sum::()).fold(f64::INFINITY, f64::min); + sum += d2 * weight; + n += weight; + } + if n > 0.0 { (sum / n).sqrt() } else { 0.0 } + }; + let eight = unsaid(8); + eight > 6.0 && eight > 0.1 * unsaid(1) +} + /// Drop unused palette entries and merge duplicates. fn compact(mut labels: Vec, palette: Vec<[u8; 3]>) -> Quantized { let mut used = vec![false; palette.len()]; diff --git a/crates/trace/src/smooth.rs b/crates/trace/src/smooth.rs new file mode 100644 index 00000000..7cd8d185 --- /dev/null +++ b/crates/trace/src/smooth.rs @@ -0,0 +1,97 @@ +//! Edge-preserving smoothing of continuous-tone images before they are quantised. +//! +//! A photo's tones run into each other, and its noise is as large as the step from one palette +//! colour to the next: quantised as it is, noise decides pixel by pixel which of two neighbouring +//! colours a pixel gets, and the trace is tens of thousands of specks. Each pixel is averaged with +//! its neighbours instead, each weighted by how alike it is (a bilateral filter: C. Tomasi and +//! R. Manduchi, "Bilateral Filtering for Gray and Color Images", 1998), so that noise within a tone +//! is averaged away while an edge between two tones stays where and as sharp as it was. Three +//! rounds, each along rows and then along columns, three pixels at a time. + +use crate::{Raster, parallel_map}; + +/// Colours this far apart (levels, all channels together) count half as much as equal ones. +const ALIKE: f64 = 20.0; + +/// One pass along rows (`dx = 1`) or columns (`dx = 0`). +fn pass(src: &[u8], w: usize, h: usize, along_rows: bool) -> Vec { + let rows: Vec = (0..h).collect(); + let px = |x: usize, y: usize| src.get((y * w + x) * 4..(y * w + x) * 4 + 4); + let done = parallel_map(&rows, |&y| { + let mut out = Vec::with_capacity(w * 4); + for x in 0..w { + let Some(p) = px(x, y) else { continue }; + if p[3] < 128 { + out.extend_from_slice(p); + continue; + } + let near = if along_rows { + [(x > 0).then(|| (x - 1, y)), (x + 1 < w).then(|| (x + 1, y))] + } else { + [(y > 0).then(|| (x, y - 1)), (y + 1 < h).then(|| (x, y + 1))] + }; + let (mut sum, mut weight) = ([f64::from(p[0]), f64::from(p[1]), f64::from(p[2])], 1.0); + for q in near.into_iter().flatten().filter_map(|(x, y)| px(x, y)).filter(|q| q[3] >= 128) { + let d2: f64 = (0..3).map(|k| (f64::from(q[k]) - f64::from(p[k])).powi(2)).sum(); + let wt = 1.0 / (1.0 + d2 / (ALIKE * ALIKE)).powi(2); + for k in 0..3 { + sum[k] += wt * f64::from(q[k]); + } + weight += wt; + } + out.extend(sum.map(|v| (v / weight).round() as u8)); + out.push(p[3]); + } + out + }); + done.concat() +} + +/// `img` with the noise within its tones smoothed away and its edges kept. +pub(crate) fn smoothed(img: &Raster) -> Raster { + let (w, h) = (img.width as usize, img.height as usize); + let mut rgba = img.rgba.clone(); + if rgba.len() == w * h * 4 { + for _ in 0..3 { + rgba = pass(&pass(&rgba, w, h, true), w, h, false); + } + } + Raster { width: img.width, height: img.height, rgba } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn noise_goes_and_an_edge_stays() { + // Left half about 60, right half about 160, with noise of ±6 on both. + let img = Raster::from_fn(40, 20, |x, y| { + let mut n = x.wrapping_mul(0x9E37_79B1) ^ y.wrapping_mul(0x85EB_CA77); + n ^= n >> 15; + n = n.wrapping_mul(0x2C1B_3C6D); + let n = ((n >> 12) % 13) as u8; + let v = if x < 20 { 54 + n } else { 154 + n }; + [v, v, v, 255] + }); + let out = smoothed(&img); + let spread = |r: &Raster, x0: u32, x1: u32| { + let v: Vec = (0..20).flat_map(|y| (x0..x1).map(move |x| (x, y))).map(|(x, y)| r.pixel(x, y)[0]).collect(); + v.iter().max().unwrap() - v.iter().min().unwrap() + }; + assert_eq!(spread(&img, 0, 20), 12); + assert!(spread(&out, 0, 20) <= 6 && spread(&out, 20, 40) <= 6, "{} {}", spread(&out, 0, 20), spread(&out, 20, 40)); + // The edge is still one pixel sharp, where it was. + assert!(out.pixel(19, 10)[0] < 70 && out.pixel(20, 10)[0] > 150); + } + + #[test] + fn transparent_pixels_and_odd_sizes_pass_through() { + let img = Raster::from_fn(3, 1, |x, _| [10 * x as u8, 0, 0, if x == 1 { 0 } else { 255 }]); + let out = smoothed(&img); + assert_eq!(out.pixel(1, 0), [10, 0, 0, 0]); + assert_eq!((out.width, out.height, out.rgba.len()), (3, 1, 12)); + let broken = Raster { width: 4, height: 4, rgba: vec![0; 7] }; + assert_eq!(smoothed(&broken).rgba.len(), 7); + } +} diff --git a/crates/trace/src/tests.rs b/crates/trace/src/tests.rs index 81ae9ef6..fd7d2bd1 100644 --- a/crates/trace/src/tests.rs +++ b/crates/trace/src/tests.rs @@ -944,3 +944,45 @@ fn the_bands_of_a_gradient_stay_apart() { }); assert!(quantize(&noisy, &sixteen_colors()).palette.len() >= 12); } + +#[test] +fn a_noisy_gradient_keeps_its_tones_without_specks() { + // Tones 0–255 across with noise larger than High Fidelity Photo's 64 steps are apart. + let img = Raster::from_fn(256, 96, |x, y| { + let c = |k: u32| (f64::from(x) + 5.0 * jitter(x, y, k)).round().clamp(0.0, 255.0) as u8; + [c(0), c(1), c(2), 255] + }); + let params = preset("High Fidelity Photo").unwrap(); + let res = trace(&img, ¶ms); + // Smoothed first, the noise mixes fewer neighbouring tones into one (`quantize` alone works + // on the picture as it is), and leaves no specks. + let unsmoothed = quantize(&img, ¶ms).palette.len(); + assert!(res.palette.len() > unsmoothed && res.palette.len() >= 24, "{} colours, {unsmoothed} unsmoothed", res.palette.len()); + assert!(res.paths.len() <= 2 * res.palette.len(), "{} paths of {} colours", res.paths.len(), res.palette.len()); +} + +#[test] +fn stacked_layers_go_by_lightness_and_leave_ignored_white_alone() { + // Stripes: black, white, mid gray, light gray (the widest). + let img = Raster::from_fn(100, 20, |x, _| { + let v = match x { + 0..20 => 0, + 20..40 => 255, + 40..60 => 120, + _ => 200, + }; + [v, v, v, 255] + }); + let params = TraceParams { mode: Mode::Grayscale, colors: 4, noise: 0, method: Method::Overlapping, ..TraceParams::default() }; + let tones = |res: &TraceResult| res.paths.iter().map(|p| p.color[0]).collect::>(); + // The largest colour is light, so the stack starts at the light end. + // (Each layer reaches under those above it: under the black stripe too, a part of its own.) + assert_eq!(tones(&trace(&img, ¶ms)), [255, 200, 200, 120, 120, 0]); + // Without white, no layer reaches under where it was. + let res = trace(&img, &TraceParams { ignore_white: true, ..params }); + assert_eq!(tones(&res), [200, 200, 120, 120, 0]); + for p in &res.paths { + let b = p.path.bounds().unwrap(); + assert!(b.x1 <= 20.5 || b.x0 >= 39.5, "a {} layer covers the white stripe: {b:?}", p.color[0]); + } +} diff --git a/docs/image-trace-quality.md b/docs/image-trace-quality.md index aef211c3..c4c30fa0 100644 --- a/docs/image-trace-quality.md +++ b/docs/image-trace-quality.md @@ -1,6 +1,6 @@ # Image Trace quality -> **Last reviewed:** 2026-10-13 · **Last updated:** 2026-10-13 · **Change:** minor (the palette: 16 Colors on flat art 70 to 4.2 paths, High Fidelity Photo 3,636 to 639) +> **Last reviewed:** 2026-10-13 · **Last updated:** 2026-10-13 · **Change:** minor (photos: High Fidelity Photo 3,653 paths to 121 with its colour error down from 2.30 to 1.75) What Image Trace (`crates/trace`) makes of images whose right answer is known, measured by a harness and compared with the numbers before each change. Nothing here is a judgement by eye, and nothing is compared @@ -72,17 +72,17 @@ Each preset on the inputs it is meant for, all sizes and variants. | Technical Drawing | polygons, star, letter A, lines | 2.66 | 13.45 | 0.201 | 1.37 | 105.76 | 4.8 | 32 | 2.23 | 100 | 85 | 5.9 | – | – | – | – | 0.1 | 0.0 | | Flat Logo | two touching halves, four-colour badge | 0.43 | 3.53 | 3.106 | 88.50 | 0.78 | 69.9 | 352 | 38.92 | 38 | 80 | 237.0 | 0.0 | 0 | 13.8 | – | 59.1 | 0.2 | -### Now (sub-pixel edges and the palette) +### Now (sub-pixel edges, the palette, photo smoothing) | preset | inputs | ΔE | edge ΔE | off mean | off max | missed max | paths | anchors | × art | lines % | corners % | kinks | odd colours | odd px | gap px | overlap px | specks | outside px | |:--|:--|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:| | Default | circle, ellipses, badge with a hole, letter D, polygons, star, letter A | 2.60 | 10.12 | 0.091 | 1.02 | 2.17 | 1.9 | 18 | 1.81 | 29 | 68 | 0.4 | – | – | 22.2 | 22.4 | 0.0 | 0.0 | -| High Fidelity Photo | gradient, photo-like | 2.37 | 2.59 | – | – | – | 638.7 | 25604 | – | 29 | – | – | – | – | 0.0 | – | 151.5 | 0.5 | -| Low Fidelity Photo | gradient, photo-like | 2.67 | 2.93 | – | – | – | 55.3 | 5019 | – | 36 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | +| High Fidelity Photo | gradient, photo-like | 1.75 | 1.98 | – | – | – | 120.7 | 9818 | – | 43 | – | – | – | – | 0.0 | – | 10.3 | 0.1 | +| Low Fidelity Photo | gradient, photo-like | 2.45 | 2.69 | – | – | – | 37.1 | 2132 | – | 44 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | | 3 Colors | two touching halves | 0.43 | 4.32 | 0.087 | 0.74 | 0.56 | 2.0 | 9 | 1.57 | 39 | 100 | 0.0 | 0.0 | 0 | 48.6 | 29.4 | 0.0 | 0.0 | | 6 Colors | two touching halves, four-colour badge | 0.56 | 5.01 | 0.137 | 1.09 | 1.14 | 4.0 | 50 | 3.15 | 40 | 88 | 3.6 | 0.0 | 0 | 39.0 | 35.7 | 0.0 | 0.0 | | 16 Colors | two touching halves, four-colour badge | 0.55 | 4.89 | 0.133 | 1.09 | 1.15 | 4.2 | 66 | 3.97 | 41 | 88 | 4.4 | 0.0 | 0 | 34.5 | 26.4 | 0.0 | 0.0 | -| Shades of Gray | gradient, photo-like | 9.33 | 9.15 | – | – | – | 72.8 | 2681 | – | 50 | – | – | – | – | 0.0 | – | 1.9 | 0.8 | +| Shades of Gray | gradient, photo-like | 9.26 | 9.06 | – | – | – | 16.5 | 879 | – | 53 | – | – | – | – | 0.0 | – | 0.4 | 0.8 | | Black and White Logo | circle, ellipses, badge with a hole, letter D, polygons, star, letter A | 2.58 | 9.39 | 0.064 | 1.00 | 2.18 | 1.4 | 27 | 2.73 | 40 | 67 | 0.3 | – | – | – | – | 0.0 | 0.0 | | Sketched Art | circle, ellipses, badge with a hole, letter D, lines | 2.71 | 12.11 | 0.195 | 1.00 | 105.54 | 1.8 | 17 | 1.49 | 16 | 86 | 0.0 | – | – | – | – | 0.0 | 0.0 | | Silhouettes | circle, ellipses, badge with a hole, letter D | 2.98 | 19.28 | 0.532 | 2.24 | 2.24 | 1.2 | 14 | 1.65 | 12 | 79 | 0.1 | – | – | – | – | 0.0 | 0.0 | @@ -90,7 +90,7 @@ Each preset on the inputs it is meant for, all sizes and variants. | Technical Drawing | polygons, star, letter A, lines | 2.53 | 9.47 | 0.086 | 0.99 | 105.85 | 4.8 | 57 | 3.73 | 69 | 74 | 0.7 | – | – | – | – | 0.3 | 0.0 | | Flat Logo | two touching halves, four-colour badge | 0.43 | 3.53 | 3.106 | 88.50 | 0.78 | 69.9 | 352 | 38.92 | 38 | 80 | 237.0 | 0.0 | 0 | 13.8 | – | 59.1 | 0.2 | -The sections below are the numbers now (sub-pixel edges and the palette). +The sections below are the numbers now (sub-pixel edges, the palette, photo smoothing). ## 1. Each preset on the inputs it is meant for @@ -99,12 +99,12 @@ All sizes and variants (clean, aliased, blurred, noisy, scanned) of those inputs | preset | inputs | ΔE | edge ΔE | off mean | off max | missed max | paths | anchors | × art | lines % | corners % | kinks | odd colours | odd px | gap px | overlap px | specks | outside px | |:--|:--|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:|--:| | Default | circle, ellipses, badge with a hole, letter D, polygons, star, letter A | 2.60 | 10.12 | 0.091 | 1.02 | 2.17 | 1.9 | 18 | 1.81 | 29 | 68 | 0.4 | – | – | 22.2 | 22.4 | 0.0 | 0.0 | -| High Fidelity Photo | gradient, photo-like | 2.37 | 2.59 | – | – | – | 638.7 | 25604 | – | 29 | – | – | – | – | 0.0 | – | 151.5 | 0.5 | -| Low Fidelity Photo | gradient, photo-like | 2.67 | 2.93 | – | – | – | 55.3 | 5019 | – | 36 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | +| High Fidelity Photo | gradient, photo-like | 1.75 | 1.98 | – | – | – | 120.7 | 9818 | – | 43 | – | – | – | – | 0.0 | – | 10.3 | 0.1 | +| Low Fidelity Photo | gradient, photo-like | 2.45 | 2.69 | – | – | – | 37.1 | 2132 | – | 44 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | | 3 Colors | two touching halves | 0.43 | 4.32 | 0.087 | 0.74 | 0.56 | 2.0 | 9 | 1.57 | 39 | 100 | 0.0 | 0.0 | 0 | 48.6 | 29.4 | 0.0 | 0.0 | | 6 Colors | two touching halves, four-colour badge | 0.56 | 5.01 | 0.137 | 1.09 | 1.14 | 4.0 | 50 | 3.15 | 40 | 88 | 3.6 | 0.0 | 0 | 39.0 | 35.7 | 0.0 | 0.0 | | 16 Colors | two touching halves, four-colour badge | 0.55 | 4.89 | 0.133 | 1.09 | 1.15 | 4.2 | 66 | 3.97 | 41 | 88 | 4.4 | 0.0 | 0 | 34.5 | 26.4 | 0.0 | 0.0 | -| Shades of Gray | gradient, photo-like | 9.33 | 9.15 | – | – | – | 72.8 | 2681 | – | 50 | – | – | – | – | 0.0 | – | 1.9 | 0.8 | +| Shades of Gray | gradient, photo-like | 9.26 | 9.06 | – | – | – | 16.5 | 879 | – | 53 | – | – | – | – | 0.0 | – | 0.4 | 0.8 | | Black and White Logo | circle, ellipses, badge with a hole, letter D, polygons, star, letter A | 2.58 | 9.39 | 0.064 | 1.00 | 2.18 | 1.4 | 27 | 2.73 | 40 | 67 | 0.3 | – | – | – | – | 0.0 | 0.0 | | Sketched Art | circle, ellipses, badge with a hole, letter D, lines | 2.71 | 12.11 | 0.195 | 1.00 | 105.54 | 1.8 | 17 | 1.49 | 16 | 86 | 0.0 | – | – | – | – | 0.0 | 0.0 | | Silhouettes | circle, ellipses, badge with a hole, letter D | 2.98 | 19.28 | 0.532 | 2.24 | 2.24 | 1.2 | 14 | 1.65 | 12 | 79 | 0.1 | – | – | – | – | 0.0 | 0.0 | @@ -123,34 +123,34 @@ All sizes and variants (clean, aliased, blurred, noisy, scanned) of those inputs | Default | gradient, photo | 39.13 | 38.78 | – | – | – | 3.2 | 698 | – | 57 | – | – | – | – | 31.2 | 40.7 | 0.0 | 0.3 | | High Fidelity Photo | curved shapes | 0.04 | 1.74 | 0.026 | 0.16 | 0.16 | 1.2 | 20 | 2.17 | 21 | 100 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | | High Fidelity Photo | polygons | 0.05 | 1.92 | 0.031 | 0.51 | 1.34 | 1.7 | 17 | 1.50 | 87 | 88 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | -| High Fidelity Photo | thin lines | 0.17 | 2.58 | 0.135 | 0.85 | 4.31 | 33.3 | 264 | 13.20 | 46 | – | – | 20.7 | 425 | 0.0 | – | 3.3 | 0.0 | -| High Fidelity Photo | flat colour art | 0.08 | 2.31 | 0.033 | 0.20 | 0.20 | 4.0 | 31 | 2.50 | 38 | 100 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | -| High Fidelity Photo | gradient, photo | 2.46 | 2.67 | – | – | – | 428.3 | 22245 | – | 30 | – | – | – | – | 0.0 | – | 54.5 | 0.3 | +| High Fidelity Photo | thin lines | 0.34 | 6.00 | 0.076 | 0.85 | 4.31 | 40.3 | 333 | 16.67 | 37 | – | – | 27.3 | 4489 | 0.0 | – | 19.0 | 0.0 | +| High Fidelity Photo | flat colour art | 0.14 | 4.17 | 0.028 | 0.20 | 0.20 | 3.5 | 71 | 4.44 | 35 | 100 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | +| High Fidelity Photo | gradient, photo | 1.80 | 2.05 | – | – | – | 134.7 | 11186 | – | 43 | – | – | – | – | 0.0 | – | 7.7 | 0.1 | | Low Fidelity Photo | curved shapes | 0.06 | 2.65 | 0.045 | 0.27 | 0.27 | 1.2 | 14 | 1.53 | 19 | 100 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | | Low Fidelity Photo | polygons | 0.06 | 2.25 | 0.037 | 0.51 | 1.34 | 1.7 | 14 | 1.25 | 86 | 88 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | -| Low Fidelity Photo | thin lines | 0.47 | 4.44 | 0.140 | 0.86 | 45.38 | 5.0 | 37 | 1.85 | 61 | – | – | 1.0 | 265 | 0.0 | – | 0.0 | 0.0 | -| Low Fidelity Photo | flat colour art | 0.09 | 2.61 | 0.048 | 0.27 | 0.27 | 4.0 | 25 | 1.88 | 36 | 100 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | -| Low Fidelity Photo | gradient, photo | 2.77 | 3.04 | – | – | – | 52.7 | 5273 | – | 35 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | +| Low Fidelity Photo | thin lines | 0.51 | 5.73 | 0.081 | 0.86 | 45.38 | 7.0 | 56 | 2.80 | 47 | – | – | 4.0 | 3974 | 0.0 | – | 0.0 | 0.0 | +| Low Fidelity Photo | flat colour art | 0.15 | 4.33 | 0.046 | 0.27 | 0.27 | 3.5 | 55 | 3.38 | 32 | 100 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | +| Low Fidelity Photo | gradient, photo | 2.53 | 2.80 | – | – | – | 42.7 | 2289 | – | 43 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | | 3 Colors | curved shapes | 0.06 | 2.65 | 0.046 | 0.33 | 0.24 | 1.8 | 16 | 1.77 | 16 | 100 | 0.0 | 0.0 | 0 | 18.7 | 15.2 | 0.0 | 0.0 | | 3 Colors | polygons | 0.06 | 2.25 | 0.037 | 0.51 | 1.34 | 2.0 | 15 | 1.35 | 86 | 88 | 0.0 | 0.0 | 0 | 5.1 | 4.7 | 0.0 | 0.0 | | 3 Colors | thin lines | 0.44 | 4.40 | 0.107 | 0.90 | 45.38 | 5.0 | 44 | 2.22 | 49 | – | – | 2.0 | 290 | 23.8 | 27.4 | 0.0 | 0.0 | | 3 Colors | flat colour art | 1.32 | 3.85 | 0.113 | 0.90 | 60.22 | 2.5 | 24 | 1.77 | 46 | 100 | 0.0 | 1.0 | 9919 | 30.3 | 31.0 | 0.0 | 0.0 | -| 3 Colors | gradient, photo | 7.49 | 7.60 | – | – | – | 5.0 | 801 | – | 50 | – | – | – | – | 30.2 | 45.2 | 0.0 | 0.2 | +| 3 Colors | gradient, photo | 7.49 | 7.60 | – | – | – | 5.7 | 532 | – | 48 | – | – | – | – | 25.5 | 26.9 | 0.0 | 0.2 | | 6 Colors | curved shapes | 0.06 | 2.38 | 0.042 | 0.28 | 0.24 | 1.8 | 17 | 1.86 | 17 | 100 | 0.0 | 0.0 | 0 | 17.9 | 14.3 | 0.0 | 0.0 | | 6 Colors | polygons | 0.05 | 2.07 | 0.034 | 0.51 | 1.34 | 2.0 | 16 | 1.42 | 86 | 88 | 0.0 | 0.0 | 0 | 3.9 | 3.9 | 0.0 | 0.0 | | 6 Colors | thin lines | 0.50 | 4.54 | 0.096 | 0.86 | 45.38 | 4.0 | 32 | 1.60 | 53 | – | – | 1.7 | 398 | 18.5 | 22.8 | 0.0 | 0.0 | | 6 Colors | flat colour art | 0.12 | 2.66 | 0.044 | 0.25 | 0.20 | 3.0 | 28 | 2.00 | 43 | 100 | 0.0 | 0.0 | 0 | 21.9 | 21.2 | 0.0 | 0.0 | -| 6 Colors | gradient, photo | 5.03 | 5.30 | – | – | – | 20.7 | 1735 | – | 40 | – | – | – | – | 61.6 | 102.9 | 0.0 | 0.2 | +| 6 Colors | gradient, photo | 5.01 | 5.30 | – | – | – | 13.0 | 833 | – | 36 | – | – | – | – | 42.6 | 37.0 | 0.0 | 0.2 | | 16 Colors | curved shapes | 0.05 | 2.26 | 0.038 | 0.26 | 0.23 | 1.8 | 18 | 1.93 | 17 | 100 | 0.0 | 0.0 | 0 | 14.9 | 12.5 | 0.0 | 0.0 | | 16 Colors | polygons | 0.05 | 2.02 | 0.034 | 0.51 | 1.34 | 2.0 | 16 | 1.44 | 86 | 88 | 0.0 | 0.0 | 0 | 3.3 | 4.2 | 0.0 | 0.0 | | 16 Colors | thin lines | 0.41 | 3.87 | 0.103 | 0.86 | 23.65 | 8.7 | 50 | 2.52 | 51 | – | – | 5.7 | 305 | 18.4 | 25.4 | 0.0 | 0.0 | | 16 Colors | flat colour art | 0.12 | 2.53 | 0.041 | 0.24 | 0.20 | 3.0 | 28 | 2.07 | 44 | 100 | 0.0 | 0.0 | 0 | 19.8 | 19.5 | 0.0 | 0.0 | -| 16 Colors | gradient, photo | 3.12 | 3.44 | – | – | – | 50.7 | 3313 | – | 34 | – | – | – | – | 121.9 | 183.8 | 0.0 | 0.2 | +| 16 Colors | gradient, photo | 3.02 | 3.33 | – | – | – | 47.2 | 2154 | – | 29 | – | – | – | – | 89.7 | 80.2 | 0.2 | 0.2 | | Shades of Gray | curved shapes | 0.06 | 2.72 | 0.046 | 0.48 | 0.65 | 1.2 | 14 | 1.56 | 18 | 92 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | | Shades of Gray | polygons | 0.05 | 1.97 | 0.033 | 0.42 | 1.26 | 1.7 | 14 | 1.21 | 89 | 91 | 0.0 | 0.0 | 0 | 0.0 | – | 0.0 | 0.0 | -| Shades of Gray | thin lines | 0.49 | 4.80 | 0.142 | 0.86 | 45.38 | 9.0 | 54 | 2.70 | 63 | – | – | 6.0 | 472 | 0.0 | – | 0.0 | 0.0 | -| Shades of Gray | flat colour art | 7.34 | 10.80 | 0.384 | 1.40 | 179.38 | 12.5 | 108 | 9.54 | 43 | 50 | 30.0 | 11.2 | 39147 | 0.0 | – | 0.0 | 0.0 | -| Shades of Gray | gradient, photo | 9.73 | 9.61 | – | – | – | 81.8 | 3187 | – | 51 | – | – | – | – | 0.0 | – | 2.2 | 0.8 | +| Shades of Gray | thin lines | 0.56 | 6.69 | 0.078 | 0.86 | 45.38 | 10.3 | 71 | 3.57 | 49 | – | – | 8.0 | 4283 | 0.0 | – | 0.0 | 0.0 | +| Shades of Gray | flat colour art | 7.33 | 11.25 | 0.264 | 1.47 | 179.38 | 4.7 | 214 | 19.86 | 24 | 50 | 0.3 | 3.7 | 173356 | 0.0 | – | 0.0 | 0.0 | +| Shades of Gray | gradient, photo | 9.71 | 9.55 | – | – | – | 18.2 | 955 | – | 53 | – | – | – | – | 0.0 | – | 0.5 | 0.8 | | Black and White Logo | curved shapes | 0.04 | 1.52 | 0.024 | 0.50 | 0.60 | 1.2 | 21 | 2.25 | 21 | 75 | 0.0 | – | – | – | – | 0.0 | 0.0 | | Black and White Logo | polygons | 0.04 | 1.83 | 0.030 | 0.45 | 1.23 | 1.7 | 15 | 1.34 | 89 | 90 | 0.0 | – | – | – | – | 0.0 | 0.0 | | Black and White Logo | thin lines | 0.50 | 4.22 | 0.065 | 0.50 | 77.21 | 10.3 | 66 | 3.30 | 65 | – | – | – | – | – | – | 0.0 | 0.0 | @@ -191,16 +191,16 @@ All sizes and variants (clean, aliased, blurred, noisy, scanned) of those inputs | Default | blurred | 0.82 | 16.65 | 0.078 | 0.86 | 2.17 | 1.9 | 26 | 2.50 | 7 | 19 | 1.6 | – | – | 23.0 | 23.6 | 0.0 | 0.0 | | Default | noisy | 1.74 | 4.55 | 0.052 | 0.57 | 1.23 | 1.9 | 16 | 1.64 | 38 | 67 | 0.0 | – | – | 16.2 | 15.1 | 0.0 | 0.0 | | Default | scanned | 15.06 | 20.24 | 0.134 | 0.87 | 2.17 | 1.9 | 26 | 2.53 | 0 | 25 | 1.0 | – | – | 20.8 | 24.7 | 0.0 | 0.0 | -| High Fidelity Photo | clean | 2.46 | 2.67 | – | – | – | 428.3 | 22245 | – | 30 | – | – | – | – | 0.0 | – | 54.5 | 0.3 | -| High Fidelity Photo | aliased | 2.32 | 2.54 | – | – | – | 239.0 | 15797 | – | 28 | – | – | – | – | 0.0 | – | 25.5 | 0.3 | -| High Fidelity Photo | blurred | 1.84 | 2.29 | – | – | – | 406.0 | 23561 | – | 24 | – | – | – | – | 0.0 | – | 39.0 | 0.1 | -| High Fidelity Photo | noisy | 2.84 | 3.01 | – | – | – | 1455.0 | 39709 | – | 20 | – | – | – | – | 0.0 | – | 479.0 | 0.5 | -| High Fidelity Photo | scanned | 2.19 | 2.29 | – | – | – | 1086.0 | 33427 | – | 38 | – | – | – | – | 0.0 | – | 353.5 | 0.3 | -| Low Fidelity Photo | clean | 2.77 | 3.04 | – | – | – | 52.7 | 5273 | – | 35 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | -| Low Fidelity Photo | aliased | 2.83 | 3.08 | – | – | – | 64.0 | 3798 | – | 36 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | -| Low Fidelity Photo | blurred | 2.47 | 2.92 | – | – | – | 40.5 | 3229 | – | 31 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | -| Low Fidelity Photo | noisy | 2.99 | 3.17 | – | – | – | 72.5 | 6536 | – | 38 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | -| Low Fidelity Photo | scanned | 2.09 | 2.19 | – | – | – | 52.0 | 5754 | – | 41 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | +| High Fidelity Photo | clean | 1.80 | 2.05 | – | – | – | 134.7 | 11186 | – | 43 | – | – | – | – | 0.0 | – | 7.7 | 0.1 | +| High Fidelity Photo | aliased | 1.78 | 2.01 | – | – | – | 73.0 | 7695 | – | 45 | – | – | – | – | 0.0 | – | 5.5 | 0.1 | +| High Fidelity Photo | blurred | 1.59 | 1.95 | – | – | – | 72.0 | 7184 | – | 45 | – | – | – | – | 0.0 | – | 0.5 | 0.1 | +| High Fidelity Photo | noisy | 2.02 | 2.19 | – | – | – | 155.5 | 10562 | – | 38 | – | – | – | – | 0.0 | – | 18.5 | 0.1 | +| High Fidelity Photo | scanned | 1.45 | 1.55 | – | – | – | 140.5 | 9726 | – | 41 | – | – | – | – | 0.0 | – | 24.5 | 0.1 | +| Low Fidelity Photo | clean | 2.53 | 2.80 | – | – | – | 42.7 | 2289 | – | 43 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | +| Low Fidelity Photo | aliased | 2.53 | 2.78 | – | – | – | 36.5 | 1504 | – | 46 | – | – | – | – | 0.0 | – | 0.0 | 0.1 | +| Low Fidelity Photo | blurred | 2.35 | 2.75 | – | – | – | 29.0 | 2004 | – | 45 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | +| Low Fidelity Photo | noisy | 2.70 | 2.85 | – | – | – | 32.0 | 1960 | – | 46 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | +| Low Fidelity Photo | scanned | 1.95 | 2.05 | – | – | – | 34.5 | 2588 | – | 42 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | | 3 Colors | clean | 0.07 | 2.53 | 0.051 | 0.24 | 0.14 | 2.0 | 10 | 1.61 | 39 | 100 | 0.0 | 0.0 | 0 | 40.0 | 25.5 | 0.0 | 0.0 | | 3 Colors | aliased | 0.18 | 9.81 | 0.236 | 0.74 | 0.56 | 2.0 | 7 | 1.17 | 39 | 100 | 0.0 | 0.0 | 0 | 123.2 | 82.4 | 0.0 | 0.0 | | 3 Colors | blurred | 0.33 | 7.80 | 0.088 | 0.21 | 0.16 | 2.0 | 10 | 1.67 | 39 | 100 | 0.0 | 0.0 | 0 | 29.7 | 18.6 | 0.0 | 0.0 | @@ -216,11 +216,11 @@ All sizes and variants (clean, aliased, blurred, noisy, scanned) of those inputs | 16 Colors | blurred | 0.62 | 9.37 | 0.250 | 1.08 | 1.15 | 7.0 | 157 | 8.43 | 44 | 50 | 11.5 | 0.0 | 0 | 27.8 | 38.2 | 0.0 | 0.0 | | 16 Colors | noisy | 0.85 | 2.34 | 0.042 | 0.27 | 0.22 | 3.0 | 32 | 2.27 | 34 | 100 | 0.0 | 0.0 | 0 | 23.4 | 15.6 | 0.0 | 0.0 | | 16 Colors | scanned | 1.74 | 4.56 | 0.243 | 1.09 | 0.96 | 7.5 | 156 | 8.53 | 32 | 62 | 19.0 | 0.0 | 0 | 53.3 | 20.8 | 0.0 | 0.0 | -| Shades of Gray | clean | 9.73 | 9.61 | – | – | – | 81.8 | 3187 | – | 51 | – | – | – | – | 0.0 | – | 2.2 | 0.8 | -| Shades of Gray | aliased | 9.73 | 9.58 | – | – | – | 80.0 | 2429 | – | 54 | – | – | – | – | 0.0 | – | 3.0 | 0.8 | -| Shades of Gray | blurred | 9.69 | 9.39 | – | – | – | 62.0 | 1644 | – | 50 | – | – | – | – | 0.0 | – | 1.0 | 0.7 | -| Shades of Gray | noisy | 9.79 | 9.50 | – | – | – | 72.5 | 2703 | – | 50 | – | – | – | – | 0.0 | – | 2.0 | 0.2 | -| Shades of Gray | scanned | 6.87 | 6.77 | – | – | – | 49.5 | 2430 | – | 44 | – | – | – | – | 0.0 | – | 1.0 | 0.2 | +| Shades of Gray | clean | 9.71 | 9.55 | – | – | – | 18.2 | 955 | – | 53 | – | – | – | – | 0.0 | – | 0.5 | 0.8 | +| Shades of Gray | aliased | 9.70 | 9.52 | – | – | – | 11.0 | 788 | – | 58 | – | – | – | – | 0.0 | – | 0.5 | 0.7 | +| Shades of Gray | blurred | 9.66 | 9.32 | – | – | – | 11.5 | 729 | – | 56 | – | – | – | – | 0.0 | – | 0.5 | 0.7 | +| Shades of Gray | noisy | 9.74 | 9.44 | – | – | – | 19.5 | 823 | – | 47 | – | – | – | – | 0.0 | – | 0.0 | 0.2 | +| Shades of Gray | scanned | 6.58 | 6.46 | – | – | – | 19.0 | 947 | – | 49 | – | – | – | – | 0.0 | – | 0.5 | 0.2 | | Black and White Logo | clean | 0.04 | 1.65 | 0.027 | 0.50 | 1.23 | 1.4 | 18 | 1.86 | 50 | 86 | 0.0 | – | – | – | – | 0.0 | 0.0 | | Black and White Logo | aliased | 0.39 | 20.41 | 0.176 | 1.00 | 1.34 | 1.4 | 24 | 2.47 | 53 | 98 | 0.0 | – | – | – | – | 0.0 | 0.0 | | Black and White Logo | blurred | 0.81 | 16.37 | 0.047 | 0.80 | 2.18 | 1.4 | 39 | 3.78 | 23 | 19 | 1.0 | – | – | – | – | 0.0 | 0.0 | @@ -284,18 +284,18 @@ One trace at a time on this machine (all cores); memory is the peak allocated ab |:--|:--|--:|:--| | Default | photo-like | 1 | 0.05 s, 29 paths, 7947 anchors, 15 MB | | Default | four-colour badge | 1 | 0.03 s, 3 paths, 106 anchors, 15 MB | -| High Fidelity Photo | photo-like | 1 | 0.42 s, 4298 paths, 260070 anchors, 143 MB | -| High Fidelity Photo | four-colour badge | 1 | 0.05 s, 7 paths, 66 anchors, 34 MB | -| Low Fidelity Photo | photo-like | 1 | 0.14 s, 245 paths, 52047 anchors, 118 MB | -| Low Fidelity Photo | four-colour badge | 1 | 0.05 s, 7 paths, 54 anchors, 34 MB | -| 3 Colors | photo-like | 1 | 0.07 s, 11 paths, 7582 anchors, 22 MB | -| 3 Colors | four-colour badge | 1 | 0.04 s, 4 paths, 79 anchors, 21 MB | -| 6 Colors | photo-like | 1 | 0.09 s, 143 paths, 20207 anchors, 38 MB | +| High Fidelity Photo | photo-like | 1 | 0.25 s, 968 paths, 113205 anchors, 238 MB | +| High Fidelity Photo | four-colour badge | 1 | 0.06 s, 6 paths, 192 anchors, 34 MB | +| Low Fidelity Photo | photo-like | 1 | 0.13 s, 129 paths, 22788 anchors, 141 MB | +| Low Fidelity Photo | four-colour badge | 1 | 0.05 s, 6 paths, 144 anchors, 36 MB | +| 3 Colors | photo-like | 1 | 0.07 s, 9 paths, 3391 anchors, 26 MB | +| 3 Colors | four-colour badge | 1 | 0.05 s, 4 paths, 79 anchors, 21 MB | +| 6 Colors | photo-like | 1 | 0.08 s, 78 paths, 9239 anchors, 42 MB | | 6 Colors | four-colour badge | 1 | 0.05 s, 5 paths, 89 anchors, 33 MB | -| 16 Colors | photo-like | 1 | 0.12 s, 403 paths, 39143 anchors, 95 MB | +| 16 Colors | photo-like | 1 | 0.11 s, 178 paths, 21069 anchors, 102 MB | | 16 Colors | four-colour badge | 1 | 0.05 s, 5 paths, 92 anchors, 33 MB | -| Shades of Gray | photo-like | 1 | 0.12 s, 447 paths, 31045 anchors, 53 MB | -| Shades of Gray | four-colour badge | 1 | 0.05 s, 36 paths, 292 anchors, 51 MB | +| Shades of Gray | photo-like | 1 | 0.09 s, 82 paths, 8511 anchors, 65 MB | +| Shades of Gray | four-colour badge | 1 | 0.06 s, 10 paths, 780 anchors, 56 MB | | Black and White Logo | photo-like | 1 | 0.05 s, 71 paths, 9067 anchors, 9 MB | | Black and White Logo | four-colour badge | 1 | 0.02 s, 1 paths, 58 anchors, 8 MB | | Sketched Art | photo-like | 1 | 0.05 s, 5 paths, 3207 anchors, 9 MB | @@ -307,64 +307,65 @@ One trace at a time on this machine (all cores); memory is the peak allocated ab | Technical Drawing | photo-like | 1 | 0.06 s, 221 paths, 10646 anchors, 9 MB | | Technical Drawing | four-colour badge | 1 | 0.02 s, 1 paths, 58 anchors, 8 MB | | Flat Logo | photo-like | 1 | refused after 0.09 s (not flat art), 40 MB | -| Flat Logo | four-colour badge | 1 | 0.65 s, 5 paths, 78 anchors, 146 MB | -| Default | photo-like | 4 | 0.21 s, 48 paths, 20717 anchors, 60 MB | +| Flat Logo | four-colour badge | 1 | 0.64 s, 5 paths, 78 anchors, 146 MB | +| Default | photo-like | 4 | 0.19 s, 48 paths, 20717 anchors, 60 MB | | Default | four-colour badge | 4 | 0.10 s, 3 paths, 148 anchors, 64 MB | -| High Fidelity Photo | photo-like | 4 | 1.75 s, 27583 paths, 1089750 anchors, 784 MB | -| High Fidelity Photo | four-colour badge | 4 | 0.22 s, 7 paths, 93 anchors, 126 MB | -| Low Fidelity Photo | photo-like | 4 | 0.46 s, 764 paths, 138552 anchors, 469 MB | -| Low Fidelity Photo | four-colour badge | 4 | 0.22 s, 7 paths, 74 anchors, 126 MB | -| 3 Colors | photo-like | 4 | 0.27 s, 22 paths, 16576 anchors, 88 MB | -| 3 Colors | four-colour badge | 4 | 0.17 s, 4 paths, 122 anchors, 84 MB | -| 6 Colors | photo-like | 4 | 0.30 s, 358 paths, 54088 anchors, 153 MB | -| 6 Colors | four-colour badge | 4 | 0.18 s, 5 paths, 116 anchors, 128 MB | -| 16 Colors | photo-like | 4 | 0.41 s, 1475 paths, 113487 anchors, 393 MB | -| 16 Colors | four-colour badge | 4 | 0.17 s, 5 paths, 124 anchors, 128 MB | -| Shades of Gray | photo-like | 4 | 0.38 s, 1289 paths, 83191 anchors, 212 MB | -| Shades of Gray | four-colour badge | 4 | 0.25 s, 37 paths, 428 anchors, 197 MB | -| Black and White Logo | photo-like | 4 | 0.22 s, 208 paths, 25916 anchors, 36 MB | -| Black and White Logo | four-colour badge | 4 | 0.09 s, 1 paths, 64 anchors, 36 MB | -| Sketched Art | photo-like | 4 | 0.22 s, 9 paths, 6875 anchors, 36 MB | -| Sketched Art | four-colour badge | 4 | 0.09 s, 2 paths, 279 anchors, 36 MB | +| High Fidelity Photo | photo-like | 4 | 0.88 s, 4475 paths, 344985 anchors, 964 MB | +| High Fidelity Photo | four-colour badge | 4 | 0.22 s, 6 paths, 216 anchors, 152 MB | +| Low Fidelity Photo | photo-like | 4 | 0.38 s, 304 paths, 61608 anchors, 592 MB | +| Low Fidelity Photo | four-colour badge | 4 | 0.23 s, 6 paths, 169 anchors, 152 MB | +| 3 Colors | photo-like | 4 | 0.28 s, 20 paths, 8647 anchors, 104 MB | +| 3 Colors | four-colour badge | 4 | 0.18 s, 4 paths, 122 anchors, 84 MB | +| 6 Colors | photo-like | 4 | 0.27 s, 115 paths, 24075 anchors, 165 MB | +| 6 Colors | four-colour badge | 4 | 0.19 s, 5 paths, 116 anchors, 128 MB | +| 16 Colors | photo-like | 4 | 0.33 s, 353 paths, 54215 anchors, 380 MB | +| 16 Colors | four-colour badge | 4 | 0.18 s, 5 paths, 124 anchors, 128 MB | +| Shades of Gray | photo-like | 4 | 0.29 s, 137 paths, 22704 anchors, 232 MB | +| Shades of Gray | four-colour badge | 4 | 0.27 s, 10 paths, 1234 anchors, 220 MB | +| Black and White Logo | photo-like | 4 | 0.21 s, 208 paths, 25916 anchors, 36 MB | +| Black and White Logo | four-colour badge | 4 | 0.08 s, 1 paths, 64 anchors, 36 MB | +| Sketched Art | photo-like | 4 | 0.21 s, 9 paths, 6875 anchors, 36 MB | +| Sketched Art | four-colour badge | 4 | 0.08 s, 2 paths, 279 anchors, 36 MB | | Silhouettes | photo-like | 4 | 0.18 s, 2 paths, 2133 anchors, 44 MB | -| Silhouettes | four-colour badge | 4 | 0.09 s, 1 paths, 32 anchors, 36 MB | +| Silhouettes | four-colour badge | 4 | 0.10 s, 1 paths, 32 anchors, 36 MB | | Line Art | photo-like | 4 | 0.21 s, 127 paths, 12595 anchors, 36 MB | -| Line Art | four-colour badge | 4 | 0.09 s, 1 paths, 465 anchors, 36 MB | -| Technical Drawing | photo-like | 4 | 0.23 s, 931 paths, 33946 anchors, 36 MB | -| Technical Drawing | four-colour badge | 4 | 0.09 s, 1 paths, 64 anchors, 36 MB | +| Line Art | four-colour badge | 4 | 0.08 s, 1 paths, 465 anchors, 36 MB | +| Technical Drawing | photo-like | 4 | 0.22 s, 931 paths, 33946 anchors, 36 MB | +| Technical Drawing | four-colour badge | 4 | 0.08 s, 1 paths, 64 anchors, 36 MB | | Flat Logo | photo-like | 4 | refused after 0.10 s (not flat art), 40 MB | -| Flat Logo | four-colour badge | 4 | 0.65 s, 5 paths, 69 anchors, 146 MB | -| Default | photo-like | 16 | 1.13 s, 127 paths, 46199 anchors, 256 MB | -| Default | four-colour badge | 16 | 0.51 s, 3 paths, 284 anchors, 240 MB | -| High Fidelity Photo | photo-like | 16 | refused after 5.01 s (over 2,000,000 anchors), 3055 MB | -| High Fidelity Photo | four-colour badge | 16 | 1.00 s, 7 paths, 100 anchors, 504 MB | -| Low Fidelity Photo | photo-like | 16 | 1.60 s, 3759 paths, 363242 anchors, 1757 MB | -| Low Fidelity Photo | four-colour badge | 16 | 1.01 s, 7 paths, 79 anchors, 504 MB | -| 3 Colors | photo-like | 16 | 1.30 s, 118 paths, 41993 anchors, 352 MB | -| 3 Colors | four-colour badge | 16 | 0.77 s, 4 paths, 179 anchors, 336 MB | -| 6 Colors | photo-like | 16 | 1.34 s, 1677 paths, 155283 anchors, 601 MB | -| 6 Colors | four-colour badge | 16 | 0.79 s, 5 paths, 118 anchors, 500 MB | -| 16 Colors | photo-like | 16 | 1.73 s, 8717 paths, 394936 anchors, 1571 MB | -| 16 Colors | four-colour badge | 16 | 0.82 s, 5 paths, 120 anchors, 512 MB | -| Shades of Gray | photo-like | 16 | 1.50 s, 5996 paths, 256732 anchors, 789 MB | -| Shades of Gray | four-colour badge | 16 | 1.26 s, 38 paths, 593 anchors, 692 MB | -| Black and White Logo | photo-like | 16 | 1.16 s, 1128 paths, 77629 anchors, 144 MB | -| Black and White Logo | four-colour badge | 16 | 0.42 s, 1 paths, 103 anchors, 128 MB | -| Sketched Art | photo-like | 16 | 1.13 s, 15 paths, 17817 anchors, 144 MB | -| Sketched Art | four-colour badge | 16 | 0.45 s, 2 paths, 478 anchors, 128 MB | -| Silhouettes | photo-like | 16 | 1.37 s, 3 paths, 4891 anchors, 176 MB | -| Silhouettes | four-colour badge | 16 | 0.54 s, 1 paths, 44 anchors, 144 MB | -| Line Art | photo-like | 16 | 1.22 s, 713 paths, 64481 anchors, 144 MB | +| Flat Logo | four-colour badge | 4 | 0.66 s, 5 paths, 69 anchors, 146 MB | +| Default | photo-like | 16 | 1.08 s, 127 paths, 46199 anchors, 256 MB | +| Default | four-colour badge | 16 | 0.46 s, 3 paths, 284 anchors, 240 MB | +| High Fidelity Photo | photo-like | 16 | 3.48 s, 31131 paths, 1254672 anchors, 3954 MB | +| High Fidelity Photo | four-colour badge | 16 | 1.07 s, 6 paths, 248 anchors, 576 MB | +| Low Fidelity Photo | photo-like | 16 | 1.57 s, 2036 paths, 185091 anchors, 2050 MB | +| Low Fidelity Photo | four-colour badge | 16 | 1.08 s, 6 paths, 188 anchors, 576 MB | +| 3 Colors | photo-like | 16 | 1.27 s, 76 paths, 23365 anchors, 416 MB | +| 3 Colors | four-colour badge | 16 | 0.80 s, 4 paths, 179 anchors, 336 MB | +| 6 Colors | photo-like | 16 | 1.17 s, 470 paths, 63030 anchors, 673 MB | +| 6 Colors | four-colour badge | 16 | 0.84 s, 5 paths, 118 anchors, 512 MB | +| 16 Colors | photo-like | 16 | 1.30 s, 1973 paths, 149717 anchors, 1633 MB | +| 16 Colors | four-colour badge | 16 | 0.84 s, 5 paths, 120 anchors, 504 MB | +| Shades of Gray | photo-like | 16 | 1.32 s, 688 paths, 65052 anchors, 850 MB | +| Shades of Gray | four-colour badge | 16 | 1.28 s, 9 paths, 2296 anchors, 800 MB | +| Black and White Logo | photo-like | 16 | 1.04 s, 1128 paths, 77629 anchors, 144 MB | +| Black and White Logo | four-colour badge | 16 | 0.45 s, 1 paths, 103 anchors, 128 MB | +| Sketched Art | photo-like | 16 | 1.15 s, 15 paths, 17817 anchors, 144 MB | +| Sketched Art | four-colour badge | 16 | 0.48 s, 2 paths, 478 anchors, 128 MB | +| Silhouettes | photo-like | 16 | 1.40 s, 3 paths, 4891 anchors, 176 MB | +| Silhouettes | four-colour badge | 16 | 0.55 s, 1 paths, 44 anchors, 144 MB | +| Line Art | photo-like | 16 | 1.21 s, 713 paths, 64481 anchors, 144 MB | | Line Art | four-colour badge | 16 | 0.45 s, 1 paths, 786 anchors, 128 MB | -| Technical Drawing | photo-like | 16 | 1.37 s, 4578 paths, 114292 anchors, 144 MB | -| Technical Drawing | four-colour badge | 16 | 0.43 s, 1 paths, 103 anchors, 128 MB | +| Technical Drawing | photo-like | 16 | 1.20 s, 4578 paths, 114292 anchors, 144 MB | +| Technical Drawing | four-colour badge | 16 | 0.44 s, 1 paths, 103 anchors, 128 MB | | Flat Logo | photo-like | 16 | refused after 0.11 s (not flat art), 40 MB | -| Flat Logo | four-colour badge | 16 | 0.67 s, 5 paths, 67 anchors, 146 MB | +| Flat Logo | four-colour badge | 16 | 0.66 s, 5 paths, 67 anchors, 146 MB | ## Revision history | date | change | |:--|:--| +| 2026-10-13 | Photos: continuous-tone images are smoothed within their tones before quantising, and stacked layers go by lightness | | 2026-10-13 | The palette: made of the picture's own colours, noise-made colours merged, blend pixels settled, cuts where colours differ most, colours compared in Oklab | | 2026-10-13 | Sub-pixel edges and the outline fitter in Black and White, Grayscale and Color; the harness gains an aliased variant and an "outside px" column, so the baseline was measured again with it (same tracer, main at `baf9693f`) | | 2026-10-12 | The harness and the baseline: every preset measured before any change to the tracer |