changeset 540:b86d445685c7

fix latest ZRLEDecoder
author e165729 <e165729@ie.u-ryukyu.ac.jp>
date Tue, 10 Sep 2019 17:03:16 +0900
parents 0d11471e0b5b
children 2840e75d2fd7
files .hgignore src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java
diffstat 2 files changed, 40 insertions(+), 88 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Thu Sep 05 19:05:02 2019 +0900
+++ b/.hgignore	Tue Sep 10 17:03:16 2019 +0900
@@ -3,3 +3,4 @@
 .gradle
 regexp
 .*.orig
+.idea
\ No newline at end of file
--- a/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java	Thu Sep 05 19:05:02 2019 +0900
+++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java	Tue Sep 10 17:03:16 2019 +0900
@@ -41,10 +41,11 @@
 	private int[] decodedBitmap;
 	private int[] palette;
 
+	// TileLoopクラス 複数の関数持ち
 	class TileLoop {
 		private final boolean blocking;
 		private final int half;
-		private int deflate_size = 55507;  // 圧縮サイズ
+		private int deflate_size = 65507;  // 圧縮サイズ
 		private ByteBuffer c1;            // パケット?
 		private int width; // phase2 length
 		private FramebufferUpdateRectangle c1rect;
@@ -101,10 +102,10 @@
 		// ?: ブロッキングしたものをc1に渡している?
 		private void zrleeBlocking(TreeRFBProto rfb, ByteBuffer header, FramebufferUpdateRectangle rect, byte bytes[]) {
 			// dump32(inputs);
-			deflater = rfb.deflater;
+			deflater = rfb.deflater;    // TreeRFBProtでoverrideしたdeflater(圧縮クラス)を使用
 			newMulticastPacket(rfb, rect);
-			c1.put(header.get(0));
-			c1rect = new FramebufferUpdateRectangle(rect.x, rect.y, 0, 0);
+			c1.put(header.get(0));    // headerの0番目をc1に入れる
+			c1rect = new FramebufferUpdateRectangle(rect.x, rect.y, 0, 0);    // rectangleのインスタンス生成
 			if (!blocking) {
 				deflater.setInput(bytes,0,prevoffset);    // bytesを圧縮データとして0からprevoffsetまでをdeflater内部にセットする
 				deflater.deflate(c1);						// setInputで入力したデータを圧縮してc1に入れる
@@ -113,14 +114,15 @@
 			return;
 		}
 
-		// ?: c1の値を設定している実部分? c1(=パケット)にheaderを設定してるっぽい? 要: TreeRFBProto読み
+		// ?: c1を初期化? 要: TreeRFBProto読み
 		private void newMulticastPacket(TreeRFBProto rfb, FramebufferUpdateRectangle rect) {
-			c1 = rfb.multicastqueue.allocate(deflate_size);  // ByteBufferのallocateと同等
-			if (rfb.addSerialNum)
+			c1 = rfb.multicastqueue.allocate(deflate_size);  // ByteBufferのallocateと同等  容量確保
+			if (rfb.addSerialNum)     // 有効時
 				c1.putLong(rfb.counter++);   // 現在のByteBufferにlongの値を書き込み
-			if (rfb.checkDelay)
+			if (rfb.checkDelay)		// 有効時
 				CheckDelay.checkDelay(c1, rect.x, rect.y, rect.width, rect.height, System.currentTimeMillis(), EncodingType.CHECK_DELAY);
-			c1headerPos = c1.position();
+			c1headerPos = c1.position();    // c1の今の読み込み位置がどこにあるかを記憶 headerの位置
+			// c1の初期化
 			c1.put((byte) 0);
 			c1.put((byte) 0);
 			c1.putShort((short) 0);
@@ -191,11 +193,11 @@
 		// フェーズ分けして、ブロッキングを行なっている部分
 		public void multicastPut(TreeRFBProto rfb, boolean last, FramebufferUpdateRectangle rect, byte[] bytes, int offset, int tileW, int tileH) {
 			if (!blocking) return;
-			int span = offset - prevoffset;    // ?: 現在の位置調整?
-			deflater.setInput(bytes,prevoffset,span);
-			prevoffset = offset;
-			c1rect.width  += tileW; width += tileW;
-			if (c1rect.x > rect.x) {  // phase 0
+			int span = offset - prevoffset;    // 一つ前のオフセットと現在のオフセットの差を出す
+			deflater.setInput(bytes,prevoffset,span);    // prevoffsetからspanまでに圧縮データを入れる
+			prevoffset = offset;						// prevoffsetの更新
+			c1rect.width  += tileW; width += tileW;     // prevoffsetが更新されたのでwidthもタイル一つ分更新?
+			if (c1rect.x > rect.x) {  // phase 0      引数の場所よりも容量が大きい場合 = 行の途中から始まって行の最後までの間
 				if (c1rect.x+c1rect.width < rect.x+rect.width) {
 					compressAndCheckFlush(rfb, rect, bytes, offset,false, last);
 				} else {
@@ -203,7 +205,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;
@@ -214,83 +216,36 @@
 				} 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);
-				}
 			}
 		}
 
+
+		// 圧縮とパケットへの書き込み
 		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);
 		}
 
 		/**
@@ -312,10 +267,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