changeset 494:7007d9785737

add zrleeBlocking
author oshiro
date Wed, 06 Feb 2019 20:39:58 +0900
parents 6f21b6176984
children 11f587612329
files src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java
diffstat 1 files changed, 60 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java	Fri Feb 01 18:34:58 2019 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java	Wed Feb 06 20:39:58 2019 +0900
@@ -632,7 +632,7 @@
      * @throws UnsupportedEncodingException
      */
     public void readSendData(int dataLen, Reader reader, byte[] bytes, FramebufferUpdateRectangle rect)
-            throws TransportException, UnsupportedEncodingException {
+            throws Exception {
         LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>();
         int BLOCKSIZE = 64 * 1024;
         int headerLen = rect.getEncodingType() == EncodingType.CHECK_DELAY ? 24 : 16;
@@ -650,6 +650,10 @@
 
             if (encoding == EncodingType.ZRLE.getId()
                     || encoding == EncodingType.ZLIB.getId()) {
+                if (true) {
+                    zrleeBlocking(dataLen, reader, bytes, rect, context.getPixelFormat().bitsPerPixel/8, bufs, header);
+                    return;
+                }
                 // recompress into ZREE
                 // uncompressed result is remain in bytes
                 ByteBuffer len = multicastqueue.allocate(4);
@@ -726,124 +730,65 @@
      * @throws TransportException
      * @throws UnsupportedEncodingException
      */
-    public void blockedReadSendData(int dataLen, Reader reader, byte[] bytes, FramebufferUpdateRectangle rect ,int bytePerPixel)
-            throws TransportException, UnsupportedEncodingException {
-        LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>();
-        int headerLen = rect.getEncodingType() == EncodingType.CHECK_DELAY ? 24 : 16;
-        ByteBuffer header = multicastqueue.allocate(headerLen);
-        ByteBuffer serial = multicastqueue.allocate(4 + 8);
-        if (!isTreeManager() && addSerialNum) {
-            reader.readBytes(serial.array(), 0, 4 + 8);
-            serial.limit(4 + 8);
-        }
-        reader.mark(dataLen);
-        reader.readBytes(header.array(), 0, headerLen);
-        header.limit(headerLen);
-        if (header.get(0) == FramebufferUpdate) {
-            int encoding = header.getInt(12);
+
+
+    private void zrleeBlocking(int dataLen, Reader reader, byte[] bytes, FramebufferUpdateRectangle rect, int bytePerPixel, LinkedList<ByteBuffer> bufs, ByteBuffer header) throws Exception {
+        ByteBuffer len = multicastqueue.allocate(4);
+        reader.readBytes(len.array(), 0, 4);
+        len.limit(4);
+        ByteBuffer inputData = multicastqueue.allocate(dataLen - 20);
+        reader.readBytes(inputData.array(), 0, inputData.capacity());
+        inputData.limit(dataLen - 20);
+        LinkedList<ByteBuffer> inputs = new LinkedList<ByteBuffer>();
+        inputs.add(inputData);
+        header.putInt(12, EncodingType.ZRLEE.getId()); // means
+        // recompress
+        // every time
+        // using new Deflecter every time is incompatible with the
+        // protocol, clients have to be modified.
+        Deflater nDeflater = deflater; // new Deflater();
+        LinkedList<ByteBuffer> out = new LinkedList<ByteBuffer>();
+        int inflate_size = rect.width * rect.height * bytePerPixel;
 
-            if (encoding == EncodingType.ZRLE.getId()
-                    || encoding == EncodingType.ZLIB.getId()) {
-                // recompress into ZREE
-                // uncompressed result is remain in bytes
-                ByteBuffer len = multicastqueue.allocate(4);
-                reader.readBytes(len.array(), 0, 4);
-                len.limit(4);
-                ByteBuffer inputData = multicastqueue.allocate(dataLen - 20);
-                reader.readBytes(inputData.array(), 0, inputData.capacity());
-                inputData.limit(dataLen - 20);
-                LinkedList<ByteBuffer> inputs = new LinkedList<ByteBuffer>();
-                inputs.add(inputData);
-                header.putInt(12, EncodingType.ZRLEE.getId()); // means
-                // recompress
-                // every time
-                // using new Deflecter every time is incompatible with the
-                // protocol, clients have to be modified.
-                Deflater nDeflater = deflater; // new Deflater();
-                LinkedList<ByteBuffer> out = new LinkedList<ByteBuffer>();
-                int inflate_size = INFLATE_BUFSIZE - INFLATE_BUFSIZE % (rect.width * bytePerPixel);
-                try {
-                    unzip(inflater, inputs, 0, bytes, inflate_size);
-                    // dump32(inputs);
-                    out.add(ByteBuffer.wrap(bytes));
-                    int len2 = 0;
-                    int inputIndex = 0;
-                    ByteBuffer c1 = multicastqueue.allocate(deflate_size);
-                    while (inputIndex < inputs.size()) {
-                        ByteBuffer b1 = inputs.get(inputIndex++);
-                        deflater.setInput(b1.array(), b1.position(), b1.remaining());
-                        /**
-                         * If we finish() stream and reset() it, Deflater start new gzip
-                         * stream, this makes continuous zlib reader unhappy. if we remove
-                         * finish(), Deflater.deflate() never flushes its output. The
-                         * original zlib deflate has flush flag. I'm pretty sure this a kind
-                         * of bug of Java library.
-                         */
-                        if (inputIndex == inputs.size())
-                            deflater.finish();
-                        int len1 = 0;
-                        do {
-                            len1 = deflater.deflate(c1.array(), c1.position(),
-                                    c1.remaining());
-                            if (len1 > 0) {
-                                len2 += len1;
-                                c1.position(c1.position() + len1);
-                                if (c1.remaining() == 0) {
-                                    c1.flip();
-                                    bufs.addLast(c1);
-                                    c1 = multicastqueue.allocate(deflate_size);
-                                }
-                            }
-                        } while (len1 > 0 || !deflater.needsInput()); // &&!deflater.finished());
-                    }
-                    if (c1.position() != 0) {
-                        c1.flip();
-                        bufs.addLast(c1);
-                    }
-                    deflater.reset();
+        unzip(inflater, inputs, 0, bytes, inflate_size);
+        // dump32(inputs);
+        out.add(ByteBuffer.wrap(bytes));
+        int inputIndex = 0;
+        ByteBuffer c1 = multicastqueue.allocate(deflate_size);
+        while (inputIndex < inflate_size) {
+            c1.reset();
+            deflater.finish();
+            deflater.setInput(bytes,inputIndex,rect.width * bytePerPixel);
+            if (c1.remaining() < rect.width * bytePerPixel) {
+                deflater.deflate(c1,Deflater.FULL_FLUSH);
+                c1.flip();
+                writeUpdateRectangleWithHeader(c1,header,c1.remaining());
+            } else {
+                deflater.deflate(c1);
+            }
+            inputIndex += rect.width * bytePerPixel;
+        }
+        return;
+    }
 
-                    ByteBuffer blen = multicastqueue.allocate(4);
-                    blen.putInt(len2);
-                    blen.flip();
-                    bufs.addFirst(blen);
-                    if (checkDelay) {
-                        bufs = createCheckDelayHeader(bufs, header);
-                    } else {
-                        bufs.addFirst(header);
-                    }
-                    if (addSerialNum) {
-                        addSerialNumber(bufs);
-                    }
-                    multicastqueue.waitput(bufs);
-                } catch (InterruptedException e) {
-                    throw new TransportException(e);
-                } catch (DataFormatException e) {
-                    throw new TransportException(e);
-                }
-                return;
-            }
+    private void writeUpdateRectangleWithHeader(ByteBuffer c1, ByteBuffer header, int len2) throws InterruptedException {
+        LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>();
+        bufs.add(c1);
+        deflater.reset();
 
-            //    ZRLEE is already compressed
-            bufs.add(header);
-            if (addSerialNum) {
-                this.addSerialNumber(bufs);
-            }
-            if (dataLen > headerLen) {
-                ByteBuffer b = multicastqueue.allocate(dataLen - headerLen);
-                reader.readBytes(b.array(), 0, dataLen - headerLen);
-                b.limit(dataLen - headerLen);
-                bufs.add(b);
-            }
-            multicastqueue.put(bufs);
-
-            return;
+        ByteBuffer blen = multicastqueue.allocate(4);
+        blen.putInt(len2);
+        blen.flip();
+        bufs.addFirst(blen);
+        if (checkDelay) {
+            bufs = createCheckDelayHeader(bufs, header);
+        } else {
+            bufs.addFirst(header);
         }
-        // It may be compressed. We can inflate here to avoid repeating clients
-        // decompressing here,
-        // but it may generate too many large data. It is better to do it in
-        // each client.
-        // But we have do inflation for all input data, so we have to do it
-        // here.
+        if (addSerialNum) {
+            addSerialNumber(bufs);
+        }
+        multicastqueue.waitput(bufs);
     }
 
     public LinkedList<ByteBuffer> createCheckDelayHeader(LinkedList<ByteBuffer> checkDelay, ByteBuffer header) {