/*
 * Copyright (c) 1991-1997 Sam Leffler
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
 *
 * 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
 * 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 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 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.
 */

/*
 * TIFF Library.
 *
 * Auxiliary Support Routines.
 */
#include "tif_predict.h"
#include "tiffiop.h"
#include <float.h>
#include <math.h>

uint32_t _TIFFMultiply32(TIFF *tif, uint32_t first, uint32_t second,
                         const char *where)
{
    if (second && first > UINT32_MAX / second)
    {
        TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
        return 0;
    }

    return first * second;
}

uint64_t _TIFFMultiply64(TIFF *tif, uint64_t first, uint64_t second,
                         const char *where)
{
    if (second && first > UINT64_MAX / second)
    {
        TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
        return 0;
    }

    return first * second;
}

uint64_t _TIFFAdd64(TIFF *tif, uint64_t first, uint64_t second,
                    const char *where)
{
    if (first > UINT64_MAX - second)
    {
        if (tif != NULL && where != NULL)
        {
            TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
        }
        return 0;
    }

    return first + second;
}

tmsize_t _TIFFMultiplySSize(TIFF *tif, tmsize_t first, tmsize_t second,
                            const char *where)
{
    if (first <= 0 || second <= 0)
    {
        if (tif != NULL && where != NULL)
        {
            TIFFErrorExtR(tif, where,
                          "Invalid argument to _TIFFMultiplySSize() in %s",
                          where);
        }
        return 0;
    }

    if (first > TIFF_TMSIZE_T_MAX / second)
    {
        if (tif != NULL && where != NULL)
        {
            TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
        }
        return 0;
    }
    return first * second;
}

tmsize_t _TIFFAddSSize(TIFF *tif, tmsize_t first, tmsize_t second,
                       const char *where)
{
    if (first < 0 || second < 0)
    {
        if (tif != NULL && where != NULL)
        {
            TIFFErrorExtR(tif, where,
                          "Invalid argument to _TIFFAddSSize() in %s", where);
        }
        return 0;
    }

    if (first > TIFF_TMSIZE_T_MAX - second)
    {
        if (tif != NULL && where != NULL)
        {
            TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
        }
        return 0;
    }
    return first + second;
}

tmsize_t _TIFFCastUInt64ToSSize(TIFF *tif, uint64_t val, const char *module)
{
    if (val > (uint64_t)TIFF_TMSIZE_T_MAX)
    {
        if (tif != NULL && module != NULL)
        {
            TIFFErrorExtR(tif, module, "Integer overflow");
        }
        return 0;
    }
    return (tmsize_t)val;
}

uint32_t _TIFFCastUInt64ToUInt32(TIFF *tif, uint64_t val, const char *module)
{
    if (val > UINT32_MAX)
    {
        if (tif != NULL && module != NULL)
        {
            TIFFErrorExtR(tif, module, "Integer overflow");
        }
        return 0;
    }
    return (uint32_t)val;
}

tmsize_t _TIFFComputeRowOffset(TIFF *tif, tmsize_t rowstride, uint32_t row,
                               const char *where)
{
    if (row == 0)
        return 0;
    return _TIFFMultiplySSize(tif, rowstride, (tmsize_t)row, where);
}

uint64_t _TIFFComputeBitOffset(TIFF *tif, uint32_t col, uint16_t spp,
                               uint16_t bps, const char *where)
{
    uint64_t samples = _TIFFMultiply64(tif, col, spp, where);
    if (samples == 0 && col != 0)
        return 0;
    return _TIFFMultiply64(tif, samples, bps, where);
}

/*
 * Returns 0 on overflow or invalid zero-sized row inputs. Callers that
 * intentionally allow empty rows should not use this helper directly.
 */
uint64_t _TIFFComputeRowSize64(TIFF *tif, uint32_t width, uint16_t spp,
                               uint16_t bps, const char *where)
{
    uint64_t samples = _TIFFMultiply64(tif, width, spp, where);
    uint64_t bits;
    if (samples == 0)
        return 0;

    bits = _TIFFMultiply64(tif, samples, bps, where);
    if (bits == 0)
        return 0;

    return TIFFhowmany8_64(bits);
}

void *_TIFFCheckRealloc(TIFF *tif, void *buffer, tmsize_t nmemb,
                        tmsize_t elem_size, const char *what)
{
    void *cp = NULL;
    tmsize_t count = _TIFFMultiplySSize(tif, nmemb, elem_size, NULL);
    /*
     * Check for integer overflow.
     */
    if (count != 0)
    {
        cp = _TIFFreallocExt(tif, buffer, count);
    }

    if (cp == NULL)
    {
        TIFFErrorExtR(tif, tif->tif_name,
                      "Failed to allocate memory for %s "
                      "(%" TIFF_SSIZE_FORMAT " elements of %" TIFF_SSIZE_FORMAT
                      " bytes each)",
                      what, nmemb, elem_size);
    }

    return cp;
}

void *_TIFFCheckMalloc(TIFF *tif, tmsize_t nmemb, tmsize_t elem_size,
                       const char *what)
{
    return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what);
}

static int TIFFDefaultTransferFunction(TIFF *tif, TIFFDirectory *td)
{
    uint16_t **tf = td->td_transferfunction;
    tmsize_t i, n, nbytes;

    tf[0] = tf[1] = tf[2] = 0;
    // Do not try to generate a default TransferFunction beyond 24 bits.
    // This otherwise leads to insane amounts, resulting in denial of service
    // See https://github.com/OSGeo/gdal/issues/10875
    if (td->td_bitspersample > 24)
        return 0;

    n = (tmsize_t)(1ULL << td->td_bitspersample);
    nbytes = (tmsize_t)((uint64_t)n * sizeof(uint16_t));
    tf[0] = (uint16_t *)_TIFFmallocExt(tif, nbytes);
    if (tf[0] == NULL)
        return 0;
    tf[0][0] = 0;
    for (i = 1; i < n; i++)
    {
        double t = (double)i / ((double)n - 1.);
        tf[0][i] = (uint16_t)floor(65535. * pow(t, 2.2) + .5);
    }

    if (td->td_samplesperpixel - td->td_extrasamples > 1)
    {
        tf[1] = (uint16_t *)_TIFFmallocExt(tif, nbytes);
        if (tf[1] == NULL)
            goto bad;
        _TIFFmemcpy(tf[1], tf[0], nbytes);
        tf[2] = (uint16_t *)_TIFFmallocExt(tif, nbytes);
        if (tf[2] == NULL)
            goto bad;
        _TIFFmemcpy(tf[2], tf[0], nbytes);
    }
    return 1;

bad:
    if (tf[0])
        _TIFFfreeExt(tif, tf[0]);
    if (tf[1])
        _TIFFfreeExt(tif, tf[1]);
    if (tf[2])
        _TIFFfreeExt(tif, tf[2]);
    tf[0] = tf[1] = tf[2] = 0;
    return 0;
}

static int TIFFDefaultRefBlackWhite(TIFF *tif, TIFFDirectory *td)
{
    int i;

    td->td_refblackwhite = (float *)_TIFFmallocExt(tif, 6 * sizeof(float));
    if (td->td_refblackwhite == NULL)
        return 0;
    if (td->td_photometric == PHOTOMETRIC_YCBCR)
    {
        /*
         * YCbCr (Class Y) images must have the ReferenceBlackWhite
         * tag set. Fix the broken images, which lacks that tag.
         */
        td->td_refblackwhite[0] = 0.0f;
        td->td_refblackwhite[1] = td->td_refblackwhite[3] =
            td->td_refblackwhite[5] = 255.0f;
        td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0f;
    }
    else
    {
        /*
         * Assume RGB (Class R)
         */
        for (i = 0; i < 3; i++)
        {
            td->td_refblackwhite[2 * i + 0] = 0;
            if (td->td_bitspersample < 64)
                td->td_refblackwhite[2 * i + 1] =
                    (float)((1ULL << td->td_bitspersample) - 1ULL);
            else
                td->td_refblackwhite[2 * i + 1] = (float)UINT64_MAX;
        }
    }
    return 1;
}

/*
 * Like TIFFGetField, but return any default
 * value if the tag is not present in the directory.
 *
 * NB:	We use the value in the directory, rather than
 *	explicit values so that defaults exist only one
 *	place in the library -- in TIFFDefaultDirectory.
 */
int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap)
{
    TIFFDirectory *td = &tif->tif_dir;

    if (TIFFVGetField(tif, tag, ap))
        return (1);
    switch (tag)
    {
        case TIFFTAG_SUBFILETYPE:
            *va_arg(ap, uint32_t *) = td->td_subfiletype;
            return (1);
        case TIFFTAG_BITSPERSAMPLE:
            *va_arg(ap, uint16_t *) = td->td_bitspersample;
            return (1);
        case TIFFTAG_THRESHHOLDING:
            *va_arg(ap, uint16_t *) = td->td_threshholding;
            return (1);
        case TIFFTAG_FILLORDER:
            *va_arg(ap, uint16_t *) = td->td_fillorder;
            return (1);
        case TIFFTAG_ORIENTATION:
            *va_arg(ap, uint16_t *) = td->td_orientation;
            return (1);
        case TIFFTAG_SAMPLESPERPIXEL:
            *va_arg(ap, uint16_t *) = td->td_samplesperpixel;
            return (1);
        case TIFFTAG_ROWSPERSTRIP:
            *va_arg(ap, uint32_t *) = td->td_rowsperstrip;
            return (1);
        case TIFFTAG_MINSAMPLEVALUE:
            *va_arg(ap, uint16_t *) = td->td_minsamplevalue;
            return (1);
        case TIFFTAG_MAXSAMPLEVALUE:
        {
            uint16_t maxsamplevalue;
            /* td_bitspersample=1 is always set in TIFFDefaultDirectory().
             * Therefore, td_maxsamplevalue has to be re-calculated in
             * TIFFGetFieldDefaulted(). */
            if (td->td_bitspersample > 0)
            {
                /* This shift operation into a uint16_t limits the value to
                 * 65535 even if td_bitspersamle is > 16 */
                if (td->td_bitspersample <= 16)
                {
                    maxsamplevalue = (uint16_t)((1U << td->td_bitspersample) -
                                                1); /* 2**(BitsPerSample) - 1 */
                }
                else
                {
                    maxsamplevalue = 65535;
                }
            }
            else
            {
                maxsamplevalue = 0;
            }
            *va_arg(ap, uint16_t *) = maxsamplevalue;
            return (1);
        }
        case TIFFTAG_PLANARCONFIG:
            *va_arg(ap, uint16_t *) = td->td_planarconfig;
            return (1);
        case TIFFTAG_RESOLUTIONUNIT:
            *va_arg(ap, uint16_t *) = td->td_resolutionunit;
            return (1);
        case TIFFTAG_PREDICTOR:
        {
            TIFFPredictorState *sp = (TIFFPredictorState *)tif->tif_data;
            if (sp == NULL)
            {
                TIFFErrorExtR(
                    tif, tif->tif_name,
                    "Cannot get \"Predictor\" tag as plugin is not configured");
                *va_arg(ap, uint16_t *) = 0;
                return 0;
            }
            *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor;
            return 1;
        }
        case TIFFTAG_DOTRANGE:
            *va_arg(ap, uint16_t *) = 0;
            if (td->td_bitspersample <= 16)
                *va_arg(ap, uint16_t *) =
                    (uint16_t)((1U << td->td_bitspersample) - 1);
            else
                *va_arg(ap, uint16_t *) = 65535;
            return (1);
        case TIFFTAG_INKSET:
            *va_arg(ap, uint16_t *) = INKSET_CMYK;
            return 1;
        case TIFFTAG_NUMBEROFINKS:
            *va_arg(ap, uint16_t *) = 4;
            return (1);
        case TIFFTAG_EXTRASAMPLES:
            *va_arg(ap, uint16_t *) = td->td_extrasamples;
            *va_arg(ap, const uint16_t **) = td->td_sampleinfo;
            return (1);
        case TIFFTAG_MATTEING:
            *va_arg(ap, uint16_t *) =
                (td->td_extrasamples == 1 && td->td_sampleinfo &&
                 td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
            return (1);
        case TIFFTAG_TILEDEPTH:
            *va_arg(ap, uint32_t *) = td->td_tiledepth;
            return (1);
        case TIFFTAG_DATATYPE:
            *va_arg(ap, uint16_t *) = (uint16_t)(td->td_sampleformat - 1);
            return (1);
        case TIFFTAG_SAMPLEFORMAT:
            *va_arg(ap, uint16_t *) = td->td_sampleformat;
            return (1);
        case TIFFTAG_IMAGEDEPTH:
            *va_arg(ap, uint32_t *) = td->td_imagedepth;
            return (1);
        case TIFFTAG_YCBCRCOEFFICIENTS:
        {
            /* defaults are from CCIR Recommendation 601-1 */
            static const float ycbcrcoeffs[] = {0.299f, 0.587f, 0.114f};
            *va_arg(ap, const float **) = ycbcrcoeffs;
            return 1;
        }
        case TIFFTAG_YCBCRSUBSAMPLING:
            *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0];
            *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1];
            return (1);
        case TIFFTAG_YCBCRPOSITIONING:
            *va_arg(ap, uint16_t *) = td->td_ycbcrpositioning;
            return (1);
        case TIFFTAG_WHITEPOINT:
        {
            /* TIFF 6.0 specification tells that it is no default
               value for the WhitePoint, but AdobePhotoshop TIFF
               Technical Note tells that it should be CIE D50. */
            static const float whitepoint[] = {
                D50_X0 / (D50_X0 + D50_Y0 + D50_Z0),
                D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0)};
            *va_arg(ap, const float **) = whitepoint;
            return 1;
        }
        case TIFFTAG_TRANSFERFUNCTION:
            if (!td->td_transferfunction[0] &&
                !TIFFDefaultTransferFunction(tif, td))
            {
                TIFFErrorExtR(tif, tif->tif_name,
                              "No space for \"TransferFunction\" tag");
                return (0);
            }
            *va_arg(ap, const uint16_t **) = td->td_transferfunction[0];
            if (td->td_samplesperpixel - td->td_extrasamples > 1)
            {
                *va_arg(ap, const uint16_t **) = td->td_transferfunction[1];
                *va_arg(ap, const uint16_t **) = td->td_transferfunction[2];
            }
            return (1);
        case TIFFTAG_REFERENCEBLACKWHITE:
            if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(tif, td))
                return (0);
            *va_arg(ap, const float **) = td->td_refblackwhite;
            return (1);
        default:
            break;
    }
    return 0;
}

/*
 * Like TIFFGetField, but return any default
 * value if the tag is not present in the directory.
 */
int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...)
{
    int ok;
    va_list ap;

    va_start(ap, tag);
    ok = TIFFVGetFieldDefaulted(tif, tag, ap);
    va_end(ap);
    return (ok);
}

float _TIFFClampDoubleToFloat(double val)
{
    if (val > (double)FLT_MAX)
        return FLT_MAX;
    if (val < -(double)FLT_MAX)
        return -FLT_MAX;
    return (float)val;
}

uint32_t _TIFFClampDoubleToUInt32(double val)
{
    if (val < 0)
        return 0;
    if (val > 0xFFFFFFFFU || isnan(val))
        return 0xFFFFFFFFU;
    return (uint32_t)val;
}

int _TIFFSeekOK(TIFF *tif, toff_t off)
{
    /* Huge offsets, especially -1 / UINT64_MAX, can cause issues */
    /* See http://bugzilla.maptools.org/show_bug.cgi?id=2726 */
    return off <= (~(uint64_t)0) / 2 && TIFFSeekFile(tif, off, SEEK_SET) == off;
}
