mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-02 06:07:06 -06:00
A CMYK JPEG is not labelled JFIF
A CMYK JPEG came out with JFIF's APP0 segment at its head and four components in the frame: APP0/JFIF APP14/Adobe APP2[ICC_PROFILE 1/4 … 4/4] SOF0: 4 components JFIF describes one- and three-component images, greyscale and YCbCr, so an APP0 segment in front of a four-component frame says two different things about the file's colours: a reader that trusts JFIF decodes nonsense, and one that checks refuses the file. Adobe's own CMYK JPEGs carry the APP14 marker the encoder already writes, and no JFIF. `jpeg-encoder` writes JFIF unconditionally, so the segment is replaced here. The resolution JFIF carried moves to an EXIF APP1 segment -- `XResolution`, `YResolution` and `ResolutionUnit` -- which is where `cmd::fileio::ppi` already looks when a file has no JFIF, so nothing is lost; with no resolution asked for the segment is simply dropped. RGB and greyscale files keep JFIF, which is what it is for. Found while looking at #3084, whose default RGB exports are valid here; this is the file that is not.
This commit is contained in:
@@ -220,6 +220,21 @@ mod tests {
|
||||
assert!(close(resolution(&jpg).unwrap(), (254.0, 240.0 * 2.54)));
|
||||
}
|
||||
|
||||
/// A CMYK JPEG carries no JFIF (it describes one- and three-component images), so its
|
||||
/// resolution is written as EXIF instead and this reader still finds it (#3084).
|
||||
#[test]
|
||||
fn a_cmyk_jpeg_keeps_its_resolution_without_jfif() {
|
||||
use vectorcraft_render::encode::jpeg::{self, ColorModel, JpegOptions};
|
||||
let o = JpegOptions { color_model: ColorModel::Cmyk, ..Default::default() };
|
||||
let jpg = jpeg::encode(&[0; 4 * 4], 2, 2, 90, Some(240.0), &o).unwrap();
|
||||
assert!(!jpg.windows(5).any(|w| w == b"JFIF\0"), "no JFIF on a CMYK file");
|
||||
assert_eq!(resolution(&jpg), Some((240.0, 240.0)));
|
||||
// An RGB file still says it in JFIF, as it always did.
|
||||
let rgb = jpeg::encode(&[0; 3 * 4], 2, 2, 90, Some(240.0), &JpegOptions::default()).unwrap();
|
||||
assert!(rgb.windows(5).any(|w| w == b"JFIF\0"));
|
||||
assert_eq!(resolution(&rgb), Some((240.0, 240.0)));
|
||||
}
|
||||
|
||||
/// A little-endian TIFF/EXIF block declaring `x`/`y` resolution in `unit`.
|
||||
fn exif_block(x: u32, y: u32, unit: u16) -> Vec<u8> {
|
||||
let mut b = b"II*\0".to_vec();
|
||||
|
||||
Reference in New Issue
Block a user