Merge branch 'master' into interlacing-fixes
This commit is contained in:
commit
e6a097e1ad
10 changed files with 63 additions and 40 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
|
@ -1,3 +1,5 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
version = "1.0.3"
|
||||
|
|
@ -149,8 +151,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.21.0"
|
||||
source = "git+https://github.com/PistonDevelopers/image?rev=41dfbae#41dfbaecfa0e702eaef61e4dba156e9be5b2f70d"
|
||||
version = "0.21.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"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)",
|
||||
|
|
@ -257,7 +259,7 @@ dependencies = [
|
|||
"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)",
|
||||
"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)",
|
||||
"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)",
|
||||
|
|
@ -419,7 +421,7 @@ dependencies = [
|
|||
"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 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 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"
|
||||
|
|
|
|||
|
|
@ -55,11 +55,7 @@ cloudflare-zlib = "^0.2.2"
|
|||
[dependencies.image]
|
||||
default-features = false
|
||||
features = ["png_codec"]
|
||||
#FIXME: Use upstream version when 0.22 is released
|
||||
#Contains bugfix for issues 167 and 168
|
||||
#version = "^0.21.0"
|
||||
git = "https://github.com/PistonDevelopers/image"
|
||||
rev = "41dfbae"
|
||||
version = "^0.21.2"
|
||||
|
||||
[features]
|
||||
binary = [
|
||||
|
|
|
|||
|
|
@ -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
|
||||
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
|
||||
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]`.
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
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
|
||||
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]`.
|
||||
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
|
||||
|
|
|
|||
28
src/lib.rs
28
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};
|
||||
|
|
@ -477,7 +477,7 @@ fn optimize_png(
|
|||
eprintln!(
|
||||
" {} bits/pixel, {} colors in palette",
|
||||
png.raw.ihdr.bit_depth,
|
||||
palette.len() / 3
|
||||
palette.len()
|
||||
);
|
||||
} else {
|
||||
eprintln!(
|
||||
|
|
@ -824,7 +824,7 @@ fn report_reduction(png: &PngImage) {
|
|||
eprintln!(
|
||||
"Reducing image to {} bits/pixel, {} colors in palette",
|
||||
png.ihdr.bit_depth,
|
||||
palette.len() / 3
|
||||
palette.len()
|
||||
);
|
||||
} else {
|
||||
eprintln!(
|
||||
|
|
@ -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,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"sPLT",
|
||||
];
|
||||
raw.aux_headers
|
||||
.retain(|hdr, _| PRESERVED_HEADERS.contains(hdr));
|
||||
let keys: Vec<[u8; 4]> = raw.aux_headers.keys().cloned().collect();
|
||||
for hdr in &keys {
|
||||
if !PRESERVED_HEADERS.contains(hdr) {
|
||||
raw.aux_headers.remove(hdr);
|
||||
}
|
||||
}
|
||||
}
|
||||
Headers::All => {
|
||||
raw.aux_headers = HashMap::new();
|
||||
raw.aux_headers = BTreeMap::new();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Vec<u8>>,
|
||||
/// 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
|
||||
|
|
@ -97,7 +97,7 @@ impl PngData {
|
|||
}
|
||||
byte_offset += 8;
|
||||
// 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();
|
||||
while let Some(header) = parse_next_header(byte_data, &mut byte_offset, fix_errors)? {
|
||||
match &header.name {
|
||||
|
|
|
|||
|
|
@ -4,24 +4,28 @@ use crate::png::PngImage;
|
|||
use bit_vec::BitVec;
|
||||
|
||||
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_1111,
|
||||
0b0011_1100,
|
||||
0b1111_0000,
|
||||
0b0101_0101,
|
||||
0b1010_1010,
|
||||
0b1111_1111,
|
||||
];
|
||||
const FOUR_BIT_PERMUTATIONS: [u8; 11] = [
|
||||
const FOUR_BIT_PERMUTATIONS: [u8; 16] = [
|
||||
0b0000_0000,
|
||||
0b0000_0011,
|
||||
0b0000_1100,
|
||||
0b0011_0000,
|
||||
0b1100_0000,
|
||||
0b0000_1111,
|
||||
0b0011_1100,
|
||||
0b1111_0000,
|
||||
0b0011_1111,
|
||||
0b1111_1100,
|
||||
0b0001_0001,
|
||||
0b0010_0010,
|
||||
0b0011_0011,
|
||||
0b0100_0100,
|
||||
0b0101_0101,
|
||||
0b0110_0110,
|
||||
0b0111_0111,
|
||||
0b1000_1000,
|
||||
0b1001_1001,
|
||||
0b1010_1010,
|
||||
0b1011_1011,
|
||||
0b1100_1100,
|
||||
0b1101_1101,
|
||||
0b1110_1110,
|
||||
0b1111_1111,
|
||||
];
|
||||
|
||||
|
|
|
|||
BIN
tests/files/issue-171.png
Normal file
BIN
tests/files/issue-171.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 220 B |
|
|
@ -332,7 +332,7 @@ fn interlacing_1_to_0_small_files() {
|
|||
|
||||
assert_eq!(png.raw.ihdr.interlaced, 0);
|
||||
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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -600,6 +600,7 @@ fn issue_159() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
fn issue_167() {
|
||||
test_it_converts(
|
||||
"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]
|
||||
fn issue_175() {
|
||||
test_it_converts(
|
||||
|
|
@ -621,4 +634,4 @@ fn issue_175() {
|
|||
ColorType::Grayscale,
|
||||
BitDepth::One,
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue