www.pudn.com > AVS_M_ver10.rar > re8_ppv.c


/* 
*********************************************************************** 
* COPYRIGHT AND WARRANTY INFORMATION 
* 
* Copyright 2007  Audio Video Coding Standard, Part ¢ú 
* 
* This software module was developed by AVS Audio sub-group 
* 
* DISCLAIMER OF WARRANTY 
* 
* These software programs are available to the users without any 
* license fee or royalty on an "as is" basis. The AVS disclaims 
* any and all warranties, whether express, implied, or statutory, 
* including any implied warranties of merchantability or of fitness 
* for a particular purpose. In no event shall the contributors or  
* the AVS be liable for any incidental, punitive, or consequential 
* damages of any kind whatsoever arising from the use of this program. 
* 
* This disclaimer of warranty extends to the user of this program 
* and user's customers, employees, agents, transferees, successors, 
* and assigns. 
* 
* The AVS does not represent or warrant that the program furnished 
* hereunder are free of infringement of any third-party patents. 
* Commercial implementations of AVS, including shareware, may be 
* subject to royalty fees to patent holders. Information regarding 
* the AVS patent policy is available from the AVS Web site at 
* http://www.avs.org.cn 
* 
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. 
************************************************************************ 
*/ 
 
#include  
#include  
#include "../include/amr_plus.h" 
static void nearest_neighbor_2D8(float x[], int y[]); 
/*-------------------------------------------------------------- 
  RE8_PPV(x,y) 
  NEAREST NEIGHBOR SEARCH IN INFINITE LATTICE RE8 
  the algorithm is based on the definition of RE8 as 
      RE8 = (2D8) U (2D8+[1,1,1,1,1,1,1,1]) 
  it applies the coset decoding of Sloane and Conway 
  (i) x: point in R^8 
  (o) y: point in RE8 (8-dimensional integer vector) 
  -------------------------------------------------------------- 
*/ 
void RE8_PPV(float x[], int y[]) 
{ 
  int i,y0[8],y1[8]; 
  float e0,e1,x1[8],tmp; 
  /* find the nearest neighbor y0 of x in 2D8 */ 
  nearest_neighbor_2D8(x, y0); 
  /* find the nearest neighbor y1 of x in 2D8+(1,...,1) (by coset decoding) */ 
  for (i=0;i<8;i++) 
    { 
      x1[i]=x[i]-1.0f; 
    } 
  nearest_neighbor_2D8(x1, y1); 
  for (i=0;i<8;i++) 
    { 
      y1[i]+=1; 
    } 
  /* compute e0=||x-y0||^2 and e1=||x-y1||^2 */ 
  e0=e1=0.0; 
  for (i=0;i<8;i++) 
    { 
      tmp = x[i]-y0[i]; 
      e0+=tmp*tmp; 
      tmp = x[i]-y1[i]; 
      e1+=tmp*tmp; 
    } 
  /* select best candidate y0 or y1 to minimize distortion */ 
  if (e0 0) */ 
    if (x[i] < 0) 
      { 
	y[i] = -2*(((int)(1.0-x[i]))>>1); 
      } 
    else 
      { 
	y[i] = 2*(((int)(1.0+x[i]))>>1); 
      } 
    sum += y[i]; 
  } 
  /* check if y1+...+y8 is a multiple of 4 
     if not, y is not round xj in the wrong way where j is defined by 
        j = arg max_i | xi -yi| 
     (this is called the Wagner rule) 
  */ 
  if (sum%4) 
    { 
      /* find j = arg max_i | xi -yi| */ 
      em=0; 
      j=0; 
      for (i=0;i<8;i++) 
	{ 
	  /* compute ei = xi-yi */ 
	  e[i]=x[i]-y[i]; 
	} 
      for (i=0;i<8;i++) 
	{ 
	  /* compute |ei| = | xi-yi | */ 
          if (e[i]<0) 
	    { 
	      s=-e[i]; 
	    } 
	  else 
	    { 
	      s=e[i]; 
	    } 
	  /* check if |ei| is maximal, if so, set j=i */ 
	  if (em