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

Generated by: LCOV version 1.14