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" 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.
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.
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
90 #include "tif_predict.h"
97 /* Tables for converting to/from 11 bit coded values */
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 */
104 #define CODE_MASK 0x7ff /* 11 bits. */
106 static float Fltsize
;
107 static float LogK1
, LogK2
;
109 #define REPEAT(n, op) { int i; i=n; do { i--; op; } while (i>0); }
112 horizontalAccumulateF(uint16
*wp
, int n
, int stride
, float *op
,
115 register unsigned int cr
, cg
, cb
, ca
, mask
;
116 register float t0
, t1
, t2
, t3
;
121 t0
= ToLinearF
[cr
= (wp
[0] & mask
)];
122 t1
= ToLinearF
[cg
= (wp
[1] & mask
)];
123 t2
= ToLinearF
[cb
= (wp
[2] & mask
)];
132 t0
= ToLinearF
[(cr
+= wp
[0]) & mask
];
133 t1
= ToLinearF
[(cg
+= wp
[1]) & mask
];
134 t2
= ToLinearF
[(cb
+= wp
[2]) & mask
];
139 } else if (stride
== 4) {
140 t0
= ToLinearF
[cr
= (wp
[0] & mask
)];
141 t1
= ToLinearF
[cg
= (wp
[1] & mask
)];
142 t2
= ToLinearF
[cb
= (wp
[2] & mask
)];
143 t3
= ToLinearF
[ca
= (wp
[3] & mask
)];
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
];
163 REPEAT(stride
, *op
= ToLinearF
[*wp
&mask
]; wp
++; op
++)
167 wp
[stride
] += *wp
; *op
= ToLinearF
[*wp
&mask
]; wp
++; op
++)
175 horizontalAccumulate12(uint16
*wp
, int n
, int stride
, int16
*op
,
178 register unsigned int cr
, cg
, cb
, ca
, mask
;
179 register float t0
, t1
, t2
, t3
;
181 #define SCALE12 2048.0F
182 #define CLAMP12(t) (((t) < 3071) ? (uint16) (t) : 3071)
187 t0
= ToLinearF
[cr
= (wp
[0] & mask
)] * SCALE12
;
188 t1
= ToLinearF
[cg
= (wp
[1] & mask
)] * SCALE12
;
189 t2
= ToLinearF
[cb
= (wp
[2] & mask
)] * SCALE12
;
198 t0
= ToLinearF
[(cr
+= wp
[0]) & mask
] * SCALE12
;
199 t1
= ToLinearF
[(cg
+= wp
[1]) & mask
] * SCALE12
;
200 t2
= ToLinearF
[(cb
+= wp
[2]) & mask
] * SCALE12
;
205 } else if (stride
== 4) {
206 t0
= ToLinearF
[cr
= (wp
[0] & mask
)] * SCALE12
;
207 t1
= ToLinearF
[cg
= (wp
[1] & mask
)] * SCALE12
;
208 t2
= ToLinearF
[cb
= (wp
[2] & mask
)] * SCALE12
;
209 t3
= ToLinearF
[ca
= (wp
[3] & mask
)] * SCALE12
;
219 t0
= ToLinearF
[(cr
+= wp
[0]) & mask
] * SCALE12
;
220 t1
= ToLinearF
[(cg
+= wp
[1]) & mask
] * SCALE12
;
221 t2
= ToLinearF
[(cb
+= wp
[2]) & mask
] * SCALE12
;
222 t3
= ToLinearF
[(ca
+= wp
[3]) & mask
] * SCALE12
;
229 REPEAT(stride
, t0
= ToLinearF
[*wp
&mask
] * SCALE12
;
230 *op
= CLAMP12(t0
); wp
++; op
++)
234 wp
[stride
] += *wp
; t0
= ToLinearF
[wp
[stride
]&mask
]*SCALE12
;
235 *op
= CLAMP12(t0
); wp
++; op
++)
243 horizontalAccumulate16(uint16
*wp
, int n
, int stride
, uint16
*op
,
246 register unsigned int cr
, cg
, cb
, ca
, mask
;
251 op
[0] = ToLinear16
[cr
= (wp
[0] & mask
)];
252 op
[1] = ToLinear16
[cg
= (wp
[1] & mask
)];
253 op
[2] = ToLinear16
[cb
= (wp
[2] & mask
)];
259 op
[0] = ToLinear16
[(cr
+= wp
[0]) & mask
];
260 op
[1] = ToLinear16
[(cg
+= wp
[1]) & mask
];
261 op
[2] = ToLinear16
[(cb
+= wp
[2]) & mask
];
263 } else if (stride
== 4) {
264 op
[0] = ToLinear16
[cr
= (wp
[0] & mask
)];
265 op
[1] = ToLinear16
[cg
= (wp
[1] & mask
)];
266 op
[2] = ToLinear16
[cb
= (wp
[2] & mask
)];
267 op
[3] = ToLinear16
[ca
= (wp
[3] & mask
)];
273 op
[0] = ToLinear16
[(cr
+= wp
[0]) & mask
];
274 op
[1] = ToLinear16
[(cg
+= wp
[1]) & mask
];
275 op
[2] = ToLinear16
[(cb
+= wp
[2]) & mask
];
276 op
[3] = ToLinear16
[(ca
+= wp
[3]) & mask
];
279 REPEAT(stride
, *op
= ToLinear16
[*wp
&mask
]; wp
++; op
++)
283 wp
[stride
] += *wp
; *op
= ToLinear16
[*wp
&mask
]; wp
++; op
++)
291 * Returns the log encoded 11-bit values with the horizontal
292 * differencing undone.
295 horizontalAccumulate11(uint16
*wp
, int n
, int stride
, uint16
*op
)
297 register unsigned int cr
, cg
, cb
, ca
, mask
;
302 op
[0] = wp
[0]; op
[1] = wp
[1]; op
[2] = wp
[2];
303 cr
= wp
[0]; cg
= wp
[1]; cb
= wp
[2];
309 op
[0] = (uint16
)((cr
+= wp
[0]) & mask
);
310 op
[1] = (uint16
)((cg
+= wp
[1]) & mask
);
311 op
[2] = (uint16
)((cb
+= wp
[2]) & mask
);
313 } else if (stride
== 4) {
314 op
[0] = wp
[0]; op
[1] = wp
[1];
315 op
[2] = wp
[2]; op
[3] = wp
[3];
316 cr
= wp
[0]; cg
= wp
[1]; cb
= wp
[2]; ca
= wp
[3];
322 op
[0] = (uint16
)((cr
+= wp
[0]) & mask
);
323 op
[1] = (uint16
)((cg
+= wp
[1]) & mask
);
324 op
[2] = (uint16
)((cb
+= wp
[2]) & mask
);
325 op
[3] = (uint16
)((ca
+= wp
[3]) & mask
);
328 REPEAT(stride
, *op
= *wp
&mask
; wp
++; op
++)
332 wp
[stride
] += *wp
; *op
= *wp
&mask
; wp
++; op
++)
340 horizontalAccumulate8(uint16
*wp
, int n
, int stride
, unsigned char *op
,
341 unsigned char *ToLinear8
)
343 register unsigned int cr
, cg
, cb
, ca
, mask
;
348 op
[0] = ToLinear8
[cr
= (wp
[0] & mask
)];
349 op
[1] = ToLinear8
[cg
= (wp
[1] & mask
)];
350 op
[2] = ToLinear8
[cb
= (wp
[2] & mask
)];
356 op
[0] = ToLinear8
[(cr
+= wp
[0]) & mask
];
357 op
[1] = ToLinear8
[(cg
+= wp
[1]) & mask
];
358 op
[2] = ToLinear8
[(cb
+= wp
[2]) & mask
];
360 } else if (stride
== 4) {
361 op
[0] = ToLinear8
[cr
= (wp
[0] & mask
)];
362 op
[1] = ToLinear8
[cg
= (wp
[1] & mask
)];
363 op
[2] = ToLinear8
[cb
= (wp
[2] & mask
)];
364 op
[3] = ToLinear8
[ca
= (wp
[3] & mask
)];
370 op
[0] = ToLinear8
[(cr
+= wp
[0]) & mask
];
371 op
[1] = ToLinear8
[(cg
+= wp
[1]) & mask
];
372 op
[2] = ToLinear8
[(cb
+= wp
[2]) & mask
];
373 op
[3] = ToLinear8
[(ca
+= wp
[3]) & mask
];
376 REPEAT(stride
, *op
= ToLinear8
[*wp
&mask
]; wp
++; op
++)
380 wp
[stride
] += *wp
; *op
= ToLinear8
[*wp
&mask
]; wp
++; op
++)
389 horizontalAccumulate8abgr(uint16
*wp
, int n
, int stride
, unsigned char *op
,
390 unsigned char *ToLinear8
)
392 register unsigned int cr
, cg
, cb
, ca
, mask
;
393 register unsigned char t0
, t1
, t2
, t3
;
399 t1
= ToLinear8
[cb
= (wp
[2] & mask
)];
400 t2
= ToLinear8
[cg
= (wp
[1] & mask
)];
401 t3
= ToLinear8
[cr
= (wp
[0] & mask
)];
411 t1
= ToLinear8
[(cb
+= wp
[2]) & mask
];
412 t2
= ToLinear8
[(cg
+= wp
[1]) & mask
];
413 t3
= ToLinear8
[(cr
+= wp
[0]) & mask
];
418 } else if (stride
== 4) {
419 t0
= ToLinear8
[ca
= (wp
[3] & mask
)];
420 t1
= ToLinear8
[cb
= (wp
[2] & mask
)];
421 t2
= ToLinear8
[cg
= (wp
[1] & mask
)];
422 t3
= ToLinear8
[cr
= (wp
[0] & mask
)];
432 t0
= ToLinear8
[(ca
+= wp
[3]) & mask
];
433 t1
= ToLinear8
[(cb
+= wp
[2]) & mask
];
434 t2
= ToLinear8
[(cg
+= wp
[1]) & mask
];
435 t3
= ToLinear8
[(cr
+= wp
[0]) & mask
];
442 REPEAT(stride
, *op
= ToLinear8
[*wp
&mask
]; wp
++; op
++)
446 wp
[stride
] += *wp
; *op
= ToLinear8
[*wp
&mask
]; wp
++; op
++)
454 * State block for each open TIFF
455 * file using PixarLog compression/decompression.
458 TIFFPredictorState predict
;
460 tmsize_t tbuf_size
; /* only set/used on reading for now */
466 #define PLSTATE_INIT 1
468 TIFFVSetMethod vgetparent
; /* super-class method */
469 TIFFVSetMethod vsetparent
; /* super-class method */
473 unsigned char *ToLinear8
;
475 uint16
*From14
; /* Really for 16-bit data, but we shift down 2 */
481 PixarLogMakeTables(PixarLogState
*sp
)
485 * We make several tables here to convert between various external
486 * representations (float, 16-bit, and 8-bit) and the internal
487 * 11-bit companded representation. The 11-bit representation has two
488 * distinct regions. A linear bottom end up through .018316 in steps
489 * of about .000073, and a region of constant ratio up to about 25.
490 * These floating point numbers are stored in the main table ToLinearF.
491 * All other tables are derived from this one. The tables (and the
492 * ratios) are continuous at the internal seam.
497 double b
, c
, linstep
, v
;
500 unsigned char *ToLinear8
;
502 uint16
*From14
; /* Really for 16-bit data, but we shift down 2 */
506 nlin
= (int)(1./c
); /* nlin must be an integer */
508 b
= exp(-c
*ONE
); /* multiplicative scale factor [b*exp(c*ONE) = 1] */
509 linstep
= b
*c
*exp(1.);
511 LogK1
= (float)(1./c
); /* if (v >= 2) token = k1*log(v*k2) */
512 LogK2
= (float)(1./b
);
513 lt2size
= (int)(2./linstep
) + 1;
514 FromLT2
= (uint16
*)_TIFFmalloc(lt2size
*sizeof(uint16
));
515 From14
= (uint16
*)_TIFFmalloc(16384*sizeof(uint16
));
516 From8
= (uint16
*)_TIFFmalloc(256*sizeof(uint16
));
517 ToLinearF
= (float *)_TIFFmalloc(TSIZEP1
* sizeof(float));
518 ToLinear16
= (uint16
*)_TIFFmalloc(TSIZEP1
* sizeof(uint16
));
519 ToLinear8
= (unsigned char *)_TIFFmalloc(TSIZEP1
* sizeof(unsigned char));
520 if (FromLT2
== NULL
|| From14
== NULL
|| From8
== NULL
||
521 ToLinearF
== NULL
|| ToLinear16
== NULL
|| ToLinear8
== NULL
) {
522 if (FromLT2
) _TIFFfree(FromLT2
);
523 if (From14
) _TIFFfree(From14
);
524 if (From8
) _TIFFfree(From8
);
525 if (ToLinearF
) _TIFFfree(ToLinearF
);
526 if (ToLinear16
) _TIFFfree(ToLinear16
);
527 if (ToLinear8
) _TIFFfree(ToLinear8
);
531 sp
->ToLinearF
= NULL
;
532 sp
->ToLinear16
= NULL
;
533 sp
->ToLinear8
= NULL
;
539 for (i
= 0; i
< nlin
; i
++) {
541 ToLinearF
[j
++] = (float)v
;
544 for (i
= nlin
; i
< TSIZE
; i
++)
545 ToLinearF
[j
++] = (float)(b
*exp(c
*i
));
547 ToLinearF
[2048] = ToLinearF
[2047];
549 for (i
= 0; i
< TSIZEP1
; i
++) {
550 v
= ToLinearF
[i
]*65535.0 + 0.5;
551 ToLinear16
[i
] = (v
> 65535.0) ? 65535 : (uint16
)v
;
552 v
= ToLinearF
[i
]*255.0 + 0.5;
553 ToLinear8
[i
] = (v
> 255.0) ? 255 : (unsigned char)v
;
557 for (i
= 0; i
< lt2size
; i
++) {
558 if ((i
*linstep
)*(i
*linstep
) > ToLinearF
[j
]*ToLinearF
[j
+1])
560 FromLT2
[i
] = (uint16
)j
;
564 * Since we lose info anyway on 16-bit data, we set up a 14-bit
565 * table and shift 16-bit values down two bits on input.
566 * saves a little table space.
569 for (i
= 0; i
< 16384; i
++) {
570 while ((i
/16383.)*(i
/16383.) > ToLinearF
[j
]*ToLinearF
[j
+1])
572 From14
[i
] = (uint16
)j
;
576 for (i
= 0; i
< 256; i
++) {
577 while ((i
/255.)*(i
/255.) > ToLinearF
[j
]*ToLinearF
[j
+1])
579 From8
[i
] = (uint16
)j
;
582 Fltsize
= (float)(lt2size
/2);
584 sp
->ToLinearF
= ToLinearF
;
585 sp
->ToLinear16
= ToLinear16
;
586 sp
->ToLinear8
= ToLinear8
;
587 sp
->FromLT2
= FromLT2
;
594 #define DecoderState(tif) ((PixarLogState*) (tif)->tif_data)
595 #define EncoderState(tif) ((PixarLogState*) (tif)->tif_data)
597 static int PixarLogEncode(TIFF
* tif
, uint8
* bp
, tmsize_t cc
, uint16 s
);
598 static int PixarLogDecode(TIFF
* tif
, uint8
* op
, tmsize_t occ
, uint16 s
);
600 #define PIXARLOGDATAFMT_UNKNOWN -1
603 PixarLogGuessDataFmt(TIFFDirectory
*td
)
605 int guess
= PIXARLOGDATAFMT_UNKNOWN
;
606 int format
= td
->td_sampleformat
;
608 /* If the user didn't tell us his datafmt,
609 * take our best guess from the bitspersample.
611 switch (td
->td_bitspersample
) {
613 if (format
== SAMPLEFORMAT_IEEEFP
)
614 guess
= PIXARLOGDATAFMT_FLOAT
;
617 if (format
== SAMPLEFORMAT_VOID
|| format
== SAMPLEFORMAT_UINT
)
618 guess
= PIXARLOGDATAFMT_16BIT
;
621 if (format
== SAMPLEFORMAT_VOID
|| format
== SAMPLEFORMAT_INT
)
622 guess
= PIXARLOGDATAFMT_12BITPICIO
;
625 if (format
== SAMPLEFORMAT_VOID
|| format
== SAMPLEFORMAT_UINT
)
626 guess
= PIXARLOGDATAFMT_11BITLOG
;
629 if (format
== SAMPLEFORMAT_VOID
|| format
== SAMPLEFORMAT_UINT
)
630 guess
= PIXARLOGDATAFMT_8BIT
;
637 #define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
638 #define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
641 multiply_ms(tmsize_t m1
, tmsize_t m2
)
643 if( m1
== 0 || m2
> TIFF_TMSIZE_T_MAX
/ m1
)
649 add_ms(tmsize_t m1
, tmsize_t m2
)
651 /* if either input is zero, assume overflow already occurred */
652 if (m1
== 0 || m2
== 0)
654 else if (m1
> TIFF_TMSIZE_T_MAX
- m2
)
661 PixarLogFixupTags(TIFF
* tif
)
668 PixarLogSetupDecode(TIFF
* tif
)
670 static const char module
[] = "PixarLogSetupDecode";
671 TIFFDirectory
*td
= &tif
->tif_dir
;
672 PixarLogState
* sp
= DecoderState(tif
);
678 /* This function can possibly be called several times by */
679 /* PredictorSetupDecode() if this function succeeds but */
680 /* PredictorSetup() fails */
681 if( (sp
->state
& PLSTATE_INIT
) != 0 )
684 strip_height
= td
->td_rowsperstrip
;
685 if( strip_height
> td
->td_imagelength
)
686 strip_height
= td
->td_imagelength
;
688 /* Make sure no byte swapping happens on the data
689 * after decompression. */
690 tif
->tif_postdecode
= _TIFFNoPostDecode
;
692 /* for some reason, we can't do this in TIFFInitPixarLog */
694 sp
->stride
= (td
->td_planarconfig
== PLANARCONFIG_CONTIG
?
695 td
->td_samplesperpixel
: 1);
696 tbuf_size
= multiply_ms(multiply_ms(multiply_ms(sp
->stride
, td
->td_imagewidth
),
697 strip_height
), sizeof(uint16
));
698 /* add one more stride in case input ends mid-stride */
699 tbuf_size
= add_ms(tbuf_size
, sizeof(uint16
) * sp
->stride
);
701 return (0); /* TODO: this is an error return without error report through TIFFErrorExt */
702 sp
->tbuf
= (uint16
*) _TIFFmalloc(tbuf_size
);
703 if (sp
->tbuf
== NULL
)
705 sp
->tbuf_size
= tbuf_size
;
706 if (sp
->user_datafmt
== PIXARLOGDATAFMT_UNKNOWN
)
707 sp
->user_datafmt
= PixarLogGuessDataFmt(td
);
708 if (sp
->user_datafmt
== PIXARLOGDATAFMT_UNKNOWN
) {
712 TIFFErrorExt(tif
->tif_clientdata
, module
,
713 "PixarLog compression can't handle bits depth/data format combination (depth: %d)",
714 td
->td_bitspersample
);
718 if (inflateInit(&sp
->stream
) != Z_OK
) {
722 TIFFErrorExt(tif
->tif_clientdata
, module
, "%s", sp
->stream
.msg
? sp
->stream
.msg
: "(null)");
725 sp
->state
|= PLSTATE_INIT
;
731 * Setup state for decoding a strip.
734 PixarLogPreDecode(TIFF
* tif
, uint16 s
)
736 static const char module
[] = "PixarLogPreDecode";
737 PixarLogState
* sp
= DecoderState(tif
);
741 sp
->stream
.next_in
= tif
->tif_rawdata
;
742 assert(sizeof(sp
->stream
.avail_in
)==4); /* if this assert gets raised,
743 we need to simplify this code to reflect a ZLib that is likely updated
744 to deal with 8byte memory sizes, though this code will respond
745 appropriately even before we simplify it */
746 sp
->stream
.avail_in
= (uInt
) tif
->tif_rawcc
;
747 if ((tmsize_t
)sp
->stream
.avail_in
!= tif
->tif_rawcc
)
749 TIFFErrorExt(tif
->tif_clientdata
, module
, "ZLib cannot deal with buffers this size");
752 return (inflateReset(&sp
->stream
) == Z_OK
);
756 PixarLogDecode(TIFF
* tif
, uint8
* op
, tmsize_t occ
, uint16 s
)
758 static const char module
[] = "PixarLogDecode";
759 TIFFDirectory
*td
= &tif
->tif_dir
;
760 PixarLogState
* sp
= DecoderState(tif
);
766 switch (sp
->user_datafmt
) {
767 case PIXARLOGDATAFMT_FLOAT
:
768 nsamples
= occ
/ sizeof(float); /* XXX float == 32 bits */
770 case PIXARLOGDATAFMT_16BIT
:
771 case PIXARLOGDATAFMT_12BITPICIO
:
772 case PIXARLOGDATAFMT_11BITLOG
:
773 nsamples
= occ
/ sizeof(uint16
); /* XXX uint16 == 16 bits */
775 case PIXARLOGDATAFMT_8BIT
:
776 case PIXARLOGDATAFMT_8BITABGR
:
780 TIFFErrorExt(tif
->tif_clientdata
, module
,
781 "%d bit input not supported in PixarLog",
782 td
->td_bitspersample
);
786 llen
= sp
->stride
* td
->td_imagewidth
;
791 sp
->stream
.next_in
= tif
->tif_rawcp
;
792 sp
->stream
.avail_in
= (uInt
) tif
->tif_rawcc
;
794 sp
->stream
.next_out
= (unsigned char *) sp
->tbuf
;
795 assert(sizeof(sp
->stream
.avail_out
)==4); /* if this assert gets raised,
796 we need to simplify this code to reflect a ZLib that is likely updated
797 to deal with 8byte memory sizes, though this code will respond
798 appropriately even before we simplify it */
799 sp
->stream
.avail_out
= (uInt
) (nsamples
* sizeof(uint16
));
800 if (sp
->stream
.avail_out
!= nsamples
* sizeof(uint16
))
802 TIFFErrorExt(tif
->tif_clientdata
, module
, "ZLib cannot deal with buffers this size");
805 /* Check that we will not fill more than what was allocated */
806 if ((tmsize_t
)sp
->stream
.avail_out
> sp
->tbuf_size
)
808 TIFFErrorExt(tif
->tif_clientdata
, module
, "sp->stream.avail_out > sp->tbuf_size");
812 int state
= inflate(&sp
->stream
, Z_PARTIAL_FLUSH
);
813 if (state
== Z_STREAM_END
) {
816 if (state
== Z_DATA_ERROR
) {
817 TIFFErrorExt(tif
->tif_clientdata
, module
,
818 "Decoding error at scanline %lu, %s",
819 (unsigned long) tif
->tif_row
, sp
->stream
.msg
? sp
->stream
.msg
: "(null)");
820 if (inflateSync(&sp
->stream
) != Z_OK
)
825 TIFFErrorExt(tif
->tif_clientdata
, module
, "ZLib error: %s",
826 sp
->stream
.msg
? sp
->stream
.msg
: "(null)");
829 } while (sp
->stream
.avail_out
> 0);
831 /* hopefully, we got all the bytes we needed */
832 if (sp
->stream
.avail_out
!= 0) {
833 TIFFErrorExt(tif
->tif_clientdata
, module
,
834 "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT
" bytes)",
835 (unsigned long) tif
->tif_row
, (TIFF_UINT64_T
) sp
->stream
.avail_out
);
839 tif
->tif_rawcp
= sp
->stream
.next_in
;
840 tif
->tif_rawcc
= sp
->stream
.avail_in
;
843 /* Swap bytes in the data if from a different endian machine. */
844 if (tif
->tif_flags
& TIFF_SWAB
)
845 TIFFSwabArrayOfShort(up
, nsamples
);
848 * if llen is not an exact multiple of nsamples, the decode operation
849 * may overflow the output buffer, so truncate it enough to prevent
850 * that but still salvage as much data as possible.
852 if (nsamples
% llen
) {
853 TIFFWarningExt(tif
->tif_clientdata
, module
,
854 "stride %lu is not a multiple of sample count, "
855 "%lu, data truncated.", (unsigned long) llen
, (unsigned long) nsamples
);
856 nsamples
-= nsamples
% llen
;
859 for (i
= 0; i
< nsamples
; i
+= llen
, up
+= llen
) {
860 switch (sp
->user_datafmt
) {
861 case PIXARLOGDATAFMT_FLOAT
:
862 horizontalAccumulateF(up
, llen
, sp
->stride
,
863 (float *)op
, sp
->ToLinearF
);
864 op
+= llen
* sizeof(float);
866 case PIXARLOGDATAFMT_16BIT
:
867 horizontalAccumulate16(up
, llen
, sp
->stride
,
868 (uint16
*)op
, sp
->ToLinear16
);
869 op
+= llen
* sizeof(uint16
);
871 case PIXARLOGDATAFMT_12BITPICIO
:
872 horizontalAccumulate12(up
, llen
, sp
->stride
,
873 (int16
*)op
, sp
->ToLinearF
);
874 op
+= llen
* sizeof(int16
);
876 case PIXARLOGDATAFMT_11BITLOG
:
877 horizontalAccumulate11(up
, llen
, sp
->stride
,
879 op
+= llen
* sizeof(uint16
);
881 case PIXARLOGDATAFMT_8BIT
:
882 horizontalAccumulate8(up
, llen
, sp
->stride
,
883 (unsigned char *)op
, sp
->ToLinear8
);
884 op
+= llen
* sizeof(unsigned char);
886 case PIXARLOGDATAFMT_8BITABGR
:
887 horizontalAccumulate8abgr(up
, llen
, sp
->stride
,
888 (unsigned char *)op
, sp
->ToLinear8
);
889 op
+= llen
* sizeof(unsigned char);
892 TIFFErrorExt(tif
->tif_clientdata
, module
,
893 "Unsupported bits/sample: %d",
894 td
->td_bitspersample
);
903 PixarLogSetupEncode(TIFF
* tif
)
905 static const char module
[] = "PixarLogSetupEncode";
906 TIFFDirectory
*td
= &tif
->tif_dir
;
907 PixarLogState
* sp
= EncoderState(tif
);
912 /* for some reason, we can't do this in TIFFInitPixarLog */
914 sp
->stride
= (td
->td_planarconfig
== PLANARCONFIG_CONTIG
?
915 td
->td_samplesperpixel
: 1);
916 tbuf_size
= multiply_ms(multiply_ms(multiply_ms(sp
->stride
, td
->td_imagewidth
),
917 td
->td_rowsperstrip
), sizeof(uint16
));
919 return (0); /* TODO: this is an error return without error report through TIFFErrorExt */
920 sp
->tbuf
= (uint16
*) _TIFFmalloc(tbuf_size
);
921 if (sp
->tbuf
== NULL
)
923 if (sp
->user_datafmt
== PIXARLOGDATAFMT_UNKNOWN
)
924 sp
->user_datafmt
= PixarLogGuessDataFmt(td
);
925 if (sp
->user_datafmt
== PIXARLOGDATAFMT_UNKNOWN
) {
926 TIFFErrorExt(tif
->tif_clientdata
, module
, "PixarLog compression can't handle %d bit linear encodings", td
->td_bitspersample
);
930 if (deflateInit(&sp
->stream
, sp
->quality
) != Z_OK
) {
931 TIFFErrorExt(tif
->tif_clientdata
, module
, "%s", sp
->stream
.msg
? sp
->stream
.msg
: "(null)");
934 sp
->state
|= PLSTATE_INIT
;
940 * Reset encoding state at the start of a strip.
943 PixarLogPreEncode(TIFF
* tif
, uint16 s
)
945 static const char module
[] = "PixarLogPreEncode";
946 PixarLogState
*sp
= EncoderState(tif
);
950 sp
->stream
.next_out
= tif
->tif_rawdata
;
951 assert(sizeof(sp
->stream
.avail_out
)==4); /* if this assert gets raised,
952 we need to simplify this code to reflect a ZLib that is likely updated
953 to deal with 8byte memory sizes, though this code will respond
954 appropriately even before we simplify it */
955 sp
->stream
.avail_out
= (uInt
)tif
->tif_rawdatasize
;
956 if ((tmsize_t
)sp
->stream
.avail_out
!= tif
->tif_rawdatasize
)
958 TIFFErrorExt(tif
->tif_clientdata
, module
, "ZLib cannot deal with buffers this size");
961 return (deflateReset(&sp
->stream
) == Z_OK
);
965 horizontalDifferenceF(float *ip
, int n
, int stride
, uint16
*wp
, uint16
*FromLT2
)
967 int32 r1
, g1
, b1
, a1
, r2
, g2
, b2
, a2
, mask
;
968 float fltsize
= Fltsize
;
970 #define CLAMP(v) ( (v<(float)0.) ? 0 \
971 : (v<(float)2.) ? FromLT2[(int)(v*fltsize)] \
972 : (v>(float)24.2) ? 2047 \
973 : LogK1*log(v*LogK2) + 0.5 )
978 r2
= wp
[0] = (uint16
) CLAMP(ip
[0]);
979 g2
= wp
[1] = (uint16
) CLAMP(ip
[1]);
980 b2
= wp
[2] = (uint16
) CLAMP(ip
[2]);
986 r1
= (int32
) CLAMP(ip
[0]); wp
[0] = (uint16
)((r1
-r2
) & mask
); r2
= r1
;
987 g1
= (int32
) CLAMP(ip
[1]); wp
[1] = (uint16
)((g1
-g2
) & mask
); g2
= g1
;
988 b1
= (int32
) CLAMP(ip
[2]); wp
[2] = (uint16
)((b1
-b2
) & mask
); b2
= b1
;
990 } else if (stride
== 4) {
991 r2
= wp
[0] = (uint16
) CLAMP(ip
[0]);
992 g2
= wp
[1] = (uint16
) CLAMP(ip
[1]);
993 b2
= wp
[2] = (uint16
) CLAMP(ip
[2]);
994 a2
= wp
[3] = (uint16
) CLAMP(ip
[3]);
1000 r1
= (int32
) CLAMP(ip
[0]); wp
[0] = (uint16
)((r1
-r2
) & mask
); r2
= r1
;
1001 g1
= (int32
) CLAMP(ip
[1]); wp
[1] = (uint16
)((g1
-g2
) & mask
); g2
= g1
;
1002 b1
= (int32
) CLAMP(ip
[2]); wp
[2] = (uint16
)((b1
-b2
) & mask
); b2
= b1
;
1003 a1
= (int32
) CLAMP(ip
[3]); wp
[3] = (uint16
)((a1
-a2
) & mask
); a2
= a1
;
1006 REPEAT(stride
, wp
[0] = (uint16
) CLAMP(ip
[0]); wp
++; ip
++)
1010 wp
[0] = (uint16
)(((int32
)CLAMP(ip
[0])-(int32
)CLAMP(ip
[-stride
])) & mask
);
1019 horizontalDifference16(unsigned short *ip
, int n
, int stride
,
1020 unsigned short *wp
, uint16
*From14
)
1022 register int r1
, g1
, b1
, a1
, r2
, g2
, b2
, a2
, mask
;
1024 /* assumption is unsigned pixel values */
1026 #define CLAMP(v) From14[(v) >> 2]
1031 r2
= wp
[0] = CLAMP(ip
[0]); g2
= wp
[1] = CLAMP(ip
[1]);
1032 b2
= wp
[2] = CLAMP(ip
[2]);
1038 r1
= CLAMP(ip
[0]); wp
[0] = (uint16
)((r1
-r2
) & mask
); r2
= r1
;
1039 g1
= CLAMP(ip
[1]); wp
[1] = (uint16
)((g1
-g2
) & mask
); g2
= g1
;
1040 b1
= CLAMP(ip
[2]); wp
[2] = (uint16
)((b1
-b2
) & mask
); b2
= b1
;
1042 } else if (stride
== 4) {
1043 r2
= wp
[0] = CLAMP(ip
[0]); g2
= wp
[1] = CLAMP(ip
[1]);
1044 b2
= wp
[2] = CLAMP(ip
[2]); a2
= wp
[3] = CLAMP(ip
[3]);
1050 r1
= CLAMP(ip
[0]); wp
[0] = (uint16
)((r1
-r2
) & mask
); r2
= r1
;
1051 g1
= CLAMP(ip
[1]); wp
[1] = (uint16
)((g1
-g2
) & mask
); g2
= g1
;
1052 b1
= CLAMP(ip
[2]); wp
[2] = (uint16
)((b1
-b2
) & mask
); b2
= b1
;
1053 a1
= CLAMP(ip
[3]); wp
[3] = (uint16
)((a1
-a2
) & mask
); a2
= a1
;
1056 REPEAT(stride
, wp
[0] = CLAMP(ip
[0]); wp
++; ip
++)
1060 wp
[0] = (uint16
)((CLAMP(ip
[0])-CLAMP(ip
[-stride
])) & mask
);
1070 horizontalDifference8(unsigned char *ip
, int n
, int stride
,
1071 unsigned short *wp
, uint16
*From8
)
1073 register int r1
, g1
, b1
, a1
, r2
, g2
, b2
, a2
, mask
;
1076 #define CLAMP(v) (From8[(v)])
1081 r2
= wp
[0] = CLAMP(ip
[0]); g2
= wp
[1] = CLAMP(ip
[1]);
1082 b2
= wp
[2] = CLAMP(ip
[2]);
1086 r1
= CLAMP(ip
[3]); wp
[3] = (uint16
)((r1
-r2
) & mask
); r2
= r1
;
1087 g1
= CLAMP(ip
[4]); wp
[4] = (uint16
)((g1
-g2
) & mask
); g2
= g1
;
1088 b1
= CLAMP(ip
[5]); wp
[5] = (uint16
)((b1
-b2
) & mask
); b2
= b1
;
1092 } else if (stride
== 4) {
1093 r2
= wp
[0] = CLAMP(ip
[0]); g2
= wp
[1] = CLAMP(ip
[1]);
1094 b2
= wp
[2] = CLAMP(ip
[2]); a2
= wp
[3] = CLAMP(ip
[3]);
1098 r1
= CLAMP(ip
[4]); wp
[4] = (uint16
)((r1
-r2
) & mask
); r2
= r1
;
1099 g1
= CLAMP(ip
[5]); wp
[5] = (uint16
)((g1
-g2
) & mask
); g2
= g1
;
1100 b1
= CLAMP(ip
[6]); wp
[6] = (uint16
)((b1
-b2
) & mask
); b2
= b1
;
1101 a1
= CLAMP(ip
[7]); wp
[7] = (uint16
)((a1
-a2
) & mask
); a2
= a1
;
1106 REPEAT(stride
, wp
[0] = CLAMP(ip
[0]); wp
++; ip
++)
1110 wp
[0] = (uint16
)((CLAMP(ip
[0])-CLAMP(ip
[-stride
])) & mask
);
1119 * Encode a chunk of pixels.
1122 PixarLogEncode(TIFF
* tif
, uint8
* bp
, tmsize_t cc
, uint16 s
)
1124 static const char module
[] = "PixarLogEncode";
1125 TIFFDirectory
*td
= &tif
->tif_dir
;
1126 PixarLogState
*sp
= EncoderState(tif
);
1130 unsigned short * up
;
1134 switch (sp
->user_datafmt
) {
1135 case PIXARLOGDATAFMT_FLOAT
:
1136 n
= cc
/ sizeof(float); /* XXX float == 32 bits */
1138 case PIXARLOGDATAFMT_16BIT
:
1139 case PIXARLOGDATAFMT_12BITPICIO
:
1140 case PIXARLOGDATAFMT_11BITLOG
:
1141 n
= cc
/ sizeof(uint16
); /* XXX uint16 == 16 bits */
1143 case PIXARLOGDATAFMT_8BIT
:
1144 case PIXARLOGDATAFMT_8BITABGR
:
1148 TIFFErrorExt(tif
->tif_clientdata
, module
,
1149 "%d bit input not supported in PixarLog",
1150 td
->td_bitspersample
);
1154 llen
= sp
->stride
* td
->td_imagewidth
;
1155 /* Check against the number of elements (of size uint16) of sp->tbuf */
1156 if( n
> (tmsize_t
)(td
->td_rowsperstrip
* llen
) )
1158 TIFFErrorExt(tif
->tif_clientdata
, module
,
1159 "Too many input bytes provided");
1163 for (i
= 0, up
= sp
->tbuf
; i
< n
; i
+= llen
, up
+= llen
) {
1164 switch (sp
->user_datafmt
) {
1165 case PIXARLOGDATAFMT_FLOAT
:
1166 horizontalDifferenceF((float *)bp
, llen
,
1167 sp
->stride
, up
, sp
->FromLT2
);
1168 bp
+= llen
* sizeof(float);
1170 case PIXARLOGDATAFMT_16BIT
:
1171 horizontalDifference16((uint16
*)bp
, llen
,
1172 sp
->stride
, up
, sp
->From14
);
1173 bp
+= llen
* sizeof(uint16
);
1175 case PIXARLOGDATAFMT_8BIT
:
1176 horizontalDifference8((unsigned char *)bp
, llen
,
1177 sp
->stride
, up
, sp
->From8
);
1178 bp
+= llen
* sizeof(unsigned char);
1181 TIFFErrorExt(tif
->tif_clientdata
, module
,
1182 "%d bit input not supported in PixarLog",
1183 td
->td_bitspersample
);
1188 sp
->stream
.next_in
= (unsigned char *) sp
->tbuf
;
1189 assert(sizeof(sp
->stream
.avail_in
)==4); /* if this assert gets raised,
1190 we need to simplify this code to reflect a ZLib that is likely updated
1191 to deal with 8byte memory sizes, though this code will respond
1192 appropriately even before we simplify it */
1193 sp
->stream
.avail_in
= (uInt
) (n
* sizeof(uint16
));
1194 if ((sp
->stream
.avail_in
/ sizeof(uint16
)) != (uInt
) n
)
1196 TIFFErrorExt(tif
->tif_clientdata
, module
,
1197 "ZLib cannot deal with buffers this size");
1202 if (deflate(&sp
->stream
, Z_NO_FLUSH
) != Z_OK
) {
1203 TIFFErrorExt(tif
->tif_clientdata
, module
, "Encoder error: %s",
1204 sp
->stream
.msg
? sp
->stream
.msg
: "(null)");
1207 if (sp
->stream
.avail_out
== 0) {
1208 tif
->tif_rawcc
= tif
->tif_rawdatasize
;
1209 TIFFFlushData1(tif
);
1210 sp
->stream
.next_out
= tif
->tif_rawdata
;
1211 sp
->stream
.avail_out
= (uInt
) tif
->tif_rawdatasize
; /* this is a safe typecast, as check is made already in PixarLogPreEncode */
1213 } while (sp
->stream
.avail_in
> 0);
1218 * Finish off an encoded strip by flushing the last
1219 * string and tacking on an End Of Information code.
1223 PixarLogPostEncode(TIFF
* tif
)
1225 static const char module
[] = "PixarLogPostEncode";
1226 PixarLogState
*sp
= EncoderState(tif
);
1229 sp
->stream
.avail_in
= 0;
1232 state
= deflate(&sp
->stream
, Z_FINISH
);
1236 if ((tmsize_t
)sp
->stream
.avail_out
!= tif
->tif_rawdatasize
) {
1238 tif
->tif_rawdatasize
- sp
->stream
.avail_out
;
1239 TIFFFlushData1(tif
);
1240 sp
->stream
.next_out
= tif
->tif_rawdata
;
1241 sp
->stream
.avail_out
= (uInt
) tif
->tif_rawdatasize
; /* this is a safe typecast, as check is made already in PixarLogPreEncode */
1245 TIFFErrorExt(tif
->tif_clientdata
, module
, "ZLib error: %s",
1246 sp
->stream
.msg
? sp
->stream
.msg
: "(null)");
1249 } while (state
!= Z_STREAM_END
);
1254 PixarLogClose(TIFF
* tif
)
1256 PixarLogState
* sp
= (PixarLogState
*) tif
->tif_data
;
1257 TIFFDirectory
*td
= &tif
->tif_dir
;
1260 /* In a really sneaky (and really incorrect, and untruthful, and
1261 * troublesome, and error-prone) maneuver that completely goes against
1262 * the spirit of TIFF, and breaks TIFF, on close, we covertly
1263 * modify both bitspersample and sampleformat in the directory to
1264 * indicate 8-bit linear. This way, the decode "just works" even for
1265 * readers that don't know about PixarLog, or how to set
1266 * the PIXARLOGDATFMT pseudo-tag.
1269 if (sp
->state
&PLSTATE_INIT
) {
1270 /* We test the state to avoid an issue such as in
1271 * http://bugzilla.maptools.org/show_bug.cgi?id=2604
1272 * What appends in that case is that the bitspersample is 1 and
1273 * a TransferFunction is set. The size of the TransferFunction
1274 * depends on 1<<bitspersample. So if we increase it, an access
1275 * out of the buffer will happen at directory flushing.
1276 * Another option would be to clear those targs.
1278 td
->td_bitspersample
= 8;
1279 td
->td_sampleformat
= SAMPLEFORMAT_UINT
;
1284 PixarLogCleanup(TIFF
* tif
)
1286 PixarLogState
* sp
= (PixarLogState
*) tif
->tif_data
;
1290 (void)TIFFPredictorCleanup(tif
);
1292 tif
->tif_tagmethods
.vgetfield
= sp
->vgetparent
;
1293 tif
->tif_tagmethods
.vsetfield
= sp
->vsetparent
;
1295 if (sp
->FromLT2
) _TIFFfree(sp
->FromLT2
);
1296 if (sp
->From14
) _TIFFfree(sp
->From14
);
1297 if (sp
->From8
) _TIFFfree(sp
->From8
);
1298 if (sp
->ToLinearF
) _TIFFfree(sp
->ToLinearF
);
1299 if (sp
->ToLinear16
) _TIFFfree(sp
->ToLinear16
);
1300 if (sp
->ToLinear8
) _TIFFfree(sp
->ToLinear8
);
1301 if (sp
->state
&PLSTATE_INIT
) {
1302 if (tif
->tif_mode
== O_RDONLY
)
1303 inflateEnd(&sp
->stream
);
1305 deflateEnd(&sp
->stream
);
1308 _TIFFfree(sp
->tbuf
);
1310 tif
->tif_data
= NULL
;
1312 _TIFFSetDefaultCompressionState(tif
);
1316 PixarLogVSetField(TIFF
* tif
, uint32 tag
, va_list ap
)
1318 static const char module
[] = "PixarLogVSetField";
1319 PixarLogState
*sp
= (PixarLogState
*)tif
->tif_data
;
1323 case TIFFTAG_PIXARLOGQUALITY
:
1324 sp
->quality
= (int) va_arg(ap
, int);
1325 if (tif
->tif_mode
!= O_RDONLY
&& (sp
->state
&PLSTATE_INIT
)) {
1326 if (deflateParams(&sp
->stream
,
1327 sp
->quality
, Z_DEFAULT_STRATEGY
) != Z_OK
) {
1328 TIFFErrorExt(tif
->tif_clientdata
, module
, "ZLib error: %s",
1329 sp
->stream
.msg
? sp
->stream
.msg
: "(null)");
1334 case TIFFTAG_PIXARLOGDATAFMT
:
1335 sp
->user_datafmt
= (int) va_arg(ap
, int);
1336 /* Tweak the TIFF header so that the rest of libtiff knows what
1337 * size of data will be passed between app and library, and
1338 * assume that the app knows what it is doing and is not
1339 * confused by these header manipulations...
1341 switch (sp
->user_datafmt
) {
1342 case PIXARLOGDATAFMT_8BIT
:
1343 case PIXARLOGDATAFMT_8BITABGR
:
1344 TIFFSetField(tif
, TIFFTAG_BITSPERSAMPLE
, 8);
1345 TIFFSetField(tif
, TIFFTAG_SAMPLEFORMAT
, SAMPLEFORMAT_UINT
);
1347 case PIXARLOGDATAFMT_11BITLOG
:
1348 TIFFSetField(tif
, TIFFTAG_BITSPERSAMPLE
, 16);
1349 TIFFSetField(tif
, TIFFTAG_SAMPLEFORMAT
, SAMPLEFORMAT_UINT
);
1351 case PIXARLOGDATAFMT_12BITPICIO
:
1352 TIFFSetField(tif
, TIFFTAG_BITSPERSAMPLE
, 16);
1353 TIFFSetField(tif
, TIFFTAG_SAMPLEFORMAT
, SAMPLEFORMAT_INT
);
1355 case PIXARLOGDATAFMT_16BIT
:
1356 TIFFSetField(tif
, TIFFTAG_BITSPERSAMPLE
, 16);
1357 TIFFSetField(tif
, TIFFTAG_SAMPLEFORMAT
, SAMPLEFORMAT_UINT
);
1359 case PIXARLOGDATAFMT_FLOAT
:
1360 TIFFSetField(tif
, TIFFTAG_BITSPERSAMPLE
, 32);
1361 TIFFSetField(tif
, TIFFTAG_SAMPLEFORMAT
, SAMPLEFORMAT_IEEEFP
);
1365 * Must recalculate sizes should bits/sample change.
1367 tif
->tif_tilesize
= isTiled(tif
) ? TIFFTileSize(tif
) : (tmsize_t
)(-1);
1368 tif
->tif_scanlinesize
= TIFFScanlineSize(tif
);
1369 result
= 1; /* NB: pseudo tag */
1372 result
= (*sp
->vsetparent
)(tif
, tag
, ap
);
1378 PixarLogVGetField(TIFF
* tif
, uint32 tag
, va_list ap
)
1380 PixarLogState
*sp
= (PixarLogState
*)tif
->tif_data
;
1383 case TIFFTAG_PIXARLOGQUALITY
:
1384 *va_arg(ap
, int*) = sp
->quality
;
1386 case TIFFTAG_PIXARLOGDATAFMT
:
1387 *va_arg(ap
, int*) = sp
->user_datafmt
;
1390 return (*sp
->vgetparent
)(tif
, tag
, ap
);
1395 static const TIFFField pixarlogFields
[] = {
1396 {TIFFTAG_PIXARLOGDATAFMT
, 0, 0, TIFF_ANY
, 0, TIFF_SETGET_INT
, TIFF_SETGET_UNDEFINED
, FIELD_PSEUDO
, FALSE
, FALSE
, "", NULL
},
1397 {TIFFTAG_PIXARLOGQUALITY
, 0, 0, TIFF_ANY
, 0, TIFF_SETGET_INT
, TIFF_SETGET_UNDEFINED
, FIELD_PSEUDO
, FALSE
, FALSE
, "", NULL
}
1401 TIFFInitPixarLog(TIFF
* tif
, int scheme
)
1403 static const char module
[] = "TIFFInitPixarLog";
1407 assert(scheme
== COMPRESSION_PIXARLOG
);
1410 * Merge codec-specific tag information.
1412 if (!_TIFFMergeFields(tif
, pixarlogFields
,
1413 TIFFArrayCount(pixarlogFields
))) {
1414 TIFFErrorExt(tif
->tif_clientdata
, module
,
1415 "Merging PixarLog codec-specific tags failed");
1420 * Allocate state block so tag methods have storage to record values.
1422 tif
->tif_data
= (uint8
*) _TIFFmalloc(sizeof (PixarLogState
));
1423 if (tif
->tif_data
== NULL
)
1425 sp
= (PixarLogState
*) tif
->tif_data
;
1426 _TIFFmemset(sp
, 0, sizeof (*sp
));
1427 sp
->stream
.data_type
= Z_BINARY
;
1428 sp
->user_datafmt
= PIXARLOGDATAFMT_UNKNOWN
;
1431 * Install codec methods.
1433 tif
->tif_fixuptags
= PixarLogFixupTags
;
1434 tif
->tif_setupdecode
= PixarLogSetupDecode
;
1435 tif
->tif_predecode
= PixarLogPreDecode
;
1436 tif
->tif_decoderow
= PixarLogDecode
;
1437 tif
->tif_decodestrip
= PixarLogDecode
;
1438 tif
->tif_decodetile
= PixarLogDecode
;
1439 tif
->tif_setupencode
= PixarLogSetupEncode
;
1440 tif
->tif_preencode
= PixarLogPreEncode
;
1441 tif
->tif_postencode
= PixarLogPostEncode
;
1442 tif
->tif_encoderow
= PixarLogEncode
;
1443 tif
->tif_encodestrip
= PixarLogEncode
;
1444 tif
->tif_encodetile
= PixarLogEncode
;
1445 tif
->tif_close
= PixarLogClose
;
1446 tif
->tif_cleanup
= PixarLogCleanup
;
1448 /* Override SetField so we can handle our private pseudo-tag */
1449 sp
->vgetparent
= tif
->tif_tagmethods
.vgetfield
;
1450 tif
->tif_tagmethods
.vgetfield
= PixarLogVGetField
; /* hook for codec tags */
1451 sp
->vsetparent
= tif
->tif_tagmethods
.vsetfield
;
1452 tif
->tif_tagmethods
.vsetfield
= PixarLogVSetField
; /* hook for codec tags */
1454 /* Default values for codec-specific fields */
1455 sp
->quality
= Z_DEFAULT_COMPRESSION
; /* default comp. level */
1458 /* we don't wish to use the predictor,
1459 * the default is none, which predictor value 1
1461 (void) TIFFPredictorInit(tif
);
1464 * build the companding tables
1466 PixarLogMakeTables(sp
);
1470 TIFFErrorExt(tif
->tif_clientdata
, module
,
1471 "No space for PixarLog state block");
1474 #endif /* PIXARLOG_SUPPORT */
1476 /* vim: set ts=8 sts=8 sw=8 noet: */