| OLD | NEW |
| (Empty) |
| 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 s
upported 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 /* | |
| 246 * compare v4.0.3 with v3.9.5, | |
| 247 * we find that horAcc8 uses while loop in the v4.0.3 and uses do while
loop in the v3.9.5. | |
| 248 * times of do while loop are less than while loop, so we use v3.9.5 ins
tead of v4.0.3. | |
| 249 */ | |
| 250 #if 0 | |
| 251 tmsize_t stride = PredictorState(tif)->stride; | |
| 252 | |
| 253 char* cp = (char*) cp0; | |
| 254 assert((cc%stride)==0); | |
| 255 if (cc > stride) { | |
| 256 /* | |
| 257 * Pipeline the most common cases. | |
| 258 */ | |
| 259 if (stride == 3) { | |
| 260 unsigned int cr = cp[0]; | |
| 261 unsigned int cg = cp[1]; | |
| 262 unsigned int cb = cp[2]; | |
| 263 cc -= 3; | |
| 264 cp += 3; | |
| 265 while (cc>0) { | |
| 266 cp[0] = (char) (cr += cp[0]); | |
| 267 cp[1] = (char) (cg += cp[1]); | |
| 268 cp[2] = (char) (cb += cp[2]); | |
| 269 cc -= 3; | |
| 270 cp += 3; | |
| 271 } | |
| 272 } else if (stride == 4) { | |
| 273 unsigned int cr = cp[0]; | |
| 274 unsigned int cg = cp[1]; | |
| 275 unsigned int cb = cp[2]; | |
| 276 unsigned int ca = cp[3]; | |
| 277 cc -= 4; | |
| 278 cp += 4; | |
| 279 while (cc>0) { | |
| 280 cp[0] = (char) (cr += cp[0]); | |
| 281 cp[1] = (char) (cg += cp[1]); | |
| 282 cp[2] = (char) (cb += cp[2]); | |
| 283 cp[3] = (char) (ca += cp[3]); | |
| 284 cc -= 4; | |
| 285 cp += 4; | |
| 286 } | |
| 287 } else { | |
| 288 cc -= stride; | |
| 289 do { | |
| 290 REPEAT4(stride, cp[stride] = | |
| 291 (char) (cp[stride] + *cp); cp++) | |
| 292 cc -= stride; | |
| 293 } while (cc>0); | |
| 294 } | |
| 295 } | |
| 296 #else | |
| 297 tsize_t stride = PredictorState(tif)->stride; | |
| 298 | |
| 299 char* cp = (char*) cp0; | |
| 300 if (cc > stride) { | |
| 301 cc -= stride; | |
| 302 /* | |
| 303 * Pipeline the most common cases. | |
| 304 */ | |
| 305 if (stride == 3) { | |
| 306 unsigned int cr = cp[0]; | |
| 307 unsigned int cg = cp[1]; | |
| 308 unsigned int cb = cp[2]; | |
| 309 do { | |
| 310 cc -= 3, cp += 3; | |
| 311 cp[0] = (char) (cr += cp[0]); | |
| 312 cp[1] = (char) (cg += cp[1]); | |
| 313 cp[2] = (char) (cb += cp[2]); | |
| 314 } while ((int32) cc > 0); | |
| 315 } else if (stride == 4) { | |
| 316 unsigned int cr = cp[0]; | |
| 317 unsigned int cg = cp[1]; | |
| 318 unsigned int cb = cp[2]; | |
| 319 unsigned int ca = cp[3]; | |
| 320 do { | |
| 321 cc -= 4, cp += 4; | |
| 322 cp[0] = (char) (cr += cp[0]); | |
| 323 cp[1] = (char) (cg += cp[1]); | |
| 324 cp[2] = (char) (cb += cp[2]); | |
| 325 cp[3] = (char) (ca += cp[3]); | |
| 326 } while ((int32) cc > 0); | |
| 327 } else { | |
| 328 do { | |
| 329 REPEAT4(stride, cp[stride] = | |
| 330 (char) (cp[stride] + *cp); cp++) | |
| 331 cc -= stride; | |
| 332 } while ((int32) cc > 0); | |
| 333 } | |
| 334 } | |
| 335 #endif | |
| 336 } | |
| 337 | |
| 338 static void | |
| 339 swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) | |
| 340 { | |
| 341 tmsize_t stride = PredictorState(tif)->stride; | |
| 342 uint16* wp = (uint16*) cp0; | |
| 343 tmsize_t wc = cc / 2; | |
| 344 | |
| 345 assert((cc%(2*stride))==0); | |
| 346 | |
| 347 if (wc > stride) { | |
| 348 TIFFSwabArrayOfShort(wp, wc); | |
| 349 wc -= stride; | |
| 350 do { | |
| 351 REPEAT4(stride, wp[stride] += wp[0]; wp++) | |
| 352 wc -= stride; | |
| 353 } while (wc > 0); | |
| 354 } | |
| 355 } | |
| 356 | |
| 357 static void | |
| 358 horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) | |
| 359 { | |
| 360 tmsize_t stride = PredictorState(tif)->stride; | |
| 361 uint16* wp = (uint16*) cp0; | |
| 362 tmsize_t wc = cc / 2; | |
| 363 | |
| 364 assert((cc%(2*stride))==0); | |
| 365 | |
| 366 if (wc > stride) { | |
| 367 wc -= stride; | |
| 368 do { | |
| 369 REPEAT4(stride, wp[stride] += wp[0]; wp++) | |
| 370 wc -= stride; | |
| 371 } while (wc > 0); | |
| 372 } | |
| 373 } | |
| 374 | |
| 375 static void | |
| 376 swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) | |
| 377 { | |
| 378 tmsize_t stride = PredictorState(tif)->stride; | |
| 379 uint32* wp = (uint32*) cp0; | |
| 380 tmsize_t wc = cc / 4; | |
| 381 | |
| 382 assert((cc%(4*stride))==0); | |
| 383 | |
| 384 if (wc > stride) { | |
| 385 TIFFSwabArrayOfLong(wp, wc); | |
| 386 wc -= stride; | |
| 387 do { | |
| 388 REPEAT4(stride, wp[stride] += wp[0]; wp++) | |
| 389 wc -= stride; | |
| 390 } while (wc > 0); | |
| 391 } | |
| 392 } | |
| 393 | |
| 394 static void | |
| 395 horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) | |
| 396 { | |
| 397 tmsize_t stride = PredictorState(tif)->stride; | |
| 398 uint32* wp = (uint32*) cp0; | |
| 399 tmsize_t wc = cc / 4; | |
| 400 | |
| 401 assert((cc%(4*stride))==0); | |
| 402 | |
| 403 if (wc > stride) { | |
| 404 wc -= stride; | |
| 405 do { | |
| 406 REPEAT4(stride, wp[stride] += wp[0]; wp++) | |
| 407 wc -= stride; | |
| 408 } while (wc > 0); | |
| 409 } | |
| 410 } | |
| 411 | |
| 412 /* | |
| 413 * Floating point predictor accumulation routine. | |
| 414 */ | |
| 415 static void | |
| 416 fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc) | |
| 417 { | |
| 418 tmsize_t stride = PredictorState(tif)->stride; | |
| 419 uint32 bps = tif->tif_dir.td_bitspersample / 8; | |
| 420 tmsize_t wc = cc / bps; | |
| 421 tmsize_t count = cc; | |
| 422 uint8 *cp = (uint8 *) cp0; | |
| 423 uint8 *tmp = (uint8 *)_TIFFmalloc(cc); | |
| 424 | |
| 425 assert((cc%(bps*stride))==0); | |
| 426 | |
| 427 if (!tmp) | |
| 428 return; | |
| 429 | |
| 430 while (count > stride) { | |
| 431 REPEAT4(stride, cp[stride] += cp[0]; 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 } | |
| 450 | |
| 451 /* | |
| 452 * Decode a scanline and apply the predictor routine. | |
| 453 */ | |
| 454 static int | |
| 455 PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) | |
| 456 { | |
| 457 TIFFPredictorState *sp = PredictorState(tif); | |
| 458 | |
| 459 assert(sp != NULL); | |
| 460 assert(sp->decoderow != NULL); | |
| 461 assert(sp->decodepfunc != NULL); | |
| 462 | |
| 463 if ((*sp->decoderow)(tif, op0, occ0, s)) { | |
| 464 (*sp->decodepfunc)(tif, op0, occ0); | |
| 465 return 1; | |
| 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 */ | |
| 477 static int | |
| 478 PredictorDecodeTile(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 assert((occ0%rowsize)==0); | |
| 489 assert(sp->decodepfunc != NULL); | |
| 490 while (occ0 > 0) { | |
| 491 (*sp->decodepfunc)(tif, op0, rowsize); | |
| 492 occ0 -= rowsize; | |
| 493 op0 += rowsize; | |
| 494 } | |
| 495 return 1; | |
| 496 } else | |
| 497 return 0; | |
| 498 } | |
| 499 | |
| 500 static void | |
| 501 horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc) | |
| 502 { | |
| 503 TIFFPredictorState* sp = PredictorState(tif); | |
| 504 tmsize_t stride = sp->stride; | |
| 505 char* cp = (char*) cp0; | |
| 506 | |
| 507 assert((cc%stride)==0); | |
| 508 | |
| 509 if (cc > stride) { | |
| 510 cc -= stride; | |
| 511 /* | |
| 512 * Pipeline the most common cases. | |
| 513 */ | |
| 514 if (stride == 3) { | |
| 515 int r1, g1, b1; | |
| 516 int r2 = cp[0]; | |
| 517 int g2 = cp[1]; | |
| 518 int b2 = cp[2]; | |
| 519 do { | |
| 520 r1 = cp[3]; cp[3] = r1-r2; r2 = r1; | |
| 521 g1 = cp[4]; cp[4] = g1-g2; g2 = g1; | |
| 522 b1 = cp[5]; cp[5] = b1-b2; b2 = b1; | |
| 523 cp += 3; | |
| 524 } while ((cc -= 3) > 0); | |
| 525 } else if (stride == 4) { | |
| 526 int r1, g1, b1, a1; | |
| 527 int r2 = cp[0]; | |
| 528 int g2 = cp[1]; | |
| 529 int b2 = cp[2]; | |
| 530 int a2 = cp[3]; | |
| 531 do { | |
| 532 r1 = cp[4]; cp[4] = r1-r2; r2 = r1; | |
| 533 g1 = cp[5]; cp[5] = g1-g2; g2 = g1; | |
| 534 b1 = cp[6]; cp[6] = b1-b2; b2 = b1; | |
| 535 a1 = cp[7]; cp[7] = a1-a2; a2 = a1; | |
| 536 cp += 4; | |
| 537 } while ((cc -= 4) > 0); | |
| 538 } else { | |
| 539 cp += cc - 1; | |
| 540 do { | |
| 541 REPEAT4(stride, cp[stride] -= cp[0]; cp--) | |
| 542 } while ((cc -= stride) > 0); | |
| 543 } | |
| 544 } | |
| 545 } | |
| 546 | |
| 547 static void | |
| 548 horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc) | |
| 549 { | |
| 550 TIFFPredictorState* sp = PredictorState(tif); | |
| 551 tmsize_t stride = sp->stride; | |
| 552 int16 *wp = (int16*) cp0; | |
| 553 tmsize_t wc = cc/2; | |
| 554 | |
| 555 assert((cc%(2*stride))==0); | |
| 556 | |
| 557 if (wc > stride) { | |
| 558 wc -= stride; | |
| 559 wp += wc - 1; | |
| 560 do { | |
| 561 REPEAT4(stride, wp[stride] -= wp[0]; wp--) | |
| 562 wc -= stride; | |
| 563 } while (wc > 0); | |
| 564 } | |
| 565 } | |
| 566 | |
| 567 static void | |
| 568 horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc) | |
| 569 { | |
| 570 TIFFPredictorState* sp = PredictorState(tif); | |
| 571 tmsize_t stride = sp->stride; | |
| 572 int32 *wp = (int32*) cp0; | |
| 573 tmsize_t wc = cc/4; | |
| 574 | |
| 575 assert((cc%(4*stride))==0); | |
| 576 | |
| 577 if (wc > stride) { | |
| 578 wc -= stride; | |
| 579 wp += wc - 1; | |
| 580 do { | |
| 581 REPEAT4(stride, wp[stride] -= wp[0]; wp--) | |
| 582 wc -= stride; | |
| 583 } while (wc > 0); | |
| 584 } | |
| 585 } | |
| 586 | |
| 587 /* | |
| 588 * Floating point predictor differencing routine. | |
| 589 */ | |
| 590 static void | |
| 591 fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc) | |
| 592 { | |
| 593 tmsize_t stride = PredictorState(tif)->stride; | |
| 594 uint32 bps = tif->tif_dir.td_bitspersample / 8; | |
| 595 tmsize_t wc = cc / bps; | |
| 596 tmsize_t count; | |
| 597 uint8 *cp = (uint8 *) cp0; | |
| 598 uint8 *tmp = (uint8 *)_TIFFmalloc(cc); | |
| 599 | |
| 600 assert((cc%(bps*stride))==0); | |
| 601 | |
| 602 if (!tmp) | |
| 603 return; | |
| 604 | |
| 605 _TIFFmemcpy(tmp, cp0, cc); | |
| 606 for (count = 0; count < wc; count++) { | |
| 607 uint32 byte; | |
| 608 for (byte = 0; byte < bps; byte++) { | |
| 609 #if WORDS_BIGENDIAN | |
| 610 cp[byte * wc + count] = tmp[bps * count + byte]; | |
| 611 #else | |
| 612 cp[(bps - byte - 1) * wc + count] = | |
| 613 tmp[bps * count + byte]; | |
| 614 #endif | |
| 615 } | |
| 616 } | |
| 617 _TIFFfree(tmp); | |
| 618 | |
| 619 cp = (uint8 *) cp0; | |
| 620 cp += cc - stride - 1; | |
| 621 for (count = cc; count > stride; count -= stride) | |
| 622 REPEAT4(stride, cp[stride] -= cp[0]; cp--) | |
| 623 } | |
| 624 | |
| 625 static int | |
| 626 PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) | |
| 627 { | |
| 628 TIFFPredictorState *sp = PredictorState(tif); | |
| 629 | |
| 630 assert(sp != NULL); | |
| 631 assert(sp->encodepfunc != NULL); | |
| 632 assert(sp->encoderow != NULL); | |
| 633 | |
| 634 /* XXX horizontal differencing alters user's data XXX */ | |
| 635 (*sp->encodepfunc)(tif, bp, cc); | |
| 636 return (*sp->encoderow)(tif, bp, cc, s); | |
| 637 } | |
| 638 | |
| 639 static int | |
| 640 PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s) | |
| 641 { | |
| 642 static const char module[] = "PredictorEncodeTile"; | |
| 643 TIFFPredictorState *sp = PredictorState(tif); | |
| 644 uint8 *working_copy; | |
| 645 tmsize_t cc = cc0, rowsize; | |
| 646 unsigned char* bp; | |
| 647 int result_code; | |
| 648 | |
| 649 assert(sp != NULL); | |
| 650 assert(sp->encodepfunc != NULL); | |
| 651 assert(sp->encodetile != NULL); | |
| 652 | |
| 653 /* | |
| 654 * Do predictor manipulation in a working buffer to avoid altering | |
| 655 * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965 | |
| 656 */ | |
| 657 working_copy = (uint8*) _TIFFmalloc(cc0); | |
| 658 if( working_copy == NULL ) | |
| 659 { | |
| 660 TIFFErrorExt(tif->tif_clientdata, module, | |
| 661 "Out of memory allocating " TIFF_SSIZE_FORMAT " byte te
mp buffer.", | |
| 662 cc0 ); | |
| 663 return 0; | |
| 664 } | |
| 665 memcpy( working_copy, bp0, cc0 ); | |
| 666 bp = working_copy; | |
| 667 | |
| 668 rowsize = sp->rowsize; | |
| 669 assert(rowsize > 0); | |
| 670 assert((cc0%rowsize)==0); | |
| 671 while (cc > 0) { | |
| 672 (*sp->encodepfunc)(tif, bp, rowsize); | |
| 673 cc -= rowsize; | |
| 674 bp += rowsize; | |
| 675 } | |
| 676 result_code = (*sp->encodetile)(tif, working_copy, cc0, s); | |
| 677 | |
| 678 _TIFFfree( working_copy ); | |
| 679 | |
| 680 return result_code; | |
| 681 } | |
| 682 | |
| 683 #define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */ | |
| 684 | |
| 685 static const TIFFField predictFields[] = { | |
| 686 { TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UI
NT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL }, | |
| 687 }; | |
| 688 | |
| 689 static int | |
| 690 PredictorVSetField(TIFF* tif, uint32 tag, va_list ap) | |
| 691 { | |
| 692 TIFFPredictorState *sp = PredictorState(tif); | |
| 693 | |
| 694 assert(sp != NULL); | |
| 695 assert(sp->vsetparent != NULL); | |
| 696 | |
| 697 switch (tag) { | |
| 698 case TIFFTAG_PREDICTOR: | |
| 699 sp->predictor = (uint16) va_arg(ap, uint16_vap); | |
| 700 TIFFSetFieldBit(tif, FIELD_PREDICTOR); | |
| 701 break; | |
| 702 default: | |
| 703 return (*sp->vsetparent)(tif, tag, ap); | |
| 704 } | |
| 705 tif->tif_flags |= TIFF_DIRTYDIRECT; | |
| 706 return 1; | |
| 707 } | |
| 708 | |
| 709 static int | |
| 710 PredictorVGetField(TIFF* tif, uint32 tag, va_list ap) | |
| 711 { | |
| 712 TIFFPredictorState *sp = PredictorState(tif); | |
| 713 | |
| 714 assert(sp != NULL); | |
| 715 assert(sp->vgetparent != NULL); | |
| 716 | |
| 717 switch (tag) { | |
| 718 case TIFFTAG_PREDICTOR: | |
| 719 *va_arg(ap, uint16*) = sp->predictor; | |
| 720 break; | |
| 721 default: | |
| 722 return (*sp->vgetparent)(tif, tag, ap); | |
| 723 } | |
| 724 return 1; | |
| 725 } | |
| 726 | |
| 727 static void | |
| 728 PredictorPrintDir(TIFF* tif, FILE* fd, long flags) | |
| 729 { | |
| 730 TIFFPredictorState* sp = PredictorState(tif); | |
| 731 | |
| 732 (void) flags; | |
| 733 if (TIFFFieldSet(tif,FIELD_PREDICTOR)) { | |
| 734 fprintf(fd, " Predictor: "); | |
| 735 switch (sp->predictor) { | |
| 736 case 1: fprintf(fd, "none "); break; | |
| 737 case 2: fprintf(fd, "horizontal differencing "); break; | |
| 738 case 3: fprintf(fd, "floating point predictor "); break; | |
| 739 } | |
| 740 fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor); | |
| 741 } | |
| 742 if (sp->printdir) | |
| 743 (*sp->printdir)(tif, fd, flags); | |
| 744 } | |
| 745 | |
| 746 int | |
| 747 TIFFPredictorInit(TIFF* tif) | |
| 748 { | |
| 749 TIFFPredictorState* sp = PredictorState(tif); | |
| 750 | |
| 751 assert(sp != 0); | |
| 752 | |
| 753 /* | |
| 754 * Merge codec-specific tag information. | |
| 755 */ | |
| 756 if (!_TIFFMergeFields(tif, predictFields, | |
| 757 TIFFArrayCount(predictFields))) { | |
| 758 TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit", | |
| 759 "Merging Predictor codec-specific tags failed"); | |
| 760 return 0; | |
| 761 } | |
| 762 | |
| 763 /* | |
| 764 * Override parent get/set field methods. | |
| 765 */ | |
| 766 sp->vgetparent = tif->tif_tagmethods.vgetfield; | |
| 767 tif->tif_tagmethods.vgetfield = | |
| 768 PredictorVGetField;/* hook for predictor tag */ | |
| 769 sp->vsetparent = tif->tif_tagmethods.vsetfield; | |
| 770 tif->tif_tagmethods.vsetfield = | |
| 771 PredictorVSetField;/* hook for predictor tag */ | |
| 772 sp->printdir = tif->tif_tagmethods.printdir; | |
| 773 tif->tif_tagmethods.printdir = | |
| 774 PredictorPrintDir; /* hook for predictor tag */ | |
| 775 | |
| 776 sp->setupdecode = tif->tif_setupdecode; | |
| 777 tif->tif_setupdecode = PredictorSetupDecode; | |
| 778 sp->setupencode = tif->tif_setupencode; | |
| 779 tif->tif_setupencode = PredictorSetupEncode; | |
| 780 | |
| 781 sp->predictor = 1; /* default value */ | |
| 782 sp->encodepfunc = NULL; /* no predictor routine */ | |
| 783 sp->decodepfunc = NULL; /* no predictor routine */ | |
| 784 return 1; | |
| 785 } | |
| 786 | |
| 787 int | |
| 788 TIFFPredictorCleanup(TIFF* tif) | |
| 789 { | |
| 790 TIFFPredictorState* sp = PredictorState(tif); | |
| 791 | |
| 792 assert(sp != 0); | |
| 793 | |
| 794 tif->tif_tagmethods.vgetfield = sp->vgetparent; | |
| 795 tif->tif_tagmethods.vsetfield = sp->vsetparent; | |
| 796 tif->tif_tagmethods.printdir = sp->printdir; | |
| 797 tif->tif_setupdecode = sp->setupdecode; | |
| 798 tif->tif_setupencode = sp->setupencode; | |
| 799 | |
| 800 return 1; | |
| 801 } | |
| 802 | |
| 803 /* vim: set ts=8 sts=8 sw=8 noet: */ | |
| 804 /* | |
| 805 * Local Variables: | |
| 806 * mode: c | |
| 807 * c-basic-offset: 8 | |
| 808 * fill-column: 78 | |
| 809 * End: | |
| 810 */ | |
| 811 | |
| OLD | NEW |