/* * ppm.c - Load a PPM image * * Written 2010-2011 by Werner Almesberger * Copyright 2010-2011 Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include #include #include #include "ppm.h" static char *fgets_comment(char *line, int n, FILE *file) { do { if (!fgets(line, n, file)) return NULL; } while (*line == '#'); return line; } uint8_t *load_ppm(const char *name, int *x, int *y) { FILE *file; char line[100]; int this_x, this_y, depth; int n; uint8_t *img; file = fopen(name, "r"); if (!file) { perror(name); exit(1); } if (!fgets_comment(line, sizeof(line), file)) { fprintf(stderr, "can't read file type\n"); exit(1); } if (strcmp(line, "P6\n")) { fprintf(stderr, "file type must be P6, not %s", line); exit(1); } if (!fgets_comment(line, sizeof(line), file)) { fprintf(stderr, "can't read resolution\n"); exit(1); } if (sscanf(line, "%d %d", &this_x, &this_y) != 2) { fprintf(stderr, "can't parse resolution: %s", line); exit(1); } if (*x || *y) { if (*x != this_x || *y != this_y) { fprintf(stderr, "resolution changed from %dx%d to %dx%d\n", *x, *y, this_x, this_y); exit(1); } } else { *x = this_x; *y = this_y; } if (!fgets_comment(line, sizeof(line), file)) { fprintf(stderr, "can't read depth\n"); exit(1); } if (sscanf(line, "%d", &depth) != 1) { fprintf(stderr, "can't parse depth: %s", line); exit(1); } if (depth != 255) { fprintf(stderr, "depth must be 255, not %d\n", depth); exit(1); } n = *x**y*3; img = malloc(n); if (!img) { perror("malloc"); exit(1); } if (fread(img, 1, n, file) != n) { fprintf(stderr, "can't read %d bytes\n", n); exit(1); } fclose(file); return img; }