Mercurial > hg > Applications > TreeVNC
annotate src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java @ 589:ef5033b06019
fix compress length in flush
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 12 Feb 2020 21:54:40 +0900 |
parents | f01eef88010f |
children | 3accb09e430c |
rev | line source |
---|---|
57
17b702648079
version2.7.2 original version.
Taninari YU <you@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1 // Copyright (C) 2010, 2011, 2012, 2013 GlavSoft LLC. |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
2 // All rights reserved. |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
3 // |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
4 //------------------------------------------------------------------------- |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
5 // This file is part of the TightVNC software. Please visit our Web site: |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
6 // |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
7 // http://www.tightvnc.com/ |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
8 // |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
9 // This program is free software; you can redistribute it and/or modify |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
10 // it under the terms of the GNU General Public License as published by |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
11 // the Free Software Foundation; either version 2 of the License, or |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
12 // (at your option) any later version. |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
13 // |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
14 // This program is distributed in the hope that it will be useful, |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
17 // GNU General Public License for more details. |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
18 // |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
19 // You should have received a copy of the GNU General Public License along |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
20 // with this program; if not, write to the Free Software Foundation, Inc., |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
22 //------------------------------------------------------------------------- |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
23 // |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
24 |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
25 package com.glavsoft.rfb.encoding.decoder; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
26 |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
27 import com.glavsoft.drawing.Renderer; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
28 import com.glavsoft.exceptions.TransportException; |
526 | 29 import com.glavsoft.rfb.encoding.EncodingType; |
582 | 30 import com.glavsoft.rfb.protocol.ReceiverTask; |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
31 import com.glavsoft.transport.Reader; |
526 | 32 import jp.ac.u_ryukyu.treevnc.CheckDelay; |
498 | 33 import jp.ac.u_ryukyu.treevnc.TreeRFBProto; |
582 | 34 |
35 import java.awt.*; | |
526 | 36 import java.io.UnsupportedEncodingException; |
37 import java.nio.ByteBuffer; | |
528 | 38 import java.util.LinkedList; |
526 | 39 import java.util.zip.Deflater; |
40 | |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
41 public class ZRLEDecoder extends ZlibDecoder { |
57
17b702648079
version2.7.2 original version.
Taninari YU <you@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
42 private static final int MAX_TILE_SIZE = 64; |
539 | 43 private int[] decodedBitmap; |
44 private int[] palette; | |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
45 |
539 | 46 class TileLoop { |
535 | 47 private final boolean blocking; |
578
c6893847c73a
zlib flush margin 16kbytes
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
577
diff
changeset
|
48 final int MARGIN = 18000; |
c6893847c73a
zlib flush margin 16kbytes
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
577
diff
changeset
|
49 final int deflate_size = 60000-MARGIN; |
528 | 50 private ByteBuffer c1; |
532 | 51 private int width; // phase2 length |
582 | 52 private FramebufferUpdateRectangle c0rect,c1rect,rect; |
528 | 53 private int prevLineOffset; |
54 private int prevC1Offset; | |
541 | 55 private int prevC1LineOffset; |
528 | 56 private int prevoffset; |
57 private Deflater deflater; | |
572 | 58 private int flushOffset; |
528 | 59 |
60 /** | |
61 * Multicast framebufferUpdate to children. | |
62 * read FrameBuffferUpdate. If it is ZLE, make it ZLEE which is self contained compressed packet. | |
63 * put the packet to the multicastqueue. Then normal rendering engine read the same stream using is.reset(). | |
539 | 64 * <p> |
528 | 65 * Haeder |
539 | 66 * messageID ( FrameBuffer Update |
67 * 1 byte padding | |
68 * 2 byte numberofrectangle | |
69 * 2 - U16 - x-position | |
70 * 2 - U16 - y-position | |
71 * 2 - U16 - width | |
72 * 2 - U16 - height | |
73 * 4 - S32 - encoding-type | |
74 * 4 byte datalengths | |
75 * datalengths databyte | |
528 | 76 * |
77 * @throws TransportException | |
78 * @throws UnsupportedEncodingException | |
79 */ | |
80 | |
566 | 81 public TileLoop(TreeRFBProto rfb, int offset) { |
577 | 82 prevoffset = prevLineOffset = flushOffset = offset; |
539 | 83 prevC1Offset = 0; |
566 | 84 if (rfb == null || offset < deflate_size + spanGap) { |
535 | 85 // packet size fit in broadcast send it all at once |
86 blocking = false; | |
87 } else | |
88 blocking = true; | |
533 | 89 } |
528 | 90 |
535 | 91 private void zrleeBlocking(TreeRFBProto rfb, ByteBuffer header, FramebufferUpdateRectangle rect, byte bytes[]) { |
528 | 92 // dump32(inputs); |
93 deflater = rfb.deflater; | |
582 | 94 this.rect = rect; |
95 c0rect = null; | |
541 | 96 c1rect = new FramebufferUpdateRectangle(rect.x, rect.y, 0, 0); |
582 | 97 newMulticastPacket(rfb); |
568 | 98 //c1.put(header.get(0)); |
535 | 99 if (!blocking) { |
579 | 100 deflater.setInput(bytes, 0,(int) prevoffset); |
535 | 101 deflater.deflate(c1); |
572 | 102 flushMuticast(rfb, bytes); |
535 | 103 } |
532 | 104 return; |
105 } | |
106 | |
582 | 107 private void newMulticastPacket(TreeRFBProto rfb) { |
578
c6893847c73a
zlib flush margin 16kbytes
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
577
diff
changeset
|
108 c1 = rfb.multicastqueue.allocate(deflate_size + MARGIN); |
c6893847c73a
zlib flush margin 16kbytes
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
577
diff
changeset
|
109 c1.limit(deflate_size); |
528 | 110 if (rfb.addSerialNum) |
111 c1.putLong(rfb.counter++); | |
112 if (rfb.checkDelay) | |
113 CheckDelay.checkDelay(c1, rect.x, rect.y, rect.width, rect.height, System.currentTimeMillis(), EncodingType.CHECK_DELAY); | |
541 | 114 c1.put((byte) 0); |
532 | 115 c1.put((byte) 0); |
116 c1.putShort((short) 0); | |
550
9c0cbe119155
fix make rectangle packet in client
e165729 <e165729@ie.u-ryukyu.ac.jp>
parents:
545
diff
changeset
|
117 c1.position(c1.position() + 12); |
532 | 118 c1.putInt(0); // should be data length |
539 | 119 prevC1Offset = c1.position(); |
541 | 120 prevC1LineOffset = prevC1Offset; |
121 c1rect.width = c1rect.height = 0; | |
582 | 122 c0rect = null; |
528 | 123 } |
531
13d3c4341d14
remove .idea modules fix for loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
529
diff
changeset
|
124 |
528 | 125 int spanGap = 128; |
126 /** | |
534
a3d0ba67e8cf
try 512 tiles / 256 tiles flush
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
533
diff
changeset
|
127 * Series of tiles compose at most three rectangles. SYNC_FLUSH is necessary on |
a3d0ba67e8cf
try 512 tiles / 256 tiles flush
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
533
diff
changeset
|
128 * rectangle boundaries. |
582 | 129 * |
545
1ba61b57be39
add test routine in -p ( running as root mode )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
543
diff
changeset
|
130 * +----+ |
1ba61b57be39
add test routine in -p ( running as root mode )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
543
diff
changeset
|
131 * | | phase 0 |
1ba61b57be39
add test routine in -p ( running as root mode )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
543
diff
changeset
|
132 * +---------------+ |
1ba61b57be39
add test routine in -p ( running as root mode )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
543
diff
changeset
|
133 * | | phase 1 |
1ba61b57be39
add test routine in -p ( running as root mode )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
543
diff
changeset
|
134 * +----+----------+ |
1ba61b57be39
add test routine in -p ( running as root mode )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
543
diff
changeset
|
135 * | | phase 2 |
1ba61b57be39
add test routine in -p ( running as root mode )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
543
diff
changeset
|
136 * +----+ |
582 | 137 * |
138 * Broadcast packet have to be less than 64kbytes | |
139 * A tile 64x64x4 166384byte | |
140 * | |
141 * we cannot rewind zlib stream, zlib stream have to be flushed at the end of rectangles | |
142 * if we leave 16kbytes space margin, zlib stream can be flushed safely | |
143 * | |
144 * keep completed previous rectangle in c0rect, which is possibly none. | |
145 * at the last or packet full, flush c0rect first, then flush c1rect if it exists | |
534
a3d0ba67e8cf
try 512 tiles / 256 tiles flush
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
533
diff
changeset
|
146 * |
528 | 147 * @param rfb |
148 * @param last | |
149 * @param bytes | |
150 * @param offset | |
151 * @param tileW | |
152 * @param tileH | |
153 */ | |
539 | 154 |
582 | 155 public void multicastPut(TreeRFBProto rfb, boolean last, byte[] bytes, int offset, int tileW, int tileH) { |
535 | 156 if (!blocking) return; |
528 | 157 int span = offset - prevoffset; |
539 | 158 deflater.setInput(bytes, prevoffset, span); |
577 | 159 do { |
580 | 160 deflater.deflate(c1, Deflater. SYNC_FLUSH); |
578
c6893847c73a
zlib flush margin 16kbytes
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
577
diff
changeset
|
161 if (!deflater.needsInput()) { |
582 | 162 // packet full |
580 | 163 flushDeflator(); |
164 prevoffset = flushOffset+(int)deflater.getBytesRead(); | |
581 | 165 assert(prevoffset==offset); |
166 System.out.println("od prevOffset = "+prevoffset+" span = "+(prevoffset-flushOffset)); | |
582 | 167 if (c0rect!=null) { flushRectangle(c0rect); moveNext(); } // finish pahse 1 |
168 flushRectangle(c1rect); // phase 2 | |
577 | 169 flushMuticast(rfb, bytes); |
581 | 170 if (last) { |
577 | 171 return; |
172 } else { | |
582 | 173 newMulticastPacket(rfb); |
174 if (width<rect.width) { // phase 0 | |
175 c1rect.x = rect.x + width; | |
176 } else { | |
177 c1rect.x = 0; // phase 1 | |
178 c1rect.y += tileH; | |
179 } | |
180 return; | |
577 | 181 } |
182 } | |
183 } while (! deflater.needsInput()); | |
184 prevoffset = offset; | |
185 if (last) { | |
580 | 186 flushDeflator(); |
582 | 187 if (c0rect!=null) { flushRectangle(c0rect); moveNext(); } |
188 flushRectangle(c1rect); | |
572 | 189 flushMuticast(rfb, bytes); |
582 | 190 return; |
564 | 191 } |
539 | 192 width += tileW; |
582 | 193 if (c1rect.height==0) c1rect.height = tileH; |
532 | 194 if (c1rect.x > rect.x) { // phase 0 |
582 | 195 assert(c0rect==null); |
539 | 196 if (c1rect.x + c1rect.width < rect.x + rect.width) { |
582 | 197 c1rect.x += tileW; |
564 | 198 } else { // end of phase 0 |
582 | 199 flushRectangle(c1rect); |
200 c1.position((c1.position()+16)); // make next header space | |
201 c1rect = new FramebufferUpdateRectangle(rect.x,c1rect.y+tileH,0,0); | |
528 | 202 } |
538 | 203 } else { // phase 1 |
564 | 204 if (width >= rect.width) { // next line |
582 | 205 deflater.deflate(c1,Deflater.FULL_FLUSH); |
206 prevC1LineOffset = c1.position(); | |
532 | 207 c1rect.width = rect.width; |
582 | 208 if (c0rect!=null) { // extend phase 1 |
209 c0rect.height += tileH; | |
210 c1rect = new FramebufferUpdateRectangle(rect.x, c0rect.y+c0rect.height,0,0); | |
211 } else { // first phase 1 case | |
212 c1rect.height = tileH; | |
213 c0rect = c1rect; | |
214 c1rect = new FramebufferUpdateRectangle(rect.x, c1rect.y+c1rect.height,0,0); | |
215 } | |
532 | 216 width = 0; |
531
13d3c4341d14
remove .idea modules fix for loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
529
diff
changeset
|
217 prevLineOffset = offset; |
534
a3d0ba67e8cf
try 512 tiles / 256 tiles flush
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
533
diff
changeset
|
218 } |
a3d0ba67e8cf
try 512 tiles / 256 tiles flush
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
533
diff
changeset
|
219 } |
a3d0ba67e8cf
try 512 tiles / 256 tiles flush
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
533
diff
changeset
|
220 } |
a3d0ba67e8cf
try 512 tiles / 256 tiles flush
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
533
diff
changeset
|
221 |
582 | 222 public void moveNext() { |
223 // previous rectangle is finished, make next header space and copy already compressed part | |
224 c1.limit(c1.limit()+16); | |
225 System.arraycopy(c1.array(),prevC1LineOffset,16,prevC1LineOffset+16,c1.position()-prevC1LineOffset); | |
226 } | |
227 | |
580 | 228 private void flushDeflator() { |
578
c6893847c73a
zlib flush margin 16kbytes
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
577
diff
changeset
|
229 c1.limit(c1.limit() + MARGIN); |
c6893847c73a
zlib flush margin 16kbytes
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
577
diff
changeset
|
230 deflater.deflate(c1, Deflater.FULL_FLUSH); |
c6893847c73a
zlib flush margin 16kbytes
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
577
diff
changeset
|
231 if (c1.remaining()==0) { |
c6893847c73a
zlib flush margin 16kbytes
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
577
diff
changeset
|
232 System.out.println("Multicast packet overrun."); |
c6893847c73a
zlib flush margin 16kbytes
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
577
diff
changeset
|
233 } |
c6893847c73a
zlib flush margin 16kbytes
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
577
diff
changeset
|
234 } |
c6893847c73a
zlib flush margin 16kbytes
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
577
diff
changeset
|
235 |
582 | 236 private void bufdump(byte[] bytes,int beigin, int end) { |
237 ReceiverTask.dump("in ",bytes,beigin,8); ReceiverTask.dump("... ",bytes,end,8); | |
238 System.out.println(); | |
239 } | |
528 | 240 |
241 /** | |
242 * fix rectangle header | |
243 * create next rectangle header | |
244 * update position paramater | |
245 * send muticast pacate if nessesally | |
246 */ | |
532 | 247 private void flushRectangle(FramebufferUpdateRectangle rect) { |
582 | 248 c1.putShort(prevC1Offset - 16, (short) rect.x); |
249 c1.putShort(prevC1Offset - 14, (short) rect.y); | |
250 c1.putShort(prevC1Offset - 12, (short) rect.width); | |
251 c1.putShort(prevC1Offset - 10, (short) rect.height); | |
550
9c0cbe119155
fix make rectangle packet in client
e165729 <e165729@ie.u-ryukyu.ac.jp>
parents:
545
diff
changeset
|
252 c1.putInt(prevC1Offset - 8, EncodingType.ZRLEE.getId()); |
589
ef5033b06019
fix compress length in flush
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
582
diff
changeset
|
253 c1.putInt(prevC1Offset - 4, c1.position() - prevC1Offset ); // data length |
539 | 254 c1.putShort(2, (short) (c1.getShort(2) + 1)); // increment rectangle count |
255 prevC1Offset = c1.position(); | |
528 | 256 } |
257 | |
581 | 258 private void flushMuticast(TreeRFBProto rfb, byte[] bytes) { |
528 | 259 c1.flip(); |
260 //System.out.println("multicastPut: " + c1rect + " length: " + (c1.remaining()-c1headerPos-header.limit())); | |
563 | 261 deflater.reset(); |
262 LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>(); | |
263 bufs.add(c1); | |
581 | 264 rfb.getContext().checkFrameBufferRectanble(c1, bytes, flushOffset, prevoffset); |
572 | 265 flushOffset = prevoffset; |
563 | 266 if (rfb.isTreeManager() && rfb.connectionPresenter.isUseMulticast()) { |
267 for (ByteBuffer buf : bufs) | |
268 rfb.getViewer().getRfbBroadcastListener().multicastUpdateRectangle(buf); | |
269 } else { | |
270 rfb.multicastqueue.put(bufs); | |
271 } | |
528 | 272 } |
273 } | |
526 | 274 |
275 @Override | |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
276 public void decode(Reader reader, Renderer renderer, |
539 | 277 FramebufferUpdateRectangle rect) throws TransportException { |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
278 int zippedLength = (int) reader.readUInt32(); |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
279 if (0 == zippedLength) return; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
280 int length = rect.width * rect.height * renderer.getBytesPerPixel(); |
577 | 281 ByteBuffer buf = unzip(reader, zippedLength, length, rect.getEncodingType()); |
282 decode1(renderer, null, rect, buf, zippedLength, null); | |
539 | 283 } |
533 | 284 |
285 | |
286 public void multicastDecode(Reader reader, Renderer renderer, | |
539 | 287 FramebufferUpdateRectangle rect, TreeRFBProto rfb) throws TransportException { |
288 ByteBuffer header = ByteBuffer.allocate(16); | |
289 reader.read(header.array()); | |
533 | 290 int zippedLength = (int) reader.readUInt32(); |
291 if (0 == zippedLength) return; | |
292 int length = rect.width * rect.height * renderer.getBytesPerPixel(); | |
577 | 293 ByteBuffer buf = unzip(reader, zippedLength, length, rect.getEncodingType()); |
294 decode1(renderer, header, rect, buf, zippedLength, rfb); | |
533 | 295 } |
296 | |
577 | 297 public void decode1(Renderer renderer, ByteBuffer header, FramebufferUpdateRectangle rect, ByteBuffer buf, int zippedLength, TreeRFBProto rfbProto) throws TransportException { |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
298 int offset = zippedLength; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
299 int maxX = rect.x + rect.width; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
300 int maxY = rect.y + rect.height; |
577 | 301 byte[] bytes = buf.array(); |
528 | 302 |
566 | 303 TileLoop tileloop = new TileLoop(rfbProto, zippedLength); |
550
9c0cbe119155
fix make rectangle packet in client
e165729 <e165729@ie.u-ryukyu.ac.jp>
parents:
545
diff
changeset
|
304 //System.out.println("decode1: "+rect.toString()); |
539 | 305 if (null == palette) { |
306 palette = new int[128]; | |
307 } | |
308 if (null == decodedBitmap) { | |
309 decodedBitmap = new int[MAX_TILE_SIZE * MAX_TILE_SIZE]; | |
310 } | |
526 | 311 |
566 | 312 if (rfbProto !=null && rfbProto.multicastBlocking) { |
539 | 313 tileloop.zrleeBlocking(rfbProto, header, rect, bytes); |
526 | 314 } |
539 | 315 try { |
316 for (int tileY = rect.y; tileY < maxY; tileY += MAX_TILE_SIZE) { | |
317 int tileHeight = Math.min(maxY - tileY, MAX_TILE_SIZE); | |
566 | 318 if (tileloop.blocking) |
319 tileloop.c1rect.height += tileHeight; | |
539 | 320 for (int tileX = rect.x; tileX < maxX; tileX += MAX_TILE_SIZE) { |
321 int tileWidth = Math.min(maxX - tileX, MAX_TILE_SIZE); | |
566 | 322 if (tileloop.blocking && tileloop.c1rect.x + tileloop.c1rect.width < rect.x + rect.width) |
564 | 323 tileloop.c1rect.width += tileWidth; |
539 | 324 int subencoding = bytes[offset++] & 0x0ff; |
325 if (subencoding != 0) | |
326 System.out.println("----------------" + subencoding); | |
327 // 128 -plain RLE, 130-255 - Palette RLE | |
328 boolean isRle = (subencoding & 128) != 0; | |
329 // 2 to 16 for raw packed palette data, 130 to 255 for Palette RLE (subencoding - 128) | |
330 int paletteSize = subencoding & 127; | |
331 offset += readPalette(bytes, offset, renderer, paletteSize); | |
332 if (1 == subencoding) { // A solid tile consisting of a single colour | |
333 renderer.fillRect(palette[0], tileX, tileY, tileWidth, tileHeight); | |
334 } else if (isRle) { | |
335 if (0 == paletteSize) { // subencoding == 128 (or paletteSize == 0) - Plain RLE | |
336 offset += decodePlainRle(bytes, offset, renderer, tileX, tileY, tileWidth, tileHeight); | |
337 } else { | |
338 offset += decodePaletteRle(bytes, offset, renderer, tileX, tileY, tileWidth, tileHeight); | |
339 } | |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
340 } else { |
539 | 341 if (0 == paletteSize) { // subencoding == 0 (or paletteSize == 0) - raw CPIXEL data |
342 offset += decodeRaw(bytes, offset, renderer, tileX, tileY, tileWidth, tileHeight); | |
63 | 343 // System.out.println("offset:"+offset); |
539 | 344 } else { |
345 offset += decodePacked(bytes, offset, renderer, paletteSize, tileX, tileY, tileWidth, tileHeight); | |
346 } | |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
347 } |
539 | 348 if (rfbProto != null && rfbProto.multicastBlocking) |
582 | 349 tileloop.multicastPut(rfbProto, false, bytes, offset, tileWidth, tileHeight); |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
350 } |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
351 } |
539 | 352 if (rfbProto != null && rfbProto.multicastBlocking) |
582 | 353 tileloop.multicastPut(rfbProto, true, bytes, offset, 0, 0); |
539 | 354 } catch (Exception e) { |
560 | 355 e.printStackTrace(); |
539 | 356 if (rfbProto != null && rfbProto.multicastBlocking) |
582 | 357 tileloop.multicastPut(rfbProto, true, bytes, offset, 0, 0); |
539 | 358 throw e; |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
359 } |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
360 } |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
361 |
539 | 362 |
363 | |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
364 private int decodePlainRle(byte[] bytes, int offset, Renderer renderer, |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
365 int tileX, int tileY, int tileWidth, int tileHeight) { |
57
17b702648079
version2.7.2 original version.
Taninari YU <you@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
366 int bytesPerCPixel = renderer.getBytesPerCPixel(); |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
367 int decodedOffset = 0; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
368 int decodedEnd = tileWidth * tileHeight; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
369 int index = offset; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
370 while (decodedOffset < decodedEnd) { |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
371 int color = renderer.getCompactPixelColor(bytes, index); |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
372 index += bytesPerCPixel; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
373 int rlength = 1; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
374 do { |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
375 rlength += bytes[index] & 0x0ff; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
376 } while ((bytes[index++] & 0x0ff) == 255); |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
377 assert rlength <= decodedEnd - decodedOffset; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
378 renderer.fillColorBitmapWithColor(decodedBitmap, decodedOffset, rlength, color); |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
379 decodedOffset += rlength; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
380 } |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
381 renderer.drawColoredBitmap(decodedBitmap, tileX, tileY, tileWidth, tileHeight); |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
382 return index - offset; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
383 } |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
384 |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
385 private int decodePaletteRle(byte[] bytes, int offset, Renderer renderer, |
57
17b702648079
version2.7.2 original version.
Taninari YU <you@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
386 int tileX, int tileY, int tileWidth, int tileHeight) { |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
387 int decodedOffset = 0; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
388 int decodedEnd = tileWidth * tileHeight; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
389 int index = offset; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
390 while (decodedOffset < decodedEnd) { |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
391 int colorIndex = bytes[index++]; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
392 int color = palette[colorIndex & 127]; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
393 int rlength = 1; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
394 if ((colorIndex & 128) != 0) { |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
395 do { |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
396 rlength += bytes[index] & 0x0ff; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
397 } while (bytes[index++] == (byte) 255); |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
398 } |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
399 assert rlength <= decodedEnd - decodedOffset; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
400 renderer.fillColorBitmapWithColor(decodedBitmap, decodedOffset, rlength, color); |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
401 decodedOffset += rlength; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
402 } |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
403 renderer.drawColoredBitmap(decodedBitmap, tileX, tileY, tileWidth, tileHeight); |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
404 return index - offset; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
405 } |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
406 |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
407 private int decodePacked(byte[] bytes, int offset, Renderer renderer, |
57
17b702648079
version2.7.2 original version.
Taninari YU <you@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
408 int paletteSize, int tileX, int tileY, int tileWidth, int tileHeight) { |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
409 int bitsPerPalletedPixel = paletteSize > 16 ? 8 : paletteSize > 4 ? 4 |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
410 : paletteSize > 2 ? 2 : 1; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
411 int packedOffset = offset; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
412 int decodedOffset = 0; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
413 for (int i = 0; i < tileHeight; ++i) { |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
414 int decodedRowEnd = decodedOffset + tileWidth; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
415 int byteProcessed = 0; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
416 int bitsRemain = 0; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
417 |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
418 while (decodedOffset < decodedRowEnd) { |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
419 if (bitsRemain == 0) { |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
420 byteProcessed = bytes[packedOffset++]; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
421 bitsRemain = 8; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
422 } |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
423 bitsRemain -= bitsPerPalletedPixel; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
424 int index = byteProcessed >> bitsRemain & (1 << bitsPerPalletedPixel) - 1 & 127; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
425 int color = palette[index]; |
57
17b702648079
version2.7.2 original version.
Taninari YU <you@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
426 renderer.fillColorBitmapWithColor(decodedBitmap, decodedOffset, 1, color); |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
427 ++decodedOffset; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
428 } |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
429 } |
57
17b702648079
version2.7.2 original version.
Taninari YU <you@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
430 renderer.drawColoredBitmap(decodedBitmap, tileX, tileY, tileWidth, tileHeight); |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
431 return packedOffset - offset; |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
432 } |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
433 |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
434 private int decodeRaw(byte[] bytes, int offset, Renderer renderer, |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
435 int tileX, int tileY, int tileWidth, int tileHeight) throws TransportException { |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
436 return renderer.drawCompactBytes(bytes, offset, tileX, tileY, tileWidth, tileHeight); |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
437 } |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
438 |
57
17b702648079
version2.7.2 original version.
Taninari YU <you@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
439 private int readPalette(byte[] bytes, int offset, Renderer renderer, int paletteSize) { |
17b702648079
version2.7.2 original version.
Taninari YU <you@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
440 final int bytesPerCPixel = renderer.getBytesPerCPixel(); |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
441 for (int i=0; i<paletteSize; ++i) { |
57
17b702648079
version2.7.2 original version.
Taninari YU <you@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
442 palette[i] = renderer.getCompactPixelColor(bytes, offset + i* bytesPerCPixel); |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
443 } |
57
17b702648079
version2.7.2 original version.
Taninari YU <you@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
444 return paletteSize * bytesPerCPixel; |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
445 } |
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
446 |
526 | 447 |
448 | |
0
4689cc86d6cb
create TreeViewer2 Repository
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
449 } |