home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Photo CD Demo 1
/
Demo.bin
/
fbm
/
src
/
fbm2tiff.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-06-24
|
8KB
|
279 lines
/*****************************************************************
* fbm2tiff.c: FBM Release 1.0 25-Feb-90 Michael Mauldin
*
* Copyright (C) 1989,1990 by Michael Mauldin. Permission is granted
* to use this file in whole or in part for any purpose, educational,
* recreational or commercial, provided that this copyright notice
* is retained unchanged. This software is available to all free of
* charge by anonymous FTP and in the UUNET archives.
*
* fbm2tiff.c:
* Convert an FBM format image to TIFF format. Uses Sam Leffler's
* libtiff.a TIFF image library to write TIFF format. See also,
* tiff2fbm for the opposite conversion.
*
* USAGE
* % fbm2tiff [ image ] > foo.tif
*
* EDITLOG
* LastEditDate = Mon Jun 25 00:03:33 1990 - Michael Mauldin
* LastFileName = /usr2/mlm/src/misc/fbm/fbm2tiff.c
*
* HISTORY
* 25-Jun-90 Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
* Package for Release 1.0
*
* 13-Jun-90 Michael Mauldin (mlm) at Carnegie-Mellon University
* Created.
*****************************************************************/
# include <stdio.h>
# include <ctype.h>
# ifdef BYTE
# undef BYTE
# endif
# include <tiff.h>
# include <tiffio.h>
# include "fbm.h"
# ifdef __STDC__
# define FIELD(tif,f) TIFFFieldSet(tif, FIELD_ ## f)
# else
/* The following macro is taken from tiff_print.c */
# define FIELD(tif,f) TIFFFieldSet(tif, FIELD_/**/f)
# endif
#define howmany(x, y) (((x)+((y)-1))/(y))
#define streq(a,b) (strcmp(a,b) == 0)
#define SCALE(x) (((x)*((1L<<16)-1))/256)
# define USAGE \
"Usage: fbm2tiff [-N] [-<compression>] [-r<rowsperstrip>] foo.tif < foo.fbm\n\
-l=lzw, -p=packbits, -n=none"
/****************************************************************
* main
****************************************************************/
#ifndef lint
static char *fbmid =
"$FBM fbm2tiff.c <1.0> 25-Jun-90 (C) 1989,1990 by Michael Mauldin, source \
code available free from MLM@CS.CMU.EDU and from UUNET archives$";
#endif
main (argc, argv)
char *argv[];
{ FBM image;
int width, height, rowlen, planes, plnlen, k;
int graybit=0;
int failed = 0;
u_short config = PLANARCONFIG_CONTIG;
u_short compression = COMPRESSION_NONE;
u_short rowsperstrip = -1;
u_char *bmp, *obm, *scanbuf;
int row, linebytes;
TIFF *out;
/* Get the options */
while (--argc > 0 && (*++argv)[0] == '-')
{ while (*++(*argv))
{ switch (**argv)
{ case 'n': compression = COMPRESSION_NONE; break;
case 'p': compression = COMPRESSION_PACKBITS; break;
case 'l': compression = COMPRESSION_LZW; break;
case 'r': rowsperstrip = atoi (*argv+1); SKIPARG; break;
case 'N': graybit = 2; compression = COMPRESSION_NONE; break;
case 'g': graybit = atoi (*argv+1); SKIPARG; break;
default: fprintf (stderr, "%s\n", USAGE);
exit (1);
}
}
}
/* Check for bad argument to reduced resolution argument */
switch (graybit)
{ case 1: case 2: case 4:
/* These are standard values */
break;
case 0: case 8:
/* These mean no reduced resolution */
graybit = 0; break;
default: fprintf (stderr,
"Error: graybit vvalue must be 0, 1, 2, or 4\n");
exit (1);
}
image.cm = image.bm = (unsigned char *) NULL;
/* Now read in an FBM image and write a TIFF format file */
if (!read_bitmap (&image, (char *) NULL))
{ exit (1); }
else
{ width = image.hdr.cols;
height = image.hdr.rows;
rowlen = image.hdr.rowlen;
planes = image.hdr.planes;
plnlen = image.hdr.plnlen;
fprintf (stderr, "input [%dx%d], %d colors, %d bits, %d physbits\n",
width, height, image.hdr.clrlen/3,
image.hdr.bits, image.hdr.physbits);
/*-Start of Tiff writing code-------------------------------------*/
if (!(out = TIFFOpen(argv[0], "w")))
{ exit(-4); }
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, height);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, graybit ? 1:image.hdr.planes);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, graybit ? graybit:image.hdr.bits);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
if (image.hdr.clrlen > 0 && !graybit)
{ register u_short *red;
register int i, j;
int mapsize;
mapsize = 1<<image.hdr.bits;
if (image.hdr.clrlen > mapsize*3)
{ fprintf(stderr,
"stdin: Huh, %d colormap entries, should be %d?\n",
image.hdr.clrlen, mapsize*3);
exit(-7);
}
if ((red = (u_short *)malloc(mapsize * 3 * sizeof (u_short))) == NULL)
{ perror ("colormap"); exit (-8); }
/* XXX -- set pointers up before we step through arrays */
TIFFSetField(out, TIFFTAG_COLORMAP,
red, red + mapsize, red + 2*mapsize);
bmp = image.cm;
for (j = 0; j < 3; j++)
{ for (i = image.hdr.clrlen; i-- > 0;)
{ *red++ = SCALE(*bmp++); }
if ((i = image.hdr.clrlen/3) < mapsize)
{ i = mapsize - i;
bzero(red, i*sizeof (u_short));
red += i;
}
}
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
}
else
{ /* XXX this is bogus... */
TIFFSetField(out, TIFFTAG_PHOTOMETRIC,
(image.hdr.planes == 3) && !graybit ?
PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK);
}
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
linebytes = ((image.hdr.bits * width+15) >> 3) &~ 1;
if (TIFFScanlineSize(out) > linebytes)
scanbuf = (u_char *)malloc(linebytes);
else
scanbuf = (u_char *)malloc(TIFFScanlineSize(out));
if (rowsperstrip != (u_short)-1)
rowsperstrip = (8*1024)/linebytes;
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
rowsperstrip == 0 ? 1 : rowsperstrip);
/* Handle bitmaps first */
if (image.hdr.bits == 1 && image.hdr.physbits == 8)
{ int byte = 0, i;
u_char *obm;
for (row = 0; row < height; row++)
{ byte = 0;
bmp = &image.bm[row*rowlen];
obm = scanbuf;
/* Write out each group of 8 bytes as one byte */
for (i=0; i<width; i++)
{ byte = (byte << 1) | (*bmp++ ? 1 : 0);
if ((i&7) == 7)
{ *obm++ = byte; byte=0; }
}
/* Handle stragglers if width not multiple of 8 */
if (i&7)
{ byte <<= (8 - (i&7));
*obm = byte;
}
if (TIFFWriteScanline(out, scanbuf, row, 0) < 0)
{ failed++; break; }
}
}
/* Handle reduced level grayscale */
else if (graybit && image.hdr.bits == 8)
{ int byte, mask, spb, shift, i; /* spb: Samples per byte mask */
u_char *obm;
switch (graybit)
{ case 1: mask = 0x80; spb = 7; shift = 7; break;
case 2: mask = 0xc0; spb = 3; shift = 6; break;
case 4: mask = 0xf0; spb = 1; shift = 4; break;
}
for (row = 0; row < height; row++)
{ byte = 0;
bmp = &image.bm[row*rowlen];
obm = scanbuf;
/* Write out each group of 8 bytes as one byte */
for (i=0; i<width; )
{ byte = (byte << graybit) | ((*bmp++ & mask) >> shift);
if ((++i & spb) == 0)
{ *obm++ = byte; byte=0; }
}
/* Handle stragglers if width not multiple of 8 */
if (i&spb)
{ while (i++ & spb)
{ byte <<= graybit; }
*obm = byte;
}
if (TIFFWriteScanline(out, scanbuf, row, 0) < 0)
{ failed++; break; }
}
}
/* Catch cases we cant handle */
else if (image.hdr.physbits != 8)
{ fprintf (stderr, "Error: cannot handle %d physical bits per pixel\n",
image.hdr.physbits);
exit (1);
}
/* Handle 8bit grayscale or 24bit rgb */
else
{ for (row = 0; row < height; row++)
{ for (k=0; k<planes; k++)
{ bcopy (&image.bm[k*plnlen + row*rowlen], scanbuf + k*width, width); }
if (TIFFWriteScanline(out, scanbuf, row, 0) < 0)
{ failed++; break; }
}
}
(void) TIFFClose(out);
if (failed)
{ exit (1); }
}
exit (0);
}