bowis's filter stuff... :)

SVN revision: 2673
This commit is contained in:
Carsten Haitzler 2000-05-20 17:37:00 +00:00
parent e28f0b22e3
commit caa073ee7b
12 changed files with 659 additions and 4 deletions

View File

@ -9,7 +9,7 @@ MAINTAINERCLEANFILES = INSTALL Makefile.in aclocal.m4 config.guess \
ltconfig ltmain.sh missing mkinstalldirs \
stamp-h.in
SUBDIRS = libltdl loaders src
SUBDIRS = libltdl loaders src filters
EXTRA_DIST = \
imlib2.spec \

View File

@ -117,5 +117,5 @@ AC_MSG_ERROR([Fatal Error: no FreeType header files detected.])
fi
fi
AC_OUTPUT(Makefile loaders/Makefile src/Makefile test/Makefile demo/Makefile,
AC_OUTPUT(Makefile loaders/Makefile src/Makefile test/Makefile filters/Makefile demo/Makefile,
[test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h])

19
filters/Makefile.am Normal file
View File

@ -0,0 +1,19 @@
## Process this file with automake to produce Makefile.in
AUTOMAKE_OPTIONS = 1.4 foreign
# A list of all the files in the current directory which can be regenerated
MAINTAINERCLEANFILES = Makefile.in
LDFLAGS = -L/usr/X11R6/lib
INCLUDES = -I/usr/X11R6/include -I$(top_srcdir)/libltdl \
$(X_CFLAGS) -I$(prefix)/include -I$(includedir) \
-I. -I$(top_srcdir) -I$(top_srcdir)/src \
-I$(top_srcdir)/loaders
pkgdir = $(libdir)/loaders/filter
pkg_LTLIBRARIES = testfilter.la
testfilter_la_SOURCES = filter_test.c
testfilter_la_LDFLAGS = -no-undefined -module -avoid-version
testfilter_la_LIBADD =

99
filters/filter_test.c Normal file
View File

@ -0,0 +1,99 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "common.h"
#include <string.h>
#include <X11/Xlib.h>
#include <X11/extensions/XShm.h>
#include <X11/Xutil.h>
#include "Imlib2.h"
#include "image.h"
#include "script.h"
#include "dynamic_filters.h"
void init( struct imlib_filter_info *info );
void deinit();
void *exec( char *filter, void *im, pIFunctionParam params );
void init( struct imlib_filter_info *info )
{
char *filters[] = { "tint", "cool_text" };
int i = 0;
info->num_filters = 2;
info->filters = malloc(sizeof(char *)*2);
for (i = 0; i < info->num_filters; i++)
info->filters[i] = strdup(filters[i]);
}
void deinit()
{
return;
}
void *exec( char *filter, void *im, pIFunctionParam params )
{
Imlib_Image imge = im;
Imlib_Image anoim;
IFunctionParam *ptr;
if( strcmp( filter, "tint" ) == 0 )
{
Imlib_Color_Modifier cm;
DATA8 atab[256];
int x = 0, y = 0, w = 100, h = 100;
DATA8 r = 255, b = 255, g = 255, a = 255;
/*
printf( "filter_test.c: tint called\n" );
*/
#define ASSIGN_DATA8_VALUE( var, v ) if( strcmp( ptr->key, var ) == 0 ) v = (DATA8)atoi( (char *)ptr->data )
#define ASSIGN_VALUE( var, v ) if( strcmp( ptr->key, var ) == 0 ) v = atoi( (char *)ptr->data )
for( ptr = params; ptr != NULL; ptr = ptr->next )
{
ASSIGN_DATA8_VALUE( "red", r );
ASSIGN_DATA8_VALUE( "blue", b );
ASSIGN_DATA8_VALUE( "green", g );
ASSIGN_VALUE( "x", x );
ASSIGN_VALUE( "y", y );
ASSIGN_VALUE( "w", w );
ASSIGN_VALUE( "h", h );
ASSIGN_DATA8_VALUE( "alpha", a );
}
/*
printf( "Using values red=%d,blue=%d,green=%d,x=%d,y=%d,height=%d,width=%d,alpha=%d\n", r,b,g,x,y,w,h,a );
*/
anoim = imlib_create_image( w, h );
cm = imlib_create_color_modifier();
imlib_context_set_color_modifier(cm);
imlib_context_set_image(anoim);
imlib_context_set_color(r, g, b, 255);
imlib_image_fill_rectangle(0, 0, w, h);
imlib_context_set_blend(1);
imlib_image_set_has_alpha(1);
memset(atab, a, sizeof(atab));
imlib_set_color_modifier_tables(NULL, NULL, NULL, atab);
imlib_apply_color_modifier_to_rectangle(0, 0, w, h);
imlib_context_set_image( imge );
imlib_blend_image_onto_image( anoim, 0, 0, 0, w, h, x, y, w, h);
imlib_free_color_modifier();
imlib_context_set_image(anoim);
imlib_free_image_and_decache();
imlib_context_set_image(imge);
return imge;
}
if( strcmp( filter, "cool_text" ) == 0 )
{
return imge;
}
}

View File

@ -268,6 +268,8 @@ void imlib_filter_set_green(int xoff, int yoff, int a, int r, int g, int b);
void imlib_filter_set_blue(int xoff, int yoff, int a, int r, int g, int b);
void imlib_filter_constants(int a, int r, int g, int b);
void imlib_filter_divisors(int a, int r, int g, int b);
Imlib_Image imlib_apply_filter( char *script, ... );
/* need to add polygon fill code */

View File

@ -16,11 +16,11 @@ include_HEADERS = Imlib2.h
libImlib2_la_SOURCES = rend.c ximage.c scale.c rgba.c image.c color.c grab.c \
blend.c file.c rgbadraw.c api.c draw.c context.c \
updates.c colormod.c font.c format.c grad.c rotate.c \
filter.c \
filter.c script.c dynamic_filters.c \
Imlib2.h image.h scale.h blend.h context.h updates.h \
color.h draw.h rend.h ximage.h colormod.h file.h \
rgba.h common.h grab.h rgbadraw.h font.h format.h \
rotate.h grad.h filter.h \
rotate.h grad.h filter.h script.h dynamic_filters.h \
asm_blend.S asm_rgba.S asm_scale.S asm_rotate.S \
asm_blend_cmod.S
libImlib2_la_LIBADD = @DLLDFLAGS@ $(top_builddir)/libltdl/libltdlc.la \

View File

@ -3,6 +3,7 @@
#include <X11/Xutil.h>
#include <X11/extensions/shape.h>
#include <string.h>
#include <stdarg.h>
#include "common.h"
#include "colormod.h"
#include "image.h"
@ -28,6 +29,8 @@
#include "grad.h"
#include "rotate.h"
#include "filter.h"
#include "dynamic_filters.h"
#include "script.h"
#include <math.h>
/* convenience macros */
@ -2428,3 +2431,31 @@ imlib_filter_divisors(int a, int r, int g, int b)
CHECK_PARAM_POINTER("imlib_filter_divisors", "filter", ctxt_filter);
__imlib_FilterDivisors((ImlibFilter *)ctxt_filter, a, r, g, b);
}
Imlib_Image imlib_apply_filter( char *script, ... )
{
Imlib_Image im;
IFunction *func = NULL, *ptr;
va_list param_list;
pImlibExternalFilter filter;
__imlib_dynamic_filters_init();
CAST_IMAGE(im, ctxt_image);
va_start( param_list, script );
func = (IFunction *)__imlib_script_parse( script, param_list );
va_end( param_list );
for( ptr = func->next; ptr != NULL; ptr = ptr->next )
{
filter = __imlib_get_dynamic_filter( ptr->name );
if( filter != NULL )
{
im = filter->exec_filter( ptr->name, im, ptr->params );
imlib_context_set_image( im );
}
}
__imlib_script_tidyup( func );
return im;
}

194
src/dynamic_filters.c Normal file
View File

@ -0,0 +1,194 @@
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
#include <X11/Xlib.h>
#include "image.h"
#include "file.h"
#include "dynamic_filters.h"
#include "script.h"
#include "loaderpath.h"
pImlibExternalFilter filters = NULL;
int dyn_initialised = 0;
#define MALLOCSHOW
#define FREESHOW
/*
#define FDEBUG
*/
pImlibExternalFilter __imlib_LoadFilter( char *file )
{
ImlibExternalFilter *ptr;
struct imlib_filter_info *info;
int i = 0;
printf( "Loading filter %s\n", file );
MALLOCSHOW;
ptr = malloc( sizeof( ImlibExternalFilter ) );
ptr->filename = strdup(file);
ptr->handle = lt_dlopenext(file);
if( !ptr->handle )
{
FREESHOW;
free( ptr->filename );
FREESHOW;
free( ptr );
return NULL;
}
ptr->init_filter = lt_dlsym( ptr->handle, "init" );
ptr->deinit_filter = lt_dlsym( ptr->handle, "deinit" );
ptr->exec_filter = lt_dlsym( ptr->handle, "exec" );
if( !ptr->init_filter || !ptr->deinit_filter || !ptr->exec_filter )
{
lt_dlclose( ptr->handle );
FREESHOW;
free( ptr->filename );
FREESHOW;
free( ptr );
return NULL;
}
info = malloc( sizeof( struct imlib_filter_info ) );
ptr->init_filter( info );
ptr->num_filters = info->num_filters;
ptr->filters = info->filters;
free( info );
#ifdef FDEBUG
printf( "Filter has %d filters in it.\n", ptr->num_filters );
for( i = 0; i < ptr->num_filters; i++ )
printf( " -> \"%s\"\n", ptr->filters[i] );
#endif
ptr->next = NULL;
return ptr;
}
void __imlib_dynamic_filters_init()
{
char **list;
int num_filters, i = 0;
ImlibExternalFilter *ptr, *tptr;
if( ! dyn_initialised )
{
MALLOCSHOW;
filters = malloc( sizeof( ImlibExternalFilter ) );
filters->filename = "";
filters->next = NULL;
ptr = filters;
#ifdef FDEBUG
printf( "DEBUG: Dynamic filters Initisialising\n" );
#endif
dyn_initialised = 1;
#ifdef FDEBUG
printf( "DEBUG: Loading Filters\n" );
#endif
list = __imlib_ListFilters( &num_filters );
for( i = num_filters - 1; i >= 0; i -- )
{
tptr = NULL;
if((tptr = __imlib_LoadFilter( list[i] )) != NULL )
{
ptr->next = tptr;
ptr = ptr->next;
}
if( list[i] ){
FREESHOW;
free( list[i] );
}
}
FREESHOW;
if( list )
free( list );
}
}
void __imlib_dynamic_filters_deinit()
{
}
pImlibExternalFilter __imlib_get_dynamic_filter( char *name )
{
pImlibExternalFilter f_ptr;
int i = 0;
/* scan the filters */
for( f_ptr = filters->next; f_ptr != NULL; f_ptr = f_ptr->next )
{
/* scan the methods provided */
for( i = 0; i < f_ptr->num_filters; i++ )
{
if( strcmp( f_ptr->filters[i], name ) == 0 )
{
#ifdef FDEBUG
printf( "DEBUG: Found filter \"%s\"\n", name );
#endif
return f_ptr;
}
}
}
return NULL;
}
/* loader dir */
char **__imlib_ListFilters(int *num_ret)
{
char **list = NULL, **l, s[4096], *home;
int num, i, pi = 0;
*num_ret = 0;
/* get the user's home dir */
home = __imlib_FileHomeDir(getuid());
sprintf(s, "%s/" USER_LOADERS_PATH "/filter", home);
/* list the dir contents of their loader dir */
l = __imlib_FileDir(s, &num);
/* if theres files */
if (num > 0)
{
/* make a list of them */
*num_ret += num;
list = malloc(sizeof(char *) * *num_ret);
for (i = 0; i < num; i++)
{
sprintf(s, "%s/" USER_LOADERS_PATH "/filter/%s", home, l[i]);
list[i] = strdup(s);
}
pi = i;
__imlib_FileFreeDirList(l, num);
}
/* same for system loader path */
sprintf(s, SYS_LOADERS_PATH "/filter");
l = __imlib_FileDir(s, &num);
if (num > 0)
{
*num_ret += num;
list = realloc(list, sizeof(char *) * *num_ret);
for (i = 0; i < num; i++)
{
sprintf(s, SYS_LOADERS_PATH "/filter/%s", l[i]);
list[pi + i] = strdup(s);
}
__imlib_FileFreeDirList(l, num);
}
free(home);
/* List currently contains *everything in there* we need to weed out
* the .so, .la, .a versions of the same loader or whatever else.
* lt_dlopen can take an extension-less name and do the Right Thing
* with it, so that's what we'll give it. */
list = __imlib_TrimLoaderList(list, num_ret);
return list;
}

38
src/dynamic_filters.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef _DYNAMIC_FILTERS_H_
#define _DYNAMIC_FILTERS_H_
#include "script.h"
struct imlib_filter_info
{
char **filters;
int num_filters;
};
typedef struct _imlib_external_filter ImlibExternalFilter;
typedef struct _imlib_external_filter *pImlibExternalFilter;
struct _imlib_external_filter
{
int num_filters;
char *filename;
void *handle;
char **filters;
void (*init_filter)( struct imlib_filter_info *info );
void (*deinit_filter)();
void *(*exec_filter)( char *filter, void *im, pIFunctionParam params );
pImlibExternalFilter next;
};
void __imlib_dynamic_filters_init();
void __imlib_dynamic_filters_deinit();
pImlibExternalFilter __imlib_get_dynamic_filter( char *name );
char **__imlib_ListFilters(int *num_ret);
pImlibExternalFilter __imlib_LoadFilter( char *file );
#endif

237
src/script.c Normal file
View File

@ -0,0 +1,237 @@
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
#include <X11/Xlib.h>
#include "image.h"
#include "file.h"
#include "script.h"
#include "loaderpath.h"
/*
#define FDEBUG 1
*/
int find_string( char *haystack, char *needle )
{
if( strstr( haystack, needle ) != NULL )
return ( strstr( haystack, needle ) - haystack );
return 0;
}
char *stripwhitespace( char *str )
{
int i, strt = 0, in_quote = 0;
char *tmpstr = calloc( strlen(str)+1, sizeof(char) );
for( i = 0; i < strlen(str); i++ )
{
if( str[i] == '\"' )
in_quote = (in_quote == 0 ? 1 : 0);
if( in_quote || ! isspace(*(str+i)) )
tmpstr[strt++] = str[i];
}
strcpy( str, tmpstr );
free(tmpstr);
return str;
}
char *copystr( char *str, int start, int end )
{
int i = 0;
char *rstr = calloc( 1024, sizeof( char ) );
if( start <= end && end < strlen( str ) )
{
for( i = start; i <= end; i++ )
rstr[i-start] = str[i];
return rstr;
}
return NULL;
}
pIFunctionParam parse_param( char *param )
{
int i;
IFunctionParam *ptr;
if( param != NULL )
{
ptr = malloc( sizeof( IFunctionParam ) );
i = find_string(param,"=");
if( i > 0 )
{
ptr->key = copystr(param, 0, i-1);
ptr->type = 1;
if( param[i+1] == '\"' )
ptr->data = (void *)copystr(param, i+2, strlen(param)-2);
else
ptr->data = (void *)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;
printf( "DEBUG: -> s_param [%s]=\"%s\"\n", ptr->key, (char *)ptr->data );
ptr->next = NULL;
}
return ptr;
}
return NULL;
}
pIFunction 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 = stripwhitespace( func );
ptrfunc->name = copystr( func, 0, 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 = 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 = copystr( func, start, i-1 );
ptrparam->next = 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( char *script, ... )
{
int i = 0, in_quote = 0, start = 0, hit_null = 0;
IFunction *ptr = parse_function( NULL ), *tmp_fptr = NULL;
IFunction *rptr = ptr;
IFunctionParam *tmp_pptr;
va_list param_list;
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 = parse_function( copystr( script, start, i-1 ) );
ptr = ptr->next;
start = i+1;
}
}
/* 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 */
va_start( param_list, script );
for( tmp_fptr = rptr->next; tmp_fptr != NULL; tmp_fptr = tmp_fptr->next )
{
for( tmp_pptr = tmp_fptr->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", tmp_fptr->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
}
}
}
va_end( param_list );
#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 );
}
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 );
free( func->name );
free( func );
}

30
src/script.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef _DYN_FUNCTION_H_
#define _DYN_FUNCTION_H_
#include "ltdl.h"
#define VAR_CHAR 1
#define VAR_PTR 2
typedef struct _imlib_function_param IFunctionParam;
typedef struct _imlib_function_param *pIFunctionParam;
struct _imlib_function_param
{
char *key;
int type;
void *data;
pIFunctionParam next;
};
typedef struct _imlib_function IFunction;
typedef struct _imlib_function *pIFunction;
struct _imlib_function
{
char *name;
pIFunctionParam params;
pIFunction next;
};
pIFunction __imlib_script_parse( char *script, ... );
void __imlib_script_tidyup( IFunction *func );
#endif /* _FUNCTION_H_ */

View File

@ -830,6 +830,11 @@ 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 );
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);
imlib_blend_image_onto_image(im_sh2, 0, 0, 0, 50, 50, 50, 0, w - 50, 50);