image_optim 0.25.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
-
[](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)
|