/* tifftorle.c */ /* main program for converting TIFF files to Utah Raster Toolkit RLE files. * by Bailey Brown, Jr. 21 June 1990 * modified: * by David R. L. Worthington, SRI International, 29 April 1991 * to handle TIFF files with only one channel and a possible colormap. */ #define NO_DECLARE_MALLOC /* tiffcompat.h declares it. */ #include "rle.h" #undef TIFF /* Defined by rle_config.h. */ #ifndef USE_STDARG #define USE_VARARGS 1 /* Needed by tiffcompat.h. */ #endif #ifdef USE_PROTOTYPES #undef USE_PROTOTYPES #define USE_PROTOTYPES 1 #endif #include #include #include "tiffio.h" #ifdef USE_PROTOTYPES void error(CONST_DECL char *s); #else void error(); #endif void get_scanlines(); static rle_hdr the_hdr; TIFF *tif; unsigned char *tiffbuf; /* needed to read all scanlines before converting to tiff (rle is upside down) */ static rle_pixel **scan_red; static rle_pixel **scan_green; static rle_pixel **scan_blue; int flip = 0; unsigned short samplesperpixel = 1; unsigned short bitspersample = 8; /* Ok to assume 8? */ unsigned char bitconvert[16]; /* Convert 1, 2, or 4-bit samples to 8-bit */ unsigned char bc4[16] = { 0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xee, 0xff }; unsigned char bc2[4] = { 0, 0x55, 0xaa, 0xff }; unsigned char bc1[2] = { 0, 0xff }; void main(argc, argv) int argc; char *argv[]; { #ifndef TIFF2p4 unsigned short imagelength, imagewidth; #else /* TIFF2p4 */ unsigned long imagelength, imagewidth; #endif /* TIFF2p4 */ unsigned short photometric, shortval; unsigned short planarconfig, matteing; int row, i; rle_pixel *rows[4]; char *infname = NULL, *outfname = NULL; the_hdr = *rle_hdr_init( (rle_hdr *)NULL ); if ( scanargs( argc, argv, "% o%-outfile.rle!s infile.tiff!s\n(\ \tConvert TIFF image to URT.)", &i, &outfname, &infname ) == 0 ) exit( 1 ); rle_names( &the_hdr, cmd_name( argv ), outfname, 0 ); tif = TIFFOpen(infname, "rb"); if (!tif) error("can't open input file"); the_hdr.rle_file = rle_open_f(cmd_name(argv), outfname, "w"); if (TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth) == 0) error("TIFFGetField TIFFTAG_IMAGEWIDTH failed!"); if (TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imagelength) == 0) error("TIFFGetField TIFFTAG_IMAGELENGTH failed!"); if (TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel) == 0) error("TIFFGetField TIFFTAG_SAMPLESPERPIXEL failed!"); if (TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample) == 0) error("TIFFGetField TIFFTAG_BITSPERSAMPLE failed!"); if (TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric) == 0) error("TIFFGetField TIFFTAG_PHOTOMETRIC failed!"); switch ( bitspersample ) { case 4: for ( i = 0; i < 16; i++ ) if ( photometric == PHOTOMETRIC_RGB ) bitconvert[i] = bc4[i]; else bitconvert[i] = i; break; case 2: for ( i = 0; i < 4; i++ ) if ( photometric == PHOTOMETRIC_RGB ) bitconvert[i] = bc2[i]; else bitconvert[i] = i; break; case 1: if ( photometric == PHOTOMETRIC_RGB ) { bitconvert[0] = bc1[0]; bitconvert[1] = bc1[1]; } else { bitconvert[0] = 0; bitconvert[1] = 1; } break; case 8: break; default: error("Bits per sample not 1, 2, 4, or 8"); break; } if (TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarconfig ) == 0) error("TIFFGetField TIFFTAG_PLANARCONFIG failed!"); /* Might not be present. */ (void)TIFFGetField(tif, TIFFTAG_MATTEING, &matteing ); switch ( photometric ) { case PHOTOMETRIC_MINISWHITE: { int size = 1 << bitspersample; if ( planarconfig == PLANARCONFIG_SEPARATE && matteing ) samplesperpixel = 1; the_hdr.ncolors = 1; the_hdr.ncmap = 1; the_hdr.cmaplen = bitspersample; the_hdr.cmap = (unsigned short *)malloc((unsigned)size*sizeof(short)); for (i=0; i> (8 - bitspersample); int phase = 8 / bitspersample, shift = 8 - bitspersample; unsigned char pix; for ( k = j = 0; j <= the_hdr.xmax; j++ ) { #define getpixel \ pix = bitconvert[(tiffbuf[k] >> shift) & mask]; \ if ( --phase == 0 ) { \ phase = 8 / bitspersample; \ shift = 8 - bitspersample; \ k++; \ } \ else \ shift -= bitspersample; getpixel; scan_red[n][j] = pix; if ( the_hdr.ncolors == 3 ) { getpixel; scan_green[n][j] = pix; getpixel; scan_blue[n][j] = pix; } /* Skip any other channels (e.g., alpha). */ for ( l = samplesperpixel - the_hdr.ncolors; l > 0; l-- ) { getpixel; } #undef getpixel } } } } void error(s) CONST_DECL char *s; { fprintf(stderr,"%s: %s in %s\n", the_hdr.cmd, s, TIFFFileName(tif)); exit(2); }