Skip to content

Commit

Permalink
Add JXL image support
Browse files Browse the repository at this point in the history
  • Loading branch information
xangelix committed Oct 29, 2024
1 parent 8fb6960 commit 60ee443
Show file tree
Hide file tree
Showing 8 changed files with 318 additions and 17 deletions.
158 changes: 152 additions & 6 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -590,9 +590,9 @@ checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"

[[package]]
name = "bytemuck"
version = "1.14.0"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6"
checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d"
dependencies = [
"bytemuck_derive",
]
Expand Down Expand Up @@ -1352,6 +1352,7 @@ dependencies = [
"ehttp",
"enum-map",
"image",
"jxl-oxide",
"log",
"mime_guess2",
"puffin",
Expand Down Expand Up @@ -2185,9 +2186,9 @@ dependencies = [

[[package]]
name = "image"
version = "0.25.2"
version = "0.25.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99314c8a2152b8ddb211f924cdae532d8c5e4c8bb54728e12fff1b0cd5963a10"
checksum = "bc144d44a31d753b02ce64093d532f55ff8dc4ebf2ffb8a63c0dda691385acae"
dependencies = [
"bytemuck",
"byteorder-lite",
Expand Down Expand Up @@ -2320,6 +2321,151 @@ dependencies = [
"wasm-bindgen",
]

[[package]]
name = "jxl-bitstream"
version = "0.5.0-alpha.0"
source = "git+https://github.com/tirr-c/jxl-oxide.git#229c223af49de96247a4e5548470ce2753912f3e"
dependencies = [
"tracing",
]

[[package]]
name = "jxl-coding"
version = "0.5.0-alpha.0"
source = "git+https://github.com/tirr-c/jxl-oxide.git#229c223af49de96247a4e5548470ce2753912f3e"
dependencies = [
"jxl-bitstream",
"tracing",
]

[[package]]
name = "jxl-color"
version = "0.9.0"
source = "git+https://github.com/tirr-c/jxl-oxide.git#229c223af49de96247a4e5548470ce2753912f3e"
dependencies = [
"jxl-bitstream",
"jxl-coding",
"jxl-grid",
"jxl-oxide-common",
"jxl-threadpool",
"tracing",
]

[[package]]
name = "jxl-frame"
version = "0.11.0"
source = "git+https://github.com/tirr-c/jxl-oxide.git#229c223af49de96247a4e5548470ce2753912f3e"
dependencies = [
"jxl-bitstream",
"jxl-coding",
"jxl-grid",
"jxl-image",
"jxl-modular",
"jxl-oxide-common",
"jxl-threadpool",
"jxl-vardct",
"tracing",
]

[[package]]
name = "jxl-grid"
version = "0.5.0"
source = "git+https://github.com/tirr-c/jxl-oxide.git#229c223af49de96247a4e5548470ce2753912f3e"
dependencies = [
"tracing",
]

[[package]]
name = "jxl-image"
version = "0.11.0"
source = "git+https://github.com/tirr-c/jxl-oxide.git#229c223af49de96247a4e5548470ce2753912f3e"
dependencies = [
"jxl-bitstream",
"jxl-color",
"jxl-grid",
"jxl-oxide-common",
"tracing",
]

[[package]]
name = "jxl-modular"
version = "0.9.0"
source = "git+https://github.com/tirr-c/jxl-oxide.git#229c223af49de96247a4e5548470ce2753912f3e"
dependencies = [
"jxl-bitstream",
"jxl-coding",
"jxl-grid",
"jxl-oxide-common",
"jxl-threadpool",
"tracing",
]

[[package]]
name = "jxl-oxide"
version = "0.10.0"
source = "git+https://github.com/tirr-c/jxl-oxide.git#229c223af49de96247a4e5548470ce2753912f3e"
dependencies = [
"bytemuck",
"image",
"jxl-bitstream",
"jxl-color",
"jxl-frame",
"jxl-grid",
"jxl-image",
"jxl-oxide-common",
"jxl-render",
"jxl-threadpool",
"tracing",
]

[[package]]
name = "jxl-oxide-common"
version = "0.1.0"
source = "git+https://github.com/tirr-c/jxl-oxide.git#229c223af49de96247a4e5548470ce2753912f3e"
dependencies = [
"jxl-bitstream",
]

[[package]]
name = "jxl-render"
version = "0.10.0"
source = "git+https://github.com/tirr-c/jxl-oxide.git#229c223af49de96247a4e5548470ce2753912f3e"
dependencies = [
"jxl-bitstream",
"jxl-coding",
"jxl-color",
"jxl-frame",
"jxl-grid",
"jxl-image",
"jxl-modular",
"jxl-oxide-common",
"jxl-threadpool",
"jxl-vardct",
"tracing",
]

[[package]]
name = "jxl-threadpool"
version = "0.1.1"
source = "git+https://github.com/tirr-c/jxl-oxide.git#229c223af49de96247a4e5548470ce2753912f3e"
dependencies = [
"tracing",
]

[[package]]
name = "jxl-vardct"
version = "0.9.0"
source = "git+https://github.com/tirr-c/jxl-oxide.git#229c223af49de96247a4e5548470ce2753912f3e"
dependencies = [
"jxl-bitstream",
"jxl-coding",
"jxl-grid",
"jxl-modular",
"jxl-oxide-common",
"jxl-threadpool",
"tracing",
]

[[package]]
name = "keyboard_events"
version = "0.1.0"
Expand Down Expand Up @@ -5202,9 +5348,9 @@ checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"

[[package]]
name = "zune-jpeg"
version = "0.4.11"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448"
checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768"
dependencies = [
"zune-core",
]
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ ahash = { version = "0.8.11", default-features = false, features = [
"std",
] }
backtrace = "0.3"
bytemuck = "1.7.2"
bytemuck = "1.19"
criterion = { version = "0.5.1", default-features = false }
dify = { version = "0.7", default-features = false }
document-features = " 0.2.8"
Expand Down
12 changes: 10 additions & 2 deletions crates/egui_extras/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ rustdoc-args = ["--generate-link-to-definition"]
[features]
default = ["dep:mime_guess2"]

## Shorthand for enabling the different types of image loaders (`file`, `http`, `image`, `svg`).
all_loaders = ["file", "http", "image", "svg", "gif"]
## Shorthand for enabling the different types of image loaders (`file`, `http`, `image`, `jxl`, `svg`, `gif`).
all_loaders = ["file", "http", "image", "jxl", "svg", "gif"]

## Enable [`DatePickerButton`] widget.
datepicker = ["chrono"]
Expand All @@ -53,6 +53,9 @@ http = ["dep:ehttp"]
## ```
image = ["dep:image"]

## Support loading jxl images via jxl-oxide. Requires the [`image`](https://docs.rs/image) crate feature.
jxl = ["dep:jxl-oxide", "image"]

## Enable profiling with the [`puffin`](https://docs.rs/puffin) crate.
##
## Only enabled on native, because of the low resolution (1ms) of clocks in browsers.
Expand Down Expand Up @@ -105,5 +108,10 @@ syntect = { version = "5", optional = true, default-features = false, features =
# svg feature
resvg = { version = "0.37", optional = true, default-features = false }

# jxl feature
jxl-oxide = { version = "0.10", git = "https://github.com/tirr-c/jxl-oxide.git", optional = true, default-features = false, features = [
"image",
] }

# http feature
ehttp = { version = "0.5", optional = true, default-features = false }
42 changes: 34 additions & 8 deletions crates/egui_extras/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,22 @@ impl RetainedImage {

use egui::ColorImage;

/// Load a (non-svg) image.
/// Load a `image::DynamicImage` image.
///
/// Requires the "image" feature. You must also opt-in to the image formats you need
/// with e.g. `image = { version = "0.25", features = ["jpeg", "png"] }`.
///
/// # Errors
/// On invalid image or unsupported image format.
#[cfg(feature = "image")]
pub fn load_dynamic_image(dynamic_image: &image::DynamicImage) -> egui::ColorImage {
let size = [dynamic_image.width() as _, dynamic_image.height() as _];
let image_buffer = dynamic_image.to_rgba8();
let pixels = image_buffer.as_flat_samples();
egui::ColorImage::from_rgba_unmultiplied(size, pixels.as_slice())
}

/// Load a (non-svg, non-jxl) image.
///
/// Requires the "image" feature. You must also opt-in to the image formats you need
/// with e.g. `image = { version = "0.25", features = ["jpeg", "png"] }`.
Expand All @@ -203,13 +218,24 @@ use egui::ColorImage;
pub fn load_image_bytes(image_bytes: &[u8]) -> Result<egui::ColorImage, String> {
crate::profile_function!();
let image = image::load_from_memory(image_bytes).map_err(|err| err.to_string())?;
let size = [image.width() as _, image.height() as _];
let image_buffer = image.to_rgba8();
let pixels = image_buffer.as_flat_samples();
Ok(egui::ColorImage::from_rgba_unmultiplied(
size,
pixels.as_slice(),
))
Ok(load_dynamic_image(&image))
}

/// Load a jxl image.
///
/// Requires the "image" and "jxl" features. You must also opt-in to any other image formats
/// you need with e.g. `image = { version = "0.25", features = ["jpeg", "png"] }`.
/// No image crate feature is required for jxl support.
///
/// # Errors
/// On invalid image or unsupported image format.
#[cfg(all(feature = "image", feature = "jxl"))]
pub fn load_image_bytes_jxl(image_bytes: &[u8]) -> Result<egui::ColorImage, String> {
crate::profile_function!();
let decoder =
jxl_oxide::integration::JxlDecoder::new(image_bytes).map_err(|err| err.to_string())?;
let image = image::DynamicImage::from_decoder(decoder).map_err(|err| err.to_string())?;
Ok(load_dynamic_image(&image))
}

/// Load an SVG and rasterize it into an egui image.
Expand Down
8 changes: 8 additions & 0 deletions crates/egui_extras/src/loaders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ pub fn install_image_loaders(ctx: &egui::Context) {
log::trace!("installed ImageCrateLoader");
}

#[cfg(feature = "jxl")]
if !ctx.is_loader_installed(self::jxl_loader::JxlLoader::ID) {
ctx.add_image_loader(std::sync::Arc::new(self::jxl_loader::JxlLoader::default()));
log::trace!("installed JxlLoader");
}

#[cfg(feature = "gif")]
if !ctx.is_loader_installed(self::gif_loader::GifLoader::ID) {
ctx.add_image_loader(std::sync::Arc::new(self::gif_loader::GifLoader::default()));
Expand Down Expand Up @@ -111,5 +117,7 @@ mod ehttp_loader;
mod gif_loader;
#[cfg(feature = "image")]
mod image_loader;
#[cfg(feature = "jxl")]
mod jxl_loader;
#[cfg(feature = "svg")]
mod svg_loader;
1 change: 1 addition & 0 deletions crates/egui_extras/src/loaders/image_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,5 +117,6 @@ mod tests {
assert!(is_supported_uri("http://test.gif"));
assert!(is_supported_uri("file://test"));
assert!(!is_supported_uri("test.svg"));
assert!(!is_supported_uri("test.jxl"));
}
}
Loading

0 comments on commit 60ee443

Please sign in to comment.