Class: VNCRec::RFB::EncZRLE::Stream
- Inherits:
-
Object
- Object
- VNCRec::RFB::EncZRLE::Stream
- Defined in:
- lib/vncrec/rfb/enczrle.rb
Instance Method Summary collapse
- #handle_ZRLE_packed_palette(stream, psize, tw = 64, th = 64) ⇒ Object
- #handle_ZRLE_palette_RLE_tile(stream, psize, tw = 64, th = 64) ⇒ Object
- #handle_ZRLE_plain_RLE_tile(stream, tw = 64, th = 64) ⇒ Object
-
#initialize(io, bitspp, depth) ⇒ Stream
constructor
A new instance of Stream.
- #read_rect(w, h) ⇒ Object
- #read_zchunk ⇒ Object
Constructor Details
#initialize(io, bitspp, depth) ⇒ Stream
Returns a new instance of Stream.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/vncrec/rfb/enczrle.rb', line 8 def initialize(io,bitspp,depth) @io = io @zstream = Zlib::Inflate.new @bpp_orig = (bitspp.to_f/8.0).ceil @bpp = case bitspp when 32 then @depth <= 24 ? 3 : 4 when 8 then 1 else raise "Cannot handle such pixel format" end @depth = depth end |
Instance Method Details
#handle_ZRLE_packed_palette(stream, psize, tw = 64, th = 64) ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/vncrec/rfb/enczrle.rb', line 151 def handle_ZRLE_packed_palette(stream, psize, tw=64, th=64) pixels = Array.new(tw*th, 0) bitspp = case psize when 2 then 1 when 3..4 then 2 when 5..16 then 4 else return pixels end palette = [] psize.times do palette << stream.read(@bpp).unpack("C*") end count = case psize when 2 then th*((tw+7)/8) when 3..4 then th*((tw+3)/4) when 5..16 then th*((tw+1)/2) end off_bits = 0 bits_per_row = bitspp * tw padding_bits = bits_per_row % 8 encoded_len_bits = 64 * (bits_per_row + padding_bits) encoded = stream.read(count).unpack("C*") pixnum = 0 while off_bits < (encoded_len_bits - padding_bits - bitspp) b1 = encoded[off_bits/8] b2 = encoded[off_bits/8 + 1] || 0 b1 <<= 8 pixels[pixnum] = palette[h_bitmask(b2 + b1, bitspp, off_bits % 16)].pack("C*") off_bits += if (off_bits % bits_per_row) > (bits_per_row - padding_bits) and (padding_bits > 0) bitspp + padding_bits else bitspp end pixnum += 1 end pixels end |
#handle_ZRLE_palette_RLE_tile(stream, psize, tw = 64, th = 64) ⇒ Object
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 123 124 |
# File 'lib/vncrec/rfb/enczrle.rb', line 92 def handle_ZRLE_palette_RLE_tile(stream,psize,tw=64,th=64) palette = [] pixels = Array.new(tw*th) psize.times do palette << stream.read(@bpp) end len = 0 begin while len < tw*th id = stream.read(1).unpack("C")[0] # #+--------+--------+--------+--------+ #| id | 255 | .. | <255 | #+--------+--------+--------+--------+ # if (id & 0b10000000) == 0 rl = 1 else id -= 128 rl = 0 rem = 0 while (rem = stream.readbyte) == 255 rl += 255 end rl += rem + 1 end pixels[len...(len+rl)] = Array.new(rl, palette[id]) #TODO: if rl == 1 len += rl end rescue EOFError end pixels end |
#handle_ZRLE_plain_RLE_tile(stream, tw = 64, th = 64) ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/vncrec/rfb/enczrle.rb', line 126 def handle_ZRLE_plain_RLE_tile(stream,tw=64,th=64) pixels = Array.new(tw*th) len = 0 begin while len < tw*th color = stream.read(@bpp) # #+--------+--------+--------+--------+ #| color | 255 | .. | <255 | #+--------+--------+--------+--------+ # rl = 0 rem = 0 while (rem = stream.readbyte) == 255 rl += 255 end rl += rem + 1 pixels[len...(len+rl)] = Array.new(rl, color) #TODO: if rl == 1 len += rl end rescue EOFError end pixels end |
#read_rect(w, h) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 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 |
# File 'lib/vncrec/rfb/enczrle.rb', line 35 def read_rect(w,h) fb = Array.new(w*h*@bpp) data = "" begin data = @zstream.inflate(read_zchunk) rescue Zlib::DataError return end stream = StringIO.new data tile_cols = (w.to_f/64).ceil tile_rows = (h.to_f/64).ceil tile_cols_rem = w % 64 tile_rows_rem = h % 64 tile_rows.times do |tile_row_num| tile_cols.times do |tile_col_num| th = if ((tile_row_num == tile_rows-1) and (tile_rows_rem > 0)) tile_rows_rem else 64 end tw = if ((tile_col_num == tile_cols-1) and (tile_cols_rem > 0)) tile_cols_rem else 64 end subenc = stream.readbyte tile = case subenc when 0 then #Raw tile = Array.new(tw*th) th.times do tile << (stream.read tw*@bpp_orig).unpack("C*").join end tile when 1 then #Solid Array.new(tw*th, stream.read(@bpp_orig)) when 2..16 then #Packed palette handle_ZRLE_packed_palette(stream, subenc, tw,th) when 128 then #Plain RLE handle_ZRLE_plain_RLE_tile(stream,tw,th) when 130..255 then #RLE w/ palette handle_ZRLE_palette_RLE_tile(stream,subenc-128, tw,th) end th.times do |y| boline = (64 * tile_row_num + y) * w offx = 64 * tile_col_num fb[(boline+offx)...(boline+offx+tw)] = tile[(tw*y)...(tw*(y+1))] end end #tile_col.times end#tile_row.times return fb.join end |
#read_zchunk ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/vncrec/rfb/enczrle.rb', line 23 def read_zchunk zdata_len = (@io.readpartial 4).unpack("L>")[0] zdata = "" to_read = zdata_len while zdata.size < zdata_len zdata += @io.read(to_read) to_read = zdata_len - zdata.size end return zdata end |