Blame contrib/ras/tif2ras.c

Packit 7838c8
#ifndef lint
Packit 7838c8
static char id[] = "$Id: tif2ras.c,v 1.3 2010-06-08 18:55:15 bfriesen Exp $"; 
Packit 7838c8
#endif
Packit 7838c8
/*-
Packit 7838c8
 * tif2ras.c - Converts from a Tagged Image File Format image to a Sun Raster.
Packit 7838c8
 *
Packit 7838c8
 * Copyright (c) 1990 by Sun Microsystems, Inc.
Packit 7838c8
 *
Packit 7838c8
 * Author: Patrick J. Naughton
Packit 7838c8
 * naughton@wind.sun.com
Packit 7838c8
 *
Packit 7838c8
 * Permission to use, copy, modify, and distribute this software and its
Packit 7838c8
 * documentation for any purpose and without fee is hereby granted,
Packit 7838c8
 * provided that the above copyright notice appear in all copies and that
Packit 7838c8
 * both that copyright notice and this permission notice appear in
Packit 7838c8
 * supporting documentation.
Packit 7838c8
 *
Packit 7838c8
 * This file is provided AS IS with no warranties of any kind.  The author
Packit 7838c8
 * shall have no liability with respect to the infringement of copyrights,
Packit 7838c8
 * trade secrets or any patents by this file or any part thereof.  In no
Packit 7838c8
 * event will the author be liable for any lost revenue or profits or
Packit 7838c8
 * other special, indirect and consequential damages.
Packit 7838c8
 *
Packit 7838c8
 * Comments and additions should be sent to the author:
Packit 7838c8
 *
Packit 7838c8
 *                     Patrick J. Naughton
Packit 7838c8
 *                     Sun Microsystems
Packit 7838c8
 *                     2550 Garcia Ave, MS 14-40
Packit 7838c8
 *                     Mountain View, CA 94043
Packit 7838c8
 *                     (415) 336-1080
Packit 7838c8
 *
Packit 7838c8
 * Revision History:
Packit 7838c8
 * 10-Jan-89: Created.
Packit 7838c8
 * 06-Mar-90: Change to byte encoded rasterfiles.
Packit 7838c8
 *	      fix bug in call to ReadScanline().
Packit 7838c8
 *	      fix bug in CVT() macro.
Packit 7838c8
 *	      fix assignment of td, (missing &).
Packit 7838c8
 *
Packit 7838c8
 * Description:
Packit 7838c8
 *   This program takes a MicroSoft/Aldus "Tagged Image File Format" image or
Packit 7838c8
 * "TIFF" file as input and writes a Sun Rasterfile [see rasterfile(5)].  The
Packit 7838c8
 * output file may be standard output, but the input TIFF file must be a real
Packit 7838c8
 * file since seek(2) is used.
Packit 7838c8
 */
Packit 7838c8
Packit 7838c8
#include <stdio.h>
Packit 7838c8
#include <pixrect/pixrect_hs.h>
Packit 7838c8
#include "tiffio.h"
Packit 7838c8
Packit 7838c8
typedef int boolean;
Packit 7838c8
#define True (1)
Packit 7838c8
#define False (0)
Packit 7838c8
#define	CVT(x)		(((x) * 255) / ((1L<<16)-1))
Packit 7838c8
Packit 7838c8
boolean     Verbose = False;
Packit 7838c8
char       *pname;		/* program name (used for error messages) */
Packit 7838c8
Packit 7838c8
void
Packit 7838c8
error(s1, s2)
Packit 7838c8
    char       *s1,
Packit 7838c8
               *s2;
Packit 7838c8
{
Packit 7838c8
    fprintf(stderr, s1, pname, s2);
Packit 7838c8
    exit(1);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
void
Packit 7838c8
usage()
Packit 7838c8
{
Packit 7838c8
    error("usage: %s -[vq] TIFFfile [rasterfile]\n", NULL);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
Packit 7838c8
main(argc, argv)
Packit 7838c8
    int         argc;
Packit 7838c8
    char       *argv[];
Packit 7838c8
{
Packit 7838c8
    char       *inf = NULL;
Packit 7838c8
    char       *outf = NULL;
Packit 7838c8
    FILE       *fp;
Packit 7838c8
    long        width,
Packit 7838c8
                height;
Packit 7838c8
    int         depth,
Packit 7838c8
                numcolors;
Packit 7838c8
    register TIFF *tif;
Packit 7838c8
    TIFFDirectory *td;
Packit 7838c8
    register u_char *inp,
Packit 7838c8
               *outp;
Packit 7838c8
    register int col,
Packit 7838c8
                i;
Packit 7838c8
    register long row;
Packit 7838c8
    u_char     *Map = NULL;
Packit 7838c8
    u_char     *buf;
Packit 7838c8
    short	bitspersample;
Packit 7838c8
    short	samplesperpixel;
Packit 7838c8
    short	photometric;
Packit 7838c8
    u_short    *redcolormap,
Packit 7838c8
	       *bluecolormap,
Packit 7838c8
	       *greencolormap;
Packit 7838c8
Packit 7838c8
    Pixrect    *pix;		/* The Sun Pixrect */
Packit 7838c8
    colormap_t  Colormap;	/* The Pixrect Colormap */
Packit 7838c8
    u_char      red[256],
Packit 7838c8
                green[256],
Packit 7838c8
                blue[256];
Packit 7838c8
Packit 7838c8
    setbuf(stderr, NULL);
Packit 7838c8
    pname = argv[0];
Packit 7838c8
Packit 7838c8
    while (--argc) {
Packit 7838c8
	if ((++argv)[0][0] == '-')
Packit 7838c8
	    switch (argv[0][1]) {
Packit 7838c8
	    case 'v':
Packit 7838c8
		Verbose = True;
Packit 7838c8
		break;
Packit 7838c8
	    case 'q':
Packit 7838c8
		usage();
Packit 7838c8
		break;
Packit 7838c8
	    default:
Packit 7838c8
		fprintf(stderr, "%s: illegal option -%c.\n", pname,
Packit 7838c8
			argv[0][1]);
Packit 7838c8
		exit(1);
Packit 7838c8
	    }
Packit 7838c8
	else if (inf == NULL)
Packit 7838c8
	    inf = argv[0];
Packit 7838c8
	else if (outf == NULL)
Packit 7838c8
	    outf = argv[0];
Packit 7838c8
	else
Packit 7838c8
	    usage();
Packit 7838c8
Packit 7838c8
    }
Packit 7838c8
Packit 7838c8
    if (inf == NULL)
Packit 7838c8
	error("%s: can't read input file from a stream.\n", NULL);
Packit 7838c8
Packit 7838c8
    if (Verbose)
Packit 7838c8
	fprintf(stderr, "Reading %s...", inf);
Packit 7838c8
Packit 7838c8
    tif = TIFFOpen(inf, "r");
Packit 7838c8
Packit 7838c8
    if (tif == NULL)
Packit 7838c8
	error("%s: error opening TIFF file %s", inf);
Packit 7838c8
Packit 7838c8
    if (Verbose)
Packit 7838c8
	TIFFPrintDirectory(tif, stderr, True, False, False);
Packit 7838c8
    TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
Packit 7838c8
    if (bitspersample > 8)
Packit 7838c8
	error("%s: can't handle more than 8-bits per sample\n", NULL);
Packit 7838c8
Packit 7838c8
    TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
Packit 7838c8
    switch (samplesperpixel) {
Packit 7838c8
    case 1:
Packit 7838c8
	if (bitspersample == 1)
Packit 7838c8
	    depth = 1;
Packit 7838c8
	else
Packit 7838c8
	    depth = 8;
Packit 7838c8
	break;
Packit 7838c8
    case 3:
Packit 7838c8
    case 4:
Packit 7838c8
	depth = 24;
Packit 7838c8
	break;
Packit 7838c8
    default:
Packit 7838c8
	error("%s: only handle 1-channel gray scale or 3-channel color\n");
Packit 7838c8
    }
Packit 7838c8
Packit 7838c8
    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
Packit 7838c8
    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
Packit 7838c8
Packit 7838c8
    if (Verbose)
Packit 7838c8
	fprintf(stderr, "%dx%dx%d image, ", width, height, depth);
Packit 7838c8
    if (Verbose)
Packit 7838c8
	fprintf(stderr, "%d bits/sample, %d samples/pixel, ",
Packit 7838c8
		bitspersample, samplesperpixel);
Packit 7838c8
Packit 7838c8
    pix = mem_create(width, height, depth);
Packit 7838c8
    if (pix == (Pixrect *) NULL)
Packit 7838c8
	error("%s: can't allocate memory for output pixrect...\n", NULL);
Packit 7838c8
Packit 7838c8
    numcolors = (1 << bitspersample);
Packit 7838c8
Packit 7838c8
    TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
Packit 7838c8
    if (numcolors == 2) {
Packit 7838c8
	if (Verbose)
Packit 7838c8
	    fprintf(stderr, "monochrome ");
Packit 7838c8
	Colormap.type = RMT_NONE;
Packit 7838c8
	Colormap.length = 0;
Packit 7838c8
	Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL;
Packit 7838c8
    } else {
Packit 7838c8
	switch (photometric) {
Packit 7838c8
	case PHOTOMETRIC_MINISBLACK:
Packit 7838c8
	    if (Verbose)
Packit 7838c8
		fprintf(stderr, "%d graylevels (min=black), ", numcolors);
Packit 7838c8
	    Map = (u_char *) malloc(numcolors * sizeof(u_char));
Packit 7838c8
	    for (i = 0; i < numcolors; i++)
Packit 7838c8
		Map[i] = (255 * i) / numcolors;
Packit 7838c8
	    Colormap.type = RMT_EQUAL_RGB;
Packit 7838c8
	    Colormap.length = numcolors;
Packit 7838c8
	    Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map;
Packit 7838c8
	    break;
Packit 7838c8
	case PHOTOMETRIC_MINISWHITE:
Packit 7838c8
	    if (Verbose)
Packit 7838c8
		fprintf(stderr, "%d graylevels (min=white), ", numcolors);
Packit 7838c8
	    Map = (u_char *) malloc(numcolors * sizeof(u_char));
Packit 7838c8
	    for (i = 0; i < numcolors; i++)
Packit 7838c8
		Map[i] = 255 - ((255 * i) / numcolors);
Packit 7838c8
	    Colormap.type = RMT_EQUAL_RGB;
Packit 7838c8
	    Colormap.length = numcolors;
Packit 7838c8
	    Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map;
Packit 7838c8
	    break;
Packit 7838c8
	case PHOTOMETRIC_RGB:
Packit 7838c8
	    if (Verbose)
Packit 7838c8
		fprintf(stderr, "truecolor ");
Packit 7838c8
	    Colormap.type = RMT_NONE;
Packit 7838c8
	    Colormap.length = 0;
Packit 7838c8
	    Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL;
Packit 7838c8
	    break;
Packit 7838c8
	case PHOTOMETRIC_PALETTE:
Packit 7838c8
	    if (Verbose)
Packit 7838c8
		fprintf(stderr, "colormapped ");
Packit 7838c8
	    Colormap.type = RMT_EQUAL_RGB;
Packit 7838c8
	    Colormap.length = numcolors;
Packit 7838c8
	    memset(red, 0, sizeof(red));
Packit 7838c8
	    memset(green, 0, sizeof(green));
Packit 7838c8
	    memset(blue, 0, sizeof(blue));
Packit 7838c8
	    TIFFGetField(tif, TIFFTAG_COLORMAP,
Packit 7838c8
		&redcolormap, &greencolormap, &bluecolormap);
Packit 7838c8
	    for (i = 0; i < numcolors; i++) {
Packit 7838c8
		red[i] = (u_char) CVT(redcolormap[i]);
Packit 7838c8
		green[i] = (u_char) CVT(greencolormap[i]);
Packit 7838c8
		blue[i] = (u_char) CVT(bluecolormap[i]);
Packit 7838c8
	    }
Packit 7838c8
	    Colormap.map[0] = red;
Packit 7838c8
	    Colormap.map[1] = green;
Packit 7838c8
	    Colormap.map[2] = blue;
Packit 7838c8
	    break;
Packit 7838c8
	case PHOTOMETRIC_MASK:
Packit 7838c8
	    error("%s: Don't know how to handle PHOTOMETRIC_MASK\n");
Packit 7838c8
	    break;
Packit 7838c8
	case PHOTOMETRIC_DEPTH:
Packit 7838c8
	    error("%s: Don't know how to handle PHOTOMETRIC_DEPTH\n");
Packit 7838c8
	    break;
Packit 7838c8
	default:
Packit 7838c8
	    error("%s: unknown photometric (cmap): %d\n", photometric);
Packit 7838c8
	}
Packit 7838c8
    }
Packit 7838c8
Packit 7838c8
    buf = (u_char *) malloc(TIFFScanlineSize(tif));
Packit 7838c8
    if (buf == NULL)
Packit 7838c8
	error("%s: can't allocate memory for scanline buffer...\n", NULL);
Packit 7838c8
Packit 7838c8
    for (row = 0; row < height; row++) {
Packit 7838c8
	if (TIFFReadScanline(tif, buf, row, 0) < 0)
Packit 7838c8
	    error("%s: bad data read on line: %d\n", row);
Packit 7838c8
	inp = buf;
Packit 7838c8
	outp = (u_char *) mprd_addr(mpr_d(pix), 0, row);
Packit 7838c8
	switch (photometric) {
Packit 7838c8
	case PHOTOMETRIC_RGB:
Packit 7838c8
	    if (samplesperpixel == 4)
Packit 7838c8
		for (col = 0; col < width; col++) {
Packit 7838c8
		    *outp++ = *inp++;	/* Blue */
Packit 7838c8
		    *outp++ = *inp++;	/* Green */
Packit 7838c8
		    *outp++ = *inp++;	/* Red */
Packit 7838c8
		    inp++;	/* skip alpha channel */
Packit 7838c8
		}
Packit 7838c8
	    else
Packit 7838c8
		for (col = 0; col < width; col++) {
Packit 7838c8
		    *outp++ = *inp++;	/* Blue */
Packit 7838c8
		    *outp++ = *inp++;	/* Green */
Packit 7838c8
		    *outp++ = *inp++;	/* Red */
Packit 7838c8
		}
Packit 7838c8
	    break;
Packit 7838c8
	case PHOTOMETRIC_MINISWHITE:
Packit 7838c8
	case PHOTOMETRIC_MINISBLACK:
Packit 7838c8
	    switch (bitspersample) {
Packit 7838c8
	    case 1:
Packit 7838c8
		for (col = 0; col < ((width + 7) / 8); col++)
Packit 7838c8
		    *outp++ = *inp++;
Packit 7838c8
		break;
Packit 7838c8
	    case 2:
Packit 7838c8
		for (col = 0; col < ((width + 3) / 4); col++) {
Packit 7838c8
		    *outp++ = (*inp >> 6) & 3;
Packit 7838c8
		    *outp++ = (*inp >> 4) & 3;
Packit 7838c8
		    *outp++ = (*inp >> 2) & 3;
Packit 7838c8
		    *outp++ = *inp++ & 3;
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	    case 4:
Packit 7838c8
		for (col = 0; col < width / 2; col++) {
Packit 7838c8
		    *outp++ = *inp >> 4;
Packit 7838c8
		    *outp++ = *inp++ & 0xf;
Packit 7838c8
		}
Packit 7838c8
		break;
Packit 7838c8
	    case 8:
Packit 7838c8
		for (col = 0; col < width; col++)
Packit 7838c8
		    *outp++ = *inp++;
Packit 7838c8
		break;
Packit 7838c8
	    default:
Packit 7838c8
		error("%s: bad bits/sample: %d\n", bitspersample);
Packit 7838c8
	    }
Packit 7838c8
	    break;
Packit 7838c8
	case PHOTOMETRIC_PALETTE:
Packit 7838c8
	    memcpy(outp, inp, width);
Packit 7838c8
	    break;
Packit 7838c8
	default:
Packit 7838c8
	    error("%s: unknown photometric (write): %d\n", photometric);
Packit 7838c8
	}
Packit 7838c8
    }
Packit 7838c8
Packit 7838c8
    free((char *) buf);
Packit 7838c8
Packit 7838c8
    if (Verbose)
Packit 7838c8
	fprintf(stderr, "done.\n");
Packit 7838c8
Packit 7838c8
    if (outf == NULL || strcmp(outf, "Standard Output") == 0) {
Packit 7838c8
	outf = "Standard Output";
Packit 7838c8
	fp = stdout;
Packit 7838c8
    } else {
Packit 7838c8
	if (!(fp = fopen(outf, "w")))
Packit 7838c8
	    error("%s: %s couldn't be opened for writing.\n", outf);
Packit 7838c8
    }
Packit 7838c8
Packit 7838c8
    if (Verbose)
Packit 7838c8
	fprintf(stderr, "Writing rasterfile in %s...", outf);
Packit 7838c8
Packit 7838c8
    if (pr_dump(pix, fp, &Colormap, RT_BYTE_ENCODED, 0) == PIX_ERR)
Packit 7838c8
	error("%s: error writing Sun Rasterfile: %s\n", outf);
Packit 7838c8
Packit 7838c8
    if (Verbose)
Packit 7838c8
	fprintf(stderr, "done.\n");
Packit 7838c8
Packit 7838c8
    pr_destroy(pix);
Packit 7838c8
Packit 7838c8
    if (fp != stdout)
Packit 7838c8
	fclose(fp);
Packit 7838c8
Packit 7838c8
    exit(0);
Packit 7838c8
}
Packit 7838c8
/*
Packit 7838c8
 * Local Variables:
Packit 7838c8
 * mode: c
Packit 7838c8
 * c-basic-offset: 8
Packit 7838c8
 * fill-column: 78
Packit 7838c8
 * End:
Packit 7838c8
 */