chunky_png 1.3.5 → 1.3.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +35 -0
- data/.standard.yml +16 -0
- data/.yardopts +1 -1
- data/CHANGELOG.rdoc +38 -4
- data/CONTRIBUTING.rdoc +17 -8
- data/Gemfile +12 -4
- data/LICENSE +1 -1
- data/README.md +94 -0
- data/Rakefile +5 -3
- data/benchmarks/decoding_benchmark.rb +17 -17
- data/benchmarks/encoding_benchmark.rb +22 -19
- data/benchmarks/filesize_benchmark.rb +6 -6
- data/bin/rake +29 -0
- data/bin/standardrb +29 -0
- data/chunky_png.gemspec +21 -13
- data/docs/.gitignore +3 -0
- data/docs/CNAME +1 -0
- data/docs/_config.yml +9 -0
- data/docs/_posts/2010-01-14-memory-efficiency-when-using-ruby.md +136 -0
- data/docs/_posts/2010-01-17-ode-to-array-pack-and-string-unpack.md +82 -0
- data/docs/_posts/2014-11-07-the-value-of-a-pure-ruby-library.md +61 -0
- data/{README.rdoc → docs/index.md} +28 -24
- data/lib/chunky_png/canvas/adam7_interlacing.rb +16 -10
- data/lib/chunky_png/canvas/data_url_exporting.rb +3 -3
- data/lib/chunky_png/canvas/data_url_importing.rb +3 -3
- data/lib/chunky_png/canvas/drawing.rb +34 -47
- data/lib/chunky_png/canvas/masking.rb +14 -14
- data/lib/chunky_png/canvas/operations.rb +28 -25
- data/lib/chunky_png/canvas/png_decoding.rb +104 -99
- data/lib/chunky_png/canvas/png_encoding.rb +111 -103
- data/lib/chunky_png/canvas/resampling.rb +27 -32
- data/lib/chunky_png/canvas/stream_exporting.rb +8 -8
- data/lib/chunky_png/canvas/stream_importing.rb +8 -8
- data/lib/chunky_png/canvas.rb +31 -28
- data/lib/chunky_png/chunk.rb +170 -55
- data/lib/chunky_png/color.rb +221 -213
- data/lib/chunky_png/datastream.rb +30 -30
- data/lib/chunky_png/dimension.rb +18 -11
- data/lib/chunky_png/image.rb +11 -11
- data/lib/chunky_png/palette.rb +13 -14
- data/lib/chunky_png/point.rb +27 -26
- data/lib/chunky_png/rmagick.rb +10 -10
- data/lib/chunky_png/vector.rb +28 -29
- data/lib/chunky_png/version.rb +3 -1
- data/lib/chunky_png.rb +49 -43
- data/spec/chunky_png/canvas/adam7_interlacing_spec.rb +20 -21
- data/spec/chunky_png/canvas/data_url_exporting_spec.rb +8 -5
- data/spec/chunky_png/canvas/data_url_importing_spec.rb +5 -6
- data/spec/chunky_png/canvas/drawing_spec.rb +46 -38
- data/spec/chunky_png/canvas/masking_spec.rb +15 -16
- data/spec/chunky_png/canvas/operations_spec.rb +68 -67
- data/spec/chunky_png/canvas/png_decoding_spec.rb +37 -38
- data/spec/chunky_png/canvas/png_encoding_spec.rb +59 -50
- data/spec/chunky_png/canvas/resampling_spec.rb +19 -21
- data/spec/chunky_png/canvas/stream_exporting_spec.rb +47 -27
- data/spec/chunky_png/canvas/stream_importing_spec.rb +10 -11
- data/spec/chunky_png/canvas_spec.rb +63 -52
- data/spec/chunky_png/color_spec.rb +115 -114
- data/spec/chunky_png/datastream_spec.rb +115 -12
- data/spec/chunky_png/dimension_spec.rb +10 -10
- data/spec/chunky_png/image_spec.rb +11 -14
- data/spec/chunky_png/point_spec.rb +21 -23
- data/spec/chunky_png/rmagick_spec.rb +7 -8
- data/spec/chunky_png/vector_spec.rb +21 -17
- data/spec/chunky_png_spec.rb +2 -2
- data/spec/png_suite_spec.rb +35 -40
- data/spec/resources/itxt_chunk.png +0 -0
- data/spec/resources/trailing_bytes_after_iend_chunk.png +0 -0
- data/spec/spec_helper.rb +15 -9
- data/tasks/benchmarks.rake +7 -8
- metadata +69 -27
- data/.travis.yml +0 -16
- data/lib/chunky_png/compatibility.rb +0 -15
data/lib/chunky_png/vector.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
|
1
|
+
# frozen-string-literal: true
|
2
2
|
|
3
|
+
module ChunkyPNG
|
3
4
|
# Factory method for {ChunkyPNG::Vector} instances.
|
4
5
|
#
|
5
6
|
# @overload Vector(x0, y0, x1, y1, x2, y2, ...)
|
6
|
-
# Creates a vector by parsing two subsequent values in the argument list
|
7
|
+
# Creates a vector by parsing two subsequent values in the argument list
|
7
8
|
# as x- and y-coordinate of a point.
|
8
9
|
# @return [ChunkyPNG::Vector] The instantiated vector.
|
9
10
|
# @overload Vector(string)
|
@@ -17,27 +18,25 @@ module ChunkyPNG
|
|
17
18
|
# @raise [ArgumentError] If the given arguments could not be understood as a vector.
|
18
19
|
# @see ChunkyPNG::Vector
|
19
20
|
def self.Vector(*args)
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
return args.first if args.length == 1 && args.first.is_a?(ChunkyPNG::Vector)
|
22
|
+
|
23
23
|
if args.length == 1 && args.first.respond_to?(:scan)
|
24
24
|
ChunkyPNG::Vector.new(ChunkyPNG::Vector.multiple_from_string(args.first)) # e.g. ['1,1 2,2 3,3']
|
25
25
|
else
|
26
26
|
ChunkyPNG::Vector.new(ChunkyPNG::Vector.multiple_from_array(args)) # e.g. [[1,1], [2,2], [3,3]] or [1,1,2,2,3,3]
|
27
27
|
end
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
# Class that represents a vector of points, i.e. a list of {ChunkyPNG::Point} instances.
|
31
31
|
#
|
32
|
-
# Vectors can be created quite flexibly. See the {ChunkyPNG.Vector} factory methods for
|
32
|
+
# Vectors can be created quite flexibly. See the {ChunkyPNG.Vector} factory methods for
|
33
33
|
# more information on how to construct vectors.
|
34
34
|
class Vector
|
35
|
-
|
36
35
|
include Enumerable
|
37
|
-
|
36
|
+
|
38
37
|
# @return [Array<ChunkyPNG::Point>] The array that holds all the points in this vector.
|
39
38
|
attr_reader :points
|
40
|
-
|
39
|
+
|
41
40
|
# Initializes a vector based on a list of Point instances.
|
42
41
|
#
|
43
42
|
# You usually do not want to use this method directly, but call {ChunkyPNG.Vector} instead.
|
@@ -47,7 +46,7 @@ module ChunkyPNG
|
|
47
46
|
def initialize(points = [])
|
48
47
|
@points = points
|
49
48
|
end
|
50
|
-
|
49
|
+
|
51
50
|
# Iterates over all the edges in this vector.
|
52
51
|
#
|
53
52
|
# An edge is a combination of two subsequent points in the vector. Together, they will form
|
@@ -63,14 +62,14 @@ module ChunkyPNG
|
|
63
62
|
points.each_cons(2) { |a, b| yield(a, b) }
|
64
63
|
yield(points.last, points.first) if close
|
65
64
|
end
|
66
|
-
|
65
|
+
|
67
66
|
# Returns the point with the given indexof this vector.
|
68
67
|
# @param [Integer] index The 0-based index of the point in this vector.
|
69
|
-
# @
|
68
|
+
# @return [ChunkyPNG::Point] The point instance.
|
70
69
|
def [](index)
|
71
70
|
points[index]
|
72
71
|
end
|
73
|
-
|
72
|
+
|
74
73
|
# Returns an enumerator that will iterate over all the edges in this vector.
|
75
74
|
# @param (see #each_edge)
|
76
75
|
# @return [Enumerator] The enumerator that iterates over the edges.
|
@@ -79,28 +78,28 @@ module ChunkyPNG
|
|
79
78
|
def edges(close = true)
|
80
79
|
to_enum(:each_edge, close)
|
81
80
|
end
|
82
|
-
|
81
|
+
|
83
82
|
# Returns the number of points in this vector.
|
84
83
|
# @return [Integer] The length of the points array.
|
85
84
|
def length
|
86
85
|
points.length
|
87
86
|
end
|
88
|
-
|
87
|
+
|
89
88
|
# Iterates over all the points in this vector
|
90
89
|
# @yield [ChunkyPNG::Point] The points in the correct order.
|
91
90
|
# @return [void]
|
92
91
|
def each(&block)
|
93
92
|
points.each(&block)
|
94
93
|
end
|
95
|
-
|
94
|
+
|
96
95
|
# Comparison between two vectors for quality.
|
97
96
|
# @param [ChunkyPNG::Vector] other The vector to compare with.
|
98
97
|
# @return [true, false] true if the list of points are identical
|
99
98
|
def eql?(other)
|
100
99
|
other.points == points
|
101
100
|
end
|
102
|
-
|
103
|
-
|
101
|
+
|
102
|
+
alias == eql?
|
104
103
|
|
105
104
|
# Returns the range in x-coordinates for all the points in this vector.
|
106
105
|
# @return [Range] The (inclusive) range of x-coordinates.
|
@@ -113,13 +112,13 @@ module ChunkyPNG
|
|
113
112
|
def y_range
|
114
113
|
Range.new(*points.map { |p| p.y }.minmax)
|
115
114
|
end
|
116
|
-
|
115
|
+
|
117
116
|
# Finds the lowest x-coordinate in this vector.
|
118
117
|
# @return [Integer] The lowest x-coordinate of all the points in the vector.
|
119
118
|
def min_x
|
120
119
|
x_range.first
|
121
120
|
end
|
122
|
-
|
121
|
+
|
123
122
|
# Finds the highest x-coordinate in this vector.
|
124
123
|
# @return [Integer] The highest x-coordinate of all the points in the vector.
|
125
124
|
def max_x
|
@@ -131,13 +130,13 @@ module ChunkyPNG
|
|
131
130
|
def min_y
|
132
131
|
y_range.first
|
133
132
|
end
|
134
|
-
|
133
|
+
|
135
134
|
# Finds the highest y-coordinate in this vector.
|
136
135
|
# @return [Integer] The highest y-coordinate of all the points in the vector.
|
137
136
|
def max_y
|
138
137
|
y_range.last
|
139
138
|
end
|
140
|
-
|
139
|
+
|
141
140
|
# Returns the offset from (0,0) of the minimal bounding box of all the
|
142
141
|
# points in this vector
|
143
142
|
# @return [ChunkyPNG::Point] A point that describes the top left corner if a
|
@@ -145,7 +144,7 @@ module ChunkyPNG
|
|
145
144
|
def offset
|
146
145
|
ChunkyPNG::Point.new(min_x, min_y)
|
147
146
|
end
|
148
|
-
|
147
|
+
|
149
148
|
# Returns the width of the minimal bounding box of all the points in this vector.
|
150
149
|
# @return [Integer] The x-distance between the points that are farthest from each other.
|
151
150
|
def width
|
@@ -157,17 +156,17 @@ module ChunkyPNG
|
|
157
156
|
def height
|
158
157
|
1 + (max_y - min_y)
|
159
158
|
end
|
160
|
-
|
159
|
+
|
161
160
|
# Returns the dimension of the minimal bounding rectangle of the points in this vector.
|
162
|
-
# @return [ChunkyPNG::Dimension] The dimension instance with the width and height
|
161
|
+
# @return [ChunkyPNG::Dimension] The dimension instance with the width and height
|
163
162
|
def dimension
|
164
163
|
ChunkyPNG::Dimension.new(width, height)
|
165
164
|
end
|
166
|
-
|
165
|
+
|
167
166
|
# @return [Array<ChunkyPNG::Point>] The list of points interpreted from the input array.
|
168
167
|
def self.multiple_from_array(source)
|
169
168
|
return [] if source.empty?
|
170
|
-
if source.first.
|
169
|
+
if source.first.is_a?(Numeric) || source.first =~ /^\d+$/
|
171
170
|
raise ArgumentError, "The points array is expected to have an even number of items!" if source.length % 2 != 0
|
172
171
|
|
173
172
|
points = []
|
@@ -177,7 +176,7 @@ module ChunkyPNG
|
|
177
176
|
source.map { |p| ChunkyPNG::Point(p) }
|
178
177
|
end
|
179
178
|
end
|
180
|
-
|
179
|
+
|
181
180
|
# @return [Array<ChunkyPNG::Point>] The list of points parsed from the string.
|
182
181
|
def self.multiple_from_string(source_str)
|
183
182
|
multiple_from_array(source_str.scan(/[\(\[\{]?(\d+)\s*[,x]?\s*(\d+)[\)\]\}]?/))
|
data/lib/chunky_png/version.rb
CHANGED
data/lib/chunky_png.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
1
3
|
# Basic requirements from standard library
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require 'enumerator'
|
4
|
+
require "set"
|
5
|
+
require "zlib"
|
6
|
+
require "stringio"
|
6
7
|
|
7
8
|
# ChunkyPNG - the pure ruby library to access PNG files.
|
8
9
|
#
|
9
10
|
# The ChunkyPNG module defines some constants that are used in the
|
10
|
-
# PNG specification, specifies some exception classes, and serves as
|
11
|
+
# PNG specification, specifies some exception classes, and serves as
|
11
12
|
# a namespace for all the other modules and classes in this library.
|
12
13
|
#
|
13
14
|
# {ChunkyPNG::Image}:: class to represent PNG images, including metadata.
|
@@ -22,32 +23,31 @@ require 'enumerator'
|
|
22
23
|
#
|
23
24
|
# @author Willem van Bergen
|
24
25
|
module ChunkyPNG
|
25
|
-
|
26
26
|
###################################################
|
27
27
|
# PNG international standard defined constants
|
28
28
|
###################################################
|
29
29
|
|
30
|
-
# Indicates that the PNG image uses grayscale colors, i.e. only a
|
30
|
+
# Indicates that the PNG image uses grayscale colors, i.e. only a
|
31
31
|
# single teint channel.
|
32
32
|
# @private
|
33
33
|
COLOR_GRAYSCALE = 0
|
34
|
-
|
34
|
+
|
35
35
|
# Indicates that the PNG image uses true color, composed of a red
|
36
36
|
# green and blue channel.
|
37
37
|
# @private
|
38
38
|
COLOR_TRUECOLOR = 2
|
39
|
-
|
39
|
+
|
40
40
|
# Indicates that the PNG image uses indexed colors, where the values
|
41
41
|
# point to colors defined on a palette.
|
42
42
|
# @private
|
43
43
|
COLOR_INDEXED = 3
|
44
|
-
|
44
|
+
|
45
45
|
# Indicates that the PNG image uses grayscale colors with opacity, i.e.
|
46
46
|
# a teint channel with an alpha channel.
|
47
47
|
# @private
|
48
48
|
COLOR_GRAYSCALE_ALPHA = 4
|
49
|
-
|
50
|
-
# Indicates that the PNG image uses true color with opacity, composed of
|
49
|
+
|
50
|
+
# Indicates that the PNG image uses true color with opacity, composed of
|
51
51
|
# a red, green and blue channel, and an alpha value.
|
52
52
|
# @private
|
53
53
|
COLOR_TRUECOLOR_ALPHA = 6
|
@@ -57,12 +57,22 @@ module ChunkyPNG
|
|
57
57
|
# @private
|
58
58
|
COMPRESSION_DEFAULT = 0
|
59
59
|
|
60
|
+
# Indicates that the PNG chunk content is not compressed
|
61
|
+
# flag used in iTXt chunk
|
62
|
+
# @private
|
63
|
+
UNCOMPRESSED_CONTENT = 0
|
64
|
+
|
65
|
+
# Indicates that the PNG chunk content is compressed
|
66
|
+
# flag used in iTXt chunk
|
67
|
+
# @private
|
68
|
+
COMPRESSED_CONTENT = 1
|
69
|
+
|
60
70
|
# Indicates that the image does not use interlacing.
|
61
71
|
# @private
|
62
72
|
INTERLACING_NONE = 0
|
63
|
-
|
73
|
+
|
64
74
|
# Indicates that the image uses Adam7 interlacing.
|
65
|
-
# @private
|
75
|
+
# @private
|
66
76
|
INTERLACING_ADAM7 = 1
|
67
77
|
|
68
78
|
### Filter method constants
|
@@ -75,19 +85,19 @@ module ChunkyPNG
|
|
75
85
|
# Indicates that no filtering is used for the scanline.
|
76
86
|
# @private
|
77
87
|
FILTER_NONE = 0
|
78
|
-
|
88
|
+
|
79
89
|
# Indicates that SUB filtering is used for the scanline.
|
80
90
|
# @private
|
81
91
|
FILTER_SUB = 1
|
82
|
-
|
92
|
+
|
83
93
|
# Indicates that UP filtering is used for the scanline.
|
84
94
|
# @private
|
85
95
|
FILTER_UP = 2
|
86
|
-
|
96
|
+
|
87
97
|
# Indicates that AVERAGE filtering is used for the scanline.
|
88
98
|
# @private
|
89
99
|
FILTER_AVERAGE = 3
|
90
|
-
|
100
|
+
|
91
101
|
# Indicates that PAETH filtering is used for the scanline.
|
92
102
|
# @private
|
93
103
|
FILTER_PAETH = 4
|
@@ -104,7 +114,7 @@ module ChunkyPNG
|
|
104
114
|
class NotSupported < ChunkyPNG::Exception
|
105
115
|
end
|
106
116
|
|
107
|
-
# Exception that is raised if the PNG signature is not encountered at the
|
117
|
+
# Exception that is raised if the PNG signature is not encountered at the
|
108
118
|
# beginning of the file.
|
109
119
|
class SignatureMismatch < ChunkyPNG::Exception
|
110
120
|
end
|
@@ -113,48 +123,44 @@ module ChunkyPNG
|
|
113
123
|
class CRCMismatch < ChunkyPNG::Exception
|
114
124
|
end
|
115
125
|
|
126
|
+
# Exception that is raised if an tTXt chunk does not contain valid UTF-8 data.
|
127
|
+
class InvalidUTF8 < ChunkyPNG::Exception
|
128
|
+
end
|
129
|
+
|
116
130
|
# Exception that is raised if an expectation fails.
|
117
131
|
class ExpectationFailed < ChunkyPNG::Exception
|
118
132
|
end
|
119
133
|
|
120
|
-
# Exception that
|
134
|
+
# Exception that when provided coordinates are out of bounds for the canvas
|
121
135
|
class OutOfBounds < ChunkyPNG::ExpectationFailed
|
122
136
|
end
|
123
137
|
|
124
|
-
|
125
|
-
|
138
|
+
# Exception that is raised when requesting the DPI of a PNG that doesn't
|
139
|
+
# specify the units of its physical pixel dimensions.
|
140
|
+
class UnitsUnknown < ChunkyPNG::Exception
|
126
141
|
end
|
127
|
-
|
128
|
-
# Empty byte array. This basically is an empty string, but with the encoding
|
129
|
-
# set correctly to ASCII-8BIT (binary) in Ruby 1.9.
|
130
|
-
# @return [String] An empty string, with encoding set to binary in Ruby 1.9
|
131
|
-
# @private
|
132
|
-
EMPTY_BYTEARRAY = force_binary("").freeze
|
133
142
|
|
134
143
|
# Null-byte, with the encoding set correctly to ASCII-8BIT (binary) in Ruby 1.9.
|
135
|
-
# @return [String] A binary string, consisting of one NULL-byte.
|
144
|
+
# @return [String] A binary string, consisting of one NULL-byte.
|
136
145
|
# @private
|
137
|
-
EXTRA_BYTE =
|
146
|
+
EXTRA_BYTE = "\0".b
|
138
147
|
end
|
139
148
|
|
140
|
-
require
|
141
|
-
|
142
|
-
# Ruby 1.8 / 1.9 compatibility
|
143
|
-
require 'chunky_png/compatibility'
|
149
|
+
require "chunky_png/version"
|
144
150
|
|
145
151
|
# PNG file structure
|
146
|
-
require
|
147
|
-
require
|
152
|
+
require "chunky_png/datastream"
|
153
|
+
require "chunky_png/chunk"
|
148
154
|
|
149
155
|
# Colors
|
150
|
-
require
|
151
|
-
require
|
156
|
+
require "chunky_png/palette"
|
157
|
+
require "chunky_png/color"
|
152
158
|
|
153
159
|
# Geometry
|
154
|
-
require
|
155
|
-
require
|
156
|
-
require
|
160
|
+
require "chunky_png/point"
|
161
|
+
require "chunky_png/vector"
|
162
|
+
require "chunky_png/dimension"
|
157
163
|
|
158
164
|
# Canvas / Image classes
|
159
|
-
require
|
160
|
-
require
|
165
|
+
require "chunky_png/canvas"
|
166
|
+
require "chunky_png/image"
|
@@ -1,48 +1,48 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe ChunkyPNG::Canvas::Adam7Interlacing do
|
4
4
|
include ChunkyPNG::Canvas::Adam7Interlacing
|
5
5
|
|
6
|
-
describe
|
6
|
+
describe "#adam7_pass_sizes" do
|
7
7
|
it "should get the pass sizes for a 8x8 image correctly" do
|
8
8
|
expect(adam7_pass_sizes(8, 8)).to eql [
|
9
|
-
|
10
|
-
|
9
|
+
[1, 1], [1, 1], [2, 1], [2, 2], [4, 2], [4, 4], [8, 4],
|
10
|
+
]
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should get the pass sizes for a 12x12 image correctly" do
|
14
14
|
expect(adam7_pass_sizes(12, 12)).to eql [
|
15
|
-
|
16
|
-
|
15
|
+
[2, 2], [1, 2], [3, 1], [3, 3], [6, 3], [6, 6], [12, 6],
|
16
|
+
]
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should get the pass sizes for a 33x47 image correctly" do
|
20
20
|
expect(adam7_pass_sizes(33, 47)).to eql [
|
21
|
-
|
22
|
-
|
21
|
+
[5, 6], [4, 6], [9, 6], [8, 12], [17, 12], [16, 24], [33, 23],
|
22
|
+
]
|
23
23
|
end
|
24
24
|
|
25
25
|
it "should get the pass sizes for a 1x1 image correctly" do
|
26
26
|
expect(adam7_pass_sizes(1, 1)).to eql [
|
27
|
-
|
28
|
-
|
27
|
+
[1, 1], [0, 1], [1, 0], [0, 1], [1, 0], [0, 1], [1, 0],
|
28
|
+
]
|
29
29
|
end
|
30
30
|
|
31
31
|
it "should get the pass sizes for a 0x0 image correctly" do
|
32
32
|
expect(adam7_pass_sizes(0, 0)).to eql [
|
33
|
-
|
34
|
-
|
33
|
+
[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0],
|
34
|
+
]
|
35
35
|
end
|
36
36
|
|
37
37
|
it "should always maintain the same amount of pixels in total" do
|
38
38
|
[[8, 8], [12, 12], [33, 47], [1, 1], [0, 0]].each do |(width, height)|
|
39
39
|
pass_sizes = adam7_pass_sizes(width, height)
|
40
|
-
expect(pass_sizes.inject(0) { |sum, (w, h)| sum + (w*h) }).to eql width * height
|
40
|
+
expect(pass_sizes.inject(0) { |sum, (w, h)| sum + (w * h) }).to eql width * height
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
describe
|
45
|
+
describe "#adam7_multiplier_offset" do
|
46
46
|
it "should get the multiplier and offset values for pass 1 correctly" do
|
47
47
|
expect(adam7_multiplier_offset(0)).to eql [3, 0, 3, 0]
|
48
48
|
end
|
@@ -72,7 +72,7 @@ describe ChunkyPNG::Canvas::Adam7Interlacing do
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
-
describe
|
75
|
+
describe "#adam7_merge_pass" do
|
76
76
|
it "should merge the submatrices correctly" do
|
77
77
|
submatrices = [
|
78
78
|
ChunkyPNG::Canvas.new(1, 1, 168430335), # r = 10
|
@@ -84,23 +84,22 @@ describe ChunkyPNG::Canvas::Adam7Interlacing do
|
|
84
84
|
ChunkyPNG::Canvas.new(8, 4, 1175063295), # r = 70
|
85
85
|
]
|
86
86
|
|
87
|
-
canvas = ChunkyPNG::Image.new(8,8)
|
87
|
+
canvas = ChunkyPNG::Image.new(8, 8)
|
88
88
|
submatrices.each_with_index { |m, pass| adam7_merge_pass(pass, canvas, m) }
|
89
|
-
expect(canvas).to eql reference_image(
|
89
|
+
expect(canvas).to eql reference_image("adam7")
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
-
describe
|
94
|
-
before(:each) { @canvas = reference_canvas(
|
93
|
+
describe "#adam7_extract_pass" do
|
94
|
+
before(:each) { @canvas = reference_canvas("adam7") }
|
95
95
|
|
96
96
|
1.upto(7) do |pass|
|
97
97
|
it "should extract pass #{pass} correctly" do
|
98
98
|
sm = adam7_extract_pass(pass - 1, @canvas)
|
99
99
|
expect(sm.pixels.length).to eql sm.width * sm.height
|
100
100
|
expect(sm.pixels.uniq.length).to eql 1
|
101
|
-
expect(ChunkyPNG::Color.r(sm[0,0])).to eql pass * 10
|
101
|
+
expect(ChunkyPNG::Color.r(sm[0, 0])).to eql pass * 10
|
102
102
|
end
|
103
103
|
end
|
104
104
|
end
|
105
|
-
|
106
105
|
end
|
@@ -1,11 +1,14 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe ChunkyPNG::Canvas do
|
4
|
-
|
5
|
-
describe '#to_data_url' do
|
4
|
+
describe "#to_data_url" do
|
6
5
|
it "should export a sample canvas to an RGBA stream correctly" do
|
7
|
-
canvas = ChunkyPNG::Canvas.new(2, 2, [
|
8
|
-
|
6
|
+
canvas = ChunkyPNG::Canvas.new(2, 2, [
|
7
|
+
ChunkyPNG::Color.rgba(1, 2, 3, 4),
|
8
|
+
ChunkyPNG::Color.rgba(5, 6, 7, 8),
|
9
|
+
ChunkyPNG::Color.rgba(4, 3, 2, 1),
|
10
|
+
ChunkyPNG::Color.rgba(8, 7, 6, 5),
|
11
|
+
])
|
9
12
|
|
10
13
|
expect(canvas.to_data_url).to eql "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEUBAgMEAwIFBgcIBwazgAAdAAAABHRSTlMEAQgFhYDlfQAAAAxJREFUeJxjUmAKAAAAwAB1GNhIEwAAAABJRU5ErkJggg=="
|
11
14
|
end
|
@@ -1,15 +1,14 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe ChunkyPNG::Canvas do
|
4
|
-
|
5
|
-
describe '.from_data_url' do
|
4
|
+
describe ".from_data_url" do
|
6
5
|
it "should import an image from a data URL" do
|
7
|
-
data_url = reference_canvas(
|
8
|
-
expect(ChunkyPNG::Canvas.from_data_url(data_url)).to eql reference_canvas(
|
6
|
+
data_url = reference_canvas("operations").to_data_url
|
7
|
+
expect(ChunkyPNG::Canvas.from_data_url(data_url)).to eql reference_canvas("operations")
|
9
8
|
end
|
10
9
|
|
11
10
|
it "should raise an exception if the string is not a proper data URL" do
|
12
|
-
expect { ChunkyPNG::Canvas.from_data_url(
|
11
|
+
expect { ChunkyPNG::Canvas.from_data_url("whatever") }.to raise_error(ChunkyPNG::SignatureMismatch)
|
13
12
|
end
|
14
13
|
end
|
15
14
|
end
|