chunky_png 1.3.9 → 1.3.12

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