Integrate image-only CCITT guards and combined rendition coverage

This commit is contained in:
FredApps
2026-11-07 15:44:44 +01:00
4 changed files with 23 additions and 2 deletions
+17
View File
@@ -133,3 +133,20 @@ fn controlled_reads_keep_limit_and_malformed_input_errors() {
}
}
}
#[test]
fn controlled_full_composites_preserve_provenance_and_selected_reads() {
let full = png(4, 3, 30);
let manifest = pcraft_manifest(1, "[]", r#", "full_composite":"composite/full.png", "composite":"composite/preview.png""#);
let file = zip(&[store("manifest.json", manifest.as_bytes()), store("composite/full.png", &full)]);
let limits = Limits::default();
let selected = craft_doc::rendition(&file, craft_doc::RenditionKind::Composite, &limits).unwrap().unwrap();
let controlled = renditions_with_cancel(&file, &limits, &|| false).unwrap();
assert_eq!(controlled, vec![selected]);
assert_eq!(controlled[0].bytes, full);
assert!(controlled[0].is_full_composite);
assert_eq!(renditions_with_cancel(&file, &limits, &|| true), Err(Error::Cancelled));
let missing_full = zip(&[store("manifest.json", manifest.as_bytes()), store("composite/preview.png", &full)]);
assert!(matches!(renditions_with_cancel(&missing_full, &limits, &|| false), Err(Error::Malformed(_))));
}
+3
View File
@@ -324,6 +324,9 @@ products match its vertices (moving the points alone skewed barycentric coordina
`restore_state` doesn't when the saved-state bound skipped the save; and a resolved JP2
palette decodes to 8 bits whatever `/BitsPerComponent` the dictionary gives.
`hayro-syntax` compiles `filter::ccitt_max_rows` and its unit tests only with the
`images` feature, matching `filter::ccitt`.
This remains the patched 0.7 backend. It retains the existing Bradford Lab conversion,
floating component precision and codec versions, rather than claiming full 0.8
equivalence. The independent color oracles, backend tests and facade contracts cover
+1 -1
View File
@@ -176,7 +176,7 @@
"path": "src/filter/mod.rs",
"source_sha256": "0af7145ab16b15b7a60c4b57efecb9bd5fd0cfdc9bb5f9388abb695386e63e49",
"source_git_blob": "06bda29487d62c25dc39c1ee109091cb17e3867f",
"sha256": "3719baece25774c09263307b823ef36e834ea095e0d1728cfc664a64123fc340"
"sha256": "74127a32b9ac86e33f41ac10f9a51a95849caca9211b0f7ee7eb535f5a59d063"
},
{
"path": "src/filter/run_length.rs",
+2 -1
View File
@@ -182,13 +182,14 @@ const MAX_CCITT_PIXELS: u64 = 1 << 28;
/// PdfCraft patch: the most rows of `columns` pixels, `row_bytes` bytes each once decoded, that fit
/// both `limit` bytes and the pixel cap; at least one when one row fits.
#[cfg(feature = "images")]
pub(crate) fn ccitt_max_rows(columns: u32, row_bytes: u32, limit: usize) -> u32 {
let by_pixels = MAX_CCITT_PIXELS / u64::from(columns.max(1));
let by_bytes = u64::try_from(limit).unwrap_or(u64::MAX) / u64::from(row_bytes.max(1));
u32::try_from(by_pixels.min(by_bytes)).unwrap_or(u32::MAX)
}
#[cfg(test)]
#[cfg(all(test, feature = "images"))]
mod ccitt_tests {
use super::ccitt_max_rows;