/*
 * 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.
 *
 * Strip-organized Image Support Routines.
 */
#include "tiffiop.h"

/*
 * Compute which strip a (row,sample) value is in.
 */
uint32_t TIFFComputeStrip(TIFF *tif, uint32_t row, uint16_t sample)
{
    static const char module[] = "TIFFComputeStrip";
    TIFFDirectory *td = &tif->tif_dir;
    uint32_t strip;

    if (td->td_rowsperstrip == 0)
    {
        TIFFErrorExtR(tif, module, "Cannot compute strip: RowsPerStrip is zero");
        return 0;
    }
    strip = row / td->td_rowsperstrip;
    if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
    {
        if (sample >= td->td_samplesperpixel)
        {
            TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu",
                          (unsigned long)sample,
                          (unsigned long)td->td_samplesperpixel);
            return (0);
        }
        strip += (uint32_t)sample * td->td_stripsperimage;
    }
    return (strip);
}

/*
 * Compute how many strips are in an image.
 */
uint32_t TIFFNumberOfStrips(TIFF *tif)
{
    TIFFDirectory *td = &tif->tif_dir;
    uint32_t nstrips;

    if (td->td_rowsperstrip == 0)
    {
        TIFFWarningExtR(tif, "TIFFNumberOfStrips", "RowsPerStrip is zero");
        return 0;
    }
    nstrips = (td->td_rowsperstrip == (uint32_t)-1
                   ? 1
                   : TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip));
    if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
        nstrips =
            _TIFFMultiply32(tif, nstrips, (uint32_t)td->td_samplesperpixel,
                            "TIFFNumberOfStrips");
    return (nstrips);
}

/*
 * Compute the # bytes in a variable height, row-aligned strip.
 */
uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows)
{
    static const char module[] = "TIFFVStripSize64";
    TIFFDirectory *td = &tif->tif_dir;
    if (nrows == (uint32_t)(-1))
        nrows = td->td_imagelength;
    if ((td->td_planarconfig == PLANARCONFIG_CONTIG) &&
        (td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif)))
    {
        /*
         * Packed YCbCr data contain one Cb+Cr for every
         * HorizontalSampling*VerticalSampling Y values.
         * Must also roundup width and height when calculating
         * since images that are not a multiple of the
         * horizontal/vertical subsampling area include
         * YCbCr data for the extended image.
         */
        uint16_t ycbcrsubsampling[2];
        uint16_t samplingblock_samples;
        uint32_t samplingblocks_hor;
        uint32_t samplingblocks_ver;
        uint64_t samplingrow_samples;
        uint64_t samplingrow_size;
        if (td->td_samplesperpixel != 3)
        {
            TIFFErrorExtR(tif, module, "Invalid td_samplesperpixel value");
            return 0;
        }
        TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
                              ycbcrsubsampling + 0, ycbcrsubsampling + 1);
        if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 &&
             ycbcrsubsampling[0] != 4) ||
            (ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 &&
             ycbcrsubsampling[1] != 4) ||
            (ycbcrsubsampling[0] == 0 || ycbcrsubsampling[1] == 0))
        {
            TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling (%dx%d)",
                          ycbcrsubsampling[0], ycbcrsubsampling[1]);
            return 0;
        }
        samplingblock_samples = ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2;
        samplingblocks_hor =
            TIFFhowmany_32(td->td_imagewidth, ycbcrsubsampling[0]);
        samplingblocks_ver = TIFFhowmany_32(nrows, ycbcrsubsampling[1]);
        samplingrow_samples = _TIFFMultiply64(tif, samplingblocks_hor,
                                              samplingblock_samples, module);
        samplingrow_size = TIFFhowmany8_64(_TIFFMultiply64(
            tif, samplingrow_samples, td->td_bitspersample, module));
        return (
            _TIFFMultiply64(tif, samplingrow_size, samplingblocks_ver, module));
    }
    else
        return (_TIFFMultiply64(tif, nrows, TIFFScanlineSize64(tif), module));
}
tmsize_t TIFFVStripSize(TIFF *tif, uint32_t nrows)
{
    static const char module[] = "TIFFVStripSize";
    uint64_t m;
    m = TIFFVStripSize64(tif, nrows);
    return _TIFFCastUInt64ToSSize(tif, m, module);
}

/*
 * Compute the # bytes in a raw strip.
 */
uint64_t TIFFRawStripSize64(TIFF *tif, uint32_t strip)
{
    static const char module[] = "TIFFRawStripSize64";
    uint64_t bytecount = TIFFGetStrileByteCount(tif, strip);

    if (bytecount == 0)
    {
        TIFFErrorExtR(tif, module,
                      "%" PRIu64 ": Invalid strip byte count, strip %lu",
                      (uint64_t)bytecount, (unsigned long)strip);
        bytecount = (uint64_t)-1;
    }

    return bytecount;
}
tmsize_t TIFFRawStripSize(TIFF *tif, uint32_t strip)
{
    static const char module[] = "TIFFRawStripSize";
    uint64_t m;
    tmsize_t n;
    m = TIFFRawStripSize64(tif, strip);
    if (m == (uint64_t)(-1))
        n = (tmsize_t)(-1);
    else
    {
        n = (tmsize_t)m;
        if ((uint64_t)n != m)
        {
            TIFFErrorExtR(tif, module, "Integer overflow");
            n = 0;
        }
    }
    return (n);
}

/*
 * Compute the # bytes in a (row-aligned) strip.
 *
 * Note that if RowsPerStrip is larger than the
 * recorded ImageLength, then the strip size is
 * truncated to reflect the actual space required
 * to hold the strip.
 */
uint64_t TIFFStripSize64(TIFF *tif)
{
    TIFFDirectory *td = &tif->tif_dir;
    uint32_t rps = td->td_rowsperstrip;
    if (rps > td->td_imagelength)
        rps = td->td_imagelength;
    return (TIFFVStripSize64(tif, rps));
}
tmsize_t TIFFStripSize(TIFF *tif)
{
    static const char module[] = "TIFFStripSize";
    uint64_t m;
    m = TIFFStripSize64(tif);
    return _TIFFCastUInt64ToSSize(tif, m, module);
}

/*
 * Compute a default strip size based on the image
 * characteristics and a requested value.  If the
 * request is <1 then we choose a strip size according
 * to certain heuristics.
 */
uint32_t TIFFDefaultStripSize(TIFF *tif, uint32_t request)
{
    return (*tif->tif_defstripsize)(tif, request);
}

uint32_t _TIFFDefaultStripSize(TIFF *tif, uint32_t s)
{
    if ((int32_t)s < 1)
    {
        /*
         * If RowsPerStrip is unspecified, try to break the
         * image up into strips that are approximately
         * STRIP_SIZE_DEFAULT bytes long.
         */
        uint64_t scanlinesize;
        uint64_t rows;
        scanlinesize = TIFFScanlineSize64(tif);
        if (scanlinesize == 0)
            scanlinesize = 1;
        rows = (uint64_t)STRIP_SIZE_DEFAULT / scanlinesize;
        if (rows == 0)
            rows = 1;
        else if (rows > 0xFFFFFFFF)
            rows = 0xFFFFFFFF;
        s = (uint32_t)rows;
    }
    return (s);
}

/*
 * Return the number of bytes to read/write in a call to
 * one of the scanline-oriented i/o routines.  Note that
 * this number may be 1/samples-per-pixel if data is
 * stored as separate planes.
 * The ScanlineSize in case of YCbCrSubsampling is defined as the
 * strip size divided by the strip height, i.e. the size of a pack of vertical
 * subsampling lines divided by vertical subsampling. It should thus make
 * sense when multiplied by a multiple of vertical subsampling.
 */
uint64_t TIFFScanlineSize64(TIFF *tif)
{
    static const char module[] = "TIFFScanlineSize64";
    TIFFDirectory *td = &tif->tif_dir;
    uint64_t scanline_size;
    if (td->td_planarconfig == PLANARCONFIG_CONTIG)
    {
        if ((td->td_photometric == PHOTOMETRIC_YCBCR) &&
            (td->td_samplesperpixel == 3) && (!isUpSampled(tif)))
        {
            uint16_t ycbcrsubsampling[2];
            uint16_t samplingblock_samples;
            uint32_t samplingblocks_hor;
            uint64_t samplingrow_samples;
            uint64_t samplingrow_size;
            if (td->td_samplesperpixel != 3)
            {
                TIFFErrorExtR(tif, module, "Invalid td_samplesperpixel value");
                return 0;
            }
            TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
                                  ycbcrsubsampling + 0, ycbcrsubsampling + 1);
            if (((ycbcrsubsampling[0] != 1) && (ycbcrsubsampling[0] != 2) &&
                 (ycbcrsubsampling[0] != 4)) ||
                ((ycbcrsubsampling[1] != 1) && (ycbcrsubsampling[1] != 2) &&
                 (ycbcrsubsampling[1] != 4)) ||
                ((ycbcrsubsampling[0] == 0) || (ycbcrsubsampling[1] == 0)))
            {
                TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling");
                return 0;
            }
            samplingblock_samples =
                ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2;
            samplingblocks_hor =
                TIFFhowmany_32(td->td_imagewidth, ycbcrsubsampling[0]);
            samplingrow_samples = _TIFFMultiply64(
                tif, samplingblocks_hor, samplingblock_samples, module);
            samplingrow_size =
                TIFFhowmany_64(_TIFFMultiply64(tif, samplingrow_samples,
                                               td->td_bitspersample, module),
                               8);
            scanline_size = (samplingrow_size / ycbcrsubsampling[1]);
        }
        else
        {
            uint64_t scanline_samples;
            uint32_t scanline_width = td->td_imagewidth;

#if 0
            // Tries to fix https://gitlab.com/libtiff/libtiff/-/merge_requests/564
            // but causes regression when decoding legit files with tiffcp -c none
            // Cf https://gitlab.com/libtiff/libtiff/-/merge_requests/644
            if (td->td_photometric == PHOTOMETRIC_YCBCR)
            {
                uint16_t subsampling_hor;
                uint16_t ignored;
                TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
                                      &subsampling_hor, &ignored);
                if (subsampling_hor > 1) // roundup width for YCbCr
                    scanline_width =
                        TIFFroundup_32(scanline_width, subsampling_hor);
            }
#endif

            scanline_samples = _TIFFMultiply64(tif, scanline_width,
                                               td->td_samplesperpixel, module);
            scanline_size =
                TIFFhowmany_64(_TIFFMultiply64(tif, scanline_samples,
                                               td->td_bitspersample, module),
                               8);
        }
    }
    else
    {
        scanline_size =
            TIFFhowmany_64(_TIFFMultiply64(tif, td->td_imagewidth,
                                           td->td_bitspersample, module),
                           8);
    }
    if (scanline_size == 0)
    {
        TIFFErrorExtR(tif, module, "Computed scanline size is zero");
        return 0;
    }
    return (scanline_size);
}
tmsize_t TIFFScanlineSize(TIFF *tif)
{
    static const char module[] = "TIFFScanlineSize";
    uint64_t m;
    m = TIFFScanlineSize64(tif);
    return _TIFFCastUInt64ToSSize(tif, m, module);
}

/*
 * Return the number of bytes required to store a complete
 * decoded and packed raster scanline (as opposed to the
 * I/O size returned by TIFFScanlineSize which may be less
 * if data is store as separate planes).
 */
uint64_t TIFFRasterScanlineSize64(TIFF *tif)
{
    static const char module[] = "TIFFRasterScanlineSize64";
    TIFFDirectory *td = &tif->tif_dir;
    uint64_t scanline;

    scanline =
        _TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module);
    if (td->td_planarconfig == PLANARCONFIG_CONTIG)
    {
        scanline =
            _TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module);
        return (TIFFhowmany8_64(scanline));
    }
    else
        return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline),
                                td->td_samplesperpixel, module));
}
tmsize_t TIFFRasterScanlineSize(TIFF *tif)
{
    static const char module[] = "TIFFRasterScanlineSize";
    uint64_t m;
    m = TIFFRasterScanlineSize64(tif);
    return _TIFFCastUInt64ToSSize(tif, m, module);
}
