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

📄 huffman.c

📁 mepg 1 layer3软解码源代码,实现了对MP3文件的软件解码
💻 C
字号:
/**********************************************************************Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reservedhuffman.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   * *   Chad Fogg email: <cfogg@xenon.com>                               * *                                                                    * * VERSION 2.10                                                       * *   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<<ht[n].linbits)-1;       sscanf(ht[n].tablename,"%u",&nn);    if (nn != n) {      fprintf(stderr,"wrong table number %u\n",n);      return(-2);    }     ht[n].xlen = xl;    ht[n].ylen = yl;    do {      fgets(line,99,fi);    } while ((line[0] == '#') || (line[0] < ' '));    sscanf(line,"%s %u",command,&t);    if (strcmp(command,".reference")==0) {      ht[n].ref   = t;      ht[n].table = ht[t].table;      ht[n].hlen  = ht[t].hlen;      if ( (xl != ht[t].xlen) ||           (yl != ht[t].ylen)  ) {        fprintf(stderr,"wrong table %u reference\n",n);        return (-3);      };      do {        fgets(line,99,fi);      } while ((line[0] == '#') || (line[0] < ' ') );    }     else {      ht[n].ref  = -1;      ht[n].table=(HUFFBITS *) calloc(xl*yl,sizeof(HUFFBITS));      if (ht[n].table == NULL) {         fprintf(stderr,"unsufficient heap error\n");         return (-4);      }      ht[n].hlen=(unsigned char *) calloc(xl*yl,sizeof(unsigned char));      if (ht[n].hlen == NULL) {         fprintf(stderr,"unsufficient heap error\n");         return (-4);      }      for (i=0; i<xl; i++) {        for (j=0;j<yl; j++) {	  if (xl>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;n<HTN;n++) {    /* .table number treelen xlen ylen linbits */     do {      fgets(line,99,fi);    } while ((line[0] == '#') || (line[0] < ' '));         sscanf(line,"%s %s %u %u %u %u",command,ht[n].tablename,           &ht[n].treelen, &ht[n].xlen, &ht[n].ylen, &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<<ht[n].linbits)-1;       sscanf(ht[n].tablename,"%u",&nn);    if (nn != n) {      fprintf(stderr,"wrong table number %u\n",n);      return(-2);    }     do {      fgets(line,99,fi);    } while ((line[0] == '#') || (line[0] < ' '));    sscanf(line,"%s %u",command,&t);    if (strcmp(command,".reference")==0) {      ht[n].ref   = t;      ht[n].val   = ht[t].val;      ht[n].treelen  = ht[t].treelen;      if ( (ht[n].xlen != ht[t].xlen) ||           (ht[n].ylen != ht[t].ylen)  ) {        fprintf(stderr,"wrong table %u reference\n",n);        return (-3);      };      while ((line[0] == '#') || (line[0] < ' ') ) {        fgets(line,99,fi);      }    }        else if (strcmp(command,".treedata")==0) {      ht[n].ref  = -1;      ht[n].val = (unsigned char (*)[2])         calloc(2*(ht[n].treelen),sizeof(unsigned char));      if ((ht[n].val == NULL) && ( ht[n].treelen != 0 )){    	fprintf(stderr, "heaperror at table %d\n",n);    	exit (-10);      }      for (i=0;i<ht[n].treelen; i++) {        fscanf(fi,"%x %x",&v0, &v1);        ht[n].val[i][0]=(unsigned char)v0;        ht[n].val[i][1]=(unsigned char)v1;      }      fgets(line,99,fi); /* read the rest of the line */    }    else {      fprintf(stderr,"huffman decodertable error at table %d\n",n);    }  }  return n;}/* do the huffman coding,  *//* note! for counta,countb - the 4 bit value is passed in y, set x to 0 *//* return value: 0-no error, 1 decode error				*/void huffman_coder( x, y, h, bs)unsigned int x; 	/* x-value */unsigned int y; 	/* y-value */struct huffcodetab *h; 	/* pointer to huffman code record 	*/Bit_stream_struc *bs;  	/* pointer to open write bitstream 	*/{  HUFFBITS huffbits; /* data left aligned */  HUFFBITS linbitsX;   HUFFBITS linbitsY;  unsigned int len;  unsigned int xl1 = h->xlen-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, y<h->ylen */      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;  }

⌨️ 快捷键说明

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