pnm 0.3.4 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/lib/pnm.rb +39 -4
- data/lib/pnm/image.rb +213 -108
- data/lib/pnm/version.rb +2 -2
- data/test/test_exceptions.rb +22 -22
- data/test/test_image.rb +23 -23
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b65acf13eeae10d44cdb6819968ab967f240ec92
|
4
|
+
data.tar.gz: ac881cf1d053ee6110a2624c62092d1e93623414
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa018e4a6f04380252ba21c8a8e572138f55f78c57c2b67a1a2bedf7afdd3108287a2c283654177e163e9bc8d5df0ec3ca67a6906a4c678cd7bcf76b30499f63
|
7
|
+
data.tar.gz: 30ac4d58dd7ced728223abec188313480c19043908548a7a550c490c1dc745c47156886c22685c5d523ffbc782ea640289b5355a829c0f68c903110b79ff407f
|
data/README.md
CHANGED
@@ -30,7 +30,7 @@ pixels = [[ 0, 10, 20],
|
|
30
30
|
options = {:maxgray => 30, :comment => 'Test Image'}
|
31
31
|
|
32
32
|
# create the image object
|
33
|
-
image = PNM
|
33
|
+
image = PNM.create(pixels, options)
|
34
34
|
|
35
35
|
# retrieve some image properties
|
36
36
|
image.info # => "PGM 3x2 Grayscale"
|
@@ -43,7 +43,7 @@ Note that for PBM bilevel images a pixel value of 0 signifies white
|
|
43
43
|
(and 1 signifies black), whereas for PGM and PPM images a value of 0
|
44
44
|
signifies black.
|
45
45
|
|
46
|
-
See PNM
|
46
|
+
See PNM.create for a more detailed description of pixel data formats
|
47
47
|
and available options.
|
48
48
|
|
49
49
|
Write an image to a file:
|
@@ -70,7 +70,7 @@ image.pixels # => [[0, 10, 20], [10, 20, 30]]
|
|
70
70
|
Force an image type:
|
71
71
|
|
72
72
|
``` ruby
|
73
|
-
image = PNM
|
73
|
+
image = PNM.create([[0, 1],[1, 0]], :type => :ppm)
|
74
74
|
image.info # => "PPM 2x2 Color"
|
75
75
|
```
|
76
76
|
|
data/lib/pnm.rb
CHANGED
@@ -36,7 +36,7 @@ require_relative 'pnm/exceptions'
|
|
36
36
|
# options = {:maxgray => 30, :comment => 'Test Image'}
|
37
37
|
#
|
38
38
|
# # create the image object
|
39
|
-
# image = PNM
|
39
|
+
# image = PNM.create(pixels, options)
|
40
40
|
#
|
41
41
|
# # retrieve some image properties
|
42
42
|
# image.info # => "PGM 3x2 Grayscale"
|
@@ -48,7 +48,7 @@ require_relative 'pnm/exceptions'
|
|
48
48
|
# (and 1 signifies black), whereas for PGM and PPM images a value of 0
|
49
49
|
# signifies black.
|
50
50
|
#
|
51
|
-
# See PNM
|
51
|
+
# See PNM.create for a more detailed description of pixel data formats
|
52
52
|
# and available options.
|
53
53
|
#
|
54
54
|
# Write an image to a file:
|
@@ -70,7 +70,7 @@ require_relative 'pnm/exceptions'
|
|
70
70
|
#
|
71
71
|
# Force an image type:
|
72
72
|
#
|
73
|
-
# image = PNM
|
73
|
+
# image = PNM.create([[0, 1],[1, 0]], :type => :ppm)
|
74
74
|
# image.info # => "PPM 2x2 Color"
|
75
75
|
#
|
76
76
|
# == See also
|
@@ -145,7 +145,42 @@ module PNM
|
|
145
145
|
options = {:type => type, :maxgray => maxgray}
|
146
146
|
options[:comment] = content[:comments].join("\n") if content[:comments]
|
147
147
|
|
148
|
-
|
148
|
+
create(pixels, options)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Creates an image from a two-dimensional array of bilevel,
|
152
|
+
# gray, or RGB values.
|
153
|
+
# The image type is guessed from the provided pixel data,
|
154
|
+
# unless it is explicitly set with the +type+ option.
|
155
|
+
#
|
156
|
+
# +pixels+:: The pixel data, given as a two-dimensional array of
|
157
|
+
#
|
158
|
+
# * for PBM: bilevel values of 0 (white) or 1 (black),
|
159
|
+
# * for PGM: gray values between 0 (black) and +maxgray+ (white),
|
160
|
+
# * for PPM: an array of 3 values between 0 and +maxgray+,
|
161
|
+
# corresponding to red, green, and blue (RGB);
|
162
|
+
# a value of 0 means that the color is turned off.
|
163
|
+
#
|
164
|
+
# Optional settings that can be specified in the +options+ hash:
|
165
|
+
#
|
166
|
+
# +type+:: The type of the image (+:pbm+, +:pgm+, or +:ppm+).
|
167
|
+
# By explicitly setting +type+, PGM images can be
|
168
|
+
# created from bilevel pixel data, and PPM images can be
|
169
|
+
# created from bilevel or gray pixel data.
|
170
|
+
# String values (<tt>"pbm"</tt>, <tt>"pgm"</tt>,
|
171
|
+
# or <tt>"ppm"</tt>) are also accepted.
|
172
|
+
# +maxgray+:: The maximum gray or color value.
|
173
|
+
# For PGM and PPM, +maxgray+ must be less or equal 255
|
174
|
+
# (the default value).
|
175
|
+
# For bilevel pixel data, setting +maxgray+ to a value
|
176
|
+
# greater than 1 implies a type of +:pgm+.
|
177
|
+
# When +type+ is explicitly set to +:pbm+,
|
178
|
+
# the +maxgray+ setting is disregarded.
|
179
|
+
# +comment+:: A multiline comment string.
|
180
|
+
#
|
181
|
+
# Returns a PNM::Image object.
|
182
|
+
def self.create(pixels, options = {})
|
183
|
+
Image.create(pixels, options)
|
149
184
|
end
|
150
185
|
|
151
186
|
# @private
|
data/lib/pnm/image.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
module PNM
|
2
2
|
|
3
|
-
#
|
3
|
+
# Abstract base class for +PBM+, +PGM+, and +PPM+ images.
|
4
4
|
#
|
5
|
-
# Images can be created from pixel values, see
|
5
|
+
# Images can be created from pixel values, see PNM.create,
|
6
6
|
# or read from a file or I/O stream, see PNM.read.
|
7
7
|
#
|
8
8
|
# See PNM module for examples.
|
9
9
|
class Image
|
10
10
|
|
11
|
-
# The type of the image. See
|
12
|
-
|
11
|
+
# The type of the image. See PNM.create for details.
|
12
|
+
def type
|
13
|
+
# implemented by subclasses
|
14
|
+
end
|
13
15
|
|
14
16
|
# The width of the image in pixels.
|
15
17
|
attr_reader :width
|
@@ -18,11 +20,11 @@ module PNM
|
|
18
20
|
attr_reader :height
|
19
21
|
|
20
22
|
# The maximum gray or color value (for PBM always set to 1).
|
21
|
-
# See
|
23
|
+
# See PNM.create for details.
|
22
24
|
attr_reader :maxgray
|
23
25
|
|
24
26
|
# The pixel data, given as a two-dimensional array.
|
25
|
-
# See
|
27
|
+
# See PNM.create for details.
|
26
28
|
attr_reader :pixels
|
27
29
|
|
28
30
|
# An optional multiline comment string (or +nil+).
|
@@ -30,64 +32,54 @@ module PNM
|
|
30
32
|
|
31
33
|
# Creates an image from a two-dimensional array of bilevel,
|
32
34
|
# gray, or RGB values.
|
33
|
-
# The image type is guessed from the provided pixel data,
|
34
|
-
# unless it is explicitly set with the +type+ option.
|
35
|
-
#
|
36
|
-
# +pixels+:: The pixel data, given as a two-dimensional array of
|
37
|
-
#
|
38
|
-
# * for PBM: bilevel values of 0 (white) or 1 (black),
|
39
|
-
# * for PGM: gray values between 0 (black) and +maxgray+ (white),
|
40
|
-
# * for PPM: an array of 3 values between 0 and +maxgray+,
|
41
|
-
# corresponding to red, green, and blue (RGB);
|
42
|
-
# a value of 0 means that the color is turned off.
|
43
35
|
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
@type = options[:type]
|
62
|
-
@maxgray = options[:maxgray]
|
63
|
-
@comment = options[:comment]
|
64
|
-
@pixels = pixels.dup
|
36
|
+
# This method should be called as PNM.create.
|
37
|
+
# See there for a description of pixel data formats
|
38
|
+
# and available options.
|
39
|
+
def self.create(pixels, options = {})
|
40
|
+
assert_valid_array(pixels)
|
41
|
+
assert_valid_maxgray(options[:maxgray])
|
42
|
+
assert_valid_comment(options[:comment])
|
43
|
+
|
44
|
+
type = sanitize_and_assert_valid_type(options[:type])
|
45
|
+
type ||= detect_type(pixels, options[:maxgray])
|
46
|
+
|
47
|
+
# except for type detection, the maxgray option must be ignored for PBM
|
48
|
+
if type == :pbm
|
49
|
+
maxgray = nil
|
50
|
+
else
|
51
|
+
maxgray = options[:maxgray]
|
52
|
+
end
|
65
53
|
|
66
|
-
|
54
|
+
image_class = case type
|
55
|
+
when :pbm
|
56
|
+
PBMImage
|
57
|
+
when :pgm
|
58
|
+
PGMImage
|
59
|
+
when :ppm
|
60
|
+
PPMImage
|
61
|
+
end
|
67
62
|
|
68
|
-
|
69
|
-
|
70
|
-
assert_valid_comment if @comment
|
71
|
-
assert_valid_array
|
63
|
+
image_class.new(pixels, maxgray, options[:comment])
|
64
|
+
end
|
72
65
|
|
66
|
+
class << self
|
67
|
+
protected :new
|
68
|
+
end
|
69
|
+
|
70
|
+
# @private
|
71
|
+
#
|
72
|
+
# Invoked by ::create after basic input validations.
|
73
|
+
def initialize(pixels, maxgray, comment) # :nodoc:
|
74
|
+
@pixels = pixels.dup
|
73
75
|
@width = pixels.first.size
|
74
76
|
@height = pixels.size
|
77
|
+
@maxgray = maxgray || default_maxgray
|
78
|
+
@comment = comment
|
75
79
|
|
76
|
-
|
77
|
-
|
78
|
-
assert_matching_type_and_data
|
79
|
-
|
80
|
-
if @type == :pbm
|
81
|
-
@maxgray = 1
|
82
|
-
else
|
83
|
-
@maxgray ||= 255
|
84
|
-
end
|
85
|
-
|
86
|
-
assert_valid_pixel_values
|
80
|
+
assert_pixel_value_range
|
87
81
|
|
88
|
-
|
89
|
-
@pixels.map! {|row| row.map {|pixel| gray_to_rgb(pixel) } }
|
90
|
-
end
|
82
|
+
post_initialize
|
91
83
|
end
|
92
84
|
|
93
85
|
# Writes the image to +file+ (a filename or an IO object),
|
@@ -119,65 +111,46 @@ module PNM
|
|
119
111
|
|
120
112
|
# Returns a string representation for debugging.
|
121
113
|
def inspect
|
122
|
-
|
123
|
-
"#<%s:0x%x %s>" % [self.class.name, object_id, info]
|
124
|
-
else
|
125
|
-
"#<%s:0x%x %s, maxgray=%d>" % [self.class.name, object_id, info, maxgray]
|
126
|
-
end
|
114
|
+
# implemented by subclasses
|
127
115
|
end
|
128
116
|
|
129
117
|
private
|
130
118
|
|
131
|
-
def
|
132
|
-
|
133
|
-
|
134
|
-
'Bilevel'
|
135
|
-
when :pgm
|
136
|
-
'Grayscale'
|
137
|
-
when :ppm
|
138
|
-
'Color'
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
def detect_type(pixels, maxgray) # :nodoc:
|
143
|
-
if pixels.first.first.kind_of?(Array)
|
144
|
-
:ppm
|
145
|
-
elsif (maxgray && maxgray > 1) || pixels.flatten.max > 1
|
146
|
-
:pgm
|
147
|
-
else
|
148
|
-
:pbm
|
149
|
-
end
|
119
|
+
def self.assert_valid_array(pixels) # :nodoc:
|
120
|
+
assert_array_dimensions(pixels)
|
121
|
+
assert_pixel_types(pixels)
|
150
122
|
end
|
151
123
|
|
152
|
-
def
|
124
|
+
def self.assert_array_dimensions(pixels) # :nodoc:
|
153
125
|
msg = "invalid pixel data: Array expected"
|
154
126
|
raise PNM::ArgumentError, msg unless Array === pixels
|
155
127
|
|
156
128
|
msg = "invalid pixel array"
|
157
|
-
raise PNM::DataError, msg unless Array === pixels.first
|
158
129
|
|
130
|
+
raise PNM::DataError, msg unless pixels.map(&:class).uniq == [Array]
|
159
131
|
width = pixels.first.size
|
160
|
-
|
132
|
+
raise PNM::DataError, msg unless pixels.map(&:size).uniq == [width]
|
133
|
+
end
|
161
134
|
|
162
|
-
|
163
|
-
|
135
|
+
def self.assert_pixel_types(pixels) # :nodoc:
|
136
|
+
pixel_values = pixels.flatten(1)
|
137
|
+
is_color = (Array === pixel_values.first)
|
164
138
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
end
|
139
|
+
if is_color
|
140
|
+
pixel_values.each {|pixel| assert_valid_color_pixel(pixel) }
|
141
|
+
else
|
142
|
+
pixel_values.each {|pixel| assert_valid_pixel(pixel) }
|
170
143
|
end
|
171
144
|
end
|
172
145
|
|
173
|
-
def assert_valid_pixel(pixel) # :nodoc:
|
146
|
+
def self.assert_valid_pixel(pixel) # :nodoc:
|
174
147
|
unless Fixnum === pixel
|
175
148
|
msg = "invalid pixel value: Fixnum expected - #{pixel.inspect}"
|
176
149
|
raise PNM::DataError, msg
|
177
150
|
end
|
178
151
|
end
|
179
152
|
|
180
|
-
def assert_valid_color_pixel(pixel) # :nodoc:
|
153
|
+
def self.assert_valid_color_pixel(pixel) # :nodoc:
|
181
154
|
unless Array === pixel && pixel.map(&:class) == [Fixnum, Fixnum, Fixnum]
|
182
155
|
msg = "invalid pixel value: "
|
183
156
|
msg << "Array of 3 Fixnums expected - #{pixel.inspect}"
|
@@ -186,33 +159,53 @@ module PNM
|
|
186
159
|
end
|
187
160
|
end
|
188
161
|
|
189
|
-
def
|
162
|
+
def self.assert_valid_maxgray(maxgray) # :nodoc:
|
163
|
+
return unless maxgray
|
164
|
+
|
165
|
+
unless Fixnum === maxgray && maxgray > 0 && maxgray <= 255
|
166
|
+
raise PNM::ArgumentError, "invalid maxgray value - #{maxgray.inspect}"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def self.assert_valid_comment(comment) # :nodoc:
|
171
|
+
return unless comment
|
172
|
+
|
173
|
+
unless String === comment
|
174
|
+
raise PNM::ArgumentError, "invalid comment value - #{comment.inspect}"
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def self.sanitize_and_assert_valid_type(type) # :nodoc:
|
179
|
+
return unless type
|
180
|
+
|
181
|
+
type = type.to_sym if type.kind_of?(String)
|
182
|
+
|
190
183
|
unless [:pbm, :pgm, :ppm].include?(type)
|
191
184
|
msg = "invalid image type - #{type.inspect}"
|
192
185
|
raise PNM::ArgumentError, msg
|
193
186
|
end
|
194
|
-
end
|
195
187
|
|
196
|
-
|
197
|
-
if Array === pixels.first.first && [:pbm, :pgm].include?(type)
|
198
|
-
msg = "specified type does not match data - #{type.inspect}"
|
199
|
-
raise PNM::DataError, msg
|
200
|
-
end
|
188
|
+
type
|
201
189
|
end
|
202
190
|
|
203
|
-
def
|
204
|
-
|
205
|
-
|
191
|
+
def self.detect_type(pixels, maxgray) # :nodoc:
|
192
|
+
if pixels.first.first.kind_of?(Array)
|
193
|
+
:ppm
|
194
|
+
elsif (maxgray && maxgray > 1) || pixels.flatten.max > 1
|
195
|
+
:pgm
|
196
|
+
else
|
197
|
+
:pbm
|
206
198
|
end
|
207
199
|
end
|
208
200
|
|
209
|
-
def
|
210
|
-
|
211
|
-
|
201
|
+
def assert_grayscale_data # :nodoc:
|
202
|
+
if color_pixels?
|
203
|
+
msg = "specified type does not match RGB data - #{type.inspect}"
|
204
|
+
raise PNM::DataError, msg
|
212
205
|
end
|
213
206
|
end
|
214
207
|
|
215
|
-
def
|
208
|
+
def assert_pixel_value_range # :nodoc:
|
216
209
|
unless pixels.flatten.max <= maxgray
|
217
210
|
raise PNM::DataError, "invalid data: value(s) greater than maxgray"
|
218
211
|
end
|
@@ -221,17 +214,20 @@ module PNM
|
|
221
214
|
end
|
222
215
|
end
|
223
216
|
|
224
|
-
def
|
217
|
+
def header_without_maxgray(encoding) # :nodoc:
|
225
218
|
header = "#{PNM.magic_number[type][encoding]}\n"
|
226
219
|
comment_lines.each do |line|
|
227
220
|
header << (line.empty? ? "#\n" : "# #{line}\n")
|
228
221
|
end
|
229
222
|
header << "#{width} #{height}\n"
|
230
|
-
header << "#{maxgray}\n" unless type == :pbm
|
231
223
|
|
232
224
|
header
|
233
225
|
end
|
234
226
|
|
227
|
+
def header_with_maxgray(encoding) # :nodoc:
|
228
|
+
header_without_maxgray(encoding) << "#{maxgray}\n"
|
229
|
+
end
|
230
|
+
|
235
231
|
def comment_lines # :nodoc:
|
236
232
|
return [] unless comment
|
237
233
|
return [''] if comment.empty?
|
@@ -252,6 +248,115 @@ module PNM
|
|
252
248
|
header(:binary) << data_string
|
253
249
|
end
|
254
250
|
|
251
|
+
def color_pixels? # :nodoc:
|
252
|
+
(pixels.first.first).kind_of?(Array)
|
253
|
+
end
|
254
|
+
|
255
|
+
def inspect_string_with_maxgray # :nodoc:
|
256
|
+
"#<%s:0x%x %s, maxgray=%d>" % [self.class.name, object_id, info, maxgray]
|
257
|
+
end
|
258
|
+
|
259
|
+
def inspect_string_without_maxgray # :nodoc:
|
260
|
+
"#<%s:0x%x %s>" % [self.class.name, object_id, info]
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
|
265
|
+
# Class for +PBM+ images. See the Image class for documentation.
|
266
|
+
class PBMImage < Image
|
267
|
+
|
268
|
+
def type
|
269
|
+
:pbm
|
270
|
+
end
|
271
|
+
|
272
|
+
def inspect
|
273
|
+
inspect_string_without_maxgray
|
274
|
+
end
|
275
|
+
|
276
|
+
private
|
277
|
+
|
278
|
+
def post_initialize # :nodoc:
|
279
|
+
assert_grayscale_data
|
280
|
+
end
|
281
|
+
|
282
|
+
def default_maxgray # :nodoc:
|
283
|
+
1
|
284
|
+
end
|
285
|
+
|
286
|
+
def type_string # :nodoc:
|
287
|
+
"Bilevel"
|
288
|
+
end
|
289
|
+
|
290
|
+
def header(encoding) # :nodoc:
|
291
|
+
header_without_maxgray(encoding)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
|
296
|
+
# Class for +PGM+ images. See the Image class for documentation.
|
297
|
+
class PGMImage < Image
|
298
|
+
|
299
|
+
def type
|
300
|
+
:pgm
|
301
|
+
end
|
302
|
+
|
303
|
+
def inspect
|
304
|
+
inspect_string_with_maxgray
|
305
|
+
end
|
306
|
+
|
307
|
+
private
|
308
|
+
|
309
|
+
def post_initialize # :nodoc:
|
310
|
+
assert_grayscale_data
|
311
|
+
end
|
312
|
+
|
313
|
+
def default_maxgray # :nodoc:
|
314
|
+
255
|
315
|
+
end
|
316
|
+
|
317
|
+
def type_string # :nodoc:
|
318
|
+
"Grayscale"
|
319
|
+
end
|
320
|
+
|
321
|
+
def header(encoding) # :nodoc:
|
322
|
+
header_with_maxgray(encoding)
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
|
327
|
+
# Class for +PPM+ images. See the Image class for documentation.
|
328
|
+
class PPMImage < Image
|
329
|
+
|
330
|
+
def type
|
331
|
+
:ppm
|
332
|
+
end
|
333
|
+
|
334
|
+
def inspect
|
335
|
+
inspect_string_with_maxgray
|
336
|
+
end
|
337
|
+
|
338
|
+
private
|
339
|
+
|
340
|
+
def post_initialize # :nodoc:
|
341
|
+
convert_pixels_to_color unless color_pixels?
|
342
|
+
end
|
343
|
+
|
344
|
+
def default_maxgray # :nodoc:
|
345
|
+
255
|
346
|
+
end
|
347
|
+
|
348
|
+
def type_string # :nodoc:
|
349
|
+
"Color"
|
350
|
+
end
|
351
|
+
|
352
|
+
def header(encoding) # :nodoc:
|
353
|
+
header_with_maxgray(encoding)
|
354
|
+
end
|
355
|
+
|
356
|
+
def convert_pixels_to_color # :nodoc:
|
357
|
+
pixels.map! {|row| row.map {|pixel| gray_to_rgb(pixel) } }
|
358
|
+
end
|
359
|
+
|
255
360
|
def gray_to_rgb(gray_value) # :nodoc:
|
256
361
|
Array.new(3, gray_value)
|
257
362
|
end
|
data/lib/pnm/version.rb
CHANGED
data/test/test_exceptions.rb
CHANGED
@@ -7,111 +7,111 @@ require 'stringio'
|
|
7
7
|
require 'pnm'
|
8
8
|
|
9
9
|
|
10
|
-
describe 'PNM
|
10
|
+
describe 'PNM.create' do
|
11
11
|
|
12
12
|
it 'raises an exception for invalid data type (String)' do
|
13
13
|
data = '0'
|
14
|
-
lambda { PNM
|
14
|
+
lambda { PNM.create(data) }.must_raise PNM::ArgumentError
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'raises an exception for invalid type' do
|
18
18
|
data = [[0, 0], [0, 0]]
|
19
|
-
lambda { PNM
|
19
|
+
lambda { PNM.create(data, :type => :abc) }.must_raise PNM::ArgumentError
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'raises an exception for invalid maxgray (String)' do
|
23
23
|
data = [[0, 0], [0, 0]]
|
24
|
-
lambda { PNM
|
24
|
+
lambda { PNM.create(data, :maxgray => '255') }.must_raise PNM::ArgumentError
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'raises an exception for invalid maxgray (> 255)' do
|
28
28
|
data = [[0, 0], [0, 0]]
|
29
|
-
lambda { PNM
|
29
|
+
lambda { PNM.create(data, :maxgray => 256) }.must_raise PNM::ArgumentError
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'raises an exception for invalid maxgray (0)' do
|
33
33
|
data = [[0, 0], [0, 0]]
|
34
|
-
lambda { PNM
|
34
|
+
lambda { PNM.create(data, :maxgray => 0) }.must_raise PNM::ArgumentError
|
35
35
|
end
|
36
36
|
|
37
37
|
it 'raises an exception for invalid comment (Fixnum)' do
|
38
38
|
data = [[0, 0], [0, 0]]
|
39
|
-
lambda { PNM
|
39
|
+
lambda { PNM.create(data, :comment => 1) }.must_raise PNM::ArgumentError
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'raises an exception for image type and data mismatch (PBM)' do
|
43
43
|
data = [[[0,0,0], [0,0,0]], [[0,0,0], [0,0,0]]]
|
44
|
-
lambda { PNM
|
44
|
+
lambda { PNM.create(data, :type => :pbm) }.must_raise PNM::DataError
|
45
45
|
end
|
46
46
|
|
47
47
|
it 'raises an exception for image type and data mismatch (PGM)' do
|
48
48
|
data = [[[0,0,0], [0,0,0]], [[0,0,0], [0,0,0]]]
|
49
|
-
lambda { PNM
|
49
|
+
lambda { PNM.create(data, :type => :pgm) }.must_raise PNM::DataError
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'raises an exception for non-integer pixel value (String)' do
|
53
53
|
data = [[0, 0], ['X', 0]]
|
54
|
-
lambda { PNM
|
54
|
+
lambda { PNM.create(data) }.must_raise PNM::DataError
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'raises an exception for non-integer pixel value (Float)' do
|
58
58
|
data = [[0, 0], [0.5, 0]]
|
59
|
-
lambda { PNM
|
59
|
+
lambda { PNM.create(data) }.must_raise PNM::DataError
|
60
60
|
end
|
61
61
|
|
62
62
|
it 'raises an exception for rows of different size' do
|
63
63
|
data = [[0, 0], [0, 0, 0]]
|
64
|
-
lambda { PNM
|
64
|
+
lambda { PNM.create(data) }.must_raise PNM::DataError
|
65
65
|
end
|
66
66
|
|
67
67
|
it 'raises an exception for invalid array dimensions (#1)' do
|
68
68
|
data = [0, 0, 0]
|
69
|
-
lambda { PNM
|
69
|
+
lambda { PNM.create(data) }.must_raise PNM::DataError
|
70
70
|
end
|
71
71
|
|
72
72
|
it 'raises an exception for invalid array dimensions (#2)' do
|
73
73
|
data = [[0, 0], 0, 0]
|
74
|
-
lambda { PNM
|
74
|
+
lambda { PNM.create(data) }.must_raise PNM::DataError
|
75
75
|
end
|
76
76
|
|
77
77
|
it 'raises an exception for invalid array dimensions (#3)' do
|
78
78
|
data = [[0, 0], [0, [0, 0]]]
|
79
|
-
lambda { PNM
|
79
|
+
lambda { PNM.create(data) }.must_raise PNM::DataError
|
80
80
|
end
|
81
81
|
|
82
82
|
it 'raises an exception for invalid array dimensions (#4)' do
|
83
83
|
data = [[[0,0], [0,0]], [[0,0], [0,0]]]
|
84
|
-
lambda { PNM
|
84
|
+
lambda { PNM.create(data) }.must_raise PNM::DataError
|
85
85
|
end
|
86
86
|
|
87
87
|
it 'raises an exception for invalid array dimensions (#5)' do
|
88
88
|
data = [[[0,0,0], [0,0,0]], [0 ,0]]
|
89
|
-
lambda { PNM
|
89
|
+
lambda { PNM.create(data) }.must_raise PNM::DataError
|
90
90
|
end
|
91
91
|
|
92
92
|
it 'raises an exception for invalid array dimensions (#6)' do
|
93
93
|
data = [[[0,0,0], 0], [0 ,0]]
|
94
|
-
lambda { PNM
|
94
|
+
lambda { PNM.create(data) }.must_raise PNM::DataError
|
95
95
|
end
|
96
96
|
|
97
97
|
it 'raises an exception for invalid PBM data (> 1)' do
|
98
98
|
data = [[0, 0], [2, 0]]
|
99
|
-
lambda { PNM
|
99
|
+
lambda { PNM.create(data, :type => :pbm) }.must_raise PNM::DataError
|
100
100
|
end
|
101
101
|
|
102
102
|
it 'raises an exception for invalid PBM data (< 0)' do
|
103
103
|
data = [[0, 0], [-1, 0]]
|
104
|
-
lambda { PNM
|
104
|
+
lambda { PNM.create(data, :type => :pbm) }.must_raise PNM::DataError
|
105
105
|
end
|
106
106
|
|
107
107
|
it 'raises an exception for invalid PGM data (> 255)' do
|
108
108
|
data = [[0, 0], [1, 500]]
|
109
|
-
lambda { PNM
|
109
|
+
lambda { PNM.create(data, :type => :pgm) }.must_raise PNM::DataError
|
110
110
|
end
|
111
111
|
|
112
112
|
it 'raises an exception for invalid PGM data (> maxgray)' do
|
113
113
|
data = [[0, 0], [1, 200]]
|
114
|
-
lambda { PNM
|
114
|
+
lambda { PNM.create(data, :maxgray => 100) }.must_raise PNM::DataError
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
data/test/test_image.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Copyright (C) 2013-2014 Marcus Stollsteimer
|
4
4
|
|
5
5
|
require 'minitest/autorun'
|
6
|
-
require 'pnm
|
6
|
+
require 'pnm'
|
7
7
|
|
8
8
|
|
9
9
|
describe PNM::Image do
|
@@ -19,7 +19,7 @@ describe PNM::Image do
|
|
19
19
|
[0,0,1,0,0],
|
20
20
|
[0,0,0,0,0]]
|
21
21
|
comment = 'Bilevel'
|
22
|
-
@bilevel = PNM
|
22
|
+
@bilevel = PNM.create(pixels, {:comment => comment})
|
23
23
|
|
24
24
|
pixels = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
25
25
|
[0,1,1,1,0,1,1,1,1,0,1,1,1,1,1,0],
|
@@ -27,95 +27,95 @@ describe PNM::Image do
|
|
27
27
|
[0,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0],
|
28
28
|
[0,0,1,0,0,1,1,1,1,0,1,0,1,0,1,0],
|
29
29
|
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]
|
30
|
-
@bilevel_2 = PNM
|
30
|
+
@bilevel_2 = PNM.create(pixels)
|
31
31
|
|
32
32
|
pixels = [[ 0, 50,100,150],
|
33
33
|
[ 50,100,150,200],
|
34
34
|
[100,150,200,250]]
|
35
35
|
comment = "Grayscale\n(with multiline comment)"
|
36
|
-
@grayscale = PNM
|
36
|
+
@grayscale = PNM.create(pixels, {:maxgray => 250, :comment => comment})
|
37
37
|
|
38
38
|
pixels = [[65,66], [13,10], [65,66]]
|
39
|
-
@grayscale_crlf = PNM
|
39
|
+
@grayscale_crlf = PNM.create(pixels)
|
40
40
|
|
41
41
|
pixels = [[[0,6,0], [1,5,1], [2,4,2], [3,3,4], [4,2,6]],
|
42
42
|
[[1,5,2], [2,4,2], [3,3,2], [4,2,2], [5,1,2]],
|
43
43
|
[[2,4,6], [3,3,4], [4,2,2], [5,1,1], [6,0,0]]]
|
44
|
-
@color = PNM
|
44
|
+
@color = PNM.create(pixels, {:maxgray => 6})
|
45
45
|
end
|
46
46
|
|
47
47
|
it 'sets maxgray to 1 for bilevel images' do
|
48
|
-
image = PNM
|
48
|
+
image = PNM.create([[0,1,0], [1,0,1]])
|
49
49
|
image.type.must_equal :pbm
|
50
50
|
image.maxgray.must_equal 1
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'sets maxgray by default to 255 for grayscale images' do
|
54
|
-
image = PNM
|
54
|
+
image = PNM.create([[0,10,20], [10,20,30]])
|
55
55
|
image.type.must_equal :pgm
|
56
56
|
image.maxgray.must_equal 255
|
57
57
|
end
|
58
58
|
|
59
59
|
it 'sets maxgray by default to 255 for color images' do
|
60
|
-
image = PNM
|
60
|
+
image = PNM.create([[[0,0,0], [10,10,10]], [[10,10,10], [20,20,20]]])
|
61
61
|
image.type.must_equal :ppm
|
62
62
|
image.maxgray.must_equal 255
|
63
63
|
end
|
64
64
|
|
65
65
|
it 'accepts setting of maxgray to 1 for bilevel images' do
|
66
|
-
image = PNM
|
66
|
+
image = PNM.create([[0,1,0], [1,0,1]], {:maxgray => 1})
|
67
67
|
image.type.must_equal :pbm
|
68
68
|
image.maxgray.must_equal 1
|
69
69
|
end
|
70
70
|
|
71
71
|
it 'ignores invalid maxgray for bilevel images and sets it to 1' do
|
72
|
-
image = PNM
|
72
|
+
image = PNM.create([[0,1,0], [1,0,1]], {:type => :pbm, :maxgray => 255})
|
73
73
|
image.type.must_equal :pbm
|
74
74
|
image.maxgray.must_equal 1
|
75
75
|
end
|
76
76
|
|
77
77
|
it 'can create a grayscale image from bilevel values (using type)' do
|
78
|
-
image = PNM
|
78
|
+
image = PNM.create([[0,1,0], [1,0,1]], {:type => :pgm})
|
79
79
|
image.type.must_equal :pgm
|
80
80
|
image.pixels.must_equal [[0,1,0], [1,0,1]]
|
81
81
|
image.maxgray.must_equal 255
|
82
82
|
end
|
83
83
|
|
84
84
|
it 'also accepts types given as string instead of symbol' do
|
85
|
-
image = PNM
|
85
|
+
image = PNM.create([[0,1,0], [1,0,1]], {:type => "pgm"})
|
86
86
|
image.type.must_equal :pgm
|
87
87
|
end
|
88
88
|
|
89
89
|
it 'can create a grayscale image from bilevel values (using maxgray)' do
|
90
|
-
image = PNM
|
90
|
+
image = PNM.create([[0,1,0], [1,0,1]], {:maxgray => 2})
|
91
91
|
image.type.must_equal :pgm
|
92
92
|
image.pixels.must_equal [[0,1,0], [1,0,1]]
|
93
93
|
image.maxgray.must_equal 2
|
94
94
|
end
|
95
95
|
|
96
96
|
it 'can create a color image from bilevel values' do
|
97
|
-
image = PNM
|
97
|
+
image = PNM.create([[0,1,0], [1,0,1]], {:type => :ppm})
|
98
98
|
image.info.must_match %r{^PPM 3x2 Color}
|
99
99
|
image.pixels.must_equal [[[0,0,0], [1,1,1], [0,0,0]], [[1,1,1], [0,0,0], [1,1,1]]]
|
100
100
|
image.maxgray.must_equal 255
|
101
101
|
end
|
102
102
|
|
103
103
|
it 'can create a color image from bilevel values with a given maxgray' do
|
104
|
-
image = PNM
|
104
|
+
image = PNM.create([[0,1,0], [1,0,1]], {:type => :ppm, :maxgray => 2})
|
105
105
|
image.info.must_match %r{^PPM 3x2 Color}
|
106
106
|
image.pixels.must_equal [[[0,0,0], [1,1,1], [0,0,0]], [[1,1,1], [0,0,0], [1,1,1]]]
|
107
107
|
image.maxgray.must_equal 2
|
108
108
|
end
|
109
109
|
|
110
110
|
it 'can create a color image from gray values' do
|
111
|
-
image = PNM
|
111
|
+
image = PNM.create([[0,3,6], [3,6,9]], {:type => :ppm})
|
112
112
|
image.info.must_match %r{^PPM 3x2 Color}
|
113
113
|
image.pixels.must_equal [[[0,0,0], [3,3,3], [6,6,6]], [[3,3,3], [6,6,6], [9,9,9]]]
|
114
114
|
end
|
115
115
|
|
116
116
|
it 'does not modify the input data for color images created from gray values' do
|
117
117
|
data = [[0,3,6], [3,6,9]]
|
118
|
-
PNM
|
118
|
+
PNM.create(data, {:type => :ppm})
|
119
119
|
data.must_equal [[0,3,6], [3,6,9]]
|
120
120
|
end
|
121
121
|
|
@@ -168,9 +168,9 @@ describe PNM::Image do
|
|
168
168
|
end
|
169
169
|
|
170
170
|
it 'can return meaningful debugging information' do
|
171
|
-
@bilevel.inspect.must_match %r{^#<PNM
|
172
|
-
@grayscale.inspect.must_match %r{^#<PNM
|
173
|
-
@color.inspect.must_match %r{^#<PNM
|
171
|
+
@bilevel.inspect.must_match %r{^#<PNM::\w+Image:0x\h+ PBM 5x6 Bilevel>$}
|
172
|
+
@grayscale.inspect.must_match %r{^#<PNM::\w+Image:0x\h+ PGM 4x3 Grayscale, maxgray=250>$}
|
173
|
+
@color.inspect.must_match %r{^#<PNM::\w+Image:0x\h+ PPM 5x3 Color, maxgray=6>$}
|
174
174
|
end
|
175
175
|
|
176
176
|
it 'can write binary data containing CRLF' do
|
@@ -187,14 +187,14 @@ describe PNM::Image do
|
|
187
187
|
|
188
188
|
it 'can write zero-length comments' do
|
189
189
|
comment = ''
|
190
|
-
PNM
|
190
|
+
PNM.create([[0,0]], :comment => comment).write(@temp_path, :ascii)
|
191
191
|
File.binread(@temp_path).must_equal "P1\n#\n2 1\n0 0\n"
|
192
192
|
File.delete(@temp_path)
|
193
193
|
end
|
194
194
|
|
195
195
|
it 'can write comments with trailing zero-length line' do
|
196
196
|
comment = "An empty line:\n"
|
197
|
-
PNM
|
197
|
+
PNM.create([[0,0]], :comment => comment).write(@temp_path, :ascii)
|
198
198
|
File.binread(@temp_path).must_equal "P1\n# An empty line:\n#\n2 1\n0 0\n"
|
199
199
|
File.delete(@temp_path)
|
200
200
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pnm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcus Stollsteimer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -80,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
80
|
version: '0'
|
81
81
|
requirements: []
|
82
82
|
rubyforge_project:
|
83
|
-
rubygems_version: 2.4.
|
83
|
+
rubygems_version: 2.4.5
|
84
84
|
signing_key:
|
85
85
|
specification_version: 4
|
86
86
|
summary: PNM - create/read/write PNM image files (PBM, PGM, PPM)
|