aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHarry Jeffery <harry@exec64.co.uk>2019-01-29 22:19:38 +0000
committerHarry Jeffery <harry@exec64.co.uk>2019-01-29 22:26:22 +0000
commit442752efde85a71030c6023e59cac61f24849309 (patch)
treed298c387170741b1fe7572691d2b5411976c9853 /src
parent4d74ab1be3430e713748ec93ebd919a1fc2f2b78 (diff)
downloadimv-442752efde85a71030c6023e59cac61f24849309.tar.gz
loader: Delete legacy loader
Diffstat (limited to 'src')
-rw-r--r--src/loader.c441
-rw-r--r--src/loader.h37
2 files changed, 0 insertions, 478 deletions
diff --git a/src/loader.c b/src/loader.c
deleted file mode 100644
index 51291bf..0000000
--- a/src/loader.c
+++ /dev/null
@@ -1,441 +0,0 @@
-#include "loader.h"
-#include "bitmap.h"
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pthread.h>
-#include <signal.h>
-#include <SDL2/SDL.h>
-#include <FreeImage.h>
-
-/* Some systems like GNU/Hurd don't define PATH_MAX */
-#ifndef PATH_MAX
-#define PATH_MAX 4096
-#endif
-
-static void block_usr1_signal(void);
-static int is_thread_cancelled(void);
-static void *bg_new_img(void *data);
-static void *bg_next_frame(void *data);
-static void error_occurred(struct imv_loader *ldr);
-
-struct imv_loader {
- pthread_mutex_t lock;
- pthread_t bg_thread;
- char *path;
- BYTE *buffer;
- size_t buffer_size;
- FIMEMORY *fi_buffer;
- FIMULTIBITMAP *mbmp;
- FIBITMAP *bmp;
- int width;
- int height;
- int cur_frame;
- int next_frame;
- int num_frames;
- double frame_time;
- unsigned int new_image_event;
- unsigned int bad_image_event;
-};
-
-static void block_usr1_signal(void)
-{
- sigset_t sigmask;
- sigemptyset(&sigmask);
- sigaddset(&sigmask, SIGUSR1);
- sigprocmask(SIG_SETMASK, &sigmask, NULL);
-}
-
-static int is_thread_cancelled(void)
-{
- sigset_t sigmask;
- sigpending(&sigmask);
- return sigismember(&sigmask, SIGUSR1);
-}
-
-static struct imv_bitmap *to_imv_bitmap(FIBITMAP *in_bmp)
-{
- struct imv_bitmap *bmp = malloc(sizeof(struct imv_bitmap));
- bmp->width = FreeImage_GetWidth(in_bmp);
- bmp->height = FreeImage_GetHeight(in_bmp);
- bmp->data = malloc(4 * bmp->width * bmp->height);
- FreeImage_ConvertToRawBits(bmp->data, in_bmp, 4 * bmp->width, 32,
- FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE);
- return bmp;
-}
-
-struct imv_loader *imv_loader_create(void)
-{
- struct imv_loader *ldr = malloc(sizeof(struct imv_loader));
- memset(ldr, 0, sizeof(struct imv_loader));
- pthread_mutex_init(&ldr->lock, NULL);
- /* ignore this signal in case we accidentally receive it */
- block_usr1_signal();
- return ldr;
-}
-
-void imv_loader_free(struct imv_loader *ldr)
-{
- /* wait for any existing bg thread to finish */
- if(ldr->bg_thread) {
- pthread_join(ldr->bg_thread, NULL);
- }
- pthread_mutex_destroy(&ldr->lock);
-
- if(ldr->bmp) {
- FreeImage_Unload(ldr->bmp);
- }
- if(ldr->mbmp) {
- FreeImage_CloseMultiBitmap(ldr->mbmp, 0);
- }
- if(ldr->path) {
- free(ldr->path);
- }
- free(ldr);
-}
-
-void imv_loader_load(struct imv_loader *ldr, const char *path,
- const void *buffer, const size_t buffer_size)
-{
- pthread_mutex_lock(&ldr->lock);
-
- /* cancel existing thread if already running */
- if(ldr->bg_thread) {
- pthread_kill(ldr->bg_thread, SIGUSR1);
- pthread_detach(ldr->bg_thread);
- }
-
- /* kick off a new thread to load the image */
- if(ldr->path) {
- free(ldr->path);
- }
- ldr->path = strdup(path);
- if (strncmp(path, "-", 2) == 0) {
- ldr->buffer = (BYTE *)buffer;
- ldr->buffer_size = buffer_size;
- } else if (ldr->fi_buffer != NULL) {
- FreeImage_CloseMemory(ldr->fi_buffer);
- ldr->fi_buffer = NULL;
- }
- pthread_create(&ldr->bg_thread, NULL, &bg_new_img, ldr);
- pthread_mutex_unlock(&ldr->lock);
-}
-
-void imv_loader_set_event_types(struct imv_loader *ldr,
- unsigned int new_image,
- unsigned int bad_image)
-{
- ldr->new_image_event = new_image;
- ldr->bad_image_event = bad_image;
-}
-
-void imv_loader_load_next_frame(struct imv_loader *ldr)
-{
- /* wait for existing thread to finish if already running */
- if(ldr->bg_thread) {
- pthread_join(ldr->bg_thread, NULL);
- }
-
- /* kick off a new thread */
- pthread_create(&ldr->bg_thread, NULL, &bg_next_frame, ldr);
-}
-
-void imv_loader_time_passed(struct imv_loader *ldr, double dt)
-{
- int get_frame = 0;
- pthread_mutex_lock(&ldr->lock);
- if(ldr->num_frames > 1) {
- ldr->frame_time -= dt;
- if(ldr->frame_time < 0.0) {
- get_frame = 1;
- }
- } else {
- ldr->frame_time = 0.0;
- }
- pthread_mutex_unlock(&ldr->lock);
-
- if(get_frame) {
- imv_loader_load_next_frame(ldr);
- }
-}
-
-double imv_loader_time_left(struct imv_loader *ldr)
-{
- return ldr->frame_time;
-}
-
-static void *bg_new_img(void *data)
-{
- /* so we can poll for it */
- block_usr1_signal();
-
- struct imv_loader *ldr = data;
- char path[PATH_MAX] = "-";
-
- pthread_mutex_lock(&ldr->lock);
- int from_stdin = !strncmp(path, ldr->path, 2);
- if(!from_stdin) {
- (void)snprintf(path, PATH_MAX, "%s", ldr->path);
- }
- pthread_mutex_unlock(&ldr->lock);
-
- FREE_IMAGE_FORMAT fmt;
- if (from_stdin) {
- pthread_mutex_lock(&ldr->lock);
- ldr->fi_buffer = FreeImage_OpenMemory(ldr->buffer, ldr->buffer_size);
- fmt = FreeImage_GetFileTypeFromMemory(ldr->fi_buffer, 0);
- pthread_mutex_unlock(&ldr->lock);
- } else {
- fmt = FreeImage_GetFileType(path, 0);
- }
- if(fmt == FIF_UNKNOWN) {
- if (from_stdin) {
- pthread_mutex_lock(&ldr->lock);
- FreeImage_CloseMemory(ldr->fi_buffer);
- ldr->fi_buffer = NULL;
- pthread_mutex_unlock(&ldr->lock);
- }
- error_occurred(ldr);
- return NULL;
- }
-
- int num_frames = 1;
- FIMULTIBITMAP *mbmp = NULL;
- FIBITMAP *bmp = NULL;
- int width, height;
- int raw_frame_time = 0;
-
- if(fmt == FIF_GIF) {
- if(from_stdin) {
- pthread_mutex_lock(&ldr->lock);
- mbmp = FreeImage_LoadMultiBitmapFromMemory(FIF_GIF, ldr->fi_buffer,
- GIF_LOAD256);
- pthread_mutex_unlock(&ldr->lock);
- } else {
- mbmp = FreeImage_OpenMultiBitmap(FIF_GIF, path,
- /* don't create file */ 0,
- /* read only */ 1,
- /* keep in memory */ 1,
- /* flags */ GIF_LOAD256);
- }
- if(!mbmp) {
- error_occurred(ldr);
- return NULL;
- }
-
- num_frames = FreeImage_GetPageCount(mbmp);
-
- FIBITMAP *frame = FreeImage_LockPage(mbmp, 0);
- width = FreeImage_GetWidth(frame);
- height = FreeImage_GetHeight(frame);
- bmp = FreeImage_ConvertTo32Bits(frame);
-
- /* get duration of first frame */
- FITAG *tag = NULL;
- FreeImage_GetMetadata(FIMD_ANIMATION, frame, "FrameTime", &tag);
- if(FreeImage_GetTagValue(tag)) {
- raw_frame_time = *(int*)FreeImage_GetTagValue(tag);
- } else {
- raw_frame_time = 100; /* default value for gifs */
- }
- FreeImage_UnlockPage(mbmp, frame, 0);
-
- } else {
- /* Future TODO: If we load image line-by-line we could stop loading large
- * ones before wasting much more time/memory on them. */
-
- int flags = (fmt == FIF_JPEG) ? JPEG_EXIFROTATE : 0;
- FIBITMAP *image;
- if(from_stdin) {
- pthread_mutex_lock(&ldr->lock);
- image = FreeImage_LoadFromMemory(fmt, ldr->fi_buffer, flags);
- pthread_mutex_unlock(&ldr->lock);
- } else {
- image = FreeImage_Load(fmt, path, flags);
- }
- if(!image) {
- error_occurred(ldr);
- pthread_mutex_lock(&ldr->lock);
- FreeImage_CloseMemory(ldr->fi_buffer);
- ldr->fi_buffer = NULL;
- pthread_mutex_unlock(&ldr->lock);
- return NULL;
- }
-
- /* Check for cancellation before we convert pixel format */
- if(is_thread_cancelled()) {
- FreeImage_Unload(image);
- return NULL;
- }
-
- width = FreeImage_GetWidth(bmp);
- height = FreeImage_GetHeight(bmp);
- bmp = FreeImage_ConvertTo32Bits(image);
- FreeImage_Unload(image);
- }
-
- /* now update the loader */
- pthread_mutex_lock(&ldr->lock);
-
- /* check for cancellation before finishing */
- if(is_thread_cancelled()) {
- if(mbmp) {
- FreeImage_CloseMultiBitmap(mbmp, 0);
- }
- if(bmp) {
- FreeImage_Unload(bmp);
- }
- pthread_mutex_unlock(&ldr->lock);
- return NULL;
- }
-
- if(ldr->mbmp) {
- FreeImage_CloseMultiBitmap(ldr->mbmp, 0);
- }
-
- if(ldr->bmp) {
- FreeImage_Unload(ldr->bmp);
- }
-
- ldr->mbmp = mbmp;
- ldr->bmp = bmp;
-
- ldr->width = width;
- ldr->height = height;
- ldr->cur_frame = 0;
- ldr->next_frame = 1;
- ldr->num_frames = num_frames;
- ldr->frame_time = (double)raw_frame_time * 0.0001;
-
- /* return the image via SDL event queue */
- SDL_Event event;
- SDL_zero(event);
- event.type = ldr->new_image_event;
- event.user.data1 = to_imv_bitmap(bmp);
- event.user.code = 1; /* is a new image */
- SDL_PushEvent(&event);
-
- pthread_mutex_unlock(&ldr->lock);
- return NULL;
-}
-
-static void *bg_next_frame(void *data)
-{
- struct imv_loader *ldr = data;
-
- pthread_mutex_lock(&ldr->lock);
- int num_frames = ldr->num_frames;
- if(num_frames < 2) {
- pthread_mutex_unlock(&ldr->lock);
- return NULL;
- }
-
- FITAG *tag = NULL;
- char disposal_method = 0;
- int frame_time = 0;
- short top = 0;
- short left = 0;
-
- ldr->cur_frame = ldr->next_frame;
- ldr->next_frame = (ldr->cur_frame + 1) % ldr->num_frames;
- FIBITMAP *frame = FreeImage_LockPage(ldr->mbmp, ldr->cur_frame);
- FIBITMAP *frame32 = FreeImage_ConvertTo32Bits(frame);
-
- /* First frame is always going to use the raw frame */
- if(ldr->cur_frame > 0) {
- FreeImage_GetMetadata(FIMD_ANIMATION, frame, "DisposalMethod", &tag);
- if(FreeImage_GetTagValue(tag)) {
- disposal_method = *(char*)FreeImage_GetTagValue(tag);
- }
- }
-
- FreeImage_GetMetadata(FIMD_ANIMATION, frame, "FrameLeft", &tag);
- if(FreeImage_GetTagValue(tag)) {
- left = *(short*)FreeImage_GetTagValue(tag);
- }
-
- FreeImage_GetMetadata(FIMD_ANIMATION, frame, "FrameTop", &tag);
- if(FreeImage_GetTagValue(tag)) {
- top = *(short*)FreeImage_GetTagValue(tag);
- }
-
- FreeImage_GetMetadata(FIMD_ANIMATION, frame, "FrameTime", &tag);
- if(FreeImage_GetTagValue(tag)) {
- frame_time = *(int*)FreeImage_GetTagValue(tag);
- }
-
- /* some gifs don't provide a frame time at all */
- if(frame_time == 0) {
- frame_time = 100;
- }
- ldr->frame_time += frame_time * 0.001;
-
- FreeImage_UnlockPage(ldr->mbmp, frame, 0);
-
- /* If this frame is inset, we need to expand it for compositing */
- if(ldr->width != (int)FreeImage_GetWidth(frame32) ||
- ldr->height != (int)FreeImage_GetHeight(frame32)) {
- FIBITMAP *expanded = FreeImage_Allocate(ldr->width, ldr->height, 32, 0,0,0);
- FreeImage_Paste(expanded, frame32, left, top, 255);
- FreeImage_Unload(frame32);
- frame32 = expanded;
- }
-
- switch(disposal_method) {
- case 0: /* nothing specified, fall through to compositing */
- case 1: /* composite over previous frame */
- if(ldr->bmp && ldr->cur_frame > 0) {
- FIBITMAP *bg_frame = FreeImage_ConvertTo24Bits(ldr->bmp);
- FreeImage_Unload(ldr->bmp);
- FIBITMAP *comp = FreeImage_Composite(frame32, 1, NULL, bg_frame);
- FreeImage_Unload(bg_frame);
- FreeImage_Unload(frame32);
- ldr->bmp = comp;
- } else {
- /* No previous frame, just render directly */
- if(ldr->bmp) {
- FreeImage_Unload(ldr->bmp);
- }
- ldr->bmp = frame32;
- }
- break;
- case 2: /* TODO - set to background, composite over that */
- if(ldr->bmp) {
- FreeImage_Unload(ldr->bmp);
- }
- ldr->bmp = frame32;
- break;
- case 3: /* TODO - restore to previous content */
- if(ldr->bmp) {
- FreeImage_Unload(ldr->bmp);
- }
- ldr->bmp = frame32;
- break;
- }
-
- SDL_Event event;
- SDL_zero(event);
- event.type = ldr->new_image_event;
- event.user.data1 = to_imv_bitmap(ldr->bmp);
- event.user.code = 0; /* not a new image */
- SDL_PushEvent(&event);
-
- pthread_mutex_unlock(&ldr->lock);
- return NULL;
-}
-
-static void error_occurred(struct imv_loader *ldr)
-{
- pthread_mutex_lock(&ldr->lock);
- char *err_path = strdup(ldr->path);
- pthread_mutex_unlock(&ldr->lock);
-
- SDL_Event event;
- SDL_zero(event);
- event.type = ldr->bad_image_event;
- event.user.data1 = err_path;
- SDL_PushEvent(&event);
-}
-
-
-/* vim:set ts=2 sts=2 sw=2 et: */
diff --git a/src/loader.h b/src/loader.h
deleted file mode 100644
index 8cf417b..0000000
--- a/src/loader.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef IMV_LOADER_H
-#define IMV_LOADER_H
-
-#include <unistd.h>
-
-struct imv_loader;
-
-/* Creates an instance of imv_loader */
-struct imv_loader *imv_loader_create(void);
-
-/* Cleans up an imv_loader instance */
-void imv_loader_free(struct imv_loader *ldr);
-
-/* Asynchronously load the given file */
-void imv_loader_load(struct imv_loader *ldr, const char *path,
- const void *buffer, const size_t buffer_size);
-
-/* Set the custom event types for returning data */
-void imv_loader_set_event_types(struct imv_loader *ldr,
- unsigned int new_image,
- unsigned int bad_image);
-
-/* Trigger the next frame of the currently loaded image to be loaded and
- * returned as soon as possible. */
-void imv_loader_load_next_frame(struct imv_loader *ldr);
-
-/* Tell the loader that dt time has passed. If the current image is animated,
- * the loader will automatically load the next frame when it is due. */
-void imv_loader_time_passed(struct imv_loader *ldr, double dt);
-
-/* Ask the loader how long we can sleep for until the next frame */
-double imv_loader_time_left(struct imv_loader *ldr);
-
-#endif
-
-
-/* vim:set ts=2 sts=2 sw=2 et: */