--keep option (#121)

This commit is contained in:
Kornel 2018-07-18 04:55:21 +01:00 committed by Josh Holmer
parent c99b3778b2
commit c530bba261
4 changed files with 26 additions and 5 deletions

View file

@ -1,3 +1,4 @@
use std::collections::HashSet;
use byteorder::{BigEndian, ReadBytesExt}; use byteorder::{BigEndian, ReadBytesExt};
use colors::{BitDepth, ColorType}; use colors::{BitDepth, ColorType};
use crc::crc32; use crc::crc32;
@ -28,10 +29,12 @@ pub struct IhdrData {
pub enum Headers { pub enum Headers {
/// None /// None
None, None,
/// Some, with a list of 4-character chunk codes /// Remove specific chunks
Some(Vec<String>), Strip(Vec<String>),
/// Headers that won't affect rendering (all but cHRM, gAMA, iCCP, sBIT, sRGB, bKGD, hIST, pHYs, sPLT) /// Headers that won't affect rendering (all but cHRM, gAMA, iCCP, sBIT, sRGB, bKGD, hIST, pHYs, sPLT)
Safe, Safe,
/// Remove all non-critical chunks except these
Keep(HashSet<String>),
/// All non-critical headers /// All non-critical headers
All, All,
} }

View file

@ -808,7 +808,12 @@ fn perform_strip(png: &mut PngData, opts: &Options) {
match opts.strip { match opts.strip {
// Strip headers // Strip headers
Headers::None => (), Headers::None => (),
Headers::Some(ref hdrs) => for hdr in hdrs { Headers::Keep(ref hdrs) => {
png.aux_headers.retain(|chunk, _| {
hdrs.contains(chunk)
});
},
Headers::Strip(ref hdrs) => for hdr in hdrs {
png.aux_headers.remove(hdr); png.aux_headers.remove(hdr);
}, },
Headers::Safe => { Headers::Safe => {

View file

@ -94,6 +94,13 @@ fn main() {
.takes_value(true) .takes_value(true)
.value_name("mode") .value_name("mode")
.conflicts_with("strip-safe")) .conflicts_with("strip-safe"))
.arg(Arg::with_name("keep")
.help("Strip all optional metadata except objects in the comma-separated list")
.long("keep")
.takes_value(true)
.value_name("list")
.conflicts_with("strip")
.conflicts_with("strip-safe"))
.arg(Arg::with_name("alpha") .arg(Arg::with_name("alpha")
.help("Perform additional alpha optimizations") .help("Perform additional alpha optimizations")
.short("a") .short("a")
@ -411,6 +418,12 @@ fn parse_opts_into_struct(matches: &ArgMatches) -> Result<(OutFile, Option<PathB
opts.idat_recoding = false; opts.idat_recoding = false;
} }
if let Some(hdrs) = matches.value_of("keep") {
opts.strip = Headers::Keep(hdrs.split(',')
.map(|x| x.trim().to_owned())
.collect())
}
if let Some(hdrs) = matches.value_of("strip") { if let Some(hdrs) = matches.value_of("strip") {
let hdrs = hdrs.split(',') let hdrs = hdrs.split(',')
.map(|x| x.trim().to_owned()) .map(|x| x.trim().to_owned())
@ -433,7 +446,7 @@ fn parse_opts_into_struct(matches: &ArgMatches) -> Result<(OutFile, Option<PathB
return Err(format!("{} chunk is not allowed to be stripped", i)); return Err(format!("{} chunk is not allowed to be stripped", i));
} }
} }
opts.strip = Headers::Some(hdrs); opts.strip = Headers::Strip(hdrs);
} }
} }

View file

@ -74,7 +74,7 @@ fn verbose_mode() {
fn strip_headers_list() { fn strip_headers_list() {
let input = PathBuf::from("tests/files/strip_headers_list.png"); let input = PathBuf::from("tests/files/strip_headers_list.png");
let (output, mut opts) = get_opts(&input); let (output, mut opts) = get_opts(&input);
opts.strip = Headers::Some(vec!["iCCP".to_owned(), "tEXt".to_owned()]); opts.strip = Headers::Strip(vec!["iCCP".to_owned(), "tEXt".to_owned()]);
let png = PngData::new(&input, opts.fix_errors).unwrap(); let png = PngData::new(&input, opts.fix_errors).unwrap();