tif_fax3.h 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  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, retrywithouteol) \
  281. do \
  282. { \
  283. if (!(sp->b.mode & FAXMODE_NOEOL)) /* skip EOL, if not present */ \
  284. { \
  285. if (EOLcnt == 0) \
  286. { \
  287. for (;;) \
  288. { \
  289. NeedBits16(11, eoflab); \
  290. if (GetBits(11) == 0) \
  291. break; /* EOL found */ \
  292. ClrBits(1); \
  293. } \
  294. } \
  295. /* Now move after EOL or detect missing EOL. */ \
  296. for (;;) \
  297. { \
  298. NeedBits8(8, noEOLFound); \
  299. if (GetBits(8)) \
  300. break; \
  301. ClrBits(8); \
  302. } \
  303. while (GetBits(1) == 0) \
  304. ClrBits(1); \
  305. ClrBits(1); /* EOL bit */ \
  306. EOLcnt = 0; /* reset EOL counter/flag */ \
  307. break; /* existing EOL skipped, leave macro */ \
  308. noEOLFound: \
  309. sp->b.mode |= FAXMODE_NOEOL; \
  310. tryG3WithoutEOL(a0); \
  311. goto retrywithouteol; \
  312. } \
  313. } while (0)
  314. /*
  315. * Cleanup the array of runs after decoding a row.
  316. * We adjust final runs to insure the user buffer is not
  317. * overwritten and/or undecoded area is white filled.
  318. */
  319. #define CLEANUP_RUNS() \
  320. do \
  321. { \
  322. if (RunLength) \
  323. SETVALUE(0); \
  324. if (a0 != lastx) \
  325. { \
  326. badlength(a0, lastx); \
  327. while (a0 > lastx && pa > thisrun) \
  328. a0 -= *--pa; \
  329. if (a0 < lastx) \
  330. { \
  331. if (a0 < 0) \
  332. a0 = 0; \
  333. if ((pa - thisrun) & 1) \
  334. SETVALUE(0); \
  335. SETVALUE(lastx - a0); \
  336. } \
  337. else if (a0 > lastx) \
  338. { \
  339. SETVALUE(lastx); \
  340. SETVALUE(0); \
  341. } \
  342. } \
  343. } while (0)
  344. /*
  345. * Decode a line of 1D-encoded data.
  346. *
  347. * The line expanders are written as macros so that they can be reused
  348. * but still have direct access to the local variables of the "calling"
  349. * function.
  350. *
  351. * Note that unlike the original version we have to explicitly test for
  352. * a0 >= lastx after each black/white run is decoded. This is because
  353. * the original code depended on the input data being zero-padded to
  354. * insure the decoder recognized an EOL before running out of data.
  355. */
  356. #define EXPAND1D(eoflab) \
  357. do \
  358. { \
  359. for (;;) \
  360. { \
  361. for (;;) \
  362. { \
  363. LOOKUP16(12, TIFFFaxWhiteTable, eof1d); \
  364. switch (TabEnt->State) \
  365. { \
  366. case S_EOL: \
  367. EOLcnt = 1; \
  368. goto done1d; \
  369. case S_TermW: \
  370. SETVALUE(TabEnt->Param); \
  371. goto doneWhite1d; \
  372. case S_MakeUpW: \
  373. case S_MakeUp: \
  374. a0 += TabEnt->Param; \
  375. RunLength += TabEnt->Param; \
  376. break; \
  377. default: \
  378. unexpected("WhiteTable", a0); \
  379. goto done1d; \
  380. } \
  381. } \
  382. doneWhite1d: \
  383. if (a0 >= lastx) \
  384. goto done1d; \
  385. for (;;) \
  386. { \
  387. LOOKUP16(13, TIFFFaxBlackTable, eof1d); \
  388. switch (TabEnt->State) \
  389. { \
  390. case S_EOL: \
  391. EOLcnt = 1; \
  392. goto done1d; \
  393. case S_TermB: \
  394. SETVALUE(TabEnt->Param); \
  395. goto doneBlack1d; \
  396. case S_MakeUpB: \
  397. case S_MakeUp: \
  398. a0 += TabEnt->Param; \
  399. RunLength += TabEnt->Param; \
  400. break; \
  401. default: \
  402. unexpected("BlackTable", a0); \
  403. goto done1d; \
  404. } \
  405. } \
  406. doneBlack1d: \
  407. if (a0 >= lastx) \
  408. goto done1d; \
  409. if (*(pa - 1) == 0 && *(pa - 2) == 0) \
  410. pa -= 2; \
  411. } \
  412. eof1d: \
  413. prematureEOF(a0); \
  414. CLEANUP_RUNS(); \
  415. goto eoflab; \
  416. done1d: \
  417. CLEANUP_RUNS(); \
  418. } while (0)
  419. /*
  420. * Update the value of b1 using the array
  421. * of runs for the reference line.
  422. */
  423. #define CHECK_b1 \
  424. do \
  425. { \
  426. if (pa != thisrun) \
  427. while (b1 <= a0 && b1 < lastx) \
  428. { \
  429. if (pb + 1 >= sp->refruns + sp->nruns) \
  430. { \
  431. TIFFErrorExtR( \
  432. tif, module, "Buffer overflow at line %u of %s %u", \
  433. sp->line, isTiled(tif) ? "tile" : "strip", \
  434. isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
  435. return (-1); \
  436. } \
  437. b1 += pb[0] + pb[1]; \
  438. pb += 2; \
  439. } \
  440. } while (0)
  441. /*
  442. * Expand a row of 2D-encoded data.
  443. */
  444. #define EXPAND2D(eoflab) \
  445. do \
  446. { \
  447. while (a0 < lastx) \
  448. { \
  449. if (pa >= thisrun + sp->nruns) \
  450. { \
  451. TIFFErrorExtR( \
  452. tif, module, "Buffer overflow at line %u of %s %u", \
  453. sp->line, isTiled(tif) ? "tile" : "strip", \
  454. isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
  455. return (-1); \
  456. } \
  457. LOOKUP8(7, TIFFFaxMainTable, eof2d); \
  458. switch (TabEnt->State) \
  459. { \
  460. case S_Pass: \
  461. CHECK_b1; \
  462. if (pb + 1 >= sp->refruns + sp->nruns) \
  463. { \
  464. TIFFErrorExtR(tif, module, \
  465. "Buffer overflow at line %u of %s %u", \
  466. sp->line, \
  467. isTiled(tif) ? "tile" : "strip", \
  468. isTiled(tif) ? tif->tif_curtile \
  469. : tif->tif_curstrip); \
  470. return (-1); \
  471. } \
  472. b1 += *pb++; \
  473. RunLength += b1 - a0; \
  474. a0 = b1; \
  475. b1 += *pb++; \
  476. break; \
  477. case S_Horiz: \
  478. if ((pa - thisrun) & 1) \
  479. { \
  480. for (;;) \
  481. { /* black first */ \
  482. LOOKUP16(13, TIFFFaxBlackTable, eof2d); \
  483. switch (TabEnt->State) \
  484. { \
  485. case S_TermB: \
  486. SETVALUE(TabEnt->Param); \
  487. goto doneWhite2da; \
  488. case S_MakeUpB: \
  489. case S_MakeUp: \
  490. a0 += TabEnt->Param; \
  491. RunLength += TabEnt->Param; \
  492. break; \
  493. default: \
  494. goto badBlack2d; \
  495. } \
  496. } \
  497. doneWhite2da:; \
  498. for (;;) \
  499. { /* then white */ \
  500. LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \
  501. switch (TabEnt->State) \
  502. { \
  503. case S_TermW: \
  504. SETVALUE(TabEnt->Param); \
  505. goto doneBlack2da; \
  506. case S_MakeUpW: \
  507. case S_MakeUp: \
  508. a0 += TabEnt->Param; \
  509. RunLength += TabEnt->Param; \
  510. break; \
  511. default: \
  512. goto badWhite2d; \
  513. } \
  514. } \
  515. doneBlack2da:; \
  516. } \
  517. else \
  518. { \
  519. for (;;) \
  520. { /* white first */ \
  521. LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \
  522. switch (TabEnt->State) \
  523. { \
  524. case S_TermW: \
  525. SETVALUE(TabEnt->Param); \
  526. goto doneWhite2db; \
  527. case S_MakeUpW: \
  528. case S_MakeUp: \
  529. a0 += TabEnt->Param; \
  530. RunLength += TabEnt->Param; \
  531. break; \
  532. default: \
  533. goto badWhite2d; \
  534. } \
  535. } \
  536. doneWhite2db:; \
  537. for (;;) \
  538. { /* then black */ \
  539. LOOKUP16(13, TIFFFaxBlackTable, eof2d); \
  540. switch (TabEnt->State) \
  541. { \
  542. case S_TermB: \
  543. SETVALUE(TabEnt->Param); \
  544. goto doneBlack2db; \
  545. case S_MakeUpB: \
  546. case S_MakeUp: \
  547. a0 += TabEnt->Param; \
  548. RunLength += TabEnt->Param; \
  549. break; \
  550. default: \
  551. goto badBlack2d; \
  552. } \
  553. } \
  554. doneBlack2db:; \
  555. } \
  556. CHECK_b1; \
  557. break; \
  558. case S_V0: \
  559. CHECK_b1; \
  560. SETVALUE(b1 - a0); \
  561. if (pb >= sp->refruns + sp->nruns) \
  562. { \
  563. TIFFErrorExtR(tif, module, \
  564. "Buffer overflow at line %u of %s %u", \
  565. sp->line, \
  566. isTiled(tif) ? "tile" : "strip", \
  567. isTiled(tif) ? tif->tif_curtile \
  568. : tif->tif_curstrip); \
  569. return (-1); \
  570. } \
  571. b1 += *pb++; \
  572. break; \
  573. case S_VR: \
  574. CHECK_b1; \
  575. SETVALUE(b1 - a0 + TabEnt->Param); \
  576. if (pb >= sp->refruns + sp->nruns) \
  577. { \
  578. TIFFErrorExtR(tif, module, \
  579. "Buffer overflow at line %u of %s %u", \
  580. sp->line, \
  581. isTiled(tif) ? "tile" : "strip", \
  582. isTiled(tif) ? tif->tif_curtile \
  583. : tif->tif_curstrip); \
  584. return (-1); \
  585. } \
  586. b1 += *pb++; \
  587. break; \
  588. case S_VL: \
  589. CHECK_b1; \
  590. if (b1 < (int)(a0 + TabEnt->Param)) \
  591. { \
  592. unexpected("VL", a0); \
  593. goto eol2d; \
  594. } \
  595. SETVALUE(b1 - a0 - TabEnt->Param); \
  596. b1 -= *--pb; \
  597. break; \
  598. case S_Ext: \
  599. *pa++ = lastx - a0; \
  600. extension(a0); \
  601. goto eol2d; \
  602. case S_EOL: \
  603. *pa++ = lastx - a0; \
  604. NeedBits8(4, eof2d); \
  605. if (GetBits(4)) \
  606. unexpected("EOL", a0); \
  607. ClrBits(4); \
  608. EOLcnt = 1; \
  609. goto eol2d; \
  610. default: \
  611. badMain2d: \
  612. unexpected("MainTable", a0); \
  613. goto eol2d; \
  614. badBlack2d: \
  615. unexpected("BlackTable", a0); \
  616. goto eol2d; \
  617. badWhite2d: \
  618. unexpected("WhiteTable", a0); \
  619. goto eol2d; \
  620. eof2d: \
  621. prematureEOF(a0); \
  622. CLEANUP_RUNS(); \
  623. goto eoflab; \
  624. } \
  625. } \
  626. if (RunLength) \
  627. { \
  628. if (RunLength + a0 < lastx) \
  629. { \
  630. /* expect a final V0 */ \
  631. NeedBits8(1, eof2d); \
  632. if (!GetBits(1)) \
  633. goto badMain2d; \
  634. ClrBits(1); \
  635. } \
  636. SETVALUE(0); \
  637. } \
  638. eol2d: \
  639. CLEANUP_RUNS(); \
  640. } while (0)
  641. #endif /* _FAX3_ */