diff --git a/SimpleImageViewer.c b/SimpleImageViewer.c index e1f1e19..d06003c 100644 --- a/SimpleImageViewer.c +++ b/SimpleImageViewer.c @@ -29,9 +29,19 @@ typedef struct{ int h; } window_size_delta; +static void error_exit(const char* msg){ + printf("%s\n", msg); + exit(-1); +} + +static void error_continue(const char* msg){ + printf("%s\n", msg); +} + Image load_image_pixels_from_file(const char* filepath){ Image image; image.pixels = stbi_load(filepath, &image.x, &image.y, &image.channels, DESIRED_IMAGE_CHANNELS); + if(!image.pixels) error_exit("Failed to load image from file!"); return image; } @@ -44,7 +54,7 @@ SDL_Window* create_window(const char* title, int w, int h){ const SDL_InitFlags init_flags = SDL_INIT_VIDEO | SDL_INIT_EVENTS; const SDL_WindowFlags window_flags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE; - SDL_Init(init_flags); + if(!SDL_Init(init_flags)) error_exit("Failed to initialize SDL!"); /* Used when a larger window is wanted, image displaying is dynamically calculated int display_count; @@ -63,14 +73,19 @@ SDL_Window* create_window(const char* title, int w, int h){ */ SDL_Window* window = SDL_CreateWindow(title, w, h, window_flags); - SDL_SetWindowAspectRatio(window, (float)w / (float)h, (float)w / (float)h); + if(!window) error_exit("Failed to create window!"); + if(SDL_SetWindowAspectRatio(window, (float)w / (float)h, (float)w / (float)h)) error_continue("Failed to set window aspect ratio! Continueing..."); return window; } -void populate_image(SDL_Window* window, Image* image){ +bool populate_image(SDL_Window* window, Image* image){ SDL_Surface* surface = SDL_GetWindowSurface(window); image->surface = SDL_CreateSurface(image->x, image->y, SDL_PIXELFORMAT_RGBA32); + if(!image->surface) { + error_continue("Failed to create image surface! Cleaning up and exiting..."); + return false; + } SDL_Rect pixel = { 0, 0, 1, 1 }; @@ -92,15 +107,26 @@ void populate_image(SDL_Window* window, Image* image){ image->pixels[current_pixel_idx + 2], image->pixels[current_pixel_idx + 3]); - SDL_FillSurfaceRect(image->surface, &pixel, color); + if(!SDL_FillSurfaceRect(image->surface, &pixel, color)) error_continue("Failed to fill surface rectangle! Trying to continue..."); } } image->texture = SDL_CreateTextureFromSurface(SDL_GetRenderer(window), image->surface); + if(!image->texture){ + error_continue("Failed to create texture from surface! Cleaning up and exiting..."); + SDL_DestroySurface(image->surface); + return false; + }; + + return true; } -void draw_image(SDL_Window* window, Image* image, float pixel_size_delta, int image_start_x, int image_start_y){ +bool draw_image(SDL_Window* window, Image* image, float pixel_size_delta, int image_start_x, int image_start_y){ SDL_Surface* surface = SDL_GetWindowSurface(window); + if(!surface){ + error_continue("Failed to get window surface! Cleaning up and exiting..."); + return false; + } float pixel_size = pixel_size_delta; @@ -111,12 +137,27 @@ void draw_image(SDL_Window* window, Image* image, float pixel_size_delta, int im SDL_FRect dst = { center_x - (image->x * pixel_size / 2) + image_start_x, center_y - (image->y * pixel_size / 2) + image_start_y, image->x * pixel_size, image->y * pixel_size }; SDL_Renderer* renderer = SDL_GetRenderer(window); - SDL_RenderClear(renderer); - SDL_RenderTexture(renderer, image->texture, NULL, &dst); - SDL_RenderPresent(renderer); - + if(!renderer){ + error_continue("Failed to get window renderer! Cleaning up and exiting..."); + return false; + } + + if(!SDL_RenderClear(renderer)){ + error_continue("Failed to clear renderer! Cleaning up and exiting..."); + return false; + } + if(!SDL_RenderTexture(renderer, image->texture, NULL, &dst)){ + error_continue("Failed to render texture! Cleaning up and exiting..."); + return false; + } + if(!SDL_RenderPresent(renderer)){ + error_continue("Failed to present renderer! Cleaning up and exiting..."); + return false; + } + printf("Redraw time: %.3fms\n", (SDL_GetTicksNS() - start) / 1000000.0); - + + return true; } int clamp(const int in, const int low, const int high){ @@ -198,8 +239,8 @@ void loop(SDL_Window* window, Image* image){ if(event.type == SDL_EVENT_MOUSE_MOTION){ if(drag_left_mouse){ int last_x, last_y; - SDL_GetWindowPosition(window, &last_x, &last_y); - SDL_SetWindowPosition(window, last_x + (int)event.motion.x - last_pointer_x, last_y + (int)event.motion.y - last_pointer_y); + if(!SDL_GetWindowPosition(window, &last_x, &last_y)) error_continue("Failed to get window position!"); + else if(!SDL_SetWindowPosition(window, last_x + (int)event.motion.x - last_pointer_x, last_y + (int)event.motion.y - last_pointer_y)) error_continue("Failed to set window position!"); } if(drag_right_mouse){ int image_start_x = (int)event.motion.x - last_pointer_x + image_start_at_drag_x; @@ -226,7 +267,7 @@ void loop(SDL_Window* window, Image* image){ if(redraw){ redraw = false; - draw_image(window, image, pixel_size_delta, current_image_start_x, current_image_start_y); + if(!draw_image(window, image, pixel_size_delta, current_image_start_x, current_image_start_y)) error_continue("Failed to draw image! Trying to continue..."); } } } @@ -253,20 +294,33 @@ int main(int argc, char** argv){ SDL_Window* window = create_window("SimpleImageViewer", image.x, image.y); if(!window){ printf("Failed to create window!"); + free_image_pixels_buffer(&image); exit(4); } SDL_Surface* surface = SDL_GetWindowSurface(window); if(!surface){ printf("Failed to get surface!"); + SDL_DestroyWindow(window); + free_image_pixels_buffer(&image); exit(5); } - populate_image(window, &image); + if(!populate_image(window, &image)){ + printf("Failed to populate image!"); + free_image_pixels_buffer(&image); + SDL_DestroyWindow(window); + exit(6); + } + free_image_pixels_buffer(&image); - draw_image(window, &image, 1.0f, 0, 0); - + if(!draw_image(window, &image, 1.0f, 0, 0)){ + printf("Failed to draw image!"); + SDL_DestroyWindow(window); + exit(7); + } + loop(window, &image); SDL_DestroyTexture(image.texture);