libtiff: added 32bit horizontal predictor support (#1911)

https://github.com/libsdl-org/libtiff/commit/4cde6c63fee59ec57ee8ecd2aa7cf3978312c9e4

From 4cde6c63fee59ec57ee8ecd2aa7cf3978312c9e4 Mon Sep 17 00:00:00 2001
From: Frank Warmerdam <[EMAIL REDACTED]>
Date: Fri, 23 Jan 2009 15:57:18 +0000
Subject: [PATCH] added 32bit horizontal predictor support (#1911)

---
 ChangeLog             |  5 ++++
 libtiff/tif_predict.c | 66 +++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b84497ac..efe62134 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-01-23  Frank Warmerdam  <warmerdam@pobox.com>
+
+	* libtiff/tif_predict.c: Add support for 32bit integer horz. predictors.
+	http://bugzilla.maptools.org/show_bug.cgi?id=1911
+
 2009-01-20  Frank Warmerdam  <warmerdam@pobox.com>
 
 	* tools/tiffsplit.c: fix sampleformat to be shortv instead of longv.
diff --git a/libtiff/tif_predict.c b/libtiff/tif_predict.c
index 5315f433..052a8e2f 100644
--- a/libtiff/tif_predict.c
+++ b/libtiff/tif_predict.c
@@ -1,4 +1,4 @@
-/* $Id: tif_predict.c,v 1.11.2.2 2007-11-22 21:24:51 fwarmerdam Exp $ */
+/* $Id: tif_predict.c,v 1.11.2.3 2009-01-23 15:57:18 fwarmerdam Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -36,9 +36,12 @@
 
 static	void horAcc8(TIFF*, tidata_t, tsize_t);
 static	void horAcc16(TIFF*, tidata_t, tsize_t);
+static	void horAcc32(TIFF*, tidata_t, tsize_t);
 static	void swabHorAcc16(TIFF*, tidata_t, tsize_t);
+static	void swabHorAcc32(TIFF*, tidata_t, tsize_t);
 static	void horDiff8(TIFF*, tidata_t, tsize_t);
 static	void horDiff16(TIFF*, tidata_t, tsize_t);
+static	void horDiff32(TIFF*, tidata_t, tsize_t);
 static	void fpAcc(TIFF*, tidata_t, tsize_t);
 static	void fpDiff(TIFF*, tidata_t, tsize_t);
 static	int PredictorDecodeRow(TIFF*, tidata_t, tsize_t, tsample_t);
@@ -60,7 +63,8 @@ PredictorSetup(TIFF* tif)
 			return 1;
 		case PREDICTOR_HORIZONTAL:
 			if (td->td_bitspersample != 8
-			    && td->td_bitspersample != 16) {
+			    && td->td_bitspersample != 16
+			    && td->td_bitspersample != 32) {
 				TIFFErrorExt(tif->tif_clientdata, module,
     "Horizontal differencing \"Predictor\" not supported with %d-bit samples",
 					  td->td_bitspersample);
@@ -107,6 +111,7 @@ PredictorSetupDecode(TIFF* tif)
 		switch (td->td_bitspersample) {
 			case 8:  sp->decodepfunc = horAcc8; break;
 			case 16: sp->decodepfunc = horAcc16; break;
+			case 32: sp->decodepfunc = horAcc32; break;
 		}
 		/*
 		 * Override default decoding method with one that does the
@@ -132,7 +137,10 @@ PredictorSetupDecode(TIFF* tif)
 			if (sp->decodepfunc == horAcc16) {
 				sp->decodepfunc = swabHorAcc16;
 				tif->tif_postdecode = _TIFFNoPostDecode;
-			} /* else handle 32-bit case... */
+			} else if (sp->decodepfunc == horAcc32) {
+				sp->decodepfunc = swabHorAcc32;
+				tif->tif_postdecode = _TIFFNoPostDecode;
+			}
 		}
 	}
 
@@ -181,6 +189,7 @@ PredictorSetupEncode(TIFF* tif)
 		switch (td->td_bitspersample) {
 			case 8:  sp->encodepfunc = horDiff8; break;
 			case 16: sp->encodepfunc = horDiff16; break;
+			case 32: sp->encodepfunc = horDiff32; break;
 		}
 		/*
 		 * Override default encoding method with one that does the
@@ -303,6 +312,39 @@ horAcc16(TIFF* tif, tidata_t cp0, tsize_t cc)
 	}
 }
 
+static void
+swabHorAcc32(TIFF* tif, tidata_t cp0, tsize_t cc)
+{
+	tsize_t stride = PredictorState(tif)->stride;
+	uint32* wp = (uint32*) cp0;
+	tsize_t wc = cc / 4;
+
+	if (wc > stride) {
+		TIFFSwabArrayOfLong(wp, wc);
+		wc -= stride;
+		do {
+			REPEAT4(stride, wp[stride] += wp[0]; wp++)
+			wc -= stride;
+		} while ((int32) wc > 0);
+	}
+}
+
+static void
+horAcc32(TIFF* tif, tidata_t cp0, tsize_t cc)
+{
+	tsize_t stride = PredictorState(tif)->stride;
+	uint32* wp = (uint32*) cp0;
+	tsize_t wc = cc / 4;
+
+	if (wc > stride) {
+		wc -= stride;
+		do {
+			REPEAT4(stride, wp[stride] += wp[0]; wp++)
+			wc -= stride;
+		} while ((int32) wc > 0);
+	}
+}
+
 /*
  * Floating point predictor accumulation routine.
  */
@@ -451,6 +493,24 @@ horDiff16(TIFF* tif, tidata_t cp0, tsize_t cc)
 	}
 }
 
+static void
+horDiff32(TIFF* tif, tidata_t cp0, tsize_t cc)
+{
+	TIFFPredictorState* sp = PredictorState(tif);
+	tsize_t stride = sp->stride;
+	int32 *wp = (int32*) cp0;
+	tsize_t wc = cc/4;
+
+	if (wc > stride) {
+		wc -= stride;
+		wp += wc - 1;
+		do {
+			REPEAT4(stride, wp[stride] -= wp[0]; wp--)
+			wc -= stride;
+		} while ((int32) wc > 0);
+	}
+}
+
 /*
  * Floating point predictor differencing routine.
  */