]> git.ipfire.org Git - thirdparty/cups.git/blob - filter/image-pnm.c
Remove svn:keywords since they cause svn_load_dirs.pl to complain about every file.
[thirdparty/cups.git] / filter / image-pnm.c
1 /*
2 * "$Id: image-pnm.c 177 2006-06-21 00:20:03Z jlovell $"
3 *
4 * Portable Any Map file routines for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1993-2006 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 USA
19 *
20 * Voice: (301) 373-9600
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 * _cupsImageReadPNM() - Read a PNM image file.
29 */
30
31 /*
32 * Include necessary headers...
33 */
34
35 #include "image-private.h"
36
37
38 /*
39 * '_cupsImageReadPNM()' - Read a PNM image file.
40 */
41
42 int /* O - Read status */
43 _cupsImageReadPNM(
44 cups_image_t *img, /* IO - cupsImage */
45 FILE *fp, /* I - cupsImage file */
46 cups_icspace_t primary, /* I - Primary choice for colorspace */
47 cups_icspace_t secondary, /* I - Secondary choice for colorspace */
48 int saturation, /* I - Color saturation (%) */
49 int hue, /* I - Color hue (degrees) */
50 const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */
51 {
52 int x, y; /* Looping vars */
53 int bpp; /* Bytes per pixel */
54 cups_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 > CUPS_IMAGE_MAX_WIDTH ||
136 img->ysize == 0 || img->ysize > CUPS_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 == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
155
156 cupsImageSetMaxTiles(img, 0);
157
158 bpp = cupsImageGetDepth(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 == CUPS_IMAGE_WHITE)
226 {
227 if (lut)
228 cupsImageLut(in, img->xsize, lut);
229
230 _cupsImagePutRow(img, 0, y, img->xsize, in);
231 }
232 else
233 {
234 switch (img->colorspace)
235 {
236 default :
237 break;
238
239 case CUPS_IMAGE_RGB :
240 cupsImageWhiteToRGB(in, out, img->xsize);
241 break;
242 case CUPS_IMAGE_BLACK :
243 cupsImageWhiteToBlack(in, out, img->xsize);
244 break;
245 case CUPS_IMAGE_CMY :
246 cupsImageWhiteToCMY(in, out, img->xsize);
247 break;
248 case CUPS_IMAGE_CMYK :
249 cupsImageWhiteToCMYK(in, out, img->xsize);
250 break;
251 }
252
253 if (lut)
254 cupsImageLut(out, img->xsize * bpp, lut);
255
256 _cupsImagePutRow(img, 0, y, img->xsize, out);
257 }
258 break;
259
260 default :
261 if ((saturation != 100 || hue != 0) && bpp > 1)
262 cupsImageRGBAdjust(in, img->xsize, saturation, hue);
263
264 switch (img->colorspace)
265 {
266 default :
267 break;
268
269 case CUPS_IMAGE_WHITE :
270 cupsImageRGBToWhite(in, out, img->xsize);
271 break;
272 case CUPS_IMAGE_RGB :
273 cupsImageRGBToRGB(in, out, img->xsize);
274 break;
275 case CUPS_IMAGE_BLACK :
276 cupsImageRGBToBlack(in, out, img->xsize);
277 break;
278 case CUPS_IMAGE_CMY :
279 cupsImageRGBToCMY(in, out, img->xsize);
280 break;
281 case CUPS_IMAGE_CMYK :
282 cupsImageRGBToCMYK(in, out, img->xsize);
283 break;
284 }
285
286 if (lut)
287 cupsImageLut(out, img->xsize * bpp, lut);
288
289 _cupsImagePutRow(img, 0, y, img->xsize, out);
290 break;
291 }
292 }
293
294 free(in);
295 free(out);
296
297 fclose(fp);
298
299 return (0);
300 }
301
302
303 /*
304 * End of "$Id: image-pnm.c 177 2006-06-21 00:20:03Z jlovell $".
305 */