• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------
2  * Project:      CMSIS DSP Library
3  * Title:        arm_bilinear_interp_f16.c
4  * Description:  Floating-point bilinear interpolation
5  *
6  * $Date:        23 April 2021
7  * $Revision:    V1.9.0
8  *
9  * Target Processor: Cortex-M and Cortex-A cores
10  * -------------------------------------------------------------------- */
11 /*
12  * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
13  *
14  * SPDX-License-Identifier: Apache-2.0
15  *
16  * Licensed under the Apache License, Version 2.0 (the License); you may
17  * not use this file except in compliance with the License.
18  * You may obtain a copy of the License at
19  *
20  * www.apache.org/licenses/LICENSE-2.0
21  *
22  * Unless required by applicable law or agreed to in writing, software
23  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25  * See the License for the specific language governing permissions and
26  * limitations under the License.
27  */
28 
29 #include "dsp/interpolation_functions_f16.h"
30 
31 #if defined(ARM_FLOAT16_SUPPORTED)
32 
33 
34 /**
35   @ingroup groupInterpolation
36  */
37 
38 /**
39    * @defgroup BilinearInterpolate Bilinear Interpolation
40    *
41    * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid.
42    * The underlying function <code>f(x, y)</code> is sampled on a regular grid and the interpolation process
43    * determines values between the grid points.
44    * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension.
45    * Bilinear interpolation is often used in image processing to rescale images.
46    * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types.
47    *
48    * <b>Algorithm</b>
49    * \par
50    * The instance structure used by the bilinear interpolation functions describes a two dimensional data table.
51    * For floating-point, the instance structure is defined as:
52    * <pre>
53    *   typedef struct
54    *   {
55    *     uint16_t numRows;
56    *     uint16_t numCols;
57    *     float16_t *pData;
58    * } arm_bilinear_interp_instance_f16;
59    * </pre>
60    *
61    * \par
62    * where <code>numRows</code> specifies the number of rows in the table;
63    * <code>numCols</code> specifies the number of columns in the table;
64    * and <code>pData</code> points to an array of size <code>numRows*numCols</code> values.
65    * The data table <code>pTable</code> is organized in row order and the supplied data values fall on integer indexes.
66    * That is, table element (x,y) is located at <code>pTable[x + y*numCols]</code> where x and y are integers.
67    *
68    * \par
69    * Let <code>(x, y)</code> specify the desired interpolation point.  Then define:
70    * <pre>
71    *     XF = floor(x)
72    *     YF = floor(y)
73    * </pre>
74    * \par
75    * The interpolated output point is computed as:
76    * <pre>
77    *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
78    *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
79    *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
80    *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
81    * </pre>
82    * Note that the coordinates (x, y) contain integer and fractional components.
83    * The integer components specify which portion of the table to use while the
84    * fractional components control the interpolation processor.
85    *
86    * \par
87    * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output.
88    */
89 
90 
91   /**
92    * @addtogroup BilinearInterpolate
93    * @{
94    */
95 
96 
97   /**
98   * @brief  Floating-point bilinear interpolation.
99   * @param[in,out] S  points to an instance of the interpolation structure.
100   * @param[in]     X  interpolation coordinate.
101   * @param[in]     Y  interpolation coordinate.
102   * @return out interpolated value.
103   */
arm_bilinear_interp_f16(const arm_bilinear_interp_instance_f16 * S,float16_t X,float16_t Y)104   float16_t arm_bilinear_interp_f16(
105   const arm_bilinear_interp_instance_f16 * S,
106   float16_t X,
107   float16_t Y)
108   {
109     float16_t out;
110     float16_t f00, f01, f10, f11;
111     float16_t *pData = S->pData;
112     int32_t xIndex, yIndex, index;
113     float16_t xdiff, ydiff;
114     float16_t b1, b2, b3, b4;
115 
116     xIndex = (int32_t) X;
117     yIndex = (int32_t) Y;
118 
119     /* Care taken for table outside boundary */
120     /* Returns zero output when values are outside table boundary */
121     if (xIndex < 0 || xIndex > (S->numCols - 2) || yIndex < 0 || yIndex > (S->numRows - 2))
122     {
123       return (0);
124     }
125 
126     /* Calculation of index for two nearest points in X-direction */
127     index = (xIndex ) + (yIndex ) * S->numCols;
128 
129 
130     /* Read two nearest points in X-direction */
131     f00 = pData[index];
132     f01 = pData[index + 1];
133 
134     /* Calculation of index for two nearest points in Y-direction */
135     index = (xIndex ) + (yIndex+1) * S->numCols;
136 
137 
138     /* Read two nearest points in Y-direction */
139     f10 = pData[index];
140     f11 = pData[index + 1];
141 
142     /* Calculation of intermediate values */
143     b1 = f00;
144     b2 = f01 - f00;
145     b3 = f10 - f00;
146     b4 = f00 - f01 - f10 + f11;
147 
148     /* Calculation of fractional part in X */
149     xdiff = X - xIndex;
150 
151     /* Calculation of fractional part in Y */
152     ydiff = Y - yIndex;
153 
154     /* Calculation of bi-linear interpolated output */
155     out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff;
156 
157     /* return to application */
158     return (out);
159   }
160 
161   /**
162    * @} end of BilinearInterpolate group
163    */
164 
165 
166 #endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
167 
168