This changes the evaluator to prefer a later image instead of an earlier
one in the case of a tie. This gives more consistent results since the
baseline is always added last.
I also removed bit depth from the key since the uncompressed size should
cover that.
Fixes#649.
(Mostly. I did discover another possible but very rare issue: if
multiple colours tie for "most popular edge colour" in the luma sort,
the sort may affect which one is actually picked and multiple runs may
flip-flop back and forth)
* Keep track of number of pixels in each scanline
* Expand depth to 8-bit
* Attempt expand bit depth
* Simplify tracking of reduction_occurred
* Fix test
* Simplify depth handling in reductions
* Add tests for disabled reductions
* Refactor filters as enum
* Include filter byte in filter output
* Add entropy filter
* Add bigrams filter
* Add bigram entropy filter
* Add brute filter
* Replace bit-vec
* Add tests and benches
* Show filters in help
* Use FxHasher in color to palette
* Use windows function for minor improvement
* Switch main compressor to libdeflate
* Use libdeflater in evaluate
* Use libdeflater to inflate
* Use libdeflater crc
* Tidy up
* Fix benches
* Allow libdeflater/freestanding feature
* Fix building without zopfli
* Switch to crossbeam-channel + rayon::spawn
* Remove thread_spawn for evaluation altogether
This allows to avoid a deadlock when there is only one Rayon thread, and doesn't sacrifice performance, since the caller of .get_result() had to always block on the iterator to be finished anyway, and all the messages are already sent from separate threads.
* Fix `verbose_mode` test
This one is easier to "fix", since we're in control of the rayon pool - just adding one extra thread to the default number to make sure we always can one root "spawn" call without stealing from the actual pool.
In order to avoid problems with mutable references,
the approach is to use the eval sender for non-parallel.
Computations will still be done synchronously
with the fake synchronous rayon module.
* Skip baselines earlier in the evaluator
We know that we'll throw them away anyway, so there is no point in even sending them to Sender and comparing them with others once we used them for the best candidate size.
* Simplify comparison logic
* Avoid using time API when we don't need it
This avoids a syscall to the time API when the result is ignored later anyway.
This allows to use the library with default options on wasm32-unknown-unknown, where the unimplemented syscall would panic otherwise.
* eval_send doesn't need to be an Option
We can drop the value manually, thus avoiding unwrap on each access.
* Keep single `use rayon::prelude::*`
If either `rayon` is already imported, then `rayon::prelude::*` should always resolve.
* Extract comparator
* Fully enable non-parallel mode
* Fix verbose message
* No cloning when restoring original data
* Make reductions return a new uncompressed image
Partially fixes#145
* Async reduction evaluator
* Assert
* Faster bit depth check
* Also try 4-bit depth for small-depth images
* Skip test when using miniz
* Ensure palette is trimmed after depth reduction
Fixes#159
* Fudge factor for reductions to prefer better reductions even if gzip estimation says otherwise