chunky_png 1.3.6 → 1.3.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.rdoc +5 -0
- data/lib/chunky_png/canvas/png_decoding.rb +35 -36
- data/lib/chunky_png/color.rb +2 -0
- data/lib/chunky_png/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2774ecc9f2d9e0bb09588d857ec1bf66fe0161e2
|
4
|
+
data.tar.gz: 0144ec4242f3bf5c180a8ef5a1bb51fd3e42ca65
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea93bfb789b22f4158605984c46fdc333a6e2a83d4f0cf2165b739be6da12383128fd61d89558bed9cef213d8546010c482b1244ccc3aa2423eb1943a0df3c34
|
7
|
+
data.tar.gz: baa158877d3f95359219b5a4c1d31e517a9853a947567a3e5bb4d27c5d9ab876be7321b5e7087d5e56f7895b0e5d515f0d2c44c2d3acb35ba32e92ab7cc9d00a
|
data/CHANGELOG.rdoc
CHANGED
@@ -9,6 +9,11 @@ The file documents the changes to this library over the different versions.
|
|
9
9
|
|
10
10
|
- Nothing yet!
|
11
11
|
|
12
|
+
=== 1.3.7 - 2016-08-31
|
13
|
+
|
14
|
+
- Performance improvement for <tt>Color.euclidean_distance_rgba</tt>.
|
15
|
+
- Bugfix in decoding transparent pixels when decoding multiple images in a row.
|
16
|
+
|
12
17
|
=== 1.3.6 - 2016-06-19
|
13
18
|
|
14
19
|
- Allow reading images from streams that have trailing data after the IEND chunk.
|
@@ -29,14 +29,6 @@ module ChunkyPNG
|
|
29
29
|
# @see http://www.w3.org/TR/PNG/ The W3C PNG format specification
|
30
30
|
module PNGDecoding
|
31
31
|
|
32
|
-
# The palette that is used to decode the image, loading from the PLTE and
|
33
|
-
# tRNS chunk from the PNG stream. For RGB(A) images, no palette is required.
|
34
|
-
# @return [ChunkyPNG::Palette]
|
35
|
-
attr_accessor :decoding_palette
|
36
|
-
|
37
|
-
# The color to be replaced with fully transparent pixels.
|
38
|
-
attr_accessor :transparent_color
|
39
|
-
|
40
32
|
# Decodes a Canvas from a PNG encoded string.
|
41
33
|
# @param [String] str The string to read from.
|
42
34
|
# @return [ChunkyPNG::Canvas] The canvas decoded from the PNG encoded string.
|
@@ -76,16 +68,17 @@ module ChunkyPNG
|
|
76
68
|
raise ExpectationFailed, "Invalid image size, width: #{width}, height: #{height}"
|
77
69
|
end
|
78
70
|
|
71
|
+
decoding_palette, transparent_color = nil, nil
|
79
72
|
case color_mode
|
80
73
|
when ChunkyPNG::COLOR_INDEXED
|
81
|
-
|
74
|
+
decoding_palette = ChunkyPNG::Palette.from_chunks(ds.palette_chunk, ds.transparency_chunk)
|
82
75
|
when ChunkyPNG::COLOR_TRUECOLOR
|
83
|
-
|
76
|
+
transparent_color = ds.transparency_chunk.truecolor_entry(depth) if ds.transparency_chunk
|
84
77
|
when ChunkyPNG::COLOR_GRAYSCALE
|
85
|
-
|
78
|
+
transparent_color = ds.transparency_chunk.grayscale_entry(depth) if ds.transparency_chunk
|
86
79
|
end
|
87
80
|
|
88
|
-
decode_png_pixelstream(ds.imagedata, width, height, color_mode, depth, interlace)
|
81
|
+
decode_png_pixelstream(ds.imagedata, width, height, color_mode, depth, interlace, decoding_palette, transparent_color)
|
89
82
|
end
|
90
83
|
|
91
84
|
# Decodes a canvas from a PNG encoded pixelstream, using a given width, height,
|
@@ -96,13 +89,15 @@ module ChunkyPNG
|
|
96
89
|
# @param [Integer] color_mode The color mode of the encoded pixelstream.
|
97
90
|
# @param [Integer] depth The bit depth of the pixel samples.
|
98
91
|
# @param [Integer] interlace The interlace method of the encoded pixelstream.
|
92
|
+
# @param [ChunkyPNG::Palette] decoding_palette The palette to use to decode colors.
|
93
|
+
# @param [Integer] transparent_color The color that should be considered fully transparent.
|
99
94
|
# @return [ChunkyPNG::Canvas] The decoded Canvas instance.
|
100
|
-
def decode_png_pixelstream(stream, width, height, color_mode, depth, interlace)
|
95
|
+
def decode_png_pixelstream(stream, width, height, color_mode, depth, interlace, decoding_palette, transparent_color)
|
101
96
|
raise ChunkyPNG::ExpectationFailed, "This palette is not suitable for decoding!" if decoding_palette && !decoding_palette.can_decode?
|
102
97
|
|
103
98
|
image = case interlace
|
104
|
-
when ChunkyPNG::INTERLACING_NONE; decode_png_without_interlacing(stream, width, height, color_mode, depth)
|
105
|
-
when ChunkyPNG::INTERLACING_ADAM7; decode_png_with_adam7_interlacing(stream, width, height, color_mode, depth)
|
99
|
+
when ChunkyPNG::INTERLACING_NONE; decode_png_without_interlacing(stream, width, height, color_mode, depth, decoding_palette)
|
100
|
+
when ChunkyPNG::INTERLACING_ADAM7; decode_png_with_adam7_interlacing(stream, width, height, color_mode, depth, decoding_palette)
|
106
101
|
else raise ChunkyPNG::NotSupported, "Don't know how the handle interlacing method #{interlace}!"
|
107
102
|
end
|
108
103
|
|
@@ -119,9 +114,10 @@ module ChunkyPNG
|
|
119
114
|
# @param height (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
120
115
|
# @param color_mode (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
121
116
|
# @param depth (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
117
|
+
# @param [ChunkyPNG::Palette] decoding_palette The palette to use to decode colors.
|
122
118
|
# @return (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
123
|
-
def decode_png_without_interlacing(stream, width, height, color_mode, depth)
|
124
|
-
decode_png_image_pass(stream, width, height, color_mode, depth, 0)
|
119
|
+
def decode_png_without_interlacing(stream, width, height, color_mode, depth, decoding_palette)
|
120
|
+
decode_png_image_pass(stream, width, height, color_mode, depth, 0, decoding_palette)
|
125
121
|
end
|
126
122
|
|
127
123
|
# Decodes a canvas from a Adam 7 interlaced PNG encoded pixelstream, using a
|
@@ -131,13 +127,14 @@ module ChunkyPNG
|
|
131
127
|
# @param height (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
132
128
|
# @param color_mode (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
133
129
|
# @param depth (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
130
|
+
# @param [ChunkyPNG::Palette] decoding_palette The palette to use to decode colors.
|
134
131
|
# @return (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
135
|
-
def decode_png_with_adam7_interlacing(stream, width, height, color_mode, depth)
|
132
|
+
def decode_png_with_adam7_interlacing(stream, width, height, color_mode, depth, decoding_palette)
|
136
133
|
canvas = new(width, height)
|
137
134
|
start_pos = 0
|
138
135
|
for pass in 0...7
|
139
136
|
sm_width, sm_height = adam7_pass_size(pass, width, height)
|
140
|
-
sm = decode_png_image_pass(stream, sm_width, sm_height, color_mode, depth, start_pos)
|
137
|
+
sm = decode_png_image_pass(stream, sm_width, sm_height, color_mode, depth, start_pos, decoding_palette)
|
141
138
|
adam7_merge_pass(pass, canvas, sm)
|
142
139
|
start_pos += ChunkyPNG::Color.pass_bytesize(color_mode, depth, sm_width, sm_height)
|
143
140
|
end
|
@@ -213,8 +210,9 @@ module ChunkyPNG
|
|
213
210
|
# @param [String] stream The stream to decode from.
|
214
211
|
# @param [Integer] pos The position in the stream on which the scanline starts (including the filter byte).
|
215
212
|
# @param [Integer] width The width in pixels of the scanline.
|
213
|
+
# @param [ChunkyPNG::Palette] decoding_palette The palette to use to decode colors.
|
216
214
|
# @return [Array<Integer>] An array of decoded pixels.
|
217
|
-
def decode_png_pixels_from_scanline_indexed_1bit(stream, pos, width)
|
215
|
+
def decode_png_pixels_from_scanline_indexed_1bit(stream, pos, width, decoding_palette)
|
218
216
|
(0...width).map do |index|
|
219
217
|
palette_pos = decode_png_extract_1bit_value(stream.getbyte(pos + 1 + (index >> 3)), index)
|
220
218
|
decoding_palette[palette_pos]
|
@@ -224,7 +222,7 @@ module ChunkyPNG
|
|
224
222
|
# Decodes a scanline of a 2-bit, indexed image into a row of pixels.
|
225
223
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
226
224
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
227
|
-
def decode_png_pixels_from_scanline_indexed_2bit(stream, pos, width)
|
225
|
+
def decode_png_pixels_from_scanline_indexed_2bit(stream, pos, width, decoding_palette)
|
228
226
|
(0...width).map do |index|
|
229
227
|
palette_pos = decode_png_extract_2bit_value(stream.getbyte(pos + 1 + (index >> 2)), index)
|
230
228
|
decoding_palette[palette_pos]
|
@@ -234,7 +232,7 @@ module ChunkyPNG
|
|
234
232
|
# Decodes a scanline of a 4-bit, indexed image into a row of pixels.
|
235
233
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
236
234
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
237
|
-
def decode_png_pixels_from_scanline_indexed_4bit(stream, pos, width)
|
235
|
+
def decode_png_pixels_from_scanline_indexed_4bit(stream, pos, width, decoding_palette)
|
238
236
|
(0...width).map do |index|
|
239
237
|
palette_pos = decode_png_extract_4bit_value(stream.getbyte(pos + 1 + (index >> 1)), index)
|
240
238
|
decoding_palette[palette_pos]
|
@@ -244,21 +242,21 @@ module ChunkyPNG
|
|
244
242
|
# Decodes a scanline of a 8-bit, indexed image into a row of pixels.
|
245
243
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
246
244
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
247
|
-
def decode_png_pixels_from_scanline_indexed_8bit(stream, pos, width)
|
245
|
+
def decode_png_pixels_from_scanline_indexed_8bit(stream, pos, width, decoding_palette)
|
248
246
|
(1..width).map { |i| decoding_palette[stream.getbyte(pos + i)] }
|
249
247
|
end
|
250
248
|
|
251
249
|
# Decodes a scanline of an 8-bit, true color image with transparency into a row of pixels.
|
252
250
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
253
251
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
254
|
-
def decode_png_pixels_from_scanline_truecolor_alpha_8bit(stream, pos, width)
|
252
|
+
def decode_png_pixels_from_scanline_truecolor_alpha_8bit(stream, pos, width, _decoding_palette)
|
255
253
|
stream.unpack("@#{pos + 1}N#{width}")
|
256
254
|
end
|
257
255
|
|
258
256
|
# Decodes a scanline of a 16-bit, true color image with transparency into a row of pixels.
|
259
257
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
260
258
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
261
|
-
def decode_png_pixels_from_scanline_truecolor_alpha_16bit(stream, pos, width)
|
259
|
+
def decode_png_pixels_from_scanline_truecolor_alpha_16bit(stream, pos, width, _decoding_palette)
|
262
260
|
pixels = []
|
263
261
|
stream.unpack("@#{pos + 1}n#{width * 4}").each_slice(4) do |r, g, b, a|
|
264
262
|
pixels << ChunkyPNG::Color.rgba(decode_png_resample_16bit_value(r), decode_png_resample_16bit_value(g),
|
@@ -270,14 +268,14 @@ module ChunkyPNG
|
|
270
268
|
# Decodes a scanline of an 8-bit, true color image into a row of pixels.
|
271
269
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
272
270
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
273
|
-
def decode_png_pixels_from_scanline_truecolor_8bit(stream, pos, width)
|
271
|
+
def decode_png_pixels_from_scanline_truecolor_8bit(stream, pos, width, _decoding_palette)
|
274
272
|
stream.unpack("@#{pos + 1}" << ('NX' * width)).map { |c| c | 0x000000ff }
|
275
273
|
end
|
276
274
|
|
277
275
|
# Decodes a scanline of a 16-bit, true color image into a row of pixels.
|
278
276
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
279
277
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
280
|
-
def decode_png_pixels_from_scanline_truecolor_16bit(stream, pos, width)
|
278
|
+
def decode_png_pixels_from_scanline_truecolor_16bit(stream, pos, width, _decoding_palette)
|
281
279
|
pixels = []
|
282
280
|
stream.unpack("@#{pos + 1}n#{width * 3}").each_slice(3) do |r, g, b|
|
283
281
|
pixels << ChunkyPNG::Color.rgb(decode_png_resample_16bit_value(r), decode_png_resample_16bit_value(g), decode_png_resample_16bit_value(b))
|
@@ -288,14 +286,14 @@ module ChunkyPNG
|
|
288
286
|
# Decodes a scanline of an 8-bit, grayscale image with transparency into a row of pixels.
|
289
287
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
290
288
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
291
|
-
def decode_png_pixels_from_scanline_grayscale_alpha_8bit(stream, pos, width)
|
289
|
+
def decode_png_pixels_from_scanline_grayscale_alpha_8bit(stream, pos, width, _decoding_palette)
|
292
290
|
(0...width).map { |i| ChunkyPNG::Color.grayscale_alpha(stream.getbyte(pos + (i * 2) + 1), stream.getbyte(pos + (i * 2) + 2)) }
|
293
291
|
end
|
294
292
|
|
295
293
|
# Decodes a scanline of a 16-bit, grayscale image with transparency into a row of pixels.
|
296
294
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
297
295
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
298
|
-
def decode_png_pixels_from_scanline_grayscale_alpha_16bit(stream, pos, width)
|
296
|
+
def decode_png_pixels_from_scanline_grayscale_alpha_16bit(stream, pos, width, _decoding_palette)
|
299
297
|
pixels = []
|
300
298
|
stream.unpack("@#{pos + 1}n#{width * 2}").each_slice(2) do |g, a|
|
301
299
|
pixels << ChunkyPNG::Color.grayscale_alpha(decode_png_resample_16bit_value(g), decode_png_resample_16bit_value(a))
|
@@ -306,7 +304,7 @@ module ChunkyPNG
|
|
306
304
|
# Decodes a scanline of a 1-bit, grayscale image into a row of pixels.
|
307
305
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
308
306
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
309
|
-
def decode_png_pixels_from_scanline_grayscale_1bit(stream, pos, width)
|
307
|
+
def decode_png_pixels_from_scanline_grayscale_1bit(stream, pos, width, _decoding_palette)
|
310
308
|
(0...width).map do |index|
|
311
309
|
value = decode_png_extract_1bit_value(stream.getbyte(pos + 1 + (index >> 3)), index)
|
312
310
|
value == 1 ? ChunkyPNG::Color::WHITE : ChunkyPNG::Color::BLACK
|
@@ -316,7 +314,7 @@ module ChunkyPNG
|
|
316
314
|
# Decodes a scanline of a 2-bit, grayscale image into a row of pixels.
|
317
315
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
318
316
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
319
|
-
def decode_png_pixels_from_scanline_grayscale_2bit(stream, pos, width)
|
317
|
+
def decode_png_pixels_from_scanline_grayscale_2bit(stream, pos, width, _decoding_palette)
|
320
318
|
(0...width).map do |index|
|
321
319
|
value = decode_png_extract_2bit_value(stream.getbyte(pos + 1 + (index >> 2)), index)
|
322
320
|
ChunkyPNG::Color.grayscale(decode_png_resample_2bit_value(value))
|
@@ -326,7 +324,7 @@ module ChunkyPNG
|
|
326
324
|
# Decodes a scanline of a 4-bit, grayscale image into a row of pixels.
|
327
325
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
328
326
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
329
|
-
def decode_png_pixels_from_scanline_grayscale_4bit(stream, pos, width)
|
327
|
+
def decode_png_pixels_from_scanline_grayscale_4bit(stream, pos, width, _decoding_palette)
|
330
328
|
(0...width).map do |index|
|
331
329
|
value = decode_png_extract_4bit_value(stream.getbyte(pos + 1 + (index >> 1)), index)
|
332
330
|
ChunkyPNG::Color.grayscale(decode_png_resample_4bit_value(value))
|
@@ -336,14 +334,14 @@ module ChunkyPNG
|
|
336
334
|
# Decodes a scanline of an 8-bit, grayscale image into a row of pixels.
|
337
335
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
338
336
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
339
|
-
def decode_png_pixels_from_scanline_grayscale_8bit(stream, pos, width)
|
337
|
+
def decode_png_pixels_from_scanline_grayscale_8bit(stream, pos, width, _decoding_palette)
|
340
338
|
(1..width).map { |i| ChunkyPNG::Color.grayscale(stream.getbyte(pos + i)) }
|
341
339
|
end
|
342
340
|
|
343
341
|
# Decodes a scanline of a 16-bit, grayscale image into a row of pixels.
|
344
342
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
345
343
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
346
|
-
def decode_png_pixels_from_scanline_grayscale_16bit(stream, pos, width)
|
344
|
+
def decode_png_pixels_from_scanline_grayscale_16bit(stream, pos, width, _decoding_palette)
|
347
345
|
values = stream.unpack("@#{pos + 1}n#{width}")
|
348
346
|
values.map { |value| ChunkyPNG::Color.grayscale(decode_png_resample_16bit_value(value)) }
|
349
347
|
end
|
@@ -378,8 +376,9 @@ module ChunkyPNG
|
|
378
376
|
# @param height (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
379
377
|
# @param color_mode (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
380
378
|
# @param [Integer] start_pos The position in the pixel stream to start reading.
|
379
|
+
# @param [ChunkyPNG::Palette] decoding_palette The palette to use to decode colors.
|
381
380
|
# @return (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
382
|
-
def decode_png_image_pass(stream, width, height, color_mode, depth, start_pos)
|
381
|
+
def decode_png_image_pass(stream, width, height, color_mode, depth, start_pos, decoding_palette)
|
383
382
|
|
384
383
|
pixels = []
|
385
384
|
if width > 0 && height > 0
|
@@ -394,7 +393,7 @@ module ChunkyPNG
|
|
394
393
|
pos, prev_pos = start_pos, nil
|
395
394
|
for _ in 0...height do
|
396
395
|
decode_png_str_scanline(stream, pos, prev_pos, line_length, pixel_size)
|
397
|
-
pixels.concat(send(pixel_decoder, stream, pos, width))
|
396
|
+
pixels.concat(send(pixel_decoder, stream, pos, width, decoding_palette))
|
398
397
|
|
399
398
|
prev_pos = pos
|
400
399
|
pos += line_length + 1
|
data/lib/chunky_png/color.rb
CHANGED
@@ -714,6 +714,8 @@ module ChunkyPNG
|
|
714
714
|
# @param pixel_before [Integer]
|
715
715
|
# @return [Float]
|
716
716
|
def euclidean_distance_rgba(pixel_after, pixel_before)
|
717
|
+
return 0.0 if pixel_after == pixel_before
|
718
|
+
|
717
719
|
Math.sqrt(
|
718
720
|
(r(pixel_after) - r(pixel_before))**2 +
|
719
721
|
(g(pixel_after) - g(pixel_before))**2 +
|
data/lib/chunky_png/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chunky_png
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Willem van Bergen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|