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/main.rs | |
parent | fa2943a6a4bc1d276b458fefae48b28cd78cdb9c (diff) | |
download | gifed-25b78bb991fa96864558cccd651519c296af1e91.tar.gz gifed-25b78bb991fa96864558cccd651519c296af1e91.zip |
changes
Diffstat (limited to 'gifcheck/src/main.rs')
-rw-r--r-- | gifcheck/src/main.rs | 103 |
1 files changed, 102 insertions, 1 deletions
diff --git a/gifcheck/src/main.rs b/gifcheck/src/main.rs index a30eb95..8eec4c1 100644 --- a/gifcheck/src/main.rs +++ b/gifcheck/src/main.rs @@ -1,3 +1,104 @@ +use std::{ops::Deref, path::PathBuf}; + +use gifed::{reader::Decoder, Gif}; + +mod fix; + fn main() { - println!("Hello, world!"); + let file = std::env::args().nth(1).unwrap(); + let arg = std::env::args().nth(2).map(|cmd| cmd.to_lowercase()); + + let gif = Decoder::file(&file).unwrap().read_all().unwrap(); + + let plt_report = same_palette(&gif); + match plt_report { + PaletteReport { + has_local: true, + local_redundant: true, + local_matching_indicies, + } => { + if local_matching_indicies { + println!("!!! LOCPLT_NORE. This could've been a global palette"); + } else { + println!("!! LOCPLT. This gif can be reindexed and have a global palette"); + } + } + PaletteReport { + has_local: true, + local_redundant: false, + .. + } => { + println!(" gif has local palettes and they differ"); + } + PaletteReport { + has_local: false, .. + } => { + println!(" gif only has a global palette"); + } + } + + if arg.as_deref() == Some("fix") { + if let Some(fix_gif) = fix::palette_errors(&gif, plt_report) { + if !fix::images_match_exactly(&gif, &fix_gif) { + panic!("fixed images did not exactly match, this is a hard error") + } + + println!("--- fixing, writing!"); + let mut path = PathBuf::from(file); + path.set_file_name(format!( + "{}_fix", + path.file_stem().unwrap().to_string_lossy() + )); + + fix_gif.save(path).unwrap(); + } + } +} + +pub struct PaletteReport { + // Does the gif even contain local color tables? + has_local: bool, + // ... do those color tables always contain the same colors? + local_redundant: bool, + // ... and do those colors all have matching inidices, making it possible + // to simply set the global palette and remove the locals? + local_matching_indicies: bool, +} + +fn same_palette(gif: &Gif) -> PaletteReport { + let mut palette = gif.global_color_table.as_ref(); + let mut report = PaletteReport { + has_local: false, + local_redundant: true, + local_matching_indicies: true, + }; + + for img in gif.images() { + if let Some(local_palette) = img.compressed.palette() { + report.has_local = true; + + match palette { + None => palette = Some(local_palette), + Some(known_palette) => { + if !local_palette.eq(known_palette) { + // Are the palletes equal, even? + report.local_redundant = false; + report.local_matching_indicies = false; + return report; + } else if report.local_matching_indicies { + // it's matching, but are the indicies the same? + for known_color in known_palette.deref() { + for local_color in local_palette.deref() { + if known_color != local_color { + report.local_matching_indicies = false; + } + } + } + } + } + } + } + } + + report } |