image_pack 0.2.0 → 0.2.2
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/CHANGELOG.md +52 -0
- data/README.md +53 -13
- data/ext/image_pack/extconf.rb +21 -17
- data/ext/image_pack/image_pack.c +1056 -286
- data/lib/image_pack/configuration.rb +3 -1
- data/lib/image_pack/version.rb +1 -1
- data/lib/image_pack.rb +89 -17
- metadata +1 -2
- data/lib/image_pack/backend.rb +0 -8
|
@@ -8,7 +8,8 @@ module ImagePack
|
|
|
8
8
|
:max_pixels,
|
|
9
9
|
:max_width,
|
|
10
10
|
:max_height,
|
|
11
|
-
:max_output_size
|
|
11
|
+
:max_output_size,
|
|
12
|
+
:max_input_size
|
|
12
13
|
|
|
13
14
|
def initialize
|
|
14
15
|
@execution = :auto
|
|
@@ -18,6 +19,7 @@ module ImagePack
|
|
|
18
19
|
@max_width = 30_000
|
|
19
20
|
@max_height = 30_000
|
|
20
21
|
@max_output_size = 256 * 1024 * 1024
|
|
22
|
+
@max_input_size = 256 * 1024 * 1024
|
|
21
23
|
end
|
|
22
24
|
end
|
|
23
25
|
end
|
data/lib/image_pack/version.rb
CHANGED
data/lib/image_pack.rb
CHANGED
|
@@ -13,7 +13,6 @@ require "pathname"
|
|
|
13
13
|
require_relative "image_pack/version"
|
|
14
14
|
require_relative "image_pack/errors"
|
|
15
15
|
require_relative "image_pack/configuration"
|
|
16
|
-
require_relative "image_pack/backend"
|
|
17
16
|
|
|
18
17
|
begin
|
|
19
18
|
require "image_pack/image_pack"
|
|
@@ -29,9 +28,11 @@ rescue LoadError
|
|
|
29
28
|
end
|
|
30
29
|
|
|
31
30
|
module ImagePack
|
|
32
|
-
ALGOS = %i[jpeg_turbo mozjpeg].freeze
|
|
31
|
+
ALGOS = %i[jpeg_turbo mozjpeg fast size].freeze
|
|
32
|
+
ALGO_TO_NATIVE = { jpeg_turbo: :jpeg_turbo, mozjpeg: :mozjpeg, fast: :jpeg_turbo, size: :mozjpeg }.freeze
|
|
33
33
|
EXECUTION_MODES = %i[direct nogvl offload auto].freeze
|
|
34
34
|
DEFAULT_QUALITY = 82
|
|
35
|
+
DEFAULT_ALGO = :mozjpeg
|
|
35
36
|
|
|
36
37
|
class << self
|
|
37
38
|
def configuration
|
|
@@ -45,9 +46,66 @@ module ImagePack
|
|
|
45
46
|
configuration
|
|
46
47
|
end
|
|
47
48
|
|
|
49
|
+
def build_info
|
|
50
|
+
{
|
|
51
|
+
version: VERSION,
|
|
52
|
+
mozjpeg: defined?(NATIVE_MOZJPEG_VERSION) ? NATIVE_MOZJPEG_VERSION : nil,
|
|
53
|
+
simd: defined?(NATIVE_SIMD) ? NATIVE_SIMD : nil
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def compress_bytes(bytes, **options)
|
|
58
|
+
raise InvalidArgumentError, "bytes must be a String" unless bytes.is_a?(String)
|
|
59
|
+
|
|
60
|
+
compress(bytes.b, **options)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def compress_file(path, **options)
|
|
64
|
+
pathname = Pathname(path)
|
|
65
|
+
raise InvalidArgumentError, "input path does not exist: #{pathname}" unless pathname.file?
|
|
66
|
+
|
|
67
|
+
compress(pathname, **options)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def optimize_bytes(bytes, **options)
|
|
71
|
+
raise InvalidArgumentError, "bytes must be a String" unless bytes.is_a?(String)
|
|
72
|
+
|
|
73
|
+
optimize_jpeg(bytes.b, **options)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def optimize_file(path, **options)
|
|
77
|
+
pathname = Pathname(path)
|
|
78
|
+
raise InvalidArgumentError, "input path does not exist: #{pathname}" unless pathname.file?
|
|
79
|
+
|
|
80
|
+
optimize_jpeg(pathname, **options)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def optimize_jpeg(input,
|
|
84
|
+
output: nil,
|
|
85
|
+
progressive: true,
|
|
86
|
+
strip_metadata: false,
|
|
87
|
+
execution: nil,
|
|
88
|
+
cancellable: false)
|
|
89
|
+
execution ||= configuration.execution
|
|
90
|
+
validate_execution!(execution)
|
|
91
|
+
validate_cancellable!(:lossless_optimize, execution, cancellable)
|
|
92
|
+
|
|
93
|
+
normalized_input_kind = input_kind!(input)
|
|
94
|
+
normalized_output_kind = output_kind!(output)
|
|
95
|
+
has_scheduler = fiber_scheduler_active?
|
|
96
|
+
|
|
97
|
+
__optimize_jpeg(input, normalized_input_kind,
|
|
98
|
+
output, normalized_output_kind,
|
|
99
|
+
progressive ? 1 : 0,
|
|
100
|
+
strip_metadata ? 1 : 0,
|
|
101
|
+
execution,
|
|
102
|
+
cancellable ? 1 : 0,
|
|
103
|
+
has_scheduler ? 1 : 0)
|
|
104
|
+
end
|
|
105
|
+
|
|
48
106
|
def compress(input,
|
|
49
107
|
output: nil,
|
|
50
|
-
algo:
|
|
108
|
+
algo: DEFAULT_ALGO,
|
|
51
109
|
quality: nil,
|
|
52
110
|
min_ssim: nil,
|
|
53
111
|
mozjpeg_trellis: true,
|
|
@@ -72,7 +130,7 @@ module ImagePack
|
|
|
72
130
|
|
|
73
131
|
__compress_jpeg(input, normalized_input_kind,
|
|
74
132
|
output, normalized_output_kind,
|
|
75
|
-
algo, effective_quality.to_i,
|
|
133
|
+
ALGO_TO_NATIVE.fetch(algo), effective_quality.to_i,
|
|
76
134
|
min_ssim ? min_ssim.to_f : 0.0,
|
|
77
135
|
mozjpeg_trellis ? 1 : 0,
|
|
78
136
|
progressive ? 1 : 0,
|
|
@@ -87,25 +145,45 @@ module ImagePack
|
|
|
87
145
|
height:,
|
|
88
146
|
channels:,
|
|
89
147
|
output: nil,
|
|
90
|
-
algo:
|
|
148
|
+
algo: DEFAULT_ALGO,
|
|
91
149
|
quality: DEFAULT_QUALITY,
|
|
150
|
+
min_ssim: nil,
|
|
92
151
|
progressive: false,
|
|
152
|
+
drop_alpha: nil,
|
|
93
153
|
execution: nil,
|
|
94
154
|
cancellable: false)
|
|
95
155
|
validate_algo!(algo)
|
|
156
|
+
validate_min_ssim!(min_ssim)
|
|
96
157
|
validate_quality!(quality)
|
|
97
158
|
validate_dimensions!(width, height, channels)
|
|
98
159
|
execution ||= configuration.execution
|
|
99
160
|
validate_execution!(execution)
|
|
100
161
|
validate_cancellable!(algo, execution, cancellable)
|
|
101
162
|
|
|
163
|
+
if channels.to_i == 4
|
|
164
|
+
case drop_alpha
|
|
165
|
+
when nil
|
|
166
|
+
warn "ImagePack.compress_pixels: RGBA input has its alpha channel " \
|
|
167
|
+
"discarded (JPEG cannot store alpha). Pass drop_alpha: true to " \
|
|
168
|
+
"silence this warning, or drop_alpha: false to raise instead."
|
|
169
|
+
when false
|
|
170
|
+
raise UnsupportedError,
|
|
171
|
+
"JPEG cannot store an alpha channel. Pass drop_alpha: true to drop it explicitly."
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
102
175
|
normalized_output_kind = output_kind!(output)
|
|
103
176
|
has_scheduler = fiber_scheduler_active?
|
|
104
177
|
|
|
178
|
+
if min_ssim && channels.to_i == 4
|
|
179
|
+
raise UnsupportedError, "min_ssim is not supported for RGBA input"
|
|
180
|
+
end
|
|
181
|
+
|
|
105
182
|
__compress_pixels(buffer,
|
|
106
183
|
width.to_i, height.to_i, channels.to_i,
|
|
107
184
|
output, normalized_output_kind,
|
|
108
|
-
algo, quality.to_i,
|
|
185
|
+
ALGO_TO_NATIVE.fetch(algo), quality.to_i,
|
|
186
|
+
min_ssim ? min_ssim.to_f : 0.0,
|
|
109
187
|
progressive ? 1 : 0,
|
|
110
188
|
execution,
|
|
111
189
|
cancellable ? 1 : 0,
|
|
@@ -123,10 +201,10 @@ module ImagePack
|
|
|
123
201
|
when String
|
|
124
202
|
if input.encoding == Encoding::BINARY || input.encoding == Encoding::ASCII_8BIT
|
|
125
203
|
:bytes
|
|
126
|
-
|
|
127
|
-
raise InvalidArgumentError, "input path does not exist: #{input.inspect}" unless File.file?(input)
|
|
128
|
-
|
|
204
|
+
elsif input.bytesize < 4096 && !input.include?("\0") && File.file?(input)
|
|
129
205
|
:path
|
|
206
|
+
else
|
|
207
|
+
:bytes
|
|
130
208
|
end
|
|
131
209
|
when Pathname
|
|
132
210
|
raise InvalidArgumentError, "input path does not exist: #{input}" unless input.file?
|
|
@@ -146,7 +224,7 @@ module ImagePack
|
|
|
146
224
|
return :return_string if output.nil?
|
|
147
225
|
return :path if output.is_a?(String) || output.is_a?(Pathname)
|
|
148
226
|
|
|
149
|
-
raise InvalidArgumentError, "output must be nil, String path, or Pathname in v0.2.
|
|
227
|
+
raise InvalidArgumentError, "output must be nil, String path, or Pathname in v0.2.2"
|
|
150
228
|
end
|
|
151
229
|
|
|
152
230
|
def validate_algo!(algo)
|
|
@@ -187,14 +265,8 @@ module ImagePack
|
|
|
187
265
|
raise InvalidArgumentError, "channels must be 1, 3 or 4" unless [1, 3, 4].include?(channels)
|
|
188
266
|
end
|
|
189
267
|
|
|
190
|
-
def validate_cancellable!(
|
|
268
|
+
def validate_cancellable!(_algo, execution, cancellable)
|
|
191
269
|
return unless cancellable
|
|
192
|
-
|
|
193
|
-
if algo == :jpeg_turbo
|
|
194
|
-
raise InvalidArgumentError,
|
|
195
|
-
"cancellable: true is only supported with algo: :mozjpeg in v0.2.0"
|
|
196
|
-
end
|
|
197
|
-
|
|
198
270
|
return unless execution == :direct
|
|
199
271
|
|
|
200
272
|
raise InvalidArgumentError,
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: image_pack
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Roman Haydarov
|
|
@@ -402,7 +402,6 @@ files:
|
|
|
402
402
|
- ext/image_pack/vendor/mozjpeg/wrtarga.c
|
|
403
403
|
- ext/image_pack/vendor/mozjpeg/yuvjpeg.c
|
|
404
404
|
- lib/image_pack.rb
|
|
405
|
-
- lib/image_pack/backend.rb
|
|
406
405
|
- lib/image_pack/configuration.rb
|
|
407
406
|
- lib/image_pack/errors.rb
|
|
408
407
|
- lib/image_pack/version.rb
|