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