summaryrefslogtreecommitdiff
path: root/tiff/tools/tiffcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'tiff/tools/tiffcp.c')
-rwxr-xr-xtiff/tools/tiffcp.c1870
1 files changed, 0 insertions, 1870 deletions
diff --git a/tiff/tools/tiffcp.c b/tiff/tools/tiffcp.c
deleted file mode 100755
index c186b9b..0000000
--- a/tiff/tools/tiffcp.c
+++ /dev/null
@@ -1,1870 +0,0 @@
-/* $Id: tiffcp.c,v 1.51 2014-12-21 16:28:37 erouault Exp $ */
-
-/*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Revised: 2/18/01 BAR -- added syntax for extracting single images from
- * multi-image TIFF files.
- *
- * New syntax is: sourceFileName,image#
- *
- * image# ranges from 0..<n-1> where n is the # of images in the file.
- * There may be no white space between the comma and the filename or
- * image number.
- *
- * Example: tiffcp source.tif,1 destination.tif
- *
- * Copies the 2nd image in source.tif to the destination.
- *
- *****
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#include "tif_config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <ctype.h>
-#include <assert.h>
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#include "tiffio.h"
-
-#ifndef HAVE_GETOPT
-extern int getopt(int, char**, char*);
-#endif
-
-#if defined(VMS)
-# define unlink delete
-#endif
-
-#define streq(a,b) (strcmp(a,b) == 0)
-#define strneq(a,b,n) (strncmp(a,b,n) == 0)
-
-#define TRUE 1
-#define FALSE 0
-
-static int outtiled = -1;
-static uint32 tilewidth;
-static uint32 tilelength;
-
-static uint16 config;
-static uint16 compression;
-static uint16 predictor;
-static int preset;
-static uint16 fillorder;
-static uint16 orientation;
-static uint32 rowsperstrip;
-static uint32 g3opts;
-static int ignore = FALSE; /* if true, ignore read errors */
-static uint32 defg3opts = (uint32) -1;
-static int quality = 75; /* JPEG quality */
-static int jpegcolormode = JPEGCOLORMODE_RGB;
-static uint16 defcompression = (uint16) -1;
-static uint16 defpredictor = (uint16) -1;
-static int defpreset = -1;
-
-static int tiffcp(TIFF*, TIFF*);
-static int processCompressOptions(char*);
-static void usage(void);
-
-static char comma = ','; /* (default) comma separator character */
-static TIFF* bias = NULL;
-static int pageNum = 0;
-static int pageInSeq = 0;
-
-static int nextSrcImage (TIFF *tif, char **imageSpec)
-/*
- seek to the next image specified in *imageSpec
- returns 1 if success, 0 if no more images to process
- *imageSpec=NULL if subsequent images should be processed in sequence
-*/
-{
- if (**imageSpec == comma) { /* if not @comma, we've done all images */
- char *start = *imageSpec + 1;
- tdir_t nextImage = (tdir_t)strtol(start, imageSpec, 0);
- if (start == *imageSpec) nextImage = TIFFCurrentDirectory (tif);
- if (**imageSpec)
- {
- if (**imageSpec == comma) {
- /* a trailing comma denotes remaining images in sequence */
- if ((*imageSpec)[1] == '\0') *imageSpec = NULL;
- }else{
- fprintf (stderr,
- "Expected a %c separated image # list after %s\n",
- comma, TIFFFileName (tif));
- exit (-4); /* syntax error */
- }
- }
- if (TIFFSetDirectory (tif, nextImage)) return 1;
- fprintf (stderr, "%s%c%d not found!\n",
- TIFFFileName(tif), comma, (int) nextImage);
- }
- return 0;
-}
-
-
-static TIFF* openSrcImage (char **imageSpec)
-/*
- imageSpec points to a pointer to a filename followed by optional ,image#'s
- Open the TIFF file and assign *imageSpec to either NULL if there are
- no images specified, or a pointer to the next image number text
-*/
-{
- TIFF *tif;
- char *fn = *imageSpec;
- *imageSpec = strchr (fn, comma);
- if (*imageSpec) { /* there is at least one image number specifier */
- **imageSpec = '\0';
- tif = TIFFOpen (fn, "r");
- /* but, ignore any single trailing comma */
- if (!(*imageSpec)[1]) {*imageSpec = NULL; return tif;}
- if (tif) {
- **imageSpec = comma; /* replace the comma */
- if (!nextSrcImage(tif, imageSpec)) {
- TIFFClose (tif);
- tif = NULL;
- }
- }
- }else
- tif = TIFFOpen (fn, "r");
- return tif;
-}
-
-int
-main(int argc, char* argv[])
-{
- uint16 defconfig = (uint16) -1;
- uint16 deffillorder = 0;
- uint32 deftilewidth = (uint32) -1;
- uint32 deftilelength = (uint32) -1;
- uint32 defrowsperstrip = (uint32) 0;
- uint64 diroff = 0;
- TIFF* in;
- TIFF* out;
- char mode[10];
- char* mp = mode;
- int c;
- extern int optind;
- extern char* optarg;
-
- *mp++ = 'w';
- *mp = '\0';
- while ((c = getopt(argc, argv, ",:b:c:f:l:o:p:r:w:aistBLMC8x")) != -1)
- switch (c) {
- case ',':
- if (optarg[0] != '=') usage();
- comma = optarg[1];
- break;
- case 'b': /* this file is bias image subtracted from others */
- if (bias) {
- fputs ("Only 1 bias image may be specified\n", stderr);
- exit (-2);
- }
- {
- uint16 samples = (uint16) -1;
- char **biasFn = &optarg;
- bias = openSrcImage (biasFn);
- if (!bias) exit (-5);
- if (TIFFIsTiled (bias)) {
- fputs ("Bias image must be organized in strips\n", stderr);
- exit (-7);
- }
- TIFFGetField(bias, TIFFTAG_SAMPLESPERPIXEL, &samples);
- if (samples != 1) {
- fputs ("Bias image must be monochrome\n", stderr);
- exit (-7);
- }
- }
- break;
- case 'a': /* append to output */
- mode[0] = 'a';
- break;
- case 'c': /* compression scheme */
- if (!processCompressOptions(optarg))
- usage();
- break;
- case 'f': /* fill order */
- if (streq(optarg, "lsb2msb"))
- deffillorder = FILLORDER_LSB2MSB;
- else if (streq(optarg, "msb2lsb"))
- deffillorder = FILLORDER_MSB2LSB;
- else
- usage();
- break;
- case 'i': /* ignore errors */
- ignore = TRUE;
- break;
- case 'l': /* tile length */
- outtiled = TRUE;
- deftilelength = atoi(optarg);
- break;
- case 'o': /* initial directory offset */
- diroff = strtoul(optarg, NULL, 0);
- break;
- case 'p': /* planar configuration */
- if (streq(optarg, "separate"))
- defconfig = PLANARCONFIG_SEPARATE;
- else if (streq(optarg, "contig"))
- defconfig = PLANARCONFIG_CONTIG;
- else
- usage();
- break;
- case 'r': /* rows/strip */
- defrowsperstrip = atol(optarg);
- break;
- case 's': /* generate stripped output */
- outtiled = FALSE;
- break;
- case 't': /* generate tiled output */
- outtiled = TRUE;
- break;
- case 'w': /* tile width */
- outtiled = TRUE;
- deftilewidth = atoi(optarg);
- break;
- case 'B':
- *mp++ = 'b'; *mp = '\0';
- break;
- case 'L':
- *mp++ = 'l'; *mp = '\0';
- break;
- case 'M':
- *mp++ = 'm'; *mp = '\0';
- break;
- case 'C':
- *mp++ = 'c'; *mp = '\0';
- break;
- case '8':
- *mp++ = '8'; *mp = '\0';
- break;
- case 'x':
- pageInSeq = 1;
- break;
- case '?':
- usage();
- /*NOTREACHED*/
- }
- if (argc - optind < 2)
- usage();
- out = TIFFOpen(argv[argc-1], mode);
- if (out == NULL)
- return (-2);
- if ((argc - optind) == 2)
- pageNum = -1;
- for (; optind < argc-1 ; optind++) {
- char *imageCursor = argv[optind];
- in = openSrcImage (&imageCursor);
- if (in == NULL) {
- (void) TIFFClose(out);
- return (-3);
- }
- if (diroff != 0 && !TIFFSetSubDirectory(in, diroff)) {
- TIFFError(TIFFFileName(in),
- "Error, setting subdirectory at " TIFF_UINT64_FORMAT, diroff);
- (void) TIFFClose(in);
- (void) TIFFClose(out);
- return (1);
- }
- for (;;) {
- config = defconfig;
- compression = defcompression;
- predictor = defpredictor;
- preset = defpreset;
- fillorder = deffillorder;
- rowsperstrip = defrowsperstrip;
- tilewidth = deftilewidth;
- tilelength = deftilelength;
- g3opts = defg3opts;
- if (!tiffcp(in, out) || !TIFFWriteDirectory(out)) {
- (void) TIFFClose(in);
- (void) TIFFClose(out);
- return (1);
- }
- if (imageCursor) { /* seek next image directory */
- if (!nextSrcImage(in, &imageCursor)) break;
- }else
- if (!TIFFReadDirectory(in)) break;
- }
- (void) TIFFClose(in);
- }
-
- (void) TIFFClose(out);
- return (0);
-}
-
-static void
-processZIPOptions(char* cp)
-{
- if ( (cp = strchr(cp, ':')) ) {
- do {
- cp++;
- if (isdigit((int)*cp))
- defpredictor = atoi(cp);
- else if (*cp == 'p')
- defpreset = atoi(++cp);
- else
- usage();
- } while( (cp = strchr(cp, ':')) );
- }
-}
-
-static void
-processG3Options(char* cp)
-{
- if( (cp = strchr(cp, ':')) ) {
- if (defg3opts == (uint32) -1)
- defg3opts = 0;
- do {
- cp++;
- if (strneq(cp, "1d", 2))
- defg3opts &= ~GROUP3OPT_2DENCODING;
- else if (strneq(cp, "2d", 2))
- defg3opts |= GROUP3OPT_2DENCODING;
- else if (strneq(cp, "fill", 4))
- defg3opts |= GROUP3OPT_FILLBITS;
- else
- usage();
- } while( (cp = strchr(cp, ':')) );
- }
-}
-
-static int
-processCompressOptions(char* opt)
-{
- if (streq(opt, "none")) {
- defcompression = COMPRESSION_NONE;
- } else if (streq(opt, "packbits")) {
- defcompression = COMPRESSION_PACKBITS;
- } else if (strneq(opt, "jpeg", 4)) {
- char* cp = strchr(opt, ':');
-
- defcompression = COMPRESSION_JPEG;
- while( cp )
- {
- if (isdigit((int)cp[1]))
- quality = atoi(cp+1);
- else if (cp[1] == 'r' )
- jpegcolormode = JPEGCOLORMODE_RAW;
- else
- usage();
-
- cp = strchr(cp+1,':');
- }
- } else if (strneq(opt, "g3", 2)) {
- processG3Options(opt);
- defcompression = COMPRESSION_CCITTFAX3;
- } else if (streq(opt, "g4")) {
- defcompression = COMPRESSION_CCITTFAX4;
- } else if (strneq(opt, "lzw", 3)) {
- char* cp = strchr(opt, ':');
- if (cp)
- defpredictor = atoi(cp+1);
- defcompression = COMPRESSION_LZW;
- } else if (strneq(opt, "zip", 3)) {
- processZIPOptions(opt);
- defcompression = COMPRESSION_ADOBE_DEFLATE;
- } else if (strneq(opt, "lzma", 4)) {
- processZIPOptions(opt);
- defcompression = COMPRESSION_LZMA;
- } else if (strneq(opt, "jbig", 4)) {
- defcompression = COMPRESSION_JBIG;
- } else if (strneq(opt, "sgilog", 6)) {
- defcompression = COMPRESSION_SGILOG;
- } else
- return (0);
- return (1);
-}
-
-char* stuff[] = {
-"usage: tiffcp [options] input... output",
-"where options are:",
-" -a append to output instead of overwriting",
-" -o offset set initial directory offset",
-" -p contig pack samples contiguously (e.g. RGBRGB...)",
-" -p separate store samples separately (e.g. RRR...GGG...BBB...)",
-" -s write output in strips",
-" -t write output in tiles",
-" -x force the merged tiff pages in sequence",
-" -8 write BigTIFF instead of default ClassicTIFF",
-" -B write big-endian instead of native byte order",
-" -L write little-endian instead of native byte order",
-" -M disable use of memory-mapped files",
-" -C disable strip chopping",
-" -i ignore read errors",
-" -b file[,#] bias (dark) monochrome image to be subtracted from all others",
-" -,=% use % rather than , to separate image #'s (per Note below)",
-"",
-" -r # make each strip have no more than # rows",
-" -w # set output tile width (pixels)",
-" -l # set output tile length (pixels)",
-"",
-" -f lsb2msb force lsb-to-msb FillOrder for output",
-" -f msb2lsb force msb-to-lsb FillOrder for output",
-"",
-" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
-" -c zip[:opts] compress output with deflate encoding",
-" -c lzma[:opts] compress output with LZMA2 encoding",
-" -c jpeg[:opts] compress output with JPEG encoding",
-" -c jbig compress output with ISO JBIG encoding",
-" -c packbits compress output with packbits encoding",
-" -c g3[:opts] compress output with CCITT Group 3 encoding",
-" -c g4 compress output with CCITT Group 4 encoding",
-" -c sgilog compress output with SGILOG encoding",
-" -c none use no compression algorithm on output",
-"",
-"Group 3 options:",
-" 1d use default CCITT Group 3 1D-encoding",
-" 2d use optional CCITT Group 3 2D-encoding",
-" fill byte-align EOL codes",
-"For example, -c g3:2d:fill to get G3-2D-encoded data with byte-aligned EOLs",
-"",
-"JPEG options:",
-" # set compression quality level (0-100, default 75)",
-" r output color image as RGB rather than YCbCr",
-"For example, -c jpeg:r:50 to get JPEG-encoded RGB data with 50% comp. quality",
-"",
-"LZW, Deflate (ZIP) and LZMA2 options:",
-" # set predictor value",
-" p# set compression level (preset)",
-"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing,",
-"-c zip:3:p9 for Deflate encoding with maximum compression level and floating",
-"point predictor.",
-"",
-"Note that input filenames may be of the form filename,x,y,z",
-"where x, y, and z specify image numbers in the filename to copy.",
-"example: tiffcp -c none -b esp.tif,1 esp.tif,0 test.tif",
-" subtract 2nd image in esp.tif from 1st yielding uncompressed result test.tif",
-NULL
-};
-
-static void
-usage(void)
-{
- char buf[BUFSIZ];
- int i;
-
- setbuf(stderr, buf);
- fprintf(stderr, "%s\n\n", TIFFGetVersion());
- for (i = 0; stuff[i] != NULL; i++)
- fprintf(stderr, "%s\n", stuff[i]);
- exit(-1);
-}
-
-#define CopyField(tag, v) \
- if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
-#define CopyField2(tag, v1, v2) \
- if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
-#define CopyField3(tag, v1, v2, v3) \
- if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
-#define CopyField4(tag, v1, v2, v3, v4) \
- if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4)
-
-static void
-cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type)
-{
- switch (type) {
- case TIFF_SHORT:
- if (count == 1) {
- uint16 shortv;
- CopyField(tag, shortv);
- } else if (count == 2) {
- uint16 shortv1, shortv2;
- CopyField2(tag, shortv1, shortv2);
- } else if (count == 4) {
- uint16 *tr, *tg, *tb, *ta;
- CopyField4(tag, tr, tg, tb, ta);
- } else if (count == (uint16) -1) {
- uint16 shortv1;
- uint16* shortav;
- CopyField2(tag, shortv1, shortav);
- }
- break;
- case TIFF_LONG:
- { uint32 longv;
- CopyField(tag, longv);
- }
- break;
- case TIFF_RATIONAL:
- if (count == 1) {
- float floatv;
- CopyField(tag, floatv);
- } else if (count == (uint16) -1) {
- float* floatav;
- CopyField(tag, floatav);
- }
- break;
- case TIFF_ASCII:
- { char* stringv;
- CopyField(tag, stringv);
- }
- break;
- case TIFF_DOUBLE:
- if (count == 1) {
- double doublev;
- CopyField(tag, doublev);
- } else if (count == (uint16) -1) {
- double* doubleav;
- CopyField(tag, doubleav);
- }
- break;
- default:
- TIFFError(TIFFFileName(in),
- "Data type %d is not supported, tag %d skipped.",
- tag, type);
- }
-}
-
-static struct cpTag {
- uint16 tag;
- uint16 count;
- TIFFDataType type;
-} tags[] = {
- { TIFFTAG_SUBFILETYPE, 1, TIFF_LONG },
- { TIFFTAG_THRESHHOLDING, 1, TIFF_SHORT },
- { TIFFTAG_DOCUMENTNAME, 1, TIFF_ASCII },
- { TIFFTAG_IMAGEDESCRIPTION, 1, TIFF_ASCII },
- { TIFFTAG_MAKE, 1, TIFF_ASCII },
- { TIFFTAG_MODEL, 1, TIFF_ASCII },
- { TIFFTAG_MINSAMPLEVALUE, 1, TIFF_SHORT },
- { TIFFTAG_MAXSAMPLEVALUE, 1, TIFF_SHORT },
- { TIFFTAG_XRESOLUTION, 1, TIFF_RATIONAL },
- { TIFFTAG_YRESOLUTION, 1, TIFF_RATIONAL },
- { TIFFTAG_PAGENAME, 1, TIFF_ASCII },
- { TIFFTAG_XPOSITION, 1, TIFF_RATIONAL },
- { TIFFTAG_YPOSITION, 1, TIFF_RATIONAL },
- { TIFFTAG_RESOLUTIONUNIT, 1, TIFF_SHORT },
- { TIFFTAG_SOFTWARE, 1, TIFF_ASCII },
- { TIFFTAG_DATETIME, 1, TIFF_ASCII },
- { TIFFTAG_ARTIST, 1, TIFF_ASCII },
- { TIFFTAG_HOSTCOMPUTER, 1, TIFF_ASCII },
- { TIFFTAG_WHITEPOINT, (uint16) -1, TIFF_RATIONAL },
- { TIFFTAG_PRIMARYCHROMATICITIES,(uint16) -1,TIFF_RATIONAL },
- { TIFFTAG_HALFTONEHINTS, 2, TIFF_SHORT },
- { TIFFTAG_INKSET, 1, TIFF_SHORT },
- { TIFFTAG_DOTRANGE, 2, TIFF_SHORT },
- { TIFFTAG_TARGETPRINTER, 1, TIFF_ASCII },
- { TIFFTAG_SAMPLEFORMAT, 1, TIFF_SHORT },
- { TIFFTAG_YCBCRCOEFFICIENTS, (uint16) -1,TIFF_RATIONAL },
- { TIFFTAG_YCBCRSUBSAMPLING, 2, TIFF_SHORT },
- { TIFFTAG_YCBCRPOSITIONING, 1, TIFF_SHORT },
- { TIFFTAG_REFERENCEBLACKWHITE, (uint16) -1,TIFF_RATIONAL },
- { TIFFTAG_EXTRASAMPLES, (uint16) -1, TIFF_SHORT },
- { TIFFTAG_SMINSAMPLEVALUE, 1, TIFF_DOUBLE },
- { TIFFTAG_SMAXSAMPLEVALUE, 1, TIFF_DOUBLE },
- { TIFFTAG_STONITS, 1, TIFF_DOUBLE },
-};
-#define NTAGS (sizeof (tags) / sizeof (tags[0]))
-
-#define CopyTag(tag, count, type) cpTag(in, out, tag, count, type)
-
-typedef int (*copyFunc)
- (TIFF* in, TIFF* out, uint32 l, uint32 w, uint16 samplesperpixel);
-static copyFunc pickCopyFunc(TIFF*, TIFF*, uint16, uint16);
-
-/* PODD */
-
-static int
-tiffcp(TIFF* in, TIFF* out)
-{
- uint16 bitspersample, samplesperpixel;
- uint16 input_compression, input_photometric;
- copyFunc cf;
- uint32 width, length;
- struct cpTag* p;
-
- CopyField(TIFFTAG_IMAGEWIDTH, width);
- CopyField(TIFFTAG_IMAGELENGTH, length);
- CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample);
- CopyField(TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
- if (compression != (uint16)-1)
- TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
- else
- CopyField(TIFFTAG_COMPRESSION, compression);
- TIFFGetFieldDefaulted(in, TIFFTAG_COMPRESSION, &input_compression);
- TIFFGetFieldDefaulted(in, TIFFTAG_PHOTOMETRIC, &input_photometric);
- if (input_compression == COMPRESSION_JPEG) {
- /* Force conversion to RGB */
- TIFFSetField(in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
- } else if (input_photometric == PHOTOMETRIC_YCBCR) {
- /* Otherwise, can't handle subsampled input */
- uint16 subsamplinghor,subsamplingver;
-
- TIFFGetFieldDefaulted(in, TIFFTAG_YCBCRSUBSAMPLING,
- &subsamplinghor, &subsamplingver);
- if (subsamplinghor!=1 || subsamplingver!=1) {
- fprintf(stderr, "tiffcp: %s: Can't copy/convert subsampled image.\n",
- TIFFFileName(in));
- return FALSE;
- }
- }
- if (compression == COMPRESSION_JPEG) {
- if (input_photometric == PHOTOMETRIC_RGB &&
- jpegcolormode == JPEGCOLORMODE_RGB)
- TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
- else
- TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
- }
- else if (compression == COMPRESSION_SGILOG
- || compression == COMPRESSION_SGILOG24)
- TIFFSetField(out, TIFFTAG_PHOTOMETRIC,
- samplesperpixel == 1 ?
- PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
- else if (input_compression == COMPRESSION_JPEG &&
- samplesperpixel == 3 ) {
- /* RGB conversion was forced above
- hence the output will be of the same type */
- TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
- }
- else
- CopyTag(TIFFTAG_PHOTOMETRIC, 1, TIFF_SHORT);
- if (fillorder != 0)
- TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
- else
- CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT);
- /*
- * Will copy `Orientation' tag from input image
- */
- TIFFGetFieldDefaulted(in, TIFFTAG_ORIENTATION, &orientation);
- switch (orientation) {
- case ORIENTATION_BOTRIGHT:
- case ORIENTATION_RIGHTBOT: /* XXX */
- TIFFWarning(TIFFFileName(in), "using bottom-left orientation");
- orientation = ORIENTATION_BOTLEFT;
- /* fall thru... */
- case ORIENTATION_LEFTBOT: /* XXX */
- case ORIENTATION_BOTLEFT:
- break;
- case ORIENTATION_TOPRIGHT:
- case ORIENTATION_RIGHTTOP: /* XXX */
- default:
- TIFFWarning(TIFFFileName(in), "using top-left orientation");
- orientation = ORIENTATION_TOPLEFT;
- /* fall thru... */
- case ORIENTATION_LEFTTOP: /* XXX */
- case ORIENTATION_TOPLEFT:
- break;
- }
- TIFFSetField(out, TIFFTAG_ORIENTATION, orientation);
- /*
- * Choose tiles/strip for the output image according to
- * the command line arguments (-tiles, -strips) and the
- * structure of the input image.
- */
- if (outtiled == -1)
- outtiled = TIFFIsTiled(in);
- if (outtiled) {
- /*
- * Setup output file's tile width&height. If either
- * is not specified, use either the value from the
- * input image or, if nothing is defined, use the
- * library default.
- */
- if (tilewidth == (uint32) -1)
- TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth);
- if (tilelength == (uint32) -1)
- TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength);
- TIFFDefaultTileSize(out, &tilewidth, &tilelength);
- TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth);
- TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength);
- } else {
- /*
- * RowsPerStrip is left unspecified: use either the
- * value from the input image or, if nothing is defined,
- * use the library default.
- */
- if (rowsperstrip == (uint32) 0) {
- if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP,
- &rowsperstrip)) {
- rowsperstrip =
- TIFFDefaultStripSize(out, rowsperstrip);
- }
- if (rowsperstrip > length && rowsperstrip != (uint32)-1)
- rowsperstrip = length;
- }
- else if (rowsperstrip == (uint32) -1)
- rowsperstrip = length;
- TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
- }
- if (config != (uint16) -1)
- TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
- else
- CopyField(TIFFTAG_PLANARCONFIG, config);
- if (samplesperpixel <= 4)
- CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT);
- CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT);
-/* SMinSampleValue & SMaxSampleValue */
- switch (compression) {
- case COMPRESSION_JPEG:
- TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
- TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
- break;
- case COMPRESSION_JBIG:
- CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
- CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
- CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
- CopyTag(TIFFTAG_FAXDCS, 1, TIFF_ASCII);
- break;
- case COMPRESSION_LZW:
- case COMPRESSION_ADOBE_DEFLATE:
- case COMPRESSION_DEFLATE:
- case COMPRESSION_LZMA:
- if (predictor != (uint16)-1)
- TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
- else
- CopyField(TIFFTAG_PREDICTOR, predictor);
- if (preset != -1) {
- if (compression == COMPRESSION_ADOBE_DEFLATE
- || compression == COMPRESSION_DEFLATE)
- TIFFSetField(out, TIFFTAG_ZIPQUALITY, preset);
- else if (compression == COMPRESSION_LZMA)
- TIFFSetField(out, TIFFTAG_LZMAPRESET, preset);
- }
- break;
- case COMPRESSION_CCITTFAX3:
- case COMPRESSION_CCITTFAX4:
- if (compression == COMPRESSION_CCITTFAX3) {
- if (g3opts != (uint32) -1)
- TIFFSetField(out, TIFFTAG_GROUP3OPTIONS,
- g3opts);
- else
- CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
- } else
- CopyTag(TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG);
- CopyTag(TIFFTAG_BADFAXLINES, 1, TIFF_LONG);
- CopyTag(TIFFTAG_CLEANFAXDATA, 1, TIFF_LONG);
- CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG);
- CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG);
- CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG);
- CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII);
- break;
- }
- {
- uint32 len32;
- void** data;
- if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data))
- TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data);
- }
- {
- uint16 ninks;
- const char* inknames;
- if (TIFFGetField(in, TIFFTAG_NUMBEROFINKS, &ninks)) {
- TIFFSetField(out, TIFFTAG_NUMBEROFINKS, ninks);
- if (TIFFGetField(in, TIFFTAG_INKNAMES, &inknames)) {
- int inknameslen = strlen(inknames) + 1;
- const char* cp = inknames;
- while (ninks > 1) {
- cp = strchr(cp, '\0');
- cp++;
- inknameslen += (strlen(cp) + 1);
- ninks--;
- }
- TIFFSetField(out, TIFFTAG_INKNAMES, inknameslen, inknames);
- }
- }
- }
- {
- unsigned short pg0, pg1;
-
- if (pageInSeq == 1) {
- if (pageNum < 0) /* only one input file */ {
- if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1))
- TIFFSetField(out, TIFFTAG_PAGENUMBER, pg0, pg1);
- } else
- TIFFSetField(out, TIFFTAG_PAGENUMBER, pageNum++, 0);
-
- } else {
- if (TIFFGetField(in, TIFFTAG_PAGENUMBER, &pg0, &pg1)) {
- if (pageNum < 0) /* only one input file */
- TIFFSetField(out, TIFFTAG_PAGENUMBER, pg0, pg1);
- else
- TIFFSetField(out, TIFFTAG_PAGENUMBER, pageNum++, 0);
- }
- }
- }
-
- for (p = tags; p < &tags[NTAGS]; p++)
- CopyTag(p->tag, p->count, p->type);
-
- cf = pickCopyFunc(in, out, bitspersample, samplesperpixel);
- return (cf ? (*cf)(in, out, length, width, samplesperpixel) : FALSE);
-}
-
-/*
- * Copy Functions.
- */
-#define DECLAREcpFunc(x) \
-static int x(TIFF* in, TIFF* out, \
- uint32 imagelength, uint32 imagewidth, tsample_t spp)
-
-#define DECLAREreadFunc(x) \
-static int x(TIFF* in, \
- uint8* buf, uint32 imagelength, uint32 imagewidth, tsample_t spp)
-typedef int (*readFunc)(TIFF*, uint8*, uint32, uint32, tsample_t);
-
-#define DECLAREwriteFunc(x) \
-static int x(TIFF* out, \
- uint8* buf, uint32 imagelength, uint32 imagewidth, tsample_t spp)
-typedef int (*writeFunc)(TIFF*, uint8*, uint32, uint32, tsample_t);
-
-/*
- * Contig -> contig by scanline for rows/strip change.
- */
-DECLAREcpFunc(cpContig2ContigByRow)
-{
- tsize_t scanlinesize = TIFFScanlineSize(in);
- tdata_t buf;
- uint32 row;
-
- buf = _TIFFmalloc(scanlinesize);
- if (!buf)
- return 0;
- _TIFFmemset(buf, 0, scanlinesize);
- (void) imagewidth; (void) spp;
- for (row = 0; row < imagelength; row++) {
- if (TIFFReadScanline(in, buf, row, 0) < 0 && !ignore) {
- TIFFError(TIFFFileName(in),
- "Error, can't read scanline %lu",
- (unsigned long) row);
- goto bad;
- }
- if (TIFFWriteScanline(out, buf, row, 0) < 0) {
- TIFFError(TIFFFileName(out),
- "Error, can't write scanline %lu",
- (unsigned long) row);
- goto bad;
- }
- }
- _TIFFfree(buf);
- return 1;
-bad:
- _TIFFfree(buf);
- return 0;
-}
-
-
-typedef void biasFn (void *image, void *bias, uint32 pixels);
-
-#define subtract(bits) \
-static void subtract##bits (void *i, void *b, uint32 pixels)\
-{\
- uint##bits *image = i;\
- uint##bits *bias = b;\
- while (pixels--) {\
- *image = *image > *bias ? *image-*bias : 0;\
- image++, bias++; \
- } \
-}
-
-subtract(8)
-subtract(16)
-subtract(32)
-
-static biasFn *lineSubtractFn (unsigned bits)
-{
- switch (bits) {
- case 8: return subtract8;
- case 16: return subtract16;
- case 32: return subtract32;
- }
- return NULL;
-}
-
-/*
- * Contig -> contig by scanline while subtracting a bias image.
- */
-DECLAREcpFunc(cpBiasedContig2Contig)
-{
- if (spp == 1) {
- tsize_t biasSize = TIFFScanlineSize(bias);
- tsize_t bufSize = TIFFScanlineSize(in);
- tdata_t buf, biasBuf;
- uint32 biasWidth = 0, biasLength = 0;
- TIFFGetField(bias, TIFFTAG_IMAGEWIDTH, &biasWidth);
- TIFFGetField(bias, TIFFTAG_IMAGELENGTH, &biasLength);
- if (biasSize == bufSize &&
- imagelength == biasLength && imagewidth == biasWidth) {
- uint16 sampleBits = 0;
- biasFn *subtractLine;
- TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &sampleBits);
- subtractLine = lineSubtractFn (sampleBits);
- if (subtractLine) {
- uint32 row;
- buf = _TIFFmalloc(bufSize);
- biasBuf = _TIFFmalloc(bufSize);
- for (row = 0; row < imagelength; row++) {
- if (TIFFReadScanline(in, buf, row, 0) < 0
- && !ignore) {
- TIFFError(TIFFFileName(in),
- "Error, can't read scanline %lu",
- (unsigned long) row);
- goto bad;
- }
- if (TIFFReadScanline(bias, biasBuf, row, 0) < 0
- && !ignore) {
- TIFFError(TIFFFileName(in),
- "Error, can't read biased scanline %lu",
- (unsigned long) row);
- goto bad;
- }
- subtractLine (buf, biasBuf, imagewidth);
- if (TIFFWriteScanline(out, buf, row, 0) < 0) {
- TIFFError(TIFFFileName(out),
- "Error, can't write scanline %lu",
- (unsigned long) row);
- goto bad;
- }
- }
-
- _TIFFfree(buf);
- _TIFFfree(biasBuf);
- TIFFSetDirectory(bias,
- TIFFCurrentDirectory(bias)); /* rewind */
- return 1;
-bad:
- _TIFFfree(buf);
- _TIFFfree(biasBuf);
- return 0;
- } else {
- TIFFError(TIFFFileName(in),
- "No support for biasing %d bit pixels\n",
- sampleBits);
- return 0;
- }
- }
- TIFFError(TIFFFileName(in),
- "Bias image %s,%d\nis not the same size as %s,%d\n",
- TIFFFileName(bias), TIFFCurrentDirectory(bias),
- TIFFFileName(in), TIFFCurrentDirectory(in));
- return 0;
- } else {
- TIFFError(TIFFFileName(in),
- "Can't bias %s,%d as it has >1 Sample/Pixel\n",
- TIFFFileName(in), TIFFCurrentDirectory(in));
- return 0;
- }
-
-}
-
-
-/*
- * Strip -> strip for change in encoding.
- */
-DECLAREcpFunc(cpDecodedStrips)
-{
- tsize_t stripsize = TIFFStripSize(in);
- tdata_t buf = _TIFFmalloc(stripsize);
-
- (void) imagewidth; (void) spp;
- if (buf) {
- tstrip_t s, ns = TIFFNumberOfStrips(in);
- uint32 row = 0;
- _TIFFmemset(buf, 0, stripsize);
- for (s = 0; s < ns; s++) {
- tsize_t cc = (row + rowsperstrip > imagelength) ?
- TIFFVStripSize(in, imagelength - row) : stripsize;
- if (TIFFReadEncodedStrip(in, s, buf, cc) < 0
- && !ignore) {
- TIFFError(TIFFFileName(in),
- "Error, can't read strip %lu",
- (unsigned long) s);
- goto bad;
- }
- if (TIFFWriteEncodedStrip(out, s, buf, cc) < 0) {
- TIFFError(TIFFFileName(out),
- "Error, can't write strip %lu",
- (unsigned long) s);
- goto bad;
- }
- row += rowsperstrip;
- }
- _TIFFfree(buf);
- return 1;
- } else {
- TIFFError(TIFFFileName(in),
- "Error, can't allocate memory buffer of size %lu "
- "to read strips", (unsigned long) stripsize);
- return 0;
- }
-
-bad:
- _TIFFfree(buf);
- return 0;
-}
-
-/*
- * Separate -> separate by row for rows/strip change.
- */
-DECLAREcpFunc(cpSeparate2SeparateByRow)
-{
- tsize_t scanlinesize = TIFFScanlineSize(in);
- tdata_t buf;
- uint32 row;
- tsample_t s;
-
- (void) imagewidth;
- buf = _TIFFmalloc(scanlinesize);
- if (!buf)
- return 0;
- _TIFFmemset(buf, 0, scanlinesize);
- for (s = 0; s < spp; s++) {
- for (row = 0; row < imagelength; row++) {
- if (TIFFReadScanline(in, buf, row, s) < 0 && !ignore) {
- TIFFError(TIFFFileName(in),
- "Error, can't read scanline %lu",
- (unsigned long) row);
- goto bad;
- }
- if (TIFFWriteScanline(out, buf, row, s) < 0) {
- TIFFError(TIFFFileName(out),
- "Error, can't write scanline %lu",
- (unsigned long) row);
- goto bad;
- }
- }
- }
- _TIFFfree(buf);
- return 1;
-bad:
- _TIFFfree(buf);
- return 0;
-}
-
-/*
- * Contig -> separate by row.
- */
-DECLAREcpFunc(cpContig2SeparateByRow)
-{
- tsize_t scanlinesizein = TIFFScanlineSize(in);
- tsize_t scanlinesizeout = TIFFScanlineSize(out);
- tdata_t inbuf;
- tdata_t outbuf;
- register uint8 *inp, *outp;
- register uint32 n;
- uint32 row;
- tsample_t s;
-
- inbuf = _TIFFmalloc(scanlinesizein);
- outbuf = _TIFFmalloc(scanlinesizeout);
- if (!inbuf || !outbuf)
- return 0;
- _TIFFmemset(inbuf, 0, scanlinesizein);
- _TIFFmemset(outbuf, 0, scanlinesizeout);
- /* unpack channels */
- for (s = 0; s < spp; s++) {
- for (row = 0; row < imagelength; row++) {
- if (TIFFReadScanline(in, inbuf, row, 0) < 0
- && !ignore) {
- TIFFError(TIFFFileName(in),
- "Error, can't read scanline %lu",
- (unsigned long) row);
- goto bad;
- }
- inp = ((uint8*)inbuf) + s;
- outp = (uint8*)outbuf;
- for (n = imagewidth; n-- > 0;) {
- *outp++ = *inp;
- inp += spp;
- }
- if (TIFFWriteScanline(out, outbuf, row, s) < 0) {
- TIFFError(TIFFFileName(out),
- "Error, can't write scanline %lu",
- (unsigned long) row);
- goto bad;
- }
- }
- }
- if (inbuf) _TIFFfree(inbuf);
- if (outbuf) _TIFFfree(outbuf);
- return 1;
-bad:
- if (inbuf) _TIFFfree(inbuf);
- if (outbuf) _TIFFfree(outbuf);
- return 0;
-}
-
-/*
- * Separate -> contig by row.
- */
-DECLAREcpFunc(cpSeparate2ContigByRow)
-{
- tsize_t scanlinesizein = TIFFScanlineSize(in);
- tsize_t scanlinesizeout = TIFFScanlineSize(out);
- tdata_t inbuf;
- tdata_t outbuf;
- register uint8 *inp, *outp;
- register uint32 n;
- uint32 row;
- tsample_t s;
-
- inbuf = _TIFFmalloc(scanlinesizein);
- outbuf = _TIFFmalloc(scanlinesizeout);
- if (!inbuf || !outbuf)
- return 0;
- _TIFFmemset(inbuf, 0, scanlinesizein);
- _TIFFmemset(outbuf, 0, scanlinesizeout);
- for (row = 0; row < imagelength; row++) {
- /* merge channels */
- for (s = 0; s < spp; s++) {
- if (TIFFReadScanline(in, inbuf, row, s) < 0
- && !ignore) {
- TIFFError(TIFFFileName(in),
- "Error, can't read scanline %lu",
- (unsigned long) row);
- goto bad;
- }
- inp = (uint8*)inbuf;
- outp = ((uint8*)outbuf) + s;
- for (n = imagewidth; n-- > 0;) {
- *outp = *inp++;
- outp += spp;
- }
- }
- if (TIFFWriteScanline(out, outbuf, row, 0) < 0) {
- TIFFError(TIFFFileName(out),
- "Error, can't write scanline %lu",
- (unsigned long) row);
- goto bad;
- }
- }
- if (inbuf) _TIFFfree(inbuf);
- if (outbuf) _TIFFfree(outbuf);
- return 1;
-bad:
- if (inbuf) _TIFFfree(inbuf);
- if (outbuf) _TIFFfree(outbuf);
- return 0;
-}
-
-static void
-cpStripToTile(uint8* out, uint8* in,
- uint32 rows, uint32 cols, int outskew, int inskew)
-{
- while (rows-- > 0) {
- uint32 j = cols;
- while (j-- > 0)
- *out++ = *in++;
- out += outskew;
- in += inskew;
- }
-}
-
-static void
-cpContigBufToSeparateBuf(uint8* out, uint8* in,
- uint32 rows, uint32 cols, int outskew, int inskew, tsample_t spp,
- int bytes_per_sample )
-{
- while (rows-- > 0) {
- uint32 j = cols;
- while (j-- > 0)
- {
- int n = bytes_per_sample;
-
- while( n-- ) {
- *out++ = *in++;
- }
- in += (spp-1) * bytes_per_sample;
- }
- out += outskew;
- in += inskew;
- }
-}
-
-static void
-cpSeparateBufToContigBuf(uint8* out, uint8* in,
- uint32 rows, uint32 cols, int outskew, int inskew, tsample_t spp,
- int bytes_per_sample)
-{
- while (rows-- > 0) {
- uint32 j = cols;
- while (j-- > 0) {
- int n = bytes_per_sample;
-
- while( n-- ) {
- *out++ = *in++;
- }
- out += (spp-1)*bytes_per_sample;
- }
- out += outskew;
- in += inskew;
- }
-}
-
-static int
-cpImage(TIFF* in, TIFF* out, readFunc fin, writeFunc fout,
- uint32 imagelength, uint32 imagewidth, tsample_t spp)
-{
- int status = 0;
- tdata_t buf = NULL;
- tsize_t scanlinesize = TIFFRasterScanlineSize(in);
- tsize_t bytes = scanlinesize * (tsize_t)imagelength;
- /*
- * XXX: Check for integer overflow.
- */
- if (scanlinesize
- && imagelength
- && bytes / (tsize_t)imagelength == scanlinesize) {
- buf = _TIFFmalloc(bytes);
- if (buf) {
- if ((*fin)(in, (uint8*)buf, imagelength,
- imagewidth, spp)) {
- status = (*fout)(out, (uint8*)buf,
- imagelength, imagewidth, spp);
- }
- _TIFFfree(buf);
- } else {
- TIFFError(TIFFFileName(in),
- "Error, can't allocate space for image buffer");
- }
- } else {
- TIFFError(TIFFFileName(in), "Error, no space for image buffer");
- }
-
- return status;
-}
-
-DECLAREreadFunc(readContigStripsIntoBuffer)
-{
- tsize_t scanlinesize = TIFFScanlineSize(in);
- uint8* bufp = buf;
- uint32 row;
-
- (void) imagewidth; (void) spp;
- for (row = 0; row < imagelength; row++) {
- if (TIFFReadScanline(in, (tdata_t) bufp, row, 0) < 0
- && !ignore) {
- TIFFError(TIFFFileName(in),
- "Error, can't read scanline %lu",
- (unsigned long) row);
- return 0;
- }
- bufp += scanlinesize;
- }
-
- return 1;
-}
-
-DECLAREreadFunc(readSeparateStripsIntoBuffer)
-{
- int status = 1;
- tsize_t scanlinesize = TIFFScanlineSize(in);
- tdata_t scanline;
- if (!scanlinesize)
- return 0;
-
- scanline = _TIFFmalloc(scanlinesize);
- if (!scanline)
- return 0;
- _TIFFmemset(scanline, 0, scanlinesize);
- (void) imagewidth;
- if (scanline) {
- uint8* bufp = (uint8*) buf;
- uint32 row;
- tsample_t s;
- for (row = 0; row < imagelength; row++) {
- /* merge channels */
- for (s = 0; s < spp; s++) {
- uint8* bp = bufp + s;
- tsize_t n = scanlinesize;
- uint8* sbuf = scanline;
-
- if (TIFFReadScanline(in, scanline, row, s) < 0
- && !ignore) {
- TIFFError(TIFFFileName(in),
- "Error, can't read scanline %lu",
- (unsigned long) row);
- status = 0;
- goto done;
- }
- while (n-- > 0)
- *bp = *sbuf++, bp += spp;
- }
- bufp += scanlinesize * spp;
- }
- }
-
-done:
- _TIFFfree(scanline);
- return status;
-}
-
-DECLAREreadFunc(readContigTilesIntoBuffer)
-{
- int status = 1;
- tsize_t tilesize = TIFFTileSize(in);
- tdata_t tilebuf;
- uint32 imagew = TIFFScanlineSize(in);
- uint32 tilew = TIFFTileRowSize(in);
- int iskew = imagew - tilew;
- uint8* bufp = (uint8*) buf;
- uint32 tw, tl;
- uint32 row;
-
- (void) spp;
- tilebuf = _TIFFmalloc(tilesize);
- if (tilebuf == 0)
- return 0;
- _TIFFmemset(tilebuf, 0, tilesize);
- (void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
- (void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
-
- for (row = 0; row < imagelength; row += tl) {
- uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
- uint32 colb = 0;
- uint32 col;
-
- for (col = 0; col < imagewidth; col += tw) {
- if (TIFFReadTile(in, tilebuf, col, row, 0, 0) < 0
- && !ignore) {
- TIFFError(TIFFFileName(in),
- "Error, can't read tile at %lu %lu",
- (unsigned long) col,
- (unsigned long) row);
- status = 0;
- goto done;
- }
- if (colb + tilew > imagew) {
- uint32 width = imagew - colb;
- uint32 oskew = tilew - width;
- cpStripToTile(bufp + colb,
- tilebuf, nrow, width,
- oskew + iskew, oskew );
- } else
- cpStripToTile(bufp + colb,
- tilebuf, nrow, tilew,
- iskew, 0);
- colb += tilew;
- }
- bufp += imagew * nrow;
- }
-done:
- _TIFFfree(tilebuf);
- return status;
-}
-
-DECLAREreadFunc(readSeparateTilesIntoBuffer)
-{
- int status = 1;
- uint32 imagew = TIFFRasterScanlineSize(in);
- uint32 tilew = TIFFTileRowSize(in);
- int iskew = imagew - tilew*spp;
- tsize_t tilesize = TIFFTileSize(in);
- tdata_t tilebuf;
- uint8* bufp = (uint8*) buf;
- uint32 tw, tl;
- uint32 row;
- uint16 bps, bytes_per_sample;
-
- tilebuf = _TIFFmalloc(tilesize);
- if (tilebuf == 0)
- return 0;
- _TIFFmemset(tilebuf, 0, tilesize);
- (void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
- (void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
- (void) TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps);
- assert( bps % 8 == 0 );
- bytes_per_sample = bps/8;
-
- for (row = 0; row < imagelength; row += tl) {
- uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
- uint32 colb = 0;
- uint32 col;
-
- for (col = 0; col < imagewidth; col += tw) {
- tsample_t s;
-
- for (s = 0; s < spp; s++) {
- if (TIFFReadTile(in, tilebuf, col, row, 0, s) < 0
- && !ignore) {
- TIFFError(TIFFFileName(in),
- "Error, can't read tile at %lu %lu, "
- "sample %lu",
- (unsigned long) col,
- (unsigned long) row,
- (unsigned long) s);
- status = 0;
- goto done;
- }
- /*
- * Tile is clipped horizontally. Calculate
- * visible portion and skewing factors.
- */
- if (colb + tilew*spp > imagew) {
- uint32 width = imagew - colb;
- int oskew = tilew*spp - width;
- cpSeparateBufToContigBuf(
- bufp+colb+s*bytes_per_sample,
- tilebuf, nrow,
- width/(spp*bytes_per_sample),
- oskew + iskew,
- oskew/spp, spp,
- bytes_per_sample);
- } else
- cpSeparateBufToContigBuf(
- bufp+colb+s*bytes_per_sample,
- tilebuf, nrow, tw,
- iskew, 0, spp,
- bytes_per_sample);
- }
- colb += tilew*spp;
- }
- bufp += imagew * nrow;
- }
-done:
- _TIFFfree(tilebuf);
- return status;
-}
-
-DECLAREwriteFunc(writeBufferToContigStrips)
-{
- uint32 row, rowsperstrip;
- tstrip_t strip = 0;
-
- (void) imagewidth; (void) spp;
- (void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
- for (row = 0; row < imagelength; row += rowsperstrip) {
- uint32 nrows = (row+rowsperstrip > imagelength) ?
- imagelength-row : rowsperstrip;
- tsize_t stripsize = TIFFVStripSize(out, nrows);
- if (TIFFWriteEncodedStrip(out, strip++, buf, stripsize) < 0) {
- TIFFError(TIFFFileName(out),
- "Error, can't write strip %u", strip - 1);
- return 0;
- }
- buf += stripsize;
- }
- return 1;
-}
-
-DECLAREwriteFunc(writeBufferToSeparateStrips)
-{
- uint32 rowsize = imagewidth * spp;
- uint32 rowsperstrip;
- tsize_t stripsize = TIFFStripSize(out);
- tdata_t obuf;
- tstrip_t strip = 0;
- tsample_t s;
-
- obuf = _TIFFmalloc(stripsize);
- if (obuf == NULL)
- return (0);
- _TIFFmemset(obuf, 0, stripsize);
- (void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
- for (s = 0; s < spp; s++) {
- uint32 row;
- for (row = 0; row < imagelength; row += rowsperstrip) {
- uint32 nrows = (row+rowsperstrip > imagelength) ?
- imagelength-row : rowsperstrip;
- tsize_t stripsize = TIFFVStripSize(out, nrows);
-
- cpContigBufToSeparateBuf(
- obuf, (uint8*) buf + row*rowsize + s,
- nrows, imagewidth, 0, 0, spp, 1);
- if (TIFFWriteEncodedStrip(out, strip++, obuf, stripsize) < 0) {
- TIFFError(TIFFFileName(out),
- "Error, can't write strip %u",
- strip - 1);
- _TIFFfree(obuf);
- return 0;
- }
- }
- }
- _TIFFfree(obuf);
- return 1;
-
-}
-
-DECLAREwriteFunc(writeBufferToContigTiles)
-{
- uint32 imagew = TIFFScanlineSize(out);
- uint32 tilew = TIFFTileRowSize(out);
- int iskew = imagew - tilew;
- tsize_t tilesize = TIFFTileSize(out);
- tdata_t obuf;
- uint8* bufp = (uint8*) buf;
- uint32 tl, tw;
- uint32 row;
-
- (void) spp;
-
- obuf = _TIFFmalloc(TIFFTileSize(out));
- if (obuf == NULL)
- return 0;
- _TIFFmemset(obuf, 0, tilesize);
- (void) TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
- (void) TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
- for (row = 0; row < imagelength; row += tilelength) {
- uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
- uint32 colb = 0;
- uint32 col;
-
- for (col = 0; col < imagewidth; col += tw) {
- /*
- * Tile is clipped horizontally. Calculate
- * visible portion and skewing factors.
- */
- if (colb + tilew > imagew) {
- uint32 width = imagew - colb;
- int oskew = tilew - width;
- cpStripToTile(obuf, bufp + colb, nrow, width,
- oskew, oskew + iskew);
- } else
- cpStripToTile(obuf, bufp + colb, nrow, tilew,
- 0, iskew);
- if (TIFFWriteTile(out, obuf, col, row, 0, 0) < 0) {
- TIFFError(TIFFFileName(out),
- "Error, can't write tile at %lu %lu",
- (unsigned long) col,
- (unsigned long) row);
- _TIFFfree(obuf);
- return 0;
- }
- colb += tilew;
- }
- bufp += nrow * imagew;
- }
- _TIFFfree(obuf);
- return 1;
-}
-
-DECLAREwriteFunc(writeBufferToSeparateTiles)
-{
- uint32 imagew = TIFFScanlineSize(out);
- tsize_t tilew = TIFFTileRowSize(out);
- uint32 iimagew = TIFFRasterScanlineSize(out);
- int iskew = iimagew - tilew*spp;
- tsize_t tilesize = TIFFTileSize(out);
- tdata_t obuf;
- uint8* bufp = (uint8*) buf;
- uint32 tl, tw;
- uint32 row;
- uint16 bps, bytes_per_sample;
-
- obuf = _TIFFmalloc(TIFFTileSize(out));
- if (obuf == NULL)
- return 0;
- _TIFFmemset(obuf, 0, tilesize);
- (void) TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
- (void) TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
- (void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
- assert( bps % 8 == 0 );
- bytes_per_sample = bps/8;
-
- for (row = 0; row < imagelength; row += tl) {
- uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
- uint32 colb = 0;
- uint32 col;
-
- for (col = 0; col < imagewidth; col += tw) {
- tsample_t s;
- for (s = 0; s < spp; s++) {
- /*
- * Tile is clipped horizontally. Calculate
- * visible portion and skewing factors.
- */
- if (colb + tilew > imagew) {
- uint32 width = (imagew - colb);
- int oskew = tilew - width;
-
- cpContigBufToSeparateBuf(obuf,
- bufp + (colb*spp) + s,
- nrow, width/bytes_per_sample,
- oskew, (oskew*spp)+iskew, spp,
- bytes_per_sample);
- } else
- cpContigBufToSeparateBuf(obuf,
- bufp + (colb*spp) + s,
- nrow, tilewidth,
- 0, iskew, spp,
- bytes_per_sample);
- if (TIFFWriteTile(out, obuf, col, row, 0, s) < 0) {
- TIFFError(TIFFFileName(out),
- "Error, can't write tile at %lu %lu "
- "sample %lu",
- (unsigned long) col,
- (unsigned long) row,
- (unsigned long) s);
- _TIFFfree(obuf);
- return 0;
- }
- }
- colb += tilew;
- }
- bufp += nrow * iimagew;
- }
- _TIFFfree(obuf);
- return 1;
-}
-
-/*
- * Contig strips -> contig tiles.
- */
-DECLAREcpFunc(cpContigStrips2ContigTiles)
-{
- return cpImage(in, out,
- readContigStripsIntoBuffer,
- writeBufferToContigTiles,
- imagelength, imagewidth, spp);
-}
-
-/*
- * Contig strips -> separate tiles.
- */
-DECLAREcpFunc(cpContigStrips2SeparateTiles)
-{
- return cpImage(in, out,
- readContigStripsIntoBuffer,
- writeBufferToSeparateTiles,
- imagelength, imagewidth, spp);
-}
-
-/*
- * Separate strips -> contig tiles.
- */
-DECLAREcpFunc(cpSeparateStrips2ContigTiles)
-{
- return cpImage(in, out,
- readSeparateStripsIntoBuffer,
- writeBufferToContigTiles,
- imagelength, imagewidth, spp);
-}
-
-/*
- * Separate strips -> separate tiles.
- */
-DECLAREcpFunc(cpSeparateStrips2SeparateTiles)
-{
- return cpImage(in, out,
- readSeparateStripsIntoBuffer,
- writeBufferToSeparateTiles,
- imagelength, imagewidth, spp);
-}
-
-/*
- * Contig strips -> contig tiles.
- */
-DECLAREcpFunc(cpContigTiles2ContigTiles)
-{
- return cpImage(in, out,
- readContigTilesIntoBuffer,
- writeBufferToContigTiles,
- imagelength, imagewidth, spp);
-}
-
-/*
- * Contig tiles -> separate tiles.
- */
-DECLAREcpFunc(cpContigTiles2SeparateTiles)
-{
- return cpImage(in, out,
- readContigTilesIntoBuffer,
- writeBufferToSeparateTiles,
- imagelength, imagewidth, spp);
-}
-
-/*
- * Separate tiles -> contig tiles.
- */
-DECLAREcpFunc(cpSeparateTiles2ContigTiles)
-{
- return cpImage(in, out,
- readSeparateTilesIntoBuffer,
- writeBufferToContigTiles,
- imagelength, imagewidth, spp);
-}
-
-/*
- * Separate tiles -> separate tiles (tile dimension change).
- */
-DECLAREcpFunc(cpSeparateTiles2SeparateTiles)
-{
- return cpImage(in, out,
- readSeparateTilesIntoBuffer,
- writeBufferToSeparateTiles,
- imagelength, imagewidth, spp);
-}
-
-/*
- * Contig tiles -> contig tiles (tile dimension change).
- */
-DECLAREcpFunc(cpContigTiles2ContigStrips)
-{
- return cpImage(in, out,
- readContigTilesIntoBuffer,
- writeBufferToContigStrips,
- imagelength, imagewidth, spp);
-}
-
-/*
- * Contig tiles -> separate strips.
- */
-DECLAREcpFunc(cpContigTiles2SeparateStrips)
-{
- return cpImage(in, out,
- readContigTilesIntoBuffer,
- writeBufferToSeparateStrips,
- imagelength, imagewidth, spp);
-}
-
-/*
- * Separate tiles -> contig strips.
- */
-DECLAREcpFunc(cpSeparateTiles2ContigStrips)
-{
- return cpImage(in, out,
- readSeparateTilesIntoBuffer,
- writeBufferToContigStrips,
- imagelength, imagewidth, spp);
-}
-
-/*
- * Separate tiles -> separate strips.
- */
-DECLAREcpFunc(cpSeparateTiles2SeparateStrips)
-{
- return cpImage(in, out,
- readSeparateTilesIntoBuffer,
- writeBufferToSeparateStrips,
- imagelength, imagewidth, spp);
-}
-
-/*
- * Select the appropriate copy function to use.
- */
-static copyFunc
-pickCopyFunc(TIFF* in, TIFF* out, uint16 bitspersample, uint16 samplesperpixel)
-{
- uint16 shortv;
- uint32 w, l, tw, tl;
- int bychunk;
-
- (void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv);
- if (shortv != config && bitspersample != 8 && samplesperpixel > 1) {
- fprintf(stderr,
- "%s: Cannot handle different planar configuration w/ bits/sample != 8\n",
- TIFFFileName(in));
- return (NULL);
- }
- TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w);
- TIFFGetField(in, TIFFTAG_IMAGELENGTH, &l);
- if (!(TIFFIsTiled(out) || TIFFIsTiled(in))) {
- uint32 irps = (uint32) -1L;
- TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &irps);
- /* if biased, force decoded copying to allow image subtraction */
- bychunk = !bias && (rowsperstrip == irps);
- }else{ /* either in or out is tiled */
- if (bias) {
- fprintf(stderr,
- "%s: Cannot handle tiled configuration w/bias image\n",
- TIFFFileName(in));
- return (NULL);
- }
- if (TIFFIsTiled(out)) {
- if (!TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw))
- tw = w;
- if (!TIFFGetField(in, TIFFTAG_TILELENGTH, &tl))
- tl = l;
- bychunk = (tw == tilewidth && tl == tilelength);
- } else { /* out's not, so in must be tiled */
- TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
- TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
- bychunk = (tw == w && tl == rowsperstrip);
- }
- }
-#define T 1
-#define F 0
-#define pack(a,b,c,d,e) ((long)(((a)<<11)|((b)<<3)|((c)<<2)|((d)<<1)|(e)))
- switch(pack(shortv,config,TIFFIsTiled(in),TIFFIsTiled(out),bychunk)) {
- /* Strips -> Tiles */
- case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,T,F):
- case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,T,T):
- return cpContigStrips2ContigTiles;
- case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,T,F):
- case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,T,T):
- return cpContigStrips2SeparateTiles;
- case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,T,F):
- case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,T,T):
- return cpSeparateStrips2ContigTiles;
- case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,T,F):
- case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,T,T):
- return cpSeparateStrips2SeparateTiles;
- /* Tiles -> Tiles */
- case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,T,F):
- case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,T,T):
- return cpContigTiles2ContigTiles;
- case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,T,F):
- case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,T,T):
- return cpContigTiles2SeparateTiles;
- case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,T,F):
- case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,T,T):
- return cpSeparateTiles2ContigTiles;
- case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,T,F):
- case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,T,T):
- return cpSeparateTiles2SeparateTiles;
- /* Tiles -> Strips */
- case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,F,F):
- case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,F,T):
- return cpContigTiles2ContigStrips;
- case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,F,F):
- case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,F,T):
- return cpContigTiles2SeparateStrips;
- case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,F,F):
- case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,F,T):
- return cpSeparateTiles2ContigStrips;
- case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,F,F):
- case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,F,T):
- return cpSeparateTiles2SeparateStrips;
- /* Strips -> Strips */
- case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,F,F):
- return bias ? cpBiasedContig2Contig : cpContig2ContigByRow;
- case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,F,T):
- return cpDecodedStrips;
- case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,F,F):
- case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,F,T):
- return cpContig2SeparateByRow;
- case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,F,F):
- case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,F,T):
- return cpSeparate2ContigByRow;
- case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,F,F):
- case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,F,T):
- return cpSeparate2SeparateByRow;
- }
-#undef pack
-#undef F
-#undef T
- fprintf(stderr, "tiffcp: %s: Don't know how to copy/convert image.\n",
- TIFFFileName(in));
- return (NULL);
-}
-
-/* vim: set ts=8 sts=8 sw=8 noet: */
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */