2 * filter_rgblut.c -- generic RGB look-up table filter with string interface
3 * Copyright (C) 2014 Janne Liljeblad
4 * Author: Janne Liljeblad
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 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 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <framework/mlt_filter.h>
22 #include <framework/mlt_frame.h>
23 #include <framework/mlt_tokeniser.h>
30 /** Fill channel lut with integers parsed from property string.
32 static void fill_channel_lut(int lut[], char* channel_table_str)
34 mlt_tokeniser tokeniser = mlt_tokeniser_init();
35 mlt_tokeniser_parse_new( tokeniser, channel_table_str, ";" );
37 // Only create lut from string if tokens count exactly right
38 if ( tokeniser->count == 256 )
40 // Fill lut with token values
43 for( i = 0; i < 256; i++ )
45 val = atoi(tokeniser->tokens[i]);
51 // Fill lut with linear no-op table
53 for( i = 0; i < 256; i++ )
58 mlt_tokeniser_close( tokeniser );
63 static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
66 mlt_filter filter = mlt_frame_pop_service( this );
68 *format = mlt_image_rgb24;
69 int error = mlt_frame_get_image( this, image, format, width, height, 0 );
71 // Only process if we have no error and a valid colour space
74 // Create lut tables from properties for each RGB channel
75 char* r_str = mlt_properties_get( MLT_FRAME_PROPERTIES( this ), "R_table" );
77 fill_channel_lut( r_lut, r_str );
79 char* g_str = mlt_properties_get( MLT_FRAME_PROPERTIES( this ), "G_table" );
81 fill_channel_lut( g_lut, g_str );
83 char* b_str = mlt_properties_get( MLT_FRAME_PROPERTIES( this ), "B_table" );
85 fill_channel_lut( b_lut, b_str );
87 // Apply look-up tables into image
88 int i = *width * *height + 1;
93 *p ++ = r_lut[ *r ++ ];
94 *p ++ = g_lut[ *r ++ ];
95 *p ++ = b_lut[ *r ++ ];
102 /** Filter processing.
105 static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
107 char* r_table = mlt_properties_get( MLT_FILTER_PROPERTIES( this ), "R_table" );
108 char* g_table = mlt_properties_get( MLT_FILTER_PROPERTIES( this ), "G_table" );
109 char* b_table = mlt_properties_get( MLT_FILTER_PROPERTIES( this ), "B_table" );
111 mlt_properties_set( MLT_FRAME_PROPERTIES( frame ), "R_table", r_table );
112 mlt_properties_set( MLT_FRAME_PROPERTIES( frame ), "G_table", g_table );
113 mlt_properties_set( MLT_FRAME_PROPERTIES( frame ), "B_table", b_table );
115 // Push the frame filter
116 mlt_frame_push_service( frame, this );
117 mlt_frame_push_get_image( frame, filter_get_image );
121 /** Constructor for the filter.
124 mlt_filter filter_rgblut_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
126 mlt_filter this = mlt_filter_new( );
129 this->process = filter_process;
130 mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "R_table", "unset" );
131 mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "G_table", "unset" );
132 mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "B_table", "unset" );