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