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