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