Skip to main content

icns/
jp2io.rs

1use super::image::{Image, PixelFormat};
2use hayro_jpeg2000::{self, ColorSpace};
3use std::io;
4
5impl Image {
6    /// Reads an image from a Jpeg 2000 file.
7    pub fn read_jp2(input: &[u8]) -> io::Result<Image> {
8        let image = match hayro_jpeg2000::Image::new(
9            input,
10            &hayro_jpeg2000::DecodeSettings {
11                resolve_palette_indices: true,
12                strict: false,
13                target_resolution: None,
14            },
15        ) {
16            Err(y) => {
17                return Err(io::Error::new(io::ErrorKind::InvalidData, y));
18            }
19            Ok(x) => x,
20        };
21
22        match image.color_space() {
23            ColorSpace::Gray => {
24                let img_data = image.decode().map_err(|e| {
25                    io::Error::new(io::ErrorKind::InvalidData, e)
26                })?;
27                let mut out = Image::new(
28                    if image.has_alpha() {
29                        PixelFormat::GrayAlpha
30                    } else {
31                        PixelFormat::Gray
32                    },
33                    image.width(),
34                    image.height(),
35                );
36                assert_eq!(img_data.len(), out.data.len());
37                out.data_mut().copy_from_slice(&img_data);
38                Ok(out)
39            }
40            ColorSpace::RGB => {
41                let img_data = image.decode().map_err(|e| {
42                    io::Error::new(io::ErrorKind::InvalidData, e)
43                })?;
44                let mut out = Image::new(
45                    if image.has_alpha() {
46                        PixelFormat::RGBA
47                    } else {
48                        PixelFormat::RGB
49                    },
50                    image.width(),
51                    image.height(),
52                );
53                assert_eq!(img_data.len(), out.data.len());
54                out.data_mut().copy_from_slice(&img_data);
55                Ok(out)
56            }
57            ColorSpace::CMYK => Err(io::Error::new(
58                io::ErrorKind::InvalidData,
59                "jpeg2000 images with CMYK color space not supported"
60                    .to_string(),
61            )),
62            ColorSpace::Unknown { num_channels } => Err(io::Error::new(
63                io::ErrorKind::InvalidData,
64                format!(
65                    "jpeg2000 images with Unknown ({num_channels}\
66                    -channel) color space not supported"
67                ),
68            )),
69            ColorSpace::Icc { .. } => Err(io::Error::new(
70                io::ErrorKind::InvalidData,
71                "jpeg2000 images with ICC profile not supported".to_string(),
72            )),
73        }
74    }
75}