#include "all.h" #include #include #include #include Image read_ppm_image(const char *filename) { Image img = {0}; FILE *f = fopen(filename, "rb"); if (!f) { perror("fopen"); return (Image){}; } int j = 0; int in_token = 0; int header_done = 0; size_t pixel_count = 0; size_t pixel_capacity = 0; unsigned char buf[4096]; size_t nread; while ((nread = fread(buf, 1, sizeof buf, f)) > 0) { for (size_t i = 0; i < nread; ++i) { unsigned char c = buf[i]; if (!header_done) { if (isspace(c)) { if (in_token) { j++; in_token = 0; if (j == 4) { header_done = 1; pixel_capacity = img.width * img.height * 3; img.pixels = malloc(pixel_capacity); if (!img.pixels) { perror("malloc"); fclose(f); return (Image){}; } } } continue; } in_token = 1; switch (j) { case 0: { size_t len = strlen(img.format); if (len + 1 < sizeof img.format) { img.format[len] = (char)c; img.format[len + 1] = '\0'; } } break; case 1: { if (isdigit(c)) { img.width = img.width * 10 + (c - '0'); } } break; case 2: { if (isdigit(c)) { img.height = img.height * 10 + (c - '0'); } } break; case 3: { if (isdigit(c)) { img.color_space = img.color_space * 10 + (c - '0'); } } break; } } else { if (pixel_count < pixel_capacity) { img.pixels[pixel_count++] = c; } } } } fclose(f); printf("Loading image: [%s] %s (%dx%d) %d (%zu/%zu)\n", filename, img.format, img.width, img.height, img.color_space, pixel_count, pixel_capacity); return img; }