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