mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-29 04:07:12 -06:00
EPS import: CMYK images keep their ink amounts
The PostScript interpreter that reads EPS and PostScript files turned the samples of a CMYK image into display RGB and stored an RGBA PNG, so the image lost its ink amounts. The DCTDecode filter decoded a CMYK JPEG to RGB, so it lost its ink amounts too. The PDF importer keeps the ink amounts of 8- and 16-bit CMYK images (in a CMYK TIFF, or the CMYK JPEG itself). A CMYK image (image or colorimage in DeviceCMYK, CIEBasedDEFG or a four-component ICCBased space) now keeps its samples in a CMYK TIFF (ImageBlob::cmyk_tiff), read through its Decode array, at every bit depth the interpreter reads. A CMYK JPEG gives its samples as stored, and the image's Decode array reads them: [1 0 1 0 1 0 1 0] undoes the inverted samples of Adobe's CMYK JPEGs. The pixels that a MaskColor or an ImageType 3 mask hides become a grayscale opacity mask over the image, as in PDF import. A mask that hides nothing adds no mask. Gray, RGB, indexed and spot color images and image masks stay RGBA PNGs. Docs: docs/file-format-parity.md, docs/target-app-parity.md.
This commit is contained in:
@@ -65,6 +65,34 @@ fn other_eps_files_are_read_by_the_postscript_interpreter() {
|
||||
assert_eq!(s.doc().unwrap().title(), "plain.eps");
|
||||
}
|
||||
|
||||
/// A CMYK image the PostScript interpreter reads keeps its ink amounts when the EPS opens and when
|
||||
/// it is placed, with its transparent pixel as its opacity mask.
|
||||
#[test]
|
||||
fn cmyk_images_keep_their_inks_when_an_eps_opens_or_is_placed() {
|
||||
let eps = b"%!PS-Adobe-3.0 EPSF-3.0\n%%BoundingBox: 0 0 60 20\n%%EndComments\n/DeviceCMYK setcolorspace 60 20 scale \
|
||||
<< /ImageType 4 /Width 2 /Height 1 /BitsPerComponent 8 /Decode [0 1 0 1 0 1 0 1] /ImageMatrix [2 0 0 -1 0 1] \
|
||||
/MaskColor [10 20 30 40] /DataSource <0a141e28 00667f08> >> image\nshowpage\n%%EOF\n";
|
||||
// Each image object's ink amounts (`None` when it isn't CMYK) and whether it has a mask.
|
||||
let images = |s: &Session| {
|
||||
let d = &s.doc().unwrap().doc;
|
||||
let mut found = vec![];
|
||||
d.walk(|n| {
|
||||
if let vectorcraft_doc::NodeKind::Image(im) = &n.kind {
|
||||
found.push((d.images[&im.key].cmyk().map(|i| i.data), n.extras().mask.is_some()));
|
||||
}
|
||||
});
|
||||
found
|
||||
};
|
||||
let want = (Some(vec![10, 20, 30, 40, 0, 102, 127, 8]), true);
|
||||
let mut s = Session::new();
|
||||
let r = open(&mut s, "cmyk.eps", eps).unwrap();
|
||||
assert_eq!(r["format"], "eps", "{r}");
|
||||
assert_eq!(images(&s), std::slice::from_ref(&want));
|
||||
let r = s.execute("file.place", &json!({"name": "cmyk.eps", "dataBase64": vectorcraft_format::base64_encode(eps)})).unwrap();
|
||||
assert_eq!(r["ids"].as_array().unwrap().len(), 1, "{r}");
|
||||
assert_eq!(images(&s), [want.clone(), want]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_unreadable_eps_file_comes_in_as_its_preview() {
|
||||
let mut s = Session::new();
|
||||
|
||||
Reference in New Issue
Block a user