3 * Copyright (c) 1990-1997 Sam Leffler
4 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6 * Permission to use, copy, modify, distribute, and sell this software and
7 * its documentation for any purpose is hereby granted without fee, provided
8 * that (i) the above copyright notices and this permission notice appear in
9 * all copies of the software and related documentation, and (ii) the names of
10 * Sam Leffler and Silicon Graphics may not be used in any advertising or
11 * publicity relating to the software without the specific, prior written
12 * permission of Sam Leffler and Silicon Graphics.
14 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
15 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
16 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
19 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
20 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
22 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
31 * CCITT Group 3 (T.4) and Group 4 (T.6) Decompression Support.
33 * Decoder support is derived, with permission, from the code
34 * in Frank Cringle's viewfax program;
35 * Copyright (C) 1990, 1995 Frank D. Cringle.
40 * To override the default routine used to image decoded
41 * spans one can use the pseduo tag TIFFTAG_FAXFILLFUNC.
42 * The routine must have the type signature given below;
45 * fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx)
47 * where buf is place to set the bits, runs is the array of b&w run
48 * lengths (white then black), erun is the last run in the array, and
49 * lastx is the width of the row in pixels. Fill routines can assume
50 * the run array has room for at least lastx runs and can overwrite
51 * data in the run array as needed (e.g. to append zero runs to bring
52 * the count up to a nice multiple).
54 typedef void (*TIFFFaxFillFunc
)(unsigned char*, uint32
*, uint32
*, uint32
);
57 * The default run filler; made external for other decoders.
59 #if defined(__cplusplus)
62 extern void _TIFFFax3fillruns(unsigned char*, uint32
*, uint32
*, uint32
);
63 #if defined(__cplusplus)
68 /* finite state machine codes */
83 typedef struct { /* state table entry */
84 unsigned char State
; /* see above */
85 unsigned char Width
; /* width of code in bits */
86 uint32 Param
; /* unsigned 32-bit run length in bits */
89 extern const TIFFFaxTabEnt TIFFFaxMainTable
[];
90 extern const TIFFFaxTabEnt TIFFFaxWhiteTable
[];
91 extern const TIFFFaxTabEnt TIFFFaxBlackTable
[];
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).
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.
105 * NB: to enable a debugging version of these macros define FAX3_DEBUG
106 * before including this file. Trace output goes to stdout.
110 #define EndOfData() (cp >= ep)
113 * Need <=8 or <=16 bits of input data. Unlike viewfax we
114 * cannot use/assume a word-aligned, properly bit swizzled
115 * input data set because data may come from an arbitrarily
116 * aligned, read-only source such as a memory-mapped file.
117 * Note also that the viewfax decoder does not check for
118 * running off the end of the input data buffer. This is
119 * possible for G3-encoded data because it prescans the input
120 * data to count EOL markers, but can cause problems for G4
121 * data. In any event, we don't prescan and must watch for
122 * running out of data since we can't permit the library to
123 * scan past the end of the input data buffer.
125 * Finally, note that we must handle remaindered data at the end
126 * of a strip specially. The coder asks for a fixed number of
127 * bits when scanning for the next code. This may be more bits
128 * than are actually present in the data stream. If we appear
129 * to run out of data but still have some number of valid bits
130 * remaining then we makeup the requested amount with zeros and
131 * return successfully. If the returned data is incorrect then
132 * we should be called again and get a premature EOF error;
133 * otherwise we should get the right answer.
136 #define NeedBits8(n,eoflab) do { \
137 if (BitsAvail < (n)) { \
139 if (BitsAvail == 0) /* no valid bits */ \
141 BitsAvail = (n); /* pad with zeros */ \
143 BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail; \
150 #define NeedBits16(n,eoflab) do { \
151 if (BitsAvail < (n)) { \
153 if (BitsAvail == 0) /* no valid bits */ \
155 BitsAvail = (n); /* pad with zeros */ \
157 BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail; \
158 if ((BitsAvail += 8) < (n)) { \
160 /* NB: we know BitsAvail is non-zero here */ \
161 BitsAvail = (n); /* pad with zeros */ \
163 BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail; \
171 #define GetBits(n) (BitAcc & ((1<<(n))-1))
172 #define ClrBits(n) do { \
178 static const char* StateNames
[] = {
193 #define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0')
194 #define LOOKUP8(wid,tab,eoflab) do { \
196 NeedBits8(wid,eoflab); \
197 TabEnt = tab + GetBits(wid); \
198 printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail, \
199 StateNames[TabEnt->State], TabEnt->Param); \
200 for (t = 0; t < TabEnt->Width; t++) \
204 ClrBits(TabEnt->Width); \
206 #define LOOKUP16(wid,tab,eoflab) do { \
208 NeedBits16(wid,eoflab); \
209 TabEnt = tab + GetBits(wid); \
210 printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail, \
211 StateNames[TabEnt->State], TabEnt->Param); \
212 for (t = 0; t < TabEnt->Width; t++) \
216 ClrBits(TabEnt->Width); \
219 #define SETVALUE(x) do { \
220 *pa++ = RunLength + (x); \
221 printf("SETVALUE: %d\t%d\n", RunLength + (x), a0); \
226 #define LOOKUP8(wid,tab,eoflab) do { \
227 NeedBits8(wid,eoflab); \
228 TabEnt = tab + GetBits(wid); \
229 ClrBits(TabEnt->Width); \
231 #define LOOKUP16(wid,tab,eoflab) do { \
232 NeedBits16(wid,eoflab); \
233 TabEnt = tab + GetBits(wid); \
234 ClrBits(TabEnt->Width); \
238 * Append a run to the run length array for the
239 * current row and reset decoding state.
241 #define SETVALUE(x) do { \
242 *pa++ = RunLength + (x); \
249 * Synchronize input decoding at the start of each
250 * row by scanning for an EOL (if appropriate) and
251 * skipping any trash data that might be present
252 * after a decoding error. Note that the decoding
253 * done elsewhere that recognizes an EOL only consumes
254 * 11 consecutive zero bits. This means that if EOLcnt
255 * is non-zero then we still need to scan for the final flag
256 * bit that is part of the EOL code.
258 #define SYNC_EOL(eoflab) do { \
261 NeedBits16(11,eoflab); \
262 if (GetBits(11) == 0) \
268 NeedBits8(8,eoflab); \
273 while (GetBits(1) == 0) \
275 ClrBits(1); /* EOL bit */ \
276 EOLcnt = 0; /* reset EOL counter/flag */ \
280 * Cleanup the array of runs after decoding a row.
281 * We adjust final runs to insure the user buffer is not
282 * overwritten and/or undecoded area is white filled.
284 #define CLEANUP_RUNS() do { \
288 badlength(a0, lastx); \
289 while (a0 > lastx && pa > thisrun) \
294 if ((pa-thisrun)&1) \
296 SETVALUE(lastx - a0); \
297 } else if (a0 > lastx) { \
305 * Decode a line of 1D-encoded data.
307 * The line expanders are written as macros so that they can be reused
308 * but still have direct access to the local variables of the "calling"
311 * Note that unlike the original version we have to explicitly test for
312 * a0 >= lastx after each black/white run is decoded. This is because
313 * the original code depended on the input data being zero-padded to
314 * insure the decoder recognized an EOL before running out of data.
316 #define EXPAND1D(eoflab) do { \
319 LOOKUP16(12, TIFFFaxWhiteTable, eof1d); \
320 switch (TabEnt->State) { \
325 SETVALUE(TabEnt->Param); \
329 a0 += TabEnt->Param; \
330 RunLength += TabEnt->Param; \
333 unexpected("WhiteTable", a0); \
341 LOOKUP16(13, TIFFFaxBlackTable, eof1d); \
342 switch (TabEnt->State) { \
347 SETVALUE(TabEnt->Param); \
351 a0 += TabEnt->Param; \
352 RunLength += TabEnt->Param; \
355 unexpected("BlackTable", a0); \
362 if( *(pa-1) == 0 && *(pa-2) == 0 ) \
374 * Update the value of b1 using the array
375 * of runs for the reference line.
377 #define CHECK_b1 do { \
378 if (pa != thisrun) while (b1 <= a0 && b1 < lastx) { \
379 b1 += pb[0] + pb[1]; \
385 * Expand a row of 2D-encoded data.
387 #define EXPAND2D(eoflab) do { \
388 while (a0 < lastx) { \
389 LOOKUP8(7, TIFFFaxMainTable, eof2d); \
390 switch (TabEnt->State) { \
394 RunLength += b1 - a0; \
399 if ((pa-thisrun)&1) { \
400 for (;;) { /* black first */ \
401 LOOKUP16(13, TIFFFaxBlackTable, eof2d); \
402 switch (TabEnt->State) { \
404 SETVALUE(TabEnt->Param); \
408 a0 += TabEnt->Param; \
409 RunLength += TabEnt->Param; \
416 for (;;) { /* then white */ \
417 LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \
418 switch (TabEnt->State) { \
420 SETVALUE(TabEnt->Param); \
424 a0 += TabEnt->Param; \
425 RunLength += TabEnt->Param; \
433 for (;;) { /* white first */ \
434 LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \
435 switch (TabEnt->State) { \
437 SETVALUE(TabEnt->Param); \
441 a0 += TabEnt->Param; \
442 RunLength += TabEnt->Param; \
449 for (;;) { /* then black */ \
450 LOOKUP16(13, TIFFFaxBlackTable, eof2d); \
451 switch (TabEnt->State) { \
453 SETVALUE(TabEnt->Param); \
457 a0 += TabEnt->Param; \
458 RunLength += TabEnt->Param; \
475 SETVALUE(b1 - a0 + TabEnt->Param); \
480 if (b1 <= (int) (a0 + TabEnt->Param)) { \
481 if (b1 < (int) (a0 + TabEnt->Param) || pa != thisrun) { \
482 unexpected("VL", a0); \
486 SETVALUE(b1 - a0 - TabEnt->Param); \
490 *pa++ = lastx - a0; \
494 *pa++ = lastx - a0; \
495 NeedBits8(4,eof2d); \
497 unexpected("EOL", a0); \
503 unexpected("MainTable", a0); \
506 unexpected("BlackTable", a0); \
509 unexpected("WhiteTable", a0); \
518 if (RunLength + a0 < lastx) { \
519 /* expect a final V0 */ \
520 NeedBits8(1,eof2d); \