Line data Source code
1 : /*
2 : * Copyright (c) 1988-1997 Sam Leffler
3 : * Copyright (c) 1991-1997 Silicon Graphics, Inc.
4 : *
5 : * Permission to use, copy, modify, distribute, and sell this software and
6 : * its documentation for any purpose is hereby granted without fee, provided
7 : * that (i) the above copyright notices and this permission notice appear in
8 : * all copies of the software and related documentation, and (ii) the names of
9 : * Sam Leffler and Silicon Graphics may not be used in any advertising or
10 : * publicity relating to the software without the specific, prior written
11 : * permission of Sam Leffler and Silicon Graphics.
12 : *
13 : * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14 : * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15 : * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16 : *
17 : * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18 : * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19 : * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 : * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21 : * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22 : * OF THIS SOFTWARE.
23 : */
24 :
25 : /*
26 : * TIFF Library.
27 : *
28 : * Predictor Tag Support (used by multiple codecs).
29 : */
30 : #include "tif_predict.h"
31 : #include "tiffiop.h"
32 :
33 : #if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC))
34 : #include <emmintrin.h>
35 : #endif
36 :
37 : #define PredictorState(tif) ((TIFFPredictorState *)(tif)->tif_data)
38 :
39 : static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc);
40 : static int horAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc);
41 : static int horAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc);
42 : static int horAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc);
43 : static int swabHorAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc);
44 : static int swabHorAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc);
45 : static int swabHorAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc);
46 : static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc);
47 : static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc);
48 : static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc);
49 : static int horDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc);
50 : static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc);
51 : static int swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc);
52 : static int swabHorDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc);
53 : static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc);
54 : static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc);
55 : static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0,
56 : uint16_t s);
57 : static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0,
58 : uint16_t s);
59 : static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
60 : static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0,
61 : uint16_t s);
62 :
63 21330 : static int PredictorSetup(TIFF *tif)
64 : {
65 : static const char module[] = "PredictorSetup";
66 :
67 21330 : TIFFPredictorState *sp = PredictorState(tif);
68 21330 : TIFFDirectory *td = &tif->tif_dir;
69 :
70 21330 : switch (sp->predictor) /* no differencing */
71 : {
72 20927 : case PREDICTOR_NONE:
73 20927 : return 1;
74 389 : case PREDICTOR_HORIZONTAL:
75 389 : if (td->td_bitspersample != 8 && td->td_bitspersample != 16 &&
76 6 : td->td_bitspersample != 32 && td->td_bitspersample != 64)
77 : {
78 0 : TIFFErrorExtR(tif, module,
79 : "Horizontal differencing \"Predictor\" not "
80 : "supported with %" PRIu16 "-bit samples",
81 0 : td->td_bitspersample);
82 0 : return 0;
83 : }
84 389 : break;
85 13 : case PREDICTOR_FLOATINGPOINT:
86 13 : if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP)
87 : {
88 0 : TIFFErrorExtR(
89 : tif, module,
90 : "Floating point \"Predictor\" not supported with %" PRIu16
91 : " data format",
92 0 : td->td_sampleformat);
93 0 : return 0;
94 : }
95 13 : if (td->td_bitspersample != 16 && td->td_bitspersample != 24 &&
96 11 : td->td_bitspersample != 32 && td->td_bitspersample != 64)
97 : { /* Should 64 be allowed? */
98 0 : TIFFErrorExtR(
99 : tif, module,
100 : "Floating point \"Predictor\" not supported with %" PRIu16
101 : "-bit samples",
102 0 : td->td_bitspersample);
103 0 : return 0;
104 : }
105 13 : break;
106 1 : default:
107 1 : TIFFErrorExtR(tif, module, "\"Predictor\" value %d not supported",
108 : sp->predictor);
109 1 : return 0;
110 : }
111 402 : sp->stride =
112 804 : (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel
113 402 : : 1);
114 : /*
115 : * Calculate the scanline/tile-width size in bytes.
116 : */
117 402 : if (isTiled(tif))
118 23 : sp->rowsize = TIFFTileRowSize(tif);
119 : else
120 379 : sp->rowsize = TIFFScanlineSize(tif);
121 402 : if (sp->rowsize == 0)
122 0 : return 0;
123 :
124 402 : return 1;
125 : }
126 :
127 3420 : static int PredictorSetupDecode(TIFF *tif)
128 : {
129 3420 : TIFFPredictorState *sp = PredictorState(tif);
130 3420 : 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 3420 : if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
136 1 : return 0;
137 :
138 3419 : if (sp->predictor == 2)
139 : {
140 97 : switch (td->td_bitspersample)
141 : {
142 77 : case 8:
143 77 : sp->decodepfunc = horAcc8;
144 77 : break;
145 17 : case 16:
146 17 : sp->decodepfunc = horAcc16;
147 17 : break;
148 2 : case 32:
149 2 : sp->decodepfunc = horAcc32;
150 2 : break;
151 1 : case 64:
152 1 : sp->decodepfunc = horAcc64;
153 1 : break;
154 0 : default:
155 0 : break;
156 : }
157 : /*
158 : * Override default decoding method with one that does the
159 : * predictor stuff.
160 : */
161 97 : if (tif->tif_decoderow != PredictorDecodeRow)
162 : {
163 97 : sp->decoderow = tif->tif_decoderow;
164 97 : tif->tif_decoderow = PredictorDecodeRow;
165 97 : sp->decodestrip = tif->tif_decodestrip;
166 97 : tif->tif_decodestrip = PredictorDecodeTile;
167 97 : sp->decodetile = tif->tif_decodetile;
168 97 : tif->tif_decodetile = PredictorDecodeTile;
169 : }
170 :
171 : /*
172 : * If the data is horizontally differenced 16-bit data that
173 : * requires byte-swapping, then it must be byte swapped before
174 : * the accumulation step. We do this with a special-purpose
175 : * routine and override the normal post decoding logic that
176 : * the library setup when the directory was read.
177 : */
178 97 : if (tif->tif_flags & TIFF_SWAB)
179 : {
180 5 : if (sp->decodepfunc == horAcc16)
181 : {
182 4 : sp->decodepfunc = swabHorAcc16;
183 4 : tif->tif_postdecode = _TIFFNoPostDecode;
184 : }
185 1 : else if (sp->decodepfunc == horAcc32)
186 : {
187 1 : sp->decodepfunc = swabHorAcc32;
188 1 : tif->tif_postdecode = _TIFFNoPostDecode;
189 : }
190 0 : else if (sp->decodepfunc == horAcc64)
191 : {
192 0 : sp->decodepfunc = swabHorAcc64;
193 0 : tif->tif_postdecode = _TIFFNoPostDecode;
194 : }
195 : }
196 : }
197 :
198 3322 : else if (sp->predictor == 3)
199 : {
200 9 : sp->decodepfunc = fpAcc;
201 : /*
202 : * Override default decoding method with one that does the
203 : * predictor stuff.
204 : */
205 9 : if (tif->tif_decoderow != PredictorDecodeRow)
206 : {
207 9 : sp->decoderow = tif->tif_decoderow;
208 9 : tif->tif_decoderow = PredictorDecodeRow;
209 9 : sp->decodestrip = tif->tif_decodestrip;
210 9 : tif->tif_decodestrip = PredictorDecodeTile;
211 9 : sp->decodetile = tif->tif_decodetile;
212 9 : tif->tif_decodetile = PredictorDecodeTile;
213 : }
214 : /*
215 : * The data should not be swapped outside of the floating
216 : * point predictor, the accumulation routine should return
217 : * bytes in the native order.
218 : */
219 9 : if (tif->tif_flags & TIFF_SWAB)
220 : {
221 2 : tif->tif_postdecode = _TIFFNoPostDecode;
222 : }
223 : }
224 :
225 3419 : return 1;
226 : }
227 :
228 17910 : static int PredictorSetupEncode(TIFF *tif)
229 : {
230 17910 : TIFFPredictorState *sp = PredictorState(tif);
231 17910 : TIFFDirectory *td = &tif->tif_dir;
232 :
233 17910 : if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
234 0 : return 0;
235 :
236 17910 : if (sp->predictor == 2)
237 : {
238 292 : switch (td->td_bitspersample)
239 : {
240 277 : case 8:
241 277 : sp->encodepfunc = horDiff8;
242 277 : break;
243 12 : case 16:
244 12 : sp->encodepfunc = horDiff16;
245 12 : break;
246 2 : case 32:
247 2 : sp->encodepfunc = horDiff32;
248 2 : break;
249 1 : case 64:
250 1 : sp->encodepfunc = horDiff64;
251 1 : break;
252 0 : default:
253 0 : break;
254 : }
255 : /*
256 : * Override default encoding method with one that does the
257 : * predictor stuff.
258 : */
259 292 : if (tif->tif_encoderow != PredictorEncodeRow)
260 : {
261 291 : sp->encoderow = tif->tif_encoderow;
262 291 : tif->tif_encoderow = PredictorEncodeRow;
263 291 : sp->encodestrip = tif->tif_encodestrip;
264 291 : tif->tif_encodestrip = PredictorEncodeTile;
265 291 : sp->encodetile = tif->tif_encodetile;
266 291 : tif->tif_encodetile = PredictorEncodeTile;
267 : }
268 :
269 : /*
270 : * If the data is horizontally differenced 16-bit data that
271 : * requires byte-swapping, then it must be byte swapped after
272 : * the differentiation step. We do this with a special-purpose
273 : * routine and override the normal post decoding logic that
274 : * the library setup when the directory was read.
275 : */
276 292 : if (tif->tif_flags & TIFF_SWAB)
277 : {
278 6 : if (sp->encodepfunc == horDiff16)
279 : {
280 5 : sp->encodepfunc = swabHorDiff16;
281 5 : tif->tif_postdecode = _TIFFNoPostDecode;
282 : }
283 1 : else if (sp->encodepfunc == horDiff32)
284 : {
285 1 : sp->encodepfunc = swabHorDiff32;
286 1 : tif->tif_postdecode = _TIFFNoPostDecode;
287 : }
288 0 : else if (sp->encodepfunc == horDiff64)
289 : {
290 0 : sp->encodepfunc = swabHorDiff64;
291 0 : tif->tif_postdecode = _TIFFNoPostDecode;
292 : }
293 : }
294 : }
295 :
296 17618 : else if (sp->predictor == 3)
297 : {
298 4 : sp->encodepfunc = fpDiff;
299 : /*
300 : * Override default encoding method with one that does the
301 : * predictor stuff.
302 : */
303 4 : if (tif->tif_encoderow != PredictorEncodeRow)
304 : {
305 4 : sp->encoderow = tif->tif_encoderow;
306 4 : tif->tif_encoderow = PredictorEncodeRow;
307 4 : sp->encodestrip = tif->tif_encodestrip;
308 4 : tif->tif_encodestrip = PredictorEncodeTile;
309 4 : sp->encodetile = tif->tif_encodetile;
310 4 : tif->tif_encodetile = PredictorEncodeTile;
311 : }
312 : /*
313 : * The data should not be swapped outside of the floating
314 : * point predictor, the differentiation routine should return
315 : * bytes in the native order.
316 : */
317 4 : if (tif->tif_flags & TIFF_SWAB)
318 : {
319 1 : tif->tif_postdecode = _TIFFNoPostDecode;
320 : }
321 : }
322 :
323 17910 : return 1;
324 : }
325 :
326 : #define REPEAT4(n, op) \
327 : switch (n) \
328 : { \
329 : default: \
330 : { \
331 : tmsize_t i; \
332 : for (i = n - 4; i > 0; i--) \
333 : { \
334 : op; \
335 : } \
336 : } /*-fallthrough*/ \
337 : case 4: \
338 : op; /*-fallthrough*/ \
339 : case 3: \
340 : op; /*-fallthrough*/ \
341 : case 2: \
342 : op; /*-fallthrough*/ \
343 : case 1: \
344 : op; /*-fallthrough*/ \
345 : case 0:; \
346 : }
347 :
348 : /* Remarks related to C standard compliance in all below functions : */
349 : /* - to avoid any undefined behavior, we only operate on unsigned types */
350 : /* since the behavior of "overflows" is defined (wrap over) */
351 : /* - when storing into the byte stream, we explicitly mask with 0xff so */
352 : /* as to make icc -check=conversions happy (not necessary by the standard) */
353 :
354 : /*
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 514708 : static void PredictorAccumulate16NativeUnaligned(uint8_t *current,
364 : const uint8_t *previous)
365 : {
366 : uint16_t thisval;
367 : uint16_t prevval;
368 514708 : memcpy(&thisval, current, sizeof(thisval));
369 514708 : memcpy(&prevval, previous, sizeof(prevval));
370 514708 : thisval =
371 514708 : (uint16_t)(((unsigned int)thisval + (unsigned int)prevval) & 0xffff);
372 514708 : memcpy(current, &thisval, sizeof(thisval));
373 514708 : }
374 :
375 : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
376 10 : static void PredictorAccumulate32NativeUnaligned(uint8_t *current,
377 : const uint8_t *previous)
378 : {
379 : uint32_t thisval;
380 : uint32_t prevval;
381 10 : memcpy(&thisval, current, sizeof(thisval));
382 10 : memcpy(&prevval, previous, sizeof(prevval));
383 10 : thisval += prevval;
384 10 : memcpy(current, &thisval, sizeof(thisval));
385 10 : }
386 :
387 : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
388 1 : static void PredictorAccumulate64NativeUnaligned(uint8_t *current,
389 : const uint8_t *previous)
390 : {
391 : uint64_t thisval;
392 : uint64_t prevval;
393 1 : memcpy(&thisval, current, sizeof(thisval));
394 1 : memcpy(&prevval, previous, sizeof(prevval));
395 1 : thisval += prevval;
396 1 : memcpy(current, &thisval, sizeof(thisval));
397 1 : }
398 :
399 245 : static void PredictorSwabByteStream16(uint8_t *cp, tmsize_t n)
400 : {
401 30514 : while (n-- > 0)
402 : {
403 30269 : uint8_t tmp = cp[0];
404 30269 : cp[0] = cp[1];
405 30269 : cp[1] = tmp;
406 30269 : cp += 2;
407 : }
408 245 : }
409 :
410 1 : static void PredictorSwabByteStream32(uint8_t *cp, tmsize_t n)
411 : {
412 7 : while (n-- > 0)
413 : {
414 6 : uint8_t tmp = cp[0];
415 6 : cp[0] = cp[3];
416 6 : cp[3] = tmp;
417 6 : tmp = cp[1];
418 6 : cp[1] = cp[2];
419 6 : cp[2] = tmp;
420 6 : cp += 4;
421 : }
422 1 : }
423 :
424 0 : static void PredictorSwabByteStream64(uint8_t *cp, tmsize_t n)
425 : {
426 0 : while (n-- > 0)
427 : {
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 : }
442 0 : }
443 :
444 : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
445 67518 : static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
446 : {
447 67518 : tmsize_t stride = PredictorState(tif)->stride;
448 :
449 67518 : uint8_t *cp = cp0;
450 67518 : if ((cc % stride) != 0)
451 : {
452 0 : TIFFErrorExtR(tif, "horAcc8", "%s", "(cc%stride)!=0");
453 0 : return 0;
454 : }
455 :
456 67518 : if (cc > stride)
457 : {
458 : /*
459 : * Pipeline the most common cases.
460 : */
461 67518 : if (stride == 1)
462 : {
463 64635 : uint32_t acc = cp[0];
464 64635 : tmsize_t i = stride;
465 4126060 : for (; i < cc - 3; i += 4)
466 : {
467 4061420 : cp[i + 0] = (uint8_t)((acc += cp[i + 0]) & 0xff);
468 4061420 : cp[i + 1] = (uint8_t)((acc += cp[i + 1]) & 0xff);
469 4061420 : cp[i + 2] = (uint8_t)((acc += cp[i + 2]) & 0xff);
470 4061420 : cp[i + 3] = (uint8_t)((acc += cp[i + 3]) & 0xff);
471 : }
472 258536 : for (; i < cc; i++)
473 : {
474 193901 : cp[i + 0] = (uint8_t)((acc += cp[i + 0]) & 0xff);
475 : }
476 : }
477 2883 : else if (stride == 3)
478 : {
479 2817 : uint32_t cr = cp[0];
480 2817 : uint32_t cg = cp[1];
481 2817 : uint32_t cb = cp[2];
482 2817 : tmsize_t i = stride;
483 299012 : for (; i < cc; i += stride)
484 : {
485 296195 : cp[i + 0] = (uint8_t)((cr += cp[i + 0]) & 0xff);
486 296195 : cp[i + 1] = (uint8_t)((cg += cp[i + 1]) & 0xff);
487 296195 : cp[i + 2] = (uint8_t)((cb += cp[i + 2]) & 0xff);
488 : }
489 : }
490 66 : else if (stride == 4)
491 : {
492 65 : uint32_t cr = cp[0];
493 65 : uint32_t cg = cp[1];
494 65 : uint32_t cb = cp[2];
495 65 : uint32_t ca = cp[3];
496 65 : tmsize_t i = stride;
497 2052 : for (; i < cc; i += stride)
498 : {
499 1987 : cp[i + 0] = (uint8_t)((cr += cp[i + 0]) & 0xff);
500 1987 : cp[i + 1] = (uint8_t)((cg += cp[i + 1]) & 0xff);
501 1987 : cp[i + 2] = (uint8_t)((cb += cp[i + 2]) & 0xff);
502 1987 : cp[i + 3] = (uint8_t)((ca += cp[i + 3]) & 0xff);
503 : }
504 : }
505 : else
506 : {
507 1 : cc -= stride;
508 : do
509 : {
510 2 : REPEAT4(stride,
511 : cp[stride] = (uint8_t)((cp[stride] + *cp) & 0xff);
512 : cp++)
513 1 : cc -= stride;
514 1 : } while (cc > 0);
515 : }
516 : }
517 67518 : return 1;
518 : }
519 :
520 245 : static int swabHorAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
521 : {
522 245 : tmsize_t wc = cc / 2;
523 :
524 245 : PredictorSwabByteStream16(cp0, wc);
525 245 : return horAcc16(tif, cp0, cc);
526 : }
527 :
528 : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
529 1736 : static int horAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
530 : {
531 1736 : tmsize_t stride = PredictorState(tif)->stride;
532 1736 : uint8_t *cp = cp0;
533 1736 : tmsize_t wc = cc / 2;
534 :
535 1736 : if ((cc % (2 * stride)) != 0)
536 : {
537 0 : TIFFErrorExtR(tif, "horAcc16", "%s", "cc%(2*stride))!=0");
538 0 : return 0;
539 : }
540 :
541 1736 : if (wc > stride)
542 : {
543 1736 : wc -= stride;
544 : do
545 : {
546 514708 : REPEAT4(stride,
547 : PredictorAccumulate16NativeUnaligned(cp + 2 * stride, cp);
548 : cp += 2)
549 514708 : wc -= stride;
550 514708 : } while (wc > 0);
551 : }
552 1736 : return 1;
553 : }
554 :
555 1 : static int swabHorAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
556 : {
557 1 : tmsize_t wc = cc / 4;
558 :
559 1 : PredictorSwabByteStream32(cp0, wc);
560 1 : return horAcc32(tif, cp0, cc);
561 : }
562 :
563 : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
564 2 : static int horAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
565 : {
566 2 : tmsize_t stride = PredictorState(tif)->stride;
567 2 : uint8_t *cp = cp0;
568 2 : tmsize_t wc = cc / 4;
569 :
570 2 : if ((cc % (4 * stride)) != 0)
571 : {
572 0 : TIFFErrorExtR(tif, "horAcc32", "%s", "cc%(4*stride))!=0");
573 0 : return 0;
574 : }
575 :
576 2 : if (wc > stride)
577 : {
578 2 : wc -= stride;
579 : do
580 : {
581 10 : REPEAT4(stride,
582 : PredictorAccumulate32NativeUnaligned(cp + 4 * stride, cp);
583 : cp += 4)
584 10 : wc -= stride;
585 10 : } while (wc > 0);
586 : }
587 2 : return 1;
588 : }
589 :
590 0 : static int swabHorAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
591 : {
592 0 : tmsize_t wc = cc / 8;
593 :
594 0 : PredictorSwabByteStream64(cp0, wc);
595 0 : return horAcc64(tif, cp0, cc);
596 : }
597 :
598 : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
599 1 : static int horAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
600 : {
601 1 : tmsize_t stride = PredictorState(tif)->stride;
602 1 : uint8_t *cp = cp0;
603 1 : tmsize_t wc = cc / 8;
604 :
605 1 : if ((cc % (8 * stride)) != 0)
606 : {
607 0 : TIFFErrorExtR(tif, "horAcc64", "%s", "cc%(8*stride))!=0");
608 0 : return 0;
609 : }
610 :
611 1 : if (wc > stride)
612 : {
613 1 : wc -= stride;
614 : do
615 : {
616 1 : REPEAT4(stride,
617 : PredictorAccumulate64NativeUnaligned(cp + 8 * stride, cp);
618 : cp += 8)
619 1 : wc -= stride;
620 1 : } while (wc > 0);
621 : }
622 1 : return 1;
623 : }
624 :
625 : /*
626 : * Floating point predictor accumulation routine.
627 : */
628 1531 : static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc)
629 : {
630 1531 : tmsize_t stride = PredictorState(tif)->stride;
631 1531 : uint32_t bps = tif->tif_dir.td_bitspersample / 8;
632 1531 : tmsize_t wc = cc / bps;
633 1531 : tmsize_t count = cc;
634 1531 : uint8_t *cp = cp0;
635 : uint8_t *tmp;
636 :
637 1531 : if (cc % (bps * stride) != 0)
638 : {
639 0 : TIFFErrorExtR(tif, "fpAcc", "%s", "cc%(bps*stride))!=0");
640 0 : return 0;
641 : }
642 :
643 1531 : tmp = (uint8_t *)_TIFFmallocExt(tif, cc);
644 1531 : if (!tmp)
645 0 : return 0;
646 :
647 1531 : if (stride == 1)
648 : {
649 : /* Optimization of general case */
650 : #define OP \
651 : do \
652 : { \
653 : cp[1] = (uint8_t)((cp[1] + cp[0]) & 0xff); \
654 : ++cp; \
655 : } while (0)
656 149205 : for (; count > 8; count -= 8)
657 : {
658 147675 : OP;
659 147675 : OP;
660 147675 : OP;
661 147675 : OP;
662 147675 : OP;
663 147675 : OP;
664 147675 : OP;
665 147675 : OP;
666 : }
667 12240 : for (; count > 1; count -= 1)
668 : {
669 10710 : OP;
670 : }
671 : #undef OP
672 : }
673 : else
674 : {
675 16 : while (count > stride)
676 : {
677 15 : REPEAT4(stride, cp[stride] = (uint8_t)((cp[stride] + cp[0]) & 0xff);
678 : cp++)
679 15 : count -= stride;
680 : }
681 : }
682 :
683 1531 : _TIFFmemcpy(tmp, cp0, cc);
684 1531 : cp = (uint8_t *)cp0;
685 1531 : count = 0;
686 :
687 : #if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC))
688 1531 : if (bps == 4)
689 : {
690 : /* Optimization of general case */
691 19425 : for (; count + 15 < wc; count += 16)
692 : {
693 : /* Interlace 4*16 byte values */
694 :
695 : __m128i xmm0 =
696 17896 : _mm_loadu_si128((const __m128i *)(tmp + count + 3 * wc));
697 : __m128i xmm1 =
698 17896 : _mm_loadu_si128((const __m128i *)(tmp + count + 2 * wc));
699 : __m128i xmm2 =
700 17896 : _mm_loadu_si128((const __m128i *)(tmp + count + 1 * wc));
701 : __m128i xmm3 =
702 35792 : _mm_loadu_si128((const __m128i *)(tmp + count + 0 * wc));
703 : /* (xmm0_0, xmm1_0, xmm0_1, xmm1_1, xmm0_2, xmm1_2, ...) */
704 17896 : __m128i tmp0 = _mm_unpacklo_epi8(xmm0, xmm1);
705 : /* (xmm0_8, xmm1_8, xmm0_9, xmm1_9, xmm0_10, xmm1_10, ...) */
706 17896 : __m128i tmp1 = _mm_unpackhi_epi8(xmm0, xmm1);
707 : /* (xmm2_0, xmm3_0, xmm2_1, xmm3_1, xmm2_2, xmm3_2, ...) */
708 17896 : __m128i tmp2 = _mm_unpacklo_epi8(xmm2, xmm3);
709 : /* (xmm2_8, xmm3_8, xmm2_9, xmm3_9, xmm2_10, xmm3_10, ...) */
710 17896 : __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 17896 : __m128i tmp2_0 = _mm_unpacklo_epi16(tmp0, tmp2);
714 17896 : __m128i tmp2_1 = _mm_unpackhi_epi16(tmp0, tmp2);
715 17896 : __m128i tmp2_2 = _mm_unpacklo_epi16(tmp1, tmp3);
716 17896 : __m128i tmp2_3 = _mm_unpackhi_epi16(tmp1, tmp3);
717 17896 : _mm_storeu_si128((__m128i *)(cp + 4 * count + 0 * 16), tmp2_0);
718 17896 : _mm_storeu_si128((__m128i *)(cp + 4 * count + 1 * 16), tmp2_1);
719 17896 : _mm_storeu_si128((__m128i *)(cp + 4 * count + 2 * 16), tmp2_2);
720 17896 : _mm_storeu_si128((__m128i *)(cp + 4 * count + 3 * 16), tmp2_3);
721 : }
722 : }
723 : #endif
724 :
725 13611 : for (; count < wc; count++)
726 : {
727 : uint32_t byte;
728 60408 : for (byte = 0; byte < bps; byte++)
729 : {
730 : #if WORDS_BIGENDIAN
731 : cp[bps * count + byte] = tmp[byte * wc + count];
732 : #else
733 48328 : cp[bps * count + byte] = tmp[(bps - byte - 1) * wc + count];
734 : #endif
735 : }
736 : }
737 1531 : _TIFFfreeExt(tif, tmp);
738 1531 : return 1;
739 : }
740 :
741 : /*
742 : * Decode a scanline and apply the predictor routine.
743 : */
744 0 : static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0,
745 : uint16_t s)
746 : {
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 : {
755 0 : return (*sp->decodepfunc)(tif, op0, occ0);
756 : }
757 : else
758 0 : return 0;
759 : }
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 488 : static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0,
769 : uint16_t s)
770 : {
771 488 : TIFFPredictorState *sp = PredictorState(tif);
772 :
773 488 : assert(sp != NULL);
774 488 : assert(sp->decodetile != NULL);
775 :
776 488 : if ((*sp->decodetile)(tif, op0, occ0, s))
777 : {
778 488 : tmsize_t rowsize = sp->rowsize;
779 488 : assert(rowsize > 0);
780 488 : if ((occ0 % rowsize) != 0)
781 : {
782 0 : TIFFErrorExtR(tif, "PredictorDecodeTile", "%s",
783 : "occ0%rowsize != 0");
784 0 : return 0;
785 : }
786 488 : assert(sp->decodepfunc != NULL);
787 71276 : while (occ0 > 0)
788 : {
789 70788 : if (!(*sp->decodepfunc)(tif, op0, rowsize))
790 0 : return 0;
791 70788 : occ0 -= rowsize;
792 70788 : op0 += rowsize;
793 : }
794 488 : return 1;
795 : }
796 : else
797 0 : return 0;
798 : }
799 :
800 : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
801 67875 : static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
802 : {
803 67875 : TIFFPredictorState *sp = PredictorState(tif);
804 67875 : tmsize_t stride = sp->stride;
805 67875 : unsigned char *cp = (unsigned char *)cp0;
806 :
807 67875 : if ((cc % stride) != 0)
808 : {
809 0 : TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%stride)!=0");
810 0 : return 0;
811 : }
812 :
813 67875 : if (cc > stride)
814 : {
815 67879 : cc -= stride;
816 : /*
817 : * Pipeline the most common cases.
818 : */
819 67879 : if (stride == 3)
820 : {
821 : unsigned int r1, g1, b1;
822 1409 : unsigned int r2 = cp[0];
823 1409 : unsigned int g2 = cp[1];
824 1409 : unsigned int b2 = cp[2];
825 : do
826 : {
827 529027 : r1 = cp[3];
828 529027 : cp[3] = (unsigned char)((r1 - r2) & 0xff);
829 529027 : r2 = r1;
830 529027 : g1 = cp[4];
831 529027 : cp[4] = (unsigned char)((g1 - g2) & 0xff);
832 529027 : g2 = g1;
833 529027 : b1 = cp[5];
834 529027 : cp[5] = (unsigned char)((b1 - b2) & 0xff);
835 529027 : b2 = b1;
836 529027 : cp += 3;
837 529027 : } while ((cc -= 3) > 0);
838 : }
839 66470 : else if (stride == 4)
840 : {
841 : unsigned int r1, g1, b1, a1;
842 33 : unsigned int r2 = cp[0];
843 33 : unsigned int g2 = cp[1];
844 33 : unsigned int b2 = cp[2];
845 33 : unsigned int a2 = cp[3];
846 : do
847 : {
848 995 : r1 = cp[4];
849 995 : cp[4] = (unsigned char)((r1 - r2) & 0xff);
850 995 : r2 = r1;
851 995 : g1 = cp[5];
852 995 : cp[5] = (unsigned char)((g1 - g2) & 0xff);
853 995 : g2 = g1;
854 995 : b1 = cp[6];
855 995 : cp[6] = (unsigned char)((b1 - b2) & 0xff);
856 995 : b2 = b1;
857 995 : a1 = cp[7];
858 995 : cp[7] = (unsigned char)((a1 - a2) & 0xff);
859 995 : a2 = a1;
860 995 : cp += 4;
861 995 : } while ((cc -= 4) > 0);
862 : }
863 : else
864 : {
865 66437 : cp += cc - 1;
866 : do
867 : {
868 10784600 : REPEAT4(stride,
869 : cp[stride] =
870 : (unsigned char)((cp[stride] - cp[0]) & 0xff);
871 : cp--)
872 10784600 : } while ((cc -= stride) > 0);
873 : }
874 : }
875 67875 : return 1;
876 : }
877 :
878 : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
879 1014 : static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
880 : {
881 1014 : TIFFPredictorState *sp = PredictorState(tif);
882 1014 : tmsize_t stride = sp->stride;
883 1014 : uint16_t *wp = (uint16_t *)cp0;
884 1014 : tmsize_t wc = cc / 2;
885 :
886 1014 : if ((cc % (2 * stride)) != 0)
887 : {
888 0 : TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%(2*stride))!=0");
889 0 : return 0;
890 : }
891 :
892 1014 : if (wc > stride)
893 : {
894 1014 : wc -= stride;
895 1014 : wp += wc - 1;
896 : do
897 : {
898 126596 : REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] -
899 : (unsigned int)wp[0]) &
900 : 0xffff);
901 : wp--)
902 126596 : wc -= stride;
903 126596 : } while (wc > 0);
904 : }
905 1014 : return 1;
906 : }
907 :
908 379 : static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc)
909 : {
910 379 : uint16_t *wp = (uint16_t *)cp0;
911 379 : tmsize_t wc = cc / 2;
912 :
913 379 : if (!horDiff16(tif, cp0, cc))
914 0 : return 0;
915 :
916 379 : TIFFSwabArrayOfShort(wp, wc);
917 379 : return 1;
918 : }
919 :
920 : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
921 2 : static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
922 : {
923 2 : TIFFPredictorState *sp = PredictorState(tif);
924 2 : tmsize_t stride = sp->stride;
925 2 : uint32_t *wp = (uint32_t *)cp0;
926 2 : tmsize_t wc = cc / 4;
927 :
928 2 : if ((cc % (4 * stride)) != 0)
929 : {
930 0 : TIFFErrorExtR(tif, "horDiff32", "%s", "(cc%(4*stride))!=0");
931 0 : return 0;
932 : }
933 :
934 2 : if (wc > stride)
935 : {
936 2 : wc -= stride;
937 2 : wp += wc - 1;
938 : do
939 : {
940 10 : REPEAT4(stride, wp[stride] -= wp[0]; wp--)
941 10 : wc -= stride;
942 10 : } while (wc > 0);
943 : }
944 2 : return 1;
945 : }
946 :
947 1 : static int swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc)
948 : {
949 1 : uint32_t *wp = (uint32_t *)cp0;
950 1 : tmsize_t wc = cc / 4;
951 :
952 1 : if (!horDiff32(tif, cp0, cc))
953 0 : return 0;
954 :
955 1 : TIFFSwabArrayOfLong(wp, wc);
956 1 : return 1;
957 : }
958 :
959 : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
960 1 : static int horDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
961 : {
962 1 : TIFFPredictorState *sp = PredictorState(tif);
963 1 : tmsize_t stride = sp->stride;
964 1 : uint64_t *wp = (uint64_t *)cp0;
965 1 : tmsize_t wc = cc / 8;
966 :
967 1 : if ((cc % (8 * stride)) != 0)
968 : {
969 0 : TIFFErrorExtR(tif, "horDiff64", "%s", "(cc%(8*stride))!=0");
970 0 : return 0;
971 : }
972 :
973 1 : if (wc > stride)
974 : {
975 1 : wc -= stride;
976 1 : wp += wc - 1;
977 : do
978 : {
979 1 : REPEAT4(stride, wp[stride] -= wp[0]; wp--)
980 1 : wc -= stride;
981 1 : } while (wc > 0);
982 : }
983 1 : return 1;
984 : }
985 :
986 0 : static int swabHorDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc)
987 : {
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 : }
997 :
998 : /*
999 : * Floating point predictor differencing routine.
1000 : */
1001 : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
1002 23 : static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc)
1003 : {
1004 23 : tmsize_t stride = PredictorState(tif)->stride;
1005 23 : uint32_t bps = tif->tif_dir.td_bitspersample / 8;
1006 23 : tmsize_t wc = cc / bps;
1007 : tmsize_t count;
1008 23 : uint8_t *cp = (uint8_t *)cp0;
1009 : uint8_t *tmp;
1010 :
1011 23 : if ((cc % (bps * stride)) != 0)
1012 : {
1013 0 : TIFFErrorExtR(tif, "fpDiff", "%s", "(cc%(bps*stride))!=0");
1014 0 : return 0;
1015 : }
1016 :
1017 23 : tmp = (uint8_t *)_TIFFmallocExt(tif, cc);
1018 23 : if (!tmp)
1019 0 : return 0;
1020 :
1021 23 : _TIFFmemcpy(tmp, cp0, cc);
1022 439 : for (count = 0; count < wc; count++)
1023 : {
1024 : uint32_t byte;
1025 2088 : for (byte = 0; byte < bps; byte++)
1026 : {
1027 : #if WORDS_BIGENDIAN
1028 : cp[byte * wc + count] = tmp[bps * count + byte];
1029 : #else
1030 1672 : cp[(bps - byte - 1) * wc + count] = tmp[bps * count + byte];
1031 : #endif
1032 : }
1033 : }
1034 23 : _TIFFfreeExt(tif, tmp);
1035 :
1036 23 : cp = (uint8_t *)cp0;
1037 23 : cp += cc - stride - 1;
1038 1656 : for (count = cc; count > stride; count -= stride)
1039 1633 : REPEAT4(stride,
1040 : cp[stride] = (unsigned char)((cp[stride] - cp[0]) & 0xff);
1041 : cp--)
1042 23 : return 1;
1043 : }
1044 :
1045 0 : static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
1046 : {
1047 : static const char module[] = "PredictorEncodeRow";
1048 0 : TIFFPredictorState *sp = PredictorState(tif);
1049 : uint8_t *working_copy;
1050 : 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 : {
1064 0 : TIFFErrorExtR(tif, module,
1065 : "Out of memory allocating %" PRId64 " byte temp buffer.",
1066 : (int64_t)cc);
1067 0 : return 0;
1068 : }
1069 0 : memcpy(working_copy, bp, (size_t)cc);
1070 :
1071 0 : if (!(*sp->encodepfunc)(tif, working_copy, cc))
1072 : {
1073 0 : _TIFFfreeExt(tif, working_copy);
1074 0 : return 0;
1075 : }
1076 0 : result_code = (*sp->encoderow)(tif, working_copy, cc, s);
1077 0 : _TIFFfreeExt(tif, working_copy);
1078 0 : return result_code;
1079 : }
1080 :
1081 315 : static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0,
1082 : uint16_t s)
1083 : {
1084 : static const char module[] = "PredictorEncodeTile";
1085 315 : TIFFPredictorState *sp = PredictorState(tif);
1086 : uint8_t *working_copy;
1087 315 : tmsize_t cc = cc0, rowsize;
1088 : unsigned char *bp;
1089 : int result_code;
1090 :
1091 315 : assert(sp != NULL);
1092 315 : assert(sp->encodepfunc != NULL);
1093 315 : 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 315 : working_copy = (uint8_t *)_TIFFmallocExt(tif, cc0);
1100 315 : if (working_copy == NULL)
1101 : {
1102 0 : TIFFErrorExtR(tif, module,
1103 : "Out of memory allocating %" PRId64 " byte temp buffer.",
1104 : (int64_t)cc0);
1105 0 : return 0;
1106 : }
1107 315 : memcpy(working_copy, bp0, (size_t)cc0);
1108 315 : bp = working_copy;
1109 :
1110 315 : rowsize = sp->rowsize;
1111 315 : assert(rowsize > 0);
1112 315 : if ((cc0 % rowsize) != 0)
1113 : {
1114 0 : TIFFErrorExtR(tif, "PredictorEncodeTile", "%s", "(cc0%rowsize)!=0");
1115 0 : _TIFFfreeExt(tif, working_copy);
1116 0 : return 0;
1117 : }
1118 68882 : while (cc > 0)
1119 : {
1120 68915 : (*sp->encodepfunc)(tif, bp, rowsize);
1121 68567 : cc -= rowsize;
1122 68567 : bp += rowsize;
1123 : }
1124 0 : result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
1125 :
1126 315 : _TIFFfreeExt(tif, working_copy);
1127 :
1128 315 : return result_code;
1129 : }
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 194172 : static int PredictorVSetField(TIFF *tif, uint32_t tag, va_list ap)
1139 : {
1140 194172 : TIFFPredictorState *sp = PredictorState(tif);
1141 :
1142 194172 : assert(sp != NULL);
1143 194172 : assert(sp->vsetparent != NULL);
1144 :
1145 194172 : switch (tag)
1146 : {
1147 7477 : case TIFFTAG_PREDICTOR:
1148 7477 : sp->predictor = (uint16_t)va_arg(ap, uint16_vap);
1149 7477 : TIFFSetFieldBit(tif, FIELD_PREDICTOR);
1150 7477 : break;
1151 186695 : default:
1152 186695 : return (*sp->vsetparent)(tif, tag, ap);
1153 : }
1154 7477 : tif->tif_flags |= TIFF_DIRTYDIRECT;
1155 7477 : return 1;
1156 : }
1157 :
1158 507345 : static int PredictorVGetField(TIFF *tif, uint32_t tag, va_list ap)
1159 : {
1160 507345 : TIFFPredictorState *sp = PredictorState(tif);
1161 :
1162 507345 : assert(sp != NULL);
1163 507345 : assert(sp->vgetparent != NULL);
1164 :
1165 507345 : switch (tag)
1166 : {
1167 22790 : case TIFFTAG_PREDICTOR:
1168 22790 : *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor;
1169 22789 : break;
1170 484555 : default:
1171 484555 : return (*sp->vgetparent)(tif, tag, ap);
1172 : }
1173 22789 : return 1;
1174 : }
1175 :
1176 0 : static void PredictorPrintDir(TIFF *tif, FILE *fd, long flags)
1177 : {
1178 0 : TIFFPredictorState *sp = PredictorState(tif);
1179 :
1180 : (void)flags;
1181 0 : if (TIFFFieldSet(tif, FIELD_PREDICTOR))
1182 : {
1183 0 : fprintf(fd, " Predictor: ");
1184 0 : switch (sp->predictor)
1185 : {
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 : }
1198 0 : fprintf(fd, "%d (0x%x)\n", sp->predictor, (unsigned)sp->predictor);
1199 : }
1200 0 : if (sp->printdir)
1201 0 : (*sp->printdir)(tif, fd, flags);
1202 0 : }
1203 :
1204 29121 : int TIFFPredictorInit(TIFF *tif)
1205 : {
1206 29121 : TIFFPredictorState *sp = PredictorState(tif);
1207 :
1208 29121 : assert(sp != 0);
1209 :
1210 : /*
1211 : * Merge codec-specific tag information.
1212 : */
1213 29121 : if (!_TIFFMergeFields(tif, predictFields, TIFFArrayCount(predictFields)))
1214 : {
1215 0 : TIFFErrorExtR(tif, "TIFFPredictorInit",
1216 : "Merging Predictor codec-specific tags failed");
1217 0 : return 0;
1218 : }
1219 :
1220 : /*
1221 : * Override parent get/set field methods.
1222 : */
1223 29122 : sp->vgetparent = tif->tif_tagmethods.vgetfield;
1224 29122 : tif->tif_tagmethods.vgetfield =
1225 : PredictorVGetField; /* hook for predictor tag */
1226 29122 : sp->vsetparent = tif->tif_tagmethods.vsetfield;
1227 29122 : tif->tif_tagmethods.vsetfield =
1228 : PredictorVSetField; /* hook for predictor tag */
1229 29122 : sp->printdir = tif->tif_tagmethods.printdir;
1230 29122 : tif->tif_tagmethods.printdir =
1231 : PredictorPrintDir; /* hook for predictor tag */
1232 :
1233 29122 : sp->setupdecode = tif->tif_setupdecode;
1234 29122 : tif->tif_setupdecode = PredictorSetupDecode;
1235 29122 : sp->setupencode = tif->tif_setupencode;
1236 29122 : tif->tif_setupencode = PredictorSetupEncode;
1237 :
1238 29122 : sp->predictor = 1; /* default value */
1239 29122 : sp->encodepfunc = NULL; /* no predictor routine */
1240 29122 : sp->decodepfunc = NULL; /* no predictor routine */
1241 29122 : return 1;
1242 : }
1243 :
1244 29117 : int TIFFPredictorCleanup(TIFF *tif)
1245 : {
1246 29117 : TIFFPredictorState *sp = PredictorState(tif);
1247 :
1248 29117 : assert(sp != 0);
1249 :
1250 29117 : tif->tif_tagmethods.vgetfield = sp->vgetparent;
1251 29117 : tif->tif_tagmethods.vsetfield = sp->vsetparent;
1252 29117 : tif->tif_tagmethods.printdir = sp->printdir;
1253 29117 : tif->tif_setupdecode = sp->setupdecode;
1254 29117 : tif->tif_setupencode = sp->setupencode;
1255 :
1256 29117 : return 1;
1257 : }
|