/*
 * 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
