image_compressor_pack 0.1.3 → 1.0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.travis.yml +7 -4
- data/CHANGELOG.md +4 -0
- data/README.md +25 -2
- data/Rakefile +3 -3
- data/image_compressor_pack.gemspec +1 -2
- data/lib/image_compressor_pack/dynamically_linked_recipes.yml +24 -21
- data/lib/image_compressor_pack/statically_linked_recipes.yml +25 -22
- data/lib/image_compressor_pack/version.rb +1 -1
- data/ports/archives/advancecomp-1.22.tar.gz +0 -0
- data/ports/archives/jpegoptim-1.4.4.tar.gz +0 -0
- data/ports/archives/lcms2-2.8.tar.gz +0 -0
- data/ports/archives/libpng-1.6.26.tar.gz +0 -0
- data/ports/archives/nasm-2.12.02.tar.gz +0 -0
- data/ports/archives/pngcrush-1.8.10.tar.gz +0 -0
- data/ports/archives/pngquant-2.8.0-src.tar.gz +0 -0
- data/ports/patches/advancecomp/0001-Add-missing-libdeflate-header-file.patch +305 -0
- data/ports/patches/libpng/0001-Do-not-build-binary-utilities.patch +211 -117
- data/ports/patches/pngcrush/0001-Add-an-install-task.patch +7 -7
- data/ports/patches/pngcrush/0002-Add-a-configure-script.patch +3 -3
- data/ports/patches/pngcrush/0003-Use-cc-by-default-instead-of-gcc.patch +7 -16
- data/ports/patches/pngcrush/0004-Produce-a-static-binary.patch +6 -6
- data/ports/patches/pngquant/0001-Work-around-mini-portile-s-configure-invocation.patch +25 -19
- data/ports/patches/pngquant/0002-Add-default-LDFLAGS.patch +4 -4
- data/ports/patches/pngquant/0003-Disable-libpng-check.patch +4 -4
- data/ports/patches/pngquant/0004-Remove-libz-check.patch +5 -5
- data/ports/patches/pngquant/0005-Remove-lcms2-check.patch +5 -5
- data/ports/patches/pngquant/0006-Do-not-build-static-binary.patch +4 -4
- data/ports/patches/pngquant/0007-Use-cc-instead-of-gcc-by-default.patch +4 -4
- metadata +12 -15
- metadata.gz.sig +0 -0
- data/bin/console +0 -14
- data/bin/setup +0 -7
- data/ports/archives/2.7.1.tar.gz +0 -0
- data/ports/archives/advancecomp-1.20.tar.gz +0 -0
- data/ports/archives/jpegoptim-1.4.3.tar.gz +0 -0
- data/ports/archives/lcms2-2.7.tar.gz +0 -0
- data/ports/archives/libpng-1.6.21.tar.gz +0 -0
- data/ports/archives/nasm-2.12.01.tar.gz +0 -0
- data/ports/archives/pngcrush-1.8.1.tar.gz +0 -0
- data/release/x86-linux/Vagrantfile +0 -84
- data/release/x86_64-freebsd10/Vagrantfile +0 -86
- data/release/x86_64-linux/Vagrantfile +0 -84
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d606ee12c458166ec47cd3361c4a7471794bba5
|
4
|
+
data.tar.gz: dc04a1f472898c69bf4948019edd4eaf631e4902
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ebb60121f6caa9ae3da7d1abd1fdea2b55272cd53fa8539df39635ce1055ccb940d28ed7f5490e73a35867516304d7269c1c7330cf2bf73659306d9f8f6a617
|
7
|
+
data.tar.gz: 5484d315f7b21f52c05283a4e0454f5d77b4c227d0532fb510772a80a0fdfc4a489680b061db464962cc857a3f9b101a8d4bf8a7058127f4d340cb878d512a37
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/.travis.yml
CHANGED
@@ -6,17 +6,20 @@ matrix:
|
|
6
6
|
- rvm: 2.2
|
7
7
|
os: osx
|
8
8
|
osx_image: xcode7.3
|
9
|
+
- rvm: 2.3.2
|
10
|
+
os: osx
|
11
|
+
osx_image: xcode8.1
|
9
12
|
- rvm: jruby-9.0.5.0
|
10
13
|
jdk: oraclejdk8
|
11
|
-
- rvm: 2.3.
|
14
|
+
- rvm: 2.3.2
|
12
15
|
dist: trusty
|
13
16
|
sudo: true
|
14
|
-
- rvm: 2.2
|
15
|
-
os: osx
|
16
|
-
osx_image: xcode6.4
|
17
17
|
- rvm: system
|
18
18
|
os: osx
|
19
19
|
osx_image: xcode7.3
|
20
|
+
- rvm: system
|
21
|
+
os: osx
|
22
|
+
osx_image: xcode8.1
|
20
23
|
- rvm: 1.9.3
|
21
24
|
allow_failures:
|
22
25
|
- rvm: 1.9.3
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
# Image Compressor Pack
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/image_compressor_pack.svg)](https://badge.fury.io/rb/image_compressor_pack)
|
3
|
+
[![Build Status](https://travis-ci.org/ignisf/image_compressor_pack.svg?branch=master)](https://travis-ci.org/ignisf/image_compressor_pack)
|
2
4
|
|
3
5
|
A source distribution of a bunch of lossy and lossless image optimisation
|
4
6
|
utilities for use with `image_optim`. Created because I didn't trust the
|
@@ -7,16 +9,37 @@ compilation from source.
|
|
7
9
|
|
8
10
|
## Installation
|
9
11
|
|
10
|
-
|
12
|
+
The gem is distributed in both source and binary form. The binary version
|
13
|
+
contain statically linked executables for Linux and FreeBSD and dynamically
|
14
|
+
linked ones for Mac OS X.
|
15
|
+
|
16
|
+
### Using the source version
|
17
|
+
|
18
|
+
To compile from source, add this line to your application's Gemfile:
|
11
19
|
|
12
20
|
```ruby
|
13
|
-
gem 'image_compressor_pack'
|
21
|
+
gem 'image_compressor_pack'
|
14
22
|
```
|
15
23
|
|
16
24
|
And then execute:
|
17
25
|
|
18
26
|
$ bundle
|
19
27
|
|
28
|
+
### Versioning
|
29
|
+
|
30
|
+
Starting with `image_compressor_pack` `1.0.0.0`, all even point releases contain
|
31
|
+
only a source-based distribution, while odd point releases contain both a
|
32
|
+
source-based distribution *and* binary distributions. However both point
|
33
|
+
releases correspond to the *exact* underlying code. The only difference is the
|
34
|
+
version number.
|
35
|
+
|
36
|
+
This way, the most recent version of the gem always has binary distributions,
|
37
|
+
but if you don't want to use the binaries, you can always "lock in" your
|
38
|
+
dependency a single point version down, forcing it to compile from source.
|
39
|
+
|
40
|
+
So for example, `1.0.0.1` contains all the binary distributions, while `1.0.0.0`
|
41
|
+
is the exact same code, but contain only a source-based distribution.
|
42
|
+
|
20
43
|
## Usage
|
21
44
|
|
22
45
|
For use in Rails with `image_optim`. Just adding it to your `Gemfile` should be
|
data/Rakefile
CHANGED
@@ -59,15 +59,15 @@ rescue LoadError
|
|
59
59
|
end
|
60
60
|
|
61
61
|
namespace :build do
|
62
|
-
['x86_64-linux', 'x86-linux', 'x86_64-freebsd10'].each do |arch|
|
62
|
+
['x86_64-linux', 'x86-linux', 'x86_64-freebsd10', 'x86_64-freebsd11'].each do |arch|
|
63
63
|
desc "build binary gem for #{arch}"
|
64
64
|
task arch do
|
65
65
|
arch_dir = Pathname(__FILE__).dirname.join("release/#{arch}")
|
66
66
|
Dir.chdir(arch_dir) do
|
67
67
|
ENV['RUBYLIB'] = nil # https://github.com/mitchellh/vagrant/issues/6158
|
68
68
|
sh "vagrant up"
|
69
|
-
|
70
|
-
|
69
|
+
sh "vagrant ssh -c 'rm -rf ~/image_compressor_pack'"
|
70
|
+
sh "vagrant ssh -c 'git clone /image_compressor_pack/.git ~/image_compressor_pack'"
|
71
71
|
sh "vagrant ssh -c 'cd ~/image_compressor_pack && bundle install --path vendor/bundle'"
|
72
72
|
sh "cat ~/.ssh/gem-private_key.pem | vagrant ssh -c 'cat > ~/.ssh/gem-private_key.pem'"
|
73
73
|
sh "vagrant ssh -c 'cd ~/image_compressor_pack && bundle exec rake binary'"
|
@@ -16,8 +16,7 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.homepage = "https://github.com/ignisf/image_compressor_pack"
|
17
17
|
spec.license = "MIT"
|
18
18
|
|
19
|
-
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
|
-
spec.files += `git ls-files -o -z ports/archives`.split("\x0")
|
19
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|release|bin)/}) }
|
21
20
|
spec.require_paths = ["lib"]
|
22
21
|
spec.extensions = ["ext/image_compressor_pack/extconf.rb"]
|
23
22
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
nasm:
|
2
|
-
version: 2.12.
|
2
|
+
version: 2.12.02
|
3
3
|
files:
|
4
|
-
- :url: http://www.nasm.us/pub/nasm/releasebuilds/2.12.
|
5
|
-
:sha256:
|
4
|
+
- :url: http://www.nasm.us/pub/nasm/releasebuilds/2.12.02/nasm-2.12.02.tar.gz
|
5
|
+
:sha256: b7346d827b282ccf70608fe90b9bcf27effb1ddbd1bcba8a5ab4be95284fd01b
|
6
6
|
zlib:
|
7
7
|
version: 1.2.8
|
8
8
|
files:
|
@@ -10,15 +10,16 @@ zlib:
|
|
10
10
|
:md5: 44d667c142d7cda120332623eab69f40
|
11
11
|
configure_options: ['--static']
|
12
12
|
lcms2:
|
13
|
-
version: 2.
|
13
|
+
version: 2.8
|
14
14
|
files:
|
15
|
-
- :url: http://
|
16
|
-
:sha256:
|
15
|
+
- :url: http://downloads.sourceforge.net/project/lcms/lcms/2.8/lcms2-2.8.tar.gz
|
16
|
+
:sha256: 66d02b229d2ea9474e62c2b6cd6720fde946155cd1d0d2bffdab829790a0fb22
|
17
|
+
configure_options: ['--enable-static', '--disable-shared', '--without-jpeg', '--without-tiff']
|
17
18
|
libpng:
|
18
|
-
version: 1.6.
|
19
|
+
version: 1.6.26
|
19
20
|
files:
|
20
|
-
- :url: http://
|
21
|
-
:md5:
|
21
|
+
- :url: http://downloads.sourceforge.net/project/libpng/libpng16/1.6.26/libpng-1.6.26.tar.gz
|
22
|
+
:md5: 236cd975520fc1f34cc0b8f0e615f7a0
|
22
23
|
patch_files:
|
23
24
|
- 0001-Do-not-build-binary-utilities.patch
|
24
25
|
configure_options: ['--enable-static', '--disable-shared', '--without-binconfigs', '--disable-unversioned-libpng-pc', '--disable-unversioned-libpng-config']
|
@@ -37,10 +38,10 @@ optipng:
|
|
37
38
|
:sha256: 4870631fcbd3825605f00a168b8debf44ea1cda8ef98a73e5411eee97199be80
|
38
39
|
configure_options: ['-with-system-libs']
|
39
40
|
pngquant:
|
40
|
-
version: 2.
|
41
|
+
version: 2.8.0
|
41
42
|
files:
|
42
|
-
- :url: https://
|
43
|
-
:
|
43
|
+
- :url: https://pngquant.org/pngquant-2.8.0-src.tar.gz
|
44
|
+
:sha1: f4428793dbc439a12bc67c7a585aa2fb9b86b349
|
44
45
|
patch_files:
|
45
46
|
- 0001-Work-around-mini-portile-s-configure-invocation.patch
|
46
47
|
- 0002-Add-default-LDFLAGS.patch
|
@@ -51,10 +52,12 @@ pngquant:
|
|
51
52
|
- 0007-Use-cc-instead-of-gcc-by-default.patch
|
52
53
|
configure_options: []
|
53
54
|
advancecomp:
|
54
|
-
version: 1.
|
55
|
+
version: 1.22
|
55
56
|
files:
|
56
|
-
- :url: https://github.com/amadvance/advancecomp/releases/download/v1.
|
57
|
-
:sha256:
|
57
|
+
- :url: https://github.com/amadvance/advancecomp/releases/download/v1.22/advancecomp-1.22.tar.gz
|
58
|
+
:sha256: 31dec84049b919176d14070b8e6f97e086a0ddcd24ff1b83cf498245ece6607d
|
59
|
+
patch_files:
|
60
|
+
- 0001-Add-missing-libdeflate-header-file.patch
|
58
61
|
gifsicle:
|
59
62
|
version: 1.88
|
60
63
|
files:
|
@@ -72,19 +75,19 @@ jhead:
|
|
72
75
|
- 0003-Make-the-configure-script-set-the-DESTDIR.patch
|
73
76
|
- 0004-Make-the-makefile-install-to-the-proper-location.patch
|
74
77
|
pngcrush:
|
75
|
-
version: 1.8.
|
78
|
+
version: 1.8.10
|
76
79
|
files:
|
77
|
-
- :url: http://downloads.sourceforge.net/project/pmt/pngcrush/1.8.
|
78
|
-
:sha256:
|
80
|
+
- :url: http://downloads.sourceforge.net/project/pmt/pngcrush/1.8.10/pngcrush-1.8.10.tar.gz
|
81
|
+
:sha256: ed8dc4759d5067ebf53a2a5188eff1e8ad10262737cf50516cccf8c60d220b6d
|
79
82
|
patch_files:
|
80
83
|
- 0001-Add-an-install-task.patch
|
81
84
|
- 0002-Add-a-configure-script.patch
|
82
85
|
- 0003-Use-cc-by-default-instead-of-gcc.patch
|
83
86
|
jpegoptim:
|
84
|
-
version: 1.4.
|
87
|
+
version: 1.4.4
|
85
88
|
files:
|
86
|
-
- :url: http://www.kokkonen.net/tjko/src/jpegoptim-1.4.
|
87
|
-
:sha256:
|
89
|
+
- :url: http://www.kokkonen.net/tjko/src/jpegoptim-1.4.4.tar.gz
|
90
|
+
:sha256: 89a03ea2dfe9483dfb2e009a2851be0befb0deb7cb45c04550bcc91e1e88c1b2
|
88
91
|
patch_files:
|
89
92
|
- 0001-Link-lm-after-ljpeg.patch
|
90
93
|
jpeg-archive:
|
@@ -1,25 +1,26 @@
|
|
1
1
|
nasm:
|
2
|
-
version: 2.12.
|
2
|
+
version: 2.12.02
|
3
3
|
files:
|
4
|
-
- :url: http://www.nasm.us/pub/nasm/releasebuilds/2.12.
|
5
|
-
:sha256:
|
4
|
+
- :url: http://www.nasm.us/pub/nasm/releasebuilds/2.12.02/nasm-2.12.02.tar.gz
|
5
|
+
:sha256: b7346d827b282ccf70608fe90b9bcf27effb1ddbd1bcba8a5ab4be95284fd01b
|
6
6
|
configure_options: ['LDFLAGS=-static']
|
7
7
|
zlib:
|
8
8
|
version: 1.2.8
|
9
9
|
files:
|
10
|
-
- :url: http://
|
10
|
+
- :url: http://downloads.sourceforge.net/project/libpng/zlib/1.2.8/zlib-1.2.8.tar.gz
|
11
11
|
:md5: 44d667c142d7cda120332623eab69f40
|
12
12
|
configure_options: ['--static']
|
13
13
|
lcms2:
|
14
|
-
version: 2.
|
14
|
+
version: 2.8
|
15
15
|
files:
|
16
|
-
- :url: http://
|
17
|
-
:sha256:
|
16
|
+
- :url: http://downloads.sourceforge.net/project/lcms/lcms/2.8/lcms2-2.8.tar.gz
|
17
|
+
:sha256: 66d02b229d2ea9474e62c2b6cd6720fde946155cd1d0d2bffdab829790a0fb22
|
18
|
+
configure_options: ['--enable-static', '--disable-shared', '--without-jpeg', '--without-tiff']
|
18
19
|
libpng:
|
19
|
-
version: 1.6.
|
20
|
+
version: 1.6.26
|
20
21
|
files:
|
21
|
-
- :url: http://
|
22
|
-
:md5:
|
22
|
+
- :url: http://downloads.sourceforge.net/project/libpng/libpng16/1.6.26/libpng-1.6.26.tar.gz
|
23
|
+
:md5: 236cd975520fc1f34cc0b8f0e615f7a0
|
23
24
|
patch_files:
|
24
25
|
- 0001-Do-not-build-binary-utilities.patch
|
25
26
|
configure_options: ['--enable-static', '--disable-shared', '--without-binconfigs', '--disable-unversioned-libpng-pc', '--disable-unversioned-libpng-config']
|
@@ -41,10 +42,10 @@ optipng:
|
|
41
42
|
patch_files:
|
42
43
|
- 0001-Allow-passing-LDFLAGS-as-configure-arg.patch
|
43
44
|
pngquant:
|
44
|
-
version: 2.
|
45
|
+
version: 2.8.0
|
45
46
|
files:
|
46
|
-
- :url: https://
|
47
|
-
:
|
47
|
+
- :url: https://pngquant.org/pngquant-2.8.0-src.tar.gz
|
48
|
+
:sha1: f4428793dbc439a12bc67c7a585aa2fb9b86b349
|
48
49
|
patch_files:
|
49
50
|
- 0001-Work-around-mini-portile-s-configure-invocation.patch
|
50
51
|
- 0002-Add-default-LDFLAGS.patch
|
@@ -54,10 +55,12 @@ pngquant:
|
|
54
55
|
- 0007-Use-cc-instead-of-gcc-by-default.patch
|
55
56
|
configure_options: ['--extra-ldflags=-lpng']
|
56
57
|
advancecomp:
|
57
|
-
version: 1.
|
58
|
+
version: 1.22
|
58
59
|
files:
|
59
|
-
- :url: https://github.com/amadvance/advancecomp/releases/download/v1.
|
60
|
-
:sha256:
|
60
|
+
- :url: https://github.com/amadvance/advancecomp/releases/download/v1.22/advancecomp-1.22.tar.gz
|
61
|
+
:sha256: 31dec84049b919176d14070b8e6f97e086a0ddcd24ff1b83cf498245ece6607d
|
62
|
+
patch_files:
|
63
|
+
- 0001-Add-missing-libdeflate-header-file.patch
|
61
64
|
configure_options: ['LDFLAGS=-static']
|
62
65
|
gifsicle:
|
63
66
|
version: 1.88
|
@@ -77,20 +80,20 @@ jhead:
|
|
77
80
|
- 0004-Make-the-makefile-install-to-the-proper-location.patch
|
78
81
|
- 0005-Produce-a-static-binary.patch
|
79
82
|
pngcrush:
|
80
|
-
version: 1.8.
|
83
|
+
version: 1.8.10
|
81
84
|
files:
|
82
|
-
- :url: http://downloads.sourceforge.net/project/pmt/pngcrush/1.8.
|
83
|
-
:sha256:
|
85
|
+
- :url: http://downloads.sourceforge.net/project/pmt/pngcrush/1.8.10/pngcrush-1.8.10.tar.gz
|
86
|
+
:sha256: ed8dc4759d5067ebf53a2a5188eff1e8ad10262737cf50516cccf8c60d220b6d
|
84
87
|
patch_files:
|
85
88
|
- 0001-Add-an-install-task.patch
|
86
89
|
- 0002-Add-a-configure-script.patch
|
87
90
|
- 0003-Use-cc-by-default-instead-of-gcc.patch
|
88
91
|
- 0004-Produce-a-static-binary.patch
|
89
92
|
jpegoptim:
|
90
|
-
version: 1.4.
|
93
|
+
version: 1.4.4
|
91
94
|
files:
|
92
|
-
- :url: http://www.kokkonen.net/tjko/src/jpegoptim-1.4.
|
93
|
-
:sha256:
|
95
|
+
- :url: http://www.kokkonen.net/tjko/src/jpegoptim-1.4.4.tar.gz
|
96
|
+
:sha256: 89a03ea2dfe9483dfb2e009a2851be0befb0deb7cb45c04550bcc91e1e88c1b2
|
94
97
|
patch_files:
|
95
98
|
- 0001-Link-lm-after-ljpeg.patch
|
96
99
|
configure_options: ['LDFLAGS=-static']
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,305 @@
|
|
1
|
+
From ad7bbef7da9a6dd7121366e8552085a0e14170f1 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Petko Bordjukov <bordjukov@gmail.com>
|
3
|
+
Date: Sat, 19 Nov 2016 12:27:16 +0200
|
4
|
+
Subject: [PATCH] Add missing libdeflate header file
|
5
|
+
|
6
|
+
---
|
7
|
+
libdeflate/crc32_impl.h | 286 ++++++++++++++++++++++++++++++++++++++++++++++++
|
8
|
+
1 file changed, 286 insertions(+)
|
9
|
+
create mode 100644 libdeflate/crc32_impl.h
|
10
|
+
|
11
|
+
diff --git a/libdeflate/crc32_impl.h b/libdeflate/crc32_impl.h
|
12
|
+
new file mode 100644
|
13
|
+
index 0000000..625bc18
|
14
|
+
--- /dev/null
|
15
|
+
+++ b/libdeflate/crc32_impl.h
|
16
|
+
@@ -0,0 +1,286 @@
|
17
|
+
+/*
|
18
|
+
+ * crc32_impl.h
|
19
|
+
+ *
|
20
|
+
+ * Copyright 2016 Eric Biggers
|
21
|
+
+ *
|
22
|
+
+ * Permission is hereby granted, free of charge, to any person
|
23
|
+
+ * obtaining a copy of this software and associated documentation
|
24
|
+
+ * files (the "Software"), to deal in the Software without
|
25
|
+
+ * restriction, including without limitation the rights to use,
|
26
|
+
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
|
27
|
+
+ * copies of the Software, and to permit persons to whom the
|
28
|
+
+ * Software is furnished to do so, subject to the following
|
29
|
+
+ * conditions:
|
30
|
+
+ *
|
31
|
+
+ * The above copyright notice and this permission notice shall be
|
32
|
+
+ * included in all copies or substantial portions of the Software.
|
33
|
+
+ *
|
34
|
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
35
|
+
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
36
|
+
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
37
|
+
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
38
|
+
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
39
|
+
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
40
|
+
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
41
|
+
+ * OTHER DEALINGS IN THE SOFTWARE.
|
42
|
+
+ */
|
43
|
+
+
|
44
|
+
+/*
|
45
|
+
+ * CRC-32 folding with PCLMULQDQ.
|
46
|
+
+ *
|
47
|
+
+ * The basic idea is to repeatedly "fold" each 512 bits into the next 512 bits,
|
48
|
+
+ * producing an abbreviated message which is congruent the original message
|
49
|
+
+ * modulo the generator polynomial G(x).
|
50
|
+
+ *
|
51
|
+
+ * Folding each 512 bits is implemented as eight 64-bit folds, each of which
|
52
|
+
+ * uses one carryless multiplication instruction. It's expected that CPUs may
|
53
|
+
+ * be able to execute some of these multiplications in parallel.
|
54
|
+
+ *
|
55
|
+
+ * Explanation of "folding": let A(x) be 64 bits from the message, and let B(x)
|
56
|
+
+ * be 95 bits from a constant distance D later in the message. The relevant
|
57
|
+
+ * portion of the message can be written as:
|
58
|
+
+ *
|
59
|
+
+ * M(x) = A(x)*x^D + B(x)
|
60
|
+
+ *
|
61
|
+
+ * ... where + and * represent addition and multiplication, respectively, of
|
62
|
+
+ * polynomials over GF(2). Note that when implemented on a computer, these
|
63
|
+
+ * operations are equivalent to XOR and carryless multiplication, respectively.
|
64
|
+
+ *
|
65
|
+
+ * For the purpose of CRC calculation, only the remainder modulo the generator
|
66
|
+
+ * polynomial G(x) matters:
|
67
|
+
+ *
|
68
|
+
+ * M(x) mod G(x) = (A(x)*x^D + B(x)) mod G(x)
|
69
|
+
+ *
|
70
|
+
+ * Since the modulo operation can be applied anywhere in a sequence of additions
|
71
|
+
+ * and multiplications without affecting the result, this is equivalent to:
|
72
|
+
+ *
|
73
|
+
+ * M(x) mod G(x) = (A(x)*(x^D mod G(x)) + B(x)) mod G(x)
|
74
|
+
+ *
|
75
|
+
+ * For any D, 'x^D mod G(x)' will be a polynomial with maximum degree 31, i.e.
|
76
|
+
+ * a 32-bit quantity. So 'A(x) * (x^D mod G(x))' is equivalent to a carryless
|
77
|
+
+ * multiplication of a 64-bit quantity by a 32-bit quantity, producing a 95-bit
|
78
|
+
+ * product. Then, adding (XOR-ing) the product to B(x) produces a polynomial
|
79
|
+
+ * with the same length as B(x) but with the same remainder as 'A(x)*x^D +
|
80
|
+
+ * B(x)'. This is the basic fold operation with 64 bits.
|
81
|
+
+ *
|
82
|
+
+ * Note that the carryless multiplication instruction PCLMULQDQ actually takes
|
83
|
+
+ * two 64-bit inputs and produces a 127-bit product in the low-order bits of a
|
84
|
+
+ * 128-bit XMM register. This works fine, but care must be taken to account for
|
85
|
+
+ * "bit endianness". With the CRC version implemented here, bits are always
|
86
|
+
+ * ordered such that the lowest-order bit represents the coefficient of highest
|
87
|
+
+ * power of x and the highest-order bit represents the coefficient of the lowest
|
88
|
+
+ * power of x. This is backwards from the more intuitive order. Still,
|
89
|
+
+ * carryless multiplication works essentially the same either way. It just must
|
90
|
+
+ * be accounted for that when we XOR the 95-bit product in the low-order 95 bits
|
91
|
+
+ * of a 128-bit XMM register into 128-bits of later data held in another XMM
|
92
|
+
+ * register, we'll really be XOR-ing the product into the mathematically higher
|
93
|
+
+ * degree end of those later bits, not the lower degree end as may be expected.
|
94
|
+
+ *
|
95
|
+
+ * So given that caveat and the fact that we process 512 bits per iteration, the
|
96
|
+
+ * 'D' values we need for the two 64-bit halves of each 128 bits of data are:
|
97
|
+
+ *
|
98
|
+
+ * D = (512 + 95) - 64 for the higher-degree half of each 128 bits,
|
99
|
+
+ * i.e. the lower order bits in the XMM register
|
100
|
+
+ *
|
101
|
+
+ * D = (512 + 95) - 128 for the lower-degree half of each 128 bits,
|
102
|
+
+ * i.e. the higher order bits in the XMM register
|
103
|
+
+ *
|
104
|
+
+ * The required 'x^D mod G(x)' values were precomputed.
|
105
|
+
+ *
|
106
|
+
+ * When <= 512 bits remain in the message, we finish up by folding across
|
107
|
+
+ * smaller distances. This works similarly; the distance D is just different,
|
108
|
+
+ * so different constant multipliers must be used. Finally, once the remaining
|
109
|
+
+ * message is just 64 bits, it is is reduced to the CRC-32 using Barrett
|
110
|
+
+ * reduction (explained later).
|
111
|
+
+ *
|
112
|
+
+ * For more information see the original paper from Intel:
|
113
|
+
+ * "Fast CRC Computation for Generic Polynomials Using PCLMULQDQ Instruction"
|
114
|
+
+ * December 2009
|
115
|
+
+ * http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf
|
116
|
+
+ */
|
117
|
+
+static u32 ATTRIBUTES
|
118
|
+
+FUNCNAME_ALIGNED(u32 remainder, const __m128i *p, size_t vec_count)
|
119
|
+
+{
|
120
|
+
+ /* Constants precomputed by gen_crc32_multipliers.c. Do not edit! */
|
121
|
+
+ const __v2di multipliers_4 = (__v2di){ 0x8F352D95, 0x1D9513D7 };
|
122
|
+
+ const __v2di multipliers_2 = (__v2di){ 0xF1DA05AA, 0x81256527 };
|
123
|
+
+ const __v2di multipliers_1 = (__v2di){ 0xAE689191, 0xCCAA009E };
|
124
|
+
+ const __v2di final_multiplier = (__v2di){ 0xB8BC6765 };
|
125
|
+
+ const __m128i mask32 = (__m128i)(__v4si){ 0xFFFFFFFF };
|
126
|
+
+ const __v2di barrett_reduction_constants =
|
127
|
+
+ (__v2di){ 0x00000001F7011641, 0x00000001DB710641 };
|
128
|
+
+
|
129
|
+
+ const __m128i * const end = p + vec_count;
|
130
|
+
+ const __m128i * const end512 = p + (vec_count & ~3);
|
131
|
+
+ __m128i x0, x1, x2, x3;
|
132
|
+
+
|
133
|
+
+ /*
|
134
|
+
+ * Account for the current 'remainder', i.e. the CRC of the part of the
|
135
|
+
+ * message already processed. Explanation: rewrite the message
|
136
|
+
+ * polynomial M(x) in terms of the first part A(x), the second part
|
137
|
+
+ * B(x), and the length of the second part in bits |B(x)| >= 32:
|
138
|
+
+ *
|
139
|
+
+ * M(x) = A(x)*x^|B(x)| + B(x)
|
140
|
+
+ *
|
141
|
+
+ * Then the CRC of M(x) is:
|
142
|
+
+ *
|
143
|
+
+ * CRC(M(x)) = CRC(A(x)*x^|B(x)| + B(x))
|
144
|
+
+ * = CRC(A(x)*x^32*x^(|B(x)| - 32) + B(x))
|
145
|
+
+ * = CRC(CRC(A(x))*x^(|B(x)| - 32) + B(x))
|
146
|
+
+ *
|
147
|
+
+ * Note: all arithmetic is modulo G(x), the generator polynomial; that's
|
148
|
+
+ * why A(x)*x^32 can be replaced with CRC(A(x)) = A(x)*x^32 mod G(x).
|
149
|
+
+ *
|
150
|
+
+ * So the CRC of the full message is the CRC of the second part of the
|
151
|
+
+ * message where the first 32 bits of the second part of the message
|
152
|
+
+ * have been XOR'ed with the CRC of the first part of the message.
|
153
|
+
+ */
|
154
|
+
+ x0 = *p++;
|
155
|
+
+ x0 ^= (__m128i)(__v4si){ remainder };
|
156
|
+
+
|
157
|
+
+ if (p > end512) /* only 128, 256, or 384 bits of input? */
|
158
|
+
+ goto _128_bits_at_a_time;
|
159
|
+
+ x1 = *p++;
|
160
|
+
+ x2 = *p++;
|
161
|
+
+ x3 = *p++;
|
162
|
+
+
|
163
|
+
+ /* Fold 512 bits at a time */
|
164
|
+
+ for (; p != end512; p += 4) {
|
165
|
+
+ __m128i y0, y1, y2, y3;
|
166
|
+
+
|
167
|
+
+ y0 = p[0];
|
168
|
+
+ y1 = p[1];
|
169
|
+
+ y2 = p[2];
|
170
|
+
+ y3 = p[3];
|
171
|
+
+
|
172
|
+
+ /*
|
173
|
+
+ * Note: the immediate constant for PCLMULQDQ specifies which
|
174
|
+
+ * 64-bit halves of the 128-bit vectors to multiply:
|
175
|
+
+ *
|
176
|
+
+ * 0x00 means low halves (higher degree polynomial terms for us)
|
177
|
+
+ * 0x11 means high halves (lower degree polynomial terms for us)
|
178
|
+
+ */
|
179
|
+
+ y0 ^= _mm_clmulepi64_si128(x0, multipliers_4, 0x00);
|
180
|
+
+ y1 ^= _mm_clmulepi64_si128(x1, multipliers_4, 0x00);
|
181
|
+
+ y2 ^= _mm_clmulepi64_si128(x2, multipliers_4, 0x00);
|
182
|
+
+ y3 ^= _mm_clmulepi64_si128(x3, multipliers_4, 0x00);
|
183
|
+
+ y0 ^= _mm_clmulepi64_si128(x0, multipliers_4, 0x11);
|
184
|
+
+ y1 ^= _mm_clmulepi64_si128(x1, multipliers_4, 0x11);
|
185
|
+
+ y2 ^= _mm_clmulepi64_si128(x2, multipliers_4, 0x11);
|
186
|
+
+ y3 ^= _mm_clmulepi64_si128(x3, multipliers_4, 0x11);
|
187
|
+
+
|
188
|
+
+ x0 = y0;
|
189
|
+
+ x1 = y1;
|
190
|
+
+ x2 = y2;
|
191
|
+
+ x3 = y3;
|
192
|
+
+ }
|
193
|
+
+
|
194
|
+
+ /* Fold 512 bits => 128 bits */
|
195
|
+
+ x2 ^= _mm_clmulepi64_si128(x0, multipliers_2, 0x00);
|
196
|
+
+ x3 ^= _mm_clmulepi64_si128(x1, multipliers_2, 0x00);
|
197
|
+
+ x2 ^= _mm_clmulepi64_si128(x0, multipliers_2, 0x11);
|
198
|
+
+ x3 ^= _mm_clmulepi64_si128(x1, multipliers_2, 0x11);
|
199
|
+
+ x3 ^= _mm_clmulepi64_si128(x2, multipliers_1, 0x00);
|
200
|
+
+ x3 ^= _mm_clmulepi64_si128(x2, multipliers_1, 0x11);
|
201
|
+
+ x0 = x3;
|
202
|
+
+
|
203
|
+
+_128_bits_at_a_time:
|
204
|
+
+ while (p != end) {
|
205
|
+
+ /* Fold 128 bits into next 128 bits */
|
206
|
+
+ x1 = *p++;
|
207
|
+
+ x1 ^= _mm_clmulepi64_si128(x0, multipliers_1, 0x00);
|
208
|
+
+ x1 ^= _mm_clmulepi64_si128(x0, multipliers_1, 0x11);
|
209
|
+
+ x0 = x1;
|
210
|
+
+ }
|
211
|
+
+
|
212
|
+
+ /* Now there are just 128 bits left, stored in 'x0'. */
|
213
|
+
+
|
214
|
+
+ /*
|
215
|
+
+ * Fold 128 => 96 bits. This also implicitly appends 32 zero bits,
|
216
|
+
+ * which is equivalent to multiplying by x^32. This is needed because
|
217
|
+
+ * the CRC is defined as M(x)*x^32 mod G(x), not just M(x) mod G(x).
|
218
|
+
+ */
|
219
|
+
+ x0 = _mm_srli_si128(x0, 8) ^
|
220
|
+
+ _mm_clmulepi64_si128(x0, multipliers_1, 0x10);
|
221
|
+
+
|
222
|
+
+ /* Fold 96 => 64 bits */
|
223
|
+
+ x0 = _mm_srli_si128(x0, 4) ^
|
224
|
+
+ _mm_clmulepi64_si128(x0 & mask32, final_multiplier, 0x00);
|
225
|
+
+
|
226
|
+
+ /*
|
227
|
+
+ * Finally, reduce 64 => 32 bits using Barrett reduction.
|
228
|
+
+ *
|
229
|
+
+ * Let M(x) = A(x)*x^32 + B(x) be the remaining message. The goal is to
|
230
|
+
+ * compute R(x) = M(x) mod G(x). Since degree(B(x)) < degree(G(x)):
|
231
|
+
+ *
|
232
|
+
+ * R(x) = (A(x)*x^32 + B(x)) mod G(x)
|
233
|
+
+ * = (A(x)*x^32) mod G(x) + B(x)
|
234
|
+
+ *
|
235
|
+
+ * Then, by the Division Algorithm there exists a unique q(x) such that:
|
236
|
+
+ *
|
237
|
+
+ * A(x)*x^32 mod G(x) = A(x)*x^32 - q(x)*G(x)
|
238
|
+
+ *
|
239
|
+
+ * Since the left-hand side is of maximum degree 31, the right-hand side
|
240
|
+
+ * must be too. This implies that we can apply 'mod x^32' to the
|
241
|
+
+ * right-hand side without changing its value:
|
242
|
+
+ *
|
243
|
+
+ * (A(x)*x^32 - q(x)*G(x)) mod x^32 = q(x)*G(x) mod x^32
|
244
|
+
+ *
|
245
|
+
+ * Note that '+' is equivalent to '-' in polynomials over GF(2).
|
246
|
+
+ *
|
247
|
+
+ * We also know that:
|
248
|
+
+ *
|
249
|
+
+ * / A(x)*x^32 \
|
250
|
+
+ * q(x) = floor ( --------- )
|
251
|
+
+ * \ G(x) /
|
252
|
+
+ *
|
253
|
+
+ * To compute this efficiently, we can multiply the top and bottom by
|
254
|
+
+ * x^32 and move the division by G(x) to the top:
|
255
|
+
+ *
|
256
|
+
+ * / A(x) * floor(x^64 / G(x)) \
|
257
|
+
+ * q(x) = floor ( ------------------------- )
|
258
|
+
+ * \ x^32 /
|
259
|
+
+ *
|
260
|
+
+ * Note that floor(x^64 / G(x)) is a constant.
|
261
|
+
+ *
|
262
|
+
+ * So finally we have:
|
263
|
+
+ *
|
264
|
+
+ * / A(x) * floor(x^64 / G(x)) \
|
265
|
+
+ * R(x) = B(x) + G(x)*floor ( ------------------------- )
|
266
|
+
+ * \ x^32 /
|
267
|
+
+ */
|
268
|
+
+ x1 = x0;
|
269
|
+
+ x0 = _mm_clmulepi64_si128(x0 & mask32, barrett_reduction_constants, 0x00);
|
270
|
+
+ x0 = _mm_clmulepi64_si128(x0 & mask32, barrett_reduction_constants, 0x10);
|
271
|
+
+ return _mm_cvtsi128_si32(_mm_srli_si128(x0 ^ x1, 4));
|
272
|
+
+}
|
273
|
+
+
|
274
|
+
+/*
|
275
|
+
+ * Fast CRC-32 implementation for x86_64 processors that have the carryless
|
276
|
+
+ * multiplication extension (PCLMUL).
|
277
|
+
+ *
|
278
|
+
+ * Note: on unaligned ends of the buffer, we fall back to crc32_slice1() instead
|
279
|
+
+ * of crc32_slice8() because only a few bytes need to be processed, so a smaller
|
280
|
+
+ * table is preferable.
|
281
|
+
+ */
|
282
|
+
+static u32 ATTRIBUTES
|
283
|
+
+FUNCNAME(u32 remainder, const u8 *buffer, size_t nbytes)
|
284
|
+
+{
|
285
|
+
+ if ((uintptr_t)buffer & 15) {
|
286
|
+
+ size_t n = MIN(nbytes, -(uintptr_t)buffer & 15);
|
287
|
+
+ remainder = crc32_slice1(remainder, buffer, n);
|
288
|
+
+ buffer += n;
|
289
|
+
+ nbytes -= n;
|
290
|
+
+ }
|
291
|
+
+ if (nbytes >= 16) {
|
292
|
+
+ remainder = FUNCNAME_ALIGNED(remainder, (const __m128i *)buffer,
|
293
|
+
+ nbytes / 16);
|
294
|
+
+ buffer += nbytes & ~15;
|
295
|
+
+ nbytes &= 15;
|
296
|
+
+ }
|
297
|
+
+ return crc32_slice1(remainder, buffer, nbytes);
|
298
|
+
+}
|
299
|
+
+
|
300
|
+
+#undef FUNCNAME
|
301
|
+
+#undef FUNCNAME_ALIGNED
|
302
|
+
+#undef ATTRIBUTES
|
303
|
+
--
|
304
|
+
2.10.2
|
305
|
+
|