]> git.sesse.net Git - mlt/commitdiff
Add lumaliftgaingamma filter to plusgpl
authorJanne Liljeblad <janne.liljeblad@gmail.com>
Mon, 24 Feb 2014 09:18:27 +0000 (11:18 +0200)
committerJanne Liljeblad <janne.liljeblad@gmail.com>
Mon, 24 Feb 2014 09:18:27 +0000 (11:18 +0200)
src/modules/plusgpl/Makefile
src/modules/plusgpl/factory.c
src/modules/plusgpl/filter_lumaliftgaingamma.c [new file with mode: 0644]
src/modules/plusgpl/filter_lumaliftgaingamma.yml [new file with mode: 0644]

index c204ad3d378b68846c006f4cc1392d29646d5faf..71de1803269582a258d8ce8fc23fe309e91f9931 100644 (file)
@@ -8,6 +8,7 @@ TARGET = ../libmltplusgpl$(LIBSUF)
 
 OBJS = factory.o \
           filter_burn.o \
+          filter_lumaliftgaingamma.o \
           image.o \
           utils.o \
           filter_rotoscoping.o \
index dddc117cd1ef20e43e26d1c1c015ed681f8467d1..a1874133791be7f1559176ec76d0ffb83ebe1980 100644 (file)
@@ -22,6 +22,7 @@
 #include <limits.h>
 
 extern mlt_filter filter_burn_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_lumaliftgaingamma_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
 extern mlt_filter filter_rotoscoping_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
 extern mlt_filter filter_telecide_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
 
@@ -36,10 +37,12 @@ MLT_REPOSITORY
 {
        MLT_REGISTER( filter_type, "BurningTV", filter_burn_init );
        MLT_REGISTER( filter_type, "burningtv", filter_burn_init );
+       MLT_REGISTER( filter_type, "lumaliftgaingamma", filter_lumaliftgaingamma_init );
        MLT_REGISTER( filter_type, "rotoscoping", filter_rotoscoping_init );
        MLT_REGISTER( filter_type, "telecide", filter_telecide_init );
 
        MLT_REGISTER_METADATA( filter_type, "BurningTV", metadata, "filter_burningtv.yml" );
        MLT_REGISTER_METADATA( filter_type, "burningtv", metadata, "filter_burningtv.yml" );
+       MLT_REGISTER_METADATA( filter_type, "lumaliftgaingamma", metadata, "filter_lumaliftgaingamma.yml" );
        MLT_REGISTER_METADATA( filter_type, "rotoscoping", metadata, "filter_rotoscoping.yml" );
 }
diff --git a/src/modules/plusgpl/filter_lumaliftgaingamma.c b/src/modules/plusgpl/filter_lumaliftgaingamma.c
new file mode 100644 (file)
index 0000000..11d5ecc
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * filter_lumaliftgaingamma.c -- Lift Gain Gamma filter for luma correction
+ * Copyright (C) 2014 Janne Liljeblad
+ * Author: Janne Liljeblad
+ *
+ * This filter is a port from Gimp and is distributed under a compatible license.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <framework/mlt_filter.h>
+#include <framework/mlt_frame.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+static double clamp( double value, double low, double high)
+{
+       if (value < low)
+               value = low;
+       if (value > high)
+               value = high;
+       return value;
+}
+
+static double lut_value( double value, double lift, double gain, double gamma )
+{
+       double nvalue;
+       double power;
+
+       value = clamp( value + lift, 0, 1 );
+
+       if( gain < 0.0)
+               value = value * (1.0 + gain);
+       else
+               value = value + ((1.0 - value) * gain);
+
+       if(gamma < 0.0)
+       {
+               if (value > 0.5)
+                       nvalue = 1.0 - value;
+               else
+                       nvalue = value;
+
+               if (nvalue < 0.0)
+                       nvalue = 0.0;
+
+               nvalue = 0.5 * pow (nvalue * 2.0 , (double) (1.0 + gamma));
+               
+               if (value > 0.5)
+                       value = 1.0 - nvalue;
+               else
+                       value = nvalue;
+       }
+       else
+       {
+               if (value > 0.5)
+                       nvalue = 1.0 - value;
+               else
+                       nvalue = value;
+
+               if (nvalue < 0.0)
+                       nvalue = 0.0;
+
+               power = (gamma == 1.0) ? 127 : 1.0 / (1.0 - gamma);
+               nvalue = 0.5 * pow (2.0 * nvalue, power);
+
+               if (value > 0.5)
+                       value = 1.0 - nvalue;
+               else
+                       value = nvalue;
+       }
+
+       return value;
+}
+
+static void fill_lgg_lut(int lgg_lut[], double lift, double gain, double gamma)
+{
+       int i;
+       double val;
+       for( i = 0; i < 256; i++ )
+       {
+               val = (double) i / 255.0;
+               lgg_lut[ i ] = (int) (lut_value( val, lift, gain, gamma ) * 255.0);
+       }
+}
+
+/** Do image filtering.
+*/
+static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
+{
+       // Get the image
+       mlt_filter filter = (mlt_filter) mlt_frame_pop_service( frame );
+       mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+       mlt_position position = mlt_filter_get_position( filter, frame );
+       mlt_position length = mlt_filter_get_length2( filter, frame );
+
+       *format = mlt_image_rgb24;
+       int error = mlt_frame_get_image( frame, image, format, width, height, 0 );
+
+       // Only process if we have no error and a valid colour space
+       if ( error == 0 )
+       {
+               // Get values and force accepted ranges
+               double lift = mlt_properties_anim_get_double( properties, "lift", position, length );
+               double gain = mlt_properties_anim_get_double( properties, "gain", position, length );
+               double gamma = mlt_properties_anim_get_double( properties, "gamma", position, length );
+               lift = clamp( lift, -0.5, 0.5 );
+               gain = clamp( gain, -0.5, 0.5 );
+               gamma = clamp( gamma, -1.0, 1.0 );
+
+               // Build lut
+               int lgg_lut[256];
+               fill_lgg_lut( lgg_lut, lift, gain, gamma);
+
+               // Filter
+               int i = *width * *height + 1;
+               uint8_t *p = *image;
+               uint8_t *r = *image;
+               while ( --i )
+               {
+                       *p ++ = lgg_lut[ *r ++ ];
+                       *p ++ = lgg_lut[ *r ++ ];
+                       *p ++ = lgg_lut[ *r ++ ];
+               }
+       }
+
+       return error;
+}
+
+/** Filter processing.
+*/
+static mlt_frame filter_process( mlt_filter filter, mlt_frame frame )
+{
+       // Push the frame filter
+       mlt_frame_push_service( frame, filter );
+       mlt_frame_push_get_image( frame, filter_get_image );
+       return frame;
+}
+
+/** Constructor for the filter.
+*/
+mlt_filter filter_lumaliftgaingamma_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+       mlt_filter filter = mlt_filter_new( );
+       if ( filter != NULL )
+       {
+               filter->process = filter_process;
+               mlt_properties_set( MLT_FILTER_PROPERTIES( filter ), "lift", "0" );
+               mlt_properties_set( MLT_FILTER_PROPERTIES( filter ), "gain", "0" );
+               mlt_properties_set( MLT_FILTER_PROPERTIES( filter ), "gamma", "0" );
+       }
+       return filter;
+}
+
diff --git a/src/modules/plusgpl/filter_lumaliftgaingamma.yml b/src/modules/plusgpl/filter_lumaliftgaingamma.yml
new file mode 100644 (file)
index 0000000..83dde74
--- /dev/null
@@ -0,0 +1,47 @@
+schema_version: 0.1
+type: filter
+identifier: lumaliftgaingamma
+title: LumaLiftGainGamma
+version: 1
+copyright: Janne Liljeblad
+creator: Janne Liljeblad
+license: GPL
+language: en
+tags:
+  - Video
+description:
+  Filter can be used to apply lift, gain and gamma correction to
+  luma values of image.
+
+parameters:
+  - identifier: lift
+    title: Lift
+    type: double
+    minimum: -0.5
+    maximum: 0.5
+    default: 0
+    description: >
+      Adds a value computed using parameter value 
+      to color channel values.
+
+parameters:
+  - identifier: gain
+    title: Gain
+    type: double
+    minimum: -0.5
+    maximum: 0.5
+    default: 0
+    description: >
+      Multiplies color channel values by value
+      computed using paramter value.
+
+parameters:
+  - identifier: gamma
+    title: Gamma
+    type: double
+    minimum: -1.0
+    maximum: 1.0
+    default: 0
+    description: >
+      Applies a gamma correction to all 
+      color channel values.