mirror of
https://github.com/LinuxBeginnings/swww.git
synced 2026-01-12 07:21:01 -03:00
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -244,7 +244,7 @@ checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||
|
||||
[[package]]
|
||||
name = "common"
|
||||
version = "0.9.5-masterV2"
|
||||
version = "0.9.5-masterV3"
|
||||
dependencies = [
|
||||
"criterion",
|
||||
"fastrand",
|
||||
@@ -853,7 +853,7 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "swww"
|
||||
version = "0.9.5-masterV2"
|
||||
version = "0.9.5-masterV3"
|
||||
dependencies = [
|
||||
"assert_cmd",
|
||||
"clap",
|
||||
@@ -866,7 +866,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swww-daemon"
|
||||
version = "0.9.5-masterV2"
|
||||
version = "0.9.5-masterV3"
|
||||
dependencies = [
|
||||
"common",
|
||||
"keyframe",
|
||||
|
||||
@@ -5,7 +5,7 @@ members = ["client", "daemon", "common"]
|
||||
default-members = ["client", "daemon"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.9.5-masterV2"
|
||||
version = "0.9.5-masterV3"
|
||||
authors = ["Leonardo Gibrowski Faé <leonardo.fae44@gmail.com>"]
|
||||
edition = "2021"
|
||||
license-file = "LICENSE"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/// Note: this file only has basic declarations and some definitions in order to be possible to
|
||||
/// import it in the build script, to automate shell completion
|
||||
use clap::{Parser, ValueEnum};
|
||||
use std::fmt::Display;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn from_hex(hex: &str) -> Result<[u8; 3], String> {
|
||||
@@ -74,6 +75,19 @@ impl std::str::FromStr for Filter {
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Filter {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let str = match self {
|
||||
Self::Nearest => "Nearest",
|
||||
Self::Bilinear => "Bilinear",
|
||||
Self::CatmullRom => "CatmullRom",
|
||||
Self::Mitchell => "Mitchell",
|
||||
Self::Lanczos3 => "Lanczos3",
|
||||
};
|
||||
write!(f, "{}", str)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum TransitionType {
|
||||
None,
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
use std::{path::Path, time::Duration};
|
||||
use std::{path::Path, str::FromStr, time::Duration};
|
||||
|
||||
use clap::Parser;
|
||||
use common::cache;
|
||||
use common::ipc::{self, Answer, Client, IpcSocket, RequestSend};
|
||||
use common::mmap::Mmap;
|
||||
use image::Pixel;
|
||||
|
||||
mod imgproc;
|
||||
use imgproc::*;
|
||||
|
||||
mod cli;
|
||||
use cli::{CliImage, ResizeStrategy, Swww};
|
||||
use cli::{CliImage, Filter, ResizeStrategy, Swww};
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
let swww = Swww::parse();
|
||||
@@ -119,13 +120,18 @@ fn make_img_request(
|
||||
for (&dim, outputs) in dims.iter().zip(outputs) {
|
||||
img_req_builder.push(
|
||||
ipc::ImgSend {
|
||||
img: image::RgbImage::from_pixel(dim.0, dim.1, image::Rgb(*color))
|
||||
.to_vec()
|
||||
.into_boxed_slice(),
|
||||
img: image::RgbaImage::from_pixel(
|
||||
dim.0,
|
||||
dim.1,
|
||||
image::Rgb(*color).to_rgba(),
|
||||
)
|
||||
.to_vec()
|
||||
.into_boxed_slice(),
|
||||
path: format!("0x{:02x}{:02x}{:02x}", color[0], color[1], color[2]),
|
||||
dim,
|
||||
format: pixel_format,
|
||||
},
|
||||
Filter::Lanczos3.to_string(),
|
||||
outputs,
|
||||
None,
|
||||
);
|
||||
@@ -176,6 +182,7 @@ fn make_img_request(
|
||||
None
|
||||
};
|
||||
|
||||
let filter = img.filter.to_string();
|
||||
let img = match img.resize {
|
||||
ResizeStrategy::No => img_pad(&img_raw, dim, &img.fill_color)?,
|
||||
ResizeStrategy::Crop => {
|
||||
@@ -196,6 +203,7 @@ fn make_img_request(
|
||||
dim,
|
||||
format: pixel_format,
|
||||
},
|
||||
filter,
|
||||
outputs,
|
||||
animation,
|
||||
);
|
||||
@@ -265,32 +273,40 @@ fn restore_from_cache(requested_outputs: &[String]) -> Result<(), String> {
|
||||
let (_, _, outputs) = get_format_dims_and_outputs(requested_outputs)?;
|
||||
|
||||
for output in outputs.iter().flatten() {
|
||||
let img_path = common::cache::get_previous_image_path(output)
|
||||
.map_err(|e| format!("failed to get previous image path: {e}"))?;
|
||||
#[allow(deprecated)]
|
||||
if let Err(e) = process_swww_args(&Swww::Img(cli::Img {
|
||||
image: cli::parse_image(&img_path)?,
|
||||
outputs: output.to_string(),
|
||||
no_resize: false,
|
||||
resize: ResizeStrategy::Crop,
|
||||
fill_color: [0, 0, 0],
|
||||
filter: cli::Filter::Lanczos3,
|
||||
transition_type: cli::TransitionType::None,
|
||||
transition_step: std::num::NonZeroU8::MAX,
|
||||
transition_duration: 0.0,
|
||||
transition_fps: 30,
|
||||
transition_angle: 0.0,
|
||||
transition_pos: cli::CliPosition {
|
||||
x: cli::CliCoord::Pixel(0.0),
|
||||
y: cli::CliCoord::Pixel(0.0),
|
||||
},
|
||||
invert_y: false,
|
||||
transition_bezier: (0.0, 0.0, 0.0, 0.0),
|
||||
transition_wave: (0.0, 0.0),
|
||||
})) {
|
||||
if let Err(e) = restore_output(output) {
|
||||
eprintln!("WARNING: failed to load cache for output {output}: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn restore_output(output: &str) -> Result<(), String> {
|
||||
let (filter, img_path) = common::cache::get_previous_image_path(output)
|
||||
.map_err(|e| format!("failed to get previous image path: {e}"))?;
|
||||
if img_path.is_empty() {
|
||||
return Err("cache file does not exist".to_string());
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
process_swww_args(&Swww::Img(cli::Img {
|
||||
image: cli::parse_image(&img_path)?,
|
||||
outputs: output.to_string(),
|
||||
no_resize: false,
|
||||
resize: ResizeStrategy::Crop,
|
||||
fill_color: [0, 0, 0],
|
||||
filter: Filter::from_str(&filter).unwrap_or(Filter::Lanczos3),
|
||||
transition_type: cli::TransitionType::None,
|
||||
transition_step: std::num::NonZeroU8::MAX,
|
||||
transition_duration: 0.0,
|
||||
transition_fps: 30,
|
||||
transition_angle: 0.0,
|
||||
transition_pos: cli::CliPosition {
|
||||
x: cli::CliCoord::Pixel(0.0),
|
||||
y: cli::CliCoord::Pixel(0.0),
|
||||
},
|
||||
invert_y: false,
|
||||
transition_bezier: (0.0, 0.0, 0.0, 0.0),
|
||||
transition_wave: (0.0, 0.0),
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -14,10 +14,10 @@ use crate::ipc::Animation;
|
||||
use crate::ipc::PixelFormat;
|
||||
use crate::mmap::Mmap;
|
||||
|
||||
pub(crate) fn store(output_name: &str, img_path: &str) -> io::Result<()> {
|
||||
pub(crate) fn store(output_name: &str, img_path: &str, filter: &str) -> io::Result<()> {
|
||||
let mut filepath = cache_dir()?;
|
||||
filepath.push(output_name);
|
||||
File::create(filepath)?.write_all(img_path.as_bytes())
|
||||
File::create(filepath)?.write_all(format!("{filter}\n{img_path}").as_bytes())
|
||||
}
|
||||
|
||||
pub(crate) fn store_animation_frames(
|
||||
@@ -64,28 +64,35 @@ pub fn load_animation_frames(
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
pub fn get_previous_image_path(output_name: &str) -> io::Result<String> {
|
||||
pub fn get_previous_image_path(output_name: &str) -> io::Result<(String, String)> {
|
||||
let mut filepath = cache_dir()?;
|
||||
clean_previous_verions(&filepath);
|
||||
|
||||
filepath.push(output_name);
|
||||
if !filepath.is_file() {
|
||||
return Ok("".to_string());
|
||||
return Ok(("".to_string(), "".to_string()));
|
||||
}
|
||||
|
||||
let mut buf = Vec::with_capacity(64);
|
||||
File::open(filepath)?.read_to_end(&mut buf)?;
|
||||
|
||||
String::from_utf8(buf).map_err(|e| {
|
||||
let buf = String::from_utf8(buf).map_err(|e| {
|
||||
std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
format!("failed to decode bytes: {e}"),
|
||||
)
|
||||
})
|
||||
})?;
|
||||
|
||||
match buf.split_once("\n") {
|
||||
Some(buf) => Ok((buf.0.to_string(), buf.1.to_string())),
|
||||
None => Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"failed to read image filter",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load(output_name: &str) -> io::Result<()> {
|
||||
let img_path = get_previous_image_path(output_name)?;
|
||||
let (filter, img_path) = get_previous_image_path(output_name)?;
|
||||
if img_path.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -105,6 +112,7 @@ pub fn load(output_name: &str) -> io::Result<()> {
|
||||
.arg("img")
|
||||
.args([
|
||||
&format!("--outputs={output_name}"),
|
||||
&format!("--filter={filter}"),
|
||||
"--transition-type=none",
|
||||
&img_path,
|
||||
])
|
||||
|
||||
@@ -59,7 +59,13 @@ impl ImageRequestBuilder {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn push(&mut self, img: ImgSend, outputs: &[String], animation: Option<Animation>) {
|
||||
pub fn push(
|
||||
&mut self,
|
||||
img: ImgSend,
|
||||
filter: String,
|
||||
outputs: &[String],
|
||||
animation: Option<Animation>,
|
||||
) {
|
||||
self.img_count += 1;
|
||||
|
||||
let ImgSend {
|
||||
@@ -89,7 +95,7 @@ impl ImageRequestBuilder {
|
||||
|
||||
// cache the request
|
||||
for output in outputs.iter() {
|
||||
if let Err(e) = super::cache::store(output, path) {
|
||||
if let Err(e) = super::cache::store(output, path, &filter) {
|
||||
eprintln!("ERROR: failed to store cache: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user