changeset 538:6620e04f994c

fix ZRLEDecoder
author riono
date Thu, 13 Jun 2019 18:19:53 +0900
parents 623e409c976a
children cb7c23cca231
files src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java src/main/java/jp/ac/u_ryukyu/treevnc/test/ZlibTest.java
diffstat 2 files changed, 26 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java	Wed Jun 05 17:29:04 2019 +0900
+++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java	Thu Jun 13 18:19:53 2019 +0900
@@ -44,7 +44,7 @@
     class TileLoop {
 		private final boolean blocking;
 		private final int half;
-		private int deflate_size = 65507;
+		private int deflate_size = 55507;
 		private ByteBuffer c1;
 		private int width; // phase2 length
 		private FramebufferUpdateRectangle c1rect;
@@ -175,7 +175,7 @@
 					c1rect.height += tileH;
 					compressAndCheckFlush(rfb,rect,bytes,offset,true, last);
 				}
-			} else if (!last && c1.remaining() > spanGap) { // phase 1
+			} else {  // phase 1
 				if (width >= rect.width) {
 					c1rect.width = rect.width;
 					width = 0;
@@ -184,87 +184,40 @@
 					prevC1Offset = c1.position();
 					compressAndCheckFlush(rfb,rect,bytes,offset,true, last);
 				} else {
-					compressAndCheckFlush(rfb,rect,bytes,offset,false, last);
-				}
-			} else { // phase2
-				//  rewind to the last line finish phase 1
-				int savew = width;
-				c1.position(prevC1Offset);
-				flushRectangle(rect);
-				if (savew>0) {
-					// recompress overrun and flush phase 2
-					c1rect.width = savew;
-					c1rect.height = tileH;
-					compressAndCheckFlush(rfb,rect,bytes,offset,true, last);
+					compressAndCheckFlush(rfb, rect, bytes, offset, false, last);
 				}
 			}
 		}
 
 		private void compressAndCheckFlush(TreeRFBProto rfb, FramebufferUpdateRectangle rect, byte[] bytes, int offset, boolean flush, boolean last) {
 			ztileInLine++;
-			if (!flush && ztileInLine < MAX_ZTILE) {
-				if (ztileInLine == MAX_ZTILE/2) {
-					hwidth = width; hc1width = c1rect.width; hoffset = offset; hc1offset = c1.position();
+
+			deflater.deflate(c1, Deflater.NO_FLUSH);
+			int headerLength = 20;
+			if (!deflater.needsInput()) {
+				deflater.finish();
+				if (offset != prevLineOffset) {  // phase 2
+					c1.limit(c1.limit() + headerLength);
+					// to make rectangle header shift last bytes
+					for (int i = 0; i < c1.position() - prevC1Offset; i++) {
+						c1.array()[prevC1Offset + headerLength - i] = c1.array() [prevC1Offset - i];
+					}
+					c1.putShort(prevC1Offset + 1,  (short)c1rect.x);
+					c1.putShort(rectPos + 3,  (short)c1rect.y);
+					c1.putShort(rectPos + 5,  (short)c1rect.width);
+					c1.putShort(rectPos + 7, (short)c1rect.height);
+					c1.putInt(rectPos + 9,EncodingType.ZRLEE.getId());
+					c1.putInt(rectPos + 13, c1.position()-rectPos-12); // data length
+					c1.putShort(2,(short)(c1.getShort(2)+1));    // increment rectangle count
 				}
+				flushMuticast(rfb);
+				newMulticastPacket(rfb, rect);
 				deflater.deflate(c1, Deflater.NO_FLUSH);
-			} else {
-				deflater.deflate(c1, Deflater.SYNC_FLUSH);
-				if (!deflater.needsInput()) {
-					// too large, try half line
-					width = hwidth;
-					c1rect.width = hc1width;
-					c1.position(hc1offset);
-					deflater.setInput(bytes, prevLineOffset, hoffset - prevC1Offset);
-					deflater.deflate(c1, Deflater.SYNC_FLUSH);
-					int from, len;
-					if (!deflater.needsInput()) {
-						// flush previous line and start new packet
-						c1.position(prevC1Offset);
-						unputrectangle();
-						flushMuticast(rfb);
-						newMulticastPacket(rfb, rect);
-						nextRectangle(rect);
-						// we already reached MIX_ZTILE do half of them, do compress right now
-						from = prevC1Offset;
-						len = offset - prevLineOffset;
-						deflater.setInput(bytes, from, len);
-						deflater.deflate(c1, Deflater.SYNC_FLUSH);
-						if (deflater.needsInput()) {
-							flushRectangle(rect);  // we are the flushed last line
-							return;
-						}
-						// half size should always succeed
-						from = prevC1Offset;
-						len = hoffset - prevLineOffset;
-						deflater.setInput(bytes, from, len);
-						deflater.deflate(c1, Deflater.SYNC_FLUSH);
-						if (!deflater.needsInput()) { /* fatal error discard this line */
-							discard++;
-							if (!last) {
-								newMulticastPacket(rfb, rect);
-								nextRectangle(rect);
-							}
-							return;
-						} else
-							flushRectangle(rect);  // normal case
-						// later half is remain continue
-					} else {
-						flushMuticast(rfb);
-						newMulticastPacket(rfb,rect);
-						nextRectangle(rect);
-					}
-					// do later half in new Packet
-					from = hoffset ; len = offset - hoffset;
-					deflater.setInput(bytes, from, len);
-					deflater.deflate(c1, Deflater.NO_FLUSH);
-					hwidth = width;
-					hoffset = offset;
-					hc1offset = c1.position();
-					ztileInLine = MAX_ZTILE/2;
-				}
 			}
+			nextRectangle(rect);
 		}
 
+
 		/**
 		 * fix rectangle header
 		 * create next rectangle header
@@ -284,10 +237,6 @@
 			ztileInLine = 0;
 		}
 
-		private void unputrectangle() {
-			c1.putShort(2,(short)(c1.getShort(2)-1));    // last rectangle is canceled
-		}
-
 		private void nextRectangle(FramebufferUpdateRectangle rect) {
 			if (c1rect.x+c1rect.width < rect.x+rect.width) {
 				c1rect.x = c1rect.width;   // next rectangle is phase 1
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/test/ZlibTest.java	Wed Jun 05 17:29:04 2019 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/test/ZlibTest.java	Thu Jun 13 18:19:53 2019 +0900
@@ -14,7 +14,7 @@
     public void zlibTest() throws IOException {
         deflater = new Deflater();
         ByteBuffer input = ByteBuffer.allocate(64 * 1024);
-        ByteBuffer output
+        ByteBuffer output ;
         while (System.in.available() > 0) {
             int length = System.in.read(input.array(), input.position(), input.remaining());
             input.position(input.position() + length);