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="\ LIBS="\
-lm \ -lm \
-pthread \
$(pkg-config --libs sdl2) \ $(pkg-config --libs sdl2) \
" "
SRC="\ SRC="\

View File

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