diff --git a/Cargo.lock b/Cargo.lock index e7a5debc..c3b2e76a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,11 +15,11 @@ dependencies = [ [[package]] name = "atty" -version = "0.2.14" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hermit-abi 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -63,13 +63,23 @@ name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "chrono" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "clap" version = "2.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -217,6 +227,11 @@ dependencies = [ "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "lazy_static" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "lazy_static" version = "1.4.0" @@ -235,6 +250,14 @@ dependencies = [ "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "log" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "maybe-uninit" version = "2.0.0" @@ -302,6 +325,11 @@ dependencies = [ "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "numtoa" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "oxipng" version = "2.3.0" @@ -315,9 +343,11 @@ dependencies = [ "indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "libdeflater 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rgb 0.8.16 (registry+https://github.com/rust-lang/crates.io-index)", + "stderrlog 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "wild 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "zopfli 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -355,6 +385,19 @@ dependencies = [ "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "redox_syscall" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rgb" version = "0.8.16" @@ -386,11 +429,42 @@ name = "semver-parser" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "stderrlog" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "termcolor" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-util 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "termion" +version = "1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)", + "numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -399,6 +473,25 @@ dependencies = [ "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "thread_local" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "time" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "typed-arena" version = "1.7.0" @@ -409,11 +502,24 @@ name = "unicode-width" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "vec_map" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "wild" version = "2.0.2" @@ -436,6 +542,14 @@ name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winapi-util" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -455,7 +569,7 @@ dependencies = [ [metadata] "checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" "checksum bit-vec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a4523a10839ffae575fb08aa3423026c8cb4687eef43952afb956229d4f246f7" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" @@ -464,6 +578,7 @@ dependencies = [ "checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" "checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +"checksum chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum cloudflare-zlib 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ed63a019d55bacd15cadcbcb96bf41b16281417fff393bdb55fa84255fe4b9" "checksum cloudflare-zlib-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e195cb274a0d6ee87e718838a09baecd7cbc9f6075dac256a84cb5842739c06" @@ -481,9 +596,11 @@ dependencies = [ "checksum indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292" "checksum inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff" "checksum itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)" = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" "checksum libdeflater 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "66dca08b13369865b2f6dca1dd05f833985cbe6c12a676b04d55f78b85e80246" +"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" "checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" "checksum miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5" @@ -492,21 +609,32 @@ dependencies = [ "checksum num-rational 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "da4dc79f9e6c81bef96148c8f6b8e72ad4541caa4a24373e900a36da07de03a3" "checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" "checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" "checksum png 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46060468187c21c00ffa2a920690b29997d7fd543f5a4d400461e4a7d4fccde8" "checksum rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098" "checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" +"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum rgb 0.8.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5ec4ab2cf0b27e111e266e161cf7f9efd20125a161190da1c0945c4a4408fef3" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum stderrlog 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "32e5ee9b90a5452c570a0b0ac1c99ae9498db7e56e33d74366de7f2a7add7f25" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" +"checksum termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c22cec9d8978d906be5ac94bceb5a010d885c626c4c8855721a4dbd20e3ac905" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14" +"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum typed-arena 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d" "checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" +"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum wild 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "97d34fecce28871e5c0e059deae21ef7f7d13b98a5964b24c58b3735c8052fc8" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-util 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fa515c5163a99cc82bab70fd3bfdd36d827be85de63737b40fcef2ce084a436e" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum zopfli 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4079b79464426ade2a1b0177fb0ce8396ba6b4084267407e333573c666073964" diff --git a/Cargo.toml b/Cargo.toml index bcbfa0eb..9e1de018 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,8 @@ miniz_oxide = "0.3" rgb = "0.8.11" indexmap = { version = "1.3.2", features = ["rayon"] } libdeflater = "0.2.0" +log = "0.4.8" +stderrlog = "0.4.3" [dependencies.rayon] optional = true @@ -50,14 +52,14 @@ version = "^2.10.0" optional = true version = "2.0.0" -[target.'cfg(any(target_arch = "x86_64", target_arch = "aarch64"))'.dependencies] -cloudflare-zlib = "^0.2.2" - [dependencies.image] default-features = false features = ["png"] version = "0.23" +[target.'cfg(any(target_arch = "x86_64", target_arch = "aarch64"))'.dependencies] +cloudflare-zlib = "^0.2.2" + [features] binary = [ "clap", diff --git a/src/lib.rs b/src/lib.rs index 3e33fd3a..153d7acb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,6 +27,7 @@ use crate::png::PngImage; use crate::reduction::*; use crc::crc32; use image::{DynamicImage, GenericImageView, ImageFormat, Pixel}; +use log::{debug, error, info, warn}; use rayon::prelude::*; use std::fmt; use std::fs::{copy, File}; @@ -139,10 +140,6 @@ pub struct Options { /// /// Default: `false` pub preserve_attrs: bool, - /// How verbose the console logging should be (`None` for quiet, `Some(0)` for normal, `Some(1)` for verbose) - /// - /// Default: `Some(0)` - pub verbosity: Option, /// Which filters to try on the file (0-5) /// /// Default: `0,5` @@ -289,7 +286,6 @@ impl Default for Options { fix_errors: false, force: false, preserve_attrs: false, - verbosity: Some(0), filter, interlace: None, alphas, @@ -312,11 +308,9 @@ impl Default for Options { /// Perform optimization on the input file using the options provided pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<()> { // Read in the file and try to decode as PNG. - if opts.verbosity.is_some() { - eprintln!("Processing: {}", input); - } + info!("Processing: {}", input); - let deadline = Arc::new(Deadline::new(opts.timeout, opts.verbosity.is_some())); + let deadline = Arc::new(Deadline::new(opts.timeout)); let in_data = match *input { InFile::Path(ref input_path) => PngData::read_file(input_path)?, @@ -335,9 +329,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<( let mut optimized_output = optimize_png(&mut png, &in_data, opts, deadline)?; if is_fully_optimized(in_data.len(), optimized_output.len(), opts) { - if opts.verbosity.is_some() { - eprintln!("File already optimized"); - } + info!("File already optimized"); match (output, input) { // if p is None, it also means same as the input path (&OutFile::Path(ref p), &InFile::Path(ref input_path)) @@ -352,9 +344,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<( } if opts.pretend { - if opts.verbosity.is_some() { - eprintln!("Running in pretend mode, no output"); - } + info!("Running in pretend mode, no output"); return Ok(()); } @@ -382,7 +372,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<( })?; if opts.preserve_attrs { if let Some(input_path) = input.path() { - copy_permissions(input_path, &out_file, opts.verbosity); + copy_permissions(input_path, &out_file); } } @@ -394,9 +384,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<( e )) })?; - if opts.verbosity.is_some() { - eprintln!("Output: {}", output_path.display()); - } + info!("Output: {}", output_path.display()); } } Ok(()) @@ -406,11 +394,9 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<( /// loaded in-memory pub fn optimize_from_memory(data: &[u8], opts: &Options) -> PngResult> { // Read in the file and try to decode as PNG. - if opts.verbosity.is_some() { - eprintln!("Processing from memory"); - } + info!("Processing from memory"); - let deadline = Arc::new(Deadline::new(opts.timeout, opts.verbosity.is_some())); + let deadline = Arc::new(Deadline::new(opts.timeout)); let original_size = data.len(); let mut png = PngData::from_slice(data, opts.fix_errors)?; @@ -419,7 +405,7 @@ pub fn optimize_from_memory(data: &[u8], opts: &Options) -> PngResult> { let optimized_output = optimize_png(&mut png, data, opts, deadline)?; if is_fully_optimized(original_size, optimized_output.len(), opts) { - eprintln!("Image already optimized"); + warn!("Image already optimized"); Ok(data.to_vec()) } else { Ok(optimized_output) @@ -448,28 +434,26 @@ fn optimize_png( // Print png info let file_original_size = original_data.len(); let idat_original_size = png.idat_data.len(); - if opts.verbosity.is_some() { - eprintln!( - " {}x{} pixels, PNG format", - png.raw.ihdr.width, png.raw.ihdr.height + info!( + " {}x{} pixels, PNG format", + png.raw.ihdr.width, png.raw.ihdr.height + ); + if let Some(ref palette) = png.raw.palette { + info!( + " {} bits/pixel, {} colors in palette", + png.raw.ihdr.bit_depth, + palette.len() + ); + } else { + info!( + " {}x{} bits/pixel, {:?}", + png.raw.channels_per_pixel(), + png.raw.ihdr.bit_depth, + png.raw.ihdr.color_type ); - if let Some(ref palette) = png.raw.palette { - eprintln!( - " {} bits/pixel, {} colors in palette", - png.raw.ihdr.bit_depth, - palette.len() - ); - } else { - eprintln!( - " {}x{} bits/pixel, {:?}", - png.raw.channels_per_pixel(), - png.raw.ihdr.bit_depth, - png.raw.ihdr.color_type - ); - } - eprintln!(" IDAT size = {} bytes", idat_original_size); - eprintln!(" File size = {} bytes", file_original_size); } + info!(" IDAT size = {} bytes", idat_original_size); + info!(" File size = {} bytes", file_original_size); let mut filter = opts.filter.clone(); let mut strategies = match &opts.deflate { @@ -548,9 +532,7 @@ fn optimize_png( } } - if opts.verbosity.is_some() { - eprintln!("Trying: {} combinations", results.len()); - } + info!("Trying: {} combinations", results.len()); let filters: IndexMap> = filter .par_iter() @@ -586,8 +568,8 @@ fn optimize_png( let new_idat = match new_idat { Ok(n) => n, - Err(PngError::DeflatedDataTooLong(max)) if opts.verbosity == Some(1) => { - eprintln!( + Err(PngError::DeflatedDataTooLong(max)) => { + debug!( " zc = {} zs = {} f = {} >{} bytes", trial.compression, trial.strategy, trial.filter, max, ); @@ -600,15 +582,13 @@ fn optimize_png( let new_size = new_idat.len(); best_size.set_min(new_size); - if opts.verbosity == Some(1) { - eprintln!( - " zc = {} zs = {} f = {} {} bytes", - trial.compression, - trial.strategy, - trial.filter, - new_idat.len() - ); - } + debug!( + " zc = {} zs = {} f = {} {} bytes", + trial.compression, + trial.strategy, + trial.filter, + new_idat.len() + ); if new_size < original_len || added_interlacing || opts.force { Some((trial, new_idat)) @@ -624,19 +604,16 @@ fn optimize_png( } }); - if let Some(better) = best { - png.idat_data = better.1; - if opts.verbosity.is_some() { - let opts = better.0; - eprintln!("Found better combination:"); - eprintln!( - " zc = {} zs = {} f = {} {} bytes", - opts.compression, - opts.strategy, - opts.filter, - png.idat_data.len() - ); - } + if let Some((opts, idat_data)) = best { + png.idat_data = idat_data; + info!("Found better combination:"); + info!( + " zc = {} zs = {} f = {} {} bytes", + opts.compression, + opts.strategy, + opts.filter, + png.idat_data.len() + ); } else if reduction_occurred { *png = original_png; } @@ -646,35 +623,33 @@ fn optimize_png( let output = png.output(); - if opts.verbosity.is_some() { - if idat_original_size >= png.idat_data.len() { - eprintln!( - " IDAT size = {} bytes ({} bytes decrease)", - png.idat_data.len(), - idat_original_size - png.idat_data.len() - ); - } else { - eprintln!( - " IDAT size = {} bytes ({} bytes increase)", - png.idat_data.len(), - png.idat_data.len() - idat_original_size - ); - } - if file_original_size >= output.len() { - eprintln!( - " file size = {} bytes ({} bytes = {:.2}% decrease)", - output.len(), - file_original_size - output.len(), - (file_original_size - output.len()) as f64 / file_original_size as f64 * 100f64 - ); - } else { - eprintln!( - " file size = {} bytes ({} bytes = {:.2}% increase)", - output.len(), - output.len() - file_original_size, - (output.len() - file_original_size) as f64 / file_original_size as f64 * 100f64 - ); - } + if idat_original_size >= png.idat_data.len() { + info!( + " IDAT size = {} bytes ({} bytes decrease)", + png.idat_data.len(), + idat_original_size - png.idat_data.len() + ); + } else { + info!( + " IDAT size = {} bytes ({} bytes increase)", + png.idat_data.len(), + png.idat_data.len() - idat_original_size + ); + } + if file_original_size >= output.len() { + info!( + " file size = {} bytes ({} bytes = {:.2}% decrease)", + output.len(), + file_original_size - output.len(), + (file_original_size - output.len()) as f64 / file_original_size as f64 * 100f64 + ); + } else { + info!( + " file size = {} bytes ({} bytes = {:.2}% increase)", + output.len(), + output.len() - file_original_size, + (output.len() - file_original_size) as f64 / file_original_size as f64 * 100f64 + ); } let (old_png, new_png) = rayon::join( @@ -695,7 +670,7 @@ fn optimize_png( } } - eprintln!( + error!( "The resulting image is corrupted and will not be outputted.\nThis is a bug! Please report it at https://github.com/shssoichiro/oxipng/issues" ); Err(PngError::new("The resulting image is corrupted")) @@ -722,9 +697,7 @@ fn perform_reductions( if let Some(reduced) = reduced_palette(&png) { png = Arc::new(reduced); eval.try_image(png.clone()); - if opts.verbosity == Some(1) { - report_reduction(&png); - } + report_reduction(&png); } if deadline.passed() { return; @@ -745,9 +718,7 @@ fn perform_reductions( eval.try_image(Arc::new(reduced)); } } - if opts.verbosity == Some(1) { - report_reduction(&png); - } + report_reduction(&png); } if deadline.passed() { return; @@ -758,9 +729,7 @@ fn perform_reductions( if let Some(reduced) = reduce_color_type(&png) { png = Arc::new(reduced); eval.try_image(png.clone()); - if opts.verbosity == Some(1) { - report_reduction(&png); - } + report_reduction(&png); } if deadline.passed() { return; @@ -785,12 +754,12 @@ pub struct Deadline { } impl Deadline { - pub fn new(timeout: Option, verbose: bool) -> Self { + pub fn new(timeout: Option) -> Self { Self { imp: timeout.map(|timeout| DeadlineImp { start: Instant::now(), timeout, - print_message: AtomicBool::new(verbose), + print_message: AtomicBool::new(true), }), } } @@ -802,9 +771,11 @@ impl Deadline { if let Some(imp) = &self.imp { let elapsed = imp.start.elapsed(); if elapsed > imp.timeout { - if imp.print_message.load(Ordering::Relaxed) { - imp.print_message.store(false, Ordering::Relaxed); - eprintln!("Timed out after {} second(s)", elapsed.as_secs()); + if imp + .print_message + .compare_and_swap(true, false, Ordering::SeqCst) + { + warn!("Timed out after {} second(s)", elapsed.as_secs()); } return true; } @@ -816,13 +787,13 @@ impl Deadline { /// Display the status of the image data after a reduction has taken place fn report_reduction(png: &PngImage) { if let Some(ref palette) = png.palette { - eprintln!( + info!( "Reducing image to {} bits/pixel, {} colors in palette", png.ihdr.bit_depth, palette.len() ); } else { - eprintln!( + info!( "Reducing image to {}x{} bits/pixel, {}", png.channels_per_pixel(), png.ihdr.bit_depth, @@ -947,7 +918,7 @@ fn perform_backup(input_path: &Path) -> PngResult<()> { } #[cfg(not(unix))] -fn copy_permissions(input_path: &Path, out_file: &File, verbosity: Option) { +fn copy_permissions(input_path: &Path, out_file: &File) { if let Ok(f) = File::open(input_path) { if let Ok(metadata) = f.metadata() { if let Ok(out_meta) = out_file.metadata() { @@ -957,13 +928,11 @@ fn copy_permissions(input_path: &Path, out_file: &File, verbosity: Option) { } } }; - if verbosity.is_some() { - eprintln!("Failed to set permissions on output file"); - } + warn!("Failed to set permissions on output file"); } #[cfg(unix)] -fn copy_permissions(input_path: &Path, out_file: &File, verbosity: Option) { +fn copy_permissions(input_path: &Path, out_file: &File) { use std::os::unix::fs::PermissionsExt; if let Ok(f) = File::open(input_path) { @@ -975,9 +944,7 @@ fn copy_permissions(input_path: &Path, out_file: &File, verbosity: Option) { } } }; - if verbosity.is_some() { - eprintln!("Failed to set permissions on output file"); - } + warn!("Failed to set permissions on output file"); } /// Compares images pixel by pixel for equivalent content diff --git a/src/main.rs b/src/main.rs index a0dfe3c5..7a917dbf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,7 @@ use clap::{App, AppSettings, Arg, ArgMatches}; use indexmap::IndexSet; +use log::{error, info}; use oxipng::AlphaOptim; use oxipng::Deflaters; use oxipng::Headers; @@ -236,7 +237,7 @@ fn main() { let (out_file, out_dir, opts) = match parse_opts_into_struct(&matches) { Ok(x) => x, Err(x) => { - eprintln!("{}", x); + error!("{}", x); exit(1) } }; @@ -259,7 +260,7 @@ fn main() { .collect(); if let Err(e) = res { - eprintln!("{}", e); + error!("{}", e); exit(1); } } @@ -284,7 +285,7 @@ fn collect_files( .collect(); in_out_pairs.extend(collect_files(files, out_dir, out_file, recursive, false)); } else { - eprintln!("{} is a directory, skipping", input.display()); + info!("{} is a directory, skipping", input.display()); } continue; }; @@ -391,13 +392,13 @@ fn parse_opts_into_struct( opts.preserve_attrs = true; } - if matches.is_present("quiet") { - opts.verbosity = None; - } - - if matches.is_present("verbose") { - opts.verbosity = Some(1); - } + stderrlog::new() + .module(module_path!()) + .quiet(matches.is_present("quiet")) + .verbosity(if matches.is_present("verbose") { 3 } else { 2 }) + .show_level(false) + .init() + .unwrap(); if matches.is_present("no-bit-reduction") { opts.bit_depth_reduction = false;