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