1
/* $Id: tiffcp.c,v 1.37.2.1 2009-01-01 00:10:43 bfriesen 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
41
#include "tif_config.h"
57
extern int getopt(int, char**, char*);
61
# define unlink delete
64
#define streq(a,b) (strcmp(a,b) == 0)
65
#define strneq(a,b,n) (strncmp(a,b,n) == 0)
70
static int outtiled = -1;
71
static uint32 tilewidth;
72
static uint32 tilelength;
75
static uint16 compression;
76
static uint16 predictor;
77
static uint16 fillorder;
78
static uint16 orientation;
79
static uint32 rowsperstrip;
81
static int ignore = FALSE; /* if true, ignore read errors */
82
static uint32 defg3opts = (uint32) -1;
83
static int quality = 75; /* JPEG quality */
84
static int jpegcolormode = JPEGCOLORMODE_RGB;
85
static uint16 defcompression = (uint16) -1;
86
static uint16 defpredictor = (uint16) -1;
88
static int tiffcp(TIFF*, TIFF*);
89
static int processCompressOptions(char*);
90
static void usage(void);
92
static char comma = ','; /* (default) comma separator character */
93
static TIFF* bias = NULL;
94
static int pageNum = 0;
96
static int nextSrcImage (TIFF *tif, char **imageSpec)
98
seek to the next image specified in *imageSpec
99
returns 1 if success, 0 if no more images to process
100
*imageSpec=NULL if subsequent images should be processed in sequence
103
if (**imageSpec == comma) { /* if not @comma, we've done all images */
104
char *start = *imageSpec + 1;
105
tdir_t nextImage = (tdir_t)strtol(start, imageSpec, 0);
106
if (start == *imageSpec) nextImage = TIFFCurrentDirectory (tif);
109
if (**imageSpec == comma) {
110
/* a trailing comma denotes remaining images in sequence */
111
if ((*imageSpec)[1] == '\0') *imageSpec = NULL;
114
"Expected a %c separated image # list after %s\n",
115
comma, TIFFFileName (tif));
116
exit (-4); /* syntax error */
119
if (TIFFSetDirectory (tif, nextImage)) return 1;
120
fprintf (stderr, "%s%c%d not found!\n",
121
TIFFFileName(tif), comma, (int) nextImage);
127
static TIFF* openSrcImage (char **imageSpec)
129
imageSpec points to a pointer to a filename followed by optional ,image#'s
130
Open the TIFF file and assign *imageSpec to either NULL if there are
131
no images specified, or a pointer to the next image number text
135
char *fn = *imageSpec;
136
*imageSpec = strchr (fn, comma);
137
if (*imageSpec) { /* there is at least one image number specifier */
139
tif = TIFFOpen (fn, "r");
140
/* but, ignore any single trailing comma */
141
if (!(*imageSpec)[1]) {*imageSpec = NULL; return tif;}
143
**imageSpec = comma; /* replace the comma */
144
if (!nextSrcImage(tif, imageSpec)) {
150
tif = TIFFOpen (fn, "r");
156
main(int argc, char* argv[])
158
uint16 defconfig = (uint16) -1;
159
uint16 deffillorder = 0;
160
uint32 deftilewidth = (uint32) -1;
161
uint32 deftilelength = (uint32) -1;
162
uint32 defrowsperstrip = (uint32) 0;
174
while ((c = getopt(argc, argv, ",:b:c:f:l:o:z:p:r:w:aistBLMC")) != -1)
177
if (optarg[0] != '=') usage();
180
case 'b': /* this file is bias image subtracted from others */
182
fputs ("Only 1 bias image may be specified\n", stderr);
186
uint16 samples = (uint16) -1;
187
char **biasFn = &optarg;
188
bias = openSrcImage (biasFn);
189
if (!bias) exit (-5);
190
if (TIFFIsTiled (bias)) {
191
fputs ("Bias image must be organized in strips\n", stderr);
194
TIFFGetField(bias, TIFFTAG_SAMPLESPERPIXEL, &samples);
196
fputs ("Bias image must be monochrome\n", stderr);
201
case 'a': /* append to output */
204
case 'c': /* compression scheme */
205
if (!processCompressOptions(optarg))
208
case 'f': /* fill order */
209
if (streq(optarg, "lsb2msb"))
210
deffillorder = FILLORDER_LSB2MSB;
211
else if (streq(optarg, "msb2lsb"))
212
deffillorder = FILLORDER_MSB2LSB;
216
case 'i': /* ignore errors */
219
case 'l': /* tile length */
221
deftilelength = atoi(optarg);
223
case 'o': /* initial directory offset */
224
diroff = strtoul(optarg, NULL, 0);
226
case 'p': /* planar configuration */
227
if (streq(optarg, "separate"))
228
defconfig = PLANARCONFIG_SEPARATE;
229
else if (streq(optarg, "contig"))
230
defconfig = PLANARCONFIG_CONTIG;
234
case 'r': /* rows/strip */
235
defrowsperstrip = atol(optarg);
237
case 's': /* generate stripped output */
240
case 't': /* generate tiled output */
243
case 'w': /* tile width */
245
deftilewidth = atoi(optarg);
248
*mp++ = 'b'; *mp = '\0';
251
*mp++ = 'l'; *mp = '\0';
254
*mp++ = 'm'; *mp = '\0';
257
*mp++ = 'c'; *mp = '\0';
263
if (argc - optind < 2)
265
out = TIFFOpen(argv[argc-1], mode);
268
if ((argc - optind) == 2)
270
for (; optind < argc-1 ; optind++) {
271
char *imageCursor = argv[optind];
272
in = openSrcImage (&imageCursor);
275
if (diroff != 0 && !TIFFSetSubDirectory(in, diroff)) {
276
TIFFError(TIFFFileName(in),
277
"Error, setting subdirectory at %#x", diroff);
278
(void) TIFFClose(out);
283
compression = defcompression;
284
predictor = defpredictor;
285
fillorder = deffillorder;
286
rowsperstrip = defrowsperstrip;
287
tilewidth = deftilewidth;
288
tilelength = deftilelength;
290
if (!tiffcp(in, out) || !TIFFWriteDirectory(out)) {
294
if (imageCursor) { /* seek next image directory */
295
if (!nextSrcImage(in, &imageCursor)) break;
297
if (!TIFFReadDirectory(in)) break;
308
processG3Options(char* cp)
310
if( (cp = strchr(cp, ':')) ) {
311
if (defg3opts == (uint32) -1)
315
if (strneq(cp, "1d", 2))
316
defg3opts &= ~GROUP3OPT_2DENCODING;
317
else if (strneq(cp, "2d", 2))
318
defg3opts |= GROUP3OPT_2DENCODING;
319
else if (strneq(cp, "fill", 4))
320
defg3opts |= GROUP3OPT_FILLBITS;
323
} while( (cp = strchr(cp, ':')) );
328
processCompressOptions(char* opt)
330
if (streq(opt, "none")) {
331
defcompression = COMPRESSION_NONE;
332
} else if (streq(opt, "packbits")) {
333
defcompression = COMPRESSION_PACKBITS;
334
} else if (strneq(opt, "jpeg", 4)) {
335
char* cp = strchr(opt, ':');
337
defcompression = COMPRESSION_JPEG;
340
if (isdigit((int)cp[1]))
341
quality = atoi(cp+1);
342
else if (cp[1] == 'r' )
343
jpegcolormode = JPEGCOLORMODE_RAW;
347
cp = strchr(cp+1,':');
349
} else if (strneq(opt, "g3", 2)) {
350
processG3Options(opt);
351
defcompression = COMPRESSION_CCITTFAX3;
352
} else if (streq(opt, "g4")) {
353
defcompression = COMPRESSION_CCITTFAX4;
354
} else if (strneq(opt, "lzw", 3)) {
355
char* cp = strchr(opt, ':');
357
defpredictor = atoi(cp+1);
358
defcompression = COMPRESSION_LZW;
359
} else if (strneq(opt, "zip", 3)) {
360
char* cp = strchr(opt, ':');
362
defpredictor = atoi(cp+1);
363
defcompression = COMPRESSION_ADOBE_DEFLATE;
364
} else if (strneq(opt, "jbig", 4)) {
365
defcompression = COMPRESSION_JBIG;
372
"usage: tiffcp [options] input... output",
373
"where options are:",
374
" -a append to output instead of overwriting",
375
" -o offset set initial directory offset",
376
" -p contig pack samples contiguously (e.g. RGBRGB...)",
377
" -p separate store samples separately (e.g. RRR...GGG...BBB...)",
378
" -s write output in strips",
379
" -t write output in tiles",
380
" -i ignore read errors",
381
" -b file[,#] bias (dark) monochrome image to be subtracted from all others",
382
" -,=% use % rather than , to separate image #'s (per Note below)",
384
" -r # make each strip have no more than # rows",
385
" -w # set output tile width (pixels)",
386
" -l # set output tile length (pixels)",
388
" -f lsb2msb force lsb-to-msb FillOrder for output",
389
" -f msb2lsb force msb-to-lsb FillOrder for output",
391
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
392
" -c zip[:opts] compress output with deflate encoding",
393
" -c jpeg[:opts] compress output with JPEG encoding",
394
" -c jbig compress output with ISO JBIG encoding",
395
" -c packbits compress output with packbits encoding",
396
" -c g3[:opts] compress output with CCITT Group 3 encoding",
397
" -c g4 compress output with CCITT Group 4 encoding",
398
" -c none use no compression algorithm on output",
401
" 1d use default CCITT Group 3 1D-encoding",
402
" 2d use optional CCITT Group 3 2D-encoding",
403
" fill byte-align EOL codes",
404
"For example, -c g3:2d:fill to get G3-2D-encoded data with byte-aligned EOLs",
407
" # set compression quality level (0-100, default 75)",
408
" r output color image as RGB rather than YCbCr",
409
"For example, -c jpeg:r:50 to get JPEG-encoded RGB data with 50% comp. quality",
411
"LZW and deflate options:",
412
" # set predictor value",
413
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
415
"Note that input filenames may be of the form filename,x,y,z",
416
"where x, y, and z specify image numbers in the filename to copy.",
417
"example: tiffcp -c none -b esp.tif,1 esp.tif,0 test.tif",
418
" subtract 2nd image in esp.tif from 1st yielding uncompressed result test.tif",
429
fprintf(stderr, "%s\n\n", TIFFGetVersion());
430
for (i = 0; stuff[i] != NULL; i++)
431
fprintf(stderr, "%s\n", stuff[i]);
435
#define CopyField(tag, v) \
436
if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
437
#define CopyField2(tag, v1, v2) \
438
if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
439
#define CopyField3(tag, v1, v2, v3) \
440
if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
441
#define CopyField4(tag, v1, v2, v3, v4) \
442
if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4)
445
cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type)
451
CopyField(tag, shortv);
452
} else if (count == 2) {
453
uint16 shortv1, shortv2;
454
CopyField2(tag, shortv1, shortv2);
455
} else if (count == 4) {
456
uint16 *tr, *tg, *tb, *ta;
457
CopyField4(tag, tr, tg, tb, ta);
458
} else if (count == (uint16) -1) {
461
CopyField2(tag, shortv1, shortav);
466
CopyField(tag, longv);
472
CopyField(tag, floatv);
473
} else if (count == (uint16) -1) {
475
CopyField(tag, floatav);
480
CopyField(tag, stringv);
486
CopyField(tag, doublev);
487
} else if (count == (uint16) -1) {
489
CopyField(tag, doubleav);
493
TIFFError(TIFFFileName(in),
494
"Data type %d is not supported, tag %d skipped.",
499
static struct cpTag {
504
{ TIFFTAG_SUBFILETYPE, 1, TIFF_LONG },
505
{ TIFFTAG_THRESHHOLDING, 1, TIFF_SHORT },
506
{ TIFFTAG_DOCUMENTNAME, 1, TIFF_ASCII },
507
{ TIFFTAG_IMAGEDESCRIPTION, 1, TIFF_ASCII },
508
{ TIFFTAG_MAKE, 1, TIFF_ASCII },
509
{ TIFFTAG_MODEL, 1, TIFF_ASCII },
510
{ TIFFTAG_MINSAMPLEVALUE, 1, TIFF_SHORT },
511
{ TIFFTAG_MAXSAMPLEVALUE, 1, TIFF_SHORT },
512
{ TIFFTAG_XRESOLUTION, 1, TIFF_RATIONAL },
513
{ TIFFTAG_YRESOLUTION, 1, TIFF_RATIONAL },
514
{ TIFFTAG_PAGENAME, 1, TIFF_ASCII },
515
{ TIFFTAG_XPOSITION, 1, TIFF_RATIONAL },
516
{ TIFFTAG_YPOSITION, 1, TIFF_RATIONAL },
517
{ TIFFTAG_RESOLUTIONUNIT, 1, TIFF_SHORT },
518
{ TIFFTAG_SOFTWARE, 1, TIFF_ASCII },
519
{ TIFFTAG_DATETIME, 1, TIFF_ASCII },
520
{ TIFFTAG_ARTIST, 1, TIFF_ASCII },
521
{ TIFFTAG_HOSTCOMPUTER, 1, TIFF_ASCII },
522
{ TIFFTAG_WHITEPOINT, (uint16) -1, TIFF_RATIONAL },
523
{ TIFFTAG_PRIMARYCHROMATICITIES,(uint16) -1,TIFF_RATIONAL },
524
{ TIFFTAG_HALFTONEHINTS, 2, TIFF_SHORT },
525
{ TIFFTAG_INKSET, 1, TIFF_SHORT },
526
{ TIFFTAG_DOTRANGE, 2, TIFF_SHORT },
527
{ TIFFTAG_TARGETPRINTER, 1, TIFF_ASCII },
528
{ TIFFTAG_SAMPLEFORMAT, 1, TIFF_SHORT },
529
{ TIFFTAG_YCBCRCOEFFICIENTS, (uint16) -1,TIFF_RATIONAL },
530
{ TIFFTAG_YCBCRSUBSAMPLING, 2, TIFF_SHORT },
531
{ TIFFTAG_YCBCRPOSITIONING, 1, TIFF_SHORT },
532
{ TIFFTAG_REFERENCEBLACKWHITE, (uint16) -1,TIFF_RATIONAL },
533
{ TIFFTAG_EXTRASAMPLES, (uint16) -1, TIFF_SHORT },
534
{ TIFFTAG_SMINSAMPLEVALUE, 1, TIFF_DOUBLE },
535
{ TIFFTAG_SMAXSAMPLEVALUE, 1, TIFF_DOUBLE },
536
{ TIFFTAG_STONITS, 1, TIFF_DOUBLE },
538
#define NTAGS (sizeof (tags) / sizeof (tags[0]))
540
#define CopyTag(tag, count, type) cpTag(in, out, tag, count, type)
542
typedef int (*copyFunc)
543
(TIFF* in, TIFF* out, uint32 l, uint32 w, uint16 samplesperpixel);
544
static copyFunc pickCopyFunc(TIFF*, TIFF*, uint16, uint16);
547
tiffcp(TIFF* in, TIFF* out)
549
uint16 bitspersample, samplesperpixel;
551
uint32 width, length;
554
CopyField(TIFFTAG_IMAGEWIDTH, width);
555
CopyField(TIFFTAG_IMAGELENGTH, length);
556
CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample);
557
CopyField(TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
558
if (compression != (uint16)-1)
559
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
561
CopyField(TIFFTAG_COMPRESSION, compression);
562
if (compression == COMPRESSION_JPEG) {
563
uint16 input_compression, input_photometric;
565
if (TIFFGetField(in, TIFFTAG_COMPRESSION, &input_compression)
566
&& input_compression == COMPRESSION_JPEG) {
567
TIFFSetField(in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
569
if (TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &input_photometric)) {
570
if(input_photometric == PHOTOMETRIC_RGB) {
571
if (jpegcolormode == JPEGCOLORMODE_RGB)
572
TIFFSetField(out, TIFFTAG_PHOTOMETRIC,
575
TIFFSetField(out, TIFFTAG_PHOTOMETRIC,
578
TIFFSetField(out, TIFFTAG_PHOTOMETRIC,
582
else if (compression == COMPRESSION_SGILOG
583
|| compression == COMPRESSION_SGILOG24)
584
TIFFSetField(out, TIFFTAG_PHOTOMETRIC,
585
samplesperpixel == 1 ?
586
PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
588
CopyTag(TIFFTAG_PHOTOMETRIC, 1, TIFF_SHORT);
590
TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
592
CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
594
* Will copy `Orientation' tag from input image
596
TIFFGetFieldDefaulted(in, TIFFTAG_ORIENTATION, &orientation);
597
switch (orientation) {
598
case ORIENTATION_BOTRIGHT:
599
case ORIENTATION_RIGHTBOT: /* XXX */
600
TIFFWarning(TIFFFileName(in), "using bottom-left orientation");
601
orientation = ORIENTATION_BOTLEFT;
603
case ORIENTATION_LEFTBOT: /* XXX */
604
case ORIENTATION_BOTLEFT:
606
case ORIENTATION_TOPRIGHT:
607
case ORIENTATION_RIGHTTOP: /* XXX */
609
TIFFWarning(TIFFFileName(in), "using top-left orientation");
610
orientation = ORIENTATION_TOPLEFT;
612
case ORIENTATION_LEFTTOP: /* XXX */
613
case ORIENTATION_TOPLEFT:
616
TIFFSetField(out, TIFFTAG_ORIENTATION, orientation);
618
* Choose tiles/strip for the output image according to
619
* the command line arguments (-tiles, -strips) and the
620
* structure of the input image.
623
outtiled = TIFFIsTiled(in);
626
* Setup output file's tile width&height. If either
627
* is not specified, use either the value from the
628
* input image or, if nothing is defined, use the
631
if (tilewidth == (uint32) -1)
632
TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
633
if (tilelength == (uint32) -1)
634
TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
635
TIFFDefaultTileSize(out, &tilewidth, &tilelength);
636
TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
637
TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
640
* RowsPerStrip is left unspecified: use either the
641
* value from the input image or, if nothing is defined,
642
* use the library default.
644
if (rowsperstrip == (uint32) 0) {
645
if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP,
648
TIFFDefaultStripSize(out, rowsperstrip);
650
if (rowsperstrip > length && rowsperstrip != (uint32)-1)
651
rowsperstrip = length;
653
else if (rowsperstrip == (uint32) -1)
654
rowsperstrip = length;
655
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
657
if (config != (uint16) -1)
658
TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
660
CopyField(TIFFTAG_PLANARCONFIG, config);
661
if (samplesperpixel <= 4)
662
CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
663
CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
664
/* SMinSampleValue & SMaxSampleValue */
665
switch (compression) {
666
case COMPRESSION_JPEG:
667
TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
668
TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
670
case COMPRESSION_JBIG:
671
CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
672
CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
673
CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
674
CopyTag(TIFFTAG_FAXDCS, 1, TIFF_ASCII);
676
case COMPRESSION_LZW:
677
case COMPRESSION_ADOBE_DEFLATE:
678
case COMPRESSION_DEFLATE:
679
if (predictor != (uint16)-1)
680
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
682
CopyField(TIFFTAG_PREDICTOR, predictor);
684
case COMPRESSION_CCITTFAX3:
685
case COMPRESSION_CCITTFAX4:
686
if (compression == COMPRESSION_CCITTFAX3) {
687
if (g3opts != (uint32) -1)
688
TIFFSetField(out, TIFFTAG_GROUP3OPTIONS,
691
CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
693
CopyTag(TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG);
694
CopyTag(TIFFTAG_BADFAXLINES, 1, TIFF_LONG);
695
CopyTag(TIFFTAG_CLEANFAXDATA, 1, TIFF_LONG);
696
CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG);
697
CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
698
CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
699
CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
704
if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
705
TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
708
const char* inknames;
709
if (TIFFGetField(in, TIFFTAG_NUMBEROFINKS, &ninks)) {
710
TIFFSetField(out, TIFFTAG_NUMBEROFINKS, ninks);
711
if (TIFFGetField(in, TIFFTAG_INKNAMES, &inknames)) {
712
int inknameslen = strlen(inknames) + 1;
713
const char* cp = inknames;
715
cp = strchr(cp, '\0');
718
inknameslen += (strlen(cp) + 1);
722
TIFFSetField(out, TIFFTAG_INKNAMES, inknameslen, inknames);
727
unsigned short pg0, pg1;
728
if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1)) {
729
if (pageNum < 0) /* only one input file */
730
TIFFSetField(out, TIFFTAG_PAGENUMBER, pg0, pg1);
732
TIFFSetField(out, TIFFTAG_PAGENUMBER, pageNum++, 0);
736
for (p = tags; p < &tags[NTAGS]; p++)
737
CopyTag(p->tag, p->count, p->type);
739
cf = pickCopyFunc(in, out, bitspersample, samplesperpixel);
740
return (cf ? (*cf)(in, out, length, width, samplesperpixel) : FALSE);
746
#define DECLAREcpFunc(x) \
747
static int x(TIFF* in, TIFF* out, \
748
uint32 imagelength, uint32 imagewidth, tsample_t spp)
750
#define DECLAREreadFunc(x) \
751
static int x(TIFF* in, \
752
uint8* buf, uint32 imagelength, uint32 imagewidth, tsample_t spp)
753
typedef int (*readFunc)(TIFF*, uint8*, uint32, uint32, tsample_t);
755
#define DECLAREwriteFunc(x) \
756
static int x(TIFF* out, \
757
uint8* buf, uint32 imagelength, uint32 imagewidth, tsample_t spp)
758
typedef int (*writeFunc)(TIFF*, uint8*, uint32, uint32, tsample_t);
761
* Contig -> contig by scanline for rows/strip change.
763
DECLAREcpFunc(cpContig2ContigByRow)
765
tdata_t buf = _TIFFmalloc(TIFFScanlineSize(in));
768
(void) imagewidth; (void) spp;
769
for (row = 0; row < imagelength; row++) {
770
if (TIFFReadScanline(in, buf, row, 0) < 0 && !ignore) {
771
TIFFError(TIFFFileName(in),
772
"Error, can't read scanline %lu",
773
(unsigned long) row);
776
if (TIFFWriteScanline(out, buf, row, 0) < 0) {
777
TIFFError(TIFFFileName(out),
778
"Error, can't write scanline %lu",
779
(unsigned long) row);
791
typedef void biasFn (void *image, void *bias, uint32 pixels);
793
#define subtract(bits) \
794
static void subtract##bits (void *i, void *b, uint32 pixels)\
796
uint##bits *image = i;\
797
uint##bits *bias = b;\
799
*image = *image > *bias ? *image-*bias : 0;\
808
static biasFn *lineSubtractFn (unsigned bits)
811
case 8: return subtract8;
812
case 16: return subtract16;
813
case 32: return subtract32;
819
* Contig -> contig by scanline while subtracting a bias image.
821
DECLAREcpFunc(cpBiasedContig2Contig)
824
tsize_t biasSize = TIFFScanlineSize(bias);
825
tsize_t bufSize = TIFFScanlineSize(in);
826
tdata_t buf, biasBuf;
827
uint32 biasWidth = 0, biasLength = 0;
828
TIFFGetField(bias, TIFFTAG_IMAGEWIDTH, &biasWidth);
829
TIFFGetField(bias, TIFFTAG_IMAGELENGTH, &biasLength);
830
if (biasSize == bufSize &&
831
imagelength == biasLength && imagewidth == biasWidth) {
832
uint16 sampleBits = 0;
833
biasFn *subtractLine;
834
TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &sampleBits);
835
subtractLine = lineSubtractFn (sampleBits);
838
buf = _TIFFmalloc(bufSize);
839
biasBuf = _TIFFmalloc(bufSize);
840
for (row = 0; row < imagelength; row++) {
841
if (TIFFReadScanline(in, buf, row, 0) < 0
843
TIFFError(TIFFFileName(in),
844
"Error, can't read scanline %lu",
845
(unsigned long) row);
848
if (TIFFReadScanline(bias, biasBuf, row, 0) < 0
850
TIFFError(TIFFFileName(in),
851
"Error, can't read biased scanline %lu",
852
(unsigned long) row);
855
subtractLine (buf, biasBuf, imagewidth);
856
if (TIFFWriteScanline(out, buf, row, 0) < 0) {
857
TIFFError(TIFFFileName(out),
858
"Error, can't write scanline %lu",
859
(unsigned long) row);
866
TIFFSetDirectory(bias,
867
TIFFCurrentDirectory(bias)); /* rewind */
874
TIFFError(TIFFFileName(in),
875
"No support for biasing %d bit pixels\n",
880
TIFFError(TIFFFileName(in),
881
"Bias image %s,%d\nis not the same size as %s,%d\n",
882
TIFFFileName(bias), TIFFCurrentDirectory(bias),
883
TIFFFileName(in), TIFFCurrentDirectory(in));
886
TIFFError(TIFFFileName(in),
887
"Can't bias %s,%d as it has >1 Sample/Pixel\n",
888
TIFFFileName(in), TIFFCurrentDirectory(in));
896
* Strip -> strip for change in encoding.
898
DECLAREcpFunc(cpDecodedStrips)
900
tsize_t stripsize = TIFFStripSize(in);
901
tdata_t buf = _TIFFmalloc(stripsize);
903
(void) imagewidth; (void) spp;
905
tstrip_t s, ns = TIFFNumberOfStrips(in);
907
for (s = 0; s < ns; s++) {
908
tsize_t cc = (row + rowsperstrip > imagelength) ?
909
TIFFVStripSize(in, imagelength - row) : stripsize;
910
if (TIFFReadEncodedStrip(in, s, buf, cc) < 0
912
TIFFError(TIFFFileName(in),
913
"Error, can't read strip %lu",
917
if (TIFFWriteEncodedStrip(out, s, buf, cc) < 0) {
918
TIFFError(TIFFFileName(out),
919
"Error, can't write strip %lu",
928
TIFFError(TIFFFileName(in),
929
"Error, can't allocate memory buffer of size %lu "
930
"to read strips", (unsigned long) stripsize);
940
* Separate -> separate by row for rows/strip change.
942
DECLAREcpFunc(cpSeparate2SeparateByRow)
944
tdata_t buf = _TIFFmalloc(TIFFScanlineSize(in));
949
for (s = 0; s < spp; s++) {
950
for (row = 0; row < imagelength; row++) {
951
if (TIFFReadScanline(in, buf, row, s) < 0 && !ignore) {
952
TIFFError(TIFFFileName(in),
953
"Error, can't read scanline %lu",
954
(unsigned long) row);
957
if (TIFFWriteScanline(out, buf, row, s) < 0) {
958
TIFFError(TIFFFileName(out),
959
"Error, can't write scanline %lu",
960
(unsigned long) row);
973
* Contig -> separate by row.
975
DECLAREcpFunc(cpContig2SeparateByRow)
977
tdata_t inbuf = _TIFFmalloc(TIFFScanlineSize(in));
978
tdata_t outbuf = _TIFFmalloc(TIFFScanlineSize(out));
979
register uint8 *inp, *outp;
984
/* unpack channels */
985
for (s = 0; s < spp; s++) {
986
for (row = 0; row < imagelength; row++) {
987
if (TIFFReadScanline(in, inbuf, row, 0) < 0
989
TIFFError(TIFFFileName(in),
990
"Error, can't read scanline %lu",
991
(unsigned long) row);
994
inp = ((uint8*)inbuf) + s;
995
outp = (uint8*)outbuf;
996
for (n = imagewidth; n-- > 0;) {
1000
if (TIFFWriteScanline(out, outbuf, row, s) < 0) {
1001
TIFFError(TIFFFileName(out),
1002
"Error, can't write scanline %lu",
1003
(unsigned long) row);
1008
if (inbuf) _TIFFfree(inbuf);
1009
if (outbuf) _TIFFfree(outbuf);
1012
if (inbuf) _TIFFfree(inbuf);
1013
if (outbuf) _TIFFfree(outbuf);
1018
* Separate -> contig by row.
1020
DECLAREcpFunc(cpSeparate2ContigByRow)
1022
tdata_t inbuf = _TIFFmalloc(TIFFScanlineSize(in));
1023
tdata_t outbuf = _TIFFmalloc(TIFFScanlineSize(out));
1024
register uint8 *inp, *outp;
1029
for (row = 0; row < imagelength; row++) {
1030
/* merge channels */
1031
for (s = 0; s < spp; s++) {
1032
if (TIFFReadScanline(in, inbuf, row, s) < 0
1034
TIFFError(TIFFFileName(in),
1035
"Error, can't read scanline %lu",
1036
(unsigned long) row);
1039
inp = (uint8*)inbuf;
1040
outp = ((uint8*)outbuf) + s;
1041
for (n = imagewidth; n-- > 0;) {
1046
if (TIFFWriteScanline(out, outbuf, row, 0) < 0) {
1047
TIFFError(TIFFFileName(out),
1048
"Error, can't write scanline %lu",
1049
(unsigned long) row);
1053
if (inbuf) _TIFFfree(inbuf);
1054
if (outbuf) _TIFFfree(outbuf);
1057
if (inbuf) _TIFFfree(inbuf);
1058
if (outbuf) _TIFFfree(outbuf);
1063
cpStripToTile(uint8* out, uint8* in,
1064
uint32 rows, uint32 cols, int outskew, int inskew)
1066
while (rows-- > 0) {
1076
cpContigBufToSeparateBuf(uint8* out, uint8* in,
1077
uint32 rows, uint32 cols, int outskew, int inskew, tsample_t spp,
1078
int bytes_per_sample )
1080
while (rows-- > 0) {
1084
int n = bytes_per_sample;
1089
in += (spp-1) * bytes_per_sample;
1097
cpSeparateBufToContigBuf(uint8* out, uint8* in,
1098
uint32 rows, uint32 cols, int outskew, int inskew, tsample_t spp,
1099
int bytes_per_sample)
1101
while (rows-- > 0) {
1104
int n = bytes_per_sample;
1109
out += (spp-1)*bytes_per_sample;
1117
cpImage(TIFF* in, TIFF* out, readFunc fin, writeFunc fout,
1118
uint32 imagelength, uint32 imagewidth, tsample_t spp)
1122
tsize_t scanlinesize = TIFFRasterScanlineSize(in);
1123
tsize_t bytes = scanlinesize * (tsize_t)imagelength;
1125
* XXX: Check for integer overflow.
1129
&& bytes / (tsize_t)imagelength == scanlinesize) {
1130
buf = _TIFFmalloc(bytes);
1132
if ((*fin)(in, (uint8*)buf, imagelength,
1134
status = (*fout)(out, (uint8*)buf,
1135
imagelength, imagewidth, spp);
1139
TIFFError(TIFFFileName(in),
1140
"Error, can't allocate space for image buffer");
1143
TIFFError(TIFFFileName(in), "Error, no space for image buffer");
1149
DECLAREreadFunc(readContigStripsIntoBuffer)
1151
tsize_t scanlinesize = TIFFScanlineSize(in);
1155
(void) imagewidth; (void) spp;
1156
for (row = 0; row < imagelength; row++) {
1157
if (TIFFReadScanline(in, (tdata_t) bufp, row, 0) < 0
1159
TIFFError(TIFFFileName(in),
1160
"Error, can't read scanline %lu",
1161
(unsigned long) row);
1164
bufp += scanlinesize;
1170
DECLAREreadFunc(readSeparateStripsIntoBuffer)
1173
tsize_t scanlinesize = TIFFScanlineSize(in);
1174
tdata_t scanline = _TIFFmalloc(scanlinesize);
1180
uint8* bufp = (uint8*) buf;
1183
for (row = 0; row < imagelength; row++) {
1184
/* merge channels */
1185
for (s = 0; s < spp; s++) {
1186
uint8* bp = bufp + s;
1187
tsize_t n = scanlinesize;
1188
uint8* sbuf = scanline;
1190
if (TIFFReadScanline(in, scanline, row, s) < 0
1192
TIFFError(TIFFFileName(in),
1193
"Error, can't read scanline %lu",
1194
(unsigned long) row);
1199
*bp = *sbuf++, bp += spp;
1201
bufp += scanlinesize * spp;
1206
_TIFFfree(scanline);
1210
DECLAREreadFunc(readContigTilesIntoBuffer)
1213
tdata_t tilebuf = _TIFFmalloc(TIFFTileSize(in));
1214
uint32 imagew = TIFFScanlineSize(in);
1215
uint32 tilew = TIFFTileRowSize(in);
1216
int iskew = imagew - tilew;
1217
uint8* bufp = (uint8*) buf;
1224
(void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
1225
(void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
1227
for (row = 0; row < imagelength; row += tl) {
1228
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
1232
for (col = 0; col < imagewidth; col += tw) {
1233
if (TIFFReadTile(in, tilebuf, col, row, 0, 0) < 0
1235
TIFFError(TIFFFileName(in),
1236
"Error, can't read tile at %lu %lu",
1237
(unsigned long) col,
1238
(unsigned long) row);
1242
if (colb + tilew > imagew) {
1243
uint32 width = imagew - colb;
1244
uint32 oskew = tilew - width;
1245
cpStripToTile(bufp + colb,
1246
tilebuf, nrow, width,
1247
oskew + iskew, oskew );
1249
cpStripToTile(bufp + colb,
1250
tilebuf, nrow, tilew,
1254
bufp += imagew * nrow;
1261
DECLAREreadFunc(readSeparateTilesIntoBuffer)
1264
uint32 imagew = TIFFRasterScanlineSize(in);
1265
uint32 tilew = TIFFTileRowSize(in);
1266
int iskew = imagew - tilew*spp;
1267
tdata_t tilebuf = _TIFFmalloc(TIFFTileSize(in));
1268
uint8* bufp = (uint8*) buf;
1271
uint16 bps, bytes_per_sample;
1275
(void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
1276
(void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
1277
(void) TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps);
1278
assert( bps % 8 == 0 );
1279
bytes_per_sample = bps/8;
1281
for (row = 0; row < imagelength; row += tl) {
1282
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
1286
for (col = 0; col < imagewidth; col += tw) {
1289
for (s = 0; s < spp; s++) {
1290
if (TIFFReadTile(in, tilebuf, col, row, 0, s) < 0
1292
TIFFError(TIFFFileName(in),
1293
"Error, can't read tile at %lu %lu, "
1295
(unsigned long) col,
1296
(unsigned long) row,
1302
* Tile is clipped horizontally. Calculate
1303
* visible portion and skewing factors.
1305
if (colb + tilew*spp > imagew) {
1306
uint32 width = imagew - colb;
1307
int oskew = tilew*spp - width;
1308
cpSeparateBufToContigBuf(
1309
bufp+colb+s*bytes_per_sample,
1311
width/(spp*bytes_per_sample),
1316
cpSeparateBufToContigBuf(
1317
bufp+colb+s*bytes_per_sample,
1324
bufp += imagew * nrow;
1331
DECLAREwriteFunc(writeBufferToContigStrips)
1333
uint32 row, rowsperstrip;
1336
(void) imagewidth; (void) spp;
1337
(void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1338
for (row = 0; row < imagelength; row += rowsperstrip) {
1339
uint32 nrows = (row+rowsperstrip > imagelength) ?
1340
imagelength-row : rowsperstrip;
1341
tsize_t stripsize = TIFFVStripSize(out, nrows);
1342
if (TIFFWriteEncodedStrip(out, strip++, buf, stripsize) < 0) {
1343
TIFFError(TIFFFileName(out),
1344
"Error, can't write strip %u", strip - 1);
1352
DECLAREwriteFunc(writeBufferToSeparateStrips)
1354
uint32 rowsize = imagewidth * spp;
1355
uint32 rowsperstrip;
1356
tdata_t obuf = _TIFFmalloc(TIFFStripSize(out));
1362
(void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1363
for (s = 0; s < spp; s++) {
1365
for (row = 0; row < imagelength; row += rowsperstrip) {
1366
uint32 nrows = (row+rowsperstrip > imagelength) ?
1367
imagelength-row : rowsperstrip;
1368
tsize_t stripsize = TIFFVStripSize(out, nrows);
1370
cpContigBufToSeparateBuf(
1371
obuf, (uint8*) buf + row*rowsize + s,
1372
nrows, imagewidth, 0, 0, spp, 1);
1373
if (TIFFWriteEncodedStrip(out, strip++, obuf, stripsize) < 0) {
1374
TIFFError(TIFFFileName(out),
1375
"Error, can't write strip %u",
1387
DECLAREwriteFunc(writeBufferToContigTiles)
1389
uint32 imagew = TIFFScanlineSize(out);
1390
uint32 tilew = TIFFTileRowSize(out);
1391
int iskew = imagew - tilew;
1392
tdata_t obuf = _TIFFmalloc(TIFFTileSize(out));
1393
uint8* bufp = (uint8*) buf;
1400
(void) TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
1401
(void) TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
1402
for (row = 0; row < imagelength; row += tilelength) {
1403
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
1407
for (col = 0; col < imagewidth; col += tw) {
1409
* Tile is clipped horizontally. Calculate
1410
* visible portion and skewing factors.
1412
if (colb + tilew > imagew) {
1413
uint32 width = imagew - colb;
1414
int oskew = tilew - width;
1415
cpStripToTile(obuf, bufp + colb, nrow, width,
1416
oskew, oskew + iskew);
1418
cpStripToTile(obuf, bufp + colb, nrow, tilew,
1420
if (TIFFWriteTile(out, obuf, col, row, 0, 0) < 0) {
1421
TIFFError(TIFFFileName(out),
1422
"Error, can't write tile at %lu %lu",
1423
(unsigned long) col,
1424
(unsigned long) row);
1430
bufp += nrow * imagew;
1436
DECLAREwriteFunc(writeBufferToSeparateTiles)
1438
uint32 imagew = TIFFScanlineSize(out);
1439
tsize_t tilew = TIFFTileRowSize(out);
1440
uint32 iimagew = TIFFRasterScanlineSize(out);
1441
int iskew = iimagew - tilew*spp;
1442
tdata_t obuf = _TIFFmalloc(TIFFTileSize(out));
1443
uint8* bufp = (uint8*) buf;
1446
uint16 bps, bytes_per_sample;
1450
(void) TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
1451
(void) TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
1452
(void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
1453
assert( bps % 8 == 0 );
1454
bytes_per_sample = bps/8;
1456
for (row = 0; row < imagelength; row += tl) {
1457
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
1461
for (col = 0; col < imagewidth; col += tw) {
1463
for (s = 0; s < spp; s++) {
1465
* Tile is clipped horizontally. Calculate
1466
* visible portion and skewing factors.
1468
if (colb + tilew > imagew) {
1469
uint32 width = (imagew - colb);
1470
int oskew = tilew - width;
1472
cpContigBufToSeparateBuf(obuf,
1473
bufp + (colb*spp) + s,
1474
nrow, width/bytes_per_sample,
1475
oskew, (oskew*spp)+iskew, spp,
1478
cpContigBufToSeparateBuf(obuf,
1479
bufp + (colb*spp) + s,
1483
if (TIFFWriteTile(out, obuf, col, row, 0, s) < 0) {
1484
TIFFError(TIFFFileName(out),
1485
"Error, can't write tile at %lu %lu "
1487
(unsigned long) col,
1488
(unsigned long) row,
1496
bufp += nrow * iimagew;
1503
* Contig strips -> contig tiles.
1505
DECLAREcpFunc(cpContigStrips2ContigTiles)
1507
return cpImage(in, out,
1508
readContigStripsIntoBuffer,
1509
writeBufferToContigTiles,
1510
imagelength, imagewidth, spp);
1514
* Contig strips -> separate tiles.
1516
DECLAREcpFunc(cpContigStrips2SeparateTiles)
1518
return cpImage(in, out,
1519
readContigStripsIntoBuffer,
1520
writeBufferToSeparateTiles,
1521
imagelength, imagewidth, spp);
1525
* Separate strips -> contig tiles.
1527
DECLAREcpFunc(cpSeparateStrips2ContigTiles)
1529
return cpImage(in, out,
1530
readSeparateStripsIntoBuffer,
1531
writeBufferToContigTiles,
1532
imagelength, imagewidth, spp);
1536
* Separate strips -> separate tiles.
1538
DECLAREcpFunc(cpSeparateStrips2SeparateTiles)
1540
return cpImage(in, out,
1541
readSeparateStripsIntoBuffer,
1542
writeBufferToSeparateTiles,
1543
imagelength, imagewidth, spp);
1547
* Contig strips -> contig tiles.
1549
DECLAREcpFunc(cpContigTiles2ContigTiles)
1551
return cpImage(in, out,
1552
readContigTilesIntoBuffer,
1553
writeBufferToContigTiles,
1554
imagelength, imagewidth, spp);
1558
* Contig tiles -> separate tiles.
1560
DECLAREcpFunc(cpContigTiles2SeparateTiles)
1562
return cpImage(in, out,
1563
readContigTilesIntoBuffer,
1564
writeBufferToSeparateTiles,
1565
imagelength, imagewidth, spp);
1569
* Separate tiles -> contig tiles.
1571
DECLAREcpFunc(cpSeparateTiles2ContigTiles)
1573
return cpImage(in, out,
1574
readSeparateTilesIntoBuffer,
1575
writeBufferToContigTiles,
1576
imagelength, imagewidth, spp);
1580
* Separate tiles -> separate tiles (tile dimension change).
1582
DECLAREcpFunc(cpSeparateTiles2SeparateTiles)
1584
return cpImage(in, out,
1585
readSeparateTilesIntoBuffer,
1586
writeBufferToSeparateTiles,
1587
imagelength, imagewidth, spp);
1591
* Contig tiles -> contig tiles (tile dimension change).
1593
DECLAREcpFunc(cpContigTiles2ContigStrips)
1595
return cpImage(in, out,
1596
readContigTilesIntoBuffer,
1597
writeBufferToContigStrips,
1598
imagelength, imagewidth, spp);
1602
* Contig tiles -> separate strips.
1604
DECLAREcpFunc(cpContigTiles2SeparateStrips)
1606
return cpImage(in, out,
1607
readContigTilesIntoBuffer,
1608
writeBufferToSeparateStrips,
1609
imagelength, imagewidth, spp);
1613
* Separate tiles -> contig strips.
1615
DECLAREcpFunc(cpSeparateTiles2ContigStrips)
1617
return cpImage(in, out,
1618
readSeparateTilesIntoBuffer,
1619
writeBufferToContigStrips,
1620
imagelength, imagewidth, spp);
1624
* Separate tiles -> separate strips.
1626
DECLAREcpFunc(cpSeparateTiles2SeparateStrips)
1628
return cpImage(in, out,
1629
readSeparateTilesIntoBuffer,
1630
writeBufferToSeparateStrips,
1631
imagelength, imagewidth, spp);
1635
* Select the appropriate copy function to use.
1638
pickCopyFunc(TIFF* in, TIFF* out, uint16 bitspersample, uint16 samplesperpixel)
1641
uint32 w, l, tw, tl;
1644
(void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv);
1645
if (shortv != config && bitspersample != 8 && samplesperpixel > 1) {
1647
"%s: Cannot handle different planar configuration w/ bits/sample != 8\n",
1651
TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w);
1652
TIFFGetField(in, TIFFTAG_IMAGELENGTH, &l);
1653
if (!(TIFFIsTiled(out) || TIFFIsTiled(in))) {
1654
uint32 irps = (uint32) -1L;
1655
TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &irps);
1656
/* if biased, force decoded copying to allow image subtraction */
1657
bychunk = !bias && (rowsperstrip == irps);
1658
}else{ /* either in or out is tiled */
1661
"%s: Cannot handle tiled configuration w/bias image\n",
1665
if (TIFFIsTiled(out)) {
1666
if (!TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw))
1668
if (!TIFFGetField(in, TIFFTAG_TILELENGTH, &tl))
1670
bychunk = (tw == tilewidth && tl == tilelength);
1671
} else { /* out's not, so in must be tiled */
1672
TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
1673
TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
1674
bychunk = (tw == w && tl == rowsperstrip);
1679
#define pack(a,b,c,d,e) ((long)(((a)<<11)|((b)<<3)|((c)<<2)|((d)<<1)|(e)))
1680
switch(pack(shortv,config,TIFFIsTiled(in),TIFFIsTiled(out),bychunk)) {
1681
/* Strips -> Tiles */
1682
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,T,F):
1683
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,T,T):
1684
return cpContigStrips2ContigTiles;
1685
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,T,F):
1686
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,T,T):
1687
return cpContigStrips2SeparateTiles;
1688
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,T,F):
1689
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,T,T):
1690
return cpSeparateStrips2ContigTiles;
1691
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,T,F):
1692
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,T,T):
1693
return cpSeparateStrips2SeparateTiles;
1694
/* Tiles -> Tiles */
1695
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,T,F):
1696
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,T,T):
1697
return cpContigTiles2ContigTiles;
1698
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,T,F):
1699
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,T,T):
1700
return cpContigTiles2SeparateTiles;
1701
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,T,F):
1702
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,T,T):
1703
return cpSeparateTiles2ContigTiles;
1704
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,T,F):
1705
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,T,T):
1706
return cpSeparateTiles2SeparateTiles;
1707
/* Tiles -> Strips */
1708
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,F,F):
1709
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,F,T):
1710
return cpContigTiles2ContigStrips;
1711
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,F,F):
1712
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,F,T):
1713
return cpContigTiles2SeparateStrips;
1714
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,F,F):
1715
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,F,T):
1716
return cpSeparateTiles2ContigStrips;
1717
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,F,F):
1718
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,F,T):
1719
return cpSeparateTiles2SeparateStrips;
1720
/* Strips -> Strips */
1721
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,F,F):
1722
return bias ? cpBiasedContig2Contig : cpContig2ContigByRow;
1723
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,F,T):
1724
return cpDecodedStrips;
1725
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,F,F):
1726
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,F,T):
1727
return cpContig2SeparateByRow;
1728
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,F,F):
1729
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,F,T):
1730
return cpSeparate2ContigByRow;
1731
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,F,F):
1732
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,F,T):
1733
return cpSeparate2SeparateByRow;
1738
fprintf(stderr, "tiffcp: %s: Don't know how to copy/convert image.\n",
1743
/* vim: set ts=8 sts=8 sw=8 noet: */