~ubuntu-branches/ubuntu/karmic/tiff/karmic-security

« back to all changes in this revision

Viewing changes to tools/tiffcp.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabio M. Di Nitto
  • Date: 2004-10-14 07:57:59 UTC
  • Revision ID: james.westby@ubuntu.com-20041014075759-a77e7zuaetya8cp0
Tags: upstream-3.6.1
ImportĀ upstreamĀ versionĀ 3.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Header: /cvsroot/osrs/libtiff/tools/tiffcp.c,v 1.15 2003/12/20 13:46:57 dron Exp $ */
 
2
 
 
3
/*
 
4
 * Copyright (c) 1988-1997 Sam Leffler
 
5
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
 
6
 *
 
7
 *  Revised:  2/18/01 BAR -- added syntax for extracting single images from
 
8
 *                          multi-image TIFF files.
 
9
 *
 
10
 *    New syntax is:  sourceFileName,image#
 
11
 *
 
12
 * image# ranges from 0..<n-1> where n is the # of images in the file.
 
13
 * There may be no white space between the comma and the filename or
 
14
 * image number.
 
15
 *
 
16
 *    Example:   tiffcp source.tif,1 destination.tif
 
17
 *
 
18
 * Copies the 2nd image in source.tif to the destination.
 
19
 *
 
20
 *****
 
21
 * Permission to use, copy, modify, distribute, and sell this software and 
 
22
 * its documentation for any purpose is hereby granted without fee, provided
 
23
 * that (i) the above copyright notices and this permission notice appear in
 
24
 * all copies of the software and related documentation, and (ii) the names of
 
25
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
 
26
 * publicity relating to the software without the specific, prior written
 
27
 * permission of Sam Leffler and Silicon Graphics.
 
28
 * 
 
29
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
 
30
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
 
31
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
 
32
 * 
 
33
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
 
34
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
 
35
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 
36
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
 
37
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
 
38
 * OF THIS SOFTWARE.
 
39
 */
 
40
 
 
41
#include <stdio.h>
 
42
#include <stdlib.h>
 
43
#include <string.h>
 
44
 
 
45
#include <ctype.h>
 
46
#include <assert.h>
 
47
 
 
48
#include "tiffio.h"
 
49
 
 
50
#if defined(VMS)
 
51
#define unlink delete
 
52
#endif
 
53
 
 
54
#define streq(a,b)      (strcmp(a,b) == 0)
 
55
#define strneq(a,b,n)   (strncmp(a,b,n) == 0)
 
56
 
 
57
#define TRUE    1
 
58
#define FALSE   0
 
59
 
 
60
static  int outtiled = -1;
 
61
static  uint32 tilewidth;
 
62
static  uint32 tilelength;
 
63
 
 
64
static  uint16 config;
 
65
static  uint16 compression;
 
66
static  uint16 predictor;
 
67
static  uint16 fillorder;
 
68
static  uint16 orientation;
 
69
static  uint32 rowsperstrip;
 
70
static  uint32 g3opts;
 
71
static  int ignore = FALSE;             /* if true, ignore read errors */
 
72
static  uint32 defg3opts = (uint32) -1;
 
73
static  int quality = 75;               /* JPEG quality */
 
74
static  int jpegcolormode = JPEGCOLORMODE_RGB;
 
75
static  uint16 defcompression = (uint16) -1;
 
76
static  uint16 defpredictor = (uint16) -1;
 
77
 
 
78
static  int tiffcp(TIFF*, TIFF*);
 
79
static  int processCompressOptions(char*);
 
80
static  void usage(void);
 
81
 
 
82
static char comma = ',';  /* (default) comma separator character */
 
83
static TIFF* bias = NULL;
 
84
static int pageNum = 0;
 
85
 
 
86
static int nextSrcImage (TIFF *tif, char **imageSpec)
 
87
/*
 
88
  seek to the next image specified in *imageSpec
 
89
  returns 1 if success, 0 if no more images to process
 
90
  *imageSpec=NULL if subsequent images should be processed in sequence
 
91
*/
 
92
{
 
93
  if (**imageSpec == comma) {  /* if not @comma, we've done all images */
 
94
    char *start = *imageSpec + 1;
 
95
    unsigned long nextImage = strtol (start, imageSpec, 0);
 
96
    if (start == *imageSpec) nextImage = TIFFCurrentDirectory (tif);
 
97
    if (**imageSpec)
 
98
    {
 
99
      if (**imageSpec == comma) {  
 
100
        /* a trailing comma denotes remaining images in sequence */
 
101
        if ((*imageSpec)[1] == '\0') *imageSpec = NULL;
 
102
      }else{
 
103
        fprintf (stderr, 
 
104
          "Expected a %c separated image # list after %s\n",
 
105
          comma, TIFFFileName (tif));
 
106
        exit (-4);   /* syntax error */
 
107
      }
 
108
    }
 
109
    if (TIFFSetDirectory (tif, nextImage)) return 1;  
 
110
    fprintf (stderr, "%s%c%d not found!\n", 
 
111
             TIFFFileName(tif), comma, (int) nextImage); 
 
112
  }
 
113
  return 0;
 
114
}
 
115
 
 
116
  
 
117
static TIFF* openSrcImage (char **imageSpec)
 
118
/*
 
119
  imageSpec points to a pointer to a filename followed by optional ,image#'s
 
120
  Open the TIFF file and assign *imageSpec to either NULL if there are
 
121
  no images specified, or a pointer to the next image number text
 
122
*/
 
123
{
 
124
    TIFF *tif;
 
125
    char *fn = *imageSpec;
 
126
    *imageSpec = strchr (fn, comma);
 
127
    if (*imageSpec) {  /* there is at least one image number specifier */
 
128
        **imageSpec = '\0'; 
 
129
        tif = TIFFOpen (fn, "r");
 
130
        /* but, ignore any single trailing comma */
 
131
        if (!(*imageSpec)[1]) {*imageSpec = NULL; return tif;}
 
132
        if (tif) { 
 
133
            **imageSpec = comma;  /* replace the comma */
 
134
            if (!nextSrcImage(tif, imageSpec)) {
 
135
              TIFFClose (tif);
 
136
              tif = NULL;
 
137
            }
 
138
        }
 
139
    }else
 
140
        tif = TIFFOpen (fn, "r");
 
141
    return tif;
 
142
}
 
143
 
 
144
 
 
145
int
 
146
main(int argc, char* argv[])
 
147
{
 
148
        uint16 defconfig = (uint16) -1;
 
149
        uint16 deffillorder = 0;
 
150
        uint32 deftilewidth = (uint32) -1;
 
151
        uint32 deftilelength = (uint32) -1;
 
152
        uint32 defrowsperstrip = (uint32) 0;
 
153
        uint32 diroff = 0;
 
154
        TIFF* in;
 
155
        TIFF* out;
 
156
        char mode[10];
 
157
        char* mp = mode;
 
158
        int c;
 
159
        extern int optind;
 
160
        extern char* optarg;
 
161
 
 
162
        *mp++ = 'w';
 
163
        *mp = '\0';
 
164
        while ((c = getopt(argc, argv, ",:b:c:f:l:o:z:p:r:w:aistBLMC")) != -1)
 
165
                switch (c) {
 
166
                case ',':
 
167
                        if (optarg[0] != '=') usage();
 
168
                        comma = optarg[1];
 
169
                        break;
 
170
                case 'b':   /* this file is bias image subtracted from others */
 
171
                        if (bias) {
 
172
                          fputs ("Only 1 bias image may be specified\n", stderr);
 
173
                          exit (-2);
 
174
                        }
 
175
                        {
 
176
                          uint16    samples = (uint16) -1;
 
177
                          char **biasFn = &optarg;
 
178
                          bias = openSrcImage (biasFn);
 
179
                          if (!bias) exit (-5);
 
180
                          if (TIFFIsTiled (bias)) {
 
181
                     fputs ("Bias image must be organized in strips\n", stderr);
 
182
                            exit (-7);
 
183
                          }
 
184
                          TIFFGetField(bias, TIFFTAG_SAMPLESPERPIXEL, &samples);
 
185
                          if (samples != 1) {
 
186
                     fputs ("Bias image must be monochrome\n", stderr);
 
187
                            exit (-7);
 
188
                          }
 
189
                        }
 
190
                        break;
 
191
                case 'a':               /* append to output */
 
192
                        mode[0] = 'a';
 
193
                        break;
 
194
                case 'c':               /* compression scheme */
 
195
                        if (!processCompressOptions(optarg))
 
196
                                usage();
 
197
                        break;
 
198
                case 'f':               /* fill order */
 
199
                        if (streq(optarg, "lsb2msb"))
 
200
                                deffillorder = FILLORDER_LSB2MSB;
 
201
                        else if (streq(optarg, "msb2lsb"))
 
202
                                deffillorder = FILLORDER_MSB2LSB;
 
203
                        else
 
204
                                usage();
 
205
                        break;
 
206
                case 'i':               /* ignore errors */
 
207
                        ignore = TRUE;
 
208
                        break;
 
209
                case 'l':               /* tile length */
 
210
                        outtiled = TRUE;
 
211
                        deftilelength = atoi(optarg);
 
212
                        break;
 
213
                case 'o':               /* initial directory offset */
 
214
                        diroff = strtoul(optarg, NULL, 0);
 
215
                        break;
 
216
                case 'p':               /* planar configuration */
 
217
                        if (streq(optarg, "separate"))
 
218
                                defconfig = PLANARCONFIG_SEPARATE;
 
219
                        else if (streq(optarg, "contig"))
 
220
                                defconfig = PLANARCONFIG_CONTIG;
 
221
                        else
 
222
                                usage();
 
223
                        break;
 
224
                case 'r':               /* rows/strip */
 
225
                        defrowsperstrip = atol(optarg);
 
226
                        break;
 
227
                case 's':               /* generate stripped output */
 
228
                        outtiled = FALSE;
 
229
                        break;
 
230
                case 't':               /* generate tiled output */
 
231
                        outtiled = TRUE;
 
232
                        break;
 
233
                case 'w':               /* tile width */
 
234
                        outtiled = TRUE;
 
235
                        deftilewidth = atoi(optarg);
 
236
                        break;
 
237
                case 'B':
 
238
                        *mp++ = 'b'; *mp = '\0';
 
239
                        break;
 
240
                case 'L':
 
241
                        *mp++ = 'l'; *mp = '\0';
 
242
                        break;
 
243
                case 'M':
 
244
                        *mp++ = 'm'; *mp = '\0';
 
245
                        break;
 
246
                case 'C':
 
247
                        *mp++ = 'c'; *mp = '\0';
 
248
                        break;
 
249
                case '?':
 
250
                        usage();
 
251
                        /*NOTREACHED*/
 
252
                }
 
253
        if (argc - optind < 2)
 
254
                usage();
 
255
        out = TIFFOpen(argv[argc-1], mode);
 
256
        if (out == NULL)
 
257
                return (-2);
 
258
        if ((argc - optind) == 2)
 
259
          pageNum = -1;
 
260
        for (; optind < argc-1 ; optind++) {
 
261
                char *imageCursor = argv[optind];
 
262
                in = openSrcImage (&imageCursor);
 
263
                if (in == NULL)
 
264
                        return (-3);
 
265
                if (diroff != 0 && !TIFFSetSubDirectory(in, diroff)) {
 
266
                        TIFFError(TIFFFileName(in),
 
267
                            "Error, setting subdirectory at %#x", diroff);
 
268
                        (void) TIFFClose(out);
 
269
                        return (1);
 
270
                }
 
271
                for (;;) {
 
272
                   config = defconfig;
 
273
                   compression = defcompression;
 
274
                   predictor = defpredictor;
 
275
                   fillorder = deffillorder;
 
276
                   rowsperstrip = defrowsperstrip;
 
277
                   tilewidth = deftilewidth;
 
278
                   tilelength = deftilelength;
 
279
                   g3opts = defg3opts;
 
280
                   if (!tiffcp(in, out) || !TIFFWriteDirectory(out)) {
 
281
                        TIFFClose(out);
 
282
                        return (1);
 
283
                   }
 
284
                   if (imageCursor) { /* seek next image directory */
 
285
                        if (!nextSrcImage(in, &imageCursor)) break;
 
286
                   }else
 
287
                        if (!TIFFReadDirectory(in)) break;
 
288
                }
 
289
                TIFFClose(in);
 
290
        }
 
291
 
 
292
        exit( 0 );
 
293
}
 
294
 
 
295
 
 
296
static void
 
297
processG3Options(char* cp)
 
298
{
 
299
        if( (cp = strchr(cp, ':')) ) {
 
300
                if (defg3opts == (uint32) -1)
 
301
                        defg3opts = 0;
 
302
                do {
 
303
                        cp++;
 
304
                        if (strneq(cp, "1d", 2))
 
305
                                defg3opts &= ~GROUP3OPT_2DENCODING;
 
306
                        else if (strneq(cp, "2d", 2))
 
307
                                defg3opts |= GROUP3OPT_2DENCODING;
 
308
                        else if (strneq(cp, "fill", 4))
 
309
                                defg3opts |= GROUP3OPT_FILLBITS;
 
310
                        else
 
311
                                usage();
 
312
                } while( (cp = strchr(cp, ':')) );
 
313
        }
 
314
}
 
315
 
 
316
static int
 
317
processCompressOptions(char* opt)
 
318
{
 
319
        if (streq(opt, "none")) {
 
320
                defcompression = COMPRESSION_NONE;
 
321
        } else if (streq(opt, "packbits")) {
 
322
                defcompression = COMPRESSION_PACKBITS;
 
323
        } else if (strneq(opt, "jpeg", 4)) {
 
324
                char* cp = strchr(opt, ':');
 
325
                if (cp && isdigit(cp[1]))
 
326
                        quality = atoi(cp+1);
 
327
                if (cp && strchr(cp, 'r'))
 
328
                        jpegcolormode = JPEGCOLORMODE_RAW;
 
329
                defcompression = COMPRESSION_JPEG;
 
330
        } else if (strneq(opt, "g3", 2)) {
 
331
                processG3Options(opt);
 
332
                defcompression = COMPRESSION_CCITTFAX3;
 
333
        } else if (streq(opt, "g4")) {
 
334
                defcompression = COMPRESSION_CCITTFAX4;
 
335
        } else if (strneq(opt, "lzw", 3)) {
 
336
                char* cp = strchr(opt, ':');
 
337
                if (cp)
 
338
                        defpredictor = atoi(cp+1);
 
339
                defcompression = COMPRESSION_LZW;
 
340
        } else if (strneq(opt, "zip", 3)) {
 
341
                char* cp = strchr(opt, ':');
 
342
                if (cp)
 
343
                        defpredictor = atoi(cp+1);
 
344
                defcompression = COMPRESSION_DEFLATE;
 
345
        } else
 
346
                return (0);
 
347
        return (1);
 
348
}
 
349
 
 
350
char* stuff[] = {
 
351
"usage: tiffcp [options] input... output",
 
352
"where options are:",
 
353
" -a            append to output instead of overwriting",
 
354
" -o offset     set initial directory offset",
 
355
" -p contig     pack samples contiguously (e.g. RGBRGB...)",
 
356
" -p separate   store samples separately (e.g. RRR...GGG...BBB...)",
 
357
" -s            write output in strips",
 
358
" -t            write output in tiles",
 
359
" -i            ignore read errors",
 
360
" -b file[,#]   bias (dark) monochrome image to be subtracted from all others",
 
361
" -,=%          use % rather than , to separate image #'s (per Note below)",           
 
362
"",
 
363
" -r #          make each strip have no more than # rows",
 
364
" -w #          set output tile width (pixels)",
 
365
" -l #          set output tile length (pixels)",
 
366
"",
 
367
" -f lsb2msb    force lsb-to-msb FillOrder for output",
 
368
" -f msb2lsb    force msb-to-lsb FillOrder for output",
 
369
"",
 
370
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
 
371
"               (no longer supported by default due to Unisys patent enforcement)", 
 
372
" -c zip[:opts] compress output with deflate encoding",
 
373
" -c jpeg[:opts]        compress output with JPEG encoding",
 
374
" -c packbits   compress output with packbits encoding",
 
375
" -c g3[:opts]  compress output with CCITT Group 3 encoding",
 
376
" -c g4         compress output with CCITT Group 4 encoding",
 
377
" -c none       use no compression algorithm on output",
 
378
"",
 
379
"Group 3 options:",
 
380
" 1d            use default CCITT Group 3 1D-encoding",
 
381
" 2d            use optional CCITT Group 3 2D-encoding",
 
382
" fill          byte-align EOL codes",
 
383
"For example, -c g3:2d:fill to get G3-2D-encoded data with byte-aligned EOLs",
 
384
"",
 
385
"JPEG options:",
 
386
" #             set compression quality level (0-100, default 75)",
 
387
" r             output color image as RGB rather than YCbCr",
 
388
"For example, -c jpeg:r:50 to get JPEG-encoded RGB data with 50% comp. quality",
 
389
"",
 
390
"LZW and deflate options:",
 
391
" #             set predictor value",
 
392
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
 
393
"",
 
394
"Note that input filenames may be of the form filename,x,y,z",
 
395
"where x, y, and z specify image numbers in the filename to copy.",
 
396
"example:  tiffcp -c none -b esp.tif,1 esp.tif,0 test.tif",
 
397
"  subtract 2nd image in esp.tif from 1st yielding uncompressed result test.tif",
 
398
NULL
 
399
};
 
400
 
 
401
static void
 
402
usage(void)
 
403
{
 
404
        char buf[BUFSIZ];
 
405
        int i;
 
406
 
 
407
        setbuf(stderr, buf);
 
408
        fprintf(stderr, "%s\n\n", TIFFGetVersion());
 
409
        for (i = 0; stuff[i] != NULL; i++)
 
410
                fprintf(stderr, "%s\n", stuff[i]);
 
411
        exit(-1);
 
412
}
 
413
 
 
414
#define CopyField(tag, v) \
 
415
    if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
 
416
#define CopyField2(tag, v1, v2) \
 
417
    if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
 
418
#define CopyField3(tag, v1, v2, v3) \
 
419
    if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
 
420
#define CopyField4(tag, v1, v2, v3, v4) \
 
421
    if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4)
 
422
 
 
423
static void
 
424
cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type)
 
425
{
 
426
        switch (type) {
 
427
        case TIFF_SHORT:
 
428
                if (count == 1) {
 
429
                        uint16 shortv;
 
430
                        CopyField(tag, shortv);
 
431
                } else if (count == 2) {
 
432
                        uint16 shortv1, shortv2;
 
433
                        CopyField2(tag, shortv1, shortv2);
 
434
                } else if (count == 4) {
 
435
                        uint16 *tr, *tg, *tb, *ta;
 
436
                        CopyField4(tag, tr, tg, tb, ta);
 
437
                } else if (count == (uint16) -1) {
 
438
                        uint16 shortv1;
 
439
                        uint16* shortav;
 
440
                        CopyField2(tag, shortv1, shortav);
 
441
                }
 
442
                break;
 
443
        case TIFF_LONG:
 
444
                { uint32 longv;
 
445
                  CopyField(tag, longv);
 
446
                }
 
447
                break;
 
448
        case TIFF_RATIONAL:
 
449
                if (count == 1) {
 
450
                        float floatv;
 
451
                        CopyField(tag, floatv);
 
452
                } else if (count == (uint16) -1) {
 
453
                        float* floatav;
 
454
                        CopyField(tag, floatav);
 
455
                }
 
456
                break;
 
457
        case TIFF_ASCII:
 
458
                { char* stringv;
 
459
                  CopyField(tag, stringv);
 
460
                }
 
461
                break;
 
462
        case TIFF_DOUBLE:
 
463
                if (count == 1) {
 
464
                        double doublev;
 
465
                        CopyField(tag, doublev);
 
466
                } else if (count == (uint16) -1) {
 
467
                        double* doubleav;
 
468
                        CopyField(tag, doubleav);
 
469
                }
 
470
                break;
 
471
          default:
 
472
            assert( FALSE );
 
473
        }
 
474
}
 
475
 
 
476
static struct cpTag {
 
477
        uint16  tag;
 
478
        uint16  count;
 
479
        TIFFDataType type;
 
480
} tags[] = {
 
481
        { TIFFTAG_SUBFILETYPE,          1, TIFF_LONG },
 
482
        { TIFFTAG_THRESHHOLDING,        1, TIFF_SHORT },
 
483
        { TIFFTAG_DOCUMENTNAME,         1, TIFF_ASCII },
 
484
        { TIFFTAG_IMAGEDESCRIPTION,     1, TIFF_ASCII },
 
485
        { TIFFTAG_MAKE,                 1, TIFF_ASCII },
 
486
        { TIFFTAG_MODEL,                1, TIFF_ASCII },
 
487
        { TIFFTAG_MINSAMPLEVALUE,       1, TIFF_SHORT },
 
488
        { TIFFTAG_MAXSAMPLEVALUE,       1, TIFF_SHORT },
 
489
        { TIFFTAG_XRESOLUTION,          1, TIFF_RATIONAL },
 
490
        { TIFFTAG_YRESOLUTION,          1, TIFF_RATIONAL },
 
491
        { TIFFTAG_PAGENAME,             1, TIFF_ASCII },
 
492
        { TIFFTAG_XPOSITION,            1, TIFF_RATIONAL },
 
493
        { TIFFTAG_YPOSITION,            1, TIFF_RATIONAL },
 
494
        { TIFFTAG_RESOLUTIONUNIT,       1, TIFF_SHORT },
 
495
        { TIFFTAG_SOFTWARE,             1, TIFF_ASCII },
 
496
        { TIFFTAG_DATETIME,             1, TIFF_ASCII },
 
497
        { TIFFTAG_ARTIST,               1, TIFF_ASCII },
 
498
        { TIFFTAG_HOSTCOMPUTER,         1, TIFF_ASCII },
 
499
        { TIFFTAG_WHITEPOINT,           1, TIFF_RATIONAL },
 
500
        { TIFFTAG_PRIMARYCHROMATICITIES,(uint16) -1,TIFF_RATIONAL },
 
501
        { TIFFTAG_HALFTONEHINTS,        2, TIFF_SHORT },
 
502
        { TIFFTAG_INKSET,               1, TIFF_SHORT },
 
503
        { TIFFTAG_INKNAMES,             1, TIFF_ASCII },
 
504
        { TIFFTAG_NUMBEROFINKS,         1, TIFF_SHORT },
 
505
        { TIFFTAG_DOTRANGE,             2, TIFF_SHORT },
 
506
        { TIFFTAG_TARGETPRINTER,        1, TIFF_ASCII },
 
507
        { TIFFTAG_SAMPLEFORMAT,         1, TIFF_SHORT },
 
508
        { TIFFTAG_YCBCRCOEFFICIENTS,    (uint16) -1,TIFF_RATIONAL },
 
509
        { TIFFTAG_YCBCRSUBSAMPLING,     2, TIFF_SHORT },
 
510
        { TIFFTAG_YCBCRPOSITIONING,     1, TIFF_SHORT },
 
511
        { TIFFTAG_REFERENCEBLACKWHITE,  (uint16) -1,TIFF_RATIONAL },
 
512
        { TIFFTAG_EXTRASAMPLES,         (uint16) -1, TIFF_SHORT },
 
513
        { TIFFTAG_SMINSAMPLEVALUE,      1, TIFF_DOUBLE },
 
514
        { TIFFTAG_SMAXSAMPLEVALUE,      1, TIFF_DOUBLE },
 
515
        { TIFFTAG_STONITS,              1, TIFF_DOUBLE },
 
516
};
 
517
#define NTAGS   (sizeof (tags) / sizeof (tags[0]))
 
518
 
 
519
#define CopyTag(tag, count, type)       cpTag(in, out, tag, count, type)
 
520
 
 
521
typedef int (*copyFunc)
 
522
    (TIFF* in, TIFF* out, uint32 l, uint32 w, uint16 samplesperpixel);
 
523
static  copyFunc pickCopyFunc(TIFF*, TIFF*, uint16, uint16);
 
524
 
 
525
static int
 
526
tiffcp(TIFF* in, TIFF* out)
 
527
{
 
528
        uint16 bitspersample, samplesperpixel;
 
529
        uint16 input_compression;
 
530
        copyFunc cf;
 
531
        uint32 width, length;
 
532
        struct cpTag* p;
 
533
 
 
534
        CopyField(TIFFTAG_IMAGEWIDTH, width);
 
535
        CopyField(TIFFTAG_IMAGELENGTH, length);
 
536
        CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample);
 
537
        CopyField(TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
 
538
        if (compression != (uint16)-1)
 
539
                TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
 
540
        else
 
541
                CopyField(TIFFTAG_COMPRESSION, compression);
 
542
        if (compression == COMPRESSION_JPEG) {
 
543
            if ( TIFFGetField( in, TIFFTAG_COMPRESSION, &input_compression )
 
544
                 && input_compression == COMPRESSION_JPEG ) {
 
545
                TIFFSetField(in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
 
546
            }
 
547
            if (jpegcolormode == JPEGCOLORMODE_RGB)
 
548
                TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
 
549
            else
 
550
                TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
 
551
        }
 
552
        else if (compression == COMPRESSION_SGILOG || compression == COMPRESSION_SGILOG24)
 
553
                TIFFSetField(out, TIFFTAG_PHOTOMETRIC,
 
554
                    samplesperpixel == 1 ?
 
555
                        PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
 
556
        else
 
557
                CopyTag(TIFFTAG_PHOTOMETRIC, 1, TIFF_SHORT);
 
558
        if (fillorder != 0)
 
559
                TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
 
560
        else
 
561
                CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
 
562
        /*
 
563
         * Will copy `Orientation' tag from input image
 
564
         */
 
565
        TIFFGetField(in, TIFFTAG_ORIENTATION, &orientation);
 
566
        switch (orientation) {
 
567
                case ORIENTATION_BOTRIGHT:
 
568
                case ORIENTATION_RIGHTBOT:      /* XXX */
 
569
                case ORIENTATION_LEFTBOT:       /* XXX */
 
570
                        TIFFWarning(TIFFFileName(in), "using bottom-left orientation");
 
571
                        orientation = ORIENTATION_BOTLEFT;
 
572
                /* fall thru... */
 
573
                case ORIENTATION_BOTLEFT:
 
574
                        break;
 
575
                case ORIENTATION_TOPRIGHT:
 
576
                case ORIENTATION_RIGHTTOP:      /* XXX */
 
577
                case ORIENTATION_LEFTTOP:       /* XXX */
 
578
                default:
 
579
                        TIFFWarning(TIFFFileName(in), "using top-left orientation");
 
580
                        orientation = ORIENTATION_TOPLEFT;
 
581
                /* fall thru... */
 
582
                case ORIENTATION_TOPLEFT:
 
583
                        break;
 
584
        }
 
585
        TIFFSetField(out, TIFFTAG_ORIENTATION, orientation);
 
586
        /*
 
587
         * Choose tiles/strip for the output image according to
 
588
         * the command line arguments (-tiles, -strips) and the
 
589
         * structure of the input image.
 
590
         */
 
591
        if (outtiled == -1)
 
592
                outtiled = TIFFIsTiled(in);
 
593
        if (outtiled) {
 
594
                /*
 
595
                 * Setup output file's tile width&height.  If either
 
596
                 * is not specified, use either the value from the
 
597
                 * input image or, if nothing is defined, use the
 
598
                 * library default.
 
599
                 */
 
600
                if (tilewidth == (uint32) -1)
 
601
                        TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
 
602
                if (tilelength == (uint32) -1)
 
603
                        TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
 
604
                TIFFDefaultTileSize(out, &tilewidth, &tilelength);
 
605
                TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
 
606
                TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
 
607
        } else {
 
608
                /*
 
609
                 * RowsPerStrip is left unspecified: use either the
 
610
                 * value from the input image or, if nothing is defined,
 
611
                 * use the library default.
 
612
                 */
 
613
                if (rowsperstrip == (uint32) 0) {
 
614
                        if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP,&rowsperstrip))
 
615
                                rowsperstrip =
 
616
                                        TIFFDefaultStripSize(out, rowsperstrip);
 
617
                }
 
618
                else if (rowsperstrip == (uint32) -1)
 
619
                        rowsperstrip = length;
 
620
                TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
 
621
        }
 
622
        if (config != (uint16) -1)
 
623
                TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
 
624
        else
 
625
                CopyField(TIFFTAG_PLANARCONFIG, config);
 
626
        if (samplesperpixel <= 4)
 
627
                CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
 
628
        CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
 
629
/* SMinSampleValue & SMaxSampleValue */
 
630
        switch (compression) {
 
631
        case COMPRESSION_JPEG:
 
632
                TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
 
633
                TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
 
634
                break;
 
635
        case COMPRESSION_LZW:
 
636
        case COMPRESSION_DEFLATE:
 
637
                if (predictor != (uint16)-1)
 
638
                        TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
 
639
                else
 
640
                        CopyField(TIFFTAG_PREDICTOR, predictor);
 
641
                break;
 
642
        case COMPRESSION_CCITTFAX3:
 
643
        case COMPRESSION_CCITTFAX4:
 
644
                if (compression == COMPRESSION_CCITTFAX3) {
 
645
                        if (g3opts != (uint32) -1)
 
646
                                TIFFSetField(out, TIFFTAG_GROUP3OPTIONS,
 
647
                                    g3opts);
 
648
                        else
 
649
                                CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
 
650
                } else
 
651
                        CopyTag(TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG);
 
652
                CopyTag(TIFFTAG_BADFAXLINES, 1, TIFF_LONG);
 
653
                CopyTag(TIFFTAG_CLEANFAXDATA, 1, TIFF_LONG);
 
654
                CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG);
 
655
                CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
 
656
                CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
 
657
                CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
 
658
                break;
 
659
        }
 
660
        { uint32 len32;
 
661
          void** data;
 
662
          if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
 
663
                TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
 
664
        }
 
665
        {
 
666
          unsigned short pg0, pg1;
 
667
          if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1))
 
668
                if (pageNum < 0) // only one input file
 
669
                        TIFFSetField(out, TIFFTAG_PAGENUMBER, pg0, pg1);
 
670
                else 
 
671
                        TIFFSetField(out, TIFFTAG_PAGENUMBER, pageNum++, 0);
 
672
        }
 
673
        for (p = tags; p < &tags[NTAGS]; p++)
 
674
                CopyTag(p->tag, p->count, p->type);
 
675
 
 
676
        cf = pickCopyFunc(in, out, bitspersample, samplesperpixel);
 
677
        return (cf ? (*cf)(in, out, length, width, samplesperpixel) : FALSE);
 
678
}
 
679
 
 
680
/*
 
681
 * Copy Functions.
 
682
 */
 
683
#define DECLAREcpFunc(x) \
 
684
static int x(TIFF* in, TIFF* out, \
 
685
    uint32 imagelength, uint32 imagewidth, tsample_t spp)
 
686
 
 
687
#define DECLAREreadFunc(x) \
 
688
static void x(TIFF* in, \
 
689
    uint8* buf, uint32 imagelength, uint32 imagewidth, tsample_t spp)
 
690
typedef void (*readFunc)(TIFF*, uint8*, uint32, uint32, tsample_t);
 
691
 
 
692
#define DECLAREwriteFunc(x) \
 
693
static int x(TIFF* out, \
 
694
    uint8* buf, uint32 imagelength, uint32 imagewidth, tsample_t spp)
 
695
typedef int (*writeFunc)(TIFF*, uint8*, uint32, uint32, tsample_t);
 
696
 
 
697
/*
 
698
 * Contig -> contig by scanline for rows/strip change.
 
699
 */
 
700
DECLAREcpFunc(cpContig2ContigByRow)
 
701
{
 
702
        tdata_t buf = _TIFFmalloc(TIFFScanlineSize(in));
 
703
        uint32 row;
 
704
 
 
705
        (void) imagewidth; (void) spp;
 
706
        for (row = 0; row < imagelength; row++) {
 
707
                if (TIFFReadScanline(in, buf, row, 0) < 0 && !ignore)
 
708
                        goto done;
 
709
                if (TIFFWriteScanline(out, buf, row, 0) < 0)
 
710
                        goto bad;
 
711
        }
 
712
done:
 
713
        _TIFFfree(buf);
 
714
        return (TRUE);
 
715
bad:
 
716
        _TIFFfree(buf);
 
717
        return (FALSE);
 
718
}
 
719
 
 
720
 
 
721
typedef void biasFn (void *image, void *bias, uint32 pixels);
 
722
 
 
723
#define subtract(bits) \
 
724
static void subtract##bits (void *i, void *b, uint32 pixels)\
 
725
{\
 
726
   uint##bits *image = i;\
 
727
   uint##bits *bias = b;\
 
728
   while (pixels--) {\
 
729
     *image = *image > *bias ? *image-*bias : 0;\
 
730
     image++, bias++; \
 
731
   } \
 
732
}
 
733
 
 
734
subtract(8)
 
735
subtract(16)
 
736
subtract(32)
 
737
 
 
738
static biasFn *lineSubtractFn (unsigned bits)
 
739
{
 
740
    switch (bits) {
 
741
      case  8:  return subtract8;
 
742
      case 16:  return subtract16;
 
743
      case 32:  return subtract32;
 
744
    }
 
745
    return NULL;
 
746
}
 
747
 
 
748
/*
 
749
 * Contig -> contig by scanline while subtracting a bias image.
 
750
 */
 
751
DECLAREcpFunc(cpBiasedContig2Contig)
 
752
{
 
753
  if (spp == 1) {
 
754
    tsize_t biasSize = TIFFScanlineSize(bias);
 
755
    tsize_t bufSize = TIFFScanlineSize(in);
 
756
    tdata_t buf, biasBuf;
 
757
    uint32 biasWidth = 0, biasLength = 0;
 
758
    TIFFGetField(bias, TIFFTAG_IMAGEWIDTH, &biasWidth);
 
759
    TIFFGetField(bias, TIFFTAG_IMAGELENGTH, &biasLength);
 
760
    if (biasSize == bufSize && 
 
761
        imagelength == biasLength && imagewidth == biasWidth) {
 
762
      uint16 sampleBits = 0;
 
763
      biasFn *subtractLine;
 
764
      TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &sampleBits);
 
765
      subtractLine = lineSubtractFn (sampleBits);
 
766
      if (subtractLine) {
 
767
        uint32 row;
 
768
        buf = _TIFFmalloc(bufSize);
 
769
        biasBuf = _TIFFmalloc(bufSize);
 
770
        for (row = 0; row < imagelength; row++) {
 
771
          if (TIFFReadScanline(in, buf, row, 0) < 0 && !ignore)
 
772
                break;
 
773
          if (TIFFReadScanline(bias, biasBuf, row, 0) < 0 && !ignore)
 
774
                break;
 
775
          subtractLine (buf, biasBuf, imagewidth);
 
776
          if (TIFFWriteScanline(out, buf, row, 0) < 0) {
 
777
            _TIFFfree(buf); _TIFFfree(biasBuf);
 
778
            return FALSE;
 
779
          }
 
780
        }
 
781
        _TIFFfree(buf); _TIFFfree(biasBuf);
 
782
        TIFFSetDirectory (bias, TIFFCurrentDirectory(bias)); /* rewind */
 
783
        return TRUE;
 
784
        
 
785
      }else{
 
786
        fprintf (stderr, "No support for biasing %d bit pixels\n", sampleBits);
 
787
        return FALSE;
 
788
      }
 
789
    }
 
790
    fprintf (stderr,"Bias image %s,%d\nis not the same size as %s,%d\n",
 
791
             TIFFFileName(bias), TIFFCurrentDirectory(bias),
 
792
             TIFFFileName(in), TIFFCurrentDirectory(in));
 
793
    return FALSE;
 
794
  }else{
 
795
    fprintf (stderr, "Can't bias %s,%d as it has >1 Sample/Pixel\n",
 
796
             TIFFFileName(in), TIFFCurrentDirectory(in));
 
797
    return FALSE;
 
798
  }
 
799
}
 
800
 
 
801
 
 
802
/*
 
803
 * Strip -> strip for change in encoding.
 
804
 */
 
805
DECLAREcpFunc(cpDecodedStrips)
 
806
{
 
807
        tsize_t stripsize  = TIFFStripSize(in);
 
808
        tdata_t buf = _TIFFmalloc(stripsize);
 
809
 
 
810
        (void) imagewidth; (void) spp;
 
811
        if (buf) {
 
812
                tstrip_t s, ns = TIFFNumberOfStrips(in);
 
813
                uint32 row = 0;
 
814
                for (s = 0; s < ns; s++) {
 
815
                        tsize_t cc = (row + rowsperstrip > imagelength) ?
 
816
                            TIFFVStripSize(in, imagelength - row) : stripsize;
 
817
                        if (TIFFReadEncodedStrip(in, s, buf, cc) < 0 && !ignore)
 
818
                                break;
 
819
                        if (TIFFWriteEncodedStrip(out, s, buf, cc) < 0) {
 
820
                                _TIFFfree(buf);
 
821
                                return (FALSE);
 
822
                        }
 
823
                        row += rowsperstrip;
 
824
                }
 
825
                _TIFFfree(buf);
 
826
                return (TRUE);
 
827
        }
 
828
        return (FALSE);
 
829
}
 
830
 
 
831
/*
 
832
 * Separate -> separate by row for rows/strip change.
 
833
 */
 
834
DECLAREcpFunc(cpSeparate2SeparateByRow)
 
835
{
 
836
        tdata_t buf = _TIFFmalloc(TIFFScanlineSize(in));
 
837
        uint32 row;
 
838
        tsample_t s;
 
839
 
 
840
        (void) imagewidth;
 
841
        for (s = 0; s < spp; s++) {
 
842
                for (row = 0; row < imagelength; row++) {
 
843
                        if (TIFFReadScanline(in, buf, row, s) < 0 && !ignore)
 
844
                                goto done;
 
845
                        if (TIFFWriteScanline(out, buf, row, s) < 0)
 
846
                                goto bad;
 
847
                }
 
848
        }
 
849
done:
 
850
        _TIFFfree(buf);
 
851
        return (TRUE);
 
852
bad:
 
853
        _TIFFfree(buf);
 
854
        return (FALSE);
 
855
}
 
856
 
 
857
/*
 
858
 * Contig -> separate by row.
 
859
 */
 
860
DECLAREcpFunc(cpContig2SeparateByRow)
 
861
{
 
862
        tdata_t inbuf = _TIFFmalloc(TIFFScanlineSize(in));
 
863
        tdata_t outbuf = _TIFFmalloc(TIFFScanlineSize(out));
 
864
        register uint8 *inp, *outp;
 
865
        register uint32 n;
 
866
        uint32 row;
 
867
        tsample_t s;
 
868
 
 
869
        /* unpack channels */
 
870
        for (s = 0; s < spp; s++) {
 
871
                for (row = 0; row < imagelength; row++) {
 
872
                        if (TIFFReadScanline(in, inbuf, row, 0) < 0 && !ignore)
 
873
                                goto done;
 
874
                        inp = ((uint8*)inbuf) + s;
 
875
                        outp = (uint8*)outbuf;
 
876
                        for (n = imagewidth; n-- > 0;) {
 
877
                                *outp++ = *inp;
 
878
                                inp += spp;
 
879
                        }
 
880
                        if (TIFFWriteScanline(out, outbuf, row, s) < 0)
 
881
                                goto bad;
 
882
                }
 
883
        }
 
884
done:
 
885
        if (inbuf) _TIFFfree(inbuf);
 
886
        if (outbuf) _TIFFfree(outbuf);
 
887
        return (TRUE);
 
888
bad:
 
889
        if (inbuf) _TIFFfree(inbuf);
 
890
        if (outbuf) _TIFFfree(outbuf);
 
891
        return (FALSE);
 
892
}
 
893
 
 
894
/*
 
895
 * Separate -> contig by row.
 
896
 */
 
897
DECLAREcpFunc(cpSeparate2ContigByRow)
 
898
{
 
899
        tdata_t inbuf = _TIFFmalloc(TIFFScanlineSize(in));
 
900
        tdata_t outbuf = _TIFFmalloc(TIFFScanlineSize(out));
 
901
        register uint8 *inp, *outp;
 
902
        register uint32 n;
 
903
        uint32 row;
 
904
        tsample_t s;
 
905
 
 
906
        for (row = 0; row < imagelength; row++) {
 
907
                /* merge channels */
 
908
                for (s = 0; s < spp; s++) {
 
909
                        if (TIFFReadScanline(in, inbuf, row, s) < 0 && !ignore)
 
910
                                goto done;
 
911
                        inp = (uint8*)inbuf;
 
912
                        outp = ((uint8*)outbuf) + s;
 
913
                        for (n = imagewidth; n-- > 0;) {
 
914
                                *outp = *inp++;
 
915
                                outp += spp;
 
916
                        }
 
917
                }
 
918
                if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
 
919
                        goto bad;
 
920
        }
 
921
done:
 
922
        if (inbuf) _TIFFfree(inbuf);
 
923
        if (outbuf) _TIFFfree(outbuf);
 
924
        return (TRUE);
 
925
bad:
 
926
        if (inbuf) _TIFFfree(inbuf);
 
927
        if (outbuf) _TIFFfree(outbuf);
 
928
        return (FALSE);
 
929
}
 
930
 
 
931
static void
 
932
cpStripToTile(uint8* out, uint8* in,
 
933
        uint32 rows, uint32 cols, int outskew, int inskew)
 
934
{
 
935
        while (rows-- > 0) {
 
936
                uint32 j = cols;
 
937
                while (j-- > 0)
 
938
                        *out++ = *in++;
 
939
                out += outskew;
 
940
                in += inskew;
 
941
        }
 
942
}
 
943
 
 
944
static void
 
945
cpContigBufToSeparateBuf(uint8* out, uint8* in,
 
946
           uint32 rows, uint32 cols, int outskew, int inskew, tsample_t spp,
 
947
           int bytes_per_sample )
 
948
{
 
949
        while (rows-- > 0) {
 
950
                uint32 j = cols;
 
951
                while (j-- > 0)
 
952
                {
 
953
                        int n = bytes_per_sample;
 
954
 
 
955
                        while( n-- ) {
 
956
                            *out++ = *in++;
 
957
                        }
 
958
                        in += (spp-1) * bytes_per_sample;
 
959
                }
 
960
                out += outskew;
 
961
                in += inskew;
 
962
        }
 
963
}
 
964
 
 
965
static void
 
966
cpSeparateBufToContigBuf(uint8* out, uint8* in,
 
967
        uint32 rows, uint32 cols, int outskew, int inskew, tsample_t spp,
 
968
                         int bytes_per_sample)
 
969
{
 
970
        while (rows-- > 0) {
 
971
                uint32 j = cols;
 
972
                while (j-- > 0) {
 
973
                        int n = bytes_per_sample;
 
974
 
 
975
                        while( n-- ) {
 
976
                                *out++ = *in++;
 
977
                        }
 
978
                        out += (spp-1)*bytes_per_sample;
 
979
                }
 
980
                out += outskew;
 
981
                in += inskew;
 
982
        }
 
983
}
 
984
 
 
985
static int
 
986
cpImage(TIFF* in, TIFF* out, readFunc fin, writeFunc fout,
 
987
        uint32 imagelength, uint32 imagewidth, tsample_t spp)
 
988
{
 
989
        int status = FALSE;
 
990
        tdata_t buf = _TIFFmalloc(TIFFRasterScanlineSize(in) * imagelength);
 
991
        
 
992
        if (buf) {
 
993
                (*fin)(in, (uint8*)buf, imagelength, imagewidth, spp);
 
994
                status = (fout)(out, (uint8*)buf, imagelength, imagewidth, spp);
 
995
                _TIFFfree(buf);
 
996
        }
 
997
        return (status);
 
998
}
 
999
 
 
1000
DECLAREreadFunc(readContigStripsIntoBuffer)
 
1001
{
 
1002
        tsize_t scanlinesize = TIFFScanlineSize(in);
 
1003
        uint8* bufp = buf;
 
1004
        uint32 row;
 
1005
 
 
1006
        (void) imagewidth; (void) spp;
 
1007
        for (row = 0; row < imagelength; row++) {
 
1008
                if (TIFFReadScanline(in, (tdata_t) bufp, row, 0) < 0 && !ignore)
 
1009
                        break;
 
1010
                bufp += scanlinesize;
 
1011
        }
 
1012
}
 
1013
 
 
1014
DECLAREreadFunc(readSeparateStripsIntoBuffer)
 
1015
{
 
1016
        tsize_t scanlinesize = TIFFScanlineSize(in);
 
1017
        tdata_t scanline = _TIFFmalloc(scanlinesize);
 
1018
 
 
1019
        (void) imagewidth;
 
1020
        if (scanline) {
 
1021
                uint8* bufp = (uint8*) buf;
 
1022
                uint32 row;
 
1023
                tsample_t s;
 
1024
 
 
1025
                for (row = 0; row < imagelength; row++) {
 
1026
                        /* merge channels */
 
1027
                        for (s = 0; s < spp; s++) {
 
1028
                                uint8* bp = bufp + s;
 
1029
                                tsize_t n = scanlinesize;
 
1030
                                uint8* sbuf = scanline;
 
1031
 
 
1032
                                if (TIFFReadScanline(in, scanline, row, s) < 0 && !ignore)
 
1033
                                        goto done;
 
1034
                                while (n-- > 0)
 
1035
                                        *bp = *sbuf++, bp += spp;
 
1036
                        }
 
1037
                        bufp += scanlinesize * spp;
 
1038
                }
 
1039
 
 
1040
done:
 
1041
                _TIFFfree(scanline);
 
1042
        }
 
1043
}
 
1044
 
 
1045
DECLAREreadFunc(readContigTilesIntoBuffer)
 
1046
{
 
1047
        tdata_t tilebuf = _TIFFmalloc(TIFFTileSize(in));
 
1048
        uint32 imagew = TIFFScanlineSize(in);
 
1049
        uint32 tilew  = TIFFTileRowSize(in);
 
1050
        int iskew = imagew - tilew;
 
1051
        uint8* bufp = (uint8*) buf;
 
1052
        uint32 tw, tl;
 
1053
        uint32 row;
 
1054
 
 
1055
        (void) spp;
 
1056
        if (tilebuf == 0)
 
1057
                return;
 
1058
        (void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
 
1059
        (void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
 
1060
        
 
1061
        for (row = 0; row < imagelength; row += tl) {
 
1062
                uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
 
1063
                uint32 colb = 0;
 
1064
                uint32 col;
 
1065
 
 
1066
                for (col = 0; col < imagewidth; col += tw) {
 
1067
                        if (TIFFReadTile(in, tilebuf, col, row, 0, 0) < 0 &&
 
1068
                            !ignore)
 
1069
                                goto done;
 
1070
                        if (colb + tilew > imagew) {
 
1071
                                uint32 width = imagew - colb;
 
1072
                                uint32 oskew = tilew - width;
 
1073
                                cpStripToTile(bufp + colb,
 
1074
                                              tilebuf, nrow, width,
 
1075
                                              oskew + iskew, oskew );
 
1076
                        } else
 
1077
                                cpStripToTile(bufp + colb,
 
1078
                                              tilebuf, nrow, tilew,
 
1079
                                              iskew, 0);
 
1080
                        colb += tilew;
 
1081
                }
 
1082
                bufp += imagew * nrow;
 
1083
        }
 
1084
done:
 
1085
        _TIFFfree(tilebuf);
 
1086
}
 
1087
 
 
1088
DECLAREreadFunc(readSeparateTilesIntoBuffer)
 
1089
{
 
1090
        uint32 imagew = TIFFRasterScanlineSize(in);
 
1091
        uint32 tilew = TIFFTileRowSize(in);
 
1092
        int iskew  = imagew - tilew*spp;
 
1093
        tdata_t tilebuf = _TIFFmalloc(TIFFTileSize(in));
 
1094
        uint8* bufp = (uint8*) buf;
 
1095
        uint32 tw, tl;
 
1096
        uint32 row;
 
1097
        uint16 bps, bytes_per_sample;
 
1098
 
 
1099
        if (tilebuf == 0)
 
1100
                return;
 
1101
        (void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
 
1102
        (void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
 
1103
        (void) TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps);
 
1104
        assert( bps % 8 == 0 );
 
1105
        bytes_per_sample = bps/8;
 
1106
 
 
1107
        for (row = 0; row < imagelength; row += tl) {
 
1108
                uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
 
1109
                uint32 colb = 0;
 
1110
                uint32 col;
 
1111
 
 
1112
                for (col = 0; col < imagewidth; col += tw) {
 
1113
                        tsample_t s;
 
1114
 
 
1115
                        for (s = 0; s < spp; s++) {
 
1116
                                if (TIFFReadTile(in, tilebuf, col, row, 0, s) < 0 && !ignore)
 
1117
                                        goto done;
 
1118
                                /*
 
1119
                                 * Tile is clipped horizontally.  Calculate
 
1120
                                 * visible portion and skewing factors.
 
1121
                                 */
 
1122
                                if (colb + tilew*spp > imagew) {
 
1123
                                        uint32 width = imagew - colb;
 
1124
                                        int oskew = tilew*spp - width;
 
1125
                                        cpSeparateBufToContigBuf(
 
1126
                                            bufp+colb+s*bytes_per_sample,
 
1127
                                            tilebuf, nrow,
 
1128
                                            width/(spp*bytes_per_sample),
 
1129
                                            oskew + iskew,
 
1130
                                            oskew/spp, spp,
 
1131
                                            bytes_per_sample);
 
1132
                                } else
 
1133
                                        cpSeparateBufToContigBuf(
 
1134
                                            bufp+colb+s*bytes_per_sample,
 
1135
                                            tilebuf, nrow, tw,
 
1136
                                            iskew, 0, spp,
 
1137
                                            bytes_per_sample);
 
1138
                        }
 
1139
                        colb += tilew*spp;
 
1140
                }
 
1141
                bufp += imagew * nrow;
 
1142
        }
 
1143
done:
 
1144
        _TIFFfree(tilebuf);
 
1145
}
 
1146
 
 
1147
DECLAREwriteFunc(writeBufferToContigStrips)
 
1148
{
 
1149
        uint32 row, rowsperstrip;
 
1150
        tstrip_t strip = 0;
 
1151
 
 
1152
        (void) imagewidth; (void) spp;
 
1153
        (void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
 
1154
        for (row = 0; row < imagelength; row += rowsperstrip) {
 
1155
                uint32 nrows = (row+rowsperstrip > imagelength) ?
 
1156
                    imagelength-row : rowsperstrip;
 
1157
                tsize_t stripsize = TIFFVStripSize(out, nrows);
 
1158
                if (TIFFWriteEncodedStrip(out, strip++, buf, stripsize) < 0)
 
1159
                        return (FALSE);
 
1160
                buf += stripsize;
 
1161
        }
 
1162
        return (TRUE);
 
1163
}
 
1164
 
 
1165
DECLAREwriteFunc(writeBufferToSeparateStrips)
 
1166
{
 
1167
        uint32 rowsize = imagewidth * spp;
 
1168
        uint32 rowsperstrip;
 
1169
        tdata_t obuf = _TIFFmalloc(TIFFStripSize(out));
 
1170
        tstrip_t strip = 0;
 
1171
        tsample_t s;
 
1172
 
 
1173
        if (obuf == NULL)
 
1174
                return (0);
 
1175
        (void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
 
1176
        for (s = 0; s < spp; s++) {
 
1177
                uint32 row;
 
1178
                for (row = 0; row < imagelength; row += rowsperstrip) {
 
1179
                        uint32 nrows = (row+rowsperstrip > imagelength) ?
 
1180
                            imagelength-row : rowsperstrip;
 
1181
                        tsize_t stripsize = TIFFVStripSize(out, nrows);
 
1182
 
 
1183
                        cpContigBufToSeparateBuf(
 
1184
                            obuf, (uint8*) buf + row*rowsize + s, 
 
1185
                            nrows, imagewidth, 0, 0, spp, 1);
 
1186
                        if (TIFFWriteEncodedStrip(out, strip++, obuf, stripsize) < 0) {
 
1187
                                _TIFFfree(obuf);
 
1188
                                return (FALSE);
 
1189
                        }
 
1190
                }
 
1191
        }
 
1192
        _TIFFfree(obuf);
 
1193
        return (TRUE);
 
1194
 
 
1195
}
 
1196
 
 
1197
DECLAREwriteFunc(writeBufferToContigTiles)
 
1198
{
 
1199
        uint32 imagew = TIFFScanlineSize(out);
 
1200
        uint32 tilew  = TIFFTileRowSize(out);
 
1201
        int iskew = imagew - tilew;
 
1202
        tdata_t obuf = _TIFFmalloc(TIFFTileSize(out));
 
1203
        uint8* bufp = (uint8*) buf;
 
1204
        uint32 tl, tw;
 
1205
        uint32 row;
 
1206
 
 
1207
        (void) spp;
 
1208
        if (obuf == NULL)
 
1209
                return (FALSE);
 
1210
        (void) TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
 
1211
        (void) TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
 
1212
        for (row = 0; row < imagelength; row += tilelength) {
 
1213
                uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
 
1214
                uint32 colb = 0;
 
1215
                uint32 col;
 
1216
 
 
1217
                for (col = 0; col < imagewidth; col += tw) {
 
1218
                        /*
 
1219
                         * Tile is clipped horizontally.  Calculate
 
1220
                         * visible portion and skewing factors.
 
1221
                         */
 
1222
                        if (colb + tilew > imagew) {
 
1223
                                uint32 width = imagew - colb;
 
1224
                                int oskew = tilew - width;
 
1225
                                cpStripToTile(obuf, bufp + colb, nrow, width,
 
1226
                                    oskew, oskew + iskew);
 
1227
                        } else
 
1228
                                cpStripToTile(obuf, bufp + colb, nrow, tilew,
 
1229
                                    0, iskew);
 
1230
                        if (TIFFWriteTile(out, obuf, col, row, 0, 0) < 0) {
 
1231
                                _TIFFfree(obuf);
 
1232
                                return (FALSE);
 
1233
                        }
 
1234
                        colb += tilew;
 
1235
                }
 
1236
                bufp += nrow * imagew;
 
1237
        }
 
1238
        _TIFFfree(obuf);
 
1239
        return (TRUE);
 
1240
}
 
1241
 
 
1242
DECLAREwriteFunc(writeBufferToSeparateTiles)
 
1243
{
 
1244
        uint32 imagew = TIFFScanlineSize(out);
 
1245
        tsize_t tilew  = TIFFTileRowSize(out);
 
1246
        uint32 iimagew = TIFFRasterScanlineSize(out);
 
1247
        int iskew = iimagew - tilew*spp;
 
1248
        tdata_t obuf = _TIFFmalloc(TIFFTileSize(out));
 
1249
        uint8* bufp = (uint8*) buf;
 
1250
        uint32 tl, tw;
 
1251
        uint32 row;
 
1252
        uint16 bps, bytes_per_sample;
 
1253
 
 
1254
        if (obuf == NULL)
 
1255
                return (FALSE);
 
1256
        (void) TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
 
1257
        (void) TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
 
1258
        (void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
 
1259
        assert( bps % 8 == 0 );
 
1260
        bytes_per_sample = bps/8;
 
1261
        
 
1262
        for (row = 0; row < imagelength; row += tl) {
 
1263
                uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
 
1264
                uint32 colb = 0;
 
1265
                uint32 col;
 
1266
 
 
1267
                for (col = 0; col < imagewidth; col += tw) {
 
1268
                        tsample_t s;
 
1269
                        for (s = 0; s < spp; s++) {
 
1270
                                /*
 
1271
                                 * Tile is clipped horizontally.  Calculate
 
1272
                                 * visible portion and skewing factors.
 
1273
                                 */
 
1274
                                if (colb + tilew > imagew) {
 
1275
                                        uint32 width = (imagew - colb);
 
1276
                                        int oskew = tilew - width;
 
1277
 
 
1278
                                        cpContigBufToSeparateBuf(obuf,
 
1279
                                            bufp + (colb*spp) + s,
 
1280
                                            nrow, width/bytes_per_sample,
 
1281
                                            oskew, (oskew*spp)+iskew, spp,
 
1282
                                            bytes_per_sample);
 
1283
                                } else
 
1284
                                        cpContigBufToSeparateBuf(obuf,
 
1285
                                            bufp + (colb*spp) + s,
 
1286
                                            nrow, tilewidth,
 
1287
                                            0, iskew, spp,
 
1288
                                            bytes_per_sample);
 
1289
                                if (TIFFWriteTile(out, obuf, col, row, 0, s) < 0) {
 
1290
                                        _TIFFfree(obuf);
 
1291
                                        return (FALSE);
 
1292
                                }
 
1293
                        }
 
1294
                        colb += tilew;
 
1295
                }
 
1296
                bufp += nrow * iimagew;
 
1297
        }
 
1298
        _TIFFfree(obuf);
 
1299
        return (TRUE);
 
1300
}
 
1301
 
 
1302
/*
 
1303
 * Contig strips -> contig tiles.
 
1304
 */
 
1305
DECLAREcpFunc(cpContigStrips2ContigTiles)
 
1306
{
 
1307
        return cpImage(in, out,
 
1308
            readContigStripsIntoBuffer,
 
1309
            writeBufferToContigTiles,
 
1310
            imagelength, imagewidth, spp);
 
1311
}
 
1312
 
 
1313
/*
 
1314
 * Contig strips -> separate tiles.
 
1315
 */
 
1316
DECLAREcpFunc(cpContigStrips2SeparateTiles)
 
1317
{
 
1318
        return cpImage(in, out,
 
1319
            readContigStripsIntoBuffer,
 
1320
            writeBufferToSeparateTiles,
 
1321
            imagelength, imagewidth, spp);
 
1322
}
 
1323
 
 
1324
/*
 
1325
 * Separate strips -> contig tiles.
 
1326
 */
 
1327
DECLAREcpFunc(cpSeparateStrips2ContigTiles)
 
1328
{
 
1329
        return cpImage(in, out,
 
1330
            readSeparateStripsIntoBuffer,
 
1331
            writeBufferToContigTiles,
 
1332
            imagelength, imagewidth, spp);
 
1333
}
 
1334
 
 
1335
/*
 
1336
 * Separate strips -> separate tiles.
 
1337
 */
 
1338
DECLAREcpFunc(cpSeparateStrips2SeparateTiles)
 
1339
{
 
1340
        return cpImage(in, out,
 
1341
            readSeparateStripsIntoBuffer,
 
1342
            writeBufferToSeparateTiles,
 
1343
            imagelength, imagewidth, spp);
 
1344
}
 
1345
 
 
1346
/*
 
1347
 * Contig strips -> contig tiles.
 
1348
 */
 
1349
DECLAREcpFunc(cpContigTiles2ContigTiles)
 
1350
{
 
1351
        return cpImage(in, out,
 
1352
            readContigTilesIntoBuffer,
 
1353
            writeBufferToContigTiles,
 
1354
            imagelength, imagewidth, spp);
 
1355
}
 
1356
 
 
1357
/*
 
1358
 * Contig tiles -> separate tiles.
 
1359
 */
 
1360
DECLAREcpFunc(cpContigTiles2SeparateTiles)
 
1361
{
 
1362
        return cpImage(in, out,
 
1363
            readContigTilesIntoBuffer,
 
1364
            writeBufferToSeparateTiles,
 
1365
            imagelength, imagewidth, spp);
 
1366
}
 
1367
 
 
1368
/*
 
1369
 * Separate tiles -> contig tiles.
 
1370
 */
 
1371
DECLAREcpFunc(cpSeparateTiles2ContigTiles)
 
1372
{
 
1373
        return cpImage(in, out,
 
1374
            readSeparateTilesIntoBuffer,
 
1375
            writeBufferToContigTiles,
 
1376
            imagelength, imagewidth, spp);
 
1377
}
 
1378
 
 
1379
/*
 
1380
 * Separate tiles -> separate tiles (tile dimension change).
 
1381
 */
 
1382
DECLAREcpFunc(cpSeparateTiles2SeparateTiles)
 
1383
{
 
1384
        return cpImage(in, out,
 
1385
            readSeparateTilesIntoBuffer,
 
1386
            writeBufferToSeparateTiles,
 
1387
            imagelength, imagewidth, spp);
 
1388
}
 
1389
 
 
1390
/*
 
1391
 * Contig tiles -> contig tiles (tile dimension change).
 
1392
 */
 
1393
DECLAREcpFunc(cpContigTiles2ContigStrips)
 
1394
{
 
1395
        return cpImage(in, out,
 
1396
            readContigTilesIntoBuffer,
 
1397
            writeBufferToContigStrips,
 
1398
            imagelength, imagewidth, spp);
 
1399
}
 
1400
 
 
1401
/*
 
1402
 * Contig tiles -> separate strips.
 
1403
 */
 
1404
DECLAREcpFunc(cpContigTiles2SeparateStrips)
 
1405
{
 
1406
        return cpImage(in, out,
 
1407
            readContigTilesIntoBuffer,
 
1408
            writeBufferToSeparateStrips,
 
1409
            imagelength, imagewidth, spp);
 
1410
}
 
1411
 
 
1412
/*
 
1413
 * Separate tiles -> contig strips.
 
1414
 */
 
1415
DECLAREcpFunc(cpSeparateTiles2ContigStrips)
 
1416
{
 
1417
        return cpImage(in, out,
 
1418
            readSeparateTilesIntoBuffer,
 
1419
            writeBufferToContigStrips,
 
1420
            imagelength, imagewidth, spp);
 
1421
}
 
1422
 
 
1423
/*
 
1424
 * Separate tiles -> separate strips.
 
1425
 */
 
1426
DECLAREcpFunc(cpSeparateTiles2SeparateStrips)
 
1427
{
 
1428
        return cpImage(in, out,
 
1429
            readSeparateTilesIntoBuffer,
 
1430
            writeBufferToSeparateStrips,
 
1431
            imagelength, imagewidth, spp);
 
1432
}
 
1433
 
 
1434
/*
 
1435
 * Select the appropriate copy function to use.
 
1436
 */
 
1437
static copyFunc
 
1438
pickCopyFunc(TIFF* in, TIFF* out, uint16 bitspersample, uint16 samplesperpixel)
 
1439
{
 
1440
        uint16 shortv;
 
1441
        uint32 w, l, tw, tl;
 
1442
        int bychunk;
 
1443
 
 
1444
        (void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv);
 
1445
        if (shortv != config && bitspersample != 8 && samplesperpixel > 1) {
 
1446
                fprintf(stderr,
 
1447
"%s: Cannot handle different planar configuration w/ bits/sample != 8\n",
 
1448
                    TIFFFileName(in));
 
1449
                return (NULL);
 
1450
        }
 
1451
        TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w);
 
1452
        TIFFGetField(in, TIFFTAG_IMAGELENGTH, &l);
 
1453
        if (!(TIFFIsTiled(out) || TIFFIsTiled(in))) {
 
1454
            uint32 irps = (uint32) -1L;
 
1455
            TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &irps);
 
1456
            /* if biased, force decoded copying to allow image subtraction */
 
1457
            bychunk = !bias && (rowsperstrip == irps);
 
1458
        }else{  /* either in or out is tiled */
 
1459
            if (bias) {
 
1460
                  fprintf(stderr,
 
1461
"%s: Cannot handle tiled configuration w/bias image\n",
 
1462
                  TIFFFileName(in));
 
1463
                  return (NULL);
 
1464
            }
 
1465
            if (TIFFIsTiled(out)) {
 
1466
                if (!TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw))
 
1467
                        tw = w;
 
1468
                if (!TIFFGetField(in, TIFFTAG_TILELENGTH, &tl))
 
1469
                        tl = l;
 
1470
                bychunk = (tw == tilewidth && tl == tilelength);
 
1471
            } else {  /* out's not, so in must be tiled */
 
1472
                TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
 
1473
                TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
 
1474
                bychunk = (tw == w && tl == rowsperstrip);
 
1475
            }
 
1476
        }
 
1477
#define T 1
 
1478
#define F 0
 
1479
#define pack(a,b,c,d,e) ((long)(((a)<<11)|((b)<<3)|((c)<<2)|((d)<<1)|(e)))
 
1480
        switch(pack(shortv,config,TIFFIsTiled(in),TIFFIsTiled(out),bychunk)) {
 
1481
/* Strips -> Tiles */
 
1482
        case pack(PLANARCONFIG_CONTIG,   PLANARCONFIG_CONTIG,   F,T,F):
 
1483
        case pack(PLANARCONFIG_CONTIG,   PLANARCONFIG_CONTIG,   F,T,T):
 
1484
                return cpContigStrips2ContigTiles;
 
1485
        case pack(PLANARCONFIG_CONTIG,   PLANARCONFIG_SEPARATE, F,T,F):
 
1486
        case pack(PLANARCONFIG_CONTIG,   PLANARCONFIG_SEPARATE, F,T,T):
 
1487
                return cpContigStrips2SeparateTiles;
 
1488
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG,   F,T,F):
 
1489
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG,   F,T,T):
 
1490
                return cpSeparateStrips2ContigTiles;
 
1491
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,T,F):
 
1492
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,T,T):
 
1493
                return cpSeparateStrips2SeparateTiles;
 
1494
/* Tiles -> Tiles */
 
1495
        case pack(PLANARCONFIG_CONTIG,   PLANARCONFIG_CONTIG,   T,T,F):
 
1496
        case pack(PLANARCONFIG_CONTIG,   PLANARCONFIG_CONTIG,   T,T,T):
 
1497
                return cpContigTiles2ContigTiles;
 
1498
        case pack(PLANARCONFIG_CONTIG,   PLANARCONFIG_SEPARATE, T,T,F):
 
1499
        case pack(PLANARCONFIG_CONTIG,   PLANARCONFIG_SEPARATE, T,T,T):
 
1500
                return cpContigTiles2SeparateTiles;
 
1501
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG,   T,T,F):
 
1502
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG,   T,T,T):
 
1503
                return cpSeparateTiles2ContigTiles;
 
1504
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,T,F):
 
1505
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,T,T):
 
1506
                return cpSeparateTiles2SeparateTiles;
 
1507
/* Tiles -> Strips */
 
1508
        case pack(PLANARCONFIG_CONTIG,   PLANARCONFIG_CONTIG,   T,F,F):
 
1509
        case pack(PLANARCONFIG_CONTIG,   PLANARCONFIG_CONTIG,   T,F,T):
 
1510
                return cpContigTiles2ContigStrips;
 
1511
        case pack(PLANARCONFIG_CONTIG,   PLANARCONFIG_SEPARATE, T,F,F):
 
1512
        case pack(PLANARCONFIG_CONTIG,   PLANARCONFIG_SEPARATE, T,F,T):
 
1513
                return cpContigTiles2SeparateStrips;
 
1514
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG,   T,F,F):
 
1515
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG,   T,F,T):
 
1516
                return cpSeparateTiles2ContigStrips;
 
1517
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,F,F):
 
1518
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,F,T):
 
1519
                return cpSeparateTiles2SeparateStrips;
 
1520
/* Strips -> Strips */
 
1521
        case pack(PLANARCONFIG_CONTIG,   PLANARCONFIG_CONTIG,   F,F,F):
 
1522
                return bias ? cpBiasedContig2Contig : cpContig2ContigByRow;
 
1523
        case pack(PLANARCONFIG_CONTIG,   PLANARCONFIG_CONTIG,   F,F,T):
 
1524
                return cpDecodedStrips;
 
1525
        case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE,   F,F,F):
 
1526
        case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE,   F,F,T):
 
1527
                return cpContig2SeparateByRow;
 
1528
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG,   F,F,F):
 
1529
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG,   F,F,T):
 
1530
                return cpSeparate2ContigByRow;
 
1531
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,F,F):
 
1532
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,F,T):
 
1533
                return cpSeparate2SeparateByRow;
 
1534
        }
 
1535
#undef pack
 
1536
#undef F
 
1537
#undef T
 
1538
        fprintf(stderr, "tiffcp: %s: Don't know how to copy/convert image.\n",
 
1539
            TIFFFileName(in));
 
1540
        return (NULL);
 
1541
}