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