Make order of chunks deterministic by sorting chunks

This commit is contained in:
Felix Hanau 2019-06-10 18:11:55 +01:00
parent 9c6190c1ff
commit 462514a82c

View file

@ -8,7 +8,7 @@ use byteorder::{BigEndian, WriteBytesExt};
use crc::crc32; use crc::crc32;
use rgb::ComponentSlice; use rgb::ComponentSlice;
use rgb::RGBA8; use rgb::RGBA8;
use std::collections::HashMap; use std::collections::{BTreeMap, HashMap};
use std::fs::File; use std::fs::File;
use std::io::{Read, Seek, SeekFrom}; use std::io::{Read, Seek, SeekFrom};
use std::iter::Iterator; use std::iter::Iterator;
@ -179,11 +179,17 @@ impl PngData {
let _ = ihdr_data.write_u8(0); // Filter method -- 5-way adaptive filtering let _ = ihdr_data.write_u8(0); // Filter method -- 5-way adaptive filtering
let _ = ihdr_data.write_u8(self.raw.ihdr.interlaced); let _ = ihdr_data.write_u8(self.raw.ihdr.interlaced);
write_png_block(b"IHDR", &ihdr_data, &mut output); write_png_block(b"IHDR", &ihdr_data, &mut output);
// Ancillary headers // Ancillary headers (put into BTreeMap for a deterministic order)
let mut aux_headers_sorted = BTreeMap::new();
for (key, header) in self for (key, header) in self
.raw .raw
.aux_headers .aux_headers
.iter() .iter()
{
aux_headers_sorted.insert(*key, header);
}
for (key, header) in aux_headers_sorted
.iter()
.filter(|&(key, _)| !(key == b"bKGD" || key == b"hIST" || key == b"tRNS")) .filter(|&(key, _)| !(key == b"bKGD" || key == b"hIST" || key == b"tRNS"))
{ {
write_png_block(key, header, &mut output); write_png_block(key, header, &mut output);
@ -220,9 +226,7 @@ impl PngData {
write_png_block(b"tRNS", transparency_pixel, &mut output); write_png_block(b"tRNS", transparency_pixel, &mut output);
} }
// Special ancillary headers that need to come after PLTE but before IDAT // Special ancillary headers that need to come after PLTE but before IDAT
for (key, header) in self for (key, header) in aux_headers_sorted
.raw
.aux_headers
.iter() .iter()
.filter(|&(key, _)| key == b"bKGD" || key == b"hIST" || key == b"tRNS") .filter(|&(key, _)| key == b"bKGD" || key == b"hIST" || key == b"tRNS")
{ {