Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / libtiff / tif_fax3.h
1 /* $Id: tif_fax3.h,v 1.1 2005-06-17 13:54:52 vp153 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 SETVAL(x) do {                                                  \
221     *pa++ = RunLength + (x);                                            \
222     printf("SETVAL: %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 SETVAL(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         SETVAL(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                 SETVAL(0);                                              \
297             SETVAL(lastx - a0);                                         \
298         } else if (a0 > lastx) {                                        \
299             SETVAL(lastx);                                              \
300             SETVAL(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                 SETVAL(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                 SETVAL(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                         SETVAL(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                         SETVAL(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                         SETVAL(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                         SETVAL(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             SETVAL(b1 - a0);                                            \
472             b1 += *pb++;                                                \
473             break;                                                      \
474         case S_VR:                                                      \
475             CHECK_b1;                                                   \
476             SETVAL(b1 - a0 + TabEnt->Param);                            \
477             b1 += *pb++;                                                \
478             break;                                                      \
479         case S_VL:                                                      \
480             CHECK_b1;                                                   \
481             SETVAL(b1 - a0 - TabEnt->Param);                            \
482             b1 -= *--pb;                                                \
483             break;                                                      \
484         case S_Ext:                                                     \
485             *pa++ = lastx - a0;                                         \
486             extension(a0);                                              \
487             goto eol2d;                                                 \
488         case S_EOL:                                                     \
489             *pa++ = lastx - a0;                                         \
490             NeedBits8(4,eof2d);                                         \
491             if (GetBits(4))                                             \
492                 unexpected("EOL", a0);                                  \
493             ClrBits(4);                                                 \
494             EOLcnt = 1;                                                 \
495             goto eol2d;                                                 \
496         default:                                                        \
497         badMain2d:                                                      \
498             unexpected("MainTable", a0);                                \
499             goto eol2d;                                                 \
500         badBlack2d:                                                     \
501             unexpected("BlackTable", a0);                               \
502             goto eol2d;                                                 \
503         badWhite2d:                                                     \
504             unexpected("WhiteTable", a0);                               \
505             goto eol2d;                                                 \
506         eof2d:                                                          \
507             prematureEOF(a0);                                           \
508             CLEANUP_RUNS();                                             \
509             goto eoflab;                                                \
510         }                                                               \
511     }                                                                   \
512     if (RunLength) {                                                    \
513         if (RunLength + a0 < lastx) {                                   \
514             /* expect a final V0 */                                     \
515             NeedBits8(1,eof2d);                                         \
516             if (!GetBits(1))                                            \
517                 goto badMain2d;                                         \
518             ClrBits(1);                                                 \
519         }                                                               \
520         SETVAL(0);                                                      \
521     }                                                                   \
522 eol2d:                                                                  \
523     CLEANUP_RUNS();                                                     \
524 } while (0)
525 #endif /* _FAX3_ */