1
/* $Id: tiffcp.c,v 1.37.2.9 2010-06-25 12:23:12 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
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;
95
static int pageInSeq = 0;
97
static int nextSrcImage (TIFF *tif, char **imageSpec)
99
seek to the next image specified in *imageSpec
100
returns 1 if success, 0 if no more images to process
101
*imageSpec=NULL if subsequent images should be processed in sequence
104
if (**imageSpec == comma) { /* if not @comma, we've done all images */
105
char *start = *imageSpec + 1;
106
tdir_t nextImage = (tdir_t)strtol(start, imageSpec, 0);
107
if (start == *imageSpec) nextImage = TIFFCurrentDirectory (tif);
110
if (**imageSpec == comma) {
111
/* a trailing comma denotes remaining images in sequence */
112
if ((*imageSpec)[1] == '\0') *imageSpec = NULL;
115
"Expected a %c separated image # list after %s\n",
116
comma, TIFFFileName (tif));
117
exit (-4); /* syntax error */
120
if (TIFFSetDirectory (tif, nextImage)) return 1;
121
fprintf (stderr, "%s%c%d not found!\n",
122
TIFFFileName(tif), comma, (int) nextImage);
128
static TIFF* openSrcImage (char **imageSpec)
130
imageSpec points to a pointer to a filename followed by optional ,image#'s
131
Open the TIFF file and assign *imageSpec to either NULL if there are
132
no images specified, or a pointer to the next image number text
136
char *fn = *imageSpec;
137
*imageSpec = strchr (fn, comma);
138
if (*imageSpec) { /* there is at least one image number specifier */
140
tif = TIFFOpen (fn, "r");
141
/* but, ignore any single trailing comma */
142
if (!(*imageSpec)[1]) {*imageSpec = NULL; return tif;}
144
**imageSpec = comma; /* replace the comma */
145
if (!nextSrcImage(tif, imageSpec)) {
151
tif = TIFFOpen (fn, "r");
157
main(int argc, char* argv[])
159
uint16 defconfig = (uint16) -1;
160
uint16 deffillorder = 0;
161
uint32 deftilewidth = (uint32) -1;
162
uint32 deftilelength = (uint32) -1;
163
uint32 defrowsperstrip = (uint32) 0;
175
while ((c = getopt(argc, argv, ",:b:c:f:l:o:z:p:r:w:aistBLMCx")) != -1)
178
if (optarg[0] != '=') usage();
181
case 'b': /* this file is bias image subtracted from others */
183
fputs ("Only 1 bias image may be specified\n", stderr);
187
uint16 samples = (uint16) -1;
188
char **biasFn = &optarg;
189
bias = openSrcImage (biasFn);
190
if (!bias) exit (-5);
191
if (TIFFIsTiled (bias)) {
192
fputs ("Bias image must be organized in strips\n", stderr);
195
TIFFGetField(bias, TIFFTAG_SAMPLESPERPIXEL, &samples);
197
fputs ("Bias image must be monochrome\n", stderr);
202
case 'a': /* append to output */
205
case 'c': /* compression scheme */
206
if (!processCompressOptions(optarg))
209
case 'f': /* fill order */
210
if (streq(optarg, "lsb2msb"))
211
deffillorder = FILLORDER_LSB2MSB;
212
else if (streq(optarg, "msb2lsb"))
213
deffillorder = FILLORDER_MSB2LSB;
217
case 'i': /* ignore errors */
220
case 'l': /* tile length */
222
deftilelength = atoi(optarg);
224
case 'o': /* initial directory offset */
225
diroff = strtoul(optarg, NULL, 0);
227
case 'p': /* planar configuration */
228
if (streq(optarg, "separate"))
229
defconfig = PLANARCONFIG_SEPARATE;
230
else if (streq(optarg, "contig"))
231
defconfig = PLANARCONFIG_CONTIG;
235
case 'r': /* rows/strip */
236
defrowsperstrip = atol(optarg);
238
case 's': /* generate stripped output */
241
case 't': /* generate tiled output */
244
case 'w': /* tile width */
246
deftilewidth = atoi(optarg);
249
*mp++ = 'b'; *mp = '\0';
252
*mp++ = 'l'; *mp = '\0';
255
*mp++ = 'm'; *mp = '\0';
258
*mp++ = 'c'; *mp = '\0';
267
if (argc - optind < 2)
269
out = TIFFOpen(argv[argc-1], mode);
272
if ((argc - optind) == 2)
274
for (; optind < argc-1 ; optind++) {
275
char *imageCursor = argv[optind];
276
in = openSrcImage (&imageCursor);
278
(void) TIFFClose(out);
281
if (diroff != 0 && !TIFFSetSubDirectory(in, diroff)) {
282
TIFFError(TIFFFileName(in),
283
"Error, setting subdirectory at %#x", diroff);
284
(void) TIFFClose(in);
285
(void) TIFFClose(out);
290
compression = defcompression;
291
predictor = defpredictor;
292
fillorder = deffillorder;
293
rowsperstrip = defrowsperstrip;
294
tilewidth = deftilewidth;
295
tilelength = deftilelength;
297
if (!tiffcp(in, out) || !TIFFWriteDirectory(out)) {
298
(void) TIFFClose(in);
299
(void) TIFFClose(out);
302
if (imageCursor) { /* seek next image directory */
303
if (!nextSrcImage(in, &imageCursor)) break;
305
if (!TIFFReadDirectory(in)) break;
307
(void) TIFFClose(in);
310
(void) TIFFClose(out);
316
processG3Options(char* cp)
318
if( (cp = strchr(cp, ':')) ) {
319
if (defg3opts == (uint32) -1)
323
if (strneq(cp, "1d", 2))
324
defg3opts &= ~GROUP3OPT_2DENCODING;
325
else if (strneq(cp, "2d", 2))
326
defg3opts |= GROUP3OPT_2DENCODING;
327
else if (strneq(cp, "fill", 4))
328
defg3opts |= GROUP3OPT_FILLBITS;
331
} while( (cp = strchr(cp, ':')) );
336
processCompressOptions(char* opt)
338
if (streq(opt, "none")) {
339
defcompression = COMPRESSION_NONE;
340
} else if (streq(opt, "packbits")) {
341
defcompression = COMPRESSION_PACKBITS;
342
} else if (strneq(opt, "jpeg", 4)) {
343
char* cp = strchr(opt, ':');
345
defcompression = COMPRESSION_JPEG;
348
if (isdigit((int)cp[1]))
349
quality = atoi(cp+1);
350
else if (cp[1] == 'r' )
351
jpegcolormode = JPEGCOLORMODE_RAW;
355
cp = strchr(cp+1,':');
357
} else if (strneq(opt, "g3", 2)) {
358
processG3Options(opt);
359
defcompression = COMPRESSION_CCITTFAX3;
360
} else if (streq(opt, "g4")) {
361
defcompression = COMPRESSION_CCITTFAX4;
362
} else if (strneq(opt, "lzw", 3)) {
363
char* cp = strchr(opt, ':');
365
defpredictor = atoi(cp+1);
366
defcompression = COMPRESSION_LZW;
367
} else if (strneq(opt, "zip", 3)) {
368
char* cp = strchr(opt, ':');
370
defpredictor = atoi(cp+1);
371
defcompression = COMPRESSION_ADOBE_DEFLATE;
372
} else if (strneq(opt, "jbig", 4)) {
373
defcompression = COMPRESSION_JBIG;
380
"usage: tiffcp [options] input... output",
381
"where options are:",
382
" -a append to output instead of overwriting",
383
" -o offset set initial directory offset",
384
" -p contig pack samples contiguously (e.g. RGBRGB...)",
385
" -p separate store samples separately (e.g. RRR...GGG...BBB...)",
386
" -s write output in strips",
387
" -t write output in tiles",
388
" -i ignore read errors",
389
" -b file[,#] bias (dark) monochrome image to be subtracted from all others",
390
" -,=% use % rather than , to separate image #'s (per Note below)",
392
" -r # make each strip have no more than # rows",
393
" -w # set output tile width (pixels)",
394
" -l # set output tile length (pixels)",
396
" -f lsb2msb force lsb-to-msb FillOrder for output",
397
" -f msb2lsb force msb-to-lsb FillOrder for output",
399
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
400
" -c zip[:opts] compress output with deflate encoding",
401
" -c jpeg[:opts] compress output with JPEG encoding",
402
" -c jbig compress output with ISO JBIG encoding",
403
" -c packbits compress output with packbits encoding",
404
" -c g3[:opts] compress output with CCITT Group 3 encoding",
405
" -c g4 compress output with CCITT Group 4 encoding",
406
" -c none use no compression algorithm on output",
409
" 1d use default CCITT Group 3 1D-encoding",
410
" 2d use optional CCITT Group 3 2D-encoding",
411
" fill byte-align EOL codes",
412
"For example, -c g3:2d:fill to get G3-2D-encoded data with byte-aligned EOLs",
415
" # set compression quality level (0-100, default 75)",
416
" r output color image as RGB rather than YCbCr",
417
"For example, -c jpeg:r:50 to get JPEG-encoded RGB data with 50% comp. quality",
419
"LZW and deflate options:",
420
" # set predictor value",
421
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
423
"Note that input filenames may be of the form filename,x,y,z",
424
"where x, y, and z specify image numbers in the filename to copy.",
425
"example: tiffcp -c none -b esp.tif,1 esp.tif,0 test.tif",
426
" subtract 2nd image in esp.tif from 1st yielding uncompressed result test.tif",
437
fprintf(stderr, "%s\n\n", TIFFGetVersion());
438
for (i = 0; stuff[i] != NULL; i++)
439
fprintf(stderr, "%s\n", stuff[i]);
443
#define CopyField(tag, v) \
444
if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
445
#define CopyField2(tag, v1, v2) \
446
if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
447
#define CopyField3(tag, v1, v2, v3) \
448
if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
449
#define CopyField4(tag, v1, v2, v3, v4) \
450
if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4)
453
cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type)
459
CopyField(tag, shortv);
460
} else if (count == 2) {
461
uint16 shortv1, shortv2;
462
CopyField2(tag, shortv1, shortv2);
463
} else if (count == 4) {
464
uint16 *tr, *tg, *tb, *ta;
465
CopyField4(tag, tr, tg, tb, ta);
466
} else if (count == (uint16) -1) {
469
CopyField2(tag, shortv1, shortav);
474
CopyField(tag, longv);
480
CopyField(tag, floatv);
481
} else if (count == (uint16) -1) {
483
CopyField(tag, floatav);
488
CopyField(tag, stringv);
494
CopyField(tag, doublev);
495
} else if (count == (uint16) -1) {
497
CopyField(tag, doubleav);
501
TIFFError(TIFFFileName(in),
502
"Data type %d is not supported, tag %d skipped.",
507
static struct cpTag {
512
{ TIFFTAG_SUBFILETYPE, 1, TIFF_LONG },
513
{ TIFFTAG_THRESHHOLDING, 1, TIFF_SHORT },
514
{ TIFFTAG_DOCUMENTNAME, 1, TIFF_ASCII },
515
{ TIFFTAG_IMAGEDESCRIPTION, 1, TIFF_ASCII },
516
{ TIFFTAG_MAKE, 1, TIFF_ASCII },
517
{ TIFFTAG_MODEL, 1, TIFF_ASCII },
518
{ TIFFTAG_MINSAMPLEVALUE, 1, TIFF_SHORT },
519
{ TIFFTAG_MAXSAMPLEVALUE, 1, TIFF_SHORT },
520
{ TIFFTAG_XRESOLUTION, 1, TIFF_RATIONAL },
521
{ TIFFTAG_YRESOLUTION, 1, TIFF_RATIONAL },
522
{ TIFFTAG_PAGENAME, 1, TIFF_ASCII },
523
{ TIFFTAG_XPOSITION, 1, TIFF_RATIONAL },
524
{ TIFFTAG_YPOSITION, 1, TIFF_RATIONAL },
525
{ TIFFTAG_RESOLUTIONUNIT, 1, TIFF_SHORT },
526
{ TIFFTAG_SOFTWARE, 1, TIFF_ASCII },
527
{ TIFFTAG_DATETIME, 1, TIFF_ASCII },
528
{ TIFFTAG_ARTIST, 1, TIFF_ASCII },
529
{ TIFFTAG_HOSTCOMPUTER, 1, TIFF_ASCII },
530
{ TIFFTAG_WHITEPOINT, (uint16) -1, TIFF_RATIONAL },
531
{ TIFFTAG_PRIMARYCHROMATICITIES,(uint16) -1,TIFF_RATIONAL },
532
{ TIFFTAG_HALFTONEHINTS, 2, TIFF_SHORT },
533
{ TIFFTAG_INKSET, 1, TIFF_SHORT },
534
{ TIFFTAG_DOTRANGE, 2, TIFF_SHORT },
535
{ TIFFTAG_TARGETPRINTER, 1, TIFF_ASCII },
536
{ TIFFTAG_SAMPLEFORMAT, 1, TIFF_SHORT },
537
{ TIFFTAG_YCBCRCOEFFICIENTS, (uint16) -1,TIFF_RATIONAL },
538
{ TIFFTAG_YCBCRSUBSAMPLING, 2, TIFF_SHORT },
539
{ TIFFTAG_YCBCRPOSITIONING, 1, TIFF_SHORT },
540
{ TIFFTAG_REFERENCEBLACKWHITE, (uint16) -1,TIFF_RATIONAL },
541
{ TIFFTAG_EXTRASAMPLES, (uint16) -1, TIFF_SHORT },
542
{ TIFFTAG_SMINSAMPLEVALUE, 1, TIFF_DOUBLE },
543
{ TIFFTAG_SMAXSAMPLEVALUE, 1, TIFF_DOUBLE },
544
{ TIFFTAG_STONITS, 1, TIFF_DOUBLE },
546
#define NTAGS (sizeof (tags) / sizeof (tags[0]))
548
#define CopyTag(tag, count, type) cpTag(in, out, tag, count, type)
550
typedef int (*copyFunc)
551
(TIFF* in, TIFF* out, uint32 l, uint32 w, uint16 samplesperpixel);
552
static copyFunc pickCopyFunc(TIFF*, TIFF*, uint16, uint16);
555
tiffcp(TIFF* in, TIFF* out)
557
uint16 bitspersample, samplesperpixel;
558
uint16 input_compression, input_photometric;
560
uint32 width, length;
563
CopyField(TIFFTAG_IMAGEWIDTH, width);
564
CopyField(TIFFTAG_IMAGELENGTH, length);
565
CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample);
566
CopyField(TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
567
if (compression != (uint16)-1)
568
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
570
CopyField(TIFFTAG_COMPRESSION, compression);
571
TIFFGetFieldDefaulted(in, TIFFTAG_COMPRESSION, &input_compression);
572
TIFFGetFieldDefaulted(in, TIFFTAG_PHOTOMETRIC, &input_photometric);
573
if (input_compression == COMPRESSION_JPEG) {
574
/* Force conversion to RGB */
575
TIFFSetField(in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
576
} else if (input_photometric == PHOTOMETRIC_YCBCR) {
577
/* Otherwise, can't handle subsampled input */
578
uint16 subsamplinghor,subsamplingver;
580
TIFFGetFieldDefaulted(in, TIFFTAG_YCBCRSUBSAMPLING,
581
&subsamplinghor, &subsamplingver);
582
if (subsamplinghor!=1 || subsamplingver!=1) {
583
fprintf(stderr, "tiffcp: %s: Can't copy/convert subsampled image.\n",
588
if (compression == COMPRESSION_JPEG) {
589
if (input_photometric == PHOTOMETRIC_RGB &&
590
jpegcolormode == JPEGCOLORMODE_RGB)
591
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
593
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
595
else if (compression == COMPRESSION_SGILOG
596
|| compression == COMPRESSION_SGILOG24)
597
TIFFSetField(out, TIFFTAG_PHOTOMETRIC,
598
samplesperpixel == 1 ?
599
PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
601
CopyTag(TIFFTAG_PHOTOMETRIC, 1, TIFF_SHORT);
603
TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
605
CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
607
* Will copy `Orientation' tag from input image
609
TIFFGetFieldDefaulted(in, TIFFTAG_ORIENTATION, &orientation);
610
switch (orientation) {
611
case ORIENTATION_BOTRIGHT:
612
case ORIENTATION_RIGHTBOT: /* XXX */
613
TIFFWarning(TIFFFileName(in), "using bottom-left orientation");
614
orientation = ORIENTATION_BOTLEFT;
616
case ORIENTATION_LEFTBOT: /* XXX */
617
case ORIENTATION_BOTLEFT:
619
case ORIENTATION_TOPRIGHT:
620
case ORIENTATION_RIGHTTOP: /* XXX */
622
TIFFWarning(TIFFFileName(in), "using top-left orientation");
623
orientation = ORIENTATION_TOPLEFT;
625
case ORIENTATION_LEFTTOP: /* XXX */
626
case ORIENTATION_TOPLEFT:
629
TIFFSetField(out, TIFFTAG_ORIENTATION, orientation);
631
* Choose tiles/strip for the output image according to
632
* the command line arguments (-tiles, -strips) and the
633
* structure of the input image.
636
outtiled = TIFFIsTiled(in);
639
* Setup output file's tile width&height. If either
640
* is not specified, use either the value from the
641
* input image or, if nothing is defined, use the
644
if (tilewidth == (uint32) -1)
645
TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
646
if (tilelength == (uint32) -1)
647
TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
648
TIFFDefaultTileSize(out, &tilewidth, &tilelength);
649
TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
650
TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
653
* RowsPerStrip is left unspecified: use either the
654
* value from the input image or, if nothing is defined,
655
* use the library default.
657
if (rowsperstrip == (uint32) 0) {
658
if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP,
661
TIFFDefaultStripSize(out, rowsperstrip);
663
if (rowsperstrip > length && rowsperstrip != (uint32)-1)
664
rowsperstrip = length;
666
else if (rowsperstrip == (uint32) -1)
667
rowsperstrip = length;
668
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
670
if (config != (uint16) -1)
671
TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
673
CopyField(TIFFTAG_PLANARCONFIG, config);
674
if (samplesperpixel <= 4)
675
CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
676
CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
677
/* SMinSampleValue & SMaxSampleValue */
678
switch (compression) {
679
case COMPRESSION_JPEG:
680
TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
681
TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
683
case COMPRESSION_JBIG:
684
CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
685
CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
686
CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
687
CopyTag(TIFFTAG_FAXDCS, 1, TIFF_ASCII);
689
case COMPRESSION_LZW:
690
case COMPRESSION_ADOBE_DEFLATE:
691
case COMPRESSION_DEFLATE:
692
if (predictor != (uint16)-1)
693
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
695
CopyField(TIFFTAG_PREDICTOR, predictor);
697
case COMPRESSION_CCITTFAX3:
698
case COMPRESSION_CCITTFAX4:
699
if (compression == COMPRESSION_CCITTFAX3) {
700
if (g3opts != (uint32) -1)
701
TIFFSetField(out, TIFFTAG_GROUP3OPTIONS,
704
CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
706
CopyTag(TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG);
707
CopyTag(TIFFTAG_BADFAXLINES, 1, TIFF_LONG);
708
CopyTag(TIFFTAG_CLEANFAXDATA, 1, TIFF_LONG);
709
CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG);
710
CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
711
CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
712
CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
717
if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
718
TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
721
const char* inknames;
722
if (TIFFGetField(in, TIFFTAG_NUMBEROFINKS, &ninks)) {
723
TIFFSetField(out, TIFFTAG_NUMBEROFINKS, ninks);
724
if (TIFFGetField(in, TIFFTAG_INKNAMES, &inknames)) {
725
int inknameslen = strlen(inknames) + 1;
726
const char* cp = inknames;
728
cp = strchr(cp, '\0');
731
inknameslen += (strlen(cp) + 1);
735
TIFFSetField(out, TIFFTAG_INKNAMES, inknameslen, inknames);
740
unsigned short pg0, pg1;
742
if (pageNum < 0) /* only one input file */ {
743
if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1))
744
TIFFSetField(out, TIFFTAG_PAGENUMBER, pg0, pg1);
746
TIFFSetField(out, TIFFTAG_PAGENUMBER, pageNum++, 0);
748
if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1)) {
749
if (pageNum < 0) /* only one input file */
750
TIFFSetField(out, TIFFTAG_PAGENUMBER, pg0, pg1);
752
TIFFSetField(out, TIFFTAG_PAGENUMBER, pageNum++, 0);
756
for (p = tags; p < &tags[NTAGS]; p++)
757
CopyTag(p->tag, p->count, p->type);
759
cf = pickCopyFunc(in, out, bitspersample, samplesperpixel);
760
return (cf ? (*cf)(in, out, length, width, samplesperpixel) : FALSE);
766
#define DECLAREcpFunc(x) \
767
static int x(TIFF* in, TIFF* out, \
768
uint32 imagelength, uint32 imagewidth, tsample_t spp)
770
#define DECLAREreadFunc(x) \
771
static int x(TIFF* in, \
772
uint8* buf, uint32 imagelength, uint32 imagewidth, tsample_t spp)
773
typedef int (*readFunc)(TIFF*, uint8*, uint32, uint32, tsample_t);
775
#define DECLAREwriteFunc(x) \
776
static int x(TIFF* out, \
777
uint8* buf, uint32 imagelength, uint32 imagewidth, tsample_t spp)
778
typedef int (*writeFunc)(TIFF*, uint8*, uint32, uint32, tsample_t);
781
* Contig -> contig by scanline for rows/strip change.
783
DECLAREcpFunc(cpContig2ContigByRow)
785
tsize_t scanlinesize = TIFFScanlineSize(in);
789
buf = _TIFFmalloc(scanlinesize);
792
_TIFFmemset(buf, 0, scanlinesize);
793
(void) imagewidth; (void) spp;
794
for (row = 0; row < imagelength; row++) {
795
if (TIFFReadScanline(in, buf, row, 0) < 0 && !ignore) {
796
TIFFError(TIFFFileName(in),
797
"Error, can't read scanline %lu",
798
(unsigned long) row);
801
if (TIFFWriteScanline(out, buf, row, 0) < 0) {
802
TIFFError(TIFFFileName(out),
803
"Error, can't write scanline %lu",
804
(unsigned long) row);
816
typedef void biasFn (void *image, void *bias, uint32 pixels);
818
#define subtract(bits) \
819
static void subtract##bits (void *i, void *b, uint32 pixels)\
821
uint##bits *image = i;\
822
uint##bits *bias = b;\
824
*image = *image > *bias ? *image-*bias : 0;\
833
static biasFn *lineSubtractFn (unsigned bits)
836
case 8: return subtract8;
837
case 16: return subtract16;
838
case 32: return subtract32;
844
* Contig -> contig by scanline while subtracting a bias image.
846
DECLAREcpFunc(cpBiasedContig2Contig)
849
tsize_t biasSize = TIFFScanlineSize(bias);
850
tsize_t bufSize = TIFFScanlineSize(in);
851
tdata_t buf, biasBuf;
852
uint32 biasWidth = 0, biasLength = 0;
853
TIFFGetField(bias, TIFFTAG_IMAGEWIDTH, &biasWidth);
854
TIFFGetField(bias, TIFFTAG_IMAGELENGTH, &biasLength);
855
if (biasSize == bufSize &&
856
imagelength == biasLength && imagewidth == biasWidth) {
857
uint16 sampleBits = 0;
858
biasFn *subtractLine;
859
TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &sampleBits);
860
subtractLine = lineSubtractFn (sampleBits);
863
buf = _TIFFmalloc(bufSize);
864
biasBuf = _TIFFmalloc(bufSize);
865
for (row = 0; row < imagelength; row++) {
866
if (TIFFReadScanline(in, buf, row, 0) < 0
868
TIFFError(TIFFFileName(in),
869
"Error, can't read scanline %lu",
870
(unsigned long) row);
873
if (TIFFReadScanline(bias, biasBuf, row, 0) < 0
875
TIFFError(TIFFFileName(in),
876
"Error, can't read biased scanline %lu",
877
(unsigned long) row);
880
subtractLine (buf, biasBuf, imagewidth);
881
if (TIFFWriteScanline(out, buf, row, 0) < 0) {
882
TIFFError(TIFFFileName(out),
883
"Error, can't write scanline %lu",
884
(unsigned long) row);
891
TIFFSetDirectory(bias,
892
TIFFCurrentDirectory(bias)); /* rewind */
899
TIFFError(TIFFFileName(in),
900
"No support for biasing %d bit pixels\n",
905
TIFFError(TIFFFileName(in),
906
"Bias image %s,%d\nis not the same size as %s,%d\n",
907
TIFFFileName(bias), TIFFCurrentDirectory(bias),
908
TIFFFileName(in), TIFFCurrentDirectory(in));
911
TIFFError(TIFFFileName(in),
912
"Can't bias %s,%d as it has >1 Sample/Pixel\n",
913
TIFFFileName(in), TIFFCurrentDirectory(in));
921
* Strip -> strip for change in encoding.
923
DECLAREcpFunc(cpDecodedStrips)
925
tsize_t stripsize = TIFFStripSize(in);
926
tdata_t buf = _TIFFmalloc(stripsize);
928
(void) imagewidth; (void) spp;
930
tstrip_t s, ns = TIFFNumberOfStrips(in);
932
_TIFFmemset(buf, 0, stripsize);
933
for (s = 0; s < ns; s++) {
934
tsize_t cc = (row + rowsperstrip > imagelength) ?
935
TIFFVStripSize(in, imagelength - row) : stripsize;
936
if (TIFFReadEncodedStrip(in, s, buf, cc) < 0
938
TIFFError(TIFFFileName(in),
939
"Error, can't read strip %lu",
943
if (TIFFWriteEncodedStrip(out, s, buf, cc) < 0) {
944
TIFFError(TIFFFileName(out),
945
"Error, can't write strip %lu",
954
TIFFError(TIFFFileName(in),
955
"Error, can't allocate memory buffer of size %lu "
956
"to read strips", (unsigned long) stripsize);
966
* Separate -> separate by row for rows/strip change.
968
DECLAREcpFunc(cpSeparate2SeparateByRow)
970
tsize_t scanlinesize = TIFFScanlineSize(in);
976
buf = _TIFFmalloc(scanlinesize);
979
_TIFFmemset(buf, 0, scanlinesize);
980
for (s = 0; s < spp; s++) {
981
for (row = 0; row < imagelength; row++) {
982
if (TIFFReadScanline(in, buf, row, s) < 0 && !ignore) {
983
TIFFError(TIFFFileName(in),
984
"Error, can't read scanline %lu",
985
(unsigned long) row);
988
if (TIFFWriteScanline(out, buf, row, s) < 0) {
989
TIFFError(TIFFFileName(out),
990
"Error, can't write scanline %lu",
991
(unsigned long) row);
1004
* Contig -> separate by row.
1006
DECLAREcpFunc(cpContig2SeparateByRow)
1008
tsize_t scanlinesizein = TIFFScanlineSize(in);
1009
tsize_t scanlinesizeout = TIFFScanlineSize(out);
1012
register uint8 *inp, *outp;
1017
inbuf = _TIFFmalloc(scanlinesizein);
1018
outbuf = _TIFFmalloc(scanlinesizeout);
1019
if (!inbuf || !outbuf)
1021
_TIFFmemset(inbuf, 0, scanlinesizein);
1022
_TIFFmemset(outbuf, 0, scanlinesizeout);
1023
/* unpack channels */
1024
for (s = 0; s < spp; s++) {
1025
for (row = 0; row < imagelength; row++) {
1026
if (TIFFReadScanline(in, inbuf, row, 0) < 0
1028
TIFFError(TIFFFileName(in),
1029
"Error, can't read scanline %lu",
1030
(unsigned long) row);
1033
inp = ((uint8*)inbuf) + s;
1034
outp = (uint8*)outbuf;
1035
for (n = imagewidth; n-- > 0;) {
1039
if (TIFFWriteScanline(out, outbuf, row, s) < 0) {
1040
TIFFError(TIFFFileName(out),
1041
"Error, can't write scanline %lu",
1042
(unsigned long) row);
1047
if (inbuf) _TIFFfree(inbuf);
1048
if (outbuf) _TIFFfree(outbuf);
1051
if (inbuf) _TIFFfree(inbuf);
1052
if (outbuf) _TIFFfree(outbuf);
1057
* Separate -> contig by row.
1059
DECLAREcpFunc(cpSeparate2ContigByRow)
1061
tsize_t scanlinesizein = TIFFScanlineSize(in);
1062
tsize_t scanlinesizeout = TIFFScanlineSize(out);
1065
register uint8 *inp, *outp;
1070
inbuf = _TIFFmalloc(scanlinesizein);
1071
outbuf = _TIFFmalloc(scanlinesizeout);
1072
if (!inbuf || !outbuf)
1074
_TIFFmemset(inbuf, 0, scanlinesizein);
1075
_TIFFmemset(outbuf, 0, scanlinesizeout);
1076
for (row = 0; row < imagelength; row++) {
1077
/* merge channels */
1078
for (s = 0; s < spp; s++) {
1079
if (TIFFReadScanline(in, inbuf, row, s) < 0
1081
TIFFError(TIFFFileName(in),
1082
"Error, can't read scanline %lu",
1083
(unsigned long) row);
1086
inp = (uint8*)inbuf;
1087
outp = ((uint8*)outbuf) + s;
1088
for (n = imagewidth; n-- > 0;) {
1093
if (TIFFWriteScanline(out, outbuf, row, 0) < 0) {
1094
TIFFError(TIFFFileName(out),
1095
"Error, can't write scanline %lu",
1096
(unsigned long) row);
1100
if (inbuf) _TIFFfree(inbuf);
1101
if (outbuf) _TIFFfree(outbuf);
1104
if (inbuf) _TIFFfree(inbuf);
1105
if (outbuf) _TIFFfree(outbuf);
1110
cpStripToTile(uint8* out, uint8* in,
1111
uint32 rows, uint32 cols, int outskew, int inskew)
1113
while (rows-- > 0) {
1123
cpContigBufToSeparateBuf(uint8* out, uint8* in,
1124
uint32 rows, uint32 cols, int outskew, int inskew, tsample_t spp,
1125
int bytes_per_sample )
1127
while (rows-- > 0) {
1131
int n = bytes_per_sample;
1136
in += (spp-1) * bytes_per_sample;
1144
cpSeparateBufToContigBuf(uint8* out, uint8* in,
1145
uint32 rows, uint32 cols, int outskew, int inskew, tsample_t spp,
1146
int bytes_per_sample)
1148
while (rows-- > 0) {
1151
int n = bytes_per_sample;
1156
out += (spp-1)*bytes_per_sample;
1164
cpImage(TIFF* in, TIFF* out, readFunc fin, writeFunc fout,
1165
uint32 imagelength, uint32 imagewidth, tsample_t spp)
1169
tsize_t scanlinesize = TIFFRasterScanlineSize(in);
1170
tsize_t bytes = scanlinesize * (tsize_t)imagelength;
1172
* XXX: Check for integer overflow.
1176
&& bytes / (tsize_t)imagelength == scanlinesize) {
1177
buf = _TIFFmalloc(bytes);
1179
if ((*fin)(in, (uint8*)buf, imagelength,
1181
status = (*fout)(out, (uint8*)buf,
1182
imagelength, imagewidth, spp);
1186
TIFFError(TIFFFileName(in),
1187
"Error, can't allocate space for image buffer");
1190
TIFFError(TIFFFileName(in), "Error, no space for image buffer");
1196
DECLAREreadFunc(readContigStripsIntoBuffer)
1198
tsize_t scanlinesize = TIFFScanlineSize(in);
1202
(void) imagewidth; (void) spp;
1203
for (row = 0; row < imagelength; row++) {
1204
if (TIFFReadScanline(in, (tdata_t) bufp, row, 0) < 0
1206
TIFFError(TIFFFileName(in),
1207
"Error, can't read scanline %lu",
1208
(unsigned long) row);
1211
bufp += scanlinesize;
1217
DECLAREreadFunc(readSeparateStripsIntoBuffer)
1220
tsize_t scanlinesize = TIFFScanlineSize(in);
1221
tdata_t scanline = _TIFFmalloc(scanlinesize);
1226
_TIFFmemset(scanline, 0, scanlinesize);
1229
uint8* bufp = (uint8*) buf;
1232
for (row = 0; row < imagelength; row++) {
1233
/* merge channels */
1234
for (s = 0; s < spp; s++) {
1235
uint8* bp = bufp + s;
1236
tsize_t n = scanlinesize;
1237
uint8* sbuf = scanline;
1239
if (TIFFReadScanline(in, scanline, row, s) < 0
1241
TIFFError(TIFFFileName(in),
1242
"Error, can't read scanline %lu",
1243
(unsigned long) row);
1248
*bp = *sbuf++, bp += spp;
1250
bufp += scanlinesize * spp;
1255
_TIFFfree(scanline);
1259
DECLAREreadFunc(readContigTilesIntoBuffer)
1262
tsize_t tilesize = TIFFTileSize(in);
1264
uint32 imagew = TIFFScanlineSize(in);
1265
uint32 tilew = TIFFTileRowSize(in);
1266
int iskew = imagew - tilew;
1267
uint8* bufp = (uint8*) buf;
1272
tilebuf = _TIFFmalloc(tilesize);
1275
_TIFFmemset(tilebuf, 0, tilesize);
1276
(void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
1277
(void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
1279
for (row = 0; row < imagelength; row += tl) {
1280
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
1284
for (col = 0; col < imagewidth; col += tw) {
1285
if (TIFFReadTile(in, tilebuf, col, row, 0, 0) < 0
1287
TIFFError(TIFFFileName(in),
1288
"Error, can't read tile at %lu %lu",
1289
(unsigned long) col,
1290
(unsigned long) row);
1294
if (colb + tilew > imagew) {
1295
uint32 width = imagew - colb;
1296
uint32 oskew = tilew - width;
1297
cpStripToTile(bufp + colb,
1298
tilebuf, nrow, width,
1299
oskew + iskew, oskew );
1301
cpStripToTile(bufp + colb,
1302
tilebuf, nrow, tilew,
1306
bufp += imagew * nrow;
1313
DECLAREreadFunc(readSeparateTilesIntoBuffer)
1316
uint32 imagew = TIFFRasterScanlineSize(in);
1317
uint32 tilew = TIFFTileRowSize(in);
1318
int iskew = imagew - tilew*spp;
1319
tsize_t tilesize = TIFFTileSize(in);
1321
uint8* bufp = (uint8*) buf;
1324
uint16 bps, bytes_per_sample;
1326
tilebuf = _TIFFmalloc(tilesize);
1329
_TIFFmemset(tilebuf, 0, tilesize);
1330
(void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
1331
(void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
1332
(void) TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps);
1333
assert( bps % 8 == 0 );
1334
bytes_per_sample = bps/8;
1336
for (row = 0; row < imagelength; row += tl) {
1337
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
1341
for (col = 0; col < imagewidth; col += tw) {
1344
for (s = 0; s < spp; s++) {
1345
if (TIFFReadTile(in, tilebuf, col, row, 0, s) < 0
1347
TIFFError(TIFFFileName(in),
1348
"Error, can't read tile at %lu %lu, "
1350
(unsigned long) col,
1351
(unsigned long) row,
1357
* Tile is clipped horizontally. Calculate
1358
* visible portion and skewing factors.
1360
if (colb + tilew*spp > imagew) {
1361
uint32 width = imagew - colb;
1362
int oskew = tilew*spp - width;
1363
cpSeparateBufToContigBuf(
1364
bufp+colb+s*bytes_per_sample,
1366
width/(spp*bytes_per_sample),
1371
cpSeparateBufToContigBuf(
1372
bufp+colb+s*bytes_per_sample,
1379
bufp += imagew * nrow;
1386
DECLAREwriteFunc(writeBufferToContigStrips)
1388
uint32 row, rowsperstrip;
1391
(void) imagewidth; (void) spp;
1392
(void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1393
for (row = 0; row < imagelength; row += rowsperstrip) {
1394
uint32 nrows = (row+rowsperstrip > imagelength) ?
1395
imagelength-row : rowsperstrip;
1396
tsize_t stripsize = TIFFVStripSize(out, nrows);
1397
if (TIFFWriteEncodedStrip(out, strip++, buf, stripsize) < 0) {
1398
TIFFError(TIFFFileName(out),
1399
"Error, can't write strip %u", strip - 1);
1407
DECLAREwriteFunc(writeBufferToSeparateStrips)
1409
uint32 rowsize = imagewidth * spp;
1410
uint32 rowsperstrip;
1411
tsize_t stripsize = TIFFStripSize(out);
1416
obuf = _TIFFmalloc(stripsize);
1419
_TIFFmemset(obuf, 0, stripsize);
1420
(void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1421
for (s = 0; s < spp; s++) {
1423
for (row = 0; row < imagelength; row += rowsperstrip) {
1424
uint32 nrows = (row+rowsperstrip > imagelength) ?
1425
imagelength-row : rowsperstrip;
1426
tsize_t stripsize = TIFFVStripSize(out, nrows);
1428
cpContigBufToSeparateBuf(
1429
obuf, (uint8*) buf + row*rowsize + s,
1430
nrows, imagewidth, 0, 0, spp, 1);
1431
if (TIFFWriteEncodedStrip(out, strip++, obuf, stripsize) < 0) {
1432
TIFFError(TIFFFileName(out),
1433
"Error, can't write strip %u",
1445
DECLAREwriteFunc(writeBufferToContigTiles)
1447
uint32 imagew = TIFFScanlineSize(out);
1448
uint32 tilew = TIFFTileRowSize(out);
1449
int iskew = imagew - tilew;
1450
tsize_t tilesize = TIFFTileSize(out);
1452
uint8* bufp = (uint8*) buf;
1458
obuf = _TIFFmalloc(TIFFTileSize(out));
1461
_TIFFmemset(obuf, 0, tilesize);
1462
(void) TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
1463
(void) TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
1464
for (row = 0; row < imagelength; row += tilelength) {
1465
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
1469
for (col = 0; col < imagewidth; col += tw) {
1471
* Tile is clipped horizontally. Calculate
1472
* visible portion and skewing factors.
1474
if (colb + tilew > imagew) {
1475
uint32 width = imagew - colb;
1476
int oskew = tilew - width;
1477
cpStripToTile(obuf, bufp + colb, nrow, width,
1478
oskew, oskew + iskew);
1480
cpStripToTile(obuf, bufp + colb, nrow, tilew,
1482
if (TIFFWriteTile(out, obuf, col, row, 0, 0) < 0) {
1483
TIFFError(TIFFFileName(out),
1484
"Error, can't write tile at %lu %lu",
1485
(unsigned long) col,
1486
(unsigned long) row);
1492
bufp += nrow * imagew;
1498
DECLAREwriteFunc(writeBufferToSeparateTiles)
1500
uint32 imagew = TIFFScanlineSize(out);
1501
tsize_t tilew = TIFFTileRowSize(out);
1502
uint32 iimagew = TIFFRasterScanlineSize(out);
1503
int iskew = iimagew - tilew*spp;
1504
tsize_t tilesize = TIFFTileSize(out);
1506
uint8* bufp = (uint8*) buf;
1509
uint16 bps, bytes_per_sample;
1511
obuf = _TIFFmalloc(TIFFTileSize(out));
1514
_TIFFmemset(obuf, 0, tilesize);
1515
(void) TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
1516
(void) TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
1517
(void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
1518
assert( bps % 8 == 0 );
1519
bytes_per_sample = bps/8;
1521
for (row = 0; row < imagelength; row += tl) {
1522
uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
1526
for (col = 0; col < imagewidth; col += tw) {
1528
for (s = 0; s < spp; s++) {
1530
* Tile is clipped horizontally. Calculate
1531
* visible portion and skewing factors.
1533
if (colb + tilew > imagew) {
1534
uint32 width = (imagew - colb);
1535
int oskew = tilew - width;
1537
cpContigBufToSeparateBuf(obuf,
1538
bufp + (colb*spp) + s,
1539
nrow, width/bytes_per_sample,
1540
oskew, (oskew*spp)+iskew, spp,
1543
cpContigBufToSeparateBuf(obuf,
1544
bufp + (colb*spp) + s,
1548
if (TIFFWriteTile(out, obuf, col, row, 0, s) < 0) {
1549
TIFFError(TIFFFileName(out),
1550
"Error, can't write tile at %lu %lu "
1552
(unsigned long) col,
1553
(unsigned long) row,
1561
bufp += nrow * iimagew;
1568
* Contig strips -> contig tiles.
1570
DECLAREcpFunc(cpContigStrips2ContigTiles)
1572
return cpImage(in, out,
1573
readContigStripsIntoBuffer,
1574
writeBufferToContigTiles,
1575
imagelength, imagewidth, spp);
1579
* Contig strips -> separate tiles.
1581
DECLAREcpFunc(cpContigStrips2SeparateTiles)
1583
return cpImage(in, out,
1584
readContigStripsIntoBuffer,
1585
writeBufferToSeparateTiles,
1586
imagelength, imagewidth, spp);
1590
* Separate strips -> contig tiles.
1592
DECLAREcpFunc(cpSeparateStrips2ContigTiles)
1594
return cpImage(in, out,
1595
readSeparateStripsIntoBuffer,
1596
writeBufferToContigTiles,
1597
imagelength, imagewidth, spp);
1601
* Separate strips -> separate tiles.
1603
DECLAREcpFunc(cpSeparateStrips2SeparateTiles)
1605
return cpImage(in, out,
1606
readSeparateStripsIntoBuffer,
1607
writeBufferToSeparateTiles,
1608
imagelength, imagewidth, spp);
1612
* Contig strips -> contig tiles.
1614
DECLAREcpFunc(cpContigTiles2ContigTiles)
1616
return cpImage(in, out,
1617
readContigTilesIntoBuffer,
1618
writeBufferToContigTiles,
1619
imagelength, imagewidth, spp);
1623
* Contig tiles -> separate tiles.
1625
DECLAREcpFunc(cpContigTiles2SeparateTiles)
1627
return cpImage(in, out,
1628
readContigTilesIntoBuffer,
1629
writeBufferToSeparateTiles,
1630
imagelength, imagewidth, spp);
1634
* Separate tiles -> contig tiles.
1636
DECLAREcpFunc(cpSeparateTiles2ContigTiles)
1638
return cpImage(in, out,
1639
readSeparateTilesIntoBuffer,
1640
writeBufferToContigTiles,
1641
imagelength, imagewidth, spp);
1645
* Separate tiles -> separate tiles (tile dimension change).
1647
DECLAREcpFunc(cpSeparateTiles2SeparateTiles)
1649
return cpImage(in, out,
1650
readSeparateTilesIntoBuffer,
1651
writeBufferToSeparateTiles,
1652
imagelength, imagewidth, spp);
1656
* Contig tiles -> contig tiles (tile dimension change).
1658
DECLAREcpFunc(cpContigTiles2ContigStrips)
1660
return cpImage(in, out,
1661
readContigTilesIntoBuffer,
1662
writeBufferToContigStrips,
1663
imagelength, imagewidth, spp);
1667
* Contig tiles -> separate strips.
1669
DECLAREcpFunc(cpContigTiles2SeparateStrips)
1671
return cpImage(in, out,
1672
readContigTilesIntoBuffer,
1673
writeBufferToSeparateStrips,
1674
imagelength, imagewidth, spp);
1678
* Separate tiles -> contig strips.
1680
DECLAREcpFunc(cpSeparateTiles2ContigStrips)
1682
return cpImage(in, out,
1683
readSeparateTilesIntoBuffer,
1684
writeBufferToContigStrips,
1685
imagelength, imagewidth, spp);
1689
* Separate tiles -> separate strips.
1691
DECLAREcpFunc(cpSeparateTiles2SeparateStrips)
1693
return cpImage(in, out,
1694
readSeparateTilesIntoBuffer,
1695
writeBufferToSeparateStrips,
1696
imagelength, imagewidth, spp);
1700
* Select the appropriate copy function to use.
1703
pickCopyFunc(TIFF* in, TIFF* out, uint16 bitspersample, uint16 samplesperpixel)
1706
uint32 w, l, tw, tl;
1709
(void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv);
1710
if (shortv != config && bitspersample != 8 && samplesperpixel > 1) {
1712
"%s: Cannot handle different planar configuration w/ bits/sample != 8\n",
1716
TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w);
1717
TIFFGetField(in, TIFFTAG_IMAGELENGTH, &l);
1718
if (!(TIFFIsTiled(out) || TIFFIsTiled(in))) {
1719
uint32 irps = (uint32) -1L;
1720
TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &irps);
1721
/* if biased, force decoded copying to allow image subtraction */
1722
bychunk = !bias && (rowsperstrip == irps);
1723
}else{ /* either in or out is tiled */
1726
"%s: Cannot handle tiled configuration w/bias image\n",
1730
if (TIFFIsTiled(out)) {
1731
if (!TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw))
1733
if (!TIFFGetField(in, TIFFTAG_TILELENGTH, &tl))
1735
bychunk = (tw == tilewidth && tl == tilelength);
1736
} else { /* out's not, so in must be tiled */
1737
TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
1738
TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
1739
bychunk = (tw == w && tl == rowsperstrip);
1744
#define pack(a,b,c,d,e) ((long)(((a)<<11)|((b)<<3)|((c)<<2)|((d)<<1)|(e)))
1745
switch(pack(shortv,config,TIFFIsTiled(in),TIFFIsTiled(out),bychunk)) {
1746
/* Strips -> Tiles */
1747
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,T,F):
1748
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,T,T):
1749
return cpContigStrips2ContigTiles;
1750
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,T,F):
1751
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,T,T):
1752
return cpContigStrips2SeparateTiles;
1753
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,T,F):
1754
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,T,T):
1755
return cpSeparateStrips2ContigTiles;
1756
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,T,F):
1757
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,T,T):
1758
return cpSeparateStrips2SeparateTiles;
1759
/* Tiles -> Tiles */
1760
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,T,F):
1761
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,T,T):
1762
return cpContigTiles2ContigTiles;
1763
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,T,F):
1764
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,T,T):
1765
return cpContigTiles2SeparateTiles;
1766
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,T,F):
1767
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,T,T):
1768
return cpSeparateTiles2ContigTiles;
1769
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,T,F):
1770
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,T,T):
1771
return cpSeparateTiles2SeparateTiles;
1772
/* Tiles -> Strips */
1773
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,F,F):
1774
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,F,T):
1775
return cpContigTiles2ContigStrips;
1776
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,F,F):
1777
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,F,T):
1778
return cpContigTiles2SeparateStrips;
1779
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,F,F):
1780
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,F,T):
1781
return cpSeparateTiles2ContigStrips;
1782
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,F,F):
1783
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,F,T):
1784
return cpSeparateTiles2SeparateStrips;
1785
/* Strips -> Strips */
1786
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,F,F):
1787
return bias ? cpBiasedContig2Contig : cpContig2ContigByRow;
1788
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,F,T):
1789
return cpDecodedStrips;
1790
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,F,F):
1791
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,F,T):
1792
return cpContig2SeparateByRow;
1793
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,F,F):
1794
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,F,T):
1795
return cpSeparate2ContigByRow;
1796
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,F,F):
1797
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,F,T):
1798
return cpSeparate2SeparateByRow;
1803
fprintf(stderr, "tiffcp: %s: Don't know how to copy/convert image.\n",
1808
/* vim: set ts=8 sts=8 sw=8 noet: */