From 994a25ca7ee1bfe95365f73cca509a9fa958a8de Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Fri, 23 Jan 2009 02:04:23 +0100 Subject: [PATCH] [301/906] depends on libpng instead of gdk_pixbuf --- gst-libs/gst/gl/gstgldisplay.c | 57 +---------- gst/gl/gstgldifferencematte.c | 136 ++++++++++++++++++++----- gst/gl/gstglpixbufoverlay.c | 22 ++-- tests/examples/gtk/fxtest/pixbufdrop.c | 5 +- 4 files changed, 129 insertions(+), 91 deletions(-) diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index e445f49763..a848e24bbf 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -2201,31 +2201,6 @@ gst_gl_display_thread_do_upload_fill (GstGLDisplay *display) case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: { - gint offsetU = 0; - gint offsetV = 0; - - switch (display->upload_video_format) - { - case GST_VIDEO_FORMAT_I420: - offsetU = 1; - offsetV = 2; - break; - case GST_VIDEO_FORMAT_YV12: - -#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) - //WIN32 - offsetU = 2; - offsetV = 1; -#else - //LINUX - offsetU = 1; - offsetV = 2; -#endif - break; - default: - g_assert_not_reached (); - } - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); @@ -2234,14 +2209,14 @@ gst_gl_display_thread_do_upload_fill (GstGLDisplay *display) GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, (guint8 *) data + - gst_video_format_get_component_offset (display->upload_video_format, offsetU, width, height)); + gst_video_format_get_component_offset (display->upload_video_format, 1, width, height)); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_v); glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, (guint8 *) data + - gst_video_format_get_component_offset (display->upload_video_format, offsetV, width, height)); + gst_video_format_get_component_offset (display->upload_video_format, 2, width, height)); } break; default: @@ -2654,30 +2629,6 @@ gst_gl_display_thread_do_download_draw_yuv (GstGLDisplay *display) case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: { - gint offsetU = 0; - gint offsetV = 0; - - switch (video_format) - { - case GST_VIDEO_FORMAT_I420: - offsetU = 1; - offsetV = 2; - break; - case GST_VIDEO_FORMAT_YV12: -#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) - //WIN32 - offsetU = 2; - offsetV = 1; -#else - //LINUX - offsetU = 1; - offsetV = 2; -#endif - break; - default: - g_assert_not_reached (); - } - glReadPixels (0, 0, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); @@ -2685,13 +2636,13 @@ gst_gl_display_thread_do_download_draw_yuv (GstGLDisplay *display) glReadPixels (0, 0, GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, (guint8 *) data + - gst_video_format_get_component_offset (video_format, offsetU, width, height)); + gst_video_format_get_component_offset (video_format, 1, width, height)); glReadBuffer(GL_COLOR_ATTACHMENT2_EXT); glReadPixels (0, 0, GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, (guint8 *) data + - gst_video_format_get_component_offset (video_format, offsetV, width, height)); + gst_video_format_get_component_offset (video_format, 2, width, height)); } break; default: diff --git a/gst/gl/gstgldifferencematte.c b/gst/gl/gstgldifferencematte.c index 103ca1c6cb..8fc6010810 100644 --- a/gst/gl/gstgldifferencematte.c +++ b/gst/gl/gstgldifferencematte.c @@ -36,9 +36,9 @@ #include "config.h" #endif +#include #include #include -#include #define GST_TYPE_GL_DIFFERENCEMATTE (gst_gl_differencematte_get_type()) #define GST_GL_DIFFERENCEMATTE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_GL_DIFFERENCEMATTE,GstGLDifferenceMatte)) @@ -56,7 +56,7 @@ struct _GstGLDifferenceMatte gchar *location; gboolean bg_has_changed; - GdkPixbuf *pixbuf; + guchar *pixbuf; GLuint savedbgtexture; GLuint newbgtexture; GLuint midtexture[4]; @@ -91,6 +91,8 @@ static void gst_gl_differencematte_reset_resources (GstGLFilter* filter); static gboolean gst_gl_differencematte_filter (GstGLFilter * filter, GstGLBuffer * inbuf, GstGLBuffer * outbuf); +static gboolean gst_gl_differencematte_loader (GstGLFilter* filter); + static const GstElementDetails element_details = GST_ELEMENT_DETAILS ( "Gstreamer OpenGL DifferenceMatte", "Filter/Effect", @@ -300,8 +302,7 @@ static void init_pixbuf_texture (GstGLDisplay *display, gpointer data) glBindTexture (GL_TEXTURE_RECTANGLE_ARB, differencematte->newbgtexture); glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, filter->width, filter->height, 0, - gdk_pixbuf_get_has_alpha (differencematte->pixbuf) ? GL_RGBA : GL_RGB, - GL_UNSIGNED_BYTE, gdk_pixbuf_get_pixels (differencematte->pixbuf)); + GL_RGB, GL_UNSIGNED_BYTE, differencematte->pixbuf); //FIXME: RGBA if (differencematte->savedbgtexture == 0) { glGenTextures (1, &differencematte->savedbgtexture); @@ -450,33 +451,29 @@ gst_gl_differencematte_filter (GstGLFilter* filter, GstGLBuffer* inbuf, GstGLBuffer* outbuf) { GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE(filter); - GdkPixbuf *pixbuf; - GError *error = NULL; differencematte->intexture = inbuf->texture; if (differencematte->bg_has_changed && (differencematte->location != NULL)) { - pixbuf = gdk_pixbuf_new_from_file (differencematte->location, &error); - if (pixbuf) { - differencematte->pixbuf = gdk_pixbuf_scale_simple (pixbuf, - filter->width, - filter->height, - GDK_INTERP_BILINEAR); - gdk_pixbuf_unref (pixbuf); - if (differencematte->pixbuf != NULL) { - gst_gl_display_thread_add (filter->display, init_pixbuf_texture, differencematte); - /* save current frame, needed to calculate difference between - * this frame and next ones */ - gst_gl_filter_render_to_target (filter, inbuf->texture, - differencematte->savedbgtexture, - gst_gl_differencematte_save_texture, - differencematte); - gdk_pixbuf_unref (differencematte->pixbuf); - } - } else { - if (error != NULL && error->message != NULL) - g_warning ("unable to load %s: %s", differencematte->location, error->message); + + if (!gst_gl_differencematte_loader (filter)) + differencematte->pixbuf = NULL; + + /* if loader failed then display is turned off */ + gst_gl_display_thread_add (filter->display, init_pixbuf_texture, differencematte); + + /* save current frame, needed to calculate difference between + * this frame and next ones */ + gst_gl_filter_render_to_target (filter, inbuf->texture, + differencematte->savedbgtexture, + gst_gl_differencematte_save_texture, + differencematte); + + if (differencematte->pixbuf) { + free (differencematte->pixbuf); + differencematte->pixbuf = NULL; } + differencematte->bg_has_changed = FALSE; } @@ -506,3 +503,90 @@ gst_gl_differencematte_filter (GstGLFilter* filter, GstGLBuffer* inbuf, return TRUE; } + +static void +user_warning_fn(png_structp png_ptr, png_const_charp warning_msg) +{ + g_warning("%s\n", warning_msg); +} + +#define LOAD_ERROR(msg) { GST_WARNING ("unable to load %s: %s", differencematte->location, msg); return FALSE; } + +static gboolean +gst_gl_differencematte_loader (GstGLFilter* filter) +{ + GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE(filter); + GstGLDisplay *display = filter->display; + + png_structp png_ptr; + png_infop info_ptr; + guint sig_read = 0; + png_uint_32 width = 0; + png_uint_32 height = 0; + gint bit_depth = 0; + gint color_type = 0; + gint interlace_type = 0; + png_FILE_p fp = NULL; + guint y = 0; + guchar **rows = NULL; + + if (!filter->display) + return TRUE; + + if ((fp = fopen(differencematte->location, "rb")) == NULL) + LOAD_ERROR ("file not found"); + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (png_ptr == NULL) + { + fclose(fp); + LOAD_ERROR ("failed to initialize the png_struct"); + } + + png_set_error_fn (png_ptr, NULL, NULL, user_warning_fn); + + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) + { + fclose(fp); + png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); + LOAD_ERROR ("failed to initialize the memory for image information"); + } + + png_init_io(png_ptr, fp); + + png_set_sig_bytes(png_ptr, sig_read); + + 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) //FIXME: RGBA + { + fclose(fp); + png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); + LOAD_ERROR ("color type is not rgb"); + } + + filter->width = width; + filter->height = height; + + differencematte->pixbuf = (guchar*) malloc ( sizeof(guchar) * width * height * 3 ); //FIXME: g_alloc, RGBA + + rows = (guchar**)malloc(sizeof(guchar*) * height); //FIXME: g_alloc + + for (y = 0; y < height; ++y) + rows[y] = (guchar*) (differencematte->pixbuf + y * width * 3); + + png_read_image(png_ptr, rows); + + free(rows); + + png_read_end(png_ptr, info_ptr); + png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); + fclose(fp); + + return TRUE; +} diff --git a/gst/gl/gstglpixbufoverlay.c b/gst/gl/gstglpixbufoverlay.c index dcea81470f..7f8210b446 100644 --- a/gst/gl/gstglpixbufoverlay.c +++ b/gst/gl/gstglpixbufoverlay.c @@ -324,16 +324,16 @@ gst_gl_pixbufoverlay_filter (GstGLFilter* filter, GstGLBuffer* inbuf, if (pixbufoverlay->pbuf_has_changed && (pixbufoverlay->location != NULL)) { - if (pixbufoverlay->pixbuf) { - free (pixbufoverlay->pixbuf); - pixbufoverlay->pixbuf = NULL; - } + if (!gst_gl_pixbufoverlay_loader (filter)) + pixbufoverlay->pixbuf = NULL; + + /* if loader failed then display is turned off */ + gst_gl_display_thread_add (filter->display, init_pixbuf_texture, pixbufoverlay); - if (!gst_gl_pixbufoverlay_loader (filter)) - pixbufoverlay->pixbuf = NULL; - - /* if loader failed then display is turned off */ - gst_gl_display_thread_add (filter->display, init_pixbuf_texture, pixbufoverlay); + if (pixbufoverlay->pixbuf) { + free (pixbufoverlay->pixbuf); + pixbufoverlay->pixbuf = NULL; + } pixbufoverlay->pbuf_has_changed = FALSE; } @@ -413,9 +413,9 @@ gst_gl_pixbufoverlay_loader (GstGLFilter* filter) pixbufoverlay->width = width; pixbufoverlay->height = height; - pixbufoverlay->pixbuf = (guchar*) malloc ( sizeof(guchar) * width * height * 3 ); + pixbufoverlay->pixbuf = (guchar*) malloc ( sizeof(guchar) * width * height * 3 ); //FIXME: g_alloc, RGBA - rows = (guchar**)malloc(sizeof(guchar*) * height); + rows = (guchar**)malloc(sizeof(guchar*) * height); //FIXME: g_alloc for (y = 0; y < height; ++y) rows[y] = (guchar*) (pixbufoverlay->pixbuf + y * width * 3); diff --git a/tests/examples/gtk/fxtest/pixbufdrop.c b/tests/examples/gtk/fxtest/pixbufdrop.c index 1aaf6bbfc6..06df5d1c68 100644 --- a/tests/examples/gtk/fxtest/pixbufdrop.c +++ b/tests/examples/gtk/fxtest/pixbufdrop.c @@ -119,7 +119,10 @@ on_drag_data_received (GtkWidget * widget, GdkPixbufFormat *format; SourceData *userdata = g_new0 (SourceData, 1); gchar **uris = gtk_selection_data_get_uris (seldata); - gchar *filename = g_filename_from_uri (uris[0], NULL, NULL); + gchar *filename = NULL; + + g_return_if_fail (uris != NULL); + filename = g_filename_from_uri (uris[0], NULL, NULL); g_return_if_fail (filename != NULL); format = gdk_pixbuf_get_file_info (filename, NULL, NULL); g_return_if_fail (format);