From 409f696fdeac4ed572845f68ffe4cab0cb2a04f3 Mon Sep 17 00:00:00 2001 From: nworbnhoj Date: Sat, 18 Jun 2022 08:43:24 +1000 Subject: [PATCH] Implement gam::PixelType enables gam::Img to import different image formats: U8 & U8x3 for now --- services/gam/src/bitmap.rs | 36 +++++++++++++++++++------- services/gam/src/lib.rs | 2 +- services/modals/src/lib.rs | 4 ++- services/modals/src/tests.rs | 4 ++- services/shellchat/src/cmds/net_cmd.rs | 6 ++--- 5 files changed, 37 insertions(+), 15 deletions(-) diff --git a/services/gam/src/bitmap.rs b/services/gam/src/bitmap.rs index f57dec177..e7022554c 100644 --- a/services/gam/src/bitmap.rs +++ b/services/gam/src/bitmap.rs @@ -290,6 +290,12 @@ impl From<&Img> for Bitmap { } } +pub enum PixelType { + U8, + U8x3, + U8x4, +} + /* * Image as a minimal flat buffer of grey u8 pixels; accessible by (x, y) * @@ -303,21 +309,33 @@ pub struct Img { } impl Img { - pub fn new(buf: Vec, width: usize) -> Self { + pub fn new(buf: Vec, width: usize, px_type: PixelType) -> Self { const R: u32 = 2126; const G: u32 = 7152; const B: u32 = 722; const BLACK: u32 = R + G + B; - let px_len = buf.len() / 3; + let px_len = match px_type { + PixelType::U8 => buf.len(), + PixelType::U8x3 => buf.len() / 3, + _ => 0, + }; let mut pixels: Vec = Vec::with_capacity(px_len); for px in 0..px_len { - let b = px * 3; - let grey_r = R * buf[b] as u32; - let grey_g = G * buf[b + 1] as u32; - let grey_b = B * buf[b + 2] as u32; - pixels.push(((grey_r + grey_g + grey_b) / BLACK) - .try_into() - .unwrap()); + let pixel: u8 = match px_type { + PixelType::U8 => buf[px], + PixelType::U8x3 => { + let b = px * 3; + let grey_r = R * buf[b] as u32; + let grey_g = G * buf[b + 1] as u32; + let grey_b = B * buf[b + 2] as u32; + ((grey_r + grey_g + grey_b) / BLACK).try_into().unwrap() + } + _ => { + log::warn!("unsupported PixelType"); + 0 + } + }; + pixels.push(pixel); } Self { pixels, width } } diff --git a/services/gam/src/lib.rs b/services/gam/src/lib.rs index 2ca97ab0b..ff6240b32 100644 --- a/services/gam/src/lib.rs +++ b/services/gam/src/lib.rs @@ -13,7 +13,7 @@ pub use apps::*; #[cfg(feature="ditherpunk")] pub mod bitmap; #[cfg(feature="ditherpunk")] -pub use bitmap::{Bitmap, Img}; +pub use bitmap::{Bitmap, Img, PixelType}; use graphics_server::api::{TextOp, TextView}; use graphics_server::api::{Gid, Line, Circle, RoundedRectangle, TokenClaim}; diff --git a/services/modals/src/lib.rs b/services/modals/src/lib.rs index 06bd68fbd..aa90ca5a5 100644 --- a/services/modals/src/lib.rs +++ b/services/modals/src/lib.rs @@ -12,6 +12,8 @@ use num_traits::*; use std::convert::TryInto; #[cfg(feature = "ditherpunk")] use std::num::NonZeroU32; +#[cfg(feature = "ditherpunk")] +use bitmap::PixelType; use xous::{send_message, Message, CID}; use xous_ipc::Buffer; @@ -280,7 +282,7 @@ impl Modals { resizer.resize(&fir_img.view(), &mut rsz_view).unwrap(); let width: usize = resized.width().get().try_into().unwrap(); - Img::new(resized.into_vec(), width ) + Img::new(resized.into_vec(), width, PixelType::U8x3) } pub fn start_progress( diff --git a/services/modals/src/tests.rs b/services/modals/src/tests.rs index 3bb10811e..a899a5a28 100644 --- a/services/modals/src/tests.rs +++ b/services/modals/src/tests.rs @@ -2,6 +2,8 @@ use super::*; use gam::*; use std::thread; use xous_names::XousNames; +#[cfg(feature = "ditherpunk")] +use bitmap::PixelType; const RADIO_TEST: [&'static str; 4] = ["zebra", "cow", "horse", "cat"]; @@ -196,7 +198,7 @@ fn clifford() -> Img { (rgb[j], rgb[j + 1], rgb[j + 2]) = (buf[i], buf[i], buf[i]); i += 1; } - Img::new(rgb, SIZE.try_into().unwrap()) + Img::new(rgb, SIZE.try_into().unwrap(), PixelType::U8x3) } fn test_validator(input: TextEntryPayload) -> Option> { diff --git a/services/shellchat/src/cmds/net_cmd.rs b/services/shellchat/src/cmds/net_cmd.rs index 16820b637..806568460 100644 --- a/services/shellchat/src/cmds/net_cmd.rs +++ b/services/shellchat/src/cmds/net_cmd.rs @@ -17,7 +17,7 @@ use dns::Dns; // necessary to work around https://github.com/rust-lang/rust/issu #[cfg(feature="ditherpunk")] use std::str::FromStr; #[cfg(feature="ditherpunk")] -use gam::Img; +use gam::{Img, PixelType}; pub struct NetCmd { callback_id: Option, @@ -389,7 +389,7 @@ impl<'a> ShellCmdApi<'a> for NetCmd { let (width, height) = (info.width, info.height); log::info!("image is {} x {}", width, height); log::info!("some image bytes: {:x?}", &buf[..64]); - let img = Img::new(buf, width as usize); + let img = Img::new(buf, width as usize, PixelType::U8x3); modals.show_image(&img).expect("show image modal failed"); write!(ret, "Image of {} bytes read successfully", content_length).unwrap(); @@ -700,4 +700,4 @@ impl Worker { thread: Some(thread), } } -} \ No newline at end of file +}