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