1 /*
2 * Alias PIX image 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 * _cupsImageReadPIX() - Read a PIX image file.
15 * read_short() - Read a 16-bit integer.
16 */
17
18 /*
19 * Include necessary headers...
20 */
21
22 #include "image-private.h"
23
24
25 /*
26 * Local functions...
27 */
28
29 static short read_short(FILE *fp);
30
31
32 /*
33 * '_cupsImageReadPIX()' - Read a PIX image file.
34 */
35
36 int /* O - Read status */
_cupsImageReadPIX(cups_image_t * img,FILE * fp,cups_icspace_t primary,cups_icspace_t secondary,int saturation,int hue,const cups_ib_t * lut)37 _cupsImageReadPIX(
38 cups_image_t *img, /* IO - cupsImage */
39 FILE *fp, /* I - cupsImage file */
40 cups_icspace_t primary, /* I - Primary choice for colorspace */
41 cups_icspace_t secondary, /* I - Secondary choice for colorspace */
42 int saturation, /* I - Color saturation (%) */
43 int hue, /* I - Color hue (degrees) */
44 const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */
45 {
46 short width, /* Width of image */
47 height, /* Height of image */
48 depth; /* Depth of image (bits) */
49 int count, /* Repetition count */
50 bpp, /* Bytes per pixel */
51 x, y; /* Looping vars */
52 cups_ib_t r, g, b; /* Red, green/gray, blue values */
53 cups_ib_t *in, /* Input pixels */
54 *out, /* Output pixels */
55 *ptr; /* Pointer into pixels */
56
57
58 /*
59 * Get the image dimensions and setup the image...
60 */
61
62 width = read_short(fp);
63 height = read_short(fp);
64 read_short(fp);
65 read_short(fp);
66 depth = read_short(fp);
67
68 /*
69 * Check the dimensions of the image. Since the short values used for the
70 * width and height cannot exceed CUPS_IMAGE_MAX_WIDTH or
71 * CUPS_IMAGE_MAX_HEIGHT, we just need to verify they are positive integers.
72 */
73
74 if (width <= 0 || height <= 0 ||
75 (depth != 8 && depth != 24))
76 {
77 fprintf(stderr, "DEBUG: Bad PIX image dimensions %dx%dx%d\n",
78 width, height, depth);
79 fclose(fp);
80 return (1);
81 }
82
83 if (depth == 8)
84 img->colorspace = secondary;
85 else
86 img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
87
88 img->xsize = width;
89 img->ysize = height;
90
91 cupsImageSetMaxTiles(img, 0);
92
93 bpp = cupsImageGetDepth(img);
94
95 if ((in = malloc(img->xsize * (depth / 8))) == NULL)
96 {
97 fputs("DEBUG: Unable to allocate memory!\n", stderr);
98 fclose(fp);
99 return (1);
100 }
101
102 if ((out = malloc(img->xsize * bpp)) == NULL)
103 {
104 fputs("DEBUG: Unable to allocate memory!\n", stderr);
105 fclose(fp);
106 free(in);
107 return (1);
108 }
109
110 /*
111 * Read the image data...
112 */
113
114 if (depth == 8)
115 {
116 for (count = 0, y = 0, g = 0; y < img->ysize; y ++)
117 {
118 if (img->colorspace == CUPS_IMAGE_WHITE)
119 ptr = out;
120 else
121 ptr = in;
122
123 for (x = img->xsize; x > 0; x --, count --)
124 {
125 if (count == 0)
126 {
127 count = getc(fp);
128 g = getc(fp);
129 }
130
131 *ptr++ = g;
132 }
133
134 if (img->colorspace != CUPS_IMAGE_WHITE)
135 switch (img->colorspace)
136 {
137 default :
138 cupsImageWhiteToRGB(in, out, img->xsize);
139 break;
140 case CUPS_IMAGE_BLACK :
141 cupsImageWhiteToBlack(in, out, img->xsize);
142 break;
143 case CUPS_IMAGE_CMY :
144 cupsImageWhiteToCMY(in, out, img->xsize);
145 break;
146 case CUPS_IMAGE_CMYK :
147 cupsImageWhiteToCMYK(in, out, img->xsize);
148 break;
149 }
150
151 if (lut)
152 cupsImageLut(out, img->xsize * bpp, lut);
153
154 _cupsImagePutRow(img, 0, y, img->xsize, out);
155 }
156 }
157 else
158 {
159 for (count = 0, y = 0, r = 0, g = 0, b = 0; y < img->ysize; y ++)
160 {
161 ptr = in;
162
163 for (x = img->xsize; x > 0; x --, count --)
164 {
165 if (count == 0)
166 {
167 count = getc(fp);
168 b = getc(fp);
169 g = getc(fp);
170 r = getc(fp);
171 }
172
173 *ptr++ = r;
174 *ptr++ = g;
175 *ptr++ = b;
176 }
177
178 if (saturation != 100 || hue != 0)
179 cupsImageRGBAdjust(in, img->xsize, saturation, hue);
180
181 switch (img->colorspace)
182 {
183 default :
184 break;
185
186 case CUPS_IMAGE_WHITE :
187 cupsImageRGBToWhite(in, out, img->xsize);
188 break;
189 case CUPS_IMAGE_RGB :
190 cupsImageRGBToWhite(in, out, img->xsize);
191 break;
192 case CUPS_IMAGE_BLACK :
193 cupsImageRGBToBlack(in, out, img->xsize);
194 break;
195 case CUPS_IMAGE_CMY :
196 cupsImageRGBToCMY(in, out, img->xsize);
197 break;
198 case CUPS_IMAGE_CMYK :
199 cupsImageRGBToCMYK(in, out, img->xsize);
200 break;
201 }
202
203 if (lut)
204 cupsImageLut(out, img->xsize * bpp, lut);
205
206 _cupsImagePutRow(img, 0, y, img->xsize, out);
207 }
208 }
209
210 fclose(fp);
211 free(in);
212 free(out);
213
214 return (0);
215 }
216
217
218 /*
219 * 'read_short()' - Read a 16-bit integer.
220 */
221
222 static short /* O - Value from file */
read_short(FILE * fp)223 read_short(FILE *fp) /* I - File to read from */
224 {
225 int ch; /* Character from file */
226
227
228 ch = getc(fp);
229 return ((ch << 8) | getc(fp));
230 }
231
232