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 */ 55typedef void (*TIFFFaxFillFunc)(unsigned char*, uint32*, uint32*, uint32); 56 57/* 58 * The default run filler; made external for other decoders. 59 */ 60#if defined(__cplusplus) 61extern "C" { 62#endif 63extern 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 84typedef 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 90extern const TIFFFaxTabEnt TIFFFaxMainTable[]; 91extern const TIFFFaxTabEnt TIFFFaxWhiteTable[]; 92extern 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 179static 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 } \ 366eof1d: \ 367 prematureEOF(a0); \ 368 CLEANUP_RUNS(); \ 369 goto eoflab; \ 370done1d: \ 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 } \ 528eol2d: \ 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 */ 539