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 + -
显示快捷键?