~ubuntu-branches/ubuntu/lucid/pdl/lucid

« back to all changes in this revision

Viewing changes to IO/Pnm/converters/tifftopnm.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Gertzfield
  • Date: 2002-04-08 18:47:16 UTC
  • Revision ID: james.westby@ubuntu.com-20020408184716-0hf64dc96kin3htp
Tags: upstream-2.3.2
ImportĀ upstreamĀ versionĀ 2.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
** tifftopnm.c - converts a Tagged Image File to a portable anymap
 
3
**
 
4
** Derived by Jef Poskanzer from tif2ras.c, which is:
 
5
**
 
6
** Copyright (c) 1990 by Sun Microsystems, Inc.
 
7
**
 
8
** Author: Patrick J. Naughton
 
9
** naughton@wind.sun.com
 
10
**
 
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.
 
16
**
 
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.
 
22
*/
 
23
 
 
24
#include "pnm.h"
 
25
#ifdef VMS
 
26
#ifdef SYSV
 
27
#undef SYSV
 
28
#endif
 
29
#include <tiffioP.h>
 
30
#endif
 
31
#include <tiffio.h>
 
32
 
 
33
#define MAXCOLORS 1024
 
34
#ifndef PHOTOMETRIC_DEPTH
 
35
#define PHOTOMETRIC_DEPTH 32768
 
36
#endif
 
37
 
 
38
static int
 
39
checkcmap(unsigned short *r, unsigned short *g, unsigned short *b,
 
40
          unsigned short bps)
 
41
{
 
42
    long n = 1L<<bps;
 
43
 
 
44
    while (n-- > 0)
 
45
        if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
 
46
            return (16);
 
47
    return (8);
 
48
}
 
49
 
 
50
int
 
51
main( argc, argv )
 
52
    int argc;
 
53
    char* argv[];
 
54
    {
 
55
    int argn, cols, rows, grayscale, format;
 
56
    uint16 plan;
 
57
    int numcolors;
 
58
    register TIFF* tif;
 
59
    int row, i;
 
60
    register int col;
 
61
    u_char* buf,*bufr,*bufg,*bufb;
 
62
    register u_char* inP;
 
63
    int maxval;
 
64
    xel* xelrow;
 
65
    register xel* xP;
 
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]";
 
75
    tsize_t sz;
 
76
 
 
77
    pnm_init( &argc, argv );
 
78
 
 
79
    argn = 1;
 
80
    headerdump = 0;
 
81
    scale8bp = 0;
 
82
    nolut = 0;
 
83
 
 
84
    while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
 
85
        {
 
86
        if ( pm_keymatch( argv[argn], "-headerdump", 2 ) )
 
87
            headerdump = 1;
 
88
        else if ( pm_keymatch( argv[argn], "-8bpalette", 2 ) )
 
89
            scale8bp = 1;
 
90
       else if ( pm_keymatch( argv[argn], "-nolut", 2 ) )
 
91
           nolut = 1;
 
92
        else
 
93
            pm_usage( usage );
 
94
        ++argn;
 
95
        }
 
96
 
 
97
    if ( argn != argc )
 
98
        {
 
99
        tif = TIFFOpen( argv[argn], "r" );
 
100
        if ( tif == NULL )
 
101
            pm_error( "error opening TIFF file %s", argv[argn] );
 
102
        ++argn;
 
103
        }
 
104
    else
 
105
        {
 
106
        tif = TIFFFdOpen( 0, "Standard Input", "r" );
 
107
        if ( tif == NULL )
 
108
            pm_error( "error opening standard input as TIFF file" );
 
109
        }
 
110
 
 
111
    if ( argn != argc )
 
112
        pm_usage( usage );
 
113
 
 
114
    if ( headerdump )
 
115
        TIFFPrintDirectory( tif, stderr, TIFFPRINT_NONE );
 
116
 
 
117
    if ( ! TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bps ) )
 
118
        bps = 1;
 
119
    if ( ! TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &spp ) )
 
120
        spp = 1;
 
121
    if ( ! TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photomet ) )
 
122
        pm_error( "error getting photometric" );
 
123
 
 
124
    switch ( spp )
 
125
        {
 
126
        case 1:
 
127
        case 3:
 
128
        case 4:
 
129
        break;
 
130
 
 
131
        default:
 
132
        pm_error(
 
133
            "can only handle 1-channel gray scale or 1- or 3-channel color" );
 
134
        }
 
135
 
 
136
    (void) TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &cols );
 
137
    (void) TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &rows );
 
138
    TIFFGetField( tif, TIFFTAG_PLANARCONFIG, &plan);
 
139
 
 
140
    if ( headerdump )
 
141
        {
 
142
        pm_message( "%dx%dx%d image", cols, rows, bps * spp );
 
143
        pm_message( "%d bits/sample, %d samples/pixel", bps, spp );
 
144
        }
 
145
 
 
146
    maxval = ( 1 << bps ) - 1;
 
147
    if ( maxval == 1 && spp == 1 )
 
148
        {
 
149
        if ( headerdump )
 
150
            pm_message("monochrome" );
 
151
        grayscale = 1;
 
152
        }
 
153
    else
 
154
        {
 
155
        switch ( photomet )
 
156
            {
 
157
            case PHOTOMETRIC_MINISBLACK:
 
158
            if ( headerdump )
 
159
                pm_message( "%d graylevels (min=black)", maxval + 1 );
 
160
            grayscale = 1;
 
161
            break;
 
162
 
 
163
            case PHOTOMETRIC_MINISWHITE:
 
164
            if ( headerdump )
 
165
                pm_message( "%d graylevels (min=white)", maxval + 1 );
 
166
            grayscale = 1;
 
167
            break;
 
168
 
 
169
            case PHOTOMETRIC_PALETTE:
 
170
            if ( headerdump )
 
171
             pm_message( "colormapped" );
 
172
           if (!nolut) {
 
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;
 
179
             grayscale = 0;
 
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 )
 
185
                  {
 
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);
 
192
                  }
 
193
              else
 
194
               if (checkcmap(redcolormap,greencolormap,bluecolormap,bps) == 16
 
195
                   && scale8bp) 
 
196
                 for ( i = 0; i < numcolors; ++i )
 
197
                   {
 
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",
 
204
                             greencolormap[i],g);
 
205
                   }
 
206
               else
 
207
                 for ( i = 0; i < numcolors; ++i )
 
208
                   {
 
209
                     register xelval r, g, b;
 
210
                     r = redcolormap[i];
 
211
                     g = greencolormap[i];
 
212
                     b = bluecolormap[i];
 
213
                     PPM_ASSIGN( colormap[i], r, g, b );
 
214
                     fprintf(stderr,"case2: in: %hu, out: %d\n",
 
215
                             greencolormap[i],g);
 
216
                   }
 
217
           } else
 
218
             grayscale = 1;
 
219
            break;
 
220
 
 
221
            case PHOTOMETRIC_RGB:
 
222
            if ( headerdump )
 
223
                pm_message( "truecolor" );
 
224
            grayscale = 0;
 
225
            break;
 
226
 
 
227
            case PHOTOMETRIC_MASK:
 
228
            pm_error( "don't know how to handle PHOTOMETRIC_MASK" );
 
229
 
 
230
            case PHOTOMETRIC_DEPTH:
 
231
            pm_error( "don't know how to handle PHOTOMETRIC_DEPTH" );
 
232
 
 
233
            default:
 
234
            pm_error( "unknown photometric: %d", photomet );
 
235
            }
 
236
        }
 
237
    if ( maxval > PNM_MAXMAXVAL )
 
238
        pm_error(
 
239
"bits/sample is too large - try reconfiguring with PGM_BIGGRAYS\n    or without PPM_PACKCOLORS" );
 
240
 
 
241
 
 
242
    if ( grayscale )
 
243
        {
 
244
        if ( maxval == 1 )
 
245
            {
 
246
            format = PBM_TYPE;
 
247
            pm_message( "writing PBM file" );
 
248
            }
 
249
        else
 
250
            {
 
251
            format = PGM_TYPE;
 
252
            pm_message( "writing PGM file" );
 
253
            }
 
254
        }
 
255
    else
 
256
        {
 
257
        format = PPM_TYPE;
 
258
        pm_message( "writing PPM file" );
 
259
        }
 
260
 
 
261
    pm_message( "The scanlinesize is %d\n",TIFFScanlineSize(tif));
 
262
    pm_message( "With planar configuration %u\n",plan);
 
263
 
 
264
    sz = TIFFScanlineSize(tif);
 
265
    if (plan == 2)
 
266
      sz *= spp;
 
267
    buf = (u_char*) malloc(sz);
 
268
    if (plan == 2)
 
269
      {
 
270
        tsize_t szl = TIFFScanlineSize(tif);
 
271
        bufr = buf;
 
272
        bufg = buf + szl;
 
273
        bufb = bufg + szl;
 
274
      }
 
275
 
 
276
    if ( buf == NULL )
 
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 );
 
280
 
 
281
#define NEXTSAMPLE \
 
282
    { \
 
283
    if ( bitsleft == 0 ) \
 
284
        { \
 
285
        ++inP; \
 
286
        bitsleft = 8; \
 
287
        } \
 
288
    bitsleft -= bps; \
 
289
    sample = ( *inP >> bitsleft ) & maxval; \
 
290
    }
 
291
 
 
292
    for ( row = 0; row < rows; ++row )
 
293
        {
 
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 );
 
301
          }
 
302
          else
 
303
            if ( TIFFReadScanline( tif, buf, row, 0 ) < 0 )
 
304
              pm_error( "bad data read on line %d", row );
 
305
 
 
306
        inP = buf;
 
307
        bitsleft = 8;
 
308
        xP = xelrow;
 
309
 
 
310
        switch ( photomet )
 
311
            {
 
312
            case PHOTOMETRIC_MINISBLACK:
 
313
            for ( col = 0; col < cols; ++col, ++xP )
 
314
                {
 
315
                NEXTSAMPLE
 
316
                PNM_ASSIGN1( *xP, sample );
 
317
                }
 
318
            break;
 
319
 
 
320
            case PHOTOMETRIC_MINISWHITE:
 
321
            for ( col = 0; col < cols; ++col, ++xP )
 
322
                {
 
323
                NEXTSAMPLE
 
324
                sample = maxval - sample;
 
325
                PNM_ASSIGN1( *xP, sample );
 
326
                }
 
327
            break;
 
328
 
 
329
            case PHOTOMETRIC_PALETTE:
 
330
             if (!nolut)
 
331
               for ( col = 0; col < cols; ++col, ++xP )
 
332
                 {
 
333
                   NEXTSAMPLE
 
334
                     *xP = colormap[sample];
 
335
                 }
 
336
             else 
 
337
               for ( col = 0; col < cols; ++col, ++xP )
 
338
                 {
 
339
                   NEXTSAMPLE
 
340
                     PNM_ASSIGN1( *xP, sample );
 
341
                 }
 
342
            break;
 
343
 
 
344
            case PHOTOMETRIC_RGB:
 
345
            for ( col = 0; col < cols; ++col, ++xP )
 
346
                {
 
347
                register xelval r, g, b;
 
348
 
 
349
                if (plan != 2) {
 
350
                  NEXTSAMPLE
 
351
                    r = sample;
 
352
                  NEXTSAMPLE
 
353
                    g = sample;
 
354
                  NEXTSAMPLE
 
355
                    b = sample;
 
356
                  if ( spp == 4 )
 
357
                    NEXTSAMPLE          /* skip alpha channel */
 
358
                      }
 
359
                else {
 
360
                  r = bufr[col];
 
361
                  g = bufg[col];
 
362
                  b = bufb[col];
 
363
                }
 
364
                PPM_ASSIGN( *xP, r, g, b );
 
365
                }
 
366
            break;
 
367
 
 
368
            default:
 
369
            pm_error( "unknown photometric: %d", photomet );
 
370
            }
 
371
        pnm_writepnmrow( stdout, xelrow, cols, (xelval) maxval, format, 0 );
 
372
        }
 
373
 
 
374
    pm_close( stdout );
 
375
    exit( 0 );
 
376
    }