summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorache <ache@ache.one>2025-05-25 22:46:50 +0200
committerache <ache@ache.one>2025-05-25 22:46:50 +0200
commit911257f56309db9bf795adadb3d3e68da9e415e0 (patch)
tree8537fcb323add1e463056c42ef25b4b119fd303d
parentImplement scolorq dithering (diff)
Fix images dimensions
-rw-r--r--src/lib.rs401
-rw-r--r--src/main.rs23
2 files changed, 50 insertions, 374 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 133432f..b6bd3d1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1144,7 +1144,7 @@ fn add_row_multiple(
// TODO: Improve maybe
fn invert_matrix(matrix: &mut Vec<Vec<f64>>) -> Vec<Vec<f64>> {
let (width, height) = (matrix[0].len(), matrix.len());
- let mut result = vec![vec![0.; width]; height];
+ let mut result = vec![vec![0.; height]; width];
// Set result to identity matrix
for i in 0..height {
@@ -1278,42 +1278,18 @@ pub fn compute_a_image(
for i in 0..3 {
a[i_x as usize][i_y as usize][i] += b_value_pixel[i] * image_pixel[i];
}
-
- /*
- if i_x == test_x && i_y == test_y {
- println!("🦊: j_x, j_y; {} {}", j_x, j_y);
- println!(
- "🦊: b_value:{:?}, image_pixel:{:?}\na_value:{:?}, dprod:[{}, {}, {}]",
- b_value_pixel,
- image_pixel,
- a[i_x as usize][i_y as usize],
- b_value_pixel[0] * image_pixel[0],
- b_value_pixel[1] * image_pixel[1],
- b_value_pixel[2] * image_pixel[2],
- );
- }
- */
}
}
for i in 0..3 {
a[i_x as usize][i_y as usize][i] *= -2.0;
}
-
- /*
- if i_x == test_x && i_y == test_y {
- println!(
- "a[{}][{}] = {:?}\n",
- test_x, test_y, a[i_x as usize][i_y as usize]
- );
- }
- */
}
}
}
-// NOTE: Done and tested
pub fn compute_b_array(filter_weights: &Vec<Vec<[f64; 3]>>, b: &mut Vec<Vec<[f64; 3]>>) {
+ // NOTE: Done and tested
// NOTE: Original comment
// Assume that the pixel i is always located at the center of b,
// and vary pixel j's location through each location in b.
@@ -1346,60 +1322,8 @@ pub fn compute_b_array(filter_weights: &Vec<Vec<[f64; 3]>>, b: &mut Vec<Vec<[f64
}
}
-pub fn compute_a_array(
- image: &Vec<Vec<[f64; 3]>>,
- a: &mut Vec<Vec<[f64; 3]>>,
- b: &Vec<Vec<[f64; 3]>>,
-) {
- // NOTE: Check compute_a_image
- panic!("Do not use");
- let radius_width = (b.len() as i32 - 1) / 2;
- let radius_height = (b[0].len() as i32 - 1) / 2;
-
- for i_y in 0..(a.len() as i32) {
- for i_x in 0..(a[0].len() as i32) {
- for mut j_y in (i_y - radius_height)..(i_y + radius_height) {
- if j_y < 0 {
- j_y = 0; // NOTE: Maybe continue instead
- }
- if j_y >= a[0].len() as i32 {
- break; // NOTE: BREAK ?!?! Ok maybe legit
- }
- for mut j_x in (i_x - radius_width)..(i_x + radius_width) {
- if j_x < 0 {
- j_x = 0; // NOTE: Maybe continue instead
- }
- if j_x >= a.len() as i32 {
- break; // NOTE: BREAK ?!?! Ok maybe legit
- }
- let tmp_ret = b_value(b, i_x, i_y, j_x, j_y);
- let image_pixel = image[j_x as usize][j_y as usize];
-
- if i_x == 10 && i_y == 10 {
- /*
- println!(
- "🐸 DEBUG: b_value:{:?}, image_pixel:{:?}",
- tmp_ret, image_pixel
- );
- */
- }
-
- // directe direct_product
- for i in 0..3 {
- a[i_x as usize][i_y as usize][i] += tmp_ret[i] * image_pixel[i];
- }
- }
- }
- for i in 0..3 {
- a[i_x as usize][i_y as usize][i] *= -2.0;
- }
- }
- }
-}
-
pub fn sum_coarsen(fine: &Vec<Vec<[f64; 3]>>, coarse: &mut Vec<Vec<[f64; 3]>>) {
- // NOTE: Done
- // TODO: To test
+ // NOTE: Done and tested!
for y in 0..coarse[0].len() {
for x in 0..coarse.len() {
@@ -1425,6 +1349,7 @@ pub fn sum_coarsen(fine: &Vec<Vec<[f64; 3]>>, coarse: &mut Vec<Vec<[f64; 3]>>) {
}
for i in 0..3 {
+ // NOTE: Comment is from the original source code
coarse[x][y][i] += /*(1/divisor)**/val[i];
}
}
@@ -1497,11 +1422,8 @@ pub fn compute_initial_j_palette_sum(
coarse_variables: &Vec<Vec<Vec<f64>>>,
palette: &Vec<(f64, f64, f64)>,
) {
- // NOTE: Done
- // TEST: Work on the first try. Must check coarse_variables.
- //
- println!("🀞🀞🀞🀞🀞🀞🀞🀞🀞🀞🀞🀞🀞compute_initial_j_palette_sum !!!!!!!");
- let mut sum_init_j: f64 = 0.;
+ // NOTE: Done and tested !
+
for j_y in 0..coarse_variables[0].len() {
for j_x in 0..coarse_variables.len() {
let mut palette_sum = [0.; 3];
@@ -1511,13 +1433,8 @@ pub fn compute_initial_j_palette_sum(
palette_sum[2] += coarse_variables[j_x][j_y][alpha] * palette[alpha].2;
}
j_palette_sum[j_x][j_y] = palette_sum;
- sum_init_j += palette_sum[0];
- sum_init_j += palette_sum[1];
- sum_init_j += palette_sum[2];
}
}
-
- // println!("@@@@@@@@@@@@@@@@@@@ Sum initial J: {:.6}", sum_init_j);
}
pub fn extract_vector_layer_2d(s: &Vec<Vec<[f64; 3]>>, k: usize) -> Vec<Vec<f64>> {
@@ -1545,16 +1462,8 @@ pub fn refine_palette(
a: &Vec<Vec<[f64; 3]>>,
palette: &mut Vec<(f64, f64, f64)>,
) {
- // TODO: done
- // To test
- // BUG: To test
- // Must have an error
- // The error seems to be from coarse variable
-
- println!("##################### Refine palette");
- print_palette(palette);
+ // NOTE: Done and tested ! ;)
- let mut sum_coarse_variables = 0.;
// Ici, vΓ©rifier les valeurs de coarse_variables
let mut r = vec![[0.; 3]; palette.len()];
for v in 0..palette.len() {
@@ -1563,29 +1472,10 @@ pub fn refine_palette(
for i in 0..3 {
r[v][i] += coarse_variables[i_x][i_y][v] * a[i_x][i_y][i];
}
- sum_coarse_variables += coarse_variables[i_x][i_y][v];
}
}
}
- /*
- for v in 0..palette.len() {
- println!("v: {}", v);
- for i_y in 0..5 {
- for i_x in 0..5 {
- print!("[{:.5}]", coarse_variables[i_x][i_y][v])
- }
- println!()
- }
- println!()
- }
- */
-
- println!(
- "Coarse variables: {:?} ({:.5})",
- sum_coarse_variables, coarse_variables[1][1][1]
- );
-
let mut palette_tmp = vec![[0.; 3]; palette.len()];
for v in 0..palette.len() {
palette_tmp[v][0] = palette[v].0;
@@ -1594,7 +1484,6 @@ pub fn refine_palette(
}
for k in 0..3 {
- // NOTE: VΓ©rifier ces deux fonctions
let mut s_k = extract_vector_layer_2d(s, k);
let r_k = extract_vector_layer_1d(&r, k);
@@ -1627,9 +1516,6 @@ pub fn refine_palette(
palette[v].1 = palette_tmp[v][1];
palette[v].2 = palette_tmp[v][2];
}
-
- print_palette(palette);
- println!("##################### End refine palette");
}
pub fn random_permutation_1d(count: usize, queue: &mut VecDeque<i32>, rng: &mut u32) {
@@ -1668,6 +1554,7 @@ pub fn best_match_color(
i_y: usize,
palette: &Vec<(f64, f64, f64)>,
) -> usize {
+ // NOTE: Done and tested !
let mut max_v = 0;
let mut max_weight = coarse_variables[i_x][i_y][0];
for v in 1..palette.len() {
@@ -1690,9 +1577,7 @@ pub fn update_s(
alpha: i32,
delta: f64,
) {
- // TEST: Done
- // WARN: Must be tested
- // BUG: It doesn't work as expected, there is a bug.
+ // TEST: Done and tested ! ;)
let palette_size = s.len() as usize;
let coarse_width = coarse_variables.len();
let coarse_height = coarse_variables[0].len();
@@ -1737,23 +1622,6 @@ pub fn update_s(
s[alpha as usize][alpha as usize][0] += delta * zero_b[0];
s[alpha as usize][alpha as usize][1] += delta * zero_b[1];
s[alpha as usize][alpha as usize][2] += delta * zero_b[2];
-
- let mut _sum_update_s: f64 = 0.;
- for i in 0..palette_size {
- for j in 0..palette_size {
- for v in 0..3 {
- _sum_update_s += s[i][j][v];
- }
- }
- }
- if alpha == 1 {
- // println!("####################### sum_update_s: {}", _sum_update_s);
- }
-
- // BUG: Should print something. It doesn't
- // if (_sum_update_s - 2531554.643253).abs() < 0.0001 {
- // println!("####################### sum_update_s: {}", _sum_update_s);
- // }
}
pub fn norm_squared(v: &Vec<f64>) -> f64 {
@@ -1766,29 +1634,6 @@ pub fn norm_squared(v: &Vec<f64>) -> f64 {
}
pub fn zoom_double(small: &Vec<Vec<Vec<f64>>>, big: &mut Vec<Vec<Vec<f64>>>) {
- println!(
- "====== Zooming from {}x{} to {}x{}",
- small.len(),
- small[0].len(),
- big.len(),
- big[0].len()
- );
- let mut sum_small = 0.;
- let mut sum_big = 0.;
-
- for y in 0..small.len() {
- for x in 0..small[0].len() {
- sum_small += small[y][x][0];
- }
- }
- for y in 0..big.len() {
- for x in 0..big[0].len() {
- sum_big += big[y][x][0];
- }
- }
- println!("Sum of small: {}", sum_small);
- println!("Sum of big: {}", sum_big);
-
// Simple scaling of the weights array based on mixing the four
// pixels falling under each fine pixel, weighted by area.
// To mix the pixels a little, we assume each fine pixel
@@ -1839,24 +1684,6 @@ pub fn zoom_double(small: &Vec<Vec<Vec<f64>>>, big: &mut Vec<Vec<Vec<f64>>>) {
}
}
}
-
- let mut sum_small = 0.;
- let mut sum_big = 0.;
-
- for y in 0..small.len() {
- for x in 0..small[0].len() {
- sum_small += small[y][x][0];
- }
- }
- for y in 0..big.len() {
- for x in 0..big[0].len() {
- sum_big += big[y][x][0];
- }
- }
- println!("Sum of small: {}", sum_small);
- println!("Sum of big: {}", sum_big);
-
- println!("==== Done zooming");
}
pub fn print_palette(palette: &Vec<(f64, f64, f64)>) {
@@ -1879,17 +1706,13 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
let ditherring_level =
0.09 * ((width * height) as f64).ln() - 0.04 * (palette_size as f64).ln() + 0.001;
- println!("Dimensions: {}x{}", width, height);
- println!("Palette size: {}", palette_size);
- println!("Dithering level: {}", ditherring_level);
-
let mut rng: u32 = 42;
- let mut image = vec![vec![[0.; 3]; width as usize]; height as usize];
+ let mut image = vec![vec![[0.; 3]; height as usize]; width as usize];
let _filter_weights_1 = vec![vec![[0.; 3]; 1]; 1];
let mut filter_weights_3 = vec![vec![[1.; 3]; 3]; 3];
let mut filter_weights_5 = vec![vec![[0.; 3]; 5]; 5];
- let mut quantized_image = vec![vec![0; width as usize]; height as usize];
+ let mut quantized_image = vec![vec![0; height as usize]; width as usize];
let mut palette: Vec<(f64, f64, f64)> = Vec::with_capacity(palette_size);
@@ -1922,8 +1745,6 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
}
}
- // println!("Sum: {}", _sum);
-
_sum /= 3.;
for i in 0..3 {
for j in 0..3 {
@@ -1946,8 +1767,6 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
}
}
- // println!("Sum5: {}", sum);
-
_sum /= 3.;
for i in 0..5 {
for j in 0..5 {
@@ -1965,15 +1784,15 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
let max_coarse_level: i32 = scolorq_max_coarse_level(width, height);
let mut coarse_variables =
vec![
- vec![vec![0.; palette_size]; (width >> max_coarse_level) as usize];
- (height >> max_coarse_level) as usize
+ vec![vec![0.; palette_size]; (height >> max_coarse_level) as usize];
+ (width >> max_coarse_level) as usize
];
// NOTE: The initialisation is tested
let mut pcoarse_variables =
vec![
- vec![vec![0.; palette_size]; (width >> max_coarse_level) as usize];
- (height >> max_coarse_level) as usize
+ vec![vec![0.; palette_size]; (height >> max_coarse_level) as usize];
+ (width >> max_coarse_level) as usize
];
for i in 0..(pcoarse_variables.len() as usize) {
for j in 0..(pcoarse_variables[0].len() as usize) {
@@ -1993,29 +1812,8 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
extended_neighborhood_height as usize
];
- /*
- for i in 0..3 {
- println!("\nfilter_weights_3[{}]", i);
- for i in 0..filter_weights_3.len() {
- for j in 0..filter_weights_3[0].len() {
- print!("[{}]", filter_weights_3[i][j][i]);
- }
- println!()
- }
- }
- */
-
compute_b_array(&filter_weights_3, &mut b0);
- let mut _sum_b0: f64 = 0.;
- for _k in 0..3 {
- for i in 0..b0.len() {
- for j in 0..b0[0].len() {
- // print!("[{}]", b0[i][j][k]);
- _sum_b0 += b0[i][j][0] + b0[i][j][1] + b0[i][j][2];
- }
- }
- }
- let mut a0 = vec![vec![[0.; 3]; width as usize]; height as usize];
+ let mut a0 = vec![vec![[0.; 3]; height as usize]; width as usize];
compute_a_image(&image, &mut a0, &b0);
@@ -2038,7 +1836,7 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
last_bvec_width = bi_width;
last_bvec_height = bi_height;
- let mut bi: Vec<Vec<[f64; 3]>> = vec![vec![[0.; 3]; bi_width as usize]; bi_height as usize];
+ let mut bi: Vec<Vec<[f64; 3]>> = vec![vec![[0.; 3]; bi_height as usize]; bi_width as usize];
for j_j_y in 0..bi_height {
for j_j_x in 0..bi_width {
@@ -2061,15 +1859,9 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
let ai_width = image.len() >> coarse_level;
let ai_height = image[0].len() >> coarse_level;
- let mut ai: Vec<Vec<[f64; 3]>> = vec![vec![[0.; 3]; ai_width as usize]; ai_height as usize];
- let mut sum_ai: f64 = 0.;
+ let mut ai: Vec<Vec<[f64; 3]>> = vec![vec![[0.; 3]; ai_height as usize]; ai_width as usize];
sum_coarsen(a_last, &mut ai);
- for i in 0..ai.len() {
- for j in 0..ai[0].len() {
- sum_ai += ai[i][j][0] + ai[i][j][1] + ai[i][j][2];
- }
- }
a_vec.push(ai);
}
@@ -2082,36 +1874,22 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
1.0 / ((cmp::max(3, max_coarse_level * iters_per_level)) as f64),
);
- // println!("Temperature multiplier: {}", temperature_multiplier);
-
let mut iters_at_current_level = 0;
let mut skip_palette_maintenance = false;
let mut s = vec![vec![[0.; 3]; palette_size]; palette_size];
compute_initial_s(&mut s, &coarse_variables, &b_vec[coarse_level as usize]);
- // BUG: Isn't the same as in C++
- // for v in 0..3 {
- // for i in 0..5 {
- // for j in 0..5 {
- // print!("[{}]", s[i][j][v]);
- // }
- // println!();
- // }
- // println!();
- // }
-
- let mut j_palette_sum = vec![vec![[0.; 3]; coarse_variables.len()]; coarse_variables[0].len()];
+ let mut j_palette_sum = vec![vec![[0.; 3]; coarse_variables[0].len()]; coarse_variables.len()];
compute_initial_j_palette_sum(&mut j_palette_sum, &coarse_variables, &palette);
while coarse_level >= 0 || temperature > final_temperature {
// Need to reseat this reference in case we changed p_coarse_variables
coarse_variables = vec![
- vec![vec![0.; palette_size]; pcoarse_variables.len() as usize];
- pcoarse_variables[0].len() as usize
+ vec![vec![0.; palette_size]; pcoarse_variables[0].len() as usize];
+ pcoarse_variables.len() as usize
];
- println!("1x 🍌🍌🍌🍌🍌🍌🍌🍌🍌🍌🍌🍌🍌🍌");
for i in 0..pcoarse_variables.len() {
for j in 0..pcoarse_variables[0].len() {
for v in 0..palette_size {
@@ -2120,51 +1898,28 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
}
}
- let mut a = &mut a_vec[coarse_level as usize];
+ let a = &mut a_vec[coarse_level as usize];
let b = &b_vec[coarse_level as usize];
- let mut middle_b = b_value(b, 0, 0, 0, 0);
-
- // println!(
- // "coarse_level: {} / Temperature: {}",
- // coarse_level, temperature
- // );
+ let middle_b = b_value(b, 0, 0, 0, 0);
let center_x = (b.len() - 1) >> 1;
let center_y = (b[0].len() - 1) >> 1;
- let mut step_counter = 0;
for _repeat in 0..repeats_per_temp {
- let mut pixels_changed = 0;
+ let mut _pixels_changed = 0;
let mut _pixel_visited = 0;
let mut visit_queue: VecDeque<(i32, i32)> = VecDeque::new();
let coarse_variables_width = coarse_variables.len();
let coarse_variables_height = coarse_variables[0].len();
- println!("Rng: {}", rng);
random_permutation_2d(
coarse_variables_width,
coarse_variables_height,
&mut visit_queue,
&mut rng,
);
- for v in 0..palette.len() {
- println!("v: {}", v);
- for i_y in 0..5 {
- for i_x in 0..5 {
- print!("[{:.5}]", coarse_variables[i_x][i_y][v])
- }
- println!()
- }
- println!()
- }
-
- // println!("Visit queue size: {}", visit_queue.len());
- // if _repeat == 0 && temperature == initial_temperature {
- // println!("Visit queue: {:?}", visit_queue);
- // }
while !visit_queue.is_empty() {
- // println!("j_palette_sum[1][9]: {:.7}", j_palette_sum[1][9][0]);
if visit_queue.len() > coarse_variables_width * coarse_variables_height * 11 / 10 {
visit_queue.clear();
random_permutation_2d(
@@ -2196,24 +1951,12 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
let b_ij = b_value(b, i_x, i_y, j_x, j_y);
let j_pal = j_palette_sum[j_x as usize][j_y as usize];
- // if pixels_changed >= 15 {
- // println!(
- // "p_i[0] = {:.5} ({:.5} + {:.5}), j_x, j_y: {}, {}",
- // p_i[0], b_ij[0], j_pal[0], j_x, j_y
- // );
- // }
p_i[0] += b_ij[0] * j_pal[0];
p_i[1] += b_ij[1] * j_pal[1];
p_i[2] += b_ij[2] * j_pal[2];
}
}
- // if pixels_changed >= 16 {
- // println!(
- // "p_i[0]: {:.7} / a[{}][{}]: {:.7}",
- // p_i[0], i_x, i_y, a[i_x as usize][i_y as usize][0]
- // );
- // }
p_i[0] = p_i[0] * 2.0 + a[i_x as usize][i_y as usize][0];
p_i[1] = p_i[1] * 2.0 + a[i_x as usize][i_y as usize][1];
@@ -2230,13 +1973,6 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
// since only the weight relative to the sum matters, so we
// will choose a value that makes the maximum e^100.
let palette_v = [palette[v].0, palette[v].1, palette[v].2];
- if pixels_changed >= 16 {
- // println!(
- // "Palette: {:.7}, {:.7}, {:.7}",
- // palette_v[0], palette_v[1], palette_v[2]
- // );
- // println!("P_i: ({:.7}, {:.7}, {:.7})", p_i[0], p_i[1], p_i[2]);
- }
let mut middle_b_tmp = vec![0.; middle_b.len()];
for i in 0..middle_b.len() {
@@ -2248,12 +1984,7 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
}
let meanfield_logs_last = -(middle_b_p_i_sum / temperature);
meanfield_logs.push(meanfield_logs_last);
- if pixels_changed >= 16 {
- // println!(
- // "temperature: {:.7} / meanfield_logs[0]: {:.7}",
- // temperature, meanfield_logs_last
- // );
- }
+
if meanfield_logs_last > max_meanfield_log {
max_meanfield_log = meanfield_logs_last;
}
@@ -2264,10 +1995,6 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
meanfields.push(tmp);
meanfield_sum += tmp;
}
- // println!(
- // "Meanfield_sum: {:.7} / max_meanfield_log: {:.7}",
- // meanfield_sum, max_meanfield_log
- // );
if meanfield_sum == 0. {
println!("Fatal errorr: Meanfield sum underflowed. Please contact developper.");
process::exit(1);
@@ -2275,8 +2002,7 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
let old_max_v =
best_match_color(&coarse_variables, i_x as usize, i_y as usize, &palette);
{
- let mut j_pal = &mut j_palette_sum[i_x as usize][i_y as usize];
- // println!("j_pal: ({:.5}, {:.5}, {:.5})", j_pal[0], j_pal[1], j_pal[2]);
+ let j_pal = &mut j_palette_sum[i_x as usize][i_y as usize];
for v in 0..palette.len() {
let mut new_val = meanfields[v] / meanfield_sum;
@@ -2287,10 +2013,6 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
new_val = 1. - 1e-10;
}
- if i_x > 2 && i_x <= 5 && i_y == 3 {
- println!("New val: {:.5}", new_val);
- }
-
let delta_m_iv = new_val - coarse_variables[i_x as usize][i_y as usize][v];
coarse_variables[i_x as usize][i_y as usize][v] = new_val;
pcoarse_variables[i_x as usize][i_y as usize][v] = new_val;
@@ -2298,22 +2020,16 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
j_pal[0] += delta_m_iv * palette[v].0;
j_pal[1] += delta_m_iv * palette[v].1;
j_pal[2] += delta_m_iv * palette[v].2;
- // println!("delta_m_iv: {:.7}", delta_m_iv,);
+
if delta_m_iv.abs() > 0.001 && !skip_palette_maintenance {
update_s(&mut s, &coarse_variables, b, i_x, i_y, v as i32, delta_m_iv);
}
}
}
- // println!(
- // "j_palette_sum: ({:.5}, {:.5}, {:.5})",
- // j_palette_sum[i_x as usize][i_y as usize][0],
- // j_palette_sum[i_x as usize][i_y as usize][1],
- // j_palette_sum[i_x as usize][i_y as usize][2]
- // );
let max_v =
best_match_color(&coarse_variables, i_x as usize, i_y as usize, &palette);
- // println!("Best match color: {}", max_v);
+
// Only consider it a change if the colors are different enough
let norm = (palette[max_v].0 - palette[old_max_v].0)
* (palette[max_v].0 - palette[old_max_v].0)
@@ -2321,12 +2037,9 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
* (palette[max_v].1 - palette[old_max_v].1)
+ (palette[max_v].2 - palette[old_max_v].2)
* (palette[max_v].2 - palette[old_max_v].2);
- // println!(
- // "Pixel change norm: {:.7} ({} vs {}) / {}",
- // norm, max_v, old_max_v, pixels_changed
- // );
+
if norm >= 1.0 / (255.0 * 255.0) {
- pixels_changed += 1;
+ _pixels_changed += 1;
// We don't add the outer layer of pixels , because
// there isn't much weight there, and if it does need
@@ -2357,19 +2070,8 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
}
}
_pixel_visited += 1;
-
- // Show progress with dots - in a graphical interface,
- // we'd show progressive refinements of the image instead,
- // and maybe a palette preview.
- step_counter += 1;
- if step_counter % 10_000 == 0 {
- print!(".");
- }
}
- println!("Queue visit end!");
- println!("Pixels changed: {} / {}", pixels_changed, _pixel_visited);
if skip_palette_maintenance {
- println!("🦊🦊🦊🦊🦊🦊🦊🦊🦊🦊🦊🦊");
compute_initial_s(&mut s, &pcoarse_variables, &b_vec[coarse_level as usize]);
}
// We only computed the half of S above the diagonal - reflect it
@@ -2385,11 +2087,7 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
iters_at_current_level += 1;
skip_palette_maintenance = false;
- // println!(
- // "Coarse level: {}, {} iters (per level: {})",
- // coarse_level, iters_at_current_level, iters_per_level
- // );
- // println!("Temperature: {:.3} / {:.3}", temperature, final_temperature);
+
if (temperature <= final_temperature || coarse_level > 0)
&& iters_at_current_level >= iters_per_level
{
@@ -2399,30 +2097,17 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
}
let mut p_new_coarse_variables =
vec![
- vec![vec![0.; palette_size]; (width >> coarse_level) as usize];
- (height >> coarse_level) as usize
+ vec![vec![0.; palette_size]; (height >> coarse_level) as usize];
+ (width >> coarse_level) as usize
];
- for x in 0..((width >> coarse_level) as usize) {
- for y in 0..((height >> coarse_level) as usize) {
- for v in 0..palette_size {
- p_new_coarse_variables[x][y][v] = 0.;
- }
- }
- }
zoom_double(&coarse_variables, &mut p_new_coarse_variables);
- println!("2x 🍌🍌🍌🍌🍌🍌🍌🍌🍌🍌🍌🍌🍌🍌");
pcoarse_variables = p_new_coarse_variables;
iters_at_current_level = 0;
j_palette_sum =
- vec![vec![[0.; 3]; pcoarse_variables.len()]; pcoarse_variables[0].len()];
+ vec![vec![[0.; 3]; pcoarse_variables[0].len()]; pcoarse_variables.len()];
compute_initial_j_palette_sum(&mut j_palette_sum, &pcoarse_variables, &palette);
- println!(
- "Image new size: {}x{}",
- pcoarse_variables.len(),
- pcoarse_variables[0].len()
- );
skip_palette_maintenance = true;
}
if temperature > final_temperature {
@@ -2435,23 +2120,18 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
coarse_level -= 1;
let mut p_new_coarse_variables =
vec![
- vec![vec![0.; palette_size]; (width >> coarse_level) as usize];
- (height >> coarse_level) as usize
+ vec![vec![0.; palette_size]; (height >> coarse_level) as usize];
+ (width >> coarse_level) as usize
];
zoom_double(&pcoarse_variables, &mut p_new_coarse_variables);
pcoarse_variables = p_new_coarse_variables;
- println!(
- "Image new_ size: {}x{}",
- pcoarse_variables.len(),
- pcoarse_variables[0].len()
- );
}
{
// Need to reseat this reference in case wee change p_coarse_variables
let mut coarse_variables =
vec![
- vec![vec![0.; palette_size]; pcoarse_variables.len() as usize];
- pcoarse_variables[0].len() as usize
+ vec![vec![0.; palette_size]; pcoarse_variables[0].len() as usize];
+ pcoarse_variables.len() as usize
];
for x in 0..pcoarse_variables.len() {
for y in 0..pcoarse_variables[0].len() {
@@ -2467,7 +2147,6 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
}
}
- print!("Palette: ");
for v in 0..palette_size {
if palette[v].0 > 1.0 {
palette[v].0 = 1.0;
@@ -2486,10 +2165,6 @@ pub fn dither_scolorq(image_in: &mut RgbImage, _palette_size: u8) {
} else if palette[v].2 < 0.0 {
palette[v].2 = 0.0;
}
- print!(
- "[]{:.2},{:.2},{:.2}] ",
- palette[v].0, palette[v].1, palette[v].2
- )
}
}
diff --git a/src/main.rs b/src/main.rs
index 8555232..ac28eb7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,16 +2,14 @@
use image::{ImageReader, Rgb};
use std::path::Path;
-const LIST_OF_SAMPLES: [&str; 2] = [
+const LIST_OF_SAMPLES: [&str; 6] = [
"samples/david.png",
"samples/david2.jpg",
- /*
- "samples/us.png",
- "samples/jane.jpg",
- "samples/jane2.webp",
- "samples/karel_kΓ€os.jpg",
- "samples/diderot_111.png",
- */
+ "samples/us.png",
+ "samples/jane.jpg",
+ "samples/jane2.webp",
+ "samples/karel_kΓ€os.jpg",
+ // "samples/diderot_111.png",
];
#[allow(dead_code)]
const PALETTE_3B: [Rgb<u8>; 8] = [
@@ -47,16 +45,17 @@ fn main() -> Result<(), image::ImageError> {
("kernel_ostromoukhov_1b", |img| {
dither::dither_ostromoukhov_1b(img)
}),
+ */
("kernel_ostromoukhov_3b", |img| {
dither::dither_ostromoukhov_3b(img)
}),
+ /*
("kernel_ostromoukhov_1b_alt", |img| {
dither::dither_ostromoukhov_1b_alt2(img)
}),
("bayer_3b", |img| dither::dither_bayer(256, img)),
*/
("scolorq", |_img| dither::dither_scolorq(_img, 16)),
- /*
("kernel_jarvis_judice_ninke_linear_3b", |img| {
dither::dither_palette_linear(
img,
@@ -73,10 +72,12 @@ fn main() -> Result<(), image::ImageError> {
},
)
}),
+ /*
("random_1b", dither::dither_random),
("random_3b", dither::dither_random_color),
("threshold_1b", dither::dither_threshold_1b),
("threshold_3b", dither::dither_threshold_3b),
+ */
("burkes_3b", |img| {
dither::dither_shift_8colors(
img,
@@ -85,10 +86,10 @@ fn main() -> Result<(), image::ImageError> {
bit_shift: dither::kernel::BURKES_KERNEL_BIT_SHIFT,
},
)
- }),*/
+ }),
];
- for sample in ["samples/us.png"] {
+ for sample in LIST_OF_SAMPLES {
for (suffix, algo) in &algos {
println!("{} on {}", suffix, sample);
let path = Path::new(sample);