random commit to help rejig stuff around

This commit is contained in:
Matthew Allum 2005-04-13 17:36:17 +00:00
parent f016f09792
commit 69e830eea4
26 changed files with 593 additions and 38 deletions

View File

@ -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 \ OBJS=cltr.o pixbuf.o util.o fonts.o \
cltr-core.o \ cltr-core.o \
cltr-glu.o \
cltr-texture.o \ cltr-texture.o \
cltr-widget.o \ cltr-widget.o \
cltr-events.o \ cltr-events.o \
@ -22,6 +23,7 @@ clutter: $(OBJS)
$(OBJS): pixbuf.h util.h fonts.h \ $(OBJS): pixbuf.h util.h fonts.h \
cltr.h \ cltr.h \
cltr-private.h \ cltr-private.h \
cltr-glu.h \
cltr-events.h \ cltr-events.h \
cltr-texture.h \ cltr-texture.h \
cltr-widget.h \ cltr-widget.h \

View File

@ -42,3 +42,19 @@ cltr_init(int *argc, char ***argv)
return 1; 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);
}

View File

@ -6,4 +6,10 @@
int int
cltr_init(int *argc, char ***argv); cltr_init(int *argc, char ***argv);
int
cltr_display_height(void);
int
cltr_display_width(void);
#endif #endif

View File

@ -157,7 +157,6 @@ cltr_main_loop()
{ {
if (!g_queue_is_empty (ctx->internal_event_q)) if (!g_queue_is_empty (ctx->internal_event_q))
{ {
CltrWidget *widget = NULL;
CltrWindow *win = CLTR_WINDOW(ctx->window); CltrWindow *win = CLTR_WINDOW(ctx->window);
/* Empty the queue */ /* Empty the queue */

133
cltr-glu.c Normal file
View File

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

17
cltr-glu.h Normal file
View File

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

View File

@ -48,7 +48,7 @@ cltr_list_cell_new(CltrList *list)
CltrListCell *cell = NULL; CltrListCell *cell = NULL;
ClutterFont *font; ClutterFont *font;
gchar buf[24]; 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"); 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); 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); cell->texture = cltr_texture_new(cell->pixb);

View File

@ -393,6 +393,7 @@ cltr_photo_grid_populate(gpointer data)
gchar *fullpath = NULL; gchar *fullpath = NULL;
int n_pixb = 0, i =0; int n_pixb = 0, i =0;
ClutterFont *font = NULL; ClutterFont *font = NULL;
PixbufPixel font_col = { 255, 255, 255, 255 };
font = font_new("Sans Bold 96"); 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); cell = cltr_photo_grid_cell_new(grid, pixb, entry);
g_snprintf(&buf[0], 24, "%i", i); 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); g_mutex_lock(Mutex_GRID);
@ -721,6 +722,7 @@ cltr_photo_grid_paint(CltrWidget *widget)
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
if (cell_item == grid->cell_active if (cell_item == grid->cell_active
&& grid->state == CLTR_PHOTO_GRID_STATE_BROWSE) && grid->state == CLTR_PHOTO_GRID_STATE_BROWSE)
glColor4f(1.0, 1.0, 1.0, 1.0); 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 */ /* Draw with origin in center of photo */
/*
glRecti(-(thumb_w/2)-4, -(thumb_h/2)-4, glRecti(-(thumb_w/2)-4, -(thumb_h/2)-4,
(thumb_w/2)+4, (thumb_h/2)+ns_border); (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); glEnable(GL_TEXTURE_2D);

View File

@ -11,6 +11,18 @@ cltr_widget_new(void)
return w; return w;
} }
int
cltr_widget_width(CltrWidget *widget)
{
return widget->width;
}
int
cltr_widget_height(CltrWidget *widget)
{
return widget->width;
}
void void
cltr_widget_show(CltrWidget *widget) cltr_widget_show(CltrWidget *widget)
{ {

View File

@ -7,22 +7,24 @@ typedef struct CltrWidget CltrWidget;
#define CLTR_WIDGET(w) ((CltrWidget*)(w)) #define CLTR_WIDGET(w) ((CltrWidget*)(w))
CltrWidget* CltrWidget*
cltr_widget_new(void); cltr_widget_new(void);
int
cltr_widget_width(CltrWidget *widget);
int
cltr_widget_height(CltrWidget *widget);
void void
cltr_widget_show(CltrWidget *widget); cltr_widget_show(CltrWidget *widget);
void void
cltr_widget_paint(CltrWidget *widget); cltr_widget_paint(CltrWidget *widget);
gboolean gboolean
cltr_widget_handle_xevent(CltrWidget *widget, XEvent *xev); cltr_widget_handle_xevent(CltrWidget *widget, XEvent *xev);
void void
cltr_widget_show_all(CltrWidget *widget); cltr_widget_show_all(CltrWidget *widget);
@ -32,5 +34,4 @@ cltr_widget_queue_paint(CltrWidget *widget);
void void
cltr_widget_add_child(CltrWidget *widget, CltrWidget *child, int x, int y); cltr_widget_add_child(CltrWidget *widget, CltrWidget *child, int x, int y);
#endif #endif

View File

@ -17,6 +17,19 @@ struct CltrWindow
CltrWidget *focused_child; 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* CltrWidget*
cltr_window_new(int width, int height) cltr_window_new(int width, int height)
{ {
@ -46,16 +59,10 @@ cltr_window_new(int width, int height)
/* All likely better somewhere else */ /* 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); ctx->window = CLTR_WIDGET(win);
clrt_window_set_gl_viewport(win);
return CLTR_WIDGET(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 static gboolean
cltr_window_handle_xevent (CltrWidget *widget, XEvent *xev) 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); 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 */ /* XXX Very basic - assumes we are only interested in mouse clicks */
if (win->focused_child) if (win->focused_child)
return cltr_widget_handle_xevent(win->focused_child, xev); return cltr_widget_handle_xevent(win->focused_child, xev);
@ -110,6 +133,25 @@ cltr_window_xwin(CltrWindow *win)
return win->xwin; 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 Window
cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget) cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget)
{ {
@ -118,6 +160,7 @@ cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget)
ClutterMainContext *ctx = CLTR_CONTEXT(); ClutterMainContext *ctx = CLTR_CONTEXT();
win->focused_child = widget; win->focused_child = widget;
} }

View File

@ -21,6 +21,9 @@ cltr_window_add_widget(CltrWindow *win, CltrWidget *widget, int x, int y);
Window Window
cltr_window_xwin(CltrWindow *win); cltr_window_xwin(CltrWindow *win);
void
cltr_window_set_fullscreen(CltrWindow *win);
Window Window
cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget); cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget);

73
cltr.c
View File

@ -1,41 +1,84 @@
#include "cltr.h" #include "cltr.h"
int
usage(char *progname)
{
fprintf(stderr, "Usage ... check source for now\n");
exit(-1);
}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
int i;
CltrWidget *win = NULL, *grid = NULL, *test = NULL, *test2 = NULL; CltrWidget *win = NULL, *grid = NULL, *test = NULL, *test2 = NULL;
CltrWidget *list;
if (argc < 2) gchar *img_path = NULL;
{ gboolean want_fullscreen = FALSE;
g_printerr("usage: '%s' <path to not too heavily populated image dir>\n" gint cols = 3;
, argv[0]);
exit(-1);
}
cltr_init(&argc, &argv); 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]);
}
/* usage(argv[0]);
grid = cltr_photo_grid_new(640, 480, 4, 4, argv[1]); }
test = cltr_scratch_new(100, 100); win = cltr_window_new(800, 600);
test2 = cltr_scratch_new(150, 150);
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); 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, test, 320, 240);
cltr_widget_add_child(win, test2, 400, 300); cltr_widget_add_child(win, test2, 400, 300);
cltr_window_focus_widget(CLTR_WINDOW(win), grid);
*/
list = cltr_list_new(640,480,640, 160); list = cltr_list_new(640,480,640, 160);
cltr_widget_add_child(win, list, 0, 0); cltr_widget_add_child(win, list, 0, 0);
*/
cltr_widget_show_all(win); cltr_widget_show_all(win);
cltr_main_loop(); cltr_main_loop();

2
cltr.h
View File

@ -8,6 +8,7 @@
#include <math.h> #include <math.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/keysym.h> #include <X11/keysym.h>
#include <GL/glx.h> #include <GL/glx.h>
@ -43,6 +44,7 @@ CltrRect;
/* ******************* */ /* ******************* */
#include "cltr-core.h" #include "cltr-core.h"
#include "cltr-glu.h"
#include "cltr-texture.h" #include "cltr-texture.h"
#include "cltr-events.h" #include "cltr-events.h"
#include "cltr-widget.h" #include "cltr-widget.h"

View File

@ -146,11 +146,11 @@ font_draw(ClutterFont *font,
Pixbuf *pixb, Pixbuf *pixb,
const char *text, const char *text,
int x, int x,
int y) int y,
PixbufPixel *p)
{ {
int layout_width, layout_height; int layout_width, layout_height;
PangoLayout *layout; PangoLayout *layout;
PixbufPixel p = { 0xff,0xff,0xff,0x80 };
layout = pango_layout_new (font->context); 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 */ /* 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, x,
y, y,
pixb->width - x, pixb->width - x,

View File

@ -25,7 +25,8 @@ font_draw(ClutterFont *font,
Pixbuf *pixb, Pixbuf *pixb,
const char *text, const char *text,
int x, int x,
int y); int y,
PixbufPixel *p);
#endif #endif

259
pixbuf.c
View File

@ -458,7 +458,7 @@ pixbuf_new(int width, int height)
pixb->bytes_per_line = pixb->bytes_per_pixel * pixb->width; pixb->bytes_per_line = pixb->bytes_per_pixel * pixb->width;
pixb->data = malloc(pixb->bytes_per_line * pixb->height); pixb->data = malloc(pixb->bytes_per_line * pixb->height);
/* memset ? */ memset(pixb->data, 0, pixb->bytes_per_line * pixb->height);
return pixb; return pixb;
} }
@ -671,3 +671,260 @@ pixbuf_scale_down(Pixbuf *pixb,
return pixb_scaled; 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