1 /*****************************************************************************
2 * This file is part of gfxprim library. *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
19 * Copyright (C) 2009-2010 Cyril Hrubis <metan@ucw.cz> *
21 *****************************************************************************/
36 PNM portable bitmap header
37 --------------------------
41 a magick number value of 'P' and one of
42 '1' - PBM 2bpp gray ASCII
44 '3' - PPM rgb888 ASCII
45 '4' - PBM 2bpp gray BINARY
47 '6' - PPM rgb888 BINARY
48 whitespace (blanks, TABs, CRs, LFs).
53 maximal value (interval is 0 ... max) (not applicable for PBM)
54 width * height ascii or binary values
56 lines starting with '#' are comments to the end of line
60 static void try_read_comments(FILE *f
)
64 while (isspace(c1
= fgetc(f
)));
68 while ((c1
= fgetc(f
)) == '#') {
71 } while (c2
!= '\n' && c2
!= EOF
);
78 static char *pnm_names
[] = {
87 FILE *GP_ReadPNM(const char *src_path
, char *fmt
,
88 uint32_t *w
, uint32_t *h
, uint32_t *depth
)
90 FILE *f
= fopen(src_path
, "r");
94 GP_DEBUG(1, "Failed to open file '%s': %s",
95 src_path
, strerror(errno
));
102 GP_DEBUG(1, "Invalid PNM header start '%c' (0x%2x) expecting 'P'",
103 isprint(ch
) ? ch
: ' ', ch
);
120 GP_DEBUG(1, "Invalid PNM format 'P%c' (0x%2x)",
121 isprint(ch
) ? ch
: ' ', ch
);
127 try_read_comments(f
);
129 if (fscanf(f
, "%"PRIu32
"\n", w
) < 1) {
130 GP_DEBUG(1, "Failed to read PNM header width");
134 try_read_comments(f
);
136 if (fscanf(f
, "%"PRIu32
"\n", h
) < 1) {
137 GP_DEBUG(1, "Failed to read PNM header height");
141 GP_DEBUG(2, "Have %s size %"PRIu32
"x%"PRIu32
,
142 pnm_names
[*fmt
- '1'], *w
, *h
);
144 if (*fmt
== '1' || *fmt
== '3')
147 try_read_comments(f
);
149 if (fscanf(f
, "%"PRIu32
"\n", depth
) < 1) {
150 GP_DEBUG(1, "Failed to read PNM header depth");
160 #define GFXPRIM_SIGNATURE "# Generated by gfxprim http://gfxprim.ucw.cz\n"
162 FILE *GP_WritePNM(const char *dst_path
, char fmt
,
163 uint32_t w
, uint32_t h
, uint32_t depth
)
165 FILE *f
= fopen(dst_path
, "w");
168 ret
= fprintf(f
, "P%c\n"GFXPRIM_SIGNATURE
169 "%"PRIu32
" %"PRIu32
"\n%"PRIu32
"\n",
173 GP_DEBUG(1, "Failed to write PNM header '%s' : %s",
174 dst_path
, strerror(errno
));