/* GStreamer
 * Copyright (C) <2014> Collabora Ltd.
 *   Author: Matthieu Bouron <matthieu.bouron@gmail.com>
 * Copyright (C) 2015, Matthew Waters <matthew@centricular.com>
 *
 * 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.
 */

#include "gstvideoaffinetransformationmeta.h"

#include <string.h>

GType
gst_video_affine_transformation_meta_api_get_type (void)
{
  static volatile GType type = 0;
  static const gchar *tags[] =
      { GST_META_TAG_VIDEO_STR, GST_META_TAG_VIDEO_ORIENTATION_STR,
    GST_META_TAG_VIDEO_ORIENTATION_STR, NULL
  };

  if (g_once_init_enter (&type)) {
    GType _type =
        gst_meta_api_type_register ("GstVideoAffineTransformationAPI", tags);
    g_once_init_leave (&type, _type);
  }
  return type;
}

static gboolean
gst_video_affine_transformation_meta_transform (GstBuffer * dest,
    GstMeta * meta, GstBuffer * buffer, GQuark type, gpointer data)
{
  GstVideoAffineTransformationMeta *dmeta, *smeta;

  smeta = (GstVideoAffineTransformationMeta *) meta;

  if (GST_META_TRANSFORM_IS_COPY (type)) {
    dmeta =
        (GstVideoAffineTransformationMeta *) gst_buffer_add_meta (dest,
        GST_VIDEO_AFFINE_TRANSFORMATION_META_INFO, NULL);

    if (!dmeta)
      return FALSE;

    memcpy (dmeta->matrix, smeta->matrix, sizeof (dmeta->matrix[0]) * 16);
  }
  return TRUE;
}

static gboolean
gst_video_affine_transformation_meta_init (GstMeta * meta, gpointer params,
    GstBuffer * buffer)
{
  GstVideoAffineTransformationMeta *af_meta =
      (GstVideoAffineTransformationMeta *) meta;
  gfloat matrix[] = {
    1.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 1.0f, 0.0f,
    0.0f, 0.0f, 0.0f, 1.0f
  };

  memcpy (af_meta->matrix, matrix, sizeof (matrix[0]) * 16);

  return TRUE;
}

const GstMetaInfo *
gst_video_affine_transformation_meta_get_info (void)
{
  static const GstMetaInfo *info = NULL;

  if (g_once_init_enter (&info)) {
    const GstMetaInfo *meta =
        gst_meta_register (GST_VIDEO_AFFINE_TRANSFORMATION_META_API_TYPE,
        "GstVideoAffineTransformationMeta",
        sizeof (GstVideoAffineTransformationMeta),
        gst_video_affine_transformation_meta_init,
        NULL,
        gst_video_affine_transformation_meta_transform);
    g_once_init_leave (&info, meta);
  }
  return info;
}

/**
 * gst_buffer_add_video_affine_transformation_meta
 * @buffer: a #GstBuffer
 *
 * Attaches GstVideoAffineTransformationMeta metadata to @buffer with
 * the given parameters.
 *
 * Returns: the #GstVideoAffineTransformationMeta on @buffer.
 *
 * Since: 1.8
 */
GstVideoAffineTransformationMeta *
gst_buffer_add_video_affine_transformation_meta (GstBuffer * buffer)
{
  GstVideoAffineTransformationMeta *meta;

  g_return_val_if_fail (buffer != NULL, NULL);

  meta =
      (GstVideoAffineTransformationMeta *) gst_buffer_add_meta (buffer,
      GST_VIDEO_AFFINE_TRANSFORMATION_META_INFO, NULL);

  if (!meta)
    return NULL;

  return meta;
}

/**
 * gst_video_affine_transformation_meta_apply_matrix:
 * @meta: a #GstVideoAffineTransformationMeta
 * @matrix: a 4x4 transformation matrix to be applied
 *
 * Apply a transformation using the given 4x4 transformation matrix
 *
 * Since: 1.8
 */
void gst_video_affine_transformation_meta_apply_matrix
    (GstVideoAffineTransformationMeta * meta, const gfloat matrix[16])
{
  gfloat res[16] = { 0.0f };
  int i, j, k;

  for (i = 0; i < 4; i++) {
    for (j = 0; j < 4; j++) {
      for (k = 0; k < 4; k++) {
        res[i + (j * 4)] += meta->matrix[i + (k * 4)] * matrix[k + (j * 4)];
      }
    }
  }

  memcpy (meta->matrix, res, sizeof (meta->matrix[0]) * 16);
}
