Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / libtiff / tif_fax3.h
diff --git a/3rdparty/libtiff/tif_fax3.h b/3rdparty/libtiff/tif_fax3.h
new file mode 100644 (file)
index 0000000..f02ddec
--- /dev/null
@@ -0,0 +1,525 @@
+/* $Id: tif_fax3.h,v 1.1 2005-06-17 13:54:52 vp153 Exp $ */
+
+/*
+ * 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.
+ */
+
+#ifndef _FAX3_
+#define        _FAX3_
+/*
+ * TIFF Library.
+ *
+ * CCITT Group 3 (T.4) and Group 4 (T.6) Decompression Support.
+ *
+ * Decoder support is derived, with permission, from the code
+ * in Frank Cringle's viewfax program;
+ *      Copyright (C) 1990, 1995  Frank D. Cringle.
+ */
+#include "tiff.h"
+
+/*
+ * To override the default routine used to image decoded
+ * spans one can use the pseduo tag TIFFTAG_FAXFILLFUNC.
+ * The routine must have the type signature given below;
+ * for example:
+ *
+ * fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx)
+ *
+ * where buf is place to set the bits, runs is the array of b&w run
+ * lengths (white then black), erun is the last run in the array, and
+ * lastx is the width of the row in pixels.  Fill routines can assume
+ * the run array has room for at least lastx runs and can overwrite
+ * data in the run array as needed (e.g. to append zero runs to bring
+ * the count up to a nice multiple).
+ */
+typedef        void (*TIFFFaxFillFunc)(unsigned char*, uint32*, uint32*, uint32);
+
+/*
+ * The default run filler; made external for other decoders.
+ */
+#if defined(__cplusplus)
+extern "C" {
+#endif
+extern void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32);
+#if defined(__cplusplus)
+}
+#endif
+
+
+/* finite state machine codes */
+#define S_Null         0
+#define S_Pass         1
+#define S_Horiz                2
+#define S_V0           3
+#define S_VR           4
+#define S_VL           5
+#define S_Ext          6
+#define S_TermW                7
+#define S_TermB                8
+#define S_MakeUpW      9
+#define S_MakeUpB      10
+#define S_MakeUp       11
+#define S_EOL          12
+
+typedef struct {               /* state table entry */
+       unsigned char State;    /* see above */
+       unsigned char Width;    /* width of code in bits */
+       uint32  Param;          /* unsigned 32-bit run length in bits */
+} TIFFFaxTabEnt;
+
+extern const TIFFFaxTabEnt TIFFFaxMainTable[];
+extern const TIFFFaxTabEnt TIFFFaxWhiteTable[];
+extern const TIFFFaxTabEnt TIFFFaxBlackTable[];
+
+/*
+ * The following macros define the majority of the G3/G4 decoder
+ * algorithm using the state tables defined elsewhere.  To build
+ * a decoder you need some setup code and some glue code. Note
+ * that you may also need/want to change the way the NeedBits*
+ * macros get input data if, for example, you know the data to be
+ * decoded is properly aligned and oriented (doing so before running
+ * the decoder can be a big performance win).
+ *
+ * Consult the decoder in the TIFF library for an idea of what you
+ * need to define and setup to make use of these definitions.
+ *
+ * NB: to enable a debugging version of these macros define FAX3_DEBUG
+ *     before including this file.  Trace output goes to stdout.
+ */
+
+#ifndef EndOfData
+#define EndOfData()    (cp >= ep)
+#endif
+/*
+ * Need <=8 or <=16 bits of input data.  Unlike viewfax we
+ * cannot use/assume a word-aligned, properly bit swizzled
+ * input data set because data may come from an arbitrarily
+ * aligned, read-only source such as a memory-mapped file.
+ * Note also that the viewfax decoder does not check for
+ * running off the end of the input data buffer.  This is
+ * possible for G3-encoded data because it prescans the input
+ * data to count EOL markers, but can cause problems for G4
+ * data.  In any event, we don't prescan and must watch for
+ * running out of data since we can't permit the library to
+ * scan past the end of the input data buffer.
+ *
+ * Finally, note that we must handle remaindered data at the end
+ * of a strip specially.  The coder asks for a fixed number of
+ * bits when scanning for the next code.  This may be more bits
+ * than are actually present in the data stream.  If we appear
+ * to run out of data but still have some number of valid bits
+ * remaining then we makeup the requested amount with zeros and
+ * return successfully.  If the returned data is incorrect then
+ * we should be called again and get a premature EOF error;
+ * otherwise we should get the right answer.
+ */
+#ifndef NeedBits8
+#define NeedBits8(n,eoflab) do {                                       \
+    if (BitsAvail < (n)) {                                             \
+       if (EndOfData()) {                                              \
+           if (BitsAvail == 0)                 /* no valid bits */     \
+               goto eoflab;                                            \
+           BitsAvail = (n);                    /* pad with zeros */    \
+       } else {                                                        \
+           BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;              \
+           BitsAvail += 8;                                             \
+       }                                                               \
+    }                                                                  \
+} while (0)
+#endif
+#ifndef NeedBits16
+#define NeedBits16(n,eoflab) do {                                      \
+    if (BitsAvail < (n)) {                                             \
+       if (EndOfData()) {                                              \
+           if (BitsAvail == 0)                 /* no valid bits */     \
+               goto eoflab;                                            \
+           BitsAvail = (n);                    /* pad with zeros */    \
+       } else {                                                        \
+           BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;              \
+           if ((BitsAvail += 8) < (n)) {                               \
+               if (EndOfData()) {                                      \
+                   /* NB: we know BitsAvail is non-zero here */        \
+                   BitsAvail = (n);            /* pad with zeros */    \
+               } else {                                                \
+                   BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;      \
+                   BitsAvail += 8;                                     \
+               }                                                       \
+           }                                                           \
+       }                                                               \
+    }                                                                  \
+} while (0)
+#endif
+#define GetBits(n)     (BitAcc & ((1<<(n))-1))
+#define ClrBits(n) do {                                                        \
+    BitsAvail -= (n);                                                  \
+    BitAcc >>= (n);                                                    \
+} while (0)
+
+#ifdef FAX3_DEBUG
+static const char* StateNames[] = {
+    "Null   ",
+    "Pass   ",
+    "Horiz  ",
+    "V0     ",
+    "VR     ",
+    "VL     ",
+    "Ext    ",
+    "TermW  ",
+    "TermB  ",
+    "MakeUpW",
+    "MakeUpB",
+    "MakeUp ",
+    "EOL    ",
+};
+#define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0')
+#define LOOKUP8(wid,tab,eoflab) do {                                   \
+    int t;                                                             \
+    NeedBits8(wid,eoflab);                                             \
+    TabEnt = tab + GetBits(wid);                                       \
+    printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail,              \
+          StateNames[TabEnt->State], TabEnt->Param);                   \
+    for (t = 0; t < TabEnt->Width; t++)                                        \
+       DEBUG_SHOW;                                                     \
+    putchar('\n');                                                     \
+    fflush(stdout);                                                    \
+    ClrBits(TabEnt->Width);                                            \
+} while (0)
+#define LOOKUP16(wid,tab,eoflab) do {                                  \
+    int t;                                                             \
+    NeedBits16(wid,eoflab);                                            \
+    TabEnt = tab + GetBits(wid);                                       \
+    printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail,              \
+          StateNames[TabEnt->State], TabEnt->Param);                   \
+    for (t = 0; t < TabEnt->Width; t++)                                        \
+       DEBUG_SHOW;                                                     \
+    putchar('\n');                                                     \
+    fflush(stdout);                                                    \
+    ClrBits(TabEnt->Width);                                            \
+} while (0)
+
+#define SETVAL(x) do {                                                 \
+    *pa++ = RunLength + (x);                                           \
+    printf("SETVAL: %d\t%d\n", RunLength + (x), a0);                   \
+    a0 += x;                                                           \
+    RunLength = 0;                                                     \
+} while (0)
+#else
+#define LOOKUP8(wid,tab,eoflab) do {                                   \
+    NeedBits8(wid,eoflab);                                             \
+    TabEnt = tab + GetBits(wid);                                       \
+    ClrBits(TabEnt->Width);                                            \
+} while (0)
+#define LOOKUP16(wid,tab,eoflab) do {                                  \
+    NeedBits16(wid,eoflab);                                            \
+    TabEnt = tab + GetBits(wid);                                       \
+    ClrBits(TabEnt->Width);                                            \
+} while (0)
+
+/*
+ * Append a run to the run length array for the
+ * current row and reset decoding state.
+ */
+#define SETVAL(x) do {                                                 \
+    *pa++ = RunLength + (x);                                           \
+    a0 += (x);                                                         \
+    RunLength = 0;                                                     \
+} while (0)
+#endif
+
+/*
+ * Synchronize input decoding at the start of each
+ * row by scanning for an EOL (if appropriate) and
+ * skipping any trash data that might be present
+ * after a decoding error.  Note that the decoding
+ * done elsewhere that recognizes an EOL only consumes
+ * 11 consecutive zero bits.  This means that if EOLcnt
+ * is non-zero then we still need to scan for the final flag
+ * bit that is part of the EOL code.
+ */
+#define        SYNC_EOL(eoflab) do {                                           \
+    if (EOLcnt == 0) {                                                 \
+       for (;;) {                                                      \
+           NeedBits16(11,eoflab);                                      \
+           if (GetBits(11) == 0)                                       \
+               break;                                                  \
+           ClrBits(1);                                                 \
+       }                                                               \
+    }                                                                  \
+    for (;;) {                                                         \
+       NeedBits8(8,eoflab);                                            \
+       if (GetBits(8))                                                 \
+           break;                                                      \
+       ClrBits(8);                                                     \
+    }                                                                  \
+    while (GetBits(1) == 0)                                            \
+       ClrBits(1);                                                     \
+    ClrBits(1);                                /* EOL bit */                   \
+    EOLcnt = 0;                                /* reset EOL counter/flag */    \
+} while (0)
+
+/*
+ * Cleanup the array of runs after decoding a row.
+ * We adjust final runs to insure the user buffer is not
+ * overwritten and/or undecoded area is white filled.
+ */
+#define        CLEANUP_RUNS() do {                                             \
+    if (RunLength)                                                     \
+       SETVAL(0);                                                      \
+    if (a0 != lastx) {                                                 \
+       badlength(a0, lastx);                                           \
+       while (a0 > lastx && pa > thisrun)                              \
+           a0 -= *--pa;                                                \
+       if (a0 < lastx) {                                               \
+           if (a0 < 0)                                                 \
+               a0 = 0;                                                 \
+           if ((pa-thisrun)&1)                                         \
+               SETVAL(0);                                              \
+           SETVAL(lastx - a0);                                         \
+       } else if (a0 > lastx) {                                        \
+           SETVAL(lastx);                                              \
+           SETVAL(0);                                                  \
+       }                                                               \
+    }                                                                  \
+} while (0)
+
+/*
+ * Decode a line of 1D-encoded data.
+ *
+ * The line expanders are written as macros so that they can be reused
+ * but still have direct access to the local variables of the "calling"
+ * function.
+ *
+ * Note that unlike the original version we have to explicitly test for
+ * a0 >= lastx after each black/white run is decoded.  This is because
+ * the original code depended on the input data being zero-padded to
+ * insure the decoder recognized an EOL before running out of data.
+ */
+#define EXPAND1D(eoflab) do {                                          \
+    for (;;) {                                                         \
+       for (;;) {                                                      \
+           LOOKUP16(12, TIFFFaxWhiteTable, eof1d);                     \
+           switch (TabEnt->State) {                                    \
+           case S_EOL:                                                 \
+               EOLcnt = 1;                                             \
+               goto done1d;                                            \
+           case S_TermW:                                               \
+               SETVAL(TabEnt->Param);                                  \
+               goto doneWhite1d;                                       \
+           case S_MakeUpW:                                             \
+           case S_MakeUp:                                              \
+               a0 += TabEnt->Param;                                    \
+               RunLength += TabEnt->Param;                             \
+               break;                                                  \
+           default:                                                    \
+               unexpected("WhiteTable", a0);                           \
+               goto done1d;                                            \
+           }                                                           \
+       }                                                               \
+    doneWhite1d:                                                       \
+       if (a0 >= lastx)                                                \
+           goto done1d;                                                \
+       for (;;) {                                                      \
+           LOOKUP16(13, TIFFFaxBlackTable, eof1d);                     \
+           switch (TabEnt->State) {                                    \
+           case S_EOL:                                                 \
+               EOLcnt = 1;                                             \
+               goto done1d;                                            \
+           case S_TermB:                                               \
+               SETVAL(TabEnt->Param);                                  \
+               goto doneBlack1d;                                       \
+           case S_MakeUpB:                                             \
+           case S_MakeUp:                                              \
+               a0 += TabEnt->Param;                                    \
+               RunLength += TabEnt->Param;                             \
+               break;                                                  \
+           default:                                                    \
+               unexpected("BlackTable", a0);                           \
+               goto done1d;                                            \
+           }                                                           \
+       }                                                               \
+    doneBlack1d:                                                       \
+       if (a0 >= lastx)                                                \
+           goto done1d;                                                \
+        if( *(pa-1) == 0 && *(pa-2) == 0 )                             \
+            pa -= 2;                                                    \
+    }                                                                  \
+eof1d:                                                                 \
+    prematureEOF(a0);                                                  \
+    CLEANUP_RUNS();                                                    \
+    goto eoflab;                                                       \
+done1d:                                                                        \
+    CLEANUP_RUNS();                                                    \
+} while (0)
+
+/*
+ * Update the value of b1 using the array
+ * of runs for the reference line.
+ */
+#define CHECK_b1 do {                                                  \
+    if (pa != thisrun) while (b1 <= a0 && b1 < lastx) {                        \
+       b1 += pb[0] + pb[1];                                            \
+       pb += 2;                                                        \
+    }                                                                  \
+} while (0)
+
+/*
+ * Expand a row of 2D-encoded data.
+ */
+#define EXPAND2D(eoflab) do {                                          \
+    while (a0 < lastx) {                                               \
+       LOOKUP8(7, TIFFFaxMainTable, eof2d);                            \
+       switch (TabEnt->State) {                                        \
+       case S_Pass:                                                    \
+           CHECK_b1;                                                   \
+           b1 += *pb++;                                                \
+           RunLength += b1 - a0;                                       \
+           a0 = b1;                                                    \
+           b1 += *pb++;                                                \
+           break;                                                      \
+       case S_Horiz:                                                   \
+           if ((pa-thisrun)&1) {                                       \
+               for (;;) {      /* black first */                       \
+                   LOOKUP16(13, TIFFFaxBlackTable, eof2d);             \
+                   switch (TabEnt->State) {                            \
+                   case S_TermB:                                       \
+                       SETVAL(TabEnt->Param);                          \
+                       goto doneWhite2da;                              \
+                   case S_MakeUpB:                                     \
+                   case S_MakeUp:                                      \
+                       a0 += TabEnt->Param;                            \
+                       RunLength += TabEnt->Param;                     \
+                       break;                                          \
+                   default:                                            \
+                       goto badBlack2d;                                \
+                   }                                                   \
+               }                                                       \
+           doneWhite2da:;                                              \
+               for (;;) {      /* then white */                        \
+                   LOOKUP16(12, TIFFFaxWhiteTable, eof2d);             \
+                   switch (TabEnt->State) {                            \
+                   case S_TermW:                                       \
+                       SETVAL(TabEnt->Param);                          \
+                       goto doneBlack2da;                              \
+                   case S_MakeUpW:                                     \
+                   case S_MakeUp:                                      \
+                       a0 += TabEnt->Param;                            \
+                       RunLength += TabEnt->Param;                     \
+                       break;                                          \
+                   default:                                            \
+                       goto badWhite2d;                                \
+                   }                                                   \
+               }                                                       \
+           doneBlack2da:;                                              \
+           } else {                                                    \
+               for (;;) {      /* white first */                       \
+                   LOOKUP16(12, TIFFFaxWhiteTable, eof2d);             \
+                   switch (TabEnt->State) {                            \
+                   case S_TermW:                                       \
+                       SETVAL(TabEnt->Param);                          \
+                       goto doneWhite2db;                              \
+                   case S_MakeUpW:                                     \
+                   case S_MakeUp:                                      \
+                       a0 += TabEnt->Param;                            \
+                       RunLength += TabEnt->Param;                     \
+                       break;                                          \
+                   default:                                            \
+                       goto badWhite2d;                                \
+                   }                                                   \
+               }                                                       \
+           doneWhite2db:;                                              \
+               for (;;) {      /* then black */                        \
+                   LOOKUP16(13, TIFFFaxBlackTable, eof2d);             \
+                   switch (TabEnt->State) {                            \
+                   case S_TermB:                                       \
+                       SETVAL(TabEnt->Param);                          \
+                       goto doneBlack2db;                              \
+                   case S_MakeUpB:                                     \
+                   case S_MakeUp:                                      \
+                       a0 += TabEnt->Param;                            \
+                       RunLength += TabEnt->Param;                     \
+                       break;                                          \
+                   default:                                            \
+                       goto badBlack2d;                                \
+                   }                                                   \
+               }                                                       \
+           doneBlack2db:;                                              \
+           }                                                           \
+           CHECK_b1;                                                   \
+           break;                                                      \
+       case S_V0:                                                      \
+           CHECK_b1;                                                   \
+           SETVAL(b1 - a0);                                            \
+           b1 += *pb++;                                                \
+           break;                                                      \
+       case S_VR:                                                      \
+           CHECK_b1;                                                   \
+           SETVAL(b1 - a0 + TabEnt->Param);                            \
+           b1 += *pb++;                                                \
+           break;                                                      \
+       case S_VL:                                                      \
+           CHECK_b1;                                                   \
+           SETVAL(b1 - a0 - TabEnt->Param);                            \
+           b1 -= *--pb;                                                \
+           break;                                                      \
+       case S_Ext:                                                     \
+           *pa++ = lastx - a0;                                         \
+           extension(a0);                                              \
+           goto eol2d;                                                 \
+       case S_EOL:                                                     \
+           *pa++ = lastx - a0;                                         \
+           NeedBits8(4,eof2d);                                         \
+           if (GetBits(4))                                             \
+               unexpected("EOL", a0);                                  \
+            ClrBits(4);                                                 \
+           EOLcnt = 1;                                                 \
+           goto eol2d;                                                 \
+       default:                                                        \
+       badMain2d:                                                      \
+           unexpected("MainTable", a0);                                \
+           goto eol2d;                                                 \
+       badBlack2d:                                                     \
+           unexpected("BlackTable", a0);                               \
+           goto eol2d;                                                 \
+       badWhite2d:                                                     \
+           unexpected("WhiteTable", a0);                               \
+           goto eol2d;                                                 \
+       eof2d:                                                          \
+           prematureEOF(a0);                                           \
+           CLEANUP_RUNS();                                             \
+           goto eoflab;                                                \
+       }                                                               \
+    }                                                                  \
+    if (RunLength) {                                                   \
+       if (RunLength + a0 < lastx) {                                   \
+           /* expect a final V0 */                                     \
+           NeedBits8(1,eof2d);                                         \
+           if (!GetBits(1))                                            \
+               goto badMain2d;                                         \
+           ClrBits(1);                                                 \
+       }                                                               \
+       SETVAL(0);                                                      \
+    }                                                                  \
+eol2d:                                                                 \
+    CLEANUP_RUNS();                                                    \
+} while (0)
+#endif /* _FAX3_ */