tif_fax3.h 41 KB

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