1 /* $Id: tif_predict.c,v 1.32 2010-03-10 18:56:49 bfriesen Exp $ */ 2 3 /* 4 * Copyright (c) 1988-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 /* 28 * TIFF Library. 29 * 30 * Predictor Tag Support (used by multiple codecs). 31 */ 32 #include "tiffiop.h" 33 #include "tif_predict.h" 34 35 #define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data) 36 37 static void horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc); 38 static void horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc); 39 static void horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc); 40 static void swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc); 41 static void swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc); 42 static void horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc); 43 static void horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc); 44 static void horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc); 45 static void fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc); 46 static void fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc); 47 static int PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s); 48 static int PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s); 49 static int PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); 50 static int PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s); 51 52 static int 53 PredictorSetup(TIFF* tif) 54 { 55 static const char module[] = "PredictorSetup"; 56 57 TIFFPredictorState* sp = PredictorState(tif); 58 TIFFDirectory* td = &tif->tif_dir; 59 60 switch (sp->predictor) /* no differencing */ 61 { 62 case PREDICTOR_NONE: 63 return 1; 64 case PREDICTOR_HORIZONTAL: 65 if (td->td_bitspersample != 8 66 && td->td_bitspersample != 16 67 && td->td_bitspersample != 32) { 68 TIFFErrorExt(tif->tif_clientdata, module, 69 "Horizontal differencing \"Predictor\" not supported with %d-bit samples", 70 td->td_bitspersample); 71 return 0; 72 } 73 break; 74 case PREDICTOR_FLOATINGPOINT: 75 if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) { 76 TIFFErrorExt(tif->tif_clientdata, module, 77 "Floating point \"Predictor\" not supported with %d data format", 78 td->td_sampleformat); 79 return 0; 80 } 81 break; 82 default: 83 TIFFErrorExt(tif->tif_clientdata, module, 84 "\"Predictor\" value %d not supported", 85 sp->predictor); 86 return 0; 87 } 88 sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? 89 td->td_samplesperpixel : 1); 90 /* 91 * Calculate the scanline/tile-width size in bytes. 92 */ 93 if (isTiled(tif)) 94 sp->rowsize = TIFFTileRowSize(tif); 95 else 96 sp->rowsize = TIFFScanlineSize(tif); 97 if (sp->rowsize == 0) 98 return 0; 99 100 return 1; 101 } 102 103 static int 104 PredictorSetupDecode(TIFF* tif) 105 { 106 TIFFPredictorState* sp = PredictorState(tif); 107 TIFFDirectory* td = &tif->tif_dir; 108 109 if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif)) 110 return 0; 111 112 if (sp->predictor == 2) { 113 switch (td->td_bitspersample) { 114 case 8: sp->decodepfunc = horAcc8; break; 115 case 16: sp->decodepfunc = horAcc16; break; 116 case 32: sp->decodepfunc = horAcc32; break; 117 } 118 /* 119 * Override default decoding method with one that does the 120 * predictor stuff. 121 */ 122 if( tif->tif_decoderow != PredictorDecodeRow ) 123 { 124 sp->decoderow = tif->tif_decoderow; 125 tif->tif_decoderow = PredictorDecodeRow; 126 sp->decodestrip = tif->tif_decodestrip; 127 tif->tif_decodestrip = PredictorDecodeTile; 128 sp->decodetile = tif->tif_decodetile; 129 tif->tif_decodetile = PredictorDecodeTile; 130 } 131 132 /* 133 * If the data is horizontally differenced 16-bit data that 134 * requires byte-swapping, then it must be byte swapped before 135 * the accumulation step. We do this with a special-purpose 136 * routine and override the normal post decoding logic that 137 * the library setup when the directory was read. 138 */ 139 if (tif->tif_flags & TIFF_SWAB) { 140 if (sp->decodepfunc == horAcc16) { 141 sp->decodepfunc = swabHorAcc16; 142 tif->tif_postdecode = _TIFFNoPostDecode; 143 } else if (sp->decodepfunc == horAcc32) { 144 sp->decodepfunc = swabHorAcc32; 145 tif->tif_postdecode = _TIFFNoPostDecode; 146 } 147 } 148 } 149 150 else if (sp->predictor == 3) { 151 sp->decodepfunc = fpAcc; 152 /* 153 * Override default decoding method with one that does the 154 * predictor stuff. 155 */ 156 if( tif->tif_decoderow != PredictorDecodeRow ) 157 { 158 sp->decoderow = tif->tif_decoderow; 159 tif->tif_decoderow = PredictorDecodeRow; 160 sp->decodestrip = tif->tif_decodestrip; 161 tif->tif_decodestrip = PredictorDecodeTile; 162 sp->decodetile = tif->tif_decodetile; 163 tif->tif_decodetile = PredictorDecodeTile; 164 } 165 /* 166 * The data should not be swapped outside of the floating 167 * point predictor, the accumulation routine should return 168 * byres in the native order. 169 */ 170 if (tif->tif_flags & TIFF_SWAB) { 171 tif->tif_postdecode = _TIFFNoPostDecode; 172 } 173 /* 174 * Allocate buffer to keep the decoded bytes before 175 * rearranging in the ight order 176 */ 177 } 178 179 return 1; 180 } 181 182 static int 183 PredictorSetupEncode(TIFF* tif) 184 { 185 TIFFPredictorState* sp = PredictorState(tif); 186 TIFFDirectory* td = &tif->tif_dir; 187 188 if (!(*sp->setupencode)(tif) || !PredictorSetup(tif)) 189 return 0; 190 191 if (sp->predictor == 2) { 192 switch (td->td_bitspersample) { 193 case 8: sp->encodepfunc = horDiff8; break; 194 case 16: sp->encodepfunc = horDiff16; break; 195 case 32: sp->encodepfunc = horDiff32; break; 196 } 197 /* 198 * Override default encoding method with one that does the 199 * predictor stuff. 200 */ 201 if( tif->tif_encoderow != PredictorEncodeRow ) 202 { 203 sp->encoderow = tif->tif_encoderow; 204 tif->tif_encoderow = PredictorEncodeRow; 205 sp->encodestrip = tif->tif_encodestrip; 206 tif->tif_encodestrip = PredictorEncodeTile; 207 sp->encodetile = tif->tif_encodetile; 208 tif->tif_encodetile = PredictorEncodeTile; 209 } 210 } 211 212 else if (sp->predictor == 3) { 213 sp->encodepfunc = fpDiff; 214 /* 215 * Override default encoding method with one that does the 216 * predictor stuff. 217 */ 218 if( tif->tif_encoderow != PredictorEncodeRow ) 219 { 220 sp->encoderow = tif->tif_encoderow; 221 tif->tif_encoderow = PredictorEncodeRow; 222 sp->encodestrip = tif->tif_encodestrip; 223 tif->tif_encodestrip = PredictorEncodeTile; 224 sp->encodetile = tif->tif_encodetile; 225 tif->tif_encodetile = PredictorEncodeTile; 226 } 227 } 228 229 return 1; 230 } 231 232 #define REPEAT4(n, op) \ 233 switch (n) { \ 234 default: { tmsize_t i; for (i = n-4; i > 0; i--) { op; } } \ 235 case 4: op; \ 236 case 3: op; \ 237 case 2: op; \ 238 case 1: op; \ 239 case 0: ; \ 240 } 241 242 static void 243 horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc) 244 { 245 tmsize_t stride = PredictorState(tif)->stride; 246 247 char* cp = (char*) cp0; 248 assert((cc%stride)==0); 249 if (cc > stride) { 250 /* 251 * Pipeline the most common cases. 252 */ 253 if (stride == 3) { 254 unsigned int cr = cp[0]; 255 unsigned int cg = cp[1]; 256 unsigned int cb = cp[2]; 257 cc -= 3; 258 cp += 3; 259 while (cc>0) { 260 cp[0] = (char) (cr += cp[0]); 261 cp[1] = (char) (cg += cp[1]); 262 cp[2] = (char) (cb += cp[2]); 263 cc -= 3; 264 cp += 3; 265 } 266 } else if (stride == 4) { 267 unsigned int cr = cp[0]; 268 unsigned int cg = cp[1]; 269 unsigned int cb = cp[2]; 270 unsigned int ca = cp[3]; 271 cc -= 4; 272 cp += 4; 273 while (cc>0) { 274 cp[0] = (char) (cr += cp[0]); 275 cp[1] = (char) (cg += cp[1]); 276 cp[2] = (char) (cb += cp[2]); 277 cp[3] = (char) (ca += cp[3]); 278 cc -= 4; 279 cp += 4; 280 } 281 } else { 282 cc -= stride; 283 do { 284 REPEAT4(stride, cp[stride] = 285 (char) (cp[stride] + *cp); cp++) 286 cc -= stride; 287 } while (cc>0); 288 } 289 } 290 } 291 292 static void 293 swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) 294 { 295 tmsize_t stride = PredictorState(tif)->stride; 296 uint16* wp = (uint16*) cp0; 297 tmsize_t wc = cc / 2; 298 299 assert((cc%(2*stride))==0); 300 301 if (wc > stride) { 302 TIFFSwabArrayOfShort(wp, wc); 303 wc -= stride; 304 do { 305 REPEAT4(stride, wp[stride] += wp[0]; wp++) 306 wc -= stride; 307 } while (wc > 0); 308 } 309 } 310 311 static void 312 horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) 313 { 314 tmsize_t stride = PredictorState(tif)->stride; 315 uint16* wp = (uint16*) cp0; 316 tmsize_t wc = cc / 2; 317 318 assert((cc%(2*stride))==0); 319 320 if (wc > stride) { 321 wc -= stride; 322 do { 323 REPEAT4(stride, wp[stride] += wp[0]; wp++) 324 wc -= stride; 325 } while (wc > 0); 326 } 327 } 328 329 static void 330 swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) 331 { 332 tmsize_t stride = PredictorState(tif)->stride; 333 uint32* wp = (uint32*) cp0; 334 tmsize_t wc = cc / 4; 335 336 assert((cc%(4*stride))==0); 337 338 if (wc > stride) { 339 TIFFSwabArrayOfLong(wp, wc); 340 wc -= stride; 341 do { 342 REPEAT4(stride, wp[stride] += wp[0]; wp++) 343 wc -= stride; 344 } while (wc > 0); 345 } 346 } 347 348 static void 349 horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) 350 { 351 tmsize_t stride = PredictorState(tif)->stride; 352 uint32* wp = (uint32*) cp0; 353 tmsize_t wc = cc / 4; 354 355 assert((cc%(4*stride))==0); 356 357 if (wc > stride) { 358 wc -= stride; 359 do { 360 REPEAT4(stride, wp[stride] += wp[0]; wp++) 361 wc -= stride; 362 } while (wc > 0); 363 } 364 } 365 366 /* 367 * Floating point predictor accumulation routine. 368 */ 369 static void 370 fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc) 371 { 372 tmsize_t stride = PredictorState(tif)->stride; 373 uint32 bps = tif->tif_dir.td_bitspersample / 8; 374 tmsize_t wc = cc / bps; 375 tmsize_t count = cc; 376 uint8 *cp = (uint8 *) cp0; 377 uint8 *tmp = (uint8 *)_TIFFmalloc(cc); 378 379 assert((cc%(bps*stride))==0); 380 381 if (!tmp) 382 return; 383 384 while (count > stride) { 385 REPEAT4(stride, cp[stride] += cp[0]; cp++) 386 count -= stride; 387 } 388 389 _TIFFmemcpy(tmp, cp0, cc); 390 cp = (uint8 *) cp0; 391 for (count = 0; count < wc; count++) { 392 uint32 byte; 393 for (byte = 0; byte < bps; byte++) { 394 #if WORDS_BIGENDIAN 395 cp[bps * count + byte] = tmp[byte * wc + count]; 396 #else 397 cp[bps * count + byte] = 398 tmp[(bps - byte - 1) * wc + count]; 399 #endif 400 } 401 } 402 _TIFFfree(tmp); 403 } 404 405 /* 406 * Decode a scanline and apply the predictor routine. 407 */ 408 static int 409 PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) 410 { 411 TIFFPredictorState *sp = PredictorState(tif); 412 413 assert(sp != NULL); 414 assert(sp->decoderow != NULL); 415 assert(sp->decodepfunc != NULL); 416 417 if ((*sp->decoderow)(tif, op0, occ0, s)) { 418 (*sp->decodepfunc)(tif, op0, occ0); 419 return 1; 420 } else 421 return 0; 422 } 423 424 /* 425 * Decode a tile/strip and apply the predictor routine. 426 * Note that horizontal differencing must be done on a 427 * row-by-row basis. The width of a "row" has already 428 * been calculated at pre-decode time according to the 429 * strip/tile dimensions. 430 */ 431 static int 432 PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) 433 { 434 TIFFPredictorState *sp = PredictorState(tif); 435 436 assert(sp != NULL); 437 assert(sp->decodetile != NULL); 438 439 if ((*sp->decodetile)(tif, op0, occ0, s)) { 440 tmsize_t rowsize = sp->rowsize; 441 assert(rowsize > 0); 442 assert((occ0%rowsize)==0); 443 assert(sp->decodepfunc != NULL); 444 while (occ0 > 0) { 445 (*sp->decodepfunc)(tif, op0, rowsize); 446 occ0 -= rowsize; 447 op0 += rowsize; 448 } 449 return 1; 450 } else 451 return 0; 452 } 453 454 static void 455 horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc) 456 { 457 TIFFPredictorState* sp = PredictorState(tif); 458 tmsize_t stride = sp->stride; 459 char* cp = (char*) cp0; 460 461 assert((cc%stride)==0); 462 463 if (cc > stride) { 464 cc -= stride; 465 /* 466 * Pipeline the most common cases. 467 */ 468 if (stride == 3) { 469 int r1, g1, b1; 470 int r2 = cp[0]; 471 int g2 = cp[1]; 472 int b2 = cp[2]; 473 do { 474 r1 = cp[3]; cp[3] = r1-r2; r2 = r1; 475 g1 = cp[4]; cp[4] = g1-g2; g2 = g1; 476 b1 = cp[5]; cp[5] = b1-b2; b2 = b1; 477 cp += 3; 478 } while ((cc -= 3) > 0); 479 } else if (stride == 4) { 480 int r1, g1, b1, a1; 481 int r2 = cp[0]; 482 int g2 = cp[1]; 483 int b2 = cp[2]; 484 int a2 = cp[3]; 485 do { 486 r1 = cp[4]; cp[4] = r1-r2; r2 = r1; 487 g1 = cp[5]; cp[5] = g1-g2; g2 = g1; 488 b1 = cp[6]; cp[6] = b1-b2; b2 = b1; 489 a1 = cp[7]; cp[7] = a1-a2; a2 = a1; 490 cp += 4; 491 } while ((cc -= 4) > 0); 492 } else { 493 cp += cc - 1; 494 do { 495 REPEAT4(stride, cp[stride] -= cp[0]; cp--) 496 } while ((cc -= stride) > 0); 497 } 498 } 499 } 500 501 static void 502 horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc) 503 { 504 TIFFPredictorState* sp = PredictorState(tif); 505 tmsize_t stride = sp->stride; 506 int16 *wp = (int16*) cp0; 507 tmsize_t wc = cc/2; 508 509 assert((cc%(2*stride))==0); 510 511 if (wc > stride) { 512 wc -= stride; 513 wp += wc - 1; 514 do { 515 REPEAT4(stride, wp[stride] -= wp[0]; wp--) 516 wc -= stride; 517 } while (wc > 0); 518 } 519 } 520 521 static void 522 horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc) 523 { 524 TIFFPredictorState* sp = PredictorState(tif); 525 tmsize_t stride = sp->stride; 526 int32 *wp = (int32*) cp0; 527 tmsize_t wc = cc/4; 528 529 assert((cc%(4*stride))==0); 530 531 if (wc > stride) { 532 wc -= stride; 533 wp += wc - 1; 534 do { 535 REPEAT4(stride, wp[stride] -= wp[0]; wp--) 536 wc -= stride; 537 } while (wc > 0); 538 } 539 } 540 541 /* 542 * Floating point predictor differencing routine. 543 */ 544 static void 545 fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc) 546 { 547 tmsize_t stride = PredictorState(tif)->stride; 548 uint32 bps = tif->tif_dir.td_bitspersample / 8; 549 tmsize_t wc = cc / bps; 550 tmsize_t count; 551 uint8 *cp = (uint8 *) cp0; 552 uint8 *tmp = (uint8 *)_TIFFmalloc(cc); 553 554 assert((cc%(bps*stride))==0); 555 556 if (!tmp) 557 return; 558 559 _TIFFmemcpy(tmp, cp0, cc); 560 for (count = 0; count < wc; count++) { 561 uint32 byte; 562 for (byte = 0; byte < bps; byte++) { 563 #if WORDS_BIGENDIAN 564 cp[byte * wc + count] = tmp[bps * count + byte]; 565 #else 566 cp[(bps - byte - 1) * wc + count] = 567 tmp[bps * count + byte]; 568 #endif 569 } 570 } 571 _TIFFfree(tmp); 572 573 cp = (uint8 *) cp0; 574 cp += cc - stride - 1; 575 for (count = cc; count > stride; count -= stride) 576 REPEAT4(stride, cp[stride] -= cp[0]; cp--) 577 } 578 579 static int 580 PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) 581 { 582 TIFFPredictorState *sp = PredictorState(tif); 583 584 assert(sp != NULL); 585 assert(sp->encodepfunc != NULL); 586 assert(sp->encoderow != NULL); 587 588 /* XXX horizontal differencing alters user's data XXX */ 589 (*sp->encodepfunc)(tif, bp, cc); 590 return (*sp->encoderow)(tif, bp, cc, s); 591 } 592 593 static int 594 PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s) 595 { 596 static const char module[] = "PredictorEncodeTile"; 597 TIFFPredictorState *sp = PredictorState(tif); 598 uint8 *working_copy; 599 tmsize_t cc = cc0, rowsize; 600 unsigned char* bp; 601 int result_code; 602 603 assert(sp != NULL); 604 assert(sp->encodepfunc != NULL); 605 assert(sp->encodetile != NULL); 606 607 /* 608 * Do predictor manipulation in a working buffer to avoid altering 609 * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965 610 */ 611 working_copy = (uint8*) _TIFFmalloc(cc0); 612 if( working_copy == NULL ) 613 { 614 TIFFErrorExt(tif->tif_clientdata, module, 615 "Out of memory allocating " TIFF_SSIZE_FORMAT " byte temp buffer.", 616 cc0 ); 617 return 0; 618 } 619 memcpy( working_copy, bp0, cc0 ); 620 bp = working_copy; 621 622 rowsize = sp->rowsize; 623 assert(rowsize > 0); 624 assert((cc0%rowsize)==0); 625 while (cc > 0) { 626 (*sp->encodepfunc)(tif, bp, rowsize); 627 cc -= rowsize; 628 bp += rowsize; 629 } 630 result_code = (*sp->encodetile)(tif, working_copy, cc0, s); 631 632 _TIFFfree( working_copy ); 633 634 return result_code; 635 } 636 637 #define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */ 638 639 static const TIFFField predictFields[] = { 640 { TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL }, 641 }; 642 643 static int 644 PredictorVSetField(TIFF* tif, uint32 tag, va_list ap) 645 { 646 TIFFPredictorState *sp = PredictorState(tif); 647 648 assert(sp != NULL); 649 assert(sp->vsetparent != NULL); 650 651 switch (tag) { 652 case TIFFTAG_PREDICTOR: 653 sp->predictor = (uint16) va_arg(ap, uint16_vap); 654 TIFFSetFieldBit(tif, FIELD_PREDICTOR); 655 break; 656 default: 657 return (*sp->vsetparent)(tif, tag, ap); 658 } 659 tif->tif_flags |= TIFF_DIRTYDIRECT; 660 return 1; 661 } 662 663 static int 664 PredictorVGetField(TIFF* tif, uint32 tag, va_list ap) 665 { 666 TIFFPredictorState *sp = PredictorState(tif); 667 668 assert(sp != NULL); 669 assert(sp->vgetparent != NULL); 670 671 switch (tag) { 672 case TIFFTAG_PREDICTOR: 673 *va_arg(ap, uint16*) = sp->predictor; 674 break; 675 default: 676 return (*sp->vgetparent)(tif, tag, ap); 677 } 678 return 1; 679 } 680 681 static void 682 PredictorPrintDir(TIFF* tif, FILE* fd, long flags) 683 { 684 TIFFPredictorState* sp = PredictorState(tif); 685 686 (void) flags; 687 if (TIFFFieldSet(tif,FIELD_PREDICTOR)) { 688 fprintf(fd, " Predictor: "); 689 switch (sp->predictor) { 690 case 1: fprintf(fd, "none "); break; 691 case 2: fprintf(fd, "horizontal differencing "); break; 692 case 3: fprintf(fd, "floating point predictor "); break; 693 } 694 fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor); 695 } 696 if (sp->printdir) 697 (*sp->printdir)(tif, fd, flags); 698 } 699 700 int 701 TIFFPredictorInit(TIFF* tif) 702 { 703 TIFFPredictorState* sp = PredictorState(tif); 704 705 assert(sp != 0); 706 707 /* 708 * Merge codec-specific tag information. 709 */ 710 if (!_TIFFMergeFields(tif, predictFields, 711 TIFFArrayCount(predictFields))) { 712 TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit", 713 "Merging Predictor codec-specific tags failed"); 714 return 0; 715 } 716 717 /* 718 * Override parent get/set field methods. 719 */ 720 sp->vgetparent = tif->tif_tagmethods.vgetfield; 721 tif->tif_tagmethods.vgetfield = 722 PredictorVGetField;/* hook for predictor tag */ 723 sp->vsetparent = tif->tif_tagmethods.vsetfield; 724 tif->tif_tagmethods.vsetfield = 725 PredictorVSetField;/* hook for predictor tag */ 726 sp->printdir = tif->tif_tagmethods.printdir; 727 tif->tif_tagmethods.printdir = 728 PredictorPrintDir; /* hook for predictor tag */ 729 730 sp->setupdecode = tif->tif_setupdecode; 731 tif->tif_setupdecode = PredictorSetupDecode; 732 sp->setupencode = tif->tif_setupencode; 733 tif->tif_setupencode = PredictorSetupEncode; 734 735 sp->predictor = 1; /* default value */ 736 sp->encodepfunc = NULL; /* no predictor routine */ 737 sp->decodepfunc = NULL; /* no predictor routine */ 738 return 1; 739 } 740 741 int 742 TIFFPredictorCleanup(TIFF* tif) 743 { 744 TIFFPredictorState* sp = PredictorState(tif); 745 746 assert(sp != 0); 747 748 tif->tif_tagmethods.vgetfield = sp->vgetparent; 749 tif->tif_tagmethods.vsetfield = sp->vsetparent; 750 tif->tif_tagmethods.printdir = sp->printdir; 751 tif->tif_setupdecode = sp->setupdecode; 752 tif->tif_setupencode = sp->setupencode; 753 754 return 1; 755 } 756 757 /* vim: set ts=8 sts=8 sw=8 noet: */ 758 /* 759 * Local Variables: 760 * mode: c 761 * c-basic-offset: 8 762 * fill-column: 78 763 * End: 764 */ 765