2
* Copyright (c) 1996-1997 Sam Leffler
3
* Copyright (c) 1996 Pixar
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.
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.
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
26
#ifdef PIXARLOG_SUPPORT
30
* PixarLog Compression Support
32
* Contributed by Dan McCoy.
34
* PixarLog film support uses the TIFF library to store companded
35
* 11 bit values into a tiff file, which are compressed using the
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.
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" hightlights 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
* susceptable to such errors than standard 8-bit encodings, but more
54
* susceptable than straight 16-bit or 32-bit encodings.
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
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).
67
* PIXARLOGDATAFMT_11BITLOG provides the internal encoding directly
68
* packed in 16-bit values. However no tools are supplied for interpreting
71
* "hot" (over 1.0) areas written in floating point get clamped to
72
* 1.0 in the integer data types.
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.
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.
87
#include "tif_predict.h"
95
/* Tables for converting to/from 11 bit coded values */
97
#define TSIZE 2048 /* decode table size (11-bit tokens) */
98
#define TSIZEP1 2049 /* Plus one for slop */
99
#define ONE 1250 /* token value of 1.0 exactly */
100
#define RATIO 1.004 /* nominal ratio for log part */
102
#define CODE_MASK 0x7ff /* 11 bits. */
104
static float Fltsize;
105
static float LogK1, LogK2;
107
#define REPEAT(n, op) { int i; i=n; do { i--; op; } while (i>0); }
110
horizontalAccumulateF(uint16 *wp, int n, int stride, float *op,
113
register unsigned int cr, cg, cb, ca, mask;
114
register float t0, t1, t2, t3;
119
t0 = ToLinearF[cr = wp[0]];
120
t1 = ToLinearF[cg = wp[1]];
121
t2 = ToLinearF[cb = wp[2]];
130
t0 = ToLinearF[(cr += wp[0]) & mask];
131
t1 = ToLinearF[(cg += wp[1]) & mask];
132
t2 = ToLinearF[(cb += wp[2]) & mask];
137
} else if (stride == 4) {
138
t0 = ToLinearF[cr = wp[0]];
139
t1 = ToLinearF[cg = wp[1]];
140
t2 = ToLinearF[cb = wp[2]];
141
t3 = ToLinearF[ca = wp[3]];
151
t0 = ToLinearF[(cr += wp[0]) & mask];
152
t1 = ToLinearF[(cg += wp[1]) & mask];
153
t2 = ToLinearF[(cb += wp[2]) & mask];
154
t3 = ToLinearF[(ca += wp[3]) & mask];
161
REPEAT(stride, *op = ToLinearF[*wp&mask]; wp++; op++)
165
wp[stride] += *wp; *op = ToLinearF[*wp&mask]; wp++; op++)
173
horizontalAccumulate12(uint16 *wp, int n, int stride, int16 *op,
176
register unsigned int cr, cg, cb, ca, mask;
177
register float t0, t1, t2, t3;
179
#define SCALE12 2048.0
180
#define CLAMP12(t) (((t) < 3071) ? (uint16) (t) : 3071)
185
t0 = ToLinearF[cr = wp[0]] * SCALE12;
186
t1 = ToLinearF[cg = wp[1]] * SCALE12;
187
t2 = ToLinearF[cb = wp[2]] * SCALE12;
196
t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
197
t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
198
t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
203
} else if (stride == 4) {
204
t0 = ToLinearF[cr = wp[0]] * SCALE12;
205
t1 = ToLinearF[cg = wp[1]] * SCALE12;
206
t2 = ToLinearF[cb = wp[2]] * SCALE12;
207
t3 = ToLinearF[ca = wp[3]] * SCALE12;
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
t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12;
227
REPEAT(stride, t0 = ToLinearF[*wp&mask] * SCALE12;
228
*op = CLAMP12(t0); wp++; op++)
232
wp[stride] += *wp; t0 = ToLinearF[wp[stride]&mask]*SCALE12;
233
*op = CLAMP12(t0); wp++; op++)
241
horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op,
244
register unsigned int cr, cg, cb, ca, mask;
249
op[0] = ToLinear16[cr = wp[0]];
250
op[1] = ToLinear16[cg = wp[1]];
251
op[2] = ToLinear16[cb = wp[2]];
257
op[0] = ToLinear16[(cr += wp[0]) & mask];
258
op[1] = ToLinear16[(cg += wp[1]) & mask];
259
op[2] = ToLinear16[(cb += wp[2]) & mask];
261
} else if (stride == 4) {
262
op[0] = ToLinear16[cr = wp[0]];
263
op[1] = ToLinear16[cg = wp[1]];
264
op[2] = ToLinear16[cb = wp[2]];
265
op[3] = ToLinear16[ca = wp[3]];
271
op[0] = ToLinear16[(cr += wp[0]) & mask];
272
op[1] = ToLinear16[(cg += wp[1]) & mask];
273
op[2] = ToLinear16[(cb += wp[2]) & mask];
274
op[3] = ToLinear16[(ca += wp[3]) & mask];
277
REPEAT(stride, *op = ToLinear16[*wp&mask]; wp++; op++)
281
wp[stride] += *wp; *op = ToLinear16[*wp&mask]; wp++; op++)
289
* Returns the log encoded 11-bit values with the horizontal
290
* differencing undone.
293
horizontalAccumulate11(uint16 *wp, int n, int stride, uint16 *op)
295
register unsigned int cr, cg, cb, ca, mask;
300
op[0] = cr = wp[0]; op[1] = cg = wp[1]; op[2] = cb = wp[2];
306
op[0] = (cr += wp[0]) & mask;
307
op[1] = (cg += wp[1]) & mask;
308
op[2] = (cb += wp[2]) & mask;
310
} else if (stride == 4) {
311
op[0] = cr = wp[0]; op[1] = cg = wp[1];
312
op[2] = cb = wp[2]; op[3] = ca = wp[3];
318
op[0] = (cr += wp[0]) & mask;
319
op[1] = (cg += wp[1]) & mask;
320
op[2] = (cb += wp[2]) & mask;
321
op[3] = (ca += wp[3]) & mask;
324
REPEAT(stride, *op = *wp&mask; wp++; op++)
328
wp[stride] += *wp; *op = *wp&mask; wp++; op++)
336
horizontalAccumulate8(uint16 *wp, int n, int stride, unsigned char *op,
337
unsigned char *ToLinear8)
339
register unsigned int cr, cg, cb, ca, mask;
344
op[0] = ToLinear8[cr = wp[0]];
345
op[1] = ToLinear8[cg = wp[1]];
346
op[2] = ToLinear8[cb = wp[2]];
352
op[0] = ToLinear8[(cr += wp[0]) & mask];
353
op[1] = ToLinear8[(cg += wp[1]) & mask];
354
op[2] = ToLinear8[(cb += wp[2]) & mask];
356
} else if (stride == 4) {
357
op[0] = ToLinear8[cr = wp[0]];
358
op[1] = ToLinear8[cg = wp[1]];
359
op[2] = ToLinear8[cb = wp[2]];
360
op[3] = ToLinear8[ca = wp[3]];
366
op[0] = ToLinear8[(cr += wp[0]) & mask];
367
op[1] = ToLinear8[(cg += wp[1]) & mask];
368
op[2] = ToLinear8[(cb += wp[2]) & mask];
369
op[3] = ToLinear8[(ca += wp[3]) & mask];
372
REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)
376
wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
385
horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op,
386
unsigned char *ToLinear8)
388
register unsigned int cr, cg, cb, ca, mask;
389
register unsigned char t0, t1, t2, t3;
395
t1 = ToLinear8[cb = wp[2]];
396
t2 = ToLinear8[cg = wp[1]];
397
t3 = ToLinear8[cr = wp[0]];
407
t1 = ToLinear8[(cb += wp[2]) & mask];
408
t2 = ToLinear8[(cg += wp[1]) & mask];
409
t3 = ToLinear8[(cr += wp[0]) & mask];
414
} else if (stride == 4) {
415
t0 = ToLinear8[ca = wp[3]];
416
t1 = ToLinear8[cb = wp[2]];
417
t2 = ToLinear8[cg = wp[1]];
418
t3 = ToLinear8[cr = wp[0]];
428
t0 = ToLinear8[(ca += wp[3]) & mask];
429
t1 = ToLinear8[(cb += wp[2]) & mask];
430
t2 = ToLinear8[(cg += wp[1]) & mask];
431
t3 = ToLinear8[(cr += wp[0]) & mask];
438
REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)
442
wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
450
* State block for each open TIFF
451
* file using PixarLog compression/decompression.
454
TIFFPredictorState predict;
461
#define PLSTATE_INIT 1
463
TIFFVSetMethod vgetparent; /* super-class method */
464
TIFFVSetMethod vsetparent; /* super-class method */
468
unsigned char *ToLinear8;
470
uint16 *From14; /* Really for 16-bit data, but we shift down 2 */
476
PixarLogMakeTables(PixarLogState *sp)
480
* We make several tables here to convert between various external
481
* representations (float, 16-bit, and 8-bit) and the internal
482
* 11-bit companded representation. The 11-bit representation has two
483
* distinct regions. A linear bottom end up through .018316 in steps
484
* of about .000073, and a region of constant ratio up to about 25.
485
* These floating point numbers are stored in the main table ToLinearF.
486
* All other tables are derived from this one. The tables (and the
487
* ratios) are continuous at the internal seam.
492
double b, c, linstep, v;
495
unsigned char *ToLinear8;
497
uint16 *From14; /* Really for 16-bit data, but we shift down 2 */
501
nlin = (int)1./c; /* nlin must be an integer */
503
b = exp(-c*ONE); /* multiplicative scale factor [b*exp(c*ONE) = 1] */
504
linstep = b*c*exp(1.);
506
LogK1 = 1./c; /* if (v >= 2) token = k1*log(v*k2) */
508
lt2size = (int)(2./linstep) + 1;
509
FromLT2 = (uint16 *)_TIFFmalloc(lt2size*sizeof(uint16));
510
From14 = (uint16 *)_TIFFmalloc(16384*sizeof(uint16));
511
From8 = (uint16 *)_TIFFmalloc(256*sizeof(uint16));
512
ToLinearF = (float *)_TIFFmalloc(TSIZEP1 * sizeof(float));
513
ToLinear16 = (uint16 *)_TIFFmalloc(TSIZEP1 * sizeof(uint16));
514
ToLinear8 = (unsigned char *)_TIFFmalloc(TSIZEP1 * sizeof(unsigned char));
515
if (FromLT2 == NULL || From14 == NULL || From8 == NULL ||
516
ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) {
517
if (FromLT2) _TIFFfree(FromLT2);
518
if (From14) _TIFFfree(From14);
519
if (From8) _TIFFfree(From8);
520
if (ToLinearF) _TIFFfree(ToLinearF);
521
if (ToLinear16) _TIFFfree(ToLinear16);
522
if (ToLinear8) _TIFFfree(ToLinear8);
526
sp->ToLinearF = NULL;
527
sp->ToLinear16 = NULL;
528
sp->ToLinear8 = NULL;
534
for (i = 0; i < nlin; i++) {
539
for (i = nlin; i < TSIZE; i++)
540
ToLinearF[j++] = b*exp(c*i);
542
ToLinearF[2048] = ToLinearF[2047];
544
for (i = 0; i < TSIZEP1; i++) {
545
v = ToLinearF[i]*65535.0 + 0.5;
546
ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16)v;
547
v = ToLinearF[i]*255.0 + 0.5;
548
ToLinear8[i] = (v > 255.0) ? 255 : (unsigned char)v;
552
for (i = 0; i < lt2size; i++) {
553
if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1])
559
* Since we lose info anyway on 16-bit data, we set up a 14-bit
560
* table and shift 16-bit values down two bits on input.
561
* saves a little table space.
564
for (i = 0; i < 16384; i++) {
565
while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1])
571
for (i = 0; i < 256; i++) {
572
while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1])
579
sp->ToLinearF = ToLinearF;
580
sp->ToLinear16 = ToLinear16;
581
sp->ToLinear8 = ToLinear8;
582
sp->FromLT2 = FromLT2;
589
#define DecoderState(tif) ((PixarLogState*) (tif)->tif_data)
590
#define EncoderState(tif) ((PixarLogState*) (tif)->tif_data)
592
static int PixarLogEncode(TIFF*, tidata_t, tsize_t, tsample_t);
593
static int PixarLogDecode(TIFF*, tidata_t, tsize_t, tsample_t);
595
#define N(a) (sizeof(a)/sizeof(a[0]))
596
#define PIXARLOGDATAFMT_UNKNOWN -1
599
PixarLogGuessDataFmt(TIFFDirectory *td)
601
int guess = PIXARLOGDATAFMT_UNKNOWN;
602
int format = td->td_sampleformat;
604
/* If the user didn't tell us his datafmt,
605
* take our best guess from the bitspersample.
607
switch (td->td_bitspersample) {
609
if (format == SAMPLEFORMAT_IEEEFP)
610
guess = PIXARLOGDATAFMT_FLOAT;
613
if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
614
guess = PIXARLOGDATAFMT_16BIT;
617
if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT)
618
guess = PIXARLOGDATAFMT_12BITPICIO;
621
if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
622
guess = PIXARLOGDATAFMT_11BITLOG;
625
if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
626
guess = PIXARLOGDATAFMT_8BIT;
634
PixarLogSetupDecode(TIFF* tif)
636
TIFFDirectory *td = &tif->tif_dir;
637
PixarLogState* sp = DecoderState(tif);
638
static const char module[] = "PixarLogSetupDecode";
642
/* Make sure no byte swapping happens on the data
643
* after decompression. */
644
tif->tif_postdecode = _TIFFNoPostDecode;
646
/* for some reason, we can't do this in TIFFInitPixarLog */
648
sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
649
td->td_samplesperpixel : 1);
650
sp->tbuf = (uint16 *) _TIFFmalloc(sp->stride *
651
td->td_imagewidth * td->td_rowsperstrip * sizeof(uint16));
652
if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
653
sp->user_datafmt = PixarLogGuessDataFmt(td);
654
if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
656
"PixarLog compression can't handle bits depth/data format combination (depth: %d)",
657
td->td_bitspersample);
661
if (inflateInit(&sp->stream) != Z_OK) {
662
TIFFError(module, "%s: %s", tif->tif_name, sp->stream.msg);
665
sp->state |= PLSTATE_INIT;
671
* Setup state for decoding a strip.
674
PixarLogPreDecode(TIFF* tif, tsample_t s)
676
PixarLogState* sp = DecoderState(tif);
680
sp->stream.next_in = tif->tif_rawdata;
681
sp->stream.avail_in = tif->tif_rawcc;
682
return (inflateReset(&sp->stream) == Z_OK);
686
PixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
688
TIFFDirectory *td = &tif->tif_dir;
689
PixarLogState* sp = DecoderState(tif);
690
static const char module[] = "PixarLogDecode";
691
int i, nsamples, llen;
694
switch (sp->user_datafmt) {
695
case PIXARLOGDATAFMT_FLOAT:
696
nsamples = occ / sizeof(float); /* XXX float == 32 bits */
698
case PIXARLOGDATAFMT_16BIT:
699
case PIXARLOGDATAFMT_12BITPICIO:
700
case PIXARLOGDATAFMT_11BITLOG:
701
nsamples = occ / sizeof(uint16); /* XXX uint16 == 16 bits */
703
case PIXARLOGDATAFMT_8BIT:
704
case PIXARLOGDATAFMT_8BITABGR:
708
TIFFError(tif->tif_name,
709
"%d bit input not supported in PixarLog",
710
td->td_bitspersample);
714
llen = sp->stride * td->td_imagewidth;
718
sp->stream.next_out = (unsigned char *) sp->tbuf;
719
sp->stream.avail_out = nsamples * sizeof(uint16);
721
int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
722
if (state == Z_STREAM_END) {
725
if (state == Z_DATA_ERROR) {
727
"%s: Decoding error at scanline %d, %s",
728
tif->tif_name, tif->tif_row, sp->stream.msg);
729
if (inflateSync(&sp->stream) != Z_OK)
734
TIFFError(module, "%s: zlib error: %s",
735
tif->tif_name, sp->stream.msg);
738
} while (sp->stream.avail_out > 0);
740
/* hopefully, we got all the bytes we needed */
741
if (sp->stream.avail_out != 0) {
743
"%s: Not enough data at scanline %d (short %d bytes)",
744
tif->tif_name, tif->tif_row, sp->stream.avail_out);
749
/* Swap bytes in the data if from a different endian machine. */
750
if (tif->tif_flags & TIFF_SWAB)
751
TIFFSwabArrayOfShort(up, nsamples);
753
for (i = 0; i < nsamples; i += llen, up += llen) {
754
switch (sp->user_datafmt) {
755
case PIXARLOGDATAFMT_FLOAT:
756
horizontalAccumulateF(up, llen, sp->stride,
757
(float *)op, sp->ToLinearF);
758
op += llen * sizeof(float);
760
case PIXARLOGDATAFMT_16BIT:
761
horizontalAccumulate16(up, llen, sp->stride,
762
(uint16 *)op, sp->ToLinear16);
763
op += llen * sizeof(uint16);
765
case PIXARLOGDATAFMT_12BITPICIO:
766
horizontalAccumulate12(up, llen, sp->stride,
767
(int16 *)op, sp->ToLinearF);
768
op += llen * sizeof(int16);
770
case PIXARLOGDATAFMT_11BITLOG:
771
horizontalAccumulate11(up, llen, sp->stride,
773
op += llen * sizeof(uint16);
775
case PIXARLOGDATAFMT_8BIT:
776
horizontalAccumulate8(up, llen, sp->stride,
777
(unsigned char *)op, sp->ToLinear8);
778
op += llen * sizeof(unsigned char);
780
case PIXARLOGDATAFMT_8BITABGR:
781
horizontalAccumulate8abgr(up, llen, sp->stride,
782
(unsigned char *)op, sp->ToLinear8);
783
op += llen * sizeof(unsigned char);
786
TIFFError(tif->tif_name,
787
"PixarLogDecode: unsupported bits/sample: %d",
788
td->td_bitspersample);
797
PixarLogSetupEncode(TIFF* tif)
799
TIFFDirectory *td = &tif->tif_dir;
800
PixarLogState* sp = EncoderState(tif);
801
static const char module[] = "PixarLogSetupEncode";
805
/* for some reason, we can't do this in TIFFInitPixarLog */
807
sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
808
td->td_samplesperpixel : 1);
809
sp->tbuf = (uint16 *) _TIFFmalloc(sp->stride *
810
td->td_imagewidth * td->td_rowsperstrip * sizeof(uint16));
811
if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
812
sp->user_datafmt = PixarLogGuessDataFmt(td);
813
if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
814
TIFFError(module, "PixarLog compression can't handle %d bit linear encodings", td->td_bitspersample);
818
if (deflateInit(&sp->stream, sp->quality) != Z_OK) {
819
TIFFError(module, "%s: %s", tif->tif_name, sp->stream.msg);
822
sp->state |= PLSTATE_INIT;
828
* Reset encoding state at the start of a strip.
831
PixarLogPreEncode(TIFF* tif, tsample_t s)
833
PixarLogState *sp = EncoderState(tif);
837
sp->stream.next_out = tif->tif_rawdata;
838
sp->stream.avail_out = tif->tif_rawdatasize;
839
return (deflateReset(&sp->stream) == Z_OK);
843
horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2)
846
register int r1, g1, b1, a1, r2, g2, b2, a2, mask;
847
register float fltsize = Fltsize;
849
#define CLAMP(v) ( (v<(float)0.) ? 0 \
850
: (v<(float)2.) ? FromLT2[(int)(v*fltsize)] \
851
: (v>(float)24.2) ? 2047 \
852
: LogK1*log(v*LogK2) + 0.5 )
857
r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]);
858
b2 = wp[2] = CLAMP(ip[2]);
864
r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
865
g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
866
b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
868
} else if (stride == 4) {
869
r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]);
870
b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]);
876
r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
877
g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
878
b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
879
a1 = CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
882
ip += n - 1; /* point to last one */
883
wp += n - 1; /* point to last one */
886
REPEAT(stride, wp[0] = CLAMP(ip[0]);
892
REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
898
horizontalDifference16(unsigned short *ip, int n, int stride,
899
unsigned short *wp, uint16 *From14)
901
register int r1, g1, b1, a1, r2, g2, b2, a2, mask;
903
/* assumption is unsigned pixel values */
905
#define CLAMP(v) From14[(v) >> 2]
910
r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]);
911
b2 = wp[2] = CLAMP(ip[2]);
917
r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
918
g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
919
b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
921
} else if (stride == 4) {
922
r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]);
923
b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]);
929
r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
930
g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
931
b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
932
a1 = CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
935
ip += n - 1; /* point to last one */
936
wp += n - 1; /* point to last one */
939
REPEAT(stride, wp[0] = CLAMP(ip[0]);
945
REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
952
horizontalDifference8(unsigned char *ip, int n, int stride,
953
unsigned short *wp, uint16 *From8)
955
register int r1, g1, b1, a1, r2, g2, b2, a2, mask;
958
#define CLAMP(v) (From8[(v)])
963
r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]);
964
b2 = wp[2] = CLAMP(ip[2]);
968
r1 = CLAMP(ip[3]); wp[3] = (r1-r2) & mask; r2 = r1;
969
g1 = CLAMP(ip[4]); wp[4] = (g1-g2) & mask; g2 = g1;
970
b1 = CLAMP(ip[5]); wp[5] = (b1-b2) & mask; b2 = b1;
974
} else if (stride == 4) {
975
r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]);
976
b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]);
980
r1 = CLAMP(ip[4]); wp[4] = (r1-r2) & mask; r2 = r1;
981
g1 = CLAMP(ip[5]); wp[5] = (g1-g2) & mask; g2 = g1;
982
b1 = CLAMP(ip[6]); wp[6] = (b1-b2) & mask; b2 = b1;
983
a1 = CLAMP(ip[7]); wp[7] = (a1-a2) & mask; a2 = a1;
988
wp += n + stride - 1; /* point to last one */
989
ip += n + stride - 1; /* point to last one */
992
REPEAT(stride, wp[0] = CLAMP(ip[0]);
998
REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
1004
* Encode a chunk of pixels.
1007
PixarLogEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
1009
TIFFDirectory *td = &tif->tif_dir;
1010
PixarLogState *sp = EncoderState(tif);
1011
static const char module[] = "PixarLogEncode";
1013
unsigned short * up;
1017
switch (sp->user_datafmt) {
1018
case PIXARLOGDATAFMT_FLOAT:
1019
n = cc / sizeof(float); /* XXX float == 32 bits */
1021
case PIXARLOGDATAFMT_16BIT:
1022
case PIXARLOGDATAFMT_12BITPICIO:
1023
case PIXARLOGDATAFMT_11BITLOG:
1024
n = cc / sizeof(uint16); /* XXX uint16 == 16 bits */
1026
case PIXARLOGDATAFMT_8BIT:
1027
case PIXARLOGDATAFMT_8BITABGR:
1031
TIFFError(tif->tif_name,
1032
"%d bit input not supported in PixarLog",
1033
td->td_bitspersample);
1037
llen = sp->stride * td->td_imagewidth;
1039
for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) {
1040
switch (sp->user_datafmt) {
1041
case PIXARLOGDATAFMT_FLOAT:
1042
horizontalDifferenceF((float *)bp, llen,
1043
sp->stride, up, sp->FromLT2);
1044
bp += llen * sizeof(float);
1046
case PIXARLOGDATAFMT_16BIT:
1047
horizontalDifference16((uint16 *)bp, llen,
1048
sp->stride, up, sp->From14);
1049
bp += llen * sizeof(uint16);
1051
case PIXARLOGDATAFMT_8BIT:
1052
horizontalDifference8((unsigned char *)bp, llen,
1053
sp->stride, up, sp->From8);
1054
bp += llen * sizeof(unsigned char);
1057
TIFFError(tif->tif_name,
1058
"%d bit input not supported in PixarLog",
1059
td->td_bitspersample);
1064
sp->stream.next_in = (unsigned char *) sp->tbuf;
1065
sp->stream.avail_in = n * sizeof(uint16);
1068
if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
1069
TIFFError(module, "%s: Encoder error: %s",
1070
tif->tif_name, sp->stream.msg);
1073
if (sp->stream.avail_out == 0) {
1074
tif->tif_rawcc = tif->tif_rawdatasize;
1075
TIFFFlushData1(tif);
1076
sp->stream.next_out = tif->tif_rawdata;
1077
sp->stream.avail_out = tif->tif_rawdatasize;
1079
} while (sp->stream.avail_in > 0);
1084
* Finish off an encoded strip by flushing the last
1085
* string and tacking on an End Of Information code.
1089
PixarLogPostEncode(TIFF* tif)
1091
PixarLogState *sp = EncoderState(tif);
1092
static const char module[] = "PixarLogPostEncode";
1095
sp->stream.avail_in = 0;
1098
state = deflate(&sp->stream, Z_FINISH);
1102
if (sp->stream.avail_out != tif->tif_rawdatasize) {
1104
tif->tif_rawdatasize - sp->stream.avail_out;
1105
TIFFFlushData1(tif);
1106
sp->stream.next_out = tif->tif_rawdata;
1107
sp->stream.avail_out = tif->tif_rawdatasize;
1111
TIFFError(module, "%s: zlib error: %s",
1112
tif->tif_name, sp->stream.msg);
1115
} while (state != Z_STREAM_END);
1120
PixarLogClose(TIFF* tif)
1122
TIFFDirectory *td = &tif->tif_dir;
1124
/* In a really sneaky maneuver, on close, we covertly modify both
1125
* bitspersample and sampleformat in the directory to indicate
1126
* 8-bit linear. This way, the decode "just works" even for
1127
* readers that don't know about PixarLog, or how to set
1128
* the PIXARLOGDATFMT pseudo-tag.
1130
td->td_bitspersample = 8;
1131
td->td_sampleformat = SAMPLEFORMAT_UINT;
1135
PixarLogCleanup(TIFF* tif)
1137
PixarLogState* sp = (PixarLogState*) tif->tif_data;
1140
if (sp->FromLT2) _TIFFfree(sp->FromLT2);
1141
if (sp->From14) _TIFFfree(sp->From14);
1142
if (sp->From8) _TIFFfree(sp->From8);
1143
if (sp->ToLinearF) _TIFFfree(sp->ToLinearF);
1144
if (sp->ToLinear16) _TIFFfree(sp->ToLinear16);
1145
if (sp->ToLinear8) _TIFFfree(sp->ToLinear8);
1146
if (sp->state&PLSTATE_INIT) {
1147
if (tif->tif_mode == O_RDONLY)
1148
inflateEnd(&sp->stream);
1150
deflateEnd(&sp->stream);
1153
_TIFFfree(sp->tbuf);
1155
tif->tif_data = NULL;
1160
PixarLogVSetField(TIFF* tif, ttag_t tag, va_list ap)
1162
PixarLogState *sp = (PixarLogState *)tif->tif_data;
1164
static const char module[] = "PixarLogVSetField";
1167
case TIFFTAG_PIXARLOGQUALITY:
1168
sp->quality = va_arg(ap, int);
1169
if (tif->tif_mode != O_RDONLY && (sp->state&PLSTATE_INIT)) {
1170
if (deflateParams(&sp->stream,
1171
sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) {
1172
TIFFError(module, "%s: zlib error: %s",
1173
tif->tif_name, sp->stream.msg);
1178
case TIFFTAG_PIXARLOGDATAFMT:
1179
sp->user_datafmt = va_arg(ap, int);
1180
/* Tweak the TIFF header so that the rest of libtiff knows what
1181
* size of data will be passed between app and library, and
1182
* assume that the app knows what it is doing and is not
1183
* confused by these header manipulations...
1185
switch (sp->user_datafmt) {
1186
case PIXARLOGDATAFMT_8BIT:
1187
case PIXARLOGDATAFMT_8BITABGR:
1188
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
1189
TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
1191
case PIXARLOGDATAFMT_11BITLOG:
1192
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
1193
TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
1195
case PIXARLOGDATAFMT_12BITPICIO:
1196
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
1197
TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
1199
case PIXARLOGDATAFMT_16BIT:
1200
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
1201
TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
1203
case PIXARLOGDATAFMT_FLOAT:
1204
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32);
1205
TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
1209
* Must recalculate sizes should bits/sample change.
1211
tif->tif_tilesize = TIFFTileSize(tif);
1212
tif->tif_scanlinesize = TIFFScanlineSize(tif);
1213
result = 1; /* NB: pseudo tag */
1216
result = (*sp->vsetparent)(tif, tag, ap);
1222
PixarLogVGetField(TIFF* tif, ttag_t tag, va_list ap)
1224
PixarLogState *sp = (PixarLogState *)tif->tif_data;
1227
case TIFFTAG_PIXARLOGQUALITY:
1228
*va_arg(ap, int*) = sp->quality;
1230
case TIFFTAG_PIXARLOGDATAFMT:
1231
*va_arg(ap, int*) = sp->user_datafmt;
1234
return (*sp->vgetparent)(tif, tag, ap);
1239
static const TIFFFieldInfo pixarlogFieldInfo[] = {
1240
{TIFFTAG_PIXARLOGDATAFMT,0,0,TIFF_ANY, FIELD_PSEUDO,FALSE,FALSE,""},
1241
{TIFFTAG_PIXARLOGQUALITY,0,0,TIFF_ANY, FIELD_PSEUDO,FALSE,FALSE,""}
1245
TIFFInitPixarLog(TIFF* tif, int scheme)
1249
assert(scheme == COMPRESSION_PIXARLOG);
1252
* Allocate state block so tag methods have storage to record values.
1254
tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (PixarLogState));
1255
if (tif->tif_data == NULL)
1257
sp = (PixarLogState*) tif->tif_data;
1258
memset(sp, 0, sizeof (*sp));
1259
sp->stream.data_type = Z_BINARY;
1260
sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN;
1263
* Install codec methods.
1265
tif->tif_setupdecode = PixarLogSetupDecode;
1266
tif->tif_predecode = PixarLogPreDecode;
1267
tif->tif_decoderow = PixarLogDecode;
1268
tif->tif_decodestrip = PixarLogDecode;
1269
tif->tif_decodetile = PixarLogDecode;
1270
tif->tif_setupencode = PixarLogSetupEncode;
1271
tif->tif_preencode = PixarLogPreEncode;
1272
tif->tif_postencode = PixarLogPostEncode;
1273
tif->tif_encoderow = PixarLogEncode;
1274
tif->tif_encodestrip = PixarLogEncode;
1275
tif->tif_encodetile = PixarLogEncode;
1276
tif->tif_close = PixarLogClose;
1277
tif->tif_cleanup = PixarLogCleanup;
1279
/* Override SetField so we can handle our private pseudo-tag */
1280
_TIFFMergeFieldInfo(tif, pixarlogFieldInfo, N(pixarlogFieldInfo));
1281
sp->vgetparent = tif->tif_tagmethods.vgetfield;
1282
tif->tif_tagmethods.vgetfield = PixarLogVGetField; /* hook for codec tags */
1283
sp->vsetparent = tif->tif_tagmethods.vsetfield;
1284
tif->tif_tagmethods.vsetfield = PixarLogVSetField; /* hook for codec tags */
1286
/* Default values for codec-specific fields */
1287
sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */
1290
/* we don't wish to use the predictor,
1291
* the default is none, which predictor value 1
1293
(void) TIFFPredictorInit(tif);
1296
* build the companding tables
1298
PixarLogMakeTables(sp);
1302
TIFFError("TIFFInitPixarLog", "No space for PixarLog state block");
1305
#endif /* PIXARLOG_SUPPORT */