From c8aed4996e086a302f4cad77bc5721800ce3bb47 Mon Sep 17 00:00:00 2001
From: Ilya Lavrenov <ilya.lavrenov@itseez.com>
Date: Thu, 31 Oct 2013 12:23:57 +0400
Subject: [PATCH] fixed ocl::warpPerspective

---
 .../ocl/src/opencl/imgproc_warpPerspective.cl | 56 +++++++++----------
 1 file changed, 25 insertions(+), 31 deletions(-)

diff --git a/modules/ocl/src/opencl/imgproc_warpPerspective.cl b/modules/ocl/src/opencl/imgproc_warpPerspective.cl
index 43863c151..dc37c1f04 100644
--- a/modules/ocl/src/opencl/imgproc_warpPerspective.cl
+++ b/modules/ocl/src/opencl/imgproc_warpPerspective.cl
@@ -100,8 +100,8 @@ __kernel void warpPerspectiveNN_C1_D0(__global uchar const * restrict src, __glo
         F4 Y0 = M[3]*DX + M[4]*dy + M[5];
         F4 W = M[6]*DX + M[7]*dy + M[8],one=1,zero=0;
         W = (W!=zero) ? one/W : zero;
-        short4 X = convert_short4(rint(X0*W));
-        short4 Y = convert_short4(rint(Y0*W));
+        short4 X = convert_short4_sat_rte(X0*W);
+        short4 Y = convert_short4_sat_rte(Y0*W);
         int4 sx = convert_int4(X);
         int4 sy = convert_int4(Y);
 
@@ -137,8 +137,8 @@ __kernel void warpPerspectiveLinear_C1_D0(__global const uchar * restrict src, _
         int X = rint(X0*W);
         int Y = rint(Y0*W);
 
-        int sx = (short)(X >> INTER_BITS);
-        int sy = (short)(Y >> INTER_BITS);
+        int sx = convert_short_sat(X >> INTER_BITS);
+        int sy = convert_short_sat(Y >> INTER_BITS);
         int ay = (short)(Y & (INTER_TAB_SIZE-1));
         int ax = (short)(X & (INTER_TAB_SIZE-1));
 
@@ -159,7 +159,7 @@ __kernel void warpPerspectiveLinear_C1_D0(__global const uchar * restrict src, _
         for(i=0; i<4;  i++)
         {
             float v = tab1y[(i>>1)] * tab1x[(i&1)];
-            itab[i] = convert_short_sat(rint( v * INTER_REMAP_COEF_SCALE ));
+            itab[i] = convert_short_sat_rte( v * INTER_REMAP_COEF_SCALE );
         }
         if(dx >=0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
         {
@@ -189,8 +189,8 @@ __kernel void warpPerspectiveCubic_C1_D0(__global uchar * src, __global uchar *
         int X = rint(X0*W);
         int Y = rint(Y0*W);
 
-        short sx = (short)(X >> INTER_BITS) - 1;
-        short sy = (short)(Y >> INTER_BITS) - 1;
+        short sx = convert_short_sat(X >> INTER_BITS) - 1;
+        short sy = convert_short_sat(Y >> INTER_BITS) - 1;
         short ay = (short)(Y & (INTER_TAB_SIZE-1));
         short ax = (short)(X & (INTER_TAB_SIZE-1));
 
@@ -266,10 +266,8 @@ __kernel void warpPerspectiveNN_C4_D0(__global uchar4 const * restrict src, __gl
         F Y0 = M[3]*dx + M[4]*dy + M[5];
         F W = M[6]*dx + M[7]*dy + M[8];
         W = (W != 0.0) ? 1./W : 0.0;
-        int X = rint(X0*W);
-        int Y = rint(Y0*W);
-        short sx = (short)X;
-        short sy = (short)Y;
+        short sx = convert_short_sat_rte(X0*W);
+        short sy = convert_short_sat_rte(Y0*W);
 
         if(dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
             dst[(dst_offset>>2)+dy*(dstStep>>2)+dx]= (sx>=0 && sx<src_cols && sy>=0 && sy<src_rows) ? src[(src_offset>>2)+sy*(srcStep>>2)+sx] : (uchar4)0;
@@ -295,8 +293,8 @@ __kernel void warpPerspectiveLinear_C4_D0(__global uchar4 const * restrict src,
         int X = rint(X0*W);
         int Y = rint(Y0*W);
 
-        short sx = (short)(X >> INTER_BITS);
-        short sy = (short)(Y >> INTER_BITS);
+        short sx = convert_short_sat(X >> INTER_BITS);
+        short sy = convert_short_sat(Y >> INTER_BITS);
         short ay = (short)(Y & (INTER_TAB_SIZE-1));
         short ax = (short)(X & (INTER_TAB_SIZE-1));
 
@@ -347,8 +345,8 @@ __kernel void warpPerspectiveCubic_C4_D0(__global uchar4 const * restrict src, _
         int X = rint(X0*W);
         int Y = rint(Y0*W);
 
-        short sx = (short)(X >> INTER_BITS) - 1;
-        short sy = (short)(Y >> INTER_BITS) - 1;
+        short sx = convert_short_sat(X >> INTER_BITS) - 1;
+        short sy = convert_short_sat(Y >> INTER_BITS) - 1;
         short ay = (short)(Y & (INTER_TAB_SIZE-1));
         short ax = (short)(X & (INTER_TAB_SIZE-1));
 
@@ -427,10 +425,8 @@ __kernel void warpPerspectiveNN_C1_D5(__global float * src, __global float * dst
         F Y0 = M[3]*dx + M[4]*dy + M[5];
         F W = M[6]*dx + M[7]*dy + M[8];
         W = (W != 0.0) ? 1./W : 0.0;
-        int X = rint(X0*W);
-        int Y = rint(Y0*W);
-        short sx = (short)X;
-        short sy = (short)Y;
+        short sx = convert_short_sat_rte(X0*W);
+        short sy = convert_short_sat_rte(Y0*W);
 
         if(dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
             dst[(dst_offset>>2)+dy*dstStep+dx]= (sx>=0 && sx<src_cols && sy>=0 && sy<src_rows) ? src[(src_offset>>2)+sy*srcStep+sx] : 0;
@@ -455,8 +451,8 @@ __kernel void warpPerspectiveLinear_C1_D5(__global float * src, __global float *
         int X = rint(X0*W);
         int Y = rint(Y0*W);
 
-        short sx = (short)(X >> INTER_BITS);
-        short sy = (short)(Y >> INTER_BITS);
+        short sx = convert_short_sat(X >> INTER_BITS);
+        short sy = convert_short_sat(Y >> INTER_BITS);
         short ay = (short)(Y & (INTER_TAB_SIZE-1));
         short ax = (short)(X & (INTER_TAB_SIZE-1));
 
@@ -505,8 +501,8 @@ __kernel void warpPerspectiveCubic_C1_D5(__global float * src, __global float *
         int X = rint(X0*W);
         int Y = rint(Y0*W);
 
-        short sx = (short)(X >> INTER_BITS) - 1;
-        short sy = (short)(Y >> INTER_BITS) - 1;
+        short sx = convert_short_sat(X >> INTER_BITS) - 1;
+        short sy = convert_short_sat(Y >> INTER_BITS) - 1;
         short ay = (short)(Y & (INTER_TAB_SIZE-1));
         short ax = (short)(X & (INTER_TAB_SIZE-1));
 
@@ -562,10 +558,8 @@ __kernel void warpPerspectiveNN_C4_D5(__global float4 * src, __global float4 * d
         F Y0 = M[3]*dx + M[4]*dy + M[5];
         F W = M[6]*dx + M[7]*dy + M[8];
         W =(W != 0.0)? 1./W : 0.0;
-        int X = rint(X0*W);
-        int Y = rint(Y0*W);
-        short sx = (short)X;
-        short sy = (short)Y;
+        short sx = convert_short_sat_rte(X0*W);
+        short sy = convert_short_sat_rte(Y0*W);
 
         if(dx >= 0 && dx < dst_cols && dy >= 0 && dy < dst_rows)
             dst[(dst_offset>>4)+dy*(dstStep>>2)+dx]= (sx>=0 && sx<src_cols && sy>=0 && sy<src_rows) ? src[(src_offset>>4)+sy*(srcStep>>2)+sx] : (float)0;
@@ -593,8 +587,8 @@ __kernel void warpPerspectiveLinear_C4_D5(__global float4 * src, __global float4
         int X = rint(X0*W);
         int Y = rint(Y0*W);
 
-        short sx0 = (short)(X >> INTER_BITS);
-        short sy0 = (short)(Y >> INTER_BITS);
+        short sx0 = convert_short_sat(X >> INTER_BITS);
+        short sy0 = convert_short_sat(Y >> INTER_BITS);
         short ay0 = (short)(Y & (INTER_TAB_SIZE-1));
         short ax0 = (short)(X & (INTER_TAB_SIZE-1));
 
@@ -646,8 +640,8 @@ __kernel void warpPerspectiveCubic_C4_D5(__global float4 * src, __global float4
         int X = rint(X0*W);
         int Y = rint(Y0*W);
 
-        short sx = (short)(X >> INTER_BITS)-1;
-        short sy = (short)(Y >> INTER_BITS)-1;
+        short sx = convert_short_sat(X >> INTER_BITS)-1;
+        short sy = convert_short_sat(Y >> INTER_BITS)-1;
         short ay = (short)(Y & (INTER_TAB_SIZE-1));
         short ax = (short)(X & (INTER_TAB_SIZE-1));