home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 1
/
crawlyvol1.bin
/
program
/
grfx_snd
/
tifflib
/
source
/
pnm2tiff.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-28
|
12KB
|
360 lines
#pragma warn -use
static char *sccsid = "@(#)PBMplus/pnm2tiff 1.21, Copyright (c) Jef Poskanzer, Dieter Linde, "__DATE__;
#pragma warn .use
/*
* pnm2tiff.c - converts a portable anymap to a Tagged Image File
*
* Derived by Jef Poskanzer from ras2tif.c, which is:
*
* Copyright ©1990 by Sun Microsystems, Inc.
*
* Author: Patrick J. Naughton
* naughton@wind.sun.com
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation.
*
* This file is provided AS IS with no warranties of any kind. The author
* shall have no liability with respect to the infringement of copyrights,
* trade secrets or any patents by this file or any part thereof. In no
* event will the author be liable for any lost revenue or profits or
* other special, indirect and consequential damages.
*/
#include "pnm.h"
#include "tiffio.h"
#ifdef PPM
#include "..\ppm\ppmcmap.h"
#define MAXCOLORS 256
#endif /* PPM */
#define COMPRESSION_UNDEF 0
/****************************************************************************
*
*/
void
main(
int argc,
char *argv[]
)
{
register int col;
register xel *xP;
char *scomp, *ids;
unsigned char *buf, *tP;
int i, cols, rows, format, row, argn, grayscale, bytesperrow;
short photometric, samplesperpixel, bitspersample;
u_short comp;
long rowsperstrip, colors;
xelval maxval;
FILE *ifp;
xel **xels;
TIFF *tif;
#ifdef PPM
unsigned short red[MAXCOLORS], grn[MAXCOLORS], blu[MAXCOLORS];
colorhist_vector chv;
colorhash_table cht;
#endif /* PPM */
char *inf = NULL;
char *usage = "[-none|-dump|-ccittrle|-rle|-ccittfax3|-fax3|-ccittfax4|-fax4|-ccittrlew|-rlew|-packbits|-lzw|-picio|-sgirle] [<pnmfile>]";
pnm_init("pnm2tiff", &argc, argv);
ids = getenv("TIFF_IMAGEDESCRIPTION");
argn = 1;
comp = COMPRESSION_UNDEF;
while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0') {
if (pm_keymatch(argv[argn], "-none", 2) || pm_keymatch(argv[argn], "-dump", 2)) {
if (comp != COMPRESSION_UNDEF)
pm_error("only one compression method may be specified");
comp = COMPRESSION_NONE;
scomp = "none";
}
else if (pm_keymatch(argv[argn], "-ccittrle", 9) || pm_keymatch(argv[argn], "-rle", 4)) {
if (comp != COMPRESSION_UNDEF)
pm_error("only one compression method may be specified");
comp = COMPRESSION_CCITTRLE;
scomp = "CCITT modified Huffman";
}
else if (pm_keymatch(argv[argn], "-ccittrlew", 10) || pm_keymatch(argv[argn], "-rlew", 5)) {
if (comp != COMPRESSION_UNDEF)
pm_error("only one compression method may be specified");
comp = COMPRESSION_CCITTRLEW;
scomp = "CCITT modified Huffman w/ word alignment";
}
else if (pm_keymatch(argv[argn], "-ccittfax3", 10) || pm_keymatch(argv[argn], "-fax3", 5)) {
if (comp != COMPRESSION_UNDEF)
pm_error("only one compression method may be specified");
comp = COMPRESSION_CCITTFAX3;
scomp = "CCITT Group 3 facsimile";
}
else if (pm_keymatch(argv[argn], "-ccittfax4", 10) || pm_keymatch(argv[argn], "-fax4", 5)) {
if (comp != COMPRESSION_UNDEF)
pm_error("only one compression method may be specified");
comp = COMPRESSION_CCITTFAX4;
scomp = "CCITT Group 4 facsimile";
}
else if (pm_keymatch(argv[argn], "-packbits", 3)) {
if (comp != COMPRESSION_UNDEF)
pm_error("only one compression method may be specified");
comp = COMPRESSION_PACKBITS;
scomp = "Macintosh PackBits";
}
else if (pm_keymatch(argv[argn], "-lzw", 2)) {
if (comp != COMPRESSION_UNDEF)
pm_error("only one compression method may be specified");
comp = COMPRESSION_LZW;
scomp = "Lempel-Ziv & Welch";
}
else if (pm_keymatch(argv[argn], "-picio", 3)) {
if (comp != COMPRESSION_UNDEF)
pm_error("only one compression method may be specified");
comp = COMPRESSION_PICIO;
scomp = "Pixar picio";
}
else if (pm_keymatch(argv[argn], "-sgirle", 2)) {
if (comp != COMPRESSION_UNDEF)
pm_error("only one compression method may be specified");
comp = COMPRESSION_SGIRLE;
scomp = "Silicon Graphics run-length";
}
else
pm_usage(usage);
argn++;
}
if (comp == COMPRESSION_UNDEF) {
comp = COMPRESSION_NONE;
scomp = "none";
}
if (argn != argc) {
inf = argv[argn];
ifp = pm_openr(inf);
argn++;
}
else {
inf = "stdin";
ifp = stdin;
if (setvbuf(ifp, NULL, _IOFBF, stdbufsize))
pm_error("out of memory allocating a filebuffer");
fsetmode(ifp, IO_BINARY);
fclrmode(ifp, IO_NBF);
}
if (argn != argc)
pm_usage(usage);
xels = pnm_readpnm(ifp, &cols, &rows, &maxval, &format);
pm_close(ifp);
/*
* Check for grayscale.
*/
switch (PNM_FORMAT_TYPE(format)) {
#ifdef PPM
case PPM_TYPE:
pm_message("computing colormap...");
if ((chv = ppm_computecolorhist(xels, cols, rows, MAXCOLORS, &colors)) == NULL) {
pm_message("too many colors -- proceeding to write a 24-bit RGB file.");
pm_message("If you want an 8-bit palette file, try doing a \"ppmquant %d\".", MAXCOLORS);
grayscale = 0;
}
else {
pm_message("%ld colors found", colors);
grayscale = 1;
for (i = 0; i < colors; i++) {
register xelval r, g, b;
r = PPM_GETR(chv[i].color);
g = PPM_GETG(chv[i].color);
b = PPM_GETB(chv[i].color);
if (r != g || g != b) {
grayscale = 0;
break;
}
}
}
break;
#endif /* PPM */
default:
grayscale = 1;
break;
}
/*
* Open output file.
*/
pm_message("using encoding method \'%s\'", scomp);
if ((tif = TIFFFdOpen(1, "stdout", "wb")) == NULL)
pm_error("error opening stdout as TIFF file");
/*
* Figure out TIFF parameters.
*/
switch (PNM_FORMAT_TYPE(format)) {
#ifdef PPM
case PPM_TYPE:
if (chv == NULL) {
samplesperpixel = 3;
bitspersample = 8;
photometric = PHOTOMETRIC_RGB;
bytesperrow = cols * 3;
}
else if (grayscale) {
samplesperpixel = 1;
bitspersample = pm_maxvaltobits(maxval);
photometric = PHOTOMETRIC_MINISBLACK;
bytesperrow = (cols + i - 1) / i;
}
else {
samplesperpixel = 1;
bitspersample = 8;
photometric = PHOTOMETRIC_PALETTE;
bytesperrow = cols;
}
break;
#endif /* PPM */
#ifdef PGM
case PGM_TYPE:
samplesperpixel = 1;
bitspersample = pm_maxvaltobits(maxval);
photometric = PHOTOMETRIC_MINISBLACK;
i = 8 / bitspersample;
bytesperrow = (cols + i - 1) / i;
break;
#endif /* PGM */
default:
samplesperpixel = 1;
bitspersample = 1;
photometric = PHOTOMETRIC_MINISBLACK;
bytesperrow = (cols + 7) / 8;
break;
}
rowsperstrip = (8 * 1024) / bytesperrow;
if ((buf = (unsigned char *)malloc(bytesperrow)) == NULL)
pm_error("out of memory allocating row buffer");
/*
* Set TIFF parameters.
*/
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, cols);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, rows);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(tif, TIFFTAG_COMPRESSION, comp);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric);
TIFFSetField(tif, TIFFTAG_DOCUMENTNAME, inf);
if (ids != NULL)
TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, ids);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
TIFFSetField(tif, TIFFTAG_STRIPBYTECOUNTS, rows / rowsperstrip);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
#ifdef PPM
if (chv == NULL)
cht = NULL;
else {
/*
* Make TIFF colormap.
*/
for (i = 0; i < colors; i++) {
red[i] = (long)PPM_GETR(chv[i].color) * 65535L / maxval;
grn[i] = (long)PPM_GETG(chv[i].color) * 65535L / maxval;
blu[i] = (long)PPM_GETB(chv[i].color) * 65535L / maxval;
}
TIFFSetField(tif, TIFFTAG_COLORMAP, red, grn, blu);
/*
* Convert color vector to color hash table, for fast lookup.
*/
cht = ppm_colorhisttocolorhash(chv, colors);
ppm_freecolorhist(chv);
}
#endif /* PPM */
/*
* Now write the TIFF data.
*/
for (row = 0; row < rows; row++) {
#ifdef PPM
if (PNM_FORMAT_TYPE(format) == PPM_TYPE && !grayscale) {
if (cht == NULL) {
for (col = 0, xP = xels[row], tP = buf; col < cols; col++, xP++) {
register unsigned char s;
s = PPM_GETR(*xP);
if (maxval != 255)
s = (long)s * 255 / maxval;
*tP++ = s;
s = PPM_GETG(*xP);
if (maxval != 255)
s = (long)s * 255 / maxval;
*tP++ = s;
s = PPM_GETB(*xP);
if (maxval != 255)
s = (long)s * 255 / maxval;
*tP++ = s;
}
}
else {
for (col = 0, xP = xels[row], tP = buf; col < cols; col++, xP++) {
register long s;
s = ppm_lookupcolor(cht, xP);
if (s == -1)
pm_error("color not found?!? (row=%d, col=%d, r=%d, g=%d, b=%d)", row, col, PPM_GETR(*xP), PPM_GETG(*xP), PPM_GETB(*xP));
*tP++ = (unsigned char)s;
}
}
}
else
#endif /* PPM */
{
register xelval bigger_maxval;
register int bitshift;
register unsigned char byte;
register xelval s;
bigger_maxval = pm_bitstomaxval(bitspersample);
bitshift = 8 - bitspersample;
byte = 0;
for (col = 0, xP = xels[row], tP = buf; col < cols; col++, xP++) {
s = PNM_GET1(*xP);
if (maxval != bigger_maxval)
s = (long)s * bigger_maxval / maxval;
byte |= (s << bitshift);
bitshift -= bitspersample;
if (bitshift < 0) {
*tP++ = byte;
bitshift = 8 - bitspersample;
byte = 0;
}
}
if (bitshift != 8 - bitspersample)
*tP++ = byte;
}
if (TIFFWriteScanline(tif, buf, row, 0) < 0)
pm_error("failed a scanline write on row %d", row);
}
TIFFFlushData(tif);
TIFFClose(tif);
fflush(stdout);
exit(0);
}