2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) <2003> David Schleef <ds@schleef.org>
4 * Copyright (C) 2003 Arwed v. Merkatz <v.merkatz@gmx.net>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
23 * This file was (probably) generated from
24 * gstvideotemplate.c,v 1.12 2004/01/07 21:07:12 ds Exp
26 * make_filter,v 1.6 2004/01/07 21:33:01 ds Exp
34 #include <gstvideofilter.h>
38 #define GST_TYPE_GAMMA \
39 (gst_gamma_get_type())
40 #define GST_GAMMA(obj) \
41 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GAMMA,GstGamma))
42 #define GST_GAMMA_CLASS(klass) \
43 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GAMMA,GstGammaClass))
44 #define GST_IS_GAMMA(obj) \
45 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GAMMA))
46 #define GST_IS_GAMMA_CLASS(obj) \
47 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GAMMA))
49 typedef struct _GstGamma GstGamma;
50 typedef struct _GstGammaClass GstGammaClass;
54 GstVideofilter videofilter;
57 double gamma_r, gamma_g, gamma_b;
58 guint8 gamma_table[256];
59 guint8 gamma_table_r[256];
60 guint8 gamma_table_g[256];
61 guint8 gamma_table_b[256];
66 GstVideofilterClass parent_class;
70 /* GstGamma signals and args */
87 static void gst_gamma_base_init (gpointer g_class);
88 static void gst_gamma_class_init (gpointer g_class, gpointer class_data);
89 static void gst_gamma_init (GTypeInstance * instance, gpointer g_class);
91 static void gst_gamma_set_property (GObject * object, guint prop_id,
92 const GValue * value, GParamSpec * pspec);
93 static void gst_gamma_get_property (GObject * object, guint prop_id,
94 GValue * value, GParamSpec * pspec);
96 static void gst_gamma_planar411 (GstVideofilter * videofilter, void *dest,
98 static void gst_gamma_rgb24 (GstVideofilter * videofilter, void *dest,
100 static void gst_gamma_rgb32 (GstVideofilter * videofilter, void *dest,
102 static void gst_gamma_setup (GstVideofilter * videofilter);
103 static void gst_gamma_calculate_tables (GstGamma * gamma);
106 gst_gamma_get_type (void)
108 static GType gamma_type = 0;
111 static const GTypeInfo gamma_info = {
112 sizeof (GstGammaClass),
115 gst_gamma_class_init,
122 gamma_type = g_type_register_static (GST_TYPE_VIDEOFILTER,
123 "GstGamma", &gamma_info, 0);
128 static GstVideofilterFormat gst_gamma_formats[] = {
129 {"I420", 12, gst_gamma_planar411,},
130 {"RGB ", 24, gst_gamma_rgb24, 24, G_BIG_ENDIAN, 0xff0000, 0xff00, 0xff},
131 {"RGB ", 32, gst_gamma_rgb32, 24, G_BIG_ENDIAN, 0x00ff00, 0xff0000,
137 gst_gamma_base_init (gpointer g_class)
139 static GstElementDetails gamma_details =
140 GST_ELEMENT_DETAILS ("Video Gamma Correction",
141 "Filter/Effect/Video",
142 "Adjusts gamma on a video stream",
143 "Arwed v. Merkatz <v.merkatz@gmx.net");
144 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
145 GstVideofilterClass *videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
148 gst_element_class_set_details (element_class, &gamma_details);
150 for (i = 0; i < G_N_ELEMENTS (gst_gamma_formats); i++) {
151 gst_videofilter_class_add_format (videofilter_class, gst_gamma_formats + i);
154 gst_videofilter_class_add_pad_templates (GST_VIDEOFILTER_CLASS (g_class));
158 gst_gamma_class_init (gpointer g_class, gpointer class_data)
160 GObjectClass *gobject_class;
161 GstVideofilterClass *videofilter_class;
163 gobject_class = G_OBJECT_CLASS (g_class);
164 videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
166 g_object_class_install_property (gobject_class, ARG_GAMMA,
167 g_param_spec_double ("gamma", "Gamma", "gamma",
168 0.01, 10, 1, G_PARAM_READWRITE));
169 g_object_class_install_property (gobject_class, ARG_GAMMA_R,
170 g_param_spec_double ("redgamma", "Gamma_r",
171 "gamma value for the red channel", 0.01, 10, 1, G_PARAM_READWRITE));
172 g_object_class_install_property (gobject_class, ARG_GAMMA_G,
173 g_param_spec_double ("greengamma", "Gamma_g",
174 "gamma value for the green channel", 0.01, 10, 1, G_PARAM_READWRITE));
175 g_object_class_install_property (gobject_class, ARG_GAMMA_B,
176 g_param_spec_double ("bluegamma", "Gamma_b",
177 "gamma value for the blue channel", 0.01, 10, 1, G_PARAM_READWRITE));
179 gobject_class->set_property = gst_gamma_set_property;
180 gobject_class->get_property = gst_gamma_get_property;
182 videofilter_class->setup = gst_gamma_setup;
186 gst_gamma_init (GTypeInstance * instance, gpointer g_class)
188 GstGamma *gamma = GST_GAMMA (instance);
189 GstVideofilter *videofilter;
191 GST_DEBUG ("gst_gamma_init");
193 videofilter = GST_VIDEOFILTER (gamma);
200 gst_gamma_calculate_tables (gamma);
204 gst_gamma_set_property (GObject * object, guint prop_id, const GValue * value,
209 /* it's not null if we got it, but it might not be ours */
210 g_return_if_fail (GST_IS_GAMMA (object));
211 gamma = GST_GAMMA (object);
213 GST_DEBUG ("gst_gamma_set_property");
216 gamma->gamma = g_value_get_double (value);
217 gst_gamma_calculate_tables (gamma);
220 gamma->gamma_r = g_value_get_double (value);
221 gst_gamma_calculate_tables (gamma);
224 gamma->gamma_g = g_value_get_double (value);
225 gst_gamma_calculate_tables (gamma);
228 gamma->gamma_b = g_value_get_double (value);
229 gst_gamma_calculate_tables (gamma);
237 gst_gamma_get_property (GObject * object, guint prop_id, GValue * value,
242 /* it's not null if we got it, but it might not be ours */
243 g_return_if_fail (GST_IS_GAMMA (object));
244 gamma = GST_GAMMA (object);
248 g_value_set_double (value, gamma->gamma);
251 g_value_set_double (value, gamma->gamma_r);
254 g_value_set_double (value, gamma->gamma_g);
257 g_value_set_double (value, gamma->gamma_b);
260 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
266 plugin_init (GstPlugin * plugin)
268 if (!gst_library_load ("gstvideofilter"))
271 return gst_element_register (plugin, "gamma", GST_RANK_NONE, GST_TYPE_GAMMA);
274 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
277 "Changes gamma on video images",
278 plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)
281 static void gst_gamma_setup (GstVideofilter * videofilter)
285 g_return_if_fail (GST_IS_GAMMA (videofilter));
286 gamma = GST_GAMMA (videofilter);
288 /* if any setup needs to be done, do it here */
293 gst_gamma_calculate_tables (GstGamma * gamma)
299 if (gamma->gamma == 1.0 &&
300 gamma->gamma_r == 1.0 && gamma->gamma_g == 1.0 && gamma->gamma_b == 1.0) {
301 GST_VIDEOFILTER (gamma)->passthru = TRUE;
304 GST_VIDEOFILTER (gamma)->passthru = FALSE;
306 exp = 1.0 / gamma->gamma;
307 for (n = 0; n < 256; n++) {
309 val = pow (val, exp);
311 gamma->gamma_table[n] = (unsigned char) floor (val + 0.5);
313 exp = 1.0 / gamma->gamma_r;
314 for (n = 0; n < 256; n++) {
316 val = pow (val, exp);
318 gamma->gamma_table_r[n] = (unsigned char) floor (val + 0.5);
320 exp = 1.0 / gamma->gamma_g;
321 for (n = 0; n < 256; n++) {
323 val = pow (val, exp);
325 gamma->gamma_table_g[n] = (unsigned char) floor (val + 0.5);
327 exp = 1.0 / gamma->gamma_b;
328 for (n = 0; n < 256; n++) {
330 val = pow (val, exp);
332 gamma->gamma_table_b[n] = (unsigned char) floor (val + 0.5);
338 gst_gamma_planar411 (GstVideofilter * videofilter, void *dest, void *src)
341 int width = gst_videofilter_get_input_width (videofilter);
342 int height = gst_videofilter_get_input_height (videofilter);
344 g_return_if_fail (GST_IS_GAMMA (videofilter));
345 gamma = GST_GAMMA (videofilter);
347 memcpy (dest, src, width * height + (width / 2) * (height / 2) * 2);
349 if (gamma->gamma != 1.0) {
351 guint8 *cdest = dest;
355 for (y = 0; y < height; y++) {
356 for (x = 0; x < width; x++) {
357 cdest[y * width + x] =
358 gamma->gamma_table[(unsigned char) csrc[y * width + x]];
366 gst_gamma_rgb24 (GstVideofilter * videofilter, void *dest, void *src)
372 guint8 *cdest = dest;
374 g_return_if_fail (GST_IS_GAMMA (videofilter));
375 gamma = GST_GAMMA (videofilter);
377 width = gst_videofilter_get_input_width (videofilter);
378 height = gst_videofilter_get_input_height (videofilter);
379 if (gamma->gamma == 1.0) {
381 while (i < width * height * 3) {
382 *cdest++ = gamma->gamma_table_r[*csrc++];
383 *cdest++ = gamma->gamma_table_g[*csrc++];
384 *cdest++ = gamma->gamma_table_b[*csrc++];
389 while (i < width * height * 3) {
390 *cdest++ = gamma->gamma_table[*csrc++];
397 gst_gamma_rgb32 (GstVideofilter * videofilter, void *dest, void *src)
403 guint8 *cdest = dest;
405 g_return_if_fail (GST_IS_GAMMA (videofilter));
406 gamma = GST_GAMMA (videofilter);
408 width = gst_videofilter_get_input_width (videofilter);
409 height = gst_videofilter_get_input_height (videofilter);
410 if (gamma->gamma == 1.0) {
412 while (i < width * height * 4) {
413 *cdest++ = gamma->gamma_table_b[*csrc++];
414 *cdest++ = gamma->gamma_table_g[*csrc++];
415 *cdest++ = gamma->gamma_table_r[*csrc++];
422 while (i < width * height * 4) {
424 *cdest++ = gamma->gamma_table[*csrc++];