/ Drivers / CMSIS / DSP / Source / InterpolationFunctions / arm_bilinear_interp_f16.c
arm_bilinear_interp_f16.c
  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    */
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 = (_Float16)f01 - (_Float16)f00;
145      b3 = (_Float16)f10 - (_Float16)f00;
146      b4 = (_Float16)f00 - (_Float16)f01 - (_Float16)f10 + (_Float16)f11;
147  
148      /* Calculation of fractional part in X */
149      xdiff = (_Float16)X - (_Float16)xIndex;
150  
151      /* Calculation of fractional part in Y */
152      ydiff = (_Float16)Y - (_Float16)yIndex;
153  
154      /* Calculation of bi-linear interpolated output */
155      out = (_Float16)b1 + (_Float16)b2 * (_Float16)xdiff + 
156      (_Float16)b3 * (_Float16)ydiff + (_Float16)b4 * (_Float16)xdiff * (_Float16)ydiff;
157  
158      /* return to application */
159      return (out);
160    }
161  
162    /**
163     * @} end of BilinearInterpolate group
164     */
165  
166  
167  #endif /* #if defined(ARM_FLOAT16_SUPPORTED) */ 
168