mirror of
https://github.com/dyne/frei0r.git
synced 2025-12-05 22:29:59 +01:00
added Elastic Scale, crop and Y scale to defish0r (#126)
* added Elastic Scale, crop and Y scale to defish0r Dynamic Stretch. -0.2 to 0.2. added a simplified version of the 'Elastic Scale' filter. fixes gopro up-scaled videos 4:3 to 16:9 thats used in GoPro's Superview Crop. true/false. crop all 4 borders straight. removing distorted sections Y scale. 1.5 to 0.5. independently scale Y axis added fix for Visual Studio roundf. VS 2013+ supports this function removed unnecessary calls to roundf in interpNN_b32(nearest neighbor). speed boost * fixed names, typos and float values
This commit is contained in:
@@ -37,6 +37,39 @@
|
|||||||
|
|
||||||
double PI=3.14159265358979;
|
double PI=3.14159265358979;
|
||||||
|
|
||||||
|
//add simplified 'Elestic Scale' to fix superview
|
||||||
|
float stretchWidth(int width, int widthCentre, float currentXPos, float stretchFactor)
|
||||||
|
{
|
||||||
|
double ratio, lowerWeight = 0.0, higherWeight = 0.0, linearRatio;
|
||||||
|
unsigned int lengthSection;
|
||||||
|
float relativeXPos = 0.0f;
|
||||||
|
|
||||||
|
//midline?
|
||||||
|
if (currentXPos < (float)widthCentre)
|
||||||
|
{
|
||||||
|
lengthSection = widthCentre - 1;
|
||||||
|
linearRatio = (double) ( currentXPos ) / lengthSection;
|
||||||
|
ratio = sin(linearRatio * PI - PI) * stretchFactor + linearRatio;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lengthSection = width - widthCentre - 1;
|
||||||
|
linearRatio = (double) ( currentXPos - widthCentre ) / lengthSection;
|
||||||
|
ratio = sin(linearRatio * PI) * stretchFactor + linearRatio;
|
||||||
|
}
|
||||||
|
ratio = ratio <= 0.0 ? 0.0 : ratio;
|
||||||
|
|
||||||
|
relativeXPos = (float) ( ratio * lengthSection );
|
||||||
|
|
||||||
|
if (currentXPos < (float)widthCentre)
|
||||||
|
relativeXPos -= currentXPos;
|
||||||
|
else
|
||||||
|
relativeXPos -= ( currentXPos - widthCentre );
|
||||||
|
|
||||||
|
return relativeXPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// r = 0...1 izhod = 0...maxr
|
// r = 0...1 izhod = 0...maxr
|
||||||
//ta funkcija da popacenje v odvisnosti od r
|
//ta funkcija da popacenje v odvisnosti od r
|
||||||
@@ -48,7 +81,7 @@ float fish(int n, float r, float f)
|
|||||||
switch (n)
|
switch (n)
|
||||||
{
|
{
|
||||||
case 0: //equidistant
|
case 0: //equidistant
|
||||||
ff=f*2.0/PI;
|
ff=f*2.0f/(float)PI;
|
||||||
rr=tanf(r/ff);
|
rr=tanf(r/ff);
|
||||||
break;
|
break;
|
||||||
case 1: //ortographic
|
case 1: //ortographic
|
||||||
@@ -59,15 +92,15 @@ float fish(int n, float r, float f)
|
|||||||
rr=tanf(asinf(ff));
|
rr=tanf(asinf(ff));
|
||||||
break;
|
break;
|
||||||
case 2: //equiarea
|
case 2: //equiarea
|
||||||
ff=r/2.0/f;
|
ff=r/2.0f/f;
|
||||||
if (ff>1.0)
|
if (ff>1.0f)
|
||||||
rr=-1.0;
|
rr=-1.0f;
|
||||||
else
|
else
|
||||||
rr=tanf(2.0*asinf(r/2.0/f));
|
rr=tanf(2.0f*asinf(r/2.0f/f));
|
||||||
break;
|
break;
|
||||||
case 3: //stereographic
|
case 3: //stereographic
|
||||||
ff=f*2.0/PI;
|
ff=f*2.0f/(float)PI;
|
||||||
rr=tanf(2.0*atanf(r/2.0/ff));
|
rr=tanf(2.0f*atanf(r/2.0f/ff));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// printf("Neznana fishitvena funkcija %d\n",n);
|
// printf("Neznana fishitvena funkcija %d\n",n);
|
||||||
@@ -86,16 +119,16 @@ float defish(int n, float r, float f, float mr)
|
|||||||
switch (n)
|
switch (n)
|
||||||
{
|
{
|
||||||
case 0: //equidistant
|
case 0: //equidistant
|
||||||
rr=f*2.0/PI*atanf(r*mr);
|
rr=f*2.0f/(float)PI*atanf(r*mr);
|
||||||
break;
|
break;
|
||||||
case 1: //ortographic
|
case 1: //ortographic
|
||||||
rr=f*sinf(atanf(r*mr));
|
rr=f*sinf(atanf(r*mr));
|
||||||
break;
|
break;
|
||||||
case 2: //equiarea
|
case 2: //equiarea
|
||||||
rr=2.0*f*sinf(atanf(r*mr)/2.0);
|
rr=2.0f*f*sinf(atanf(r*mr)/2.0f);
|
||||||
break;
|
break;
|
||||||
case 3: //stereographic
|
case 3: //stereographic
|
||||||
rr=f*4.0/PI*tanf(atanf(r*mr)/2.0);
|
rr=f*4.0f/(float)PI*tanf(atanf(r*mr)/2.0f);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// printf("Neznana fishitvena funkcija %d\n",n);
|
// printf("Neznana fishitvena funkcija %d\n",n);
|
||||||
@@ -119,26 +152,28 @@ float defish(int n, float r, float f, float mr)
|
|||||||
//scal = scaling factor
|
//scal = scaling factor
|
||||||
//pari, paro = pixel aspect ratio (input / output)
|
//pari, paro = pixel aspect ratio (input / output)
|
||||||
//dx, dy offset on input (for non-cosited chroma subsampling)
|
//dx, dy offset on input (for non-cosited chroma subsampling)
|
||||||
void fishmap(int wi, int hi, int wo, int ho, int n, float f, float scal, float pari, float paro, float dx, float dy, float *map)
|
void fishmap(int wi, int hi, int wo, int ho, int n, float f, float scal, float pari, float paro, float dx, float dy, float *map
|
||||||
|
, float stretchFactor, float yScale)
|
||||||
{
|
{
|
||||||
float rmax,maxr,r,kot,x,y,imax;
|
float rmax,maxr,r,kot,x,y,imax;
|
||||||
int i,j,ww,wi2,hi2,wo2,ho2;
|
int i, j, ww;
|
||||||
float ii,jj,sc;
|
float ii,jj,sc;
|
||||||
|
int wiMid = wi/2;
|
||||||
|
int hiMid = hi/2;
|
||||||
|
|
||||||
rmax=hypotf(ho/2.0,wo/2.0*paro);
|
rmax=hypotf(ho/2.0f,wo/2.0f*paro);
|
||||||
maxr=fish(n,1.0,f);
|
maxr=fish(n,1.0,f);
|
||||||
imax=hypotf(hi/2.0,wi/2.0*pari);
|
imax=hypotf(hi/2.0f,wi/2.0f*pari);
|
||||||
sc=imax/maxr;
|
sc=imax/maxr;
|
||||||
|
|
||||||
//printf("Fishmap: F=%5.2f Rmax= %7.2f Maxr=%6.2f sc=%6.2f scal=%6.2f\n",f,rmax,maxr,sc,scal);
|
//printf("Fishmap: F=%5.2f Rmax= %7.2f Maxr=%6.2f sc=%6.2f scal=%6.2f\n",f,rmax,maxr,sc,scal);
|
||||||
|
|
||||||
wi2=wi/2; hi2=hi/2; wo2=wo/2; ho2=ho/2;
|
for (i=0;i<hi;i++)
|
||||||
for (i=0;i<ho;i++)
|
|
||||||
{
|
{
|
||||||
ii=i-ho2;
|
ii=(float)(i-hiMid)*yScale; //add Y scale
|
||||||
for (j=0;j<wo;j++)
|
for (j=0;j<wi;j++)
|
||||||
{
|
{
|
||||||
jj=(j-wo2)*paro;
|
jj=(j-wiMid)*paro;
|
||||||
r=hypotf(ii,jj);
|
r=hypotf(ii,jj);
|
||||||
kot=atan2f(ii,jj);
|
kot=atan2f(ii,jj);
|
||||||
r=fish(n,r/rmax*scal,f)*sc;
|
r=fish(n,r/rmax*scal,f)*sc;
|
||||||
@@ -150,10 +185,12 @@ void fishmap(int wi, int hi, int wo, int ho, int n, float f, float scal, float p
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
x=wi2+r*cosf(kot)/pari;
|
x=wiMid+r*cosf(kot)/pari;
|
||||||
y=hi2+r*sinf(kot);
|
y=hiMid+r*sinf(kot);
|
||||||
if ((x>0)&(x<(wi-1))&(y>0)&(y<(hi-1)))
|
if ((x>0)&(x<(wi-1))&(y>0)&(y<(hi-1)))
|
||||||
{
|
{
|
||||||
|
if (stretchFactor != 0.0f)
|
||||||
|
x += stretchWidth(wo, wiMid, x, stretchFactor); //add stretch
|
||||||
map[ww]=x+dx;
|
map[ww]=x+dx;
|
||||||
map[ww+1]=y+dy;
|
map[ww+1]=y+dy;
|
||||||
}
|
}
|
||||||
@@ -165,9 +202,9 @@ void fishmap(int wi, int hi, int wo, int ho, int n, float f, float scal, float p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
//nafila array map s polozaji pikslov
|
//nafila array map s polozaji pikslov
|
||||||
//locena funkcija, da jo poklicem samo enkrat na zacetku,
|
//locena funkcija, da jo poklicem samo enkrat na zacetku,
|
||||||
@@ -179,30 +216,35 @@ void fishmap(int wi, int hi, int wo, int ho, int n, float f, float scal, float p
|
|||||||
//scal = scaling factor
|
//scal = scaling factor
|
||||||
//pari,paro = pixel aspect ratio (input / output)
|
//pari,paro = pixel aspect ratio (input / output)
|
||||||
//dx, dy offset on input (for non-cosited chroma subsampling)
|
//dx, dy offset on input (for non-cosited chroma subsampling)
|
||||||
void defishmap(int wi, int hi, int wo, int ho, int n, float f, float scal, float pari, float paro, float dx, float dy, float *map)
|
//lbox = letterbox
|
||||||
|
//stretch = dymanic stretch, convert between 4:3 and 16:9
|
||||||
|
//yScale = -0.5.. 0.5 change aspect ratio on y acess only
|
||||||
|
void defishmap(int wi, int hi, int wo, int ho, int n, float f, float scal, float pari, float paro, float dx, float dy, float *map
|
||||||
|
, int lbox, float stretchFactor, float yScale)
|
||||||
{
|
{
|
||||||
float rmax,maxr,r,kot,x,y,imax;
|
float rmax,maxr,r,kot,x,y,imax;
|
||||||
int i,j,ww,wi2,hi2,wo2,ho2;
|
int i,j,ww;
|
||||||
float ii,jj,sc;
|
float ii,jj,sc;
|
||||||
|
int wiMid = wi/2;
|
||||||
|
int hiMid = hi/2;
|
||||||
|
|
||||||
rmax=hypotf(ho/2.0,wo/2.0*paro);
|
rmax=hypotf(ho/2.0f,wo/2.0f*paro);
|
||||||
maxr=fish(n,1.0,f);
|
maxr=fish(n,1.0,f);
|
||||||
imax=hypotf(hi/2.0,wi/2.0*pari);
|
imax=hypotf(hi/2.0f,wi/2.0f*pari);
|
||||||
sc=imax/maxr;
|
sc=imax/maxr;
|
||||||
|
|
||||||
//printf("Defishmap: F=%f rmax= %f Maxr=%f sc=%6.2f scal=%6.2f\n",f,rmax,maxr,sc,scal);
|
//printf("Defishmap: F=%f rmax= %f Maxr=%f sc=%6.2f scal=%6.2f\n",f,rmax,maxr,sc,scal);
|
||||||
|
|
||||||
wi2=wi/2; hi2=hi/2; wo2=wo/2; ho2=ho/2;
|
for (i=0;i<hi;i++)
|
||||||
for (i=0;i<ho;i++)
|
|
||||||
{
|
{
|
||||||
ii=i-ho2;
|
ii = (float)(i-hiMid)*yScale; //add Y scale
|
||||||
for (j=0;j<wo;j++)
|
for (j=0;j<wi;j++)
|
||||||
{
|
{
|
||||||
jj=(j-wo2)*paro; //aspect....
|
jj=(j-wiMid)*paro; //aspect....
|
||||||
r=hypotf(ii,jj)/scal;
|
r=hypotf(ii,jj)/scal;
|
||||||
kot=atan2f(ii,jj);
|
kot=atan2f(ii,jj);
|
||||||
ww=2*(wo*i+j);
|
ww=2*(wi*i+j);
|
||||||
r=defish(n,r/sc,f,1.0)*rmax;
|
r=defish(n,r/sc,f,1.0)*imax;
|
||||||
if (r<0.0)
|
if (r<0.0)
|
||||||
{
|
{
|
||||||
map[ww]=-1;
|
map[ww]=-1;
|
||||||
@@ -210,10 +252,14 @@ void defishmap(int wi, int hi, int wo, int ho, int n, float f, float scal, float
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
x=wi2+r*cosf(kot)/pari;
|
x=wiMid+r*cosf(kot)/pari;
|
||||||
y=hi2+r*sinf(kot);
|
y=hiMid+r*sinf(kot);
|
||||||
if ((x>0)&(x<(wi-1))&(y>0)&(y<(hi-1)))
|
|
||||||
|
if ((x>0)&&(x<(wi-1))&&(y>0)&&(y<(hi-1)))
|
||||||
{
|
{
|
||||||
|
if (stretchFactor != 0.0f)
|
||||||
|
x += stretchWidth(wi, wiMid, x, stretchFactor); //add stretch
|
||||||
|
|
||||||
map[ww]=x;
|
map[ww]=x;
|
||||||
map[ww+1]=y;
|
map[ww+1]=y;
|
||||||
}
|
}
|
||||||
@@ -225,6 +271,38 @@ void defishmap(int wi, int hi, int wo, int ho, int n, float f, float scal, float
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//crop all 4 borders
|
||||||
|
if (lbox)
|
||||||
|
{ //top/bottom
|
||||||
|
for (i = 0; i < hi; i++)
|
||||||
|
{
|
||||||
|
ww = 2 * (wi*i + wiMid);
|
||||||
|
if (map[ww] <= 0)
|
||||||
|
{
|
||||||
|
for (j = 0; j < wi; j++)
|
||||||
|
{ //clear entire row
|
||||||
|
ww = 2 * (wi*i + j);
|
||||||
|
map[ww] = -1;
|
||||||
|
map[ww + 1] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//left/right
|
||||||
|
for (i = 0; i < wi; i++)
|
||||||
|
{
|
||||||
|
ww = 2 * (wi*hiMid +i);
|
||||||
|
if (map[ww] <= 0)
|
||||||
|
{
|
||||||
|
for (j = 0; j < hi; j++)
|
||||||
|
{ //clear entire column
|
||||||
|
ww = 2 * (wi*j + i);
|
||||||
|
map[ww] = -1;
|
||||||
|
map[ww + 1] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=====================================================
|
//=====================================================
|
||||||
@@ -237,6 +315,8 @@ void defishmap(int wi, int hi, int wo, int ho, int n, float f, float scal, float
|
|||||||
//intp: 0..6 type of interpolator
|
//intp: 0..6 type of interpolator
|
||||||
//aspt: 0..4 aspect type square, PAL, NTSC, HDV, manual
|
//aspt: 0..4 aspect type square, PAL, NTSC, HDV, manual
|
||||||
//par: pixel aspect ratio
|
//par: pixel aspect ratio
|
||||||
|
//lbox: 1=letterbox
|
||||||
|
//stretch 0..1 stretch video to fix superview distorsion
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int w;
|
int w;
|
||||||
@@ -251,6 +331,9 @@ typedef struct
|
|||||||
float mpar;
|
float mpar;
|
||||||
float par;
|
float par;
|
||||||
float *map;
|
float *map;
|
||||||
|
int lbox;
|
||||||
|
float stretch;
|
||||||
|
float yScale;
|
||||||
interpp interpol;
|
interpp interpol;
|
||||||
} param;
|
} param;
|
||||||
|
|
||||||
@@ -297,7 +380,7 @@ void make_map(param p)
|
|||||||
case 3: //manual
|
case 3: //manual
|
||||||
dscal=p.mscale; break;
|
dscal=p.mscale; break;
|
||||||
}
|
}
|
||||||
defishmap(p.w ,p.h ,p.w ,p.h, p.type, p.f, dscal, p.par, p.par, 0.0, 0.0, p.map);
|
defishmap(p.w ,p.h ,p.w ,p.h, p.type, p.f, dscal, p.par, p.par, 0.0, 0.0, p.map, p.lbox, p.stretch, p.yScale);
|
||||||
}
|
}
|
||||||
else //fish
|
else //fish
|
||||||
{
|
{
|
||||||
@@ -315,7 +398,7 @@ void make_map(param p)
|
|||||||
case 3: //manual
|
case 3: //manual
|
||||||
fscal=1.0/p.mscale; break;
|
fscal=1.0/p.mscale; break;
|
||||||
}
|
}
|
||||||
fishmap(p.w, p.h, p.w ,p.h, p.type, p.f, fscal, p.par, p.par, 0.0, 0.0, p.map);
|
fishmap(p.w, p.h, p.w ,p.h, p.type, p.f, fscal, p.par, p.par, 0.0, 0.0, p.map, p.stretch, p.yScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -344,8 +427,8 @@ void f0r_get_plugin_info(f0r_plugin_info_t* info)
|
|||||||
info->color_model=F0R_COLOR_MODEL_RGBA8888;
|
info->color_model=F0R_COLOR_MODEL_RGBA8888;
|
||||||
info->frei0r_version=FREI0R_MAJOR_VERSION;
|
info->frei0r_version=FREI0R_MAJOR_VERSION;
|
||||||
info->major_version=0;
|
info->major_version=0;
|
||||||
info->minor_version=3;
|
info->minor_version=4;
|
||||||
info->num_params=8;
|
info->num_params=11;
|
||||||
info->explanation="Non rectilinear lens mappings";
|
info->explanation="Non rectilinear lens mappings";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,6 +477,21 @@ void f0r_get_param_info(f0r_param_info_t* info, int param_index)
|
|||||||
info->type = F0R_PARAM_DOUBLE;
|
info->type = F0R_PARAM_DOUBLE;
|
||||||
info->explanation = "Manual Pixel Aspect ratio";
|
info->explanation = "Manual Pixel Aspect ratio";
|
||||||
break;
|
break;
|
||||||
|
case 8:
|
||||||
|
info->name = "Crop";
|
||||||
|
info->type = F0R_PARAM_BOOL;
|
||||||
|
info->explanation = "Straighten all edges of video frame";
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
info->name = "Non-Linear scale";
|
||||||
|
info->type = F0R_PARAM_DOUBLE;
|
||||||
|
info->explanation = "Fix camera scaling between 4:3 and 16:9";
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
info->name = "Y Scale";
|
||||||
|
info->type = F0R_PARAM_DOUBLE;
|
||||||
|
info->explanation = "Scale Y to affect aspect ratio";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -417,6 +515,9 @@ f0r_instance_t f0r_construct(unsigned int width, unsigned int height)
|
|||||||
p->aspt=0; //square pixels
|
p->aspt=0; //square pixels
|
||||||
p->par=1.0; //square pixels
|
p->par=1.0; //square pixels
|
||||||
p->mpar=1.0;
|
p->mpar=1.0;
|
||||||
|
p->lbox=0; //letterbox
|
||||||
|
p->stretch = 0.0f; //dynamic stretch
|
||||||
|
p->yScale = 1.0f; //seperate Y stretch
|
||||||
|
|
||||||
p->map=(float*)calloc(1, sizeof(float)*(p->w*p->h*2+2));
|
p->map=(float*)calloc(1, sizeof(float)*(p->w*p->h*2+2));
|
||||||
p->interpol=set_intp(*p);
|
p->interpol=set_intp(*p);
|
||||||
@@ -578,6 +679,21 @@ void f0r_set_param_value(f0r_instance_t instance, f0r_param_t parm, int param_in
|
|||||||
if (p->mpar != tmpf) chg=1;
|
if (p->mpar != tmpf) chg=1;
|
||||||
p->mpar=tmpf;
|
p->mpar=tmpf;
|
||||||
break;
|
break;
|
||||||
|
case 8: //letterbox
|
||||||
|
tmpi=(int)map_value_forward(*((double*)parm), 0.0f, 1.0f);//BOOL!!
|
||||||
|
if (p->lbox != tmpi) chg=1;
|
||||||
|
p->lbox=tmpi;
|
||||||
|
break;
|
||||||
|
case 9: //stretch
|
||||||
|
tmpf=map_value_forward(*((double*)parm), -0.2f, 0.2f);
|
||||||
|
if (p->stretch != tmpf) chg=1;
|
||||||
|
p->stretch=tmpf;
|
||||||
|
break;
|
||||||
|
case 10: //Y scale
|
||||||
|
tmpf=map_value_forward(*((double*)parm), 1.5f, 0.5f);
|
||||||
|
if (p->yScale != tmpf) chg=1;
|
||||||
|
p->yScale=tmpf;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chg!=0)
|
if (chg!=0)
|
||||||
@@ -633,6 +749,15 @@ void f0r_get_param_value(f0r_instance_t instance, f0r_param_t parm, int param_in
|
|||||||
case 7: //manual aspect
|
case 7: //manual aspect
|
||||||
*((double*)parm)=map_value_backward_log(p->mpar, 0.5, 2.0);
|
*((double*)parm)=map_value_backward_log(p->mpar, 0.5, 2.0);
|
||||||
break;
|
break;
|
||||||
|
case 8: //letterbox
|
||||||
|
*((double*)parm)=map_value_backward((float)p->lbox, 0.0f, 1.0f); //BOOL!!
|
||||||
|
break;
|
||||||
|
case 9: //stretch/upscale fix
|
||||||
|
*((double*)parm)=map_value_backward_log(p->stretch, -0.2f, 0.2f);
|
||||||
|
break;
|
||||||
|
case 10: //Y scale
|
||||||
|
*((double*)parm)=map_value_backward(p->yScale, 1.5f, 0.5f);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ void remap32(int wi, int hi, int wo, int ho, unsigned char *vhs, unsigned char *
|
|||||||
//**************************************
|
//**************************************
|
||||||
//HERE BEGIN THE INTERPOLATION FUNCTIONS
|
//HERE BEGIN THE INTERPOLATION FUNCTIONS
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER) && _MSC_VER < 1800
|
||||||
__inline const float roundf(float x){
|
__inline const float roundf(float x){
|
||||||
return (int)floor(x+0.5);
|
return (int)floor(x+0.5);
|
||||||
}
|
}
|
||||||
@@ -162,14 +162,17 @@ int interpNN_b(unsigned char *sl, int w, int h, float x, float y, unsigned char
|
|||||||
// *v interpolirana vrednost
|
// *v interpolirana vrednost
|
||||||
int interpNN_b32(unsigned char *sl, int w, int h, float x, float y, unsigned char *v)
|
int interpNN_b32(unsigned char *sl, int w, int h, float x, float y, unsigned char *v)
|
||||||
{
|
{
|
||||||
|
//int index = (int)(x+0.5f)*4+(int)(y+0.5f)*4*w; //fast rounding
|
||||||
|
int index = (int)roundf(x)*4+(int)roundf(y)*4*w; //call once
|
||||||
|
|
||||||
#ifdef TEST_XY_LIMITS
|
#ifdef TEST_XY_LIMITS
|
||||||
if ((x<0)||(x>w)||(y<0)||(y>h)) return -1;
|
if ((x<0)||(x>w)||(y<0)||(y>h)) return -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
v[0]=sl[(int)roundf(x)*4+(int)roundf(y)*4*w];
|
v[0]=sl[index];
|
||||||
v[1]=sl[(int)roundf(x)*4+(int)roundf(y)*4*w+1];
|
v[1]=sl[index+1];
|
||||||
v[2]=sl[(int)roundf(x)*4+(int)roundf(y)*4*w+2];
|
v[2]=sl[index+2];
|
||||||
v[3]=sl[(int)roundf(x)*4+(int)roundf(y)*4*w+3];
|
v[3]=sl[index+3];
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user