• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* $Id: tif_fax3.h,v 1.9 2011-03-10 20:23:07 fwarmerdam 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 pseduo 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 typedef struct {                /* state table entry */
85 	unsigned char State;    /* see above */
86 	unsigned char Width;    /* width of code in bits */
87 	uint32 Param;           /* unsigned 32-bit run length in bits */
88 } TIFFFaxTabEnt;
89 
90 extern const TIFFFaxTabEnt TIFFFaxMainTable[];
91 extern const TIFFFaxTabEnt TIFFFaxWhiteTable[];
92 extern const TIFFFaxTabEnt TIFFFaxBlackTable[];
93 
94 /*
95  * The following macros define the majority of the G3/G4 decoder
96  * algorithm using the state tables defined elsewhere.  To build
97  * a decoder you need some setup code and some glue code. Note
98  * that you may also need/want to change the way the NeedBits*
99  * macros get input data if, for example, you know the data to be
100  * decoded is properly aligned and oriented (doing so before running
101  * the decoder can be a big performance win).
102  *
103  * Consult the decoder in the TIFF library for an idea of what you
104  * need to define and setup to make use of these definitions.
105  *
106  * NB: to enable a debugging version of these macros define FAX3_DEBUG
107  *     before including this file.  Trace output goes to stdout.
108  */
109 
110 #ifndef EndOfData
111 #define EndOfData()	(cp >= ep)
112 #endif
113 /*
114  * Need <=8 or <=16 bits of input data.  Unlike viewfax we
115  * cannot use/assume a word-aligned, properly bit swizzled
116  * input data set because data may come from an arbitrarily
117  * aligned, read-only source such as a memory-mapped file.
118  * Note also that the viewfax decoder does not check for
119  * running off the end of the input data buffer.  This is
120  * possible for G3-encoded data because it prescans the input
121  * data to count EOL markers, but can cause problems for G4
122  * data.  In any event, we don't prescan and must watch for
123  * running out of data since we can't permit the library to
124  * scan past the end of the input data buffer.
125  *
126  * Finally, note that we must handle remaindered data at the end
127  * of a strip specially.  The coder asks for a fixed number of
128  * bits when scanning for the next code.  This may be more bits
129  * than are actually present in the data stream.  If we appear
130  * to run out of data but still have some number of valid bits
131  * remaining then we makeup the requested amount with zeros and
132  * return successfully.  If the returned data is incorrect then
133  * we should be called again and get a premature EOF error;
134  * otherwise we should get the right answer.
135  */
136 #ifndef NeedBits8
137 #define NeedBits8(n,eoflab) do {					\
138     if (BitsAvail < (n)) {						\
139 	if (EndOfData()) {						\
140 	    if (BitsAvail == 0)			/* no valid bits */	\
141 		goto eoflab;						\
142 	    BitsAvail = (n);			/* pad with zeros */	\
143 	} else {							\
144 	    BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;		\
145 	    BitsAvail += 8;						\
146 	}								\
147     }									\
148 } while (0)
149 #endif
150 #ifndef NeedBits16
151 #define NeedBits16(n,eoflab) do {					\
152     if (BitsAvail < (n)) {						\
153 	if (EndOfData()) {						\
154 	    if (BitsAvail == 0)			/* no valid bits */	\
155 		goto eoflab;						\
156 	    BitsAvail = (n);			/* pad with zeros */	\
157 	} else {							\
158 	    BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;		\
159 	    if ((BitsAvail += 8) < (n)) {				\
160 		if (EndOfData()) {					\
161 		    /* NB: we know BitsAvail is non-zero here */	\
162 		    BitsAvail = (n);		/* pad with zeros */	\
163 		} else {						\
164 		    BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail;	\
165 		    BitsAvail += 8;					\
166 		}							\
167 	    }								\
168 	}								\
169     }									\
170 } while (0)
171 #endif
172 #define GetBits(n)	(BitAcc & ((1<<(n))-1))
173 #define ClrBits(n) do {							\
174     BitsAvail -= (n);							\
175     BitAcc >>= (n);							\
176 } while (0)
177 
178 #ifdef FAX3_DEBUG
179 static const char* StateNames[] = {
180     "Null   ",
181     "Pass   ",
182     "Horiz  ",
183     "V0     ",
184     "VR     ",
185     "VL     ",
186     "Ext    ",
187     "TermW  ",
188     "TermB  ",
189     "MakeUpW",
190     "MakeUpB",
191     "MakeUp ",
192     "EOL    ",
193 };
194 #define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0')
195 #define LOOKUP8(wid,tab,eoflab) do {					\
196     int t;								\
197     NeedBits8(wid,eoflab);						\
198     TabEnt = tab + GetBits(wid);					\
199     printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail,		\
200 	   StateNames[TabEnt->State], TabEnt->Param);			\
201     for (t = 0; t < TabEnt->Width; t++)					\
202 	DEBUG_SHOW;							\
203     putchar('\n');							\
204     fflush(stdout);							\
205     ClrBits(TabEnt->Width);						\
206 } while (0)
207 #define LOOKUP16(wid,tab,eoflab) do {					\
208     int t;								\
209     NeedBits16(wid,eoflab);						\
210     TabEnt = tab + GetBits(wid);					\
211     printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail,		\
212 	   StateNames[TabEnt->State], TabEnt->Param);			\
213     for (t = 0; t < TabEnt->Width; t++)					\
214 	DEBUG_SHOW;							\
215     putchar('\n');							\
216     fflush(stdout);							\
217     ClrBits(TabEnt->Width);						\
218 } while (0)
219 
220 #define SETVALUE(x) do {							\
221     *pa++ = RunLength + (x);						\
222     printf("SETVALUE: %d\t%d\n", RunLength + (x), a0);			\
223     a0 += x;								\
224     RunLength = 0;							\
225 } while (0)
226 #else
227 #define LOOKUP8(wid,tab,eoflab) do {					\
228     NeedBits8(wid,eoflab);						\
229     TabEnt = tab + GetBits(wid);					\
230     ClrBits(TabEnt->Width);						\
231 } while (0)
232 #define LOOKUP16(wid,tab,eoflab) do {					\
233     NeedBits16(wid,eoflab);						\
234     TabEnt = tab + GetBits(wid);					\
235     ClrBits(TabEnt->Width);						\
236 } while (0)
237 
238 /*
239  * Append a run to the run length array for the
240  * current row and reset decoding state.
241  */
242 #define SETVALUE(x) do {							\
243     *pa++ = RunLength + (x);						\
244     a0 += (x);								\
245     RunLength = 0;							\
246 } while (0)
247 #endif
248 
249 /*
250  * Synchronize input decoding at the start of each
251  * row by scanning for an EOL (if appropriate) and
252  * skipping any trash data that might be present
253  * after a decoding error.  Note that the decoding
254  * done elsewhere that recognizes an EOL only consumes
255  * 11 consecutive zero bits.  This means that if EOLcnt
256  * is non-zero then we still need to scan for the final flag
257  * bit that is part of the EOL code.
258  */
259 #define	SYNC_EOL(eoflab) do {						\
260     if (EOLcnt == 0) {							\
261 	for (;;) {							\
262 	    NeedBits16(11,eoflab);					\
263 	    if (GetBits(11) == 0)					\
264 		break;							\
265 	    ClrBits(1);							\
266 	}								\
267     }									\
268     for (;;) {								\
269 	NeedBits8(8,eoflab);						\
270 	if (GetBits(8))							\
271 	    break;							\
272 	ClrBits(8);							\
273     }									\
274     while (GetBits(1) == 0)						\
275 	ClrBits(1);							\
276     ClrBits(1);				/* EOL bit */			\
277     EOLcnt = 0;				/* reset EOL counter/flag */	\
278 } while (0)
279 
280 /*
281  * Cleanup the array of runs after decoding a row.
282  * We adjust final runs to insure the user buffer is not
283  * overwritten and/or undecoded area is white filled.
284  */
285 #define	CLEANUP_RUNS() do {						\
286     if (RunLength)							\
287 	SETVALUE(0);							\
288     if (a0 != lastx) {							\
289 	badlength(a0, lastx);						\
290 	while (a0 > lastx && pa > thisrun)				\
291 	    a0 -= *--pa;						\
292 	if (a0 < lastx) {						\
293 	    if (a0 < 0)							\
294 		a0 = 0;							\
295 	    if ((pa-thisrun)&1)						\
296 		SETVALUE(0);						\
297 	    SETVALUE(lastx - a0);						\
298 	} else if (a0 > lastx) {					\
299 	    SETVALUE(lastx);						\
300 	    SETVALUE(0);							\
301 	}								\
302     }									\
303 } while (0)
304 
305 /*
306  * Decode a line of 1D-encoded data.
307  *
308  * The line expanders are written as macros so that they can be reused
309  * but still have direct access to the local variables of the "calling"
310  * function.
311  *
312  * Note that unlike the original version we have to explicitly test for
313  * a0 >= lastx after each black/white run is decoded.  This is because
314  * the original code depended on the input data being zero-padded to
315  * insure the decoder recognized an EOL before running out of data.
316  */
317 #define EXPAND1D(eoflab) do {						\
318     for (;;) {								\
319 	for (;;) {							\
320 	    LOOKUP16(12, TIFFFaxWhiteTable, eof1d);			\
321 	    switch (TabEnt->State) {					\
322 	    case S_EOL:							\
323 		EOLcnt = 1;						\
324 		goto done1d;						\
325 	    case S_TermW:						\
326 		SETVALUE(TabEnt->Param);					\
327 		goto doneWhite1d;					\
328 	    case S_MakeUpW:						\
329 	    case S_MakeUp:						\
330 		a0 += TabEnt->Param;					\
331 		RunLength += TabEnt->Param;				\
332 		break;							\
333 	    default:							\
334 		unexpected("WhiteTable", a0);				\
335 		goto done1d;						\
336 	    }								\
337 	}								\
338     doneWhite1d:							\
339 	if (a0 >= lastx)						\
340 	    goto done1d;						\
341 	for (;;) {							\
342 	    LOOKUP16(13, TIFFFaxBlackTable, eof1d);			\
343 	    switch (TabEnt->State) {					\
344 	    case S_EOL:							\
345 		EOLcnt = 1;						\
346 		goto done1d;						\
347 	    case S_TermB:						\
348 		SETVALUE(TabEnt->Param);					\
349 		goto doneBlack1d;					\
350 	    case S_MakeUpB:						\
351 	    case S_MakeUp:						\
352 		a0 += TabEnt->Param;					\
353 		RunLength += TabEnt->Param;				\
354 		break;							\
355 	    default:							\
356 		unexpected("BlackTable", a0);				\
357 		goto done1d;						\
358 	    }								\
359 	}								\
360     doneBlack1d:							\
361 	if (a0 >= lastx)						\
362 	    goto done1d;						\
363         if( *(pa-1) == 0 && *(pa-2) == 0 )				\
364             pa -= 2;                                                    \
365     }									\
366 eof1d:									\
367     prematureEOF(a0);							\
368     CLEANUP_RUNS();							\
369     goto eoflab;							\
370 done1d:									\
371     CLEANUP_RUNS();							\
372 } while (0)
373 
374 /*
375  * Update the value of b1 using the array
376  * of runs for the reference line.
377  */
378 #define CHECK_b1 do {							\
379     if (pa != thisrun) while (b1 <= a0 && b1 < lastx) {			\
380 	b1 += pb[0] + pb[1];						\
381 	pb += 2;							\
382     }									\
383 } while (0)
384 
385 /*
386  * Expand a row of 2D-encoded data.
387  */
388 #define EXPAND2D(eoflab) do {						\
389     while (a0 < lastx) {						\
390 	LOOKUP8(7, TIFFFaxMainTable, eof2d);				\
391 	switch (TabEnt->State) {					\
392 	case S_Pass:							\
393 	    CHECK_b1;							\
394 	    b1 += *pb++;						\
395 	    RunLength += b1 - a0;					\
396 	    a0 = b1;							\
397 	    b1 += *pb++;						\
398 	    break;							\
399 	case S_Horiz:							\
400 	    if ((pa-thisrun)&1) {					\
401 		for (;;) {	/* black first */			\
402 		    LOOKUP16(13, TIFFFaxBlackTable, eof2d);		\
403 		    switch (TabEnt->State) {				\
404 		    case S_TermB:					\
405 			SETVALUE(TabEnt->Param);				\
406 			goto doneWhite2da;				\
407 		    case S_MakeUpB:					\
408 		    case S_MakeUp:					\
409 			a0 += TabEnt->Param;				\
410 			RunLength += TabEnt->Param;			\
411 			break;						\
412 		    default:						\
413 			goto badBlack2d;				\
414 		    }							\
415 		}							\
416 	    doneWhite2da:;						\
417 		for (;;) {	/* then white */			\
418 		    LOOKUP16(12, TIFFFaxWhiteTable, eof2d);		\
419 		    switch (TabEnt->State) {				\
420 		    case S_TermW:					\
421 			SETVALUE(TabEnt->Param);				\
422 			goto doneBlack2da;				\
423 		    case S_MakeUpW:					\
424 		    case S_MakeUp:					\
425 			a0 += TabEnt->Param;				\
426 			RunLength += TabEnt->Param;			\
427 			break;						\
428 		    default:						\
429 			goto badWhite2d;				\
430 		    }							\
431 		}							\
432 	    doneBlack2da:;						\
433 	    } else {							\
434 		for (;;) {	/* white first */			\
435 		    LOOKUP16(12, TIFFFaxWhiteTable, eof2d);		\
436 		    switch (TabEnt->State) {				\
437 		    case S_TermW:					\
438 			SETVALUE(TabEnt->Param);				\
439 			goto doneWhite2db;				\
440 		    case S_MakeUpW:					\
441 		    case S_MakeUp:					\
442 			a0 += TabEnt->Param;				\
443 			RunLength += TabEnt->Param;			\
444 			break;						\
445 		    default:						\
446 			goto badWhite2d;				\
447 		    }							\
448 		}							\
449 	    doneWhite2db:;						\
450 		for (;;) {	/* then black */			\
451 		    LOOKUP16(13, TIFFFaxBlackTable, eof2d);		\
452 		    switch (TabEnt->State) {				\
453 		    case S_TermB:					\
454 			SETVALUE(TabEnt->Param);				\
455 			goto doneBlack2db;				\
456 		    case S_MakeUpB:					\
457 		    case S_MakeUp:					\
458 			a0 += TabEnt->Param;				\
459 			RunLength += TabEnt->Param;			\
460 			break;						\
461 		    default:						\
462 			goto badBlack2d;				\
463 		    }							\
464 		}							\
465 	    doneBlack2db:;						\
466 	    }								\
467 	    CHECK_b1;							\
468 	    break;							\
469 	case S_V0:							\
470 	    CHECK_b1;							\
471 	    SETVALUE(b1 - a0);						\
472 	    b1 += *pb++;						\
473 	    break;							\
474 	case S_VR:							\
475 	    CHECK_b1;							\
476 	    SETVALUE(b1 - a0 + TabEnt->Param);				\
477 	    b1 += *pb++;						\
478 	    break;							\
479 	case S_VL:							\
480 	    CHECK_b1;							\
481 	    if (b1 <= (int) (a0 + TabEnt->Param)) {			\
482 		if (b1 < (int) (a0 + TabEnt->Param) || pa != thisrun) {	\
483 		    unexpected("VL", a0);				\
484 		    goto eol2d;						\
485 		}							\
486 	    }								\
487 	    SETVALUE(b1 - a0 - TabEnt->Param);				\
488 	    b1 -= *--pb;						\
489 	    break;							\
490 	case S_Ext:							\
491 	    *pa++ = lastx - a0;						\
492 	    extension(a0);						\
493 	    goto eol2d;							\
494 	case S_EOL:							\
495 	    *pa++ = lastx - a0;						\
496 	    NeedBits8(4,eof2d);						\
497 	    if (GetBits(4))						\
498 		unexpected("EOL", a0);					\
499             ClrBits(4);                                                 \
500 	    EOLcnt = 1;							\
501 	    goto eol2d;							\
502 	default:							\
503 	badMain2d:							\
504 	    unexpected("MainTable", a0);				\
505 	    goto eol2d;							\
506 	badBlack2d:							\
507 	    unexpected("BlackTable", a0);				\
508 	    goto eol2d;							\
509 	badWhite2d:							\
510 	    unexpected("WhiteTable", a0);				\
511 	    goto eol2d;							\
512 	eof2d:								\
513 	    prematureEOF(a0);						\
514 	    CLEANUP_RUNS();						\
515 	    goto eoflab;						\
516 	}								\
517     }									\
518     if (RunLength) {							\
519 	if (RunLength + a0 < lastx) {					\
520 	    /* expect a final V0 */					\
521 	    NeedBits8(1,eof2d);						\
522 	    if (!GetBits(1))						\
523 		goto badMain2d;						\
524 	    ClrBits(1);							\
525 	}								\
526 	SETVALUE(0);							\
527     }									\
528 eol2d:									\
529     CLEANUP_RUNS();							\
530 } while (0)
531 #endif /* _FAX3_ */
532 /*
533  * Local Variables:
534  * mode: c
535  * c-basic-offset: 8
536  * fill-column: 78
537  * End:
538  */
539