fix(psd): keep a pixel layer's vstk when it has no vector mask, as Photoshop does
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
91f734aa80
commit
9aaeb6e628
|
|
@ -89,7 +89,7 @@ fn raster_layer_with_stale_blocks_writes_none() {
|
||||||
assert!(l.psd_blocks.iter().any(|(k, _)| k == b"SoCo"));
|
assert!(l.psd_blocks.iter().any(|(k, _)| k == b"SoCo"));
|
||||||
l.content = LayerContent::Raster(photocraft_raster::Surface::new(fmt));
|
l.content = LayerContent::Raster(photocraft_raster::Surface::new(fmt));
|
||||||
l.psd_blocks.push((*b"TySh", std::sync::Arc::new(vec![0; 8])));
|
l.psd_blocks.push((*b"TySh", std::sync::Arc::new(vec![0; 8])));
|
||||||
l.psd_blocks.push((*b"vstk", std::sync::Arc::new(vec![0; 8])));
|
l.psd_blocks.push((*b"vscg", std::sync::Arc::new(vec![0; 8])));
|
||||||
l.psd_blocks.push((*b"levl", std::sync::Arc::new(vec![0; 8])));
|
l.psd_blocks.push((*b"levl", std::sync::Arc::new(vec![0; 8])));
|
||||||
assert!(!has_block(&doc, &name, &[b"SoCo", b"TySh", b"vstk", b"vscg", b"SoLd", b"PlLd", b"levl"]));
|
assert!(!has_block(&doc, &name, &[b"SoCo", b"TySh", b"vstk", b"vscg", b"SoLd", b"PlLd", b"levl"]));
|
||||||
assert_eq!(kind_named(&reopen(&doc), &name), "raster");
|
assert_eq!(kind_named(&reopen(&doc), &name), "raster");
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@ use crate::pixels::{deinterleave, encode_be, psd_depth};
|
||||||
use crate::psd_import::REGENERATED;
|
use crate::psd_import::REGENERATED;
|
||||||
|
|
||||||
/// Blocks that define a layer's content as something other than pixels: fill (`SoCo`, `GdFl`,
|
/// Blocks that define a layer's content as something other than pixels: fill (`SoCo`, `GdFl`,
|
||||||
/// `PtFl`), placed / smart object (`SoLd`, `PlLd`, `SoLE`), type (`TySh`), shape fill and stroke
|
/// `PtFl`), placed / smart object (`SoLd`, `PlLd`, `SoLE`), type (`TySh`) and shape fill (`vscg`).
|
||||||
/// (`vscg`, `vstk`). A raster layer never writes them, nor adjustment blocks.
|
/// A raster layer never writes them, nor adjustment blocks.
|
||||||
const RASTER_STALE_KEYS: [&[u8; 4]; 9] = [b"SoCo", b"GdFl", b"PtFl", b"SoLd", b"PlLd", b"SoLE", b"TySh", b"vscg", b"vstk"];
|
const RASTER_STALE_KEYS: [&[u8; 4]; 8] = [b"SoCo", b"GdFl", b"PtFl", b"SoLd", b"PlLd", b"SoLE", b"TySh", b"vscg"];
|
||||||
|
|
||||||
const PSD_MAX_FILE_SIZE: u64 = 2 * 1024 * 1024 * 1024;
|
const PSD_MAX_FILE_SIZE: u64 = 2 * 1024 * 1024 * 1024;
|
||||||
const PSD_ESTIMATE_FIXED_OVERHEAD: u64 = 1024 * 1024;
|
const PSD_ESTIMATE_FIXED_OVERHEAD: u64 = 1024 * 1024;
|
||||||
|
|
@ -590,12 +590,13 @@ impl Ex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// A pixel layer carries no content-defining blocks: a fill, placed (smart), type or
|
// A pixel layer carries no content-defining blocks: a fill, placed (smart), type or
|
||||||
// shape-content block left over from before Rasterize would make a reader (ours or
|
// shape-fill block left over from before Rasterize would make a reader (ours or
|
||||||
// Photoshop's) reopen the layer as that kind and discard the pixels. A vector mask
|
// Photoshop's) reopen the layer as that kind and discard the pixels. A shape stroke
|
||||||
// (`vmsk`/`vsms`, with its live-shape `vogk`) stays.
|
// (`vstk`) beside a vector mask makes a shape too; without one, Photoshop keeps it on
|
||||||
|
// pixel layers, so it stays. A vector mask (`vmsk`/`vsms`, `vogk`) stays.
|
||||||
LayerContent::Raster(_) => {
|
LayerContent::Raster(_) => {
|
||||||
let masked = l.vector_mask.is_some();
|
let masked = l.vector_mask.is_some();
|
||||||
raw.retain(|(k, _)| !RASTER_STALE_KEYS.contains(&k) && !adjust_map::ADJUSTMENT_KEYS.contains(&k) && k != b"CgEd" && !(k == b"vogk" && !masked));
|
raw.retain(|(k, _)| !RASTER_STALE_KEYS.contains(&k) && !adjust_map::ADJUSTMENT_KEYS.contains(&k) && k != b"CgEd" && !(k == b"vstk" && masked));
|
||||||
}
|
}
|
||||||
LayerContent::Group(_) => {}
|
LayerContent::Group(_) => {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue