ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tif_fax3.h
Go to the documentation of this file.
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  */

Generated on Sat May 26 2012 04:31:59 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.