From 1db84390e3755c4b089f2e2113012200e7941d72 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Tue, 27 Aug 2024 11:07:16 +0200 Subject: [PATCH] Deduplicate image handling code --- src/render/image.rs | 86 ++++++++++++++------------------------------- 1 file changed, 27 insertions(+), 59 deletions(-) diff --git a/src/render/image.rs b/src/render/image.rs index aa2060c1..9a7ee46b 100644 --- a/src/render/image.rs +++ b/src/render/image.rs @@ -26,75 +26,30 @@ pub fn render( return Ok(()); } + let load_with_format = |content, format| { + image::load_from_memory_with_format(content, format).map_err(|_| InvalidImage) + }; + // Will return the name of the image (in the Resources dictionary) and the dimensions of the // actual image (i.e. the actual image size, not the size in the PDF, which will always be 1x1 // because that's how ImageXObjects are scaled by default. let (image_name, image_size) = match kind { ImageKind::JPEG(content) => { - let dynamic_image = - image::load_from_memory_with_format(content, ImageFormat::Jpeg) - .map_err(|_| InvalidImage)?; // JPEGs don't support alphas, so no extra processing is required. - create_raster_image( - chunk, - ctx, - content, - Filter::DctDecode, - &dynamic_image, - None, - rc, - ) + let image = load_with_format(content, ImageFormat::Jpeg)?; + create_raster_image(chunk, ctx, content, Filter::DctDecode, &image, None, rc) } ImageKind::PNG(content) => { - let dynamic_image = - image::load_from_memory_with_format(content, ImageFormat::Png) - .map_err(|_| InvalidImage)?; - // Alpha channels need to be written separately as a soft mask, hence the extra processing - // step. - let (samples, filter, alpha_mask) = handle_transparent_image(&dynamic_image); - create_raster_image( - chunk, - ctx, - &samples, - filter, - &dynamic_image, - alpha_mask.as_deref(), - rc, - ) + let image = load_with_format(content, ImageFormat::Png)?; + create_transparent_image(chunk, ctx, &image, rc) } ImageKind::GIF(content) => { - let dynamic_image = - image::load_from_memory_with_format(content, ImageFormat::Gif) - .map_err(|_| InvalidImage)?; - // Alpha channels need to be written separately as a soft mask, hence the extra processing - // step. - let (samples, filter, alpha_mask) = handle_transparent_image(&dynamic_image); - create_raster_image( - chunk, - ctx, - &samples, - filter, - &dynamic_image, - alpha_mask.as_deref(), - rc, - ) + let image = load_with_format(content, ImageFormat::Gif)?; + create_transparent_image(chunk, ctx, &image, rc) } ImageKind::WEBP(content) => { - let dynamic_image = - image::load_from_memory_with_format(content, ImageFormat::WebP) - .map_err(|_| InvalidImage)?; - // Alpha channels need to be written separately as a soft mask, hence the extra processing - // step. - let (samples, filter, alpha_mask) = handle_transparent_image(&dynamic_image); - create_raster_image( - chunk, - ctx, - &samples, - filter, - &dynamic_image, - alpha_mask.as_deref(), - rc, - ) + let image = load_with_format(content, ImageFormat::WebP)?; + create_transparent_image(chunk, ctx, &image, rc) } // SVGs just get rendered recursively. ImageKind::SVG(tree) => create_svg_image(tree, chunk, ctx, rc)?, @@ -129,7 +84,12 @@ pub fn render( Ok(()) } -fn handle_transparent_image(image: &DynamicImage) -> (Vec, Filter, Option>) { +fn create_transparent_image( + chunk: &mut Chunk, + ctx: &mut Context, + image: &DynamicImage, + rc: &mut ResourceContainer, +) -> (Rc, Size) { let color = image.color(); let bits = color.bits_per_pixel(); let channels = color.channel_count() as u16; @@ -179,7 +139,15 @@ fn handle_transparent_image(image: &DynamicImage) -> (Vec, Filter, Option