2 * filter_lumaliftgaingamma.c -- Lift Gain Gamma filter for luma correction
3 * Copyright (C) 2014 Janne Liljeblad
4 * Author: Janne Liljeblad
6 * This filter is a port from Gimp and is distributed under a compatible license.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include <framework/mlt_filter.h>
24 #include <framework/mlt_frame.h>
31 static double clamp( double value, double low, double high)
40 static double lut_value( double value, double lift, double gain, double gamma )
45 value = clamp( value + lift, 0, 1 );
48 value = value * (1.0 + gain);
50 value = value + ((1.0 - value) * gain);
62 nvalue = 0.5 * pow (nvalue * 2.0 , (double) (1.0 + gamma));
79 power = (gamma == 1.0) ? 127 : 1.0 / (1.0 - gamma);
80 nvalue = 0.5 * pow (2.0 * nvalue, power);
91 static void fill_lgg_lut(int lgg_lut[], double lift, double gain, double gamma)
95 for( i = 0; i < 256; i++ )
97 val = (double) i / 255.0;
98 lgg_lut[ i ] = (int) (lut_value( val, lift, gain, gamma ) * 255.0);
102 /** Do image filtering.
104 static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
107 mlt_filter filter = (mlt_filter) mlt_frame_pop_service( frame );
108 mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
109 mlt_position position = mlt_filter_get_position( filter, frame );
110 mlt_position length = mlt_filter_get_length2( filter, frame );
112 *format = mlt_image_rgb24;
113 int error = mlt_frame_get_image( frame, image, format, width, height, 0 );
115 // Only process if we have no error and a valid colour space
118 // Get values and force accepted ranges
119 double lift = mlt_properties_anim_get_double( properties, "lift", position, length );
120 double gain = mlt_properties_anim_get_double( properties, "gain", position, length );
121 double gamma = mlt_properties_anim_get_double( properties, "gamma", position, length );
122 lift = clamp( lift, -0.5, 0.5 );
123 gain = clamp( gain, -0.5, 0.5 );
124 gamma = clamp( gamma, -1.0, 1.0 );
128 fill_lgg_lut( lgg_lut, lift, gain, gamma);
131 int i = *width * *height + 1;
136 *p ++ = lgg_lut[ *r ++ ];
137 *p ++ = lgg_lut[ *r ++ ];
138 *p ++ = lgg_lut[ *r ++ ];
145 /** Filter processing.
147 static mlt_frame filter_process( mlt_filter filter, mlt_frame frame )
149 // Push the frame filter
150 mlt_frame_push_service( frame, filter );
151 mlt_frame_push_get_image( frame, filter_get_image );
155 /** Constructor for the filter.
157 mlt_filter filter_lumaliftgaingamma_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
159 mlt_filter filter = mlt_filter_new( );
160 if ( filter != NULL )
162 filter->process = filter_process;
163 mlt_properties_set( MLT_FILTER_PROPERTIES( filter ), "lift", "0" );
164 mlt_properties_set( MLT_FILTER_PROPERTIES( filter ), "gain", "0" );
165 mlt_properties_set( MLT_FILTER_PROPERTIES( filter ), "gamma", "0" );