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