Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

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