]> git.ipfire.org Git - thirdparty/cups.git/blame - filter/image-sun.c
Update copyright notices, addresses, etc.
[thirdparty/cups.git] / filter / image-sun.c
CommitLineData
516ba4c9 1/*
c9d3f842 2 * "$Id$"
516ba4c9 3 *
ed19bd98 4 * Sun Raster image file routines for the Common UNIX Printing System (CUPS).
516ba4c9 5 *
c9d3f842 6 * Copyright 1993-2005 by Easy Software Products.
516ba4c9 7 *
ed19bd98 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:
516ba4c9 14 *
ed19bd98 15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
c9d3f842 18 * Hollywood, Maryland 20636 USA
516ba4c9 19 *
9639c4de 20 * Voice: (301) 373-9600
ed19bd98 21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
516ba4c9 23 *
dab1a4d8 24 * This file is subject to the Apple OS-Developed Software exception.
25 *
ed19bd98 26 * Contents:
516ba4c9 27 *
6de9968b 28 * ImageReadSunRaster() - Read a SunRaster image file.
29 * read_unsigned() - Read a 32-bit unsigned integer.
516ba4c9 30 */
31
32/*
33 * Include necessary headers...
34 */
35
36#include "image.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
72static unsigned read_unsigned(FILE *fp);
73
74
6de9968b 75/*
76 * 'ImageReadSunRaster()' - Read a SunRaster image file.
77 */
78
79int /* O - Read status */
081ab09a 80ImageReadSunRaster(image_t *img, /* IO - Image */
81 FILE *fp, /* I - Image file */
82 int primary, /* I - Primary choice for colorspace */
83 int secondary,/* I - Secondary choice for colorspace */
84 int saturation,/* I - Color saturation (%) */
85 int hue, /* I - Color hue (degrees) */
86 const ib_t *lut) /* I - Lookup table for gamma/brightness */
516ba4c9 87{
88 int i, x, y,
89 bpp, /* Bytes per pixel */
90 scanwidth,
91 run_count,
92 run_value;
93 ib_t *in,
94 *out,
95 *scanline,
96 *scanptr,
97 *p,
98 bit;
99 unsigned ras_depth, /* depth (1, 8, or 24 bits) of pixel */
516ba4c9 100 ras_type, /* type of file; see RT_* below */
516ba4c9 101 ras_maplength; /* length (bytes) of following map */
4aa97df2 102 unsigned char cmap[3][256]; /* colormap */
516ba4c9 103
104
105 /*
106 * Read the header; we already know that this is a raster file (ImageOpen
107 * checks this) so we don't need to check the magic number again.
108 */
109
f33d1239 110 fputs("DEBUG: Reading Sun Raster image...\n", stderr);
111
516ba4c9 112 read_unsigned(fp); /* Skip magic */
113 img->xsize = read_unsigned(fp);
114 img->ysize = read_unsigned(fp);
115 ras_depth = read_unsigned(fp);
ed19bd98 116 /* ras_length */read_unsigned(fp);
516ba4c9 117 ras_type = read_unsigned(fp);
ed19bd98 118 /* ras_maptype*/read_unsigned(fp);
516ba4c9 119 ras_maplength = read_unsigned(fp);
120
f33d1239 121 fprintf(stderr, "DEBUG: ras_width=%d, ras_height=%d, ras_depth=%d, ras_type=%d, ras_maplength=%d\n",
122 img->xsize, img->ysize, ras_depth, ras_type, ras_maplength);
123
099f4d77 124 if (ras_maplength > 768 ||
125 img->xsize == 0 || img->xsize > IMAGE_MAX_WIDTH ||
126 img->ysize == 0 || img->ysize > IMAGE_MAX_HEIGHT ||
127 ras_depth == 0 || ras_depth > 32)
901b295d 128 {
099f4d77 129 fputs("ERROR: Raster image cannot be loaded!\n", stderr);
901b295d 130 return (1);
131 }
132
516ba4c9 133 if (ras_maplength > 0)
4aa97df2 134 {
f33d1239 135 memset(cmap[0], 255, sizeof(cmap[0]));
136 memset(cmap[1], 0, sizeof(cmap[1]));
137 memset(cmap[2], 0, sizeof(cmap[2]));
138
4aa97df2 139 fread(cmap[0], 1, ras_maplength / 3, fp);
140 fread(cmap[1], 1, ras_maplength / 3, fp);
141 fread(cmap[2], 1, ras_maplength / 3, fp);
ed19bd98 142 }
516ba4c9 143
144 /*
145 * Compute the width of each line and allocate memory as needed...
146 */
147
148 scanwidth = (img->xsize * ras_depth + 7) / 8;
149 if (scanwidth & 1)
150 scanwidth ++;
151
4aa97df2 152 if (ras_depth < 24 && ras_maplength == 0)
516ba4c9 153 {
154 img->colorspace = secondary;
155 in = malloc(img->xsize + 1);
156 }
157 else
158 {
350807be 159 img->colorspace = (primary == IMAGE_RGB_CMYK) ? IMAGE_RGB : primary;
516ba4c9 160 in = malloc(img->xsize * 3 + 1);
ed19bd98 161 }
516ba4c9 162
163 bpp = ImageGetDepth(img);
164 out = malloc(img->xsize * bpp);
165 scanline = malloc(scanwidth);
166 run_count = 0;
d21a7597 167 run_value = 0;
516ba4c9 168
f33d1239 169 fprintf(stderr, "DEBUG: bpp=%d, scanwidth=%d\n", bpp, scanwidth);
170
516ba4c9 171 for (y = 0; y < img->ysize; y ++)
172 {
4aa97df2 173 if (ras_depth != 8 || ras_maplength > 0)
516ba4c9 174 p = scanline;
175 else
176 p = in;
177
178 if (ras_type != RT_BYTE_ENCODED)
179 fread(p, scanwidth, 1, fp);
180 else
181 {
182 for (i = scanwidth; i > 0; i --, p ++)
183 {
184 if (run_count > 0)
185 {
186 *p = run_value;
187 run_count --;
188 }
189 else
190 {
191 run_value = getc(fp);
192
193 if (run_value == RAS_RLE)
194 {
195 run_count = getc(fp);
196 if (run_count == 0)
197 *p = RAS_RLE;
198 else
199 run_value = *p = getc(fp);
200 }
201 else
202 *p = run_value;
ed19bd98 203 }
204 }
205 }
516ba4c9 206
4aa97df2 207 if (ras_depth == 1 && ras_maplength == 0)
516ba4c9 208 {
4aa97df2 209 /*
210 * 1-bit B&W image...
211 */
212
516ba4c9 213 for (x = img->xsize, bit = 128, scanptr = scanline, p = in;
214 x > 0;
215 x --, p ++)
216 {
217 if (*scanptr & bit)
218 *p = 255;
219 else
220 *p = 0;
221
222 if (bit > 1)
223 {
224 bit = 128;
225 scanptr ++;
226 }
227 else
228 bit >>= 1;
ed19bd98 229 }
516ba4c9 230 }
4aa97df2 231 else if (ras_depth == 1)
232 {
233 /*
234 * 1-bit colormapped image...
235 */
236
237 for (x = img->xsize, bit = 128, scanptr = scanline, p = in;
238 x > 0;
239 x --)
240 {
241 if (*scanptr & bit)
242 {
243 *p++ = cmap[0][1];
244 *p++ = cmap[1][1];
245 *p++ = cmap[2][1];
246 }
247 else
248 {
249 *p++ = cmap[0][0];
250 *p++ = cmap[1][0];
251 *p++ = cmap[2][0];
ed19bd98 252 }
4aa97df2 253
254 if (bit > 1)
255 {
256 bit = 128;
257 scanptr ++;
258 }
259 else
260 bit >>= 1;
ed19bd98 261 }
4aa97df2 262 }
263 else if (ras_depth == 8 && ras_maplength > 0)
264 {
265 /*
266 * 8-bit colormapped image.
267 */
268
269 for (x = img->xsize, scanptr = scanline, p = in;
270 x > 0;
271 x --)
272 {
273 *p++ = cmap[0][*scanptr];
274 *p++ = cmap[1][*scanptr];
275 *p++ = cmap[2][*scanptr++];
ed19bd98 276 }
4aa97df2 277 }
516ba4c9 278 else if (ras_depth == 24 && ras_type != RT_FORMAT_RGB)
279 {
280 /*
281 * Convert BGR to RGB...
282 */
283
284 for (x = img->xsize, scanptr = scanline, p = in;
285 x > 0;
4aa97df2 286 x --, scanptr += 3)
516ba4c9 287 {
4aa97df2 288 *p++ = scanptr[2];
289 *p++ = scanptr[1];
290 *p++ = scanptr[0];
ed19bd98 291 }
292 }
516ba4c9 293
f33d1239 294 if (ras_depth <= 8 && ras_maplength == 0)
516ba4c9 295 {
296 if (img->colorspace == IMAGE_WHITE)
6de9968b 297 {
298 if (lut)
299 ImageLut(in, img->xsize, lut);
300
516ba4c9 301 ImagePutRow(img, 0, y, img->xsize, in);
6de9968b 302 }
516ba4c9 303 else
304 {
305 switch (img->colorspace)
306 {
307 case IMAGE_RGB :
308 ImageWhiteToRGB(in, out, img->xsize);
309 break;
310 case IMAGE_BLACK :
311 ImageWhiteToBlack(in, out, img->xsize);
312 break;
313 case IMAGE_CMY :
314 ImageWhiteToCMY(in, out, img->xsize);
315 break;
316 case IMAGE_CMYK :
317 ImageWhiteToCMYK(in, out, img->xsize);
318 break;
ed19bd98 319 }
516ba4c9 320
6de9968b 321 if (lut)
322 ImageLut(out, img->xsize * bpp, lut);
323
516ba4c9 324 ImagePutRow(img, 0, y, img->xsize, out);
ed19bd98 325 }
516ba4c9 326 }
327 else
328 {
329 if (img->colorspace == IMAGE_RGB)
330 {
331 if (saturation != 100 || hue != 0)
332 ImageRGBAdjust(in, img->xsize, saturation, hue);
333
6de9968b 334 if (lut)
335 ImageLut(in, img->xsize * 3, lut);
336
516ba4c9 337 ImagePutRow(img, 0, y, img->xsize, in);
338 }
339 else
340 {
341 if ((saturation != 100 || hue != 0) && bpp > 1)
342 ImageRGBAdjust(in, img->xsize, saturation, hue);
343
344 switch (img->colorspace)
345 {
346 case IMAGE_WHITE :
347 ImageRGBToWhite(in, out, img->xsize);
348 break;
349 case IMAGE_BLACK :
350 ImageRGBToBlack(in, out, img->xsize);
351 break;
352 case IMAGE_CMY :
353 ImageRGBToCMY(in, out, img->xsize);
354 break;
355 case IMAGE_CMYK :
356 ImageRGBToCMYK(in, out, img->xsize);
357 break;
ed19bd98 358 }
516ba4c9 359
6de9968b 360 if (lut)
361 ImageLut(out, img->xsize * bpp, lut);
362
516ba4c9 363 ImagePutRow(img, 0, y, img->xsize, out);
ed19bd98 364 }
365 }
366 }
516ba4c9 367
368 free(scanline);
369 free(in);
370 free(out);
371
372 fclose(fp);
373
374 return (0);
375}
376
377
6de9968b 378/*
379 * 'read_unsigned()' - Read a 32-bit unsigned integer.
380 */
381
382static unsigned /* O - Integer from file */
383read_unsigned(FILE *fp) /* I - File to read from */
516ba4c9 384{
6de9968b 385 unsigned v; /* Integer from file */
516ba4c9 386
387
388 v = getc(fp);
389 v = (v << 8) | getc(fp);
390 v = (v << 8) | getc(fp);
391 v = (v << 8) | getc(fp);
392
393 return (v);
394}
395
396
397/*
c9d3f842 398 * End of "$Id$".
516ba4c9 399 */