1 /* 2 * Copyright (c) 1996-1997 Sam Leffler 3 * Copyright (c) 1996 Pixar 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and 6 * its documentation for any purpose is hereby granted without fee, provided 7 * that (i) the above copyright notices and this permission notice appear in 8 * all copies of the software and related documentation, and (ii) the names of 9 * Pixar, Sam Leffler and Silicon Graphics may not be used in any advertising or 10 * publicity relating to the software without the specific, prior written 11 * permission of Pixar, Sam Leffler and Silicon Graphics. 12 * 13 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 14 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 15 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 16 * 17 * IN NO EVENT SHALL PIXAR, SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 18 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 19 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 20 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 21 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 22 * OF THIS SOFTWARE. 23 */ 24 25 #include <precomp.h> 26 #ifdef PIXARLOG_SUPPORT 27 28 /* 29 * TIFF Library. 30 * PixarLog Compression Support 31 * 32 * Contributed by Dan McCoy. 33 * 34 * PixarLog film support uses the TIFF library to store companded 35 * 11 bit values into a tiff file, which are compressed using the 36 * zip compressor. 37 * 38 * The codec can take as input and produce as output 32-bit IEEE float values 39 * as well as 16-bit or 8-bit unsigned integer values. 40 * 41 * On writing any of the above are converted into the internal 42 * 11-bit log format. In the case of 8 and 16 bit values, the 43 * input is assumed to be unsigned linear color values that represent 44 * the range 0-1. In the case of IEEE values, the 0-1 range is assumed to 45 * be the normal linear color range, in addition over 1 values are 46 * accepted up to a value of about 25.0 to encode "hot" highlights and such. 47 * The encoding is lossless for 8-bit values, slightly lossy for the 48 * other bit depths. The actual color precision should be better 49 * than the human eye can perceive with extra room to allow for 50 * error introduced by further image computation. As with any quantized 51 * color format, it is possible to perform image calculations which 52 * expose the quantization error. This format should certainly be less 53 * susceptible to such errors than standard 8-bit encodings, but more 54 * susceptible than straight 16-bit or 32-bit encodings. 55 * 56 * On reading the internal format is converted to the desired output format. 57 * The program can request which format it desires by setting the internal 58 * pseudo tag TIFFTAG_PIXARLOGDATAFMT to one of these possible values: 59 * PIXARLOGDATAFMT_FLOAT = provide IEEE float values. 60 * PIXARLOGDATAFMT_16BIT = provide unsigned 16-bit integer values 61 * PIXARLOGDATAFMT_8BIT = provide unsigned 8-bit integer values 62 * 63 * alternately PIXARLOGDATAFMT_8BITABGR provides unsigned 8-bit integer 64 * values with the difference that if there are exactly three or four channels 65 * (rgb or rgba) it swaps the channel order (bgr or abgr). 66 * 67 * PIXARLOGDATAFMT_11BITLOG provides the internal encoding directly 68 * packed in 16-bit values. However no tools are supplied for interpreting 69 * these values. 70 * 71 * "hot" (over 1.0) areas written in floating point get clamped to 72 * 1.0 in the integer data types. 73 * 74 * When the file is closed after writing, the bit depth and sample format 75 * are set always to appear as if 8-bit data has been written into it. 76 * That way a naive program unaware of the particulars of the encoding 77 * gets the format it is most likely able to handle. 78 * 79 * The codec does it's own horizontal differencing step on the coded 80 * values so the libraries predictor stuff should be turned off. 81 * The codec also handle byte swapping the encoded values as necessary 82 * since the library does not have the information necessary 83 * to know the bit depth of the raw unencoded buffer. 84 * 85 * NOTE: This decoder does not appear to update tif_rawcp, and tif_rawcc. 86 * This can cause problems with the implementation of CHUNKY_STRIP_READ_SUPPORT 87 * as noted in http://trac.osgeo.org/gdal/ticket/3894. FrankW - Jan'11 88 */ 89 90 #include "tif_predict.h" 91 #include "zlib.h" 92 93 #include <stdio.h> 94 #include <stdlib.h> 95 #include <math.h> 96 97 /* Tables for converting to/from 11 bit coded values */ 98 99 #define TSIZE 2048 /* decode table size (11-bit tokens) */ 100 #define TSIZEP1 2049 /* Plus one for slop */ 101 #define ONE 1250 /* token value of 1.0 exactly */ 102 #define RATIO 1.004 /* nominal ratio for log part */ 103 104 #define CODE_MASK 0x7ff /* 11 bits. */ 105 106 static float Fltsize; 107 static float LogK1, LogK2; 108 109 #define REPEAT(n, op) { int i; i=n; do { i--; op; } while (i>0); } 110 111 static void 112 horizontalAccumulateF(uint16 *wp, int n, int stride, float *op, 113 float *ToLinearF) 114 { 115 register unsigned int cr, cg, cb, ca, mask; 116 register float t0, t1, t2, t3; 117 118 if (n >= stride) { 119 mask = CODE_MASK; 120 if (stride == 3) { 121 t0 = ToLinearF[cr = (wp[0] & mask)]; 122 t1 = ToLinearF[cg = (wp[1] & mask)]; 123 t2 = ToLinearF[cb = (wp[2] & mask)]; 124 op[0] = t0; 125 op[1] = t1; 126 op[2] = t2; 127 n -= 3; 128 while (n > 0) { 129 wp += 3; 130 op += 3; 131 n -= 3; 132 t0 = ToLinearF[(cr += wp[0]) & mask]; 133 t1 = ToLinearF[(cg += wp[1]) & mask]; 134 t2 = ToLinearF[(cb += wp[2]) & mask]; 135 op[0] = t0; 136 op[1] = t1; 137 op[2] = t2; 138 } 139 } else if (stride == 4) { 140 t0 = ToLinearF[cr = (wp[0] & mask)]; 141 t1 = ToLinearF[cg = (wp[1] & mask)]; 142 t2 = ToLinearF[cb = (wp[2] & mask)]; 143 t3 = ToLinearF[ca = (wp[3] & mask)]; 144 op[0] = t0; 145 op[1] = t1; 146 op[2] = t2; 147 op[3] = t3; 148 n -= 4; 149 while (n > 0) { 150 wp += 4; 151 op += 4; 152 n -= 4; 153 t0 = ToLinearF[(cr += wp[0]) & mask]; 154 t1 = ToLinearF[(cg += wp[1]) & mask]; 155 t2 = ToLinearF[(cb += wp[2]) & mask]; 156 t3 = ToLinearF[(ca += wp[3]) & mask]; 157 op[0] = t0; 158 op[1] = t1; 159 op[2] = t2; 160 op[3] = t3; 161 } 162 } else { 163 REPEAT(stride, *op = ToLinearF[*wp&mask]; wp++; op++) 164 n -= stride; 165 while (n > 0) { 166 REPEAT(stride, 167 wp[stride] += *wp; *op = ToLinearF[*wp&mask]; wp++; op++) 168 n -= stride; 169 } 170 } 171 } 172 } 173 174 static void 175 horizontalAccumulate12(uint16 *wp, int n, int stride, int16 *op, 176 float *ToLinearF) 177 { 178 register unsigned int cr, cg, cb, ca, mask; 179 register float t0, t1, t2, t3; 180 181 #define SCALE12 2048.0F 182 #define CLAMP12(t) (((t) < 3071) ? (uint16) (t) : 3071) 183 184 if (n >= stride) { 185 mask = CODE_MASK; 186 if (stride == 3) { 187 t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; 188 t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; 189 t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; 190 op[0] = CLAMP12(t0); 191 op[1] = CLAMP12(t1); 192 op[2] = CLAMP12(t2); 193 n -= 3; 194 while (n > 0) { 195 wp += 3; 196 op += 3; 197 n -= 3; 198 t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12; 199 t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12; 200 t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12; 201 op[0] = CLAMP12(t0); 202 op[1] = CLAMP12(t1); 203 op[2] = CLAMP12(t2); 204 } 205 } else if (stride == 4) { 206 t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; 207 t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; 208 t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; 209 t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12; 210 op[0] = CLAMP12(t0); 211 op[1] = CLAMP12(t1); 212 op[2] = CLAMP12(t2); 213 op[3] = CLAMP12(t3); 214 n -= 4; 215 while (n > 0) { 216 wp += 4; 217 op += 4; 218 n -= 4; 219 t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12; 220 t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12; 221 t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12; 222 t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12; 223 op[0] = CLAMP12(t0); 224 op[1] = CLAMP12(t1); 225 op[2] = CLAMP12(t2); 226 op[3] = CLAMP12(t3); 227 } 228 } else { 229 REPEAT(stride, t0 = ToLinearF[*wp&mask] * SCALE12; 230 *op = CLAMP12(t0); wp++; op++) 231 n -= stride; 232 while (n > 0) { 233 REPEAT(stride, 234 wp[stride] += *wp; t0 = ToLinearF[wp[stride]&mask]*SCALE12; 235 *op = CLAMP12(t0); wp++; op++) 236 n -= stride; 237 } 238 } 239 } 240 } 241 242 static void 243 horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op, 244 uint16 *ToLinear16) 245 { 246 register unsigned int cr, cg, cb, ca, mask; 247 248 if (n >= stride) { 249 mask = CODE_MASK; 250 if (stride == 3) { 251 op[0] = ToLinear16[cr = (wp[0] & mask)]; 252 op[1] = ToLinear16[cg = (wp[1] & mask)]; 253 op[2] = ToLinear16[cb = (wp[2] & mask)]; 254 n -= 3; 255 while (n > 0) { 256 wp += 3; 257 op += 3; 258 n -= 3; 259 op[0] = ToLinear16[(cr += wp[0]) & mask]; 260 op[1] = ToLinear16[(cg += wp[1]) & mask]; 261 op[2] = ToLinear16[(cb += wp[2]) & mask]; 262 } 263 } else if (stride == 4) { 264 op[0] = ToLinear16[cr = (wp[0] & mask)]; 265 op[1] = ToLinear16[cg = (wp[1] & mask)]; 266 op[2] = ToLinear16[cb = (wp[2] & mask)]; 267 op[3] = ToLinear16[ca = (wp[3] & mask)]; 268 n -= 4; 269 while (n > 0) { 270 wp += 4; 271 op += 4; 272 n -= 4; 273 op[0] = ToLinear16[(cr += wp[0]) & mask]; 274 op[1] = ToLinear16[(cg += wp[1]) & mask]; 275 op[2] = ToLinear16[(cb += wp[2]) & mask]; 276 op[3] = ToLinear16[(ca += wp[3]) & mask]; 277 } 278 } else { 279 REPEAT(stride, *op = ToLinear16[*wp&mask]; wp++; op++) 280 n -= stride; 281 while (n > 0) { 282 REPEAT(stride, 283 wp[stride] += *wp; *op = ToLinear16[*wp&mask]; wp++; op++) 284 n -= stride; 285 } 286 } 287 } 288 } 289 290 /* 291 * Returns the log encoded 11-bit values with the horizontal 292 * differencing undone. 293 */ 294 static void 295 horizontalAccumulate11(uint16 *wp, int n, int stride, uint16 *op) 296 { 297 register unsigned int cr, cg, cb, ca, mask; 298 299 if (n >= stride) { 300 mask = CODE_MASK; 301 if (stride == 3) { 302 op[0] = wp[0]; op[1] = wp[1]; op[2] = wp[2]; 303 cr = wp[0]; cg = wp[1]; cb = wp[2]; 304 n -= 3; 305 while (n > 0) { 306 wp += 3; 307 op += 3; 308 n -= 3; 309 op[0] = (uint16)((cr += wp[0]) & mask); 310 op[1] = (uint16)((cg += wp[1]) & mask); 311 op[2] = (uint16)((cb += wp[2]) & mask); 312 } 313 } else if (stride == 4) { 314 op[0] = wp[0]; op[1] = wp[1]; 315 op[2] = wp[2]; op[3] = wp[3]; 316 cr = wp[0]; cg = wp[1]; cb = wp[2]; ca = wp[3]; 317 n -= 4; 318 while (n > 0) { 319 wp += 4; 320 op += 4; 321 n -= 4; 322 op[0] = (uint16)((cr += wp[0]) & mask); 323 op[1] = (uint16)((cg += wp[1]) & mask); 324 op[2] = (uint16)((cb += wp[2]) & mask); 325 op[3] = (uint16)((ca += wp[3]) & mask); 326 } 327 } else { 328 REPEAT(stride, *op = *wp&mask; wp++; op++) 329 n -= stride; 330 while (n > 0) { 331 REPEAT(stride, 332 wp[stride] += *wp; *op = *wp&mask; wp++; op++) 333 n -= stride; 334 } 335 } 336 } 337 } 338 339 static void 340 horizontalAccumulate8(uint16 *wp, int n, int stride, unsigned char *op, 341 unsigned char *ToLinear8) 342 { 343 register unsigned int cr, cg, cb, ca, mask; 344 345 if (n >= stride) { 346 mask = CODE_MASK; 347 if (stride == 3) { 348 op[0] = ToLinear8[cr = (wp[0] & mask)]; 349 op[1] = ToLinear8[cg = (wp[1] & mask)]; 350 op[2] = ToLinear8[cb = (wp[2] & mask)]; 351 n -= 3; 352 while (n > 0) { 353 n -= 3; 354 wp += 3; 355 op += 3; 356 op[0] = ToLinear8[(cr += wp[0]) & mask]; 357 op[1] = ToLinear8[(cg += wp[1]) & mask]; 358 op[2] = ToLinear8[(cb += wp[2]) & mask]; 359 } 360 } else if (stride == 4) { 361 op[0] = ToLinear8[cr = (wp[0] & mask)]; 362 op[1] = ToLinear8[cg = (wp[1] & mask)]; 363 op[2] = ToLinear8[cb = (wp[2] & mask)]; 364 op[3] = ToLinear8[ca = (wp[3] & mask)]; 365 n -= 4; 366 while (n > 0) { 367 n -= 4; 368 wp += 4; 369 op += 4; 370 op[0] = ToLinear8[(cr += wp[0]) & mask]; 371 op[1] = ToLinear8[(cg += wp[1]) & mask]; 372 op[2] = ToLinear8[(cb += wp[2]) & mask]; 373 op[3] = ToLinear8[(ca += wp[3]) & mask]; 374 } 375 } else { 376 REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++) 377 n -= stride; 378 while (n > 0) { 379 REPEAT(stride, 380 wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++) 381 n -= stride; 382 } 383 } 384 } 385 } 386 387 388 static void 389 horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op, 390 unsigned char *ToLinear8) 391 { 392 register unsigned int cr, cg, cb, ca, mask; 393 register unsigned char t0, t1, t2, t3; 394 395 if (n >= stride) { 396 mask = CODE_MASK; 397 if (stride == 3) { 398 op[0] = 0; 399 t1 = ToLinear8[cb = (wp[2] & mask)]; 400 t2 = ToLinear8[cg = (wp[1] & mask)]; 401 t3 = ToLinear8[cr = (wp[0] & mask)]; 402 op[1] = t1; 403 op[2] = t2; 404 op[3] = t3; 405 n -= 3; 406 while (n > 0) { 407 n -= 3; 408 wp += 3; 409 op += 4; 410 op[0] = 0; 411 t1 = ToLinear8[(cb += wp[2]) & mask]; 412 t2 = ToLinear8[(cg += wp[1]) & mask]; 413 t3 = ToLinear8[(cr += wp[0]) & mask]; 414 op[1] = t1; 415 op[2] = t2; 416 op[3] = t3; 417 } 418 } else if (stride == 4) { 419 t0 = ToLinear8[ca = (wp[3] & mask)]; 420 t1 = ToLinear8[cb = (wp[2] & mask)]; 421 t2 = ToLinear8[cg = (wp[1] & mask)]; 422 t3 = ToLinear8[cr = (wp[0] & mask)]; 423 op[0] = t0; 424 op[1] = t1; 425 op[2] = t2; 426 op[3] = t3; 427 n -= 4; 428 while (n > 0) { 429 n -= 4; 430 wp += 4; 431 op += 4; 432 t0 = ToLinear8[(ca += wp[3]) & mask]; 433 t1 = ToLinear8[(cb += wp[2]) & mask]; 434 t2 = ToLinear8[(cg += wp[1]) & mask]; 435 t3 = ToLinear8[(cr += wp[0]) & mask]; 436 op[0] = t0; 437 op[1] = t1; 438 op[2] = t2; 439 op[3] = t3; 440 } 441 } else { 442 REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++) 443 n -= stride; 444 while (n > 0) { 445 REPEAT(stride, 446 wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++) 447 n -= stride; 448 } 449 } 450 } 451 } 452 453 /* 454 * State block for each open TIFF 455 * file using PixarLog compression/decompression. 456 */ 457 typedef struct { 458 TIFFPredictorState predict; 459 z_stream stream; 460 tmsize_t tbuf_size; /* only set/used on reading for now */ 461 uint16 *tbuf; 462 uint16 stride; 463 int state; 464 int user_datafmt; 465 int quality; 466 #define PLSTATE_INIT 1 467 468 TIFFVSetMethod vgetparent; /* super-class method */ 469 TIFFVSetMethod vsetparent; /* super-class method */ 470 471 float *ToLinearF; 472 uint16 *ToLinear16; 473 unsigned char *ToLinear8; 474 uint16 *FromLT2; 475 uint16 *From14; /* Really for 16-bit data, but we shift down 2 */ 476 uint16 *From8; 477 478 } PixarLogState; 479 480 static int 481 PixarLogMakeTables(PixarLogState *sp) 482 { 483 484 /* 485 * We make several tables here to convert between various external 486 * representations (float, 16-bit, and 8-bit) and the internal 487 * 11-bit companded representation. The 11-bit representation has two 488 * distinct regions. A linear bottom end up through .018316 in steps 489 * of about .000073, and a region of constant ratio up to about 25. 490 * These floating point numbers are stored in the main table ToLinearF. 491 * All other tables are derived from this one. The tables (and the 492 * ratios) are continuous at the internal seam. 493 */ 494 495 int nlin, lt2size; 496 int i, j; 497 double b, c, linstep, v; 498 float *ToLinearF; 499 uint16 *ToLinear16; 500 unsigned char *ToLinear8; 501 uint16 *FromLT2; 502 uint16 *From14; /* Really for 16-bit data, but we shift down 2 */ 503 uint16 *From8; 504 505 c = log(RATIO); 506 nlin = (int)(1./c); /* nlin must be an integer */ 507 c = 1./nlin; 508 b = exp(-c*ONE); /* multiplicative scale factor [b*exp(c*ONE) = 1] */ 509 linstep = b*c*exp(1.); 510 511 LogK1 = (float)(1./c); /* if (v >= 2) token = k1*log(v*k2) */ 512 LogK2 = (float)(1./b); 513 lt2size = (int)(2./linstep) + 1; 514 FromLT2 = (uint16 *)_TIFFmalloc(lt2size*sizeof(uint16)); 515 From14 = (uint16 *)_TIFFmalloc(16384*sizeof(uint16)); 516 From8 = (uint16 *)_TIFFmalloc(256*sizeof(uint16)); 517 ToLinearF = (float *)_TIFFmalloc(TSIZEP1 * sizeof(float)); 518 ToLinear16 = (uint16 *)_TIFFmalloc(TSIZEP1 * sizeof(uint16)); 519 ToLinear8 = (unsigned char *)_TIFFmalloc(TSIZEP1 * sizeof(unsigned char)); 520 if (FromLT2 == NULL || From14 == NULL || From8 == NULL || 521 ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) { 522 if (FromLT2) _TIFFfree(FromLT2); 523 if (From14) _TIFFfree(From14); 524 if (From8) _TIFFfree(From8); 525 if (ToLinearF) _TIFFfree(ToLinearF); 526 if (ToLinear16) _TIFFfree(ToLinear16); 527 if (ToLinear8) _TIFFfree(ToLinear8); 528 sp->FromLT2 = NULL; 529 sp->From14 = NULL; 530 sp->From8 = NULL; 531 sp->ToLinearF = NULL; 532 sp->ToLinear16 = NULL; 533 sp->ToLinear8 = NULL; 534 return 0; 535 } 536 537 j = 0; 538 539 for (i = 0; i < nlin; i++) { 540 v = i * linstep; 541 ToLinearF[j++] = (float)v; 542 } 543 544 for (i = nlin; i < TSIZE; i++) 545 ToLinearF[j++] = (float)(b*exp(c*i)); 546 547 ToLinearF[2048] = ToLinearF[2047]; 548 549 for (i = 0; i < TSIZEP1; i++) { 550 v = ToLinearF[i]*65535.0 + 0.5; 551 ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16)v; 552 v = ToLinearF[i]*255.0 + 0.5; 553 ToLinear8[i] = (v > 255.0) ? 255 : (unsigned char)v; 554 } 555 556 j = 0; 557 for (i = 0; i < lt2size; i++) { 558 if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1]) 559 j++; 560 FromLT2[i] = (uint16)j; 561 } 562 563 /* 564 * Since we lose info anyway on 16-bit data, we set up a 14-bit 565 * table and shift 16-bit values down two bits on input. 566 * saves a little table space. 567 */ 568 j = 0; 569 for (i = 0; i < 16384; i++) { 570 while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1]) 571 j++; 572 From14[i] = (uint16)j; 573 } 574 575 j = 0; 576 for (i = 0; i < 256; i++) { 577 while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1]) 578 j++; 579 From8[i] = (uint16)j; 580 } 581 582 Fltsize = (float)(lt2size/2); 583 584 sp->ToLinearF = ToLinearF; 585 sp->ToLinear16 = ToLinear16; 586 sp->ToLinear8 = ToLinear8; 587 sp->FromLT2 = FromLT2; 588 sp->From14 = From14; 589 sp->From8 = From8; 590 591 return 1; 592 } 593 594 #define DecoderState(tif) ((PixarLogState*) (tif)->tif_data) 595 #define EncoderState(tif) ((PixarLogState*) (tif)->tif_data) 596 597 static int PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); 598 static int PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s); 599 600 #define PIXARLOGDATAFMT_UNKNOWN -1 601 602 static int 603 PixarLogGuessDataFmt(TIFFDirectory *td) 604 { 605 int guess = PIXARLOGDATAFMT_UNKNOWN; 606 int format = td->td_sampleformat; 607 608 /* If the user didn't tell us his datafmt, 609 * take our best guess from the bitspersample. 610 */ 611 switch (td->td_bitspersample) { 612 case 32: 613 if (format == SAMPLEFORMAT_IEEEFP) 614 guess = PIXARLOGDATAFMT_FLOAT; 615 break; 616 case 16: 617 if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) 618 guess = PIXARLOGDATAFMT_16BIT; 619 break; 620 case 12: 621 if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT) 622 guess = PIXARLOGDATAFMT_12BITPICIO; 623 break; 624 case 11: 625 if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) 626 guess = PIXARLOGDATAFMT_11BITLOG; 627 break; 628 case 8: 629 if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) 630 guess = PIXARLOGDATAFMT_8BIT; 631 break; 632 } 633 634 return guess; 635 } 636 637 static tmsize_t 638 multiply_ms(tmsize_t m1, tmsize_t m2) 639 { 640 return _TIFFMultiplySSize(NULL, m1, m2, NULL); 641 } 642 643 static tmsize_t 644 add_ms(tmsize_t m1, tmsize_t m2) 645 { 646 assert(m1 >= 0 && m2 >= 0); 647 /* if either input is zero, assume overflow already occurred */ 648 if (m1 == 0 || m2 == 0) 649 return 0; 650 else if (m1 > TIFF_TMSIZE_T_MAX - m2) 651 return 0; 652 653 return m1 + m2; 654 } 655 656 static int 657 PixarLogFixupTags(TIFF* tif) 658 { 659 (void) tif; 660 return (1); 661 } 662 663 static int 664 PixarLogSetupDecode(TIFF* tif) 665 { 666 static const char module[] = "PixarLogSetupDecode"; 667 TIFFDirectory *td = &tif->tif_dir; 668 PixarLogState* sp = DecoderState(tif); 669 tmsize_t tbuf_size; 670 uint32 strip_height; 671 672 assert(sp != NULL); 673 674 /* This function can possibly be called several times by */ 675 /* PredictorSetupDecode() if this function succeeds but */ 676 /* PredictorSetup() fails */ 677 if( (sp->state & PLSTATE_INIT) != 0 ) 678 return 1; 679 680 strip_height = td->td_rowsperstrip; 681 if( strip_height > td->td_imagelength ) 682 strip_height = td->td_imagelength; 683 684 /* Make sure no byte swapping happens on the data 685 * after decompression. */ 686 tif->tif_postdecode = _TIFFNoPostDecode; 687 688 /* for some reason, we can't do this in TIFFInitPixarLog */ 689 690 sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? 691 td->td_samplesperpixel : 1); 692 tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), 693 strip_height), sizeof(uint16)); 694 /* add one more stride in case input ends mid-stride */ 695 tbuf_size = add_ms(tbuf_size, sizeof(uint16) * sp->stride); 696 if (tbuf_size == 0) 697 return (0); /* TODO: this is an error return without error report through TIFFErrorExt */ 698 sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size); 699 if (sp->tbuf == NULL) 700 return (0); 701 sp->tbuf_size = tbuf_size; 702 if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) 703 sp->user_datafmt = PixarLogGuessDataFmt(td); 704 if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { 705 _TIFFfree(sp->tbuf); 706 sp->tbuf = NULL; 707 sp->tbuf_size = 0; 708 TIFFErrorExt(tif->tif_clientdata, module, 709 "PixarLog compression can't handle bits depth/data format combination (depth: %d)", 710 td->td_bitspersample); 711 return (0); 712 } 713 714 if (inflateInit(&sp->stream) != Z_OK) { 715 _TIFFfree(sp->tbuf); 716 sp->tbuf = NULL; 717 sp->tbuf_size = 0; 718 TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg ? sp->stream.msg : "(null)"); 719 return (0); 720 } else { 721 sp->state |= PLSTATE_INIT; 722 return (1); 723 } 724 } 725 726 /* 727 * Setup state for decoding a strip. 728 */ 729 static int 730 PixarLogPreDecode(TIFF* tif, uint16 s) 731 { 732 static const char module[] = "PixarLogPreDecode"; 733 PixarLogState* sp = DecoderState(tif); 734 735 (void) s; 736 assert(sp != NULL); 737 sp->stream.next_in = tif->tif_rawdata; 738 assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, 739 we need to simplify this code to reflect a ZLib that is likely updated 740 to deal with 8byte memory sizes, though this code will respond 741 appropriately even before we simplify it */ 742 sp->stream.avail_in = (uInt) tif->tif_rawcc; 743 if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) 744 { 745 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); 746 return (0); 747 } 748 return (inflateReset(&sp->stream) == Z_OK); 749 } 750 751 static int 752 PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) 753 { 754 static const char module[] = "PixarLogDecode"; 755 TIFFDirectory *td = &tif->tif_dir; 756 PixarLogState* sp = DecoderState(tif); 757 tmsize_t i; 758 tmsize_t nsamples; 759 int llen; 760 uint16 *up; 761 762 switch (sp->user_datafmt) { 763 case PIXARLOGDATAFMT_FLOAT: 764 nsamples = occ / sizeof(float); /* XXX float == 32 bits */ 765 break; 766 case PIXARLOGDATAFMT_16BIT: 767 case PIXARLOGDATAFMT_12BITPICIO: 768 case PIXARLOGDATAFMT_11BITLOG: 769 nsamples = occ / sizeof(uint16); /* XXX uint16 == 16 bits */ 770 break; 771 case PIXARLOGDATAFMT_8BIT: 772 case PIXARLOGDATAFMT_8BITABGR: 773 nsamples = occ; 774 break; 775 default: 776 TIFFErrorExt(tif->tif_clientdata, module, 777 "%d bit input not supported in PixarLog", 778 td->td_bitspersample); 779 return 0; 780 } 781 782 llen = sp->stride * td->td_imagewidth; 783 784 (void) s; 785 assert(sp != NULL); 786 787 sp->stream.next_in = tif->tif_rawcp; 788 sp->stream.avail_in = (uInt) tif->tif_rawcc; 789 790 sp->stream.next_out = (unsigned char *) sp->tbuf; 791 assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, 792 we need to simplify this code to reflect a ZLib that is likely updated 793 to deal with 8byte memory sizes, though this code will respond 794 appropriately even before we simplify it */ 795 sp->stream.avail_out = (uInt) (nsamples * sizeof(uint16)); 796 if (sp->stream.avail_out != nsamples * sizeof(uint16)) 797 { 798 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); 799 return (0); 800 } 801 /* Check that we will not fill more than what was allocated */ 802 if ((tmsize_t)sp->stream.avail_out > sp->tbuf_size) 803 { 804 TIFFErrorExt(tif->tif_clientdata, module, "sp->stream.avail_out > sp->tbuf_size"); 805 return (0); 806 } 807 do { 808 int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); 809 if (state == Z_STREAM_END) { 810 break; /* XXX */ 811 } 812 if (state == Z_DATA_ERROR) { 813 TIFFErrorExt(tif->tif_clientdata, module, 814 "Decoding error at scanline %lu, %s", 815 (unsigned long) tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)"); 816 return (0); 817 } 818 if (state != Z_OK) { 819 TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", 820 sp->stream.msg ? sp->stream.msg : "(null)"); 821 return (0); 822 } 823 } while (sp->stream.avail_out > 0); 824 825 /* hopefully, we got all the bytes we needed */ 826 if (sp->stream.avail_out != 0) { 827 TIFFErrorExt(tif->tif_clientdata, module, 828 "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)", 829 (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out); 830 return (0); 831 } 832 833 tif->tif_rawcp = sp->stream.next_in; 834 tif->tif_rawcc = sp->stream.avail_in; 835 836 up = sp->tbuf; 837 /* Swap bytes in the data if from a different endian machine. */ 838 if (tif->tif_flags & TIFF_SWAB) 839 TIFFSwabArrayOfShort(up, nsamples); 840 841 /* 842 * if llen is not an exact multiple of nsamples, the decode operation 843 * may overflow the output buffer, so truncate it enough to prevent 844 * that but still salvage as much data as possible. 845 */ 846 if (nsamples % llen) { 847 TIFFWarningExt(tif->tif_clientdata, module, 848 "stride %lu is not a multiple of sample count, " 849 "%lu, data truncated.", (unsigned long) llen, (unsigned long) nsamples); 850 nsamples -= nsamples % llen; 851 } 852 853 for (i = 0; i < nsamples; i += llen, up += llen) { 854 switch (sp->user_datafmt) { 855 case PIXARLOGDATAFMT_FLOAT: 856 horizontalAccumulateF(up, llen, sp->stride, 857 (float *)op, sp->ToLinearF); 858 op += llen * sizeof(float); 859 break; 860 case PIXARLOGDATAFMT_16BIT: 861 horizontalAccumulate16(up, llen, sp->stride, 862 (uint16 *)op, sp->ToLinear16); 863 op += llen * sizeof(uint16); 864 break; 865 case PIXARLOGDATAFMT_12BITPICIO: 866 horizontalAccumulate12(up, llen, sp->stride, 867 (int16 *)op, sp->ToLinearF); 868 op += llen * sizeof(int16); 869 break; 870 case PIXARLOGDATAFMT_11BITLOG: 871 horizontalAccumulate11(up, llen, sp->stride, 872 (uint16 *)op); 873 op += llen * sizeof(uint16); 874 break; 875 case PIXARLOGDATAFMT_8BIT: 876 horizontalAccumulate8(up, llen, sp->stride, 877 (unsigned char *)op, sp->ToLinear8); 878 op += llen * sizeof(unsigned char); 879 break; 880 case PIXARLOGDATAFMT_8BITABGR: 881 horizontalAccumulate8abgr(up, llen, sp->stride, 882 (unsigned char *)op, sp->ToLinear8); 883 op += llen * sizeof(unsigned char); 884 break; 885 default: 886 TIFFErrorExt(tif->tif_clientdata, module, 887 "Unsupported bits/sample: %d", 888 td->td_bitspersample); 889 return (0); 890 } 891 } 892 893 return (1); 894 } 895 896 static int 897 PixarLogSetupEncode(TIFF* tif) 898 { 899 static const char module[] = "PixarLogSetupEncode"; 900 TIFFDirectory *td = &tif->tif_dir; 901 PixarLogState* sp = EncoderState(tif); 902 tmsize_t tbuf_size; 903 904 assert(sp != NULL); 905 906 /* for some reason, we can't do this in TIFFInitPixarLog */ 907 908 sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? 909 td->td_samplesperpixel : 1); 910 tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), 911 td->td_rowsperstrip), sizeof(uint16)); 912 if (tbuf_size == 0) 913 return (0); /* TODO: this is an error return without error report through TIFFErrorExt */ 914 sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size); 915 if (sp->tbuf == NULL) 916 return (0); 917 if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) 918 sp->user_datafmt = PixarLogGuessDataFmt(td); 919 if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { 920 TIFFErrorExt(tif->tif_clientdata, module, "PixarLog compression can't handle %d bit linear encodings", td->td_bitspersample); 921 return (0); 922 } 923 924 if (deflateInit(&sp->stream, sp->quality) != Z_OK) { 925 TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg ? sp->stream.msg : "(null)"); 926 return (0); 927 } else { 928 sp->state |= PLSTATE_INIT; 929 return (1); 930 } 931 } 932 933 /* 934 * Reset encoding state at the start of a strip. 935 */ 936 static int 937 PixarLogPreEncode(TIFF* tif, uint16 s) 938 { 939 static const char module[] = "PixarLogPreEncode"; 940 PixarLogState *sp = EncoderState(tif); 941 942 (void) s; 943 assert(sp != NULL); 944 sp->stream.next_out = tif->tif_rawdata; 945 assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, 946 we need to simplify this code to reflect a ZLib that is likely updated 947 to deal with 8byte memory sizes, though this code will respond 948 appropriately even before we simplify it */ 949 sp->stream.avail_out = (uInt)tif->tif_rawdatasize; 950 if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) 951 { 952 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); 953 return (0); 954 } 955 return (deflateReset(&sp->stream) == Z_OK); 956 } 957 958 static void 959 horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2) 960 { 961 int32 r1, g1, b1, a1, r2, g2, b2, a2, mask; 962 float fltsize = Fltsize; 963 964 #define CLAMP(v) ( (v<(float)0.) ? 0 \ 965 : (v<(float)2.) ? FromLT2[(int)(v*fltsize)] \ 966 : (v>(float)24.2) ? 2047 \ 967 : LogK1*log(v*LogK2) + 0.5 ) 968 969 mask = CODE_MASK; 970 if (n >= stride) { 971 if (stride == 3) { 972 r2 = wp[0] = (uint16) CLAMP(ip[0]); 973 g2 = wp[1] = (uint16) CLAMP(ip[1]); 974 b2 = wp[2] = (uint16) CLAMP(ip[2]); 975 n -= 3; 976 while (n > 0) { 977 n -= 3; 978 wp += 3; 979 ip += 3; 980 r1 = (int32) CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1; 981 g1 = (int32) CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1; 982 b1 = (int32) CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1; 983 } 984 } else if (stride == 4) { 985 r2 = wp[0] = (uint16) CLAMP(ip[0]); 986 g2 = wp[1] = (uint16) CLAMP(ip[1]); 987 b2 = wp[2] = (uint16) CLAMP(ip[2]); 988 a2 = wp[3] = (uint16) CLAMP(ip[3]); 989 n -= 4; 990 while (n > 0) { 991 n -= 4; 992 wp += 4; 993 ip += 4; 994 r1 = (int32) CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1; 995 g1 = (int32) CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1; 996 b1 = (int32) CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1; 997 a1 = (int32) CLAMP(ip[3]); wp[3] = (uint16)((a1-a2) & mask); a2 = a1; 998 } 999 } else { 1000 REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp++; ip++) 1001 n -= stride; 1002 while (n > 0) { 1003 REPEAT(stride, 1004 wp[0] = (uint16)(((int32)CLAMP(ip[0])-(int32)CLAMP(ip[-stride])) & mask); 1005 wp++; ip++) 1006 n -= stride; 1007 } 1008 } 1009 } 1010 } 1011 1012 static void 1013 horizontalDifference16(unsigned short *ip, int n, int stride, 1014 unsigned short *wp, uint16 *From14) 1015 { 1016 register int r1, g1, b1, a1, r2, g2, b2, a2, mask; 1017 1018 /* assumption is unsigned pixel values */ 1019 #undef CLAMP 1020 #define CLAMP(v) From14[(v) >> 2] 1021 1022 mask = CODE_MASK; 1023 if (n >= stride) { 1024 if (stride == 3) { 1025 r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); 1026 b2 = wp[2] = CLAMP(ip[2]); 1027 n -= 3; 1028 while (n > 0) { 1029 n -= 3; 1030 wp += 3; 1031 ip += 3; 1032 r1 = CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1; 1033 g1 = CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1; 1034 b1 = CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1; 1035 } 1036 } else if (stride == 4) { 1037 r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); 1038 b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]); 1039 n -= 4; 1040 while (n > 0) { 1041 n -= 4; 1042 wp += 4; 1043 ip += 4; 1044 r1 = CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1; 1045 g1 = CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1; 1046 b1 = CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1; 1047 a1 = CLAMP(ip[3]); wp[3] = (uint16)((a1-a2) & mask); a2 = a1; 1048 } 1049 } else { 1050 REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++) 1051 n -= stride; 1052 while (n > 0) { 1053 REPEAT(stride, 1054 wp[0] = (uint16)((CLAMP(ip[0])-CLAMP(ip[-stride])) & mask); 1055 wp++; ip++) 1056 n -= stride; 1057 } 1058 } 1059 } 1060 } 1061 1062 1063 static void 1064 horizontalDifference8(unsigned char *ip, int n, int stride, 1065 unsigned short *wp, uint16 *From8) 1066 { 1067 register int r1, g1, b1, a1, r2, g2, b2, a2, mask; 1068 1069 #undef CLAMP 1070 #define CLAMP(v) (From8[(v)]) 1071 1072 mask = CODE_MASK; 1073 if (n >= stride) { 1074 if (stride == 3) { 1075 r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); 1076 b2 = wp[2] = CLAMP(ip[2]); 1077 n -= 3; 1078 while (n > 0) { 1079 n -= 3; 1080 r1 = CLAMP(ip[3]); wp[3] = (uint16)((r1-r2) & mask); r2 = r1; 1081 g1 = CLAMP(ip[4]); wp[4] = (uint16)((g1-g2) & mask); g2 = g1; 1082 b1 = CLAMP(ip[5]); wp[5] = (uint16)((b1-b2) & mask); b2 = b1; 1083 wp += 3; 1084 ip += 3; 1085 } 1086 } else if (stride == 4) { 1087 r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); 1088 b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]); 1089 n -= 4; 1090 while (n > 0) { 1091 n -= 4; 1092 r1 = CLAMP(ip[4]); wp[4] = (uint16)((r1-r2) & mask); r2 = r1; 1093 g1 = CLAMP(ip[5]); wp[5] = (uint16)((g1-g2) & mask); g2 = g1; 1094 b1 = CLAMP(ip[6]); wp[6] = (uint16)((b1-b2) & mask); b2 = b1; 1095 a1 = CLAMP(ip[7]); wp[7] = (uint16)((a1-a2) & mask); a2 = a1; 1096 wp += 4; 1097 ip += 4; 1098 } 1099 } else { 1100 REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++) 1101 n -= stride; 1102 while (n > 0) { 1103 REPEAT(stride, 1104 wp[0] = (uint16)((CLAMP(ip[0])-CLAMP(ip[-stride])) & mask); 1105 wp++; ip++) 1106 n -= stride; 1107 } 1108 } 1109 } 1110 } 1111 1112 /* 1113 * Encode a chunk of pixels. 1114 */ 1115 static int 1116 PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) 1117 { 1118 static const char module[] = "PixarLogEncode"; 1119 TIFFDirectory *td = &tif->tif_dir; 1120 PixarLogState *sp = EncoderState(tif); 1121 tmsize_t i; 1122 tmsize_t n; 1123 int llen; 1124 unsigned short * up; 1125 1126 (void) s; 1127 1128 switch (sp->user_datafmt) { 1129 case PIXARLOGDATAFMT_FLOAT: 1130 n = cc / sizeof(float); /* XXX float == 32 bits */ 1131 break; 1132 case PIXARLOGDATAFMT_16BIT: 1133 case PIXARLOGDATAFMT_12BITPICIO: 1134 case PIXARLOGDATAFMT_11BITLOG: 1135 n = cc / sizeof(uint16); /* XXX uint16 == 16 bits */ 1136 break; 1137 case PIXARLOGDATAFMT_8BIT: 1138 case PIXARLOGDATAFMT_8BITABGR: 1139 n = cc; 1140 break; 1141 default: 1142 TIFFErrorExt(tif->tif_clientdata, module, 1143 "%d bit input not supported in PixarLog", 1144 td->td_bitspersample); 1145 return 0; 1146 } 1147 1148 llen = sp->stride * td->td_imagewidth; 1149 /* Check against the number of elements (of size uint16) of sp->tbuf */ 1150 if( n > ((tmsize_t)td->td_rowsperstrip * llen) ) 1151 { 1152 TIFFErrorExt(tif->tif_clientdata, module, 1153 "Too many input bytes provided"); 1154 return 0; 1155 } 1156 1157 for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) { 1158 switch (sp->user_datafmt) { 1159 case PIXARLOGDATAFMT_FLOAT: 1160 horizontalDifferenceF((float *)bp, llen, 1161 sp->stride, up, sp->FromLT2); 1162 bp += llen * sizeof(float); 1163 break; 1164 case PIXARLOGDATAFMT_16BIT: 1165 horizontalDifference16((uint16 *)bp, llen, 1166 sp->stride, up, sp->From14); 1167 bp += llen * sizeof(uint16); 1168 break; 1169 case PIXARLOGDATAFMT_8BIT: 1170 horizontalDifference8((unsigned char *)bp, llen, 1171 sp->stride, up, sp->From8); 1172 bp += llen * sizeof(unsigned char); 1173 break; 1174 default: 1175 TIFFErrorExt(tif->tif_clientdata, module, 1176 "%d bit input not supported in PixarLog", 1177 td->td_bitspersample); 1178 return 0; 1179 } 1180 } 1181 1182 sp->stream.next_in = (unsigned char *) sp->tbuf; 1183 assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, 1184 we need to simplify this code to reflect a ZLib that is likely updated 1185 to deal with 8byte memory sizes, though this code will respond 1186 appropriately even before we simplify it */ 1187 sp->stream.avail_in = (uInt) (n * sizeof(uint16)); 1188 if ((sp->stream.avail_in / sizeof(uint16)) != (uInt) n) 1189 { 1190 TIFFErrorExt(tif->tif_clientdata, module, 1191 "ZLib cannot deal with buffers this size"); 1192 return (0); 1193 } 1194 1195 do { 1196 if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { 1197 TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s", 1198 sp->stream.msg ? sp->stream.msg : "(null)"); 1199 return (0); 1200 } 1201 if (sp->stream.avail_out == 0) { 1202 tif->tif_rawcc = tif->tif_rawdatasize; 1203 TIFFFlushData1(tif); 1204 sp->stream.next_out = tif->tif_rawdata; 1205 sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */ 1206 } 1207 } while (sp->stream.avail_in > 0); 1208 return (1); 1209 } 1210 1211 /* 1212 * Finish off an encoded strip by flushing the last 1213 * string and tacking on an End Of Information code. 1214 */ 1215 1216 static int 1217 PixarLogPostEncode(TIFF* tif) 1218 { 1219 static const char module[] = "PixarLogPostEncode"; 1220 PixarLogState *sp = EncoderState(tif); 1221 int state; 1222 1223 sp->stream.avail_in = 0; 1224 1225 do { 1226 state = deflate(&sp->stream, Z_FINISH); 1227 switch (state) { 1228 case Z_STREAM_END: 1229 case Z_OK: 1230 if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { 1231 tif->tif_rawcc = 1232 tif->tif_rawdatasize - sp->stream.avail_out; 1233 TIFFFlushData1(tif); 1234 sp->stream.next_out = tif->tif_rawdata; 1235 sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */ 1236 } 1237 break; 1238 default: 1239 TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", 1240 sp->stream.msg ? sp->stream.msg : "(null)"); 1241 return (0); 1242 } 1243 } while (state != Z_STREAM_END); 1244 return (1); 1245 } 1246 1247 static void 1248 PixarLogClose(TIFF* tif) 1249 { 1250 PixarLogState* sp = (PixarLogState*) tif->tif_data; 1251 TIFFDirectory *td = &tif->tif_dir; 1252 1253 assert(sp != 0); 1254 /* In a really sneaky (and really incorrect, and untruthful, and 1255 * troublesome, and error-prone) maneuver that completely goes against 1256 * the spirit of TIFF, and breaks TIFF, on close, we covertly 1257 * modify both bitspersample and sampleformat in the directory to 1258 * indicate 8-bit linear. This way, the decode "just works" even for 1259 * readers that don't know about PixarLog, or how to set 1260 * the PIXARLOGDATFMT pseudo-tag. 1261 */ 1262 1263 if (sp->state&PLSTATE_INIT) { 1264 /* We test the state to avoid an issue such as in 1265 * http://bugzilla.maptools.org/show_bug.cgi?id=2604 1266 * What appends in that case is that the bitspersample is 1 and 1267 * a TransferFunction is set. The size of the TransferFunction 1268 * depends on 1<<bitspersample. So if we increase it, an access 1269 * out of the buffer will happen at directory flushing. 1270 * Another option would be to clear those targs. 1271 */ 1272 td->td_bitspersample = 8; 1273 td->td_sampleformat = SAMPLEFORMAT_UINT; 1274 } 1275 } 1276 1277 static void 1278 PixarLogCleanup(TIFF* tif) 1279 { 1280 PixarLogState* sp = (PixarLogState*) tif->tif_data; 1281 1282 assert(sp != 0); 1283 1284 (void)TIFFPredictorCleanup(tif); 1285 1286 tif->tif_tagmethods.vgetfield = sp->vgetparent; 1287 tif->tif_tagmethods.vsetfield = sp->vsetparent; 1288 1289 if (sp->FromLT2) _TIFFfree(sp->FromLT2); 1290 if (sp->From14) _TIFFfree(sp->From14); 1291 if (sp->From8) _TIFFfree(sp->From8); 1292 if (sp->ToLinearF) _TIFFfree(sp->ToLinearF); 1293 if (sp->ToLinear16) _TIFFfree(sp->ToLinear16); 1294 if (sp->ToLinear8) _TIFFfree(sp->ToLinear8); 1295 if (sp->state&PLSTATE_INIT) { 1296 if (tif->tif_mode == O_RDONLY) 1297 inflateEnd(&sp->stream); 1298 else 1299 deflateEnd(&sp->stream); 1300 } 1301 if (sp->tbuf) 1302 _TIFFfree(sp->tbuf); 1303 _TIFFfree(sp); 1304 tif->tif_data = NULL; 1305 1306 _TIFFSetDefaultCompressionState(tif); 1307 } 1308 1309 static int 1310 PixarLogVSetField(TIFF* tif, uint32 tag, va_list ap) 1311 { 1312 static const char module[] = "PixarLogVSetField"; 1313 PixarLogState *sp = (PixarLogState *)tif->tif_data; 1314 int result; 1315 1316 switch (tag) { 1317 case TIFFTAG_PIXARLOGQUALITY: 1318 sp->quality = (int) va_arg(ap, int); 1319 if (tif->tif_mode != O_RDONLY && (sp->state&PLSTATE_INIT)) { 1320 if (deflateParams(&sp->stream, 1321 sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) { 1322 TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", 1323 sp->stream.msg ? sp->stream.msg : "(null)"); 1324 return (0); 1325 } 1326 } 1327 return (1); 1328 case TIFFTAG_PIXARLOGDATAFMT: 1329 sp->user_datafmt = (int) va_arg(ap, int); 1330 /* Tweak the TIFF header so that the rest of libtiff knows what 1331 * size of data will be passed between app and library, and 1332 * assume that the app knows what it is doing and is not 1333 * confused by these header manipulations... 1334 */ 1335 switch (sp->user_datafmt) { 1336 case PIXARLOGDATAFMT_8BIT: 1337 case PIXARLOGDATAFMT_8BITABGR: 1338 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8); 1339 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); 1340 break; 1341 case PIXARLOGDATAFMT_11BITLOG: 1342 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); 1343 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); 1344 break; 1345 case PIXARLOGDATAFMT_12BITPICIO: 1346 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); 1347 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); 1348 break; 1349 case PIXARLOGDATAFMT_16BIT: 1350 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); 1351 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); 1352 break; 1353 case PIXARLOGDATAFMT_FLOAT: 1354 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32); 1355 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); 1356 break; 1357 } 1358 /* 1359 * Must recalculate sizes should bits/sample change. 1360 */ 1361 tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); 1362 tif->tif_scanlinesize = TIFFScanlineSize(tif); 1363 result = 1; /* NB: pseudo tag */ 1364 break; 1365 default: 1366 result = (*sp->vsetparent)(tif, tag, ap); 1367 } 1368 return (result); 1369 } 1370 1371 static int 1372 PixarLogVGetField(TIFF* tif, uint32 tag, va_list ap) 1373 { 1374 PixarLogState *sp = (PixarLogState *)tif->tif_data; 1375 1376 switch (tag) { 1377 case TIFFTAG_PIXARLOGQUALITY: 1378 *va_arg(ap, int*) = sp->quality; 1379 break; 1380 case TIFFTAG_PIXARLOGDATAFMT: 1381 *va_arg(ap, int*) = sp->user_datafmt; 1382 break; 1383 default: 1384 return (*sp->vgetparent)(tif, tag, ap); 1385 } 1386 return (1); 1387 } 1388 1389 static const TIFFField pixarlogFields[] = { 1390 {TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}, 1391 {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL} 1392 }; 1393 1394 int 1395 TIFFInitPixarLog(TIFF* tif, int scheme) 1396 { 1397 static const char module[] = "TIFFInitPixarLog"; 1398 1399 PixarLogState* sp; 1400 1401 assert(scheme == COMPRESSION_PIXARLOG); 1402 1403 /* 1404 * Merge codec-specific tag information. 1405 */ 1406 if (!_TIFFMergeFields(tif, pixarlogFields, 1407 TIFFArrayCount(pixarlogFields))) { 1408 TIFFErrorExt(tif->tif_clientdata, module, 1409 "Merging PixarLog codec-specific tags failed"); 1410 return 0; 1411 } 1412 1413 /* 1414 * Allocate state block so tag methods have storage to record values. 1415 */ 1416 tif->tif_data = (uint8*) _TIFFmalloc(sizeof (PixarLogState)); 1417 if (tif->tif_data == NULL) 1418 goto bad; 1419 sp = (PixarLogState*) tif->tif_data; 1420 _TIFFmemset(sp, 0, sizeof (*sp)); 1421 sp->stream.data_type = Z_BINARY; 1422 sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN; 1423 1424 /* 1425 * Install codec methods. 1426 */ 1427 tif->tif_fixuptags = PixarLogFixupTags; 1428 tif->tif_setupdecode = PixarLogSetupDecode; 1429 tif->tif_predecode = PixarLogPreDecode; 1430 tif->tif_decoderow = PixarLogDecode; 1431 tif->tif_decodestrip = PixarLogDecode; 1432 tif->tif_decodetile = PixarLogDecode; 1433 tif->tif_setupencode = PixarLogSetupEncode; 1434 tif->tif_preencode = PixarLogPreEncode; 1435 tif->tif_postencode = PixarLogPostEncode; 1436 tif->tif_encoderow = PixarLogEncode; 1437 tif->tif_encodestrip = PixarLogEncode; 1438 tif->tif_encodetile = PixarLogEncode; 1439 tif->tif_close = PixarLogClose; 1440 tif->tif_cleanup = PixarLogCleanup; 1441 1442 /* Override SetField so we can handle our private pseudo-tag */ 1443 sp->vgetparent = tif->tif_tagmethods.vgetfield; 1444 tif->tif_tagmethods.vgetfield = PixarLogVGetField; /* hook for codec tags */ 1445 sp->vsetparent = tif->tif_tagmethods.vsetfield; 1446 tif->tif_tagmethods.vsetfield = PixarLogVSetField; /* hook for codec tags */ 1447 1448 /* Default values for codec-specific fields */ 1449 sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */ 1450 sp->state = 0; 1451 1452 /* we don't wish to use the predictor, 1453 * the default is none, which predictor value 1 1454 */ 1455 (void) TIFFPredictorInit(tif); 1456 1457 /* 1458 * build the companding tables 1459 */ 1460 PixarLogMakeTables(sp); 1461 1462 return (1); 1463 bad: 1464 TIFFErrorExt(tif->tif_clientdata, module, 1465 "No space for PixarLog state block"); 1466 return (0); 1467 } 1468 #endif /* PIXARLOG_SUPPORT */ 1469 1470 /* vim: set ts=8 sts=8 sw=8 noet: */ 1471 /* 1472 * Local Variables: 1473 * mode: c 1474 * c-basic-offset: 8 1475 * fill-column: 78 1476 * End: 1477 */ 1478