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 */ 541