/* GStreamer
 * Copyright (C) 2010 Oblong Industries, Inc.
 * Copyright (C) 2010 Collabora Multimedia
 *
 * 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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

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

#include "jp2kcodestream.h"

GST_DEBUG_CATEGORY_EXTERN (gst_jp2k_decimator_debug);
#define GST_CAT_DEFAULT gst_jp2k_decimator_debug

/* Delimiting markers and marker segments */
#define MARKER_SOC 0xFF4F
#define MARKER_SOT 0xFF90
#define MARKER_SOD 0xFF93
#define MARKER_EOC 0xFFD9

/* Fixed information marker segments */
#define MARKER_SIZ 0xFF51

/* Functional marker segments */
#define MARKER_COD 0xFF52
#define MARKER_COC 0xFF53
#define MARKER_RGN 0xFF5E
#define MARKER_QCD 0xFF5C
#define MARKER_QCC 0xFF5D
#define MARKER_POC 0xFF5F

/* Pointer marker segments */
#define MARKER_PLM 0xFF57
#define MARKER_PLT 0xFF58
#define MARKER_PPM 0xFF60
#define MARKER_PPT 0xFF61
#define MARKER_TLM 0xFF55

/* In-bit-stream markers and marker segments */
#define MARKER_SOP 0xFF91
#define MARKER_EPH 0xFF92

/* Informational marker segments */
#define MARKER_CRG 0xFF63
#define MARKER_COM 0xFF64

static void
packet_iterator_changed_resolution_or_component (PacketIterator * it)
{
  gint tx0, tx1, ty0, ty1;
  gint tcx0, tcx1, tcy0, tcy1;
  gint trx0, trx1, try0, try1;
  gint tpx0, tpx1, tpy0, tpy1;
  gint two_nl_r;
  gint two_ppx, two_ppy;
  gint xr, yr;
  guint8 *PPx, *PPy;

  tx0 = it->tile->tx0;
  tx1 = it->tile->tx1;
  ty0 = it->tile->ty0;
  ty1 = it->tile->ty1;

  it->two_nl_r = two_nl_r = (1 << (it->n_resolutions - it->cur_resolution - 1));

  PPx = it->tile->cod ? it->tile->cod->PPx : it->header->cod.PPx;
  PPy = it->tile->cod ? it->tile->cod->PPy : it->header->cod.PPy;
  it->two_ppx = two_ppx = (1 << (PPx ? PPx[it->cur_resolution] : 15));
  it->two_ppy = two_ppy = (1 << (PPy ? PPy[it->cur_resolution] : 15));

  it->xr = xr = it->header->siz.components[it->cur_component].xr;
  it->yr = yr = it->header->siz.components[it->cur_component].yr;

  it->tcx0 = tcx0 = (tx0 + xr - 1) / xr;
  it->tcx1 = tcx1 = (tx1 + xr - 1) / xr;
  it->tcy0 = tcy0 = (ty0 + yr - 1) / yr;
  it->tcy1 = tcy1 = (ty1 + yr - 1) / yr;

  it->trx0 = trx0 = (tcx0 + two_nl_r - 1) / two_nl_r;
  it->trx1 = trx1 = (tcx1 + two_nl_r - 1) / two_nl_r;
  it->try0 = try0 = (tcy0 + two_nl_r - 1) / two_nl_r;
  it->try1 = try1 = (tcy1 + two_nl_r - 1) / two_nl_r;

  it->tpx0 = tpx0 = two_ppx * (trx0 / two_ppx);
  it->tpx1 = tpx1 = two_ppx * ((trx1 + two_ppx - 1) / two_ppx);
  it->tpy0 = tpy0 = two_ppy * (try0 / two_ppy);
  it->tpy1 = tpy1 = two_ppy * ((try1 + two_ppy - 1) / two_ppy);

  it->n_precincts_w = (trx0 == trx1) ? 0 : (tpx1 - tpx0) / two_ppx;
  it->n_precincts_h = (try0 == try1) ? 0 : (tpy1 - tpy0) / two_ppy;
  it->n_precincts = it->n_precincts_w * it->n_precincts_h;
}

static gboolean
packet_iterator_next_lrcp (PacketIterator * it)
{
  g_return_val_if_fail (it->cur_layer < it->n_layers, FALSE);

  if (it->first) {
    packet_iterator_changed_resolution_or_component (it);
    it->first = FALSE;
    return TRUE;
  }

  it->cur_precinct += 1;
  if (it->cur_precinct >= it->n_precincts) {
    it->cur_precinct = 0;

    it->cur_component += 1;
    if (it->cur_component >= it->n_components) {
      it->cur_component = 0;

      it->cur_resolution += 1;
      if (it->cur_resolution >= it->n_resolutions) {
        it->cur_resolution = 0;
        it->cur_layer += 1;
        if (it->cur_layer >= it->n_layers) {
          it->cur_packet++;
          return FALSE;
        }
      }
    }
    packet_iterator_changed_resolution_or_component (it);
  }

  it->cur_packet++;

  return TRUE;
}

static gboolean
packet_iterator_next_rlcp (PacketIterator * it)
{
  g_return_val_if_fail (it->cur_resolution < it->n_resolutions, FALSE);

  if (it->first) {
    packet_iterator_changed_resolution_or_component (it);
    it->first = FALSE;
    return TRUE;
  }

  it->cur_precinct += 1;
  if (it->cur_precinct >= it->n_precincts) {
    it->cur_precinct = 0;

    it->cur_component += 1;
    if (it->cur_component >= it->n_components) {
      it->cur_component = 0;

      it->cur_layer += 1;
      if (it->cur_layer >= it->n_layers) {
        it->cur_layer = 0;
        it->cur_resolution += 1;
        if (it->cur_resolution >= it->n_resolutions) {
          it->cur_packet++;
          return FALSE;
        }
      }
    }
    packet_iterator_changed_resolution_or_component (it);
  }

  it->cur_packet++;

  return TRUE;
}

static gboolean
packet_iterator_next_rpcl (PacketIterator * it)
{
  g_return_val_if_fail (it->cur_resolution < it->n_resolutions, FALSE);

  if (it->first) {
    packet_iterator_changed_resolution_or_component (it);
    it->first = FALSE;
    return TRUE;
  }

  it->cur_layer += 1;
  if (it->cur_layer >= it->n_layers) {
    it->cur_layer = 0;

    /* Loop and advance the position and resolution until
     * we find the next precinct
     */
    while (TRUE) {
      it->cur_component += 1;
      if (it->cur_component >= it->n_components) {
        it->cur_component = 0;

        it->cur_x += it->x_step - (it->cur_x % it->x_step);
        if (it->cur_x >= it->tx1) {
          it->cur_x = it->tx0;

          it->cur_y += it->y_step - (it->cur_y % it->y_step);
          if (it->cur_y >= it->ty1) {
            it->cur_y = it->ty0;

            it->cur_resolution += 1;

            if (it->cur_resolution >= it->n_resolutions) {
              it->cur_packet++;
              return FALSE;
            }
          }
        }
      }

      packet_iterator_changed_resolution_or_component (it);

      if (((it->cur_y % (it->yr * it->two_ppy * it->two_nl_r) == 0)
              || (it->cur_y == it->ty0
                  && ((it->try0 * it->two_nl_r) %
                      (it->two_ppy * it->two_nl_r) != 0)))
          && ((it->cur_x % (it->xr * it->two_ppx * it->two_nl_r) == 0)
              || (it->cur_x == it->tx0
                  && ((it->trx0 * it->two_nl_r) %
                      (it->two_ppx * it->two_nl_r) != 0)))) {
        gint k;

        k = (((it->cur_x + it->xr * it->two_nl_r - 1) /
                (it->xr * it->two_nl_r)) / it->two_ppx) -
            (it->trx0 / it->two_ppx) +
            it->n_precincts_w *
            (((it->cur_y + it->yr * it->two_nl_r - 1) /
                (it->yr * it->two_nl_r)) / it->two_ppy);

        g_assert (k < it->n_precincts);

        it->cur_precinct = k;
        break;
      }
    }
  }

  it->cur_packet++;

  return TRUE;
}

static gboolean
packet_iterator_next_pcrl (PacketIterator * it)
{
  g_return_val_if_fail (it->cur_resolution < it->n_resolutions, FALSE);

  if (it->first) {
    it->first = FALSE;
    return TRUE;
  }

  it->cur_layer += 1;
  if (it->cur_layer >= it->n_layers) {
    it->cur_layer = 0;

    /* Loop and advance the position and resolution until
     * we find the next precinct
     */
    while (TRUE) {
      it->cur_resolution += 1;
      if (it->cur_resolution >= it->n_resolutions) {
        it->cur_resolution = 0;

        it->cur_component += 1;
        if (it->cur_component >= it->n_components) {

          it->cur_x += it->x_step - (it->cur_x % it->x_step);
          if (it->cur_x >= it->tx1) {
            it->cur_x = it->tx0;

            it->cur_y += it->y_step - (it->cur_y % it->y_step);
            if (it->cur_y >= it->ty1) {
              it->cur_packet++;
              return FALSE;
            }
          }
        }
      }

      packet_iterator_changed_resolution_or_component (it);

      if (((it->cur_y % (it->yr * it->two_ppy * it->two_nl_r) == 0)
              || (it->cur_y == it->ty0
                  && ((it->try0 * it->two_nl_r) %
                      (it->two_ppy * it->two_nl_r) != 0)))
          && ((it->cur_x % (it->xr * it->two_ppx * it->two_nl_r) == 0)
              || (it->cur_x == it->tx0
                  && ((it->trx0 * it->two_nl_r) %
                      (it->two_ppx * it->two_nl_r) != 0)))) {
        gint k;

        k = (((it->cur_x + it->xr * it->two_nl_r - 1) /
                (it->xr * it->two_nl_r)) / it->two_ppx) -
            (it->trx0 / it->two_ppx) +
            it->n_precincts_w *
            (((it->cur_y + it->yr * it->two_nl_r - 1) /
                (it->yr * it->two_nl_r)) / it->two_ppy);

        g_assert (k < it->n_precincts);

        it->cur_precinct = k;
        break;
      }
    }
  }

  it->cur_packet++;

  return TRUE;
}

static gboolean
packet_iterator_next_cprl (PacketIterator * it)
{
  g_return_val_if_fail (it->cur_resolution < it->n_resolutions, FALSE);

  if (it->first) {
    packet_iterator_changed_resolution_or_component (it);
    it->first = FALSE;
    return TRUE;
  }

  it->cur_layer += 1;
  if (it->cur_layer >= it->n_layers) {
    it->cur_layer = 0;

    /* Loop and advance the position and resolution until
     * we find the next precinct
     */
    while (TRUE) {
      it->cur_resolution += 1;
      if (it->cur_resolution >= it->n_resolutions) {
        it->cur_resolution = 0;

        it->cur_x += it->x_step - (it->cur_x % it->x_step);
        if (it->cur_x >= it->tx1) {
          it->cur_x = it->tx0;

          it->cur_y += it->y_step - (it->cur_y % it->y_step);
          if (it->cur_y >= it->ty1) {
            it->cur_y = it->ty0;

            it->cur_component += 1;

            if (it->cur_component >= it->n_components) {
              it->cur_packet++;
              return FALSE;
            }
          }
        }
      }

      packet_iterator_changed_resolution_or_component (it);

      if (((it->cur_y % (it->yr * it->two_ppy * it->two_nl_r) == 0)
              || (it->cur_y == it->ty0
                  && ((it->try0 * it->two_nl_r) %
                      (it->two_ppy * it->two_nl_r) != 0)))
          && ((it->cur_x % (it->xr * it->two_ppx * it->two_nl_r) == 0)
              || (it->cur_x == it->tx0
                  && ((it->trx0 * it->two_nl_r) %
                      (it->two_ppx * it->two_nl_r) != 0)))) {
        gint k;

        k = (((it->cur_x + it->xr * it->two_nl_r - 1) /
                (it->xr * it->two_nl_r)) / it->two_ppx) -
            (it->trx0 / it->two_ppx) +
            it->n_precincts_w *
            (((it->cur_y + it->yr * it->two_nl_r - 1) /
                (it->yr * it->two_nl_r)) / it->two_ppy);

        g_assert (k < it->n_precincts);

        it->cur_precinct = k;
        break;
      }
    }
  }

  it->cur_packet++;

  return TRUE;
}

static GstFlowReturn
init_packet_iterator (GstJP2kDecimator * self, PacketIterator * it,
    const MainHeader * header, const Tile * tile)
{
  ProgressionOrder order;
  gint i, j;

  memset (it, 0, sizeof (PacketIterator));

  it->header = header;
  it->tile = tile;

  it->first = TRUE;

  it->n_layers = (tile->cod) ? tile->cod->n_layers : header->cod.n_layers;
  it->n_resolutions =
      1 +
      ((tile->cod) ? tile->cod->n_decompositions : header->cod.
      n_decompositions);
  it->n_components = header->siz.n_components;

  it->tx0 = tile->tx0;
  it->tx1 = tile->tx1;
  it->ty0 = tile->ty0;
  it->ty1 = tile->ty1;

  it->cur_x = it->tx0;
  it->cur_y = it->ty0;

  /* Calculate the step sizes for the position-dependent progression orders */
  it->x_step = it->y_step = 0;
  for (i = 0; i < it->n_components; i++) {
    gint xr, yr;

    xr = header->siz.components[i].xr;
    yr = header->siz.components[i].yr;


    for (j = 0; j < it->n_resolutions; j++) {
      gint xs, ys;
      guint8 PPx, PPy;

      if (tile->cod) {
        PPx = (tile->cod->PPx) ? tile->cod->PPx[j] : 15;
        PPy = (tile->cod->PPy) ? tile->cod->PPy[j] : 15;
      } else {
        PPx = (header->cod.PPx) ? header->cod.PPx[j] : 15;
        PPy = (header->cod.PPy) ? header->cod.PPy[j] : 15;
      }

      xs = xr * (1 << (PPx + it->n_resolutions - j - 1));
      ys = yr * (1 << (PPy + it->n_resolutions - j - 1));

      if (it->x_step == 0 || it->x_step > xs)
        it->x_step = xs;
      if (it->y_step == 0 || it->y_step > ys)
        it->y_step = ys;
    }
  }

  order =
      (tile->cod) ? tile->cod->progression_order : header->cod.
      progression_order;
  if (order == PROGRESSION_ORDER_LRCP) {
    it->next = packet_iterator_next_lrcp;
  } else if (order == PROGRESSION_ORDER_RLCP) {
    it->next = packet_iterator_next_rlcp;
  } else if (order == PROGRESSION_ORDER_RPCL) {
    it->next = packet_iterator_next_rpcl;
  } else if (order == PROGRESSION_ORDER_PCRL) {
    it->next = packet_iterator_next_pcrl;
  } else if (order == PROGRESSION_ORDER_CPRL) {
    it->next = packet_iterator_next_cprl;
  } else {
    GST_ERROR_OBJECT (self, "Progression order %d not supported", order);
    return GST_FLOW_ERROR;
  }

  return GST_FLOW_OK;
}

static GstFlowReturn
parse_siz (GstJP2kDecimator * self, GstByteReader * reader,
    ImageSize * siz, guint16 length)
{
  gint i;

  if (length < 38) {
    GST_ERROR_OBJECT (self, "Invalid SIZ marker");
    return GST_FLOW_ERROR;
  }

  siz->caps = gst_byte_reader_get_uint16_be_unchecked (reader);
  siz->x = gst_byte_reader_get_uint32_be_unchecked (reader);
  siz->y = gst_byte_reader_get_uint32_be_unchecked (reader);
  siz->xo = gst_byte_reader_get_uint32_be_unchecked (reader);
  siz->yo = gst_byte_reader_get_uint32_be_unchecked (reader);
  siz->xt = gst_byte_reader_get_uint32_be_unchecked (reader);
  siz->yt = gst_byte_reader_get_uint32_be_unchecked (reader);
  siz->xto = gst_byte_reader_get_uint32_be_unchecked (reader);
  siz->yto = gst_byte_reader_get_uint32_be_unchecked (reader);
  siz->n_components = gst_byte_reader_get_uint16_be_unchecked (reader);

  if (length < 38 + 3 * siz->n_components) {
    GST_ERROR_OBJECT (self, "Invalid SIZ marker");
    return GST_FLOW_ERROR;
  }

  siz->components = g_slice_alloc (sizeof (ComponentSize) * siz->n_components);
  for (i = 0; i < siz->n_components; i++) {
    siz->components[i].s = gst_byte_reader_get_uint8_unchecked (reader);
    siz->components[i].xr = gst_byte_reader_get_uint8_unchecked (reader);
    siz->components[i].yr = gst_byte_reader_get_uint8_unchecked (reader);
  }

  return GST_FLOW_OK;
}

static guint
sizeof_siz (GstJP2kDecimator * self, const ImageSize * siz)
{
  return 2 + 38 + 3 * siz->n_components;
}

static void
reset_siz (GstJP2kDecimator * self, ImageSize * siz)
{
  if (siz->components)
    g_slice_free1 (sizeof (ComponentSize) * siz->n_components, siz->components);
  memset (siz, 0, sizeof (ImageSize));
}

static GstFlowReturn
write_siz (GstJP2kDecimator * self, GstByteWriter * writer,
    const ImageSize * siz)
{
  gint i;

  if (!gst_byte_writer_ensure_free_space (writer,
          2 + 38 + 3 * siz->n_components)) {
    GST_ERROR_OBJECT (self, "Could not ensure free space");
    return GST_FLOW_ERROR;
  }

  gst_byte_writer_put_uint16_be_unchecked (writer, MARKER_SIZ);
  gst_byte_writer_put_uint16_be_unchecked (writer, 38 + 3 * siz->n_components);
  gst_byte_writer_put_uint16_be_unchecked (writer, siz->caps);
  gst_byte_writer_put_uint32_be_unchecked (writer, siz->x);
  gst_byte_writer_put_uint32_be_unchecked (writer, siz->y);
  gst_byte_writer_put_uint32_be_unchecked (writer, siz->xo);
  gst_byte_writer_put_uint32_be_unchecked (writer, siz->yo);
  gst_byte_writer_put_uint32_be_unchecked (writer, siz->xt);
  gst_byte_writer_put_uint32_be_unchecked (writer, siz->yt);
  gst_byte_writer_put_uint32_be_unchecked (writer, siz->xto);
  gst_byte_writer_put_uint32_be_unchecked (writer, siz->yto);
  gst_byte_writer_put_uint16_be_unchecked (writer, siz->n_components);

  for (i = 0; i < siz->n_components; i++) {
    gst_byte_writer_put_uint8_unchecked (writer, siz->components[i].s);
    gst_byte_writer_put_uint8_unchecked (writer, siz->components[i].xr);
    gst_byte_writer_put_uint8_unchecked (writer, siz->components[i].yr);
  }

  return GST_FLOW_OK;
}

static GstFlowReturn
parse_cod (GstJP2kDecimator * self, GstByteReader * reader,
    CodingStyleDefault * cod, guint16 length)
{
  guint8 Scod;

  if (length < 12) {
    GST_ERROR_OBJECT (self, "Invalid COD marker");
    return GST_FLOW_ERROR;
  }

  Scod = gst_byte_reader_get_uint8_unchecked (reader);
  cod->sop = ! !(Scod & 0x02);
  cod->eph = ! !(Scod & 0x04);

  /* SGcod */
  cod->progression_order = gst_byte_reader_get_uint8_unchecked (reader);
  cod->n_layers = gst_byte_reader_get_uint16_be_unchecked (reader);
  cod->multi_component_transform = gst_byte_reader_get_uint8_unchecked (reader);

  /* SPcod */
  cod->n_decompositions = gst_byte_reader_get_uint8_unchecked (reader);
  cod->xcb = gst_byte_reader_get_uint8_unchecked (reader) + 2;
  cod->ycb = gst_byte_reader_get_uint8_unchecked (reader) + 2;
  cod->code_block_style = gst_byte_reader_get_uint8_unchecked (reader);
  cod->transformation = gst_byte_reader_get_uint8_unchecked (reader);

  if ((Scod & 0x01)) {
    gint i;
    /* User defined precincts */

    if (length < 12 + (Scod & 0x01) * (cod->n_decompositions + 1)) {
      GST_ERROR_OBJECT (self, "Invalid COD marker");
      return GST_FLOW_ERROR;
    }

    cod->PPx = g_slice_alloc (sizeof (guint8) * (cod->n_decompositions + 1));
    for (i = 0; i < cod->n_decompositions + 1; i++) {
      guint8 v = gst_byte_reader_get_uint8_unchecked (reader);
      cod->PPx[i] = (v & 0x0f);
      cod->PPy[i] = (v >> 4);
    }
  }

  return GST_FLOW_OK;
}

static guint
sizeof_cod (GstJP2kDecimator * self, const CodingStyleDefault * cod)
{
  return 2 + 12 + (cod->PPx ? (cod->n_decompositions + 1) : 0);
}

static void
reset_cod (GstJP2kDecimator * self, CodingStyleDefault * cod)
{
  if (cod->PPx)
    g_slice_free1 (sizeof (guint8) * (cod->n_decompositions + 1), cod->PPx);
  if (cod->PPy)
    g_slice_free1 (sizeof (guint8) * (cod->n_decompositions + 1), cod->PPy);
  memset (cod, 0, sizeof (CodingStyleDefault));
}

static GstFlowReturn
write_cod (GstJP2kDecimator * self, GstByteWriter * writer,
    const CodingStyleDefault * cod)
{
  guint tmp;

  tmp = 12 + (cod->PPx ? (1 + cod->n_decompositions) : 0);
  if (!gst_byte_writer_ensure_free_space (writer, tmp)) {
    GST_ERROR_OBJECT (self, "Could not ensure free space");
    return GST_FLOW_ERROR;
  }

  gst_byte_writer_put_uint16_be_unchecked (writer, MARKER_COD);
  gst_byte_writer_put_uint16_be_unchecked (writer, tmp);

  /* Scod */
  tmp =
      (cod->PPx ? 0x01 : 0x00) | (cod->sop ? 0x02 : 0x00) | (cod->
      eph ? 0x04 : 0x00);
  gst_byte_writer_put_uint8_unchecked (writer, tmp);

  /* SGcod */
  gst_byte_writer_put_uint8_unchecked (writer, cod->progression_order);
  gst_byte_writer_put_uint16_be_unchecked (writer, cod->n_layers);
  gst_byte_writer_put_uint8_unchecked (writer, cod->multi_component_transform);

  /* SPcod */
  gst_byte_writer_put_uint8_unchecked (writer, cod->n_decompositions);
  gst_byte_writer_put_uint8_unchecked (writer, cod->xcb - 2);
  gst_byte_writer_put_uint8_unchecked (writer, cod->ycb - 2);
  gst_byte_writer_put_uint8_unchecked (writer, cod->code_block_style);
  gst_byte_writer_put_uint8_unchecked (writer, cod->transformation);

  if (cod->PPx) {
    gint i;

    for (i = 0; i < cod->n_decompositions + 1; i++) {
      tmp = (cod->PPx[i]) | (cod->PPy[i] << 4);
      gst_byte_writer_put_uint8_unchecked (writer, tmp);
    }
  }

  return GST_FLOW_OK;
}

static GstFlowReturn
parse_plt (GstJP2kDecimator * self, GstByteReader * reader,
    PacketLengthTilePart * plt, guint length)
{
  guint32 n;
  guint8 b = 0;
  gint i;

  if (length < 3) {
    GST_ERROR_OBJECT (self, "Invalid PLT");
    return GST_FLOW_ERROR;
  }

  plt->index = gst_byte_reader_get_uint8_unchecked (reader);
  plt->packet_lengths = g_array_new (FALSE, FALSE, sizeof (guint32));

  length -= 3;

  n = 0;
  for (i = 0; i < length; i++) {
    b = gst_byte_reader_get_uint8_unchecked (reader);

    if ((n & 0xfe000000)) {
      GST_ERROR_OBJECT (self, "PLT element overflow");
      return GST_FLOW_ERROR;
    }

    n = (n << 7) | (b & 0x7f);
    if ((b & 0x80) == 0x00) {
      g_array_append_val (plt->packet_lengths, n);
      n = 0;
    }
  }

  if ((b & 0x80) != 0x00) {
    GST_ERROR_OBJECT (self, "Truncated PLT");
    return GST_FLOW_ERROR;
  }
  return GST_FLOW_OK;
}

static guint
sizeof_plt (GstJP2kDecimator * self, const PacketLengthTilePart * plt)
{
  guint size = 2 + 3;
  gint i, n;

  n = plt->packet_lengths->len;
  for (i = 0; i < n; i++) {
    guint32 len = g_array_index (plt->packet_lengths, guint32, i);

    if (len < (1 << 7)) {
      size += 1;
    } else if (len < (1 << 14)) {
      size += 2;
    } else if (len < (1 << 21)) {
      size += 3;
    } else if (len < (1 << 28)) {
      size += 4;
    } else {
      size += 5;
    }
  }

  return size;
}

static void
reset_plt (GstJP2kDecimator * self, PacketLengthTilePart * plt)
{
  if (plt->packet_lengths)
    g_array_free (plt->packet_lengths, TRUE);
  memset (plt, 0, sizeof (PacketLengthTilePart));
}

static GstFlowReturn
write_plt (GstJP2kDecimator * self, GstByteWriter * writer,
    const PacketLengthTilePart * plt)
{
  gint i, n;
  guint plt_start_pos, plt_end_pos;

  if (!gst_byte_writer_ensure_free_space (writer, 2 + 2 + 1)) {
    GST_ERROR_OBJECT (self, "Could not ensure free space");
    return GST_FLOW_ERROR;
  }

  gst_byte_writer_put_uint16_be_unchecked (writer, MARKER_PLT);
  plt_start_pos = gst_byte_writer_get_pos (writer);
  gst_byte_writer_put_uint16_be_unchecked (writer, 0);

  gst_byte_writer_put_uint8_unchecked (writer, plt->index);

  n = plt->packet_lengths->len;
  for (i = 0; i < n; i++) {
    guint32 len = g_array_index (plt->packet_lengths, guint32, i);

    /* FIXME: Write multiple plt here */
    if (gst_byte_writer_get_pos (writer) - plt_start_pos > 65535 - 5) {
      GST_ERROR_OBJECT (self, "Too big PLT");
      return GST_FLOW_ERROR;
    }

    if (len < (1 << 7)) {
      if (!gst_byte_writer_ensure_free_space (writer, 1)) {
        GST_ERROR_OBJECT (self, "Could not ensure free space");
        return GST_FLOW_ERROR;
      }
      gst_byte_writer_put_uint8_unchecked (writer, (0x00 | (len & 0x7f)));
    } else if (len < (1 << 14)) {
      if (!gst_byte_writer_ensure_free_space (writer, 2)) {
        GST_ERROR_OBJECT (self, "Could not ensure free space");
        return GST_FLOW_ERROR;
      }
      gst_byte_writer_put_uint8_unchecked (writer,
          (0x80 | ((len >> 7) & 0x7f)));
      gst_byte_writer_put_uint8_unchecked (writer, (0x00 | (len & 0x7f)));
    } else if (len < (1 << 21)) {
      if (!gst_byte_writer_ensure_free_space (writer, 3)) {
        GST_ERROR_OBJECT (self, "Could not ensure free space");
        return GST_FLOW_ERROR;
      }
      gst_byte_writer_put_uint8_unchecked (writer,
          (0x80 | ((len >> 14) & 0x7f)));
      gst_byte_writer_put_uint8_unchecked (writer,
          (0x80 | ((len >> 7) & 0x7f)));
      gst_byte_writer_put_uint8_unchecked (writer, (0x00 | (len & 0x7f)));
    } else if (len < (1 << 28)) {
      if (!gst_byte_writer_ensure_free_space (writer, 4)) {
        GST_ERROR_OBJECT (self, "Could not ensure free space");
        return GST_FLOW_ERROR;
      }
      gst_byte_writer_put_uint8_unchecked (writer,
          (0x80 | ((len >> 21) & 0x7f)));
      gst_byte_writer_put_uint8_unchecked (writer,
          (0x80 | ((len >> 14) & 0x7f)));
      gst_byte_writer_put_uint8_unchecked (writer,
          (0x80 | ((len >> 7) & 0x7f)));
      gst_byte_writer_put_uint8_unchecked (writer, (0x00 | (len & 0x7f)));
    } else {
      if (!gst_byte_writer_ensure_free_space (writer, 5)) {
        GST_ERROR_OBJECT (self, "Could not ensure free space");
        return GST_FLOW_ERROR;
      }
      gst_byte_writer_put_uint8_unchecked (writer,
          (0x80 | ((len >> 28) & 0x7f)));
      gst_byte_writer_put_uint8_unchecked (writer,
          (0x80 | ((len >> 21) & 0x7f)));
      gst_byte_writer_put_uint8_unchecked (writer,
          (0x80 | ((len >> 14) & 0x7f)));
      gst_byte_writer_put_uint8_unchecked (writer,
          (0x80 | ((len >> 7) & 0x7f)));
      gst_byte_writer_put_uint8_unchecked (writer, (0x00 | (len & 0x7f)));
    }
  }

  plt_end_pos = gst_byte_writer_get_pos (writer);
  gst_byte_writer_set_pos (writer, plt_start_pos);
  if (!gst_byte_writer_put_uint16_be (writer, plt_end_pos - plt_start_pos)) {
    GST_ERROR_OBJECT (self, "Not enough space to write plt size");
    return GST_FLOW_ERROR;
  }

  gst_byte_writer_set_pos (writer, plt_end_pos);

  return GST_FLOW_OK;
}

static GstFlowReturn
parse_packet (GstJP2kDecimator * self, GstByteReader * reader,
    const MainHeader * header, Tile * tile, const PacketIterator * it)
{
  GstFlowReturn ret = GST_FLOW_OK;
  guint16 marker = 0, length;
  guint16 seqno = 0;
  guint packet_start_pos;
  const guint8 *packet_start_data;
  gboolean sop, eph;
  PacketLengthTilePart *plt = NULL;

  sop = (tile->cod) ? tile->cod->sop : header->cod.sop;
  eph = (tile->cod) ? tile->cod->eph : header->cod.eph;
  if (tile->plt) {
    if (g_list_length (tile->plt) > 1) {
      GST_ERROR_OBJECT (self,
          "Only a single PLT per tile is supported currently");
      ret = GST_FLOW_ERROR;
      goto done;
    }
    plt = tile->plt->data;
  }

  if (plt) {
    guint32 length;
    Packet *p;

    if (plt->packet_lengths->len <= it->cur_packet) {
      GST_ERROR_OBJECT (self, "Truncated PLT");
      ret = GST_FLOW_ERROR;
      goto done;
    }

    length = g_array_index (plt->packet_lengths, guint32, it->cur_packet);

    if (gst_byte_reader_get_remaining (reader) < length) {
      GST_ERROR_OBJECT (self, "Truncated file");
      ret = GST_FLOW_ERROR;
      goto done;
    }

    p = g_slice_new0 (Packet);

    /* If there is a SOP keep the seqno */
    if (sop && length > 6) {
      if (!gst_byte_reader_peek_uint16_be (reader, &marker)) {
        GST_ERROR_OBJECT (self, "Truncated file");
        ret = GST_FLOW_ERROR;
        g_slice_free (Packet, p);
        goto done;
      }

      if (marker == MARKER_SOP) {
        guint16 dummy;

        gst_byte_reader_skip_unchecked (reader, 2);

        if (!gst_byte_reader_get_uint16_be (reader, &dummy)) {
          GST_ERROR_OBJECT (self, "Truncated file");
          ret = GST_FLOW_ERROR;
          g_slice_free (Packet, p);
          goto done;
        }

        if (!gst_byte_reader_get_uint16_be (reader, &seqno)) {
          GST_ERROR_OBJECT (self, "Truncated file");
          ret = GST_FLOW_ERROR;
          g_slice_free (Packet, p);
          goto done;
        }
        p->data = gst_byte_reader_peek_data_unchecked (reader);
        p->length = length - 6;
        p->sop = TRUE;
        p->eph = eph;
        p->seqno = seqno;
        gst_byte_reader_skip_unchecked (reader, length - 6);
      }
    }

    if (!p->data) {
      p->data = gst_byte_reader_peek_data_unchecked (reader);
      p->length = length;
      p->sop = FALSE;
      p->eph = eph;
      gst_byte_reader_skip_unchecked (reader, length);
    }

    tile->packets = g_list_prepend (tile->packets, p);
  } else if (sop) {
    if (!gst_byte_reader_peek_uint16_be (reader, &marker)) {
      GST_ERROR_OBJECT (self, "Truncated file");
      ret = GST_FLOW_ERROR;
      goto done;
    }

    if (marker != MARKER_SOP) {
      GST_ERROR_OBJECT (self, "No SOP marker");
      ret = GST_FLOW_EOS;
      goto done;
    }

    gst_byte_reader_skip_unchecked (reader, 2);

    if (!gst_byte_reader_get_uint16_be (reader, &length)) {
      GST_ERROR_OBJECT (self, "Truncated file");
      ret = GST_FLOW_ERROR;
      goto done;
    }

    if (!gst_byte_reader_get_uint16_be (reader, &seqno)) {
      GST_ERROR_OBJECT (self, "Truncated file");
      ret = GST_FLOW_ERROR;
      goto done;
    }

    packet_start_data = reader->data + reader->byte;
    packet_start_pos = gst_byte_reader_get_pos (reader);

    /* Find end of packet */
    while (TRUE) {
      if (!gst_byte_reader_peek_uint16_be (reader, &marker)) {
        GST_ERROR_OBJECT (self, "Truncated file");
        ret = GST_FLOW_ERROR;
        goto done;
      }

      if (marker == MARKER_SOP || marker == MARKER_EOC || marker == MARKER_SOT) {
        Packet *p = g_slice_new (Packet);

        p->sop = TRUE;
        p->eph = eph;
        p->seqno = seqno;
        p->data = packet_start_data;
        p->length = reader->byte - packet_start_pos;
        tile->packets = g_list_prepend (tile->packets, p);

        if (marker == MARKER_EOC || marker == MARKER_SOT)
          goto done;
        else
          break;
      }

      gst_byte_reader_skip_unchecked (reader, 1);
    }
  } else {
    GST_ERROR_OBJECT (self, "Either PLT or SOP are required");
    ret = GST_FLOW_ERROR;
    goto done;
  }

done:

  return ret;
}

static guint
sizeof_packet (GstJP2kDecimator * self, const Packet * packet)
{
  return packet->length + (packet->sop ? 6 : 0) + ((packet->eph
          && !packet->data) ? 2 : 0);
}

static GstFlowReturn
parse_packets (GstJP2kDecimator * self, GstByteReader * reader,
    const MainHeader * header, Tile * tile)
{
  guint16 marker = 0;
  GstFlowReturn ret = GST_FLOW_OK;
  PacketIterator it;

  /* Start of data here */
  if (!gst_byte_reader_get_uint16_be (reader, &marker)
      && marker != MARKER_SOD) {
    GST_ERROR_OBJECT (self, "No SOD in tile");
    return GST_FLOW_ERROR;
  }

  ret = init_packet_iterator (self, &it, header, tile);
  if (ret != GST_FLOW_OK)
    goto done;

  while ((it.next (&it))) {
    ret = parse_packet (self, reader, header, tile, &it);
    if (ret != GST_FLOW_OK)
      goto done;
  }

  tile->packets = g_list_reverse (tile->packets);

done:

  return ret;
}

static GstFlowReturn
parse_tile (GstJP2kDecimator * self, GstByteReader * reader,
    const MainHeader * header, Tile * tile)
{
  GstFlowReturn ret = GST_FLOW_OK;
  guint16 marker = 0, length;

  if (!gst_byte_reader_peek_uint16_be (reader, &marker)) {
    GST_ERROR_OBJECT (self, "Could not read marker");
    ret = GST_FLOW_ERROR;
    goto done;
  }

  if (marker != MARKER_SOT) {
    GST_ERROR_OBJECT (self, "Unexpected marker 0x%04x", marker);
    ret = GST_FLOW_ERROR;
    goto done;
  }

  /* Skip marker */
  gst_byte_reader_skip_unchecked (reader, 2);

  if (gst_byte_reader_get_remaining (reader) < 10) {
    GST_ERROR_OBJECT (self, "Invalid SOT marker");
    ret = GST_FLOW_ERROR;
    goto done;
  }

  length = gst_byte_reader_get_uint16_be_unchecked (reader);
  if (length != 10) {
    GST_ERROR_OBJECT (self, "Invalid SOT length");
    ret = GST_FLOW_ERROR;
    goto done;
  }

  /* FIXME: handle multiple tile parts per tile */
  tile->sot.tile_index = gst_byte_reader_get_uint16_be_unchecked (reader);
  tile->sot.tile_part_size = gst_byte_reader_get_uint32_be_unchecked (reader);
  tile->sot.tile_part_index = gst_byte_reader_get_uint8_unchecked (reader);
  tile->sot.n_tile_parts = gst_byte_reader_get_uint8_unchecked (reader);

  if (tile->sot.tile_part_size >
      2 + 10 + gst_byte_reader_get_remaining (reader)) {
    GST_ERROR_OBJECT (self, "Truncated tile part");
    ret = GST_FLOW_ERROR;
    goto done;
  }

  tile->tile_x = tile->sot.tile_index % header->n_tiles_x;
  tile->tile_y = tile->sot.tile_index / header->n_tiles_x;

  tile->tx0 =
      MAX (header->siz.xto + tile->tile_x * header->siz.xt, header->siz.xo);
  tile->ty0 =
      MAX (header->siz.yto + tile->tile_y * header->siz.yt, header->siz.yo);
  tile->tx1 =
      MIN (header->siz.xto + (tile->tile_x + 1) * header->siz.xt,
      header->siz.x);
  tile->ty1 =
      MIN (header->siz.yto + (tile->tile_y + 1) * header->siz.yt,
      header->siz.y);

  /* tile part header */
  while (TRUE) {
    if (!gst_byte_reader_peek_uint16_be (reader, &marker)) {
      GST_ERROR_OBJECT (self, "Could not read marker");
      ret = GST_FLOW_ERROR;
      goto done;
    }

    /* SOD starts the data */
    if (marker == MARKER_SOD) {
      break;
    }

    if ((marker >> 8) != 0xff) {
      GST_ERROR_OBJECT (self, "Lost synchronization (0x%04x)", marker);
      ret = GST_FLOW_ERROR;
      goto done;
    }

    /* Skip the marker */
    gst_byte_reader_skip_unchecked (reader, 2);

    /* All markers here have a length */
    if (!gst_byte_reader_get_uint16_be (reader, &length)) {
      GST_ERROR_OBJECT (self, "Could not read marker length");
      ret = GST_FLOW_ERROR;
      goto done;
    }

    if (length < 2 || gst_byte_reader_get_remaining (reader) < length - 2) {
      GST_ERROR_OBJECT (self, "Invalid marker length %u (available %u)",
          length, gst_byte_reader_get_remaining (reader));
      ret = GST_FLOW_ERROR;
      goto done;
    }

    GST_LOG_OBJECT (self,
        "Tile header Marker 0x%04x at offset %u with length %u", marker,
        gst_byte_reader_get_pos (reader), length);

    switch (marker) {
      case MARKER_COD:
        if (tile->cod) {
          GST_ERROR_OBJECT (self, "Only one COD allowed");
          ret = GST_FLOW_ERROR;
          goto done;
        }

        tile->cod = g_slice_new0 (CodingStyleDefault);
        ret = parse_cod (self, reader, tile->cod, length);
        if (ret != GST_FLOW_OK)
          goto done;
        break;
      case MARKER_COC:
        GST_ERROR_OBJECT (self, "COC marker not supported yet");
        ret = GST_FLOW_ERROR;
        goto done;
      case MARKER_POC:
        GST_ERROR_OBJECT (self, "POC marker not supported yet");
        ret = GST_FLOW_ERROR;
        goto done;
      case MARKER_RGN:
        GST_ERROR_OBJECT (self, "RGN marker not supported yet");
        ret = GST_FLOW_ERROR;
        goto done;
      case MARKER_PPT:
        GST_ERROR_OBJECT (self, "PPT marker not supported yet");
        ret = GST_FLOW_ERROR;
        goto done;
      case MARKER_PLT:{
        PacketLengthTilePart *plt = g_slice_new (PacketLengthTilePart);

        ret = parse_plt (self, reader, plt, length);
        if (ret != GST_FLOW_OK) {
          g_slice_free (PacketLengthTilePart, plt);
          goto done;
        }

        tile->plt = g_list_append (tile->plt, plt);
        break;
      }
      case MARKER_QCD:
        if (tile->qcd != NULL) {
          GST_ERROR_OBJECT (self, "Multiple QCD markers");
          ret = GST_FLOW_ERROR;
          goto done;
        }
        tile->qcd = g_slice_new (Buffer);
        tile->qcd->data = gst_byte_reader_peek_data_unchecked (reader);
        tile->qcd->length = length - 2;
        gst_byte_reader_skip_unchecked (reader, length - 2);
        break;
      case MARKER_QCC:{
        Buffer *p = g_slice_new (Buffer);
        p->data = gst_byte_reader_peek_data_unchecked (reader);
        p->length = length - 2;
        tile->qcc = g_list_append (tile->qcc, p);
        gst_byte_reader_skip_unchecked (reader, length - 2);
        break;
      }
      case MARKER_COM:{
        Buffer *p = g_slice_new (Buffer);
        p->data = gst_byte_reader_peek_data_unchecked (reader);
        p->length = length - 2;
        tile->com = g_list_append (tile->com, p);
        gst_byte_reader_skip_unchecked (reader, length - 2);
        break;
      }
      default:
        GST_DEBUG_OBJECT (self, "Skipping unknown marker 0x%04x", marker);
        gst_byte_reader_skip_unchecked (reader, length - 2);
        break;
    }
  }

  ret = parse_packets (self, reader, header, tile);

done:

  return ret;
}

static guint
sizeof_tile (GstJP2kDecimator * self, const Tile * tile)
{
  guint size = 0;
  GList *l;

  /* SOT */
  size += 2 + 2 + 2 + 4 + 1 + 1;

  if (tile->cod)
    size += sizeof_cod (self, tile->cod);

  if (tile->qcd)
    size += 2 + 2 + tile->qcd->length;

  for (l = tile->qcc; l; l = l->next) {
    Buffer *b = l->data;
    size += 2 + 2 + b->length;
  }

  for (l = tile->plt; l; l = l->next) {
    PacketLengthTilePart *plt = l->data;
    size += sizeof_plt (self, plt);
  }

  for (l = tile->com; l; l = l->next) {
    Buffer *b = l->data;
    size += 2 + 2 + b->length;
  }

  /* SOD */
  size += 2;

  for (l = tile->packets; l; l = l->next) {
    Packet *p = l->data;
    size += sizeof_packet (self, p);
  }

  return size;
}

static void
reset_tile (GstJP2kDecimator * self, const MainHeader * header, Tile * tile)
{
  GList *l;

  if (tile->cod) {
    reset_cod (self, tile->cod);
    g_slice_free (CodingStyleDefault, tile->cod);
  }

  for (l = tile->plt; l; l = l->next) {
    PacketLengthTilePart *plt = l->data;

    reset_plt (self, plt);

    g_slice_free (PacketLengthTilePart, plt);
  }
  g_list_free (tile->plt);

  if (tile->qcd)
    g_slice_free (Buffer, tile->qcd);

  for (l = tile->qcc; l; l = l->next) {
    g_slice_free (Buffer, l->data);
  }
  g_list_free (tile->qcc);

  for (l = tile->com; l; l = l->next) {
    g_slice_free (Buffer, l->data);
  }
  g_list_free (tile->com);

  for (l = tile->packets; l; l = l->next) {
    Packet *p = l->data;

    g_slice_free (Packet, p);
  }
  g_list_free (tile->packets);

  memset (tile, 0, sizeof (Tile));
}

static GstFlowReturn
write_marker_buffer (GstJP2kDecimator * self, GstByteWriter * writer,
    guint16 marker, const Buffer * buffer)
{
  if (!gst_byte_writer_ensure_free_space (writer, 2 + 2 + buffer->length)) {
    GST_ERROR_OBJECT (self, "Could not ensure free space");
    return GST_FLOW_ERROR;
  }

  gst_byte_writer_put_uint16_be_unchecked (writer, marker);
  gst_byte_writer_put_uint16_be_unchecked (writer, buffer->length + 2);
  gst_byte_writer_put_data_unchecked (writer, buffer->data, buffer->length);

  return GST_FLOW_OK;
}

static GstFlowReturn
write_packet (GstJP2kDecimator * self, GstByteWriter * writer,
    const Packet * packet)
{
  guint size = packet->length;

  if (packet->sop)
    size += 6;
  if (packet->eph && !packet->data)
    size += 2;

  if (!gst_byte_writer_ensure_free_space (writer, size)) {
    GST_ERROR_OBJECT (self, "Could not ensure free space");
    return GST_FLOW_ERROR;
  }

  if (packet->sop) {
    gst_byte_writer_put_uint16_be_unchecked (writer, MARKER_SOP);
    gst_byte_writer_put_uint16_be_unchecked (writer, 4);
    gst_byte_writer_put_uint16_be_unchecked (writer, packet->seqno);
  }

  if (packet->data) {
    gst_byte_writer_put_data_unchecked (writer, packet->data, packet->length);
  } else {
    gst_byte_writer_put_uint8_unchecked (writer, 0);
    if (packet->eph) {
      gst_byte_writer_put_uint16_be_unchecked (writer, MARKER_EPH);
    }
  }

  return GST_FLOW_OK;
}

static GstFlowReturn
write_tile (GstJP2kDecimator * self, GstByteWriter * writer,
    const MainHeader * header, Tile * tile)
{
  GList *l;
  GstFlowReturn ret = GST_FLOW_OK;

  if (!gst_byte_writer_ensure_free_space (writer, 12)) {
    GST_ERROR_OBJECT (self, "Could not ensure free space");
    return GST_FLOW_ERROR;
  }

  gst_byte_writer_put_uint16_be_unchecked (writer, MARKER_SOT);
  gst_byte_writer_put_uint16_be_unchecked (writer, 10);

  gst_byte_writer_put_uint16_be_unchecked (writer, tile->sot.tile_index);
  gst_byte_writer_put_uint32_be_unchecked (writer, tile->sot.tile_part_size);
  gst_byte_writer_put_uint8_unchecked (writer, tile->sot.tile_part_index);
  gst_byte_writer_put_uint8_unchecked (writer, tile->sot.n_tile_parts);

  if (tile->cod) {
    ret = write_cod (self, writer, tile->cod);
    if (ret != GST_FLOW_OK)
      goto done;
  }

  if (tile->qcd) {
    ret = write_marker_buffer (self, writer, MARKER_QCD, tile->qcd);
    if (ret != GST_FLOW_OK)
      goto done;
  }

  for (l = tile->qcc; l; l = l->next) {
    Buffer *p = l->data;

    ret = write_marker_buffer (self, writer, MARKER_QCC, p);
    if (ret != GST_FLOW_OK)
      goto done;
  }

  for (l = tile->plt; l; l = l->next) {
    PacketLengthTilePart *plt = l->data;

    ret = write_plt (self, writer, plt);
    if (ret != GST_FLOW_OK)
      goto done;
  }

  for (l = tile->com; l; l = l->next) {
    Buffer *p = l->data;

    ret = write_marker_buffer (self, writer, MARKER_COM, p);
    if (ret != GST_FLOW_OK)
      goto done;
  }

  if (!gst_byte_writer_put_uint16_be (writer, MARKER_SOD)) {
    GST_ERROR_OBJECT (self, "Could not ensure free space");
    ret = GST_FLOW_ERROR;
    goto done;
  }

  for (l = tile->packets; l; l = l->next) {
    Packet *p = l->data;

    ret = write_packet (self, writer, p);
    if (ret != GST_FLOW_OK)
      goto done;
  }

done:

  return ret;
}

GstFlowReturn
parse_main_header (GstJP2kDecimator * self, GstByteReader * reader,
    MainHeader * header)
{
  GstFlowReturn ret = GST_FLOW_OK;
  guint16 marker = 0, length = 0;

  /* First SOC */
  if (!gst_byte_reader_get_uint16_be (reader, &marker)
      || marker != MARKER_SOC) {
    GST_ERROR_OBJECT (self, "Frame does not start with SOC");
    ret = GST_FLOW_ERROR;
    goto done;
  }

  while (TRUE) {
    if (!gst_byte_reader_peek_uint16_be (reader, &marker)) {
      GST_ERROR_OBJECT (self, "Could not read marker");
      ret = GST_FLOW_ERROR;
      goto done;
    }

    /* SOT starts the tiles */
    if (marker == MARKER_SOT) {
      ret = GST_FLOW_OK;
      break;
    } else if (marker == MARKER_EOC) {
      GST_WARNING_OBJECT (self, "EOC marker before SOT");
      ret = GST_FLOW_EOS;
      goto done;
    }

    if ((marker >> 8) != 0xff) {
      GST_ERROR_OBJECT (self, "Lost synchronization (0x%04x)", marker);
      ret = GST_FLOW_ERROR;
      goto done;
    }

    /* Now skip the marker */
    gst_byte_reader_skip_unchecked (reader, 2);

    /* All markers here have a length */
    if (!gst_byte_reader_get_uint16_be (reader, &length)) {
      GST_ERROR_OBJECT (self, "Could not read marker length");
      ret = GST_FLOW_ERROR;
      goto done;
    }

    if (length < 2 || gst_byte_reader_get_remaining (reader) < length - 2) {
      GST_ERROR_OBJECT (self, "Invalid marker length %u (available %u)",
          length, gst_byte_reader_get_remaining (reader));
      ret = GST_FLOW_ERROR;
      goto done;
    }

    GST_LOG_OBJECT (self, "Marker 0x%04x at offset %u with length %u", marker,
        gst_byte_reader_get_pos (reader), length);

    switch (marker) {
      case MARKER_SIZ:

        if (header->siz.n_components != 0) {
          GST_ERROR_OBJECT (self, "Multiple SIZ marker");
          ret = GST_FLOW_ERROR;
          goto done;
        }
        ret = parse_siz (self, reader, &header->siz, length);
        if (ret != GST_FLOW_OK)
          goto done;
        break;
      case MARKER_COD:
        if (header->siz.n_components == 0) {
          GST_ERROR_OBJECT (self, "Require SIZ before COD");
          ret = GST_FLOW_ERROR;
          goto done;
        }

        if (header->cod.n_layers != 0) {
          GST_ERROR_OBJECT (self, "Multiple COD");
          ret = GST_FLOW_ERROR;
          goto done;
        }

        ret = parse_cod (self, reader, &header->cod, length);
        if (ret != GST_FLOW_OK)
          goto done;

        break;
      case MARKER_POC:
        GST_ERROR_OBJECT (self, "POC marker not supported yet");
        ret = GST_FLOW_ERROR;
        goto done;
      case MARKER_COC:
        GST_ERROR_OBJECT (self, "COC marker not supported yet");
        ret = GST_FLOW_ERROR;
        goto done;
      case MARKER_RGN:
        GST_ERROR_OBJECT (self, "RGN marker not supported yet");
        ret = GST_FLOW_ERROR;
        goto done;
      case MARKER_TLM:
        GST_ERROR_OBJECT (self, "TLM marker not supported yet");
        ret = GST_FLOW_ERROR;
        goto done;
      case MARKER_PLM:
        GST_ERROR_OBJECT (self, "PLM marker not supported yet");
        ret = GST_FLOW_ERROR;
        goto done;
      case MARKER_PPM:
        GST_ERROR_OBJECT (self, "PPM marker not supported yet");
        ret = GST_FLOW_ERROR;
        goto done;
      case MARKER_QCD:
        if (header->qcd.data != NULL) {
          GST_ERROR_OBJECT (self, "Multiple QCD markers");
          ret = GST_FLOW_ERROR;
          goto done;
        }
        header->qcd.data = gst_byte_reader_peek_data_unchecked (reader);
        header->qcd.length = length - 2;
        gst_byte_reader_skip_unchecked (reader, length - 2);
        break;
      case MARKER_QCC:{
        Buffer *p = g_slice_new (Buffer);
        p->data = gst_byte_reader_peek_data_unchecked (reader);
        p->length = length - 2;
        header->qcc = g_list_append (header->qcc, p);
        gst_byte_reader_skip_unchecked (reader, length - 2);
        break;
      }
      case MARKER_COM:{
        Buffer *p = g_slice_new (Buffer);
        p->data = gst_byte_reader_peek_data_unchecked (reader);
        p->length = length - 2;
        header->com = g_list_append (header->com, p);
        gst_byte_reader_skip_unchecked (reader, length - 2);
        break;
      }
      case MARKER_CRG:{
        Buffer *p = g_slice_new (Buffer);
        p->data = gst_byte_reader_peek_data_unchecked (reader);
        p->length = length - 2;
        header->crg = g_list_append (header->crg, p);
        gst_byte_reader_skip_unchecked (reader, length - 2);
        break;
      }
      default:
        GST_DEBUG_OBJECT (self, "Skipping unknown marker 0x%04x", marker);
        gst_byte_reader_skip_unchecked (reader, length - 2);
        break;
    }
  }

  if (header->siz.n_components == 0 || header->cod.n_layers == 0) {
    GST_ERROR_OBJECT (self, "No SIZ or COD before SOT");
    return GST_FLOW_ERROR;
  }

  header->n_tiles_x =
      (header->siz.x - header->siz.xto + header->siz.xt - 1) / header->siz.xt;
  header->n_tiles_y =
      (header->siz.y - header->siz.yto + header->siz.yt - 1) / header->siz.yt;
  header->n_tiles = header->n_tiles_x * header->n_tiles_y;

  header->tiles = g_slice_alloc0 (sizeof (Tile) * header->n_tiles);

  /* now at SOT marker, read the tiles */
  {
    gint i;

    for (i = 0; i < header->n_tiles; i++) {
      ret = parse_tile (self, reader, header, &header->tiles[i]);
      if (ret != GST_FLOW_OK)
        goto done;
    }
  }

  /* now there must be the EOC marker */
  if (!gst_byte_reader_get_uint16_be (reader, &marker)
      || marker != MARKER_EOC) {
    GST_ERROR_OBJECT (self, "Frame does not end with EOC");
    ret = GST_FLOW_ERROR;
    goto done;
  }

done:

  return ret;
}

guint
sizeof_main_header (GstJP2kDecimator * self, const MainHeader * header)
{
  guint size = 2;
  GList *l;
  gint i;

  size += sizeof_siz (self, &header->siz);
  size += sizeof_cod (self, &header->cod);
  size += 2 + 2 + header->qcd.length;

  for (l = header->qcc; l; l = l->next) {
    Buffer *b = l->data;
    size += 2 + 2 + b->length;
  }

  for (l = header->crg; l; l = l->next) {
    Buffer *b = l->data;
    size += 2 + 2 + b->length;
  }

  for (l = header->com; l; l = l->next) {
    Buffer *b = l->data;
    size += 2 + 2 + b->length;
  }

  for (i = 0; i < header->n_tiles; i++) {
    size += sizeof_tile (self, &header->tiles[i]);
  }

  /* EOC */
  size += 2;

  return size;
}

void
reset_main_header (GstJP2kDecimator * self, MainHeader * header)
{
  gint i;
  GList *l;

  if (header->tiles) {
    for (i = 0; i < header->n_tiles; i++) {
      reset_tile (self, header, &header->tiles[i]);
    }
    g_slice_free1 (sizeof (Tile) * header->n_tiles, header->tiles);
  }

  for (l = header->qcc; l; l = l->next)
    g_slice_free (Buffer, l->data);
  g_list_free (header->qcc);

  for (l = header->com; l; l = l->next)
    g_slice_free (Buffer, l->data);
  g_list_free (header->com);

  for (l = header->crg; l; l = l->next)
    g_slice_free (Buffer, l->data);
  g_list_free (header->crg);

  reset_cod (self, &header->cod);
  reset_siz (self, &header->siz);

  memset (header, 0, sizeof (MainHeader));
}

GstFlowReturn
write_main_header (GstJP2kDecimator * self, GstByteWriter * writer,
    const MainHeader * header)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GList *l;
  gint i;

  if (!gst_byte_writer_ensure_free_space (writer, 2)) {
    GST_ERROR_OBJECT (self, "Could not ensure free space");
    return GST_FLOW_ERROR;
  }

  gst_byte_writer_put_uint16_be_unchecked (writer, MARKER_SOC);

  ret = write_siz (self, writer, &header->siz);
  if (ret != GST_FLOW_OK)
    goto done;

  ret = write_cod (self, writer, &header->cod);
  if (ret != GST_FLOW_OK)
    goto done;

  ret = write_marker_buffer (self, writer, MARKER_QCD, &header->qcd);
  if (ret != GST_FLOW_OK)
    goto done;

  for (l = header->qcc; l; l = l->next) {
    Buffer *p = l->data;

    ret = write_marker_buffer (self, writer, MARKER_QCC, p);
    if (ret != GST_FLOW_OK)
      goto done;
  }

  for (l = header->crg; l; l = l->next) {
    Buffer *p = l->data;

    ret = write_marker_buffer (self, writer, MARKER_CRG, p);
    if (ret != GST_FLOW_OK)
      goto done;
  }

  for (l = header->com; l; l = l->next) {
    Buffer *p = l->data;

    ret = write_marker_buffer (self, writer, MARKER_COM, p);
    if (ret != GST_FLOW_OK)
      goto done;
  }

  for (i = 0; i < header->n_tiles; i++) {
    ret = write_tile (self, writer, header, &header->tiles[i]);
    if (ret != GST_FLOW_OK)
      goto done;
  }

  if (!gst_byte_writer_ensure_free_space (writer, 2)) {
    GST_ERROR_OBJECT (self, "Could not ensure free space");
    ret = GST_FLOW_ERROR;
    goto done;
  }
  gst_byte_writer_put_uint16_be_unchecked (writer, MARKER_EOC);

done:
  return ret;
}

GstFlowReturn
decimate_main_header (GstJP2kDecimator * self, MainHeader * header)
{
  GstFlowReturn ret = GST_FLOW_OK;
  gint i;

  for (i = 0; i < header->n_tiles; i++) {
    Tile *tile = &header->tiles[i];
    GList *l;
    PacketIterator it;
    PacketLengthTilePart *plt = NULL;

    if (tile->plt) {
      if (g_list_length (tile->plt) > 1) {
        GST_ERROR_OBJECT (self, "Multiple PLT per tile not supported yet");
        ret = GST_FLOW_ERROR;
        goto done;
      }
      plt = g_slice_new (PacketLengthTilePart);
      plt->index = 0;
      plt->packet_lengths = g_array_new (FALSE, FALSE, sizeof (guint32));
    }

    init_packet_iterator (self, &it, header, tile);

    l = tile->packets;
    while ((it.next (&it))) {
      Packet *p;

      if (l == NULL) {
        GST_ERROR_OBJECT (self, "Not enough packets");
        ret = GST_FLOW_ERROR;
        g_array_free (plt->packet_lengths, TRUE);
        g_slice_free (PacketLengthTilePart, plt);
        goto done;
      }

      p = l->data;

      if ((self->max_layers != 0 && it.cur_layer >= self->max_layers) ||
          (self->max_decomposition_levels != -1
              && it.cur_resolution > self->max_decomposition_levels)) {
        p->data = NULL;
        p->length = 1;
      }

      if (plt) {
        guint32 len = sizeof_packet (self, p);
        g_array_append_val (plt->packet_lengths, len);
      }

      l = l->next;
    }

    if (plt) {
      reset_plt (self, tile->plt->data);
      g_slice_free (PacketLengthTilePart, tile->plt->data);
      tile->plt->data = plt;
    }

    tile->sot.tile_part_size = sizeof_tile (self, tile);
  }

done:
  return ret;
}
