/* * Copyright (c) 1996-1997 Sam Leffler * Copyright (c) 1996 Pixar * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Pixar, Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Pixar, Sam Leffler and Silicon Graphics. * * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL PIXAR, SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "tiffiop.h" #ifdef PIXARLOG_SUPPORT /* * TIFF Library. * PixarLog Compression Support * * Contributed by Dan McCoy. * * PixarLog film support uses the TIFF library to store companded * 11 bit values into a tiff file, which are compressed using the * zip compressor. * * The codec can take as input and produce as output 32-bit IEEE float values * as well as 16-bit or 8-bit unsigned integer values. * * On writing any of the above are converted into the internal * 11-bit log format. In the case of 8 and 16 bit values, the * input is assumed to be unsigned linear color values that represent * the range 0-1. In the case of IEEE values, the 0-1 range is assumed to * be the normal linear color range, in addition over 1 values are * accepted up to a value of about 25.0 to encode "hot" highlights and such. * The encoding is lossless for 8-bit values, slightly lossy for the * other bit depths. The actual color precision should be better * than the human eye can perceive with extra room to allow for * error introduced by further image computation. As with any quantized * color format, it is possible to perform image calculations which * expose the quantization error. This format should certainly be less * susceptible to such errors than standard 8-bit encodings, but more * susceptible than straight 16-bit or 32-bit encodings. * * On reading the internal format is converted to the desired output format. * The program can request which format it desires by setting the internal * pseudo tag TIFFTAG_PIXARLOGDATAFMT to one of these possible values: * PIXARLOGDATAFMT_FLOAT = provide IEEE float values. * PIXARLOGDATAFMT_16BIT = provide unsigned 16-bit integer values * PIXARLOGDATAFMT_8BIT = provide unsigned 8-bit integer values * * alternately PIXARLOGDATAFMT_8BITABGR provides unsigned 8-bit integer * values with the difference that if there are exactly three or four channels * (rgb or rgba) it swaps the channel order (bgr or abgr). * * PIXARLOGDATAFMT_11BITLOG provides the internal encoding directly * packed in 16-bit values. However no tools are supplied for interpreting * these values. * * "hot" (over 1.0) areas written in floating point get clamped to * 1.0 in the integer data types. * * When the file is closed after writing, the bit depth and sample format * are set always to appear as if 8-bit data has been written into it. * That way a naive program unaware of the particulars of the encoding * gets the format it is most likely able to handle. * * The codec does it's own horizontal differencing step on the coded * values so the libraries predictor stuff should be turned off. * The codec also handle byte swapping the encoded values as necessary * since the library does not have the information necessary * to know the bit depth of the raw unencoded buffer. * * NOTE: This decoder does not appear to update tif_rawcp, and tif_rawcc. * This can cause problems with the implementation of CHUNKY_STRIP_READ_SUPPORT * as noted in http://trac.osgeo.org/gdal/ticket/3894. FrankW - Jan'11 */ #include "tif_predict.h" #include "zlib.h" #include <math.h> #include <stdio.h> #include <stdlib.h> /* Tables for converting to/from 11 bit coded values */ #define TSIZE … #define TSIZEP1 … #define ONE … #define RATIO … #define CODE_MASK … static float Fltsize; static float LogK1, LogK2; #define REPEAT(n, op) … static void horizontalAccumulateF(uint16_t *wp, int n, int stride, float *op, float *ToLinearF) { … } static void horizontalAccumulate12(uint16_t *wp, int n, int stride, int16_t *op, float *ToLinearF) { … } static void horizontalAccumulate16(uint16_t *wp, int n, int stride, uint16_t *op, uint16_t *ToLinear16) { … } /* * Returns the log encoded 11-bit values with the horizontal * differencing undone. */ static void horizontalAccumulate11(uint16_t *wp, int n, int stride, uint16_t *op) { … } static void horizontalAccumulate8(uint16_t *wp, int n, int stride, unsigned char *op, unsigned char *ToLinear8) { … } static void horizontalAccumulate8abgr(uint16_t *wp, int n, int stride, unsigned char *op, unsigned char *ToLinear8) { … } /* * State block for each open TIFF * file using PixarLog compression/decompression. */ PixarLogState; static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp) { … } #define DecoderState(tif) … #define EncoderState(tif) … static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); #define PIXARLOGDATAFMT_UNKNOWN … static int PixarLogGuessDataFmt(TIFFDirectory *td) { … } static tmsize_t multiply_ms(tmsize_t m1, tmsize_t m2) { … } static tmsize_t add_ms(tmsize_t m1, tmsize_t m2) { … } static int PixarLogFixupTags(TIFF *tif) { … } static int PixarLogSetupDecode(TIFF *tif) { … } /* * Setup state for decoding a strip. */ static int PixarLogPreDecode(TIFF *tif, uint16_t s) { … } static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { … } static int PixarLogSetupEncode(TIFF *tif) { … } /* * Reset encoding state at the start of a strip. */ static int PixarLogPreEncode(TIFF *tif, uint16_t s) { … } static void horizontalDifferenceF(float *ip, int n, int stride, uint16_t *wp, uint16_t *FromLT2) { … } static void horizontalDifference16(unsigned short *ip, int n, int stride, unsigned short *wp, uint16_t *From14) { … } static void horizontalDifference8(unsigned char *ip, int n, int stride, unsigned short *wp, uint16_t *From8) { … } /* * Encode a chunk of pixels. */ static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { … } /* * Finish off an encoded strip by flushing the last * string and tacking on an End Of Information code. */ static int PixarLogPostEncode(TIFF *tif) { … } static void PixarLogClose(TIFF *tif) { … } static void PixarLogCleanup(TIFF *tif) { … } static int PixarLogVSetField(TIFF *tif, uint32_t tag, va_list ap) { … } static int PixarLogVGetField(TIFF *tif, uint32_t tag, va_list ap) { … } static const TIFFField pixarlogFields[] = …; int TIFFInitPixarLog(TIFF *tif, int scheme) { … } #endif /* PIXARLOG_SUPPORT */