Blame tools/tiffcp.c

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