www.pudn.com > ampegsrc.zip > HUFFMAN.C


/********************************************************************** 
Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reserved 
huffman.c 
**********************************************************************/ 
/********************************************************************** 
 * MPEG/audio coding/decoding software, work in progress              * 
 *   NOT for public distribution until verified and approved by the   * 
 *   MPEG/audio committee.  For further information, please contact   * 
 *   Davis Pan, 708-538-5671, e-mail: pan@ukraine.corp.mot.com        * 
 *                                                                    * 
 * VERSION 4.3                                                        * 
 *   changes made since last update:                                  * 
 *   date   programmers                comment                        * 
 *27.2.92   F.O.Witte                  (ITT Intermetall)              * 
 *				       email: otto.witte@itt-sc.de    * 
 *				       tel:   ++49 (761)517-125	      * 
 *				       fax:   ++49 (761)517-880	      * 
 *12.6.92   J. Pineda                  Added sign bit to decoder.     * 
 * 08/24/93 M. Iwadare                 Changed for 1 pass decoding.   * 
 *--------------------------------------------------------------------* 
 *  7/14/94 Juergen Koller      Bug fixes in Layer III code           * 
 *********************************************************************/	 
 
#include "common.h" 
#include "huffman.h" 
      
HUFFBITS dmask = 1 << (sizeof(HUFFBITS)*8-1); 
unsigned int hs = sizeof(HUFFBITS)*8; 
 
struct huffcodetab ht[HTN];	/* array of all huffcodtable headers	*/ 
				/* 0..31 Huffman code table 0..31	*/ 
				/* 32,33 count1-tables			*/ 
 
/* read the huffman encode table */ 
int read_huffcodetab(fi)  
FILE *fi; 
{ 
 
  char line[100],command[40],huffdata[40]; 
  unsigned int t,i,j,k,nn,x,y,n=0; 
  unsigned int xl, yl, len; 
  HUFFBITS h; 
  int	hsize; 
   
  hsize = sizeof(HUFFBITS)*8;  
  do { 
      fgets(line,99,fi); 
  } while ((line[0] == '#') || (line[0] < ' ') ); 
   
  do {     
    while ((line[0]=='#') || (line[0] < ' ')) { 
      fgets(line,99,fi); 
    }  
 
    sscanf(line,"%s %s %u %u %u",command,ht[n].tablename, 
			         &xl,&yl,&ht[n].linbits); 
    if (strcmp(command,".end")==0) 
      return n; 
    else if (strcmp(command,".table")!=0) { 
      fprintf(stderr,"huffman table %u data corrupted\n",n); 
      return -1; 
    } 
    ht[n].linmax = (1<1)  
            sscanf(line,"%u %u %u %s",&x, &y, &len,huffdata); 
	  else  
            sscanf(line,"%u %u %s",&x,&len,huffdata); 
          h=0;k=0; 
	  while (huffdata[k]) { 
            h <<= 1; 
            if (huffdata[k] == '1') 
              h++; 
            else if (huffdata[k] != '0'){ 
              fprintf(stderr,"huffman-table %u bit error\n",n); 
              return (-5); 
            }; 
            k++; 
          }; 
          if (k != len) { 
           fprintf(stderr, 
              "warning: wrong codelen in table %u, pos [%2u][%2u]\n", 
	       n,i,j); 
          }; 
          ht[n].table[i*xl+j] = h; 
          ht[n].hlen[i*xl+j] = (unsigned char) len; 
	  do { 
            fgets(line,99,fi); 
          } while ((line[0] == '#') || (line[0] < ' ')); 
        } 
      } 
    } 
    n++; 
  } while (1); 
} 
 
/* read the huffman decoder table */ 
int read_decoder_table(fi)  
FILE *fi; 
{ 
  int n,i,nn,t; 
  unsigned int v0,v1; 
  char command[100],line[100]; 
  for (n=0;nxlen-1; 
  unsigned int yl1 = h->ylen-1; 
  linbitsX = 0; 
  linbitsY = 0; 
  if (h->table == NULL) return; 
  if (((x < xl1) || (xl1==0)) && (y < yl1)) { 
    huffbits = h->table[x*(h->xlen)+y]; 
    len = h->hlen[x*(h->xlen)+y]; 
    putbits(bs,huffbits,len); 
    return; 
  }   
  else if (x >= xl1) { 
    linbitsX = x-xl1; 
    if (linbitsX > h->linmax) { 
      fprintf(stderr,"warning: Huffman X table overflow\n"); 
      linbitsX= h->linmax; 
    }; 
    if (y >= yl1) { 
      huffbits = h->table[(h->ylen)*(h->xlen)-1]; 
      len = h->hlen[(h->ylen)*(h->xlen)-1]; 
      putbits(bs,huffbits,len); 
      linbitsY = y-yl1; 
      if (linbitsY > h->linmax) { 
        fprintf(stderr,"warning: Huffman Y table overflow\n"); 
        linbitsY = h->linmax; 
      }; 
      if (h->linbits) { 
        putbits(bs,linbitsX,h->linbits); 
        putbits(bs,linbitsY,h->linbits); 
      } 
    }  
    else { /* x>= h->xlen, yylen */ 
      huffbits = h->table[(h->ylen)*xl1+y]; 
      len = h->hlen[(h->ylen)*xl1+y]; 
      putbits(bs,huffbits,len); 
      if (h->linbits) { 
        putbits(bs,linbitsX,h->linbits); 
      } 
    } 
  } 
  else  { /* ((x < h->xlen) && (y>=h->ylen)) */ 
    huffbits = h->table[(h->ylen)*x+yl1]; 
    len = h->hlen[(h->ylen)*x+yl1]; 
    putbits(bs,huffbits,len); 
    linbitsY = y-yl1; 
    if (linbitsY > h->linmax) { 
      fprintf(stderr,"warning: Huffman Y table overflow\n"); 
      linbitsY = h->linmax; 
    }; 
    if (h->linbits) { 
       putbits(bs,linbitsY,h->linbits); 
    } 
  } 
} 
 
/* do the huffman-decoding 						*/ 
/* note! for counta,countb -the 4 bit value is returned in y, discard x */ 
int huffman_decoder(h, x, y, v, w) 
struct huffcodetab *h;	/* pointer to huffman code record	*/ 
/* unsigned */ int *x; 	/* returns decoded x value 		*/ 
/* unsigned */ int *y;	/* returns decoded y value		*/ 
int *v; 
int *w; 
{   
  HUFFBITS level; 
  int point = 0; 
  int error = 1; 
  level     = dmask; 
  if (h->val == NULL) return 2; 
 
  /* table 0 needs no bits */ 
  if ( h->treelen == 0) 
  {  *x = *y = 0; 
     return 0; 
  } 
 
 
  /* Lookup in Huffman table. */ 
 
  do { 
    if (h->val[point][0]==0) {   /*end of tree*/ 
      *x = h->val[point][1] >> 4; 
      *y = h->val[point][1] & 0xf; 
 
      error = 0; 
      break; 
    }  
    if (hget1bit()) { 
      while (h->val[point][1] >= MXOFF) point += h->val[point][1];  
      point += h->val[point][1]; 
    } 
    else { 
      while (h->val[point][0] >= MXOFF) point += h->val[point][0];  
      point += h->val[point][0]; 
    } 
    level >>= 1; 
  } while (level  || (point < ht->treelen) ); 
   
  /* Check for error. */ 
   
  if (error) { /* set x and y to a medium value as a simple concealment */ 
    printf("Illegal Huffman code in data.\n"); 
    *x = (h->xlen-1 << 1); 
    *y = (h->ylen-1 << 1); 
  } 
 
  /* Process sign encodings for quadruples tables. */ 
 
  if (h->tablename[0] == '3' 
      && (h->tablename[1] == '2' || h->tablename[1] == '3')) { 
     *v = (*y>>3) & 1; 
     *w = (*y>>2) & 1; 
     *x = (*y>>1) & 1; 
     *y = *y & 1; 
 
     /* v, w, x and y are reversed in the bitstream.  
        switch them around to make test bistream work. */ 
      
/*   {int i=*v; *v=*y; *y=i; i=*w; *w=*x; *x=i;}  MI */ 
 
     if (*v) 
        if (hget1bit() == 1) *v = -*v; 
     if (*w) 
        if (hget1bit() == 1) *w = -*w; 
     if (*x) 
        if (hget1bit() == 1) *x = -*x; 
     if (*y) 
        if (hget1bit() == 1) *y = -*y; 
     } 
      
  /* Process sign and escape encodings for dual tables. */ 
   
  else { 
   
      /* x and y are reversed in the test bitstream. 
         Reverse x and y here to make test bitstream work. */ 
	  
/*    removed 11/11/92 -ag   
		{int i=*x; *x=*y; *y=i;}  
*/       
     if (h->linbits) 
       if ((h->xlen-1) == *x)  
         *x += hgetbits(h->linbits); 
     if (*x) 
        if (hget1bit() == 1) *x = -*x; 
     if (h->linbits)	   
       if ((h->ylen-1) == *y) 
         *y += hgetbits(h->linbits); 
     if (*y) 
        if (hget1bit() == 1) *y = -*y; 
     } 
	   
  return error;   
}