Coverage Report

Created: 2026-09-14 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/frmts/gtiff/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) && !defined(_M_ARM64EC))
34
#include <emmintrin.h>
35
#endif
36
37
0
#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
0
{
65
0
    static const char module[] = "PredictorSetup";
66
67
0
    TIFFPredictorState *sp = PredictorState(tif);
68
0
    TIFFDirectory *td = &tif->tif_dir;
69
70
0
    switch (sp->predictor) /* no differencing */
71
0
    {
72
0
        case PREDICTOR_NONE:
73
0
            return 1;
74
0
        case PREDICTOR_HORIZONTAL:
75
0
            if (td->td_bitspersample != 8 && td->td_bitspersample != 16 &&
76
0
                td->td_bitspersample != 32 && td->td_bitspersample != 64)
77
0
            {
78
0
                TIFFErrorExtR(tif, module,
79
0
                              "Horizontal differencing \"Predictor\" not "
80
0
                              "supported with %" PRIu16 "-bit samples",
81
0
                              td->td_bitspersample);
82
0
                return 0;
83
0
            }
84
0
            break;
85
0
        case PREDICTOR_FLOATINGPOINT:
86
0
            if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP)
87
0
            {
88
0
                TIFFErrorExtR(
89
0
                    tif, module,
90
0
                    "Floating point \"Predictor\" not supported with %" PRIu16
91
0
                    " data format",
92
0
                    td->td_sampleformat);
93
0
                return 0;
94
0
            }
95
0
            if (td->td_bitspersample != 16 && td->td_bitspersample != 24 &&
96
0
                td->td_bitspersample != 32 && td->td_bitspersample != 64)
97
0
            { /* Should 64 be allowed? */
98
0
                TIFFErrorExtR(
99
0
                    tif, module,
100
0
                    "Floating point \"Predictor\" not supported with %" PRIu16
101
0
                    "-bit samples",
102
0
                    td->td_bitspersample);
103
0
                return 0;
104
0
            }
105
0
            break;
106
0
        default:
107
0
            TIFFErrorExtR(tif, module, "\"Predictor\" value %d not supported",
108
0
                          sp->predictor);
109
0
            return 0;
110
0
    }
111
0
    sp->stride =
112
0
        (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel
113
0
                                                    : 1);
114
    /*
115
     * Calculate the scanline/tile-width size in bytes.
116
     */
117
0
    if (isTiled(tif))
118
0
        sp->rowsize = TIFFTileRowSize(tif);
119
0
    else
120
0
        sp->rowsize = TIFFScanlineSize(tif);
121
0
    if (sp->rowsize == 0)
122
0
        return 0;
123
124
0
    return 1;
125
0
}
126
127
static int PredictorSetupDecode(TIFF *tif)
128
0
{
129
0
    TIFFPredictorState *sp = PredictorState(tif);
130
0
    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
0
    if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
136
0
        return 0;
137
138
0
    if (sp->predictor == 2)
139
0
    {
140
0
        switch (td->td_bitspersample)
141
0
        {
142
0
            case 8:
143
0
                sp->decodepfunc = horAcc8;
144
0
                break;
145
0
            case 16:
146
0
                sp->decodepfunc = horAcc16;
147
0
                break;
148
0
            case 32:
149
0
                sp->decodepfunc = horAcc32;
150
0
                break;
151
0
            case 64:
152
0
                sp->decodepfunc = horAcc64;
153
0
                break;
154
0
            default:
155
0
                break;
156
0
        }
157
        /*
158
         * Override default decoding method with one that does the
159
         * predictor stuff.
160
         */
161
0
        if (tif->tif_decoderow != PredictorDecodeRow)
162
0
        {
163
0
            sp->decoderow = tif->tif_decoderow;
164
0
            tif->tif_decoderow = PredictorDecodeRow;
165
0
            sp->decodestrip = tif->tif_decodestrip;
166
0
            tif->tif_decodestrip = PredictorDecodeTile;
167
0
            sp->decodetile = tif->tif_decodetile;
168
0
            tif->tif_decodetile = PredictorDecodeTile;
169
0
        }
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
0
        if (tif->tif_flags & TIFF_SWAB)
179
0
        {
180
0
            if (sp->decodepfunc == horAcc16)
181
0
            {
182
0
                sp->decodepfunc = swabHorAcc16;
183
0
                tif->tif_postdecode = _TIFFNoPostDecode;
184
0
            }
185
0
            else if (sp->decodepfunc == horAcc32)
186
0
            {
187
0
                sp->decodepfunc = swabHorAcc32;
188
0
                tif->tif_postdecode = _TIFFNoPostDecode;
189
0
            }
190
0
            else if (sp->decodepfunc == horAcc64)
191
0
            {
192
0
                sp->decodepfunc = swabHorAcc64;
193
0
                tif->tif_postdecode = _TIFFNoPostDecode;
194
0
            }
195
0
        }
196
0
    }
197
198
0
    else if (sp->predictor == 3)
199
0
    {
200
0
        sp->decodepfunc = fpAcc;
201
        /*
202
         * Override default decoding method with one that does the
203
         * predictor stuff.
204
         */
205
0
        if (tif->tif_decoderow != PredictorDecodeRow)
206
0
        {
207
0
            sp->decoderow = tif->tif_decoderow;
208
0
            tif->tif_decoderow = PredictorDecodeRow;
209
0
            sp->decodestrip = tif->tif_decodestrip;
210
0
            tif->tif_decodestrip = PredictorDecodeTile;
211
0
            sp->decodetile = tif->tif_decodetile;
212
0
            tif->tif_decodetile = PredictorDecodeTile;
213
0
        }
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
0
        if (tif->tif_flags & TIFF_SWAB)
220
0
        {
221
0
            tif->tif_postdecode = _TIFFNoPostDecode;
222
0
        }
223
0
    }
224
225
0
    return 1;
226
0
}
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
0
    switch (n)                                                                 \
328
0
    {                                                                          \
329
0
        default:                                                               \
330
0
        {                                                                      \
331
0
            tmsize_t i;                                                        \
332
0
            for (i = n - 4; i > 0; i--)                                        \
333
0
            {                                                                  \
334
0
                op;                                                            \
335
0
            }                                                                  \
336
0
        } /*-fallthrough*/                                                     \
337
0
        case 4:                                                                \
338
0
            op; /*-fallthrough*/                                               \
339
0
        case 3:                                                                \
340
0
            op; /*-fallthrough*/                                               \
341
0
        case 2:                                                                \
342
0
            op; /*-fallthrough*/                                               \
343
0
        case 1:                                                                \
344
0
            op; /*-fallthrough*/                                               \
345
0
        case 0:;                                                               \
346
0
    }
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
/*
355
 * Predictor accumulation works on native-order samples.  If the TIFF byte
356
 * order differs from host byte order, the swab wrapper first swaps the byte
357
 * stream explicitly.  These helpers only avoid unaligned typed dereferences.
358
 * Use fixed-size memcpy() calls directly so optimizing compilers can expand
359
 * them in this per-sample hot path.  _TIFFmemcpy() is an out-of-line wrapper
360
 * in non-LTO builds.
361
 */
362
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
363
static void PredictorAccumulate16NativeUnaligned(uint8_t *current,
364
                                                 const uint8_t *previous)
365
0
{
366
0
    uint16_t thisval;
367
0
    uint16_t prevval;
368
0
    memcpy(&thisval, current, sizeof(thisval));
369
0
    memcpy(&prevval, previous, sizeof(prevval));
370
0
    thisval =
371
0
        (uint16_t)(((unsigned int)thisval + (unsigned int)prevval) & 0xffff);
372
0
    memcpy(current, &thisval, sizeof(thisval));
373
0
}
374
375
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
376
static void PredictorAccumulate32NativeUnaligned(uint8_t *current,
377
                                                 const uint8_t *previous)
378
0
{
379
0
    uint32_t thisval;
380
0
    uint32_t prevval;
381
0
    memcpy(&thisval, current, sizeof(thisval));
382
0
    memcpy(&prevval, previous, sizeof(prevval));
383
0
    thisval += prevval;
384
0
    memcpy(current, &thisval, sizeof(thisval));
385
0
}
386
387
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
388
static void PredictorAccumulate64NativeUnaligned(uint8_t *current,
389
                                                 const uint8_t *previous)
390
0
{
391
0
    uint64_t thisval;
392
0
    uint64_t prevval;
393
0
    memcpy(&thisval, current, sizeof(thisval));
394
0
    memcpy(&prevval, previous, sizeof(prevval));
395
0
    thisval += prevval;
396
0
    memcpy(current, &thisval, sizeof(thisval));
397
0
}
398
399
static void PredictorSwabByteStream16(uint8_t *cp, tmsize_t n)
400
0
{
401
0
    while (n-- > 0)
402
0
    {
403
0
        uint8_t tmp = cp[0];
404
0
        cp[0] = cp[1];
405
0
        cp[1] = tmp;
406
0
        cp += 2;
407
0
    }
408
0
}
409
410
static void PredictorSwabByteStream32(uint8_t *cp, tmsize_t n)
411
0
{
412
0
    while (n-- > 0)
413
0
    {
414
0
        uint8_t tmp = cp[0];
415
0
        cp[0] = cp[3];
416
0
        cp[3] = tmp;
417
0
        tmp = cp[1];
418
0
        cp[1] = cp[2];
419
0
        cp[2] = tmp;
420
0
        cp += 4;
421
0
    }
422
0
}
423
424
static void PredictorSwabByteStream64(uint8_t *cp, tmsize_t n)
425
0
{
426
0
    while (n-- > 0)
427
0
    {
428
0
        uint8_t tmp = cp[0];
429
0
        cp[0] = cp[7];
430
0
        cp[7] = tmp;
431
0
        tmp = cp[1];
432
0
        cp[1] = cp[6];
433
0
        cp[6] = tmp;
434
0
        tmp = cp[2];
435
0
        cp[2] = cp[5];
436
0
        cp[5] = tmp;
437
0
        tmp = cp[3];
438
0
        cp[3] = cp[4];
439
0
        cp[4] = tmp;
440
0
        cp += 8;
441
0
    }
442
0
}
443
444
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
445
static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
446
0
{
447
0
    tmsize_t stride = PredictorState(tif)->stride;
448
449
0
    uint8_t *cp = cp0;
450
0
    if ((cc % stride) != 0)
451
0
    {
452
0
        TIFFErrorExtR(tif, "horAcc8", "%s", "(cc%stride)!=0");
453
0
        return 0;
454
0
    }
455
456
0
    if (cc > stride)
457
0
    {
458
        /*
459
         * Pipeline the most common cases.
460
         */
461
0
        if (stride == 1)
462
0
        {
463
0
            uint32_t acc = cp[0];
464
0
            tmsize_t i = stride;
465
0
            for (; i < cc - 3; i += 4)
466
0
            {
467
0
                cp[i + 0] = (uint8_t)((acc += cp[i + 0]) & 0xff);
468
0
                cp[i + 1] = (uint8_t)((acc += cp[i + 1]) & 0xff);
469
0
                cp[i + 2] = (uint8_t)((acc += cp[i + 2]) & 0xff);
470
0
                cp[i + 3] = (uint8_t)((acc += cp[i + 3]) & 0xff);
471
0
            }
472
0
            for (; i < cc; i++)
473
0
            {
474
0
                cp[i + 0] = (uint8_t)((acc += cp[i + 0]) & 0xff);
475
0
            }
476
0
        }
477
0
        else if (stride == 3)
478
0
        {
479
0
            uint32_t cr = cp[0];
480
0
            uint32_t cg = cp[1];
481
0
            uint32_t cb = cp[2];
482
0
            tmsize_t i = stride;
483
0
            for (; i < cc; i += stride)
484
0
            {
485
0
                cp[i + 0] = (uint8_t)((cr += cp[i + 0]) & 0xff);
486
0
                cp[i + 1] = (uint8_t)((cg += cp[i + 1]) & 0xff);
487
0
                cp[i + 2] = (uint8_t)((cb += cp[i + 2]) & 0xff);
488
0
            }
489
0
        }
490
0
        else if (stride == 4)
491
0
        {
492
0
            uint32_t cr = cp[0];
493
0
            uint32_t cg = cp[1];
494
0
            uint32_t cb = cp[2];
495
0
            uint32_t ca = cp[3];
496
0
            tmsize_t i = stride;
497
0
            for (; i < cc; i += stride)
498
0
            {
499
0
                cp[i + 0] = (uint8_t)((cr += cp[i + 0]) & 0xff);
500
0
                cp[i + 1] = (uint8_t)((cg += cp[i + 1]) & 0xff);
501
0
                cp[i + 2] = (uint8_t)((cb += cp[i + 2]) & 0xff);
502
0
                cp[i + 3] = (uint8_t)((ca += cp[i + 3]) & 0xff);
503
0
            }
504
0
        }
505
0
        else
506
0
        {
507
0
            cc -= stride;
508
0
            do
509
0
            {
510
0
                REPEAT4(stride,
511
0
                        cp[stride] = (uint8_t)((cp[stride] + *cp) & 0xff);
512
0
                        cp++)
513
0
                cc -= stride;
514
0
            } while (cc > 0);
515
0
        }
516
0
    }
517
0
    return 1;
518
0
}
519
520
static int swabHorAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
521
0
{
522
0
    tmsize_t wc = cc / 2;
523
524
0
    PredictorSwabByteStream16(cp0, wc);
525
0
    return horAcc16(tif, cp0, cc);
526
0
}
527
528
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
529
static int horAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
530
0
{
531
0
    tmsize_t stride = PredictorState(tif)->stride;
532
0
    uint8_t *cp = cp0;
533
0
    tmsize_t wc = cc / 2;
534
535
0
    if ((cc % (2 * stride)) != 0)
536
0
    {
537
0
        TIFFErrorExtR(tif, "horAcc16", "%s", "cc%(2*stride))!=0");
538
0
        return 0;
539
0
    }
540
541
0
    if (wc > stride)
542
0
    {
543
0
        wc -= stride;
544
0
        do
545
0
        {
546
0
            REPEAT4(stride,
547
0
                    PredictorAccumulate16NativeUnaligned(cp + 2 * stride, cp);
548
0
                    cp += 2)
549
0
            wc -= stride;
550
0
        } while (wc > 0);
551
0
    }
552
0
    return 1;
553
0
}
554
555
static int swabHorAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
556
0
{
557
0
    tmsize_t wc = cc / 4;
558
559
0
    PredictorSwabByteStream32(cp0, wc);
560
0
    return horAcc32(tif, cp0, cc);
561
0
}
562
563
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
564
static int horAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
565
0
{
566
0
    tmsize_t stride = PredictorState(tif)->stride;
567
0
    uint8_t *cp = cp0;
568
0
    tmsize_t wc = cc / 4;
569
570
0
    if ((cc % (4 * stride)) != 0)
571
0
    {
572
0
        TIFFErrorExtR(tif, "horAcc32", "%s", "cc%(4*stride))!=0");
573
0
        return 0;
574
0
    }
575
576
0
    if (wc > stride)
577
0
    {
578
0
        wc -= stride;
579
0
        do
580
0
        {
581
0
            REPEAT4(stride,
582
0
                    PredictorAccumulate32NativeUnaligned(cp + 4 * stride, cp);
583
0
                    cp += 4)
584
0
            wc -= stride;
585
0
        } while (wc > 0);
586
0
    }
587
0
    return 1;
588
0
}
589
590
static int swabHorAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
591
0
{
592
0
    tmsize_t wc = cc / 8;
593
594
0
    PredictorSwabByteStream64(cp0, wc);
595
0
    return horAcc64(tif, cp0, cc);
596
0
}
597
598
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
599
static int horAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
600
0
{
601
0
    tmsize_t stride = PredictorState(tif)->stride;
602
0
    uint8_t *cp = cp0;
603
0
    tmsize_t wc = cc / 8;
604
605
0
    if ((cc % (8 * stride)) != 0)
606
0
    {
607
0
        TIFFErrorExtR(tif, "horAcc64", "%s", "cc%(8*stride))!=0");
608
0
        return 0;
609
0
    }
610
611
0
    if (wc > stride)
612
0
    {
613
0
        wc -= stride;
614
0
        do
615
0
        {
616
0
            REPEAT4(stride,
617
0
                    PredictorAccumulate64NativeUnaligned(cp + 8 * stride, cp);
618
0
                    cp += 8)
619
0
            wc -= stride;
620
0
        } while (wc > 0);
621
0
    }
622
0
    return 1;
623
0
}
624
625
/*
626
 * Floating point predictor accumulation routine.
627
 */
628
static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc)
629
0
{
630
0
    tmsize_t stride = PredictorState(tif)->stride;
631
0
    uint32_t bps = tif->tif_dir.td_bitspersample / 8;
632
0
    tmsize_t wc = cc / bps;
633
0
    tmsize_t count = cc;
634
0
    uint8_t *cp = cp0;
635
0
    uint8_t *tmp;
636
637
0
    if (cc % (bps * stride) != 0)
638
0
    {
639
0
        TIFFErrorExtR(tif, "fpAcc", "%s", "cc%(bps*stride))!=0");
640
0
        return 0;
641
0
    }
642
643
0
    tmp = (uint8_t *)_TIFFmallocExt(tif, cc);
644
0
    if (!tmp)
645
0
        return 0;
646
647
0
    if (stride == 1)
648
0
    {
649
        /* Optimization of general case */
650
0
#define OP                                                                     \
651
0
    do                                                                         \
652
0
    {                                                                          \
653
0
        cp[1] = (uint8_t)((cp[1] + cp[0]) & 0xff);                             \
654
0
        ++cp;                                                                  \
655
0
    } while (0)
656
0
        for (; count > 8; count -= 8)
657
0
        {
658
0
            OP;
659
0
            OP;
660
0
            OP;
661
0
            OP;
662
0
            OP;
663
0
            OP;
664
0
            OP;
665
0
            OP;
666
0
        }
667
0
        for (; count > 1; count -= 1)
668
0
        {
669
0
            OP;
670
0
        }
671
0
#undef OP
672
0
    }
673
0
    else
674
0
    {
675
0
        while (count > stride)
676
0
        {
677
0
            REPEAT4(stride, cp[stride] = (uint8_t)((cp[stride] + cp[0]) & 0xff);
678
0
                    cp++)
679
0
            count -= stride;
680
0
        }
681
0
    }
682
683
0
    _TIFFmemcpy(tmp, cp0, cc);
684
0
    cp = (uint8_t *)cp0;
685
0
    count = 0;
686
687
0
#if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC))
688
0
    if (bps == 4)
689
0
    {
690
        /* Optimization of general case */
691
0
        for (; count + 15 < wc; count += 16)
692
0
        {
693
            /* Interlace 4*16 byte values */
694
695
0
            __m128i xmm0 =
696
0
                _mm_loadu_si128((const __m128i *)(tmp + count + 3 * wc));
697
0
            __m128i xmm1 =
698
0
                _mm_loadu_si128((const __m128i *)(tmp + count + 2 * wc));
699
0
            __m128i xmm2 =
700
0
                _mm_loadu_si128((const __m128i *)(tmp + count + 1 * wc));
701
0
            __m128i xmm3 =
702
0
                _mm_loadu_si128((const __m128i *)(tmp + count + 0 * wc));
703
            /* (xmm0_0, xmm1_0, xmm0_1, xmm1_1, xmm0_2, xmm1_2, ...) */
704
0
            __m128i tmp0 = _mm_unpacklo_epi8(xmm0, xmm1);
705
            /* (xmm0_8, xmm1_8, xmm0_9, xmm1_9, xmm0_10, xmm1_10, ...) */
706
0
            __m128i tmp1 = _mm_unpackhi_epi8(xmm0, xmm1);
707
            /* (xmm2_0, xmm3_0, xmm2_1, xmm3_1, xmm2_2, xmm3_2, ...) */
708
0
            __m128i tmp2 = _mm_unpacklo_epi8(xmm2, xmm3);
709
            /* (xmm2_8, xmm3_8, xmm2_9, xmm3_9, xmm2_10, xmm3_10, ...) */
710
0
            __m128i tmp3 = _mm_unpackhi_epi8(xmm2, xmm3);
711
            /* (xmm0_0, xmm1_0, xmm2_0, xmm3_0, xmm0_1, xmm1_1, xmm2_1, xmm3_1,
712
             * ...) */
713
0
            __m128i tmp2_0 = _mm_unpacklo_epi16(tmp0, tmp2);
714
0
            __m128i tmp2_1 = _mm_unpackhi_epi16(tmp0, tmp2);
715
0
            __m128i tmp2_2 = _mm_unpacklo_epi16(tmp1, tmp3);
716
0
            __m128i tmp2_3 = _mm_unpackhi_epi16(tmp1, tmp3);
717
0
            _mm_storeu_si128((__m128i *)(cp + 4 * count + 0 * 16), tmp2_0);
718
0
            _mm_storeu_si128((__m128i *)(cp + 4 * count + 1 * 16), tmp2_1);
719
0
            _mm_storeu_si128((__m128i *)(cp + 4 * count + 2 * 16), tmp2_2);
720
0
            _mm_storeu_si128((__m128i *)(cp + 4 * count + 3 * 16), tmp2_3);
721
0
        }
722
0
    }
723
0
#endif
724
725
0
    for (; count < wc; count++)
726
0
    {
727
0
        uint32_t byte;
728
0
        for (byte = 0; byte < bps; byte++)
729
0
        {
730
#if WORDS_BIGENDIAN
731
            cp[bps * count + byte] = tmp[byte * wc + count];
732
#else
733
0
            cp[bps * count + byte] = tmp[(bps - byte - 1) * wc + count];
734
0
#endif
735
0
        }
736
0
    }
737
0
    _TIFFfreeExt(tif, tmp);
738
0
    return 1;
739
0
}
740
741
/*
742
 * Decode a scanline and apply the predictor routine.
743
 */
744
static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0,
745
                              uint16_t s)
746
0
{
747
0
    TIFFPredictorState *sp = PredictorState(tif);
748
749
0
    assert(sp != NULL);
750
0
    assert(sp->decoderow != NULL);
751
0
    assert(sp->decodepfunc != NULL);
752
753
0
    if ((*sp->decoderow)(tif, op0, occ0, s))
754
0
    {
755
0
        return (*sp->decodepfunc)(tif, op0, occ0);
756
0
    }
757
0
    else
758
0
        return 0;
759
0
}
760
761
/*
762
 * Decode a tile/strip and apply the predictor routine.
763
 * Note that horizontal differencing must be done on a
764
 * row-by-row basis.  The width of a "row" has already
765
 * been calculated at pre-decode time according to the
766
 * strip/tile dimensions.
767
 */
768
static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0,
769
                               uint16_t s)
770
0
{
771
0
    TIFFPredictorState *sp = PredictorState(tif);
772
773
0
    assert(sp != NULL);
774
0
    assert(sp->decodetile != NULL);
775
776
0
    if ((*sp->decodetile)(tif, op0, occ0, s))
777
0
    {
778
0
        tmsize_t rowsize = sp->rowsize;
779
0
        assert(rowsize > 0);
780
0
        if ((occ0 % rowsize) != 0)
781
0
        {
782
0
            TIFFErrorExtR(tif, "PredictorDecodeTile", "%s",
783
0
                          "occ0%rowsize != 0");
784
0
            return 0;
785
0
        }
786
0
        assert(sp->decodepfunc != NULL);
787
0
        while (occ0 > 0)
788
0
        {
789
0
            if (!(*sp->decodepfunc)(tif, op0, rowsize))
790
0
                return 0;
791
0
            occ0 -= rowsize;
792
0
            op0 += rowsize;
793
0
        }
794
0
        return 1;
795
0
    }
796
0
    else
797
0
        return 0;
798
0
}
799
800
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
801
static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
802
0
{
803
0
    TIFFPredictorState *sp = PredictorState(tif);
804
0
    tmsize_t stride = sp->stride;
805
0
    unsigned char *cp = (unsigned char *)cp0;
806
807
0
    if ((cc % stride) != 0)
808
0
    {
809
0
        TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%stride)!=0");
810
0
        return 0;
811
0
    }
812
813
0
    if (cc > stride)
814
0
    {
815
0
        cc -= stride;
816
        /*
817
         * Pipeline the most common cases.
818
         */
819
0
        if (stride == 3)
820
0
        {
821
0
            unsigned int r1, g1, b1;
822
0
            unsigned int r2 = cp[0];
823
0
            unsigned int g2 = cp[1];
824
0
            unsigned int b2 = cp[2];
825
0
            do
826
0
            {
827
0
                r1 = cp[3];
828
0
                cp[3] = (unsigned char)((r1 - r2) & 0xff);
829
0
                r2 = r1;
830
0
                g1 = cp[4];
831
0
                cp[4] = (unsigned char)((g1 - g2) & 0xff);
832
0
                g2 = g1;
833
0
                b1 = cp[5];
834
0
                cp[5] = (unsigned char)((b1 - b2) & 0xff);
835
0
                b2 = b1;
836
0
                cp += 3;
837
0
            } while ((cc -= 3) > 0);
838
0
        }
839
0
        else if (stride == 4)
840
0
        {
841
0
            unsigned int r1, g1, b1, a1;
842
0
            unsigned int r2 = cp[0];
843
0
            unsigned int g2 = cp[1];
844
0
            unsigned int b2 = cp[2];
845
0
            unsigned int a2 = cp[3];
846
0
            do
847
0
            {
848
0
                r1 = cp[4];
849
0
                cp[4] = (unsigned char)((r1 - r2) & 0xff);
850
0
                r2 = r1;
851
0
                g1 = cp[5];
852
0
                cp[5] = (unsigned char)((g1 - g2) & 0xff);
853
0
                g2 = g1;
854
0
                b1 = cp[6];
855
0
                cp[6] = (unsigned char)((b1 - b2) & 0xff);
856
0
                b2 = b1;
857
0
                a1 = cp[7];
858
0
                cp[7] = (unsigned char)((a1 - a2) & 0xff);
859
0
                a2 = a1;
860
0
                cp += 4;
861
0
            } while ((cc -= 4) > 0);
862
0
        }
863
0
        else
864
0
        {
865
0
            cp += cc - 1;
866
0
            do
867
0
            {
868
0
                REPEAT4(stride,
869
0
                        cp[stride] =
870
0
                            (unsigned char)((cp[stride] - cp[0]) & 0xff);
871
0
                        cp--)
872
0
            } while ((cc -= stride) > 0);
873
0
        }
874
0
    }
875
0
    return 1;
876
0
}
877
878
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
879
static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
880
0
{
881
0
    TIFFPredictorState *sp = PredictorState(tif);
882
0
    tmsize_t stride = sp->stride;
883
0
    uint16_t *wp = (uint16_t *)cp0;
884
0
    tmsize_t wc = cc / 2;
885
886
0
    if ((cc % (2 * stride)) != 0)
887
0
    {
888
0
        TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%(2*stride))!=0");
889
0
        return 0;
890
0
    }
891
892
0
    if (wc > stride)
893
0
    {
894
0
        wc -= stride;
895
0
        wp += wc - 1;
896
0
        do
897
0
        {
898
0
            REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] -
899
0
                                                     (unsigned int)wp[0]) &
900
0
                                                    0xffff);
901
0
                    wp--)
902
0
            wc -= stride;
903
0
        } while (wc > 0);
904
0
    }
905
0
    return 1;
906
0
}
907
908
static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
909
0
{
910
0
    uint16_t *wp = (uint16_t *)cp0;
911
0
    tmsize_t wc = cc / 2;
912
913
0
    if (!horDiff16(tif, cp0, cc))
914
0
        return 0;
915
916
0
    TIFFSwabArrayOfShort(wp, wc);
917
0
    return 1;
918
0
}
919
920
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
921
static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
922
0
{
923
0
    TIFFPredictorState *sp = PredictorState(tif);
924
0
    tmsize_t stride = sp->stride;
925
0
    uint32_t *wp = (uint32_t *)cp0;
926
0
    tmsize_t wc = cc / 4;
927
928
0
    if ((cc % (4 * stride)) != 0)
929
0
    {
930
0
        TIFFErrorExtR(tif, "horDiff32", "%s", "(cc%(4*stride))!=0");
931
0
        return 0;
932
0
    }
933
934
0
    if (wc > stride)
935
0
    {
936
0
        wc -= stride;
937
0
        wp += wc - 1;
938
0
        do
939
0
        {
940
0
            REPEAT4(stride, wp[stride] -= wp[0]; wp--)
941
0
            wc -= stride;
942
0
        } while (wc > 0);
943
0
    }
944
0
    return 1;
945
0
}
946
947
static int swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
948
0
{
949
0
    uint32_t *wp = (uint32_t *)cp0;
950
0
    tmsize_t wc = cc / 4;
951
952
0
    if (!horDiff32(tif, cp0, cc))
953
0
        return 0;
954
955
0
    TIFFSwabArrayOfLong(wp, wc);
956
0
    return 1;
957
0
}
958
959
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
960
static int horDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
961
0
{
962
0
    TIFFPredictorState *sp = PredictorState(tif);
963
0
    tmsize_t stride = sp->stride;
964
0
    uint64_t *wp = (uint64_t *)cp0;
965
0
    tmsize_t wc = cc / 8;
966
967
0
    if ((cc % (8 * stride)) != 0)
968
0
    {
969
0
        TIFFErrorExtR(tif, "horDiff64", "%s", "(cc%(8*stride))!=0");
970
0
        return 0;
971
0
    }
972
973
0
    if (wc > stride)
974
0
    {
975
0
        wc -= stride;
976
0
        wp += wc - 1;
977
0
        do
978
0
        {
979
0
            REPEAT4(stride, wp[stride] -= wp[0]; wp--)
980
0
            wc -= stride;
981
0
        } while (wc > 0);
982
0
    }
983
0
    return 1;
984
0
}
985
986
static int swabHorDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
987
0
{
988
0
    uint64_t *wp = (uint64_t *)cp0;
989
0
    tmsize_t wc = cc / 8;
990
991
0
    if (!horDiff64(tif, cp0, cc))
992
0
        return 0;
993
994
0
    TIFFSwabArrayOfLong8(wp, wc);
995
0
    return 1;
996
0
}
997
998
/*
999
 * Floating point predictor differencing routine.
1000
 */
1001
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
1002
static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc)
1003
0
{
1004
0
    tmsize_t stride = PredictorState(tif)->stride;
1005
0
    uint32_t bps = tif->tif_dir.td_bitspersample / 8;
1006
0
    tmsize_t wc = cc / bps;
1007
0
    tmsize_t count;
1008
0
    uint8_t *cp = (uint8_t *)cp0;
1009
0
    uint8_t *tmp;
1010
1011
0
    if ((cc % (bps * stride)) != 0)
1012
0
    {
1013
0
        TIFFErrorExtR(tif, "fpDiff", "%s", "(cc%(bps*stride))!=0");
1014
0
        return 0;
1015
0
    }
1016
1017
0
    tmp = (uint8_t *)_TIFFmallocExt(tif, cc);
1018
0
    if (!tmp)
1019
0
        return 0;
1020
1021
0
    _TIFFmemcpy(tmp, cp0, cc);
1022
0
    for (count = 0; count < wc; count++)
1023
0
    {
1024
0
        uint32_t byte;
1025
0
        for (byte = 0; byte < bps; byte++)
1026
0
        {
1027
#if WORDS_BIGENDIAN
1028
            cp[byte * wc + count] = tmp[bps * count + byte];
1029
#else
1030
0
            cp[(bps - byte - 1) * wc + count] = tmp[bps * count + byte];
1031
0
#endif
1032
0
        }
1033
0
    }
1034
0
    _TIFFfreeExt(tif, tmp);
1035
1036
0
    cp = (uint8_t *)cp0;
1037
0
    cp += cc - stride - 1;
1038
0
    for (count = cc; count > stride; count -= stride)
1039
0
        REPEAT4(stride,
1040
0
                cp[stride] = (unsigned char)((cp[stride] - cp[0]) & 0xff);
1041
0
                cp--)
1042
0
    return 1;
1043
0
}
1044
1045
static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
1046
0
{
1047
0
    static const char module[] = "PredictorEncodeRow";
1048
0
    TIFFPredictorState *sp = PredictorState(tif);
1049
0
    uint8_t *working_copy;
1050
0
    int result_code;
1051
1052
0
    assert(sp != NULL);
1053
0
    assert(sp->encodepfunc != NULL);
1054
0
    assert(sp->encoderow != NULL);
1055
1056
    /*
1057
     * Do predictor manipulation in a working buffer to avoid altering
1058
     * the callers buffer, like for PredictorEncodeTile().
1059
     * https://gitlab.com/libtiff/libtiff/-/issues/5
1060
     */
1061
0
    working_copy = (uint8_t *)_TIFFmallocExt(tif, cc);
1062
0
    if (working_copy == NULL)
1063
0
    {
1064
0
        TIFFErrorExtR(tif, module,
1065
0
                      "Out of memory allocating %" PRId64 " byte temp buffer.",
1066
0
                      (int64_t)cc);
1067
0
        return 0;
1068
0
    }
1069
0
    memcpy(working_copy, bp, (size_t)cc);
1070
1071
0
    if (!(*sp->encodepfunc)(tif, working_copy, cc))
1072
0
    {
1073
0
        _TIFFfreeExt(tif, working_copy);
1074
0
        return 0;
1075
0
    }
1076
0
    result_code = (*sp->encoderow)(tif, working_copy, cc, s);
1077
0
    _TIFFfreeExt(tif, working_copy);
1078
0
    return result_code;
1079
0
}
1080
1081
static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0,
1082
                               uint16_t s)
1083
0
{
1084
0
    static const char module[] = "PredictorEncodeTile";
1085
0
    TIFFPredictorState *sp = PredictorState(tif);
1086
0
    uint8_t *working_copy;
1087
0
    tmsize_t cc = cc0, rowsize;
1088
0
    unsigned char *bp;
1089
0
    int result_code;
1090
1091
0
    assert(sp != NULL);
1092
0
    assert(sp->encodepfunc != NULL);
1093
0
    assert(sp->encodetile != NULL);
1094
1095
    /*
1096
     * Do predictor manipulation in a working buffer to avoid altering
1097
     * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
1098
     */
1099
0
    working_copy = (uint8_t *)_TIFFmallocExt(tif, cc0);
1100
0
    if (working_copy == NULL)
1101
0
    {
1102
0
        TIFFErrorExtR(tif, module,
1103
0
                      "Out of memory allocating %" PRId64 " byte temp buffer.",
1104
0
                      (int64_t)cc0);
1105
0
        return 0;
1106
0
    }
1107
0
    memcpy(working_copy, bp0, (size_t)cc0);
1108
0
    bp = working_copy;
1109
1110
0
    rowsize = sp->rowsize;
1111
0
    assert(rowsize > 0);
1112
0
    if ((cc0 % rowsize) != 0)
1113
0
    {
1114
0
        TIFFErrorExtR(tif, "PredictorEncodeTile", "%s", "(cc0%rowsize)!=0");
1115
0
        _TIFFfreeExt(tif, working_copy);
1116
0
        return 0;
1117
0
    }
1118
0
    while (cc > 0)
1119
0
    {
1120
0
        (*sp->encodepfunc)(tif, bp, rowsize);
1121
0
        cc -= rowsize;
1122
0
        bp += rowsize;
1123
0
    }
1124
0
    result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
1125
1126
0
    _TIFFfreeExt(tif, working_copy);
1127
1128
0
    return result_code;
1129
0
}
1130
1131
#define FIELD_PREDICTOR (FIELD_CODEC + 0) /* XXX */
1132
1133
static const TIFFField predictFields[] = {
1134
    {TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
1135
     FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL},
1136
};
1137
1138
static int PredictorVSetField(TIFF *tif, uint32_t tag, va_list ap)
1139
0
{
1140
0
    TIFFPredictorState *sp = PredictorState(tif);
1141
1142
0
    assert(sp != NULL);
1143
0
    assert(sp->vsetparent != NULL);
1144
1145
0
    switch (tag)
1146
0
    {
1147
0
        case TIFFTAG_PREDICTOR:
1148
0
            sp->predictor = (uint16_t)va_arg(ap, uint16_vap);
1149
0
            TIFFSetFieldBit(tif, FIELD_PREDICTOR);
1150
0
            break;
1151
0
        default:
1152
0
            return (*sp->vsetparent)(tif, tag, ap);
1153
0
    }
1154
0
    tif->tif_flags |= TIFF_DIRTYDIRECT;
1155
0
    return 1;
1156
0
}
1157
1158
static int PredictorVGetField(TIFF *tif, uint32_t tag, va_list ap)
1159
0
{
1160
0
    TIFFPredictorState *sp = PredictorState(tif);
1161
1162
0
    assert(sp != NULL);
1163
0
    assert(sp->vgetparent != NULL);
1164
1165
0
    switch (tag)
1166
0
    {
1167
0
        case TIFFTAG_PREDICTOR:
1168
0
            *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor;
1169
0
            break;
1170
0
        default:
1171
0
            return (*sp->vgetparent)(tif, tag, ap);
1172
0
    }
1173
0
    return 1;
1174
0
}
1175
1176
static void PredictorPrintDir(TIFF *tif, FILE *fd, long flags)
1177
0
{
1178
0
    TIFFPredictorState *sp = PredictorState(tif);
1179
1180
0
    (void)flags;
1181
0
    if (TIFFFieldSet(tif, FIELD_PREDICTOR))
1182
0
    {
1183
0
        fprintf(fd, "  Predictor: ");
1184
0
        switch (sp->predictor)
1185
0
        {
1186
0
            case 1:
1187
0
                fprintf(fd, "none ");
1188
0
                break;
1189
0
            case 2:
1190
0
                fprintf(fd, "horizontal differencing ");
1191
0
                break;
1192
0
            case 3:
1193
0
                fprintf(fd, "floating point predictor ");
1194
0
                break;
1195
0
            default:
1196
0
                break;
1197
0
        }
1198
0
        fprintf(fd, "%d (0x%x)\n", sp->predictor, (unsigned)sp->predictor);
1199
0
    }
1200
0
    if (sp->printdir)
1201
0
        (*sp->printdir)(tif, fd, flags);
1202
0
}
1203
1204
int TIFFPredictorInit(TIFF *tif)
1205
0
{
1206
0
    TIFFPredictorState *sp = PredictorState(tif);
1207
1208
0
    assert(sp != 0);
1209
1210
    /*
1211
     * Merge codec-specific tag information.
1212
     */
1213
0
    if (!_TIFFMergeFields(tif, predictFields, TIFFArrayCount(predictFields)))
1214
0
    {
1215
0
        TIFFErrorExtR(tif, "TIFFPredictorInit",
1216
0
                      "Merging Predictor codec-specific tags failed");
1217
0
        return 0;
1218
0
    }
1219
1220
    /*
1221
     * Override parent get/set field methods.
1222
     */
1223
0
    sp->vgetparent = tif->tif_tagmethods.vgetfield;
1224
0
    tif->tif_tagmethods.vgetfield =
1225
0
        PredictorVGetField; /* hook for predictor tag */
1226
0
    sp->vsetparent = tif->tif_tagmethods.vsetfield;
1227
0
    tif->tif_tagmethods.vsetfield =
1228
0
        PredictorVSetField; /* hook for predictor tag */
1229
0
    sp->printdir = tif->tif_tagmethods.printdir;
1230
0
    tif->tif_tagmethods.printdir =
1231
0
        PredictorPrintDir; /* hook for predictor tag */
1232
1233
0
    sp->setupdecode = tif->tif_setupdecode;
1234
0
    tif->tif_setupdecode = PredictorSetupDecode;
1235
0
    sp->setupencode = tif->tif_setupencode;
1236
0
    tif->tif_setupencode = PredictorSetupEncode;
1237
1238
0
    sp->predictor = 1;      /* default value */
1239
0
    sp->encodepfunc = NULL; /* no predictor routine */
1240
0
    sp->decodepfunc = NULL; /* no predictor routine */
1241
0
    return 1;
1242
0
}
1243
1244
int TIFFPredictorCleanup(TIFF *tif)
1245
0
{
1246
0
    TIFFPredictorState *sp = PredictorState(tif);
1247
1248
0
    assert(sp != 0);
1249
1250
0
    tif->tif_tagmethods.vgetfield = sp->vgetparent;
1251
0
    tif->tif_tagmethods.vsetfield = sp->vsetparent;
1252
0
    tif->tif_tagmethods.printdir = sp->printdir;
1253
0
    tif->tif_setupdecode = sp->setupdecode;
1254
0
    tif->tif_setupencode = sp->setupencode;
1255
1256
0
    return 1;
1257
0
}