1 /* $Id: tif_luv.c,v 1.47 2017-05-14 10:17:27 erouault Exp $ */ 2 3 /* 4 * Copyright (c) 1997 Greg Ward Larson 5 * Copyright (c) 1997 Silicon Graphics, Inc. 6 * 7 * Permission to use, copy, modify, distribute, and sell this software and 8 * its documentation for any purpose is hereby granted without fee, provided 9 * that (i) the above copyright notices and this permission notice appear in 10 * all copies of the software and related documentation, and (ii) the names of 11 * Sam Leffler, Greg Larson and Silicon Graphics may not be used in any 12 * advertising or publicity relating to the software without the specific, 13 * prior written permission of Sam Leffler, Greg Larson and Silicon Graphics. 14 * 15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 18 * 19 * IN NO EVENT SHALL SAM LEFFLER, GREG LARSON OR SILICON GRAPHICS BE LIABLE 20 * FOR 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 29 #ifdef LOGLUV_SUPPORT 30 31 /* 32 * TIFF Library. 33 * LogLuv compression support for high dynamic range images. 34 * 35 * Contributed by Greg Larson. 36 * 37 * LogLuv image support uses the TIFF library to store 16 or 10-bit 38 * log luminance values with 8 bits each of u and v or a 14-bit index. 39 * 40 * The codec can take as input and produce as output 32-bit IEEE float values 41 * as well as 16-bit integer values. A 16-bit luminance is interpreted 42 * as a sign bit followed by a 15-bit integer that is converted 43 * to and from a linear magnitude using the transformation: 44 * 45 * L = 2^( (Le+.5)/256 - 64 ) # real from 15-bit 46 * 47 * Le = floor( 256*(log2(L) + 64) ) # 15-bit from real 48 * 49 * The actual conversion to world luminance units in candelas per sq. meter 50 * requires an additional multiplier, which is stored in the TIFFTAG_STONITS. 51 * This value is usually set such that a reasonable exposure comes from 52 * clamping decoded luminances above 1 to 1 in the displayed image. 53 * 54 * The 16-bit values for u and v may be converted to real values by dividing 55 * each by 32768. (This allows for negative values, which aren't useful as 56 * far as we know, but are left in case of future improvements in human 57 * color vision.) 58 * 59 * Conversion from (u,v), which is actually the CIE (u',v') system for 60 * you color scientists, is accomplished by the following transformation: 61 * 62 * u = 4*x / (-2*x + 12*y + 3) 63 * v = 9*y / (-2*x + 12*y + 3) 64 * 65 * x = 9*u / (6*u - 16*v + 12) 66 * y = 4*v / (6*u - 16*v + 12) 67 * 68 * This process is greatly simplified by passing 32-bit IEEE floats 69 * for each of three CIE XYZ coordinates. The codec then takes care 70 * of conversion to and from LogLuv, though the application is still 71 * responsible for interpreting the TIFFTAG_STONITS calibration factor. 72 * 73 * By definition, a CIE XYZ vector of [1 1 1] corresponds to a neutral white 74 * point of (x,y)=(1/3,1/3). However, most color systems assume some other 75 * white point, such as D65, and an absolute color conversion to XYZ then 76 * to another color space with a different white point may introduce an 77 * unwanted color cast to the image. It is often desirable, therefore, to 78 * perform a white point conversion that maps the input white to [1 1 1] 79 * in XYZ, then record the original white point using the TIFFTAG_WHITEPOINT 80 * tag value. A decoder that demands absolute color calibration may use 81 * this white point tag to get back the original colors, but usually it 82 * will be ignored and the new white point will be used instead that 83 * matches the output color space. 84 * 85 * Pixel information is compressed into one of two basic encodings, depending 86 * on the setting of the compression tag, which is one of COMPRESSION_SGILOG 87 * or COMPRESSION_SGILOG24. For COMPRESSION_SGILOG, greyscale data is 88 * stored as: 89 * 90 * 1 15 91 * |-+---------------| 92 * 93 * COMPRESSION_SGILOG color data is stored as: 94 * 95 * 1 15 8 8 96 * |-+---------------|--------+--------| 97 * S Le ue ve 98 * 99 * For the 24-bit COMPRESSION_SGILOG24 color format, the data is stored as: 100 * 101 * 10 14 102 * |----------|--------------| 103 * Le' Ce 104 * 105 * There is no sign bit in the 24-bit case, and the (u,v) chromaticity is 106 * encoded as an index for optimal color resolution. The 10 log bits are 107 * defined by the following conversions: 108 * 109 * L = 2^((Le'+.5)/64 - 12) # real from 10-bit 110 * 111 * Le' = floor( 64*(log2(L) + 12) ) # 10-bit from real 112 * 113 * The 10 bits of the smaller format may be converted into the 15 bits of 114 * the larger format by multiplying by 4 and adding 13314. Obviously, 115 * a smaller range of magnitudes is covered (about 5 orders of magnitude 116 * instead of 38), and the lack of a sign bit means that negative luminances 117 * are not allowed. (Well, they aren't allowed in the real world, either, 118 * but they are useful for certain types of image processing.) 119 * 120 * The desired user format is controlled by the setting the internal 121 * pseudo tag TIFFTAG_SGILOGDATAFMT to one of: 122 * SGILOGDATAFMT_FLOAT = IEEE 32-bit float XYZ values 123 * SGILOGDATAFMT_16BIT = 16-bit integer encodings of logL, u and v 124 * Raw data i/o is also possible using: 125 * SGILOGDATAFMT_RAW = 32-bit unsigned integer with encoded pixel 126 * In addition, the following decoding is provided for ease of display: 127 * SGILOGDATAFMT_8BIT = 8-bit default RGB gamma-corrected values 128 * 129 * For grayscale images, we provide the following data formats: 130 * SGILOGDATAFMT_FLOAT = IEEE 32-bit float Y values 131 * SGILOGDATAFMT_16BIT = 16-bit integer w/ encoded luminance 132 * SGILOGDATAFMT_8BIT = 8-bit gray monitor values 133 * 134 * Note that the COMPRESSION_SGILOG applies a simple run-length encoding 135 * scheme by separating the logL, u and v bytes for each row and applying 136 * a PackBits type of compression. Since the 24-bit encoding is not 137 * adaptive, the 32-bit color format takes less space in many cases. 138 * 139 * Further control is provided over the conversion from higher-resolution 140 * formats to final encoded values through the pseudo tag 141 * TIFFTAG_SGILOGENCODE: 142 * SGILOGENCODE_NODITHER = do not dither encoded values 143 * SGILOGENCODE_RANDITHER = apply random dithering during encoding 144 * 145 * The default value of this tag is SGILOGENCODE_NODITHER for 146 * COMPRESSION_SGILOG to maximize run-length encoding and 147 * SGILOGENCODE_RANDITHER for COMPRESSION_SGILOG24 to turn 148 * quantization errors into noise. 149 */ 150 151 #include <stdio.h> 152 #include <stdlib.h> 153 #include <math.h> 154 155 /* 156 * State block for each open TIFF 157 * file using LogLuv compression/decompression. 158 */ 159 typedef struct logLuvState LogLuvState; 160 161 struct logLuvState { 162 int encoder_state; /* 1 if encoder correctly initialized */ 163 int user_datafmt; /* user data format */ 164 int encode_meth; /* encoding method */ 165 int pixel_size; /* bytes per pixel */ 166 167 uint8* tbuf; /* translation buffer */ 168 tmsize_t tbuflen; /* buffer length */ 169 void (*tfunc)(LogLuvState*, uint8*, tmsize_t); 170 171 TIFFVSetMethod vgetparent; /* super-class method */ 172 TIFFVSetMethod vsetparent; /* super-class method */ 173 }; 174 175 #define DecoderState(tif) ((LogLuvState*) (tif)->tif_data) 176 #define EncoderState(tif) ((LogLuvState*) (tif)->tif_data) 177 178 #define SGILOGDATAFMT_UNKNOWN -1 179 180 #define MINRUN 4 /* minimum run length */ 181 182 /* 183 * Decode a string of 16-bit gray pixels. 184 */ 185 static int 186 LogL16Decode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) 187 { 188 static const char module[] = "LogL16Decode"; 189 LogLuvState* sp = DecoderState(tif); 190 int shft; 191 tmsize_t i; 192 tmsize_t npixels; 193 unsigned char* bp; 194 int16* tp; 195 int16 b; 196 tmsize_t cc; 197 int rc; 198 199 assert(s == 0); 200 assert(sp != NULL); 201 202 npixels = occ / sp->pixel_size; 203 204 if (sp->user_datafmt == SGILOGDATAFMT_16BIT) 205 tp = (int16*) op; 206 else { 207 if(sp->tbuflen < npixels) { 208 TIFFErrorExt(tif->tif_clientdata, module, 209 "Translation buffer too short"); 210 return (0); 211 } 212 tp = (int16*) sp->tbuf; 213 } 214 _TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0])); 215 216 bp = (unsigned char*) tif->tif_rawcp; 217 cc = tif->tif_rawcc; 218 /* get each byte string */ 219 for (shft = 2*8; (shft -= 8) >= 0; ) { 220 for (i = 0; i < npixels && cc > 0; ) { 221 if (*bp >= 128) { /* run */ 222 if( cc < 2 ) 223 break; 224 rc = *bp++ + (2-128); 225 b = (int16)(*bp++ << shft); 226 cc -= 2; 227 while (rc-- && i < npixels) 228 tp[i++] |= b; 229 } else { /* non-run */ 230 rc = *bp++; /* nul is noop */ 231 while (--cc && rc-- && i < npixels) 232 tp[i++] |= (int16)*bp++ << shft; 233 } 234 } 235 if (i != npixels) { 236 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) 237 TIFFErrorExt(tif->tif_clientdata, module, 238 "Not enough data at row %lu (short %I64d pixels)", 239 (unsigned long) tif->tif_row, 240 (unsigned __int64) (npixels - i)); 241 #else 242 TIFFErrorExt(tif->tif_clientdata, module, 243 "Not enough data at row %lu (short %llu pixels)", 244 (unsigned long) tif->tif_row, 245 (unsigned long long) (npixels - i)); 246 #endif 247 tif->tif_rawcp = (uint8*) bp; 248 tif->tif_rawcc = cc; 249 return (0); 250 } 251 } 252 (*sp->tfunc)(sp, op, npixels); 253 tif->tif_rawcp = (uint8*) bp; 254 tif->tif_rawcc = cc; 255 return (1); 256 } 257 258 /* 259 * Decode a string of 24-bit pixels. 260 */ 261 static int 262 LogLuvDecode24(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) 263 { 264 static const char module[] = "LogLuvDecode24"; 265 LogLuvState* sp = DecoderState(tif); 266 tmsize_t cc; 267 tmsize_t i; 268 tmsize_t npixels; 269 unsigned char* bp; 270 uint32* tp; 271 272 assert(s == 0); 273 assert(sp != NULL); 274 275 npixels = occ / sp->pixel_size; 276 277 if (sp->user_datafmt == SGILOGDATAFMT_RAW) 278 tp = (uint32 *)op; 279 else { 280 if(sp->tbuflen < npixels) { 281 TIFFErrorExt(tif->tif_clientdata, module, 282 "Translation buffer too short"); 283 return (0); 284 } 285 tp = (uint32 *) sp->tbuf; 286 } 287 /* copy to array of uint32 */ 288 bp = (unsigned char*) tif->tif_rawcp; 289 cc = tif->tif_rawcc; 290 for (i = 0; i < npixels && cc >= 3; i++) { 291 tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2]; 292 bp += 3; 293 cc -= 3; 294 } 295 tif->tif_rawcp = (uint8*) bp; 296 tif->tif_rawcc = cc; 297 if (i != npixels) { 298 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) 299 TIFFErrorExt(tif->tif_clientdata, module, 300 "Not enough data at row %lu (short %I64d pixels)", 301 (unsigned long) tif->tif_row, 302 (unsigned __int64) (npixels - i)); 303 #else 304 TIFFErrorExt(tif->tif_clientdata, module, 305 "Not enough data at row %lu (short %llu pixels)", 306 (unsigned long) tif->tif_row, 307 (unsigned long long) (npixels - i)); 308 #endif 309 return (0); 310 } 311 (*sp->tfunc)(sp, op, npixels); 312 return (1); 313 } 314 315 /* 316 * Decode a string of 32-bit pixels. 317 */ 318 static int 319 LogLuvDecode32(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) 320 { 321 static const char module[] = "LogLuvDecode32"; 322 LogLuvState* sp; 323 int shft; 324 tmsize_t i; 325 tmsize_t npixels; 326 unsigned char* bp; 327 uint32* tp; 328 uint32 b; 329 tmsize_t cc; 330 int rc; 331 332 assert(s == 0); 333 sp = DecoderState(tif); 334 assert(sp != NULL); 335 336 npixels = occ / sp->pixel_size; 337 338 if (sp->user_datafmt == SGILOGDATAFMT_RAW) 339 tp = (uint32*) op; 340 else { 341 if(sp->tbuflen < npixels) { 342 TIFFErrorExt(tif->tif_clientdata, module, 343 "Translation buffer too short"); 344 return (0); 345 } 346 tp = (uint32*) sp->tbuf; 347 } 348 _TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0])); 349 350 bp = (unsigned char*) tif->tif_rawcp; 351 cc = tif->tif_rawcc; 352 /* get each byte string */ 353 for (shft = 4*8; (shft -= 8) >= 0; ) { 354 for (i = 0; i < npixels && cc > 0; ) { 355 if (*bp >= 128) { /* run */ 356 if( cc < 2 ) 357 break; 358 rc = *bp++ + (2-128); 359 b = (uint32)*bp++ << shft; 360 cc -= 2; 361 while (rc-- && i < npixels) 362 tp[i++] |= b; 363 } else { /* non-run */ 364 rc = *bp++; /* nul is noop */ 365 while (--cc && rc-- && i < npixels) 366 tp[i++] |= (uint32)*bp++ << shft; 367 } 368 } 369 if (i != npixels) { 370 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) 371 TIFFErrorExt(tif->tif_clientdata, module, 372 "Not enough data at row %lu (short %I64d pixels)", 373 (unsigned long) tif->tif_row, 374 (unsigned __int64) (npixels - i)); 375 #else 376 TIFFErrorExt(tif->tif_clientdata, module, 377 "Not enough data at row %lu (short %llu pixels)", 378 (unsigned long) tif->tif_row, 379 (unsigned long long) (npixels - i)); 380 #endif 381 tif->tif_rawcp = (uint8*) bp; 382 tif->tif_rawcc = cc; 383 return (0); 384 } 385 } 386 (*sp->tfunc)(sp, op, npixels); 387 tif->tif_rawcp = (uint8*) bp; 388 tif->tif_rawcc = cc; 389 return (1); 390 } 391 392 /* 393 * Decode a strip of pixels. We break it into rows to 394 * maintain synchrony with the encode algorithm, which 395 * is row by row. 396 */ 397 static int 398 LogLuvDecodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) 399 { 400 tmsize_t rowlen = TIFFScanlineSize(tif); 401 402 if (rowlen == 0) 403 return 0; 404 405 assert(cc%rowlen == 0); 406 while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) { 407 bp += rowlen; 408 cc -= rowlen; 409 } 410 return (cc == 0); 411 } 412 413 /* 414 * Decode a tile of pixels. We break it into rows to 415 * maintain synchrony with the encode algorithm, which 416 * is row by row. 417 */ 418 static int 419 LogLuvDecodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) 420 { 421 tmsize_t rowlen = TIFFTileRowSize(tif); 422 423 if (rowlen == 0) 424 return 0; 425 426 assert(cc%rowlen == 0); 427 while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) { 428 bp += rowlen; 429 cc -= rowlen; 430 } 431 return (cc == 0); 432 } 433 434 /* 435 * Encode a row of 16-bit pixels. 436 */ 437 static int 438 LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) 439 { 440 static const char module[] = "LogL16Encode"; 441 LogLuvState* sp = EncoderState(tif); 442 int shft; 443 tmsize_t i; 444 tmsize_t j; 445 tmsize_t npixels; 446 uint8* op; 447 int16* tp; 448 int16 b; 449 tmsize_t occ; 450 int rc=0, mask; 451 tmsize_t beg; 452 453 assert(s == 0); 454 assert(sp != NULL); 455 npixels = cc / sp->pixel_size; 456 457 if (sp->user_datafmt == SGILOGDATAFMT_16BIT) 458 tp = (int16*) bp; 459 else { 460 tp = (int16*) sp->tbuf; 461 if(sp->tbuflen < npixels) { 462 TIFFErrorExt(tif->tif_clientdata, module, 463 "Translation buffer too short"); 464 return (0); 465 } 466 (*sp->tfunc)(sp, bp, npixels); 467 } 468 /* compress each byte string */ 469 op = tif->tif_rawcp; 470 occ = tif->tif_rawdatasize - tif->tif_rawcc; 471 for (shft = 2*8; (shft -= 8) >= 0; ) 472 for (i = 0; i < npixels; i += rc) { 473 if (occ < 4) { 474 tif->tif_rawcp = op; 475 tif->tif_rawcc = tif->tif_rawdatasize - occ; 476 if (!TIFFFlushData1(tif)) 477 return (0); 478 op = tif->tif_rawcp; 479 occ = tif->tif_rawdatasize - tif->tif_rawcc; 480 } 481 mask = 0xff << shft; /* find next run */ 482 for (beg = i; beg < npixels; beg += rc) { 483 b = (int16) (tp[beg] & mask); 484 rc = 1; 485 while (rc < 127+2 && beg+rc < npixels && 486 (tp[beg+rc] & mask) == b) 487 rc++; 488 if (rc >= MINRUN) 489 break; /* long enough */ 490 } 491 if (beg-i > 1 && beg-i < MINRUN) { 492 b = (int16) (tp[i] & mask);/*check short run */ 493 j = i+1; 494 while ((tp[j++] & mask) == b) 495 if (j == beg) { 496 *op++ = (uint8)(128-2+j-i); 497 *op++ = (uint8)(b >> shft); 498 occ -= 2; 499 i = beg; 500 break; 501 } 502 } 503 while (i < beg) { /* write out non-run */ 504 if ((j = beg-i) > 127) j = 127; 505 if (occ < j+3) { 506 tif->tif_rawcp = op; 507 tif->tif_rawcc = tif->tif_rawdatasize - occ; 508 if (!TIFFFlushData1(tif)) 509 return (0); 510 op = tif->tif_rawcp; 511 occ = tif->tif_rawdatasize - tif->tif_rawcc; 512 } 513 *op++ = (uint8) j; occ--; 514 while (j--) { 515 *op++ = (uint8) (tp[i++] >> shft & 0xff); 516 occ--; 517 } 518 } 519 if (rc >= MINRUN) { /* write out run */ 520 *op++ = (uint8) (128-2+rc); 521 *op++ = (uint8) (tp[beg] >> shft & 0xff); 522 occ -= 2; 523 } else 524 rc = 0; 525 } 526 tif->tif_rawcp = op; 527 tif->tif_rawcc = tif->tif_rawdatasize - occ; 528 529 return (1); 530 } 531 532 /* 533 * Encode a row of 24-bit pixels. 534 */ 535 static int 536 LogLuvEncode24(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) 537 { 538 static const char module[] = "LogLuvEncode24"; 539 LogLuvState* sp = EncoderState(tif); 540 tmsize_t i; 541 tmsize_t npixels; 542 tmsize_t occ; 543 uint8* op; 544 uint32* tp; 545 546 assert(s == 0); 547 assert(sp != NULL); 548 npixels = cc / sp->pixel_size; 549 550 if (sp->user_datafmt == SGILOGDATAFMT_RAW) 551 tp = (uint32*) bp; 552 else { 553 tp = (uint32*) sp->tbuf; 554 if(sp->tbuflen < npixels) { 555 TIFFErrorExt(tif->tif_clientdata, module, 556 "Translation buffer too short"); 557 return (0); 558 } 559 (*sp->tfunc)(sp, bp, npixels); 560 } 561 /* write out encoded pixels */ 562 op = tif->tif_rawcp; 563 occ = tif->tif_rawdatasize - tif->tif_rawcc; 564 for (i = npixels; i--; ) { 565 if (occ < 3) { 566 tif->tif_rawcp = op; 567 tif->tif_rawcc = tif->tif_rawdatasize - occ; 568 if (!TIFFFlushData1(tif)) 569 return (0); 570 op = tif->tif_rawcp; 571 occ = tif->tif_rawdatasize - tif->tif_rawcc; 572 } 573 *op++ = (uint8)(*tp >> 16); 574 *op++ = (uint8)(*tp >> 8 & 0xff); 575 *op++ = (uint8)(*tp++ & 0xff); 576 occ -= 3; 577 } 578 tif->tif_rawcp = op; 579 tif->tif_rawcc = tif->tif_rawdatasize - occ; 580 581 return (1); 582 } 583 584 /* 585 * Encode a row of 32-bit pixels. 586 */ 587 static int 588 LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) 589 { 590 static const char module[] = "LogLuvEncode32"; 591 LogLuvState* sp = EncoderState(tif); 592 int shft; 593 tmsize_t i; 594 tmsize_t j; 595 tmsize_t npixels; 596 uint8* op; 597 uint32* tp; 598 uint32 b; 599 tmsize_t occ; 600 int rc=0, mask; 601 tmsize_t beg; 602 603 assert(s == 0); 604 assert(sp != NULL); 605 606 npixels = cc / sp->pixel_size; 607 608 if (sp->user_datafmt == SGILOGDATAFMT_RAW) 609 tp = (uint32*) bp; 610 else { 611 tp = (uint32*) sp->tbuf; 612 if(sp->tbuflen < npixels) { 613 TIFFErrorExt(tif->tif_clientdata, module, 614 "Translation buffer too short"); 615 return (0); 616 } 617 (*sp->tfunc)(sp, bp, npixels); 618 } 619 /* compress each byte string */ 620 op = tif->tif_rawcp; 621 occ = tif->tif_rawdatasize - tif->tif_rawcc; 622 for (shft = 4*8; (shft -= 8) >= 0; ) 623 for (i = 0; i < npixels; i += rc) { 624 if (occ < 4) { 625 tif->tif_rawcp = op; 626 tif->tif_rawcc = tif->tif_rawdatasize - occ; 627 if (!TIFFFlushData1(tif)) 628 return (0); 629 op = tif->tif_rawcp; 630 occ = tif->tif_rawdatasize - tif->tif_rawcc; 631 } 632 mask = 0xff << shft; /* find next run */ 633 for (beg = i; beg < npixels; beg += rc) { 634 b = tp[beg] & mask; 635 rc = 1; 636 while (rc < 127+2 && beg+rc < npixels && 637 (tp[beg+rc] & mask) == b) 638 rc++; 639 if (rc >= MINRUN) 640 break; /* long enough */ 641 } 642 if (beg-i > 1 && beg-i < MINRUN) { 643 b = tp[i] & mask; /* check short run */ 644 j = i+1; 645 while ((tp[j++] & mask) == b) 646 if (j == beg) { 647 *op++ = (uint8)(128-2+j-i); 648 *op++ = (uint8)(b >> shft); 649 occ -= 2; 650 i = beg; 651 break; 652 } 653 } 654 while (i < beg) { /* write out non-run */ 655 if ((j = beg-i) > 127) j = 127; 656 if (occ < j+3) { 657 tif->tif_rawcp = op; 658 tif->tif_rawcc = tif->tif_rawdatasize - occ; 659 if (!TIFFFlushData1(tif)) 660 return (0); 661 op = tif->tif_rawcp; 662 occ = tif->tif_rawdatasize - tif->tif_rawcc; 663 } 664 *op++ = (uint8) j; occ--; 665 while (j--) { 666 *op++ = (uint8)(tp[i++] >> shft & 0xff); 667 occ--; 668 } 669 } 670 if (rc >= MINRUN) { /* write out run */ 671 *op++ = (uint8) (128-2+rc); 672 *op++ = (uint8)(tp[beg] >> shft & 0xff); 673 occ -= 2; 674 } else 675 rc = 0; 676 } 677 tif->tif_rawcp = op; 678 tif->tif_rawcc = tif->tif_rawdatasize - occ; 679 680 return (1); 681 } 682 683 /* 684 * Encode a strip of pixels. We break it into rows to 685 * avoid encoding runs across row boundaries. 686 */ 687 static int 688 LogLuvEncodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) 689 { 690 tmsize_t rowlen = TIFFScanlineSize(tif); 691 692 if (rowlen == 0) 693 return 0; 694 695 assert(cc%rowlen == 0); 696 while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) { 697 bp += rowlen; 698 cc -= rowlen; 699 } 700 return (cc == 0); 701 } 702 703 /* 704 * Encode a tile of pixels. We break it into rows to 705 * avoid encoding runs across row boundaries. 706 */ 707 static int 708 LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) 709 { 710 tmsize_t rowlen = TIFFTileRowSize(tif); 711 712 if (rowlen == 0) 713 return 0; 714 715 assert(cc%rowlen == 0); 716 while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) { 717 bp += rowlen; 718 cc -= rowlen; 719 } 720 return (cc == 0); 721 } 722 723 /* 724 * Encode/Decode functions for converting to and from user formats. 725 */ 726 727 #include "uvcode.h" 728 729 #ifndef UVSCALE 730 #define U_NEU 0.210526316 731 #define V_NEU 0.473684211 732 #define UVSCALE 410. 733 #endif 734 735 #ifndef M_LN2 736 #define M_LN2 0.69314718055994530942 737 #endif 738 #ifndef M_PI 739 #define M_PI 3.14159265358979323846 740 #endif 741 #undef log2 /* Conflict with C'99 function */ 742 #define log2(x) ((1./M_LN2)*log(x)) 743 #undef exp2 /* Conflict with C'99 function */ 744 #define exp2(x) exp(M_LN2*(x)) 745 746 #define itrunc(x,m) ((m)==SGILOGENCODE_NODITHER ? \ 747 (int)(x) : \ 748 (int)((x) + rand()*(1./RAND_MAX) - .5)) 749 750 #if !LOGLUV_PUBLIC 751 static 752 #endif 753 double 754 LogL16toY(int p16) /* compute luminance from 16-bit LogL */ 755 { 756 int Le = p16 & 0x7fff; 757 double Y; 758 759 if (!Le) 760 return (0.); 761 Y = exp(M_LN2/256.*(Le+.5) - M_LN2*64.); 762 return (!(p16 & 0x8000) ? Y : -Y); 763 } 764 765 #if !LOGLUV_PUBLIC 766 static 767 #endif 768 int 769 LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */ 770 { 771 if (Y >= 1.8371976e19) 772 return (0x7fff); 773 if (Y <= -1.8371976e19) 774 return (0xffff); 775 if (Y > 5.4136769e-20) 776 return itrunc(256.*(log2(Y) + 64.), em); 777 if (Y < -5.4136769e-20) 778 return (~0x7fff | itrunc(256.*(log2(-Y) + 64.), em)); 779 return (0); 780 } 781 782 static void 783 L16toY(LogLuvState* sp, uint8* op, tmsize_t n) 784 { 785 int16* l16 = (int16*) sp->tbuf; 786 float* yp = (float*) op; 787 788 while (n-- > 0) 789 *yp++ = (float)LogL16toY(*l16++); 790 } 791 792 static void 793 L16toGry(LogLuvState* sp, uint8* op, tmsize_t n) 794 { 795 int16* l16 = (int16*) sp->tbuf; 796 uint8* gp = (uint8*) op; 797 798 while (n-- > 0) { 799 double Y = LogL16toY(*l16++); 800 *gp++ = (uint8) ((Y <= 0.) ? 0 : (Y >= 1.) ? 255 : (int)(256.*sqrt(Y))); 801 } 802 } 803 804 static void 805 L16fromY(LogLuvState* sp, uint8* op, tmsize_t n) 806 { 807 int16* l16 = (int16*) sp->tbuf; 808 float* yp = (float*) op; 809 810 while (n-- > 0) 811 *l16++ = (int16) (LogL16fromY(*yp++, sp->encode_meth)); 812 } 813 814 #if !LOGLUV_PUBLIC 815 static 816 #endif 817 void 818 XYZtoRGB24(float xyz[3], uint8 rgb[3]) 819 { 820 double r, g, b; 821 /* assume CCIR-709 primaries */ 822 r = 2.690*xyz[0] + -1.276*xyz[1] + -0.414*xyz[2]; 823 g = -1.022*xyz[0] + 1.978*xyz[1] + 0.044*xyz[2]; 824 b = 0.061*xyz[0] + -0.224*xyz[1] + 1.163*xyz[2]; 825 /* assume 2.0 gamma for speed */ 826 /* could use integer sqrt approx., but this is probably faster */ 827 rgb[0] = (uint8)((r<=0.) ? 0 : (r >= 1.) ? 255 : (int)(256.*sqrt(r))); 828 rgb[1] = (uint8)((g<=0.) ? 0 : (g >= 1.) ? 255 : (int)(256.*sqrt(g))); 829 rgb[2] = (uint8)((b<=0.) ? 0 : (b >= 1.) ? 255 : (int)(256.*sqrt(b))); 830 } 831 832 #if !LOGLUV_PUBLIC 833 static 834 #endif 835 double 836 LogL10toY(int p10) /* compute luminance from 10-bit LogL */ 837 { 838 if (p10 == 0) 839 return (0.); 840 return (exp(M_LN2/64.*(p10+.5) - M_LN2*12.)); 841 } 842 843 #if !LOGLUV_PUBLIC 844 static 845 #endif 846 int 847 LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */ 848 { 849 if (Y >= 15.742) 850 return (0x3ff); 851 else if (Y <= .00024283) 852 return (0); 853 else 854 return itrunc(64.*(log2(Y) + 12.), em); 855 } 856 857 #define NANGLES 100 858 #define uv2ang(u, v) ( (NANGLES*.499999999/M_PI) \ 859 * atan2((v)-V_NEU,(u)-U_NEU) + .5*NANGLES ) 860 861 static int 862 oog_encode(double u, double v) /* encode out-of-gamut chroma */ 863 { 864 static int oog_table[NANGLES]; 865 static int initialized = 0; 866 register int i; 867 868 if (!initialized) { /* set up perimeter table */ 869 double eps[NANGLES], ua, va, ang, epsa; 870 int ui, vi, ustep; 871 for (i = NANGLES; i--; ) 872 eps[i] = 2.; 873 for (vi = UV_NVS; vi--; ) { 874 va = UV_VSTART + (vi+.5)*UV_SQSIZ; 875 ustep = uv_row[vi].nus-1; 876 if (vi == UV_NVS-1 || vi == 0 || ustep <= 0) 877 ustep = 1; 878 for (ui = uv_row[vi].nus-1; ui >= 0; ui -= ustep) { 879 ua = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ; 880 ang = uv2ang(ua, va); 881 i = (int) ang; 882 epsa = fabs(ang - (i+.5)); 883 if (epsa < eps[i]) { 884 oog_table[i] = uv_row[vi].ncum + ui; 885 eps[i] = epsa; 886 } 887 } 888 } 889 for (i = NANGLES; i--; ) /* fill any holes */ 890 if (eps[i] > 1.5) { 891 int i1, i2; 892 for (i1 = 1; i1 < NANGLES/2; i1++) 893 if (eps[(i+i1)%NANGLES] < 1.5) 894 break; 895 for (i2 = 1; i2 < NANGLES/2; i2++) 896 if (eps[(i+NANGLES-i2)%NANGLES] < 1.5) 897 break; 898 if (i1 < i2) 899 oog_table[i] = 900 oog_table[(i+i1)%NANGLES]; 901 else 902 oog_table[i] = 903 oog_table[(i+NANGLES-i2)%NANGLES]; 904 } 905 initialized = 1; 906 } 907 i = (int) uv2ang(u, v); /* look up hue angle */ 908 return (oog_table[i]); 909 } 910 911 #undef uv2ang 912 #undef NANGLES 913 914 #if !LOGLUV_PUBLIC 915 static 916 #endif 917 int 918 uv_encode(double u, double v, int em) /* encode (u',v') coordinates */ 919 { 920 register int vi, ui; 921 922 if (v < UV_VSTART) 923 return oog_encode(u, v); 924 vi = itrunc((v - UV_VSTART)*(1./UV_SQSIZ), em); 925 if (vi >= UV_NVS) 926 return oog_encode(u, v); 927 if (u < uv_row[vi].ustart) 928 return oog_encode(u, v); 929 ui = itrunc((u - uv_row[vi].ustart)*(1./UV_SQSIZ), em); 930 if (ui >= uv_row[vi].nus) 931 return oog_encode(u, v); 932 933 return (uv_row[vi].ncum + ui); 934 } 935 936 #if !LOGLUV_PUBLIC 937 static 938 #endif 939 int 940 uv_decode(double *up, double *vp, int c) /* decode (u',v') index */ 941 { 942 int upper, lower; 943 register int ui, vi; 944 945 if (c < 0 || c >= UV_NDIVS) 946 return (-1); 947 lower = 0; /* binary search */ 948 upper = UV_NVS; 949 while (upper - lower > 1) { 950 vi = (lower + upper) >> 1; 951 ui = c - uv_row[vi].ncum; 952 if (ui > 0) 953 lower = vi; 954 else if (ui < 0) 955 upper = vi; 956 else { 957 lower = vi; 958 break; 959 } 960 } 961 vi = lower; 962 ui = c - uv_row[vi].ncum; 963 *up = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ; 964 *vp = UV_VSTART + (vi+.5)*UV_SQSIZ; 965 return (0); 966 } 967 968 #if !LOGLUV_PUBLIC 969 static 970 #endif 971 void 972 LogLuv24toXYZ(uint32 p, float XYZ[3]) 973 { 974 int Ce; 975 double L, u, v, s, x, y; 976 /* decode luminance */ 977 L = LogL10toY(p>>14 & 0x3ff); 978 if (L <= 0.) { 979 XYZ[0] = XYZ[1] = XYZ[2] = 0.; 980 return; 981 } 982 /* decode color */ 983 Ce = p & 0x3fff; 984 if (uv_decode(&u, &v, Ce) < 0) { 985 u = U_NEU; v = V_NEU; 986 } 987 s = 1./(6.*u - 16.*v + 12.); 988 x = 9.*u * s; 989 y = 4.*v * s; 990 /* convert to XYZ */ 991 XYZ[0] = (float)(x/y * L); 992 XYZ[1] = (float)L; 993 XYZ[2] = (float)((1.-x-y)/y * L); 994 } 995 996 #if !LOGLUV_PUBLIC 997 static 998 #endif 999 uint32 1000 LogLuv24fromXYZ(float XYZ[3], int em) 1001 { 1002 int Le, Ce; 1003 double u, v, s; 1004 /* encode luminance */ 1005 Le = LogL10fromY(XYZ[1], em); 1006 /* encode color */ 1007 s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2]; 1008 if (!Le || s <= 0.) { 1009 u = U_NEU; 1010 v = V_NEU; 1011 } else { 1012 u = 4.*XYZ[0] / s; 1013 v = 9.*XYZ[1] / s; 1014 } 1015 Ce = uv_encode(u, v, em); 1016 if (Ce < 0) /* never happens */ 1017 Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER); 1018 /* combine encodings */ 1019 return (Le << 14 | Ce); 1020 } 1021 1022 static void 1023 Luv24toXYZ(LogLuvState* sp, uint8* op, tmsize_t n) 1024 { 1025 uint32* luv = (uint32*) sp->tbuf; 1026 float* xyz = (float*) op; 1027 1028 while (n-- > 0) { 1029 LogLuv24toXYZ(*luv, xyz); 1030 xyz += 3; 1031 luv++; 1032 } 1033 } 1034 1035 static void 1036 Luv24toLuv48(LogLuvState* sp, uint8* op, tmsize_t n) 1037 { 1038 uint32* luv = (uint32*) sp->tbuf; 1039 int16* luv3 = (int16*) op; 1040 1041 while (n-- > 0) { 1042 double u, v; 1043 1044 *luv3++ = (int16)((*luv >> 12 & 0xffd) + 13314); 1045 if (uv_decode(&u, &v, *luv&0x3fff) < 0) { 1046 u = U_NEU; 1047 v = V_NEU; 1048 } 1049 *luv3++ = (int16)(u * (1L<<15)); 1050 *luv3++ = (int16)(v * (1L<<15)); 1051 luv++; 1052 } 1053 } 1054 1055 static void 1056 Luv24toRGB(LogLuvState* sp, uint8* op, tmsize_t n) 1057 { 1058 uint32* luv = (uint32*) sp->tbuf; 1059 uint8* rgb = (uint8*) op; 1060 1061 while (n-- > 0) { 1062 float xyz[3]; 1063 1064 LogLuv24toXYZ(*luv++, xyz); 1065 XYZtoRGB24(xyz, rgb); 1066 rgb += 3; 1067 } 1068 } 1069 1070 static void 1071 Luv24fromXYZ(LogLuvState* sp, uint8* op, tmsize_t n) 1072 { 1073 uint32* luv = (uint32*) sp->tbuf; 1074 float* xyz = (float*) op; 1075 1076 while (n-- > 0) { 1077 *luv++ = LogLuv24fromXYZ(xyz, sp->encode_meth); 1078 xyz += 3; 1079 } 1080 } 1081 1082 static void 1083 Luv24fromLuv48(LogLuvState* sp, uint8* op, tmsize_t n) 1084 { 1085 uint32* luv = (uint32*) sp->tbuf; 1086 int16* luv3 = (int16*) op; 1087 1088 while (n-- > 0) { 1089 int Le, Ce; 1090 1091 if (luv3[0] <= 0) 1092 Le = 0; 1093 else if (luv3[0] >= (1<<12)+3314) 1094 Le = (1<<10) - 1; 1095 else if (sp->encode_meth == SGILOGENCODE_NODITHER) 1096 Le = (luv3[0]-3314) >> 2; 1097 else 1098 Le = itrunc(.25*(luv3[0]-3314.), sp->encode_meth); 1099 1100 Ce = uv_encode((luv3[1]+.5)/(1<<15), (luv3[2]+.5)/(1<<15), 1101 sp->encode_meth); 1102 if (Ce < 0) /* never happens */ 1103 Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER); 1104 *luv++ = (uint32)Le << 14 | Ce; 1105 luv3 += 3; 1106 } 1107 } 1108 1109 #if !LOGLUV_PUBLIC 1110 static 1111 #endif 1112 void 1113 LogLuv32toXYZ(uint32 p, float XYZ[3]) 1114 { 1115 double L, u, v, s, x, y; 1116 /* decode luminance */ 1117 L = LogL16toY((int)p >> 16); 1118 if (L <= 0.) { 1119 XYZ[0] = XYZ[1] = XYZ[2] = 0.; 1120 return; 1121 } 1122 /* decode color */ 1123 u = 1./UVSCALE * ((p>>8 & 0xff) + .5); 1124 v = 1./UVSCALE * ((p & 0xff) + .5); 1125 s = 1./(6.*u - 16.*v + 12.); 1126 x = 9.*u * s; 1127 y = 4.*v * s; 1128 /* convert to XYZ */ 1129 XYZ[0] = (float)(x/y * L); 1130 XYZ[1] = (float)L; 1131 XYZ[2] = (float)((1.-x-y)/y * L); 1132 } 1133 1134 #if !LOGLUV_PUBLIC 1135 static 1136 #endif 1137 uint32 1138 LogLuv32fromXYZ(float XYZ[3], int em) 1139 { 1140 unsigned int Le, ue, ve; 1141 double u, v, s; 1142 /* encode luminance */ 1143 Le = (unsigned int)LogL16fromY(XYZ[1], em); 1144 /* encode color */ 1145 s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2]; 1146 if (!Le || s <= 0.) { 1147 u = U_NEU; 1148 v = V_NEU; 1149 } else { 1150 u = 4.*XYZ[0] / s; 1151 v = 9.*XYZ[1] / s; 1152 } 1153 if (u <= 0.) ue = 0; 1154 else ue = itrunc(UVSCALE*u, em); 1155 if (ue > 255) ue = 255; 1156 if (v <= 0.) ve = 0; 1157 else ve = itrunc(UVSCALE*v, em); 1158 if (ve > 255) ve = 255; 1159 /* combine encodings */ 1160 return (Le << 16 | ue << 8 | ve); 1161 } 1162 1163 static void 1164 Luv32toXYZ(LogLuvState* sp, uint8* op, tmsize_t n) 1165 { 1166 uint32* luv = (uint32*) sp->tbuf; 1167 float* xyz = (float*) op; 1168 1169 while (n-- > 0) { 1170 LogLuv32toXYZ(*luv++, xyz); 1171 xyz += 3; 1172 } 1173 } 1174 1175 static void 1176 Luv32toLuv48(LogLuvState* sp, uint8* op, tmsize_t n) 1177 { 1178 uint32* luv = (uint32*) sp->tbuf; 1179 int16* luv3 = (int16*) op; 1180 1181 while (n-- > 0) { 1182 double u, v; 1183 1184 *luv3++ = (int16)(*luv >> 16); 1185 u = 1./UVSCALE * ((*luv>>8 & 0xff) + .5); 1186 v = 1./UVSCALE * ((*luv & 0xff) + .5); 1187 *luv3++ = (int16)(u * (1L<<15)); 1188 *luv3++ = (int16)(v * (1L<<15)); 1189 luv++; 1190 } 1191 } 1192 1193 static void 1194 Luv32toRGB(LogLuvState* sp, uint8* op, tmsize_t n) 1195 { 1196 uint32* luv = (uint32*) sp->tbuf; 1197 uint8* rgb = (uint8*) op; 1198 1199 while (n-- > 0) { 1200 float xyz[3]; 1201 1202 LogLuv32toXYZ(*luv++, xyz); 1203 XYZtoRGB24(xyz, rgb); 1204 rgb += 3; 1205 } 1206 } 1207 1208 static void 1209 Luv32fromXYZ(LogLuvState* sp, uint8* op, tmsize_t n) 1210 { 1211 uint32* luv = (uint32*) sp->tbuf; 1212 float* xyz = (float*) op; 1213 1214 while (n-- > 0) { 1215 *luv++ = LogLuv32fromXYZ(xyz, sp->encode_meth); 1216 xyz += 3; 1217 } 1218 } 1219 1220 static void 1221 Luv32fromLuv48(LogLuvState* sp, uint8* op, tmsize_t n) 1222 { 1223 uint32* luv = (uint32*) sp->tbuf; 1224 int16* luv3 = (int16*) op; 1225 1226 if (sp->encode_meth == SGILOGENCODE_NODITHER) { 1227 while (n-- > 0) { 1228 *luv++ = (uint32)luv3[0] << 16 | 1229 (luv3[1]*(uint32)(UVSCALE+.5) >> 7 & 0xff00) | 1230 (luv3[2]*(uint32)(UVSCALE+.5) >> 15 & 0xff); 1231 luv3 += 3; 1232 } 1233 return; 1234 } 1235 while (n-- > 0) { 1236 *luv++ = (uint32)luv3[0] << 16 | 1237 (itrunc(luv3[1]*(UVSCALE/(1<<15)), sp->encode_meth) << 8 & 0xff00) | 1238 (itrunc(luv3[2]*(UVSCALE/(1<<15)), sp->encode_meth) & 0xff); 1239 luv3 += 3; 1240 } 1241 } 1242 1243 static void 1244 _logLuvNop(LogLuvState* sp, uint8* op, tmsize_t n) 1245 { 1246 (void) sp; (void) op; (void) n; 1247 } 1248 1249 static int 1250 LogL16GuessDataFmt(TIFFDirectory *td) 1251 { 1252 #define PACK(s,b,f) (((b)<<6)|((s)<<3)|(f)) 1253 switch (PACK(td->td_samplesperpixel, td->td_bitspersample, td->td_sampleformat)) { 1254 case PACK(1, 32, SAMPLEFORMAT_IEEEFP): 1255 return (SGILOGDATAFMT_FLOAT); 1256 case PACK(1, 16, SAMPLEFORMAT_VOID): 1257 case PACK(1, 16, SAMPLEFORMAT_INT): 1258 case PACK(1, 16, SAMPLEFORMAT_UINT): 1259 return (SGILOGDATAFMT_16BIT); 1260 case PACK(1, 8, SAMPLEFORMAT_VOID): 1261 case PACK(1, 8, SAMPLEFORMAT_UINT): 1262 return (SGILOGDATAFMT_8BIT); 1263 } 1264 #undef PACK 1265 return (SGILOGDATAFMT_UNKNOWN); 1266 } 1267 1268 1269 #define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0)) 1270 #define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1) 1271 1272 static tmsize_t 1273 multiply_ms(tmsize_t m1, tmsize_t m2) 1274 { 1275 if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 ) 1276 return 0; 1277 return m1 * m2; 1278 } 1279 1280 static int 1281 LogL16InitState(TIFF* tif) 1282 { 1283 static const char module[] = "LogL16InitState"; 1284 TIFFDirectory *td = &tif->tif_dir; 1285 LogLuvState* sp = DecoderState(tif); 1286 1287 assert(sp != NULL); 1288 assert(td->td_photometric == PHOTOMETRIC_LOGL); 1289 1290 if( td->td_samplesperpixel != 1 ) 1291 { 1292 TIFFErrorExt(tif->tif_clientdata, module, 1293 "Sorry, can not handle LogL image with %s=%d", 1294 "Samples/pixel", td->td_samplesperpixel); 1295 return 0; 1296 } 1297 1298 /* for some reason, we can't do this in TIFFInitLogL16 */ 1299 if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN) 1300 sp->user_datafmt = LogL16GuessDataFmt(td); 1301 switch (sp->user_datafmt) { 1302 case SGILOGDATAFMT_FLOAT: 1303 sp->pixel_size = sizeof (float); 1304 break; 1305 case SGILOGDATAFMT_16BIT: 1306 sp->pixel_size = sizeof (int16); 1307 break; 1308 case SGILOGDATAFMT_8BIT: 1309 sp->pixel_size = sizeof (uint8); 1310 break; 1311 default: 1312 TIFFErrorExt(tif->tif_clientdata, module, 1313 "No support for converting user data format to LogL"); 1314 return (0); 1315 } 1316 if( isTiled(tif) ) 1317 sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); 1318 else if( td->td_rowsperstrip != (uint32)-1 ) 1319 sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); 1320 else 1321 sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength); 1322 if (multiply_ms(sp->tbuflen, sizeof (int16)) == 0 || 1323 (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (int16))) == NULL) { 1324 TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer"); 1325 return (0); 1326 } 1327 return (1); 1328 } 1329 1330 static int 1331 LogLuvGuessDataFmt(TIFFDirectory *td) 1332 { 1333 int guess; 1334 1335 /* 1336 * If the user didn't tell us their datafmt, 1337 * take our best guess from the bitspersample. 1338 */ 1339 #define PACK(a,b) (((a)<<3)|(b)) 1340 switch (PACK(td->td_bitspersample, td->td_sampleformat)) { 1341 case PACK(32, SAMPLEFORMAT_IEEEFP): 1342 guess = SGILOGDATAFMT_FLOAT; 1343 break; 1344 case PACK(32, SAMPLEFORMAT_VOID): 1345 case PACK(32, SAMPLEFORMAT_UINT): 1346 case PACK(32, SAMPLEFORMAT_INT): 1347 guess = SGILOGDATAFMT_RAW; 1348 break; 1349 case PACK(16, SAMPLEFORMAT_VOID): 1350 case PACK(16, SAMPLEFORMAT_INT): 1351 case PACK(16, SAMPLEFORMAT_UINT): 1352 guess = SGILOGDATAFMT_16BIT; 1353 break; 1354 case PACK( 8, SAMPLEFORMAT_VOID): 1355 case PACK( 8, SAMPLEFORMAT_UINT): 1356 guess = SGILOGDATAFMT_8BIT; 1357 break; 1358 default: 1359 guess = SGILOGDATAFMT_UNKNOWN; 1360 break; 1361 #undef PACK 1362 } 1363 /* 1364 * Double-check samples per pixel. 1365 */ 1366 switch (td->td_samplesperpixel) { 1367 case 1: 1368 if (guess != SGILOGDATAFMT_RAW) 1369 guess = SGILOGDATAFMT_UNKNOWN; 1370 break; 1371 case 3: 1372 if (guess == SGILOGDATAFMT_RAW) 1373 guess = SGILOGDATAFMT_UNKNOWN; 1374 break; 1375 default: 1376 guess = SGILOGDATAFMT_UNKNOWN; 1377 break; 1378 } 1379 return (guess); 1380 } 1381 1382 static int 1383 LogLuvInitState(TIFF* tif) 1384 { 1385 static const char module[] = "LogLuvInitState"; 1386 TIFFDirectory* td = &tif->tif_dir; 1387 LogLuvState* sp = DecoderState(tif); 1388 1389 assert(sp != NULL); 1390 assert(td->td_photometric == PHOTOMETRIC_LOGLUV); 1391 1392 /* for some reason, we can't do this in TIFFInitLogLuv */ 1393 if (td->td_planarconfig != PLANARCONFIG_CONTIG) { 1394 TIFFErrorExt(tif->tif_clientdata, module, 1395 "SGILog compression cannot handle non-contiguous data"); 1396 return (0); 1397 } 1398 if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN) 1399 sp->user_datafmt = LogLuvGuessDataFmt(td); 1400 switch (sp->user_datafmt) { 1401 case SGILOGDATAFMT_FLOAT: 1402 sp->pixel_size = 3*sizeof (float); 1403 break; 1404 case SGILOGDATAFMT_16BIT: 1405 sp->pixel_size = 3*sizeof (int16); 1406 break; 1407 case SGILOGDATAFMT_RAW: 1408 sp->pixel_size = sizeof (uint32); 1409 break; 1410 case SGILOGDATAFMT_8BIT: 1411 sp->pixel_size = 3*sizeof (uint8); 1412 break; 1413 default: 1414 TIFFErrorExt(tif->tif_clientdata, module, 1415 "No support for converting user data format to LogLuv"); 1416 return (0); 1417 } 1418 if( isTiled(tif) ) 1419 sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); 1420 else 1421 sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); 1422 if (multiply_ms(sp->tbuflen, sizeof (uint32)) == 0 || 1423 (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (uint32))) == NULL) { 1424 TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer"); 1425 return (0); 1426 } 1427 return (1); 1428 } 1429 1430 static int 1431 LogLuvFixupTags(TIFF* tif) 1432 { 1433 (void) tif; 1434 return (1); 1435 } 1436 1437 static int 1438 LogLuvSetupDecode(TIFF* tif) 1439 { 1440 static const char module[] = "LogLuvSetupDecode"; 1441 LogLuvState* sp = DecoderState(tif); 1442 TIFFDirectory* td = &tif->tif_dir; 1443 1444 tif->tif_postdecode = _TIFFNoPostDecode; 1445 switch (td->td_photometric) { 1446 case PHOTOMETRIC_LOGLUV: 1447 if (!LogLuvInitState(tif)) 1448 break; 1449 if (td->td_compression == COMPRESSION_SGILOG24) { 1450 tif->tif_decoderow = LogLuvDecode24; 1451 switch (sp->user_datafmt) { 1452 case SGILOGDATAFMT_FLOAT: 1453 sp->tfunc = Luv24toXYZ; 1454 break; 1455 case SGILOGDATAFMT_16BIT: 1456 sp->tfunc = Luv24toLuv48; 1457 break; 1458 case SGILOGDATAFMT_8BIT: 1459 sp->tfunc = Luv24toRGB; 1460 break; 1461 } 1462 } else { 1463 tif->tif_decoderow = LogLuvDecode32; 1464 switch (sp->user_datafmt) { 1465 case SGILOGDATAFMT_FLOAT: 1466 sp->tfunc = Luv32toXYZ; 1467 break; 1468 case SGILOGDATAFMT_16BIT: 1469 sp->tfunc = Luv32toLuv48; 1470 break; 1471 case SGILOGDATAFMT_8BIT: 1472 sp->tfunc = Luv32toRGB; 1473 break; 1474 } 1475 } 1476 return (1); 1477 case PHOTOMETRIC_LOGL: 1478 if (!LogL16InitState(tif)) 1479 break; 1480 tif->tif_decoderow = LogL16Decode; 1481 switch (sp->user_datafmt) { 1482 case SGILOGDATAFMT_FLOAT: 1483 sp->tfunc = L16toY; 1484 break; 1485 case SGILOGDATAFMT_8BIT: 1486 sp->tfunc = L16toGry; 1487 break; 1488 } 1489 return (1); 1490 default: 1491 TIFFErrorExt(tif->tif_clientdata, module, 1492 "Inappropriate photometric interpretation %d for SGILog compression; %s", 1493 td->td_photometric, "must be either LogLUV or LogL"); 1494 break; 1495 } 1496 return (0); 1497 } 1498 1499 static int 1500 LogLuvSetupEncode(TIFF* tif) 1501 { 1502 static const char module[] = "LogLuvSetupEncode"; 1503 LogLuvState* sp = EncoderState(tif); 1504 TIFFDirectory* td = &tif->tif_dir; 1505 1506 switch (td->td_photometric) { 1507 case PHOTOMETRIC_LOGLUV: 1508 if (!LogLuvInitState(tif)) 1509 break; 1510 if (td->td_compression == COMPRESSION_SGILOG24) { 1511 tif->tif_encoderow = LogLuvEncode24; 1512 switch (sp->user_datafmt) { 1513 case SGILOGDATAFMT_FLOAT: 1514 sp->tfunc = Luv24fromXYZ; 1515 break; 1516 case SGILOGDATAFMT_16BIT: 1517 sp->tfunc = Luv24fromLuv48; 1518 break; 1519 case SGILOGDATAFMT_RAW: 1520 break; 1521 default: 1522 goto notsupported; 1523 } 1524 } else { 1525 tif->tif_encoderow = LogLuvEncode32; 1526 switch (sp->user_datafmt) { 1527 case SGILOGDATAFMT_FLOAT: 1528 sp->tfunc = Luv32fromXYZ; 1529 break; 1530 case SGILOGDATAFMT_16BIT: 1531 sp->tfunc = Luv32fromLuv48; 1532 break; 1533 case SGILOGDATAFMT_RAW: 1534 break; 1535 default: 1536 goto notsupported; 1537 } 1538 } 1539 break; 1540 case PHOTOMETRIC_LOGL: 1541 if (!LogL16InitState(tif)) 1542 break; 1543 tif->tif_encoderow = LogL16Encode; 1544 switch (sp->user_datafmt) { 1545 case SGILOGDATAFMT_FLOAT: 1546 sp->tfunc = L16fromY; 1547 break; 1548 case SGILOGDATAFMT_16BIT: 1549 break; 1550 default: 1551 goto notsupported; 1552 } 1553 break; 1554 default: 1555 TIFFErrorExt(tif->tif_clientdata, module, 1556 "Inappropriate photometric interpretation %d for SGILog compression; %s", 1557 td->td_photometric, "must be either LogLUV or LogL"); 1558 break; 1559 } 1560 sp->encoder_state = 1; 1561 return (1); 1562 notsupported: 1563 TIFFErrorExt(tif->tif_clientdata, module, 1564 "SGILog compression supported only for %s, or raw data", 1565 td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv"); 1566 return (0); 1567 } 1568 1569 static void 1570 LogLuvClose(TIFF* tif) 1571 { 1572 LogLuvState* sp = (LogLuvState*) tif->tif_data; 1573 TIFFDirectory *td = &tif->tif_dir; 1574 1575 assert(sp != 0); 1576 /* 1577 * For consistency, we always want to write out the same 1578 * bitspersample and sampleformat for our TIFF file, 1579 * regardless of the data format being used by the application. 1580 * Since this routine is called after tags have been set but 1581 * before they have been recorded in the file, we reset them here. 1582 * Note: this is really a nasty approach. See PixarLogClose 1583 */ 1584 if( sp->encoder_state ) 1585 { 1586 /* See PixarLogClose. Might avoid issues with tags whose size depends 1587 * on those below, but not completely sure this is enough. */ 1588 td->td_samplesperpixel = 1589 (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3; 1590 td->td_bitspersample = 16; 1591 td->td_sampleformat = SAMPLEFORMAT_INT; 1592 } 1593 } 1594 1595 static void 1596 LogLuvCleanup(TIFF* tif) 1597 { 1598 LogLuvState* sp = (LogLuvState *)tif->tif_data; 1599 1600 assert(sp != 0); 1601 1602 tif->tif_tagmethods.vgetfield = sp->vgetparent; 1603 tif->tif_tagmethods.vsetfield = sp->vsetparent; 1604 1605 if (sp->tbuf) 1606 _TIFFfree(sp->tbuf); 1607 _TIFFfree(sp); 1608 tif->tif_data = NULL; 1609 1610 _TIFFSetDefaultCompressionState(tif); 1611 } 1612 1613 static int 1614 LogLuvVSetField(TIFF* tif, uint32 tag, va_list ap) 1615 { 1616 static const char module[] = "LogLuvVSetField"; 1617 LogLuvState* sp = DecoderState(tif); 1618 int bps, fmt; 1619 1620 switch (tag) { 1621 case TIFFTAG_SGILOGDATAFMT: 1622 sp->user_datafmt = (int) va_arg(ap, int); 1623 /* 1624 * Tweak the TIFF header so that the rest of libtiff knows what 1625 * size of data will be passed between app and library, and 1626 * assume that the app knows what it is doing and is not 1627 * confused by these header manipulations... 1628 */ 1629 switch (sp->user_datafmt) { 1630 case SGILOGDATAFMT_FLOAT: 1631 bps = 32; 1632 fmt = SAMPLEFORMAT_IEEEFP; 1633 break; 1634 case SGILOGDATAFMT_16BIT: 1635 bps = 16; 1636 fmt = SAMPLEFORMAT_INT; 1637 break; 1638 case SGILOGDATAFMT_RAW: 1639 bps = 32; 1640 fmt = SAMPLEFORMAT_UINT; 1641 TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1); 1642 break; 1643 case SGILOGDATAFMT_8BIT: 1644 bps = 8; 1645 fmt = SAMPLEFORMAT_UINT; 1646 break; 1647 default: 1648 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 1649 "Unknown data format %d for LogLuv compression", 1650 sp->user_datafmt); 1651 return (0); 1652 } 1653 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); 1654 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, fmt); 1655 /* 1656 * Must recalculate sizes should bits/sample change. 1657 */ 1658 tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t) -1; 1659 tif->tif_scanlinesize = TIFFScanlineSize(tif); 1660 return (1); 1661 case TIFFTAG_SGILOGENCODE: 1662 sp->encode_meth = (int) va_arg(ap, int); 1663 if (sp->encode_meth != SGILOGENCODE_NODITHER && 1664 sp->encode_meth != SGILOGENCODE_RANDITHER) { 1665 TIFFErrorExt(tif->tif_clientdata, module, 1666 "Unknown encoding %d for LogLuv compression", 1667 sp->encode_meth); 1668 return (0); 1669 } 1670 return (1); 1671 default: 1672 return (*sp->vsetparent)(tif, tag, ap); 1673 } 1674 } 1675 1676 static int 1677 LogLuvVGetField(TIFF* tif, uint32 tag, va_list ap) 1678 { 1679 LogLuvState *sp = (LogLuvState *)tif->tif_data; 1680 1681 switch (tag) { 1682 case TIFFTAG_SGILOGDATAFMT: 1683 *va_arg(ap, int*) = sp->user_datafmt; 1684 return (1); 1685 default: 1686 return (*sp->vgetparent)(tif, tag, ap); 1687 } 1688 } 1689 1690 static const TIFFField LogLuvFields[] = { 1691 { TIFFTAG_SGILOGDATAFMT, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogDataFmt", NULL}, 1692 { TIFFTAG_SGILOGENCODE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogEncode", NULL} 1693 }; 1694 1695 int 1696 TIFFInitSGILog(TIFF* tif, int scheme) 1697 { 1698 static const char module[] = "TIFFInitSGILog"; 1699 LogLuvState* sp; 1700 1701 assert(scheme == COMPRESSION_SGILOG24 || scheme == COMPRESSION_SGILOG); 1702 1703 /* 1704 * Merge codec-specific tag information. 1705 */ 1706 if (!_TIFFMergeFields(tif, LogLuvFields, 1707 TIFFArrayCount(LogLuvFields))) { 1708 TIFFErrorExt(tif->tif_clientdata, module, 1709 "Merging SGILog codec-specific tags failed"); 1710 return 0; 1711 } 1712 1713 /* 1714 * Allocate state block so tag methods have storage to record values. 1715 */ 1716 tif->tif_data = (uint8*) _TIFFmalloc(sizeof (LogLuvState)); 1717 if (tif->tif_data == NULL) 1718 goto bad; 1719 sp = (LogLuvState*) tif->tif_data; 1720 _TIFFmemset((void*)sp, 0, sizeof (*sp)); 1721 sp->user_datafmt = SGILOGDATAFMT_UNKNOWN; 1722 sp->encode_meth = (scheme == COMPRESSION_SGILOG24) ? 1723 SGILOGENCODE_RANDITHER : SGILOGENCODE_NODITHER; 1724 sp->tfunc = _logLuvNop; 1725 1726 /* 1727 * Install codec methods. 1728 * NB: tif_decoderow & tif_encoderow are filled 1729 * in at setup time. 1730 */ 1731 tif->tif_fixuptags = LogLuvFixupTags; 1732 tif->tif_setupdecode = LogLuvSetupDecode; 1733 tif->tif_decodestrip = LogLuvDecodeStrip; 1734 tif->tif_decodetile = LogLuvDecodeTile; 1735 tif->tif_setupencode = LogLuvSetupEncode; 1736 tif->tif_encodestrip = LogLuvEncodeStrip; 1737 tif->tif_encodetile = LogLuvEncodeTile; 1738 tif->tif_close = LogLuvClose; 1739 tif->tif_cleanup = LogLuvCleanup; 1740 1741 /* 1742 * Override parent get/set field methods. 1743 */ 1744 sp->vgetparent = tif->tif_tagmethods.vgetfield; 1745 tif->tif_tagmethods.vgetfield = LogLuvVGetField; /* hook for codec tags */ 1746 sp->vsetparent = tif->tif_tagmethods.vsetfield; 1747 tif->tif_tagmethods.vsetfield = LogLuvVSetField; /* hook for codec tags */ 1748 1749 return (1); 1750 bad: 1751 TIFFErrorExt(tif->tif_clientdata, module, 1752 "%s: No space for LogLuv state block", tif->tif_name); 1753 return (0); 1754 } 1755 #endif /* LOGLUV_SUPPORT */ 1756 1757 /* vim: set ts=8 sts=8 sw=8 noet: */ 1758 /* 1759 * Local Variables: 1760 * mode: c 1761 * c-basic-offset: 8 1762 * fill-column: 78 1763 * End: 1764 */ 1765