⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hplx_hor.c

📁 JPEG2000 EBCOT算法源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************/
/* Copyright 1998, Hewlett-Packard Company                                   */
/* All rights reserved                                                       */
/* Author: Christos Chrysafis                                                */
/* Version: V2.1                                                             */
/* Last Revised: 10/2/98                                                     */
/*****************************************************************************/

#include <local_heap.h>
#include <memory.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <line_block_ifc.h>
#include <hplx_hor.h>
#include <hplx_coeffs.h>
#include <hplx_def.h>




/*******************************************************************************/
/*  inner product two pixels at a time */
/******************************************************************************/
void two_at_once_h(int plus, int *flag,int i,float m,float *a,float *b,float *c)
{
	if(!m) return;

	if(plus)
	{
		if(*flag)
			while(i--)    *a++  = m * ( *(b+=2) + *(c+=2));
			else
				while(i--)    *a++ += m * ( *(b+=2) + *(c+=2));
	}
	else
	{
		if(*flag)
			while(i--)    *a++  = m * ( *(b+=2) - *(c+=2));
			else
				while(i--)    *a++ += m * ( *(b+=2) - *(c+=2));
	}
	*flag=0;
}
/*******************************************************************************/
/*  inner product one pixel at a time */
/*******************************************************************************/
void one_at_once_h(int *flag,int i,float m,float *a,float *b)
{
	if(!m) return;
	
		if(*flag)
			while(i--)    *a++  = m * *(b+=2) ;
			else
				while(i--)    *a++ += m *  *(b+=2) ;
	
	*flag=0;
}

/************************************************************************/

/************************************************************************/
static  int 
inner_prod_fixed( int * a,  int  b,
                 short int  *c, int  k)
{       
  while( b-- )
    k+=((int) *(a++)) * ((int)*(c++));
  return(k);
}

/************************************************************************/

static float
inner_prod(float* a, float *b, float *c,float k)
{       
  while( a != b )
    k+=*(a++)**(c++);
  return(k);
}

/************************************************************************/
/* Set the size for the one dimensional line 
* to be decomposed.
*
*
*  One object can be used for different decompositions
*
*/
/************************************************************************/

static void
decimator__set_size(decimator_ref self, int t)
{
  self->Length=min(t,self->xdim);
}      

/*****************************************************************************/
/* 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);
}

/************************************************************************/
/*
*  Destructor for decimator object
*
*/
/************************************************************************/

static int
decimator__terminate(decimator_ref self )
{
  if(self->fixed)
  {
    local_free(self->buffer_I-=self->V_max);
    local_free(self->BufFast);
    local_free(self->VL_Low_I);
    local_free(self->VH_Low_I);
  }
  else
  {
    local_free(self->buffer-=self->V_max);
    local_free(self->VL_Low);
    local_free(self->VH_Low);
  }
  
  local_free(self);
  return(0);  
}

/************************************************************************/
/* Initialization routine for class decimator
*
*/
/************************************************************************/

static void
  decimator__initialize(decimator_ref self,      
                        int  X,
                        filter_info_ref info,
                        int c_levs, int component_idx)
{       
  int i,PLUSMINUS1;
  float *l_taps, *h_taps;
  int h_neg, h_pos, l_neg, l_pos, Lmin, Lbeyond, Hmin, Hbeyond;
  char *built_in_id;
  
  self->DefaultFB = 0;
  self->component_idx = component_idx;
  
  l_taps = info->get_taps(info,0,component_idx,0x0F&c_levs,&l_neg,&l_pos,NULL);
  h_taps = info->get_taps(info,FILTER__HIGH,component_idx,0x0F&c_levs,
                          &h_neg,&h_pos,&built_in_id);
  if ((built_in_id != NULL) && (strcmp(built_in_id,"0") == 0))
    self->DefaultFB = 1;
  
  self->EvenFilter = (l_neg+l_pos) & 1;
  Lmin = -l_pos; Lbeyond = l_neg+1;
  Hmin = -h_pos; Hbeyond = h_neg+1;
  if (self->EvenFilter)
  { Hmin--; Hbeyond--; }
  
  self->VL_min = Lmin;
  self->VL_max = Lbeyond;
  self->VH_min = Hmin;
  self->VH_max = Hbeyond;
  self->V_min = min( self->VL_min, self->VH_min );
  self->V_max = max( self->VL_max, self->VH_max );
  PLUSMINUS1     = self->EvenFilter?(-1):1;          
  

  self->VL_Low = (float *)
    local_malloc(sizeof(float)*(size_t)(Lbeyond-Lmin));
  self->VH_Low = (float *)
    local_malloc(sizeof(float)*(size_t)(Hbeyond-Hmin));
  self->VL_High = self->VL_Low + (Lbeyond - Lmin);
  self->VH_High = self->VH_Low + (Hbeyond - Hmin);
  for (i=0; i < (Lbeyond - Lmin); i++)
    self->VL_High[-i-1] = l_taps[i];
  for (i=0; i < (Hbeyond - Hmin); i++)
    self->VH_High[-i-1] = h_taps[i];
  
  for(i=0;i<self->VH_max-self->VH_min;i++)
    self->VH_Low[i] *=PLUSMINUS1;
  
  self->xdim=self->Length=X;
         
  self->buffer =
    ((float*)
    local_malloc((self->Length-self->V_min+self->V_max)*sizeof(float)))
    + self->V_max;
}

/************************************************************************/
/*
*  decomposes an input line, 
*
*/
/************************************************************************/

static void 
decimator__decimate(decimator_ref self, float * V)
{

  int j,i,evenF,effectiveL,flag;
  float *SindxL,*SindxH,*Sindex1,*OindxH,qu=0;
  float *downL,*downH;
  int  shift_factorL, shift_factorH,_Strange,OddSignal;  

  downL=self->VL_Low;
  downH=self->VH_Low;
  evenF=self->EvenFilter;
 
  effectiveL=self->Length;
  if( (effectiveL&1) && evenF)
  {effectiveL--; _Strange=1;} else _Strange=0;
  
  /***********************************************
  ** This is the main part of the signal
  ***********************************************/
  
  OddSignal = effectiveL & 1;
  shift_factorL =  - self->VL_max - 1;
  shift_factorH =  - self->VH_max - evenF ;

  if (_Strange)
	  qu =(float)( (*(self->buffer+effectiveL))); 
  
  /***********************************************
  ** Extension to the left of the signal
  ***********************************************/
  
  for(j=-1,i=-(int)(evenF);j>-self->V_max;j--)
	  self->buffer[j]=self->buffer[(++i)%effectiveL];
  
  /***********************************************
  ** Extension to the right of the signal
  ***********************************************/
  
  for ( j = effectiveL ,
	  i = ( ( effectiveL << 1 ) - !evenF ) ;
  j < effectiveL - self->V_min; j++ )  
	  self->buffer[j]=self->buffer[(--i)%effectiveL];
  
  /********************************
  Filtering for the Low pass
  Filtering for the High pass
  ********************************/
  
      SindxL        = self->buffer + shift_factorL ;
      OindxH       = V + ((effectiveL+1+_Strange)>>1);
      SindxH        = self->buffer + shift_factorH ;
      
 if(!self->DefaultFB)
   {   
	  /* Low Pass*/
	  j=(effectiveL>>1)+OddSignal;
	  flag=1;
      i=self->VL_max-self->VL_min;
	  Sindex1=SindxL+i-1;
	  i>>=1;
	  while(i--)
          two_at_once_h(1, &flag,j, *(downL++) ,V, SindxL++,Sindex1--);

      if(!evenF)   /*Oddlength Filter */
          one_at_once_h(&flag,j,*(downL++),V,SindxL++);
	  
	  V+=j;
      if(_Strange) *(V++)=qu;  
      /*  High Pass */  

	  j=(effectiveL>>1);
	  flag=1;
      i=self->VH_max-self->VH_min;
	  Sindex1=SindxH+i-1;
	  i>>=1;

	  while(i--)
        two_at_once_h(!evenF, &flag,j, *(downH++) ,V, SindxH++,Sindex1--);

       if(!evenF)   /*Oddlength Filter */
          one_at_once_h(&flag,j,*(downH++),V,SindxH++);
      
      } 
      else
      {  
        for(i=0;i<(effectiveL>>1);i++)
        {
          SindxL+=2;
          *(V++) =     
            (float)(ha4) * (SindxL[0]+SindxL[8])+
            (float)(ha3) * (SindxL[1]+SindxL[7])+
            (float)(ha2) * (SindxL[2]+SindxL[6])+
            (float)(ha1) * (SindxL[3]+SindxL[5])+
            (float)(ha0) *  SindxL[4] ;
          *(OindxH++)=   
            (float)(ga3) * (SindxL[2]+SindxL[8])+
            (float)(ga2) * (SindxL[3]+SindxL[7])+
            (float)(ga1) * (SindxL[4]+SindxL[6])+ 
            (float)(ga0) *  SindxL[5];
        }		 
  
        if(OddSignal)
        {
          SindxL+=2;
          *(V++) =     
            (float)(ha4) * (SindxL[0]+SindxL[8])+
            (float)(ha3) * (SindxL[1]+SindxL[7])+
            (float)(ha2) * (SindxL[2]+SindxL[6])+
            (float)(ha1) * (SindxL[3]+SindxL[5])+
            (float)(ha0) *  SindxL[4] ;
        }
		 if(_Strange) *(V)=qu;   
      }
}



/************************************************************************/
static void
interpolator__set_size(interpolator_ref self, int t)
{
  self->Length=min(t,self->xdim);
  
}


/************************************************************************/
/*
*  initialization routine for class interpolator
*
*   c_levs           levels of decomposition performed
*/
/************************************************************************/

static void
  interpolator__initialize(interpolator_ref self, 
                           int  X, filter_info_ref info,int c_levs,
                           int component_idx)
{
  int i,PLUSMINUS1;
  float *Lfilt,*Hfilt;
  float *l_taps, *h_taps; 
  int h_neg, h_pos, l_neg, l_pos, Lmin, Lbeyond, Hmin, Hbeyond;
  char *built_in_id;
  
  self->DefaultFB = 0;
  self->component_idx = component_idx;
 
  l_taps = info->get_taps(info,FILTER__SYNTH,component_idx,0x0F & c_levs,
                          &l_neg,&l_pos,NULL);
  h_taps = info->get_taps(info,FILTER__HIGH | FILTER__SYNTH,component_idx,
                          0x0F & c_levs,&h_neg,&h_pos,&built_in_id);
  if (strcmp(built_in_id,"0") == 0)
    self->DefaultFB = 1;
  
  self->EvenFilter = (l_neg+l_pos) & 1;
  Lmin = -l_neg; Lbeyond = l_pos+1;
  Hmin = -h_neg; Hbeyond = h_pos+1;
  if (self->EvenFilter)
  { Lmin--; Lbeyond--; }
  
  self->VH_min = Hmin;
  self->VH_max = Hbeyond;
  self->VL_min = Lmin;
  self->VL_max = Lbeyond;
  self->V_min = min( self->VL_min, self->VH_min );
  self->V_max = max( self->VL_max, self->VH_max );
  
  self->_data = (float*)
    local_malloc(sizeof(float)*(X));
  
  self->xdim = self->Length = X;
 
  PLUSMINUS1 =  self->EvenFilter?(-1):1; 
  
  i= max(max(self->VL_max,abs(self->VL_min)),
    max(self->VH_max,abs(self->VH_min)));
  
 
  self->buffer =
    ((float*)
    local_malloc((self->Length-self->V_min + self->V_max)*sizeof(float)))
    + self->V_max;

  Lfilt =
    ((float*)
    local_malloc((self->V_max-self->V_min+1)*sizeof(float)))
    - self->V_min;
  Hfilt =
    ((float*)
    local_malloc((self->V_max-self->V_min+1)*sizeof(float)))
    - self->V_min;
  
  for(i = self->V_min; i <self->V_max ; i++)
    Lfilt[i]=Hfilt[i]=0;
  
  l_taps -= Lmin;
  h_taps -= Hmin; /* Get centres. */
  
  for(i=0;i<self->V_max;i+=2)
  {
    if(i-self->EvenFilter<self->VH_max)
      Hfilt[-i]=h_taps[i-self->EvenFilter];
    else
      Hfilt[-i]=(float)(0.0);
    
    if(i<self->VL_max)
      Lfilt[-i-self->EvenFilter]=l_taps[i];
    else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -