Class: Tb::PNMReader
- Inherits:
-
Object
- Object
- Tb::PNMReader
- Defined in:
- lib/tb/pnm.rb
Overview
practical only for (very) small images.
Constant Summary collapse
- WSP =
/(?:[ \t\r\n]|\#[^\r\n]*[\r\n])+/
Instance Method Summary collapse
- #each ⇒ Object
-
#initialize(pnm_content) ⇒ PNMReader
constructor
A new instance of PNMReader.
- #make_raw_pbm_each_pixel_component(width) ⇒ Object
- #plain_pbm_each_pixel_component(raster) ⇒ Object
- #plain_ppm_pgm_each_pixel_component(raster) ⇒ Object
- #raw_ppm_pgm_1byte_each_pixel_component(raster, &b) ⇒ Object
- #raw_ppm_pgm_2byte_each_pixel_component(raster) ⇒ Object
- #shift ⇒ Object
- #to_a ⇒ Object
Constructor Details
#initialize(pnm_content) ⇒ PNMReader
Returns a new instance of PNMReader.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/tb/pnm.rb', line 66 def initialize(pnm_content) pnm_content.force_encoding("ASCII-8BIT") if pnm_content.respond_to? :force_encoding if /\A(P[63])(#{WSP})(\d+)(#{WSP})(\d+)(#{WSP})(\d+)[ \t\r\n]/on =~ pnm_content magic, wsp1, w, wsp2, h, wsp3, max, raster = $1, $2, $3.to_i, $4, $5.to_i, $6, $7.to_i, $' pixel_component = %w[R G B] elsif /\A(P[52])(#{WSP})(\d+)(#{WSP})(\d+)(#{WSP})(\d+)[ \t\r\n]/on =~ pnm_content magic, wsp1, w, wsp2, h, wsp3, max, raster = $1, $2, $3.to_i, $4, $5.to_i, $6, $7.to_i, $' pixel_component = %w[V] elsif /\A(P[41])(#{WSP})(\d+)(#{WSP})(\d+)[ \t\r\n]/on =~ pnm_content magic, wsp1, w, wsp2, h, raster = $1, $2, $3.to_i, $4, $5.to_i, $' wsp3 = nil max = 1 pixel_component = %w[V] else raise ArgumentError, "not PNM format" end raise ArgumentError, "unsupported max value: #{max}" if 65535 < max @ary = [ ['type', 'x', 'y', 'component', 'value'], ['meta', nil, nil, 'pnm_type', magic], ['meta', nil, nil, 'width', w], ['meta', nil, nil, 'height', h], ['meta', nil, nil, 'max', max] ] [wsp1, wsp2, wsp3].each {|wsp| next if !wsp wsp.scan(/\#([^\r\n]*)[\r\n]/) { @ary << ['meta', nil, nil, 'comment', $1] } } if /P[65]/ =~ magic # raw (binary) PPM/PGM if max < 0x100 each_pixel_component = method(:raw_ppm_pgm_1byte_each_pixel_component) else each_pixel_component = method(:raw_ppm_pgm_2byte_each_pixel_component) end elsif /P4/ =~ magic # raw (binary) PBM each_pixel_component = make_raw_pbm_each_pixel_component(w) elsif /P[32]/ =~ magic # plain (ascii) PPM/PGM each_pixel_component = method(:plain_ppm_pgm_each_pixel_component) elsif /P1/ =~ magic # plain (ascii) PBM each_pixel_component = method(:plain_pbm_each_pixel_component) end n = w * h * pixel_component.length i = 0 each_pixel_component.call(raster) {|value| break if i == n y, x = (i / pixel_component.length).divmod(w) c = pixel_component[i % pixel_component.length] @ary << ['pixel', x, y, c, value.to_f / max] i += 1 } if i != n raise ArgumentError, "PNM raster data too short." end end |
Instance Method Details
#each ⇒ Object
170 171 172 173 174 175 |
# File 'lib/tb/pnm.rb', line 170 def each while ary = self.shift yield ary end nil end |
#make_raw_pbm_each_pixel_component(width) ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/tb/pnm.rb', line 143 def make_raw_pbm_each_pixel_component(width) iter = Object.new iter.instance_variable_set(:@width, width) def iter.call(raster) numbytes = (@width + 7) / 8 y = 0 while true return if raster.size <= y * numbytes line = raster[y * numbytes, numbytes] x = 0 while x < @width i, j = x.divmod(8) return if line.size <= i byte = line[x/8].ord yield 1 - ((byte >> (7-j)) & 1) x += 1 end y += 1 end end iter end |
#plain_pbm_each_pixel_component(raster) ⇒ Object
139 140 141 |
# File 'lib/tb/pnm.rb', line 139 def plain_pbm_each_pixel_component(raster) raster.scan(/[01]/) { yield 1 - $&.to_i } end |
#plain_ppm_pgm_each_pixel_component(raster) ⇒ Object
135 136 137 |
# File 'lib/tb/pnm.rb', line 135 def plain_ppm_pgm_each_pixel_component(raster) raster.scan(/\d+/) { yield $&.to_i } end |
#raw_ppm_pgm_1byte_each_pixel_component(raster, &b) ⇒ Object
124 125 126 |
# File 'lib/tb/pnm.rb', line 124 def raw_ppm_pgm_1byte_each_pixel_component(raster, &b) raster.each_byte(&b) end |
#raw_ppm_pgm_2byte_each_pixel_component(raster) ⇒ Object
128 129 130 131 132 133 |
# File 'lib/tb/pnm.rb', line 128 def raw_ppm_pgm_2byte_each_pixel_component(raster) raster.enum_for(:each_byte).each_slice(2) {|byte1, byte2| word = byte1 * 0x100 + byte2 yield word } end |
#shift ⇒ Object
166 167 168 |
# File 'lib/tb/pnm.rb', line 166 def shift @ary.shift end |
#to_a ⇒ Object
177 178 179 180 181 |
# File 'lib/tb/pnm.rb', line 177 def to_a result= [] each {|ary| result << ary } result end |