1
/* $Header: /cvsroot/osrs/libtiff/tools/tiffcp.c,v 1.15 2003/12/20 13:46:57 dron Exp $ */
4
* Copyright (c) 1988-1997 Sam Leffler
5
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
7
* Revised: 2/18/01 BAR -- added syntax for extracting single images from
8
* multi-image TIFF files.
10
* New syntax is: sourceFileName,image#
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
16
* Example: tiffcp source.tif,1 destination.tif
18
* Copies the 2nd image in source.tif to the destination.
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.
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.
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
54
#define streq(a,b) (strcmp(a,b) == 0)
55
#define strneq(a,b,n) (strncmp(a,b,n) == 0)
60
static int outtiled = -1;
61
static uint32 tilewidth;
62
static uint32 tilelength;
65
static uint16 compression;
66
static uint16 predictor;
67
static uint16 fillorder;
68
static uint16 orientation;
69
static uint32 rowsperstrip;
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;
78
static int tiffcp(TIFF*, TIFF*);
79
static int processCompressOptions(char*);
80
static void usage(void);
82
static char comma = ','; /* (default) comma separator character */
83
static TIFF* bias = NULL;
84
static int pageNum = 0;
86
static int nextSrcImage (TIFF *tif, char **imageSpec)
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
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);
99
if (**imageSpec == comma) {
100
/* a trailing comma denotes remaining images in sequence */
101
if ((*imageSpec)[1] == '\0') *imageSpec = NULL;
104
"Expected a %c separated image # list after %s\n",
105
comma, TIFFFileName (tif));
106
exit (-4); /* syntax error */
109
if (TIFFSetDirectory (tif, nextImage)) return 1;
110
fprintf (stderr, "%s%c%d not found!\n",
111
TIFFFileName(tif), comma, (int) nextImage);
117
static TIFF* openSrcImage (char **imageSpec)
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
125
char *fn = *imageSpec;
126
*imageSpec = strchr (fn, comma);
127
if (*imageSpec) { /* there is at least one image number specifier */
129
tif = TIFFOpen (fn, "r");
130
/* but, ignore any single trailing comma */
131
if (!(*imageSpec)[1]) {*imageSpec = NULL; return tif;}
133
**imageSpec = comma; /* replace the comma */
134
if (!nextSrcImage(tif, imageSpec)) {
140
tif = TIFFOpen (fn, "r");
146
main(int argc, char* argv[])
148
uint16 defconfig = (uint16) -1;
149
uint16 deffillorder = 0;
150
uint32 deftilewidth = (uint32) -1;
151
uint32 deftilelength = (uint32) -1;
152
uint32 defrowsperstrip = (uint32) 0;
164
while ((c = getopt(argc, argv, ",:b:c:f:l:o:z:p:r:w:aistBLMC")) != -1)
167
if (optarg[0] != '=') usage();
170
case 'b': /* this file is bias image subtracted from others */
172
fputs ("Only 1 bias image may be specified\n", stderr);
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);
184
TIFFGetField(bias, TIFFTAG_SAMPLESPERPIXEL, &samples);
186
fputs ("Bias image must be monochrome\n", stderr);
191
case 'a': /* append to output */
194
case 'c': /* compression scheme */
195
if (!processCompressOptions(optarg))
198
case 'f': /* fill order */
199
if (streq(optarg, "lsb2msb"))
200
deffillorder = FILLORDER_LSB2MSB;
201
else if (streq(optarg, "msb2lsb"))
202
deffillorder = FILLORDER_MSB2LSB;
206
case 'i': /* ignore errors */
209
case 'l': /* tile length */
211
deftilelength = atoi(optarg);
213
case 'o': /* initial directory offset */
214
diroff = strtoul(optarg, NULL, 0);
216
case 'p': /* planar configuration */
217
if (streq(optarg, "separate"))
218
defconfig = PLANARCONFIG_SEPARATE;
219
else if (streq(optarg, "contig"))
220
defconfig = PLANARCONFIG_CONTIG;
224
case 'r': /* rows/strip */
225
defrowsperstrip = atol(optarg);
227
case 's': /* generate stripped output */
230
case 't': /* generate tiled output */
233
case 'w': /* tile width */
235
deftilewidth = atoi(optarg);
238
*mp++ = 'b'; *mp = '\0';
241
*mp++ = 'l'; *mp = '\0';
244
*mp++ = 'm'; *mp = '\0';
247
*mp++ = 'c'; *mp = '\0';
253
if (argc - optind < 2)
255
out = TIFFOpen(argv[argc-1], mode);
258
if ((argc - optind) == 2)
260
for (; optind < argc-1 ; optind++) {
261
char *imageCursor = argv[optind];
262
in = openSrcImage (&imageCursor);
265
if (diroff != 0 && !TIFFSetSubDirectory(in, diroff)) {
266
TIFFError(TIFFFileName(in),
267
"Error, setting subdirectory at %#x", diroff);
268
(void) TIFFClose(out);
273
compression = defcompression;
274
predictor = defpredictor;
275
fillorder = deffillorder;
276
rowsperstrip = defrowsperstrip;
277
tilewidth = deftilewidth;
278
tilelength = deftilelength;
280
if (!tiffcp(in, out) || !TIFFWriteDirectory(out)) {
284
if (imageCursor) { /* seek next image directory */
285
if (!nextSrcImage(in, &imageCursor)) break;
287
if (!TIFFReadDirectory(in)) break;
297
processG3Options(char* cp)
299
if( (cp = strchr(cp, ':')) ) {
300
if (defg3opts == (uint32) -1)
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;
312
} while( (cp = strchr(cp, ':')) );
317
processCompressOptions(char* opt)
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, ':');
338
defpredictor = atoi(cp+1);
339
defcompression = COMPRESSION_LZW;
340
} else if (strneq(opt, "zip", 3)) {
341
char* cp = strchr(opt, ':');
343
defpredictor = atoi(cp+1);
344
defcompression = COMPRESSION_DEFLATE;
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)",
363
" -r # make each strip have no more than # rows",
364
" -w # set output tile width (pixels)",
365
" -l # set output tile length (pixels)",
367
" -f lsb2msb force lsb-to-msb FillOrder for output",
368
" -f msb2lsb force msb-to-lsb FillOrder for output",
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",
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",
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",
390
"LZW and deflate options:",
391
" # set predictor value",
392
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
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",
408
fprintf(stderr, "%s\n\n", TIFFGetVersion());
409
for (i = 0; stuff[i] != NULL; i++)
410
fprintf(stderr, "%s\n", stuff[i]);
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)
424
cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type)
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) {
440
CopyField2(tag, shortv1, shortav);
445
CopyField(tag, longv);
451
CopyField(tag, floatv);
452
} else if (count == (uint16) -1) {
454
CopyField(tag, floatav);
459
CopyField(tag, stringv);
465
CopyField(tag, doublev);
466
} else if (count == (uint16) -1) {
468
CopyField(tag, doubleav);
476
static struct cpTag {
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 },
517
#define NTAGS (sizeof (tags) / sizeof (tags[0]))
519
#define CopyTag(tag, count, type) cpTag(in, out, tag, count, type)
521
typedef int (*copyFunc)
522
(TIFF* in, TIFF* out, uint32 l, uint32 w, uint16 samplesperpixel);
523
static copyFunc pickCopyFunc(TIFF*, TIFF*, uint16, uint16);
526
tiffcp(TIFF* in, TIFF* out)
528
uint16 bitspersample, samplesperpixel;
529
uint16 input_compression;
531
uint32 width, length;
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);
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);
547
if (jpegcolormode == JPEGCOLORMODE_RGB)
548
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
550
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
552
else if (compression == COMPRESSION_SGILOG || compression == COMPRESSION_SGILOG24)
553
TIFFSetField(out, TIFFTAG_PHOTOMETRIC,
554
samplesperpixel == 1 ?
555
PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
557
CopyTag(TIFFTAG_PHOTOMETRIC, 1, TIFF_SHORT);
559
TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
561
CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
563
* Will copy `Orientation' tag from input image
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;
573
case ORIENTATION_BOTLEFT:
575
case ORIENTATION_TOPRIGHT:
576
case ORIENTATION_RIGHTTOP: /* XXX */
577
case ORIENTATION_LEFTTOP: /* XXX */
579
TIFFWarning(TIFFFileName(in), "using top-left orientation");
580
orientation = ORIENTATION_TOPLEFT;
582
case ORIENTATION_TOPLEFT:
585
TIFFSetField(out, TIFFTAG_ORIENTATION, orientation);
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.
592
outtiled = TIFFIsTiled(in);
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
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);
609
* RowsPerStrip is left unspecified: use either the
610
* value from the input image or, if nothing is defined,
611
* use the library default.
613
if (rowsperstrip == (uint32) 0) {
614
if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP,&rowsperstrip))
616
TIFFDefaultStripSize(out, rowsperstrip);
618
else if (rowsperstrip == (uint32) -1)
619
rowsperstrip = length;
620
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
622
if (config != (uint16) -1)
623
TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
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);
635
case COMPRESSION_LZW:
636
case COMPRESSION_DEFLATE:
637
if (predictor != (uint16)-1)
638
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
640
CopyField(TIFFTAG_PREDICTOR, predictor);
642
case COMPRESSION_CCITTFAX3:
643
case COMPRESSION_CCITTFAX4:
644
if (compression == COMPRESSION_CCITTFAX3) {
645
if (g3opts != (uint32) -1)
646
TIFFSetField(out, TIFFTAG_GROUP3OPTIONS,
649
CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
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);
662
if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
663
TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
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);
671
TIFFSetField(out, TIFFTAG_PAGENUMBER, pageNum++, 0);
673
for (p = tags; p < &tags[NTAGS]; p++)
674
CopyTag(p->tag, p->count, p->type);
676
cf = pickCopyFunc(in, out, bitspersample, samplesperpixel);
677
return (cf ? (*cf)(in, out, length, width, samplesperpixel) : FALSE);
683
#define DECLAREcpFunc(x) \
684
static int x(TIFF* in, TIFF* out, \
685
uint32 imagelength, uint32 imagewidth, tsample_t spp)
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);
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);
698
* Contig -> contig by scanline for rows/strip change.
700
DECLAREcpFunc(cpContig2ContigByRow)
702
tdata_t buf = _TIFFmalloc(TIFFScanlineSize(in));
705
(void) imagewidth; (void) spp;
706
for (row = 0; row < imagelength; row++) {
707
if (TIFFReadScanline(in, buf, row, 0) < 0 && !ignore)
709
if (TIFFWriteScanline(out, buf, row, 0) < 0)
721
typedef void biasFn (void *image, void *bias, uint32 pixels);
723
#define subtract(bits) \
724
static void subtract##bits (void *i, void *b, uint32 pixels)\
726
uint##bits *image = i;\
727
uint##bits *bias = b;\
729
*image = *image > *bias ? *image-*bias : 0;\
738
static biasFn *lineSubtractFn (unsigned bits)
741
case 8: return subtract8;
742
case 16: return subtract16;
743
case 32: return subtract32;
749
* Contig -> contig by scanline while subtracting a bias image.
751
DECLAREcpFunc(cpBiasedContig2Contig)
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);
768
buf = _TIFFmalloc(bufSize);
769
biasBuf = _TIFFmalloc(bufSize);
770
for (row = 0; row < imagelength; row++) {
771
if (TIFFReadScanline(in, buf, row, 0) < 0 && !ignore)
773
if (TIFFReadScanline(bias, biasBuf, row, 0) < 0 && !ignore)
775
subtractLine (buf, biasBuf, imagewidth);
776
if (TIFFWriteScanline(out, buf, row, 0) < 0) {
777
_TIFFfree(buf); _TIFFfree(biasBuf);
781
_TIFFfree(buf); _TIFFfree(biasBuf);
782
TIFFSetDirectory (bias, TIFFCurrentDirectory(bias)); /* rewind */
786
fprintf (stderr, "No support for biasing %d bit pixels\n", sampleBits);
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));
795
fprintf (stderr, "Can't bias %s,%d as it has >1 Sample/Pixel\n",
796
TIFFFileName(in), TIFFCurrentDirectory(in));
803
* Strip -> strip for change in encoding.
805
DECLAREcpFunc(cpDecodedStrips)
807
tsize_t stripsize = TIFFStripSize(in);
808
tdata_t buf = _TIFFmalloc(stripsize);
810
(void) imagewidth; (void) spp;
812
tstrip_t s, ns = TIFFNumberOfStrips(in);
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)
819
if (TIFFWriteEncodedStrip(out, s, buf, cc) < 0) {
832
* Separate -> separate by row for rows/strip change.
834
DECLAREcpFunc(cpSeparate2SeparateByRow)
836
tdata_t buf = _TIFFmalloc(TIFFScanlineSize(in));
841
for (s = 0; s < spp; s++) {
842
for (row = 0; row < imagelength; row++) {
843
if (TIFFReadScanline(in, buf, row, s) < 0 && !ignore)
845
if (TIFFWriteScanline(out, buf, row, s) < 0)
858
* Contig -> separate by row.
860
DECLAREcpFunc(cpContig2SeparateByRow)
862
tdata_t inbuf = _TIFFmalloc(TIFFScanlineSize(in));
863
tdata_t outbuf = _TIFFmalloc(TIFFScanlineSize(out));
864
register uint8 *inp, *outp;
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)
874
inp = ((uint8*)inbuf) + s;
875
outp = (uint8*)outbuf;
876
for (n = imagewidth; n-- > 0;) {
880
if (TIFFWriteScanline(out, outbuf, row, s) < 0)
885
if (inbuf) _TIFFfree(inbuf);
886
if (outbuf) _TIFFfree(outbuf);
889
if (inbuf) _TIFFfree(inbuf);
890
if (outbuf) _TIFFfree(outbuf);
895
* Separate -> contig by row.
897
DECLAREcpFunc(cpSeparate2ContigByRow)
899
tdata_t inbuf = _TIFFmalloc(TIFFScanlineSize(in));
900
tdata_t outbuf = _TIFFmalloc(TIFFScanlineSize(out));
901
register uint8 *inp, *outp;
906
for (row = 0; row < imagelength; row++) {
908
for (s = 0; s < spp; s++) {
909
if (TIFFReadScanline(in, inbuf, row, s) < 0 && !ignore)
912
outp = ((uint8*)outbuf) + s;
913
for (n = imagewidth; n-- > 0;) {
918
if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
922
if (inbuf) _TIFFfree(inbuf);
923
if (outbuf) _TIFFfree(outbuf);
926
if (inbuf) _TIFFfree(inbuf);
927
if (outbuf) _TIFFfree(outbuf);
932
cpStripToTile(uint8* out, uint8* in,
933
uint32 rows, uint32 cols, int outskew, int inskew)
945
cpContigBufToSeparateBuf(uint8* out, uint8* in,
946
uint32 rows, uint32 cols, int outskew, int inskew, tsample_t spp,
947
int bytes_per_sample )
953
int n = bytes_per_sample;
958
in += (spp-1) * bytes_per_sample;
966
cpSeparateBufToContigBuf(uint8* out, uint8* in,
967
uint32 rows, uint32 cols, int outskew, int inskew, tsample_t spp,
968
int bytes_per_sample)
973
int n = bytes_per_sample;
978
out += (spp-1)*bytes_per_sample;
986
cpImage(TIFF* in, TIFF* out, readFunc fin, writeFunc fout,
987
uint32 imagelength, uint32 imagewidth, tsample_t spp)
990
tdata_t buf = _TIFFmalloc(TIFFRasterScanlineSize(in) * imagelength);
993
(*fin)(in, (uint8*)buf, imagelength, imagewidth, spp);
994
status = (fout)(out, (uint8*)buf, imagelength, imagewidth, spp);
1000
DECLAREreadFunc(readContigStripsIntoBuffer)
1002
tsize_t scanlinesize = TIFFScanlineSize(in);
1006
(void) imagewidth; (void) spp;
1007
for (row = 0; row < imagelength; row++) {
1008
if (TIFFReadScanline(in, (tdata_t) bufp, row, 0) < 0 && !ignore)
1010
bufp += scanlinesize;
1014
DECLAREreadFunc(readSeparateStripsIntoBuffer)
1016
tsize_t scanlinesize = TIFFScanlineSize(in);
1017
tdata_t scanline = _TIFFmalloc(scanlinesize);
1021
uint8* bufp = (uint8*) buf;
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;
1032
if (TIFFReadScanline(in, scanline, row, s) < 0 && !ignore)
1035
*bp = *sbuf++, bp += spp;
1037
bufp += scanlinesize * spp;
1041
_TIFFfree(scanline);
1045
DECLAREreadFunc(readContigTilesIntoBuffer)
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;
1058
(void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
1059
(void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
1061
for (row = 0; row < imagelength; row += tl) {
1062
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
1066
for (col = 0; col < imagewidth; col += tw) {
1067
if (TIFFReadTile(in, tilebuf, col, row, 0, 0) < 0 &&
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 );
1077
cpStripToTile(bufp + colb,
1078
tilebuf, nrow, tilew,
1082
bufp += imagew * nrow;
1088
DECLAREreadFunc(readSeparateTilesIntoBuffer)
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;
1097
uint16 bps, bytes_per_sample;
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;
1107
for (row = 0; row < imagelength; row += tl) {
1108
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
1112
for (col = 0; col < imagewidth; col += tw) {
1115
for (s = 0; s < spp; s++) {
1116
if (TIFFReadTile(in, tilebuf, col, row, 0, s) < 0 && !ignore)
1119
* Tile is clipped horizontally. Calculate
1120
* visible portion and skewing factors.
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,
1128
width/(spp*bytes_per_sample),
1133
cpSeparateBufToContigBuf(
1134
bufp+colb+s*bytes_per_sample,
1141
bufp += imagew * nrow;
1147
DECLAREwriteFunc(writeBufferToContigStrips)
1149
uint32 row, rowsperstrip;
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)
1165
DECLAREwriteFunc(writeBufferToSeparateStrips)
1167
uint32 rowsize = imagewidth * spp;
1168
uint32 rowsperstrip;
1169
tdata_t obuf = _TIFFmalloc(TIFFStripSize(out));
1175
(void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1176
for (s = 0; s < spp; s++) {
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);
1183
cpContigBufToSeparateBuf(
1184
obuf, (uint8*) buf + row*rowsize + s,
1185
nrows, imagewidth, 0, 0, spp, 1);
1186
if (TIFFWriteEncodedStrip(out, strip++, obuf, stripsize) < 0) {
1197
DECLAREwriteFunc(writeBufferToContigTiles)
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;
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;
1217
for (col = 0; col < imagewidth; col += tw) {
1219
* Tile is clipped horizontally. Calculate
1220
* visible portion and skewing factors.
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);
1228
cpStripToTile(obuf, bufp + colb, nrow, tilew,
1230
if (TIFFWriteTile(out, obuf, col, row, 0, 0) < 0) {
1236
bufp += nrow * imagew;
1242
DECLAREwriteFunc(writeBufferToSeparateTiles)
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;
1252
uint16 bps, bytes_per_sample;
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;
1262
for (row = 0; row < imagelength; row += tl) {
1263
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
1267
for (col = 0; col < imagewidth; col += tw) {
1269
for (s = 0; s < spp; s++) {
1271
* Tile is clipped horizontally. Calculate
1272
* visible portion and skewing factors.
1274
if (colb + tilew > imagew) {
1275
uint32 width = (imagew - colb);
1276
int oskew = tilew - width;
1278
cpContigBufToSeparateBuf(obuf,
1279
bufp + (colb*spp) + s,
1280
nrow, width/bytes_per_sample,
1281
oskew, (oskew*spp)+iskew, spp,
1284
cpContigBufToSeparateBuf(obuf,
1285
bufp + (colb*spp) + s,
1289
if (TIFFWriteTile(out, obuf, col, row, 0, s) < 0) {
1296
bufp += nrow * iimagew;
1303
* Contig strips -> contig tiles.
1305
DECLAREcpFunc(cpContigStrips2ContigTiles)
1307
return cpImage(in, out,
1308
readContigStripsIntoBuffer,
1309
writeBufferToContigTiles,
1310
imagelength, imagewidth, spp);
1314
* Contig strips -> separate tiles.
1316
DECLAREcpFunc(cpContigStrips2SeparateTiles)
1318
return cpImage(in, out,
1319
readContigStripsIntoBuffer,
1320
writeBufferToSeparateTiles,
1321
imagelength, imagewidth, spp);
1325
* Separate strips -> contig tiles.
1327
DECLAREcpFunc(cpSeparateStrips2ContigTiles)
1329
return cpImage(in, out,
1330
readSeparateStripsIntoBuffer,
1331
writeBufferToContigTiles,
1332
imagelength, imagewidth, spp);
1336
* Separate strips -> separate tiles.
1338
DECLAREcpFunc(cpSeparateStrips2SeparateTiles)
1340
return cpImage(in, out,
1341
readSeparateStripsIntoBuffer,
1342
writeBufferToSeparateTiles,
1343
imagelength, imagewidth, spp);
1347
* Contig strips -> contig tiles.
1349
DECLAREcpFunc(cpContigTiles2ContigTiles)
1351
return cpImage(in, out,
1352
readContigTilesIntoBuffer,
1353
writeBufferToContigTiles,
1354
imagelength, imagewidth, spp);
1358
* Contig tiles -> separate tiles.
1360
DECLAREcpFunc(cpContigTiles2SeparateTiles)
1362
return cpImage(in, out,
1363
readContigTilesIntoBuffer,
1364
writeBufferToSeparateTiles,
1365
imagelength, imagewidth, spp);
1369
* Separate tiles -> contig tiles.
1371
DECLAREcpFunc(cpSeparateTiles2ContigTiles)
1373
return cpImage(in, out,
1374
readSeparateTilesIntoBuffer,
1375
writeBufferToContigTiles,
1376
imagelength, imagewidth, spp);
1380
* Separate tiles -> separate tiles (tile dimension change).
1382
DECLAREcpFunc(cpSeparateTiles2SeparateTiles)
1384
return cpImage(in, out,
1385
readSeparateTilesIntoBuffer,
1386
writeBufferToSeparateTiles,
1387
imagelength, imagewidth, spp);
1391
* Contig tiles -> contig tiles (tile dimension change).
1393
DECLAREcpFunc(cpContigTiles2ContigStrips)
1395
return cpImage(in, out,
1396
readContigTilesIntoBuffer,
1397
writeBufferToContigStrips,
1398
imagelength, imagewidth, spp);
1402
* Contig tiles -> separate strips.
1404
DECLAREcpFunc(cpContigTiles2SeparateStrips)
1406
return cpImage(in, out,
1407
readContigTilesIntoBuffer,
1408
writeBufferToSeparateStrips,
1409
imagelength, imagewidth, spp);
1413
* Separate tiles -> contig strips.
1415
DECLAREcpFunc(cpSeparateTiles2ContigStrips)
1417
return cpImage(in, out,
1418
readSeparateTilesIntoBuffer,
1419
writeBufferToContigStrips,
1420
imagelength, imagewidth, spp);
1424
* Separate tiles -> separate strips.
1426
DECLAREcpFunc(cpSeparateTiles2SeparateStrips)
1428
return cpImage(in, out,
1429
readSeparateTilesIntoBuffer,
1430
writeBufferToSeparateStrips,
1431
imagelength, imagewidth, spp);
1435
* Select the appropriate copy function to use.
1438
pickCopyFunc(TIFF* in, TIFF* out, uint16 bitspersample, uint16 samplesperpixel)
1441
uint32 w, l, tw, tl;
1444
(void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv);
1445
if (shortv != config && bitspersample != 8 && samplesperpixel > 1) {
1447
"%s: Cannot handle different planar configuration w/ bits/sample != 8\n",
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 */
1461
"%s: Cannot handle tiled configuration w/bias image\n",
1465
if (TIFFIsTiled(out)) {
1466
if (!TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw))
1468
if (!TIFFGetField(in, TIFFTAG_TILELENGTH, &tl))
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);
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;
1538
fprintf(stderr, "tiffcp: %s: Don't know how to copy/convert image.\n",