/*
 * Copyright (c) 1988-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.
 *
 * Predictor Tag Support (used by multiple codecs).
 */
#include "tif_predict.h"
#include "tiffiop.h"

#define PredictorState(tif) ((TIFFPredictorState *)(tif)->tif_data)

static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc);
static int horAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc);
static int horAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc);
static int horAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc);
static int swabHorAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc);
static int swabHorAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc);
static int swabHorAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc);
static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc);
static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc);
static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc);
static int horDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc);
static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc);
static int swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc);
static int swabHorDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc);
static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc);
static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc);
static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0,
                              uint16_t s);
static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0,
                               uint16_t s);
static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0,
                               uint16_t s);

static int PredictorSetup(TIFF *tif)
{
    static const char module[] = "PredictorSetup";

    TIFFPredictorState *sp = PredictorState(tif);
    TIFFDirectory *td = &tif->tif_dir;

    switch (sp->predictor) /* no differencing */
    {
        case PREDICTOR_NONE:
            return 1;
        case PREDICTOR_HORIZONTAL:
            if (td->td_bitspersample != 8 && td->td_bitspersample != 16 &&
                td->td_bitspersample != 32 && td->td_bitspersample != 64)
            {
                TIFFErrorExtR(tif, module,
                              "Horizontal differencing \"Predictor\" not "
                              "supported with %" PRIu16 "-bit samples",
                              td->td_bitspersample);
                return 0;
            }
            break;
        case PREDICTOR_FLOATINGPOINT:
            if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP)
            {
                TIFFErrorExtR(
                    tif, module,
                    "Floating point \"Predictor\" not supported with %" PRIu16
                    " data format",
                    td->td_sampleformat);
                return 0;
            }
            if (td->td_bitspersample != 16 && td->td_bitspersample != 24 &&
                td->td_bitspersample != 32 && td->td_bitspersample != 64)
            { /* Should 64 be allowed? */
                TIFFErrorExtR(
                    tif, module,
                    "Floating point \"Predictor\" not supported with %" PRIu16
                    "-bit samples",
                    td->td_bitspersample);
                return 0;
            }
            break;
        default:
            TIFFErrorExtR(tif, module, "\"Predictor\" value %d not supported",
                          sp->predictor);
            return 0;
    }
    sp->stride =
        (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel
                                                    : 1);
    /*
     * Calculate the scanline/tile-width size in bytes.
     */
    if (isTiled(tif))
        sp->rowsize = TIFFTileRowSize(tif);
    else
        sp->rowsize = TIFFScanlineSize(tif);
    if (sp->rowsize == 0)
        return 0;

    return 1;
}

static int PredictorSetupDecode(TIFF *tif)
{
    TIFFPredictorState *sp = PredictorState(tif);
    TIFFDirectory *td = &tif->tif_dir;

    /* Note: when PredictorSetup() fails, the effets of setupdecode() */
    /* will not be "canceled" so setupdecode() might be robust to */
    /* be called several times. */
    if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
        return 0;

    if (sp->predictor == 2)
    {
        switch (td->td_bitspersample)
        {
            case 8:
                sp->decodepfunc = horAcc8;
                break;
            case 16:
                sp->decodepfunc = horAcc16;
                break;
            case 32:
                sp->decodepfunc = horAcc32;
                break;
            case 64:
                sp->decodepfunc = horAcc64;
                break;
        }
        /*
         * Override default decoding method with one that does the
         * predictor stuff.
         */
        if (tif->tif_decoderow != PredictorDecodeRow)
        {
            sp->decoderow = tif->tif_decoderow;
            tif->tif_decoderow = PredictorDecodeRow;
            sp->decodestrip = tif->tif_decodestrip;
            tif->tif_decodestrip = PredictorDecodeTile;
            sp->decodetile = tif->tif_decodetile;
            tif->tif_decodetile = PredictorDecodeTile;
        }

        /*
         * If the data is horizontally differenced 16-bit data that
         * requires byte-swapping, then it must be byte swapped before
         * the accumulation step.  We do this with a special-purpose
         * routine and override the normal post decoding logic that
         * the library setup when the directory was read.
         */
        if (tif->tif_flags & TIFF_SWAB)
        {
            if (sp->decodepfunc == horAcc16)
            {
                sp->decodepfunc = swabHorAcc16;
                tif->tif_postdecode = _TIFFNoPostDecode;
            }
            else if (sp->decodepfunc == horAcc32)
            {
                sp->decodepfunc = swabHorAcc32;
                tif->tif_postdecode = _TIFFNoPostDecode;
            }
            else if (sp->decodepfunc == horAcc64)
            {
                sp->decodepfunc = swabHorAcc64;
                tif->tif_postdecode = _TIFFNoPostDecode;
            }
        }
    }

    else if (sp->predictor == 3)
    {
        sp->decodepfunc = fpAcc;
        /*
         * Override default decoding method with one that does the
         * predictor stuff.
         */
        if (tif->tif_decoderow != PredictorDecodeRow)
        {
            sp->decoderow = tif->tif_decoderow;
            tif->tif_decoderow = PredictorDecodeRow;
            sp->decodestrip = tif->tif_decodestrip;
            tif->tif_decodestrip = PredictorDecodeTile;
            sp->decodetile = tif->tif_decodetile;
            tif->tif_decodetile = PredictorDecodeTile;
        }
        /*
         * The data should not be swapped outside of the floating
         * point predictor, the accumulation routine should return
         * byres in the native order.
         */
        if (tif->tif_flags & TIFF_SWAB)
        {
            tif->tif_postdecode = _TIFFNoPostDecode;
        }
        /*
         * Allocate buffer to keep the decoded bytes before
         * rearranging in the right order
         */
    }

    return 1;
}

static int PredictorSetupEncode(TIFF *tif)
{
    TIFFPredictorState *sp = PredictorState(tif);
    TIFFDirectory *td = &tif->tif_dir;

    if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
        return 0;

    if (sp->predictor == 2)
    {
        switch (td->td_bitspersample)
        {
            case 8:
                sp->encodepfunc = horDiff8;
                break;
            case 16:
                sp->encodepfunc = horDiff16;
                break;
            case 32:
                sp->encodepfunc = horDiff32;
                break;
            case 64:
                sp->encodepfunc = horDiff64;
                break;
        }
        /*
         * Override default encoding method with one that does the
         * predictor stuff.
         */
        if (tif->tif_encoderow != PredictorEncodeRow)
        {
            sp->encoderow = tif->tif_encoderow;
            tif->tif_encoderow = PredictorEncodeRow;
            sp->encodestrip = tif->tif_encodestrip;
            tif->tif_encodestrip = PredictorEncodeTile;
            sp->encodetile = tif->tif_encodetile;
            tif->tif_encodetile = PredictorEncodeTile;
        }

        /*
         * If the data is horizontally differenced 16-bit data that
         * requires byte-swapping, then it must be byte swapped after
         * the differentiation step.  We do this with a special-purpose
         * routine and override the normal post decoding logic that
         * the library setup when the directory was read.
         */
        if (tif->tif_flags & TIFF_SWAB)
        {
            if (sp->encodepfunc == horDiff16)
            {
                sp->encodepfunc = swabHorDiff16;
                tif->tif_postdecode = _TIFFNoPostDecode;
            }
            else if (sp->encodepfunc == horDiff32)
            {
                sp->encodepfunc = swabHorDiff32;
                tif->tif_postdecode = _TIFFNoPostDecode;
            }
            else if (sp->encodepfunc == horDiff64)
            {
                sp->encodepfunc = swabHorDiff64;
                tif->tif_postdecode = _TIFFNoPostDecode;
            }
        }
    }

    else if (sp->predictor == 3)
    {
        sp->encodepfunc = fpDiff;
        /*
         * Override default encoding method with one that does the
         * predictor stuff.
         */
        if (tif->tif_encoderow != PredictorEncodeRow)
        {
            sp->encoderow = tif->tif_encoderow;
            tif->tif_encoderow = PredictorEncodeRow;
            sp->encodestrip = tif->tif_encodestrip;
            tif->tif_encodestrip = PredictorEncodeTile;
            sp->encodetile = tif->tif_encodetile;
            tif->tif_encodetile = PredictorEncodeTile;
        }
    }

    return 1;
}

#define REPEAT4(n, op)                                                         \
    switch (n)                                                                 \
    {                                                                          \
        default:                                                               \
        {                                                                      \
            tmsize_t i;                                                        \
            for (i = n - 4; i > 0; i--)                                        \
            {                                                                  \
                op;                                                            \
            }                                                                  \
        } /*-fallthrough*/                                                     \
        case 4:                                                                \
            op; /*-fallthrough*/                                               \
        case 3:                                                                \
            op; /*-fallthrough*/                                               \
        case 2:                                                                \
            op; /*-fallthrough*/                                               \
        case 1:                                                                \
            op; /*-fallthrough*/                                               \
        case 0:;                                                               \
    }

/* Remarks related to C standard compliance in all below functions : */
/* - to avoid any undefined behavior, we only operate on unsigned types */
/*   since the behavior of "overflows" is defined (wrap over) */
/* - when storing into the byte stream, we explicitly mask with 0xff so */
/*   as to make icc -check=conversions happy (not necessary by the standard) */

TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
    tmsize_t stride = PredictorState(tif)->stride;

    unsigned char *cp = (unsigned char *)cp0;
    if ((cc % stride) != 0)
    {
        TIFFErrorExtR(tif, "horAcc8", "%s", "(cc%stride)!=0");
        return 0;
    }

    if (cc > stride)
    {
        /*
         * Pipeline the most common cases.
         */
        if (stride == 3)
        {
            unsigned int cr = cp[0];
            unsigned int cg = cp[1];
            unsigned int cb = cp[2];
            tmsize_t i = stride;
            for (; i < cc; i += stride)
            {
                cp[i + 0] = (unsigned char)((cr += cp[i + 0]) & 0xff);
                cp[i + 1] = (unsigned char)((cg += cp[i + 1]) & 0xff);
                cp[i + 2] = (unsigned char)((cb += cp[i + 2]) & 0xff);
            }
        }
        else if (stride == 4)
        {
            unsigned int cr = cp[0];
            unsigned int cg = cp[1];
            unsigned int cb = cp[2];
            unsigned int ca = cp[3];
            tmsize_t i = stride;
            for (; i < cc; i += stride)
            {
                cp[i + 0] = (unsigned char)((cr += cp[i + 0]) & 0xff);
                cp[i + 1] = (unsigned char)((cg += cp[i + 1]) & 0xff);
                cp[i + 2] = (unsigned char)((cb += cp[i + 2]) & 0xff);
                cp[i + 3] = (unsigned char)((ca += cp[i + 3]) & 0xff);
            }
        }
        else
        {
            cc -= stride;
            do
            {
                REPEAT4(stride,
                        cp[stride] = (unsigned char)((cp[stride] + *cp) & 0xff);
                        cp++)
                cc -= stride;
            } while (cc > 0);
        }
    }
    return 1;
}

static int swabHorAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
    uint16_t *wp = (uint16_t *)cp0;
    tmsize_t wc = cc / 2;

    TIFFSwabArrayOfShort(wp, wc);
    return horAcc16(tif, cp0, cc);
}

TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int horAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
    tmsize_t stride = PredictorState(tif)->stride;
    uint16_t *wp = (uint16_t *)cp0;
    tmsize_t wc = cc / 2;

    if ((cc % (2 * stride)) != 0)
    {
        TIFFErrorExtR(tif, "horAcc16", "%s", "cc%(2*stride))!=0");
        return 0;
    }

    if (wc > stride)
    {
        wc -= stride;
        do
        {
            REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] +
                                                     (unsigned int)wp[0]) &
                                                    0xffff);
                    wp++)
            wc -= stride;
        } while (wc > 0);
    }
    return 1;
}

static int swabHorAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
    uint32_t *wp = (uint32_t *)cp0;
    tmsize_t wc = cc / 4;

    TIFFSwabArrayOfLong(wp, wc);
    return horAcc32(tif, cp0, cc);
}

TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int horAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
    tmsize_t stride = PredictorState(tif)->stride;
    uint32_t *wp = (uint32_t *)cp0;
    tmsize_t wc = cc / 4;

    if ((cc % (4 * stride)) != 0)
    {
        TIFFErrorExtR(tif, "horAcc32", "%s", "cc%(4*stride))!=0");
        return 0;
    }

    if (wc > stride)
    {
        wc -= stride;
        do
        {
            REPEAT4(stride, wp[stride] += wp[0]; wp++)
            wc -= stride;
        } while (wc > 0);
    }
    return 1;
}

static int swabHorAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
    uint64_t *wp = (uint64_t *)cp0;
    tmsize_t wc = cc / 8;

    TIFFSwabArrayOfLong8(wp, wc);
    return horAcc64(tif, cp0, cc);
}

TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int horAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
    tmsize_t stride = PredictorState(tif)->stride;
    uint64_t *wp = (uint64_t *)cp0;
    tmsize_t wc = cc / 8;

    if ((cc % (8 * stride)) != 0)
    {
        TIFFErrorExtR(tif, "horAcc64", "%s", "cc%(8*stride))!=0");
        return 0;
    }

    if (wc > stride)
    {
        wc -= stride;
        do
        {
            REPEAT4(stride, wp[stride] += wp[0]; wp++)
            wc -= stride;
        } while (wc > 0);
    }
    return 1;
}

/*
 * Floating point predictor accumulation routine.
 */
static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
    tmsize_t stride = PredictorState(tif)->stride;
    uint32_t bps = tif->tif_dir.td_bitspersample / 8;
    tmsize_t wc = cc / bps;
    tmsize_t count = cc;
    uint8_t *cp = (uint8_t *)cp0;
    uint8_t *tmp;

    if (cc % (bps * stride) != 0)
    {
        TIFFErrorExtR(tif, "fpAcc", "%s", "cc%(bps*stride))!=0");
        return 0;
    }

    tmp = (uint8_t *)_TIFFmallocExt(tif, cc);
    if (!tmp)
        return 0;

    while (count > stride)
    {
        REPEAT4(stride,
                cp[stride] = (unsigned char)((cp[stride] + cp[0]) & 0xff);
                cp++)
        count -= stride;
    }

    _TIFFmemcpy(tmp, cp0, cc);
    cp = (uint8_t *)cp0;
    for (count = 0; count < wc; count++)
    {
        uint32_t byte;
        for (byte = 0; byte < bps; byte++)
        {
#if WORDS_BIGENDIAN
            cp[bps * count + byte] = tmp[byte * wc + count];
#else
            cp[bps * count + byte] = tmp[(bps - byte - 1) * wc + count];
#endif
        }
    }
    _TIFFfreeExt(tif, tmp);
    return 1;
}

/*
 * Decode a scanline and apply the predictor routine.
 */
static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0,
                              uint16_t s)
{
    TIFFPredictorState *sp = PredictorState(tif);

    assert(sp != NULL);
    assert(sp->decoderow != NULL);
    assert(sp->decodepfunc != NULL);

    if ((*sp->decoderow)(tif, op0, occ0, s))
    {
        return (*sp->decodepfunc)(tif, op0, occ0);
    }
    else
        return 0;
}

/*
 * Decode a tile/strip and apply the predictor routine.
 * Note that horizontal differencing must be done on a
 * row-by-row basis.  The width of a "row" has already
 * been calculated at pre-decode time according to the
 * strip/tile dimensions.
 */
static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0,
                               uint16_t s)
{
    TIFFPredictorState *sp = PredictorState(tif);

    assert(sp != NULL);
    assert(sp->decodetile != NULL);

    if ((*sp->decodetile)(tif, op0, occ0, s))
    {
        tmsize_t rowsize = sp->rowsize;
        assert(rowsize > 0);
        if ((occ0 % rowsize) != 0)
        {
            TIFFErrorExtR(tif, "PredictorDecodeTile", "%s",
                          "occ0%rowsize != 0");
            return 0;
        }
        assert(sp->decodepfunc != NULL);
        while (occ0 > 0)
        {
            if (!(*sp->decodepfunc)(tif, op0, rowsize))
                return 0;
            occ0 -= rowsize;
            op0 += rowsize;
        }
        return 1;
    }
    else
        return 0;
}

TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
    TIFFPredictorState *sp = PredictorState(tif);
    tmsize_t stride = sp->stride;
    unsigned char *cp = (unsigned char *)cp0;

    if ((cc % stride) != 0)
    {
        TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%stride)!=0");
        return 0;
    }

    if (cc > stride)
    {
        cc -= stride;
        /*
         * Pipeline the most common cases.
         */
        if (stride == 3)
        {
            unsigned int r1, g1, b1;
            unsigned int r2 = cp[0];
            unsigned int g2 = cp[1];
            unsigned int b2 = cp[2];
            do
            {
                r1 = cp[3];
                cp[3] = (unsigned char)((r1 - r2) & 0xff);
                r2 = r1;
                g1 = cp[4];
                cp[4] = (unsigned char)((g1 - g2) & 0xff);
                g2 = g1;
                b1 = cp[5];
                cp[5] = (unsigned char)((b1 - b2) & 0xff);
                b2 = b1;
                cp += 3;
            } while ((cc -= 3) > 0);
        }
        else if (stride == 4)
        {
            unsigned int r1, g1, b1, a1;
            unsigned int r2 = cp[0];
            unsigned int g2 = cp[1];
            unsigned int b2 = cp[2];
            unsigned int a2 = cp[3];
            do
            {
                r1 = cp[4];
                cp[4] = (unsigned char)((r1 - r2) & 0xff);
                r2 = r1;
                g1 = cp[5];
                cp[5] = (unsigned char)((g1 - g2) & 0xff);
                g2 = g1;
                b1 = cp[6];
                cp[6] = (unsigned char)((b1 - b2) & 0xff);
                b2 = b1;
                a1 = cp[7];
                cp[7] = (unsigned char)((a1 - a2) & 0xff);
                a2 = a1;
                cp += 4;
            } while ((cc -= 4) > 0);
        }
        else
        {
            cp += cc - 1;
            do
            {
                REPEAT4(stride,
                        cp[stride] =
                            (unsigned char)((cp[stride] - cp[0]) & 0xff);
                        cp--)
            } while ((cc -= stride) > 0);
        }
    }
    return 1;
}

TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
    TIFFPredictorState *sp = PredictorState(tif);
    tmsize_t stride = sp->stride;
    uint16_t *wp = (uint16_t *)cp0;
    tmsize_t wc = cc / 2;

    if ((cc % (2 * stride)) != 0)
    {
        TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%(2*stride))!=0");
        return 0;
    }

    if (wc > stride)
    {
        wc -= stride;
        wp += wc - 1;
        do
        {
            REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] -
                                                     (unsigned int)wp[0]) &
                                                    0xffff);
                    wp--)
            wc -= stride;
        } while (wc > 0);
    }
    return 1;
}

static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
    uint16_t *wp = (uint16_t *)cp0;
    tmsize_t wc = cc / 2;

    if (!horDiff16(tif, cp0, cc))
        return 0;

    TIFFSwabArrayOfShort(wp, wc);
    return 1;
}

TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
    TIFFPredictorState *sp = PredictorState(tif);
    tmsize_t stride = sp->stride;
    uint32_t *wp = (uint32_t *)cp0;
    tmsize_t wc = cc / 4;

    if ((cc % (4 * stride)) != 0)
    {
        TIFFErrorExtR(tif, "horDiff32", "%s", "(cc%(4*stride))!=0");
        return 0;
    }

    if (wc > stride)
    {
        wc -= stride;
        wp += wc - 1;
        do
        {
            REPEAT4(stride, wp[stride] -= wp[0]; wp--)
            wc -= stride;
        } while (wc > 0);
    }
    return 1;
}

static int swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
    uint32_t *wp = (uint32_t *)cp0;
    tmsize_t wc = cc / 4;

    if (!horDiff32(tif, cp0, cc))
        return 0;

    TIFFSwabArrayOfLong(wp, wc);
    return 1;
}

TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int horDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
    TIFFPredictorState *sp = PredictorState(tif);
    tmsize_t stride = sp->stride;
    uint64_t *wp = (uint64_t *)cp0;
    tmsize_t wc = cc / 8;

    if ((cc % (8 * stride)) != 0)
    {
        TIFFErrorExtR(tif, "horDiff64", "%s", "(cc%(8*stride))!=0");
        return 0;
    }

    if (wc > stride)
    {
        wc -= stride;
        wp += wc - 1;
        do
        {
            REPEAT4(stride, wp[stride] -= wp[0]; wp--)
            wc -= stride;
        } while (wc > 0);
    }
    return 1;
}

static int swabHorDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
    uint64_t *wp = (uint64_t *)cp0;
    tmsize_t wc = cc / 8;

    if (!horDiff64(tif, cp0, cc))
        return 0;

    TIFFSwabArrayOfLong8(wp, wc);
    return 1;
}

/*
 * Floating point predictor differencing routine.
 */
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
    tmsize_t stride = PredictorState(tif)->stride;
    uint32_t bps = tif->tif_dir.td_bitspersample / 8;
    tmsize_t wc = cc / bps;
    tmsize_t count;
    uint8_t *cp = (uint8_t *)cp0;
    uint8_t *tmp;

    if ((cc % (bps * stride)) != 0)
    {
        TIFFErrorExtR(tif, "fpDiff", "%s", "(cc%(bps*stride))!=0");
        return 0;
    }

    tmp = (uint8_t *)_TIFFmallocExt(tif, cc);
    if (!tmp)
        return 0;

    _TIFFmemcpy(tmp, cp0, cc);
    for (count = 0; count < wc; count++)
    {
        uint32_t byte;
        for (byte = 0; byte < bps; byte++)
        {
#if WORDS_BIGENDIAN
            cp[byte * wc + count] = tmp[bps * count + byte];
#else
            cp[(bps - byte - 1) * wc + count] = tmp[bps * count + byte];
#endif
        }
    }
    _TIFFfreeExt(tif, tmp);

    cp = (uint8_t *)cp0;
    cp += cc - stride - 1;
    for (count = cc; count > stride; count -= stride)
        REPEAT4(stride,
                cp[stride] = (unsigned char)((cp[stride] - cp[0]) & 0xff);
                cp--)
    return 1;
}

static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
{
    TIFFPredictorState *sp = PredictorState(tif);

    assert(sp != NULL);
    assert(sp->encodepfunc != NULL);
    assert(sp->encoderow != NULL);

    /* XXX horizontal differencing alters user's data XXX */
    if (!(*sp->encodepfunc)(tif, bp, cc))
        return 0;
    return (*sp->encoderow)(tif, bp, cc, s);
}

static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0,
                               uint16_t s)
{
    static const char module[] = "PredictorEncodeTile";
    TIFFPredictorState *sp = PredictorState(tif);
    uint8_t *working_copy;
    tmsize_t cc = cc0, rowsize;
    unsigned char *bp;
    int result_code;

    assert(sp != NULL);
    assert(sp->encodepfunc != NULL);
    assert(sp->encodetile != NULL);

    /*
     * Do predictor manipulation in a working buffer to avoid altering
     * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
     */
    working_copy = (uint8_t *)_TIFFmallocExt(tif, cc0);
    if (working_copy == NULL)
    {
        TIFFErrorExtR(tif, module,
                      "Out of memory allocating %" PRId64 " byte temp buffer.",
                      (int64_t)cc0);
        return 0;
    }
    memcpy(working_copy, bp0, cc0);
    bp = working_copy;

    rowsize = sp->rowsize;
    assert(rowsize > 0);
    if ((cc0 % rowsize) != 0)
    {
        TIFFErrorExtR(tif, "PredictorEncodeTile", "%s", "(cc0%rowsize)!=0");
        _TIFFfreeExt(tif, working_copy);
        return 0;
    }
    while (cc > 0)
    {
        (*sp->encodepfunc)(tif, bp, rowsize);
        cc -= rowsize;
        bp += rowsize;
    }
    result_code = (*sp->encodetile)(tif, working_copy, cc0, s);

    _TIFFfreeExt(tif, working_copy);

    return result_code;
}

#define FIELD_PREDICTOR (FIELD_CODEC + 0) /* XXX */

static const TIFFField predictFields[] = {
    {TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
     TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL},
};

static int PredictorVSetField(TIFF *tif, uint32_t tag, va_list ap)
{
    TIFFPredictorState *sp = PredictorState(tif);

    assert(sp != NULL);
    assert(sp->vsetparent != NULL);

    switch (tag)
    {
        case TIFFTAG_PREDICTOR:
            sp->predictor = (uint16_t)va_arg(ap, uint16_vap);
            TIFFSetFieldBit(tif, FIELD_PREDICTOR);
            break;
        default:
            return (*sp->vsetparent)(tif, tag, ap);
    }
    tif->tif_flags |= TIFF_DIRTYDIRECT;
    return 1;
}

static int PredictorVGetField(TIFF *tif, uint32_t tag, va_list ap)
{
    TIFFPredictorState *sp = PredictorState(tif);

    assert(sp != NULL);
    assert(sp->vgetparent != NULL);

    switch (tag)
    {
        case TIFFTAG_PREDICTOR:
            *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor;
            break;
        default:
            return (*sp->vgetparent)(tif, tag, ap);
    }
    return 1;
}

static void PredictorPrintDir(TIFF *tif, FILE *fd, long flags)
{
    TIFFPredictorState *sp = PredictorState(tif);

    (void)flags;
    if (TIFFFieldSet(tif, FIELD_PREDICTOR))
    {
        fprintf(fd, "  Predictor: ");
        switch (sp->predictor)
        {
            case 1:
                fprintf(fd, "none ");
                break;
            case 2:
                fprintf(fd, "horizontal differencing ");
                break;
            case 3:
                fprintf(fd, "floating point predictor ");
                break;
        }
        fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor);
    }
    if (sp->printdir)
        (*sp->printdir)(tif, fd, flags);
}

int TIFFPredictorInit(TIFF *tif)
{
    TIFFPredictorState *sp = PredictorState(tif);

    assert(sp != 0);

    /*
     * Merge codec-specific tag information.
     */
    if (!_TIFFMergeFields(tif, predictFields, TIFFArrayCount(predictFields)))
    {
        TIFFErrorExtR(tif, "TIFFPredictorInit",
                      "Merging Predictor codec-specific tags failed");
        return 0;
    }

    /*
     * Override parent get/set field methods.
     */
    sp->vgetparent = tif->tif_tagmethods.vgetfield;
    tif->tif_tagmethods.vgetfield =
        PredictorVGetField; /* hook for predictor tag */
    sp->vsetparent = tif->tif_tagmethods.vsetfield;
    tif->tif_tagmethods.vsetfield =
        PredictorVSetField; /* hook for predictor tag */
    sp->printdir = tif->tif_tagmethods.printdir;
    tif->tif_tagmethods.printdir =
        PredictorPrintDir; /* hook for predictor tag */

    sp->setupdecode = tif->tif_setupdecode;
    tif->tif_setupdecode = PredictorSetupDecode;
    sp->setupencode = tif->tif_setupencode;
    tif->tif_setupencode = PredictorSetupEncode;

    sp->predictor = 1;      /* default value */
    sp->encodepfunc = NULL; /* no predictor routine */
    sp->decodepfunc = NULL; /* no predictor routine */
    return 1;
}

int TIFFPredictorCleanup(TIFF *tif)
{
    TIFFPredictorState *sp = PredictorState(tif);

    assert(sp != 0);

    tif->tif_tagmethods.vgetfield = sp->vgetparent;
    tif->tif_tagmethods.vsetfield = sp->vsetparent;
    tif->tif_tagmethods.printdir = sp->printdir;
    tif->tif_setupdecode = sp->setupdecode;
    tif->tif_setupencode = sp->setupencode;

    return 1;
}
