This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project gfxprim.git.
The branch, master has been updated via a2550171ddb5623635256c50ffa60e5e20d6b2dd (commit) via cd3240b7d4f5cd92e2dbbf750807cfac4d8299ea (commit) via c696722f489a1cd8e8019dd27821e260f2f80756 (commit) from 55303a1b980b3e008a6cac5cf9070e21c1814a51 (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- http://repo.or.cz/w/gfxprim.git/commit/a2550171ddb5623635256c50ffa60e5e20d6b...
commit a2550171ddb5623635256c50ffa60e5e20d6b2dd Author: Cyril Hrubis metan@ucw.cz Date: Tue Nov 1 21:04:39 2011 +0100
fbshow: Now with two threads (needs a little cleaup).
diff --git a/demos/fbshow/Makefile b/demos/fbshow/Makefile index 0a8147c..a3bf9c3 100644 --- a/demos/fbshow/Makefile +++ b/demos/fbshow/Makefile @@ -3,6 +3,7 @@ TOPDIR=../.. CSOURCES=$(shell echo *.c)
INCLUDE= +CFLAGS+=-pthread LDLIBS+=-lGP -L$(TOPDIR)/build/
APPS=fbshow diff --git a/demos/fbshow/fbshow.c b/demos/fbshow/fbshow.c index 37f7e3a..260e821 100644 --- a/demos/fbshow/fbshow.c +++ b/demos/fbshow/fbshow.c @@ -29,6 +29,7 @@ #include <signal.h> #include <unistd.h> #include <string.h> +#include <pthread.h>
#include <GP.h> #include <backends/GP_Framebuffer.h> @@ -39,17 +40,23 @@ static GP_Pixel white_pixel;
static GP_Framebuffer *fb = NULL;
+/* image loader thread */ +static int abort_flag = 0; static int rotate = 0;
- -static void sighandler(int signo __attribute__((unused))) +static int image_loader_callback(GP_ProgressCallback *self) { - if (fb != NULL) - GP_FramebufferExit(fb); - - exit(1); + if (abort_flag) + return 1; + + return 0; }
+struct loader_params { + const char *img_path; + int clear; +}; + static float calc_img_size(uint32_t img_w, uint32_t img_h, uint32_t src_w, uint32_t src_h) { @@ -59,23 +66,29 @@ static float calc_img_size(uint32_t img_w, uint32_t img_h, return GP_MIN(w_rat, h_rat); }
-static int show_image(GP_Framebuffer *fb, const char *img_path, int clear) +static void *image_loader(void *ptr) { - GP_Context *img; + struct loader_params *params = ptr;
- fprintf(stderr, "Loading '%s'n", img_path); + fprintf(stderr, "Loading '%s'n", params->img_path);
- if (clear) { + if (params->clear) { char buf[100]; - snprintf(buf, sizeof(buf), "Loading '%s'", img_path); + snprintf(buf, sizeof(buf), "Loading '%s'", params->img_path); GP_Fill(&fb->context, black_pixel); GP_BoxCenteredText(&fb->context, NULL, 0, 0, fb->context.w, fb->context.h, buf, white_pixel); }
- if (GP_LoadImage(img_path, &img) != 0) - return 1; + GP_Context *img = NULL; + + if (GP_LoadImage(params->img_path, &img) != 0) { + GP_BoxCenteredText(&fb->context, NULL, 0, 0, + fb->context.w, fb->context.h, + "Failed to load image", white_pixel); + return NULL; + }
GP_Size w, h;
@@ -94,7 +107,7 @@ static int show_image(GP_Framebuffer *fb, const char *img_path, int clear) }
float rat = calc_img_size(img->w, img->h, w, h); - + /* Workaround */ if (img->pixel_type != GP_PIXEL_RGB888) { GP_Context *tmp = GP_ContextConvert(img, GP_PIXEL_RGB888); @@ -102,23 +115,29 @@ static int show_image(GP_Framebuffer *fb, const char *img_path, int clear) img = tmp; } + GP_ProgressCallback callback = {.callback = image_loader_callback}; + GP_Context *ret;
-// GP_FilterGaussianBlur(img, img, 0.7, 0.7, NULL); - ret = GP_FilterResize(img, NULL, GP_INTERP_CUBIC, img->w * rat, img->h * rat, NULL); +// if (GP_FilterGaussianBlur(img, img, 0.7, 0.7, &callback)) +// return NULL; + ret = GP_FilterResize(img, NULL, GP_INTERP_CUBIC, img->w * rat, img->h * rat, &callback); GP_ContextFree(img);
+ if (ret == NULL) + return NULL; + switch (rotate) { case 0: break; case 90: - img = GP_FilterRotate90(ret, NULL, NULL); + img = GP_FilterRotate90(ret, NULL, &callback); break; case 180: - img = GP_FilterRotate180(ret, NULL, NULL); + img = GP_FilterRotate180(ret, NULL, &callback); break; case 270: - img = GP_FilterRotate270(ret, NULL, NULL); + img = GP_FilterRotate270(ret, NULL, &callback); break; }
@@ -127,6 +146,9 @@ static int show_image(GP_Framebuffer *fb, const char *img_path, int clear) ret = img; }
+ if (img == NULL) + return NULL; + uint32_t cx = (fb->context.w - ret->w)/2; uint32_t cy = (fb->context.h - ret->h)/2;
@@ -139,7 +161,42 @@ static int show_image(GP_Framebuffer *fb, const char *img_path, int clear) GP_FillRectXYWH(&fb->context, ret->w+cx, 0, cx, fb->context.h, black_pixel); GP_FillRectXYWH(&fb->context, 0, ret->h+cy, fb->context.w, cy, black_pixel);
- return 0; + return NULL; +} + +static pthread_t loader_thread = (pthread_t)0; +static struct loader_params params; + +static void show_image(const char *img_path, int clear) +{ + int ret; + + params.img_path = img_path; + params.clear = clear; + + /* stop previous loader thread */ + if (loader_thread) { + abort_flag = 1; + pthread_join(loader_thread, NULL); + loader_thread = (pthread_t)0; + abort_flag = 0; + } + + ret = pthread_create(&loader_thread, NULL, image_loader, (void*)¶ms); + + if (ret) { + fprintf(stderr, "Failed to start thread: %sn", strerror(ret)); + GP_FramebufferExit(fb); + exit(1); + } +} + +static void sighandler(int signo __attribute__((unused))) +{ + if (fb != NULL) + GP_FramebufferExit(fb); + + exit(1); }
int main(int argc, char *argv[]) @@ -204,7 +261,7 @@ int main(int argc, char *argv[]) int argf = optind; int argn = argf;
- show_image(fb, argv[argf], 1); + show_image(argv[argf], 1);
/* Initalize select */ fd_set rfds; @@ -231,7 +288,7 @@ int main(int argc, char *argv[]) if (argn >= argc) argn = argf; - show_image(fb, argv[argn], 0); + show_image(argv[argn], 0); break; default: while (GP_InputDriverLinuxRead(drv)); @@ -245,7 +302,7 @@ int main(int argc, char *argv[]) if (argn >= argc) argn = argf; - show_image(fb, argv[argn], 0); + show_image(argv[argn], 0); }
/* Read and parse events */ @@ -265,7 +322,7 @@ int main(int argc, char *argv[]) rotate += 90; if (rotate > 270) rotate = 0; - show_image(fb, argv[argn], 1); + show_image(argv[argn], 1); break; case GP_KEY_ESC: case GP_KEY_ENTER: @@ -273,11 +330,20 @@ int main(int argc, char *argv[]) GP_FramebufferExit(fb); return 0; break; + case GP_KEY_UP: case GP_KEY_SPACE: argn++; if (argn >= argc) argn = argf; - show_image(fb, argv[argn], 1); + show_image(argv[argn], 1); + break; + case GP_KEY_DOWN: + argn--; + + if (argn < argf) + argn = argc - 1; + + show_image(argv[argn], 1); break; } break; diff --git a/demos/fbshow/runtest.sh b/demos/fbshow/runtest.sh index 163c76c..0794707 100755 --- a/demos/fbshow/runtest.sh +++ b/demos/fbshow/runtest.sh @@ -6,5 +6,4 @@ PROG="$1" shift
-echo "LD_LIBRARY_PATH=../../build/ ./$PROG $@" LD_LIBRARY_PATH=../../build/ ./$PROG "$@"
http://repo.or.cz/w/gfxprim.git/commit/cd3240b7d4f5cd92e2dbbf750807cfac4d829...
commit cd3240b7d4f5cd92e2dbbf750807cfac4d8299ea Author: Cyril Hrubis metan@ucw.cz Date: Tue Nov 1 21:00:55 2011 +0100
Fix the mirror filters.
For odd size and dst != src we must copy the middle odd line.
diff --git a/libs/filters/GP_MirrorV.gen.c.t b/libs/filters/GP_MirrorV.gen.c.t index cdc21cd..a54d949 100644 --- a/libs/filters/GP_MirrorV.gen.c.t +++ b/libs/filters/GP_MirrorV.gen.c.t @@ -30,7 +30,14 @@ int GP_MirrorV_Raw_{{ ps.suffix }}(const GP_Context *src, GP_Context *dst, if (GP_ProgressCallbackReport(callback, 2 * x, src->w, src->h)) return 1; } - + + /* Copy the middle odd line */ + if (src != dst && src->w % 2) { + x = src->w / 2; + for (y = 0; y < src->h; y++) + GP_PutPixel_Raw_{{ ps.suffix }}(dst, x, y, GP_GetPixel_Raw_{{ ps.suffix }}(src, x, y)); + } + GP_ProgressCallbackDone(callback); return 0; } diff --git a/libs/filters/GP_Rotate.c b/libs/filters/GP_Rotate.c index b45b74c..1409e06 100644 --- a/libs/filters/GP_Rotate.c +++ b/libs/filters/GP_Rotate.c @@ -37,19 +37,32 @@ int GP_FilterMirrorH_Raw(const GP_Context *src, GP_Context *dst, GP_DEBUG(1, "Mirroring image horizontally %ux%u", src->w, src->h);
#warning FIXME: non byte aligned pixels - + + /* Note that this should work both for src != dst and src == dst */ for (y = 0; y < src->h/2; y++) { - uint8_t *l1 = dst->pixels + bpr * y; - uint8_t *l2 = dst->pixels + bpr * (src->h - y - 1); - - memcpy(buf, l1, bpr); - memcpy(l1, l2, bpr); - memcpy(l2, buf, bpr); + uint8_t *sl1 = src->pixels + bpr * y; + uint8_t *sl2 = src->pixels + bpr * (src->h - y - 1); + uint8_t *dl1 = dst->pixels + bpr * y; + uint8_t *dl2 = dst->pixels + bpr * (src->h - y - 1); + + memcpy(buf, sl1, bpr); + memcpy(dl1, sl2, bpr); + memcpy(dl2, buf, bpr); if (GP_ProgressCallbackReport(callback, 2 * y, src->h, src->w)) return 1; }
+ /* Copy the middle odd line */ + if (src != dst && src->h % 2) { + y = src->h / 2; + + uint8_t *sl = src->pixels + bpr * y; + uint8_t *dl = dst->pixels + bpr * y; + + memcpy(dl, sl, bpr); + } + GP_ProgressCallbackDone(callback); return 0; }
http://repo.or.cz/w/gfxprim.git/commit/c696722f489a1cd8e8019dd27821e260f2f80...
commit c696722f489a1cd8e8019dd27821e260f2f80756 Author: Cyril Hrubis metan@ucw.cz Date: Tue Nov 1 19:16:28 2011 +0100
The filter could now be aborted from progress callback.
If progress callback returns non zero number the filter is aborted, allocated memory freed and NULL is returned.
diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c index 51c362b..2854ac3 100644 --- a/demos/grinder/grinder.c +++ b/demos/grinder/grinder.c @@ -33,10 +33,12 @@ static GP_ProgressCallback *progress_callback = NULL;
static const char *progress_prefix = NULL;
-static void show_progress(GP_ProgressCallback *self) +static int show_progress(GP_ProgressCallback *self) { fprintf(stderr, "rFilter %s %3.2f%%", progress_prefix, self->percentage); + + return 0; }
static int param_err(const struct param *self, const char *val, void *priv) diff --git a/include/filters/GP_Filter.h b/include/filters/GP_Filter.h index 20d323c..74637ab 100644 --- a/include/filters/GP_Filter.h +++ b/include/filters/GP_Filter.h @@ -33,26 +33,37 @@
/* * Progress callback + * + * Non zero return value from callback will abort current operation + * free memory and return NULL from filter. */ typedef struct GP_ProgressCallback { float percentage; - void (*callback)(struct GP_ProgressCallback *self); + int (*callback)(struct GP_ProgressCallback *self); void *priv; } GP_ProgressCallback;
-static inline void GP_ProgressCallbackReport(GP_ProgressCallback *callback, - float percentage) +static inline int GP_ProgressCallbackReport(GP_ProgressCallback *callback, + unsigned int val, unsigned int max, + unsigned int mul __attribute__((unused))) { if (callback == NULL) - return; + return 0;
- callback->percentage = percentage; - callback->callback(callback); + if (val % 100) + return 0; + + callback->percentage = 100.00 * val / max; + return callback->callback(callback); }
static inline void GP_ProgressCallbackDone(GP_ProgressCallback *callback) { - GP_ProgressCallbackReport(callback, 100); + if (callback == NULL) + return; + + callback->percentage = 100; + callback->callback(callback); }
#endif /* FILTERS_GP_FILTER_H */ diff --git a/include/filters/GP_Linear.h b/include/filters/GP_Linear.h index 3c0d1e9..21c627b 100644 --- a/include/filters/GP_Linear.h +++ b/include/filters/GP_Linear.h @@ -44,9 +44,9 @@ * * GP_FilterGaussianBlur_Raw(context, context, ...); */ -void GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst, - float sigma_x, float sigma_y, - GP_ProgressCallback *callback); +int GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst, + float sigma_x, float sigma_y, + GP_ProgressCallback *callback); /* * Gaussian blur. * @@ -78,9 +78,9 @@ GP_Context *GP_FilterGaussianBlur(const GP_Context *src, GP_Context *dst, * * This function works also in-place. */ -void GP_FilterLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, - float kernel[], uint32_t kw, uint32_t kh, - GP_ProgressCallback *callback); +int GP_FilterLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, + float kernel[], uint32_t kw, uint32_t kh, + GP_ProgressCallback *callback);
/* * Special cases for convolution only in horizontal/vertical direction. @@ -92,12 +92,12 @@ void GP_FilterLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, * * Both works also in-place. */ -void GP_FilterHLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, - float kernel[], uint32_t kw, - GP_ProgressCallback *callback); +int GP_FilterHLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, + float kernel[], uint32_t kw, + GP_ProgressCallback *callback);
-void GP_FilterVLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, - float kernel[], uint32_t kh, - GP_ProgressCallback *callback); +int GP_FilterVLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, + float kernel[], uint32_t kh, + GP_ProgressCallback *callback);
#endif /* FILTERS_GP_LINEAR_H */ diff --git a/include/filters/GP_Resize.h b/include/filters/GP_Resize.h index 63a6143..692339c 100644 --- a/include/filters/GP_Resize.h +++ b/include/filters/GP_Resize.h @@ -54,9 +54,9 @@ typedef enum GP_InterpolationType { /* * Just interpolate the source context into destination context. */ -void GP_FilterResize_Raw(const GP_Context *src, GP_Context *dst, - GP_InterpolationType type, - GP_ProgressCallback *callback); +int GP_FilterResize_Raw(const GP_Context *src, GP_Context *dst, + GP_InterpolationType type, + GP_ProgressCallback *callback);
/* * If destination is non NULL, the w and h are used to create subcontext from diff --git a/include/filters/GP_Rotate.h b/include/filters/GP_Rotate.h index 245e3c2..515d2b5 100644 --- a/include/filters/GP_Rotate.h +++ b/include/filters/GP_Rotate.h @@ -37,8 +37,8 @@ * * Works 'in place'. The contexts must have equal pixel_type and size. */ -void GP_FilterMirrorH_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback); +int GP_FilterMirrorH_Raw(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback);
/* * Mirrors bitmap horizontally. @@ -55,8 +55,8 @@ GP_Context *GP_FilterMirrorH(const GP_Context *src, GP_Context *dst, * * Works 'in place'. The contexts must have equal pixel_type and size. */ -void GP_FilterMirrorV_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback); +int GP_FilterMirrorV_Raw(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback);
/* * Mirrors bitmap vertically. @@ -74,14 +74,14 @@ GP_Context *GP_FilterMirrorV(const GP_Context *src, GP_Context *dst, * Doesn't work 'in place'. The contexts must have equal pixel_type size must * match the rotated size (is equal for 180 and swapped for 90 and 270). */ -void GP_FilterRotate90_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback); +int GP_FilterRotate90_Raw(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback);
-void GP_FilterRotate180_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback); +int GP_FilterRotate180_Raw(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback);
-void GP_FilterRotate270_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback); +int GP_FilterRotate270_Raw(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback);
/* * Rotate the context by 90, 180, 270. diff --git a/libs/filters/GP_Linear.c b/libs/filters/GP_Linear.c index b0148c9..e5b8d81 100644 --- a/libs/filters/GP_Linear.c +++ b/libs/filters/GP_Linear.c @@ -49,19 +49,25 @@ static inline void gaussian_kernel_init(float sigma, float *kernel) } }
-static void gaussian_callback_1(GP_ProgressCallback *self) +static int gaussian_callback_horiz(GP_ProgressCallback *self) { - GP_ProgressCallbackReport(self->priv, self->percentage/2); + GP_ProgressCallback *callback = self->priv; + + callback->percentage = self->percentage / 2; + return callback->callback(callback); }
-static void gaussian_callback_2(GP_ProgressCallback *self) +static int gaussian_callback_vert(GP_ProgressCallback *self) { - GP_ProgressCallbackReport(self->priv, self->percentage/2 + 50); + GP_ProgressCallback *callback = self->priv; + + callback->percentage = self->percentage / 2 + 50; + return callback->callback(callback); }
-void GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst, - float sigma_x, float sigma_y, - GP_ProgressCallback *callback) +int GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst, + float sigma_x, float sigma_y, + GP_ProgressCallback *callback) { unsigned int size_x = gaussian_kernel_size(sigma_x); unsigned int size_y = gaussian_kernel_size(sigma_y); @@ -72,7 +78,7 @@ void GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *new_callback = NULL;
GP_ProgressCallback gaussian_callback = { - .callback = gaussian_callback_1, + .callback = gaussian_callback_horiz, .priv = callback };
@@ -84,23 +90,26 @@ void GP_FilterGaussianBlur_Raw(const GP_Context *src, GP_Context *dst, float kernel_x[size_x]; gaussian_kernel_init(sigma_x, kernel_x); - GP_FilterHLinearConvolution_Raw(src, dst, kernel_x, size_x, - new_callback); + if (GP_FilterHLinearConvolution_Raw(src, dst, kernel_x, size_x, + new_callback)) + return 1; } if (new_callback != NULL) - new_callback->callback = gaussian_callback_2; + new_callback->callback = gaussian_callback_vert;
/* compute kernel and apply in vertical direction */ if (sigma_y > 0) { float kernel_y[size_y]; gaussian_kernel_init(sigma_y, kernel_y); - GP_FilterVLinearConvolution_Raw(dst, dst, kernel_y, size_y, - new_callback); + if (GP_FilterVLinearConvolution_Raw(dst, dst, kernel_y, size_y, + new_callback)) + return 1; }
GP_ProgressCallbackDone(callback); + return 0; }
GP_Context *GP_FilterGaussianBlur(const GP_Context *src, GP_Context *dst, @@ -128,9 +137,9 @@ GP_Context *GP_FilterGaussianBlur(const GP_Context *src, GP_Context *dst, return dst; }
-void GP_FilterHLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, - float kernel[], uint32_t kw, - GP_ProgressCallback *callback) +int GP_FilterHLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, + float kernel[], uint32_t kw, + GP_ProgressCallback *callback) { float kernel_sum = 0; GP_Coord x, y; @@ -221,11 +230,12 @@ void GP_FilterHLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, idx = 0; } - if (callback != NULL && y % 100 == 0) - GP_ProgressCallbackReport(callback, 100.00 * y/dst->h); + if (GP_ProgressCallbackReport(callback, y, dst->h, dst->w)) + return 1; }
GP_ProgressCallbackDone(callback); + return 0; }
/* @@ -233,9 +243,9 @@ void GP_FilterHLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, * * Can be used in-place. */ -void GP_FilterVLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, - float kernel[], uint32_t kh, - GP_ProgressCallback *callback) +int GP_FilterVLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, + float kernel[], uint32_t kh, + GP_ProgressCallback *callback) { float kernel_sum = 0; GP_Coord x, y; @@ -326,11 +336,12 @@ void GP_FilterVLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, idx = 0; } - if (callback != NULL && x % 100 == 0) - GP_ProgressCallbackReport(callback, 100.00 * x/dst->w); + if (GP_ProgressCallbackReport(callback, x, dst->w, dst->h)) + return 1; }
GP_ProgressCallbackDone(callback); + return 0; }
@@ -339,9 +350,9 @@ void GP_FilterVLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, * * Can be used in-place. */ -void GP_FilterLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, - float kernel[], uint32_t kw, uint32_t kh, - GP_ProgressCallback *callback) +int GP_FilterLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, + float kernel[], uint32_t kw, uint32_t kh, + GP_ProgressCallback *callback) { float kernel_sum = 0; GP_Coord x, y; @@ -452,9 +463,10 @@ void GP_FilterLinearConvolution_Raw(const GP_Context *src, GP_Context *dst, idx = 0; } - if (callback != NULL && y % 100 == 0) - GP_ProgressCallbackReport(callback, 100.00 * y/dst->h); + if (GP_ProgressCallbackReport(callback, y, dst->h, dst->w)) + return 1; }
GP_ProgressCallbackDone(callback); + return 0; } diff --git a/libs/filters/GP_MirrorV.gen.c.t b/libs/filters/GP_MirrorV.gen.c.t index c696349..cdc21cd 100644 --- a/libs/filters/GP_MirrorV.gen.c.t +++ b/libs/filters/GP_MirrorV.gen.c.t @@ -11,7 +11,7 @@ Vertical Mirror alogorithm #include "GP_Rotate.h"
%% for ps in pixelsizes -void GP_MirrorV_Raw_{{ ps.suffix }}(const GP_Context *src, GP_Context *dst, +int GP_MirrorV_Raw_{{ ps.suffix }}(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback) { uint32_t x, y; @@ -27,18 +27,20 @@ void GP_MirrorV_Raw_{{ ps.suffix }}(const GP_Context *src, GP_Context *dst, GP_PutPixel_Raw_{{ ps.suffix }}(dst, xm, y, tmp); }
- if (callback != NULL && x % 100 == 0) - GP_ProgressCallbackReport(callback, 200.00 * x / src->w); + if (GP_ProgressCallbackReport(callback, 2 * x, src->w, src->h)) + return 1; } GP_ProgressCallbackDone(callback); + return 0; }
%% endfor
-void GP_FilterMirrorV_Raw(const GP_Context *src, GP_Context *dst, +int GP_FilterMirrorV_Raw(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback) { - GP_FN_PER_BPP_CONTEXT(GP_MirrorV_Raw, src, src, dst, callback); + GP_FN_RET_PER_BPP_CONTEXT(GP_MirrorV_Raw, src, src, dst, callback); + return 1; } %% endblock body diff --git a/libs/filters/GP_Resize.c b/libs/filters/GP_Resize.c index eb42478..1c7d593 100644 --- a/libs/filters/GP_Resize.c +++ b/libs/filters/GP_Resize.c @@ -27,8 +27,8 @@
#include <GP_Resize.h>
-void GP_FilterInterpolate_NN(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +int GP_FilterInterpolate_NN(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { GP_Coord x, y; @@ -46,11 +46,12 @@ void GP_FilterInterpolate_NN(const GP_Context *src, GP_Context *dst, GP_PutPixel_Raw_24BPP(dst, x, y, pix); } - if (callback != NULL && y % 100 == 0) - GP_ProgressCallbackReport(callback, 100.00 * y/dst->h); + if (GP_ProgressCallbackReport(callback, y, dst->h, dst->w)) + return 1; }
GP_ProgressCallbackDone(callback); + return 0; }
#define A 0.5 @@ -79,8 +80,8 @@ typedef union v4f { #define MUL_V4SF(a, b) ((union v4f)((a).v * (b).v)) #define SUM_V4SF(a) ((a).f[0] + (a).f[1] + (a).f[2] + (a).f[3])
-void GP_FilterInterpolate_Cubic(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +int GP_FilterInterpolate_Cubic(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { float col_r[src->h], col_g[src->h], col_b[src->h]; uint32_t i, j; @@ -202,25 +203,26 @@ void GP_FilterInterpolate_Cubic(const GP_Context *src, GP_Context *dst, GP_PutPixel_Raw_24BPP(dst, i, j, pix); } - if (callback != NULL && i % 100 == 0) - GP_ProgressCallbackReport(callback, 100.00 * i/dst->w); + if (GP_ProgressCallbackReport(callback, i, dst->w, dst->h)) + return 1; }
GP_ProgressCallbackDone(callback); + return 0; }
-void GP_FilterResize_Raw(const GP_Context *src, GP_Context *dst, - GP_InterpolationType type, - GP_ProgressCallback *callback) +int GP_FilterResize_Raw(const GP_Context *src, GP_Context *dst, + GP_InterpolationType type, + GP_ProgressCallback *callback) { switch (type) { case GP_INTERP_NN: - GP_FilterInterpolate_NN(src, dst, callback); - break; + return GP_FilterInterpolate_NN(src, dst, callback); case GP_INTERP_CUBIC: - GP_FilterInterpolate_Cubic(src, dst, callback); - break; + return GP_FilterInterpolate_Cubic(src, dst, callback); } + + return 1; }
GP_Context *GP_FilterResize(const GP_Context *src, GP_Context *dst, @@ -235,12 +237,10 @@ GP_Context *GP_FilterResize(const GP_Context *src, GP_Context *dst, return NULL;
if (dst == NULL) { - dst = GP_ContextAlloc(w, h, src->pixel_type); + res = GP_ContextAlloc(w, h, src->pixel_type);
- if (dst == NULL) + if (res == NULL) return NULL; - - res = dst; } else { GP_ASSERT(src->pixel_type == dst->pixel_type, "The src and dst pixel types must match"); @@ -250,7 +250,19 @@ GP_Context *GP_FilterResize(const GP_Context *src, GP_Context *dst, res = GP_ContextSubContext(dst, &sub, 0, 0, w, h); }
- GP_FilterResize_Raw(src, res, type, callback); + /* + * Operation was aborted by progress callback. + * + * Free any alloacted data and exit. + */ + if (GP_FilterResize_Raw(src, res, type, callback)) { + GP_DEBUG(1, "Operation aborted"); + + if (dst == NULL) + GP_ContextFree(dst); + + return NULL; + }
- return dst; + return dst == NULL ? res : dst; } diff --git a/libs/filters/GP_Rotate.c b/libs/filters/GP_Rotate.c index 73987e7..b45b74c 100644 --- a/libs/filters/GP_Rotate.c +++ b/libs/filters/GP_Rotate.c @@ -27,8 +27,8 @@
#include <string.h>
-void GP_FilterMirrorH_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +int GP_FilterMirrorH_Raw(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { uint32_t bpr = src->bytes_per_row; uint8_t buf[bpr]; @@ -46,20 +46,23 @@ void GP_FilterMirrorH_Raw(const GP_Context *src, GP_Context *dst, memcpy(l1, l2, bpr); memcpy(l2, buf, bpr); - if (callback != NULL && y % 100 == 0) - GP_ProgressCallbackReport(callback, 200.00 * y / src->h); + if (GP_ProgressCallbackReport(callback, 2 * y, src->h, src->w)) + return 1; }
GP_ProgressCallbackDone(callback); + return 0; }
GP_Context *GP_FilterMirrorH(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback) { - if (dst == NULL) { - dst = GP_ContextCopy(src, 0); + GP_Context *res = dst; + + if (res == NULL) { + res = GP_ContextCopy(src, 0); - if (dst == NULL) + if (res == NULL) return NULL; } else { GP_ASSERT(src->pixel_type == dst->pixel_type, @@ -68,19 +71,28 @@ GP_Context *GP_FilterMirrorH(const GP_Context *src, GP_Context *dst, "Destination is not big enough"); }
- GP_FilterMirrorH_Raw(src, dst, callback); + if (GP_FilterMirrorH_Raw(src, res, callback)) { + GP_DEBUG(1, "Operation aborted"); + + if (dst == NULL) + GP_ContextFree(res); + + return NULL; + }
- return dst; + return res; }
GP_Context *GP_FilterMirrorV(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback) { - if (dst == NULL) { - dst = GP_ContextCopy(src, 0); + GP_Context *res = dst; + + if (res == NULL) { + res = GP_ContextCopy(src, 0); - if (dst == NULL) + if (res == NULL) return NULL; } else { GP_ASSERT(src->pixel_type == dst->pixel_type, @@ -89,27 +101,38 @@ GP_Context *GP_FilterMirrorV(const GP_Context *src, GP_Context *dst, "Destination is not big enough"); } - GP_FilterMirrorV_Raw(src, dst, callback); + if (GP_FilterMirrorV_Raw(src, dst, callback)) { + GP_DEBUG(1, "Operation aborted"); + + if (dst == NULL) + GP_ContextFree(res); + + return NULL; + }
- return dst; + return res; }
-void GP_FilterRotate180_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +int GP_FilterRotate180_Raw(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { #warning FIXME: Callbacks, faster algorighm?
GP_FilterMirrorV_Raw(src, dst, NULL); GP_FilterMirrorH_Raw(dst, dst, callback); + + return 0; }
GP_Context *GP_FilterRotate90(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback) { - if (dst == NULL) { - dst = GP_ContextAlloc(src->h, src->w, src->pixel_type); + GP_Context *res = dst; + + if (res == NULL) { + res = GP_ContextAlloc(src->h, src->w, src->pixel_type); - if (dst == NULL) + if (res == NULL) return NULL; } else { GP_ASSERT(src->pixel_type == dst->pixel_type, @@ -118,18 +141,27 @@ GP_Context *GP_FilterRotate90(const GP_Context *src, GP_Context *dst, "Destination is not big enough"); }
- GP_FilterRotate90_Raw(src, dst, callback); + if (GP_FilterRotate90_Raw(src, res, callback)) { + GP_DEBUG(1, "Operation aborted"); + + if (dst == NULL) + GP_ContextFree(res); + + return NULL; + }
- return dst; + return res; }
GP_Context *GP_FilterRotate180(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback) { - if (dst == NULL) { - dst = GP_ContextCopy(src, 0); + GP_Context *res = dst; + + if (res == NULL) { + res = GP_ContextCopy(src, 0); - if (dst == NULL) + if (res == NULL) return NULL; } else { GP_ASSERT(src->pixel_type == dst->pixel_type, @@ -138,18 +170,27 @@ GP_Context *GP_FilterRotate180(const GP_Context *src, GP_Context *dst, "Destination is not big enough"); }
- GP_FilterRotate180_Raw(src, dst, callback); + if (GP_FilterRotate180_Raw(src, res, callback)) { + GP_DEBUG(1, "Operation aborted"); + + if (dst == NULL) + GP_ContextFree(res); + + return NULL; + }
- return dst; + return res; }
GP_Context *GP_FilterRotate270(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback) { - if (dst == NULL) { - dst = GP_ContextAlloc(src->h, src->w, src->pixel_type); + GP_Context *res = dst; + + if (res == NULL) { + res = GP_ContextAlloc(src->h, src->w, src->pixel_type); - if (dst == NULL) + if (res == NULL) return NULL; } else { GP_ASSERT(src->pixel_type == dst->pixel_type, @@ -158,9 +199,16 @@ GP_Context *GP_FilterRotate270(const GP_Context *src, GP_Context *dst, "Destination is not big enough"); }
- GP_FilterRotate270_Raw(src, dst, callback); + if (GP_FilterRotate270_Raw(src, res, callback)) { + GP_DEBUG(1, "Operation aborted"); + + if (dst == NULL) + GP_ContextFree(res); + + return NULL; + }
- return dst; + return res; }
GP_Context *GP_FilterSymmetry(const GP_Context *src, GP_Context *dst, @@ -180,5 +228,7 @@ GP_Context *GP_FilterSymmetry(const GP_Context *src, GP_Context *dst, return GP_FilterMirrorV(src, dst, callback); }
+ GP_DEBUG(1, "Invalid symmetry %i", (int) symmetry); + return NULL; } diff --git a/libs/filters/GP_Rotate.gen.c.t b/libs/filters/GP_Rotate.gen.c.t index 9ef7bd9..af2e679 100644 --- a/libs/filters/GP_Rotate.gen.c.t +++ b/libs/filters/GP_Rotate.gen.c.t @@ -11,8 +11,8 @@ Vertical Mirror alogorithm #include "GP_Rotate.h"
%% for ps in pixelsizes -void GP_FilterRotate90_Raw_{{ ps.suffix }}(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +int GP_FilterRotate90_Raw_{{ ps.suffix }}(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { uint32_t x, y; @@ -24,23 +24,25 @@ void GP_FilterRotate90_Raw_{{ ps.suffix }}(const GP_Context *src, GP_Context *ds GP_PutPixel_Raw_{{ ps.suffix }}(dst, yr, x, GP_GetPixel_Raw_{{ ps.suffix }}(src, x, y)); } - if (callback != NULL && x % 100 == 0) - GP_ProgressCallbackReport(callback, 100.00 * x / src->w); + if (GP_ProgressCallbackReport(callback, x, src->w, src->h)) + return 1; } GP_ProgressCallbackDone(callback); + return 0; }
%% endfor
-void GP_FilterRotate90_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +int GP_FilterRotate90_Raw(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { - GP_FN_PER_BPP_CONTEXT(GP_FilterRotate90_Raw, src, src, dst, callback); + GP_FN_RET_PER_BPP_CONTEXT(GP_FilterRotate90_Raw, src, src, dst, callback); + return 1; }
%% for ps in pixelsizes -void GP_FilterRotate270_Raw_{{ ps.suffix }}(const GP_Context *src, GP_Context *dst, +int GP_FilterRotate270_Raw_{{ ps.suffix }}(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback) { uint32_t x, y; @@ -53,19 +55,21 @@ void GP_FilterRotate270_Raw_{{ ps.suffix }}(const GP_Context *src, GP_Context *d GP_PutPixel_Raw_{{ ps.suffix }}(dst, y, xr, GP_GetPixel_Raw_{{ ps.suffix }}(src, x, y)); }
- if (callback != NULL && x % 100 == 0) - GP_ProgressCallbackReport(callback, 100.00 * x / src->w); + if (GP_ProgressCallbackReport(callback, x, src->w, src->h)) + return 1; } GP_ProgressCallbackDone(callback); + return 0; }
%% endfor
-void GP_FilterRotate270_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +int GP_FilterRotate270_Raw(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { - GP_FN_PER_BPP_CONTEXT(GP_FilterRotate270_Raw, src, src, dst, callback); + GP_FN_RET_PER_BPP_CONTEXT(GP_FilterRotate270_Raw, src, src, dst, callback); + return 1; }
%% endblock body diff --git a/pylib/templates/filter.point.c.t b/pylib/templates/filter.point.c.t index 4c3bdaa..9a925cf 100644 --- a/pylib/templates/filter.point.c.t +++ b/pylib/templates/filter.point.c.t @@ -16,7 +16,7 @@ %% macro filter_per_pixel_size(name, opts="") %% for ps in pixelsizes %% if ps.size <= 8 and ps.size > 1 -void GP_Filter{{ name }}_{{ ps.suffix }}(const GP_Context *src, GP_Context *dst{{ maybe_opts(opts) }}, +int GP_Filter{{ name }}_{{ ps.suffix }}(const GP_Context *src, GP_Context *dst{{ maybe_opts(opts) }}, GP_ProgressCallback *callback) { uint32_t x, y; @@ -28,11 +28,12 @@ void GP_Filter{{ name }}_{{ ps.suffix }}(const GP_Context *src, GP_Context *dst{ GP_PutPixel_Raw_{{ ps.suffix }}(dst, x, y, pix); } - if (callback != NULL && y % 100 == 0) - GP_ProgressCallbackReport(callback, 100.00 * y/src->h); + if (GP_ProgressCallbackReport(callback, y, src->h, src->w)) + return 1; }
GP_ProgressCallbackDone(callback); + return 0; } %% endif %% endfor @@ -44,7 +45,7 @@ void GP_Filter{{ name }}_{{ ps.suffix }}(const GP_Context *src, GP_Context *dst{ %% macro filter_per_pixel_type(name, opts="") %% for pt in pixeltypes %% if not pt.is_unknown() and len(pt.chanslist) > 1 -void GP_Filter{{ name }}_{{ pt.name }}(const GP_Context *src, GP_Context *dst{{ maybe_opts(opts) }}, +int GP_Filter{{ name }}_{{ pt.name }}(const GP_Context *src, GP_Context *dst{{ maybe_opts(opts) }}, GP_ProgressCallback *callback) { uint32_t x, y; @@ -65,11 +66,12 @@ void GP_Filter{{ name }}_{{ pt.name }}(const GP_Context *src, GP_Context *dst{{ GP_PutPixel_Raw_{{ pt.pixelsize.suffix }}(dst, x, y, pix); } - if (callback != NULL && y % 100 == 0) - GP_ProgressCallbackReport(callback, 100.00 * y/src->h); + if (GP_ProgressCallbackReport(callback, y, src->h, src->w)) + return 1; }
GP_ProgressCallbackDone(callback); + return 0; }
%% endif @@ -91,7 +93,7 @@ void GP_Filter{{ name }}_{{ pt.name }}(const GP_Context *src, GP_Context *dst{{ * Switch per pixel sizes or pixel types. */ %% macro filter_functions(name, opts="", params="", fmt="") -void GP_Filter{{ name }}_Raw(const GP_Context *src, GP_Context *dst{{ maybe_opts(opts) }}, +int GP_Filter{{ name }}_Raw(const GP_Context *src, GP_Context *dst{{ maybe_opts(opts) }}, GP_ProgressCallback *callback) { GP_DEBUG(1, "Running filter {{ name }} {{ fmt }}"{{ maybe_opts(params) }}); @@ -100,27 +102,29 @@ void GP_Filter{{ name }}_Raw(const GP_Context *src, GP_Context *dst{{ maybe_opts %% for pt in pixeltypes case GP_PIXEL_{{ pt.name }}: %% if pt.is_unknown() or pt.pixelsize.size < 2 - return; + return 1; %% elif len(pt.chanslist) == 1: - GP_Filter{{ name }}_{{ pt.pixelsize.suffix }}(src, dst{{ maybe_opts(params) }}, callback); + return GP_Filter{{ name }}_{{ pt.pixelsize.suffix }}(src, dst{{ maybe_opts(params) }}, callback); %% else - GP_Filter{{ name }}_{{ pt.name }}(src, dst{{ maybe_opts(params) }}, callback); + return GP_Filter{{ name }}_{{ pt.name }}(src, dst{{ maybe_opts(params) }}, callback); %% endif - break; %% endfor default: break; } + + return 1; }
GP_Context *GP_Filter{{ name }}(const GP_Context *src, GP_Context *dst{{ maybe_opts(opts) }}, GP_ProgressCallback *callback) { + GP_Context *res = dst;
- if (dst == NULL) { - dst = GP_ContextCopy(src, 0); + if (res == NULL) { + res = GP_ContextCopy(src, 0);
- if (dst == NULL) + if (res == NULL) return NULL; } else { GP_ASSERT(src->pixel_type == dst->pixel_type, @@ -129,9 +133,16 @@ GP_Context *GP_Filter{{ name }}(const GP_Context *src, GP_Context *dst{{ maybe_o "Destination is not big enough"); }
- GP_Filter{{ name }}_Raw(src, dst{{ maybe_opts(params) }}, callback); + if (GP_Filter{{ name }}_Raw(src, dst{{ maybe_opts(params) }}, callback)) { + GP_DEBUG(1, "Operation aborted"); + + if (dst == NULL) + GP_ContextFree(res); + + return NULL; + }
- return dst; + return res; } %% endmacro
-----------------------------------------------------------------------
Summary of changes: demos/fbshow/Makefile | 1 + demos/fbshow/fbshow.c | 116 +++++++++++++++++++++++++------- demos/fbshow/runtest.sh | 1 - demos/grinder/grinder.c | 4 +- include/filters/GP_Filter.h | 25 +++++-- include/filters/GP_Linear.h | 24 +++--- include/filters/GP_Resize.h | 6 +- include/filters/GP_Rotate.h | 20 +++--- libs/filters/GP_Linear.c | 68 +++++++++++-------- libs/filters/GP_MirrorV.gen.c.t | 21 ++++-- libs/filters/GP_Resize.c | 54 +++++++++------ libs/filters/GP_Rotate.c | 137 +++++++++++++++++++++++++++---------- libs/filters/GP_Rotate.gen.c.t | 30 +++++---- pylib/templates/filter.point.c.t | 43 ++++++++----- 14 files changed, 370 insertions(+), 180 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos@gmail.com if you want to unsubscribe, or site admin admin@repo.or.cz if you receive no reply.