changeset 528:2956c4a7bfbd

define TileLoop class
author anatofuz
date Fri, 03 May 2019 18:16:58 +0900
parents 96e15614a31f
children 9de5137e1598
files src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java
diffstat 2 files changed, 171 insertions(+), 165 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java	Thu May 02 17:54:09 2019 +0900
+++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java	Fri May 03 18:16:58 2019 +0900
@@ -35,6 +35,7 @@
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.nio.ByteBuffer;
+import java.util.LinkedList;
 import java.util.zip.DataFormatException;
 import java.util.zip.Deflater;
 
@@ -43,12 +44,171 @@
     private int[] decodedBitmap;
     private int[] palette;
 
-	private int deflate_size = 65507;
-	private ByteBuffer c1;
-	private FramebufferUpdateRectangle c1rect;
-	private int c1headerPos;
-	private int prevLineOffset;
-	private int prevC1Offset;
+    class TileLoop {
+		private int deflate_size = 65507;
+		private ByteBuffer c1;
+		private FramebufferUpdateRectangle c1rect;
+		private int c1headerPos;
+		private int prevLineOffset;
+		private int prevC1Offset;
+		private int prevoffset;
+		private Deflater deflater;
+
+		/**
+		 * Multicast framebufferUpdate to children.
+		 * read FrameBuffferUpdate. If it is ZLE, make it ZLEE which is self contained compressed packet.
+		 * put the packet to the multicastqueue. Then normal rendering engine read the same stream using is.reset().
+		 *
+		 * Haeder
+		 *    messageID  ( FrameBuffer Update
+		 *    1 byte padding
+		 *    2 byte numberofrectangle
+		 *      2 - U16 - x-position
+		 *      2 - U16 - y-position
+		 *      2 - U16 - width
+		 *      2 - U16 - height
+		 *      4 - S32 - encoding-type
+		 *      4 byte datalengths
+		 *      datalengths databyte
+		 *
+		 * @throws TransportException
+		 * @throws UnsupportedEncodingException
+		 */
+
+
+		private void zrleeBlocking(TreeRFBProto rfb, ByteBuffer header, byte[] bytes, FramebufferUpdateRectangle rect) throws TransportException, DataFormatException {
+			// dump32(inputs);
+			deflater = rfb.deflater;
+			c1 = rfb.multicastqueue.allocate(deflate_size);
+			if (rfb.addSerialNum)
+				c1.putLong(rfb.counter++);
+			if (rfb.checkDelay)
+				CheckDelay.checkDelay(c1, rect.x, rect.y, rect.width, rect.height, System.currentTimeMillis(), EncodingType.CHECK_DELAY);
+			c1headerPos = c1.position();
+			c1.put(header);
+			header.flip();
+			c1.putInt(0);
+			c1rect = new FramebufferUpdateRectangle(rect.x, rect.y, 0, 0);
+			return;
+		}
+		int spanGap = 128;
+
+		/**
+		 *
+		 * @param rfb
+		 * @param last
+		 * @param header
+		 * @param rect
+		 * @param bytes
+		 * @param offset
+		 * @param tileX
+		 * @param tileY
+		 * @param tileW
+		 * @param tileH
+		 */
+		public void multicastPut(TreeRFBProto rfb, boolean last, ByteBuffer header, FramebufferUpdateRectangle rect, byte[] bytes, int offset, int tileX, int tileY, int tileW, int tileH) {
+			int span = offset - prevoffset;
+			deflater.setInput(bytes,prevoffset,span);
+			prevoffset = offset;
+			c1rect.height += tileH;
+			c1rect.width  += tileW;
+			if (c1rect.x > rect.x) {  // phase0
+				if (c1.remaining() > span + spanGap && c1rect.width < rect.width) {
+					deflater.deflate(c1, Deflater.SYNC_FLUSH);
+					return;
+				}
+				flushRectangle(rfb, header, rect,  false);
+				return;
+			}
+			if (!last) { // phase1
+				if (c1.remaining() > span + spanGap) {
+					if (c1rect.width >= rect.width) {
+						prevLineOffset = offset;
+						prevC1Offset = c1.position();
+					}
+					deflater.deflate(c1, Deflater.SYNC_FLUSH);
+				} else { // phase2
+					c1.position(prevC1Offset);
+					flushRectangle(rfb, header, rect,  false);
+					deflater.setInput(bytes, prevLineOffset, span);
+					deflater.deflate(c1, Deflater.SYNC_FLUSH);
+					flushRectangle(rfb, header,rect,  false);
+				}
+				return;
+			}
+			flushRectangle(rfb, header, rect, true);
+		}
+
+		/**
+		 * fix rectangle header
+		 * create next rectangle header
+		 * update position paramater
+		 * send muticast pacate if nessesally
+		 * @param rfb
+		 * @param header
+		 * @param rect
+
+		 * @param b
+		 */
+		private void flushRectangle(TreeRFBProto rfb, ByteBuffer header, FramebufferUpdateRectangle rect, boolean b) {
+			flushMuticast(rfb, header, rect);
+		}
+
+		private void flushMuticast(TreeRFBProto rfb, ByteBuffer header, FramebufferUpdateRectangle rect) {
+			deflater.deflate(c1, Deflater.FULL_FLUSH);
+			deflater.finish();
+			c1.flip();
+			//System.out.println("multicastPut: " + c1rect + " length: " + (c1.remaining()-c1headerPos-header.limit()));
+			try {
+				writeUpdateRectangleWithHeader(c1, c1headerPos, c1.remaining()-c1headerPos-header.limit()-4, c1rect.x, c1rect.y, c1rect.width + tileW, c1rect.height + tileY);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+			c1rect.x += c1rect.width;
+			if (c1rect.x >= rect.x + rect.width) {
+				c1rect.x = rect.x;
+				c1rect.y += tileH;
+			}
+			c1rect.width = 0;
+			c1 = rfb.multicastqueue.allocate(deflate_size);
+			if (rfb.addSerialNum)
+				c1.putLong(rfb.counter++);
+			c1headerPos = c1.position();
+			c1.put(header);
+			header.flip();
+			c1.putInt(0);
+		}
+
+		/**
+		 * make and send frameBufferUpdateRectangle packet
+		 * @param c1
+		 * @param headerPos
+		 * @param len2
+		 * @param x
+		 * @param y
+		 * @param w
+		 * @param h
+		 * @throws InterruptedException
+		 *
+		 */
+		public void writeUpdateRectangleWithHeader(ByteBuffer c1, int headerPos, int len2, int x, int y, int w, int h) throws InterruptedException {
+			deflater.reset();
+
+			c1.putInt(headerPos + 16, len2);
+			c1.putShort(headerPos + 4, (short) x);
+			c1.putShort(headerPos + 6, (short) y);
+			c1.putShort(headerPos + 8, (short) w);
+			c1.putShort(headerPos + 10, (short) h);
+			LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>();
+			bufs.add(c1);
+			if (rfb.isTreeManager && rfb.connectionPresenter.isUseMulticast()) {
+				for (ByteBuffer buf : bufs)
+					rfb.viewer.getRfbBroadcastListener().multicastUpdateRectangle(buf);
+			} else {
+				rfb.multicastqueue.waitput(bufs);
+			}
+		}
+	}
 
 	@Override
 	public void decode(Reader reader, Renderer renderer,
@@ -64,7 +224,8 @@
 		int offset = zippedLength;
 		int maxX = rect.x + rect.width;
 		int maxY = rect.y + rect.height;
-		int prevoffset = offset;
+
+		TileLoop tileloop = new TileLoop();
 		//System.out.println("decode1: "+rect);
         if (null == palette) {
             palette = new int [128];
@@ -75,7 +236,7 @@
 
 		if (rfbProto.multicastBlocking)  {
 			try {
-				zrleeBlocking(rfbProto, header, bytes, rect);
+				tileloop.zrleeBlocking(rfbProto, header, bytes, rect);
 			} catch (DataFormatException e) {
 				e.printStackTrace();
 			}
@@ -109,11 +270,10 @@
 						offset += decodePacked(bytes, offset, renderer, paletteSize, tileX, tileY, tileWidth, tileHeight);
 					}
 				}
-				if (rfbProto != null && rfbProto.multicastBlocking) multicastPut(rfbProto, false, header, rect, bytes, prevoffset, offset, tileX, tileY,tileWidth, tileHeight);
-				prevoffset = offset;
+				if (rfbProto != null && rfbProto.multicastBlocking) tileloop.multicastPut(rfbProto, false, header, rect, bytes,  offset, tileX, tileY,tileWidth, tileHeight);
 			}
 		}
-		if (rfbProto != null && rfbProto.multicastBlocking) multicastPut(rfbProto, false, header, rect, bytes, prevoffset, offset, maxX, maxY, 0, 0);
+		if (rfbProto != null && rfbProto.multicastBlocking) tileloop.multicastPut(rfbProto, false, header, rect, bytes,  offset, maxX, maxY, 0, 0);
 	}
 
 	private int decodePlainRle(byte[] bytes, int offset, Renderer renderer,
@@ -200,120 +360,5 @@
 	}
 
 
-	/**
-	 * Multicast framebufferUpdate to children.
-	 * read FrameBuffferUpdate. If it is ZLE, make it ZLEE which is self contained compressed packet.
-	 * put the packet to the multicastqueue. Then normal rendering engine read the same stream using is.reset().
-	 *
-	 * Haeder
-	 *    messageID  ( FrameBuffer Update
-	 *    1 byte padding
-	 *    2 byte numberofrectangle
-	 *      2 - U16 - x-position
-	 *      2 - U16 - y-position
-	 *      2 - U16 - width
-	 *      2 - U16 - height
-	 *      4 - S32 - encoding-type
-	 *      4 byte datalengths
-	 *      datalengths databyte
-	 *
-	 * @throws TransportException
-	 * @throws UnsupportedEncodingException
-	 */
 
-
-	private void zrleeBlocking(TreeRFBProto rfb, ByteBuffer header, byte[] bytes, FramebufferUpdateRectangle rect) throws TransportException, DataFormatException {
-		// dump32(inputs);
-		c1 = rfb.multicastqueue.allocate(deflate_size);
-		if (rfb.addSerialNum)
-			c1.putLong(rfb.counter++);
-		if (rfb.checkDelay)
-			CheckDelay.checkDelay(c1, rect.x, rect.y, rect.width, rect.height, System.currentTimeMillis(), EncodingType.CHECK_DELAY);
-		c1headerPos = c1.position();
-		c1.put(header);
-		header.flip();
-		c1.putInt(0);
-		c1rect = new FramebufferUpdateRectangle(rect.x, rect.y, 0, 0);
-		return;
-	}
-	int spanGap = 128;
-
-	public void multicastPut(TreeRFBProto rfb, boolean last, ByteBuffer header, FramebufferUpdateRectangle rect, byte[] bytes, int prevoffset, int offset, int tileX, int tileY, int tileW, int tileH) {
-		int span = offset - prevoffset;
-		rfb.deflater.setInput(bytes,prevoffset,span);
-		c1rect.height = tileH;
-		if (c1rect.x > 0) {  // phase0
-			if (c1.remaining() > span + spanGap && c1rect.width + tileW < rect.width) {
-				rfb.deflater.deflate(c1, Deflater.SYNC_FLUSH);
-				return;
-			}
-			flushRectangle(rfb, header, offset, rect, tileX, tileY, tileW, tileH, false);
-			return;
-		}
-		if (!last) { // phase1
-			if (c1.remaining() > span + spanGap) {
-				if (tileX == tileW) {
-					prevLineOffset = offset;
-					prevC1Offset = c1.position();
-				}
-				rfb.deflater.deflate(c1, Deflater.SYNC_FLUSH);
-				return;
-			}
-			if (tileX < tileW) { // phase2
-				c1.position(prevC1Offset);
-				flushRectangle(rfb, header, prevoffset, rect, 0, tileY-tileH, tileW, tileH, false);
-				rfb.deflater.setInput(bytes, prevLineOffset, span);
-				rfb.deflater.deflate(c1, Deflater.SYNC_FLUSH);
-				flushRectangle(rfb, header, prevoffset, rect, 0, tileY-tileH, tileW, tileH, false);
-				return;
-			}
-			return;
-		}
-		flushRectangle(rfb, header, prevoffset, rect, 0, tileY-tileH, tileW, tileH, true);
-		c1rect.width += tileW;
-	}
-
-	/**
-	 * fix rectangle header
-	 * create next rectangle header
-	 * update position paramater
-	 * send muticast pacate if necessary
-	 * @param rfb
-	 * @param header
-	 * @param prevoffset
-	 * @param rect
-	 * @param i
-	 * @param i1
-	 * @param tileW
-	 * @param tileH
-	 * @param b
-	 */
-	private void flushRectangle(TreeRFBProto rfb, ByteBuffer header, int prevoffset, FramebufferUpdateRectangle rect, int i, int i1, int tileW, int tileH, boolean b) {
-		flushMuticast(rfb, header, rect, tileY, tileW, tileH);
-	}
-
-	private void flushMuticast(TreeRFBProto rfb, ByteBuffer header, FramebufferUpdateRectangle rect, int tileY, int tileW, int tileH) {
-		rfb.deflater.deflate(c1, Deflater.FULL_FLUSH);
-		rfb.deflater.finish();
-		c1.flip();
-		//System.out.println("multicastPut: " + c1rect + " length: " + (c1.remaining()-c1headerPos-header.limit()));
-		try {
-			rfb.writeUpdateRectangleWithHeader(c1, c1headerPos, c1.remaining()-c1headerPos-header.limit()-4, c1rect.x, c1rect.y, c1rect.width + tileW, c1rect.height + tileY);
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-		}
-		c1rect.x += c1rect.width;
-		if (c1rect.x >= rect.x + rect.width) {
-			c1rect.x = rect.x;
-			c1rect.y += tileH;
-		}
-		c1rect.width = 0;
-		c1 = rfb.multicastqueue.allocate(deflate_size);
-		if (rfb.addSerialNum)
-			c1.putLong(rfb.counter++);
-		c1headerPos = c1.position();
-		c1.put(header);
-		header.flip();
-		c1.putInt(0);
-	}
 }
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java	Thu May 02 17:54:09 2019 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java	Fri May 03 18:16:58 2019 +0900
@@ -724,46 +724,7 @@
 
 
 
-    /**
-     * make and send frameBufferUpdateRectangle packet
-     * @param c1
-     * @param headerPos
-     * @param len2
-     * @param x
-     * @param y
-     * @param w
-     * @param h
-     * @throws InterruptedException
-     *
-     * [8]    sequence number (if used )
-     *  0  0      FRAMEBUFFEUPDATERRECTANGLE  < headerPos
-     *  1  0      padding
-     *  2  int16  count of frame
-     *  4  int16 x
-     *  6  int16 y
-     *  8  int16 w
-     * 10  int16 h
-     * 12  int32  encoding type
-     * 16  [int32]   datalen if zcompressed
-     * 20  compressedData
-     */
-    public void writeUpdateRectangleWithHeader(ByteBuffer c1, int headerPos, int len2, int x, int y, int w, int h) throws InterruptedException {
-        deflater.reset();
 
-        c1.putInt(headerPos + 16, len2);
-        c1.putShort(headerPos + 4, (short) x);
-        c1.putShort(headerPos + 6, (short) y);
-        c1.putShort(headerPos + 8, (short) w);
-        c1.putShort(headerPos + 10, (short) h);
-        LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>();
-        bufs.add(c1);
-        if (isTreeManager && connectionPresenter.isUseMulticast()) {
-            for (ByteBuffer buf : bufs)
-                viewer.getRfbBroadcastListener().multicastUpdateRectangle(buf);
-        } else {
-            multicastqueue.waitput(bufs);
-        }
-    }
 
     public LinkedList<ByteBuffer> createCheckDelayHeader(LinkedList<ByteBuffer> checkDelay, ByteBuffer header) {
         int x = (int) header.getShort(4);