Skip to content

Commit

Permalink
Update gif.ski to 1.7.1 (#281)
Browse files Browse the repository at this point in the history
  • Loading branch information
kornelski authored Aug 21, 2022
1 parent 93f70c3 commit cc8ed65
Show file tree
Hide file tree
Showing 8 changed files with 304 additions and 253 deletions.
216 changes: 112 additions & 104 deletions gifski-api/Cargo.lock

Large diffs are not rendered by default.

18 changes: 11 additions & 7 deletions gifski-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ documentation = "https://docs.rs/gifski"
homepage = "https://gif.ski"
include = ["/README.md", "/Cargo.toml", "/src/**/*.rs", "/src/bin/*.rs"]
keywords = ["gif", "encoder", "converter", "maker", "gifquant"]
license = "AGPL-3.0+"
license = "AGPL-3.0-or-later"
name = "gifski"
readme = "README.md"
repository = "https://github.com/ImageOptim/gifski"
version = "1.7.0"
version = "1.7.1"
autobins = false
edition = "2021"
rust-version = "1.57"

[[bin]]
doctest = false
Expand All @@ -25,12 +26,12 @@ required-features = ["png"]

[dependencies]
gifsicle = { version = "1.92.5", optional = true }
clap = { version = "3.0.14", features = ["cargo"], optional = true }
clap = { version = "3.1.18", features = ["cargo"], optional = true }
gif = "0.11.3"
gif-dispose = "3.1.1"
imagequant = "4.0.0"
imgref = "1.9.1"
lodepng = { version = "3.6.1", optional = true }
imagequant = "4.0.1"
imgref = "1.9.2"
lodepng = { version = "3.7.0", optional = true }
pbr = { version = "1.0.4", optional = true }
resize = "0.7.2"
rgb = "0.8.31"
Expand All @@ -40,10 +41,12 @@ quick-error = "2.0.1"
dunce = { version = "1.0.2", optional = true }
crossbeam-channel = "0.5.2"
loop9 = "0.1.3"
# noisy-float 0.2 bug
num-traits = { version = "0.2.14", features = ["i128", "std"] }

[dependencies.ffmpeg]
package = "ffmpeg-next"
version = ">= 4.4.0, <6"
version = "4.4.0"
optional = true
default-features = false
features = ["codec", "format", "filter", "software-resampling", "software-scaling"]
Expand All @@ -57,6 +60,7 @@ openmp = [] # deprecated, obsolete
openmp-static = [] # deprecated, obsolete
video = ["ffmpeg"]
video-static = ["video", "ffmpeg/build"]
video-prebuilt-static = ["video", "ffmpeg/static"]

[lib]
path = "src/lib.rs"
Expand Down
2 changes: 1 addition & 1 deletion gifski-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See [releases](https://github.com/ImageOptim/gifski/releases) page for executabl

If you have [Homebrew](https://brew.sh/), you can also get it with `brew install gifski`.

If you have [Rust](https://www.rust-lang.org/install.html) 1.49+, you can also build it from source with [`cargo install gifski`](https://lib.rs/crates/gifski).
If you have [Rust](https://www.rust-lang.org/install.html) 1.57+, you can also build it from source with [`cargo install gifski`](https://lib.rs/crates/gifski).

## Usage

Expand Down
15 changes: 7 additions & 8 deletions gifski-api/src/bin/gifski.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#[macro_use] extern crate clap;

use std::ffi::OsStr;
use std::io::Read;
use gifski::{Settings, Repeat};
Expand All @@ -14,7 +12,7 @@ use gifski::progress::{NoProgress, ProgressBar, ProgressReporter};

pub type BinResult<T, E = Box<dyn std::error::Error + Send + Sync>> = Result<T, E>;

use clap::{App, AppSettings, Arg};
use clap::{Command, AppSettings, Arg};

use std::env;
use std::fmt;
Expand All @@ -41,19 +39,20 @@ fn main() {

#[allow(clippy::float_cmp)]
fn bin_main() -> BinResult<()> {
let matches = App::new(crate_name!())
.version(crate_version!())
let matches = Command::new(clap::crate_name!())
.version(clap::crate_version!())
.about("https://gif.ski by Kornel Lesiński")
.setting(AppSettings::DeriveDisplayOrder)
.setting(AppSettings::ArgRequiredElseHelp)
.setting(AppSettings::AllowNegativeNumbers)
.arg_required_else_help(true)
.allow_negative_numbers(true)
.arg(Arg::new("output")
.long("output")
.short('o')
.help("Destination file to write to; \"-\" means stdout")
.forbid_empty_values(true)
.takes_value(true)
.value_name("a.gif")
.allow_invalid_utf8(true)
.required(true))
.arg(Arg::new("fps")
.long("fps")
Expand Down Expand Up @@ -110,7 +109,7 @@ fn bin_main() -> BinResult<()> {
.help(VIDEO_FRAMES_ARG_HELP)
.min_values(1)
.forbid_empty_values(true)
.use_delimiter(false)
.use_value_delimiter(false)
.required(true))
.arg(Arg::new("repeat")
.long("repeat")
Expand Down
4 changes: 2 additions & 2 deletions gifski-api/src/c_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ fn progress_abort() {
assert_eq!(GifskiError::OK, gifski_set_write_callback(g, Some(cb), ptr::null_mut()));
assert_eq!(GifskiError::OK, gifski_add_frame_rgb(g, 0, 1, 3, 1, &RGB::new(0,0,0), 3.));
assert_eq!(GifskiError::OK, gifski_add_frame_rgb(g, 0, 1, 3, 1, &RGB::new(0,0,0), 10.));
assert_eq!(GifskiError::OK, gifski_finish(g));
assert_eq!(GifskiError::ABORTED, gifski_finish(g));
}
}

Expand All @@ -533,7 +533,7 @@ fn cant_write_after_finish() {
}
unsafe {
assert_eq!(GifskiError::OK, gifski_set_write_callback(g, Some(cb), 0 as _));
assert_eq!(GifskiError::OTHER, gifski_finish(g));
assert_eq!(GifskiError::INVALID_STATE, gifski_finish(g));
}
}

Expand Down
69 changes: 37 additions & 32 deletions gifski-api/src/denoise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ pub struct Denoiser<T> {
metadatas: Vec<T>,
}

#[derive(Debug)]
pub struct WrongSizeError;

impl<T> Denoiser<T> {
#[inline]
pub fn new(width: usize, height: usize, quality: u8) -> Self {
Expand Down Expand Up @@ -118,17 +121,18 @@ impl<T> Denoiser<T> {
}
}

pub fn push_frame(&mut self, frame: ImgRef<RGBA8>, frame_metadata: T) {
assert_eq!(frame.width(), self.splat.width());
assert_eq!(frame.height(), self.splat.height());
pub fn push_frame(&mut self, frame: ImgRef<RGBA8>, frame_metadata: T) -> Result<(), WrongSizeError> {
if frame.width() != self.splat.width() || frame.height() != self.splat.height() {
return Err(WrongSizeError);
}

self.metadatas.insert(0, frame_metadata);

self.frames += 1;
// Can't output anything yet
if self.frames < LOOKAHEAD {
self.quick_append(frame);
return;
return Ok(());
}

let mut median = Vec::with_capacity(frame.width() * frame.height());
Expand All @@ -144,6 +148,7 @@ impl<T> Denoiser<T> {
let median = ImgVec::new(median, frame.width(), frame.height());
let imp_map = ImgVec::new(imp_map, frame.width(), frame.height());
self.processed.insert(0, (median, imp_map));
Ok(())
}

pub fn pop(&mut self) -> Denoised<T> {
Expand Down Expand Up @@ -303,7 +308,7 @@ fn px<T>(f: Denoised<T>) -> (RGBA8, T) {
fn one() {
let mut d = Denoiser::new(1,1, 100);
let w = RGBA8::new(255,255,255,255);
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 0);
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 0).unwrap();
assert!(matches!(d.pop(), Denoised::NotYet));
d.flush();
assert_eq!(px(d.pop()), (w, 0));
Expand All @@ -315,8 +320,8 @@ fn two() {
let mut d = Denoiser::new(1,1, 100);
let w = RGBA8::new(254,253,252,255);
let b = RGBA8::new(8,7,0,255);
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 0);
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), 1);
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 0).unwrap();
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), 1).unwrap();
assert!(matches!(d.pop(), Denoised::NotYet));
d.flush();
assert_eq!(px(d.pop()), (w, 0));
Expand All @@ -329,9 +334,9 @@ fn three() {
let mut d = Denoiser::new(1,1, 100);
let w = RGBA8::new(254,253,252,255);
let b = RGBA8::new(8,7,0,255);
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 0);
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), 1);
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), 2);
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 0).unwrap();
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), 1).unwrap();
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), 2).unwrap();
assert!(matches!(d.pop(), Denoised::NotYet));
d.flush();
assert_eq!(px(d.pop()), (w, 0));
Expand All @@ -347,10 +352,10 @@ fn four() {
let w = RGBA8::new(254,253,252,255);
let b = RGBA8::new(8,7,0,255);
let t = RGBA8::new(0,0,0,0);
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 0);
d.push_frame(ImgVec::new(vec![t], 1, 1).as_ref(), 1);
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), 2);
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 3);
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 0).unwrap();
d.push_frame(ImgVec::new(vec![t], 1, 1).as_ref(), 1).unwrap();
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), 2).unwrap();
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 3).unwrap();
assert!(matches!(d.pop(), Denoised::NotYet));
d.flush();
assert_eq!(px(d.pop()), (w, 0));
Expand All @@ -366,12 +371,12 @@ fn five() {
let w = RGBA8::new(254,253,252,255);
let b = RGBA8::new(8,7,0,255);
let t = RGBA8::new(0,0,0,0);
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 0);
d.push_frame(ImgVec::new(vec![t], 1, 1).as_ref(), 1);
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), 2);
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), 3);
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 0).unwrap();
d.push_frame(ImgVec::new(vec![t], 1, 1).as_ref(), 1).unwrap();
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), 2).unwrap();
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), 3).unwrap();
assert!(matches!(d.pop(), Denoised::NotYet));
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 4);
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 4).unwrap();
assert_eq!(px(d.pop()), (w, 0));
d.flush();
assert_eq!(px(d.pop()), (t, 1));
Expand All @@ -388,17 +393,17 @@ fn six() {
let b = RGBA8::new(8,7,0,255);
let t = RGBA8::new(0,0,0,0);
let x = RGBA8::new(4,5,6,255);
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 0);
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 0).unwrap();
assert!(matches!(d.pop(), Denoised::NotYet));
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), 1);
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), 1).unwrap();
assert!(matches!(d.pop(), Denoised::NotYet));
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), 2);
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), 2).unwrap();
assert!(matches!(d.pop(), Denoised::NotYet));
d.push_frame(ImgVec::new(vec![t], 1, 1).as_ref(), 3);
d.push_frame(ImgVec::new(vec![t], 1, 1).as_ref(), 3).unwrap();
assert!(matches!(d.pop(), Denoised::NotYet));
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 4);
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), 4).unwrap();
assert_eq!(px(d.pop()), (w, 0));
d.push_frame(ImgVec::new(vec![x], 1, 1).as_ref(), 5);
d.push_frame(ImgVec::new(vec![x], 1, 1).as_ref(), 5).unwrap();
d.flush();
assert_eq!(px(d.pop()), (b, 1));
assert_eq!(px(d.pop()), (b, 2));
Expand All @@ -415,19 +420,19 @@ fn many() {
let w = RGBA8::new(255,254,253,255);
let b = RGBA8::new(1,2,3,255);
let t = RGBA8::new(0,0,0,0);
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), "w0");
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), "w0").unwrap();
assert!(matches!(d.pop(), Denoised::NotYet));
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), "w1");
d.push_frame(ImgVec::new(vec![w], 1, 1).as_ref(), "w1").unwrap();
assert!(matches!(d.pop(), Denoised::NotYet));
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), "b2");
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), "b2").unwrap();
assert!(matches!(d.pop(), Denoised::NotYet));
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), "b3");
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), "b3").unwrap();
assert!(matches!(d.pop(), Denoised::NotYet));
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), "b4");
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), "b4").unwrap();
assert_eq!(px(d.pop()), (w, "w0"));
d.push_frame(ImgVec::new(vec![t], 1, 1).as_ref(), "t5");
d.push_frame(ImgVec::new(vec![t], 1, 1).as_ref(), "t5").unwrap();
assert_eq!(px(d.pop()), (w, "w1"));
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), "b6");
d.push_frame(ImgVec::new(vec![b], 1, 1).as_ref(), "b6").unwrap();
assert_eq!(px(d.pop()), (b, "b2"));
d.flush();
assert_eq!(px(d.pop()), (b, "b3"));
Expand Down
Loading

0 comments on commit cc8ed65

Please sign in to comment.