use crate::kind::Rs2Format;
use std::{os::raw::c_void, slice};
#[derive(Debug)]
pub enum PixelKind<'a> {
Yuyv {
y: &'a u8,
u: &'a u8,
v: &'a u8,
},
Uyvy {
y: &'a u8,
u: &'a u8,
v: &'a u8,
},
Bgr8 {
b: &'a u8,
g: &'a u8,
r: &'a u8,
},
Bgra8 {
b: &'a u8,
g: &'a u8,
r: &'a u8,
a: &'a u8,
},
Rgb8 {
r: &'a u8,
g: &'a u8,
b: &'a u8,
},
Rgba8 {
r: &'a u8,
g: &'a u8,
b: &'a u8,
a: &'a u8,
},
Raw8 {
val: &'a u8,
},
Y8 {
y: &'a u8,
},
Y16 {
y: &'a u16,
},
Z16 {
depth: &'a u16,
},
Distance {
distance: &'a f32,
},
Disparity32 {
disparity: &'a f32,
},
Xyz32f {
x: &'a f32,
y: &'a f32,
z: &'a f32,
},
}
#[inline]
pub(crate) unsafe fn get_pixel<'a>(
format: Rs2Format,
data_size_in_bytes: usize,
data: *const c_void,
stride_in_bytes: usize,
col: usize,
row: usize,
) -> PixelKind<'a> {
match format {
Rs2Format::Yuyv => {
let slice = slice::from_raw_parts(data.cast::<u8>(), data_size_in_bytes);
let offset = (row * stride_in_bytes) + (col / 2) * 4;
let y = if row % 2 == 0 {
slice.get_unchecked(offset)
} else {
slice.get_unchecked(offset + 2)
};
PixelKind::Yuyv {
y,
u: slice.get_unchecked(offset + 1),
v: slice.get_unchecked(offset + 3),
}
}
Rs2Format::Uyvy => {
let slice = slice::from_raw_parts(data.cast::<u8>(), data_size_in_bytes);
let offset = (row * stride_in_bytes) + (col / 2) * 4;
let y = if row % 2 == 0 {
slice.get_unchecked(offset + 1)
} else {
slice.get_unchecked(offset + 3)
};
PixelKind::Uyvy {
y,
u: slice.get_unchecked(offset),
v: slice.get_unchecked(offset + 2),
}
}
Rs2Format::Bgr8 => {
let slice = slice::from_raw_parts(data.cast::<u8>(), data_size_in_bytes);
let offset = (row * stride_in_bytes) + (col * 3);
PixelKind::Bgr8 {
b: slice.get_unchecked(offset),
g: slice.get_unchecked(offset + 1),
r: slice.get_unchecked(offset + 2),
}
}
Rs2Format::Bgra8 => {
let slice = slice::from_raw_parts(data.cast::<u8>(), data_size_in_bytes);
let offset = (row * stride_in_bytes) + (col * 4);
PixelKind::Bgra8 {
b: slice.get_unchecked(offset),
g: slice.get_unchecked(offset + 1),
r: slice.get_unchecked(offset + 2),
a: slice.get_unchecked(offset + 3),
}
}
Rs2Format::Rgb8 => {
let slice = slice::from_raw_parts(data.cast::<u8>(), data_size_in_bytes);
let offset = (row * stride_in_bytes) + (col * 3);
PixelKind::Bgr8 {
r: slice.get_unchecked(offset),
g: slice.get_unchecked(offset + 1),
b: slice.get_unchecked(offset + 2),
}
}
Rs2Format::Rgba8 => {
let slice = slice::from_raw_parts(data.cast::<u8>(), data_size_in_bytes);
let offset = (row * stride_in_bytes) + (col * 4);
PixelKind::Bgra8 {
r: slice.get_unchecked(offset),
g: slice.get_unchecked(offset + 1),
b: slice.get_unchecked(offset + 2),
a: slice.get_unchecked(offset + 3),
}
}
Rs2Format::Raw8 => {
let slice = slice::from_raw_parts(data.cast::<u8>(), data_size_in_bytes);
let offset = (row * stride_in_bytes) + col;
PixelKind::Raw8 {
val: slice.get_unchecked(offset),
}
}
Rs2Format::Y8 => {
let slice = slice::from_raw_parts(data.cast::<u8>(), data_size_in_bytes);
let offset = (row * stride_in_bytes) + col;
PixelKind::Y8 {
y: slice.get_unchecked(offset),
}
}
Rs2Format::Y16 => {
let size = data_size_in_bytes / std::mem::size_of::<u16>();
let stride = stride_in_bytes / std::mem::size_of::<u16>();
let slice = slice::from_raw_parts(data.cast::<u16>(), size);
let offset = (row * stride) + col;
PixelKind::Y16 {
y: slice.get_unchecked(offset),
}
}
Rs2Format::Z16 => {
let size = data_size_in_bytes / std::mem::size_of::<u16>();
let stride = stride_in_bytes / std::mem::size_of::<u16>();
let slice = slice::from_raw_parts(data.cast::<u16>(), size);
let offset = (row * stride) + col;
PixelKind::Z16 {
depth: slice.get_unchecked(offset),
}
}
Rs2Format::Distance => {
let size = data_size_in_bytes / std::mem::size_of::<f32>();
let stride = stride_in_bytes / std::mem::size_of::<f32>();
let slice = slice::from_raw_parts(data.cast::<f32>(), size);
let offset = (row * stride) + col;
PixelKind::Distance {
distance: slice.get_unchecked(offset),
}
}
Rs2Format::Disparity32 => {
let size = data_size_in_bytes / std::mem::size_of::<f32>();
let stride = stride_in_bytes / std::mem::size_of::<f32>();
let slice = slice::from_raw_parts(data.cast::<f32>(), size);
let offset = (row * stride) + col;
PixelKind::Disparity32 {
disparity: slice.get_unchecked(offset),
}
}
Rs2Format::Xyz32F => {
let size = data_size_in_bytes / std::mem::size_of::<f32>();
let stride = stride_in_bytes / std::mem::size_of::<f32>();
let slice = slice::from_raw_parts(data.cast::<f32>(), size);
let offset = (row * stride) + col;
PixelKind::Xyz32f {
x: slice.get_unchecked(offset),
y: slice.get_unchecked(offset + 1),
z: slice.get_unchecked(offset + 2),
}
}
_ => {
panic!("Unsupported video format.");
}
}
}