1 /* ppm.c - load PPM image from file
3 * Raster graphics library
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * Copyright (c) 2014 Window Maker Team
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library 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 GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
33 #include "imgformat.h"
38 * fileio.c - routines to read elements based on Netpbm
40 * Copyright (C) 1988 by Jef Poskanzer.
42 * Permission to use, copy, modify, and distribute this software and its
43 * documentation for any purpose and without fee is hereby granted, provided
44 * that the above copyright notice appear in all copies and that both that
45 * copyright notice and this permission notice appear in supporting
46 * documentation. This software is provided "as is" without express or
50 char pm_getc(FILE *const fileP
, const char *filename
)
57 fprintf(stderr
, _("wrlib: EOF / read error reading a byte from PPM file \"%s\"\n"), filename
);
64 fprintf(stderr
, _("wrlib: EOF / read error reading a byte from PPM file \"%s\"\n"), filename
);
66 } while (ch
!= '\n' && ch
!= '\r');
71 unsigned char pm_getrawbyte(FILE *const file
, const char *filename
)
77 fprintf(stderr
, _("wrlib: EOF / read error reading a byte from PPM file \"%s\"\n"), filename
);
78 return (unsigned char)iby
;
81 int pm_getuint(FILE *const ifP
, const char *filename
)
87 ch
= pm_getc(ifP
, filename
);
88 } while (ch
== ' ' || ch
== '\t' || ch
== '\n' || ch
== '\r');
90 if (ch
< '0' || ch
> '9') {
91 fprintf(stderr
, _("wrlib: junk in PPM file \"%s\", expected an unsigned integer but got 0x%02X\n"), filename
, (int)ch
);
97 unsigned int const digitVal
= ch
- '0';
99 if (i
> INT_MAX
/ 10) {
100 fprintf(stderr
, _("wrlib: ASCII decimal integer in PPM file \"%s\" is too large to be processed\n"), filename
);
106 if (i
> INT_MAX
- digitVal
) {
107 fprintf(stderr
, _("wrlib: ASCII decimal integer in PPM file \"%s\" is too large to be processed\n"), filename
);
113 ch
= pm_getc(ifP
, filename
);
114 } while (ch
>= '0' && ch
<= '9');
118 /* end of fileio.c re-used code */
119 /******************************************************************************************/
121 /* PGM: support for portable graymap ascii and binary encoding */
122 static RImage
*load_graymap(FILE *file
, int w
, int h
, int max
, int raw
, const char *filename
)
128 if (raw
!= '2' && raw
!= '5') {
129 RErrorCode
= RERR_BADFORMAT
;
133 image
= RCreateImage(w
, h
, 0);
135 RErrorCode
= RERR_NOMEMORY
;
144 for (y
= 0; y
< h
; y
++) {
145 for (x
= 0; x
< w
; x
++) {
146 val
= pm_getuint(file
, filename
);
148 if (val
> max
|| val
< 0) {
149 RErrorCode
= RERR_BADIMAGEFILE
;
150 RReleaseImage(image
);
154 val
= val
* 255 / max
;
166 RErrorCode
= RERR_NOMEMORY
;
167 RReleaseImage(image
);
170 for (y
= 0; y
< h
; y
++) {
171 if (!fread(buf
, w
, 1, file
)) {
173 RErrorCode
= RERR_BADIMAGEFILE
;
174 RReleaseImage(image
);
178 for (x
= 0; x
< w
; x
++) {
191 /* PPM: support for portable pixmap ascii and binary encoding */
192 static RImage
*load_pixmap(FILE *file
, int w
, int h
, int max
, int raw
, const char *filename
)
198 if (raw
!= '3' && raw
!= '6') {
199 RErrorCode
= RERR_BADFORMAT
;
203 image
= RCreateImage(w
, h
, 0);
205 RErrorCode
= RERR_NOMEMORY
;
214 for (y
= 0; y
< h
; y
++) {
215 for (x
= 0; x
< w
; x
++) {
216 for (i
= 0; i
< 3; i
++) {
217 val
= pm_getuint(file
, filename
);
219 if (val
> max
|| val
< 0) {
220 RErrorCode
= RERR_BADIMAGEFILE
;
221 RReleaseImage(image
);
225 val
= val
* 255 / max
;
230 } else if (raw
== '6') {
235 if (fread(buf
, 1, 3, file
) != 3) {
236 RErrorCode
= RERR_BADIMAGEFILE
;
237 RReleaseImage(image
);
251 /* PBM: support for portable bitmap ascii and binary encoding */
252 static RImage
*load_bitmap(FILE *file
, int w
, int h
, int max
, int raw
, const char *filename
)
258 if (raw
!= '1' && raw
!= '4') {
259 RErrorCode
= RERR_BADFORMAT
;
263 image
= RCreateImage(w
, h
, 0);
265 RErrorCode
= RERR_NOMEMORY
;
274 val
= pm_getuint(file
, filename
);
276 if (val
> max
|| val
< 0) {
277 RErrorCode
= RERR_BADIMAGEFILE
;
278 RReleaseImage(image
);
282 val
= (val
== 0) ? 255 : 0;
294 for (y
= 0; y
< h
; y
++) {
296 for (x
= 0; x
< w
; x
++) {
297 if (bitshift
== -1) {
298 buf
= pm_getrawbyte(file
, filename
);
301 val
= (buf
>> bitshift
) & 1;
302 val
= (val
== 0) ? 255 : 0;
314 RImage
*RLoadPPM(const char *file_name
)
317 RImage
*image
= NULL
;
322 file
= fopen(file_name
, "rb");
324 RErrorCode
= RERR_OPEN
;
329 if (!fgets(buffer
, 255, file
)) {
330 RErrorCode
= RERR_BADIMAGEFILE
;
335 /* accept bitmaps, pixmaps or graymaps */
336 if (buffer
[0] != 'P' || (buffer
[1] < '1' || buffer
[1] > '6')) {
337 RErrorCode
= RERR_BADFORMAT
;
346 if (!fgets(buffer
, 255, file
)) {
347 RErrorCode
= RERR_BADIMAGEFILE
;
352 if (buffer
[0] != '#')
357 if (sscanf(buffer
, "%i %i", &w
, &h
) != 2 || w
< 1 || h
< 1) {
359 RErrorCode
= RERR_BADIMAGEFILE
;
364 if (type
!= '1' && type
!= '4') {
365 if (!fgets(buffer
, 255, file
)) {
366 RErrorCode
= RERR_BADIMAGEFILE
;
371 if (sscanf(buffer
, "%i", &m
) != 1 || m
< 1) {
373 RErrorCode
= RERR_BADIMAGEFILE
;
381 if (type
== '1' || type
== '4') {
382 /* Portable Bit Map: P1 is for 'plain' (ascii, rare), P4 for 'regular' (binary) */
383 image
= load_bitmap(file
, w
, h
, m
, type
, file_name
);
384 } else if (type
== '2' || type
== '5') {
385 /* Portable Gray Map: P2 is for 'plain' (ascii, rare), P5 for 'regular' (binary) */
386 image
= load_graymap(file
, w
, h
, m
, type
, file_name
);
387 } else if (type
== '3' || type
== '6') {
388 /* Portable Pix Map: P3 is for 'plain' (ascii, rare), P6 for 'regular' (binary) */
389 image
= load_pixmap(file
, w
, h
, m
, type
, file_name
);