tiff conversion for fax

Sector
Sector used Ask the Experts™
on
Hi, I'm Sector and I would know witch conversion I should perform to my tiff file. I also read that in phase C i should skip some bytes from header? How many? Why? I should add some information to file?

Thanks to all...
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Commented:
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_ */

Author

Commented:
Thanks a lot!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial