Skip to content

Commit

Permalink
[4/4] Remove TensorBuffer::JPEG, DecodedTensor, `TensorDecodeCach…
Browse files Browse the repository at this point in the history
…e` (#6884)

* Part of #6844
* Closes #3803

⚠️ This breaks any existing `JPEG`-encoded RRDs

### Rust API
* Removed `TensorBuffer::JPEG`
* Removed `TensorData::from_jpeg_bytes`
* Deprecated `Image::from_file_path` and `from_file_contents`

For all of these, use `ImageEncoded` instead.

### PR train
* Prev: #6882
* Prev: #6874
* Prev: #6883

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested the web demo (if applicable):
* Using examples from latest `main` build:
[rerun.io/viewer](https://rerun.io/viewer/pr/6884?manifest_url=https://app.rerun.io/version/main/examples_manifest.json)
* Using full set of examples from `nightly` build:
[rerun.io/viewer](https://rerun.io/viewer/pr/6884?manifest_url=https://app.rerun.io/version/nightly/examples_manifest.json)
* [x] The PR title and labels are set such as to maximize their
usefulness for the next release's CHANGELOG
* [x] If applicable, add a new check to the [release
checklist](https://github.com/rerun-io/rerun/blob/main/tests/python/release_checklist)!
* [x] If have noted any breaking changes to the log API in
`CHANGELOG.md` and the migration guide

- [PR Build Summary](https://build.rerun.io/pr/6884)
- [Recent benchmark results](https://build.rerun.io/graphs/crates.html)
- [Wasm size tracking](https://build.rerun.io/graphs/sizes.html)

To run all checks from `main`, comment on the PR with `@rerun-bot
full-check`.
  • Loading branch information
emilk authored Jul 15, 2024
1 parent 528eda6 commit 8124967
Show file tree
Hide file tree
Showing 47 changed files with 312 additions and 978 deletions.
11 changes: 7 additions & 4 deletions crates/store/re_data_loader/src/loader_archetype.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use re_chunk::{Chunk, RowId};
use re_log_types::{EntityPath, TimeInt, TimePoint};
use re_types::components::MediaType;

use crate::{DataLoader, DataLoaderError, LoadedData};

Expand Down Expand Up @@ -138,10 +139,12 @@ fn load_image(

let rows = [
{
let arch = re_types::archetypes::Image::from_file_contents(
contents,
image::ImageFormat::from_path(filepath).ok(),
)?;
let mut arch = re_types::archetypes::ImageEncoded::from_file_contents(contents);

if let Ok(format) = image::ImageFormat::from_path(filepath) {
arch.media_type = Some(MediaType::from(format.to_mime_type()));
}

Chunk::builder(entity_path)
.with_archetype(RowId::new(), timepoint, &arch)
.build()?
Expand Down
2 changes: 1 addition & 1 deletion crates/store/re_types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ re_tracing.workspace = true
re_types_core.workspace = true

# External
anyhow.workspace = true
anyhow.workspace = true # TODO(#1845): Use thiserror instead
array-init.workspace = true
arrow2 = { workspace = true, features = [
"io_ipc",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ namespace rerun.components;
/// These dimensions are combined with an index to look up values from the `buffer` field,
/// which stores a contiguous array of typed values.
///
/// Note that the buffer may be encoded in a compressed format such as `jpeg` or
/// in a format with downsampled chroma, such as NV12 or YUY2.
/// For file formats, the shape is used as a hint, for chroma downsampled format
/// the shape has to be the shape of the decoded image.
/// Note that the buffer may in a format with downsampled chroma, such as NV12 or YUY2.
/// For chroma downsampled formats the shape has to be the shape of the decoded image.
table TensorData (
"attr.arrow.transparent",
"attr.rust.derive": "Default, PartialEq",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ table F64Buffer(order: 100, transparent) {
data: [double] (order: 100);
}

/// Raw bytes of a JPEG file.
table JPEGBuffer(order: 100, transparent) {
data: [ubyte] (order: 100);
}

table NV12Buffer(order: 100, transparent) {
data: [ubyte] (order: 100);
}
Expand Down Expand Up @@ -102,9 +97,6 @@ union TensorBuffer (
/// 64bit IEEE-754 floating point, also known as `double`.
F64: F64Buffer (transparent),

/// Raw bytes of a JPEG file.
JPEG: JPEGBuffer (transparent),

/// NV12 is a YUV 4:2:0 chroma downsamples format with 8 bits per channel.
///
/// First comes entire image in Y, followed by interleaved lines ordered as U0, V0, U1, V1, etc.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ namespace rerun.datatypes;
/// These dimensions are combined with an index to look up values from the `buffer` field,
/// which stores a contiguous array of typed values.
///
/// Note that the buffer may be encoded in a compressed format such as `jpeg` or
/// in a format with downsampled chroma, such as NV12 or YUY2.
/// For file formats, the shape is used as a hint, for chroma downsampled format
/// the shape has to be the shape of the decoded image.
/// Note that the buffer may in a format with downsampled chroma, such as NV12 or YUY2.
/// For chroma downsampled formats the shape has to be the shape of the decoded image.
table TensorData (
"attr.python.aliases": "npt.ArrayLike",
"attr.python.array_aliases": "npt.ArrayLike",
Expand Down
8 changes: 4 additions & 4 deletions crates/store/re_types/src/archetypes/asset3d_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ impl Asset3D {
///
/// If no [`MediaType`] can be guessed at the moment, the Rerun Viewer will try to guess one
/// from the data at render-time. If it can't, rendering will fail with an error.
///
/// Returns an error if the file cannot be read.
#[cfg(not(target_arch = "wasm32"))]
#[inline]
pub fn from_file(filepath: impl AsRef<std::path::Path>) -> anyhow::Result<Self> {
use anyhow::Context as _;
pub fn from_file(filepath: impl AsRef<std::path::Path>) -> std::io::Result<Self> {
let filepath = filepath.as_ref();
let contents = std::fs::read(filepath)
.with_context(|| format!("could not read file contents: {filepath:?}"))?;
let contents = std::fs::read(filepath)?;
Ok(Self::from_file_contents(
contents,
MediaType::guess_from_path(filepath),
Expand Down
8 changes: 4 additions & 4 deletions crates/store/re_types/src/archetypes/image_encoded_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ impl ImageEncoded {
/// Creates a new 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::path::Path>) -> anyhow::Result<Self> {
use anyhow::Context as _;
pub fn from_file(filepath: impl AsRef<std::path::Path>) -> std::io::Result<Self> {
let filepath = filepath.as_ref();
let contents = std::fs::read(filepath)
.with_context(|| format!("could not read file contents: {filepath:?}"))?;
let contents = std::fs::read(filepath)?;
Ok(Self::from_file_contents(contents))
}

Expand Down
28 changes: 9 additions & 19 deletions crates/store/re_types/src/archetypes/image_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use crate::{
image::{find_non_empty_dim_indices, ImageConstructionError},
};

use super::ImageEncoded;

use super::Image;

impl Image {
Expand Down Expand Up @@ -48,36 +50,24 @@ impl Image {
/// Creates a new [`Image`] from a file.
///
/// The image format will be inferred from the path (extension), or the contents if that fails.
#[cfg(feature = "image")]
#[deprecated = "Use ImageEncoded::from_file instead"]
#[cfg(not(target_arch = "wasm32"))]
#[inline]
pub fn from_file_path(filepath: impl AsRef<std::path::Path>) -> anyhow::Result<Self> {
let filepath = filepath.as_ref();
Ok(Self::new(crate::datatypes::TensorData::from_image_file(
filepath,
)?))
pub fn from_file_path(filepath: impl AsRef<std::path::Path>) -> std::io::Result<ImageEncoded> {
ImageEncoded::from_file(filepath)
}

/// Creates a new [`Image`] from the contents of a file.
///
/// If unspecified, the image format will be inferred from the contents.
#[deprecated = "Use ImageEncoded::from_file_contents instead"]
#[cfg(feature = "image")]
#[inline]
pub fn from_file_contents(
contents: Vec<u8>,
format: Option<image::ImageFormat>,
) -> anyhow::Result<Self> {
let format = if let Some(format) = format {
format
} else {
image::guess_format(&contents)?
};

let tensor = crate::components::TensorData(crate::datatypes::TensorData::from_image_bytes(
contents, format,
)?);

Ok(Self::new(tensor))
_format: Option<image::ImageFormat>,
) -> ImageEncoded {
ImageEncoded::from_file_contents(contents)
}
}

Expand Down
44 changes: 44 additions & 0 deletions crates/store/re_types/src/archetypes/tensor_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,50 @@ impl Tensor {
}
}

#[cfg(feature = "image")]
impl Tensor {
/// Construct a tensor from something that can be turned into a [`image::DynamicImage`].
///
/// Requires the `image` feature.
pub fn from_image(
image: impl Into<image::DynamicImage>,
) -> Result<Self, crate::tensor_data::TensorImageLoadError> {
TensorData::from_image(image).map(|data| Self { data: data.into() })
}

/// Construct a tensor from [`image::DynamicImage`].
///
/// Requires the `image` feature.
pub fn from_dynamic_image(
image: image::DynamicImage,
) -> Result<Self, crate::tensor_data::TensorImageLoadError> {
TensorData::from_dynamic_image(image).map(|data| Self { data: data.into() })
}
}

impl AsRef<TensorData> for Tensor {
#[inline(always)]
fn as_ref(&self) -> &TensorData {
&self.data
}
}

impl std::ops::Deref for Tensor {
type Target = TensorData;

#[inline(always)]
fn deref(&self) -> &TensorData {
&self.data
}
}

impl std::borrow::Borrow<TensorData> for Tensor {
#[inline(always)]
fn borrow(&self) -> &TensorData {
&self.data
}
}

// ----------------------------------------------------------------------------
// Make it possible to create an ArrayView directly from a Tensor.

Expand Down
6 changes: 2 additions & 4 deletions crates/store/re_types/src/components/tensor_data.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8124967

Please sign in to comment.