chunky_png 1.3.5 → 1.3.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.rdoc +13 -0
- data/LICENSE +1 -1
- data/README.md +88 -0
- data/benchmarks/filesize_benchmark.rb +1 -1
- data/chunky_png.gemspec +1 -1
- data/lib/chunky_png.rb +2 -2
- data/lib/chunky_png/canvas/drawing.rb +4 -4
- data/lib/chunky_png/canvas/operations.rb +0 -1
- data/lib/chunky_png/canvas/png_decoding.rb +36 -36
- data/lib/chunky_png/color.rb +1 -1
- data/lib/chunky_png/datastream.rb +1 -1
- data/lib/chunky_png/version.rb +1 -1
- data/spec/chunky_png/datastream_spec.rb +6 -0
- data/spec/resources/trailing_bytes_after_iend_chunk.png +0 -0
- metadata +7 -5
- data/README.rdoc +0 -84
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fcd13f536104dcb74ae0a6ab6f4c32fe743b62d0
|
4
|
+
data.tar.gz: dfbfd7a772203855d816b00650b2c0559392588c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5eaa5acf93abd3766ff83a825552c879396c8a61cc0f9f72ee1b4904cbd38f4e4f33caf98d1968cae748c30140f6d65f0f10453ed34c001b9a2cda37bf76ab66
|
7
|
+
data.tar.gz: 184f7559e6cabfe646b6c18cc1cb9d33c5f67b64f204deb30ceb264c0143959fbea27e34630521f3a84fe9d8fff59579fabc2ad96fe15577e6e10eb898f22272
|
data/CHANGELOG.rdoc
CHANGED
@@ -9,6 +9,19 @@ The file documents the changes to this library over the different versions.
|
|
9
9
|
|
10
10
|
- Nothing yet!
|
11
11
|
|
12
|
+
=== 1.3.6 - 2016-06-19
|
13
|
+
|
14
|
+
- Allow reading images from streams that have trailing data after the IEND chunk.
|
15
|
+
- Add compatibility for Ruby 2.3's frozen string literals.
|
16
|
+
- Documentation updates and small cleanups.
|
17
|
+
|
18
|
+
=== 1.3.5 - 2015-10-28
|
19
|
+
|
20
|
+
- Performance improvements for <tt>Canvas#crop!</tt> and <tt>ImageData.combine_chunks</tt>
|
21
|
+
- Update <tt>chunky_png/rmagick</tt> to work with the latest versions of RMagick.
|
22
|
+
- Bugfix in <tt>Color#from_hsl</tt> and <tt>Color#from_hsv</tt> when hue value is 360.
|
23
|
+
- Fix encoding issue in <tt>Datastream#to_blob</tt>
|
24
|
+
|
12
25
|
=== 1.3.4 - 2015-02-16
|
13
26
|
|
14
27
|
- Assert compatibility with Ruby 2.2
|
data/LICENSE
CHANGED
data/README.md
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# ChunkyPNG [![Build Status](https://travis-ci.org/wvanbergen/chunky_png.svg?branch=master)](https://travis-ci.org/wvanbergen/chunky_png)
|
2
|
+
|
3
|
+
This library can read and write PNG files. It is written in pure Ruby for
|
4
|
+
maximum portability. Let me rephrase: it does NOT require RMagick or any other
|
5
|
+
memory leaking image library.
|
6
|
+
|
7
|
+
- [Source code](http://github.com/wvanbergen/chunky_png/tree)
|
8
|
+
- [RDoc](http://rdoc.info/gems/chunky_png/frames)
|
9
|
+
- [Wiki](http://github.com/wvanbergen/chunky_png/wiki)
|
10
|
+
- [Issue tracker](http://github.com/wvanbergen/chunky_png/issues)
|
11
|
+
|
12
|
+
## Features
|
13
|
+
|
14
|
+
- Decodes any image that the PNG standard allows. This includes all standard
|
15
|
+
color modes, all bit depths, all transparency, and interlacing and filtering
|
16
|
+
options.
|
17
|
+
- Encodes images supports all color modes (true color, grayscale, and indexed)
|
18
|
+
and transparency for all these color modes. The best color mode will be
|
19
|
+
chosen automatically, based on the amount of used colors.
|
20
|
+
- R/W access to the image's pixels.
|
21
|
+
- R/W access to all image metadata that is stored in chunks.
|
22
|
+
- Memory efficient (uses a Fixnum, i.e. 4 or 8 bytes of memory per pixel,
|
23
|
+
depending on the hardware)
|
24
|
+
- Reasonably fast for Ruby standards, by only using integer math and a highly
|
25
|
+
optimized saving routine.
|
26
|
+
- Interoperability with RMagick if you really have to.
|
27
|
+
|
28
|
+
Also, have a look at [OilyPNG](http://github.com/wvanbergen/oily_png) which
|
29
|
+
is a mixin module that implements some of the ChunkyPNG algorithms in C, which
|
30
|
+
provides a massive speed boost to encoding and decoding.
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
require 'chunky_png'
|
36
|
+
|
37
|
+
# Creating an image from scratch, save as an interlaced PNG
|
38
|
+
png = ChunkyPNG::Image.new(16, 16, ChunkyPNG::Color::TRANSPARENT)
|
39
|
+
png[1,1] = ChunkyPNG::Color.rgba(10, 20, 30, 128)
|
40
|
+
png[2,1] = ChunkyPNG::Color('black @ 0.5')
|
41
|
+
png.save('filename.png', :interlace => true)
|
42
|
+
|
43
|
+
# Compose images using alpha blending.
|
44
|
+
avatar = ChunkyPNG::Image.from_file('avatar.png')
|
45
|
+
badge = ChunkyPNG::Image.from_file('no_ie_badge.png')
|
46
|
+
avatar.compose!(badge, 10, 10)
|
47
|
+
avatar.save('composited.png', :fast_rgba) # Force the fast saving routine.
|
48
|
+
|
49
|
+
# Accessing metadata
|
50
|
+
image = ChunkyPNG::Image.from_file('with_metadata.png')
|
51
|
+
puts image.metadata['Title']
|
52
|
+
image.metadata['Author'] = 'Willem van Bergen'
|
53
|
+
image.save('with_metadata.png') # Overwrite file
|
54
|
+
|
55
|
+
# Low level access to PNG chunks
|
56
|
+
png_stream = ChunkyPNG::Datastream.from_file('filename.png')
|
57
|
+
png_stream.each_chunk { |chunk| p chunk.type }
|
58
|
+
```
|
59
|
+
|
60
|
+
Also check out the screencast on the ChunkyPNG homepage by John Davison,
|
61
|
+
which illustrates basic usage of the library on the [ChunkyPNG
|
62
|
+
website](http://chunkypng.com/).
|
63
|
+
|
64
|
+
For more information, see the [project
|
65
|
+
wiki](https://github.com/wvanbergen/chunky_png/wiki) or the [RDOC
|
66
|
+
documentation](http://www.rubydoc.info/gems/chunky_png/frames).
|
67
|
+
|
68
|
+
## Security warning
|
69
|
+
|
70
|
+
ChunkyPNG is vulnerable to decompression bombs, which means that ChunkyPNG is
|
71
|
+
vulnerable to DOS attacks by running out of memory when loading a specifically
|
72
|
+
crafted PNG file. Because of the pure-Ruby nature of the library it is very hard
|
73
|
+
to fix this problem in the library itself.
|
74
|
+
|
75
|
+
In order to safely deal with untrusted images, you should make sure to do the
|
76
|
+
image processing using ChunkyPNG in a separate process, e.g. by using fork or a
|
77
|
+
background processing library.
|
78
|
+
|
79
|
+
## About
|
80
|
+
|
81
|
+
The library is written by Willem van Bergen for Floorplanner.com, and released
|
82
|
+
under the MIT license (see LICENSE). Please contact me for questions or
|
83
|
+
remarks. Patches are greatly appreciated!
|
84
|
+
|
85
|
+
Please check out CHANGELOG.rdoc to see what changed in all versions.
|
86
|
+
|
87
|
+
P.S.: The name of this library is intentionally similar to Chunky Bacon and
|
88
|
+
Chunky GIF. Use Google if you want to know _why_. :-)
|
@@ -4,7 +4,7 @@ require 'bundler/setup'
|
|
4
4
|
require 'benchmark'
|
5
5
|
require 'chunky_png'
|
6
6
|
|
7
|
-
files = ['pixelstream_reference.png', 'operations.png', '
|
7
|
+
files = ['pixelstream_reference.png', 'operations.png', 'clock.png']
|
8
8
|
|
9
9
|
def encode_png(image, constraints = {})
|
10
10
|
filesize = nil
|
data/chunky_png.gemspec
CHANGED
@@ -40,7 +40,7 @@ Gem::Specification.new do |s|
|
|
40
40
|
s.add_development_dependency('rspec', '~> 3')
|
41
41
|
|
42
42
|
s.rdoc_options << '--title' << s.name << '--main' << 'README.rdoc' << '--line-numbers' << '--inline-source'
|
43
|
-
s.extra_rdoc_files = ['README.
|
43
|
+
s.extra_rdoc_files = ['README.md', 'BENCHMARKING.rdoc', 'CONTRIBUTING.rdoc', 'CHANGELOG.rdoc']
|
44
44
|
|
45
45
|
s.files = `git ls-files`.split($/)
|
46
46
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
data/lib/chunky_png.rb
CHANGED
@@ -129,12 +129,12 @@ module ChunkyPNG
|
|
129
129
|
# set correctly to ASCII-8BIT (binary) in Ruby 1.9.
|
130
130
|
# @return [String] An empty string, with encoding set to binary in Ruby 1.9
|
131
131
|
# @private
|
132
|
-
EMPTY_BYTEARRAY = force_binary(
|
132
|
+
EMPTY_BYTEARRAY = force_binary(String.new).freeze
|
133
133
|
|
134
134
|
# Null-byte, with the encoding set correctly to ASCII-8BIT (binary) in Ruby 1.9.
|
135
135
|
# @return [String] A binary string, consisting of one NULL-byte.
|
136
136
|
# @private
|
137
|
-
EXTRA_BYTE = force_binary("\0").freeze
|
137
|
+
EXTRA_BYTE = force_binary(String.new("\0")).freeze
|
138
138
|
end
|
139
139
|
|
140
140
|
require 'chunky_png/version'
|
@@ -299,12 +299,12 @@ module ChunkyPNG
|
|
299
299
|
end
|
300
300
|
|
301
301
|
unless fill_color == ChunkyPNG::Color::TRANSPARENT
|
302
|
-
lines.each_with_index do |length,
|
302
|
+
lines.each_with_index do |length, y_offset|
|
303
303
|
if length > 0
|
304
|
-
line(x0 - length, y0 -
|
304
|
+
line(x0 - length, y0 - y_offset, x0 + length, y0 - y_offset, fill_color)
|
305
305
|
end
|
306
|
-
if length > 0 &&
|
307
|
-
line(x0 - length, y0 +
|
306
|
+
if length > 0 && y_offset > 0
|
307
|
+
line(x0 - length, y0 + y_offset, x0 + length, y0 + y_offset, fill_color)
|
308
308
|
end
|
309
309
|
end
|
310
310
|
end
|
@@ -273,7 +273,6 @@ module ChunkyPNG
|
|
273
273
|
# @return [ChunkyPNG::Canvas] Itself, but rotated clockwise.
|
274
274
|
# @see #rotate_right for a version that leaves the current canvas intact
|
275
275
|
def rotate_right!
|
276
|
-
rotated = self.class.new(height, width)
|
277
276
|
new_pixels = []
|
278
277
|
0.upto(width - 1) { |i| new_pixels += column(i).reverse }
|
279
278
|
replace_canvas!(height, width, new_pixels)
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module ChunkyPNG
|
2
2
|
class Canvas
|
3
3
|
|
4
|
-
# The PNGDecoding contains methods for decoding PNG datastreams to create a
|
5
|
-
# Canvas object. The datastream can be provided as filename, string or IO
|
4
|
+
# The PNGDecoding contains methods for decoding PNG datastreams to create a
|
5
|
+
# Canvas object. The datastream can be provided as filename, string or IO
|
6
6
|
# stream.
|
7
7
|
#
|
8
8
|
# Overview of the decoding process:
|
@@ -22,7 +22,7 @@ module ChunkyPNG
|
|
22
22
|
# * All lines combined to form the original image.
|
23
23
|
#
|
24
24
|
# For interlaced images, the original image was split into 7 subimages.
|
25
|
-
# These images get decoded just like the process above (from step 3), and get
|
25
|
+
# These images get decoded just like the process above (from step 3), and get
|
26
26
|
# combined to form the original images.
|
27
27
|
#
|
28
28
|
# @see ChunkyPNG::Canvas::PNGEncoding
|
@@ -33,7 +33,7 @@ module ChunkyPNG
|
|
33
33
|
# tRNS chunk from the PNG stream. For RGB(A) images, no palette is required.
|
34
34
|
# @return [ChunkyPNG::Palette]
|
35
35
|
attr_accessor :decoding_palette
|
36
|
-
|
36
|
+
|
37
37
|
# The color to be replaced with fully transparent pixels.
|
38
38
|
attr_accessor :transparent_color
|
39
39
|
|
@@ -84,11 +84,11 @@ module ChunkyPNG
|
|
84
84
|
when ChunkyPNG::COLOR_GRAYSCALE
|
85
85
|
self.transparent_color = ds.transparency_chunk.grayscale_entry(depth) if ds.transparency_chunk
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
decode_png_pixelstream(ds.imagedata, width, height, color_mode, depth, interlace)
|
89
89
|
end
|
90
90
|
|
91
|
-
# Decodes a canvas from a PNG encoded pixelstream, using a given width, height,
|
91
|
+
# Decodes a canvas from a PNG encoded pixelstream, using a given width, height,
|
92
92
|
# color mode and interlacing mode.
|
93
93
|
# @param [String] stream The pixelstream to read from.
|
94
94
|
# @param [Integer] width The width of the image.
|
@@ -105,14 +105,14 @@ module ChunkyPNG
|
|
105
105
|
when ChunkyPNG::INTERLACING_ADAM7; decode_png_with_adam7_interlacing(stream, width, height, color_mode, depth)
|
106
106
|
else raise ChunkyPNG::NotSupported, "Don't know how the handle interlacing method #{interlace}!"
|
107
107
|
end
|
108
|
-
|
108
|
+
|
109
109
|
image.pixels.map! { |c| c == transparent_color ? ChunkyPNG::Color::TRANSPARENT : c } if transparent_color
|
110
110
|
return image
|
111
111
|
end
|
112
112
|
|
113
113
|
protected
|
114
114
|
|
115
|
-
# Decodes a canvas from a non-interlaced PNG encoded pixelstream, using a
|
115
|
+
# Decodes a canvas from a non-interlaced PNG encoded pixelstream, using a
|
116
116
|
# given width, height and color mode.
|
117
117
|
# @param stream (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
118
118
|
# @param width (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
@@ -124,7 +124,7 @@ module ChunkyPNG
|
|
124
124
|
decode_png_image_pass(stream, width, height, color_mode, depth, 0)
|
125
125
|
end
|
126
126
|
|
127
|
-
# Decodes a canvas from a Adam 7 interlaced PNG encoded pixelstream, using a
|
127
|
+
# Decodes a canvas from a Adam 7 interlaced PNG encoded pixelstream, using a
|
128
128
|
# given width, height and color mode.
|
129
129
|
# @param stream (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
130
130
|
# @param width (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
@@ -143,19 +143,19 @@ module ChunkyPNG
|
|
143
143
|
end
|
144
144
|
canvas
|
145
145
|
end
|
146
|
-
|
146
|
+
|
147
147
|
# Extract 4 consecutive bits from a byte.
|
148
148
|
# @param [Integer] byte The byte (0..255) value to extract a 4 bit value from.
|
149
|
-
# @param [Integer] index The index within the byte. This should be either 0 or 2;
|
149
|
+
# @param [Integer] index The index within the byte. This should be either 0 or 2;
|
150
150
|
# the value will be modded by 2 to enforce this.
|
151
151
|
# @return [Integer] The extracted 4bit value (0..15)
|
152
152
|
def decode_png_extract_4bit_value(byte, index)
|
153
153
|
(index & 0x01 == 0) ? ((byte & 0xf0) >> 4) : (byte & 0x0f)
|
154
154
|
end
|
155
|
-
|
155
|
+
|
156
156
|
# Extract 2 consecutive bits from a byte.
|
157
157
|
# @param [Integer] byte The byte (0..255) value to extract a 2 bit value from.
|
158
|
-
# @param [Integer] index The index within the byte. This should be either 0, 1, 2, or 3;
|
158
|
+
# @param [Integer] index The index within the byte. This should be either 0, 1, 2, or 3;
|
159
159
|
# the value will be modded by 4 to enforce this.
|
160
160
|
# @return [Integer] The extracted 2 bit value (0..3)
|
161
161
|
def decode_png_extract_2bit_value(byte, index)
|
@@ -165,49 +165,49 @@ module ChunkyPNG
|
|
165
165
|
|
166
166
|
# Extract a bit from a byte on a given index.
|
167
167
|
# @param [Integer] byte The byte (0..255) value to extract a bit from.
|
168
|
-
# @param [Integer] index The index within the byte. This should be 0..7;
|
168
|
+
# @param [Integer] index The index within the byte. This should be 0..7;
|
169
169
|
# the value will be modded by 8 to enforce this.
|
170
170
|
# @return [Integer] Either 1 or 0.
|
171
171
|
def decode_png_extract_1bit_value(byte, index)
|
172
172
|
bitshift = 7 - (index & 0x07)
|
173
173
|
(byte & (0x01 << bitshift)) >> bitshift
|
174
174
|
end
|
175
|
-
|
175
|
+
|
176
176
|
# Resamples a 16 bit value to an 8 bit value. This will discard some color information.
|
177
177
|
# @param [Integer] value The 16 bit value to resample.
|
178
178
|
# @return [Integer] The 8 bit resampled value
|
179
179
|
def decode_png_resample_16bit_value(value)
|
180
180
|
value >> 8
|
181
181
|
end
|
182
|
-
|
182
|
+
|
183
183
|
# No-op - available for completeness sake only
|
184
184
|
# @param [Integer] value The 8 bit value to resample.
|
185
185
|
# @return [Integer] The 8 bit resampled value
|
186
186
|
def decode_png_resample_8bit_value(value)
|
187
187
|
value
|
188
188
|
end
|
189
|
-
|
189
|
+
|
190
190
|
# Resamples a 4 bit value to an 8 bit value.
|
191
191
|
# @param [Integer] value The 4 bit value to resample.
|
192
192
|
# @return [Integer] The 8 bit resampled value.
|
193
193
|
def decode_png_resample_4bit_value(value)
|
194
194
|
value << 4 | value
|
195
195
|
end
|
196
|
-
|
196
|
+
|
197
197
|
# Resamples a 2 bit value to an 8 bit value.
|
198
198
|
# @param [Integer] value The 2 bit value to resample.
|
199
199
|
# @return [Integer] The 8 bit resampled value.
|
200
200
|
def decode_png_resample_2bit_value(value)
|
201
201
|
value << 6 | value << 4 | value << 2 | value
|
202
202
|
end
|
203
|
-
|
203
|
+
|
204
204
|
# Resamples a 1 bit value to an 8 bit value.
|
205
205
|
# @param [Integer] value The 1 bit value to resample.
|
206
206
|
# @return [Integer] The 8 bit resampled value
|
207
207
|
def decode_png_resample_1bit_value(value)
|
208
208
|
value == 0x01 ? 0xff : 0x00
|
209
209
|
end
|
210
|
-
|
210
|
+
|
211
211
|
|
212
212
|
# Decodes a scanline of a 1-bit, indexed image into a row of pixels.
|
213
213
|
# @param [String] stream The stream to decode from.
|
@@ -216,7 +216,7 @@ module ChunkyPNG
|
|
216
216
|
# @return [Array<Integer>] An array of decoded pixels.
|
217
217
|
def decode_png_pixels_from_scanline_indexed_1bit(stream, pos, width)
|
218
218
|
(0...width).map do |index|
|
219
|
-
palette_pos = decode_png_extract_1bit_value(stream.getbyte(pos + 1 + (index >> 3)), index)
|
219
|
+
palette_pos = decode_png_extract_1bit_value(stream.getbyte(pos + 1 + (index >> 3)), index)
|
220
220
|
decoding_palette[palette_pos]
|
221
221
|
end
|
222
222
|
end
|
@@ -266,14 +266,14 @@ module ChunkyPNG
|
|
266
266
|
end
|
267
267
|
return pixels
|
268
268
|
end
|
269
|
-
|
269
|
+
|
270
270
|
# Decodes a scanline of an 8-bit, true color image into a row of pixels.
|
271
271
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
272
272
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
273
273
|
def decode_png_pixels_from_scanline_truecolor_8bit(stream, pos, width)
|
274
274
|
stream.unpack("@#{pos + 1}" << ('NX' * width)).map { |c| c | 0x000000ff }
|
275
275
|
end
|
276
|
-
|
276
|
+
|
277
277
|
# Decodes a scanline of a 16-bit, true color image into a row of pixels.
|
278
278
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
279
279
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
@@ -291,7 +291,7 @@ module ChunkyPNG
|
|
291
291
|
def decode_png_pixels_from_scanline_grayscale_alpha_8bit(stream, pos, width)
|
292
292
|
(0...width).map { |i| ChunkyPNG::Color.grayscale_alpha(stream.getbyte(pos + (i * 2) + 1), stream.getbyte(pos + (i * 2) + 2)) }
|
293
293
|
end
|
294
|
-
|
294
|
+
|
295
295
|
# Decodes a scanline of a 16-bit, grayscale image with transparency into a row of pixels.
|
296
296
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
297
297
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
@@ -332,14 +332,14 @@ module ChunkyPNG
|
|
332
332
|
ChunkyPNG::Color.grayscale(decode_png_resample_4bit_value(value))
|
333
333
|
end
|
334
334
|
end
|
335
|
-
|
335
|
+
|
336
336
|
# Decodes a scanline of an 8-bit, grayscale image into a row of pixels.
|
337
337
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
338
338
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
339
339
|
def decode_png_pixels_from_scanline_grayscale_8bit(stream, pos, width)
|
340
340
|
(1..width).map { |i| ChunkyPNG::Color.grayscale(stream.getbyte(pos + i)) }
|
341
341
|
end
|
342
|
-
|
342
|
+
|
343
343
|
# Decodes a scanline of a 16-bit, grayscale image into a row of pixels.
|
344
344
|
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
345
345
|
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
@@ -347,7 +347,7 @@ module ChunkyPNG
|
|
347
347
|
values = stream.unpack("@#{pos + 1}n#{width}")
|
348
348
|
values.map { |value| ChunkyPNG::Color.grayscale(decode_png_resample_16bit_value(value)) }
|
349
349
|
end
|
350
|
-
|
350
|
+
|
351
351
|
# Returns the method name to use to decode scanlines into pixels.
|
352
352
|
# @param [Integer] color_mode The color mode of the image.
|
353
353
|
# @param [Integer] depth The bit depth of the image.
|
@@ -362,12 +362,12 @@ module ChunkyPNG
|
|
362
362
|
when ChunkyPNG::COLOR_GRAYSCALE_ALPHA; :"decode_png_pixels_from_scanline_grayscale_alpha_#{depth}bit"
|
363
363
|
else nil
|
364
364
|
end
|
365
|
-
|
365
|
+
|
366
366
|
raise ChunkyPNG::NotSupported, "No decoder found for color mode #{color_mode} and #{depth}-bit depth!" unless respond_to?(decoder_method, true)
|
367
367
|
decoder_method
|
368
368
|
end
|
369
369
|
|
370
|
-
# Decodes a single PNG image pass width a given width, height and color
|
370
|
+
# Decodes a single PNG image pass width a given width, height and color
|
371
371
|
# mode, to a Canvas, starting at the given position in the stream.
|
372
372
|
#
|
373
373
|
# A non-interlaced image only consists of one pass, while an Adam7
|
@@ -380,21 +380,21 @@ module ChunkyPNG
|
|
380
380
|
# @param [Integer] start_pos The position in the pixel stream to start reading.
|
381
381
|
# @return (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
382
382
|
def decode_png_image_pass(stream, width, height, color_mode, depth, start_pos)
|
383
|
-
|
383
|
+
|
384
384
|
pixels = []
|
385
385
|
if width > 0 && height > 0
|
386
|
-
|
386
|
+
|
387
387
|
stream << ChunkyPNG::EXTRA_BYTE if color_mode == ChunkyPNG::COLOR_TRUECOLOR
|
388
388
|
pixel_decoder = decode_png_pixels_from_scanline_method(color_mode, depth)
|
389
389
|
line_length = ChunkyPNG::Color.scanline_bytesize(color_mode, depth, width)
|
390
390
|
pixel_size = ChunkyPNG::Color.pixel_bytesize(color_mode, depth)
|
391
|
-
|
391
|
+
|
392
392
|
raise ChunkyPNG::ExpectationFailed, "Invalid stream length!" unless stream.bytesize - start_pos >= ChunkyPNG::Color.pass_bytesize(color_mode, depth, width, height)
|
393
393
|
|
394
394
|
pos, prev_pos = start_pos, nil
|
395
|
-
for
|
395
|
+
for _ in 0...height do
|
396
396
|
decode_png_str_scanline(stream, pos, prev_pos, line_length, pixel_size)
|
397
|
-
pixels
|
397
|
+
pixels.concat(send(pixel_decoder, stream, pos, width))
|
398
398
|
|
399
399
|
prev_pos = pos
|
400
400
|
pos += line_length + 1
|
@@ -404,9 +404,9 @@ module ChunkyPNG
|
|
404
404
|
new(width, height, pixels)
|
405
405
|
end
|
406
406
|
|
407
|
-
# Decodes a scanline if it was encoded using filtering.
|
407
|
+
# Decodes a scanline if it was encoded using filtering.
|
408
408
|
#
|
409
|
-
# It will extract the filtering method from the first byte of the scanline, and uses the
|
409
|
+
# It will extract the filtering method from the first byte of the scanline, and uses the
|
410
410
|
# method to change the subsequent bytes to unfiltered values. This will modify the pixelstream.
|
411
411
|
#
|
412
412
|
# The bytes of the scanline can then be used to construct pixels, based on the color mode..
|
data/lib/chunky_png/color.rb
CHANGED
@@ -589,7 +589,7 @@ module ChunkyPNG
|
|
589
589
|
# include_alpha=true (0-255)
|
590
590
|
# @see http://en.wikipedia.org/wiki/HSL_and_HSV
|
591
591
|
def to_hsv(color, include_alpha = false)
|
592
|
-
hue, chroma, max,
|
592
|
+
hue, chroma, max, _ = hue_and_chroma(color)
|
593
593
|
value = max
|
594
594
|
saturation = chroma.zero? ? 0.0 : chroma.fdiv(value)
|
595
595
|
|
data/lib/chunky_png/version.rb
CHANGED
@@ -17,6 +17,12 @@ describe ChunkyPNG::Datastream do
|
|
17
17
|
stream = StringIO.new
|
18
18
|
expect { ChunkyPNG::Datastream.from_io(stream) }.to raise_error(ChunkyPNG::SignatureMismatch)
|
19
19
|
end
|
20
|
+
|
21
|
+
it "should read a stream with trailing data without failing" do
|
22
|
+
filename = resource_file('trailing_bytes_after_iend_chunk.png')
|
23
|
+
image = ChunkyPNG::Datastream.from_file(filename)
|
24
|
+
expect(image).to be_instance_of(ChunkyPNG::Datastream)
|
25
|
+
end
|
20
26
|
end
|
21
27
|
|
22
28
|
describe '#metadata' do
|
Binary file
|
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.6
|
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:
|
11
|
+
date: 2016-06-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -60,7 +60,7 @@ email:
|
|
60
60
|
executables: []
|
61
61
|
extensions: []
|
62
62
|
extra_rdoc_files:
|
63
|
-
- README.
|
63
|
+
- README.md
|
64
64
|
- BENCHMARKING.rdoc
|
65
65
|
- CONTRIBUTING.rdoc
|
66
66
|
- CHANGELOG.rdoc
|
@@ -73,7 +73,7 @@ files:
|
|
73
73
|
- CONTRIBUTING.rdoc
|
74
74
|
- Gemfile
|
75
75
|
- LICENSE
|
76
|
-
- README.
|
76
|
+
- README.md
|
77
77
|
- Rakefile
|
78
78
|
- benchmarks/decoding_benchmark.rb
|
79
79
|
- benchmarks/encoding_benchmark.rb
|
@@ -384,6 +384,7 @@ files:
|
|
384
384
|
- spec/resources/rect.png
|
385
385
|
- spec/resources/replaced.png
|
386
386
|
- spec/resources/text_chunk.png
|
387
|
+
- spec/resources/trailing_bytes_after_iend_chunk.png
|
387
388
|
- spec/resources/ztxt_chunk.png
|
388
389
|
- spec/spec_helper.rb
|
389
390
|
- tasks/benchmarks.rake
|
@@ -413,7 +414,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
413
414
|
version: '0'
|
414
415
|
requirements: []
|
415
416
|
rubyforge_project:
|
416
|
-
rubygems_version: 2.0.14
|
417
|
+
rubygems_version: 2.0.14.1
|
417
418
|
signing_key:
|
418
419
|
specification_version: 4
|
419
420
|
summary: Pure ruby library for read/write, chunk-level access to PNG files
|
@@ -699,5 +700,6 @@ test_files:
|
|
699
700
|
- spec/resources/rect.png
|
700
701
|
- spec/resources/replaced.png
|
701
702
|
- spec/resources/text_chunk.png
|
703
|
+
- spec/resources/trailing_bytes_after_iend_chunk.png
|
702
704
|
- spec/resources/ztxt_chunk.png
|
703
705
|
- spec/spec_helper.rb
|
data/README.rdoc
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
= Chunky PNG {<img src="https://travis-ci.org/wvanbergen/chunky_png.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/wvanbergen/chunky_png]
|
2
|
-
|
3
|
-
This library can read and write PNG files. It is written in pure Ruby for
|
4
|
-
maximum portability. Let me rephrase: it does NOT require RMagick or any other
|
5
|
-
memory leaking image library.
|
6
|
-
|
7
|
-
Source code:: http://github.com/wvanbergen/chunky_png/tree
|
8
|
-
RDoc:: http://rdoc.info/gems/chunky_png/frames
|
9
|
-
Wiki:: http://github.com/wvanbergen/chunky_png/wiki
|
10
|
-
Issue tracker:: http://github.com/wvanbergen/chunky_png/issues
|
11
|
-
|
12
|
-
== Features
|
13
|
-
|
14
|
-
* Decodes any image that the PNG standard allows. This includes all standard
|
15
|
-
color modes, all bit depths and all transparency, interlacing and filtering options.
|
16
|
-
* Encodes images supports all color modes (true color, grayscale and indexed)
|
17
|
-
and transparency for all these color modes. The best color mode will be
|
18
|
-
chosen automatically, based on the amount of used colors.
|
19
|
-
* R/W access to the image's pixels.
|
20
|
-
* R/W access to all image metadata that is stored in chunks.
|
21
|
-
* Memory efficient (uses a Fixnum, i.e. 4 or 8 bytes of memory per pixel, depending
|
22
|
-
on the hardware)
|
23
|
-
* Reasonably fast for Ruby standards, by only using integer math and a highly
|
24
|
-
optimized saving routine.
|
25
|
-
* Interoperability with RMagick if you really have to.
|
26
|
-
|
27
|
-
Also, have a look at OilyPNG at http://github.com/wvanbergen/oily_png. OilyPNG is a
|
28
|
-
mixin module that implements some of the ChunkyPNG algorithms in C, which
|
29
|
-
provides a massive speed boost to encoding and decoding.
|
30
|
-
|
31
|
-
== Usage
|
32
|
-
|
33
|
-
require 'chunky_png'
|
34
|
-
|
35
|
-
# Creating an image from scratch, save as an interlaced PNG
|
36
|
-
png = ChunkyPNG::Image.new(16, 16, ChunkyPNG::Color::TRANSPARENT)
|
37
|
-
png[1,1] = ChunkyPNG::Color.rgba(10, 20, 30, 128)
|
38
|
-
png[2,1] = ChunkyPNG::Color('black @ 0.5')
|
39
|
-
png.save('filename.png', :interlace => true)
|
40
|
-
|
41
|
-
# Compose images using alpha blending.
|
42
|
-
avatar = ChunkyPNG::Image.from_file('avatar.png')
|
43
|
-
badge = ChunkyPNG::Image.from_file('no_ie_badge.png')
|
44
|
-
avatar.compose!(badge, 10, 10)
|
45
|
-
avatar.save('composited.png', :fast_rgba) # Force the fast saving routine.
|
46
|
-
|
47
|
-
# Accessing metadata
|
48
|
-
image = ChunkyPNG::Image.from_file('with_metadata.png')
|
49
|
-
puts image.metadata['Title']
|
50
|
-
image.metadata['Author'] = 'Willem van Bergen'
|
51
|
-
image.save('with_metadata.png') # Overwrite file
|
52
|
-
|
53
|
-
# Low level access to PNG chunks
|
54
|
-
png_stream = ChunkyPNG::Datastream.from_file('filename.png')
|
55
|
-
png_stream.each_chunk { |chunk| p chunk.type }
|
56
|
-
|
57
|
-
Also check out the screencast on the ChunkyPNG homepage by John Davison,
|
58
|
-
which illustrates basic usage of the library on the ChunkyPNG website:
|
59
|
-
http://chunkypng.com/
|
60
|
-
|
61
|
-
For more information, see the project wiki on https://github.com/wvanbergen/chunky_png/wiki
|
62
|
-
or the RDOC documentation on http://www.rubydoc.info/gems/chunky_png/frames
|
63
|
-
|
64
|
-
== Security warning
|
65
|
-
|
66
|
-
ChunkyPNG is vulnerable to decompression bombs, which means that ChunkyPNG is vulnerable to
|
67
|
-
DOS attacks by running out of memory when loading a specifically crafted PNG file. Because
|
68
|
-
of the pure-Ruby nature of the library it is very hard to fix this problem in the library
|
69
|
-
itself.
|
70
|
-
|
71
|
-
In order to safely deal with untrusted images, you should make sure to do the image
|
72
|
-
processing using ChunkyPNG in a separate process, e.g. by using fork or a background
|
73
|
-
processing library.
|
74
|
-
|
75
|
-
== About
|
76
|
-
|
77
|
-
The library is written by Willem van Bergen for Floorplanner.com, and released
|
78
|
-
under the MIT license (see LICENSE). Please contact me for questions or
|
79
|
-
remarks. Patches are greatly appreciated!
|
80
|
-
|
81
|
-
Please check out CHANGELOG.rdoc to see what changed in all versions.
|
82
|
-
|
83
|
-
P.S.: The name of this library is intentionally similar to Chunky Bacon and
|
84
|
-
Chunky GIF. Use Google if you want to know _why. :-)
|