image_optim 0.25.0 → 0.26.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/.rubocop.yml +4 -1
- data/.travis.yml +7 -8
- data/CHANGELOG.markdown +5 -0
- data/README.markdown +2 -6
- data/bin/image_optim +1 -1
- data/image_optim.gemspec +1 -1
- data/lib/image_optim/runner/option_parser.rb +3 -1
- data/lib/image_optim/worker.rb +2 -1
- data/lib/image_optim/worker/jpegtran.rb +1 -1
- data/vendor/jpegrescan +173 -0
- data/vendor/jpegrescan.bat +6 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1aeb8f8d2ab461d2e51a1956f736301d9c49bb86
|
4
|
+
data.tar.gz: 183e8cc5d1a0669a2f11292bf735e9cdf43ab642
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f06ddb5e329cd2592bfde66cabcc7cd10136c40b03f25c45ab872a1155cc3ba909da869ade47e59f038071c07c0cdc3d9408c869e7f799d9a9646f6b78f7d29
|
7
|
+
data.tar.gz: 44e30b8b6bd3e43d0dbe309bbc34ae6ced6725ec87fa3f3661572eb4906ceed6a9e149a51c669878e8eff42a554a898302e2b448af57f50d1bddf98e7a3cbcbc
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -40,6 +40,9 @@ Lint/AmbiguousBlockAssociation:
|
|
40
40
|
Lint/EndAlignment:
|
41
41
|
EnforcedStyleAlignWith: variable
|
42
42
|
|
43
|
+
Lint/RescueWithoutErrorClass:
|
44
|
+
Enabled: false
|
45
|
+
|
43
46
|
Lint/UnneededSplatExpansion:
|
44
47
|
Enabled: false
|
45
48
|
|
@@ -78,7 +81,7 @@ Style/EmptyCaseCondition:
|
|
78
81
|
Enabled: false
|
79
82
|
|
80
83
|
Style/Encoding:
|
81
|
-
|
84
|
+
Enabled: false
|
82
85
|
|
83
86
|
Style/HashSyntax:
|
84
87
|
EnforcedStyle: hash_rockets
|
data/.travis.yml
CHANGED
@@ -10,10 +10,9 @@ rvm:
|
|
10
10
|
- '1.9.3-p551'
|
11
11
|
- '2.0.0-p648'
|
12
12
|
- '2.1.10'
|
13
|
-
- '2.2.
|
14
|
-
- '2.3.
|
15
|
-
- '2.4.
|
16
|
-
- 'jruby-1.7.26'
|
13
|
+
- '2.2.8'
|
14
|
+
- '2.3.5'
|
15
|
+
- '2.4.2'
|
17
16
|
- 'jruby-9.0.5.0'
|
18
17
|
- 'jruby-9.1.9.0'
|
19
18
|
script:
|
@@ -24,19 +23,19 @@ before_install:
|
|
24
23
|
- gem update bundler
|
25
24
|
- nvm install stable
|
26
25
|
- mkdir -p ~/bin
|
27
|
-
- command -v svgo || npm install svgo
|
26
|
+
- command -v svgo || npm install -g svgo
|
28
27
|
- command -v pngout || curl -L "http://static.jonof.id.au/dl/kenutils/pngout-20130221-linux.tar.gz" | tar -xz -C ~/bin --strip-components 2 --wildcards '*/x86_64/pngout'
|
29
28
|
matrix:
|
30
29
|
include:
|
31
30
|
- env: CODECLIMATE=✓
|
32
|
-
rvm: '2.4.
|
31
|
+
rvm: '2.4.2'
|
33
32
|
after_success: bundle exec codeclimate-test-reporter
|
34
33
|
- env: RUBOCOP=✓
|
35
|
-
rvm: '2.4.
|
34
|
+
rvm: '2.4.2'
|
36
35
|
script: bundle exec rubocop
|
37
36
|
before_install:
|
38
37
|
- env: CHECK_RUBIES=✓
|
39
|
-
rvm: '2.4.
|
38
|
+
rvm: '2.4.2'
|
40
39
|
script: bundle exec travis_check_rubies
|
41
40
|
before_install:
|
42
41
|
addons:
|
data/CHANGELOG.markdown
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
## unreleased
|
4
4
|
|
5
|
+
## v0.26.0 (2017-11-13)
|
6
|
+
|
7
|
+
* Enable `jpegrescan` by default after removing its dependency on `File::Slurp` and fixing for windows [#153](https://github.com/toy/image_optim/issues/153) [@toy](https://github.com/toy)
|
8
|
+
* Extend description of `--verbose` flag [#152](https://github.com/toy/image_optim/issues/152) [@toy](https://github.com/toy)
|
9
|
+
|
5
10
|
## v0.25.0 (2017-07-06)
|
6
11
|
|
7
12
|
* Fix error `uninitialized constant EXIFR::JPEG` (breaking change in [exifr v1.3.0](https://github.com/remvee/exifr/commit/e073a22d06c39f2c1c0e77f5b5fe71545b25e967)) [#150](https://github.com/toy/image_optim/pull/150) [@abemedia](https://github.com/abemedia)
|
data/README.markdown
CHANGED
@@ -58,7 +58,7 @@ With version:
|
|
58
58
|
|
59
59
|
<!---<update-version>-->
|
60
60
|
```ruby
|
61
|
-
gem 'image_optim', '~> 0.
|
61
|
+
gem 'image_optim', '~> 0.26'
|
62
62
|
```
|
63
63
|
<!---</update-version>-->
|
64
64
|
|
@@ -300,7 +300,7 @@ Worker has no options
|
|
300
300
|
### jpegtran:
|
301
301
|
* `:copy_chunks` — Copy all chunks *(defaults to `false`)*
|
302
302
|
* `:progressive` — Create progressive JPEG file *(defaults to `true`)*
|
303
|
-
* `:jpegrescan` — Use jpegtran through jpegrescan, ignore progressive option *(defaults to `
|
303
|
+
* `:jpegrescan` — Use jpegtran through jpegrescan, ignore progressive option *(defaults to `true`)*
|
304
304
|
|
305
305
|
### optipng:
|
306
306
|
* `:level` — Optimization level preset: `0` is least, `7` is best *(defaults to `6`)*
|
@@ -335,10 +335,6 @@ Worker has no options
|
|
335
335
|
|
336
336
|
If you would like to contribute - that is great and you are very welcome. Please check few notes in file [CONTRIBUTING.markdown](CONTRIBUTING.markdown).
|
337
337
|
|
338
|
-
Financial contributions can be made via [gratipay](https://gratipay.com/toy/).
|
339
|
-
|
340
|
-
[![Support via Gratipay](https://cdn.rawgit.com/gratipay/gratipay-badge/2.1.2/dist/gratipay.png)](https://gratipay.com/toy/)
|
341
|
-
|
342
338
|
## ChangeLog
|
343
339
|
|
344
340
|
In separate file [CHANGELOG.markdown](CHANGELOG.markdown).
|
data/bin/image_optim
CHANGED
data/image_optim.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'image_optim'
|
5
|
-
s.version = '0.
|
5
|
+
s.version = '0.26.0'
|
6
6
|
s.summary = %q{Optimize (lossless compress, optionally lossy) images (jpeg, png, gif, svg) using external utilities (advpng, gifsicle, jhead, jpeg-recompress, jpegoptim, jpegrescan, jpegtran, optipng, pngcrush, pngout, pngquant, svgo)}
|
7
7
|
s.homepage = "http://github.com/toy/#{s.name}"
|
8
8
|
s.authors = ['Ivan Kuchin']
|
@@ -221,7 +221,9 @@ ImageOptim::Runner::OptionParser::DEFINE = proc do |op, options|
|
|
221
221
|
op.separator nil
|
222
222
|
op.separator ' Common options:'
|
223
223
|
|
224
|
-
op.on_tail('-v', '--verbose', 'Verbose output'
|
224
|
+
op.on_tail('-v', '--verbose', 'Verbose output (show global and worker '\
|
225
|
+
'config, binary resolution log, information about each tool invocation, '\
|
226
|
+
'backtrace of exception)') do
|
225
227
|
options[:verbose] = true
|
226
228
|
end
|
227
229
|
|
data/lib/image_optim/worker.rb
CHANGED
@@ -14,7 +14,7 @@ class ImageOptim
|
|
14
14
|
option(:progressive, true, 'Create progressive JPEG file'){ |v| !!v }
|
15
15
|
|
16
16
|
JPEGRESCAN_OPTION =
|
17
|
-
option(:jpegrescan,
|
17
|
+
option(:jpegrescan, true, 'Use jpegtran through jpegrescan, '\
|
18
18
|
'ignore progressive option'){ |v| !!v }
|
19
19
|
|
20
20
|
def used_bins
|
data/vendor/jpegrescan
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
#!/usr/bin/env perl
|
2
|
+
# jpegrescan by Loren Merritt
|
3
|
+
# Last updated: 2008-11-29 / 2013-03-19
|
4
|
+
# This code is public domain.
|
5
|
+
|
6
|
+
use warnings;
|
7
|
+
use File::Temp qw/ tempfile /;
|
8
|
+
|
9
|
+
%switches = ();
|
10
|
+
while (@ARGV && $ARGV[0] =~ /^-.+/) {
|
11
|
+
for (shift @ARGV) {
|
12
|
+
m/^--$/ && last;
|
13
|
+
m/^-([svq])$/ && do { $switches{$1} = 1; next; };
|
14
|
+
die "Unknown switch: $_";
|
15
|
+
}
|
16
|
+
}
|
17
|
+
@ARGV==2 or die "usage: jpegrescan in.jpg out.jpg
|
18
|
+
tries various progressive scan orders
|
19
|
+
switches:
|
20
|
+
-s strip from all extra markers (`jpegtran -copy none` otherwise `jpegtran -copy all`)
|
21
|
+
-v verbose output
|
22
|
+
-q supress all output
|
23
|
+
";
|
24
|
+
$fin = $ARGV[0];
|
25
|
+
$fout = $ARGV[1];
|
26
|
+
(undef, $meta_tmp) = tempfile(SUFFIX => ".scan");
|
27
|
+
(undef, $baseline_tmp) = tempfile(SUFFIX => ".jpg");
|
28
|
+
$output_tmp = $fout;
|
29
|
+
$verbose = $switches{'v'};
|
30
|
+
$quiet = $switches{'q'};
|
31
|
+
@strip = $switches{'s'} ? ("-copy","none") : ("-copy","all");
|
32
|
+
undef $/;
|
33
|
+
$|=1;
|
34
|
+
|
35
|
+
sub read_file {
|
36
|
+
my ($path) = @_;
|
37
|
+
my $data;
|
38
|
+
|
39
|
+
open my $fh, '<', $path
|
40
|
+
or die "Could not open file $path: $!\n";
|
41
|
+
binmode $fh;
|
42
|
+
$data = <$fh>;
|
43
|
+
close $fh
|
44
|
+
or die "Could not close $path: $!\n";
|
45
|
+
|
46
|
+
return $data;
|
47
|
+
}
|
48
|
+
|
49
|
+
sub write_file {
|
50
|
+
my ($path, $data) = @_;
|
51
|
+
|
52
|
+
open my $fh, '>', $path
|
53
|
+
or die "Could not open file $path: $!\n";
|
54
|
+
binmode $fh;
|
55
|
+
print $fh $data;
|
56
|
+
close $fh
|
57
|
+
or die "Could not close $path: $!\n";
|
58
|
+
}
|
59
|
+
|
60
|
+
# convert the input to baseline, just to make all the other conversions faster
|
61
|
+
# FIXME there's still a bunch of redundant computation in separate calls to jpegtran
|
62
|
+
open $OLDERR, ">&", STDERR;
|
63
|
+
open STDERR, ">", $meta_tmp;
|
64
|
+
system("jpegtran", "-v", @strip, "-optimize", "-outfile", $baseline_tmp, $fin) == 0 or die;
|
65
|
+
open STDERR, ">&", $OLDERR;
|
66
|
+
|
67
|
+
$type = read_file($meta_tmp);
|
68
|
+
$type =~ /components=(\d+)/ or die "Could not find components=\d+ in $type";
|
69
|
+
$rgb = $1==3 ? 1 : $1==1 ? 0 : die "not RGB nor gray\n";
|
70
|
+
|
71
|
+
# FIXME optimize order for either progressive transfer or decoding speed
|
72
|
+
sub canonize {
|
73
|
+
my $txt = $prefix.$suffix.shift;
|
74
|
+
$txt =~ s/\s*;\s*/;\n/g;
|
75
|
+
$txt =~ s/^\s*//;
|
76
|
+
$txt =~ s/ +/ /g;
|
77
|
+
$txt =~ s/: (\d+) (\d+)/sprintf ": %2d %2d", $1, $2/ge;
|
78
|
+
# treat u and v identically. I shouldn't need to do this, but with jpegtran overhead it saves 9% speed. cost: .008% bitrate.
|
79
|
+
$txt =~ s/^2:.*\n//gm;
|
80
|
+
$txt =~ s/^1:(.+)\n/1:$1\n2:$1\n/gm;
|
81
|
+
# dc before ac, coarse before fine
|
82
|
+
my @txt = sort {"$a\n$b" =~ /: *(\d+) .* (\d);\n.*: *(\d+) .* (\d);/ or die; !$3 <=> !$1 or $4 <=> $2 or $a cmp $b;} split /\n/, $txt;
|
83
|
+
return join "\n", @txt;
|
84
|
+
}
|
85
|
+
|
86
|
+
sub try {
|
87
|
+
my $txt = canonize(shift);
|
88
|
+
return $memo{$txt} if $memo{$txt};
|
89
|
+
write_file($meta_tmp, $txt);
|
90
|
+
system("jpegtran", @strip, "-scans", $meta_tmp, "-outfile", $output_tmp, $baseline_tmp) == 0 or die;
|
91
|
+
$data = read_file($output_tmp);
|
92
|
+
my $s = length $data;
|
93
|
+
$s or die;
|
94
|
+
$memo{$txt} = $s;
|
95
|
+
!$quiet && print $verbose ? "$txt\n$s\n\n" : ".";
|
96
|
+
return $s;
|
97
|
+
}
|
98
|
+
|
99
|
+
sub triesn {
|
100
|
+
my($bmode, $bsize);
|
101
|
+
my ($limit, @modes) = @_;
|
102
|
+
my $overshoot = 0;
|
103
|
+
for(@modes) {
|
104
|
+
my $s = try($_);
|
105
|
+
if(!$bsize || $s < $bsize) {
|
106
|
+
$bsize = $s;
|
107
|
+
$bmode = $_;
|
108
|
+
$overshoot = 0;
|
109
|
+
} elsif(++$overshoot >= $limit) {
|
110
|
+
last;
|
111
|
+
}
|
112
|
+
}
|
113
|
+
return $bmode;
|
114
|
+
}
|
115
|
+
|
116
|
+
sub tries { triesn(99, @_); }
|
117
|
+
|
118
|
+
$prefix = "";
|
119
|
+
$suffix = "";
|
120
|
+
|
121
|
+
if($rgb) {
|
122
|
+
# 012 helps very little
|
123
|
+
# 0/12 and 0/1/2 are pretty evenly matched in frequency, but 0/12 wins in total size if every image had to use the same mode
|
124
|
+
# dc refinement passes never help
|
125
|
+
$dc = tries(
|
126
|
+
# "0: 0 0 0 0; 1 2: 0 0 0 0;", # two scans expose a bug in Opera <= 11.61
|
127
|
+
"0: 0 0 0 0; 1: 0 0 0 0; 2: 0 0 0 0;");
|
128
|
+
# jpegtran won't let me omit dc entirely, but I can at least quantize it away to make the rest of the tests faster.
|
129
|
+
$prefix = "0 1 2: 0 0 0 9;";
|
130
|
+
} else {
|
131
|
+
$dc = "0: 0 0 0 0;";
|
132
|
+
$prefix = "0: 0 0 0 9;";
|
133
|
+
}
|
134
|
+
|
135
|
+
# luma can make use of up to 3 refinement passes.
|
136
|
+
# chroma can make use of up to 2 refinement passes.
|
137
|
+
# refinement passes have some chance of being split (luma: 4%,4%,4%. chroma: 20%,8%) but the total bit gain is negligible.
|
138
|
+
# msb pass should almost always be split (luma: 87%, chroma: 81%).
|
139
|
+
# I have no theoretical reason for this list of split positions, they're just the most common in practice.
|
140
|
+
# splitting into 3 ections is often slightly better, but the total number of bits saved is negligible.
|
141
|
+
# FIXME: penalize lots of refinement passes because it's slower to decode. if so, then also force overwrite if bigger than the input.
|
142
|
+
sub try_splits {
|
143
|
+
my $str = shift;
|
144
|
+
my %n = map {$_ => sprintf "$c: 1 %d $str; $c: %d 63 $str;", $_, $_+1} 2,5,8,12,18;
|
145
|
+
my $mode = triesn(2, "$c: 1 63 $str;", @n{2,8,5});
|
146
|
+
return $mode if $mode ne $n{8};
|
147
|
+
return triesn(1, $mode, @n{12,18});
|
148
|
+
}
|
149
|
+
|
150
|
+
foreach $c (0..$rgb) {
|
151
|
+
my @modes;
|
152
|
+
my $ml = "";
|
153
|
+
for(0..($c?2:3)) {
|
154
|
+
push @modes, "$c: 1 8 0 $_; $c: 9 63 0 $_;".$ml;
|
155
|
+
$ml .= sprintf("$c: 1 63 %d %d;", $_+1, $_);
|
156
|
+
}
|
157
|
+
my $refine = triesn(1, @modes);
|
158
|
+
$refine =~ s/.* (0 \d);//;
|
159
|
+
$ac .= $refine . try_splits($1);
|
160
|
+
}
|
161
|
+
|
162
|
+
$prefix = "";
|
163
|
+
undef %memo;
|
164
|
+
$mode = canonize($dc.$ac);
|
165
|
+
try($mode);
|
166
|
+
$size = $memo{$mode};
|
167
|
+
!$quiet && print "\n$mode\n$size\n";
|
168
|
+
$old_size = -s $fin;
|
169
|
+
!$quiet && printf "%+.2f%%\n", ($size/$old_size-1)*100;
|
170
|
+
if($size < $old_size) {
|
171
|
+
write_file($fout, $data);
|
172
|
+
}
|
173
|
+
unlink $meta_tmp, $baseline_tmp;
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: image_optim
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.26.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Kuchin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-11-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fspath
|
@@ -250,6 +250,7 @@ files:
|
|
250
250
|
- spec/images/vergroessert.jpg
|
251
251
|
- spec/spec_helper.rb
|
252
252
|
- vendor/jpegrescan
|
253
|
+
- vendor/jpegrescan.bat
|
253
254
|
homepage: http://github.com/toy/image_optim
|
254
255
|
licenses:
|
255
256
|
- MIT
|
@@ -272,7 +273,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
272
273
|
version: '0'
|
273
274
|
requirements: []
|
274
275
|
rubyforge_project: image_optim
|
275
|
-
rubygems_version: 2.6.
|
276
|
+
rubygems_version: 2.6.14
|
276
277
|
signing_key:
|
277
278
|
specification_version: 4
|
278
279
|
summary: Optimize (lossless compress, optionally lossy) images (jpeg, png, gif, svg)
|