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