]> git.ipfire.org Git - thirdparty/cups.git/blob - filter/image-photocd.c
Import CUPS 1.4svn-r7226.
[thirdparty/cups.git] / filter / image-photocd.c
1 /*
2 * "$Id: image-photocd.c 6649 2007-07-11 21:46:42Z mike $"
3 *
4 * PhotoCD routines for the Common UNIX Printing System (CUPS).
5 *
6 * PhotoCD support is currently limited to the 768x512 base image, which
7 * is only YCC encoded. Support for the higher resolution images will
8 * require a lot of extra code...
9 *
10 * Copyright 2007-2008 by Apple Inc.
11 * Copyright 1993-2006 by Easy Software Products.
12 *
13 * These coded instructions, statements, and computer programs are the
14 * property of Apple Inc. and are protected by Federal copyright
15 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
16 * which should have been included with this file. If this file is
17 * file is missing or damaged, see the license at "http://www.cups.org/".
18 *
19 * This file is subject to the Apple OS-Developed Software exception.
20 *
21 * Contents:
22 *
23 * _cupsImageReadPhotoCD() - Read a PhotoCD image file.
24 */
25
26 /*
27 * Include necessary headers...
28 */
29
30 #include "image-private.h"
31
32
33 /*
34 * '_cupsImageReadPhotoCD()' - Read a PhotoCD image file.
35 */
36
37 int /* O - Read status */
38 _cupsImageReadPhotoCD(
39 cups_image_t *img, /* IO - cupsImage */
40 FILE *fp, /* I - cupsImage file */
41 cups_icspace_t primary, /* I - Primary choice for colorspace */
42 cups_icspace_t secondary, /* I - Secondary choice for colorspace */
43 int saturation, /* I - Color saturation (%) */
44 int hue, /* I - Color hue (degrees) */
45 const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */
46 {
47 int x, y; /* Looping vars */
48 int xdir, /* X direction */
49 xstart; /* X starting point */
50 int bpp; /* Bytes per pixel */
51 int pass; /* Pass number */
52 int rotation; /* 0 for 768x512, 1 for 512x768 */
53 int temp, /* Adjusted luminance */
54 temp2, /* Red, green, and blue values */
55 cb, cr; /* Adjusted chroma values */
56 cups_ib_t *in, /* Input (YCC) pixels */
57 *iy, /* Luminance */
58 *icb, /* Blue chroma */
59 *icr, /* Red chroma */
60 *rgb, /* RGB */
61 *rgbptr, /* Pointer into RGB data */
62 *out; /* Output pixels */
63
64
65 (void)secondary;
66
67 /*
68 * Get the image orientation...
69 */
70
71 fseek(fp, 72, SEEK_SET);
72 rotation = (getc(fp) & 63) != 8;
73
74 /*
75 * Seek to the start of the base image...
76 */
77
78 fseek(fp, 0x30000, SEEK_SET);
79
80 /*
81 * Allocate and initialize...
82 */
83
84 img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
85 img->xppi = 128;
86 img->yppi = 128;
87
88 if (rotation)
89 {
90 img->xsize = 512;
91 img->ysize = 768;
92 }
93 else
94 {
95 img->xsize = 768;
96 img->ysize = 512;
97 }
98
99 cupsImageSetMaxTiles(img, 0);
100
101 bpp = cupsImageGetDepth(img);
102
103 if ((in = malloc(768 * 3)) == NULL)
104 {
105 fputs("DEBUG: Unable to allocate memory!\n", stderr);
106 fclose(fp);
107 return (1);
108 }
109
110 if ((out = malloc(768 * bpp)) == NULL)
111 {
112 fputs("DEBUG: Unable to allocate memory!\n", stderr);
113 fclose(fp);
114 free(in);
115 return (1);
116 }
117
118 if (bpp > 1)
119 {
120 if ((rgb = malloc(768 * 3)) == NULL)
121 {
122 fputs("DEBUG: Unable to allocate memory!\n", stderr);
123 fclose(fp);
124 free(in);
125 free(out);
126 return (1);
127 }
128 }
129 else
130 rgb = NULL;
131
132 if (rotation)
133 {
134 xstart = 767 * bpp;
135 xdir = -2 * bpp;
136 }
137 else
138 {
139 xstart = 0;
140 xdir = 0;
141 }
142
143 /*
144 * Read the image file...
145 */
146
147 for (y = 0; y < 512; y += 2)
148 {
149 /*
150 * Grab the next two scanlines:
151 *
152 * YYYYYYYYYYYYYYY...
153 * YYYYYYYYYYYYYYY...
154 * CbCbCb...CrCrCr...
155 */
156
157 if (fread(in, 1, 768 * 3, fp) < (768 * 3))
158 {
159 /*
160 * Couldn't read a row of data - return an error!
161 */
162
163 free(in);
164 free(out);
165
166 if (bpp > 1)
167 free(rgb);
168
169 return (-1);
170 }
171
172 /*
173 * Process the two scanlines...
174 */
175
176 for (pass = 0, iy = in; pass < 2; pass ++)
177 {
178 if (bpp == 1)
179 {
180 /*
181 * Just extract the luminance channel from the line and put it
182 * in the image...
183 */
184
185 if (primary == CUPS_IMAGE_BLACK)
186 {
187 if (rotation)
188 {
189 for (rgbptr = out + xstart, x = 0; x < 768; x ++)
190 *rgbptr-- = 255 - *iy++;
191
192 if (lut)
193 cupsImageLut(out, 768, lut);
194
195 _cupsImagePutCol(img, 511 - y - pass, 0, 768, out);
196 }
197 else
198 {
199 cupsImageWhiteToBlack(iy, out, 768);
200
201 if (lut)
202 cupsImageLut(out, 768, lut);
203
204 _cupsImagePutRow(img, 0, y + pass, 768, out);
205 iy += 768;
206 }
207 }
208 else if (rotation)
209 {
210 for (rgbptr = out + xstart, x = 0; x < 768; x ++)
211 *rgbptr-- = 255 - *iy++;
212
213 if (lut)
214 cupsImageLut(out, 768, lut);
215
216 _cupsImagePutCol(img, 511 - y - pass, 0, 768, out);
217 }
218 else
219 {
220 if (lut)
221 cupsImageLut(iy, 768, lut);
222
223 _cupsImagePutRow(img, 0, y + pass, 768, iy);
224 iy += 768;
225 }
226 }
227 else
228 {
229 /*
230 * Convert YCbCr to RGB... While every pixel gets a luminance
231 * value, adjacent pixels share chroma information.
232 */
233
234 cb = cr = 0.0f;
235
236 for (x = 0, rgbptr = rgb + xstart, icb = in + 1536, icr = in + 1920;
237 x < 768;
238 x ++, iy ++, rgbptr += xdir)
239 {
240 if (!(x & 1))
241 {
242 cb = (float)(*icb - 156);
243 cr = (float)(*icr - 137);
244 }
245
246 temp = 92241 * (*iy);
247
248 temp2 = (temp + 86706 * cr) / 65536;
249 if (temp2 < 0)
250 *rgbptr++ = 0;
251 else if (temp2 > 255)
252 *rgbptr++ = 255;
253 else
254 *rgbptr++ = temp2;
255
256 temp2 = (temp - 25914 * cb - 44166 * cr) / 65536;
257 if (temp2 < 0)
258 *rgbptr++ = 0;
259 else if (temp2 > 255)
260 *rgbptr++ = 255;
261 else
262 *rgbptr++ = temp2;
263
264 temp2 = (temp + 133434 * cb) / 65536;
265 if (temp2 < 0)
266 *rgbptr++ = 0;
267 else if (temp2 > 255)
268 *rgbptr++ = 255;
269 else
270 *rgbptr++ = temp2;
271
272 if (x & 1)
273 {
274 icb ++;
275 icr ++;
276 }
277 }
278
279 /*
280 * Adjust the hue and saturation if needed...
281 */
282
283 if (saturation != 100 || hue != 0)
284 cupsImageRGBAdjust(rgb, 768, saturation, hue);
285
286 /*
287 * Then convert the RGB data to the appropriate colorspace and
288 * put it in the image...
289 */
290
291 switch (img->colorspace)
292 {
293 default :
294 break;
295
296 case CUPS_IMAGE_RGB :
297 cupsImageRGBToRGB(rgb, out, 768);
298 break;
299 case CUPS_IMAGE_CMY :
300 cupsImageRGBToCMY(rgb, out, 768);
301 break;
302 case CUPS_IMAGE_CMYK :
303 cupsImageRGBToCMYK(rgb, out, 768);
304 break;
305 }
306
307 if (lut)
308 cupsImageLut(out, 768 * bpp, lut);
309
310 if (rotation)
311 _cupsImagePutCol(img, 511 - y - pass, 0, 768, out);
312 else
313 _cupsImagePutRow(img, 0, y + pass, 768, out);
314 }
315 }
316 }
317
318 /*
319 * Free memory and return...
320 */
321
322 free(in);
323 free(out);
324 if (bpp > 1)
325 free(rgb);
326
327 return (0);
328 }
329
330
331 /*
332 * End of "$Id: image-photocd.c 6649 2007-07-11 21:46:42Z mike $".
333 */