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