]> git.ipfire.org Git - thirdparty/cups.git/blob - filter/image-sun.c
Load cups into easysw/current.
[thirdparty/cups.git] / filter / image-sun.c
1 /*
2 * "$Id: image-sun.c 6147 2006-12-06 20:21:46Z mike $"
3 *
4 * Sun Raster image file routines for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1993-2006 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 USA
19 *
20 * Voice: (301) 373-9600
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 * _cupsImageReadSunRaster() - Read a SunRaster image file.
29 * read_unsigned() - Read a 32-bit unsigned integer.
30 */
31
32 /*
33 * Include necessary headers...
34 */
35
36 #include "image-private.h"
37
38
39 #define RAS_MAGIC 0x59a66a95
40
41 /* Sun supported ras_type's */
42 #define RT_OLD 0 /* Raw pixrect image in 68000 byte order */
43 #define RT_STANDARD 1 /* Raw pixrect image in 68000 byte order */
44 #define RT_BYTE_ENCODED 2 /* Run-length compression of bytes */
45 #define RT_FORMAT_RGB 3 /* XRGB or RGB instead of XBGR or BGR */
46 #define RT_EXPERIMENTAL 0xffff /* Reserved for testing */
47
48 /* Sun registered ras_maptype's */
49 #define RMT_RAW 2
50 /* Sun supported ras_maptype's */
51 #define RMT_NONE 0 /* ras_maplength is expected to be 0 */
52 #define RMT_EQUAL_RGB 1 /* red[ras_maplength/3],green[],blue[] */
53
54 #define RAS_RLE 0x80
55
56 /*
57 * NOTES:
58 * Each line of the image is rounded out to a multiple of 16 bits.
59 * This corresponds to the rounding convention used by the memory pixrect
60 * package (/usr/include/pixrect/memvar.h) of the SunWindows system.
61 * The ras_encoding field (always set to 0 by Sun's supported software)
62 * was renamed to ras_length in release 2.0. As a result, rasterfiles
63 * of type 0 generated by the old software claim to have 0 length; for
64 * compatibility, code reading rasterfiles must be prepared to compute the
65 * true length from the width, height, and depth fields.
66 */
67
68 /*
69 * Local functions...
70 */
71
72 static unsigned read_unsigned(FILE *fp);
73
74
75 /*
76 * '_cupsImageReadSunRaster()' - Read a SunRaster image file.
77 */
78
79 int /* O - Read status */
80 _cupsImageReadSunRaster(
81 cups_image_t *img, /* IO - cupsImage */
82 FILE *fp, /* I - cupsImage file */
83 cups_icspace_t primary, /* I - Primary choice for colorspace */
84 cups_icspace_t secondary, /* I - Secondary choice for colorspace */
85 int saturation, /* I - Color saturation (%) */
86 int hue, /* I - Color hue (degrees) */
87 const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */
88 {
89 int i, x, y,
90 bpp, /* Bytes per pixel */
91 scanwidth,
92 run_count,
93 run_value;
94 cups_ib_t *in,
95 *out,
96 *scanline,
97 *scanptr,
98 *p,
99 bit;
100 unsigned ras_depth, /* depth (1, 8, or 24 bits) of pixel */
101 ras_type, /* type of file; see RT_* below */
102 ras_maplength; /* length (bytes) of following map */
103 unsigned char cmap[3][256]; /* colormap */
104
105
106 /*
107 * Read the header; we already know that this is a raster file (cupsImageOpen
108 * checks this) so we don't need to check the magic number again.
109 */
110
111 fputs("DEBUG: Reading Sun Raster image...\n", stderr);
112
113 read_unsigned(fp); /* Skip magic */
114 img->xsize = read_unsigned(fp);
115 img->ysize = read_unsigned(fp);
116 ras_depth = read_unsigned(fp);
117 /* ras_length */read_unsigned(fp);
118 ras_type = read_unsigned(fp);
119 /* ras_maptype*/read_unsigned(fp);
120 ras_maplength = read_unsigned(fp);
121
122 fprintf(stderr, "DEBUG: ras_width=%d, ras_height=%d, ras_depth=%d, ras_type=%d, ras_maplength=%d\n",
123 img->xsize, img->ysize, ras_depth, ras_type, ras_maplength);
124
125 if (ras_maplength > 768 ||
126 img->xsize == 0 || img->xsize > CUPS_IMAGE_MAX_WIDTH ||
127 img->ysize == 0 || img->ysize > CUPS_IMAGE_MAX_HEIGHT ||
128 ras_depth == 0 || ras_depth > 32)
129 {
130 fputs("ERROR: Raster image cannot be loaded!\n", stderr);
131 return (1);
132 }
133
134 if (ras_maplength > 0)
135 {
136 memset(cmap[0], 255, sizeof(cmap[0]));
137 memset(cmap[1], 0, sizeof(cmap[1]));
138 memset(cmap[2], 0, sizeof(cmap[2]));
139
140 fread(cmap[0], 1, ras_maplength / 3, fp);
141 fread(cmap[1], 1, ras_maplength / 3, fp);
142 fread(cmap[2], 1, ras_maplength / 3, fp);
143 }
144
145 /*
146 * Compute the width of each line and allocate memory as needed...
147 */
148
149 scanwidth = (img->xsize * ras_depth + 7) / 8;
150 if (scanwidth & 1)
151 scanwidth ++;
152
153 if (ras_depth < 24 && ras_maplength == 0)
154 {
155 img->colorspace = secondary;
156 in = malloc(img->xsize + 1);
157 }
158 else
159 {
160 img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
161 in = malloc(img->xsize * 3 + 1);
162 }
163
164 bpp = cupsImageGetDepth(img);
165 out = malloc(img->xsize * bpp);
166 scanline = malloc(scanwidth);
167 run_count = 0;
168 run_value = 0;
169
170 fprintf(stderr, "DEBUG: bpp=%d, scanwidth=%d\n", bpp, scanwidth);
171
172 for (y = 0; y < img->ysize; y ++)
173 {
174 if ((ras_depth != 8 && ras_depth != 24) || ras_maplength > 0)
175 p = scanline;
176 else
177 p = in;
178
179 if (ras_type != RT_BYTE_ENCODED)
180 fread(p, scanwidth, 1, fp);
181 else
182 {
183 for (i = scanwidth; i > 0; i --, p ++)
184 {
185 if (run_count > 0)
186 {
187 *p = run_value;
188 run_count --;
189 }
190 else
191 {
192 run_value = getc(fp);
193
194 if (run_value == RAS_RLE)
195 {
196 run_count = getc(fp);
197 if (run_count == 0)
198 *p = RAS_RLE;
199 else
200 run_value = *p = getc(fp);
201 }
202 else
203 *p = run_value;
204 }
205 }
206 }
207
208 if (ras_depth == 1 && ras_maplength == 0)
209 {
210 /*
211 * 1-bit B&W image...
212 */
213
214 for (x = img->xsize, bit = 128, scanptr = scanline, p = in;
215 x > 0;
216 x --, p ++)
217 {
218 if (*scanptr & bit)
219 *p = 255;
220 else
221 *p = 0;
222
223 if (bit > 1)
224 bit >>= 1;
225 else
226 {
227 bit = 128;
228 scanptr ++;
229 }
230 }
231 }
232 else if (ras_depth == 1)
233 {
234 /*
235 * 1-bit colormapped image...
236 */
237
238 for (x = img->xsize, bit = 128, scanptr = scanline, p = in;
239 x > 0;
240 x --)
241 {
242 if (*scanptr & bit)
243 {
244 *p++ = cmap[0][1];
245 *p++ = cmap[1][1];
246 *p++ = cmap[2][1];
247 }
248 else
249 {
250 *p++ = cmap[0][0];
251 *p++ = cmap[1][0];
252 *p++ = cmap[2][0];
253 }
254
255 if (bit > 1)
256 bit >>= 1;
257 else
258 {
259 bit = 128;
260 scanptr ++;
261 }
262 }
263 }
264 else if (ras_depth == 8 && ras_maplength > 0)
265 {
266 /*
267 * 8-bit colormapped image.
268 */
269
270 for (x = img->xsize, scanptr = scanline, p = in;
271 x > 0;
272 x --)
273 {
274 *p++ = cmap[0][*scanptr];
275 *p++ = cmap[1][*scanptr];
276 *p++ = cmap[2][*scanptr++];
277 }
278 }
279 else if (ras_depth == 24 && ras_type != RT_FORMAT_RGB)
280 {
281 /*
282 * Convert BGR to RGB...
283 */
284
285 for (x = img->xsize, scanptr = scanline, p = in;
286 x > 0;
287 x --, scanptr += 3)
288 {
289 *p++ = scanptr[2];
290 *p++ = scanptr[1];
291 *p++ = scanptr[0];
292 }
293 }
294
295 if (ras_depth <= 8 && ras_maplength == 0)
296 {
297 if (img->colorspace == CUPS_IMAGE_WHITE)
298 {
299 if (lut)
300 cupsImageLut(in, img->xsize, lut);
301
302 _cupsImagePutRow(img, 0, y, img->xsize, in);
303 }
304 else
305 {
306 switch (img->colorspace)
307 {
308 default :
309 break;
310
311 case CUPS_IMAGE_RGB :
312 cupsImageWhiteToRGB(in, out, img->xsize);
313 break;
314 case CUPS_IMAGE_BLACK :
315 cupsImageWhiteToBlack(in, out, img->xsize);
316 break;
317 case CUPS_IMAGE_CMY :
318 cupsImageWhiteToCMY(in, out, img->xsize);
319 break;
320 case CUPS_IMAGE_CMYK :
321 cupsImageWhiteToCMYK(in, out, img->xsize);
322 break;
323 }
324
325 if (lut)
326 cupsImageLut(out, img->xsize * bpp, lut);
327
328 _cupsImagePutRow(img, 0, y, img->xsize, out);
329 }
330 }
331 else
332 {
333 if ((saturation != 100 || hue != 0) && bpp > 1)
334 cupsImageRGBAdjust(in, img->xsize, saturation, hue);
335
336 switch (img->colorspace)
337 {
338 default :
339 break;
340
341 case CUPS_IMAGE_WHITE :
342 cupsImageRGBToWhite(in, out, img->xsize);
343 break;
344 case CUPS_IMAGE_BLACK :
345 cupsImageRGBToBlack(in, out, img->xsize);
346 break;
347 case CUPS_IMAGE_CMY :
348 cupsImageRGBToCMY(in, out, img->xsize);
349 break;
350 case CUPS_IMAGE_CMYK :
351 cupsImageRGBToCMYK(in, out, img->xsize);
352 break;
353 }
354
355 if (lut)
356 cupsImageLut(out, img->xsize * bpp, lut);
357
358 _cupsImagePutRow(img, 0, y, img->xsize, out);
359 }
360 }
361
362 free(scanline);
363 free(in);
364 free(out);
365
366 fclose(fp);
367
368 return (0);
369 }
370
371
372 /*
373 * 'read_unsigned()' - Read a 32-bit unsigned integer.
374 */
375
376 static unsigned /* O - Integer from file */
377 read_unsigned(FILE *fp) /* I - File to read from */
378 {
379 unsigned v; /* Integer from file */
380
381
382 v = getc(fp);
383 v = (v << 8) | getc(fp);
384 v = (v << 8) | getc(fp);
385 v = (v << 8) | getc(fp);
386
387 return (v);
388 }
389
390
391 /*
392 * End of "$Id: image-sun.c 6147 2006-12-06 20:21:46Z mike $".
393 */