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

Generated by: LCOV version 1.14