From a5080482112847588b1817f2645cc93d429b2a65 Mon Sep 17 00:00:00 2001
From: Abdelrahman <said.abdelrahman89@gmail.com>
Date: Sat, 4 May 2024 19:15:34 +0100
Subject: [PATCH] Display loaded TIFF in SDL window

---
 src/main.c | 214 ++++++++++++++++++++++++++++-------------------------
 1 file changed, 113 insertions(+), 101 deletions(-)

diff --git a/src/main.c b/src/main.c
index fef9520..253c45c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -30,6 +30,8 @@ struct point {
 };
 
 Point point_from_index(u32 index, u32 w);
+void write_debug_ppm6(const Image *img);
+SDL_Texture *image_to_texture(SDL_Renderer *renderer, const Image *img);
 
 int main(int argc, char *argv[]) {
   int exit_code = EXIT_SUCCESS;
@@ -47,6 +49,91 @@ int main(int argc, char *argv[]) {
     goto MAIN_DESTROY_ARENA;
   }
 
+  write_debug_ppm6(img);
+
+  if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
+    exit_code = EXIT_FAILURE;
+    goto MAIN_DESTROY_ARENA;
+  };
+
+  SDL_Window *window =
+      SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
+                       WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
+  if (!window) {
+    exit_code = EXIT_FAILURE;
+    goto MAIN_QUIT_SDL;
+  }
+
+  SDL_Renderer *renderer = SDL_CreateRenderer(
+      window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+  if (!renderer) {
+    exit_code = EXIT_FAILURE;
+    goto MAIN_DESTROY_WINDOW;
+  }
+
+  SDL_Texture *texture = image_to_texture(renderer, img);
+  if (!texture) {
+    exit_code = EXIT_FAILURE;
+    goto MAIN_DESTROY_RENDERER;
+  }
+
+  SDL_Rect dest = {
+      .h = img->height,
+      .w = img->width,
+      .x = (WINDOW_WIDTH - img->width) / 2,
+      .y = (WINDOW_HEIGHT - img->height) / 2,
+  };
+
+  bool running = true;
+
+  SDL_Event event = {0};
+
+  while (running) {
+    while (SDL_PollEvent(&event)) {
+      switch (event.type) {
+      case SDL_QUIT:
+        running = false;
+        break;
+      }
+    }
+
+    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
+
+    SDL_RenderClear(renderer);
+
+    SDL_RenderCopy(renderer, texture, NULL, &dest);
+
+    SDL_RenderPresent(renderer);
+  }
+
+  SDL_DestroyTexture(texture);
+
+MAIN_DESTROY_RENDERER:
+  SDL_DestroyRenderer(renderer);
+
+MAIN_DESTROY_WINDOW:
+  SDL_DestroyWindow(window);
+
+MAIN_QUIT_SDL:
+  SDL_Quit();
+
+MAIN_DESTROY_ARENA:
+  wapp_mem_arena_destroy(&arena);
+
+  return exit_code;
+}
+
+Point point_from_index(u32 index, u32 w) {
+  Point out = {0};
+
+  out.x = index % w;
+
+  out.y = (index - (index % w)) / w;
+
+  return out;
+}
+
+void write_debug_ppm6(const Image *img) {
   FILE *out = fopen("test.ppm", "wb");
 
   char magic[] = {'P', '6', '\n'};
@@ -65,110 +152,35 @@ int main(int argc, char *argv[]) {
   }
 
   fclose(out);
-
-  // if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
-  //   exit_code = EXIT_FAILURE;
-  //   goto MAIN_FREE_CONTEXT;
-  // };
-
-  // SDL_Window *window =
-  //     SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED,
-  //     SDL_WINDOWPOS_CENTERED,
-  //                      WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
-  // if (!window) {
-  //   exit_code = EXIT_FAILURE;
-  //   goto MAIN_QUIT_SDL;
-  // }
-
-  // SDL_Renderer *renderer = SDL_CreateRenderer(
-  //     window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
-  // if (!renderer) {
-  //   exit_code = EXIT_FAILURE;
-  //   goto MAIN_DESTROY_WINDOW;
-  // }
-
-  // SDL_Surface *surface = SDL_CreateRGBSurface(0, img->width, img->height, 32,
-  //                                             RMASK, GMASK, BMASK, AMASK);
-  // if (!surface) {
-  //   exit_code = EXIT_FAILURE;
-  //   goto MAIN_DESTROY_RENDERER;
-  // }
-
-  // uint64_t surface_length = surface->h * surface->pitch;
-  // printf("%lu\n", surface_length);
-  // printf("%u\n", surface->w * surface->h);
-
-  // SDL_LockSurface(surface);
-  // u64 position = 0;
-  // for (u64 i = 0; i < surface_length; i += surface->pitch) {
-  //   memcpy(&(((u32 *)surface->pixels)[i]), &(img->data[position]),
-  //          surface->pitch / sizeof(Pixel));
-
-  //   position += surface->pitch;
-  // }
-  // SDL_UnlockSurface(surface);
-
-  // SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
-  // if (!texture) {
-  //   exit_code = EXIT_FAILURE;
-  //   goto MAIN_DESTROY_SURFACE;
-  // }
-
-  // SDL_Rect dest = {
-  //     .w = surface->w,
-  //     .h = surface->h,
-  //     .x = (WINDOW_WIDTH - surface->w) / 2,
-  //     .y = (WINDOW_HEIGHT - surface->h) / 2,
-  // };
-
-  // bool running = true;
-
-  // SDL_Event event = {0};
-
-  // while (running) {
-  //   while (SDL_PollEvent(&event)) {
-  //     switch (event.type) {
-  //     case SDL_QUIT:
-  //       running = false;
-  //       break;
-  //     }
-  //   }
-
-  //   SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
-
-  //   SDL_RenderClear(renderer);
-
-  //   SDL_RenderCopy(renderer, texture, NULL, &dest);
-
-  //   SDL_RenderPresent(renderer);
-  // }
-
-  // SDL_DestroyTexture(texture);
-
-  // MAIN_DESTROY_SURFACE:
-  // SDL_FreeSurface(surface);
-
-  // MAIN_DESTROY_RENDERER:
-  // SDL_DestroyRenderer(renderer);
-
-  // MAIN_DESTROY_WINDOW:
-  // SDL_DestroyWindow(window);
-
-  // MAIN_QUIT_SDL:
-  // SDL_Quit();
-
-MAIN_DESTROY_ARENA:
-  wapp_mem_arena_destroy(&arena);
-
-  return exit_code;
 }
 
-Point point_from_index(u32 index, u32 w) {
-  Point out = {0};
+SDL_Texture *image_to_texture(SDL_Renderer *renderer, const Image *img) {
+  SDL_Texture *output = NULL;
+  if (!renderer || !img) {
+    goto IMAGE_TO_TEXTURE_RETURN;
+  }
 
-  out.x = index % w;
+  SDL_Surface *surface = SDL_CreateRGBSurface(0, img->width, img->height, 32,
+                                              RMASK, GMASK, BMASK, AMASK);
+  if (!surface) {
+    goto IMAGE_TO_TEXTURE_RETURN;
+  }
 
-  out.y = (index - (index % w)) / w;
+  SDL_LockSurface(surface);
+  u64 position = 0;
+  for (u64 i = 0; i < img->pixel_count; i += surface->w) {
+    void *start = (void *)((uptr)(surface->pixels) + position);
 
-  return out;
+    memcpy(start, &(img->data[i]), surface->w * sizeof(Pixel));
+
+    position += surface->pitch;
+  }
+  SDL_UnlockSurface(surface);
+
+  output = SDL_CreateTextureFromSurface(renderer, surface);
+
+  SDL_FreeSurface(surface);
+
+IMAGE_TO_TEXTURE_RETURN:
+  return output;
 }