Implement vector clamp for all types.

Change-Id: I95772f23fca3037a646bea7ad937dbdeec261f7a
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/WhiteBalance.java b/java/tests/ImageProcessing/src/com/android/rs/image/WhiteBalance.java
index a836067..e8078c2 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/WhiteBalance.java
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/WhiteBalance.java
@@ -25,13 +25,14 @@
 
     public void createTest(android.content.res.Resources res) {
         mScript = new ScriptC_wbalance(mRS);
-    }
 
-    public void runTest() {
         mScript.set_histogramSource(mInPixelsAllocation);
         mScript.set_histogramWidth(mInPixelsAllocation.getType().getX());
         mScript.set_histogramHeight(mInPixelsAllocation.getType().getY());
         mScript.invoke_prepareWhiteBalance();
+    }
+
+    public void runTest() {
         mScript.forEach_whiteBalanceKernel(mInPixelsAllocation, mOutPixelsAllocation);
     }
 
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/contrast.rs b/java/tests/ImageProcessing/src/com/android/rs/image/contrast.rs
index 5b67252..ef6fd63 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/contrast.rs
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/contrast.rs
@@ -27,12 +27,6 @@
 
 void contrast(const uchar4 *in, uchar4 *out)
 {
-#if 0
-    out->r = rsClamp((int)(brightM * in->r + brightC), 0, 255);
-    out->g = rsClamp((int)(brightM * in->g + brightC), 0, 255);
-    out->b = rsClamp((int)(brightM * in->b + brightC), 0, 255);
-#else
     float3 v = convert_float3(in->rgb) * brightM + brightC;
     out->rgb = convert_uchar3(clamp(v, 0.f, 255.f));
-#endif
 }
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/exposure.rs b/java/tests/ImageProcessing/src/com/android/rs/image/exposure.rs
index 9ad4f8d..88bb1d6 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/exposure.rs
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/exposure.rs
@@ -26,9 +26,8 @@
 uchar4 __attribute__((kernel)) exposure(uchar4 in)
 {
     uchar4 out = {0, 0, 0, 255};
-    out.r = rsClamp((int)(bright * in.r), 0, 255);
-    out.g = rsClamp((int)(bright * in.g), 0, 255);
-    out.b = rsClamp((int)(bright * in.b), 0, 255);
+    float3 t = convert_float3(in.rgb);
+    out.rgb = convert_uchar3(clamp(convert_int3(t * bright), 0, 255));
     return out;
 }
 
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/vibrance.rs b/java/tests/ImageProcessing/src/com/android/rs/image/vibrance.rs
index 300be16..b82e1d3 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/vibrance.rs
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/vibrance.rs
@@ -32,13 +32,13 @@
     int r = in->r;
     int g = in->g;
     int b = in->b;
-    float red = (r-max(g, b))/256.f;
+    float red = (r-max(g, b)) * (1.f / 256.f);
     float S = (float)(Vib/(1+native_exp(-red*3)))+1;
     float MS = 1.0f - S;
     float Rt = Rf * MS;
     float Gt = Gf * MS;
     float Bt = Bf * MS;
-    int t = (r + g) / 2;
+    int t = (r + g) >> 1;
     R = r;
     G = g;
     B = b;
diff --git a/java/tests/ImageProcessing/src/com/android/rs/image/wbalance.rs b/java/tests/ImageProcessing/src/com/android/rs/image/wbalance.rs
index e643196..fbdd869 100644
--- a/java/tests/ImageProcessing/src/com/android/rs/image/wbalance.rs
+++ b/java/tests/ImageProcessing/src/com/android/rs/image/wbalance.rs
@@ -23,9 +23,7 @@
 uint32_t histogramHeight;
 uint32_t histogramWidth;
 
-static float scaleR;
-static float scaleG;
-static float scaleB;
+static float3 scale;
 
 static uchar4 estimateWhite() {
 
@@ -115,31 +113,18 @@
     int maximum = max(estimation.r, max(estimation.g, estimation.b));
     float avg = (minimum + maximum) / 2.f;
 
-    scaleR =  avg/estimation.r;
-    scaleG =  avg/estimation.g;
-    scaleB =  avg/estimation.b;
-
-}
-
-static unsigned char contrastClamp(int c)
-{
-    int N = 255;
-    c &= ~(c >> 31);
-    c -= N;
-    c &= (c >> 31);
-    c += N;
-    return  (unsigned char) c;
+    scale.r =  avg / estimation.r;
+    scale.g =  avg / estimation.g;
+    scale.b =  avg / estimation.b;
 }
 
 uchar4 __attribute__((kernel)) whiteBalanceKernel(uchar4 in) {
-    float Rc =  in.r*scaleR;
-    float Gc =  in.g*scaleG;
-    float Bc =  in.b*scaleB;
+    float3 t = convert_float3(in.rgb);
+    t *= scale;
+    t = min(t, 255.f);
 
     uchar4 out;
-    out.r = contrastClamp(Rc);
-    out.g = contrastClamp(Gc);
-    out.b = contrastClamp(Bc);
+    out.rgb = convert_uchar3(t);
     out.a = 255;
     return out;
 }
diff --git a/scriptc/rs_cl.rsh b/scriptc/rs_cl.rsh
index 26d0727..6dc971c 100644
--- a/scriptc/rs_cl.rsh
+++ b/scriptc/rs_cl.rsh
@@ -827,9 +827,34 @@
  * @param low Lower bound, must be scalar or matching vector.
  * @param high High bound, must match type of low
  */
+
+#if !defined(RS_VERSION) || (RS_VERSION < 19)
 _RS_RUNTIME float __attribute__((const, overloadable)) clamp(float amount, float low, float high);
 FN_FUNC_FN_FN_FN(clamp)
 FN_FUNC_FN_F_F(clamp)
+#else
+#define _CLAMP(T)                                                                   \
+extern T __attribute__((overloadable)) clamp(T amount, T low, T high);              \
+extern T##2 __attribute__((overloadable)) clamp(T##2 amount, T##2 low, T##2 high);  \
+extern T##3 __attribute__((overloadable)) clamp(T##3 amount, T##3 low, T##3 high);  \
+extern T##4 __attribute__((overloadable)) clamp(T##4 amount, T##4 low, T##4 high);  \
+extern T##2 __attribute__((overloadable)) clamp(T##2 amount, T low, T high);        \
+extern T##3 __attribute__((overloadable)) clamp(T##3 amount, T low, T high);        \
+extern T##4 __attribute__((overloadable)) clamp(T##4 amount, T low, T high)
+
+_CLAMP(float);
+_CLAMP(double);
+_CLAMP(char);
+_CLAMP(uchar);
+_CLAMP(short);
+_CLAMP(ushort);
+_CLAMP(int);
+_CLAMP(uint);
+_CLAMP(long);
+_CLAMP(ulong);
+
+#undef _CLAMP
+#endif
 
 /**
  * Convert from radians to degrees.