annotate pnm_loader.c @ 32605:7b4f8ecdc33b

Fix mp_check_mp3_header: it checked for a byte-swapped MP3-header on little-endian, and on big-endian it would only accept a MP3-header that would be valid when read in both directions. The latter was the reason for bug 905, causing the PS demuxer to claim files far too agressively (the MP3 check avoiding misdetection as DV is not exactly a sane approach, but it mostly works).
author reimar
date Sat, 11 Dec 2010 21:11:33 +0000
parents 58232aeb3fdd
children 08a90b0e44e1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32427
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
1 /*
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
2 * PNM image files loader
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
3 *
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
4 * copyleft (C) 2005-2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
5 *
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
6 * This file is part of MPlayer.
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
7 *
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
8 * MPlayer is free software; you can redistribute it and/or modify
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
9 * it under the terms of the GNU General Public License as published by
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
10 * the Free Software Foundation; either version 2 of the License, or
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
11 * (at your option) any later version.
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
12 *
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
13 * MPlayer is distributed in the hope that it will be useful,
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
16 * GNU General Public License for more details.
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
17 *
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
18 * You should have received a copy of the GNU General Public License along
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
19 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
21 *
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
22 * You can alternatively redistribute this file and/or
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
23 * modify it under the terms of the GNU Lesser General Public
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
24 * License as published by the Free Software Foundation; either
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
25 * version 2.1 of the License, or (at your option) any later version.
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
26 */
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
27
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
28 /**
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
29 * \file pnm_loader.c
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
30 * \brief PNM image files loader
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
31 */
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
32
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
33 #include <stdlib.h>
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
34 #include <stdint.h>
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
35 #include <stdio.h>
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
36 #include <ctype.h>
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
37 #include "pnm_loader.h"
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
38
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
39 /**
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
40 * \brief skips whitespace and comments
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
41 * \param f file to read from
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
42 */
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
43 static void ppm_skip(FILE *f) {
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
44 int c, comment = 0;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
45 do {
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
46 c = fgetc(f);
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
47 if (c == '#')
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
48 comment = 1;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
49 if (c == '\n')
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
50 comment = 0;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
51 } while (c != EOF && (isspace(c) || comment));
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
52 if (c != EOF)
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
53 ungetc(c, f);
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
54 }
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
55
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
56 #define MAXDIM (16 * 1024)
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
57
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
58 uint8_t *read_pnm(FILE *f, int *width, int *height,
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
59 int *bytes_per_pixel, int *maxval) {
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
60 uint8_t *data;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
61 int type;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
62 unsigned w, h, m, val, bpp;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
63 *width = *height = *bytes_per_pixel = *maxval = 0;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
64 ppm_skip(f);
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
65 if (fgetc(f) != 'P')
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
66 return NULL;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
67 type = fgetc(f);
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
68 if (type != '5' && type != '6')
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
69 return NULL;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
70 ppm_skip(f);
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
71 if (fscanf(f, "%u", &w) != 1)
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
72 return NULL;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
73 ppm_skip(f);
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
74 if (fscanf(f, "%u", &h) != 1)
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
75 return NULL;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
76 ppm_skip(f);
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
77 if (fscanf(f, "%u", &m) != 1)
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
78 return NULL;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
79 val = fgetc(f);
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
80 if (!isspace(val))
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
81 return NULL;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
82 if (w > MAXDIM || h > MAXDIM)
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
83 return NULL;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
84 bpp = (m > 255) ? 2 : 1;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
85 if (type == '6')
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
86 bpp *= 3;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
87 data = malloc(w * h * bpp);
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
88 if (fread(data, w * bpp, h, f) != h) {
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
89 free(data);
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
90 return NULL;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
91 }
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
92 *width = w;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
93 *height = h;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
94 *bytes_per_pixel = bpp;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
95 *maxval = m;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
96 return data;
58232aeb3fdd Move the read_pnm function into a separate file.
cigaes
parents:
diff changeset
97 }