File formats: JPEG XL reads Exif resolution and bounds the container copy

A JPEG XL container's Exif box now sizes opened and placed images by its
resolution tags, as TIFF and WebP Exif do; a bare codestream stays at
72 ppi. The pixel boxes copied out of a container are limited to the
raster allowance and reserved fallibly, so a large payload is refused
with "the JPEG XL container is too large to read" before decoding.
This commit is contained in:
dotCooCoo
2026-10-30 21:53:19 -07:00
parent 00c37d2d42
commit 6118e7afba
25 changed files with 111 additions and 9 deletions
+13 -6
View File
@@ -42,9 +42,11 @@ pub fn is_jxl(bytes: &[u8]) -> bool {
/// The first frame of a JPEG XL image as straight RGBA, with the embedded ICC profile its colors
/// are in when they are not converted to sRGB ([`kept_profile`]). Fails, without decoding the
/// pixels, when the image would take more than `max_alloc` bytes as RGBA. The image is also too
/// large to draw when the decoder's buffers for its pixels need more than they are allowed.
/// large to draw when the decoder's buffers for its pixels need more than they are allowed. A
/// container whose selected boxes exceed `max_alloc` or [`HEADER_BUFFERS`], whichever is greater,
/// is refused with "the JPEG XL container is too large to read".
pub fn decode(bytes: &[u8], max_alloc: u64) -> Result<(image::RgbaImage, Option<Vec<u8>>), String> {
let pixel_boxes = pixel_boxes(bytes);
let pixel_boxes = pixel_boxes(bytes, max_alloc.max(HEADER_BUFFERS as u64))?;
let bytes = pixel_boxes.as_deref().unwrap_or(bytes);
// The decoder reads the header first, with buffers for the header alone.
let (head, _) = header(bytes, HEADER_BUFFERS, None)?;
@@ -169,9 +171,10 @@ pub(crate) fn to_rgba(
/// A container's signature and the boxes the decoder reads pixels from (`ftyp`, `jxll`, `jxlc` and
/// `jxlp`). Every other box is left out: Exif, XMP, JPEG reconstruction data and Brotli-compressed
/// `brob` boxes, which the decoder would otherwise store and unpack without a size limit. A box
/// cut short ends the file. `None` for a bare codestream.
fn pixel_boxes(bytes: &[u8]) -> Option<Vec<u8>> {
let mut rest = bytes.strip_prefix(&CONTAINER)?;
/// cut short ends the file. Selected boxes exceeding `max_copy` are refused with "the JPEG XL
/// container is too large to read". `None` for a bare codestream.
pub(super) fn pixel_boxes(bytes: &[u8], max_copy: u64) -> Result<Option<Vec<u8>>, String> {
let Some(mut rest) = bytes.strip_prefix(&CONTAINER) else { return Ok(None) };
let mut out = CONTAINER.to_vec();
while let (Some(size), Some(ty)) = (rest.get(..4).and_then(|s| <[u8; 4]>::try_from(s).ok()), rest.get(4..8)) {
let (head, len) = match u32::from_be_bytes(size) {
@@ -188,11 +191,15 @@ fn pixel_boxes(bytes: &[u8]) -> Option<Vec<u8>> {
let len = usize::try_from(len).unwrap_or(usize::MAX).min(rest.len());
let (b, after) = rest.split_at(len);
if matches!(ty, b"ftyp" | b"jxll" | b"jxlc" | b"jxlp") {
if (out.len() as u64).saturating_add(b.len() as u64) > max_copy {
return Err("the JPEG XL container is too large to read".into());
}
out.try_reserve_exact(b.len()).map_err(|_| "the JPEG XL container is too large to read")?;
out.extend_from_slice(b);
}
rest = after;
}
Some(out)
Ok(Some(out))
}
/// A decoder whose buffers may take `buffers` bytes, given as few of `bytes` as it needs to read
+29 -1
View File
@@ -1,5 +1,5 @@
//! Image resolution metadata (pixels per inch): PNG `pHYs`, JPEG JFIF density or EXIF, TIFF and
//! WebP EXIF resolution tags, BMP pixels per metre, a Photoshop document's ResolutionInfo, a PCX
//! WebP and JPEG XL EXIF resolution tags, BMP pixels per metre, a Photoshop document's ResolutionInfo, a PCX
//! header's HDpi and VDpi. Place
//! sizes an image by it (72 ppi when the file has none); images converted to PNG on import keep it
//! as a `pHYs` chunk.
@@ -16,6 +16,8 @@ pub fn resolution(bytes: &[u8]) -> Option<(f64, f64)> {
jpeg(bytes)
} else if bytes.starts_with(b"II*\0") || bytes.starts_with(b"MM\0*") {
tiff(bytes)
} else if super::jxlread::is_jxl(bytes) {
jxl(bytes)
} else if bytes.len() >= 12 && &bytes[..4] == b"RIFF" && &bytes[8..12] == b"WEBP" {
webp(bytes)
} else if bytes.starts_with(b"BM") {
@@ -153,6 +155,32 @@ fn webp(b: &[u8]) -> Option<(f64, f64)> {
None
}
fn jxl(b: &[u8]) -> Option<(f64, f64)> {
if !b.starts_with(&[0, 0, 0, 12, b'J', b'X', b'L', b' ', 13, 10, 135, 10]) {
return None;
}
let mut at = 12;
while at < b.len() {
let size = be32(b, at)?;
let ty = slice(b, at.checked_add(4)?, 4)?;
let (header, len) = match size {
0 => (8, b.len().checked_sub(at)?),
1 => (16, usize::try_from(u64::from_be_bytes(bytes(b, at.checked_add(8)?)?)).ok()?),
_ => (8, size as usize),
};
if len < header {
return None;
}
let payload = slice(b, at.checked_add(header)?, len - header)?;
if ty == b"Exif" {
let offset = usize::try_from(be32(payload, 0)?).ok()?;
return tiff(payload.get(4usize.checked_add(offset)?..)?);
}
at = at.checked_add(len)?;
}
None
}
fn bmp(b: &[u8]) -> Option<(f64, f64)> {
// BITMAPINFOHEADER (40 bytes or longer) at 14: pixels per metre at +24 and +28.
if le32(b, 14)? < 40 {
+47 -1
View File
@@ -6,7 +6,7 @@ use zune_core::bit_depth::BitDepth;
use zune_core::colorspace::ColorSpace;
use zune_core::options::EncoderOptions;
use super::jxlread::{ToSrgb, decode, is_jxl, kept_profile, to_rgba};
use super::jxlread::{ToSrgb, decode, is_jxl, kept_profile, pixel_boxes, to_rgba};
use super::*;
/// A lossless JPEG XL codestream of `w` × `h` pixels: `samples` in `space`, 8-bit, or 16-bit in
@@ -69,6 +69,52 @@ fn jxl_images_open_and_place_with_their_pixels_and_alpha() {
assert!(open_filters().any(|f| f == ("JPEG XL", &["jxl"][..])) && place_filters().any(|f| f == ("JPEG XL", &["jxl"][..])));
}
#[test]
fn container_copy_stays_within_the_input_allowance() {
let f = container(&[0; 128]);
assert!(pixel_boxes(&f, 64).unwrap_err().contains("too large"));
assert_eq!(pixel_boxes(&f, f.len() as u64).unwrap().unwrap(), f);
}
#[test]
fn container_exif_resolution_sizes_open_and_place() {
let bare = rgba8();
let mut f = container(&[]);
f.truncate(32);
let mut exif = Vec::new();
exif.extend(4u32.to_be_bytes());
exif.extend(b"Exif");
exif.extend(b"II*\0");
exif.extend(8u32.to_le_bytes());
exif.extend(3u16.to_le_bytes());
for (tag, value) in [(282u16, 50u32), (283, 58), (296, 2)] {
exif.extend(tag.to_le_bytes());
exif.extend((if tag == 296 { 3u16 } else { 5 }).to_le_bytes());
exif.extend(1u32.to_le_bytes());
exif.extend(value.to_le_bytes());
}
exif.extend(0u32.to_le_bytes());
for value in [144u32, 1, 72, 1] {
exif.extend(value.to_le_bytes());
}
f.extend((8 + exif.len() as u32).to_be_bytes());
f.extend(b"Exif");
f.extend(&exif);
f.extend((8 + bare.len() as u32).to_be_bytes());
f.extend(b"jxlc");
f.extend(&bare);
assert_eq!(super::ppi::resolution(&f), Some((144.0, 72.0)));
assert_eq!(super::ppi::resolution(&bare), None);
let mut s = Session::new();
s.execute("document.open", &json!({"name": "resolved.jxl", "dataBase64": b64(&f)})).unwrap();
let rect = s.doc().unwrap().doc.artboards[0].rect;
assert_eq!((rect.width(), rect.height()), (1.5, 2.0));
s.execute("file.new", &json!({"width": 100, "height": 100})).unwrap();
let r = s.execute("file.place", &json!({"name": "resolved.jxl", "dataBase64": b64(&f)})).unwrap();
assert_eq!((r["width"].as_f64(), r["height"].as_f64()), (Some(1.5), Some(2.0)));
assert_eq!(super::ppi::resolution(&s.doc().unwrap().doc.images.values().next().unwrap().bytes), Some((144.0, 72.0)));
}
/// A `.jxl` file copied in a file manager pastes as its image.
#[test]
fn a_copied_jxl_file_pastes_as_its_image() {
+1
View File
@@ -5941,6 +5941,7 @@ breakText Glyphs Glifs
@msg `kind` must be "line" or "paragraph", not {other} `kind` ha de ser "line" o "paragraph", no {other}
@msg `align` must be "left", "center" or "right", not {other} `align` ha de ser "left", "center" o "right", no {other}
@msg the JPEG XL file is cut short el fitxer JPEG XL està truncat
@msg the JPEG XL container is too large to read el contenidor JPEG XL és massa gran per llegir-lo
@msg CMYK JPEG XL images can't be read les imatges JPEG XL en CMYK no es poden llegir
@msg the JPEG XL file can't be read: {e} no es pot llegir el fitxer JPEG XL: {e}
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4888,6 +4888,7 @@ imageTrace Outline Obrys
@msg the PSD file's header is damaged hlavička souboru PSD je poškozená
@msg the PSD file's image data can't be read: {e} obrazová data souboru PSD nelze přečíst: {e}
@msg the JPEG XL file is cut short soubor JPEG XL je useknutý
@msg the JPEG XL container is too large to read kontejner JPEG XL je příliš velký pro načtení
@msg CMYK JPEG XL images can't be read obrázky JPEG XL v režimu CMYK nelze přečíst
@msg the JPEG XL file can't be read: {e} soubor JPEG XL nelze přečíst: {e}
@msg Imported library {name} Importována knihovna {name}
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4625,6 +4625,7 @@ theme Appearance Erscheinungsbild
@msg zipped 32-bit PSD image data with prediction can't be read ZIP-komprimierte 32-Bit-PSD-Bilddaten mit Vorhersage können nicht gelesen werden
@msg {depth}-bit PSD files in this colour mode can't be read {depth}-Bit-PSD-Dateien in diesem Farbmodus können nicht gelesen werden
@msg the JPEG XL file is cut short die JPEG-XL-Datei ist unvollständig
@msg the JPEG XL container is too large to read der JPEG-XL-Container ist zu groß zum Lesen
@msg CMYK JPEG XL images can't be read JPEG-XL-Bilder im CMYK-Modus können nicht gelesen werden
@msg the JPEG XL file can't be read: {e} die JPEG-XL-Datei kann nicht gelesen werden: {e}
Value Axis Werteachse
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4569,6 +4569,7 @@ theme Appearance Εμφάνιση
@msg the PSD file's header is damaged η κεφαλίδα του αρχείου PSD είναι κατεστραμμένη
@msg the PSD file's image data can't be read: {e} τα δεδομένα εικόνας PSD δεν μπορούν να διαβαστούν: {e}
@msg the JPEG XL file is cut short το αρχείο JPEG XL είναι περικομμένο
@msg the JPEG XL container is too large to read το κοντέινερ JPEG XL είναι πολύ μεγάλο για ανάγνωση
@msg CMYK JPEG XL images can't be read οι εικόνες JPEG XL σε CMYK δεν διαβάζονται
@msg the JPEG XL file can't be read: {e} το αρχείο JPEG XL δεν μπορεί να διαβαστεί: {e}
Create New Fields by Δημιουργία νέων πεδίων κατά
Can't render this file because it contains an unexpected character in line 164 and column 5.
+1
View File
@@ -4609,6 +4609,7 @@ axis Both Ambos
@msg the PSD file's header is damaged el encabezado del archivo PSD está dañado
@msg the PSD file's image data can't be read: {e} no se pueden leer los datos de imagen del archivo PSD: {e}
@msg the JPEG XL file is cut short el archivo JPEG XL está incompleto
@msg the JPEG XL container is too large to read el contenedor JPEG XL es demasiado grande para leerlo
@msg CMYK JPEG XL images can't be read las imágenes JPEG XL en CMYK no se pueden leer
@msg the JPEG XL file can't be read: {e} no se puede leer el archivo JPEG XL: {e}
Video Video
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4791,6 +4791,7 @@ imageTrace Outline Ääriviiva
@msg the PSD file's header is damaged tämän PSD-tiedoston otsake on vaurioitunut
@msg the PSD file's image data can't be read: {e} tämän PSD-tiedoston kuvadataa ei voi lukea: {e}
@msg the JPEG XL file is cut short tämä JPEG XL -tiedosto on katkennut
@msg the JPEG XL container is too large to read JPEG XL -säiliö on liian suuri luettavaksi
@msg CMYK JPEG XL images can't be read CMYK-tilassa olevia JPEG XL -kuvia ei voi lukea
@msg the JPEG XL file can't be read: {e} tätä JPEG XL -tiedostoa ei voi lukea: {e}
@msg Imported library {name} Tuotiin kirjasto {name}
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4620,6 +4620,7 @@ axis Both Les deux
@msg the PSD file's header is damaged l'en-tête du fichier PSD est endommagé
@msg the PSD file's image data can't be read: {e} les données d'image du fichier PSD ne peuvent pas être lues : {e}
@msg the JPEG XL file is cut short le fichier JPEG XL est tronqué
@msg the JPEG XL container is too large to read le conteneur JPEG XL est trop volumineux pour être lu
@msg CMYK JPEG XL images can't be read les images JPEG XL en CMJN ne peuvent pas être lues
@msg the JPEG XL file can't be read: {e} le fichier JPEG XL ne peut pas être lu : {e}
Video Vidéo
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -5122,6 +5122,7 @@ imageTrace Outline Körvonal
@msg the PSD file's header is damaged a PSD-fájl fejléce sérült
@msg the PSD file's image data can't be read: {e} a PSD-fájl képadatai nem olvashatók: {e}
@msg the JPEG XL file is cut short a JPEG XL-fájl csonka
@msg the JPEG XL container is too large to read a JPEG XL-konténer túl nagy az olvasáshoz
@msg CMYK JPEG XL images can't be read CMYK módú JPEG XL-képek nem olvashatók
@msg the JPEG XL file can't be read: {e} a JPEG XL-fájl nem olvasható: {e}
@msg the PSD file's image data uses an unknown compression ({m}) a PSD-fájl képadatai ismeretlen tömörítést használnak ({m})
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4649,6 +4649,7 @@ axis Both Entrambi
@msg the PSD file's header is damaged l'intestazione del file PSD è danneggiata
@msg the PSD file's image data can't be read: {e} i dati immagine del file PSD non possono essere letti: {e}
@msg the JPEG XL file is cut short il file JPEG XL è troncato
@msg the JPEG XL container is too large to read il contenitore JPEG XL è troppo grande per essere letto
@msg CMYK JPEG XL images can't be read le immagini JPEG XL in CMYK non possono essere lette
@msg the JPEG XL file can't be read: {e} il file JPEG XL non può essere letto: {e}
Video Video
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4694,6 +4694,7 @@ swatch Bright Violet ビビッドバイオレット
@msg the PSD file's header is damaged PSD ファイルのヘッダーが破損しています
@msg the PSD file's image data can't be read: {e} PSD ファイルの画像データを読み込めません:{e}
@msg the JPEG XL file is cut short JPEG XL ファイルが途中で切れています
@msg the JPEG XL container is too large to read JPEG XL コンテナが大きすぎて読み込めません
@msg CMYK JPEG XL images can't be read CMYK の JPEG XL 画像は読み込めません
@msg the JPEG XL file can't be read: {e} JPEG XL ファイルを読み込めません:{e}
Video ビデオ
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4328,6 +4328,7 @@ font-technology Variable ცვლადი
@msg the PSD file's header is damaged PSD ფაილის სათაური დაზიანებულია
@msg the PSD file's image data can't be read: {e} PSD ფაილის გამოსახულების მონაცემების წაკითხვა ვერ ხერხდება: {e}
@msg the JPEG XL file is cut short JPEG XL ფაილი შეკვეცილია
@msg the JPEG XL container is too large to read JPEG XL კონტეინერი წასაკითხად ზედმეტად დიდია
@msg CMYK JPEG XL images can't be read CMYK JPEG XL გამოსახულებების წაკითხვა ვერ ხერხდება
@msg the JPEG XL file can't be read: {e} JPEG XL ფაილის წაკითხვა ვერ ხერხდება: {e}
@msg Imported library {name} შემოტანილია ბიბლიოთეკა {name}
Can't render this file because it is too large.
+1
View File
@@ -4619,6 +4619,7 @@ theme Appearance 외관
@msg the PSD file's header is damaged PSD 파일의 헤더가 손상되었습니다
@msg the PSD file's image data can't be read: {e} PSD 파일의 이미지 데이터를 읽을 수 없습니다: {e}
@msg the JPEG XL file is cut short JPEG XL 파일이 잘려 있습니다
@msg the JPEG XL container is too large to read JPEG XL 컨테이너가 너무 커서 읽을 수 없습니다
@msg CMYK JPEG XL images can't be read CMYK JPEG XL 이미지는 읽을 수 없습니다
@msg the JPEG XL file can't be read: {e} JPEG XL 파일을 읽을 수 없습니다: {e}
Video 비디오
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4715,6 +4715,7 @@ imageTrace Outline Kontur
@msg the PSD file's header is damaged nagłówek pliku PSD jest uszkodzony
@msg the PSD file's image data can't be read: {e} nie można odczytać danych obrazu pliku PSD: {e}
@msg the JPEG XL file is cut short plik JPEG XL jest ucięty
@msg the JPEG XL container is too large to read kontener JPEG XL jest zbyt duży, aby go odczytać
@msg CMYK JPEG XL images can't be read nie można odczytać obrazów JPEG XL w trybie CMYK
@msg the JPEG XL file can't be read: {e} nie można odczytać pliku JPEG XL: {e}
@msg Imported library {name} Zaimportowano bibliotekę {name}
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4152,6 +4152,7 @@ axis Both Ambos
@msg the PSD file's header is damaged o cabeçalho do arquivo PSD está danificado
@msg the PSD file's image data can't be read: {e} os dados de imagem do arquivo PSD não podem ser lidos: {e}
@msg the JPEG XL file is cut short o arquivo JPEG XL está incompleto
@msg the JPEG XL container is too large to read o contêiner JPEG XL é grande demais para ser lido
@msg CMYK JPEG XL images can't be read imagens JPEG XL em CMYK não podem ser lidas
@msg the JPEG XL file can't be read: {e} o arquivo JPEG XL não pode ser lido: {e}
@msg Imported library {name} Biblioteca {name} importada
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1
View File
@@ -4647,6 +4647,7 @@ axis Both Оба
@msg the PSD file's header is damaged заголовок файла PSD повреждён
@msg the PSD file's image data can't be read: {e} не удаётся прочитать данные изображения файла PSD: {e}
@msg the JPEG XL file is cut short файл JPEG XL обрезан
@msg the JPEG XL container is too large to read контейнер JPEG XL слишком велик для чтения
@msg CMYK JPEG XL images can't be read изображения JPEG XL в режиме CMYK не читаются
@msg the JPEG XL file can't be read: {e} не удаётся прочитать файл JPEG XL: {e}
Video Видео
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4526,6 +4526,7 @@ axis Both Båda
@msg the PSD file's header is damaged PSD-filens huvud är skadat
@msg the PSD file's image data can't be read: {e} PSD-filens bilddata kan inte läsas: {e}
@msg the JPEG XL file is cut short JPEG XL-filen är avkortad
@msg the JPEG XL container is too large to read JPEG XL-behållaren är för stor för att läsas
@msg CMYK JPEG XL images can't be read JPEG XL-bilder i CMYK kan inte läsas
@msg the JPEG XL file can't be read: {e} JPEG XL-filen kan inte läsas: {e}
Video Video
Can't render this file because it contains an unexpected character in line 5 and column 25.
+1
View File
@@ -4369,6 +4369,7 @@ axis Both Her İkisi
@msg the PSD file's header is damaged PSD dosyasının başlığı hasarlı
@msg the PSD file's image data can't be read: {e} PSD dosyasının görüntü verileri okunamıyor: {e}
@msg the JPEG XL file is cut short JPEG XL dosyası kısa kesildi
@msg the JPEG XL container is too large to read JPEG XL kapsayıcısı okunamayacak kadar büyük
@msg CMYK JPEG XL images can't be read CMYK JPEG XL görüntüleri okunamıyor
@msg the JPEG XL file can't be read: {e} JPEG XL dosyası okunamıyor: {e}
Video video
Can't render this file because it contains an unexpected character in line 5 and column 25.
+1
View File
@@ -4633,6 +4633,7 @@ axis Both Обидві
@msg the PSD file's header is damaged заголовок файлу PSD пошкоджено
@msg the PSD file's image data can't be read: {e} не вдається прочитати дані зображення файлу PSD: {e}
@msg the JPEG XL file is cut short файл JPEG XL обрізаний
@msg the JPEG XL container is too large to read контейнер JPEG XL завеликий для читання
@msg CMYK JPEG XL images can't be read зображення JPEG XL у режимі CMYK не читаються
@msg the JPEG XL file can't be read: {e} не вдається прочитати файл JPEG XL: {e}
Video Відео
Can't render this file because it contains an unexpected character in line 178 and column 5.
+1
View File
@@ -4779,6 +4779,7 @@ theme Appearance Giao diện
@msg the PSD file's header is damaged tiêu đề tệp PSD bị hỏng
@msg the PSD file's image data can't be read: {e} dữ liệu ảnh tệp PSD không thể đọc được: {e}
@msg the JPEG XL file is cut short tệp JPEG XL bị cắt ngắn
@msg the JPEG XL container is too large to read vùng chứa JPEG XL quá lớn để đọc
@msg CMYK JPEG XL images can't be read ảnh JPEG XL hệ màu CMYK không thể đọc được
@msg the JPEG XL file can't be read: {e} tệp JPEG XL không thể đọc được: {e}
@msg the PSD file's image data uses an unknown compression ({m}) dữ liệu ảnh tệp PSD dùng nén không xác định ({m})
Can't render this file because it contains an unexpected character in line 200 and column 5.
+1
View File
@@ -5180,6 +5180,7 @@ lighting Light 光源
Load EPS into Clipboard 将 EPS 载入剪贴板
@msg an image of {w} × {h} pixels is too large to draw {w} × {h} 像素的图像过大,无法绘制
@msg the JPEG XL file is cut short JPEG XL 文件不完整
@msg the JPEG XL container is too large to read JPEG XL 容器过大,无法读取
@msg CMYK JPEG XL images can't be read 无法读取 CMYK 模式的 JPEG XL 图像
@msg the JPEG XL file can't be read: {e} 无法读取 JPEG XL 文件:{e}
@msg an image of {w} × {h} pixels is shown at reduced size {w} × {h} 像素的图像以缩小的尺寸显示
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2341,6 +2341,7 @@ file-filter Templates 範本
@msg the PSD file's header is damaged PSD 檔頭已損毀
@msg the PSD file's image data can't be read: {e} 無法讀取 PSD 檔案的影像資料:{e}
@msg the JPEG XL file is cut short JPEG XL 檔案不完整
@msg the JPEG XL container is too large to read JPEG XL 容器過大,無法讀取
@msg CMYK JPEG XL images can't be read 無法讀取 CMYK 模式的 JPEG XL 影像
@msg the JPEG XL file can't be read: {e} 無法讀取 JPEG XL 檔案:{e}
@msg Imported library {name} 已匯入資料庫 {name}
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1 -1
View File
@@ -105,7 +105,7 @@ the app's own editing copy of a file (an EPS after its `%%EOF`, a `.ai`'s `AIPri
| PSB | open | yes (merged image) | no | |
| PNG / JPEG / GIF / BMP / TIFF / Targa | open, place, export | yes (Targa: `.tga`, `.vda`, `.icb` and `.vst`, raw or run-length encoded, with a 16-bit file's one-bit alpha) | yes; TIFF is also selectable in Export for Screens and Asset Export with its existing options | Targa: `tests_tiffbmp.rs`, `tests/links.rs`; TIFF: grayscale with an alpha channel or other extra channels reads (#1466 in part), and so do files that store each channel as its own plane (PlanarConfiguration 2), CMYK ones with their ink amounts, and 1-bit files compressed with CCITT Group 3 (Compression 2 and 3, one- and two-dimensional rows); the ICC profiles embedded in JPEG and TIFF have 4-byte aligned tags (#1584); PNG export marks its colours as sRGB (`embedIcc`, an `sRGB` chunk; no ICC profile is embedded, #2221) |
| WebP | export (Export for Screens) | yes | yes (lossless only; lossy written lossless with a warning) | |
| JPEG XL `.jxl` | — | yes (first frame; 16-bit and floating-point samples as 8 bits, alpha kept; CMYK refused) | no | decoded with jxl-oxide; the size is checked from the header before decoding; tests in `crates/engine/src/cmd/fileio/tests_jxlread.rs` and `crates/engine/tests/import_fuzz.rs` |
| JPEG XL `.jxl` | — | yes (first frame; 16-bit and floating-point samples as 8 bits, alpha kept; CMYK refused) | no | decoded with jxl-oxide; the size is checked from the header before decoding; container Exif resolution sizes opened and placed images; tests in `crates/engine/src/cmd/fileio/tests_jxlread.rs` and `crates/engine/tests/import_fuzz.rs` |
| HEIC / HEIF | open, place | no | no | |
| JPEG 2000 | open, place | no | no | |
| PCX | open, place | yes (1 bit in the header palette's first two colors, black and white without them; 1 bit in two to four planes and 4 bits with up to 16 colors; 2 bits in the CGA colors the header's CGA palette settings pick; 8 bits with the 256-color palette, gray without one; 24-bit color in three planes) | no | the header's HDpi and VDpi size the image; a file of another depth or plane count, cut short or past the pixel allowance is refused with a message; tests in `crates/engine/src/cmd/fileio/tests_pcxread.rs` and `crates/engine/tests/import_fuzz.rs` |