changeset 527:96e15614a31f

create flushRectangle method
author riono210
date Thu, 02 May 2019 17:54:09 +0900
parents fcd833c2e148
children 2956c4a7bfbd
files .idea/modules.xml TreeVNC.iml src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java
diffstat 3 files changed, 97 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/.idea/modules.xml	Thu May 02 16:18:44 2019 +0900
+++ b/.idea/modules.xml	Thu May 02 17:54:09 2019 +0900
@@ -2,7 +2,7 @@
 <project version="4">
   <component name="ProjectModuleManager">
     <modules>
-      <module fileurl="file://$PROJECT_DIR$/.idea/modules/TreeVNC.iml" filepath="$PROJECT_DIR$/.idea/modules/TreeVNC.iml" />
+      <module fileurl="file://$PROJECT_DIR$/TreeVNC.iml" filepath="$PROJECT_DIR$/TreeVNC.iml" />
       <module fileurl="file://$PROJECT_DIR$/.idea/modules/TreeVNC_main.iml" filepath="$PROJECT_DIR$/.idea/modules/TreeVNC_main.iml" group="TreeVNC" />
       <module fileurl="file://$PROJECT_DIR$/.idea/modules/TreeVNC_test.iml" filepath="$PROJECT_DIR$/.idea/modules/TreeVNC_test.iml" group="TreeVNC" />
       <module fileurl="file://$PROJECT_DIR$/.idea/modules/TreeVNC_viewerSwing.iml" filepath="$PROJECT_DIR$/.idea/modules/TreeVNC_viewerSwing.iml" group="TreeVNC" />
--- a/TreeVNC.iml	Thu May 02 16:18:44 2019 +0900
+++ b/TreeVNC.iml	Thu May 02 17:54:09 2019 +0900
@@ -1,13 +1,15 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.id="TreeVNC" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="2.7.2" type="JAVA_MODULE" version="4">
+<module external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="android-gradle" name="Android-Gradle">
+      <configuration>
+        <option name="GRADLE_PROJECT_PATH" value=":" />
+      </configuration>
+    </facet>
+  </component>
   <component name="NewModuleRootManager" inherit-compiler-output="true">
     <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
-      <excludeFolder url="file://$MODULE_DIR$/build" />
-      <excludeFolder url="file://$MODULE_DIR$/out" />
-    </content>
-    <orderEntry type="inheritedJdk" />
+    <content url="file://$MODULE_DIR$" />
     <orderEntry type="sourceFolder" forTests="false" />
   </component>
 </module>
\ No newline at end of file
--- a/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java	Thu May 02 16:18:44 2019 +0900
+++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java	Thu May 02 17:54:09 2019 +0900
@@ -47,6 +47,8 @@
 	private ByteBuffer c1;
 	private FramebufferUpdateRectangle c1rect;
 	private int c1headerPos;
+	private int prevLineOffset;
+	private int prevC1Offset;
 
 	@Override
 	public void decode(Reader reader, Renderer renderer,
@@ -107,10 +109,11 @@
 						offset += decodePacked(bytes, offset, renderer, paletteSize, tileX, tileY, tileWidth, tileHeight);
 					}
 				}
-				if (rfbProto != null && rfbProto.multicastBlocking) multicastPut(rfbProto, rect, bytes, prevoffset, offset, 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) multicastPut(rfbProto, false, header, rect, bytes, prevoffset, offset, maxX, maxY, 0, 0);
 	}
 
 	private int decodePlainRle(byte[] bytes, int offset, Renderer renderer,
@@ -202,6 +205,18 @@
 	 * 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
 	 */
@@ -221,37 +236,84 @@
 		c1rect = new FramebufferUpdateRectangle(rect.x, rect.y, 0, 0);
 		return;
 	}
+	int spanGap = 128;
 
-	public void multicastPut(TreeRFBProto rfb, ByteBuffer header, FramebufferUpdateRectangle rect, byte[] bytes, int prevoffset, int offset, int tileX, int tileY, int tileW, int tileH) {
+	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 (c1.remaining() < span || c1rect.x + c1rect.width + tileW >= rect.x + rect.width ) {
-			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();
+		if (c1rect.x > 0) {  // phase0
+			if (c1.remaining() > span + spanGap && c1rect.width + tileW < rect.width) {
+				rfb.deflater.deflate(c1, Deflater.SYNC_FLUSH);
+				return;
 			}
-			c1rect.x += c1rect.width;
-			if (c1rect.x >= rect.x + rect.width) {
-				c1rect.x = rect.x;
-				c1rect.y += tileH;
+			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;
 			}
-			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);
-		} else {
-			rfb.deflater.deflate(c1, Deflater.SYNC_FLUSH);
+			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);
+	}
 }