1 /* $Id: tif_predict.c,v 1.43 2017-05-10 15:21:16 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 static int
horAcc8(TIFF * tif,uint8 * cp0,tmsize_t cc)281 horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc)
282 {
283 tmsize_t stride = PredictorState(tif)->stride;
284
285 unsigned char* cp = (unsigned char*) cp0;
286 if((cc%stride)!=0)
287 {
288 TIFFErrorExt(tif->tif_clientdata, "horAcc8",
289 "%s", "(cc%stride)!=0");
290 return 0;
291 }
292
293 if (cc > stride) {
294 /*
295 * Pipeline the most common cases.
296 */
297 if (stride == 3) {
298 unsigned int cr = cp[0];
299 unsigned int cg = cp[1];
300 unsigned int cb = cp[2];
301 cc -= 3;
302 cp += 3;
303 while (cc>0) {
304 cp[0] = (unsigned char) ((cr += cp[0]) & 0xff);
305 cp[1] = (unsigned char) ((cg += cp[1]) & 0xff);
306 cp[2] = (unsigned char) ((cb += cp[2]) & 0xff);
307 cc -= 3;
308 cp += 3;
309 }
310 } else if (stride == 4) {
311 unsigned int cr = cp[0];
312 unsigned int cg = cp[1];
313 unsigned int cb = cp[2];
314 unsigned int ca = cp[3];
315 cc -= 4;
316 cp += 4;
317 while (cc>0) {
318 cp[0] = (unsigned char) ((cr += cp[0]) & 0xff);
319 cp[1] = (unsigned char) ((cg += cp[1]) & 0xff);
320 cp[2] = (unsigned char) ((cb += cp[2]) & 0xff);
321 cp[3] = (unsigned char) ((ca += cp[3]) & 0xff);
322 cc -= 4;
323 cp += 4;
324 }
325 } else {
326 cc -= stride;
327 do {
328 REPEAT4(stride, cp[stride] =
329 (unsigned char) ((cp[stride] + *cp) & 0xff); cp++)
330 cc -= stride;
331 } while (cc>0);
332 }
333 }
334 return 1;
335 }
336
337 static int
swabHorAcc16(TIFF * tif,uint8 * cp0,tmsize_t cc)338 swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
339 {
340 uint16* wp = (uint16*) cp0;
341 tmsize_t wc = cc / 2;
342
343 TIFFSwabArrayOfShort(wp, wc);
344 return horAcc16(tif, cp0, cc);
345 }
346
347 static int
horAcc16(TIFF * tif,uint8 * cp0,tmsize_t cc)348 horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
349 {
350 tmsize_t stride = PredictorState(tif)->stride;
351 uint16* wp = (uint16*) cp0;
352 tmsize_t wc = cc / 2;
353
354 if((cc%(2*stride))!=0)
355 {
356 TIFFErrorExt(tif->tif_clientdata, "horAcc16",
357 "%s", "cc%(2*stride))!=0");
358 return 0;
359 }
360
361 if (wc > stride) {
362 wc -= stride;
363 do {
364 REPEAT4(stride, wp[stride] = (uint16)(((unsigned int)wp[stride] + (unsigned int)wp[0]) & 0xffff); wp++)
365 wc -= stride;
366 } while (wc > 0);
367 }
368 return 1;
369 }
370
371 static int
swabHorAcc32(TIFF * tif,uint8 * cp0,tmsize_t cc)372 swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
373 {
374 uint32* wp = (uint32*) cp0;
375 tmsize_t wc = cc / 4;
376
377 TIFFSwabArrayOfLong(wp, wc);
378 return horAcc32(tif, cp0, cc);
379 }
380
381 static int
horAcc32(TIFF * tif,uint8 * cp0,tmsize_t cc)382 horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
383 {
384 tmsize_t stride = PredictorState(tif)->stride;
385 uint32* wp = (uint32*) cp0;
386 tmsize_t wc = cc / 4;
387
388 if((cc%(4*stride))!=0)
389 {
390 TIFFErrorExt(tif->tif_clientdata, "horAcc32",
391 "%s", "cc%(4*stride))!=0");
392 return 0;
393 }
394
395 if (wc > stride) {
396 wc -= stride;
397 do {
398 REPEAT4(stride, wp[stride] += wp[0]; wp++)
399 wc -= stride;
400 } while (wc > 0);
401 }
402 return 1;
403 }
404
405 /*
406 * Floating point predictor accumulation routine.
407 */
408 static int
fpAcc(TIFF * tif,uint8 * cp0,tmsize_t cc)409 fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc)
410 {
411 tmsize_t stride = PredictorState(tif)->stride;
412 uint32 bps = tif->tif_dir.td_bitspersample / 8;
413 tmsize_t wc = cc / bps;
414 tmsize_t count = cc;
415 uint8 *cp = (uint8 *) cp0;
416 uint8 *tmp;
417
418 if(cc%(bps*stride)!=0)
419 {
420 TIFFErrorExt(tif->tif_clientdata, "fpAcc",
421 "%s", "cc%(bps*stride))!=0");
422 return 0;
423 }
424
425 tmp = (uint8 *)_TIFFmalloc(cc);
426 if (!tmp)
427 return 0;
428
429 while (count > stride) {
430 REPEAT4(stride, cp[stride] =
431 (unsigned char) ((cp[stride] + cp[0]) & 0xff); cp++)
432 count -= stride;
433 }
434
435 _TIFFmemcpy(tmp, cp0, cc);
436 cp = (uint8 *) cp0;
437 for (count = 0; count < wc; count++) {
438 uint32 byte;
439 for (byte = 0; byte < bps; byte++) {
440 #if WORDS_BIGENDIAN
441 cp[bps * count + byte] = tmp[byte * wc + count];
442 #else
443 cp[bps * count + byte] =
444 tmp[(bps - byte - 1) * wc + count];
445 #endif
446 }
447 }
448 _TIFFfree(tmp);
449 return 1;
450 }
451
452 /*
453 * Decode a scanline and apply the predictor routine.
454 */
455 static int
PredictorDecodeRow(TIFF * tif,uint8 * op0,tmsize_t occ0,uint16 s)456 PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
457 {
458 TIFFPredictorState *sp = PredictorState(tif);
459
460 assert(sp != NULL);
461 assert(sp->decoderow != NULL);
462 assert(sp->decodepfunc != NULL);
463
464 if ((*sp->decoderow)(tif, op0, occ0, s)) {
465 return (*sp->decodepfunc)(tif, op0, occ0);
466 } else
467 return 0;
468 }
469
470 /*
471 * Decode a tile/strip and apply the predictor routine.
472 * Note that horizontal differencing must be done on a
473 * row-by-row basis. The width of a "row" has already
474 * been calculated at pre-decode time according to the
475 * strip/tile dimensions.
476 */
477 static int
PredictorDecodeTile(TIFF * tif,uint8 * op0,tmsize_t occ0,uint16 s)478 PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
479 {
480 TIFFPredictorState *sp = PredictorState(tif);
481
482 assert(sp != NULL);
483 assert(sp->decodetile != NULL);
484
485 if ((*sp->decodetile)(tif, op0, occ0, s)) {
486 tmsize_t rowsize = sp->rowsize;
487 assert(rowsize > 0);
488 if((occ0%rowsize) !=0)
489 {
490 TIFFErrorExt(tif->tif_clientdata, "PredictorDecodeTile",
491 "%s", "occ0%rowsize != 0");
492 return 0;
493 }
494 assert(sp->decodepfunc != NULL);
495 while (occ0 > 0) {
496 if( !(*sp->decodepfunc)(tif, op0, rowsize) )
497 return 0;
498 occ0 -= rowsize;
499 op0 += rowsize;
500 }
501 return 1;
502 } else
503 return 0;
504 }
505
506 static int
horDiff8(TIFF * tif,uint8 * cp0,tmsize_t cc)507 horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc)
508 {
509 TIFFPredictorState* sp = PredictorState(tif);
510 tmsize_t stride = sp->stride;
511 unsigned char* cp = (unsigned char*) cp0;
512
513 if((cc%stride)!=0)
514 {
515 TIFFErrorExt(tif->tif_clientdata, "horDiff8",
516 "%s", "(cc%stride)!=0");
517 return 0;
518 }
519
520 if (cc > stride) {
521 cc -= stride;
522 /*
523 * Pipeline the most common cases.
524 */
525 if (stride == 3) {
526 unsigned int r1, g1, b1;
527 unsigned int r2 = cp[0];
528 unsigned int g2 = cp[1];
529 unsigned int b2 = cp[2];
530 do {
531 r1 = cp[3]; cp[3] = (unsigned char)((r1-r2)&0xff); r2 = r1;
532 g1 = cp[4]; cp[4] = (unsigned char)((g1-g2)&0xff); g2 = g1;
533 b1 = cp[5]; cp[5] = (unsigned char)((b1-b2)&0xff); b2 = b1;
534 cp += 3;
535 } while ((cc -= 3) > 0);
536 } else if (stride == 4) {
537 unsigned int r1, g1, b1, a1;
538 unsigned int r2 = cp[0];
539 unsigned int g2 = cp[1];
540 unsigned int b2 = cp[2];
541 unsigned int a2 = cp[3];
542 do {
543 r1 = cp[4]; cp[4] = (unsigned char)((r1-r2)&0xff); r2 = r1;
544 g1 = cp[5]; cp[5] = (unsigned char)((g1-g2)&0xff); g2 = g1;
545 b1 = cp[6]; cp[6] = (unsigned char)((b1-b2)&0xff); b2 = b1;
546 a1 = cp[7]; cp[7] = (unsigned char)((a1-a2)&0xff); a2 = a1;
547 cp += 4;
548 } while ((cc -= 4) > 0);
549 } else {
550 cp += cc - 1;
551 do {
552 REPEAT4(stride, cp[stride] = (unsigned char)((cp[stride] - cp[0])&0xff); cp--)
553 } while ((cc -= stride) > 0);
554 }
555 }
556 return 1;
557 }
558
559 static int
horDiff16(TIFF * tif,uint8 * cp0,tmsize_t cc)560 horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc)
561 {
562 TIFFPredictorState* sp = PredictorState(tif);
563 tmsize_t stride = sp->stride;
564 uint16 *wp = (uint16*) cp0;
565 tmsize_t wc = cc/2;
566
567 if((cc%(2*stride))!=0)
568 {
569 TIFFErrorExt(tif->tif_clientdata, "horDiff8",
570 "%s", "(cc%(2*stride))!=0");
571 return 0;
572 }
573
574 if (wc > stride) {
575 wc -= stride;
576 wp += wc - 1;
577 do {
578 REPEAT4(stride, wp[stride] = (uint16)(((unsigned int)wp[stride] - (unsigned int)wp[0]) & 0xffff); wp--)
579 wc -= stride;
580 } while (wc > 0);
581 }
582 return 1;
583 }
584
585 static int
swabHorDiff16(TIFF * tif,uint8 * cp0,tmsize_t cc)586 swabHorDiff16(TIFF* tif, uint8* cp0, tmsize_t cc)
587 {
588 uint16* wp = (uint16*) cp0;
589 tmsize_t wc = cc / 2;
590
591 if( !horDiff16(tif, cp0, cc) )
592 return 0;
593
594 TIFFSwabArrayOfShort(wp, wc);
595 return 1;
596 }
597
598 static int
horDiff32(TIFF * tif,uint8 * cp0,tmsize_t cc)599 horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
600 {
601 TIFFPredictorState* sp = PredictorState(tif);
602 tmsize_t stride = sp->stride;
603 uint32 *wp = (uint32*) cp0;
604 tmsize_t wc = cc/4;
605
606 if((cc%(4*stride))!=0)
607 {
608 TIFFErrorExt(tif->tif_clientdata, "horDiff32",
609 "%s", "(cc%(4*stride))!=0");
610 return 0;
611 }
612
613 if (wc > stride) {
614 wc -= stride;
615 wp += wc - 1;
616 do {
617 REPEAT4(stride, wp[stride] -= wp[0]; wp--)
618 wc -= stride;
619 } while (wc > 0);
620 }
621 return 1;
622 }
623
624 static int
swabHorDiff32(TIFF * tif,uint8 * cp0,tmsize_t cc)625 swabHorDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
626 {
627 uint32* wp = (uint32*) cp0;
628 tmsize_t wc = cc / 4;
629
630 if( !horDiff32(tif, cp0, cc) )
631 return 0;
632
633 TIFFSwabArrayOfLong(wp, wc);
634 return 1;
635 }
636
637 /*
638 * Floating point predictor differencing routine.
639 */
640 static int
fpDiff(TIFF * tif,uint8 * cp0,tmsize_t cc)641 fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc)
642 {
643 tmsize_t stride = PredictorState(tif)->stride;
644 uint32 bps = tif->tif_dir.td_bitspersample / 8;
645 tmsize_t wc = cc / bps;
646 tmsize_t count;
647 uint8 *cp = (uint8 *) cp0;
648 uint8 *tmp;
649
650 if((cc%(bps*stride))!=0)
651 {
652 TIFFErrorExt(tif->tif_clientdata, "fpDiff",
653 "%s", "(cc%(bps*stride))!=0");
654 return 0;
655 }
656
657 tmp = (uint8 *)_TIFFmalloc(cc);
658 if (!tmp)
659 return 0;
660
661 _TIFFmemcpy(tmp, cp0, cc);
662 for (count = 0; count < wc; count++) {
663 uint32 byte;
664 for (byte = 0; byte < bps; byte++) {
665 #if WORDS_BIGENDIAN
666 cp[byte * wc + count] = tmp[bps * count + byte];
667 #else
668 cp[(bps - byte - 1) * wc + count] =
669 tmp[bps * count + byte];
670 #endif
671 }
672 }
673 _TIFFfree(tmp);
674
675 cp = (uint8 *) cp0;
676 cp += cc - stride - 1;
677 for (count = cc; count > stride; count -= stride)
678 REPEAT4(stride, cp[stride] = (unsigned char)((cp[stride] - cp[0])&0xff); cp--)
679 return 1;
680 }
681
682 static int
PredictorEncodeRow(TIFF * tif,uint8 * bp,tmsize_t cc,uint16 s)683 PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
684 {
685 TIFFPredictorState *sp = PredictorState(tif);
686
687 assert(sp != NULL);
688 assert(sp->encodepfunc != NULL);
689 assert(sp->encoderow != NULL);
690
691 /* XXX horizontal differencing alters user's data XXX */
692 if( !(*sp->encodepfunc)(tif, bp, cc) )
693 return 0;
694 return (*sp->encoderow)(tif, bp, cc, s);
695 }
696
697 static int
PredictorEncodeTile(TIFF * tif,uint8 * bp0,tmsize_t cc0,uint16 s)698 PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s)
699 {
700 static const char module[] = "PredictorEncodeTile";
701 TIFFPredictorState *sp = PredictorState(tif);
702 uint8 *working_copy;
703 tmsize_t cc = cc0, rowsize;
704 unsigned char* bp;
705 int result_code;
706
707 assert(sp != NULL);
708 assert(sp->encodepfunc != NULL);
709 assert(sp->encodetile != NULL);
710
711 /*
712 * Do predictor manipulation in a working buffer to avoid altering
713 * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
714 */
715 working_copy = (uint8*) _TIFFmalloc(cc0);
716 if( working_copy == NULL )
717 {
718 TIFFErrorExt(tif->tif_clientdata, module,
719 "Out of memory allocating " TIFF_SSIZE_FORMAT " byte temp buffer.",
720 cc0 );
721 return 0;
722 }
723 memcpy( working_copy, bp0, cc0 );
724 bp = working_copy;
725
726 rowsize = sp->rowsize;
727 assert(rowsize > 0);
728 if((cc0%rowsize)!=0)
729 {
730 TIFFErrorExt(tif->tif_clientdata, "PredictorEncodeTile",
731 "%s", "(cc0%rowsize)!=0");
732 _TIFFfree( working_copy );
733 return 0;
734 }
735 while (cc > 0) {
736 (*sp->encodepfunc)(tif, bp, rowsize);
737 cc -= rowsize;
738 bp += rowsize;
739 }
740 result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
741
742 _TIFFfree( working_copy );
743
744 return result_code;
745 }
746
747 #define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */
748
749 static const TIFFField predictFields[] = {
750 { TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL },
751 };
752
753 static int
PredictorVSetField(TIFF * tif,uint32 tag,va_list ap)754 PredictorVSetField(TIFF* tif, uint32 tag, va_list ap)
755 {
756 TIFFPredictorState *sp = PredictorState(tif);
757
758 assert(sp != NULL);
759 assert(sp->vsetparent != NULL);
760
761 switch (tag) {
762 case TIFFTAG_PREDICTOR:
763 sp->predictor = (uint16) va_arg(ap, uint16_vap);
764 TIFFSetFieldBit(tif, FIELD_PREDICTOR);
765 break;
766 default:
767 return (*sp->vsetparent)(tif, tag, ap);
768 }
769 tif->tif_flags |= TIFF_DIRTYDIRECT;
770 return 1;
771 }
772
773 static int
PredictorVGetField(TIFF * tif,uint32 tag,va_list ap)774 PredictorVGetField(TIFF* tif, uint32 tag, va_list ap)
775 {
776 TIFFPredictorState *sp = PredictorState(tif);
777
778 assert(sp != NULL);
779 assert(sp->vgetparent != NULL);
780
781 switch (tag) {
782 case TIFFTAG_PREDICTOR:
783 *va_arg(ap, uint16*) = (uint16)sp->predictor;
784 break;
785 default:
786 return (*sp->vgetparent)(tif, tag, ap);
787 }
788 return 1;
789 }
790
791 static void
PredictorPrintDir(TIFF * tif,FILE * fd,long flags)792 PredictorPrintDir(TIFF* tif, FILE* fd, long flags)
793 {
794 TIFFPredictorState* sp = PredictorState(tif);
795
796 (void) flags;
797 if (TIFFFieldSet(tif,FIELD_PREDICTOR)) {
798 fprintf(fd, " Predictor: ");
799 switch (sp->predictor) {
800 case 1: fprintf(fd, "none "); break;
801 case 2: fprintf(fd, "horizontal differencing "); break;
802 case 3: fprintf(fd, "floating point predictor "); break;
803 }
804 fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor);
805 }
806 if (sp->printdir)
807 (*sp->printdir)(tif, fd, flags);
808 }
809
810 int
TIFFPredictorInit(TIFF * tif)811 TIFFPredictorInit(TIFF* tif)
812 {
813 TIFFPredictorState* sp = PredictorState(tif);
814
815 assert(sp != 0);
816
817 /*
818 * Merge codec-specific tag information.
819 */
820 if (!_TIFFMergeFields(tif, predictFields,
821 TIFFArrayCount(predictFields))) {
822 TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit",
823 "Merging Predictor codec-specific tags failed");
824 return 0;
825 }
826
827 /*
828 * Override parent get/set field methods.
829 */
830 sp->vgetparent = tif->tif_tagmethods.vgetfield;
831 tif->tif_tagmethods.vgetfield =
832 PredictorVGetField;/* hook for predictor tag */
833 sp->vsetparent = tif->tif_tagmethods.vsetfield;
834 tif->tif_tagmethods.vsetfield =
835 PredictorVSetField;/* hook for predictor tag */
836 sp->printdir = tif->tif_tagmethods.printdir;
837 tif->tif_tagmethods.printdir =
838 PredictorPrintDir; /* hook for predictor tag */
839
840 sp->setupdecode = tif->tif_setupdecode;
841 tif->tif_setupdecode = PredictorSetupDecode;
842 sp->setupencode = tif->tif_setupencode;
843 tif->tif_setupencode = PredictorSetupEncode;
844
845 sp->predictor = 1; /* default value */
846 sp->encodepfunc = NULL; /* no predictor routine */
847 sp->decodepfunc = NULL; /* no predictor routine */
848 return 1;
849 }
850
851 int
TIFFPredictorCleanup(TIFF * tif)852 TIFFPredictorCleanup(TIFF* tif)
853 {
854 TIFFPredictorState* sp = PredictorState(tif);
855
856 assert(sp != 0);
857
858 tif->tif_tagmethods.vgetfield = sp->vgetparent;
859 tif->tif_tagmethods.vsetfield = sp->vsetparent;
860 tif->tif_tagmethods.printdir = sp->printdir;
861 tif->tif_setupdecode = sp->setupdecode;
862 tif->tif_setupencode = sp->setupencode;
863
864 return 1;
865 }
866
867 /* vim: set ts=8 sts=8 sw=8 noet: */
868 /*
869 * Local Variables:
870 * mode: c
871 * c-basic-offset: 8
872 * fill-column: 78
873 * End:
874 */
875