PBRT
/home/felix/UBC/projects/AdaptiveLightfieldSampling/pbrt_v2/src/3rdparty/tiff-3.9.4/tif_fax3.h
00001 /* $Id: tif_fax3.h,v 1.5.2.1 2010-06-08 18:50:42 bfriesen Exp $ */
00002 
00003 /*
00004  * Copyright (c) 1990-1997 Sam Leffler
00005  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
00006  *
00007  * Permission to use, copy, modify, distribute, and sell this software and 
00008  * its documentation for any purpose is hereby granted without fee, provided
00009  * that (i) the above copyright notices and this permission notice appear in
00010  * all copies of the software and related documentation, and (ii) the names of
00011  * Sam Leffler and Silicon Graphics may not be used in any advertising or
00012  * publicity relating to the software without the specific, prior written
00013  * permission of Sam Leffler and Silicon Graphics.
00014  * 
00015  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
00016  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
00017  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
00018  * 
00019  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
00020  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
00021  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
00022  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
00023  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
00024  * OF THIS SOFTWARE.
00025  */
00026 
00027 #ifndef _FAX3_
00028 #define _FAX3_
00029 /*
00030  * TIFF Library.
00031  *
00032  * CCITT Group 3 (T.4) and Group 4 (T.6) Decompression Support.
00033  *
00034  * Decoder support is derived, with permission, from the code
00035  * in Frank Cringle's viewfax program;
00036  *      Copyright (C) 1990, 1995  Frank D. Cringle.
00037  */
00038 #include "tiff.h"
00039 
00040 /*
00041  * To override the default routine used to image decoded
00042  * spans one can use the pseduo tag TIFFTAG_FAXFILLFUNC.
00043  * The routine must have the type signature given below;
00044  * for example:
00045  *
00046  * fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx)
00047  *
00048  * where buf is place to set the bits, runs is the array of b&w run
00049  * lengths (white then black), erun is the last run in the array, and
00050  * lastx is the width of the row in pixels.  Fill routines can assume
00051  * the run array has room for at least lastx runs and can overwrite
00052  * data in the run array as needed (e.g. to append zero runs to bring
00053  * the count up to a nice multiple).
00054  */
00055 typedef void (*TIFFFaxFillFunc)(unsigned char*, uint32*, uint32*, uint32);
00056 
00057 /*
00058  * The default run filler; made external for other decoders.
00059  */
00060 #if defined(__cplusplus)
00061 extern "C" {
00062 #endif
00063 extern  void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32);
00064 #if defined(__cplusplus)
00065 }
00066 #endif
00067 
00068 
00069 /* finite state machine codes */
00070 #define S_Null          0
00071 #define S_Pass          1
00072 #define S_Horiz         2
00073 #define S_V0            3
00074 #define S_VR            4
00075 #define S_VL            5
00076 #define S_Ext           6
00077 #define S_TermW         7
00078 #define S_TermB         8
00079 #define S_MakeUpW       9
00080 #define S_MakeUpB       10
00081 #define S_MakeUp        11
00082 #define S_EOL           12
00083 
00084 typedef struct {                /* state table entry */
00085         unsigned char State;    /* see above */
00086         unsigned char Width;    /* width of code in bits */
00087         uint32  Param;          /* unsigned 32-bit run length in bits */
00088 } TIFFFaxTabEnt;
00089 
00090 extern  const TIFFFaxTabEnt TIFFFaxMainTable[];
00091 extern  const TIFFFaxTabEnt TIFFFaxWhiteTable[];
00092 extern  const TIFFFaxTabEnt TIFFFaxBlackTable[];
00093 
00094 /*
00095  * The following macros define the majority of the G3/G4 decoder
00096  * algorithm using the state tables defined elsewhere.  To build
00097  * a decoder you need some setup code and some glue code. Note
00098  * that you may also need/want to change the way the NeedBits*
00099  * macros get input data if, for example, you know the data to be
00100  * decoded is properly aligned and oriented (doing so before running
00101  * the decoder can be a big performance win).
00102  *
00103  * Consult the decoder in the TIFF library for an idea of what you
00104  * need to define and setup to make use of these definitions.
00105  *
00106  * NB: to enable a debugging version of these macros define FAX3_DEBUG
00107  *     before including this file.  Trace output goes to stdout.
00108  */
00109 
00110 #ifndef EndOfData
00111 #define EndOfData()     (cp >= ep)
00112 #endif
00113 /*
00114  * Need <=8 or <=16 bits of input data.  Unlike viewfax we
00115  * cannot use/assume a word-aligned, properly bit swizzled
00116  * input data set because data may come from an arbitrarily
00117  * aligned, read-only source such as a memory-mapped file.
00118  * Note also that the viewfax decoder does not check for
00119  * running off the end of the input data buffer.  This is
00120  * possible for G3-encoded data because it prescans the input
00121  * data to count EOL markers, but can cause problems for G4
00122  * data.  In any event, we don't prescan and must watch for
00123  * running out of data since we can't permit the library to
00124  * scan past the end of the input data buffer.
00125  *
00126  * Finally, note that we must handle remaindered data at the end
00127  * of a strip specially.  The coder asks for a fixed number of
00128  * bits when scanning for the next code.  This may be more bits
00129  * than are actually present in the data stream.  If we appear
00130  * to run out of data but still have some number of valid bits
00131  * remaining then we makeup the requested amount with zeros and
00132  * return successfully.  If the returned data is incorrect then
00133  * we should be called again and get a premature EOF error;
00134  * otherwise we should get the right answer.
00135  */
00136 #ifndef NeedBits8
00137 #define NeedBits8(n,eoflab) do {                                        \
00138     if (BitsAvail < (n)) {                                              \
00139         if (EndOfData()) {                                              \
00140             if (BitsAvail == 0)                 /* no valid bits */     \
00141                 goto eoflab;                                            \
00142             BitsAvail = (n);                    /* pad with zeros */    \
00143         } else {                                                        \
00144             BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;              \
00145             BitsAvail += 8;                                             \
00146         }                                                               \
00147     }                                                                   \
00148 } while (0)
00149 #endif
00150 #ifndef NeedBits16
00151 #define NeedBits16(n,eoflab) do {                                       \
00152     if (BitsAvail < (n)) {                                              \
00153         if (EndOfData()) {                                              \
00154             if (BitsAvail == 0)                 /* no valid bits */     \
00155                 goto eoflab;                                            \
00156             BitsAvail = (n);                    /* pad with zeros */    \
00157         } else {                                                        \
00158             BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;              \
00159             if ((BitsAvail += 8) < (n)) {                               \
00160                 if (EndOfData()) {                                      \
00161                     /* NB: we know BitsAvail is non-zero here */        \
00162                     BitsAvail = (n);            /* pad with zeros */    \
00163                 } else {                                                \
00164                     BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;      \
00165                     BitsAvail += 8;                                     \
00166                 }                                                       \
00167             }                                                           \
00168         }                                                               \
00169     }                                                                   \
00170 } while (0)
00171 #endif
00172 #define GetBits(n)      (BitAcc & ((1<<(n))-1))
00173 #define ClrBits(n) do {                                                 \
00174     BitsAvail -= (n);                                                   \
00175     BitAcc >>= (n);                                                     \
00176 } while (0)
00177 
00178 #ifdef FAX3_DEBUG
00179 static const char* StateNames[] = {
00180     "Null   ",
00181     "Pass   ",
00182     "Horiz  ",
00183     "V0     ",
00184     "VR     ",
00185     "VL     ",
00186     "Ext    ",
00187     "TermW  ",
00188     "TermB  ",
00189     "MakeUpW",
00190     "MakeUpB",
00191     "MakeUp ",
00192     "EOL    ",
00193 };
00194 #define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0')
00195 #define LOOKUP8(wid,tab,eoflab) do {                                    \
00196     int t;                                                              \
00197     NeedBits8(wid,eoflab);                                              \
00198     TabEnt = tab + GetBits(wid);                                        \
00199     printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail,               \
00200            StateNames[TabEnt->State], TabEnt->Param);                   \
00201     for (t = 0; t < TabEnt->Width; t++)                                 \
00202         DEBUG_SHOW;                                                     \
00203     putchar('\n');                                                      \
00204     fflush(stdout);                                                     \
00205     ClrBits(TabEnt->Width);                                             \
00206 } while (0)
00207 #define LOOKUP16(wid,tab,eoflab) do {                                   \
00208     int t;                                                              \
00209     NeedBits16(wid,eoflab);                                             \
00210     TabEnt = tab + GetBits(wid);                                        \
00211     printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail,               \
00212            StateNames[TabEnt->State], TabEnt->Param);                   \
00213     for (t = 0; t < TabEnt->Width; t++)                                 \
00214         DEBUG_SHOW;                                                     \
00215     putchar('\n');                                                      \
00216     fflush(stdout);                                                     \
00217     ClrBits(TabEnt->Width);                                             \
00218 } while (0)
00219 
00220 #define SETVALUE(x) do {                                                        \
00221     *pa++ = RunLength + (x);                                            \
00222     printf("SETVALUE: %d\t%d\n", RunLength + (x), a0);                  \
00223     a0 += x;                                                            \
00224     RunLength = 0;                                                      \
00225 } while (0)
00226 #else
00227 #define LOOKUP8(wid,tab,eoflab) do {                                    \
00228     NeedBits8(wid,eoflab);                                              \
00229     TabEnt = tab + GetBits(wid);                                        \
00230     ClrBits(TabEnt->Width);                                             \
00231 } while (0)
00232 #define LOOKUP16(wid,tab,eoflab) do {                                   \
00233     NeedBits16(wid,eoflab);                                             \
00234     TabEnt = tab + GetBits(wid);                                        \
00235     ClrBits(TabEnt->Width);                                             \
00236 } while (0)
00237 
00238 /*
00239  * Append a run to the run length array for the
00240  * current row and reset decoding state.
00241  */
00242 #define SETVALUE(x) do {                                                        \
00243     *pa++ = RunLength + (x);                                            \
00244     a0 += (x);                                                          \
00245     RunLength = 0;                                                      \
00246 } while (0)
00247 #endif
00248 
00249 /*
00250  * Synchronize input decoding at the start of each
00251  * row by scanning for an EOL (if appropriate) and
00252  * skipping any trash data that might be present
00253  * after a decoding error.  Note that the decoding
00254  * done elsewhere that recognizes an EOL only consumes
00255  * 11 consecutive zero bits.  This means that if EOLcnt
00256  * is non-zero then we still need to scan for the final flag
00257  * bit that is part of the EOL code.
00258  */
00259 #define SYNC_EOL(eoflab) do {                                           \
00260     if (EOLcnt == 0) {                                                  \
00261         for (;;) {                                                      \
00262             NeedBits16(11,eoflab);                                      \
00263             if (GetBits(11) == 0)                                       \
00264                 break;                                                  \
00265             ClrBits(1);                                                 \
00266         }                                                               \
00267     }                                                                   \
00268     for (;;) {                                                          \
00269         NeedBits8(8,eoflab);                                            \
00270         if (GetBits(8))                                                 \
00271             break;                                                      \
00272         ClrBits(8);                                                     \
00273     }                                                                   \
00274     while (GetBits(1) == 0)                                             \
00275         ClrBits(1);                                                     \
00276     ClrBits(1);                         /* EOL bit */                   \
00277     EOLcnt = 0;                         /* reset EOL counter/flag */    \
00278 } while (0)
00279 
00280 /*
00281  * Cleanup the array of runs after decoding a row.
00282  * We adjust final runs to insure the user buffer is not
00283  * overwritten and/or undecoded area is white filled.
00284  */
00285 #define CLEANUP_RUNS() do {                                             \
00286     if (RunLength)                                                      \
00287         SETVALUE(0);                                                    \
00288     if (a0 != lastx) {                                                  \
00289         badlength(a0, lastx);                                           \
00290         while (a0 > lastx && pa > thisrun)                              \
00291             a0 -= *--pa;                                                \
00292         if (a0 < lastx) {                                               \
00293             if (a0 < 0)                                                 \
00294                 a0 = 0;                                                 \
00295             if ((pa-thisrun)&1)                                         \
00296                 SETVALUE(0);                                            \
00297             SETVALUE(lastx - a0);                                               \
00298         } else if (a0 > lastx) {                                        \
00299             SETVALUE(lastx);                                            \
00300             SETVALUE(0);                                                        \
00301         }                                                               \
00302     }                                                                   \
00303 } while (0)
00304 
00305 /*
00306  * Decode a line of 1D-encoded data.
00307  *
00308  * The line expanders are written as macros so that they can be reused
00309  * but still have direct access to the local variables of the "calling"
00310  * function.
00311  *
00312  * Note that unlike the original version we have to explicitly test for
00313  * a0 >= lastx after each black/white run is decoded.  This is because
00314  * the original code depended on the input data being zero-padded to
00315  * insure the decoder recognized an EOL before running out of data.
00316  */
00317 #define EXPAND1D(eoflab) do {                                           \
00318     for (;;) {                                                          \
00319         for (;;) {                                                      \
00320             LOOKUP16(12, TIFFFaxWhiteTable, eof1d);                     \
00321             switch (TabEnt->State) {                                    \
00322             case S_EOL:                                                 \
00323                 EOLcnt = 1;                                             \
00324                 goto done1d;                                            \
00325             case S_TermW:                                               \
00326                 SETVALUE(TabEnt->Param);                                        \
00327                 goto doneWhite1d;                                       \
00328             case S_MakeUpW:                                             \
00329             case S_MakeUp:                                              \
00330                 a0 += TabEnt->Param;                                    \
00331                 RunLength += TabEnt->Param;                             \
00332                 break;                                                  \
00333             default:                                                    \
00334                 unexpected("WhiteTable", a0);                           \
00335                 goto done1d;                                            \
00336             }                                                           \
00337         }                                                               \
00338     doneWhite1d:                                                        \
00339         if (a0 >= lastx)                                                \
00340             goto done1d;                                                \
00341         for (;;) {                                                      \
00342             LOOKUP16(13, TIFFFaxBlackTable, eof1d);                     \
00343             switch (TabEnt->State) {                                    \
00344             case S_EOL:                                                 \
00345                 EOLcnt = 1;                                             \
00346                 goto done1d;                                            \
00347             case S_TermB:                                               \
00348                 SETVALUE(TabEnt->Param);                                        \
00349                 goto doneBlack1d;                                       \
00350             case S_MakeUpB:                                             \
00351             case S_MakeUp:                                              \
00352                 a0 += TabEnt->Param;                                    \
00353                 RunLength += TabEnt->Param;                             \
00354                 break;                                                  \
00355             default:                                                    \
00356                 unexpected("BlackTable", a0);                           \
00357                 goto done1d;                                            \
00358             }                                                           \
00359         }                                                               \
00360     doneBlack1d:                                                        \
00361         if (a0 >= lastx)                                                \
00362             goto done1d;                                                \
00363         if( *(pa-1) == 0 && *(pa-2) == 0 )                              \
00364             pa -= 2;                                                    \
00365     }                                                                   \
00366 eof1d:                                                                  \
00367     prematureEOF(a0);                                                   \
00368     CLEANUP_RUNS();                                                     \
00369     goto eoflab;                                                        \
00370 done1d:                                                                 \
00371     CLEANUP_RUNS();                                                     \
00372 } while (0)
00373 
00374 /*
00375  * Update the value of b1 using the array
00376  * of runs for the reference line.
00377  */
00378 #define CHECK_b1 do {                                                   \
00379     if (pa != thisrun) while (b1 <= a0 && b1 < lastx) {                 \
00380         b1 += pb[0] + pb[1];                                            \
00381         pb += 2;                                                        \
00382     }                                                                   \
00383 } while (0)
00384 
00385 /*
00386  * Expand a row of 2D-encoded data.
00387  */
00388 #define EXPAND2D(eoflab) do {                                           \
00389     while (a0 < lastx) {                                                \
00390         LOOKUP8(7, TIFFFaxMainTable, eof2d);                            \
00391         switch (TabEnt->State) {                                        \
00392         case S_Pass:                                                    \
00393             CHECK_b1;                                                   \
00394             b1 += *pb++;                                                \
00395             RunLength += b1 - a0;                                       \
00396             a0 = b1;                                                    \
00397             b1 += *pb++;                                                \
00398             break;                                                      \
00399         case S_Horiz:                                                   \
00400             if ((pa-thisrun)&1) {                                       \
00401                 for (;;) {      /* black first */                       \
00402                     LOOKUP16(13, TIFFFaxBlackTable, eof2d);             \
00403                     switch (TabEnt->State) {                            \
00404                     case S_TermB:                                       \
00405                         SETVALUE(TabEnt->Param);                                \
00406                         goto doneWhite2da;                              \
00407                     case S_MakeUpB:                                     \
00408                     case S_MakeUp:                                      \
00409                         a0 += TabEnt->Param;                            \
00410                         RunLength += TabEnt->Param;                     \
00411                         break;                                          \
00412                     default:                                            \
00413                         goto badBlack2d;                                \
00414                     }                                                   \
00415                 }                                                       \
00416             doneWhite2da:;                                              \
00417                 for (;;) {      /* then white */                        \
00418                     LOOKUP16(12, TIFFFaxWhiteTable, eof2d);             \
00419                     switch (TabEnt->State) {                            \
00420                     case S_TermW:                                       \
00421                         SETVALUE(TabEnt->Param);                                \
00422                         goto doneBlack2da;                              \
00423                     case S_MakeUpW:                                     \
00424                     case S_MakeUp:                                      \
00425                         a0 += TabEnt->Param;                            \
00426                         RunLength += TabEnt->Param;                     \
00427                         break;                                          \
00428                     default:                                            \
00429                         goto badWhite2d;                                \
00430                     }                                                   \
00431                 }                                                       \
00432             doneBlack2da:;                                              \
00433             } else {                                                    \
00434                 for (;;) {      /* white first */                       \
00435                     LOOKUP16(12, TIFFFaxWhiteTable, eof2d);             \
00436                     switch (TabEnt->State) {                            \
00437                     case S_TermW:                                       \
00438                         SETVALUE(TabEnt->Param);                                \
00439                         goto doneWhite2db;                              \
00440                     case S_MakeUpW:                                     \
00441                     case S_MakeUp:                                      \
00442                         a0 += TabEnt->Param;                            \
00443                         RunLength += TabEnt->Param;                     \
00444                         break;                                          \
00445                     default:                                            \
00446                         goto badWhite2d;                                \
00447                     }                                                   \
00448                 }                                                       \
00449             doneWhite2db:;                                              \
00450                 for (;;) {      /* then black */                        \
00451                     LOOKUP16(13, TIFFFaxBlackTable, eof2d);             \
00452                     switch (TabEnt->State) {                            \
00453                     case S_TermB:                                       \
00454                         SETVALUE(TabEnt->Param);                                \
00455                         goto doneBlack2db;                              \
00456                     case S_MakeUpB:                                     \
00457                     case S_MakeUp:                                      \
00458                         a0 += TabEnt->Param;                            \
00459                         RunLength += TabEnt->Param;                     \
00460                         break;                                          \
00461                     default:                                            \
00462                         goto badBlack2d;                                \
00463                     }                                                   \
00464                 }                                                       \
00465             doneBlack2db:;                                              \
00466             }                                                           \
00467             CHECK_b1;                                                   \
00468             break;                                                      \
00469         case S_V0:                                                      \
00470             CHECK_b1;                                                   \
00471             SETVALUE(b1 - a0);                                          \
00472             b1 += *pb++;                                                \
00473             break;                                                      \
00474         case S_VR:                                                      \
00475             CHECK_b1;                                                   \
00476             SETVALUE(b1 - a0 + TabEnt->Param);                          \
00477             b1 += *pb++;                                                \
00478             break;                                                      \
00479         case S_VL:                                                      \
00480             CHECK_b1;                                                   \
00481             SETVALUE(b1 - a0 - TabEnt->Param);                          \
00482             b1 -= *--pb;                                                \
00483             break;                                                      \
00484         case S_Ext:                                                     \
00485             *pa++ = lastx - a0;                                         \
00486             extension(a0);                                              \
00487             goto eol2d;                                                 \
00488         case S_EOL:                                                     \
00489             *pa++ = lastx - a0;                                         \
00490             NeedBits8(4,eof2d);                                         \
00491             if (GetBits(4))                                             \
00492                 unexpected("EOL", a0);                                  \
00493             ClrBits(4);                                                 \
00494             EOLcnt = 1;                                                 \
00495             goto eol2d;                                                 \
00496         default:                                                        \
00497         badMain2d:                                                      \
00498             unexpected("MainTable", a0);                                \
00499             goto eol2d;                                                 \
00500         badBlack2d:                                                     \
00501             unexpected("BlackTable", a0);                               \
00502             goto eol2d;                                                 \
00503         badWhite2d:                                                     \
00504             unexpected("WhiteTable", a0);                               \
00505             goto eol2d;                                                 \
00506         eof2d:                                                          \
00507             prematureEOF(a0);                                           \
00508             CLEANUP_RUNS();                                             \
00509             goto eoflab;                                                \
00510         }                                                               \
00511     }                                                                   \
00512     if (RunLength) {                                                    \
00513         if (RunLength + a0 < lastx) {                                   \
00514             /* expect a final V0 */                                     \
00515             NeedBits8(1,eof2d);                                         \
00516             if (!GetBits(1))                                            \
00517                 goto badMain2d;                                         \
00518             ClrBits(1);                                                 \
00519         }                                                               \
00520         SETVALUE(0);                                                    \
00521     }                                                                   \
00522 eol2d:                                                                  \
00523     CLEANUP_RUNS();                                                     \
00524 } while (0)
00525 #endif /* _FAX3_ */
00526 /*
00527  * Local Variables:
00528  * mode: c
00529  * c-basic-offset: 8
00530  * fill-column: 78
00531  * End:
00532  */