Limit intermediate precision bits correctly

The intermediate precision must be correctly
limited since the current implementation stores
the intremidiate filtered data in signed 16 bit
buffers. Therefore for n-bit sources, the intermediate
extra precision bits must be at most 15-n.

This is now needed since the intermediate extra
precision is now an user configurable parameter.

Change-Id: Ie87f6aaaa66af335b945765d441125ab494dfaa1
diff --git a/tools/lanczos/lanczos_README.txt b/tools/lanczos/lanczos_README.txt
index b37dfdb..75b2da6 100644
--- a/tools/lanczos/lanczos_README.txt
+++ b/tools/lanczos/lanczos_README.txt
@@ -52,6 +52,7 @@
                                  [default: 14]
           -ieb:<n>        - providing intermediate extra bits of
                             prec between horz and vert filtering
+                            clamped to maximum of (15 - bitdepth)
                                  [default: 2]
           -ext:<ext_type> - providing the extension type
                <ext_type> is one of:
diff --git a/tools/lanczos/lanczos_resample.c b/tools/lanczos/lanczos_resample.c
index 6f321ef..c529fdf 100644
--- a/tools/lanczos/lanczos_resample.c
+++ b/tools/lanczos/lanczos_resample.c
@@ -26,6 +26,9 @@
   (((value) < 0) ? -ROUND_POWER_OF_TWO(-(value), (n)) \
                  : ROUND_POWER_OF_TWO((value), (n)))
 
+#define MAX(a, b) ((a) < (b) ? (b) : (a))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
 #ifndef M_PI
 #define M_PI (3.14159265358979323846)
 #endif
@@ -343,11 +346,13 @@
     for (int j = -tapsby2 + 1; j <= tapsby2; ++j) {
       sum += (int)rf->filter[p][j + tapsby2 - 1] * (int)xext[j];
     }
-    y[i] = ROUND_POWER_OF_TWO_SIGNED(sum, downshift);
+    sum = ROUND_POWER_OF_TWO_SIGNED(sum, downshift);
     if (clip) {
-      y[i] = (int16_t)clip->issigned ? doclip(y[i], -(1 << (clip->bits - 1)),
+      y[i] = (int16_t)clip->issigned ? doclip(sum, -(1 << (clip->bits - 1)),
                                               (1 << (clip->bits - 1)) - 1)
-                                     : doclip(y[i], 0, (1 << clip->bits) - 1);
+                                     : doclip(sum, 0, (1 << clip->bits) - 1);
+    } else {
+      y[i] = (int16_t)sum;
     }
     xext += rf->steps[p];
   }
@@ -472,6 +477,8 @@
   int16_t *tmparrv = tmparr_ + outheight + rfv->length / 2;
   int16_t *tmparro = tmparr_;
   int tmpstride = outwidth;
+  // intermediate data is stored in 16 bit buffers, so limit int_extra_bits
+  int_extra_bits = MIN(int_extra_bits, 15 - clip->bits);
   const int downshifth = rfh->filter_bits - int_extra_bits;
   const int downshiftv = rfh->filter_bits + int_extra_bits;
   for (int i = 0; i < inheight; ++i) {
@@ -531,11 +538,13 @@
     for (int j = -tapsby2 + 1; j <= tapsby2; ++j) {
       sum += (int)rf->filter[p][j + tapsby2 - 1] * (int)xext[j];
     }
-    y[i] = (int16_t)ROUND_POWER_OF_TWO_SIGNED(sum, downshift);
+    sum = ROUND_POWER_OF_TWO_SIGNED(sum, downshift);
     if (clip) {
-      y[i] = (int16_t)clip->issigned ? doclip(y[i], -(1 << (clip->bits - 1)),
+      y[i] = (int16_t)clip->issigned ? doclip(sum, -(1 << (clip->bits - 1)),
                                               (1 << (clip->bits - 1)) - 1)
-                                     : doclip(y[i], 0, (1 << clip->bits) - 1);
+                                     : doclip(sum, 0, (1 << clip->bits) - 1);
+    } else {
+      y[i] = (int16_t)sum;
     }
     xext += rf->steps[p];
   }
@@ -555,11 +564,13 @@
     for (int j = -tapsby2 + 1; j <= tapsby2; ++j) {
       sum += (int)rf->filter[p][j + tapsby2 - 1] * (int)xext[j];
     }
-    y[i] = (uint8_t)ROUND_POWER_OF_TWO_SIGNED(sum, downshift);
+    sum = ROUND_POWER_OF_TWO_SIGNED(sum, downshift);
     if (clip) {
-      y[i] = (uint8_t)clip->issigned ? doclip(y[i], -(1 << (clip->bits - 1)),
+      y[i] = (uint8_t)clip->issigned ? doclip(sum, -(1 << (clip->bits - 1)),
                                               (1 << (clip->bits - 1)) - 1)
-                                     : doclip(y[i], 0, (1 << clip->bits) - 1);
+                                     : doclip(sum, 0, (1 << clip->bits) - 1);
+    } else {
+      y[i] = (uint8_t)sum;
     }
     xext += rf->steps[p];
   }
@@ -706,6 +717,8 @@
   int16_t *tmparrv = tmparr_ + outheight + rfv->length / 2;
   int16_t *tmparro = tmparr_;
   int tmpstride = outwidth;
+  // intermediate data is stored in 16 bit buffers, so limit int_extra_bits
+  int_extra_bits = MIN(int_extra_bits, 15 - clip->bits);
   const int downshifth = rfh->filter_bits - int_extra_bits;
   const int downshiftv = rfh->filter_bits + int_extra_bits;
   for (int i = 0; i < inheight; ++i) {
diff --git a/tools/lanczos/lanczos_resample_filter.c b/tools/lanczos/lanczos_resample_filter.c
index e4d246f..b516baf 100644
--- a/tools/lanczos/lanczos_resample_filter.c
+++ b/tools/lanczos/lanczos_resample_filter.c
@@ -42,6 +42,7 @@
   printf("                                 [default: 14]\n");
   printf("          -ieb:<n>        - providing intermediate extra bits of\n");
   printf("                            prec between horz and vert filtering\n");
+  printf("                            clamped to maximum of (15 - bitdepth)\n");
   printf("                                 [default: 2]\n");
   printf("          -ext:<ext_type> - providing the extension type\n");
   printf("               <ext_type> is one of:\n");
diff --git a/tools/lanczos/lanczos_resample_y4m.c b/tools/lanczos/lanczos_resample_y4m.c
index 852d932..814e00b 100644
--- a/tools/lanczos/lanczos_resample_y4m.c
+++ b/tools/lanczos/lanczos_resample_y4m.c
@@ -56,6 +56,7 @@
   printf("                                 [default: 14]\n");
   printf("          -ieb:<n>        - providing intermediate extra bits of\n");
   printf("                            prec between horz and vert filtering\n");
+  printf("                            clamped to maximum of (15 - bitdepth)\n");
   printf("                                 [default: 2]\n");
   printf("          -ext:<ext_type> - providing the extension type\n");
   printf("               <ext_type> is one of:\n");
diff --git a/tools/lanczos/lanczos_resample_yuv.c b/tools/lanczos/lanczos_resample_yuv.c
index ea1e17c..422c397 100644
--- a/tools/lanczos/lanczos_resample_yuv.c
+++ b/tools/lanczos/lanczos_resample_yuv.c
@@ -58,6 +58,7 @@
   printf("                                 [default: 14]\n");
   printf("          -ieb:<n>        - providing intermediate extra bits of\n");
   printf("                            prec between horz and vert filtering\n");
+  printf("                            clamped to maximum of (15 - bitdepth)\n");
   printf("                                 [default: 2]\n");
   printf("          -ext:<ext_type> - providing the extension type\n");
   printf("               <ext_type> is one of:\n");