📄 hplx_vert.c
字号:
/*****************************************************************************/
/* Copyright 1998, Hewlett-Packard Company */
/* All rights reserved */
/* Author: Christos Chrysafis */
/* Version: V2.1 */
/* Last Revised: 10/2/98 */
/*****************************************************************************/
#include <local_heap.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <hplx_def.h>
#include <line_block_ifc.h>
#include <memory.h>
/********************************************************/
int float2int(float fl)
{
int tmp;
#if defined (WIN32) && !defined (__GNUC__)
_asm{ fld fl
fistp tmp}
#else
tmp=(int) ( fl +( (fl>0) ? 0.5F : -0.5F ) );
#endif
return(tmp);
}
/***********************************************************************************/
/* inner product two lines at a time */
/**********************************************************************************/
void two_at_once(int plus, int *flag,int i,float m,float *a,float *b,float *c)
{
if(!m) return;
if(plus)
{if(*flag)
while(i--)
*a++ = ( *b++ + *c++) * m;
else
while(i--)
*a++ += ( *b++ + *c++) * m;}
else{
if(*flag)
while(i--)
*a++ = m * ( *b++ - *c++);
else
while(i--)
*a++ += m * ( *b++ - *c++);
}
*flag=0;
}
/****************************************************/
void two_at_once_fixed(int plus, int *flag,int i,int m,int *a,int *b,int *c)
{
if(!m) return;
if(plus)
{if(*flag)
while(i--)
*a++ = m * ( *b++ + *c++);
else
while(i--)
*a++ += m * ( *b++ + *c++);}
else{
if(*flag)
while(i--)
*a++ = m * ( *b++ - *c++);
else
while(i--)
*a++ += m * ( *b++ - *c++);
}
*flag=0;
}
/***********************************************************************************/
/* inner product one line at a time */
/**********************************************************************************/
void one_at_once(int *flag,int i,float m,float *a,float *b)
{
if(!m) return;
if(*flag)
while(i--)
*a++ = m * *b++ ;
else
while(i--)
*a++ += m * *b++ ;
*flag=0;
}
/*********************************************************************
* performs analysis along the vertical direction
*
**********************************************************************/
static int
transform_line_based_analysis(transform_ref self,float *ptr)
{
int LowPassTrue,k,inc,flag,L,NevenF;
float *in_indx2,*low,*buf;
int m,n,g,N;
L=self->h;
++self->Cpeek;
NevenF=!self->EvenFilter;
inc=(int)self->w;
N=self->Cpoke - self->Middle;
/* If we do not have a single line at the end of the image line*/
if(N != self->ImageRows || !self->LoneLine)
{
LowPassTrue= N & 1;
if ( LowPassTrue || NevenF)
{
for( k = 0 ; k < 1 +!NevenF ; k++,LowPassTrue=!LowPassTrue)
{ buf= (LowPassTrue||NevenF) ? ptr : self->SecBuf;
low= LowPassTrue ? self->LowA : self->HighA;
flag=1;
in_indx2=*self->_data ;
m=L>>1;
n=N-NevenF;
g=n+L-1;
while(m--)
two_at_once(LowPassTrue||NevenF,&flag,inc,*(low++),
buf,
in_indx2 + inc * ( (n++)%L),
in_indx2 + inc * ( (g--)%L));
if(NevenF)
one_at_once(&flag,inc,*(low++),buf,in_indx2 + inc * ( (n++)%L));
}
}
else /* this is the High pass in the case of Even length Filters*/
memcpy( ptr , self->SecBuf , sizeof(float) * inc );
}
else /* This is the line at the end of the band if Even Filter, Odd signal*/
memcpy( ptr , self->ExtraLine , sizeof(float) * inc );
return(0);
}
/*********************************************************************
* performs synthesis along the vertical direcion
*
**********************************************************************/
static int transform_line_based_synthesis(transform_ref self,float *ptr)
{
int LowPassTrue,k,h,flag,N,m,n,NevenF,g;
int inc;
float *low,*buf;
float *in_indx2;
inc=self->w;
h=self->h;
N=self->Cpoke - self->Middle;
NevenF=!self->EvenFilter;
if(N != self->ImageRows || ! self->LoneLine)
{
LowPassTrue=( N -!NevenF ) & 1;
if( (NevenF) || (!LowPassTrue))
{
for( k = 0 ; k < 1 + !NevenF ; k++, LowPassTrue=!LowPassTrue)
{
low=LowPassTrue ? self->LowS:self->HighS;
buf=(!NevenF&&LowPassTrue )?self->SecBuf:ptr;
/***********************************/
flag=1;
in_indx2=*self->_data;
n=N-NevenF;
m=h;
if(!NevenF) /*Even Length Filter */
while(m--)
one_at_once(&flag,inc,*(low++),buf,in_indx2 + inc * ( (n++)%h));
else /* Odd Length Filter */
{m>>=1;
g=n+h-1;
while(m--)
two_at_once(LowPassTrue||NevenF,&flag,inc,*(low++),
buf,
in_indx2 + inc * ( (n++)%h),
in_indx2 + inc * ( (g--)%h));
one_at_once(&flag,inc,*(low++),buf,in_indx2 + inc * ( (n++)%h));
}
}
}
else
memcpy( ptr , self->SecBuf , sizeof(float) * inc );
}
else
memcpy( ptr , self->ExtraLine , sizeof(float) * inc );
return(0);
}
/*********************************************************************/
/* updates some state information and
* performs symetric extension when needed
*/
/**********************************************************************/
static void transform_line_based_update(transform_ref self)
{
int i,j,k;
float *tmp_ptr,*tmp1;
if(self->Cpoke < self->Middle + self->maxY )
{
self->RawData=
self->_data[(self->Cpoke+self->Middle)%self->h];
if( ( (int)(self->Cpoke) >= (int)(self->maxY) ) &&
( (int)(self->ImageRows) > 0 ) ) /* End of the Image*/
{
k=(self->Cpoke-self->maxY);
i= self->ImageRows- k - 2 + self->EvenFilter +
self->Middle + self->h-self->TrueExtra;
if(self->UsedAsAnalysis || !self->EvenFilter)
memcpy( self->RawData, self->_data[i%self->h] ,
sizeof(float) * self->w);
else
{
if( !( k & 1 ) ) /* Low */
memcpy( self->RawData, self->_data[ (--i) % self->h ] , sizeof(float) * self->w);
else
{ /* High */
tmp_ptr = self->RawData;
tmp1=self->_data[ (++i) % self->h];
for(j = 0 ; j < self->w; j++ )
*(tmp_ptr++) = -*(tmp1++);
}
}
}
else /*Begining of the image*/
{
if( self->Cpoke == self->Middle )
{
if( self->UsedAsAnalysis || !self->EvenFilter)
{
for( i = self->EvenFilter; i < self->Middle; i++)
memcpy( self->_data[i],
self->_data[(int)(self->h)-i-1] ,
sizeof(float) * self->w);
}
else
{
/* This is the Low */
for( i = self->Middle - 2 ; i >= (int)(self->EvenFilter); i-=2)
memcpy( self->_data[i],
self->_data[2*(int)(self->Middle)-2-i] ,
sizeof(float) * self->w);
/* Self is the High */
for( i=self->Middle - 1;i>=(int)(self->EvenFilter);i-=2)
{
tmp_ptr = self->_data[i];
tmp1=self->_data[2*self->Middle-i];
for(j=0;j<self->w;j++) *(tmp_ptr++) = -*(tmp1++);
}
}
}
}
}
self->Cpoke++;
if( (self->Cpoke != self->maxY) || (!self->LoneLine))
self->RawData = self->_data[(self->Cpoke+self->Middle)%self->h];
else
{
self->RawData=self->ExtraLine;
self->TrueExtra=1;
}
}
/*********************************************************************
* performs analysis along the vertical direction
*
**********************************************************************/
static int
transform_line_based_analysis_fixed(transform_ref self,short int *ptr)
{
int i,LowPassTrue,k,flag,m,n,g,NevenF,N;
register int inc;
register short int *in_indx,*in_indx3;
short int *in_indx2,*buf;
register int *tmp_ptr;
register int *low;
register int fltmp;
register int l1,l;
int band, width,L;
l=self->shiftFactor;
l1=1<<(l-1);
L=self->h;
inc=self->w;
++self->Cpeek;
NevenF=!self->EvenFilter;
N=self->Cpoke - self->Middle;
if( N != self->ImageRows || !self->LoneLine)
{LowPassTrue = N & 1;
if (NevenF || LowPassTrue){
for( k = 0 ; k < 1 +!NevenF ; k++,LowPassTrue=!LowPassTrue)
{ buf=(!NevenF && (!LowPassTrue) ) ? self->SecBuf_I:ptr;
for (band=0; band < 2; band++)
{ low= LowPassTrue ? self->LowA_I[band] : self->HighA_I[band];
flag=1;
width=(inc+!band)>>1;
in_indx2=*self->_data_I+(band? ((inc+1)>>1):0 ) ;
m=L>>1;
n=N-NevenF;
g=n+L-1;
while(m--)
{register short int *in_indx1,*in_indx13;
register int fltmp1;
if(m){
fltmp=*(low++);
fltmp1=*(low++);m--;
tmp_ptr=self->BufFast;
i=width;
in_indx3 = in_indx2 + inc * ( (g--)%L) ;
in_indx = in_indx2 + inc * ( (n++)%L) ;
in_indx13 =in_indx2 + inc * ( (g--)%L) ;
in_indx1 =in_indx2 + inc * ( (n++)%L) ;
if(fltmp){
if(LowPassTrue||NevenF){if(flag)
while(i--)*(tmp_ptr++)=
fltmp * ((int)*(in_indx++)+(int)*(in_indx3++))+
fltmp1 * ((int)*(in_indx1++)+(int)*(in_indx13++));
else while(i--) *(tmp_ptr++)+=
fltmp * ((int)*(in_indx++)+(int)*(in_indx3++))+
fltmp1 * ((int)*(in_indx1++)+(int)*(in_indx13++)); }
else{if(flag)
while(i--)*(tmp_ptr++)=
fltmp * ((int)*(in_indx++)-(int)*(in_indx3++))+
fltmp1 * ((int)*(in_indx1++)-(int)*(in_indx13++));
else while(i--) *(tmp_ptr++)+=
fltmp * ((int)*(in_indx++)-(int)*(in_indx3++))+
fltmp1 * ((int)*(in_indx1++)-(int)*(in_indx13++));}
}else
{
if(LowPassTrue||NevenF){if(flag)
while(i--)*(tmp_ptr++)=
fltmp1 * ((int)*(in_indx1++)+(int)*(in_indx13++));
else while(i--) *(tmp_ptr++)+=
fltmp1 * ((int)*(in_indx1++)+(int)*(in_indx13++)); }
else{if(flag)
while(i--)*(tmp_ptr++)=
fltmp1 * ((int)*(in_indx1++)-(int)*(in_indx13++));
else while(i--) *(tmp_ptr++)+=
fltmp1 * ((int)*(in_indx1++)-(int)*(in_indx13++)); }
}
flag=0;}
else{
fltmp=*(low++);
tmp_ptr=self->BufFast;
i=width;
in_indx3 = in_indx2 + inc * ( (g--)%L) ;
in_indx = in_indx2 + inc * ( (n++)%L) ;
if(fltmp){
if(LowPassTrue||NevenF){if(flag)
while(i--)*(tmp_ptr++)=
fltmp * ((int)*(in_indx++)+(int)*(in_indx3++));
else while(i--) *(tmp_ptr++)+=
fltmp * ((int)*(in_indx++)+(int)*(in_indx3++)); }
else{if(flag)
while(i--)*(tmp_ptr++)=
fltmp * ((int)*(in_indx++)-(int)*(in_indx3++));
else while(i--) *(tmp_ptr++)+=
fltmp * ((int)*(in_indx++)-(int)*(in_indx3++));}
flag=0;}}
}
if(NevenF)
{ fltmp=*(low++);
tmp_ptr=self->BufFast;
i=width;
in_indx = in_indx2 + inc * ( (n++)%L) ;
if(fltmp){if(flag)
while(i--)*(tmp_ptr++)=
fltmp * (int)*(in_indx++);
else while(i--) *(tmp_ptr++)+=
fltmp * (int)*(in_indx++); }}
tmp_ptr=self->BufFast;
while(width--) *(buf++)=(short int )((*(tmp_ptr++)+(l1))>>l);
}
}
}
else
memcpy( ptr , self->SecBuf_I , sizeof(short int ) * inc );
}
else /* Only if Even Filter Odd number of rows*/
{ in_indx = self->ExtraLine_I;
for (i=(inc+1)>>1, band=0; band < 2; band++, i=inc>>1)
{
int lone_factor;
lone_factor = self->lone_factors[band];
for (; i > 0; i--, in_indx++, ptr++)
*ptr = (short int)((((int) *in_indx)*lone_factor + l1) >> l);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -