feat: expose image max alloc and bound to allow for more control (#376)

This commit is contained in:
三咲雅 · Misaki Masa 2023-11-18 10:01:05 +08:00 committed by GitHub
parent bb2353c7b9
commit f3e45d4a47
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 7 deletions

View file

@ -1,13 +1,28 @@
use std::path::{Path, PathBuf}; use std::{fs::File, io::BufReader, path::{Path, PathBuf}};
use anyhow::Result; use anyhow::Result;
use image::{imageops::FilterType, DynamicImage, ImageFormat}; use image::{imageops::FilterType, io::Limits, DynamicImage, ImageFormat};
use yazi_config::PREVIEW; use yazi_config::{PREVIEW, TASKS};
use yazi_shared::Term; use yazi_shared::Term;
pub struct Image; pub struct Image;
impl Image { impl Image {
fn set_limits(mut r: image::io::Reader<BufReader<File>>) -> image::io::Reader<BufReader<File>> {
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<DynamicImage> { pub(super) async fn downscale(path: &Path, size: (u16, u16)) -> Result<DynamicImage> {
let (w, h) = Term::ratio() let (w, h) = Term::ratio()
.map(|(w, h)| { .map(|(w, h)| {
@ -18,7 +33,7 @@ impl Image {
let path = path.to_owned(); let path = path.to_owned();
let img = tokio::task::spawn_blocking(move || { 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??; .await??;
@ -35,7 +50,7 @@ impl Image {
pub async fn precache(path: &Path, cache: PathBuf) -> Result<()> { pub async fn precache(path: &Path, cache: PathBuf) -> Result<()> {
let path = path.to_owned(); let path = path.to_owned();
let img = tokio::task::spawn_blocking(move || { 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??; .await??;
@ -50,7 +65,7 @@ impl Image {
.await? .await?
} }
pub async fn precache_bin(bin: Vec<u8>, cache: PathBuf) -> Result<()> { pub async fn precache_vec(bin: Vec<u8>, cache: PathBuf) -> Result<()> {
let img = tokio::task::spawn_blocking(move || image::load_from_memory(&bin)).await??; let img = tokio::task::spawn_blocking(move || image::load_from_memory(&bin)).await??;
tokio::task::spawn_blocking(move || { tokio::task::spawn_blocking(move || {

View file

@ -69,6 +69,8 @@ rules = [
micro_workers = 5 micro_workers = 5
macro_workers = 10 macro_workers = 10
bizarre_retry = 5 bizarre_retry = 5
image_alloc = 536870912 # 512MB
image_bound = [ 0, 0 ]
[plugins] [plugins]
preload = [] preload = []

View file

@ -11,6 +11,9 @@ pub struct Tasks {
pub macro_workers: u8, pub macro_workers: u8,
#[validate(range(min = 1, message = "Cannot be less than 1"))] #[validate(range(min = 1, message = "Cannot be less than 1"))]
pub bizarre_retry: u8, pub bizarre_retry: u8,
pub image_alloc: u32,
pub image_bound: [u16; 2],
} }
impl Default for Tasks { impl Default for Tasks {

View file

@ -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()) }; 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?)
} }