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 177fb88927406348571117c81c0ae6ceac6b92e3 (commit) via d2f0c789183f62bc30cd0638c7da9bf5aa52ba44 (commit) from f13f4d07dae989e9db0a670f5e8bfa7dc78e197d (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/177fb88927406348571117c81c0ae6ceac6b9...
commit 177fb88927406348571117c81c0ae6ceac6b92e3 Author: Cyril Hrubis metan@ucw.cz Date: Sat Jul 13 19:14:05 2013 +0200
spiv: Large scale cleanup.
This is large scale cleanup in spiv which is much needed before the functional changes.
This also fixes several bugs that were not posible to fix before the cleanup, namely:
* Image that doesn't fit to the image cache is now freed (this bug was there since the implementation of the cache)
* Image size in info box is printed correctly even when image is rotated
+ numerous small fixes
Signed-off-by: Cyril Hrubis metan@ucw.cz
diff --git a/demos/spiv/Makefile b/demos/spiv/Makefile index 10bac03..93750f3 100644 --- a/demos/spiv/Makefile +++ b/demos/spiv/Makefile @@ -1,4 +1,5 @@ TOPDIR=../.. +include $(TOPDIR)/pre.mk
CSOURCES=$(shell echo *.c)
@@ -10,8 +11,8 @@ LDLIBS+=$(LDLIBS_LOADERS) $(LDLIBS_BACKENDS)
APPS=spiv
-spiv: cpu_timer.o image_cache.o image_list.o image_actions.o spiv_help.o +spiv: cpu_timer.o image_cache.o image_list.o image_actions.o spiv_help.o+ image_loader.o
-include $(TOPDIR)/pre.mk include $(TOPDIR)/app.mk include $(TOPDIR)/post.mk diff --git a/demos/spiv/image_cache.c b/demos/spiv/image_cache.c index 22f3b70..509d507 100644 --- a/demos/spiv/image_cache.c +++ b/demos/spiv/image_cache.c @@ -20,6 +20,7 @@ * * *****************************************************************************/
+#include <stdarg.h> #include <string.h> #include <GP.h> #include "image_cache.h" @@ -34,8 +35,6 @@ struct image { unsigned int elevated;
/* this identifies an image */ - long cookie1; - long cookie2; char path[]; };
@@ -124,8 +123,7 @@ static void remove_img(struct image_cache *self, struct image *img, size_t size) static void remove_img_free(struct image_cache *self, struct image *img, size_t size) { - GP_DEBUG(2, "Freeing image '%s:%10li:%10li' size %zu", - img->path, img->cookie1, img->cookie2, size); + GP_DEBUG(2, "Freeing image '%s' size %zu", img->path, size);
remove_img(self, img, size); GP_ContextFree(img->ctx); @@ -151,19 +149,18 @@ static void add_img(struct image_cache *self, struct image *img, size_t size) self->end = img; }
-GP_Context *image_cache_get(struct image_cache *self, const char *path, - long cookie1, long cookie2, int elevate) +GP_Context *image_cache_get(struct image_cache *self, int elevate, + const char *key) { struct image *i;
if (self == NULL) return NULL;
- GP_DEBUG(2, "Looking for image '%s:%10li:%10li'", path, cookie1, cookie2); + GP_DEBUG(2, "Looking for image '%s'", key);
for (i = self->root; i != NULL; i = i->next) - if (!strcmp(path, i->path) && - i->cookie1 == cookie1 && i->cookie2 == cookie2) + if (!strcmp(key, i->path)) break;
if (i == NULL) @@ -173,8 +170,7 @@ GP_Context *image_cache_get(struct image_cache *self, const char *path, if (elevate) { size_t size = image_size(i);
- GP_DEBUG(2, "Refreshing image '%s:%10li:%10li", - path, cookie1, cookie2); + GP_DEBUG(2, "Refreshing image '%s'", key);
remove_img(self, i, size); add_img(self, i, size); @@ -185,6 +181,58 @@ GP_Context *image_cache_get(struct image_cache *self, const char *path, return i->ctx; }
+GP_Context *image_cache_get2(struct image_cache *self, int elevate, + const char *fmt, ...) +{ + va_list va; + size_t len; + char buf[512]; + char *key = buf; + struct image *i; + + if (self == NULL) + return NULL; + + va_start(va, fmt); + len = vsnprintf(buf, sizeof(buf), fmt, va); + va_end(va); + + if (len >= sizeof(buf)) { + key = malloc(len + 1); + if (!key) { + GP_WARN("Malloc failed :("); + return NULL; + } + + va_start(va, fmt); + vsprintf(key, fmt, va); + va_end(va); + } + + GP_DEBUG(2, "Looking for image '%s'", key); + + for (i = self->root; i != NULL; i = i->next) + if (!strcmp(key, i->path)) + break; + + /* Push the image to the root of the list */ + if (i && elevate) { + size_t size = image_size(i); + + GP_DEBUG(2, "Refreshing image '%s'", key); + + remove_img(self, i, size); + add_img(self, i, size); + + i->elevated++; + } + + if (len >= sizeof(buf)) + free(key); + + return i ? i->ctx : NULL; +} + void image_cache_print(struct image_cache *self) { struct image *i; @@ -197,8 +245,8 @@ void image_cache_print(struct image_cache *self) printf("Image cache size %u used %un", self->max_size, self->cur_size);
for (i = self->root; i != NULL; i = i->next) - printf(" Image '%s:%10li:%10li' size %10zu elevated %un", i->path, - i->cookie1, i->cookie2, image_size(i), i->elevated); + printf(" size=%10zu elevated=%u key='%s'n", + image_size(i), i->elevated, i->path); }
static int assert_size(struct image_cache *self, size_t size) @@ -219,15 +267,56 @@ static int assert_size(struct image_cache *self, size_t size) return 0; }
-int image_cache_put(struct image_cache *self, GP_Context *ctx, const char *path, - long cookie1, long cookie2) +int image_cache_put(struct image_cache *self, GP_Context *ctx, + const char *key) { size_t size;
if (self == NULL) return 1;
- size = image_size2(ctx, path); + size = image_size2(ctx, key); + + /* + * We try to create room for the image. If this fails we add the image + * anyway because we need to store it while we are showing it (and it + * will be removed from cache by next image for sure). + */ + assert_size(self, size); + + struct image *img = malloc(sizeof(struct image) + strlen(key) + 1); + + if (img == NULL) { + GP_WARN("Malloc failed :("); + return 1; + } + + img->ctx = ctx; + img->elevated = 0; + strcpy(img->path, key); + + GP_DEBUG(2, "Adding image '%s' size %zu", img->path, size); + + add_img(self, img, size); + + return 0; +} + +int image_cache_put2(struct image_cache *self, GP_Context *ctx, + const char *fmt, ...) +{ + size_t size, len; + va_list va; + + if (self == NULL) + return 1; + + va_start(va, fmt); + len = vsnprintf(NULL, 0, fmt, va); + va_end(va); + + //TODO: FIX THIS + size = image_size2(ctx, "") + len + 1;
/* * We try to create room for the image. If this fails we add the image @@ -236,7 +325,7 @@ int image_cache_put(struct image_cache *self, GP_Context *ctx, const char *path, */ assert_size(self, size);
- struct image *img = malloc(sizeof(struct image) + strlen(path) + 1); + struct image *img = malloc(sizeof(struct image) + len + 1);
if (img == NULL) { GP_WARN("Malloc failed :("); @@ -244,13 +333,14 @@ int image_cache_put(struct image_cache *self, GP_Context *ctx, const char *path, }
img->ctx = ctx; - img->cookie1 = cookie1; - img->cookie2 = cookie2; img->elevated = 0; - strcpy(img->path, path);
- GP_DEBUG(2, "Adding image '%s:%10li:%10li' size %zu", - img->path, img->cookie1, img->cookie2, size); + va_start(va, fmt); + vsprintf(img->path, fmt, va); + va_end(va); + + GP_DEBUG(2, "Adding image '%s' size %zu", + img->path, size);
add_img(self, img, size);
diff --git a/demos/spiv/image_cache.h b/demos/spiv/image_cache.h index 1c03545..84cec1d 100644 --- a/demos/spiv/image_cache.h +++ b/demos/spiv/image_cache.h @@ -47,14 +47,21 @@ struct image_cache *image_cache_create(unsigned int max_size_bytes); * If elevate set and image is found, the image is elevated to the top so * it has lesser chance of being freed. */ -GP_Context *image_cache_get(struct image_cache *self, const char *path, - long cookie1, long cookie2, int elevate); +GP_Context *image_cache_get(struct image_cache *self, int elevate, + const char *key);
+GP_Context *image_cache_get2(struct image_cache *self, int elevate, + const char *fmt, ...) + __attribute__ ((format (printf, 3, 4))); /* * Puts an image into a cache. */ int image_cache_put(struct image_cache *self, GP_Context *img, - const char *path, long cookie1, long cookie2); + const char *key); + +int image_cache_put2(struct image_cache *self, GP_Context *img, + const char *fmt, ...) + __attribute__ ((format (printf, 3, 4)));
/* * Drop all image in cache. diff --git a/demos/spiv/image_loader.c b/demos/spiv/image_loader.c new file mode 100644 index 0000000..1c6321f --- /dev/null +++ b/demos/spiv/image_loader.c @@ -0,0 +1,169 @@ +/***************************************************************************** + * This file is part of gfxprim library. * + * * + * Gfxprim is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * Gfxprim is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with gfxprim; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + * Copyright (C) 2009-2013 Cyril Hrubis metan@ucw.cz * + * * + *****************************************************************************/ + +#include <core/GP_Context.h> +#include <core/GP_Debug.h> + +#include <loaders/GP_Loaders.h> + +#include "cpu_timer.h" +#include "image_cache.h" +#include "image_list.h" +#include "image_loader.h" + +static struct image_cache *img_cache; +static struct image_list *img_list; +static GP_Context *cur_img; + +int image_loader_init(const char *args[], unsigned int cache_max_bytes) +{ + img_cache = image_cache_create(cache_max_bytes); + + if (!img_cache) { + GP_WARN("Failed to initialize image cache (size=%u)", + cache_max_bytes); + } + + img_list = image_list_create(args); + + if (!img_list) { + GP_FATAL("Failed to initialize image list"); + return 1; + } + + return 0; +} + +GP_Context *image_loader_get_image(GP_ProgressCallback *callback, int elevate) +{ + struct cpu_timer timer; + const char *path; + GP_Context *img; + + if (cur_img) + return cur_img; + + path = image_list_img_path(img_list); + + cur_img = image_cache_get(img_cache, elevate, path); + + if (cur_img) + return cur_img; + + cpu_timer_start(&timer, "Loading"); + + img = GP_LoadImage(path, callback); + + if (!img) + return NULL; + + image_cache_put(img_cache, img, path); + + cpu_timer_stop(&timer); + + return img; +} + +const char *image_loader_img_path(void) +{ + return image_list_img_path(img_list); +} + +const char *image_loader_img_name(void) +{ + return image_list_img_path(img_list); +} + +static void drop_cur_img(void) +{ + const char *path; + + path = image_list_img_path(img_list); + + /* + * Currently loaded image is too big to be cached -> free it. + */ + if (!image_cache_get(img_cache, 1, path)) + GP_ContextFree(cur_img); + + cur_img = NULL; +} + +void image_loader_seek(enum img_seek_offset offset, int whence) +{ + drop_cur_img(); + + switch (offset) { + case IMG_FIRST: + image_list_first(img_list); + break; + case IMG_LAST: + image_list_last(img_list); + break; + case IMG_CUR: + break; + case IMG_DIR: + image_list_dir_move(img_list, whence); + return; + } + + if (!whence) + return; + + image_list_move(img_list, whence); +} + +unsigned int image_loader_count(void) +{ + return image_list_count(img_list); +} + +unsigned int image_loader_pos(void) +{ + return image_list_pos(img_list); +} + +int image_loader_is_in_dir(void) +{ + return image_list_dir_count(img_list) != 0; +} + +unsigned int image_loader_dir_count(void) +{ + return image_list_dir_count(img_list); +} + +unsigned int image_loader_dir_pos(void) +{ + return image_list_dir_pos(img_list); +} + +void image_loader_drop_cache(void) +{ + image_cache_drop(img_cache); +} + +void image_loader_destroy(void) +{ + image_cache_destroy(img_cache); + //TODO Image list destroy? +} diff --git a/demos/spiv/image_loader.h b/demos/spiv/image_loader.h new file mode 100644 index 0000000..46b65fa --- /dev/null +++ b/demos/spiv/image_loader.h @@ -0,0 +1,116 @@ +/***************************************************************************** + * This file is part of gfxprim library. * + * * + * Gfxprim is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * Gfxprim is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with gfxprim; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + * Copyright (C) 2009-2013 Cyril Hrubis metan@ucw.cz * + * * + *****************************************************************************/ + + /* + + Image loader. + + This is abstraction on the top of the image list and image cache. + + */ + +#ifndef __IMAGE_LOADER_H__ +#define __IMAGE_LOADER_H__ + +#include <core/GP_Context.h> +#include <core/GP_ProgressCallback.h> + +/* + * Initialize image loader. + */ +int image_loader_init(const char *args[], unsigned int cache_max_bytes); + +/* + * Fills pointer to current image. + * + * Returns zero or, in case of failure, errno. + * + * Note that the callback may not be called when the image is cached. + */ +GP_Context *image_loader_get_image(GP_ProgressCallback *callback, int elevate); + +/* + * Returns path to current image. + */ +const char *image_loader_img_path(void); + +/* + * Returns image name. + * + * Note that in case of image containers this is different from the image path. + */ +const char *image_loader_img_name(void); + + +enum img_seek_offset { + IMG_FIRST, + IMG_LAST, + IMG_CUR, + /* + * Seeks to the last image in the directory if whence > 0 + * to the first image in dir otherwise. + */ + IMG_DIR, +}; + +/* + * Changes position in image list. + */ +void image_loader_seek(enum img_seek_offset offset, int whence); + +/* + * Drops image cache. + */ +void image_loader_drop_cache(void); + +/* + * Free all memory, close all files. + */ +void image_loader_destroy(void); + +/* + * Counts images in the image list. + */ +unsigned int image_loader_count(void); + +/* + * Returns current position. + */ +unsigned int image_loader_pos(void); + + +/* + * Returns non-zero if we are in diretory. + */ +int image_loader_is_in_dir(void); + +/* + * Counts number of images in current directory. + */ +unsigned int image_loader_dir_count(void); + +/* + * Returns current position in directory. + */ +unsigned int image_loader_dir_pos(void); + +#endif /* __IMAGE_LOADER_H__ */ diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c index 245412a..c594205 100644 --- a/demos/spiv/spiv.c +++ b/demos/spiv/spiv.c @@ -36,6 +36,7 @@
#include "image_cache.h" #include "image_list.h" +#include "image_loader.h" #include "image_actions.h" #include "spiv_help.h" #include "cpu_timer.h" @@ -75,8 +76,6 @@ enum zoom_type { };
struct loader_params { - /* current image path */ - const char *img_path; /* current resize ratio */ float rat;
@@ -106,10 +105,6 @@ struct loader_params {
/* caches for loaded images */ struct image_cache *img_resized_cache; - struct image_cache *img_orig_cache; - - /* image list structure */ - struct image_list *img_list; };
static int image_loader_callback(GP_ProgressCallback *self) @@ -148,17 +143,16 @@ static int image_loader_callback(GP_ProgressCallback *self) return 0; }
-static GP_Context *load_image(struct loader_params *params, int elevate); +static GP_Context *load_image(int elevate);
/* * Ask backend to resize window may not be implemented or authorized. If * backend (window) is resized we will get SYS_RESIZE event, see the main event * loop. */ -static void resize_backend(struct loader_params *params, - float ratio, int shift_flag) +static void resize_backend(float ratio, int shift_flag) { - GP_Context *img = load_image(params, 1); + GP_Context *img = load_image(1);
if (!shift_flag) ratio = 1.00 / ratio; @@ -188,7 +182,7 @@ static float calc_img_size(struct loader_params *params, case ZOOM_FIXED: return params->zoom; case ZOOM_FIXED_WIN: - resize_backend(params, params->zoom, 0); + resize_backend(params->zoom, 0); return params->zoom; }
@@ -219,51 +213,29 @@ static void set_caption(const char *path, float rat) /* * Loads image */ -static GP_Context *load_image(struct loader_params *params, int elevate) +static GP_Context *load_image(int elevate) { - struct cpu_timer timer; - GP_Context *img, *context = backend->context; - + GP_Context *img; GP_ProgressCallback callback = {.callback = image_loader_callback, .priv = "Loading image"};
- img = image_cache_get(params->img_orig_cache, params->img_path, 0, 0, elevate); - - /* Image not cached, load it */ - if (img == NULL) { - fprintf(stderr, "Loading '%s'n", params->img_path); + img = image_loader_get_image(&callback, elevate);
- cpu_timer_start(&timer, "Loading"); - if ((img = GP_LoadImage(params->img_path, &callback)) == NULL) { - - if (errno == ECANCELED) - return NULL; - - GP_Fill(context, black_pixel); - GP_Print(context, NULL, context->w/2, context->h/2 - 10, - GP_ALIGN_CENTER|GP_VALIGN_CENTER, white_pixel, black_pixel, - "'%s'", params->img_path); - GP_Print(context, NULL, context->w/2, context->h/2 + 10, - GP_ALIGN_CENTER|GP_VALIGN_CENTER, white_pixel, black_pixel, - "Failed to load image :( (%s)", strerror(errno)); - GP_BackendFlip(backend); - return NULL; - } - - /* Workaround */ -// if (img->pixel_type != GP_PIXEL_RGB888) { -// GP_Context *tmp; -// tmp = GP_ContextConvertAlloc(img, GP_PIXEL_RGB888); -// GP_ContextFree(img); -// img = tmp; -// } + if (img) + return img;
- image_cache_put(params->img_orig_cache, img, params->img_path, 0, 0); + GP_Context *ctx = backend->context;
- cpu_timer_stop(&timer); - } + GP_Fill(ctx, black_pixel); + GP_Print(ctx, NULL, ctx->w/2, ctx->h/2 - 10, + GP_ALIGN_CENTER|GP_VALIGN_CENTER, white_pixel, black_pixel, + "'%s'", image_loader_img_path()); + GP_Print(ctx, NULL, ctx->w/2, ctx->h/2 + 10, + GP_ALIGN_CENTER|GP_VALIGN_CENTER, white_pixel, black_pixel, + "Failed to load image :( (%s)", strerror(errno)); + GP_BackendFlip(backend);
- return img; + return NULL; }
/* @@ -296,10 +268,8 @@ static void pattern_fill(GP_Context *ctx, unsigned int x0, unsigned int y0, } }
-/* - * Updates display. - */ -static void update_display(struct loader_params *params, GP_Context *img) +static void update_display(struct loader_params *params, GP_Context *img, + GP_Context *orig_img) { GP_Context *context = backend->context; struct cpu_timer timer; @@ -359,9 +329,6 @@ static void update_display(struct loader_params *params, GP_Context *img)
cpu_timer_stop(&timer);
- if (params->rotate) - GP_ContextFree(img); - /* clean up the rest of the display */ GP_FillRectXYWH(context, 0, 0, cx, context->h, black_pixel); GP_FillRectXYWH(context, 0, 0, context->w, cy, black_pixel); @@ -376,90 +343,91 @@ static void update_display(struct loader_params *params, GP_Context *img) if (h > 0) GP_FillRectXYWH(context, 0, img->h + cy, context->w, h, black_pixel);
- set_caption(params->img_path, params->rat); + const char *img_path = image_loader_img_path();
- if (!params->show_info) { - GP_BackendFlip(backend); - return; - } + set_caption(img_path, params->rat); + + if (!params->show_info) + goto out;
GP_Size th = GP_TextHeight(NULL);
GP_Print(context, NULL, 11, 11, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, - black_pixel, white_pixel, "%ux%u", img->w, img->h); + black_pixel, white_pixel, "%ux%u (%ux%u) 1:%3.3f", + img->w, img->h, orig_img->w, orig_img->h, params->rat);
GP_Print(context, NULL, 10, 10, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, - white_pixel, black_pixel, "%ux%u", img->w, img->h); + white_pixel, black_pixel, "%ux%u (%ux%u) 1:%3.3f", + img->w, img->h, orig_img->w, orig_img->h, params->rat);
GP_Print(context, NULL, 11, 13 + th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, - black_pixel, white_pixel, "1:%3.3f", params->rat); + black_pixel, white_pixel, "%s", img_name(img_path));
GP_Print(context, NULL, 10, 12 + th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, - white_pixel, black_pixel, "1:%3.3f", params->rat); + white_pixel, black_pixel, "%s", img_name(img_path));
- GP_Print(context, NULL, 11, 15 + 2 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, - black_pixel, white_pixel, "%s", img_name(params->img_path)); - - GP_Print(context, NULL, 10, 14 + 2 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, - white_pixel, black_pixel, "%s", img_name(params->img_path)); - - GP_Print(context, NULL, 11, 17 + 3 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, + GP_Print(context, NULL, 11, 13 + 2 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, black_pixel, white_pixel, "%s%s", params->use_low_pass && params->rat < 1 ? "Gaussian LP + " : "", GP_InterpolationTypeName(params->resampling_method));
- GP_Print(context, NULL, 10, 16 + 3 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, + GP_Print(context, NULL, 10, 14 + 2 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, white_pixel, black_pixel, "%s%s", params->use_low_pass && params->rat < 1 ? "Gaussian LP + " : "", GP_InterpolationTypeName(params->resampling_method));
- unsigned int count = image_list_count(params->img_list); - unsigned int pos = image_list_pos(params->img_list) + 1; + unsigned int count = image_loader_count(); + unsigned int pos = image_loader_pos() + 1;
- GP_Print(context, NULL, 11, 19 + 4 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, + GP_Print(context, NULL, 11, 17 + 3 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, black_pixel, white_pixel, "%u of %u", pos, count);
- GP_Print(context, NULL, 10, 18 + 4 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, + GP_Print(context, NULL, 10, 16 + 3 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, white_pixel, black_pixel, "%u of %u", pos, count);
- unsigned int dir_count = image_list_dir_count(params->img_list); - unsigned int dir_pos = image_list_dir_pos(params->img_list) + 1; + if (!image_loader_is_in_dir()) + goto out;
- if (dir_count > 1 && dir_count != count) { - GP_Print(context, NULL, 11, 21 + 5 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, - black_pixel, white_pixel, "%u of %u in directory", dir_pos, dir_count); + unsigned int dir_count = image_loader_dir_count(); + unsigned int dir_pos = image_loader_dir_pos() + 1;
- GP_Print(context, NULL, 10, 20 + 5 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, - white_pixel, black_pixel, "%u of %u in directory", dir_pos, dir_count); - } + GP_Print(context, NULL, 11, 19 + 4 * th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, + black_pixel, white_pixel, "%u of %u in directory", dir_pos, dir_count); + + GP_Print(context, NULL, 10, 18 + 4* th, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM, + white_pixel, black_pixel, "%u of %u in directory", dir_pos, dir_count); +out: + if (params->rotate) + GP_ContextFree(img);
GP_BackendFlip(backend); }
GP_Context *load_resized_image(struct loader_params *params, GP_Size w, GP_Size h) { - long cookie = (w & 0xffff) | (h & 0xffff)<<16; GP_Context *img, *res = NULL; struct cpu_timer timer; GP_ProgressCallback callback = {.callback = image_loader_callback};
- int key = (params->resampling_method<<1) | !!(params->use_low_pass); + const char *img_path = image_loader_img_path();
/* Try to get resized cached image */ - img = image_cache_get(params->img_resized_cache, params->img_path, cookie, key, 1); + img = image_cache_get2(params->img_resized_cache, 1, "%s %ux%u r%i l%i", + img_path, w, h, params->resampling_method, + params->use_low_pass);
if (img != NULL) return img;
/* Otherwise load image and resize it */ - if ((img = load_image(params, 1)) == NULL) + if ((img = load_image(1)) == NULL) return NULL;
if (params->show_nn_first) { /* Do simple interpolation and blit the result */ GP_Context *nn = GP_FilterResizeNNAlloc(img, w, h, NULL); if (nn != NULL) { - update_display(params, nn); + update_display(params, nn, img); GP_ContextFree(nn); } } @@ -509,7 +477,9 @@ GP_Context *load_resized_image(struct loader_params *params, GP_Size w, GP_Size if (img == NULL) return NULL;
- image_cache_put(params->img_resized_cache, img, params->img_path, cookie, key); + image_cache_put2(params->img_resized_cache, img, "%s %ux%u r%i l%i", + img_path, w, h, params->resampling_method, + params->use_low_pass);
return img; } @@ -518,7 +488,7 @@ static void *image_loader(void *ptr) { struct loader_params *params = ptr; struct cpu_timer sum_timer; - GP_Context *img, *context = backend->context; + GP_Context *img, *orig_img, *context = backend->context;
cpu_timer_start(&sum_timer, "sum");
@@ -542,28 +512,28 @@ static void *image_loader(void *ptr) break; }
- if ((img = load_image(params, 0)) == NULL) + if ((orig_img = load_image(0)) == NULL) return NULL;
- params->rat = calc_img_size(params, img->w, img->h, w, h); + params->rat = calc_img_size(params, orig_img->w, orig_img->h, w, h);
/* Special case => no need to resize */ - if (params->rat == 1.0) + if (params->rat == 1.0) { + img = orig_img; goto update; + }
- w = img->w; - h = img->h; + w = orig_img->w * params->rat + 0.5; + h = orig_img->h * params->rat + 0.5;
- img = load_resized_image(params, w * params->rat + 0.5, h * params->rat + 0.5); + img = load_resized_image(params, w, h);
if (img == NULL) return NULL;
image_cache_print(params->img_resized_cache); - image_cache_print(params->img_orig_cache); - update: - update_display(params, img); + update_display(params, img, orig_img); cpu_timer_stop(&sum_timer);
return NULL; @@ -581,13 +551,10 @@ static void stop_loader(void) } }
-static void show_image(struct loader_params *params, const char *path) +static void show_image(struct loader_params *params) { int ret;
- if (path != NULL) - params->img_path = path; - /* stop previous loader thread */ stop_loader();
@@ -600,17 +567,24 @@ static void show_image(struct loader_params *params, const char *path) } }
+static void image_seek(struct loader_params *params, + enum img_seek_offset offset, int whence) +{ + image_loader_seek(offset, whence); + show_image(params); +} + static void set_zoom_offset(struct loader_params *params, int dx, int dy) { params->zoom_x_offset += dx; params->zoom_y_offset += dy; - show_image(params, NULL); + show_image(params); }
static void zoom_mul(struct loader_params *params, float mul) { params->zoom *= mul; - show_image(params, NULL); + show_image(params); }
static void sighandler(int signo) @@ -633,7 +607,12 @@ static void init_backend(const char *backend_opts) } }
-static void init_caches(struct loader_params *params) +/* + * Figure out cache size depending on the size of RAM. + * + * Initialize cache, image loader. + */ +static int init_loader(struct loader_params *params, const char **argv) { size_t size = image_cache_get_ram_size(); unsigned int resized_size = (1024 * size)/10; @@ -642,24 +621,23 @@ static void init_caches(struct loader_params *params) if (resized_size > 100 * 1024 * 1024) resized_size = 100 * 1024 * 1024;
- if (orig_size > 40 * 1024 * 1024) - orig_size = 40 * 1024 * 1024; + GP_DEBUG(1, "Resized cache size = %u", resized_size);
- GP_DEBUG(1, "Cache sizes original = %u, resized = %u", - orig_size, resized_size); + //TODO: cache size init + if (image_loader_init(argv, orig_size)) + return 1;
params->img_resized_cache = image_cache_create(resized_size); - params->img_orig_cache = image_cache_create(orig_size);
-// params->img_resized_cache = NULL; -// params->img_orig_cache = NULL; + return 0; }
static uint32_t timer_callback(GP_Timer *self) { struct loader_params *params = self->priv;
- show_image(params, image_list_move(params->img_list, 1)); + image_loader_seek(IMG_CUR, 1); + show_image(params);
return 0; } @@ -674,8 +652,6 @@ int main(int argc, char *argv[]) GP_PixelType emul_type = GP_PIXEL_UNKNOWN;
struct loader_params params = { - .img_path = NULL, - .show_progress = 0, .show_progress_once = 0, .show_info = 0, @@ -684,11 +660,10 @@ int main(int argc, char *argv[]) .rotate = 0, .resampling_method = GP_INTERP_LINEAR_LF_INT,
- .zoom_type = ZOOM_FIT_DOWNSCALE, + .zoom_type = ZOOM_FIT, .zoom = 1,
.img_resized_cache = NULL, - .img_orig_cache = NULL, };
GP_TIMER_DECLARE(timer, 0, 0, "Slideshow", timer_callback, ¶ms); @@ -771,7 +746,8 @@ int main(int argc, char *argv[]) signal(SIGBUS, sighandler); signal(SIGABRT, sighandler);
- init_caches(¶ms); + if (init_loader(¶ms, (const char **)argv + optind)) + return 1;
init_backend(backend_opts);
@@ -787,11 +763,8 @@ int main(int argc, char *argv[]) GP_Fill(context, black_pixel); GP_BackendFlip(backend);
- struct image_list *list = image_list_create((const char**)argv + optind); - params.img_list = list; - params.show_progress_once = 1; - show_image(¶ms, image_list_img_path(list)); + show_image(¶ms);
if (sleep_ms) { timer.period = sleep_ms; @@ -831,7 +804,7 @@ int main(int argc, char *argv[]) switch (ev.val.key.key) { case GP_KEY_H: draw_help(backend); - show_image(¶ms, NULL); + show_image(¶ms); break; case GP_KEY_F: if (GP_BackendIsX11(backend)) @@ -841,7 +814,7 @@ int main(int argc, char *argv[]) params.show_info = !params.show_info;
params.show_progress_once = 1; - show_image(¶ms, NULL); + show_image(¶ms); break; case GP_KEY_P: params.show_progress = !params.show_progress; @@ -852,7 +825,7 @@ int main(int argc, char *argv[]) params.rotate = 0;
params.show_progress_once = 1; - show_image(¶ms, NULL); + show_image(¶ms); break; case GP_KEY_RIGHT_BRACE: params.resampling_method++; @@ -869,7 +842,7 @@ int main(int argc, char *argv[]) }
params.show_progress_once = 1; - show_image(¶ms, image_list_img_path(list)); + show_image(¶ms); break; case GP_KEY_LEFT_BRACE: if (params.resampling_method == 0) @@ -886,41 +859,41 @@ int main(int argc, char *argv[]) }
params.show_progress_once = 1; - show_image(¶ms, image_list_img_path(list)); + show_image(¶ms); break; case GP_KEY_L: params.use_low_pass = !params.use_low_pass;
params.show_progress_once = 1; - show_image(¶ms, image_list_img_path(list)); + show_image(¶ms); break; case GP_KEY_D: image_cache_drop(params.img_resized_cache); - image_cache_drop(params.img_orig_cache); + image_loader_drop_cache(); break; case GP_KEY_ESC: case GP_KEY_ENTER: case GP_KEY_Q: image_cache_drop(params.img_resized_cache); - image_cache_drop(params.img_orig_cache); + image_loader_drop_cache(); GP_BackendExit(backend); return 0; break; case GP_KEY_PAGE_UP: params.show_progress_once = 1; - show_image(¶ms, image_list_dir_move(list, -1)); + image_seek(¶ms, IMG_DIR, -1); break; case GP_KEY_PAGE_DOWN: params.show_progress_once = 1; - show_image(¶ms, image_list_dir_move(list, 1)); + image_seek(¶ms, IMG_DIR, 1); break; case GP_KEY_HOME: params.show_progress_once = 1; - show_image(¶ms, image_list_first(list)); + image_seek(¶ms, IMG_FIRST, 0); break; case GP_KEY_END: params.show_progress_once = 1; - show_image(¶ms, image_list_last(list)); + image_seek(¶ms, IMG_LAST, 0); break; case GP_KEY_RIGHT: if (shift_flag) @@ -951,45 +924,22 @@ int main(int argc, char *argv[]) case GP_KEY_SPACE: params.show_progress_once = 1; if (shift_flag) - show_image(¶ms, image_list_move(list, 10)); + image_seek(¶ms, IMG_CUR, 10); else - show_image(¶ms, image_list_move(list, 1)); + image_seek(¶ms, IMG_CUR, 1); break; prev: case GP_KEY_BACKSPACE: params.show_progress_once = 1; if (shift_flag) - show_image(¶ms, image_list_move(list, -10)); + image_seek(¶ms, IMG_CUR, -10); else - show_image(¶ms, image_list_move(list, -1)); - break; - case GP_KEY_1: - resize_backend(¶ms, 1, shift_flag); - break; - case GP_KEY_2: - resize_backend(¶ms, 2, shift_flag); - break; - case GP_KEY_3: - resize_backend(¶ms, 3, shift_flag); - break; - case GP_KEY_4: - resize_backend(¶ms, 4, shift_flag); - break; - case GP_KEY_5: - resize_backend(¶ms, 5, shift_flag); - break; - case GP_KEY_6: - resize_backend(¶ms, 6, shift_flag); - break; - case GP_KEY_7: - resize_backend(¶ms, 7, shift_flag); - break; - case GP_KEY_8: - resize_backend(¶ms, 8, shift_flag); - break; - case GP_KEY_9: - resize_backend(¶ms, 9, shift_flag); + image_seek(¶ms, IMG_CUR, -1); break; + case GP_KEY_1 ... GP_KEY_9: { + int val = ev.val.key.key - GP_KEY_1 + 1; + resize_backend(val, shift_flag); + } break; case GP_KEY_KP_PLUS: case GP_KEY_DOT: params.show_progress_once = 1; @@ -1002,7 +952,7 @@ int main(int argc, char *argv[]) break; case GP_KEY_F1 ... GP_KEY_F10: image_action_run(ev.val.key.key - GP_KEY_F1, - image_list_img_path(list)); + image_loader_img_path()); break; } break; @@ -1014,7 +964,7 @@ int main(int argc, char *argv[]) GP_BackendResizeAck(backend); GP_Fill(backend->context, 0); params.show_progress_once = 1; - show_image(¶ms, NULL); + show_image(¶ms); break; case GP_EV_SYS_QUIT: GP_BackendExit(backend);
http://repo.or.cz/w/gfxprim.git/commit/d2f0c789183f62bc30cd0638c7da9bf5aa52b...
commit d2f0c789183f62bc30cd0638c7da9bf5aa52ba44 Author: Cyril Hrubis metan@ucw.cz Date: Sat Jul 13 18:28:43 2013 +0200
libs: EventQueue: Zero keypress bitflags on init.
Each event carries bitflags of currently pressed keys, these flags are recorded in bitflag array in the the EventQueue and must be initialized to zeroes prior the use.
This fixes bug where some of the keys were wrongly reported as pressed at the start of the application.
Signed-off-by: Cyril Hrubis metan@ucw.cz
diff --git a/libs/input/GP_EventQueue.c b/libs/input/GP_EventQueue.c index f13a733..ec13f73 100644 --- a/libs/input/GP_EventQueue.c +++ b/libs/input/GP_EventQueue.c @@ -20,6 +20,8 @@ * * *****************************************************************************/
+#include <string.h> + #include "core/GP_Common.h" #include "core/GP_Debug.h"
@@ -32,6 +34,8 @@ void GP_EventQueueInit(struct GP_EventQueue *self, self->screen_w = screen_w; self->screen_h = screen_h;
+ memset(&self->cur_state, 0, sizeof(self->cur_state)); + self->cur_state.cursor_x = screen_w / 2; self->cur_state.cursor_y = screen_h / 2;
-----------------------------------------------------------------------
Summary of changes: demos/spiv/Makefile | 5 +- demos/spiv/image_cache.c | 134 +++++++++++-- demos/spiv/image_cache.h | 13 +- demos/spiv/image_loader.c | 169 ++++++++++++++++ demos/spiv/{image_list.h => image_loader.h} | 85 +++++--- demos/spiv/spiv.c | 288 +++++++++++---------------- libs/input/GP_EventQueue.c | 4 + 7 files changed, 473 insertions(+), 225 deletions(-) create mode 100644 demos/spiv/image_loader.c copy demos/spiv/{image_list.h => image_loader.h} (52%)
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.