home *** CD-ROM | disk | FTP | other *** search
- /*
- Adopted from "huffman.c" from the ISO MPEG Audio Subgroup Software Simulation
- Group's public c source for its MPEG audio decoder. Optimizations and
- conversion of stdio routines to stream routines by Jeff Tsay
- (ctsay@pasteur.eecs.berkeley.edu). Also most error checks were removed.
-
- Last modified : 01/28/97 */
-
- /**********************************************************************
- 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, 508-493-2241, e-mail: pan@gauss.enet.dec.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 *
- *********************************************************************/
-
- #define STRICT
- #define WIN32_LEAN_AND_MEAN
- #define NOMCX
- #define NOIME
- #define NOGDI
- #define NOUSER
- #define NOSOUND
- #define NOCOMM
- #define NODRIVERS
- #define OEMRESOURCE
- #define NONLS
- #define NOSERVICE
- #define NOKANJI
- #define NOMINMAX
- #define NOLOGERROR
- #define NOPROFILER
- #define NOMEMMGR
- #define NOLFILEIO
- #define NOOPENFILE
- #define NORESOURCE
- #define NOATOM
- #define NOLANGUAGE
- // #define NOLSTRING
- #define NODBCS
- #define NOKEYBOARDINFO
- #define NOGDICAPMASKS
- #define NOCOLOR
- #define NOGDIOBJ
- #define NODRAWTEXT
- #define NOTEXTMETRIC
- #define NOSCALABLEFONT
- #define NOBITMAP
- #define NORASTEROPS
- #define NOMETAFILE
- #define NOSYSMETRICS
- #define NOSYSTEMPARAMSINFO
- #define NOMSG
- #define NOWINSTYLES
- #define NOWINOFFSETS
- #define NOSHOWWINDOW
- #define NODEFERWINDOWPOS
- #define NOVIRTUALKEYCODES
- #define NOKEYSTATES
- #define NOWH
- #define NOMENUS
- #define NOSCROLL
- #define NOCLIPBOARD
- #define NOICONS
- #define NOMB
- #define NOSYSCOMMANDS
- #define NOMDI
- #define NOCTLMGR
- #define NOWINMESSAGES
- #define NOHELP
- #define _WINUSER_
- #define __oleidl_h__
- #define _OLE2_H_
- #include <windows.h>
-
- #include <fstream.h>
- #include <strstrea.h>
- #include "all.h"
- #include "bit_res.h"
- #include "huffman.h"
-
- HUFFBITS dmask = 1 << (sizeof(HUFFBITS)*8-1);
- uint32 hs = sizeof(HUFFBITS)*8;
-
- struct huffcodetab ht[HTN];
- /* array of all huffcodtable headers */
- /* 0..31 Huffman code table 0..31 */
- /* 32,33 count1-tables */
-
- int32 hexstr_to_int(char *hexstr)
- {
- int32 result = 0;
- int32 shifts = 0;
- int32 i;
- char c;
-
- for (i = (lstrlen(hexstr) - 1); i>=0; i--) {
-
- if ((c = hexstr[i]) <= '9')
- result+= ((int32) (c - '0')) << shifts;
- else
- result+= ((int32) (c - 'a') + 10) << shifts;
-
- shifts+=4;
- }
-
- return (result);
- }
-
- /* read the huffman decoder table */
-
- int32 read_decoder_table(char *filename)
- {
- int32 n,i, nn, t;
- char v0str[4];
- char v1str[4];
- char command[100],line[100];
-
- ifstream fi((const char *) filename);
- istrstream *line_stream = NULL;
-
- for (n=0;n<HTN;n++) {
- // .table number treelen xlen ylen linbits
- do {
- fi.getline(line, 99, '\n');
- } while ((line[0] == '#') || (line[0] < ' '));
-
- delete line_stream;
- line_stream = new istrstream(line);
-
- *line_stream >> command >> ht[n].tablename >> ht[n].treelen
- >> ht[n].xlen >> ht[n].ylen >> ht[n].linbits;
-
- if (lstrcmp(command,".end")==0)
- return(n);
- else if (lstrcmp(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);
- } */
- delete line_stream;
- line_stream = new istrstream(ht[n].tablename);
-
- *line_stream >> nn;
-
- do {
- fi.getline(line, 99, '\n');
- } while ((line[0] == '#') || (line[0] < ' '));
-
- delete line_stream;
- line_stream = new istrstream(line);
- *line_stream >> command >> t;
-
- if (lstrcmp(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] < ' ') ) {
- fi.getline(line, 99, '\n');
- }
- }
- else if (lstrcmp(command,".treedata")==0) {
- ht[n].ref = -1;
- ht[n].val= new unsigned char[ht[n].treelen] [2];
-
- /* if (ht[n].val == NULL) {
- fprintf(stderr, "heaperror at table %d\n",n);
- exit (-10);
- } */
-
- for (i=0;i<ht[n].treelen; i++) {
- fi >> v0str >> v1str;
- ht[n].val[i][0]=(unsigned char) hexstr_to_int(v0str);
- ht[n].val[i][1]=(unsigned char) hexstr_to_int(v1str);
- }
-
- fi.getline(line, 99, '\n');
- }
- /* else {
- fprintf(stderr,"huffman decodertable error at table %d\n",n);
- } */
- }
-
- return n;
- }
-
- /* do the huffman-decoding */
- /* note! for counta,countb -the 4 bit value is returned in y, discard x */
- int32 huffman_decoder(struct huffcodetab *h, int32 *x, int32 *y, int32 *v,
- int32 *w, Bit_Reserve *br)
- {
- 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 (br->hgetbits(1)) {
- 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. */
-
- if (*v)
- if (br->hgetbits(1)) *v = -*v;
- if (*w)
- if (br->hgetbits(1)) *w = -*w;
- if (*x)
- if (br->hgetbits(1)) *x = -*x;
- if (*y)
- if (br->hgetbits(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. */
-
- if (h->linbits)
- if ((h->xlen-1) == *x)
- *x += br->hgetbits(h->linbits);
- if (*x)
- if (br->hgetbits(1)) *x = -*x;
- if (h->linbits)
- if ((h->ylen-1) == *y)
- *y += br->hgetbits(h->linbits);
- if (*y)
- if (br->hgetbits(1)) *y = -*y;
- }
-
- return(error);
- }
-
-
-