PBRT
|
00001 /* $Id: tif_fax3.h,v 1.5.2.1 2010-06-08 18:50:42 bfriesen Exp $ */ 00002 00003 /* 00004 * Copyright (c) 1990-1997 Sam Leffler 00005 * Copyright (c) 1991-1997 Silicon Graphics, Inc. 00006 * 00007 * Permission to use, copy, modify, distribute, and sell this software and 00008 * its documentation for any purpose is hereby granted without fee, provided 00009 * that (i) the above copyright notices and this permission notice appear in 00010 * all copies of the software and related documentation, and (ii) the names of 00011 * Sam Leffler and Silicon Graphics may not be used in any advertising or 00012 * publicity relating to the software without the specific, prior written 00013 * permission of Sam Leffler and Silicon Graphics. 00014 * 00015 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 00016 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 00017 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 00018 * 00019 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 00020 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 00021 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 00022 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 00023 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 00024 * OF THIS SOFTWARE. 00025 */ 00026 00027 #ifndef _FAX3_ 00028 #define _FAX3_ 00029 /* 00030 * TIFF Library. 00031 * 00032 * CCITT Group 3 (T.4) and Group 4 (T.6) Decompression Support. 00033 * 00034 * Decoder support is derived, with permission, from the code 00035 * in Frank Cringle's viewfax program; 00036 * Copyright (C) 1990, 1995 Frank D. Cringle. 00037 */ 00038 #include "tiff.h" 00039 00040 /* 00041 * To override the default routine used to image decoded 00042 * spans one can use the pseduo tag TIFFTAG_FAXFILLFUNC. 00043 * The routine must have the type signature given below; 00044 * for example: 00045 * 00046 * fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx) 00047 * 00048 * where buf is place to set the bits, runs is the array of b&w run 00049 * lengths (white then black), erun is the last run in the array, and 00050 * lastx is the width of the row in pixels. Fill routines can assume 00051 * the run array has room for at least lastx runs and can overwrite 00052 * data in the run array as needed (e.g. to append zero runs to bring 00053 * the count up to a nice multiple). 00054 */ 00055 typedef void (*TIFFFaxFillFunc)(unsigned char*, uint32*, uint32*, uint32); 00056 00057 /* 00058 * The default run filler; made external for other decoders. 00059 */ 00060 #if defined(__cplusplus) 00061 extern "C" { 00062 #endif 00063 extern void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32); 00064 #if defined(__cplusplus) 00065 } 00066 #endif 00067 00068 00069 /* finite state machine codes */ 00070 #define S_Null 0 00071 #define S_Pass 1 00072 #define S_Horiz 2 00073 #define S_V0 3 00074 #define S_VR 4 00075 #define S_VL 5 00076 #define S_Ext 6 00077 #define S_TermW 7 00078 #define S_TermB 8 00079 #define S_MakeUpW 9 00080 #define S_MakeUpB 10 00081 #define S_MakeUp 11 00082 #define S_EOL 12 00083 00084 typedef struct { /* state table entry */ 00085 unsigned char State; /* see above */ 00086 unsigned char Width; /* width of code in bits */ 00087 uint32 Param; /* unsigned 32-bit run length in bits */ 00088 } TIFFFaxTabEnt; 00089 00090 extern const TIFFFaxTabEnt TIFFFaxMainTable[]; 00091 extern const TIFFFaxTabEnt TIFFFaxWhiteTable[]; 00092 extern const TIFFFaxTabEnt TIFFFaxBlackTable[]; 00093 00094 /* 00095 * The following macros define the majority of the G3/G4 decoder 00096 * algorithm using the state tables defined elsewhere. To build 00097 * a decoder you need some setup code and some glue code. Note 00098 * that you may also need/want to change the way the NeedBits* 00099 * macros get input data if, for example, you know the data to be 00100 * decoded is properly aligned and oriented (doing so before running 00101 * the decoder can be a big performance win). 00102 * 00103 * Consult the decoder in the TIFF library for an idea of what you 00104 * need to define and setup to make use of these definitions. 00105 * 00106 * NB: to enable a debugging version of these macros define FAX3_DEBUG 00107 * before including this file. Trace output goes to stdout. 00108 */ 00109 00110 #ifndef EndOfData 00111 #define EndOfData() (cp >= ep) 00112 #endif 00113 /* 00114 * Need <=8 or <=16 bits of input data. Unlike viewfax we 00115 * cannot use/assume a word-aligned, properly bit swizzled 00116 * input data set because data may come from an arbitrarily 00117 * aligned, read-only source such as a memory-mapped file. 00118 * Note also that the viewfax decoder does not check for 00119 * running off the end of the input data buffer. This is 00120 * possible for G3-encoded data because it prescans the input 00121 * data to count EOL markers, but can cause problems for G4 00122 * data. In any event, we don't prescan and must watch for 00123 * running out of data since we can't permit the library to 00124 * scan past the end of the input data buffer. 00125 * 00126 * Finally, note that we must handle remaindered data at the end 00127 * of a strip specially. The coder asks for a fixed number of 00128 * bits when scanning for the next code. This may be more bits 00129 * than are actually present in the data stream. If we appear 00130 * to run out of data but still have some number of valid bits 00131 * remaining then we makeup the requested amount with zeros and 00132 * return successfully. If the returned data is incorrect then 00133 * we should be called again and get a premature EOF error; 00134 * otherwise we should get the right answer. 00135 */ 00136 #ifndef NeedBits8 00137 #define NeedBits8(n,eoflab) do { \ 00138 if (BitsAvail < (n)) { \ 00139 if (EndOfData()) { \ 00140 if (BitsAvail == 0) /* no valid bits */ \ 00141 goto eoflab; \ 00142 BitsAvail = (n); /* pad with zeros */ \ 00143 } else { \ 00144 BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail; \ 00145 BitsAvail += 8; \ 00146 } \ 00147 } \ 00148 } while (0) 00149 #endif 00150 #ifndef NeedBits16 00151 #define NeedBits16(n,eoflab) do { \ 00152 if (BitsAvail < (n)) { \ 00153 if (EndOfData()) { \ 00154 if (BitsAvail == 0) /* no valid bits */ \ 00155 goto eoflab; \ 00156 BitsAvail = (n); /* pad with zeros */ \ 00157 } else { \ 00158 BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail; \ 00159 if ((BitsAvail += 8) < (n)) { \ 00160 if (EndOfData()) { \ 00161 /* NB: we know BitsAvail is non-zero here */ \ 00162 BitsAvail = (n); /* pad with zeros */ \ 00163 } else { \ 00164 BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail; \ 00165 BitsAvail += 8; \ 00166 } \ 00167 } \ 00168 } \ 00169 } \ 00170 } while (0) 00171 #endif 00172 #define GetBits(n) (BitAcc & ((1<<(n))-1)) 00173 #define ClrBits(n) do { \ 00174 BitsAvail -= (n); \ 00175 BitAcc >>= (n); \ 00176 } while (0) 00177 00178 #ifdef FAX3_DEBUG 00179 static const char* StateNames[] = { 00180 "Null ", 00181 "Pass ", 00182 "Horiz ", 00183 "V0 ", 00184 "VR ", 00185 "VL ", 00186 "Ext ", 00187 "TermW ", 00188 "TermB ", 00189 "MakeUpW", 00190 "MakeUpB", 00191 "MakeUp ", 00192 "EOL ", 00193 }; 00194 #define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0') 00195 #define LOOKUP8(wid,tab,eoflab) do { \ 00196 int t; \ 00197 NeedBits8(wid,eoflab); \ 00198 TabEnt = tab + GetBits(wid); \ 00199 printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail, \ 00200 StateNames[TabEnt->State], TabEnt->Param); \ 00201 for (t = 0; t < TabEnt->Width; t++) \ 00202 DEBUG_SHOW; \ 00203 putchar('\n'); \ 00204 fflush(stdout); \ 00205 ClrBits(TabEnt->Width); \ 00206 } while (0) 00207 #define LOOKUP16(wid,tab,eoflab) do { \ 00208 int t; \ 00209 NeedBits16(wid,eoflab); \ 00210 TabEnt = tab + GetBits(wid); \ 00211 printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail, \ 00212 StateNames[TabEnt->State], TabEnt->Param); \ 00213 for (t = 0; t < TabEnt->Width; t++) \ 00214 DEBUG_SHOW; \ 00215 putchar('\n'); \ 00216 fflush(stdout); \ 00217 ClrBits(TabEnt->Width); \ 00218 } while (0) 00219 00220 #define SETVALUE(x) do { \ 00221 *pa++ = RunLength + (x); \ 00222 printf("SETVALUE: %d\t%d\n", RunLength + (x), a0); \ 00223 a0 += x; \ 00224 RunLength = 0; \ 00225 } while (0) 00226 #else 00227 #define LOOKUP8(wid,tab,eoflab) do { \ 00228 NeedBits8(wid,eoflab); \ 00229 TabEnt = tab + GetBits(wid); \ 00230 ClrBits(TabEnt->Width); \ 00231 } while (0) 00232 #define LOOKUP16(wid,tab,eoflab) do { \ 00233 NeedBits16(wid,eoflab); \ 00234 TabEnt = tab + GetBits(wid); \ 00235 ClrBits(TabEnt->Width); \ 00236 } while (0) 00237 00238 /* 00239 * Append a run to the run length array for the 00240 * current row and reset decoding state. 00241 */ 00242 #define SETVALUE(x) do { \ 00243 *pa++ = RunLength + (x); \ 00244 a0 += (x); \ 00245 RunLength = 0; \ 00246 } while (0) 00247 #endif 00248 00249 /* 00250 * Synchronize input decoding at the start of each 00251 * row by scanning for an EOL (if appropriate) and 00252 * skipping any trash data that might be present 00253 * after a decoding error. Note that the decoding 00254 * done elsewhere that recognizes an EOL only consumes 00255 * 11 consecutive zero bits. This means that if EOLcnt 00256 * is non-zero then we still need to scan for the final flag 00257 * bit that is part of the EOL code. 00258 */ 00259 #define SYNC_EOL(eoflab) do { \ 00260 if (EOLcnt == 0) { \ 00261 for (;;) { \ 00262 NeedBits16(11,eoflab); \ 00263 if (GetBits(11) == 0) \ 00264 break; \ 00265 ClrBits(1); \ 00266 } \ 00267 } \ 00268 for (;;) { \ 00269 NeedBits8(8,eoflab); \ 00270 if (GetBits(8)) \ 00271 break; \ 00272 ClrBits(8); \ 00273 } \ 00274 while (GetBits(1) == 0) \ 00275 ClrBits(1); \ 00276 ClrBits(1); /* EOL bit */ \ 00277 EOLcnt = 0; /* reset EOL counter/flag */ \ 00278 } while (0) 00279 00280 /* 00281 * Cleanup the array of runs after decoding a row. 00282 * We adjust final runs to insure the user buffer is not 00283 * overwritten and/or undecoded area is white filled. 00284 */ 00285 #define CLEANUP_RUNS() do { \ 00286 if (RunLength) \ 00287 SETVALUE(0); \ 00288 if (a0 != lastx) { \ 00289 badlength(a0, lastx); \ 00290 while (a0 > lastx && pa > thisrun) \ 00291 a0 -= *--pa; \ 00292 if (a0 < lastx) { \ 00293 if (a0 < 0) \ 00294 a0 = 0; \ 00295 if ((pa-thisrun)&1) \ 00296 SETVALUE(0); \ 00297 SETVALUE(lastx - a0); \ 00298 } else if (a0 > lastx) { \ 00299 SETVALUE(lastx); \ 00300 SETVALUE(0); \ 00301 } \ 00302 } \ 00303 } while (0) 00304 00305 /* 00306 * Decode a line of 1D-encoded data. 00307 * 00308 * The line expanders are written as macros so that they can be reused 00309 * but still have direct access to the local variables of the "calling" 00310 * function. 00311 * 00312 * Note that unlike the original version we have to explicitly test for 00313 * a0 >= lastx after each black/white run is decoded. This is because 00314 * the original code depended on the input data being zero-padded to 00315 * insure the decoder recognized an EOL before running out of data. 00316 */ 00317 #define EXPAND1D(eoflab) do { \ 00318 for (;;) { \ 00319 for (;;) { \ 00320 LOOKUP16(12, TIFFFaxWhiteTable, eof1d); \ 00321 switch (TabEnt->State) { \ 00322 case S_EOL: \ 00323 EOLcnt = 1; \ 00324 goto done1d; \ 00325 case S_TermW: \ 00326 SETVALUE(TabEnt->Param); \ 00327 goto doneWhite1d; \ 00328 case S_MakeUpW: \ 00329 case S_MakeUp: \ 00330 a0 += TabEnt->Param; \ 00331 RunLength += TabEnt->Param; \ 00332 break; \ 00333 default: \ 00334 unexpected("WhiteTable", a0); \ 00335 goto done1d; \ 00336 } \ 00337 } \ 00338 doneWhite1d: \ 00339 if (a0 >= lastx) \ 00340 goto done1d; \ 00341 for (;;) { \ 00342 LOOKUP16(13, TIFFFaxBlackTable, eof1d); \ 00343 switch (TabEnt->State) { \ 00344 case S_EOL: \ 00345 EOLcnt = 1; \ 00346 goto done1d; \ 00347 case S_TermB: \ 00348 SETVALUE(TabEnt->Param); \ 00349 goto doneBlack1d; \ 00350 case S_MakeUpB: \ 00351 case S_MakeUp: \ 00352 a0 += TabEnt->Param; \ 00353 RunLength += TabEnt->Param; \ 00354 break; \ 00355 default: \ 00356 unexpected("BlackTable", a0); \ 00357 goto done1d; \ 00358 } \ 00359 } \ 00360 doneBlack1d: \ 00361 if (a0 >= lastx) \ 00362 goto done1d; \ 00363 if( *(pa-1) == 0 && *(pa-2) == 0 ) \ 00364 pa -= 2; \ 00365 } \ 00366 eof1d: \ 00367 prematureEOF(a0); \ 00368 CLEANUP_RUNS(); \ 00369 goto eoflab; \ 00370 done1d: \ 00371 CLEANUP_RUNS(); \ 00372 } while (0) 00373 00374 /* 00375 * Update the value of b1 using the array 00376 * of runs for the reference line. 00377 */ 00378 #define CHECK_b1 do { \ 00379 if (pa != thisrun) while (b1 <= a0 && b1 < lastx) { \ 00380 b1 += pb[0] + pb[1]; \ 00381 pb += 2; \ 00382 } \ 00383 } while (0) 00384 00385 /* 00386 * Expand a row of 2D-encoded data. 00387 */ 00388 #define EXPAND2D(eoflab) do { \ 00389 while (a0 < lastx) { \ 00390 LOOKUP8(7, TIFFFaxMainTable, eof2d); \ 00391 switch (TabEnt->State) { \ 00392 case S_Pass: \ 00393 CHECK_b1; \ 00394 b1 += *pb++; \ 00395 RunLength += b1 - a0; \ 00396 a0 = b1; \ 00397 b1 += *pb++; \ 00398 break; \ 00399 case S_Horiz: \ 00400 if ((pa-thisrun)&1) { \ 00401 for (;;) { /* black first */ \ 00402 LOOKUP16(13, TIFFFaxBlackTable, eof2d); \ 00403 switch (TabEnt->State) { \ 00404 case S_TermB: \ 00405 SETVALUE(TabEnt->Param); \ 00406 goto doneWhite2da; \ 00407 case S_MakeUpB: \ 00408 case S_MakeUp: \ 00409 a0 += TabEnt->Param; \ 00410 RunLength += TabEnt->Param; \ 00411 break; \ 00412 default: \ 00413 goto badBlack2d; \ 00414 } \ 00415 } \ 00416 doneWhite2da:; \ 00417 for (;;) { /* then white */ \ 00418 LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \ 00419 switch (TabEnt->State) { \ 00420 case S_TermW: \ 00421 SETVALUE(TabEnt->Param); \ 00422 goto doneBlack2da; \ 00423 case S_MakeUpW: \ 00424 case S_MakeUp: \ 00425 a0 += TabEnt->Param; \ 00426 RunLength += TabEnt->Param; \ 00427 break; \ 00428 default: \ 00429 goto badWhite2d; \ 00430 } \ 00431 } \ 00432 doneBlack2da:; \ 00433 } else { \ 00434 for (;;) { /* white first */ \ 00435 LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \ 00436 switch (TabEnt->State) { \ 00437 case S_TermW: \ 00438 SETVALUE(TabEnt->Param); \ 00439 goto doneWhite2db; \ 00440 case S_MakeUpW: \ 00441 case S_MakeUp: \ 00442 a0 += TabEnt->Param; \ 00443 RunLength += TabEnt->Param; \ 00444 break; \ 00445 default: \ 00446 goto badWhite2d; \ 00447 } \ 00448 } \ 00449 doneWhite2db:; \ 00450 for (;;) { /* then black */ \ 00451 LOOKUP16(13, TIFFFaxBlackTable, eof2d); \ 00452 switch (TabEnt->State) { \ 00453 case S_TermB: \ 00454 SETVALUE(TabEnt->Param); \ 00455 goto doneBlack2db; \ 00456 case S_MakeUpB: \ 00457 case S_MakeUp: \ 00458 a0 += TabEnt->Param; \ 00459 RunLength += TabEnt->Param; \ 00460 break; \ 00461 default: \ 00462 goto badBlack2d; \ 00463 } \ 00464 } \ 00465 doneBlack2db:; \ 00466 } \ 00467 CHECK_b1; \ 00468 break; \ 00469 case S_V0: \ 00470 CHECK_b1; \ 00471 SETVALUE(b1 - a0); \ 00472 b1 += *pb++; \ 00473 break; \ 00474 case S_VR: \ 00475 CHECK_b1; \ 00476 SETVALUE(b1 - a0 + TabEnt->Param); \ 00477 b1 += *pb++; \ 00478 break; \ 00479 case S_VL: \ 00480 CHECK_b1; \ 00481 SETVALUE(b1 - a0 - TabEnt->Param); \ 00482 b1 -= *--pb; \ 00483 break; \ 00484 case S_Ext: \ 00485 *pa++ = lastx - a0; \ 00486 extension(a0); \ 00487 goto eol2d; \ 00488 case S_EOL: \ 00489 *pa++ = lastx - a0; \ 00490 NeedBits8(4,eof2d); \ 00491 if (GetBits(4)) \ 00492 unexpected("EOL", a0); \ 00493 ClrBits(4); \ 00494 EOLcnt = 1; \ 00495 goto eol2d; \ 00496 default: \ 00497 badMain2d: \ 00498 unexpected("MainTable", a0); \ 00499 goto eol2d; \ 00500 badBlack2d: \ 00501 unexpected("BlackTable", a0); \ 00502 goto eol2d; \ 00503 badWhite2d: \ 00504 unexpected("WhiteTable", a0); \ 00505 goto eol2d; \ 00506 eof2d: \ 00507 prematureEOF(a0); \ 00508 CLEANUP_RUNS(); \ 00509 goto eoflab; \ 00510 } \ 00511 } \ 00512 if (RunLength) { \ 00513 if (RunLength + a0 < lastx) { \ 00514 /* expect a final V0 */ \ 00515 NeedBits8(1,eof2d); \ 00516 if (!GetBits(1)) \ 00517 goto badMain2d; \ 00518 ClrBits(1); \ 00519 } \ 00520 SETVALUE(0); \ 00521 } \ 00522 eol2d: \ 00523 CLEANUP_RUNS(); \ 00524 } while (0) 00525 #endif /* _FAX3_ */ 00526 /* 00527 * Local Variables: 00528 * mode: c 00529 * c-basic-offset: 8 00530 * fill-column: 78 00531 * End: 00532 */