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