image_optim 0.22.1 → 0.23.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/.appveyor.yml +95 -0
- data/.rubocop.yml +3 -0
- data/.travis.yml +27 -22
- data/CHANGELOG.markdown +10 -0
- data/CONTRIBUTING.markdown +2 -1
- data/Gemfile +1 -1
- data/README.markdown +10 -2
- data/image_optim.gemspec +4 -4
- data/lib/image_optim.rb +32 -16
- data/lib/image_optim/bin_resolver/bin.rb +11 -4
- data/lib/image_optim/cache.rb +71 -0
- data/lib/image_optim/cache_path.rb +16 -0
- data/lib/image_optim/config.rb +12 -2
- data/lib/image_optim/handler.rb +1 -1
- data/lib/image_optim/image_meta.rb +5 -10
- data/lib/image_optim/optimized_path.rb +25 -0
- data/lib/image_optim/path.rb +70 -0
- data/lib/image_optim/runner/option_parser.rb +13 -0
- data/lib/image_optim/worker.rb +5 -8
- data/lib/image_optim/worker/class_methods.rb +3 -1
- data/lib/image_optim/worker/jpegoptim.rb +3 -0
- data/lib/image_optim/worker/jpegrecompress.rb +3 -0
- data/lib/image_optim/worker/pngquant.rb +3 -0
- data/script/worker_analysis +10 -9
- data/spec/image_optim/bin_resolver/comparable_condition_spec.rb +1 -1
- data/spec/image_optim/bin_resolver/simple_version_spec.rb +48 -40
- data/spec/image_optim/bin_resolver_spec.rb +190 -172
- data/spec/image_optim/cache_path_spec.rb +59 -0
- data/spec/image_optim/cache_spec.rb +159 -0
- data/spec/image_optim/cmd_spec.rb +11 -7
- data/spec/image_optim/config_spec.rb +92 -71
- data/spec/image_optim/handler_spec.rb +3 -6
- data/spec/image_optim/image_meta_spec.rb +61 -0
- data/spec/image_optim/optimized_path_spec.rb +58 -0
- data/spec/image_optim/option_helpers_spec.rb +25 -0
- data/spec/image_optim/path_spec.rb +105 -0
- data/spec/image_optim/railtie_spec.rb +6 -6
- data/spec/image_optim/runner/glob_helpers_spec.rb +2 -6
- data/spec/image_optim/runner/option_parser_spec.rb +3 -3
- data/spec/image_optim/space_spec.rb +16 -18
- data/spec/image_optim/worker/optipng_spec.rb +3 -3
- data/spec/image_optim/worker/pngquant_spec.rb +47 -7
- data/spec/image_optim/worker_spec.rb +114 -17
- data/spec/image_optim_spec.rb +58 -69
- data/spec/images/broken_jpeg +1 -0
- data/spec/spec_helper.rb +40 -10
- metadata +30 -8
- data/lib/image_optim/image_path.rb +0 -68
- data/spec/image_optim/image_path_spec.rb +0 -54
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MzcwOTc4MmMxMjI0YWM4YmQ2NzcyZTE0NTRkNjM4YjNlMmMwZGExMA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZmFmOWZhY2U5MTMyNjIwM2U3N2M0Y2U1NjVkNTJkNmNjYTk4NzQ0Yg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NDMyNWI3ODA2ZTg5NTFjN2Y3YTJjMzU5MjAzZGM4ZDg3NzU4Y2IzYjU3NGZl
|
10
|
+
NmJkN2JiMTg3YmMyNmJjZjFkMDRlOGVlYWIzYjg2MmVhYzMxYTY5YjE0NDc5
|
11
|
+
N2ZlMmU2ZTQxNTU4NGMyYzcxMjU3MDM2MTllZGMxZjhiYjc0Y2E=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
OWU2NjI5YjMyOWJmNmEzMGJjNGNmMjA0NmNlYWYyNzMxMDA0MTgyNDhjNmQz
|
14
|
+
NGU2NGY1Yzg4YzI3NTVkMjI4NTFiOGY1MzY0ZDlkYmI2MWFjNThmOTI3NGM0
|
15
|
+
M2ZmMjQ3OGIyZDc3YzY1NDI1MjU2N2U5ZDUyMDg3MDcwMzBkYTE=
|
data/.appveyor.yml
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
version: '{build}-{branch}'
|
2
|
+
install:
|
3
|
+
- mkdir tmp\bin || exit 0
|
4
|
+
- set PATH=%cd%\tmp\bin;%PATH%
|
5
|
+
- ruby --version
|
6
|
+
- bundle package --all
|
7
|
+
- echo curl.exe -fsSL --max-time 15 --retry 5 -o %%%%1 %%%%2 > tmp\bin\download.bat
|
8
|
+
|
9
|
+
- ps: | # advpng
|
10
|
+
if (-not (test-path tmp/bin/advpng.exe)) {
|
11
|
+
download.bat tmp/advancecomp.zip https://github.com/amadvance/advancecomp/releases/download/v1.20/advancecomp-1.20-windows-x86.zip
|
12
|
+
7z e tmp/advancecomp.zip -otmp/bin advpng.exe
|
13
|
+
}
|
14
|
+
|
15
|
+
- ps: | # gifsicle
|
16
|
+
if (-not (test-path tmp/bin/gifsicle.exe)) {
|
17
|
+
download.bat tmp/gifsicle.zip https://eternallybored.org/misc/gifsicle/releases/gifsicle-1.88-win64.zip
|
18
|
+
7z e tmp/gifsicle.zip -otmp/bin */gifsicle.exe
|
19
|
+
}
|
20
|
+
|
21
|
+
- ps: | # jhead
|
22
|
+
if (-not (test-path tmp/bin/jhead.exe)) {
|
23
|
+
download.bat tmp/bin/jhead.exe http://www.sentex.net/~mwandel/jhead/jhead.exe
|
24
|
+
}
|
25
|
+
|
26
|
+
- ps: | # jpeg-recompress
|
27
|
+
if (-not (test-path tmp/bin/jpeg-recompress.exe)) {
|
28
|
+
download.bat tmp/jpeg-archive.zip https://ci.appveyor.com/api/buildjobs/8t8vga27t8vn1js2/artifacts/jpeg-archive.zip
|
29
|
+
7z e tmp/jpeg-archive.zip -otmp/bin jpeg-recompress.exe
|
30
|
+
}
|
31
|
+
|
32
|
+
- ps: | # jpegoptim
|
33
|
+
if (-not (test-path tmp/bin/jpegoptim.exe)) {
|
34
|
+
download.bat tmp/jpegoptim.zip https://bitbucket.org/rorgoroth/jpegoptim-for-windows/downloads/jpegoptim-1.4.3-Win32.zip
|
35
|
+
7z e tmp/jpegoptim.zip -otmp/bin */jpegoptim.exe
|
36
|
+
}
|
37
|
+
|
38
|
+
- ps: | # jpegtran
|
39
|
+
if (-not (test-path tmp/bin/jpegtran.exe)) {
|
40
|
+
download.bat tmp/bin/jpegtran.exe http://jpegclub.org/jpegtran.exe
|
41
|
+
}
|
42
|
+
|
43
|
+
- ps: | # optipng
|
44
|
+
if (-not (test-path tmp/bin/optipng.exe)) {
|
45
|
+
download.bat tmp/optipng.zip https://sourceforge.net/projects/optipng/files/OptiPNG/optipng-0.7.6/optipng-0.7.6-win32.zip/download
|
46
|
+
7z e tmp/optipng.zip -otmp/bin */optipng.exe
|
47
|
+
}
|
48
|
+
|
49
|
+
- ps: | # pngcrush
|
50
|
+
if (-not (test-path tmp/bin/pngcrush.exe)) {
|
51
|
+
download.bat tmp/bin/pngcrush.exe https://sourceforge.net/projects/pmt/files/pngcrush-executables/1.8.1/pngcrush_1_8.1_w32.exe/download
|
52
|
+
}
|
53
|
+
|
54
|
+
- ps: | # pngout
|
55
|
+
if (-not (test-path tmp/bin/pngout.exe)) {
|
56
|
+
download.bat tmp/bin/pngout.exe http://advsys.net/ken/util/pngout.exe
|
57
|
+
}
|
58
|
+
|
59
|
+
- ps: | # pngquant
|
60
|
+
if (-not (test-path tmp/bin/pngquant.exe)) {
|
61
|
+
download.bat tmp/pngquant.zip https://pngquant.org/pngquant-windows.zip
|
62
|
+
7z e tmp/pngquant.zip -otmp/bin */pngquant.exe
|
63
|
+
}
|
64
|
+
|
65
|
+
- ps: | # svgo
|
66
|
+
npm install -g svgo
|
67
|
+
|
68
|
+
- ps: | # ImageMagick
|
69
|
+
if ((-not (test-path tmp/bin/convert.exe)) -or (-not (test-path tmp/bin/compare.exe)) -or (-not (test-path tmp/bin/magic.xml))) {
|
70
|
+
choco install -y imagemagick.tool
|
71
|
+
cp C:\ProgramData\chocolatey\lib\imagemagick.tool\tools\convert.exe tmp\bin
|
72
|
+
cp C:\ProgramData\chocolatey\lib\imagemagick.tool\tools\compare.exe tmp\bin
|
73
|
+
cp C:\ProgramData\chocolatey\lib\imagemagick.tool\tools\magic.xml tmp\bin
|
74
|
+
}
|
75
|
+
|
76
|
+
- bundle exec image_optim --info --allow-lossy --no-pack
|
77
|
+
cache:
|
78
|
+
- tmp/bin
|
79
|
+
build: off
|
80
|
+
test_script:
|
81
|
+
- ps: |
|
82
|
+
$path = $env:Path
|
83
|
+
$rubypaths = ls -Path C:\Ruby*\bin
|
84
|
+
foreach ($rubypath in $rubypaths[0, -2, -1]) {
|
85
|
+
echo "################################################################################"
|
86
|
+
$env:Path = "$rubypath;" + $path
|
87
|
+
ruby --version
|
88
|
+
bundle install --local -j4
|
89
|
+
bundle exec rspec
|
90
|
+
if ($LASTEXITCODE -gt 0) {
|
91
|
+
exit 1
|
92
|
+
}
|
93
|
+
}
|
94
|
+
$env:Path = $path
|
95
|
+
- bundle exec image_optim --allow-lossy -r spec/images
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -13,25 +13,30 @@ rvm:
|
|
13
13
|
- '2.2'
|
14
14
|
- jruby-19mode
|
15
15
|
- ree
|
16
|
-
script:
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
&&
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
16
|
+
script: |
|
17
|
+
(
|
18
|
+
set -ex
|
19
|
+
if [ -n "$RUBOCOP" ]; then
|
20
|
+
bundle exec rubocop
|
21
|
+
elif [ -n "$RAILS_VERSION" ] && [ -z "$CODECLIMATE" ]; then
|
22
|
+
bundle exec image_optim --info
|
23
|
+
bundle exec rspec spec/image_optim/railtie_spec.rb
|
24
|
+
else
|
25
|
+
bundle exec image_optim --info
|
26
|
+
bundle exec rspec
|
27
|
+
fi
|
28
|
+
)
|
29
|
+
before_install: |
|
30
|
+
(
|
31
|
+
set -ex
|
32
|
+
if [ -z "$RUBOCOP" ]; then
|
33
|
+
command -v svgo || npm install svgo
|
34
|
+
command -v pngout || {
|
35
|
+
mkdir -p ~/bin
|
36
|
+
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'
|
37
|
+
}
|
38
|
+
fi
|
39
|
+
)
|
35
40
|
matrix:
|
36
41
|
fast_finish: true
|
37
42
|
include:
|
@@ -40,9 +45,9 @@ matrix:
|
|
40
45
|
- env: RAILS_VERSION='~> 3.2'
|
41
46
|
rvm: default
|
42
47
|
- env: RAILS_VERSION='~> 4.0' SPROCKETS_RAILS_VERSION='~> 2.0'
|
43
|
-
rvm:
|
44
|
-
- env: RAILS_VERSION='~> 4.0'
|
45
|
-
rvm:
|
48
|
+
rvm: '2'
|
49
|
+
- env: RAILS_VERSION='~> 4.0' CODECLIMATE=1
|
50
|
+
rvm: '2'
|
46
51
|
- env: RUBOCOP=true
|
47
52
|
rvm: default
|
48
53
|
allow_failures:
|
data/CHANGELOG.markdown
CHANGED
@@ -2,6 +2,16 @@
|
|
2
2
|
|
3
3
|
## unreleased
|
4
4
|
|
5
|
+
## v0.23.0 (2016-07-17)
|
6
|
+
|
7
|
+
* Added `cache_dir` and `cache_worker_digests` options to cache results [#83](https://github.com/toy/image_optim/issues/83) [@gpakosz](https://github.com/gpakosz)
|
8
|
+
* Should work on windows [#24](https://github.com/toy/image_optim/issues/24) [@toy](https://github.com/toy)
|
9
|
+
* Rename `ImageOptim::ImagePath` to `ImageOptim::Path` and its method `#format` to `#image_format` [@toy](https://github.com/toy)
|
10
|
+
* Ignore empty config files [#133](https://github.com/toy/image_optim/issues/133) [@toy](https://github.com/toy)
|
11
|
+
* Use `FileUtils.move` in `ImagePath#replace` to rename file instead of copying on same device, don't preserve mtime and atime [#134](https://github.com/toy/image_optim/issues/134) [@toy](https://github.com/toy)
|
12
|
+
* Make `:allow_lossy` an individual option for workers that can use it, so it will be in the list of worker options [#130](https://github.com/toy/image_optim/issues/130) [@toy](https://github.com/toy)
|
13
|
+
* Use first 8 characters of sha1 hex for jpegrescan version [#131](https://github.com/toy/image_optim/issues/131) [@toy](https://github.com/toy)
|
14
|
+
|
5
15
|
## v0.22.1 (2016-02-21)
|
6
16
|
|
7
17
|
* Fix missing old (1.x) `pngquant` version as it was output to stderr [#123](https://github.com/toy/image_optim/issues/123) [@toy](https://github.com/toy)
|
data/CONTRIBUTING.markdown
CHANGED
@@ -2,9 +2,10 @@
|
|
2
2
|
|
3
3
|
* Create topic/feature branch: `git checkout -b awesome-changes`
|
4
4
|
* Commit…
|
5
|
-
* Add entry
|
5
|
+
* Add entry at the top of [ChangeLog](CHANGELOG.markdown)
|
6
6
|
* Run tests: `bundle exec rspec`
|
7
7
|
* Check code style: `bundle exec rubocop`
|
8
|
+
* Rebase on master and squash commits to logical units
|
8
9
|
* Push your branch: `git push origin awesome-changes`
|
9
10
|
* Create pull request
|
10
11
|
* Check if [travis is happy](https://travis-ci.org/toy/image_optim/pull_requests)
|
data/Gemfile
CHANGED
data/README.markdown
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
[](https://rubygems.org/gems/image_optim)
|
2
2
|
[](https://travis-ci.org/toy/image_optim)
|
3
|
+
[](https://ci.appveyor.com/project/toy/image-optim)
|
3
4
|
[](https://codeclimate.com/github/toy/image_optim)
|
4
5
|
[](https://codeclimate.com/github/toy/image_optim)
|
5
6
|
[](https://gemnasium.com/toy/image_optim)
|
6
|
-
[](https://inch-ci.org/github/toy/image_optim)
|
7
8
|
|
8
9
|
# image_optim
|
9
10
|
|
@@ -55,9 +56,11 @@ gem 'image_optim_pack'
|
|
55
56
|
|
56
57
|
With version:
|
57
58
|
|
59
|
+
<!---<update-version>-->
|
58
60
|
```ruby
|
59
|
-
gem 'image_optim', '~> 0.
|
61
|
+
gem 'image_optim', '~> 0.23'
|
60
62
|
```
|
63
|
+
<!---</update-version>-->
|
61
64
|
|
62
65
|
If you want to check latest changes:
|
63
66
|
|
@@ -271,6 +274,8 @@ optipng:
|
|
271
274
|
* `: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`)*
|
272
275
|
* `:skip_missing_workers` — Skip workers with missing or problematic binaries *(defaults to `false`)*
|
273
276
|
* `:allow_lossy` — Allow lossy workers and optimizations *(defaults to `false`)*
|
277
|
+
* `:cache_dir` — Configure cache directory
|
278
|
+
* `:cache_worker_digests` - Also cache worker digests along with original file digest and worker options: updating workers invalidates cache
|
274
279
|
|
275
280
|
Worker can be disabled by passing `false` instead of options hash or by setting option `:disable` to `true`.
|
276
281
|
|
@@ -289,10 +294,12 @@ Worker can be disabled by passing `false` instead of options hash or by setting
|
|
289
294
|
Worker has no options
|
290
295
|
|
291
296
|
### jpegoptim:
|
297
|
+
* `:allow_lossy` — Allow limiting maximum quality *(defaults to `false`)*
|
292
298
|
* `:strip` — List of extra markers to strip: `:comments`, `:exif`, `:iptc`, `:icc` or `:all` *(defaults to `:all`)*
|
293
299
|
* `:max_quality` — Maximum image quality factor `0`..`100`, ignored in default/lossless mode *(defaults to `100`)*
|
294
300
|
|
295
301
|
### jpegrecompress:
|
302
|
+
* `:allow_lossy` — Allow worker, it is always lossy *(defaults to `false`)*
|
296
303
|
* `:quality` — JPEG quality preset: `0` - low, `1` - medium, `2` - high, `3` - veryhigh *(defaults to `3`)*
|
297
304
|
|
298
305
|
### jpegtran:
|
@@ -316,6 +323,7 @@ Worker has no options
|
|
316
323
|
* `:strategy` — Strategy: `0` - xtreme, `1` - intense, `2` - longest Match, `3` - huffman Only, `4` - uncompressed *(defaults to `0`)*
|
317
324
|
|
318
325
|
### pngquant:
|
326
|
+
* `:allow_lossy` — Allow quality option *(defaults to `false`)*
|
319
327
|
* `:quality` — min..max - don't save below min, use less colors below max (both in range `0..100`; in yaml - `!ruby/range 0..100`), ignored in default/lossless mode *(defaults to `100..100`, `0..100` in lossy mode)*
|
320
328
|
* `:speed` — speed/quality trade-off: `1` - slow, `3` - default, `11` - fast & rough *(defaults to `3`)*
|
321
329
|
|
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.23.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']
|
@@ -15,15 +15,15 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
16
|
s.require_paths = %w[lib]
|
17
17
|
|
18
|
-
s.add_dependency 'fspath', '~>
|
18
|
+
s.add_dependency 'fspath', '~> 3.0'
|
19
19
|
s.add_dependency 'image_size', '~> 1.3'
|
20
20
|
s.add_dependency 'exifr', '~> 1.2', '>= 1.2.2'
|
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.2'
|
24
|
+
s.add_development_dependency 'image_optim_pack', '~> 0.2', '>= 0.2.2'
|
25
25
|
s.add_development_dependency 'rspec', '~> 3.0'
|
26
|
-
if
|
26
|
+
if RUBY_VERSION >= '1.9.3'
|
27
27
|
s.add_development_dependency 'rubocop', '~> 0.37'
|
28
28
|
end
|
29
29
|
end
|
data/lib/image_optim.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
require 'image_optim/bin_resolver'
|
2
|
+
require 'image_optim/cache'
|
2
3
|
require 'image_optim/config'
|
3
4
|
require 'image_optim/handler'
|
4
5
|
require 'image_optim/image_meta'
|
5
|
-
require 'image_optim/
|
6
|
+
require 'image_optim/optimized_path'
|
7
|
+
require 'image_optim/path'
|
6
8
|
require 'image_optim/railtie' if defined?(Rails)
|
7
9
|
require 'image_optim/worker'
|
8
10
|
require 'in_threads'
|
@@ -37,6 +39,12 @@ class ImageOptim
|
|
37
39
|
# Allow lossy workers and optimizations
|
38
40
|
attr_reader :allow_lossy
|
39
41
|
|
42
|
+
# Cache directory
|
43
|
+
attr_reader :cache_dir
|
44
|
+
|
45
|
+
# Cache worker digests
|
46
|
+
attr_reader :cache_worker_digests
|
47
|
+
|
40
48
|
# Initialize workers, specify options using worker underscored name:
|
41
49
|
#
|
42
50
|
# pass false to disable worker
|
@@ -67,6 +75,8 @@ class ImageOptim
|
|
67
75
|
pack
|
68
76
|
skip_missing_workers
|
69
77
|
allow_lossy
|
78
|
+
cache_dir
|
79
|
+
cache_worker_digests
|
70
80
|
].each do |name|
|
71
81
|
instance_variable_set(:"@#{name}", config.send(name))
|
72
82
|
$stderr << "#{name}: #{send(name)}\n" if verbose
|
@@ -78,6 +88,8 @@ class ImageOptim
|
|
78
88
|
config.for_worker(klass)
|
79
89
|
end
|
80
90
|
|
91
|
+
@cache = Cache.new(self, @workers_by_format)
|
92
|
+
|
81
93
|
log_workers_by_format if verbose
|
82
94
|
|
83
95
|
config.assert_no_unused_options!
|
@@ -85,39 +97,43 @@ class ImageOptim
|
|
85
97
|
|
86
98
|
# Get workers for image
|
87
99
|
def workers_for_image(path)
|
88
|
-
@workers_by_format[
|
100
|
+
@workers_by_format[Path.convert(path).image_format]
|
89
101
|
end
|
90
102
|
|
91
|
-
# Optimize one file, return new path as
|
103
|
+
# Optimize one file, return new path as OptimizedPath or nil if
|
92
104
|
# optimization failed
|
93
105
|
def optimize_image(original)
|
94
|
-
original =
|
106
|
+
original = Path.convert(original)
|
95
107
|
return unless (workers = workers_for_image(original))
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
108
|
+
|
109
|
+
optimized = @cache.fetch(original) do
|
110
|
+
Handler.for(original) do |handler|
|
111
|
+
workers.each do |worker|
|
112
|
+
handler.process do |src, dst|
|
113
|
+
worker.optimize(src, dst)
|
114
|
+
end
|
100
115
|
end
|
101
116
|
end
|
102
117
|
end
|
103
|
-
|
104
|
-
|
118
|
+
|
119
|
+
return unless optimized
|
120
|
+
OptimizedPath.new(optimized, original)
|
105
121
|
end
|
106
122
|
|
107
|
-
# Optimize one file in place, return original as
|
123
|
+
# Optimize one file in place, return original as OptimizedPath or nil if
|
108
124
|
# optimization failed
|
109
125
|
def optimize_image!(original)
|
110
|
-
original =
|
126
|
+
original = Path.convert(original)
|
111
127
|
return unless (result = optimize_image(original))
|
112
128
|
result.replace(original)
|
113
|
-
|
129
|
+
OptimizedPath.new(original, result.original_size)
|
114
130
|
end
|
115
131
|
|
116
132
|
# Optimize image data, return new data or nil if optimization failed
|
117
133
|
def optimize_image_data(original_data)
|
118
|
-
|
119
|
-
return unless
|
120
|
-
|
134
|
+
format = ImageMeta.format_for_data(original_data)
|
135
|
+
return unless format
|
136
|
+
Path.temp_file %W[image_optim .#{format}] do |temp|
|
121
137
|
temp.binmode
|
122
138
|
temp.write(original_data)
|
123
139
|
temp.close
|
@@ -2,7 +2,9 @@ require 'image_optim/bin_resolver/error'
|
|
2
2
|
require 'image_optim/bin_resolver/simple_version'
|
3
3
|
require 'image_optim/bin_resolver/comparable_condition'
|
4
4
|
require 'image_optim/cmd'
|
5
|
+
require 'image_optim/path'
|
5
6
|
require 'shellwords'
|
7
|
+
require 'digest/sha1'
|
6
8
|
|
7
9
|
class ImageOptim
|
8
10
|
class BinResolver
|
@@ -18,6 +20,11 @@ class ImageOptim
|
|
18
20
|
@version = detect_version
|
19
21
|
end
|
20
22
|
|
23
|
+
def digest
|
24
|
+
return @digest if defined?(@digest)
|
25
|
+
@digest = File.exist?(@path) && Digest::SHA1.file(@path).hexdigest
|
26
|
+
end
|
27
|
+
|
21
28
|
def to_s
|
22
29
|
"#{name} #{version || '?'} at #{path}"
|
23
30
|
end
|
@@ -73,11 +80,11 @@ class ImageOptim
|
|
73
80
|
def version_string
|
74
81
|
case name
|
75
82
|
when :advpng, :gifsicle, :jpegoptim, :optipng
|
76
|
-
capture("#{escaped_path} --version 2>
|
83
|
+
capture("#{escaped_path} --version 2> #{Path::NULL}")[/\d+(\.\d+)+/]
|
77
84
|
when :svgo, :pngquant
|
78
85
|
capture("#{escaped_path} --version 2>&1")[/\d+(\.\d+)+/]
|
79
86
|
when :jhead, :'jpeg-recompress'
|
80
|
-
capture("#{escaped_path} -V 2>
|
87
|
+
capture("#{escaped_path} -V 2> #{Path::NULL}")[/\d+(\.\d+)+/]
|
81
88
|
when :jpegtran
|
82
89
|
capture("#{escaped_path} -v - 2>&1")[/version (\d+\S*)/, 1]
|
83
90
|
when :pngcrush
|
@@ -87,8 +94,8 @@ class ImageOptim
|
|
87
94
|
date_str = capture("#{escaped_path} 2>&1")[date_regexp]
|
88
95
|
Date.parse(date_str).strftime('%Y%m%d') if date_str
|
89
96
|
when :jpegrescan
|
90
|
-
# jpegrescan has no version so
|
91
|
-
path
|
97
|
+
# jpegrescan has no version so use first 8 characters of sha1 hex
|
98
|
+
Digest::SHA1.file(path).hexdigest[0, 8] if path
|
92
99
|
else
|
93
100
|
fail "getting `#{name}` version is not defined"
|
94
101
|
end
|