test(create,optimize): the other way round, the same size and larger

The shapes in these tests all ran one way. The way round depends on the shapes: 1 × 100,000 to
100,000 × 1 asks for 10 GB if it goes across first, or 30 GB at three components, so that is held to
as well. A mask of its image's size comes through byte for byte, and a larger one scales.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmsdeUCdTaD72jkDw2pJKY
This commit is contained in:
Grzegorz Martens
2026-11-01 09:31:58 +01:00
co-authored by Claude Opus 5.5
parent 640e7acb15
commit db4162d2ef
2 changed files with 33 additions and 7 deletions
+18 -4
View File
@@ -2210,9 +2210,11 @@ fn jbig2_globals_are_decoded_within_a_limit_of_their_own() {
}
}
/// A mask of other proportions than its image is scaled to it, however far apart they are: these
/// shapes asked for 160 GB on the way, in a file of a kilobyte, and that aborted the process. The
/// value comes through, and masks of ordinary proportions are scaled as they always were.
/// A mask of other proportions than its image is scaled to it, however far apart they are: the
/// first two shapes asked for 160 GB on the way, in a file of a kilobyte, and that aborted the
/// process. The third would ask for 10 GB if it went across first, which is why the way round
/// depends on the shapes. The value comes through, and masks of ordinary proportions, of the
/// image's size and larger than it, are scaled as they always were.
#[test]
fn a_mask_of_other_proportions_than_its_image_is_scaled_without_the_memory_of_both() {
use pdfcraft_cos::{Dict, Document, Object, Stream};
@@ -2226,7 +2228,16 @@ fn a_mask_of_other_proportions_than_its_image_is_scaled_without_the_memory_of_bo
d.set(b"Filter".to_vec(), Object::name("FlateDecode"));
Stream::from_raw(d, pdfcraft_filters::encode_flate(data))
};
for (mask_w, mask_h, w, h) in [(100_000usize, 1usize, 1usize, 100_000usize), (100_000, 64, 64, 100_000), (64, 1, 1, 64), (3, 2, 6, 4)] {
let shapes = [
(100_000usize, 1usize, 1usize, 100_000usize),
(100_000, 64, 64, 100_000),
(1, 100_000, 100_000, 1),
(64, 1, 1, 64),
(3, 2, 6, 4),
(3, 2, 3, 2),
(6, 4, 3, 2),
];
for (mask_w, mask_h, w, h) in shapes {
let mut doc = Document::new_empty();
let mask = doc.add(Object::Stream(gray(mask_w as i64, mask_h as i64, &vec![0x80; mask_w * mask_h])));
let mut image = gray(w as i64, h as i64, &vec![0x40; w * h]);
@@ -2269,4 +2280,7 @@ fn proportions_up_to_the_limit_scale_as_they_did() {
let mask = noise(25, 15);
let direct = image::imageops::resize(&mask, 10, 20, image::imageops::FilterType::Triangle);
assert_ne!(crate::extract::scaled(&mask, 10, 20), direct);
// A mask of its image's size comes through as it is.
let mask = noise(20, 10);
assert_eq!(crate::extract::scaled(&mask, 20, 10), mask);
}
+15 -3
View File
@@ -1262,11 +1262,20 @@ mod dimension_tests {
}
/// Resampling goes through no more than one of the two sizes holds, whatever their proportions:
/// these shapes asked for 160 GB and more on the way, and that aborted the process. A flat
/// picture stays flat, and pictures of ordinary proportions resample as they always did.
/// the first three shapes asked for 160 GB and more on the way, and that aborted the process.
/// The last two would ask for 10 GB and 30 GB if they went across first, which is why the way
/// round depends on the shapes. A flat picture stays flat, and pictures of ordinary proportions
/// resample as they always did.
#[test]
fn resampling_across_proportions_takes_the_memory_of_neither_product() {
for (w, h, nw, nh, n) in [(100_000u32, 1u32, 1u32, 100_000u32, 1usize), (1_000_000, 1, 4, 100_000, 1), (100_000, 1, 1, 100_000, 3)] {
let shapes = [
(100_000u32, 1u32, 1u32, 100_000u32, 1usize),
(1_000_000, 1, 4, 100_000, 1),
(100_000, 1, 1, 100_000, 3),
(1, 100_000, 100_000, 1, 1),
(1, 100_000, 100_000, 1, 3),
];
for (w, h, nw, nh, n) in shapes {
let px = vec![0x60; (w * h) as usize * n];
let out = resample(&px, n, w, h, nw, nh).unwrap();
assert_eq!(out.len(), (nw * nh) as usize * n);
@@ -1307,6 +1316,9 @@ mod dimension_tests {
// A step past it goes the long way, which is how to tell.
let px = noise(25, 15);
assert_ne!(resample(&px, 1, 25, 15, 10, 20).unwrap(), direct(&px, 25, 15, 10, 20));
// A picture of the size asked for comes through as it is.
let px = noise(20, 10);
assert_eq!(resample(&px, 1, 20, 10, 20, 10).unwrap(), px);
}
}