/* ---------------------------------------------------------------------- * Project: CMSIS DSP Library * Title: arm_linear_interp_q7.c * Description: Q7 linear interpolation * * $Date: 23 April 2021 * $Revision: V1.9.0 * * Target Processor: Cortex-M and Cortex-A cores * -------------------------------------------------------------------- */ /* * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "dsp/interpolation_functions.h" /** @ingroup groupInterpolation */ /** * @addtogroup BilinearInterpolate * @{ */ /** * @brief Q7 bilinear interpolation. * @param[in,out] S points to an instance of the interpolation structure. * @param[in] X interpolation coordinate in 12.20 format. * @param[in] Y interpolation coordinate in 12.20 format. * @return out interpolated value. */ q7_t arm_bilinear_interp_q7( arm_bilinear_interp_instance_q7 * S, q31_t X, q31_t Y) { q63_t acc = 0; /* output */ q31_t out; /* Temporary output */ q31_t xfract, yfract; /* X, Y fractional parts */ q7_t x1, x2, y1, y2; /* Nearest output values */ int32_t rI, cI; /* Row and column indices */ q7_t *pYData = S->pData; /* pointer to output table values */ uint32_t nCols = S->numCols; /* num of rows */ /* Input is in 12.20 format */ /* 12 bits for the table index */ /* Index value calculation */ rI = ((X & (q31_t)0xFFF00000) >> 20); /* Input is in 12.20 format */ /* 12 bits for the table index */ /* Index value calculation */ cI = ((Y & (q31_t)0xFFF00000) >> 20); /* Care taken for table outside boundary */ /* Returns zero output when values are outside table boundary */ if (rI < 0 || rI > (S->numCols - 2) || cI < 0 || cI > (S->numRows - 2)) { return (0); } /* 20 bits for the fractional part */ /* xfract should be in 12.20 format */ xfract = (X & (q31_t)0x000FFFFF); /* Read two nearest output values from the index */ x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; /* 20 bits for the fractional part */ /* yfract should be in 12.20 format */ yfract = (Y & (q31_t)0x000FFFFF); /* Read two nearest output values from the index */ y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ out = ((x1 * (0xFFFFF - xfract))); acc = (((q63_t) out * (0xFFFFF - yfract))); /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ out = ((x2 * (0xFFFFF - yfract))); acc += (((q63_t) out * (xfract))); /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ out = ((y1 * (0xFFFFF - xfract))); acc += (((q63_t) out * (yfract))); /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ out = ((y2 * (yfract))); acc += (((q63_t) out * (xfract))); /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ return ((q7_t)(acc >> 40)); } /** * @} end of BilinearInterpolate group */