Load the image in a separate thread
This commit is contained in:
		
							
								
								
									
										1
									
								
								compile
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								compile
									
									
									
									
									
								
							| @@ -9,6 +9,7 @@ INCLUDES="\ | ||||
| " | ||||
| LIBS="\ | ||||
| 	-lm \ | ||||
| 	-pthread \ | ||||
| 	$(pkg-config --libs sdl2) \ | ||||
| " | ||||
| SRC="\ | ||||
|   | ||||
							
								
								
									
										59
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								src/main.c
									
									
									
									
									
								
							| @@ -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; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user