LCOV - code coverage report
Current view: directory - frmts/gtiff/libtiff - tif_pixarlog.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 740 0 0.0 %
Date: 2011-12-18 Functions: 25 0 0.0 %

       1                 : /* $Id: tif_pixarlog.c,v 1.35 2011-01-06 16:00:23 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               0 : 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               0 :     if (n >= stride) {
     121               0 :   mask = CODE_MASK;
     122               0 :   if (stride == 3) {
     123               0 :       t0 = ToLinearF[cr = wp[0]];
     124               0 :       t1 = ToLinearF[cg = wp[1]];
     125               0 :       t2 = ToLinearF[cb = wp[2]];
     126               0 :       op[0] = t0;
     127               0 :       op[1] = t1;
     128               0 :       op[2] = t2;
     129               0 :       n -= 3;
     130               0 :       while (n > 0) {
     131               0 :     wp += 3;
     132               0 :     op += 3;
     133               0 :     n -= 3;
     134               0 :     t0 = ToLinearF[(cr += wp[0]) & mask];
     135               0 :     t1 = ToLinearF[(cg += wp[1]) & mask];
     136               0 :     t2 = ToLinearF[(cb += wp[2]) & mask];
     137               0 :     op[0] = t0;
     138               0 :     op[1] = t1;
     139               0 :     op[2] = t2;
     140                 :       }
     141               0 :   } else if (stride == 4) {
     142               0 :       t0 = ToLinearF[cr = wp[0]];
     143               0 :       t1 = ToLinearF[cg = wp[1]];
     144               0 :       t2 = ToLinearF[cb = wp[2]];
     145               0 :       t3 = ToLinearF[ca = wp[3]];
     146               0 :       op[0] = t0;
     147               0 :       op[1] = t1;
     148               0 :       op[2] = t2;
     149               0 :       op[3] = t3;
     150               0 :       n -= 4;
     151               0 :       while (n > 0) {
     152               0 :     wp += 4;
     153               0 :     op += 4;
     154               0 :     n -= 4;
     155               0 :     t0 = ToLinearF[(cr += wp[0]) & mask];
     156               0 :     t1 = ToLinearF[(cg += wp[1]) & mask];
     157               0 :     t2 = ToLinearF[(cb += wp[2]) & mask];
     158               0 :     t3 = ToLinearF[(ca += wp[3]) & mask];
     159               0 :     op[0] = t0;
     160               0 :     op[1] = t1;
     161               0 :     op[2] = t2;
     162               0 :     op[3] = t3;
     163                 :       }
     164                 :   } else {
     165               0 :       REPEAT(stride, *op = ToLinearF[*wp&mask]; wp++; op++)
     166               0 :       n -= stride;
     167               0 :       while (n > 0) {
     168               0 :     REPEAT(stride,
     169                 :         wp[stride] += *wp; *op = ToLinearF[*wp&mask]; wp++; op++)
     170               0 :     n -= stride;
     171                 :       }
     172                 :   }
     173                 :     }
     174               0 : }
     175                 : 
     176                 : static void
     177               0 : 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               0 :     if (n >= stride) {
     187               0 :   mask = CODE_MASK;
     188               0 :   if (stride == 3) {
     189               0 :       t0 = ToLinearF[cr = wp[0]] * SCALE12;
     190               0 :       t1 = ToLinearF[cg = wp[1]] * SCALE12;
     191               0 :       t2 = ToLinearF[cb = wp[2]] * SCALE12;
     192               0 :       op[0] = CLAMP12(t0);
     193               0 :       op[1] = CLAMP12(t1);
     194               0 :       op[2] = CLAMP12(t2);
     195               0 :       n -= 3;
     196               0 :       while (n > 0) {
     197               0 :     wp += 3;
     198               0 :     op += 3;
     199               0 :     n -= 3;
     200               0 :     t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
     201               0 :     t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
     202               0 :     t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
     203               0 :     op[0] = CLAMP12(t0);
     204               0 :     op[1] = CLAMP12(t1);
     205               0 :     op[2] = CLAMP12(t2);
     206                 :       }
     207               0 :   } else if (stride == 4) {
     208               0 :       t0 = ToLinearF[cr = wp[0]] * SCALE12;
     209               0 :       t1 = ToLinearF[cg = wp[1]] * SCALE12;
     210               0 :       t2 = ToLinearF[cb = wp[2]] * SCALE12;
     211               0 :       t3 = ToLinearF[ca = wp[3]] * SCALE12;
     212               0 :       op[0] = CLAMP12(t0);
     213               0 :       op[1] = CLAMP12(t1);
     214               0 :       op[2] = CLAMP12(t2);
     215               0 :       op[3] = CLAMP12(t3);
     216               0 :       n -= 4;
     217               0 :       while (n > 0) {
     218               0 :     wp += 4;
     219               0 :     op += 4;
     220               0 :     n -= 4;
     221               0 :     t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
     222               0 :     t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
     223               0 :     t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
     224               0 :     t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12;
     225               0 :     op[0] = CLAMP12(t0);
     226               0 :     op[1] = CLAMP12(t1);
     227               0 :     op[2] = CLAMP12(t2);
     228               0 :     op[3] = CLAMP12(t3);
     229                 :       }
     230                 :   } else {
     231               0 :       REPEAT(stride, t0 = ToLinearF[*wp&mask] * SCALE12;
     232                 :                            *op = CLAMP12(t0); wp++; op++)
     233               0 :       n -= stride;
     234               0 :       while (n > 0) {
     235               0 :     REPEAT(stride,
     236                 :         wp[stride] += *wp; t0 = ToLinearF[wp[stride]&mask]*SCALE12;
     237                 :         *op = CLAMP12(t0);  wp++; op++)
     238               0 :     n -= stride;
     239                 :       }
     240                 :   }
     241                 :     }
     242               0 : }
     243                 : 
     244                 : static void
     245               0 : horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op,
     246                 :   uint16 *ToLinear16)
     247                 : {
     248                 :     register unsigned int  cr, cg, cb, ca, mask;
     249                 : 
     250               0 :     if (n >= stride) {
     251               0 :   mask = CODE_MASK;
     252               0 :   if (stride == 3) {
     253               0 :       op[0] = ToLinear16[cr = wp[0]];
     254               0 :       op[1] = ToLinear16[cg = wp[1]];
     255               0 :       op[2] = ToLinear16[cb = wp[2]];
     256               0 :       n -= 3;
     257               0 :       while (n > 0) {
     258               0 :     wp += 3;
     259               0 :     op += 3;
     260               0 :     n -= 3;
     261               0 :     op[0] = ToLinear16[(cr += wp[0]) & mask];
     262               0 :     op[1] = ToLinear16[(cg += wp[1]) & mask];
     263               0 :     op[2] = ToLinear16[(cb += wp[2]) & mask];
     264                 :       }
     265               0 :   } else if (stride == 4) {
     266               0 :       op[0] = ToLinear16[cr = wp[0]];
     267               0 :       op[1] = ToLinear16[cg = wp[1]];
     268               0 :       op[2] = ToLinear16[cb = wp[2]];
     269               0 :       op[3] = ToLinear16[ca = wp[3]];
     270               0 :       n -= 4;
     271               0 :       while (n > 0) {
     272               0 :     wp += 4;
     273               0 :     op += 4;
     274               0 :     n -= 4;
     275               0 :     op[0] = ToLinear16[(cr += wp[0]) & mask];
     276               0 :     op[1] = ToLinear16[(cg += wp[1]) & mask];
     277               0 :     op[2] = ToLinear16[(cb += wp[2]) & mask];
     278               0 :     op[3] = ToLinear16[(ca += wp[3]) & mask];
     279                 :       }
     280                 :   } else {
     281               0 :       REPEAT(stride, *op = ToLinear16[*wp&mask]; wp++; op++)
     282               0 :       n -= stride;
     283               0 :       while (n > 0) {
     284               0 :     REPEAT(stride,
     285                 :         wp[stride] += *wp; *op = ToLinear16[*wp&mask]; wp++; op++)
     286               0 :     n -= stride;
     287                 :       }
     288                 :   }
     289                 :     }
     290               0 : }
     291                 : 
     292                 : /* 
     293                 :  * Returns the log encoded 11-bit values with the horizontal
     294                 :  * differencing undone.
     295                 :  */
     296                 : static void
     297               0 : horizontalAccumulate11(uint16 *wp, int n, int stride, uint16 *op)
     298                 : {
     299                 :     register unsigned int  cr, cg, cb, ca, mask;
     300                 : 
     301               0 :     if (n >= stride) {
     302               0 :   mask = CODE_MASK;
     303               0 :   if (stride == 3) {
     304               0 :       op[0] = cr = wp[0];  op[1] = cg = wp[1];  op[2] = cb = wp[2];
     305               0 :       n -= 3;
     306               0 :       while (n > 0) {
     307               0 :     wp += 3;
     308               0 :     op += 3;
     309               0 :     n -= 3;
     310               0 :     op[0] = (cr += wp[0]) & mask;
     311               0 :     op[1] = (cg += wp[1]) & mask;
     312               0 :     op[2] = (cb += wp[2]) & mask;
     313                 :       }
     314               0 :   } else if (stride == 4) {
     315               0 :       op[0] = cr = wp[0];  op[1] = cg = wp[1];
     316               0 :       op[2] = cb = wp[2];  op[3] = ca = wp[3];
     317               0 :       n -= 4;
     318               0 :       while (n > 0) {
     319               0 :     wp += 4;
     320               0 :     op += 4;
     321               0 :     n -= 4;
     322               0 :     op[0] = (cr += wp[0]) & mask;
     323               0 :     op[1] = (cg += wp[1]) & mask;
     324               0 :     op[2] = (cb += wp[2]) & mask;
     325               0 :     op[3] = (ca += wp[3]) & mask;
     326                 :       } 
     327                 :   } else {
     328               0 :       REPEAT(stride, *op = *wp&mask; wp++; op++)
     329               0 :       n -= stride;
     330               0 :       while (n > 0) {
     331               0 :     REPEAT(stride,
     332                 :         wp[stride] += *wp; *op = *wp&mask; wp++; op++)
     333               0 :     n -= stride;
     334                 :       }
     335                 :   }
     336                 :     }
     337               0 : }
     338                 : 
     339                 : static void
     340               0 : 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               0 :     if (n >= stride) {
     346               0 :   mask = CODE_MASK;
     347               0 :   if (stride == 3) {
     348               0 :       op[0] = ToLinear8[cr = wp[0]];
     349               0 :       op[1] = ToLinear8[cg = wp[1]];
     350               0 :       op[2] = ToLinear8[cb = wp[2]];
     351               0 :       n -= 3;
     352               0 :       while (n > 0) {
     353               0 :     n -= 3;
     354               0 :     wp += 3;
     355               0 :     op += 3;
     356               0 :     op[0] = ToLinear8[(cr += wp[0]) & mask];
     357               0 :     op[1] = ToLinear8[(cg += wp[1]) & mask];
     358               0 :     op[2] = ToLinear8[(cb += wp[2]) & mask];
     359                 :       }
     360               0 :   } else if (stride == 4) {
     361               0 :       op[0] = ToLinear8[cr = wp[0]];
     362               0 :       op[1] = ToLinear8[cg = wp[1]];
     363               0 :       op[2] = ToLinear8[cb = wp[2]];
     364               0 :       op[3] = ToLinear8[ca = wp[3]];
     365               0 :       n -= 4;
     366               0 :       while (n > 0) {
     367               0 :     n -= 4;
     368               0 :     wp += 4;
     369               0 :     op += 4;
     370               0 :     op[0] = ToLinear8[(cr += wp[0]) & mask];
     371               0 :     op[1] = ToLinear8[(cg += wp[1]) & mask];
     372               0 :     op[2] = ToLinear8[(cb += wp[2]) & mask];
     373               0 :     op[3] = ToLinear8[(ca += wp[3]) & mask];
     374                 :       }
     375                 :   } else {
     376               0 :       REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)
     377               0 :       n -= stride;
     378               0 :       while (n > 0) {
     379               0 :     REPEAT(stride,
     380                 :         wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
     381               0 :     n -= stride;
     382                 :       }
     383                 :   }
     384                 :     }
     385               0 : }
     386                 : 
     387                 : 
     388                 : static void
     389               0 : 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               0 :     if (n >= stride) {
     396               0 :   mask = CODE_MASK;
     397               0 :   if (stride == 3) {
     398               0 :       op[0] = 0;
     399               0 :       t1 = ToLinear8[cb = wp[2]];
     400               0 :       t2 = ToLinear8[cg = wp[1]];
     401               0 :       t3 = ToLinear8[cr = wp[0]];
     402               0 :       op[1] = t1;
     403               0 :       op[2] = t2;
     404               0 :       op[3] = t3;
     405               0 :       n -= 3;
     406               0 :       while (n > 0) {
     407               0 :     n -= 3;
     408               0 :     wp += 3;
     409               0 :     op += 4;
     410               0 :     op[0] = 0;
     411               0 :     t1 = ToLinear8[(cb += wp[2]) & mask];
     412               0 :     t2 = ToLinear8[(cg += wp[1]) & mask];
     413               0 :     t3 = ToLinear8[(cr += wp[0]) & mask];
     414               0 :     op[1] = t1;
     415               0 :     op[2] = t2;
     416               0 :     op[3] = t3;
     417                 :       }
     418               0 :   } else if (stride == 4) {
     419               0 :       t0 = ToLinear8[ca = wp[3]];
     420               0 :       t1 = ToLinear8[cb = wp[2]];
     421               0 :       t2 = ToLinear8[cg = wp[1]];
     422               0 :       t3 = ToLinear8[cr = wp[0]];
     423               0 :       op[0] = t0;
     424               0 :       op[1] = t1;
     425               0 :       op[2] = t2;
     426               0 :       op[3] = t3;
     427               0 :       n -= 4;
     428               0 :       while (n > 0) {
     429               0 :     n -= 4;
     430               0 :     wp += 4;
     431               0 :     op += 4;
     432               0 :     t0 = ToLinear8[(ca += wp[3]) & mask];
     433               0 :     t1 = ToLinear8[(cb += wp[2]) & mask];
     434               0 :     t2 = ToLinear8[(cg += wp[1]) & mask];
     435               0 :     t3 = ToLinear8[(cr += wp[0]) & mask];
     436               0 :     op[0] = t0;
     437               0 :     op[1] = t1;
     438               0 :     op[2] = t2;
     439               0 :     op[3] = t3;
     440                 :       }
     441                 :   } else {
     442               0 :       REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)
     443               0 :       n -= stride;
     444               0 :       while (n > 0) {
     445               0 :     REPEAT(stride,
     446                 :         wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
     447               0 :     n -= stride;
     448                 :       }
     449                 :   }
     450                 :     }
     451               0 : }
     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               0 : 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               0 :     c = log(RATIO); 
     505               0 :     nlin = (int)(1./c); /* nlin must be an integer */
     506               0 :     c = 1./nlin;
     507               0 :     b = exp(-c*ONE);  /* multiplicative scale factor [b*exp(c*ONE) = 1] */
     508               0 :     linstep = b*c*exp(1.);
     509                 : 
     510               0 :     LogK1 = (float)(1./c);  /* if (v >= 2)  token = k1*log(v*k2) */
     511               0 :     LogK2 = (float)(1./b);
     512               0 :     lt2size = (int)(2./linstep) + 1;
     513               0 :     FromLT2 = (uint16 *)_TIFFmalloc(lt2size*sizeof(uint16));
     514               0 :     From14 = (uint16 *)_TIFFmalloc(16384*sizeof(uint16));
     515               0 :     From8 = (uint16 *)_TIFFmalloc(256*sizeof(uint16));
     516               0 :     ToLinearF = (float *)_TIFFmalloc(TSIZEP1 * sizeof(float));
     517               0 :     ToLinear16 = (uint16 *)_TIFFmalloc(TSIZEP1 * sizeof(uint16));
     518               0 :     ToLinear8 = (unsigned char *)_TIFFmalloc(TSIZEP1 * sizeof(unsigned char));
     519               0 :     if (FromLT2 == NULL || From14  == NULL || From8   == NULL ||
     520                 :    ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) {
     521               0 :   if (FromLT2) _TIFFfree(FromLT2);
     522               0 :   if (From14) _TIFFfree(From14);
     523               0 :   if (From8) _TIFFfree(From8);
     524               0 :   if (ToLinearF) _TIFFfree(ToLinearF);
     525               0 :   if (ToLinear16) _TIFFfree(ToLinear16);
     526               0 :   if (ToLinear8) _TIFFfree(ToLinear8);
     527               0 :   sp->FromLT2 = NULL;
     528               0 :   sp->From14 = NULL;
     529               0 :   sp->From8 = NULL;
     530               0 :   sp->ToLinearF = NULL;
     531               0 :   sp->ToLinear16 = NULL;
     532               0 :   sp->ToLinear8 = NULL;
     533               0 :   return 0;
     534                 :     }
     535                 : 
     536               0 :     j = 0;
     537                 : 
     538               0 :     for (i = 0; i < nlin; i++)  {
     539               0 :   v = i * linstep;
     540               0 :   ToLinearF[j++] = (float)v;
     541                 :     }
     542                 : 
     543               0 :     for (i = nlin; i < TSIZE; i++)
     544               0 :   ToLinearF[j++] = (float)(b*exp(c*i));
     545                 : 
     546               0 :     ToLinearF[2048] = ToLinearF[2047];
     547                 : 
     548               0 :     for (i = 0; i < TSIZEP1; i++)  {
     549               0 :   v = ToLinearF[i]*65535.0 + 0.5;
     550               0 :   ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16)v;
     551               0 :   v = ToLinearF[i]*255.0  + 0.5;
     552               0 :   ToLinear8[i]  = (v > 255.0) ? 255 : (unsigned char)v;
     553                 :     }
     554                 : 
     555               0 :     j = 0;
     556               0 :     for (i = 0; i < lt2size; i++)  {
     557               0 :   if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1])
     558               0 :       j++;
     559               0 :   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               0 :     j = 0;
     568               0 :     for (i = 0; i < 16384; i++)  {
     569               0 :   while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1])
     570               0 :       j++;
     571               0 :   From14[i] = j;
     572                 :     }
     573                 : 
     574               0 :     j = 0;
     575               0 :     for (i = 0; i < 256; i++)  {
     576               0 :   while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1])
     577               0 :       j++;
     578               0 :   From8[i] = j;
     579                 :     }
     580                 : 
     581               0 :     Fltsize = (float)(lt2size/2);
     582                 : 
     583               0 :     sp->ToLinearF = ToLinearF;
     584               0 :     sp->ToLinear16 = ToLinear16;
     585               0 :     sp->ToLinear8 = ToLinear8;
     586               0 :     sp->FromLT2 = FromLT2;
     587               0 :     sp->From14 = From14;
     588               0 :     sp->From8 = From8;
     589                 : 
     590               0 :     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               0 : PixarLogGuessDataFmt(TIFFDirectory *td)
     603                 : {
     604               0 :   int guess = PIXARLOGDATAFMT_UNKNOWN;
     605               0 :   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               0 :   switch (td->td_bitspersample) {
     611                 :    case 32:
     612               0 :     if (format == SAMPLEFORMAT_IEEEFP)
     613               0 :       guess = PIXARLOGDATAFMT_FLOAT;
     614               0 :     break;
     615                 :    case 16:
     616               0 :     if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
     617               0 :       guess = PIXARLOGDATAFMT_16BIT;
     618               0 :     break;
     619                 :    case 12:
     620               0 :     if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT)
     621               0 :       guess = PIXARLOGDATAFMT_12BITPICIO;
     622               0 :     break;
     623                 :    case 11:
     624               0 :     if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
     625               0 :       guess = PIXARLOGDATAFMT_11BITLOG;
     626               0 :     break;
     627                 :    case 8:
     628               0 :     if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
     629               0 :       guess = PIXARLOGDATAFMT_8BIT;
     630                 :     break;
     631                 :   }
     632                 : 
     633               0 :   return guess;
     634                 : }
     635                 : 
     636                 : static tmsize_t
     637               0 : multiply_ms(tmsize_t m1, tmsize_t m2)
     638                 : {
     639               0 :   tmsize_t bytes = m1 * m2;
     640                 : 
     641               0 :   if (m1 && bytes / m1 != m2)
     642               0 :     bytes = 0;
     643                 : 
     644               0 :   return bytes;
     645                 : }
     646                 : 
     647                 : static int
     648               0 : PixarLogFixupTags(TIFF* tif)
     649                 : {
     650                 :   (void) tif;
     651               0 :   return (1);
     652                 : }
     653                 : 
     654                 : static int
     655               0 : PixarLogSetupDecode(TIFF* tif)
     656                 : {
     657                 :   static const char module[] = "PixarLogSetupDecode";
     658               0 :   TIFFDirectory *td = &tif->tif_dir;
     659               0 :   PixarLogState* sp = DecoderState(tif);
     660                 :   tmsize_t tbuf_size;
     661                 : 
     662               0 :   assert(sp != NULL);
     663                 : 
     664                 :   /* Make sure no byte swapping happens on the data
     665                 :    * after decompression. */
     666               0 :   tif->tif_postdecode = _TIFFNoPostDecode;  
     667                 : 
     668                 :   /* for some reason, we can't do this in TIFFInitPixarLog */
     669                 : 
     670               0 :   sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
     671                 :       td->td_samplesperpixel : 1);
     672               0 :   tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth),
     673               0 :               td->td_rowsperstrip), sizeof(uint16));
     674               0 :   if (tbuf_size == 0)
     675               0 :     return (0);   /* TODO: this is an error return without error report through TIFFErrorExt */
     676               0 :   sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size);
     677               0 :   if (sp->tbuf == NULL)
     678               0 :     return (0);
     679               0 :   if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
     680               0 :     sp->user_datafmt = PixarLogGuessDataFmt(td);
     681               0 :   if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
     682               0 :     TIFFErrorExt(tif->tif_clientdata, module,
     683                 :       "PixarLog compression can't handle bits depth/data format combination (depth: %d)", 
     684               0 :       td->td_bitspersample);
     685               0 :     return (0);
     686                 :   }
     687                 : 
     688               0 :   if (inflateInit(&sp->stream) != Z_OK) {
     689               0 :     TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
     690               0 :     return (0);
     691                 :   } else {
     692               0 :     sp->state |= PLSTATE_INIT;
     693               0 :     return (1);
     694                 :   }
     695                 : }
     696                 : 
     697                 : /*
     698                 :  * Setup state for decoding a strip.
     699                 :  */
     700                 : static int
     701               0 : PixarLogPreDecode(TIFF* tif, uint16 s)
     702                 : {
     703                 :   static const char module[] = "PixarLogPreDecode";
     704               0 :   PixarLogState* sp = DecoderState(tif);
     705                 : 
     706                 :   (void) s;
     707               0 :   assert(sp != NULL);
     708               0 :   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               0 :   sp->stream.avail_in = (uInt) tif->tif_rawcc;
     714               0 :   if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
     715                 :   {
     716               0 :     TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
     717               0 :     return (0);
     718                 :   }
     719               0 :   return (inflateReset(&sp->stream) == Z_OK);
     720                 : }
     721                 : 
     722                 : static int
     723               0 : PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
     724                 : {
     725                 :   static const char module[] = "PixarLogDecode";
     726               0 :   TIFFDirectory *td = &tif->tif_dir;
     727               0 :   PixarLogState* sp = DecoderState(tif);
     728                 :   tmsize_t i;
     729                 :   tmsize_t nsamples;
     730                 :   int llen;
     731                 :   uint16 *up;
     732                 : 
     733               0 :   switch (sp->user_datafmt) {
     734                 :   case PIXARLOGDATAFMT_FLOAT:
     735               0 :     nsamples = occ / sizeof(float); /* XXX float == 32 bits */
     736               0 :     break;
     737                 :   case PIXARLOGDATAFMT_16BIT:
     738                 :   case PIXARLOGDATAFMT_12BITPICIO:
     739                 :   case PIXARLOGDATAFMT_11BITLOG:
     740               0 :     nsamples = occ / sizeof(uint16); /* XXX uint16 == 16 bits */
     741               0 :     break;
     742                 :   case PIXARLOGDATAFMT_8BIT:
     743                 :   case PIXARLOGDATAFMT_8BITABGR:
     744               0 :     nsamples = occ;
     745               0 :     break;
     746                 :   default:
     747               0 :     TIFFErrorExt(tif->tif_clientdata, module,
     748                 :       "%d bit input not supported in PixarLog",
     749               0 :       td->td_bitspersample);
     750               0 :     return 0;
     751                 :   }
     752                 : 
     753               0 :   llen = sp->stride * td->td_imagewidth;
     754                 : 
     755                 :   (void) s;
     756               0 :   assert(sp != NULL);
     757               0 :   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               0 :   sp->stream.avail_out = (uInt) (nsamples * sizeof(uint16));
     763               0 :   if (sp->stream.avail_out != nsamples * sizeof(uint16))
     764                 :   {
     765               0 :     TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
     766               0 :     return (0);
     767                 :   }
     768                 :   do {
     769               0 :     int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
     770               0 :     if (state == Z_STREAM_END) {
     771               0 :       break;      /* XXX */
     772                 :     }
     773               0 :     if (state == Z_DATA_ERROR) {
     774               0 :       TIFFErrorExt(tif->tif_clientdata, module,
     775                 :           "Decoding error at scanline %lu, %s",
     776                 :           (unsigned long) tif->tif_row, sp->stream.msg);
     777               0 :       if (inflateSync(&sp->stream) != Z_OK)
     778               0 :         return (0);
     779               0 :       continue;
     780                 :     }
     781               0 :     if (state != Z_OK) {
     782               0 :       TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
     783                 :           sp->stream.msg);
     784               0 :       return (0);
     785                 :     }
     786               0 :   } while (sp->stream.avail_out > 0);
     787                 : 
     788                 :   /* hopefully, we got all the bytes we needed */
     789               0 :   if (sp->stream.avail_out != 0) {
     790               0 :     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               0 :     return (0);
     794                 :   }
     795                 : 
     796               0 :   up = sp->tbuf;
     797                 :   /* Swap bytes in the data if from a different endian machine. */
     798               0 :   if (tif->tif_flags & TIFF_SWAB)
     799               0 :     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               0 :   if (nsamples % llen) { 
     807               0 :     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               0 :     nsamples -= nsamples % llen;
     811                 :   }
     812                 : 
     813               0 :   for (i = 0; i < nsamples; i += llen, up += llen) {
     814               0 :     switch (sp->user_datafmt)  {
     815                 :     case PIXARLOGDATAFMT_FLOAT:
     816               0 :       horizontalAccumulateF(up, llen, sp->stride,
     817                 :           (float *)op, sp->ToLinearF);
     818               0 :       op += llen * sizeof(float);
     819               0 :       break;
     820                 :     case PIXARLOGDATAFMT_16BIT:
     821               0 :       horizontalAccumulate16(up, llen, sp->stride,
     822                 :           (uint16 *)op, sp->ToLinear16);
     823               0 :       op += llen * sizeof(uint16);
     824               0 :       break;
     825                 :     case PIXARLOGDATAFMT_12BITPICIO:
     826               0 :       horizontalAccumulate12(up, llen, sp->stride,
     827                 :           (int16 *)op, sp->ToLinearF);
     828               0 :       op += llen * sizeof(int16);
     829               0 :       break;
     830                 :     case PIXARLOGDATAFMT_11BITLOG:
     831               0 :       horizontalAccumulate11(up, llen, sp->stride,
     832                 :           (uint16 *)op);
     833               0 :       op += llen * sizeof(uint16);
     834               0 :       break;
     835                 :     case PIXARLOGDATAFMT_8BIT:
     836               0 :       horizontalAccumulate8(up, llen, sp->stride,
     837                 :           (unsigned char *)op, sp->ToLinear8);
     838               0 :       op += llen * sizeof(unsigned char);
     839               0 :       break;
     840                 :     case PIXARLOGDATAFMT_8BITABGR:
     841               0 :       horizontalAccumulate8abgr(up, llen, sp->stride,
     842                 :           (unsigned char *)op, sp->ToLinear8);
     843               0 :       op += llen * sizeof(unsigned char);
     844               0 :       break;
     845                 :     default:
     846               0 :       TIFFErrorExt(tif->tif_clientdata, module,
     847                 :           "Unsupported bits/sample: %d",
     848               0 :           td->td_bitspersample);
     849               0 :       return (0);
     850                 :     }
     851                 :   }
     852                 : 
     853               0 :   return (1);
     854                 : }
     855                 : 
     856                 : static int
     857               0 : PixarLogSetupEncode(TIFF* tif)
     858                 : {
     859                 :   static const char module[] = "PixarLogSetupEncode";
     860               0 :   TIFFDirectory *td = &tif->tif_dir;
     861               0 :   PixarLogState* sp = EncoderState(tif);
     862                 :   tmsize_t tbuf_size;
     863                 : 
     864               0 :   assert(sp != NULL);
     865                 : 
     866                 :   /* for some reason, we can't do this in TIFFInitPixarLog */
     867                 : 
     868               0 :   sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
     869                 :       td->td_samplesperpixel : 1);
     870               0 :   tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth),
     871               0 :               td->td_rowsperstrip), sizeof(uint16));
     872               0 :   if (tbuf_size == 0)
     873               0 :     return (0);  /* TODO: this is an error return without error report through TIFFErrorExt */
     874               0 :   sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size);
     875               0 :   if (sp->tbuf == NULL)
     876               0 :     return (0);
     877               0 :   if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
     878               0 :     sp->user_datafmt = PixarLogGuessDataFmt(td);
     879               0 :   if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
     880               0 :     TIFFErrorExt(tif->tif_clientdata, module, "PixarLog compression can't handle %d bit linear encodings", td->td_bitspersample);
     881               0 :     return (0);
     882                 :   }
     883                 : 
     884               0 :   if (deflateInit(&sp->stream, sp->quality) != Z_OK) {
     885               0 :     TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
     886               0 :     return (0);
     887                 :   } else {
     888               0 :     sp->state |= PLSTATE_INIT;
     889               0 :     return (1);
     890                 :   }
     891                 : }
     892                 : 
     893                 : /*
     894                 :  * Reset encoding state at the start of a strip.
     895                 :  */
     896                 : static int
     897               0 : PixarLogPreEncode(TIFF* tif, uint16 s)
     898                 : {
     899                 :   static const char module[] = "PixarLogPreEncode";
     900               0 :   PixarLogState *sp = EncoderState(tif);
     901                 : 
     902                 :   (void) s;
     903               0 :   assert(sp != NULL);
     904               0 :   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               0 :   sp->stream.avail_out = tif->tif_rawdatasize;
     910               0 :   if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
     911                 :   {
     912               0 :     TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
     913               0 :     return (0);
     914                 :   }
     915               0 :   return (deflateReset(&sp->stream) == Z_OK);
     916                 : }
     917                 : 
     918                 : static void
     919               0 : horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2)
     920                 : {
     921                 :     int32 r1, g1, b1, a1, r2, g2, b2, a2, mask;
     922               0 :     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               0 :     mask = CODE_MASK;
     930               0 :     if (n >= stride) {
     931               0 :   if (stride == 3) {
     932               0 :       r2 = wp[0] = (uint16) CLAMP(ip[0]);
     933               0 :       g2 = wp[1] = (uint16) CLAMP(ip[1]);
     934               0 :       b2 = wp[2] = (uint16) CLAMP(ip[2]);
     935               0 :       n -= 3;
     936               0 :       while (n > 0) {
     937               0 :     n -= 3;
     938               0 :     wp += 3;
     939               0 :     ip += 3;
     940               0 :     r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
     941               0 :     g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
     942               0 :     b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
     943                 :       }
     944               0 :   } else if (stride == 4) {
     945               0 :       r2 = wp[0] = (uint16) CLAMP(ip[0]);
     946               0 :       g2 = wp[1] = (uint16) CLAMP(ip[1]);
     947               0 :       b2 = wp[2] = (uint16) CLAMP(ip[2]);
     948               0 :       a2 = wp[3] = (uint16) CLAMP(ip[3]);
     949               0 :       n -= 4;
     950               0 :       while (n > 0) {
     951               0 :     n -= 4;
     952               0 :     wp += 4;
     953               0 :     ip += 4;
     954               0 :     r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
     955               0 :     g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
     956               0 :     b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
     957               0 :     a1 = (int32) CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
     958                 :       }
     959                 :   } else {
     960               0 :       ip += n - 1;  /* point to last one */
     961               0 :       wp += n - 1;  /* point to last one */
     962               0 :       n -= stride;
     963               0 :       while (n > 0) {
     964               0 :     REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]);
     965                 :         wp[stride] -= wp[0];
     966                 :         wp[stride] &= mask;
     967                 :         wp--; ip--)
     968               0 :     n -= stride;
     969                 :       }
     970               0 :       REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp--; ip--)
     971                 :   }
     972                 :     }
     973               0 : }
     974                 : 
     975                 : static void
     976               0 : 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               0 :     mask = CODE_MASK;
     986               0 :     if (n >= stride) {
     987               0 :   if (stride == 3) {
     988               0 :       r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
     989               0 :       b2 = wp[2] = CLAMP(ip[2]);
     990               0 :       n -= 3;
     991               0 :       while (n > 0) {
     992               0 :     n -= 3;
     993               0 :     wp += 3;
     994               0 :     ip += 3;
     995               0 :     r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
     996               0 :     g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
     997               0 :     b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
     998                 :       }
     999               0 :   } else if (stride == 4) {
    1000               0 :       r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
    1001               0 :       b2 = wp[2] = CLAMP(ip[2]);  a2 = wp[3] = CLAMP(ip[3]);
    1002               0 :       n -= 4;
    1003               0 :       while (n > 0) {
    1004               0 :     n -= 4;
    1005               0 :     wp += 4;
    1006               0 :     ip += 4;
    1007               0 :     r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
    1008               0 :     g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
    1009               0 :     b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
    1010               0 :     a1 = CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
    1011                 :       }
    1012                 :   } else {
    1013               0 :       ip += n - 1;  /* point to last one */
    1014               0 :       wp += n - 1;  /* point to last one */
    1015               0 :       n -= stride;
    1016               0 :       while (n > 0) {
    1017               0 :     REPEAT(stride, wp[0] = CLAMP(ip[0]);
    1018                 :         wp[stride] -= wp[0];
    1019                 :         wp[stride] &= mask;
    1020                 :         wp--; ip--)
    1021               0 :     n -= stride;
    1022                 :       }
    1023               0 :       REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
    1024                 :   }
    1025                 :     }
    1026               0 : }
    1027                 : 
    1028                 : 
    1029                 : static void
    1030               0 : 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               0 :     mask = CODE_MASK;
    1039               0 :     if (n >= stride) {
    1040               0 :   if (stride == 3) {
    1041               0 :       r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
    1042               0 :       b2 = wp[2] = CLAMP(ip[2]);
    1043               0 :       n -= 3;
    1044               0 :       while (n > 0) {
    1045               0 :     n -= 3;
    1046               0 :     r1 = CLAMP(ip[3]); wp[3] = (r1-r2) & mask; r2 = r1;
    1047               0 :     g1 = CLAMP(ip[4]); wp[4] = (g1-g2) & mask; g2 = g1;
    1048               0 :     b1 = CLAMP(ip[5]); wp[5] = (b1-b2) & mask; b2 = b1;
    1049               0 :     wp += 3;
    1050               0 :     ip += 3;
    1051                 :       }
    1052               0 :   } else if (stride == 4) {
    1053               0 :       r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
    1054               0 :       b2 = wp[2] = CLAMP(ip[2]);  a2 = wp[3] = CLAMP(ip[3]);
    1055               0 :       n -= 4;
    1056               0 :       while (n > 0) {
    1057               0 :     n -= 4;
    1058               0 :     r1 = CLAMP(ip[4]); wp[4] = (r1-r2) & mask; r2 = r1;
    1059               0 :     g1 = CLAMP(ip[5]); wp[5] = (g1-g2) & mask; g2 = g1;
    1060               0 :     b1 = CLAMP(ip[6]); wp[6] = (b1-b2) & mask; b2 = b1;
    1061               0 :     a1 = CLAMP(ip[7]); wp[7] = (a1-a2) & mask; a2 = a1;
    1062               0 :     wp += 4;
    1063               0 :     ip += 4;
    1064                 :       }
    1065                 :   } else {
    1066               0 :       wp += n + stride - 1; /* point to last one */
    1067               0 :       ip += n + stride - 1; /* point to last one */
    1068               0 :       n -= stride;
    1069               0 :       while (n > 0) {
    1070               0 :     REPEAT(stride, wp[0] = CLAMP(ip[0]);
    1071                 :         wp[stride] -= wp[0];
    1072                 :         wp[stride] &= mask;
    1073                 :         wp--; ip--)
    1074               0 :     n -= stride;
    1075                 :       }
    1076               0 :       REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
    1077                 :   }
    1078                 :     }
    1079               0 : }
    1080                 : 
    1081                 : /*
    1082                 :  * Encode a chunk of pixels.
    1083                 :  */
    1084                 : static int
    1085               0 : PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
    1086                 : {
    1087                 :   static const char module[] = "PixarLogEncode";
    1088               0 :   TIFFDirectory *td = &tif->tif_dir;
    1089               0 :   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               0 :   switch (sp->user_datafmt) {
    1098                 :   case PIXARLOGDATAFMT_FLOAT:
    1099               0 :     n = cc / sizeof(float);   /* XXX float == 32 bits */
    1100               0 :     break;
    1101                 :   case PIXARLOGDATAFMT_16BIT:
    1102                 :   case PIXARLOGDATAFMT_12BITPICIO:
    1103                 :   case PIXARLOGDATAFMT_11BITLOG:
    1104               0 :     n = cc / sizeof(uint16);  /* XXX uint16 == 16 bits */
    1105               0 :     break;
    1106                 :   case PIXARLOGDATAFMT_8BIT:
    1107                 :   case PIXARLOGDATAFMT_8BITABGR:
    1108               0 :     n = cc;
    1109               0 :     break;
    1110                 :   default:
    1111               0 :     TIFFErrorExt(tif->tif_clientdata, module,
    1112                 :       "%d bit input not supported in PixarLog",
    1113               0 :       td->td_bitspersample);
    1114               0 :     return 0;
    1115                 :   }
    1116                 : 
    1117               0 :   llen = sp->stride * td->td_imagewidth;
    1118                 : 
    1119               0 :   for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) {
    1120               0 :     switch (sp->user_datafmt)  {
    1121                 :     case PIXARLOGDATAFMT_FLOAT:
    1122               0 :       horizontalDifferenceF((float *)bp, llen, 
    1123               0 :         sp->stride, up, sp->FromLT2);
    1124               0 :       bp += llen * sizeof(float);
    1125               0 :       break;
    1126                 :     case PIXARLOGDATAFMT_16BIT:
    1127               0 :       horizontalDifference16((uint16 *)bp, llen, 
    1128               0 :         sp->stride, up, sp->From14);
    1129               0 :       bp += llen * sizeof(uint16);
    1130               0 :       break;
    1131                 :     case PIXARLOGDATAFMT_8BIT:
    1132               0 :       horizontalDifference8((unsigned char *)bp, llen, 
    1133               0 :         sp->stride, up, sp->From8);
    1134               0 :       bp += llen * sizeof(unsigned char);
    1135               0 :       break;
    1136                 :     default:
    1137               0 :       TIFFErrorExt(tif->tif_clientdata, module,
    1138                 :         "%d bit input not supported in PixarLog",
    1139               0 :         td->td_bitspersample);
    1140               0 :       return 0;
    1141                 :     }
    1142                 :   }
    1143                 :  
    1144               0 :   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               0 :   sp->stream.avail_in = (uInt) (n * sizeof(uint16));
    1150               0 :   if ((sp->stream.avail_in / sizeof(uint16)) != (uInt) n)
    1151                 :   {
    1152               0 :     TIFFErrorExt(tif->tif_clientdata, module,
    1153                 :            "ZLib cannot deal with buffers this size");
    1154               0 :     return (0);
    1155                 :   }
    1156                 : 
    1157                 :   do {
    1158               0 :     if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
    1159               0 :       TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s",
    1160                 :           sp->stream.msg);
    1161               0 :       return (0);
    1162                 :     }
    1163               0 :     if (sp->stream.avail_out == 0) {
    1164               0 :       tif->tif_rawcc = tif->tif_rawdatasize;
    1165               0 :       TIFFFlushData1(tif);
    1166               0 :       sp->stream.next_out = tif->tif_rawdata;
    1167               0 :       sp->stream.avail_out = (uInt) tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in PixarLogPreEncode */
    1168                 :     }
    1169               0 :   } while (sp->stream.avail_in > 0);
    1170               0 :   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               0 : PixarLogPostEncode(TIFF* tif)
    1180                 : {
    1181                 :   static const char module[] = "PixarLogPostEncode";
    1182               0 :   PixarLogState *sp = EncoderState(tif);
    1183                 :   int state;
    1184                 : 
    1185               0 :   sp->stream.avail_in = 0;
    1186                 : 
    1187                 :   do {
    1188               0 :     state = deflate(&sp->stream, Z_FINISH);
    1189               0 :     switch (state) {
    1190                 :     case Z_STREAM_END:
    1191                 :     case Z_OK:
    1192               0 :         if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) {
    1193               0 :           tif->tif_rawcc =
    1194               0 :         tif->tif_rawdatasize - sp->stream.avail_out;
    1195               0 :           TIFFFlushData1(tif);
    1196               0 :           sp->stream.next_out = tif->tif_rawdata;
    1197               0 :           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               0 :       TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
    1202                 :       sp->stream.msg);
    1203               0 :         return (0);
    1204                 :     }
    1205               0 :   } while (state != Z_STREAM_END);
    1206               0 :   return (1);
    1207                 : }
    1208                 : 
    1209                 : static void
    1210               0 : PixarLogClose(TIFF* tif)
    1211                 : {
    1212               0 :   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               0 :   td->td_bitspersample = 8;
    1223               0 :   td->td_sampleformat = SAMPLEFORMAT_UINT;
    1224               0 : }
    1225                 : 
    1226                 : static void
    1227               0 : PixarLogCleanup(TIFF* tif)
    1228                 : {
    1229               0 :   PixarLogState* sp = (PixarLogState*) tif->tif_data;
    1230                 : 
    1231               0 :   assert(sp != 0);
    1232                 : 
    1233               0 :   (void)TIFFPredictorCleanup(tif);
    1234                 : 
    1235               0 :   tif->tif_tagmethods.vgetfield = sp->vgetparent;
    1236               0 :   tif->tif_tagmethods.vsetfield = sp->vsetparent;
    1237                 : 
    1238               0 :   if (sp->FromLT2) _TIFFfree(sp->FromLT2);
    1239               0 :   if (sp->From14) _TIFFfree(sp->From14);
    1240               0 :   if (sp->From8) _TIFFfree(sp->From8);
    1241               0 :   if (sp->ToLinearF) _TIFFfree(sp->ToLinearF);
    1242               0 :   if (sp->ToLinear16) _TIFFfree(sp->ToLinear16);
    1243               0 :   if (sp->ToLinear8) _TIFFfree(sp->ToLinear8);
    1244               0 :   if (sp->state&PLSTATE_INIT) {
    1245               0 :     if (tif->tif_mode == O_RDONLY)
    1246               0 :       inflateEnd(&sp->stream);
    1247                 :     else
    1248               0 :       deflateEnd(&sp->stream);
    1249                 :   }
    1250               0 :   if (sp->tbuf)
    1251               0 :     _TIFFfree(sp->tbuf);
    1252               0 :   _TIFFfree(sp);
    1253               0 :   tif->tif_data = NULL;
    1254                 : 
    1255               0 :   _TIFFSetDefaultCompressionState(tif);
    1256               0 : }
    1257                 : 
    1258                 : static int
    1259               0 : PixarLogVSetField(TIFF* tif, uint32 tag, va_list ap)
    1260                 : {
    1261                 :     static const char module[] = "PixarLogVSetField";
    1262               0 :     PixarLogState *sp = (PixarLogState *)tif->tif_data;
    1263                 :     int result;
    1264                 : 
    1265               0 :     switch (tag) {
    1266                 :      case TIFFTAG_PIXARLOGQUALITY:
    1267               0 :     sp->quality = (int) va_arg(ap, int);
    1268               0 :     if (tif->tif_mode != O_RDONLY && (sp->state&PLSTATE_INIT)) {
    1269               0 :       if (deflateParams(&sp->stream,
    1270                 :           sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) {
    1271               0 :         TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
    1272                 :           sp->stream.msg);
    1273               0 :         return (0);
    1274                 :       }
    1275                 :     }
    1276               0 :     return (1);
    1277                 :      case TIFFTAG_PIXARLOGDATAFMT:
    1278               0 :   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               0 :   switch (sp->user_datafmt) {
    1285                 :    case PIXARLOGDATAFMT_8BIT:
    1286                 :    case PIXARLOGDATAFMT_8BITABGR:
    1287               0 :       TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
    1288               0 :       TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
    1289               0 :       break;
    1290                 :    case PIXARLOGDATAFMT_11BITLOG:
    1291               0 :       TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
    1292               0 :       TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
    1293               0 :       break;
    1294                 :    case PIXARLOGDATAFMT_12BITPICIO:
    1295               0 :       TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
    1296               0 :       TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
    1297               0 :       break;
    1298                 :    case PIXARLOGDATAFMT_16BIT:
    1299               0 :       TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
    1300               0 :       TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
    1301               0 :       break;
    1302                 :    case PIXARLOGDATAFMT_FLOAT:
    1303               0 :       TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32);
    1304               0 :       TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
    1305                 :       break;
    1306                 :   }
    1307                 :   /*
    1308                 :    * Must recalculate sizes should bits/sample change.
    1309                 :    */
    1310               0 :   tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
    1311               0 :   tif->tif_scanlinesize = TIFFScanlineSize(tif);
    1312               0 :   result = 1;   /* NB: pseudo tag */
    1313               0 :   break;
    1314                 :      default:
    1315               0 :   result = (*sp->vsetparent)(tif, tag, ap);
    1316                 :     }
    1317               0 :     return (result);
    1318                 : }
    1319                 : 
    1320                 : static int
    1321               0 : PixarLogVGetField(TIFF* tif, uint32 tag, va_list ap)
    1322                 : {
    1323               0 :     PixarLogState *sp = (PixarLogState *)tif->tif_data;
    1324                 : 
    1325               0 :     switch (tag) {
    1326                 :      case TIFFTAG_PIXARLOGQUALITY:
    1327               0 :   *va_arg(ap, int*) = sp->quality;
    1328               0 :   break;
    1329                 :      case TIFFTAG_PIXARLOGDATAFMT:
    1330               0 :   *va_arg(ap, int*) = sp->user_datafmt;
    1331               0 :   break;
    1332                 :      default:
    1333               0 :   return (*sp->vgetparent)(tif, tag, ap);
    1334                 :     }
    1335               0 :     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               0 : TIFFInitPixarLog(TIFF* tif, int scheme)
    1345                 : {
    1346                 :   static const char module[] = "TIFFInitPixarLog";
    1347                 : 
    1348                 :   PixarLogState* sp;
    1349                 : 
    1350               0 :   assert(scheme == COMPRESSION_PIXARLOG);
    1351                 : 
    1352                 :   /*
    1353                 :    * Merge codec-specific tag information.
    1354                 :    */
    1355               0 :   if (!_TIFFMergeFields(tif, pixarlogFields,
    1356                 :             TIFFArrayCount(pixarlogFields))) {
    1357               0 :     TIFFErrorExt(tif->tif_clientdata, module,
    1358                 :            "Merging PixarLog codec-specific tags failed");
    1359               0 :     return 0;
    1360                 :   }
    1361                 : 
    1362                 :   /*
    1363                 :    * Allocate state block so tag methods have storage to record values.
    1364                 :    */
    1365               0 :   tif->tif_data = (uint8*) _TIFFmalloc(sizeof (PixarLogState));
    1366               0 :   if (tif->tif_data == NULL)
    1367               0 :     goto bad;
    1368               0 :   sp = (PixarLogState*) tif->tif_data;
    1369               0 :   _TIFFmemset(sp, 0, sizeof (*sp));
    1370               0 :   sp->stream.data_type = Z_BINARY;
    1371               0 :   sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN;
    1372                 : 
    1373                 :   /*
    1374                 :    * Install codec methods.
    1375                 :    */
    1376               0 :   tif->tif_fixuptags = PixarLogFixupTags; 
    1377               0 :   tif->tif_setupdecode = PixarLogSetupDecode;
    1378               0 :   tif->tif_predecode = PixarLogPreDecode;
    1379               0 :   tif->tif_decoderow = PixarLogDecode;
    1380               0 :   tif->tif_decodestrip = PixarLogDecode;  
    1381               0 :   tif->tif_decodetile = PixarLogDecode;
    1382               0 :   tif->tif_setupencode = PixarLogSetupEncode;
    1383               0 :   tif->tif_preencode = PixarLogPreEncode;
    1384               0 :   tif->tif_postencode = PixarLogPostEncode;
    1385               0 :   tif->tif_encoderow = PixarLogEncode;  
    1386               0 :   tif->tif_encodestrip = PixarLogEncode;
    1387               0 :   tif->tif_encodetile = PixarLogEncode;  
    1388               0 :   tif->tif_close = PixarLogClose;
    1389               0 :   tif->tif_cleanup = PixarLogCleanup;
    1390                 : 
    1391                 :   /* Override SetField so we can handle our private pseudo-tag */
    1392               0 :   sp->vgetparent = tif->tif_tagmethods.vgetfield;
    1393               0 :   tif->tif_tagmethods.vgetfield = PixarLogVGetField;   /* hook for codec tags */
    1394               0 :   sp->vsetparent = tif->tif_tagmethods.vsetfield;
    1395               0 :   tif->tif_tagmethods.vsetfield = PixarLogVSetField;   /* hook for codec tags */
    1396                 : 
    1397                 :   /* Default values for codec-specific fields */
    1398               0 :   sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */
    1399               0 :   sp->state = 0;
    1400                 : 
    1401                 :   /* we don't wish to use the predictor, 
    1402                 :    * the default is none, which predictor value 1
    1403                 :    */
    1404               0 :   (void) TIFFPredictorInit(tif);
    1405                 : 
    1406                 :   /*
    1407                 :    * build the companding tables 
    1408                 :    */
    1409               0 :   PixarLogMakeTables(sp);
    1410                 : 
    1411               0 :   return (1);
    1412                 : bad:
    1413               0 :   TIFFErrorExt(tif->tif_clientdata, module,
    1414                 :          "No space for PixarLog state block");
    1415               0 :   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                 :  */

Generated by: LCOV version 1.7