tif_fax3.h
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:16k
源码类别:

传真(Fax)编程

开发平台:

C/C++

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