Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
rsuu committed Dec 11, 2022
1 parent a7ecaa2 commit b3bc693
Show file tree
Hide file tree
Showing 15 changed files with 1,985 additions and 258 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 8 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rmg"
version = "0.2.4"
version = "0.3.0"
edition = "2021"
authors = ["RSUU <[email protected]>"]
description = "Rust: Tiny Manga/Image Viewer"
Expand Down Expand Up @@ -51,9 +51,9 @@ asefile ={ version = "0.3.5", optional = true }
gif = "0.12.0"
gif-dispose = "4"
# svg
usvg = "0.27.0"
tiny-skia = "0.8.2"
resvg = "0.27.0"
usvg ={ version = "0.27.0", optional = true }
tiny-skia ={ version = "0.8.2", optional = true }
resvg ={ version = "0.27.0", optional = true }

# args
lexopt = "0.2.1"
Expand Down Expand Up @@ -92,6 +92,9 @@ ex_tar = ["dep:zip"]
sse4_1 = []
avx2 = []


# image
de_all = ["de_heic","de_aseprite","de_svg"]
de_heic = ["dep:libheif-rs"]
de_ase = ["dep:asefile"]
de_aseprite = ["dep:asefile"]
de_svg= ["dep:usvg","dep:tiny-skia","dep:resvg"]
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ q | quit
.heic / .avif|🔬|❌|libheif
.gif|🔬|✅|
.aseprite|🔬|❌|
.svg|🔬|❌|

---
| Format | Supported | Default |Dependency
Expand All @@ -89,7 +90,10 @@ cargo run --release -F "de_heic"


# for heic AND aseprite
cargo run --release -F "de_heic" -F "de_ase"
cargo run --release -F "de_heic" -F "de_aseprite"

# for svg
cargo run --release -F "de_svg"

# [CpuExtensions](https://docs.rs/fast_image_resize/latest/fast_image_resize/index.html#resize-rgb8-image-u8x3-4928x3279--852x567)
cargo run --release -F "avx2"
Expand Down
44 changes: 29 additions & 15 deletions src/color/rgba.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,29 @@ impl TransRgba {
pub fn rgba_as_argb_u32(r: &u8, g: &u8, b: &u8, a: &u8) -> u32 {
// (r, g, b, a) -> (a, r, g, b) -> u32
// 3 2 1 0 3 2 1 0
((*r as u32) << 8 * 2)
+ ((*g as u32) << 8 * 1)
+ ((*b as u32) << 8 * 0)
+ ((*a as u32) << 8 * 3)
u32::from_be_bytes([*a, *r, *g, *b])
}

#[inline(always)]
pub fn rgba_as_u32(r: &u8, g: &u8, b: &u8, a: &u8) -> u32 {
// (r, g, b, a) -> u32
// 3 2 1 0
((*r as u32) << 8 * 3)
+ ((*g as u32) << 8 * 2)
+ ((*b as u32) << 8 * 1)
+ ((*a as u32) << 8 * 0)
u32::from_be_bytes([*r, *g, *b, *a])
}

#[inline(always)]
pub fn rgba_from_u32(rgba: u32) -> (u8, u8, u8, u8) {
pub fn rgba_from_u32(rgba: &u32) -> [u8; 4] {
// u32 -> (r, g, b, a)
// 3 2 1 0
(
((rgba >> 8 * 3) & 0x0ff) as u8,
((rgba >> 8 * 2) & 0x0ff) as u8,
((rgba >> 8 * 1) & 0x0ff) as u8,
(rgba & 0x0ff) as u8,
)
// [
// ((rgba >> 8 * 3) & 0x0ff) as u8,
// ((rgba >> 8 * 2) & 0x0ff) as u8,
// ((rgba >> 8 * 1) & 0x0ff) as u8,
// (rgba & 0x0ff) as u8,
// ];

// SAFETY
unsafe { std::mem::transmute::<u32, [u8; 4]>(rgba.to_be()) }
}
}

Expand All @@ -49,3 +46,20 @@ impl TransRgba {
// r + g + b + a
// }
// }

mod test {
use super::TransRgba;

#[test]
fn _rgba_as_argb_u32() {}

#[test]
fn _rgba_as_u32() {
assert_eq!(16909060, TransRgba::rgba_as_u32(&1, &2, &3, &4));
}

#[test]
fn _rgba_from_u32() {
assert_eq!([1_u8, 2, 3, 4], TransRgba::rgba_from_u32(&16909060));
}
}
18 changes: 11 additions & 7 deletions src/img/ase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,29 @@ use crate::{
utils::err::{MyErr, Res},
};

pub fn load_ase(bytes: &[u8]) -> Res<(Size<u32>, Vec<Vec<u8>>)> {
pub fn load_ase(bytes: &[u8]) -> Res<(Size<u32>, Vec<Vec<u8>>, Vec<u32>)> {
cfg_if::cfg_if! {
if #[cfg(feature = "de_ase")] {
if #[cfg(feature = "de_aseprite")] {
feat::load_ase(bytes)
} else {
Err(MyErr::FeatAse)
}
}
}

#[cfg(feature = "de_ase")]
#[cfg(feature = "de_aseprite")]
mod feat {
use crate::{
img::size::Size,
reader::view::Page,
utils::err::{MyErr, Res},
FPS,
};
use asefile::AsepriteFile;
use std::mem;

#[inline]
pub fn load_ase(bytes: &[u8]) -> Res<(Size<u32>, Vec<Vec<u8>>)> {
pub fn load_ase(bytes: &[u8]) -> Res<(Size<u32>, Vec<Vec<u8>>, Vec<u32>)> {
let ase = AsepriteFile::read(bytes).unwrap();

let size = Size::new(ase.width() as u32, ase.height() as u32);
Expand All @@ -32,13 +34,15 @@ mod feat {
let tail = ase.num_frames();

let mut data = Vec::with_capacity(tail as usize);
let mut pts_list = Vec::with_capacity(tail as usize);

for idx in head..tail {
let frame = ase.frame(idx);
let mut frame = ase.frame(idx);
pts_list.push(FPS as u32 + frame.duration());

data.push(frame.image().to_vec());
data.push(mem::take(&mut frame.image().to_vec()));
}

Ok((size, data))
Ok((size, data, pts_list))
}
}
23 changes: 12 additions & 11 deletions src/img/gif.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::FPS;
use gif;


use std::io::Read;
use std::mem;

Expand All @@ -10,10 +10,7 @@ use gif_dispose;

use super::size::Size;

pub fn load_gif(bytes: impl Read) -> Res<(Size<u32>, Vec<Vec<u8>>)> {
let mut res = vec![];
let mut buffer_frame = Vec::new();

pub fn load_gif(bytes: impl Read) -> Res<(Size<u32>, Vec<Vec<u8>>, Vec<u32>)> {
let mut gif_opts = gif::DecodeOptions::new();
gif_opts.set_color_output(gif::ColorOutput::Indexed);
let mut decoder = gif_opts.read_info(bytes).unwrap();
Expand All @@ -24,26 +21,30 @@ pub fn load_gif(bytes: impl Read) -> Res<(Size<u32>, Vec<Vec<u8>>)> {
height: decoder.height() as u32,
};

let mut frames = vec![];
let mut buffer_frame = Vec::new();
let mut pts = 0;
let mut pts_list = vec![];

loop {
"decoded frame"._dbg();

if let Some(frame) = decoder.read_next_frame().unwrap() {
screen.blit_frame(frame).unwrap();

for rgba in screen.pixels.buf().iter() {
buffer_frame.push(rgba.r);
buffer_frame.push(rgba.g);
buffer_frame.push(rgba.b);
buffer_frame.push(rgba.a);
buffer_frame.extend_from_slice(&[rgba.r, rgba.g, rgba.b, rgba.a]);
}

res.push(mem::take(&mut buffer_frame));
pts += FPS as u32 + frame.delay as u32;
pts_list.push(pts);
frames.push(mem::take(&mut buffer_frame));
} else {
break;
}
}

Ok((size, res))
Ok((size, frames, pts_list))
}

// image
Expand Down
67 changes: 38 additions & 29 deletions src/img/svg.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,46 @@
use resvg;
use tiny_skia;
use usvg::{self, ScreenRect};
use crate::{
img::size::Size,
utils::err::{MyErr, Res},
};

use crate::utils::err::Res;
pub fn load_svg(bytes: &[u8]) -> Res<(Size<u32>, Vec<Vec<u8>>)> {
cfg_if::cfg_if! {
if #[cfg(feature = "de_svg")] {
feat::load_svg(bytes)
} else {
Err(MyErr::FeatSvg)
}
}
}

use super::size::Size;
#[cfg(feature = "de_svg")]
mod feat {

pub fn load_svg(bytes: &[u8]) -> Res<(Size<u32>, Vec<Vec<u8>>)> {
let size = Size::new(2000, 2000);
let opt = usvg::Options::default();
use crate::{
img::size::Size,
utils::err::{MyErr, Res},
};

if let Ok(rtree) = usvg::Tree::from_data(&bytes, &opt.to_ref()) {
let pixmap_size = rtree
.size
.to_screen_size()
.scale_to(usvg::ScreenSize::new(size.width, size.height).unwrap());
pub fn load_svg(bytes: &[u8]) -> Res<(Size<u32>, Vec<Vec<u8>>)> {
// BUG:
let mut opt = usvg::Options::default();
let rtree = usvg::Tree::from_data(bytes, &opt.to_ref()).unwrap();
let pixmap_size = rtree.size.to_screen_size();
//.scale_to(usvg::ScreenSize::new(size.width, size.height).unwrap());

if let Some(mut pixmap) = tiny_skia::Pixmap::new(pixmap_size.width(), pixmap_size.height())
{
resvg::render(
&rtree,
usvg::FitTo::Height(size.height),
//usvg::FitTo::Original,
tiny_skia::Transform::identity(),
pixmap.as_mut(),
)
.unwrap();
let size = Size::new(pixmap_size.width(), pixmap_size.height());
//let mut pixmap = tiny_skia::Pixmap::new(size.width, size.height).unwrap();
let mut pixmap = tiny_skia::Pixmap::new(pixmap_size.width(), pixmap_size.height()).unwrap();

return Ok((size, vec![pixmap.data().to_vec()]));
} else {
}
} else {
}
resvg::render(
&rtree,
usvg::FitTo::Original,
//usvg::FitTo::Height(size.height),
tiny_skia::Transform::default(),
pixmap.as_mut(),
)
.unwrap();

Err(crate::utils::err::MyErr::Todo)
Ok((size, vec![pixmap.data().to_vec()]))
}
}
13 changes: 2 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub const FPS: u64 = 40; // 1000/25
pub const EXT_LIST: &[&str] = &[
"jpg", "jpeg", "png", "heic", "heif", "avif", "ase", "aseprite", "gif",
"jpg", "jpeg", "png", "heic", "heif", "avif", "ase", "aseprite", "gif", "svg",
];
pub static mut TIMER: usize = 0;

#[inline]
pub fn has_supported(path: &str) -> bool {
Expand All @@ -24,15 +24,6 @@ pub fn has_supported(path: &str) -> bool {

// block | expr | ident | item | lifetime | literal
// meta | pat | pat_param | path | stmt | tt | ty | vis
// #[macro_export]
// macro_rules! unwrap_or_return {
// ( $e:expr , $err:expr) => {
// match $e {
// Ok(x) => x,
// Err(e) => return Err($err(e)),
// }
// };
// }
//
// #[macro_export]
// macro_rules! check {
Expand Down
10 changes: 5 additions & 5 deletions src/reader/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
window::Canvas,
},
utils::err::Res,
FPS,
};
use log::{debug, info};
use std::{
Expand All @@ -17,8 +18,6 @@ use std::{
sync::{Arc, RwLock},
};

const FPS: u128 = 40; // 1000/25

/// display images
pub fn cat_img(
config: &Config,
Expand Down Expand Up @@ -131,6 +130,7 @@ pub fn for_minifb_scroll(
let arc_page: Arc<RwLock<Page>> = Arc::new(RwLock::new(Page::null()));

let mut time_start = std::time::Instant::now();
let mut sleep = FPS;

'l1: while canvas.window.is_open() {
match keymap::match_event(canvas.window.get_keys().iter().as_slice(), keymaps) {
Expand Down Expand Up @@ -194,12 +194,12 @@ pub fn for_minifb_scroll(
buf.flush(canvas, &arc_state);

let now = std::time::Instant::now();
let count = (now - time_start).as_millis();
let count = (now - time_start).as_millis() as u64;

time_start = now;

//debug!("{}", (FPS - (count / 6)));
sleep = FPS.checked_sub(count / 6).unwrap_or(10);

std::thread::sleep(std::time::Duration::from_millis((FPS - (count / 6)) as u64));
std::thread::sleep(std::time::Duration::from_millis(sleep));
}
}
Loading

0 comments on commit b3bc693

Please sign in to comment.