l3bitstream.c

来自「mp3 source code decoder & encoder」· C语言 代码 · 共 837 行 · 第 1/2 页

C
837
字号
            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 (config.wave.channels==2) bits_sent += 136;
	else                           bits_sent += 72;
    }
    return bits_sent;
}

static void write_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 void
drain_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 void
Huffmancodebits(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;

	    int (*ix_s)[192][3]; 
	    int *scalefac = &sfBandIndex[config.mpeg.samplerate_index+(config.mpeg.type*3)].s[0];
	    
	    ix_s = (int (*)[192][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];
		if (tableindex >= 32) ERROR("tableindex error");

		for (window = 0; window < 3; window++)
		    for (line = start; line < end; line += 2)
		    {
			x = (*ix_s)[line][window];
			y = (*ix_s)[line + 1][window];
			if ((idx >= 576) || (idx < 0)) ERROR("id_x out of range");
			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;
		int (*ix_s)[192][3];
                int *scalefac = &sfBandIndex[config.mpeg.samplerate_index+(config.mpeg.type*3)].s[0];
		
		ix_s = (int (*)[192][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];
		if (tableindex >= 32) ERROR("index error");

		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[config.mpeg.samplerate_index+(config.mpeg.type*3)].l[0];
		unsigned scalefac_index = 100;
		
		if (gi->mixed_block_flag)
		{
		    region1Start = 36;
		    region2Start = 576;
		}
		else
		{
		    scalefac_index = gi->region0_count + 1;
		    if (scalefac_index >= 23) ERROR("scalefactor error");
		    region1Start = scalefac[scalefac_index];
		    scalefac_index += gi->region1_count + 1;
		    if (scalefac_index >= 23) ERROR("scalefactor error");   
		    region2Start = scalefac[scalefac_index];
		    if (region1Start != gi->address1) ERROR("regionStart error");
		}
		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;
			}
		    if (tableindex >= 32) ERROR("table index error");
		    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 */
    if ((gi->count1table_select >= 2)) ERROR("gi error");
    h = &ht[gi->count1table_select + 32];
    count1End = bigvalues + (gi->count1 * 4);
    if (count1End > 576) ERROR("countEnd error");
    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;
	if (stuffingBits <= 0) ERROR("stufbits error");

	/*
	  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;
    }
    if (bitsWritten != gi->part2_3_length - gi->part2_length) ERROR("bits write error");

/* MP3STEGO-> */
#if defined(_DEBUG)
	fprintf(fLog, "- %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
/* ->MP3STEGO */
}

int abs_and_sign(int *x)
{
    if (*x > 0) return 0;
    *x *= -1;
    return 1;
}

int L3_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 */
int HuffmanCode(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;
	    if (linbitsx > h->linmax) ERROR("linbits error");
	    x = 15;
	}
	if (y > 14)
	{
	    linbitsy = y - 15;
	    if (linbitsy > h->linmax) ERROR("linbits error");;
	    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;
	}
    }
    if ((*cbits > 32) || (*xbits > 32)) ERROR("cbits error");
    return *cbits + *xbits;
}

⌨️ 快捷键说明

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