diff options
Diffstat (limited to 'src/backend_libjpeg.c')
-rw-r--r-- | src/backend_libjpeg.c | 139 |
1 files changed, 39 insertions, 100 deletions
diff --git a/src/backend_libjpeg.c b/src/backend_libjpeg.c index 34dfb43..c9d70df 100644 --- a/src/backend_libjpeg.c +++ b/src/backend_libjpeg.c @@ -1,5 +1,8 @@ #include "backend.h" +#include "bitmap.h" +#include "image.h" #include "source.h" +#include "source_private.h" #include <assert.h> #include <stdlib.h> @@ -16,15 +19,16 @@ struct private { void *data; size_t len; tjhandle jpeg; + int width; + int height; }; -static void source_free(struct imv_source *src) +static void free_private(void *raw_private) { - pthread_mutex_lock(&src->busy); - free(src->name); - src->name = NULL; - - struct private *private = src->private; + if (!raw_private) { + return; + } + struct private *private = raw_private; tjDestroy(private->jpeg); if (private->fd >= 0) { munmap(private->data, private->len); @@ -34,77 +38,38 @@ static void source_free(struct imv_source *src) } private->data = NULL; - free(src->private); - src->private = NULL; - - pthread_mutex_unlock(&src->busy); - pthread_mutex_destroy(&src->busy); - free(src); -} - -static struct imv_image *to_image(int width, int height, void *bitmap) -{ - struct imv_bitmap *bmp = malloc(sizeof *bmp); - bmp->width = width; - bmp->height = height; - bmp->format = IMV_ABGR; - bmp->data = bitmap; - struct imv_image *image = imv_image_create_from_bitmap(bmp); - return image; -} - -static void report_error(struct imv_source *src) -{ - assert(src->callback); - - struct imv_source_message msg; - msg.source = src; - msg.user_data = src->user_data; - msg.image = NULL; - msg.error = "Internal error"; - - pthread_mutex_unlock(&src->busy); - src->callback(&msg); + free(private); } -static void send_bitmap(struct imv_source *src, void *bitmap) +static void load_image(void *raw_private, struct imv_image **image, int *frametime) { - assert(src->callback); + *image = NULL; + *frametime = 0; - struct imv_source_message msg; - msg.source = src; - msg.user_data = src->user_data; - msg.image = to_image(src->width, src->height, bitmap); - msg.frametime = 0; - msg.error = NULL; + struct private *private = raw_private; - pthread_mutex_unlock(&src->busy); - src->callback(&msg); -} - -static void *load_image(struct imv_source *src) -{ - /* Don't run if this source is already active */ - if (pthread_mutex_trylock(&src->busy)) { - return NULL; - } - - struct private *private = src->private; - - void *bitmap = malloc(src->height * src->width * 4); + void *bitmap = malloc(private->height * private->width * 4); int rcode = tjDecompress2(private->jpeg, private->data, private->len, - bitmap, src->width, 0, src->height, TJPF_RGBA, TJFLAG_FASTDCT); + bitmap, private->width, 0, private->height, TJPF_RGBA, TJFLAG_FASTDCT); if (rcode) { free(bitmap); - report_error(src); - return NULL; + return; } - send_bitmap(src, bitmap); - return NULL; + struct imv_bitmap *bmp = malloc(sizeof *bmp); + bmp->width = private->width; + bmp->height = private->height; + bmp->format = IMV_ABGR; + bmp->data = bitmap; + *image = imv_image_create_from_bitmap(bmp); } +static const struct imv_source_vtable vtable = { + .load_first_frame = load_image, + .free = free_private +}; + static enum backend_result open_path(const char *path, struct imv_source **src) { struct private private; @@ -135,9 +100,8 @@ static enum backend_result open_path(const char *path, struct imv_source **src) return BACKEND_UNSUPPORTED; } - int width, height; int rcode = tjDecompressHeader(private.jpeg, private.data, private.len, - &width, &height); + &private.width, &private.height); if (rcode) { tjDestroy(private.jpeg); munmap(private.data, private.len); @@ -145,22 +109,10 @@ static enum backend_result open_path(const char *path, struct imv_source **src) return BACKEND_UNSUPPORTED; } - struct imv_source *source = calloc(1, sizeof *source); - source->name = strdup(path); - source->width = width; - source->height = height; - source->num_frames = 1; - source->next_frame = 1; - pthread_mutex_init(&source->busy, NULL); - source->load_first_frame = &load_image; - source->load_next_frame = NULL; - source->free = &source_free; - source->callback = NULL; - source->user_data = NULL; - source->private = malloc(sizeof private); - memcpy(source->private, &private, sizeof private); - - *src = source; + struct private *new_private = malloc(sizeof private); + memcpy(new_private, &private, sizeof private); + + *src = imv_source_create(&vtable, new_private); return BACKEND_SUCCESS; } @@ -177,30 +129,17 @@ static enum backend_result open_memory(void *data, size_t len, struct imv_source return BACKEND_UNSUPPORTED; } - int width, height; int rcode = tjDecompressHeader(private.jpeg, private.data, private.len, - &width, &height); + &private.width, &private.height); if (rcode) { tjDestroy(private.jpeg); return BACKEND_UNSUPPORTED; } - struct imv_source *source = calloc(1, sizeof *source); - source->name = strdup("-"); - source->width = width; - source->height = height; - source->num_frames = 1; - source->next_frame = 1; - pthread_mutex_init(&source->busy, NULL); - source->load_first_frame = &load_image; - source->load_next_frame = NULL; - source->free = &source_free; - source->callback = NULL; - source->user_data = NULL; - source->private = malloc(sizeof private); - memcpy(source->private, &private, sizeof private); - - *src = source; + struct private *new_private = malloc(sizeof private); + memcpy(new_private, &private, sizeof private); + + *src = imv_source_create(&vtable, new_private); return BACKEND_SUCCESS; } |