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