From f4eaa25fa73e9aaa0f8ffd68abb09d2d6e7c36ea Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 30 May 2000 22:10:01 +0000 Subject: [PATCH] Start of a filter test app, and applied Willem's patch for imlib2. thanks Willem. SVN revision: 2731 --- Makefile.am | 2 +- filters/Makefile.am | 6 +- filters/filter_colormod.c | 200 ++++++++++++++++++++++++++++++++++++ src/api.c | 6 +- src/colormod.c | 23 ++++- src/colormod.h | 2 +- src/rend.c | 5 +- test/Makefile.am | 7 +- test/bmtest.c | 120 ++++++++++++++++++++++ test/test_images/imlib2.png | Bin 0 -> 4877 bytes 10 files changed, 360 insertions(+), 11 deletions(-) create mode 100644 filters/filter_colormod.c create mode 100644 test/bmtest.c create mode 100644 test/test_images/imlib2.png diff --git a/Makefile.am b/Makefile.am index efaefa5..a079fea 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,7 +9,7 @@ MAINTAINERCLEANFILES = INSTALL Makefile.in aclocal.m4 config.guess \ ltconfig ltmain.sh missing mkinstalldirs \ stamp-h.in -SUBDIRS = libltdl loaders src filters dox +SUBDIRS = libltdl loaders src filters EXTRA_DIST = \ imlib2.spec.in \ diff --git a/filters/Makefile.am b/filters/Makefile.am index f21c7b3..87b7daf 100644 --- a/filters/Makefile.am +++ b/filters/Makefile.am @@ -12,7 +12,7 @@ INCLUDES = -I/usr/X11R6/include -I$(top_srcdir)/libltdl \ -I$(top_srcdir)/loaders pkgdir = $(libdir)/loaders/filter -pkg_LTLIBRARIES = testfilter.la bump_map.la +pkg_LTLIBRARIES = testfilter.la bump_map.la colormod.la testfilter_la_SOURCES = filter_test.c testfilter_la_LDFLAGS = -no-undefined -module -avoid-version @@ -21,3 +21,7 @@ testfilter_la_LIBADD = bump_map_la_SOURCES = filter_bumpmap.c bump_map_la_LDFLAGS = -no-undefined -module -avoid-version bump_map_la_LIBADD = + +colormod_la_SOURCES = filter_colormod.c +colormod_la_LDFLAGS = -no-undefined -module -avoid-version +colormod_la_LIBADD = diff --git a/filters/filter_colormod.c b/filters/filter_colormod.c new file mode 100644 index 0000000..2ad187d --- /dev/null +++ b/filters/filter_colormod.c @@ -0,0 +1,200 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "common.h" +#include +#include +#include +#include +#include +#include "Imlib2.h" +#include "image.h" +#include "script.h" +#include "dynamic_filters.h" + +#define GET_INT(x, ptr) (((ptr)->type == VAR_PTR) ? \ + (x) = (*(int *)(ptr)->data) : \ + ((ptr)->type == VAR_CHAR) ? \ + (x) = strtol((ptr)->data, 0, 0) \ + : 0) + +#define GET_DOUBLE(x, ptr) (((ptr)->type == VAR_PTR) ? \ + (x) = (*(double *)(ptr)->data) : \ + ((ptr)->type == VAR_CHAR) ? \ + (x) = strtod((ptr)->data, 0) \ + : 0) + +static void +mod_brightness(double t[256], double v) +{ + int i; + for (i = 256; --i >= 0; ) + t[i] += v; +} + +static void +mod_contrast(double t[256], double v) +{ + int i; + for (i = 256; --i >= 0; ) + t[i] = ((t[i] - 0.5) * v) + 0.5; +} + +static void +mod_gamma(double t[256], double v) +{ + int i; + for (i = 256; --i >= 0; ) + t[i] = pow(t[i], 1 / v); +} + +static void +mod_tint(double t[256], double v) +{ + int i; + for (i = 256; --i >= 0; ) + t[i] *= v; +} + +static Imlib_Image +colormod(Imlib_Image im, pIFunctionParam par) +{ + double a_d[256], r_d[256], g_d[256], b_d[256]; + DATA8 a_b[256], r_b[256], g_b[256], b_b[256]; + pIFunctionParam ptr; + int x = 0, y = 0, h, w, i; + double v; + + imlib_context_set_image(im); + w = imlib_image_get_width(); + h = imlib_image_get_height(); + + for (i = 256; --i >= 0; ) + a_d[i] = r_d[i] = g_d[i] = b_d[i] = (double)i / 255; + + for (ptr = par; ptr; ptr = ptr->next) { + if (!strcmp("x", ptr->key)) { + GET_INT(x, ptr); + } else if (!strcmp("y", ptr->key)) { + GET_INT(y, ptr); + } else if (!strcmp("w", ptr->key)) { + GET_INT(w, ptr); + } else if (!strcmp("h", ptr->key)) { + GET_INT(h, ptr); + } else if (!memcmp("brightness", ptr->key, 10)) { + GET_DOUBLE(v, ptr); + if (!ptr->key[10]) { + mod_brightness(r_d, v); + mod_brightness(g_d, v); + mod_brightness(b_d, v); + mod_brightness(a_d, v); + } else if (!strcmp("_r", ptr->key + 10)) { + mod_brightness(r_d, v); + } else if (!strcmp("_g", ptr->key + 10)) { + mod_brightness(g_d, v); + } else if (!strcmp("_b", ptr->key + 10)) { + mod_brightness(b_d, v); + } else if (!strcmp("_a", ptr->key + 10)) { + mod_brightness(a_d, v); + } + } else if (!memcmp("contrast", ptr->key, 8)) { + GET_DOUBLE(v, ptr); + if (!ptr->key[8]) { + mod_contrast(r_d, v); + mod_contrast(g_d, v); + mod_contrast(b_d, v); + mod_contrast(a_d, v); + } else if (!strcmp("_r", ptr->key + 8)) { + mod_contrast(r_d, v); + } else if (!strcmp("_g", ptr->key + 8)) { + mod_contrast(g_d, v); + } else if (!strcmp("_b", ptr->key + 8)) { + mod_contrast(b_d, v); + } else if (!strcmp("_a", ptr->key + 8)) { + mod_contrast(a_d, v); + } + } else if (!memcmp("gamma", ptr->key, 5)) { + GET_DOUBLE(v, ptr); + if (!ptr->key[5]) { + mod_gamma(r_d, v); + mod_gamma(g_d, v); + mod_gamma(b_d, v); + mod_gamma(a_d, v); + } else if (!strcmp("_r", ptr->key + 5)) { + mod_gamma(r_d, v); + } else if (!strcmp("_g", ptr->key + 5)) { + mod_gamma(g_d, v); + } else if (!strcmp("_b", ptr->key + 5)) { + mod_gamma(b_d, v); + } else if (!strcmp("_a", ptr->key + 5)) { + mod_gamma(a_d, v); + } + } else if (!memcmp("tint", ptr->key, 4)) { + GET_DOUBLE(v, ptr); + if (!ptr->key[4]) { + mod_tint(r_d, v); + mod_tint(g_d, v); + mod_tint(b_d, v); + mod_tint(a_d, v); + } else if (!strcmp("_r", ptr->key + 4)) { + mod_tint(r_d, v); + } else if (!strcmp("_g", ptr->key + 4)) { + mod_tint(g_d, v); + } else if (!strcmp("_b", ptr->key + 4)) { + mod_tint(b_d, v); + } else if (!strcmp("_a", ptr->key + 4)) { + mod_tint(a_d, v); + } + } + } + for (i = 256; --i >= 0; ) { + if (a_d[i] < 0) a_d[i] = 0; + if (a_d[i] > 1) a_d[i] = 1; + a_b[i] = a_d[i] * 255; + if (r_d[i] < 0) r_d[i] = 0; + if (r_d[i] > 1) r_d[i] = 1; + r_b[i] = r_d[i] * 255; + if (g_d[i] < 0) g_d[i] = 0; + if (g_d[i] > 1) g_d[i] = 1; + g_b[i] = g_d[i] * 255; + if (b_d[i] < 0) b_d[i] = 0; + if (b_d[i] > 1) b_d[i] = 1; + b_b[i] = b_d[i] * 255; + } + imlib_context_set_color_modifier(imlib_create_color_modifier()); + imlib_set_color_modifier_tables(r_b, g_b, b_b, a_b); + imlib_apply_color_modifier_to_rectangle(x, y, w, h); + imlib_free_color_modifier(); + return im; +} + +void +init(struct imlib_filter_info *info) +{ + char *filters[] = { "colormod" }; + int i = (sizeof(filters) / sizeof(*filters)); + + info->name = strdup( "Tinting" ); + info->author = strdup( "Willem Monsuwe (willem@stack.nl)" ); + info->description = strdup( "Provides most common color modification filters." ); + info->num_filters = i; + info->filters = malloc(sizeof(char *) * i); + while (--i >= 0) + info->filters[i] = strdup(filters[i]); + +} + +void +deinit() +{ + return; +} + +void * +exec(char *filter, void *im, pIFunctionParam par) +{ + if (!strcmp(filter, "colormod")) + return colormod((Imlib_Image)im, par); + return im; +} diff --git a/src/api.c b/src/api.c index 63ba127..2daa568 100644 --- a/src/api.c +++ b/src/api.c @@ -1840,7 +1840,7 @@ imlib_apply_color_modifier(void) return; __imlib_DirtyImage(im); __imlib_DirtyPixmapsForImage(im); - __imlib_DataCmodApply(im->data, im->w, im->h, 0, + __imlib_DataCmodApply(im->data, im->w, im->h, 0, &im->flags, (ImlibColorModifier *)ctxt_color_modifier); } @@ -1881,7 +1881,7 @@ imlib_apply_color_modifier_to_rectangle(int x, int y, int width, int height) __imlib_DirtyImage(im); __imlib_DirtyPixmapsForImage(im); __imlib_DataCmodApply(im->data + (y * im->w) + x, width, height, - im->w - width, + im->w - width, &im->flags, (ImlibColorModifier *)ctxt_color_modifier); } @@ -2441,6 +2441,8 @@ void imlib_apply_filter( char *script, ... ) __imlib_dynamic_filters_init(); CAST_IMAGE(im, ctxt_image); + __imlib_DirtyImage(im); + __imlib_DirtyPixmapsForImage(im); va_start( param_list, script ); __imlib_script_parse( im, script, param_list ); va_end( param_list ); diff --git a/src/colormod.c b/src/colormod.c index b99cd1c..2b9bd77 100644 --- a/src/colormod.c +++ b/src/colormod.c @@ -77,12 +77,33 @@ __imlib_CmodReset(ImlibColorModifier *cm) void __imlib_DataCmodApply(DATA32 *data, int w, int h, int jump, - ImlibColorModifier *cm) + int *fl, ImlibColorModifier *cm) { int x, y; DATA32 *p; DATA8 r, g, b, a; + /*\ We might be adding alpha \*/ + if (!(*fl & F_HAS_ALPHA)) + { + p = data; + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + R_VAL(p) = R_CMOD(cm, R_VAL(p)); + G_VAL(p) = G_CMOD(cm, G_VAL(p)); + B_VAL(p) = B_CMOD(cm, B_VAL(p)); + A_VAL(p) = A_CMOD(cm, 255); + p++; + } + p += jump; + } + if (A_CMOD(cm, 255) != 255) + *fl |= F_HAS_ALPHA; + return; + } + p = data; for (y = 0; y < h; y++) { diff --git a/src/colormod.h b/src/colormod.h index f1a0a86..c8fc0be 100644 --- a/src/colormod.h +++ b/src/colormod.h @@ -48,7 +48,7 @@ void __imlib_CmodSetTables(ImlibColorModifier *cm, DATA8 *r, DATA8 *g, DATA8 *b, DATA8 *a); void __imlib_CmodReset(ImlibColorModifier *cm); void __imlib_DataCmodApply(DATA32 *data, int w, int h, - int jump, + int jump, int *fl, ImlibColorModifier *cm); void __imlib_CmodGetTables(ImlibColorModifier *cm, DATA8 *r, diff --git a/src/rend.c b/src/rend.c index 93c9997..a54e308 100644 --- a/src/rend.c +++ b/src/rend.c @@ -11,7 +11,6 @@ #include "grab.h" #include "blend.h" #include "rend.h" -#include "colormod.h" /* size of the lines per segment we scale / render at a time */ #define LINESIZE 16 @@ -189,7 +188,7 @@ __imlib_RenderImage(Display *d, ImlibImage *im, jump = 0; pointer = buf; if (cmod) - __imlib_DataCmodApply(buf, dw, hh, 0, cmod); + __imlib_DataCmodApply(buf, dw, hh, 0, NULL, cmod); } else { @@ -208,7 +207,7 @@ __imlib_RenderImage(Display *d, ImlibImage *im, } memcpy(buf, im->data + ((y + sy) * im->w) + sx, im->w * hh * sizeof(DATA32)); - __imlib_DataCmodApply(buf, dw, hh, im->w - dw, cmod); + __imlib_DataCmodApply(buf, dw, hh, im->w - dw, NULL, cmod); pointer = buf; jump = 0; } diff --git a/test/Makefile.am b/test/Makefile.am index b357763..2a1fa1c 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -11,8 +11,11 @@ INCLUDES = -I/usr/X11R6/include -I$(top_srcdir)/libltdl \ -I. -I$(top_srcdir) -I$(top_srcdir)/src \ -I$(top_srcdir)/loaders -bin_PROGRAMS = imlib2 +bin_PROGRAMS = imlib2 bumpmaptest imlib2_SOURCES = main.c imlib2_LDADD = @DLLDFLAGS@ $(top_builddir)/libltdl/libltdlc.la \ -lX11 -lXext -lttf -lImlib2 - + +bumpmaptest_SOURCES = bmtest.c +bumpmaptest_LDADD = @DLLDFLAGS@ $(top_builddir)/libltdl/libltdlc.la \ + -lX11 -lXext -lttf -lImlib2 diff --git a/test/bmtest.c b/test/bmtest.c new file mode 100644 index 0000000..494412c --- /dev/null +++ b/test/bmtest.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* +#include +#include "common.h" +#include "image.h" +#include "rend.h" +#include "rgba.h" +#include "ximage.h" +#include "color.h" + */ +#include "Imlib2.h" + +Display *disp; +Window win; +Visual *vis; +Colormap cm; +int depth; + +int main (int argc, char **argv) +{ + int i, j, w, h, x, y; + Imlib_Image im = NULL, im_bg = NULL; + XEvent ev; + + /** + * Initialization according to options + */ + printf("Initialising\n"); + + /** + * First tests to determine which rendering task to perform + */ + disp = XOpenDisplay(NULL); + vis = DefaultVisual(disp, DefaultScreen(disp)); + depth = DefaultDepth(disp, DefaultScreen(disp)); + cm = DefaultColormap(disp, DefaultScreen(disp)); + win = XCreateSimpleWindow(disp, DefaultRootWindow(disp), 0, 0, 100, 100, 0, 0, 0); + XSelectInput(disp, win, ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask | PointerMotionMask | ExposureMask); + XMapWindow(disp, win); + + /** + * Start rendering + */ + printf("Rendering\n"); + imlib_context_set_display(disp); + imlib_context_set_visual(vis); + imlib_context_set_colormap(cm); + imlib_context_set_drawable(win); + imlib_context_set_blend(0); + imlib_context_set_color_modifier(NULL); + + im_bg = imlib_load_image("test_images/imlib2.png"); + im = imlib_load_image("test_images/imlib2.png"); + + imlib_context_set_image(im_bg); + w = imlib_image_get_width(); + h = imlib_image_get_height(); + printf( "Resizing Window to %d by %d\n", w, h ); + XResizeWindow(disp, win, w, h); + XSync(disp, False); + x = -9999; + y = -9999; + while (1) + { + Imlib_Image *temp, *temp2; + do + { + XNextEvent(disp, &ev); + switch (ev.type) + { + case Expose: + break; + case ButtonRelease: + exit(0); + break; + case MotionNotify: + x = ev.xmotion.x; + y = ev.xmotion.y; + default: + break; + + } + } + while (XPending(disp)); + + imlib_context_set_blend( 0 ); + imlib_context_set_image(im_bg); + temp = imlib_clone_image(); + imlib_context_set_image( temp ); + + /* imlib_blend_image_onto_image(im_bg, 0, + 0, 0, w, h, + 0, 0, w, h); + first = 0;*/ + + imlib_apply_filter("bump_map_point(x=[],y=[],map=test_images/imlib2.png);", &x, &y ); + + temp2 = im_bg; + im_bg = temp; + imlib_context_set_image(im_bg); + imlib_render_image_on_drawable(0, 0 ); + im_bg = temp2; + imlib_context_set_image(temp); + imlib_free_image_and_decache(); + } + + return 0; +} diff --git a/test/test_images/imlib2.png b/test/test_images/imlib2.png new file mode 100644 index 0000000000000000000000000000000000000000..e0ac3993bff906145b39755e612eab34e8f1e0af GIT binary patch literal 4877 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 Pt^hh32I`gfZNvTry%s)0 literal 0 HcmV?d00001