8a435059c7b3c95c2aa944fb61c3932fbbeb5f75
[reactos.git] / sdk / include / reactos / libs / libtiff / tif_fax3.h
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 */