Merge branch 'master' into interlacing-fixes

This commit is contained in:
Felix Hanau 2019-06-26 13:47:21 +01:00 committed by GitHub
commit e6a097e1ad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 63 additions and 40 deletions

10
Cargo.lock generated
View file

@ -1,3 +1,5 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]] [[package]]
name = "adler32" name = "adler32"
version = "1.0.3" version = "1.0.3"
@ -149,8 +151,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "image" name = "image"
version = "0.21.0" version = "0.21.2"
source = "git+https://github.com/PistonDevelopers/image?rev=41dfbae#41dfbaecfa0e702eaef61e4dba156e9be5b2f70d" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -257,7 +259,7 @@ dependencies = [
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cloudflare-zlib 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "cloudflare-zlib 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.21.0 (git+https://github.com/PistonDevelopers/image?rev=41dfbae)", "image 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -419,7 +421,7 @@ dependencies = [
"checksum deflate 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6abb26e16e8d419b5c78662aa9f82857c2386a073da266840e474d5055ec86" "checksum deflate 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6abb26e16e8d419b5c78662aa9f82857c2386a073da266840e474d5055ec86"
"checksum either 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c67353c641dc847124ea1902d69bd753dee9bb3beff9aa3662ecf86c971d1fac" "checksum either 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c67353c641dc847124ea1902d69bd753dee9bb3beff9aa3662ecf86c971d1fac"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum image 0.21.0 (git+https://github.com/PistonDevelopers/image?rev=41dfbae)" = "<none>" "checksum image 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)" = "99198e595d012efccf12abf4abc08da2d97be0b0355a2b08d101347527476ba4"
"checksum inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff" "checksum inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff"
"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"

View file

@ -55,11 +55,7 @@ cloudflare-zlib = "^0.2.2"
[dependencies.image] [dependencies.image]
default-features = false default-features = false
features = ["png_codec"] features = ["png_codec"]
#FIXME: Use upstream version when 0.22 is released version = "^0.21.2"
#Contains bugfix for issues 167 and 168
#version = "^0.21.0"
git = "https://github.com/PistonDevelopers/image"
rev = "41dfbae"
[features] [features]
binary = [ binary = [

View file

@ -49,7 +49,7 @@ to give any extra compression gains and is not recommended.
PNG interlacing on any images that are processed. `-i 0` will remove interlacing from all PNG interlacing on any images that are processed. `-i 0` will remove interlacing from all
processed images. Not specifying either will keep the same interlacing state as the processed images. Not specifying either will keep the same interlacing state as the
input image. Note: Interlacing can add 25-50% to the size of an optimized image. Only use input image. Note: Interlacing can add 25-50% to the size of an optimized image. Only use
it if you believe the benefits outweight the costs for your use case. it if you believe the benefits outweigh the costs for your use case.
* Strip: Used to remove metadata info from processed images. Used via `--strip [safe,all]`. * Strip: Used to remove metadata info from processed images. Used via `--strip [safe,all]`.
Can save a few kilobytes if you don't need the metadata. "Safe" removes only metadata that Can save a few kilobytes if you don't need the metadata. "Safe" removes only metadata that
will never affect rendering of the image. "All" removes all metadata that is not critical will never affect rendering of the image. "All" removes all metadata that is not critical

View file

@ -49,7 +49,7 @@ to give any extra compression gains and is not recommended.
PNG interlacing on any images that are processed. `-i 0` will remove interlacing from all PNG interlacing on any images that are processed. `-i 0` will remove interlacing from all
processed images. Not specifying either will keep the same interlacing state as the processed images. Not specifying either will keep the same interlacing state as the
input image. Note: Interlacing can add 25-50% to the size of an optimized image. Only use input image. Note: Interlacing can add 25-50% to the size of an optimized image. Only use
it if you believe the benefits outweight the costs for your use case. it if you believe the benefits outweigh the costs for your use case.
* Strip: Used to remove metadata info from processed images. Used via `--strip [safe,all]`. * Strip: Used to remove metadata info from processed images. Used via `--strip [safe,all]`.
Can save a few kilobytes if you don't need the metadata. "Safe" removes only metadata that Can save a few kilobytes if you don't need the metadata. "Safe" removes only metadata that
will never affect rendering of the image. "All" removes all metadata that is not critical will never affect rendering of the image. "All" removes all metadata that is not critical

View file

@ -14,7 +14,7 @@ use crate::reduction::*;
use crc::crc32; use crc::crc32;
use image::{DynamicImage, GenericImageView, ImageFormat, Pixel}; use image::{DynamicImage, GenericImageView, ImageFormat, Pixel};
use rayon::prelude::*; use rayon::prelude::*;
use std::collections::{HashMap, HashSet}; use std::collections::{BTreeMap, HashMap, HashSet};
use std::fmt; use std::fmt;
use std::fs::{copy, File}; use std::fs::{copy, File};
use std::io::{stdin, stdout, BufWriter, Read, Write}; use std::io::{stdin, stdout, BufWriter, Read, Write};
@ -477,7 +477,7 @@ fn optimize_png(
eprintln!( eprintln!(
" {} bits/pixel, {} colors in palette", " {} bits/pixel, {} colors in palette",
png.raw.ihdr.bit_depth, png.raw.ihdr.bit_depth,
palette.len() / 3 palette.len()
); );
} else { } else {
eprintln!( eprintln!(
@ -824,7 +824,7 @@ fn report_reduction(png: &PngImage) {
eprintln!( eprintln!(
"Reducing image to {} bits/pixel, {} colors in palette", "Reducing image to {} bits/pixel, {} colors in palette",
png.ihdr.bit_depth, png.ihdr.bit_depth,
palette.len() / 3 palette.len()
); );
} else { } else {
eprintln!( eprintln!(
@ -843,11 +843,15 @@ fn perform_strip(png: &mut PngData, opts: &Options) {
// Strip headers // Strip headers
Headers::None => (), Headers::None => (),
Headers::Keep(ref hdrs) => { Headers::Keep(ref hdrs) => {
raw.aux_headers.retain(|chunk, _| { let keys: Vec<[u8; 4]> = raw.aux_headers.keys().cloned().collect();
std::str::from_utf8(chunk) for hdr in &keys {
let preserve = std::str::from_utf8(hdr)
.ok() .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) => { Headers::Strip(ref hdrs) => {
for hdr in hdrs { for hdr in hdrs {
@ -859,11 +863,15 @@ 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"cHRM", *b"gAMA", *b"iCCP", *b"sBIT", *b"sRGB", *b"bKGD", *b"hIST", *b"pHYs",
*b"sPLT", *b"sPLT",
]; ];
raw.aux_headers let keys: Vec<[u8; 4]> = raw.aux_headers.keys().cloned().collect();
.retain(|hdr, _| PRESERVED_HEADERS.contains(hdr)); for hdr in &keys {
if !PRESERVED_HEADERS.contains(hdr) {
raw.aux_headers.remove(hdr);
}
}
} }
Headers::All => { Headers::All => {
raw.aux_headers = HashMap::new(); raw.aux_headers = BTreeMap::new();
} }
} }

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;
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;
@ -38,7 +38,7 @@ pub struct PngImage {
/// The pixel value that should be rendered as transparent /// The pixel value that should be rendered as transparent
pub transparency_pixel: Option<Vec<u8>>, pub transparency_pixel: Option<Vec<u8>>,
/// All non-critical headers from the PNG are stored here /// All non-critical headers from the PNG are stored here
pub aux_headers: HashMap<[u8; 4], Vec<u8>>, pub aux_headers: BTreeMap<[u8; 4], Vec<u8>>,
} }
/// Contains all data relevant to a PNG image /// Contains all data relevant to a PNG image
@ -97,7 +97,7 @@ impl PngData {
} }
byte_offset += 8; byte_offset += 8;
// Read the data headers // Read the data headers
let mut aux_headers: HashMap<[u8; 4], Vec<u8>> = HashMap::new(); let mut aux_headers: BTreeMap<[u8; 4], Vec<u8>> = BTreeMap::new();
let mut idat_headers: Vec<u8> = Vec::new(); let mut idat_headers: Vec<u8> = Vec::new();
while let Some(header) = parse_next_header(byte_data, &mut byte_offset, fix_errors)? { while let Some(header) = parse_next_header(byte_data, &mut byte_offset, fix_errors)? {
match &header.name { match &header.name {

View file

@ -4,24 +4,28 @@ use crate::png::PngImage;
use bit_vec::BitVec; use bit_vec::BitVec;
const ONE_BIT_PERMUTATIONS: [u8; 2] = [0b0000_0000, 0b1111_1111]; const ONE_BIT_PERMUTATIONS: [u8; 2] = [0b0000_0000, 0b1111_1111];
const TWO_BIT_PERMUTATIONS: [u8; 5] = [ const TWO_BIT_PERMUTATIONS: [u8; 4] = [
0b0000_0000, 0b0000_0000,
0b0000_1111, 0b0101_0101,
0b0011_1100, 0b1010_1010,
0b1111_0000,
0b1111_1111, 0b1111_1111,
]; ];
const FOUR_BIT_PERMUTATIONS: [u8; 11] = [ const FOUR_BIT_PERMUTATIONS: [u8; 16] = [
0b0000_0000, 0b0000_0000,
0b0000_0011, 0b0001_0001,
0b0000_1100, 0b0010_0010,
0b0011_0000, 0b0011_0011,
0b1100_0000, 0b0100_0100,
0b0000_1111, 0b0101_0101,
0b0011_1100, 0b0110_0110,
0b1111_0000, 0b0111_0111,
0b0011_1111, 0b1000_1000,
0b1111_1100, 0b1001_1001,
0b1010_1010,
0b1011_1011,
0b1100_1100,
0b1101_1101,
0b1110_1110,
0b1111_1111, 0b1111_1111,
]; ];

BIN
tests/files/issue-171.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

View file

@ -332,7 +332,7 @@ fn interlacing_1_to_0_small_files() {
assert_eq!(png.raw.ihdr.interlaced, 0); assert_eq!(png.raw.ihdr.interlaced, 0);
assert_eq!(png.raw.ihdr.color_type, ColorType::Indexed); assert_eq!(png.raw.ihdr.color_type, ColorType::Indexed);
// the depth can't be asserted reliably, because on such small file different zlib implementaitons pick diferent depth as the best // the depth can't be asserted reliably, because on such small file different zlib implementations pick different depth as the best
remove_file(output).ok(); remove_file(output).ok();
} }

View file

@ -600,6 +600,7 @@ fn issue_159() {
} }
#[test] #[test]
#[cfg(target_pointer_width = "64")]
fn issue_167() { fn issue_167() {
test_it_converts( test_it_converts(
"tests/files/issue-167.png", "tests/files/issue-167.png",
@ -611,6 +612,18 @@ fn issue_167() {
); );
} }
#[test]
fn issue_171() {
test_it_converts(
"tests/files/issue-171.png",
None,
ColorType::Grayscale,
BitDepth::Eight,
ColorType::Grayscale,
BitDepth::Eight,
);
}
#[test] #[test]
fn issue_175() { fn issue_175() {
test_it_converts( test_it_converts(
@ -621,4 +634,4 @@ fn issue_175() {
ColorType::Grayscale, ColorType::Grayscale,
BitDepth::One, BitDepth::One,
); );
} }