image_optim 0.18.0 → 0.19.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 +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]
|