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