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 0000000..e0ac399 Binary files /dev/null and b/test/test_images/imlib2.png differ