Blame libtiff/tif_fax3.h

Packit Service 2594b8
/* $Id: tif_fax3.h,v 1.13 2016-12-14 18:36:27 faxguy Exp $ */
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Copyright (c) 1990-1997 Sam Leffler
Packit Service 2594b8
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
Packit Service 2594b8
 *
Packit Service 2594b8
 * Permission to use, copy, modify, distribute, and sell this software and 
Packit Service 2594b8
 * its documentation for any purpose is hereby granted without fee, provided
Packit Service 2594b8
 * that (i) the above copyright notices and this permission notice appear in
Packit Service 2594b8
 * all copies of the software and related documentation, and (ii) the names of
Packit Service 2594b8
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
Packit Service 2594b8
 * publicity relating to the software without the specific, prior written
Packit Service 2594b8
 * permission of Sam Leffler and Silicon Graphics.
Packit Service 2594b8
 * 
Packit Service 2594b8
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
Packit Service 2594b8
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
Packit Service 2594b8
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
Packit Service 2594b8
 * 
Packit Service 2594b8
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
Packit Service 2594b8
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
Packit Service 2594b8
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
Packit Service 2594b8
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
Packit Service 2594b8
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
Packit Service 2594b8
 * OF THIS SOFTWARE.
Packit Service 2594b8
 */
Packit Service 2594b8
Packit Service 2594b8
#ifndef _FAX3_
Packit Service 2594b8
#define	_FAX3_
Packit Service 2594b8
/*
Packit Service 2594b8
 * TIFF Library.
Packit Service 2594b8
 *
Packit Service 2594b8
 * CCITT Group 3 (T.4) and Group 4 (T.6) Decompression Support.
Packit Service 2594b8
 *
Packit Service 2594b8
 * Decoder support is derived, with permission, from the code
Packit Service 2594b8
 * in Frank Cringle's viewfax program;
Packit Service 2594b8
 *      Copyright (C) 1990, 1995  Frank D. Cringle.
Packit Service 2594b8
 */
Packit Service 2594b8
#include "tiff.h"
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * To override the default routine used to image decoded
Packit Service 2594b8
 * spans one can use the pseudo tag TIFFTAG_FAXFILLFUNC.
Packit Service 2594b8
 * The routine must have the type signature given below;
Packit Service 2594b8
 * for example:
Packit Service 2594b8
 *
Packit Service 2594b8
 * fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx)
Packit Service 2594b8
 *
Packit Service 2594b8
 * where buf is place to set the bits, runs is the array of b&w run
Packit Service 2594b8
 * lengths (white then black), erun is the last run in the array, and
Packit Service 2594b8
 * lastx is the width of the row in pixels.  Fill routines can assume
Packit Service 2594b8
 * the run array has room for at least lastx runs and can overwrite
Packit Service 2594b8
 * data in the run array as needed (e.g. to append zero runs to bring
Packit Service 2594b8
 * the count up to a nice multiple).
Packit Service 2594b8
 */
Packit Service 2594b8
typedef void (*TIFFFaxFillFunc)(unsigned char*, uint32*, uint32*, uint32);
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * The default run filler; made external for other decoders.
Packit Service 2594b8
 */
Packit Service 2594b8
#if defined(__cplusplus)
Packit Service 2594b8
extern "C" {
Packit Service 2594b8
#endif
Packit Service 2594b8
extern void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32);
Packit Service 2594b8
#if defined(__cplusplus)
Packit Service 2594b8
}
Packit Service 2594b8
#endif
Packit Service 2594b8
Packit Service 2594b8
Packit Service 2594b8
/* finite state machine codes */
Packit Service 2594b8
#define S_Null     0
Packit Service 2594b8
#define S_Pass     1
Packit Service 2594b8
#define S_Horiz    2
Packit Service 2594b8
#define S_V0       3
Packit Service 2594b8
#define S_VR       4
Packit Service 2594b8
#define S_VL       5
Packit Service 2594b8
#define S_Ext      6
Packit Service 2594b8
#define S_TermW    7
Packit Service 2594b8
#define S_TermB    8
Packit Service 2594b8
#define S_MakeUpW  9
Packit Service 2594b8
#define S_MakeUpB  10
Packit Service 2594b8
#define S_MakeUp   11
Packit Service 2594b8
#define S_EOL      12
Packit Service 2594b8
Packit Service 2594b8
/* WARNING: do not change the layout of this structure as the HylaFAX software */
Packit Service 2594b8
/* really depends on it. See http://bugzilla.maptools.org/show_bug.cgi?id=2636 */
Packit Service 2594b8
typedef struct {                /* state table entry */
Packit Service 2594b8
	unsigned char State;    /* see above */
Packit Service 2594b8
	unsigned char Width;    /* width of code in bits */
Packit Service 2594b8
	uint32 Param;           /* unsigned 32-bit run length in bits (holds on 16 bit actually, but cannot be changed. See above warning) */
Packit Service 2594b8
} TIFFFaxTabEnt;
Packit Service 2594b8
Packit Service 2594b8
extern const TIFFFaxTabEnt TIFFFaxMainTable[];
Packit Service 2594b8
extern const TIFFFaxTabEnt TIFFFaxWhiteTable[];
Packit Service 2594b8
extern const TIFFFaxTabEnt TIFFFaxBlackTable[];
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * The following macros define the majority of the G3/G4 decoder
Packit Service 2594b8
 * algorithm using the state tables defined elsewhere.  To build
Packit Service 2594b8
 * a decoder you need some setup code and some glue code. Note
Packit Service 2594b8
 * that you may also need/want to change the way the NeedBits*
Packit Service 2594b8
 * macros get input data if, for example, you know the data to be
Packit Service 2594b8
 * decoded is properly aligned and oriented (doing so before running
Packit Service 2594b8
 * the decoder can be a big performance win).
Packit Service 2594b8
 *
Packit Service 2594b8
 * Consult the decoder in the TIFF library for an idea of what you
Packit Service 2594b8
 * need to define and setup to make use of these definitions.
Packit Service 2594b8
 *
Packit Service 2594b8
 * NB: to enable a debugging version of these macros define FAX3_DEBUG
Packit Service 2594b8
 *     before including this file.  Trace output goes to stdout.
Packit Service 2594b8
 */
Packit Service 2594b8
Packit Service 2594b8
#ifndef EndOfData
Packit Service 2594b8
#define EndOfData()	(cp >= ep)
Packit Service 2594b8
#endif
Packit Service 2594b8
/*
Packit Service 2594b8
 * Need <=8 or <=16 bits of input data.  Unlike viewfax we
Packit Service 2594b8
 * cannot use/assume a word-aligned, properly bit swizzled
Packit Service 2594b8
 * input data set because data may come from an arbitrarily
Packit Service 2594b8
 * aligned, read-only source such as a memory-mapped file.
Packit Service 2594b8
 * Note also that the viewfax decoder does not check for
Packit Service 2594b8
 * running off the end of the input data buffer.  This is
Packit Service 2594b8
 * possible for G3-encoded data because it prescans the input
Packit Service 2594b8
 * data to count EOL markers, but can cause problems for G4
Packit Service 2594b8
 * data.  In any event, we don't prescan and must watch for
Packit Service 2594b8
 * running out of data since we can't permit the library to
Packit Service 2594b8
 * scan past the end of the input data buffer.
Packit Service 2594b8
 *
Packit Service 2594b8
 * Finally, note that we must handle remaindered data at the end
Packit Service 2594b8
 * of a strip specially.  The coder asks for a fixed number of
Packit Service 2594b8
 * bits when scanning for the next code.  This may be more bits
Packit Service 2594b8
 * than are actually present in the data stream.  If we appear
Packit Service 2594b8
 * to run out of data but still have some number of valid bits
Packit Service 2594b8
 * remaining then we makeup the requested amount with zeros and
Packit Service 2594b8
 * return successfully.  If the returned data is incorrect then
Packit Service 2594b8
 * we should be called again and get a premature EOF error;
Packit Service 2594b8
 * otherwise we should get the right answer.
Packit Service 2594b8
 */
Packit Service 2594b8
#ifndef NeedBits8
Packit Service 2594b8
#define NeedBits8(n,eoflab) do {					\
Packit Service 2594b8
    if (BitsAvail < (n)) {						\
Packit Service 2594b8
	if (EndOfData()) {						\
Packit Service 2594b8
	    if (BitsAvail == 0)			/* no valid bits */	\
Packit Service 2594b8
		goto eoflab;						\
Packit Service 2594b8
	    BitsAvail = (n);			/* pad with zeros */	\
Packit Service 2594b8
	} else {							\
Packit Service 2594b8
	    BitAcc |= ((uint32) bitmap[*cp++])<
Packit Service 2594b8
	    BitsAvail += 8;						\
Packit Service 2594b8
	}								\
Packit Service 2594b8
    }									\
Packit Service 2594b8
} while (0)
Packit Service 2594b8
#endif
Packit Service 2594b8
#ifndef NeedBits16
Packit Service 2594b8
#define NeedBits16(n,eoflab) do {					\
Packit Service 2594b8
    if (BitsAvail < (n)) {						\
Packit Service 2594b8
	if (EndOfData()) {						\
Packit Service 2594b8
	    if (BitsAvail == 0)			/* no valid bits */	\
Packit Service 2594b8
		goto eoflab;						\
Packit Service 2594b8
	    BitsAvail = (n);			/* pad with zeros */	\
Packit Service 2594b8
	} else {							\
Packit Service 2594b8
	    BitAcc |= ((uint32) bitmap[*cp++])<
Packit Service 2594b8
	    if ((BitsAvail += 8) < (n)) {				\
Packit Service 2594b8
		if (EndOfData()) {					\
Packit Service 2594b8
		    /* NB: we know BitsAvail is non-zero here */	\
Packit Service 2594b8
		    BitsAvail = (n);		/* pad with zeros */	\
Packit Service 2594b8
		} else {						\
Packit Service 2594b8
		    BitAcc |= ((uint32) bitmap[*cp++])<
Packit Service 2594b8
		    BitsAvail += 8;					\
Packit Service 2594b8
		}							\
Packit Service 2594b8
	    }								\
Packit Service 2594b8
	}								\
Packit Service 2594b8
    }									\
Packit Service 2594b8
} while (0)
Packit Service 2594b8
#endif
Packit Service 2594b8
#define GetBits(n)	(BitAcc & ((1<<(n))-1))
Packit Service 2594b8
#define ClrBits(n) do {							\
Packit Service 2594b8
    BitsAvail -= (n);							\
Packit Service 2594b8
    BitAcc >>= (n);							\
Packit Service 2594b8
} while (0)
Packit Service 2594b8
Packit Service 2594b8
#ifdef FAX3_DEBUG
Packit Service 2594b8
static const char* StateNames[] = {
Packit Service 2594b8
    "Null   ",
Packit Service 2594b8
    "Pass   ",
Packit Service 2594b8
    "Horiz  ",
Packit Service 2594b8
    "V0     ",
Packit Service 2594b8
    "VR     ",
Packit Service 2594b8
    "VL     ",
Packit Service 2594b8
    "Ext    ",
Packit Service 2594b8
    "TermW  ",
Packit Service 2594b8
    "TermB  ",
Packit Service 2594b8
    "MakeUpW",
Packit Service 2594b8
    "MakeUpB",
Packit Service 2594b8
    "MakeUp ",
Packit Service 2594b8
    "EOL    ",
Packit Service 2594b8
};
Packit Service 2594b8
#define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0')
Packit Service 2594b8
#define LOOKUP8(wid,tab,eoflab) do {					\
Packit Service 2594b8
    int t;								\
Packit Service 2594b8
    NeedBits8(wid,eoflab);						\
Packit Service 2594b8
    TabEnt = tab + GetBits(wid);					\
Packit Service 2594b8
    printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail,		\
Packit Service 2594b8
	   StateNames[TabEnt->State], TabEnt->Param);			\
Packit Service 2594b8
    for (t = 0; t < TabEnt->Width; t++)					\
Packit Service 2594b8
	DEBUG_SHOW;							\
Packit Service 2594b8
    putchar('\n');							\
Packit Service 2594b8
    fflush(stdout);							\
Packit Service 2594b8
    ClrBits(TabEnt->Width);						\
Packit Service 2594b8
} while (0)
Packit Service 2594b8
#define LOOKUP16(wid,tab,eoflab) do {					\
Packit Service 2594b8
    int t;								\
Packit Service 2594b8
    NeedBits16(wid,eoflab);						\
Packit Service 2594b8
    TabEnt = tab + GetBits(wid);					\
Packit Service 2594b8
    printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail,		\
Packit Service 2594b8
	   StateNames[TabEnt->State], TabEnt->Param);			\
Packit Service 2594b8
    for (t = 0; t < TabEnt->Width; t++)					\
Packit Service 2594b8
	DEBUG_SHOW;							\
Packit Service 2594b8
    putchar('\n');							\
Packit Service 2594b8
    fflush(stdout);							\
Packit Service 2594b8
    ClrBits(TabEnt->Width);						\
Packit Service 2594b8
} while (0)
Packit Service 2594b8
Packit Service 2594b8
#define SETVALUE(x) do {							\
Packit Service 2594b8
    *pa++ = RunLength + (x);						\
Packit Service 2594b8
    printf("SETVALUE: %d\t%d\n", RunLength + (x), a0);			\
Packit Service 2594b8
    a0 += x;								\
Packit Service 2594b8
    RunLength = 0;							\
Packit Service 2594b8
} while (0)
Packit Service 2594b8
#else
Packit Service 2594b8
#define LOOKUP8(wid,tab,eoflab) do {					\
Packit Service 2594b8
    NeedBits8(wid,eoflab);						\
Packit Service 2594b8
    TabEnt = tab + GetBits(wid);					\
Packit Service 2594b8
    ClrBits(TabEnt->Width);						\
Packit Service 2594b8
} while (0)
Packit Service 2594b8
#define LOOKUP16(wid,tab,eoflab) do {					\
Packit Service 2594b8
    NeedBits16(wid,eoflab);						\
Packit Service 2594b8
    TabEnt = tab + GetBits(wid);					\
Packit Service 2594b8
    ClrBits(TabEnt->Width);						\
Packit Service 2594b8
} while (0)
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Append a run to the run length array for the
Packit Service 2594b8
 * current row and reset decoding state.
Packit Service 2594b8
 */
Packit Service 2594b8
#define SETVALUE(x) do {							\
Packit Service 2594b8
    *pa++ = RunLength + (x);						\
Packit Service 2594b8
    a0 += (x);								\
Packit Service 2594b8
    RunLength = 0;							\
Packit Service 2594b8
} while (0)
Packit Service 2594b8
#endif
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Synchronize input decoding at the start of each
Packit Service 2594b8
 * row by scanning for an EOL (if appropriate) and
Packit Service 2594b8
 * skipping any trash data that might be present
Packit Service 2594b8
 * after a decoding error.  Note that the decoding
Packit Service 2594b8
 * done elsewhere that recognizes an EOL only consumes
Packit Service 2594b8
 * 11 consecutive zero bits.  This means that if EOLcnt
Packit Service 2594b8
 * is non-zero then we still need to scan for the final flag
Packit Service 2594b8
 * bit that is part of the EOL code.
Packit Service 2594b8
 */
Packit Service 2594b8
#define	SYNC_EOL(eoflab) do {						\
Packit Service 2594b8
    if (EOLcnt == 0) {							\
Packit Service 2594b8
	for (;;) {							\
Packit Service 2594b8
	    NeedBits16(11,eoflab);					\
Packit Service 2594b8
	    if (GetBits(11) == 0)					\
Packit Service 2594b8
		break;							\
Packit Service 2594b8
	    ClrBits(1);							\
Packit Service 2594b8
	}								\
Packit Service 2594b8
    }									\
Packit Service 2594b8
    for (;;) {								\
Packit Service 2594b8
	NeedBits8(8,eoflab);						\
Packit Service 2594b8
	if (GetBits(8))							\
Packit Service 2594b8
	    break;							\
Packit Service 2594b8
	ClrBits(8);							\
Packit Service 2594b8
    }									\
Packit Service 2594b8
    while (GetBits(1) == 0)						\
Packit Service 2594b8
	ClrBits(1);							\
Packit Service 2594b8
    ClrBits(1);				/* EOL bit */			\
Packit Service 2594b8
    EOLcnt = 0;				/* reset EOL counter/flag */	\
Packit Service 2594b8
} while (0)
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Cleanup the array of runs after decoding a row.
Packit Service 2594b8
 * We adjust final runs to insure the user buffer is not
Packit Service 2594b8
 * overwritten and/or undecoded area is white filled.
Packit Service 2594b8
 */
Packit Service 2594b8
#define	CLEANUP_RUNS() do {						\
Packit Service 2594b8
    if (RunLength)							\
Packit Service 2594b8
	SETVALUE(0);							\
Packit Service 2594b8
    if (a0 != lastx) {							\
Packit Service 2594b8
	badlength(a0, lastx);						\
Packit Service 2594b8
	while (a0 > lastx && pa > thisrun)				\
Packit Service 2594b8
	    a0 -= *--pa;						\
Packit Service 2594b8
	if (a0 < lastx) {						\
Packit Service 2594b8
	    if (a0 < 0)							\
Packit Service 2594b8
		a0 = 0;							\
Packit Service 2594b8
	    if ((pa-thisrun)&1)						\
Packit Service 2594b8
		SETVALUE(0);						\
Packit Service 2594b8
	    SETVALUE(lastx - a0);						\
Packit Service 2594b8
	} else if (a0 > lastx) {					\
Packit Service 2594b8
	    SETVALUE(lastx);						\
Packit Service 2594b8
	    SETVALUE(0);							\
Packit Service 2594b8
	}								\
Packit Service 2594b8
    }									\
Packit Service 2594b8
} while (0)
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Decode a line of 1D-encoded data.
Packit Service 2594b8
 *
Packit Service 2594b8
 * The line expanders are written as macros so that they can be reused
Packit Service 2594b8
 * but still have direct access to the local variables of the "calling"
Packit Service 2594b8
 * function.
Packit Service 2594b8
 *
Packit Service 2594b8
 * Note that unlike the original version we have to explicitly test for
Packit Service 2594b8
 * a0 >= lastx after each black/white run is decoded.  This is because
Packit Service 2594b8
 * the original code depended on the input data being zero-padded to
Packit Service 2594b8
 * insure the decoder recognized an EOL before running out of data.
Packit Service 2594b8
 */
Packit Service 2594b8
#define EXPAND1D(eoflab) do {						\
Packit Service 2594b8
    for (;;) {								\
Packit Service 2594b8
	for (;;) {							\
Packit Service 2594b8
	    LOOKUP16(12, TIFFFaxWhiteTable, eof1d);			\
Packit Service 2594b8
	    switch (TabEnt->State) {					\
Packit Service 2594b8
	    case S_EOL:							\
Packit Service 2594b8
		EOLcnt = 1;						\
Packit Service 2594b8
		goto done1d;						\
Packit Service 2594b8
	    case S_TermW:						\
Packit Service 2594b8
		SETVALUE(TabEnt->Param);					\
Packit Service 2594b8
		goto doneWhite1d;					\
Packit Service 2594b8
	    case S_MakeUpW:						\
Packit Service 2594b8
	    case S_MakeUp:						\
Packit Service 2594b8
		a0 += TabEnt->Param;					\
Packit Service 2594b8
		RunLength += TabEnt->Param;				\
Packit Service 2594b8
		break;							\
Packit Service 2594b8
	    default:							\
Packit Service 2594b8
		unexpected("WhiteTable", a0);				\
Packit Service 2594b8
		goto done1d;						\
Packit Service 2594b8
	    }								\
Packit Service 2594b8
	}								\
Packit Service 2594b8
    doneWhite1d:							\
Packit Service 2594b8
	if (a0 >= lastx)						\
Packit Service 2594b8
	    goto done1d;						\
Packit Service 2594b8
	for (;;) {							\
Packit Service 2594b8
	    LOOKUP16(13, TIFFFaxBlackTable, eof1d);			\
Packit Service 2594b8
	    switch (TabEnt->State) {					\
Packit Service 2594b8
	    case S_EOL:							\
Packit Service 2594b8
		EOLcnt = 1;						\
Packit Service 2594b8
		goto done1d;						\
Packit Service 2594b8
	    case S_TermB:						\
Packit Service 2594b8
		SETVALUE(TabEnt->Param);					\
Packit Service 2594b8
		goto doneBlack1d;					\
Packit Service 2594b8
	    case S_MakeUpB:						\
Packit Service 2594b8
	    case S_MakeUp:						\
Packit Service 2594b8
		a0 += TabEnt->Param;					\
Packit Service 2594b8
		RunLength += TabEnt->Param;				\
Packit Service 2594b8
		break;							\
Packit Service 2594b8
	    default:							\
Packit Service 2594b8
		unexpected("BlackTable", a0);				\
Packit Service 2594b8
		goto done1d;						\
Packit Service 2594b8
	    }								\
Packit Service 2594b8
	}								\
Packit Service 2594b8
    doneBlack1d:							\
Packit Service 2594b8
	if (a0 >= lastx)						\
Packit Service 2594b8
	    goto done1d;						\
Packit Service 2594b8
        if( *(pa-1) == 0 && *(pa-2) == 0 )				\
Packit Service 2594b8
            pa -= 2;                                                    \
Packit Service 2594b8
    }									\
Packit Service 2594b8
eof1d:									\
Packit Service 2594b8
    prematureEOF(a0);							\
Packit Service 2594b8
    CLEANUP_RUNS();							\
Packit Service 2594b8
    goto eoflab;							\
Packit Service 2594b8
done1d:									\
Packit Service 2594b8
    CLEANUP_RUNS();							\
Packit Service 2594b8
} while (0)
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Update the value of b1 using the array
Packit Service 2594b8
 * of runs for the reference line.
Packit Service 2594b8
 */
Packit Service 2594b8
#define CHECK_b1 do {							\
Packit Service 2594b8
    if (pa != thisrun) while (b1 <= a0 && b1 < lastx) {			\
Packit Service 2594b8
	b1 += pb[0] + pb[1];						\
Packit Service 2594b8
	pb += 2;							\
Packit Service 2594b8
    }									\
Packit Service 2594b8
} while (0)
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Expand a row of 2D-encoded data.
Packit Service 2594b8
 */
Packit Service 2594b8
#define EXPAND2D(eoflab) do {						\
Packit Service 2594b8
    while (a0 < lastx) {						\
Packit Service 2594b8
	LOOKUP8(7, TIFFFaxMainTable, eof2d);				\
Packit Service 2594b8
	switch (TabEnt->State) {					\
Packit Service 2594b8
	case S_Pass:							\
Packit Service 2594b8
	    CHECK_b1;							\
Packit Service 2594b8
	    b1 += *pb++;						\
Packit Service 2594b8
	    RunLength += b1 - a0;					\
Packit Service 2594b8
	    a0 = b1;							\
Packit Service 2594b8
	    b1 += *pb++;						\
Packit Service 2594b8
	    break;							\
Packit Service 2594b8
	case S_Horiz:							\
Packit Service 2594b8
	    if ((pa-thisrun)&1) {					\
Packit Service 2594b8
		for (;;) {	/* black first */			\
Packit Service 2594b8
		    LOOKUP16(13, TIFFFaxBlackTable, eof2d);		\
Packit Service 2594b8
		    switch (TabEnt->State) {				\
Packit Service 2594b8
		    case S_TermB:					\
Packit Service 2594b8
			SETVALUE(TabEnt->Param);				\
Packit Service 2594b8
			goto doneWhite2da;				\
Packit Service 2594b8
		    case S_MakeUpB:					\
Packit Service 2594b8
		    case S_MakeUp:					\
Packit Service 2594b8
			a0 += TabEnt->Param;				\
Packit Service 2594b8
			RunLength += TabEnt->Param;			\
Packit Service 2594b8
			break;						\
Packit Service 2594b8
		    default:						\
Packit Service 2594b8
			goto badBlack2d;				\
Packit Service 2594b8
		    }							\
Packit Service 2594b8
		}							\
Packit Service 2594b8
	    doneWhite2da:;						\
Packit Service 2594b8
		for (;;) {	/* then white */			\
Packit Service 2594b8
		    LOOKUP16(12, TIFFFaxWhiteTable, eof2d);		\
Packit Service 2594b8
		    switch (TabEnt->State) {				\
Packit Service 2594b8
		    case S_TermW:					\
Packit Service 2594b8
			SETVALUE(TabEnt->Param);				\
Packit Service 2594b8
			goto doneBlack2da;				\
Packit Service 2594b8
		    case S_MakeUpW:					\
Packit Service 2594b8
		    case S_MakeUp:					\
Packit Service 2594b8
			a0 += TabEnt->Param;				\
Packit Service 2594b8
			RunLength += TabEnt->Param;			\
Packit Service 2594b8
			break;						\
Packit Service 2594b8
		    default:						\
Packit Service 2594b8
			goto badWhite2d;				\
Packit Service 2594b8
		    }							\
Packit Service 2594b8
		}							\
Packit Service 2594b8
	    doneBlack2da:;						\
Packit Service 2594b8
	    } else {							\
Packit Service 2594b8
		for (;;) {	/* white first */			\
Packit Service 2594b8
		    LOOKUP16(12, TIFFFaxWhiteTable, eof2d);		\
Packit Service 2594b8
		    switch (TabEnt->State) {				\
Packit Service 2594b8
		    case S_TermW:					\
Packit Service 2594b8
			SETVALUE(TabEnt->Param);				\
Packit Service 2594b8
			goto doneWhite2db;				\
Packit Service 2594b8
		    case S_MakeUpW:					\
Packit Service 2594b8
		    case S_MakeUp:					\
Packit Service 2594b8
			a0 += TabEnt->Param;				\
Packit Service 2594b8
			RunLength += TabEnt->Param;			\
Packit Service 2594b8
			break;						\
Packit Service 2594b8
		    default:						\
Packit Service 2594b8
			goto badWhite2d;				\
Packit Service 2594b8
		    }							\
Packit Service 2594b8
		}							\
Packit Service 2594b8
	    doneWhite2db:;						\
Packit Service 2594b8
		for (;;) {	/* then black */			\
Packit Service 2594b8
		    LOOKUP16(13, TIFFFaxBlackTable, eof2d);		\
Packit Service 2594b8
		    switch (TabEnt->State) {				\
Packit Service 2594b8
		    case S_TermB:					\
Packit Service 2594b8
			SETVALUE(TabEnt->Param);				\
Packit Service 2594b8
			goto doneBlack2db;				\
Packit Service 2594b8
		    case S_MakeUpB:					\
Packit Service 2594b8
		    case S_MakeUp:					\
Packit Service 2594b8
			a0 += TabEnt->Param;				\
Packit Service 2594b8
			RunLength += TabEnt->Param;			\
Packit Service 2594b8
			break;						\
Packit Service 2594b8
		    default:						\
Packit Service 2594b8
			goto badBlack2d;				\
Packit Service 2594b8
		    }							\
Packit Service 2594b8
		}							\
Packit Service 2594b8
	    doneBlack2db:;						\
Packit Service 2594b8
	    }								\
Packit Service 2594b8
	    CHECK_b1;							\
Packit Service 2594b8
	    break;							\
Packit Service 2594b8
	case S_V0:							\
Packit Service 2594b8
	    CHECK_b1;							\
Packit Service 2594b8
	    SETVALUE(b1 - a0);						\
Packit Service 2594b8
	    b1 += *pb++;						\
Packit Service 2594b8
	    break;							\
Packit Service 2594b8
	case S_VR:							\
Packit Service 2594b8
	    CHECK_b1;							\
Packit Service 2594b8
	    SETVALUE(b1 - a0 + TabEnt->Param);				\
Packit Service 2594b8
	    b1 += *pb++;						\
Packit Service 2594b8
	    break;							\
Packit Service 2594b8
	case S_VL:							\
Packit Service 2594b8
	    CHECK_b1;							\
Packit Service 2594b8
	    if (b1 <= (int) (a0 + TabEnt->Param)) {			\
Packit Service 2594b8
		if (b1 < (int) (a0 + TabEnt->Param) || pa != thisrun) {	\
Packit Service 2594b8
		    unexpected("VL", a0);				\
Packit Service 2594b8
		    goto eol2d;						\
Packit Service 2594b8
		}							\
Packit Service 2594b8
	    }								\
Packit Service 2594b8
	    SETVALUE(b1 - a0 - TabEnt->Param);				\
Packit Service 2594b8
	    b1 -= *--pb;						\
Packit Service 2594b8
	    break;							\
Packit Service 2594b8
	case S_Ext:							\
Packit Service 2594b8
	    *pa++ = lastx - a0;						\
Packit Service 2594b8
	    extension(a0);						\
Packit Service 2594b8
	    goto eol2d;							\
Packit Service 2594b8
	case S_EOL:							\
Packit Service 2594b8
	    *pa++ = lastx - a0;						\
Packit Service 2594b8
	    NeedBits8(4,eof2d);						\
Packit Service 2594b8
	    if (GetBits(4))						\
Packit Service 2594b8
		unexpected("EOL", a0);					\
Packit Service 2594b8
            ClrBits(4);                                                 \
Packit Service 2594b8
	    EOLcnt = 1;							\
Packit Service 2594b8
	    goto eol2d;							\
Packit Service 2594b8
	default:							\
Packit Service 2594b8
	badMain2d:							\
Packit Service 2594b8
	    unexpected("MainTable", a0);				\
Packit Service 2594b8
	    goto eol2d;							\
Packit Service 2594b8
	badBlack2d:							\
Packit Service 2594b8
	    unexpected("BlackTable", a0);				\
Packit Service 2594b8
	    goto eol2d;							\
Packit Service 2594b8
	badWhite2d:							\
Packit Service 2594b8
	    unexpected("WhiteTable", a0);				\
Packit Service 2594b8
	    goto eol2d;							\
Packit Service 2594b8
	eof2d:								\
Packit Service 2594b8
	    prematureEOF(a0);						\
Packit Service 2594b8
	    CLEANUP_RUNS();						\
Packit Service 2594b8
	    goto eoflab;						\
Packit Service 2594b8
	}								\
Packit Service 2594b8
    }									\
Packit Service 2594b8
    if (RunLength) {							\
Packit Service 2594b8
	if (RunLength + a0 < lastx) {					\
Packit Service 2594b8
	    /* expect a final V0 */					\
Packit Service 2594b8
	    NeedBits8(1,eof2d);						\
Packit Service 2594b8
	    if (!GetBits(1))						\
Packit Service 2594b8
		goto badMain2d;						\
Packit Service 2594b8
	    ClrBits(1);							\
Packit Service 2594b8
	}								\
Packit Service 2594b8
	SETVALUE(0);							\
Packit Service 2594b8
    }									\
Packit Service 2594b8
eol2d:									\
Packit Service 2594b8
    CLEANUP_RUNS();							\
Packit Service 2594b8
} while (0)
Packit Service 2594b8
#endif /* _FAX3_ */
Packit Service 2594b8
/*
Packit Service 2594b8
 * Local Variables:
Packit Service 2594b8
 * mode: c
Packit Service 2594b8
 * c-basic-offset: 8
Packit Service 2594b8
 * fill-column: 78
Packit Service 2594b8
 * End:
Packit Service 2594b8
 */