]> git.ipfire.org Git - thirdparty/cups.git/blob - filter/image-pnm.c
Mirror 1.1.x changes.
[thirdparty/cups.git] / filter / image-pnm.c
1 /*
2 * "$Id: image-pnm.c,v 1.7.2.6 2004/02/25 20:01:37 mike Exp $"
3 *
4 * Portable Any Map file routines for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1993-2003 by Easy Software Products.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
19 *
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * This file is subject to the Apple OS-Developed Software exception.
25 *
26 * Contents:
27 *
28 * ImageReadPNM() - Read a PNM image file.
29 */
30
31 /*
32 * Include necessary headers...
33 */
34
35 #include "image.h"
36 #include <ctype.h>
37
38
39 /*
40 * 'ImageReadPNM()' - Read a PNM image file.
41 */
42
43 int /* O - Read status */
44 ImageReadPNM(image_t *img, /* IO - Image */
45 FILE *fp, /* I - Image file */
46 int primary, /* I - Primary choice for colorspace */
47 int secondary, /* I - Secondary choice for colorspace */
48 int saturation, /* I - Color saturation (%) */
49 int hue, /* I - Color hue (degrees) */
50 const ib_t *lut) /* I - Lookup table for gamma/brightness */
51 {
52 int x, y; /* Looping vars */
53 int bpp; /* Bytes per pixel */
54 ib_t *in, /* Input pixels */
55 *inptr, /* Current input pixel */
56 *out, /* Output pixels */
57 *outptr, /* Current output pixel */
58 bit; /* Bit in input line */
59 char line[255], /* Input line */
60 *lineptr; /* Pointer in line */
61 int format, /* Format of PNM file */
62 val, /* Pixel value */
63 maxval; /* Maximum pixel value */
64
65
66 /*
67 * Read the file header in the format:
68 *
69 * Pformat
70 * # comment1
71 * # comment2
72 * ...
73 * # commentN
74 * width
75 * height
76 * max sample
77 */
78
79 lineptr = fgets(line, sizeof(line), fp);
80 lineptr ++;
81
82 format = atoi(lineptr);
83 while (isdigit(*lineptr & 255))
84 lineptr ++;
85
86 while (lineptr != NULL && img->xsize == 0)
87 {
88 if (*lineptr == '\0' || *lineptr == '#')
89 lineptr = fgets(line, sizeof(line), fp);
90 else if (isdigit(*lineptr & 255))
91 {
92 img->xsize = atoi(lineptr);
93 while (isdigit(*lineptr & 255))
94 lineptr ++;
95 }
96 else
97 lineptr ++;
98 }
99
100 while (lineptr != NULL && img->ysize == 0)
101 {
102 if (*lineptr == '\0' || *lineptr == '#')
103 lineptr = fgets(line, sizeof(line), fp);
104 else if (isdigit(*lineptr & 255))
105 {
106 img->ysize = atoi(lineptr);
107 while (isdigit(*lineptr & 255))
108 lineptr ++;
109 }
110 else
111 lineptr ++;
112 }
113
114 if (format != 1 && format != 4)
115 {
116 maxval = 0;
117
118 while (lineptr != NULL && maxval == 0)
119 {
120 if (*lineptr == '\0' || *lineptr == '#')
121 lineptr = fgets(line, sizeof(line), fp);
122 else if (isdigit(*lineptr & 255))
123 {
124 maxval = atoi(lineptr);
125 while (isdigit(*lineptr & 255))
126 lineptr ++;
127 }
128 else
129 lineptr ++;
130 }
131 }
132 else
133 maxval = 1;
134
135 if (img->xsize == 0 || img->xsize > IMAGE_MAX_WIDTH ||
136 img->ysize == 0 || img->ysize > IMAGE_MAX_HEIGHT)
137 {
138 fprintf(stderr, "ERROR: Bad PNM dimensions %dx%d!\n",
139 img->xsize, img->ysize);
140 fclose(fp);
141 return (1);
142 }
143
144 if (maxval == 0)
145 {
146 fprintf(stderr, "ERROR: Bad PNM max value %d!\n", maxval);
147 fclose(fp);
148 return (1);
149 }
150
151 if (format == 1 || format == 2 || format == 4 || format == 5)
152 img->colorspace = secondary;
153 else
154 img->colorspace = (primary == IMAGE_RGB_CMYK) ? IMAGE_RGB : primary;
155
156 ImageSetMaxTiles(img, 0);
157
158 bpp = ImageGetDepth(img);
159 in = malloc(img->xsize * 3);
160 out = malloc(img->xsize * bpp);
161
162 /*
163 * Read the image file...
164 */
165
166 for (y = 0; y < img->ysize; y ++)
167 {
168 switch (format)
169 {
170 case 1 :
171 case 2 :
172 for (x = img->xsize, inptr = in; x > 0; x --, inptr ++)
173 if (fscanf(fp, "%d", &val) == 1)
174 *inptr = 255 * val / maxval;
175 break;
176
177 case 3 :
178 for (x = img->xsize, inptr = in; x > 0; x --, inptr += 3)
179 {
180 if (fscanf(fp, "%d", &val) == 1)
181 inptr[0] = 255 * val / maxval;
182 if (fscanf(fp, "%d", &val) == 1)
183 inptr[1] = 255 * val / maxval;
184 if (fscanf(fp, "%d", &val) == 1)
185 inptr[2] = 255 * val / maxval;
186 }
187 break;
188
189 case 4 :
190 fread(out, (img->xsize + 7) / 8, 1, fp);
191 for (x = img->xsize, inptr = in, outptr = out, bit = 128;
192 x > 0;
193 x --, inptr ++)
194 {
195 if (*outptr & bit)
196 *inptr = 255;
197 else
198 *inptr = 0;
199
200 if (bit > 1)
201 bit >>= 1;
202 else
203 {
204 bit = 128;
205 inptr ++;
206 }
207 }
208 break;
209
210 case 5 :
211 fread(in, img->xsize, 1, fp);
212 break;
213
214 case 6 :
215 fread(in, img->xsize, 3, fp);
216 break;
217 }
218
219 switch (format)
220 {
221 case 1 :
222 case 2 :
223 case 4 :
224 case 5 :
225 if (img->colorspace == IMAGE_WHITE)
226 {
227 if (lut)
228 ImageLut(in, img->xsize, lut);
229
230 ImagePutRow(img, 0, y, img->xsize, in);
231 }
232 else
233 {
234 switch (img->colorspace)
235 {
236 case IMAGE_RGB :
237 ImageWhiteToRGB(in, out, img->xsize);
238 break;
239 case IMAGE_BLACK :
240 ImageWhiteToBlack(in, out, img->xsize);
241 break;
242 case IMAGE_CMY :
243 ImageWhiteToCMY(in, out, img->xsize);
244 break;
245 case IMAGE_CMYK :
246 ImageWhiteToCMYK(in, out, img->xsize);
247 break;
248 }
249
250 if (lut)
251 ImageLut(out, img->xsize * bpp, lut);
252
253 ImagePutRow(img, 0, y, img->xsize, out);
254 }
255 break;
256
257 default :
258 if ((saturation != 100 || hue != 0) && bpp > 1)
259 ImageRGBAdjust(in, img->xsize, saturation, hue);
260
261 if (img->colorspace == IMAGE_RGB)
262 {
263 if (lut)
264 ImageLut(in, img->xsize * 3, lut);
265
266 ImagePutRow(img, 0, y, img->xsize, in);
267 }
268 else
269 {
270 switch (img->colorspace)
271 {
272 case IMAGE_WHITE :
273 ImageRGBToWhite(in, out, img->xsize);
274 break;
275 case IMAGE_BLACK :
276 ImageRGBToBlack(in, out, img->xsize);
277 break;
278 case IMAGE_CMY :
279 ImageRGBToCMY(in, out, img->xsize);
280 break;
281 case IMAGE_CMYK :
282 ImageRGBToCMYK(in, out, img->xsize);
283 break;
284 }
285
286 if (lut)
287 ImageLut(out, img->xsize * bpp, lut);
288
289 ImagePutRow(img, 0, y, img->xsize, out);
290 }
291 break;
292 }
293 }
294
295 free(in);
296 free(out);
297
298 fclose(fp);
299
300 return (0);
301 }
302
303
304 /*
305 * End of "$Id: image-pnm.c,v 1.7.2.6 2004/02/25 20:01:37 mike Exp $".
306 */