Reputation: 6852
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
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