l3bitstream.c

来自「ISO mp3 sources (distribution 10) Layer」· C语言 代码 · 共 866 行 · 第 1/2 页

C
866
字号
		for ( region = 0; region < 2; region++ )		    *pph = BF_addEntry( *pph, gi->table_select[region],  5 );		for ( window = 0; window < 3; window++ )		    *pph = BF_addEntry( *pph, gi->subblock_gain[window], 3 );	    }	    else	    {		for ( region = 0; region < 3; region++ )		    *pph = BF_addEntry( *pph, gi->table_select[region], 5 );		*pph = BF_addEntry( *pph, gi->region0_count, 4 );		*pph = BF_addEntry( *pph, gi->region1_count, 3 );	    }	    *pph = BF_addEntry( *pph, gi->scalefac_scale,     1 );	    *pph = BF_addEntry( *pph, gi->count1table_select, 1 );	}	if ( stereo == 2 )	    bits_sent += 136;	else	    bits_sent += 72;    }    return bits_sent;}static voidwrite_ancillary_data( char *theData, int lengthInBits ){    /*     */    int bytesToSend = lengthInBits / 8;    int remainingBits = lengthInBits % 8;    unsigned wrd;    int i;    userFrameDataPH->part->nrEntries = 0;    for ( i = 0; i < bytesToSend; i++ )    {	wrd = theData[i];	userFrameDataPH = BF_addEntry( userFrameDataPH, wrd, 8 );    }    if ( remainingBits )    {	/* right-justify remaining bits */	wrd = theData[bytesToSend] >> (8 - remainingBits);	userFrameDataPH = BF_addEntry( userFrameDataPH, wrd, remainingBits );    }    }/*  Some combinations of bitrate, Fs, and stereo make it impossible to stuff  out a frame using just main_data, due to the limited number of bits to  indicate main_data_length. In these situations, we put stuffing bits into  the ancillary data...*/static voiddrain_into_ancillary_data( int lengthInBits ){    /*     */    int wordsToSend   = lengthInBits / 32;    int remainingBits = lengthInBits % 32;    int i;    /*      userFrameDataPH->part->nrEntries set by call to write_ancillary_data()    */    for ( i = 0; i < wordsToSend; i++ )	userFrameDataPH = BF_addEntry( userFrameDataPH, 0, 32 );    if ( remainingBits )	userFrameDataPH = BF_addEntry( userFrameDataPH, 0, remainingBits );    }/*  Note the discussion of huffmancodebits() on pages 28  and 29 of the IS, as well as the definitions of the side  information on pages 26 and 27.  */static voidHuffmancodebits( BF_PartHolder **pph, int *ix, gr_info *gi ){    int L3_huffman_coder_count1( BF_PartHolder **pph, struct huffcodetab *h, int v, int w, int x, int y );    int bigv_bitcount( int ix[576], gr_info *cod_info );    int region1Start;    int region2Start;    int i, bigvalues, count1End;    int v, w, x, y, bits, cbits, xbits, stuffingBits;    unsigned int code, ext;    struct huffcodetab *h;    int bvbits, c1bits, tablezeros, r0, r1, r2, rt, *pr;    int bitsWritten = 0;    int idx = 0;    tablezeros = 0;    r0 = r1 = r2 = 0;        /* 1: Write the bigvalues */    bigvalues = gi->big_values * 2;    if ( bigvalues )    {	if ( !(gi->mixed_block_flag) && gi->window_switching_flag && (gi->block_type == 2) )	{ /* Three short blocks */	    /*	      Within each scalefactor band, data is given for successive	      time windows, beginning with window 0 and ending with window 2.	      Within each window, the quantized values are then arranged in	      order of increasing frequency...	      */	    int sfb, window, line, start, end;	    I192_3 *ix_s;	    int *scalefac = &sfBandIndex[fr_ps->header->sampling_frequency + (fr_ps->header->version * 3)].s[0];	    	    ix_s = (I192_3 *) ix;	    region1Start = 12;	    region2Start = 576;	    for ( sfb = 0; sfb < 13; sfb++ )	    {		unsigned tableindex = 100;		start = scalefac[ sfb ];		end   = scalefac[ sfb+1 ];		if ( start < region1Start )		    tableindex = gi->table_select[ 0 ];		else		    tableindex = gi->table_select[ 1 ];		assert( tableindex < 32 );		for ( window = 0; window < 3; window++ )		    for ( line = start; line < end; line += 2 )		    {			x = (*ix_s)[line][window];			y = (*ix_s)[line + 1][window];			assert( idx < 576 );			assert( idx >= 0 );			bits = HuffmanCode( tableindex, x, y, &code, &ext, &cbits, &xbits );			*pph = BF_addEntry( *pph,  code, cbits );			*pph = BF_addEntry( *pph,  ext, xbits );			bitsWritten += bits;		    }			    }	}	else	    if ( gi->mixed_block_flag && gi->block_type == 2 )	    {  /* Mixed blocks long, short */		int sfb, window, line, start, end;		unsigned tableindex;		I192_3 *ix_s;		int *scalefac = &sfBandIndex[fr_ps->header->sampling_frequency + (fr_ps->header->version * 3)].s[0];				ix_s = (I192_3 *) ix;		/* Write the long block region */		tableindex = gi->table_select[0];		if ( tableindex )		    for ( i = 0; i < 36; i += 2 )		    {			x = ix[i];			y = ix[i + 1];			bits = HuffmanCode( tableindex, x, y, &code, &ext, &cbits, &xbits );			*pph = BF_addEntry( *pph,  code, cbits );			*pph = BF_addEntry( *pph,  ext, xbits );			bitsWritten += bits;					    }		/* Write the short block region */		tableindex = gi->table_select[ 1 ];		assert( tableindex < 32 );		for ( sfb = 3; sfb < 13; sfb++ )		{		    start = scalefac[ sfb ];		    end   = scalefac[ sfb+1 ];           		    		    for ( window = 0; window < 3; window++ )			for ( line = start; line < end; line += 2 )			{			    x = (*ix_s)[line][window];			    y = (*ix_s)[line + 1][window];			    bits = HuffmanCode( tableindex, x, y, &code, &ext, &cbits, &xbits );			    *pph = BF_addEntry( *pph,  code, cbits );			    *pph = BF_addEntry( *pph,  ext, xbits );			    bitsWritten += bits;			}		}	    }	    else	    { /* Long blocks */		int *scalefac = &sfBandIndex[fr_ps->header->sampling_frequency + (fr_ps->header->version * 3)].l[0];		unsigned scalefac_index = 100;				if ( gi->mixed_block_flag )		{		    region1Start = 36;		    region2Start = 576;		}		else		{		    scalefac_index = gi->region0_count + 1;		    assert( scalefac_index < 23 );		    region1Start = scalefac[ scalefac_index ];		    scalefac_index += gi->region1_count + 1;		    assert( scalefac_index < 23 );    		    region2Start = scalefac[ scalefac_index ];		    assert( region1Start == gi->address1 );		}		for ( i = 0; i < bigvalues; i += 2 )		{		    unsigned tableindex = 100;		    /* get table pointer */		    if ( i < region1Start )		    {			tableindex = gi->table_select[0];			pr = &r0;		    }		    else			if ( i < region2Start )			{			    tableindex = gi->table_select[1];			    pr = &r1;			}			else			{			    tableindex = gi->table_select[2];			    pr = &r2;			}		    assert( tableindex < 32 );		    h = &ht[ tableindex ];		    /* get huffman code */		    x = ix[i];		    y = ix[i + 1];		    if ( tableindex )		    {			bits = HuffmanCode( tableindex, x, y, &code, &ext, &cbits, &xbits );			*pph = BF_addEntry( *pph,  code, cbits );			*pph = BF_addEntry( *pph,  ext, xbits );			bitsWritten += rt = bits;			*pr += rt;		    }		    else		    {			tablezeros += 1;			*pr = 0;		    }		}	    }    }    bvbits = bitsWritten;     /* 2: Write count1 area */    assert( (gi->count1table_select < 2) );    h = &ht[gi->count1table_select + 32];    count1End = bigvalues + (gi->count1 * 4);    assert( count1End <= 576 );    for ( i = bigvalues; i < count1End; i += 4 )    {	v = ix[i];	w = ix[i+1];	x = ix[i+2];	y = ix[i+3];	bitsWritten += L3_huffman_coder_count1( pph, h, v, w, x, y );    }    c1bits = bitsWritten - bvbits;    if ( (stuffingBits = gi->part2_3_length - gi->part2_length - bitsWritten) )    {	int stuffingWords = stuffingBits / 32;	int remainingBits = stuffingBits % 32;	assert( stuffingBits > 0 );	/*	  Due to the nature of the Huffman code	  tables, we will pad with ones	*/	while ( stuffingWords-- )	    *pph = BF_addEntry( *pph, ~0, 32 );	if ( remainingBits )	    *pph = BF_addEntry( *pph, ~0, remainingBits );	bitsWritten += stuffingBits;    }    assert( bitsWritten == gi->part2_3_length - gi->part2_length );#ifdef DEBUG    printf( "#### %d Huffman bits written (%02d + %02d), part2_length = %d, part2_3_length = %d, %d stuffing ####\n",	    bitsWritten, bvbits, c1bits, gi->part2_length, gi->part2_3_length, stuffingBits );#endif}intabs_and_sign( int *x ){    if ( *x > 0 )	return 0;    *x *= -1;    return 1;}intL3_huffman_coder_count1( BF_PartHolder **pph, struct huffcodetab *h, int v, int w, int x, int y ){    HUFFBITS huffbits;    unsigned int signv, signw, signx, signy, p;    int len;    int totalBits = 0;        signv = abs_and_sign( &v );    signw = abs_and_sign( &w );    signx = abs_and_sign( &x );    signy = abs_and_sign( &y );        p = v + (w << 1) + (x << 2) + (y << 3);    huffbits = h->table[p];    len = h->hlen[ p ];    *pph = BF_addEntry( *pph,  huffbits, len );    totalBits += len;    if ( v )    {	*pph = BF_addEntry( *pph,  signv, 1 );	totalBits += 1;    }    if ( w )    {	*pph = BF_addEntry( *pph,  signw, 1 );	totalBits += 1;    }    if ( x )    {	*pph = BF_addEntry( *pph,  signx, 1 );	totalBits += 1;    }    if ( y )    {	*pph = BF_addEntry( *pph,  signy, 1 );	totalBits += 1;    }    return totalBits;}/*  Implements the pseudocode of page 98 of the IS  */intHuffmanCode( int table_select, int x, int y, unsigned int *code, unsigned int *ext, int *cbits, int *xbits ){    unsigned signx, signy, linbitsx, linbitsy, linbits, xlen, ylen, idx;    struct huffcodetab *h;    *cbits = 0;    *xbits = 0;    *code  = 0;    *ext   = 0;        if ( table_select == 0 )	return 0;        signx = abs_and_sign( &x );    signy = abs_and_sign( &y );    h = &(ht[table_select]);    xlen = h->xlen;    ylen = h->ylen;    linbits = h->linbits;    linbitsx = linbitsy = 0;    if ( table_select > 15 )    { /* ESC-table is used */	if ( x > 14 )	{	    linbitsx = x - 15;	    assert( linbitsx <= h->linmax );	    x = 15;	}	if ( y > 14 )	{	    linbitsy = y - 15;	    assert( linbitsy <= h->linmax );	    y = 15;	}	idx = (x * ylen) + y;	*code = h->table[idx];	*cbits = h->hlen[ idx ];	if ( x > 14 )	{	    *ext |= linbitsx;	    *xbits += linbits;	}	if ( x != 0 )	{	    *ext <<= 1;	    *ext |= signx;	    *xbits += 1;	}	if ( y > 14 )	{	    *ext <<= linbits;	    *ext |= linbitsy;	    *xbits += linbits;	}	if ( y != 0 )	{	    *ext <<= 1;	    *ext |= signy;	    *xbits += 1;	}    }    else    { /* No ESC-words */	idx = (x * ylen) + y;	*code = h->table[idx];	*cbits += h->hlen[ idx ];	if ( x != 0 )	{	    *code <<= 1;	    *code |= signx;	    *cbits += 1;	}	if ( y != 0 )	{	    *code <<= 1;	    *code |= signy;	    *cbits += 1;	}    }    assert( *cbits <= 32 );    assert( *xbits <= 32 );    return *cbits + *xbits;}

⌨️ 快捷键说明

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