forked from old/legacy-imlib2
* rewrite of the script parser, basically you can now parser a filter as a
variable to another filter as willem requested the other day. eg. filter( var=anotherfilter( var=13,var=30 ), var=blum ); youcan have as manylevels of filters as you want. * parser should be quicker, no need to add "NULL" to the end of a imlib_apply_filter() command. * some more funky filters should be added soon, at 4.45am i decided to leave that job till t/m. SVN revision: 2686
This commit is contained in:
parent
431278a13c
commit
bd5836823e
|
@ -2442,7 +2442,6 @@ void imlib_apply_filter( char *script, ... )
|
|||
__imlib_dynamic_filters_init();
|
||||
CAST_IMAGE(im, ctxt_image);
|
||||
va_start( param_list, script );
|
||||
func = __imlib_script_parse( im, script, param_list );
|
||||
__imlib_script_parse( im, script, param_list );
|
||||
va_end( param_list );
|
||||
__imlib_script_tidyup( func );
|
||||
}
|
||||
|
|
381
src/script.c
381
src/script.c
|
@ -21,6 +21,15 @@
|
|||
/*
|
||||
#define FDEBUG 1
|
||||
*/
|
||||
#ifdef FDEBUG
|
||||
# define D( str ) printf( "DEBUG: %s\n", str )
|
||||
#else
|
||||
#define D( str )
|
||||
#endif
|
||||
|
||||
IVariable *vars, *current_var, *curtail;
|
||||
|
||||
|
||||
int __imlib_find_string( char *haystack, char *needle )
|
||||
{
|
||||
if( strstr( haystack, needle ) != NULL )
|
||||
|
@ -37,7 +46,7 @@ char *__imlib_stripwhitespace( char *str )
|
|||
if( str[i] == '\"' )
|
||||
in_quote = (in_quote == 0 ? 1 : 0);
|
||||
if( in_quote || ! isspace(*(str+i)) )
|
||||
tmpstr[strt++] = str[i];
|
||||
tmpstr[strt++] = str[i];
|
||||
}
|
||||
strcpy( str, tmpstr );
|
||||
free(tmpstr);
|
||||
|
@ -57,197 +66,203 @@ char *__imlib_copystr( char *str, int start, int end )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
pIFunctionParam __imlib_parse_param( char *param )
|
||||
{
|
||||
int i;
|
||||
|
||||
IFunctionParam *ptr;
|
||||
if( param != NULL )
|
||||
{
|
||||
ptr = malloc( sizeof( IFunctionParam ) );
|
||||
i = __imlib_find_string(param,"=");
|
||||
if( i > 0 )
|
||||
{
|
||||
ptr->key = __imlib_copystr(param, 0, i-1);
|
||||
ptr->type = 1;
|
||||
if( param[i+1] == '\"' )
|
||||
ptr->data = (void *)__imlib_copystr(param, i+2, strlen(param)-2);
|
||||
else
|
||||
ptr->data = (void *)__imlib_copystr(param, i+1, strlen(param)-1);
|
||||
#ifdef FDEBUG
|
||||
printf( "DEBUG: -> param [%s]=\"%s\"\n", ptr->key, (char *)ptr->data );
|
||||
#endif /* FDEBUG */
|
||||
ptr->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr->key = strdup(param);
|
||||
ptr->data = strdup( "" );
|
||||
ptr->type = VAR_CHAR;
|
||||
#ifdef FDEBUG
|
||||
printf( "DEBUG: -> s_param [%s]=\"%s\"\n", ptr->key, (char *)ptr->data );
|
||||
#endif
|
||||
ptr->next = NULL;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pIFunction __imlib_parse_function( char *func )
|
||||
{
|
||||
int i = 0, in_quote=0, start=0;
|
||||
IFunction *ptrfunc = malloc( sizeof( IFunction ) );
|
||||
IFunctionParam *ptrparam = NULL;
|
||||
char *tmpbuf;
|
||||
|
||||
if( func != NULL )
|
||||
{
|
||||
func = __imlib_stripwhitespace( func );
|
||||
ptrfunc->name = __imlib_copystr( func, 0, __imlib_find_string( func, "(" ) - 1 );
|
||||
#ifdef FDEBUG
|
||||
printf( "DEBUG: Function name: \"%s\"\n", ptrfunc->name );
|
||||
#endif /* FDEBUG */
|
||||
|
||||
ptrfunc->params = malloc( sizeof( IFunctionParam ) );
|
||||
ptrfunc->params->key = strdup("");
|
||||
ptrfunc->params->data = strdup("");
|
||||
ptrfunc->params->type = VAR_CHAR;
|
||||
ptrfunc->params->next = NULL;
|
||||
ptrparam = ptrfunc->params;
|
||||
|
||||
start = __imlib_find_string( func, "(" ) + 1;
|
||||
for( i = start; i < strlen(func); i++ )
|
||||
{
|
||||
if( func[i] == '\"' )
|
||||
in_quote = (in_quote == 0 ? 1 : 0);
|
||||
if( !in_quote && (func[i] == ',' || func[i] == ')') )
|
||||
{
|
||||
tmpbuf = __imlib_copystr( func, start, i-1 );
|
||||
ptrparam->next = __imlib_parse_param( tmpbuf );
|
||||
if( ptrparam->next != NULL )
|
||||
ptrparam = ptrparam->next;
|
||||
start = i+1;
|
||||
if( tmpbuf && tmpbuf != NULL ) free(tmpbuf);
|
||||
}
|
||||
}
|
||||
free( func );
|
||||
}
|
||||
else
|
||||
{
|
||||
ptrfunc->name = strdup( "root-function" );
|
||||
ptrfunc->params = NULL;
|
||||
}
|
||||
ptrfunc->next = NULL;
|
||||
return ptrfunc;
|
||||
}
|
||||
|
||||
pIFunction __imlib_script_parse( Imlib_Image im, char *script, va_list param_list )
|
||||
{
|
||||
int i = 0, in_quote = 0, start = 0, hit_null = 0;
|
||||
IFunction *ptr = __imlib_parse_function( NULL ), *tmp_fptr = NULL;
|
||||
IFunction *rptr = ptr;
|
||||
IFunctionParam *tmp_pptr;
|
||||
pImlibExternalFilter filter;
|
||||
void *tmpptr;
|
||||
|
||||
#ifdef FDEBUG
|
||||
printf( "DEBUG: Imlib Script Parser Start.\n" );
|
||||
#endif
|
||||
|
||||
if( script != NULL )
|
||||
{
|
||||
/* scan the script line */
|
||||
for( i = 0; i < strlen(script); i++ )
|
||||
{
|
||||
if( script[i] == '\"' )
|
||||
in_quote = (in_quote == 0 ? 1 : 0);
|
||||
if( ! in_quote && script[i] == ';' )
|
||||
{
|
||||
ptr->next = __imlib_parse_function( __imlib_copystr( script, start, i-1 ) );
|
||||
ptr = ptr->next;
|
||||
/* righty now we need to traverse the whole of the function tree and see if we have hit
|
||||
* any [], if we have replace it with the next var off the list update the pointer, luverly
|
||||
* jubly */
|
||||
for( tmp_pptr = ptr->params; tmp_pptr != NULL; tmp_pptr = tmp_pptr->next )
|
||||
{
|
||||
if( strcmp( (char *)(tmp_pptr->data), "[]" ) == 0 )
|
||||
{
|
||||
if( !hit_null )
|
||||
tmpptr = va_arg( param_list, void *);
|
||||
else
|
||||
tmpptr = NULL;
|
||||
|
||||
if( tmpptr == NULL )
|
||||
{
|
||||
#ifdef FDEBUG
|
||||
printf( "DEBUG: WARNING: We have hit a null. (dyn_filter.c)\n" );
|
||||
#endif
|
||||
hit_null = 1;
|
||||
}
|
||||
#ifdef FDEBUG
|
||||
printf( "Setting %s::%s to a pointer.\n", ptr->name, tmp_pptr->key );
|
||||
#endif
|
||||
tmp_pptr->type = VAR_PTR;
|
||||
tmp_pptr->data = ( tmpptr != NULL ? tmpptr : NULL );
|
||||
#ifdef FDEBUG
|
||||
printf( "%p\n", tmp_pptr->data );
|
||||
#endif
|
||||
}
|
||||
/* for more funcky stuff in the furutre
|
||||
* if( strlen( (char *)(tmp_pptr->data) ) == 0 )
|
||||
* {
|
||||
* free( tmp_pptr->data );
|
||||
* tmp_pptr->data = __imlib_script_get_variable( tmp_pptr->key );
|
||||
* }
|
||||
*/
|
||||
}
|
||||
/* excutre the filter */
|
||||
filter = __imlib_get_dynamic_filter( ptr->name );
|
||||
if( filter != NULL )
|
||||
{
|
||||
#ifdef FDEBUG
|
||||
printf( "Executing Filter %s\n", ptr->name );
|
||||
#endif
|
||||
im = filter->exec_filter( ptr->name, im, ptr->params );
|
||||
imlib_context_set_image( im );
|
||||
}
|
||||
start = i+1;
|
||||
}
|
||||
}
|
||||
#ifdef FDEBUG
|
||||
printf( "DEBUG: Imlib Script Parser End.\n" );
|
||||
#endif
|
||||
return rptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef FDEBUG
|
||||
printf( "DEBUG: Imlib Script Parser End. (!!)\n" );
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void __imlib_script_tidyup_params( IFunctionParam *param )
|
||||
{
|
||||
if( param->next ){
|
||||
__imlib_script_tidyup_params( param->next );
|
||||
__imlib_script_tidyup_params( param->next );
|
||||
}
|
||||
free( param->key );
|
||||
if( param->type == VAR_CHAR )
|
||||
free( param->data );
|
||||
free( param );
|
||||
}
|
||||
|
||||
void __imlib_script_tidyup( IFunction *func )
|
||||
{
|
||||
if( func->next != NULL )
|
||||
__imlib_script_tidyup( func->next );
|
||||
|
||||
if( func->params != NULL )
|
||||
__imlib_script_tidyup_params( func->params );
|
||||
IFunctionParam *__imlib_script_parse_parameters( Imlib_Image im, char *parameters )
|
||||
{
|
||||
int i = 0, in_quote = 0, depth=0, start=0, value_start=0;
|
||||
char *key = NULL, *value = NULL;
|
||||
IFunctionParam *rootptr, *ptr;
|
||||
|
||||
free( func->name );
|
||||
free( func );
|
||||
D( "(--) ===> Entering __imlib_script_parse_parameters()" );
|
||||
|
||||
rootptr = malloc( sizeof( IFunctionParam ) );
|
||||
rootptr->key = strdup( "NO-KEY" );
|
||||
rootptr->type = 0;
|
||||
rootptr->data = strdup( "NO-VALUE" );
|
||||
rootptr->next = NULL;
|
||||
ptr = rootptr;
|
||||
|
||||
for( i = 0; i <= strlen( parameters ); i++ )
|
||||
{
|
||||
if( parameters[i] == '\"' )
|
||||
in_quote = (in_quote == 0 ? 1 : 0);
|
||||
if( !in_quote && parameters[i] == '(' ) depth++;
|
||||
if( !in_quote && parameters[i] == ')' ) depth--;
|
||||
if( !in_quote && parameters[i] == '=' && depth == 0) value_start=i+1;
|
||||
if( !in_quote && (parameters[i] == ',' || i == (strlen(parameters))) && depth == 0 )
|
||||
{
|
||||
ptr->next = malloc( sizeof( IFunctionParam ) );
|
||||
ptr = ptr->next;
|
||||
ptr->key = __imlib_copystr( parameters, start, value_start - 2 );
|
||||
value = __imlib_copystr( parameters, value_start, i-1 );
|
||||
#ifdef FDEBUG
|
||||
printf( "DEBUG: (--) --> Variable \"%s\" = \"%s\"\n", ptr->key, value );
|
||||
#endif
|
||||
if( __imlib_find_string( value, "(" ) < __imlib_find_string( value, "\"" ) )
|
||||
{
|
||||
D( "(--) Found a function" );
|
||||
ptr->data = __imlib_script_parse_function( im, value );
|
||||
ptr->type = VAR_PTR;
|
||||
free( value );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( strcmp( value, "[]" ) == 0 )
|
||||
{
|
||||
ptr->data = __imlib_script_get_next_var();
|
||||
if( ptr->data == NULL )
|
||||
D( "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEK" );
|
||||
/* printf( "Using pointer variable %p\n", ptr->data );*/
|
||||
ptr->type = VAR_PTR;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr->data = value;
|
||||
ptr->type = VAR_CHAR;
|
||||
}
|
||||
}
|
||||
ptr->next = NULL;
|
||||
start = i+1;
|
||||
}
|
||||
}
|
||||
D( "(--) <=== Leaving __imlib_script_parse_parameters()" );
|
||||
return rootptr;
|
||||
}
|
||||
|
||||
Imlib_Image __imlib_script_parse_function( Imlib_Image im, char *function )
|
||||
{
|
||||
char *funcname, *funcparams;
|
||||
IFunctionParam *params;
|
||||
ImlibExternalFilter *filter = NULL;
|
||||
Imlib_Image retval;
|
||||
|
||||
D( "(--) ===> Entering __imlib_script_parse_function()" );
|
||||
funcname = __imlib_copystr( function, 0, __imlib_find_string( function, "(" ) - 1 );
|
||||
funcparams = __imlib_copystr( function, __imlib_find_string( function, "(" ) + 1, strlen(function)-2 );
|
||||
#ifdef FDEBUG
|
||||
printf( "DEBUG: (??) = function <%s>( \"%s\" )\n", funcname, funcparams );
|
||||
#endif
|
||||
params = __imlib_script_parse_parameters( im, funcparams );
|
||||
/* excute the filter */
|
||||
filter = __imlib_get_dynamic_filter( funcname );
|
||||
if( filter != NULL )
|
||||
{
|
||||
#ifdef FDEBUG
|
||||
printf( "DEBUG: (--) Executing Filter \"%s\".\n", funcname );
|
||||
#endif
|
||||
retval = filter->exec_filter( funcname, im, params );
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef FDEBUG
|
||||
printf( "DEBUG: (!!) Can't find filter \"%s\", returning given image.\n", funcname );
|
||||
#endif
|
||||
retval = im;
|
||||
}
|
||||
D( "Get Here" );
|
||||
/* clean up params */
|
||||
free( funcname );
|
||||
free( funcparams );
|
||||
__imlib_script_tidyup_params( params );
|
||||
D( "(--) <=== Leaving __imlib_script_parse_function()" );
|
||||
return retval;
|
||||
}
|
||||
|
||||
Imlib_Image __imlib_script_parse( Imlib_Image im, char *script, va_list param_list )
|
||||
{
|
||||
int i = 0, in_quote = 0, start = 0, depth = 0;
|
||||
char *scriptbuf = NULL, *function, *paramstr;
|
||||
IFunction *func = NULL;
|
||||
IFunctionParam *params = NULL;
|
||||
|
||||
D( "(--) Script Parser Start." );
|
||||
if( script != NULL && strlen(script) > 0 )
|
||||
{
|
||||
vars = malloc( sizeof( IVariable ) );
|
||||
vars->ptr = NULL;
|
||||
vars->next = NULL;
|
||||
curtail = vars;
|
||||
current_var = vars;
|
||||
/* gather up variable from the command line */
|
||||
D( "(--) String Whitespace from script." );
|
||||
scriptbuf = __imlib_stripwhitespace( strdup( script ) );
|
||||
|
||||
i = __imlib_find_string( scriptbuf+start, "=[]") - 1;
|
||||
while( i > 0 )
|
||||
{
|
||||
__imlib_script_add_var( va_arg( param_list, void * ) );
|
||||
start = start+i+2;
|
||||
i = __imlib_find_string( scriptbuf+start, "=[]") - 1;
|
||||
i = ( i == 0 ? 0 : i );
|
||||
D( "(??) Found pointer variable" );
|
||||
}
|
||||
|
||||
start = 0;
|
||||
i = 0;
|
||||
for( i = 0; i < strlen( scriptbuf ); i++ )
|
||||
{
|
||||
if( script[i] == '\"' )
|
||||
in_quote = (in_quote == 0 ? 1 : 0);
|
||||
if( !in_quote && script[i] == '(' ) depth++;
|
||||
if( !in_quote && script[i] == ')' ) depth--;
|
||||
if( !in_quote && (script[i] == ';') && depth == 0 )
|
||||
{
|
||||
function = __imlib_copystr( scriptbuf, start, i-1 );
|
||||
im = __imlib_script_parse_function( im, function );
|
||||
imlib_context_set_image( im );
|
||||
start = i+1;
|
||||
free( function );
|
||||
}
|
||||
}
|
||||
D( "(--) Cleaning up parameter list" );
|
||||
__imlib_script_tidyup();
|
||||
D( "(--) Script Parser Successful." );
|
||||
free( scriptbuf );
|
||||
return im;
|
||||
}
|
||||
else
|
||||
{
|
||||
D( "(!!) Script Parser Failed." );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void __imlib_script_delete_variable( IVariable *var )
|
||||
{
|
||||
if( var->next != NULL )
|
||||
__imlib_script_delete_variable( var->next );
|
||||
free( var );
|
||||
}
|
||||
|
||||
void __imlib_script_tidyup()
|
||||
{
|
||||
__imlib_script_delete_variable( vars );
|
||||
}
|
||||
|
||||
void *__imlib_script_get_next_var()
|
||||
{
|
||||
if( current_var != NULL )
|
||||
current_var = current_var->next;
|
||||
if( current_var != NULL )
|
||||
return current_var->ptr;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void __imlib_script_add_var( void *ptr )
|
||||
{
|
||||
curtail->next = malloc( sizeof( IVariable ) );
|
||||
curtail = curtail->next;
|
||||
curtail->ptr = ptr;
|
||||
curtail->next = NULL;
|
||||
}
|
||||
|
|
15
src/script.h
15
src/script.h
|
@ -27,6 +27,17 @@ struct _imlib_function
|
|||
pIFunction next;
|
||||
};
|
||||
|
||||
pIFunction __imlib_script_parse( Imlib_Image im, char *script, va_list );
|
||||
void __imlib_script_tidyup( IFunction *func );
|
||||
typedef struct _imlib_variable
|
||||
{
|
||||
void *ptr;
|
||||
struct _imlib_variable *next;
|
||||
} IVariable;
|
||||
|
||||
Imlib_Image __imlib_script_parse( Imlib_Image im, char *script, va_list );
|
||||
IFunctionParam *__imlib_script_parse_parameters( Imlib_Image im, char *parameters );
|
||||
Imlib_Image __imlib_script_parse_function( Imlib_Image im, char *function );
|
||||
void __imlib_script_tidyup();
|
||||
void *__imlib_script_get_next_var();
|
||||
void __imlib_script_add_var( void *ptr );
|
||||
|
||||
#endif /* _FUNCTION_H_ */
|
||||
|
|
|
@ -746,9 +746,9 @@ int main (int argc, char **argv)
|
|||
|
||||
}
|
||||
if( bump_map_to_point )
|
||||
imlib_apply_filter("bump_map_to_point(x=[],y=[],map=test_images/bulb.png);", &x, &y, NULL);
|
||||
imlib_apply_filter("bump_map_point(x=[],y=[],map=test_images/bulb.png);", &x, &y );
|
||||
else
|
||||
imlib_apply_filter("bump_map(x=[],y=[],map=test_images/bulb.png);", &x, &y, NULL);
|
||||
imlib_apply_filter("bump_map(x=[],y=[],map=test_images/bulb.png);", &x, &y );
|
||||
|
||||
up = imlib_update_append_rect(up, 0, 0,
|
||||
imlib_image_get_width(),
|
||||
|
@ -844,8 +844,7 @@ int main (int argc, char **argv)
|
|||
}
|
||||
imlib_apply_filter( "tint(x=200,y=200,w=300,h=100,alpha=100,red=155,green=25,blue=25);"\
|
||||
"tint(green=20,red=20,blue=20,alpha=200,x=30,y=30);" \
|
||||
"tint(green=40,red=40,blue=240,alpha=60,x=50,y=150,h=200);",
|
||||
NULL );
|
||||
"tint(green=40,red=40,blue=240,alpha=60,x=50,y=150,h=200);" );
|
||||
|
||||
imlib_blend_image_onto_image(im_sh1, 0, 0, 0, 50, 50, 0, 0, 50, 50);
|
||||
up = imlib_update_append_rect(up, 0, 0, 50, 50);
|
||||
|
|
Loading…
Reference in New Issue