/* GStreamer
 * Copyright (C) 2007 Michael Smith <msmith@xiph.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * This is a decoder for the VMWare VMnc video codec, which VMWare uses for 
 * recording * of virtual machine instances.
 * It's essentially a serialisation of RFB (the VNC protocol) 
 * 'FramebufferUpdate' messages, with some special encoding-types for VMnc
 * extensions. There's some documentation (with fixes from VMWare employees) at:
 *   http://wiki.multimedia.cx/index.php?title=VMware_Video
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <gst/gst.h>
#include <gst/base/gstadapter.h>
#include <gst/video/video.h>
#include <string.h>

#define GST_CAT_DEFAULT vmnc_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

#define GST_TYPE_VMNC_DEC \
  (gst_vmnc_dec_get_type())
#define GST_VMNC_DEC(obj) \
  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VMNC_DEC,GstVMncDec))

#define RFB_GET_UINT32(ptr) GST_READ_UINT32_BE(ptr)
#define RFB_GET_UINT16(ptr) GST_READ_UINT16_BE(ptr)
#define RFB_GET_UINT8(ptr) GST_READ_UINT8(ptr)

enum
{
  ARG_0,
};

enum
{
  ERROR_INVALID = -1,           /* Invalid data in bitstream */
  ERROR_INSUFFICIENT_DATA = -2  /* Haven't received enough data yet */
};

#define MAKE_TYPE(a,b,c,d) ((a<<24)|(b<<16)|(c<<8)|d)
enum
{
  TYPE_RAW = 0,
  TYPE_COPY = 1,
  TYPE_RRE = 2,
  TYPE_CoRRE = 4,
  TYPE_HEXTILE = 5,

  TYPE_WMVd = MAKE_TYPE ('W', 'M', 'V', 'd'),
  TYPE_WMVe = MAKE_TYPE ('W', 'M', 'V', 'e'),
  TYPE_WMVf = MAKE_TYPE ('W', 'M', 'V', 'f'),
  TYPE_WMVg = MAKE_TYPE ('W', 'M', 'V', 'g'),
  TYPE_WMVh = MAKE_TYPE ('W', 'M', 'V', 'h'),
  TYPE_WMVi = MAKE_TYPE ('W', 'M', 'V', 'i'),
  TYPE_WMVj = MAKE_TYPE ('W', 'M', 'V', 'j')
};

struct RFBFormat
{
  int width;
  int height;
  int stride;
  int bytes_per_pixel;
  int depth;
  int big_endian;

  guint8 descriptor[16];        /* The raw format descriptor block */
};

enum CursorType
{
  CURSOR_COLOUR = 0,
  CURSOR_ALPHA = 1
};

struct Cursor
{
  enum CursorType type;
  int visible;
  int x;
  int y;
  int width;
  int height;
  int hot_x;
  int hot_y;
  guint8 *cursordata;
  guint8 *cursormask;
};

typedef struct
{
  GstElement element;

  GstPad *sinkpad;
  GstPad *srcpad;

  GstCaps *caps;
  gboolean have_format;

  int parsed;
  GstAdapter *adapter;

  int framerate_num;
  int framerate_denom;

  struct Cursor cursor;
  struct RFBFormat format;
  guint8 *imagedata;
} GstVMncDec;

typedef struct
{
  GstElementClass parent_class;
} GstVMncDecClass;

static GstStaticPadTemplate vmnc_dec_src_factory =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-raw-rgb"));

static GstStaticPadTemplate vmnc_dec_sink_factory =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-vmnc, version=(int)1, "
        "framerate=(fraction)[0, max], "
        "width=(int)[0, max], " "height=(int)[0, max]")
    );

GST_BOILERPLATE (GstVMncDec, gst_vmnc_dec, GstElement, GST_TYPE_ELEMENT);

static void vmnc_dec_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void vmnc_dec_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);

static GstFlowReturn vmnc_dec_chain (GstPad * pad, GstBuffer * buffer);
static gboolean vmnc_dec_setcaps (GstPad * pad, GstCaps * caps);
static GstStateChangeReturn vmnc_dec_change_state (GstElement * element,
    GstStateChange transition);
static void vmnc_dec_finalize (GObject * object);

static void
gst_vmnc_dec_base_init (gpointer g_class)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&vmnc_dec_src_factory));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&vmnc_dec_sink_factory));
  gst_element_class_set_details_simple (element_class, "VMnc video decoder",
      "Codec/Decoder/Video",
      "Decode VmWare video to raw (RGB) video",
      "Michael Smith <msmith@xiph.org>");
}

static void
gst_vmnc_dec_class_init (GstVMncDecClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);

  gobject_class->set_property = vmnc_dec_set_property;
  gobject_class->get_property = vmnc_dec_get_property;

  gobject_class->finalize = vmnc_dec_finalize;

  gstelement_class->change_state = vmnc_dec_change_state;

  GST_DEBUG_CATEGORY_INIT (vmnc_debug, "vmncdec", 0, "VMnc decoder");
}

static void
gst_vmnc_dec_init (GstVMncDec * dec, GstVMncDecClass * g_class)
{
  dec->sinkpad =
      gst_pad_new_from_static_template (&vmnc_dec_sink_factory, "sink");
  gst_pad_set_chain_function (dec->sinkpad, vmnc_dec_chain);
  gst_pad_set_setcaps_function (dec->sinkpad, vmnc_dec_setcaps);
  gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);

  dec->srcpad = gst_pad_new_from_static_template (&vmnc_dec_src_factory, "src");
  gst_pad_use_fixed_caps (dec->srcpad);

  gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);

  dec->adapter = gst_adapter_new ();
}

static void
vmnc_dec_finalize (GObject * object)
{
  GstVMncDec *dec = GST_VMNC_DEC (object);

  g_object_unref (dec->adapter);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
gst_vmnc_dec_reset (GstVMncDec * dec)
{
  if (dec->caps) {
    gst_caps_unref (dec->caps);
    dec->caps = NULL;
  }
  if (dec->imagedata) {
    g_free (dec->imagedata);
    dec->imagedata = NULL;
  }

  if (dec->cursor.cursordata) {
    g_free (dec->cursor.cursordata);
    dec->cursor.cursordata = NULL;
  }
  if (dec->cursor.cursormask) {
    g_free (dec->cursor.cursormask);
    dec->cursor.cursormask = NULL;
  }
  dec->cursor.visible = 0;

  /* Use these as defaults if the container doesn't provide anything */
  dec->framerate_num = 5;
  dec->framerate_denom = 1;

  dec->have_format = FALSE;

  gst_adapter_clear (dec->adapter);
}

struct RfbRectangle
{
  guint16 x;
  guint16 y;
  guint16 width;
  guint16 height;

  gint32 type;
};

/* Rectangle handling functions.
 * Return number of bytes consumed, or < 0 on error
 */
typedef int (*rectangle_handler) (GstVMncDec * dec, struct RfbRectangle * rect,
    const guint8 * data, int len, gboolean decode);

static int
vmnc_handle_wmvi_rectangle (GstVMncDec * dec, struct RfbRectangle *rect,
    const guint8 * data, int len, gboolean decode)
{
  GstCaps *caps;
  gint bpp, tc;
  guint32 redmask, greenmask, bluemask;
  guint32 endianness, dataendianness;

  /* A WMVi rectangle has a 16byte payload */
  if (len < 16) {
    GST_DEBUG_OBJECT (dec, "Bad WMVi rect: too short");
    return ERROR_INSUFFICIENT_DATA;
  }

  /* We only compare 13 bytes; ignoring the 3 padding bytes at the end */
  if (dec->caps && memcmp (data, dec->format.descriptor, 13) == 0) {
    /* Nothing changed, so just exit */
    return 16;
  }

  /* Store the whole block for simple comparison later */
  memcpy (dec->format.descriptor, data, 16);

  if (rect->x != 0 || rect->y != 0) {
    GST_WARNING_OBJECT (dec, "Bad WMVi rect: wrong coordinates");
    return ERROR_INVALID;
  }

  bpp = data[0];
  dec->format.depth = data[1];
  dec->format.big_endian = data[2];
  dataendianness = data[2] ? G_BIG_ENDIAN : G_LITTLE_ENDIAN;
  tc = data[3];

  if (bpp != 8 && bpp != 16 && bpp != 32) {
    GST_WARNING_OBJECT (dec, "Bad bpp value: %d", bpp);
    return ERROR_INVALID;
  }

  if (!tc) {
    GST_WARNING_OBJECT (dec, "Paletted video not supported");
    return ERROR_INVALID;
  }

  dec->format.bytes_per_pixel = bpp / 8;
  dec->format.width = rect->width;
  dec->format.height = rect->height;

  redmask = (guint32) (RFB_GET_UINT16 (data + 4)) << data[10];
  greenmask = (guint32) (RFB_GET_UINT16 (data + 6)) << data[11];
  bluemask = (guint32) (RFB_GET_UINT16 (data + 8)) << data[12];

  GST_DEBUG_OBJECT (dec, "Red: mask %d, shift %d",
      RFB_GET_UINT16 (data + 4), data[10]);
  GST_DEBUG_OBJECT (dec, "Green: mask %d, shift %d",
      RFB_GET_UINT16 (data + 6), data[11]);
  GST_DEBUG_OBJECT (dec, "Blue: mask %d, shift %d",
      RFB_GET_UINT16 (data + 8), data[12]);
  GST_DEBUG_OBJECT (dec, "BPP: %d. endianness: %s", bpp,
      data[2] ? "big" : "little");

  /* GStreamer's RGB caps are a bit weird. */
  if (bpp == 8) {
    endianness = G_BYTE_ORDER;  /* Doesn't matter */
  } else if (bpp == 16) {
    /* We require host-endian. */
    endianness = G_BYTE_ORDER;
  } else {                      /* bpp == 32 */
    /* We require big endian */
    endianness = G_BIG_ENDIAN;
    if (endianness != dataendianness) {
      redmask = GUINT32_SWAP_LE_BE (redmask);
      greenmask = GUINT32_SWAP_LE_BE (greenmask);
      bluemask = GUINT32_SWAP_LE_BE (bluemask);
    }
  }

  dec->have_format = TRUE;
  if (!decode) {
    GST_DEBUG_OBJECT (dec, "Parsing, not setting caps");
    return 16;
  }

  caps = gst_caps_new_simple ("video/x-raw-rgb",
      "framerate", GST_TYPE_FRACTION, dec->framerate_num, dec->framerate_denom,
      "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
      "width", G_TYPE_INT, rect->width, "height", G_TYPE_INT, rect->height,
      "bpp", G_TYPE_INT, bpp,
      "depth", G_TYPE_INT, dec->format.depth,
      "endianness", G_TYPE_INT, endianness,
      "red_mask", G_TYPE_INT, redmask,
      "green_mask", G_TYPE_INT, greenmask,
      "blue_mask", G_TYPE_INT, bluemask, NULL);
  gst_pad_set_caps (dec->srcpad, caps);

  if (dec->caps)
    gst_caps_unref (dec->caps);
  dec->caps = caps;

  if (dec->imagedata)
    g_free (dec->imagedata);
  dec->imagedata = g_malloc (dec->format.width * dec->format.height *
      dec->format.bytes_per_pixel);
  GST_DEBUG_OBJECT (dec, "Allocated image data at %p", dec->imagedata);

  dec->format.stride = dec->format.width * dec->format.bytes_per_pixel;

  return 16;
}

static void
render_colour_cursor (GstVMncDec * dec, guint8 * data, int x, int y,
    int off_x, int off_y, int width, int height)
{
  int i, j;
  guint8 *dstraw = data + dec->format.stride * y +
      dec->format.bytes_per_pixel * x;
  guint8 *srcraw = dec->cursor.cursordata +
      dec->cursor.width * dec->format.bytes_per_pixel * off_y;
  guint8 *maskraw = dec->cursor.cursormask +
      dec->cursor.width * dec->format.bytes_per_pixel * off_y;

  /* Boundchecking done by caller; this is just the renderer inner loop */
  if (dec->format.bytes_per_pixel == 1) {
    guint8 *dst = dstraw;
    guint8 *src = srcraw;
    guint8 *mask = maskraw;

    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        dst[j] = (dst[j] & src[j]) ^ mask[j];
      }
      dst += dec->format.width;
      src += dec->cursor.width;
      mask += dec->cursor.width;
    }
  } else if (dec->format.bytes_per_pixel == 2) {
    guint16 *dst = (guint16 *) dstraw;
    guint16 *src = (guint16 *) srcraw;
    guint16 *mask = (guint16 *) maskraw;

    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        dst[j] = (dst[j] & src[j]) ^ mask[j];
      }
      dst += dec->format.width;
      src += dec->cursor.width;
      mask += dec->cursor.width;
    }
  } else {
    guint32 *dst = (guint32 *) dstraw;
    guint32 *src = (guint32 *) srcraw;
    guint32 *mask = (guint32 *) maskraw;

    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        dst[j] = (dst[j] & src[j]) ^ mask[j];
      }
      dst += dec->format.width;
      src += dec->cursor.width;
      mask += dec->cursor.width;
    }
  }
}

static void
render_cursor (GstVMncDec * dec, guint8 * data)
{
  /* First, figure out the portion of the cursor that's on-screen */
  /* X,Y of top-left of cursor */
  int x = dec->cursor.x - dec->cursor.hot_x;
  int y = dec->cursor.y - dec->cursor.hot_y;

  /* Width, height of rendered portion of cursor */
  int width = dec->cursor.width;
  int height = dec->cursor.height;

  /* X,Y offset of rendered portion of cursor */
  int off_x = 0;
  int off_y = 0;

  if (x < 0) {
    off_x = -x;
    width += x;
    x = 0;
  }
  if (x + width > dec->format.width)
    width = dec->format.width - x;
  if (y < 0) {
    off_y = -y;
    height += y;
    y = 0;
  }
  if (y + height > dec->format.height)
    height = dec->format.height - y;

  if (dec->cursor.type == CURSOR_COLOUR) {
    render_colour_cursor (dec, data, x, y, off_x, off_y, width, height);
  } else {
    /* Alpha cursor. */
    /* TODO: Implement me! */
    GST_WARNING_OBJECT (dec, "Alpha composited cursors not yet implemented");
  }
}

static GstBuffer *
vmnc_make_buffer (GstVMncDec * dec, GstBuffer * inbuf)
{
  int size = dec->format.stride * dec->format.height;
  GstBuffer *buf = gst_buffer_new_and_alloc (size);
  guint8 *data = GST_BUFFER_DATA (buf);

  memcpy (data, dec->imagedata, size);

  if (dec->cursor.visible) {
    render_cursor (dec, data);
  }

  if (inbuf) {
    gst_buffer_copy_metadata (buf, inbuf, GST_BUFFER_COPY_TIMESTAMPS);
  }

  gst_buffer_set_caps (buf, dec->caps);

  return buf;
}

static int
vmnc_handle_wmvd_rectangle (GstVMncDec * dec, struct RfbRectangle *rect,
    const guint8 * data, int len, gboolean decode)
{
  /* Cursor data. */
  int datalen = 2;
  int type, size;

  if (len < datalen) {
    GST_DEBUG_OBJECT (dec, "Cursor data too short");
    return ERROR_INSUFFICIENT_DATA;
  }

  type = RFB_GET_UINT8 (data);

  if (type == CURSOR_COLOUR) {
    datalen += rect->width * rect->height * dec->format.bytes_per_pixel * 2;
  } else if (type == CURSOR_ALPHA) {
    datalen += rect->width * rect->height * 4;
  } else {
    GST_WARNING_OBJECT (dec, "Unknown cursor type: %d", type);
    return ERROR_INVALID;
  }

  if (len < datalen) {
    GST_DEBUG_OBJECT (dec, "Cursor data too short");
    return ERROR_INSUFFICIENT_DATA;
  } else if (!decode)
    return datalen;

  dec->cursor.type = type;
  dec->cursor.width = rect->width;
  dec->cursor.height = rect->height;
  dec->cursor.type = type;
  dec->cursor.hot_x = rect->x;
  dec->cursor.hot_y = rect->y;

  if (dec->cursor.cursordata)
    g_free (dec->cursor.cursordata);
  if (dec->cursor.cursormask)
    g_free (dec->cursor.cursormask);

  if (type == 0) {
    size = rect->width * rect->height * dec->format.bytes_per_pixel;
    dec->cursor.cursordata = g_malloc (size);
    dec->cursor.cursormask = g_malloc (size);
    memcpy (dec->cursor.cursordata, data + 2, size);
    memcpy (dec->cursor.cursormask, data + 2 + size, size);
  } else {
    dec->cursor.cursordata = g_malloc (rect->width * rect->height * 4);
    memcpy (dec->cursor.cursordata, data + 2, rect->width * rect->height * 4);
  }

  return datalen;
}

static int
vmnc_handle_wmve_rectangle (GstVMncDec * dec, struct RfbRectangle *rect,
    const guint8 * data, int len, gboolean decode)
{
  guint16 flags;

  /* Cursor state. */
  if (len < 2) {
    GST_DEBUG_OBJECT (dec, "Cursor data too short");
    return ERROR_INSUFFICIENT_DATA;
  } else if (!decode)
    return 2;

  flags = RFB_GET_UINT16 (data);
  dec->cursor.visible = flags & 0x01;

  return 2;
}

static int
vmnc_handle_wmvf_rectangle (GstVMncDec * dec, struct RfbRectangle *rect,
    const guint8 * data, int len, gboolean decode)
{
  /* Cursor position. */
  dec->cursor.x = rect->x;
  dec->cursor.y = rect->y;
  return 0;
}

static int
vmnc_handle_wmvg_rectangle (GstVMncDec * dec, struct RfbRectangle *rect,
    const guint8 * data, int len, gboolean decode)
{
  /* Keyboard stuff; not interesting for playback */
  if (len < 10) {
    GST_DEBUG_OBJECT (dec, "Keyboard data too short");
    return ERROR_INSUFFICIENT_DATA;
  }
  return 10;
}

static int
vmnc_handle_wmvh_rectangle (GstVMncDec * dec, struct RfbRectangle *rect,
    const guint8 * data, int len, gboolean decode)
{
  /* More keyboard stuff; not interesting for playback */
  if (len < 4) {
    GST_DEBUG_OBJECT (dec, "Keyboard data too short");
    return ERROR_INSUFFICIENT_DATA;
  }
  return 4;
}

static int
vmnc_handle_wmvj_rectangle (GstVMncDec * dec, struct RfbRectangle *rect,
    const guint8 * data, int len, gboolean decode)
{
  /* VM state info, not interesting for playback */
  if (len < 2) {
    GST_DEBUG_OBJECT (dec, "VM state data too short");
    return ERROR_INSUFFICIENT_DATA;
  }
  return 2;
}

static void
render_raw_tile (GstVMncDec * dec, const guint8 * data, int x, int y,
    int width, int height)
{
  int i;
  guint8 *dst;
  const guint8 *src;
  int line;

  src = data;
  dst = dec->imagedata + dec->format.stride * y +
      dec->format.bytes_per_pixel * x;
  line = width * dec->format.bytes_per_pixel;

  for (i = 0; i < height; i++) {
    /* This is wrong-endian currently */
    memcpy (dst, src, line);

    dst += dec->format.stride;
    src += line;
  }
}

static void
render_subrect (GstVMncDec * dec, int x, int y, int width,
    int height, guint32 colour)
{
  /* Crazy inefficient! */
  int i, j;
  guint8 *dst;

  for (i = 0; i < height; i++) {
    dst = dec->imagedata + dec->format.stride * (y + i) +
        dec->format.bytes_per_pixel * x;
    for (j = 0; j < width; j++) {
      memcpy (dst, &colour, dec->format.bytes_per_pixel);
      dst += dec->format.bytes_per_pixel;
    }
  }
}

static int
vmnc_handle_raw_rectangle (GstVMncDec * dec, struct RfbRectangle *rect,
    const guint8 * data, int len, gboolean decode)
{
  int datalen = rect->width * rect->height * dec->format.bytes_per_pixel;

  if (len < datalen) {
    GST_DEBUG_OBJECT (dec, "Raw data too short");
    return ERROR_INSUFFICIENT_DATA;
  }

  if (decode)
    render_raw_tile (dec, data, rect->x, rect->y, rect->width, rect->height);

  return datalen;
}

static int
vmnc_handle_copy_rectangle (GstVMncDec * dec, struct RfbRectangle *rect,
    const guint8 * data, int len, gboolean decode)
{
  int src_x, src_y;
  guint8 *src, *dst;
  int i;

  if (len < 4) {
    GST_DEBUG_OBJECT (dec, "Copy data too short");
    return ERROR_INSUFFICIENT_DATA;
  } else if (!decode)
    return 4;

  src_x = RFB_GET_UINT16 (data);
  src_y = RFB_GET_UINT16 (data + 2);

  /* Our destination rectangle is guaranteed in-frame; check this for the source
   * rectangle. */
  if (src_x + rect->width > dec->format.width ||
      src_y + rect->height > dec->format.height) {
    GST_WARNING_OBJECT (dec, "Source rectangle out of range");
    return ERROR_INVALID;
  }

  if (src_y > rect->y || src_x > rect->x) {
    /* Moving forward */
    src = dec->imagedata + dec->format.stride * src_y +
        dec->format.bytes_per_pixel * src_x;
    dst = dec->imagedata + dec->format.stride * rect->y +
        dec->format.bytes_per_pixel * rect->x;
    for (i = 0; i < rect->height; i++) {
      memmove (dst, src, rect->width * dec->format.bytes_per_pixel);
      dst += dec->format.stride;
      src += dec->format.stride;
    }
  } else {
    /* Backwards */
    src = dec->imagedata + dec->format.stride * (src_y + rect->height - 1) +
        dec->format.bytes_per_pixel * src_x;
    dst = dec->imagedata + dec->format.stride * (rect->y + rect->height - 1) +
        dec->format.bytes_per_pixel * rect->x;
    for (i = rect->height; i > 0; i--) {
      memmove (dst, src, rect->width * dec->format.bytes_per_pixel);
      dst -= dec->format.stride;
      src -= dec->format.stride;
    }
  }

  return 4;
}

/* FIXME: data+off might not be properly aligned */
#define READ_PIXEL(pixel, data, off, len)         \
  if (dec->format.bytes_per_pixel == 1) {         \
     if (off >= len)                              \
       return ERROR_INSUFFICIENT_DATA;            \
     pixel = data[off++];                         \
  } else if (dec->format.bytes_per_pixel == 2) {  \
     if (off+2 > len)                             \
       return ERROR_INSUFFICIENT_DATA;            \
     pixel = (*(guint16 *)(data + off));          \
     off += 2;                                    \
  } else {                                        \
     if (off+4 > len)                             \
       return ERROR_INSUFFICIENT_DATA;            \
     pixel = (*(guint32 *)(data + off));          \
     off += 4;                                    \
  }

static int
vmnc_handle_hextile_rectangle (GstVMncDec * dec, struct RfbRectangle *rect,
    const guint8 * data, int len, gboolean decode)
{
  int tilesx = GST_ROUND_UP_16 (rect->width) / 16;
  int tilesy = GST_ROUND_UP_16 (rect->height) / 16;
  int x, y, z;
  int off = 0;
  int subrects;
  int coloured;
  int width, height;
  guint32 fg = 0, bg = 0, colour;
  guint8 flags;

  for (y = 0; y < tilesy; y++) {
    if (y == tilesy - 1)
      height = rect->height - (tilesy - 1) * 16;
    else
      height = 16;

    for (x = 0; x < tilesx; x++) {
      if (x == tilesx - 1)
        width = rect->width - (tilesx - 1) * 16;
      else
        width = 16;

      if (off >= len) {
        return ERROR_INSUFFICIENT_DATA;
      }
      flags = data[off++];

      if (flags & 0x1) {
        if (off + width * height * dec->format.bytes_per_pixel > len) {
          return ERROR_INSUFFICIENT_DATA;
        }
        if (decode)
          render_raw_tile (dec, data + off, rect->x + x * 16, rect->y + y * 16,
              width, height);
        off += width * height * dec->format.bytes_per_pixel;
      } else {
        if (flags & 0x2) {
          READ_PIXEL (bg, data, off, len)
        }
        if (flags & 0x4) {
          READ_PIXEL (fg, data, off, len)
        }

        subrects = 0;
        if (flags & 0x8) {
          if (off >= len) {
            return ERROR_INSUFFICIENT_DATA;
          }
          subrects = data[off++];
        }

        /* Paint background colour on entire tile */
        if (decode)
          render_subrect (dec, rect->x + x * 16, rect->y + y * 16,
              width, height, bg);

        coloured = flags & 0x10;
        for (z = 0; z < subrects; z++) {
          if (coloured) {
            READ_PIXEL (colour, data, off, len);
          } else
            colour = fg;
          if (off + 2 > len)
            return ERROR_INSUFFICIENT_DATA;

          {
            int off_x = (data[off] & 0xf0) >> 4;
            int off_y = (data[off] & 0x0f);
            int w = ((data[off + 1] & 0xf0) >> 4) + 1;
            int h = (data[off + 1] & 0x0f) + 1;

            off += 2;

            /* Ensure we don't have out of bounds coordinates */
            if (off_x + w > width || off_y + h > height) {
              GST_WARNING_OBJECT (dec, "Subrect out of bounds: %d-%d x %d-%d "
                  "extends outside %dx%d", off_x, w, off_y, h, width, height);
              return ERROR_INVALID;
            }

            if (decode)
              render_subrect (dec, rect->x + x * 16 + off_x,
                  rect->y + y * 16 + off_y, w, h, colour);
          }
        }
      }
    }
  }

  return off;
}

/* Handle a packet in one of two modes: decode or parse.
 * In parse mode, we don't execute any of the decoding, we just do enough to
 * figure out how many bytes it contains
 *
 * Returns: >= 0, the number of bytes consumed
 *           < 0, packet too short to decode, or error
 */
static int
vmnc_handle_packet (GstVMncDec * dec, const guint8 * data, int len,
    gboolean decode)
{
  int type;
  int offset = 0;

  if (len < 4) {
    GST_DEBUG_OBJECT (dec, "Packet too short");
    return ERROR_INSUFFICIENT_DATA;
  }

  type = data[0];

  switch (type) {
    case 0:
    {
      int numrect = RFB_GET_UINT16 (data + 2);
      int i;
      int read;

      offset = 4;

      for (i = 0; i < numrect; i++) {
        struct RfbRectangle r;
        rectangle_handler handler;

        if (len < offset + 12) {
          GST_DEBUG_OBJECT (dec,
              "Packet too short for rectangle header: %d < %d",
              len, offset + 12);
          return ERROR_INSUFFICIENT_DATA;
        }
        GST_DEBUG_OBJECT (dec, "Reading rectangle %d", i);
        r.x = RFB_GET_UINT16 (data + offset);
        r.y = RFB_GET_UINT16 (data + offset + 2);
        r.width = RFB_GET_UINT16 (data + offset + 4);
        r.height = RFB_GET_UINT16 (data + offset + 6);
        r.type = RFB_GET_UINT32 (data + offset + 8);

        if (r.type != TYPE_WMVi) {
          /* We must have a WMVi packet to initialise things before we can 
           * continue */
          if (!dec->have_format) {
            GST_WARNING_OBJECT (dec, "Received packet without WMVi: %d",
                r.type);
            return ERROR_INVALID;
          }
          if (r.x + r.width > dec->format.width ||
              r.y + r.height > dec->format.height) {
            GST_WARNING_OBJECT (dec, "Rectangle out of range, type %d", r.type);
            return ERROR_INVALID;
          }
        }

        switch (r.type) {
          case TYPE_WMVd:
            handler = vmnc_handle_wmvd_rectangle;
            break;
          case TYPE_WMVe:
            handler = vmnc_handle_wmve_rectangle;
            break;
          case TYPE_WMVf:
            handler = vmnc_handle_wmvf_rectangle;
            break;
          case TYPE_WMVg:
            handler = vmnc_handle_wmvg_rectangle;
            break;
          case TYPE_WMVh:
            handler = vmnc_handle_wmvh_rectangle;
            break;
          case TYPE_WMVi:
            handler = vmnc_handle_wmvi_rectangle;
            break;
          case TYPE_WMVj:
            handler = vmnc_handle_wmvj_rectangle;
            break;
          case TYPE_RAW:
            handler = vmnc_handle_raw_rectangle;
            break;
          case TYPE_COPY:
            handler = vmnc_handle_copy_rectangle;
            break;
          case TYPE_HEXTILE:
            handler = vmnc_handle_hextile_rectangle;
            break;
          default:
            GST_WARNING_OBJECT (dec, "Unknown rectangle type");
            return ERROR_INVALID;
        }

        read = handler (dec, &r, data + offset + 12, len - offset - 12, decode);
        if (read < 0) {
          GST_DEBUG_OBJECT (dec, "Error calling rectangle handler\n");
          return read;
        }
        offset += 12 + read;
      }
      break;
    }
    default:
      GST_WARNING_OBJECT (dec, "Packet type unknown: %d", type);
      return ERROR_INVALID;
  }

  return offset;
}

static gboolean
vmnc_dec_setcaps (GstPad * pad, GstCaps * caps)
{
  /* We require a format descriptor in-stream, so we ignore the info from the
   * container here. We just use the framerate */
  GstVMncDec *dec = GST_VMNC_DEC (gst_pad_get_parent (pad));

  if (gst_caps_get_size (caps) > 0) {
    GstStructure *structure = gst_caps_get_structure (caps, 0);

    /* We gave these a default in reset(), so we don't need to check for failure
     * here */
    gst_structure_get_fraction (structure, "framerate",
        &dec->framerate_num, &dec->framerate_denom);

    dec->parsed = TRUE;
  } else {
    GST_DEBUG_OBJECT (dec, "Unparsed input");
    dec->parsed = FALSE;
  }

  gst_object_unref (dec);

  return TRUE;
}

static GstFlowReturn
vmnc_dec_chain_frame (GstVMncDec * dec, GstBuffer * inbuf,
    const guint8 * data, int len)
{
  int res;
  GstFlowReturn ret = GST_FLOW_OK;
  GstBuffer *outbuf;

  res = vmnc_handle_packet (dec, data, len, TRUE);

  if (res < 0) {
    ret = GST_FLOW_ERROR;
    GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("Couldn't decode packet"));
  } else {
    GST_DEBUG_OBJECT (dec, "read %d bytes of %d", res, len);
    /* inbuf may be NULL; that's ok */
    outbuf = vmnc_make_buffer (dec, inbuf);
    ret = gst_pad_push (dec->srcpad, outbuf);
  }

  return ret;
}

static GstFlowReturn
vmnc_dec_chain (GstPad * pad, GstBuffer * buf)
{
  GstVMncDec *dec;
  GstFlowReturn ret = GST_FLOW_OK;

  dec = GST_VMNC_DEC (gst_pad_get_parent (pad));

  if (!dec->parsed) {
    /* Submit our input buffer to adapter, then parse. Push each frame found
     * through the decoder
     */
    int avail;
    const guint8 *data;
    int read = 0;

    gst_adapter_push (dec->adapter, buf);


    avail = gst_adapter_available (dec->adapter);
    data = gst_adapter_peek (dec->adapter, avail);

    GST_DEBUG_OBJECT (dec, "Parsing %d bytes", avail);

    while (TRUE) {
      int len = vmnc_handle_packet (dec, data, avail, FALSE);

      if (len == ERROR_INSUFFICIENT_DATA) {
        GST_DEBUG_OBJECT (dec, "Not enough data yet");
        ret = GST_FLOW_OK;
        break;
      } else if (len < 0) {
        GST_DEBUG_OBJECT (dec, "Fatal error in bitstream");
        ret = GST_FLOW_ERROR;
        break;
      }

      GST_DEBUG_OBJECT (dec, "Parsed packet: %d bytes", len);

      ret = vmnc_dec_chain_frame (dec, NULL, data, len);
      avail -= len;
      data += len;

      read += len;

      if (ret != GST_FLOW_OK)
        break;
    }
    GST_DEBUG_OBJECT (dec, "Flushing %d bytes", read);

    gst_adapter_flush (dec->adapter, read);
  } else {
    ret = vmnc_dec_chain_frame (dec, buf, GST_BUFFER_DATA (buf),
        GST_BUFFER_SIZE (buf));
    gst_buffer_unref (buf);
  }

  gst_object_unref (dec);

  return ret;
}

static GstStateChangeReturn
vmnc_dec_change_state (GstElement * element, GstStateChange transition)
{
  GstVMncDec *dec = GST_VMNC_DEC (element);
  GstStateChangeReturn ret;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_vmnc_dec_reset (dec);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

  ret = parent_class->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_vmnc_dec_reset (dec);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

  return ret;
}

static void
vmnc_dec_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  /*GstVMncDec *dec = GST_VMNC_DEC (object); */

  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
vmnc_dec_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  /*GstVMncDec *dec = GST_VMNC_DEC (object); */

  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  if (!gst_element_register (plugin, "vmncdec", GST_RANK_PRIMARY,
          gst_vmnc_dec_get_type ()))
    return FALSE;
  return TRUE;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    "vmnc",
    "VmWare Video Codec plugins",
    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
