From 69e830eea470bbc7e3bfa0916730bd697d322abf Mon Sep 17 00:00:00 2001 From: Matthew Allum Date: Wed, 13 Apr 2005 17:36:17 +0000 Subject: [PATCH] random commit to help rejig stuff around --- Makefile | 2 + cltr-core.c | 16 ++ cltr-core.h | 6 + cltr-events.c | 1 - cltr-glu.c | 133 +++++++++ cltr-glu.h | 17 ++ cltr-list.c | 6 +- cltr-photo-grid.c | 20 +- cltr-widget.c | 12 + cltr-widget.h | 11 +- cltr-window.c | 59 +++- cltr-window.h | 3 + cltr.c | 75 +++-- cltr.h | 2 + cltr-events.h => clutter/cltr-events.h | 0 cltr-list.h => clutter/cltr-list.h | 0 .../cltr-photo-grid.h | 0 cltr-private.h => clutter/cltr-private.h | 0 cltr-texture.c => clutter/cltr-texture.c | 0 cltr-texture.h => clutter/cltr-texture.h | 0 pixbuf.h => clutter/pixbuf.h | 0 util.c => clutter/util.c | 0 util.h => clutter/util.h | 0 fonts.c | 6 +- fonts.h | 3 +- pixbuf.c | 259 +++++++++++++++++- 26 files changed, 593 insertions(+), 38 deletions(-) create mode 100644 cltr-glu.c create mode 100644 cltr-glu.h rename cltr-events.h => clutter/cltr-events.h (100%) rename cltr-list.h => clutter/cltr-list.h (100%) rename cltr-photo-grid.h => clutter/cltr-photo-grid.h (100%) rename cltr-private.h => clutter/cltr-private.h (100%) rename cltr-texture.c => clutter/cltr-texture.c (100%) rename cltr-texture.h => clutter/cltr-texture.h (100%) rename pixbuf.h => clutter/pixbuf.h (100%) rename util.c => clutter/util.c (100%) rename util.h => clutter/util.h (100%) diff --git a/Makefile b/Makefile index 0addf3f84..aaa5dc56d 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ CFLAGS=`pkg-config --cflags pangoft2 pango glib-2.0 gthread-2.0` OBJS=cltr.o pixbuf.o util.o fonts.o \ cltr-core.o \ + cltr-glu.o \ cltr-texture.o \ cltr-widget.o \ cltr-events.o \ @@ -22,6 +23,7 @@ clutter: $(OBJS) $(OBJS): pixbuf.h util.h fonts.h \ cltr.h \ cltr-private.h \ + cltr-glu.h \ cltr-events.h \ cltr-texture.h \ cltr-widget.h \ diff --git a/cltr-core.c b/cltr-core.c index 745f6eff0..034c9aca8 100644 --- a/cltr-core.c +++ b/cltr-core.c @@ -42,3 +42,19 @@ cltr_init(int *argc, char ***argv) return 1; } + +int +cltr_display_width(void) +{ + ClutterMainContext *ctx = CLTR_CONTEXT(); + + return DisplayWidth(ctx->xdpy, ctx->xscreen); +} + +int +cltr_display_height(void) +{ + ClutterMainContext *ctx = CLTR_CONTEXT(); + + return DisplayHeight(ctx->xdpy, ctx->xscreen); +} diff --git a/cltr-core.h b/cltr-core.h index 76e2a5c2a..9175b039f 100644 --- a/cltr-core.h +++ b/cltr-core.h @@ -6,4 +6,10 @@ int cltr_init(int *argc, char ***argv); +int +cltr_display_height(void); + +int +cltr_display_width(void); + #endif diff --git a/cltr-events.c b/cltr-events.c index c03f7a25a..9e864b89b 100644 --- a/cltr-events.c +++ b/cltr-events.c @@ -157,7 +157,6 @@ cltr_main_loop() { if (!g_queue_is_empty (ctx->internal_event_q)) { - CltrWidget *widget = NULL; CltrWindow *win = CLTR_WINDOW(ctx->window); /* Empty the queue */ diff --git a/cltr-glu.c b/cltr-glu.c new file mode 100644 index 000000000..3b1384b16 --- /dev/null +++ b/cltr-glu.c @@ -0,0 +1,133 @@ +#include "cltr-glu.h" +#include "cltr-private.h" + +/* Clutter GL Utility routines */ + +#define PI 3.1415926535897932384626433832795 + +void +cltr_glu_set_color(PixbufPixel *p) +{ + glColor4ub(p->r, p->b, p->g, p->a); +} + +#if 0 +void +DrawRoundedSquare(float LineWidth, + float x, + float y, + float radius, + float width, + float height, + float r, + float b, + float g) +{ + double ang=0; + + glColor3f(r, b, g); + glLineWidth(LineWidth); + + glBegin(GL_LINES); + glVertex2f(x, y + radius); + glVertex2f(x, y + height - radius); /* Left Line */ + + glVertex2f(x + radius, y); + glVertex2f(x + width - radius, y); /* Top Line */ + + glVertex2f(x + width, y + radius); + glVertex2f(x + width, y + height - radius); /* Right Line */ + + glVertex2f(x + radius, y + height); + glVertex2f(x + width - radius, y + height);//Bottom Line + glEnd(); + + float cX= x+radius, cY = y+radius; + glBegin(GL_LINE_STRIP); + for(ang = PI; ang <= (1.5*PI); ang = ang + 0.05) + { + glVertex2d(radius* cos(ang) + cX, radius * sin(ang) + cY); //Top Left + } + cX = x+width-radius; + glEnd(); + glBegin(GL_LINE_STRIP); + for(ang = (1.5*PI); ang <= (2 * PI); ang = ang + 0.05) + { + glVertex2d(radius* cos(ang) + cX, radius * sin(ang) + cY); //Top Right + } + glEnd(); + glBegin(GL_LINE_STRIP); + cY = y+height-radius; + for(ang = 0; ang <= (0.5*PI); ang = ang + 0.05) + { + glVertex2d(radius* cos(ang) + cX, radius * sin(ang) + cY); //Bottom Right + } + glEnd(); + glBegin(GL_LINE_STRIP); + cX = x+radius; + for(ang = (0.5*PI); ang <= PI; ang = ang + 0.05) + { + glVertex2d(radius* cos(ang) + cX, radius * sin(ang) + cY);//Bottom Left + } + glEnd(); +} +#endif + +void +cltr_glu_rounded_rect(int x1, + int y1, + int x2, + int y2, + int radius, + PixbufPixel *col) +{ + double i = 0; + double gap = 0.05; + float cX = x1 + radius, cY = y1 + radius; + + if (col) + cltr_glu_set_color(col); + + glBegin(GL_POLYGON); + + /* Left Line */ + glVertex2f(x1, y2 - radius); + glVertex2f(x1, y1 + radius); + + /* Top Left */ + for(i = PI; i <= (1.5*PI); i += gap) + glVertex2d(radius* cos(i) + cX, radius * sin(i) + cY); + + /* Top Line */ + glVertex2f(x1 + radius, y1); + glVertex2f(x2 - radius, y1); + + cX = x2 - radius; + + /* Top Right */ + for(i = (1.5*PI); i <= (2 * PI); i += gap) + glVertex2d(radius* cos(i) + cX, radius * sin(i) + cY); + + glVertex2f(x2, y1 + radius); + + /* Right Line */ + glVertex2f(x2, y2 - radius); + + cY = y2 - radius; + + /* Bottom Right */ + for(i = 0; i <= (0.5*PI); i+=gap) + glVertex2d(radius* cos(i) + cX, radius * sin(i) + cY); + + /* Bottom Line */ + glVertex2f(x1 + radius, y2); + glVertex2f(x2 - radius, y2); + + /* Bottom Left */ + cX = x1 + radius; + for(i = (0.5*PI); i <= PI; i += gap) + glVertex2d(radius* cos(i) + cX, radius * sin(i) + cY); + + glEnd(); +} + diff --git a/cltr-glu.h b/cltr-glu.h new file mode 100644 index 000000000..6f0c01f11 --- /dev/null +++ b/cltr-glu.h @@ -0,0 +1,17 @@ +#ifndef _HAVE_CLTR_GLU_H +#define _HAVE_CLTR_GLU_H + +#include "cltr.h" + +void +cltr_glu_set_color(PixbufPixel *p); + +void +cltr_glu_rounded_rect(int x1, + int y1, + int x2, + int y2, + int radius, + PixbufPixel *col); + +#endif diff --git a/cltr-list.c b/cltr-list.c index fff6cbbbf..f17ca72c2 100644 --- a/cltr-list.c +++ b/cltr-list.c @@ -48,7 +48,7 @@ cltr_list_cell_new(CltrList *list) CltrListCell *cell = NULL; ClutterFont *font; gchar buf[24]; - PixbufPixel pixel = { 255, 20, 20, 255 }; + PixbufPixel pixel = { 255, 20, 20, 255 }, font_pixel = { 255, 255, 255, 200 }; font = font_new ("Sans Bold 96"); @@ -60,7 +60,9 @@ cltr_list_cell_new(CltrList *list) g_snprintf(&buf[0], 24, "%i %i %i", rand()%10, rand()%10, rand()%10); - font_draw(font, cell->pixb, buf, 10, 10); + + + font_draw(font, cell->pixb, buf, 10, 10, &font_pixel); cell->texture = cltr_texture_new(cell->pixb); diff --git a/cltr-photo-grid.c b/cltr-photo-grid.c index 55f6c34dd..47650c3c4 100644 --- a/cltr-photo-grid.c +++ b/cltr-photo-grid.c @@ -393,6 +393,7 @@ cltr_photo_grid_populate(gpointer data) gchar *fullpath = NULL; int n_pixb = 0, i =0; ClutterFont *font = NULL; + PixbufPixel font_col = { 255, 255, 255, 255 }; font = font_new("Sans Bold 96"); @@ -430,7 +431,7 @@ cltr_photo_grid_populate(gpointer data) cell = cltr_photo_grid_cell_new(grid, pixb, entry); g_snprintf(&buf[0], 24, "%i", i); - font_draw(font, cell->pixb, buf, 10, 10); + font_draw(font, cell->pixb, buf, 10, 10, &font_col); g_mutex_lock(Mutex_GRID); @@ -721,6 +722,7 @@ cltr_photo_grid_paint(CltrWidget *widget) glDisable(GL_TEXTURE_2D); + if (cell_item == grid->cell_active && grid->state == CLTR_PHOTO_GRID_STATE_BROWSE) glColor4f(1.0, 1.0, 1.0, 1.0); @@ -729,8 +731,24 @@ cltr_photo_grid_paint(CltrWidget *widget) /* Draw with origin in center of photo */ + /* glRecti(-(thumb_w/2)-4, -(thumb_h/2)-4, (thumb_w/2)+4, (thumb_h/2)+ns_border); + */ + + cltr_glu_rounded_rect(-(thumb_w/2)-4, -(thumb_h/2)-4, + (thumb_w/2)+4, (thumb_h/2)+ns_border, + thumb_w/40, + NULL); + + glColor4f(0.1, 0.1, 0.1, 0.5); + + cltr_glu_rounded_rect(-(thumb_w/2)-4, -(thumb_h/2)-4+1, + (thumb_w/2)+4, (thumb_h/2)+ns_border+1, + thumb_w/40, + NULL); + + glColor4f(1.0, 1.0, 1.0, 1.0); glEnable(GL_TEXTURE_2D); diff --git a/cltr-widget.c b/cltr-widget.c index d0f052c89..4ffa4a4a4 100644 --- a/cltr-widget.c +++ b/cltr-widget.c @@ -11,6 +11,18 @@ cltr_widget_new(void) return w; } +int +cltr_widget_width(CltrWidget *widget) +{ + return widget->width; +} + +int +cltr_widget_height(CltrWidget *widget) +{ + return widget->width; +} + void cltr_widget_show(CltrWidget *widget) { diff --git a/cltr-widget.h b/cltr-widget.h index 75618ce3c..868658716 100644 --- a/cltr-widget.h +++ b/cltr-widget.h @@ -7,22 +7,24 @@ typedef struct CltrWidget CltrWidget; #define CLTR_WIDGET(w) ((CltrWidget*)(w)) - CltrWidget* cltr_widget_new(void); +int +cltr_widget_width(CltrWidget *widget); + +int +cltr_widget_height(CltrWidget *widget); + void cltr_widget_show(CltrWidget *widget); void cltr_widget_paint(CltrWidget *widget); - gboolean cltr_widget_handle_xevent(CltrWidget *widget, XEvent *xev); - - void cltr_widget_show_all(CltrWidget *widget); @@ -32,5 +34,4 @@ cltr_widget_queue_paint(CltrWidget *widget); void cltr_widget_add_child(CltrWidget *widget, CltrWidget *child, int x, int y); - #endif diff --git a/cltr-window.c b/cltr-window.c index 73999d8dd..097f2ddc7 100644 --- a/cltr-window.c +++ b/cltr-window.c @@ -17,6 +17,19 @@ struct CltrWindow CltrWidget *focused_child; }; +void +clrt_window_set_gl_viewport(CltrWindow *win) +{ + CltrWidget *widget = CLTR_WIDGET(win); + + glViewport (0, 0, widget->width, widget->height); + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + glOrtho (0, widget->width, widget->height, 0, -1, 1); /* 2d */ + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); +} + CltrWidget* cltr_window_new(int width, int height) { @@ -46,16 +59,10 @@ cltr_window_new(int width, int height) /* All likely better somewhere else */ - /* view port */ - glViewport (0, 0, width, height); - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); - glOrtho (0, width, height, 0, -1, 1); /* 2d */ - glMatrixMode (GL_MODELVIEW); - glLoadIdentity (); - ctx->window = CLTR_WIDGET(win); + clrt_window_set_gl_viewport(win); + return CLTR_WIDGET(win); } @@ -83,6 +90,17 @@ cltr_window_paint(CltrWidget *widget) } +static void +cltr_window_handle_xconfigure(CltrWindow *win, XConfigureEvent *cxev) +{ + + /* + widget.width = cxev->width; + widget.height = cxev->height; + */ + +} + static gboolean cltr_window_handle_xevent (CltrWidget *widget, XEvent *xev) { @@ -95,6 +113,11 @@ cltr_window_handle_xevent (CltrWidget *widget, XEvent *xev) cltr_widget_queue_paint(widget); } + /* + case ConfigureNotify: + wm_handle_configure_request(w, &ev.xconfigure); break; + */ + /* XXX Very basic - assumes we are only interested in mouse clicks */ if (win->focused_child) return cltr_widget_handle_xevent(win->focused_child, xev); @@ -110,6 +133,25 @@ cltr_window_xwin(CltrWindow *win) return win->xwin; } +void +cltr_window_set_fullscreen(CltrWindow *win) +{ + ClutterMainContext *ctx = CLTR_CONTEXT(); + + Atom atom_WINDOW_STATE, atom_WINDOW_STATE_FULLSCREEN; + + atom_WINDOW_STATE + = XInternAtom(ctx->xdpy, "_NET_WM_STATE", False); + atom_WINDOW_STATE_FULLSCREEN + = XInternAtom(ctx->xdpy, "_NET_WM_STATE_FULLSCREEN",False); + + XChangeProperty(ctx->xdpy, win->xwin, + atom_WINDOW_STATE, XA_ATOM, 32, + PropModeReplace, + (unsigned char *)&atom_WINDOW_STATE_FULLSCREEN, 1); +} + + Window cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget) { @@ -118,6 +160,7 @@ cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget) ClutterMainContext *ctx = CLTR_CONTEXT(); win->focused_child = widget; + } diff --git a/cltr-window.h b/cltr-window.h index e5baae0f2..d3ff82a2b 100644 --- a/cltr-window.h +++ b/cltr-window.h @@ -21,6 +21,9 @@ cltr_window_add_widget(CltrWindow *win, CltrWidget *widget, int x, int y); Window cltr_window_xwin(CltrWindow *win); +void +cltr_window_set_fullscreen(CltrWindow *win); + Window cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget); diff --git a/cltr.c b/cltr.c index de2950911..abb8c5993 100644 --- a/cltr.c +++ b/cltr.c @@ -1,41 +1,84 @@ #include "cltr.h" +int +usage(char *progname) +{ + fprintf(stderr, "Usage ... check source for now\n"); + exit(-1); +} + int main(int argc, char **argv) { - CltrWidget *win = NULL, *grid = NULL, *test = NULL, *test2 = NULL; - CltrWidget *list; + int i; + CltrWidget *win = NULL, *grid = NULL, *test = NULL, *test2 = NULL; - if (argc < 2) - { - g_printerr("usage: '%s' \n" - , argv[0]); - exit(-1); - } + gchar *img_path = NULL; + gboolean want_fullscreen = FALSE; + gint cols = 3; cltr_init(&argc, &argv); - win = cltr_window_new(640, 480); + for (i = 1; i < argc; i++) + { + if (!strcmp ("--image-path", argv[i]) || !strcmp ("-i", argv[i])) + { + if (++i>=argc) usage (argv[0]); + img_path = argv[i]; + continue; + } + if (!strcmp ("--cols", argv[i]) || !strcmp ("-c", argv[i])) + { + if (++i>=argc) usage (argv[0]); + cols = atoi(argv[i]); + continue; + } + if (!strcmp ("-fs", argv[i]) || !strcmp ("--fullscreen", argv[i])) + { + want_fullscreen = TRUE; + continue; + } + if (!strcmp("--help", argv[i]) || !strcmp("-h", argv[i])) + { + usage(argv[0]); + } - /* - grid = cltr_photo_grid_new(640, 480, 4, 4, argv[1]); + usage(argv[0]); + } - test = cltr_scratch_new(100, 100); - test2 = cltr_scratch_new(150, 150); + win = cltr_window_new(800, 600); + + if (want_fullscreen) + cltr_window_set_fullscreen(CLTR_WINDOW(win)); + + + grid = cltr_photo_grid_new(800, 600, cols, cols, img_path); + + cltr_window_focus_widget(CLTR_WINDOW(win), grid); cltr_widget_add_child(win, grid, 0, 0); + /* + test = cltr_scratch_new(300, 100); + test2 = cltr_scratch_new(150, 150); + + cltr_widget_add_child(win, test, 400, 240); + */ + + + + /* cltr_widget_add_child(win, test, 320, 240); cltr_widget_add_child(win, test2, 400, 300); - cltr_window_focus_widget(CLTR_WINDOW(win), grid); - */ - list = cltr_list_new(640,480,640, 160); cltr_widget_add_child(win, list, 0, 0); + */ + + cltr_widget_show_all(win); cltr_main_loop(); diff --git a/cltr.h b/cltr.h index 18695ae08..28cb84b1c 100644 --- a/cltr.h +++ b/cltr.h @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -43,6 +44,7 @@ CltrRect; /* ******************* */ #include "cltr-core.h" +#include "cltr-glu.h" #include "cltr-texture.h" #include "cltr-events.h" #include "cltr-widget.h" diff --git a/cltr-events.h b/clutter/cltr-events.h similarity index 100% rename from cltr-events.h rename to clutter/cltr-events.h diff --git a/cltr-list.h b/clutter/cltr-list.h similarity index 100% rename from cltr-list.h rename to clutter/cltr-list.h diff --git a/cltr-photo-grid.h b/clutter/cltr-photo-grid.h similarity index 100% rename from cltr-photo-grid.h rename to clutter/cltr-photo-grid.h diff --git a/cltr-private.h b/clutter/cltr-private.h similarity index 100% rename from cltr-private.h rename to clutter/cltr-private.h diff --git a/cltr-texture.c b/clutter/cltr-texture.c similarity index 100% rename from cltr-texture.c rename to clutter/cltr-texture.c diff --git a/cltr-texture.h b/clutter/cltr-texture.h similarity index 100% rename from cltr-texture.h rename to clutter/cltr-texture.h diff --git a/pixbuf.h b/clutter/pixbuf.h similarity index 100% rename from pixbuf.h rename to clutter/pixbuf.h diff --git a/util.c b/clutter/util.c similarity index 100% rename from util.c rename to clutter/util.c diff --git a/util.h b/clutter/util.h similarity index 100% rename from util.h rename to clutter/util.h diff --git a/fonts.c b/fonts.c index 77f8b3b55..9eb661aae 100644 --- a/fonts.c +++ b/fonts.c @@ -146,11 +146,11 @@ font_draw(ClutterFont *font, Pixbuf *pixb, const char *text, int x, - int y) + int y, + PixbufPixel *p) { int layout_width, layout_height; PangoLayout *layout; - PixbufPixel p = { 0xff,0xff,0xff,0x80 }; layout = pango_layout_new (font->context); @@ -161,7 +161,7 @@ font_draw(ClutterFont *font, /* cant rely on just clip - need to set layout width too */ - draw_layout_on_pixbuf (layout, pixb, &p, x, y, + draw_layout_on_pixbuf (layout, pixb, p, x, y, x, y, pixb->width - x, diff --git a/fonts.h b/fonts.h index ffbfaf303..5f39e260f 100644 --- a/fonts.h +++ b/fonts.h @@ -25,7 +25,8 @@ font_draw(ClutterFont *font, Pixbuf *pixb, const char *text, int x, - int y); + int y, + PixbufPixel *p); #endif diff --git a/pixbuf.c b/pixbuf.c index a8337beb2..c5b82536b 100644 --- a/pixbuf.c +++ b/pixbuf.c @@ -458,7 +458,7 @@ pixbuf_new(int width, int height) pixb->bytes_per_line = pixb->bytes_per_pixel * pixb->width; pixb->data = malloc(pixb->bytes_per_line * pixb->height); - /* memset ? */ + memset(pixb->data, 0, pixb->bytes_per_line * pixb->height); return pixb; } @@ -671,3 +671,260 @@ pixbuf_scale_down(Pixbuf *pixb, return pixb_scaled; } + +#if 0 + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% C o n v o l v e I m a g e % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Method ConvolveImage applies a general image convolution kernel to an +% image returns the results. ConvolveImage allocates the memory necessary for +% the new Image structure and returns a pointer to the new image. +% +% The format of the ConvolveImage method is: +% +% Image *ConvolveImage(Image *image,const unsigned int order, +% const double *kernel,ExceptionInfo *exception) +% +% A description of each parameter follows: +% +% o convolve_image: Method ConvolveImage returns a pointer to the image +% after it is convolved. A null image is returned if there is a memory +% shortage. +% +% o image: The address of a structure of type Image; returned from +% ReadImage. +% +% o order: The number of columns and rows in the filter kernel. +% +% o kernel: An array of double representing the convolution kernel. +% +% o exception: return any errors or warnings in this structure. +% +% +*/ +MagickExport Image *ConvolveImage(Image *image, + const unsigned int order, + const double *kernel, + ExceptionInfo *exception) +{ +#define ConvolveImageText " Convolving image... " +#define Cx(x) \ + (x) < 0 ? (x)+image->columns : (x) >= image->columns ? (x)-image->columns : x +#define Cy(y) \ + (y) < 0 ? (y)+image->rows : (y) >= image->rows ? (y)-image->rows : y + + double + blue, + green, + normalize, + opacity, + red; + + Image + *convolve_image; + + int + i, + width, + y; + + PixelPacket + *p, + pixel; + + register const double + *k; + + register int + u, + v, + x; + + register PixelPacket + *q, + *s; + + /* + Initialize convolved image attributes. + */ + assert(image != (Image *) NULL); + assert(image->signature == MagickSignature); + assert(exception != (ExceptionInfo *) NULL); + assert(exception->signature == MagickSignature); + width=order; + if ((width % 2) == 0) + ThrowImageException(OptionWarning,"Unable to convolve image", + "kernel width must be an odd number"); + if ((image->columns < width) || (image->rows < width)) + ThrowImageException(OptionWarning,"Unable to convolve image", + "image smaller than kernel width"); + convolve_image=CloneImage(image,image->columns,image->rows,False,exception); + if (convolve_image == (Image *) NULL) + return((Image *) NULL); + convolve_image->storage_class=DirectClass; + /* + Convolve image. + */ + normalize=0.0; + for (i=0; i < (width*width); i++) + normalize+=kernel[i]; + for (y=0; y < (int) convolve_image->rows; y++) + { + p=(PixelPacket *) NULL; + q=SetImagePixels(convolve_image,0,y,convolve_image->columns,1); + if (q == (PixelPacket *) NULL) + break; + for (x=0; x < (int) convolve_image->columns; x++) + { + red=0.0; + green=0.0; + blue=0.0; + opacity=0.0; + k=kernel; + if ((x < (width/2)) || (x >= (int) (image->columns-width/2)) || + (y < (width/2)) || (y >= (int) (image->rows-width/2))) + { + for (v=(-width/2); v <= (width/2); v++) + { + for (u=(-width/2); u <= (width/2); u++) + { + pixel=GetOnePixel(image,Cx(x+u),Cy(y+v)); + red+=(*k)*pixel.red; + green+=(*k)*pixel.green; + blue+=(*k)*pixel.blue; + opacity+=(*k)*pixel.opacity; + k++; + } + } + } + else + { + if (p == (PixelPacket *) NULL) + { + p=GetImagePixels(image,0,y-width/2,image->columns,width); + if (p == (PixelPacket *) NULL) + break; + } + s=p+x; + for (v=(-width/2); v <= (width/2); v++) + { + for (u=(-width/2); u <= (width/2); u++) + { + red+=(*k)*s[u].red; + green+=(*k)*s[u].green; + blue+=(*k)*s[u].blue; + opacity+=(*k)*s[u].opacity; + k++; + } + s+=image->columns; + } + } + if ((normalize != 0.0) && (normalize != 1.0)) + { + red/=normalize; + green/=normalize; + blue/=normalize; + opacity/=normalize; + } + q->red=(Quantum) ((red < 0) ? 0 : (red > MaxRGB) ? MaxRGB : red+0.5); + q->green=(Quantum) + ((green < 0) ? 0 : (green > MaxRGB) ? MaxRGB : green+0.5); + q->blue=(Quantum) ((blue < 0) ? 0 : (blue > MaxRGB) ? MaxRGB : blue+0.5); + q->opacity=(Quantum) + ((opacity < 0) ? 0 : (opacity > MaxRGB) ? MaxRGB : opacity+0.5); + q++; + } + if (!SyncImagePixels(convolve_image)) + break; + if (QuantumTick(y,convolve_image->rows)) + MagickMonitor(ConvolveImageText,y,convolve_image->rows); + } + return(convolve_image); +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% G a u s s i a n B l u r I m a g e % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Method GaussianBlurImage creates a new image that is a copy of an existing +% one with the pixels blur. It allocates the memory necessary for the +% new Image structure and returns a pointer to the new image. +% +% The format of the BlurImage method is: +% +% Image *GaussianBlurImage(Image *image,const double radius, +% const double sigma,ExceptionInfo *exception) +% +% A description of each parameter follows: +% +% o blur_image: Method GaussianBlurImage returns a pointer to the image +% after it is blur. A null image is returned if there is a memory +% shortage. +% +% o radius: the radius of the Gaussian, in pixels, not counting the center +% pixel. +% +% o sigma: the standard deviation of the Gaussian, in pixels. +% +% o exception: return any errors or warnings in this structure. +% +% +*/ +MagickExport Image *GaussianBlurImage(Image *image,const double radius, + const double sigma,ExceptionInfo *exception) +{ + double + *kernel; + + Image + *blur_image; + + int + width; + + register int + i, + u, + v; + + assert(image != (Image *) NULL); + assert(image->signature == MagickSignature); + assert(exception != (ExceptionInfo *) NULL); + assert(exception->signature == MagickSignature); + width=GetOptimalKernelWidth2D(radius,sigma); + if ((image->columns < width) || (image->rows < width)) + ThrowImageException(OptionWarning,"Unable to Gaussian blur image", + "image is smaller than radius"); + kernel=(double *) AcquireMemory(width*width*sizeof(double)); + if (kernel == (double *) NULL) + ThrowImageException(ResourceLimitWarning,"Unable to Gaussian blur image", + "Memory allocation failed"); + i=0; + for (v=(-width/2); v <= (width/2); v++) + { + for (u=(-width/2); u <= (width/2); u++) + { + kernel[i]=exp((double) -(u*u+v*v)/(sigma*sigma)); + i++; + } + } + blur_image=ConvolveImage(image,width,kernel,exception); + LiberateMemory((void **) &kernel); + return(blur_image); +} + +#endif