OLD | NEW |
| (Empty) |
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 */ | |
OLD | NEW |