]>
Commit | Line | Data |
---|---|---|
b47c832e RR |
1 | /* $Id$ */ |
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; \ | |
00cb87b4 VZ |
363 | if( *(pa-1) == 0 && *(pa-2) == 0 ) \ |
364 | pa -= 2; \ | |
b47c832e RR |
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; \ | |
00cb87b4 VZ |
490 | NeedBits8(4,eof2d); \ |
491 | if (GetBits(4)) \ | |
b47c832e | 492 | unexpected("EOL", a0); \ |
00cb87b4 | 493 | ClrBits(4); \ |
b47c832e RR |
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_ */ |