]> git.ipfire.org Git - thirdparty/cups.git/blob - filter/image-photocd.c
Change the end copyright for Easy Software Products files to 2003.
[thirdparty/cups.git] / filter / image-photocd.c
1 /*
2 * "$Id: image-photocd.c,v 1.14 2002/12/17 18:59:26 swdev Exp $"
3 *
4 * PhotoCD routines for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1993-2003 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-3111 USA
19 *
20 * Voice: (301) 373-9603
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 * ImageReadPhotoCD() - Read a PhotoCD image file.
29 */
30
31 /*
32 * Include necessary headers...
33 */
34
35 #include "image.h"
36
37
38 /*
39 * PhotoCD support is currently limited to the 768x512 base image, which
40 * is only YCC encoded. Support for the higher resolution images will
41 * require a lot of extra code...
42 */
43
44 /*
45 * 'ImageReadPhotoCD()' - Read a PhotoCD image file.
46 */
47
48 int /* O - Read status */
49 ImageReadPhotoCD(image_t *img, /* IO - Image */
50 FILE *fp, /* I - Image file */
51 int primary, /* I - Primary choice for colorspace */
52 int secondary, /* I - Secondary choice for colorspace */
53 int saturation, /* I - Color saturation (%) */
54 int hue, /* I - Color hue (degrees) */
55 const ib_t *lut) /* I - Lookup table for gamma/brightness */
56 {
57 int x, y; /* Looping vars */
58 int xdir, /* X direction */
59 xstart; /* X starting point */
60 int bpp; /* Bytes per pixel */
61 int pass; /* Pass number */
62 int rotation; /* 0 for 768x512, 1 for 512x768 */
63 int temp, /* Adjusted luminance */
64 temp2, /* Red, green, and blue values */
65 cb, cr; /* Adjusted chroma values */
66 ib_t *in, /* Input (YCC) pixels */
67 *iy, /* Luminance */
68 *icb, /* Blue chroma */
69 *icr, /* Red chroma */
70 *rgb, /* RGB */
71 *rgbptr, /* Pointer into RGB data */
72 *out; /* Output pixels */
73
74
75 (void)secondary;
76
77 /*
78 * Get the image orientation...
79 */
80
81 fseek(fp, 72, SEEK_SET);
82 rotation = (getc(fp) & 63) != 8;
83
84 /*
85 * Seek to the start of the base image...
86 */
87
88 fseek(fp, 0x30000, SEEK_SET);
89
90 /*
91 * Allocate and initialize...
92 */
93
94 img->colorspace = (primary == IMAGE_RGB_CMYK) ? IMAGE_RGB : primary;
95 img->xppi = 128;
96 img->yppi = 128;
97
98 if (rotation)
99 {
100 img->xsize = 512;
101 img->ysize = 768;
102 }
103 else
104 {
105 img->xsize = 768;
106 img->ysize = 512;
107 }
108
109 ImageSetMaxTiles(img, 0);
110
111 bpp = ImageGetDepth(img);
112 in = malloc(768 * 3);
113 out = malloc(768 * bpp);
114
115 if (bpp > 1)
116 rgb = malloc(768 * 3);
117 else
118 rgb = NULL;
119
120 if (rotation)
121 {
122 xstart = 767 * bpp;
123 xdir = -2 * bpp;
124 }
125 else
126 {
127 xstart = 0;
128 xdir = 0;
129 }
130
131 /*
132 * Read the image file...
133 */
134
135 for (y = 0; y < 512; y += 2)
136 {
137 /*
138 * Grab the next two scanlines:
139 *
140 * YYYYYYYYYYYYYYY...
141 * YYYYYYYYYYYYYYY...
142 * CbCbCb...CrCrCr...
143 */
144
145 if (fread(in, 1, 768 * 3, fp) < (768 * 3))
146 {
147 /*
148 * Couldn't read a row of data - return an error!
149 */
150
151 free(in);
152 free(out);
153
154 return (-1);
155 }
156
157 /*
158 * Process the two scanlines...
159 */
160
161 for (pass = 0, iy = in; pass < 2; pass ++)
162 {
163 if (bpp == 1)
164 {
165 /*
166 * Just extract the luminance channel from the line and put it
167 * in the image...
168 */
169
170 if (primary == IMAGE_BLACK)
171 {
172 if (rotation)
173 {
174 for (rgbptr = out + xstart, x = 0; x < 768; x ++)
175 *rgbptr-- = 255 - *iy++;
176
177 if (lut)
178 ImageLut(out, 768, lut);
179
180 ImagePutCol(img, 511 - y - pass, 0, 768, out);
181 }
182 else
183 {
184 ImageWhiteToBlack(iy, out, 768);
185
186 if (lut)
187 ImageLut(out, 768, lut);
188
189 ImagePutRow(img, 0, y + pass, 768, out);
190 iy += 768;
191 }
192 }
193 else if (rotation)
194 {
195 for (rgbptr = out + xstart, x = 0; x < 768; x ++)
196 *rgbptr-- = 255 - *iy++;
197
198 if (lut)
199 ImageLut(out, 768, lut);
200
201 ImagePutCol(img, 511 - y - pass, 0, 768, out);
202 }
203 else
204 {
205 if (lut)
206 ImageLut(iy, 768, lut);
207
208 ImagePutRow(img, 0, y + pass, 768, iy);
209 iy += 768;
210 }
211 }
212 else
213 {
214 /*
215 * Convert YCbCr to RGB... While every pixel gets a luminance
216 * value, adjacent pixels share chroma information.
217 */
218
219 cb = cr = 0.0f;
220
221 for (x = 0, rgbptr = rgb + xstart, icb = in + 1536, icr = in + 1920;
222 x < 768;
223 x ++, iy ++, rgbptr += xdir)
224 {
225 if (!(x & 1))
226 {
227 cb = (float)(*icb - 156);
228 cr = (float)(*icr - 137);
229 }
230
231 temp = 92241 * (*iy);
232
233 temp2 = (temp + 86706 * cr) / 65536;
234 if (temp2 < 0)
235 *rgbptr++ = 0;
236 else if (temp2 > 255)
237 *rgbptr++ = 255;
238 else
239 *rgbptr++ = temp2;
240
241 temp2 = (temp - 25914 * cb - 44166 * cr) / 65536;
242 if (temp2 < 0)
243 *rgbptr++ = 0;
244 else if (temp2 > 255)
245 *rgbptr++ = 255;
246 else
247 *rgbptr++ = temp2;
248
249 temp2 = (temp + 133434 * cb) / 65536;
250 if (temp2 < 0)
251 *rgbptr++ = 0;
252 else if (temp2 > 255)
253 *rgbptr++ = 255;
254 else
255 *rgbptr++ = temp2;
256
257 if (x & 1)
258 {
259 icb ++;
260 icr ++;
261 }
262 }
263
264 /*
265 * Adjust the hue and saturation if needed...
266 */
267
268 if (saturation != 100 || hue != 0)
269 ImageRGBAdjust(rgb, 768, saturation, hue);
270
271 /*
272 * Then convert the RGB data to the appropriate colorspace and
273 * put it in the image...
274 */
275
276 if (img->colorspace == IMAGE_RGB)
277 {
278 if (lut)
279 ImageLut(rgb, 768 * 3, lut);
280
281 if (rotation)
282 ImagePutCol(img, 511 - y - pass, 0, 768, rgb);
283 else
284 ImagePutRow(img, 0, y + pass, 768, rgb);
285 }
286 else
287 {
288 switch (img->colorspace)
289 {
290 case IMAGE_CMY :
291 ImageRGBToCMY(rgb, out, 768);
292 break;
293 case IMAGE_CMYK :
294 ImageRGBToCMYK(rgb, out, 768);
295 break;
296 }
297
298 if (lut)
299 ImageLut(out, 768 * bpp, lut);
300
301 if (rotation)
302 ImagePutCol(img, 511 - y - pass, 0, 768, out);
303 else
304 ImagePutRow(img, 0, y + pass, 768, out);
305 }
306 }
307 }
308 }
309
310 /*
311 * Free memory and return...
312 */
313
314 free(in);
315 free(out);
316 if (bpp > 1)
317 free(rgb);
318
319 return (0);
320 }
321
322
323 /*
324 * End of "$Id: image-photocd.c,v 1.14 2002/12/17 18:59:26 swdev Exp $".
325 */