📄 huffman.c
字号:
This function takes an element that is larger than 16 and generates the base10 value of the
equivalent escape sequence. It returns the escape sequence in the variable, 'output'. It
also passed the length of the escape sequence through the parameter, 'len_esc_sequence'.
*/
{
float x,y;
int output;
int N;
N = -1;
y = (float)ABS(input);
x = y / 16;
while (x >= 1) {
N++;
x = x/2;
}
*len_esc_sequence = 2*N + 5; /* the length of the escape sequence in bits */
output = (int)((pow(2,N) - 1)*pow(2,N+5) + y - pow(2,N+4));
return(output);
}
int OutputBits(CoderInfo *coderInfo,
#ifdef DRM
int *book, /* we need to change book for VCB11 */
#else
int book,
#endif
int *quant,
int offset,
int length)
{
/*
This function inputs
- a specific codebook number, 'book'
- the quantized spectral data, 'quant[][]'
- the offset into the spectral data to begin scanning, 'offset'
- the 'length' of the segment to huffman code
-> therefore, the segment quant[offset] to quant[offset+length-1]
is huffman coded.
This function outputs
- the number of bits required, 'bits' using the prescribed codebook, book applied to
the given segment of spectral data.
There are three parameters that are passed back and forth into this function. data[]
and len[] are one-dimensional arrays that store the codebook values and their respective
bit lengths. These are used when packing the data for the bitstream in OutputBits(). The
index into these arrays is 'coderInfo->spectral_count''. It gets incremented internally in this
function as counter, then passed to the outside through outside_counter. The next time
OutputBits() is called, counter starts at the value it left off from the previous call.
*/
int esc_sequence;
int len_esc;
int index;
int bits=0;
int tmp;
int codebook,i,j;
int counter;
/* Set up local pointers to coderInfo elements data and len */
int* data= coderInfo->data;
int* len= coderInfo->len;
#ifdef DRM
int* num_data = coderInfo->num_data_cw;
int cur_cw_len;
int max_esc_sequ = 0;
#endif
counter = coderInfo->spectral_count;
#ifdef DRM
switch (*book) {
#else
switch (book) {
#endif
case 0:
case INTENSITY_HCB2:
case INTENSITY_HCB:
#ifdef DRM
for(i=offset;i<offset+length;i=i+4){
#endif
/* This case also applies to intensity stereo encoding */
coderInfo->data[counter] = 0;
coderInfo->len[counter++] = 0;
coderInfo->spectral_count = counter; /* send the current count back to the outside world */
#ifdef DRM
num_data[coderInfo->cur_cw++] = 1;
}
#endif
return(bits);
case 1:
for(i=offset;i<offset+length;i=i+4){
index = 27*quant[i] + 9*quant[i+1] + 3*quant[i+2] + quant[i+3] + 40;
codebook = huff1[index][LASTINTAB];
tmp = huff1[index][FIRSTINTAB];
bits += tmp;
data[counter] = codebook;
len[counter++] = tmp;
#ifdef DRM
num_data[coderInfo->cur_cw++] = 1;
coderInfo->iLenReordSpData += tmp;
if (tmp > coderInfo->iLenLongestCW)
coderInfo->iLenLongestCW = tmp;
#endif
}
coderInfo->spectral_count = counter; /* send the current count back to the outside world */
return(bits);
case 2:
for(i=offset;i<offset+length;i=i+4){
index = 27*quant[i] + 9*quant[i+1] + 3*quant[i+2] + quant[i+3] + 40;
codebook = huff2[index][LASTINTAB];
tmp = huff2[index][FIRSTINTAB];
bits += tmp;
data[counter] = codebook;
len[counter++] = tmp;
#ifdef DRM
num_data[coderInfo->cur_cw++] = 1;
coderInfo->iLenReordSpData += tmp;
if (tmp > coderInfo->iLenLongestCW)
coderInfo->iLenLongestCW = tmp;
#endif
}
coderInfo->spectral_count = counter; /* send the current count back to the outside world */
return(bits);
case 3:
for(i=offset;i<offset+length;i=i+4){
index = 27*ABS(quant[i]) + 9*ABS(quant[i+1]) + 3*ABS(quant[i+2]) + ABS(quant[i+3]);
codebook = huff3[index][LASTINTAB];
tmp = huff3[index][FIRSTINTAB];
bits = bits + tmp;
data[counter] = codebook;
len[counter++] = tmp;
#ifdef DRM
num_data[coderInfo->cur_cw] = 1;
cur_cw_len = tmp;
#endif
for(j=0;j<4;j++){
if(quant[i+j] > 0) { /* send out '0' if a positive value */
data[counter] = 0;
len[counter++] = 1;
bits += 1;
#ifdef DRM
num_data[coderInfo->cur_cw]++;
cur_cw_len += 1;
#endif
} else
if(quant[i+j] < 0) { /* send out '1' if a negative value */
data[counter] = 1;
len[counter++] = 1;
bits += 1;
#ifdef DRM
num_data[coderInfo->cur_cw]++;
cur_cw_len += 1;
#endif
}
}
#ifdef DRM
coderInfo->iLenReordSpData += cur_cw_len;
if (cur_cw_len > coderInfo->iLenLongestCW)
coderInfo->iLenLongestCW = cur_cw_len;
coderInfo->cur_cw++;
#endif
}
coderInfo->spectral_count = counter; /* send the current count back to the outside world */
return(bits);
case 4:
for(i=offset;i<offset+length;i=i+4){
index = 27*ABS(quant[i]) + 9*ABS(quant[i+1]) + 3*ABS(quant[i+2]) + ABS(quant[i+3]);
codebook = huff4[index][LASTINTAB];
tmp = huff4[index][FIRSTINTAB];
bits = bits + tmp;
data[counter] = codebook;
len[counter++] = tmp;
#ifdef DRM
num_data[coderInfo->cur_cw] = 1;
cur_cw_len = tmp;
#endif
for(j=0;j<4;j++){
if(quant[i+j] > 0) { /* send out '0' if a positive value */
data[counter] = 0;
len[counter++] = 1;
bits += 1;
#ifdef DRM
num_data[coderInfo->cur_cw]++;
cur_cw_len += 1;
#endif
} else
if(quant[i+j] < 0) { /* send out '1' if a negative value */
data[counter] = 1;
len[counter++] = 1;
bits += 1;
#ifdef DRM
num_data[coderInfo->cur_cw]++;
cur_cw_len += 1;
#endif
}
}
#ifdef DRM
coderInfo->iLenReordSpData += cur_cw_len;
if (cur_cw_len > coderInfo->iLenLongestCW)
coderInfo->iLenLongestCW = cur_cw_len;
coderInfo->cur_cw++;
#endif
}
coderInfo->spectral_count = counter; /* send the current count back to the outside world */
return(bits);
case 5:
for(i=offset;i<offset+length;i=i+2){
index = 9*(quant[i]) + (quant[i+1]) + 40;
codebook = huff5[index][LASTINTAB];
tmp = huff5[index][FIRSTINTAB];
bits = bits + tmp;
data[counter] = codebook;
len[counter++] = tmp;
#ifdef DRM
num_data[coderInfo->cur_cw++] = 1;
coderInfo->iLenReordSpData += tmp;
if (tmp > coderInfo->iLenLongestCW)
coderInfo->iLenLongestCW = tmp;
#endif
}
coderInfo->spectral_count = counter; /* send the current count back to the outside world */
return(bits);
case 6:
for(i=offset;i<offset+length;i=i+2){
index = 9*(quant[i]) + (quant[i+1]) + 40;
codebook = huff6[index][LASTINTAB];
tmp = huff6[index][FIRSTINTAB];
bits = bits + tmp;
data[counter] = codebook;
len[counter++] = tmp;
#ifdef DRM
num_data[coderInfo->cur_cw++] = 1;
coderInfo->iLenReordSpData += tmp;
if (tmp > coderInfo->iLenLongestCW)
coderInfo->iLenLongestCW = tmp;
#endif
}
coderInfo->spectral_count = counter; /* send the current count back to the outside world */
return(bits);
case 7:
for(i=offset;i<offset+length;i=i+2){
index = 8*ABS(quant[i]) + ABS(quant[i+1]);
codebook = huff7[index][LASTINTAB];
tmp = huff7[index][FIRSTINTAB];
bits = bits + tmp;
data[counter] = codebook;
len[counter++] = tmp;
#ifdef DRM
num_data[coderInfo->cur_cw] = 1;
cur_cw_len = tmp;
#endif
for(j=0;j<2;j++){
if(quant[i+j] > 0) { /* send out '0' if a positive value */
data[counter] = 0;
len[counter++] = 1;
bits += 1;
#ifdef DRM
num_data[coderInfo->cur_cw]++;
cur_cw_len += 1;
#endif
} else
if(quant[i+j] < 0) { /* send out '1' if a negative value */
data[counter] = 1;
len[counter++] = 1;
bits += 1;
#ifdef DRM
num_data[coderInfo->cur_cw]++;
cur_cw_len += 1;
#endif
}
}
#ifdef DRM
coderInfo->iLenReordSpData += cur_cw_len;
if (cur_cw_len > coderInfo->iLenLongestCW)
coderInfo->iLenLongestCW = cur_cw_len;
coderInfo->cur_cw++;
#endif
}
coderInfo->spectral_count = counter; /* send the current count back to the outside world */
return(bits);
case 8:
for(i=offset;i<offset+length;i=i+2){
index = 8*ABS(quant[i]) + ABS(quant[i+1]);
codebook = huff8[index][LASTINTAB];
tmp = huff8[index][FIRSTINTAB];
bits = bits + tmp;
data[counter] = codebook;
len[counter++] = tmp;
#ifdef DRM
num_data[coderInfo->cur_cw] = 1;
cur_cw_len = tmp;
#endif
for(j=0;j<2;j++){
if(quant[i+j] > 0) { /* send out '0' if a positive value */
data[counter] = 0;
len[counter++] = 1;
bits += 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -