Skip to content

Commit

Permalink
fix(codecs): updated mozjpeg encoder to new api
Browse files Browse the repository at this point in the history
  • Loading branch information
SalOne22 committed Apr 11, 2024
1 parent d07193d commit b408b31
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 14 deletions.
54 changes: 47 additions & 7 deletions src/codecs/mozjpeg/encoder/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::mem;
use std::{io, mem, panic::AssertUnwindSafe};

use mozjpeg::qtable::QTable;
use zune_core::{bit_depth::BitDepth, colorspace::ColorSpace};
use zune_core::{bit_depth::BitDepth, bytestream::ZByteWriterTrait, colorspace::ColorSpace};
use zune_image::{codecs::ImageFormat, errors::ImageErrors, image::Image, traits::EncoderTrait};

/// Advanced options for MozJpeg encoding
Expand Down Expand Up @@ -32,6 +32,37 @@ pub struct MozJpegEncoder {
options: MozJpegOptions,
}

struct TempVt<T: ZByteWriterTrait> {
inner: T,
bytes_written: usize,
}
impl<T: ZByteWriterTrait> io::Write for TempVt<T> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let bytes_written = self.inner.write_bytes(buf).map_err(|e| match e {
zune_core::bytestream::ZByteIoError::StdIoError(e) => e,
e => io::Error::other(format!("{e:?}")),
})?;
self.bytes_written += bytes_written;
Ok(bytes_written)
}

fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.inner.write_all_bytes(buf).map_err(|e| match e {
zune_core::bytestream::ZByteIoError::StdIoError(e) => e,
e => io::Error::other(format!("{e:?}")),
})?;
self.bytes_written += buf.len();
Ok(())
}

fn flush(&mut self) -> io::Result<()> {
self.inner.flush_bytes().map_err(|e| match e {
zune_core::bytestream::ZByteIoError::StdIoError(e) => e,
e => io::Error::other(format!("{e:?}")),
})
}
}

impl Default for MozJpegOptions {
fn default() -> Self {
Self {
Expand Down Expand Up @@ -65,14 +96,18 @@ impl EncoderTrait for MozJpegEncoder {
"mozjpeg-encoder"
}

fn encode_inner(&mut self, image: &Image) -> Result<Vec<u8>, ImageErrors> {
fn encode_inner<T: ZByteWriterTrait>(
&mut self,
image: &Image,
sink: T,
) -> Result<usize, ImageErrors> {
let (width, height) = image.dimensions();
let data = &image.flatten_to_u8()[0];

let luma_qtable = self.options.luma_qtable.as_ref();
let chroma_qtable = self.options.chroma_qtable.as_ref();

std::panic::catch_unwind(|| -> Result<Vec<u8>, ImageErrors> {
std::panic::catch_unwind(AssertUnwindSafe(|| -> Result<usize, ImageErrors> {
let format = match image.colorspace() {
ColorSpace::RGB => mozjpeg::ColorSpace::JCS_RGB,
ColorSpace::RGBA => mozjpeg::ColorSpace::JCS_EXT_RGBA,
Expand Down Expand Up @@ -131,7 +166,12 @@ impl EncoderTrait for MozJpegEncoder {
comp.set_chroma_qtable(qtable)
}

let mut comp = comp.start_compress(Vec::new())?;
let writer = TempVt {
inner: sink,
bytes_written: 0,
};

let mut comp = comp.start_compress(writer)?;

#[cfg(feature = "metadata")]
{
Expand Down Expand Up @@ -159,8 +199,8 @@ impl EncoderTrait for MozJpegEncoder {

comp.write_scanlines(data)?;

Ok(comp.finish()?)
})
Ok(comp.finish()?.bytes_written)
}))
.map_err(|err| {
if let Ok(mut err) = err.downcast::<String>() {
ImageErrors::EncodeErrors(zune_image::errors::ImgEncodeErrors::Generic(mem::take(
Expand Down
30 changes: 23 additions & 7 deletions src/codecs/mozjpeg/encoder/tests.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::io::Cursor;

use zune_core::colorspace::ColorSpace;

use crate::test_utils::*;
Expand All @@ -19,7 +21,9 @@ fn encode_colorspaces_u8() {

let mut encoder = MozJpegEncoder::new();

let result = encoder.encode(&image);
let buf = Cursor::new(vec![]);

let result = encoder.encode(&image, buf);

if result.is_err() {
dbg!(&result);
Expand Down Expand Up @@ -50,7 +54,9 @@ fn encode_colorspaces_u16() {

let mut encoder = MozJpegEncoder::new();

let result = encoder.encode(&image);
let buf = Cursor::new(vec![]);

let result = encoder.encode(&image, buf);

if result.is_err() {
dbg!(&result);
Expand Down Expand Up @@ -81,7 +87,9 @@ fn encode_colorspaces_f32() {

let mut encoder = MozJpegEncoder::new();

let result = encoder.encode(&image);
let buf = Cursor::new(vec![]);

let result = encoder.encode(&image, buf);

if result.is_err() {
dbg!(&result);
Expand All @@ -102,7 +110,9 @@ fn encode_u8() {
let image = create_test_image_u8(200, 200, ColorSpace::RGB);
let mut encoder = MozJpegEncoder::new();

let result = encoder.encode(&image);
let buf = Cursor::new(vec![]);

let result = encoder.encode(&image, buf);
dbg!(&result);

assert!(result.is_ok());
Expand All @@ -113,7 +123,9 @@ fn encode_u16() {
let image = create_test_image_u16(200, 200, ColorSpace::RGB);
let mut encoder = MozJpegEncoder::new();

let result = encoder.encode(&image);
let buf = Cursor::new(vec![]);

let result = encoder.encode(&image, buf);
dbg!(&result);

assert!(result.is_ok());
Expand All @@ -124,7 +136,9 @@ fn encode_f32() {
let image = create_test_image_f32(200, 200, ColorSpace::RGB);
let mut encoder = MozJpegEncoder::new();

let result = encoder.encode(&image);
let buf = Cursor::new(vec![]);

let result = encoder.encode(&image, buf);
dbg!(&result);

assert!(result.is_ok());
Expand All @@ -135,7 +149,9 @@ fn encode_animated() {
let image = create_test_image_animated(200, 200, ColorSpace::RGB);
let mut encoder = MozJpegEncoder::new();

let result = encoder.encode(&image);
let buf = Cursor::new(vec![]);

let result = encoder.encode(&image, buf);
dbg!(&result);

assert!(result.is_ok());
Expand Down

0 comments on commit b408b31

Please sign in to comment.