📄 _csl_reszcalcreszvalue.c
字号:
/** @file _csl_reszCalcReszValue.c
*
* @brief File for functional layer of CSL API @a CSL_reszCalcReszValue()
*
* Description
* - The @a CSL_reszCalcReszValue() function definition & it's associated
* functions
*
* @date 10th May, 2005
* @author Jesse Villarreal
*
* @date 25th Aug, 2005
* @author Jesse Villarreal
*/
#include <csl_resz_aux.h>
#pragma CODE_SECTION (CSL_reszCalcReszValue, ".text:csl_section:resz");
/** @brief Calculates the appropriate Resize value or Input Size
* There are 2 modes of calculation in this function:
* 1. Input & Output sizes known (Calculate Resize Value)
* Set 'input', 'output', and 'phase' to their desired values
* and set ratio = 0. The return struct will set the appropriate
* rsz value and may modify the input value to meet restrictions.
* 2. Resize value & Output size known (Calculate Required Input Size)
* Set 'ratio', 'output', and 'phase' to their desired values
* and set input = 0. The return struct will set the appropriate
* input value.
*
* For mode 1 above, the resize ratio may be calculated under the following 2 conditions:
* 1. inMax = TRUE. The input passed to this function is the maximum allowable input.
* This can be the case if the input is the output of the preview engine, or the input
* from SDRAM is the whole image.
* 2. inMax = FALSE. The input passed to this function is at least 3 pixels from both sides of
* the actual edge of the image (padded data available). This is applicable when resizing
* a smaller portion of an image.
*
*
* Notes: This function expects that either the 'input' or the 'ratio' value is
* set to 0. If they are both 0, then the CSL_ESYS_INVPARAMS error
* is returned.
*/
CSL_Status CSL_reszCalcReszValue(
/** Pointer to the object that holds reference to the
* instance of RESZ requested after the call
*/
CSL_ReszHandle hResz,
/** Pointer to structure holding the data
*/
CSL_ReszCalcReszVal *data
){
Uint16 input, org_input, output, rsz;
Uint8 shifter = 0; // instantiated to 0 for resize of 0.5x .. 4.0x
Uint8 offset = 7; // instantiated for the common case (not vertical 0.5x .. 4.0x)
Uint8 stPh, numPhases, endPhase;
Int16 stPix, phase, pixAlign;
// Bool tap7 = FALSE;
if(data == NULL) return (CSL_ESYS_INVPARAMS);
input = *data->input;
org_input = *data->input;
output = *data->output;
phase = *data->phase;
rsz = *data->ratio;
if( (!input && !rsz) || !output) // Check for invalid parameters
return (CSL_ESYS_INVPARAMS);
// If the input was set (calculate resize ratio, adjust input)
if(input != 0)
{
if(data->inMax)
{
input -= 6;
pixAlign = 0;
rsz = input * 256 / output; // initial ratio calculation
if(rsz<=512) // 4 tap
{
if(data->horzDir)
{
if(data->inSdram)
{
pixAlign = 3;
input +=2;
stPix = 0;
stPh = 1;
}
else
{
input -=4;
stPix = 3;
stPh = 1;
}
}
else
{
input +=2;
stPix = 0;
stPh = 1;
}
rsz = input * 256 / output;
if(rsz>512)
{
input -=2;
rsz = 512;
}
}
else
{
stPix = 0;
stPh = 1;
}
}
else
{
rsz = input * 256 / output;
if(rsz<=512 && !(data->horzDir && !data->inSdram))
pixAlign = 3;
else
pixAlign = 6;
}
}
// Set the start pixel and phase for the rest of the cases
if(org_input == 0 || (org_input != 0 && !data->inMax))
{
if(rsz>512)
{
stPix = -3;
stPh = 2;
}
else
{
stPix = -1;
stPh = 0;
}
}
// Adjust the phase and start pixel
numPhases = (rsz>512) ? 4 : 8;
phase += stPh;
stPix += phase / numPhases;
phase %= numPhases;
// Rsz ratio is given (or calculated), compute (adjust) input size
if(rsz>512) // 0.25x .. ~0.5x -> 7 tap
{
shifter = 1;
}
else if(!data->horzDir) // 0.5x .. 4.0x -> 4 tap vertical
offset = 4;
// Instead of just finding input in one shot, break apart to find end phase as well
// input = ((phase<<(5+shifter)) + (16<<shifter) + ((output-1)*rsz)>>8) + offset;
{
long fip, cip;
fip = (phase<<(5+shifter)) + (16<<shifter) + ((output-1)*rsz);
cip = fip >> (5+shifter);
input = cip/numPhases + offset;
endPhase = cip % numPhases;
}
if(data->inMax)
phase += ((org_input - stPix + pixAlign - input)*numPhases - (numPhases - 1 - endPhase))>>1;
else
phase += ((org_input + pixAlign - input)*numPhases - endPhase)>>1;
if(phase < 0)
{
stPix += (phase+1) / numPhases - 1;
phase = (phase%numPhases) + numPhases;
}
else
{
stPix += phase / numPhases;
phase %= numPhases;
}
// Recalculating input size since the phase may have changed.
input = ((phase<<(5+shifter)) + (16<<shifter) + ((output-1)*rsz)>>8) + offset;
/* Old implementation removed 8/24/05 by Jesse Villarreal*/
/*
if(!rsz) // Calculate ratio (and maybe adjust input)
{
// output = input x (256/rsz)
rsz = (input<<8)/output;
}
if(rsz>512) // 0.25x .. ~0.5x -> 7 tap
{
shifter = 1;
tap7 = TRUE;
}
else if(!data->horzDir) // 0.5x .. 4.0x -> 4 tap vertical
offset = 4;
if(input && data->inMax) // Fine tune ratio and input size
{
Uint32 temp;
// This calculation guarantees that the input is ALWAYS equal to or less than the given input
rsz = ( ((input - offset)<<8) - (phase<<(5+shifter)) - (16<<shifter) )/(output-1);
if(tap7 && rsz <= 512) // if calculation has changed rsz from 7tap to 4tap (0.42% chance)
{
shifter = 0;
if(!data->horzDir) // 0.5x .. 4.0x -> 4 tap vertical
offset = 4;
rsz = ( ((input - offset)<<8) - (phase<<(5+shifter)) - (16<<shifter) )/(output-1);
if(rsz > 512) // if this happens, there is more calculations to guarantee a closer
rsz = 512; // input size, but the amount off is a only a few pixels,
// the chance of this happening is 0.04% and the extra code is not worth it.
}
temp = (phase<<(5+shifter)) + (16<<shifter);
// Checks to see if incrementing the ratio will get a closer input calculation
if(rsz!=512 && (input = ((temp + (output-1)*(rsz+1))>>8) + offset) <= *data->input)
rsz++;
else
input = ((temp + (output-1)*rsz)>>8) + offset;
}
else // Calculate input
{
input = ((phase<<(5+shifter)) + (16<<shifter) + ((output-1)*rsz)>>8) + offset;
}
*/
*data->ratio = rsz;
*data->input = input;
*data->phase = phase;
data->stPix = stPix;
if(rsz < 64 || rsz > 1024) {
return (CSL_ESYS_INVPARAMS);
}
return (CSL_SOK);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -