Pad an open void's canvas to a tile: the merge page's preview is shorter than one, and filled nothing
This commit is contained in:
@@ -303,7 +303,7 @@ fn fill_once(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The padded canvas with mirrored context, and the hole within it.
|
// The padded canvas with mirrored context, and the hole within it.
|
||||||
let ctx = MirroredContext::build(rgb, width, height, known, mirror_depth);
|
let ctx = MirroredContext::build(rgb, width, height, known, mirror_depth, t);
|
||||||
let (pw, ph) = (ctx.width, ctx.height);
|
let (pw, ph) = (ctx.width, ctx.height);
|
||||||
|
|
||||||
// Tiles that touch the hole, on a grid that reaches both far edges.
|
// Tiles that touch the hole, on a grid that reaches both far edges.
|
||||||
@@ -499,16 +499,36 @@ struct MirroredContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MirroredContext {
|
impl MirroredContext {
|
||||||
fn build(rgb: &[f32], width: usize, height: usize, known: &[bool], depth: usize) -> Self {
|
fn build(
|
||||||
|
rgb: &[f32],
|
||||||
|
width: usize,
|
||||||
|
height: usize,
|
||||||
|
known: &[bool],
|
||||||
|
depth: usize,
|
||||||
|
tile: usize,
|
||||||
|
) -> Self {
|
||||||
if depth == 0 {
|
if depth == 0 {
|
||||||
// Open: the picture as it is, the hole as it is. What the hole
|
// Open: the picture as it is, the hole as it is. What the hole
|
||||||
// holds does not matter — the model masks it out.
|
// holds does not matter — the model masks it out. A picture
|
||||||
|
// smaller than a tile (the merge page's preview) sits at the
|
||||||
|
// origin of a tile-sized canvas whose rest is hole: still the
|
||||||
|
// void as it is, and the only way a tile fits at all.
|
||||||
|
let (pw, ph) = (width.max(tile), height.max(tile));
|
||||||
|
let mut canvas = vec![0.0f32; pw * ph * 3];
|
||||||
|
let mut hole = vec![true; pw * ph];
|
||||||
|
for y in 0..height {
|
||||||
|
canvas[y * pw * 3..(y * pw + width) * 3]
|
||||||
|
.copy_from_slice(&rgb[y * width * 3..(y + 1) * width * 3]);
|
||||||
|
for x in 0..width {
|
||||||
|
hole[y * pw + x] = !known[y * width + x];
|
||||||
|
}
|
||||||
|
}
|
||||||
return MirroredContext {
|
return MirroredContext {
|
||||||
width,
|
width: pw,
|
||||||
height,
|
height: ph,
|
||||||
ring: 0,
|
ring: 0,
|
||||||
rgb: rgb.to_vec(),
|
rgb: canvas,
|
||||||
hole: known.iter().map(|&k| !k).collect(),
|
hole,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let fold = |d: usize| fold(d, depth);
|
let fold = |d: usize| fold(d, depth);
|
||||||
@@ -715,6 +735,30 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_picture_smaller_than_the_tile_is_still_filled_when_the_void_is_open() {
|
||||||
|
// The merge page's preview is 1600 wide and a few hundred tall —
|
||||||
|
// shorter than a 512 tile. With no ring the canvas is padded to a
|
||||||
|
// tile, the padding hole, and the border is still filled.
|
||||||
|
let (mut rgb, known) = picture(300, 40, 8);
|
||||||
|
let mut model = Flat {
|
||||||
|
tile: 64,
|
||||||
|
seen: Vec::new(),
|
||||||
|
};
|
||||||
|
let tiles = fill_border(&mut rgb, 300, 40, &known, &mut model, test_params(0), &mut |_, _| {})
|
||||||
|
.unwrap();
|
||||||
|
assert!(tiles > 0, "no tile fitted a picture shorter than the tile");
|
||||||
|
for i in 0..300 * 40 {
|
||||||
|
if !known[i] {
|
||||||
|
assert!((rgb[i * 3] - 0.5).abs() < 1e-4, "pixel {i}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// And the model saw the padding as hole, never as black content.
|
||||||
|
for (_, k) in &model.seen {
|
||||||
|
assert_eq!(k.len(), 64 * 64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn the_fine_passes_run_in_bands_after_the_coarse_one() {
|
fn the_fine_passes_run_in_bands_after_the_coarse_one() {
|
||||||
// A 150-tall hole above and below a picture: the coarse pass sees
|
// A 150-tall hole above and below a picture: the coarse pass sees
|
||||||
@@ -824,7 +868,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn the_context_mirrors_the_top_rows_upward() {
|
fn the_context_mirrors_the_top_rows_upward() {
|
||||||
let (rgb, known) = picture(40, 30, 5);
|
let (rgb, known) = picture(40, 30, 5);
|
||||||
let ctx = MirroredContext::build(&rgb, 40, 30, &known, 48);
|
let ctx = MirroredContext::build(&rgb, 40, 30, &known, 48, 64);
|
||||||
let x = RING + 10;
|
let x = RING + 10;
|
||||||
let first = RING + 5;
|
let first = RING + 5;
|
||||||
for k in 1..=4 {
|
for k in 1..=4 {
|
||||||
@@ -846,7 +890,7 @@ mod tests {
|
|||||||
for x in 0..40 {
|
for x in 0..40 {
|
||||||
rgb[(ridge * 40 + x) * 3..(ridge * 40 + x) * 3 + 3].copy_from_slice(&[0.9, 0.1, 0.1]);
|
rgb[(ridge * 40 + x) * 3..(ridge * 40 + x) * 3 + 3].copy_from_slice(&[0.9, 0.1, 0.1]);
|
||||||
}
|
}
|
||||||
let ctx = MirroredContext::build(&rgb, 40, 400, &known, 48);
|
let ctx = MirroredContext::build(&rgb, 40, 400, &known, 48, 64);
|
||||||
let x = RING + 10;
|
let x = RING + 10;
|
||||||
for y in 0..RING + 5 {
|
for y in 0..RING + 5 {
|
||||||
let p = (y * ctx.width + x) * 3;
|
let p = (y * ctx.width + x) * 3;
|
||||||
|
|||||||
Reference in New Issue
Block a user