home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / tiff / tif_luv.c < prev    next >
C/C++ Source or Header  |  2000-08-09  |  36KB  |  1,429 lines

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