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

📄 huffdec2.c

📁 jpeg and mpeg 编解码技术源代码
💻 C
字号:

#include <math.h>
#include "all.h"


typedef int DINT_DATATYPE ;

static void
deinterleave(DINT_DATATYPE inptr[], DINT_DATATYPE outptr[], short ngroups,
    short nsubgroups[], int ncells[], short cellsize[])
{
    int i, j, k, l;
    DINT_DATATYPE *start_inptr, *start_subgroup_ptr, *subgroup_ptr;
    short cell_inc, subgroup_inc;

    start_subgroup_ptr = outptr;

    for (i = 0; i < ngroups; i++)
    {
	cell_inc = 0;
	start_inptr = inptr;

	/* Compute the increment size for the subgroup pointer */

	subgroup_inc = 0;
	for (j = 0; j < ncells[i]; j++) {
	    subgroup_inc += cellsize[j];
	}

	/* Perform the deinterleaving across all subgroups in a group */

	for (j = 0; j < ncells[i]; j++) {
	    subgroup_ptr = start_subgroup_ptr;

	    for (k = 0; k < nsubgroups[i]; k++) {
		outptr = subgroup_ptr + cell_inc;
		for (l = 0; l < cellsize[j]; l++) {
		    *outptr++ = *inptr++;
		}
		subgroup_ptr += subgroup_inc;
	    }
	    cell_inc += cellsize[j];
	}
	start_subgroup_ptr += (inptr - start_inptr);
    }
}

static void 
calc_gsfb_table(Info *info, byte *group)
{
    int group_offset;
    int group_idx;
    int offset;
    short * group_offset_p;
    int sfb,len;
    /* first calc the group length*/
    if (info->islong){
	return;
    } else {
	group_offset = 0;
	group_idx =0;
	do  {
	    info->group_len[group_idx]=group[group_idx]-group_offset;
	    group_offset=group[group_idx];
	    group_idx++;
	} while (group_offset<8);
	info->num_groups=group_idx;
	group_offset_p = info->bk_sfb_top;
	offset=0;
	for (group_idx=0;group_idx<info->num_groups;group_idx++){
	    len = info->group_len[group_idx];
	    for (sfb=0;sfb<info->sfb_per_sbk[group_idx];sfb++){
		offset += info->sfb_width_128[sfb] * len;
		*group_offset_p++ = offset;
	    }
	}
    }
}

void
getgroup(Info *info, byte *group)
{
    int i, j, first_short;

    first_short=1;
    for (i = 0; i < info->nsbk; i++) {
	if (info->bins_per_sbk[i] > SN2) {
	    /* non-short windows are always their own group */
	    *group++ = i+1;
	}
	else {
	    /* only short-window sequences are grouped! */
	    if (first_short) {
		/* first short window is always a new group */
		first_short=0;
	    }
	    else {
		if((j = getbits(1)) == 0) {
		    *group++ = i;
		}
	    }
	}
    }
    *group = i;
}

/*
 * read a synthesis mask
 *  uses EXTENDED_MS_MASK
 *  and grouped mask 
 */
int
getmask(Info *info, byte *group, byte max_sfb, byte *mask)
{
    int b, i, mp;

    mp = getbits(LEN_MASK_PRES);

    /* special EXTENDED_MS_MASK cases */
    if(mp == 0) { /* no ms at all */
	return 0;
    }
    if(mp == 2) {/* MS for whole spectrum on, mask bits set to 1 */
	for(b = 0; b < info->nsbk; b = *group++)
	    for(i = 0; i < info->sfb_per_sbk[b]; i ++)
		*mask++ = 1;
	return 2;
    }

    /* otherwise get mask */
    for(b = 0; b < info->nsbk; b = *group++){
	for(i = 0; i < max_sfb; i ++) {
	    *mask = getbits(LEN_MASK);
	    mask++;
	}
	for( ; i < info->sfb_per_sbk[b]; i++){
	    *mask = 0;
	    mask++;
	}
    }
    return 1;
}

void
clr_tns( Info *info, TNS_frame_info *tns_frame_info )
{
    int s;

    tns_frame_info->n_subblocks = info->nsbk;
    for (s=0; s<tns_frame_info->n_subblocks; s++)
	tns_frame_info->info[s].n_filt = 0;
}

int
get_tns( Info *info, TNS_frame_info *tns_frame_info )
{
    int                       f, t, top, res, res2, compress;
    int                       short_flag, s;
    short                     *sp, tmp, s_mask, n_mask;
    TNSfilt                   *tns_filt;
    TNSinfo                   *tns_info;
    static short              sgn_mask[] = { 
	0x2, 0x4, 0x8     };
    static short              neg_mask[] = { 
	0xfffc, 0xfff8, 0xfff0     };


    short_flag = (!info->islong);
    tns_frame_info->n_subblocks = info->nsbk;

    for (s=0; s<tns_frame_info->n_subblocks; s++) {
	tns_info = &tns_frame_info->info[s];

	if (!(tns_info->n_filt = getbits( short_flag ? 1 : 2 )))
	    continue;
	    
	tns_info -> coef_res = res = getbits( 1 ) + 3;
	top = info->sfb_per_sbk[s];
	tns_filt = &tns_info->filt[ 0 ];
	for (f=tns_info->n_filt; f>0; f--)  {
	    tns_filt->stop_band = top;
	    top = tns_filt->start_band = top - getbits( short_flag ? 4 : 6 );
	    tns_filt->order = getbits( short_flag ? 3 : 5 );

	    if (tns_filt->order)  {
		tns_filt->direction = getbits( 1 );
		compress = getbits( 1 );

		res2 = res - compress;
		s_mask = sgn_mask[ res2 - 2 ];
		n_mask = neg_mask[ res2 - 2 ];

		sp = tns_filt -> coef;
		for (t=tns_filt->order; t>0; t--)  {
		    tmp = getbits( res2 );
		    *sp++ = (tmp & s_mask) ? (tmp | n_mask) : tmp;
		}
	    }
	    tns_filt++;
	}
    }   /* subblock loop */
    return 1;
}

/*
 * NEC noiseless coding
 */
struct Nec_Info
{
    int pulse_data_present;
    int number_pulse;
    int pulse_start_sfb;
    int pulse_position[NUM_NEC_LINES];
    int pulse_offset[NUM_NEC_LINES];
    int pulse_amp[NUM_NEC_LINES];
};
static struct Nec_Info nec_info;

static void
get_nec_nc(struct Nec_Info *nec_info)
{
    int i;
    nec_info->number_pulse = getbits(LEN_NEC_NPULSE);
    nec_info->pulse_start_sfb = getbits(LEN_NEC_ST_SFB);
    for(i=0; i<nec_info->number_pulse+1; i++) {
	nec_info->pulse_offset[i] = getbits(LEN_NEC_POFF);
	nec_info->pulse_amp[i] = getbits(LEN_NEC_PAMP);
    }
}

static void
nec_nc(int *coef, struct Nec_Info *nec_info)
{
    int i, k;

    k = only_long_info.sbk_sfb_top[0][nec_info->pulse_start_sfb];

    for(i=0; i<=nec_info->number_pulse; i++) {
		k += nec_info->pulse_offset[i];
		if (coef[k]>0)
			coef[k] += nec_info->pulse_amp[i];
		else
			coef[k] -= nec_info->pulse_amp[i];
    }
}

int
getics(Info *info, int common_window, byte *win, byte *wshape, 
    byte *group, byte *max_sfb, int *lpflag, int *prstflag, 
    byte *cb_map, Float *coef, short *global_gain, 
    short *factors,
    TNS_frame_info *tns
	   )
{
    int nsect, i, cb, top, bot, tot_sfb;
    byte sect[ 2*(MAXBANDS+1) ];

    /*
	* global gain
	*/
    *global_gain = getbits(LEN_SCL_PCM);

    if (!common_window)
		get_ics_info(win, wshape, group, max_sfb, lpflag, prstflag
		);
    memcpy(info, winmap[*win], sizeof(Info));

    /* calculate total number of sfb for this grouping */
    if (*max_sfb == 0) {
		tot_sfb = 0;
    }
    else {
		i=0;
		tot_sfb = info->sfb_per_sbk[0];
		while (group[i++] < info->nsbk) {
			tot_sfb += info->sfb_per_sbk[0];
		}
    }

    /* 
	* section data
	*/
    nsect = huffcb(sect, info->sectbits, tot_sfb, info->sfb_per_sbk[0], *max_sfb);
    if(nsect==0 && *max_sfb>0)
		return 0;

		/* generate "linear" description from section info
		* stored as codebook for each scalefactor band and group
	*/
    if (nsect) {
		bot = 0;
		for (i=0; i<nsect; i++) {
			cb = sect[2*i];
			top = sect[2*i + 1];
			for (; bot<top; bot++)
				*cb_map++ = cb;
			bot = top;
		}
    }  else {
		for (i=0; i<MAXBANDS; i++)
			cb_map[i] = 0;
    }

    /* calculate band offsets
	* (because of grouping and interleaving this cannot be
	* a constant: store it in info.bk_sfb_top)
	*/
    calc_gsfb_table(info, group);

    /*
	* scale factor data
	*/
    if(!hufffac(info, group, nsect, sect, *global_gain, factors))
		return 0;

	/*
	* NEC noiseless coding
	*/
    if ((nec_info.pulse_data_present = getbits(LEN_PULSE_PRES))) {
		if (info->islong) {
			get_nec_nc(&nec_info);
		}
		else {
			CommonExit(1,"Pulse data not allowed for short blocks");
		}
    }

    /*
	* tns data
	*/
    if (getbits(LEN_TNS_PRES)) {
		get_tns(info, tns);
    }
    else {
		clr_tns(info, tns);
    }

    /*
	* Sony gain control
    */
    if (getbits(LEN_GAIN_PRES)) {
		CommonExit(1, "Gain control not implemented");
    }

    return huffspec(info, nsect, sect, factors, coef);
}

/*
 * read the codebook and boundaries
 */
int
huffcb(byte *sect, int *sectbits, int tot_sfb, int sfb_per_sbk, byte max_sfb)
{
    int nsect, n, base, bits, len;

    bits = sectbits[0];
    len = (1 << bits) - 1;
    nsect = 0;
    for(base = 0; base < tot_sfb && nsect < tot_sfb; ){
	*sect++ = getbits(LEN_CB);

	n = getbits(bits);
	while(n == len && base < tot_sfb){
	    base += len;
	    n = getbits(bits);
	}
	base += n;
	*sect++ = base;
	nsect++;

	/* insert a zero section for regions above max_sfb for each group */
	if ((sect[-1] % sfb_per_sbk) == max_sfb) {
	    base += (sfb_per_sbk - max_sfb);
	    *sect++ = 0;
	    *sect++ = base;
	    nsect++;
	}
    }

    if(base != tot_sfb || nsect > tot_sfb)
	return 0;
    return nsect;
}

/* 
 * get scale factors
 */
int
hufffac(Info *info, byte *group, int nsect, byte *sect,
		short global_gain, short *factors)
{
    Hcb *hcb;
    Huffman *hcw;
    int i, b, bb, t, n, sfb, top, fac, is_pos;
    int factor_transmitted[MAXBANDS], *fac_trans;

    /* clear array for the case of max_sfb == 0 */
//	memset(factor_transmitted, 0, MAXBANDS*sizeof(*factor_transmitted));
//	memset(factors, 0, MAXBANDS*sizeof(*factors));

    sfb = 0;
    fac_trans = factor_transmitted;
    for(i = 0; i < nsect; i++){
		top = sect[1];		/* top of section in sfb */
		t = sect[0];		/* codebook for this section */
		sect += 2;
		for(; sfb < top; sfb++) {
			fac_trans[sfb] = t;
		}
    }

    /* scale factors are dpcm relative to global gain
	* intensity positions are dpcm relative to zero
	*/
    fac = global_gain;
    is_pos = 0;

    /* get scale factors */
    hcb = &book[BOOKSCL];
    hcw = hcb->hcw;
    bb = 0;
    for(b = 0; b < info->nsbk; ){
		n = info->sfb_per_sbk[b];
		b = *group++;
		for(i = 0; i < n; i++){
			switch (fac_trans[i]) {
			case ZERO_HCB:	    /* zero book */
				break;
			default:		    /* spectral books */
				/* decode scale factor */
				t = decode_huff_cw(hcw);
				fac += t - MIDFAC;    /* 1.5 dB */
				if(fac >= 2*maxfac || fac < 0)
					return 0;
				factors[i] = fac;
				break;
			case BOOKSCL:	    /* invalid books */
				return 0;
			case INTENSITY_HCB:	    /* intensity books */
			case INTENSITY_HCB2:
				/* decode intensity position */
				t = decode_huff_cw(hcw);
				is_pos += t - MIDFAC;
				factors[i] = is_pos;
				break;
			}
		}

		/* expand short block grouping */
		if (!(info->islong)) {
			for(bb++; bb < b; bb++) {
				for (i=0; i<n; i++) {
					factors[i+n] = factors[i];
				}
				factors += n;
			}
		}
		fac_trans += n;
		factors += n;
    }
    return 1;
}

/* rm2 inverse quantization
 * escape books need ftn call
 * other books done via macro
 */
#define iquant( q ) ( q >= 0 ) ? \
	(Float)iq_exp_tbl[ q ] : (Float)(-iq_exp_tbl[ - q ])

Float
esc_iquant(int q)
{
    if (q > 0) {
		if (q < MAX_IQ_TBL) {
			return((Float)iq_exp_tbl[q]);
		}
		else {
			return(pow(q, 4./3.));
		}
    }
    else {
		q = -q;
		if (q < MAX_IQ_TBL) {
			return((Float)(-iq_exp_tbl[q]));
		}
		else {
			return(-pow(q, 4./3.));
		}
    }
}



int
huffspec(Info *info, int nsect, byte *sect, short *factors, Float *coef)
{
    Hcb *hcb;
    Huffman *hcw;
    int i, j, k, table, step, temp, stop, bottom, top;
    short *bands, *bandp;
    int quant[LN2], *qp;	    /* probably could be short */

    int kstart;
    int tmp_spec[LN2];

//	memset(quant, 0, LN2*sizeof(*quant));
	for (i = 0; i < LN2; i++)
		quant[i] = 0;

    bands = info->bk_sfb_top;
    bottom = 0;
    k = 0;
    bandp = bands;
    for(i = nsect; i; i--) {
		table = sect[0];
		top = sect[1];
		sect += 2;
		if( (table == 0) || (table == INTENSITY_HCB) || (table == INTENSITY_HCB2) ) {
			bandp = bands+top;
			k = bandp[-1];
			bottom = top;
			continue;
		}
		if(table < BY4BOOKS+1) {
			step = 4;
		}
		else {
			step = 2;
		}	hcb = &book[table];
		hcw = hcb->hcw;
		qp = quant+k;
		kstart=k;
		for(j=bottom; j<top; j++) {
			stop = *bandp++;
			while(k < stop) {
				temp = decode_huff_cw(hcw);
				unpack_idx(qp, temp, hcb);

				if (!hcb->signed_cb)
					get_sign_bits(qp, step);
				if(table == ESCBOOK){
					qp[0] = getescape(qp[0]);
					qp[1] = getescape(qp[1]);
				}
				qp += step;
				k += step;
			}
		}
		bottom = top;
    }

    /* NEC noisless coding reconstruction */
    if ( (info->islong) && (nec_info.pulse_data_present) )
		nec_nc(quant, &nec_info);

    if (!info->islong) {
		deinterleave (quant,tmp_spec,
			info->num_groups,   
			info->group_len,
			info->sfb_per_sbk,
			info->sfb_width_128);
		memcpy(quant,tmp_spec,sizeof(tmp_spec));
    }

    /* inverse quantization */
    for (i=0; i<info->bins_per_bk; i++) {
		coef[i] = esc_iquant(quant[i]);
    }

    /* rescaling */
    {
		int sbk, nsbk, sfb, nsfb, fac, top;
		Float *fp, scale;

		i = 0;
		fp = coef;
		nsbk = info->nsbk;
		for (sbk=0; sbk<nsbk; sbk++) {
			nsfb = info->sfb_per_sbk[sbk];
			k=0;
			for (sfb=0; sfb<nsfb; sfb++) {
				top = info->sbk_sfb_top[sbk][sfb];
				fac = factors[i++]-SF_OFFSET;

				if (fac >= 0 && fac < TEXP) {
					scale = exptable[fac];
				}
				else {
					if (fac == -SF_OFFSET) {
						scale = 0;
					}
					else {
						scale = pow( 2.0,  0.25*fac );
					}
				}
				for ( ; k<top; k++) {
					*fp++ *= scale;
				}
			}
		}
    }
    return 1;
}

int byte_align(void)
{
    int i=0;

    if(nbits <= 16){
		cword = (cword<<16) | getshort();
		nbits += 16;
    }

    while (nbits & ((1<<3)-1)) {
		nbits -= 1;
		i += 1;
    }
    return(i);
}

long getbits(int n)
{
    if(nbits <= 16){
		cword = (cword<<16) | getshort();
		nbits += 16;
    }

    nbits -= n;
    return (cword>>nbits) & ((1<<n)-1);
}

int getescape(int q)
{
    int i, off, neg;

    if(q < 0){
		if(q != -16)
			return q;
		neg = 1;
    } else{
		if(q != +16)
			return q;
		neg = 0;
    }

    for(i=4;; i++){
		if(getbits(1) == 0)
			break;
    }

    if(i > 16){
		off = getbits(i-16) << 16;
		off |= getbits(16);
    } else
		off = getbits(i);

    i = off + (1<<i);
    if(neg)
		i = -i;
    return i;
}

⌨️ 快捷键说明

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