[LIBTIFF]
[reactos.git] / reactos / dll / 3rdparty / libtiff / tif_pixarlog.c
index d36f1f9..4e61445 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_pixarlog.c,v 1.38 2012-06-21 01:01:53 fwarmerdam Exp $ */
+/* $Id: tif_pixarlog.c,v 1.48 2016-09-23 22:12:18 erouault Exp $ */
 
 /*
  * Copyright (c) 1996-1997 Sam Leffler
  * 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" hightlights and such.
+ * 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 
- * susceptable to such errors than standard 8-bit encodings, but more
- * susceptable than straight 16-bit or 32-bit encodings.
+ * 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
@@ -93,6 +93,8 @@
 #include "tif_predict.h"
 #include "zlib.h"
 
+//#include <stdio.h>
+//#include <stdlib.h>
 #include <math.h>
 
 /* Tables for converting to/from 11 bit coded values */
@@ -295,33 +297,35 @@ horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op,
 static void
 horizontalAccumulate11(uint16 *wp, int n, int stride, uint16 *op)
 {
-    register unsigned int  cr, cg, cb, ca, mask;
+    register unsigned int cr, cg, cb, ca, mask;
 
     if (n >= stride) {
        mask = CODE_MASK;
        if (stride == 3) {
-           op[0] = cr = wp[0];  op[1] = cg = wp[1];  op[2] = cb = wp[2];
+           op[0] = wp[0];  op[1] = wp[1];  op[2] = wp[2];
+            cr = wp[0];  cg = wp[1];  cb = wp[2];
            n -= 3;
            while (n > 0) {
                wp += 3;
                op += 3;
                n -= 3;
-               op[0] = (cr += wp[0]) & mask;
-               op[1] = (cg += wp[1]) & mask;
-               op[2] = (cb += wp[2]) & mask;
+               op[0] = (uint16)((cr += wp[0]) & mask);
+               op[1] = (uint16)((cg += wp[1]) & mask);
+               op[2] = (uint16)((cb += wp[2]) & mask);
            }
        } else if (stride == 4) {
-           op[0] = cr = wp[0];  op[1] = cg = wp[1];
-           op[2] = cb = wp[2];  op[3] = ca = wp[3];
+           op[0] = wp[0];  op[1] = wp[1];
+           op[2] = wp[2];  op[3] = wp[3];
+            cr = wp[0]; cg = wp[1]; cb = wp[2]; ca = wp[3];
            n -= 4;
            while (n > 0) {
                wp += 4;
                op += 4;
                n -= 4;
-               op[0] = (cr += wp[0]) & mask;
-               op[1] = (cg += wp[1]) & mask;
-               op[2] = (cb += wp[2]) & mask;
-               op[3] = (ca += wp[3]) & mask;
+               op[0] = (uint16)((cr += wp[0]) & mask);
+               op[1] = (uint16)((cg += wp[1]) & mask);
+               op[2] = (uint16)((cb += wp[2]) & mask);
+               op[3] = (uint16)((ca += wp[3]) & mask);
            } 
        } else {
            REPEAT(stride, *op = *wp&mask; wp++; op++)
@@ -456,6 +460,7 @@ horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op,
 typedef        struct {
        TIFFPredictorState      predict;
        z_stream                stream;
+       tmsize_t                tbuf_size; /* only set/used on reading for now */
        uint16                  *tbuf; 
        uint16                  stride;
        int                     state;
@@ -555,7 +560,7 @@ PixarLogMakeTables(PixarLogState *sp)
     for (i = 0; i < lt2size; i++)  {
        if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1])
            j++;
-       FromLT2[i] = j;
+       FromLT2[i] = (uint16)j;
     }
 
     /*
@@ -567,14 +572,14 @@ PixarLogMakeTables(PixarLogState *sp)
     for (i = 0; i < 16384; i++)  {
        while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1])
            j++;
-       From14[i] = j;
+       From14[i] = (uint16)j;
     }
 
     j = 0;
     for (i = 0; i < 256; i++)  {
        while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1])
            j++;
-       From8[i] = j;
+       From8[i] = (uint16)j;
     }
 
     Fltsize = (float)(lt2size/2);
@@ -643,6 +648,20 @@ multiply_ms(tmsize_t m1, tmsize_t m2)
        return bytes;
 }
 
+static tmsize_t
+add_ms(tmsize_t m1, tmsize_t m2)
+{
+       tmsize_t bytes = m1 + m2;
+
+       /* if either input is zero, assume overflow already occurred */
+       if (m1 == 0 || m2 == 0)
+               bytes = 0;
+       else if (bytes <= m1 || bytes <= m2)
+               bytes = 0;
+
+       return bytes;
+}
+
 static int
 PixarLogFixupTags(TIFF* tif)
 {
@@ -670,11 +689,14 @@ PixarLogSetupDecode(TIFF* tif)
            td->td_samplesperpixel : 1);
        tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth),
                                      td->td_rowsperstrip), sizeof(uint16));
+       /* add one more stride in case input ends mid-stride */
+       tbuf_size = add_ms(tbuf_size, sizeof(uint16) * sp->stride);
        if (tbuf_size == 0)
                return (0);   /* TODO: this is an error return without error report through TIFFErrorExt */
-       sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size+sizeof(uint16)*sp->stride);
+       sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size);
        if (sp->tbuf == NULL)
                return (0);
+       sp->tbuf_size = tbuf_size;
        if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
                sp->user_datafmt = PixarLogGuessDataFmt(td);
        if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
@@ -685,7 +707,7 @@ PixarLogSetupDecode(TIFF* tif)
        }
 
        if (inflateInit(&sp->stream) != Z_OK) {
-               TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
+               TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg ? sp->stream.msg : "(null)");
                return (0);
        } else {
                sp->state |= PLSTATE_INIT;
@@ -708,7 +730,7 @@ PixarLogPreDecode(TIFF* tif, uint16 s)
        assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
            we need to simplify this code to reflect a ZLib that is likely updated
            to deal with 8byte memory sizes, though this code will respond
-           apropriately even before we simplify it */
+           appropriately even before we simplify it */
        sp->stream.avail_in = (uInt) tif->tif_rawcc;
        if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
        {
@@ -757,13 +779,19 @@ PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
        assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
            we need to simplify this code to reflect a ZLib that is likely updated
            to deal with 8byte memory sizes, though this code will respond
-           apropriately even before we simplify it */
+           appropriately even before we simplify it */
        sp->stream.avail_out = (uInt) (nsamples * sizeof(uint16));
        if (sp->stream.avail_out != nsamples * sizeof(uint16))
        {
                TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
                return (0);
        }
+       /* Check that we will not fill more than what was allocated */
+       if ((tmsize_t)sp->stream.avail_out > sp->tbuf_size)
+       {
+               TIFFErrorExt(tif->tif_clientdata, module, "sp->stream.avail_out > sp->tbuf_size");
+               return (0);
+       }
        do {
                int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
                if (state == Z_STREAM_END) {
@@ -772,14 +800,14 @@ PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
                if (state == Z_DATA_ERROR) {
                        TIFFErrorExt(tif->tif_clientdata, module,
                            "Decoding error at scanline %lu, %s",
-                           (unsigned long) tif->tif_row, sp->stream.msg);
+                           (unsigned long) tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)");
                        if (inflateSync(&sp->stream) != Z_OK)
                                return (0);
                        continue;
                }
                if (state != Z_OK) {
                        TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
-                           sp->stream.msg);
+                           sp->stream.msg ? sp->stream.msg : "(null)");
                        return (0);
                }
        } while (sp->stream.avail_out > 0);
@@ -881,7 +909,7 @@ PixarLogSetupEncode(TIFF* tif)
        }
 
        if (deflateInit(&sp->stream, sp->quality) != Z_OK) {
-               TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
+               TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg ? sp->stream.msg : "(null)");
                return (0);
        } else {
                sp->state |= PLSTATE_INIT;
@@ -904,8 +932,8 @@ PixarLogPreEncode(TIFF* tif, uint16 s)
        assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
            we need to simplify this code to reflect a ZLib that is likely updated
            to deal with 8byte memory sizes, though this code will respond
-           apropriately even before we simplify it */
-       sp->stream.avail_out = tif->tif_rawdatasize;
+           appropriately even before we simplify it */
+       sp->stream.avail_out = (uInt)tif->tif_rawdatasize;
        if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
        {
                TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
@@ -936,9 +964,9 @@ horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2)
                n -= 3;
                wp += 3;
                ip += 3;
-               r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
-               g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
-               b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
+               r1 = (int32) CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1;
+               g1 = (int32) CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1;
+               b1 = (int32) CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1;
            }
        } else if (stride == 4) {
            r2 = wp[0] = (uint16) CLAMP(ip[0]);
@@ -950,23 +978,20 @@ horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2)
                n -= 4;
                wp += 4;
                ip += 4;
-               r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
-               g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
-               b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
-               a1 = (int32) CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
+               r1 = (int32) CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1;
+               g1 = (int32) CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1;
+               b1 = (int32) CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1;
+               a1 = (int32) CLAMP(ip[3]); wp[3] = (uint16)((a1-a2) & mask); a2 = a1;
            }
        } else {
-           ip += n - 1;        /* point to last one */
-           wp += n - 1;        /* point to last one */
-           n -= stride;
-           while (n > 0) {
-               REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]);
-                               wp[stride] -= wp[0];
-                               wp[stride] &= mask;
-                               wp--; ip--)
-               n -= stride;
-           }
-           REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp--; ip--)
+        REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp++; ip++)
+        n -= stride;
+        while (n > 0) {
+            REPEAT(stride,
+                wp[0] = (uint16)(((int32)CLAMP(ip[0])-(int32)CLAMP(ip[-stride])) & mask);
+                wp++; ip++)
+            n -= stride;
+        }
        }
     }
 }
@@ -991,9 +1016,9 @@ horizontalDifference16(unsigned short *ip, int n, int stride,
                n -= 3;
                wp += 3;
                ip += 3;
-               r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
-               g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
-               b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
+               r1 = CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1;
+               g1 = CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1;
+               b1 = CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1;
            }
        } else if (stride == 4) {
            r2 = wp[0] = CLAMP(ip[0]);  g2 = wp[1] = CLAMP(ip[1]);
@@ -1003,23 +1028,20 @@ horizontalDifference16(unsigned short *ip, int n, int stride,
                n -= 4;
                wp += 4;
                ip += 4;
-               r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
-               g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
-               b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
-               a1 = CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
+               r1 = CLAMP(ip[0]); wp[0] = (uint16)((r1-r2) & mask); r2 = r1;
+               g1 = CLAMP(ip[1]); wp[1] = (uint16)((g1-g2) & mask); g2 = g1;
+               b1 = CLAMP(ip[2]); wp[2] = (uint16)((b1-b2) & mask); b2 = b1;
+               a1 = CLAMP(ip[3]); wp[3] = (uint16)((a1-a2) & mask); a2 = a1;
            }
        } else {
-           ip += n - 1;        /* point to last one */
-           wp += n - 1;        /* point to last one */
+        REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++)
            n -= stride;
            while (n > 0) {
-               REPEAT(stride, wp[0] = CLAMP(ip[0]);
-                               wp[stride] -= wp[0];
-                               wp[stride] &= mask;
-                               wp--; ip--)
-               n -= stride;
-           }
-           REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
+            REPEAT(stride,
+                wp[0] = (uint16)((CLAMP(ip[0])-CLAMP(ip[-stride])) & mask);
+                wp++; ip++)
+            n -= stride;
+        }
        }
     }
 }
@@ -1042,9 +1064,9 @@ horizontalDifference8(unsigned char *ip, int n, int stride,
            n -= 3;
            while (n > 0) {
                n -= 3;
-               r1 = CLAMP(ip[3]); wp[3] = (r1-r2) & mask; r2 = r1;
-               g1 = CLAMP(ip[4]); wp[4] = (g1-g2) & mask; g2 = g1;
-               b1 = CLAMP(ip[5]); wp[5] = (b1-b2) & mask; b2 = b1;
+               r1 = CLAMP(ip[3]); wp[3] = (uint16)((r1-r2) & mask); r2 = r1;
+               g1 = CLAMP(ip[4]); wp[4] = (uint16)((g1-g2) & mask); g2 = g1;
+               b1 = CLAMP(ip[5]); wp[5] = (uint16)((b1-b2) & mask); b2 = b1;
                wp += 3;
                ip += 3;
            }
@@ -1054,26 +1076,23 @@ horizontalDifference8(unsigned char *ip, int n, int stride,
            n -= 4;
            while (n > 0) {
                n -= 4;
-               r1 = CLAMP(ip[4]); wp[4] = (r1-r2) & mask; r2 = r1;
-               g1 = CLAMP(ip[5]); wp[5] = (g1-g2) & mask; g2 = g1;
-               b1 = CLAMP(ip[6]); wp[6] = (b1-b2) & mask; b2 = b1;
-               a1 = CLAMP(ip[7]); wp[7] = (a1-a2) & mask; a2 = a1;
+               r1 = CLAMP(ip[4]); wp[4] = (uint16)((r1-r2) & mask); r2 = r1;
+               g1 = CLAMP(ip[5]); wp[5] = (uint16)((g1-g2) & mask); g2 = g1;
+               b1 = CLAMP(ip[6]); wp[6] = (uint16)((b1-b2) & mask); b2 = b1;
+               a1 = CLAMP(ip[7]); wp[7] = (uint16)((a1-a2) & mask); a2 = a1;
                wp += 4;
                ip += 4;
            }
        } else {
-           wp += n + stride - 1;       /* point to last one */
-           ip += n + stride - 1;       /* point to last one */
-           n -= stride;
-           while (n > 0) {
-               REPEAT(stride, wp[0] = CLAMP(ip[0]);
-                               wp[stride] -= wp[0];
-                               wp[stride] &= mask;
-                               wp--; ip--)
-               n -= stride;
-           }
-           REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
-       }
+        REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++)
+        n -= stride;
+        while (n > 0) {
+            REPEAT(stride,
+                wp[0] = (uint16)((CLAMP(ip[0])-CLAMP(ip[-stride])) & mask);
+                wp++; ip++)
+            n -= stride;
+        }
+    }
     }
 }
 
@@ -1114,6 +1133,13 @@ PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
        }
 
        llen = sp->stride * td->td_imagewidth;
+    /* Check against the number of elements (of size uint16) of sp->tbuf */
+    if( n > (tmsize_t)(td->td_rowsperstrip * llen) )
+    {
+        TIFFErrorExt(tif->tif_clientdata, module,
+                     "Too many input bytes provided");
+        return 0;
+    }
 
        for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) {
                switch (sp->user_datafmt)  {
@@ -1144,7 +1170,7 @@ PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
        assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
            we need to simplify this code to reflect a ZLib that is likely updated
            to deal with 8byte memory sizes, though this code will respond
-           apropriately even before we simplify it */
+           appropriately even before we simplify it */
        sp->stream.avail_in = (uInt) (n * sizeof(uint16));
        if ((sp->stream.avail_in / sizeof(uint16)) != (uInt) n)
        {
@@ -1156,7 +1182,7 @@ PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
        do {
                if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
                        TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s",
-                           sp->stream.msg);
+                           sp->stream.msg ? sp->stream.msg : "(null)");
                        return (0);
                }
                if (sp->stream.avail_out == 0) {
@@ -1198,7 +1224,7 @@ PixarLogPostEncode(TIFF* tif)
                    break;
                default:
                        TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
-                       sp->stream.msg);
+                       sp->stream.msg ? sp->stream.msg : "(null)");
                    return (0);
                }
        } while (state != Z_STREAM_END);
@@ -1210,7 +1236,7 @@ PixarLogClose(TIFF* tif)
 {
        TIFFDirectory *td = &tif->tif_dir;
 
-       /* In a really sneaky (and really incorrect, and untruthfull, and
+       /* In a really sneaky (and really incorrect, and untruthful, and
         * troublesome, and error-prone) maneuver that completely goes against
         * the spirit of TIFF, and breaks TIFF, on close, we covertly
         * modify both bitspersample and sampleformat in the directory to
@@ -1268,7 +1294,7 @@ PixarLogVSetField(TIFF* tif, uint32 tag, va_list ap)
                        if (deflateParams(&sp->stream,
                            sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) {
                                TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
-                                       sp->stream.msg);
+                                       sp->stream.msg ? sp->stream.msg : "(null)");
                                return (0);
                        }
                }