1 /* $Id: tif_predict.c,v 1.35 2015-08-31 15:05:57 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 void horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc);
38 static void horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
39 static void horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
40 static void swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
41 static void swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
42 static void horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc);
43 static void horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc);
44 static void horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc);
45 static void swabHorDiff16(TIFF* tif, uint8* cp0, tmsize_t cc);
46 static void swabHorDiff32(TIFF* tif, uint8* cp0, tmsize_t cc);
47 static void fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc);
48 static void 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 break;
84 default:
85 TIFFErrorExt(tif->tif_clientdata, module,
86 "\"Predictor\" value %d not supported",
87 sp->predictor);
88 return 0;
89 }
90 sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
91 td->td_samplesperpixel : 1);
92 /*
93 * Calculate the scanline/tile-width size in bytes.
94 */
95 if (isTiled(tif))
96 sp->rowsize = TIFFTileRowSize(tif);
97 else
98 sp->rowsize = TIFFScanlineSize(tif);
99 if (sp->rowsize == 0)
100 return 0;
101
102 return 1;
103 }
104
105 static int
PredictorSetupDecode(TIFF * tif)106 PredictorSetupDecode(TIFF* tif)
107 {
108 TIFFPredictorState* sp = PredictorState(tif);
109 TIFFDirectory* td = &tif->tif_dir;
110
111 if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
112 {
113 (*tif->tif_cleanup)(tif);
114 return 0;
115 }
116
117 if (sp->predictor == 2) {
118 switch (td->td_bitspersample) {
119 case 8: sp->decodepfunc = horAcc8; break;
120 case 16: sp->decodepfunc = horAcc16; break;
121 case 32: sp->decodepfunc = horAcc32; break;
122 }
123 /*
124 * Override default decoding method with one that does the
125 * predictor stuff.
126 */
127 if( tif->tif_decoderow != PredictorDecodeRow )
128 {
129 sp->decoderow = tif->tif_decoderow;
130 tif->tif_decoderow = PredictorDecodeRow;
131 sp->decodestrip = tif->tif_decodestrip;
132 tif->tif_decodestrip = PredictorDecodeTile;
133 sp->decodetile = tif->tif_decodetile;
134 tif->tif_decodetile = PredictorDecodeTile;
135 }
136
137 /*
138 * If the data is horizontally differenced 16-bit data that
139 * requires byte-swapping, then it must be byte swapped before
140 * the accumulation step. We do this with a special-purpose
141 * routine and override the normal post decoding logic that
142 * the library setup when the directory was read.
143 */
144 if (tif->tif_flags & TIFF_SWAB) {
145 if (sp->decodepfunc == horAcc16) {
146 sp->decodepfunc = swabHorAcc16;
147 tif->tif_postdecode = _TIFFNoPostDecode;
148 } else if (sp->decodepfunc == horAcc32) {
149 sp->decodepfunc = swabHorAcc32;
150 tif->tif_postdecode = _TIFFNoPostDecode;
151 }
152 }
153 }
154
155 else if (sp->predictor == 3) {
156 sp->decodepfunc = fpAcc;
157 /*
158 * Override default decoding method with one that does the
159 * predictor stuff.
160 */
161 if( tif->tif_decoderow != PredictorDecodeRow )
162 {
163 sp->decoderow = tif->tif_decoderow;
164 tif->tif_decoderow = PredictorDecodeRow;
165 sp->decodestrip = tif->tif_decodestrip;
166 tif->tif_decodestrip = PredictorDecodeTile;
167 sp->decodetile = tif->tif_decodetile;
168 tif->tif_decodetile = PredictorDecodeTile;
169 }
170 /*
171 * The data should not be swapped outside of the floating
172 * point predictor, the accumulation routine should return
173 * byres in the native order.
174 */
175 if (tif->tif_flags & TIFF_SWAB) {
176 tif->tif_postdecode = _TIFFNoPostDecode;
177 }
178 /*
179 * Allocate buffer to keep the decoded bytes before
180 * rearranging in the ight order
181 */
182 }
183
184 return 1;
185 }
186
187 static int
PredictorSetupEncode(TIFF * tif)188 PredictorSetupEncode(TIFF* tif)
189 {
190 TIFFPredictorState* sp = PredictorState(tif);
191 TIFFDirectory* td = &tif->tif_dir;
192
193 if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
194 return 0;
195
196 if (sp->predictor == 2) {
197 switch (td->td_bitspersample) {
198 case 8: sp->encodepfunc = horDiff8; break;
199 case 16: sp->encodepfunc = horDiff16; break;
200 case 32: sp->encodepfunc = horDiff32; break;
201 }
202 /*
203 * Override default encoding method with one that does the
204 * predictor stuff.
205 */
206 if( tif->tif_encoderow != PredictorEncodeRow )
207 {
208 sp->encoderow = tif->tif_encoderow;
209 tif->tif_encoderow = PredictorEncodeRow;
210 sp->encodestrip = tif->tif_encodestrip;
211 tif->tif_encodestrip = PredictorEncodeTile;
212 sp->encodetile = tif->tif_encodetile;
213 tif->tif_encodetile = PredictorEncodeTile;
214 }
215
216 /*
217 * If the data is horizontally differenced 16-bit data that
218 * requires byte-swapping, then it must be byte swapped after
219 * the differenciation step. We do this with a special-purpose
220 * routine and override the normal post decoding logic that
221 * the library setup when the directory was read.
222 */
223 if (tif->tif_flags & TIFF_SWAB) {
224 if (sp->encodepfunc == horDiff16) {
225 sp->encodepfunc = swabHorDiff16;
226 tif->tif_postdecode = _TIFFNoPostDecode;
227 } else if (sp->encodepfunc == horDiff32) {
228 sp->encodepfunc = swabHorDiff32;
229 tif->tif_postdecode = _TIFFNoPostDecode;
230 }
231 }
232 }
233
234 else if (sp->predictor == 3) {
235 sp->encodepfunc = fpDiff;
236 /*
237 * Override default encoding method with one that does the
238 * predictor stuff.
239 */
240 if( tif->tif_encoderow != PredictorEncodeRow )
241 {
242 sp->encoderow = tif->tif_encoderow;
243 tif->tif_encoderow = PredictorEncodeRow;
244 sp->encodestrip = tif->tif_encodestrip;
245 tif->tif_encodestrip = PredictorEncodeTile;
246 sp->encodetile = tif->tif_encodetile;
247 tif->tif_encodetile = PredictorEncodeTile;
248 }
249 }
250
251 return 1;
252 }
253
254 #define REPEAT4(n, op) \
255 switch (n) { \
256 default: { tmsize_t i; for (i = n-4; i > 0; i--) { op; } } \
257 case 4: op; \
258 case 3: op; \
259 case 2: op; \
260 case 1: op; \
261 case 0: ; \
262 }
263
264 /* Remarks related to C standard compliance in all below functions : */
265 /* - to avoid any undefined behaviour, we only operate on unsigned types */
266 /* since the behaviour of "overflows" is defined (wrap over) */
267 /* - when storing into the byte stream, we explicitly mask with 0xff so */
268 /* as to make icc -check=conversions happy (not necessary by the standard) */
269
270 static void
horAcc8(TIFF * tif,uint8 * cp0,tmsize_t cc)271 horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc)
272 {
273 tmsize_t stride = PredictorState(tif)->stride;
274
275 unsigned char* cp = (unsigned char*) cp0;
276 assert((cc%stride)==0);
277 if (cc > stride) {
278 /*
279 * Pipeline the most common cases.
280 */
281 if (stride == 3) {
282 unsigned int cr = cp[0];
283 unsigned int cg = cp[1];
284 unsigned int cb = cp[2];
285 cc -= 3;
286 cp += 3;
287 while (cc>0) {
288 cp[0] = (unsigned char) ((cr += cp[0]) & 0xff);
289 cp[1] = (unsigned char) ((cg += cp[1]) & 0xff);
290 cp[2] = (unsigned char) ((cb += cp[2]) & 0xff);
291 cc -= 3;
292 cp += 3;
293 }
294 } else if (stride == 4) {
295 unsigned int cr = cp[0];
296 unsigned int cg = cp[1];
297 unsigned int cb = cp[2];
298 unsigned int ca = cp[3];
299 cc -= 4;
300 cp += 4;
301 while (cc>0) {
302 cp[0] = (unsigned char) ((cr += cp[0]) & 0xff);
303 cp[1] = (unsigned char) ((cg += cp[1]) & 0xff);
304 cp[2] = (unsigned char) ((cb += cp[2]) & 0xff);
305 cp[3] = (unsigned char) ((ca += cp[3]) & 0xff);
306 cc -= 4;
307 cp += 4;
308 }
309 } else {
310 cc -= stride;
311 do {
312 REPEAT4(stride, cp[stride] =
313 (unsigned char) ((cp[stride] + *cp) & 0xff); cp++)
314 cc -= stride;
315 } while (cc>0);
316 }
317 }
318 }
319
320 static void
swabHorAcc16(TIFF * tif,uint8 * cp0,tmsize_t cc)321 swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
322 {
323 uint16* wp = (uint16*) cp0;
324 tmsize_t wc = cc / 2;
325
326 TIFFSwabArrayOfShort(wp, wc);
327 horAcc16(tif, cp0, cc);
328 }
329
330 static void
horAcc16(TIFF * tif,uint8 * cp0,tmsize_t cc)331 horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
332 {
333 tmsize_t stride = PredictorState(tif)->stride;
334 uint16* wp = (uint16*) cp0;
335 tmsize_t wc = cc / 2;
336
337 assert((cc%(2*stride))==0);
338
339 if (wc > stride) {
340 wc -= stride;
341 do {
342 REPEAT4(stride, wp[stride] = (uint16)(((unsigned int)wp[stride] + (unsigned int)wp[0]) & 0xffff); wp++)
343 wc -= stride;
344 } while (wc > 0);
345 }
346 }
347
348 static void
swabHorAcc32(TIFF * tif,uint8 * cp0,tmsize_t cc)349 swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
350 {
351 uint32* wp = (uint32*) cp0;
352 tmsize_t wc = cc / 4;
353
354 TIFFSwabArrayOfLong(wp, wc);
355 horAcc32(tif, cp0, cc);
356 }
357
358 static void
horAcc32(TIFF * tif,uint8 * cp0,tmsize_t cc)359 horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
360 {
361 tmsize_t stride = PredictorState(tif)->stride;
362 uint32* wp = (uint32*) cp0;
363 tmsize_t wc = cc / 4;
364
365 assert((cc%(4*stride))==0);
366
367 if (wc > stride) {
368 wc -= stride;
369 do {
370 REPEAT4(stride, wp[stride] += wp[0]; wp++)
371 wc -= stride;
372 } while (wc > 0);
373 }
374 }
375
376 /*
377 * Floating point predictor accumulation routine.
378 */
379 static void
fpAcc(TIFF * tif,uint8 * cp0,tmsize_t cc)380 fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc)
381 {
382 tmsize_t stride = PredictorState(tif)->stride;
383 uint32 bps = tif->tif_dir.td_bitspersample / 8;
384 tmsize_t wc = cc / bps;
385 tmsize_t count = cc;
386 uint8 *cp = (uint8 *) cp0;
387 uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
388
389 assert((cc%(bps*stride))==0);
390
391 if (!tmp)
392 return;
393
394 while (count > stride) {
395 REPEAT4(stride, cp[stride] =
396 (unsigned char) ((cp[stride] + cp[0]) & 0xff); cp++)
397 count -= stride;
398 }
399
400 _TIFFmemcpy(tmp, cp0, cc);
401 cp = (uint8 *) cp0;
402 for (count = 0; count < wc; count++) {
403 uint32 byte;
404 for (byte = 0; byte < bps; byte++) {
405 #if WORDS_BIGENDIAN
406 cp[bps * count + byte] = tmp[byte * wc + count];
407 #else
408 cp[bps * count + byte] =
409 tmp[(bps - byte - 1) * wc + count];
410 #endif
411 }
412 }
413 _TIFFfree(tmp);
414 }
415
416 /*
417 * Decode a scanline and apply the predictor routine.
418 */
419 static int
PredictorDecodeRow(TIFF * tif,uint8 * op0,tmsize_t occ0,uint16 s)420 PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
421 {
422 TIFFPredictorState *sp = PredictorState(tif);
423
424 assert(sp != NULL);
425 assert(sp->decoderow != NULL);
426 assert(sp->decodepfunc != NULL);
427
428 if ((*sp->decoderow)(tif, op0, occ0, s)) {
429 (*sp->decodepfunc)(tif, op0, occ0);
430 return 1;
431 } else
432 return 0;
433 }
434
435 /*
436 * Decode a tile/strip and apply the predictor routine.
437 * Note that horizontal differencing must be done on a
438 * row-by-row basis. The width of a "row" has already
439 * been calculated at pre-decode time according to the
440 * strip/tile dimensions.
441 */
442 static int
PredictorDecodeTile(TIFF * tif,uint8 * op0,tmsize_t occ0,uint16 s)443 PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
444 {
445 TIFFPredictorState *sp = PredictorState(tif);
446
447 assert(sp != NULL);
448 assert(sp->decodetile != NULL);
449
450 if ((*sp->decodetile)(tif, op0, occ0, s)) {
451 tmsize_t rowsize = sp->rowsize;
452 assert(rowsize > 0);
453 assert((occ0%rowsize)==0);
454 assert(sp->decodepfunc != NULL);
455 while (occ0 > 0) {
456 (*sp->decodepfunc)(tif, op0, rowsize);
457 occ0 -= rowsize;
458 op0 += rowsize;
459 }
460 return 1;
461 } else
462 return 0;
463 }
464
465 static void
horDiff8(TIFF * tif,uint8 * cp0,tmsize_t cc)466 horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc)
467 {
468 TIFFPredictorState* sp = PredictorState(tif);
469 tmsize_t stride = sp->stride;
470 unsigned char* cp = (unsigned char*) cp0;
471
472 assert((cc%stride)==0);
473
474 if (cc > stride) {
475 cc -= stride;
476 /*
477 * Pipeline the most common cases.
478 */
479 if (stride == 3) {
480 unsigned int r1, g1, b1;
481 unsigned int r2 = cp[0];
482 unsigned int g2 = cp[1];
483 unsigned int b2 = cp[2];
484 do {
485 r1 = cp[3]; cp[3] = (unsigned char)((r1-r2)&0xff); r2 = r1;
486 g1 = cp[4]; cp[4] = (unsigned char)((g1-g2)&0xff); g2 = g1;
487 b1 = cp[5]; cp[5] = (unsigned char)((b1-b2)&0xff); b2 = b1;
488 cp += 3;
489 } while ((cc -= 3) > 0);
490 } else if (stride == 4) {
491 unsigned int r1, g1, b1, a1;
492 unsigned int r2 = cp[0];
493 unsigned int g2 = cp[1];
494 unsigned int b2 = cp[2];
495 unsigned int a2 = cp[3];
496 do {
497 r1 = cp[4]; cp[4] = (unsigned char)((r1-r2)&0xff); r2 = r1;
498 g1 = cp[5]; cp[5] = (unsigned char)((g1-g2)&0xff); g2 = g1;
499 b1 = cp[6]; cp[6] = (unsigned char)((b1-b2)&0xff); b2 = b1;
500 a1 = cp[7]; cp[7] = (unsigned char)((a1-a2)&0xff); a2 = a1;
501 cp += 4;
502 } while ((cc -= 4) > 0);
503 } else {
504 cp += cc - 1;
505 do {
506 REPEAT4(stride, cp[stride] = (unsigned char)((cp[stride] - cp[0])&0xff); cp--)
507 } while ((cc -= stride) > 0);
508 }
509 }
510 }
511
512 static void
horDiff16(TIFF * tif,uint8 * cp0,tmsize_t cc)513 horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc)
514 {
515 TIFFPredictorState* sp = PredictorState(tif);
516 tmsize_t stride = sp->stride;
517 uint16 *wp = (uint16*) cp0;
518 tmsize_t wc = cc/2;
519
520 assert((cc%(2*stride))==0);
521
522 if (wc > stride) {
523 wc -= stride;
524 wp += wc - 1;
525 do {
526 REPEAT4(stride, wp[stride] = (uint16)(((unsigned int)wp[stride] - (unsigned int)wp[0]) & 0xffff); wp--)
527 wc -= stride;
528 } while (wc > 0);
529 }
530 }
531
532 static void
swabHorDiff16(TIFF * tif,uint8 * cp0,tmsize_t cc)533 swabHorDiff16(TIFF* tif, uint8* cp0, tmsize_t cc)
534 {
535 uint16* wp = (uint16*) cp0;
536 tmsize_t wc = cc / 2;
537
538 horDiff16(tif, cp0, cc);
539
540 TIFFSwabArrayOfShort(wp, wc);
541 }
542
543 static void
horDiff32(TIFF * tif,uint8 * cp0,tmsize_t cc)544 horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
545 {
546 TIFFPredictorState* sp = PredictorState(tif);
547 tmsize_t stride = sp->stride;
548 uint32 *wp = (uint32*) cp0;
549 tmsize_t wc = cc/4;
550
551 assert((cc%(4*stride))==0);
552
553 if (wc > stride) {
554 wc -= stride;
555 wp += wc - 1;
556 do {
557 REPEAT4(stride, wp[stride] -= wp[0]; wp--)
558 wc -= stride;
559 } while (wc > 0);
560 }
561 }
562
563 static void
swabHorDiff32(TIFF * tif,uint8 * cp0,tmsize_t cc)564 swabHorDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
565 {
566 uint32* wp = (uint32*) cp0;
567 tmsize_t wc = cc / 4;
568
569 horDiff32(tif, cp0, cc);
570
571 TIFFSwabArrayOfLong(wp, wc);
572 }
573
574 /*
575 * Floating point predictor differencing routine.
576 */
577 static void
fpDiff(TIFF * tif,uint8 * cp0,tmsize_t cc)578 fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc)
579 {
580 tmsize_t stride = PredictorState(tif)->stride;
581 uint32 bps = tif->tif_dir.td_bitspersample / 8;
582 tmsize_t wc = cc / bps;
583 tmsize_t count;
584 uint8 *cp = (uint8 *) cp0;
585 uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
586
587 assert((cc%(bps*stride))==0);
588
589 if (!tmp)
590 return;
591
592 _TIFFmemcpy(tmp, cp0, cc);
593 for (count = 0; count < wc; count++) {
594 uint32 byte;
595 for (byte = 0; byte < bps; byte++) {
596 #if WORDS_BIGENDIAN
597 cp[byte * wc + count] = tmp[bps * count + byte];
598 #else
599 cp[(bps - byte - 1) * wc + count] =
600 tmp[bps * count + byte];
601 #endif
602 }
603 }
604 _TIFFfree(tmp);
605
606 cp = (uint8 *) cp0;
607 cp += cc - stride - 1;
608 for (count = cc; count > stride; count -= stride)
609 REPEAT4(stride, cp[stride] = (unsigned char)((cp[stride] - cp[0])&0xff); cp--)
610 }
611
612 static int
PredictorEncodeRow(TIFF * tif,uint8 * bp,tmsize_t cc,uint16 s)613 PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
614 {
615 TIFFPredictorState *sp = PredictorState(tif);
616
617 assert(sp != NULL);
618 assert(sp->encodepfunc != NULL);
619 assert(sp->encoderow != NULL);
620
621 /* XXX horizontal differencing alters user's data XXX */
622 (*sp->encodepfunc)(tif, bp, cc);
623 return (*sp->encoderow)(tif, bp, cc, s);
624 }
625
626 static int
PredictorEncodeTile(TIFF * tif,uint8 * bp0,tmsize_t cc0,uint16 s)627 PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s)
628 {
629 static const char module[] = "PredictorEncodeTile";
630 TIFFPredictorState *sp = PredictorState(tif);
631 uint8 *working_copy;
632 tmsize_t cc = cc0, rowsize;
633 unsigned char* bp;
634 int result_code;
635
636 assert(sp != NULL);
637 assert(sp->encodepfunc != NULL);
638 assert(sp->encodetile != NULL);
639
640 /*
641 * Do predictor manipulation in a working buffer to avoid altering
642 * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
643 */
644 working_copy = (uint8*) _TIFFmalloc(cc0);
645 if( working_copy == NULL )
646 {
647 TIFFErrorExt(tif->tif_clientdata, module,
648 "Out of memory allocating " TIFF_SSIZE_FORMAT " byte temp buffer.",
649 cc0 );
650 return 0;
651 }
652 memcpy( working_copy, bp0, cc0 );
653 bp = working_copy;
654
655 rowsize = sp->rowsize;
656 assert(rowsize > 0);
657 assert((cc0%rowsize)==0);
658 while (cc > 0) {
659 (*sp->encodepfunc)(tif, bp, rowsize);
660 cc -= rowsize;
661 bp += rowsize;
662 }
663 result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
664
665 _TIFFfree( working_copy );
666
667 return result_code;
668 }
669
670 #define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */
671
672 static const TIFFField predictFields[] = {
673 { TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL },
674 };
675
676 static int
PredictorVSetField(TIFF * tif,uint32 tag,va_list ap)677 PredictorVSetField(TIFF* tif, uint32 tag, va_list ap)
678 {
679 TIFFPredictorState *sp = PredictorState(tif);
680
681 assert(sp != NULL);
682 assert(sp->vsetparent != NULL);
683
684 switch (tag) {
685 case TIFFTAG_PREDICTOR:
686 sp->predictor = (uint16) va_arg(ap, uint16_vap);
687 TIFFSetFieldBit(tif, FIELD_PREDICTOR);
688 break;
689 default:
690 return (*sp->vsetparent)(tif, tag, ap);
691 }
692 tif->tif_flags |= TIFF_DIRTYDIRECT;
693 return 1;
694 }
695
696 static int
PredictorVGetField(TIFF * tif,uint32 tag,va_list ap)697 PredictorVGetField(TIFF* tif, uint32 tag, va_list ap)
698 {
699 TIFFPredictorState *sp = PredictorState(tif);
700
701 assert(sp != NULL);
702 assert(sp->vgetparent != NULL);
703
704 switch (tag) {
705 case TIFFTAG_PREDICTOR:
706 *va_arg(ap, uint16*) = sp->predictor;
707 break;
708 default:
709 return (*sp->vgetparent)(tif, tag, ap);
710 }
711 return 1;
712 }
713
714 static void
PredictorPrintDir(TIFF * tif,FILE * fd,long flags)715 PredictorPrintDir(TIFF* tif, FILE* fd, long flags)
716 {
717 TIFFPredictorState* sp = PredictorState(tif);
718
719 (void) flags;
720 if (TIFFFieldSet(tif,FIELD_PREDICTOR)) {
721 fprintf(fd, " Predictor: ");
722 switch (sp->predictor) {
723 case 1: fprintf(fd, "none "); break;
724 case 2: fprintf(fd, "horizontal differencing "); break;
725 case 3: fprintf(fd, "floating point predictor "); break;
726 }
727 fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor);
728 }
729 if (sp->printdir)
730 (*sp->printdir)(tif, fd, flags);
731 }
732
733 int
TIFFPredictorInit(TIFF * tif)734 TIFFPredictorInit(TIFF* tif)
735 {
736 TIFFPredictorState* sp = PredictorState(tif);
737
738 assert(sp != 0);
739
740 /*
741 * Merge codec-specific tag information.
742 */
743 if (!_TIFFMergeFields(tif, predictFields,
744 TIFFArrayCount(predictFields))) {
745 TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit",
746 "Merging Predictor codec-specific tags failed");
747 return 0;
748 }
749
750 /*
751 * Override parent get/set field methods.
752 */
753 sp->vgetparent = tif->tif_tagmethods.vgetfield;
754 tif->tif_tagmethods.vgetfield =
755 PredictorVGetField;/* hook for predictor tag */
756 sp->vsetparent = tif->tif_tagmethods.vsetfield;
757 tif->tif_tagmethods.vsetfield =
758 PredictorVSetField;/* hook for predictor tag */
759 sp->printdir = tif->tif_tagmethods.printdir;
760 tif->tif_tagmethods.printdir =
761 PredictorPrintDir; /* hook for predictor tag */
762
763 sp->setupdecode = tif->tif_setupdecode;
764 tif->tif_setupdecode = PredictorSetupDecode;
765 sp->setupencode = tif->tif_setupencode;
766 tif->tif_setupencode = PredictorSetupEncode;
767
768 sp->predictor = 1; /* default value */
769 sp->encodepfunc = NULL; /* no predictor routine */
770 sp->decodepfunc = NULL; /* no predictor routine */
771 return 1;
772 }
773
774 int
TIFFPredictorCleanup(TIFF * tif)775 TIFFPredictorCleanup(TIFF* tif)
776 {
777 TIFFPredictorState* sp = PredictorState(tif);
778
779 assert(sp != 0);
780
781 tif->tif_tagmethods.vgetfield = sp->vgetparent;
782 tif->tif_tagmethods.vsetfield = sp->vsetparent;
783 tif->tif_tagmethods.printdir = sp->printdir;
784 tif->tif_setupdecode = sp->setupdecode;
785 tif->tif_setupencode = sp->setupencode;
786
787 return 1;
788 }
789
790 /* vim: set ts=8 sts=8 sw=8 noet: */
791 /*
792 * Local Variables:
793 * mode: c
794 * c-basic-offset: 8
795 * fill-column: 78
796 * End:
797 */
798