Mercurial > hg > Applications > TreeVNC
diff src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java @ 541:355954eac478
fix ZRLEDecoder
author | riono |
---|---|
date | Thu, 31 Oct 2019 19:19:30 +0900 |
parents | cb7c23cca231 |
children | 00841c822145 |
line wrap: on
line diff
--- a/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java Thu Oct 17 19:05:41 2019 +0900 +++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java Thu Oct 31 19:19:30 2019 +0900 @@ -43,22 +43,15 @@ class TileLoop { private final boolean blocking; - private final int half; private int deflate_size = 55507; private ByteBuffer c1; private int width; // phase2 length private FramebufferUpdateRectangle c1rect; - private int c1headerPos; private int prevLineOffset; private int prevC1Offset; + private int prevC1LineOffset; private int prevoffset; private Deflater deflater; - private int ztileInLine; - private int hwidth; - private int hc1width; - private int hoffset; - private int hc1offset; - private int discard; /** * Multicast framebufferUpdate to children. @@ -89,16 +82,14 @@ blocking = false; } else blocking = true; - discard = 0; - half = 0; } private void zrleeBlocking(TreeRFBProto rfb, ByteBuffer header, FramebufferUpdateRectangle rect, byte bytes[]) { // dump32(inputs); deflater = rfb.deflater; + c1rect = new FramebufferUpdateRectangle(rect.x, rect.y, 0, 0); newMulticastPacket(rfb, rect); c1.put(header.get(0)); - c1rect = new FramebufferUpdateRectangle(rect.x, rect.y, 0, 0); if (!blocking) { deflater.setInput(bytes, 0, prevoffset); deflater.deflate(c1); @@ -114,15 +105,16 @@ 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((byte) 0); c1.put((byte) 0); c1.put((byte) 0); c1.putShort((short) 0); c1.position(c1.position() + 16); c1.putInt(0); // should be data length prevC1Offset = c1.position(); + prevC1LineOffset = prevC1Offset; width = 0; - ztileInLine = 0; + c1rect.width = c1rect.height = 0; } int spanGap = 128; @@ -167,67 +159,68 @@ int span = offset - prevoffset; deflater.setInput(bytes, prevoffset, span); prevoffset = offset; - c1rect.width += tileW; width += tileW; if (c1rect.x > rect.x) { // phase 0 if (c1rect.x + c1rect.width < rect.x + rect.width) { compressAndCheckFlush(rfb, rect, bytes, offset, false, last); } else { c1rect.width = rect.x + rect.width - c1rect.x; - c1rect.height += tileH; + prevC1LineOffset = c1.position(); compressAndCheckFlush(rfb, rect, bytes, offset, true, last); } } else { // phase 1 if (width >= rect.width) { c1rect.width = rect.width; width = 0; - c1rect.height += tileH; prevLineOffset = offset; + prevC1LineOffset = c1.position(); compressAndCheckFlush(rfb, rect, bytes, offset, true, last); } else { compressAndCheckFlush(rfb, rect, bytes, offset, false, last); + + } } } - private void compressAndCheckFlush(TreeRFBProto rfb, FramebufferUpdateRectangle rect, byte[] bytes, int offset, boolean flush, boolean last) { - ztileInLine++; - + private boolean compressAndCheckFlush(TreeRFBProto rfb, FramebufferUpdateRectangle rect, byte[] bytes, int offset, boolean flush, boolean last) { deflater.deflate(c1, Deflater.NO_FLUSH); int headerLength = 20; if (!deflater.needsInput()) { deflater.finish(); if (offset != prevLineOffset) { - prevC1Offset++; + // fix phase1 rectangle header c1.putShort(prevC1Offset + 0, (short) c1rect.x); c1.putShort(prevC1Offset + 2, (short) c1rect.y); c1.putShort(prevC1Offset + 4, (short) c1rect.width); c1.putShort(prevC1Offset + 6, (short) c1rect.height); c1.putInt(prevC1Offset + 8, EncodingType.ZRLEE.getId()); - c1.putInt(prevC1Offset + 12, c1.position() - prevC1Offset - 12); // data length + c1.putInt(prevC1Offset + 12, c1.position() - prevC1LineOffset - 12); // data length c1.putShort(2, (short) (c1.getShort(2) + 1)); // increment rectangle count + if (c1rect.x == rect.x) { // phase0 needs no phase1 // make header space for phase2 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]; + for (int i = 0; i < c1.position() - prevC1LineOffset; i++) { + c1.array()[prevC1LineOffset + headerLength - i] = c1.array()[prevC1LineOffset - i]; } + prevC1Offset = prevC1LineOffset; } } flushRectangle(rect); flushMuticast(rfb); newMulticastPacket(rfb, rect); deflater.deflate(c1, Deflater.NO_FLUSH); + return true; } else if (last) { flushRectangle(rect); flushMuticast(rfb); - return; - } else { - nextBlock(rect); + return true; } + return false; } /** @@ -244,11 +237,12 @@ c1.putInt(prevC1Offset + 8, EncodingType.ZRLEE.getId()); c1.putInt(prevC1Offset + 12, c1.position() - prevC1Offset - 12); // data length c1.putShort(2, (short) (c1.getShort(2) + 1)); // increment rectangle count - ztileInLine = 0; prevC1Offset = c1.position(); + + nextPhase(rect); } - private void nextBlock(FramebufferUpdateRectangle rect) { + private void nextPhase(FramebufferUpdateRectangle rect) { if (c1rect.x + c1rect.width < rect.x + rect.width) { c1rect.x = c1rect.width; // next rectangle is phase 1 } else { @@ -256,8 +250,6 @@ c1rect.y += c1rect.height; } width = 0; - c1rect.width = 0; - c1rect.height = 0; } private void flushMuticast(TreeRFBProto rfb) { @@ -322,9 +314,11 @@ try { for (int tileY = rect.y; tileY < maxY; tileY += MAX_TILE_SIZE) { int tileHeight = Math.min(maxY - tileY, MAX_TILE_SIZE); + tileloop.c1rect.height += tileHeight; for (int tileX = rect.x; tileX < maxX; tileX += MAX_TILE_SIZE) { int tileWidth = Math.min(maxX - tileX, MAX_TILE_SIZE); + tileloop.c1rect.width += tileWidth; int subencoding = bytes[offset++] & 0x0ff; if (subencoding != 0) System.out.println("----------------" + subencoding);