LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_predict.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 447 553 80.8 %
Date: 2025-08-01 10:10:57 Functions: 23 28 82.1 %

          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)
      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       20980 : static int PredictorSetup(TIFF *tif)
      64             : {
      65             :     static const char module[] = "PredictorSetup";
      66             : 
      67       20980 :     TIFFPredictorState *sp = PredictorState(tif);
      68       20980 :     TIFFDirectory *td = &tif->tif_dir;
      69             : 
      70       20980 :     switch (sp->predictor) /* no differencing */
      71             :     {
      72       20581 :         case PREDICTOR_NONE:
      73       20581 :             return 1;
      74         387 :         case PREDICTOR_HORIZONTAL:
      75         387 :             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         387 :             break;
      85          11 :         case PREDICTOR_FLOATINGPOINT:
      86          11 :             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          11 :             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          11 :             break;
     106           1 :         default:
     107           1 :             TIFFErrorExtR(tif, module, "\"Predictor\" value %d not supported",
     108             :                           sp->predictor);
     109           1 :             return 0;
     110             :     }
     111         398 :     sp->stride =
     112         796 :         (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel
     113         398 :                                                     : 1);
     114             :     /*
     115             :      * Calculate the scanline/tile-width size in bytes.
     116             :      */
     117         398 :     if (isTiled(tif))
     118          22 :         sp->rowsize = TIFFTileRowSize(tif);
     119             :     else
     120         376 :         sp->rowsize = TIFFScanlineSize(tif);
     121         398 :     if (sp->rowsize == 0)
     122           0 :         return 0;
     123             : 
     124         398 :     return 1;
     125             : }
     126             : 
     127        3323 : static int PredictorSetupDecode(TIFF *tif)
     128             : {
     129        3323 :     TIFFPredictorState *sp = PredictorState(tif);
     130        3323 :     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        3323 :     if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
     136           1 :         return 0;
     137             : 
     138        3322 :     if (sp->predictor == 2)
     139             :     {
     140          96 :         switch (td->td_bitspersample)
     141             :         {
     142          76 :             case 8:
     143          76 :                 sp->decodepfunc = horAcc8;
     144          76 :                 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             :         }
     155             :         /*
     156             :          * Override default decoding method with one that does the
     157             :          * predictor stuff.
     158             :          */
     159          96 :         if (tif->tif_decoderow != PredictorDecodeRow)
     160             :         {
     161          96 :             sp->decoderow = tif->tif_decoderow;
     162          96 :             tif->tif_decoderow = PredictorDecodeRow;
     163          96 :             sp->decodestrip = tif->tif_decodestrip;
     164          96 :             tif->tif_decodestrip = PredictorDecodeTile;
     165          96 :             sp->decodetile = tif->tif_decodetile;
     166          96 :             tif->tif_decodetile = PredictorDecodeTile;
     167             :         }
     168             : 
     169             :         /*
     170             :          * If the data is horizontally differenced 16-bit data that
     171             :          * requires byte-swapping, then it must be byte swapped before
     172             :          * the accumulation step.  We do this with a special-purpose
     173             :          * routine and override the normal post decoding logic that
     174             :          * the library setup when the directory was read.
     175             :          */
     176          96 :         if (tif->tif_flags & TIFF_SWAB)
     177             :         {
     178           5 :             if (sp->decodepfunc == horAcc16)
     179             :             {
     180           4 :                 sp->decodepfunc = swabHorAcc16;
     181           4 :                 tif->tif_postdecode = _TIFFNoPostDecode;
     182             :             }
     183           1 :             else if (sp->decodepfunc == horAcc32)
     184             :             {
     185           1 :                 sp->decodepfunc = swabHorAcc32;
     186           1 :                 tif->tif_postdecode = _TIFFNoPostDecode;
     187             :             }
     188           0 :             else if (sp->decodepfunc == horAcc64)
     189             :             {
     190           0 :                 sp->decodepfunc = swabHorAcc64;
     191           0 :                 tif->tif_postdecode = _TIFFNoPostDecode;
     192             :             }
     193             :         }
     194             :     }
     195             : 
     196        3226 :     else if (sp->predictor == 3)
     197             :     {
     198           8 :         sp->decodepfunc = fpAcc;
     199             :         /*
     200             :          * Override default decoding method with one that does the
     201             :          * predictor stuff.
     202             :          */
     203           8 :         if (tif->tif_decoderow != PredictorDecodeRow)
     204             :         {
     205           8 :             sp->decoderow = tif->tif_decoderow;
     206           8 :             tif->tif_decoderow = PredictorDecodeRow;
     207           8 :             sp->decodestrip = tif->tif_decodestrip;
     208           8 :             tif->tif_decodestrip = PredictorDecodeTile;
     209           8 :             sp->decodetile = tif->tif_decodetile;
     210           8 :             tif->tif_decodetile = PredictorDecodeTile;
     211             :         }
     212             :         /*
     213             :          * The data should not be swapped outside of the floating
     214             :          * point predictor, the accumulation routine should return
     215             :          * bytes in the native order.
     216             :          */
     217           8 :         if (tif->tif_flags & TIFF_SWAB)
     218             :         {
     219           2 :             tif->tif_postdecode = _TIFFNoPostDecode;
     220             :         }
     221             :     }
     222             : 
     223        3322 :     return 1;
     224             : }
     225             : 
     226       17657 : static int PredictorSetupEncode(TIFF *tif)
     227             : {
     228       17657 :     TIFFPredictorState *sp = PredictorState(tif);
     229       17657 :     TIFFDirectory *td = &tif->tif_dir;
     230             : 
     231       17657 :     if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
     232           0 :         return 0;
     233             : 
     234       17657 :     if (sp->predictor == 2)
     235             :     {
     236         291 :         switch (td->td_bitspersample)
     237             :         {
     238         276 :             case 8:
     239         276 :                 sp->encodepfunc = horDiff8;
     240         276 :                 break;
     241          12 :             case 16:
     242          12 :                 sp->encodepfunc = horDiff16;
     243          12 :                 break;
     244           2 :             case 32:
     245           2 :                 sp->encodepfunc = horDiff32;
     246           2 :                 break;
     247           1 :             case 64:
     248           1 :                 sp->encodepfunc = horDiff64;
     249           1 :                 break;
     250             :         }
     251             :         /*
     252             :          * Override default encoding method with one that does the
     253             :          * predictor stuff.
     254             :          */
     255         291 :         if (tif->tif_encoderow != PredictorEncodeRow)
     256             :         {
     257         290 :             sp->encoderow = tif->tif_encoderow;
     258         290 :             tif->tif_encoderow = PredictorEncodeRow;
     259         290 :             sp->encodestrip = tif->tif_encodestrip;
     260         290 :             tif->tif_encodestrip = PredictorEncodeTile;
     261         290 :             sp->encodetile = tif->tif_encodetile;
     262         290 :             tif->tif_encodetile = PredictorEncodeTile;
     263             :         }
     264             : 
     265             :         /*
     266             :          * If the data is horizontally differenced 16-bit data that
     267             :          * requires byte-swapping, then it must be byte swapped after
     268             :          * the differentiation step.  We do this with a special-purpose
     269             :          * routine and override the normal post decoding logic that
     270             :          * the library setup when the directory was read.
     271             :          */
     272         291 :         if (tif->tif_flags & TIFF_SWAB)
     273             :         {
     274           6 :             if (sp->encodepfunc == horDiff16)
     275             :             {
     276           5 :                 sp->encodepfunc = swabHorDiff16;
     277           5 :                 tif->tif_postdecode = _TIFFNoPostDecode;
     278             :             }
     279           1 :             else if (sp->encodepfunc == horDiff32)
     280             :             {
     281           1 :                 sp->encodepfunc = swabHorDiff32;
     282           1 :                 tif->tif_postdecode = _TIFFNoPostDecode;
     283             :             }
     284           0 :             else if (sp->encodepfunc == horDiff64)
     285             :             {
     286           0 :                 sp->encodepfunc = swabHorDiff64;
     287           0 :                 tif->tif_postdecode = _TIFFNoPostDecode;
     288             :             }
     289             :         }
     290             :     }
     291             : 
     292       17366 :     else if (sp->predictor == 3)
     293             :     {
     294           3 :         sp->encodepfunc = fpDiff;
     295             :         /*
     296             :          * Override default encoding method with one that does the
     297             :          * predictor stuff.
     298             :          */
     299           3 :         if (tif->tif_encoderow != PredictorEncodeRow)
     300             :         {
     301           3 :             sp->encoderow = tif->tif_encoderow;
     302           3 :             tif->tif_encoderow = PredictorEncodeRow;
     303           3 :             sp->encodestrip = tif->tif_encodestrip;
     304           3 :             tif->tif_encodestrip = PredictorEncodeTile;
     305           3 :             sp->encodetile = tif->tif_encodetile;
     306           3 :             tif->tif_encodetile = PredictorEncodeTile;
     307             :         }
     308             :         /*
     309             :          * The data should not be swapped outside of the floating
     310             :          * point predictor, the differentiation routine should return
     311             :          * bytes in the native order.
     312             :          */
     313           3 :         if (tif->tif_flags & TIFF_SWAB)
     314             :         {
     315           1 :             tif->tif_postdecode = _TIFFNoPostDecode;
     316             :         }
     317             :     }
     318             : 
     319       17657 :     return 1;
     320             : }
     321             : 
     322             : #define REPEAT4(n, op)                                                         \
     323             :     switch (n)                                                                 \
     324             :     {                                                                          \
     325             :         default:                                                               \
     326             :         {                                                                      \
     327             :             tmsize_t i;                                                        \
     328             :             for (i = n - 4; i > 0; i--)                                        \
     329             :             {                                                                  \
     330             :                 op;                                                            \
     331             :             }                                                                  \
     332             :         } /*-fallthrough*/                                                     \
     333             :         case 4:                                                                \
     334             :             op; /*-fallthrough*/                                               \
     335             :         case 3:                                                                \
     336             :             op; /*-fallthrough*/                                               \
     337             :         case 2:                                                                \
     338             :             op; /*-fallthrough*/                                               \
     339             :         case 1:                                                                \
     340             :             op; /*-fallthrough*/                                               \
     341             :         case 0:;                                                               \
     342             :     }
     343             : 
     344             : /* Remarks related to C standard compliance in all below functions : */
     345             : /* - to avoid any undefined behavior, we only operate on unsigned types */
     346             : /*   since the behavior of "overflows" is defined (wrap over) */
     347             : /* - when storing into the byte stream, we explicitly mask with 0xff so */
     348             : /*   as to make icc -check=conversions happy (not necessary by the standard) */
     349             : 
     350             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     351       67006 : static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     352             : {
     353       67006 :     tmsize_t stride = PredictorState(tif)->stride;
     354             : 
     355       67006 :     uint8_t *cp = cp0;
     356       67006 :     if ((cc % stride) != 0)
     357             :     {
     358           0 :         TIFFErrorExtR(tif, "horAcc8", "%s", "(cc%stride)!=0");
     359           0 :         return 0;
     360             :     }
     361             : 
     362       67006 :     if (cc > stride)
     363             :     {
     364             :         /*
     365             :          * Pipeline the most common cases.
     366             :          */
     367       67006 :         if (stride == 1)
     368             :         {
     369       64635 :             uint32_t acc = cp[0];
     370       64635 :             tmsize_t i = stride;
     371     4126060 :             for (; i < cc - 3; i += 4)
     372             :             {
     373     4061420 :                 cp[i + 0] = (uint8_t)((acc += cp[i + 0]) & 0xff);
     374     4061420 :                 cp[i + 1] = (uint8_t)((acc += cp[i + 1]) & 0xff);
     375     4061420 :                 cp[i + 2] = (uint8_t)((acc += cp[i + 2]) & 0xff);
     376     4061420 :                 cp[i + 3] = (uint8_t)((acc += cp[i + 3]) & 0xff);
     377             :             }
     378      258536 :             for (; i < cc; i++)
     379             :             {
     380      193901 :                 cp[i + 0] = (uint8_t)((acc += cp[i + 0]) & 0xff);
     381             :             }
     382             :         }
     383        2371 :         else if (stride == 3)
     384             :         {
     385        2305 :             uint32_t cr = cp[0];
     386        2305 :             uint32_t cg = cp[1];
     387        2305 :             uint32_t cb = cp[2];
     388        2305 :             tmsize_t i = stride;
     389       36868 :             for (; i < cc; i += stride)
     390             :             {
     391       34563 :                 cp[i + 0] = (uint8_t)((cr += cp[i + 0]) & 0xff);
     392       34563 :                 cp[i + 1] = (uint8_t)((cg += cp[i + 1]) & 0xff);
     393       34563 :                 cp[i + 2] = (uint8_t)((cb += cp[i + 2]) & 0xff);
     394             :             }
     395             :         }
     396          66 :         else if (stride == 4)
     397             :         {
     398          65 :             uint32_t cr = cp[0];
     399          65 :             uint32_t cg = cp[1];
     400          65 :             uint32_t cb = cp[2];
     401          65 :             uint32_t ca = cp[3];
     402          65 :             tmsize_t i = stride;
     403        2052 :             for (; i < cc; i += stride)
     404             :             {
     405        1987 :                 cp[i + 0] = (uint8_t)((cr += cp[i + 0]) & 0xff);
     406        1987 :                 cp[i + 1] = (uint8_t)((cg += cp[i + 1]) & 0xff);
     407        1987 :                 cp[i + 2] = (uint8_t)((cb += cp[i + 2]) & 0xff);
     408        1987 :                 cp[i + 3] = (uint8_t)((ca += cp[i + 3]) & 0xff);
     409             :             }
     410             :         }
     411             :         else
     412             :         {
     413           1 :             cc -= stride;
     414             :             do
     415             :             {
     416           2 :                 REPEAT4(stride,
     417             :                         cp[stride] = (uint8_t)((cp[stride] + *cp) & 0xff);
     418             :                         cp++)
     419           1 :                 cc -= stride;
     420           1 :             } while (cc > 0);
     421             :         }
     422             :     }
     423       67006 :     return 1;
     424             : }
     425             : 
     426         245 : static int swabHorAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     427             : {
     428         245 :     uint16_t *wp = (uint16_t *)cp0;
     429         245 :     tmsize_t wc = cc / 2;
     430             : 
     431         245 :     TIFFSwabArrayOfShort(wp, wc);
     432         245 :     return horAcc16(tif, cp0, cc);
     433             : }
     434             : 
     435             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     436        1736 : static int horAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     437             : {
     438        1736 :     tmsize_t stride = PredictorState(tif)->stride;
     439        1736 :     uint16_t *wp = (uint16_t *)cp0;
     440        1736 :     tmsize_t wc = cc / 2;
     441             : 
     442        1736 :     if ((cc % (2 * stride)) != 0)
     443             :     {
     444           0 :         TIFFErrorExtR(tif, "horAcc16", "%s", "cc%(2*stride))!=0");
     445           0 :         return 0;
     446             :     }
     447             : 
     448        1736 :     if (wc > stride)
     449             :     {
     450        1736 :         wc -= stride;
     451             :         do
     452             :         {
     453      514708 :             REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] +
     454             :                                                      (unsigned int)wp[0]) &
     455             :                                                     0xffff);
     456             :                     wp++)
     457      514708 :             wc -= stride;
     458      514708 :         } while (wc > 0);
     459             :     }
     460        1736 :     return 1;
     461             : }
     462             : 
     463           1 : static int swabHorAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     464             : {
     465           1 :     uint32_t *wp = (uint32_t *)cp0;
     466           1 :     tmsize_t wc = cc / 4;
     467             : 
     468           1 :     TIFFSwabArrayOfLong(wp, wc);
     469           1 :     return horAcc32(tif, cp0, cc);
     470             : }
     471             : 
     472             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     473           2 : static int horAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     474             : {
     475           2 :     tmsize_t stride = PredictorState(tif)->stride;
     476           2 :     uint32_t *wp = (uint32_t *)cp0;
     477           2 :     tmsize_t wc = cc / 4;
     478             : 
     479           2 :     if ((cc % (4 * stride)) != 0)
     480             :     {
     481           0 :         TIFFErrorExtR(tif, "horAcc32", "%s", "cc%(4*stride))!=0");
     482           0 :         return 0;
     483             :     }
     484             : 
     485           2 :     if (wc > stride)
     486             :     {
     487           2 :         wc -= stride;
     488             :         do
     489             :         {
     490          10 :             REPEAT4(stride, wp[stride] += wp[0]; wp++)
     491          10 :             wc -= stride;
     492          10 :         } while (wc > 0);
     493             :     }
     494           2 :     return 1;
     495             : }
     496             : 
     497           0 : static int swabHorAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     498             : {
     499           0 :     uint64_t *wp = (uint64_t *)cp0;
     500           0 :     tmsize_t wc = cc / 8;
     501             : 
     502           0 :     TIFFSwabArrayOfLong8(wp, wc);
     503           0 :     return horAcc64(tif, cp0, cc);
     504             : }
     505             : 
     506             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     507           1 : static int horAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     508             : {
     509           1 :     tmsize_t stride = PredictorState(tif)->stride;
     510           1 :     uint64_t *wp = (uint64_t *)cp0;
     511           1 :     tmsize_t wc = cc / 8;
     512             : 
     513           1 :     if ((cc % (8 * stride)) != 0)
     514             :     {
     515           0 :         TIFFErrorExtR(tif, "horAcc64", "%s", "cc%(8*stride))!=0");
     516           0 :         return 0;
     517             :     }
     518             : 
     519           1 :     if (wc > stride)
     520             :     {
     521           1 :         wc -= stride;
     522             :         do
     523             :         {
     524           1 :             REPEAT4(stride, wp[stride] += wp[0]; wp++)
     525           1 :             wc -= stride;
     526           1 :         } while (wc > 0);
     527             :     }
     528           1 :     return 1;
     529             : }
     530             : 
     531             : /*
     532             :  * Floating point predictor accumulation routine.
     533             :  */
     534        1530 : static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     535             : {
     536        1530 :     tmsize_t stride = PredictorState(tif)->stride;
     537        1530 :     uint32_t bps = tif->tif_dir.td_bitspersample / 8;
     538        1530 :     tmsize_t wc = cc / bps;
     539        1530 :     tmsize_t count = cc;
     540        1530 :     uint8_t *cp = cp0;
     541             :     uint8_t *tmp;
     542             : 
     543        1530 :     if (cc % (bps * stride) != 0)
     544             :     {
     545           0 :         TIFFErrorExtR(tif, "fpAcc", "%s", "cc%(bps*stride))!=0");
     546           0 :         return 0;
     547             :     }
     548             : 
     549        1530 :     tmp = (uint8_t *)_TIFFmallocExt(tif, cc);
     550        1530 :     if (!tmp)
     551           0 :         return 0;
     552             : 
     553        1530 :     if (stride == 1)
     554             :     {
     555             :         /* Optimization of general case */
     556             : #define OP                                                                     \
     557             :     do                                                                         \
     558             :     {                                                                          \
     559             :         cp[1] = (uint8_t)((cp[1] + cp[0]) & 0xff);                             \
     560             :         ++cp;                                                                  \
     561             :     } while (0)
     562      149204 :         for (; count > 8; count -= 8)
     563             :         {
     564      147675 :             OP;
     565      147675 :             OP;
     566      147675 :             OP;
     567      147675 :             OP;
     568      147675 :             OP;
     569      147675 :             OP;
     570      147675 :             OP;
     571      147675 :             OP;
     572             :         }
     573       12232 :         for (; count > 1; count -= 1)
     574             :         {
     575       10703 :             OP;
     576             :         }
     577             : #undef OP
     578             :     }
     579             :     else
     580             :     {
     581          16 :         while (count > stride)
     582             :         {
     583          15 :             REPEAT4(stride, cp[stride] = (uint8_t)((cp[stride] + cp[0]) & 0xff);
     584             :                     cp++)
     585          15 :             count -= stride;
     586             :         }
     587             :     }
     588             : 
     589        1530 :     _TIFFmemcpy(tmp, cp0, cc);
     590        1530 :     cp = (uint8_t *)cp0;
     591        1530 :     count = 0;
     592             : 
     593             : #if defined(__x86_64__) || defined(_M_X64)
     594        1530 :     if (bps == 4)
     595             :     {
     596             :         /* Optimization of general case */
     597       19425 :         for (; count + 15 < wc; count += 16)
     598             :         {
     599             :             /* Interlace 4*16 byte values */
     600             : 
     601             :             __m128i xmm0 =
     602       17896 :                 _mm_loadu_si128((const __m128i *)(tmp + count + 3 * wc));
     603             :             __m128i xmm1 =
     604       17896 :                 _mm_loadu_si128((const __m128i *)(tmp + count + 2 * wc));
     605             :             __m128i xmm2 =
     606       17896 :                 _mm_loadu_si128((const __m128i *)(tmp + count + 1 * wc));
     607             :             __m128i xmm3 =
     608       35792 :                 _mm_loadu_si128((const __m128i *)(tmp + count + 0 * wc));
     609             :             /* (xmm0_0, xmm1_0, xmm0_1, xmm1_1, xmm0_2, xmm1_2, ...) */
     610       17896 :             __m128i tmp0 = _mm_unpacklo_epi8(xmm0, xmm1);
     611             :             /* (xmm0_8, xmm1_8, xmm0_9, xmm1_9, xmm0_10, xmm1_10, ...) */
     612       17896 :             __m128i tmp1 = _mm_unpackhi_epi8(xmm0, xmm1);
     613             :             /* (xmm2_0, xmm3_0, xmm2_1, xmm3_1, xmm2_2, xmm3_2, ...) */
     614       17896 :             __m128i tmp2 = _mm_unpacklo_epi8(xmm2, xmm3);
     615             :             /* (xmm2_8, xmm3_8, xmm2_9, xmm3_9, xmm2_10, xmm3_10, ...) */
     616       17896 :             __m128i tmp3 = _mm_unpackhi_epi8(xmm2, xmm3);
     617             :             /* (xmm0_0, xmm1_0, xmm2_0, xmm3_0, xmm0_1, xmm1_1, xmm2_1, xmm3_1,
     618             :              * ...) */
     619       17896 :             __m128i tmp2_0 = _mm_unpacklo_epi16(tmp0, tmp2);
     620       17896 :             __m128i tmp2_1 = _mm_unpackhi_epi16(tmp0, tmp2);
     621       17896 :             __m128i tmp2_2 = _mm_unpacklo_epi16(tmp1, tmp3);
     622       17896 :             __m128i tmp2_3 = _mm_unpackhi_epi16(tmp1, tmp3);
     623       17896 :             _mm_storeu_si128((__m128i *)(cp + 4 * count + 0 * 16), tmp2_0);
     624       17896 :             _mm_storeu_si128((__m128i *)(cp + 4 * count + 1 * 16), tmp2_1);
     625       17896 :             _mm_storeu_si128((__m128i *)(cp + 4 * count + 2 * 16), tmp2_2);
     626       17896 :             _mm_storeu_si128((__m128i *)(cp + 4 * count + 3 * 16), tmp2_3);
     627             :         }
     628             :     }
     629             : #endif
     630             : 
     631       13606 :     for (; count < wc; count++)
     632             :     {
     633             :         uint32_t byte;
     634       60396 :         for (byte = 0; byte < bps; byte++)
     635             :         {
     636             : #if WORDS_BIGENDIAN
     637             :             cp[bps * count + byte] = tmp[byte * wc + count];
     638             : #else
     639       48320 :             cp[bps * count + byte] = tmp[(bps - byte - 1) * wc + count];
     640             : #endif
     641             :         }
     642             :     }
     643        1530 :     _TIFFfreeExt(tif, tmp);
     644        1530 :     return 1;
     645             : }
     646             : 
     647             : /*
     648             :  * Decode a scanline and apply the predictor routine.
     649             :  */
     650           0 : static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0,
     651             :                               uint16_t s)
     652             : {
     653           0 :     TIFFPredictorState *sp = PredictorState(tif);
     654             : 
     655           0 :     assert(sp != NULL);
     656           0 :     assert(sp->decoderow != NULL);
     657           0 :     assert(sp->decodepfunc != NULL);
     658             : 
     659           0 :     if ((*sp->decoderow)(tif, op0, occ0, s))
     660             :     {
     661           0 :         return (*sp->decodepfunc)(tif, op0, occ0);
     662             :     }
     663             :     else
     664           0 :         return 0;
     665             : }
     666             : 
     667             : /*
     668             :  * Decode a tile/strip and apply the predictor routine.
     669             :  * Note that horizontal differencing must be done on a
     670             :  * row-by-row basis.  The width of a "row" has already
     671             :  * been calculated at pre-decode time according to the
     672             :  * strip/tile dimensions.
     673             :  */
     674         486 : static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0,
     675             :                                uint16_t s)
     676             : {
     677         486 :     TIFFPredictorState *sp = PredictorState(tif);
     678             : 
     679         486 :     assert(sp != NULL);
     680         486 :     assert(sp->decodetile != NULL);
     681             : 
     682         486 :     if ((*sp->decodetile)(tif, op0, occ0, s))
     683             :     {
     684         486 :         tmsize_t rowsize = sp->rowsize;
     685         486 :         assert(rowsize > 0);
     686         486 :         if ((occ0 % rowsize) != 0)
     687             :         {
     688           0 :             TIFFErrorExtR(tif, "PredictorDecodeTile", "%s",
     689             :                           "occ0%rowsize != 0");
     690           0 :             return 0;
     691             :         }
     692         486 :         assert(sp->decodepfunc != NULL);
     693       70761 :         while (occ0 > 0)
     694             :         {
     695       70275 :             if (!(*sp->decodepfunc)(tif, op0, rowsize))
     696           0 :                 return 0;
     697       70275 :             occ0 -= rowsize;
     698       70275 :             op0 += rowsize;
     699             :         }
     700         486 :         return 1;
     701             :     }
     702             :     else
     703           0 :         return 0;
     704             : }
     705             : 
     706             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     707       67444 : static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     708             : {
     709       67444 :     TIFFPredictorState *sp = PredictorState(tif);
     710       67444 :     tmsize_t stride = sp->stride;
     711       67444 :     unsigned char *cp = (unsigned char *)cp0;
     712             : 
     713       67444 :     if ((cc % stride) != 0)
     714             :     {
     715           0 :         TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%stride)!=0");
     716           0 :         return 0;
     717             :     }
     718             : 
     719       67444 :     if (cc > stride)
     720             :     {
     721       67448 :         cc -= stride;
     722             :         /*
     723             :          * Pipeline the most common cases.
     724             :          */
     725       67448 :         if (stride == 3)
     726             :         {
     727             :             unsigned int r1, g1, b1;
     728         897 :             unsigned int r2 = cp[0];
     729         897 :             unsigned int g2 = cp[1];
     730         897 :             unsigned int b2 = cp[2];
     731             :             do
     732             :             {
     733      267395 :                 r1 = cp[3];
     734      267395 :                 cp[3] = (unsigned char)((r1 - r2) & 0xff);
     735      267395 :                 r2 = r1;
     736      267395 :                 g1 = cp[4];
     737      267395 :                 cp[4] = (unsigned char)((g1 - g2) & 0xff);
     738      267395 :                 g2 = g1;
     739      267395 :                 b1 = cp[5];
     740      267395 :                 cp[5] = (unsigned char)((b1 - b2) & 0xff);
     741      267395 :                 b2 = b1;
     742      267395 :                 cp += 3;
     743      267395 :             } while ((cc -= 3) > 0);
     744             :         }
     745       66551 :         else if (stride == 4)
     746             :         {
     747             :             unsigned int r1, g1, b1, a1;
     748          33 :             unsigned int r2 = cp[0];
     749          33 :             unsigned int g2 = cp[1];
     750          33 :             unsigned int b2 = cp[2];
     751          33 :             unsigned int a2 = cp[3];
     752             :             do
     753             :             {
     754         995 :                 r1 = cp[4];
     755         995 :                 cp[4] = (unsigned char)((r1 - r2) & 0xff);
     756         995 :                 r2 = r1;
     757         995 :                 g1 = cp[5];
     758         995 :                 cp[5] = (unsigned char)((g1 - g2) & 0xff);
     759         995 :                 g2 = g1;
     760         995 :                 b1 = cp[6];
     761         995 :                 cp[6] = (unsigned char)((b1 - b2) & 0xff);
     762         995 :                 b2 = b1;
     763         995 :                 a1 = cp[7];
     764         995 :                 cp[7] = (unsigned char)((a1 - a2) & 0xff);
     765         995 :                 a2 = a1;
     766         995 :                 cp += 4;
     767         995 :             } while ((cc -= 4) > 0);
     768             :         }
     769             :         else
     770             :         {
     771       66518 :             cp += cc - 1;
     772             :             do
     773             :             {
     774    10652000 :                 REPEAT4(stride,
     775             :                         cp[stride] =
     776             :                             (unsigned char)((cp[stride] - cp[0]) & 0xff);
     777             :                         cp--)
     778    10652000 :             } while ((cc -= stride) > 0);
     779             :         }
     780             :     }
     781       67444 :     return 1;
     782             : }
     783             : 
     784             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     785        1014 : static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     786             : {
     787        1014 :     TIFFPredictorState *sp = PredictorState(tif);
     788        1014 :     tmsize_t stride = sp->stride;
     789        1014 :     uint16_t *wp = (uint16_t *)cp0;
     790        1014 :     tmsize_t wc = cc / 2;
     791             : 
     792        1014 :     if ((cc % (2 * stride)) != 0)
     793             :     {
     794           0 :         TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%(2*stride))!=0");
     795           0 :         return 0;
     796             :     }
     797             : 
     798        1014 :     if (wc > stride)
     799             :     {
     800        1014 :         wc -= stride;
     801        1014 :         wp += wc - 1;
     802             :         do
     803             :         {
     804      126596 :             REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] -
     805             :                                                      (unsigned int)wp[0]) &
     806             :                                                     0xffff);
     807             :                     wp--)
     808      126596 :             wc -= stride;
     809      126596 :         } while (wc > 0);
     810             :     }
     811        1014 :     return 1;
     812             : }
     813             : 
     814         379 : static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     815             : {
     816         379 :     uint16_t *wp = (uint16_t *)cp0;
     817         379 :     tmsize_t wc = cc / 2;
     818             : 
     819         379 :     if (!horDiff16(tif, cp0, cc))
     820           0 :         return 0;
     821             : 
     822         379 :     TIFFSwabArrayOfShort(wp, wc);
     823         379 :     return 1;
     824             : }
     825             : 
     826             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     827           2 : static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     828             : {
     829           2 :     TIFFPredictorState *sp = PredictorState(tif);
     830           2 :     tmsize_t stride = sp->stride;
     831           2 :     uint32_t *wp = (uint32_t *)cp0;
     832           2 :     tmsize_t wc = cc / 4;
     833             : 
     834           2 :     if ((cc % (4 * stride)) != 0)
     835             :     {
     836           0 :         TIFFErrorExtR(tif, "horDiff32", "%s", "(cc%(4*stride))!=0");
     837           0 :         return 0;
     838             :     }
     839             : 
     840           2 :     if (wc > stride)
     841             :     {
     842           2 :         wc -= stride;
     843           2 :         wp += wc - 1;
     844             :         do
     845             :         {
     846          10 :             REPEAT4(stride, wp[stride] -= wp[0]; wp--)
     847          10 :             wc -= stride;
     848          10 :         } while (wc > 0);
     849             :     }
     850           2 :     return 1;
     851             : }
     852             : 
     853           1 : static int swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     854             : {
     855           1 :     uint32_t *wp = (uint32_t *)cp0;
     856           1 :     tmsize_t wc = cc / 4;
     857             : 
     858           1 :     if (!horDiff32(tif, cp0, cc))
     859           0 :         return 0;
     860             : 
     861           1 :     TIFFSwabArrayOfLong(wp, wc);
     862           1 :     return 1;
     863             : }
     864             : 
     865             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     866           1 : static int horDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     867             : {
     868           1 :     TIFFPredictorState *sp = PredictorState(tif);
     869           1 :     tmsize_t stride = sp->stride;
     870           1 :     uint64_t *wp = (uint64_t *)cp0;
     871           1 :     tmsize_t wc = cc / 8;
     872             : 
     873           1 :     if ((cc % (8 * stride)) != 0)
     874             :     {
     875           0 :         TIFFErrorExtR(tif, "horDiff64", "%s", "(cc%(8*stride))!=0");
     876           0 :         return 0;
     877             :     }
     878             : 
     879           1 :     if (wc > stride)
     880             :     {
     881           1 :         wc -= stride;
     882           1 :         wp += wc - 1;
     883             :         do
     884             :         {
     885           1 :             REPEAT4(stride, wp[stride] -= wp[0]; wp--)
     886           1 :             wc -= stride;
     887           1 :         } while (wc > 0);
     888             :     }
     889           1 :     return 1;
     890             : }
     891             : 
     892           0 : static int swabHorDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     893             : {
     894           0 :     uint64_t *wp = (uint64_t *)cp0;
     895           0 :     tmsize_t wc = cc / 8;
     896             : 
     897           0 :     if (!horDiff64(tif, cp0, cc))
     898           0 :         return 0;
     899             : 
     900           0 :     TIFFSwabArrayOfLong8(wp, wc);
     901           0 :     return 1;
     902             : }
     903             : 
     904             : /*
     905             :  * Floating point predictor differencing routine.
     906             :  */
     907             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     908          22 : static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     909             : {
     910          22 :     tmsize_t stride = PredictorState(tif)->stride;
     911          22 :     uint32_t bps = tif->tif_dir.td_bitspersample / 8;
     912          22 :     tmsize_t wc = cc / bps;
     913             :     tmsize_t count;
     914          22 :     uint8_t *cp = (uint8_t *)cp0;
     915             :     uint8_t *tmp;
     916             : 
     917          22 :     if ((cc % (bps * stride)) != 0)
     918             :     {
     919           0 :         TIFFErrorExtR(tif, "fpDiff", "%s", "(cc%(bps*stride))!=0");
     920           0 :         return 0;
     921             :     }
     922             : 
     923          22 :     tmp = (uint8_t *)_TIFFmallocExt(tif, cc);
     924          22 :     if (!tmp)
     925           0 :         return 0;
     926             : 
     927          22 :     _TIFFmemcpy(tmp, cp0, cc);
     928         434 :     for (count = 0; count < wc; count++)
     929             :     {
     930             :         uint32_t byte;
     931        2076 :         for (byte = 0; byte < bps; byte++)
     932             :         {
     933             : #if WORDS_BIGENDIAN
     934             :             cp[byte * wc + count] = tmp[bps * count + byte];
     935             : #else
     936        1664 :             cp[(bps - byte - 1) * wc + count] = tmp[bps * count + byte];
     937             : #endif
     938             :         }
     939             :     }
     940          22 :     _TIFFfreeExt(tif, tmp);
     941             : 
     942          22 :     cp = (uint8_t *)cp0;
     943          22 :     cp += cc - stride - 1;
     944        1648 :     for (count = cc; count > stride; count -= stride)
     945        1626 :         REPEAT4(stride,
     946             :                 cp[stride] = (unsigned char)((cp[stride] - cp[0]) & 0xff);
     947             :                 cp--)
     948          22 :     return 1;
     949             : }
     950             : 
     951           0 : static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
     952             : {
     953             :     static const char module[] = "PredictorEncodeRow";
     954           0 :     TIFFPredictorState *sp = PredictorState(tif);
     955             :     uint8_t *working_copy;
     956             :     int result_code;
     957             : 
     958           0 :     assert(sp != NULL);
     959           0 :     assert(sp->encodepfunc != NULL);
     960           0 :     assert(sp->encoderow != NULL);
     961             : 
     962             :     /*
     963             :      * Do predictor manipulation in a working buffer to avoid altering
     964             :      * the callers buffer, like for PredictorEncodeTile().
     965             :      * https://gitlab.com/libtiff/libtiff/-/issues/5
     966             :      */
     967           0 :     working_copy = (uint8_t *)_TIFFmallocExt(tif, cc);
     968           0 :     if (working_copy == NULL)
     969             :     {
     970           0 :         TIFFErrorExtR(tif, module,
     971             :                       "Out of memory allocating %" PRId64 " byte temp buffer.",
     972             :                       (int64_t)cc);
     973           0 :         return 0;
     974             :     }
     975           0 :     memcpy(working_copy, bp, cc);
     976             : 
     977           0 :     if (!(*sp->encodepfunc)(tif, working_copy, cc))
     978             :     {
     979           0 :         _TIFFfreeExt(tif, working_copy);
     980           0 :         return 0;
     981             :     }
     982           0 :     result_code = (*sp->encoderow)(tif, working_copy, cc, s);
     983           0 :     _TIFFfreeExt(tif, working_copy);
     984           0 :     return result_code;
     985             : }
     986             : 
     987         313 : static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0,
     988             :                                uint16_t s)
     989             : {
     990             :     static const char module[] = "PredictorEncodeTile";
     991         313 :     TIFFPredictorState *sp = PredictorState(tif);
     992             :     uint8_t *working_copy;
     993         313 :     tmsize_t cc = cc0, rowsize;
     994             :     unsigned char *bp;
     995             :     int result_code;
     996             : 
     997         313 :     assert(sp != NULL);
     998         313 :     assert(sp->encodepfunc != NULL);
     999         313 :     assert(sp->encodetile != NULL);
    1000             : 
    1001             :     /*
    1002             :      * Do predictor manipulation in a working buffer to avoid altering
    1003             :      * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
    1004             :      */
    1005         313 :     working_copy = (uint8_t *)_TIFFmallocExt(tif, cc0);
    1006         312 :     if (working_copy == NULL)
    1007             :     {
    1008           0 :         TIFFErrorExtR(tif, module,
    1009             :                       "Out of memory allocating %" PRId64 " byte temp buffer.",
    1010             :                       (int64_t)cc0);
    1011           0 :         return 0;
    1012             :     }
    1013         313 :     memcpy(working_copy, bp0, cc0);
    1014         313 :     bp = working_copy;
    1015             : 
    1016         313 :     rowsize = sp->rowsize;
    1017         313 :     assert(rowsize > 0);
    1018         313 :     if ((cc0 % rowsize) != 0)
    1019             :     {
    1020           0 :         TIFFErrorExtR(tif, "PredictorEncodeTile", "%s", "(cc0%rowsize)!=0");
    1021           0 :         _TIFFfreeExt(tif, working_copy);
    1022           0 :         return 0;
    1023             :     }
    1024       68805 :     while (cc > 0)
    1025             :     {
    1026       68483 :         (*sp->encodepfunc)(tif, bp, rowsize);
    1027       68492 :         cc -= rowsize;
    1028       68492 :         bp += rowsize;
    1029             :     }
    1030         322 :     result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
    1031             : 
    1032         313 :     _TIFFfreeExt(tif, working_copy);
    1033             : 
    1034         313 :     return result_code;
    1035             : }
    1036             : 
    1037             : #define FIELD_PREDICTOR (FIELD_CODEC + 0) /* XXX */
    1038             : 
    1039             : static const TIFFField predictFields[] = {
    1040             :     {TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
    1041             :      FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL},
    1042             : };
    1043             : 
    1044      185536 : static int PredictorVSetField(TIFF *tif, uint32_t tag, va_list ap)
    1045             : {
    1046      185536 :     TIFFPredictorState *sp = PredictorState(tif);
    1047             : 
    1048      185536 :     assert(sp != NULL);
    1049      185536 :     assert(sp->vsetparent != NULL);
    1050             : 
    1051      185536 :     switch (tag)
    1052             :     {
    1053        6915 :         case TIFFTAG_PREDICTOR:
    1054        6915 :             sp->predictor = (uint16_t)va_arg(ap, uint16_vap);
    1055        6915 :             TIFFSetFieldBit(tif, FIELD_PREDICTOR);
    1056        6915 :             break;
    1057      178621 :         default:
    1058      178621 :             return (*sp->vsetparent)(tif, tag, ap);
    1059             :     }
    1060        6915 :     tif->tif_flags |= TIFF_DIRTYDIRECT;
    1061        6915 :     return 1;
    1062             : }
    1063             : 
    1064      492634 : static int PredictorVGetField(TIFF *tif, uint32_t tag, va_list ap)
    1065             : {
    1066      492634 :     TIFFPredictorState *sp = PredictorState(tif);
    1067             : 
    1068      492634 :     assert(sp != NULL);
    1069      492634 :     assert(sp->vgetparent != NULL);
    1070             : 
    1071      492634 :     switch (tag)
    1072             :     {
    1073       22154 :         case TIFFTAG_PREDICTOR:
    1074       22154 :             *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor;
    1075       22154 :             break;
    1076      470480 :         default:
    1077      470480 :             return (*sp->vgetparent)(tif, tag, ap);
    1078             :     }
    1079       22154 :     return 1;
    1080             : }
    1081             : 
    1082           0 : static void PredictorPrintDir(TIFF *tif, FILE *fd, long flags)
    1083             : {
    1084           0 :     TIFFPredictorState *sp = PredictorState(tif);
    1085             : 
    1086             :     (void)flags;
    1087           0 :     if (TIFFFieldSet(tif, FIELD_PREDICTOR))
    1088             :     {
    1089           0 :         fprintf(fd, "  Predictor: ");
    1090           0 :         switch (sp->predictor)
    1091             :         {
    1092           0 :             case 1:
    1093           0 :                 fprintf(fd, "none ");
    1094           0 :                 break;
    1095           0 :             case 2:
    1096           0 :                 fprintf(fd, "horizontal differencing ");
    1097           0 :                 break;
    1098           0 :             case 3:
    1099           0 :                 fprintf(fd, "floating point predictor ");
    1100           0 :                 break;
    1101             :         }
    1102           0 :         fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor);
    1103             :     }
    1104           0 :     if (sp->printdir)
    1105           0 :         (*sp->printdir)(tif, fd, flags);
    1106           0 : }
    1107             : 
    1108       28292 : int TIFFPredictorInit(TIFF *tif)
    1109             : {
    1110       28292 :     TIFFPredictorState *sp = PredictorState(tif);
    1111             : 
    1112       28292 :     assert(sp != 0);
    1113             : 
    1114             :     /*
    1115             :      * Merge codec-specific tag information.
    1116             :      */
    1117       28292 :     if (!_TIFFMergeFields(tif, predictFields, TIFFArrayCount(predictFields)))
    1118             :     {
    1119           0 :         TIFFErrorExtR(tif, "TIFFPredictorInit",
    1120             :                       "Merging Predictor codec-specific tags failed");
    1121           0 :         return 0;
    1122             :     }
    1123             : 
    1124             :     /*
    1125             :      * Override parent get/set field methods.
    1126             :      */
    1127       28293 :     sp->vgetparent = tif->tif_tagmethods.vgetfield;
    1128       28293 :     tif->tif_tagmethods.vgetfield =
    1129             :         PredictorVGetField; /* hook for predictor tag */
    1130       28293 :     sp->vsetparent = tif->tif_tagmethods.vsetfield;
    1131       28293 :     tif->tif_tagmethods.vsetfield =
    1132             :         PredictorVSetField; /* hook for predictor tag */
    1133       28293 :     sp->printdir = tif->tif_tagmethods.printdir;
    1134       28293 :     tif->tif_tagmethods.printdir =
    1135             :         PredictorPrintDir; /* hook for predictor tag */
    1136             : 
    1137       28293 :     sp->setupdecode = tif->tif_setupdecode;
    1138       28293 :     tif->tif_setupdecode = PredictorSetupDecode;
    1139       28293 :     sp->setupencode = tif->tif_setupencode;
    1140       28293 :     tif->tif_setupencode = PredictorSetupEncode;
    1141             : 
    1142       28293 :     sp->predictor = 1;      /* default value */
    1143       28293 :     sp->encodepfunc = NULL; /* no predictor routine */
    1144       28293 :     sp->decodepfunc = NULL; /* no predictor routine */
    1145       28293 :     return 1;
    1146             : }
    1147             : 
    1148       28288 : int TIFFPredictorCleanup(TIFF *tif)
    1149             : {
    1150       28288 :     TIFFPredictorState *sp = PredictorState(tif);
    1151             : 
    1152       28288 :     assert(sp != 0);
    1153             : 
    1154       28288 :     tif->tif_tagmethods.vgetfield = sp->vgetparent;
    1155       28288 :     tif->tif_tagmethods.vsetfield = sp->vsetparent;
    1156       28288 :     tif->tif_tagmethods.printdir = sp->printdir;
    1157       28288 :     tif->tif_setupdecode = sp->setupdecode;
    1158       28288 :     tif->tif_setupencode = sp->setupencode;
    1159             : 
    1160       28288 :     return 1;
    1161             : }

Generated by: LCOV version 1.14