/****************************************************************************** * * Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * Use of the Software is limited solely to applications: * (a) running on a Xilinx device, or * (b) that interact with a Xilinx device through a bus or interconnect. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of the Xilinx shall not be used * in advertising or otherwise to promote the sale, use or other dealings in * this Software without prior written authorization from Xilinx. * ******************************************************************************/ /** * * @file xscaler_coefs.c * * This file contains Lanczos coefficient generation for use in the Xilinx Video Scaler. * * * *
* MODIFICATION HISTORY:
*
* Ver   Who  Date     Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a xd   06/15/09 First release. Coefficients are auto-generated in
*                     Matlab using
*                     /Video_Scaler/reference_model/src/CreateCoefficients.m
* 2.00a xd   12/14/09 Updated doxygen document tags
* 5.00a mpv  12/13/13 Updated to dynamic coeff generation to reduce driver size
* 7.0   adk  08/22/14 Removed typedef unsigned short s16 as it was already
*                     defined in xil_types.h.
*                     Updated doxygen document tags.
*                     XScaler_coef_table is made as a global variable.
*                     Memory allocated was freed after usage.
* 
* ******************************************************************************/ #include "xscaler.h" /************************** Constant Definitions *****************************/ /** @name PI definition * @{ */ #define PI 3.14159265358979 /*@}*/ /************************* Data Structure Definitions ************************/ /** * XScaler_CoefficientsBinScalingFactors contains scaling factors calculated * using (Output_Size * 10000 / Input_Size). This table could help find * the index of coefficient Bin given an input size and a output size. */ u16 XScaler_CoefficientBinScalingFactors[XSCL_NUM_COEF_BINS] = { 20000, 625, 1250, 1875, 2500, 3125, 3750, 4375, 5000, 5625, 6250, 6875, 7500, 8125, 8750, 9375, 10000, 10000, 6666 }; s16* XScaler_coef_table = NULL; /**< Coefficients table */ /** * This structure contains a pointer to double dimensional array which will be * filled by coefficients. */ struct coefs_struct{ short int** coefficients; }SingleFrameCoefs; /************************** Function Definitions ******************************/ /*****************************************************************************/ /** * This function allocates memory to a double dimensional array. * * @param Coefs is a pointer to Coefs_Struct structure which has a * double dimensional array which needs to be allocated memory. * @param Max_Taps indicates the number of taps which is used to allocate * that number of columns. * @param Max_Phases indicates the number of phases which is used to * allocate that number of rows. * * @return * 1 - Indicates allocation of memory is failed. * 0 - Indicates allocation of memory is success. * * @note None. * ******************************************************************************/ int XScaler_AllocCoefsBuff(struct coefs_struct* Coefs, u32 Max_Taps, u32 Max_Phases) { u32 Phase; if ((Coefs->coefficients = (s16 **) ((s16**)calloc(Max_Phases, sizeof(s16*)))) == 0) { return(1); } for (Phase = 0; Phase < Max_Phases; Phase++) { if ((Coefs->coefficients[Phase] = (s16 *) ((s16*)calloc(Max_Taps, sizeof(s16)))) == 0) { return(1); } } return(0); } /*****************************************************************************/ /** * This Sine generation algorithm implements Taylor series decomposition of the * Sine function. * * @param x is a float variable which needs to be set. * * @return Returns Taylor series. * * @note It works according to * http://en.wikipedia.org/wiki/Taylor_series#Approximation_and_convergence * * ******************************************************************************/ float XScaler_Sine(float x) { int n, fac=1; float px, taylor=0; float rng = ((x-PI)/PI); x = x - rng*PI; px = x; for (n=0;n<6;n++) { taylor += (px / fac); px *= -(x*x); fac *= (2*n+2)*(2*n+3); } return taylor; } /*****************************************************************************/ /** * This function generates coffficient. * * @param x is a float varaible based on which coefficient is * generated. * @param a is a 32 bit variable which holds half of the number of taps. * * @return Returns Coefficient value depending on inputs. * * @note It works according to * http://en.wikipedia.org/wiki/Taylor_series#Approximation_and_convergence * * ******************************************************************************/ float XScaler_Lanczos(float x, int a) { return((x<-a) ? 0 : ((x>a) ? 0 : ((x==0) ? 1.0 : ( a*XScaler_Sine(PI*x)*XScaler_Sine(PI*x/a)/(PI*PI*x*x))))); } /*****************************************************************************/ /** * This coefficient generation algorithm implements the Lanczos coefficients. * For a particular scaling ratio, the coefficients can be pre-canned to memory. * * @param p is a float variable. * @param icoeffs is a pointer to a single row of Coefficients array * which is in SingleFrameCoefs structure. * @param NCOEFF is variable which holds number of taps which indicates * the number of columns * * @return None. * * @note It works according to * http://en.wikipedia.org/wiki/Lanczos_resampling. * ******************************************************************************/ void XScaler_GetLanczosCoeffs(float p, short int icoeffs[], int NCOEFF) { float s=0; float coeff[64]; int i; /* To implement convolution using the * 2D FIR kernel, coefficient order is reversed */ for (i=0; i>1)+p, (NCOEFF>>1))); } /* Normalize coefficients, so sum()=1 for all phases.*/ for (i=0; i