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