# HG changeset patch # User riono # Date 1560417593 -32400 # Node ID 6620e04f994cc0799fbd6fb85cbe9d56a6f57cb5 # Parent 623e409c976a90dd1ad34064bbd0e99b840e242b fix ZRLEDecoder diff -r 623e409c976a -r 6620e04f994c src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java --- 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 diff -r 623e409c976a -r 6620e04f994c src/main/java/jp/ac/u_ryukyu/treevnc/test/ZlibTest.java --- 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);