Skip to content

Commit c6a6975

Browse files
committed
Upgrade to new gif crate
1 parent 5bf8b1a commit c6a6975

File tree

6 files changed

+67
-62
lines changed

6 files changed

+67
-62
lines changed

Cargo.lock

Lines changed: 37 additions & 37 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ license = "AGPL-3.0-or-later"
1010
name = "gifski"
1111
readme = "README.md"
1212
repository = "https://github.com/ImageOptim/gifski"
13-
version = "1.14.0"
13+
version = "1.14.1"
1414
autobins = false
1515
edition = "2021"
1616
rust-version = "1.65"
@@ -22,9 +22,9 @@ required-features = ["binary"]
2222

2323
[dependencies]
2424
clap = { version = "4.3.24", features = ["cargo"], optional = true }
25-
gif = { version = "0.13.0-beta.1", default-features = false, features = ["std", "raii_no_panic"] }
26-
gif-dispose = "5.0.0-beta.1"
2725
imgref = "1.10.0"
26+
gif = { version = "0.13", default-features = false, features = ["std", "raii_no_panic"] }
27+
gif-dispose = "5.0.0-beta.2"
2828
imagequant = "4.3.0"
2929
lodepng = { version = "3.10.1", optional = true }
3030
pbr = { version = "1.1.1", optional = true }
@@ -48,7 +48,7 @@ default-features = false
4848
features = ["codec", "format", "filter", "software-resampling", "software-scaling"]
4949

5050
[dev-dependencies]
51-
lodepng = "3.9.3"
51+
lodepng = "3.10.1"
5252

5353
[features]
5454
# `cargo build` will skip the binaries with missing `required-features`

src/bin/gif.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl Source for GifDecoder {
3838
let mut delay_ts = 0;
3939
while let Some(frame) = self.decoder.read_next_frame()? {
4040
self.screen.blit_frame(frame)?;
41-
let pixels = self.screen.pixels.clone();
41+
let pixels = self.screen.pixels_rgba().map_buf(|b| b.to_owned());
4242
let presentation_timestamp = f64::from(delay_ts) * (f64::from(self.speed) / 100.);
4343
c.add_frame_rgba(idx, pixels, presentation_timestamp)?;
4444
idx += 1;

src/encoderust.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rgb::ComponentBytes;
66
use rgb::RGB8;
77
use std::cell::Cell;
88
use std::io::Write;
9+
use std::iter::repeat;
910
use std::rc::Rc;
1011

1112
#[cfg(feature = "gifsicle")]
@@ -53,11 +54,13 @@ impl<W: Write> RustEncoder<W> {
5354

5455
let (buffer, width, height) = image.into_contiguous_buf();
5556

56-
let mut pal_rgb = Vec::with_capacity(3 * pal.len());
57-
for p in &pal {
58-
pal_rgb.extend_from_slice([p.rgb()].as_bytes());
57+
let mut pal_rgb = pal.as_bytes().to_vec();
58+
// Palette should be power-of-two sized
59+
if pal.len() != 256 {
60+
let needed_size = 3 * pal.len().max(2).next_power_of_two();
61+
pal_rgb.extend(repeat([115,107,105,46,103,105,102]).flat_map(|x| x).take(needed_size - pal_rgb.len()));
62+
debug_assert_eq!(needed_size, pal_rgb.len());
5963
}
60-
6164
let mut frame = gif::Frame {
6265
delay: 1, // TBD
6366
dispose,

src/lib.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ struct GIFFrame {
144144
left: u16,
145145
top: u16,
146146
image: ImgVec<u8>,
147-
pal: Vec<RGBA8>,
147+
pal: Vec<RGB8>,
148148
dispose: DisposalMethod,
149149
transparent_index: Option<u8>,
150150
}
@@ -424,7 +424,8 @@ impl Writer {
424424
};
425425
liq.set_quality(0, quality)?;
426426
if self.settings.s.quality < 50 {
427-
liq.set_max_colors(u32::from(self.settings.s.quality * 2).max(16).next_power_of_two())?;
427+
let min_colors = 5 + self.fixed_colors.len() as u32;
428+
liq.set_max_colors(u32::from(self.settings.s.quality * 2).max(min_colors).next_power_of_two().min(256))?;
428429
}
429430
let (buf, width, height) = image.into_contiguous_buf();
430431
let mut img = liq.new_image(buf, width, height, 0.)?;
@@ -759,23 +760,24 @@ impl Writer {
759760
fn remap_frames(&self, mut inputs: OrdQueueIter<RemapMessage>, write_queue: Sender<FrameMessage>) -> CatResult<()> {
760761
let mut frame_index = 0;
761762
let first_frame = inputs.next().ok_or(Error::NoFrames)?;
762-
let mut screen = gif_dispose::Screen::new(first_frame.liq_image.width(), first_frame.liq_image.height(), RGBA8::new(0, 0, 0, 0), None);
763+
let mut screen = gif_dispose::Screen::new(first_frame.liq_image.width(), first_frame.liq_image.height(), None);
763764

764765
let mut next_frame = Some(first_frame);
765766
while let Some(RemapMessage {ordinal_frame_number, end_pts, dispose, liq, remap, liq_image, out_buf, has_next_frame}) = next_frame {
766-
let screen_width = screen.pixels.width() as u16;
767-
let screen_height = screen.pixels.height() as u16;
768-
let mut screen_after_dispose = screen.dispose();
767+
let pixels = screen.pixels_rgba();
768+
let screen_width = pixels.width() as u16;
769+
let screen_height = pixels.height() as u16;
770+
let mut screen_after_dispose = screen.dispose_only();
769771

770-
let (mut image8, mut image8_pal) = {
771-
let bg = if frame_index != 0 { Some(screen_after_dispose.pixels()) } else { None };
772+
let (mut image8, image8_pal) = {
773+
let bg = if frame_index != 0 { Some(screen_after_dispose.pixels_rgba()) } else { None };
772774
self.remap(liq, remap, liq_image, bg, out_buf)?
773775
};
774776

775-
let transparent_index = transparent_index_from_palette(&mut image8_pal, image8.as_mut());
777+
let (image8_pal, transparent_index) = transparent_index_from_palette(image8_pal, image8.as_mut());
776778

777779
let (left, top) = if frame_index != 0 && has_next_frame {
778-
let (left, top, new_width, new_height) = trim_image(image8.as_ref(), &image8_pal, transparent_index, dispose, screen_after_dispose.pixels())
780+
let (left, top, new_width, new_height) = trim_image(image8.as_ref(), &image8_pal, transparent_index, dispose, screen_after_dispose.pixels_rgba())
779781
.unwrap_or((0, 0, 1, 1));
780782
if new_width != image8.width() || new_height != image8.height() {
781783
let new_buf = image8.sub_image(left.into(), top.into(), new_width, new_height).to_contiguous_buf().0.into_owned();
@@ -811,12 +813,12 @@ impl Writer {
811813
}
812814
}
813815

814-
fn transparent_index_from_palette(image8_pal: &mut [RGBA<u8>], mut image8: ImgRefMut<u8>) -> Option<u8> {
816+
fn transparent_index_from_palette(mut image8_pal: Vec<RGBA8>, mut image8: ImgRefMut<u8>) -> (Vec<RGB8>, Option<u8>) {
815817
// Palette may have multiple transparent indices :(
816818
let mut transparent_index = None;
817819
for (i, p) in image8_pal.iter_mut().enumerate() {
818820
if p.a <= 128 {
819-
p.a = 0;
821+
*p = RGBA8::new(71,80,76,0);
820822
let new_index = i as u8;
821823
if let Some(old_index) = transparent_index {
822824
image8.pixels_mut().filter(|px| **px == new_index).for_each(|px| *px = old_index);
@@ -831,7 +833,7 @@ fn transparent_index_from_palette(image8_pal: &mut [RGBA<u8>], mut image8: ImgRe
831833
Some(idx as u8) == transparent_index || color.a > 128 || !image8.pixels().any(|px| px == idx as u8)
832834
}));
833835

834-
transparent_index
836+
(image8_pal.into_iter().map(|r| r.rgb()).collect(), transparent_index)
835837
}
836838

837839
/// When one thread unexpectedly fails, all other threads fail with Aborted, but that Aborted isn't the relevant cause
@@ -847,7 +849,7 @@ fn combine_res(res1: Result<(), Error>, res2: Result<(), Error>) -> Result<(), E
847849
}
848850
}
849851

850-
fn trim_image(mut image_trimmed: ImgRef<u8>, image8_pal: &[RGBA8], transparent_index: Option<u8>, dispose: DisposalMethod, mut screen: ImgRef<RGBA8>) -> Option<(u16, u16, usize, usize)> {
852+
fn trim_image(mut image_trimmed: ImgRef<u8>, image8_pal: &[RGB8], transparent_index: Option<u8>, dispose: DisposalMethod, mut screen: ImgRef<RGBA8>) -> Option<(u16, u16, usize, usize)> {
851853
let is_matching_pixel = move |px: u8, bg: RGBA8| -> bool {
852854
if Some(px) == transparent_index {
853855
if dispose == DisposalMethod::Keep {
@@ -858,7 +860,7 @@ fn trim_image(mut image_trimmed: ImgRef<u8>, image8_pal: &[RGBA8], transparent_i
858860
bg.a == 0
859861
}
860862
} else {
861-
image8_pal.get(px as usize).copied().unwrap_or_default() == bg
863+
image8_pal.get(px as usize).map(|px| px.alpha(255)).unwrap_or_default() == bg
862864
}
863865
};
864866

tests/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ fn for_each_frame(mut gif_data: &[u8], mut cb: impl FnMut(&gif::Frame, ImgRef<RG
9595

9696
while let Some(frame) = decoder.read_next_frame().unwrap() {
9797
screen.blit_frame(frame).unwrap();
98-
cb(frame, screen.pixels.as_ref());
98+
cb(frame, screen.pixels_rgba());
9999
}
100100
}
101101

0 commit comments

Comments
 (0)