mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-01 21:57:12 -06:00
TIFF: planar grayscale files with extra channels, and planar CMYK files, open and place
TIFFs that store each channel as its own plane (PlanarConfiguration 2) did not open, place or relink when they were CMYK or grayscale with extra channels: the image decoder refuses planar CMYK, and the readers for CMYK inks and for extra samples returned nothing for planar files. The two readers now read every plane through the tiff crate and put each pixel's samples together. A planar CMYK TIFF keeps its ink amounts and is stored as a CMYK TIFF with each pixel's inks together, at the file's resolution. Grayscale TIFFs with an alpha channel or other extra channels, and CMYK TIFFs with alpha, read as their chunky versions do. A TIFF whose header claims more strips or tiles than the tiff decoder can count is refused as too large to draw. The decoder multiplies those counts without a check, which panics in builds with overflow checks. Part of #1466. Docs: docs/file-format-parity.md, docs/target-app-parity.md.
This commit is contained in:
@@ -1303,6 +1303,17 @@ fn raster_samples() -> Vec<(&'static str, Vec<u8>)> {
|
||||
out.push((name, b));
|
||||
}
|
||||
out[0].1 = vectorcraft_engine::cmd::fileio::ppi::with_png_resolution(&out[0].1, (300.0, 150.0));
|
||||
// TIFFs that store one plane per channel: CMYK with a channel after the inks, and gray with
|
||||
// alpha, 16 bits a sample.
|
||||
let plane = |v: u16| vec![v; 15];
|
||||
let cmyk = [plane(200), plane(40), plane(10), plane(0), plane(90)];
|
||||
let cmyk =
|
||||
vectorcraft_testkit::tiff::Tiff { width: 5, height: 3, photometric: 5, bits: 8, extra: &[0], planar: true, ppi: Some(300), channels: &cmyk };
|
||||
out.push(("planar-cmyk.tif", vectorcraft_testkit::tiff::tiff(&cmyk)));
|
||||
let gray = [plane(30_000), plane(65_535)];
|
||||
let gray =
|
||||
vectorcraft_testkit::tiff::Tiff { width: 5, height: 3, photometric: 1, bits: 16, extra: &[2], planar: true, ppi: None, channels: &gray };
|
||||
out.push(("planar-gray.tif", vectorcraft_testkit::tiff::tiff(&gray)));
|
||||
// A layered PSD with transparency (as VectorCraft exports it), and a PackBits PSB by hand.
|
||||
let mut s = rich_session();
|
||||
let r = s.execute("document.export", &json!({"format": "psd", "ppi": 2})).unwrap();
|
||||
@@ -1325,7 +1336,7 @@ proptest! {
|
||||
/// Mutated image headers (resolution metadata, chunk and segment lengths) never crash reading
|
||||
/// their resolution or placing them.
|
||||
#[test]
|
||||
fn mutated_images_place_without_panics(which in 0usize..6, cut in 0usize..4000, edits in prop::collection::vec((0usize..120, any::<u8>()), 0..12)) {
|
||||
fn mutated_images_place_without_panics(which in 0usize..8, cut in 0usize..4000, edits in prop::collection::vec((0usize..120, any::<u8>()), 0..12)) {
|
||||
let (name, mut bytes) = raster_samples().swap_remove(which);
|
||||
for (at, b) in edits {
|
||||
if let Some(x) = bytes.get_mut(at) {
|
||||
|
||||
Reference in New Issue
Block a user