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

/*
 * Copyright (c) 1990, 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.
 *
 * CCITT Group 3 and Group 4 Compression Support.
 */
#include "tiffioP.h"
#include <stdio.h>
#include <assert.h>
#include "tif_fax3.h"
#define	G3CODES
#include "t4.h"
#define	G3STATES
#include "g3states.h"

typedef struct {
	Fax3BaseState b;
} Fax3DecodeState;

typedef struct {
	Fax3BaseState b;
	u_char	*wruns;
	u_char	*bruns;
	short	k;			/* #rows left that can be 2d encoded */
	short	maxk;			/* max #rows that can be 2d encoded */
} Fax3EncodeState;

#if USE_PROTOTYPES
static	Fax3PreDecode(TIFF *);
static	Fax3Decode(TIFF*, u_char *, int, u_int);
static	int Fax3Decode1DRow(TIFF*, u_char *, int);
static	Fax3PreEncode(TIFF *);
static	Fax3PostEncode(TIFF *);
static	Fax3Encode(TIFF*, u_char *, int, u_int);
static	int Fax3Encode1DRow(TIFF *, u_char *, int);
static	Fax3Close(TIFF *);
static	Fax3Cleanup(TIFF *);
static	void *Fax3SetupState(TIFF *, int);
static	void fillspan(char *, int, int);
static	int findspan(u_char **, int, int, u_char const *);
static	int finddiff(u_char *, int, int, int);
static	void skiptoeol(TIFF *, int);
static	void putbits(TIFF *, u_int, u_int);
static	void putcode(TIFF *, tableentry const *);
static	void putspan(TIFF *, int, tableentry const *);
extern	int TIFFFlushData1(TIFF *);
#else
static	int Fax3PreEncode(), Fax3Encode(), Fax3PostEncode();
static	int Fax3Encode1DRow();
static	int Fax3Decode(), Fax3PreDecode();
static	int Fax3Decode1DRow();
static	int Fax3Close(), Fax3Cleanup();
static	void *Fax3SetupState();
static	void fillspan();
static	int findspan();
static	int finddiff();
static	void skiptoeol();
static	void putbits();
static	void putcode();
static	void putspan();
extern	int TIFFFlushData1();
#endif

TIFFInitCCITTFax3(tif)
	TIFF *tif;
{
	tif->tif_predecode = Fax3PreDecode;
	tif->tif_decoderow = Fax3Decode;
	tif->tif_decodestrip = Fax3Decode;
	tif->tif_decodetile = Fax3Decode;
	tif->tif_preencode = Fax3PreEncode;
	tif->tif_postencode = Fax3PostEncode;
	tif->tif_encoderow = Fax3Encode;
	tif->tif_encodestrip = Fax3Encode;
	tif->tif_encodetile = Fax3Encode;
	tif->tif_close = Fax3Close;
	tif->tif_cleanup = Fax3Cleanup;
	tif->tif_options |= FAX3_CLASSF;	/* default */
	tif->tif_flags |= TIFF_NOBITREV;	/* we handle bit reversal */
	return (1);
}

TIFFModeCCITTFax3(tif, isClassF)
	TIFF *tif;
	int isClassF;
{
	if (isClassF)
		tif->tif_options |= FAX3_CLASSF;
	else
		tif->tif_options &= ~FAX3_CLASSF;
}

static u_char bitMask[8] =
    { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
#define	isBitSet(sp)	((sp)->b.data & bitMask[(sp)->b.bit])

#define	is2DEncoding(tif) \
	(tif->tif_dir.td_group3options & GROUP3OPT_2DENCODING)
#define	fetchByte(tif, sp) \
	((tif)->tif_rawcc--, (sp)->b.bitmap[*(u_char *)(tif)->tif_rawcp++])

#define	BITCASE(b)			\
    case b:				\
	code <<= 1;			\
	if (data & (1<<(7-b))) code |= 1;\
	len++;				\
	if (code > 0) { bit = b+1; break; }

/*
 * Skip over input until an EOL code is found.  The
 * value of len is passed as 0 except during error
 * recovery when decoding 2D data.  Note also that
 * we don't use the optimized state tables to locate
 * an EOL because we can't assume much of anything
 * about our state (e.g. bit position).
 */
static void
skiptoeol(tif, len)
	TIFF *tif;
	int len;
{
	Fax3DecodeState *sp = (Fax3DecodeState *)tif->tif_data;
	register int bit = sp->b.bit;
	register int data = sp->b.data;
	int code = 0;

	/*
	 * Our handling of ``bit'' is painful because
	 * the rest of the code does not maintain it as
	 * exactly the bit offset in the current data
	 * byte (bit == 0 means refill the data byte).
	 * Thus we have to be careful on entry and
	 * exit to insure that we maintain a value that's
	 * understandable elsewhere in the decoding logic.
	 */
	if (bit == 0)			/* force refill */
		bit = 8;
	for (;;) {
		switch (bit) {
	again:	BITCASE(0);
		BITCASE(1);
		BITCASE(2);
		BITCASE(3);
		BITCASE(4);
		BITCASE(5);
		BITCASE(6);
		BITCASE(7);
		default:
			if (tif->tif_rawcc <= 0)
				return;
			data = fetchByte(tif, sp);
			goto again;
		}
		if (len >= 12 && code == EOL)
			break;
		code = len = 0;
	}
	sp->b.bit = bit > 7 ? 0 : bit;	/* force refill */
	sp->b.data = data;
}

/*
 * Return the next bit in the input stream.  This is
 * used to extract 2D tag values and the color tag
 * at the end of a terminating uncompressed data code.
 */
static int
nextbit(tif)
	TIFF *tif;
{
	Fax3DecodeState *sp = (Fax3DecodeState *)tif->tif_data;
	int bit;

	if (sp->b.bit == 0 && tif->tif_rawcc > 0)
		sp->b.data = fetchByte(tif, sp);
	bit = isBitSet(sp);
	if (++(sp->b.bit) > 7)
		sp->b.bit = 0;
	return (bit);
}

static void
bset(cp, n, v)
	register unsigned char *cp;
	register int n;
	register int v;
{
	while (n-- > 0)
		*cp++ = v;
}

/*
 * Setup G3-related compression/decompression
 * state before data is processed.  This routine
 * is called once per image -- it sets up different
 * state based on whether or not 2D encoding is used.
 */
static void *
Fax3SetupState(tif, space)
	TIFF *tif;
	int space;
{
	TIFFDirectory *td = &tif->tif_dir;
	Fax3BaseState *sp;
	int cc = space;
	long rowbytes, rowpixels;

	if (td->td_bitspersample != 1) {
		TIFFError(tif->tif_name,
		    "Bits/sample must be 1 for Group 3/4 encoding/decoding");
		return (0);
	}
	/*
	 * Calculate the scanline/tile widths.
	 */
	if (isTiled(tif)) {
		rowbytes = TIFFTileRowSize(tif);
		rowpixels = tif->tif_dir.td_tilewidth;
	} else {
		rowbytes = TIFFScanlineSize(tif);
		rowpixels = tif->tif_dir.td_imagewidth;
	}
	if (is2DEncoding(tif) || td->td_compression == COMPRESSION_CCITTFAX4)
		cc += rowbytes+1;
	tif->tif_data = malloc(cc);
	if (tif->tif_data == NULL) {
		TIFFError("Fax3SetupState",
		    "%s: No space for Fax3 state block", tif->tif_name);
		return (0);
	}
	sp = (Fax3BaseState *)tif->tif_data;
	sp->rowbytes = rowbytes;
	sp->rowpixels = rowpixels;
	sp->bitmap = (tif->tif_fillorder != td->td_fillorder ? 
	    TIFFBitRevTable : TIFFNoBitRevTable);
	sp->white = (td->td_photometric == PHOTOMETRIC_MINISBLACK);
	if (is2DEncoding(tif) || td->td_compression == COMPRESSION_CCITTFAX4) {
		/*
		 * 2d encoding/decoding requires a scanline
		 * buffer for the ``reference line''; the
		 * scanline against which delta encoding
		 * is referenced.  The reference line must
		 * be initialized to be ``white'' (done elsewhere).
		 */
		sp->refline = (u_char *)tif->tif_data + space + 1;
		/*
		 * Initialize pixel just to the left of the
		 * reference line to white.  This extra pixel
		 * simplifies the edge-condition logic.
		 */
		sp->refline[-1] = sp->white ? 0xff : 0x00;
	} else
		sp->refline = 0;
	return (sp);
}

/*
 * Setup state for decoding a strip.
 */
static
Fax3PreDecode(tif)
	TIFF *tif;
{
	Fax3DecodeState *sp = (Fax3DecodeState *)tif->tif_data;

	if (sp == NULL) {
		sp = (Fax3DecodeState *)Fax3SetupState(tif, sizeof (*sp));
		if (!sp)
			return (0);
	}
	sp->b.bit = 0;			/* force initial read */
	sp->b.data = 0;
	sp->b.tag = G3_1D;
	if (sp->b.refline)
		bset(sp->b.refline, sp->b.rowbytes, sp->b.white ? 0xff : 0x00);
	/*
	 * If image has EOL codes, they precede each line
	 * of data.  We skip over the first one here so that
	 * when we decode rows, we can use an EOL to signal
	 * that less than the expected number of pixels are
	 * present for the scanline.
	 */
	if ((tif->tif_options & FAX3_NOEOL) == 0) {
		skiptoeol(tif, 0);
		if (is2DEncoding(tif))
			/* tag should always be 1D! */
			sp->b.tag = nextbit(tif) ? G3_1D : G3_2D;
	}
	return (1);
}

/*
 * Fill a span with ones.
 */
static void
fillspan(cp, x, count)
	register char *cp;
	register int x, count;
{
	static const unsigned char masks[] =
	    { 0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };

	if (count <= 0)
		return;
	cp += x>>3;
	if (x &= 7) {			/* align to byte boundary */
		if (count < 8 - x) {
			*cp++ |= masks[count] >> x;
			return;
		}
		*cp++ |= 0xff >> x;
		count -= 8 - x;
	}
	while (count >= 8) {
		*cp++ = 0xff;
		count -= 8;
	}
	*cp |= masks[count];
}

/*
 * Decode the requested amount of data.
 */
static
Fax3Decode(tif, buf, occ, s)
	TIFF *tif;
	u_char *buf;
	int occ;
	u_int s;
{
	Fax3DecodeState *sp = (Fax3DecodeState *)tif->tif_data;

	bzero(buf, occ);		/* decoding only sets non-zero bits */
	while (occ > 0) {
		if (sp->b.tag == G3_1D) {
			if (!Fax3Decode1DRow(tif, buf, sp->b.rowpixels))
				return (0);
		} else {
			if (!Fax3Decode2DRow(tif, buf, sp->b.rowpixels))
				return (0);
		}
		if (is2DEncoding(tif)) {
			/*
			 * Fetch the tag bit that indicates
			 * whether the next row is 1d or 2d
			 * encoded.  If 2d-encoded, then setup
			 * the reference line from the decoded
			 * scanline just completed.
			 */
			sp->b.tag = nextbit(tif) ? G3_1D : G3_2D;
			if (sp->b.tag == G3_2D)
				bcopy(buf, sp->b.refline, sp->b.rowbytes);
		}
		buf += sp->b.rowbytes;
		occ -= sp->b.rowbytes;
	}
	return (1);
}

/*
 * Decode a run of white.
 */
static int
decode_white_run(tif)
	TIFF *tif;
{
	Fax3DecodeState *sp = (Fax3DecodeState *)tif->tif_data;
	short state = sp->b.bit;
	short action;
	int runlen = 0;

	for (;;) {
		if (sp->b.bit == 0) {
	nextbyte:
			if (tif->tif_rawcc <= 0)
				return (G3CODE_EOF);
			sp->b.data = fetchByte(tif, sp);
		}
		action = TIFFFax1DAction[state][sp->b.data];
		state = TIFFFax1DNextState[state][sp->b.data];
		if (action == ACT_INCOMP)
			goto nextbyte;
		if (action == ACT_INVALID)
			return (G3CODE_INVALID);
		if (action == ACT_EOL)
			return (G3CODE_EOL);
		sp->b.bit = state;
		action = RUNLENGTH(action - ACT_WRUNT);
		runlen += action;
		if (action < 64)
			return (runlen);
	}
	/*NOTREACHED*/
}

/*
 * Decode a run of black.
 */
static int
decode_black_run(tif)
	TIFF *tif;
{
	Fax3DecodeState *sp = (Fax3DecodeState *)tif->tif_data;
	short state = sp->b.bit + 8;
	short action;
	int runlen = 0;

	for (;;) {
		if (sp->b.bit == 0) {
	nextbyte:
			if (tif->tif_rawcc <= 0)
				return (G3CODE_EOF);
			sp->b.data = fetchByte(tif, sp);
		}
		action = TIFFFax1DAction[state][sp->b.data];
		state = TIFFFax1DNextState[state][sp->b.data];
		if (action == ACT_INCOMP)
			goto nextbyte;
		if (action == ACT_INVALID)
			return (G3CODE_INVALID);
		if (action == ACT_EOL)
			return (G3CODE_EOL);
		sp->b.bit = state;
		action = RUNLENGTH(action - ACT_BRUNT);
		runlen += action;
		if (action < 64)
			return (runlen);
		state += 8;
	}
	/*NOTREACHED*/
}

/*
 * Process one row of 1d Huffman-encoded data.
 */
static int
Fax3Decode1DRow(tif, buf, npels)
	TIFF *tif;
	u_char *buf;
	int npels;
{
	Fax3DecodeState *sp = (Fax3DecodeState *)tif->tif_data;
	int x = 0;
	int runlen;
	short action;
	short color = sp->b.white;
	static char module[] = "Fax3Decode1D";

	for (;;) {
		if (color == sp->b.white)
			runlen = decode_white_run(tif);
		else
			runlen = decode_black_run(tif);
		switch (runlen) {
		case G3CODE_EOF:
			TIFFError(module,
			    "%s: Premature EOF at scanline %d (x %d)",
			    tif->tif_name, tif->tif_row, x);
			return (0);
		case G3CODE_INVALID:	/* invalid code */
			/*
			 * An invalid code was encountered.
			 * Flush the remainder of the line
			 * and allow the caller to decide whether
			 * or not to continue.  Note that this
			 * only works if we have a G3 image
			 * with EOL markers.
			 */
			TIFFError(module,
			   "%s: Bad code word at scanline %d (x %d)",
			   tif->tif_name, tif->tif_row, x);
			goto done;
		case G3CODE_EOL:	/* premature end-of-line code */
			TIFFWarning(module,
			    "%s: Premature EOL at scanline %d (x %d)",
			    tif->tif_name, tif->tif_row, x);
			return (1);	/* try to resynchronize... */
		}
		if (x+runlen > npels)
			runlen = npels-x;
		if (runlen > 0) {
			if (color)
				fillspan((char *)buf, x, runlen);
			x += runlen;
			if (x >= npels)
				break;
		}
		color = !color;
	}
done:
	/*
	 * Cleanup at the end of the row.  This convoluted
	 * logic is merely so that we can reuse the code with
	 * two other related compression algorithms (2 & 32771).
	 *
	 * Note also that our handling of word alignment assumes
	 * that the buffer is at least word aligned.  This is
	 * the case for most all versions of malloc (typically
	 * the buffer is returned longword aligned).
	 */
	if ((tif->tif_options & FAX3_NOEOL) == 0)
		skiptoeol(tif, 0);
	if (tif->tif_options & FAX3_BYTEALIGN)
		sp->b.bit = 0;
	if ((tif->tif_options & FAX3_WORDALIGN) && ((long)tif->tif_rawcp & 1))
		(void) fetchByte(tif, sp);
	return (x == npels);
}

/*
 * Group 3 2d Decoding support.
 */

/*
 * Return the next uncompressed mode code word.
 */
static int
decode_uncomp_code(tif)
	TIFF *tif;
{
	Fax3DecodeState *sp = (Fax3DecodeState *)tif->tif_data;
	short code;

	do {
		if (sp->b.bit == 0 || sp->b.bit > 7) {
			if (tif->tif_rawcc <= 0)
				return (UNCOMP_EOF);
			sp->b.data = fetchByte(tif, sp);
		}
		code = TIFFFaxUncompAction[sp->b.bit][sp->b.data];
		sp->b.bit = TIFFFaxUncompNextState[sp->b.bit][sp->b.data];
	} while (code == ACT_INCOMP);
	return (code);
}

/*
 * Process one row of 2d encoded data.
 */
int
Fax3Decode2DRow(tif, buf, npels)
	TIFF *tif;
	u_char *buf;
	int npels;
{
#define	PIXEL(buf,ix)	((((buf)[(ix)>>3]) >> (7-((ix)&7))) & 1)
	Fax3DecodeState *sp = (Fax3DecodeState *)tif->tif_data;
	int a0 = -1;
	int b1, b2;
	int run1, run2;		/* for horizontal mode */
	short mode;
	short color = sp->b.white;
	static char module[] = "Fax3Decode2D";

	do {
		if (sp->b.bit == 0 || sp->b.bit > 7) {
			if (tif->tif_rawcc <= 0) {
			    TIFFError(module,
				"%s: Premature EOF at scanline %d",
			        tif->tif_name, tif->tif_row);
			    return (0);
			}
			sp->b.data = fetchByte(tif, sp);
		}
		mode = TIFFFax2DMode[sp->b.bit][sp->b.data];
		sp->b.bit = TIFFFax2DNextState[sp->b.bit][sp->b.data];
		switch (mode) {
		case MODE_NULL:
			break;
		case MODE_PASS:
			b2 = finddiff(sp->b.refline, a0, npels, !color);
			b1 = finddiff(sp->b.refline, b2, npels, color);
			b2 = finddiff(sp->b.refline, b1, npels, !color);
			if (color) {
				if (a0 < 0)
					a0 = 0;
				fillspan((char *)buf, a0, b2 - a0);
			}
			a0 = b2;
			break;
		case MODE_HORIZ:
			if (color == sp->b.white) {
				run1 = decode_white_run(tif);
				run2 = decode_black_run(tif);
			} else {
				run1 = decode_black_run(tif);
				run2 = decode_white_run(tif);
			}
			/*
			 * Do the appropriate fill.  Note that we exit
			 * this logic with the same color that we enter
			 * with since we do 2 fills.  This explains the
			 * somewhat obscure logic below.
			 */
			if (a0 < 0)
				a0 = 0;
			if (a0 + run1 > npels)
				run1 = npels - a0;
			if (color)
				fillspan((char *)buf, a0, run1);
			a0 += run1;
			if (a0 + run2 > npels)
				run2 = npels - a0;
			if (!color)
				fillspan((char *)buf, a0, run2);
			a0 += run2;
			break;
		case MODE_VERT_V0:
		case MODE_VERT_VR1:
		case MODE_VERT_VR2:
		case MODE_VERT_VR3:
		case MODE_VERT_VL1:
		case MODE_VERT_VL2:
		case MODE_VERT_VL3:
			b2 = finddiff(sp->b.refline, a0, npels, !color);
			b1 = finddiff(sp->b.refline, b2, npels, color);
			b1 += mode - MODE_VERT_V0;
			if (color) {
				if (a0 < 0)
					a0 = 0;
				fillspan((char *)buf, a0, b1 - a0);
			}
			color = !color;
			a0 = b1;
			break;
	        case MODE_UNCOMP:
			/*
			 * Uncompressed mode: select from the
			 * special set of code words.
			 */
			if (a0 < 0)
				a0 = 0;
			do {
				mode = decode_uncomp_code(tif);
				switch (mode) {
				case UNCOMP_RUN1:
				case UNCOMP_RUN2:
				case UNCOMP_RUN3:
				case UNCOMP_RUN4:
				case UNCOMP_RUN5:
					run1 = mode - UNCOMP_RUN0;
					fillspan((char *)buf, a0+run1-1, 1);
					a0 += run1;
					break;
				case UNCOMP_RUN6:
					a0 += 5;
					break;
				case UNCOMP_TRUN0:
				case UNCOMP_TRUN1:
				case UNCOMP_TRUN2:
				case UNCOMP_TRUN3:
				case UNCOMP_TRUN4:
					run1 = mode - UNCOMP_TRUN0;
					a0 += run1;
					color = nextbit(tif) ?
					    !sp->b.white : sp->b.white;
					break;
				case UNCOMP_INVALID:
					TIFFError(module,
				"%s: Bad uncompressed code word at scanline %d",
					    tif->tif_name, tif->tif_row);
					goto bad;
				case UNCOMP_EOF:
					TIFFError(module,
					    "%s: Premature EOF at scanline %d",
					    tif->tif_name, tif->tif_row);
					return (0);
				}
			} while (mode < UNCOMP_EXIT);
			break;
	        case MODE_ERROR_1:
			if ((tif->tif_options & FAX3_NOEOL) == 0) {
				TIFFWarning(module,
				    "%s: Premature EOL at scanline %d (x %d)",
				    tif->tif_name, tif->tif_row, a0);
				skiptoeol(tif, 7);	/* seen 7 0's already */
				return (1);		/* try to synchronize */
			}
			/* fall thru... */
	        case MODE_ERROR:
			TIFFError(module,
			    "%s: Bad 2D code word at scanline %d",
			    tif->tif_name, tif->tif_row);
			goto bad;
	        default:
			TIFFError(module,
			    "%s: Panic, bad decoding state at scanline %d",
			    tif->tif_name, tif->tif_row);
			return (0);
		}
	} while (a0 < npels);
bad:
	/*
	 * Cleanup at the end of row.  We check for
	 * EOL separately so that this code can be
	 * reused by the Group 4 decoding routine.
	 */
	if ((tif->tif_options & FAX3_NOEOL) == 0)
		skiptoeol(tif, 0);
	return (a0 >= npels);
#undef	PIXEL
}

/*
 * CCITT Group 3 FAX Encoding.
 */

/*
 * Write a variable-length bit-value to
 * the output stream.  Values are
 * assumed to be at most 16 bits.
 */
static void
putbits(tif, bits, length)
	TIFF *tif;
	u_int bits, length;
{
	Fax3BaseState *sp = (Fax3BaseState *)tif->tif_data;
	static const int mask[9] =
	    { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };

	while (length > sp->bit) {
		sp->data |= bits >> (length - sp->bit);
		length -= sp->bit;
		Fax3FlushBits(tif, sp);
	}
	sp->data |= (bits & mask[length]) << (sp->bit - length);
	sp->bit -= length;
	if (sp->bit == 0)
		Fax3FlushBits(tif, sp);
}

/*
 * Write a code to the output stream.
 */
static void
putcode(tif, te)
	TIFF *tif;
	tableentry const *te;
{
	putbits(tif, te->code, te->length);
}

/*
 * Write the sequence of codes that describes
 * the specified span of zero's or one's.  The
 * appropriate table that holds the make-up and
 * terminating codes is supplied.
 */
static void
putspan(tif, span, tab)
	TIFF *tif;
	int span;
	tableentry const *tab;
{
	while (span >= 2624) {
		tableentry const *te = &tab[63 + (2560>>6)];
		putcode(tif, te);
		span -= te->runlen;
	}
	if (span >= 64) {
		tableentry const *te = &tab[63 + (span>>6)];
		assert(te->runlen == 64*(span>>6));
		putcode(tif, te);
		span -= te->runlen;
	}
	putcode(tif, &tab[span]);
}

/*
 * Write an EOL code to the output stream.  The zero-fill
 * logic for byte-aligning encoded scanlines is handled
 * here.  We also handle writing the tag bit for the next
 * scanline when doing 2d encoding.
 */
void
Fax3PutEOL(tif)
	TIFF *tif;
{
	Fax3BaseState *sp = (Fax3BaseState *)tif->tif_data;

	if (tif->tif_dir.td_group3options & GROUP3OPT_FILLBITS) {
		/*
		 * Force bit alignment so EOL will terminate on
		 * a byte boundary.  That is, force the bit alignment
		 * to 16-12 = 4 before putting out the EOL code.
		 */
		int align = 8 - 4;
		if (align != sp->bit) {
			if (align > sp->bit)
				align = sp->bit + (8 - align);
			else
				align = sp->bit - align;
			putbits(tif, 0, align);
		}
	}
	putbits(tif, EOL, 12);
	if (is2DEncoding(tif))
		putbits(tif, sp->tag == G3_1D, 1);
}

static const u_char zeroruns[256] = {
    8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,	/* 0x00 - 0x0f */
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,	/* 0x10 - 0x1f */
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0x20 - 0x2f */
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0x30 - 0x3f */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x40 - 0x4f */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x50 - 0x5f */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x60 - 0x6f */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x70 - 0x7f */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x80 - 0x8f */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x90 - 0x9f */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xa0 - 0xaf */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xb0 - 0xbf */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xc0 - 0xcf */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xd0 - 0xdf */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xe0 - 0xef */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xf0 - 0xff */
};
static const u_char oneruns[256] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x00 - 0x0f */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x10 - 0x1f */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x20 - 0x2f */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x30 - 0x3f */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x40 - 0x4f */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x50 - 0x5f */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x60 - 0x6f */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x70 - 0x7f */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x80 - 0x8f */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x90 - 0x9f */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0xa0 - 0xaf */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0xb0 - 0xbf */
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0xc0 - 0xcf */
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0xd0 - 0xdf */
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,	/* 0xe0 - 0xef */
    4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,	/* 0xf0 - 0xff */
};

/*
 * Reset encoding state at the start of a strip.
 */
static
Fax3PreEncode(tif)
	TIFF *tif;
{
	Fax3EncodeState *sp = (Fax3EncodeState *)tif->tif_data;

	if (sp == NULL) {
		sp = (Fax3EncodeState *)Fax3SetupState(tif, sizeof (*sp));
		if (!sp)
			return (0);
		if (sp->b.white == 0) {
			sp->wruns = zeroruns;
			sp->bruns = oneruns;
		} else {
			sp->wruns = oneruns;
			sp->bruns = zeroruns;
		}
	}
	sp->b.bit = 8;
	sp->b.data = 0;
	sp->b.tag = G3_1D;
	/*
	 * This is necessary for Group 4; otherwise it isn't
	 * needed because the first scanline of each strip ends
	 * up being copied into the refline.
	 */
	if (sp->b.refline)
		bset(sp->b.refline, sp->b.rowbytes, sp->b.white ? 0xff : 0x00);
	if (is2DEncoding(tif)) {
		float res = tif->tif_dir.td_yresolution;
		/*
		 * The CCITT spec says that when doing 2d encoding, you
		 * should only do it on K consecutive scanlines, where K
		 * depends on the resolution of the image being encoded
		 * (2 for <= 200 lpi, 4 for > 200 lpi).  Since the directory
		 * code initializes td_yresolution to 0, this code will
		 * select a K of 2 unless the YResolution tag is set
		 * appropriately.  (Note also that we fudge a little here
		 * and use 150 lpi to avoid problems with units conversion.)
		 */
		if (tif->tif_dir.td_resolutionunit == RESUNIT_CENTIMETER)
			res = (res * .3937) / 2.54;	/* convert to inches */
		sp->maxk = (res > 150 ? 4 : 2);
		sp->k = sp->maxk-1;
	} else
		sp->k = sp->maxk = 0;
	return (1);
}

/*
 * 1d-encode a row of pixels.  The encoding is
 * a sequence of all-white or all-black spans
 * of pixels encoded with Huffman codes.
 */
static int
Fax3Encode1DRow(tif, bp, bits)
	TIFF *tif;
	u_char *bp;
	int bits;
{
	Fax3EncodeState *sp = (Fax3EncodeState *)tif->tif_data;
	int bs = 0, span;

	for (;;) {
		span = findspan(&bp, bs, bits, sp->wruns);	/* white span */
		putspan(tif, span, TIFFFaxWhiteCodes);
		bs += span;
		if (bs >= bits)
			break;
		span = findspan(&bp, bs, bits, sp->bruns);	/* black span */
		putspan(tif, span, TIFFFaxBlackCodes);
		bs += span;
		if (bs >= bits)
			break;
	}
	return (1);
}

static const tableentry horizcode =
    { 3, 0x1 };		/* 001 */
static const tableentry passcode =
    { 4, 0x1 };		/* 0001 */
static const tableentry vcodes[7] = {
    { 7, 0x03 },	/* 0000 011 */
    { 6, 0x03 },	/* 0000 11 */
    { 3, 0x03 },	/* 011 */
    { 1, 0x1 },		/* 1 */
    { 3, 0x2 },		/* 010 */
    { 6, 0x02 },	/* 0000 10 */
    { 7, 0x02 }		/* 0000 010 */
};

/*
 * 2d-encode a row of pixels.  Consult the CCITT
 * documentation for the algorithm.
 */
int
Fax3Encode2DRow(tif, bp, rp, bits)
	TIFF *tif;
	u_char *bp, *rp;
	int bits;
{
#define	PIXEL(buf,ix)	((((buf)[(ix)>>3]) >> (7-((ix)&7))) & 1)
	short white = ((Fax3BaseState *)tif->tif_data)->white;
	int a0 = 0;
	int a1 = (PIXEL(bp, 0) != white ? 0 : finddiff(bp, 0, bits, white));
	int b1 = (PIXEL(rp, 0) != white ? 0 : finddiff(rp, 0, bits, white));
	int a2, b2;

	for (;;) {
		b2 = finddiff(rp, b1, bits, PIXEL(rp,b1));
		if (b2 >= a1) {
			int d = b1 - a1;
			if (!(-3 <= d && d <= 3)) {	/* horizontal mode */
				a2 = finddiff(bp, a1, bits, PIXEL(bp,a1));
				putcode(tif, &horizcode);
				if (a0+a1 == 0 || PIXEL(bp, a0) == white) {
					putspan(tif, a1-a0, TIFFFaxWhiteCodes);
					putspan(tif, a2-a1, TIFFFaxBlackCodes);
				} else {
					putspan(tif, a1-a0, TIFFFaxBlackCodes);
					putspan(tif, a2-a1, TIFFFaxWhiteCodes);
				}
				a0 = a2;
			} else {			/* vertical mode */
				putcode(tif, &vcodes[d+3]);
				a0 = a1;
			}
		} else {				/* pass mode */
			putcode(tif, &passcode);
			a0 = b2;
		}
		if (a0 >= bits)
			break;
		a1 = finddiff(bp, a0, bits, PIXEL(bp,a0));
		b1 = finddiff(rp, a0, bits, !PIXEL(bp,a0));
		b1 = finddiff(rp, b1, bits, PIXEL(bp,a0));
	}
	return (1);
#undef PIXEL
}

/*
 * Encode a buffer of pixels.
 */
static int
Fax3Encode(tif, bp, cc, s)
	TIFF *tif;
	u_char *bp;
	int cc;
	u_int s;
{
	Fax3EncodeState *sp = (Fax3EncodeState *)tif->tif_data;

	while (cc > 0) {
		Fax3PutEOL(tif);
		if (is2DEncoding(tif)) {
			if (sp->b.tag == G3_1D) {
				if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
					return (0);
				sp->b.tag = G3_2D;
			} else {
				if (!Fax3Encode2DRow(tif, bp, sp->b.refline, sp->b.rowpixels))
					return (0);
				sp->k--;
			}
			if (sp->k == 0) {
				sp->b.tag = G3_1D;
				sp->k = sp->maxk-1;
			} else
				bcopy(bp, sp->b.refline, sp->b.rowbytes);
		} else {
			if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
				return (0);
		}
		bp += sp->b.rowbytes;
		cc -= sp->b.rowbytes;
	}
	return (1);
}

static int
Fax3PostEncode(tif)
	TIFF *tif;
{
	Fax3BaseState *sp = (Fax3BaseState *)tif->tif_data;

	if (sp->bit != 8)
		Fax3FlushBits(tif, sp);
	return (1);
}

static
Fax3Close(tif)
	TIFF *tif;
{
	if ((tif->tif_options & FAX3_CLASSF) == 0) {	/* append RTC */
		int i;
		for (i = 0; i < 6; i++)
			Fax3PutEOL(tif);
		(void) Fax3PostEncode(tif);
	}
}

static
Fax3Cleanup(tif)
	TIFF *tif;
{
	if (tif->tif_data) {
		free(tif->tif_data);
		tif->tif_data = NULL;
	}
}

/*
 * Bit handling utilities.
 */

/*
 * Find a span of ones or zeros using the supplied
 * table.  The byte-aligned start of the bit string
 * is supplied along with the start+end bit indices.
 * The table gives the number of consecutive ones or
 * zeros starting from the msb and is indexed by byte
 * value.
 */
static int
findspan(bpp, bs, be, tab)
	u_char **bpp;
	int bs, be;
	register u_char const *tab;
{
	register u_char *bp = *bpp;
	register int bits = be - bs;
	register int n, span;

	/*
	 * Check partial byte on lhs.
	 */
	if (bits > 0 && (n = (bs & 7))) {
		span = tab[(*bp << n) & 0xff];
		if (span > 8-n)		/* table value too generous */
			span = 8-n;
		if (span > bits)	/* constrain span to bit range */
			span = bits;
		if (n+span < 8)		/* doesn't extend to edge of byte */
			goto done;
		bits -= span;
		bp++;
	} else
		span = 0;
	/*
	 * Scan full bytes for all 1's or all 0's.
	 */
	while (bits >= 8) {
		n = tab[*bp];
		span += n;
		bits -= n;
		if (n < 8)		/* end of run */
			goto done;
		bp++;
	}
	/*
	 * Check partial byte on rhs.
	 */
	if (bits > 0) {
		n = tab[*bp];
		span += (n > bits ? bits : n);
	}
done:
	*bpp = bp;
	return (span);
}

/*
 * Return the offset of the next bit in the range
 * [bs..be] that is different from the specified
 * color.  The end, be, is returned if no such bit
 * exists.
 */
static int
finddiff(cp, bs, be, color)
	u_char *cp;
	int bs, be, color;
{
	cp += bs >> 3;			/* adjust byte offset */
	return (bs + findspan(&cp, bs, be, color ? oneruns : zeroruns));
}
