From 17cef8dcee022ca89ccef62eaec23ff6c0e4cdf9 Mon Sep 17 00:00:00 2001 From: Martin Haug Date: Tue, 2 May 2023 13:53:20 +0200 Subject: Add ICC profiles to images in PDF and update `usvg`, `svg2pdf` (#822) --- src/export/pdf/image.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src/export/pdf/image.rs') diff --git a/src/export/pdf/image.rs b/src/export/pdf/image.rs index 04d4dcc3..dcd5a45a 100644 --- a/src/export/pdf/image.rs +++ b/src/export/pdf/image.rs @@ -11,6 +11,7 @@ use crate::image::{DecodedImage, RasterFormat}; pub fn write_images(ctx: &mut PdfContext) { for image in ctx.image_map.items() { let image_ref = ctx.alloc.bump(); + let icc_ref = ctx.alloc.bump(); ctx.image_refs.push(image_ref); let width = image.width(); @@ -19,7 +20,7 @@ pub fn write_images(ctx: &mut PdfContext) { // Add the primary image. // TODO: Error if image could not be encoded. match image.decoded() { - DecodedImage::Raster(dynamic, format) => { + DecodedImage::Raster(dynamic, icc, format) => { // TODO: Error if image could not be encoded. let (data, filter, has_color) = encode_image(*format, dynamic).unwrap(); let mut image = ctx.writer.image_xobject(image_ref, &data); @@ -29,7 +30,9 @@ pub fn write_images(ctx: &mut PdfContext) { image.bits_per_component(8); let space = image.color_space(); - if has_color { + if icc.is_some() { + space.icc_based(icc_ref); + } else if has_color { space.device_rgb(); } else { space.device_gray(); @@ -49,6 +52,21 @@ pub fn write_images(ctx: &mut PdfContext) { mask.height(height as i32); mask.color_space().device_gray(); mask.bits_per_component(8); + } else { + image.finish(); + } + + if let Some(icc) = icc { + let compressed = deflate(&icc.0); + let mut stream = ctx.writer.icc_profile(icc_ref, &compressed); + stream.filter(Filter::FlateDecode); + if has_color { + stream.n(3); + stream.alternate().srgb(); + } else { + stream.n(1); + stream.alternate().d65_gray(); + } } } DecodedImage::Svg(svg) => { -- cgit v1.2.3