Skip to content

Commit

Permalink
Merge pull request #205 from LGFae/fix-single-image-webp-and-gif
Browse files Browse the repository at this point in the history
fix single image webp and gif
  • Loading branch information
LGFae authored Feb 13, 2024
2 parents 01e9cf8 + 9b86f05 commit 0b07d27
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 0b07d27

Please sign in to comment.