* 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:
Chris Ross 2000-05-22 03:23:03 +00:00
parent 431278a13c
commit bd5836823e
4 changed files with 215 additions and 191 deletions

View File

@ -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 );
}

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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);