aboutsummaryrefslogtreecommitdiff
path: root/src/backend_libtiff.c
diff options
context:
space:
mode:
authorHarry Jeffery <harry@exec64.co.uk>2019-08-30 00:40:29 +0100
committerHarry Jeffery <harry@exec64.co.uk>2019-08-30 00:40:29 +0100
commit8b2aaf102f76921721209459eea10bed2094a730 (patch)
tree6942c0e840252e8832aa0a8276435045525a40b4 /src/backend_libtiff.c
parent4c0123bb3b449a2ea45b3e831db725d853bb03a1 (diff)
downloadimv-8b2aaf102f76921721209459eea10bed2094a730.tar.gz
source: Refactor out common async logic
Diffstat (limited to 'src/backend_libtiff.c')
-rw-r--r--src/backend_libtiff.c149
1 files changed, 40 insertions, 109 deletions
diff --git a/src/backend_libtiff.c b/src/backend_libtiff.c
index de7fc70..b0e955f 100644
--- a/src/backend_libtiff.c
+++ b/src/backend_libtiff.c
@@ -1,20 +1,19 @@
#include "backend.h"
+#include "bitmap.h"
+#include "image.h"
#include "source.h"
+#include "source_private.h"
-#include <assert.h>
#include <stdlib.h>
-#include <stdio.h>
-#include <sys/mman.h>
#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-
#include <tiffio.h>
struct private {
TIFF *tiff;
void *data;
size_t pos, len;
+ int width;
+ int height;
};
static tsize_t mem_read(thandle_t data, tdata_t buffer, tsize_t len)
@@ -60,93 +59,53 @@ static toff_t mem_size(thandle_t data)
return private->len;
}
-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;
+ if (!raw_private) {
+ return;
+ }
- struct private *private = src->private;
+ struct private *private = raw_private;
TIFFClose(private->tiff);
private->tiff = 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;
-
- 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;
+ struct private *private = raw_private;
/* libtiff suggests using their own allocation routines to support systems
* with segmented memory. I have no desire to support that, so I'm just
* going to use vanilla malloc/free. Systems where that isn't acceptable
* don't have upstream support from imv.
*/
- void *bitmap = malloc(src->height * src->width * 4);
- int rcode = TIFFReadRGBAImageOriented(private->tiff, src->width, src->height,
+ void *bitmap = malloc(private->height * private->width * 4);
+ int rcode = TIFFReadRGBAImageOriented(private->tiff, private->width, private->height,
bitmap, ORIENTATION_TOPLEFT, 0);
/* 1 = success, unlike the rest of *nix */
if (rcode != 1) {
- 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;
@@ -157,26 +116,13 @@ static enum backend_result open_path(const char *path, struct imv_source **src)
return BACKEND_UNSUPPORTED;
}
- unsigned int width, height;
- TIFFGetField(private.tiff, TIFFTAG_IMAGEWIDTH, &width);
- TIFFGetField(private.tiff, TIFFTAG_IMAGELENGTH, &height);
-
- 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;
+ TIFFGetField(private.tiff, TIFFTAG_IMAGEWIDTH, &private.width);
+ TIFFGetField(private.tiff, TIFFTAG_IMAGELENGTH, &private.height);
+
+ struct private *new_private = malloc(sizeof private);
+ memcpy(new_private, &private, sizeof private);
+
+ *src = imv_source_create(&vtable, new_private);
return BACKEND_SUCCESS;
}
@@ -195,25 +141,10 @@ static enum backend_result open_memory(void *data, size_t len, struct imv_source
return BACKEND_UNSUPPORTED;
}
- unsigned int width, height;
- TIFFGetField(private->tiff, TIFFTAG_IMAGEWIDTH, &width);
- TIFFGetField(private->tiff, TIFFTAG_IMAGELENGTH, &height);
-
- 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 = private;
-
- *src = source;
+ TIFFGetField(private->tiff, TIFFTAG_IMAGEWIDTH, &private->width);
+ TIFFGetField(private->tiff, TIFFTAG_IMAGELENGTH, &private->height);
+
+ *src = imv_source_create(&vtable, private);
return BACKEND_SUCCESS;
}