Root/ubb-vga/ppm.c

1/*
2 * ppm.c - Load a PPM image
3 *
4 * Written 2010-2011 by Werner Almesberger
5 * Copyright 2010-2011 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <stdint.h>
15#include <stdlib.h>
16#include <stdio.h>
17#include <string.h>
18
19#include "ppm.h"
20
21
22static char *fgets_comment(char *line, int n, FILE *file)
23{
24    do {
25        if (!fgets(line, n, file))
26            return NULL;
27    }
28    while (*line == '#');
29    return line;
30}
31
32
33uint8_t *load_ppm(const char *name, int *x, int *y)
34{
35    FILE *file;
36    char line[100];
37    int this_x, this_y, depth;
38    int n;
39    uint8_t *img;
40
41    file = fopen(name, "r");
42    if (!file) {
43        perror(name);
44        exit(1);
45    }
46    if (!fgets_comment(line, sizeof(line), file)) {
47        fprintf(stderr, "can't read file type\n");
48        exit(1);
49    }
50    if (strcmp(line, "P6\n")) {
51        fprintf(stderr, "file type must be P6, not %s", line);
52        exit(1);
53    }
54    if (!fgets_comment(line, sizeof(line), file)) {
55        fprintf(stderr, "can't read resolution\n");
56        exit(1);
57    }
58    if (sscanf(line, "%d %d", &this_x, &this_y) != 2) {
59        fprintf(stderr, "can't parse resolution: %s", line);
60        exit(1);
61    }
62    if (*x || *y) {
63        if (*x != this_x || *y != this_y) {
64            fprintf(stderr,
65                "resolution changed from %dx%d to %dx%d\n",
66                *x, *y, this_x, this_y);
67            exit(1);
68        }
69    } else {
70        *x = this_x;
71        *y = this_y;
72    }
73    if (!fgets_comment(line, sizeof(line), file)) {
74        fprintf(stderr, "can't read depth\n");
75        exit(1);
76    }
77    if (sscanf(line, "%d", &depth) != 1) {
78        fprintf(stderr, "can't parse depth: %s", line);
79        exit(1);
80    }
81    if (depth != 255) {
82        fprintf(stderr, "depth must be 255, not %d\n", depth);
83        exit(1);
84    }
85    n = *x**y*3;
86    img = malloc(n);
87    if (!img) {
88        perror("malloc");
89        exit(1);
90    }
91    if (fread(img, 1, n, file) != n) {
92        fprintf(stderr, "can't read %d bytes\n", n);
93        exit(1);
94    }
95    fclose(file);
96    return img;
97}
98

Archive Download this file

Branches:
master



interactive