diff options
author | gennyble <gen@nyble.dev> | 2023-10-09 17:45:19 -0500 |
---|---|---|
committer | gennyble <gen@nyble.dev> | 2023-10-09 17:45:19 -0500 |
commit | 25b78bb991fa96864558cccd651519c296af1e91 (patch) | |
tree | 417eb3c94b4dd8477d6971b4d3401af5ebfd928e /gifcheck/src/fix.rs | |
parent | fa2943a6a4bc1d276b458fefae48b28cd78cdb9c (diff) | |
download | gifed-25b78bb991fa96864558cccd651519c296af1e91.tar.gz gifed-25b78bb991fa96864558cccd651519c296af1e91.zip |
changes
Diffstat (limited to 'gifcheck/src/fix.rs')
-rw-r--r-- | gifcheck/src/fix.rs | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/gifcheck/src/fix.rs b/gifcheck/src/fix.rs new file mode 100644 index 0000000..95f7ef2 --- /dev/null +++ b/gifcheck/src/fix.rs @@ -0,0 +1,103 @@ +use gifed::{ + block::{Block, Palette}, + Color, Gif, +}; + +use crate::PaletteReport; + +pub fn palette_errors(gif: &Gif, report: PaletteReport) -> Option<Gif> { + if report.local_matching_indicies { + let mut new = gif.clone(); + + for block in new.blocks.iter_mut() { + if let Block::CompressedImage(comp) = block { + comp.image_descriptor.packed.set_color_table(false); + comp.image_descriptor.packed.set_color_table_size(0); + + if let Some(plt) = comp.local_color_table.take() { + new.global_color_table.get_or_insert(plt); + } + } + } + + Some(new) + } else { + None + } +} + +pub fn images_match_exactly(gifa: &Gif, gifb: &Gif) -> bool { + let mut a_buf = vec![0; gifa.width() * gifa.height() * 4]; + let mut b_buf = vec![0; gifb.width() * gifb.height() * 4]; + + for (a, b) in gifa.images().zip(gifb.images()) { + if a.width() != b.width() || a.height() != b.height() { + return false; + } + + if a.left() != b.left() || a.top() != b.top() { + return false; + } + + let a_decomp = a.decompess(); + let b_decomp = b.decompess(); + + let a_size = deindex( + &a_decomp.indicies, + a.palette(), + a.transparent_index(), + &mut a_buf, + ); + + let b_size = deindex( + &b_decomp.indicies, + b.palette(), + b.transparent_index(), + &mut b_buf, + ); + + match (a_size, b_size) { + (None, _) | (_, None) => return false, + (Some(asize), Some(bsize)) => { + if asize != bsize { + return false; + } + + if a_buf[..asize] != b_buf[..bsize] { + return false; + } + } + } + } + + true +} + +fn deindex(indicies: &[u8], plt: &Palette, trns: Option<u8>, buffer: &mut [u8]) -> Option<usize> { + let mut rgba = |idx: usize, clr: Option<Color>| match clr { + None => { + buffer[idx] = 0; + buffer[idx + 1] = 0; + buffer[idx + 2] = 0; + buffer[idx + 3] = 0; + } + Some(clr) => { + buffer[idx] = clr.r; + buffer[idx + 1] = clr.g; + buffer[idx + 2] = clr.b; + buffer[idx + 3] = 255; + } + }; + + for (idx, color_idx) in indicies.iter().enumerate() { + match (trns, plt.get(*color_idx)) { + (Some(trns_idx), _) if trns_idx == *color_idx => rgba(idx * 4, None), + (_, Some(color)) => rgba(idx * 4, Some(color)), + (Some(_) | None, None) => { + return None; + } + } + } + + Some(indicies.len() * 4) +} |