From 6d53140c73dae77bd15cdcbc28b35fbee2b0ddda Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sun, 11 Jan 2004 21:52:10 +0000 Subject: New gamma filter Original commit message from CVS: New gamma filter --- gst/videofilter/Makefile.am | 6 +- gst/videofilter/gstgamma.c | 293 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 298 insertions(+), 1 deletion(-) create mode 100644 gst/videofilter/gstgamma.c (limited to 'gst/videofilter') diff --git a/gst/videofilter/Makefile.am b/gst/videofilter/Makefile.am index 56e54c98..23a6da3e 100644 --- a/gst/videofilter/Makefile.am +++ b/gst/videofilter/Makefile.am @@ -1,6 +1,6 @@ plugin_LTLIBRARIES = libgstvideofilter.la libgstvideoflip.la \ - libgstvideobalance.la + libgstvideobalance.la libgstgamma.la noinst_LTLIBRARIES = libgstvideoexample.la noinst_HEADERS = gstvideofilter.h gstvideoflip.h gstvideobalance.h @@ -28,6 +28,10 @@ libgstvideobalance_la_CFLAGS = $(GST_CFLAGS) libgstvideobalance_la_LIBADD = libgstvideobalance_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -lm +libgstgamma_la_SOURCES = gstgamma.c +libgstgamma_la_CFLAGS = $(GST_CFLAGS) +libgstgamma_la_LIBADD = +libgstgamma_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -lm gstvideoexample.c: $(srcdir)/make_filter $(srcdir)/gstvideotemplate.c $(srcdir)/make_filter Videoexample $(srcdir)/gstvideotemplate.c diff --git a/gst/videofilter/gstgamma.c b/gst/videofilter/gstgamma.c new file mode 100644 index 00000000..b05127c0 --- /dev/null +++ b/gst/videofilter/gstgamma.c @@ -0,0 +1,293 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * Copyright (C) <2003> David Schleef + * Copyright (C) 2003 Arwed v. Merkatz + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * This file was (probably) generated from + * gstvideotemplate.c,v 1.12 2004/01/07 21:07:12 ds Exp + * and + * make_filter,v 1.6 2004/01/07 21:33:01 ds Exp + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#define GST_TYPE_GAMMA \ + (gst_gamma_get_type()) +#define GST_GAMMA(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GAMMA,GstGamma)) +#define GST_GAMMA_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GAMMA,GstGammaClass)) +#define GST_IS_GAMMA(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GAMMA)) +#define GST_IS_GAMMA_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GAMMA)) + +typedef struct _GstGamma GstGamma; +typedef struct _GstGammaClass GstGammaClass; + +struct _GstGamma { + GstVideofilter videofilter; + + double gamma; + guint8 gamma_table[256]; +}; + +struct _GstGammaClass { + GstVideofilterClass parent_class; +}; + + +/* GstGamma signals and args */ +enum { + /* FILL ME */ + LAST_SIGNAL +}; + +enum { + ARG_0, + ARG_GAMMA, + /* FILL ME */ +}; + +static void gst_gamma_base_init (gpointer g_class); +static void gst_gamma_class_init (gpointer g_class, gpointer class_data); +static void gst_gamma_init (GTypeInstance *instance, gpointer g_class); + +static void gst_gamma_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +static void gst_gamma_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); + +static void gst_gamma_planar411(GstVideofilter *videofilter, void *dest, void *src); +static void gst_gamma_setup(GstVideofilter *videofilter); +static void gst_gamma_calculate_table (GstGamma *gamma); + +GType +gst_gamma_get_type (void) +{ + static GType gamma_type = 0; + + if (!gamma_type) { + static const GTypeInfo gamma_info = { + sizeof(GstGammaClass), + gst_gamma_base_init, + NULL, + gst_gamma_class_init, + NULL, + NULL, + sizeof(GstGamma), + 0, + gst_gamma_init, + }; + gamma_type = g_type_register_static(GST_TYPE_VIDEOFILTER, + "GstGamma", &gamma_info, 0); + } + return gamma_type; +} + +static GstVideofilterFormat gst_gamma_formats[] = { + { "I420", 12, gst_gamma_planar411, }, +}; + + +static void +gst_gamma_base_init (gpointer g_class) +{ + static GstElementDetails gamma_details = GST_ELEMENT_DETAILS ( + "Video Gamma Correction", + "Filter/Effect/Video", + "Adjusts gamma on a video stream", + "Arwed v. Merkatz set_property = gst_gamma_set_property; + gobject_class->get_property = gst_gamma_get_property; + + videofilter_class->setup = gst_gamma_setup; +} + +static void +gst_gamma_init (GTypeInstance *instance, gpointer g_class) +{ + GstGamma *gamma = GST_GAMMA (instance); + GstVideofilter *videofilter; + + GST_DEBUG("gst_gamma_init"); + + videofilter = GST_VIDEOFILTER(gamma); + + /* do stuff */ + gamma->gamma = 1; + gst_gamma_calculate_table (gamma); +} + +static void +gst_gamma_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GstGamma *gamma; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail(GST_IS_GAMMA(object)); + gamma = GST_GAMMA(object); + + GST_DEBUG("gst_gamma_set_property"); + switch (prop_id) { + case ARG_GAMMA: + gamma->gamma = g_value_get_double (value); + gst_gamma_calculate_table (gamma); + break; + default: + break; + } +} + +static void +gst_gamma_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GstGamma *gamma; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail(GST_IS_GAMMA(object)); + gamma = GST_GAMMA(object); + + switch (prop_id) { + case ARG_GAMMA: + g_value_set_double (value, gamma->gamma); + gst_gamma_calculate_table (gamma); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean plugin_init (GstPlugin *plugin) +{ + if(!gst_library_load("gstvideofilter")) + return FALSE; + + return gst_element_register (plugin, "gamma", GST_RANK_NONE, + GST_TYPE_GAMMA); +} + +GST_PLUGIN_DEFINE ( + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "gamma", + "Changes gamma on video images", + plugin_init, + VERSION, + GST_LICENSE, + GST_PACKAGE, + GST_ORIGIN +) + + +static void gst_gamma_setup(GstVideofilter *videofilter) +{ + GstGamma *gamma; + + g_return_if_fail(GST_IS_GAMMA(videofilter)); + gamma = GST_GAMMA(videofilter); + + /* if any setup needs to be done, do it here */ + +} + +static void +gst_gamma_calculate_table (GstGamma *gamma) +{ + int n; + double val; + double exp; + + if (gamma->gamma == 1.0) { + GST_VIDEOFILTER (gamma)->passthru = TRUE; + return; + } + GST_VIDEOFILTER (gamma)->passthru = FALSE; + + exp = 1.0 / gamma->gamma; + for (n = 0; n < 256; n++) { + val = n/255.0; + val = pow(val, exp); + val = 255.0 * val; + gamma->gamma_table[n] = (unsigned char) floor(val + 0.5); + } + +} + +static void gst_gamma_planar411(GstVideofilter *videofilter, + void *dest, void *src) +{ + GstGamma *gamma; + int width = gst_videofilter_get_input_width(videofilter); + int height = gst_videofilter_get_input_height(videofilter); + + g_return_if_fail(GST_IS_GAMMA(videofilter)); + gamma = GST_GAMMA(videofilter); + + memcpy(dest,src,width * height + (width/2) * (height/2) * 2); + + if (gamma->gamma != 1.0) { + { + guint8 *cdest = dest; + guint8 *csrc = src; + int x,y; + for (y=0; y < height; y++) { + for (x=0; x < width; x++) { + cdest[y*width + x] = gamma->gamma_table[(unsigned char)csrc[y*width + x]]; + } + } + } + } +} + -- cgit