hplx_vert.c
来自「JPEG2000 EBCOT算法源码」· C语言 代码 · 共 2,020 行 · 第 1/5 页
C
2,020 行
}
}
return(0);
}
/*********************************************************************
* performs synthesis along the vertical direcion
*
**********************************************************************/
static int
transform_line_based_synthesis_fixed(transform_ref self,short int *ptr)
{
int i,LowPassTrue,k,flag,n,m,g;
register short int *in_indx,*in_indx2;
short int *in_indx1,*buf;
register int *tmp_ptr;
int *low;
register int fltmp;
register int l1,l;
int inc,NevenF,N,L,band, width;
L=self->h;
l=self->shiftFactor;
l1=1<<(l-1);
inc = self->w;
NevenF=!self->EvenFilter;
N=self->Cpoke - self->Middle;
/****************************************************/
if(N != self->ImageRows || ! self->LoneLine)
{LowPassTrue=(N- !NevenF) & 1;
if((!self->EvenFilter) || (!LowPassTrue))
{for( k = 0 ; k < 1 + !NevenF ; k++,LowPassTrue=!LowPassTrue)
{in_indx1 = *self->_data_I;
buf=(!NevenF && LowPassTrue )? self->SecBuf_I:ptr;
for (i=0, width=(inc+1)>>1, band=0; band < 2;
i=(inc+1)>>1,band++, width=inc>>1)
{
low=LowPassTrue? self->LowS_I[band]: self->HighS_I[band];
/***********************************/
flag=1;
in_indx2=*self->_data_I+(band? ((inc+1)>>1):0 ) ;
m=L;
n=N-NevenF;
g=n+L-1;
if(!NevenF)
{
while(m--)
{ register int fltmp1;
if(m){/* We have more than one tap to go */
fltmp=*(low++);
fltmp1=*(low++);
m--;
tmp_ptr=self->BufFast;
i=width;
in_indx = in_indx2 + inc * ( (n++)%L) ;
in_indx1 = in_indx2 + inc * ( (n++)%L) ;
if(fltmp&&fltmp1) /* Both taps are non zero*/
{ if(flag) while(i--)*(tmp_ptr++)=
fltmp * (int)*(in_indx++)+fltmp1*(int)*(in_indx1++);
else while(i--) *(tmp_ptr++)+=
fltmp*(int)*(in_indx++)+fltmp1*(int)*(in_indx1++);
flag=0; }
else if(fltmp1) /* None tap is non zero*/
{ if(flag)
while(i--) *(tmp_ptr++)=fltmp1*(int)*(in_indx1++);
else while(i--) *(tmp_ptr++)+=fltmp1*(int)*(in_indx1++);
flag=0; }
else { /* The other tap is non zero*/
if(flag) while(i--) *(tmp_ptr++)=fltmp * (int)*(in_indx++);
else while(i--) *(tmp_ptr++)+=fltmp*(int)*(in_indx++);
flag=0; }}/*END m>1 */
else{ /*m==0*/
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++);
flag=0; }}
} /* END while(m--) loop*/
}
else
{
m=L>>1;
while(m--)
{register short int *in_indx13,*in_indx3;
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(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++)=
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(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;
i=width;
while(i--)
*(buf++)=(short int )((*(tmp_ptr++)+(l1))>>l);
}
}
}
else
memcpy( ptr,self->SecBuf_I ,sizeof(short int ) * inc);
}
else{
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);}
}
return(0);
}
/*********************************************************************/
/* updates some state information and
* performs symetric extension when needed
*/
/**********************************************************************/
static void
transform_line_based_update_fixed(transform_ref self)
{
int i,j,k;
short int *tmp_ptr,*tmp1;
if(self->Cpoke < self->Middle + self->maxY )
{
self->RawData_I =
self->_data_I[(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_I,self->_data_I[i%self->h],
sizeof(short int ) * self->w);
else
{
if( !( k & 1 ) ) /* Low */
memcpy(self->RawData_I,
self->_data_I[ (--i) % self->h ],
sizeof(short int ) * self->w);
else
{ /* High */
tmp_ptr = self->RawData_I;
tmp1=self->_data_I[ (++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[i],
self->_data_I[(int)(self->h)-i-1],
sizeof(short int ) * self->w);
}
else
{
/* This is the Low */
for( i = self->Middle - 2 ; i >= (int)(self->EvenFilter); i-=2)
memcpy(self->_data_I[i],
self->_data_I[2*(int)(self->Middle)-2-i],
sizeof(short int ) * self->w);
/* Self is the High */
for( i=self->Middle - 1;i>=(int)(self->EvenFilter);i-=2)
{
tmp_ptr = self->_data_I[i];
tmp1=self->_data_I[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_I =
self->_data_I[(self->Cpoke+self->Middle)%self->h];
else
{
self->RawData_I=self->ExtraLine_I;
self->TrueExtra=1;
}
}
/*****************************************************************************/
/* STATIC compute_shift_factor */
/*****************************************************************************/
static int
compute_shift_factor(float *l_taps, int l_num, float *h_taps, int h_num,
int precision, float max_scale)
{
float val, max_val;
int i;
max_val = 0.0F;
for (i=0; i < l_num; i++)
{
val = l_taps[i];
if (val > max_val)
max_val = val;
else if ((-val) > max_val)
max_val = -val;
}
for (i=0; i < h_num; i++)
{
val = h_taps[i];
if (val > max_val)
max_val = val;
else if ((-val) > max_val)
max_val = -val;
}
max_val *= max_scale;
max_val *= 2.0F; /* all scaled coefficients will fit within this dynamic
range. Want 2^R >= `max_val'*2^S where R is the
precision and S is the shift we want to find. */
val = ((float)(1<<precision)) / max_val;
i=0;
while (val >= 1.0F)
{
val *= 0.5F;
i++;
}
i--;
assert(((1<<i)*max_val <= (float)(1<<precision)) &&
((1<<i)*max_val > (float)(1<<(precision-1))));
return(i);
}
/* ========================================================================= */
/* ---------------------------- Push Functions ----------------------------- */
/* ========================================================================= */
/*****************************************************************************/
/* STATIC push_line_float_zero */
/*****************************************************************************/
static void
push_line_float_zero(transform_ref self, ifc_int *ptr_indx)
{
int i;
float *tmp;
for( i = 0, tmp = self->RawData ;i<self->w;i++)
*(tmp++) = (float)(*(ptr_indx++));
self->quant->push_line_float(self->quant,self->RawData,
self->component_idx,0, 0,self->w);
}
/*****************************************************************************/
/* STATIC push_line_float */
/*****************************************************************************/
static void
push_line_float(transform_ref self, ifc_int *ptr_indx)
{
float *tmp;
int i;
if(!self->CmpLevel && ptr_indx!=NULL)
{
for( i = 0, tmp = self->frd->buffer ;i<self->w;i++)
*(tmp++) = (float)(*(ptr_indx++));
self->frd->set_size(self->frd,self->w);
self->frd->decimate(self->frd,self->RawData);
}
transform_line_based_update(self);
if( self->Cpoke > self->Middle) /* Start Filtering for the l level */
{
if( ((self->Cpoke - self->Middle) & 1))
{
if(self->next!=NULL)
{
if( self->next->Cpoke < self->next->ImageRows )
{
transform_line_based_analysis(self,self->frd->buffer);
self->quant->push_line_float(self->quant,
self->frd->buffer+(self->w+1)/2,
self->component_idx,self->ZLevel-1,HL_BAND,
( self->w >> 1 ) );
self->frd->set_size(self->frd,(int)(self->w+1)>>1);
self->frd->decimate(self->frd,self->next->RawData);
}
push_line_float(self->next,NULL);
}
else
{
transform_line_based_analysis(self,self->frd->buffer);
self->quant->push_line_float( self->quant,
self->frd->buffer,self->component_idx,self->ZLevel-1,LL_BAND,
( self->w +1)/2 );
self->quant->push_line_float( self->quant,
self->frd->buffer + ( self->w +1) /2 ,
self->component_idx,self->ZLevel-1, HL_BAND, self->w >> 1 );
}
}
else if ( self->Cpeek < self->ImageRows)
{
transform_line_based_analysis(self,self->frd->buffer);
self->quant->push_line_float(self->quant,
self->frd->buffer,self->component_idx,self->ZLevel-1, LH_BAND,
(self->w+1)/2 );
self->quant->push_line_float(self->quant,
self->frd->buffer+(self->w+1)/2 ,self->component_idx,
self->ZLevel-1, HH_BAND, self->w>>1 );
}
}
}
/*****************************************************************************/
/* STATIC push_line_fixed */
/*****************************************************************************/
#if (IMPLEMENTATION_PRECISION == 16)
static void
push_line_fixed(transform_ref self, short int *ptr_indx)
{
if(!self->CmpLevel && ptr_indx!=NULL )
{
memcpy(self->frd->buffer_I,ptr_indx,self->w*sizeof(short int));
self->frd->set_size(self->frd,self->w);
self->frd->decimate_fixed(self->frd,self->RawData_I);
}
transform_line_based_update_fixed(self);
if( self->Cpoke > self->Middle) /* Start Filtering for the l level */
{
if( ((self->Cpoke - self->Middle) & 1))
{
if(self->next!=NULL)
{
if( self->next->Cpoke < self->next->ImageRows )
{
transform_line_based_analysis_fixed(self,self->frd->buffer_I);
self->quant->push_line_fixed(self->quant,
self->frd->buffer_I+((self->w+1)>>1),
self->component_idx,self->ZLevel-1,HL_BAND,
( self->w >> 1 ) );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?