• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *   SGI image 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  *   _cupsImageReadSGI() - Read a SGI image file.
15  */
16 
17 /*
18  * Include necessary headers...
19  */
20 
21 #include "image-private.h"
22 #include "image-sgi.h"
23 
24 
25 /*
26  * '_cupsImageReadSGI()' - Read a SGI image file.
27  */
28 
29 int					/* O - Read status */
_cupsImageReadSGI(cups_image_t * img,FILE * fp,cups_icspace_t primary,cups_icspace_t secondary,int saturation,int hue,const cups_ib_t * lut)30 _cupsImageReadSGI(
31     cups_image_t    *img,		/* IO - cupsImage */
32     FILE            *fp,		/* I - cupsImage file */
33     cups_icspace_t  primary,		/* I - Primary choice for colorspace */
34     cups_icspace_t  secondary,		/* I - Secondary choice for colorspace */
35     int             saturation,		/* I - Color saturation (%) */
36     int             hue,		/* I - Color hue (degrees) */
37     const cups_ib_t *lut)		/* I - Lookup table for gamma/brightness */
38 {
39   int		i, y;			/* Looping vars */
40   int		bpp;			/* Bytes per pixel */
41   sgi_t		*sgip;			/* SGI image file */
42   cups_ib_t	*in,			/* Input pixels */
43 		*inptr,			/* Current input pixel */
44 		*out;			/* Output pixels */
45   unsigned short *rows[4],		/* Row pointers for image data */
46 		*red,
47 		*green,
48 		*blue,
49 		*gray,
50 		*alpha;
51 
52 
53  /*
54   * Setup the SGI file...
55   */
56 
57   sgip = sgiOpenFile(fp, SGI_READ, 0, 0, 0, 0, 0);
58 
59  /*
60   * Get the image dimensions and load the output image...
61   */
62 
63  /*
64   * Check the image dimensions; since xsize and ysize are unsigned shorts,
65   * just check if they are 0 since they can't exceed CUPS_IMAGE_MAX_WIDTH or
66   * CUPS_IMAGE_MAX_HEIGHT...
67   */
68 
69   if (sgip->xsize == 0 || sgip->ysize == 0 ||
70       sgip->zsize == 0 || sgip->zsize > 4)
71   {
72     fprintf(stderr, "DEBUG: Bad SGI image dimensions %ux%ux%u!\n",
73             sgip->xsize, sgip->ysize, sgip->zsize);
74     sgiClose(sgip);
75     return (1);
76   }
77 
78   if (sgip->zsize < 3)
79     img->colorspace = secondary;
80   else
81     img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
82 
83   img->xsize = sgip->xsize;
84   img->ysize = sgip->ysize;
85 
86   cupsImageSetMaxTiles(img, 0);
87 
88   bpp = cupsImageGetDepth(img);
89 
90   if ((in = malloc(img->xsize * sgip->zsize)) == NULL)
91   {
92     fputs("DEBUG: Unable to allocate memory!\n", stderr);
93     sgiClose(sgip);
94     return (1);
95   }
96 
97   if ((out = malloc(img->xsize * bpp)) == NULL)
98   {
99     fputs("DEBUG: Unable to allocate memory!\n", stderr);
100     sgiClose(sgip);
101     free(in);
102     return (1);
103   }
104 
105   if ((rows[0] = calloc(img->xsize * sgip->zsize,
106                         sizeof(unsigned short))) == NULL)
107   {
108     fputs("DEBUG: Unable to allocate memory!\n", stderr);
109     sgiClose(sgip);
110     free(in);
111     free(out);
112     return (1);
113   }
114 
115   for (i = 1; i < sgip->zsize; i ++)
116     rows[i] = rows[0] + i * img->xsize;
117 
118  /*
119   * Read the SGI image file...
120   */
121 
122   for (y = 0; y < img->ysize; y ++)
123   {
124     for (i = 0; i < sgip->zsize; i ++)
125       sgiGetRow(sgip, rows[i], img->ysize - 1 - y, i);
126 
127     switch (sgip->zsize)
128     {
129       case 1 :
130           if (sgip->bpp == 1)
131 	    for (i = img->xsize - 1, gray = rows[0], inptr = in;
132 		 i >= 0;
133 		 i --)
134             {
135               *inptr++ = *gray++;
136             }
137           else
138 	    for (i = img->xsize - 1, gray = rows[0], inptr = in;
139 		 i >= 0;
140 		 i --)
141             {
142               *inptr++ = (*gray++) / 256 + 128;
143             }
144           break;
145       case 2 :
146           if (sgip->bpp == 1)
147 	    for (i = img->xsize - 1, gray = rows[0], alpha = rows[1], inptr = in;
148 		 i >= 0;
149 		 i --)
150             {
151               *inptr++ = (*gray++) * (*alpha++) / 255;
152             }
153           else
154 	    for (i = img->xsize - 1, gray = rows[0], alpha = rows[1], inptr = in;
155 		 i >= 0;
156 		 i --)
157             {
158               *inptr++ = ((*gray++) / 256 + 128) * (*alpha++) / 32767;
159             }
160           break;
161       case 3 :
162           if (sgip->bpp == 1)
163 	    for (i = img->xsize - 1, red = rows[0], green = rows[1],
164 	             blue = rows[2], inptr = in;
165 		 i >= 0;
166 		 i --)
167             {
168               *inptr++ = *red++;
169               *inptr++ = *green++;
170               *inptr++ = *blue++;
171             }
172           else
173 	    for (i = img->xsize - 1, red = rows[0], green = rows[1],
174 	             blue = rows[2], inptr = in;
175 		 i >= 0;
176 		 i --)
177             {
178               *inptr++ = (*red++) / 256 + 128;
179               *inptr++ = (*green++) / 256 + 128;
180               *inptr++ = (*blue++) / 256 + 128;
181             }
182           break;
183       case 4 :
184           if (sgip->bpp == 1)
185 	    for (i = img->xsize - 1, red = rows[0], green = rows[1],
186 	             blue = rows[2], alpha = rows[3], inptr = in;
187 		 i >= 0;
188 		 i --)
189             {
190               *inptr++ = (*red++) * (*alpha) / 255;
191               *inptr++ = (*green++) * (*alpha) / 255;
192               *inptr++ = (*blue++) * (*alpha++) / 255;
193             }
194           else
195 	    for (i = img->xsize - 1, red = rows[0], green = rows[1],
196 	             blue = rows[2], alpha = rows[3], inptr = in;
197 		 i >= 0;
198 		 i --)
199             {
200               *inptr++ = ((*red++) / 256 + 128) * (*alpha) / 32767;
201               *inptr++ = ((*green++) / 256 + 128) * (*alpha) / 32767;
202               *inptr++ = ((*blue++) / 256 + 128) * (*alpha++) / 32767;
203             }
204           break;
205     }
206 
207     if (sgip->zsize < 3)
208     {
209       if (img->colorspace == CUPS_IMAGE_WHITE)
210       {
211         if (lut)
212 	  cupsImageLut(in, img->xsize, lut);
213 
214         _cupsImagePutRow(img, 0, y, img->xsize, in);
215       }
216       else
217       {
218 	switch (img->colorspace)
219 	{
220 	  default :
221 	      break;
222 
223 	  case CUPS_IMAGE_RGB :
224 	  case CUPS_IMAGE_RGB_CMYK :
225 	      cupsImageWhiteToRGB(in, out, img->xsize);
226 	      break;
227 	  case CUPS_IMAGE_BLACK :
228 	      cupsImageWhiteToBlack(in, out, img->xsize);
229 	      break;
230 	  case CUPS_IMAGE_CMY :
231 	      cupsImageWhiteToCMY(in, out, img->xsize);
232 	      break;
233 	  case CUPS_IMAGE_CMYK :
234 	      cupsImageWhiteToCMYK(in, out, img->xsize);
235 	      break;
236 	}
237 
238         if (lut)
239 	  cupsImageLut(out, img->xsize * bpp, lut);
240 
241         _cupsImagePutRow(img, 0, y, img->xsize, out);
242       }
243     }
244     else
245     {
246       if ((saturation != 100 || hue != 0) && bpp > 1)
247 	cupsImageRGBAdjust(in, img->xsize, saturation, hue);
248 
249       switch (img->colorspace)
250       {
251 	default :
252 	    break;
253 
254 	case CUPS_IMAGE_WHITE :
255 	    cupsImageRGBToWhite(in, out, img->xsize);
256 	    break;
257 	case CUPS_IMAGE_RGB :
258 	    cupsImageRGBToRGB(in, out, img->xsize);
259 	    break;
260 	case CUPS_IMAGE_BLACK :
261 	    cupsImageRGBToBlack(in, out, img->xsize);
262 	    break;
263 	case CUPS_IMAGE_CMY :
264 	    cupsImageRGBToCMY(in, out, img->xsize);
265 	    break;
266 	case CUPS_IMAGE_CMYK :
267 	    cupsImageRGBToCMYK(in, out, img->xsize);
268 	    break;
269       }
270 
271       if (lut)
272 	cupsImageLut(out, img->xsize * bpp, lut);
273 
274       _cupsImagePutRow(img, 0, y, img->xsize, out);
275     }
276   }
277 
278   free(in);
279   free(out);
280   free(rows[0]);
281 
282   sgiClose(sgip);
283 
284   return (0);
285 }
286 
287