LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_predict.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 480 608 78.9 %
Date: 2026-08-22 15:37:05 Functions: 28 34 82.4 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 1988-1997 Sam Leffler
       3             :  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
       4             :  *
       5             :  * Permission to use, copy, modify, distribute, and sell this software and
       6             :  * its documentation for any purpose is hereby granted without fee, provided
       7             :  * that (i) the above copyright notices and this permission notice appear in
       8             :  * all copies of the software and related documentation, and (ii) the names of
       9             :  * Sam Leffler and Silicon Graphics may not be used in any advertising or
      10             :  * publicity relating to the software without the specific, prior written
      11             :  * permission of Sam Leffler and Silicon Graphics.
      12             :  *
      13             :  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
      14             :  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
      15             :  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
      16             :  *
      17             :  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
      18             :  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
      19             :  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
      20             :  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
      21             :  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
      22             :  * OF THIS SOFTWARE.
      23             :  */
      24             : 
      25             : /*
      26             :  * TIFF Library.
      27             :  *
      28             :  * Predictor Tag Support (used by multiple codecs).
      29             :  */
      30             : #include "tif_predict.h"
      31             : #include "tiffiop.h"
      32             : 
      33             : #if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC))
      34             : #include <emmintrin.h>
      35             : #endif
      36             : 
      37             : #define PredictorState(tif) ((TIFFPredictorState *)(tif)->tif_data)
      38             : 
      39             : static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc);
      40             : static int horAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc);
      41             : static int horAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc);
      42             : static int horAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc);
      43             : static int swabHorAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc);
      44             : static int swabHorAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc);
      45             : static int swabHorAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc);
      46             : static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc);
      47             : static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc);
      48             : static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc);
      49             : static int horDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc);
      50             : static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc);
      51             : static int swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc);
      52             : static int swabHorDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc);
      53             : static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc);
      54             : static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc);
      55             : static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0,
      56             :                               uint16_t s);
      57             : static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0,
      58             :                                uint16_t s);
      59             : static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
      60             : static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0,
      61             :                                uint16_t s);
      62             : 
      63       21330 : static int PredictorSetup(TIFF *tif)
      64             : {
      65             :     static const char module[] = "PredictorSetup";
      66             : 
      67       21330 :     TIFFPredictorState *sp = PredictorState(tif);
      68       21330 :     TIFFDirectory *td = &tif->tif_dir;
      69             : 
      70       21330 :     switch (sp->predictor) /* no differencing */
      71             :     {
      72       20927 :         case PREDICTOR_NONE:
      73       20927 :             return 1;
      74         389 :         case PREDICTOR_HORIZONTAL:
      75         389 :             if (td->td_bitspersample != 8 && td->td_bitspersample != 16 &&
      76           6 :                 td->td_bitspersample != 32 && td->td_bitspersample != 64)
      77             :             {
      78           0 :                 TIFFErrorExtR(tif, module,
      79             :                               "Horizontal differencing \"Predictor\" not "
      80             :                               "supported with %" PRIu16 "-bit samples",
      81           0 :                               td->td_bitspersample);
      82           0 :                 return 0;
      83             :             }
      84         389 :             break;
      85          13 :         case PREDICTOR_FLOATINGPOINT:
      86          13 :             if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP)
      87             :             {
      88           0 :                 TIFFErrorExtR(
      89             :                     tif, module,
      90             :                     "Floating point \"Predictor\" not supported with %" PRIu16
      91             :                     " data format",
      92           0 :                     td->td_sampleformat);
      93           0 :                 return 0;
      94             :             }
      95          13 :             if (td->td_bitspersample != 16 && td->td_bitspersample != 24 &&
      96          11 :                 td->td_bitspersample != 32 && td->td_bitspersample != 64)
      97             :             { /* Should 64 be allowed? */
      98           0 :                 TIFFErrorExtR(
      99             :                     tif, module,
     100             :                     "Floating point \"Predictor\" not supported with %" PRIu16
     101             :                     "-bit samples",
     102           0 :                     td->td_bitspersample);
     103           0 :                 return 0;
     104             :             }
     105          13 :             break;
     106           1 :         default:
     107           1 :             TIFFErrorExtR(tif, module, "\"Predictor\" value %d not supported",
     108             :                           sp->predictor);
     109           1 :             return 0;
     110             :     }
     111         402 :     sp->stride =
     112         804 :         (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel
     113         402 :                                                     : 1);
     114             :     /*
     115             :      * Calculate the scanline/tile-width size in bytes.
     116             :      */
     117         402 :     if (isTiled(tif))
     118          23 :         sp->rowsize = TIFFTileRowSize(tif);
     119             :     else
     120         379 :         sp->rowsize = TIFFScanlineSize(tif);
     121         402 :     if (sp->rowsize == 0)
     122           0 :         return 0;
     123             : 
     124         402 :     return 1;
     125             : }
     126             : 
     127        3420 : static int PredictorSetupDecode(TIFF *tif)
     128             : {
     129        3420 :     TIFFPredictorState *sp = PredictorState(tif);
     130        3420 :     TIFFDirectory *td = &tif->tif_dir;
     131             : 
     132             :     /* Note: when PredictorSetup() fails, the effets of setupdecode() */
     133             :     /* will not be "canceled" so setupdecode() might be robust to */
     134             :     /* be called several times. */
     135        3420 :     if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
     136           1 :         return 0;
     137             : 
     138        3419 :     if (sp->predictor == 2)
     139             :     {
     140          97 :         switch (td->td_bitspersample)
     141             :         {
     142          77 :             case 8:
     143          77 :                 sp->decodepfunc = horAcc8;
     144          77 :                 break;
     145          17 :             case 16:
     146          17 :                 sp->decodepfunc = horAcc16;
     147          17 :                 break;
     148           2 :             case 32:
     149           2 :                 sp->decodepfunc = horAcc32;
     150           2 :                 break;
     151           1 :             case 64:
     152           1 :                 sp->decodepfunc = horAcc64;
     153           1 :                 break;
     154           0 :             default:
     155           0 :                 break;
     156             :         }
     157             :         /*
     158             :          * Override default decoding method with one that does the
     159             :          * predictor stuff.
     160             :          */
     161          97 :         if (tif->tif_decoderow != PredictorDecodeRow)
     162             :         {
     163          97 :             sp->decoderow = tif->tif_decoderow;
     164          97 :             tif->tif_decoderow = PredictorDecodeRow;
     165          97 :             sp->decodestrip = tif->tif_decodestrip;
     166          97 :             tif->tif_decodestrip = PredictorDecodeTile;
     167          97 :             sp->decodetile = tif->tif_decodetile;
     168          97 :             tif->tif_decodetile = PredictorDecodeTile;
     169             :         }
     170             : 
     171             :         /*
     172             :          * If the data is horizontally differenced 16-bit data that
     173             :          * requires byte-swapping, then it must be byte swapped before
     174             :          * the accumulation step.  We do this with a special-purpose
     175             :          * routine and override the normal post decoding logic that
     176             :          * the library setup when the directory was read.
     177             :          */
     178          97 :         if (tif->tif_flags & TIFF_SWAB)
     179             :         {
     180           5 :             if (sp->decodepfunc == horAcc16)
     181             :             {
     182           4 :                 sp->decodepfunc = swabHorAcc16;
     183           4 :                 tif->tif_postdecode = _TIFFNoPostDecode;
     184             :             }
     185           1 :             else if (sp->decodepfunc == horAcc32)
     186             :             {
     187           1 :                 sp->decodepfunc = swabHorAcc32;
     188           1 :                 tif->tif_postdecode = _TIFFNoPostDecode;
     189             :             }
     190           0 :             else if (sp->decodepfunc == horAcc64)
     191             :             {
     192           0 :                 sp->decodepfunc = swabHorAcc64;
     193           0 :                 tif->tif_postdecode = _TIFFNoPostDecode;
     194             :             }
     195             :         }
     196             :     }
     197             : 
     198        3322 :     else if (sp->predictor == 3)
     199             :     {
     200           9 :         sp->decodepfunc = fpAcc;
     201             :         /*
     202             :          * Override default decoding method with one that does the
     203             :          * predictor stuff.
     204             :          */
     205           9 :         if (tif->tif_decoderow != PredictorDecodeRow)
     206             :         {
     207           9 :             sp->decoderow = tif->tif_decoderow;
     208           9 :             tif->tif_decoderow = PredictorDecodeRow;
     209           9 :             sp->decodestrip = tif->tif_decodestrip;
     210           9 :             tif->tif_decodestrip = PredictorDecodeTile;
     211           9 :             sp->decodetile = tif->tif_decodetile;
     212           9 :             tif->tif_decodetile = PredictorDecodeTile;
     213             :         }
     214             :         /*
     215             :          * The data should not be swapped outside of the floating
     216             :          * point predictor, the accumulation routine should return
     217             :          * bytes in the native order.
     218             :          */
     219           9 :         if (tif->tif_flags & TIFF_SWAB)
     220             :         {
     221           2 :             tif->tif_postdecode = _TIFFNoPostDecode;
     222             :         }
     223             :     }
     224             : 
     225        3419 :     return 1;
     226             : }
     227             : 
     228       17910 : static int PredictorSetupEncode(TIFF *tif)
     229             : {
     230       17910 :     TIFFPredictorState *sp = PredictorState(tif);
     231       17910 :     TIFFDirectory *td = &tif->tif_dir;
     232             : 
     233       17910 :     if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
     234           0 :         return 0;
     235             : 
     236       17910 :     if (sp->predictor == 2)
     237             :     {
     238         292 :         switch (td->td_bitspersample)
     239             :         {
     240         277 :             case 8:
     241         277 :                 sp->encodepfunc = horDiff8;
     242         277 :                 break;
     243          12 :             case 16:
     244          12 :                 sp->encodepfunc = horDiff16;
     245          12 :                 break;
     246           2 :             case 32:
     247           2 :                 sp->encodepfunc = horDiff32;
     248           2 :                 break;
     249           1 :             case 64:
     250           1 :                 sp->encodepfunc = horDiff64;
     251           1 :                 break;
     252           0 :             default:
     253           0 :                 break;
     254             :         }
     255             :         /*
     256             :          * Override default encoding method with one that does the
     257             :          * predictor stuff.
     258             :          */
     259         292 :         if (tif->tif_encoderow != PredictorEncodeRow)
     260             :         {
     261         291 :             sp->encoderow = tif->tif_encoderow;
     262         291 :             tif->tif_encoderow = PredictorEncodeRow;
     263         291 :             sp->encodestrip = tif->tif_encodestrip;
     264         291 :             tif->tif_encodestrip = PredictorEncodeTile;
     265         291 :             sp->encodetile = tif->tif_encodetile;
     266         291 :             tif->tif_encodetile = PredictorEncodeTile;
     267             :         }
     268             : 
     269             :         /*
     270             :          * If the data is horizontally differenced 16-bit data that
     271             :          * requires byte-swapping, then it must be byte swapped after
     272             :          * the differentiation step.  We do this with a special-purpose
     273             :          * routine and override the normal post decoding logic that
     274             :          * the library setup when the directory was read.
     275             :          */
     276         292 :         if (tif->tif_flags & TIFF_SWAB)
     277             :         {
     278           6 :             if (sp->encodepfunc == horDiff16)
     279             :             {
     280           5 :                 sp->encodepfunc = swabHorDiff16;
     281           5 :                 tif->tif_postdecode = _TIFFNoPostDecode;
     282             :             }
     283           1 :             else if (sp->encodepfunc == horDiff32)
     284             :             {
     285           1 :                 sp->encodepfunc = swabHorDiff32;
     286           1 :                 tif->tif_postdecode = _TIFFNoPostDecode;
     287             :             }
     288           0 :             else if (sp->encodepfunc == horDiff64)
     289             :             {
     290           0 :                 sp->encodepfunc = swabHorDiff64;
     291           0 :                 tif->tif_postdecode = _TIFFNoPostDecode;
     292             :             }
     293             :         }
     294             :     }
     295             : 
     296       17618 :     else if (sp->predictor == 3)
     297             :     {
     298           4 :         sp->encodepfunc = fpDiff;
     299             :         /*
     300             :          * Override default encoding method with one that does the
     301             :          * predictor stuff.
     302             :          */
     303           4 :         if (tif->tif_encoderow != PredictorEncodeRow)
     304             :         {
     305           4 :             sp->encoderow = tif->tif_encoderow;
     306           4 :             tif->tif_encoderow = PredictorEncodeRow;
     307           4 :             sp->encodestrip = tif->tif_encodestrip;
     308           4 :             tif->tif_encodestrip = PredictorEncodeTile;
     309           4 :             sp->encodetile = tif->tif_encodetile;
     310           4 :             tif->tif_encodetile = PredictorEncodeTile;
     311             :         }
     312             :         /*
     313             :          * The data should not be swapped outside of the floating
     314             :          * point predictor, the differentiation routine should return
     315             :          * bytes in the native order.
     316             :          */
     317           4 :         if (tif->tif_flags & TIFF_SWAB)
     318             :         {
     319           1 :             tif->tif_postdecode = _TIFFNoPostDecode;
     320             :         }
     321             :     }
     322             : 
     323       17910 :     return 1;
     324             : }
     325             : 
     326             : #define REPEAT4(n, op)                                                         \
     327             :     switch (n)                                                                 \
     328             :     {                                                                          \
     329             :         default:                                                               \
     330             :         {                                                                      \
     331             :             tmsize_t i;                                                        \
     332             :             for (i = n - 4; i > 0; i--)                                        \
     333             :             {                                                                  \
     334             :                 op;                                                            \
     335             :             }                                                                  \
     336             :         } /*-fallthrough*/                                                     \
     337             :         case 4:                                                                \
     338             :             op; /*-fallthrough*/                                               \
     339             :         case 3:                                                                \
     340             :             op; /*-fallthrough*/                                               \
     341             :         case 2:                                                                \
     342             :             op; /*-fallthrough*/                                               \
     343             :         case 1:                                                                \
     344             :             op; /*-fallthrough*/                                               \
     345             :         case 0:;                                                               \
     346             :     }
     347             : 
     348             : /* Remarks related to C standard compliance in all below functions : */
     349             : /* - to avoid any undefined behavior, we only operate on unsigned types */
     350             : /*   since the behavior of "overflows" is defined (wrap over) */
     351             : /* - when storing into the byte stream, we explicitly mask with 0xff so */
     352             : /*   as to make icc -check=conversions happy (not necessary by the standard) */
     353             : 
     354             : /*
     355             :  * Predictor accumulation works on native-order samples.  If the TIFF byte
     356             :  * order differs from host byte order, the swab wrapper first swaps the byte
     357             :  * stream explicitly.  These helpers only avoid unaligned typed dereferences.
     358             :  * Use fixed-size memcpy() calls directly so optimizing compilers can expand
     359             :  * them in this per-sample hot path.  _TIFFmemcpy() is an out-of-line wrapper
     360             :  * in non-LTO builds.
     361             :  */
     362             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     363      514708 : static void PredictorAccumulate16NativeUnaligned(uint8_t *current,
     364             :                                                  const uint8_t *previous)
     365             : {
     366             :     uint16_t thisval;
     367             :     uint16_t prevval;
     368      514708 :     memcpy(&thisval, current, sizeof(thisval));
     369      514708 :     memcpy(&prevval, previous, sizeof(prevval));
     370      514708 :     thisval =
     371      514708 :         (uint16_t)(((unsigned int)thisval + (unsigned int)prevval) & 0xffff);
     372      514708 :     memcpy(current, &thisval, sizeof(thisval));
     373      514708 : }
     374             : 
     375             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     376          10 : static void PredictorAccumulate32NativeUnaligned(uint8_t *current,
     377             :                                                  const uint8_t *previous)
     378             : {
     379             :     uint32_t thisval;
     380             :     uint32_t prevval;
     381          10 :     memcpy(&thisval, current, sizeof(thisval));
     382          10 :     memcpy(&prevval, previous, sizeof(prevval));
     383          10 :     thisval += prevval;
     384          10 :     memcpy(current, &thisval, sizeof(thisval));
     385          10 : }
     386             : 
     387             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     388           1 : static void PredictorAccumulate64NativeUnaligned(uint8_t *current,
     389             :                                                  const uint8_t *previous)
     390             : {
     391             :     uint64_t thisval;
     392             :     uint64_t prevval;
     393           1 :     memcpy(&thisval, current, sizeof(thisval));
     394           1 :     memcpy(&prevval, previous, sizeof(prevval));
     395           1 :     thisval += prevval;
     396           1 :     memcpy(current, &thisval, sizeof(thisval));
     397           1 : }
     398             : 
     399         245 : static void PredictorSwabByteStream16(uint8_t *cp, tmsize_t n)
     400             : {
     401       30514 :     while (n-- > 0)
     402             :     {
     403       30269 :         uint8_t tmp = cp[0];
     404       30269 :         cp[0] = cp[1];
     405       30269 :         cp[1] = tmp;
     406       30269 :         cp += 2;
     407             :     }
     408         245 : }
     409             : 
     410           1 : static void PredictorSwabByteStream32(uint8_t *cp, tmsize_t n)
     411             : {
     412           7 :     while (n-- > 0)
     413             :     {
     414           6 :         uint8_t tmp = cp[0];
     415           6 :         cp[0] = cp[3];
     416           6 :         cp[3] = tmp;
     417           6 :         tmp = cp[1];
     418           6 :         cp[1] = cp[2];
     419           6 :         cp[2] = tmp;
     420           6 :         cp += 4;
     421             :     }
     422           1 : }
     423             : 
     424           0 : static void PredictorSwabByteStream64(uint8_t *cp, tmsize_t n)
     425             : {
     426           0 :     while (n-- > 0)
     427             :     {
     428           0 :         uint8_t tmp = cp[0];
     429           0 :         cp[0] = cp[7];
     430           0 :         cp[7] = tmp;
     431           0 :         tmp = cp[1];
     432           0 :         cp[1] = cp[6];
     433           0 :         cp[6] = tmp;
     434           0 :         tmp = cp[2];
     435           0 :         cp[2] = cp[5];
     436           0 :         cp[5] = tmp;
     437           0 :         tmp = cp[3];
     438           0 :         cp[3] = cp[4];
     439           0 :         cp[4] = tmp;
     440           0 :         cp += 8;
     441             :     }
     442           0 : }
     443             : 
     444             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     445       67518 : static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     446             : {
     447       67518 :     tmsize_t stride = PredictorState(tif)->stride;
     448             : 
     449       67518 :     uint8_t *cp = cp0;
     450       67518 :     if ((cc % stride) != 0)
     451             :     {
     452           0 :         TIFFErrorExtR(tif, "horAcc8", "%s", "(cc%stride)!=0");
     453           0 :         return 0;
     454             :     }
     455             : 
     456       67518 :     if (cc > stride)
     457             :     {
     458             :         /*
     459             :          * Pipeline the most common cases.
     460             :          */
     461       67518 :         if (stride == 1)
     462             :         {
     463       64635 :             uint32_t acc = cp[0];
     464       64635 :             tmsize_t i = stride;
     465     4126060 :             for (; i < cc - 3; i += 4)
     466             :             {
     467     4061420 :                 cp[i + 0] = (uint8_t)((acc += cp[i + 0]) & 0xff);
     468     4061420 :                 cp[i + 1] = (uint8_t)((acc += cp[i + 1]) & 0xff);
     469     4061420 :                 cp[i + 2] = (uint8_t)((acc += cp[i + 2]) & 0xff);
     470     4061420 :                 cp[i + 3] = (uint8_t)((acc += cp[i + 3]) & 0xff);
     471             :             }
     472      258536 :             for (; i < cc; i++)
     473             :             {
     474      193901 :                 cp[i + 0] = (uint8_t)((acc += cp[i + 0]) & 0xff);
     475             :             }
     476             :         }
     477        2883 :         else if (stride == 3)
     478             :         {
     479        2817 :             uint32_t cr = cp[0];
     480        2817 :             uint32_t cg = cp[1];
     481        2817 :             uint32_t cb = cp[2];
     482        2817 :             tmsize_t i = stride;
     483      299012 :             for (; i < cc; i += stride)
     484             :             {
     485      296195 :                 cp[i + 0] = (uint8_t)((cr += cp[i + 0]) & 0xff);
     486      296195 :                 cp[i + 1] = (uint8_t)((cg += cp[i + 1]) & 0xff);
     487      296195 :                 cp[i + 2] = (uint8_t)((cb += cp[i + 2]) & 0xff);
     488             :             }
     489             :         }
     490          66 :         else if (stride == 4)
     491             :         {
     492          65 :             uint32_t cr = cp[0];
     493          65 :             uint32_t cg = cp[1];
     494          65 :             uint32_t cb = cp[2];
     495          65 :             uint32_t ca = cp[3];
     496          65 :             tmsize_t i = stride;
     497        2052 :             for (; i < cc; i += stride)
     498             :             {
     499        1987 :                 cp[i + 0] = (uint8_t)((cr += cp[i + 0]) & 0xff);
     500        1987 :                 cp[i + 1] = (uint8_t)((cg += cp[i + 1]) & 0xff);
     501        1987 :                 cp[i + 2] = (uint8_t)((cb += cp[i + 2]) & 0xff);
     502        1987 :                 cp[i + 3] = (uint8_t)((ca += cp[i + 3]) & 0xff);
     503             :             }
     504             :         }
     505             :         else
     506             :         {
     507           1 :             cc -= stride;
     508             :             do
     509             :             {
     510           2 :                 REPEAT4(stride,
     511             :                         cp[stride] = (uint8_t)((cp[stride] + *cp) & 0xff);
     512             :                         cp++)
     513           1 :                 cc -= stride;
     514           1 :             } while (cc > 0);
     515             :         }
     516             :     }
     517       67518 :     return 1;
     518             : }
     519             : 
     520         245 : static int swabHorAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     521             : {
     522         245 :     tmsize_t wc = cc / 2;
     523             : 
     524         245 :     PredictorSwabByteStream16(cp0, wc);
     525         245 :     return horAcc16(tif, cp0, cc);
     526             : }
     527             : 
     528             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     529        1736 : static int horAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     530             : {
     531        1736 :     tmsize_t stride = PredictorState(tif)->stride;
     532        1736 :     uint8_t *cp = cp0;
     533        1736 :     tmsize_t wc = cc / 2;
     534             : 
     535        1736 :     if ((cc % (2 * stride)) != 0)
     536             :     {
     537           0 :         TIFFErrorExtR(tif, "horAcc16", "%s", "cc%(2*stride))!=0");
     538           0 :         return 0;
     539             :     }
     540             : 
     541        1736 :     if (wc > stride)
     542             :     {
     543        1736 :         wc -= stride;
     544             :         do
     545             :         {
     546      514708 :             REPEAT4(stride,
     547             :                     PredictorAccumulate16NativeUnaligned(cp + 2 * stride, cp);
     548             :                     cp += 2)
     549      514708 :             wc -= stride;
     550      514708 :         } while (wc > 0);
     551             :     }
     552        1736 :     return 1;
     553             : }
     554             : 
     555           1 : static int swabHorAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     556             : {
     557           1 :     tmsize_t wc = cc / 4;
     558             : 
     559           1 :     PredictorSwabByteStream32(cp0, wc);
     560           1 :     return horAcc32(tif, cp0, cc);
     561             : }
     562             : 
     563             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     564           2 : static int horAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     565             : {
     566           2 :     tmsize_t stride = PredictorState(tif)->stride;
     567           2 :     uint8_t *cp = cp0;
     568           2 :     tmsize_t wc = cc / 4;
     569             : 
     570           2 :     if ((cc % (4 * stride)) != 0)
     571             :     {
     572           0 :         TIFFErrorExtR(tif, "horAcc32", "%s", "cc%(4*stride))!=0");
     573           0 :         return 0;
     574             :     }
     575             : 
     576           2 :     if (wc > stride)
     577             :     {
     578           2 :         wc -= stride;
     579             :         do
     580             :         {
     581          10 :             REPEAT4(stride,
     582             :                     PredictorAccumulate32NativeUnaligned(cp + 4 * stride, cp);
     583             :                     cp += 4)
     584          10 :             wc -= stride;
     585          10 :         } while (wc > 0);
     586             :     }
     587           2 :     return 1;
     588             : }
     589             : 
     590           0 : static int swabHorAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     591             : {
     592           0 :     tmsize_t wc = cc / 8;
     593             : 
     594           0 :     PredictorSwabByteStream64(cp0, wc);
     595           0 :     return horAcc64(tif, cp0, cc);
     596             : }
     597             : 
     598             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     599           1 : static int horAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     600             : {
     601           1 :     tmsize_t stride = PredictorState(tif)->stride;
     602           1 :     uint8_t *cp = cp0;
     603           1 :     tmsize_t wc = cc / 8;
     604             : 
     605           1 :     if ((cc % (8 * stride)) != 0)
     606             :     {
     607           0 :         TIFFErrorExtR(tif, "horAcc64", "%s", "cc%(8*stride))!=0");
     608           0 :         return 0;
     609             :     }
     610             : 
     611           1 :     if (wc > stride)
     612             :     {
     613           1 :         wc -= stride;
     614             :         do
     615             :         {
     616           1 :             REPEAT4(stride,
     617             :                     PredictorAccumulate64NativeUnaligned(cp + 8 * stride, cp);
     618             :                     cp += 8)
     619           1 :             wc -= stride;
     620           1 :         } while (wc > 0);
     621             :     }
     622           1 :     return 1;
     623             : }
     624             : 
     625             : /*
     626             :  * Floating point predictor accumulation routine.
     627             :  */
     628        1531 : static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     629             : {
     630        1531 :     tmsize_t stride = PredictorState(tif)->stride;
     631        1531 :     uint32_t bps = tif->tif_dir.td_bitspersample / 8;
     632        1531 :     tmsize_t wc = cc / bps;
     633        1531 :     tmsize_t count = cc;
     634        1531 :     uint8_t *cp = cp0;
     635             :     uint8_t *tmp;
     636             : 
     637        1531 :     if (cc % (bps * stride) != 0)
     638             :     {
     639           0 :         TIFFErrorExtR(tif, "fpAcc", "%s", "cc%(bps*stride))!=0");
     640           0 :         return 0;
     641             :     }
     642             : 
     643        1531 :     tmp = (uint8_t *)_TIFFmallocExt(tif, cc);
     644        1531 :     if (!tmp)
     645           0 :         return 0;
     646             : 
     647        1531 :     if (stride == 1)
     648             :     {
     649             :         /* Optimization of general case */
     650             : #define OP                                                                     \
     651             :     do                                                                         \
     652             :     {                                                                          \
     653             :         cp[1] = (uint8_t)((cp[1] + cp[0]) & 0xff);                             \
     654             :         ++cp;                                                                  \
     655             :     } while (0)
     656      149205 :         for (; count > 8; count -= 8)
     657             :         {
     658      147675 :             OP;
     659      147675 :             OP;
     660      147675 :             OP;
     661      147675 :             OP;
     662      147675 :             OP;
     663      147675 :             OP;
     664      147675 :             OP;
     665      147675 :             OP;
     666             :         }
     667       12240 :         for (; count > 1; count -= 1)
     668             :         {
     669       10710 :             OP;
     670             :         }
     671             : #undef OP
     672             :     }
     673             :     else
     674             :     {
     675          16 :         while (count > stride)
     676             :         {
     677          15 :             REPEAT4(stride, cp[stride] = (uint8_t)((cp[stride] + cp[0]) & 0xff);
     678             :                     cp++)
     679          15 :             count -= stride;
     680             :         }
     681             :     }
     682             : 
     683        1531 :     _TIFFmemcpy(tmp, cp0, cc);
     684        1531 :     cp = (uint8_t *)cp0;
     685        1531 :     count = 0;
     686             : 
     687             : #if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC))
     688        1531 :     if (bps == 4)
     689             :     {
     690             :         /* Optimization of general case */
     691       19425 :         for (; count + 15 < wc; count += 16)
     692             :         {
     693             :             /* Interlace 4*16 byte values */
     694             : 
     695             :             __m128i xmm0 =
     696       17896 :                 _mm_loadu_si128((const __m128i *)(tmp + count + 3 * wc));
     697             :             __m128i xmm1 =
     698       17896 :                 _mm_loadu_si128((const __m128i *)(tmp + count + 2 * wc));
     699             :             __m128i xmm2 =
     700       17896 :                 _mm_loadu_si128((const __m128i *)(tmp + count + 1 * wc));
     701             :             __m128i xmm3 =
     702       35792 :                 _mm_loadu_si128((const __m128i *)(tmp + count + 0 * wc));
     703             :             /* (xmm0_0, xmm1_0, xmm0_1, xmm1_1, xmm0_2, xmm1_2, ...) */
     704       17896 :             __m128i tmp0 = _mm_unpacklo_epi8(xmm0, xmm1);
     705             :             /* (xmm0_8, xmm1_8, xmm0_9, xmm1_9, xmm0_10, xmm1_10, ...) */
     706       17896 :             __m128i tmp1 = _mm_unpackhi_epi8(xmm0, xmm1);
     707             :             /* (xmm2_0, xmm3_0, xmm2_1, xmm3_1, xmm2_2, xmm3_2, ...) */
     708       17896 :             __m128i tmp2 = _mm_unpacklo_epi8(xmm2, xmm3);
     709             :             /* (xmm2_8, xmm3_8, xmm2_9, xmm3_9, xmm2_10, xmm3_10, ...) */
     710       17896 :             __m128i tmp3 = _mm_unpackhi_epi8(xmm2, xmm3);
     711             :             /* (xmm0_0, xmm1_0, xmm2_0, xmm3_0, xmm0_1, xmm1_1, xmm2_1, xmm3_1,
     712             :              * ...) */
     713       17896 :             __m128i tmp2_0 = _mm_unpacklo_epi16(tmp0, tmp2);
     714       17896 :             __m128i tmp2_1 = _mm_unpackhi_epi16(tmp0, tmp2);
     715       17896 :             __m128i tmp2_2 = _mm_unpacklo_epi16(tmp1, tmp3);
     716       17896 :             __m128i tmp2_3 = _mm_unpackhi_epi16(tmp1, tmp3);
     717       17896 :             _mm_storeu_si128((__m128i *)(cp + 4 * count + 0 * 16), tmp2_0);
     718       17896 :             _mm_storeu_si128((__m128i *)(cp + 4 * count + 1 * 16), tmp2_1);
     719       17896 :             _mm_storeu_si128((__m128i *)(cp + 4 * count + 2 * 16), tmp2_2);
     720       17896 :             _mm_storeu_si128((__m128i *)(cp + 4 * count + 3 * 16), tmp2_3);
     721             :         }
     722             :     }
     723             : #endif
     724             : 
     725       13611 :     for (; count < wc; count++)
     726             :     {
     727             :         uint32_t byte;
     728       60408 :         for (byte = 0; byte < bps; byte++)
     729             :         {
     730             : #if WORDS_BIGENDIAN
     731             :             cp[bps * count + byte] = tmp[byte * wc + count];
     732             : #else
     733       48328 :             cp[bps * count + byte] = tmp[(bps - byte - 1) * wc + count];
     734             : #endif
     735             :         }
     736             :     }
     737        1531 :     _TIFFfreeExt(tif, tmp);
     738        1531 :     return 1;
     739             : }
     740             : 
     741             : /*
     742             :  * Decode a scanline and apply the predictor routine.
     743             :  */
     744           0 : static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0,
     745             :                               uint16_t s)
     746             : {
     747           0 :     TIFFPredictorState *sp = PredictorState(tif);
     748             : 
     749           0 :     assert(sp != NULL);
     750           0 :     assert(sp->decoderow != NULL);
     751           0 :     assert(sp->decodepfunc != NULL);
     752             : 
     753           0 :     if ((*sp->decoderow)(tif, op0, occ0, s))
     754             :     {
     755           0 :         return (*sp->decodepfunc)(tif, op0, occ0);
     756             :     }
     757             :     else
     758           0 :         return 0;
     759             : }
     760             : 
     761             : /*
     762             :  * Decode a tile/strip and apply the predictor routine.
     763             :  * Note that horizontal differencing must be done on a
     764             :  * row-by-row basis.  The width of a "row" has already
     765             :  * been calculated at pre-decode time according to the
     766             :  * strip/tile dimensions.
     767             :  */
     768         488 : static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0,
     769             :                                uint16_t s)
     770             : {
     771         488 :     TIFFPredictorState *sp = PredictorState(tif);
     772             : 
     773         488 :     assert(sp != NULL);
     774         488 :     assert(sp->decodetile != NULL);
     775             : 
     776         488 :     if ((*sp->decodetile)(tif, op0, occ0, s))
     777             :     {
     778         488 :         tmsize_t rowsize = sp->rowsize;
     779         488 :         assert(rowsize > 0);
     780         488 :         if ((occ0 % rowsize) != 0)
     781             :         {
     782           0 :             TIFFErrorExtR(tif, "PredictorDecodeTile", "%s",
     783             :                           "occ0%rowsize != 0");
     784           0 :             return 0;
     785             :         }
     786         488 :         assert(sp->decodepfunc != NULL);
     787       71276 :         while (occ0 > 0)
     788             :         {
     789       70788 :             if (!(*sp->decodepfunc)(tif, op0, rowsize))
     790           0 :                 return 0;
     791       70788 :             occ0 -= rowsize;
     792       70788 :             op0 += rowsize;
     793             :         }
     794         488 :         return 1;
     795             :     }
     796             :     else
     797           0 :         return 0;
     798             : }
     799             : 
     800             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     801       67875 : static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     802             : {
     803       67875 :     TIFFPredictorState *sp = PredictorState(tif);
     804       67875 :     tmsize_t stride = sp->stride;
     805       67875 :     unsigned char *cp = (unsigned char *)cp0;
     806             : 
     807       67875 :     if ((cc % stride) != 0)
     808             :     {
     809           0 :         TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%stride)!=0");
     810           0 :         return 0;
     811             :     }
     812             : 
     813       67875 :     if (cc > stride)
     814             :     {
     815       67879 :         cc -= stride;
     816             :         /*
     817             :          * Pipeline the most common cases.
     818             :          */
     819       67879 :         if (stride == 3)
     820             :         {
     821             :             unsigned int r1, g1, b1;
     822        1409 :             unsigned int r2 = cp[0];
     823        1409 :             unsigned int g2 = cp[1];
     824        1409 :             unsigned int b2 = cp[2];
     825             :             do
     826             :             {
     827      529027 :                 r1 = cp[3];
     828      529027 :                 cp[3] = (unsigned char)((r1 - r2) & 0xff);
     829      529027 :                 r2 = r1;
     830      529027 :                 g1 = cp[4];
     831      529027 :                 cp[4] = (unsigned char)((g1 - g2) & 0xff);
     832      529027 :                 g2 = g1;
     833      529027 :                 b1 = cp[5];
     834      529027 :                 cp[5] = (unsigned char)((b1 - b2) & 0xff);
     835      529027 :                 b2 = b1;
     836      529027 :                 cp += 3;
     837      529027 :             } while ((cc -= 3) > 0);
     838             :         }
     839       66470 :         else if (stride == 4)
     840             :         {
     841             :             unsigned int r1, g1, b1, a1;
     842          33 :             unsigned int r2 = cp[0];
     843          33 :             unsigned int g2 = cp[1];
     844          33 :             unsigned int b2 = cp[2];
     845          33 :             unsigned int a2 = cp[3];
     846             :             do
     847             :             {
     848         995 :                 r1 = cp[4];
     849         995 :                 cp[4] = (unsigned char)((r1 - r2) & 0xff);
     850         995 :                 r2 = r1;
     851         995 :                 g1 = cp[5];
     852         995 :                 cp[5] = (unsigned char)((g1 - g2) & 0xff);
     853         995 :                 g2 = g1;
     854         995 :                 b1 = cp[6];
     855         995 :                 cp[6] = (unsigned char)((b1 - b2) & 0xff);
     856         995 :                 b2 = b1;
     857         995 :                 a1 = cp[7];
     858         995 :                 cp[7] = (unsigned char)((a1 - a2) & 0xff);
     859         995 :                 a2 = a1;
     860         995 :                 cp += 4;
     861         995 :             } while ((cc -= 4) > 0);
     862             :         }
     863             :         else
     864             :         {
     865       66437 :             cp += cc - 1;
     866             :             do
     867             :             {
     868    10784600 :                 REPEAT4(stride,
     869             :                         cp[stride] =
     870             :                             (unsigned char)((cp[stride] - cp[0]) & 0xff);
     871             :                         cp--)
     872    10784600 :             } while ((cc -= stride) > 0);
     873             :         }
     874             :     }
     875       67875 :     return 1;
     876             : }
     877             : 
     878             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     879        1014 : static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     880             : {
     881        1014 :     TIFFPredictorState *sp = PredictorState(tif);
     882        1014 :     tmsize_t stride = sp->stride;
     883        1014 :     uint16_t *wp = (uint16_t *)cp0;
     884        1014 :     tmsize_t wc = cc / 2;
     885             : 
     886        1014 :     if ((cc % (2 * stride)) != 0)
     887             :     {
     888           0 :         TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%(2*stride))!=0");
     889           0 :         return 0;
     890             :     }
     891             : 
     892        1014 :     if (wc > stride)
     893             :     {
     894        1014 :         wc -= stride;
     895        1014 :         wp += wc - 1;
     896             :         do
     897             :         {
     898      126596 :             REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] -
     899             :                                                      (unsigned int)wp[0]) &
     900             :                                                     0xffff);
     901             :                     wp--)
     902      126596 :             wc -= stride;
     903      126596 :         } while (wc > 0);
     904             :     }
     905        1014 :     return 1;
     906             : }
     907             : 
     908         379 : static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     909             : {
     910         379 :     uint16_t *wp = (uint16_t *)cp0;
     911         379 :     tmsize_t wc = cc / 2;
     912             : 
     913         379 :     if (!horDiff16(tif, cp0, cc))
     914           0 :         return 0;
     915             : 
     916         379 :     TIFFSwabArrayOfShort(wp, wc);
     917         379 :     return 1;
     918             : }
     919             : 
     920             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     921           2 : static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     922             : {
     923           2 :     TIFFPredictorState *sp = PredictorState(tif);
     924           2 :     tmsize_t stride = sp->stride;
     925           2 :     uint32_t *wp = (uint32_t *)cp0;
     926           2 :     tmsize_t wc = cc / 4;
     927             : 
     928           2 :     if ((cc % (4 * stride)) != 0)
     929             :     {
     930           0 :         TIFFErrorExtR(tif, "horDiff32", "%s", "(cc%(4*stride))!=0");
     931           0 :         return 0;
     932             :     }
     933             : 
     934           2 :     if (wc > stride)
     935             :     {
     936           2 :         wc -= stride;
     937           2 :         wp += wc - 1;
     938             :         do
     939             :         {
     940          10 :             REPEAT4(stride, wp[stride] -= wp[0]; wp--)
     941          10 :             wc -= stride;
     942          10 :         } while (wc > 0);
     943             :     }
     944           2 :     return 1;
     945             : }
     946             : 
     947           1 : static int swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     948             : {
     949           1 :     uint32_t *wp = (uint32_t *)cp0;
     950           1 :     tmsize_t wc = cc / 4;
     951             : 
     952           1 :     if (!horDiff32(tif, cp0, cc))
     953           0 :         return 0;
     954             : 
     955           1 :     TIFFSwabArrayOfLong(wp, wc);
     956           1 :     return 1;
     957             : }
     958             : 
     959             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     960           1 : static int horDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     961             : {
     962           1 :     TIFFPredictorState *sp = PredictorState(tif);
     963           1 :     tmsize_t stride = sp->stride;
     964           1 :     uint64_t *wp = (uint64_t *)cp0;
     965           1 :     tmsize_t wc = cc / 8;
     966             : 
     967           1 :     if ((cc % (8 * stride)) != 0)
     968             :     {
     969           0 :         TIFFErrorExtR(tif, "horDiff64", "%s", "(cc%(8*stride))!=0");
     970           0 :         return 0;
     971             :     }
     972             : 
     973           1 :     if (wc > stride)
     974             :     {
     975           1 :         wc -= stride;
     976           1 :         wp += wc - 1;
     977             :         do
     978             :         {
     979           1 :             REPEAT4(stride, wp[stride] -= wp[0]; wp--)
     980           1 :             wc -= stride;
     981           1 :         } while (wc > 0);
     982             :     }
     983           1 :     return 1;
     984             : }
     985             : 
     986           0 : static int swabHorDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     987             : {
     988           0 :     uint64_t *wp = (uint64_t *)cp0;
     989           0 :     tmsize_t wc = cc / 8;
     990             : 
     991           0 :     if (!horDiff64(tif, cp0, cc))
     992           0 :         return 0;
     993             : 
     994           0 :     TIFFSwabArrayOfLong8(wp, wc);
     995           0 :     return 1;
     996             : }
     997             : 
     998             : /*
     999             :  * Floating point predictor differencing routine.
    1000             :  */
    1001             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
    1002          23 : static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc)
    1003             : {
    1004          23 :     tmsize_t stride = PredictorState(tif)->stride;
    1005          23 :     uint32_t bps = tif->tif_dir.td_bitspersample / 8;
    1006          23 :     tmsize_t wc = cc / bps;
    1007             :     tmsize_t count;
    1008          23 :     uint8_t *cp = (uint8_t *)cp0;
    1009             :     uint8_t *tmp;
    1010             : 
    1011          23 :     if ((cc % (bps * stride)) != 0)
    1012             :     {
    1013           0 :         TIFFErrorExtR(tif, "fpDiff", "%s", "(cc%(bps*stride))!=0");
    1014           0 :         return 0;
    1015             :     }
    1016             : 
    1017          23 :     tmp = (uint8_t *)_TIFFmallocExt(tif, cc);
    1018          23 :     if (!tmp)
    1019           0 :         return 0;
    1020             : 
    1021          23 :     _TIFFmemcpy(tmp, cp0, cc);
    1022         439 :     for (count = 0; count < wc; count++)
    1023             :     {
    1024             :         uint32_t byte;
    1025        2088 :         for (byte = 0; byte < bps; byte++)
    1026             :         {
    1027             : #if WORDS_BIGENDIAN
    1028             :             cp[byte * wc + count] = tmp[bps * count + byte];
    1029             : #else
    1030        1672 :             cp[(bps - byte - 1) * wc + count] = tmp[bps * count + byte];
    1031             : #endif
    1032             :         }
    1033             :     }
    1034          23 :     _TIFFfreeExt(tif, tmp);
    1035             : 
    1036          23 :     cp = (uint8_t *)cp0;
    1037          23 :     cp += cc - stride - 1;
    1038        1656 :     for (count = cc; count > stride; count -= stride)
    1039        1633 :         REPEAT4(stride,
    1040             :                 cp[stride] = (unsigned char)((cp[stride] - cp[0]) & 0xff);
    1041             :                 cp--)
    1042          23 :     return 1;
    1043             : }
    1044             : 
    1045           0 : static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
    1046             : {
    1047             :     static const char module[] = "PredictorEncodeRow";
    1048           0 :     TIFFPredictorState *sp = PredictorState(tif);
    1049             :     uint8_t *working_copy;
    1050             :     int result_code;
    1051             : 
    1052           0 :     assert(sp != NULL);
    1053           0 :     assert(sp->encodepfunc != NULL);
    1054           0 :     assert(sp->encoderow != NULL);
    1055             : 
    1056             :     /*
    1057             :      * Do predictor manipulation in a working buffer to avoid altering
    1058             :      * the callers buffer, like for PredictorEncodeTile().
    1059             :      * https://gitlab.com/libtiff/libtiff/-/issues/5
    1060             :      */
    1061           0 :     working_copy = (uint8_t *)_TIFFmallocExt(tif, cc);
    1062           0 :     if (working_copy == NULL)
    1063             :     {
    1064           0 :         TIFFErrorExtR(tif, module,
    1065             :                       "Out of memory allocating %" PRId64 " byte temp buffer.",
    1066             :                       (int64_t)cc);
    1067           0 :         return 0;
    1068             :     }
    1069           0 :     memcpy(working_copy, bp, (size_t)cc);
    1070             : 
    1071           0 :     if (!(*sp->encodepfunc)(tif, working_copy, cc))
    1072             :     {
    1073           0 :         _TIFFfreeExt(tif, working_copy);
    1074           0 :         return 0;
    1075             :     }
    1076           0 :     result_code = (*sp->encoderow)(tif, working_copy, cc, s);
    1077           0 :     _TIFFfreeExt(tif, working_copy);
    1078           0 :     return result_code;
    1079             : }
    1080             : 
    1081         315 : static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0,
    1082             :                                uint16_t s)
    1083             : {
    1084             :     static const char module[] = "PredictorEncodeTile";
    1085         315 :     TIFFPredictorState *sp = PredictorState(tif);
    1086             :     uint8_t *working_copy;
    1087         315 :     tmsize_t cc = cc0, rowsize;
    1088             :     unsigned char *bp;
    1089             :     int result_code;
    1090             : 
    1091         315 :     assert(sp != NULL);
    1092         315 :     assert(sp->encodepfunc != NULL);
    1093         315 :     assert(sp->encodetile != NULL);
    1094             : 
    1095             :     /*
    1096             :      * Do predictor manipulation in a working buffer to avoid altering
    1097             :      * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
    1098             :      */
    1099         315 :     working_copy = (uint8_t *)_TIFFmallocExt(tif, cc0);
    1100         315 :     if (working_copy == NULL)
    1101             :     {
    1102           0 :         TIFFErrorExtR(tif, module,
    1103             :                       "Out of memory allocating %" PRId64 " byte temp buffer.",
    1104             :                       (int64_t)cc0);
    1105           0 :         return 0;
    1106             :     }
    1107         315 :     memcpy(working_copy, bp0, (size_t)cc0);
    1108         315 :     bp = working_copy;
    1109             : 
    1110         315 :     rowsize = sp->rowsize;
    1111         315 :     assert(rowsize > 0);
    1112         315 :     if ((cc0 % rowsize) != 0)
    1113             :     {
    1114           0 :         TIFFErrorExtR(tif, "PredictorEncodeTile", "%s", "(cc0%rowsize)!=0");
    1115           0 :         _TIFFfreeExt(tif, working_copy);
    1116           0 :         return 0;
    1117             :     }
    1118       68882 :     while (cc > 0)
    1119             :     {
    1120       68915 :         (*sp->encodepfunc)(tif, bp, rowsize);
    1121       68567 :         cc -= rowsize;
    1122       68567 :         bp += rowsize;
    1123             :     }
    1124           0 :     result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
    1125             : 
    1126         315 :     _TIFFfreeExt(tif, working_copy);
    1127             : 
    1128         315 :     return result_code;
    1129             : }
    1130             : 
    1131             : #define FIELD_PREDICTOR (FIELD_CODEC + 0) /* XXX */
    1132             : 
    1133             : static const TIFFField predictFields[] = {
    1134             :     {TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
    1135             :      FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL},
    1136             : };
    1137             : 
    1138      194172 : static int PredictorVSetField(TIFF *tif, uint32_t tag, va_list ap)
    1139             : {
    1140      194172 :     TIFFPredictorState *sp = PredictorState(tif);
    1141             : 
    1142      194172 :     assert(sp != NULL);
    1143      194172 :     assert(sp->vsetparent != NULL);
    1144             : 
    1145      194172 :     switch (tag)
    1146             :     {
    1147        7477 :         case TIFFTAG_PREDICTOR:
    1148        7477 :             sp->predictor = (uint16_t)va_arg(ap, uint16_vap);
    1149        7477 :             TIFFSetFieldBit(tif, FIELD_PREDICTOR);
    1150        7477 :             break;
    1151      186695 :         default:
    1152      186695 :             return (*sp->vsetparent)(tif, tag, ap);
    1153             :     }
    1154        7477 :     tif->tif_flags |= TIFF_DIRTYDIRECT;
    1155        7477 :     return 1;
    1156             : }
    1157             : 
    1158      507345 : static int PredictorVGetField(TIFF *tif, uint32_t tag, va_list ap)
    1159             : {
    1160      507345 :     TIFFPredictorState *sp = PredictorState(tif);
    1161             : 
    1162      507345 :     assert(sp != NULL);
    1163      507345 :     assert(sp->vgetparent != NULL);
    1164             : 
    1165      507345 :     switch (tag)
    1166             :     {
    1167       22790 :         case TIFFTAG_PREDICTOR:
    1168       22790 :             *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor;
    1169       22789 :             break;
    1170      484555 :         default:
    1171      484555 :             return (*sp->vgetparent)(tif, tag, ap);
    1172             :     }
    1173       22789 :     return 1;
    1174             : }
    1175             : 
    1176           0 : static void PredictorPrintDir(TIFF *tif, FILE *fd, long flags)
    1177             : {
    1178           0 :     TIFFPredictorState *sp = PredictorState(tif);
    1179             : 
    1180             :     (void)flags;
    1181           0 :     if (TIFFFieldSet(tif, FIELD_PREDICTOR))
    1182             :     {
    1183           0 :         fprintf(fd, "  Predictor: ");
    1184           0 :         switch (sp->predictor)
    1185             :         {
    1186           0 :             case 1:
    1187           0 :                 fprintf(fd, "none ");
    1188           0 :                 break;
    1189           0 :             case 2:
    1190           0 :                 fprintf(fd, "horizontal differencing ");
    1191           0 :                 break;
    1192           0 :             case 3:
    1193           0 :                 fprintf(fd, "floating point predictor ");
    1194           0 :                 break;
    1195           0 :             default:
    1196           0 :                 break;
    1197             :         }
    1198           0 :         fprintf(fd, "%d (0x%x)\n", sp->predictor, (unsigned)sp->predictor);
    1199             :     }
    1200           0 :     if (sp->printdir)
    1201           0 :         (*sp->printdir)(tif, fd, flags);
    1202           0 : }
    1203             : 
    1204       29121 : int TIFFPredictorInit(TIFF *tif)
    1205             : {
    1206       29121 :     TIFFPredictorState *sp = PredictorState(tif);
    1207             : 
    1208       29121 :     assert(sp != 0);
    1209             : 
    1210             :     /*
    1211             :      * Merge codec-specific tag information.
    1212             :      */
    1213       29121 :     if (!_TIFFMergeFields(tif, predictFields, TIFFArrayCount(predictFields)))
    1214             :     {
    1215           0 :         TIFFErrorExtR(tif, "TIFFPredictorInit",
    1216             :                       "Merging Predictor codec-specific tags failed");
    1217           0 :         return 0;
    1218             :     }
    1219             : 
    1220             :     /*
    1221             :      * Override parent get/set field methods.
    1222             :      */
    1223       29122 :     sp->vgetparent = tif->tif_tagmethods.vgetfield;
    1224       29122 :     tif->tif_tagmethods.vgetfield =
    1225             :         PredictorVGetField; /* hook for predictor tag */
    1226       29122 :     sp->vsetparent = tif->tif_tagmethods.vsetfield;
    1227       29122 :     tif->tif_tagmethods.vsetfield =
    1228             :         PredictorVSetField; /* hook for predictor tag */
    1229       29122 :     sp->printdir = tif->tif_tagmethods.printdir;
    1230       29122 :     tif->tif_tagmethods.printdir =
    1231             :         PredictorPrintDir; /* hook for predictor tag */
    1232             : 
    1233       29122 :     sp->setupdecode = tif->tif_setupdecode;
    1234       29122 :     tif->tif_setupdecode = PredictorSetupDecode;
    1235       29122 :     sp->setupencode = tif->tif_setupencode;
    1236       29122 :     tif->tif_setupencode = PredictorSetupEncode;
    1237             : 
    1238       29122 :     sp->predictor = 1;      /* default value */
    1239       29122 :     sp->encodepfunc = NULL; /* no predictor routine */
    1240       29122 :     sp->decodepfunc = NULL; /* no predictor routine */
    1241       29122 :     return 1;
    1242             : }
    1243             : 
    1244       29117 : int TIFFPredictorCleanup(TIFF *tif)
    1245             : {
    1246       29117 :     TIFFPredictorState *sp = PredictorState(tif);
    1247             : 
    1248       29117 :     assert(sp != 0);
    1249             : 
    1250       29117 :     tif->tif_tagmethods.vgetfield = sp->vgetparent;
    1251       29117 :     tif->tif_tagmethods.vsetfield = sp->vsetparent;
    1252       29117 :     tif->tif_tagmethods.printdir = sp->printdir;
    1253       29117 :     tif->tif_setupdecode = sp->setupdecode;
    1254       29117 :     tif->tif_setupencode = sp->setupencode;
    1255             : 
    1256       29117 :     return 1;
    1257             : }

Generated by: LCOV version 1.14