home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************
- * 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);
- }
-