2 * "$Id: image-sun.c 9771 2011-05-12 05:21:56Z mike $"
4 * Sun Raster image file routines for CUPS.
6 * Copyright 2007-2011 by Apple Inc.
7 * Copyright 1993-2007 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
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/".
15 * This file is subject to the Apple OS-Developed Software exception.
19 * _cupsImageReadSunRaster() - Read a SunRaster image file.
20 * read_unsigned() - Read a 32-bit unsigned integer.
24 * Include necessary headers...
27 #include "image-private.h"
30 #define RAS_MAGIC 0x59a66a95
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 */
39 /* Sun registered ras_maptype's */
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[] */
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.
63 static unsigned read_unsigned(FILE *fp);
67 * '_cupsImageReadSunRaster()' - Read a SunRaster image file.
70 int /* 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 */
81 bpp, /* Bytes per pixel */
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 */
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.
102 fputs("DEBUG: Reading Sun Raster image...\n", stderr);
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);
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);
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)
121 fputs("DEBUG: Raster image cannot be loaded!\n", stderr);
125 if (ras_maplength > 0)
127 memset(cmap[0], 255, sizeof(cmap[0]));
128 memset(cmap[1], 0, sizeof(cmap[1]));
129 memset(cmap[2], 0, sizeof(cmap[2]));
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);
137 * Compute the width of each line and allocate memory as needed...
140 scanwidth = (img->xsize * ras_depth + 7) / 8;
144 if (ras_depth < 24 && ras_maplength == 0)
146 img->colorspace = secondary;
147 in = malloc(img->xsize + 1);
151 img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
152 in = malloc(img->xsize * 3 + 1);
157 fputs("DEBUG: Unable to allocate memory!\n", stderr);
162 bpp = cupsImageGetDepth(img);
164 if ((out = malloc(img->xsize * bpp)) == NULL)
166 fputs("DEBUG: Unable to allocate memory!\n", stderr);
172 if ((scanline = malloc(scanwidth)) == NULL)
174 fputs("DEBUG: Unable to allocate memory!\n", stderr);
184 fprintf(stderr, "DEBUG: bpp=%d, scanwidth=%d\n", bpp, scanwidth);
186 for (y = 0; y < img->ysize; y ++)
188 if ((ras_depth != 8 && ras_depth != 24) || ras_maplength > 0)
193 if (ras_type != RT_BYTE_ENCODED)
194 fread(p, scanwidth, 1, fp);
197 for (i = scanwidth; i > 0; i --, p ++)
206 run_value = getc(fp);
208 if (run_value == RAS_RLE)
210 run_count = getc(fp);
214 run_value = *p = getc(fp);
222 if (ras_depth == 1 && ras_maplength == 0)
228 for (x = img->xsize, bit = 128, scanptr = scanline, p = in;
246 else if (ras_depth == 1)
249 * 1-bit colormapped image...
252 for (x = img->xsize, bit = 128, scanptr = scanline, p = in;
278 else if (ras_depth == 8 && ras_maplength > 0)
281 * 8-bit colormapped image.
284 for (x = img->xsize, scanptr = scanline, p = in;
288 *p++ = cmap[0][*scanptr];
289 *p++ = cmap[1][*scanptr];
290 *p++ = cmap[2][*scanptr++];
293 else if (ras_depth == 24 && ras_type != RT_FORMAT_RGB)
296 * Convert BGR to RGB...
299 for (x = img->xsize, scanptr = scanline, p = in;
309 if (ras_depth <= 8 && ras_maplength == 0)
311 if (img->colorspace == CUPS_IMAGE_WHITE)
314 cupsImageLut(in, img->xsize, lut);
316 _cupsImagePutRow(img, 0, y, img->xsize, in);
320 switch (img->colorspace)
325 case CUPS_IMAGE_RGB :
326 cupsImageWhiteToRGB(in, out, img->xsize);
328 case CUPS_IMAGE_BLACK :
329 cupsImageWhiteToBlack(in, out, img->xsize);
331 case CUPS_IMAGE_CMY :
332 cupsImageWhiteToCMY(in, out, img->xsize);
334 case CUPS_IMAGE_CMYK :
335 cupsImageWhiteToCMYK(in, out, img->xsize);
340 cupsImageLut(out, img->xsize * bpp, lut);
342 _cupsImagePutRow(img, 0, y, img->xsize, out);
347 if ((saturation != 100 || hue != 0) && bpp > 1)
348 cupsImageRGBAdjust(in, img->xsize, saturation, hue);
350 switch (img->colorspace)
355 case CUPS_IMAGE_WHITE :
356 cupsImageRGBToWhite(in, out, img->xsize);
358 case CUPS_IMAGE_BLACK :
359 cupsImageRGBToBlack(in, out, img->xsize);
361 case CUPS_IMAGE_CMY :
362 cupsImageRGBToCMY(in, out, img->xsize);
364 case CUPS_IMAGE_CMYK :
365 cupsImageRGBToCMYK(in, out, img->xsize);
370 cupsImageLut(out, img->xsize * bpp, lut);
372 _cupsImagePutRow(img, 0, y, img->xsize, out);
387 * 'read_unsigned()' - Read a 32-bit unsigned integer.
390 static unsigned /* O - Integer from file */
391 read_unsigned(FILE *fp) /* I - File to read from */
393 unsigned v; /* Integer from file */
397 v = (v << 8) | getc(fp);
398 v = (v << 8) | getc(fp);
399 v = (v << 8) | getc(fp);
406 * End of "$Id: image-sun.c 9771 2011-05-12 05:21:56Z mike $".