/*
 * GStreamer
 * Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@gmail.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:element-gloverlay
 * @title: gloverlay
 *
 * Overlay GL video texture with a PNG image
 *
 * ## Examples
 * |[
 * gst-launch-1.0 videotestsrc ! gloverlay location=image.jpg ! glimagesink
 * ]|
 * FBO (Frame Buffer Object) is required.
 *
 */

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

#include <gst/base/gsttypefindhelper.h>
#include <gst/gl/gstglconfig.h>

#include "gstgloverlay.h"
#include "effects/gstgleffectssources.h"
#include "gstglutils.h"

#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER
#define HAVE_BOOLEAN
#endif
#include <jpeglib.h>
#include <png.h>

#if PNG_LIBPNG_VER >= 10400
#define int_p_NULL         NULL
#define png_infopp_NULL    NULL
#endif

#define GST_CAT_DEFAULT gst_gl_overlay_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

#define DEBUG_INIT \
  GST_DEBUG_CATEGORY_INIT (gst_gl_overlay_debug, "gloverlay", 0, "gloverlay element");

#define gst_gl_overlay_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLOverlay, gst_gl_overlay, GST_TYPE_GL_FILTER,
    DEBUG_INIT);

static gboolean gst_gl_overlay_set_caps (GstGLFilter * filter,
    GstCaps * incaps, GstCaps * outcaps);

static void gst_gl_overlay_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_gl_overlay_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static void gst_gl_overlay_before_transform (GstBaseTransform * trans,
    GstBuffer * outbuf);
static gboolean gst_gl_overlay_filter_texture (GstGLFilter * filter,
    GstGLMemory * in_tex, GstGLMemory * out_tex);

static gboolean gst_gl_overlay_load_png (GstGLOverlay * overlay, FILE * fp);
static gboolean gst_gl_overlay_load_jpeg (GstGLOverlay * overlay, FILE * fp);

enum
{
  PROP_0,
  PROP_LOCATION,
  PROP_OFFSET_X,
  PROP_OFFSET_Y,
  PROP_RELATIVE_X,
  PROP_RELATIVE_Y,
  PROP_OVERLAY_WIDTH,
  PROP_OVERLAY_HEIGHT,
  PROP_ALPHA
};

/* *INDENT-OFF* */
/* vertex source */
static const gchar *overlay_v_src =
    "attribute vec4 a_position;\n"
    "attribute vec2 a_texcoord;\n"
    "varying vec2 v_texcoord;\n"
    "void main()\n"
    "{\n"
    "   gl_Position = a_position;\n"
    "   v_texcoord = a_texcoord;\n"
    "}";

/* fragment source */
static const gchar *overlay_f_src =
    "#ifdef GL_ES\n"
    "precision mediump float;\n"
    "#endif\n"
    "uniform sampler2D texture;\n"
    "uniform float alpha;\n"
    "varying vec2 v_texcoord;\n"
    "void main()\n"
    "{\n"
    "  vec4 rgba = texture2D( texture, v_texcoord );\n"
    "  gl_FragColor = vec4(rgba.rgb, rgba.a * alpha);\n"
    "}\n";
/* *INDENT-ON* */

/* init resources that need a gl context */
static gboolean
gst_gl_overlay_gl_start (GstGLBaseFilter * base_filter)
{
  GstGLOverlay *overlay = GST_GL_OVERLAY (base_filter);

  if (!GST_GL_BASE_FILTER_CLASS (parent_class)->gl_start (base_filter))
    return FALSE;

  return gst_gl_context_gen_shader (base_filter->context, overlay_v_src,
      overlay_f_src, &overlay->shader);
}

/* free resources that need a gl context */
static void
gst_gl_overlay_gl_stop (GstGLBaseFilter * base_filter)
{
  GstGLOverlay *overlay = GST_GL_OVERLAY (base_filter);
  const GstGLFuncs *gl = base_filter->context->gl_vtable;

  if (overlay->shader) {
    gst_object_unref (overlay->shader);
    overlay->shader = NULL;
  }

  if (overlay->image_memory) {
    gst_memory_unref ((GstMemory *) overlay->image_memory);
    overlay->image_memory = NULL;
  }

  if (overlay->vao) {
    gl->DeleteVertexArrays (1, &overlay->vao);
    overlay->vao = 0;
  }

  if (overlay->vbo) {
    gl->DeleteBuffers (1, &overlay->vbo);
    overlay->vbo = 0;
  }

  if (overlay->vbo_indices) {
    gl->DeleteBuffers (1, &overlay->vbo_indices);
    overlay->vbo_indices = 0;
  }

  if (overlay->overlay_vao) {
    gl->DeleteVertexArrays (1, &overlay->overlay_vao);
    overlay->overlay_vao = 0;
  }

  if (overlay->overlay_vbo) {
    gl->DeleteBuffers (1, &overlay->overlay_vbo);
    overlay->overlay_vbo = 0;
  }

  GST_GL_BASE_FILTER_CLASS (parent_class)->gl_stop (base_filter);
}

static void
gst_gl_overlay_class_init (GstGLOverlayClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;

  gobject_class = (GObjectClass *) klass;
  element_class = GST_ELEMENT_CLASS (klass);

  gobject_class->set_property = gst_gl_overlay_set_property;
  gobject_class->get_property = gst_gl_overlay_get_property;

  GST_GL_BASE_FILTER_CLASS (klass)->gl_start = gst_gl_overlay_gl_start;
  GST_GL_BASE_FILTER_CLASS (klass)->gl_stop = gst_gl_overlay_gl_stop;

  GST_GL_FILTER_CLASS (klass)->set_caps = gst_gl_overlay_set_caps;
  GST_GL_FILTER_CLASS (klass)->filter_texture = gst_gl_overlay_filter_texture;

  GST_BASE_TRANSFORM_CLASS (klass)->before_transform =
      GST_DEBUG_FUNCPTR (gst_gl_overlay_before_transform);

  g_object_class_install_property (gobject_class, PROP_LOCATION,
      g_param_spec_string ("location", "location",
          "Location of image file to overlay", NULL, GST_PARAM_CONTROLLABLE
          | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
          | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_OFFSET_X,
      g_param_spec_int ("offset-x", "X Offset",
          "For positive value, horizontal offset of overlay image in pixels from"
          " left of video image. For negative value, horizontal offset of overlay"
          " image in pixels from right of video image", G_MININT, G_MAXINT, 0,
          GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
          | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_OFFSET_Y,
      g_param_spec_int ("offset-y", "Y Offset",
          "For positive value, vertical offset of overlay image in pixels from"
          " top of video image. For negative value, vertical offset of overlay"
          " image in pixels from bottom of video image", G_MININT, G_MAXINT, 0,
          GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
          | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_RELATIVE_X,
      g_param_spec_double ("relative-x", "Relative X Offset",
          "Horizontal offset of overlay image in fractions of video image "
          "width, from top-left corner of video image", 0.0, 1.0, 0.0,
          GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
          | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_RELATIVE_Y,
      g_param_spec_double ("relative-y", "Relative Y Offset",
          "Vertical offset of overlay image in fractions of video image "
          "height, from top-left corner of video image", 0.0, 1.0, 0.0,
          GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
          | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_OVERLAY_WIDTH,
      g_param_spec_int ("overlay-width", "Overlay Width",
          "Width of overlay image in pixels (0 = same as overlay image)", 0,
          G_MAXINT, 0,
          GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
          | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_OVERLAY_HEIGHT,
      g_param_spec_int ("overlay-height", "Overlay Height",
          "Height of overlay image in pixels (0 = same as overlay image)", 0,
          G_MAXINT, 0,
          GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
          | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_ALPHA,
      g_param_spec_double ("alpha", "Alpha", "Global alpha of overlay image",
          0.0, 1.0, 1.0, GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING
          | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_set_metadata (element_class,
      "Gstreamer OpenGL Overlay", "Filter/Effect/Video",
      "Overlay GL video texture with a JPEG/PNG image",
      "Filippo Argiolas <filippo.argiolas@gmail.com>, "
      "Matthew Waters <matthew@centricular.com>");

  GST_GL_BASE_FILTER_CLASS (klass)->supported_gl_api =
      GST_GL_API_OPENGL | GST_GL_API_GLES2 | GST_GL_API_OPENGL3;
}

static void
gst_gl_overlay_init (GstGLOverlay * overlay)
{
  overlay->offset_x = 0;
  overlay->offset_y = 0;

  overlay->relative_x = 0.0;
  overlay->relative_y = 0.0;

  overlay->overlay_width = 0;
  overlay->overlay_height = 0;

  overlay->alpha = 1.0;
}

static void
gst_gl_overlay_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstGLOverlay *overlay = GST_GL_OVERLAY (object);

  switch (prop_id) {
    case PROP_LOCATION:
      g_free (overlay->location);
      overlay->location_has_changed = TRUE;
      overlay->location = g_value_dup_string (value);
      break;
    case PROP_OFFSET_X:
      overlay->offset_x = g_value_get_int (value);
      overlay->geometry_change = TRUE;
      break;
    case PROP_OFFSET_Y:
      overlay->offset_y = g_value_get_int (value);
      overlay->geometry_change = TRUE;
      break;
    case PROP_RELATIVE_X:
      overlay->relative_x = g_value_get_double (value);
      overlay->geometry_change = TRUE;
      break;
    case PROP_RELATIVE_Y:
      overlay->relative_y = g_value_get_double (value);
      overlay->geometry_change = TRUE;
      break;
    case PROP_OVERLAY_WIDTH:
      overlay->overlay_width = g_value_get_int (value);
      overlay->geometry_change = TRUE;
      break;
    case PROP_OVERLAY_HEIGHT:
      overlay->overlay_height = g_value_get_int (value);
      overlay->geometry_change = TRUE;
      break;
    case PROP_ALPHA:
      overlay->alpha = g_value_get_double (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_gl_overlay_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstGLOverlay *overlay = GST_GL_OVERLAY (object);

  switch (prop_id) {
    case PROP_LOCATION:
      g_value_set_string (value, overlay->location);
      break;
    case PROP_OFFSET_X:
      g_value_set_int (value, overlay->offset_x);
      break;
    case PROP_OFFSET_Y:
      g_value_set_int (value, overlay->offset_y);
      break;
    case PROP_RELATIVE_X:
      g_value_set_double (value, overlay->relative_x);
      break;
    case PROP_RELATIVE_Y:
      g_value_set_double (value, overlay->relative_y);
      break;
    case PROP_OVERLAY_WIDTH:
      g_value_set_int (value, overlay->overlay_width);
      break;
    case PROP_OVERLAY_HEIGHT:
      g_value_set_int (value, overlay->overlay_height);
      break;
    case PROP_ALPHA:
      g_value_set_double (value, overlay->alpha);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_gl_overlay_set_caps (GstGLFilter * filter, GstCaps * incaps,
    GstCaps * outcaps)
{
  GstGLOverlay *overlay = GST_GL_OVERLAY (filter);
  GstStructure *s = gst_caps_get_structure (incaps, 0);
  gint width = 0;
  gint height = 0;

  gst_structure_get_int (s, "width", &width);
  gst_structure_get_int (s, "height", &height);

  overlay->window_width = width;
  overlay->window_height = height;

  return TRUE;
}

static void
_unbind_buffer (GstGLOverlay * overlay)
{
  GstGLFilter *filter = GST_GL_FILTER (overlay);
  const GstGLFuncs *gl = GST_GL_BASE_FILTER (overlay)->context->gl_vtable;

  gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
  gl->BindBuffer (GL_ARRAY_BUFFER, 0);

  gl->DisableVertexAttribArray (filter->draw_attr_position_loc);
  gl->DisableVertexAttribArray (filter->draw_attr_texture_loc);
}

static void
_bind_buffer (GstGLOverlay * overlay, GLuint vbo)
{
  GstGLFilter *filter = GST_GL_FILTER (overlay);
  const GstGLFuncs *gl = GST_GL_BASE_FILTER (overlay)->context->gl_vtable;

  gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, overlay->vbo_indices);
  gl->BindBuffer (GL_ARRAY_BUFFER, vbo);

  gl->EnableVertexAttribArray (filter->draw_attr_position_loc);
  gl->EnableVertexAttribArray (filter->draw_attr_texture_loc);

  gl->VertexAttribPointer (filter->draw_attr_position_loc, 3, GL_FLOAT,
      GL_FALSE, 5 * sizeof (GLfloat), (void *) 0);
  gl->VertexAttribPointer (filter->draw_attr_texture_loc, 2, GL_FLOAT,
      GL_FALSE, 5 * sizeof (GLfloat), (void *) (3 * sizeof (GLfloat)));
}

/* *INDENT-OFF* */
float v_vertices[] = {
/*|      Vertex     | TexCoord  |*/
  -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
   1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
   1.0f,  1.0f, 0.0f, 1.0f, 1.0f,
  -1.0f,  1.0f, 0.0f, 0.0f, 1.0f,
};

static const GLushort indices[] = { 0, 1, 2, 0, 2, 3, };
/* *INDENT-ON* */

static gboolean
gst_gl_overlay_callback (GstGLFilter * filter, GstGLMemory * in_tex,
    gpointer stuff)
{
  GstGLOverlay *overlay = GST_GL_OVERLAY (filter);
  GstMapInfo map_info;
  guint image_tex;
  gboolean memory_mapped = FALSE;
  const GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
  gboolean ret = FALSE;

#if GST_GL_HAVE_OPENGL
  if (gst_gl_context_get_gl_api (GST_GL_BASE_FILTER (filter)->context) &
      GST_GL_API_OPENGL) {

    gl->MatrixMode (GL_PROJECTION);
    gl->LoadIdentity ();
  }
#endif

  gl->ActiveTexture (GL_TEXTURE0);
  gl->BindTexture (GL_TEXTURE_2D, gst_gl_memory_get_texture_id (in_tex));

  gst_gl_shader_use (overlay->shader);

  gst_gl_shader_set_uniform_1f (overlay->shader, "alpha", 1.0f);
  gst_gl_shader_set_uniform_1i (overlay->shader, "texture", 0);

  filter->draw_attr_position_loc =
      gst_gl_shader_get_attribute_location (overlay->shader, "a_position");
  filter->draw_attr_texture_loc =
      gst_gl_shader_get_attribute_location (overlay->shader, "a_texcoord");

  gst_gl_filter_draw_fullscreen_quad (filter);

  if (!overlay->image_memory)
    goto out;

  if (!gst_memory_map ((GstMemory *) overlay->image_memory, &map_info,
          GST_MAP_READ | GST_MAP_GL) || map_info.data == NULL)
    goto out;

  memory_mapped = TRUE;
  image_tex = *(guint *) map_info.data;

  if (!overlay->overlay_vbo) {
    if (gl->GenVertexArrays) {
      gl->GenVertexArrays (1, &overlay->overlay_vao);
      gl->BindVertexArray (overlay->overlay_vao);
    }

    gl->GenBuffers (1, &overlay->vbo_indices);
    gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, overlay->vbo_indices);
    gl->BufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indices), indices,
        GL_STATIC_DRAW);

    gl->GenBuffers (1, &overlay->overlay_vbo);
    gl->BindBuffer (GL_ARRAY_BUFFER, overlay->overlay_vbo);
    gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, overlay->vbo_indices);
    overlay->geometry_change = TRUE;
  }

  if (gl->GenVertexArrays) {
    gl->BindVertexArray (overlay->overlay_vao);
  }

  if (overlay->geometry_change) {
    gint render_width, render_height;
    gfloat x, y, image_width, image_height;

    /* *INDENT-OFF* */
    float vertices[] = {
     -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
      1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
      1.0f,  1.0f, 0.0f, 1.0f, 1.0f,
     -1.0f,  1.0f, 0.0f, 0.0,  1.0f,
    };
    /* *INDENT-ON* */

    /* scale from [0, 1] -> [-1, 1] */
    x = ((gfloat) overlay->offset_x / (gfloat) overlay->window_width +
        overlay->relative_x) * 2.0f - 1.0;
    y = ((gfloat) overlay->offset_y / (gfloat) overlay->window_height +
        overlay->relative_y) * 2.0f - 1.0;
    /* scale from [0, 1] -> [0, 2] */
    render_width =
        overlay->overlay_width >
        0 ? overlay->overlay_width : overlay->image_width;
    render_height =
        overlay->overlay_height >
        0 ? overlay->overlay_height : overlay->image_height;
    image_width =
        ((gfloat) render_width / (gfloat) overlay->window_width) * 2.0f;
    image_height =
        ((gfloat) render_height / (gfloat) overlay->window_height) * 2.0f;

    vertices[0] = vertices[15] = x;
    vertices[5] = vertices[10] = x + image_width;
    vertices[1] = vertices[6] = y;
    vertices[11] = vertices[16] = y + image_height;

    gl->BufferData (GL_ARRAY_BUFFER, 4 * 5 * sizeof (GLfloat), vertices,
        GL_STATIC_DRAW);
  }

  _bind_buffer (overlay, overlay->overlay_vbo);

  gl->BindTexture (GL_TEXTURE_2D, image_tex);
  gst_gl_shader_set_uniform_1f (overlay->shader, "alpha", overlay->alpha);

  gl->Enable (GL_BLEND);
  gl->BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  gl->BlendEquation (GL_FUNC_ADD);

  gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);

  gl->Disable (GL_BLEND);
  ret = TRUE;

out:
  if (gl->GenVertexArrays)
    gl->BindVertexArray (0);
  _unbind_buffer (overlay);

  gst_gl_context_clear_shader (GST_GL_BASE_FILTER (filter)->context);

  if (memory_mapped)
    gst_memory_unmap ((GstMemory *) overlay->image_memory, &map_info);

  overlay->geometry_change = FALSE;

  return ret;
}

static gboolean
load_file (GstGLOverlay * overlay)
{
  FILE *fp;
  guint8 buff[16];
  gsize n_read;
  GstCaps *caps;
  GstStructure *structure;
  gboolean success = FALSE;

  if (overlay->location == NULL)
    return TRUE;

  if ((fp = fopen (overlay->location, "rb")) == NULL) {
    GST_ELEMENT_ERROR (overlay, RESOURCE, NOT_FOUND, ("Can't open file"),
        ("File: %s", overlay->location));
    return FALSE;
  }

  n_read = fread (buff, 1, sizeof (buff), fp);
  if (n_read != sizeof (buff)) {
    GST_ELEMENT_ERROR (overlay, STREAM, DECODE, ("Can't read file header"),
        ("File: %s", overlay->location));
    goto out;
  }

  caps = gst_type_find_helper_for_data (GST_OBJECT (overlay), buff,
      sizeof (buff), NULL);

  if (caps == NULL) {
    GST_ELEMENT_ERROR (overlay, STREAM, DECODE, ("Can't find file type"),
        ("File: %s", overlay->location));
    goto out;
  }

  fseek (fp, 0, SEEK_SET);

  structure = gst_caps_get_structure (caps, 0);
  if (gst_structure_has_name (structure, "image/jpeg")) {
    success = gst_gl_overlay_load_jpeg (overlay, fp);
  } else if (gst_structure_has_name (structure, "image/png")) {
    success = gst_gl_overlay_load_png (overlay, fp);
  } else {
    GST_ELEMENT_ERROR (overlay, STREAM, DECODE, ("Image type not supported"),
        ("File: %s", overlay->location));
  }

out:
  fclose (fp);
  gst_caps_replace (&caps, NULL);

  return success;
}

static gboolean
gst_gl_overlay_filter_texture (GstGLFilter * filter, GstGLMemory * in_tex,
    GstGLMemory * out_tex)
{
  GstGLOverlay *overlay = GST_GL_OVERLAY (filter);

  if (overlay->location_has_changed) {
    if (overlay->image_memory) {
      gst_memory_unref ((GstMemory *) overlay->image_memory);
      overlay->image_memory = NULL;
    }

    if (!load_file (overlay))
      return FALSE;

    overlay->location_has_changed = FALSE;
  }

  gst_gl_filter_render_to_target (filter, in_tex, out_tex,
      gst_gl_overlay_callback, overlay);

  return TRUE;
}

static void
gst_gl_overlay_before_transform (GstBaseTransform * trans, GstBuffer * outbuf)
{
  GstClockTime stream_time;

  stream_time = gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME,
      GST_BUFFER_TIMESTAMP (outbuf));

  if (GST_CLOCK_TIME_IS_VALID (stream_time))
    gst_object_sync_values (GST_OBJECT (trans), stream_time);
}

static void
user_warning_fn (png_structp png_ptr, png_const_charp warning_msg)
{
  g_warning ("%s\n", warning_msg);
}

static gboolean
gst_gl_overlay_load_jpeg (GstGLOverlay * overlay, FILE * fp)
{
  GstGLBaseMemoryAllocator *mem_allocator;
  GstGLVideoAllocationParams *params;
  GstVideoInfo v_info;
  GstVideoAlignment v_align;
  GstMapInfo map_info;
  struct jpeg_decompress_struct cinfo;
  struct jpeg_error_mgr jerr;
  JSAMPROW j;
  int i;

  jpeg_create_decompress (&cinfo);
  cinfo.err = jpeg_std_error (&jerr);
  jpeg_stdio_src (&cinfo, fp);
  jpeg_read_header (&cinfo, TRUE);
  jpeg_start_decompress (&cinfo);
  overlay->image_width = cinfo.image_width;
  overlay->image_height = cinfo.image_height;

  if (cinfo.num_components == 1)
    gst_video_info_set_format (&v_info, GST_VIDEO_FORMAT_Y444,
        overlay->image_width, overlay->image_height);
  else
    gst_video_info_set_format (&v_info, GST_VIDEO_FORMAT_RGB,
        overlay->image_width, overlay->image_height);

  gst_video_alignment_reset (&v_align);
  v_align.stride_align[0] = 32 - 1;
  gst_video_info_align (&v_info, &v_align);

  mem_allocator =
      GST_GL_BASE_MEMORY_ALLOCATOR (gst_gl_memory_allocator_get_default
      (GST_GL_BASE_FILTER (overlay)->context));
  params =
      gst_gl_video_allocation_params_new (GST_GL_BASE_FILTER (overlay)->context,
      NULL, &v_info, 0, &v_align, GST_GL_TEXTURE_TARGET_2D, GST_GL_RGBA);
  overlay->image_memory = (GstGLMemory *)
      gst_gl_base_memory_alloc (mem_allocator,
      (GstGLAllocationParams *) params);
  gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
  gst_object_unref (mem_allocator);

  if (!gst_memory_map ((GstMemory *) overlay->image_memory, &map_info,
          GST_MAP_WRITE)) {
    GST_ELEMENT_ERROR (overlay, STREAM, DECODE, ("failed to map memory"),
        ("File: %s", overlay->location));
    return FALSE;
  }

  for (i = 0; i < overlay->image_height; ++i) {
    j = map_info.data + v_info.stride[0] * i;
    jpeg_read_scanlines (&cinfo, &j, 1);
  }
  jpeg_finish_decompress (&cinfo);
  jpeg_destroy_decompress (&cinfo);
  gst_memory_unmap ((GstMemory *) overlay->image_memory, &map_info);

  return TRUE;
}

static gboolean
gst_gl_overlay_load_png (GstGLOverlay * overlay, FILE * fp)
{
  GstGLBaseMemoryAllocator *mem_allocator;
  GstGLVideoAllocationParams *params;
  GstVideoInfo v_info;
  GstMapInfo map_info;

  png_structp png_ptr;
  png_infop info_ptr;
  png_uint_32 width = 0;
  png_uint_32 height = 0;
  gint bit_depth = 0;
  gint color_type = 0;
  gint interlace_type = 0;
  guint y = 0;
  guchar **rows = NULL;
  gint filler;
  png_byte magic[8];
  gint n_read;

  if (!GST_GL_BASE_FILTER (overlay)->context)
    return FALSE;

  /* Read magic number */
  n_read = fread (magic, 1, sizeof (magic), fp);
  if (n_read != sizeof (magic)) {
    GST_ELEMENT_ERROR (overlay, STREAM, DECODE,
        ("can't read PNG magic number"), ("File: %s", overlay->location));
    return FALSE;
  }

  /* Check for valid magic number */
  if (png_sig_cmp (magic, 0, sizeof (magic))) {
    GST_ELEMENT_ERROR (overlay, STREAM, DECODE,
        ("not a valid PNG image"), ("File: %s", overlay->location));
    return FALSE;
  }

  png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

  if (png_ptr == NULL) {
    GST_ELEMENT_ERROR (overlay, STREAM, DECODE,
        ("failed to initialize the png_struct"), ("File: %s",
            overlay->location));
    return FALSE;
  }

  png_set_error_fn (png_ptr, NULL, NULL, user_warning_fn);

  info_ptr = png_create_info_struct (png_ptr);
  if (info_ptr == NULL) {
    png_destroy_read_struct (&png_ptr, png_infopp_NULL, png_infopp_NULL);
    GST_ELEMENT_ERROR (overlay, STREAM, DECODE,
        ("failed to initialize the memory for image information"),
        ("File: %s", overlay->location));
    return FALSE;
  }

  png_init_io (png_ptr, fp);

  png_set_sig_bytes (png_ptr, sizeof (magic));

  png_read_info (png_ptr, info_ptr);

  png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
      &interlace_type, int_p_NULL, int_p_NULL);

  if (color_type == PNG_COLOR_TYPE_RGB) {
    filler = 0xff;
    png_set_filler (png_ptr, filler, PNG_FILLER_AFTER);
    color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  }

  if (color_type != PNG_COLOR_TYPE_RGB_ALPHA) {
    png_destroy_read_struct (&png_ptr, png_infopp_NULL, png_infopp_NULL);
    GST_ELEMENT_ERROR (overlay, STREAM, DECODE,
        ("color type is not rgb"), ("File: %s", overlay->location));
    return FALSE;
  }

  overlay->image_width = width;
  overlay->image_height = height;

  gst_video_info_set_format (&v_info, GST_VIDEO_FORMAT_RGBA, width, height);
  mem_allocator =
      GST_GL_BASE_MEMORY_ALLOCATOR (gst_gl_memory_allocator_get_default
      (GST_GL_BASE_FILTER (overlay)->context));
  params =
      gst_gl_video_allocation_params_new (GST_GL_BASE_FILTER (overlay)->context,
      NULL, &v_info, 0, NULL, GST_GL_TEXTURE_TARGET_2D, GST_GL_RGBA);
  overlay->image_memory = (GstGLMemory *)
      gst_gl_base_memory_alloc (mem_allocator,
      (GstGLAllocationParams *) params);
  gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
  gst_object_unref (mem_allocator);

  if (!gst_memory_map ((GstMemory *) overlay->image_memory, &map_info,
          GST_MAP_WRITE)) {
    png_destroy_read_struct (&png_ptr, &info_ptr, png_infopp_NULL);
    GST_ELEMENT_ERROR (overlay, STREAM, DECODE,
        ("failed to map memory"), ("File: %s", overlay->location));
    return FALSE;
  }
  rows = (guchar **) malloc (sizeof (guchar *) * height);

  for (y = 0; y < height; ++y)
    rows[y] = (guchar *) (map_info.data + y * width * 4);

  png_read_image (png_ptr, rows);

  free (rows);
  gst_memory_unmap ((GstMemory *) overlay->image_memory, &map_info);

  png_read_end (png_ptr, info_ptr);
  png_destroy_read_struct (&png_ptr, &info_ptr, png_infopp_NULL);

  return TRUE;
}
