Skip to content

Commit

Permalink
crates: Update jxl dependency.
Browse files Browse the repository at this point in the history
  • Loading branch information
etemesi254 committed Mar 30, 2024
1 parent 270fa8e commit 23c8bb1
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 112 deletions.
41 changes: 17 additions & 24 deletions crates/zune-capi/src/imread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use zune_image::codecs::bmp::BmpDecoder;
use zune_image::codecs::farbfeld::FarbFeldDecoder;
use zune_image::codecs::hdr::HdrDecoder;
use zune_image::codecs::jpeg::JpegDecoder;
use zune_image::codecs::jpeg_xl::jxl_oxide::RenderResult;
use zune_image::codecs::png::PngDecoder;
use zune_image::codecs::ppm::PPMDecoder;
use zune_image::codecs::psd::PSDDecoder;
Expand Down Expand Up @@ -498,36 +497,30 @@ where
decoder.decode_into(output)?;
}
ImageFormat::JPEG_XL => {
let mut decoder = zune_image::codecs::jpeg_xl::jxl_oxide::JxlImage::from_reader(
ZReader::new(data)
)
.map_err(|x| ImageErrors::GenericString(x.to_string()))?;
let decoder = zune_image::codecs::jpeg_xl::jxl_oxide::JxlImage::builder()
.read(ZReader::new(data))
.map_err(|x| ImageErrors::GenericString(x.to_string()))?;

let result = decoder
.render_next_frame()
let render = decoder
.render_frame(0)
.map_err(|x| ImageErrors::GenericString(x.to_string()))?;

match result {
RenderResult::Done(render) => {
let (a, f32_buf, c) = unsafe { output.align_to_mut() };
let (a, f32_buf, c) = unsafe { output.align_to_mut() };

if !(a.is_empty() && c.is_empty()) {
// misalignment
return Err(ImageErrors::GenericStr("Buffer misalignment"));
}
if !(a.is_empty() && c.is_empty()) {
// misalignment
return Err(ImageErrors::GenericStr("Buffer misalignment"));
}

let im_plannar = render.image();
let buf_len = im_plannar.buf().len();
let im_plannar = render.image();
let buf_len = im_plannar.buf().len();

if buf_len > f32_buf.len() {
return Err(ImageErrors::GenericStr(
"Too small of a buffer for jxl output"
));
}
f32_buf[..buf_len].copy_from_slice(im_plannar.buf())
}
_ => return Err(ImageErrors::GenericStr("Cannot handle jxl status"))
if buf_len > f32_buf.len() {
return Err(ImageErrors::GenericStr(
"Too small of a buffer for jxl output"
));
}
f32_buf[..buf_len].copy_from_slice(im_plannar.buf())
}
ImageFormat::HDR => {
let mut decoder = HdrDecoder::new(data);
Expand Down
24 changes: 12 additions & 12 deletions crates/zune-image/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"
authors = ["caleb <[email protected]>"]
repository = "https://github.com/etemesi254/zune-image/tree/dev/crates/zune-image"
license = "MIT OR Apache-2.0 OR Zlib"
keywords = ["image", "decoder", "encoder","image-processing"]
keywords = ["image", "decoder", "encoder", "image-processing"]
categories = ["multimedia::images"]
description = "An image library, contiaining necessary capabilities to decode, manipulate and encode images"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down Expand Up @@ -41,22 +41,22 @@ all = ["image_formats", "serde-support", "metadata", "threads", "simd", "log"]
# Core primitives
zune-core = { path = "../zune-core", version = "^0.4.12" }
# Images
zune-png = { path = "../zune-png",version = "0.4", optional = true }
zune-jpeg = { path = "../zune-jpeg",version = "0.4", optional = true }
zune-ppm = { path = "../zune-ppm",version = "0.4", optional = true }
zune-psd = { path = "../zune-psd",version = "0.4", optional = true }
zune-farbfeld = { path = "../zune-farbfeld",version = "0.4", optional = true }
zune-qoi = { path = "../zune-qoi",version = "0.4", optional = true }
zune-jpegxl = { path = "../zune-jpegxl",version = "0.4", optional = true }
zune-hdr = { path = "../zune-hdr",version = "0.4", optional = true }
zune-bmp = { path = "../zune-bmp",version = "0.4", optional = true }
zune-png = { path = "../zune-png", version = "0.4", optional = true }
zune-jpeg = { path = "../zune-jpeg", version = "0.4", optional = true }
zune-ppm = { path = "../zune-ppm", version = "0.4", optional = true }
zune-psd = { path = "../zune-psd", version = "0.4", optional = true }
zune-farbfeld = { path = "../zune-farbfeld", version = "0.4", optional = true }
zune-qoi = { path = "../zune-qoi", version = "0.4", optional = true }
zune-jpegxl = { path = "../zune-jpegxl", version = "0.4", optional = true }
zune-hdr = { path = "../zune-hdr", version = "0.4", optional = true }
zune-bmp = { path = "../zune-bmp", version = "0.4", optional = true }
# Channel conversions in a safe way
bytemuck = { version = "1.13", default-features = false }
# Serializing info
serde = { version = "1.0.152", optional = true }
# External image APIs
jpeg-encoder = { version = "0.5.1", optional = true, features = ["simd", "std"] }
jxl-oxide = { version = "0.4.0", optional = true }
jpeg-encoder = { version = "0.6.0", optional = true, features = ["simd", "std"] }
jxl-oxide = { version = "0.8.0", optional = true }
# metadata
kamadak-exif = { version = "0.5.5", optional = true }

Expand Down
87 changes: 39 additions & 48 deletions crates/zune-image/src/codecs/jpeg_xl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use std::thread::sleep;
use std::time::Duration;

pub use jxl_oxide;
use jxl_oxide::{PixelFormat, RenderResult};
use jxl_oxide::{JxlImage, PixelFormat, RenderResult};
use zune_core::bit_depth::{BitDepth, BitType};
use zune_core::bytestream::ZByteWriterTrait;
use zune_core::colorspace::ColorSpace;
Expand Down Expand Up @@ -117,14 +117,15 @@ impl From<JxlEncodeErrors> for ImgEncodeErrors {
}
}

pub struct JxlDecoder<R: Read> {
inner: jxl_oxide::JxlImage<R>,
pub struct JxlDecoder {
inner: jxl_oxide::JxlImage,
options: DecoderOptions
}

impl<R: Read> JxlDecoder<R> {
pub fn try_new(source: R, options: DecoderOptions) -> Result<JxlDecoder<R>, ImageErrors> {
let parser = jxl_oxide::JxlImage::from_reader(source)
impl JxlDecoder {
pub fn try_new<R: Read>(source: R, options: DecoderOptions) -> Result<JxlDecoder, ImageErrors> {
let parser = jxl_oxide::JxlImage::builder()
.read(source)
.map_err(|x| ImageErrors::ImageDecodeErrors(format!("{:?}", x)))?;

let decoder = JxlDecoder {
Expand All @@ -135,15 +136,12 @@ impl<R: Read> JxlDecoder<R> {
}
}

impl<R> DecoderTrait for JxlDecoder<R>
where
R: Read
{
impl DecoderTrait for JxlDecoder {
fn decode(&mut self) -> Result<Image, ImageErrors> {
// by now headers have been decoded, so we can fetch these
let metadata = self.read_headers()?;
let (w, h) = <JxlDecoder<R> as DecoderTrait>::dimensions(self).unwrap();
let color = <JxlDecoder<R> as DecoderTrait>::out_colorspace(self);
let (w, h) = <JxlDecoder as DecoderTrait>::dimensions(self).unwrap();
let color = <JxlDecoder as DecoderTrait>::out_colorspace(self);

let mut total_frames = vec![];

Expand Down Expand Up @@ -173,44 +171,37 @@ where
return Err(ImageErrors::ImageDecodeErrors(msg));
}

loop {
let result = self
let taken = if self.options.jxl_decode_animated() {
self.inner.num_loaded_frames()
} else {
1
};

for frame in 0..taken {
let render = self
.inner
.render_next_frame()
.render_frame(frame)
.map_err(|x| ImageErrors::ImageDecodeErrors(format!("{}", x)))?;

match result {
RenderResult::Done(render) => {
// get the images
let duration = render.duration();

let im_plannar = render.image_planar();
let mut frame_v = vec![];

for channel in im_plannar {
let mut chan = Channel::new_with_bit_type(
channel.width() * channel.height() * size_of::<f32>(),
BitType::F32
);
// copy the channel as plannar
let c = chan.reinterpret_as_mut()?;
c.copy_from_slice(channel.buf());
// then store it in frame_v
frame_v.push(chan);
}
let frame = Frame::new(frame_v);
total_frames.push(frame);
}
RenderResult::NeedMoreData => {
sleep(Duration::new(1, 0));
// return to the loop
}
RenderResult::NoMoreFrames => break
}
if !self.options.jxl_decode_animated() {
// we won't be decoding animated, so don't decode the next frame
break;
// get the images
let duration = render.duration();

let im_plannar = render.image_planar();
let mut frame_v = vec![];

for channel in im_plannar {
let mut chan = Channel::new_with_bit_type(
channel.width() * channel.height() * size_of::<f32>(),
BitType::F32
);
// copy the channel as plannar
let c = chan.reinterpret_as_mut()?;
c.copy_from_slice(channel.buf());
// then store it in frame_v
frame_v.push(chan);
}
let frame = Frame::new(frame_v);
total_frames.push(frame);
}
// then create a new image
let mut image = Image::new_frames(total_frames, BitDepth::Float32, w, h, color);
Expand Down Expand Up @@ -242,8 +233,8 @@ where
}

fn read_headers(&mut self) -> Result<Option<ImageMetadata>, ImageErrors> {
let (w, h) = <JxlDecoder<R> as DecoderTrait>::dimensions(self).unwrap();
let color = <JxlDecoder<R> as DecoderTrait>::out_colorspace(self);
let (w, h) = <JxlDecoder as DecoderTrait>::dimensions(self).unwrap();
let color = <JxlDecoder as DecoderTrait>::out_colorspace(self);

let (width, height) = self.dimensions().unwrap();

Expand Down
50 changes: 22 additions & 28 deletions crates/zune-python/src/py_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use zune_image::codecs::bmp::BmpDecoder;
use zune_image::codecs::farbfeld::FarbFeldDecoder;
use zune_image::codecs::hdr::HdrDecoder;
use zune_image::codecs::jpeg::JpegDecoder;
use zune_image::codecs::jpeg_xl::jxl_oxide::RenderResult;
use zune_image::codecs::png::PngDecoder;
use zune_image::codecs::ppm::PPMDecoder;
use zune_image::codecs::psd::PSDDecoder;
Expand Down Expand Up @@ -339,39 +338,34 @@ pub fn imread(py: Python<'_>, file: String) -> PyResult<&PyUntypedArray> {
ImageFormat::JPEG_XL => {
let c = ZReader::new(ZCursor::new(&bytes));

let mut decoder =
zune_image::codecs::jpeg_xl::jxl_oxide::JxlImage::from_reader(c)
.map_err(|x| PyErr::new::<PyException, _>(format!("{x:?}")))?;
let decoder = zune_image::codecs::jpeg_xl::jxl_oxide::JxlImage::builder()
.read(c)
.map_err(|x| PyErr::new::<PyException, _>(format!("{x:?}")))?;

let (w, h) = (decoder.width() as usize, decoder.height() as usize);
let color = decoder.pixel_format();

let result = decoder
.render_next_frame()
let render = decoder
.render_frame(0)
.map_err(|x| PyErr::new::<PyException, _>(format!("{x}")))?;

match result {
RenderResult::Done(render) => {
// get the images
let im_plannar = render.image();

if color.channels() == 1 {
let arr = PyArray2::zeros(py, [h, w], false);
arr.try_readwrite()?
.as_slice_mut()?
.copy_from_slice(im_plannar.buf());

Ok(arr.as_untyped())
} else {
let arr = PyArray3::zeros(py, [h, w, color.channels()], false);
arr.try_readwrite()?
.as_slice_mut()?
.copy_from_slice(im_plannar.buf());

Ok(arr.as_untyped())
}
}
_ => return Err(PyErr::new::<PyException, _>("Cannot process jxl frame"))
// get the images
let im_plannar = render.image();

if color.channels() == 1 {
let arr = PyArray2::zeros(py, [h, w], false);
arr.try_readwrite()?
.as_slice_mut()?
.copy_from_slice(im_plannar.buf());

Ok(arr.as_untyped())
} else {
let arr = PyArray3::zeros(py, [h, w, color.channels()], false);
arr.try_readwrite()?
.as_slice_mut()?
.copy_from_slice(im_plannar.buf());

Ok(arr.as_untyped())
}
}
d @ ImageFormat::Unknown => Err(PyErr::new::<PyException, _>(format!(
Expand Down

0 comments on commit 23c8bb1

Please sign in to comment.