Skip to content

Commit

Permalink
fix single image webp and gif
Browse files Browse the repository at this point in the history
simply detect it ahead of time if the webp image has any frames
  • Loading branch information
LGFae committed Feb 10, 2024
1 parent 01e9cf8 commit 9b86f05
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 19 deletions.
2 changes: 1 addition & 1 deletion daemon/src/wallpaper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ impl Wallpaper {
id: AtomicUsize::new(0),
transition_finished: Arc::new(AtomicBool::new(false)),
},
configured: AtomicBool::new(false)
configured: AtomicBool::new(false),
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ pub struct Img {
///
///The 'left', 'right', 'top' and 'bottom' options make the transition happen from that
///position to its opposite in the screen.
///
///
///'none' is an alias to 'simple' that also sets the 'transition-step' to 255. This has the
///effect of the transition finishing instantly
///
Expand Down
68 changes: 52 additions & 16 deletions src/imgproc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,52 +21,85 @@ use crate::cli::ResizeStrategy;

use super::cli;

pub enum ImgBuf {
enum ImgBufInner {
Stdin(BufReader<Stdin>),
File(image::io::Reader<BufReader<File>>),
}

impl ImgBufInner {
/// Guess the format of the ImgBufInner
#[inline]
fn format(&self) -> Option<ImageFormat> {
match &self {
ImgBufInner::Stdin(_) => None, // not seekable
ImgBufInner::File(reader) => reader.format(),
}
}
}

pub struct ImgBuf {
inner: ImgBufInner,
is_animated: bool,
}

impl ImgBuf {
/// Create a new ImgBuf from a given path. Use - for Stdin
pub fn new(path: &Path) -> Result<Self, String> {
Ok(if let Some("-") = path.to_str() {
let reader = BufReader::new(stdin());
Self::Stdin(reader)
Self {
inner: ImgBufInner::Stdin(reader),
is_animated: false,
}
} else {
let reader = image::io::Reader::open(path)
.map_err(|e| format!("failed to open image: {e}"))?
.with_guessed_format()
.map_err(|e| format!("failed to detect the image's format: {e}"))?;

Self::File(reader)
let is_animated = {
match reader.format() {
Some(ImageFormat::Gif) => true,
Some(ImageFormat::WebP) => {
// Note: unwraping is safe because we already openned the file once before this
WebPDecoder::new(BufReader::new(File::open(path).unwrap()))
.map_err(|e| format!("failed to decode Webp Image: {e}"))?
.has_animation()
}

_ => false,
}
};

Self {
inner: ImgBufInner::File(reader),
is_animated,
}
})
}

/// Guess the format of the ImgBuf
fn format(&self) -> Option<ImageFormat> {
match self {
ImgBuf::Stdin(_) => None, // not seekable
ImgBuf::File(reader) => reader.format(),
}
self.inner.format()
}

/// Is this ImgBuf an animated image?
#[inline]
pub fn is_animated(&self) -> bool {
matches!(self.format(), Some(ImageFormat::Gif | ImageFormat::WebP))
self.is_animated
}

/// Decode the ImgBuf into am RgbImage
pub fn decode(self) -> Result<RgbImage, String> {
Ok(match self {
ImgBuf::Stdin(mut reader) => {
Ok(match self.inner {
ImgBufInner::Stdin(mut reader) => {
let mut buffer = Vec::new();
reader
.read_to_end(&mut buffer)
.map_err(|e| format!("failed to read stdin: {e}"))?;

image::load_from_memory(&buffer)
}
ImgBuf::File(reader) => reader.decode(),
ImgBufInner::File(reader) => reader.decode(),
}
.map_err(|e| format!("failed to decode image: {e}"))?
.into_rgb8())
Expand All @@ -90,9 +123,9 @@ impl ImgBuf {
}

let img_format = self.format();
match self {
ImgBuf::Stdin(reader) => create_decoder(img_format, reader),
ImgBuf::File(reader) => create_decoder(img_format, reader.into_inner()),
match self.inner {
ImgBufInner::Stdin(reader) => create_decoder(img_format, reader),
ImgBufInner::File(reader) => create_decoder(img_format, reader.into_inner()),
}
}
}
Expand Down Expand Up @@ -139,7 +172,10 @@ pub fn compress_frames(
canvas = Some(img);
}
//Add the first frame we got earlier:
compressed_frames.push((BitPack::pack(&canvas.unwrap(), &first_img)?, first_duration));
compressed_frames.push((
BitPack::pack(canvas.as_ref().unwrap_or(&first_img), &first_img)?,
first_duration,
));
Ok(compressed_frames)
}

Expand Down
2 changes: 1 addition & 1 deletion utils/src/ipc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ pub fn read_socket(stream: &UnixStream) -> Result<Vec<u8>, String> {
if e.kind() == std::io::ErrorKind::WouldBlock && tries < 5 {
std::thread::sleep(Duration::from_millis(1));
} else {
return Err(format!("failed to read serialized length: {e}"));
return Err(format!("failed to read serialized length: {e}"));
}
}
}
Expand Down

0 comments on commit 9b86f05

Please sign in to comment.