#include namespace daguerre { //TODO: make this more robust static unsigned read_text_int(FILE *input) { unsigned n = 0; char ch; fread(&ch, 1, 1, input); if (ch == '#') { do fread(&ch, 1, 1, input); while (ch != '\n'); fread(&ch, 1, 1, input); } do { n = n * 10 + ch - '0'; fread(&ch, 1, 1, input); } while (ch >= '0' && ch <= '9'); return n; } //TODO: this only supports p6 format, and assumes max < 256 std::optional> try_load_ppm(FILE *input) { char header[3]; if (fread(header, 1, 3, input) != 3) return {}; if (header[0] != 'P' || header[1] != '6' || header[2] != '\n') return {}; unsigned width = read_text_int(input); unsigned height = read_text_int(input); unsigned max = read_text_int(input); image im(width, height); for (unsigned y = 0; y < height; ++y) for (unsigned x = 0; x < width; ++x) { if (fread(&im.buffer[y * width + x].r, 1, 1, input) != 1) return {}; if (fread(&im.buffer[y * width + x].g, 1, 1, input) != 1) return {}; if (fread(&im.buffer[y * width + x].b, 1, 1, input) != 1) return {}; } if (max != 255) for (unsigned v = 0; v < width * height; ++v) { im.buffer[v].r = ((uint16_t)im.buffer[v].r * 255) / max; im.buffer[v].g = ((uint16_t)im.buffer[v].g * 255) / max; im.buffer[v].b = ((uint16_t)im.buffer[v].b * 255) / max; } return im; } }