#ifndef lint
static char rcsid[] = "$Header: /cvs/bao-parsec/ext/splash2x/apps/volrend/src/libtiff/tif_getimage.c,v 1.1.1.1 2012/03/29 17:22:43 uid42307 Exp $";
#endif

/*
 * Copyright (c) 1991, 1992 Sam Leffler
 * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
 *
 * 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.
 */

/*
 * TIFF Library
 *
 * Read and return a packed RGBA image.
 */
#include "tiffio.h"
#include "tiffcompat.h"
#include "prototypes.h"

typedef	u_char RGBvalue;

static	u_long width, height;		/* image width & height */
static	u_short bitspersample;
static	u_short samplesperpixel;
static	u_short photometric;
static	u_short orientation;
/* colormap for pallete images */
static	u_short *redcmap, *greencmap, *bluecmap;
static	int stoponerr;			/* stop on read error */
static	char *filename;
/* YCbCr support */
static	u_short YCbCrHorizSampling;
static	u_short YCbCrVertSampling;
static	float *YCbCrCoeffs;
static	float *refBlackWhite;

static	u_long **BWmap;
static	u_long **PALmap;

static	int gt();

TIFFReadRGBAImage(tif, rwidth, rheight, raster, stop)
	TIFF *tif;
	u_long rwidth, rheight;
	u_long *raster;
	int stop;
{
	int ok;
	u_long width, height;

	TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
	switch (bitspersample) {
	case 1: case 2: case 4:
	case 8: case 16:
		break;
	default:
		TIFFError(TIFFFileName(tif),
		    "Sorry, can not handle %d-bit pictures", bitspersample);
		return (0);
	}
	TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
	switch (samplesperpixel) {
	case 1: case 3: case 4:
		break;
	default:
		TIFFError(TIFFFileName(tif),
		    "Sorry, can not handle %d-channel images", samplesperpixel);
		return (0);
	}
	if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
		switch (samplesperpixel) {
		case 1:
			photometric = PHOTOMETRIC_MINISBLACK;
			break;
		case 3: case 4:
			photometric = PHOTOMETRIC_RGB;
			break;
		default:
			TIFFError(TIFFFileName(tif),
			    "Missing needed \"PhotometricInterpretation\" tag");
			return (0);
		}
		TIFFError(TIFFFileName(tif),
		    "No \"PhotometricInterpretation\" tag, assuming %s\n",
		    photometric == PHOTOMETRIC_RGB ? "RGB" : "min-is-black");
	}
	/* XXX maybe should check photometric? */
	TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
	TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
	/* XXX verify rwidth and rheight against width and height */
	stoponerr = stop;
	BWmap = NULL;
	PALmap = NULL;
	ok = gt(tif, rwidth, height, raster + (rheight-height)*rwidth);
	if (BWmap)
		free((char *)BWmap);
	if (PALmap)
		free((char *)PALmap);
	return (ok);
}

static int
checkcmap(n, r, g, b)
	int n;
	u_short *r, *g, *b;
{
	while (n-- > 0)
		if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
			return (16);
	TIFFWarning(filename, "Assuming 8-bit colormap");
	return (8);
}

static	gtTileContig();
static	gtTileSeparate();
static	gtStripContig();
static	gtStripSeparate();
static	void initYCbCrConversion();

static
gt(tif, w, h, raster)
	TIFF *tif;
	int w, h;
	u_long *raster;
{
	u_short minsamplevalue, maxsamplevalue, planarconfig;
	RGBvalue *Map;
	int e;

	TIFFGetFieldDefaulted(tif, TIFFTAG_MINSAMPLEVALUE, &minsamplevalue);
	TIFFGetFieldDefaulted(tif, TIFFTAG_MAXSAMPLEVALUE, &maxsamplevalue);
	Map = NULL;
	switch (photometric) {
	case PHOTOMETRIC_YCBCR:
		TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRCOEFFICIENTS,
		    &YCbCrCoeffs);
		TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
		    &YCbCrHorizSampling, &YCbCrVertSampling);
		TIFFGetFieldDefaulted(tif, TIFFTAG_REFERENCEBLACKWHITE,
		    &refBlackWhite);
		initYCbCrConversion();
		/* fall thru... */
	case PHOTOMETRIC_RGB:
		if (minsamplevalue == 0 && maxsamplevalue == 255)
			break;
		/* fall thru... */
	case PHOTOMETRIC_MINISBLACK:
	case PHOTOMETRIC_MINISWHITE: {
		register int x, range;

		range = maxsamplevalue - minsamplevalue;
		Map = (RGBvalue *)malloc((range + 1) * sizeof (RGBvalue));
		if (Map == NULL) {
			TIFFError(filename,
			    "No space for photometric conversion table");
			return (0);
		}
		if (photometric == PHOTOMETRIC_MINISWHITE) {
			for (x = 0; x <= range; x++)
			Map[x] = ((range - x) * 255) / range;
		} else {
			for (x = 0; x <= range; x++)
			Map[x] = (x * 255) / range;
		}
		if (photometric != PHOTOMETRIC_RGB && bitspersample <= 8) {
			/*
			 * Use photometric mapping table to construct
			 * unpacking tables for samples <= 8 bits.
			 */
			if (!makebwmap(Map))
				return (0);
			/* no longer need Map, free it */
			free((char *)Map);
			Map = NULL;
		}
		break;
	}
	case PHOTOMETRIC_PALETTE:
		if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
				  &redcmap, &greencmap, &bluecmap)) {
			TIFFError(filename,
			    "Missing required \"Colormap\" tag");
			return (0);
		}
		/*
		 * Convert 16-bit colormap to 8-bit (unless it looks
		 * like an old-style 8-bit colormap).
		 */
		if (checkcmap(1<<bitspersample, redcmap, greencmap, bluecmap) == 16) {
			int i;
			for (i = (1<<bitspersample)-1; i > 0; i--) {
#define	CVT(x)		(((x) * 255) / ((1L<<16)-1))
				redcmap[i] = CVT(redcmap[i]);
				greencmap[i] = CVT(greencmap[i]);
				bluecmap[i] = CVT(bluecmap[i]);
			}
		}
		if (bitspersample <= 8) {
			/*
			 * Use mapping table and colormap to construct
			 * unpacking tables for samples < 8 bits.
			 */
			if (!makecmap(redcmap, greencmap, bluecmap))
				return (0);
		}
		break;
	}
	TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
	if (planarconfig == PLANARCONFIG_SEPARATE && samplesperpixel > 1) {
		e = TIFFIsTiled(tif) ?
		    gtTileSeparate(tif, raster, Map, h, w) :
		    gtStripSeparate(tif, raster, Map, h, w);
	} else {
		e = TIFFIsTiled(tif) ? 
		    gtTileContig(tif, raster, Map, h, w) :
		    gtStripContig(tif, raster, Map, h, w);
	}
	if (Map)
		free((char *)Map);
	return (e);
}

u_long
setorientation(tif, h)
	TIFF *tif;
	u_long h;
{
	u_long y;

	TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &orientation);
	switch (orientation) {
	case ORIENTATION_BOTRIGHT:
	case ORIENTATION_RIGHTBOT:	/* XXX */
	case ORIENTATION_LEFTBOT:	/* XXX */
		TIFFWarning(filename, "using bottom-left orientation");
		orientation = ORIENTATION_BOTLEFT;
		/* fall thru... */
	case ORIENTATION_BOTLEFT:
		y = 0;
		break;
	case ORIENTATION_TOPRIGHT:
	case ORIENTATION_RIGHTTOP:	/* XXX */
	case ORIENTATION_LEFTTOP:	/* XXX */
	default:
		TIFFWarning(filename, "using top-left orientation");
		orientation = ORIENTATION_TOPLEFT;
		/* fall thru... */
	case ORIENTATION_TOPLEFT:
		y = h-1;
		break;
	}
	return (y);
}

#if USE_PROTOTYPES
typedef void (*tileContigRoutine)
    (u_long*, u_char*, RGBvalue*, u_long, u_long, int, int);
static tileContigRoutine pickTileContigCase(RGBvalue*);
#else
typedef void (*tileContigRoutine)();
static tileContigRoutine pickTileContigCase();
#endif

/*
 * Get an tile-organized image that has
 *	PlanarConfiguration contiguous if SamplesPerPixel > 1
 * or
 *	SamplesPerPixel == 1
 */	
static
gtTileContig(tif, raster, Map, h, w)
	TIFF *tif;
	u_long *raster;
	RGBvalue *Map;
	u_long h, w;
{
	u_long col, row, y;
	u_long tw, th;
	u_char *buf;
	int fromskew, toskew;
	u_int nrow;
	tileContigRoutine put;

	put = pickTileContigCase(Map);
	if (put == 0)
		return (0);
	buf = (u_char *)malloc(TIFFTileSize(tif));
	if (buf == 0) {
		TIFFError(filename, "No space for tile buffer");
		return (0);
	}
	TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
	TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
	y = setorientation(tif, h);
	toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
	for (row = 0; row < h; row += th) {
		nrow = (row + th > h ? h - row : th);
		for (col = 0; col < w; col += tw) {
			if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0 &&
			    stoponerr)
				break;
			if (col + tw > w) {
				/*
				 * Tile is clipped horizontally.  Calculate
				 * visible portion and skewing factors.
				 */
				u_long npix = w - col;
				fromskew = tw - npix;
				(*put)(raster + y*w + col, buf, Map,
				    npix, nrow, fromskew, toskew + fromskew);
			} else
				(*put)(raster + y*w + col, buf, Map,
				    tw, nrow, 0, toskew);
		}
		y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
	}
	free(buf);
	return (1);
}

#if USE_PROTOTYPES
typedef void (*tileSeparateRoutine)
    (u_long*, u_char*, u_char*, u_char*, RGBvalue*, u_long, u_long, int, int);
static tileSeparateRoutine pickTileSeparateCase(RGBvalue*);
#else
typedef void (*tileSeparateRoutine)();
static tileSeparateRoutine pickTileSeparateCase();
#endif

/*
 * Get an tile-organized image that has
 *	 SamplesPerPixel > 1
 *	 PlanarConfiguration separated
 * We assume that all such images are RGB.
 */	
static
gtTileSeparate(tif, raster, Map, h, w)
	TIFF *tif;
	u_long *raster;
	RGBvalue *Map;
	u_long h, w;
{
	u_long col, row, y;
	u_long tw, th;
	u_char *buf;
	u_char *r, *g, *b;
	int tilesize;
	int fromskew, toskew;
	u_int nrow;
	tileSeparateRoutine put;

	put = pickTileSeparateCase(Map);
	if (put == 0)
		return (0);
	tilesize = TIFFTileSize(tif);
	buf = (u_char *)malloc(3*tilesize);
	if (buf == 0) {
		TIFFError(filename, "No space for tile buffer");
		return (0);
	}
	r = buf;
	g = r + tilesize;
	b = g + tilesize;
	TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
	TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
	y = setorientation(tif, h);
	toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
	for (row = 0; row < h; row += th) {
		nrow = (row + th > h ? h - row : th);
		for (col = 0; col < w; col += tw) {
			if (TIFFReadTile(tif, r, col, row,0,0) < 0 && stoponerr)
				break;
			if (TIFFReadTile(tif, g, col, row,0,1) < 0 && stoponerr)
				break;
			if (TIFFReadTile(tif, b, col, row,0,2) < 0 && stoponerr)
				break;
			if (col + tw > w) {
				/*
				 * Tile is clipped horizontally.  Calculate
				 * visible portion and skewing factors.
				 */
				u_long npix = w - col;
				fromskew = tw - npix;
				(*put)(raster + y*w + col, r, g, b, Map,
				    npix, nrow, fromskew, toskew + fromskew);
			} else
				(*put)(raster + y*w + col, r, g, b, Map,
				    tw, nrow, 0, toskew);
		}
		y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
	}
	free(buf);
	return (1);
}

/*
 * Get a strip-organized image that has
 *	PlanarConfiguration contiguous if SamplesPerPixel > 1
 * or
 *	SamplesPerPixel == 1
 */	
static
gtStripContig(tif, raster, Map, h, w)
	TIFF *tif;
	u_long *raster;
	RGBvalue *Map;
	u_long h, w;
{
	u_long row, y, nrow;
	u_char *buf;
	tileContigRoutine put;
	u_long rowsperstrip;
	u_long imagewidth;
	int scanline;
	int fromskew, toskew;

	put = pickTileContigCase(Map);
	if (put == 0)
		return (0);
	buf = (u_char *)malloc(TIFFStripSize(tif));
	if (buf == 0) {
		TIFFError(filename, "No space for strip buffer");
		return (0);
	}
	y = setorientation(tif, h);
	toskew = (orientation == ORIENTATION_TOPLEFT ? -w + -w : -w + w);
	TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
	TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
	scanline = TIFFScanlineSize(tif);
	fromskew = (w < imagewidth ? imagewidth - w : 0);
	for (row = 0; row < h; row += rowsperstrip) {
		nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
		if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
		    buf, nrow*scanline) < 0 && stoponerr)
			break;
		(*put)(raster + y*w, buf, Map, w, nrow, fromskew, toskew);
		y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
	}
	free(buf);
	return (1);
}

/*
 * Get a strip-organized image with
 *	 SamplesPerPixel > 1
 *	 PlanarConfiguration separated
 * We assume that all such images are RGB.
 */
static
gtStripSeparate(tif, raster, Map, h, w)
	TIFF *tif;
	u_long *raster;
	register RGBvalue *Map;
	u_long h, w;
{
	u_char *buf;
	u_char *r, *g, *b;
	u_long row, y, nrow;
	int scanline;
	tileSeparateRoutine put;
	u_long rowsperstrip;
	u_long imagewidth;
	u_int stripsize;
	int fromskew, toskew;

	stripsize = TIFFStripSize(tif);
	r = buf = (u_char *)malloc(3*stripsize);
	if (buf == 0)
		return (0);
	g = r + stripsize;
	b = g + stripsize;
	put = pickTileSeparateCase(Map);
	if (put == 0) {
		TIFFError(filename, "Can not handle format");
		return (0);
	}
	y = setorientation(tif, h);
	toskew = (orientation == ORIENTATION_TOPLEFT ? -w + -w : -w + w);
	TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
	TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
	scanline = TIFFScanlineSize(tif);
	fromskew = (w < imagewidth ? imagewidth - w : 0);
	for (row = 0; row < h; row += rowsperstrip) {
		nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
		if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
		    r, nrow*scanline) < 0 && stoponerr)
			break;
		if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 1),
		    g, nrow*scanline) < 0 && stoponerr)
			break;
		if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 2),
		    b, nrow*scanline) < 0 && stoponerr)
			break;
		(*put)(raster + y*w, r, g, b, Map, w, nrow, fromskew, toskew);
		y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
	}
	free(buf);
	return (1);
}

#define	PACK(r,g,b)	((u_long)(r)|((u_long)(g)<<8)|((u_long)(b)<<16))

/*
 * Greyscale images with less than 8 bits/sample are handled
 * with a table to avoid lots of shifts and masks.  The table
 * is setup so that put*bwtile (below) can retrieve 8/bitspersample
 * pixel values simply by indexing into the table with one
 * number.
 */
makebwmap(Map)
	RGBvalue *Map;
{
	register int i;
	int nsamples = 8 / bitspersample;
	register u_long *p;

	BWmap = (u_long **)malloc(
	    256*sizeof (u_long *)+(256*nsamples*sizeof(u_long)));
	if (BWmap == NULL) {
		TIFFError(filename, "No space for B&W mapping table");
		return (0);
	}
	p = (u_long *)(BWmap + 256);
	for (i = 0; i < 256; i++) {
		BWmap[i] = p;
		switch (bitspersample) {
			register RGBvalue c;
#define	GREY(x)	c = Map[x]; *p++ = PACK(c,c,c);
		case 1:
			GREY(i>>7);
			GREY((i>>6)&1);
			GREY((i>>5)&1);
			GREY((i>>4)&1);
			GREY((i>>3)&1);
			GREY((i>>2)&1);
			GREY((i>>1)&1);
			GREY(i&1);
			break;
		case 2:
			GREY(i>>6);
			GREY((i>>4)&3);
			GREY((i>>2)&3);
			GREY(i&3);
			break;
		case 4:
			GREY(i>>4);
			GREY(i&0xf);
			break;
		case 8:
			GREY(i);
			break;
		}
#undef	GREY
	}
	return (1);
}

/*
 * Palette images with <= 8 bits/sample are handled
 * with a table to avoid lots of shifts and masks.  The table
 * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
 * pixel values simply by indexing into the table with one
 * number.
 */
makecmap(rmap, gmap, bmap)
	u_short *rmap, *gmap, *bmap;
{
	register int i;
	int nsamples = 8 / bitspersample;
	register u_long *p;

	PALmap = (u_long **)malloc(
	    256*sizeof (u_long *)+(256*nsamples*sizeof(u_long)));
	if (PALmap == NULL) {
		TIFFError(filename, "No space for Palette mapping table");
		return (0);
	}
	p = (u_long *)(PALmap + 256);
	for (i = 0; i < 256; i++) {
		PALmap[i] = p;
#define	CMAP(x)	\
c = x; *p++ = PACK(rmap[c]&0xff, gmap[c]&0xff, bmap[c]&0xff);
		switch (bitspersample) {
			register RGBvalue c;
		case 1:
			CMAP(i>>7);
			CMAP((i>>6)&1);
			CMAP((i>>5)&1);
			CMAP((i>>4)&1);
			CMAP((i>>3)&1);
			CMAP((i>>2)&1);
			CMAP((i>>1)&1);
			CMAP(i&1);
			break;
		case 2:
			CMAP(i>>6);
			CMAP((i>>4)&3);
			CMAP((i>>2)&3);
			CMAP(i&3);
			break;
		case 4:
			CMAP(i>>4);
			CMAP(i&0xf);
			break;
		case 8:
			CMAP(i);
			break;
		}
#undef CMAP
	}
	return (1);
}

/*
 * The following routines move decoded data returned
 * from the TIFF library into rasters filled with packed
 * ABGR pixels (i.e. suitable for passing to lrecwrite.)
 *
 * The routines have been created according to the most
 * important cases and optimized.  pickTileContigCase and
 * pickTileSeparateCase analyze the parameters and select
 * the appropriate "put" routine to use.
 */
#define	REPEAT8(op)	REPEAT4(op); REPEAT4(op)
#define	REPEAT4(op)	REPEAT2(op); REPEAT2(op)
#define	REPEAT2(op)	op; op
#define	CASE8(x,op)				\
	switch (x) {				\
	case 7: op; case 6: op; case 5: op;	\
	case 4: op; case 3: op; case 2: op;	\
	case 1: op;				\
	}
#define	CASE4(x,op)	switch (x) { case 3: op; case 2: op; case 1: op; }

#define	UNROLL8(w, op1, op2) {		\
	register u_long x;		\
	for (x = w; x >= 8; x -= 8) {	\
		op1;			\
		REPEAT8(op2);		\
	}				\
	if (x > 0) {			\
		op1;			\
		CASE8(x,op2);		\
	}				\
}
#define	UNROLL4(w, op1, op2) {		\
	register u_long x;		\
	for (x = w; x >= 4; x -= 4) {	\
		op1;			\
		REPEAT4(op2);		\
	}				\
	if (x > 0) {			\
		op1;			\
		CASE4(x,op2);		\
	}				\
}
#define	UNROLL2(w, op1, op2) {		\
	register u_long x;		\
	for (x = w; x >= 2; x -= 2) {	\
		op1;			\
		REPEAT2(op2);		\
	}				\
	if (x) {			\
		op1;			\
		op2;			\
	}				\
}
			

#define	SKEW(r,g,b,skew)	{ r += skew; g += skew; b += skew; }

/*
 * 8-bit palette => colormap/RGB
 */
static void
put8bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
	register u_long *cp;
	register u_char *pp;
	RGBvalue *Map;
	u_long w, h;
	int fromskew, toskew;
{
	while (h-- > 0) {
		UNROLL8(w,, *cp++ = PALmap[*pp++][0]);
		cp += toskew;
		pp += fromskew;
	}
}

/*
 * 4-bit palette => colormap/RGB
 */
static void
put4bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
	register u_long *cp;
	register u_char *pp;
	register RGBvalue *Map;
	u_long w, h;
	int fromskew, toskew;
{
	register u_long *bw;

	fromskew /= 2;
	while (h-- > 0) {
		UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
		cp += toskew;
		pp += fromskew;
	}
}

/*
 * 2-bit palette => colormap/RGB
 */
static void
put2bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
	register u_long *cp;
	register u_char *pp;
	register RGBvalue *Map;
	u_long w, h;
	int fromskew, toskew;
{
	register u_long *bw;

	fromskew /= 4;
	while (h-- > 0) {
		UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
		cp += toskew;
		pp += fromskew;
	}
}

/*
 * 1-bit palette => colormap/RGB
 */
static void
put1bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
	register u_long *cp;
	register u_char *pp;
	register RGBvalue *Map;
	u_long w, h;
	int fromskew, toskew;
{
	register u_long *bw;

	fromskew /= 8;
	while (h-- > 0) {
		UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
		cp += toskew;
		pp += fromskew;
	}
}

/*
 * 8-bit greyscale => colormap/RGB
 */
static void
putgreytile(cp, pp, Map, w, h, fromskew, toskew)
	register u_long *cp;
	register u_char *pp;
	RGBvalue *Map;
	u_long w, h;
	int fromskew, toskew;
{
	while (h-- > 0) {
		register u_long x;
		for (x = w; x-- > 0;)
			*cp++ = BWmap[*pp++][0];
		cp += toskew;
		pp += fromskew;
	}
}

/*
 * 1-bit bilevel => colormap/RGB
 */
static void
put1bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
	u_long *cp;
	u_char *pp;
	RGBvalue *Map;
	u_long w, h;
	int fromskew, toskew;
{
	register u_long *bw;

	fromskew /= 8;
	while (h-- > 0) {
		UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
		cp += toskew;
		pp += fromskew;
	}
}

/*
 * 2-bit greyscale => colormap/RGB
 */
static void
put2bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
	u_long *cp;
	u_char *pp;
	RGBvalue *Map;
	u_long w, h;
	int fromskew, toskew;
{
	register u_long *bw;

	fromskew /= 4;
	while (h-- > 0) {
		UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
		cp += toskew;
		pp += fromskew;
	}
}

/*
 * 4-bit greyscale => colormap/RGB
 */
static void
put4bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
	u_long *cp;
	u_char *pp;
	RGBvalue *Map;
	u_long w, h;
	int fromskew, toskew;
{
	register u_long *bw;

	fromskew /= 2;
	while (h-- > 0) {
		UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
		cp += toskew;
		pp += fromskew;
	}
}

/*
 * 8-bit packed samples => RGB
 */
static void
putRGBcontig8bittile(cp, pp, Map, w, h, fromskew, toskew)
	register u_long *cp;
	register u_char *pp;
	register RGBvalue *Map;
	u_long w, h;
	int fromskew, toskew;
{
	fromskew *= samplesperpixel;
	if (Map) {
		while (h-- > 0) {
			register u_long x;
			for (x = w; x-- > 0;) {
				*cp++ = PACK(Map[pp[0]], Map[pp[1]], Map[pp[2]]);
				pp += samplesperpixel;
			}
			pp += fromskew;
			cp += toskew;
		}
	} else {
		while (h-- > 0) {
			UNROLL8(w,,
			    *cp++ = PACK(pp[0], pp[1], pp[2]);
			    pp += samplesperpixel);
			cp += toskew;
			pp += fromskew;
		}
	}
}

/*
 * 16-bit packed samples => RGB
 */
static void
putRGBcontig16bittile(cp, pp, Map, w, h, fromskew, toskew)
	register u_long *cp;
	u_char *pp;
	register RGBvalue *Map;
	u_long w, h;
	int fromskew, toskew;
{
	register u_short *wp = (u_short *)pp;
	register u_int x;

	fromskew *= samplesperpixel;
	if (Map) {
		while (h-- > 0) {
			for (x = w; x-- > 0;) {
				*cp++ = PACK(Map[wp[0]], Map[wp[1]], Map[wp[2]]);
				wp += samplesperpixel;
			}
			cp += toskew;
			wp += fromskew;
		}
	} else {
		while (h-- > 0) {
			for (x = w; x-- > 0;) {
				*cp++ = PACK(wp[0], wp[1], wp[2]);
				wp += samplesperpixel;
			}
			cp += toskew;
			wp += fromskew;
		}
	}
}

/*
 * 8-bit unpacked samples => RGB
 */
static void
putRGBseparate8bittile(cp, r, g, b, Map, w, h, fromskew, toskew)
	register u_long *cp;
	register u_char *r, *g, *b;
	register RGBvalue *Map;
	u_long w, h;
	int fromskew, toskew;

{
	if (Map) {
		while (h-- > 0) {
			register u_long x;
			for (x = w; x > 0; x--)
				*cp++ = PACK(Map[*r++], Map[*g++], Map[*b++]);
			SKEW(r, g, b, fromskew);
			cp += toskew;
		}
	} else {
		while (h-- > 0) {
			UNROLL8(w,, *cp++ = PACK(*r++, *g++, *b++));
			SKEW(r, g, b, fromskew);
			cp += toskew;
		}
	}
}

/*
 * 16-bit unpacked samples => RGB
 */
static void
putRGBseparate16bittile(cp, br, bg, bb, Map, w, h, fromskew, toskew)
	register u_long *cp;
	u_char *br, *bg, *bb;
	register RGBvalue *Map;
	u_long w, h;
	int fromskew, toskew;
{
	register u_short *r = (u_short *)br;
	register u_short *g = (u_short *)bg;
	register u_short *b = (u_short *)bb;
	register u_long x;

	if (Map) {
		while (h-- > 0) {
			for (x = w; x > 0; x--)
				*cp++ = PACK(Map[*r++], Map[*g++], Map[*b++]);
			SKEW(r, g, b, fromskew);
			cp += toskew;
		}
	} else {
		while (h-- > 0) {
			for (x = 0; x < w; x++)
				*cp++ = PACK(*r++, *g++, *b++);
			SKEW(r, g, b, fromskew);
			cp += toskew;
		}
	}
}

#define	Code2V(c, RB, RW, CR)	((((c)-RB)*(float)CR)/(float)(RW-RB))
#define	CLAMP(f,min,max) \
    (int)((f)+.5 < (min) ? (min) : (f)+.5 > (max) ? (max) : (f)+.5)

#define	LumaRed		YCbCrCoeffs[0]
#define	LumaGreen	YCbCrCoeffs[1]
#define	LumaBlue	YCbCrCoeffs[2]

static	float D1, D2;
static	float D3, D4;

static void
initYCbCrConversion()
{
	D1 = 2 - 2*LumaRed;
	D2 = D1*LumaRed / LumaGreen;
	D3 = 2 - 2*LumaBlue;
	D4 = D2*LumaBlue / LumaGreen;
}

static void
putRGBContigYCbCrClump(cp, pp, cw, ch, w, n, fromskew, toskew)
	register u_long *cp;
	register u_char *pp;
	int cw, ch;
	u_long w;
	int n, fromskew, toskew;
{
	float Cb, Cr;
	int j, k;

	Cb = Code2V(pp[n],   refBlackWhite[2], refBlackWhite[3], 127);
	Cr = Code2V(pp[n+1], refBlackWhite[4], refBlackWhite[5], 127);
	for (j = 0; j < ch; j++) {
		for (k = 0; k < cw; k++) {
			float Y, R, G, B;
			Y = Code2V(*pp++,
			    refBlackWhite[0], refBlackWhite[1], 255);
			R = Y + Cr*D1;
			B = Y + Cb*D3;
			G = Y - Cb*D4 - Cr*D2;
			cp[k] = PACK(CLAMP(R,0,255),
				     CLAMP(G,0,255),
				     CLAMP(B,0,255));
		}
		cp += w+toskew;
		pp += fromskew;
	}
}
#undef LumaBlue
#undef LumaGreen
#undef LumaRed
#undef CLAMP
#undef Code2V

/*
 * 8-bit packed YCbCr samples => RGB
 */
static void
putcontig8bitYCbCrtile(cp, pp, Map, w, h, fromskew, toskew)
	register u_long *cp;
	register u_char *pp;
	register RGBvalue *Map;
	u_long w, h;
	int fromskew, toskew;
{
	u_int Coff = YCbCrVertSampling * YCbCrHorizSampling;
	u_long *tp;
	u_long x;

	/* XXX adjust fromskew */
	while (h >= YCbCrVertSampling) {
		tp = cp;
		for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
			putRGBContigYCbCrClump(tp, pp,
			    YCbCrHorizSampling, YCbCrVertSampling,
			    w, Coff, 0, toskew);
			tp += YCbCrHorizSampling;
			pp += Coff+2;
		}
		if (x > 0) {
			putRGBContigYCbCrClump(tp, pp,
			    x, YCbCrVertSampling,
			    w, Coff, YCbCrHorizSampling - x, toskew);
			pp += Coff+2;
		}
		cp += YCbCrVertSampling*(w + toskew);
		pp += fromskew;
		h -= YCbCrVertSampling;
	}
	if (h > 0) {
		tp = cp;
		for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
			putRGBContigYCbCrClump(tp, pp, YCbCrHorizSampling, h,
			    w, Coff, 0, toskew);
			tp += YCbCrHorizSampling;
			pp += Coff+2;
		}
		if (x > 0)
			putRGBContigYCbCrClump(tp, pp, x, h,
			    w, Coff, YCbCrHorizSampling - x, toskew);
	}
}

/*
 * Select the appropriate conversion routine for packed data.
 */
static tileContigRoutine
DECLARE1(pickTileContigCase, RGBvalue*, Map)
{
	tileContigRoutine put = 0;

	switch (photometric) {
	case PHOTOMETRIC_RGB:
		put = (bitspersample == 8 ?
		    putRGBcontig8bittile : putRGBcontig16bittile);
		break;
	case PHOTOMETRIC_PALETTE:
		switch (bitspersample) {
		case 8:	put = put8bitcmaptile; break;
		case 4: put = put4bitcmaptile; break;
		case 2: put = put2bitcmaptile; break;
		case 1: put = put1bitcmaptile; break;
		}
		break;
	case PHOTOMETRIC_MINISWHITE:
	case PHOTOMETRIC_MINISBLACK:
		switch (bitspersample) {
		case 8:	put = putgreytile; break;
		case 4: put = put4bitbwtile; break;
		case 2: put = put2bitbwtile; break;
		case 1: put = put1bitbwtile; break;
		}
		break;
	case PHOTOMETRIC_YCBCR:
		switch (bitspersample) {
		case 8: put = putcontig8bitYCbCrtile; break;
		}
		break;
	}
	if (put == 0)
		TIFFError(filename, "Can not handle format");
	return (put);
}

/*
 * Select the appropriate conversion routine for unpacked data.
 *
 * NB: we assume that unpacked single channel data is directed
 *	 to the "packed routines.
 */
static tileSeparateRoutine
DECLARE1(pickTileSeparateCase, RGBvalue*, Map)
{
	tileSeparateRoutine put = 0;

	switch (photometric) {
	case PHOTOMETRIC_RGB:
		put = (bitspersample == 8 ?
		    putRGBseparate8bittile : putRGBseparate16bittile);
		break;
	}
	if (put == 0)
		TIFFError(filename, "Can not handle format");
	return (put);
}
