ReactOS 0.4.15-dev-8339-g4028de8
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
106static float Fltsize;
107static float LogK1, LogK2;
108
109#define REPEAT(n, op) { int i; i=n; do { i--; op; } while (i>0); }
110
111static void
112horizontalAccumulateF(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) {
167 wp[stride] += *wp; *op = ToLinearF[*wp&mask]; wp++; op++)
168 n -= stride;
169 }
170 }
171 }
172}
173
174static void
175horizontalAccumulate12(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) {
234 wp[stride] += *wp; t0 = ToLinearF[wp[stride]&mask]*SCALE12;
235 *op = CLAMP12(t0); wp++; op++)
236 n -= stride;
237 }
238 }
239 }
240}
241
242static void
243horizontalAccumulate16(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) {
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 */
294static void
295horizontalAccumulate11(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) {
332 wp[stride] += *wp; *op = *wp&mask; wp++; op++)
333 n -= stride;
334 }
335 }
336 }
337}
338
339static void
340horizontalAccumulate8(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) {
380 wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
381 n -= stride;
382 }
383 }
384 }
385}
386
387
388static void
389horizontalAccumulate8abgr(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) {
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 */
457typedef struct {
458 TIFFPredictorState predict;
460 tmsize_t tbuf_size; /* only set/used on reading for now */
461 uint16 *tbuf;
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
480static int
481PixarLogMakeTables(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
597static int PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
598static int PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s);
599
600#define PIXARLOGDATAFMT_UNKNOWN -1
601
602static int
603PixarLogGuessDataFmt(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:
627 break;
628 case 8:
630 guess = PIXARLOGDATAFMT_8BIT;
631 break;
632 }
633
634 return guess;
635}
636
637static tmsize_t
638multiply_ms(tmsize_t m1, tmsize_t m2)
639{
640 return _TIFFMultiplySSize(NULL, m1, m2, NULL);
641}
642
643static tmsize_t
644add_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
656static int
657PixarLogFixupTags(TIFF* tif)
658{
659 (void) tif;
660 return (1);
661}
662
663static int
664PixarLogSetupDecode(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 */
729static int
730PixarLogPreDecode(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
751static int
752PixarLogDecode(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
896static int
897PixarLogSetupEncode(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 */
936static int
937PixarLogPreEncode(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
958static void
959horizontalDifferenceF(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
1012static void
1013horizontalDifference16(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
1063static void
1064horizontalDifference8(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 */
1115static int
1116PixarLogEncode(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) {
1130 n = cc / sizeof(float); /* XXX float == 32 bits */
1131 break;
1135 n = cc / sizeof(uint16); /* XXX uint16 == 16 bits */
1136 break;
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) {
1160 horizontalDifferenceF((float *)bp, llen,
1161 sp->stride, up, sp->FromLT2);
1162 bp += llen * sizeof(float);
1163 break;
1165 horizontalDifference16((uint16 *)bp, llen,
1166 sp->stride, up, sp->From14);
1167 bp += llen * sizeof(uint16);
1168 break;
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
1216static int
1217PixarLogPostEncode(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
1247static void
1248PixarLogClose(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
1277static void
1278PixarLogCleanup(TIFF* tif)
1279{
1280 PixarLogState* sp = (PixarLogState*) tif->tif_data;
1281
1282 assert(sp != 0);
1283
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
1309static int
1310PixarLogVSetField(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) {
1340 break;
1344 break;
1348 break;
1352 break;
1356 break;
1357 }
1358 /*
1359 * Must recalculate sizes should bits/sample change.
1360 */
1361 tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
1363 result = 1; /* NB: pseudo tag */
1364 break;
1365 default:
1366 result = (*sp->vsetparent)(tif, tag, ap);
1367 }
1368 return (result);
1369}
1370
1371static int
1372PixarLogVGetField(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
1389static const TIFFField pixarlogFields[] = {
1392};
1393
1394int
1395TIFFInitPixarLog(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);
1463bad:
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 */
char * va_list
Definition: acmsvcex.h:78
#define va_arg(ap, T)
Definition: acmsvcex.h:89
#define O_RDONLY
Definition: acwin.h:108
static int state
Definition: maze.c:121
#define REPEAT(statement)
Definition: bitmap.c:42
unsigned short uint16
Definition: types.h:30
unsigned int uint32
Definition: types.h:32
unsigned char uint8
Definition: types.h:28
int ZEXPORT deflateReset(z_streamp strm)
Definition: deflate.c:541
int ZEXPORT deflateParams(z_streamp strm, int level, int strategy)
Definition: deflate.c:605
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:236
static const WCHAR ca[]
Definition: main.c:455
static int inflateReset(z_streamp strm)
Definition: inflate.c:839
int inflate(z_streamp strm, int flush)
Definition: inflate.c:1257
int inflateEnd(z_streamp strm)
Definition: inflate.c:1910
#define Z_BINARY
Definition: zlib.h:140
#define Z_DEFAULT_STRATEGY
Definition: zlib.h:137
#define Z_STREAM_END
Definition: zlib.h:115
#define Z_FINISH
Definition: zlib.h:109
unsigned int uInt
Definition: zlib.h:38
#define Z_OK
Definition: zlib.h:114
int deflate(z_streamp strm, int flush) DECLSPEC_HIDDEN
Definition: deflate.c:815
#define Z_DATA_ERROR
Definition: zlib.h:119
#define Z_NO_FLUSH
Definition: zlib.h:105
int deflateEnd(z_streamp strm) DECLSPEC_HIDDEN
Definition: deflate.c:1130
#define Z_PARTIAL_FLUSH
Definition: zlib.h:106
#define Z_DEFAULT_COMPRESSION
Definition: zlib.h:130
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned char
Definition: typeof.h:29
#define assert(x)
Definition: debug.h:53
switch(r->id)
Definition: btrfs.c:3046
short int16
Definition: platform.h:11
long int32
Definition: platform.h:12
const GLdouble * v
Definition: gl.h:2040
GLdouble s
Definition: gl.h:2039
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLdouble n
Definition: glext.h:7729
GLsizei stride
Definition: glext.h:5848
const GLubyte * c
Definition: glext.h:8905
GLenum GLint GLuint mask
Definition: glext.h:6028
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLuint64EXT * result
Definition: glext.h:11304
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
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 up(mutex)
Definition: glue.h:30
uint32_t cc
Definition: isohybrid.c:75
#define ONE
Definition: jdct.h:351
int quality
Definition: jpeglib.h:992
#define c
Definition: ke_i.h:80
#define b
Definition: ke_i.h:79
if(dx< 0)
Definition: linetemp.h:194
static const struct update_accum a1
Definition: msg.c:578
static const struct update_accum a2
Definition: msg.c:586
static CRYPT_DATA_BLOB b2[]
Definition: msg.c:582
static CRYPT_DATA_BLOB b1[]
Definition: msg.c:573
static DNS_RECORDW r1
Definition: record.c:37
static DNS_RECORDW r2
Definition: record.c:38
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static const WCHAR sp[]
Definition: suminfo.c:287
static float(__cdecl *square_half_float)(float x
DWORD exp
Definition: msg.c:16058
DWORD scheme
#define inflateInit(strm)
Definition: zlib.h:1812
#define deflateInit(strm, level)
Definition: zlib.h:1810
#define log(outFile, fmt,...)
Definition: util.h:15
uint16 td_sampleformat
Definition: tif_dir.h:76
uint16 td_samplesperpixel
Definition: tif_dir.h:82
uint16 td_bitspersample
Definition: tif_dir.h:75
uint32 td_imagewidth
Definition: tif_dir.h:72
uint32 td_rowsperstrip
Definition: tif_dir.h:83
uint16 td_planarconfig
Definition: tif_dir.h:89
uint32 td_imagelength
Definition: tif_dir.h:72
TIFFVGetMethod vgetfield
Definition: tiffio.h:334
TIFFVSetMethod vsetfield
Definition: tiffio.h:333
Definition: dhcpd.h:62
Definition: parse.h:23
Definition: ecma_167.h:138
Definition: tiffiop.h:115
TIFFCodeMethod tif_encodestrip
Definition: tiffiop.h:183
TIFFCodeMethod tif_encodetile
Definition: tiffiop.h:185
TIFFTagMethods tif_tagmethods
Definition: tiffiop.h:219
tmsize_t tif_scanlinesize
Definition: tiffiop.h:193
TIFFPreMethod tif_preencode
Definition: tiffiop.h:178
TIFFBoolMethod tif_fixuptags
Definition: tiffiop.h:173
tmsize_t tif_rawcc
Definition: tiffiop.h:200
TIFFPreMethod tif_predecode
Definition: tiffiop.h:175
TIFFCodeMethod tif_decodestrip
Definition: tiffiop.h:182
TIFFPostMethod tif_postdecode
Definition: tiffiop.h:214
thandle_t tif_clientdata
Definition: tiffiop.h:207
uint32 tif_flags
Definition: tiffiop.h:119
TIFFCodeMethod tif_decoderow
Definition: tiffiop.h:180
TIFFBoolMethod tif_setupencode
Definition: tiffiop.h:176
TIFFDirectory tif_dir
Definition: tiffiop.h:151
TIFFBoolMethod tif_postencode
Definition: tiffiop.h:179
uint8 * tif_data
Definition: tiffiop.h:191
TIFFCodeMethod tif_encoderow
Definition: tiffiop.h:181
TIFFVoidMethod tif_close
Definition: tiffiop.h:186
TIFFVoidMethod tif_cleanup
Definition: tiffiop.h:188
uint32 tif_row
Definition: tiffiop.h:159
TIFFBoolMethod tif_setupdecode
Definition: tiffiop.h:174
tmsize_t tif_rawdatasize
Definition: tiffiop.h:196
tmsize_t tif_tilesize
Definition: tiffiop.h:170
uint8 * tif_rawcp
Definition: tiffiop.h:199
TIFFCodeMethod tif_decodetile
Definition: tiffiop.h:184
int tif_mode
Definition: tiffiop.h:118
uint8 * tif_rawdata
Definition: tiffiop.h:195
tmsize_t _TIFFMultiplySSize(TIFF *tif, tmsize_t first, tmsize_t second, const char *where)
Definition: tif_aux.c:59
#define TIFFInitPixarLog
Definition: tif_codec.c:66
#define CLAMP(f, min, max)
Definition: tif_color.c:177
void _TIFFSetDefaultCompressionState(TIFF *tif)
Definition: tif_compress.c:135
#define TIFF_UINT64_FORMAT
Definition: tif_config.h:52
#define TIFF_UINT64_T
Definition: tif_config.h:58
int TIFFSetField(TIFF *tif, uint32 tag,...)
Definition: tif_dir.c:807
#define FIELD_PSEUDO
Definition: tif_dir.h:190
@ TIFF_SETGET_UNDEFINED
Definition: tif_dir.h:204
@ TIFF_SETGET_INT
Definition: tif_dir.h:217
int _TIFFMergeFields(TIFF *tif, const TIFFField info[], uint32 n)
Definition: tif_dirinfo.c:369
void TIFFErrorExt(thandle_t fd, const char *module, const char *fmt,...)
Definition: tif_error.c:65
int TIFFPredictorCleanup(TIFF *tif)
Definition: tif_predict.c:857
int TIFFPredictorInit(TIFF *tif)
Definition: tif_predict.c:816
void _TIFFNoPostDecode(TIFF *tif, uint8 *buf, tmsize_t cc)
Definition: tif_read.c:1603
tmsize_t TIFFScanlineSize(TIFF *tif)
Definition: tif_strip.c:314
void TIFFSwabArrayOfShort(register uint16 *wp, tmsize_t n)
Definition: tif_swab.c:71
tmsize_t TIFFTileSize(TIFF *tif)
Definition: tif_tile.c:257
void _TIFFfree(void *p)
Definition: tif_unix.c:326
void _TIFFmemset(void *p, int v, tmsize_t c)
Definition: tif_unix.c:338
void * _TIFFmalloc(tmsize_t s)
Definition: tif_unix.c:309
void TIFFWarningExt(thandle_t fd, const char *module, const char *fmt,...)
Definition: tif_warning.c:65
int TIFFFlushData1(TIFF *tif)
Definition: tif_write.c:803
#define TIFFTAG_BITSPERSAMPLE
Definition: tiff.h:156
#define COMPRESSION_PIXARLOG
Definition: tiff.h:180
#define PIXARLOGDATAFMT_8BITABGR
Definition: tiff.h:530
#define PIXARLOGDATAFMT_8BIT
Definition: tiff.h:529
#define SAMPLEFORMAT_UINT
Definition: tiff.h:308
#define PIXARLOGDATAFMT_16BIT
Definition: tiff.h:533
#define PIXARLOGDATAFMT_12BITPICIO
Definition: tiff.h:532
#define TIFFTAG_PIXARLOGDATAFMT
Definition: tiff.h:528
#define TIFFTAG_PIXARLOGQUALITY
Definition: tiff.h:554
#define SAMPLEFORMAT_IEEEFP
Definition: tiff.h:310
#define PIXARLOGDATAFMT_11BITLOG
Definition: tiff.h:531
#define TIFFTAG_SAMPLEFORMAT
Definition: tiff.h:307
#define PIXARLOGDATAFMT_FLOAT
Definition: tiff.h:534
#define SAMPLEFORMAT_VOID
Definition: tiff.h:311
#define SAMPLEFORMAT_INT
Definition: tiff.h:309
#define PLANARCONFIG_CONTIG
Definition: tiff.h:239
TIFF_SSIZE_T tmsize_t
Definition: tiffio.h:65
#define TIFF_ANY
Definition: tiffio.h:307
int(* TIFFVSetMethod)(TIFF *, uint32, va_list)
Definition: tiffio.h:328
#define isTiled(tif)
Definition: tiffiop.h:229
#define TIFF_TMSIZE_T_MAX
Definition: tiffiop.h:81
#define TIFF_SWAB
Definition: tiffiop.h:126
#define TIFFArrayCount(a)
Definition: tiffiop.h:283
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36