remove dependency on fast-image-resize crate

This commit is contained in:
nworbnhoj 2022-06-18 12:07:58 +10:00
parent 81ebb74b58
commit 2dbdb10704
3 changed files with 55 additions and 50 deletions

View file

@ -352,6 +352,31 @@ impl Img {
pub fn as_slice(&self) -> &[u8] {
self.pixels.as_slice()
}
// simply retains the closest pixel
pub fn resize(&self, width: usize, height: usize) -> Img {
let mut buf = vec![0u8; (width * height).try_into().unwrap()];
let (self_width, self_height, _) = self.size();
let x_scale = self_width as f32 / width as f32;
let y_scale = self_height as f32 / height as f32;
let self_x_base = x_scale * 0.5;
let self_y_base = y_scale * 0.5;
// Pretabulate horizontal pixel positions
let mut self_x_tab: Vec<usize> = Vec::with_capacity(width);
for buf_x in 0..width {
self_x_tab.push(((self_x_base + x_scale * buf_x as f32) as usize).min(self_width - 1));
}
for buf_y in 0..height {
let self_y = ((self_y_base + y_scale * buf_y as f32) as usize).min(self_height - 1);
let self_row = self_y * self_width;
let buf_row = buf_y * width;
for (buf_x, self_x) in self_x_tab.iter().enumerate() {
buf[buf_row + buf_x] = self.pixels[self_row + self_x];
}
}
Img::new(buf, width.try_into().unwrap(), PixelType::U8)
}
}
/*

View file

@ -22,12 +22,10 @@ tts-frontend = {path="../tts"}
locales = {path = "../../locales"}
bit_field = "0.9.0"
fast_image_resize = {version = "0.9.2", optional = true}
[target.'cfg(not(any(windows,unix)))'.dependencies]
utralib = { path = "../../utralib"}
[features]
tts = []
ditherpunk = ["fast_image_resize"]
ditherpunk = []
default = []

View file

@ -10,10 +10,6 @@ use gam::*;
use num_traits::*;
#[cfg(feature = "ditherpunk")]
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;
@ -201,7 +197,8 @@ impl Modals {
pub fn show_image(&self, img: &Img) -> Result<(), xous::Error> {
self.lock();
// resize and/or rotate
let (modal_width, modal_height) = (gam::IMG_MODAL_WIDTH as f32, gam::IMG_MODAL_HEIGHT as f32);
let (modal_width, modal_height) =
(gam::IMG_MODAL_WIDTH as f32, gam::IMG_MODAL_HEIGHT as f32);
let (w, h, _) = img.size();
let (img_width, img_height) = (w as f32, h as f32);
@ -209,13 +206,19 @@ impl Modals {
let landscape_scale = (modal_width / img_height).min(modal_height / img_width);
let mut bm = if portrait_scale >= 1.0 {
Bitmap::from(img)
} else if landscape_scale >= 1.0 {
} else if landscape_scale >= 1.0 {
Bitmap::from(img).rotate90()
} else if portrait_scale >= landscape_scale {
let resized = Modals::resize_image(img, portrait_scale);
let resized = img.resize(
(portrait_scale * img_width) as usize,
(portrait_scale * img_height) as usize,
);
Bitmap::from(&resized)
} else {
let resized = Modals::resize_image(img, landscape_scale);
let resized = img.resize(
(landscape_scale * img_width) as usize,
(landscape_scale * img_height) as usize,
);
Bitmap::from(&resized).rotate90()
};
@ -225,8 +228,10 @@ impl Modals {
// center image in modal
let center = Point::new(
((gam::IMG_MODAL_WIDTH - bm_width) / 2).try_into().unwrap(),
((gam::IMG_MODAL_HEIGHT - bm_height) / 2).try_into().unwrap(),
);
((gam::IMG_MODAL_HEIGHT - bm_height) / 2)
.try_into()
.unwrap(),
);
bm.translate(center);
let mut tiles: [Option<Tile>; 6] = [None; 6];
@ -248,38 +253,6 @@ impl Modals {
Ok(())
}
#[allow(dead_code)]
#[cfg(feature = "ditherpunk")]
fn resize_image(img: &Img, scale: f32) -> Img {
let (w, h, _) = img.size();
let (img_width, img_height) = (w as f32, h as f32);
let height: u32 = (scale * img_height).floor() as u32;
let width: u32 = (scale * img_width).floor() as u32;
let fir_img = fast_image_resize::Image::from_vec_u8(
NonZeroU32::new(width).unwrap(),
NonZeroU32::new(height).unwrap(),
img.as_slice().to_vec(),
fast_image_resize::PixelType::U8,
)
.unwrap();
// Create container for data of destination image
let mut resized = fast_image_resize::Image::new(
NonZeroU32::new(width).unwrap(),
NonZeroU32::new(height).unwrap(),
fir_img.pixel_type(),
);
let mut rsz_view = resized.view_mut();
// resize image with fastest available algorithm
let mut resizer = fast_image_resize::Resizer::new(fast_image_resize::ResizeAlg::Nearest);
resizer.resize(&fir_img.view(), &mut rsz_view).unwrap();
let width: usize = resized.width().get().try_into().unwrap();
Img::new(resized.into_vec(), width, PixelType::U8x3)
}
pub fn start_progress(
&self,
title: &str,
@ -532,10 +505,14 @@ impl Modals {
fn unlock(&self) {
self.have_lock.set(false);
}
pub fn conn(&self) -> CID {self.conn}
pub fn conn(&self) -> CID {
self.conn
}
/// Don't leak this token outside of your server, otherwise, another server can pretend to be you and
/// steal your modal information!
pub fn token(&self) -> [u32; 4] {self.token}
pub fn token(&self) -> [u32; 4] {
self.token
}
}
use core::sync::atomic::{AtomicU32, Ordering};
@ -563,7 +540,10 @@ impl Drop for Modals {
///
/// This function is "broken out" so that it can be called from a thread without having
/// to wrap a mutex around the primary Modals structure.
pub fn dynamic_notification_blocking_listener(token: [u32; 4], conn: CID) -> Result<Option<char>, xous::Error> {
pub fn dynamic_notification_blocking_listener(
token: [u32; 4],
conn: CID,
) -> Result<Option<char>, xous::Error> {
match send_message(
conn,
Message::new_blocking_scalar(
@ -573,7 +553,9 @@ pub fn dynamic_notification_blocking_listener(token: [u32; 4], conn: CID) -> Res
token[2] as usize,
token[3] as usize,
),
).expect("couldn't listen") {
)
.expect("couldn't listen")
{
xous::Result::Scalar2(is_some, code) => {
if is_some == 1 {
let c = char::from_u32(code as u32).unwrap_or('\u{0000}');
@ -585,6 +567,6 @@ pub fn dynamic_notification_blocking_listener(token: [u32; 4], conn: CID) -> Res
Ok(None)
}
}
_ => Err(xous::Error::InternalError)
_ => Err(xous::Error::InternalError),
}
}