AmigoNico
AmigoNico

Reputation: 6852

No-copy way of creating an NDArray from an unboxed slice?

I am writing a Rust plugin for an Electron app using Neon. The Javascript code passes me an image -- a 3D array of rows of columns of 4-element pixels (RGBA). Because the # of rows and # of columns are not known at compile time, I would like to create an NDArray of the passed image (probably a 2D array of pixels rather than a 3D array of bytes).

However, I don't want to copy the image. It's megabytes in size, and this is happening many times per second, so copying would be inefficient.

I think I see how it could be done if the image were Boxed -- something like this:

let vec = boxed_image.into_vec(??);
let array = Array::from_shape_vec((rows, cols), vec);
...
let vec = array.into_raw_vec();
let ptr = vec.leak();

But this array belongs to the Javascript code; I get to look at it, but I don't own it. And it was not allocated by Rust, so it's not Boxed.

Is there a way to create an NDArray from an unboxed slice? Or is there a better way to crack this nut?

Upvotes: 1

Views: 330

Answers (1)

sebpuetz
sebpuetz

Reputation: 2618

Assuming that you're getting a byte slice from Javascript, you should be able to use ndarray::ArrayView to create a borrowed view into the data:

https://docs.rs/ndarray/0.15.1/ndarray/type.ArrayView.html#impl

// copied from https://docs.rs/ndarray/0.15.1/ndarray/type.ArrayView.html#impl
use ndarray::ArrayView;
use ndarray::arr3;
use ndarray::ShapeBuilder;

// advanced example where we are even specifying exact strides to use (which is optional).
let s = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
let a = ArrayView::from_shape((2, 3, 2).strides((1, 4, 2)),
                              &s).unwrap();

assert!(
    a == arr3(&[[[0, 2],
                 [4, 6],
                 [8, 10]],
                [[1, 3],
                 [5, 7],
                 [9, 11]]])
);
assert!(a.strides() == &[1, 4, 2]);

This will of course only work if you don't need to own the data, which is pretty much implied by not creating a copy.

Upvotes: 2

Related Questions