diff --git a/yazi-adaptor/src/image.rs b/yazi-adaptor/src/image.rs index 05ada492..61643206 100644 --- a/yazi-adaptor/src/image.rs +++ b/yazi-adaptor/src/image.rs @@ -1,13 +1,28 @@ -use std::path::{Path, PathBuf}; +use std::{fs::File, io::BufReader, path::{Path, PathBuf}}; use anyhow::Result; -use image::{imageops::FilterType, DynamicImage, ImageFormat}; -use yazi_config::PREVIEW; +use image::{imageops::FilterType, io::Limits, DynamicImage, ImageFormat}; +use yazi_config::{PREVIEW, TASKS}; use yazi_shared::Term; pub struct Image; impl Image { + fn set_limits(mut r: image::io::Reader>) -> image::io::Reader> { + let mut limits = Limits::no_limits(); + if TASKS.image_alloc > 0 { + limits.max_alloc = Some(TASKS.image_alloc as u64); + } + if TASKS.image_bound[0] > 0 { + limits.max_image_width = Some(TASKS.image_bound[0] as u32); + } + if TASKS.image_bound[1] > 0 { + limits.max_image_height = Some(TASKS.image_bound[1] as u32); + } + r.limits(limits); + r + } + pub(super) async fn downscale(path: &Path, size: (u16, u16)) -> Result { let (w, h) = Term::ratio() .map(|(w, h)| { @@ -18,7 +33,7 @@ impl Image { let path = path.to_owned(); let img = tokio::task::spawn_blocking(move || { - image::io::Reader::open(path)?.with_guessed_format()?.decode() + Self::set_limits(image::io::Reader::open(path)?.with_guessed_format()?).decode() }) .await??; @@ -35,7 +50,7 @@ impl Image { pub async fn precache(path: &Path, cache: PathBuf) -> Result<()> { let path = path.to_owned(); let img = tokio::task::spawn_blocking(move || { - image::io::Reader::open(path)?.with_guessed_format()?.decode() + Self::set_limits(image::io::Reader::open(path)?.with_guessed_format()?).decode() }) .await??; @@ -50,7 +65,7 @@ impl Image { .await? } - pub async fn precache_bin(bin: Vec, cache: PathBuf) -> Result<()> { + pub async fn precache_vec(bin: Vec, cache: PathBuf) -> Result<()> { let img = tokio::task::spawn_blocking(move || image::load_from_memory(&bin)).await??; tokio::task::spawn_blocking(move || { diff --git a/yazi-config/preset/yazi.toml b/yazi-config/preset/yazi.toml index 349b836b..36665aa9 100644 --- a/yazi-config/preset/yazi.toml +++ b/yazi-config/preset/yazi.toml @@ -69,6 +69,8 @@ rules = [ micro_workers = 5 macro_workers = 10 bizarre_retry = 5 +image_alloc = 536870912 # 512MB +image_bound = [ 0, 0 ] [plugins] preload = [] diff --git a/yazi-config/src/tasks/tasks.rs b/yazi-config/src/tasks/tasks.rs index 31028e4d..ec73d54a 100644 --- a/yazi-config/src/tasks/tasks.rs +++ b/yazi-config/src/tasks/tasks.rs @@ -11,6 +11,9 @@ pub struct Tasks { pub macro_workers: u8, #[validate(range(min = 1, message = "Cannot be less than 1"))] pub bizarre_retry: u8, + + pub image_alloc: u32, + pub image_bound: [u16; 2], } impl Default for Tasks { diff --git a/yazi-core/src/external/pdftoppm.rs b/yazi-core/src/external/pdftoppm.rs index 77f71ba7..763612d3 100644 --- a/yazi-core/src/external/pdftoppm.rs +++ b/yazi-core/src/external/pdftoppm.rs @@ -25,5 +25,5 @@ pub async fn pdftoppm(src: &Path, dest: &Path, skip: usize) -> Result<(), PeekEr return if pages > 0 { Err(PeekError::Exceed(pages - 1)) } else { Err(s.to_string().into()) }; } - Ok(Image::precache_bin(output.stdout, dest.to_owned()).await?) + Ok(Image::precache_vec(output.stdout, dest.to_owned()).await?) }