2
** tifftopnm.c - converts a Tagged Image File to a portable anymap
4
** Derived by Jef Poskanzer from tif2ras.c, which is:
6
** Copyright (c) 1990 by Sun Microsystems, Inc.
8
** Author: Patrick J. Naughton
9
** naughton@wind.sun.com
11
** Permission to use, copy, modify, and distribute this software and its
12
** documentation for any purpose and without fee is hereby granted,
13
** provided that the above copyright notice appear in all copies and that
14
** both that copyright notice and this permission notice appear in
15
** supporting documentation.
17
** This file is provided AS IS with no warranties of any kind. The author
18
** shall have no liability with respect to the infringement of copyrights,
19
** trade secrets or any patents by this file or any part thereof. In no
20
** event will the author be liable for any lost revenue or profits or
21
** other special, indirect and consequential damages.
33
#define MAXCOLORS 1024
34
#ifndef PHOTOMETRIC_DEPTH
35
#define PHOTOMETRIC_DEPTH 32768
39
checkcmap(unsigned short *r, unsigned short *g, unsigned short *b,
45
if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
55
int argn, cols, rows, grayscale, format;
61
u_char* buf,*bufr,*bufg,*bufb;
66
xel colormap[MAXCOLORS];
67
int headerdump, scale8bp, nolut;
68
register u_char sample;
69
register int bitsleft;
70
unsigned short bps, spp, photomet;
71
unsigned short* redcolormap;
72
unsigned short* greencolormap;
73
unsigned short* bluecolormap;
74
char* usage = "[-headerdump -8bpalette -nolut] [tifffile]";
77
pnm_init( &argc, argv );
84
while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
86
if ( pm_keymatch( argv[argn], "-headerdump", 2 ) )
88
else if ( pm_keymatch( argv[argn], "-8bpalette", 2 ) )
90
else if ( pm_keymatch( argv[argn], "-nolut", 2 ) )
99
tif = TIFFOpen( argv[argn], "r" );
101
pm_error( "error opening TIFF file %s", argv[argn] );
106
tif = TIFFFdOpen( 0, "Standard Input", "r" );
108
pm_error( "error opening standard input as TIFF file" );
115
TIFFPrintDirectory( tif, stderr, TIFFPRINT_NONE );
117
if ( ! TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bps ) )
119
if ( ! TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &spp ) )
121
if ( ! TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photomet ) )
122
pm_error( "error getting photometric" );
133
"can only handle 1-channel gray scale or 1- or 3-channel color" );
136
(void) TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &cols );
137
(void) TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &rows );
138
TIFFGetField( tif, TIFFTAG_PLANARCONFIG, &plan);
142
pm_message( "%dx%dx%d image", cols, rows, bps * spp );
143
pm_message( "%d bits/sample, %d samples/pixel", bps, spp );
146
maxval = ( 1 << bps ) - 1;
147
if ( maxval == 1 && spp == 1 )
150
pm_message("monochrome" );
157
case PHOTOMETRIC_MINISBLACK:
159
pm_message( "%d graylevels (min=black)", maxval + 1 );
163
case PHOTOMETRIC_MINISWHITE:
165
pm_message( "%d graylevels (min=white)", maxval + 1 );
169
case PHOTOMETRIC_PALETTE:
171
pm_message( "colormapped" );
173
if ( ! TIFFGetField( tif, TIFFTAG_COLORMAP, &redcolormap, &greencolormap, &bluecolormap ) )
174
pm_error( "error getting colormaps" );
175
numcolors = maxval + 1;
176
if ( numcolors > MAXCOLORS )
177
pm_error( "too many colors" );
178
maxval = PNM_MAXMAXVAL;
180
/* do the conversion only if necessary due to PNM_MAXMAXVAL
181
being smaller than the largest possible colormap entry,
182
saves you trouble with rounding errors, etc. (CS) */
183
if (PNM_MAXMAXVAL < 65535L)
184
for ( i = 0; i < numcolors; ++i )
186
register xelval r, g, b;
187
r = (long) redcolormap[i] * PNM_MAXMAXVAL / 65535L;
188
g = (long) greencolormap[i] * PNM_MAXMAXVAL / 65535L;
189
b = (long) bluecolormap[i] * PNM_MAXMAXVAL / 65535L;
190
PPM_ASSIGN( colormap[i], r, g, b );
191
fprintf(stderr,"in: %hu, out: %d\n",greencolormap[i],g);
194
if (checkcmap(redcolormap,greencolormap,bluecolormap,bps) == 16
196
for ( i = 0; i < numcolors; ++i )
198
register xelval r, g, b;
199
r = redcolormap[i] >> 8;
200
g = greencolormap[i] >> 8;
201
b = bluecolormap[i] >> 8;
202
PPM_ASSIGN( colormap[i], r, g, b );
203
fprintf(stderr,"case2: in: %hu, out: %d\n",
207
for ( i = 0; i < numcolors; ++i )
209
register xelval r, g, b;
211
g = greencolormap[i];
213
PPM_ASSIGN( colormap[i], r, g, b );
214
fprintf(stderr,"case2: in: %hu, out: %d\n",
221
case PHOTOMETRIC_RGB:
223
pm_message( "truecolor" );
227
case PHOTOMETRIC_MASK:
228
pm_error( "don't know how to handle PHOTOMETRIC_MASK" );
230
case PHOTOMETRIC_DEPTH:
231
pm_error( "don't know how to handle PHOTOMETRIC_DEPTH" );
234
pm_error( "unknown photometric: %d", photomet );
237
if ( maxval > PNM_MAXMAXVAL )
239
"bits/sample is too large - try reconfiguring with PGM_BIGGRAYS\n or without PPM_PACKCOLORS" );
247
pm_message( "writing PBM file" );
252
pm_message( "writing PGM file" );
258
pm_message( "writing PPM file" );
261
pm_message( "The scanlinesize is %d\n",TIFFScanlineSize(tif));
262
pm_message( "With planar configuration %u\n",plan);
264
sz = TIFFScanlineSize(tif);
267
buf = (u_char*) malloc(sz);
270
tsize_t szl = TIFFScanlineSize(tif);
277
pm_error( "can't allocate memory for scanline buffer" );
278
pnm_writepnminit( stdout, cols, rows, (xelval) maxval, format, 0 );
279
xelrow = pnm_allocrow( cols );
283
if ( bitsleft == 0 ) \
289
sample = ( *inP >> bitsleft ) & maxval; \
292
for ( row = 0; row < rows; ++row )
294
if (plan ==2 && photomet == PHOTOMETRIC_RGB) {
295
if ( TIFFReadScanline( tif, bufr, row, 0 ) < 0 )
296
pm_error( "bad data read on line %d", row );
297
if ( TIFFReadScanline( tif, bufg, row, 1 ) < 0 )
298
pm_error( "bad data read on line %d", row );
299
if ( TIFFReadScanline( tif, bufb, row, 2 ) < 0 )
300
pm_error( "bad data read on line %d", row );
303
if ( TIFFReadScanline( tif, buf, row, 0 ) < 0 )
304
pm_error( "bad data read on line %d", row );
312
case PHOTOMETRIC_MINISBLACK:
313
for ( col = 0; col < cols; ++col, ++xP )
316
PNM_ASSIGN1( *xP, sample );
320
case PHOTOMETRIC_MINISWHITE:
321
for ( col = 0; col < cols; ++col, ++xP )
324
sample = maxval - sample;
325
PNM_ASSIGN1( *xP, sample );
329
case PHOTOMETRIC_PALETTE:
331
for ( col = 0; col < cols; ++col, ++xP )
334
*xP = colormap[sample];
337
for ( col = 0; col < cols; ++col, ++xP )
340
PNM_ASSIGN1( *xP, sample );
344
case PHOTOMETRIC_RGB:
345
for ( col = 0; col < cols; ++col, ++xP )
347
register xelval r, g, b;
357
NEXTSAMPLE /* skip alpha channel */
364
PPM_ASSIGN( *xP, r, g, b );
369
pm_error( "unknown photometric: %d", photomet );
371
pnm_writepnmrow( stdout, xelrow, cols, (xelval) maxval, format, 0 );