Home | History | Annotate | Download | only in libtiff
      1 /* $Id: tif_fax3.h,v 1.9 2011-03-10 20:23:07 fwarmerdam Exp $ */
      2 
      3 /*
      4  * Copyright (c) 1990-1997 Sam Leffler
      5  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
      6  *
      7  * Permission to use, copy, modify, distribute, and sell this software and
      8  * its documentation for any purpose is hereby granted without fee, provided
      9  * that (i) the above copyright notices and this permission notice appear in
     10  * all copies of the software and related documentation, and (ii) the names of
     11  * Sam Leffler and Silicon Graphics may not be used in any advertising or
     12  * publicity relating to the software without the specific, prior written
     13  * permission of Sam Leffler and Silicon Graphics.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
     16  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
     17  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
     18  *
     19  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
     20  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
     21  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
     22  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
     23  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
     24  * OF THIS SOFTWARE.
     25  */
     26 
     27 #ifndef _FAX3_
     28 #define	_FAX3_
     29 /*
     30  * TIFF Library.
     31  *
     32  * CCITT Group 3 (T.4) and Group 4 (T.6) Decompression Support.
     33  *
     34  * Decoder support is derived, with permission, from the code
     35  * in Frank Cringle's viewfax program;
     36  *      Copyright (C) 1990, 1995  Frank D. Cringle.
     37  */
     38 #include "tiff.h"
     39 
     40 /*
     41  * To override the default routine used to image decoded
     42  * spans one can use the pseduo tag TIFFTAG_FAXFILLFUNC.
     43  * The routine must have the type signature given below;
     44  * for example:
     45  *
     46  * fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx)
     47  *
     48  * where buf is place to set the bits, runs is the array of b&w run
     49  * lengths (white then black), erun is the last run in the array, and
     50  * lastx is the width of the row in pixels.  Fill routines can assume
     51  * the run array has room for at least lastx runs and can overwrite
     52  * data in the run array as needed (e.g. to append zero runs to bring
     53  * the count up to a nice multiple).
     54  */
     55 typedef void (*TIFFFaxFillFunc)(unsigned char*, uint32*, uint32*, uint32);
     56 
     57 /*
     58  * The default run filler; made external for other decoders.
     59  */
     60 #if defined(__cplusplus)
     61 extern "C" {
     62 #endif
     63 extern void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32);
     64 #if defined(__cplusplus)
     65 }
     66 #endif
     67 
     68 
     69 /* finite state machine codes */
     70 #define S_Null     0
     71 #define S_Pass     1
     72 #define S_Horiz    2
     73 #define S_V0       3
     74 #define S_VR       4
     75 #define S_VL       5
     76 #define S_Ext      6
     77 #define S_TermW    7
     78 #define S_TermB    8
     79 #define S_MakeUpW  9
     80 #define S_MakeUpB  10
     81 #define S_MakeUp   11
     82 #define S_EOL      12
     83 
     84 typedef struct {                /* state table entry */
     85     unsigned char State;    /* see above */
     86     unsigned char Width;    /* width of code in bits */
     87     uint32 Param;           /* unsigned 32-bit run length in bits */
     88 } TIFFFaxTabEnt;
     89 
     90 extern const TIFFFaxTabEnt TIFFFaxMainTable[];
     91 extern const TIFFFaxTabEnt TIFFFaxWhiteTable[];
     92 extern const TIFFFaxTabEnt TIFFFaxBlackTable[];
     93 
     94 /*
     95  * The following macros define the majority of the G3/G4 decoder
     96  * algorithm using the state tables defined elsewhere.  To build
     97  * a decoder you need some setup code and some glue code. Note
     98  * that you may also need/want to change the way the NeedBits*
     99  * macros get input data if, for example, you know the data to be
    100  * decoded is properly aligned and oriented (doing so before running
    101  * the decoder can be a big performance win).
    102  *
    103  * Consult the decoder in the TIFF library for an idea of what you
    104  * need to define and setup to make use of these definitions.
    105  *
    106  * NB: to enable a debugging version of these macros define FAX3_DEBUG
    107  *     before including this file.  Trace output goes to stdout.
    108  */
    109 
    110 #ifndef EndOfData
    111 #define EndOfData()	(cp >= ep)
    112 #endif
    113 /*
    114  * Need <=8 or <=16 bits of input data.  Unlike viewfax we
    115  * cannot use/assume a word-aligned, properly bit swizzled
    116  * input data set because data may come from an arbitrarily
    117  * aligned, read-only source such as a memory-mapped file.
    118  * Note also that the viewfax decoder does not check for
    119  * running off the end of the input data buffer.  This is
    120  * possible for G3-encoded data because it prescans the input
    121  * data to count EOL markers, but can cause problems for G4
    122  * data.  In any event, we don't prescan and must watch for
    123  * running out of data since we can't permit the library to
    124  * scan past the end of the input data buffer.
    125  *
    126  * Finally, note that we must handle remaindered data at the end
    127  * of a strip specially.  The coder asks for a fixed number of
    128  * bits when scanning for the next code.  This may be more bits
    129  * than are actually present in the data stream.  If we appear
    130  * to run out of data but still have some number of valid bits
    131  * remaining then we makeup the requested amount with zeros and
    132  * return successfully.  If the returned data is incorrect then
    133  * we should be called again and get a premature EOF error;
    134  * otherwise we should get the right answer.
    135  */
    136 #ifndef NeedBits8
    137 #define NeedBits8(n,eoflab) do {					\
    138     if (BitsAvail < (n)) {						\
    139     if (EndOfData()) {						\
    140         if (BitsAvail == 0)			/* no valid bits */	\
    141         goto eoflab;						\
    142         BitsAvail = (n);			/* pad with zeros */	\
    143     } else {							\
    144         BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;		\
    145         BitsAvail += 8;						\
    146     }								\
    147     }									\
    148 } while (0)
    149 #endif
    150 #ifndef NeedBits16
    151 #define NeedBits16(n,eoflab) do {					\
    152     if (BitsAvail < (n)) {						\
    153     if (EndOfData()) {						\
    154         if (BitsAvail == 0)			/* no valid bits */	\
    155         goto eoflab;						\
    156         BitsAvail = (n);			/* pad with zeros */	\
    157     } else {							\
    158         BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;		\
    159         if ((BitsAvail += 8) < (n)) {				\
    160         if (EndOfData()) {					\
    161             /* NB: we know BitsAvail is non-zero here */	\
    162             BitsAvail = (n);		/* pad with zeros */	\
    163         } else {						\
    164             BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;	\
    165             BitsAvail += 8;					\
    166         }							\
    167         }								\
    168     }								\
    169     }									\
    170 } while (0)
    171 #endif
    172 #define GetBits(n)	(BitAcc & ((1<<(n))-1))
    173 #define ClrBits(n) do {							\
    174     BitsAvail -= (n);							\
    175     BitAcc >>= (n);							\
    176 } while (0)
    177 
    178 #ifdef FAX3_DEBUG
    179 static const char* StateNames[] = {
    180     "Null   ",
    181     "Pass   ",
    182     "Horiz  ",
    183     "V0     ",
    184     "VR     ",
    185     "VL     ",
    186     "Ext    ",
    187     "TermW  ",
    188     "TermB  ",
    189     "MakeUpW",
    190     "MakeUpB",
    191     "MakeUp ",
    192     "EOL    ",
    193 };
    194 #define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0')
    195 #define LOOKUP8(wid,tab,eoflab) do {					\
    196     int t;								\
    197     NeedBits8(wid,eoflab);						\
    198     TabEnt = tab + GetBits(wid);					\
    199     printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail,		\
    200        StateNames[TabEnt->State], TabEnt->Param);			\
    201     for (t = 0; t < TabEnt->Width; t++)					\
    202     DEBUG_SHOW;							\
    203     putchar('\n');							\
    204     fflush(stdout);							\
    205     ClrBits(TabEnt->Width);						\
    206 } while (0)
    207 #define LOOKUP16(wid,tab,eoflab) do {					\
    208     int t;								\
    209     NeedBits16(wid,eoflab);						\
    210     TabEnt = tab + GetBits(wid);					\
    211     printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail,		\
    212        StateNames[TabEnt->State], TabEnt->Param);			\
    213     for (t = 0; t < TabEnt->Width; t++)					\
    214     DEBUG_SHOW;							\
    215     putchar('\n');							\
    216     fflush(stdout);							\
    217     ClrBits(TabEnt->Width);						\
    218 } while (0)
    219 
    220 #define SETVALUE(x) do {							\
    221     *pa++ = RunLength + (x);						\
    222     printf("SETVALUE: %d\t%d\n", RunLength + (x), a0);			\
    223     a0 += x;								\
    224     RunLength = 0;							\
    225 } while (0)
    226 #else
    227 #define LOOKUP8(wid,tab,eoflab) do {					\
    228     NeedBits8(wid,eoflab);						\
    229     TabEnt = tab + GetBits(wid);					\
    230     ClrBits(TabEnt->Width);						\
    231 } while (0)
    232 #define LOOKUP16(wid,tab,eoflab) do {					\
    233     NeedBits16(wid,eoflab);						\
    234     TabEnt = tab + GetBits(wid);					\
    235     ClrBits(TabEnt->Width);						\
    236 } while (0)
    237 
    238 /*
    239  * Append a run to the run length array for the
    240  * current row and reset decoding state.
    241  */
    242 #define SETVALUE(x) do {							\
    243     *pa++ = RunLength + (x);						\
    244     a0 += (x);								\
    245     RunLength = 0;							\
    246 } while (0)
    247 #endif
    248 
    249 /*
    250  * Synchronize input decoding at the start of each
    251  * row by scanning for an EOL (if appropriate) and
    252  * skipping any trash data that might be present
    253  * after a decoding error.  Note that the decoding
    254  * done elsewhere that recognizes an EOL only consumes
    255  * 11 consecutive zero bits.  This means that if EOLcnt
    256  * is non-zero then we still need to scan for the final flag
    257  * bit that is part of the EOL code.
    258  */
    259 #define	SYNC_EOL(eoflab) do {						\
    260     if (EOLcnt == 0) {							\
    261     for (;;) {							\
    262         NeedBits16(11,eoflab);					\
    263         if (GetBits(11) == 0)					\
    264         break;							\
    265         ClrBits(1);							\
    266     }								\
    267     }									\
    268     for (;;) {								\
    269     NeedBits8(8,eoflab);						\
    270     if (GetBits(8))							\
    271         break;							\
    272     ClrBits(8);							\
    273     }									\
    274     while (GetBits(1) == 0)						\
    275     ClrBits(1);							\
    276     ClrBits(1);				/* EOL bit */			\
    277     EOLcnt = 0;				/* reset EOL counter/flag */	\
    278 } while (0)
    279 
    280 /*
    281  * Cleanup the array of runs after decoding a row.
    282  * We adjust final runs to insure the user buffer is not
    283  * overwritten and/or undecoded area is white filled.
    284  */
    285 #define	CLEANUP_RUNS() do {						\
    286     if (RunLength)							\
    287     SETVALUE(0);							\
    288     if (a0 != lastx) {							\
    289     badlength(a0, lastx);						\
    290     while (a0 > lastx && pa > thisrun)				\
    291         a0 -= *--pa;						\
    292     if (a0 < lastx) {						\
    293         if (a0 < 0)							\
    294         a0 = 0;							\
    295         if ((pa-thisrun)&1)						\
    296         SETVALUE(0);						\
    297         SETVALUE(lastx - a0);						\
    298     } else if (a0 > lastx) {					\
    299         SETVALUE(lastx);						\
    300         SETVALUE(0);							\
    301     }								\
    302     }									\
    303 } while (0)
    304 
    305 /*
    306  * Decode a line of 1D-encoded data.
    307  *
    308  * The line expanders are written as macros so that they can be reused
    309  * but still have direct access to the local variables of the "calling"
    310  * function.
    311  *
    312  * Note that unlike the original version we have to explicitly test for
    313  * a0 >= lastx after each black/white run is decoded.  This is because
    314  * the original code depended on the input data being zero-padded to
    315  * insure the decoder recognized an EOL before running out of data.
    316  */
    317 #define EXPAND1D(eoflab) do {						\
    318     for (;;) {								\
    319     for (;;) {							\
    320         LOOKUP16(12, TIFFFaxWhiteTable, eof1d);			\
    321         switch (TabEnt->State) {					\
    322         case S_EOL:							\
    323         EOLcnt = 1;						\
    324         goto done1d;						\
    325         case S_TermW:						\
    326         SETVALUE(TabEnt->Param);					\
    327         goto doneWhite1d;					\
    328         case S_MakeUpW:						\
    329         case S_MakeUp:						\
    330         a0 += TabEnt->Param;					\
    331         RunLength += TabEnt->Param;				\
    332         break;							\
    333         default:							\
    334         unexpected("WhiteTable", a0);				\
    335         goto done1d;						\
    336         }								\
    337     }								\
    338     doneWhite1d:							\
    339     if (a0 >= lastx)						\
    340         goto done1d;						\
    341     for (;;) {							\
    342         LOOKUP16(13, TIFFFaxBlackTable, eof1d);			\
    343         switch (TabEnt->State) {					\
    344         case S_EOL:							\
    345         EOLcnt = 1;						\
    346         goto done1d;						\
    347         case S_TermB:						\
    348         SETVALUE(TabEnt->Param);					\
    349         goto doneBlack1d;					\
    350         case S_MakeUpB:						\
    351         case S_MakeUp:						\
    352         a0 += TabEnt->Param;					\
    353         RunLength += TabEnt->Param;				\
    354         break;							\
    355         default:							\
    356         unexpected("BlackTable", a0);				\
    357         goto done1d;						\
    358         }								\
    359     }								\
    360     doneBlack1d:							\
    361     if (a0 >= lastx)						\
    362         goto done1d;						\
    363         if( *(pa-1) == 0 && *(pa-2) == 0 )				\
    364             pa -= 2;                                                    \
    365     }									\
    366 eof1d:									\
    367     prematureEOF(a0);							\
    368     CLEANUP_RUNS();							\
    369     goto eoflab;							\
    370 done1d:									\
    371     CLEANUP_RUNS();							\
    372 } while (0)
    373 
    374 /*
    375  * Update the value of b1 using the array
    376  * of runs for the reference line.
    377  */
    378 #define CHECK_b1 do {							\
    379     if (pa != thisrun) while (b1 <= a0 && b1 < lastx) {			\
    380     b1 += pb[0] + pb[1];						\
    381     pb += 2;							\
    382     }									\
    383 } while (0)
    384 
    385 /*
    386  * Expand a row of 2D-encoded data.
    387  */
    388 #define EXPAND2D(eoflab) do {						\
    389     while (a0 < lastx) {						\
    390     LOOKUP8(7, TIFFFaxMainTable, eof2d);				\
    391     switch (TabEnt->State) {					\
    392     case S_Pass:							\
    393         CHECK_b1;							\
    394         b1 += *pb++;						\
    395         RunLength += b1 - a0;					\
    396         a0 = b1;							\
    397         b1 += *pb++;						\
    398         break;							\
    399     case S_Horiz:							\
    400         if ((pa-thisrun)&1) {					\
    401         for (;;) {	/* black first */			\
    402             LOOKUP16(13, TIFFFaxBlackTable, eof2d);		\
    403             switch (TabEnt->State) {				\
    404             case S_TermB:					\
    405             SETVALUE(TabEnt->Param);				\
    406             goto doneWhite2da;				\
    407             case S_MakeUpB:					\
    408             case S_MakeUp:					\
    409             a0 += TabEnt->Param;				\
    410             RunLength += TabEnt->Param;			\
    411             break;						\
    412             default:						\
    413             goto badBlack2d;				\
    414             }							\
    415         }							\
    416         doneWhite2da:;						\
    417         for (;;) {	/* then white */			\
    418             LOOKUP16(12, TIFFFaxWhiteTable, eof2d);		\
    419             switch (TabEnt->State) {				\
    420             case S_TermW:					\
    421             SETVALUE(TabEnt->Param);				\
    422             goto doneBlack2da;				\
    423             case S_MakeUpW:					\
    424             case S_MakeUp:					\
    425             a0 += TabEnt->Param;				\
    426             RunLength += TabEnt->Param;			\
    427             break;						\
    428             default:						\
    429             goto badWhite2d;				\
    430             }							\
    431         }							\
    432         doneBlack2da:;						\
    433         } else {							\
    434         for (;;) {	/* white first */			\
    435             LOOKUP16(12, TIFFFaxWhiteTable, eof2d);		\
    436             switch (TabEnt->State) {				\
    437             case S_TermW:					\
    438             SETVALUE(TabEnt->Param);				\
    439             goto doneWhite2db;				\
    440             case S_MakeUpW:					\
    441             case S_MakeUp:					\
    442             a0 += TabEnt->Param;				\
    443             RunLength += TabEnt->Param;			\
    444             break;						\
    445             default:						\
    446             goto badWhite2d;				\
    447             }							\
    448         }							\
    449         doneWhite2db:;						\
    450         for (;;) {	/* then black */			\
    451             LOOKUP16(13, TIFFFaxBlackTable, eof2d);		\
    452             switch (TabEnt->State) {				\
    453             case S_TermB:					\
    454             SETVALUE(TabEnt->Param);				\
    455             goto doneBlack2db;				\
    456             case S_MakeUpB:					\
    457             case S_MakeUp:					\
    458             a0 += TabEnt->Param;				\
    459             RunLength += TabEnt->Param;			\
    460             break;						\
    461             default:						\
    462             goto badBlack2d;				\
    463             }							\
    464         }							\
    465         doneBlack2db:;						\
    466         }								\
    467         CHECK_b1;							\
    468         break;							\
    469     case S_V0:							\
    470         CHECK_b1;							\
    471         SETVALUE(b1 - a0);						\
    472         b1 += *pb++;						\
    473         break;							\
    474     case S_VR:							\
    475         CHECK_b1;							\
    476         SETVALUE(b1 - a0 + TabEnt->Param);				\
    477         b1 += *pb++;						\
    478         break;							\
    479     case S_VL:							\
    480         CHECK_b1;							\
    481         if (b1 <= (int) (a0 + TabEnt->Param)) {			\
    482         if (b1 < (int) (a0 + TabEnt->Param) || pa != thisrun) {	\
    483             unexpected("VL", a0);				\
    484             goto eol2d;						\
    485         }							\
    486         }								\
    487         SETVALUE(b1 - a0 - TabEnt->Param);				\
    488         b1 -= *--pb;						\
    489         break;							\
    490     case S_Ext:							\
    491         *pa++ = lastx - a0;						\
    492         extension(a0);						\
    493         goto eol2d;							\
    494     case S_EOL:							\
    495         *pa++ = lastx - a0;						\
    496         NeedBits8(4,eof2d);						\
    497         if (GetBits(4))						\
    498         unexpected("EOL", a0);					\
    499             ClrBits(4);                                                 \
    500         EOLcnt = 1;							\
    501         goto eol2d;							\
    502     default:							\
    503     badMain2d:							\
    504         unexpected("MainTable", a0);				\
    505         goto eol2d;							\
    506     badBlack2d:							\
    507         unexpected("BlackTable", a0);				\
    508         goto eol2d;							\
    509     badWhite2d:							\
    510         unexpected("WhiteTable", a0);				\
    511         goto eol2d;							\
    512     eof2d:								\
    513         prematureEOF(a0);						\
    514         CLEANUP_RUNS();						\
    515         goto eoflab;						\
    516     }								\
    517     }									\
    518     if (RunLength) {							\
    519     if (RunLength + a0 < lastx) {					\
    520         /* expect a final V0 */					\
    521         NeedBits8(1,eof2d);						\
    522         if (!GetBits(1))						\
    523         goto badMain2d;						\
    524         ClrBits(1);							\
    525     }								\
    526     SETVALUE(0);							\
    527     }									\
    528 eol2d:									\
    529     CLEANUP_RUNS();							\
    530 } while (0)
    531 #endif /* _FAX3_ */
    532 /*
    533  * Local Variables:
    534  * mode: c
    535  * c-basic-offset: 8
    536  * fill-column: 78
    537  * End:
    538  */
    539