tif_pixarlog.c
上传用户:looem2003
上传日期:2014-07-20
资源大小:13733k
文件大小:36k
源码类别:

打印编程

开发平台:

Visual C++

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