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. 
 159 static int LINKAGEMODE
 
 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. 
 216 static int LINKAGEMODE
 
 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. 
 259 static int LINKAGEMODE
 
 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 
 319 static int LINKAGEMODE
 
 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 
 335 static int LINKAGEMODE
 
 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. 
 349 static int LINKAGEMODE
 
 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. 
 437 static int LINKAGEMODE
 
 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. 
 482 static int LINKAGEMODE
 
 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. 
 572 static int LINKAGEMODE
 
 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. 
 587 static int LINKAGEMODE
 
 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 
 612 #define log2(x)         ((1./LOGOF2)*log(x)) 
 615 #define exp2(x)         exp(LOGOF2*(x)) 
 622         int     Le 
= p16 
& 0x7fff; 
 627         Y 
= exp(LOGOF2
/256.*(Le
+.5) - LOGOF2
*64.); 
 638         if (Y 
<= -1.84467e19
) 
 641                 return (int)(256.*(log2(Y
) + 64.)); 
 642         if (Y 
< -5.43571e-20) 
 643                 return (~0x7fff | (int)(256.*(log2(-Y
) + 64.))); 
 648 L16toY(LogLuvState
* sp
, tidata_t op
, int n
) 
 650         int16
* l16 
= (int16
*) sp
->tbuf
; 
 651         float* yp 
= (float*) op
; 
 654                 *yp
++ = pix16toY(*l16
++); 
 658 L16toGry(LogLuvState
* sp
, tidata_t op
, int n
) 
 660         int16
* l16 
= (int16
*) sp
->tbuf
; 
 661         uint8
* gp 
= (uint8
*) op
; 
 664                 double Y 
= pix16toY(*l16
++); 
 665                 *gp
++ = (Y 
<= 0.) ? 0 : (Y 
>= 1.) ? 255 : (int)(256.*sqrt(Y
)); 
 670 L16fromY(LogLuvState
* sp
, tidata_t op
, int n
) 
 672         int16
* l16 
= (int16
*) sp
->tbuf
; 
 673         float* yp 
= (float*) op
; 
 676                 *l16
++ = pix16fromY(*yp
++); 
 680 XYZtoRGB24(float xyz
[3], uint8 rgb
[3]) 
 683                                         /* assume CCIR-709 primaries */ 
 684         r 
=  2.690*xyz
[0] + -1.276*xyz
[1] + -0.414*xyz
[2]; 
 685         g 
= -1.022*xyz
[0] +  1.978*xyz
[1] +  0.044*xyz
[2]; 
 686         b 
=  0.061*xyz
[0] + -0.224*xyz
[1] +  1.163*xyz
[2]; 
 687                                         /* assume 2.0 gamma for speed */ 
 688         /* could use integer sqrt approx., but this is probably faster */ 
 689         rgb
[0] = (r 
<= 0.) ? 0 : (r 
>= 1.) ? 255 : (int)(256.*sqrt(r
)); 
 690         rgb
[1] = (g 
<= 0.) ? 0 : (g 
>= 1.) ? 255 : (int)(256.*sqrt(g
)); 
 691         rgb
[2] = (b 
<= 0.) ? 0 : (b 
>= 1.) ? 255 : (int)(256.*sqrt(b
)); 
 695 uv_encode(double u
, double v
)           /* encode (u',v') coordinates */ 
 701         vi 
= (v 
- UV_VSTART
)*(1./UV_SQSIZ
); 
 704         if (u 
< uv_row
[vi
].ustart
) 
 706         ui 
= (u 
- uv_row
[vi
].ustart
)*(1./UV_SQSIZ
); 
 707         if (ui 
>= uv_row
[vi
].nus
) 
 709         return(uv_row
[vi
].ncum 
+ ui
); 
 713 uv_decode(double *up
, double *vp
, int c
)        /* decode (u',v') index */ 
 718         if (c 
< 0 || c 
>= UV_NDIVS
) 
 720         lower 
= 0;                      /* binary search */ 
 723                 vi 
= (lower 
+ upper
) >> 1; 
 724                 ui 
= c 
- uv_row
[vi
].ncum
; 
 731         } while (upper 
- lower 
> 1); 
 733         ui 
= c 
- uv_row
[vi
].ncum
; 
 734         *up 
= uv_row
[vi
].ustart 
+ (ui
+.5)*UV_SQSIZ
; 
 735         *vp 
= UV_VSTART 
+ (vi
+.5)*UV_SQSIZ
; 
 740 pix24toXYZ(uint32 p
, float XYZ
[3]) 
 743         double  L
, u
, v
, s
, x
, y
; 
 744                                         /* decode luminance */ 
 745         Le 
= p 
>> 14 & 0x3ff; 
 747                 XYZ
[0] = XYZ
[1] = XYZ
[2] = 0.; 
 750         L 
= exp(LOGOF2
/64.*(Le
+.5) - LOGOF2
*12.); 
 753         if (uv_decode(&u
, &v
, Ce
) < 0) { 
 754                 u 
= U_NEU
; v 
= V_NEU
; 
 756         s 
= 1./(6.*u 
- 16.*v 
+ 12.); 
 762         XYZ
[2] = (1.-x
-y
)/y 
* L
; 
 766 pix24fromXYZ(float XYZ
[3]) 
 770                                         /* encode luminance */ 
 774         else if (L 
<= 1./4096.) 
 777                 Le 
= 64.*(log2(L
) + 12.); 
 779         s 
= XYZ
[0] + 15.*XYZ
[1] + 3.*XYZ
[2]; 
 787         Ce 
= uv_encode(u
, v
); 
 789                 Ce 
= uv_encode(U_NEU
, V_NEU
); 
 790                                         /* combine encodings */ 
 791         return (Le 
<< 14 | Ce
); 
 795 Luv24toXYZ(LogLuvState
* sp
, tidata_t op
, int n
) 
 797         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 798         float* xyz 
= (float*) op
; 
 801                 pix24toXYZ(*luv
, xyz
); 
 808 Luv24toLuv48(LogLuvState
* sp
, tidata_t op
, int n
) 
 810         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 811         int16
* luv3 
= (int16
*) op
; 
 816                 *luv3
++ = (*luv 
>> 12 & 0xffd) + 13314; 
 817                 if (uv_decode(&u
, &v
, *luv
&0x3fff) < 0) { 
 821                 *luv3
++ = u 
* (1L<<15); 
 822                 *luv3
++ = v 
* (1L<<15); 
 828 Luv24toRGB(LogLuvState
* sp
, tidata_t op
, int n
) 
 830         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 831         uint8
* rgb 
= (uint8
*) op
; 
 836                 pix24toXYZ(*luv
++, xyz
); 
 837                 XYZtoRGB24(xyz
, rgb
); 
 843 Luv24fromXYZ(LogLuvState
* sp
, tidata_t op
, int n
) 
 845         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 846         float* xyz 
= (float*) op
; 
 849                 *luv
++ = pix24fromXYZ(xyz
); 
 855 Luv24fromLuv48(LogLuvState
* sp
, tidata_t op
, int n
) 
 857         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 858         int16
* luv3 
= (int16
*) op
; 
 865                 else if (luv3
[0] >= (1<<12)+3314) 
 868                         Le 
= (luv3
[0]-3314) >> 2; 
 869                 Ce 
= uv_encode((luv
[1]+.5)/(1<<15), (luv
[2]+.5)/(1<<15)); 
 871                         Ce 
= uv_encode(U_NEU
, V_NEU
); 
 872                 *luv
++ = (uint32
)Le 
<< 14 | Ce
; 
 878 pix32toXYZ(uint32 p
, float XYZ
[3]) 
 880         double  L
, u
, v
, s
, x
, y
; 
 881                                         /* decode luminance */ 
 882         L 
= pix16toY((int)p 
>> 16); 
 884                 XYZ
[0] = XYZ
[1] = XYZ
[2] = 0.; 
 888         u 
= 1./UVSCALE 
* ((p
>>8 & 0xff) + .5); 
 889         v 
= 1./UVSCALE 
* ((p 
& 0xff) + .5); 
 890         s 
= 1./(6.*u 
- 16.*v 
+ 12.); 
 896         XYZ
[2] = (1.-x
-y
)/y 
* L
; 
 900 pix32fromXYZ(float XYZ
[3]) 
 902         unsigned int    Le
, ue
, ve
; 
 904                                         /* encode luminance */ 
 905         Le 
= (unsigned int)pix16fromY(XYZ
[1]); 
 907         s 
= XYZ
[0] + 15.*XYZ
[1] + 3.*XYZ
[2]; 
 916         else ue 
= UVSCALE 
* u
; 
 917         if (ue 
> 255) ue 
= 255; 
 919         else ve 
= UVSCALE 
* v
; 
 920         if (ve 
> 255) ve 
= 255; 
 921                                         /* combine encodings */ 
 922         return (Le 
<< 16 | ue 
<< 8 | ve
); 
 926 Luv32toXYZ(LogLuvState
* sp
, tidata_t op
, int n
) 
 928         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 929         float* xyz 
= (float*) op
; 
 932                 pix32toXYZ(*luv
++, xyz
); 
 938 Luv32toLuv48(LogLuvState
* sp
, tidata_t op
, int n
) 
 940         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 941         int16
* luv3 
= (int16
*) op
; 
 946                 *luv3
++ = *luv 
>> 16; 
 947                 u 
= 1./UVSCALE 
* ((*luv
>>8 & 0xff) + .5); 
 948                 v 
= 1./UVSCALE 
* ((*luv 
& 0xff) + .5); 
 949                 *luv3
++ = u 
* (1L<<15); 
 950                 *luv3
++ = v 
* (1L<<15); 
 956 Luv32toRGB(LogLuvState
* sp
, tidata_t op
, int n
) 
 958         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 959         uint8
* rgb 
= (uint8
*) op
; 
 964                 pix32toXYZ(*luv
++, xyz
); 
 965                 XYZtoRGB24(xyz
, rgb
); 
 971 Luv32fromXYZ(LogLuvState
* sp
, tidata_t op
, int n
) 
 973         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 974         float* xyz 
= (float*) op
; 
 977                 *luv
++ = pix32fromXYZ(xyz
); 
 983 Luv32fromLuv48(LogLuvState
* sp
, tidata_t op
, int n
) 
 985         uint32
* luv 
= (uint32
*) sp
->tbuf
; 
 986         int16
* luv3 
= (int16
*) op
; 
 989                 *luv
++ = (uint32
)luv3
[0] << 16 | 
 990                         (luv3
[1]*(uint32
)(UVSCALE
+.5) >> 7 & 0xff00) | 
 991                         (luv3
[2]*(uint32
)(UVSCALE
+.5) >> 15 & 0xff); 
 997 _logLuvNop(LogLuvState
* sp
, tidata_t op
, int n
) 
 999         (void) sp
; (void) op
; (void) n
; 
1003 LogL16GuessDataFmt(TIFFDirectory 
*td
) 
1005 #define PACK(s,b,f)     (((b)<<6)|((s)<<3)|(f)) 
1006         switch (PACK(td
->td_samplesperpixel
, td
->td_bitspersample
, td
->td_sampleformat
)) { 
1007         case PACK(1, 32, SAMPLEFORMAT_IEEEFP
): 
1008                 return (SGILOGDATAFMT_FLOAT
); 
1009         case PACK(1, 16, SAMPLEFORMAT_VOID
): 
1010         case PACK(1, 16, SAMPLEFORMAT_INT
): 
1011         case PACK(1, 16, SAMPLEFORMAT_UINT
): 
1012                 return (SGILOGDATAFMT_16BIT
); 
1013         case PACK(1,  8, SAMPLEFORMAT_VOID
): 
1014         case PACK(1,  8, SAMPLEFORMAT_UINT
): 
1015                 return (SGILOGDATAFMT_8BIT
); 
1018         return (SGILOGDATAFMT_UNKNOWN
); 
1022 LogL16InitState(TIFF
* tif
) 
1024         TIFFDirectory 
*td 
= &tif
->tif_dir
; 
1025         LogLuvState
* sp 
= DecoderState(tif
); 
1026         static const char module[] = "LogL16InitState"; 
1029         assert(td
->td_photometric 
== PHOTOMETRIC_LOGL
); 
1031         /* for some reason, we can't do this in TIFFInitLogL16 */ 
1032         if (sp
->user_datafmt 
== SGILOGDATAFMT_UNKNOWN
) 
1033                 sp
->user_datafmt 
= LogL16GuessDataFmt(td
); 
1034         switch (sp
->user_datafmt
) { 
1035         case SGILOGDATAFMT_FLOAT
: 
1036                 sp
->pixel_size 
= sizeof (float); 
1038         case SGILOGDATAFMT_16BIT
: 
1039                 sp
->pixel_size 
= sizeof (int16
); 
1041         case SGILOGDATAFMT_8BIT
: 
1042                 sp
->pixel_size 
= sizeof (uint8
); 
1045                 TIFFError(tif
->tif_name
, 
1046                     "No support for converting user data format to LogL"); 
1049         sp
->tbuflen 
= td
->td_imagewidth 
* td
->td_rowsperstrip
; 
1050         sp
->tbuf 
= (tidata_t
*) _TIFFmalloc(sp
->tbuflen 
* sizeof (int16
)); 
1051         if (sp
->tbuf 
== NULL
) { 
1052                 TIFFError(module, "%s: No space for SGILog translation buffer", 
1060 LogLuvGuessDataFmt(TIFFDirectory 
*td
) 
1065          * If the user didn't tell us their datafmt, 
1066          * take our best guess from the bitspersample. 
1068 #define PACK(a,b)       (((a)<<3)|(b)) 
1069         switch (PACK(td
->td_bitspersample
, td
->td_sampleformat
)) { 
1070         case PACK(32, SAMPLEFORMAT_IEEEFP
): 
1071                 guess 
= SGILOGDATAFMT_FLOAT
; 
1073         case PACK(32, SAMPLEFORMAT_VOID
): 
1074         case PACK(32, SAMPLEFORMAT_UINT
): 
1075         case PACK(32, SAMPLEFORMAT_INT
): 
1076                 guess 
= SGILOGDATAFMT_RAW
; 
1078         case PACK(16, SAMPLEFORMAT_VOID
): 
1079         case PACK(16, SAMPLEFORMAT_INT
): 
1080         case PACK(16, SAMPLEFORMAT_UINT
): 
1081                 guess 
= SGILOGDATAFMT_16BIT
; 
1083         case PACK( 8, SAMPLEFORMAT_VOID
): 
1084         case PACK( 8, SAMPLEFORMAT_UINT
): 
1085                 guess 
= SGILOGDATAFMT_8BIT
; 
1088                 guess 
= SGILOGDATAFMT_UNKNOWN
; 
1093          * Double-check samples per pixel. 
1095         switch (td
->td_samplesperpixel
) { 
1097                 if (guess 
!= SGILOGDATAFMT_RAW
) 
1098                         guess 
= SGILOGDATAFMT_UNKNOWN
; 
1101                 if (guess 
== SGILOGDATAFMT_RAW
) 
1102                         guess 
= SGILOGDATAFMT_UNKNOWN
; 
1105                 guess 
= SGILOGDATAFMT_UNKNOWN
; 
1112 LogLuvInitState(TIFF
* tif
) 
1114         TIFFDirectory
* td 
= &tif
->tif_dir
; 
1115         LogLuvState
* sp 
= DecoderState(tif
); 
1116         static const char module[] = "LogLuvInitState"; 
1119         assert(td
->td_photometric 
== PHOTOMETRIC_LOGLUV
); 
1121         /* for some reason, we can't do this in TIFFInitLogLuv */ 
1122         if (td
->td_planarconfig 
!= PLANARCONFIG_CONTIG
) { 
1124                     "SGILog compression cannot handle non-contiguous data"); 
1127         if (sp
->user_datafmt 
== SGILOGDATAFMT_UNKNOWN
) 
1128                 sp
->user_datafmt 
= LogLuvGuessDataFmt(td
); 
1129         switch (sp
->user_datafmt
) { 
1130         case SGILOGDATAFMT_FLOAT
: 
1131                 sp
->pixel_size 
= 3*sizeof (float); 
1133         case SGILOGDATAFMT_16BIT
: 
1134                 sp
->pixel_size 
= 3*sizeof (int16
); 
1136         case SGILOGDATAFMT_RAW
: 
1137                 sp
->pixel_size 
= sizeof (uint32
); 
1139         case SGILOGDATAFMT_8BIT
: 
1140                 sp
->pixel_size 
= 3*sizeof (uint8
); 
1143                 TIFFError(tif
->tif_name
, 
1144                     "No support for converting user data format to LogLuv"); 
1147         sp
->tbuflen 
= td
->td_imagewidth 
* td
->td_rowsperstrip
; 
1148         sp
->tbuf 
= (tidata_t
*) _TIFFmalloc(sp
->tbuflen 
* sizeof (uint32
)); 
1149         if (sp
->tbuf 
== NULL
) { 
1150                 TIFFError(module, "%s: No space for SGILog translation buffer", 
1158 LogLuvSetupDecode(TIFF
* tif
) 
1160         LogLuvState
* sp 
= DecoderState(tif
); 
1161         TIFFDirectory
* td 
= &tif
->tif_dir
; 
1163         tif
->tif_postdecode 
= _TIFFNoPostDecode
; 
1164         switch (td
->td_photometric
) { 
1165         case PHOTOMETRIC_LOGLUV
: 
1166                 if (!LogLuvInitState(tif
)) 
1168                 if (td
->td_compression 
== COMPRESSION_SGILOG24
) { 
1169                         tif
->tif_decoderow 
= LogLuvDecode24
; 
1170                         switch (sp
->user_datafmt
) { 
1171                         case SGILOGDATAFMT_FLOAT
: 
1172                                 sp
->tfunc 
= Luv24toXYZ
; 
1174                         case SGILOGDATAFMT_16BIT
: 
1175                                 sp
->tfunc 
= Luv24toLuv48
; 
1177                         case SGILOGDATAFMT_8BIT
: 
1178                                 sp
->tfunc 
= Luv24toRGB
; 
1182                         tif
->tif_decoderow 
= LogLuvDecode32
; 
1183                         switch (sp
->user_datafmt
) { 
1184                         case SGILOGDATAFMT_FLOAT
: 
1185                                 sp
->tfunc 
= Luv32toXYZ
; 
1187                         case SGILOGDATAFMT_16BIT
: 
1188                                 sp
->tfunc 
= Luv32toLuv48
; 
1190                         case SGILOGDATAFMT_8BIT
: 
1191                                 sp
->tfunc 
= Luv32toRGB
; 
1196         case PHOTOMETRIC_LOGL
: 
1197                 if (!LogL16InitState(tif
)) 
1199                 tif
->tif_decoderow 
= LogL16Decode
; 
1200                 switch (sp
->user_datafmt
) { 
1201                 case SGILOGDATAFMT_FLOAT
: 
1204                 case SGILOGDATAFMT_8BIT
: 
1205                         sp
->tfunc 
= L16toGry
; 
1210                 TIFFError(tif
->tif_name
, 
1211     "Inappropriate photometric interpretation %d for SGILog compression; %s", 
1212                     td
->td_photometric
, "must be either LogLUV or LogL"); 
1219 LogLuvSetupEncode(TIFF
* tif
) 
1221         LogLuvState
* sp 
= EncoderState(tif
); 
1222         TIFFDirectory
* td 
= &tif
->tif_dir
; 
1224         switch (td
->td_photometric
) { 
1225         case PHOTOMETRIC_LOGLUV
: 
1226                 if (!LogLuvInitState(tif
)) 
1228                 if (td
->td_compression 
== COMPRESSION_SGILOG24
) { 
1229                         tif
->tif_encoderow 
= LogLuvEncode24
; 
1230                         switch (sp
->user_datafmt
) { 
1231                         case SGILOGDATAFMT_FLOAT
: 
1232                                 sp
->tfunc 
= Luv24fromXYZ
; 
1234                         case SGILOGDATAFMT_16BIT
: 
1235                                 sp
->tfunc 
= Luv24fromLuv48
; 
1237                         case SGILOGDATAFMT_RAW
: 
1243                         tif
->tif_encoderow 
= LogLuvEncode32
; 
1244                         switch (sp
->user_datafmt
) { 
1245                         case SGILOGDATAFMT_FLOAT
: 
1246                                 sp
->tfunc 
= Luv32fromXYZ
; 
1248                         case SGILOGDATAFMT_16BIT
: 
1249                                 sp
->tfunc 
= Luv32fromLuv48
; 
1251                         case SGILOGDATAFMT_RAW
: 
1258         case PHOTOMETRIC_LOGL
: 
1259                 if (!LogL16InitState(tif
)) 
1261                 tif
->tif_encoderow 
= LogL16Encode
; 
1262                 switch (sp
->user_datafmt
) { 
1263                 case SGILOGDATAFMT_FLOAT
: 
1264                         sp
->tfunc 
= L16fromY
; 
1266                 case SGILOGDATAFMT_16BIT
: 
1273                 TIFFError(tif
->tif_name
, 
1274     "Inappropriate photometric interpretation %d for SGILog compression; %s", 
1275                     td
->td_photometric
, "must be either LogLUV or LogL"); 
1280         TIFFError(tif
->tif_name
, 
1281             "SGILog compression supported only for %s, or raw data", 
1282             td
->td_photometric 
== PHOTOMETRIC_LOGL 
? "Y, L" : "XYZ, Luv"); 
1287 LogLuvClose(TIFF
* tif
) 
1289         TIFFDirectory 
*td 
= &tif
->tif_dir
; 
1292          * For consistency, we always want to write out the same 
1293          * bitspersample and sampleformat for our TIFF file, 
1294          * regardless of the data format being used by the application. 
1295          * Since this routine is called after tags have been set but 
1296          * before they have been recorded in the file, we reset them here. 
1298         td
->td_samplesperpixel 
= 
1299             (td
->td_photometric 
== PHOTOMETRIC_LOGL
) ? 1 : 3; 
1300         td
->td_bitspersample 
= 16; 
1301         td
->td_sampleformat 
= SAMPLEFORMAT_INT
; 
1305 LogLuvCleanup(TIFF
* tif
) 
1307         LogLuvState
* sp 
= (LogLuvState 
*)tif
->tif_data
; 
1311                         _TIFFfree(sp
->tbuf
); 
1313                 tif
->tif_data 
= NULL
; 
1318 LogLuvVSetField(TIFF
* tif
, ttag_t tag
, va_list ap
) 
1320         LogLuvState
* sp 
= DecoderState(tif
); 
1324         case TIFFTAG_SGILOGDATAFMT
: 
1325                 sp
->user_datafmt 
= va_arg(ap
, int); 
1327                  * Tweak the TIFF header so that the rest of libtiff knows what 
1328                  * size of data will be passed between app and library, and 
1329                  * assume that the app knows what it is doing and is not 
1330                  * confused by these header manipulations... 
1332                 switch (sp
->user_datafmt
) { 
1333                 case SGILOGDATAFMT_FLOAT
: 
1334                         bps 
= 32, fmt 
= SAMPLEFORMAT_IEEEFP
; 
1336                 case SGILOGDATAFMT_16BIT
: 
1337                         bps 
= 16, fmt 
= SAMPLEFORMAT_INT
; 
1339                 case SGILOGDATAFMT_RAW
: 
1340                         bps 
= 32, fmt 
= SAMPLEFORMAT_UINT
; 
1342                 case SGILOGDATAFMT_8BIT
: 
1343                         bps 
= 8, fmt 
= SAMPLEFORMAT_UINT
; 
1346                         TIFFError(tif
->tif_name
, 
1347                             "Unknown data format %d for LogLuv compression", 
1351                 TIFFSetField(tif
, TIFFTAG_BITSPERSAMPLE
, bps
); 
1352                 TIFFSetField(tif
, TIFFTAG_SAMPLEFORMAT
, fmt
); 
1354                  * Must recalculate sizes should bits/sample change. 
1356                 tif
->tif_tilesize 
= TIFFTileSize(tif
); 
1357                 tif
->tif_scanlinesize 
= TIFFScanlineSize(tif
); 
1360                 return (*sp
->vsetparent
)(tif
, tag
, ap
); 
1365 LogLuvVGetField(TIFF
* tif
, ttag_t tag
, va_list ap
) 
1367         LogLuvState 
*sp 
= (LogLuvState 
*)tif
->tif_data
; 
1370         case TIFFTAG_SGILOGDATAFMT
: 
1371                 *va_arg(ap
, int*) = sp
->user_datafmt
; 
1374                 return (*sp
->vgetparent
)(tif
, tag
, ap
); 
1378 static const TIFFFieldInfo LogLuvFieldInfo
[] = { 
1379     { TIFFTAG_SGILOGDATAFMT
,      0, 0, TIFF_SHORT
,     FIELD_PSEUDO
, 
1380       TRUE
,     FALSE
,  "SGILogDataFmt"} 
1384 TIFFInitSGILog(TIFF
* tif
, int scheme
) 
1386         static const char module[] = "TIFFInitSGILog"; 
1389         assert(scheme 
== COMPRESSION_SGILOG24 
|| scheme 
== COMPRESSION_SGILOG
); 
1392          * Allocate state block so tag methods have storage to record values. 
1394         tif
->tif_data 
= (tidata_t
) _TIFFmalloc(sizeof (LogLuvState
)); 
1395         if (tif
->tif_data 
== NULL
) 
1397         sp 
= (LogLuvState
*) tif
->tif_data
; 
1398         memset(sp
, 0, sizeof (*sp
)); 
1399         sp
->user_datafmt 
= SGILOGDATAFMT_UNKNOWN
; 
1400         sp
->tfunc 
= _logLuvNop
; 
1403          * Install codec methods. 
1404          * NB: tif_decoderow & tif_encoderow are filled 
1407         tif
->tif_setupdecode 
= LogLuvSetupDecode
; 
1408         tif
->tif_decodestrip 
= LogLuvDecodeStrip
; 
1409         tif
->tif_decodetile 
= LogLuvDecodeTile
; 
1410         tif
->tif_setupencode 
= LogLuvSetupEncode
; 
1411         tif
->tif_encodestrip 
= LogLuvEncodeStrip
; 
1412         tif
->tif_encodetile 
= LogLuvEncodeTile
; 
1413         tif
->tif_close 
= LogLuvClose
; 
1414         tif
->tif_cleanup 
= LogLuvCleanup
; 
1416         /* override SetField so we can handle our private pseudo-tag */ 
1417         _TIFFMergeFieldInfo(tif
, LogLuvFieldInfo
, N(LogLuvFieldInfo
)); 
1418         sp
->vgetparent 
= tif
->tif_vgetfield
; 
1419         tif
->tif_vgetfield 
= LogLuvVGetField
;   /* hook for codec tags */ 
1420         sp
->vsetparent 
= tif
->tif_vsetfield
; 
1421         tif
->tif_vsetfield 
= LogLuvVSetField
;   /* hook for codec tags */ 
1425         TIFFError(module, "%s: No space for LogLuv state block", tif
->tif_name
); 
1428 #endif /* LOGLUV_SUPPORT */