use bytemuck::{cast_slice, cast_slice_mut};
use crate::cms::Profile;
use crate::convert::ToSRGBImage;
use crate::exif::parse_exif;
use crate::format::Format;
use crate::image::{Image, ImageMeta, Rotate};
use crate::loader::Loader;
use crate::pixel_format::CMYK;
use jpeg_decoder::{CodingProcess, PixelFormat};
use rgb::{FromSlice, bytemuck};
use std::fs;
impl Loader {
pub(crate) fn load_jpeg(&self, data: &[u8], fs_meta: Option<fs::Metadata>) -> Result<Image, crate::Error> {
let mut dec = jpeg_decoder::Decoder::new(data);
dec.read_info()?;
let info = dec.info().ok_or(crate::Error::UnsupportedJpeg)?;
if info.coding_process == CodingProcess::Lossless {
return Err(crate::Error::UnsupportedJpeg);
}
let width = info.width.into();
let height = info.height.into();
self.check_dimensions(width, height)?;
let mut pixels = dec.decode()?;
let exif = dec.exif_data();
let (orientation, is_adobe_1998) = exif.map_or((1, false), parse_exif);
let profile = dec.icc_profile().as_deref()
.or(if is_adobe_1998 { Some(crate::profiles::ADOBE1998) } else { None })
.and_then(|icc| self.process_profile(Profile::new_icc(icc)));
let meta = ImageMeta::new(Format::Jpeg, vec![], fs_meta);
let img = match info.pixel_format {
PixelFormat::L8 => cast_slice_mut::<_, rgb::Gray<u8>>(&mut pixels).to_image(profile, width, height, true, meta),
PixelFormat::L16 => return Err(crate::Error::UnsupportedJpeg),
PixelFormat::RGB24 => pixels.as_rgb_mut().to_image(profile, width, height, true, meta),
PixelFormat::CMYK32 => cast_slice::<u8, CMYK>(&pixels).to_image(profile, width, height, true, meta),
};
Ok(img.rotated(Rotate::from_exif_orientation(orientation)))
}
}