1 /* $Id: tif_predict.c,v 1.44 2017-06-18 10:31:50 erouault Exp $ */
2
3 /*
4 * Copyright (c) 1988-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and
8 * its documentation for any purpose is hereby granted without fee, provided
9 * that (i) the above copyright notices and this permission notice appear in
10 * all copies of the software and related documentation, and (ii) the names of
11 * Sam Leffler and Silicon Graphics may not be used in any advertising or
12 * publicity relating to the software without the specific, prior written
13 * permission of Sam Leffler and Silicon Graphics.
14 *
15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18 *
19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24 * OF THIS SOFTWARE.
25 */
26
27 /*
28 * TIFF Library.
29 *
30 * Predictor Tag Support (used by multiple codecs).
31 */
32 #include "tiffiop.h"
33 #include "tif_predict.h"
34
35 #define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data)
36
37 static int horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc);
38 static int horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
39 static int horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
40 static int swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
41 static int swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
42 static int horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc);
43 static int horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc);
44 static int horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc);
45 static int swabHorDiff16(TIFF* tif, uint8* cp0, tmsize_t cc);
46 static int swabHorDiff32(TIFF* tif, uint8* cp0, tmsize_t cc);
47 static int fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc);
48 static int fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc);
49 static int PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
50 static int PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
51 static int PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
52 static int PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s);
53
54 static int
PredictorSetup(TIFF * tif)55 PredictorSetup(TIFF* tif)
56 {
57 static const char module[] = "PredictorSetup";
58
59 TIFFPredictorState* sp = PredictorState(tif);
60 TIFFDirectory* td = &tif->tif_dir;
61
62 switch (sp->predictor) /* no differencing */
63 {
64 case PREDICTOR_NONE:
65 return 1;
66 case PREDICTOR_HORIZONTAL:
67 if (td->td_bitspersample != 8
68 && td->td_bitspersample != 16
69 && td->td_bitspersample != 32) {
70 TIFFErrorExt(tif->tif_clientdata, module,
71 "Horizontal differencing \"Predictor\" not supported with %d-bit samples",
72 td->td_bitspersample);
73 return 0;
74 }
75 break;
76 case PREDICTOR_FLOATINGPOINT:
77 if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) {
78 TIFFErrorExt(tif->tif_clientdata, module,
79 "Floating point \"Predictor\" not supported with %d data format",
80 td->td_sampleformat);
81 return 0;
82 }
83 if (td->td_bitspersample != 16
84 && td->td_bitspersample != 24
85 && td->td_bitspersample != 32
86 && td->td_bitspersample != 64) { /* Should 64 be allowed? */
87 TIFFErrorExt(tif->tif_clientdata, module,
88 "Floating point \"Predictor\" not supported with %d-bit samples",
89 td->td_bitspersample);
90 return 0;
91 }
92 break;
93 default:
94 TIFFErrorExt(tif->tif_clientdata, module,
95 "\"Predictor\" value %d not supported",
96 sp->predictor);
97 return 0;
98 }
99 sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
100 td->td_samplesperpixel : 1);
101 /*
102 * Calculate the scanline/tile-width size in bytes.
103 */
104 if (isTiled(tif))
105 sp->rowsize = TIFFTileRowSize(tif);
106 else
107 sp->rowsize = TIFFScanlineSize(tif);
108 if (sp->rowsize == 0)
109 return 0;
110
111 return 1;
112 }
113
114 static int
PredictorSetupDecode(TIFF * tif)115 PredictorSetupDecode(TIFF* tif)
116 {
117 TIFFPredictorState* sp = PredictorState(tif);
118 TIFFDirectory* td = &tif->tif_dir;
119
120 /* Note: when PredictorSetup() fails, the effets of setupdecode() */
121 /* will not be "cancelled" so setupdecode() might be robust to */
122 /* be called several times. */
123 if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
124 return 0;
125
126 if (sp->predictor == 2) {
127 switch (td->td_bitspersample) {
128 case 8: sp->decodepfunc = horAcc8; break;
129 case 16: sp->decodepfunc = horAcc16; break;
130 case 32: sp->decodepfunc = horAcc32; break;
131 }
132 /*
133 * Override default decoding method with one that does the
134 * predictor stuff.
135 */
136 if( tif->tif_decoderow != PredictorDecodeRow )
137 {
138 sp->decoderow = tif->tif_decoderow;
139 tif->tif_decoderow = PredictorDecodeRow;
140 sp->decodestrip = tif->tif_decodestrip;
141 tif->tif_decodestrip = PredictorDecodeTile;
142 sp->decodetile = tif->tif_decodetile;
143 tif->tif_decodetile = PredictorDecodeTile;
144 }
145
146 /*
147 * If the data is horizontally differenced 16-bit data that
148 * requires byte-swapping, then it must be byte swapped before
149 * the accumulation step. We do this with a special-purpose
150 * routine and override the normal post decoding logic that
151 * the library setup when the directory was read.
152 */
153 if (tif->tif_flags & TIFF_SWAB) {
154 if (sp->decodepfunc == horAcc16) {
155 sp->decodepfunc = swabHorAcc16;
156 tif->tif_postdecode = _TIFFNoPostDecode;
157 } else if (sp->decodepfunc == horAcc32) {
158 sp->decodepfunc = swabHorAcc32;
159 tif->tif_postdecode = _TIFFNoPostDecode;
160 }
161 }
162 }
163
164 else if (sp->predictor == 3) {
165 sp->decodepfunc = fpAcc;
166 /*
167 * Override default decoding method with one that does the
168 * predictor stuff.
169 */
170 if( tif->tif_decoderow != PredictorDecodeRow )
171 {
172 sp->decoderow = tif->tif_decoderow;
173 tif->tif_decoderow = PredictorDecodeRow;
174 sp->decodestrip = tif->tif_decodestrip;
175 tif->tif_decodestrip = PredictorDecodeTile;
176 sp->decodetile = tif->tif_decodetile;
177 tif->tif_decodetile = PredictorDecodeTile;
178 }
179 /*
180 * The data should not be swapped outside of the floating
181 * point predictor, the accumulation routine should return
182 * byres in the native order.
183 */
184 if (tif->tif_flags & TIFF_SWAB) {
185 tif->tif_postdecode = _TIFFNoPostDecode;
186 }
187 /*
188 * Allocate buffer to keep the decoded bytes before
189 * rearranging in the right order
190 */
191 }
192
193 return 1;
194 }
195
196 static int
PredictorSetupEncode(TIFF * tif)197 PredictorSetupEncode(TIFF* tif)
198 {
199 TIFFPredictorState* sp = PredictorState(tif);
200 TIFFDirectory* td = &tif->tif_dir;
201
202 if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
203 return 0;
204
205 if (sp->predictor == 2) {
206 switch (td->td_bitspersample) {
207 case 8: sp->encodepfunc = horDiff8; break;
208 case 16: sp->encodepfunc = horDiff16; break;
209 case 32: sp->encodepfunc = horDiff32; break;
210 }
211 /*
212 * Override default encoding method with one that does the
213 * predictor stuff.
214 */
215 if( tif->tif_encoderow != PredictorEncodeRow )
216 {
217 sp->encoderow = tif->tif_encoderow;
218 tif->tif_encoderow = PredictorEncodeRow;
219 sp->encodestrip = tif->tif_encodestrip;
220 tif->tif_encodestrip = PredictorEncodeTile;
221 sp->encodetile = tif->tif_encodetile;
222 tif->tif_encodetile = PredictorEncodeTile;
223 }
224
225 /*
226 * If the data is horizontally differenced 16-bit data that
227 * requires byte-swapping, then it must be byte swapped after
228 * the differentiation step. We do this with a special-purpose
229 * routine and override the normal post decoding logic that
230 * the library setup when the directory was read.
231 */
232 if (tif->tif_flags & TIFF_SWAB) {
233 if (sp->encodepfunc == horDiff16) {
234 sp->encodepfunc = swabHorDiff16;
235 tif->tif_postdecode = _TIFFNoPostDecode;
236 } else if (sp->encodepfunc == horDiff32) {
237 sp->encodepfunc = swabHorDiff32;
238 tif->tif_postdecode = _TIFFNoPostDecode;
239 }
240 }
241 }
242
243 else if (sp->predictor == 3) {
244 sp->encodepfunc = fpDiff;
245 /*
246 * Override default encoding method with one that does the
247 * predictor stuff.
248 */
249 if( tif->tif_encoderow != PredictorEncodeRow )
250 {
251 sp->encoderow = tif->tif_encoderow;
252 tif->tif_encoderow = PredictorEncodeRow;
253 sp->encodestrip = tif->tif_encodestrip;
254 tif->tif_encodestrip = PredictorEncodeTile;
255 sp->encodetile = tif->tif_encodetile;
256 tif->tif_encodetile = PredictorEncodeTile;
257 }
258 }
259
260 return 1;
261 }
262
263 #define REPEAT4(n, op) \
264 switch (n) { \
265 default: { \
266 tmsize_t i; for (i = n-4; i > 0; i--) { op; } } /*-fallthrough*/ \
267 case 4: op; /*-fallthrough*/ \
268 case 3: op; /*-fallthrough*/ \
269 case 2: op; /*-fallthrough*/ \
270 case 1: op; /*-fallthrough*/ \
271 case 0: ; \
272 }
273
274 /* Remarks related to C standard compliance in all below functions : */
275 /* - to avoid any undefined behaviour, we only operate on unsigned types */
276 /* since the behaviour of "overflows" is defined (wrap over) */
277 /* - when storing into the byte stream, we explicitly mask with 0xff so */
278 /* as to make icc -check=conversions happy (not necessary by the standard) */
279
280 TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
281 static int
horAcc8(TIFF * tif,uint8 * cp0,tmsize_t cc)282 horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc)
283 {
284 tmsize_t stride = PredictorState(tif)->stride;
285
286 unsigned char* cp = (unsigned char*) cp0;
287 if((cc%stride)!=0)
288 {
289 TIFFErrorExt(tif->tif_clientdata, "horAcc8",
290 "%s", "(cc%stride)!=0");
291 return 0;
292 }
293
294 if (cc > stride) {
295 /*
296 * Pipeline the most common cases.
297 */
298 if (stride == 3) {
299 unsigned int cr = cp[0];
300 unsigned int cg = cp[1];
301 unsigned int cb = cp[2];
302 cc -= 3;
303 cp += 3;
304 while (cc>0) {
305 cp[0] = (unsigned char) ((cr += cp[0]) & 0xff);
306 cp[1] = (unsigned char) ((cg += cp[1]) & 0xff);
307 cp[2] = (unsigned char) ((cb += cp[2]) & 0xff);
308 cc -= 3;
309 cp += 3;
310 }
311 } else if (stride == 4) {
312 unsigned int cr = cp[0];
313 unsigned int cg = cp[1];
314 unsigned int cb = cp[2];
315 unsigned int ca = cp[3];
316 cc -= 4;
317 cp += 4;
318 while (cc>0) {
319 cp[0] = (unsigned char) ((cr += cp[0]) & 0xff);
320 cp[1] = (unsigned char) ((cg += cp[1]) & 0xff);
321 cp[2] = (unsigned char) ((cb += cp[2]) & 0xff);
322 cp[3] = (unsigned char) ((ca += cp[3]) & 0xff);
323 cc -= 4;
324 cp += 4;
325 }
326 } else {
327 cc -= stride;
328 do {
329 REPEAT4(stride, cp[stride] =
330 (unsigned char) ((cp[stride] + *cp) & 0xff); cp++)
331 cc -= stride;
332 } while (cc>0);
333 }
334 }
335 return 1;
336 }
337
338 static int
swabHorAcc16(TIFF * tif,uint8 * cp0,tmsize_t cc)339 swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
340 {
341 uint16* wp = (uint16*) cp0;
342 tmsize_t wc = cc / 2;
343
344 TIFFSwabArrayOfShort(wp, wc);
345 return horAcc16(tif, cp0, cc);
346 }
347
348 TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
349 static int
horAcc16(TIFF * tif,uint8 * cp0,tmsize_t cc)350 horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
351 {
352 tmsize_t stride = PredictorState(tif)->stride;
353 uint16* wp = (uint16*) cp0;
354 tmsize_t wc = cc / 2;
355
356 if((cc%(2*stride))!=0)
357 {
358 TIFFErrorExt(tif->tif_clientdata, "horAcc16",
359 "%s", "cc%(2*stride))!=0");
360 return 0;
361 }
362
363 if (wc > stride) {
364 wc -= stride;
365 do {
366 REPEAT4(stride, wp[stride] = (uint16)(((unsigned int)wp[stride] + (unsigned int)wp[0]) & 0xffff); wp++)
367 wc -= stride;
368 } while (wc > 0);
369 }
370 return 1;
371 }
372
373 static int
swabHorAcc32(TIFF * tif,uint8 * cp0,tmsize_t cc)374 swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
375 {
376 uint32* wp = (uint32*) cp0;
377 tmsize_t wc = cc / 4;
378
379 TIFFSwabArrayOfLong(wp, wc);
380 return horAcc32(tif, cp0, cc);
381 }
382
383 TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
384 static int
horAcc32(TIFF * tif,uint8 * cp0,tmsize_t cc)385 horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
386 {
387 tmsize_t stride = PredictorState(tif)->stride;
388 uint32* wp = (uint32*) cp0;
389 tmsize_t wc = cc / 4;
390
391 if((cc%(4*stride))!=0)
392 {
393 TIFFErrorExt(tif->tif_clientdata, "horAcc32",
394 "%s", "cc%(4*stride))!=0");
395 return 0;
396 }
397
398 if (wc > stride) {
399 wc -= stride;
400 do {
401 REPEAT4(stride, wp[stride] += wp[0]; wp++)
402 wc -= stride;
403 } while (wc > 0);
404 }
405 return 1;
406 }
407
408 /*
409 * Floating point predictor accumulation routine.
410 */
411 static int
fpAcc(TIFF * tif,uint8 * cp0,tmsize_t cc)412 fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc)
413 {
414 tmsize_t stride = PredictorState(tif)->stride;
415 uint32 bps = tif->tif_dir.td_bitspersample / 8;
416 tmsize_t wc = cc / bps;
417 tmsize_t count = cc;
418 uint8 *cp = (uint8 *) cp0;
419 uint8 *tmp;
420
421 if(cc%(bps*stride)!=0)
422 {
423 TIFFErrorExt(tif->tif_clientdata, "fpAcc",
424 "%s", "cc%(bps*stride))!=0");
425 return 0;
426 }
427
428 tmp = (uint8 *)_TIFFmalloc(cc);
429 if (!tmp)
430 return 0;
431
432 while (count > stride) {
433 REPEAT4(stride, cp[stride] =
434 (unsigned char) ((cp[stride] + cp[0]) & 0xff); cp++)
435 count -= stride;
436 }
437
438 _TIFFmemcpy(tmp, cp0, cc);
439 cp = (uint8 *) cp0;
440 for (count = 0; count < wc; count++) {
441 uint32 byte;
442 for (byte = 0; byte < bps; byte++) {
443 #if WORDS_BIGENDIAN
444 cp[bps * count + byte] = tmp[byte * wc + count];
445 #else
446 cp[bps * count + byte] =
447 tmp[(bps - byte - 1) * wc + count];
448 #endif
449 }
450 }
451 _TIFFfree(tmp);
452 return 1;
453 }
454
455 /*
456 * Decode a scanline and apply the predictor routine.
457 */
458 static int
PredictorDecodeRow(TIFF * tif,uint8 * op0,tmsize_t occ0,uint16 s)459 PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
460 {
461 TIFFPredictorState *sp = PredictorState(tif);
462
463 assert(sp != NULL);
464 assert(sp->decoderow != NULL);
465 assert(sp->decodepfunc != NULL);
466
467 if ((*sp->decoderow)(tif, op0, occ0, s)) {
468 return (*sp->decodepfunc)(tif, op0, occ0);
469 } else
470 return 0;
471 }
472
473 /*
474 * Decode a tile/strip and apply the predictor routine.
475 * Note that horizontal differencing must be done on a
476 * row-by-row basis. The width of a "row" has already
477 * been calculated at pre-decode time according to the
478 * strip/tile dimensions.
479 */
480 static int
PredictorDecodeTile(TIFF * tif,uint8 * op0,tmsize_t occ0,uint16 s)481 PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
482 {
483 TIFFPredictorState *sp = PredictorState(tif);
484
485 assert(sp != NULL);
486 assert(sp->decodetile != NULL);
487
488 if ((*sp->decodetile)(tif, op0, occ0, s)) {
489 tmsize_t rowsize = sp->rowsize;
490 assert(rowsize > 0);
491 if((occ0%rowsize) !=0)
492 {
493 TIFFErrorExt(tif->tif_clientdata, "PredictorDecodeTile",
494 "%s", "occ0%rowsize != 0");
495 return 0;
496 }
497 assert(sp->decodepfunc != NULL);
498 while (occ0 > 0) {
499 if( !(*sp->decodepfunc)(tif, op0, rowsize) )
500 return 0;
501 occ0 -= rowsize;
502 op0 += rowsize;
503 }
504 return 1;
505 } else
506 return 0;
507 }
508
509 TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
510 static int
horDiff8(TIFF * tif,uint8 * cp0,tmsize_t cc)511 horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc)
512 {
513 TIFFPredictorState* sp = PredictorState(tif);
514 tmsize_t stride = sp->stride;
515 unsigned char* cp = (unsigned char*) cp0;
516
517 if((cc%stride)!=0)
518 {
519 TIFFErrorExt(tif->tif_clientdata, "horDiff8",
520 "%s", "(cc%stride)!=0");
521 return 0;
522 }
523
524 if (cc > stride) {
525 cc -= stride;
526 /*
527 * Pipeline the most common cases.
528 */
529 if (stride == 3) {
530 unsigned int r1, g1, b1;
531 unsigned int r2 = cp[0];
532 unsigned int g2 = cp[1];
533 unsigned int b2 = cp[2];
534 do {
535 r1 = cp[3]; cp[3] = (unsigned char)((r1-r2)&0xff); r2 = r1;
536 g1 = cp[4]; cp[4] = (unsigned char)((g1-g2)&0xff); g2 = g1;
537 b1 = cp[5]; cp[5] = (unsigned char)((b1-b2)&0xff); b2 = b1;
538 cp += 3;
539 } while ((cc -= 3) > 0);
540 } else if (stride == 4) {
541 unsigned int r1, g1, b1, a1;
542 unsigned int r2 = cp[0];
543 unsigned int g2 = cp[1];
544 unsigned int b2 = cp[2];
545 unsigned int a2 = cp[3];
546 do {
547 r1 = cp[4]; cp[4] = (unsigned char)((r1-r2)&0xff); r2 = r1;
548 g1 = cp[5]; cp[5] = (unsigned char)((g1-g2)&0xff); g2 = g1;
549 b1 = cp[6]; cp[6] = (unsigned char)((b1-b2)&0xff); b2 = b1;
550 a1 = cp[7]; cp[7] = (unsigned char)((a1-a2)&0xff); a2 = a1;
551 cp += 4;
552 } while ((cc -= 4) > 0);
553 } else {
554 cp += cc - 1;
555 do {
556 REPEAT4(stride, cp[stride] = (unsigned char)((cp[stride] - cp[0])&0xff); cp--)
557 } while ((cc -= stride) > 0);
558 }
559 }
560 return 1;
561 }
562
563 TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
564 static int
horDiff16(TIFF * tif,uint8 * cp0,tmsize_t cc)565 horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc)
566 {
567 TIFFPredictorState* sp = PredictorState(tif);
568 tmsize_t stride = sp->stride;
569 uint16 *wp = (uint16*) cp0;
570 tmsize_t wc = cc/2;
571
572 if((cc%(2*stride))!=0)
573 {
574 TIFFErrorExt(tif->tif_clientdata, "horDiff8",
575 "%s", "(cc%(2*stride))!=0");
576 return 0;
577 }
578
579 if (wc > stride) {
580 wc -= stride;
581 wp += wc - 1;
582 do {
583 REPEAT4(stride, wp[stride] = (uint16)(((unsigned int)wp[stride] - (unsigned int)wp[0]) & 0xffff); wp--)
584 wc -= stride;
585 } while (wc > 0);
586 }
587 return 1;
588 }
589
590 static int
swabHorDiff16(TIFF * tif,uint8 * cp0,tmsize_t cc)591 swabHorDiff16(TIFF* tif, uint8* cp0, tmsize_t cc)
592 {
593 uint16* wp = (uint16*) cp0;
594 tmsize_t wc = cc / 2;
595
596 if( !horDiff16(tif, cp0, cc) )
597 return 0;
598
599 TIFFSwabArrayOfShort(wp, wc);
600 return 1;
601 }
602
603 TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
604 static int
horDiff32(TIFF * tif,uint8 * cp0,tmsize_t cc)605 horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
606 {
607 TIFFPredictorState* sp = PredictorState(tif);
608 tmsize_t stride = sp->stride;
609 uint32 *wp = (uint32*) cp0;
610 tmsize_t wc = cc/4;
611
612 if((cc%(4*stride))!=0)
613 {
614 TIFFErrorExt(tif->tif_clientdata, "horDiff32",
615 "%s", "(cc%(4*stride))!=0");
616 return 0;
617 }
618
619 if (wc > stride) {
620 wc -= stride;
621 wp += wc - 1;
622 do {
623 REPEAT4(stride, wp[stride] -= wp[0]; wp--)
624 wc -= stride;
625 } while (wc > 0);
626 }
627 return 1;
628 }
629
630 static int
swabHorDiff32(TIFF * tif,uint8 * cp0,tmsize_t cc)631 swabHorDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
632 {
633 uint32* wp = (uint32*) cp0;
634 tmsize_t wc = cc / 4;
635
636 if( !horDiff32(tif, cp0, cc) )
637 return 0;
638
639 TIFFSwabArrayOfLong(wp, wc);
640 return 1;
641 }
642
643 /*
644 * Floating point predictor differencing routine.
645 */
646 TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
647 static int
fpDiff(TIFF * tif,uint8 * cp0,tmsize_t cc)648 fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc)
649 {
650 tmsize_t stride = PredictorState(tif)->stride;
651 uint32 bps = tif->tif_dir.td_bitspersample / 8;
652 tmsize_t wc = cc / bps;
653 tmsize_t count;
654 uint8 *cp = (uint8 *) cp0;
655 uint8 *tmp;
656
657 if((cc%(bps*stride))!=0)
658 {
659 TIFFErrorExt(tif->tif_clientdata, "fpDiff",
660 "%s", "(cc%(bps*stride))!=0");
661 return 0;
662 }
663
664 tmp = (uint8 *)_TIFFmalloc(cc);
665 if (!tmp)
666 return 0;
667
668 _TIFFmemcpy(tmp, cp0, cc);
669 for (count = 0; count < wc; count++) {
670 uint32 byte;
671 for (byte = 0; byte < bps; byte++) {
672 #if WORDS_BIGENDIAN
673 cp[byte * wc + count] = tmp[bps * count + byte];
674 #else
675 cp[(bps - byte - 1) * wc + count] =
676 tmp[bps * count + byte];
677 #endif
678 }
679 }
680 _TIFFfree(tmp);
681
682 cp = (uint8 *) cp0;
683 cp += cc - stride - 1;
684 for (count = cc; count > stride; count -= stride)
685 REPEAT4(stride, cp[stride] = (unsigned char)((cp[stride] - cp[0])&0xff); cp--)
686 return 1;
687 }
688
689 static int
PredictorEncodeRow(TIFF * tif,uint8 * bp,tmsize_t cc,uint16 s)690 PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
691 {
692 TIFFPredictorState *sp = PredictorState(tif);
693
694 assert(sp != NULL);
695 assert(sp->encodepfunc != NULL);
696 assert(sp->encoderow != NULL);
697
698 /* XXX horizontal differencing alters user's data XXX */
699 if( !(*sp->encodepfunc)(tif, bp, cc) )
700 return 0;
701 return (*sp->encoderow)(tif, bp, cc, s);
702 }
703
704 static int
PredictorEncodeTile(TIFF * tif,uint8 * bp0,tmsize_t cc0,uint16 s)705 PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s)
706 {
707 static const char module[] = "PredictorEncodeTile";
708 TIFFPredictorState *sp = PredictorState(tif);
709 uint8 *working_copy;
710 tmsize_t cc = cc0, rowsize;
711 unsigned char* bp;
712 int result_code;
713
714 assert(sp != NULL);
715 assert(sp->encodepfunc != NULL);
716 assert(sp->encodetile != NULL);
717
718 /*
719 * Do predictor manipulation in a working buffer to avoid altering
720 * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
721 */
722 working_copy = (uint8*) _TIFFmalloc(cc0);
723 if( working_copy == NULL )
724 {
725 TIFFErrorExt(tif->tif_clientdata, module,
726 "Out of memory allocating " TIFF_SSIZE_FORMAT " byte temp buffer.",
727 cc0 );
728 return 0;
729 }
730 memcpy( working_copy, bp0, cc0 );
731 bp = working_copy;
732
733 rowsize = sp->rowsize;
734 assert(rowsize > 0);
735 if((cc0%rowsize)!=0)
736 {
737 TIFFErrorExt(tif->tif_clientdata, "PredictorEncodeTile",
738 "%s", "(cc0%rowsize)!=0");
739 _TIFFfree( working_copy );
740 return 0;
741 }
742 while (cc > 0) {
743 (*sp->encodepfunc)(tif, bp, rowsize);
744 cc -= rowsize;
745 bp += rowsize;
746 }
747 result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
748
749 _TIFFfree( working_copy );
750
751 return result_code;
752 }
753
754 #define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */
755
756 static const TIFFField predictFields[] = {
757 { TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL },
758 };
759
760 static int
PredictorVSetField(TIFF * tif,uint32 tag,va_list ap)761 PredictorVSetField(TIFF* tif, uint32 tag, va_list ap)
762 {
763 TIFFPredictorState *sp = PredictorState(tif);
764
765 assert(sp != NULL);
766 assert(sp->vsetparent != NULL);
767
768 switch (tag) {
769 case TIFFTAG_PREDICTOR:
770 sp->predictor = (uint16) va_arg(ap, uint16_vap);
771 TIFFSetFieldBit(tif, FIELD_PREDICTOR);
772 break;
773 default:
774 return (*sp->vsetparent)(tif, tag, ap);
775 }
776 tif->tif_flags |= TIFF_DIRTYDIRECT;
777 return 1;
778 }
779
780 static int
PredictorVGetField(TIFF * tif,uint32 tag,va_list ap)781 PredictorVGetField(TIFF* tif, uint32 tag, va_list ap)
782 {
783 TIFFPredictorState *sp = PredictorState(tif);
784
785 assert(sp != NULL);
786 assert(sp->vgetparent != NULL);
787
788 switch (tag) {
789 case TIFFTAG_PREDICTOR:
790 *va_arg(ap, uint16*) = (uint16)sp->predictor;
791 break;
792 default:
793 return (*sp->vgetparent)(tif, tag, ap);
794 }
795 return 1;
796 }
797
798 static void
PredictorPrintDir(TIFF * tif,FILE * fd,long flags)799 PredictorPrintDir(TIFF* tif, FILE* fd, long flags)
800 {
801 TIFFPredictorState* sp = PredictorState(tif);
802
803 (void) flags;
804 if (TIFFFieldSet(tif,FIELD_PREDICTOR)) {
805 fprintf(fd, " Predictor: ");
806 switch (sp->predictor) {
807 case 1: fprintf(fd, "none "); break;
808 case 2: fprintf(fd, "horizontal differencing "); break;
809 case 3: fprintf(fd, "floating point predictor "); break;
810 }
811 fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor);
812 }
813 if (sp->printdir)
814 (*sp->printdir)(tif, fd, flags);
815 }
816
817 int
TIFFPredictorInit(TIFF * tif)818 TIFFPredictorInit(TIFF* tif)
819 {
820 TIFFPredictorState* sp = PredictorState(tif);
821
822 assert(sp != 0);
823
824 /*
825 * Merge codec-specific tag information.
826 */
827 if (!_TIFFMergeFields(tif, predictFields,
828 TIFFArrayCount(predictFields))) {
829 TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit",
830 "Merging Predictor codec-specific tags failed");
831 return 0;
832 }
833
834 /*
835 * Override parent get/set field methods.
836 */
837 sp->vgetparent = tif->tif_tagmethods.vgetfield;
838 tif->tif_tagmethods.vgetfield =
839 PredictorVGetField;/* hook for predictor tag */
840 sp->vsetparent = tif->tif_tagmethods.vsetfield;
841 tif->tif_tagmethods.vsetfield =
842 PredictorVSetField;/* hook for predictor tag */
843 sp->printdir = tif->tif_tagmethods.printdir;
844 tif->tif_tagmethods.printdir =
845 PredictorPrintDir; /* hook for predictor tag */
846
847 sp->setupdecode = tif->tif_setupdecode;
848 tif->tif_setupdecode = PredictorSetupDecode;
849 sp->setupencode = tif->tif_setupencode;
850 tif->tif_setupencode = PredictorSetupEncode;
851
852 sp->predictor = 1; /* default value */
853 sp->encodepfunc = NULL; /* no predictor routine */
854 sp->decodepfunc = NULL; /* no predictor routine */
855 return 1;
856 }
857
858 int
TIFFPredictorCleanup(TIFF * tif)859 TIFFPredictorCleanup(TIFF* tif)
860 {
861 TIFFPredictorState* sp = PredictorState(tif);
862
863 assert(sp != 0);
864
865 tif->tif_tagmethods.vgetfield = sp->vgetparent;
866 tif->tif_tagmethods.vsetfield = sp->vsetparent;
867 tif->tif_tagmethods.printdir = sp->printdir;
868 tif->tif_setupdecode = sp->setupdecode;
869 tif->tif_setupencode = sp->setupencode;
870
871 return 1;
872 }
873
874 /* vim: set ts=8 sts=8 sw=8 noet: */
875 /*
876 * Local Variables:
877 * mode: c
878 * c-basic-offset: 8
879 * fill-column: 78
880 * End:
881 */
882