[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2 08/15] vnc: Add ZRLE and ZYWRLE encodings.
From: |
Blue Swirl |
Subject: |
Re: [Qemu-devel] [PATCH v2 08/15] vnc: Add ZRLE and ZYWRLE encodings. |
Date: |
Thu, 11 Nov 2010 18:58:28 +0000 |
On Thu, Nov 11, 2010 at 4:56 PM, Corentin Chary <address@hidden> wrote:
> Add ZRLE [1] and ZYWRLE [2] encodings. The code is inspire^W stolen
> from libvncserver (again), but have been rewriten to match QEMU coding
> style.
>
> [1] http://www.realvnc.com/docs/rfbproto.pdf
> [2] http://micro-vnc.jp/research/remote_desktop_ng/ZYWRLE/publications/
>
> Signed-off-by: Corentin Chary <address@hidden>
> ---
> Makefile.objs | 1 +
> ui/vnc-enc-zrle-template.c | 275 ++++++++++++++++++
> ui/vnc-enc-zrle.c | 389 +++++++++++++++++++++++++
> ui/vnc-enc-zrle.h | 40 +++
> ui/vnc-enc-zywrle-template.c | 170 +++++++++++
> ui/vnc-enc-zywrle.h | 652
> ++++++++++++++++++++++++++++++++++++++++++
> ui/vnc-jobs-async.c | 2 +
> ui/vnc.c | 15 +
> ui/vnc.h | 27 ++-
> 9 files changed, 1570 insertions(+), 1 deletions(-)
> create mode 100644 ui/vnc-enc-zrle-template.c
> create mode 100644 ui/vnc-enc-zrle.c
> create mode 100644 ui/vnc-enc-zrle.h
> create mode 100644 ui/vnc-enc-zywrle-template.c
> create mode 100644 ui/vnc-enc-zywrle.h
>
> diff --git a/Makefile.objs b/Makefile.objs
> index 15569af..3da959c 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -121,6 +121,7 @@ ui-obj-$(CONFIG_CURSES) += curses.o
> ui-obj-y += vnc.o d3des.o
> ui-obj-y += vnc-enc-zlib.o vnc-enc-hextile.o
> ui-obj-y += vnc-enc-tight.o vnc-palette.o
> +ui-obj-y += vnc-enc-zrle.o
> ui-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o
> ui-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o
> ui-obj-$(CONFIG_COCOA) += cocoa.o
> diff --git a/ui/vnc-enc-zrle-template.c b/ui/vnc-enc-zrle-template.c
> new file mode 100644
> index 0000000..94e92fb
> --- /dev/null
> +++ b/ui/vnc-enc-zrle-template.c
> @@ -0,0 +1,275 @@
> +/*
> + * QEMU VNC display driver: Zlib Run-length Encoding (ZRLE)
> + *
> + * From libvncserver/libvncserver/zrleencodetemplate.c
> + * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
> + * Copyright (C) 2003 Sun Microsystems, Inc.
> + *
> + * Copyright (C) 2010 Corentin Chary <address@hidden>
> + *
> + * This is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This software is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this software; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
> + * USA.
The current address of FSF is:
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301
USA
However, please use the URL version like used elsewhere.
> + */
> +
> +/*
> + * Before including this file, you must define a number of CPP macros.
> + *
> + * ZRLE_BPP should be 8, 16 or 32 depending on the bits per pixel.
> + *
> + * Note that the buf argument to ZRLE_ENCODE needs to be at least one pixel
> + * bigger than the largest tile of pixel data, since the ZRLE encoding
> + * algorithm writes to the position one past the end of the pixel data.
> + */
> +
> +
> +#include <assert.h>
> +
> +#undef ZRLE_ENDIAN_SUFFIX
> +
> +#if ZYWRLE_ENDIAN == ENDIAN_LITTLE
> +#define ZRLE_ENDIAN_SUFFIX le
> +#elif ZYWRLE_ENDIAN == ENDIAN_BIG
> +#define ZRLE_ENDIAN_SUFFIX be
> +#else
> +#define ZRLE_ENDIAN_SUFFIX ne
> +#endif
> +
> +#ifndef ZRLE_CONCAT
> +#define ZRLE_CONCAT_I(a, b) a##b
> +#define ZRLE_CONCAT2(a, b) ZRLE_CONCAT_I(a, b)
> +#define ZRLE_CONCAT3(a, b, c) ZRLE_CONCAT2(a, ZRLE_CONCAT2(b, c))
> +#endif
> +
> +#ifdef ZRLE_COMPACT_PIXEL
> +#define ZRLE_ENCODE_SUFFIX
> ZRLE_CONCAT2(ZRLE_COMPACT_PIXEL,ZRLE_ENDIAN_SUFFIX)
> +#define ZRLE_WRITE_SUFFIX ZRLE_COMPACT_PIXEL
> +#define ZRLE_PIXEL ZRLE_CONCAT3(uint,ZRLE_BPP,_t)
> +#define ZRLE_BPP_OUT 24
> +#elif ZRLE_BPP == 15
> +#define ZRLE_ENCODE_SUFFIX ZRLE_CONCAT2(ZRLE_BPP,ZRLE_ENDIAN_SUFFIX)
> +#define ZRLE_WRITE_SUFFIX 16
> +#define ZRLE_PIXEL uint16_t
> +#define ZRLE_BPP_OUT 16
> +#else
> +#define ZRLE_ENCODE_SUFFIX ZRLE_CONCAT2(ZRLE_BPP,ZRLE_ENDIAN_SUFFIX)
> +#define ZRLE_WRITE_SUFFIX ZRLE_BPP
> +#define ZRLE_BPP_OUT ZRLE_BPP
> +#define ZRLE_PIXEL ZRLE_CONCAT3(uint,ZRLE_BPP,_t)
> +#endif
> +
> +#define ZRLE_WRITE_PIXEL ZRLE_CONCAT2(zrle_write_u,
> ZRLE_WRITE_SUFFIX)
> +#define ZRLE_ENCODE ZRLE_CONCAT2(zrle_encode_,
> ZRLE_ENCODE_SUFFIX)
> +#define ZRLE_ENCODE_TILE ZRLE_CONCAT2(zrle_encode_tile,
> ZRLE_ENCODE_SUFFIX)
> +#define ZRLE_WRITE_PALETTE
> ZRLE_CONCAT2(zrle_write_palette,ZRLE_ENCODE_SUFFIX)
> +
> +static void ZRLE_ENCODE_TILE(VncState *vs, ZRLE_PIXEL *data, int w, int h,
> + int zywrle_level);
> +
> +#if ZRLE_BPP != 8
> +#include "vnc-enc-zywrle-template.c"
> +#endif
> +
> +
> +static void ZRLE_ENCODE(VncState *vs, int x, int y, int w, int h,
> + int zywrle_level)
> +{
> + int ty;
> +
> + for (ty = y; ty < y + h; ty += VNC_ZRLE_TILE_HEIGHT) {
> +
> + int tx, th;
> +
> + th = MIN(VNC_ZRLE_TILE_HEIGHT, y + h - ty);
> +
> + for (tx = x; tx < x + w; tx += VNC_ZRLE_TILE_WIDTH) {
> + int tw;
> + ZRLE_PIXEL *buf;
> +
> + tw = MIN(VNC_ZRLE_TILE_WIDTH, x + w - tx);
> +
> + buf = zrle_convert_fb(vs, tx, ty, tw, th, ZRLE_BPP);
> + ZRLE_ENCODE_TILE(vs, buf, tw, th, zywrle_level);
> + }
> + }
> +}
> +
> +static void ZRLE_ENCODE_TILE(VncState *vs, ZRLE_PIXEL *data, int w, int h,
> + int zywrle_level)
> +{
> + VncPalette *palette = &vs->zrle.palette;
> +
> + int runs = 0;
> + int single_pixels = 0;
> +
> + bool use_rle;
> + bool use_palette;
> +
> + int i;
> +
> + ZRLE_PIXEL *ptr = data;
> + ZRLE_PIXEL *end = ptr + h * w;
> + *end = ~*(end-1); /* one past the end is different so the while loop
> ends */
> +
> + /* Real limit is 127 but we wan't a way to know if there is more than
> 127 */
> + palette_init(palette, 256, ZRLE_BPP);
> +
> + while (ptr < end) {
> + ZRLE_PIXEL pix = *ptr;
> + if (*++ptr != pix) { /* FIXME */
> + single_pixels++;
> + } else {
> + while (*++ptr == pix) ;
> + runs++;
> + }
> + palette_put(palette, pix);
> + }
> +
> + /* Solid tile is a special case */
> +
> + if (palette_size(palette) == 1) {
> + bool found;
> +
> + vnc_write_u8(vs, 1);
> + ZRLE_WRITE_PIXEL(vs, palette_color(palette, 0, &found));
> + return;
> + }
> +
> + zrle_choose_palette_rle(vs, w, h, palette, ZRLE_BPP_OUT,
> + runs, single_pixels, zywrle_level,
> + &use_rle, &use_palette);
> +
> + if (!use_palette) {
> + vnc_write_u8(vs, (use_rle ? 128 : 0));
> + } else {
> + uint32_t colors[VNC_PALETTE_MAX_SIZE];
> + size_t size = palette_size(palette);
> +
> + vnc_write_u8(vs, (use_rle ? 128 : 0) | size);
> + palette_fill(palette, colors);
> +
> + for (i = 0; i < size; i++) {
> + ZRLE_WRITE_PIXEL(vs, colors[i]);
> + }
> + }
> +
> + if (use_rle) {
> + ZRLE_PIXEL *ptr = data;
> + ZRLE_PIXEL *end = ptr + w * h;
> + ZRLE_PIXEL *run_start;
> + ZRLE_PIXEL pix;
> +
> + while (ptr < end) {
> + int len;
> + int index = 0;
> +
> + run_start = ptr;
> + pix = *ptr++;
> +
> + while (*ptr == pix && ptr < end) {
> + ptr++;
> + }
> +
> + len = ptr - run_start;
> +
> + if (use_palette)
> + index = palette_idx(palette, pix);
> +
> + if (len <= 2 && use_palette) {
> + if (len == 2) {
> + vnc_write_u8(vs, index);
> + }
> + vnc_write_u8(vs, index);
> + continue;
> + }
> + if (use_palette) {
> + vnc_write_u8(vs, index | 128);
> + } else {
> + ZRLE_WRITE_PIXEL(vs, pix);
> + }
> +
> + len -= 1;
> +
> + while (len >= 255) {
> + vnc_write_u8(vs, 255);
> + len -= 255;
> + }
> +
> + vnc_write_u8(vs, len);
> + }
> + } else if (use_palette) { /* no RLE */
> + int bppp;
> + ZRLE_PIXEL *ptr = data;
> +
> + /* packed pixels */
> +
> + assert (palette_size(palette) < 17);
> +
> + bppp = bits_per_packed_pixel[palette_size(palette)-1];
> +
> + for (i = 0; i < h; i++) {
> + uint8_t nbits = 0;
> + uint8_t byte = 0;
> +
> + ZRLE_PIXEL *eol = ptr + w;
> +
> + while (ptr < eol) {
> + ZRLE_PIXEL pix = *ptr++;
> + uint8_t index = palette_idx(palette, pix);
> +
> + byte = (byte << bppp) | index;
> + nbits += bppp;
> + if (nbits >= 8) {
> + vnc_write_u8(vs, byte);
> + nbits = 0;
> + }
> + }
> + if (nbits > 0) {
> + byte <<= 8 - nbits;
> + vnc_write_u8(vs, byte);
> + }
> + }
> + } else {
> +
> + /* raw */
> +
> +#if ZRLE_BPP != 8
> + if (zywrle_level > 0 && !(zywrle_level & 0x80)) {
> + ZYWRLE_ANALYZE(data, data, w, h, w, zywrle_level,
> vs->zywrle.buf);
> + ZRLE_ENCODE_TILE(vs, data, w, h, zywrle_level | 0x80);
> + }
> + else
> +#endif
> + {
> +#ifdef ZRLE_COMPACT_PIXEL
> + ZRLE_PIXEL *ptr;
> +
> + for (ptr = data; ptr < data + w * h; ptr++) {
> + ZRLE_WRITE_PIXEL(vs, *ptr);
> + }
> +#else
> + vnc_write(vs, data, w * h * (ZRLE_BPP / 8));
> +#endif
> + }
> + }
> +}
> +
> +#undef ZRLE_PIXEL
> +#undef ZRLE_WRITE_PIXEL
> +#undef ZRLE_ENCODE
> +#undef ZRLE_ENCODE_TILE
> +#undef ZYWRLE_ENCODE_TILE
> +#undef ZRLE_BPP_OUT
> +#undef ZRLE_WRITE_SUFFIX
> +#undef ZRLE_ENCODE_SUFFIX
> diff --git a/ui/vnc-enc-zrle.c b/ui/vnc-enc-zrle.c
> new file mode 100644
> index 0000000..4460890
> --- /dev/null
> +++ b/ui/vnc-enc-zrle.c
> @@ -0,0 +1,389 @@
> +/*
> + * QEMU VNC display driver: Zlib Run-length Encoding (ZRLE)
> + *
> + * From libvncserver/libvncserver/zrle.c
> + * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
> + * Copyright (C) 2003 Sun Microsystems, Inc.
> + *
> + * Copyright (C) 2010 Corentin Chary <address@hidden>
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> deal
> + * in the Software without restriction, including without limitation the
> rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#include "vnc.h"
> +#include "vnc-enc-zrle.h"
> +
> +static const int bits_per_packed_pixel[] = {
> + 0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
> +};
> +
> +
> +static void vnc_zrle_start(VncState *vs)
> +{
> + buffer_reset(&vs->zrle.zrle);
> +
> + // make the output buffer be the zlib buffer, so we can compress it later
Please use C89 comments.
> + vs->zrle.tmp = vs->output;
> + vs->output = vs->zrle.zrle;
> +}
> +
> +static void vnc_zrle_stop(VncState *vs)
> +{
> + // switch back to normal output/zlib buffers
> + vs->zrle.zrle = vs->output;
> + vs->output = vs->zrle.tmp;
> +}
> +
> +static void *zrle_convert_fb(VncState *vs, int x, int y, int w, int h,
> + int bpp)
> +{
> + Buffer tmp;
> +
> + buffer_reset(&vs->zrle.fb);
> + buffer_reserve(&vs->zrle.fb, w * h * bpp + bpp);
> +
> + tmp = vs->output;
> + vs->output = vs->zrle.fb;
> +
> + vnc_raw_send_framebuffer_update(vs, x, y, w, h);
> +
> + vs->zrle.fb = vs->output;
> + vs->output = tmp;
> + return vs->zrle.fb.buffer;
> +}
> +
> +static int zrle_compress_data(VncState *vs, int level)
> +{
> + z_streamp zstream = &vs->zrle.stream;
> +
> + buffer_reset(&vs->zrle.zlib);
> +
> + if (zstream->opaque != vs) {
> + int err;
> +
> + zstream->zalloc = vnc_zlib_zalloc;
> + zstream->zfree = vnc_zlib_zfree;
> +
> + err = deflateInit2(zstream, level, Z_DEFLATED, MAX_WBITS,
> + MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
> +
> + if (err != Z_OK) {
> + fprintf(stderr, "VNC: error initializing zlib\n");
> + return -1;
> + }
> +
> + zstream->opaque = vs;
> + }
> +
> + /* reserve memory in output buffer */
> + buffer_reserve(&vs->zrle.zlib, vs->zrle.zrle.offset + 64);
> +
> + /* set pointers */
> + zstream->next_in = vs->zrle.zrle.buffer;
> + zstream->avail_in = vs->zrle.zrle.offset;
> + zstream->next_out = vs->zrle.zlib.buffer + vs->zrle.zlib.offset;
> + zstream->avail_out = vs->zrle.zlib.capacity - vs->zrle.zlib.offset;
> + zstream->data_type = Z_BINARY;
> +
> + /* start encoding */
> + if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
> + fprintf(stderr, "VNC: error during zrle compression\n");
> + return -1;
> + }
> +
> + vs->zrle.zlib.offset = vs->zrle.zlib.capacity - zstream->avail_out;
> + return vs->zrle.zlib.offset;
> +}
> +
> +/* Try to work out whether to use RLE and/or a palette. We do this by
> + * estimating the number of bytes which will be generated and picking the
> + * method which results in the fewest bytes. Of course this may not result
> + * in the fewest bytes after compression... */
> +static void zrle_choose_palette_rle(VncState *vs, int w, int h,
> + VncPalette *palette, int bpp_out,
> + int runs, int single_pixels,
> + int zywrle_level,
> + bool *use_rle, bool *use_palette)
> +{
> + size_t estimated_bytes;
> + size_t plain_rle_bytes;
> +
> + *use_palette = *use_rle = false;
> +
> + estimated_bytes = w * h * (bpp_out / 8); /* start assuming raw */
> +
> + if (bpp_out != 8) {
> + if (zywrle_level > 0 && !(zywrle_level & 0x80))
> + estimated_bytes >>= zywrle_level;
> + }
> +
> + plain_rle_bytes = ((bpp_out / 8) + 1) * (runs + single_pixels);
> +
> + if (plain_rle_bytes < estimated_bytes) {
> + *use_rle = true;
> + estimated_bytes = plain_rle_bytes;
> + }
> +
> + if (palette_size(palette) < 128) {
> + int palette_rle_bytes;
> +
> + palette_rle_bytes = (bpp_out / 8) * palette_size(palette);
> + palette_rle_bytes += 2 * runs + single_pixels;
> +
> + if (palette_rle_bytes < estimated_bytes) {
> + *use_rle = true;
> + *use_palette = true;
> + estimated_bytes = palette_rle_bytes;
> + }
> +
> + if (palette_size(palette) < 17) {
> + int packed_bytes;
> +
> + packed_bytes = (bpp_out / 8) * palette_size(palette);
> + packed_bytes += w * h *
> + bits_per_packed_pixel[palette_size(palette)-1] / 8;
> +
> + if (packed_bytes < estimated_bytes) {
> + *use_rle = false;
> + *use_palette = true;
> + estimated_bytes = packed_bytes;
> + }
> + }
> + }
> +}
> +
> +static void zrle_write_u32(VncState *vs, uint32_t value)
> +{
> + uint8_t buf[4];
> +
> + buf[0] = ((uint8_t *)&value)[0];
> + buf[1] = ((uint8_t *)&value)[1];
> + buf[2] = ((uint8_t *)&value)[2];
> + buf[3] = ((uint8_t *)&value)[3];
These don't look endian safe, please use for example buf[0] = value &
0xff; etc. Also below.
> +
> + vnc_write(vs, buf, 4);
> +}
> +
> +static void zrle_write_u24a(VncState *vs, uint32_t value)
> +{
> + uint8_t buf[3];
> +
> + buf[0] = ((uint8_t *)&value)[0];
> + buf[1] = ((uint8_t *)&value)[1];
> + buf[2] = ((uint8_t *)&value)[2];
> +
> + vnc_write(vs, buf, 3);
> +}
> +
> +static void zrle_write_u24b(VncState *vs, uint32_t value)
> +{
> + uint8_t buf[3];
> +
> + buf[0] = ((uint8_t *)&value)[1];
> + buf[1] = ((uint8_t *)&value)[2];
> + buf[2] = ((uint8_t *)&value)[3];
> +
> + vnc_write(vs, buf, 3);
> +}
> +
> +static void zrle_write_u16(VncState *vs, uint16_t value)
> +{
> + uint8_t buf[2];
> +
> + buf[0] = ((uint8_t *)&value)[0];
> + buf[1] = ((uint8_t *)&value)[1];
> +
> + vnc_write(vs, buf, 2);
> +}
> +
> +static void zrle_write_u8(VncState *vs, uint8_t value)
> +{
> + vnc_write_u8(vs, value);
> +}
> +
> +#define ENDIAN_LITTLE 0
> +#define ENDIAN_BIG 1
> +#define ENDIAN_NO 2
> +
> +#define ZRLE_BPP 8
> +#define ZYWRLE_ENDIAN ENDIAN_NO
> +#include "vnc-enc-zrle-template.c"
> +#undef ZRLE_BPP
> +
> +#define ZRLE_BPP 15
> +#undef ZYWRLE_ENDIAN
> +#define ZYWRLE_ENDIAN ENDIAN_LITTLE
> +#include "vnc-enc-zrle-template.c"
> +
> +#undef ZYWRLE_ENDIAN
> +#define ZYWRLE_ENDIAN ENDIAN_BIG
> +#include "vnc-enc-zrle-template.c"
> +
> +#undef ZRLE_BPP
> +#define ZRLE_BPP 16
> +#undef ZYWRLE_ENDIAN
> +#define ZYWRLE_ENDIAN ENDIAN_LITTLE
> +#include "vnc-enc-zrle-template.c"
> +
> +#undef ZYWRLE_ENDIAN
> +#define ZYWRLE_ENDIAN ENDIAN_BIG
> +#include "vnc-enc-zrle-template.c"
> +
> +#undef ZRLE_BPP
> +#define ZRLE_BPP 32
> +#undef ZYWRLE_ENDIAN
> +#define ZYWRLE_ENDIAN ENDIAN_LITTLE
> +#include "vnc-enc-zrle-template.c"
> +
> +#undef ZYWRLE_ENDIAN
> +#define ZYWRLE_ENDIAN ENDIAN_BIG
> +#include "vnc-enc-zrle-template.c"
> +
> +#define ZRLE_COMPACT_PIXEL 24a
> +#undef ZYWRLE_ENDIAN
> +#define ZYWRLE_ENDIAN ENDIAN_LITTLE
> +#include "vnc-enc-zrle-template.c"
> +
> +#undef ZYWRLE_ENDIAN
> +#define ZYWRLE_ENDIAN ENDIAN_BIG
> +#include "vnc-enc-zrle-template.c"
> +
> +#undef ZRLE_COMPACT_PIXEL
> +#define ZRLE_COMPACT_PIXEL 24b
> +#undef ZYWRLE_ENDIAN
> +#define ZYWRLE_ENDIAN ENDIAN_LITTLE
> +#include "vnc-enc-zrle-template.c"
> +
> +#undef ZYWRLE_ENDIAN
> +#define ZYWRLE_ENDIAN ENDIAN_BIG
> +#include "vnc-enc-zrle-template.c"
> +#undef ZRLE_COMPACT_PIXEL
> +#undef ZRLE_BPP
> +
> +static int zrle_send_framebuffer_update(VncState *vs, int x, int y,
> + int w, int h)
> +{
> + bool be = !!(vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG);
The indentation is too small.
> + size_t bytes;
> + int zywrle_level;
> +
> + if (vs->zrle.type == VNC_ENCODING_ZYWRLE) {
> + if (!vs->vd->lossy || vs->tight.quality < 0 || vs->tight.quality == 9)
> {
> + zywrle_level = 0;
> + vs->zrle.type = VNC_ENCODING_ZRLE;
> + } else if (vs->tight.quality < 3) {
> + zywrle_level = 3;
> + } else if (vs->tight.quality < 6) {
> + zywrle_level = 2;
> + } else {
> + zywrle_level = 1;
> + }
> + } else {
> + zywrle_level = 0;
> + }
> +
> + vnc_zrle_start(vs);
> +
> + switch(vs->clientds.pf.bytes_per_pixel) {
> + case 1:
> + zrle_encode_8ne(vs, x, y, w, h, zywrle_level);
> + break;
> +
> + case 2:
> + if (vs->clientds.pf.gmax > 0x1F) {
> + if (be) {
> + zrle_encode_16be(vs, x, y, w, h, zywrle_level);
> + } else {
> + zrle_encode_16le(vs, x, y, w, h, zywrle_level);
> + }
> + } else {
> + if (be) {
> + zrle_encode_15be(vs, x, y, w, h, zywrle_level);
> + } else {
> + zrle_encode_15le(vs, x, y, w, h, zywrle_level);
> + }
> + }
> + break;
> +
> + case 4:
> + {
> + bool fits_in_ls3bytes;
> + bool fits_in_ms3bytes;
> +
> + fits_in_ls3bytes =
> + ((vs->clientds.pf.rmax << vs->clientds.pf.rshift) < (1 << 24) &&
> + (vs->clientds.pf.gmax << vs->clientds.pf.gshift) < (1 << 24) &&
> + (vs->clientds.pf.bmax << vs->clientds.pf.bshift) < (1 << 24));
> +
> + fits_in_ms3bytes = (vs->clientds.pf.rshift > 7 &&
> + vs->clientds.pf.gshift > 7 &&
> + vs->clientds.pf.bshift > 7);
> +
> + if ((fits_in_ls3bytes && !be) || (fits_in_ms3bytes && be)) {
> + if (be) {
> + zrle_encode_24abe(vs, x, y, w, h, zywrle_level);
> + } else {
> + zrle_encode_24ale(vs, x, y, w, h, zywrle_level);
> + }
> + } else if ((fits_in_ls3bytes && be) || (fits_in_ms3bytes && !be)) {
> + if (be) {
> + zrle_encode_24bbe(vs, x, y, w, h, zywrle_level);
> + } else {
> + zrle_encode_24ble(vs, x, y, w, h, zywrle_level);
> + }
> + } else {
> + if (be) {
> + zrle_encode_32be(vs, x, y, w, h, zywrle_level);
> + } else {
> + zrle_encode_32le(vs, x, y, w, h, zywrle_level);
> + }
> + }
> + }
> + break;
> + }
> +
> + vnc_zrle_stop(vs);
> + bytes = zrle_compress_data(vs, Z_DEFAULT_COMPRESSION);
> + vnc_framebuffer_update(vs, x, y, w, h, vs->zrle.type);
> + vnc_write_u32(vs, bytes);
> + vnc_write(vs, vs->zrle.zlib.buffer, vs->zrle.zlib.offset);
> + return 1;
> +}
> +
> +int vnc_zrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int
> h)
> +{
> + vs->zrle.type = VNC_ENCODING_ZRLE;
> + return zrle_send_framebuffer_update(vs, x, y, w, h);
> +}
> +
> +int vnc_zywrle_send_framebuffer_update(VncState *vs, int x, int y, int w,
> int h)
> +{
> + vs->zrle.type = VNC_ENCODING_ZYWRLE;
> + return zrle_send_framebuffer_update(vs, x, y, w, h);
> +}
> +
> +void vnc_zrle_clear(VncState *vs)
> +{
> + if (vs->zrle.stream.opaque) {
> + deflateEnd(&vs->zrle.stream);
> + }
> + buffer_free(&vs->zrle.zrle);
> + buffer_free(&vs->zrle.fb);
> + buffer_free(&vs->zrle.zlib);
> +}
> diff --git a/ui/vnc-enc-zrle.h b/ui/vnc-enc-zrle.h
> new file mode 100644
> index 0000000..6b18213
> --- /dev/null
> +++ b/ui/vnc-enc-zrle.h
> @@ -0,0 +1,40 @@
> +/*
> + * QEMU VNC display driver: Zlib Run-length Encoding (ZRLE)
> + *
> + * From libvncserver/libvncserver/zrle.c
> + * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
> + * Copyright (C) 2003 Sun Microsystems, Inc.
> + *
> + * Copyright (C) 2010 Corentin Chary <address@hidden>
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> copy
> + * of this software and associated documentation files (the "Software"), to
> deal
> + * in the Software without restriction, including without limitation the
> rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#ifndef VNC_ENCODING_ZRLE_H
> +#define VNC_ENCODING_ZRLE_H
> +
> +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> - -
> + * ZRLE - encoding combining Zlib compression, tiling, palettisation and
> + * run-length encoding.
> + */
> +
> +#define VNC_ZRLE_TILE_WIDTH 64
> +#define VNC_ZRLE_TILE_HEIGHT 64
> +
> +#endif
> diff --git a/ui/vnc-enc-zywrle-template.c b/ui/vnc-enc-zywrle-template.c
> new file mode 100644
> index 0000000..4cde6e4
> --- /dev/null
> +++ b/ui/vnc-enc-zywrle-template.c
> @@ -0,0 +1,170 @@
> +
> +/********************************************************************
> + * *
> + * THIS FILE IS PART OF THE 'ZYWRLE' VNC CODEC SOURCE CODE. *
> + * *
> + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
> + * GOVERNED BY A FOLLOWING BSD-STYLE SOURCE LICENSE. *
> + * PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
> + * *
> + * THE 'ZYWRLE' VNC CODEC SOURCE CODE IS (C) COPYRIGHT 2006 *
> + * BY Hitachi Systems & Services, Ltd. *
> + * (Noriaki Yamazaki, Research & Developement Center) *
> + * *
> + * *
> + ********************************************************************
> +Redistribution and use in source and binary forms, with or without
> +modification, are permitted provided that the following conditions
> +are met:
> +
> +- Redistributions of source code must retain the above copyright
> +notice, this list of conditions and the following disclaimer.
> +
> +- Redistributions in binary form must reproduce the above copyright
> +notice, this list of conditions and the following disclaimer in the
> +documentation and/or other materials provided with the distribution.
> +
> +- Neither the name of the Hitachi Systems & Services, Ltd. nor
> +the names of its contributors may be used to endorse or promote
> +products derived from this software without specific prior written
> +permission.
> +
> +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
> +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + ********************************************************************/
> +
> +/* Change Log:
> + V0.02 : 2008/02/04 : Fix mis encode/decode when width != scanline
> + (Thanks Johannes Schindelin, author of LibVNC
> + Server/Client)
> + V0.01 : 2007/02/06 : Initial release
> +*/
> +
> +/*
> +[References]
> + PLHarr:
> + Senecal, J. G., P. Lindstrom, M. A. Duchaineau, and K. I. Joy,
> + "An Improved N-Bit to N-Bit Reversible Haar-Like Transform,"
> + Pacific Graphics 2004, October 2004, pp. 371-380.
> + EZW:
> + Shapiro, JM: Embedded Image Coding Using Zerotrees of Wavelet
> Coefficients,
> + IEEE Trans. Signal. Process., Vol.41, pp.3445-3462 (1993).
> +*/
> +
> +
> +/* Template Macro stuffs. */
> +#undef ZYWRLE_ANALYZE
> +#undef ZYWRLE_SYNTHESIZE
> +
> +#define ZYWRLE_SUFFIX ZRLE_CONCAT2(ZRLE_BPP,ZRLE_ENDIAN_SUFFIX)
> +
> +#define ZYWRLE_ANALYZE ZRLE_CONCAT2(zywrle_analyze_, ZYWRLE_SUFFIX)
> +#define ZYWRLE_SYNTHESIZE ZRLE_CONCAT2(zywrle_synthesize_,ZYWRLE_SUFFIX)
> +
> +#define ZYWRLE_RGBYUV ZRLE_CONCAT2(zywrle_rgbyuv_, ZYWRLE_SUFFIX)
> +#define ZYWRLE_YUVRGB ZRLE_CONCAT2(zywrle_yuvrgb_, ZYWRLE_SUFFIX)
> +#define ZYWRLE_YMASK ZRLE_CONCAT2(ZYWRLE_YMASK, ZRLE_BPP)
> +#define ZYWRLE_UVMASK ZRLE_CONCAT2(ZYWRLE_UVMASK, ZRLE_BPP)
> +#define ZYWRLE_LOAD_PIXEL ZRLE_CONCAT2(ZYWRLE_LOAD_PIXEL, ZRLE_BPP)
> +#define ZYWRLE_SAVE_PIXEL ZRLE_CONCAT2(ZYWRLE_SAVE_PIXEL, ZRLE_BPP)
> +
> +/* Packing/Unpacking pixel stuffs.
> + Endian conversion stuffs. */
> +#undef S_0
> +#undef S_1
> +#undef L_0
> +#undef L_1
> +#undef L_2
> +
> +#if ZYWRLE_ENDIAN == ENDIAN_BIG
> +# define S_0 1
> +# define S_1 0
> +# define L_0 3
> +# define L_1 2
> +# define L_2 1
> +#else
> +# define S_0 0
> +# define S_1 1
> +# define L_0 0
> +# define L_1 1
> +# define L_2 2
> +#endif
> +
> +#define ZYWRLE_QUANTIZE
> +#include "vnc-enc-zywrle.h"
> +
> +#ifndef ZRLE_COMPACT_PIXEL
> +static inline void ZYWRLE_RGBYUV(int *buf, ZRLE_PIXEL *data,
> + int width, int height, int scanline)
> +{
> + int r, g, b;
> + int y, u, v;
> + int *line;
> + int *end;
> +
> + end = buf + height * width;
> + while (buf < end) {
> + line = buf + width;
> + while (buf < line) {
> + ZYWRLE_LOAD_PIXEL(data, r, g, b);
> + ZYWRLE_RGBYUV_(r, g, b, y, u, v, ZYWRLE_YMASK, ZYWRLE_UVMASK);
> + ZYWRLE_SAVE_COEFF(buf, v, y, u);
> + buf++;
> + data++;
> + }
> + data += scanline - width;
> + }
> +}
> +
> +static ZRLE_PIXEL *ZYWRLE_ANALYZE(ZRLE_PIXEL *dst, ZRLE_PIXEL *src,
> + int w, int h, int scanline, int level,
> + int *buf) {
> + int l;
> + int uw = w;
> + int uh = h;
> + int *top;
> + int *end;
> + int *line;
> + ZRLE_PIXEL *p;
> + int r, g, b;
> + int s;
> + int *ph;
> +
> + zywrle_calc_size(&w, &h, level);
> +
> + if (w == 0 || h == 0) {
> + return NULL;
> + }
> + uw -= w;
> + uh -= h;
> +
> + p = dst;
> + ZYWRLE_LOAD_UNALIGN(src,*(ZRLE_PIXEL*)top = *p;);
> + ZYWRLE_RGBYUV(buf, src, w, h, scanline);
> + wavelet(buf, w, h, level);
> + for (l = 0; l < level; l++) {
> + ZYWRLE_PACK_COEFF(buf, dst, 3, w, h, scanline, l);
> + ZYWRLE_PACK_COEFF(buf, dst, 2, w, h, scanline, l);
> + ZYWRLE_PACK_COEFF(buf, dst, 1, w, h, scanline, l);
> + if (l == level - 1) {
> + ZYWRLE_PACK_COEFF(buf, dst, 0, w, h, scanline, l);
> + }
> + }
> + ZYWRLE_SAVE_UNALIGN(dst,*dst = *(ZRLE_PIXEL*)top;);
> + return dst;
> +}
> +#endif /* ZRLE_COMPACT_PIXEL */
> +
> +#undef ZYWRLE_RGBYUV
> +#undef ZYWRLE_YUVRGB
> +#undef ZYWRLE_LOAD_PIXEL
> +#undef ZYWRLE_SAVE_PIXEL
> diff --git a/ui/vnc-enc-zywrle.h b/ui/vnc-enc-zywrle.h
> new file mode 100644
> index 0000000..722bd7d
> --- /dev/null
> +++ b/ui/vnc-enc-zywrle.h
> @@ -0,0 +1,652 @@
> +/********************************************************************
> + * *
> + * THIS FILE IS PART OF THE 'ZYWRLE' VNC CODEC SOURCE CODE. *
> + * *
> + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
> + * GOVERNED BY A FOLLOWING BSD-STYLE SOURCE LICENSE. *
> + * PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
> + * *
> + * THE 'ZYWRLE' VNC CODEC SOURCE CODE IS (C) COPYRIGHT 2006 *
> + * BY Hitachi Systems & Services, Ltd. *
> + * (Noriaki Yamazaki, Research & Developement Center) *
> + * *
> + * *
> + ********************************************************************
> +Redistribution and use in source and binary forms, with or without
> +modification, are permitted provided that the following conditions
> +are met:
> +
> +- Redistributions of source code must retain the above copyright
> +notice, this list of conditions and the following disclaimer.
> +
> +- Redistributions in binary form must reproduce the above copyright
> +notice, this list of conditions and the following disclaimer in the
> +documentation and/or other materials provided with the distribution.
> +
> +- Neither the name of the Hitachi Systems & Services, Ltd. nor
> +the names of its contributors may be used to endorse or promote
> +products derived from this software without specific prior written
> +permission.
> +
> +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
> +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + ********************************************************************/
> +
> +#ifndef VNC_ENCODING_ZYWRLE_H
> +#define VNC_ENCODING_ZYWRLE_H
> +
> +/* Tables for Coefficients filtering. */
> +#ifndef ZYWRLE_QUANTIZE
> +/* Type A:lower bit omitting of EZW style. */
> +const static unsigned int zywrle_param[3][3]={
This should be 'static const'.
> + {0x0000F000,0x00000000,0x00000000},
There should be a space after commas.
> + {0x0000C000,0x00F0F0F0,0x00000000},
> + {0x0000C000,0x00C0C0C0,0x00F0F0F0},
> +/* {0x0000FF00,0x00000000,0x00000000},
> + {0x0000FF00,0x00FFFFFF,0x00000000},
> + {0x0000FF00,0x00FFFFFF,0x00FFFFFF}, */
> +};
> +#else
> +/* Type B:Non liner quantization filter. */
> +static const signed char zywrle_conv[4][256]={
I'd use int8_t here.
> +{ /* bi=5, bo=5 r=0.0:PSNR=24.849 */
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> +},
> +{ /* bi=5, bo=5 r=2.0:PSNR=74.031 */
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 32,
> + 32, 32, 32, 32, 32, 32, 32, 32,
> + 32, 32, 32, 32, 32, 32, 32, 32,
> + 48, 48, 48, 48, 48, 48, 48, 48,
> + 48, 48, 48, 56, 56, 56, 56, 56,
> + 56, 56, 56, 56, 64, 64, 64, 64,
> + 64, 64, 64, 64, 72, 72, 72, 72,
> + 72, 72, 72, 72, 80, 80, 80, 80,
> + 80, 80, 88, 88, 88, 88, 88, 88,
> + 88, 88, 88, 88, 88, 88, 96, 96,
> + 96, 96, 96, 104, 104, 104, 104, 104,
> + 104, 104, 104, 104, 104, 112, 112, 112,
> + 112, 112, 112, 112, 112, 112, 120, 120,
> + 120, 120, 120, 120, 120, 120, 120, 120,
> + 0, -120, -120, -120, -120, -120, -120, -120,
> + -120, -120, -120, -112, -112, -112, -112, -112,
> + -112, -112, -112, -112, -104, -104, -104, -104,
> + -104, -104, -104, -104, -104, -104, -96, -96,
> + -96, -96, -96, -88, -88, -88, -88, -88,
> + -88, -88, -88, -88, -88, -88, -88, -80,
> + -80, -80, -80, -80, -80, -72, -72, -72,
> + -72, -72, -72, -72, -72, -64, -64, -64,
> + -64, -64, -64, -64, -64, -56, -56, -56,
> + -56, -56, -56, -56, -56, -56, -48, -48,
> + -48, -48, -48, -48, -48, -48, -48, -48,
> + -48, -32, -32, -32, -32, -32, -32, -32,
> + -32, -32, -32, -32, -32, -32, -32, -32,
> + -32, -32, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> +},
> +{ /* bi=5, bo=4 r=2.0:PSNR=64.441 */
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 48, 48, 48, 48, 48, 48, 48, 48,
> + 48, 48, 48, 48, 48, 48, 48, 48,
> + 48, 48, 48, 48, 48, 48, 48, 48,
> + 64, 64, 64, 64, 64, 64, 64, 64,
> + 64, 64, 64, 64, 64, 64, 64, 64,
> + 80, 80, 80, 80, 80, 80, 80, 80,
> + 80, 80, 80, 80, 80, 88, 88, 88,
> + 88, 88, 88, 88, 88, 88, 88, 88,
> + 104, 104, 104, 104, 104, 104, 104, 104,
> + 104, 104, 104, 112, 112, 112, 112, 112,
> + 112, 112, 112, 112, 120, 120, 120, 120,
> + 120, 120, 120, 120, 120, 120, 120, 120,
> + 0, -120, -120, -120, -120, -120, -120, -120,
> + -120, -120, -120, -120, -120, -112, -112, -112,
> + -112, -112, -112, -112, -112, -112, -104, -104,
> + -104, -104, -104, -104, -104, -104, -104, -104,
> + -104, -88, -88, -88, -88, -88, -88, -88,
> + -88, -88, -88, -88, -80, -80, -80, -80,
> + -80, -80, -80, -80, -80, -80, -80, -80,
> + -80, -64, -64, -64, -64, -64, -64, -64,
> + -64, -64, -64, -64, -64, -64, -64, -64,
> + -64, -48, -48, -48, -48, -48, -48, -48,
> + -48, -48, -48, -48, -48, -48, -48, -48,
> + -48, -48, -48, -48, -48, -48, -48, -48,
> + -48, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> +},
> +{ /* bi=5, bo=2 r=2.0:PSNR=43.175 */
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 88, 88, 88, 88, 88, 88, 88, 88,
> + 88, 88, 88, 88, 88, 88, 88, 88,
> + 88, 88, 88, 88, 88, 88, 88, 88,
> + 88, 88, 88, 88, 88, 88, 88, 88,
> + 88, 88, 88, 88, 88, 88, 88, 88,
> + 88, 88, 88, 88, 88, 88, 88, 88,
> + 88, 88, 88, 88, 88, 88, 88, 88,
> + 88, 88, 88, 88, 88, 88, 88, 88,
> + 0, -88, -88, -88, -88, -88, -88, -88,
> + -88, -88, -88, -88, -88, -88, -88, -88,
> + -88, -88, -88, -88, -88, -88, -88, -88,
> + -88, -88, -88, -88, -88, -88, -88, -88,
> + -88, -88, -88, -88, -88, -88, -88, -88,
> + -88, -88, -88, -88, -88, -88, -88, -88,
> + -88, -88, -88, -88, -88, -88, -88, -88,
> + -88, -88, -88, -88, -88, -88, -88, -88,
> + -88, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0,
> +}
> +};
> +
> +static const signed char *zywrle_param[3][3][3]={
> + {{zywrle_conv[0], zywrle_conv[2], zywrle_conv[0]},
> + {zywrle_conv[0], zywrle_conv[0], zywrle_conv[0]},
> + {zywrle_conv[0], zywrle_conv[0], zywrle_conv[0]}},
> + {{zywrle_conv[0], zywrle_conv[3], zywrle_conv[0]},
> + {zywrle_conv[1], zywrle_conv[1], zywrle_conv[1]},
> + {zywrle_conv[0], zywrle_conv[0], zywrle_conv[0]}},
> + {{zywrle_conv[0], zywrle_conv[3], zywrle_conv[0]},
> + {zywrle_conv[2], zywrle_conv[2], zywrle_conv[2]},
> + {zywrle_conv[1], zywrle_conv[1], zywrle_conv[1]}},
> +};
> +#endif
> +
> +/* Load/Save pixel stuffs. */
> +#define ZYWRLE_YMASK15 0xFFFFFFF8
> +#define ZYWRLE_UVMASK15 0xFFFFFFF8
> +#define ZYWRLE_LOAD_PIXEL15(src, r, g, b) \
> + do { \
> + r = (((uint8_t*)src)[S_1]<< 1)& 0xF8; \
> + g = (((uint8_t*)src)[S_1]<< 6) | (((uint8_t*)src)[S_0]>> 2); \
> + g &= 0xF8; \
> + b = (((uint8_t*)src)[S_0]<< 3)& 0xF8; \
> + } while (0)
> +
> +#define ZYWRLE_SAVE_PIXEL15(dst, r, g, b) \
> + do { \
> + r &= 0xF8; \
> + g &= 0xF8; \
> + b &= 0xF8; \
> + ((uint8_t*)dst)[S_1] = (uint8_t)((r >> 1)|(g >> 6)); \
> + ((uint8_t*)dst)[S_0] = (uint8_t)(((b >> 3)|(g << 2))& 0xFF); \
> + } while (0)
> +
> +#define ZYWRLE_YMASK16 0xFFFFFFFC
> +#define ZYWRLE_UVMASK16 0xFFFFFFF8
> +#define ZYWRLE_LOAD_PIXEL16(src, r, g, b) \
> + do { \
> + r = ((uint8_t*)src)[S_1] & 0xF8; \
> + g = (((uint8_t*)src)[S_1]<< 5) | (((uint8_t*)src)[S_0] >> 3); \
> + g &= 0xFC; \
> + b = (((uint8_t*)src)[S_0]<< 3) & 0xF8; \
> + } while (0)
> +
> +#define ZYWRLE_SAVE_PIXEL16(dst, r, g,b) \
> + do { \
> + r &= 0xF8; \
> + g &= 0xFC; \
> + b &= 0xF8; \
> + ((uint8_t*)dst)[S_1] = (uint8_t)(r | (g >> 5)); \
> + ((uint8_t*)dst)[S_0] = (uint8_t)(((b >> 3)|(g << 3)) & 0xFF); \
> + } while (0)
> +
> +#define ZYWRLE_YMASK32 0xFFFFFFFF
> +#define ZYWRLE_UVMASK32 0xFFFFFFFF
> +#define ZYWRLE_LOAD_PIXEL32(src, r, g, b) \
> + do { \
> + r = ((uint8_t*)src)[L_2]; \
> + g = ((uint8_t*)src)[L_1]; \
> + b = ((uint8_t*)src)[L_0]; \
> + } while (0)
> +#define ZYWRLE_SAVE_PIXEL32(dst, r, g, b) \
> + do { \
> + ((uint8_t*)dst)[L_2] = (uint8_t)r; \
> + ((uint8_t*)dst)[L_1] = (uint8_t)g; \
> + ((uint8_t*)dst)[L_0] = (uint8_t)b; \
> + } while (0)
> +
> +static inline void harr(int8_t *px0, int8_t *px1)
> +{
> + /* Piecewise-Linear Harr(PLHarr) */
> + int x0 = (int)*px0, x1 = (int)*px1;
> + int orgx0 = x0, orgx1 = x1;
> +
> + if ((x0 ^ x1) & 0x80) {
> + /* differ sign */
> + x1 += x0;
> + if (((x1 ^ orgx1) & 0x80) == 0) {
> + /* |x1| > |x0| */
> + x0 -= x1; /* H = -B */
> + }
> + } else {
> + /* same sign */
> + x0 -= x1;
> + if (((x0 ^ orgx0) & 0x80) == 0) {
> + /* |x0| > |x1| */
> + x1 += x0; /* L = A */
> + }
> + }
> + *px0 = (int8_t)x1;
> + *px1 = (int8_t)x0;
> +}
> +
> +/*
> + 1D-Wavelet transform.
> +
> + In coefficients array, the famous 'pyramid' decomposition is well used.
> +
> + 1D Model:
> + |L0L0L0L0|L0L0L0L0|H0H0H0H0|H0H0H0H0| : level 0
> + |L1L1L1L1|H1H1H1H1|H0H0H0H0|H0H0H0H0| : level 1
> +
> + But this method needs line buffer because H/L is different position from
> X0/X1.
> + So, I used 'interleave' decomposition instead of it.
> +
> + 1D Model:
> + |L0H0L0H0|L0H0L0H0|L0H0L0H0|L0H0L0H0| : level 0
> + |L1H0H1H0|L1H0H1H0|L1H0H1H0|L1H0H1H0| : level 1
> +
> + In this method, H/L and X0/X1 is always same position.
> + This lead us to more speed and less memory.
> + Of cause, the result of both method is quite same
> + because it's only difference that coefficient position.
> +*/
> +static inline void wavelet_level(int *data, int size, int l, int skip_pixel)
> +{
> + int s, ofs;
> + int8_t *px0;
> + int8_t *end;
> +
> + px0 = (int8_t*)data;
> + s = (8 << l) * skip_pixel;
> + end = px0 + (size >> (l + 1)) * s;
> + s -= 2;
> + ofs = (4 << l) * skip_pixel;
> +
> + while (px0 < end) {
> + harr(px0, px0 + ofs);
> + px0++;
> + harr(px0, px0 + ofs);
> + px0++;
> + harr(px0, px0 + ofs);
> + px0 += s;
> + }
> +}
> +
> +#ifndef ZYWRLE_QUANTIZE
> +/* Type A:lower bit omitting of EZW style. */
> +static inline void filter_wavelet_square(int *buf, int width, int height,
> + int level, int l)
> +{
> + int r, s;
> + int x, y;
> + int *h;
> + const unsigned int *m;
> +
> + m = &(zywrle_param[level - 1][l]);
> + s = 2 << l;
> +
> + for (r = 1; r < 4; r++) {
> + h = buf;
> + if (r & 0x01)
> + h += s >> 1;
Missing braces, also below.
- [Qemu-devel] [PATCH v2 01/15] vnc: don't set the quality if lossy encoding are disabled, (continued)
- [Qemu-devel] [PATCH v2 01/15] vnc: don't set the quality if lossy encoding are disabled, Corentin Chary, 2010/11/11
- [Qemu-devel] [PATCH v2 03/15] vnc: refresh lossy rect after a given timeout, Corentin Chary, 2010/11/11
- [Qemu-devel] [PATCH v2 04/15] vnc: tight: use the update frequency to choose between lossy and lossless, Corentin Chary, 2010/11/11
- [Qemu-devel] [PATCH v2 05/15] vnc: palette: use a pool to reduce memory allocations, Corentin Chary, 2010/11/11
- [Qemu-devel] [PATCH v2 06/15] vnc: palette: add palette_init calls, Corentin Chary, 2010/11/11
- [Qemu-devel] [PATCH v2 07/15] vnc: palette: and fill and color calls., Corentin Chary, 2010/11/11
- [Qemu-devel] [PATCH v2 02/15] vnc: add a way to get the update frequency for a given region, Corentin Chary, 2010/11/11
- [Qemu-devel] [PATCH v2 10/15] vnc: fix lossy rect refreshing, Corentin Chary, 2010/11/11
- [Qemu-devel] [PATCH v2 08/15] vnc: Add ZRLE and ZYWRLE encodings., Corentin Chary, 2010/11/11
- Re: [Qemu-devel] [PATCH v2 08/15] vnc: Add ZRLE and ZYWRLE encodings.,
Blue Swirl <=
- [Qemu-devel] [PATCH v2 12/15] vnc: use the new generic bitmap functions, Corentin Chary, 2010/11/11
- [Qemu-devel] [PATCH v2 11/15] bitmap: add a generic bitmap and bitops library, Corentin Chary, 2010/11/11
- [Qemu-devel] [PATCH v2 09/15] vnc: fix uint8_t comparisons with negative values, Corentin Chary, 2010/11/11
- [Qemu-devel] [PATCH v2 13/15] vnc: don't try to send bigger updates that client height, Corentin Chary, 2010/11/11
- [Qemu-devel] [PATCH v2 14/15] vnc: tight: tweak adaptive tight settings, Corentin Chary, 2010/11/11
- [Qemu-devel] [PATCH v2 15/15] vnc: add a non-adaptive option, Corentin Chary, 2010/11/11
- [Qemu-devel] Re: [PATCH v2 00/15] vnc: adapative tight, zrle, zywrle, and bitmap module, Alexander Graf, 2010/11/11