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