1#ifndef lint
2static char sccsid[] = "@(#)ras2tif.c 1.2 90/03/06";
3#endif
4/*-
5 * ras2tif.c - Converts from a Sun Rasterfile to a Tagged Image File.
6 *
7 * Copyright (c) 1990 by Sun Microsystems, Inc.
8 *
9 * Author: Patrick J. Naughton
10 * naughton@wind.sun.com
11 *
12 * Permission to use, copy, modify, and distribute this software and its
13 * documentation for any purpose and without fee is hereby granted,
14 * provided that the above copyright notice appear in all copies and that
15 * both that copyright notice and this permission notice appear in
16 * supporting documentation.
17 *
18 * This file is provided AS IS with no warranties of any kind.  The author
19 * shall have no liability with respect to the infringement of copyrights,
20 * trade secrets or any patents by this file or any part thereof.  In no
21 * event will the author be liable for any lost revenue or profits or
22 * other special, indirect and consequential damages.
23 *
24 * Comments and additions should be sent to the author:
25 *
26 *                     Patrick J. Naughton
27 *                     Sun Microsystems
28 *                     2550 Garcia Ave, MS 14-40
29 *                     Mountain View, CA 94043
30 *                     (415) 336-1080
31 *
32 * Revision History:
33 * 11-Jan-89: Created.
34 * 06-Mar-90: fix bug in SCALE() macro.
35 *	      got rid of xres and yres, (they weren't working anyways).
36 *	      fixed bpsl calculation.
37 * 25-Nov-99: y2k fix (year as 1900 + tm_year) <mike@onshore.com>
38 *
39 * Description:
40 *   This program takes a Sun Rasterfile [see rasterfile(5)] as input and
41 * writes a MicroSoft/Aldus "Tagged Image File Format" image or "TIFF" file.
42 * The input file may be standard input, but the output TIFF file must be a
43 * real file since seek(2) is used.
44 */
45
46#include <stdio.h>
47#include <sys/time.h>
48#include <pixrect/pixrect_hs.h>
49#include "tiffio.h"
50
51typedef int boolean;
52#define True (1)
53#define False (0)
54#define	SCALE(x)	(((x)*((1L<<16)-1))/255)
55
56boolean     Verbose = False;
57boolean     dummyinput = False;
58char       *pname;		/* program name (used for error messages) */
59
60void
61error(s1, s2)
62    char       *s1,
63               *s2;
64{
65    fprintf(stderr, s1, pname, s2);
66    exit(1);
67}
68
69void
70usage()
71{
72    error("usage: %s -[vq] [-|rasterfile] TIFFfile\n", NULL);
73}
74
75
76main(argc, argv)
77    int         argc;
78    char       *argv[];
79{
80    char       *inf = NULL;
81    char       *outf = NULL;
82    FILE       *fp;
83    int         depth,
84                i;
85    long        row;
86    TIFF       *tif;
87    Pixrect    *pix;		/* The Sun Pixrect */
88    colormap_t  Colormap;	/* The Pixrect Colormap */
89    u_short     red[256],
90                green[256],
91                blue[256];
92    struct tm  *ct;
93    struct timeval tv;
94    long        width,
95                height;
96    long        rowsperstrip;
97    int         year;
98    short       photometric;
99    short       samplesperpixel;
100    short       bitspersample;
101    int         bpsl;
102    static char *version = "ras2tif 1.0";
103    static char *datetime = "1990:01:01 12:00:00";
104
105    gettimeofday(&tv, (struct timezone *) NULL);
106    ct = localtime(&tv.tv_sec);
107    year=1900 + ct->tm_year;
108    sprintf(datetime, "%04d:%02d:%02d %02d:%02d:%02d",
109	    year, ct->tm_mon + 1, ct->tm_mday,
110	    ct->tm_hour, ct->tm_min, ct->tm_sec);
111
112    setbuf(stderr, NULL);
113    pname = argv[0];
114
115    while (--argc) {
116	if ((++argv)[0][0] == '-') {
117	    switch (argv[0][1]) {
118	    case 'v':
119		Verbose = True;
120		break;
121	    case 'q':
122		usage();
123		break;
124	    case '\0':
125		if (inf == NULL)
126		    dummyinput = True;
127		else
128		    usage();
129		break;
130	    default:
131		fprintf(stderr, "%s: illegal option -%c.\n", pname,
132			argv[0][1]);
133		exit(1);
134	    }
135	} else if (inf == NULL && !dummyinput) {
136	    inf = argv[0];
137	} else if (outf == NULL)
138	    outf = argv[0];
139	else
140	    usage();
141    }
142
143    if (outf == NULL)
144	error("%s: can't write output file to a stream.\n", NULL);
145
146    if (dummyinput || inf == NULL) {
147	inf = "Standard Input";
148	fp = stdin;
149    } else if ((fp = fopen(inf, "r")) == NULL)
150	error("%s: %s couldn't be opened.\n", inf);
151
152    if (Verbose)
153	fprintf(stderr, "Reading rasterfile from %s...", inf);
154
155    pix = pr_load(fp, &Colormap);
156    if (pix == NULL)
157	error("%s: %s is not a raster file.\n", inf);
158
159    if (Verbose)
160	fprintf(stderr, "done.\n");
161
162    if (Verbose)
163	fprintf(stderr, "Writing %s...", outf);
164
165    tif = TIFFOpen(outf, "w");
166
167    if (tif == NULL)
168	error("%s: error opening TIFF file %s", outf);
169
170    width = pix->pr_width;
171    height = pix->pr_height;
172    depth = pix->pr_depth;
173
174    switch (depth) {
175    case 1:
176	samplesperpixel = 1;
177	bitspersample = 1;
178	photometric = PHOTOMETRIC_MINISBLACK;
179	break;
180    case 8:
181	samplesperpixel = 1;
182	bitspersample = 8;
183	photometric = PHOTOMETRIC_PALETTE;
184	break;
185    case 24:
186	samplesperpixel = 3;
187	bitspersample = 8;
188	photometric = PHOTOMETRIC_RGB;
189	break;
190    case 32:
191	samplesperpixel = 4;
192	bitspersample = 8;
193	photometric = PHOTOMETRIC_RGB;
194	break;
195    default:
196	error("%s: bogus depth: %d\n", depth);
197    }
198
199    bpsl = ((depth * width + 15) >> 3) & ~1;
200    rowsperstrip = (8 * 1024) / bpsl;
201
202    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
203    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
204    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
205    TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
206    TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
207    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric);
208    TIFFSetField(tif, TIFFTAG_DOCUMENTNAME, inf);
209    TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, "converted Sun rasterfile");
210    TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
211    TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
212    TIFFSetField(tif, TIFFTAG_STRIPBYTECOUNTS, height / rowsperstrip);
213    TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
214    TIFFSetField(tif, TIFFTAG_SOFTWARE, version);
215    TIFFSetField(tif, TIFFTAG_DATETIME, datetime);
216
217    memset(red, 0, sizeof(red));
218    memset(green, 0, sizeof(green));
219    memset(blue, 0, sizeof(blue));
220    if (depth == 8) {
221	TIFFSetField(tif, TIFFTAG_COLORMAP, red, green, blue);
222	for (i = 0; i < Colormap.length; i++) {
223	    red[i] = SCALE(Colormap.map[0][i]);
224	    green[i] = SCALE(Colormap.map[1][i]);
225	    blue[i] = SCALE(Colormap.map[2][i]);
226	}
227    }
228    if (Verbose)
229	fprintf(stderr, "%dx%dx%d image, ", width, height, depth);
230
231    for (row = 0; row < height; row++)
232	if (TIFFWriteScanline(tif,
233			      (u_char *) mprd_addr(mpr_d(pix), 0, row),
234			      row, 0) < 0) {
235	    fprintf("failed a scanline write (%d)\n", row);
236	    break;
237	}
238    TIFFFlushData(tif);
239    TIFFClose(tif);
240
241    if (Verbose)
242	fprintf(stderr, "done.\n");
243
244    pr_destroy(pix);
245
246    exit(0);
247}
248/*
249 * Local Variables:
250 * mode: c
251 * c-basic-offset: 8
252 * fill-column: 78
253 * End:
254 */
255