diff --git a/crates/store/re_data_loader/src/lib.rs b/crates/store/re_data_loader/src/lib.rs index ae3a1f0a30e7..f7f89cdba33a 100644 --- a/crates/store/re_data_loader/src/lib.rs +++ b/crates/store/re_data_loader/src/lib.rs @@ -471,6 +471,8 @@ pub const SUPPORTED_IMAGE_EXTENSIONS: &[&str] = &[ "pbm", "pgm", "png", "ppm", "tga", "tif", "tiff", "webp", ]; +pub const SUPPORTED_DEPTH_IMAGE_EXTENSIONS: &[&str] = &["rvl", "png"]; + pub const SUPPORTED_VIDEO_EXTENSIONS: &[&str] = &["mp4"]; pub const SUPPORTED_MESH_EXTENSIONS: &[&str] = &["glb", "gltf", "obj", "stl"]; @@ -492,6 +494,7 @@ pub fn supported_extensions() -> impl Iterator { .iter() .chain(SUPPORTED_THIRD_PARTY_FORMATS) .chain(SUPPORTED_IMAGE_EXTENSIONS) + .chain(SUPPORTED_DEPTH_IMAGE_EXTENSIONS) .chain(SUPPORTED_VIDEO_EXTENSIONS) .chain(SUPPORTED_MESH_EXTENSIONS) .chain(SUPPORTED_POINT_CLOUD_EXTENSIONS) diff --git a/crates/store/re_data_loader/src/loader_archetype.rs b/crates/store/re_data_loader/src/loader_archetype.rs index 1283bc021f90..6354844dfc78 100644 --- a/crates/store/re_data_loader/src/loader_archetype.rs +++ b/crates/store/re_data_loader/src/loader_archetype.rs @@ -114,6 +114,14 @@ impl DataLoader for ArchetypeLoader { entity_path, contents.into_owned(), )?); + } else if crate::SUPPORTED_DEPTH_IMAGE_EXTENSIONS.contains(&extension.as_str()) { + re_log::debug!(?filepath, loader = self.name(), "Loading depth image…",); + rows.extend(load_depth_image( + &filepath, + timepoint, + entity_path, + contents.into_owned(), + )?); } else if crate::SUPPORTED_VIDEO_EXTENSIONS.contains(&extension.as_str()) { re_log::debug!(?filepath, loader = self.name(), "Loading video…",); rows.extend(load_video( @@ -191,6 +199,35 @@ fn load_image( Ok(rows.into_iter()) } +fn load_depth_image( + filepath: &std::path::Path, + timepoint: TimePoint, + entity_path: EntityPath, + contents: Vec, +) -> Result + use<>, DataLoaderError> { + re_tracing::profile_function!(); + + let rows = [{ + let mut arch = re_sdk_types::archetypes::EncodedDepthImage::from_file_contents(contents); + + if let Ok(format) = image::ImageFormat::from_path(filepath) { + arch = arch.with_media_type(format.to_mime_type()); + } else if filepath + .extension() + .and_then(|ext| ext.to_str()) + .is_some_and(|ext| ext.to_lowercase() == "rvl") + { + arch = arch.with_media_type(re_sdk_types::components::MediaType::RVL); + } + + Chunk::builder(entity_path) + .with_archetype(RowId::new(), timepoint, &arch) + .build()? + }]; + + Ok(rows.into_iter()) +} + fn load_video( filepath: &std::path::Path, mut timepoint: TimePoint, diff --git a/crates/store/re_sdk_types/src/archetypes/encoded_depth_image_ext.rs b/crates/store/re_sdk_types/src/archetypes/encoded_depth_image_ext.rs new file mode 100644 index 000000000000..20adf43fd048 --- /dev/null +++ b/crates/store/re_sdk_types/src/archetypes/encoded_depth_image_ext.rs @@ -0,0 +1,33 @@ +use super::EncodedDepthImage; + +impl EncodedDepthImage { + /// Creates a new depth image from the file contents at `path`. + /// + /// The [`MediaType`][crate::components::MediaType] will first be guessed from the file contents. + /// + /// Returns an error if the file cannot be read. + #[cfg(not(target_arch = "wasm32"))] + #[inline] + pub fn from_file(filepath: impl AsRef) -> std::io::Result { + let filepath = filepath.as_ref(); + let contents = std::fs::read(filepath)?; + Ok(Self::from_file_contents(contents)) + } + + /// Construct a depth image given the encoded content of some image file, e.g. a PNG or RVL. + /// + /// [`Self::media_type`] will be guessed from the bytes. + pub fn from_file_contents(bytes: Vec) -> Self { + #[cfg(feature = "image")] + { + if let Some(media_type) = image::guess_format(&bytes) + .ok() + .map(|format| crate::components::MediaType::from(format.to_mime_type())) + { + return Self::new(bytes).with_media_type(media_type); + } + } + + Self::new(bytes) + } +} diff --git a/crates/store/re_sdk_types/src/archetypes/mod.rs b/crates/store/re_sdk_types/src/archetypes/mod.rs index fa18ea0435d7..4de6062810fd 100644 --- a/crates/store/re_sdk_types/src/archetypes/mod.rs +++ b/crates/store/re_sdk_types/src/archetypes/mod.rs @@ -24,6 +24,7 @@ mod depth_image_ext; mod ellipsoids3d; mod ellipsoids3d_ext; mod encoded_depth_image; +mod encoded_depth_image_ext; mod encoded_image; mod encoded_image_ext; mod geo_line_strings;