tif_fax3.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  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* runs, uint32* erun, uint32 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*, uint32*, uint32);
  52. /*
  53. * The default run filler; made external for other decoders.
  54. */
  55. #if defined(__cplusplus)
  56. extern "C" {
  57. #endif
  58. extern void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32);
  59. #if defined(__cplusplus)
  60. }
  61. #endif
  62. /* finite state machine codes */
  63. #define S_Null 0
  64. #define S_Pass 1
  65. #define S_Horiz 2
  66. #define S_V0 3
  67. #define S_VR 4
  68. #define S_VL 5
  69. #define S_Ext 6
  70. #define S_TermW 7
  71. #define S_TermB 8
  72. #define S_MakeUpW 9
  73. #define S_MakeUpB 10
  74. #define S_MakeUp 11
  75. #define S_EOL 12
  76. /* WARNING: do not change the layout of this structure as the HylaFAX software */
  77. /* really depends on it. See http://bugzilla.maptools.org/show_bug.cgi?id=2636 */
  78. typedef struct { /* state table entry */
  79. unsigned char State; /* see above */
  80. unsigned char Width; /* width of code in bits */
  81. uint32 Param; /* unsigned 32-bit run length in bits (holds on 16 bit actually, but cannot be changed. See above warning) */
  82. } TIFFFaxTabEnt;
  83. extern const TIFFFaxTabEnt TIFFFaxMainTable[];
  84. extern const TIFFFaxTabEnt TIFFFaxWhiteTable[];
  85. extern const TIFFFaxTabEnt TIFFFaxBlackTable[];
  86. /*
  87. * The following macros define the majority of the G3/G4 decoder
  88. * algorithm using the state tables defined elsewhere. To build
  89. * a decoder you need some setup code and some glue code. Note
  90. * that you may also need/want to change the way the NeedBits*
  91. * macros get input data if, for example, you know the data to be
  92. * decoded is properly aligned and oriented (doing so before running
  93. * the decoder can be a big performance win).
  94. *
  95. * Consult the decoder in the TIFF library for an idea of what you
  96. * need to define and setup to make use of these definitions.
  97. *
  98. * NB: to enable a debugging version of these macros define FAX3_DEBUG
  99. * before including this file. Trace output goes to stdout.
  100. */
  101. #ifndef EndOfData
  102. #define EndOfData() (cp >= ep)
  103. #endif
  104. /*
  105. * Need <=8 or <=16 bits of input data. Unlike viewfax we
  106. * cannot use/assume a word-aligned, properly bit swizzled
  107. * input data set because data may come from an arbitrarily
  108. * aligned, read-only source such as a memory-mapped file.
  109. * Note also that the viewfax decoder does not check for
  110. * running off the end of the input data buffer. This is
  111. * possible for G3-encoded data because it prescans the input
  112. * data to count EOL markers, but can cause problems for G4
  113. * data. In any event, we don't prescan and must watch for
  114. * running out of data since we can't permit the library to
  115. * scan past the end of the input data buffer.
  116. *
  117. * Finally, note that we must handle remaindered data at the end
  118. * of a strip specially. The coder asks for a fixed number of
  119. * bits when scanning for the next code. This may be more bits
  120. * than are actually present in the data stream. If we appear
  121. * to run out of data but still have some number of valid bits
  122. * remaining then we makeup the requested amount with zeros and
  123. * return successfully. If the returned data is incorrect then
  124. * we should be called again and get a premature EOF error;
  125. * otherwise we should get the right answer.
  126. */
  127. #ifndef NeedBits8
  128. #define NeedBits8(n,eoflab) do { \
  129. if (BitsAvail < (n)) { \
  130. if (EndOfData()) { \
  131. if (BitsAvail == 0) /* no valid bits */ \
  132. goto eoflab; \
  133. BitsAvail = (n); /* pad with zeros */ \
  134. } else { \
  135. BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail; \
  136. BitsAvail += 8; \
  137. } \
  138. } \
  139. } while (0)
  140. #endif
  141. #ifndef NeedBits16
  142. #define NeedBits16(n,eoflab) do { \
  143. if (BitsAvail < (n)) { \
  144. if (EndOfData()) { \
  145. if (BitsAvail == 0) /* no valid bits */ \
  146. goto eoflab; \
  147. BitsAvail = (n); /* pad with zeros */ \
  148. } else { \
  149. BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail; \
  150. if ((BitsAvail += 8) < (n)) { \
  151. if (EndOfData()) { \
  152. /* NB: we know BitsAvail is non-zero here */ \
  153. BitsAvail = (n); /* pad with zeros */ \
  154. } else { \
  155. BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail; \
  156. BitsAvail += 8; \
  157. } \
  158. } \
  159. } \
  160. } \
  161. } while (0)
  162. #endif
  163. #define GetBits(n) (BitAcc & ((1<<(n))-1))
  164. #define ClrBits(n) do { \
  165. BitsAvail -= (n); \
  166. BitAcc >>= (n); \
  167. } while (0)
  168. #ifdef FAX3_DEBUG
  169. static const char* StateNames[] = {
  170. "Null ",
  171. "Pass ",
  172. "Horiz ",
  173. "V0 ",
  174. "VR ",
  175. "VL ",
  176. "Ext ",
  177. "TermW ",
  178. "TermB ",
  179. "MakeUpW",
  180. "MakeUpB",
  181. "MakeUp ",
  182. "EOL ",
  183. };
  184. #define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0')
  185. #define LOOKUP8(wid,tab,eoflab) do { \
  186. int t; \
  187. NeedBits8(wid,eoflab); \
  188. TabEnt = tab + GetBits(wid); \
  189. printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail, \
  190. StateNames[TabEnt->State], TabEnt->Param); \
  191. for (t = 0; t < TabEnt->Width; t++) \
  192. DEBUG_SHOW; \
  193. putchar('\n'); \
  194. fflush(stdout); \
  195. ClrBits(TabEnt->Width); \
  196. } while (0)
  197. #define LOOKUP16(wid,tab,eoflab) do { \
  198. int t; \
  199. NeedBits16(wid,eoflab); \
  200. TabEnt = tab + GetBits(wid); \
  201. printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail, \
  202. StateNames[TabEnt->State], TabEnt->Param); \
  203. for (t = 0; t < TabEnt->Width; t++) \
  204. DEBUG_SHOW; \
  205. putchar('\n'); \
  206. fflush(stdout); \
  207. ClrBits(TabEnt->Width); \
  208. } while (0)
  209. #define SETVALUE(x) do { \
  210. *pa++ = RunLength + (x); \
  211. printf("SETVALUE: %d\t%d\n", RunLength + (x), a0); \
  212. a0 += x; \
  213. RunLength = 0; \
  214. } while (0)
  215. #else
  216. #define LOOKUP8(wid,tab,eoflab) do { \
  217. NeedBits8(wid,eoflab); \
  218. TabEnt = tab + GetBits(wid); \
  219. ClrBits(TabEnt->Width); \
  220. } while (0)
  221. #define LOOKUP16(wid,tab,eoflab) do { \
  222. NeedBits16(wid,eoflab); \
  223. TabEnt = tab + GetBits(wid); \
  224. ClrBits(TabEnt->Width); \
  225. } while (0)
  226. /*
  227. * Append a run to the run length array for the
  228. * current row and reset decoding state.
  229. */
  230. #define SETVALUE(x) do { \
  231. if (pa >= thisrun + sp->nruns) { \
  232. TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
  233. sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
  234. return (-1); \
  235. } \
  236. *pa++ = RunLength + (x); \
  237. a0 += (x); \
  238. RunLength = 0; \
  239. } while (0)
  240. #endif
  241. /*
  242. * Synchronize input decoding at the start of each
  243. * row by scanning for an EOL (if appropriate) and
  244. * skipping any trash data that might be present
  245. * after a decoding error. Note that the decoding
  246. * done elsewhere that recognizes an EOL only consumes
  247. * 11 consecutive zero bits. This means that if EOLcnt
  248. * is non-zero then we still need to scan for the final flag
  249. * bit that is part of the EOL code.
  250. */
  251. #define SYNC_EOL(eoflab) do { \
  252. if (EOLcnt == 0) { \
  253. for (;;) { \
  254. NeedBits16(11,eoflab); \
  255. if (GetBits(11) == 0) \
  256. break; \
  257. ClrBits(1); \
  258. } \
  259. } \
  260. for (;;) { \
  261. NeedBits8(8,eoflab); \
  262. if (GetBits(8)) \
  263. break; \
  264. ClrBits(8); \
  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. SETVALUE(0); \
  279. if (a0 != lastx) { \
  280. badlength(a0, lastx); \
  281. while (a0 > lastx && pa > thisrun) \
  282. a0 -= *--pa; \
  283. if (a0 < lastx) { \
  284. if (a0 < 0) \
  285. a0 = 0; \
  286. if ((pa-thisrun)&1) \
  287. SETVALUE(0); \
  288. SETVALUE(lastx - a0); \
  289. } else if (a0 > lastx) { \
  290. SETVALUE(lastx); \
  291. SETVALUE(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. SETVALUE(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 (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. SETVALUE(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 (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 && b1 < lastx) { \
  369. if( pb + 1 >= sp->refruns + sp->nruns) { \
  370. TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
  371. sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
  372. return (-1); \
  373. } \
  374. b1 += pb[0] + pb[1]; \
  375. pb += 2; \
  376. } \
  377. } while (0)
  378. /*
  379. * Expand a row of 2D-encoded data.
  380. */
  381. #define EXPAND2D(eoflab) do { \
  382. while (a0 < lastx) { \
  383. if (pa >= thisrun + sp->nruns) { \
  384. TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
  385. sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
  386. return (-1); \
  387. } \
  388. LOOKUP8(7, TIFFFaxMainTable, eof2d); \
  389. switch (TabEnt->State) { \
  390. case S_Pass: \
  391. CHECK_b1; \
  392. if( pb + 1 >= sp->refruns + sp->nruns) { \
  393. TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
  394. sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
  395. return (-1); \
  396. } \
  397. b1 += *pb++; \
  398. RunLength += b1 - a0; \
  399. a0 = b1; \
  400. b1 += *pb++; \
  401. break; \
  402. case S_Horiz: \
  403. if ((pa-thisrun)&1) { \
  404. for (;;) { /* black first */ \
  405. LOOKUP16(13, TIFFFaxBlackTable, eof2d); \
  406. switch (TabEnt->State) { \
  407. case S_TermB: \
  408. SETVALUE(TabEnt->Param); \
  409. goto doneWhite2da; \
  410. case S_MakeUpB: \
  411. case S_MakeUp: \
  412. a0 += TabEnt->Param; \
  413. RunLength += TabEnt->Param; \
  414. break; \
  415. default: \
  416. goto badBlack2d; \
  417. } \
  418. } \
  419. doneWhite2da:; \
  420. for (;;) { /* then white */ \
  421. LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \
  422. switch (TabEnt->State) { \
  423. case S_TermW: \
  424. SETVALUE(TabEnt->Param); \
  425. goto doneBlack2da; \
  426. case S_MakeUpW: \
  427. case S_MakeUp: \
  428. a0 += TabEnt->Param; \
  429. RunLength += TabEnt->Param; \
  430. break; \
  431. default: \
  432. goto badWhite2d; \
  433. } \
  434. } \
  435. doneBlack2da:; \
  436. } else { \
  437. for (;;) { /* white first */ \
  438. LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \
  439. switch (TabEnt->State) { \
  440. case S_TermW: \
  441. SETVALUE(TabEnt->Param); \
  442. goto doneWhite2db; \
  443. case S_MakeUpW: \
  444. case S_MakeUp: \
  445. a0 += TabEnt->Param; \
  446. RunLength += TabEnt->Param; \
  447. break; \
  448. default: \
  449. goto badWhite2d; \
  450. } \
  451. } \
  452. doneWhite2db:; \
  453. for (;;) { /* then black */ \
  454. LOOKUP16(13, TIFFFaxBlackTable, eof2d); \
  455. switch (TabEnt->State) { \
  456. case S_TermB: \
  457. SETVALUE(TabEnt->Param); \
  458. goto doneBlack2db; \
  459. case S_MakeUpB: \
  460. case S_MakeUp: \
  461. a0 += TabEnt->Param; \
  462. RunLength += TabEnt->Param; \
  463. break; \
  464. default: \
  465. goto badBlack2d; \
  466. } \
  467. } \
  468. doneBlack2db:; \
  469. } \
  470. CHECK_b1; \
  471. break; \
  472. case S_V0: \
  473. CHECK_b1; \
  474. SETVALUE(b1 - a0); \
  475. if( pb >= sp->refruns + sp->nruns) { \
  476. TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
  477. sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
  478. return (-1); \
  479. } \
  480. b1 += *pb++; \
  481. break; \
  482. case S_VR: \
  483. CHECK_b1; \
  484. SETVALUE(b1 - a0 + TabEnt->Param); \
  485. if( pb >= sp->refruns + sp->nruns) { \
  486. TIFFErrorExt(tif->tif_clientdata, module, "Buffer overflow at line %u of %s %u", \
  487. sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \
  488. return (-1); \
  489. } \
  490. b1 += *pb++; \
  491. break; \
  492. case S_VL: \
  493. CHECK_b1; \
  494. if (b1 < (int) (a0 + TabEnt->Param)) { \
  495. unexpected("VL", a0); \
  496. goto eol2d; \
  497. } \
  498. SETVALUE(b1 - a0 - TabEnt->Param); \
  499. b1 -= *--pb; \
  500. break; \
  501. case S_Ext: \
  502. *pa++ = lastx - a0; \
  503. extension(a0); \
  504. goto eol2d; \
  505. case S_EOL: \
  506. *pa++ = lastx - a0; \
  507. NeedBits8(4,eof2d); \
  508. if (GetBits(4)) \
  509. unexpected("EOL", a0); \
  510. ClrBits(4); \
  511. EOLcnt = 1; \
  512. goto eol2d; \
  513. default: \
  514. badMain2d: \
  515. unexpected("MainTable", a0); \
  516. goto eol2d; \
  517. badBlack2d: \
  518. unexpected("BlackTable", a0); \
  519. goto eol2d; \
  520. badWhite2d: \
  521. unexpected("WhiteTable", a0); \
  522. goto eol2d; \
  523. eof2d: \
  524. prematureEOF(a0); \
  525. CLEANUP_RUNS(); \
  526. goto eoflab; \
  527. } \
  528. } \
  529. if (RunLength) { \
  530. if (RunLength + a0 < lastx) { \
  531. /* expect a final V0 */ \
  532. NeedBits8(1,eof2d); \
  533. if (!GetBits(1)) \
  534. goto badMain2d; \
  535. ClrBits(1); \
  536. } \
  537. SETVALUE(0); \
  538. } \
  539. eol2d: \
  540. CLEANUP_RUNS(); \
  541. } while (0)
  542. #endif /* _FAX3_ */
  543. /* vim: set ts=8 sts=4 sw=4 noet: */
  544. /*
  545. * Local Variables:
  546. * mode: c
  547. * c-basic-offset: 8
  548. * fill-column: 78
  549. * End:
  550. */