image_optim 0.18.0 → 0.19.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.travis.yml +14 -17
- data/CHANGELOG.markdown +10 -0
- data/README.markdown +13 -3
- data/image_optim.gemspec +3 -3
- data/lib/image_optim.rb +16 -31
- data/lib/image_optim/bin_resolver.rb +3 -1
- data/lib/image_optim/bin_resolver/bin.rb +33 -24
- data/lib/image_optim/config.rb +5 -0
- data/lib/image_optim/runner/option_parser.rb +12 -5
- data/lib/image_optim/worker.rb +10 -62
- data/lib/image_optim/worker/class_methods.rb +89 -0
- data/lib/image_optim/worker/gifsicle.rb +25 -2
- data/lib/image_optim/worker/jpegrecompress.rb +44 -0
- data/lib/image_optim/worker/optipng.rb +1 -1
- data/script/update_worker_options_in_readme +6 -7
- data/script/worker_analysis +15 -5
- data/script/worker_analysis.haml +31 -10
- data/spec/image_optim/bin_resolver_spec.rb +52 -20
- data/spec/image_optim/worker_spec.rb +139 -0
- data/spec/image_optim_spec.rb +35 -53
- metadata +9 -7
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZDA2ZTJlMWRhYTk0MmEwNmI1MzI1M2I3NGMxNWFjYjIwYWU4ZTI4Yg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZTA5NWU3OGU1ZTFkMDBhMzBlZGUyZmZkNTI5MGNlOTE3NDgxMDYyNQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YTcxM2U5OGQwMTU1NzFmNzA4NGIyNzE2NWZmYjQ4ZDFmZDQ0ZjVlZWVhZGMw
|
10
|
+
OGIwMjFlZDYxMWI2NmJlY2FlNjQ5ZTE3NTE2OTRmOGQ3ODdjMmFlMTBlNGQ2
|
11
|
+
ODgzYjY3Yzc1ODViN2ZlN2I5NTYyYThkNDY5ODQzN2QxN2FhZDM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
Zjg1ZmJkYjQ3MmM0MDRmM2Y2ZWRhNGQwNGJhY2NhZTQ1Njg4YmQ0OWE2N2Zh
|
14
|
+
MTExZTM5MzkyNzZjM2Y4Y2I5ZDZiNWIyNmU0MDQyYzM2NGRkZTJmZDZhZjEx
|
15
|
+
MWJlNGUyYTRjODc4YWE1YzNmZThlYzFiYmM0YzAwODFmMjcxOTE=
|
data/.travis.yml
CHANGED
@@ -5,29 +5,26 @@ rvm:
|
|
5
5
|
- 1.9.3
|
6
6
|
- 2.0.0
|
7
7
|
- 2.1.0
|
8
|
-
- ruby-head
|
9
8
|
- jruby-18mode
|
10
9
|
- jruby-19mode
|
11
|
-
- jruby-head
|
12
10
|
- ree
|
13
11
|
script:
|
14
|
-
-
|
15
|
-
|
16
|
-
|
12
|
+
if [ -z "$RUBOCOP" ]; then
|
13
|
+
bundle exec image_optim --info
|
14
|
+
&& bundle exec rspec
|
15
|
+
; else
|
16
|
+
bundle exec rubocop
|
17
|
+
; fi
|
17
18
|
before_install:
|
18
|
-
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
- echo 'Installing pngout:'
|
24
|
-
- PNGOUT_VERSION=20130221
|
25
|
-
- curl -L "http://static.jonof.id.au/dl/kenutils/pngout-$PNGOUT_VERSION-linux.tar.gz" | tar -xz
|
26
|
-
- mv pngout-$PNGOUT_VERSION-linux/x86_64/pngout ~/bin
|
19
|
+
if [ -z "$RUBOCOP" ]; then
|
20
|
+
mkdir ~/bin
|
21
|
+
&& npm install -g svgo
|
22
|
+
&& 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'
|
23
|
+
; fi
|
27
24
|
env:
|
28
25
|
- PATH=~/bin:$PATH
|
29
26
|
matrix:
|
30
27
|
fast_finish: true
|
31
|
-
|
32
|
-
-
|
33
|
-
|
28
|
+
include:
|
29
|
+
- env: RUBOCOP=true
|
30
|
+
rvm: default
|
data/CHANGELOG.markdown
CHANGED
@@ -2,6 +2,16 @@
|
|
2
2
|
|
3
3
|
## unreleased
|
4
4
|
|
5
|
+
## v0.19.0 (2014-11-08)
|
6
|
+
|
7
|
+
* Added lossy worker `jpegrecompress` (uses [`jpeg-recompress`](https://github.com/danielgtaylor/jpeg-archive#jpeg-recompress)), disabled unless `:allow_lossy` is true [#65](https://github.com/toy/image_optim/issues/65) [@wjordan](https://github.com/wjordan) [@toy](https://github.com/toy)
|
8
|
+
* `:allow_lossy` option to allow lossy workers and optimizations [@toy](https://github.com/toy)
|
9
|
+
* Don't warn multiple times about problematic binary [#69](https://github.com/toy/image_optim/issues/69) [@toy](https://github.com/toy)
|
10
|
+
* Run gisicle two times (with interlace off then with on) if interlace is not set explicitly [#70](https://github.com/toy/image_optim/issues/70) [@toy](https://github.com/toy)
|
11
|
+
* Remove app and other extensions from gif images [@toy](https://github.com/toy)
|
12
|
+
* Change behaviour of gifsicle interlace option to deinterlace for `false`, pass `nil` to leave as is [@toy](https://github.com/toy)
|
13
|
+
* Worker can change its initialization by overriding `init` and can initialize multiple instances [#70](https://github.com/toy/image_optim/issues/70) [@toy](https://github.com/toy)
|
14
|
+
|
5
15
|
## v0.18.0 (2014-11-01)
|
6
16
|
|
7
17
|
* Add interface to `image_optim_pack` [@toy](https://github.com/toy)
|
data/README.markdown
CHANGED
@@ -6,13 +6,14 @@
|
|
6
6
|
|
7
7
|
# image_optim
|
8
8
|
|
9
|
-
Optimize (lossless compress) images (jpeg, png, gif, svg) using external utilities:
|
9
|
+
Optimize (lossless compress, optionally lossy) images (jpeg, png, gif, svg) using external utilities:
|
10
10
|
|
11
11
|
* [advpng](http://advancemame.sourceforge.net/doc-advpng.html) from [AdvanceCOMP](http://advancemame.sourceforge.net/comp-readme.html)
|
12
12
|
(will use [zopfli](https://code.google.com/p/zopfli/) on default/maximum level 4)
|
13
13
|
* [gifsicle](http://www.lcdf.org/gifsicle/)
|
14
14
|
* [jhead](http://www.sentex.net/~mwandel/jhead/)
|
15
15
|
* [jpegoptim](http://www.kokkonen.net/tjko/projects.html)
|
16
|
+
* [jpeg-recompress](https://github.com/danielgtaylor/jpeg-archive#jpeg-recompress)
|
16
17
|
* jpegtran from [Independent JPEG Group's JPEG library](http://www.ijg.org/)
|
17
18
|
* [optipng](http://optipng.sourceforge.net/)
|
18
19
|
* [pngcrush](http://pmt.sourceforge.net/pngcrush/)
|
@@ -173,6 +174,11 @@ _Note: pngout is free to use even in commercial soft, but you can not redistribu
|
|
173
174
|
npm install -g svgo
|
174
175
|
```
|
175
176
|
|
177
|
+
### jpeg-recompress installation (optional)
|
178
|
+
|
179
|
+
Download and install the `jpeg-recompress` binary from the [JPEG-Archive Releases](https://github.com/danielgtaylor/jpeg-archive/releases) page,
|
180
|
+
or follow the instructions to [build from source](https://github.com/danielgtaylor/jpeg-archive#building).
|
181
|
+
|
176
182
|
## Usage
|
177
183
|
|
178
184
|
### From shell
|
@@ -263,6 +269,7 @@ optipng:
|
|
263
269
|
* `:verbose` — Verbose output *(defaults to `false`)*
|
264
270
|
* `:pack` — Require image\_optim\_pack or disable it, by default image\_optim\_pack will be used if available, will turn on `:skip-missing-workers` unless explicitly disabled *(defaults to `nil`)*
|
265
271
|
* `:skip_missing_workers` — Skip workers with missing or problematic binaries *(defaults to `false`)*
|
272
|
+
* `:allow_lossy` — Allow lossy workers and optimizations *(defaults to `false`)*
|
266
273
|
|
267
274
|
Worker can be disabled by passing `false` instead of options hash.
|
268
275
|
|
@@ -273,7 +280,7 @@ Worker can be disabled by passing `false` instead of options hash.
|
|
273
280
|
* `:level` — Compression level: `0` - don't compress, `1` - fast, `2` - normal, `3` - extra, `4` - extreme *(defaults to `4`)*
|
274
281
|
|
275
282
|
### :gifsicle =>
|
276
|
-
* `:interlace` —
|
283
|
+
* `:interlace` — Interlace: `true` - interlace on, `false` - interlace off, `nil` - as is in original image (defaults to running two instances, one with interlace off and one with on)
|
277
284
|
* `:level` — Compression level: `1` - light and fast, `2` - normal, `3` - heavy (slower) *(defaults to `3`)*
|
278
285
|
* `:careful` — Avoid bugs with some software *(defaults to `false`)*
|
279
286
|
|
@@ -284,6 +291,9 @@ Worker has no options
|
|
284
291
|
* `:strip` — List of extra markers to strip: `:comments`, `:exif`, `:iptc`, `:icc` or `:all` *(defaults to `:all`)*
|
285
292
|
* `:max_quality` — Maximum image quality factor `0`..`100` *(defaults to `100`)*
|
286
293
|
|
294
|
+
### :jpegrecompress =>
|
295
|
+
* `:quality` — JPEG quality preset: `0` - low, `1` - medium, `2` - high, `3` - veryhigh *(defaults to `3`)*
|
296
|
+
|
287
297
|
### :jpegtran =>
|
288
298
|
* `:copy_chunks` — Copy all chunks *(defaults to `false`)*
|
289
299
|
* `:progressive` — Create progressive JPEG file *(defaults to `true`)*
|
@@ -291,7 +301,7 @@ Worker has no options
|
|
291
301
|
|
292
302
|
### :optipng =>
|
293
303
|
* `:level` — Optimization level preset: `0` is least, `7` is best *(defaults to `6`)*
|
294
|
-
* `:interlace` — Interlace
|
304
|
+
* `:interlace` — Interlace: `true` - interlace on, `false` - interlace off, `nil` - as is in original image *(defaults to `false`)*
|
295
305
|
|
296
306
|
### :pngcrush =>
|
297
307
|
* `:chunks` — List of chunks to remove or `:alla` - all except tRNS/transparency or `:allb` - all except tRNS and gAMA/gamma *(defaults to `:alla`)*
|
data/image_optim.gemspec
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'image_optim'
|
5
|
-
s.version = '0.
|
6
|
-
s.summary = %q{Optimize (lossless compress) images (jpeg, png, gif, svg) using external utilities (advpng, gifsicle, jhead, jpegoptim, jpegrescan, jpegtran, optipng, pngcrush, pngout, pngquant, svgo)}
|
5
|
+
s.version = '0.19.0'
|
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']
|
9
9
|
s.license = 'MIT'
|
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.add_dependency 'progress', '~> 3.0', '>= 3.0.1'
|
22
22
|
s.add_dependency 'in_threads', '~> 1.3'
|
23
23
|
|
24
|
-
s.add_development_dependency 'image_optim_pack', '~> 0.
|
24
|
+
s.add_development_dependency 'image_optim_pack', '~> 0.2'
|
25
25
|
s.add_development_dependency 'rspec', '~> 3.0'
|
26
26
|
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('1.9.3')
|
27
27
|
s.add_development_dependency 'rubocop', '~> 0.26.0'
|
data/lib/image_optim.rb
CHANGED
@@ -3,10 +3,20 @@ require 'image_optim/config'
|
|
3
3
|
require 'image_optim/handler'
|
4
4
|
require 'image_optim/image_meta'
|
5
5
|
require 'image_optim/image_path'
|
6
|
+
require 'image_optim/railtie' if defined?(Rails)
|
6
7
|
require 'image_optim/worker'
|
7
8
|
require 'in_threads'
|
8
9
|
require 'shellwords'
|
9
10
|
|
11
|
+
%w[
|
12
|
+
pngcrush pngout advpng optipng pngquant
|
13
|
+
jhead jpegoptim jpegrecompress jpegtran
|
14
|
+
gifsicle
|
15
|
+
svgo
|
16
|
+
].each do |worker|
|
17
|
+
require "image_optim/worker/#{worker}"
|
18
|
+
end
|
19
|
+
|
10
20
|
# Main interface
|
11
21
|
class ImageOptim
|
12
22
|
# Nice level
|
@@ -24,6 +34,9 @@ class ImageOptim
|
|
24
34
|
# Skip workers with missing or problematic binaries
|
25
35
|
attr_reader :skip_missing_workers
|
26
36
|
|
37
|
+
# Allow lossy workers and optimizations
|
38
|
+
attr_reader :allow_lossy
|
39
|
+
|
27
40
|
# Initialize workers, specify options using worker underscored name:
|
28
41
|
#
|
29
42
|
# pass false to disable worker
|
@@ -50,6 +63,7 @@ class ImageOptim
|
|
50
63
|
@verbose = config.verbose
|
51
64
|
@pack = config.pack
|
52
65
|
@skip_missing_workers = config.skip_missing_workers
|
66
|
+
@allow_lossy = config.allow_lossy
|
53
67
|
|
54
68
|
if verbose
|
55
69
|
$stderr << "config:\n"
|
@@ -60,11 +74,12 @@ class ImageOptim
|
|
60
74
|
$stderr << "threads: #{threads}\n"
|
61
75
|
$stderr << "pack: #{pack}\n"
|
62
76
|
$stderr << "skip_missing_workers: #{skip_missing_workers}\n"
|
77
|
+
$stderr << "allow_lossy: #{allow_lossy}\n"
|
63
78
|
end
|
64
79
|
|
65
80
|
@bin_resolver = BinResolver.new(self)
|
66
81
|
|
67
|
-
@workers_by_format =
|
82
|
+
@workers_by_format = Worker.create_all_by_format(self) do |klass|
|
68
83
|
config.for_worker(klass)
|
69
84
|
end
|
70
85
|
|
@@ -192,25 +207,6 @@ private
|
|
192
207
|
end
|
193
208
|
end
|
194
209
|
|
195
|
-
# Create hash with format mapped to list of workers sorted by run order
|
196
|
-
def create_workers_by_format(&options_proc)
|
197
|
-
by_format = {}
|
198
|
-
workers = Worker.create_all(self, &options_proc)
|
199
|
-
if skip_missing_workers
|
200
|
-
workers = Worker.reject_missing(workers)
|
201
|
-
else
|
202
|
-
Worker.resolve_all!(workers)
|
203
|
-
end
|
204
|
-
sorted = workers.sort_by.with_index{ |worker, i| [worker.run_order, i] }
|
205
|
-
sorted.each do |worker|
|
206
|
-
worker.image_formats.each do |format|
|
207
|
-
by_format[format] ||= []
|
208
|
-
by_format[format] << worker
|
209
|
-
end
|
210
|
-
end
|
211
|
-
by_format
|
212
|
-
end
|
213
|
-
|
214
210
|
# Run method for each item in list
|
215
211
|
# if block given yields item and result for item and returns array of yield
|
216
212
|
# results
|
@@ -235,14 +231,3 @@ private
|
|
235
231
|
end
|
236
232
|
end
|
237
233
|
end
|
238
|
-
|
239
|
-
%w[
|
240
|
-
pngcrush pngout advpng optipng pngquant
|
241
|
-
jhead jpegoptim jpegtran
|
242
|
-
gifsicle
|
243
|
-
svgo
|
244
|
-
].each do |worker|
|
245
|
-
require "image_optim/worker/#{worker}"
|
246
|
-
end
|
247
|
-
|
248
|
-
require 'image_optim/railtie' if defined?(Rails)
|
@@ -8,6 +8,7 @@ class ImageOptim
|
|
8
8
|
class BinResolver
|
9
9
|
# Holds bin name and path, gets version
|
10
10
|
class Bin
|
11
|
+
class UnknownVersion < Error; end
|
11
12
|
class BadVersion < Error; end
|
12
13
|
|
13
14
|
attr_reader :name, :path, :version
|
@@ -21,31 +22,39 @@ class ImageOptim
|
|
21
22
|
"#{name} #{version || '?'} at #{path}"
|
22
23
|
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
is = ComparableCondition.is
|
26
|
+
|
27
|
+
FAIL_CHECKS = [
|
28
|
+
[:pngcrush, is.between?('1.7.60', '1.7.65'), 'is known to produce '\
|
29
|
+
'broken pngs'],
|
30
|
+
[:pngquant, is < '2.0', 'is not supported'],
|
31
|
+
]
|
32
|
+
|
33
|
+
WARN_CHECKS = [
|
34
|
+
[:advpng, is < '1.17', 'does not use zopfli'],
|
35
|
+
[:pngquant, is < '2.1', 'may be lossy even with quality `100-`'],
|
36
|
+
[:gifsicle, is < '1.85', 'does not support removing extension blocks'],
|
37
|
+
]
|
38
|
+
|
39
|
+
# Fail if version will not work properly
|
40
|
+
def check_fail!
|
41
|
+
fail UnknownVersion, "didn't get version of #{self}" unless version
|
42
|
+
|
43
|
+
FAIL_CHECKS.each do |bin_name, matcher, message|
|
44
|
+
next unless bin_name == name
|
45
|
+
next unless matcher.match(version)
|
46
|
+
fail BadVersion, "#{self} (#{matcher}) #{message}"
|
28
47
|
end
|
48
|
+
end
|
29
49
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
case version
|
39
|
-
when c = is < '1.17'
|
40
|
-
warn "WARN: #{self} (#{c}) does not use zopfli"
|
41
|
-
end
|
42
|
-
when :pngquant
|
43
|
-
case version
|
44
|
-
when c = is < '2.0'
|
45
|
-
fail BadVersion, "#{self} (#{c}) is not supported"
|
46
|
-
when c = is < '2.1'
|
47
|
-
warn "WARN: #{self} (#{c}) may be lossy even with quality `100-`"
|
48
|
-
end
|
50
|
+
# Run check_fail!, otherwise warn if version is known to misbehave
|
51
|
+
def check!
|
52
|
+
check_fail!
|
53
|
+
|
54
|
+
WARN_CHECKS.each do |bin_name, matcher, message|
|
55
|
+
next unless bin_name == name
|
56
|
+
next unless matcher.match(version)
|
57
|
+
warn "WARN: #{self} (#{matcher}) #{message}"
|
49
58
|
end
|
50
59
|
end
|
51
60
|
|
@@ -64,7 +73,7 @@ class ImageOptim
|
|
64
73
|
capture("#{escaped_path} --version 2> /dev/null")[/\d+(\.\d+){1,}/]
|
65
74
|
when :svgo
|
66
75
|
capture("#{escaped_path} --version 2>&1")[/\d+(\.\d+){1,}/]
|
67
|
-
when :jhead
|
76
|
+
when :jhead, :'jpeg-recompress'
|
68
77
|
capture("#{escaped_path} -V 2> /dev/null")[/\d+(\.\d+){1,}/]
|
69
78
|
when :jpegtran
|
70
79
|
capture("#{escaped_path} -v - 2>&1")[/version (\d+\S*)/, 1]
|
data/lib/image_optim/config.rb
CHANGED
@@ -142,6 +142,11 @@ class ImageOptim
|
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
145
|
+
# Allow lossy workers and optimizations, converted to boolean
|
146
|
+
def allow_lossy
|
147
|
+
!!get!(:allow_lossy)
|
148
|
+
end
|
149
|
+
|
145
150
|
# Options for worker class by its `bin_sym`:
|
146
151
|
# * `Hash` passed as is
|
147
152
|
# * `{}` for `true` or `nil`
|
@@ -157,6 +157,13 @@ ImageOptim::Runner::OptionParser::DEFINE = proc do |op, options|
|
|
157
157
|
op.separator nil
|
158
158
|
op.separator ' Worker options:'
|
159
159
|
|
160
|
+
op.on('--allow-lossy', 'Allow lossy workers and '\
|
161
|
+
'optimizations') do |allow_lossy|
|
162
|
+
options[:allow_lossy] = allow_lossy
|
163
|
+
end
|
164
|
+
|
165
|
+
op.separator nil
|
166
|
+
|
160
167
|
ImageOptim::Worker.klasses.each_with_index do |klass, i|
|
161
168
|
next if klass.option_definitions.empty?
|
162
169
|
op.separator nil unless i.zero?
|
@@ -180,12 +187,12 @@ ImageOptim::Runner::OptionParser::DEFINE = proc do |op, options|
|
|
180
187
|
fail "Unknown type #{type}"
|
181
188
|
end
|
182
189
|
|
183
|
-
|
184
|
-
|
185
|
-
(defaults to #{default})
|
186
|
-
|
190
|
+
description = option_definition.description.gsub(' - ', ' - ')
|
191
|
+
unless description['(defaults']
|
192
|
+
description << " (defaults to #{default})"
|
193
|
+
end
|
187
194
|
|
188
|
-
op.on("--#{bin}-#{name} #{marking}", type,
|
195
|
+
op.on("--#{bin}-#{name} #{marking}", type, description) do |value|
|
189
196
|
options[bin] = {} unless options[bin].is_a?(Hash)
|
190
197
|
options[bin][option_definition.name.to_sym] = value
|
191
198
|
end
|
data/lib/image_optim/worker.rb
CHANGED
@@ -1,84 +1,32 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require 'image_optim/bin_resolver/error'
|
4
|
-
require 'image_optim/configuration_error'
|
5
|
-
require 'image_optim/option_definition'
|
6
|
-
require 'image_optim/option_helpers'
|
7
3
|
require 'image_optim/cmd'
|
4
|
+
require 'image_optim/configuration_error'
|
5
|
+
require 'image_optim/worker/class_methods'
|
8
6
|
require 'shellwords'
|
9
7
|
require 'English'
|
10
8
|
|
11
9
|
class ImageOptim
|
12
10
|
# Base class for all workers
|
13
11
|
class Worker
|
14
|
-
|
12
|
+
extend ClassMethods
|
15
13
|
|
16
14
|
class << self
|
17
|
-
#
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
# Remember all classes inheriting from this one
|
23
|
-
def inherited(base)
|
24
|
-
@klasses << base
|
25
|
-
end
|
26
|
-
|
27
|
-
# Underscored class name symbol
|
28
|
-
def bin_sym
|
29
|
-
@underscored_name ||= name.
|
30
|
-
split('::').last. # get last part
|
31
|
-
gsub(/([a-z])([A-Z])/, '\1_\2').downcase. # convert AbcDef to abc_def
|
32
|
-
to_sym
|
33
|
-
end
|
34
|
-
|
35
|
-
def option_definitions
|
36
|
-
@option_definitions ||= []
|
37
|
-
end
|
38
|
-
|
39
|
-
def option(name, default, type, description = nil, &proc)
|
40
|
-
attr_reader name
|
41
|
-
option_definitions <<
|
42
|
-
OptionDefinition.new(name, default, type, description, &proc)
|
43
|
-
end
|
44
|
-
|
45
|
-
# Initialize all workers using options from calling options_proc with
|
46
|
-
# klass
|
47
|
-
def create_all(image_optim, &options_proc)
|
48
|
-
Worker.klasses.map do |klass|
|
49
|
-
next unless (options = options_proc[klass])
|
50
|
-
klass.new(image_optim, options)
|
51
|
-
end.compact
|
52
|
-
end
|
53
|
-
|
54
|
-
# Resolve all bins of all workers failing with one joint exception
|
55
|
-
def resolve_all!(workers)
|
56
|
-
errors = BinResolver.collect_errors(workers) do |worker|
|
57
|
-
worker.resolve_used_bins!
|
58
|
-
end
|
59
|
-
return if errors.empty?
|
60
|
-
fail BinResolver::Error, ['Bin resolving errors:', *errors].join("\n")
|
61
|
-
end
|
62
|
-
|
63
|
-
# Resolve all bins of all workers showing warning for missing ones and
|
64
|
-
# returning others
|
65
|
-
def reject_missing(workers)
|
66
|
-
resolved = []
|
67
|
-
errors = BinResolver.collect_errors(workers) do |worker|
|
68
|
-
worker.resolve_used_bins!
|
69
|
-
resolved << worker
|
70
|
-
end
|
71
|
-
errors.each{ |error| warn error }
|
72
|
-
resolved
|
73
|
-
end
|
15
|
+
# Default init for worker is new
|
16
|
+
# Check example of override in gifsicle worker
|
17
|
+
alias_method :init, :new
|
74
18
|
end
|
75
19
|
|
20
|
+
# Allow lossy optimizations
|
21
|
+
attr_reader :allow_lossy
|
22
|
+
|
76
23
|
# Configure (raises on extra options)
|
77
24
|
def initialize(image_optim, options = {})
|
78
25
|
unless image_optim.is_a?(ImageOptim)
|
79
26
|
fail ArgumentError, 'first parameter should be an ImageOptim instance'
|
80
27
|
end
|
81
28
|
@image_optim = image_optim
|
29
|
+
@allow_lossy = !!options.delete(:allow_lossy)
|
82
30
|
self.class.option_definitions.each do |option_definition|
|
83
31
|
value = if options.key?(option_definition.name)
|
84
32
|
options[option_definition.name]
|