~ubuntu-branches/ubuntu/jaunty/freeimage/jaunty

« back to all changes in this revision

Viewing changes to FreeImage/Source/LibTIFF/tif_luv.c

  • Committer: Bazaar Package Importer
  • Author(s): Federico Di Gregorio
  • Date: 2007-05-07 15:35:21 UTC
  • Revision ID: james.westby@ubuntu.com-20070507153521-m4lx765bzxxug9qf
Tags: upstream-3.9.3
ImportĀ upstreamĀ versionĀ 3.9.3

Show diffs side-by-side

added added

removed removed

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