1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 use crabby_avif::image::*; 16 use crabby_avif::reformat::rgb; 17 use crabby_avif::AvifError; 18 use crabby_avif::AvifResult; 19 20 use super::Writer; 21 22 use image::codecs::jpeg; 23 use std::fs::File; 24 25 #[derive(Default)] 26 pub(crate) struct JpegWriter { 27 pub quality: Option<u8>, 28 } 29 30 impl Writer for JpegWriter { write_frame(&mut self, file: &mut File, image: &Image) -> AvifResult<()>31 fn write_frame(&mut self, file: &mut File, image: &Image) -> AvifResult<()> { 32 let mut rgb = rgb::Image::create_from_yuv(image); 33 rgb.depth = 8; 34 rgb.format = rgb::Format::Rgb; 35 rgb.allocate()?; 36 rgb.convert_from_yuv(image)?; 37 38 let rgba_pixels = rgb.pixels.as_ref().unwrap(); 39 let mut encoder = jpeg::JpegEncoder::new_with_quality(file, self.quality.unwrap_or(90)); 40 encoder 41 .encode( 42 rgba_pixels.slice(0, rgba_pixels.size() as u32)?, 43 image.width, 44 image.height, 45 image::ColorType::Rgb8, 46 ) 47 .or(Err(AvifError::UnknownError("Jpeg encoding failed".into())))?; 48 Ok(()) 49 } 50 } 51