#include "aliases.h" #include "image.h" #include "mem_arena.h" #include "tiffread.h" #include #include #include #include #include #include #include #include #include #include #define MAIN_ARENA_CAPACITY 50 * 1024 * 1024 #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600 #define AMASK 0xff000000 #define BMASK 0x00ff0000 #define GMASK 0x0000ff00 #define RMASK 0x000000ff #define WHITE 0xff typedef struct point Point; struct point { u32 x; u32 y; }; internal void write_debug_ppm6(const Image *img); internal SDL_Texture *image_to_texture(SDL_Renderer *renderer, const Image *img); int main(int argc, char *argv[]) { int exit_code = EXIT_SUCCESS; Arena *arena = NULL; if (!wapp_mem_arena_init(&arena, MAIN_ARENA_CAPACITY)) { return EXIT_FAILURE; } const char *file_to_open = argc > 1 ? argv[1] : "./resources/test.tif"; Image *img = read_baseline_tiff(file_to_open, arena); if (!img) { 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; }; 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; } internal void write_debug_ppm6(const Image *img) { FILE *out = fopen("test.ppm", "wb"); char magic[] = {'P', '6', '\n'}; fwrite(magic, sizeof(magic), 1, out); char size[128]; sprintf(size, "%lu %lu\n", img->width, img->height); u64 size_length = strlen(size); fwrite(size, size_length, 1, out); char max[] = {'2', '5', '5', '\n'}; fwrite(max, sizeof(max), 1, out); for (u64 i = 0; i < img->pixel_count; ++i) { fwrite(&(img->data[i]), sizeof(u8), 3, out); } 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; } SDL_Surface *surface = SDL_CreateRGBSurface(0, img->width, img->height, 32, RMASK, GMASK, BMASK, AMASK); if (!surface) { goto IMAGE_TO_TEXTURE_RETURN; } SDL_LockSurface(surface); u64 position = 0; for (u64 i = 0; i < img->pixel_count; i += surface->w) { void *start = (void *)((uptr)(surface->pixels) + position); 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; }