Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
tifftorle.c
Go to the documentation of this file.
1 /* tifftorle.c */
2 /* main program for converting TIFF files to Utah Raster Toolkit RLE files.
3  * by Bailey Brown, Jr. 21 June 1990
4  * modified:
5  * by David R. L. Worthington, SRI International, 29 April 1991
6  * to handle TIFF files with only one channel and a possible colormap.
7  */
8 
9 
10 #define NO_DECLARE_MALLOC /* tiffcompat.h declares it. */
11 #include "rle.h"
12 #undef TIFF /* Defined by rle_config.h. */
13 #ifndef USE_STDARG
14 #define USE_VARARGS 1 /* Needed by tiffcompat.h. */
15 #endif
16 #ifdef USE_PROTOTYPES
17 #undef USE_PROTOTYPES
18 #define USE_PROTOTYPES 1
19 #endif
20 
21 #include <math.h>
22 #include <stdio.h>
23 #include "tiffio.h"
24 
25 #ifdef USE_PROTOTYPES
26 void error(CONST_DECL char *s);
27 #else
28 void error();
29 #endif
30 void get_scanlines();
31 
32 static rle_hdr the_hdr;
33 TIFF *tif;
34 unsigned char *tiffbuf;
35 /* needed to read all scanlines before converting
36  to tiff (rle is upside down) */
40 
41 int flip = 0;
42 unsigned short samplesperpixel = 1;
43 unsigned short bitspersample = 8; /* Ok to assume 8? */
44 unsigned char bitconvert[16]; /* Convert 1, 2, or 4-bit samples to 8-bit */
45 unsigned char bc4[16] = { 0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
46  0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xee, 0xff };
47 unsigned char bc2[4] = { 0, 0x55, 0xaa, 0xff };
48 unsigned char bc1[2] = { 0, 0xff };
49 
50 void
52 int argc;
53 char *argv[];
54 {
55 #ifndef TIFF2p4
56  unsigned short imagelength, imagewidth;
57 #else /* TIFF2p4 */
58  unsigned long imagelength, imagewidth;
59 #endif /* TIFF2p4 */
60  unsigned short photometric, shortval;
61  unsigned short planarconfig, matteing;
62  int row, i;
63  rle_pixel *rows[4];
64  char *infname = NULL, *outfname = NULL;
65 
66  the_hdr = *rle_hdr_init( (rle_hdr *)NULL );
67  if ( scanargs( argc, argv, "% o%-outfile.rle!s infile.tiff!s\n(\
68 \tConvert TIFF image to URT.)",
69  &i, &outfname, &infname ) == 0 )
70  exit( 1 );
71 
72  rle_names( &the_hdr, cmd_name( argv ), outfname, 0 );
73 
74  tif = TIFFOpen(infname, "rb");
75  if (!tif) error("can't open input file");
76  the_hdr.rle_file = rle_open_f(cmd_name(argv), outfname, "w");
77 
78  if (TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth) == 0)
79  error("TIFFGetField TIFFTAG_IMAGEWIDTH failed!");
80  if (TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imagelength) == 0)
81  error("TIFFGetField TIFFTAG_IMAGELENGTH failed!");
82  if (TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel) == 0)
83  error("TIFFGetField TIFFTAG_SAMPLESPERPIXEL failed!");
84  if (TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample) == 0)
85  error("TIFFGetField TIFFTAG_BITSPERSAMPLE failed!");
86  if (TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric) == 0)
87  error("TIFFGetField TIFFTAG_PHOTOMETRIC failed!");
88  switch ( bitspersample )
89  {
90  case 4:
91  for ( i = 0; i < 16; i++ )
92  if ( photometric == PHOTOMETRIC_RGB )
93  bitconvert[i] = bc4[i];
94  else
95  bitconvert[i] = i;
96  break;
97  case 2:
98  for ( i = 0; i < 4; i++ )
99  if ( photometric == PHOTOMETRIC_RGB )
100  bitconvert[i] = bc2[i];
101  else
102  bitconvert[i] = i;
103  break;
104  case 1:
105  if ( photometric == PHOTOMETRIC_RGB )
106  {
107  bitconvert[0] = bc1[0];
108  bitconvert[1] = bc1[1];
109  }
110  else
111  {
112  bitconvert[0] = 0;
113  bitconvert[1] = 1;
114  }
115  break;
116  case 8:
117  break;
118  default:
119  error("Bits per sample not 1, 2, 4, or 8");
120  break;
121  }
122  if (TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarconfig ) == 0)
123  error("TIFFGetField TIFFTAG_PLANARCONFIG failed!");
124  /* Might not be present. */
125  (void)TIFFGetField(tif, TIFFTAG_MATTEING, &matteing );
126 
127  switch ( photometric ) {
128  case PHOTOMETRIC_MINISWHITE:
129  {
130  int size = 1 << bitspersample;
131  if ( planarconfig == PLANARCONFIG_SEPARATE && matteing )
132  samplesperpixel = 1;
133  the_hdr.ncolors = 1;
134  the_hdr.ncmap = 1;
136  the_hdr.cmap = (unsigned short *)malloc((unsigned)size*sizeof(short));
137  for (i=0; i<size; i++)
138  the_hdr.cmap[i] = 65535L - ((long)i * 65535L)/(size - 1);
139  break;
140  }
141  case PHOTOMETRIC_MINISBLACK:
142  {
143  int size = 1 << bitspersample;
144  if ( planarconfig == PLANARCONFIG_SEPARATE && matteing )
145  samplesperpixel = 1;
146  the_hdr.ncolors = 1;
147  the_hdr.ncmap = 1;
149  the_hdr.cmap = (unsigned short *)malloc((unsigned)size*sizeof(short));
150  for (i=0; i<size; i++)
151  the_hdr.cmap[i] = ((long)i * 65535L)/(size - 1);
152  break;
153  }
154  case PHOTOMETRIC_RGB:
155  if (planarconfig != PLANARCONFIG_CONTIG)
156  error("can't handle separate planar config");
157 
158  the_hdr.ncolors = 3;
159  the_hdr.ncmap = 0;
160  the_hdr.cmaplen = 0;
161  the_hdr.cmap = 0;
162  break;
163  case PHOTOMETRIC_PALETTE: /* Handle Colormap */
164  {
165  unsigned short *red, *green, *blue;
166  int size;
167 
168  size = 1 << bitspersample;
169  if ( planarconfig == PLANARCONFIG_SEPARATE && matteing )
170  samplesperpixel = 1;
171  if (TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue)) {
172  the_hdr.ncolors = 1;
173  the_hdr.ncmap = 3;
175  the_hdr.cmap = (unsigned short *)malloc((unsigned)
176  (3*size*sizeof(short)) );
177  for (i=0; i<size; i++) {
178  the_hdr.cmap[i] = red[i];
179  the_hdr.cmap[i + size] = green[i];
180  the_hdr.cmap[i + 2*size] = blue[i];
181  }
182  } else error("TIFFGetField TIFFTAG_COLORMAP failed!");
183  break;
184  }
185  default:
186  error("tiff file PhotoMetric Interpretation not recognized");
187  }
189  if (the_hdr.ncolors == 3) {
192  }
193 
194  the_hdr.bg_color = NULL;
195  the_hdr.alpha = 0;
196  the_hdr.background = 0;
197  the_hdr.xmin = 0;
198  the_hdr.xmax = imagewidth - 1;
199  the_hdr.ymin = 0;
200  the_hdr.ymax = imagelength - 1;
201 
202  rle_addhist( argv, (rle_hdr *)NULL, &the_hdr );
204 
205  tiffbuf = (unsigned char*)malloc((unsigned)TIFFScanlineSize(tif));
206  if (!tiffbuf) error("can't allocate tiff scanline buffer");
207 
208  get_scanlines();
209 
210  rows[0] = NULL;
211  for ( row = 0; row < the_hdr.ymax + 1; row++) {
212  rows[1] = scan_red[row];
213  if (the_hdr.ncolors == 3) {
214  rows[2] = scan_green[row];
215  rows[3] = scan_blue[row];
216  }
218  }
219 }
220 
221 void
222 get_scanlines()
223 {
224  int i,j,k,l,n;
225 
226  scan_red = (rle_pixel**)malloc(sizeof(rle_pixel*)*(the_hdr.ymax+1));
227  if (!scan_red)
228  error("can't allocate a scan buffer");
229  if (the_hdr.ncolors == 3) {
230  scan_green = (rle_pixel**)malloc(sizeof(rle_pixel*)*(the_hdr.ymax+1));
231  scan_blue = (rle_pixel**)malloc(sizeof(rle_pixel*)*(the_hdr.ymax+1));
232  if (!(scan_green && scan_blue))
233  error("can't allocate a scan buffer");
234  }
235  for (i = 0; i < the_hdr.ymax+1; i++) {
236  if ( !flip )
237  n = the_hdr.ymax - i;
238  else
239  n = i;
240  TIFFReadScanline(tif, tiffbuf, i, 0);
241  scan_red[n] = (unsigned char*)malloc(the_hdr.xmax+1);
242  if (!scan_red[n])
243  error("can't allocate scan buffer");
244  if (the_hdr.ncolors == 3) {
245  scan_green[n] = (unsigned char*)malloc(the_hdr.xmax+1);
246  scan_blue[n] = (unsigned char*)malloc(the_hdr.xmax+1);
247  if (!(scan_green[n] && scan_blue[n]))
248  error("can't allocate scan buffer");
249  }
250  if ( bitspersample == 8 )
251  {
252  for (k = j = 0; j < the_hdr.xmax+1; k+= samplesperpixel, j++) {
253  scan_red[n][j] = tiffbuf[k];
254  if (the_hdr.ncolors == 3) {
255  scan_green[n][j] = tiffbuf[k+1];
256  scan_blue[n][j] = tiffbuf[k+2];
257  }
258  }
259  }
260  else
261  {
262  unsigned char mask = 0xff >> (8 - bitspersample);
263  int phase = 8 / bitspersample, shift = 8 - bitspersample;
264  unsigned char pix;
265 
266  for ( k = j = 0; j <= the_hdr.xmax; j++ )
267  {
268 #define getpixel
269  pix = bitconvert[(tiffbuf[k] >> shift) & mask];
270  if ( --phase == 0 ) {
271  phase = 8 / bitspersample;
272  shift = 8 - bitspersample;
273  k++;
274  }
275  else
276  shift -= bitspersample;
277  getpixel;
278  scan_red[n][j] = pix;
279  if ( the_hdr.ncolors == 3 )
280  {
281  getpixel;
282  scan_green[n][j] = pix;
283  getpixel;
284  scan_blue[n][j] = pix;
285  }
286  /* Skip any other channels (e.g., alpha). */
287  for ( l = samplesperpixel - the_hdr.ncolors; l > 0; l-- )
288  {
289  getpixel;
290  }
291 #undef getpixel
292  }
293  }
294  }
295 }
296 
297 void
298 error(s)
299 CONST_DECL char *s;
300 {
301  fprintf(stderr,"%s: %s in %s\n", the_hdr.cmd, s,
302  TIFFFileName(tif));
303  exit(2);
304 }
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
#define RLE_SET_BIT(glob, bit)
Definition: rle.h:122
#define USE_STDARG
Definition: rle_config.h:24
int xmin
Definition: rle.h:100
TIFF * tif
Definition: tifftorle.c:33
#define USE_PROTOTYPES
Definition: rle_config.h:22
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
Definition: rle_hdr.c:48
static rle_pixel ** scan_red
Definition: tifftorle.c:37
unsigned char bc1[2]
Definition: tifftorle.c:48
char * cmd_name(char **argv)
Definition: cmd_name.c:31
void main(int argc, char **argv)
Definition: aliastorle.c:121
rle_map * cmap
Definition: rle.h:112
#define RLE_GREEN
Definition: rle.h:63
int * bg_color
Definition: rle.h:100
unsigned short samplesperpixel
Definition: tifftorle.c:42
int ymin
Definition: rle.h:100
#define RLE_BLUE
Definition: rle.h:64
unsigned char * tiffbuf
Definition: tifftorle.c:34
static rle_pixel ** scan_blue
Definition: tifftorle.c:39
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
static rle_pixel ** scan_green
Definition: tifftorle.c:38
const char * cmd
Definition: rle.h:133
#define RLE_RED
Definition: rle.h:62
void rle_putrow(rows, int rowlen, rle_hdr *the_hdr)
Definition: rle_putrow.c:96
int xmax
Definition: rle.h:100
#define CONST_DECL
Definition: rle_config.h:42
void rle_addhist(argv, rle_hdr *in_hdr, rle_hdr *out_hdr)
Definition: rle_addhist.c:54
unsigned char bc4[16]
Definition: tifftorle.c:45
unsigned short bitspersample
Definition: tifftorle.c:43
int background
Definition: rle.h:100
int ncmap
Definition: rle.h:100
int ymax
Definition: rle.h:100
static rle_hdr the_hdr
Definition: tifftorle.c:32
unsigned char rle_pixel
Definition: rle.h:56
void rle_put_setup(rle_hdr *the_hdr)
Definition: rle_putrow.c:453
int cmaplen
Definition: rle.h:100
int alpha
Definition: rle.h:100
unsigned char bc2[4]
Definition: tifftorle.c:47
unsigned char bitconvert[16]
Definition: tifftorle.c:44
int flip
Definition: tifftorle.c:41
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
FILE * rle_file
Definition: rle.h:114
int ncolors
Definition: rle.h:100
#define getpixel