1 /* $Id: tif_pixarlog.c,v 1.54 2017-07-10 10:40:28 erouault 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 <precomp.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" highlights 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 * susceptible to such errors than standard 8-bit encodings, but more 56 * susceptible 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] = wp[0]; op[1] = wp[1]; op[2] = wp[2]; 305 cr = wp[0]; cg = wp[1]; cb = wp[2]; 306 n -= 3; 307 while (n > 0) { 308 wp += 3; 309 op += 3; 310 n -= 3; 311 op[0] = (uint16)((cr += wp[0]) & mask); 312 op[1] = (uint16)((cg += wp[1]) & mask); 313 op[2] = (uint16)((cb += wp[2]) & mask); 314 } 315 } else if (stride == 4) { 316 op[0] = wp[0]; op[1] = wp[1]; 317 op[2] = wp[2]; op[3] = wp[3]; 318 cr = wp[0]; cg = wp[1]; cb = wp[2]; ca = wp[3]; 319 n -= 4; 320 while (n > 0) { 321 wp += 4; 322 op += 4; 323 n -= 4; 324 op[0] = (uint16)((cr += wp[0]) & mask); 325 op[1] = (uint16)((cg += wp[1]) & mask); 326 op[2] = (uint16)((cb += wp[2]) & mask); 327 op[3] = (uint16)((ca += wp[3]) & mask); 328 } 329 } else { 330 REPEAT(stride, *op = *wp&mask; wp++; op++) 331 n -= stride; 332 while (n > 0) { 333 REPEAT(stride, 334 wp[stride] += *wp; *op = *wp&mask; wp++; op++) 335 n -= stride; 336 } 337 } 338 } 339 } 340 341 static void 342 horizontalAccumulate8(uint16 *wp, int n, int stride, unsigned char *op, 343 unsigned char *ToLinear8) 344 { 345 register unsigned int cr, cg, cb, ca, mask; 346 347 if (n >= stride) { 348 mask = CODE_MASK; 349 if (stride == 3) { 350 op[0] = ToLinear8[cr = (wp[0] & mask)]; 351 op[1] = ToLinear8[cg = (wp[1] & mask)]; 352 op[2] = ToLinear8[cb = (wp[2] & mask)]; 353 n -= 3; 354 while (n > 0) { 355 n -= 3; 356 wp += 3; 357 op += 3; 358 op[0] = ToLinear8[(cr += wp[0]) & mask]; 359 op[1] = ToLinear8[(cg += wp[1]) & mask]; 360 op[2] = ToLinear8[(cb += wp[2]) & mask]; 361 } 362 } else if (stride == 4) { 363 op[0] = ToLinear8[cr = (wp[0] & mask)]; 364 op[1] = ToLinear8[cg = (wp[1] & mask)]; 365 op[2] = ToLinear8[cb = (wp[2] & mask)]; 366 op[3] = ToLinear8[ca = (wp[3] & mask)]; 367 n -= 4; 368 while (n > 0) { 369 n -= 4; 370 wp += 4; 371 op += 4; 372 op[0] = ToLinear8[(cr += wp[0]) & mask]; 373 op[1] = ToLinear8[(cg += wp[1]) & mask]; 374 op[2] = ToLinear8[(cb += wp[2]) & mask]; 375 op[3] = ToLinear8[(ca += wp[3]) & mask]; 376 } 377 } else { 378 REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++) 379 n -= stride; 380 while (n > 0) { 381 REPEAT(stride, 382 wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++) 383 n -= stride; 384 } 385 } 386 } 387 } 388 389 390 static void 391 horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op, 392 unsigned char *ToLinear8) 393 { 394 register unsigned int cr, cg, cb, ca, mask; 395 register unsigned char t0, t1, t2, t3; 396 397 if (n >= stride) { 398 mask = CODE_MASK; 399 if (stride == 3) { 400 op[0] = 0; 401 t1 = ToLinear8[cb = (wp[2] & mask)]; 402 t2 = ToLinear8[cg = (wp[1] & mask)]; 403 t3 = ToLinear8[cr = (wp[0] & mask)]; 404 op[1] = t1; 405 op[2] = t2; 406 op[3] = t3; 407 n -= 3; 408 while (n > 0) { 409 n -= 3; 410 wp += 3; 411 op += 4; 412 op[0] = 0; 413 t1 = ToLinear8[(cb += wp[2]) & mask]; 414 t2 = ToLinear8[(cg += wp[1]) & mask]; 415 t3 = ToLinear8[(cr += wp[0]) & mask]; 416 op[1] = t1; 417 op[2] = t2; 418 op[3] = t3; 419 } 420 } else if (stride == 4) { 421 t0 = ToLinear8[ca = (wp[3] & mask)]; 422 t1 = ToLinear8[cb = (wp[2] & mask)]; 423 t2 = ToLinear8[cg = (wp[1] & mask)]; 424 t3 = ToLinear8[cr = (wp[0] & mask)]; 425 op[0] = t0; 426 op[1] = t1; 427 op[2] = t2; 428 op[3] = t3; 429 n -= 4; 430 while (n > 0) { 431 n -= 4; 432 wp += 4; 433 op += 4; 434 t0 = ToLinear8[(ca += wp[3]) & mask]; 435 t1 = ToLinear8[(cb += wp[2]) & mask]; 436 t2 = ToLinear8[(cg += wp[1]) & mask]; 437 t3 = ToLinear8[(cr += wp[0]) & mask]; 438 op[0] = t0; 439 op[1] = t1; 440 op[2] = t2; 441 op[3] = t3; 442 } 443 } else { 444 REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++) 445 n -= stride; 446 while (n > 0) { 447 REPEAT(stride, 448 wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++) 449 n -= stride; 450 } 451 } 452 } 453 } 454 455 /* 456 * State block for each open TIFF 457 * file using PixarLog compression/decompression. 458 */ 459 typedef struct { 460 TIFFPredictorState predict; 461 z_stream stream; 462 tmsize_t tbuf_size; /* only set/used on reading for now */ 463 uint16 *tbuf; 464 uint16 stride; 465 int state; 466 int user_datafmt; 467 int quality; 468 #define PLSTATE_INIT 1 469 470 TIFFVSetMethod vgetparent; /* super-class method */ 471 TIFFVSetMethod vsetparent; /* super-class method */ 472 473 float *ToLinearF; 474 uint16 *ToLinear16; 475 unsigned char *ToLinear8; 476 uint16 *FromLT2; 477 uint16 *From14; /* Really for 16-bit data, but we shift down 2 */ 478 uint16 *From8; 479 480 } PixarLogState; 481 482 static int 483 PixarLogMakeTables(PixarLogState *sp) 484 { 485 486 /* 487 * We make several tables here to convert between various external 488 * representations (float, 16-bit, and 8-bit) and the internal 489 * 11-bit companded representation. The 11-bit representation has two 490 * distinct regions. A linear bottom end up through .018316 in steps 491 * of about .000073, and a region of constant ratio up to about 25. 492 * These floating point numbers are stored in the main table ToLinearF. 493 * All other tables are derived from this one. The tables (and the 494 * ratios) are continuous at the internal seam. 495 */ 496 497 int nlin, lt2size; 498 int i, j; 499 double b, c, linstep, v; 500 float *ToLinearF; 501 uint16 *ToLinear16; 502 unsigned char *ToLinear8; 503 uint16 *FromLT2; 504 uint16 *From14; /* Really for 16-bit data, but we shift down 2 */ 505 uint16 *From8; 506 507 c = log(RATIO); 508 nlin = (int)(1./c); /* nlin must be an integer */ 509 c = 1./nlin; 510 b = exp(-c*ONE); /* multiplicative scale factor [b*exp(c*ONE) = 1] */ 511 linstep = b*c*exp(1.); 512 513 LogK1 = (float)(1./c); /* if (v >= 2) token = k1*log(v*k2) */ 514 LogK2 = (float)(1./b); 515 lt2size = (int)(2./linstep) + 1; 516 FromLT2 = (uint16 *)_TIFFmalloc(lt2size*sizeof(uint16)); 517 From14 = (uint16 *)_TIFFmalloc(16384*sizeof(uint16)); 518 From8 = (uint16 *)_TIFFmalloc(256*sizeof(uint16)); 519 ToLinearF = (float *)_TIFFmalloc(TSIZEP1 * sizeof(float)); 520 ToLinear16 = (uint16 *)_TIFFmalloc(TSIZEP1 * sizeof(uint16)); 521 ToLinear8 = (unsigned char *)_TIFFmalloc(TSIZEP1 * sizeof(unsigned char)); 522 if (FromLT2 == NULL || From14 == NULL || From8 == NULL || 523 ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) { 524 if (FromLT2) _TIFFfree(FromLT2); 525 if (From14) _TIFFfree(From14); 526 if (From8) _TIFFfree(From8); 527 if (ToLinearF) _TIFFfree(ToLinearF); 528 if (ToLinear16) _TIFFfree(ToLinear16); 529 if (ToLinear8) _TIFFfree(ToLinear8); 530 sp->FromLT2 = NULL; 531 sp->From14 = NULL; 532 sp->From8 = NULL; 533 sp->ToLinearF = NULL; 534 sp->ToLinear16 = NULL; 535 sp->ToLinear8 = NULL; 536 return 0; 537 } 538 539 j = 0; 540 541 for (i = 0; i < nlin; i++) { 542 v = i * linstep; 543 ToLinearF[j++] = (float)v; 544 } 545 546 for (i = nlin; i < TSIZE; i++) 547 ToLinearF[j++] = (float)(b*exp(c*i)); 548 549 ToLinearF[2048] = ToLinearF[2047]; 550 551 for (i = 0; i < TSIZEP1; i++) { 552 v = ToLinearF[i]*65535.0 + 0.5; 553 ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16)v; 554 v = ToLinearF[i]*255.0 + 0.5; 555 ToLinear8[i] = (v > 255.0) ? 255 : (unsigned char)v; 556 } 557 558 j = 0; 559 for (i = 0; i < lt2size; i++) { 560 if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1]) 561 j++; 562 FromLT2[i] = (uint16)j; 563 } 564 565 /* 566 * Since we lose info anyway on 16-bit data, we set up a 14-bit 567 * table and shift 16-bit values down two bits on input. 568 * saves a little table space. 569 */ 570 j = 0; 571 for (i = 0; i < 16384; i++) { 572 while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1]) 573 j++; 574 From14[i] = (uint16)j; 575 } 576 577 j = 0; 578 for (i = 0; i < 256; i++) { 579 while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1]) 580 j++; 581 From8[i] = (uint16)j; 582 } 583 584 Fltsize = (float)(lt2size/2); 585 586 sp->ToLinearF = ToLinearF; 587 sp->ToLinear16 = ToLinear16; 588 sp->ToLinear8 = ToLinear8; 589 sp->FromLT2 = FromLT2; 590 sp->From14 = From14; 591 sp->From8 = From8; 592 593 return 1; 594 } 595 596 #define DecoderState(tif) ((PixarLogState*) (tif)->tif_data) 597 #define EncoderState(tif) ((PixarLogState*) (tif)->tif_data) 598 599 static int PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); 600 static int PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s); 601 602 #define PIXARLOGDATAFMT_UNKNOWN -1 603 604 static int 605 PixarLogGuessDataFmt(TIFFDirectory *td) 606 { 607 int guess = PIXARLOGDATAFMT_UNKNOWN; 608 int format = td->td_sampleformat; 609 610 /* If the user didn't tell us his datafmt, 611 * take our best guess from the bitspersample. 612 */ 613 switch (td->td_bitspersample) { 614 case 32: 615 if (format == SAMPLEFORMAT_IEEEFP) 616 guess = PIXARLOGDATAFMT_FLOAT; 617 break; 618 case 16: 619 if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) 620 guess = PIXARLOGDATAFMT_16BIT; 621 break; 622 case 12: 623 if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT) 624 guess = PIXARLOGDATAFMT_12BITPICIO; 625 break; 626 case 11: 627 if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) 628 guess = PIXARLOGDATAFMT_11BITLOG; 629 break; 630 case 8: 631 if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) 632 guess = PIXARLOGDATAFMT_8BIT; 633 break; 634 } 635 636 return guess; 637 } 638 639 #define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0)) 640 #define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1) 641 642 static tmsize_t 643 multiply_ms(tmsize_t m1, tmsize_t m2) 644 { 645 if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 ) 646 return 0; 647 return m1 * m2; 648 } 649 650 static tmsize_t 651 add_ms(tmsize_t m1, tmsize_t m2) 652 { 653 /* if either input is zero, assume overflow already occurred */ 654 if (m1 == 0 || m2 == 0) 655 return 0; 656 else if (m1 > TIFF_TMSIZE_T_MAX - m2) 657 return 0; 658 659 return m1 + m2; 660 } 661 662 static int 663 PixarLogFixupTags(TIFF* tif) 664 { 665 (void) tif; 666 return (1); 667 } 668 669 static int 670 PixarLogSetupDecode(TIFF* tif) 671 { 672 static const char module[] = "PixarLogSetupDecode"; 673 TIFFDirectory *td = &tif->tif_dir; 674 PixarLogState* sp = DecoderState(tif); 675 tmsize_t tbuf_size; 676 uint32 strip_height; 677 678 assert(sp != NULL); 679 680 /* This function can possibly be called several times by */ 681 /* PredictorSetupDecode() if this function succeeds but */ 682 /* PredictorSetup() fails */ 683 if( (sp->state & PLSTATE_INIT) != 0 ) 684 return 1; 685 686 strip_height = td->td_rowsperstrip; 687 if( strip_height > td->td_imagelength ) 688 strip_height = td->td_imagelength; 689 690 /* Make sure no byte swapping happens on the data 691 * after decompression. */ 692 tif->tif_postdecode = _TIFFNoPostDecode; 693 694 /* for some reason, we can't do this in TIFFInitPixarLog */ 695 696 sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? 697 td->td_samplesperpixel : 1); 698 tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), 699 strip_height), sizeof(uint16)); 700 /* add one more stride in case input ends mid-stride */ 701 tbuf_size = add_ms(tbuf_size, sizeof(uint16) * sp->stride); 702 if (tbuf_size == 0) 703 return (0); /* TODO: this is an error return without error report through TIFFErrorExt */ 704 sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size); 705 if (sp->tbuf == NULL) 706 return (0); 707 sp->tbuf_size = tbuf_size; 708 if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) 709 sp->user_datafmt = PixarLogGuessDataFmt(td); 710 if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { 711 _TIFFfree(sp->tbuf); 712 sp->tbuf = NULL; 713 sp->tbuf_size = 0; 714 TIFFErrorExt(tif->tif_clientdata, module, 715 "PixarLog compression can't handle bits depth/data format combination (depth: %d)", 716 td->td_bitspersample); 717 return (0); 718 } 719 720 if (inflateInit(&sp->stream) != Z_OK) { 721 _TIFFfree(sp->tbuf); 722 sp->tbuf = NULL; 723 sp->tbuf_size = 0; 724 TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg ? sp->stream.msg : "(null)"); 725 return (0); 726 } else { 727 sp->state |= PLSTATE_INIT; 728 return (1); 729 } 730 } 731 732 /* 733 * Setup state for decoding a strip. 734 */ 735 static int 736 PixarLogPreDecode(TIFF* tif, uint16 s) 737 { 738 static const char module[] = "PixarLogPreDecode"; 739 PixarLogState* sp = DecoderState(tif); 740 741 (void) s; 742 assert(sp != NULL); 743 sp->stream.next_in = tif->tif_rawdata; 744 assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, 745 we need to simplify this code to reflect a ZLib that is likely updated 746 to deal with 8byte memory sizes, though this code will respond 747 appropriately even before we simplify it */ 748 sp->stream.avail_in = (uInt) tif->tif_rawcc; 749 if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) 750 { 751 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); 752 return (0); 753 } 754 return (inflateReset(&sp->stream) == Z_OK); 755 } 756 757 static int 758 PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) 759 { 760 static const char module[] = "PixarLogDecode"; 761 TIFFDirectory *td = &tif->tif_dir; 762 PixarLogState* sp = DecoderState(tif); 763 tmsize_t i; 764 tmsize_t nsamples; 765 int llen; 766 uint16 *up; 767 768 switch (sp->user_datafmt) { 769 case PIXARLOGDATAFMT_FLOAT: 770 nsamples = occ / sizeof(float); /* XXX float == 32 bits */ 771 break; 772 case PIXARLOGDATAFMT_16BIT: 773 case PIXARLOGDATAFMT_12BITPICIO: 774 case PIXARLOGDATAFMT_11BITLOG: 775 nsamples = occ / sizeof(uint16); /* XXX uint16 == 16 bits */ 776 break; 777 case PIXARLOGDATAFMT_8BIT: 778 case PIXARLOGDATAFMT_8BITABGR: 779 nsamples = occ; 780 break; 781 default: 782 TIFFErrorExt(tif->tif_clientdata, module, 783 "%d bit input not supported in PixarLog", 784 td->td_bitspersample); 785 return 0; 786 } 787 788 llen = sp->stride * td->td_imagewidth; 789 790 (void) s; 791 assert(sp != NULL); 792 793 sp->stream.next_in = tif->tif_rawcp; 794 sp->stream.avail_in = (uInt) tif->tif_rawcc; 795 796 sp->stream.next_out = (unsigned char *) sp->tbuf; 797 assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, 798 we need to simplify this code to reflect a ZLib that is likely updated 799 to deal with 8byte memory sizes, though this code will respond 800 appropriately even before we simplify it */ 801 sp->stream.avail_out = (uInt) (nsamples * sizeof(uint16)); 802 if (sp->stream.avail_out != nsamples * sizeof(uint16)) 803 { 804 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); 805 return (0); 806 } 807 /* Check that we will not fill more than what was allocated */ 808 if ((tmsize_t)sp->stream.avail_out > sp->tbuf_size) 809 { 810 TIFFErrorExt(tif->tif_clientdata, module, "sp->stream.avail_out > sp->tbuf_size"); 811 return (0); 812 } 813 do { 814 int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); 815 if (state == Z_STREAM_END) { 816 break; /* XXX */ 817 } 818 if (state == Z_DATA_ERROR) { 819 TIFFErrorExt(tif->tif_clientdata, module, 820 "Decoding error at scanline %lu, %s", 821 (unsigned long) tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)"); 822 if (inflateSync(&sp->stream) != Z_OK) 823 return (0); 824 continue; 825 } 826 if (state != Z_OK) { 827 TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", 828 sp->stream.msg ? sp->stream.msg : "(null)"); 829 return (0); 830 } 831 } while (sp->stream.avail_out > 0); 832 833 /* hopefully, we got all the bytes we needed */ 834 if (sp->stream.avail_out != 0) { 835 TIFFErrorExt(tif->tif_clientdata, module, 836 "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)", 837 (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out); 838 return (0); 839 } 840 841 tif->tif_rawcp = sp->stream.next_in; 842 tif->tif_rawcc = sp->stream.avail_in; 843 844 up = sp->tbuf; 845 /* Swap bytes in the data if from a different endian machine. */ 846 if (tif->tif_flags & TIFF_SWAB) 847 TIFFSwabArrayOfShort(up, nsamples); 848 849 /* 850 * if llen is not an exact multiple of nsamples, the decode operation 851 * may overflow the output buffer, so truncate it enough to prevent 852 * that but still salvage as much data as possible. 853 */ 854 if (nsamples % llen) { 855 TIFFWarningExt(tif->tif_clientdata, module, 856 "stride %lu is not a multiple of sample count, " 857 "%lu, data truncated.", (unsigned long) llen, (unsigned long) nsamples); 858 nsamples -= nsamples % llen; 859 } 860 861 for (i = 0; i < nsamples; i += llen, up += llen) { 862 switch (sp->user_datafmt) { 863 case PIXARLOGDATAFMT_FLOAT: 864 horizontalAccumulateF(up, llen, sp->stride, 865 (float *)op, sp->ToLinearF); 866 op += llen * sizeof(float); 867 break; 868 case PIXARLOGDATAFMT_16BIT: 869 horizontalAccumulate16(up, llen, sp->stride, 870 (uint16 *)op, sp->ToLinear16); 871 op += llen * sizeof(uint16); 872 break; 873 case PIXARLOGDATAFMT_12BITPICIO: 874 horizontalAccumulate12(up, llen, sp->stride, 875 (int16 *)op, sp->ToLinearF); 876 op += llen * sizeof(int16); 877 break; 878 case PIXARLOGDATAFMT_11BITLOG: 879 horizontalAccumulate11(up, llen, sp->stride, 880 (uint16 *)op); 881 op += llen * sizeof(uint16); 882 break; 883 case PIXARLOGDATAFMT_8BIT: 884 horizontalAccumulate8(up, llen, sp->stride, 885 (unsigned char *)op, sp->ToLinear8); 886 op += llen * sizeof(unsigned char); 887 break; 888 case PIXARLOGDATAFMT_8BITABGR: 889 horizontalAccumulate8abgr(up, llen, sp->stride, 890 (unsigned char *)op, sp->ToLinear8); 891 op += llen * sizeof(unsigned char); 892 break; 893 default: 894 TIFFErrorExt(tif->tif_clientdata, module, 895 "Unsupported bits/sample: %d", 896 td->td_bitspersample); 897 return (0); 898 } 899 } 900 901 return (1); 902 } 903 904 static int 905 PixarLogSetupEncode(TIFF* tif) 906 { 907 static const char module[] = "PixarLogSetupEncode"; 908 TIFFDirectory *td = &tif->tif_dir; 909 PixarLogState* sp = EncoderState(tif); 910 tmsize_t tbuf_size; 911 912 assert(sp != NULL); 913 914 /* for some reason, we can't do this in TIFFInitPixarLog */ 915 916 sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? 917 td->td_samplesperpixel : 1); 918 tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), 919 td->td_rowsperstrip), sizeof(uint16)); 920 if (tbuf_size == 0) 921 return (0); /* TODO: this is an error return without error report through TIFFErrorExt */ 922 sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size); 923 if (sp->tbuf == NULL) 924 return (0); 925 if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) 926 sp->user_datafmt = PixarLogGuessDataFmt(td); 927 if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { 928 TIFFErrorExt(tif->tif_clientdata, module, "PixarLog compression can't handle %d bit linear encodings", td->td_bitspersample); 929 return (0); 930 } 931 932 if (deflateInit(&sp->stream, sp->quality) != Z_OK) { 933 TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg ? sp->stream.msg : "(null)"); 934 return (0); 935 } else { 936 sp->state |= PLSTATE_INIT; 937 return (1); 938 } 939 } 940 941 /* 942 * Reset encoding state at the start of a strip. 943 */ 944 static int 945 PixarLogPreEncode(TIFF* tif, uint16 s) 946 { 947 static const char module[] = "PixarLogPreEncode"; 948 PixarLogState *sp = EncoderState(tif); 949 950 (void) s; 951 assert(sp != NULL); 952 sp->stream.next_out = tif->tif_rawdata; 953 assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, 954 we need to simplify this code to reflect a ZLib that is likely updated 955 to deal with 8byte memory sizes, though this code will respond 956 appropriately even before we simplify it */ 957 sp->stream.avail_out = (uInt)tif->tif_rawdatasize; 958 if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) 959 { 960 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); 961 return (0); 962 } 963 return (deflateReset(&sp->stream) == Z_OK); 964 } 965 966 static void 967 horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2) 968 { 969 int32 r1, g1, b1, a1, r2, g2, b2, a2, mask; 970 float fltsize = Fltsize; 971 972 #define CLAMP(v) ( (v<(float)0.) ? 0 \ 973 : (v<(float)2.) ? FromLT2[(int)(v*fltsize)] \ 974 : (v>(float)24.2) ? 2047 \ 975 : LogK1*log(v*LogK2) + 0.5 ) 976 977 mask = CODE_MASK; 978 if (n >= stride) { 979 if (stride == 3) { 980 r2 = wp[0] = (uint16) CLAMP(ip[0]); 981 g2 = wp[1] = (uint16) CLAMP(ip[1]); 982 b2 = wp[2] = (uint16) CLAMP(ip[2]); 983 n -= 3; 984 while (n > 0) { 985 n -= 3; 986 wp += 3; 987 ip += 3; 988 r1 = (int32) CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1; 989 g1 = (int32) CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1; 990 b1 = (int32) CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1; 991 } 992 } else if (stride == 4) { 993 r2 = wp[0] = (uint16) CLAMP(ip[0]); 994 g2 = wp[1] = (uint16) CLAMP(ip[1]); 995 b2 = wp[2] = (uint16) CLAMP(ip[2]); 996 a2 = wp[3] = (uint16) CLAMP(ip[3]); 997 n -= 4; 998 while (n > 0) { 999 n -= 4; 1000 wp += 4; 1001 ip += 4; 1002 r1 = (int32) CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1; 1003 g1 = (int32) CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1; 1004 b1 = (int32) CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1; 1005 a1 = (int32) CLAMP(ip[3]); wp[3] = (uint16)((a1-a2) & mask); a2 = a1; 1006 } 1007 } else { 1008 REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp++; ip++) 1009 n -= stride; 1010 while (n > 0) { 1011 REPEAT(stride, 1012 wp[0] = (uint16)(((int32)CLAMP(ip[0])-(int32)CLAMP(ip[-stride])) & mask); 1013 wp++; ip++) 1014 n -= stride; 1015 } 1016 } 1017 } 1018 } 1019 1020 static void 1021 horizontalDifference16(unsigned short *ip, int n, int stride, 1022 unsigned short *wp, uint16 *From14) 1023 { 1024 register int r1, g1, b1, a1, r2, g2, b2, a2, mask; 1025 1026 /* assumption is unsigned pixel values */ 1027 #undef CLAMP 1028 #define CLAMP(v) From14[(v) >> 2] 1029 1030 mask = CODE_MASK; 1031 if (n >= stride) { 1032 if (stride == 3) { 1033 r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); 1034 b2 = wp[2] = CLAMP(ip[2]); 1035 n -= 3; 1036 while (n > 0) { 1037 n -= 3; 1038 wp += 3; 1039 ip += 3; 1040 r1 = CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1; 1041 g1 = CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1; 1042 b1 = CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1; 1043 } 1044 } else if (stride == 4) { 1045 r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); 1046 b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]); 1047 n -= 4; 1048 while (n > 0) { 1049 n -= 4; 1050 wp += 4; 1051 ip += 4; 1052 r1 = CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1; 1053 g1 = CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1; 1054 b1 = CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1; 1055 a1 = CLAMP(ip[3]); wp[3] = (uint16)((a1-a2) & mask); a2 = a1; 1056 } 1057 } else { 1058 REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++) 1059 n -= stride; 1060 while (n > 0) { 1061 REPEAT(stride, 1062 wp[0] = (uint16)((CLAMP(ip[0])-CLAMP(ip[-stride])) & mask); 1063 wp++; ip++) 1064 n -= stride; 1065 } 1066 } 1067 } 1068 } 1069 1070 1071 static void 1072 horizontalDifference8(unsigned char *ip, int n, int stride, 1073 unsigned short *wp, uint16 *From8) 1074 { 1075 register int r1, g1, b1, a1, r2, g2, b2, a2, mask; 1076 1077 #undef CLAMP 1078 #define CLAMP(v) (From8[(v)]) 1079 1080 mask = CODE_MASK; 1081 if (n >= stride) { 1082 if (stride == 3) { 1083 r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); 1084 b2 = wp[2] = CLAMP(ip[2]); 1085 n -= 3; 1086 while (n > 0) { 1087 n -= 3; 1088 r1 = CLAMP(ip[3]); wp[3] = (uint16)((r1-r2) & mask); r2 = r1; 1089 g1 = CLAMP(ip[4]); wp[4] = (uint16)((g1-g2) & mask); g2 = g1; 1090 b1 = CLAMP(ip[5]); wp[5] = (uint16)((b1-b2) & mask); b2 = b1; 1091 wp += 3; 1092 ip += 3; 1093 } 1094 } else if (stride == 4) { 1095 r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); 1096 b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]); 1097 n -= 4; 1098 while (n > 0) { 1099 n -= 4; 1100 r1 = CLAMP(ip[4]); wp[4] = (uint16)((r1-r2) & mask); r2 = r1; 1101 g1 = CLAMP(ip[5]); wp[5] = (uint16)((g1-g2) & mask); g2 = g1; 1102 b1 = CLAMP(ip[6]); wp[6] = (uint16)((b1-b2) & mask); b2 = b1; 1103 a1 = CLAMP(ip[7]); wp[7] = (uint16)((a1-a2) & mask); a2 = a1; 1104 wp += 4; 1105 ip += 4; 1106 } 1107 } else { 1108 REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++) 1109 n -= stride; 1110 while (n > 0) { 1111 REPEAT(stride, 1112 wp[0] = (uint16)((CLAMP(ip[0])-CLAMP(ip[-stride])) & mask); 1113 wp++; ip++) 1114 n -= stride; 1115 } 1116 } 1117 } 1118 } 1119 1120 /* 1121 * Encode a chunk of pixels. 1122 */ 1123 static int 1124 PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) 1125 { 1126 static const char module[] = "PixarLogEncode"; 1127 TIFFDirectory *td = &tif->tif_dir; 1128 PixarLogState *sp = EncoderState(tif); 1129 tmsize_t i; 1130 tmsize_t n; 1131 int llen; 1132 unsigned short * up; 1133 1134 (void) s; 1135 1136 switch (sp->user_datafmt) { 1137 case PIXARLOGDATAFMT_FLOAT: 1138 n = cc / sizeof(float); /* XXX float == 32 bits */ 1139 break; 1140 case PIXARLOGDATAFMT_16BIT: 1141 case PIXARLOGDATAFMT_12BITPICIO: 1142 case PIXARLOGDATAFMT_11BITLOG: 1143 n = cc / sizeof(uint16); /* XXX uint16 == 16 bits */ 1144 break; 1145 case PIXARLOGDATAFMT_8BIT: 1146 case PIXARLOGDATAFMT_8BITABGR: 1147 n = cc; 1148 break; 1149 default: 1150 TIFFErrorExt(tif->tif_clientdata, module, 1151 "%d bit input not supported in PixarLog", 1152 td->td_bitspersample); 1153 return 0; 1154 } 1155 1156 llen = sp->stride * td->td_imagewidth; 1157 /* Check against the number of elements (of size uint16) of sp->tbuf */ 1158 if( n > (tmsize_t)(td->td_rowsperstrip * llen) ) 1159 { 1160 TIFFErrorExt(tif->tif_clientdata, module, 1161 "Too many input bytes provided"); 1162 return 0; 1163 } 1164 1165 for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) { 1166 switch (sp->user_datafmt) { 1167 case PIXARLOGDATAFMT_FLOAT: 1168 horizontalDifferenceF((float *)bp, llen, 1169 sp->stride, up, sp->FromLT2); 1170 bp += llen * sizeof(float); 1171 break; 1172 case PIXARLOGDATAFMT_16BIT: 1173 horizontalDifference16((uint16 *)bp, llen, 1174 sp->stride, up, sp->From14); 1175 bp += llen * sizeof(uint16); 1176 break; 1177 case PIXARLOGDATAFMT_8BIT: 1178 horizontalDifference8((unsigned char *)bp, llen, 1179 sp->stride, up, sp->From8); 1180 bp += llen * sizeof(unsigned char); 1181 break; 1182 default: 1183 TIFFErrorExt(tif->tif_clientdata, module, 1184 "%d bit input not supported in PixarLog", 1185 td->td_bitspersample); 1186 return 0; 1187 } 1188 } 1189 1190 sp->stream.next_in = (unsigned char *) sp->tbuf; 1191 assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, 1192 we need to simplify this code to reflect a ZLib that is likely updated 1193 to deal with 8byte memory sizes, though this code will respond 1194 appropriately even before we simplify it */ 1195 sp->stream.avail_in = (uInt) (n * sizeof(uint16)); 1196 if ((sp->stream.avail_in / sizeof(uint16)) != (uInt) n) 1197 { 1198 TIFFErrorExt(tif->tif_clientdata, module, 1199 "ZLib cannot deal with buffers this size"); 1200 return (0); 1201 } 1202 1203 do { 1204 if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { 1205 TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s", 1206 sp->stream.msg ? sp->stream.msg : "(null)"); 1207 return (0); 1208 } 1209 if (sp->stream.avail_out == 0) { 1210 tif->tif_rawcc = tif->tif_rawdatasize; 1211 TIFFFlushData1(tif); 1212 sp->stream.next_out = tif->tif_rawdata; 1213 sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */ 1214 } 1215 } while (sp->stream.avail_in > 0); 1216 return (1); 1217 } 1218 1219 /* 1220 * Finish off an encoded strip by flushing the last 1221 * string and tacking on an End Of Information code. 1222 */ 1223 1224 static int 1225 PixarLogPostEncode(TIFF* tif) 1226 { 1227 static const char module[] = "PixarLogPostEncode"; 1228 PixarLogState *sp = EncoderState(tif); 1229 int state; 1230 1231 sp->stream.avail_in = 0; 1232 1233 do { 1234 state = deflate(&sp->stream, Z_FINISH); 1235 switch (state) { 1236 case Z_STREAM_END: 1237 case Z_OK: 1238 if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { 1239 tif->tif_rawcc = 1240 tif->tif_rawdatasize - sp->stream.avail_out; 1241 TIFFFlushData1(tif); 1242 sp->stream.next_out = tif->tif_rawdata; 1243 sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */ 1244 } 1245 break; 1246 default: 1247 TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", 1248 sp->stream.msg ? sp->stream.msg : "(null)"); 1249 return (0); 1250 } 1251 } while (state != Z_STREAM_END); 1252 return (1); 1253 } 1254 1255 static void 1256 PixarLogClose(TIFF* tif) 1257 { 1258 PixarLogState* sp = (PixarLogState*) tif->tif_data; 1259 TIFFDirectory *td = &tif->tif_dir; 1260 1261 assert(sp != 0); 1262 /* In a really sneaky (and really incorrect, and untruthful, and 1263 * troublesome, and error-prone) maneuver that completely goes against 1264 * the spirit of TIFF, and breaks TIFF, on close, we covertly 1265 * modify both bitspersample and sampleformat in the directory to 1266 * indicate 8-bit linear. This way, the decode "just works" even for 1267 * readers that don't know about PixarLog, or how to set 1268 * the PIXARLOGDATFMT pseudo-tag. 1269 */ 1270 1271 if (sp->state&PLSTATE_INIT) { 1272 /* We test the state to avoid an issue such as in 1273 * http://bugzilla.maptools.org/show_bug.cgi?id=2604 1274 * What appends in that case is that the bitspersample is 1 and 1275 * a TransferFunction is set. The size of the TransferFunction 1276 * depends on 1<<bitspersample. So if we increase it, an access 1277 * out of the buffer will happen at directory flushing. 1278 * Another option would be to clear those targs. 1279 */ 1280 td->td_bitspersample = 8; 1281 td->td_sampleformat = SAMPLEFORMAT_UINT; 1282 } 1283 } 1284 1285 static void 1286 PixarLogCleanup(TIFF* tif) 1287 { 1288 PixarLogState* sp = (PixarLogState*) tif->tif_data; 1289 1290 assert(sp != 0); 1291 1292 (void)TIFFPredictorCleanup(tif); 1293 1294 tif->tif_tagmethods.vgetfield = sp->vgetparent; 1295 tif->tif_tagmethods.vsetfield = sp->vsetparent; 1296 1297 if (sp->FromLT2) _TIFFfree(sp->FromLT2); 1298 if (sp->From14) _TIFFfree(sp->From14); 1299 if (sp->From8) _TIFFfree(sp->From8); 1300 if (sp->ToLinearF) _TIFFfree(sp->ToLinearF); 1301 if (sp->ToLinear16) _TIFFfree(sp->ToLinear16); 1302 if (sp->ToLinear8) _TIFFfree(sp->ToLinear8); 1303 if (sp->state&PLSTATE_INIT) { 1304 if (tif->tif_mode == O_RDONLY) 1305 inflateEnd(&sp->stream); 1306 else 1307 deflateEnd(&sp->stream); 1308 } 1309 if (sp->tbuf) 1310 _TIFFfree(sp->tbuf); 1311 _TIFFfree(sp); 1312 tif->tif_data = NULL; 1313 1314 _TIFFSetDefaultCompressionState(tif); 1315 } 1316 1317 static int 1318 PixarLogVSetField(TIFF* tif, uint32 tag, va_list ap) 1319 { 1320 static const char module[] = "PixarLogVSetField"; 1321 PixarLogState *sp = (PixarLogState *)tif->tif_data; 1322 int result; 1323 1324 switch (tag) { 1325 case TIFFTAG_PIXARLOGQUALITY: 1326 sp->quality = (int) va_arg(ap, int); 1327 if (tif->tif_mode != O_RDONLY && (sp->state&PLSTATE_INIT)) { 1328 if (deflateParams(&sp->stream, 1329 sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) { 1330 TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", 1331 sp->stream.msg ? sp->stream.msg : "(null)"); 1332 return (0); 1333 } 1334 } 1335 return (1); 1336 case TIFFTAG_PIXARLOGDATAFMT: 1337 sp->user_datafmt = (int) va_arg(ap, int); 1338 /* Tweak the TIFF header so that the rest of libtiff knows what 1339 * size of data will be passed between app and library, and 1340 * assume that the app knows what it is doing and is not 1341 * confused by these header manipulations... 1342 */ 1343 switch (sp->user_datafmt) { 1344 case PIXARLOGDATAFMT_8BIT: 1345 case PIXARLOGDATAFMT_8BITABGR: 1346 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8); 1347 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); 1348 break; 1349 case PIXARLOGDATAFMT_11BITLOG: 1350 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); 1351 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); 1352 break; 1353 case PIXARLOGDATAFMT_12BITPICIO: 1354 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); 1355 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); 1356 break; 1357 case PIXARLOGDATAFMT_16BIT: 1358 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); 1359 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); 1360 break; 1361 case PIXARLOGDATAFMT_FLOAT: 1362 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32); 1363 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); 1364 break; 1365 } 1366 /* 1367 * Must recalculate sizes should bits/sample change. 1368 */ 1369 tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); 1370 tif->tif_scanlinesize = TIFFScanlineSize(tif); 1371 result = 1; /* NB: pseudo tag */ 1372 break; 1373 default: 1374 result = (*sp->vsetparent)(tif, tag, ap); 1375 } 1376 return (result); 1377 } 1378 1379 static int 1380 PixarLogVGetField(TIFF* tif, uint32 tag, va_list ap) 1381 { 1382 PixarLogState *sp = (PixarLogState *)tif->tif_data; 1383 1384 switch (tag) { 1385 case TIFFTAG_PIXARLOGQUALITY: 1386 *va_arg(ap, int*) = sp->quality; 1387 break; 1388 case TIFFTAG_PIXARLOGDATAFMT: 1389 *va_arg(ap, int*) = sp->user_datafmt; 1390 break; 1391 default: 1392 return (*sp->vgetparent)(tif, tag, ap); 1393 } 1394 return (1); 1395 } 1396 1397 static const TIFFField pixarlogFields[] = { 1398 {TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}, 1399 {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL} 1400 }; 1401 1402 int 1403 TIFFInitPixarLog(TIFF* tif, int scheme) 1404 { 1405 static const char module[] = "TIFFInitPixarLog"; 1406 1407 PixarLogState* sp; 1408 1409 assert(scheme == COMPRESSION_PIXARLOG); 1410 1411 /* 1412 * Merge codec-specific tag information. 1413 */ 1414 if (!_TIFFMergeFields(tif, pixarlogFields, 1415 TIFFArrayCount(pixarlogFields))) { 1416 TIFFErrorExt(tif->tif_clientdata, module, 1417 "Merging PixarLog codec-specific tags failed"); 1418 return 0; 1419 } 1420 1421 /* 1422 * Allocate state block so tag methods have storage to record values. 1423 */ 1424 tif->tif_data = (uint8*) _TIFFmalloc(sizeof (PixarLogState)); 1425 if (tif->tif_data == NULL) 1426 goto bad; 1427 sp = (PixarLogState*) tif->tif_data; 1428 _TIFFmemset(sp, 0, sizeof (*sp)); 1429 sp->stream.data_type = Z_BINARY; 1430 sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN; 1431 1432 /* 1433 * Install codec methods. 1434 */ 1435 tif->tif_fixuptags = PixarLogFixupTags; 1436 tif->tif_setupdecode = PixarLogSetupDecode; 1437 tif->tif_predecode = PixarLogPreDecode; 1438 tif->tif_decoderow = PixarLogDecode; 1439 tif->tif_decodestrip = PixarLogDecode; 1440 tif->tif_decodetile = PixarLogDecode; 1441 tif->tif_setupencode = PixarLogSetupEncode; 1442 tif->tif_preencode = PixarLogPreEncode; 1443 tif->tif_postencode = PixarLogPostEncode; 1444 tif->tif_encoderow = PixarLogEncode; 1445 tif->tif_encodestrip = PixarLogEncode; 1446 tif->tif_encodetile = PixarLogEncode; 1447 tif->tif_close = PixarLogClose; 1448 tif->tif_cleanup = PixarLogCleanup; 1449 1450 /* Override SetField so we can handle our private pseudo-tag */ 1451 sp->vgetparent = tif->tif_tagmethods.vgetfield; 1452 tif->tif_tagmethods.vgetfield = PixarLogVGetField; /* hook for codec tags */ 1453 sp->vsetparent = tif->tif_tagmethods.vsetfield; 1454 tif->tif_tagmethods.vsetfield = PixarLogVSetField; /* hook for codec tags */ 1455 1456 /* Default values for codec-specific fields */ 1457 sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */ 1458 sp->state = 0; 1459 1460 /* we don't wish to use the predictor, 1461 * the default is none, which predictor value 1 1462 */ 1463 (void) TIFFPredictorInit(tif); 1464 1465 /* 1466 * build the companding tables 1467 */ 1468 PixarLogMakeTables(sp); 1469 1470 return (1); 1471 bad: 1472 TIFFErrorExt(tif->tif_clientdata, module, 1473 "No space for PixarLog state block"); 1474 return (0); 1475 } 1476 #endif /* PIXARLOG_SUPPORT */ 1477 1478 /* vim: set ts=8 sts=8 sw=8 noet: */ 1479 /* 1480 * Local Variables: 1481 * mode: c 1482 * c-basic-offset: 8 1483 * fill-column: 78 1484 * End: 1485 */ 1486