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 "tiffiop.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 <math.h>
94 #include <stdio.h>
95 #include <stdlib.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) \
110 { \
111 int i; \
112 i = n; \
113 do \
114 { \
115 i--; \
116 op; \
117 } while (i > 0); \
118 }
119
horizontalAccumulateF(uint16_t * wp,int n,int stride,float * op,float * ToLinearF)120 static void horizontalAccumulateF(uint16_t *wp, int n, int stride, float *op,
121 float *ToLinearF)
122 {
123 register unsigned int cr, cg, cb, ca, mask;
124 register float t0, t1, t2, t3;
125
126 if (n >= stride)
127 {
128 mask = CODE_MASK;
129 if (stride == 3)
130 {
131 t0 = ToLinearF[cr = (wp[0] & mask)];
132 t1 = ToLinearF[cg = (wp[1] & mask)];
133 t2 = ToLinearF[cb = (wp[2] & mask)];
134 op[0] = t0;
135 op[1] = t1;
136 op[2] = t2;
137 n -= 3;
138 while (n > 0)
139 {
140 wp += 3;
141 op += 3;
142 n -= 3;
143 t0 = ToLinearF[(cr += wp[0]) & mask];
144 t1 = ToLinearF[(cg += wp[1]) & mask];
145 t2 = ToLinearF[(cb += wp[2]) & mask];
146 op[0] = t0;
147 op[1] = t1;
148 op[2] = t2;
149 }
150 }
151 else if (stride == 4)
152 {
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 n -= 4;
162 while (n > 0)
163 {
164 wp += 4;
165 op += 4;
166 n -= 4;
167 t0 = ToLinearF[(cr += wp[0]) & mask];
168 t1 = ToLinearF[(cg += wp[1]) & mask];
169 t2 = ToLinearF[(cb += wp[2]) & mask];
170 t3 = ToLinearF[(ca += wp[3]) & mask];
171 op[0] = t0;
172 op[1] = t1;
173 op[2] = t2;
174 op[3] = t3;
175 }
176 }
177 else
178 {
179 REPEAT(stride, *op = ToLinearF[*wp & mask]; wp++; op++)
180 n -= stride;
181 while (n > 0)
182 {
183 REPEAT(stride, wp[stride] += *wp; *op = ToLinearF[*wp & mask];
184 wp++; op++)
185 n -= stride;
186 }
187 }
188 }
189 }
190
horizontalAccumulate12(uint16_t * wp,int n,int stride,int16_t * op,float * ToLinearF)191 static void horizontalAccumulate12(uint16_t *wp, int n, int stride, int16_t *op,
192 float *ToLinearF)
193 {
194 register unsigned int cr, cg, cb, ca, mask;
195 register float t0, t1, t2, t3;
196
197 #define SCALE12 2048.0F
198 #define CLAMP12(t) (((t) < 3071) ? (uint16_t)(t) : 3071)
199
200 if (n >= stride)
201 {
202 mask = CODE_MASK;
203 if (stride == 3)
204 {
205 t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12;
206 t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12;
207 t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12;
208 op[0] = CLAMP12(t0);
209 op[1] = CLAMP12(t1);
210 op[2] = CLAMP12(t2);
211 n -= 3;
212 while (n > 0)
213 {
214 wp += 3;
215 op += 3;
216 n -= 3;
217 t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
218 t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
219 t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
220 op[0] = CLAMP12(t0);
221 op[1] = CLAMP12(t1);
222 op[2] = CLAMP12(t2);
223 }
224 }
225 else if (stride == 4)
226 {
227 t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12;
228 t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12;
229 t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12;
230 t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12;
231 op[0] = CLAMP12(t0);
232 op[1] = CLAMP12(t1);
233 op[2] = CLAMP12(t2);
234 op[3] = CLAMP12(t3);
235 n -= 4;
236 while (n > 0)
237 {
238 wp += 4;
239 op += 4;
240 n -= 4;
241 t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
242 t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
243 t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
244 t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12;
245 op[0] = CLAMP12(t0);
246 op[1] = CLAMP12(t1);
247 op[2] = CLAMP12(t2);
248 op[3] = CLAMP12(t3);
249 }
250 }
251 else
252 {
253 REPEAT(stride, t0 = ToLinearF[*wp & mask] * SCALE12;
254 *op = CLAMP12(t0); wp++; op++)
255 n -= stride;
256 while (n > 0)
257 {
258 REPEAT(stride, wp[stride] += *wp;
259 t0 = ToLinearF[wp[stride] & mask] * SCALE12;
260 *op = CLAMP12(t0); wp++; op++)
261 n -= stride;
262 }
263 }
264 }
265 }
266
horizontalAccumulate16(uint16_t * wp,int n,int stride,uint16_t * op,uint16_t * ToLinear16)267 static void horizontalAccumulate16(uint16_t *wp, int n, int stride,
268 uint16_t *op, uint16_t *ToLinear16)
269 {
270 register unsigned int cr, cg, cb, ca, mask;
271
272 if (n >= stride)
273 {
274 mask = CODE_MASK;
275 if (stride == 3)
276 {
277 op[0] = ToLinear16[cr = (wp[0] & mask)];
278 op[1] = ToLinear16[cg = (wp[1] & mask)];
279 op[2] = ToLinear16[cb = (wp[2] & mask)];
280 n -= 3;
281 while (n > 0)
282 {
283 wp += 3;
284 op += 3;
285 n -= 3;
286 op[0] = ToLinear16[(cr += wp[0]) & mask];
287 op[1] = ToLinear16[(cg += wp[1]) & mask];
288 op[2] = ToLinear16[(cb += wp[2]) & mask];
289 }
290 }
291 else if (stride == 4)
292 {
293 op[0] = ToLinear16[cr = (wp[0] & mask)];
294 op[1] = ToLinear16[cg = (wp[1] & mask)];
295 op[2] = ToLinear16[cb = (wp[2] & mask)];
296 op[3] = ToLinear16[ca = (wp[3] & mask)];
297 n -= 4;
298 while (n > 0)
299 {
300 wp += 4;
301 op += 4;
302 n -= 4;
303 op[0] = ToLinear16[(cr += wp[0]) & mask];
304 op[1] = ToLinear16[(cg += wp[1]) & mask];
305 op[2] = ToLinear16[(cb += wp[2]) & mask];
306 op[3] = ToLinear16[(ca += wp[3]) & mask];
307 }
308 }
309 else
310 {
311 REPEAT(stride, *op = ToLinear16[*wp & mask]; wp++; op++)
312 n -= stride;
313 while (n > 0)
314 {
315 REPEAT(stride, wp[stride] += *wp; *op = ToLinear16[*wp & mask];
316 wp++; op++)
317 n -= stride;
318 }
319 }
320 }
321 }
322
323 /*
324 * Returns the log encoded 11-bit values with the horizontal
325 * differencing undone.
326 */
horizontalAccumulate11(uint16_t * wp,int n,int stride,uint16_t * op)327 static void horizontalAccumulate11(uint16_t *wp, int n, int stride,
328 uint16_t *op)
329 {
330 register unsigned int cr, cg, cb, ca, mask;
331
332 if (n >= stride)
333 {
334 mask = CODE_MASK;
335 if (stride == 3)
336 {
337 op[0] = wp[0];
338 op[1] = wp[1];
339 op[2] = wp[2];
340 cr = wp[0];
341 cg = wp[1];
342 cb = wp[2];
343 n -= 3;
344 while (n > 0)
345 {
346 wp += 3;
347 op += 3;
348 n -= 3;
349 op[0] = (uint16_t)((cr += wp[0]) & mask);
350 op[1] = (uint16_t)((cg += wp[1]) & mask);
351 op[2] = (uint16_t)((cb += wp[2]) & mask);
352 }
353 }
354 else if (stride == 4)
355 {
356 op[0] = wp[0];
357 op[1] = wp[1];
358 op[2] = wp[2];
359 op[3] = wp[3];
360 cr = wp[0];
361 cg = wp[1];
362 cb = wp[2];
363 ca = wp[3];
364 n -= 4;
365 while (n > 0)
366 {
367 wp += 4;
368 op += 4;
369 n -= 4;
370 op[0] = (uint16_t)((cr += wp[0]) & mask);
371 op[1] = (uint16_t)((cg += wp[1]) & mask);
372 op[2] = (uint16_t)((cb += wp[2]) & mask);
373 op[3] = (uint16_t)((ca += wp[3]) & mask);
374 }
375 }
376 else
377 {
378 REPEAT(stride, *op = *wp & mask; wp++; op++)
379 n -= stride;
380 while (n > 0)
381 {
382 REPEAT(stride, wp[stride] += *wp; *op = *wp & mask; wp++; op++)
383 n -= stride;
384 }
385 }
386 }
387 }
388
horizontalAccumulate8(uint16_t * wp,int n,int stride,unsigned char * op,unsigned char * ToLinear8)389 static void horizontalAccumulate8(uint16_t *wp, int n, int stride,
390 unsigned char *op, unsigned char *ToLinear8)
391 {
392 register unsigned int cr, cg, cb, ca, mask;
393
394 if (n >= stride)
395 {
396 mask = CODE_MASK;
397 if (stride == 3)
398 {
399 op[0] = ToLinear8[cr = (wp[0] & mask)];
400 op[1] = ToLinear8[cg = (wp[1] & mask)];
401 op[2] = ToLinear8[cb = (wp[2] & mask)];
402 n -= 3;
403 while (n > 0)
404 {
405 n -= 3;
406 wp += 3;
407 op += 3;
408 op[0] = ToLinear8[(cr += wp[0]) & mask];
409 op[1] = ToLinear8[(cg += wp[1]) & mask];
410 op[2] = ToLinear8[(cb += wp[2]) & mask];
411 }
412 }
413 else if (stride == 4)
414 {
415 op[0] = ToLinear8[cr = (wp[0] & mask)];
416 op[1] = ToLinear8[cg = (wp[1] & mask)];
417 op[2] = ToLinear8[cb = (wp[2] & mask)];
418 op[3] = ToLinear8[ca = (wp[3] & mask)];
419 n -= 4;
420 while (n > 0)
421 {
422 n -= 4;
423 wp += 4;
424 op += 4;
425 op[0] = ToLinear8[(cr += wp[0]) & mask];
426 op[1] = ToLinear8[(cg += wp[1]) & mask];
427 op[2] = ToLinear8[(cb += wp[2]) & mask];
428 op[3] = ToLinear8[(ca += wp[3]) & mask];
429 }
430 }
431 else
432 {
433 REPEAT(stride, *op = ToLinear8[*wp & mask]; wp++; op++)
434 n -= stride;
435 while (n > 0)
436 {
437 REPEAT(stride, wp[stride] += *wp; *op = ToLinear8[*wp & mask];
438 wp++; op++)
439 n -= stride;
440 }
441 }
442 }
443 }
444
horizontalAccumulate8abgr(uint16_t * wp,int n,int stride,unsigned char * op,unsigned char * ToLinear8)445 static void horizontalAccumulate8abgr(uint16_t *wp, int n, int stride,
446 unsigned char *op,
447 unsigned char *ToLinear8)
448 {
449 register unsigned int cr, cg, cb, ca, mask;
450 register unsigned char t0, t1, t2, t3;
451
452 if (n >= stride)
453 {
454 mask = CODE_MASK;
455 if (stride == 3)
456 {
457 op[0] = 0;
458 t1 = ToLinear8[cb = (wp[2] & mask)];
459 t2 = ToLinear8[cg = (wp[1] & mask)];
460 t3 = ToLinear8[cr = (wp[0] & mask)];
461 op[1] = t1;
462 op[2] = t2;
463 op[3] = t3;
464 n -= 3;
465 while (n > 0)
466 {
467 n -= 3;
468 wp += 3;
469 op += 4;
470 op[0] = 0;
471 t1 = ToLinear8[(cb += wp[2]) & mask];
472 t2 = ToLinear8[(cg += wp[1]) & mask];
473 t3 = ToLinear8[(cr += wp[0]) & mask];
474 op[1] = t1;
475 op[2] = t2;
476 op[3] = t3;
477 }
478 }
479 else if (stride == 4)
480 {
481 t0 = ToLinear8[ca = (wp[3] & mask)];
482 t1 = ToLinear8[cb = (wp[2] & mask)];
483 t2 = ToLinear8[cg = (wp[1] & mask)];
484 t3 = ToLinear8[cr = (wp[0] & mask)];
485 op[0] = t0;
486 op[1] = t1;
487 op[2] = t2;
488 op[3] = t3;
489 n -= 4;
490 while (n > 0)
491 {
492 n -= 4;
493 wp += 4;
494 op += 4;
495 t0 = ToLinear8[(ca += wp[3]) & mask];
496 t1 = ToLinear8[(cb += wp[2]) & mask];
497 t2 = ToLinear8[(cg += wp[1]) & mask];
498 t3 = ToLinear8[(cr += wp[0]) & mask];
499 op[0] = t0;
500 op[1] = t1;
501 op[2] = t2;
502 op[3] = t3;
503 }
504 }
505 else
506 {
507 REPEAT(stride, *op = ToLinear8[*wp & mask]; wp++; op++)
508 n -= stride;
509 while (n > 0)
510 {
511 REPEAT(stride, wp[stride] += *wp; *op = ToLinear8[*wp & mask];
512 wp++; op++)
513 n -= stride;
514 }
515 }
516 }
517 }
518
519 /*
520 * State block for each open TIFF
521 * file using PixarLog compression/decompression.
522 */
523 typedef struct
524 {
525 TIFFPredictorState predict;
526 z_stream stream;
527 tmsize_t tbuf_size; /* only set/used on reading for now */
528 uint16_t *tbuf;
529 uint16_t stride;
530 int state;
531 int user_datafmt;
532 int quality;
533 #define PLSTATE_INIT 1
534
535 TIFFVSetMethod vgetparent; /* super-class method */
536 TIFFVSetMethod vsetparent; /* super-class method */
537
538 float *ToLinearF;
539 uint16_t *ToLinear16;
540 unsigned char *ToLinear8;
541 uint16_t *FromLT2;
542 uint16_t *From14; /* Really for 16-bit data, but we shift down 2 */
543 uint16_t *From8;
544
545 } PixarLogState;
546
PixarLogMakeTables(TIFF * tif,PixarLogState * sp)547 static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp)
548 {
549
550 /*
551 * We make several tables here to convert between various external
552 * representations (float, 16-bit, and 8-bit) and the internal
553 * 11-bit companded representation. The 11-bit representation has two
554 * distinct regions. A linear bottom end up through .018316 in steps
555 * of about .000073, and a region of constant ratio up to about 25.
556 * These floating point numbers are stored in the main table ToLinearF.
557 * All other tables are derived from this one. The tables (and the
558 * ratios) are continuous at the internal seam.
559 */
560
561 int nlin, lt2size;
562 int i, j;
563 double b, c, linstep, v;
564 float *ToLinearF;
565 uint16_t *ToLinear16;
566 unsigned char *ToLinear8;
567 uint16_t *FromLT2;
568 uint16_t *From14; /* Really for 16-bit data, but we shift down 2 */
569 uint16_t *From8;
570
571 c = log(RATIO);
572 nlin = (int)(1. / c); /* nlin must be an integer */
573 c = 1. / nlin;
574 b = exp(-c * ONE); /* multiplicative scale factor [b*exp(c*ONE) = 1] */
575 linstep = b * c * exp(1.);
576
577 LogK1 = (float)(1. / c); /* if (v >= 2) token = k1*log(v*k2) */
578 LogK2 = (float)(1. / b);
579 lt2size = (int)(2. / linstep) + 1;
580 FromLT2 = (uint16_t *)_TIFFmallocExt(tif, lt2size * sizeof(uint16_t));
581 From14 = (uint16_t *)_TIFFmallocExt(tif, 16384 * sizeof(uint16_t));
582 From8 = (uint16_t *)_TIFFmallocExt(tif, 256 * sizeof(uint16_t));
583 ToLinearF = (float *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(float));
584 ToLinear16 = (uint16_t *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(uint16_t));
585 ToLinear8 =
586 (unsigned char *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(unsigned char));
587 if (FromLT2 == NULL || From14 == NULL || From8 == NULL ||
588 ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL)
589 {
590 if (FromLT2)
591 _TIFFfreeExt(tif, FromLT2);
592 if (From14)
593 _TIFFfreeExt(tif, From14);
594 if (From8)
595 _TIFFfreeExt(tif, From8);
596 if (ToLinearF)
597 _TIFFfreeExt(tif, ToLinearF);
598 if (ToLinear16)
599 _TIFFfreeExt(tif, ToLinear16);
600 if (ToLinear8)
601 _TIFFfreeExt(tif, ToLinear8);
602 sp->FromLT2 = NULL;
603 sp->From14 = NULL;
604 sp->From8 = NULL;
605 sp->ToLinearF = NULL;
606 sp->ToLinear16 = NULL;
607 sp->ToLinear8 = NULL;
608 return 0;
609 }
610
611 j = 0;
612
613 for (i = 0; i < nlin; i++)
614 {
615 v = i * linstep;
616 ToLinearF[j++] = (float)v;
617 }
618
619 for (i = nlin; i < TSIZE; i++)
620 ToLinearF[j++] = (float)(b * exp(c * i));
621
622 ToLinearF[2048] = ToLinearF[2047];
623
624 for (i = 0; i < TSIZEP1; i++)
625 {
626 v = ToLinearF[i] * 65535.0 + 0.5;
627 ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16_t)v;
628 v = ToLinearF[i] * 255.0 + 0.5;
629 ToLinear8[i] = (v > 255.0) ? 255 : (unsigned char)v;
630 }
631
632 j = 0;
633 for (i = 0; i < lt2size; i++)
634 {
635 if ((i * linstep) * (i * linstep) > ToLinearF[j] * ToLinearF[j + 1])
636 j++;
637 FromLT2[i] = (uint16_t)j;
638 }
639
640 /*
641 * Since we lose info anyway on 16-bit data, we set up a 14-bit
642 * table and shift 16-bit values down two bits on input.
643 * saves a little table space.
644 */
645 j = 0;
646 for (i = 0; i < 16384; i++)
647 {
648 while ((i / 16383.) * (i / 16383.) > ToLinearF[j] * ToLinearF[j + 1])
649 j++;
650 From14[i] = (uint16_t)j;
651 }
652
653 j = 0;
654 for (i = 0; i < 256; i++)
655 {
656 while ((i / 255.) * (i / 255.) > ToLinearF[j] * ToLinearF[j + 1])
657 j++;
658 From8[i] = (uint16_t)j;
659 }
660
661 Fltsize = (float)(lt2size / 2);
662
663 sp->ToLinearF = ToLinearF;
664 sp->ToLinear16 = ToLinear16;
665 sp->ToLinear8 = ToLinear8;
666 sp->FromLT2 = FromLT2;
667 sp->From14 = From14;
668 sp->From8 = From8;
669
670 return 1;
671 }
672
673 #define DecoderState(tif) ((PixarLogState *)(tif)->tif_data)
674 #define EncoderState(tif) ((PixarLogState *)(tif)->tif_data)
675
676 static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
677 static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
678
679 #define PIXARLOGDATAFMT_UNKNOWN -1
680
PixarLogGuessDataFmt(TIFFDirectory * td)681 static int PixarLogGuessDataFmt(TIFFDirectory *td)
682 {
683 int guess = PIXARLOGDATAFMT_UNKNOWN;
684 int format = td->td_sampleformat;
685
686 /* If the user didn't tell us his datafmt,
687 * take our best guess from the bitspersample.
688 */
689 switch (td->td_bitspersample)
690 {
691 case 32:
692 if (format == SAMPLEFORMAT_IEEEFP)
693 guess = PIXARLOGDATAFMT_FLOAT;
694 break;
695 case 16:
696 if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
697 guess = PIXARLOGDATAFMT_16BIT;
698 break;
699 case 12:
700 if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT)
701 guess = PIXARLOGDATAFMT_12BITPICIO;
702 break;
703 case 11:
704 if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
705 guess = PIXARLOGDATAFMT_11BITLOG;
706 break;
707 case 8:
708 if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
709 guess = PIXARLOGDATAFMT_8BIT;
710 break;
711 }
712
713 return guess;
714 }
715
multiply_ms(tmsize_t m1,tmsize_t m2)716 static tmsize_t multiply_ms(tmsize_t m1, tmsize_t m2)
717 {
718 return _TIFFMultiplySSize(NULL, m1, m2, NULL);
719 }
720
add_ms(tmsize_t m1,tmsize_t m2)721 static tmsize_t add_ms(tmsize_t m1, tmsize_t m2)
722 {
723 assert(m1 >= 0 && m2 >= 0);
724 /* if either input is zero, assume overflow already occurred */
725 if (m1 == 0 || m2 == 0)
726 return 0;
727 else if (m1 > TIFF_TMSIZE_T_MAX - m2)
728 return 0;
729
730 return m1 + m2;
731 }
732
PixarLogFixupTags(TIFF * tif)733 static int PixarLogFixupTags(TIFF *tif)
734 {
735 (void)tif;
736 return (1);
737 }
738
PixarLogSetupDecode(TIFF * tif)739 static int PixarLogSetupDecode(TIFF *tif)
740 {
741 static const char module[] = "PixarLogSetupDecode";
742 TIFFDirectory *td = &tif->tif_dir;
743 PixarLogState *sp = DecoderState(tif);
744 tmsize_t tbuf_size;
745 uint32_t strip_height;
746
747 assert(sp != NULL);
748
749 /* This function can possibly be called several times by */
750 /* PredictorSetupDecode() if this function succeeds but */
751 /* PredictorSetup() fails */
752 if ((sp->state & PLSTATE_INIT) != 0)
753 return 1;
754
755 strip_height = td->td_rowsperstrip;
756 if (strip_height > td->td_imagelength)
757 strip_height = td->td_imagelength;
758
759 /* Make sure no byte swapping happens on the data
760 * after decompression. */
761 tif->tif_postdecode = _TIFFNoPostDecode;
762
763 /* for some reason, we can't do this in TIFFInitPixarLog */
764
765 sp->stride =
766 (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel
767 : 1);
768 tbuf_size = multiply_ms(
769 multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), strip_height),
770 sizeof(uint16_t));
771 /* add one more stride in case input ends mid-stride */
772 tbuf_size = add_ms(tbuf_size, sizeof(uint16_t) * sp->stride);
773 if (tbuf_size == 0)
774 return (0); /* TODO: this is an error return without error report
775 through TIFFErrorExt */
776 sp->tbuf = (uint16_t *)_TIFFmallocExt(tif, tbuf_size);
777 if (sp->tbuf == NULL)
778 return (0);
779 sp->tbuf_size = tbuf_size;
780 if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
781 sp->user_datafmt = PixarLogGuessDataFmt(td);
782 if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
783 {
784 _TIFFfreeExt(tif, sp->tbuf);
785 sp->tbuf = NULL;
786 sp->tbuf_size = 0;
787 TIFFErrorExtR(tif, module,
788 "PixarLog compression can't handle bits depth/data "
789 "format combination (depth: %" PRIu16 ")",
790 td->td_bitspersample);
791 return (0);
792 }
793
794 if (inflateInit(&sp->stream) != Z_OK)
795 {
796 _TIFFfreeExt(tif, sp->tbuf);
797 sp->tbuf = NULL;
798 sp->tbuf_size = 0;
799 TIFFErrorExtR(tif, module, "%s",
800 sp->stream.msg ? sp->stream.msg : "(null)");
801 return (0);
802 }
803 else
804 {
805 sp->state |= PLSTATE_INIT;
806 return (1);
807 }
808 }
809
810 /*
811 * Setup state for decoding a strip.
812 */
PixarLogPreDecode(TIFF * tif,uint16_t s)813 static int PixarLogPreDecode(TIFF *tif, uint16_t s)
814 {
815 static const char module[] = "PixarLogPreDecode";
816 PixarLogState *sp = DecoderState(tif);
817
818 (void)s;
819 assert(sp != NULL);
820 sp->stream.next_in = tif->tif_rawdata;
821 assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised,
822 we need to simplify this code to reflect a ZLib that is likely updated
823 to deal with 8byte memory sizes, though this code will respond
824 appropriately even before we simplify it */
825 sp->stream.avail_in = (uInt)tif->tif_rawcc;
826 if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
827 {
828 TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size");
829 return (0);
830 }
831 return (inflateReset(&sp->stream) == Z_OK);
832 }
833
PixarLogDecode(TIFF * tif,uint8_t * op,tmsize_t occ,uint16_t s)834 static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
835 {
836 static const char module[] = "PixarLogDecode";
837 TIFFDirectory *td = &tif->tif_dir;
838 PixarLogState *sp = DecoderState(tif);
839 tmsize_t i;
840 tmsize_t nsamples;
841 int llen;
842 uint16_t *up;
843
844 switch (sp->user_datafmt)
845 {
846 case PIXARLOGDATAFMT_FLOAT:
847 nsamples = occ / sizeof(float); /* XXX float == 32 bits */
848 break;
849 case PIXARLOGDATAFMT_16BIT:
850 case PIXARLOGDATAFMT_12BITPICIO:
851 case PIXARLOGDATAFMT_11BITLOG:
852 nsamples = occ / sizeof(uint16_t); /* XXX uint16_t == 16 bits */
853 break;
854 case PIXARLOGDATAFMT_8BIT:
855 case PIXARLOGDATAFMT_8BITABGR:
856 nsamples = occ;
857 break;
858 default:
859 TIFFErrorExtR(tif, module,
860 "%" PRIu16 " bit input not supported in PixarLog",
861 td->td_bitspersample);
862 return 0;
863 }
864
865 llen = sp->stride * td->td_imagewidth;
866
867 (void)s;
868 assert(sp != NULL);
869
870 sp->stream.next_in = tif->tif_rawcp;
871 sp->stream.avail_in = (uInt)tif->tif_rawcc;
872
873 sp->stream.next_out = (unsigned char *)sp->tbuf;
874 assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised,
875 we need to simplify this code to reflect a ZLib that is likely updated
876 to deal with 8byte memory sizes, though this code will respond
877 appropriately even before we simplify it */
878 sp->stream.avail_out = (uInt)(nsamples * sizeof(uint16_t));
879 if (sp->stream.avail_out != nsamples * sizeof(uint16_t))
880 {
881 TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size");
882 return (0);
883 }
884 /* Check that we will not fill more than what was allocated */
885 if (sp->tbuf_size < 0 || sp->stream.avail_out > (uInt) sp->tbuf_size)
886 {
887 TIFFErrorExtR(tif, module, "sp->stream.avail_out > sp->tbuf_size");
888 return (0);
889 }
890 do
891 {
892 int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
893 if (state == Z_STREAM_END)
894 {
895 break; /* XXX */
896 }
897 if (state == Z_DATA_ERROR)
898 {
899 TIFFErrorExtR(
900 tif, module, "Decoding error at scanline %" PRIu32 ", %s",
901 tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)");
902 return (0);
903 }
904 if (state != Z_OK)
905 {
906 TIFFErrorExtR(tif, module, "ZLib error: %s",
907 sp->stream.msg ? sp->stream.msg : "(null)");
908 return (0);
909 }
910 } while (sp->stream.avail_out > 0);
911
912 /* hopefully, we got all the bytes we needed */
913 if (sp->stream.avail_out != 0)
914 {
915 TIFFErrorExtR(tif, module,
916 "Not enough data at scanline %" PRIu32
917 " (short %u bytes)",
918 tif->tif_row, sp->stream.avail_out);
919 return (0);
920 }
921
922 tif->tif_rawcp = sp->stream.next_in;
923 tif->tif_rawcc = sp->stream.avail_in;
924
925 up = sp->tbuf;
926 /* Swap bytes in the data if from a different endian machine. */
927 if (tif->tif_flags & TIFF_SWAB)
928 TIFFSwabArrayOfShort(up, nsamples);
929
930 /*
931 * if llen is not an exact multiple of nsamples, the decode operation
932 * may overflow the output buffer, so truncate it enough to prevent
933 * that but still salvage as much data as possible.
934 */
935 if (nsamples % llen)
936 {
937 TIFFWarningExtR(tif, module,
938 "stride %d is not a multiple of sample count, "
939 "%" TIFF_SSIZE_FORMAT ", data truncated.",
940 llen, nsamples);
941 nsamples -= nsamples % llen;
942 }
943
944 for (i = 0; i < nsamples; i += llen, up += llen)
945 {
946 switch (sp->user_datafmt)
947 {
948 case PIXARLOGDATAFMT_FLOAT:
949 horizontalAccumulateF(up, llen, sp->stride, (float *)op,
950 sp->ToLinearF);
951 op += llen * sizeof(float);
952 break;
953 case PIXARLOGDATAFMT_16BIT:
954 horizontalAccumulate16(up, llen, sp->stride, (uint16_t *)op,
955 sp->ToLinear16);
956 op += llen * sizeof(uint16_t);
957 break;
958 case PIXARLOGDATAFMT_12BITPICIO:
959 horizontalAccumulate12(up, llen, sp->stride, (int16_t *)op,
960 sp->ToLinearF);
961 op += llen * sizeof(int16_t);
962 break;
963 case PIXARLOGDATAFMT_11BITLOG:
964 horizontalAccumulate11(up, llen, sp->stride, (uint16_t *)op);
965 op += llen * sizeof(uint16_t);
966 break;
967 case PIXARLOGDATAFMT_8BIT:
968 horizontalAccumulate8(up, llen, sp->stride, (unsigned char *)op,
969 sp->ToLinear8);
970 op += llen * sizeof(unsigned char);
971 break;
972 case PIXARLOGDATAFMT_8BITABGR:
973 horizontalAccumulate8abgr(up, llen, sp->stride,
974 (unsigned char *)op, sp->ToLinear8);
975 op += llen * sizeof(unsigned char);
976 break;
977 default:
978 TIFFErrorExtR(tif, module, "Unsupported bits/sample: %" PRIu16,
979 td->td_bitspersample);
980 return (0);
981 }
982 }
983
984 return (1);
985 }
986
PixarLogSetupEncode(TIFF * tif)987 static int PixarLogSetupEncode(TIFF *tif)
988 {
989 static const char module[] = "PixarLogSetupEncode";
990 TIFFDirectory *td = &tif->tif_dir;
991 PixarLogState *sp = EncoderState(tif);
992 tmsize_t tbuf_size;
993
994 assert(sp != NULL);
995
996 /* for some reason, we can't do this in TIFFInitPixarLog */
997
998 sp->stride =
999 (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel
1000 : 1);
1001 tbuf_size =
1002 multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth),
1003 td->td_rowsperstrip),
1004 sizeof(uint16_t));
1005 if (tbuf_size == 0)
1006 return (0); /* TODO: this is an error return without error report
1007 through TIFFErrorExt */
1008 sp->tbuf = (uint16_t *)_TIFFmallocExt(tif, tbuf_size);
1009 if (sp->tbuf == NULL)
1010 return (0);
1011 if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
1012 sp->user_datafmt = PixarLogGuessDataFmt(td);
1013 if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
1014 {
1015 TIFFErrorExtR(tif, module,
1016 "PixarLog compression can't handle %" PRIu16
1017 " bit linear encodings",
1018 td->td_bitspersample);
1019 return (0);
1020 }
1021
1022 if (deflateInit(&sp->stream, sp->quality) != Z_OK)
1023 {
1024 TIFFErrorExtR(tif, module, "%s",
1025 sp->stream.msg ? sp->stream.msg : "(null)");
1026 return (0);
1027 }
1028 else
1029 {
1030 sp->state |= PLSTATE_INIT;
1031 return (1);
1032 }
1033 }
1034
1035 /*
1036 * Reset encoding state at the start of a strip.
1037 */
PixarLogPreEncode(TIFF * tif,uint16_t s)1038 static int PixarLogPreEncode(TIFF *tif, uint16_t s)
1039 {
1040 static const char module[] = "PixarLogPreEncode";
1041 PixarLogState *sp = EncoderState(tif);
1042
1043 (void)s;
1044 assert(sp != NULL);
1045 sp->stream.next_out = tif->tif_rawdata;
1046 assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised,
1047 we need to simplify this code to reflect a ZLib that is likely updated
1048 to deal with 8byte memory sizes, though this code will respond
1049 appropriately even before we simplify it */
1050 sp->stream.avail_out = (uInt)tif->tif_rawdatasize;
1051 if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
1052 {
1053 TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size");
1054 return (0);
1055 }
1056 return (deflateReset(&sp->stream) == Z_OK);
1057 }
1058
horizontalDifferenceF(float * ip,int n,int stride,uint16_t * wp,uint16_t * FromLT2)1059 static void horizontalDifferenceF(float *ip, int n, int stride, uint16_t *wp,
1060 uint16_t *FromLT2)
1061 {
1062 int32_t r1, g1, b1, a1, r2, g2, b2, a2, mask;
1063 float fltsize = Fltsize;
1064
1065 #define CLAMP(v) \
1066 ((v < (float)0.) ? 0 \
1067 : (v < (float)2.) ? FromLT2[(int)(v * fltsize)] \
1068 : (v > (float)24.2) ? 2047 \
1069 : LogK1 * log(v * LogK2) + 0.5)
1070
1071 mask = CODE_MASK;
1072 if (n >= stride)
1073 {
1074 if (stride == 3)
1075 {
1076 r2 = wp[0] = (uint16_t)CLAMP(ip[0]);
1077 g2 = wp[1] = (uint16_t)CLAMP(ip[1]);
1078 b2 = wp[2] = (uint16_t)CLAMP(ip[2]);
1079 n -= 3;
1080 while (n > 0)
1081 {
1082 n -= 3;
1083 wp += 3;
1084 ip += 3;
1085 r1 = (int32_t)CLAMP(ip[0]);
1086 wp[0] = (uint16_t)((r1 - r2) & mask);
1087 r2 = r1;
1088 g1 = (int32_t)CLAMP(ip[1]);
1089 wp[1] = (uint16_t)((g1 - g2) & mask);
1090 g2 = g1;
1091 b1 = (int32_t)CLAMP(ip[2]);
1092 wp[2] = (uint16_t)((b1 - b2) & mask);
1093 b2 = b1;
1094 }
1095 }
1096 else if (stride == 4)
1097 {
1098 r2 = wp[0] = (uint16_t)CLAMP(ip[0]);
1099 g2 = wp[1] = (uint16_t)CLAMP(ip[1]);
1100 b2 = wp[2] = (uint16_t)CLAMP(ip[2]);
1101 a2 = wp[3] = (uint16_t)CLAMP(ip[3]);
1102 n -= 4;
1103 while (n > 0)
1104 {
1105 n -= 4;
1106 wp += 4;
1107 ip += 4;
1108 r1 = (int32_t)CLAMP(ip[0]);
1109 wp[0] = (uint16_t)((r1 - r2) & mask);
1110 r2 = r1;
1111 g1 = (int32_t)CLAMP(ip[1]);
1112 wp[1] = (uint16_t)((g1 - g2) & mask);
1113 g2 = g1;
1114 b1 = (int32_t)CLAMP(ip[2]);
1115 wp[2] = (uint16_t)((b1 - b2) & mask);
1116 b2 = b1;
1117 a1 = (int32_t)CLAMP(ip[3]);
1118 wp[3] = (uint16_t)((a1 - a2) & mask);
1119 a2 = a1;
1120 }
1121 }
1122 else
1123 {
1124 REPEAT(stride, wp[0] = (uint16_t)CLAMP(ip[0]); wp++; ip++)
1125 n -= stride;
1126 while (n > 0)
1127 {
1128 REPEAT(stride,
1129 wp[0] = (uint16_t)(((int32_t)CLAMP(ip[0]) -
1130 (int32_t)CLAMP(ip[-stride])) &
1131 mask);
1132 wp++; ip++)
1133 n -= stride;
1134 }
1135 }
1136 }
1137 }
1138
horizontalDifference16(unsigned short * ip,int n,int stride,unsigned short * wp,uint16_t * From14)1139 static void horizontalDifference16(unsigned short *ip, int n, int stride,
1140 unsigned short *wp, uint16_t *From14)
1141 {
1142 register int r1, g1, b1, a1, r2, g2, b2, a2, mask;
1143
1144 /* assumption is unsigned pixel values */
1145 #undef CLAMP
1146 #define CLAMP(v) From14[(v) >> 2]
1147
1148 mask = CODE_MASK;
1149 if (n >= stride)
1150 {
1151 if (stride == 3)
1152 {
1153 r2 = wp[0] = CLAMP(ip[0]);
1154 g2 = wp[1] = CLAMP(ip[1]);
1155 b2 = wp[2] = CLAMP(ip[2]);
1156 n -= 3;
1157 while (n > 0)
1158 {
1159 n -= 3;
1160 wp += 3;
1161 ip += 3;
1162 r1 = CLAMP(ip[0]);
1163 wp[0] = (uint16_t)((r1 - r2) & mask);
1164 r2 = r1;
1165 g1 = CLAMP(ip[1]);
1166 wp[1] = (uint16_t)((g1 - g2) & mask);
1167 g2 = g1;
1168 b1 = CLAMP(ip[2]);
1169 wp[2] = (uint16_t)((b1 - b2) & mask);
1170 b2 = b1;
1171 }
1172 }
1173 else if (stride == 4)
1174 {
1175 r2 = wp[0] = CLAMP(ip[0]);
1176 g2 = wp[1] = CLAMP(ip[1]);
1177 b2 = wp[2] = CLAMP(ip[2]);
1178 a2 = wp[3] = CLAMP(ip[3]);
1179 n -= 4;
1180 while (n > 0)
1181 {
1182 n -= 4;
1183 wp += 4;
1184 ip += 4;
1185 r1 = CLAMP(ip[0]);
1186 wp[0] = (uint16_t)((r1 - r2) & mask);
1187 r2 = r1;
1188 g1 = CLAMP(ip[1]);
1189 wp[1] = (uint16_t)((g1 - g2) & mask);
1190 g2 = g1;
1191 b1 = CLAMP(ip[2]);
1192 wp[2] = (uint16_t)((b1 - b2) & mask);
1193 b2 = b1;
1194 a1 = CLAMP(ip[3]);
1195 wp[3] = (uint16_t)((a1 - a2) & mask);
1196 a2 = a1;
1197 }
1198 }
1199 else
1200 {
1201 REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++)
1202 n -= stride;
1203 while (n > 0)
1204 {
1205 REPEAT(stride,
1206 wp[0] = (uint16_t)((CLAMP(ip[0]) - CLAMP(ip[-stride])) &
1207 mask);
1208 wp++; ip++)
1209 n -= stride;
1210 }
1211 }
1212 }
1213 }
1214
horizontalDifference8(unsigned char * ip,int n,int stride,unsigned short * wp,uint16_t * From8)1215 static void horizontalDifference8(unsigned char *ip, int n, int stride,
1216 unsigned short *wp, uint16_t *From8)
1217 {
1218 register int r1, g1, b1, a1, r2, g2, b2, a2, mask;
1219
1220 #undef CLAMP
1221 #define CLAMP(v) (From8[(v)])
1222
1223 mask = CODE_MASK;
1224 if (n >= stride)
1225 {
1226 if (stride == 3)
1227 {
1228 r2 = wp[0] = CLAMP(ip[0]);
1229 g2 = wp[1] = CLAMP(ip[1]);
1230 b2 = wp[2] = CLAMP(ip[2]);
1231 n -= 3;
1232 while (n > 0)
1233 {
1234 n -= 3;
1235 r1 = CLAMP(ip[3]);
1236 wp[3] = (uint16_t)((r1 - r2) & mask);
1237 r2 = r1;
1238 g1 = CLAMP(ip[4]);
1239 wp[4] = (uint16_t)((g1 - g2) & mask);
1240 g2 = g1;
1241 b1 = CLAMP(ip[5]);
1242 wp[5] = (uint16_t)((b1 - b2) & mask);
1243 b2 = b1;
1244 wp += 3;
1245 ip += 3;
1246 }
1247 }
1248 else if (stride == 4)
1249 {
1250 r2 = wp[0] = CLAMP(ip[0]);
1251 g2 = wp[1] = CLAMP(ip[1]);
1252 b2 = wp[2] = CLAMP(ip[2]);
1253 a2 = wp[3] = CLAMP(ip[3]);
1254 n -= 4;
1255 while (n > 0)
1256 {
1257 n -= 4;
1258 r1 = CLAMP(ip[4]);
1259 wp[4] = (uint16_t)((r1 - r2) & mask);
1260 r2 = r1;
1261 g1 = CLAMP(ip[5]);
1262 wp[5] = (uint16_t)((g1 - g2) & mask);
1263 g2 = g1;
1264 b1 = CLAMP(ip[6]);
1265 wp[6] = (uint16_t)((b1 - b2) & mask);
1266 b2 = b1;
1267 a1 = CLAMP(ip[7]);
1268 wp[7] = (uint16_t)((a1 - a2) & mask);
1269 a2 = a1;
1270 wp += 4;
1271 ip += 4;
1272 }
1273 }
1274 else
1275 {
1276 REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++)
1277 n -= stride;
1278 while (n > 0)
1279 {
1280 REPEAT(stride,
1281 wp[0] = (uint16_t)((CLAMP(ip[0]) - CLAMP(ip[-stride])) &
1282 mask);
1283 wp++; ip++)
1284 n -= stride;
1285 }
1286 }
1287 }
1288 }
1289
1290 /*
1291 * Encode a chunk of pixels.
1292 */
PixarLogEncode(TIFF * tif,uint8_t * bp,tmsize_t cc,uint16_t s)1293 static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
1294 {
1295 static const char module[] = "PixarLogEncode";
1296 TIFFDirectory *td = &tif->tif_dir;
1297 PixarLogState *sp = EncoderState(tif);
1298 tmsize_t i;
1299 tmsize_t n;
1300 int llen;
1301 unsigned short *up;
1302
1303 (void)s;
1304
1305 switch (sp->user_datafmt)
1306 {
1307 case PIXARLOGDATAFMT_FLOAT:
1308 n = cc / sizeof(float); /* XXX float == 32 bits */
1309 break;
1310 case PIXARLOGDATAFMT_16BIT:
1311 case PIXARLOGDATAFMT_12BITPICIO:
1312 case PIXARLOGDATAFMT_11BITLOG:
1313 n = cc / sizeof(uint16_t); /* XXX uint16_t == 16 bits */
1314 break;
1315 case PIXARLOGDATAFMT_8BIT:
1316 case PIXARLOGDATAFMT_8BITABGR:
1317 n = cc;
1318 break;
1319 default:
1320 TIFFErrorExtR(tif, module,
1321 "%" PRIu16 " bit input not supported in PixarLog",
1322 td->td_bitspersample);
1323 return 0;
1324 }
1325
1326 llen = sp->stride * td->td_imagewidth;
1327 /* Check against the number of elements (of size uint16_t) of sp->tbuf */
1328 if (n > ((tmsize_t)td->td_rowsperstrip * llen))
1329 {
1330 TIFFErrorExtR(tif, module, "Too many input bytes provided");
1331 return 0;
1332 }
1333
1334 for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen)
1335 {
1336 switch (sp->user_datafmt)
1337 {
1338 case PIXARLOGDATAFMT_FLOAT:
1339 horizontalDifferenceF((float *)bp, llen, sp->stride, up,
1340 sp->FromLT2);
1341 bp += llen * sizeof(float);
1342 break;
1343 case PIXARLOGDATAFMT_16BIT:
1344 horizontalDifference16((uint16_t *)bp, llen, sp->stride, up,
1345 sp->From14);
1346 bp += llen * sizeof(uint16_t);
1347 break;
1348 case PIXARLOGDATAFMT_8BIT:
1349 horizontalDifference8((unsigned char *)bp, llen, sp->stride, up,
1350 sp->From8);
1351 bp += llen * sizeof(unsigned char);
1352 break;
1353 default:
1354 TIFFErrorExtR(tif, module,
1355 "%" PRIu16 " bit input not supported in PixarLog",
1356 td->td_bitspersample);
1357 return 0;
1358 }
1359 }
1360
1361 sp->stream.next_in = (unsigned char *)sp->tbuf;
1362 assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised,
1363 we need to simplify this code to reflect a ZLib that is likely updated
1364 to deal with 8byte memory sizes, though this code will respond
1365 appropriately even before we simplify it */
1366 sp->stream.avail_in = (uInt)(n * sizeof(uint16_t));
1367 if ((sp->stream.avail_in / sizeof(uint16_t)) != (uInt)n)
1368 {
1369 TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size");
1370 return (0);
1371 }
1372
1373 do
1374 {
1375 if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK)
1376 {
1377 TIFFErrorExtR(tif, module, "Encoder error: %s",
1378 sp->stream.msg ? sp->stream.msg : "(null)");
1379 return (0);
1380 }
1381 if (sp->stream.avail_out == 0)
1382 {
1383 tif->tif_rawcc = tif->tif_rawdatasize;
1384 if (!TIFFFlushData1(tif))
1385 return 0;
1386 sp->stream.next_out = tif->tif_rawdata;
1387 sp->stream.avail_out =
1388 (uInt)tif
1389 ->tif_rawdatasize; /* this is a safe typecast, as check is
1390 made already in PixarLogPreEncode */
1391 }
1392 } while (sp->stream.avail_in > 0);
1393 return (1);
1394 }
1395
1396 /*
1397 * Finish off an encoded strip by flushing the last
1398 * string and tacking on an End Of Information code.
1399 */
1400
PixarLogPostEncode(TIFF * tif)1401 static int PixarLogPostEncode(TIFF *tif)
1402 {
1403 static const char module[] = "PixarLogPostEncode";
1404 PixarLogState *sp = EncoderState(tif);
1405 int state;
1406
1407 sp->stream.avail_in = 0;
1408
1409 do
1410 {
1411 state = deflate(&sp->stream, Z_FINISH);
1412 switch (state)
1413 {
1414 case Z_STREAM_END:
1415 case Z_OK:
1416 if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
1417 {
1418 tif->tif_rawcc =
1419 tif->tif_rawdatasize - sp->stream.avail_out;
1420 if (!TIFFFlushData1(tif))
1421 return 0;
1422 sp->stream.next_out = tif->tif_rawdata;
1423 sp->stream.avail_out =
1424 (uInt)tif->tif_rawdatasize; /* this is a safe typecast,
1425 as check is made already
1426 in PixarLogPreEncode */
1427 }
1428 break;
1429 default:
1430 TIFFErrorExtR(tif, module, "ZLib error: %s",
1431 sp->stream.msg ? sp->stream.msg : "(null)");
1432 return (0);
1433 }
1434 } while (state != Z_STREAM_END);
1435 return (1);
1436 }
1437
PixarLogClose(TIFF * tif)1438 static void PixarLogClose(TIFF *tif)
1439 {
1440 PixarLogState *sp = (PixarLogState *)tif->tif_data;
1441 TIFFDirectory *td = &tif->tif_dir;
1442
1443 assert(sp != 0);
1444 /* In a really sneaky (and really incorrect, and untruthful, and
1445 * troublesome, and error-prone) maneuver that completely goes against
1446 * the spirit of TIFF, and breaks TIFF, on close, we covertly
1447 * modify both bitspersample and sampleformat in the directory to
1448 * indicate 8-bit linear. This way, the decode "just works" even for
1449 * readers that don't know about PixarLog, or how to set
1450 * the PIXARLOGDATFMT pseudo-tag.
1451 */
1452
1453 if (sp->state & PLSTATE_INIT)
1454 {
1455 /* We test the state to avoid an issue such as in
1456 * http://bugzilla.maptools.org/show_bug.cgi?id=2604
1457 * What appends in that case is that the bitspersample is 1 and
1458 * a TransferFunction is set. The size of the TransferFunction
1459 * depends on 1<<bitspersample. So if we increase it, an access
1460 * out of the buffer will happen at directory flushing.
1461 * Another option would be to clear those targs.
1462 */
1463 td->td_bitspersample = 8;
1464 td->td_sampleformat = SAMPLEFORMAT_UINT;
1465 }
1466 }
1467
PixarLogCleanup(TIFF * tif)1468 static void PixarLogCleanup(TIFF *tif)
1469 {
1470 PixarLogState *sp = (PixarLogState *)tif->tif_data;
1471
1472 assert(sp != 0);
1473
1474 (void)TIFFPredictorCleanup(tif);
1475
1476 tif->tif_tagmethods.vgetfield = sp->vgetparent;
1477 tif->tif_tagmethods.vsetfield = sp->vsetparent;
1478
1479 if (sp->FromLT2)
1480 _TIFFfreeExt(tif, sp->FromLT2);
1481 if (sp->From14)
1482 _TIFFfreeExt(tif, sp->From14);
1483 if (sp->From8)
1484 _TIFFfreeExt(tif, sp->From8);
1485 if (sp->ToLinearF)
1486 _TIFFfreeExt(tif, sp->ToLinearF);
1487 if (sp->ToLinear16)
1488 _TIFFfreeExt(tif, sp->ToLinear16);
1489 if (sp->ToLinear8)
1490 _TIFFfreeExt(tif, sp->ToLinear8);
1491 if (sp->state & PLSTATE_INIT)
1492 {
1493 if (tif->tif_mode == O_RDONLY)
1494 inflateEnd(&sp->stream);
1495 else
1496 deflateEnd(&sp->stream);
1497 }
1498 if (sp->tbuf)
1499 _TIFFfreeExt(tif, sp->tbuf);
1500 _TIFFfreeExt(tif, sp);
1501 tif->tif_data = NULL;
1502
1503 _TIFFSetDefaultCompressionState(tif);
1504 }
1505
PixarLogVSetField(TIFF * tif,uint32_t tag,va_list ap)1506 static int PixarLogVSetField(TIFF *tif, uint32_t tag, va_list ap)
1507 {
1508 static const char module[] = "PixarLogVSetField";
1509 PixarLogState *sp = (PixarLogState *)tif->tif_data;
1510 int result;
1511
1512 switch (tag)
1513 {
1514 case TIFFTAG_PIXARLOGQUALITY:
1515 sp->quality = (int)va_arg(ap, int);
1516 if (tif->tif_mode != O_RDONLY && (sp->state & PLSTATE_INIT))
1517 {
1518 if (deflateParams(&sp->stream, sp->quality,
1519 Z_DEFAULT_STRATEGY) != Z_OK)
1520 {
1521 TIFFErrorExtR(tif, module, "ZLib error: %s",
1522 sp->stream.msg ? sp->stream.msg : "(null)");
1523 return (0);
1524 }
1525 }
1526 return (1);
1527 case TIFFTAG_PIXARLOGDATAFMT:
1528 sp->user_datafmt = (int)va_arg(ap, int);
1529 /* Tweak the TIFF header so that the rest of libtiff knows what
1530 * size of data will be passed between app and library, and
1531 * assume that the app knows what it is doing and is not
1532 * confused by these header manipulations...
1533 */
1534 switch (sp->user_datafmt)
1535 {
1536 case PIXARLOGDATAFMT_8BIT:
1537 case PIXARLOGDATAFMT_8BITABGR:
1538 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
1539 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
1540 break;
1541 case PIXARLOGDATAFMT_11BITLOG:
1542 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
1543 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
1544 break;
1545 case PIXARLOGDATAFMT_12BITPICIO:
1546 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
1547 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
1548 break;
1549 case PIXARLOGDATAFMT_16BIT:
1550 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
1551 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
1552 break;
1553 case PIXARLOGDATAFMT_FLOAT:
1554 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32);
1555 TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT,
1556 SAMPLEFORMAT_IEEEFP);
1557 break;
1558 }
1559 /*
1560 * Must recalculate sizes should bits/sample change.
1561 */
1562 tif->tif_tilesize =
1563 isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
1564 tif->tif_scanlinesize = TIFFScanlineSize(tif);
1565 result = 1; /* NB: pseudo tag */
1566 break;
1567 default:
1568 result = (*sp->vsetparent)(tif, tag, ap);
1569 }
1570 return (result);
1571 }
1572
PixarLogVGetField(TIFF * tif,uint32_t tag,va_list ap)1573 static int PixarLogVGetField(TIFF *tif, uint32_t tag, va_list ap)
1574 {
1575 PixarLogState *sp = (PixarLogState *)tif->tif_data;
1576
1577 switch (tag)
1578 {
1579 case TIFFTAG_PIXARLOGQUALITY:
1580 *va_arg(ap, int *) = sp->quality;
1581 break;
1582 case TIFFTAG_PIXARLOGDATAFMT:
1583 *va_arg(ap, int *) = sp->user_datafmt;
1584 break;
1585 default:
1586 return (*sp->vgetparent)(tif, tag, ap);
1587 }
1588 return (1);
1589 }
1590
1591 static const TIFFField pixarlogFields[] = {
1592 {TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
1593 TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL},
1594 {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
1595 TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}};
1596
TIFFInitPixarLog(TIFF * tif,int scheme)1597 int TIFFInitPixarLog(TIFF *tif, int scheme)
1598 {
1599 static const char module[] = "TIFFInitPixarLog";
1600
1601 PixarLogState *sp;
1602
1603 (void)scheme;
1604 assert(scheme == COMPRESSION_PIXARLOG);
1605
1606 /*
1607 * Merge codec-specific tag information.
1608 */
1609 if (!_TIFFMergeFields(tif, pixarlogFields, TIFFArrayCount(pixarlogFields)))
1610 {
1611 TIFFErrorExtR(tif, module,
1612 "Merging PixarLog codec-specific tags failed");
1613 return 0;
1614 }
1615
1616 /*
1617 * Allocate state block so tag methods have storage to record values.
1618 */
1619 tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(PixarLogState));
1620 if (tif->tif_data == NULL)
1621 goto bad;
1622 sp = (PixarLogState *)tif->tif_data;
1623 _TIFFmemset(sp, 0, sizeof(*sp));
1624 sp->stream.data_type = Z_BINARY;
1625 sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN;
1626
1627 /*
1628 * Install codec methods.
1629 */
1630 tif->tif_fixuptags = PixarLogFixupTags;
1631 tif->tif_setupdecode = PixarLogSetupDecode;
1632 tif->tif_predecode = PixarLogPreDecode;
1633 tif->tif_decoderow = PixarLogDecode;
1634 tif->tif_decodestrip = PixarLogDecode;
1635 tif->tif_decodetile = PixarLogDecode;
1636 tif->tif_setupencode = PixarLogSetupEncode;
1637 tif->tif_preencode = PixarLogPreEncode;
1638 tif->tif_postencode = PixarLogPostEncode;
1639 tif->tif_encoderow = PixarLogEncode;
1640 tif->tif_encodestrip = PixarLogEncode;
1641 tif->tif_encodetile = PixarLogEncode;
1642 tif->tif_close = PixarLogClose;
1643 tif->tif_cleanup = PixarLogCleanup;
1644
1645 /* Override SetField so we can handle our private pseudo-tag */
1646 sp->vgetparent = tif->tif_tagmethods.vgetfield;
1647 tif->tif_tagmethods.vgetfield = PixarLogVGetField; /* hook for codec tags */
1648 sp->vsetparent = tif->tif_tagmethods.vsetfield;
1649 tif->tif_tagmethods.vsetfield = PixarLogVSetField; /* hook for codec tags */
1650
1651 /* Default values for codec-specific fields */
1652 sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */
1653 sp->state = 0;
1654
1655 /* we don't wish to use the predictor,
1656 * the default is none, which predictor value 1
1657 */
1658 (void)TIFFPredictorInit(tif);
1659
1660 /*
1661 * build the companding tables
1662 */
1663 PixarLogMakeTables(tif, sp);
1664
1665 return (1);
1666 bad:
1667 TIFFErrorExtR(tif, module, "No space for PixarLog state block");
1668 return (0);
1669 }
1670 #endif /* PIXARLOG_SUPPORT */
1671