home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- * ISO MPEG Audio Subgroup Software Simulation Group (1996)
- * ISO 13818-3 MPEG-2 Audio Decoder - Lower Sampling Frequency Extension
- *
- * $Id: huffman.c,v 1.2 1996/03/28 03:13:37 rowlands Exp $
- *
- * $Log: huffman.c,v $
- * Revision 1.2 1996/03/28 03:13:37 rowlands
- * Merged layers 1-2 and layer 3 revisions
- *
- * Revision 1.1 1996/02/14 03:45:52 rowlands
- * Initial revision
- *
- * Received from FhG
- **********************************************************************/
- /**********************************************************************
- * 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 *
- *--------------------------------------------------------------------*
- * 12/16/96 Johan Hagman Adapted for Solaris (mpeg3play 0.9) *
- *********************************************************************/
-
- #include "common.h"
- #include "huffman.h"
- #include "stdlib.h"
-
- HUFFBITS dmask = (HUFFBITS)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(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);
- }
-
- #ifndef BUILTIN_TABLES
-
- /* Read the huffman decoder table */
- int read_decoder_table(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) {
- fprintf(stderr, "heap error 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;
- }
-
- #endif
-
-
- /* 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(
- 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(
- 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 */
- fprintf(stderr, "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;
- } else {
- /* Process sign and escape encodings for dual tables */
-
- // 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;
- }
-