/*
 * 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 <corentin.chary@gmail.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

/*
 * 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 "qemu/osdep.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
