Initial revision
[wmaker-crm.git] / wrlib / ppm.c
blob7c94bd00772f08cbebff284256ff12497878e98d
1 /* ppm.c - load PPM image from file
2 *
3 * Raster graphics library
4 *
5 * Copyright (c) 1997 Alfredo K. Kojima
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <config.h>
25 #include <X11/Xlib.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
30 #include "wraster.h"
33 static RImage*
34 load_graymap(char *file_name, FILE *file, int w, int h, int max, int raw)
36 RImage *image;
38 image = RCreateImage(w, h, 0);
39 if (!image) {
40 sprintf(RErrorString, "out of memory");
41 return NULL;
43 if (!raw) {
45 } else {
46 if (max<256) {
47 if (!fgets(image->data[0], w*h, file))
48 goto short_file;
49 memcpy(image->data[0], image->data[1], w*h);
50 memcpy(image->data[0], image->data[2], w*h);
51 } else {
56 return image;
58 short_file:
59 sprintf(RErrorString, "PPM file \"%s\" seems to be truncated", file_name);
60 return NULL;
64 static RImage*
65 load_pixmap(char *file_name, FILE *file, int w, int h, int max, int raw)
67 RImage *image;
68 int i;
69 char buf[3];
70 char *r, *g, *b;
72 image = RCreateImage(w, h, 0);
73 if (!image) {
74 sprintf(RErrorString, "out of memory");
75 return NULL;
77 r = image->data[0];
78 g = image->data[1];
79 b = image->data[2];
80 if (!raw) {
82 } else {
83 if (max<256) {
84 i = 0;
85 while (i < w*h) {
86 if (fread(buf, 1, 3, file)!=3)
87 goto short_file;
88 *(r++) = buf[0];
89 *(g++) = buf[1];
90 *(b++) = buf[2];
91 i++;
93 } else {
98 return image;
100 short_file:
101 sprintf(RErrorString, "PPM file \"%s\" seems to be truncated", file_name);
102 return NULL;
106 RImage*
107 RLoadPPM(RContext *context, char *file_name, int index)
109 FILE *file;
110 RImage *image = NULL;
111 char buffer[256];
112 int w, h, m;
113 int type;
115 #define GETL() if (!fgets(buffer, 255, file)) goto short_file
117 RErrorString[0] = 0;
119 file = fopen(file_name, "r");
120 if (!file) {
121 sprintf(RErrorString, "could not open PPM file \"%s\"", file_name);
122 return NULL;
125 /* get signature */
126 GETL();
128 /* only accept raw pixmaps or graymaps */
129 if (buffer[0] != 'P' || (buffer[1] != '5' && buffer[1] != '6')) {
130 sprintf(RErrorString, "unknown PPM format in \"%s\"", file_name);
131 fclose(file);
132 return NULL;
135 type = buffer[1];
137 /* skip comments */
138 while (1) {
139 GETL();
141 if (buffer[0]!='#')
142 break;
145 /* get size */
146 if (sscanf(buffer, "%i %i", &w, &h)!=2)
147 goto bad_file;
150 GETL();
151 if (sscanf(buffer, "%i", &m)!=1 || m < 1)
152 goto bad_file;
154 if (type=='5')
155 image = load_graymap(file_name, file, w, h, m, type=='5');
156 else if (type=='6')
157 image = load_pixmap(file_name, file, w, h, m, type=='6');
159 fclose(file);
160 return image;
162 bad_file:
163 sprintf(RErrorString, "PPM file \"%s\" seems to be corrupted", file_name);
164 fclose(file);
165 return NULL;
167 short_file:
168 sprintf(RErrorString, "PPM file \"%s\" seems to be truncated", file_name);
169 fclose(file);
170 return NULL;