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

📄 text_bits.c

📁 <VC++视频音频开发>一书的光盘资料。
💻 C
字号:
#include "momusys.h"
#include "text_defs.h"
#include "bitstream.h"
#include "text_bits.h"
#include "putvlc.h"
#include "zigzag.h"								  
#include "max_level.h"							  
Int  	IntraDC_dpcm (Int val, Int lum, Image *bitstream);
Int  	CodeCoeff (Int j_start, Int Mode, Int qcoeff[],
		Int block, Int ncoeffs, Image *bitstream);
Int  	CodeCoeff_RVLC (Int j_start, Int Mode, Int qcoeff[],
		Int block, Int ncoeffs, Image *bitstream);
Void MB_CodeCoeff(Bits* bits, Int *qcoeff,
Int Mode, Int CBP, Int ncoeffs,
Int intra_dcpred_disable,
Image *DCbitstream,
Image *bitstream,
Int transp_pattern[], Int direction[],
Int error_res_disable,
Int reverse_vlc,
Int switched,
Int alternate_scan)
{
	Int i, m, coeff[64];
	Int *zz = alternate_scan ? zigzag_v : zigzag;
	if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
	{
		if (intra_dcpred_disable == 0)
		{
			for (i = 0; i < 6; i++)
			{
				{
					if (!alternate_scan)
					{
						switch (direction[i])
						{
							case 1: zz = zigzag_v; break;
							case 2: zz = zigzag_h; break;
							case 0: break;
							default: fprintf(stderr, "MB_CodeCoeff(): Error in zigzag direction\n");
							exit(-1);
						}
					}
					
					for (m = 0; m < 64; m++)
					{
						*(coeff + zz[m]) = qcoeff[i*ncoeffs+m];
					}
					if (switched==0)
					{
						if (error_res_disable)
						{
							if (i < 4)
								bits->Y += IntraDC_dpcm(coeff[0],1,bitstream);
							else
								bits->C += IntraDC_dpcm(coeff[0],0,bitstream);
						}
						else
						{
							if (i < 4)
								bits->Y += IntraDC_dpcm(coeff[0],1,DCbitstream);
							else
								bits->C += IntraDC_dpcm(coeff[0],0,DCbitstream);
						}
					}
					
					if ((i==0 && CBP&32) ||
						(i==1 && CBP&16) ||
						(i==2 && CBP&8)  ||
						(i==3 && CBP&4)  ||
						(i==4 && CBP&2)  ||
						(i==5 && CBP&1))
					{
						if (error_res_disable || ((!error_res_disable) && (!reverse_vlc)))
						{
							if (i < 4)
								bits->Y += CodeCoeff(1-switched,Mode, coeff,i,ncoeffs,bitstream);
							else
								bits->C += CodeCoeff(1-switched,Mode, coeff,i,ncoeffs,
									bitstream);
						}
						else
						{
							if (i < 4)
								bits->Y += CodeCoeff_RVLC(1-switched,Mode, coeff, i,
									ncoeffs, bitstream);
							else
								bits->C += CodeCoeff_RVLC(1-switched,Mode, coeff, i,
									ncoeffs, bitstream);
						}
					}
				}
			}
		}
		else									  
		{
			for (i = 0; i < 6; i++)
			{
				{
					
					for (m = 0; m < 64; m++)
						*(coeff + zz[m]) = qcoeff[i*ncoeffs+m];
					if (switched==0)
					{
						if (error_res_disable)
						{
							if (coeff[0] != 128)
								BitstreamPutBits(bitstream,(long)(coeff[0]),8L);
							else
								BitstreamPutBits(bitstream, 255L, 8L);
						}
						else
						{
							if (coeff[0] != 128)
								BitstreamPutBits(DCbitstream,(long)(coeff[0]),8L);
							else
								BitstreamPutBits(DCbitstream,255L, 8L);
						}
						if (i < 4)
							bits->Y += 8;
						else
							bits->C += 8;
					}
					if ((i==0 && CBP&32) || (i==1 && CBP&16) ||
						(i==2 && CBP&8) || (i==3 && CBP&4) ||
						(i==4 && CBP&2) || (i==5 && CBP&1))
					{
						
						if (error_res_disable || ((!error_res_disable) && (!reverse_vlc)))
						{
							if (i < 4)
								bits->Y += CodeCoeff(1-switched,Mode, coeff,i,ncoeffs,
									bitstream);
							else
								bits->C += CodeCoeff(1-switched,Mode, coeff,i,ncoeffs,
									bitstream);
						}
						else
						{
							if (i < 4)
								bits->Y += CodeCoeff_RVLC(1-switched,Mode, coeff, i,
									ncoeffs, bitstream);
							else
								bits->C += CodeCoeff_RVLC(1-switched,Mode, coeff, i,
									ncoeffs, bitstream);
						}
					}
				}
			}
		}
	}
	else										  
	{
		for (i = 0; i < 6; i++)
		{
			
			for (m = 0; m < 64; m++)
				*(coeff + zz[m]) = qcoeff[i*ncoeffs+m];
			if ((i==0 && CBP&32) ||
				(i==1 && CBP&16) ||
				(i==2 && CBP&8) ||
				(i==3 && CBP&4) ||
				(i==4 && CBP&2) ||
				(i==5 && CBP&1))
			{
				if (error_res_disable || ((!error_res_disable) && (!reverse_vlc)))
				{
					if (i < 4)
						bits->Y += CodeCoeff(0,Mode, coeff, i, ncoeffs, bitstream);
					else
						bits->C += CodeCoeff(0,Mode, coeff, i, ncoeffs, bitstream);
				}
				else
				{
					if (i < 4)
						bits->Y += CodeCoeff_RVLC(0,Mode, coeff, i, ncoeffs,
							bitstream);
					else
						bits->C += CodeCoeff_RVLC(0,Mode, coeff, i, ncoeffs,
							bitstream);
				}
			}
		}
	}
}
Int
IntraDC_dpcm(Int val, Int lum, Image *bitstream)
{
	Int n_bits;
	Int absval, size = 0;
	absval = ( val <0)?-val:val;				  
	
	size = 0;
	while(absval)
	{
		absval>>=1;
		size++;
	}
	if (lum)
	{											  
		n_bits = PutDCsize_lum (size, bitstream);
	}
	else
	{											  
		n_bits = PutDCsize_chrom (size, bitstream);
	}
	if ( size != 0 )
	{
		if (val>=0)
		{
			;
		}
		else
		{
			absval = -val;						  
			val = (absval ^( (int)pow(2.0,(double)size)-1) );
		}
		BitstreamPutBits(bitstream, (long)(val), (long)(size));
		n_bits += size;
		if (size > 8)
			BitstreamPutBits(bitstream, (long)1, (long)1);
	}
	return n_bits;								  
}
Int CodeCoeff(Int j_start, Int Mode, Int qcoeff[], Int block, Int ncoeffs, Image *bitstream)
{
	Int j, bits;
	Int prev_run, run, prev_level, level, first;
	Int prev_ind, ind, prev_s, s, length;
	run = bits = 0;
	first = 1;
	prev_run = prev_level = prev_ind = level = s = prev_s = ind = 0;
	for (j = j_start; j< ncoeffs; j++)
	{
		
		{
			
			
			s = 0;
			
			if ((level = qcoeff[j]) == 0)
			{
				run++;
			}
			else
			{
				
				if (level < 0)
				{
					s = 1;
					level = -level;
				}
				ind = level | run<<4;
				ind = ind | 0<<12;				  
				if (!first)
				{
					
					if ((prev_run < 64) &&
						(((prev_level < 13) && (Mode != MODE_INTRA &&
						Mode != MODE_INTRA_Q))
						|| ((prev_level < 28) && (Mode == MODE_INTRA ||
						Mode == MODE_INTRA_Q))))
					{
						
						if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
						{
							length = PutCoeff_Intra(prev_run, prev_level,
								0, bitstream);
						}
						else
						{
							length = PutCoeff_Inter(prev_run, prev_level,
								0, bitstream);
						}
					}
					else
						length = 0;
					
					if (length == 0)
					{
						if ( prev_run < 64 )
						{
							
							int level_minus_max;
							if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
								level_minus_max = prev_level -
									intra_max_level[0][prev_run];
							else
								level_minus_max = prev_level -
									inter_max_level[0][prev_run];
							if (  ( (level_minus_max < 13) && (Mode != MODE_INTRA && Mode != MODE_INTRA_Q) ) ||
								( (level_minus_max < 28) && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) ) )
							{
								
								if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
								{
									length = PutLevelCoeff_Intra(prev_run, level_minus_max, 0, bitstream);
								}
								else
								{
									length = PutLevelCoeff_Inter(prev_run, level_minus_max, 0, bitstream);
								}
							} else
							length = 0;
						}
						else length = 0;
					}
					
					if (length == 0)
					{
						if ( ((prev_level < 13) && (Mode != MODE_INTRA && Mode != MODE_INTRA_Q)) ||
							((prev_level < 28) && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)) )
						{
							
							int run_minus_max;
							if (prev_level == 0)
							{
								fprintf (stdout, "ERROR(CodeCoeff-second esc): level is %d\n", prev_level);
								exit(-1);
							}
							if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
								run_minus_max = prev_run - (intra_max_run0[prev_level]+1);
							else
								run_minus_max = prev_run - (inter_max_run0[prev_level]+1);
												  
							if (run_minus_max < 64)
							{
								
								if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
								{
									length = PutRunCoeff_Intra(run_minus_max, prev_level, 0, bitstream);
								}
								else
								{
									length = PutRunCoeff_Inter(run_minus_max, prev_level, 0, bitstream);
								}
							} else
							length = 0;
						}
						else length = 0;
					}
					
					if (length == 0)
					{							  
						if (prev_s == 1)
						{
							
							
							prev_level = (prev_level^0xfff)+1;
						}
						BitstreamPutBits(bitstream, 3L, 7L);
												  
						BitstreamPutBits(bitstream, 3L, 2L);
												  
						BitstreamPutBits(bitstream, 0L, 1L);
												  
						BitstreamPutBits(bitstream, (long)(prev_run), 6L);
						
						BitstreamPutBits(bitstream, MARKER_BIT, 1);
						
						
						
												  
						BitstreamPutBits(bitstream, (long)(prev_level), 12L);
						
						BitstreamPutBits(bitstream, MARKER_BIT, 1);
						
						bits += 30;
					}
					else
					{
						BitstreamPutBits(bitstream, (long)(prev_s), 1L);
						bits += length + 1;
					}
				}
				prev_run = run; prev_s = s;
				prev_level = level; prev_ind = ind;
				run = first = 0;
			}
		}
	}
	
	if (!first)
	{
		prev_ind = prev_ind | 1<<12;			  
		if ((prev_run < 64) &&
			(((prev_level < 4) && (Mode != MODE_INTRA &&
			Mode != MODE_INTRA_Q))
			|| ((prev_level < 9) && ((Mode == MODE_INTRA) ||
			(Mode == MODE_INTRA_Q)))))
		{
			
			if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
			{
				length = PutCoeff_Intra(prev_run, prev_level, 1,
					bitstream);
			}
			else
			{
				length = PutCoeff_Inter(prev_run, prev_level, 1,
					bitstream);
			}
		}
		else
			length = 0;
		
		if (length == 0)
		{
			if ( prev_run < 64 )
			{
				
				int level_minus_max;
				if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
					level_minus_max = prev_level - intra_max_level[1][prev_run];
				else
					level_minus_max = prev_level - inter_max_level[1][prev_run];
				if (  ( (level_minus_max < 4) && (Mode != MODE_INTRA && Mode != MODE_INTRA_Q) ) ||
					( (level_minus_max < 9) && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) ) )
				{
					
					if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
					{
						length = PutLevelCoeff_Intra(prev_run, level_minus_max, 1, bitstream);
					}
					else
					{
						length = PutLevelCoeff_Inter(prev_run, level_minus_max, 1, bitstream);
					}
				} else
				length = 0;
			}
			else length = 0;
		}
		
		if (length == 0)
		{
			if (((prev_level < 4) && (Mode != MODE_INTRA && Mode != MODE_INTRA_Q))||
				((prev_level < 9) && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)) )
			{
				
				int run_minus_max;
				if (prev_level == 0)
				{
					fprintf (stdout, "ERROR(CodeCoeff-second esc): level is %d\n", prev_level);
					exit(-1);
				}
				if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
					run_minus_max = prev_run - (intra_max_run1[prev_level]+1);
				else
					run_minus_max = prev_run - (inter_max_run1[prev_level]+1);
				if (run_minus_max < 64)			  
				{
					
					if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
					{
						length = PutRunCoeff_Intra(run_minus_max, prev_level, 1, bitstream);
					}
					else
					{
						length = PutRunCoeff_Inter(run_minus_max, prev_level, 1, bitstream);
					}
				} else
				length = 0;
			}
			else length = 0;
		}
		
		if (length == 0)
		{										  
			if (prev_s == 1)
			{
				
				
				prev_level = (prev_level^0xfff)+1;
			}
			BitstreamPutBits(bitstream, 3L, 7L);
			BitstreamPutBits(bitstream, 3L, 2L);  
			BitstreamPutBits(bitstream, 1L, 1L);  
			BitstreamPutBits(bitstream, (long)(prev_run), 6L);
			
			BitstreamPutBits(bitstream, MARKER_BIT, 1);
			
			
			
												  
			BitstreamPutBits(bitstream, (long)(prev_level), 12L);
			
			BitstreamPutBits(bitstream, MARKER_BIT, 1);
			
			bits += 30;
		}
		else
		{
			BitstreamPutBits(bitstream, (long)(prev_s), 1L);
			bits += length + 1;
		}
	}
	return bits;
}
Int CodeCoeff_RVLC(Int j_start, Int Mode, Int qcoeff[], Int block, Int ncoeffs, Image *bitstream)
{
	Int j, bits;
	Int prev_run, run, prev_level, level, first;
	Int prev_ind, ind, prev_s, s, length;
	run = bits = 0;
	first = 1;
	prev_run = prev_level = prev_ind = level = s = prev_s = ind = 0;
	for (j = j_start; j< ncoeffs; j++)
	{
		
		{
			
			
			s = 0;
			
			if ((level = qcoeff[j]) == 0)
			{
				run++;
			}
			else
			{
				
				if (level < 0)
				{
					s = 1;
					level = -level;
				}
				ind = level | run<<4;
				ind = ind | 0<<12;				  
				if (!first)
				{
					
					if (prev_level  < 28 && prev_run < 39)
						
						if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
					{
						length = PutCoeff_Intra_RVLC(prev_run, prev_level, 0,
							bitstream);
					}
					else
					{
						length = PutCoeff_Inter_RVLC(prev_run, prev_level, 0,
							bitstream);
					}
					else
						length = 0;
					if (length == 0)
					{							  
												  
						BitstreamPutBits(bitstream, 1L, 5L);
												  
						BitstreamPutBits(bitstream, 0L, 1L);
						BitstreamPutBits(bitstream,
							(long)(prev_run), 6L);
						
						
						
						
						BitstreamPutBits( bitstream, MARKER_BIT, 1 );
												  
						BitstreamPutBits( bitstream, (long)(prev_level), 11L);
						BitstreamPutBits( bitstream, MARKER_BIT, 1 );
												  
						BitstreamPutBits(bitstream, 0L, 4L);
												  
						BitstreamPutBits(bitstream,
							(long)(prev_s),1L);
						bits += 5 + 1 + 6 + 1 + 11 + 1 + 4 + 1;
						
					}
					else
					{
						BitstreamPutBits(bitstream,
							(long)(prev_s), 1L);
						bits += length + 1;
					}
				}
				prev_run = run; prev_s = s;
				prev_level = level; prev_ind = ind;
				run = first = 0;
			}
		}
	}
	
	if (!first)
	{
		prev_ind = prev_ind | 1<<12;			  
		if (prev_level  < 5 && prev_run < 45)
			
			if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
		{
			length = PutCoeff_Intra_RVLC(prev_run, prev_level, 1,
				bitstream);
		}
		else
		{
			length = PutCoeff_Inter_RVLC(prev_run, prev_level, 1,
				bitstream);
		}
		else
			length = 0;
		if (length == 0)
		{										  
			BitstreamPutBits(bitstream, 1L, 5L);  
			BitstreamPutBits(bitstream, 1L, 1L);  
												  
			BitstreamPutBits(bitstream, (long)(prev_run), 6L);
			
			
			
			BitstreamPutBits( bitstream, MARKER_BIT, 1 );
												  
			BitstreamPutBits( bitstream, (long)(prev_level), 11L);
			BitstreamPutBits( bitstream, MARKER_BIT, 1 );
			BitstreamPutBits(bitstream, 0L, 4L);  
												  
			BitstreamPutBits(bitstream, (long)(prev_s), 1L);
			bits += 24;
		}
		else
		{
			BitstreamPutBits(bitstream, (long)(prev_s), 1L);
			bits += length + 1;
		}
	}
	return bits;
}
void
Bits_Reset (Bits *bits)
{
	memset(bits, 0, sizeof(Bits));
}

⌨️ 快捷键说明

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