/* GStreamer PNM encoder
 * 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-pnmenc
 * @title: pnmenc
 *
 * Encodes pnm images. This plugin supports both raw and ASCII encoding.
 * To enable ASCII encoding, set the parameter ascii to TRUE. If you omit
 * the parameter or set it to FALSE, the output will be raw encoded.
 *
 * ## Example launch line
 * |[
 * gst-launch-1.0 videotestsrc num_buffers=1 ! videoconvert ! "video/x-raw,format=GRAY8" ! pnmenc ascii=true ! filesink location=test.pnm
 * ]| The above pipeline writes a test pnm file (ASCII encoding).
 *
 */

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

#include "gstpnmenc.h"
#include "gstpnmutils.h"

#include <gst/gstutils.h>
#include <gst/video/video.h>
#include <gst/video/gstvideometa.h>
#include <stdio.h>

#include <string.h>

enum
{
  GST_PNMENC_PROP_0,
  GST_PNMENC_PROP_ASCII
      /* Add here. */
};



static GstStaticPadTemplate sink_pad_template =
GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
        ("{ RGB, GRAY8, GRAY16_BE, GRAY16_LE }")));


static GstStaticPadTemplate src_pad_template =
GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
    GST_STATIC_CAPS (MIME_ALL));

G_DEFINE_TYPE (GstPnmenc, gst_pnmenc, GST_TYPE_VIDEO_ENCODER);
#define parent_class gst_pnmenc_parent_class

static GstFlowReturn
gst_pnmenc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame);

static void gst_pnmenc_finalize (GObject * object);

static void
gst_pnmenc_set_property (GObject * object, guint prop_id, const GValue * value,
    GParamSpec * pspec)
{
  GstPnmenc *s = GST_PNMENC (object);

  switch (prop_id) {
    case GST_PNMENC_PROP_ASCII:
      if (g_value_get_boolean (value)) {
        s->info.encoding = GST_PNM_ENCODING_ASCII;
      } else {
        s->info.encoding = GST_PNM_ENCODING_RAW;
      }
      s->info.fields |= GST_PNM_INFO_FIELDS_ENCODING;
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_pnmenc_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstPnmenc *s = GST_PNMENC (object);

  switch (prop_id) {
    case GST_PNMENC_PROP_ASCII:
      g_value_set_boolean (value, s->info.encoding == GST_PNM_ENCODING_ASCII);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_pnmenc_init (GstPnmenc * s)
{
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_ENCODER_SINK_PAD (s));

  /* Set default encoding as RAW as ASCII takes up 4 time more bytes */
  s->info.encoding = GST_PNM_ENCODING_RAW;
}

static void
gst_pnmenc_finalize (GObject * object)
{
  GstPnmenc *pnmenc = GST_PNMENC (object);
  if (pnmenc->input_state)
    gst_video_codec_state_unref (pnmenc->input_state);

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

static gboolean
gst_pnmenc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
{
  GstPnmenc *pnmenc;
  gboolean ret = TRUE;
  GstVideoInfo *info;
  GstVideoCodecState *output_state;
  const gchar *mime_type = NULL;

  pnmenc = GST_PNMENC (encoder);
  info = &state->info;

  switch (GST_VIDEO_INFO_FORMAT (info)) {
    case GST_VIDEO_FORMAT_RGB:
      pnmenc->info.max = 255;
      pnmenc->info.type = GST_PNM_TYPE_PIXMAP;
      mime_type = MIME_PM;
      break;
    case GST_VIDEO_FORMAT_GRAY8:
      pnmenc->info.max = 255;
      pnmenc->info.type = GST_PNM_TYPE_GRAYMAP;
      mime_type = MIME_GM;
      break;
    case GST_VIDEO_FORMAT_GRAY16_BE:
    case GST_VIDEO_FORMAT_GRAY16_LE:
      pnmenc->info.max = 65535;
      pnmenc->info.type = GST_PNM_TYPE_GRAYMAP;
      mime_type = MIME_GM;
      break;
    default:
      ret = FALSE;
      goto done;
  }

  pnmenc->info.width = GST_VIDEO_INFO_WIDTH (info);
  pnmenc->info.height = GST_VIDEO_INFO_HEIGHT (info);

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

  output_state =
      gst_video_encoder_set_output_state (encoder,
      gst_caps_new_empty_simple (mime_type), state);
  gst_video_codec_state_unref (output_state);

done:
  return ret;
}

static GstFlowReturn
gst_pnmenc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
{
  GstPnmenc *pnmenc;
  guint size, pixels, bytesize;
  GstMapInfo omap, imap;
  gchar *header = NULL;
  GstVideoInfo *info;
  GstFlowReturn ret = GST_FLOW_OK;
  guint i_rowstride, o_rowstride;
  guint bytes = 0, index, head_size;
  guint i, j;
  guint maxbytes_per_pixel, str_len;
  gchar format_str[4];
  pnmenc = GST_PNMENC (encoder);
  info = &pnmenc->input_state->info;

  switch (GST_VIDEO_INFO_FORMAT (info)) {
    case GST_VIDEO_FORMAT_RGB:
      pixels = size = pnmenc->info.width * pnmenc->info.height * 3;
      bytesize = 1;
      maxbytes_per_pixel = 4;
      str_len = 3;
      g_strlcpy (format_str, "%3i", 4);
      break;
    case GST_VIDEO_FORMAT_GRAY8:
      pixels = size = pnmenc->info.width * pnmenc->info.height * 1;
      bytesize = 1;
      maxbytes_per_pixel = 4;
      str_len = 3;
      g_strlcpy (format_str, "%3i", 4);
      break;
    case GST_VIDEO_FORMAT_GRAY16_LE:
    case GST_VIDEO_FORMAT_GRAY16_BE:
      pixels = pnmenc->info.width * pnmenc->info.height * 1;
      bytesize = 2;
      size = pixels * bytesize;
      maxbytes_per_pixel = 6;
      str_len = 5;
      g_strlcpy (format_str, "%5i", 4);
      break;
    default:
      ret = FALSE;
      goto done;
  }

  header = g_strdup_printf ("P%i\n%i %i\n%i\n",
      pnmenc->info.type + 3 * (1 - pnmenc->info.encoding), pnmenc->info.width,
      pnmenc->info.height, pnmenc->info.max);

  if (pnmenc->info.encoding == GST_PNM_ENCODING_ASCII) {
    /* Per component 4 bytes are used in case of ASCII encoding */
    size = size * 4 + size / 20;
    size += strlen (header);
    frame->output_buffer =
        gst_video_encoder_allocate_output_buffer (encoder, (size));
  } else {
    size += strlen (header);
    frame->output_buffer =
        gst_video_encoder_allocate_output_buffer (encoder, size);
  }

  if (gst_buffer_map (frame->output_buffer, &omap, GST_MAP_WRITE) == FALSE) {
    ret = GST_FLOW_ERROR;
    goto done;
  }
  if (gst_buffer_map (frame->input_buffer, &imap, GST_MAP_READ) == FALSE) {
    /* Unmap already mapped buffer */
    gst_buffer_unmap (frame->output_buffer, &omap);
    ret = GST_FLOW_ERROR;
    goto done;
  }
  /* Copy out the header first */
  head_size = strlen (header);
  memcpy (omap.data, header, head_size);

  if (pnmenc->info.encoding == GST_PNM_ENCODING_ASCII) {
    /* We need to convert to ASCII */
    /* Convert from gstreamer rowstride to PNM rowstride as we go */
    if (pnmenc->info.type == GST_PNM_TYPE_PIXMAP) {
      o_rowstride = 3 * pnmenc->info.width;
    } else {
      o_rowstride = pnmenc->info.width;
    }
    i_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (pnmenc->input_state, 0);

    switch (GST_VIDEO_INFO_FORMAT (info)) {
      case GST_VIDEO_FORMAT_RGB:
      case GST_VIDEO_FORMAT_GRAY8:
        for (i = 0; i < pnmenc->info.height; i++) {
          index = i * i_rowstride;
          for (j = 0; j < o_rowstride; j++, bytes++, index++) {
            g_snprintf ((char *) omap.data + head_size, maxbytes_per_pixel,
                format_str, imap.data[index]);
            head_size += str_len;
            omap.data[head_size++] = ' ';
            /* Add new line so that file will not end up with single big line */
            if (!((bytes + 1) % 20))
              omap.data[head_size++] = '\n';
          }
        }
        break;
      case GST_VIDEO_FORMAT_GRAY16_BE:
        for (i = 0; i < pnmenc->info.height; i++) {
          index = i * i_rowstride;
          for (j = 0; j < o_rowstride; j++, bytes++, index += 2) {
            g_snprintf ((char *) omap.data + head_size, maxbytes_per_pixel,
                format_str, GST_READ_UINT16_BE (imap.data + index));
            head_size += str_len;
            omap.data[head_size++] = ' ';
            /* Add new line so that file will not end up with single big line */
            if (!((bytes + 1) % 20))
              omap.data[head_size++] = '\n';
          }
        }
        break;
      case GST_VIDEO_FORMAT_GRAY16_LE:
        for (i = 0; i < pnmenc->info.height; i++) {
          index = i * i_rowstride;
          for (j = 0; j < o_rowstride; j++, bytes++, index += 2) {
            g_snprintf ((char *) omap.data + head_size, maxbytes_per_pixel,
                format_str, GST_READ_UINT16_LE (imap.data + index));
            head_size += str_len;
            omap.data[head_size++] = ' ';
            /* Add new line so that file will not end up with single big line */
            if (!((bytes + 1) % 20))
              omap.data[head_size++] = '\n';
          }
        }
        break;
      default:
        GST_ERROR_OBJECT (encoder, "Unhandled format %s",
            gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (info)));
        gst_buffer_unmap (frame->output_buffer, &omap);
        gst_buffer_unmap (frame->input_buffer, &imap);
        g_free (header);
        return GST_FLOW_ERROR;
    }

    gst_buffer_set_size (frame->output_buffer, head_size);
  } else {
    guint out_index = head_size;

    /* Binary output. 8-bit, or 16-bit BE */
    if (pnmenc->info.type == GST_PNM_TYPE_PIXMAP) {
      o_rowstride = 3 * pnmenc->info.width * bytesize;
    } else {
      o_rowstride = pnmenc->info.width * bytesize;
    }
    i_rowstride = GST_VIDEO_FRAME_COMP_STRIDE (pnmenc->input_state, 0);

    switch (GST_VIDEO_INFO_FORMAT (info)) {
      case GST_VIDEO_FORMAT_GRAY16_BE:
        for (i = 0; i < pnmenc->info.height; i++) {
          index = i * i_rowstride;
          for (j = 0; j < o_rowstride; j += 2, index += 2) {
            guint16 val = GST_READ_UINT16_LE (imap.data + index);
            GST_WRITE_UINT16_BE (omap.data + out_index, val);
            out_index += 2;
          }
        }
        break;
      case GST_VIDEO_FORMAT_GRAY16_LE:
        for (i = 0; i < pnmenc->info.height; i++) {
          index = i * i_rowstride;
          for (j = 0; j < o_rowstride; j += 2, index += 2) {
            guint16 val = GST_READ_UINT16_LE (imap.data + index);
            GST_WRITE_UINT16_BE (omap.data + out_index, val);
            out_index += 2;
          }
        }
        break;
      default:
        for (i = 0; i < pnmenc->info.height; i++) {
          memcpy (omap.data + head_size + o_rowstride * i,
              imap.data + i_rowstride * i, o_rowstride);
        }
    }
  }

  gst_buffer_unmap (frame->output_buffer, &omap);
  gst_buffer_unmap (frame->input_buffer, &imap);

  if ((ret = gst_video_encoder_finish_frame (encoder, frame)) != GST_FLOW_OK)
    goto done;

done:
  g_free (header);
  return ret;
}

static void
gst_pnmenc_class_init (GstPnmencClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstVideoEncoderClass *venc_class = (GstVideoEncoderClass *) klass;

  parent_class = g_type_class_peek_parent (klass);
  gobject_class->set_property = gst_pnmenc_set_property;
  gobject_class->get_property = gst_pnmenc_get_property;

  g_object_class_install_property (gobject_class, GST_PNMENC_PROP_ASCII,
      g_param_spec_boolean ("ascii", "ASCII Encoding", "The output will be "
          "ASCII encoded", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_add_static_pad_template (element_class, &sink_pad_template);
  gst_element_class_add_static_pad_template (element_class, &src_pad_template);

  gst_element_class_set_static_metadata (element_class, "PNM image encoder",
      "Codec/Encoder/Image",
      "Encodes images into portable pixmap or graymap (PNM) format",
      "Lutz Mueller <lutz@users.sourceforge.net>");

  venc_class->set_format = gst_pnmenc_set_format;
  venc_class->handle_frame = gst_pnmenc_handle_frame;
  gobject_class->finalize = gst_pnmenc_finalize;
}
