configure: add return_check and return_statement_check helpers
[mplayer/greg.git] / pnm_loader.c
blob048461e51f4901acd09262c966e43db13a4c0035
1 /*
2 * PNM image files loader
4 * copyleft (C) 2005-2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
6 * This file is part of MPlayer.
8 * MPlayer is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * MPlayer is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 * You can alternatively redistribute this file and/or
23 * modify it under the terms of the GNU Lesser General Public
24 * License as published by the Free Software Foundation; either
25 * version 2.1 of the License, or (at your option) any later version.
28 /**
29 * \file pnm_loader.c
30 * \brief PNM image files loader
33 #include <stdlib.h>
34 #include <stdint.h>
35 #include <stdio.h>
36 #include <ctype.h>
37 #include "pnm_loader.h"
39 /**
40 * \brief skips whitespace and comments
41 * \param f file to read from
43 static void ppm_skip(FILE *f) {
44 int c, comment = 0;
45 do {
46 c = fgetc(f);
47 if (c == '#')
48 comment = 1;
49 if (c == '\n')
50 comment = 0;
51 } while (c != EOF && (isspace(c) || comment));
52 if (c != EOF)
53 ungetc(c, f);
56 #define MAXDIM (16 * 1024)
58 uint8_t *read_pnm(FILE *f, int *width, int *height,
59 int *bytes_per_pixel, int *maxval) {
60 uint8_t *data;
61 int type;
62 unsigned w, h, m, val, bpp;
63 *width = *height = *bytes_per_pixel = *maxval = 0;
64 ppm_skip(f);
65 if (fgetc(f) != 'P')
66 return NULL;
67 type = fgetc(f);
68 if (type != '5' && type != '6')
69 return NULL;
70 ppm_skip(f);
71 if (fscanf(f, "%u", &w) != 1)
72 return NULL;
73 ppm_skip(f);
74 if (fscanf(f, "%u", &h) != 1)
75 return NULL;
76 ppm_skip(f);
77 if (fscanf(f, "%u", &m) != 1)
78 return NULL;
79 val = fgetc(f);
80 if (!isspace(val))
81 return NULL;
82 if (w > MAXDIM || h > MAXDIM)
83 return NULL;
84 bpp = (m > 255) ? 2 : 1;
85 if (type == '6')
86 bpp *= 3;
87 data = malloc(w * h * bpp);
88 if (fread(data, w * bpp, h, f) != h) {
89 free(data);
90 return NULL;
92 *width = w;
93 *height = h;
94 *bytes_per_pixel = bpp;
95 *maxval = m;
96 return data;