chunky_png 1.3.10 → 1.3.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ruby.yml +35 -0
  3. data/.standard.yml +16 -0
  4. data/.yardopts +1 -1
  5. data/CHANGELOG.rdoc +5 -1
  6. data/CONTRIBUTING.rdoc +17 -8
  7. data/Gemfile +5 -3
  8. data/LICENSE +1 -1
  9. data/README.md +6 -1
  10. data/Rakefile +5 -3
  11. data/benchmarks/decoding_benchmark.rb +17 -17
  12. data/benchmarks/encoding_benchmark.rb +22 -19
  13. data/benchmarks/filesize_benchmark.rb +6 -6
  14. data/bin/rake +29 -0
  15. data/bin/standardrb +29 -0
  16. data/chunky_png.gemspec +20 -14
  17. data/lib/chunky_png.rb +17 -30
  18. data/lib/chunky_png/canvas.rb +30 -27
  19. data/lib/chunky_png/canvas/adam7_interlacing.rb +16 -10
  20. data/lib/chunky_png/canvas/data_url_exporting.rb +3 -3
  21. data/lib/chunky_png/canvas/data_url_importing.rb +3 -3
  22. data/lib/chunky_png/canvas/drawing.rb +30 -43
  23. data/lib/chunky_png/canvas/masking.rb +14 -14
  24. data/lib/chunky_png/canvas/operations.rb +28 -24
  25. data/lib/chunky_png/canvas/png_decoding.rb +38 -32
  26. data/lib/chunky_png/canvas/png_encoding.rb +110 -102
  27. data/lib/chunky_png/canvas/resampling.rb +27 -32
  28. data/lib/chunky_png/canvas/stream_exporting.rb +8 -8
  29. data/lib/chunky_png/canvas/stream_importing.rb +8 -8
  30. data/lib/chunky_png/chunk.rb +72 -61
  31. data/lib/chunky_png/color.rb +213 -206
  32. data/lib/chunky_png/datastream.rb +23 -29
  33. data/lib/chunky_png/dimension.rb +18 -11
  34. data/lib/chunky_png/image.rb +11 -11
  35. data/lib/chunky_png/palette.rb +6 -9
  36. data/lib/chunky_png/point.rb +27 -26
  37. data/lib/chunky_png/rmagick.rb +10 -10
  38. data/lib/chunky_png/vector.rb +28 -29
  39. data/lib/chunky_png/version.rb +3 -1
  40. data/spec/chunky_png/canvas/adam7_interlacing_spec.rb +20 -21
  41. data/spec/chunky_png/canvas/data_url_exporting_spec.rb +8 -5
  42. data/spec/chunky_png/canvas/data_url_importing_spec.rb +5 -6
  43. data/spec/chunky_png/canvas/drawing_spec.rb +46 -38
  44. data/spec/chunky_png/canvas/masking_spec.rb +15 -16
  45. data/spec/chunky_png/canvas/operations_spec.rb +68 -67
  46. data/spec/chunky_png/canvas/png_decoding_spec.rb +37 -38
  47. data/spec/chunky_png/canvas/png_encoding_spec.rb +59 -50
  48. data/spec/chunky_png/canvas/resampling_spec.rb +19 -21
  49. data/spec/chunky_png/canvas/stream_exporting_spec.rb +47 -27
  50. data/spec/chunky_png/canvas/stream_importing_spec.rb +10 -11
  51. data/spec/chunky_png/canvas_spec.rb +57 -52
  52. data/spec/chunky_png/color_spec.rb +115 -114
  53. data/spec/chunky_png/datastream_spec.rb +55 -51
  54. data/spec/chunky_png/dimension_spec.rb +10 -10
  55. data/spec/chunky_png/image_spec.rb +11 -14
  56. data/spec/chunky_png/point_spec.rb +21 -23
  57. data/spec/chunky_png/rmagick_spec.rb +7 -8
  58. data/spec/chunky_png/vector_spec.rb +21 -17
  59. data/spec/chunky_png_spec.rb +2 -2
  60. data/spec/png_suite_spec.rb +35 -40
  61. data/spec/spec_helper.rb +6 -10
  62. data/tasks/benchmarks.rake +7 -8
  63. metadata +39 -8
  64. data/.travis.yml +0 -16
  65. data/lib/chunky_png/compatibility.rb +0 -15
@@ -1,10 +1,8 @@
1
-
2
-
1
+ # frozen-string-literal: true
3
2
 
4
3
  module ChunkyPNG
5
4
  class Canvas
6
-
7
- # The ChunkyPNG::Canvas::Resampling module defines methods to perform image resampling to
5
+ # The ChunkyPNG::Canvas::Resampling module defines methods to perform image resampling to
8
6
  # a {ChunkyPNG::Canvas}.
9
7
  #
10
8
  # Currently, only the nearest neighbor algorithm is implemented. Bilinear and cubic
@@ -12,22 +10,21 @@ module ChunkyPNG
12
10
  #
13
11
  # @see ChunkyPNG::Canvas
14
12
  module Resampling
15
-
16
13
  # Integer Interpolation between two values
17
14
  #
18
15
  # Used for generating indicies for interpolation (eg, nearest
19
16
  # neighbour).
20
17
  #
21
- # @param [Integer] width The width of the source
18
+ # @param [Integer] width The width of the source
22
19
  # @param [Integer] new_width The width of the destination
23
20
  # @return [Array<Integer>] An Array of Integer indicies
24
21
  def steps(width, new_width)
25
22
  indicies, residues = steps_residues(width, new_width)
26
-
23
+
27
24
  for i in 1..new_width
28
- indicies[i-1] = (indicies[i-1] + (residues[i-1] + 127)/255)
25
+ indicies[i - 1] = (indicies[i - 1] + (residues[i - 1] + 127) / 255)
29
26
  end
30
- return indicies
27
+ indicies
31
28
  end
32
29
 
33
30
  # Fractional Interpolation between two values
@@ -39,9 +36,9 @@ module ChunkyPNG
39
36
  # @param [Integer] new_width The width of the destination
40
37
  # @return [Array<Integer>, Array<Integer>] Two arrays of indicies and residues
41
38
  def steps_residues(width, new_width)
42
- indicies = Array.new(new_width, obj=nil)
43
- residues = Array.new(new_width, obj=nil)
44
-
39
+ indicies = Array.new(new_width, nil)
40
+ residues = Array.new(new_width, nil)
41
+
45
42
  # This works by accumulating the fractional error and
46
43
  # overflowing when necessary.
47
44
 
@@ -49,15 +46,15 @@ module ChunkyPNG
49
46
  # 2 * new_width
50
47
  base_step = width / new_width
51
48
  err_step = (width % new_width) << 1
52
- denominator = (new_width) << 1
53
-
49
+ denominator = new_width << 1
50
+
54
51
  # Initial pixel
55
52
  index = (width - new_width) / denominator
56
53
  err = (width - new_width) % denominator
57
54
 
58
55
  for i in 1..new_width
59
- indicies[i-1] = index
60
- residues[i-1] = (255.0 * err.to_f / denominator.to_f).round
56
+ indicies[i - 1] = index
57
+ residues[i - 1] = (255.0 * err.to_f / denominator.to_f).round
61
58
 
62
59
  index += base_step
63
60
  err += err_step
@@ -67,10 +64,9 @@ module ChunkyPNG
67
64
  end
68
65
  end
69
66
 
70
- return indicies, residues
67
+ [indicies, residues]
71
68
  end
72
69
 
73
-
74
70
  # Resamples the canvas using nearest neighbor interpolation.
75
71
  # @param [Integer] new_width The width of the resampled canvas.
76
72
  # @param [Integer] new_height The height of the resampled canvas.
@@ -79,8 +75,7 @@ module ChunkyPNG
79
75
  steps_x = steps(width, new_width)
80
76
  steps_y = steps(height, new_height)
81
77
 
82
-
83
- pixels = Array.new(new_width*new_height)
78
+ pixels = Array.new(new_width * new_height)
84
79
  i = 0
85
80
  for y in steps_y
86
81
  for x in steps_x
@@ -88,10 +83,10 @@ module ChunkyPNG
88
83
  i += 1
89
84
  end
90
85
  end
91
-
86
+
92
87
  replace_canvas!(new_width.to_i, new_height.to_i, pixels)
93
88
  end
94
-
89
+
95
90
  def resample_nearest_neighbor(new_width, new_height)
96
91
  dup.resample_nearest_neighbor!(new_width, new_height)
97
92
  end
@@ -104,19 +99,19 @@ module ChunkyPNG
104
99
  index_x, interp_x = steps_residues(width, new_width)
105
100
  index_y, interp_y = steps_residues(height, new_height)
106
101
 
107
- pixels = Array.new(new_width*new_height)
102
+ pixels = Array.new(new_width * new_height)
108
103
  i = 0
109
104
  for y in 1..new_height
110
105
  # Clamp the indicies to the edges of the image
111
- y1 = [index_y[y-1], 0].max
112
- y2 = [index_y[y-1] + 1, height - 1].min
113
- y_residue = interp_y[y-1]
106
+ y1 = [index_y[y - 1], 0].max
107
+ y2 = [index_y[y - 1] + 1, height - 1].min
108
+ y_residue = interp_y[y - 1]
114
109
 
115
110
  for x in 1..new_width
116
111
  # Clamp the indicies to the edges of the image
117
- x1 = [index_x[x-1], 0].max
118
- x2 = [index_x[x-1] + 1, width - 1].min
119
- x_residue = interp_x[x-1]
112
+ x1 = [index_x[x - 1], 0].max
113
+ x2 = [index_x[x - 1] + 1, width - 1].min
114
+ x_residue = interp_x[x - 1]
120
115
 
121
116
  pixel_11 = get_pixel(x1, y1)
122
117
  pixel_21 = get_pixel(x2, y1)
@@ -139,9 +134,9 @@ module ChunkyPNG
139
134
  def resample_bilinear(new_width, new_height)
140
135
  dup.resample_bilinear!(new_width, new_height)
141
136
  end
142
-
143
- alias_method :resample, :resample_nearest_neighbor
144
- alias_method :resize, :resample
137
+
138
+ alias resample resample_nearest_neighbor
139
+ alias resize resample
145
140
  end
146
141
  end
147
142
  end
@@ -1,9 +1,9 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module ChunkyPNG
2
4
  class Canvas
3
-
4
5
  # Methods to save load a canvas from to stream, encoded in RGB, RGBA, BGR or ABGR format.
5
6
  module StreamExporting
6
-
7
7
  # Creates an RGB-formatted pixelstream with the pixel data from this canvas.
8
8
  #
9
9
  # Note that this format is fast but bloated, because no compression is used
@@ -12,7 +12,7 @@ module ChunkyPNG
12
12
  #
13
13
  # @return [String] The RGBA-formatted pixel data.
14
14
  def to_rgba_stream
15
- pixels.pack('N*')
15
+ pixels.pack("N*")
16
16
  end
17
17
 
18
18
  # Creates an RGB-formatted pixelstream with the pixel data from this canvas.
@@ -23,14 +23,14 @@ module ChunkyPNG
23
23
  #
24
24
  # @return [String] The RGB-formatted pixel data.
25
25
  def to_rgb_stream
26
- pixels.pack('NX' * pixels.length)
26
+ pixels.pack("NX" * pixels.length)
27
27
  end
28
-
28
+
29
29
  # Creates a stream of the alpha channel of this canvas.
30
30
  #
31
31
  # @return [String] The 0-255 alpha values of all pixels packed as string
32
32
  def to_alpha_channel_stream
33
- pixels.pack('C*')
33
+ pixels.pack("C*")
34
34
  end
35
35
 
36
36
  # Creates a grayscale stream of this canvas.
@@ -40,7 +40,7 @@ module ChunkyPNG
40
40
  #
41
41
  # @return [String] The 0-255 grayscale values of all pixels packed as string.
42
42
  def to_grayscale_stream
43
- pixels.pack('nX' * pixels.length)
43
+ pixels.pack("nX" * pixels.length)
44
44
  end
45
45
 
46
46
  # Creates an ABGR-formatted pixelstream with the pixel data from this canvas.
@@ -51,7 +51,7 @@ module ChunkyPNG
51
51
  #
52
52
  # @return [String] The RGBA-formatted pixel data.
53
53
  def to_abgr_stream
54
- pixels.pack('V*')
54
+ pixels.pack("V*")
55
55
  end
56
56
  end
57
57
  end
@@ -1,9 +1,9 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module ChunkyPNG
2
4
  class Canvas
3
-
4
5
  # Methods to quickly load a canvas from a stream, encoded in RGB, RGBA, BGR or ABGR format.
5
6
  module StreamImporting
6
-
7
7
  # Creates a canvas by reading pixels from an RGB formatted stream with a
8
8
  # provided with and height.
9
9
  #
@@ -18,9 +18,9 @@ module ChunkyPNG
18
18
  def from_rgb_stream(width, height, stream)
19
19
  string = stream.respond_to?(:read) ? stream.read(3 * width * height) : stream.to_s[0, 3 * width * height]
20
20
  string << ChunkyPNG::EXTRA_BYTE # Add a fourth byte to the last RGB triple.
21
- unpacker = 'NX' * (width * height)
21
+ unpacker = "NX" * (width * height)
22
22
  pixels = string.unpack(unpacker).map { |color| color | 0x000000ff }
23
- self.new(width, height, pixels)
23
+ new(width, height, pixels)
24
24
  end
25
25
 
26
26
  # Creates a canvas by reading pixels from an RGBA formatted stream with a
@@ -36,7 +36,7 @@ module ChunkyPNG
36
36
  # @return [ChunkyPNG::Canvas] The newly constructed canvas instance.
37
37
  def from_rgba_stream(width, height, stream)
38
38
  string = stream.respond_to?(:read) ? stream.read(4 * width * height) : stream.to_s[0, 4 * width * height]
39
- self.new(width, height, string.unpack("N*"))
39
+ new(width, height, string.unpack("N*"))
40
40
  end
41
41
 
42
42
  # Creates a canvas by reading pixels from an BGR formatted stream with a
@@ -53,8 +53,8 @@ module ChunkyPNG
53
53
  def from_bgr_stream(width, height, stream)
54
54
  string = ChunkyPNG::EXTRA_BYTE.dup # Add a first byte to the first BGR triple.
55
55
  string << (stream.respond_to?(:read) ? stream.read(3 * width * height) : stream.to_s[0, 3 * width * height])
56
- pixels = string.unpack("@1" << ('XV' * (width * height))).map { |color| color | 0x000000ff }
57
- self.new(width, height, pixels)
56
+ pixels = string.unpack("@1#{"XV" * (width * height)}").map { |color| color | 0x000000ff }
57
+ new(width, height, pixels)
58
58
  end
59
59
 
60
60
  # Creates a canvas by reading pixels from an ARGB formatted stream with a
@@ -70,7 +70,7 @@ module ChunkyPNG
70
70
  # @return [ChunkyPNG::Canvas] The newly constructed canvas instance.
71
71
  def from_abgr_stream(width, height, stream)
72
72
  string = stream.respond_to?(:read) ? stream.read(4 * width * height) : stream.to_s[0, 4 * width * height]
73
- self.new(width, height, string.unpack("V*"))
73
+ new(width, height, string.unpack("V*"))
74
74
  end
75
75
  end
76
76
  end
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module ChunkyPNG
2
4
  # A PNG datastream consists of multiple chunks. This module, and the classes
3
5
  # contained within, help with handling these chunks. It supports both reading
@@ -16,10 +18,10 @@ module ChunkyPNG
16
18
  # @param io [IO, #read] The IO stream to read from.
17
19
  # @return [ChunkyPNG::Chung::Base] The loaded chunk instance.
18
20
  def self.read(io)
19
- length, type = read_bytes(io, 8).unpack('Na4')
21
+ length, type = read_bytes(io, 8).unpack("Na4")
20
22
 
21
23
  content = read_bytes(io, length)
22
- crc = read_bytes(io, 4).unpack('N').first
24
+ crc = read_bytes(io, 4).unpack("N").first
23
25
  verify_crc!(type, content, crc)
24
26
 
25
27
  CHUNK_TYPES.fetch(type, Generic).read(type, content)
@@ -74,8 +76,8 @@ module ChunkyPNG
74
76
  # @param io [IO] The IO stream to write to.
75
77
  # @param content [String] The content for this chunk.
76
78
  def write_with_crc(io, content)
77
- io << [content.length].pack('N') << type << content
78
- io << [Zlib.crc32(content, Zlib.crc32(type))].pack('N')
79
+ io << [content.length].pack("N") << type << content
80
+ io << [Zlib.crc32(content, Zlib.crc32(type))].pack("N")
79
81
  end
80
82
 
81
83
  # Writes the chunk to the IO stream.
@@ -84,7 +86,7 @@ module ChunkyPNG
84
86
  # and will calculate and append the checksum automatically.
85
87
  # @param io [IO] The IO stream to write to.
86
88
  def write(io)
87
- write_with_crc(io, content || '')
89
+ write_with_crc(io, content || "")
88
90
  end
89
91
  end
90
92
 
@@ -95,8 +97,8 @@ module ChunkyPNG
95
97
  # written by the +write+ method.
96
98
  attr_accessor :content
97
99
 
98
- def initialize(type, content = '')
99
- super(type, :content => content)
100
+ def initialize(type, content = "")
101
+ super(type, content: content)
100
102
  end
101
103
 
102
104
  # Creates an instance, given the chunk's type and content.
@@ -118,11 +120,10 @@ module ChunkyPNG
118
120
  # Note that it is still possible to access the chunk for such an image, but
119
121
  # ChunkyPNG will raise an exception if you try to access the pixel data.
120
122
  class Header < Base
121
- attr_accessor :width, :height, :depth, :color, :compression, :filtering,
122
- :interlace
123
+ attr_accessor :width, :height, :depth, :color, :compression, :filtering, :interlace
123
124
 
124
125
  def initialize(attrs = {})
125
- super('IHDR', attrs)
126
+ super("IHDR", attrs)
126
127
  @depth ||= 8
127
128
  @color ||= ChunkyPNG::COLOR_TRUECOLOR
128
129
  @compression ||= ChunkyPNG::COMPRESSION_DEFAULT
@@ -137,31 +138,39 @@ module ChunkyPNG
137
138
  # @return [ChunkyPNG::Chunk::End] The new Header chunk instance with the
138
139
  # variables set to the values according to the content.
139
140
  def self.read(type, content)
140
- fields = content.unpack('NNC5')
141
- new(:width => fields[0],
142
- :height => fields[1],
143
- :depth => fields[2],
144
- :color => fields[3],
145
- :compression => fields[4],
146
- :filtering => fields[5],
147
- :interlace => fields[6])
141
+ fields = content.unpack("NNC5")
142
+ new(
143
+ width: fields[0],
144
+ height: fields[1],
145
+ depth: fields[2],
146
+ color: fields[3],
147
+ compression: fields[4],
148
+ filtering: fields[5],
149
+ interlace: fields[6]
150
+ )
148
151
  end
149
152
 
150
153
  # Returns the content for this chunk when it gets written to a file, by
151
154
  # packing the image information variables into the correct format.
152
155
  # @return [String] The 13-byte content for the header chunk.
153
156
  def content
154
- [width, height, depth, color, compression, filtering, interlace].
155
- pack('NNC5')
157
+ [
158
+ width,
159
+ height,
160
+ depth,
161
+ color,
162
+ compression,
163
+ filtering,
164
+ interlace,
165
+ ].pack("NNC5")
156
166
  end
157
167
  end
158
168
 
159
169
  # The End (IEND) chunk indicates the last chunk of a PNG stream. It does
160
170
  # not contain any data.
161
171
  class End < Base
162
-
163
172
  def initialize
164
- super('IEND')
173
+ super("IEND")
165
174
  end
166
175
 
167
176
  # Reads the END chunk. It will check if the content is empty.
@@ -172,14 +181,14 @@ module ChunkyPNG
172
181
  # @return [ChunkyPNG::Chunk::End] The new End chunk instance.
173
182
  # @raise [ChunkyPNG::ExpectationFailed] Raises an exception if the content was not empty.
174
183
  def self.read(type, content)
175
- raise ExpectationFailed, 'The IEND chunk should be empty!' if content.bytesize > 0
176
- self.new
184
+ raise ExpectationFailed, "The IEND chunk should be empty!" if content.bytesize > 0
185
+ new
177
186
  end
178
187
 
179
188
  # Returns an empty string, because this chunk should always be empty.
180
189
  # @return [""] An empty string.
181
190
  def content
182
- ChunkyPNG::Datastream.empty_bytearray
191
+ "".b
183
192
  end
184
193
  end
185
194
 
@@ -214,7 +223,7 @@ module ChunkyPNG
214
223
  # @return [Array<Integer>] Returns an array of alpha channel values
215
224
  # [0-255].
216
225
  def palette_alpha_channel
217
- content.unpack('C*')
226
+ content.unpack("C*")
218
227
  end
219
228
 
220
229
  # Returns the truecolor entry to be replaced by transparent pixels,
@@ -224,9 +233,8 @@ module ChunkyPNG
224
233
  #
225
234
  # @return [Integer] The color to replace with fully transparent pixels.
226
235
  def truecolor_entry(bit_depth)
227
- values = content.unpack('nnn').map do |c|
228
- ChunkyPNG::Canvas.send(:"decode_png_resample_#{bit_depth}bit_value", c)
229
- end
236
+ decode_method_name = :"decode_png_resample_#{bit_depth}bit_value"
237
+ values = content.unpack("nnn").map { |c| ChunkyPNG::Canvas.send(decode_method_name, c) }
230
238
  ChunkyPNG::Color.rgb(*values)
231
239
  end
232
240
 
@@ -238,7 +246,7 @@ module ChunkyPNG
238
246
  # @return [Integer] The (grayscale) color to replace with fully
239
247
  # transparent pixels.
240
248
  def grayscale_entry(bit_depth)
241
- value = ChunkyPNG::Canvas.send(:"decode_png_resample_#{bit_depth}bit_value", content.unpack('n')[0])
249
+ value = ChunkyPNG::Canvas.send(:"decode_png_resample_#{bit_depth}bit_value", content.unpack("n")[0])
242
250
  ChunkyPNG::Color.grayscale(value)
243
251
  end
244
252
  end
@@ -255,7 +263,7 @@ module ChunkyPNG
255
263
  def self.split_in_chunks(data, level = Zlib::DEFAULT_COMPRESSION, chunk_size = 2147483647)
256
264
  streamdata = Zlib::Deflate.deflate(data, level)
257
265
  # TODO: Split long streamdata over multiple chunks
258
- [ ChunkyPNG::Chunk::ImageData.new('IDAT', streamdata) ]
266
+ [ChunkyPNG::Chunk::ImageData.new("IDAT", streamdata)]
259
267
  end
260
268
  end
261
269
 
@@ -271,12 +279,12 @@ module ChunkyPNG
271
279
  attr_accessor :keyword, :value
272
280
 
273
281
  def initialize(keyword, value)
274
- super('tEXt')
282
+ super("tEXt")
275
283
  @keyword, @value = keyword, value
276
284
  end
277
285
 
278
286
  def self.read(type, content)
279
- keyword, value = content.unpack('Z*a*')
287
+ keyword, value = content.unpack("Z*a*")
280
288
  new(keyword, value)
281
289
  end
282
290
 
@@ -285,7 +293,7 @@ module ChunkyPNG
285
293
  #
286
294
  # @return The content that should be written to the datastream.
287
295
  def content
288
- [keyword, value].pack('Z*a*')
296
+ [keyword, value].pack("Z*a*")
289
297
  end
290
298
  end
291
299
 
@@ -299,12 +307,12 @@ module ChunkyPNG
299
307
  attr_accessor :keyword, :value
300
308
 
301
309
  def initialize(keyword, value)
302
- super('zTXt')
310
+ super("zTXt")
303
311
  @keyword, @value = keyword, value
304
312
  end
305
313
 
306
314
  def self.read(type, content)
307
- keyword, compression, value = content.unpack('Z*Ca*')
315
+ keyword, compression, value = content.unpack("Z*Ca*")
308
316
  raise ChunkyPNG::NotSupported, "Compression method #{compression.inspect} not supported!" unless compression == ChunkyPNG::COMPRESSION_DEFAULT
309
317
  new(keyword, Zlib::Inflate.inflate(value))
310
318
  end
@@ -314,8 +322,11 @@ module ChunkyPNG
314
322
  #
315
323
  # @return The content that should be written to the datastream.
316
324
  def content
317
- [keyword, ChunkyPNG::COMPRESSION_DEFAULT, Zlib::Deflate.deflate(value)].
318
- pack('Z*Ca*')
325
+ [
326
+ keyword,
327
+ ChunkyPNG::COMPRESSION_DEFAULT,
328
+ Zlib::Deflate.deflate(value),
329
+ ].pack("Z*Ca*")
319
330
  end
320
331
  end
321
332
 
@@ -327,23 +338,23 @@ module ChunkyPNG
327
338
  attr_accessor :ppux, :ppuy, :unit
328
339
 
329
340
  def initialize(ppux, ppuy, unit = :unknown)
330
- raise ArgumentError, 'unit must be either :meters or :unknown' unless [:meters, :unknown].member?(unit)
331
- super('pHYs')
341
+ raise ArgumentError, "unit must be either :meters or :unknown" unless [:meters, :unknown].member?(unit)
342
+ super("pHYs")
332
343
  @ppux, @ppuy, @unit = ppux, ppuy, unit
333
344
  end
334
345
 
335
346
  def dpix
336
- raise ChunkyPNG::UnitsUnknown, 'the PNG specifies its physical aspect ratio, but does not specify the units of its pixels\' physical dimensions' unless unit == :meters
347
+ raise ChunkyPNG::UnitsUnknown, "the PNG specifies its physical aspect ratio, but does not specify the units of its pixels' physical dimensions" unless unit == :meters
337
348
  ppux * INCHES_PER_METER
338
349
  end
339
350
 
340
351
  def dpiy
341
- raise ChunkyPNG::UnitsUnknown, 'the PNG specifies its physical aspect ratio, but does not specify the units of its pixels\' physical dimensions' unless unit == :meters
352
+ raise ChunkyPNG::UnitsUnknown, "the PNG specifies its physical aspect ratio, but does not specify the units of its pixels' physical dimensions" unless unit == :meters
342
353
  ppuy * INCHES_PER_METER
343
354
  end
344
355
 
345
356
  def self.read(type, content)
346
- ppux, ppuy, unit = content.unpack('NNC')
357
+ ppux, ppuy, unit = content.unpack("NNC")
347
358
  unit = unit == 1 ? :meters : :unknown
348
359
  new(ppux, ppuy, unit)
349
360
  end
@@ -351,7 +362,7 @@ module ChunkyPNG
351
362
  # Assembles the content to write to the stream for this chunk.
352
363
  # @return [String] The binary content that should be written to the datastream.
353
364
  def content
354
- [ppux, ppuy, unit == :meters ? 1 : 0].pack('NNC')
365
+ [ppux, ppuy, unit == :meters ? 1 : 0].pack("NNC")
355
366
  end
356
367
 
357
368
  INCHES_PER_METER = 0.0254
@@ -372,8 +383,8 @@ module ChunkyPNG
372
383
  class InternationalText < Base
373
384
  attr_accessor :keyword, :text, :language_tag, :translated_keyword, :compressed, :compression
374
385
 
375
- def initialize(keyword, text, language_tag = '', translated_keyword = '', compressed = ChunkyPNG::UNCOMPRESSED_CONTENT, compression = ChunkyPNG::COMPRESSION_DEFAULT)
376
- super('iTXt')
386
+ def initialize(keyword, text, language_tag = "", translated_keyword = "", compressed = ChunkyPNG::UNCOMPRESSED_CONTENT, compression = ChunkyPNG::COMPRESSION_DEFAULT)
387
+ super("iTXt")
377
388
  @keyword = keyword
378
389
  @text = text
379
390
  @language_tag = language_tag
@@ -390,16 +401,16 @@ module ChunkyPNG
390
401
  # @raise [ChunkyPNG::NotSupported] If the chunk refers to an unsupported compression method.
391
402
  # Currently uncompressed data and deflate are supported.
392
403
  def self.read(type, content)
393
- keyword, compressed, compression, language_tag, translated_keyword, text = content.unpack('Z*CCZ*Z*a*')
404
+ keyword, compressed, compression, language_tag, translated_keyword, text = content.unpack("Z*CCZ*Z*a*")
394
405
  raise ChunkyPNG::NotSupported, "Compression flag #{compressed.inspect} not supported!" unless compressed == ChunkyPNG::UNCOMPRESSED_CONTENT || compressed == ChunkyPNG::COMPRESSED_CONTENT
395
406
  raise ChunkyPNG::NotSupported, "Compression method #{compression.inspect} not supported!" unless compression == ChunkyPNG::COMPRESSION_DEFAULT
396
407
 
397
408
  text = Zlib::Inflate.inflate(text) if compressed == ChunkyPNG::COMPRESSED_CONTENT
398
409
 
399
- text.force_encoding('utf-8')
410
+ text.force_encoding("utf-8")
400
411
  raise ChunkyPNG::InvalidUTF8, "Invalid unicode encountered in iTXt chunk" unless text.valid_encoding?
401
412
 
402
- translated_keyword.force_encoding('utf-8')
413
+ translated_keyword.force_encoding("utf-8")
403
414
  raise ChunkyPNG::InvalidUTF8, "Invalid unicode encountered in iTXt chunk" unless translated_keyword.valid_encoding?
404
415
 
405
416
  new(keyword, text, language_tag, translated_keyword, compressed, compression)
@@ -408,10 +419,10 @@ module ChunkyPNG
408
419
  # Assembles the content to write to the stream for this chunk.
409
420
  # @return [String] The binary content that should be written to the datastream.
410
421
  def content
411
- text_field = text.encode('utf-8')
412
- text_field = (compressed == ChunkyPNG::COMPRESSED_CONTENT) ? Zlib::Deflate.deflate(text_field) : text_field
422
+ text_field = text.encode("utf-8")
423
+ text_field = compressed == ChunkyPNG::COMPRESSED_CONTENT ? Zlib::Deflate.deflate(text_field) : text_field
413
424
 
414
- [keyword, compressed, compression, language_tag, translated_keyword.encode('utf-8'), text_field].pack('Z*CCZ*Z*a*')
425
+ [keyword, compressed, compression, language_tag, translated_keyword.encode("utf-8"), text_field].pack("Z*CCZ*Z*a*")
415
426
  end
416
427
  end
417
428
 
@@ -423,15 +434,15 @@ module ChunkyPNG
423
434
  #
424
435
  # @see ChunkyPNG::Chunk.read
425
436
  CHUNK_TYPES = {
426
- 'IHDR' => Header,
427
- 'IEND' => End,
428
- 'IDAT' => ImageData,
429
- 'PLTE' => Palette,
430
- 'tRNS' => Transparency,
431
- 'tEXt' => Text,
432
- 'zTXt' => CompressedText,
433
- 'iTXt' => InternationalText,
434
- 'pHYs' => Physical,
437
+ "IHDR" => Header,
438
+ "IEND" => End,
439
+ "IDAT" => ImageData,
440
+ "PLTE" => Palette,
441
+ "tRNS" => Transparency,
442
+ "tEXt" => Text,
443
+ "zTXt" => CompressedText,
444
+ "iTXt" => InternationalText,
445
+ "pHYs" => Physical,
435
446
  }
436
447
  end
437
448
  end