Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to image 0.25 #5280

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 28 additions & 16 deletions Cargo.lock
Expand Up @@ -242,7 +242,7 @@ checksum = "1faa3c733d9a3dd6fbaf85da5d162a2e03b2e0033a90dceb0e2a90fdd1e5380a"
dependencies = [
"clipboard-win",
"core-graphics",
"image",
"image 0.24.6",
"log",
"objc",
"objc-foundation",
Expand Down Expand Up @@ -1588,7 +1588,7 @@ dependencies = [
"egui-wgpu",
"egui-winit",
"egui_glow",
"image",
"image 0.24.6",
"js-sys",
"log",
"objc",
Expand Down Expand Up @@ -1685,7 +1685,7 @@ dependencies = [
"egui",
"ehttp",
"enum-map",
"image",
"image 0.24.6",
"log",
"mime_guess2",
"puffin",
Expand Down Expand Up @@ -2300,7 +2300,7 @@ dependencies = [
"base64 0.13.1",
"byteorder",
"gltf-json",
"image",
"image 0.24.6",
"lazy_static",
"urlencoding",
]
Expand Down Expand Up @@ -2573,6 +2573,20 @@ dependencies = [
"tiff",
]

[[package]]
name = "image"
version = "0.25.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11"
dependencies = [
"bytemuck",
"byteorder",
"num-traits",
"png",
"zune-core",
"zune-jpeg",
]

[[package]]
name = "incremental_logging"
version = "0.17.0-alpha.3"
Expand Down Expand Up @@ -4228,7 +4242,7 @@ version = "0.17.0-alpha.3"
dependencies = [
"ahash",
"anyhow",
"image",
"image 0.25.1",
"once_cell",
"parking_lot",
"rayon",
Expand Down Expand Up @@ -4302,7 +4316,7 @@ dependencies = [
"egui",
"egui_extras",
"egui_plot",
"image",
"image 0.25.1",
"itertools 0.12.0",
"re_data_store",
"re_entity_db",
Expand Down Expand Up @@ -4604,7 +4618,7 @@ dependencies = [
"bytemuck",
"console_error_panic_hook",
"glam",
"image",
"image 0.25.1",
"itertools 0.12.0",
"macaw",
"pollster",
Expand Down Expand Up @@ -4944,7 +4958,7 @@ dependencies = [
"emath",
"glam",
"half 2.3.1",
"image",
"image 0.25.1",
"infer",
"itertools 0.12.0",
"linked-hash-map",
Expand All @@ -4966,8 +4980,6 @@ dependencies = [
"smallvec",
"thiserror",
"uuid",
"zune-core",
"zune-jpeg",
]

[[package]]
Expand Down Expand Up @@ -5065,7 +5077,7 @@ dependencies = [
"egui-wgpu",
"egui_plot",
"ehttp",
"image",
"image 0.25.1",
"itertools 0.12.0",
"js-sys",
"poll-promise",
Expand Down Expand Up @@ -5172,7 +5184,7 @@ dependencies = [
"egui",
"egui_tiles",
"glam",
"image",
"image 0.25.1",
"itertools 0.12.0",
"nohash-hasher",
"rayon",
Expand Down Expand Up @@ -5534,7 +5546,7 @@ version = "0.17.0-alpha.3"
dependencies = [
"anyhow",
"clap",
"image",
"image 0.25.1",
"re_log",
"rerun",
]
Expand All @@ -5556,7 +5568,7 @@ dependencies = [
"anyhow",
"clap",
"half 2.3.1",
"image",
"image 0.25.1",
"ndarray",
"re_log",
"rerun",
Expand Down Expand Up @@ -5618,7 +5630,7 @@ version = "0.17.0-alpha.3"
dependencies = [
"anyhow",
"clap",
"image",
"image 0.25.1",
"re_log",
"rerun",
]
Expand Down Expand Up @@ -6310,7 +6322,7 @@ version = "0.17.0-alpha.3"
dependencies = [
"anyhow",
"clap",
"image",
"image 0.25.1",
"re_log",
"rerun",
]
Expand Down
4 changes: 1 addition & 3 deletions Cargo.toml
Expand Up @@ -144,7 +144,7 @@ glam = "0.22" # glam update blocked by macaw
glob = "0.3"
gltf = "1.1"
half = "2.3.1"
image = { version = "0.24", default-features = false }
image = { version = "0.25", default-features = false }
indent = "0.1"
indexmap = "2.1" # Version chosen to align with other dependencies
indicatif = "0.17.7" # Progress bar
Expand Down Expand Up @@ -259,8 +259,6 @@ wgpu = { version = "0.19.4", default-features = false, features = [
wgpu-core = "0.19.4"
xshell = "0.2"
zip = { version = "0.6", default-features = false }
zune-core = "0.4"
zune-jpeg = "0.4"


[profile.dev]
Expand Down
2 changes: 0 additions & 2 deletions crates/re_log/src/lib.rs
Expand Up @@ -51,8 +51,6 @@ pub mod external {

/// Never log anything less serious than a `ERROR` from these crates.
const CRATES_AT_ERROR_LEVEL: &[&str] = &[
// Waiting for https://github.com/etemesi254/zune-image/issues/131 to be released
"zune_jpeg",
// silence rustls in release mode: https://github.com/rerun-io/rerun/issues/3104
#[cfg(not(debug_assertions))]
"rustls",
Expand Down
8 changes: 4 additions & 4 deletions crates/re_types/Cargo.toml
Expand Up @@ -37,7 +37,7 @@ egui_plot = ["dep:egui_plot"]
glam = ["dep:glam"]

## Integration with the [`image`](https://crates.io/crates/image/) crate, plus JPEG support.
image = ["dep:ecolor", "dep:image", "dep:zune-core", "dep:zune-jpeg"]
image = ["dep:ecolor", "dep:image"]

## Enable (de)serialization using serde.
serde = ["dep:serde"]
Expand Down Expand Up @@ -81,11 +81,11 @@ uuid = { workspace = true, features = ["serde", "v4", "js"] }
ecolor = { workspace = true, optional = true }
egui_plot = { workspace = true, optional = true }
glam = { workspace = true, optional = true }
image = { workspace = true, optional = true, default-features = false }
image = { workspace = true, optional = true, default-features = false, features = [
"jpeg",
] }
mint = { workspace = true, optional = true }
serde = { workspace = true, optional = true, features = ["derive", "rc"] }
zune-core = { workspace = true, optional = true }
zune-jpeg = { workspace = true, optional = true }


[dev-dependencies]
Expand Down
14 changes: 6 additions & 8 deletions crates/re_types/src/datatypes/tensor_data_ext.rs
Expand Up @@ -647,19 +647,17 @@ impl TensorData {
pub fn from_jpeg_bytes(jpeg_bytes: Vec<u8>) -> Result<Self, TensorImageLoadError> {
re_tracing::profile_function!();

use zune_jpeg::JpegDecoder;

let mut decoder = JpegDecoder::new(&jpeg_bytes);
decoder.decode_headers()?;
let (w, h) = decoder
.dimensions()
.expect("can't fail after a successful decode_headers");
// Parse JPEG header:
use image::ImageDecoder as _;
let jpeg = image::codecs::jpeg::JpegDecoder::new(std::io::Cursor::new(&jpeg_bytes))?;
let (w, h) = jpeg.dimensions();
let depth = jpeg.color_type().channel_count();

Ok(Self {
shape: vec![
TensorDimension::height(h as _),
TensorDimension::width(w as _),
TensorDimension::depth(3),
TensorDimension::depth(depth as _),
],
buffer: TensorBuffer::Jpeg(jpeg_bytes.into()),
})
Expand Down
58 changes: 12 additions & 46 deletions crates/re_types/src/tensor_data.rs
Expand Up @@ -47,9 +47,6 @@ pub enum TensorImageLoadError {

#[error("The encoded tensor shape did not match its metadata {expected:?} != {found:?}")]
InvalidMetaData { expected: Vec<u64>, found: Vec<u64> },

#[error(transparent)]
JpegDecode(#[from] zune_jpeg::errors::DecodeErrors),
}

#[cfg(feature = "image")]
Expand Down Expand Up @@ -562,62 +559,31 @@ impl DecodedTensor {
/// Decode the contents of a JPEG file, with the given expected size.
///
/// Returns an error if the size does not match.
fn decode_jpeg_bytes(
pub fn decode_jpeg_bytes(
jpeg_bytes: &[u8],
[expected_height, expected_width, expected_channels]: [u64; 3],
) -> Result<Self, TensorImageLoadError> {
re_tracing::profile_function!(format!("{expected_width}x{expected_height}"));

use zune_core::colorspace::ColorSpace;
use zune_core::options::DecoderOptions;
use zune_jpeg::JpegDecoder;

let mut options = DecoderOptions::default();

let depth = if expected_channels == 1 {
options = options.jpeg_set_out_colorspace(ColorSpace::Luma);
1
} else {
// We decode to RGBA directly so we don't need to pad to four bytes later when uploading to GPU.
options = options.jpeg_set_out_colorspace(ColorSpace::RGBA);
4
use image::io::Reader as ImageReader;
let mut reader = ImageReader::new(std::io::Cursor::new(jpeg_bytes));
reader.set_format(image::ImageFormat::Jpeg);
let img = {
re_tracing::profile_scope!("decode_jpeg");
reader.decode()?
};

let mut decoder = JpegDecoder::new_with_options(jpeg_bytes, options);
let pixels = decoder.decode()?;
let (w, h) = decoder
.dimensions()
.expect("can't fail after a successful decode");

let (w, h) = (w as u64, h as u64);
let (w, h) = (img.width() as u64, img.height() as u64);
let channels = img.color().channel_count() as u64;

if w != expected_width || h != expected_height {
if (w, h, channels) != (expected_width, expected_height, expected_channels) {
return Err(TensorImageLoadError::InvalidMetaData {
expected: [expected_height, expected_width, expected_channels].into(),
found: [h, w, depth].into(),
found: [h, w, channels].into(),
});
}

if pixels.len() as u64 != w * h * depth {
return Err(zune_jpeg::errors::DecodeErrors::Format(format!(
"Bug in zune-jpeg: Expected {w}x{h}x{depth}={} bytes, got {}",
w * h * depth,
pixels.len()
))
.into());
}

let tensor = TensorData {
shape: vec![
TensorDimension::height(h),
TensorDimension::width(w),
TensorDimension::depth(depth),
],
buffer: TensorBuffer::U8(pixels.into()),
};
let decoded_tensor = Self(tensor);

Ok(decoded_tensor)
Self::from_image(img)
}
}

Expand Down