diff --git a/src/lib.rs b/src/lib.rs index a9d456ba..226bdf86 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,7 +14,7 @@ use crate::reduction::*; use crc::crc32; use image::{DynamicImage, GenericImageView, ImageFormat, Pixel}; use rayon::prelude::*; -use std::collections::{HashMap, HashSet}; +use std::collections::{BTreeMap, HashMap, HashSet}; use std::fmt; use std::fs::{copy, File}; use std::io::{stdin, stdout, BufWriter, Read, Write}; @@ -843,11 +843,15 @@ fn perform_strip(png: &mut PngData, opts: &Options) { // Strip headers Headers::None => (), Headers::Keep(ref hdrs) => { - raw.aux_headers.retain(|chunk, _| { - std::str::from_utf8(chunk) + let keys: Vec<[u8; 4]> = raw.aux_headers.keys().cloned().collect(); + for hdr in &keys { + let preserve = std::str::from_utf8(hdr) .ok() - .map_or(false, |name| hdrs.contains(name)) - }); + .map_or(false, |name| hdrs.contains(name)); + if !preserve { + raw.aux_headers.remove(hdr); + } + } } Headers::Strip(ref hdrs) => { for hdr in hdrs { @@ -859,11 +863,14 @@ fn perform_strip(png: &mut PngData, opts: &Options) { *b"cHRM", *b"gAMA", *b"iCCP", *b"sBIT", *b"sRGB", *b"bKGD", *b"hIST", *b"pHYs", *b"sPLT", ]; - raw.aux_headers - .retain(|hdr, _| PRESERVED_HEADERS.contains(hdr)); + for hdr in &PRESERVED_HEADERS { + if !PRESERVED_HEADERS.contains(hdr) { + raw.aux_headers.remove(hdr); + } + } } Headers::All => { - raw.aux_headers = HashMap::new(); + raw.aux_headers = BTreeMap::new(); } } diff --git a/src/png/mod.rs b/src/png/mod.rs index 6d46670e..2fd5184f 100644 --- a/src/png/mod.rs +++ b/src/png/mod.rs @@ -8,7 +8,7 @@ use byteorder::{BigEndian, WriteBytesExt}; use crc::crc32; use rgb::ComponentSlice; use rgb::RGBA8; -use std::collections::HashMap; +use std::collections::BTreeMap; use std::fs::File; use std::io::{Read, Seek, SeekFrom}; use std::iter::Iterator; @@ -38,7 +38,7 @@ pub struct PngImage { /// The pixel value that should be rendered as transparent pub transparency_pixel: Option>, /// All non-critical headers from the PNG are stored here - pub aux_headers: HashMap<[u8; 4], Vec>, + pub aux_headers: BTreeMap<[u8; 4], Vec>, } /// Contains all data relevant to a PNG image @@ -97,7 +97,7 @@ impl PngData { } byte_offset += 8; // Read the data headers - let mut aux_headers: HashMap<[u8; 4], Vec> = HashMap::new(); + let mut aux_headers: BTreeMap<[u8; 4], Vec> = BTreeMap::new(); let mut idat_headers: Vec = Vec::new(); while let Some(header) = parse_next_header(byte_data, &mut byte_offset, fix_errors)? { match &header.name {