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

📄 mpeglayer3.cpp

📁 JPEG-MPEG編解碼技術書集的代碼
💻 CPP
📖 第 1 页 / 共 4 页
字号:

void MPEGaudio::layer3getscalefactors_2(int ch)
{
  static int sfbblockindex[6][3][4]=
  {
    {{ 6, 5, 5, 5},{ 9, 9, 9, 9},{ 6, 9, 9, 9}},
    {{ 6, 5, 7, 3},{ 9, 9,12, 6},{ 6, 9,12, 6}},
    {{11,10, 0, 0},{18,18, 0, 0},{15,18, 0, 0}},
    {{ 7, 7, 7, 0},{12,12,12, 0},{ 6,15,12, 0}},
    {{ 6, 6, 6, 3},{12, 9, 9, 6},{ 6,12, 9, 6}},
    {{ 8, 8, 5, 0},{15,12, 9, 0},{ 6,18, 9, 0}}
  };

  int sb[54];
  layer3grinfo *gi=&(sideinfo.ch[ch].gr[0]);
  register layer3scalefactor *sf=(&scalefactors[ch]);

  {
    int blocktypenumber,sc;
    int blocknumber;
    int slen[4];

    if(gi->block_type==2)blocktypenumber=1+gi->mixed_block_flag;
    else blocktypenumber=0;

    sc=gi->scalefac_compress;
    if(!((extendedmode==1 || extendedmode==3) && (ch==1)))
    {
      if(sc<400)
      {
	slen[0]=(sc>>4)/5;
	slen[1]=(sc>>4)%5;
	slen[2]=(sc%16)>>2;
	slen[3]=(sc%4);
	gi->preflag=0;
	blocknumber=0;
      }
      else if(sc<500)
      {
	sc-=400;
	slen[0]=(sc>>2)/5;
	slen[1]=(sc>>2)%5;
	slen[2]=sc%4;
	slen[3]=0;
	gi->preflag=0;
	blocknumber=1;
      }
      else // if(sc<512)
      {
	sc-=500;
	slen[0]=sc/3;
	slen[1]=sc%3;
	slen[2]=0;
	slen[3]=0;
	gi->preflag=1;
	blocknumber=2;
      }
    }
    else
    {
      sc>>=1;
      if(sc<180)
      {
	slen[0]=sc/36;
	slen[1]=(sc%36)/6;
	slen[2]=(sc%36)%6;
	slen[3]=0;
	gi->preflag=0;
	blocknumber=3;
      }
      else if(sc<244)
      {
	sc-=180;
	slen[0]=(sc%64)>>4;
	slen[1]=(sc%16)>>2;
	slen[2]=sc%4;
	slen[3]=0;
	gi->preflag=0;
	blocknumber=4;
      }
      else // if(sc<255)
      {
	sc-=244;
	slen[0]=sc/3;
	slen[1]=sc%3;
	slen[2]=
	slen[3]=0;
	gi->preflag=0;
	blocknumber=5;
      }
    }

    {
      int i,j,k,*si;

      si=sfbblockindex[blocknumber][blocktypenumber];
      for(i=0;i<45;i++)sb[i]=0;

      for(k=i=0;i<4;i++)
	for(j=0;j<si[i];j++,k++)
	  if(slen[i]==0)sb[k]=0;
	  else sb[k]=wgetbits(slen[i]);
    }
  }


  {
    int sfb,window;
    int k=0;

    if(gi->window_switching_flag && (gi->block_type==2))
    {
      if(gi->mixed_block_flag)
      {
	for(sfb=0;sfb<8;sfb++)sf->l[sfb]=sb[k++];
	sfb=3;
      }
      else sfb=0;

      for(;sfb<12;sfb++)
	for(window=0;window<3;window++)
	  sf->s[window][sfb]=sb[k++];

      sf->s[0][12]=sf->s[1][12]=sf->s[2][12]=0;
    }
    else
    {
      for(sfb=0;sfb<21;sfb++)
	sf->l[sfb]=sb[k++];
      sf->l[21]=sf->l[22]=0;
    }
  }
}


typedef unsigned int HUFFBITS;
#define MXOFF   250

/* do the huffman-decoding 						*/
/* note! for counta,countb -the 4 bit value is returned in y, discard x */
// Huffman decoder for tablename<32
void MPEGaudio::huffmandecoder_1(const HUFFMANCODETABLE *h,int *x,int *y)
{  
  HUFFBITS level=(1<<(sizeof(HUFFBITS)*8-1));
  int point=0;

  /* Lookup in Huffman table. */
  for(;;)
  {
    if(h->val[point][0]==0)
    {   /*end of tree*/
      int xx,yy;

      xx=h->val[point][1]>>4;
      yy=h->val[point][1]&0xf;

      if(h->linbits)
      {
	if((h->xlen)==(unsigned)xx)xx+=wgetbits(h->linbits);
	if(xx)if(wgetbit())xx=-xx;
	if((h->ylen)==(unsigned)yy)yy+=wgetbits(h->linbits);
	if(yy)if(wgetbit())yy=-yy;
      }
      else
      {
	if(xx)if(wgetbit())xx=-xx;
	if(yy)if(wgetbit())yy=-yy;
      }
      *x=xx;*y=yy;
      break;
    } 

    point+=h->val[point][wgetbit()];
    
    level>>=1;
    if(!(level || ((unsigned)point<ht->treelen)))
    {
      register int xx,yy;

      xx=(h->xlen<<1);// set x and y to a medium value as a simple concealment
      yy=(h->ylen<<1);

      // h->xlen and h->ylen can't be 1 under tablename 32
      //      if(xx)
	if(wgetbit())xx=-xx;
      //      if(yy)
	if(wgetbit())yy=-yy;

      *x=xx;*y=yy;
      break;
    }
  }
}

// Huffman decoder tablenumber>=32
void MPEGaudio::huffmandecoder_2(const HUFFMANCODETABLE *h,
				       int *x,int *y,int *v,int *w)
{  
  HUFFBITS level=(1<<(sizeof(HUFFBITS)*8-1));
  int point=0;

  /* Lookup in Huffman table. */
  for(;;)
  {
    if(h->val[point][0]==0)
    {   /*end of tree*/
      register int t=h->val[point][1];

      if(t&8)*v=1-(wgetbit()<<1); else *v=0;
      if(t&4)*w=1-(wgetbit()<<1); else *w=0;
      if(t&2)*x=1-(wgetbit()<<1); else *x=0;
      if(t&1)*y=1-(wgetbit()<<1); else *y=0;
      break;
    } 
    point+=h->val[point][wgetbit()];
    level>>=1;
    if(!(level || ((unsigned)point<ht->treelen)))
    {
      *v=1-(wgetbit()<<1);
      *w=1-(wgetbit()<<1);
      *x=1-(wgetbit()<<1);
      *y=1-(wgetbit()<<1);
      break;
    }
  }
}

typedef struct
{
  int l[23];
  int s[14];
}SFBANDINDEX;

static SFBANDINDEX sfBandIndextable[2][3]=
{
  // MPEG 1
  {{{0,4,8,12,16,20,24,30,36,44,52,62,74,90,110,134,162,196,238,288,342,418,576},
    {0,4,8,12,16,22,30,40,52,66,84,106,136,192}},
   {{0,4,8,12,16,20,24,30,36,42,50,60,72,88,106,128,156,190,230,276,330,384,576},
    {0,4,8,12,16,22,28,38,50,64,80,100,126,192}},
   {{0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576},
    {0,4,8,12,16,22,30,42,58,78,104,138,180,192}}},

  // MPEG 2
  {{{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
    {0,4,8,12,18,24,32,42,56,74,100,132,174,192}},
   {{0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576},
    {0,4,8,12,18,26,36,48,62,80,104,136,180,192}},
   {{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
    {0,4,8,12,18,26,36,48,62,80,104,134,174,192}}}
};


void MPEGaudio::layer3huffmandecode(int ch,int gr,int out[SBLIMIT][SSLIMIT])
{
  layer3grinfo *gi=&(sideinfo.ch[ch].gr[gr]);
  int part2_3_end=layer3part2start+(gi->part2_3_length);
  int region1Start,region2Start;
  int i,e=gi->big_values<<1;

  /* Find region boundary for short block case. */
  if(gi->generalflag)
  {
    /* Region2. */
    region1Start=36; /* sfb[9/3]*3=36 */
    region2Start=576;/* No Region2 for short block case. */
  }
  else
  {          /* Find region boundary for long block case. */
    region1Start=sfBandIndextable[version][frequency].l[gi->region0_count+1];
    region2Start=sfBandIndextable[version][frequency].l[gi->region0_count+
						        gi->region1_count+2];
  }

  /* Read bigvalues area. */
  for(i=0;i<e;)
  {
    const HUFFMANCODETABLE *h;
    register int end;
      
    if     (i<region1Start)
    {
      h=&ht[gi->table_select[0]];
      if(region1Start>e)end=e; else end=region1Start;
    }
    else if(i<region2Start)
    {
      h=&ht[gi->table_select[1]];
      if(region2Start>e)end=e; else end=region2Start;
    }
    else
    {
      h=&ht[gi->table_select[2]];
      end=e;
    }

    if(h->treelen)
      while(i<end)
      {
	huffmandecoder_1(h,&out[0][i],&out[0][i+1]);
	i+=2;
      }
    else
      for(;i<end;i+=2)
	out[0][i]  =
	out[0][i+1]=0;
  }

  /* Read count1 area. */
  const HUFFMANCODETABLE *h=&ht[gi->count1table_select+32];
  while(bitwindow.gettotalbit()<part2_3_end)
  {
    huffmandecoder_2(h,&out[0][i+2],&out[0][i+3],
		     &out[0][i  ],&out[0][i+1]);
    i+=4;

    if(i>=ARRAYSIZE)
    {
      bitwindow.rewind(bitwindow.gettotalbit()-part2_3_end);
      return;
    }
  }
  
  for(;i<ARRAYSIZE;i++)out[0][i]=0;
  bitwindow.rewind(bitwindow.gettotalbit()-part2_3_end);
}


static int pretab[22]={0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0};

REAL MPEGaudio::layer3twopow2(int scale,int preflag,
				     int pretab_offset,int l)
{
  int index=l;
  
  if(preflag)index+=pretab_offset;
  return(two_to_negative_half_pow[index<<scale]);
}

REAL MPEGaudio::layer3twopow2_1(int a,int b,int c)
{
  return POW2_1[a][b][c];
}

void MPEGaudio::layer3dequantizesample(int ch,int gr,
				       int   in[SBLIMIT][SSLIMIT],
				       REAL out[SBLIMIT][SSLIMIT])
{
  layer3grinfo *gi=&(sideinfo.ch[ch].gr[gr]);
  SFBANDINDEX *sfBandIndex=&(sfBandIndextable[version][frequency]);
  REAL globalgain=POW2[gi->global_gain];
  REAL *TO_FOUR_THIRDS=TO_FOUR_THIRDSTABLE+FOURTHIRDSTABLENUMBER;

  /* choose correct scalefactor band per block type, initalize boundary */
  /* and apply formula per block type */
  
  if(!gi->generalflag)
  {                                          /* LONG blocks: 0,1,3 */
    int next_cb_boundary;
    int cb=-1,index=0;
    REAL factor;

    do
    {
      next_cb_boundary=sfBandIndex->l[(++cb)+1];
      factor=globalgain*
	     layer3twopow2(gi->scalefac_scale,gi->preflag,
			   pretab[cb],scalefactors[ch].l[cb]);
      for(;index<next_cb_boundary;)
      {
	out[0][index]=factor*TO_FOUR_THIRDS[in[0][index]];index++;
	out[0][index]=factor*TO_FOUR_THIRDS[in[0][index]];index++;
      }
    }while(index<ARRAYSIZE);
  }
  else if(!gi->mixed_block_flag)
  {
    int cb=0,index=0;
    int cb_width;

    do
    {
      cb_width=(sfBandIndex->s[cb+1]-sfBandIndex->s[cb])>>1;

      for(register int k=0;k<3;k++)
      {
	register REAL factor;
	register int count=cb_width;

	factor=globalgain*
	       layer3twopow2_1(gi->subblock_gain[k],gi->scalefac_scale,
			       scalefactors[ch].s[k][cb]);
	do{
	  out[0][index]=factor*TO_FOUR_THIRDS[in[0][index]];index++;
	  out[0][index]=factor*TO_FOUR_THIRDS[in[0][index]];index++;
	}while(--count);
      }
      cb++;
    }while(index<ARRAYSIZE);
  }
  else
  {
    int cb_begin=0,cb_width=0;
    int cb=0;
    int next_cb_boundary=sfBandIndex->l[1]; /* LONG blocks: 0,1,3 */
    int index;

    /* Compute overall (global) scaling. */
    {
      for(int sb=0;sb<SBLIMIT;sb++)
      {
	int *i=in[sb];
	REAL *o=out[sb];

	o[ 0]=globalgain*TO_FOUR_THIRDS[i[ 0]];o[ 1]=globalgain*TO_FOUR_THIRDS[i[ 1]];
	o[ 2]=globalgain*TO_FOUR_THIRDS[i[ 2]];o[ 3]=globalgain*TO_FOUR_THIRDS[i[ 3]];
	o[ 4]=globalgain*TO_FOUR_THIRDS[i[ 4]];o[ 5]=globalgain*TO_FOUR_THIRDS[i[ 5]];
	o[ 6]=globalgain*TO_FOUR_THIRDS[i[ 6]];o[ 7]=globalgain*TO_FOUR_THIRDS[i[ 7]];
	o[ 8]=globalgain*TO_FOUR_THIRDS[i[ 8]];o[ 9]=globalgain*TO_FOUR_THIRDS[i[ 9]];
	o[10]=globalgain*TO_FOUR_THIRDS[i[10]];o[11]=globalgain*TO_FOUR_THIRDS[i[11]];
	o[12]=globalgain*TO_FOUR_THIRDS[i[12]];o[13]=globalgain*TO_FOUR_THIRDS[i[13]];
	o[14]=globalgain*TO_FOUR_THIRDS[i[14]];o[15]=globalgain*TO_FOUR_THIRDS[i[15]];
	o[16]=globalgain*TO_FOUR_THIRDS[i[16]];o[17]=globalgain*TO_FOUR_THIRDS[i[17]];
      }
    }

    for(index=0;index<SSLIMIT*2;index++)
    {
      if(index==next_cb_boundary)
      {
	if(index==sfBandIndex->l[8])
	{
	  next_cb_boundary=sfBandIndex->s[4];
	  next_cb_boundary=MUL3(next_cb_boundary);
	  cb=3;
	  cb_width=sfBandIndex->s[4]-sfBandIndex->s[3];
	  cb_begin=sfBandIndex->s[3];
	  cb_begin=MUL3(cb_begin);
	}
	else if(index<sfBandIndex->l[8])
	  next_cb_boundary=sfBandIndex->l[(++cb)+1];
	else 
	{
	  next_cb_boundary=sfBandIndex->s[(++cb)+1];
	  next_cb_boundary=MUL3(next_cb_boundary);
	  cb_begin=sfBandIndex->s[cb];
	  cb_width=sfBandIndex->s[cb+1]-cb_begin;
	  cb_begin=MUL3(cb_begin);
	}
      }
      /* LONG block types 0,1,3 & 1st 2 subbands of switched blocks */
      out[0][index]*=layer3twopow2(gi->scalefac_scale,gi->preflag,
				   pretab[cb],scalefactors[ch].l[cb]);
    }

    for(;index<ARRAYSIZE;index++)
    { 
      if(index==next_cb_boundary)
      {
	if(index==sfBandIndex->l[8])
	{
	  next_cb_boundary=sfBandIndex->s[4];
	  next_cb_boundary=MUL3(next_cb_boundary);
	  cb=3;
	  cb_width=sfBandIndex->s[4]-sfBandIndex->s[3];
	  cb_begin=sfBandIndex->s[3];
	  cb_begin=(cb_begin<<2)-cb_begin;
	}
	else if(index<sfBandIndex->l[8])
	  next_cb_boundary=sfBandIndex->l[(++cb)+1];
	else 
	{
	  next_cb_boundary=sfBandIndex->s[(++cb)+1];
	  next_cb_boundary=MUL3(next_cb_boundary);
	  cb_begin=sfBandIndex->s[cb];

⌨️ 快捷键说明

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