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