807 lines
17 KiB
C
807 lines
17 KiB
C
/* File: sv_h261_huffman.c */
|
||
/*****************************************************************************
|
||
** Copyright (c) Digital Equipment Corporation, 1995, 1997 **
|
||
** **
|
||
** All Rights Reserved. Unpublished rights reserved under the copyright **
|
||
** laws of the United States. **
|
||
** **
|
||
** The software contained on this media is proprietary to and embodies **
|
||
** the confidential technology of Digital Equipment Corporation. **
|
||
** Possession, use, duplication or dissemination of the software and **
|
||
** media is authorized only pursuant to a valid written license from **
|
||
** Digital Equipment Corporation. **
|
||
** **
|
||
** RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the U.S. **
|
||
** Government is subject to restrictions as set forth in Subparagraph **
|
||
** (c)(1)(ii) of DFARS 252.227-7013, or in FAR 52.227-19, as applicable. **
|
||
******************************************************************************/
|
||
/*************************************************************
|
||
This file contains the Huffman routines.
|
||
*************************************************************/
|
||
|
||
/*
|
||
#define _SLIBDEBUG_
|
||
*/
|
||
|
||
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include "SV.h"
|
||
#include "sv_intrn.h"
|
||
#include "sv_h261.h"
|
||
#include "proto.h"
|
||
|
||
#ifdef _SLIBDEBUG_
|
||
#define _DEBUG_ 0 /* detailed debuging statements */
|
||
#define _VERBOSE_ 0 /* show progress */
|
||
#define _VERIFY_ 1 /* verify correct operation */
|
||
#define _WARN_ 0 /* warnings about strange behavior */
|
||
#endif
|
||
|
||
static DHUFF *MakeDhuff();
|
||
static EHUFF *MakeEhuff(int n);
|
||
static void LoadETable(int *array, EHUFF *table);
|
||
static void LoadDTable(int *array, DHUFF *table);
|
||
static int GetNextState(DHUFF *huff);
|
||
static void DestroyDhuff(DHUFF **huff);
|
||
static void DestroyEhuff(EHUFF **huff);
|
||
static void AddCode(int n, int code, int value, DHUFF *huff);
|
||
|
||
/* Actual Tables */
|
||
#define GetLeft(sval,huff) ((huff->state[(sval)] >> 16) & 0xffff)
|
||
#define GetRight(sval,huff) (huff->state[(sval)] & 0xffff)
|
||
|
||
#define SetLeft(number,sval,huff) huff->state[(sval)]=\
|
||
(((huff->state[(sval)]) & 0xffff)|(number<<16));
|
||
#define SetRight(number,sval,huff) huff->state[(sval)]=\
|
||
(((huff->state[(sval)]) & 0xffff0000)|(number));
|
||
|
||
#define EmptyState 0xffff
|
||
#define Numberp(value) ((value & 0x8000) ? 1 : 0)
|
||
#define MakeHVal(value) (value | 0x8000)
|
||
#define GetHVal(value) (value & 0x7fff)
|
||
|
||
int MTypeCoeff[] = {
|
||
0,4,1,
|
||
1,7,1,
|
||
2,1,1,
|
||
3,5,1,
|
||
4,9,1,
|
||
5,8,1,
|
||
6,10,1,
|
||
7,3,1,
|
||
8,2,1,
|
||
9,6,1,
|
||
-1,-1};
|
||
|
||
int MBACoeff[] = {
|
||
1,1,1,
|
||
2,3,3,
|
||
3,3,2,
|
||
4,4,3,
|
||
5,4,2,
|
||
6,5,3,
|
||
7,5,2,
|
||
8,7,7,
|
||
9,7,6,
|
||
10,8,11,
|
||
11,8,10,
|
||
12,8,9,
|
||
13,8,8,
|
||
14,8,7,
|
||
15,8,6,
|
||
16,10,23,
|
||
17,10,22,
|
||
18,10,21,
|
||
19,10,20,
|
||
20,10,19,
|
||
21,10,18,
|
||
22,11,35,
|
||
23,11,34,
|
||
24,11,33,
|
||
25,11,32,
|
||
26,11,31,
|
||
27,11,30,
|
||
28,11,29,
|
||
29,11,28,
|
||
30,11,27,
|
||
31,11,26,
|
||
32,11,25,
|
||
33,11,24,
|
||
34,11,15, /* Stuffing */
|
||
35,16,1, /* Start */
|
||
-1,-1};
|
||
|
||
int MVDCoeff[] = {
|
||
16,11,25,
|
||
17,11,27,
|
||
18,11,29,
|
||
19,11,31,
|
||
20,11,33,
|
||
21,11,35,
|
||
22,10,19,
|
||
23,10,21,
|
||
24,10,23,
|
||
25,8,7,
|
||
26,8,9,
|
||
27,8,11,
|
||
28,7,7,
|
||
29,5,3,
|
||
30,4,3,
|
||
31,3,3,
|
||
0,1,1,
|
||
1,3,2,
|
||
2,4,2,
|
||
3,5,2,
|
||
4,7,6,
|
||
5,8,10,
|
||
6,8,8,
|
||
7,8,6,
|
||
8,10,22,
|
||
9,10,20,
|
||
10,10,18,
|
||
11,11,34,
|
||
12,11,32,
|
||
13,11,30,
|
||
14,11,28,
|
||
15,11,26,
|
||
-1,-1};
|
||
|
||
int CBPCoeff[] = {
|
||
60,3,7,
|
||
4,4,13,
|
||
8,4,12,
|
||
16,4,11,
|
||
32,4,10,
|
||
12,5,19,
|
||
48,5,18,
|
||
20,5,17,
|
||
40,5,16,
|
||
28,5,15,
|
||
44,5,14,
|
||
52,5,13,
|
||
56,5,12,
|
||
1,5,11,
|
||
61,5,10,
|
||
2,5,9,
|
||
62,5,8,
|
||
24,6,15,
|
||
36,6,14,
|
||
3,6,13,
|
||
63,6,12,
|
||
5,7,23,
|
||
9,7,22,
|
||
17,7,21,
|
||
33,7,20,
|
||
6,7,19,
|
||
10,7,18,
|
||
18,7,17,
|
||
34,7,16,
|
||
7,8,31,
|
||
11,8,30,
|
||
19,8,29,
|
||
35,8,28,
|
||
13,8,27,
|
||
49,8,26,
|
||
21,8,25,
|
||
41,8,24,
|
||
14,8,23,
|
||
50,8,22,
|
||
22,8,21,
|
||
42,8,20,
|
||
15,8,19,
|
||
51,8,18,
|
||
23,8,17,
|
||
43,8,16,
|
||
25,8,15,
|
||
37,8,14,
|
||
26,8,13,
|
||
38,8,12,
|
||
29,8,11,
|
||
45,8,10,
|
||
53,8,9,
|
||
57,8,8,
|
||
30,8,7,
|
||
46,8,6,
|
||
54,8,5,
|
||
58,8,4,
|
||
31,9,7,
|
||
47,9,6,
|
||
55,9,5,
|
||
59,9,4,
|
||
27,9,3,
|
||
39,9,2,
|
||
-1,-1};
|
||
|
||
int TCoeff1[] = {
|
||
0,2,2, /* EOF */
|
||
1,2,3, /* Not First Coef */
|
||
2,4,4,
|
||
3,5,5,
|
||
4,7,6,
|
||
5,8,38,
|
||
6,8,33,
|
||
7,10,10,
|
||
8,12,29,
|
||
9,12,24,
|
||
10,12,19,
|
||
11,12,16,
|
||
12,13,26,
|
||
13,13,25,
|
||
14,13,24,
|
||
15,13,23,
|
||
257,3,3,
|
||
258,6,6,
|
||
259,8,37,
|
||
260,10,12,
|
||
261,12,27,
|
||
262,13,22,
|
||
263,13,21,
|
||
513,4,5,
|
||
514,7,4,
|
||
515,10,11,
|
||
516,12,20,
|
||
517,13,20,
|
||
769,5,7,
|
||
770,8,36,
|
||
771,12,28,
|
||
772,13,19,
|
||
1025,5,6,
|
||
1026,10,15,
|
||
1027,12,18,
|
||
1281,6,7,
|
||
1282,10,9,
|
||
1283,13,18,
|
||
1537,6,5,
|
||
1538,12,30,
|
||
1793,6,4,
|
||
1794,12,21,
|
||
2049,7,7,
|
||
2050,12,17,
|
||
2305,7,5,
|
||
2306,13,17,
|
||
2561,8,39,
|
||
2562,13,16,
|
||
2817,8,35,
|
||
3073,8,34,
|
||
3329,8,32,
|
||
3585,10,14,
|
||
3841,10,13,
|
||
4097,10,8,
|
||
4353,12,31,
|
||
4609,12,26,
|
||
4865,12,25,
|
||
5121,12,23,
|
||
5377,12,22,
|
||
5633,13,31,
|
||
5889,13,30,
|
||
6145,13,29,
|
||
6401,13,28,
|
||
6657,13,27,
|
||
6913,6,1, /* Escape */
|
||
-1,-1
|
||
};
|
||
|
||
/* Excludes EOB */
|
||
|
||
int TCoeff2[] = {
|
||
1,1,1, /* First Coef */
|
||
2,4,4,
|
||
3,5,5,
|
||
4,7,6,
|
||
5,8,38,
|
||
6,8,33,
|
||
7,10,10,
|
||
8,12,29,
|
||
9,12,24,
|
||
10,12,19,
|
||
11,12,16,
|
||
12,13,26,
|
||
13,13,25,
|
||
14,13,24,
|
||
15,13,23,
|
||
257,3,3,
|
||
258,6,6,
|
||
259,8,37,
|
||
260,10,12,
|
||
261,12,27,
|
||
262,13,22,
|
||
263,13,21,
|
||
513,4,5,
|
||
514,7,4,
|
||
515,10,11,
|
||
516,12,20,
|
||
517,13,20,
|
||
769,5,7,
|
||
770,8,36,
|
||
771,12,28,
|
||
772,13,19,
|
||
1025,5,6,
|
||
1026,10,15,
|
||
1027,12,18,
|
||
1281,6,7,
|
||
1282,10,9,
|
||
1283,13,18,
|
||
1537,6,5,
|
||
1538,12,30,
|
||
1793,6,4,
|
||
1794,12,21,
|
||
2049,7,7,
|
||
2050,12,17,
|
||
2305,7,5,
|
||
2306,13,17,
|
||
2561,8,39,
|
||
2562,13,16,
|
||
2817,8,35,
|
||
3073,8,34,
|
||
3329,8,32,
|
||
3585,10,14,
|
||
3841,10,13,
|
||
4097,10,8,
|
||
4353,12,31,
|
||
4609,12,26,
|
||
4865,12,25,
|
||
5121,12,23,
|
||
5377,12,22,
|
||
5633,13,31,
|
||
5889,13,30,
|
||
6145,13,29,
|
||
6401,13,28,
|
||
6657,13,27,
|
||
6913,6,1, /* Escape */
|
||
-1,-1
|
||
};
|
||
|
||
|
||
/*
|
||
* Function: inithuff()
|
||
* Purpose: Initializes all of the Huffman structures to the
|
||
* appropriate values. It must be called before any of
|
||
* the tables are used.
|
||
*/
|
||
void sv_H261HuffInit(SvH261Info_t *H261)
|
||
{
|
||
H261->NumberBitsCoded = 0;
|
||
H261->MBADHuff = MakeDhuff();
|
||
H261->MVDDHuff = MakeDhuff();
|
||
H261->CBPDHuff = MakeDhuff();
|
||
H261->T1DHuff = MakeDhuff();
|
||
H261->T2DHuff = MakeDhuff();
|
||
H261->T3DHuff = MakeDhuff();
|
||
H261->MBAEHuff = MakeEhuff(40);
|
||
H261->MVDEHuff = MakeEhuff(40);
|
||
H261->CBPEHuff = MakeEhuff(70);
|
||
H261->T1EHuff = MakeEhuff(8192);
|
||
H261->T2EHuff = MakeEhuff(8192);
|
||
H261->T3EHuff = MakeEhuff(20);
|
||
LoadDTable(MBACoeff,H261->MBADHuff);
|
||
LoadETable(MBACoeff,H261->MBAEHuff);
|
||
LoadDTable(MVDCoeff,H261->MVDDHuff);
|
||
LoadETable(MVDCoeff,H261->MVDEHuff);
|
||
LoadDTable(CBPCoeff,H261->CBPDHuff);
|
||
LoadETable(CBPCoeff,H261->CBPEHuff);
|
||
LoadDTable(TCoeff1,H261->T1DHuff);
|
||
LoadETable(TCoeff1,H261->T1EHuff);
|
||
LoadDTable(TCoeff2,H261->T2DHuff);
|
||
LoadETable(TCoeff2,H261->T2EHuff);
|
||
LoadDTable(MTypeCoeff,H261->T3DHuff);
|
||
LoadETable(MTypeCoeff,H261->T3EHuff);
|
||
}
|
||
|
||
/*
|
||
* Function: freehuff()
|
||
* Purpose: Frees all memory allocated for the Huffman structures.
|
||
*/
|
||
void sv_H261HuffFree(SvH261Info_t *H261)
|
||
{
|
||
DestroyDhuff(&H261->MBADHuff);
|
||
DestroyDhuff(&H261->MVDDHuff);
|
||
DestroyDhuff(&H261->CBPDHuff);
|
||
DestroyDhuff(&H261->T1DHuff);
|
||
DestroyDhuff(&H261->T2DHuff);
|
||
DestroyDhuff(&H261->T3DHuff);
|
||
DestroyEhuff(&H261->MBAEHuff);
|
||
DestroyEhuff(&H261->MVDEHuff);
|
||
DestroyEhuff(&H261->CBPEHuff);
|
||
DestroyEhuff(&H261->T1EHuff);
|
||
DestroyEhuff(&H261->T2EHuff);
|
||
DestroyEhuff(&H261->T3EHuff);
|
||
}
|
||
|
||
|
||
/*
|
||
** Function: MakeDhuff()
|
||
** Purpose: Constructs a decoder Huffman table and returns
|
||
** the structure.
|
||
*/
|
||
static DHUFF *MakeDhuff()
|
||
{
|
||
int i;
|
||
DHUFF *temp;
|
||
_SlibDebug(_DEBUG_, printf("MakeDhuff()\n") );
|
||
|
||
temp = (DHUFF *)ScAlloc(sizeof(DHUFF));
|
||
temp->NumberStates=1;
|
||
for(i=0; i<512; i++)
|
||
temp->state[i] = -1;
|
||
return(temp);
|
||
}
|
||
|
||
static void DestroyDhuff(DHUFF **huff)
|
||
{
|
||
if (huff)
|
||
{
|
||
ScFree(*huff);
|
||
*huff=NULL;
|
||
}
|
||
}
|
||
|
||
/*
|
||
** Function: MakeEhuff()
|
||
** Purpose: Constructs an encoder huff with a designated table-size.
|
||
** This table-size, n, is used for the lookup of Huffman values,
|
||
** and must represent the largest positive Huffman value.
|
||
*/
|
||
static EHUFF *MakeEhuff(int n)
|
||
{
|
||
int i;
|
||
EHUFF *temp;
|
||
_SlibDebug(_DEBUG_, printf("MakeEhuff()\n") );
|
||
|
||
temp = (EHUFF *)ScAlloc(sizeof(EHUFF));
|
||
temp->n = n;
|
||
temp->Hlen = (int *)ScAlloc(n*sizeof(int));
|
||
temp->Hcode = (int *)ScAlloc(n*sizeof(int));
|
||
for(i=0; i<n; i++)
|
||
{
|
||
temp->Hlen[i] = -1;
|
||
temp->Hcode[i] = -1;
|
||
}
|
||
return(temp);
|
||
}
|
||
|
||
static void DestroyEhuff(EHUFF **huff)
|
||
{
|
||
if (huff)
|
||
{
|
||
if ((*huff)->Hlen)
|
||
ScFree((*huff)->Hlen);
|
||
if ((*huff)->Hcode)
|
||
ScFree((*huff)->Hcode);
|
||
ScFree(*huff);
|
||
*huff=NULL;
|
||
}
|
||
}
|
||
|
||
|
||
/*
|
||
** Function: LoadETable()
|
||
** Purpose: Used to load an array into an encoder table. The
|
||
** array is grouped in triplets and the first negative value
|
||
** signals the end of the table.
|
||
*/
|
||
static void LoadETable(int *array, EHUFF *table)
|
||
{
|
||
_SlibDebug(_DEBUG_, printf("LoadETable()\n") );
|
||
|
||
while(*array>=0)
|
||
{
|
||
if (*array>table->n)
|
||
{
|
||
printf("Table overflow.\n");
|
||
}
|
||
table->Hlen[*array] = array[1];
|
||
table->Hcode[*array] = (int )array[2];
|
||
array+=3;
|
||
}
|
||
}
|
||
|
||
/*
|
||
** Function: LoadDHUFF()
|
||
** Purpose: Used to load an array into the DHUFF structure. The
|
||
** array consists of trios of Huffman definitions, the
|
||
** first one the value, the next one the size, and the
|
||
** third one the code.
|
||
*/
|
||
static void LoadDTable(int *array, DHUFF *table)
|
||
{
|
||
_SlibDebug(_DEBUG_, printf("LoadDTable()\n") );
|
||
|
||
while(*array>=0)
|
||
{
|
||
AddCode(array[1],array[2],array[0],table);
|
||
array+=3;
|
||
}
|
||
}
|
||
|
||
/*
|
||
** Function: GetNextState()
|
||
** Returns the next free state of the decoder Huffman
|
||
** structure. It no longer exits an error upon overflow.
|
||
*/
|
||
static int GetNextState(DHUFF *huff)
|
||
{
|
||
_SlibDebug(_DEBUG_, printf("GetNextState()\n") );
|
||
/*
|
||
if (huff->NumberStates==512)
|
||
{
|
||
_SlibDebug(_DEBUG_, printf("Overflow\n") );
|
||
exit(ERROR_BOUNDS);
|
||
}
|
||
*/
|
||
return(huff->NumberStates++);
|
||
}
|
||
|
||
/*
|
||
** Function: sv_H261HuffEncode()
|
||
** Purpose: Encodes a value according to a designated encoder Huffman
|
||
** table out to the stream. It returns the number of bits
|
||
** written to the stream and a zero on error.
|
||
*/
|
||
int sv_H261HuffEncode(SvH261Info_t *H261, ScBitstream_t *bs, int val, EHUFF *huff)
|
||
{
|
||
_SlibDebug(_DEBUG_, printf("Encode(val=%d)\n", val) );
|
||
if (val < 0)
|
||
{
|
||
_SlibDebug(_DEBUG_, printf("Encode() Out of bounds val: %d.\n",val) );
|
||
return(0);
|
||
}
|
||
else if (val>=huff->n)
|
||
return(0); /* No serious error, can occur with some values */
|
||
else if (huff->Hlen[val]<0)
|
||
return(0); /* No serious error: can pass thru by alerting routine.*/
|
||
else
|
||
{
|
||
_SlibDebug(_DEBUG_,
|
||
printf("Encode() Value: %d|%x Length: %d Code: %d\n",
|
||
val,val,huff->Hlen[val],huff->Hcode[val]) );
|
||
H261->NumberBitsCoded+=huff->Hlen[val];
|
||
ScBSPutBits(bs, huff->Hcode[val], huff->Hlen[val]);
|
||
return(huff->Hlen[val]);
|
||
}
|
||
}
|
||
|
||
|
||
/*
|
||
** Function: sv_H261HuffDecode()
|
||
** Purpose: Returns an integer read off the stream using the designated
|
||
** Huffman structure.
|
||
*/
|
||
#if 1
|
||
int sv_H261HuffDecode(SvH261Info_t *H261, ScBitstream_t *bs, DHUFF *huff)
|
||
{
|
||
register int State=0, bits;
|
||
register unsigned short cb;
|
||
_SlibDebug(_DEBUG_, printf("Decode()\n") );
|
||
|
||
cb = (unsigned short)ScBSPeekBits(bs, 16);
|
||
if (bs->EOI)
|
||
return(0);
|
||
if ((State = nextstate(huff, State, 0x8000)) & 0x8000) {
|
||
bits=1;
|
||
State = (State == 0xffff) ? 0 : State & 0x7fff;
|
||
} else if ((State = nextstate(huff, State, 0x4000)) & 0x8000) {
|
||
bits=2;
|
||
State = (State == 0xffff) ? 0 : State & 0x7fff;
|
||
} else if ((State = nextstate(huff, State, 0x2000)) & 0x8000) {
|
||
bits=3;
|
||
State = (State == 0xffff) ? 0 : State & 0x7fff;
|
||
} else if ((State = nextstate(huff, State, 0x1000)) & 0x8000) {
|
||
bits=4;
|
||
State = (State == 0xffff) ? 0 : State & 0x7fff;
|
||
} else if ((State = nextstate(huff, State, 0x0800)) & 0x8000) {
|
||
bits=5;
|
||
State = (State == 0xffff) ? 0 : State & 0x7fff;
|
||
} else if ((State = nextstate(huff, State, 0x0400)) & 0x8000) {
|
||
bits=6;
|
||
State = (State == 0xffff) ? 0 : State & 0x7fff;
|
||
} else if ((State = nextstate(huff, State, 0x0200)) & 0x8000) {
|
||
bits=7;
|
||
State = (State == 0xffff) ? 0 : State & 0x7fff;
|
||
} else if ((State = nextstate(huff, State, 0x0100)) & 0x8000) {
|
||
bits=8;
|
||
State = (State == 0xffff) ? 0 : State & 0x7fff;
|
||
} else if ((State = nextstate(huff, State, 0x0080)) & 0x8000) {
|
||
bits=9;
|
||
State = (State == 0xffff) ? 0 : State & 0x7fff;
|
||
} else if ((State = nextstate(huff, State, 0x0040)) & 0x8000) {
|
||
bits=10;
|
||
State = (State == 0xffff) ? 0 : State & 0x7fff;
|
||
} else if ((State = nextstate(huff, State, 0x0020)) & 0x8000) {
|
||
bits=11;
|
||
State = (State == 0xffff) ? 0 : State & 0x7fff;
|
||
} else if ((State = nextstate(huff, State, 0x0010)) & 0x8000) {
|
||
bits=12;
|
||
State = (State == 0xffff) ? 0 : State & 0x7fff;
|
||
} else if ((State = nextstate(huff, State, 0x0008)) & 0x8000) {
|
||
bits=13;
|
||
State = (State == 0xffff) ? 0 : State & 0x7fff;
|
||
} else if ((State = nextstate(huff, State, 0x0004)) & 0x8000) {
|
||
bits=14;
|
||
State = (State == 0xffff) ? 0 : State & 0x7fff;
|
||
} else if ((State = nextstate(huff, State, 0x0002)) & 0x8000) {
|
||
bits=15;
|
||
State = (State == 0xffff) ? 0 : State & 0x7fff;
|
||
} else if ((State = nextstate(huff, State, 0x0001)) & 0x8000) {
|
||
bits=16;
|
||
State = (State == 0xffff) ? 0 : State & 0x7fff;
|
||
}
|
||
|
||
ScBSSkipBits(bs, bits);
|
||
return(State);
|
||
}
|
||
#else
|
||
int sv_H261HuffDecode(SvH261Info_t *H261, ScBitstream_t *bs, DHUFF *huff)
|
||
{
|
||
int Next,cb;
|
||
int CurrentState=0;
|
||
_SlibDebug(_DEBUG_, printf("Decode()\n") );
|
||
|
||
while(1)
|
||
{
|
||
cb = ScBSGetBit(bs);
|
||
if (bs->EOI)
|
||
return(0);
|
||
Next = cb ? GetLeft(CurrentState,huff) : GetRight(CurrentState,huff);
|
||
if (Next == EmptyState)
|
||
return(0);
|
||
else if (Numberp(Next))
|
||
return(GetHVal(Next));
|
||
else
|
||
CurrentState = Next;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
/*
|
||
** Function: AddCode()
|
||
** Purpose: Adds a Huffman code to the decoder structure. It is called
|
||
** everytime a new Huffman code is to be defined. This function
|
||
** exits when an invalid code is attempted to be placed in
|
||
** the structure.
|
||
*/
|
||
static void AddCode(int n, int code, int value, DHUFF *huff)
|
||
{
|
||
int i,Next;
|
||
int CurrentState=0;
|
||
_SlibDebug(_DEBUG_, printf("AddCode()\n") );
|
||
|
||
if (value < 0)
|
||
return;
|
||
|
||
for(i=n-1;i>0;i--)
|
||
{
|
||
if (code & (1 << i))
|
||
{
|
||
Next = GetLeft(CurrentState,huff);
|
||
if (Next == EmptyState)
|
||
{
|
||
Next = GetNextState(huff);
|
||
SetLeft(Next,CurrentState,huff);
|
||
CurrentState = Next;
|
||
}
|
||
else /* if (Numberp(Next))
|
||
{
|
||
printf("Bad Value/State match:\n");
|
||
printf("Length: %d Code: %d Value: %d\n",
|
||
n,code,value);
|
||
exit(ERROR_BOUNDS);
|
||
}
|
||
else
|
||
*/
|
||
{
|
||
CurrentState = Next;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Next = GetRight(CurrentState,huff);
|
||
if (Next == EmptyState)
|
||
{
|
||
Next = GetNextState(huff);
|
||
SetRight(Next,CurrentState,huff);
|
||
CurrentState = Next;
|
||
}
|
||
else /* if (Numberp(Next))
|
||
{
|
||
printf("Bad Value/State match:\n");
|
||
printf("Length: %d Code: %d Value: %d\n",
|
||
n,code,value);
|
||
exit(ERROR_BOUNDS);
|
||
}
|
||
else
|
||
*/
|
||
{
|
||
CurrentState = Next;
|
||
}
|
||
}
|
||
}
|
||
if (code & 1)
|
||
{
|
||
Next = GetLeft(CurrentState,huff);
|
||
/* if (Next != EmptyState)
|
||
{
|
||
printf("Overflow on Huffman Table: Nonunique prefix.\n");
|
||
printf("Length: %d Code: %d|%x Value: %d|%x\n",
|
||
n,code,code,value,value);
|
||
exit(ERROR_BOUNDS);
|
||
}
|
||
*/
|
||
SetLeft(MakeHVal(value),CurrentState,huff);
|
||
}
|
||
else
|
||
{
|
||
Next = GetRight(CurrentState,huff);
|
||
/* if (Next != EmptyState)
|
||
{
|
||
printf("Overflow on Huffman Table: Nonunique prefix.\n");
|
||
printf("Length: %d Code: %d|%x Value: %d|%x\n",
|
||
n,code,code,value,value);
|
||
exit(ERROR_BOUNDS);
|
||
}
|
||
*/
|
||
SetRight(MakeHVal(value),CurrentState,huff);
|
||
}
|
||
}
|
||
|
||
/*
|
||
** Function: PrintDHUFF()
|
||
** Purpose: Prints out the decoder Huffman structure that is passed
|
||
** into it.
|
||
*/
|
||
void PrintDhuff(DHUFF *huff)
|
||
{
|
||
int i;
|
||
|
||
printf("Modified Huffman Decoding Structure: %p\n",huff);
|
||
printf("Number of states %d\n",huff->NumberStates);
|
||
for(i=0;i<huff->NumberStates;i++)
|
||
{
|
||
printf("State: %d Left State: %x Right State: %x\n",
|
||
i,
|
||
GetLeft(i,huff),
|
||
GetRight(i,huff));
|
||
}
|
||
}
|
||
|
||
/*
|
||
** Function: PrintEhuff()
|
||
** Purpose: Prints the encoder Huffman structure passed into it.
|
||
*/
|
||
void PrintEhuff(EHUFF *huff)
|
||
{
|
||
BEGIN("PrintEhuff");
|
||
int i;
|
||
|
||
printf("Modified Huffman Encoding Structure: %p\n",huff);
|
||
printf("Number of values %d\n",huff->n);
|
||
for(i=0;i<huff->n;i++)
|
||
{
|
||
if (huff->Hlen[i]>=0)
|
||
{
|
||
printf("Value: %x Length: %d Code: %x\n",
|
||
i,huff->Hlen[i],huff->Hcode[i]);
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
** Function: PrintTable()
|
||
** Purpose: Prints out 256 elements in a nice byte ordered fashion.
|
||
*/
|
||
void PrintTable(int *table)
|
||
{
|
||
int i,j;
|
||
|
||
for(i=0;i<16;i++)
|
||
{
|
||
for(j=0;j<16;j++)
|
||
{
|
||
printf("%2x ",*(table++));
|
||
}
|
||
printf("\n");
|
||
}
|
||
}
|
||
|
||
|