chunky_png 1.3.11 → 1.3.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.standard.yml +16 -0
- data/.travis.yml +5 -5
- data/.yardopts +1 -1
- data/CHANGELOG.rdoc +5 -1
- data/CONTRIBUTING.rdoc +17 -8
- data/Gemfile +3 -3
- data/LICENSE +1 -1
- data/README.md +6 -1
- data/Rakefile +3 -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 +15 -15
- data/lib/chunky_png.rb +16 -25
- data/lib/chunky_png/canvas.rb +28 -27
- data/lib/chunky_png/canvas/adam7_interlacing.rb +14 -10
- data/lib/chunky_png/canvas/data_url_exporting.rb +1 -3
- data/lib/chunky_png/canvas/data_url_importing.rb +1 -3
- data/lib/chunky_png/canvas/drawing.rb +28 -43
- data/lib/chunky_png/canvas/masking.rb +12 -14
- data/lib/chunky_png/canvas/operations.rb +26 -24
- data/lib/chunky_png/canvas/png_decoding.rb +36 -32
- data/lib/chunky_png/canvas/png_encoding.rb +106 -100
- data/lib/chunky_png/canvas/resampling.rb +26 -33
- data/lib/chunky_png/canvas/stream_exporting.rb +6 -8
- data/lib/chunky_png/canvas/stream_importing.rb +6 -8
- data/lib/chunky_png/chunk.rb +69 -60
- data/lib/chunky_png/color.rb +211 -206
- data/lib/chunky_png/datastream.rb +20 -22
- data/lib/chunky_png/dimension.rb +16 -11
- data/lib/chunky_png/image.rb +9 -11
- data/lib/chunky_png/palette.rb +4 -9
- data/lib/chunky_png/point.rb +25 -26
- data/lib/chunky_png/rmagick.rb +8 -10
- data/lib/chunky_png/vector.rb +26 -29
- data/lib/chunky_png/version.rb +1 -1
- 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 +57 -52
- data/spec/chunky_png/color_spec.rb +115 -114
- data/spec/chunky_png/datastream_spec.rb +49 -51
- 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/spec_helper.rb +6 -10
- data/tasks/benchmarks.rake +7 -8
- metadata +34 -5
- data/lib/chunky_png/compatibility.rb +0 -15
@@ -1,14 +1,14 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe ChunkyPNG::Canvas::PNGEncoding do
|
4
4
|
include ChunkyPNG::Canvas::PNGEncoding
|
5
5
|
|
6
|
-
context
|
6
|
+
context "determining encoding options" do
|
7
7
|
[:indexed, :grayscale, :grayscale_alpha, :truecolor, :truecolor_alpha].each do |color_mode_name|
|
8
8
|
it "should encode an image with color mode #{color_mode_name} correctly" do
|
9
9
|
canvas = ChunkyPNG::Canvas.new(10, 10, ChunkyPNG::Color.rgb(100, 100, 100))
|
10
10
|
color_mode = ChunkyPNG.const_get("COLOR_#{color_mode_name.to_s.upcase}")
|
11
|
-
blob = canvas.to_blob(:
|
11
|
+
blob = canvas.to_blob(color_mode: color_mode)
|
12
12
|
|
13
13
|
ds = ChunkyPNG::Datastream.from_blob(blob)
|
14
14
|
expect(ds.header_chunk.color).to eql color_mode
|
@@ -17,7 +17,7 @@ describe ChunkyPNG::Canvas::PNGEncoding do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should encode an image with 2 colors using 1-bit indexed color mode" do
|
20
|
-
@canvas = ChunkyPNG::Canvas.from_file(png_suite_file(
|
20
|
+
@canvas = ChunkyPNG::Canvas.from_file(png_suite_file("basic", "basn3p01.png"))
|
21
21
|
ds = ChunkyPNG::Datastream.from_blob(@canvas.to_blob)
|
22
22
|
expect(ds.header_chunk.color).to eql ChunkyPNG::COLOR_INDEXED
|
23
23
|
expect(ds.header_chunk.depth).to eql 1
|
@@ -25,7 +25,7 @@ describe ChunkyPNG::Canvas::PNGEncoding do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should encode an image with 4 colors using 2-bit indexed color mode" do
|
28
|
-
@canvas = ChunkyPNG::Canvas.from_file(png_suite_file(
|
28
|
+
@canvas = ChunkyPNG::Canvas.from_file(png_suite_file("basic", "basn3p02.png"))
|
29
29
|
ds = ChunkyPNG::Datastream.from_blob(@canvas.to_blob)
|
30
30
|
expect(ds.header_chunk.color).to eql ChunkyPNG::COLOR_INDEXED
|
31
31
|
expect(ds.header_chunk.depth).to eql 2
|
@@ -33,7 +33,7 @@ describe ChunkyPNG::Canvas::PNGEncoding do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it "should encode an image with 16 colors using 4-bit indexed color mode" do
|
36
|
-
@canvas = ChunkyPNG::Canvas.from_file(png_suite_file(
|
36
|
+
@canvas = ChunkyPNG::Canvas.from_file(png_suite_file("basic", "basn3p04.png"))
|
37
37
|
ds = ChunkyPNG::Datastream.from_blob(@canvas.to_blob)
|
38
38
|
expect(ds.header_chunk.color).to eql ChunkyPNG::COLOR_INDEXED
|
39
39
|
expect(ds.header_chunk.depth).to eql 4
|
@@ -41,7 +41,7 @@ describe ChunkyPNG::Canvas::PNGEncoding do
|
|
41
41
|
end
|
42
42
|
|
43
43
|
it "should encode an image with 256 colors using 8-bit indexed color mode" do
|
44
|
-
@canvas = ChunkyPNG::Canvas.from_file(png_suite_file(
|
44
|
+
@canvas = ChunkyPNG::Canvas.from_file(png_suite_file("basic", "basn3p08.png"))
|
45
45
|
ds = ChunkyPNG::Datastream.from_blob(@canvas.to_blob)
|
46
46
|
expect(ds.header_chunk.color).to eql ChunkyPNG::COLOR_INDEXED
|
47
47
|
expect(ds.header_chunk.depth).to eql 8
|
@@ -49,16 +49,16 @@ describe ChunkyPNG::Canvas::PNGEncoding do
|
|
49
49
|
end
|
50
50
|
|
51
51
|
it "should use a higher bit depth than necessary if requested" do
|
52
|
-
@canvas = ChunkyPNG::Canvas.from_file(png_suite_file(
|
53
|
-
ds = ChunkyPNG::Datastream.from_blob(@canvas.to_blob(:
|
52
|
+
@canvas = ChunkyPNG::Canvas.from_file(png_suite_file("basic", "basn3p01.png"))
|
53
|
+
ds = ChunkyPNG::Datastream.from_blob(@canvas.to_blob(bit_depth: 4))
|
54
54
|
expect(ds.header_chunk.color).to eql ChunkyPNG::COLOR_INDEXED
|
55
55
|
expect(ds.header_chunk.depth).to eql 4
|
56
56
|
expect(@canvas).to eql ChunkyPNG::Canvas.from_datastream(ds)
|
57
57
|
end
|
58
58
|
|
59
59
|
it "should encode an image with interlacing correctly" do
|
60
|
-
input_canvas = ChunkyPNG::Canvas.from_file(resource_file(
|
61
|
-
blob = input_canvas.to_blob(:
|
60
|
+
input_canvas = ChunkyPNG::Canvas.from_file(resource_file("operations.png"))
|
61
|
+
blob = input_canvas.to_blob(interlace: true)
|
62
62
|
|
63
63
|
ds = ChunkyPNG::Datastream.from_blob(blob)
|
64
64
|
expect(ds.header_chunk.interlace).to eql ChunkyPNG::INTERLACING_ADAM7
|
@@ -66,55 +66,57 @@ describe ChunkyPNG::Canvas::PNGEncoding do
|
|
66
66
|
end
|
67
67
|
|
68
68
|
it "should save an image using the normal routine correctly" do
|
69
|
-
canvas = reference_canvas(
|
70
|
-
expect(Zlib::Deflate).to receive(:deflate).with(anything, Zlib::DEFAULT_COMPRESSION).and_return(
|
69
|
+
canvas = reference_canvas("operations")
|
70
|
+
expect(Zlib::Deflate).to receive(:deflate).with(anything, Zlib::DEFAULT_COMPRESSION).and_return("")
|
71
71
|
canvas.to_blob
|
72
72
|
end
|
73
73
|
|
74
74
|
it "should save an image using the :fast_rgba routine correctly" do
|
75
|
-
canvas = reference_canvas(
|
75
|
+
canvas = reference_canvas("operations")
|
76
76
|
expect(canvas).to_not receive(:encode_png_str_scanline_none)
|
77
77
|
expect(canvas).to_not receive(:encode_png_str_scanline_sub)
|
78
78
|
expect(canvas).to_not receive(:encode_png_str_scanline_up)
|
79
79
|
expect(canvas).to_not receive(:encode_png_str_scanline_average)
|
80
80
|
expect(canvas).to_not receive(:encode_png_str_scanline_paeth)
|
81
|
-
expect(Zlib::Deflate).to receive(:deflate).with(anything, Zlib::BEST_SPEED).and_return(
|
81
|
+
expect(Zlib::Deflate).to receive(:deflate).with(anything, Zlib::BEST_SPEED).and_return("")
|
82
82
|
canvas.to_blob(:fast_rgba)
|
83
83
|
end
|
84
84
|
|
85
85
|
it "should save an image using the :good_compression routine correctly" do
|
86
|
-
canvas = reference_canvas(
|
86
|
+
canvas = reference_canvas("operations")
|
87
87
|
expect(canvas).to_not receive(:encode_png_str_scanline_none)
|
88
88
|
expect(canvas).to_not receive(:encode_png_str_scanline_sub)
|
89
89
|
expect(canvas).to_not receive(:encode_png_str_scanline_up)
|
90
90
|
expect(canvas).to_not receive(:encode_png_str_scanline_average)
|
91
91
|
expect(canvas).to_not receive(:encode_png_str_scanline_paeth)
|
92
|
-
expect(Zlib::Deflate).to receive(:deflate).with(anything, Zlib::BEST_COMPRESSION).and_return(
|
92
|
+
expect(Zlib::Deflate).to receive(:deflate).with(anything, Zlib::BEST_COMPRESSION).and_return("")
|
93
93
|
canvas.to_blob(:good_compression)
|
94
94
|
end
|
95
95
|
|
96
96
|
it "should save an image using the :best_compression routine correctly" do
|
97
|
-
canvas = reference_canvas(
|
97
|
+
canvas = reference_canvas("operations")
|
98
98
|
expect(canvas).to receive(:encode_png_str_scanline_paeth).exactly(canvas.height).times
|
99
|
-
expect(Zlib::Deflate).to receive(:deflate).with(anything, Zlib::BEST_COMPRESSION).and_return(
|
99
|
+
expect(Zlib::Deflate).to receive(:deflate).with(anything, Zlib::BEST_COMPRESSION).and_return("")
|
100
100
|
canvas.to_blob(:best_compression)
|
101
101
|
end
|
102
102
|
|
103
103
|
it "should save an image with black and white only if requested" do
|
104
|
-
ds = ChunkyPNG::Datastream.from_blob(reference_canvas(
|
104
|
+
ds = ChunkyPNG::Datastream.from_blob(reference_canvas("lines").to_blob(:black_and_white))
|
105
105
|
expect(ds.header_chunk.color).to eql ChunkyPNG::COLOR_GRAYSCALE
|
106
106
|
expect(ds.header_chunk.depth).to eql 1
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
|
-
describe
|
110
|
+
describe "different color modes and bit depths" do
|
111
111
|
before do
|
112
112
|
@canvas = ChunkyPNG::Canvas.new(2, 2)
|
113
113
|
|
114
|
+
# rubocop:disable Layout/ExtraSpacing, Layout/SpaceInsideParens
|
114
115
|
@canvas[0, 0] = ChunkyPNG::Color.rgba( 1, 2, 3, 4)
|
115
116
|
@canvas[1, 0] = ChunkyPNG::Color.rgba(252, 253, 254, 255)
|
116
117
|
@canvas[0, 1] = ChunkyPNG::Color.rgba(255, 254, 253, 252)
|
117
118
|
@canvas[1, 1] = ChunkyPNG::Color.rgba( 4, 3, 2, 1)
|
119
|
+
# rubocop:enable Layout/ExtraSpacing, Layout/SpaceInsideParens
|
118
120
|
|
119
121
|
@canvas.encoding_palette = @canvas.palette
|
120
122
|
@canvas.encoding_palette.to_plte_chunk
|
@@ -122,32 +124,32 @@ describe ChunkyPNG::Canvas::PNGEncoding do
|
|
122
124
|
|
123
125
|
it "should encode using 8-bit RGBA mode correctly" do
|
124
126
|
stream = @canvas.encode_png_pixelstream(ChunkyPNG::COLOR_TRUECOLOR_ALPHA, 8, ChunkyPNG::INTERLACING_NONE, ChunkyPNG::FILTER_NONE)
|
125
|
-
expect(stream).to eql
|
127
|
+
expect(stream).to eql "\0\x01\x02\x03\x04\xFC\xFD\xFE\xFF\0\xFF\xFE\xFD\xFC\x04\x03\x02\x01".force_encoding(Encoding::BINARY)
|
126
128
|
end
|
127
129
|
|
128
130
|
it "should encode using 8 bit RGB mode correctly" do
|
129
131
|
stream = @canvas.encode_png_pixelstream(ChunkyPNG::COLOR_TRUECOLOR, 8, ChunkyPNG::INTERLACING_NONE, ChunkyPNG::FILTER_NONE)
|
130
|
-
expect(stream).to eql
|
132
|
+
expect(stream).to eql "\0\x01\x02\x03\xFC\xFD\xFE\0\xFF\xFE\xFD\x04\x03\x02".force_encoding(Encoding::BINARY)
|
131
133
|
end
|
132
134
|
|
133
135
|
it "should encode using 1-bit grayscale mode correctly" do
|
134
136
|
stream = @canvas.encode_png_pixelstream(ChunkyPNG::COLOR_GRAYSCALE, 1, ChunkyPNG::INTERLACING_NONE, ChunkyPNG::FILTER_NONE)
|
135
|
-
expect(stream).to eql
|
137
|
+
expect(stream).to eql "\0\x40\0\x80".force_encoding(Encoding::BINARY) # Using the B byte of the pixel == 3, assuming R == G == B for grayscale images
|
136
138
|
end
|
137
139
|
|
138
140
|
it "should encode using 2-bit grayscale mode correctly" do
|
139
141
|
stream = @canvas.encode_png_pixelstream(ChunkyPNG::COLOR_GRAYSCALE, 2, ChunkyPNG::INTERLACING_NONE, ChunkyPNG::FILTER_NONE)
|
140
|
-
expect(stream).to eql
|
142
|
+
expect(stream).to eql "\0\x30\0\xC0".force_encoding(Encoding::BINARY) # Using the B byte of the pixel == 3, assuming R == G == B for grayscale images
|
141
143
|
end
|
142
144
|
|
143
145
|
it "should encode using 4-bit grayscale mode correctly" do
|
144
146
|
stream = @canvas.encode_png_pixelstream(ChunkyPNG::COLOR_GRAYSCALE, 4, ChunkyPNG::INTERLACING_NONE, ChunkyPNG::FILTER_NONE)
|
145
|
-
expect(stream).to eql
|
147
|
+
expect(stream).to eql "\0\x0F\0\xF0".force_encoding(Encoding::BINARY) # Using the B byte of the pixel == 3, assuming R == G == B for grayscale images
|
146
148
|
end
|
147
149
|
|
148
150
|
it "should encode using 8-bit grayscale mode correctly" do
|
149
151
|
stream = @canvas.encode_png_pixelstream(ChunkyPNG::COLOR_GRAYSCALE, 8, ChunkyPNG::INTERLACING_NONE, ChunkyPNG::FILTER_NONE)
|
150
|
-
expect(stream).to eql
|
152
|
+
expect(stream).to eql "\0\x03\xFE\0\xFD\x02".force_encoding(Encoding::BINARY) # Using the B byte of the pixel == 3, assuming R == G == B for grayscale images
|
151
153
|
end
|
152
154
|
|
153
155
|
it "should not encode using 1-bit indexed mode because the image has too many colors" do
|
@@ -158,78 +160,85 @@ describe ChunkyPNG::Canvas::PNGEncoding do
|
|
158
160
|
|
159
161
|
it "should encode using 2-bit indexed mode correctly" do
|
160
162
|
stream = @canvas.encode_png_pixelstream(ChunkyPNG::COLOR_INDEXED, 2, ChunkyPNG::INTERLACING_NONE, ChunkyPNG::FILTER_NONE)
|
161
|
-
expect(stream).to eql
|
163
|
+
expect(stream).to eql "\0\x20\0\xD0".force_encoding(Encoding::BINARY)
|
162
164
|
end
|
163
165
|
|
164
166
|
it "should encode using 4-bit indexed mode correctly" do
|
165
167
|
stream = @canvas.encode_png_pixelstream(ChunkyPNG::COLOR_INDEXED, 4, ChunkyPNG::INTERLACING_NONE, ChunkyPNG::FILTER_NONE)
|
166
|
-
expect(stream).to eql
|
168
|
+
expect(stream).to eql "\0\x02\0\x31".force_encoding(Encoding::BINARY)
|
167
169
|
end
|
168
170
|
|
169
171
|
it "should encode using 8-bit indexed mode correctly" do
|
170
172
|
stream = @canvas.encode_png_pixelstream(ChunkyPNG::COLOR_INDEXED, 8, ChunkyPNG::INTERLACING_NONE, ChunkyPNG::FILTER_NONE)
|
171
|
-
expect(stream).to eql
|
173
|
+
expect(stream).to eql "\0\x00\x02\0\x03\x01".force_encoding(Encoding::BINARY)
|
172
174
|
end
|
173
175
|
end
|
174
176
|
|
175
|
-
describe
|
176
|
-
|
177
|
+
describe "different filter methods" do
|
177
178
|
it "should encode a scanline without filtering correctly" do
|
178
|
-
stream = [ChunkyPNG::FILTER_NONE, 0, 0, 0, 1, 1, 1, 2, 2, 2].pack(
|
179
|
+
stream = [ChunkyPNG::FILTER_NONE, 0, 0, 0, 1, 1, 1, 2, 2, 2].pack("C*")
|
179
180
|
encode_png_str_scanline_none(stream, 0, nil, 9, 3)
|
180
|
-
expect(stream.unpack(
|
181
|
+
expect(stream.unpack("C*")).to eql [ChunkyPNG::FILTER_NONE, 0, 0, 0, 1, 1, 1, 2, 2, 2]
|
181
182
|
end
|
182
183
|
|
183
184
|
it "should encode a scanline with sub filtering correctly" do
|
184
|
-
stream = [
|
185
|
-
|
185
|
+
stream = [
|
186
|
+
ChunkyPNG::FILTER_NONE, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
187
|
+
ChunkyPNG::FILTER_NONE, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
188
|
+
].pack("C*")
|
186
189
|
|
187
190
|
# Check line with previous line
|
188
191
|
encode_png_str_scanline_sub(stream, 10, 0, 9, 3)
|
189
|
-
expect(stream.unpack(
|
192
|
+
expect(stream.unpack("@10C10")).to eql [ChunkyPNG::FILTER_SUB, 255, 255, 255, 0, 0, 0, 0, 0, 0]
|
190
193
|
|
191
194
|
# Check line without previous line
|
192
195
|
encode_png_str_scanline_sub(stream, 0, nil, 9, 3)
|
193
|
-
expect(stream.unpack(
|
196
|
+
expect(stream.unpack("@0C10")).to eql [ChunkyPNG::FILTER_SUB, 255, 255, 255, 0, 0, 0, 0, 0, 0]
|
194
197
|
end
|
195
198
|
|
196
199
|
it "should encode a scanline with up filtering correctly" do
|
197
|
-
stream = [
|
198
|
-
|
200
|
+
stream = [
|
201
|
+
ChunkyPNG::FILTER_NONE, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
202
|
+
ChunkyPNG::FILTER_NONE, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
203
|
+
].pack("C*")
|
199
204
|
|
200
205
|
# Check line with previous line
|
201
206
|
encode_png_str_scanline_up(stream, 10, 0, 9, 3)
|
202
|
-
expect(stream.unpack(
|
207
|
+
expect(stream.unpack("@10C10")).to eql [ChunkyPNG::FILTER_UP, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
203
208
|
|
204
209
|
# Check line without previous line
|
205
210
|
encode_png_str_scanline_up(stream, 0, nil, 9, 3)
|
206
|
-
expect(stream.unpack(
|
211
|
+
expect(stream.unpack("@0C10")).to eql [ChunkyPNG::FILTER_UP, 255, 255, 255, 255, 255, 255, 255, 255, 255]
|
207
212
|
end
|
208
213
|
|
209
214
|
it "should encode a scanline with average filtering correctly" do
|
210
|
-
stream = [
|
211
|
-
|
215
|
+
stream = [
|
216
|
+
ChunkyPNG::FILTER_NONE, 10, 20, 30, 40, 50, 60, 70, 80, 80, 100, 110, 120, # rubocop:disable Layout/ExtraSpacing
|
217
|
+
ChunkyPNG::FILTER_NONE, 5, 10, 25, 45, 45, 55, 80, 125, 105, 150, 114, 165, # rubocop:disable Layout/ExtraSpacing
|
218
|
+
].pack("C*")
|
212
219
|
|
213
220
|
# Check line with previous line
|
214
221
|
encode_png_str_scanline_average(stream, 13, 0, 12, 3)
|
215
|
-
expect(stream.unpack(
|
222
|
+
expect(stream.unpack("@13C13")).to eql [ChunkyPNG::FILTER_AVERAGE, 0, 0, 10, 23, 15, 13, 23, 63, 38, 60, 253, 53]
|
216
223
|
|
217
224
|
# Check line without previous line
|
218
225
|
encode_png_str_scanline_average(stream, 0, nil, 12, 3)
|
219
|
-
expect(stream.unpack(
|
226
|
+
expect(stream.unpack("@0C13")).to eql [ChunkyPNG::FILTER_AVERAGE, 10, 20, 30, 35, 40, 45, 50, 55, 50, 65, 70, 80]
|
220
227
|
end
|
221
228
|
|
222
229
|
it "should encode a scanline with paeth filtering correctly" do
|
223
|
-
stream = [
|
224
|
-
|
230
|
+
stream = [
|
231
|
+
ChunkyPNG::FILTER_NONE, 10, 20, 30, 40, 50, 60, 70, 80, 80, 100, 110, 120, # rubocop:disable Layout/ExtraSpacing
|
232
|
+
ChunkyPNG::FILTER_NONE, 10, 20, 40, 60, 60, 60, 70, 120, 90, 120, 54, 120, # rubocop:disable Layout/ExtraSpacing
|
233
|
+
].pack("C*")
|
225
234
|
|
226
235
|
# Check line with previous line
|
227
236
|
encode_png_str_scanline_paeth(stream, 13, 0, 12, 3)
|
228
|
-
expect(stream.unpack(
|
237
|
+
expect(stream.unpack("@13C13")).to eql [ChunkyPNG::FILTER_PAETH, 0, 0, 10, 20, 10, 0, 0, 40, 10, 20, 190, 0]
|
229
238
|
|
230
239
|
# Check line without previous line
|
231
240
|
encode_png_str_scanline_paeth(stream, 0, nil, 12, 3)
|
232
|
-
expect(stream.unpack(
|
241
|
+
expect(stream.unpack("@0C13")).to eql [ChunkyPNG::FILTER_PAETH, 10, 20, 30, 30, 30, 30, 30, 30, 20, 30, 30, 40]
|
233
242
|
end
|
234
243
|
end
|
235
244
|
end
|
@@ -1,11 +1,9 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe ChunkyPNG::Canvas::Resampling do
|
4
|
+
subject { reference_canvas("clock") }
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
describe '#resample_nearest_neighbor' do
|
8
|
-
|
6
|
+
describe "#resample_nearest_neighbor" do
|
9
7
|
it "should downscale from 2x2 to 1x1 correctly" do
|
10
8
|
canvas = ChunkyPNG::Canvas.new(2, 2, [1, 2, 3, 4])
|
11
9
|
expect(canvas.resample_nearest_neighbor(1, 1)).to eql ChunkyPNG::Canvas.new(1, 1, [4])
|
@@ -17,15 +15,15 @@ describe ChunkyPNG::Canvas::Resampling do
|
|
17
15
|
end
|
18
16
|
|
19
17
|
it "should upscale both axis of the image" do
|
20
|
-
expect(subject.resample_nearest_neighbor(45, 45)).to eql reference_canvas(
|
18
|
+
expect(subject.resample_nearest_neighbor(45, 45)).to eql reference_canvas("clock_nn_xup_yup")
|
21
19
|
end
|
22
20
|
|
23
21
|
it "should downscale both axis of the image" do
|
24
|
-
expect(subject.resample_nearest_neighbor(12, 12)).to eql reference_canvas(
|
22
|
+
expect(subject.resample_nearest_neighbor(12, 12)).to eql reference_canvas("clock_nn_xdown_ydown")
|
25
23
|
end
|
26
24
|
|
27
25
|
it "should downscale the x-axis and upscale the y-axis of the image" do
|
28
|
-
expect(subject.resample_nearest_neighbor(20, 50)).to eql reference_canvas(
|
26
|
+
expect(subject.resample_nearest_neighbor(20, 50)).to eql reference_canvas("clock_nn_xdown_yup")
|
29
27
|
end
|
30
28
|
|
31
29
|
it "should not return itself" do
|
@@ -37,20 +35,20 @@ describe ChunkyPNG::Canvas::Resampling do
|
|
37
35
|
end
|
38
36
|
end
|
39
37
|
|
40
|
-
describe
|
38
|
+
describe "#resample_nearest_neighbor!" do
|
41
39
|
it "should upscale both axis of the image" do
|
42
40
|
subject.resample_nearest_neighbor!(45, 45)
|
43
|
-
expect(subject).to eql reference_canvas(
|
41
|
+
expect(subject).to eql reference_canvas("clock_nn_xup_yup")
|
44
42
|
end
|
45
43
|
|
46
44
|
it "should downscale both axis of the image" do
|
47
45
|
subject.resample_nearest_neighbor!(12, 12)
|
48
|
-
expect(subject).to eql reference_canvas(
|
46
|
+
expect(subject).to eql reference_canvas("clock_nn_xdown_ydown")
|
49
47
|
end
|
50
48
|
|
51
49
|
it "should downscale the x-axis and upscale the y-axis of the image" do
|
52
50
|
subject.resample_nearest_neighbor!(20, 50)
|
53
|
-
expect(subject).to eql reference_canvas(
|
51
|
+
expect(subject).to eql reference_canvas("clock_nn_xdown_yup")
|
54
52
|
end
|
55
53
|
|
56
54
|
it "should return itself" do
|
@@ -58,7 +56,7 @@ describe ChunkyPNG::Canvas::Resampling do
|
|
58
56
|
end
|
59
57
|
|
60
58
|
it "should change the original image's dimensions" do
|
61
|
-
expect { subject.resample_nearest_neighbor!(1, 1) }.to change { subject.dimension }.to(ChunkyPNG::Dimension(
|
59
|
+
expect { subject.resample_nearest_neighbor!(1, 1) }.to change { subject.dimension }.to(ChunkyPNG::Dimension("1x1"))
|
62
60
|
end
|
63
61
|
end
|
64
62
|
|
@@ -74,15 +72,15 @@ describe ChunkyPNG::Canvas::Resampling do
|
|
74
72
|
end
|
75
73
|
|
76
74
|
it "should upscale both axis of the image" do
|
77
|
-
expect(subject.resample_bilinear(45, 45)).to eql reference_canvas(
|
75
|
+
expect(subject.resample_bilinear(45, 45)).to eql reference_canvas("clock_bl_xup_yup")
|
78
76
|
end
|
79
77
|
|
80
78
|
it "should downscale both axis of the image" do
|
81
|
-
expect(subject.resample_bilinear(12, 12)).to eql reference_canvas(
|
79
|
+
expect(subject.resample_bilinear(12, 12)).to eql reference_canvas("clock_bl_xdown_ydown")
|
82
80
|
end
|
83
81
|
|
84
82
|
it "should downscale the x-axis and upscale the y-axis of the image" do
|
85
|
-
expect(subject.resample_bilinear(20, 50)).to eql reference_canvas(
|
83
|
+
expect(subject.resample_bilinear(20, 50)).to eql reference_canvas("clock_bl_xdown_yup")
|
86
84
|
end
|
87
85
|
|
88
86
|
it "should not return itself" do
|
@@ -94,20 +92,20 @@ describe ChunkyPNG::Canvas::Resampling do
|
|
94
92
|
end
|
95
93
|
end
|
96
94
|
|
97
|
-
describe
|
95
|
+
describe "#resample_bilinear!" do
|
98
96
|
it "should upscale both axis of the image" do
|
99
97
|
subject.resample_bilinear!(45, 45)
|
100
|
-
expect(subject).to eql reference_canvas(
|
98
|
+
expect(subject).to eql reference_canvas("clock_bl_xup_yup")
|
101
99
|
end
|
102
100
|
|
103
101
|
it "should downscale both axis of the image" do
|
104
102
|
subject.resample_bilinear!(12, 12)
|
105
|
-
expect(subject).to eql reference_canvas(
|
103
|
+
expect(subject).to eql reference_canvas("clock_bl_xdown_ydown")
|
106
104
|
end
|
107
105
|
|
108
106
|
it "should downscale the x-axis and upscale the y-axis of the image" do
|
109
107
|
subject.resample_bilinear!(20, 50)
|
110
|
-
expect(subject).to eql reference_canvas(
|
108
|
+
expect(subject).to eql reference_canvas("clock_bl_xdown_yup")
|
111
109
|
end
|
112
110
|
|
113
111
|
it "should return itself" do
|
@@ -115,7 +113,7 @@ describe ChunkyPNG::Canvas::Resampling do
|
|
115
113
|
end
|
116
114
|
|
117
115
|
it "should change the original image's dimensions" do
|
118
|
-
expect { subject.resample_bilinear!(1, 1) }.to change { subject.dimension }.to(ChunkyPNG::Dimension(
|
116
|
+
expect { subject.resample_bilinear!(1, 1) }.to change { subject.dimension }.to(ChunkyPNG::Dimension("1x1"))
|
119
117
|
end
|
120
118
|
end
|
121
119
|
end
|
@@ -1,59 +1,79 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe ChunkyPNG::Canvas do
|
4
|
-
|
5
|
-
describe '#to_rgba_stream' do
|
4
|
+
describe "#to_rgba_stream" 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
|
-
expect(canvas.to_rgba_stream).to eql
|
13
|
+
expect(canvas.to_rgba_stream).to eql [1, 2, 3, 4, 5, 6, 7, 8, 4, 3, 2, 1, 8, 7, 6, 5].pack("C16")
|
11
14
|
end
|
12
15
|
|
13
16
|
it "should export an image to an RGBA datastream correctly" do
|
14
|
-
expect(reference_canvas(
|
17
|
+
expect(reference_canvas("pixelstream_reference").to_rgba_stream).to eql resource_data("pixelstream.rgba")
|
15
18
|
end
|
16
19
|
end
|
17
20
|
|
18
|
-
describe
|
21
|
+
describe "#to_rgb_stream" do
|
19
22
|
it "should export a sample canvas to an RGBA stream correctly" do
|
20
|
-
canvas = ChunkyPNG::Canvas.new(2, 2, [
|
21
|
-
|
23
|
+
canvas = ChunkyPNG::Canvas.new(2, 2, [
|
24
|
+
ChunkyPNG::Color.rgba(1, 2, 3, 4),
|
25
|
+
ChunkyPNG::Color.rgba(5, 6, 7, 8),
|
26
|
+
ChunkyPNG::Color.rgba(4, 3, 2, 1),
|
27
|
+
ChunkyPNG::Color.rgba(8, 7, 6, 5),
|
28
|
+
])
|
22
29
|
|
23
|
-
expect(canvas.to_rgb_stream).to eql [1,2,3,5,6,7,4,3,2,8,7,6].pack(
|
30
|
+
expect(canvas.to_rgb_stream).to eql [1, 2, 3, 5, 6, 7, 4, 3, 2, 8, 7, 6].pack("C12")
|
24
31
|
end
|
25
32
|
|
26
33
|
it "should export an image to an RGB datastream correctly" do
|
27
|
-
expect(reference_canvas(
|
34
|
+
expect(reference_canvas("pixelstream_reference").to_rgb_stream).to eql resource_data("pixelstream.rgb")
|
28
35
|
end
|
29
36
|
end
|
30
37
|
|
31
|
-
describe
|
32
|
-
|
38
|
+
describe "#to_grayscale_stream" do
|
33
39
|
it "should export a grayscale image to a grayscale datastream correctly" do
|
34
|
-
canvas = ChunkyPNG::Canvas.new(2, 2, [
|
35
|
-
|
36
|
-
|
37
|
-
|
40
|
+
canvas = ChunkyPNG::Canvas.new(2, 2, [
|
41
|
+
ChunkyPNG::Color.grayscale(1),
|
42
|
+
ChunkyPNG::Color.grayscale(2),
|
43
|
+
ChunkyPNG::Color.grayscale(3),
|
44
|
+
ChunkyPNG::Color.grayscale(4),
|
45
|
+
])
|
38
46
|
|
47
|
+
expect(canvas.to_grayscale_stream).to eql [1, 2, 3, 4].pack("C4")
|
48
|
+
end
|
39
49
|
|
40
50
|
it "should export a color image to a grayscale datastream, using B values" do
|
41
|
-
canvas = ChunkyPNG::Canvas.new(2, 2, [
|
42
|
-
|
43
|
-
|
51
|
+
canvas = ChunkyPNG::Canvas.new(2, 2, [
|
52
|
+
ChunkyPNG::Color.rgba(1, 2, 3, 4),
|
53
|
+
ChunkyPNG::Color.rgba(5, 6, 7, 8),
|
54
|
+
ChunkyPNG::Color.rgba(4, 3, 2, 1),
|
55
|
+
ChunkyPNG::Color.rgba(8, 7, 6, 5),
|
56
|
+
])
|
57
|
+
|
58
|
+
expect(canvas.to_grayscale_stream).to eql [3, 7, 2, 6].pack("C4")
|
44
59
|
end
|
45
60
|
end
|
46
61
|
|
47
|
-
describe
|
62
|
+
describe "#to_alpha_channel_stream" do
|
48
63
|
it "should export an opaque image to an alpha channel datastream correctly" do
|
49
|
-
grayscale_array = Array.new(reference_canvas(
|
50
|
-
expect(reference_canvas(
|
64
|
+
grayscale_array = Array.new(reference_canvas("pixelstream_reference").pixels.length, 255)
|
65
|
+
expect(reference_canvas("pixelstream_reference").to_alpha_channel_stream).to eql grayscale_array.pack("C*")
|
51
66
|
end
|
52
67
|
|
53
68
|
it "should export a transparent image to an alpha channel datastream correctly" do
|
54
|
-
canvas = ChunkyPNG::Canvas.new(2, 2, [
|
55
|
-
|
56
|
-
|
69
|
+
canvas = ChunkyPNG::Canvas.new(2, 2, [
|
70
|
+
ChunkyPNG::Color.rgba(1, 2, 3, 4),
|
71
|
+
ChunkyPNG::Color.rgba(5, 6, 7, 8),
|
72
|
+
ChunkyPNG::Color.rgba(4, 3, 2, 1),
|
73
|
+
ChunkyPNG::Color.rgba(8, 7, 6, 5),
|
74
|
+
])
|
75
|
+
|
76
|
+
expect(canvas.to_alpha_channel_stream).to eql [4, 8, 1, 5].pack("C4")
|
57
77
|
end
|
58
78
|
end
|
59
79
|
end
|