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,30 +1,29 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe ChunkyPNG::Canvas do
|
4
|
-
|
5
|
-
describe '.from_rgb_stream' do
|
4
|
+
describe ".from_rgb_stream" do
|
6
5
|
it "should load an image correctly from a datastream" do
|
7
|
-
File.open(resource_file(
|
6
|
+
File.open(resource_file("pixelstream.rgb")) do |stream|
|
8
7
|
matrix = ChunkyPNG::Canvas.from_rgb_stream(240, 180, stream)
|
9
|
-
expect(matrix).to eql reference_canvas(
|
8
|
+
expect(matrix).to eql reference_canvas("pixelstream_reference")
|
10
9
|
end
|
11
10
|
end
|
12
11
|
end
|
13
12
|
|
14
|
-
describe
|
13
|
+
describe ".from_bgr_stream" do
|
15
14
|
it "should load an image correctly from a datastream" do
|
16
|
-
File.open(resource_file(
|
15
|
+
File.open(resource_file("pixelstream.bgr")) do |stream|
|
17
16
|
matrix = ChunkyPNG::Canvas.from_bgr_stream(240, 180, stream)
|
18
|
-
expect(matrix).to eql reference_canvas(
|
17
|
+
expect(matrix).to eql reference_canvas("pixelstream_reference")
|
19
18
|
end
|
20
19
|
end
|
21
20
|
end
|
22
21
|
|
23
|
-
describe
|
22
|
+
describe ".from_rgba_stream" do
|
24
23
|
it "should load an image correctly from a datastream" do
|
25
|
-
File.open(resource_file(
|
24
|
+
File.open(resource_file("pixelstream.rgba")) do |stream|
|
26
25
|
matrix = ChunkyPNG::Canvas.from_rgba_stream(240, 180, stream)
|
27
|
-
expect(matrix).to eql reference_canvas(
|
26
|
+
expect(matrix).to eql reference_canvas("pixelstream_reference")
|
28
27
|
end
|
29
28
|
end
|
30
29
|
end
|
@@ -1,17 +1,16 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe ChunkyPNG::Canvas do
|
4
|
-
|
5
4
|
subject { ChunkyPNG::Canvas.new(1, 1, ChunkyPNG::Color::WHITE) }
|
6
5
|
|
7
6
|
it { should respond_to(:width) }
|
8
7
|
it { should respond_to(:height) }
|
9
8
|
it { should respond_to(:pixels) }
|
10
9
|
|
11
|
-
describe
|
10
|
+
describe "#initialize" do
|
12
11
|
it "should accept a single color value as background color" do
|
13
|
-
canvas = ChunkyPNG::Canvas.new(2, 2,
|
14
|
-
expect(canvas[1, 0]).to eql ChunkyPNG::Color.parse(
|
12
|
+
canvas = ChunkyPNG::Canvas.new(2, 2, "red @ 0.8")
|
13
|
+
expect(canvas[1, 0]).to eql ChunkyPNG::Color.parse("red @ 0.8")
|
15
14
|
end
|
16
15
|
|
17
16
|
it "should raise an error if the color value is not understood" do
|
@@ -19,7 +18,7 @@ describe ChunkyPNG::Canvas do
|
|
19
18
|
end
|
20
19
|
|
21
20
|
it "should accept an array as initial pixel values" do
|
22
|
-
canvas = ChunkyPNG::Canvas.new(2, 2, [1,2,3,4])
|
21
|
+
canvas = ChunkyPNG::Canvas.new(2, 2, [1, 2, 3, 4])
|
23
22
|
expect(canvas[0, 0]).to eql 1
|
24
23
|
expect(canvas[1, 0]).to eql 2
|
25
24
|
expect(canvas[0, 1]).to eql 3
|
@@ -27,32 +26,32 @@ describe ChunkyPNG::Canvas do
|
|
27
26
|
end
|
28
27
|
|
29
28
|
it "should raise an ArgumentError if the initial array does not have the correct number of elements" do
|
30
|
-
expect { ChunkyPNG::Canvas.new(2, 2, [1,2,3]) }.to raise_error(ArgumentError)
|
31
|
-
expect { ChunkyPNG::Canvas.new(2, 2, [1,2,3,4,5]) }.to raise_error(ArgumentError)
|
29
|
+
expect { ChunkyPNG::Canvas.new(2, 2, [1, 2, 3]) }.to raise_error(ArgumentError)
|
30
|
+
expect { ChunkyPNG::Canvas.new(2, 2, [1, 2, 3, 4, 5]) }.to raise_error(ArgumentError)
|
32
31
|
end
|
33
32
|
|
34
33
|
it "should use a transparent background by default" do
|
35
34
|
canvas = ChunkyPNG::Canvas.new(1, 1)
|
36
|
-
expect(canvas[0,0]).to eql ChunkyPNG::Color::TRANSPARENT
|
35
|
+
expect(canvas[0, 0]).to eql ChunkyPNG::Color::TRANSPARENT
|
37
36
|
end
|
38
37
|
end
|
39
38
|
|
40
|
-
describe
|
39
|
+
describe "#dimension" do
|
41
40
|
it "should return the dimensions as a Dimension instance" do
|
42
|
-
expect(subject.dimension).to eql ChunkyPNG::Dimension(
|
41
|
+
expect(subject.dimension).to eql ChunkyPNG::Dimension("1x1")
|
43
42
|
end
|
44
43
|
end
|
45
44
|
|
46
|
-
describe
|
45
|
+
describe "#area" do
|
47
46
|
it "should return the dimensions as two-item array" do
|
48
|
-
expect(subject.area).to eql ChunkyPNG::Dimension(
|
47
|
+
expect(subject.area).to eql ChunkyPNG::Dimension("1x1").area
|
49
48
|
end
|
50
49
|
end
|
51
50
|
|
52
|
-
describe
|
51
|
+
describe "#include?" do
|
53
52
|
it "should return true if the coordinates are within bounds, false otherwise" do
|
53
|
+
# rubocop:disable Layout/SpaceInsideParens
|
54
54
|
expect(subject.include_xy?( 0, 0)).to eql true
|
55
|
-
|
56
55
|
expect(subject.include_xy?(-1, 0)).to eql false
|
57
56
|
expect(subject.include_xy?( 1, 0)).to eql false
|
58
57
|
expect(subject.include_xy?( 0, -1)).to eql false
|
@@ -61,37 +60,38 @@ describe ChunkyPNG::Canvas do
|
|
61
60
|
expect(subject.include_xy?(-1, 1)).to eql false
|
62
61
|
expect(subject.include_xy?( 1, -1)).to eql false
|
63
62
|
expect(subject.include_xy?( 1, 1)).to eql false
|
63
|
+
# rubocop:enable Layout/SpaceInsideParens
|
64
64
|
end
|
65
65
|
|
66
66
|
it "should accept strings, arrays, hashes and points as well" do
|
67
|
-
expect(subject).to
|
68
|
-
subject.
|
69
|
-
expect(subject).to
|
70
|
-
subject.
|
71
|
-
expect(subject).to
|
72
|
-
subject.
|
73
|
-
expect(subject).to
|
74
|
-
subject.
|
67
|
+
expect(subject).to include("0, 0")
|
68
|
+
expect(subject).to_not include("0, 1")
|
69
|
+
expect(subject).to include([0, 0])
|
70
|
+
expect(subject).to_not include([0, 1])
|
71
|
+
expect(subject).to include(y: 0, x: 0)
|
72
|
+
expect(subject).to_not include(y: 1, x: 0)
|
73
|
+
expect(subject).to include(ChunkyPNG::Point.new(0, 0))
|
74
|
+
expect(subject).to_not include(ChunkyPNG::Point.new(0, 1))
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
-
describe
|
78
|
+
describe "#include_x?" do
|
79
79
|
it "should return true if the x-coordinate is within bounds, false otherwise" do
|
80
|
-
expect(subject.include_x?(
|
80
|
+
expect(subject.include_x?(0)).to eql true
|
81
81
|
expect(subject.include_x?(-1)).to eql false
|
82
|
-
expect(subject.include_x?(
|
82
|
+
expect(subject.include_x?(1)).to eql false
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
describe
|
86
|
+
describe "#include_y?" do
|
87
87
|
it "should return true if the y-coordinate is within bounds, false otherwise" do
|
88
|
-
expect(subject.include_y?(
|
88
|
+
expect(subject.include_y?(0)).to eql true
|
89
89
|
expect(subject.include_y?(-1)).to eql false
|
90
|
-
expect(subject.include_y?(
|
90
|
+
expect(subject.include_y?(1)).to eql false
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
-
describe
|
94
|
+
describe "#assert_xy!" do
|
95
95
|
it "should not raise an exception if the coordinates are within bounds" do
|
96
96
|
expect(subject).to receive(:include_xy?).with(0, 0).and_return(true)
|
97
97
|
expect { subject.send(:assert_xy!, 0, 0) }.to_not raise_error
|
@@ -103,7 +103,7 @@ describe ChunkyPNG::Canvas do
|
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
|
-
describe
|
106
|
+
describe "#assert_x!" do
|
107
107
|
it "should not raise an exception if the x-coordinate is within bounds" do
|
108
108
|
expect(subject).to receive(:include_x?).with(0).and_return(true)
|
109
109
|
expect { subject.send(:assert_x!, 0) }.to_not raise_error
|
@@ -115,7 +115,7 @@ describe ChunkyPNG::Canvas do
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
-
describe
|
118
|
+
describe "#[]" do
|
119
119
|
it "should return the pixel value if the coordinates are within bounds" do
|
120
120
|
expect(subject[0, 0]).to eql ChunkyPNG::Color::WHITE
|
121
121
|
end
|
@@ -126,7 +126,7 @@ describe ChunkyPNG::Canvas do
|
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
129
|
-
describe
|
129
|
+
describe "#get_pixel" do
|
130
130
|
it "should return the pixel value if the coordinates are within bounds" do
|
131
131
|
expect(subject.get_pixel(0, 0)).to eql ChunkyPNG::Color::WHITE
|
132
132
|
end
|
@@ -138,10 +138,11 @@ describe ChunkyPNG::Canvas do
|
|
138
138
|
end
|
139
139
|
end
|
140
140
|
|
141
|
-
describe
|
141
|
+
describe "#[]=" do
|
142
142
|
it "should change the pixel's color value" do
|
143
|
-
expect { subject[0, 0] = ChunkyPNG::Color::BLACK }.to change { subject[0, 0] }
|
144
|
-
from(ChunkyPNG::Color::WHITE)
|
143
|
+
expect { subject[0, 0] = ChunkyPNG::Color::BLACK }.to change { subject[0, 0] }
|
144
|
+
.from(ChunkyPNG::Color::WHITE)
|
145
|
+
.to(ChunkyPNG::Color::BLACK)
|
145
146
|
end
|
146
147
|
|
147
148
|
it "should assert the bounds of the image" do
|
@@ -150,10 +151,11 @@ describe ChunkyPNG::Canvas do
|
|
150
151
|
end
|
151
152
|
end
|
152
153
|
|
153
|
-
describe
|
154
|
+
describe "set_pixel" do
|
154
155
|
it "should change the pixel's color value" do
|
155
|
-
expect { subject.set_pixel(0, 0, ChunkyPNG::Color::BLACK) }.to change { subject[0, 0] }
|
156
|
-
|
156
|
+
expect { subject.set_pixel(0, 0, ChunkyPNG::Color::BLACK) }.to change { subject[0, 0] }
|
157
|
+
.from(ChunkyPNG::Color::WHITE)
|
158
|
+
.to(ChunkyPNG::Color::BLACK)
|
157
159
|
end
|
158
160
|
|
159
161
|
it "should not assert or check the bounds of the image" do
|
@@ -163,10 +165,11 @@ describe ChunkyPNG::Canvas do
|
|
163
165
|
end
|
164
166
|
end
|
165
167
|
|
166
|
-
describe
|
168
|
+
describe "#set_pixel_if_within_bounds" do
|
167
169
|
it "should change the pixel's color value" do
|
168
|
-
expect { subject.set_pixel_if_within_bounds(0, 0, ChunkyPNG::Color::BLACK) }.to change { subject[0, 0] }
|
169
|
-
|
170
|
+
expect { subject.set_pixel_if_within_bounds(0, 0, ChunkyPNG::Color::BLACK) }.to change { subject[0, 0] }
|
171
|
+
.from(ChunkyPNG::Color::WHITE)
|
172
|
+
.to(ChunkyPNG::Color::BLACK)
|
170
173
|
end
|
171
174
|
|
172
175
|
it "should not assert, but only check the coordinates" do
|
@@ -181,8 +184,8 @@ describe ChunkyPNG::Canvas do
|
|
181
184
|
end
|
182
185
|
end
|
183
186
|
|
184
|
-
describe
|
185
|
-
before { @canvas = reference_canvas(
|
187
|
+
describe "#row" do
|
188
|
+
before { @canvas = reference_canvas("operations") }
|
186
189
|
|
187
190
|
it "should give an out of bounds exception when y-coordinate is out of bounds" do
|
188
191
|
expect { @canvas.row(-1) }.to raise_error(ChunkyPNG::OutOfBounds)
|
@@ -196,8 +199,8 @@ describe ChunkyPNG::Canvas do
|
|
196
199
|
end
|
197
200
|
end
|
198
201
|
|
199
|
-
describe
|
200
|
-
before { @canvas = reference_canvas(
|
202
|
+
describe "#column" do
|
203
|
+
before { @canvas = reference_canvas("operations") }
|
201
204
|
|
202
205
|
it "should give an out of bounds exception when x-coordinate is out of bounds" do
|
203
206
|
expect { @canvas.column(-1) }.to raise_error(ChunkyPNG::OutOfBounds)
|
@@ -211,19 +214,21 @@ describe ChunkyPNG::Canvas do
|
|
211
214
|
end
|
212
215
|
end
|
213
216
|
|
214
|
-
describe
|
217
|
+
describe "#replace_canvas" do
|
215
218
|
it "should change the dimension of the canvas" do
|
216
|
-
expect { subject.send(:replace_canvas!, 2, 2, [1,2,3,4]) }.to change { subject.dimension }
|
217
|
-
|
219
|
+
expect { subject.send(:replace_canvas!, 2, 2, [1, 2, 3, 4]) }.to change { subject.dimension }
|
220
|
+
.from(ChunkyPNG::Dimension("1x1"))
|
221
|
+
.to(ChunkyPNG::Dimension("2x2"))
|
218
222
|
end
|
219
223
|
|
220
224
|
it "should change the pixel array" do
|
221
|
-
expect { subject.send(:replace_canvas!, 2, 2, [1,2,3,4]) }.to change { subject.pixels }
|
222
|
-
|
225
|
+
expect { subject.send(:replace_canvas!, 2, 2, [1, 2, 3, 4]) }.to change { subject.pixels }
|
226
|
+
.from([ChunkyPNG::Color("white")])
|
227
|
+
.to([1, 2, 3, 4])
|
223
228
|
end
|
224
229
|
|
225
230
|
it "should return itself" do
|
226
|
-
expect(subject.send(:replace_canvas!, 2, 2, [1,2,3,4])).to equal(subject)
|
231
|
+
expect(subject.send(:replace_canvas!, 2, 2, [1, 2, 3, 4])).to equal(subject)
|
227
232
|
end
|
228
233
|
end
|
229
234
|
end
|
@@ -1,22 +1,22 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
|
-
describe
|
4
|
-
it
|
3
|
+
describe "ChunyPNG.Color" do
|
4
|
+
it "should interpret 4 arguments as RGBA values" do
|
5
5
|
expect(ChunkyPNG::Color(1, 2, 3, 4)).to eql ChunkyPNG::Color.rgba(1, 2, 3, 4)
|
6
6
|
end
|
7
7
|
|
8
|
-
it
|
8
|
+
it "should interpret 3 arguments as RGBA values" do
|
9
9
|
expect(ChunkyPNG::Color(1, 2, 3)).to eql ChunkyPNG::Color.rgb(1, 2, 3)
|
10
10
|
end
|
11
11
|
|
12
|
-
it
|
13
|
-
expect(ChunkyPNG::Color(
|
14
|
-
expect(ChunkyPNG::Color(
|
12
|
+
it "should interpret 2 arguments as a color to parse and an opacity value" do
|
13
|
+
expect(ChunkyPNG::Color("0x0a649664", 0xaa)).to eql 0x0a6496aa
|
14
|
+
expect(ChunkyPNG::Color("spring green @ 0.6666", 0xff)).to eql 0x00ff7fff
|
15
15
|
end
|
16
16
|
|
17
|
-
it
|
18
|
-
expect(ChunkyPNG::Color).to receive(:parse).with(
|
19
|
-
ChunkyPNG::Color(
|
17
|
+
it "should interpret 1 argument as a color to parse" do
|
18
|
+
expect(ChunkyPNG::Color).to receive(:parse).with("0x0a649664")
|
19
|
+
ChunkyPNG::Color("0x0a649664")
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -34,85 +34,87 @@ describe ChunkyPNG::Color do
|
|
34
34
|
@blue = 0x0000ffff
|
35
35
|
end
|
36
36
|
|
37
|
-
describe
|
38
|
-
it
|
39
|
-
expect(parse(
|
37
|
+
describe "#parse" do
|
38
|
+
it "should interpret a hex string correctly" do
|
39
|
+
expect(parse("0x0a649664")).to eql ChunkyPNG::Color.from_hex("#0a649664")
|
40
40
|
end
|
41
41
|
|
42
|
-
it
|
42
|
+
it "should interpret a color name correctly" do
|
43
43
|
expect(parse(:spring_green)).to eql 0x00ff7fff
|
44
|
-
expect(parse(
|
45
|
-
expect(parse(
|
44
|
+
expect(parse("spring green")).to eql 0x00ff7fff
|
45
|
+
expect(parse("spring green @ 0.6666")).to eql 0x00ff7faa
|
46
46
|
end
|
47
47
|
|
48
|
-
it
|
49
|
-
expect(parse(
|
48
|
+
it "should return numbers as is" do
|
49
|
+
expect(parse("12345")).to eql 12345
|
50
50
|
expect(parse(12345)).to eql 12345
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
describe
|
55
|
-
it
|
54
|
+
describe "#pixel_bytesize" do
|
55
|
+
it "should return the normal amount of bytes with a bit depth of 8" do
|
56
56
|
expect(pixel_bytesize(ChunkyPNG::COLOR_TRUECOLOR, 8)).to eql 3
|
57
57
|
end
|
58
58
|
|
59
|
-
it
|
59
|
+
it "should return a multiple of the normal amount of bytes with a bit depth greater than 8" do
|
60
60
|
expect(pixel_bytesize(ChunkyPNG::COLOR_TRUECOLOR, 16)).to eql 6
|
61
61
|
expect(pixel_bytesize(ChunkyPNG::COLOR_TRUECOLOR_ALPHA, 16)).to eql 8
|
62
62
|
expect(pixel_bytesize(ChunkyPNG::COLOR_GRAYSCALE_ALPHA, 16)).to eql 4
|
63
63
|
end
|
64
64
|
|
65
|
-
it
|
65
|
+
it "should return 1 with a bit depth lower than 0" do
|
66
66
|
expect(pixel_bytesize(ChunkyPNG::COLOR_TRUECOLOR, 4)).to eql 1
|
67
67
|
expect(pixel_bytesize(ChunkyPNG::COLOR_INDEXED, 2)).to eql 1
|
68
68
|
expect(pixel_bytesize(ChunkyPNG::COLOR_GRAYSCALE_ALPHA, 1)).to eql 1
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
describe
|
73
|
-
it
|
72
|
+
describe "#pass_bytesize" do
|
73
|
+
it "should calculate a pass size correctly" do
|
74
74
|
expect(pass_bytesize(ChunkyPNG::COLOR_TRUECOLOR, 8, 10, 10)).to eql 310
|
75
75
|
end
|
76
76
|
|
77
|
-
it
|
77
|
+
it "should return 0 if one of the dimensions is zero" do
|
78
78
|
expect(pass_bytesize(ChunkyPNG::COLOR_TRUECOLOR, 8, 0, 10)).to eql 0
|
79
79
|
expect(pass_bytesize(ChunkyPNG::COLOR_TRUECOLOR, 8, 10, 0)).to eql 0
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
-
describe
|
84
|
-
it
|
83
|
+
describe "#rgba" do
|
84
|
+
it "should represent pixels as the correct number" do
|
85
|
+
# rubocop:disable Layout/ExtraSpacing, Layout/SpaceInsideParens
|
85
86
|
expect(rgba(255, 255, 255, 255)).to eql @white
|
86
87
|
expect(rgba( 0, 0, 0, 255)).to eql @black
|
87
88
|
expect(rgba( 10, 100, 150, 255)).to eql @opaque
|
88
89
|
expect(rgba( 10, 100, 150, 100)).to eql @non_opaque
|
89
90
|
expect(rgba( 10, 100, 150, 0)).to eql @fully_transparent
|
91
|
+
# rubocop:enable Layout/ExtraSpacing, Layout/SpaceInsideParens
|
90
92
|
end
|
91
93
|
end
|
92
94
|
|
93
|
-
describe
|
94
|
-
it
|
95
|
-
expect(from_hex(
|
96
|
-
expect(from_hex(
|
97
|
-
expect(from_hex(
|
98
|
-
expect(from_hex(
|
99
|
-
expect(from_hex(
|
100
|
-
expect(from_hex(
|
101
|
-
expect(from_hex(
|
102
|
-
expect(from_hex(
|
103
|
-
expect(from_hex(
|
104
|
-
end
|
105
|
-
|
106
|
-
it
|
107
|
-
expect(from_hex(
|
108
|
-
expect(from_hex(
|
109
|
-
expect(from_hex(
|
110
|
-
expect(from_hex(
|
95
|
+
describe "#from_hex" do
|
96
|
+
it "should load colors correctly from hex notation" do
|
97
|
+
expect(from_hex("0a649664")).to eql @non_opaque
|
98
|
+
expect(from_hex("#0a649664")).to eql @non_opaque
|
99
|
+
expect(from_hex("0x0a649664")).to eql @non_opaque
|
100
|
+
expect(from_hex("0a6496")).to eql @opaque
|
101
|
+
expect(from_hex("#0a6496")).to eql @opaque
|
102
|
+
expect(from_hex("0x0a6496")).to eql @opaque
|
103
|
+
expect(from_hex("abc")).to eql 0xaabbccff
|
104
|
+
expect(from_hex("#abc")).to eql 0xaabbccff
|
105
|
+
expect(from_hex("0xabc")).to eql 0xaabbccff
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should allow setting opacity explicitly" do
|
109
|
+
expect(from_hex("0x0a6496", 0x64)).to eql @non_opaque
|
110
|
+
expect(from_hex("#0a6496", 0x64)).to eql @non_opaque
|
111
|
+
expect(from_hex("0xabc", 0xdd)).to eql 0xaabbccdd
|
112
|
+
expect(from_hex("#abc", 0xdd)).to eql 0xaabbccdd
|
111
113
|
end
|
112
114
|
end
|
113
115
|
|
114
|
-
describe
|
115
|
-
it
|
116
|
+
describe "#from_hsv" do
|
117
|
+
it "should load colors correctly from an HSV triple" do
|
116
118
|
# At 0 brightness, should be @black independent of hue or sat
|
117
119
|
expect(from_hsv(0, 0, 0)).to eql @black
|
118
120
|
expect(from_hsv(100, 1, 0)).to eql @black
|
@@ -135,7 +137,7 @@ describe ChunkyPNG::Color do
|
|
135
137
|
expect(from_hsv(0, 0.5, 0.5)).to eql from_hsv(360.0, 0.5, 0.5)
|
136
138
|
end
|
137
139
|
|
138
|
-
it
|
140
|
+
it "should optionally accept a fourth param for alpha" do
|
139
141
|
expect(from_hsv(0, 1, 1, 255)).to eql @red
|
140
142
|
expect(from_hsv(120, 1, 1, 255)).to eql @green
|
141
143
|
expect(from_hsv(240, 1, 1, 255)).to eql @blue
|
@@ -145,8 +147,8 @@ describe ChunkyPNG::Color do
|
|
145
147
|
end
|
146
148
|
end
|
147
149
|
|
148
|
-
describe
|
149
|
-
it
|
150
|
+
describe "#from_hsl" do
|
151
|
+
it "should load colors correctly from an HSL triple" do
|
150
152
|
# At 0 lightness, should always be black
|
151
153
|
expect(from_hsl(0, 0, 0)).to eql @black
|
152
154
|
expect(from_hsl(100, 0, 0)).to eql @black
|
@@ -163,16 +165,16 @@ describe ChunkyPNG::Color do
|
|
163
165
|
expect(from_hsl(240, 1, 0.5)).to eql @blue
|
164
166
|
|
165
167
|
# Random colors
|
166
|
-
from_hsl(87.27, 0.5, 0.5686)
|
167
|
-
from_hsl(271.83, 0.5399, 0.4176)
|
168
|
-
from_hsl(63.6, 0.5984, 0.4882)
|
168
|
+
expect(from_hsl(87.27, 0.5, 0.5686)).to eql 0x95c759ff
|
169
|
+
expect(from_hsl(271.83, 0.5399, 0.4176)).to eql 0x6d30a3ff
|
170
|
+
expect(from_hsl(63.6, 0.5984, 0.4882)).to eql 0xbec631ff
|
169
171
|
|
170
172
|
# Hue 0 and hue 360 should be equivalent
|
171
173
|
expect(from_hsl(0, 0.5, 0.5)).to eql from_hsl(360, 0.5, 0.5)
|
172
174
|
expect(from_hsl(0, 0.5, 0.5)).to eql from_hsl(360.0, 0.5, 0.5)
|
173
175
|
end
|
174
176
|
|
175
|
-
it
|
177
|
+
it "should optionally accept a fourth param for alpha" do
|
176
178
|
expect(from_hsl(0, 1, 0.5, 255)).to eql @red
|
177
179
|
expect(from_hsl(120, 1, 0.5, 255)).to eql @green
|
178
180
|
expect(from_hsl(240, 1, 0.5, 255)).to eql @blue
|
@@ -182,35 +184,35 @@ describe ChunkyPNG::Color do
|
|
182
184
|
end
|
183
185
|
end
|
184
186
|
|
185
|
-
describe
|
186
|
-
it
|
187
|
+
describe "#html_color" do
|
188
|
+
it "should find the correct color value" do
|
187
189
|
expect(html_color(:springgreen)).to eql 0x00ff7fff
|
188
190
|
expect(html_color(:spring_green)).to eql 0x00ff7fff
|
189
|
-
expect(html_color(
|
190
|
-
expect(html_color(
|
191
|
-
expect(html_color(
|
192
|
-
expect(html_color(
|
191
|
+
expect(html_color("springgreen")).to eql 0x00ff7fff
|
192
|
+
expect(html_color("spring green")).to eql 0x00ff7fff
|
193
|
+
expect(html_color("SpringGreen")).to eql 0x00ff7fff
|
194
|
+
expect(html_color("SPRING_GREEN")).to eql 0x00ff7fff
|
193
195
|
end
|
194
196
|
|
195
|
-
it
|
197
|
+
it "should set the opacity level explicitly" do
|
196
198
|
expect(html_color(:springgreen, 0xff)).to eql 0x00ff7fff
|
197
199
|
expect(html_color(:springgreen, 0xaa)).to eql 0x00ff7faa
|
198
200
|
expect(html_color(:springgreen, 0x00)).to eql 0x00ff7f00
|
199
201
|
end
|
200
202
|
|
201
|
-
it
|
202
|
-
expect(html_color(
|
203
|
-
expect(html_color(
|
204
|
-
expect(html_color(
|
203
|
+
it "should set opacity levels from the color name" do
|
204
|
+
expect(html_color("Spring green @ 1.0")).to eql 0x00ff7fff
|
205
|
+
expect(html_color("Spring green @ 0.666")).to eql 0x00ff7faa
|
206
|
+
expect(html_color("Spring green @ 0.0")).to eql 0x00ff7f00
|
205
207
|
end
|
206
208
|
|
207
|
-
it
|
209
|
+
it "should raise for an unkown color name" do
|
208
210
|
expect { html_color(:nonsense) }.to raise_error(ArgumentError)
|
209
211
|
end
|
210
212
|
end
|
211
213
|
|
212
|
-
describe
|
213
|
-
it
|
214
|
+
describe "#opaque?" do
|
215
|
+
it "should correctly check for opaqueness" do
|
214
216
|
expect(opaque?(@white)).to eql true
|
215
217
|
expect(opaque?(@black)).to eql true
|
216
218
|
expect(opaque?(@opaque)).to eql true
|
@@ -219,8 +221,8 @@ describe ChunkyPNG::Color do
|
|
219
221
|
end
|
220
222
|
end
|
221
223
|
|
222
|
-
describe
|
223
|
-
it
|
224
|
+
describe "extraction of separate color channels" do
|
225
|
+
it "should extract components from a color correctly" do
|
224
226
|
expect(r(@opaque)).to eql 10
|
225
227
|
expect(g(@opaque)).to eql 100
|
226
228
|
expect(b(@opaque)).to eql 150
|
@@ -228,47 +230,47 @@ describe ChunkyPNG::Color do
|
|
228
230
|
end
|
229
231
|
end
|
230
232
|
|
231
|
-
describe
|
232
|
-
it
|
233
|
+
describe "#grayscale_teint" do
|
234
|
+
it "should calculate the correct grayscale teint" do
|
233
235
|
expect(grayscale_teint(@opaque)).to eql 79
|
234
236
|
expect(grayscale_teint(@non_opaque)).to eql 79
|
235
237
|
end
|
236
238
|
end
|
237
239
|
|
238
|
-
describe
|
239
|
-
it
|
240
|
+
describe "#to_grayscale" do
|
241
|
+
it "should use the grayscale teint for r, g and b" do
|
240
242
|
gs = to_grayscale(@non_opaque)
|
241
243
|
expect(r(gs)).to eql grayscale_teint(@non_opaque)
|
242
244
|
expect(g(gs)).to eql grayscale_teint(@non_opaque)
|
243
245
|
expect(b(gs)).to eql grayscale_teint(@non_opaque)
|
244
246
|
end
|
245
247
|
|
246
|
-
it
|
248
|
+
it "should preserve the alpha channel" do
|
247
249
|
expect(a(to_grayscale(@non_opaque))).to eql a(@non_opaque)
|
248
250
|
expect(a(to_grayscale(@opaque))).to eql ChunkyPNG::Color::MAX
|
249
251
|
end
|
250
252
|
end
|
251
253
|
|
252
|
-
describe
|
253
|
-
it
|
254
|
-
expect(to_hex(@white)).to eql
|
255
|
-
expect(to_hex(@black)).to eql
|
256
|
-
expect(to_hex(@opaque)).to eql
|
257
|
-
expect(to_hex(@non_opaque)).to eql
|
258
|
-
expect(to_hex(@fully_transparent)).to eql
|
254
|
+
describe "#to_hex" do
|
255
|
+
it "should represent colors correcly using hex notation" do
|
256
|
+
expect(to_hex(@white)).to eql "#ffffffff"
|
257
|
+
expect(to_hex(@black)).to eql "#000000ff"
|
258
|
+
expect(to_hex(@opaque)).to eql "#0a6496ff"
|
259
|
+
expect(to_hex(@non_opaque)).to eql "#0a649664"
|
260
|
+
expect(to_hex(@fully_transparent)).to eql "#0a649600"
|
259
261
|
end
|
260
262
|
|
261
|
-
it
|
262
|
-
expect(to_hex(@white, false)).to eql
|
263
|
-
expect(to_hex(@black, false)).to eql
|
264
|
-
expect(to_hex(@opaque, false)).to eql
|
265
|
-
expect(to_hex(@non_opaque, false)).to eql
|
266
|
-
expect(to_hex(@fully_transparent, false)).to eql
|
263
|
+
it "should represent colors correcly using hex notation without alpha channel" do
|
264
|
+
expect(to_hex(@white, false)).to eql "#ffffff"
|
265
|
+
expect(to_hex(@black, false)).to eql "#000000"
|
266
|
+
expect(to_hex(@opaque, false)).to eql "#0a6496"
|
267
|
+
expect(to_hex(@non_opaque, false)).to eql "#0a6496"
|
268
|
+
expect(to_hex(@fully_transparent, false)).to eql "#0a6496"
|
267
269
|
end
|
268
270
|
end
|
269
271
|
|
270
|
-
describe
|
271
|
-
it
|
272
|
+
describe "#to_hsv" do
|
273
|
+
it "should return a [hue, saturation, value] array" do
|
272
274
|
expect(to_hsv(@white)).to eql [0, 0.0, 1.0]
|
273
275
|
expect(to_hsv(@black)).to eql [0, 0.0, 0.0]
|
274
276
|
expect(to_hsv(@red)).to eql [0, 1.0, 1.0]
|
@@ -279,7 +281,7 @@ describe ChunkyPNG::Color do
|
|
279
281
|
expect(to_hsv(0x805440ff)[2]).to be_within(0.01).of(0.5)
|
280
282
|
end
|
281
283
|
|
282
|
-
it
|
284
|
+
it "should optionally include the alpha channel" do
|
283
285
|
expect(to_hsv(@white, true)).to eql [0, 0.0, 1.0, 255]
|
284
286
|
expect(to_hsv(@red, true)).to eql [0, 1.0, 1.0, 255]
|
285
287
|
expect(to_hsv(@blue, true)).to eql [240, 1.0, 1.0, 255]
|
@@ -289,8 +291,8 @@ describe ChunkyPNG::Color do
|
|
289
291
|
end
|
290
292
|
end
|
291
293
|
|
292
|
-
describe
|
293
|
-
it
|
294
|
+
describe "#to_hsl" do
|
295
|
+
it "should return a [hue, saturation, lightness] array" do
|
294
296
|
expect(to_hsl(@white)).to eql [0, 0.0, 1.0]
|
295
297
|
expect(to_hsl(@black)).to eql [0, 0.0, 0.0]
|
296
298
|
expect(to_hsl(@red)).to eql [0, 1.0, 0.5]
|
@@ -298,7 +300,7 @@ describe ChunkyPNG::Color do
|
|
298
300
|
expect(to_hsl(@green)).to eql [120, 1.0, 0.5]
|
299
301
|
end
|
300
302
|
|
301
|
-
it
|
303
|
+
it "should optionally include the alpha channel in the returned array" do
|
302
304
|
expect(to_hsl(@white, true)).to eql [0, 0.0, 1.0, 255]
|
303
305
|
expect(to_hsl(@black, true)).to eql [0, 0.0, 0.0, 255]
|
304
306
|
expect(to_hsl(@red, true)).to eql [0, 1.0, 0.5, 255]
|
@@ -309,79 +311,78 @@ describe ChunkyPNG::Color do
|
|
309
311
|
end
|
310
312
|
end
|
311
313
|
|
312
|
-
describe
|
313
|
-
it
|
314
|
+
describe "conversion to other formats" do
|
315
|
+
it "should convert the individual color values back correctly" do
|
314
316
|
expect(to_truecolor_bytes(@opaque)).to eql [10, 100, 150]
|
315
317
|
expect(to_truecolor_alpha_bytes(@non_opaque)).to eql [10, 100, 150, 100]
|
316
318
|
end
|
317
319
|
end
|
318
320
|
|
319
|
-
describe
|
320
|
-
|
321
|
-
it 'should use the foregorund color as is when the background color is fully transparent' do
|
321
|
+
describe "#compose" do
|
322
|
+
it "should use the foregorund color as is when the background color is fully transparent" do
|
322
323
|
expect(compose(@non_opaque, @fully_transparent)).to eql @non_opaque
|
323
324
|
end
|
324
325
|
|
325
|
-
it
|
326
|
+
it "should use the foregorund color as is when an opaque color is given as foreground color" do
|
326
327
|
expect(compose(@opaque, @white)).to eql @opaque
|
327
328
|
end
|
328
329
|
|
329
|
-
it
|
330
|
+
it "should use the background color as is when a fully transparent pixel is given as foreground color" do
|
330
331
|
expect(compose(@fully_transparent, @white)).to eql @white
|
331
332
|
end
|
332
333
|
|
333
|
-
it
|
334
|
+
it "should compose pixels correctly with both algorithms" do
|
334
335
|
expect(compose_quick(@non_opaque, @white)).to eql 0x9fc2d6ff
|
335
336
|
expect(compose_precise(@non_opaque, @white)).to eql 0x9fc2d6ff
|
336
337
|
end
|
337
338
|
end
|
338
339
|
|
339
|
-
describe
|
340
|
-
it
|
340
|
+
describe "#decompose_alpha" do
|
341
|
+
it "should decompose the alpha channel correctly" do
|
341
342
|
expect(decompose_alpha(0x9fc2d6ff, @opaque, @white)).to eql 0x00000064
|
342
343
|
end
|
343
344
|
|
344
|
-
it
|
345
|
+
it "should return fully transparent if the background channel matches the resulting color" do
|
345
346
|
expect(decompose_alpha(0xabcdefff, 0xff000000, 0xabcdefff)).to eql 0x00
|
346
347
|
end
|
347
348
|
|
348
|
-
it
|
349
|
+
it "should return fully opaque if the background channel matches the mask color" do
|
349
350
|
expect(decompose_alpha(0xff000000, 0xabcdefff, 0xabcdefff)).to eql 0xff
|
350
351
|
end
|
351
352
|
|
352
|
-
it
|
353
|
+
it "should return fully opaque if the resulting color matches the mask color" do
|
353
354
|
expect(decompose_alpha(0xabcdefff, 0xabcdefff, 0xffffffff)).to eql 255
|
354
355
|
end
|
355
356
|
end
|
356
357
|
|
357
|
-
describe
|
358
|
-
it
|
358
|
+
describe "#blend" do
|
359
|
+
it "should blend colors correctly" do
|
359
360
|
expect(blend(@opaque, @black)).to eql 0x05324bff
|
360
361
|
end
|
361
362
|
|
362
|
-
it
|
363
|
+
it "should not matter what color is used as foreground, and what as background" do
|
363
364
|
expect(blend(@opaque, @black)).to eql blend(@black, @opaque)
|
364
365
|
end
|
365
366
|
end
|
366
367
|
|
367
|
-
describe
|
368
|
+
describe "#euclidean_distance_rgba" do
|
368
369
|
subject { euclidean_distance_rgba(color_a, color_b) }
|
369
370
|
|
370
|
-
context
|
371
|
+
context "with white and black" do
|
371
372
|
let(:color_a) { @white }
|
372
373
|
let(:color_b) { @black }
|
373
374
|
|
374
375
|
it { should == Math.sqrt(195_075) } # sqrt(255^2 * 3)
|
375
376
|
end
|
376
377
|
|
377
|
-
context
|
378
|
+
context "with black and white" do
|
378
379
|
let(:color_a) { @black }
|
379
380
|
let(:color_b) { @white }
|
380
381
|
|
381
382
|
it { should == Math.sqrt(195_075) } # sqrt(255^2 * 3)
|
382
383
|
end
|
383
384
|
|
384
|
-
context
|
385
|
+
context "with the same colors" do
|
385
386
|
let(:color_a) { @white }
|
386
387
|
let(:color_b) { @white }
|
387
388
|
|