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