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
- #close ⇒ Object
- #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.
62 63 64 65 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 |
# File 'lib/tb/pnm.rb', line 62 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
#close ⇒ Object
179 180 |
# File 'lib/tb/pnm.rb', line 179 def close end |
#each ⇒ Object
166 167 168 169 170 171 |
# File 'lib/tb/pnm.rb', line 166 def each while ary = self.shift yield ary end nil end |
#make_raw_pbm_each_pixel_component(width) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/tb/pnm.rb', line 139 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
135 136 137 |
# File 'lib/tb/pnm.rb', line 135 def plain_pbm_each_pixel_component(raster) raster.scan(/[01]/) { yield 1 - $&.to_i } end |
#plain_ppm_pgm_each_pixel_component(raster) ⇒ Object
131 132 133 |
# File 'lib/tb/pnm.rb', line 131 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
120 121 122 |
# File 'lib/tb/pnm.rb', line 120 def raw_ppm_pgm_1byte_each_pixel_component(raster, &b) raster.each_byte(&b) end |
#raw_ppm_pgm_2byte_each_pixel_component(raster) ⇒ Object
124 125 126 127 128 129 |
# File 'lib/tb/pnm.rb', line 124 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
162 163 164 |
# File 'lib/tb/pnm.rb', line 162 def shift @ary.shift end |
#to_a ⇒ Object
173 174 175 176 177 |
# File 'lib/tb/pnm.rb', line 173 def to_a result= [] each {|ary| result << ary } result end |