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