1 #ifndef lint
2 static 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 
51 typedef int boolean;
52 #define True (1)
53 #define False (0)
54 #define	SCALE(x)	(((x)*((1L<<16)-1))/255)
55 
56 boolean     Verbose = False;
57 boolean     dummyinput = False;
58 char       *pname;		/* program name (used for error messages) */
59 
60 void
error(s1,s2)61 error(s1, s2)
62     char       *s1,
63                *s2;
64 {
65     fprintf(stderr, s1, pname, s2);
66     exit(1);
67 }
68 
69 void
usage()70 usage()
71 {
72     error("usage: %s -[vq] [-|rasterfile] TIFFfile\n", NULL);
73 }
74 
75 
main(argc,argv)76 main(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