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.
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ImagePack
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.2"
5
5
  end
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: :jpeg_turbo,
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: :jpeg_turbo,
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
- else
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.0"
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!(algo, execution, 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.0
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
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ImagePack
4
- module Backend
5
- JPEG_TURBO = :jpeg_turbo
6
- MOZJPEG = :mozjpeg
7
- end
8
- end