]>
Commit | Line | Data |
---|---|---|
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 | ||
72 | static unsigned read_unsigned(FILE *fp); | |
73 | ||
74 | ||
6de9968b | 75 | /* |
76 | * 'ImageReadSunRaster()' - Read a SunRaster image file. | |
77 | */ | |
78 | ||
79 | int /* O - Read status */ | |
081ab09a | 80 | ImageReadSunRaster(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 | ||
382 | static unsigned /* O - Integer from file */ | |
383 | read_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 | */ |