|
roentgen |
b75cab |
#ifndef lint
|
|
roentgen |
b75cab |
static char sccsid[] = "@(#)ras2tif.c 1.2 90/03/06";
|
|
roentgen |
b75cab |
#endif
|
|
roentgen |
b75cab |
/*-
|
|
roentgen |
b75cab |
* ras2tif.c - Converts from a Sun Rasterfile to a Tagged Image File.
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* Author: Patrick J. Naughton
|
|
roentgen |
b75cab |
* naughton@wind.sun.com
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* Permission to use, copy, modify, and distribute this software and its
|
|
roentgen |
b75cab |
* documentation for any purpose and without fee is hereby granted,
|
|
roentgen |
b75cab |
* provided that the above copyright notice appear in all copies and that
|
|
roentgen |
b75cab |
* both that copyright notice and this permission notice appear in
|
|
roentgen |
b75cab |
* supporting documentation.
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* This file is provided AS IS with no warranties of any kind. The author
|
|
roentgen |
b75cab |
* shall have no liability with respect to the infringement of copyrights,
|
|
roentgen |
b75cab |
* trade secrets or any patents by this file or any part thereof. In no
|
|
roentgen |
b75cab |
* event will the author be liable for any lost revenue or profits or
|
|
roentgen |
b75cab |
* other special, indirect and consequential damages.
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* Comments and additions should be sent to the author:
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* Patrick J. Naughton
|
|
roentgen |
b75cab |
* Sun Microsystems
|
|
roentgen |
b75cab |
* 2550 Garcia Ave, MS 14-40
|
|
roentgen |
b75cab |
* Mountain View, CA 94043
|
|
roentgen |
b75cab |
* (415) 336-1080
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* Revision History:
|
|
roentgen |
b75cab |
* 11-Jan-89: Created.
|
|
roentgen |
b75cab |
* 06-Mar-90: fix bug in SCALE() macro.
|
|
roentgen |
b75cab |
* got rid of xres and yres, (they weren't working anyways).
|
|
roentgen |
b75cab |
* fixed bpsl calculation.
|
|
roentgen |
b75cab |
* 25-Nov-99: y2k fix (year as 1900 + tm_year) <mike@onshore.com></mike@onshore.com>
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* Description:
|
|
roentgen |
b75cab |
* This program takes a Sun Rasterfile [see rasterfile(5)] as input and
|
|
roentgen |
b75cab |
* writes a MicroSoft/Aldus "Tagged Image File Format" image or "TIFF" file.
|
|
roentgen |
b75cab |
* The input file may be standard input, but the output TIFF file must be a
|
|
roentgen |
b75cab |
* real file since seek(2) is used.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#include <stdio.h></stdio.h>
|
|
roentgen |
b75cab |
#include <sys time.h=""></sys>
|
|
roentgen |
b75cab |
#include <pixrect pixrect_hs.h=""></pixrect>
|
|
roentgen |
b75cab |
#include "tiffio.h"
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
typedef int boolean;
|
|
roentgen |
b75cab |
#define True (1)
|
|
roentgen |
b75cab |
#define False (0)
|
|
roentgen |
b75cab |
#define SCALE(x) (((x)*((1L<<16)-1))/255)
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
boolean Verbose = False;
|
|
roentgen |
b75cab |
boolean dummyinput = False;
|
|
roentgen |
b75cab |
char *pname; /* program name (used for error messages) */
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
void
|
|
roentgen |
b75cab |
error(s1, s2)
|
|
roentgen |
b75cab |
char *s1,
|
|
roentgen |
b75cab |
*s2;
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
fprintf(stderr, s1, pname, s2);
|
|
roentgen |
b75cab |
exit(1);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
void
|
|
roentgen |
b75cab |
usage()
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
error("usage: %s -[vq] [-|rasterfile] TIFFfile\n", NULL);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
main(argc, argv)
|
|
roentgen |
b75cab |
int argc;
|
|
roentgen |
b75cab |
char *argv[];
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
char *inf = NULL;
|
|
roentgen |
b75cab |
char *outf = NULL;
|
|
roentgen |
b75cab |
FILE *fp;
|
|
roentgen |
b75cab |
int depth,
|
|
roentgen |
b75cab |
i;
|
|
roentgen |
b75cab |
long row;
|
|
roentgen |
b75cab |
TIFF *tif;
|
|
roentgen |
b75cab |
Pixrect *pix; /* The Sun Pixrect */
|
|
roentgen |
b75cab |
colormap_t Colormap; /* The Pixrect Colormap */
|
|
roentgen |
b75cab |
u_short red[256],
|
|
roentgen |
b75cab |
green[256],
|
|
roentgen |
b75cab |
blue[256];
|
|
roentgen |
b75cab |
struct tm *ct;
|
|
roentgen |
b75cab |
struct timeval tv;
|
|
roentgen |
b75cab |
long width,
|
|
roentgen |
b75cab |
height;
|
|
roentgen |
b75cab |
long rowsperstrip;
|
|
roentgen |
b75cab |
int year;
|
|
roentgen |
b75cab |
short photometric;
|
|
roentgen |
b75cab |
short samplesperpixel;
|
|
roentgen |
b75cab |
short bitspersample;
|
|
roentgen |
b75cab |
int bpsl;
|
|
roentgen |
b75cab |
static char *version = "ras2tif 1.0";
|
|
roentgen |
b75cab |
static char *datetime = "1990:01:01 12:00:00";
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
gettimeofday(&tv, (struct timezone *) NULL);
|
|
roentgen |
b75cab |
ct = localtime(&tv.tv_sec);
|
|
roentgen |
b75cab |
year=1900 + ct->tm_year;
|
|
roentgen |
b75cab |
sprintf(datetime, "%04d:%02d:%02d %02d:%02d:%02d",
|
|
roentgen |
b75cab |
year, ct->tm_mon + 1, ct->tm_mday,
|
|
roentgen |
b75cab |
ct->tm_hour, ct->tm_min, ct->tm_sec);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
setbuf(stderr, NULL);
|
|
roentgen |
b75cab |
pname = argv[0];
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
while (--argc) {
|
|
roentgen |
b75cab |
if ((++argv)[0][0] == '-') {
|
|
roentgen |
b75cab |
switch (argv[0][1]) {
|
|
roentgen |
b75cab |
case 'v':
|
|
roentgen |
b75cab |
Verbose = True;
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 'q':
|
|
roentgen |
b75cab |
usage();
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case '\0':
|
|
roentgen |
b75cab |
if (inf == NULL)
|
|
roentgen |
b75cab |
dummyinput = True;
|
|
roentgen |
b75cab |
else
|
|
roentgen |
b75cab |
usage();
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
default:
|
|
roentgen |
b75cab |
fprintf(stderr, "%s: illegal option -%c.\n", pname,
|
|
roentgen |
b75cab |
argv[0][1]);
|
|
roentgen |
b75cab |
exit(1);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
} else if (inf == NULL && !dummyinput) {
|
|
roentgen |
b75cab |
inf = argv[0];
|
|
roentgen |
b75cab |
} else if (outf == NULL)
|
|
roentgen |
b75cab |
outf = argv[0];
|
|
roentgen |
b75cab |
else
|
|
roentgen |
b75cab |
usage();
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
if (outf == NULL)
|
|
roentgen |
b75cab |
error("%s: can't write output file to a stream.\n", NULL);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
if (dummyinput || inf == NULL) {
|
|
roentgen |
b75cab |
inf = "Standard Input";
|
|
roentgen |
b75cab |
fp = stdin;
|
|
roentgen |
b75cab |
} else if ((fp = fopen(inf, "r")) == NULL)
|
|
roentgen |
b75cab |
error("%s: %s couldn't be opened.\n", inf);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
if (Verbose)
|
|
roentgen |
b75cab |
fprintf(stderr, "Reading rasterfile from %s...", inf);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
pix = pr_load(fp, &Colormap);
|
|
roentgen |
b75cab |
if (pix == NULL)
|
|
roentgen |
b75cab |
error("%s: %s is not a raster file.\n", inf);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
if (Verbose)
|
|
roentgen |
b75cab |
fprintf(stderr, "done.\n");
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
if (Verbose)
|
|
roentgen |
b75cab |
fprintf(stderr, "Writing %s...", outf);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
tif = TIFFOpen(outf, "w");
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
if (tif == NULL)
|
|
roentgen |
b75cab |
error("%s: error opening TIFF file %s", outf);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
width = pix->pr_width;
|
|
roentgen |
b75cab |
height = pix->pr_height;
|
|
roentgen |
b75cab |
depth = pix->pr_depth;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
switch (depth) {
|
|
roentgen |
b75cab |
case 1:
|
|
roentgen |
b75cab |
samplesperpixel = 1;
|
|
roentgen |
b75cab |
bitspersample = 1;
|
|
roentgen |
b75cab |
photometric = PHOTOMETRIC_MINISBLACK;
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 8:
|
|
roentgen |
b75cab |
samplesperpixel = 1;
|
|
roentgen |
b75cab |
bitspersample = 8;
|
|
roentgen |
b75cab |
photometric = PHOTOMETRIC_PALETTE;
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 24:
|
|
roentgen |
b75cab |
samplesperpixel = 3;
|
|
roentgen |
b75cab |
bitspersample = 8;
|
|
roentgen |
b75cab |
photometric = PHOTOMETRIC_RGB;
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case 32:
|
|
roentgen |
b75cab |
samplesperpixel = 4;
|
|
roentgen |
b75cab |
bitspersample = 8;
|
|
roentgen |
b75cab |
photometric = PHOTOMETRIC_RGB;
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
default:
|
|
roentgen |
b75cab |
error("%s: bogus depth: %d\n", depth);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
bpsl = ((depth * width + 15) >> 3) & ~1;
|
|
roentgen |
b75cab |
rowsperstrip = (8 * 1024) / bpsl;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
|
|
roentgen |
b75cab |
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
|
|
roentgen |
b75cab |
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
|
|
roentgen |
b75cab |
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
|
|
roentgen |
b75cab |
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
|
|
roentgen |
b75cab |
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric);
|
|
roentgen |
b75cab |
TIFFSetField(tif, TIFFTAG_DOCUMENTNAME, inf);
|
|
roentgen |
b75cab |
TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, "converted Sun rasterfile");
|
|
roentgen |
b75cab |
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
|
|
roentgen |
b75cab |
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
|
|
roentgen |
b75cab |
TIFFSetField(tif, TIFFTAG_STRIPBYTECOUNTS, height / rowsperstrip);
|
|
roentgen |
b75cab |
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
|
|
roentgen |
b75cab |
TIFFSetField(tif, TIFFTAG_SOFTWARE, version);
|
|
roentgen |
b75cab |
TIFFSetField(tif, TIFFTAG_DATETIME, datetime);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
memset(red, 0, sizeof(red));
|
|
roentgen |
b75cab |
memset(green, 0, sizeof(green));
|
|
roentgen |
b75cab |
memset(blue, 0, sizeof(blue));
|
|
roentgen |
b75cab |
if (depth == 8) {
|
|
roentgen |
b75cab |
TIFFSetField(tif, TIFFTAG_COLORMAP, red, green, blue);
|
|
roentgen |
b75cab |
for (i = 0; i < Colormap.length; i++) {
|
|
roentgen |
b75cab |
red[i] = SCALE(Colormap.map[0][i]);
|
|
roentgen |
b75cab |
green[i] = SCALE(Colormap.map[1][i]);
|
|
roentgen |
b75cab |
blue[i] = SCALE(Colormap.map[2][i]);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
if (Verbose)
|
|
roentgen |
b75cab |
fprintf(stderr, "%dx%dx%d image, ", width, height, depth);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
for (row = 0; row < height; row++)
|
|
roentgen |
b75cab |
if (TIFFWriteScanline(tif,
|
|
roentgen |
b75cab |
(u_char *) mprd_addr(mpr_d(pix), 0, row),
|
|
roentgen |
b75cab |
row, 0) < 0) {
|
|
roentgen |
b75cab |
fprintf("failed a scanline write (%d)\n", row);
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
TIFFFlushData(tif);
|
|
roentgen |
b75cab |
TIFFClose(tif);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
if (Verbose)
|
|
roentgen |
b75cab |
fprintf(stderr, "done.\n");
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
pr_destroy(pix);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
exit(0);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Local Variables:
|
|
roentgen |
b75cab |
* mode: c
|
|
roentgen |
b75cab |
* c-basic-offset: 8
|
|
roentgen |
b75cab |
* fill-column: 78
|
|
roentgen |
b75cab |
* End:
|
|
roentgen |
b75cab |
*/
|