Load the image in a separate thread

This commit is contained in:
Abdelrahman Said 2024-05-12 20:00:09 +01:00
parent 53c70156a6
commit dde1cce8e4
2 changed files with 36 additions and 24 deletions

View File

@ -9,6 +9,7 @@ INCLUDES="\
"
LIBS="\
-lm \
-pthread \
$(pkg-config --libs sdl2) \
"
SRC="\

View File

@ -8,6 +8,7 @@
#include <SDL2/SDL_surface.h>
#include <SDL2/SDL_video.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@ -32,8 +33,13 @@ struct point {
};
internal void write_debug_ppm6(const Image *img);
internal SDL_Texture *image_to_texture(SDL_Renderer *renderer,
const Image *img);
internal void *load_tiff_image(void *args);
typedef struct img_thread_args ImgThreadArgs;
struct img_thread_args {
const char *filename;
Arena *arena;
};
int main(int argc, char *argv[]) {
int exit_code = EXIT_SUCCESS;
@ -45,14 +51,13 @@ int main(int argc, char *argv[]) {
const char *file_to_open = argc > 1 ? argv[1] : "./resources/test.tif";
Image *img = read_baseline_tiff(file_to_open, arena);
if (!img) {
pthread_t img_thread;
ImgThreadArgs args = {.filename = file_to_open, .arena = arena};
if (pthread_create(&img_thread, NULL, load_tiff_image, &args) != 0) {
exit_code = EXIT_FAILURE;
goto MAIN_DESTROY_ARENA;
}
write_debug_ppm6(img);
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
exit_code = EXIT_FAILURE;
goto MAIN_DESTROY_ARENA;
@ -73,17 +78,23 @@ int main(int argc, char *argv[]) {
goto MAIN_DESTROY_WINDOW;
}
SDL_Texture *texture = image_to_texture(renderer, img);
if (!texture) {
SDL_Surface *surface = NULL;
if (pthread_join(img_thread, (void **)&surface) != 0 || !surface) {
exit_code = EXIT_FAILURE;
goto MAIN_DESTROY_RENDERER;
}
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
if (!texture) {
exit_code = EXIT_FAILURE;
goto MAIN_DESTROY_SURFACE;
}
SDL_Rect dest = {
.h = img->height,
.w = img->width,
.x = (WINDOW_WIDTH - img->width) / 2,
.y = (WINDOW_HEIGHT - img->height) / 2,
.h = surface->h,
.w = surface->w,
.x = (WINDOW_WIDTH - surface->w) / 2,
.y = (WINDOW_HEIGHT - surface->h) / 2,
};
bool running = true;
@ -110,6 +121,9 @@ int main(int argc, char *argv[]) {
SDL_DestroyTexture(texture);
MAIN_DESTROY_SURFACE:
SDL_FreeSurface(surface);
MAIN_DESTROY_RENDERER:
SDL_DestroyRenderer(renderer);
@ -146,17 +160,19 @@ internal void write_debug_ppm6(const Image *img) {
fclose(out);
}
internal SDL_Texture *image_to_texture(SDL_Renderer *renderer,
const Image *img) {
SDL_Texture *output = NULL;
if (!renderer || !img) {
goto IMAGE_TO_TEXTURE_RETURN;
internal void *load_tiff_image(void *args) {
ImgThreadArgs *img_args = (ImgThreadArgs *)args;
Image *img = read_baseline_tiff(img_args->filename, img_args->arena);
if (!img) {
return NULL;
}
write_debug_ppm6(img);
SDL_Surface *surface = SDL_CreateRGBSurface(0, img->width, img->height, 32,
RMASK, GMASK, BMASK, AMASK);
if (!surface) {
goto IMAGE_TO_TEXTURE_RETURN;
return NULL;
}
SDL_LockSurface(surface);
@ -170,10 +186,5 @@ internal SDL_Texture *image_to_texture(SDL_Renderer *renderer,
}
SDL_UnlockSurface(surface);
output = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);
IMAGE_TO_TEXTURE_RETURN:
return output;
return surface;
}