Coverage Report

Created: 2026-03-31 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libtiff/libtiff/tif_predict.c
Line
Count
Source
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
389k
#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
static int PredictorSetup(TIFF *tif)
64
6.83k
{
65
6.83k
    static const char module[] = "PredictorSetup";
66
67
6.83k
    TIFFPredictorState *sp = PredictorState(tif);
68
6.83k
    TIFFDirectory *td = &tif->tif_dir;
69
70
6.83k
    switch (sp->predictor) /* no differencing */
71
6.83k
    {
72
4.95k
        case PREDICTOR_NONE:
73
4.95k
            return 1;
74
1.54k
        case PREDICTOR_HORIZONTAL:
75
1.54k
            if (td->td_bitspersample != 8 && td->td_bitspersample != 16 &&
76
480
                td->td_bitspersample != 32 && td->td_bitspersample != 64)
77
8
            {
78
8
                TIFFErrorExtR(tif, module,
79
8
                              "Horizontal differencing \"Predictor\" not "
80
8
                              "supported with %" PRIu16 "-bit samples",
81
8
                              td->td_bitspersample);
82
8
                return 0;
83
8
            }
84
1.53k
            break;
85
1.53k
        case PREDICTOR_FLOATINGPOINT:
86
329
            if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP)
87
8
            {
88
8
                TIFFErrorExtR(
89
8
                    tif, module,
90
8
                    "Floating point \"Predictor\" not supported with %" PRIu16
91
8
                    " data format",
92
8
                    td->td_sampleformat);
93
8
                return 0;
94
8
            }
95
321
            if (td->td_bitspersample != 16 && td->td_bitspersample != 24 &&
96
165
                td->td_bitspersample != 32 && td->td_bitspersample != 64)
97
6
            { /* Should 64 be allowed? */
98
6
                TIFFErrorExtR(
99
6
                    tif, module,
100
6
                    "Floating point \"Predictor\" not supported with %" PRIu16
101
6
                    "-bit samples",
102
6
                    td->td_bitspersample);
103
6
                return 0;
104
6
            }
105
315
            break;
106
315
        default:
107
5
            TIFFErrorExtR(tif, module, "\"Predictor\" value %d not supported",
108
5
                          sp->predictor);
109
5
            return 0;
110
6.83k
    }
111
1.84k
    sp->stride =
112
1.84k
        (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel
113
1.84k
                                                    : 1);
114
    /*
115
     * Calculate the scanline/tile-width size in bytes.
116
     */
117
1.84k
    if (isTiled(tif))
118
79
        sp->rowsize = TIFFTileRowSize(tif);
119
1.77k
    else
120
1.77k
        sp->rowsize = TIFFScanlineSize(tif);
121
1.84k
    if (sp->rowsize == 0)
122
0
        return 0;
123
124
1.84k
    return 1;
125
1.84k
}
126
127
static int PredictorSetupDecode(TIFF *tif)
128
6.87k
{
129
6.87k
    TIFFPredictorState *sp = PredictorState(tif);
130
6.87k
    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
6.87k
    if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
136
73
        return 0;
137
138
6.80k
    if (sp->predictor == 2)
139
1.53k
    {
140
1.53k
        switch (td->td_bitspersample)
141
1.53k
        {
142
741
            case 8:
143
741
                sp->decodepfunc = horAcc8;
144
741
                break;
145
321
            case 16:
146
321
                sp->decodepfunc = horAcc16;
147
321
                break;
148
236
            case 32:
149
236
                sp->decodepfunc = horAcc32;
150
236
                break;
151
236
            case 64:
152
236
                sp->decodepfunc = horAcc64;
153
236
                break;
154
0
            default:
155
0
                break;
156
1.53k
        }
157
        /*
158
         * Override default decoding method with one that does the
159
         * predictor stuff.
160
         */
161
1.53k
        if (tif->tif_decoderow != PredictorDecodeRow)
162
1.53k
        {
163
1.53k
            sp->decoderow = tif->tif_decoderow;
164
1.53k
            tif->tif_decoderow = PredictorDecodeRow;
165
1.53k
            sp->decodestrip = tif->tif_decodestrip;
166
1.53k
            tif->tif_decodestrip = PredictorDecodeTile;
167
1.53k
            sp->decodetile = tif->tif_decodetile;
168
1.53k
            tif->tif_decodetile = PredictorDecodeTile;
169
1.53k
        }
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
1.53k
        if (tif->tif_flags & TIFF_SWAB)
179
362
        {
180
362
            if (sp->decodepfunc == horAcc16)
181
61
            {
182
61
                sp->decodepfunc = swabHorAcc16;
183
61
                tif->tif_postdecode = _TIFFNoPostDecode;
184
61
            }
185
301
            else if (sp->decodepfunc == horAcc32)
186
80
            {
187
80
                sp->decodepfunc = swabHorAcc32;
188
80
                tif->tif_postdecode = _TIFFNoPostDecode;
189
80
            }
190
221
            else if (sp->decodepfunc == horAcc64)
191
128
            {
192
128
                sp->decodepfunc = swabHorAcc64;
193
128
                tif->tif_postdecode = _TIFFNoPostDecode;
194
128
            }
195
362
        }
196
1.53k
    }
197
198
5.27k
    else if (sp->predictor == 3)
199
315
    {
200
315
        sp->decodepfunc = fpAcc;
201
        /*
202
         * Override default decoding method with one that does the
203
         * predictor stuff.
204
         */
205
315
        if (tif->tif_decoderow != PredictorDecodeRow)
206
315
        {
207
315
            sp->decoderow = tif->tif_decoderow;
208
315
            tif->tif_decoderow = PredictorDecodeRow;
209
315
            sp->decodestrip = tif->tif_decodestrip;
210
315
            tif->tif_decodestrip = PredictorDecodeTile;
211
315
            sp->decodetile = tif->tif_decodetile;
212
315
            tif->tif_decodetile = PredictorDecodeTile;
213
315
        }
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
315
        if (tif->tif_flags & TIFF_SWAB)
220
31
        {
221
31
            tif->tif_postdecode = _TIFFNoPostDecode;
222
31
        }
223
315
    }
224
225
6.80k
    return 1;
226
6.80k
}
227
228
static int PredictorSetupEncode(TIFF *tif)
229
0
{
230
0
    TIFFPredictorState *sp = PredictorState(tif);
231
0
    TIFFDirectory *td = &tif->tif_dir;
232
233
0
    if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
234
0
        return 0;
235
236
0
    if (sp->predictor == 2)
237
0
    {
238
0
        switch (td->td_bitspersample)
239
0
        {
240
0
            case 8:
241
0
                sp->encodepfunc = horDiff8;
242
0
                break;
243
0
            case 16:
244
0
                sp->encodepfunc = horDiff16;
245
0
                break;
246
0
            case 32:
247
0
                sp->encodepfunc = horDiff32;
248
0
                break;
249
0
            case 64:
250
0
                sp->encodepfunc = horDiff64;
251
0
                break;
252
0
            default:
253
0
                break;
254
0
        }
255
        /*
256
         * Override default encoding method with one that does the
257
         * predictor stuff.
258
         */
259
0
        if (tif->tif_encoderow != PredictorEncodeRow)
260
0
        {
261
0
            sp->encoderow = tif->tif_encoderow;
262
0
            tif->tif_encoderow = PredictorEncodeRow;
263
0
            sp->encodestrip = tif->tif_encodestrip;
264
0
            tif->tif_encodestrip = PredictorEncodeTile;
265
0
            sp->encodetile = tif->tif_encodetile;
266
0
            tif->tif_encodetile = PredictorEncodeTile;
267
0
        }
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
0
        if (tif->tif_flags & TIFF_SWAB)
277
0
        {
278
0
            if (sp->encodepfunc == horDiff16)
279
0
            {
280
0
                sp->encodepfunc = swabHorDiff16;
281
0
                tif->tif_postdecode = _TIFFNoPostDecode;
282
0
            }
283
0
            else if (sp->encodepfunc == horDiff32)
284
0
            {
285
0
                sp->encodepfunc = swabHorDiff32;
286
0
                tif->tif_postdecode = _TIFFNoPostDecode;
287
0
            }
288
0
            else if (sp->encodepfunc == horDiff64)
289
0
            {
290
0
                sp->encodepfunc = swabHorDiff64;
291
0
                tif->tif_postdecode = _TIFFNoPostDecode;
292
0
            }
293
0
        }
294
0
    }
295
296
0
    else if (sp->predictor == 3)
297
0
    {
298
0
        sp->encodepfunc = fpDiff;
299
        /*
300
         * Override default encoding method with one that does the
301
         * predictor stuff.
302
         */
303
0
        if (tif->tif_encoderow != PredictorEncodeRow)
304
0
        {
305
0
            sp->encoderow = tif->tif_encoderow;
306
0
            tif->tif_encoderow = PredictorEncodeRow;
307
0
            sp->encodestrip = tif->tif_encodestrip;
308
0
            tif->tif_encodestrip = PredictorEncodeTile;
309
0
            sp->encodetile = tif->tif_encodetile;
310
0
            tif->tif_encodetile = PredictorEncodeTile;
311
0
        }
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
0
        if (tif->tif_flags & TIFF_SWAB)
318
0
        {
319
0
            tif->tif_postdecode = _TIFFNoPostDecode;
320
0
        }
321
0
    }
322
323
0
    return 1;
324
0
}
325
326
#define REPEAT4(n, op)                                                         \
327
118k
    switch (n)                                                                 \
328
118k
    {                                                                          \
329
16.8k
        default:                                                               \
330
16.8k
        {                                                                      \
331
16.8k
            tmsize_t i;                                                        \
332
587k
            for (i = n - 4; i > 0; i--)                                        \
333
570k
            {                                                                  \
334
570k
                op;                                                            \
335
570k
            }                                                                  \
336
16.8k
        } /*-fallthrough*/                                                     \
337
24.5k
        case 4:                                                                \
338
24.5k
            op; /*-fallthrough*/                                               \
339
43.6k
        case 3:                                                                \
340
43.6k
            op; /*-fallthrough*/                                               \
341
90.1k
        case 2:                                                                \
342
90.1k
            op; /*-fallthrough*/                                               \
343
118k
        case 1:                                                                \
344
118k
            op; /*-fallthrough*/                                               \
345
118k
        case 0:;                                                               \
346
118k
    }
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
static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
356
27.4k
{
357
27.4k
    tmsize_t stride = PredictorState(tif)->stride;
358
359
27.4k
    uint8_t *cp = cp0;
360
27.4k
    if ((cc % stride) != 0)
361
0
    {
362
0
        TIFFErrorExtR(tif, "horAcc8", "%s", "(cc%stride)!=0");
363
0
        return 0;
364
0
    }
365
366
27.4k
    if (cc > stride)
367
22.9k
    {
368
        /*
369
         * Pipeline the most common cases.
370
         */
371
22.9k
        if (stride == 1)
372
17.0k
        {
373
17.0k
            uint32_t acc = cp[0];
374
17.0k
            tmsize_t i = stride;
375
1.58M
            for (; i < cc - 3; i += 4)
376
1.56M
            {
377
1.56M
                cp[i + 0] = (uint8_t)((acc += cp[i + 0]) & 0xff);
378
1.56M
                cp[i + 1] = (uint8_t)((acc += cp[i + 1]) & 0xff);
379
1.56M
                cp[i + 2] = (uint8_t)((acc += cp[i + 2]) & 0xff);
380
1.56M
                cp[i + 3] = (uint8_t)((acc += cp[i + 3]) & 0xff);
381
1.56M
            }
382
58.3k
            for (; i < cc; i++)
383
41.2k
            {
384
41.2k
                cp[i + 0] = (uint8_t)((acc += cp[i + 0]) & 0xff);
385
41.2k
            }
386
17.0k
        }
387
5.88k
        else if (stride == 3)
388
2.10k
        {
389
2.10k
            uint32_t cr = cp[0];
390
2.10k
            uint32_t cg = cp[1];
391
2.10k
            uint32_t cb = cp[2];
392
2.10k
            tmsize_t i = stride;
393
43.1k
            for (; i < cc; i += stride)
394
41.0k
            {
395
41.0k
                cp[i + 0] = (uint8_t)((cr += cp[i + 0]) & 0xff);
396
41.0k
                cp[i + 1] = (uint8_t)((cg += cp[i + 1]) & 0xff);
397
41.0k
                cp[i + 2] = (uint8_t)((cb += cp[i + 2]) & 0xff);
398
41.0k
            }
399
2.10k
        }
400
3.77k
        else if (stride == 4)
401
1.95k
        {
402
1.95k
            uint32_t cr = cp[0];
403
1.95k
            uint32_t cg = cp[1];
404
1.95k
            uint32_t cb = cp[2];
405
1.95k
            uint32_t ca = cp[3];
406
1.95k
            tmsize_t i = stride;
407
265k
            for (; i < cc; i += stride)
408
263k
            {
409
263k
                cp[i + 0] = (uint8_t)((cr += cp[i + 0]) & 0xff);
410
263k
                cp[i + 1] = (uint8_t)((cg += cp[i + 1]) & 0xff);
411
263k
                cp[i + 2] = (uint8_t)((cb += cp[i + 2]) & 0xff);
412
263k
                cp[i + 3] = (uint8_t)((ca += cp[i + 3]) & 0xff);
413
263k
            }
414
1.95k
        }
415
1.82k
        else
416
1.82k
        {
417
1.82k
            cc -= stride;
418
1.82k
            do
419
14.6k
            {
420
14.6k
                REPEAT4(stride,
421
14.6k
                        cp[stride] = (uint8_t)((cp[stride] + *cp) & 0xff);
422
14.6k
                        cp++)
423
14.6k
                cc -= stride;
424
14.6k
            } while (cc > 0);
425
1.82k
        }
426
22.9k
    }
427
27.4k
    return 1;
428
27.4k
}
429
430
static int swabHorAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
431
338
{
432
338
    uint16_t *wp = (uint16_t *)cp0;
433
338
    tmsize_t wc = cc / 2;
434
435
338
    TIFFSwabArrayOfShort(wp, wc);
436
338
    return horAcc16(tif, cp0, cc);
437
338
}
438
439
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
440
static int horAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
441
5.99k
{
442
5.99k
    tmsize_t stride = PredictorState(tif)->stride;
443
5.99k
    uint16_t *wp = (uint16_t *)cp0;
444
5.99k
    tmsize_t wc = cc / 2;
445
446
5.99k
    if ((cc % (2 * stride)) != 0)
447
0
    {
448
0
        TIFFErrorExtR(tif, "horAcc16", "%s", "cc%(2*stride))!=0");
449
0
        return 0;
450
0
    }
451
452
5.99k
    if (wc > stride)
453
3.51k
    {
454
3.51k
        wc -= stride;
455
3.51k
        do
456
50.1k
        {
457
50.1k
            REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] +
458
50.1k
                                                     (unsigned int)wp[0]) &
459
50.1k
                                                    0xffff);
460
50.1k
                    wp++)
461
50.1k
            wc -= stride;
462
50.1k
        } while (wc > 0);
463
3.51k
    }
464
5.99k
    return 1;
465
5.99k
}
466
467
static int swabHorAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
468
117
{
469
117
    uint32_t *wp = (uint32_t *)cp0;
470
117
    tmsize_t wc = cc / 4;
471
472
117
    TIFFSwabArrayOfLong(wp, wc);
473
117
    return horAcc32(tif, cp0, cc);
474
117
}
475
476
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
477
static int horAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
478
2.78k
{
479
2.78k
    tmsize_t stride = PredictorState(tif)->stride;
480
2.78k
    uint32_t *wp = (uint32_t *)cp0;
481
2.78k
    tmsize_t wc = cc / 4;
482
483
2.78k
    if ((cc % (4 * stride)) != 0)
484
0
    {
485
0
        TIFFErrorExtR(tif, "horAcc32", "%s", "cc%(4*stride))!=0");
486
0
        return 0;
487
0
    }
488
489
2.78k
    if (wc > stride)
490
1.62k
    {
491
1.62k
        wc -= stride;
492
1.62k
        do
493
31.4k
        {
494
31.4k
            REPEAT4(stride, wp[stride] += wp[0]; wp++)
495
31.4k
            wc -= stride;
496
31.4k
        } while (wc > 0);
497
1.62k
    }
498
2.78k
    return 1;
499
2.78k
}
500
501
static int swabHorAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
502
80
{
503
80
    uint64_t *wp = (uint64_t *)cp0;
504
80
    tmsize_t wc = cc / 8;
505
506
80
    TIFFSwabArrayOfLong8(wp, wc);
507
80
    return horAcc64(tif, cp0, cc);
508
80
}
509
510
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
511
static int horAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
512
1.30k
{
513
1.30k
    tmsize_t stride = PredictorState(tif)->stride;
514
1.30k
    uint64_t *wp = (uint64_t *)cp0;
515
1.30k
    tmsize_t wc = cc / 8;
516
517
1.30k
    if ((cc % (8 * stride)) != 0)
518
0
    {
519
0
        TIFFErrorExtR(tif, "horAcc64", "%s", "cc%(8*stride))!=0");
520
0
        return 0;
521
0
    }
522
523
1.30k
    if (wc > stride)
524
769
    {
525
769
        wc -= stride;
526
769
        do
527
3.28k
        {
528
3.28k
            REPEAT4(stride, wp[stride] += wp[0]; wp++)
529
3.28k
            wc -= stride;
530
3.28k
        } while (wc > 0);
531
769
    }
532
1.30k
    return 1;
533
1.30k
}
534
535
/*
536
 * Floating point predictor accumulation routine.
537
 */
538
static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc)
539
4.82k
{
540
4.82k
    tmsize_t stride = PredictorState(tif)->stride;
541
4.82k
    uint32_t bps = tif->tif_dir.td_bitspersample / 8;
542
4.82k
    tmsize_t wc = cc / bps;
543
4.82k
    tmsize_t count = cc;
544
4.82k
    uint8_t *cp = cp0;
545
4.82k
    uint8_t *tmp;
546
547
4.82k
    if (cc % (bps * stride) != 0)
548
0
    {
549
0
        TIFFErrorExtR(tif, "fpAcc", "%s", "cc%(bps*stride))!=0");
550
0
        return 0;
551
0
    }
552
553
4.82k
    tmp = (uint8_t *)_TIFFmallocExt(tif, cc);
554
4.82k
    if (!tmp)
555
0
        return 0;
556
557
4.82k
    if (stride == 1)
558
2.76k
    {
559
        /* Optimization of general case */
560
2.76k
#define OP                                                                     \
561
168k
    do                                                                         \
562
168k
    {                                                                          \
563
168k
        cp[1] = (uint8_t)((cp[1] + cp[0]) & 0xff);                             \
564
168k
        ++cp;                                                                  \
565
168k
    } while (0)
566
22.5k
        for (; count > 8; count -= 8)
567
19.7k
        {
568
19.7k
            OP;
569
19.7k
            OP;
570
19.7k
            OP;
571
19.7k
            OP;
572
19.7k
            OP;
573
19.7k
            OP;
574
19.7k
            OP;
575
19.7k
            OP;
576
19.7k
        }
577
12.8k
        for (; count > 1; count -= 1)
578
10.1k
        {
579
10.1k
            OP;
580
10.1k
        }
581
2.76k
#undef OP
582
2.76k
    }
583
2.06k
    else
584
2.06k
    {
585
21.1k
        while (count > stride)
586
19.1k
        {
587
19.1k
            REPEAT4(stride, cp[stride] = (uint8_t)((cp[stride] + cp[0]) & 0xff);
588
19.1k
                    cp++)
589
19.1k
            count -= stride;
590
19.1k
        }
591
2.06k
    }
592
593
4.82k
    _TIFFmemcpy(tmp, cp0, cc);
594
4.82k
    cp = (uint8_t *)cp0;
595
4.82k
    count = 0;
596
597
4.82k
#if defined(__x86_64__) || defined(_M_X64)
598
4.82k
    if (bps == 4)
599
2.20k
    {
600
        /* Optimization of general case */
601
4.89k
        for (; count + 15 < wc; count += 16)
602
2.69k
        {
603
            /* Interlace 4*16 byte values */
604
605
2.69k
            __m128i xmm0 =
606
2.69k
                _mm_loadu_si128((const __m128i *)(tmp + count + 3 * wc));
607
2.69k
            __m128i xmm1 =
608
2.69k
                _mm_loadu_si128((const __m128i *)(tmp + count + 2 * wc));
609
2.69k
            __m128i xmm2 =
610
2.69k
                _mm_loadu_si128((const __m128i *)(tmp + count + 1 * wc));
611
2.69k
            __m128i xmm3 =
612
2.69k
                _mm_loadu_si128((const __m128i *)(tmp + count + 0 * wc));
613
            /* (xmm0_0, xmm1_0, xmm0_1, xmm1_1, xmm0_2, xmm1_2, ...) */
614
2.69k
            __m128i tmp0 = _mm_unpacklo_epi8(xmm0, xmm1);
615
            /* (xmm0_8, xmm1_8, xmm0_9, xmm1_9, xmm0_10, xmm1_10, ...) */
616
2.69k
            __m128i tmp1 = _mm_unpackhi_epi8(xmm0, xmm1);
617
            /* (xmm2_0, xmm3_0, xmm2_1, xmm3_1, xmm2_2, xmm3_2, ...) */
618
2.69k
            __m128i tmp2 = _mm_unpacklo_epi8(xmm2, xmm3);
619
            /* (xmm2_8, xmm3_8, xmm2_9, xmm3_9, xmm2_10, xmm3_10, ...) */
620
2.69k
            __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
2.69k
            __m128i tmp2_0 = _mm_unpacklo_epi16(tmp0, tmp2);
624
2.69k
            __m128i tmp2_1 = _mm_unpackhi_epi16(tmp0, tmp2);
625
2.69k
            __m128i tmp2_2 = _mm_unpacklo_epi16(tmp1, tmp3);
626
2.69k
            __m128i tmp2_3 = _mm_unpackhi_epi16(tmp1, tmp3);
627
2.69k
            _mm_storeu_si128((__m128i *)(cp + 4 * count + 0 * 16), tmp2_0);
628
2.69k
            _mm_storeu_si128((__m128i *)(cp + 4 * count + 1 * 16), tmp2_1);
629
2.69k
            _mm_storeu_si128((__m128i *)(cp + 4 * count + 2 * 16), tmp2_2);
630
2.69k
            _mm_storeu_si128((__m128i *)(cp + 4 * count + 3 * 16), tmp2_3);
631
2.69k
        }
632
2.20k
    }
633
4.82k
#endif
634
635
26.9k
    for (; count < wc; count++)
636
22.0k
    {
637
22.0k
        uint32_t byte;
638
106k
        for (byte = 0; byte < bps; byte++)
639
84.6k
        {
640
#if WORDS_BIGENDIAN
641
            cp[bps * count + byte] = tmp[byte * wc + count];
642
#else
643
84.6k
            cp[bps * count + byte] = tmp[(bps - byte - 1) * wc + count];
644
84.6k
#endif
645
84.6k
        }
646
22.0k
    }
647
4.82k
    _TIFFfreeExt(tif, tmp);
648
4.82k
    return 1;
649
4.82k
}
650
651
/*
652
 * Decode a scanline and apply the predictor routine.
653
 */
654
static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0,
655
                              uint16_t s)
656
0
{
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
0
    {
665
0
        return (*sp->decodepfunc)(tif, op0, occ0);
666
0
    }
667
0
    else
668
0
        return 0;
669
0
}
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
static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0,
679
                               uint16_t s)
680
3.04k
{
681
3.04k
    TIFFPredictorState *sp = PredictorState(tif);
682
683
3.04k
    assert(sp != NULL);
684
3.04k
    assert(sp->decodetile != NULL);
685
686
3.04k
    if ((*sp->decodetile)(tif, op0, occ0, s))
687
2.31k
    {
688
2.31k
        tmsize_t rowsize = sp->rowsize;
689
2.31k
        assert(rowsize > 0);
690
2.31k
        if ((occ0 % rowsize) != 0)
691
0
        {
692
0
            TIFFErrorExtR(tif, "PredictorDecodeTile", "%s",
693
0
                          "occ0%rowsize != 0");
694
0
            return 0;
695
0
        }
696
2.31k
        assert(sp->decodepfunc != NULL);
697
44.6k
        while (occ0 > 0)
698
42.3k
        {
699
42.3k
            if (!(*sp->decodepfunc)(tif, op0, rowsize))
700
0
                return 0;
701
42.3k
            occ0 -= rowsize;
702
42.3k
            op0 += rowsize;
703
42.3k
        }
704
2.31k
        return 1;
705
2.31k
    }
706
731
    else
707
731
        return 0;
708
3.04k
}
709
710
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
711
static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
712
0
{
713
0
    TIFFPredictorState *sp = PredictorState(tif);
714
0
    tmsize_t stride = sp->stride;
715
0
    unsigned char *cp = (unsigned char *)cp0;
716
717
0
    if ((cc % stride) != 0)
718
0
    {
719
0
        TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%stride)!=0");
720
0
        return 0;
721
0
    }
722
723
0
    if (cc > stride)
724
0
    {
725
0
        cc -= stride;
726
        /*
727
         * Pipeline the most common cases.
728
         */
729
0
        if (stride == 3)
730
0
        {
731
0
            unsigned int r1, g1, b1;
732
0
            unsigned int r2 = cp[0];
733
0
            unsigned int g2 = cp[1];
734
0
            unsigned int b2 = cp[2];
735
0
            do
736
0
            {
737
0
                r1 = cp[3];
738
0
                cp[3] = (unsigned char)((r1 - r2) & 0xff);
739
0
                r2 = r1;
740
0
                g1 = cp[4];
741
0
                cp[4] = (unsigned char)((g1 - g2) & 0xff);
742
0
                g2 = g1;
743
0
                b1 = cp[5];
744
0
                cp[5] = (unsigned char)((b1 - b2) & 0xff);
745
0
                b2 = b1;
746
0
                cp += 3;
747
0
            } while ((cc -= 3) > 0);
748
0
        }
749
0
        else if (stride == 4)
750
0
        {
751
0
            unsigned int r1, g1, b1, a1;
752
0
            unsigned int r2 = cp[0];
753
0
            unsigned int g2 = cp[1];
754
0
            unsigned int b2 = cp[2];
755
0
            unsigned int a2 = cp[3];
756
0
            do
757
0
            {
758
0
                r1 = cp[4];
759
0
                cp[4] = (unsigned char)((r1 - r2) & 0xff);
760
0
                r2 = r1;
761
0
                g1 = cp[5];
762
0
                cp[5] = (unsigned char)((g1 - g2) & 0xff);
763
0
                g2 = g1;
764
0
                b1 = cp[6];
765
0
                cp[6] = (unsigned char)((b1 - b2) & 0xff);
766
0
                b2 = b1;
767
0
                a1 = cp[7];
768
0
                cp[7] = (unsigned char)((a1 - a2) & 0xff);
769
0
                a2 = a1;
770
0
                cp += 4;
771
0
            } while ((cc -= 4) > 0);
772
0
        }
773
0
        else
774
0
        {
775
0
            cp += cc - 1;
776
0
            do
777
0
            {
778
0
                REPEAT4(stride,
779
0
                        cp[stride] =
780
0
                            (unsigned char)((cp[stride] - cp[0]) & 0xff);
781
0
                        cp--)
782
0
            } while ((cc -= stride) > 0);
783
0
        }
784
0
    }
785
0
    return 1;
786
0
}
787
788
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
789
static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
790
0
{
791
0
    TIFFPredictorState *sp = PredictorState(tif);
792
0
    tmsize_t stride = sp->stride;
793
0
    uint16_t *wp = (uint16_t *)cp0;
794
0
    tmsize_t wc = cc / 2;
795
796
0
    if ((cc % (2 * stride)) != 0)
797
0
    {
798
0
        TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%(2*stride))!=0");
799
0
        return 0;
800
0
    }
801
802
0
    if (wc > stride)
803
0
    {
804
0
        wc -= stride;
805
0
        wp += wc - 1;
806
0
        do
807
0
        {
808
0
            REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] -
809
0
                                                     (unsigned int)wp[0]) &
810
0
                                                    0xffff);
811
0
                    wp--)
812
0
            wc -= stride;
813
0
        } while (wc > 0);
814
0
    }
815
0
    return 1;
816
0
}
817
818
static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
819
0
{
820
0
    uint16_t *wp = (uint16_t *)cp0;
821
0
    tmsize_t wc = cc / 2;
822
823
0
    if (!horDiff16(tif, cp0, cc))
824
0
        return 0;
825
826
0
    TIFFSwabArrayOfShort(wp, wc);
827
0
    return 1;
828
0
}
829
830
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
831
static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
832
0
{
833
0
    TIFFPredictorState *sp = PredictorState(tif);
834
0
    tmsize_t stride = sp->stride;
835
0
    uint32_t *wp = (uint32_t *)cp0;
836
0
    tmsize_t wc = cc / 4;
837
838
0
    if ((cc % (4 * stride)) != 0)
839
0
    {
840
0
        TIFFErrorExtR(tif, "horDiff32", "%s", "(cc%(4*stride))!=0");
841
0
        return 0;
842
0
    }
843
844
0
    if (wc > stride)
845
0
    {
846
0
        wc -= stride;
847
0
        wp += wc - 1;
848
0
        do
849
0
        {
850
0
            REPEAT4(stride, wp[stride] -= wp[0]; wp--)
851
0
            wc -= stride;
852
0
        } while (wc > 0);
853
0
    }
854
0
    return 1;
855
0
}
856
857
static int swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
858
0
{
859
0
    uint32_t *wp = (uint32_t *)cp0;
860
0
    tmsize_t wc = cc / 4;
861
862
0
    if (!horDiff32(tif, cp0, cc))
863
0
        return 0;
864
865
0
    TIFFSwabArrayOfLong(wp, wc);
866
0
    return 1;
867
0
}
868
869
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
870
static int horDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
871
0
{
872
0
    TIFFPredictorState *sp = PredictorState(tif);
873
0
    tmsize_t stride = sp->stride;
874
0
    uint64_t *wp = (uint64_t *)cp0;
875
0
    tmsize_t wc = cc / 8;
876
877
0
    if ((cc % (8 * stride)) != 0)
878
0
    {
879
0
        TIFFErrorExtR(tif, "horDiff64", "%s", "(cc%(8*stride))!=0");
880
0
        return 0;
881
0
    }
882
883
0
    if (wc > stride)
884
0
    {
885
0
        wc -= stride;
886
0
        wp += wc - 1;
887
0
        do
888
0
        {
889
0
            REPEAT4(stride, wp[stride] -= wp[0]; wp--)
890
0
            wc -= stride;
891
0
        } while (wc > 0);
892
0
    }
893
0
    return 1;
894
0
}
895
896
static int swabHorDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
897
0
{
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
0
}
907
908
/*
909
 * Floating point predictor differencing routine.
910
 */
911
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
912
static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc)
913
0
{
914
0
    tmsize_t stride = PredictorState(tif)->stride;
915
0
    uint32_t bps = tif->tif_dir.td_bitspersample / 8;
916
0
    tmsize_t wc = cc / bps;
917
0
    tmsize_t count;
918
0
    uint8_t *cp = (uint8_t *)cp0;
919
0
    uint8_t *tmp;
920
921
0
    if ((cc % (bps * stride)) != 0)
922
0
    {
923
0
        TIFFErrorExtR(tif, "fpDiff", "%s", "(cc%(bps*stride))!=0");
924
0
        return 0;
925
0
    }
926
927
0
    tmp = (uint8_t *)_TIFFmallocExt(tif, cc);
928
0
    if (!tmp)
929
0
        return 0;
930
931
0
    _TIFFmemcpy(tmp, cp0, cc);
932
0
    for (count = 0; count < wc; count++)
933
0
    {
934
0
        uint32_t byte;
935
0
        for (byte = 0; byte < bps; byte++)
936
0
        {
937
#if WORDS_BIGENDIAN
938
            cp[byte * wc + count] = tmp[bps * count + byte];
939
#else
940
0
            cp[(bps - byte - 1) * wc + count] = tmp[bps * count + byte];
941
0
#endif
942
0
        }
943
0
    }
944
0
    _TIFFfreeExt(tif, tmp);
945
946
0
    cp = (uint8_t *)cp0;
947
0
    cp += cc - stride - 1;
948
0
    for (count = cc; count > stride; count -= stride)
949
0
        REPEAT4(stride,
950
0
                cp[stride] = (unsigned char)((cp[stride] - cp[0]) & 0xff);
951
0
                cp--)
952
0
    return 1;
953
0
}
954
955
static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
956
0
{
957
0
    static const char module[] = "PredictorEncodeRow";
958
0
    TIFFPredictorState *sp = PredictorState(tif);
959
0
    uint8_t *working_copy;
960
0
    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
0
    {
974
0
        TIFFErrorExtR(tif, module,
975
0
                      "Out of memory allocating %" PRId64 " byte temp buffer.",
976
0
                      (int64_t)cc);
977
0
        return 0;
978
0
    }
979
0
    memcpy(working_copy, bp, cc);
980
981
0
    if (!(*sp->encodepfunc)(tif, working_copy, cc))
982
0
    {
983
0
        _TIFFfreeExt(tif, working_copy);
984
0
        return 0;
985
0
    }
986
0
    result_code = (*sp->encoderow)(tif, working_copy, cc, s);
987
0
    _TIFFfreeExt(tif, working_copy);
988
0
    return result_code;
989
0
}
990
991
static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0,
992
                               uint16_t s)
993
0
{
994
0
    static const char module[] = "PredictorEncodeTile";
995
0
    TIFFPredictorState *sp = PredictorState(tif);
996
0
    uint8_t *working_copy;
997
0
    tmsize_t cc = cc0, rowsize;
998
0
    unsigned char *bp;
999
0
    int result_code;
1000
1001
0
    assert(sp != NULL);
1002
0
    assert(sp->encodepfunc != NULL);
1003
0
    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
0
    working_copy = (uint8_t *)_TIFFmallocExt(tif, cc0);
1010
0
    if (working_copy == NULL)
1011
0
    {
1012
0
        TIFFErrorExtR(tif, module,
1013
0
                      "Out of memory allocating %" PRId64 " byte temp buffer.",
1014
0
                      (int64_t)cc0);
1015
0
        return 0;
1016
0
    }
1017
0
    memcpy(working_copy, bp0, cc0);
1018
0
    bp = working_copy;
1019
1020
0
    rowsize = sp->rowsize;
1021
0
    assert(rowsize > 0);
1022
0
    if ((cc0 % rowsize) != 0)
1023
0
    {
1024
0
        TIFFErrorExtR(tif, "PredictorEncodeTile", "%s", "(cc0%rowsize)!=0");
1025
0
        _TIFFfreeExt(tif, working_copy);
1026
0
        return 0;
1027
0
    }
1028
0
    while (cc > 0)
1029
0
    {
1030
0
        (*sp->encodepfunc)(tif, bp, rowsize);
1031
0
        cc -= rowsize;
1032
0
        bp += rowsize;
1033
0
    }
1034
0
    result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
1035
1036
0
    _TIFFfreeExt(tif, working_copy);
1037
1038
0
    return result_code;
1039
0
}
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
static int PredictorVSetField(TIFF *tif, uint32_t tag, va_list ap)
1049
92.4k
{
1050
92.4k
    TIFFPredictorState *sp = PredictorState(tif);
1051
1052
92.4k
    assert(sp != NULL);
1053
92.4k
    assert(sp->vsetparent != NULL);
1054
1055
92.4k
    switch (tag)
1056
92.4k
    {
1057
2.82k
        case TIFFTAG_PREDICTOR:
1058
2.82k
            sp->predictor = (uint16_t)va_arg(ap, uint16_vap);
1059
2.82k
            TIFFSetFieldBit(tif, FIELD_PREDICTOR);
1060
2.82k
            break;
1061
89.6k
        default:
1062
89.6k
            return (*sp->vsetparent)(tif, tag, ap);
1063
92.4k
    }
1064
2.82k
    tif->tif_flags |= TIFF_DIRTYDIRECT;
1065
2.82k
    return 1;
1066
92.4k
}
1067
1068
static int PredictorVGetField(TIFF *tif, uint32_t tag, va_list ap)
1069
218k
{
1070
218k
    TIFFPredictorState *sp = PredictorState(tif);
1071
1072
218k
    assert(sp != NULL);
1073
218k
    assert(sp->vgetparent != NULL);
1074
1075
218k
    switch (tag)
1076
218k
    {
1077
0
        case TIFFTAG_PREDICTOR:
1078
0
            *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor;
1079
0
            break;
1080
218k
        default:
1081
218k
            return (*sp->vgetparent)(tif, tag, ap);
1082
218k
    }
1083
0
    return 1;
1084
218k
}
1085
1086
static void PredictorPrintDir(TIFF *tif, FILE *fd, long flags)
1087
0
{
1088
0
    TIFFPredictorState *sp = PredictorState(tif);
1089
1090
0
    (void)flags;
1091
0
    if (TIFFFieldSet(tif, FIELD_PREDICTOR))
1092
0
    {
1093
0
        fprintf(fd, "  Predictor: ");
1094
0
        switch (sp->predictor)
1095
0
        {
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
0
        }
1108
0
        fprintf(fd, "%d (0x%x)\n", sp->predictor, (unsigned)sp->predictor);
1109
0
    }
1110
0
    if (sp->printdir)
1111
0
        (*sp->printdir)(tif, fd, flags);
1112
0
}
1113
1114
int TIFFPredictorInit(TIFF *tif)
1115
9.85k
{
1116
9.85k
    TIFFPredictorState *sp = PredictorState(tif);
1117
1118
9.85k
    assert(sp != 0);
1119
1120
    /*
1121
     * Merge codec-specific tag information.
1122
     */
1123
9.85k
    if (!_TIFFMergeFields(tif, predictFields, TIFFArrayCount(predictFields)))
1124
0
    {
1125
0
        TIFFErrorExtR(tif, "TIFFPredictorInit",
1126
0
                      "Merging Predictor codec-specific tags failed");
1127
0
        return 0;
1128
0
    }
1129
1130
    /*
1131
     * Override parent get/set field methods.
1132
     */
1133
9.85k
    sp->vgetparent = tif->tif_tagmethods.vgetfield;
1134
9.85k
    tif->tif_tagmethods.vgetfield =
1135
9.85k
        PredictorVGetField; /* hook for predictor tag */
1136
9.85k
    sp->vsetparent = tif->tif_tagmethods.vsetfield;
1137
9.85k
    tif->tif_tagmethods.vsetfield =
1138
9.85k
        PredictorVSetField; /* hook for predictor tag */
1139
9.85k
    sp->printdir = tif->tif_tagmethods.printdir;
1140
9.85k
    tif->tif_tagmethods.printdir =
1141
9.85k
        PredictorPrintDir; /* hook for predictor tag */
1142
1143
9.85k
    sp->setupdecode = tif->tif_setupdecode;
1144
9.85k
    tif->tif_setupdecode = PredictorSetupDecode;
1145
9.85k
    sp->setupencode = tif->tif_setupencode;
1146
9.85k
    tif->tif_setupencode = PredictorSetupEncode;
1147
1148
9.85k
    sp->predictor = 1;      /* default value */
1149
9.85k
    sp->encodepfunc = NULL; /* no predictor routine */
1150
9.85k
    sp->decodepfunc = NULL; /* no predictor routine */
1151
9.85k
    return 1;
1152
9.85k
}
1153
1154
int TIFFPredictorCleanup(TIFF *tif)
1155
9.85k
{
1156
9.85k
    TIFFPredictorState *sp = PredictorState(tif);
1157
1158
9.85k
    assert(sp != 0);
1159
1160
9.85k
    tif->tif_tagmethods.vgetfield = sp->vgetparent;
1161
9.85k
    tif->tif_tagmethods.vsetfield = sp->vsetparent;
1162
9.85k
    tif->tif_tagmethods.printdir = sp->printdir;
1163
9.85k
    tif->tif_setupdecode = sp->setupdecode;
1164
9.85k
    tif->tif_setupencode = sp->setupencode;
1165
1166
9.85k
    return 1;
1167
9.85k
}