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