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-05-31 00:00:17 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       20922 : static int PredictorSetup(TIFF *tif)
      64             : {
      65             :     static const char module[] = "PredictorSetup";
      66             : 
      67       20922 :     TIFFPredictorState *sp = PredictorState(tif);
      68       20922 :     TIFFDirectory *td = &tif->tif_dir;
      69             : 
      70       20922 :     switch (sp->predictor) /* no differencing */
      71             :     {
      72       20523 :         case PREDICTOR_NONE:
      73       20523 :             return 1;
      74         386 :         case PREDICTOR_HORIZONTAL:
      75         386 :             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         386 :             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           2 :         default:
     107           2 :             TIFFErrorExtR(tif, module, "\"Predictor\" value %d not supported",
     108             :                           sp->predictor);
     109           1 :             return 0;
     110             :     }
     111         397 :     sp->stride =
     112         795 :         (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel
     113         397 :                                                     : 1);
     114             :     /*
     115             :      * Calculate the scanline/tile-width size in bytes.
     116             :      */
     117         397 :     if (isTiled(tif))
     118          22 :         sp->rowsize = TIFFTileRowSize(tif);
     119             :     else
     120         375 :         sp->rowsize = TIFFScanlineSize(tif);
     121         398 :     if (sp->rowsize == 0)
     122           0 :         return 0;
     123             : 
     124         398 :     return 1;
     125             : }
     126             : 
     127        3275 : static int PredictorSetupDecode(TIFF *tif)
     128             : {
     129        3275 :     TIFFPredictorState *sp = PredictorState(tif);
     130        3275 :     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        3275 :     if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
     136           1 :         return 0;
     137             : 
     138        3274 :     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        3178 :     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        3274 :     return 1;
     224             : }
     225             : 
     226       17647 : static int PredictorSetupEncode(TIFF *tif)
     227             : {
     228       17647 :     TIFFPredictorState *sp = PredictorState(tif);
     229       17647 :     TIFFDirectory *td = &tif->tif_dir;
     230             : 
     231       17647 :     if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
     232           0 :         return 0;
     233             : 
     234       17647 :     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         289 :             sp->encoderow = tif->tif_encoderow;
     258         289 :             tif->tif_encoderow = PredictorEncodeRow;
     259         289 :             sp->encodestrip = tif->tif_encodestrip;
     260         289 :             tif->tif_encodestrip = PredictorEncodeTile;
     261         289 :             sp->encodetile = tif->tif_encodetile;
     262         289 :             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       17356 :     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       17647 :     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       67005 : static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     352             : {
     353       67005 :     tmsize_t stride = PredictorState(tif)->stride;
     354             : 
     355       67005 :     uint8_t *cp = cp0;
     356       67005 :     if ((cc % stride) != 0)
     357             :     {
     358           0 :         TIFFErrorExtR(tif, "horAcc8", "%s", "(cc%stride)!=0");
     359           0 :         return 0;
     360             :     }
     361             : 
     362       67005 :     if (cc > stride)
     363             :     {
     364             :         /*
     365             :          * Pipeline the most common cases.
     366             :          */
     367       67005 :         if (stride == 1)
     368             :         {
     369       64635 :             uint32_t acc = cp[0];
     370       64635 :             tmsize_t i = 1;
     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        2370 :         else if (stride == 3)
     384             :         {
     385        2304 :             uint32_t cr = cp[0];
     386        2304 :             uint32_t cg = cp[1];
     387        2304 :             uint32_t cb = cp[2];
     388        2304 :             tmsize_t i = stride;
     389       36812 :             for (; i < cc; i += stride)
     390             :             {
     391       34508 :                 cp[i + 0] = (uint8_t)((cr += cp[i + 0]) & 0xff);
     392       34508 :                 cp[i + 1] = (uint8_t)((cg += cp[i + 1]) & 0xff);
     393       34508 :                 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       67005 :     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 = (uint8_t *)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] = (unsigned char)((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,
     584             :                     cp[stride] = (unsigned char)((cp[stride] + cp[0]) & 0xff);
     585             :                     cp++)
     586          15 :             count -= stride;
     587             :         }
     588             :     }
     589             : 
     590        1530 :     _TIFFmemcpy(tmp, cp0, cc);
     591        1530 :     cp = (uint8_t *)cp0;
     592        1530 :     count = 0;
     593             : 
     594             : #if defined(__x86_64__) || defined(_M_X64)
     595        1530 :     if (bps == 4)
     596             :     {
     597             :         /* Optimization of general case */
     598       19425 :         for (; count + 15 < wc; count += 16)
     599             :         {
     600             :             /* Interlace 4*16 byte values */
     601             : 
     602             :             __m128i xmm0 =
     603       17896 :                 _mm_loadu_si128((__m128i const *)(tmp + count + 3 * wc));
     604             :             __m128i xmm1 =
     605       17896 :                 _mm_loadu_si128((__m128i const *)(tmp + count + 2 * wc));
     606             :             __m128i xmm2 =
     607       17896 :                 _mm_loadu_si128((__m128i const *)(tmp + count + 1 * wc));
     608             :             __m128i xmm3 =
     609       35792 :                 _mm_loadu_si128((__m128i const *)(tmp + count + 0 * wc));
     610             :             /* (xmm0_0, xmm1_0, xmm0_1, xmm1_1, xmm0_2, xmm1_2, ...) */
     611       17896 :             __m128i tmp0 = _mm_unpacklo_epi8(xmm0, xmm1);
     612             :             /* (xmm0_8, xmm1_8, xmm0_9, xmm1_9, xmm0_10, xmm1_10, ...) */
     613       17896 :             __m128i tmp1 = _mm_unpackhi_epi8(xmm0, xmm1);
     614             :             /* (xmm2_0, xmm3_0, xmm2_1, xmm3_1, xmm2_2, xmm3_2, ...) */
     615       17896 :             __m128i tmp2 = _mm_unpacklo_epi8(xmm2, xmm3);
     616             :             /* (xmm2_8, xmm3_8, xmm2_9, xmm3_9, xmm2_10, xmm3_10, ...) */
     617       17896 :             __m128i tmp3 = _mm_unpackhi_epi8(xmm2, xmm3);
     618             :             /* (xmm0_0, xmm1_0, xmm2_0, xmm3_0, xmm0_1, xmm1_1, xmm2_1, xmm3_1,
     619             :              * ...) */
     620       17896 :             __m128i tmp2_0 = _mm_unpacklo_epi16(tmp0, tmp2);
     621       17896 :             __m128i tmp2_1 = _mm_unpackhi_epi16(tmp0, tmp2);
     622       17896 :             __m128i tmp2_2 = _mm_unpacklo_epi16(tmp1, tmp3);
     623       17896 :             __m128i tmp2_3 = _mm_unpackhi_epi16(tmp1, tmp3);
     624       17896 :             _mm_storeu_si128((__m128i *)(cp + 4 * count + 0 * 16), tmp2_0);
     625       17896 :             _mm_storeu_si128((__m128i *)(cp + 4 * count + 1 * 16), tmp2_1);
     626       17896 :             _mm_storeu_si128((__m128i *)(cp + 4 * count + 2 * 16), tmp2_2);
     627       17896 :             _mm_storeu_si128((__m128i *)(cp + 4 * count + 3 * 16), tmp2_3);
     628             :         }
     629             :     }
     630             : #endif
     631             : 
     632       13606 :     for (; count < wc; count++)
     633             :     {
     634             :         uint32_t byte;
     635       60396 :         for (byte = 0; byte < bps; byte++)
     636             :         {
     637             : #if WORDS_BIGENDIAN
     638             :             cp[bps * count + byte] = tmp[byte * wc + count];
     639             : #else
     640       48320 :             cp[bps * count + byte] = tmp[(bps - byte - 1) * wc + count];
     641             : #endif
     642             :         }
     643             :     }
     644        1530 :     _TIFFfreeExt(tif, tmp);
     645        1530 :     return 1;
     646             : }
     647             : 
     648             : /*
     649             :  * Decode a scanline and apply the predictor routine.
     650             :  */
     651           0 : static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0,
     652             :                               uint16_t s)
     653             : {
     654           0 :     TIFFPredictorState *sp = PredictorState(tif);
     655             : 
     656           0 :     assert(sp != NULL);
     657           0 :     assert(sp->decoderow != NULL);
     658           0 :     assert(sp->decodepfunc != NULL);
     659             : 
     660           0 :     if ((*sp->decoderow)(tif, op0, occ0, s))
     661             :     {
     662           0 :         return (*sp->decodepfunc)(tif, op0, occ0);
     663             :     }
     664             :     else
     665           0 :         return 0;
     666             : }
     667             : 
     668             : /*
     669             :  * Decode a tile/strip and apply the predictor routine.
     670             :  * Note that horizontal differencing must be done on a
     671             :  * row-by-row basis.  The width of a "row" has already
     672             :  * been calculated at pre-decode time according to the
     673             :  * strip/tile dimensions.
     674             :  */
     675         486 : static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0,
     676             :                                uint16_t s)
     677             : {
     678         486 :     TIFFPredictorState *sp = PredictorState(tif);
     679             : 
     680         486 :     assert(sp != NULL);
     681         486 :     assert(sp->decodetile != NULL);
     682             : 
     683         486 :     if ((*sp->decodetile)(tif, op0, occ0, s))
     684             :     {
     685         486 :         tmsize_t rowsize = sp->rowsize;
     686         486 :         assert(rowsize > 0);
     687         486 :         if ((occ0 % rowsize) != 0)
     688             :         {
     689           0 :             TIFFErrorExtR(tif, "PredictorDecodeTile", "%s",
     690             :                           "occ0%rowsize != 0");
     691           0 :             return 0;
     692             :         }
     693         486 :         assert(sp->decodepfunc != NULL);
     694       70760 :         while (occ0 > 0)
     695             :         {
     696       70274 :             if (!(*sp->decodepfunc)(tif, op0, rowsize))
     697           0 :                 return 0;
     698       70274 :             occ0 -= rowsize;
     699       70274 :             op0 += rowsize;
     700             :         }
     701         486 :         return 1;
     702             :     }
     703             :     else
     704           0 :         return 0;
     705             : }
     706             : 
     707             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     708       67426 : static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     709             : {
     710       67426 :     TIFFPredictorState *sp = PredictorState(tif);
     711       67426 :     tmsize_t stride = sp->stride;
     712       67426 :     unsigned char *cp = (unsigned char *)cp0;
     713             : 
     714       67426 :     if ((cc % stride) != 0)
     715             :     {
     716           0 :         TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%stride)!=0");
     717           0 :         return 0;
     718             :     }
     719             : 
     720       67426 :     if (cc > stride)
     721             :     {
     722       67362 :         cc -= stride;
     723             :         /*
     724             :          * Pipeline the most common cases.
     725             :          */
     726       67362 :         if (stride == 3)
     727             :         {
     728             :             unsigned int r1, g1, b1;
     729         897 :             unsigned int r2 = cp[0];
     730         897 :             unsigned int g2 = cp[1];
     731         897 :             unsigned int b2 = cp[2];
     732             :             do
     733             :             {
     734      267395 :                 r1 = cp[3];
     735      267395 :                 cp[3] = (unsigned char)((r1 - r2) & 0xff);
     736      267395 :                 r2 = r1;
     737      267395 :                 g1 = cp[4];
     738      267395 :                 cp[4] = (unsigned char)((g1 - g2) & 0xff);
     739      267395 :                 g2 = g1;
     740      267395 :                 b1 = cp[5];
     741      267395 :                 cp[5] = (unsigned char)((b1 - b2) & 0xff);
     742      267395 :                 b2 = b1;
     743      267395 :                 cp += 3;
     744      267395 :             } while ((cc -= 3) > 0);
     745             :         }
     746       66465 :         else if (stride == 4)
     747             :         {
     748             :             unsigned int r1, g1, b1, a1;
     749          33 :             unsigned int r2 = cp[0];
     750          33 :             unsigned int g2 = cp[1];
     751          33 :             unsigned int b2 = cp[2];
     752          33 :             unsigned int a2 = cp[3];
     753             :             do
     754             :             {
     755         995 :                 r1 = cp[4];
     756         995 :                 cp[4] = (unsigned char)((r1 - r2) & 0xff);
     757         995 :                 r2 = r1;
     758         995 :                 g1 = cp[5];
     759         995 :                 cp[5] = (unsigned char)((g1 - g2) & 0xff);
     760         995 :                 g2 = g1;
     761         995 :                 b1 = cp[6];
     762         995 :                 cp[6] = (unsigned char)((b1 - b2) & 0xff);
     763         995 :                 b2 = b1;
     764         995 :                 a1 = cp[7];
     765         995 :                 cp[7] = (unsigned char)((a1 - a2) & 0xff);
     766         995 :                 a2 = a1;
     767         995 :                 cp += 4;
     768         995 :             } while ((cc -= 4) > 0);
     769             :         }
     770             :         else
     771             :         {
     772       66432 :             cp += cc - 1;
     773             :             do
     774             :             {
     775     9695380 :                 REPEAT4(stride,
     776             :                         cp[stride] =
     777             :                             (unsigned char)((cp[stride] - cp[0]) & 0xff);
     778             :                         cp--)
     779     9695380 :             } while ((cc -= stride) > 0);
     780             :         }
     781             :     }
     782       67426 :     return 1;
     783             : }
     784             : 
     785             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     786        1014 : static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     787             : {
     788        1014 :     TIFFPredictorState *sp = PredictorState(tif);
     789        1014 :     tmsize_t stride = sp->stride;
     790        1014 :     uint16_t *wp = (uint16_t *)cp0;
     791        1014 :     tmsize_t wc = cc / 2;
     792             : 
     793        1014 :     if ((cc % (2 * stride)) != 0)
     794             :     {
     795           0 :         TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%(2*stride))!=0");
     796           0 :         return 0;
     797             :     }
     798             : 
     799        1014 :     if (wc > stride)
     800             :     {
     801        1014 :         wc -= stride;
     802        1014 :         wp += wc - 1;
     803             :         do
     804             :         {
     805      126596 :             REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] -
     806             :                                                      (unsigned int)wp[0]) &
     807             :                                                     0xffff);
     808             :                     wp--)
     809      126596 :             wc -= stride;
     810      126596 :         } while (wc > 0);
     811             :     }
     812        1014 :     return 1;
     813             : }
     814             : 
     815         379 : static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     816             : {
     817         379 :     uint16_t *wp = (uint16_t *)cp0;
     818         379 :     tmsize_t wc = cc / 2;
     819             : 
     820         379 :     if (!horDiff16(tif, cp0, cc))
     821           0 :         return 0;
     822             : 
     823         379 :     TIFFSwabArrayOfShort(wp, wc);
     824         379 :     return 1;
     825             : }
     826             : 
     827             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     828           2 : static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     829             : {
     830           2 :     TIFFPredictorState *sp = PredictorState(tif);
     831           2 :     tmsize_t stride = sp->stride;
     832           2 :     uint32_t *wp = (uint32_t *)cp0;
     833           2 :     tmsize_t wc = cc / 4;
     834             : 
     835           2 :     if ((cc % (4 * stride)) != 0)
     836             :     {
     837           0 :         TIFFErrorExtR(tif, "horDiff32", "%s", "(cc%(4*stride))!=0");
     838           0 :         return 0;
     839             :     }
     840             : 
     841           2 :     if (wc > stride)
     842             :     {
     843           2 :         wc -= stride;
     844           2 :         wp += wc - 1;
     845             :         do
     846             :         {
     847          10 :             REPEAT4(stride, wp[stride] -= wp[0]; wp--)
     848          10 :             wc -= stride;
     849          10 :         } while (wc > 0);
     850             :     }
     851           2 :     return 1;
     852             : }
     853             : 
     854           1 : static int swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     855             : {
     856           1 :     uint32_t *wp = (uint32_t *)cp0;
     857           1 :     tmsize_t wc = cc / 4;
     858             : 
     859           1 :     if (!horDiff32(tif, cp0, cc))
     860           0 :         return 0;
     861             : 
     862           1 :     TIFFSwabArrayOfLong(wp, wc);
     863           1 :     return 1;
     864             : }
     865             : 
     866             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     867           1 : static int horDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     868             : {
     869           1 :     TIFFPredictorState *sp = PredictorState(tif);
     870           1 :     tmsize_t stride = sp->stride;
     871           1 :     uint64_t *wp = (uint64_t *)cp0;
     872           1 :     tmsize_t wc = cc / 8;
     873             : 
     874           1 :     if ((cc % (8 * stride)) != 0)
     875             :     {
     876           0 :         TIFFErrorExtR(tif, "horDiff64", "%s", "(cc%(8*stride))!=0");
     877           0 :         return 0;
     878             :     }
     879             : 
     880           1 :     if (wc > stride)
     881             :     {
     882           1 :         wc -= stride;
     883           1 :         wp += wc - 1;
     884             :         do
     885             :         {
     886           1 :             REPEAT4(stride, wp[stride] -= wp[0]; wp--)
     887           1 :             wc -= stride;
     888           1 :         } while (wc > 0);
     889             :     }
     890           1 :     return 1;
     891             : }
     892             : 
     893           0 : static int swabHorDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     894             : {
     895           0 :     uint64_t *wp = (uint64_t *)cp0;
     896           0 :     tmsize_t wc = cc / 8;
     897             : 
     898           0 :     if (!horDiff64(tif, cp0, cc))
     899           0 :         return 0;
     900             : 
     901           0 :     TIFFSwabArrayOfLong8(wp, wc);
     902           0 :     return 1;
     903             : }
     904             : 
     905             : /*
     906             :  * Floating point predictor differencing routine.
     907             :  */
     908             : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
     909          22 : static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc)
     910             : {
     911          22 :     tmsize_t stride = PredictorState(tif)->stride;
     912          22 :     uint32_t bps = tif->tif_dir.td_bitspersample / 8;
     913          22 :     tmsize_t wc = cc / bps;
     914             :     tmsize_t count;
     915          22 :     uint8_t *cp = (uint8_t *)cp0;
     916             :     uint8_t *tmp;
     917             : 
     918          22 :     if ((cc % (bps * stride)) != 0)
     919             :     {
     920           0 :         TIFFErrorExtR(tif, "fpDiff", "%s", "(cc%(bps*stride))!=0");
     921           0 :         return 0;
     922             :     }
     923             : 
     924          22 :     tmp = (uint8_t *)_TIFFmallocExt(tif, cc);
     925          22 :     if (!tmp)
     926           0 :         return 0;
     927             : 
     928          22 :     _TIFFmemcpy(tmp, cp0, cc);
     929         434 :     for (count = 0; count < wc; count++)
     930             :     {
     931             :         uint32_t byte;
     932        2076 :         for (byte = 0; byte < bps; byte++)
     933             :         {
     934             : #if WORDS_BIGENDIAN
     935             :             cp[byte * wc + count] = tmp[bps * count + byte];
     936             : #else
     937        1664 :             cp[(bps - byte - 1) * wc + count] = tmp[bps * count + byte];
     938             : #endif
     939             :         }
     940             :     }
     941          22 :     _TIFFfreeExt(tif, tmp);
     942             : 
     943          22 :     cp = (uint8_t *)cp0;
     944          22 :     cp += cc - stride - 1;
     945        1648 :     for (count = cc; count > stride; count -= stride)
     946        1626 :         REPEAT4(stride,
     947             :                 cp[stride] = (unsigned char)((cp[stride] - cp[0]) & 0xff);
     948             :                 cp--)
     949          22 :     return 1;
     950             : }
     951             : 
     952           0 : static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
     953             : {
     954             :     static const char module[] = "PredictorEncodeRow";
     955           0 :     TIFFPredictorState *sp = PredictorState(tif);
     956             :     uint8_t *working_copy;
     957             :     int result_code;
     958             : 
     959           0 :     assert(sp != NULL);
     960           0 :     assert(sp->encodepfunc != NULL);
     961           0 :     assert(sp->encoderow != NULL);
     962             : 
     963             :     /*
     964             :      * Do predictor manipulation in a working buffer to avoid altering
     965             :      * the callers buffer, like for PredictorEncodeTile().
     966             :      * https://gitlab.com/libtiff/libtiff/-/issues/5
     967             :      */
     968           0 :     working_copy = (uint8_t *)_TIFFmallocExt(tif, cc);
     969           0 :     if (working_copy == NULL)
     970             :     {
     971           0 :         TIFFErrorExtR(tif, module,
     972             :                       "Out of memory allocating %" PRId64 " byte temp buffer.",
     973             :                       (int64_t)cc);
     974           0 :         return 0;
     975             :     }
     976           0 :     memcpy(working_copy, bp, cc);
     977             : 
     978           0 :     if (!(*sp->encodepfunc)(tif, working_copy, cc))
     979             :     {
     980           0 :         _TIFFfreeExt(tif, working_copy);
     981           0 :         return 0;
     982             :     }
     983           0 :     result_code = (*sp->encoderow)(tif, working_copy, cc, s);
     984           0 :     _TIFFfreeExt(tif, working_copy);
     985           0 :     return result_code;
     986             : }
     987             : 
     988         313 : static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0,
     989             :                                uint16_t s)
     990             : {
     991             :     static const char module[] = "PredictorEncodeTile";
     992         313 :     TIFFPredictorState *sp = PredictorState(tif);
     993             :     uint8_t *working_copy;
     994         313 :     tmsize_t cc = cc0, rowsize;
     995             :     unsigned char *bp;
     996             :     int result_code;
     997             : 
     998         313 :     assert(sp != NULL);
     999         313 :     assert(sp->encodepfunc != NULL);
    1000         313 :     assert(sp->encodetile != NULL);
    1001             : 
    1002             :     /*
    1003             :      * Do predictor manipulation in a working buffer to avoid altering
    1004             :      * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
    1005             :      */
    1006         313 :     working_copy = (uint8_t *)_TIFFmallocExt(tif, cc0);
    1007         313 :     if (working_copy == NULL)
    1008             :     {
    1009           0 :         TIFFErrorExtR(tif, module,
    1010             :                       "Out of memory allocating %" PRId64 " byte temp buffer.",
    1011             :                       (int64_t)cc0);
    1012           0 :         return 0;
    1013             :     }
    1014         313 :     memcpy(working_copy, bp0, cc0);
    1015         313 :     bp = working_copy;
    1016             : 
    1017         313 :     rowsize = sp->rowsize;
    1018         313 :     assert(rowsize > 0);
    1019         313 :     if ((cc0 % rowsize) != 0)
    1020             :     {
    1021           0 :         TIFFErrorExtR(tif, "PredictorEncodeTile", "%s", "(cc0%rowsize)!=0");
    1022           0 :         _TIFFfreeExt(tif, working_copy);
    1023           0 :         return 0;
    1024             :     }
    1025       68777 :     while (cc > 0)
    1026             :     {
    1027       68471 :         (*sp->encodepfunc)(tif, bp, rowsize);
    1028       68464 :         cc -= rowsize;
    1029       68464 :         bp += rowsize;
    1030             :     }
    1031         306 :     result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
    1032             : 
    1033         313 :     _TIFFfreeExt(tif, working_copy);
    1034             : 
    1035         313 :     return result_code;
    1036             : }
    1037             : 
    1038             : #define FIELD_PREDICTOR (FIELD_CODEC + 0) /* XXX */
    1039             : 
    1040             : static const TIFFField predictFields[] = {
    1041             :     {TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
    1042             :      FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL},
    1043             : };
    1044             : 
    1045      184527 : static int PredictorVSetField(TIFF *tif, uint32_t tag, va_list ap)
    1046             : {
    1047      184527 :     TIFFPredictorState *sp = PredictorState(tif);
    1048             : 
    1049      184527 :     assert(sp != NULL);
    1050      184527 :     assert(sp->vsetparent != NULL);
    1051             : 
    1052      184527 :     switch (tag)
    1053             :     {
    1054        6895 :         case TIFFTAG_PREDICTOR:
    1055        6895 :             sp->predictor = (uint16_t)va_arg(ap, uint16_vap);
    1056        6895 :             TIFFSetFieldBit(tif, FIELD_PREDICTOR);
    1057        6895 :             break;
    1058      177632 :         default:
    1059      177632 :             return (*sp->vsetparent)(tif, tag, ap);
    1060             :     }
    1061        6895 :     tif->tif_flags |= TIFF_DIRTYDIRECT;
    1062        6895 :     return 1;
    1063             : }
    1064             : 
    1065      489938 : static int PredictorVGetField(TIFF *tif, uint32_t tag, va_list ap)
    1066             : {
    1067      489938 :     TIFFPredictorState *sp = PredictorState(tif);
    1068             : 
    1069      489938 :     assert(sp != NULL);
    1070      489938 :     assert(sp->vgetparent != NULL);
    1071             : 
    1072      489938 :     switch (tag)
    1073             :     {
    1074       22128 :         case TIFFTAG_PREDICTOR:
    1075       22128 :             *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor;
    1076       22128 :             break;
    1077      467810 :         default:
    1078      467810 :             return (*sp->vgetparent)(tif, tag, ap);
    1079             :     }
    1080       22128 :     return 1;
    1081             : }
    1082             : 
    1083           0 : static void PredictorPrintDir(TIFF *tif, FILE *fd, long flags)
    1084             : {
    1085           0 :     TIFFPredictorState *sp = PredictorState(tif);
    1086             : 
    1087             :     (void)flags;
    1088           0 :     if (TIFFFieldSet(tif, FIELD_PREDICTOR))
    1089             :     {
    1090           0 :         fprintf(fd, "  Predictor: ");
    1091           0 :         switch (sp->predictor)
    1092             :         {
    1093           0 :             case 1:
    1094           0 :                 fprintf(fd, "none ");
    1095           0 :                 break;
    1096           0 :             case 2:
    1097           0 :                 fprintf(fd, "horizontal differencing ");
    1098           0 :                 break;
    1099           0 :             case 3:
    1100           0 :                 fprintf(fd, "floating point predictor ");
    1101           0 :                 break;
    1102             :         }
    1103           0 :         fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor);
    1104             :     }
    1105           0 :     if (sp->printdir)
    1106           0 :         (*sp->printdir)(tif, fd, flags);
    1107           0 : }
    1108             : 
    1109       28195 : int TIFFPredictorInit(TIFF *tif)
    1110             : {
    1111       28195 :     TIFFPredictorState *sp = PredictorState(tif);
    1112             : 
    1113       28195 :     assert(sp != 0);
    1114             : 
    1115             :     /*
    1116             :      * Merge codec-specific tag information.
    1117             :      */
    1118       28195 :     if (!_TIFFMergeFields(tif, predictFields, TIFFArrayCount(predictFields)))
    1119             :     {
    1120           0 :         TIFFErrorExtR(tif, "TIFFPredictorInit",
    1121             :                       "Merging Predictor codec-specific tags failed");
    1122           0 :         return 0;
    1123             :     }
    1124             : 
    1125             :     /*
    1126             :      * Override parent get/set field methods.
    1127             :      */
    1128       28195 :     sp->vgetparent = tif->tif_tagmethods.vgetfield;
    1129       28195 :     tif->tif_tagmethods.vgetfield =
    1130             :         PredictorVGetField; /* hook for predictor tag */
    1131       28195 :     sp->vsetparent = tif->tif_tagmethods.vsetfield;
    1132       28195 :     tif->tif_tagmethods.vsetfield =
    1133             :         PredictorVSetField; /* hook for predictor tag */
    1134       28195 :     sp->printdir = tif->tif_tagmethods.printdir;
    1135       28195 :     tif->tif_tagmethods.printdir =
    1136             :         PredictorPrintDir; /* hook for predictor tag */
    1137             : 
    1138       28195 :     sp->setupdecode = tif->tif_setupdecode;
    1139       28195 :     tif->tif_setupdecode = PredictorSetupDecode;
    1140       28195 :     sp->setupencode = tif->tif_setupencode;
    1141       28195 :     tif->tif_setupencode = PredictorSetupEncode;
    1142             : 
    1143       28195 :     sp->predictor = 1;      /* default value */
    1144       28195 :     sp->encodepfunc = NULL; /* no predictor routine */
    1145       28195 :     sp->decodepfunc = NULL; /* no predictor routine */
    1146       28195 :     return 1;
    1147             : }
    1148             : 
    1149       28191 : int TIFFPredictorCleanup(TIFF *tif)
    1150             : {
    1151       28191 :     TIFFPredictorState *sp = PredictorState(tif);
    1152             : 
    1153       28191 :     assert(sp != 0);
    1154             : 
    1155       28191 :     tif->tif_tagmethods.vgetfield = sp->vgetparent;
    1156       28191 :     tif->tif_tagmethods.vsetfield = sp->vsetparent;
    1157       28191 :     tif->tif_tagmethods.printdir = sp->printdir;
    1158       28191 :     tif->tif_setupdecode = sp->setupdecode;
    1159       28191 :     tif->tif_setupencode = sp->setupencode;
    1160             : 
    1161       28191 :     return 1;
    1162             : }

Generated by: LCOV version 1.14