/*
 * GStreamer
 * 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.
 */

/**
 * SECTION:gstglformat
 * @title: GstGLFormat
 * @short_description: utilities for dealing with OpenGL formats
 * @see_also: #GstGLBaseMemory, #GstGLMemory, #GstGLFramebuffer, #GstGLBuffer
 *
 * Some useful utilities for converting between various formats and OpenGL
 * formats.
 */

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

#include "gstglformat.h"

#include "gstglcontext.h"
#include "gstglfuncs.h"

#define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
#define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
#define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
#define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))

#ifndef GL_TEXTURE_RECTANGLE
#define GL_TEXTURE_RECTANGLE 0x84F5
#endif
#ifndef GL_TEXTURE_EXTERNAL_OES
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
#endif

static inline guint
_gl_format_n_components (guint format)
{
  switch (format) {
    case GST_VIDEO_GL_TEXTURE_TYPE_RGBA:
    case GST_GL_RGBA:
      return 4;
    case GST_VIDEO_GL_TEXTURE_TYPE_RGB:
    case GST_VIDEO_GL_TEXTURE_TYPE_RGB16:
    case GST_GL_RGB:
    case GST_GL_RGB565:
      return 3;
    case GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA:
    case GST_VIDEO_GL_TEXTURE_TYPE_RG:
    case GST_GL_LUMINANCE_ALPHA:
    case GST_GL_RG:
      return 2;
    case GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE:
    case GST_VIDEO_GL_TEXTURE_TYPE_R:
    case GST_GL_LUMINANCE:
    case GST_GL_RED:
      return 1;
    default:
      return 0;
  }
}

static inline guint
_gl_type_n_components (guint type)
{
  switch (type) {
    case GL_UNSIGNED_BYTE:
      return 1;
    case GL_UNSIGNED_SHORT_5_6_5:
      return 3;
    default:
      g_assert_not_reached ();
      return 0;
  }
}

static inline guint
_gl_type_n_bytes (guint type)
{
  switch (type) {
    case GL_UNSIGNED_BYTE:
      return 1;
    case GL_UNSIGNED_SHORT_5_6_5:
      return 2;
    default:
      g_assert_not_reached ();
      return 0;
  }
}

/**
 * gst_gl_format_type_n_bytes:
 * @format: the OpenGL format, %GL_RGBA, %GL_LUMINANCE, etc
 * @type: the OpenGL type, %GL_UNSIGNED_BYTE, %GL_FLOAT, etc
 *
 * Returns: the number of bytes the specified @format, @type combination takes
 * per pixel
 */
guint
gst_gl_format_type_n_bytes (guint format, guint type)
{
  return _gl_format_n_components (format) / _gl_type_n_components (type) *
      _gl_type_n_bytes (type);
}

/**
 * gst_gl_format_from_video_info:
 * @context: a #GstGLContext
 * @vinfo: a #GstVideoInfo
 * @plane: the plane number in @vinfo
 *
 * Returns: the #GstGLFormat necessary for holding the data in @plane of @vinfo
 */
GstGLFormat
gst_gl_format_from_video_info (GstGLContext * context, GstVideoInfo * vinfo,
    guint plane)
{
  gboolean texture_rg =
      gst_gl_context_check_feature (context, "GL_EXT_texture_rg")
      || gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0)
      || gst_gl_context_check_feature (context, "GL_ARB_texture_rg")
      || gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 0);
  GstVideoFormat v_format = GST_VIDEO_INFO_FORMAT (vinfo);
  guint n_plane_components;

  switch (v_format) {
    case GST_VIDEO_FORMAT_RGBx:
    case GST_VIDEO_FORMAT_BGRx:
    case GST_VIDEO_FORMAT_xRGB:
    case GST_VIDEO_FORMAT_xBGR:
    case GST_VIDEO_FORMAT_RGBA:
    case GST_VIDEO_FORMAT_BGRA:
    case GST_VIDEO_FORMAT_ARGB:
    case GST_VIDEO_FORMAT_ABGR:
    case GST_VIDEO_FORMAT_AYUV:
      n_plane_components = 4;
      break;
    case GST_VIDEO_FORMAT_RGB:
    case GST_VIDEO_FORMAT_BGR:
      n_plane_components = 3;
      break;
    case GST_VIDEO_FORMAT_RGB16:
    case GST_VIDEO_FORMAT_BGR16:
      return GST_GL_RGB565;
    case GST_VIDEO_FORMAT_GRAY16_BE:
    case GST_VIDEO_FORMAT_GRAY16_LE:
    case GST_VIDEO_FORMAT_YUY2:
    case GST_VIDEO_FORMAT_UYVY:
      n_plane_components = 2;
      break;
    case GST_VIDEO_FORMAT_NV12:
    case GST_VIDEO_FORMAT_NV21:
      n_plane_components = plane == 0 ? 1 : 2;
      break;
    case GST_VIDEO_FORMAT_GRAY8:
    case GST_VIDEO_FORMAT_Y444:
    case GST_VIDEO_FORMAT_Y42B:
    case GST_VIDEO_FORMAT_Y41B:
    case GST_VIDEO_FORMAT_I420:
    case GST_VIDEO_FORMAT_YV12:
      n_plane_components = 1;
      break;
    default:
      n_plane_components = 4;
      g_assert_not_reached ();
      break;
  }

  switch (n_plane_components) {
    case 4:
      return GST_GL_RGBA;
      break;
    case 3:
      return GST_GL_RGB;
      break;
    case 2:
      return texture_rg ? GST_GL_RG : GST_GL_LUMINANCE_ALPHA;
      break;
    case 1:
      return texture_rg ? GST_GL_RED : GST_GL_LUMINANCE;
      break;
    default:
      g_assert_not_reached ();
      break;
  }

  return GST_GL_RGBA;
}

/**
 * gst_gl_sized_gl_format_from_gl_format_type:
 * @context: a #GstGLContext
 * @format: an OpenGL format, %GL_RGBA, %GL_LUMINANCE, etc
 * @type: an OpenGL type, %GL_UNSIGNED_BYTE, %GL_FLOAT, etc
 *
 * Returns: the sized internal format specified by @format and @type that can
 *          be used in @context
 */
guint
gst_gl_sized_gl_format_from_gl_format_type (GstGLContext * context,
    guint format, guint type)
{
  gboolean ext_texture_rg =
      gst_gl_context_check_feature (context, "GL_EXT_texture_rg");

  switch (format) {
    case GST_GL_RGBA:
      switch (type) {
        case GL_UNSIGNED_BYTE:
          return USING_GLES2 (context)
              && !USING_GLES3 (context) ? GST_GL_RGBA : GST_GL_RGBA8;
          break;
      }
      break;
    case GST_GL_RGB:
      switch (type) {
        case GL_UNSIGNED_BYTE:
          return USING_GLES2 (context)
              && !USING_GLES3 (context) ? GST_GL_RGB : GST_GL_RGB8;
          break;
        case GL_UNSIGNED_SHORT_5_6_5:
          return GST_GL_RGB565;
          break;
      }
      break;
    case GST_GL_RG:
      switch (type) {
        case GL_UNSIGNED_BYTE:
          if (!USING_GLES3 (context) && USING_GLES2 (context) && ext_texture_rg)
            return GST_GL_RG;
          return GST_GL_RG8;
          break;
      }
      break;
    case GST_GL_RED:
      switch (type) {
        case GL_UNSIGNED_BYTE:
          if (!USING_GLES3 (context) && USING_GLES2 (context) && ext_texture_rg)
            return GST_GL_RED;
          return GST_GL_R8;
          break;
      }
      break;
    case GST_GL_RGBA8:
    case GST_GL_RGB8:
    case GST_GL_RGB565:
    case GST_GL_RG8:
    case GST_GL_R8:
    case GST_GL_LUMINANCE:
    case GST_GL_LUMINANCE_ALPHA:
    case GST_GL_ALPHA:
    case GST_GL_DEPTH_COMPONENT16:
    case GST_GL_DEPTH24_STENCIL8:
      return format;
    default:
      break;
  }

  g_assert_not_reached ();
  return 0;
}

/**
 * gst_gl_texture_target_to_string:
 * @target: a #GstGLTextureTarget
 *
 * Returns: the stringified version of @target or %NULL
 */
const gchar *
gst_gl_texture_target_to_string (GstGLTextureTarget target)
{
  switch (target) {
    case GST_GL_TEXTURE_TARGET_2D:
      return GST_GL_TEXTURE_TARGET_2D_STR;
    case GST_GL_TEXTURE_TARGET_RECTANGLE:
      return GST_GL_TEXTURE_TARGET_RECTANGLE_STR;
    case GST_GL_TEXTURE_TARGET_EXTERNAL_OES:
      return GST_GL_TEXTURE_TARGET_EXTERNAL_OES_STR;
    default:
      return NULL;
  }
}

/**
 * gst_gl_texture_target_from_string:
 * @str: a string equivalant to one of the GST_GL_TEXTURE_TARGET_*_STR values
 *
 * Returns: the #GstGLTextureTarget represented by @str or
 *          %GST_GL_TEXTURE_TARGET_NONE
 */
GstGLTextureTarget
gst_gl_texture_target_from_string (const gchar * str)
{
  if (!str)
    return GST_GL_TEXTURE_TARGET_NONE;

  if (g_strcmp0 (str, GST_GL_TEXTURE_TARGET_2D_STR) == 0)
    return GST_GL_TEXTURE_TARGET_2D;
  if (g_strcmp0 (str, GST_GL_TEXTURE_TARGET_RECTANGLE_STR) == 0)
    return GST_GL_TEXTURE_TARGET_RECTANGLE;
  if (g_strcmp0 (str, GST_GL_TEXTURE_TARGET_EXTERNAL_OES_STR) == 0)
    return GST_GL_TEXTURE_TARGET_EXTERNAL_OES;

  return GST_GL_TEXTURE_TARGET_NONE;
}

/**
 * gst_gl_texture_target_to_gl:
 * @target: a #GstGLTextureTarget
 *
 * Returns: the OpenGL value for binding the @target with glBindTexture() and
 *          similar functions or 0
 */
guint
gst_gl_texture_target_to_gl (GstGLTextureTarget target)
{
  switch (target) {
    case GST_GL_TEXTURE_TARGET_2D:
      return GL_TEXTURE_2D;
    case GST_GL_TEXTURE_TARGET_RECTANGLE:
      return GL_TEXTURE_RECTANGLE;
    case GST_GL_TEXTURE_TARGET_EXTERNAL_OES:
      return GL_TEXTURE_EXTERNAL_OES;
    default:
      return 0;
  }
}

/**
 * gst_gl_texture_target_from_gl:
 * @target: an OpenGL texture binding target
 *
 * Returns: the #GstGLTextureTarget that's equiavalant to @target or
 *          %GST_GL_TEXTURE_TARGET_NONE
 */
GstGLTextureTarget
gst_gl_texture_target_from_gl (guint target)
{
  switch (target) {
    case GL_TEXTURE_2D:
      return GST_GL_TEXTURE_TARGET_2D;
    case GL_TEXTURE_RECTANGLE:
      return GST_GL_TEXTURE_TARGET_RECTANGLE;
    case GL_TEXTURE_EXTERNAL_OES:
      return GST_GL_TEXTURE_TARGET_EXTERNAL_OES;
    default:
      return GST_GL_TEXTURE_TARGET_NONE;
  }
}

/**
 * gst_gl_texture_target_to_buffer_pool_option:
 * @target: a #GstGLTextureTarget
 *
 * Returns: a string representing the @GstBufferPoolOption specified by @target
 */
const gchar *
gst_gl_texture_target_to_buffer_pool_option (GstGLTextureTarget target)
{
  switch (target) {
    case GST_GL_TEXTURE_TARGET_2D:
      return GST_BUFFER_POOL_OPTION_GL_TEXTURE_TARGET_2D;
    case GST_GL_TEXTURE_TARGET_RECTANGLE:
      return GST_BUFFER_POOL_OPTION_GL_TEXTURE_TARGET_RECTANGLE;
    case GST_GL_TEXTURE_TARGET_EXTERNAL_OES:
      return GST_BUFFER_POOL_OPTION_GL_TEXTURE_TARGET_EXTERNAL_OES;
    default:
      return NULL;
  }
}
