clean up clippy core errors

This commit is contained in:
l1npengtul
2022-11-06 15:33:08 +09:00
parent 6fb211d356
commit 6dab1433d2
6 changed files with 84 additions and 462 deletions
+1
View File
@@ -21,6 +21,7 @@ crate-type = ["cdylib", "rlib"]
default = ["flume", "decoding"]
serialize = ["serde", "nokhwa-core/serialize"]
decoding = ["nokhwa-core/mjpeg"]
input-native = ["input-avfoundation", "input-v4l", "input-msmf"]
input-v4l = ["v4l", "v4l2-sys-mit"]
input-msmf = ["nokhwa-bindings-windows"]
input-avfoundation = ["nokhwa-bindings-macos"]
+3 -3
View File
@@ -14,9 +14,9 @@ input-opencv = ["nokhwa/input-opencv"]
input-avfoundation = ["nokhwa/input-avfoundation"]
[dependencies]
clap = "2.33.3"
glium = "0.31.0"
glutin = "0.27.0"
clap = "4.0.19"
glium = "0.32.1"
glutin = "0.30.0"
flume = "0.10.9"
# Use these as you need
+1 -399
View File
@@ -16,402 +16,4 @@
// Some assembly required. For developers 7 and up.
use clap::{App, Arg};
use glium::{
implement_vertex, index::PrimitiveType, program, texture::RawImage2d, uniform, Display,
IndexBuffer, Surface, Texture2d, VertexBuffer,
};
use glutin::{
event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder,
ContextBuilder,
};
use nokhwa::{nokhwa_initialize, query, ApiBackend, Camera, FrameFormat};
use std::time::Instant;
#[derive(Copy, Clone)]
pub struct Vertex {
position: [f32; 2],
tex_coords: [f32; 2],
}
fn main() {
let matches = App::new("nokhwa-example")
.version("0.1.0")
.author("l1npengtul <l1npengtul@protonmail.com> and the Nokhwa Contributers")
.about("Example program using Nokhwa")
.arg(Arg::with_name("query")
.short("q")
.long("query")
.value_name("BACKEND")
// TODO: Update as new backends are added!
.help("Query the system? Pass AUTO for automatic backend, UVC to query using UVC, V4L to query using Video4Linux, GST to query using Gstreamer, MSMF to query using Media Foundation.. Will post the list of availible devices.")
.default_value("AUTO")
.takes_value(true))
.arg(Arg::with_name("capture")
.short("c")
.long("capture")
.value_name("LOCATION")
.help("Capture from device? Pass the device index or string. Defaults to 0. If the input is not a number, it will be assumed an IPCamera")
.default_value("0")
.takes_value(true))
.arg(Arg::with_name("query-device")
.short("s")
.long("query-device")
.help("Show device queries from `compatible_fourcc` and `compatible_list_by_resolution`. Requires -c to be passed to work.")
.takes_value(false))
.arg(Arg::with_name("width")
.short("w")
.long("width")
.value_name("WIDTH")
.help("Set width of capture. Does nothing if -c flag is not set.")
.default_value("640")
.takes_value(true))
.arg(Arg::with_name("height")
.short("h")
.long("height")
.value_name("HEIGHT")
.help("Set height of capture. Does nothing if -c flag is not set.")
.default_value("480")
.takes_value(true))
.arg(Arg::with_name("framerate")
.short("rate")
.long("framerate")
.value_name("FRAMES_PER_SECOND")
.help("Set FPS of capture. Does nothing if -c flag is not set.")
.default_value("15")
.takes_value(true))
.arg(Arg::with_name("format")
.short("4cc")
.long("format")
.value_name("FORMAT")
.help("Set format of capture. Does nothing if -c flag is not set. Possible values are MJPG and YUYV. Will be ignored if not either. Ignored by GStreamer backend.")
.default_value("MJPG")
.takes_value(true))
.arg(Arg::with_name("capture-backend")
.short("b")
.long("backend")
.value_name("BACKEND")
.help("Set the capture backend. Pass AUTO for automatic backend, UVC to query using UVC, V4L to query using Video4Linux, GST to query using Gstreamer, OPENCV to use OpenCV, MSMF to use Media Foundation")
.default_value("AUTO")
.takes_value(true))
.arg(Arg::with_name("display")
.short("d")
.long("display")
.help("Pass to open a window and display.")
.takes_value(false))
.arg(Arg::with_name("controls")
.short("o")
.long("controls")
.help("List the camera controls. Does nothing if -c flag is not set.")
.takes_value(false))
.arg(Arg::with_name("setcontrols")
.short("p")
.long("setcontrols")
.help("Set the camera controls. Takes a comma seperated list of strings (lowercase!) that is \"<KEY>:\"<VALUE>\"\" (e.g.) \"Contrast:10,Brightness:50\". Does nothing if -c flag is not set.").takes_value(true))
.get_matches();
// Query example
if matches.is_present("query") {
let backend_value = matches.value_of("query").unwrap();
let mut use_backend = ApiBackend::Auto;
// AUTO
if backend_value == "AUTO" {
use_backend = ApiBackend::Auto;
} else if backend_value == "UVC" {
use_backend = ApiBackend::UniversalVideoClass;
} else if backend_value == "GST" {
use_backend = ApiBackend::GStreamer;
} else if backend_value == "V4L" {
use_backend = ApiBackend::Video4Linux;
} else if backend_value == "MSMF" {
use_backend = ApiBackend::MediaFoundation;
} else if backend_value == "AVF" {
nokhwa_initialize(|x| {
println!("{}", x);
});
use_backend = ApiBackend::AVFoundation;
}
match query(use_backend) {
Ok(devs) => {
for (idx, camera) in devs.iter().enumerate() {
println!("Device at index {}: {}", idx, camera)
}
}
Err(why) => {
println!("Failed to query: {why}")
}
}
}
if matches.is_present("capture") {
let backend_value = {
match matches.value_of("capture-backend").unwrap() {
"UVC" => ApiBackend::UniversalVideoClass,
"GST" => ApiBackend::GStreamer,
"V4L" => ApiBackend::Video4Linux,
"OPENCV" => ApiBackend::OpenCv,
"MSMF" => ApiBackend::MediaFoundation,
"AVF" => ApiBackend::AVFoundation,
_ => ApiBackend::Auto,
}
};
let width = matches
.value_of("width")
.unwrap()
.trim()
.parse::<u32>()
.expect("Width must be a u32!");
let height = matches
.value_of("height")
.unwrap()
.trim()
.parse::<u32>()
.expect("Height must be a u32!");
let fps = matches
.value_of("framerate")
.unwrap()
.trim()
.parse::<u32>()
.expect("Framerate must be a u32!");
let format = {
match matches.value_of("format").unwrap() {
"YUYV" => FrameFormat::YUYV,
_ => FrameFormat::MJPEG,
}
};
let matches_clone = matches.clone();
let (send, recv) = flume::unbounded();
// spawn a thread for capture
std::thread::spawn(move || {
// Index camera
if let Ok(index) = matches_clone
.value_of("capture")
.unwrap()
.trim()
.parse::<usize>()
{
let mut camera =
Camera::new_with(index, width, height, fps, format, backend_value).unwrap();
if matches_clone.is_present("query-device") {
match camera.compatible_fourcc() {
Ok(fcc) => {
for ff in fcc {
match camera.compatible_list_by_resolution(ff) {
Ok(compat) => {
println!("For FourCC {}", ff);
for (res, fps) in compat {
println!("{}x{}: {:?}", res.width(), res.height(), fps);
}
}
Err(why) => {
println!("Failed to get compatible resolution/FPS list for FrameFormat {ff}: {why}")
}
}
}
}
Err(why) => {
println!("Failed to get compatible FourCC: {why}")
}
}
}
if matches_clone.is_present("controls") {
match camera.camera_controls() {
Ok(controls) => {
println!("Supported Camera Controls: ");
for (index, control) in controls.into_iter().enumerate() {
println!("{}. {}", (index + 1), control)
}
}
Err(why) => {
println!("Failed to get camera controls: {why}")
}
}
}
if let Some(s) = matches_clone.value_of("setcontrols") {
let set_ctrls = s.to_string();
let supported = match camera.camera_controls_string() {
Ok(cc) => cc,
Err(why) => {
println!("Failed to get camera controls: {why}");
return;
}
};
for control in set_ctrls.split(',') {
let ctrl = control
.replace(' ', "")
.split(':')
.map(ToString::to_string)
.collect::<Vec<String>>();
let value = ctrl[1].parse::<i32>().unwrap();
let mut cc = match supported.get(&ctrl[0]) {
Some(camc) => *camc,
None => {
return;
}
};
cc.set_value(value).unwrap();
cc.set_active(true);
camera.set_camera_control(cc).unwrap();
}
}
// open stream
camera.open_stream().unwrap();
loop {
if let Ok(frame) = camera.frame() {
println!(
"Captured frame {}x{} @ {}FPS size {}",
frame.width(),
frame.height(),
fps,
frame.len()
);
let _send = send.send(frame);
}
}
}
});
// run glium
if matches.is_present("display") {
let gl_event_loop = EventLoop::new();
let window_builder = WindowBuilder::new();
let context_builder = ContextBuilder::new().with_vsync(true);
let gl_display = Display::new(window_builder, context_builder, &gl_event_loop).unwrap();
implement_vertex!(Vertex, position, tex_coords);
let vert_buffer = VertexBuffer::new(
&gl_display,
&[
Vertex {
position: [-1.0, -1.0],
tex_coords: [0.0, 0.0],
},
Vertex {
position: [-1.0, 1.0],
tex_coords: [0.0, 1.0],
},
Vertex {
position: [1.0, 1.0],
tex_coords: [1.0, 1.0],
},
Vertex {
position: [1.0, -1.0],
tex_coords: [1.0, 0.0],
},
],
)
.unwrap();
let idx_buf =
IndexBuffer::new(&gl_display, PrimitiveType::TriangleStrip, &[1_u16, 2, 0, 3])
.unwrap();
let program = program!(&gl_display,
140 => {
vertex: "
#version 140
uniform mat4 matrix;
in vec2 position;
in vec2 tex_coords;
out vec2 v_tex_coords;
void main() {
gl_Position = matrix * vec4(position, 0.0, 1.0);
v_tex_coords = tex_coords;
}
",
outputs_srgb: true,
fragment: "
#version 140
uniform sampler2D tex;
in vec2 v_tex_coords;
out vec4 f_color;
void main() {
f_color = texture(tex, v_tex_coords);
}
"
},
)
.unwrap();
// run the event loop
gl_event_loop.run(move |event, _window, ctrl| {
*ctrl = match event {
Event::MainEventsCleared => {
let instant = Instant::now();
let frame = recv.recv().unwrap();
let capture_elapsed = instant.elapsed().as_millis();
let frame_size = (frame.width(), frame.height());
let raw_data = RawImage2d::from_raw_rgb(frame.into_raw(), frame_size);
let gl_texture = Texture2d::new(&gl_display, raw_data).unwrap();
let uniforms = uniform! {
matrix: [
[1.0, 0.0, 0.0, 0.0],
[0.0, -1.0, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 1.0f32]
],
tex: &gl_texture
};
let mut target = gl_display.draw();
target.clear_color(0.0, 0.0, 0.0, 0.0);
target
.draw(
&vert_buffer,
&idx_buf,
&program,
&uniforms,
&Default::default(),
)
.unwrap();
target.finish().unwrap();
println!("Took {capture_elapsed}ms to capture",);
ControlFlow::Poll
}
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => ControlFlow::Exit,
_ => ControlFlow::Poll,
}
})
}
// dont
else {
loop {
if let Ok(frame) = recv.recv() {
println!(
"Frame width {} height {} size {}",
frame.width(),
frame.height(),
frame.len()
);
} else {
println!("Thread terminated, closing!");
break;
}
}
}
}
}
fn main() {}
+18
View File
@@ -1,3 +1,21 @@
#![deny(clippy::pedantic)]
#![warn(clippy::all)]
/*
* Copyright 2022 l1npengtul <l1npengtul@protonmail.com> / The Nokhwa Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//! Core type definitions for `nokhwa`
pub mod buffer;
pub mod error;
+5 -13
View File
@@ -210,6 +210,7 @@ impl FormatDecoder for LumaFormat {
&[FrameFormat::MJPEG, FrameFormat::YUYV, FrameFormat::GRAY];
#[allow(clippy::cast_possible_truncation)]
#[allow(clippy::cast_sign_loss)]
fn write_output(
fcc: FrameFormat,
resolution: Resolution,
@@ -246,7 +247,7 @@ impl FormatDecoder for LumaFormat {
FrameFormat::GRAY => Ok(data.to_vec()),
FrameFormat::RAWRGB => Ok(data
.chunks(3)
.map(|px| ((px[0] as i32 + px[1] as i32 + px[2] as i32) / 3) as u8)
.map(|px| ((i32::from(px[0]) + i32::from(px[1]) + i32::from(px[2])) / 3) as u8)
.collect()),
}
}
@@ -258,24 +259,15 @@ impl FormatDecoder for LumaFormat {
dest: &mut [u8],
) -> Result<(), NokhwaError> {
match fcc {
FrameFormat::MJPEG => {
// FIXME: implement!
// TODO: implement!
FrameFormat::MJPEG | FrameFormat::YUYV | FrameFormat::NV12 => {
Err(NokhwaError::ProcessFrameError {
src: fcc,
destination: "Luma => RGB".to_string(),
error: "Conversion Error".to_string(),
})
}
FrameFormat::YUYV => Err(NokhwaError::ProcessFrameError {
src: fcc,
destination: "Luma => RGB".to_string(),
error: "Conversion Error".to_string(),
}),
FrameFormat::NV12 => Err(NokhwaError::ProcessFrameError {
src: fcc,
destination: "Luma => RGB".to_string(),
error: "Conversion Error".to_string(),
}),
FrameFormat::GRAY => {
data.iter().zip(dest.iter_mut()).for_each(|(pxv, d)| {
*d = *pxv;
+56 -47
View File
@@ -36,7 +36,7 @@ impl Default for RequestedFormatType {
impl Display for RequestedFormatType {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
write!(f, "{self:?}")
}
}
@@ -50,6 +50,7 @@ pub struct RequestedFormat<'a> {
impl RequestedFormat<'_> {
/// Creates a new [`RequestedFormat`] by using the [`RequestedFormatType`] and getting the [`FrameFormat`]
/// constraints from a generic type.
#[must_use]
pub fn new<Decoder: FormatDecoder>(requested: RequestedFormatType) -> RequestedFormat<'static> {
RequestedFormat {
requested_format: requested,
@@ -59,6 +60,7 @@ impl RequestedFormat<'_> {
/// Creates a new [`RequestedFormat`] by using the [`RequestedFormatType`] and getting the [`FrameFormat`]
/// constraints from a statically allocated slice.
#[must_use]
pub fn with_formats(
requested: RequestedFormatType,
decoder: &[FrameFormat],
@@ -70,6 +72,7 @@ impl RequestedFormat<'_> {
}
/// Gets the [`RequestedFormatType`]
#[must_use]
pub fn requested_format_type(&self) -> RequestedFormatType {
self.requested_format
}
@@ -77,11 +80,13 @@ impl RequestedFormat<'_> {
/// Fulfill the requested using a list of all available formats.
///
/// See [`RequestedFormatType`] for more details.
#[must_use]
#[allow(clippy::too_many_lines)]
pub fn fulfill(&self, all_formats: &[CameraFormat]) -> Option<CameraFormat> {
match self.requested_format {
RequestedFormatType::HighestResolutionAbs => {
let mut formats = all_formats.to_vec();
formats.sort_by_key(|a| a.resolution());
formats.sort_by_key(CameraFormat::resolution);
let resolution = *formats.iter().last()?;
let mut format_resolutions = formats
.into_iter()
@@ -90,12 +95,12 @@ impl RequestedFormat<'_> {
&& self.wanted_decoder.contains(&fmt.format())
})
.collect::<Vec<CameraFormat>>();
format_resolutions.sort_by_key(|a| a.frame_rate());
format_resolutions.sort_by_key(CameraFormat::frame_rate);
format_resolutions.last().copied()
}
RequestedFormatType::HighestFrameRateAbs => {
let mut formats = all_formats.to_vec();
formats.sort_by_key(|a| a.frame_rate());
formats.sort_by_key(CameraFormat::resolution);
let frame_rate = *formats.iter().last()?;
let mut format_framerates = formats
.into_iter()
@@ -104,7 +109,7 @@ impl RequestedFormat<'_> {
&& self.wanted_decoder.contains(&fmt.format())
})
.collect::<Vec<CameraFormat>>();
format_framerates.sort_by_key(|a| a.resolution());
format_framerates.sort_by_key(CameraFormat::resolution);
format_framerates.last().copied()
}
RequestedFormatType::HighestResolution(fps) => {
@@ -146,6 +151,7 @@ impl RequestedFormat<'_> {
None
}
}
#[allow(clippy::cast_possible_wrap)]
RequestedFormatType::Closest(c) => {
let same_fmt_formats = all_formats
.iter()
@@ -185,7 +191,7 @@ impl RequestedFormat<'_> {
(abs.unsigned_abs(), *x)
})
.collect::<Vec<(u32, u32)>>();
framerate_map.sort();
framerate_map.sort_by(|a, b| a.0.cmp(&b.0));
let frame_rate = framerate_map.first()?.1;
Some(CameraFormat::new(resolution, c.format(), frame_rate))
}
@@ -199,13 +205,13 @@ impl RequestedFormat<'_> {
impl Display for RequestedFormat<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
write!(f, "{self:?}")
}
}
/// Describes the index of the camera.
/// - Index: A numbered index
/// - String: A string, used for IPCameras.
/// - String: A string, used for `IPCameras`.
#[derive(Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub enum CameraIndex {
@@ -724,7 +730,7 @@ pub enum KnownCameraControlFlag {
impl Display for KnownCameraControlFlag {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
write!(f, "{self:?}")
}
}
@@ -1002,11 +1008,7 @@ impl Display for ControlValueDescription {
default,
step,
} => {
write!(
f,
"(Current: {}, Default: {}, Step: {})",
value, default, step
)
write!(f, "(Current: {value}, Default: {default}, Step: {step})",)
}
ControlValueDescription::IntegerRange {
min,
@@ -1017,8 +1019,7 @@ impl Display for ControlValueDescription {
} => {
write!(
f,
"(Current: {}, Default: {}, Step: {}, Range: ({}, {}))",
value, default, step, min, max
"(Current: {value}, Default: {default}, Step: {step}, Range: ({min}, {max}))",
)
}
ControlValueDescription::Float {
@@ -1026,11 +1027,7 @@ impl Display for ControlValueDescription {
default,
step,
} => {
write!(
f,
"(Current: {}, Default: {}, Step: {})",
value, default, step
)
write!(f, "(Current: {value}, Default: {default}, Step: {step})",)
}
ControlValueDescription::FloatRange {
min,
@@ -1041,18 +1038,17 @@ impl Display for ControlValueDescription {
} => {
write!(
f,
"(Current: {}, Default: {}, Step: {}, Range: ({}, {}))",
value, default, step, min, max
"(Current: {value}, Default: {default}, Step: {step}, Range: ({min}, {max}))",
)
}
ControlValueDescription::Boolean { value, default } => {
write!(f, "(Current: {}, Default: {})", value, default)
write!(f, "(Current: {value}, Default: {default})")
}
ControlValueDescription::String { value, default } => {
write!(f, "(Current: {}, Default: {:?})", value, default)
write!(f, "(Current: {value}, Default: {default:?})")
}
ControlValueDescription::Bytes { value, default } => {
write!(f, "(Current: {:x?}, Default: {:x?})", value, default)
write!(f, "(Current: {value:x?}, Default: {default:x?})")
}
ControlValueDescription::KeyValuePair {
key,
@@ -1061,8 +1057,8 @@ impl Display for ControlValueDescription {
} => {
write!(
f,
"Current: ({}, {}), Default: ({}, {})",
key, value, default.0, default.1
"Current: ({key}, {value}), Default: ({}, {})",
default.0, default.1
)
}
ControlValueDescription::Point { value, default } => {
@@ -1079,8 +1075,7 @@ impl Display for ControlValueDescription {
} => {
write!(
f,
"Current: {}, Possible Values: {:?}, Default: {}",
value, possible, default
"Current: {value}, Possible Values: {possible:?}, Default: {default}",
)
}
ControlValueDescription::RGB {
@@ -1215,6 +1210,7 @@ pub enum ControlValueSetter {
}
impl ControlValueSetter {
#[must_use]
pub fn as_none(&self) -> Option<()> {
if let ControlValueSetter::None = self {
Some(())
@@ -1222,6 +1218,7 @@ impl ControlValueSetter {
None
}
}
#[must_use]
pub fn as_integer(&self) -> Option<&i64> {
if let ControlValueSetter::Integer(i) = self {
@@ -1230,6 +1227,7 @@ impl ControlValueSetter {
None
}
}
#[must_use]
pub fn as_float(&self) -> Option<&f64> {
if let ControlValueSetter::Float(f) = self {
@@ -1238,6 +1236,8 @@ impl ControlValueSetter {
None
}
}
#[must_use]
pub fn as_boolean(&self) -> Option<&bool> {
if let ControlValueSetter::Boolean(f) = self {
Some(f)
@@ -1245,6 +1245,8 @@ impl ControlValueSetter {
None
}
}
#[must_use]
pub fn as_str(&self) -> Option<&str> {
if let ControlValueSetter::String(s) = self {
Some(s)
@@ -1252,6 +1254,8 @@ impl ControlValueSetter {
None
}
}
#[must_use]
pub fn as_bytes(&self) -> Option<&[u8]> {
if let ControlValueSetter::Bytes(b) = self {
Some(b)
@@ -1259,6 +1263,8 @@ impl ControlValueSetter {
None
}
}
#[must_use]
pub fn as_key_value(&self) -> Option<(&i128, &i128)> {
if let ControlValueSetter::KeyValue(k, v) = self {
Some((k, v))
@@ -1266,6 +1272,7 @@ impl ControlValueSetter {
None
}
}
#[must_use]
pub fn as_point(&self) -> Option<(&f64, &f64)> {
if let ControlValueSetter::Point(x, y) = self {
@@ -1274,6 +1281,7 @@ impl ControlValueSetter {
None
}
}
#[must_use]
pub fn as_enum(&self) -> Option<&i64> {
if let ControlValueSetter::EnumValue(e) = self {
@@ -1282,6 +1290,7 @@ impl ControlValueSetter {
None
}
}
#[must_use]
pub fn as_rgb(&self) -> Option<(&f64, &f64, &f64)> {
if let ControlValueSetter::RGB(r, g, b) = self {
@@ -1299,31 +1308,31 @@ impl Display for ControlValueSetter {
write!(f, "Value: None")
}
ControlValueSetter::Integer(i) => {
write!(f, "IntegerValue: {}", i)
write!(f, "IntegerValue: {i}")
}
ControlValueSetter::Float(d) => {
write!(f, "FloatValue: {}", d)
write!(f, "FloatValue: {d}")
}
ControlValueSetter::Boolean(b) => {
write!(f, "BoolValue: {}", b)
write!(f, "BoolValue: {b}")
}
ControlValueSetter::String(s) => {
write!(f, "StrValue: {}", s)
write!(f, "StrValue: {s}")
}
ControlValueSetter::Bytes(b) => {
write!(f, "BytesValue: {:x?}", b)
write!(f, "BytesValue: {b:x?}")
}
ControlValueSetter::KeyValue(k, v) => {
write!(f, "KVValue: ({}, {})", k, v)
write!(f, "KVValue: ({k}, {v})")
}
ControlValueSetter::Point(x, y) => {
write!(f, "PointValue: ({}, {})", x, y)
write!(f, "PointValue: ({x}, {y})")
}
ControlValueSetter::EnumValue(v) => {
write!(f, "EnumValue: {}", v)
write!(f, "EnumValue: {v}")
}
ControlValueSetter::RGB(r, g, b) => {
write!(f, "RGBValue: ({}, {}, {})", r, g, b)
write!(f, "RGBValue: ({r}, {g}, {b})")
}
}
}
@@ -1357,8 +1366,7 @@ pub enum ApiBackend {
impl Display for ApiBackend {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let self_str = format!("{:?}", self);
write!(f, "{}", self_str)
write!(f, "{self:?}")
}
}
@@ -1705,6 +1713,7 @@ pub fn yuv_420_to_rgb(
/// Converts a YUYV 4:2:0 datastream to a RGB888 Stream and outputs it into a destination buffer. [For further reading](https://en.wikipedia.org/wiki/YUV#Converting_between_Y%E2%80%B2UV_and_RGB)
/// # Errors
/// This may error when the data stream size is wrong.
#[allow(clippy::similar_names)]
pub fn buf_yuv_420_to_rgb(
resolution: Resolution,
data: &[u8],
@@ -1752,14 +1761,14 @@ pub fn buf_yuv_420_to_rgb(
let r0_idx = ((w * 2) + (h * resolution.width())) as usize;
let r1_idx = ((w * 2) + ((h + 1) * resolution.width())) as usize;
let y0 = data[r0_idx] as i32;
let y1 = data[r0_idx + 1] as i32;
let y2 = data[r1_idx] as i32;
let y3 = data[r1_idx + 1] as i32;
let y0 = i32::from(data[r0_idx]);
let y1 = i32::from(data[r0_idx + 1]);
let y2 = i32::from(data[r1_idx]);
let y3 = i32::from(data[r1_idx + 1]);
let cell_number = (h * resolution.width()) + h;
let u0 = data[(u_values_start + cell_number) as usize] as i32;
let v0 = data[(v_values_start + cell_number) as usize] as i32;
let u0 = i32::from(data[(u_values_start + cell_number) as usize]);
let v0 = i32::from(data[(v_values_start + cell_number) as usize]);
if rgba {
let rgb0 = yuyv444_to_rgba(y0, u0, v0);