summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/typst-pdf/src/image.rs52
1 files changed, 17 insertions, 35 deletions
diff --git a/crates/typst-pdf/src/image.rs b/crates/typst-pdf/src/image.rs
index 3857e68f..a4833e6e 100644
--- a/crates/typst-pdf/src/image.rs
+++ b/crates/typst-pdf/src/image.rs
@@ -113,42 +113,24 @@ pub(crate) fn write_images(ctx: &mut PdfContext) {
/// Skips the alpha channel as that's encoded separately.
fn encode_raster_image(image: &RasterImage) -> (Vec<u8>, Filter, bool) {
let dynamic = image.dynamic();
- match (image.format(), dynamic) {
- // 8-bit gray JPEG.
- (RasterFormat::Jpg, DynamicImage::ImageLuma8(_)) => {
- let mut data = Cursor::new(vec![]);
- dynamic.write_to(&mut data, image::ImageFormat::Jpeg).unwrap();
- (data.into_inner(), Filter::DctDecode, false)
- }
-
- // 8-bit RGB JPEG (CMYK JPEGs get converted to RGB earlier).
- (RasterFormat::Jpg, DynamicImage::ImageRgb8(_)) => {
- let mut data = Cursor::new(vec![]);
- dynamic.write_to(&mut data, image::ImageFormat::Jpeg).unwrap();
- (data.into_inner(), Filter::DctDecode, true)
- }
-
+ let channel_count = dynamic.color().channel_count();
+ let has_color = channel_count > 2;
+
+ if image.format() == RasterFormat::Jpg {
+ let mut data = Cursor::new(vec![]);
+ dynamic.write_to(&mut data, image::ImageFormat::Jpeg).unwrap();
+ (data.into_inner(), Filter::DctDecode, has_color)
+ } else {
// TODO: Encode flate streams with PNG-predictor?
-
- // 8-bit gray PNG.
- (RasterFormat::Png, DynamicImage::ImageLuma8(luma)) => {
- let data = deflate(luma.as_raw());
- (data, Filter::FlateDecode, false)
- }
-
- // Anything else (including Rgb(a) PNGs).
- (_, buf) => {
- let (width, height) = buf.dimensions();
- let mut pixels = Vec::with_capacity(3 * width as usize * height as usize);
- for (_, _, Rgba([r, g, b, _])) in buf.pixels() {
- pixels.push(r);
- pixels.push(g);
- pixels.push(b);
- }
-
- let data = deflate(&pixels);
- (data, Filter::FlateDecode, true)
- }
+ let data = match (dynamic, channel_count) {
+ (DynamicImage::ImageLuma8(luma), _) => deflate(luma.as_raw()),
+ (DynamicImage::ImageRgb8(rgb), _) => deflate(rgb.as_raw()),
+ // Grayscale image
+ (_, 1 | 2) => deflate(dynamic.to_luma8().as_raw()),
+ // Anything else
+ _ => deflate(dynamic.to_rgb8().as_raw()),
+ };
+ (data, Filter::FlateDecode, has_color)
}
}