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