/*
 * Copyright (c) 1990-1997 Sam Leffler
 * Copyright (c) 1991-1997 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.
 */

#include "tiffiop.h"
#ifdef CCITT_SUPPORT
/*
 * TIFF Library.
 *
 * CCITT Group 3 (T.4) and Group 4 (T.6) Compression Support.
 *
 * This file contains support for decoding and encoding TIFF
 * compression algorithms 2, 3, 4, and 32771.
 *
 * Decoder support is derived, with permission, from the code
 * in Frank Cringle's viewfax program;
 *      Copyright (C) 1990, 1995  Frank D. Cringle.
 */
#include "tif_fax3.h"
#define	G3CODES
#include "t4.h"
#include <stdio.h>

/*
 * Compression+decompression state blocks are
 * derived from this ``base state'' block.
 */
typedef struct {
	int      rw_mode;                /* O_RDONLY for decode, else encode */
	int      mode;                   /* operating mode */
	tmsize_t rowbytes;               /* bytes in a decoded scanline */
	uint32   rowpixels;              /* pixels in a scanline */

	uint16   cleanfaxdata;           /* CleanFaxData tag */
	uint32   badfaxrun;              /* BadFaxRun tag */
	uint32   badfaxlines;            /* BadFaxLines tag */
	uint32   groupoptions;           /* Group 3/4 options tag */

	TIFFVGetMethod  vgetparent;      /* super-class method */
	TIFFVSetMethod  vsetparent;      /* super-class method */
	TIFFPrintMethod printdir;        /* super-class method */
} Fax3BaseState;
#define	Fax3State(tif)		((Fax3BaseState*) (tif)->tif_data)

typedef enum { G3_1D, G3_2D } Ttag;
typedef struct {
	Fax3BaseState b;

	/* Decoder state info */
	const unsigned char* bitmap;	/* bit reversal table */
	uint32	data;			/* current i/o byte/word */
	int	bit;			/* current i/o bit in byte */
	int	EOLcnt;			/* count of EOL codes recognized */
	TIFFFaxFillFunc fill;		/* fill routine */
	uint32*	runs;			/* b&w runs for current/previous row */
	uint32	nruns;			/* size of the refruns / curruns arrays */
	uint32*	refruns;		/* runs for reference line */
	uint32*	curruns;		/* runs for current line */

	/* Encoder state info */
	Ttag    tag;			/* encoding state */
	unsigned char*	refline;	/* reference line for 2d decoding */
	int	k;			/* #rows left that can be 2d encoded */
	int	maxk;			/* max #rows that can be 2d encoded */

	int line;
} Fax3CodecState;
#define DecoderState(tif) ((Fax3CodecState*) Fax3State(tif))
#define EncoderState(tif) ((Fax3CodecState*) Fax3State(tif))

#define is2DEncoding(sp) (sp->b.groupoptions & GROUP3OPT_2DENCODING)
#define isAligned(p,t) ((((size_t)(p)) & (sizeof (t)-1)) == 0)

/*
 * Group 3 and Group 4 Decoding.
 */

/*
 * These macros glue the TIFF library state to
 * the state expected by Frank's decoder.
 */
#define	DECLARE_STATE(tif, sp, mod)					\
    static const char module[] = mod;					\
    Fax3CodecState* sp = DecoderState(tif);				\
    int a0;				/* reference element */		\
    int lastx = sp->b.rowpixels;	/* last element in row */	\
    uint32 BitAcc;			/* bit accumulator */		\
    int BitsAvail;			/* # valid bits in BitAcc */	\
    int RunLength;			/* length of current run */	\
    unsigned char* cp;			/* next byte of input data */	\
    unsigned char* ep;			/* end of input data */		\
    uint32* pa;				/* place to stuff next run */	\
    uint32* thisrun;			/* current row's run array */	\
    int EOLcnt;				/* # EOL codes recognized */	\
    const unsigned char* bitmap = sp->bitmap;	/* input data bit reverser */	\
    const TIFFFaxTabEnt* TabEnt
#define	DECLARE_STATE_2D(tif, sp, mod)					\
    DECLARE_STATE(tif, sp, mod);					\
    int b1;				/* next change on prev line */	\
    uint32* pb				/* next run in reference line */\
/*
 * Load any state that may be changed during decoding.
 */
#define	CACHE_STATE(tif, sp) do {					\
    BitAcc = sp->data;							\
    BitsAvail = sp->bit;						\
    EOLcnt = sp->EOLcnt;						\
    cp = (unsigned char*) tif->tif_rawcp;				\
    ep = cp + tif->tif_rawcc;						\
} while (0)
/*
 * Save state possibly changed during decoding.
 */
#define	UNCACHE_STATE(tif, sp) do {					\
    sp->bit = BitsAvail;						\
    sp->data = BitAcc;							\
    sp->EOLcnt = EOLcnt;						\
    tif->tif_rawcc -= (tmsize_t)((uint8*) cp - tif->tif_rawcp);		\
    tif->tif_rawcp = (uint8*) cp;					\
} while (0)

/*
 * Setup state for decoding a strip.
 */
static int
Fax3PreDecode(TIFF* tif, uint16 s)
{
	Fax3CodecState* sp = DecoderState(tif);

	(void) s;
	assert(sp != NULL);
	sp->bit = 0;			/* force initial read */
	sp->data = 0;
	sp->EOLcnt = 0;			/* force initial scan for EOL */
	/*
	 * Decoder assumes lsb-to-msb bit order.  Note that we select
	 * this here rather than in Fax3SetupState so that viewers can
	 * hold the image open, fiddle with the FillOrder tag value,
	 * and then re-decode the image.  Otherwise they'd need to close
	 * and open the image to get the state reset.
	 */
	sp->bitmap =
	    TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB);
	sp->curruns = sp->runs;
	if (sp->refruns) {		/* init reference line to white */
		sp->refruns = sp->runs + sp->nruns;
		sp->refruns[0] = (uint32) sp->b.rowpixels;
		sp->refruns[1] = 0;
	}
	sp->line = 0;
	return (1);
}

/*
 * Routine for handling various errors/conditions.
 * Note how they are "glued into the decoder" by
 * overriding the definitions used by the decoder.
 */

static void
Fax3Unexpected(const char* module, TIFF* tif, uint32 line, uint32 a0)
{
	TIFFErrorExt(tif->tif_clientdata, module, "Bad code word at line %u of %s %u (x %u)",
	    line, isTiled(tif) ? "tile" : "strip",
	    (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
	    a0);
}
#define	unexpected(table, a0)	Fax3Unexpected(module, tif, sp->line, a0)

static void
Fax3Extension(const char* module, TIFF* tif, uint32 line, uint32 a0)
{
	TIFFErrorExt(tif->tif_clientdata, module,
	    "Uncompressed data (not supported) at line %u of %s %u (x %u)",
	    line, isTiled(tif) ? "tile" : "strip",
	    (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
	    a0);
}
#define	extension(a0)	Fax3Extension(module, tif, sp->line, a0)

static void
Fax3BadLength(const char* module, TIFF* tif, uint32 line, uint32 a0, uint32 lastx)
{
	TIFFWarningExt(tif->tif_clientdata, module, "%s at line %u of %s %u (got %u, expected %u)",
	    a0 < lastx ? "Premature EOL" : "Line length mismatch",
	    line, isTiled(tif) ? "tile" : "strip",
	    (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
	    a0, lastx);
}
#define	badlength(a0,lastx)	Fax3BadLength(module, tif, sp->line, a0, lastx)

static void
Fax3PrematureEOF(const char* module, TIFF* tif, uint32 line, uint32 a0)
{
	TIFFWarningExt(tif->tif_clientdata, module, "Premature EOF at line %u of %s %u (x %u)",
	    line, isTiled(tif) ? "tile" : "strip",
	    (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
	    a0);
}
#define	prematureEOF(a0)	Fax3PrematureEOF(module, tif, sp->line, a0)

#define	Nop

/**
 * Decode the requested amount of G3 1D-encoded data.
 * @param buf destination buffer
 * @param occ available bytes in destination buffer
 * @param s number of planes (ignored)
 * @returns 1 for success, -1 in case of error
 */
static int
Fax3Decode1D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
{
	DECLARE_STATE(tif, sp, "Fax3Decode1D");
	(void) s;
	if (occ % sp->b.rowbytes)
	{
		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
		return (-1);
	}
	CACHE_STATE(tif, sp);
	thisrun = sp->curruns;
	while (occ > 0) {
		a0 = 0;
		RunLength = 0;
		pa = thisrun;
#ifdef FAX3_DEBUG
		printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail);
		printf("-------------------- %d\n", tif->tif_row);
		fflush(stdout);
#endif
		SYNC_EOL(EOF1D);
		EXPAND1D(EOF1Da);
		(*sp->fill)(buf, thisrun, pa, lastx);
		buf += sp->b.rowbytes;
		occ -= sp->b.rowbytes;
		sp->line++;
		continue;
	EOF1D:				/* premature EOF */
		CLEANUP_RUNS();
	EOF1Da:				/* premature EOF */
		(*sp->fill)(buf, thisrun, pa, lastx);
		UNCACHE_STATE(tif, sp);
		return (-1);
	}
	UNCACHE_STATE(tif, sp);
	return (1);
}

#define	SWAP(t,a,b)	{ t x; x = (a); (a) = (b); (b) = x; }
/*
 * Decode the requested amount of G3 2D-encoded data.
 */
static int
Fax3Decode2D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
{
	DECLARE_STATE_2D(tif, sp, "Fax3Decode2D");
	int is1D;			/* current line is 1d/2d-encoded */
	(void) s;
	if (occ % sp->b.rowbytes)
	{
		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
		return (-1);
	}
	CACHE_STATE(tif, sp);
	while (occ > 0) {
		a0 = 0;
		RunLength = 0;
		pa = thisrun = sp->curruns;
#ifdef FAX3_DEBUG
		printf("\nBitAcc=%08X, BitsAvail = %d EOLcnt = %d",
		    BitAcc, BitsAvail, EOLcnt);
#endif
		SYNC_EOL(EOF2D);
		NeedBits8(1, EOF2D);
		is1D = GetBits(1);	/* 1D/2D-encoding tag bit */
		ClrBits(1);
#ifdef FAX3_DEBUG
		printf(" %s\n-------------------- %d\n",
		    is1D ? "1D" : "2D", tif->tif_row);
		fflush(stdout);
#endif
		pb = sp->refruns;
		b1 = *pb++;
		if (is1D)
			EXPAND1D(EOF2Da);
		else
			EXPAND2D(EOF2Da);
		(*sp->fill)(buf, thisrun, pa, lastx);
		if (pa < thisrun + sp->nruns) {
			SETVALUE(0);	/* imaginary change for reference */
		}
		SWAP(uint32*, sp->curruns, sp->refruns);
		buf += sp->b.rowbytes;
		occ -= sp->b.rowbytes;
		sp->line++;
		continue;
	EOF2D:				/* premature EOF */
		CLEANUP_RUNS();
	EOF2Da:				/* premature EOF */
		(*sp->fill)(buf, thisrun, pa, lastx);
		UNCACHE_STATE(tif, sp);
		return (-1);
	}
	UNCACHE_STATE(tif, sp);
	return (1);
}
#undef SWAP

/*
 * The ZERO & FILL macros must handle spans < 2*sizeof(long) bytes.
 * For machines with 64-bit longs this is <16 bytes; otherwise
 * this is <8 bytes.  We optimize the code here to reflect the
 * machine characteristics.
 */
#if SIZEOF_UNSIGNED_LONG == 8
# define FILL(n, cp)							    \
    switch (n) {							    \
    case 15:(cp)[14] = 0xff; /*-fallthrough*/ \
    case 14:(cp)[13] = 0xff; /*-fallthrough*/ \
    case 13:(cp)[12] = 0xff; /*-fallthrough*/ \
    case 12:(cp)[11] = 0xff; /*-fallthrough*/ \
    case 11:(cp)[10] = 0xff; /*-fallthrough*/ \
    case 10: (cp)[9] = 0xff; /*-fallthrough*/ \
    case  9: (cp)[8] = 0xff; /*-fallthrough*/ \
    case  8: (cp)[7] = 0xff; /*-fallthrough*/ \
    case  7: (cp)[6] = 0xff; /*-fallthrough*/ \
    case  6: (cp)[5] = 0xff; /*-fallthrough*/ \
    case  5: (cp)[4] = 0xff; /*-fallthrough*/ \
    case  4: (cp)[3] = 0xff; /*-fallthrough*/ \
    case  3: (cp)[2] = 0xff; /*-fallthrough*/ \
    case  2: (cp)[1] = 0xff; /*-fallthrough*/ \
    case  1: (cp)[0] = 0xff; (cp) += (n); /*-fallthrough*/ \
    case 0:  ;			      \
    }
# define ZERO(n, cp)							\
    switch (n) {							\
    case 15:(cp)[14] = 0; /*-fallthrough*/ \
    case 14:(cp)[13] = 0; /*-fallthrough*/ \
    case 13:(cp)[12] = 0; /*-fallthrough*/ \
    case 12:(cp)[11] = 0; /*-fallthrough*/ \
    case 11:(cp)[10] = 0; /*-fallthrough*/ \
    case 10: (cp)[9] = 0; /*-fallthrough*/ \
    case  9: (cp)[8] = 0; /*-fallthrough*/ \
    case  8: (cp)[7] = 0; /*-fallthrough*/ \
    case  7: (cp)[6] = 0; /*-fallthrough*/ \
    case  6: (cp)[5] = 0; /*-fallthrough*/ \
    case  5: (cp)[4] = 0; /*-fallthrough*/ \
    case  4: (cp)[3] = 0; /*-fallthrough*/ \
    case  3: (cp)[2] = 0; /*-fallthrough*/ \
    case  2: (cp)[1] = 0; /*-fallthrough*/ \
    case  1: (cp)[0] = 0; (cp) += (n); /*-fallthrough*/ \
    case 0:  ;			\
    }
#else
# define FILL(n, cp)							    \
    switch (n) {							    \
    case 7: (cp)[6] = 0xff; /*-fallthrough*/ \
    case 6: (cp)[5] = 0xff; /*-fallthrough*/ \
    case 5: (cp)[4] = 0xff; /*-fallthrough*/ \
    case 4: (cp)[3] = 0xff; /*-fallthrough*/ \
    case 3: (cp)[2] = 0xff; /*-fallthrough*/ \
    case 2: (cp)[1] = 0xff; /*-fallthrough*/ \
    case 1: (cp)[0] = 0xff; (cp) += (n);  /*-fallthrough*/ \
    case 0:  ;			    \
    }
# define ZERO(n, cp)							\
    switch (n) {							\
    case 7: (cp)[6] = 0; /*-fallthrough*/ \
    case 6: (cp)[5] = 0; /*-fallthrough*/ \
    case 5: (cp)[4] = 0; /*-fallthrough*/ \
    case 4: (cp)[3] = 0; /*-fallthrough*/ \
    case 3: (cp)[2] = 0; /*-fallthrough*/ \
    case 2: (cp)[1] = 0; /*-fallthrough*/ \
    case 1: (cp)[0] = 0; (cp) += (n); /*-fallthrough*/ \
    case 0:  ;			\
    }
#endif

/*
 * Bit-fill a row according to the white/black
 * runs generated during G3/G4 decoding.
 */
void
_TIFFFax3fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx)
{
	static const unsigned char _fillmasks[] =
	    { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
	unsigned char* cp;
	uint32 x, bx, run;
	int32 n, nw;
	long* lp;

	if ((erun-runs)&1)
	    *erun++ = 0;
	x = 0;
	for (; runs < erun; runs += 2) {
	    run = runs[0];
	    if (x+run > lastx || run > lastx )
		run = runs[0] = (uint32) (lastx - x);
	    if (run) {
		cp = buf + (x>>3);
		bx = x&7;
		if (run > 8-bx) {
		    if (bx) {			/* align to byte boundary */
			*cp++ &= 0xff << (8-bx);
			run -= 8-bx;
		    }
		    if( (n = run >> 3) != 0 ) {	/* multiple bytes to fill */
			if ((n/sizeof (long)) > 1) {
			    /*
			     * Align to longword boundary and fill.
			     */
			    for (; n && !isAligned(cp, long); n--)
				    *cp++ = 0x00;
			    lp = (long*) cp;
			    nw = (int32)(n / sizeof (long));
			    n -= nw * sizeof (long);
			    do {
				    *lp++ = 0L;
			    } while (--nw);
			    cp = (unsigned char*) lp;
			}
			ZERO(n, cp);
			run &= 7;
		    }
		    if (run)
			cp[0] &= 0xff >> run;
		} else
		    cp[0] &= ~(_fillmasks[run]>>bx);
		x += runs[0];
	    }
	    run = runs[1];
	    if (x+run > lastx || run > lastx )
		run = runs[1] = lastx - x;
	    if (run) {
		cp = buf + (x>>3);
		bx = x&7;
		if (run > 8-bx) {
		    if (bx) {			/* align to byte boundary */
			*cp++ |= 0xff >> bx;
			run -= 8-bx;
		    }
		    if( (n = run>>3) != 0 ) {	/* multiple bytes to fill */
			if ((n/sizeof (long)) > 1) {
			    /*
			     * Align to longword boundary and fill.
			     */
			    for (; n && !isAligned(cp, long); n--)
				*cp++ = 0xff;
			    lp = (long*) cp;
			    nw = (int32)(n / sizeof (long));
			    n -= nw * sizeof (long);
			    do {
				*lp++ = -1L;
			    } while (--nw);
			    cp = (unsigned char*) lp;
			}
			FILL(n, cp);
			run &= 7;
		    }
                    /* Explicit 0xff masking to make icc -check=conversions happy */
		    if (run)
			cp[0] = (unsigned char)((cp[0] | (0xff00 >> run))&0xff);
		} else
		    cp[0] |= _fillmasks[run]>>bx;
		x += runs[1];
	    }
	}
	assert(x == lastx);
}
#undef	ZERO
#undef	FILL

static int
Fax3FixupTags(TIFF* tif)
{
	(void) tif;
	return (1);
}

/*
 * Setup G3/G4-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 decoding or encoding is being done and whether
 * 1D- or 2D-encoded data is involved.
 */
static int
Fax3SetupState(TIFF* tif)
{
	static const char module[] = "Fax3SetupState";
	TIFFDirectory* td = &tif->tif_dir;
	Fax3BaseState* sp = Fax3State(tif);
	int needsRefLine;
	Fax3CodecState* dsp = (Fax3CodecState*) Fax3State(tif);
	tmsize_t rowbytes;
	uint32 rowpixels;

	if (td->td_bitspersample != 1) {
		TIFFErrorExt(tif->tif_clientdata, module,
		    "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 = td->td_tilewidth;
	} else {
		rowbytes = TIFFScanlineSize(tif);
		rowpixels = td->td_imagewidth;
	}
	if ((uint64)rowbytes < ((uint64)rowpixels + 7) / 8)
	{
		TIFFErrorExt(tif->tif_clientdata, module,
			"Inconsistent number of bytes per row : rowbytes=%lu rowpixels=%lu",
			(unsigned long)(rowbytes), (unsigned long)(rowpixels));
		return (0);
	}
	sp->rowbytes = rowbytes;
	sp->rowpixels = rowpixels;
	/*
	 * Allocate any additional space required for decoding/encoding.
	 */
	needsRefLine = (
	    (sp->groupoptions & GROUP3OPT_2DENCODING) ||
	    td->td_compression == COMPRESSION_CCITTFAX4
	);

	/*
	  Assure that allocation computations do not overflow.
	  
	  TIFFroundup and TIFFSafeMultiply return zero on integer overflow
	*/
	dsp->runs=(uint32*) NULL;
	dsp->nruns = TIFFroundup_32(rowpixels,32);
	if (needsRefLine) {
		dsp->nruns = TIFFSafeMultiply(uint32,dsp->nruns,2);
	}
	if ((dsp->nruns == 0) || (TIFFSafeMultiply(uint32,dsp->nruns,2) == 0)) {
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
			     "Row pixels integer overflow (rowpixels %u)",
			     rowpixels);
		return (0);
	}
	dsp->runs = (uint32*) _TIFFCheckMalloc(tif,
					       TIFFSafeMultiply(uint32,dsp->nruns,2),
					       sizeof (uint32),
					       "for Group 3/4 run arrays");
	if (dsp->runs == NULL)
		return (0);
	memset( dsp->runs, 0, TIFFSafeMultiply(uint32,dsp->nruns,2)*sizeof(uint32));
	dsp->curruns = dsp->runs;
	if (needsRefLine)
		dsp->refruns = dsp->runs + dsp->nruns;
	else
		dsp->refruns = NULL;
	if (td->td_compression == COMPRESSION_CCITTFAX3
	    && is2DEncoding(dsp)) {	/* NB: default is 1D routine */
		tif->tif_decoderow = Fax3Decode2D;
		tif->tif_decodestrip = Fax3Decode2D;
		tif->tif_decodetile = Fax3Decode2D;
	}

	if (needsRefLine) {		/* 2d encoding */
		Fax3CodecState* esp = EncoderState(tif);
		/*
		 * 2d encoding 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).
		 */
		esp->refline = (unsigned char*) _TIFFmalloc(rowbytes);
		if (esp->refline == NULL) {
			TIFFErrorExt(tif->tif_clientdata, module,
			    "No space for Group 3/4 reference line");
			return (0);
		}
	} else					/* 1d encoding */
		EncoderState(tif)->refline = NULL;

	return (1);
}

/*
 * CCITT Group 3 FAX Encoding.
 */

#define	Fax3FlushBits(tif, sp) {				\
	if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) {	\
		if( !TIFFFlushData1(tif) )			\
			return 0;				\
        }							\
	*(tif)->tif_rawcp++ = (uint8) (sp)->data;		\
	(tif)->tif_rawcc++;					\
	(sp)->data = 0, (sp)->bit = 8;				\
}
#define	_FlushBits(tif) {					\
	if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) {	\
		if( !TIFFFlushData1(tif) )			\
			return 0;				\
        }							\
	*(tif)->tif_rawcp++ = (uint8) data;		\
	(tif)->tif_rawcc++;					\
	data = 0, bit = 8;					\
}
static const int _msbmask[9] =
    { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
#define	_PutBits(tif, bits, length) {				\
	while (length > bit) {					\
		data |= bits >> (length - bit);			\
		length -= bit;					\
		_FlushBits(tif);				\
	}							\
        assert( length < 9 );                                   \
	data |= (bits & _msbmask[length]) << (bit - length);	\
	bit -= length;						\
	if (bit == 0)						\
		_FlushBits(tif);				\
}
	
/*
 * Write a variable-length bit-value to
 * the output stream.  Values are
 * assumed to be at most 16 bits.
 */
static int
Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length)
{
	Fax3CodecState* sp = EncoderState(tif);
	unsigned int bit = sp->bit;
	int data = sp->data;

	_PutBits(tif, bits, length);

	sp->data = data;
	sp->bit = bit;
        return 1;
}

/*
 * Write a code to the output stream.
 */
#define putcode(tif, te)	Fax3PutBits(tif, (te)->code, (te)->length)

#ifdef FAX3_DEBUG
#define	DEBUG_COLOR(w) (tab == TIFFFaxWhiteCodes ? w "W" : w "B")
#define	DEBUG_PRINT(what,len) {						\
    int t;								\
    printf("%08X/%-2d: %s%5d\t", data, bit, DEBUG_COLOR(what), len);	\
    for (t = length-1; t >= 0; t--)					\
	putchar(code & (1<<t) ? '1' : '0');				\
    putchar('\n');							\
}
#endif

/*
 * 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 int
putspan(TIFF* tif, int32 span, const tableentry* tab)
{
	Fax3CodecState* sp = EncoderState(tif);
	unsigned int bit = sp->bit;
	int data = sp->data;
	unsigned int code, length;

	while (span >= 2624) {
		const tableentry* te = &tab[63 + (2560>>6)];
		code = te->code;
		length = te->length;
#ifdef FAX3_DEBUG
		DEBUG_PRINT("MakeUp", te->runlen);
#endif
		_PutBits(tif, code, length);
		span -= te->runlen;
	}
	if (span >= 64) {
		const tableentry* te = &tab[63 + (span>>6)];
		assert(te->runlen == 64*(span>>6));
		code = te->code;
		length = te->length;
#ifdef FAX3_DEBUG
		DEBUG_PRINT("MakeUp", te->runlen);
#endif
		_PutBits(tif, code, length);
		span -= te->runlen;
	}
	code = tab[span].code;
	length = tab[span].length;
#ifdef FAX3_DEBUG
	DEBUG_PRINT("  Term", tab[span].runlen);
#endif
	_PutBits(tif, code, length);

	sp->data = data;
	sp->bit = bit;

        return 1;
}

/*
 * 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.
 */
static int
Fax3PutEOL(TIFF* tif)
{
	Fax3CodecState* sp = EncoderState(tif);
	unsigned int bit = sp->bit;
	int data = sp->data;
	unsigned int code, length, tparm;

	if (sp->b.groupoptions & 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;
			tparm=align; 
			_PutBits(tif, 0, tparm);
		}
	}
	code = EOL;
	length = 12;
	if (is2DEncoding(sp)) {
		code = (code<<1) | (sp->tag == G3_1D);
		length++;
	}
	_PutBits(tif, code, length);

	sp->data = data;
	sp->bit = bit;

        return 1;
}

/*
 * Reset encoding state at the start of a strip.
 */
static int
Fax3PreEncode(TIFF* tif, uint16 s)
{
	Fax3CodecState* sp = EncoderState(tif);

	(void) s;
	assert(sp != NULL);
	sp->bit = 8;
	sp->data = 0;
	sp->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->refline)
		_TIFFmemset(sp->refline, 0x00, sp->b.rowbytes);
	if (is2DEncoding(sp)) {
		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 *= 2.54f;		/* convert to inches */
		sp->maxk = (res > 150 ? 4 : 2);
		sp->k = sp->maxk-1;
	} else
		sp->k = sp->maxk = 0;
	sp->line = 0;
	return (1);
}

static const unsigned 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 unsigned 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 */
};

/*
 * On certain systems it pays to inline
 * the routines that find pixel spans.
 */
#ifdef VAXC
static	int32 find0span(unsigned char*, int32, int32);
static	int32 find1span(unsigned char*, int32, int32);
#pragma inline(find0span,find1span)
#endif

/*
 * Find a span of ones or zeros using the supplied
 * table.  The ``base'' of the bit string is supplied
 * along with the start+end bit indices.
 */
inline static int32
find0span(unsigned char* bp, int32 bs, int32 be)
{
	int32 bits = be - bs;
	int32 n, span;

	bp += bs>>3;
	/*
	 * Check partial byte on lhs.
	 */
	if (bits > 0 && (n = (bs & 7)) != 0) {
		span = zeroruns[(*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 */
			return (span);
		bits -= span;
		bp++;
	} else
		span = 0;
	if (bits >= (int32)(2 * 8 * sizeof(long))) {
		long* lp;
		/*
		 * Align to longword boundary and check longwords.
		 */
		while (!isAligned(bp, long)) {
			if (*bp != 0x00)
				return (span + zeroruns[*bp]);
			span += 8;
			bits -= 8;
			bp++;
		}
		lp = (long*) bp;
		while ((bits >= (int32)(8 * sizeof(long))) && (0 == *lp)) {
			span += 8*sizeof (long);
			bits -= 8*sizeof (long);
			lp++;
		}
		bp = (unsigned char*) lp;
	}
	/*
	 * Scan full bytes for all 0's.
	 */
	while (bits >= 8) {
		if (*bp != 0x00)	/* end of run */
			return (span + zeroruns[*bp]);
		span += 8;
		bits -= 8;
		bp++;
	}
	/*
	 * Check partial byte on rhs.
	 */
	if (bits > 0) {
		n = zeroruns[*bp];
		span += (n > bits ? bits : n);
	}
	return (span);
}

inline static int32
find1span(unsigned char* bp, int32 bs, int32 be)
{
	int32 bits = be - bs;
	int32 n, span;

	bp += bs>>3;
	/*
	 * Check partial byte on lhs.
	 */
	if (bits > 0 && (n = (bs & 7)) != 0) {
		span = oneruns[(*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 */
			return (span);
		bits -= span;
		bp++;
	} else
		span = 0;
	if (bits >= (int32)(2 * 8 * sizeof(long))) {
		long* lp;
		/*
		 * Align to longword boundary and check longwords.
		 */
		while (!isAligned(bp, long)) {
			if (*bp != 0xff)
				return (span + oneruns[*bp]);
			span += 8;
			bits -= 8;
			bp++;
		}
		lp = (long*) bp;
		while ((bits >= (int32)(8 * sizeof(long))) && (~0 == *lp)) {
			span += 8*sizeof (long);
			bits -= 8*sizeof (long);
			lp++;
		}
		bp = (unsigned char*) lp;
	}
	/*
	 * Scan full bytes for all 1's.
	 */
	while (bits >= 8) {
		if (*bp != 0xff)	/* end of run */
			return (span + oneruns[*bp]);
		span += 8;
		bits -= 8;
		bp++;
	}
	/*
	 * Check partial byte on rhs.
	 */
	if (bits > 0) {
		n = oneruns[*bp];
		span += (n > bits ? bits : n);
	}
	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.
 */
#define	finddiff(_cp, _bs, _be, _color)	\
	(_bs + (_color ? find1span(_cp,_bs,_be) : find0span(_cp,_bs,_be)))
/*
 * Like finddiff, but also check the starting bit
 * against the end in case start > end.
 */
#define	finddiff2(_cp, _bs, _be, _color) \
	(_bs < _be ? finddiff(_cp,_bs,_be,_color) : _be)

/*
 * 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(TIFF* tif, unsigned char* bp, uint32 bits)
{
	Fax3CodecState* sp = EncoderState(tif);
	int32 span;
        uint32 bs = 0;

	for (;;) {
		span = find0span(bp, bs, bits);		/* white span */
		if( !putspan(tif, span, TIFFFaxWhiteCodes) )
                    return 0;
		bs += span;
		if (bs >= bits)
			break;
		span = find1span(bp, bs, bits);		/* black span */
		if( !putspan(tif, span, TIFFFaxBlackCodes) )
                    return 0;
		bs += span;
		if (bs >= bits)
			break;
	}
	if (sp->b.mode & (FAXMODE_BYTEALIGN|FAXMODE_WORDALIGN)) {
		if (sp->bit != 8)			/* byte-align */
			Fax3FlushBits(tif, sp);
		if ((sp->b.mode&FAXMODE_WORDALIGN) &&
		    !isAligned(tif->tif_rawcp, uint16))
			Fax3FlushBits(tif, sp);
	}
	return (1);
}

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

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

	for (;;) {
		b2 = finddiff2(rp, b1, bits, PIXEL(rp,b1));
		if (b2 >= a1) {
			/* Naive computation triggers -fsanitize=undefined,unsigned-integer-overflow */
			/* although it is correct unless the difference between both is < 31 bit */
			/* int32 d = b1 - a1; */
			int32 d = (b1 >= a1 && b1 - a1 <= 3U) ? (int32)(b1 - a1):
			          (b1 < a1 && a1 - b1 <= 3U) ? -(int32)(a1 - b1) : 0x7FFFFFFF;
			if (!(-3 <= d && d <= 3)) {	/* horizontal mode */
				a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1));
				if( !putcode(tif, &horizcode) )
                                    return 0;
				if (a0+a1 == 0 || PIXEL(bp, a0) == 0) {
					if( !putspan(tif, a1-a0, TIFFFaxWhiteCodes) )
                                            return 0;
					if( !putspan(tif, a2-a1, TIFFFaxBlackCodes) )
                                            return 0;
				} else {
					if( !putspan(tif, a1-a0, TIFFFaxBlackCodes) )
                                            return 0;
					if( !putspan(tif, a2-a1, TIFFFaxWhiteCodes) )
                                            return 0;
				}
				a0 = a2;
			} else {			/* vertical mode */
				if( !putcode(tif, &vcodes[d+3]) )
                                    return 0;
				a0 = a1;
			}
		} else {				/* pass mode */
			if( !putcode(tif, &passcode) )
                            return 0;
			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(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
{
	static const char module[] = "Fax3Encode";
	Fax3CodecState* sp = EncoderState(tif);
	(void) s;
	if (cc % sp->b.rowbytes)
	{
		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be written");
		return (0);
	}
	while (cc > 0) {
		if ((sp->b.mode & FAXMODE_NOEOL) == 0)
                {
			if( !Fax3PutEOL(tif) )
                            return 0;
                }
		if (is2DEncoding(sp)) {
			if (sp->tag == G3_1D) {
				if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
					return (0);
				sp->tag = G3_2D;
			} else {
				if (!Fax3Encode2DRow(tif, bp, sp->refline,
				    sp->b.rowpixels))
					return (0);
				sp->k--;
			}
			if (sp->k == 0) {
				sp->tag = G3_1D;
				sp->k = sp->maxk-1;
			} else
				_TIFFmemcpy(sp->refline, bp, 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(TIFF* tif)
{
	Fax3CodecState* sp = EncoderState(tif);

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

static int
_Fax3Close(TIFF* tif)
{
	if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0 && tif->tif_rawcp) {
		Fax3CodecState* sp = EncoderState(tif);
		unsigned int code = EOL;
		unsigned int length = 12;
		int i;

		if (is2DEncoding(sp)) {
			code = (code<<1) | (sp->tag == G3_1D);
			length++;
		}
		for (i = 0; i < 6; i++)
			Fax3PutBits(tif, code, length);
		Fax3FlushBits(tif, sp);
	}
	return 1;
}

static void
Fax3Close(TIFF* tif)
{
    _Fax3Close(tif);
}

static void
Fax3Cleanup(TIFF* tif)
{
	Fax3CodecState* sp = DecoderState(tif);
	
	assert(sp != 0);

	tif->tif_tagmethods.vgetfield = sp->b.vgetparent;
	tif->tif_tagmethods.vsetfield = sp->b.vsetparent;
	tif->tif_tagmethods.printdir = sp->b.printdir;

	if (sp->runs)
		_TIFFfree(sp->runs);
	if (sp->refline)
		_TIFFfree(sp->refline);

	_TIFFfree(tif->tif_data);
	tif->tif_data = NULL;

	_TIFFSetDefaultCompressionState(tif);
}

#define	FIELD_BADFAXLINES	(FIELD_CODEC+0)
#define	FIELD_CLEANFAXDATA	(FIELD_CODEC+1)
#define	FIELD_BADFAXRUN		(FIELD_CODEC+2)

#define	FIELD_OPTIONS		(FIELD_CODEC+7)

static const TIFFField faxFields[] = {
    { TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxMode", NULL },
    { TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxFillFunc", NULL },
    { TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines", NULL },
    { TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData", NULL },
    { TIFFTAG_CONSECUTIVEBADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines", NULL }};
static const TIFFField fax3Fields[] = {
    { TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL },
};
static const TIFFField fax4Fields[] = {
    { TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group4Options", NULL },
};

static int
Fax3VSetField(TIFF* tif, uint32 tag, va_list ap)
{
	Fax3BaseState* sp = Fax3State(tif);
	const TIFFField* fip;

	assert(sp != 0);
	assert(sp->vsetparent != 0);

	switch (tag) {
	case TIFFTAG_FAXMODE:
		sp->mode = (int) va_arg(ap, int);
		return 1;			/* NB: pseudo tag */
	case TIFFTAG_FAXFILLFUNC:
		DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc);
		return 1;			/* NB: pseudo tag */
	case TIFFTAG_GROUP3OPTIONS:
		/* XXX: avoid reading options if compression mismatches. */
		if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3)
			sp->groupoptions = (uint32) va_arg(ap, uint32);
		break;
	case TIFFTAG_GROUP4OPTIONS:
		/* XXX: avoid reading options if compression mismatches. */
		if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4)
			sp->groupoptions = (uint32) va_arg(ap, uint32);
		break;
	case TIFFTAG_BADFAXLINES:
		sp->badfaxlines = (uint32) va_arg(ap, uint32);
		break;
	case TIFFTAG_CLEANFAXDATA:
		sp->cleanfaxdata = (uint16) va_arg(ap, uint16_vap);
		break;
	case TIFFTAG_CONSECUTIVEBADFAXLINES:
		sp->badfaxrun = (uint32) va_arg(ap, uint32);
		break;
	default:
		return (*sp->vsetparent)(tif, tag, ap);
	}
	
	if ((fip = TIFFFieldWithTag(tif, tag)) != NULL)
		TIFFSetFieldBit(tif, fip->field_bit);
	else
		return 0;

	tif->tif_flags |= TIFF_DIRTYDIRECT;
	return 1;
}

static int
Fax3VGetField(TIFF* tif, uint32 tag, va_list ap)
{
	Fax3BaseState* sp = Fax3State(tif);

	assert(sp != 0);

	switch (tag) {
	case TIFFTAG_FAXMODE:
		*va_arg(ap, int*) = sp->mode;
		break;
	case TIFFTAG_FAXFILLFUNC:
		*va_arg(ap, TIFFFaxFillFunc*) = DecoderState(tif)->fill;
		break;
	case TIFFTAG_GROUP3OPTIONS:
	case TIFFTAG_GROUP4OPTIONS:
		*va_arg(ap, uint32*) = sp->groupoptions;
		break;
	case TIFFTAG_BADFAXLINES:
		*va_arg(ap, uint32*) = sp->badfaxlines;
		break;
	case TIFFTAG_CLEANFAXDATA:
		*va_arg(ap, uint16*) = sp->cleanfaxdata;
		break;
	case TIFFTAG_CONSECUTIVEBADFAXLINES:
		*va_arg(ap, uint32*) = sp->badfaxrun;
		break;
	default:
		return (*sp->vgetparent)(tif, tag, ap);
	}
	return (1);
}

static void
Fax3PrintDir(TIFF* tif, FILE* fd, long flags)
{
	Fax3BaseState* sp = Fax3State(tif);

	assert(sp != 0);

	(void) flags;
	if (TIFFFieldSet(tif,FIELD_OPTIONS)) {
		const char* sep = " ";
		if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) {
			fprintf(fd, "  Group 4 Options:");
			if (sp->groupoptions & GROUP4OPT_UNCOMPRESSED)
				fprintf(fd, "%suncompressed data", sep);
		} else {

			fprintf(fd, "  Group 3 Options:");
			if (sp->groupoptions & GROUP3OPT_2DENCODING) {
				fprintf(fd, "%s2-d encoding", sep);
				sep = "+";
			}
			if (sp->groupoptions & GROUP3OPT_FILLBITS) {
				fprintf(fd, "%sEOL padding", sep);
				sep = "+";
			}
			if (sp->groupoptions & GROUP3OPT_UNCOMPRESSED)
				fprintf(fd, "%suncompressed data", sep);
		}
		fprintf(fd, " (%lu = 0x%lx)\n",
                        (unsigned long) sp->groupoptions,
                        (unsigned long) sp->groupoptions);
	}
	if (TIFFFieldSet(tif,FIELD_CLEANFAXDATA)) {
		fprintf(fd, "  Fax Data:");
		switch (sp->cleanfaxdata) {
		case CLEANFAXDATA_CLEAN:
			fprintf(fd, " clean");
			break;
		case CLEANFAXDATA_REGENERATED:
			fprintf(fd, " receiver regenerated");
			break;
		case CLEANFAXDATA_UNCLEAN:
			fprintf(fd, " uncorrected errors");
			break;
		}
		fprintf(fd, " (%u = 0x%x)\n",
		    sp->cleanfaxdata, sp->cleanfaxdata);
	}
	if (TIFFFieldSet(tif,FIELD_BADFAXLINES))
		fprintf(fd, "  Bad Fax Lines: %lu\n",
                        (unsigned long) sp->badfaxlines);
	if (TIFFFieldSet(tif,FIELD_BADFAXRUN))
		fprintf(fd, "  Consecutive Bad Fax Lines: %lu\n",
		    (unsigned long) sp->badfaxrun);
	if (sp->printdir)
		(*sp->printdir)(tif, fd, flags);
}

static int
InitCCITTFax3(TIFF* tif)
{
	static const char module[] = "InitCCITTFax3";
	Fax3BaseState* sp;

	/*
	 * Merge codec-specific tag information.
	 */
	if (!_TIFFMergeFields(tif, faxFields, TIFFArrayCount(faxFields))) {
		TIFFErrorExt(tif->tif_clientdata, "InitCCITTFax3",
			"Merging common CCITT Fax codec-specific tags failed");
		return 0;
	}

	/*
	 * Allocate state block so tag methods have storage to record values.
	 */
	tif->tif_data = (uint8*)
		_TIFFmalloc(sizeof (Fax3CodecState));

	if (tif->tif_data == NULL) {
		TIFFErrorExt(tif->tif_clientdata, module,
		    "No space for state block");
		return (0);
	}
	_TIFFmemset(tif->tif_data, 0, sizeof (Fax3CodecState));

	sp = Fax3State(tif);
        sp->rw_mode = tif->tif_mode;

	/*
	 * Override parent get/set field methods.
	 */
	sp->vgetparent = tif->tif_tagmethods.vgetfield;
	tif->tif_tagmethods.vgetfield = Fax3VGetField; /* hook for codec tags */
	sp->vsetparent = tif->tif_tagmethods.vsetfield;
	tif->tif_tagmethods.vsetfield = Fax3VSetField; /* hook for codec tags */
	sp->printdir = tif->tif_tagmethods.printdir;
	tif->tif_tagmethods.printdir = Fax3PrintDir;   /* hook for codec tags */
	sp->groupoptions = 0;	

	if (sp->rw_mode == O_RDONLY) /* FIXME: improve for in place update */
		tif->tif_flags |= TIFF_NOBITREV; /* decoder does bit reversal */
	DecoderState(tif)->runs = NULL;
	TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, _TIFFFax3fillruns);
	EncoderState(tif)->refline = NULL;

	/*
	 * Install codec methods.
	 */
	tif->tif_fixuptags = Fax3FixupTags;
	tif->tif_setupdecode = Fax3SetupState;
	tif->tif_predecode = Fax3PreDecode;
	tif->tif_decoderow = Fax3Decode1D;
	tif->tif_decodestrip = Fax3Decode1D;
	tif->tif_decodetile = Fax3Decode1D;
	tif->tif_setupencode = Fax3SetupState;
	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;

	return (1);
}

int
TIFFInitCCITTFax3(TIFF* tif, int scheme)
{
	(void) scheme;
	if (InitCCITTFax3(tif)) {
		/*
		 * Merge codec-specific tag information.
		 */
		if (!_TIFFMergeFields(tif, fax3Fields,
				      TIFFArrayCount(fax3Fields))) {
			TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax3",
			"Merging CCITT Fax 3 codec-specific tags failed");
			return 0;
		}

		/*
		 * The default format is Class/F-style w/o RTC.
		 */
		return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF);
	} else
		return 01;
}

/*
 * CCITT Group 4 (T.6) Facsimile-compatible
 * Compression Scheme Support.
 */

#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; }
/*
 * Decode the requested amount of G4-encoded data.
 */
static int
Fax4Decode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
{
	DECLARE_STATE_2D(tif, sp, "Fax4Decode");
	(void) s;
	if (occ % sp->b.rowbytes)
	{
		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
		return (-1);
	}
	CACHE_STATE(tif, sp);
	while (occ > 0) {
		a0 = 0;
		RunLength = 0;
		pa = thisrun = sp->curruns;
		pb = sp->refruns;
		b1 = *pb++;
#ifdef FAX3_DEBUG
		printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail);
		printf("-------------------- %d\n", tif->tif_row);
		fflush(stdout);
#endif
		EXPAND2D(EOFG4);
                if (EOLcnt)
                    goto EOFG4;
		if (((lastx + 7) >> 3) > (int)occ)	/* check for buffer overrun */
		{
			TIFFErrorExt(tif->tif_clientdata, module,
			             "Buffer overrun detected : %d bytes available, %d bits needed",
			             (int)occ, lastx);
			return -1;
		}
		(*sp->fill)(buf, thisrun, pa, lastx);
		SETVALUE(0);		/* imaginary change for reference */
		SWAP(uint32*, sp->curruns, sp->refruns);
		buf += sp->b.rowbytes;
		occ -= sp->b.rowbytes;
		sp->line++;
		continue;
	EOFG4:
                NeedBits16( 13, BADG4 );
        BADG4:
#ifdef FAX3_DEBUG
                if( GetBits(13) != 0x1001 )
                    fputs( "Bad EOFB\n", stderr );
#endif                
                ClrBits( 13 );
		if (((lastx + 7) >> 3) > (int)occ)	/* check for buffer overrun */
		{
			TIFFErrorExt(tif->tif_clientdata, module,
			             "Buffer overrun detected : %d bytes available, %d bits needed",
			             (int)occ, lastx);
			return -1;
		}
		(*sp->fill)(buf, thisrun, pa, lastx);
		UNCACHE_STATE(tif, sp);
		return ( sp->line ? 1 : -1);	/* don't error on badly-terminated strips */
	}
	UNCACHE_STATE(tif, sp);
	return (1);
}
#undef	SWAP

/*
 * Encode the requested amount of data.
 */
static int
Fax4Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
{
	static const char module[] = "Fax4Encode";
	Fax3CodecState *sp = EncoderState(tif);
	(void) s;
	if (cc % sp->b.rowbytes)
	{
		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be written");
		return (0);
	}
	while (cc > 0) {
		if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels))
			return (0);
		_TIFFmemcpy(sp->refline, bp, sp->b.rowbytes);
		bp += sp->b.rowbytes;
		cc -= sp->b.rowbytes;
	}
	return (1);
}

static int
Fax4PostEncode(TIFF* tif)
{
	Fax3CodecState *sp = EncoderState(tif);

	/* terminate strip w/ EOFB */
	Fax3PutBits(tif, EOL, 12);
	Fax3PutBits(tif, EOL, 12);
	if (sp->bit != 8)
		Fax3FlushBits(tif, sp);
	return (1);
}

int
TIFFInitCCITTFax4(TIFF* tif, int scheme)
{
	(void) scheme;
	if (InitCCITTFax3(tif)) {		/* reuse G3 support */
		/*
		 * Merge codec-specific tag information.
		 */
		if (!_TIFFMergeFields(tif, fax4Fields,
				      TIFFArrayCount(fax4Fields))) {
			TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax4",
			"Merging CCITT Fax 4 codec-specific tags failed");
			return 0;
		}

		tif->tif_decoderow = Fax4Decode;
		tif->tif_decodestrip = Fax4Decode;
		tif->tif_decodetile = Fax4Decode;
		tif->tif_encoderow = Fax4Encode;
		tif->tif_encodestrip = Fax4Encode;
		tif->tif_encodetile = Fax4Encode;
		tif->tif_postencode = Fax4PostEncode;
		/*
		 * Suppress RTC at the end of each strip.
		 */
		return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC);
	} else
		return (0);
}

/*
 * CCITT Group 3 1-D Modified Huffman RLE Compression Support.
 * (Compression algorithms 2 and 32771)
 */

/*
 * Decode the requested amount of RLE-encoded data.
 */
static int
Fax3DecodeRLE(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
{
	DECLARE_STATE(tif, sp, "Fax3DecodeRLE");
	int mode = sp->b.mode;
	(void) s;
	if (occ % sp->b.rowbytes)
	{
		TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
		return (-1);
	}
	CACHE_STATE(tif, sp);
	thisrun = sp->curruns;
	while (occ > 0) {
		a0 = 0;
		RunLength = 0;
		pa = thisrun;
#ifdef FAX3_DEBUG
		printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail);
		printf("-------------------- %d\n", tif->tif_row);
		fflush(stdout);
#endif
		EXPAND1D(EOFRLE);
		(*sp->fill)(buf, thisrun, pa, lastx);
		/*
		 * Cleanup at the end of the row.
		 */
		if (mode & FAXMODE_BYTEALIGN) {
			int n = BitsAvail - (BitsAvail &~ 7);
			ClrBits(n);
		} else if (mode & FAXMODE_WORDALIGN) {
			int n = BitsAvail - (BitsAvail &~ 15);
			ClrBits(n);
			if (BitsAvail == 0 && !isAligned(cp, uint16))
			    cp++;
		}
		buf += sp->b.rowbytes;
		occ -= sp->b.rowbytes;
		sp->line++;
		continue;
	EOFRLE:				/* premature EOF */
		(*sp->fill)(buf, thisrun, pa, lastx);
		UNCACHE_STATE(tif, sp);
		return (-1);
	}
	UNCACHE_STATE(tif, sp);
	return (1);
}

int
TIFFInitCCITTRLE(TIFF* tif, int scheme)
{
	(void) scheme;
	if (InitCCITTFax3(tif)) {		/* reuse G3 support */
		tif->tif_decoderow = Fax3DecodeRLE;
		tif->tif_decodestrip = Fax3DecodeRLE;
		tif->tif_decodetile = Fax3DecodeRLE;
		/*
		 * Suppress RTC+EOLs when encoding and byte-align data.
		 */
		return TIFFSetField(tif, TIFFTAG_FAXMODE,
		    FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_BYTEALIGN);
	} else
		return (0);
}

int
TIFFInitCCITTRLEW(TIFF* tif, int scheme)
{
	(void) scheme;
	if (InitCCITTFax3(tif)) {		/* reuse G3 support */
		tif->tif_decoderow = Fax3DecodeRLE;
		tif->tif_decodestrip = Fax3DecodeRLE;
		tif->tif_decodetile = Fax3DecodeRLE;  
		/*
		 * Suppress RTC+EOLs when encoding and word-align data.
		 */
		return TIFFSetField(tif, TIFFTAG_FAXMODE,
		    FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_WORDALIGN);
	} else
		return (0);
}
#endif /* CCITT_SUPPORT */

/* vim: set ts=8 sts=8 sw=8 noet: */
/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 8
 * fill-column: 78
 * End:
 */
