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 */