/* GStreamer PNM decoder
 * Copyright (C) 2009 Lutz Mueller <lutz@users.sourceforge.net>
 *
 * 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.
 */

/**
 * SECTION:element-pnmdec
 * @title: pnmdec
 *
 * Decodes pnm images.
 *
 * ## Example launch line
 * |[
 * gst-launch-1.0 filesrc location=test.pnm ! pnmdec ! videoconvert ! autovideosink
 * ]| The above pipeline reads a pnm file and renders it to the screen.
 *
 */

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

#include "gstpnmdec.h"
#include "gstpnmutils.h"

#include <gst/gstutils.h>
#include <gst/video/video.h>
#include <gst/base/gstbytereader.h>
#include <string.h>
#include <stdio.h>

static gboolean gst_pnmdec_start (GstVideoDecoder * decoder);
static GstFlowReturn gst_pnmdec_finish (GstVideoDecoder * decoder);
static gboolean gst_pnmdec_set_format (GstVideoDecoder * decoder,
    GstVideoCodecState * state);
static gboolean gst_pnmdec_stop (GstVideoDecoder * decoder);
static GstFlowReturn gst_pnmdec_parse (GstVideoDecoder * decoder,
    GstVideoCodecFrame * frame, GstAdapter * adapter, gboolean at_eos);
static GstFlowReturn gst_pnmdec_handle_frame (GstVideoDecoder * decoder,
    GstVideoCodecFrame * frame);
static GstFlowReturn
gst_pnmdec_parse_ascii (GstPnmdec * s, const guint8 * b, guint bs);

G_DEFINE_TYPE (GstPnmdec, gst_pnmdec, GST_TYPE_VIDEO_DECODER);

static GstStaticPadTemplate gst_pnmdec_src_pad_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
        ("{ RGB, GRAY8, GRAY16_BE, GRAY16_LE }")));

static GstStaticCaps gst_pnmdec_gray16_caps =
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ GRAY16_BE, GRAY16_LE }"));

static GstStaticPadTemplate gst_pnmdec_sink_pad_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (MIME_ALL));

GST_DEBUG_CATEGORY (pnmdecoder_debug);
#define GST_CAT_DEFAULT pnmdecoder_debug

static void
gst_pnmdec_class_init (GstPnmdecClass * klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstVideoDecoderClass *vdec_class = (GstVideoDecoderClass *) klass;

  GST_DEBUG_CATEGORY_INIT (pnmdecoder_debug, "pnmdec", 0, "PNM Video Decoder");

  gst_element_class_add_static_pad_template (element_class,
      &gst_pnmdec_src_pad_template);
  gst_element_class_add_static_pad_template (element_class,
      &gst_pnmdec_sink_pad_template);

  gst_element_class_set_static_metadata (element_class, "PNM image decoder",
      "Codec/Decoder/Image",
      "Decodes images in portable pixmap/graymap/bitmap/anymamp (PNM) format",
      "Lutz Mueller <lutz@users.sourceforge.net>");

  vdec_class->start = gst_pnmdec_start;
  vdec_class->finish = gst_pnmdec_finish;
  vdec_class->stop = gst_pnmdec_stop;
  vdec_class->parse = gst_pnmdec_parse;
  vdec_class->handle_frame = gst_pnmdec_handle_frame;
  vdec_class->set_format = gst_pnmdec_set_format;
}

static void
gst_pnmdec_flush (GstPnmdec * s)
{
  memset (&s->mngr, 0, sizeof (s->mngr));
  s->size = 0;
  s->current_size = 0;
  if (s->buf) {
    gst_buffer_unref (s->buf);
    s->buf = NULL;
  }
}

static void
gst_pnmdec_init (GstPnmdec * s)
{
  /* Initialize decoder */
  s->buf = NULL;
  gst_pnmdec_flush (s);

  gst_video_decoder_set_use_default_pad_acceptcaps (GST_VIDEO_DECODER_CAST
      (s), TRUE);
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_DECODER_SINK_PAD (s));
}

static GstFlowReturn
gst_pnmdec_negotiate (GstVideoDecoder * decoder)
{
  GstPnmdec *pnmdec = (GstPnmdec *) decoder;
  GstVideoFormat fmt = GST_VIDEO_FORMAT_UNKNOWN;
  GstVideoCodecState *output_state;

  switch (pnmdec->mngr.info.type) {
    case GST_PNM_TYPE_BITMAP:
      if (pnmdec->mngr.info.encoding == GST_PNM_ENCODING_ASCII) {
        return GST_FLOW_ERROR;
      }
      pnmdec->size = pnmdec->mngr.info.width * pnmdec->mngr.info.height * 1;
      fmt = GST_VIDEO_FORMAT_GRAY8;
      break;
    case GST_PNM_TYPE_GRAYMAP:
      if (pnmdec->mngr.info.max > 255) {
        GstCaps *gray16_caps = gst_static_caps_get (&gst_pnmdec_gray16_caps);
        GstCaps *peercaps;
        GstStructure *peerstruct;
        const gchar *fmtstr;

        pnmdec->size = pnmdec->mngr.info.width * pnmdec->mngr.info.height * 2;
        /* perform some basic negotiation to resolve which endianess,
         * if any, is supported by the component downstream. Query
         * the peer caps, intersecting with our preferred caps
         */
        peercaps =
            gst_pad_peer_query_caps (GST_VIDEO_DECODER_SRC_PAD (decoder),
            gray16_caps);
        gst_caps_unref (gray16_caps);

        GST_DEBUG ("Received caps from peer: %" GST_PTR_FORMAT, peercaps);
        if (gst_caps_is_empty (peercaps)) {
          gst_caps_unref (peercaps);
          return FALSE;
        }

        if (!gst_caps_is_fixed (peercaps))
          peercaps = gst_caps_fixate (peercaps);

        peerstruct = gst_caps_get_structure (peercaps, 0);
        fmtstr = gst_structure_get_string (peerstruct, "format");
        if (fmtstr) {
          if (g_str_equal (fmtstr, "GRAY16_BE")) {
            fmt = GST_VIDEO_FORMAT_GRAY16_BE;
          } else if (g_str_equal (fmtstr, "GRAY16_LE")) {
            fmt = GST_VIDEO_FORMAT_GRAY16_LE;
          }
        }
        gst_caps_unref (peercaps);
      } else {
        pnmdec->size = pnmdec->mngr.info.width * pnmdec->mngr.info.height * 1;
        fmt = GST_VIDEO_FORMAT_GRAY8;
      }
      break;
    case GST_PNM_TYPE_PIXMAP:
      pnmdec->size = pnmdec->mngr.info.width * pnmdec->mngr.info.height * 3;
      fmt = GST_VIDEO_FORMAT_RGB;
      break;
  }

  if (fmt == GST_VIDEO_FORMAT_UNKNOWN)
    return GST_FLOW_NOT_NEGOTIATED;

  pnmdec->out_format = fmt;

  output_state =
      gst_video_decoder_set_output_state (decoder, fmt,
      pnmdec->mngr.info.width, pnmdec->mngr.info.height, pnmdec->input_state);
  gst_video_codec_state_unref (output_state);

  if (gst_video_decoder_negotiate (decoder) == FALSE)
    return GST_FLOW_NOT_NEGOTIATED;

  return GST_FLOW_OK;
}

static gboolean
gst_pnmdec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
{
  GstPnmdec *pnmdec = (GstPnmdec *) decoder;

  gst_pnmdec_negotiate (decoder);

  if (pnmdec->input_state)
    gst_video_codec_state_unref (pnmdec->input_state);
  pnmdec->input_state = gst_video_codec_state_ref (state);

  return TRUE;
}

static gboolean
gst_pnmdec_stop (GstVideoDecoder * decoder)
{
  GstPnmdec *pnmdec = (GstPnmdec *) decoder;

  if (pnmdec->input_state) {
    gst_video_codec_state_unref (pnmdec->input_state);
    pnmdec->input_state = NULL;
  }

  if (pnmdec->buf) {
    gst_buffer_unref (pnmdec->buf);
    pnmdec->buf = NULL;
  }
  return TRUE;
}

static GstFlowReturn
gst_pnmdec_parse_ascii (GstPnmdec * s, const guint8 * b, guint bs)
{
  GScanner *scanner;
  guint i = 0;
  guint target, last_val = 0;
  GstMapInfo map;
  guint8 *outdata;

  target = s->size - s->current_size;

  gst_buffer_map (s->buf, &map, GST_MAP_WRITE);

  if (bs) {
    GST_MEMDUMP_OBJECT (s, "Starting parse:", b, MIN (16, bs));
  }

  /* leave the number of bytes already parsed */
  outdata = map.data + s->current_size;

  if (s->have_last_val) {
    while (bs && *b >= '0' && *b <= '9') {
      s->last_val = 10 * s->last_val + *b - '0';
      b++;
      if (!--bs) {
        goto drop_error;
      }
    }
    if (s->last_val > s->mngr.info.max) {
      GST_DEBUG_OBJECT (s, "Corrupt ASCII encoded PNM file.");
      goto drop_error;
    }

    GST_LOG_OBJECT (s, "Collected partial value from previous parse - %u",
        s->last_val);
    if (s->mngr.info.max > 255) {
      if (i + 1 >= target) {
        GST_DEBUG_OBJECT (s, "PNM file contains too much data.");
        goto drop_error;
      }
      if (s->out_format == GST_VIDEO_FORMAT_GRAY16_BE)
        GST_WRITE_UINT16_BE (outdata + i, s->last_val);
      else
        GST_WRITE_UINT16_LE (outdata + i, s->last_val);
      i += 2;
    } else {
      outdata[i++] = s->last_val;
    }
    last_val = s->last_val;
    s->have_last_val = FALSE;
  }

  /* Might be no data if we're at EOS */
  if (!bs)
    goto done;

  scanner = g_scanner_new (NULL);
  g_scanner_input_text (scanner, (gchar *) b, bs);
  while (!g_scanner_eof (scanner)) {
    switch (g_scanner_get_next_token (scanner)) {
      case G_TOKEN_INT:
        if (s->mngr.info.max > 255) {
          if (i + 1 >= target) {
            GST_DEBUG_OBJECT (s,
                "PNM file contains too much data after line %u col %u.",
                scanner->line, scanner->position);
            g_scanner_destroy (scanner);
            goto done;          // drop_error;
          }
          if (s->out_format == GST_VIDEO_FORMAT_GRAY16_BE)
            GST_WRITE_UINT16_BE (outdata + i, scanner->value.v_int);
          else
            GST_WRITE_UINT16_LE (outdata + i, scanner->value.v_int);
          i += 2;
        } else {
          if (i == target) {
            GST_DEBUG_OBJECT (s,
                "PNM file contains too much data after line %u col %u.",
                scanner->line, scanner->position);
            g_scanner_destroy (scanner);
            goto drop_error;
          }
          outdata[i++] = scanner->value.v_int;
        }
        last_val = scanner->value.v_int;
        break;
      default:
        /* Should we care? */ ;
    }
  }
  g_scanner_destroy (scanner);

  /* If we didn't get the whole image, handle the last byte with care. */
  if (i && i < target && b[bs - 1] >= '0' && b[bs - 1] <= '9') {
    s->last_val = last_val;
    s->have_last_val = TRUE;
    if (s->mngr.info.max > 255)
      i -= 2;
    else
      i--;
    GST_LOG_OBJECT (s, "Stored last value %u for next parse cycle",
        s->last_val);
  }

done:
  /* Update the number of output bytes parsed in this scan */
  s->current_size += i;
  GST_LOG_OBJECT (s, "Parsed %u bytes, now have %u bytes of %u output",
      i, s->current_size, s->size);
  gst_buffer_unmap (s->buf, &map);

  return GST_FLOW_OK;

drop_error:
  gst_buffer_unmap (s->buf, &map);

  return GST_FLOW_ERROR;
}

static GstFlowReturn
gst_pnmdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
{
  GstPnmdec *s = (GstPnmdec *) decoder;
  GstMapInfo imap, omap;
  guint i_rowstride;
  guint o_rowstride;
  GstFlowReturn r = GST_FLOW_OK;
  gint bytes, i, total_bytes = 0;

  r = gst_video_decoder_allocate_output_frame (decoder, frame);
  if (r != GST_FLOW_OK) {
    gst_video_decoder_drop_frame (GST_VIDEO_DECODER (s), frame);
    goto out;
  }

  if (s->mngr.info.encoding == GST_PNM_ENCODING_ASCII) {
    /* In case of ASCII parsed data is stored in buf, so input needs to be
       taken from here for frame processing */
    gst_buffer_map (s->buf, &imap, GST_MAP_READ);
  } else {
    gst_buffer_map (frame->input_buffer, &imap, GST_MAP_READ);
  }
  gst_buffer_map (frame->output_buffer, &omap, GST_MAP_WRITE);

  gst_buffer_copy_into (frame->output_buffer, frame->input_buffer,
      GST_BUFFER_COPY_METADATA, 0, 0);

  if (s->mngr.info.type == GST_PNM_TYPE_BITMAP) {
    bytes = (s->mngr.info.width * s->mngr.info.height + 7) / 8;
    for (i = 0; i < bytes; i++) {
      omap.data[i * 8] = (imap.data[i] & 0x80) ? 0 : 255;
      omap.data[i * 8 + 1] = (imap.data[i] & 0x40) ? 0 : 255;
      omap.data[i * 8 + 2] = (imap.data[i] & 0x20) ? 0 : 255;
      omap.data[i * 8 + 3] = (imap.data[i] & 0x10) ? 0 : 255;
      omap.data[i * 8 + 4] = (imap.data[i] & 0x08) ? 0 : 255;
      omap.data[i * 8 + 5] = (imap.data[i] & 0x04) ? 0 : 255;
      omap.data[i * 8 + 6] = (imap.data[i] & 0x02) ? 0 : 255;
      omap.data[i * 8 + 7] = (imap.data[i] & 0x01) ? 0 : 255;
    }
    total_bytes = bytes * 8;
  } else
    /* Need to convert from PNM rowstride to GStreamer rowstride */
  if (s->mngr.info.width % 4 != 0) {
    if (s->mngr.info.type == GST_PNM_TYPE_PIXMAP) {
      i_rowstride = 3 * s->mngr.info.width;
      o_rowstride = GST_ROUND_UP_4 (i_rowstride);
    } else {
      if (s->mngr.info.max > 255)
        i_rowstride = s->mngr.info.width * 2;
      else
        i_rowstride = s->mngr.info.width;
      o_rowstride = GST_ROUND_UP_4 (i_rowstride);
    }

    for (i = 0; i < s->mngr.info.height; i++)
      memcpy (omap.data + i * o_rowstride, imap.data + i * i_rowstride,
          i_rowstride);
    total_bytes = o_rowstride * s->mngr.info.height;
  } else {
    memcpy (omap.data, imap.data, s->size);
    total_bytes = s->size;
  }

  if (s->mngr.info.type != GST_PNM_TYPE_BITMAP) {
    if (s->mngr.info.max > 255 && s->mngr.info.max < 65535) {
      /* Convert the pixels from 0 - max range to 0 - 65535 range
       * and appropriate endianness (input is always BE) */
      guint8 *data = omap.data;
      gint max = s->mngr.info.max;
      if (s->out_format == GST_VIDEO_FORMAT_GRAY16_BE) {
        for (i = 0; i < total_bytes; i += 2) {
          /* Clamp to 65535 */
          guint16 val = GST_READ_UINT16_BE (data + i);
          val = (val > max) ? 65535 : 65535 * val / max;
          GST_WRITE_UINT16_BE (data + i, val);
        }
      } else {
        for (i = 0; i < total_bytes; i += 2) {
          /* Clamp to 65535 */
          guint16 val = GST_READ_UINT16_BE (data + i);
          val = (val > max) ? 65535 : 65535 * val / max;
          GST_WRITE_UINT16_LE (data + i, val);
        }
      }
    } else if (s->mngr.info.max < 255) {
      /* Convert the pixels from 0 - max range to 0 - 255 range */
      gint max = s->mngr.info.max;
      for (i = 0; i < total_bytes; i++) {
        if (omap.data[i] <= max) {
          omap.data[i] = 255 * omap.data[i] / max;
        } else {
          /* This is an error case, wherein value in the data stream is
             more than max. Clamp such values to 255 */
          omap.data[i] = 255;
        }
      }
    }
  }

  if (s->mngr.info.encoding == GST_PNM_ENCODING_ASCII) {
    gst_buffer_unmap (s->buf, &imap);
  } else {
    gst_buffer_unmap (frame->input_buffer, &imap);
  }
  gst_buffer_unmap (frame->output_buffer, &omap);

  s->current_size = 0;

  r = gst_video_decoder_finish_frame (GST_VIDEO_DECODER (s), frame);

out:
  gst_pnmdec_flush (s);

  return r;
}

static GstFlowReturn
gst_pnmdec_parse (GstVideoDecoder * decoder, GstVideoCodecFrame * frame,
    GstAdapter * adapter, gboolean at_eos)
{
  gsize size;
  GstPnmdec *s = GST_PNMDEC (decoder);
  GstFlowReturn r = GST_FLOW_OK;
  guint offset = 0;
  const guint8 *raw_data = NULL;

  GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);

  size = gst_adapter_available (adapter);
  if (size > 0)
    raw_data = gst_adapter_map (adapter, size);

  GST_LOG_OBJECT (s, "Entering parse with %" G_GSIZE_FORMAT " bytes. at_eos %d",
      size, at_eos);

  if (s->mngr.info.fields != GST_PNM_INFO_FIELDS_ALL) {
    GstPnmInfoMngrResult res;

    if (size < 8)
      goto need_more_data;

    res = gst_pnm_info_mngr_scan (&s->mngr, raw_data, size);

    switch (res) {
      case GST_PNM_INFO_MNGR_RESULT_FAILED:
        r = GST_FLOW_ERROR;
        goto out;
      case GST_PNM_INFO_MNGR_RESULT_READING:
        r = GST_FLOW_OK;
        goto out;
      case GST_PNM_INFO_MNGR_RESULT_FINISHED:

        r = gst_pnmdec_negotiate (decoder);
        if (r != GST_FLOW_OK)
          goto out;

        if (s->mngr.info.encoding == GST_PNM_ENCODING_ASCII) {
          /* It is not possible to know the size of input ascii data to parse.
             So we have to parse and know the number of pixels parsed and
             then finally decide when we have full frame */
          GST_DEBUG_OBJECT (s, "Allocating output frame of size %u", s->size);
          s->buf = gst_buffer_new_and_alloc (s->size);
        }
        offset = s->mngr.data_offset;
        gst_adapter_flush (adapter, offset);
        size = size - offset;
    }
  }

  if (s->mngr.info.encoding == GST_PNM_ENCODING_ASCII) {
    /* Parse ASCII data and populate s->current_size with the number of
       bytes actually parsed from the input data */
    GST_DEBUG_OBJECT (s, "Parsing %u bytes at offset %u", (guint) size, offset);
    r = gst_pnmdec_parse_ascii (s, raw_data + offset, size);
  } else {
    /* Bitmap Contains 8 pixels in a byte */
    if (s->mngr.info.type == GST_PNM_TYPE_BITMAP)
      s->current_size += (size * 8);
    else
      s->current_size += size;
  }

  gst_video_decoder_add_to_frame (decoder, size);
  if (s->size <= s->current_size) {
    goto have_full_frame;
  }

need_more_data:
  return GST_VIDEO_DECODER_FLOW_NEED_DATA;

have_full_frame:
  return gst_video_decoder_have_frame (decoder);

out:
  return r;
}

static gboolean
gst_pnmdec_start (GstVideoDecoder * decoder)
{
  GstPnmdec *pnmdec = (GstPnmdec *) decoder;
  gst_video_decoder_set_packetized (GST_VIDEO_DECODER (pnmdec), FALSE);
  gst_pnmdec_flush (pnmdec);
  return TRUE;
}

static GstFlowReturn
gst_pnmdec_finish (GstVideoDecoder * decoder)
{
  GstPnmdec *s = (GstPnmdec *) decoder;

  GST_LOG_OBJECT (s, "finishing");

  if (s->mngr.info.encoding == GST_PNM_ENCODING_ASCII) {
    /* One last go at outputting any final value */
    gst_pnmdec_parse_ascii (s, 0, 0);
    if (s->size <= s->current_size) {
      return gst_video_decoder_have_frame (decoder);
    }
  }

  return GST_FLOW_OK;
}
