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

📄 huffman.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 3 页
字号:
     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;

	counter = coderInfo->spectral_count;

	switch (book) {
	case 0:
	case INTENSITY_HCB2:
	case INTENSITY_HCB:
		/* 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 */
		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;
		}
		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;
		}
		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;
			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;
				} else
				if(quant[i+j] < 0) {  /* send out '1' if a negative value */
					data[counter] = 1;
					len[counter++] = 1;
					bits += 1;
				}
			}
		}
		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;
			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;
				} else
				if(quant[i+j] < 0) {  /* send out '1' if a negative value */
					data[counter] = 1;
					len[counter++] = 1;
					bits += 1;
				}
			}
		}
		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;
		}
		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;
		}
		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;
			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;
				} else
				if(quant[i+j] < 0) {  /* send out '1' if a negative value */
					data[counter] = 1;
					len[counter++] = 1;
					bits += 1;
				}
			}
		}
		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;
			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;
				} else
				if(quant[i+j] < 0) {  /* send out '1' if a negative value */
					data[counter] = 1;
					len[counter++] = 1;
					bits += 1;
				}
			}
		}
		coderInfo->spectral_count = counter;  /* send the current count back to the outside world */
		return(bits);
	case 9:
		for(i=offset;i<offset+length;i=i+2){
			index = 13*ABS(quant[i]) + ABS(quant[i+1]);
			codebook = huff9[index][LASTINTAB];
			tmp = huff9[index][FIRSTINTAB];
			bits = bits + tmp;
			data[counter] = codebook;
			len[counter++] = tmp;

			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;
				} else
				if(quant[i+j] < 0) {  /* send out '1' if a negative value */
					data[counter] = 1;
					len[counter++] = 1;
					bits += 1;
				}
			}
		}
		coderInfo->spectral_count = counter;  /* send the current count back to the outside world */
		return(bits);
	case 10:
		for(i=offset;i<offset+length;i=i+2){
			index = 13*ABS(quant[i]) + ABS(quant[i+1]);
			codebook = huff10[index][LASTINTAB];
			tmp = huff10[index][FIRSTINTAB];
			bits = bits + tmp;
			data[counter] = codebook;
			len[counter++] = tmp;

			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;
				} else
				if(quant[i+j] < 0) {  /* send out '1' if a negative value */
					data[counter] = 1;
					len[counter++] = 1;
					bits += 1;
				}
			}
		}
		coderInfo->spectral_count = counter;  /* send the current count back to the outside world */
		return(bits);
	case 11:
		/* First, calculate the indecies into the huffman tables */
		for(i=offset;i<offset+length;i=i+2){
			if ((ABS(quant[i]) >= 16) && (ABS(quant[i+1]) >= 16)) {  /* both codewords were above 16 */
				/* first, code the orignal pair, with the larger value saturated to +/- 16 */
				index = 17*16 + 16;
			}
			else if (ABS(quant[i]) >= 16) {  /* the first codeword was above 16, not the second one */
				/* first, code the orignal pair, with the larger value saturated to +/- 16 */
				index = 17*16 + ABS(quant[i+1]);
			}
			else if (ABS(quant[i+1]) >= 16) { /* the second codeword was above 16, not the first one */
				index = 17*ABS(quant[i]) + 16;
			}
			else {  /* there were no values above 16, so no escape sequences */
				index = 17*ABS(quant[i]) + ABS(quant[i+1]);
			}

			/* write out the codewords */
			tmp = huff11[index][FIRSTINTAB];
			codebook = huff11[index][LASTINTAB];
			bits += tmp;
			data[counter] = codebook;
			len[counter++] = tmp;
			
			/* Take care of the sign bits */
			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;
				} else
				if(quant[i+j] < 0) {  /* send out '1' if a negative value */
					data[counter] = 1;
					len[counter++] = 1;
					bits += 1;
				}
			}

			/* write out the escape sequences */
			if ((ABS(quant[i]) >= 16) && (ABS(quant[i+1]) >= 16)) {  /* both codewords were above 16 */
				/* code and transmit the first escape_sequence */
				esc_sequence = CalculateEscSequence(quant[i],&len_esc); 
				bits += len_esc;
				data[counter] = esc_sequence;
				len[counter++] = len_esc;

				/* then code and transmit the second escape_sequence */
				esc_sequence = CalculateEscSequence(quant[i+1],&len_esc);
				bits += len_esc;
				data[counter] = esc_sequence;
				len[counter++] = len_esc;
			}
			else if (ABS(quant[i]) >= 16) {  /* the first codeword was above 16, not the second one */
				/* code and transmit the escape_sequence */
				esc_sequence = CalculateEscSequence(quant[i],&len_esc); 
				bits += len_esc;
				data[counter] = esc_sequence;
				len[counter++] = len_esc;
			}
			else if (ABS(quant[i+1]) >= 16) { /* the second codeword was above 16, not the first one */
				/* code and transmit the escape_sequence */
				esc_sequence = CalculateEscSequence(quant[i+1],&len_esc); 
				bits += len_esc;
				data[counter] = esc_sequence;
				len[counter++] = len_esc;
			} 
		}
		coderInfo -> spectral_count = counter;  /* send the current count back to the outside world */
		return(bits);
	}
	return 0;
}

int CalcBits(CoderInfo *coderInfo,
			 int book,
			 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'

⌨️ 快捷键说明

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