2  * Copyright (c) 1997 Greg Ward Larson 
   3  * Copyright (c) 1997 Silicon Graphics, Inc. 
   5  * Permission to use, copy, modify, distribute, and sell this software and  
   6  * its documentation for any purpose is hereby granted without fee, provided 
   7  * that (i) the above copyright notices and this permission notice appear in 
   8  * all copies of the software and related documentation, and (ii) the names of 
   9  * Sam Leffler, Greg Larson and Silicon Graphics may not be used in any 
  10  * advertising or publicity relating to the software without the specific, 
  11  * prior written permission of Sam Leffler, Greg Larson and Silicon Graphics. 
  13  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,  
  14  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY  
  15  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.   
  17  * IN NO EVENT SHALL SAM LEFFLER, GREG LARSON OR SILICON GRAPHICS BE LIABLE 
  18  * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 
  19  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
  20  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF  
  21  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE  
  30  * LogLuv compression support for high dynamic range images. 
  32  * Contributed by Greg Larson. 
  34  * LogLuv image support uses the TIFF library to store 16 or 10-bit 
  35  * log luminance values with 8 bits each of u and v or a 14-bit index. 
  37  * The codec can take as input and produce as output 32-bit IEEE float values  
  38  * as well as 16-bit integer values.  A 16-bit luminance is interpreted 
  39  * as a sign bit followed by a 15-bit integer that is converted 
  40  * to and from a linear magnitude using the transformation: 
  42  *      L = 2^( (Le+.5)/256 - 64 )              # real from 15-bit 
  44  *      Le = floor( 256*(log2(L) + 64) )        # 15-bit from real 
  46  * The actual conversion to world luminance units in candelas per sq. meter 
  47  * requires an additional multiplier, which is stored in the TIFFTAG_STONITS. 
  48  * This value is usually set such that a reasonable exposure comes from 
  49  * clamping decoded luminances above 1 to 1 in the displayed image. 
  51  * The 16-bit values for u and v may be converted to real values by dividing 
  52  * each by 32768.  (This allows for negative values, which aren't useful as 
  53  * far as we know, but are left in case of future improvements in human 
  56  * Conversion from (u,v), which is actually the CIE (u',v') system for 
  57  * you color scientists, is accomplished by the following transformation: 
  59  *      u = 4*x / (-2*x + 12*y + 3) 
  60  *      v = 9*y / (-2*x + 12*y + 3) 
  62  *      x = 9*u / (6*u - 16*v + 12) 
  63  *      y = 4*v / (6*u - 16*v + 12) 
  65  * This process is greatly simplified by passing 32-bit IEEE floats 
  66  * for each of three CIE XYZ coordinates.  The codec then takes care 
  67  * of conversion to and from LogLuv, though the application is still 
  68  * responsible for interpreting the TIFFTAG_STONITS calibration factor. 
  70  * By definition, a CIE XYZ vector of [1 1 1] corresponds to a neutral white 
  71  * point of (x,y)=(1/3,1/3).  However, most color systems assume some other 
  72  * white point, such as D65, and an absolute color conversion to XYZ then 
  73  * to another color space with a different white point may introduce an 
  74  * unwanted color cast to the image.  It is often desirable, therefore, to 
  75  * perform a white point conversion that maps the input white to [1 1 1] 
  76  * in XYZ, then record the original white point using the TIFFTAG_WHITEPOINT 
  77  * tag value.  A decoder that demands absolute color calibration may use 
  78  * this white point tag to get back the original colors, but usually it 
  79  * will be ignored and the new white point will be used instead that 
  80  * matches the output color space. 
  82  * Pixel information is compressed into one of two basic encodings, depending 
  83  * on the setting of the compression tag, which is one of COMPRESSION_SGILOG 
  84  * or COMPRESSION_SGILOG24.  For COMPRESSION_SGILOG, greyscale data is 
  90  * COMPRESSION_SGILOG color data is stored as: 
  93  *      |-+---------------|--------+--------| 
  96  * For the 24-bit COMPRESSION_SGILOG24 color format, the data is stored as: 
  99  *      |----------|--------------| 
 102  * There is no sign bit in the 24-bit case, and the (u,v) chromaticity is 
 103  * encoded as an index for optimal color resolution.  The 10 log bits are 
 104  * defined by the following conversions: 
 106  *      L = 2^((Le'+.5)/64 - 12)                # real from 10-bit 
 108  *      Le' = floor( 64*(log2(L) + 12) )        # 10-bit from real 
 110  * The 10 bits of the smaller format may be converted into the 15 bits of 
 111  * the larger format by multiplying by 4 and adding 13314.  Obviously, 
 112  * a smaller range of magnitudes is covered (about 5 orders of magnitude 
 113  * instead of 38), and the lack of a sign bit means that negative luminances 
 114  * are not allowed.  (Well, they aren't allowed in the real world, either, 
 115  * but they are useful for certain types of image processing.) 
 117  * The desired user format is controlled by the setting the internal 
 118  * pseudo tag TIFFTAG_SGILOGDATAFMT to one of: 
 119  *  SGILOGDATAFMT_FLOAT       = IEEE 32-bit float XYZ values 
 120  *  SGILOGDATAFMT_16BIT       = 16-bit integer encodings of logL, u and v 
 121  * Raw data i/o is also possible using: 
 122  *  SGILOGDATAFMT_RAW         = 32-bit unsigned integer with encoded pixel 
 123  * In addition, the following decoding is provided for ease of display: 
 124  *  SGILOGDATAFMT_8BIT        = 8-bit default RGB gamma-corrected values 
 126  * For grayscale images, we provide the following data formats: 
 127  *  SGILOGDATAFMT_FLOAT       = IEEE 32-bit float Y values 
 128  *  SGILOGDATAFMT_16BIT       = 16-bit integer w/ encoded luminance 
 129  *  SGILOGDATAFMT_8BIT        = 8-bit gray monitor values 
 131  * Note that the COMPRESSION_SGILOG applies a simple run-length encoding 
 132  * scheme by separating the logL, u and v bytes for each row and applying 
 133  * a PackBits type of compression.  Since the 24-bit encoding is not 
 134  * adaptive, the 32-bit color format takes less space in many cases. 
 136  * Further control is provided over the conversion from higher-resolution 
 137  * formats to final encoded values through the pseudo tag 
 138  * TIFFTAG_SGILOGENCODE: 
 139  *  SGILOGENCODE_NODITHER     = do not dither encoded values 
 140  *  SGILOGENCODE_RANDITHER    = apply random dithering during encoding 
 142  * The default value of this tag is SGILOGENCODE_NODITHER for 
 143  * COMPRESSION_SGILOG to maximize run-length encoding and 
 144  * SGILOGENCODE_RANDITHER for COMPRESSION_SGILOG24 to turn 
 145  * quantization errors into noise. 
 154  * State block for each open TIFF 
 155  * file using LogLuv compression/decompression. 
 157 typedef struct logLuvState LogLuvState
; 
 160         int                     user_datafmt
;   /* user data format */ 
 161         int                     encode_meth
;    /* encoding method */ 
 162         int                     pixel_size
;     /* bytes per pixel */ 
 164         tidata_t
*               tbuf
;           /* translation buffer */ 
 165         int                     tbuflen
;        /* buffer length */ 
 166         void (*tfunc
)(LogLuvState
*, tidata_t
, int); 
 168         TIFFVSetMethod          vgetparent
;     /* super-class method */ 
 169         TIFFVSetMethod          vsetparent
;     /* super-class method */ 
 172 #define DecoderState(tif)       ((LogLuvState*) (tif)->tif_data) 
 173 #define EncoderState(tif)       ((LogLuvState*) (tif)->tif_data) 
 175 #define N(a)   (sizeof(a)/sizeof(a[0])) 
 176 #define SGILOGDATAFMT_UNKNOWN   -1 
 178 #define MINRUN          4       /* minimum run length */ 
 181  * Decode a string of 16-bit gray pixels. 
 184 LogL16Decode(TIFF
* tif
, tidata_t op
, tsize_t occ
, tsample_t s
) 
 186         LogLuvState
* sp 
= DecoderState(tif
); 
 187         int shft
, i
, npixels
; 
 196         npixels 
= occ 
/ sp
->pixel_size
; 
 198         if (sp
->user_datafmt 
== SGILOGDATAFMT_16BIT
) 
 201                 assert(sp
->tbuflen 
>= npixels
); 
 202                 tp 
= (int16
*) sp
->tbuf
; 
 204         _TIFFmemset((tdata_t
) tp
, 0, npixels
*sizeof (tp
[0])); 
 206         bp 
= (u_char
*) tif
->tif_rawcp
; 
 208                                         /* get each byte string */ 
 209         for (shft 
= 2*8; (shft 
-= 8) >= 0; ) { 
 210                 for (i 
= 0; i 
< npixels 
&& cc 
> 0; ) 
 211                         if (*bp 
>= 128) {               /* run */ 
 212                                 rc 
= *bp
++ + (2-128); 
 213                                 b 
= (int16
)(*bp
++ << shft
); 
 215                                 while (rc
-- && i 
< npixels
) 
 217                         } else {                        /* non-run */ 
 218                                 rc 
= *bp
++;             /* nul is noop */ 
 219                                 while (--cc 
&& rc
-- && i 
< npixels
) 
 220                                         tp
[i
++] |= (int16
)*bp
++ << shft
; 
 223                         TIFFError(tif
->tif_name
, 
 224                 "LogL16Decode: Not enough data at row %d (short %d pixels)", 
 225                             tif
->tif_row
, npixels 
- i
); 
 226                         tif
->tif_rawcp 
= (tidata_t
) bp
; 
 231         (*sp
->tfunc
)(sp
, op
, npixels
); 
 232         tif
->tif_rawcp 
= (tidata_t
) bp
; 
 238  * Decode a string of 24-bit pixels. 
 241 LogLuvDecode24(TIFF
* tif
, tidata_t op
, tsize_t occ
, tsample_t s
) 
 243         LogLuvState
* sp 
= DecoderState(tif
); 
 251         npixels 
= occ 
/ sp
->pixel_size
; 
 253         if (sp
->user_datafmt 
== SGILOGDATAFMT_RAW
) 
 256                 assert(sp
->tbuflen 
>= npixels
); 
 257                 tp 
= (uint32 
*) sp
->tbuf
; 
 259                                         /* copy to array of uint32 */ 
 260         bp 
= (u_char
*) tif
->tif_rawcp
; 
 262         for (i 
= 0; i 
< npixels 
&& cc 
> 0; i
++) { 
 263                 tp
[i
] = bp
[0] << 16 | bp
[1] << 8 | bp
[2]; 
 267         tif
->tif_rawcp 
= (tidata_t
) bp
; 
 270                 TIFFError(tif
->tif_name
, 
 271             "LogLuvDecode24: Not enough data at row %d (short %d pixels)", 
 272                     tif
->tif_row
, npixels 
- i
); 
 275         (*sp
->tfunc
)(sp
, op
, npixels
); 
 280  * Decode a string of 32-bit pixels. 
 283 LogLuvDecode32(TIFF
* tif
, tidata_t op
, tsize_t occ
, tsample_t s
) 
 286         int shft
, i
, npixels
; 
 293         sp 
= DecoderState(tif
); 
 296         npixels 
= occ 
/ sp
->pixel_size
; 
 298         if (sp
->user_datafmt 
== SGILOGDATAFMT_RAW
) 
 301                 assert(sp
->tbuflen 
>= npixels
); 
 302                 tp 
= (uint32
*) sp
->tbuf
; 
 304         _TIFFmemset((tdata_t
) tp
, 0, npixels
*sizeof (tp
[0])); 
 306         bp 
= (u_char
*) tif
->tif_rawcp
; 
 308                                         /* get each byte string */ 
 309         for (shft 
= 4*8; (shft 
-= 8) >= 0; ) { 
 310                 for (i 
= 0; i 
< npixels 
&& cc 
> 0; ) 
 311                         if (*bp 
>= 128) {               /* run */ 
 312                                 rc 
= *bp
++ + (2-128); 
 313                                 b 
= (uint32
)*bp
++ << shft
; 
 315                                 while (rc
-- && i 
< npixels
) 
 317                         } else {                        /* non-run */ 
 318                                 rc 
= *bp
++;             /* nul is noop */ 
 319                                 while (--cc 
&& rc
-- && i 
< npixels
) 
 320                                         tp
[i
++] |= (uint32
)*bp
++ << shft
; 
 323                         TIFFError(tif
->tif_name
, 
 324                 "LogLuvDecode32: Not enough data at row %d (short %d pixels)", 
 325                             tif
->tif_row
, npixels 
- i
); 
 326                         tif
->tif_rawcp 
= (tidata_t
) bp
; 
 331         (*sp
->tfunc
)(sp
, op
, npixels
); 
 332         tif
->tif_rawcp 
= (tidata_t
) bp
; 
 338  * Decode a strip of pixels.  We break it into rows to 
 339  * maintain synchrony with the encode algorithm, which 
 343 LogLuvDecodeStrip(TIFF
* tif
, tidata_t bp
, tsize_t cc
, tsample_t s
) 
 345         tsize_t rowlen 
= TIFFScanlineSize(tif
); 
 347         assert(cc%rowlen 
== 0); 
 348         while (cc 
&& (*tif
->tif_decoderow
)(tif
, bp
, rowlen
, s
)) 
 349                 bp 
+= rowlen
, cc 
-= rowlen
; 
 354  * Decode a tile of pixels.  We break it into rows to 
 355  * maintain synchrony with the encode algorithm, which 
 359 LogLuvDecodeTile(TIFF
* tif
, tidata_t bp
, tsize_t cc
, tsample_t s
) 
 361         tsize_t rowlen 
= TIFFTileRowSize(tif
); 
 363         assert(cc%rowlen 
== 0); 
 364         while (cc 
&& (*tif
->tif_decoderow
)(tif
, bp
, rowlen
, s
)) 
 365                 bp 
+= rowlen
, cc 
-= rowlen
; 
 370  * Encode a row of 16-bit pixels. 
 373 LogL16Encode(TIFF
* tif
, tidata_t bp
, tsize_t cc
, tsample_t s
) 
 375         LogLuvState
* sp 
= EncoderState(tif
); 
 376         int shft
, i
, j
, npixels
; 
 380         int occ
, rc
=0, mask
, beg
; 
 384         npixels 
= cc 
/ sp
->pixel_size
; 
 386         if (sp
->user_datafmt 
== SGILOGDATAFMT_16BIT
) 
 389                 tp 
= (int16
*) sp
->tbuf
; 
 390                 assert(sp
->tbuflen 
>= npixels
); 
 391                 (*sp
->tfunc
)(sp
, bp
, npixels
); 
 393                                         /* compress each byte string */ 
 395         occ 
= tif
->tif_rawdatasize 
- tif
->tif_rawcc
; 
 396         for (shft 
= 2*8; (shft 
-= 8) >= 0; ) 
 397                 for (i 
= 0; i 
< npixels
; i 
+= rc
) { 
 400                                 tif
->tif_rawcc 
= tif
->tif_rawdatasize 
- occ
; 
 401                                 if (!TIFFFlushData1(tif
)) 
 404                                 occ 
= tif
->tif_rawdatasize 
- tif
->tif_rawcc
; 
 406                         mask 
= 0xff << shft
;            /* find next run */ 
 407                         for (beg 
= i
; beg 
< npixels
; beg 
+= rc
) { 
 408                                 b 
= (int16
) (tp
[beg
] & mask
); 
 410                                 while (rc 
< 127+2 && beg
+rc 
< npixels 
&& 
 411                                                 (tp
[beg
+rc
] & mask
) == b
) 
 414                                         break;          /* long enough */ 
 416                         if (beg
-i 
> 1 && beg
-i 
< MINRUN
) { 
 417                                 b 
= (int16
) (tp
[i
] & mask
);/*check short run */ 
 419                                 while ((tp
[j
++] & mask
) == b
) 
 421                                         *op
++ = (tidataval_t
)(128-2+j
-i
); 
 422                                         *op
++ = (tidataval_t
) (b 
>> shft
); 
 428                         while (i 
< beg
) {               /* write out non-run */ 
 429                                 if ((j 
= beg
-i
) > 127) j 
= 127; 
 432                                     tif
->tif_rawcc 
= tif
->tif_rawdatasize 
- occ
; 
 433                                     if (!TIFFFlushData1(tif
)) 
 436                                     occ 
= tif
->tif_rawdatasize 
- tif
->tif_rawcc
; 
 438                                 *op
++ = (tidataval_t
) j
; occ
--; 
 440                                         *op
++ = (tidataval_t
) (tp
[i
++] >> shft 
& 0xff); 
 444                         if (rc 
>= MINRUN
) {             /* write out run */ 
 445                                 *op
++ = (tidataval_t
) (128-2+rc
); 
 446                                 *op
++ = (tidataval_t
) (tp
[beg
] >> shft 
& 0xff); 
 452         tif
->tif_rawcc 
= tif
->tif_rawdatasize 
- occ
; 
 458  * Encode a row of 24-bit pixels. 
 461 LogLuvEncode24(TIFF
* tif
, tidata_t bp
, tsize_t cc
, tsample_t s
) 
 463         LogLuvState
* sp 
= EncoderState(tif
); 
 470         npixels 
= cc 
/ sp
->pixel_size
; 
 472         if (sp
->user_datafmt 
== SGILOGDATAFMT_RAW
) 
 475                 tp 
= (uint32
*) sp
->tbuf
; 
 476                 assert(sp
->tbuflen 
>= npixels
); 
 477                 (*sp
->tfunc
)(sp
, bp
, npixels
); 
 479                                         /* write out encoded pixels */ 
 481         occ 
= tif
->tif_rawdatasize 
- tif
->tif_rawcc
; 
 482         for (i 
= npixels
; i
--; ) { 
 485                         tif
->tif_rawcc 
= tif
->tif_rawdatasize 
- occ
; 
 486                         if (!TIFFFlushData1(tif
)) 
 489                         occ 
= tif
->tif_rawdatasize 
- tif
->tif_rawcc
; 
 491                 *op
++ = (tidataval_t
)(*tp 
>> 16); 
 492                 *op
++ = (tidataval_t
)(*tp 
>> 8 & 0xff); 
 493                 *op
++ = (tidataval_t
)(*tp
++ & 0xff); 
 497         tif
->tif_rawcc 
= tif
->tif_rawdatasize 
- occ
; 
 503  * Encode a row of 32-bit pixels. 
 506 LogLuvEncode32(TIFF
* tif
, tidata_t bp
, tsize_t cc
, tsample_t s
) 
 508         LogLuvState
* sp 
= EncoderState(tif
); 
 509         int shft
, i
, j
, npixels
; 
 513         int occ
, rc
=0, mask
, beg
; 
 518         npixels 
= cc 
/ sp
->pixel_size
; 
 520         if (sp
->user_datafmt 
== SGILOGDATAFMT_RAW
) 
 523                 tp 
= (uint32
*) sp
->tbuf
; 
 524                 assert(sp
->tbuflen 
>= npixels
); 
 525                 (*sp
->tfunc
)(sp
, bp
, npixels
); 
 527                                         /* compress each byte string */ 
 529         occ 
= tif
->tif_rawdatasize 
- tif
->tif_rawcc
; 
 530         for (shft 
= 4*8; (shft 
-= 8) >= 0; ) 
 531                 for (i 
= 0; i 
< npixels
; i 
+= rc
) { 
 534                                 tif
->tif_rawcc 
= tif
->tif_rawdatasize 
- occ
; 
 535                                 if (!TIFFFlushData1(tif
)) 
 538                                 occ 
= tif
->tif_rawdatasize 
- tif
->tif_rawcc
; 
 540                         mask 
= 0xff << shft
;            /* find next run */ 
 541                         for (beg 
= i
; beg 
< npixels
; beg 
+= rc
) { 
 544                                 while (rc 
< 127+2 && beg
+rc 
< npixels 
&& 
 545                                                 (tp
[beg
+rc
] & mask
) == b
) 
 548                                         break;          /* long enough */ 
 550                         if (beg
-i 
> 1 && beg
-i 
< MINRUN
) { 
 551                                 b 
= tp
[i
] & mask
;       /* check short run */ 
 553                                 while ((tp
[j
++] & mask
) == b
) 
 555                                                 *op
++ = (tidataval_t
)(128-2+j
-i
); 
 556                                                 *op
++ = (tidataval_t
)(b 
>> shft
); 
 562                         while (i 
< beg
) {               /* write out non-run */ 
 563                                 if ((j 
= beg
-i
) > 127) j 
= 127; 
 566                                         tif
->tif_rawcc 
= tif
->tif_rawdatasize 
- occ
; 
 567                                         if (!TIFFFlushData1(tif
)) 
 570                                         occ 
= tif
->tif_rawdatasize 
- tif
->tif_rawcc
; 
 572                                 *op
++ = (tidataval_t
) j
; occ
--; 
 574                                         *op
++ = (tidataval_t
)(tp
[i
++] >> shft 
& 0xff); 
 578                         if (rc 
>= MINRUN
) {             /* write out run */ 
 579                                 *op
++ = (tidataval_t
) (128-2+rc
); 
 580                                 *op
++ = (tidataval_t
)(tp
[beg
] >> shft 
& 0xff); 
 586         tif
->tif_rawcc 
= tif
->tif_rawdatasize 
- occ
; 
 592  * Encode a strip of pixels.  We break it into rows to 
 593  * avoid encoding runs across row boundaries. 
 596 LogLuvEncodeStrip(TIFF
* tif
, tidata_t bp
, tsize_t cc
, tsample_t s
) 
 598         tsize_t rowlen 
= TIFFScanlineSize(tif
); 
 600         assert(cc%rowlen 
== 0); 
 601         while (cc 
&& (*tif
->tif_encoderow
)(tif
, bp
, rowlen
, s
) == 0) 
 602                 bp 
+= rowlen
, cc 
-= rowlen
; 
 607  * Encode a tile of pixels.  We break it into rows to 
 608  * avoid encoding runs across row boundaries. 
 611 LogLuvEncodeTile(TIFF
* tif
, tidata_t bp
, tsize_t cc
, tsample_t s
) 
 613         tsize_t rowlen 
= TIFFTileRowSize(tif
); 
 615         assert(cc%rowlen 
== 0); 
 616         while (cc 
&& (*tif
->tif_encoderow
)(tif
, bp
, rowlen
, s
) == 0) 
 617                 bp 
+= rowlen
, cc 
-= rowlen
; 
 622  * Encode/Decode functions for converting to and from user formats. 
 628 #define U_NEU           0.210526316 
 629 #define V_NEU           0.473684211 
 634 #define M_LN2           0.69314718055994530942 
 637 #define M_PI            3.14159265358979323846 
 639 #define log2(x)         ((1./M_LN2)*log(x)) 
 640 #define exp2(x)         exp(M_LN2*(x)) 
 642 #define itrunc(x,m)     ((m)==SGILOGENCODE_NODITHER ? \ 
 644                                 (int)((x) + rand()*(1./RAND_MAX) - .5)) 
 650 LogL16toY(int p16
)              /* compute luminance from 16-bit LogL */ 
 652         int     Le 
= p16 
& 0x7fff; 
 657         Y 
= exp(M_LN2
/256.*(Le
+.5) - M_LN2
*64.); 
 658         return (!(p16 
& 0x8000) ? Y 
: -Y
); 
 665 LogL16fromY(double Y
, int em
)   /* get 16-bit LogL from Y */ 
 667         if (Y 
>= 1.8371976e19
) 
 669         if (Y 
<= -1.8371976e19
) 
 671         if (Y 
> 5.4136769e-20) 
 672                 return itrunc(256.*(log2(Y
) + 64.), em
); 
 673         if (Y 
< -5.4136769e-20) 
 674                 return (~0x7fff | itrunc(256.*(log2(-Y
) + 64.), em
)); 
 679 L16toY(LogLuvState
* sp
, tidata_t op
, int n
) 
 681         int16
* l16 
= (int16
*) sp
->tbuf
; 
 682         float* yp 
= (float*) op
; 
 685                 *yp
++ = (float)LogL16toY(*l16
++); 
 689 L16toGry(LogLuvState
* sp
, tidata_t op
, int n
) 
 691         int16
* l16 
= (int16
*) sp
->tbuf
; 
 692         uint8
* gp 
= (uint8
*) op
; 
 695                 double Y 
= LogL16toY(*l16
++); 
 696                 *gp
++ = (uint8
) ((Y 
<= 0.) ? 0 : (Y 
>= 1.) ? 255 : (int)(256.*sqrt(Y
))); 
 701 L16fromY(LogLuvState
* sp
, tidata_t op
, int n
) 
 703         int16
* l16 
= (int16
*) sp
->tbuf
; 
 704         float* yp 
= (float*) op
; 
 707                 *l16
++ = (int16
) (LogL16fromY(*yp
++, sp
->encode_meth
)); 
 714 XYZtoRGB24(float xyz
[3], uint8 rgb
[3]) 
 717                                         /* assume CCIR-709 primaries */ 
 718         r 
=  2.690*xyz
[0] + -1.276*xyz
[1] + -0.414*xyz
[2]; 
 719         g 
= -1.022*xyz
[0] +  1.978*xyz
[1] +  0.044*xyz
[2]; 
 720         b 
=  0.061*xyz
[0] + -0.224*xyz
[1] +  1.163*xyz
[2]; 
 721                                         /* assume 2.0 gamma for speed */ 
 722         /* could use integer sqrt approx., but this is probably faster */ 
 723         rgb
[0] = (uint8
)((r
<=0.) ? 0 : (r 
>= 1.) ? 255 : (int)(256.*sqrt(r
))); 
 724         rgb
[1] = (uint8
)((g
<=0.) ? 0 : (g 
>= 1.) ? 255 : (int)(256.*sqrt(g
))); 
 725         rgb
[2] = (uint8
)((b
<=0.) ? 0 : (b 
>= 1.) ? 255 : (int)(256.*sqrt(b
))); 
 732 LogL10toY(int p10
)              /* compute luminance from 10-bit LogL */ 
 736         return (exp(M_LN2
/64.*(p10
+.5) - M_LN2
*12.)); 
 743 LogL10fromY(double Y
, int em
)   /* get 10-bit LogL from Y */ 
 747         else if (Y 
<= .00024283) 
 750                 return itrunc(64.*(log2(Y
) + 12.), em
); 
 754 #define uv2ang(u, v)    ( (NANGLES*.499999999/M_PI) \ 
 755                                 * atan2((v)-V_NEU,(u)-U_NEU) + .5*NANGLES ) 
 758 oog_encode(double u
, double v
)          /* encode out-of-gamut chroma */ 
 760         static int      oog_table
[NANGLES
]; 
 761         static int      initialized 
= 0; 
 764         if (!initialized
) {             /* set up perimeter table */ 
 765                 double  eps
[NANGLES
], ua
, va
, ang
, epsa
; 
 767                 for (i 
= NANGLES
; i
--; ) 
 769                 for (vi 
= UV_NVS
; vi
--; ) { 
 770                         va 
= UV_VSTART 
+ (vi
+.5)*UV_SQSIZ
; 
 771                         ustep 
= uv_row
[vi
].nus
-1; 
 772                         if (vi 
== UV_NVS
-1 || vi 
== 0 || ustep 
<= 0) 
 774                         for (ui 
= uv_row
[vi
].nus
-1; ui 
>= 0; ui 
-= ustep
) { 
 775                                 ua 
= uv_row
[vi
].ustart 
+ (ui
+.5)*UV_SQSIZ
; 
 776                                 ang 
= uv2ang(ua
, va
); 
 778                                 epsa 
= fabs(ang 
- (i
+.5)); 
 780                                         oog_table
[i
] = uv_row
[vi
].ncum 
+ ui
; 
 785                 for (i 
= NANGLES
; i
--; )        /* fill any holes */ 
 788                                 for (i1 
= 1; i1 
< NANGLES
/2; i1
++) 
 789                                         if (eps
[(i
+i1
)%NANGLES
] < 1.5) 
 791                                 for (i2 
= 1; i2 
< NANGLES
/2; i2
++) 
 792                                         if (eps
[(i
+NANGLES
-i2
)%NANGLES
] < 1.5) 
 796                                                 oog_table
[(i
+i1
)%NANGLES
]; 
 799                                                 oog_table
[(i
+NANGLES
-i2
)%NANGLES
]; 
 803         i 
= (int) uv2ang(u
, v
);         /* look up hue angle */ 
 804         return (oog_table
[i
]); 
 814 uv_encode(double u
, double v
, int em
)   /* encode (u',v') coordinates */ 
 819                 return oog_encode(u
, v
); 
 820         vi 
= itrunc((v 
- UV_VSTART
)*(1./UV_SQSIZ
), em
); 
 822                 return oog_encode(u
, v
); 
 823         if (u 
< uv_row
[vi
].ustart
) 
 824                 return oog_encode(u
, v
); 
 825         ui 
= itrunc((u 
- uv_row
[vi
].ustart
)*(1./UV_SQSIZ
), em
); 
 826         if (ui 
>= uv_row
[vi
].nus
) 
 827                 return oog_encode(u
, v
); 
 829         return (uv_row
[vi
].ncum 
+ ui
); 
 836 uv_decode(double *up
, double *vp
, int c
)        /* decode (u',v') index */ 
 841         if (c 
< 0 || c 
>= UV_NDIVS
) 
 843         lower 
= 0;                              /* binary search */ 
 845         while (upper 
- lower 
> 1) { 
 846                 vi 
= (lower 
+ upper
) >> 1; 
 847                 ui 
= c 
- uv_row
[vi
].ncum
; 
 858         ui 
= c 
- uv_row
[vi
].ncum
; 
 859         *up 
= uv_row
[vi
].ustart 
+ (ui
+.5)*UV_SQSIZ
; 
 860         *vp 
= UV_VSTART 
+ (vi
+.5)*UV_SQSIZ
; 
 868 LogLuv24toXYZ(uint32 p
, float XYZ
[3]) 
 871         double  L
, u
, v
, s
, x
, y
; 
 872                                         /* decode luminance */ 
 873         L 
= LogL10toY(p
>>14 & 0x3ff); 
 875                 XYZ
[0] = XYZ
[1] = XYZ
[2] = 0.; 
 880         if (uv_decode(&u
, &v
, Ce
) < 0) { 
 881                 u 
= U_NEU
; v 
= V_NEU
; 
 883         s 
= 1./(6.*u 
- 16.*v 
+ 12.); 
 887         XYZ
[0] = (float)(x
/y 
* L
); 
 889         XYZ
[2] = (float)((1.-x
-y
)/y 
* L
); 
 896 LogLuv24fromXYZ(float XYZ
[3], int em
) 
 900                                         /* encode luminance */ 
 901         Le 
= LogL10fromY(XYZ
[1], em
); 
 903         s 
= XYZ
[0] + 15.*XYZ
[1] + 3.*XYZ
[2]; 
 904         if (!Le 
|| s 
<= 0.) { 
 911         Ce 
= uv_encode(u
, v
, em
); 
 912         if (Ce 
< 0)                     /* never happens */ 
 913                 Ce 
= uv_encode(U_NEU
, V_NEU
, SGILOGENCODE_NODITHER
); 
 914                                         /* combine encodings */ 
 915         return (Le 
<< 14 | Ce
); 
 919 Luv24toXYZ(LogLuvState
* sp
, tidata_t op
, int n
) 
 921         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 922         float* xyz 
= (float*) op
; 
 925                 LogLuv24toXYZ(*luv
, xyz
); 
 932 Luv24toLuv48(LogLuvState
* sp
, tidata_t op
, int n
) 
 934         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 935         int16
* luv3 
= (int16
*) op
; 
 940                 *luv3
++ = (int16
)((*luv 
>> 12 & 0xffd) + 13314); 
 941                 if (uv_decode(&u
, &v
, *luv
&0x3fff) < 0) { 
 945                 *luv3
++ = (int16
)(u 
* (1L<<15)); 
 946                 *luv3
++ = (int16
)(v 
* (1L<<15)); 
 952 Luv24toRGB(LogLuvState
* sp
, tidata_t op
, int n
) 
 954         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 955         uint8
* rgb 
= (uint8
*) op
; 
 960                 LogLuv24toXYZ(*luv
++, xyz
); 
 961                 XYZtoRGB24(xyz
, rgb
); 
 967 Luv24fromXYZ(LogLuvState
* sp
, tidata_t op
, int n
) 
 969         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 970         float* xyz 
= (float*) op
; 
 973                 *luv
++ = LogLuv24fromXYZ(xyz
, sp
->encode_meth
); 
 979 Luv24fromLuv48(LogLuvState
* sp
, tidata_t op
, int n
) 
 981         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 982         int16
* luv3 
= (int16
*) op
; 
 989                 else if (luv3
[0] >= (1<<12)+3314) 
 991                 else if (sp
->encode_meth 
== SGILOGENCODE_NODITHER
) 
 992                         Le 
= (luv3
[0]-3314) >> 2; 
 994                         Le 
= itrunc(.25*(luv3
[0]-3314.), sp
->encode_meth
); 
 996                 Ce 
= uv_encode((luv3
[1]+.5)/(1<<15), (luv3
[2]+.5)/(1<<15), 
 998                 if (Ce 
< 0)     /* never happens */ 
 999                         Ce 
= uv_encode(U_NEU
, V_NEU
, SGILOGENCODE_NODITHER
); 
1000                 *luv
++ = (uint32
)Le 
<< 14 | Ce
; 
1009 LogLuv32toXYZ(uint32 p
, float XYZ
[3]) 
1011         double  L
, u
, v
, s
, x
, y
; 
1012                                         /* decode luminance */ 
1013         L 
= LogL16toY((int)p 
>> 16); 
1015                 XYZ
[0] = XYZ
[1] = XYZ
[2] = 0.; 
1019         u 
= 1./UVSCALE 
* ((p
>>8 & 0xff) + .5); 
1020         v 
= 1./UVSCALE 
* ((p 
& 0xff) + .5); 
1021         s 
= 1./(6.*u 
- 16.*v 
+ 12.); 
1024                                         /* convert to XYZ */ 
1025         XYZ
[0] = (float)(x
/y 
* L
); 
1027         XYZ
[2] = (float)((1.-x
-y
)/y 
* L
); 
1034 LogLuv32fromXYZ(float XYZ
[3], int em
) 
1036         unsigned int    Le
, ue
, ve
; 
1038                                         /* encode luminance */ 
1039         Le 
= (unsigned int)LogL16fromY(XYZ
[1], em
); 
1041         s 
= XYZ
[0] + 15.*XYZ
[1] + 3.*XYZ
[2]; 
1042         if (!Le 
|| s 
<= 0.) { 
1049         if (u 
<= 0.) ue 
= 0; 
1050         else ue 
= itrunc(UVSCALE
*u
, em
); 
1051         if (ue 
> 255) ue 
= 255; 
1052         if (v 
<= 0.) ve 
= 0; 
1053         else ve 
= itrunc(UVSCALE
*v
, em
); 
1054         if (ve 
> 255) ve 
= 255; 
1055                                         /* combine encodings */ 
1056         return (Le 
<< 16 | ue 
<< 8 | ve
); 
1060 Luv32toXYZ(LogLuvState
* sp
, tidata_t op
, int n
) 
1062         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
1063         float* xyz 
= (float*) op
; 
1066                 LogLuv32toXYZ(*luv
++, xyz
); 
1072 Luv32toLuv48(LogLuvState
* sp
, tidata_t op
, int n
) 
1074         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
1075         int16
* luv3 
= (int16
*) op
; 
1080                 *luv3
++ = (int16
)(*luv 
>> 16); 
1081                 u 
= 1./UVSCALE 
* ((*luv
>>8 & 0xff) + .5); 
1082                 v 
= 1./UVSCALE 
* ((*luv 
& 0xff) + .5); 
1083                 *luv3
++ = (int16
)(u 
* (1L<<15)); 
1084                 *luv3
++ = (int16
)(v 
* (1L<<15)); 
1090 Luv32toRGB(LogLuvState
* sp
, tidata_t op
, int n
) 
1092         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
1093         uint8
* rgb 
= (uint8
*) op
; 
1098                 LogLuv32toXYZ(*luv
++, xyz
); 
1099                 XYZtoRGB24(xyz
, rgb
); 
1105 Luv32fromXYZ(LogLuvState
* sp
, tidata_t op
, int n
) 
1107         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
1108         float* xyz 
= (float*) op
; 
1111                 *luv
++ = LogLuv32fromXYZ(xyz
, sp
->encode_meth
); 
1117 Luv32fromLuv48(LogLuvState
* sp
, tidata_t op
, int n
) 
1119         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
1120         int16
* luv3 
= (int16
*) op
; 
1122         if (sp
->encode_meth 
== SGILOGENCODE_NODITHER
) { 
1124                         *luv
++ = (uint32
)luv3
[0] << 16 | 
1125                                 (luv3
[1]*(uint32
)(UVSCALE
+.5) >> 7 & 0xff00) | 
1126                                 (luv3
[2]*(uint32
)(UVSCALE
+.5) >> 15 & 0xff); 
1132                 *luv
++ = (uint32
)luv3
[0] << 16 | 
1133         (itrunc(luv3
[1]*(UVSCALE
/(1<<15)), sp
->encode_meth
) << 8 & 0xff00) | 
1134                 (itrunc(luv3
[2]*(UVSCALE
/(1<<15)), sp
->encode_meth
) & 0xff); 
1140 _logLuvNop(LogLuvState
* sp
, tidata_t op
, int n
) 
1142         (void) sp
; (void) op
; (void) n
; 
1146 LogL16GuessDataFmt(TIFFDirectory 
*td
) 
1148 #define PACK(s,b,f)     (((b)<<6)|((s)<<3)|(f)) 
1149         switch (PACK(td
->td_samplesperpixel
, td
->td_bitspersample
, td
->td_sampleformat
)) { 
1150         case PACK(1, 32, SAMPLEFORMAT_IEEEFP
): 
1151                 return (SGILOGDATAFMT_FLOAT
); 
1152         case PACK(1, 16, SAMPLEFORMAT_VOID
): 
1153         case PACK(1, 16, SAMPLEFORMAT_INT
): 
1154         case PACK(1, 16, SAMPLEFORMAT_UINT
): 
1155                 return (SGILOGDATAFMT_16BIT
); 
1156         case PACK(1,  8, SAMPLEFORMAT_VOID
): 
1157         case PACK(1,  8, SAMPLEFORMAT_UINT
): 
1158                 return (SGILOGDATAFMT_8BIT
); 
1161         return (SGILOGDATAFMT_UNKNOWN
); 
1165 multiply(size_t m1
, size_t m2
) 
1167         uint32  bytes 
= m1 
* m2
; 
1169         if (m1 
&& bytes 
/ m1 
!= m2
) 
1176 LogL16InitState(TIFF
* tif
) 
1178         TIFFDirectory 
*td 
= &tif
->tif_dir
; 
1179         LogLuvState
* sp 
= DecoderState(tif
); 
1180         static const char module[] = "LogL16InitState"; 
1183         assert(td
->td_photometric 
== PHOTOMETRIC_LOGL
); 
1185         /* for some reason, we can't do this in TIFFInitLogL16 */ 
1186         if (sp
->user_datafmt 
== SGILOGDATAFMT_UNKNOWN
) 
1187                 sp
->user_datafmt 
= LogL16GuessDataFmt(td
); 
1188         switch (sp
->user_datafmt
) { 
1189         case SGILOGDATAFMT_FLOAT
: 
1190                 sp
->pixel_size 
= sizeof (float); 
1192         case SGILOGDATAFMT_16BIT
: 
1193                 sp
->pixel_size 
= sizeof (int16
); 
1195         case SGILOGDATAFMT_8BIT
: 
1196                 sp
->pixel_size 
= sizeof (uint8
); 
1199                 TIFFError(tif
->tif_name
, 
1200                     "No support for converting user data format to LogL"); 
1203         sp
->tbuflen 
= multiply(td
->td_imagewidth
, td
->td_rowsperstrip
); 
1204         if (multiply(sp
->tbuflen
, sizeof (int16
)) == 0 || 
1205             (sp
->tbuf 
= (tidata_t
*) _TIFFmalloc(sp
->tbuflen 
* sizeof (int16
))) == NULL
) { 
1206                 TIFFError(module, "%s: No space for SGILog translation buffer", 
1214 LogLuvGuessDataFmt(TIFFDirectory 
*td
) 
1219          * If the user didn't tell us their datafmt, 
1220          * take our best guess from the bitspersample. 
1222 #define PACK(a,b)       (((a)<<3)|(b)) 
1223         switch (PACK(td
->td_bitspersample
, td
->td_sampleformat
)) { 
1224         case PACK(32, SAMPLEFORMAT_IEEEFP
): 
1225                 guess 
= SGILOGDATAFMT_FLOAT
; 
1227         case PACK(32, SAMPLEFORMAT_VOID
): 
1228         case PACK(32, SAMPLEFORMAT_UINT
): 
1229         case PACK(32, SAMPLEFORMAT_INT
): 
1230                 guess 
= SGILOGDATAFMT_RAW
; 
1232         case PACK(16, SAMPLEFORMAT_VOID
): 
1233         case PACK(16, SAMPLEFORMAT_INT
): 
1234         case PACK(16, SAMPLEFORMAT_UINT
): 
1235                 guess 
= SGILOGDATAFMT_16BIT
; 
1237         case PACK( 8, SAMPLEFORMAT_VOID
): 
1238         case PACK( 8, SAMPLEFORMAT_UINT
): 
1239                 guess 
= SGILOGDATAFMT_8BIT
; 
1242                 guess 
= SGILOGDATAFMT_UNKNOWN
; 
1247          * Double-check samples per pixel. 
1249         switch (td
->td_samplesperpixel
) { 
1251                 if (guess 
!= SGILOGDATAFMT_RAW
) 
1252                         guess 
= SGILOGDATAFMT_UNKNOWN
; 
1255                 if (guess 
== SGILOGDATAFMT_RAW
) 
1256                         guess 
= SGILOGDATAFMT_UNKNOWN
; 
1259                 guess 
= SGILOGDATAFMT_UNKNOWN
; 
1266 LogLuvInitState(TIFF
* tif
) 
1268         TIFFDirectory
* td 
= &tif
->tif_dir
; 
1269         LogLuvState
* sp 
= DecoderState(tif
); 
1270         static const char module[] = "LogLuvInitState"; 
1273         assert(td
->td_photometric 
== PHOTOMETRIC_LOGLUV
); 
1275         /* for some reason, we can't do this in TIFFInitLogLuv */ 
1276         if (td
->td_planarconfig 
!= PLANARCONFIG_CONTIG
) { 
1278                     "SGILog compression cannot handle non-contiguous data"); 
1281         if (sp
->user_datafmt 
== SGILOGDATAFMT_UNKNOWN
) 
1282                 sp
->user_datafmt 
= LogLuvGuessDataFmt(td
); 
1283         switch (sp
->user_datafmt
) { 
1284         case SGILOGDATAFMT_FLOAT
: 
1285                 sp
->pixel_size 
= 3*sizeof (float); 
1287         case SGILOGDATAFMT_16BIT
: 
1288                 sp
->pixel_size 
= 3*sizeof (int16
); 
1290         case SGILOGDATAFMT_RAW
: 
1291                 sp
->pixel_size 
= sizeof (uint32
); 
1293         case SGILOGDATAFMT_8BIT
: 
1294                 sp
->pixel_size 
= 3*sizeof (uint8
); 
1297                 TIFFError(tif
->tif_name
, 
1298                     "No support for converting user data format to LogLuv"); 
1301         sp
->tbuflen 
= multiply(td
->td_imagewidth
, td
->td_rowsperstrip
); 
1302         if (multiply(sp
->tbuflen
, sizeof (uint32
)) == 0 || 
1303             (sp
->tbuf 
= (tidata_t
*) _TIFFmalloc(sp
->tbuflen 
* sizeof (uint32
))) == NULL
) { 
1304                 TIFFError(module, "%s: No space for SGILog translation buffer", 
1312 LogLuvSetupDecode(TIFF
* tif
) 
1314         LogLuvState
* sp 
= DecoderState(tif
); 
1315         TIFFDirectory
* td 
= &tif
->tif_dir
; 
1317         tif
->tif_postdecode 
= _TIFFNoPostDecode
; 
1318         switch (td
->td_photometric
) { 
1319         case PHOTOMETRIC_LOGLUV
: 
1320                 if (!LogLuvInitState(tif
)) 
1322                 if (td
->td_compression 
== COMPRESSION_SGILOG24
) { 
1323                         tif
->tif_decoderow 
= LogLuvDecode24
; 
1324                         switch (sp
->user_datafmt
) { 
1325                         case SGILOGDATAFMT_FLOAT
: 
1326                                 sp
->tfunc 
= Luv24toXYZ
; 
1328                         case SGILOGDATAFMT_16BIT
: 
1329                                 sp
->tfunc 
= Luv24toLuv48
; 
1331                         case SGILOGDATAFMT_8BIT
: 
1332                                 sp
->tfunc 
= Luv24toRGB
; 
1336                         tif
->tif_decoderow 
= LogLuvDecode32
; 
1337                         switch (sp
->user_datafmt
) { 
1338                         case SGILOGDATAFMT_FLOAT
: 
1339                                 sp
->tfunc 
= Luv32toXYZ
; 
1341                         case SGILOGDATAFMT_16BIT
: 
1342                                 sp
->tfunc 
= Luv32toLuv48
; 
1344                         case SGILOGDATAFMT_8BIT
: 
1345                                 sp
->tfunc 
= Luv32toRGB
; 
1350         case PHOTOMETRIC_LOGL
: 
1351                 if (!LogL16InitState(tif
)) 
1353                 tif
->tif_decoderow 
= LogL16Decode
; 
1354                 switch (sp
->user_datafmt
) { 
1355                 case SGILOGDATAFMT_FLOAT
: 
1358                 case SGILOGDATAFMT_8BIT
: 
1359                         sp
->tfunc 
= L16toGry
; 
1364                 TIFFError(tif
->tif_name
, 
1365     "Inappropriate photometric interpretation %d for SGILog compression; %s", 
1366                     td
->td_photometric
, "must be either LogLUV or LogL"); 
1373 LogLuvSetupEncode(TIFF
* tif
) 
1375         LogLuvState
* sp 
= EncoderState(tif
); 
1376         TIFFDirectory
* td 
= &tif
->tif_dir
; 
1378         switch (td
->td_photometric
) { 
1379         case PHOTOMETRIC_LOGLUV
: 
1380                 if (!LogLuvInitState(tif
)) 
1382                 if (td
->td_compression 
== COMPRESSION_SGILOG24
) { 
1383                         tif
->tif_encoderow 
= LogLuvEncode24
; 
1384                         switch (sp
->user_datafmt
) { 
1385                         case SGILOGDATAFMT_FLOAT
: 
1386                                 sp
->tfunc 
= Luv24fromXYZ
; 
1388                         case SGILOGDATAFMT_16BIT
: 
1389                                 sp
->tfunc 
= Luv24fromLuv48
; 
1391                         case SGILOGDATAFMT_RAW
: 
1397                         tif
->tif_encoderow 
= LogLuvEncode32
; 
1398                         switch (sp
->user_datafmt
) { 
1399                         case SGILOGDATAFMT_FLOAT
: 
1400                                 sp
->tfunc 
= Luv32fromXYZ
; 
1402                         case SGILOGDATAFMT_16BIT
: 
1403                                 sp
->tfunc 
= Luv32fromLuv48
; 
1405                         case SGILOGDATAFMT_RAW
: 
1412         case PHOTOMETRIC_LOGL
: 
1413                 if (!LogL16InitState(tif
)) 
1415                 tif
->tif_encoderow 
= LogL16Encode
; 
1416                 switch (sp
->user_datafmt
) { 
1417                 case SGILOGDATAFMT_FLOAT
: 
1418                         sp
->tfunc 
= L16fromY
; 
1420                 case SGILOGDATAFMT_16BIT
: 
1427                 TIFFError(tif
->tif_name
, 
1428     "Inappropriate photometric interpretation %d for SGILog compression; %s", 
1429                     td
->td_photometric
, "must be either LogLUV or LogL"); 
1434         TIFFError(tif
->tif_name
, 
1435             "SGILog compression supported only for %s, or raw data", 
1436             td
->td_photometric 
== PHOTOMETRIC_LOGL 
? "Y, L" : "XYZ, Luv"); 
1441 LogLuvClose(TIFF
* tif
) 
1443         TIFFDirectory 
*td 
= &tif
->tif_dir
; 
1446          * For consistency, we always want to write out the same 
1447          * bitspersample and sampleformat for our TIFF file, 
1448          * regardless of the data format being used by the application. 
1449          * Since this routine is called after tags have been set but 
1450          * before they have been recorded in the file, we reset them here. 
1452         td
->td_samplesperpixel 
= 
1453             (td
->td_photometric 
== PHOTOMETRIC_LOGL
) ? 1 : 3; 
1454         td
->td_bitspersample 
= 16; 
1455         td
->td_sampleformat 
= SAMPLEFORMAT_INT
; 
1459 LogLuvCleanup(TIFF
* tif
) 
1461         LogLuvState
* sp 
= (LogLuvState 
*)tif
->tif_data
; 
1465                         _TIFFfree(sp
->tbuf
); 
1467                 tif
->tif_data 
= NULL
; 
1472 LogLuvVSetField(TIFF
* tif
, ttag_t tag
, va_list ap
) 
1474         LogLuvState
* sp 
= DecoderState(tif
); 
1478         case TIFFTAG_SGILOGDATAFMT
: 
1479                 sp
->user_datafmt 
= va_arg(ap
, int); 
1481                  * Tweak the TIFF header so that the rest of libtiff knows what 
1482                  * size of data will be passed between app and library, and 
1483                  * assume that the app knows what it is doing and is not 
1484                  * confused by these header manipulations... 
1486                 switch (sp
->user_datafmt
) { 
1487                 case SGILOGDATAFMT_FLOAT
: 
1488                         bps 
= 32, fmt 
= SAMPLEFORMAT_IEEEFP
; 
1490                 case SGILOGDATAFMT_16BIT
: 
1491                         bps 
= 16, fmt 
= SAMPLEFORMAT_INT
; 
1493                 case SGILOGDATAFMT_RAW
: 
1494                         bps 
= 32, fmt 
= SAMPLEFORMAT_UINT
; 
1495                         TIFFSetField(tif
, TIFFTAG_SAMPLESPERPIXEL
, 1); 
1497                 case SGILOGDATAFMT_8BIT
: 
1498                         bps 
= 8, fmt 
= SAMPLEFORMAT_UINT
; 
1501                         TIFFError(tif
->tif_name
, 
1502                             "Unknown data format %d for LogLuv compression", 
1506                 TIFFSetField(tif
, TIFFTAG_BITSPERSAMPLE
, bps
); 
1507                 TIFFSetField(tif
, TIFFTAG_SAMPLEFORMAT
, fmt
); 
1509                  * Must recalculate sizes should bits/sample change. 
1511                 tif
->tif_tilesize 
= TIFFTileSize(tif
); 
1512                 tif
->tif_scanlinesize 
= TIFFScanlineSize(tif
); 
1514         case TIFFTAG_SGILOGENCODE
: 
1515                 sp
->encode_meth 
= va_arg(ap
, int); 
1516                 if (sp
->encode_meth 
!= SGILOGENCODE_NODITHER 
&& 
1517                                 sp
->encode_meth 
!= SGILOGENCODE_RANDITHER
) { 
1518                         TIFFError(tif
->tif_name
, 
1519                                 "Unknown encoding %d for LogLuv compression", 
1525                 return (*sp
->vsetparent
)(tif
, tag
, ap
); 
1530 LogLuvVGetField(TIFF
* tif
, ttag_t tag
, va_list ap
) 
1532         LogLuvState 
*sp 
= (LogLuvState 
*)tif
->tif_data
; 
1535         case TIFFTAG_SGILOGDATAFMT
: 
1536                 *va_arg(ap
, int*) = sp
->user_datafmt
; 
1539                 return (*sp
->vgetparent
)(tif
, tag
, ap
); 
1543 static const TIFFFieldInfo LogLuvFieldInfo
[] = { 
1544     { TIFFTAG_SGILOGDATAFMT
,      0, 0, TIFF_SHORT
,     FIELD_PSEUDO
, 
1545       TRUE
,     FALSE
,  "SGILogDataFmt"}, 
1546     { TIFFTAG_SGILOGENCODE
,       0, 0, TIFF_SHORT
,     FIELD_PSEUDO
, 
1547       TRUE
,     FALSE
,  "SGILogEncode"} 
1551 TIFFInitSGILog(TIFF
* tif
, int scheme
) 
1553         static const char module[] = "TIFFInitSGILog"; 
1556         assert(scheme 
== COMPRESSION_SGILOG24 
|| scheme 
== COMPRESSION_SGILOG
); 
1559          * Allocate state block so tag methods have storage to record values. 
1561         tif
->tif_data 
= (tidata_t
) _TIFFmalloc(sizeof (LogLuvState
)); 
1562         if (tif
->tif_data 
== NULL
) 
1564         sp 
= (LogLuvState
*) tif
->tif_data
; 
1565         _TIFFmemset((tdata_t
)sp
, 0, sizeof (*sp
)); 
1566         sp
->user_datafmt 
= SGILOGDATAFMT_UNKNOWN
; 
1567         sp
->encode_meth 
= (scheme 
== COMPRESSION_SGILOG24
) ? 
1568                                 SGILOGENCODE_RANDITHER 
: SGILOGENCODE_NODITHER
; 
1569         sp
->tfunc 
= _logLuvNop
; 
1572          * Install codec methods. 
1573          * NB: tif_decoderow & tif_encoderow are filled 
1576         tif
->tif_setupdecode 
= LogLuvSetupDecode
; 
1577         tif
->tif_decodestrip 
= LogLuvDecodeStrip
; 
1578         tif
->tif_decodetile 
= LogLuvDecodeTile
; 
1579         tif
->tif_setupencode 
= LogLuvSetupEncode
; 
1580         tif
->tif_encodestrip 
= LogLuvEncodeStrip
; 
1581         tif
->tif_encodetile 
= LogLuvEncodeTile
; 
1582         tif
->tif_close 
= LogLuvClose
; 
1583         tif
->tif_cleanup 
= LogLuvCleanup
; 
1585         /* override SetField so we can handle our private pseudo-tag */ 
1586         _TIFFMergeFieldInfo(tif
, LogLuvFieldInfo
, N(LogLuvFieldInfo
)); 
1587         sp
->vgetparent 
= tif
->tif_tagmethods
.vgetfield
; 
1588         tif
->tif_tagmethods
.vgetfield 
= LogLuvVGetField
;   /* hook for codec tags */ 
1589         sp
->vsetparent 
= tif
->tif_tagmethods
.vsetfield
; 
1590         tif
->tif_tagmethods
.vsetfield 
= LogLuvVSetField
;   /* hook for codec tags */ 
1594         TIFFError(module, "%s: No space for LogLuv state block", tif
->tif_name
); 
1597 #endif /* LOGLUV_SUPPORT */