mirror of
https://github.com/l1npengtul/nokhwa.git
synced 2026-07-04 10:37:26 +00:00
nokhwa-decoders basic implemention: todo tests
This commit is contained in:
+30
-15
@@ -4,11 +4,13 @@ use crate::image::{DecodedImage, NonFloatScalarWidth};
|
||||
use crate::types::{Resolution};
|
||||
pub use image::{ImageBuffer, Pixel, Primitive};
|
||||
use std::fmt::Debug;
|
||||
use bytemuck::try_cast_slice_mut;
|
||||
use crate::pixel_destination::PixelDestination;
|
||||
|
||||
pub trait Decoder {
|
||||
type Config: Clone + Debug;
|
||||
type OutputMeta: Clone + Debug;
|
||||
type DestinationFormatHint: Clone + Debug;
|
||||
const SUPPORTED_DESTINATIONS: &'static [PixelDestination];
|
||||
|
||||
fn config(&self) -> &Self::Config;
|
||||
|
||||
@@ -18,16 +20,29 @@ pub trait Decoder {
|
||||
&mut self,
|
||||
to_decode: FrameBuffer,
|
||||
buffer: impl AsMut<[u8]>,
|
||||
destination_format_hint: Option<Self::DestinationFormatHint>,
|
||||
destination_format: PixelDestination,
|
||||
) -> Result<Self::OutputMeta, NokhwaError>;
|
||||
|
||||
fn decode_to_pixel_buffer<P: Pixel>(
|
||||
&mut self,
|
||||
to_decode: FrameBuffer,
|
||||
buffer: impl AsMut<[P::Subpixel]>,
|
||||
) -> Result<Self::OutputMeta, NokhwaError>
|
||||
fn decode_to_pixel_buffer<P: Pixel>(&mut self, to_decode: FrameBuffer, mut buffer: impl AsMut<[P::Subpixel]>) -> Result<Self::OutputMeta, NokhwaError>
|
||||
where
|
||||
<P as Pixel>::Subpixel: NonFloatScalarWidth;
|
||||
<P as Pixel>::Subpixel: NonFloatScalarWidth
|
||||
{
|
||||
let destination = match PixelDestination::get_by_pixel::<P>() {
|
||||
Some(dest) => dest,
|
||||
None => return Err(NokhwaError::DecoderUnknownDestinationPixelFormat(P::COLOR_MODEL, P::Subpixel::WIDTH_BYTES))
|
||||
};
|
||||
|
||||
if !Self::supports_destination(destination) {
|
||||
return Err(NokhwaError::DecoderUnsupportedDestinationPixelFormat(destination))
|
||||
}
|
||||
|
||||
let buffer = buffer.as_mut();
|
||||
|
||||
let cast_slice = try_cast_slice_mut::<P::Subpixel, u8>(buffer)
|
||||
.map_err(|why| NokhwaError::DecoderInvalidBuffer(why.to_string()))?;
|
||||
|
||||
self.decode_to_buffer(to_decode, cast_slice, destination)
|
||||
}
|
||||
|
||||
fn decode<P: Pixel>(
|
||||
&mut self,
|
||||
@@ -36,16 +51,16 @@ pub trait Decoder {
|
||||
where
|
||||
<P as Pixel>::Subpixel: NonFloatScalarWidth;
|
||||
|
||||
fn output_decoder_min_size_pixel<P>(&self, resolution: Resolution) -> usize where
|
||||
fn output_decoder_min_size_pixel<P>(&self, resolution: Resolution) -> Result<usize, NokhwaError> where
|
||||
P: Pixel,
|
||||
<P as Pixel>::Subpixel: NonFloatScalarWidth {
|
||||
let channels = P::CHANNEL_COUNT as usize;
|
||||
let width_bytes = <<P as Pixel>::Subpixel as NonFloatScalarWidth>::WIDTH_BYTES;
|
||||
let resolution_mult = resolution.height() * resolution.width();
|
||||
(resolution_mult as usize) * (width_bytes as usize) * channels
|
||||
PixelDestination::get_by_pixel::<P>().map(|dest| self.output_decoder_min_size(resolution, dest)).ok_or(NokhwaError::DecoderUnknownDestinationPixelFormat(P::COLOR_MODEL, P::Subpixel::WIDTH_BYTES))?
|
||||
|
||||
}
|
||||
|
||||
fn output_decoder_min_size(&self, resolution: Resolution, destination_format: Self::DestinationFormatHint) -> usize;
|
||||
fn output_decoder_min_size(&self, resolution: Resolution, destination_format: PixelDestination) -> Result<usize, NokhwaError>;
|
||||
|
||||
fn buffer_takes_destination_hint(&self) -> bool;
|
||||
fn supports_destination(pixel_destination: PixelDestination) -> bool {
|
||||
Self::SUPPORTED_DESTINATIONS.contains(&pixel_destination)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
use crate::frame_format::{CustomFrameFormat, FrameFormat};
|
||||
use std::fmt::Debug;
|
||||
use thiserror::Error;
|
||||
use crate::pixel_destination::PixelDestination;
|
||||
use crate::types::Backends;
|
||||
|
||||
pub type NokhwaResult<T> = Result<T, NokhwaError>;
|
||||
@@ -68,8 +69,10 @@ pub enum NokhwaError {
|
||||
DecoderUnsupportedFrameFormat(FrameFormat),
|
||||
#[error("The destination frame format from {0} to {1} is not supported.")]
|
||||
DecoderUnsupportedCustomFrameFormatDestination(CustomFrameFormat, FrameFormat),
|
||||
#[error("Unsupported pixel configuration {0} with width {1}b.")]
|
||||
DecoderUnsupportedDestinationPixelFormat(&'static str, u32),
|
||||
#[error("Unknown pixel configuration {0} with width {1}b.")]
|
||||
DecoderUnknownDestinationPixelFormat(&'static str, u32),
|
||||
#[error("Unsupported pixel configuration {0}.")]
|
||||
DecoderUnsupportedDestinationPixelFormat(PixelDestination),
|
||||
#[error("Bad decoder configuration: {0}")]
|
||||
DecoderInvalidConfiguration(String),
|
||||
#[error("Failed to initialize decoder: {0}")]
|
||||
|
||||
@@ -35,3 +35,4 @@ pub mod stream;
|
||||
pub mod traits;
|
||||
pub mod types;
|
||||
pub mod utils;
|
||||
pub mod pixel_destination;
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
use std::fmt::{Display, Formatter};
|
||||
use image::Pixel;
|
||||
use crate::image::NonFloatScalarWidth;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialOrd, PartialEq)]
|
||||
pub enum PixelDestination {
|
||||
Rgb8,
|
||||
Rgba8,
|
||||
Rgb16,
|
||||
Rgba16,
|
||||
Bgr8,
|
||||
Bgra8,
|
||||
Bgr16,
|
||||
Bgra16,
|
||||
Luma8,
|
||||
LumaA8,
|
||||
Luma16,
|
||||
LumaA16,
|
||||
}
|
||||
|
||||
impl PixelDestination {
|
||||
pub fn get_by_pixel<P>() -> Option<Self>
|
||||
where
|
||||
P: Pixel,
|
||||
<P as Pixel>::Subpixel: NonFloatScalarWidth,
|
||||
{
|
||||
match P::COLOR_MODEL {
|
||||
"RGB" => match P::Subpixel::WIDTH_BYTES {
|
||||
1 => Some(PixelDestination::Rgb8),
|
||||
2 => Some(PixelDestination::Rgb16),
|
||||
_ => None,
|
||||
},
|
||||
"RGBA" => match P::Subpixel::WIDTH_BYTES {
|
||||
1 => Some(PixelDestination::Rgba8),
|
||||
2 => Some(PixelDestination::Rgba16),
|
||||
_ => None,
|
||||
},
|
||||
"BGR" => match P::Subpixel::WIDTH_BYTES {
|
||||
1 => Some(PixelDestination::Bgr8),
|
||||
2 => Some(PixelDestination::Bgr16),
|
||||
_ => None,
|
||||
},
|
||||
"BGRA" => match P::Subpixel::WIDTH_BYTES {
|
||||
1 => Some(PixelDestination::Bgra8),
|
||||
2 => Some(PixelDestination::Bgra16),
|
||||
_ => None,
|
||||
},
|
||||
"Y" => match P::Subpixel::WIDTH_BYTES {
|
||||
1 => Some(PixelDestination::Luma8),
|
||||
2 => Some(PixelDestination::Luma16),
|
||||
_ => None,
|
||||
},
|
||||
"YA" => match P::Subpixel::WIDTH_BYTES {
|
||||
1 => Some(PixelDestination::LumaA8),
|
||||
2 => Some(PixelDestination::LumaA16),
|
||||
_ => None,
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for PixelDestination {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
use crate::camera::Camera;
|
||||
use crate::error::NokhwaResult;
|
||||
use crate::types::{Backends, CameraIndex, CameraInformation, QueriedCamera};
|
||||
use std::fmt::{Display, Formatter};
|
||||
use crate::types::{Backends, CameraIndex, QueriedCamera};
|
||||
|
||||
|
||||
pub trait PlatformTrait {
|
||||
|
||||
@@ -8,7 +8,6 @@ use serde::{Deserialize, Serialize};
|
||||
use std::num::NonZeroI32;
|
||||
use std::ops::{Div, Rem};
|
||||
use std::{
|
||||
borrow::Borrow,
|
||||
cmp::Ordering,
|
||||
fmt::{Debug, Display, Formatter},
|
||||
hash::Hash,
|
||||
|
||||
Reference in New Issue
Block a user