Home | History | Annotate | Download | only in libtiff
      1 /* $Id: tif_pixarlog.c,v 1.37 2012-05-24 23:21:45 fwarmerdam Exp $ */
      2 
      3 /*
      4  * Copyright (c) 1996-1997 Sam Leffler
      5  * Copyright (c) 1996 Pixar
      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  * Pixar, Sam Leffler and Silicon Graphics may not be used in any advertising or
     12  * publicity relating to the software without the specific, prior written
     13  * permission of Pixar, Sam Leffler 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 PIXAR, SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
     20  * 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 PIXARLOG_SUPPORT
     29 
     30 /*
     31  * TIFF Library.
     32  * PixarLog Compression Support
     33  *
     34  * Contributed by Dan McCoy.
     35  *
     36  * PixarLog film support uses the TIFF library to store companded
     37  * 11 bit values into a tiff file, which are compressed using the
     38  * zip compressor.
     39  *
     40  * The codec can take as input and produce as output 32-bit IEEE float values
     41  * as well as 16-bit or 8-bit unsigned integer values.
     42  *
     43  * On writing any of the above are converted into the internal
     44  * 11-bit log format.   In the case of  8 and 16 bit values, the
     45  * input is assumed to be unsigned linear color values that represent
     46  * the range 0-1.  In the case of IEEE values, the 0-1 range is assumed to
     47  * be the normal linear color range, in addition over 1 values are
     48  * accepted up to a value of about 25.0 to encode "hot" hightlights and such.
     49  * The encoding is lossless for 8-bit values, slightly lossy for the
     50  * other bit depths.  The actual color precision should be better
     51  * than the human eye can perceive with extra room to allow for
     52  * error introduced by further image computation.  As with any quantized
     53  * color format, it is possible to perform image calculations which
     54  * expose the quantization error. This format should certainly be less
     55  * susceptable to such errors than standard 8-bit encodings, but more
     56  * susceptable than straight 16-bit or 32-bit encodings.
     57  *
     58  * On reading the internal format is converted to the desired output format.
     59  * The program can request which format it desires by setting the internal
     60  * pseudo tag TIFFTAG_PIXARLOGDATAFMT to one of these possible values:
     61  *  PIXARLOGDATAFMT_FLOAT     = provide IEEE float values.
     62  *  PIXARLOGDATAFMT_16BIT     = provide unsigned 16-bit integer values
     63  *  PIXARLOGDATAFMT_8BIT      = provide unsigned 8-bit integer values
     64  *
     65  * alternately PIXARLOGDATAFMT_8BITABGR provides unsigned 8-bit integer
     66  * values with the difference that if there are exactly three or four channels
     67  * (rgb or rgba) it swaps the channel order (bgr or abgr).
     68  *
     69  * PIXARLOGDATAFMT_11BITLOG provides the internal encoding directly
     70  * packed in 16-bit values.   However no tools are supplied for interpreting
     71  * these values.
     72  *
     73  * "hot" (over 1.0) areas written in floating point get clamped to
     74  * 1.0 in the integer data types.
     75  *
     76  * When the file is closed after writing, the bit depth and sample format
     77  * are set always to appear as if 8-bit data has been written into it.
     78  * That way a naive program unaware of the particulars of the encoding
     79  * gets the format it is most likely able to handle.
     80  *
     81  * The codec does it's own horizontal differencing step on the coded
     82  * values so the libraries predictor stuff should be turned off.
     83  * The codec also handle byte swapping the encoded values as necessary
     84  * since the library does not have the information necessary
     85  * to know the bit depth of the raw unencoded buffer.
     86  *
     87  * NOTE: This decoder does not appear to update tif_rawcp, and tif_rawcc.
     88  * This can cause problems with the implementation of CHUNKY_STRIP_READ_SUPPORT
     89  * as noted in http://trac.osgeo.org/gdal/ticket/3894.   FrankW - Jan'11
     90  */
     91 
     92 #include "tif_predict.h"
     93 #include "zlib.h"
     94 
     95 #include <stdio.h>
     96 #include <stdlib.h>
     97 #include <math.h>
     98 
     99 /* Tables for converting to/from 11 bit coded values */
    100 
    101 #define  TSIZE	 2048		/* decode table size (11-bit tokens) */
    102 #define  TSIZEP1 2049		/* Plus one for slop */
    103 #define  ONE	 1250		/* token value of 1.0 exactly */
    104 #define  RATIO	 1.004		/* nominal ratio for log part */
    105 
    106 #define CODE_MASK 0x7ff         /* 11 bits. */
    107 
    108 static float  Fltsize;
    109 static float  LogK1, LogK2;
    110 
    111 #define REPEAT(n, op)   { int i; i=n; do { i--; op; } while (i>0); }
    112 
    113 static void
    114 horizontalAccumulateF(uint16 *wp, int n, int stride, float *op,
    115     float *ToLinearF)
    116 {
    117     register unsigned int  cr, cg, cb, ca, mask;
    118     register float  t0, t1, t2, t3;
    119 
    120     if (n >= stride) {
    121     mask = CODE_MASK;
    122     if (stride == 3) {
    123         t0 = ToLinearF[cr = (wp[0] & mask)];
    124         t1 = ToLinearF[cg = (wp[1] & mask)];
    125         t2 = ToLinearF[cb = (wp[2] & mask)];
    126         op[0] = t0;
    127         op[1] = t1;
    128         op[2] = t2;
    129         n -= 3;
    130         while (n > 0) {
    131         wp += 3;
    132         op += 3;
    133         n -= 3;
    134         t0 = ToLinearF[(cr += wp[0]) & mask];
    135         t1 = ToLinearF[(cg += wp[1]) & mask];
    136         t2 = ToLinearF[(cb += wp[2]) & mask];
    137         op[0] = t0;
    138         op[1] = t1;
    139         op[2] = t2;
    140         }
    141     } else if (stride == 4) {
    142         t0 = ToLinearF[cr = (wp[0] & mask)];
    143         t1 = ToLinearF[cg = (wp[1] & mask)];
    144         t2 = ToLinearF[cb = (wp[2] & mask)];
    145         t3 = ToLinearF[ca = (wp[3] & mask)];
    146         op[0] = t0;
    147         op[1] = t1;
    148         op[2] = t2;
    149         op[3] = t3;
    150         n -= 4;
    151         while (n > 0) {
    152         wp += 4;
    153         op += 4;
    154         n -= 4;
    155         t0 = ToLinearF[(cr += wp[0]) & mask];
    156         t1 = ToLinearF[(cg += wp[1]) & mask];
    157         t2 = ToLinearF[(cb += wp[2]) & mask];
    158         t3 = ToLinearF[(ca += wp[3]) & mask];
    159         op[0] = t0;
    160         op[1] = t1;
    161         op[2] = t2;
    162         op[3] = t3;
    163         }
    164     } else {
    165         REPEAT(stride, *op = ToLinearF[*wp&mask]; wp++; op++)
    166         n -= stride;
    167         while (n > 0) {
    168         REPEAT(stride,
    169             wp[stride] += *wp; *op = ToLinearF[*wp&mask]; wp++; op++)
    170         n -= stride;
    171         }
    172     }
    173     }
    174 }
    175 
    176 static void
    177 horizontalAccumulate12(uint16 *wp, int n, int stride, int16 *op,
    178     float *ToLinearF)
    179 {
    180     register unsigned int  cr, cg, cb, ca, mask;
    181     register float  t0, t1, t2, t3;
    182 
    183 #define SCALE12 2048.0F
    184 #define CLAMP12(t) (((t) < 3071) ? (uint16) (t) : 3071)
    185 
    186     if (n >= stride) {
    187     mask = CODE_MASK;
    188     if (stride == 3) {
    189         t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12;
    190         t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12;
    191         t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12;
    192         op[0] = CLAMP12(t0);
    193         op[1] = CLAMP12(t1);
    194         op[2] = CLAMP12(t2);
    195         n -= 3;
    196         while (n > 0) {
    197         wp += 3;
    198         op += 3;
    199         n -= 3;
    200         t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
    201         t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
    202         t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
    203         op[0] = CLAMP12(t0);
    204         op[1] = CLAMP12(t1);
    205         op[2] = CLAMP12(t2);
    206         }
    207     } else if (stride == 4) {
    208         t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12;
    209         t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12;
    210         t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12;
    211         t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12;
    212         op[0] = CLAMP12(t0);
    213         op[1] = CLAMP12(t1);
    214         op[2] = CLAMP12(t2);
    215         op[3] = CLAMP12(t3);
    216         n -= 4;
    217         while (n > 0) {
    218         wp += 4;
    219         op += 4;
    220         n -= 4;
    221         t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
    222         t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
    223         t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
    224         t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12;
    225         op[0] = CLAMP12(t0);
    226         op[1] = CLAMP12(t1);
    227         op[2] = CLAMP12(t2);
    228         op[3] = CLAMP12(t3);
    229         }
    230     } else {
    231         REPEAT(stride, t0 = ToLinearF[*wp&mask] * SCALE12;
    232                            *op = CLAMP12(t0); wp++; op++)
    233         n -= stride;
    234         while (n > 0) {
    235         REPEAT(stride,
    236             wp[stride] += *wp; t0 = ToLinearF[wp[stride]&mask]*SCALE12;
    237             *op = CLAMP12(t0);  wp++; op++)
    238         n -= stride;
    239         }
    240     }
    241     }
    242 }
    243 
    244 static void
    245 horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op,
    246     uint16 *ToLinear16)
    247 {
    248     register unsigned int  cr, cg, cb, ca, mask;
    249 
    250     if (n >= stride) {
    251     mask = CODE_MASK;
    252     if (stride == 3) {
    253         op[0] = ToLinear16[cr = (wp[0] & mask)];
    254         op[1] = ToLinear16[cg = (wp[1] & mask)];
    255         op[2] = ToLinear16[cb = (wp[2] & mask)];
    256         n -= 3;
    257         while (n > 0) {
    258         wp += 3;
    259         op += 3;
    260         n -= 3;
    261         op[0] = ToLinear16[(cr += wp[0]) & mask];
    262         op[1] = ToLinear16[(cg += wp[1]) & mask];
    263         op[2] = ToLinear16[(cb += wp[2]) & mask];
    264         }
    265     } else if (stride == 4) {
    266         op[0] = ToLinear16[cr = (wp[0] & mask)];
    267         op[1] = ToLinear16[cg = (wp[1] & mask)];
    268         op[2] = ToLinear16[cb = (wp[2] & mask)];
    269         op[3] = ToLinear16[ca = (wp[3] & mask)];
    270         n -= 4;
    271         while (n > 0) {
    272         wp += 4;
    273         op += 4;
    274         n -= 4;
    275         op[0] = ToLinear16[(cr += wp[0]) & mask];
    276         op[1] = ToLinear16[(cg += wp[1]) & mask];
    277         op[2] = ToLinear16[(cb += wp[2]) & mask];
    278         op[3] = ToLinear16[(ca += wp[3]) & mask];
    279         }
    280     } else {
    281         REPEAT(stride, *op = ToLinear16[*wp&mask]; wp++; op++)
    282         n -= stride;
    283         while (n > 0) {
    284         REPEAT(stride,
    285             wp[stride] += *wp; *op = ToLinear16[*wp&mask]; wp++; op++)
    286         n -= stride;
    287         }
    288     }
    289     }
    290 }
    291 
    292 /*
    293  * Returns the log encoded 11-bit values with the horizontal
    294  * differencing undone.
    295  */
    296 static void
    297 horizontalAccumulate11(uint16 *wp, int n, int stride, uint16 *op)
    298 {
    299     register unsigned int  cr, cg, cb, ca, mask;
    300 
    301     if (n >= stride) {
    302     mask = CODE_MASK;
    303     if (stride == 3) {
    304         op[0] = cr = wp[0];  op[1] = cg = wp[1];  op[2] = cb = wp[2];
    305         n -= 3;
    306         while (n > 0) {
    307         wp += 3;
    308         op += 3;
    309         n -= 3;
    310         op[0] = (cr += wp[0]) & mask;
    311         op[1] = (cg += wp[1]) & mask;
    312         op[2] = (cb += wp[2]) & mask;
    313         }
    314     } else if (stride == 4) {
    315         op[0] = cr = wp[0];  op[1] = cg = wp[1];
    316         op[2] = cb = wp[2];  op[3] = ca = wp[3];
    317         n -= 4;
    318         while (n > 0) {
    319         wp += 4;
    320         op += 4;
    321         n -= 4;
    322         op[0] = (cr += wp[0]) & mask;
    323         op[1] = (cg += wp[1]) & mask;
    324         op[2] = (cb += wp[2]) & mask;
    325         op[3] = (ca += wp[3]) & mask;
    326         }
    327     } else {
    328         REPEAT(stride, *op = *wp&mask; wp++; op++)
    329         n -= stride;
    330         while (n > 0) {
    331         REPEAT(stride,
    332             wp[stride] += *wp; *op = *wp&mask; wp++; op++)
    333         n -= stride;
    334         }
    335     }
    336     }
    337 }
    338 
    339 static void
    340 horizontalAccumulate8(uint16 *wp, int n, int stride, unsigned char *op,
    341     unsigned char *ToLinear8)
    342 {
    343     register unsigned int  cr, cg, cb, ca, mask;
    344 
    345     if (n >= stride) {
    346     mask = CODE_MASK;
    347     if (stride == 3) {
    348         op[0] = ToLinear8[cr = (wp[0] & mask)];
    349         op[1] = ToLinear8[cg = (wp[1] & mask)];
    350         op[2] = ToLinear8[cb = (wp[2] & mask)];
    351         n -= 3;
    352         while (n > 0) {
    353         n -= 3;
    354         wp += 3;
    355         op += 3;
    356         op[0] = ToLinear8[(cr += wp[0]) & mask];
    357         op[1] = ToLinear8[(cg += wp[1]) & mask];
    358         op[2] = ToLinear8[(cb += wp[2]) & mask];
    359         }
    360     } else if (stride == 4) {
    361         op[0] = ToLinear8[cr = (wp[0] & mask)];
    362         op[1] = ToLinear8[cg = (wp[1] & mask)];
    363         op[2] = ToLinear8[cb = (wp[2] & mask)];
    364         op[3] = ToLinear8[ca = (wp[3] & mask)];
    365         n -= 4;
    366         while (n > 0) {
    367         n -= 4;
    368         wp += 4;
    369         op += 4;
    370         op[0] = ToLinear8[(cr += wp[0]) & mask];
    371         op[1] = ToLinear8[(cg += wp[1]) & mask];
    372         op[2] = ToLinear8[(cb += wp[2]) & mask];
    373         op[3] = ToLinear8[(ca += wp[3]) & mask];
    374         }
    375     } else {
    376         REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)
    377         n -= stride;
    378         while (n > 0) {
    379         REPEAT(stride,
    380             wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
    381         n -= stride;
    382         }
    383     }
    384     }
    385 }
    386 
    387 
    388 static void
    389 horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op,
    390     unsigned char *ToLinear8)
    391 {
    392     register unsigned int  cr, cg, cb, ca, mask;
    393     register unsigned char  t0, t1, t2, t3;
    394 
    395     if (n >= stride) {
    396     mask = CODE_MASK;
    397     if (stride == 3) {
    398         op[0] = 0;
    399         t1 = ToLinear8[cb = (wp[2] & mask)];
    400         t2 = ToLinear8[cg = (wp[1] & mask)];
    401         t3 = ToLinear8[cr = (wp[0] & mask)];
    402         op[1] = t1;
    403         op[2] = t2;
    404         op[3] = t3;
    405         n -= 3;
    406         while (n > 0) {
    407         n -= 3;
    408         wp += 3;
    409         op += 4;
    410         op[0] = 0;
    411         t1 = ToLinear8[(cb += wp[2]) & mask];
    412         t2 = ToLinear8[(cg += wp[1]) & mask];
    413         t3 = ToLinear8[(cr += wp[0]) & mask];
    414         op[1] = t1;
    415         op[2] = t2;
    416         op[3] = t3;
    417         }
    418     } else if (stride == 4) {
    419         t0 = ToLinear8[ca = (wp[3] & mask)];
    420         t1 = ToLinear8[cb = (wp[2] & mask)];
    421         t2 = ToLinear8[cg = (wp[1] & mask)];
    422         t3 = ToLinear8[cr = (wp[0] & mask)];
    423         op[0] = t0;
    424         op[1] = t1;
    425         op[2] = t2;
    426         op[3] = t3;
    427         n -= 4;
    428         while (n > 0) {
    429         n -= 4;
    430         wp += 4;
    431         op += 4;
    432         t0 = ToLinear8[(ca += wp[3]) & mask];
    433         t1 = ToLinear8[(cb += wp[2]) & mask];
    434         t2 = ToLinear8[(cg += wp[1]) & mask];
    435         t3 = ToLinear8[(cr += wp[0]) & mask];
    436         op[0] = t0;
    437         op[1] = t1;
    438         op[2] = t2;
    439         op[3] = t3;
    440         }
    441     } else {
    442         REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)
    443         n -= stride;
    444         while (n > 0) {
    445         REPEAT(stride,
    446             wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
    447         n -= stride;
    448         }
    449     }
    450     }
    451 }
    452 
    453 /*
    454  * State block for each open TIFF
    455  * file using PixarLog compression/decompression.
    456  */
    457 typedef	struct {
    458     TIFFPredictorState	predict;
    459     z_stream		stream;
    460     uint16			*tbuf;
    461     uint16			stride;
    462     int			state;
    463     int			user_datafmt;
    464     int			quality;
    465 #define PLSTATE_INIT 1
    466 
    467     TIFFVSetMethod		vgetparent;	/* super-class method */
    468     TIFFVSetMethod		vsetparent;	/* super-class method */
    469 
    470     float *ToLinearF;
    471     uint16 *ToLinear16;
    472     unsigned char *ToLinear8;
    473     uint16  *FromLT2;
    474     uint16  *From14; /* Really for 16-bit data, but we shift down 2 */
    475     uint16  *From8;
    476 
    477 } PixarLogState;
    478 
    479 static int
    480 PixarLogMakeTables(PixarLogState *sp)
    481 {
    482 
    483 /*
    484  *    We make several tables here to convert between various external
    485  *    representations (float, 16-bit, and 8-bit) and the internal
    486  *    11-bit companded representation.  The 11-bit representation has two
    487  *    distinct regions.  A linear bottom end up through .018316 in steps
    488  *    of about .000073, and a region of constant ratio up to about 25.
    489  *    These floating point numbers are stored in the main table ToLinearF.
    490  *    All other tables are derived from this one.  The tables (and the
    491  *    ratios) are continuous at the internal seam.
    492  */
    493 
    494     int  nlin, lt2size;
    495     int  i, j;
    496     double  b, c, linstep, v;
    497     float *ToLinearF;
    498     uint16 *ToLinear16;
    499     unsigned char *ToLinear8;
    500     uint16  *FromLT2;
    501     uint16  *From14; /* Really for 16-bit data, but we shift down 2 */
    502     uint16  *From8;
    503 
    504     c = log(RATIO);
    505     nlin = (int)(1./c);	/* nlin must be an integer */
    506     c = 1./nlin;
    507     b = exp(-c*ONE);	/* multiplicative scale factor [b*exp(c*ONE) = 1] */
    508     linstep = b*c*exp(1.);
    509 
    510     LogK1 = (float)(1./c);	/* if (v >= 2)  token = k1*log(v*k2) */
    511     LogK2 = (float)(1./b);
    512     lt2size = (int)(2./linstep) + 1;
    513     FromLT2 = (uint16 *)_TIFFmalloc(lt2size*sizeof(uint16));
    514     From14 = (uint16 *)_TIFFmalloc(16384*sizeof(uint16));
    515     From8 = (uint16 *)_TIFFmalloc(256*sizeof(uint16));
    516     ToLinearF = (float *)_TIFFmalloc(TSIZEP1 * sizeof(float));
    517     ToLinear16 = (uint16 *)_TIFFmalloc(TSIZEP1 * sizeof(uint16));
    518     ToLinear8 = (unsigned char *)_TIFFmalloc(TSIZEP1 * sizeof(unsigned char));
    519     if (FromLT2 == NULL || From14  == NULL || From8   == NULL ||
    520      ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) {
    521     if (FromLT2) _TIFFfree(FromLT2);
    522     if (From14) _TIFFfree(From14);
    523     if (From8) _TIFFfree(From8);
    524     if (ToLinearF) _TIFFfree(ToLinearF);
    525     if (ToLinear16) _TIFFfree(ToLinear16);
    526     if (ToLinear8) _TIFFfree(ToLinear8);
    527     sp->FromLT2 = NULL;
    528     sp->From14 = NULL;
    529     sp->From8 = NULL;
    530     sp->ToLinearF = NULL;
    531     sp->ToLinear16 = NULL;
    532     sp->ToLinear8 = NULL;
    533     return 0;
    534     }
    535 
    536     j = 0;
    537 
    538     for (i = 0; i < nlin; i++)  {
    539     v = i * linstep;
    540     ToLinearF[j++] = (float)v;
    541     }
    542 
    543     for (i = nlin; i < TSIZE; i++)
    544     ToLinearF[j++] = (float)(b*exp(c*i));
    545 
    546     ToLinearF[2048] = ToLinearF[2047];
    547 
    548     for (i = 0; i < TSIZEP1; i++)  {
    549     v = ToLinearF[i]*65535.0 + 0.5;
    550     ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16)v;
    551     v = ToLinearF[i]*255.0  + 0.5;
    552     ToLinear8[i]  = (v > 255.0) ? 255 : (unsigned char)v;
    553     }
    554 
    555     j = 0;
    556     for (i = 0; i < lt2size; i++)  {
    557     if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1])
    558         j++;
    559     FromLT2[i] = j;
    560     }
    561 
    562     /*
    563      * Since we lose info anyway on 16-bit data, we set up a 14-bit
    564      * table and shift 16-bit values down two bits on input.
    565      * saves a little table space.
    566      */
    567     j = 0;
    568     for (i = 0; i < 16384; i++)  {
    569     while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1])
    570         j++;
    571     From14[i] = j;
    572     }
    573 
    574     j = 0;
    575     for (i = 0; i < 256; i++)  {
    576     while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1])
    577         j++;
    578     From8[i] = j;
    579     }
    580 
    581     Fltsize = (float)(lt2size/2);
    582 
    583     sp->ToLinearF = ToLinearF;
    584     sp->ToLinear16 = ToLinear16;
    585     sp->ToLinear8 = ToLinear8;
    586     sp->FromLT2 = FromLT2;
    587     sp->From14 = From14;
    588     sp->From8 = From8;
    589 
    590     return 1;
    591 }
    592 
    593 #define DecoderState(tif)	((PixarLogState*) (tif)->tif_data)
    594 #define EncoderState(tif)	((PixarLogState*) (tif)->tif_data)
    595 
    596 static int PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
    597 static int PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s);
    598 
    599 #define PIXARLOGDATAFMT_UNKNOWN	-1
    600 
    601 static int
    602 PixarLogGuessDataFmt(TIFFDirectory *td)
    603 {
    604     int guess = PIXARLOGDATAFMT_UNKNOWN;
    605     int format = td->td_sampleformat;
    606 
    607     /* If the user didn't tell us his datafmt,
    608      * take our best guess from the bitspersample.
    609      */
    610     switch (td->td_bitspersample) {
    611      case 32:
    612         if (format == SAMPLEFORMAT_IEEEFP)
    613             guess = PIXARLOGDATAFMT_FLOAT;
    614         break;
    615      case 16:
    616         if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
    617             guess = PIXARLOGDATAFMT_16BIT;
    618         break;
    619      case 12:
    620         if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT)
    621             guess = PIXARLOGDATAFMT_12BITPICIO;
    622         break;
    623      case 11:
    624         if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
    625             guess = PIXARLOGDATAFMT_11BITLOG;
    626         break;
    627      case 8:
    628         if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
    629             guess = PIXARLOGDATAFMT_8BIT;
    630         break;
    631     }
    632 
    633     return guess;
    634 }
    635 
    636 static tmsize_t
    637 multiply_ms(tmsize_t m1, tmsize_t m2)
    638 {
    639     tmsize_t bytes = m1 * m2;
    640 
    641     if (m1 && bytes / m1 != m2)
    642         bytes = 0;
    643 
    644     return bytes;
    645 }
    646 
    647 static int
    648 PixarLogFixupTags(TIFF* tif)
    649 {
    650     (void) tif;
    651     return (1);
    652 }
    653 
    654 static int
    655 PixarLogSetupDecode(TIFF* tif)
    656 {
    657     static const char module[] = "PixarLogSetupDecode";
    658     TIFFDirectory *td = &tif->tif_dir;
    659     PixarLogState* sp = DecoderState(tif);
    660     tmsize_t tbuf_size;
    661 
    662     assert(sp != NULL);
    663 
    664     /* Make sure no byte swapping happens on the data
    665      * after decompression. */
    666     tif->tif_postdecode = _TIFFNoPostDecode;
    667 
    668     /* for some reason, we can't do this in TIFFInitPixarLog */
    669 
    670     sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
    671         td->td_samplesperpixel : 1);
    672     tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth),
    673                       td->td_rowsperstrip), sizeof(uint16));
    674     if (tbuf_size == 0)
    675         return (0);   /* TODO: this is an error return without error report through TIFFErrorExt */
    676     sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size+sizeof(uint16));
    677     if (sp->tbuf == NULL)
    678         return (0);
    679     if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
    680         sp->user_datafmt = PixarLogGuessDataFmt(td);
    681     if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
    682         TIFFErrorExt(tif->tif_clientdata, module,
    683             "PixarLog compression can't handle bits depth/data format combination (depth: %d)",
    684             td->td_bitspersample);
    685         return (0);
    686     }
    687 
    688     if (inflateInit(&sp->stream) != Z_OK) {
    689         TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
    690         return (0);
    691     } else {
    692         sp->state |= PLSTATE_INIT;
    693         return (1);
    694     }
    695 }
    696 
    697 /*
    698  * Setup state for decoding a strip.
    699  */
    700 static int
    701 PixarLogPreDecode(TIFF* tif, uint16 s)
    702 {
    703     static const char module[] = "PixarLogPreDecode";
    704     PixarLogState* sp = DecoderState(tif);
    705 
    706     (void) s;
    707     assert(sp != NULL);
    708     sp->stream.next_in = tif->tif_rawdata;
    709     assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
    710         we need to simplify this code to reflect a ZLib that is likely updated
    711         to deal with 8byte memory sizes, though this code will respond
    712         apropriately even before we simplify it */
    713     sp->stream.avail_in = (uInt) tif->tif_rawcc;
    714     if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
    715     {
    716         TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
    717         return (0);
    718     }
    719     return (inflateReset(&sp->stream) == Z_OK);
    720 }
    721 
    722 static int
    723 PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
    724 {
    725     static const char module[] = "PixarLogDecode";
    726     TIFFDirectory *td = &tif->tif_dir;
    727     PixarLogState* sp = DecoderState(tif);
    728     tmsize_t i;
    729     tmsize_t nsamples;
    730     int llen;
    731     uint16 *up;
    732 
    733     switch (sp->user_datafmt) {
    734     case PIXARLOGDATAFMT_FLOAT:
    735         nsamples = occ / sizeof(float);	/* XXX float == 32 bits */
    736         break;
    737     case PIXARLOGDATAFMT_16BIT:
    738     case PIXARLOGDATAFMT_12BITPICIO:
    739     case PIXARLOGDATAFMT_11BITLOG:
    740         nsamples = occ / sizeof(uint16); /* XXX uint16 == 16 bits */
    741         break;
    742     case PIXARLOGDATAFMT_8BIT:
    743     case PIXARLOGDATAFMT_8BITABGR:
    744         nsamples = occ;
    745         break;
    746     default:
    747         TIFFErrorExt(tif->tif_clientdata, module,
    748             "%d bit input not supported in PixarLog",
    749             td->td_bitspersample);
    750         return 0;
    751     }
    752 
    753     llen = sp->stride * td->td_imagewidth;
    754 
    755     (void) s;
    756     assert(sp != NULL);
    757     sp->stream.next_out = (unsigned char *) sp->tbuf;
    758     assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
    759         we need to simplify this code to reflect a ZLib that is likely updated
    760         to deal with 8byte memory sizes, though this code will respond
    761         apropriately even before we simplify it */
    762     sp->stream.avail_out = (uInt) (nsamples * sizeof(uint16));
    763     if (sp->stream.avail_out != nsamples * sizeof(uint16))
    764     {
    765         TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
    766         return (0);
    767     }
    768     do {
    769         int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
    770         if (state == Z_STREAM_END) {
    771             break;			/* XXX */
    772         }
    773         if (state == Z_DATA_ERROR) {
    774             TIFFErrorExt(tif->tif_clientdata, module,
    775                 "Decoding error at scanline %lu, %s",
    776                 (unsigned long) tif->tif_row, sp->stream.msg);
    777             if (inflateSync(&sp->stream) != Z_OK)
    778                 return (0);
    779             continue;
    780         }
    781         if (state != Z_OK) {
    782             TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
    783                 sp->stream.msg);
    784             return (0);
    785         }
    786     } while (sp->stream.avail_out > 0);
    787 
    788     /* hopefully, we got all the bytes we needed */
    789     if (sp->stream.avail_out != 0) {
    790         TIFFErrorExt(tif->tif_clientdata, module,
    791             "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)",
    792             (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out);
    793         return (0);
    794     }
    795 
    796     up = sp->tbuf;
    797     /* Swap bytes in the data if from a different endian machine. */
    798     if (tif->tif_flags & TIFF_SWAB)
    799         TIFFSwabArrayOfShort(up, nsamples);
    800 
    801     /*
    802      * if llen is not an exact multiple of nsamples, the decode operation
    803      * may overflow the output buffer, so truncate it enough to prevent
    804      * that but still salvage as much data as possible.
    805      */
    806     if (nsamples % llen) {
    807         TIFFWarningExt(tif->tif_clientdata, module,
    808             "stride %lu is not a multiple of sample count, "
    809             "%lu, data truncated.", (unsigned long) llen, (unsigned long) nsamples);
    810         nsamples -= nsamples % llen;
    811     }
    812 
    813     for (i = 0; i < nsamples; i += llen, up += llen) {
    814         switch (sp->user_datafmt)  {
    815         case PIXARLOGDATAFMT_FLOAT:
    816             horizontalAccumulateF(up, llen, sp->stride,
    817                     (float *)op, sp->ToLinearF);
    818             op += llen * sizeof(float);
    819             break;
    820         case PIXARLOGDATAFMT_16BIT:
    821             horizontalAccumulate16(up, llen, sp->stride,
    822                     (uint16 *)op, sp->ToLinear16);
    823             op += llen * sizeof(uint16);
    824             break;
    825         case PIXARLOGDATAFMT_12BITPICIO:
    826             horizontalAccumulate12(up, llen, sp->stride,
    827                     (int16 *)op, sp->ToLinearF);
    828             op += llen * sizeof(int16);
    829             break;
    830         case PIXARLOGDATAFMT_11BITLOG:
    831             horizontalAccumulate11(up, llen, sp->stride,
    832                     (uint16 *)op);
    833             op += llen * sizeof(uint16);
    834             break;
    835         case PIXARLOGDATAFMT_8BIT:
    836             horizontalAccumulate8(up, llen, sp->stride,
    837                     (unsigned char *)op, sp->ToLinear8);
    838             op += llen * sizeof(unsigned char);
    839             break;
    840         case PIXARLOGDATAFMT_8BITABGR:
    841             horizontalAccumulate8abgr(up, llen, sp->stride,
    842                     (unsigned char *)op, sp->ToLinear8);
    843             op += llen * sizeof(unsigned char);
    844             break;
    845         default:
    846             TIFFErrorExt(tif->tif_clientdata, module,
    847                   "Unsupported bits/sample: %d",
    848                   td->td_bitspersample);
    849             return (0);
    850         }
    851     }
    852 
    853     return (1);
    854 }
    855 
    856 static int
    857 PixarLogSetupEncode(TIFF* tif)
    858 {
    859     static const char module[] = "PixarLogSetupEncode";
    860     TIFFDirectory *td = &tif->tif_dir;
    861     PixarLogState* sp = EncoderState(tif);
    862     tmsize_t tbuf_size;
    863 
    864     assert(sp != NULL);
    865 
    866     /* for some reason, we can't do this in TIFFInitPixarLog */
    867 
    868     sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
    869         td->td_samplesperpixel : 1);
    870     tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth),
    871                       td->td_rowsperstrip), sizeof(uint16));
    872     if (tbuf_size == 0)
    873         return (0);  /* TODO: this is an error return without error report through TIFFErrorExt */
    874     sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size);
    875     if (sp->tbuf == NULL)
    876         return (0);
    877     if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
    878         sp->user_datafmt = PixarLogGuessDataFmt(td);
    879     if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
    880         TIFFErrorExt(tif->tif_clientdata, module, "PixarLog compression can't handle %d bit linear encodings", td->td_bitspersample);
    881         return (0);
    882     }
    883 
    884     if (deflateInit(&sp->stream, sp->quality) != Z_OK) {
    885         TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
    886         return (0);
    887     } else {
    888         sp->state |= PLSTATE_INIT;
    889         return (1);
    890     }
    891 }
    892 
    893 /*
    894  * Reset encoding state at the start of a strip.
    895  */
    896 static int
    897 PixarLogPreEncode(TIFF* tif, uint16 s)
    898 {
    899     static const char module[] = "PixarLogPreEncode";
    900     PixarLogState *sp = EncoderState(tif);
    901 
    902     (void) s;
    903     assert(sp != NULL);
    904     sp->stream.next_out = tif->tif_rawdata;
    905     assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
    906         we need to simplify this code to reflect a ZLib that is likely updated
    907         to deal with 8byte memory sizes, though this code will respond
    908         apropriately even before we simplify it */
    909     sp->stream.avail_out = tif->tif_rawdatasize;
    910     if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
    911     {
    912         TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
    913         return (0);
    914     }
    915     return (deflateReset(&sp->stream) == Z_OK);
    916 }
    917 
    918 static void
    919 horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2)
    920 {
    921     int32 r1, g1, b1, a1, r2, g2, b2, a2, mask;
    922     float fltsize = Fltsize;
    923 
    924 #define  CLAMP(v) ( (v<(float)0.)   ? 0				\
    925           : (v<(float)2.)   ? FromLT2[(int)(v*fltsize)]	\
    926           : (v>(float)24.2) ? 2047			\
    927           : LogK1*log(v*LogK2) + 0.5 )
    928 
    929     mask = CODE_MASK;
    930     if (n >= stride) {
    931     if (stride == 3) {
    932         r2 = wp[0] = (uint16) CLAMP(ip[0]);
    933         g2 = wp[1] = (uint16) CLAMP(ip[1]);
    934         b2 = wp[2] = (uint16) CLAMP(ip[2]);
    935         n -= 3;
    936         while (n > 0) {
    937         n -= 3;
    938         wp += 3;
    939         ip += 3;
    940         r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
    941         g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
    942         b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
    943         }
    944     } else if (stride == 4) {
    945         r2 = wp[0] = (uint16) CLAMP(ip[0]);
    946         g2 = wp[1] = (uint16) CLAMP(ip[1]);
    947         b2 = wp[2] = (uint16) CLAMP(ip[2]);
    948         a2 = wp[3] = (uint16) CLAMP(ip[3]);
    949         n -= 4;
    950         while (n > 0) {
    951         n -= 4;
    952         wp += 4;
    953         ip += 4;
    954         r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
    955         g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
    956         b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
    957         a1 = (int32) CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
    958         }
    959     } else {
    960         ip += n - 1;	/* point to last one */
    961         wp += n - 1;	/* point to last one */
    962         n -= stride;
    963         while (n > 0) {
    964         REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]);
    965                 wp[stride] -= wp[0];
    966                 wp[stride] &= mask;
    967                 wp--; ip--)
    968         n -= stride;
    969         }
    970         REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp--; ip--)
    971     }
    972     }
    973 }
    974 
    975 static void
    976 horizontalDifference16(unsigned short *ip, int n, int stride,
    977     unsigned short *wp, uint16 *From14)
    978 {
    979     register int  r1, g1, b1, a1, r2, g2, b2, a2, mask;
    980 
    981 /* assumption is unsigned pixel values */
    982 #undef   CLAMP
    983 #define  CLAMP(v) From14[(v) >> 2]
    984 
    985     mask = CODE_MASK;
    986     if (n >= stride) {
    987     if (stride == 3) {
    988         r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
    989         b2 = wp[2] = CLAMP(ip[2]);
    990         n -= 3;
    991         while (n > 0) {
    992         n -= 3;
    993         wp += 3;
    994         ip += 3;
    995         r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
    996         g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
    997         b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
    998         }
    999     } else if (stride == 4) {
   1000         r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
   1001         b2 = wp[2] = CLAMP(ip[2]);  a2 = wp[3] = CLAMP(ip[3]);
   1002         n -= 4;
   1003         while (n > 0) {
   1004         n -= 4;
   1005         wp += 4;
   1006         ip += 4;
   1007         r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
   1008         g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
   1009         b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
   1010         a1 = CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
   1011         }
   1012     } else {
   1013         ip += n - 1;	/* point to last one */
   1014         wp += n - 1;	/* point to last one */
   1015         n -= stride;
   1016         while (n > 0) {
   1017         REPEAT(stride, wp[0] = CLAMP(ip[0]);
   1018                 wp[stride] -= wp[0];
   1019                 wp[stride] &= mask;
   1020                 wp--; ip--)
   1021         n -= stride;
   1022         }
   1023         REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
   1024     }
   1025     }
   1026 }
   1027 
   1028 
   1029 static void
   1030 horizontalDifference8(unsigned char *ip, int n, int stride,
   1031     unsigned short *wp, uint16 *From8)
   1032 {
   1033     register int  r1, g1, b1, a1, r2, g2, b2, a2, mask;
   1034 
   1035 #undef	 CLAMP
   1036 #define  CLAMP(v) (From8[(v)])
   1037 
   1038     mask = CODE_MASK;
   1039     if (n >= stride) {
   1040     if (stride == 3) {
   1041         r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
   1042         b2 = wp[2] = CLAMP(ip[2]);
   1043         n -= 3;
   1044         while (n > 0) {
   1045         n -= 3;
   1046         r1 = CLAMP(ip[3]); wp[3] = (r1-r2) & mask; r2 = r1;
   1047         g1 = CLAMP(ip[4]); wp[4] = (g1-g2) & mask; g2 = g1;
   1048         b1 = CLAMP(ip[5]); wp[5] = (b1-b2) & mask; b2 = b1;
   1049         wp += 3;
   1050         ip += 3;
   1051         }
   1052     } else if (stride == 4) {
   1053         r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
   1054         b2 = wp[2] = CLAMP(ip[2]);  a2 = wp[3] = CLAMP(ip[3]);
   1055         n -= 4;
   1056         while (n > 0) {
   1057         n -= 4;
   1058         r1 = CLAMP(ip[4]); wp[4] = (r1-r2) & mask; r2 = r1;
   1059         g1 = CLAMP(ip[5]); wp[5] = (g1-g2) & mask; g2 = g1;
   1060         b1 = CLAMP(ip[6]); wp[6] = (b1-b2) & mask; b2 = b1;
   1061         a1 = CLAMP(ip[7]); wp[7] = (a1-a2) & mask; a2 = a1;
   1062         wp += 4;
   1063         ip += 4;
   1064         }
   1065     } else {
   1066         wp += n + stride - 1;	/* point to last one */
   1067         ip += n + stride - 1;	/* point to last one */
   1068         n -= stride;
   1069         while (n > 0) {
   1070         REPEAT(stride, wp[0] = CLAMP(ip[0]);
   1071                 wp[stride] -= wp[0];
   1072                 wp[stride] &= mask;
   1073                 wp--; ip--)
   1074         n -= stride;
   1075         }
   1076         REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
   1077     }
   1078     }
   1079 }
   1080 
   1081 /*
   1082  * Encode a chunk of pixels.
   1083  */
   1084 static int
   1085 PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
   1086 {
   1087     static const char module[] = "PixarLogEncode";
   1088     TIFFDirectory *td = &tif->tif_dir;
   1089     PixarLogState *sp = EncoderState(tif);
   1090     tmsize_t i;
   1091     tmsize_t n;
   1092     int llen;
   1093     unsigned short * up;
   1094 
   1095     (void) s;
   1096 
   1097     switch (sp->user_datafmt) {
   1098     case PIXARLOGDATAFMT_FLOAT:
   1099         n = cc / sizeof(float);		/* XXX float == 32 bits */
   1100         break;
   1101     case PIXARLOGDATAFMT_16BIT:
   1102     case PIXARLOGDATAFMT_12BITPICIO:
   1103     case PIXARLOGDATAFMT_11BITLOG:
   1104         n = cc / sizeof(uint16);	/* XXX uint16 == 16 bits */
   1105         break;
   1106     case PIXARLOGDATAFMT_8BIT:
   1107     case PIXARLOGDATAFMT_8BITABGR:
   1108         n = cc;
   1109         break;
   1110     default:
   1111         TIFFErrorExt(tif->tif_clientdata, module,
   1112             "%d bit input not supported in PixarLog",
   1113             td->td_bitspersample);
   1114         return 0;
   1115     }
   1116 
   1117     llen = sp->stride * td->td_imagewidth;
   1118 
   1119     for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) {
   1120         switch (sp->user_datafmt)  {
   1121         case PIXARLOGDATAFMT_FLOAT:
   1122             horizontalDifferenceF((float *)bp, llen,
   1123                 sp->stride, up, sp->FromLT2);
   1124             bp += llen * sizeof(float);
   1125             break;
   1126         case PIXARLOGDATAFMT_16BIT:
   1127             horizontalDifference16((uint16 *)bp, llen,
   1128                 sp->stride, up, sp->From14);
   1129             bp += llen * sizeof(uint16);
   1130             break;
   1131         case PIXARLOGDATAFMT_8BIT:
   1132             horizontalDifference8((unsigned char *)bp, llen,
   1133                 sp->stride, up, sp->From8);
   1134             bp += llen * sizeof(unsigned char);
   1135             break;
   1136         default:
   1137             TIFFErrorExt(tif->tif_clientdata, module,
   1138                 "%d bit input not supported in PixarLog",
   1139                 td->td_bitspersample);
   1140             return 0;
   1141         }
   1142     }
   1143 
   1144     sp->stream.next_in = (unsigned char *) sp->tbuf;
   1145     assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
   1146         we need to simplify this code to reflect a ZLib that is likely updated
   1147         to deal with 8byte memory sizes, though this code will respond
   1148         apropriately even before we simplify it */
   1149     sp->stream.avail_in = (uInt) (n * sizeof(uint16));
   1150     if ((sp->stream.avail_in / sizeof(uint16)) != (uInt) n)
   1151     {
   1152         TIFFErrorExt(tif->tif_clientdata, module,
   1153                  "ZLib cannot deal with buffers this size");
   1154         return (0);
   1155     }
   1156 
   1157     do {
   1158         if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
   1159             TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s",
   1160                 sp->stream.msg);
   1161             return (0);
   1162         }
   1163         if (sp->stream.avail_out == 0) {
   1164             tif->tif_rawcc = tif->tif_rawdatasize;
   1165             TIFFFlushData1(tif);
   1166             sp->stream.next_out = tif->tif_rawdata;
   1167             sp->stream.avail_out = (uInt) tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in PixarLogPreEncode */
   1168         }
   1169     } while (sp->stream.avail_in > 0);
   1170     return (1);
   1171 }
   1172 
   1173 /*
   1174  * Finish off an encoded strip by flushing the last
   1175  * string and tacking on an End Of Information code.
   1176  */
   1177 
   1178 static int
   1179 PixarLogPostEncode(TIFF* tif)
   1180 {
   1181     static const char module[] = "PixarLogPostEncode";
   1182     PixarLogState *sp = EncoderState(tif);
   1183     int state;
   1184 
   1185     sp->stream.avail_in = 0;
   1186 
   1187     do {
   1188         state = deflate(&sp->stream, Z_FINISH);
   1189         switch (state) {
   1190         case Z_STREAM_END:
   1191         case Z_OK:
   1192             if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) {
   1193                 tif->tif_rawcc =
   1194                 tif->tif_rawdatasize - sp->stream.avail_out;
   1195                 TIFFFlushData1(tif);
   1196                 sp->stream.next_out = tif->tif_rawdata;
   1197                 sp->stream.avail_out = (uInt) tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in PixarLogPreEncode */
   1198             }
   1199             break;
   1200         default:
   1201             TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
   1202             sp->stream.msg);
   1203             return (0);
   1204         }
   1205     } while (state != Z_STREAM_END);
   1206     return (1);
   1207 }
   1208 
   1209 static void
   1210 PixarLogClose(TIFF* tif)
   1211 {
   1212     TIFFDirectory *td = &tif->tif_dir;
   1213 
   1214     /* In a really sneaky (and really incorrect, and untruthfull, and
   1215      * troublesome, and error-prone) maneuver that completely goes against
   1216      * the spirit of TIFF, and breaks TIFF, on close, we covertly
   1217      * modify both bitspersample and sampleformat in the directory to
   1218      * indicate 8-bit linear.  This way, the decode "just works" even for
   1219      * readers that don't know about PixarLog, or how to set
   1220      * the PIXARLOGDATFMT pseudo-tag.
   1221      */
   1222     td->td_bitspersample = 8;
   1223     td->td_sampleformat = SAMPLEFORMAT_UINT;
   1224 }
   1225 
   1226 static void
   1227 PixarLogCleanup(TIFF* tif)
   1228 {
   1229     PixarLogState* sp = (PixarLogState*) tif->tif_data;
   1230 
   1231     assert(sp != 0);
   1232 
   1233     (void)TIFFPredictorCleanup(tif);
   1234 
   1235     tif->tif_tagmethods.vgetfield = sp->vgetparent;
   1236     tif->tif_tagmethods.vsetfield = sp->vsetparent;
   1237 
   1238     if (sp->FromLT2) _TIFFfree(sp->FromLT2);
   1239     if (sp->From14) _TIFFfree(sp->From14);
   1240     if (sp->From8) _TIFFfree(sp->From8);
   1241     if (sp->ToLinearF) _TIFFfree(sp->ToLinearF);
   1242     if (sp->ToLinear16) _TIFFfree(sp->ToLinear16);
   1243     if (sp->ToLinear8) _TIFFfree(sp->ToLinear8);
   1244     if (sp->state&PLSTATE_INIT) {
   1245         if (tif->tif_mode == O_RDONLY)
   1246             inflateEnd(&sp->stream);
   1247         else
   1248             deflateEnd(&sp->stream);
   1249     }
   1250     if (sp->tbuf)
   1251         _TIFFfree(sp->tbuf);
   1252     _TIFFfree(sp);
   1253     tif->tif_data = NULL;
   1254 
   1255     _TIFFSetDefaultCompressionState(tif);
   1256 }
   1257 
   1258 static int
   1259 PixarLogVSetField(TIFF* tif, uint32 tag, va_list ap)
   1260 {
   1261     static const char module[] = "PixarLogVSetField";
   1262     PixarLogState *sp = (PixarLogState *)tif->tif_data;
   1263     int result;
   1264 
   1265     switch (tag) {
   1266      case TIFFTAG_PIXARLOGQUALITY:
   1267         sp->quality = (int) va_arg(ap, int);
   1268         if (tif->tif_mode != O_RDONLY && (sp->state&PLSTATE_INIT)) {
   1269             if (deflateParams(&sp->stream,
   1270                 sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) {
   1271                 TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
   1272                     sp->stream.msg);
   1273                 return (0);
   1274             }
   1275         }
   1276         return (1);
   1277      case TIFFTAG_PIXARLOGDATAFMT:
   1278     sp->user_datafmt = (int) va_arg(ap, int);
   1279     /* Tweak the TIFF header so that the rest of libtiff knows what
   1280      * size of data will be passed between app and library, and
   1281      * assume that the app knows what it is doing and is not
   1282      * confused by these header manipulations...
   1283      */
   1284     switch (sp->user_datafmt) {
   1285      case PIXARLOGDATAFMT_8BIT:
   1286      case PIXARLOGDATAFMT_8BITABGR:
   1287         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
   1288         TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
   1289         break;
   1290      case PIXARLOGDATAFMT_11BITLOG:
   1291         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
   1292         TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
   1293         break;
   1294      case PIXARLOGDATAFMT_12BITPICIO:
   1295         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
   1296         TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
   1297         break;
   1298      case PIXARLOGDATAFMT_16BIT:
   1299         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
   1300         TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
   1301         break;
   1302      case PIXARLOGDATAFMT_FLOAT:
   1303         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32);
   1304         TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
   1305         break;
   1306     }
   1307     /*
   1308      * Must recalculate sizes should bits/sample change.
   1309      */
   1310     tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
   1311     tif->tif_scanlinesize = TIFFScanlineSize(tif);
   1312     result = 1;		/* NB: pseudo tag */
   1313     break;
   1314      default:
   1315     result = (*sp->vsetparent)(tif, tag, ap);
   1316     }
   1317     return (result);
   1318 }
   1319 
   1320 static int
   1321 PixarLogVGetField(TIFF* tif, uint32 tag, va_list ap)
   1322 {
   1323     PixarLogState *sp = (PixarLogState *)tif->tif_data;
   1324 
   1325     switch (tag) {
   1326      case TIFFTAG_PIXARLOGQUALITY:
   1327     *va_arg(ap, int*) = sp->quality;
   1328     break;
   1329      case TIFFTAG_PIXARLOGDATAFMT:
   1330     *va_arg(ap, int*) = sp->user_datafmt;
   1331     break;
   1332      default:
   1333     return (*sp->vgetparent)(tif, tag, ap);
   1334     }
   1335     return (1);
   1336 }
   1337 
   1338 static const TIFFField pixarlogFields[] = {
   1339     {TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL},
   1340     {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}
   1341 };
   1342 
   1343 int
   1344 TIFFInitPixarLog(TIFF* tif, int scheme)
   1345 {
   1346     static const char module[] = "TIFFInitPixarLog";
   1347 
   1348     PixarLogState* sp;
   1349 
   1350     assert(scheme == COMPRESSION_PIXARLOG);
   1351 
   1352     /*
   1353      * Merge codec-specific tag information.
   1354      */
   1355     if (!_TIFFMergeFields(tif, pixarlogFields,
   1356                   TIFFArrayCount(pixarlogFields))) {
   1357         TIFFErrorExt(tif->tif_clientdata, module,
   1358                  "Merging PixarLog codec-specific tags failed");
   1359         return 0;
   1360     }
   1361 
   1362     /*
   1363      * Allocate state block so tag methods have storage to record values.
   1364      */
   1365     tif->tif_data = (uint8*) _TIFFmalloc(sizeof (PixarLogState));
   1366     if (tif->tif_data == NULL)
   1367         goto bad;
   1368     sp = (PixarLogState*) tif->tif_data;
   1369     _TIFFmemset(sp, 0, sizeof (*sp));
   1370     sp->stream.data_type = Z_BINARY;
   1371     sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN;
   1372 
   1373     /*
   1374      * Install codec methods.
   1375      */
   1376     tif->tif_fixuptags = PixarLogFixupTags;
   1377     tif->tif_setupdecode = PixarLogSetupDecode;
   1378     tif->tif_predecode = PixarLogPreDecode;
   1379     tif->tif_decoderow = PixarLogDecode;
   1380     tif->tif_decodestrip = PixarLogDecode;
   1381     tif->tif_decodetile = PixarLogDecode;
   1382     tif->tif_setupencode = PixarLogSetupEncode;
   1383     tif->tif_preencode = PixarLogPreEncode;
   1384     tif->tif_postencode = PixarLogPostEncode;
   1385     tif->tif_encoderow = PixarLogEncode;
   1386     tif->tif_encodestrip = PixarLogEncode;
   1387     tif->tif_encodetile = PixarLogEncode;
   1388     tif->tif_close = PixarLogClose;
   1389     tif->tif_cleanup = PixarLogCleanup;
   1390 
   1391     /* Override SetField so we can handle our private pseudo-tag */
   1392     sp->vgetparent = tif->tif_tagmethods.vgetfield;
   1393     tif->tif_tagmethods.vgetfield = PixarLogVGetField;   /* hook for codec tags */
   1394     sp->vsetparent = tif->tif_tagmethods.vsetfield;
   1395     tif->tif_tagmethods.vsetfield = PixarLogVSetField;   /* hook for codec tags */
   1396 
   1397     /* Default values for codec-specific fields */
   1398     sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */
   1399     sp->state = 0;
   1400 
   1401     /* we don't wish to use the predictor,
   1402      * the default is none, which predictor value 1
   1403      */
   1404     (void) TIFFPredictorInit(tif);
   1405 
   1406     /*
   1407      * build the companding tables
   1408      */
   1409     PixarLogMakeTables(sp);
   1410 
   1411     return (1);
   1412 bad:
   1413     TIFFErrorExt(tif->tif_clientdata, module,
   1414              "No space for PixarLog state block");
   1415     return (0);
   1416 }
   1417 #endif /* PIXARLOG_SUPPORT */
   1418 
   1419 /* vim: set ts=8 sts=8 sw=8 noet: */
   1420 /*
   1421  * Local Variables:
   1422  * mode: c
   1423  * c-basic-offset: 8
   1424  * fill-column: 78
   1425  * End:
   1426  */
   1427