]> git.sesse.net Git - x264/blob - filters/filters.c
x86inc: Improve FMA instruction handling
[x264] / filters / filters.c
1 /*****************************************************************************
2  * filters.c: common filter functions
3  *****************************************************************************
4  * Copyright (C) 2010-2015 x264 project
5  *
6  * Authors: Diogo Franco <diogomfranco@gmail.com>
7  *          Steven Walters <kemuri9@gmail.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
22  *
23  * This program is also available under a commercial proprietary license.
24  * For more information, contact us at licensing@x264.com.
25  *****************************************************************************/
26
27 #include "filters.h"
28 #define RETURN_IF_ERROR( cond, ... ) RETURN_IF_ERR( cond, "options", NULL, __VA_ARGS__ )
29
30 char **x264_split_string( char *string, char *sep, int limit )
31 {
32     if( !string )
33         return NULL;
34     int sep_count = 0;
35     int sep_len = strlen( sep );
36     char *tmp = string;
37     while( ( tmp = ( tmp = strstr( tmp, sep ) ) ? tmp + sep_len : 0 ) )
38         ++sep_count;
39     if( sep_count == 0 )
40     {
41         if( string[0] == '\0' )
42             return calloc( 1, sizeof( char* ) );
43         char **ret = calloc( 2, sizeof( char* ) );
44         ret[0] = strdup( string );
45         return ret;
46     }
47
48     char **split = calloc( ( limit > 0 ? limit : sep_count ) + 2, sizeof(char*) );
49     int i = 0;
50     char *str = strdup( string );
51     assert( str );
52     char *esc = NULL;
53     char *tok = str, *nexttok = str;
54     do
55     {
56         nexttok = strstr( nexttok, sep );
57         if( nexttok )
58             *nexttok++ = '\0';
59         if( ( limit > 0 && i >= limit ) ||
60             ( i > 0 && ( ( esc = strrchr( split[i-1], '\\' ) ) ? esc[1] == '\0' : 0 ) ) ) // Allow escaping
61         {
62             int j = i-1;
63             if( esc )
64                 esc[0] = '\0';
65             split[j] = realloc( split[j], strlen( split[j] ) + sep_len + strlen( tok ) + 1 );
66             assert( split[j] );
67             strcat( split[j], sep );
68             strcat( split[j], tok );
69             esc = NULL;
70         }
71         else
72         {
73             split[i++] = strdup( tok );
74             assert( split[i-1] );
75         }
76         tok = nexttok;
77     } while ( tok );
78     free( str );
79     assert( !split[i] );
80
81     return split;
82 }
83
84 void x264_free_string_array( char **array )
85 {
86     if( !array )
87         return;
88     for( int i = 0; array[i] != NULL; i++ )
89         free( array[i] );
90     free( array );
91 }
92
93 char **x264_split_options( const char *opt_str, const char *options[] )
94 {
95     if( !opt_str )
96         return NULL;
97     char *opt_str_dup = strdup( opt_str );
98     char **split = x264_split_string( opt_str_dup, ",", 0 );
99     free( opt_str_dup );
100     int split_count = 0;
101     while( split[split_count] != NULL )
102         ++split_count;
103
104     int options_count = 0;
105     while( options[options_count] != NULL )
106         ++options_count;
107
108     char **opts = calloc( split_count * 2 + 2, sizeof( char * ) );
109     char **arg = NULL;
110     int opt = 0, found_named = 0, invalid = 0;
111     for( int i = 0; split[i] != NULL; i++, invalid = 0 )
112     {
113         arg = x264_split_string( split[i], "=", 2 );
114         if( arg == NULL )
115         {
116             if( found_named )
117                 invalid = 1;
118             else RETURN_IF_ERROR( i > options_count || options[i] == NULL, "Too many options given\n" )
119             else
120             {
121                 opts[opt++] = strdup( options[i] );
122                 opts[opt++] = strdup( "" );
123             }
124         }
125         else if( arg[0] == NULL || arg[1] == NULL )
126         {
127             if( found_named )
128                 invalid = 1;
129             else RETURN_IF_ERROR( i > options_count || options[i] == NULL, "Too many options given\n" )
130             else
131             {
132                 opts[opt++] = strdup( options[i] );
133                 if( arg[0] )
134                     opts[opt++] = strdup( arg[0] );
135                 else
136                     opts[opt++] = strdup( "" );
137             }
138         }
139         else
140         {
141             found_named = 1;
142             int j = 0;
143             while( options[j] != NULL && strcmp( arg[0], options[j] ) )
144                 ++j;
145             RETURN_IF_ERROR( options[j] == NULL, "Invalid option '%s'\n", arg[0] )
146             else
147             {
148                 opts[opt++] = strdup( arg[0] );
149                 opts[opt++] = strdup( arg[1] );
150             }
151         }
152         RETURN_IF_ERROR( invalid, "Ordered option given after named\n" )
153         x264_free_string_array( arg );
154     }
155     x264_free_string_array( split );
156     return opts;
157 }
158
159 char *x264_get_option( const char *name, char **split_options )
160 {
161     if( !split_options )
162         return NULL;
163     int last_i = -1;
164     for( int i = 0; split_options[i] != NULL; i += 2 )
165         if( !strcmp( split_options[i], name ) )
166             last_i = i;
167     if( last_i >= 0 )
168         return split_options[last_i+1][0] ? split_options[last_i+1] : NULL;
169     return NULL;
170 }
171
172 int x264_otob( char *str, int def )
173 {
174    int ret = def;
175    if( str )
176        ret = !strcasecmp( str, "true" ) ||
177              !strcmp( str, "1" ) ||
178              !strcasecmp( str, "yes" );
179    return ret;
180 }
181
182 double x264_otof( char *str, double def )
183 {
184    double ret = def;
185    if( str )
186    {
187        char *end;
188        ret = strtod( str, &end );
189        if( end == str || *end != '\0' )
190            ret = def;
191    }
192    return ret;
193 }
194
195 int x264_otoi( char *str, int def )
196 {
197     int ret = def;
198     if( str )
199     {
200         char *end;
201         ret = strtol( str, &end, 0 );
202         if( end == str || *end != '\0' )
203             ret = def;
204     }
205     return ret;
206 }
207
208 char *x264_otos( char *str, char *def )
209 {
210     return str ? str : def;
211 }