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  * The information is compressed into one of two basic encodings, depending on 
  71  * the setting of the compression tag, which is one of COMPRESSION_SGILOG 
  72  * or COMPRESSION_SGILOG24.  For COMPRESSION_SGILOG, greyscale data is 
  78  * COMPRESSION_SGILOG color data is stored as: 
  81  *      |-+---------------|--------+--------| 
  84  * For the 24-bit COMPRESSION_SGILOG24 color format, the data is stored as: 
  87  *      |----------|--------------| 
  90  * There is no sign bit in the 24-bit case, and the (u,v) chromaticity is 
  91  * encoded as an index for optimal color resolution.  The 10 log bits are 
  92  * defined by the following conversions: 
  94  *      L = 2^((Le'+.5)/64 - 12)                # real from 10-bit 
  96  *      Le' = floor( 64*(log2(L) + 12) )        # 10-bit from real 
  98  * The 10 bits of the smaller format may be converted into the 15 bits of 
  99  * the larger format by multiplying by 4 and adding 13314.  Obviously, 
 100  * a smaller range of magnitudes is covered (about 5 orders of magnitude 
 101  * instead of 38), and the lack of a sign bit means that negative luminances 
 102  * are not allowed.  (Well, they aren't allowed in the real world, either, 
 103  * but they are useful for certain types of image processing.) 
 105  * The desired user format is controlled by the setting the internal 
 106  * pseudo tag TIFFTAG_SGILOGDATAFMT to one of: 
 107  *  SGILOGDATAFMT_FLOAT       = IEEE 32-bit float XYZ values 
 108  *  SGILOGDATAFMT_16BIT       = 16-bit integer encodings of logL, u and v 
 109  * Raw data i/o is also possible using: 
 110  *  SGILOGDATAFMT_RAW         = 32-bit unsigned integer with encoded pixel 
 111  * In addition, the following decoding is provided for ease of display: 
 112  *  SGILOGDATAFMT_8BIT        = 8-bit default RGB gamma-corrected values 
 114  * For grayscale images, we provide the following data formats: 
 115  *  SGILOGDATAFMT_FLOAT       = IEEE 32-bit float Y values 
 116  *  SGILOGDATAFMT_16BIT       = 16-bit integer w/ encoded luminance 
 117  *  SGILOGDATAFMT_8BIT        = 8-bit gray monitor values 
 119  * Note that the COMPRESSION_SGILOG applies a simple run-length encoding 
 120  * scheme by separating the logL, u and v bytes for each row and applying 
 121  * a PackBits type of compression.  Since the 24-bit encoding is not 
 122  * adaptive, the 32-bit color format takes less space in many cases. 
 131  * State block for each open TIFF 
 132  * file using LogLuv compression/decompression. 
 134 typedef struct logLuvState LogLuvState
; 
 137         int                     user_datafmt
;   /* user data format */ 
 138         int                     pixel_size
;     /* bytes per pixel */ 
 140         tidata_t
*               tbuf
;           /* translation buffer */ 
 141         short                   tbuflen
;        /* buffer length */ 
 142         void (*tfunc
)(LogLuvState
*, tidata_t
, int); 
 144         TIFFVSetMethod          vgetparent
;     /* super-class method */ 
 145         TIFFVSetMethod          vsetparent
;     /* super-class method */ 
 148 #define DecoderState(tif)       ((LogLuvState*) (tif)->tif_data) 
 149 #define EncoderState(tif)       ((LogLuvState*) (tif)->tif_data) 
 151 #define N(a)   (sizeof(a)/sizeof(a[0])) 
 152 #define SGILOGDATAFMT_UNKNOWN   -1 
 154 #define MINRUN          4       /* minimum run length */ 
 157  * Decode a string of 16-bit gray pixels. 
 160 LogL16Decode(TIFF
* tif
, tidata_t op
, tsize_t occ
, tsample_t s
) 
 162         LogLuvState
* sp 
= DecoderState(tif
); 
 163         int shft
, i
, npixels
; 
 172         npixels 
= occ 
/ sp
->pixel_size
; 
 174         if (sp
->user_datafmt 
== SGILOGDATAFMT_16BIT
) 
 177                 assert(sp
->tbuflen 
>= npixels
); 
 178                 tp 
= (int16
*) sp
->tbuf
; 
 180         _TIFFmemset((tdata_t
) tp
, 0, npixels
*sizeof (tp
[0])); 
 182         bp 
= (u_char
*) tif
->tif_rawcp
; 
 184                                         /* get each byte string */ 
 185         for (shft 
= 2*8; (shft 
-= 8) >= 0; ) { 
 186                 for (i 
= 0; i 
< npixels 
&& cc 
> 0; ) 
 187                         if (*bp 
>= 128) {               /* run */ 
 188                                 rc 
= *bp
++ + (2-128); 
 189                                 b 
= (int16
)*bp
++ << shft
; 
 193                         } else {                        /* non-run */ 
 194                                 rc 
= *bp
++;             /* nul is noop */ 
 196                                         tp
[i
++] |= (int16
)*bp
++ << shft
; 
 199                         TIFFError(tif
->tif_name
, 
 200                 "LogL16Decode: Not enough data at row %d (short %d pixels)", 
 201                             tif
->tif_row
, npixels 
- i
); 
 202                         tif
->tif_rawcp 
= (tidata_t
) bp
; 
 207         (*sp
->tfunc
)(sp
, op
, npixels
); 
 208         tif
->tif_rawcp 
= (tidata_t
) bp
; 
 214  * Decode a string of 24-bit pixels. 
 217 LogLuvDecode24(TIFF
* tif
, tidata_t op
, tsize_t occ
, tsample_t s
) 
 219         LogLuvState
* sp 
= DecoderState(tif
); 
 227         npixels 
= occ 
/ sp
->pixel_size
; 
 229         if (sp
->user_datafmt 
== SGILOGDATAFMT_RAW
) 
 232                 assert(sp
->tbuflen 
>= npixels
); 
 233                 tp 
= (uint32 
*) sp
->tbuf
; 
 235         _TIFFmemset((tdata_t
) tp
, 0, npixels
*sizeof (tp
[0])); 
 236                                         /* copy to array of uint32 */ 
 237         bp 
= (u_char
*) tif
->tif_rawcp
; 
 239         for (i 
= 0; i 
< npixels 
&& cc 
> 0; i
++) { 
 240                 tp
[i
] = bp
[0] << 16 | bp
[1] << 8 | bp
[2]; 
 244         tif
->tif_rawcp 
= (tidata_t
) bp
; 
 247                 TIFFError(tif
->tif_name
, 
 248             "LogLuvDecode24: Not enough data at row %d (short %d pixels)", 
 249                     tif
->tif_row
, npixels 
- i
); 
 252         (*sp
->tfunc
)(sp
, op
, npixels
); 
 257  * Decode a string of 32-bit pixels. 
 260 LogLuvDecode32(TIFF
* tif
, tidata_t op
, tsize_t occ
, tsample_t s
) 
 263         int shft
, i
, npixels
; 
 270         sp 
= DecoderState(tif
); 
 273         npixels 
= occ 
/ sp
->pixel_size
; 
 275         if (sp
->user_datafmt 
== SGILOGDATAFMT_RAW
) 
 278                 assert(sp
->tbuflen 
>= npixels
); 
 279                 tp 
= (uint32
*) sp
->tbuf
; 
 281         _TIFFmemset((tdata_t
) tp
, 0, npixels
*sizeof (tp
[0])); 
 283         bp 
= (u_char
*) tif
->tif_rawcp
; 
 285                                         /* get each byte string */ 
 286         for (shft 
= 4*8; (shft 
-= 8) >= 0; ) { 
 287                 for (i 
= 0; i 
< npixels 
&& cc 
> 0; ) 
 288                         if (*bp 
>= 128) {               /* run */ 
 289                                 rc 
= *bp
++ + (2-128); 
 290                                 b 
= (uint32
)*bp
++ << shft
; 
 294                         } else {                        /* non-run */ 
 295                                 rc 
= *bp
++;             /* nul is noop */ 
 297                                         tp
[i
++] |= (uint32
)*bp
++ << shft
; 
 300                         TIFFError(tif
->tif_name
, 
 301                 "LogLuvDecode32: Not enough data at row %d (short %d pixels)", 
 302                             tif
->tif_row
, npixels 
- i
); 
 303                         tif
->tif_rawcp 
= (tidata_t
) bp
; 
 308         (*sp
->tfunc
)(sp
, op
, npixels
); 
 309         tif
->tif_rawcp 
= (tidata_t
) bp
; 
 315  * Decode a strip of pixels.  We break it into rows to 
 316  * maintain synchrony with the encode algorithm, which 
 320 LogLuvDecodeStrip(TIFF
* tif
, tidata_t bp
, tsize_t cc
, tsample_t s
) 
 322         tsize_t rowlen 
= TIFFScanlineSize(tif
); 
 324         assert(cc%rowlen 
== 0); 
 325         while (cc 
&& (*tif
->tif_decoderow
)(tif
, bp
, rowlen
, s
)) 
 326                 bp 
+= rowlen
, cc 
-= rowlen
; 
 331  * Decode a tile of pixels.  We break it into rows to 
 332  * maintain synchrony with the encode algorithm, which 
 336 LogLuvDecodeTile(TIFF
* tif
, tidata_t bp
, tsize_t cc
, tsample_t s
) 
 338         tsize_t rowlen 
= TIFFTileRowSize(tif
); 
 340         assert(cc%rowlen 
== 0); 
 341         while (cc 
&& (*tif
->tif_decoderow
)(tif
, bp
, rowlen
, s
)) 
 342                 bp 
+= rowlen
, cc 
-= rowlen
; 
 347  * Encode a row of 16-bit pixels. 
 350 LogL16Encode(TIFF
* tif
, tidata_t bp
, tsize_t cc
, tsample_t s
) 
 352         LogLuvState
* sp 
= EncoderState(tif
); 
 353         int shft
, i
, j
, npixels
; 
 357         int occ
, rc
=0, mask
, beg
; 
 361         npixels 
= cc 
/ sp
->pixel_size
; 
 363         if (sp
->user_datafmt 
== SGILOGDATAFMT_16BIT
) 
 366                 tp 
= (int16
*) sp
->tbuf
; 
 367                 assert(sp
->tbuflen 
>= npixels
); 
 368                 (*sp
->tfunc
)(sp
, bp
, npixels
); 
 370                                         /* compress each byte string */ 
 372         occ 
= tif
->tif_rawdatasize 
- tif
->tif_rawcc
; 
 373         for (shft 
= 2*8; (shft 
-= 8) >= 0; ) 
 374                 for (i 
= 0; i 
< npixels
; i 
+= rc
) { 
 377                                 tif
->tif_rawcc 
= tif
->tif_rawdatasize 
- occ
; 
 378                                 if (!TIFFFlushData1(tif
)) 
 381                                 occ 
= tif
->tif_rawdatasize 
- tif
->tif_rawcc
; 
 383                         mask 
= 0xff << shft
;            /* find next run */ 
 384                         for (beg 
= i
; beg 
< npixels
; beg 
+= rc
) { 
 387                                 while (rc 
< 127+2 && beg
+rc 
< npixels 
&& 
 388                                                 (tp
[beg
+rc
] & mask
) == b
) 
 391                                         break;          /* long enough */ 
 393                         if (beg
-i 
> 1 && beg
-i 
< MINRUN
) { 
 394                                 b 
= tp
[i
] & mask
;       /* check short run */ 
 396                                 while ((tp
[j
++] & mask
) == b
) 
 405                         while (i 
< beg
) {               /* write out non-run */ 
 406                                 if ((j 
= beg
-i
) > 127) j 
= 127; 
 409                                         tif
->tif_rawcc 
= tif
->tif_rawdatasize 
- occ
; 
 410                                         if (!TIFFFlushData1(tif
)) 
 413                                         occ 
= tif
->tif_rawdatasize 
- tif
->tif_rawcc
; 
 417                                         *op
++ = tp
[i
++] >> shft 
& 0xff; 
 421                         if (rc 
>= MINRUN
) {             /* write out run */ 
 423                                 *op
++ = tp
[beg
] >> shft 
& 0xff; 
 429         tif
->tif_rawcc 
= tif
->tif_rawdatasize 
- occ
; 
 435  * Encode a row of 24-bit pixels. 
 438 LogLuvEncode24(TIFF
* tif
, tidata_t bp
, tsize_t cc
, tsample_t s
) 
 440         LogLuvState
* sp 
= EncoderState(tif
); 
 447         npixels 
= cc 
/ sp
->pixel_size
; 
 449         if (sp
->user_datafmt 
== SGILOGDATAFMT_RAW
) 
 452                 tp 
= (uint32
*) sp
->tbuf
; 
 453                 assert(sp
->tbuflen 
>= npixels
); 
 454                 (*sp
->tfunc
)(sp
, bp
, npixels
); 
 456                                         /* write out encoded pixels */ 
 458         occ 
= tif
->tif_rawdatasize 
- tif
->tif_rawcc
; 
 459         for (i 
= npixels
; i
--; ) { 
 462                         tif
->tif_rawcc 
= tif
->tif_rawdatasize 
- occ
; 
 463                         if (!TIFFFlushData1(tif
)) 
 466                         occ 
= tif
->tif_rawdatasize 
- tif
->tif_rawcc
; 
 469                 *op
++ = *tp 
>> 8 & 0xff; 
 470                 *op
++ = *tp
++ & 0xff; 
 474         tif
->tif_rawcc 
= tif
->tif_rawdatasize 
- occ
; 
 480  * Encode a row of 32-bit pixels. 
 483 LogLuvEncode32(TIFF
* tif
, tidata_t bp
, tsize_t cc
, tsample_t s
) 
 485         LogLuvState
* sp 
= EncoderState(tif
); 
 486         int shft
, i
, j
, npixels
; 
 490         int occ
, rc
=0, mask
, beg
; 
 495         npixels 
= cc 
/ sp
->pixel_size
; 
 497         if (sp
->user_datafmt 
== SGILOGDATAFMT_RAW
) 
 500                 tp 
= (uint32
*) sp
->tbuf
; 
 501                 assert(sp
->tbuflen 
>= npixels
); 
 502                 (*sp
->tfunc
)(sp
, bp
, npixels
); 
 504                                         /* compress each byte string */ 
 506         occ 
= tif
->tif_rawdatasize 
- tif
->tif_rawcc
; 
 507         for (shft 
= 4*8; (shft 
-= 8) >= 0; ) 
 508                 for (i 
= 0; i 
< npixels
; i 
+= rc
) { 
 511                                 tif
->tif_rawcc 
= tif
->tif_rawdatasize 
- occ
; 
 512                                 if (!TIFFFlushData1(tif
)) 
 515                                 occ 
= tif
->tif_rawdatasize 
- tif
->tif_rawcc
; 
 517                         mask 
= 0xff << shft
;            /* find next run */ 
 518                         for (beg 
= i
; beg 
< npixels
; beg 
+= rc
) { 
 521                                 while (rc 
< 127+2 && beg
+rc 
< npixels 
&& 
 522                                                 (tp
[beg
+rc
] & mask
) == b
) 
 525                                         break;          /* long enough */ 
 527                         if (beg
-i 
> 1 && beg
-i 
< MINRUN
) { 
 528                                 b 
= tp
[i
] & mask
;       /* check short run */ 
 530                                 while ((tp
[j
++] & mask
) == b
) 
 539                         while (i 
< beg
) {               /* write out non-run */ 
 540                                 if ((j 
= beg
-i
) > 127) j 
= 127; 
 543                                         tif
->tif_rawcc 
= tif
->tif_rawdatasize 
- occ
; 
 544                                         if (!TIFFFlushData1(tif
)) 
 547                                         occ 
= tif
->tif_rawdatasize 
- tif
->tif_rawcc
; 
 551                                         *op
++ = tp
[i
++] >> shft 
& 0xff; 
 555                         if (rc 
>= MINRUN
) {             /* write out run */ 
 557                                 *op
++ = tp
[beg
] >> shft 
& 0xff; 
 563         tif
->tif_rawcc 
= tif
->tif_rawdatasize 
- occ
; 
 569  * Encode a strip of pixels.  We break it into rows to 
 570  * avoid encoding runs across row boundaries. 
 573 LogLuvEncodeStrip(TIFF
* tif
, tidata_t bp
, tsize_t cc
, tsample_t s
) 
 575         tsize_t rowlen 
= TIFFScanlineSize(tif
); 
 577         assert(cc%rowlen 
== 0); 
 578         while (cc 
&& (*tif
->tif_encoderow
)(tif
, bp
, rowlen
, s
) == 0) 
 579                 bp 
+= rowlen
, cc 
-= rowlen
; 
 584  * Encode a tile of pixels.  We break it into rows to 
 585  * avoid encoding runs across row boundaries. 
 588 LogLuvEncodeTile(TIFF
* tif
, tidata_t bp
, tsize_t cc
, tsample_t s
) 
 590         tsize_t rowlen 
= TIFFTileRowSize(tif
); 
 592         assert(cc%rowlen 
== 0); 
 593         while (cc 
&& (*tif
->tif_encoderow
)(tif
, bp
, rowlen
, s
) == 0) 
 594                 bp 
+= rowlen
, cc 
-= rowlen
; 
 599  * Encode/Decode functions for converting to and from user formats. 
 603 #define U_NEU   0.210526316 
 604 #define V_NEU   0.473684211 
 609 #define LOGOF2          0.69314718055994530942 
 611 #define log2(x)         ((1./LOGOF2)*log(x)) 
 612 #define exp2(x)         exp(LOGOF2*(x)) 
 619         int     Le 
= p16 
& 0x7fff; 
 624         Y 
= exp(LOGOF2
/256.*(Le
+.5) - LOGOF2
*64.); 
 635         if (Y 
<= -1.84467e19
) 
 638                 return (int)(256.*(log2(Y
) + 64.)); 
 639         if (Y 
< -5.43571e-20) 
 640                 return (~0x7fff | (int)(256.*(log2(-Y
) + 64.))); 
 645 L16toY(LogLuvState
* sp
, tidata_t op
, int n
) 
 647         int16
* l16 
= (int16
*) sp
->tbuf
; 
 648         float* yp 
= (float*) op
; 
 651                 *yp
++ = pix16toY(*l16
++); 
 655 L16toGry(LogLuvState
* sp
, tidata_t op
, int n
) 
 657         int16
* l16 
= (int16
*) sp
->tbuf
; 
 658         uint8
* gp 
= (uint8
*) op
; 
 661                 double Y 
= pix16toY(*l16
++); 
 662                 *gp
++ = (Y 
<= 0.) ? 0 : (Y 
>= 1.) ? 255 : (int)(256.*sqrt(Y
)); 
 667 L16fromY(LogLuvState
* sp
, tidata_t op
, int n
) 
 669         int16
* l16 
= (int16
*) sp
->tbuf
; 
 670         float* yp 
= (float*) op
; 
 673                 *l16
++ = pix16fromY(*yp
++); 
 677 XYZtoRGB24(float xyz
[3], uint8 rgb
[3]) 
 680                                         /* assume CCIR-709 primaries */ 
 681         r 
=  2.690*xyz
[0] + -1.276*xyz
[1] + -0.414*xyz
[2]; 
 682         g 
= -1.022*xyz
[0] +  1.978*xyz
[1] +  0.044*xyz
[2]; 
 683         b 
=  0.061*xyz
[0] + -0.224*xyz
[1] +  1.163*xyz
[2]; 
 684                                         /* assume 2.0 gamma for speed */ 
 685         /* could use integer sqrt approx., but this is probably faster */ 
 686         rgb
[0] = (r 
<= 0.) ? 0 : (r 
>= 1.) ? 255 : (int)(256.*sqrt(r
)); 
 687         rgb
[1] = (g 
<= 0.) ? 0 : (g 
>= 1.) ? 255 : (int)(256.*sqrt(g
)); 
 688         rgb
[2] = (b 
<= 0.) ? 0 : (b 
>= 1.) ? 255 : (int)(256.*sqrt(b
)); 
 692 uv_encode(double u
, double v
)           /* encode (u',v') coordinates */ 
 698         vi 
= (v 
- UV_VSTART
)*(1./UV_SQSIZ
); 
 701         if (u 
< uv_row
[vi
].ustart
) 
 703         ui 
= (u 
- uv_row
[vi
].ustart
)*(1./UV_SQSIZ
); 
 704         if (ui 
>= uv_row
[vi
].nus
) 
 706         return(uv_row
[vi
].ncum 
+ ui
); 
 710 uv_decode(double *up
, double *vp
, int c
)        /* decode (u',v') index */ 
 715         if (c 
< 0 || c 
>= UV_NDIVS
) 
 717         lower 
= 0;                      /* binary search */ 
 720                 vi 
= (lower 
+ upper
) >> 1; 
 721                 ui 
= c 
- uv_row
[vi
].ncum
; 
 728         } while (upper 
- lower 
> 1); 
 730         ui 
= c 
- uv_row
[vi
].ncum
; 
 731         *up 
= uv_row
[vi
].ustart 
+ (ui
+.5)*UV_SQSIZ
; 
 732         *vp 
= UV_VSTART 
+ (vi
+.5)*UV_SQSIZ
; 
 737 pix24toXYZ(uint32 p
, float XYZ
[3]) 
 740         double  L
, u
, v
, s
, x
, y
; 
 741                                         /* decode luminance */ 
 742         Le 
= p 
>> 14 & 0x3ff; 
 744                 XYZ
[0] = XYZ
[1] = XYZ
[2] = 0.; 
 747         L 
= exp(LOGOF2
/64.*(Le
+.5) - LOGOF2
*12.); 
 750         if (uv_decode(&u
, &v
, Ce
) < 0) { 
 751                 u 
= U_NEU
; v 
= V_NEU
; 
 753         s 
= 1./(6.*u 
- 16.*v 
+ 12.); 
 759         XYZ
[2] = (1.-x
-y
)/y 
* L
; 
 763 pix24fromXYZ(float XYZ
[3]) 
 767                                         /* encode luminance */ 
 771         else if (L 
<= 1./4096.) 
 774                 Le 
= 64.*(log2(L
) + 12.); 
 776         s 
= XYZ
[0] + 15.*XYZ
[1] + 3.*XYZ
[2]; 
 784         Ce 
= uv_encode(u
, v
); 
 786                 Ce 
= uv_encode(U_NEU
, V_NEU
); 
 787                                         /* combine encodings */ 
 788         return (Le 
<< 14 | Ce
); 
 792 Luv24toXYZ(LogLuvState
* sp
, tidata_t op
, int n
) 
 794         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 795         float* xyz 
= (float*) op
; 
 798                 pix24toXYZ(*luv
, xyz
); 
 805 Luv24toLuv48(LogLuvState
* sp
, tidata_t op
, int n
) 
 807         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 808         int16
* luv3 
= (int16
*) op
; 
 813                 *luv3
++ = (*luv 
>> 12 & 0xffd) + 13314; 
 814                 if (uv_decode(&u
, &v
, *luv
&0x3fff) < 0) { 
 818                 *luv3
++ = u 
* (1L<<15); 
 819                 *luv3
++ = v 
* (1L<<15); 
 825 Luv24toRGB(LogLuvState
* sp
, tidata_t op
, int n
) 
 827         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 828         uint8
* rgb 
= (uint8
*) op
; 
 833                 pix24toXYZ(*luv
++, xyz
); 
 834                 XYZtoRGB24(xyz
, rgb
); 
 840 Luv24fromXYZ(LogLuvState
* sp
, tidata_t op
, int n
) 
 842         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 843         float* xyz 
= (float*) op
; 
 846                 *luv
++ = pix24fromXYZ(xyz
); 
 852 Luv24fromLuv48(LogLuvState
* sp
, tidata_t op
, int n
) 
 854         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 855         int16
* luv3 
= (int16
*) op
; 
 862                 else if (luv3
[0] >= (1<<12)+3314) 
 865                         Le 
= (luv3
[0]-3314) >> 2; 
 866                 Ce 
= uv_encode((luv
[1]+.5)/(1<<15), (luv
[2]+.5)/(1<<15)); 
 868                         Ce 
= uv_encode(U_NEU
, V_NEU
); 
 869                 *luv
++ = (uint32
)Le 
<< 14 | Ce
; 
 875 pix32toXYZ(uint32 p
, float XYZ
[3]) 
 877         double  L
, u
, v
, s
, x
, y
; 
 878                                         /* decode luminance */ 
 879         L 
= pix16toY((int)p 
>> 16); 
 881                 XYZ
[0] = XYZ
[1] = XYZ
[2] = 0.; 
 885         u 
= 1./UVSCALE 
* ((p
>>8 & 0xff) + .5); 
 886         v 
= 1./UVSCALE 
* ((p 
& 0xff) + .5); 
 887         s 
= 1./(6.*u 
- 16.*v 
+ 12.); 
 893         XYZ
[2] = (1.-x
-y
)/y 
* L
; 
 897 pix32fromXYZ(float XYZ
[3]) 
 899         unsigned int    Le
, ue
, ve
; 
 901                                         /* encode luminance */ 
 902         Le 
= (unsigned int)pix16fromY(XYZ
[1]); 
 904         s 
= XYZ
[0] + 15.*XYZ
[1] + 3.*XYZ
[2]; 
 913         else ue 
= UVSCALE 
* u
; 
 914         if (ue 
> 255) ue 
= 255; 
 916         else ve 
= UVSCALE 
* v
; 
 917         if (ve 
> 255) ve 
= 255; 
 918                                         /* combine encodings */ 
 919         return (Le 
<< 16 | ue 
<< 8 | ve
); 
 923 Luv32toXYZ(LogLuvState
* sp
, tidata_t op
, int n
) 
 925         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 926         float* xyz 
= (float*) op
; 
 929                 pix32toXYZ(*luv
++, xyz
); 
 935 Luv32toLuv48(LogLuvState
* sp
, tidata_t op
, int n
) 
 937         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 938         int16
* luv3 
= (int16
*) op
; 
 943                 *luv3
++ = *luv 
>> 16; 
 944                 u 
= 1./UVSCALE 
* ((*luv
>>8 & 0xff) + .5); 
 945                 v 
= 1./UVSCALE 
* ((*luv 
& 0xff) + .5); 
 946                 *luv3
++ = u 
* (1L<<15); 
 947                 *luv3
++ = v 
* (1L<<15); 
 953 Luv32toRGB(LogLuvState
* sp
, tidata_t op
, int n
) 
 955         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 956         uint8
* rgb 
= (uint8
*) op
; 
 961                 pix32toXYZ(*luv
++, xyz
); 
 962                 XYZtoRGB24(xyz
, rgb
); 
 968 Luv32fromXYZ(LogLuvState
* sp
, tidata_t op
, int n
) 
 970         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 971         float* xyz 
= (float*) op
; 
 974                 *luv
++ = pix32fromXYZ(xyz
); 
 980 Luv32fromLuv48(LogLuvState
* sp
, tidata_t op
, int n
) 
 982         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 983         int16
* luv3 
= (int16
*) op
; 
 986                 *luv
++ = (uint32
)luv3
[0] << 16 | 
 987                         (luv3
[1]*(uint32
)(UVSCALE
+.5) >> 7 & 0xff00) | 
 988                         (luv3
[2]*(uint32
)(UVSCALE
+.5) >> 15 & 0xff); 
 994 _logLuvNop(LogLuvState
* sp
, tidata_t op
, int n
) 
 996         (void) sp
; (void) op
; (void) n
; 
1000 LogL16GuessDataFmt(TIFFDirectory 
*td
) 
1002 #define PACK(s,b,f)     (((b)<<6)|((s)<<3)|(f)) 
1003         switch (PACK(td
->td_samplesperpixel
, td
->td_bitspersample
, td
->td_sampleformat
)) { 
1004         case PACK(1, 32, SAMPLEFORMAT_IEEEFP
): 
1005                 return (SGILOGDATAFMT_FLOAT
); 
1006         case PACK(1, 16, SAMPLEFORMAT_VOID
): 
1007         case PACK(1, 16, SAMPLEFORMAT_INT
): 
1008         case PACK(1, 16, SAMPLEFORMAT_UINT
): 
1009                 return (SGILOGDATAFMT_16BIT
); 
1010         case PACK(1,  8, SAMPLEFORMAT_VOID
): 
1011         case PACK(1,  8, SAMPLEFORMAT_UINT
): 
1012                 return (SGILOGDATAFMT_8BIT
); 
1015         return (SGILOGDATAFMT_UNKNOWN
); 
1019 LogL16InitState(TIFF
* tif
) 
1021         TIFFDirectory 
*td 
= &tif
->tif_dir
; 
1022         LogLuvState
* sp 
= DecoderState(tif
); 
1023         static const char module[] = "LogL16InitState"; 
1026         assert(td
->td_photometric 
== PHOTOMETRIC_LOGL
); 
1028         /* for some reason, we can't do this in TIFFInitLogL16 */ 
1029         if (sp
->user_datafmt 
== SGILOGDATAFMT_UNKNOWN
) 
1030                 sp
->user_datafmt 
= LogL16GuessDataFmt(td
); 
1031         switch (sp
->user_datafmt
) { 
1032         case SGILOGDATAFMT_FLOAT
: 
1033                 sp
->pixel_size 
= sizeof (float); 
1035         case SGILOGDATAFMT_16BIT
: 
1036                 sp
->pixel_size 
= sizeof (int16
); 
1038         case SGILOGDATAFMT_8BIT
: 
1039                 sp
->pixel_size 
= sizeof (uint8
); 
1042                 TIFFError(tif
->tif_name
, 
1043                     "No support for converting user data format to LogL"); 
1046         sp
->tbuflen 
= td
->td_imagewidth 
* td
->td_rowsperstrip
; 
1047         sp
->tbuf 
= (tidata_t
*) _TIFFmalloc(sp
->tbuflen 
* sizeof (int16
)); 
1048         if (sp
->tbuf 
== NULL
) { 
1049                 TIFFError(module, "%s: No space for SGILog translation buffer", 
1057 LogLuvGuessDataFmt(TIFFDirectory 
*td
) 
1062          * If the user didn't tell us their datafmt, 
1063          * take our best guess from the bitspersample. 
1065 #define PACK(a,b)       (((a)<<3)|(b)) 
1066         switch (PACK(td
->td_bitspersample
, td
->td_sampleformat
)) { 
1067         case PACK(32, SAMPLEFORMAT_IEEEFP
): 
1068                 guess 
= SGILOGDATAFMT_FLOAT
; 
1070         case PACK(32, SAMPLEFORMAT_VOID
): 
1071         case PACK(32, SAMPLEFORMAT_UINT
): 
1072         case PACK(32, SAMPLEFORMAT_INT
): 
1073                 guess 
= SGILOGDATAFMT_RAW
; 
1075         case PACK(16, SAMPLEFORMAT_VOID
): 
1076         case PACK(16, SAMPLEFORMAT_INT
): 
1077         case PACK(16, SAMPLEFORMAT_UINT
): 
1078                 guess 
= SGILOGDATAFMT_16BIT
; 
1080         case PACK( 8, SAMPLEFORMAT_VOID
): 
1081         case PACK( 8, SAMPLEFORMAT_UINT
): 
1082                 guess 
= SGILOGDATAFMT_8BIT
; 
1085                 guess 
= SGILOGDATAFMT_UNKNOWN
; 
1090          * Double-check samples per pixel. 
1092         switch (td
->td_samplesperpixel
) { 
1094                 if (guess 
!= SGILOGDATAFMT_RAW
) 
1095                         guess 
= SGILOGDATAFMT_UNKNOWN
; 
1098                 if (guess 
== SGILOGDATAFMT_RAW
) 
1099                         guess 
= SGILOGDATAFMT_UNKNOWN
; 
1102                 guess 
= SGILOGDATAFMT_UNKNOWN
; 
1109 LogLuvInitState(TIFF
* tif
) 
1111         TIFFDirectory
* td 
= &tif
->tif_dir
; 
1112         LogLuvState
* sp 
= DecoderState(tif
); 
1113         static const char module[] = "LogLuvInitState"; 
1116         assert(td
->td_photometric 
== PHOTOMETRIC_LOGLUV
); 
1118         /* for some reason, we can't do this in TIFFInitLogLuv */ 
1119         if (td
->td_planarconfig 
!= PLANARCONFIG_CONTIG
) { 
1121                     "SGILog compression cannot handle non-contiguous data"); 
1124         if (sp
->user_datafmt 
== SGILOGDATAFMT_UNKNOWN
) 
1125                 sp
->user_datafmt 
= LogLuvGuessDataFmt(td
); 
1126         switch (sp
->user_datafmt
) { 
1127         case SGILOGDATAFMT_FLOAT
: 
1128                 sp
->pixel_size 
= 3*sizeof (float); 
1130         case SGILOGDATAFMT_16BIT
: 
1131                 sp
->pixel_size 
= 3*sizeof (int16
); 
1133         case SGILOGDATAFMT_RAW
: 
1134                 sp
->pixel_size 
= sizeof (uint32
); 
1136         case SGILOGDATAFMT_8BIT
: 
1137                 sp
->pixel_size 
= 3*sizeof (uint8
); 
1140                 TIFFError(tif
->tif_name
, 
1141                     "No support for converting user data format to LogLuv"); 
1144         sp
->tbuflen 
= td
->td_imagewidth 
* td
->td_rowsperstrip
; 
1145         sp
->tbuf 
= (tidata_t
*) _TIFFmalloc(sp
->tbuflen 
* sizeof (uint32
)); 
1146         if (sp
->tbuf 
== NULL
) { 
1147                 TIFFError(module, "%s: No space for SGILog translation buffer", 
1155 LogLuvSetupDecode(TIFF
* tif
) 
1157         LogLuvState
* sp 
= DecoderState(tif
); 
1158         TIFFDirectory
* td 
= &tif
->tif_dir
; 
1160         tif
->tif_postdecode 
= _TIFFNoPostDecode
; 
1161         switch (td
->td_photometric
) { 
1162         case PHOTOMETRIC_LOGLUV
: 
1163                 if (!LogLuvInitState(tif
)) 
1165                 if (td
->td_compression 
== COMPRESSION_SGILOG24
) { 
1166                         tif
->tif_decoderow 
= LogLuvDecode24
; 
1167                         switch (sp
->user_datafmt
) { 
1168                         case SGILOGDATAFMT_FLOAT
: 
1169                                 sp
->tfunc 
= Luv24toXYZ
; 
1171                         case SGILOGDATAFMT_16BIT
: 
1172                                 sp
->tfunc 
= Luv24toLuv48
; 
1174                         case SGILOGDATAFMT_8BIT
: 
1175                                 sp
->tfunc 
= Luv24toRGB
; 
1179                         tif
->tif_decoderow 
= LogLuvDecode32
; 
1180                         switch (sp
->user_datafmt
) { 
1181                         case SGILOGDATAFMT_FLOAT
: 
1182                                 sp
->tfunc 
= Luv32toXYZ
; 
1184                         case SGILOGDATAFMT_16BIT
: 
1185                                 sp
->tfunc 
= Luv32toLuv48
; 
1187                         case SGILOGDATAFMT_8BIT
: 
1188                                 sp
->tfunc 
= Luv32toRGB
; 
1193         case PHOTOMETRIC_LOGL
: 
1194                 if (!LogL16InitState(tif
)) 
1196                 tif
->tif_decoderow 
= LogL16Decode
; 
1197                 switch (sp
->user_datafmt
) { 
1198                 case SGILOGDATAFMT_FLOAT
: 
1201                 case SGILOGDATAFMT_8BIT
: 
1202                         sp
->tfunc 
= L16toGry
; 
1207                 TIFFError(tif
->tif_name
, 
1208     "Inappropriate photometric interpretation %d for SGILog compression; %s", 
1209                     td
->td_photometric
, "must be either LogLUV or LogL"); 
1216 LogLuvSetupEncode(TIFF
* tif
) 
1218         LogLuvState
* sp 
= EncoderState(tif
); 
1219         TIFFDirectory
* td 
= &tif
->tif_dir
; 
1221         switch (td
->td_photometric
) { 
1222         case PHOTOMETRIC_LOGLUV
: 
1223                 if (!LogLuvInitState(tif
)) 
1225                 if (td
->td_compression 
== COMPRESSION_SGILOG24
) { 
1226                         tif
->tif_encoderow 
= LogLuvEncode24
; 
1227                         switch (sp
->user_datafmt
) { 
1228                         case SGILOGDATAFMT_FLOAT
: 
1229                                 sp
->tfunc 
= Luv24fromXYZ
; 
1231                         case SGILOGDATAFMT_16BIT
: 
1232                                 sp
->tfunc 
= Luv24fromLuv48
; 
1234                         case SGILOGDATAFMT_RAW
: 
1240                         tif
->tif_encoderow 
= LogLuvEncode32
; 
1241                         switch (sp
->user_datafmt
) { 
1242                         case SGILOGDATAFMT_FLOAT
: 
1243                                 sp
->tfunc 
= Luv32fromXYZ
; 
1245                         case SGILOGDATAFMT_16BIT
: 
1246                                 sp
->tfunc 
= Luv32fromLuv48
; 
1248                         case SGILOGDATAFMT_RAW
: 
1255         case PHOTOMETRIC_LOGL
: 
1256                 if (!LogL16InitState(tif
)) 
1258                 tif
->tif_encoderow 
= LogL16Encode
; 
1259                 switch (sp
->user_datafmt
) { 
1260                 case SGILOGDATAFMT_FLOAT
: 
1261                         sp
->tfunc 
= L16fromY
; 
1263                 case SGILOGDATAFMT_16BIT
: 
1270                 TIFFError(tif
->tif_name
, 
1271     "Inappropriate photometric interpretation %d for SGILog compression; %s", 
1272                     td
->td_photometric
, "must be either LogLUV or LogL"); 
1277         TIFFError(tif
->tif_name
, 
1278             "SGILog compression supported only for %s, or raw data", 
1279             td
->td_photometric 
== PHOTOMETRIC_LOGL 
? "Y, L" : "XYZ, Luv"); 
1284 LogLuvClose(TIFF
* tif
) 
1286         TIFFDirectory 
*td 
= &tif
->tif_dir
; 
1289          * For consistency, we always want to write out the same 
1290          * bitspersample and sampleformat for our TIFF file, 
1291          * regardless of the data format being used by the application. 
1292          * Since this routine is called after tags have been set but 
1293          * before they have been recorded in the file, we reset them here. 
1295         td
->td_samplesperpixel 
= 
1296             (td
->td_photometric 
== PHOTOMETRIC_LOGL
) ? 1 : 3; 
1297         td
->td_bitspersample 
= 16; 
1298         td
->td_sampleformat 
= SAMPLEFORMAT_INT
; 
1302 LogLuvCleanup(TIFF
* tif
) 
1304         LogLuvState
* sp 
= (LogLuvState 
*)tif
->tif_data
; 
1308                         _TIFFfree(sp
->tbuf
); 
1310                 tif
->tif_data 
= NULL
; 
1315 LogLuvVSetField(TIFF
* tif
, ttag_t tag
, va_list ap
) 
1317         LogLuvState
* sp 
= DecoderState(tif
); 
1321         case TIFFTAG_SGILOGDATAFMT
: 
1322                 sp
->user_datafmt 
= va_arg(ap
, int); 
1324                  * Tweak the TIFF header so that the rest of libtiff knows what 
1325                  * size of data will be passed between app and library, and 
1326                  * assume that the app knows what it is doing and is not 
1327                  * confused by these header manipulations... 
1329                 switch (sp
->user_datafmt
) { 
1330                 case SGILOGDATAFMT_FLOAT
: 
1331                         bps 
= 32, fmt 
= SAMPLEFORMAT_IEEEFP
; 
1333                 case SGILOGDATAFMT_16BIT
: 
1334                         bps 
= 16, fmt 
= SAMPLEFORMAT_INT
; 
1336                 case SGILOGDATAFMT_RAW
: 
1337                         bps 
= 32, fmt 
= SAMPLEFORMAT_UINT
; 
1339                 case SGILOGDATAFMT_8BIT
: 
1340                         bps 
= 8, fmt 
= SAMPLEFORMAT_UINT
; 
1343                         TIFFError(tif
->tif_name
, 
1344                             "Unknown data format %d for LogLuv compression", 
1348                 TIFFSetField(tif
, TIFFTAG_BITSPERSAMPLE
, bps
); 
1349                 TIFFSetField(tif
, TIFFTAG_SAMPLEFORMAT
, fmt
); 
1351                  * Must recalculate sizes should bits/sample change. 
1353                 tif
->tif_tilesize 
= TIFFTileSize(tif
); 
1354                 tif
->tif_scanlinesize 
= TIFFScanlineSize(tif
); 
1357                 return (*sp
->vsetparent
)(tif
, tag
, ap
); 
1362 LogLuvVGetField(TIFF
* tif
, ttag_t tag
, va_list ap
) 
1364         LogLuvState 
*sp 
= (LogLuvState 
*)tif
->tif_data
; 
1367         case TIFFTAG_SGILOGDATAFMT
: 
1368                 *va_arg(ap
, int*) = sp
->user_datafmt
; 
1371                 return (*sp
->vgetparent
)(tif
, tag
, ap
); 
1375 static const TIFFFieldInfo LogLuvFieldInfo
[] = { 
1376     { TIFFTAG_SGILOGDATAFMT
,      0, 0, TIFF_SHORT
,     FIELD_PSEUDO
, 
1377       TRUE
,     FALSE
,  "SGILogDataFmt"} 
1381 TIFFInitSGILog(TIFF
* tif
, int scheme
) 
1383         static const char module[] = "TIFFInitSGILog"; 
1386         assert(scheme 
== COMPRESSION_SGILOG24 
|| scheme 
== COMPRESSION_SGILOG
); 
1389          * Allocate state block so tag methods have storage to record values. 
1391         tif
->tif_data 
= (tidata_t
) _TIFFmalloc(sizeof (LogLuvState
)); 
1392         if (tif
->tif_data 
== NULL
) 
1394         sp 
= (LogLuvState
*) tif
->tif_data
; 
1395         memset(sp
, 0, sizeof (*sp
)); 
1396         sp
->user_datafmt 
= SGILOGDATAFMT_UNKNOWN
; 
1397         sp
->tfunc 
= _logLuvNop
; 
1400          * Install codec methods. 
1401          * NB: tif_decoderow & tif_encoderow are filled 
1404         tif
->tif_setupdecode 
= LogLuvSetupDecode
; 
1405         tif
->tif_decodestrip 
= LogLuvDecodeStrip
; 
1406         tif
->tif_decodetile 
= LogLuvDecodeTile
; 
1407         tif
->tif_setupencode 
= LogLuvSetupEncode
; 
1408         tif
->tif_encodestrip 
= LogLuvEncodeStrip
; 
1409         tif
->tif_encodetile 
= LogLuvEncodeTile
; 
1410         tif
->tif_close 
= LogLuvClose
; 
1411         tif
->tif_cleanup 
= LogLuvCleanup
; 
1413         /* override SetField so we can handle our private pseudo-tag */ 
1414         _TIFFMergeFieldInfo(tif
, LogLuvFieldInfo
, N(LogLuvFieldInfo
)); 
1415         sp
->vgetparent 
= tif
->tif_vgetfield
; 
1416         tif
->tif_vgetfield 
= LogLuvVGetField
;   /* hook for codec tags */ 
1417         sp
->vsetparent 
= tif
->tif_vsetfield
; 
1418         tif
->tif_vsetfield 
= LogLuvVSetField
;   /* hook for codec tags */ 
1422         TIFFError(module, "%s: No space for LogLuv state block", tif
->tif_name
); 
1425 #endif /* LOGLUV_SUPPORT */