www.pudn.com > avs-m3.rar > image.c


 
/*! 
 ************************************************************************************* 
 * \file  
 *    image.c 
 * \brief 
 *    Decoding a slice 
 * \notes: 
 *    upadated @ June 14th 2005 according to the FCD  
 ************************************************************************************* 
 */ 
#include  
#include  
#include  
//#include  
 
#include "header.h" 
#include "global.h" 
#include "vlc.h" 
#include "memalloc.h" 
extern FILE *bits; 
 
 
 
 
 
extern unsigned int seq_parameter_set_id; 
extern unsigned int cpb_dpb_cnt_minus1; 
extern unsigned int *cpb_underflow_allowable_flag; 
extern unsigned int *bit_rate_value_minus1_lsb; 
extern unsigned int *bit_rate_value_minus1_msb; 
extern unsigned int *cpb_size_value_minus1_lsb; 
extern unsigned int *cpb_size_value_minus1_msb; 
extern unsigned int *dpb_size_value_minus1_lsb; 
extern unsigned int *dpb_size_value_minus1_msb; 
extern unsigned int *initial_cpb_removal_delay_lsb; 
extern unsigned int *initial_cpb_removal_delay_msb; 
extern unsigned int *initial_cpb_removal_delay; 
extern unsigned int *initial_dpb_output_delay_lsb; 
extern unsigned int *initial_dpb_output_delay_msb; 
extern unsigned int *initial_dpb_output_delay; 
 
 
extern unsigned int *Bit_Buffer; 
 
extern unsigned int *ROT; 
extern struct DecodedPictureBuffer dpb; 
extern struct FrameBuffer outframe; 
extern struct FrameBuffer decframe; 
 
extern unsigned int outputtimer; 
extern int pre_picture_distance; 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#ifdef _HRD_ 
 #include "HRD.h" 
#endif // _HRD_ 
extern void UpdateiREG(); 
/*! 
************************************************************************ 
* \brief 
*    decodes one I- or P-frame 
************************************************************************ 
*/ 
int decode_one_picture(struct snr_par *snr) 
{ 
  time_t ltime1;                  // for time measurement 
  time_t ltime2; 
#ifdef _HRD_ 
  int j, i; 
  int framenum=0; 
#endif // _HRD_ 
/* 
#ifdef WIN32 
  struct _timeb tstruct1; 
  struct _timeb tstruct2; 
#else 
  struct timeb tstruct1; 
  struct timeb tstruct2; 
#endif 
*/ 
  int tmp_time;                   // time used by decoding the last frame 
 /* 
#ifdef WIN32 
  _ftime (&tstruct1);             // start time ms 
#else 
  ftime (&tstruct1);              // start time ms 
#endif 
  time( <ime1 );                // start time s 
 */ 
  init_frame(); 
 
  //cbzhu 0412 
#ifdef _ISOLATED_REGION_ 
  if(iREGenable) 
  { 
		UpdateiREG(); 
  } 
#endif //_ISOLATED_REGION_ 
 
  //!< optional mode - simulate  a lower-end decoder that can only decode video with low frame rate 
  //!< if you just want to decode the reference frames, plz active following skip_img_flag! 
  //!< zhan ma -- Sept 1st 2005 
  //if (pgImage->skip_img_flag) 
  //  return (SOP); 
 
  decode_picture_data();  // decoding process 
 
  DeblockFrame(imgY , imgUV); 
 
#ifdef _HRD_ 
  { 
    
  for (j = 0; j < pgImage->height; j++) 
    for (i = 0; i < pgImage->width; i++) 
      decframe.imgY[j][i] = imgY[j][i]; 
   
  for (j = 0; j < pgImage->height / 2; j++) 
    for (i = 0; i < pgImage->width / 2; i++) 
    { 
      decframe.imgUV[0][j][i] = imgUV[0][j][i]; 
      decframe.imgUV[1][j][i] = imgUV[1][j][i]; 
    } 
 
  decframe.frmnum = pgImage->number; 
  decframe.outputted = 0; 
     
  if (pgImage->type == I_IMG) 
    decframe.used_for_ref = 1; 
  else 
  { 
    if (!pgImage->pic_ref_flag) 
      decframe.used_for_ref = 1; 
    else 
      decframe.used_for_ref = 0; 
  } 
 
  if (pgImage->number == 0) 
  { 
    decframe.rotvalue = 0; 
    ROT[0] = 0; 
  } 
  else 
  { 
    if (pgImage->type == I_IMG) 
      ROT[pgImage->number] = ROT[pgImage->number - 1] + (pgImage->picture_distance_gap_minus1 + 1) * sps->delta_time_picture_distance_1; 
    else 
    {  
      ROT[pgImage->number] = ROT[pgImage->number - 1] + ((pgImage->picture_distance - pre_picture_distance) % 256) * sps->delta_time_picture_distance_1; 
      // added by yiwang, 2005.7.2 
		  framenum = pgImage->picture_distance - pre_picture_distance; 
    } 
 
    decframe.rotvalue = ROT[pgImage->number]; 
    pre_picture_distance = pgImage->picture_distance; 
  } 
 
 
  outputtimer += pgImage->delta_time_picture_distance_1 * framenum; 
  Store_OneFrame_Into_DPB(&decframe); 
  UpdateRefFrameBufFlag(); 
  } 
#endif // _HRD_ 
 
 
#if TRACE 
   trace_frame(p_trace,pgImage->width,pgImage->height,imgY,imgUV); 
#endif 
 
/* 
 
#ifdef WIN32 
  _ftime (&tstruct2);   //!< end time ms 
#else 
  ftime (&tstruct2);    //!< end time ms 
#endif 
  */ 
	 
  if (p_ref) 
		find_snr(snr,p_ref);      //!< if ref sequence exist 
 
  time( <ime2 );                                // end time sec 
  //tmp_time=(ltime2*1000+tstruct2.millitm) - (ltime1*1000+tstruct1.millitm); 
  tot_time=tot_time + tmp_time; 
 
  report_picture(tmp_time); 
   
  write_frame(p_out); 
   
  Update_Picture_Buffers(); 
   
  pgImage->number++; 
 
  return (SOP); 
} 
/*! 
************************************************************************ 
* \brief 
*     
************************************************************************ 
*/ 
void report_picture(int time_pic) 
{ 
 
#ifndef _PSNR_YUV_ 
  if(pgImage->type == I_IMG) // I picture 
	// 
      fprintf(stdout,"%3d(I)   %5d %7.4f %7.4f %7.4f %5d\n", 
      pgImage->number, pgImage->qp,snr->snr_y,snr->snr_u,snr->snr_v,time_pic); 
	// 
  else if(pgImage->type == P_IMG) // P pictures 
      fprintf(stdout,"%3d(P)   %5d %7.4f %7.4f %7.4f %5d\n", 
      pgImage->number,  pgImage->qp,snr->snr_y,snr->snr_u,snr->snr_v,time_pic); 
#else 
  if(pgImage->type == I_IMG) // I picture 
	  // 
      fprintf(stdout,"%3d(I)   %5d %7.4f %7.4f %7.4f %7.4f %5d\n", 
      pgImage->number, pgImage->qp,snr->snr_y,snr->snr_u,snr->snr_v,snr->snr_yuv,time_pic); 
	  // 
  else if(pgImage->type == P_IMG) // P pictures 
	  // 
      fprintf(stdout,"%3d(P)   %5d %7.4f %7.4f %7.4f %7.4f %5d\n", 
      pgImage->number,  pgImage->qp,snr->snr_y,snr->snr_u,snr->snr_v,snr->snr_yuv, time_pic); 
	  // 
 
#endif // _PSNR_YUV_ 
  
  fflush(stdout); 
} 
 
/*! 
************************************************************************ 
* \brief 
*    Find PSNR for all three components.Compare decoded frame with 
*    the original sequence. Read input->jumpd frames to reflect frame skipping. 
************************************************************************ 
*/ 
void find_snr(struct snr_par *snr,   //!< pointer to snr parameters 
              FILE *p_ref)           //!< filestream to reference YUV file 
{ 
  int i,j; 
  int diff_y,diff_u,diff_v; 
  int uv; 
  int  status; 
#ifdef _PSNR_YUV_ 
  float tmpy, tmpu, tmpv; 
#endif // _PSNR_YUV_ 
   
	if(!p_ref) 
	{ 
		printf("no ref file!\n"); 
		snr->snr_u = -1; 
		snr->snr_u1 = -1; 
		snr->snr_ua = -1; 
		snr->snr_v  = -1; 
		snr->snr_v1 = -1; 
		snr->snr_va = -1; 
		snr->snr_y = -1; 
		snr->snr_y1 = -1; 
		snr->snr_ya = -1; 
		return ; 
	} 
 
  rewind(p_ref); 
  status = fseek (p_ref, pgImage->number*pgImage->height*pgImage->width*3/2, 0); 
 
  for (j=0; j < pgImage->height; j++) 
    for (i=0; i < pgImage->width; i++) 
    { 
      imgY_ref[j][i]=fgetc(p_ref); 
    } 
     
  for (uv=0; uv < 2; uv++) 
    for (j=0; j < pgImage->height_cr ; j++) 
      for (i=0; i < pgImage->width_cr; i++) 
        imgUV_ref[uv][j][i]=fgetc(p_ref); 
 
  pgImage->quad[0]=0; 
  diff_y=0; 
  for (j=0; j < pgImage->height; ++j) 
  { 
    for (i=0; i < pgImage->width; ++i) 
    { 
      diff_y += pgImage->quad[abs(imgY[j][i]-imgY_ref[j][i])]; 
    } 
  } 
 
  // Chroma 
  diff_u=0; 
  diff_v=0; 
 
  for (j=0; j < pgImage->height_cr; ++j) 
  { 
    for (i=0; i < pgImage->width_cr; ++i) 
    { 
      diff_u += pgImage->quad[abs(imgUV_ref[0][j][i]-imgUV[0][j][i])]; 
      diff_v += pgImage->quad[abs(imgUV_ref[1][j][i]-imgUV[1][j][i])]; 
	  /* 
	  if(pgImage->quad[abs(imgUV_ref[1][j][i]-imgUV[1][j][i])]!=0)//²âÊÔ 
	  { 
		  printf("x=%d,y=%d\n",i,j); 
		  getch(); 
	  } 
	   */     
    } 
  } 
 
  // Collecting SNR statistics 
  if (diff_y != 0) 
    snr->snr_y=(float)(10*log10(65025*(float)(pgImage->width)*(pgImage->height)/(float)diff_y));        // luma snr for current frame 
  if (diff_u != 0) 
    snr->snr_u=(float)(10*log10(65025*(float)(pgImage->width)*(pgImage->height)/(float)(4*diff_u)));    //  chroma snr for current frame 
  if (diff_v != 0) 
    snr->snr_v=(float)(10*log10(65025*(float)(pgImage->width)*(pgImage->height)/(float)(4*diff_v)));    //  chroma snr for current frame 
#ifdef _PSNR_YUV_ 
  tmpy = (float)(4.0 / pow(10, snr->snr_y / 10)); 
  tmpu = (float)(1.0 / pow(10, snr->snr_u / 10)); 
  tmpv = (float)(1.0 / pow(10, snr->snr_v / 10)); 
  snr->snr_yuv = (float)(10 * log10(6 / ( tmpy + tmpu + tmpv ) ));  
#endif // _PSNR_YUV_ 
   
  if (pgImage->number == 0) // first 
  { 
    snr->snr_y1=(float)(10*log10(65025*(float)(pgImage->width)*(pgImage->height)/(float)diff_y));       // keep luma snr for first frame 
    snr->snr_u1=(float)(10*log10(65025*(float)(pgImage->width)*(pgImage->height)/(float)(4*diff_u)));   // keep chroma snr for first frame 
    snr->snr_v1=(float)(10*log10(65025*(float)(pgImage->width)*(pgImage->height)/(float)(4*diff_v)));   // keep chroma snr for first frame 
    snr->snr_ya=snr->snr_y1; 
    snr->snr_ua=snr->snr_u1; 
    snr->snr_va=snr->snr_v1; 
 
    if (diff_y == 0)    
      snr->snr_ya=50; // need to assign a reasonable large number so avg snr of entire sequece isn't infinite 
    if (diff_u == 0) 
      snr->snr_ua=50; 
    if (diff_v == 0) 
      snr->snr_va=50; 
#ifdef _PSNR_YUV_ 
    if ( diff_y == 0 && diff_u == 0 && diff_v == 0 ) 
    { 
        snr->snr_yuva = 50; 
    } 
    else 
    { 
        tmpy = (float)(4.0 / pow(10, snr->snr_y1 / 10)); 
        tmpu = (float)(1.0 / pow(10, snr->snr_u1 / 10)); 
        tmpv = (float)(1.0 / pow(10, snr->snr_v1 / 10)); 
        snr->snr_yuva = (float)(10 * log10(6 / ( tmpy + tmpu + tmpv ) )); 
    } 
#endif // _PSNR_YUV_ 
  } 
  else 
  { 
    snr->snr_ya=(float)(snr->snr_ya*(pgImage->number/*+Bframe_ctr*/)+snr->snr_y)/(pgImage->number/*+Bframe_ctr*/+1); // average snr chroma for all frames 
    snr->snr_ua=(float)(snr->snr_ua*(pgImage->number/*+Bframe_ctr*/)+snr->snr_u)/(pgImage->number/*+Bframe_ctr*/+1); // average snr luma for all frames 
    snr->snr_va=(float)(snr->snr_va*(pgImage->number/*+Bframe_ctr*/)+snr->snr_v)/(pgImage->number/*+Bframe_ctr*/+1); // average snr luma for all frames 
#ifdef _PSNR_YUV_ 
    snr->snr_yuva = (float)(snr->snr_yuva*(pgImage->number)+snr->snr_yuv)/(pgImage->number + 1); 
#endif // _PSNR_YUV_ 
  } 
} 
 
/*! 
************************************************************************ 
* \brief 
*    Interpolation of 1/4 subpixel 
************************************************************************ 
*/ 
void get_block(int x_pos, int y_pos, int block[4][4], unsigned char **ref_pic)//mark1 
{ 
 
    int dx, dy; 
    int x, y; 
    int i, j; 
    int maxold_x,maxold_y; 
    int result; 
    int tmp_res[26][26]; 
    int tmp_res_2[26][26]; 
		int tmp_res_3[26][26]; 
    static const int COEF_HALF_h[8] = {-1,4,-12,41,41,-12,4,-1}; 
		static const int COEF_HALF_v[8] = {0,0,-1,5,5,-1,0,0}; 
		const int iWeight1_2_h = 64; 
		const int iWeight1_2_v = 8; 
 
 
    static const int COEF_QUART[4] = {0, 1, 1, 0}; 
		const int iWeight1_4 = 2; 
		 
 
    //    A  a  1  b  B 
    //    c  d  e  f 
    //    2  h  3  i 
    //    j  k  l  m 
    //    C           D 
 
    dx = x_pos & 3; 
    dy = y_pos & 3; 
    x_pos = ( x_pos - dx ) / 4; 
    y_pos = ( y_pos - dy ) / 4; 
    maxold_x = pgImage->width  - 1; 
    maxold_y = pgImage->height - 1; 
     
    if (dx == 0 && dy == 0)  
    {  //fullpel position: A 
        for (j = 0; j < BLOCK_SIZE; j++) 
        { 
            for (i = 0; i < BLOCK_SIZE; i++) 
            { 
                block[i][j] = ref_pic[max(0, min(maxold_y, y_pos + j))][max(0, min(maxold_x, x_pos + i))]; 
            } 
        } 
    } 
    else  
    {  
        if ( (dx == 2) && (dy == 0)) 
        {//horizonal 1/2 position: 1 
            for (j = 0; j < BLOCK_SIZE; j++) 
            { 
                for (i = 0; i < BLOCK_SIZE; i++)  
                { 
                    for (result = 0, x = -3; x < 5; x++) 
                    { 
                        result += ref_pic[max(0, min(maxold_y, y_pos + j))] 
                                         [max(0, min(maxold_x, x_pos + i + x))]  
                                  * COEF_HALF_h[x + 3]; 
                    } 
                    //block[i][j] = max(0, min(255, (result + 1) / 2)); 
                    //block[i][j] = max(0, min(255, (result + iWeight1_2_h / 2) / iWeight1_2_h)); 
										block[i][j] = max(0, min(255, (result + iWeight1_2_h / 2)>>6)); 
                } 
            } 
        } 
        else if ( ( (dx == 1) || (dx == 3) ) && (dy == 0) ) 
        {//horizonal 1/4 position: a and b   
            for (j = 0; j < BLOCK_SIZE; j++)  
            { 
                for (i = -1; i < BLOCK_SIZE + 1; i++)  
                { 
                    for (result = 0, x = -3; x < 5; x++) 
                    { 
                        result += ref_pic[max(0, min(maxold_y, y_pos + j))] 
                                         [max(0, min(maxold_x, x_pos + i + x))]  
                                  * COEF_HALF_h[x + 3]; 
                    } 
                    //tmp_res[j][2 * (i + 1)] = max(0, min(255, (result + 4) / 8)); 
                    tmp_res[j][2 * (i + 1)] = max(0, min(255, (result + iWeight1_2_h / 2 ) >> 6)); 
                    tmp_res[j][2 * (i + 1) + 1] = ref_pic[max(0, min(maxold_y, y_pos + j))] 
                                                         [max(0, min(maxold_x, x_pos + i + 1))]; 
                } 
            } 
 
            for (j = 0; j < BLOCK_SIZE; j++)  
            { 
                for (i = 0; i < BLOCK_SIZE; i++)  
                { 
                    for (result = 0, x = -1; x < 3; x++) 
                    { 
 
                        if (dx == 1)//a 
                        { 
                            result += tmp_res[j][2 * i + x + 1] * COEF_QUART[x + 1]; 
                        } 
                        else//b 
                        { 
                            result += tmp_res[j][2 * i + x + 2] * COEF_QUART[3-(x + 1)]; 
                        } 
                    } 
                    //block[i][j] = max(0, min(255, (result + 8) / 16)); 
                    block[i][j] = max(0, min(255, (result + iWeight1_4 / 2 ) >>1)); 
                } 
            } 
        }//else if ( ( (dx == 1) || (dx == 3) ) && (dy == 0) ) 
        else if ( (dy == 2) && (dx == 0) ) 
        {//vertical 1/2 position: 2   
            for (j = 0; j < BLOCK_SIZE; j++)  
            { 
                for (i = 0; i < BLOCK_SIZE; i++)  
                { 
                    for (result = 0, y = -3; y < 5; y++) 
                    { 
                        result += ref_pic[max(0, min(maxold_y, y_pos + j + y))] 
                                         [max(0, min(maxold_x, x_pos + i))] 
                                  * COEF_HALF_v[y + 3]; 
                    } 
                    //block[i][j] = max(0, min(255, (result + 1) / 2)); 
                    block[i][j] = max(0, min(255, (result + iWeight1_2_v / 2) >>3)); 
                } 
            } 
        }//else if ( (dy == 2) && (dx == 0) ) 
        else if( ( (dy == 1) || (dy == 3)) && (dx == 0) ) 
        {//vertical 1/4 position: c and j 
            for (j = -1; j < BLOCK_SIZE + 1; j++)  
            { 
                for (i = 0; i < BLOCK_SIZE; i++)  
                { 
                    for (result = 0, y = -3; y < 5; y++) 
                    { 
                        result += ref_pic[max(0, min(maxold_y, y_pos + j + y))] 
                                         [max(0, min(maxold_x, x_pos + i))] 
                                  * COEF_HALF_v[y + 3]; 
                    } 
                    //tmp_res[2 * ( j + 1 )][i] = max(0, min(255, (result + 4) / 8)); 
                    tmp_res[2 * ( j + 1 )][i] = max(0, min(255, (result + iWeight1_2_v / 2) >>3)); 
                    tmp_res[2 * ( j + 1 ) + 1][i] = ref_pic[max(0, min(maxold_y, y_pos + j + 1))] 
                                                           [max(0, min(maxold_x, x_pos + i))]; 
                } 
            } 
            for (j = 0; j < BLOCK_SIZE; j++)  
            { 
                for (i = 0; i < BLOCK_SIZE; i++)  
                { 
                    for (result = 0, y = -1; y < 3; y++) 
                    { 
                        if (dy == 1)//c 
                        { 
                            result += tmp_res[2 * j + y + 1][i] * COEF_QUART[y + 1]; 
                        } 
                        else//j 
                        { 
                            result += tmp_res[2 * j + y + 2][i] * COEF_QUART[3-(y + 1)]; 
                        } 
                    } 
                    //block[i][j] = max(0, min(255, (result + 8) / 16)); 
                    block[i][j] = max(0, min(255, (result + iWeight1_4 / 2) >>1)); 
                } 
            } 
        }//else if( ( (dy == 1) || (dy == 3)) && (dx == 0) ) 
        else if ( (dx == 2) && (dy == 2) ) 
        {//horizonal and vertical 1/2 position: 3     
            for (j = -3; j < BLOCK_SIZE + 4; j++)  
            { 
                for (i = 0; i < BLOCK_SIZE; i++)  
                { 
                    for (result = 0, x = -3; x < 5; x++) 
                    { 
                        result += ref_pic[max(0, min(maxold_y, y_pos + j))] 
                                         [max(0, min(maxold_x, x_pos + i + x))]  
                                  * COEF_HALF_h[x + 3]; 
                    } 
                    tmp_res[j + 3][i] = max(0, min(255, (result + iWeight1_2_h / 2) >>6));//max(0, min(255, (result+4)/8)); 
                } 
            } 
            for (j = 0; j < BLOCK_SIZE; j++)  
            { 
                for (i = 0; i < BLOCK_SIZE; i++)  
                { 
                    for (result = 0, y = -3; y < 5; y++) 
                    { 
                        result += tmp_res[j + y + 3][i] * COEF_HALF_v[y + 3]; 
                    } 
                    block[i][j] = max(0, min(255, (result + iWeight1_2_v / 2) >>3)); 
                } 
            } 
        } 
        else if( ( (dx == 1) || (dx == 3) ) && (dy == 2) ) 
        {//horizonal and vertical 1/4 position: h and i 
            
			/////////////////////////////////////////////// 
 
			for (j = -3; j < BLOCK_SIZE + 4; j++)  
            { 
                for (i = -1; i < BLOCK_SIZE+1; i++)  
                { 
                    for (result = 0, x = -3; x < 5; x++) 
                    { 
                        result += ref_pic[max(0, min(maxold_y, y_pos + j))] 
							[max(0, min(maxold_x, x_pos + i + x))]  
							* COEF_HALF_h[x + 3]; 
                    } 
                    tmp_res[j + 3][i+1] = max(0, min(255, (result + iWeight1_2_h / 2) >>6));//max(0, min(255, (result+4)/8)); 
                } 
            } 
            for (j = 0; j < BLOCK_SIZE; j++)  
            { 
                for (i = -1; i < BLOCK_SIZE+1; i++)  
                { 
                    for (result = 0, y = -3; y < 5; y++) 
                    { 
                        result += tmp_res[j + y + 3][i+1] * COEF_HALF_v[y + 3]; 
                    } 
                    tmp_res_3[j][i+1] = max(0, min(255, (result + iWeight1_2_v / 2) >>3)); 
                } 
            } 
 
 
 
 
 
			/////////////////////////////////////////////// 
			for (j = 0; j < BLOCK_SIZE; j++)  
            { 
                //for (i = -4; i < BLOCK_SIZE + 5; i++)  
				for (i = 0; i < BLOCK_SIZE + 2; i++)  
                { 
                    for (result = 0, y = -3; y < 5; y++) 
                    { 
                        result += ref_pic[max(0, min(maxold_y, y_pos + j + y))] 
                                         [max(0, min(maxold_x, x_pos + i))] 
                                  * COEF_HALF_v[y + 3]; 
                    } 
                    tmp_res[j][i] = max(0, min(255, (result + iWeight1_2_v / 2) >>3));//max(0, min(255, (result+4)/8)); 
                     
                } 
            } 
            for (j = 0; j < BLOCK_SIZE; j++)  
            { 
                for (i = 0; i < BLOCK_SIZE + 2; i++)  
                { 
                     tmp_res_2[j][2 * i] = tmp_res_3[j][i]; 
                     tmp_res_2[j][2 * i + 1] = tmp_res[j][i]; 
                } 
            } 
            for (j = 0; j < BLOCK_SIZE; j++)  
            { 
                for (i = 0; i < BLOCK_SIZE; i++)  
                { 
                    for (result = 0, x = -1; x < 3; x++) 
                    { 
                        if (dx == 1)//h 
                        { 
                            result += tmp_res_2[j][2 * i + x + 1] * COEF_QUART[x + 1]; 
                        } 
                        else 
                        { 
                            result += tmp_res_2[j][2 * i + x + 2] * COEF_QUART[3-(x + 1)]; 
                        } 
                    } 
                    //block[i][j] = max(0, min(255, (result + 8) / 16)); 
                    block[i][j] = max(0, min(255, (result + iWeight1_4 / 2) >>1)); 
                } 
            } 
        } 
        else if( ( (dy == 1) || (dy == 3) ) && (dx == 2) ) 
        {//vertical and horizonal 1/4 position: e and l 
            for (j = -4; j < BLOCK_SIZE+5; j++)  
            { 
                for (i = 0; i < BLOCK_SIZE; i++)  
                { 
                    for (result = 0, x = -3; x < 5; x++) 
                    { 
                        result += ref_pic[max(0, min(maxold_y, y_pos + j))] 
                                         [max(0, min(maxold_x, x_pos + i + x))]  
                                  * COEF_HALF_h[x + 3]; 
                    } 
                    tmp_res[j + 4][i] = max(0, min(255, (result + iWeight1_2_h / 2) >>6));// max(0, min(255, (result+4)/8)); 
                    //tmp_res[j + 2][i] = max(0, min(255, (result + iWeight1_2 / 2) / iWeight1_2)); 
                } 
            } 
            for (j = 0; j < BLOCK_SIZE + 2; j++)  
            { 
                for (i = 0; i < BLOCK_SIZE; i++)  
                { 
                    for (result = 0, y = -3; y < 5; y++) 
                    { 
                        result += tmp_res[j + y + 3][i] * COEF_HALF_v[y + 3]; 
                    } 
                    //tmp_res_2[2 * j][i] = max(0, min(255, (result + 32) / 64)); 
                    tmp_res_2[2 * j][i] = max(0, min(255, (result + iWeight1_2_v / 2) >>3)); 
                    //tmp_res_2[2 * j + 1][i] =  max(0, min(255, (tmp_res[j + 2][i] + 4) / 8)); 
                    tmp_res_2[2 * j + 1][i] =  tmp_res[j + 4][i]; 
                } 
            } 
            for (j = 0; j < BLOCK_SIZE; j++)  
            { 
                for (i = 0; i < BLOCK_SIZE; i++)  
                { 
                    for (result = 0, y = -1; y < 3; y++) 
                    { 
                        if(dy == 1)//e 
                        { 
                            result += tmp_res_2[2 * j + y + 1][i] * COEF_QUART[y + 1]; 
                        } 
                        else//l 
                        { 
                            result += tmp_res_2[2 * j + y + 2][i] * COEF_QUART[3-(y + 1)]; 
                        } 
                    } 
                    //block[i][j] = max(0, min(255, (result + 8) / 16)); 
                    block[i][j] = max(0, min(255, (result + iWeight1_4 / 2) >>1)); 
                } 
            } 
        } 
        else 
        {//Diagonal 1/4 position : d, f, k and m 
            for (j = -3; j < BLOCK_SIZE + 5; j++)  
            { 
                for (i = 0; i < BLOCK_SIZE; i++)  
                { 
                    for (result = 0, x = -3; x < 5; x++) 
                    { 
                        result += ref_pic[max(0, min(maxold_y, y_pos + j))] 
                                         [max(0, min(maxold_x, x_pos + i + x))]  
                                  * COEF_HALF_h[x + 3]; 
                    } 
                    tmp_res[j + 3][i] = max(0, min(255, (result + iWeight1_2_h / 2) >>6));//max(0, min(255, (result+4)/8)); 
                    //tmp_res[j + 1][i] = max(0, min(255, (result + iWeight1_2 / 2) / iWeight1_2)); 
                }        
            } 
            for (j = 0; j < BLOCK_SIZE; j++)  
            { 
                for (i = 0; i < BLOCK_SIZE; i++)  
                { 
                    for (result = 0, y = -3; y < 5; y++) 
                    { 
                        result += tmp_res[j + y + 3][i] * COEF_HALF_v[y + 3]; 
                    } 
                    //tmp_res_2[j][i] = max(0, min(255, (result + 32) / 64)); 
                    tmp_res_2[j][i] = max(0, min(255, (result + iWeight1_2_v / 2) >>3)); 
                } 
            }    
            for (j = 0; j < BLOCK_SIZE; j++)  
            { 
                for (i = 0; i < BLOCK_SIZE; i++)  
                { 
                    if( (dx == 1) && (dy == 1) )//d 
                    { 
                        result = tmp_res_2[j][i] + ref_pic[max(0, min(maxold_y, y_pos + j))] 
                                                          [max(0, min(maxold_x, x_pos + i))]; 
                    } 
                    else if( (dx == 3) && (dy == 1) )//f 
                    { 
                        result = tmp_res_2[j][i] + ref_pic[max(0, min(maxold_y, y_pos + j))] 
                                                          [max(0, min(maxold_x, x_pos + i + 1))]; 
                    } 
                    else if ((dx == 1) && (dy == 3))//k 
                    { 
                        result = tmp_res_2[j][i] + ref_pic[max(0, min(maxold_y, y_pos + j + 1))] 
                                                          [max(0, min(maxold_x, x_pos + i))]; 
                    } 
                    else if((dx == 3) && (dy == 3))//m 
                    { 
                        result = tmp_res_2[j][i] + ref_pic[max(0, min(maxold_y, y_pos + j + 1))] 
                                                          [max(0, min(maxold_x, x_pos + i + 1))]; 
                    } 
                    block[i][j] = max(0, min(255, (result + 1) / 2)); 
                } 
            } 
        } 
    }//if (dx == 0 && dy == 0) else 
} 
 
/*! 
************************************************************************ 
* \brief 
*    Initializes the parameters for a new frame 
************************************************************************ 
*/ 
void init_frame()   //qwang 2004-3-10 
{ 
	int i,j; 
 
	for(i=0;i<(pgImage->width/BLOCK_SIZE+2);i++)          // set edge to -1, indicate nothing to predict from 
	for(j=0;j<(pgImage->height/BLOCK_SIZE+2);j++) 
	{ 
		pgImage->ipredmode[i][j]=-1; 
	} 
 
	 
	for(i=0; imax_mb_nr; i++) 
	{ 
		mb_data[i].slice_nr = -1;  
	} 
	 
 
	pgImage->current_mb_nr = 0; 
	imgY =  current_frame[0]; 
	imgUV = ¤t_frame[1]; 
 
	pgImage->current_slice_nr=-1;//WJP FOR SLICE_HEADER 050320 
} 
/*! 
************************************************************************ 
* \brief 
*    decodes one picture 
************************************************************************ 
*/ 
void decode_picture_data() 
{ 
	//WJP FOR SLICE 
	//int tmp; 
	int pos_of_NSLE_SC = 1; 
	int next_slice_start_pos=0;//WJP FOR SLICE_HEADER 050320 
	 
	int slice_delta_qp;//WJP FOR SLICE_HEADER 050320 
	int first_mb_nr_in_slice;//WJP FOR SLICE_HEADER 050320 
 
  
 
  pgImage->cod_counter=-1; 
   
	while (pgImage->current_mb_nrPicSizeInMbs) // loop over macroblocks 
	{ 
 
    //decode_slice_header(); 
   if(pos_of_NSLE_SC!=0) 
   { 
		if(pgImage->current_mb_nr == next_slice_start_pos)  
		{ 
#if TRACE 
    fprintf(p_trace,"\n"); 
    tracebits2("start_code_prefix",24,0x01); 
#endif 
     	pgImage->current_slice_nr++; 
			//slice_nr=pgImage->current_slice_nr; 
       
      pgImage->cod_counter=-1; 
			 
			pos_of_NSLE_SC = Position_of_Slice_in_Picbuff[pgImage->current_slice_nr + 1]; 
 
#if TRACE 
     // fprintf(p_trace,"ANNEX B NALU, len %d, forbidden_bit %d, nal_reference_idc %d, nal_unit_type %d,\n", 
     //         (pos_of_NSLE_SC+1),0,1,3);  /* temporary */ 
#endif 
 
 
			next_slice_start_pos = search_ue_code(pos_of_NSLE_SC*8); 
 
		  currStream->frame_bitoffset = Position_of_Slice_in_Picbuff[pgImage->current_slice_nr]*8; 
 
			first_mb_nr_in_slice = ue_v("SliceHeader: first_mb_nr_in_slice");    
 
			if(!fixed_picture_qp_flag) 
			{ 
				fixed_slice_qp_flag = u_v(1,"SliceHeader: fixed_slice_qp"); 
				slice_delta_qp = se_v("SliceHeader: slice_delta_qp");		           
        previous_qp = pgImage->qp + slice_delta_qp; // zhan ma 0714 
			} 
      else 
      { 
        fixed_slice_qp_flag = 1;      // zhan ma 0714 
        slice_delta_qp = 0; 
      } 
 
      
     if(!pgImage->loop_filter_disable_flag)  
			{ 
				pgImage->disable_loop_filter_slice_flag = u_v(1,"SliceHeader: disable_loop_filter_slice_flag"); 
        pgImage->SliceLFDisbaleFlag[pgImage->current_slice_nr] = pgImage->disable_loop_filter_slice_flag; 
			} 
 
     //fprintf(stdout,"%2d",pgImage->SliceLFDisbaleFlag[pgImage->current_slice_nr]); 
 
     CheckSliceHeaderValid(first_mb_nr_in_slice,slice_delta_qp);   /* check slice header conformance*/ 
		} 
	} 
 
    
   /* slice data decoding */ 
   decode_slice_data(); 
    
 
 
  //if (pgImage->current_mb_nr == (next_slice_start_pos)) 
  //   DecodeTrailingBits1(currStream,pos_of_NSLE_SC+1); 
	   
#ifdef _ISOLATED_REGION_ 
    if(iREGenable) 
    { 
      if (pgImage->type == P_IMG) 
      { 
        int j, i; 
        if (iREGmap[pgImage->mb_y][pgImage->mb_x] != 2) 
          for (j = 0; j < 4; j++) 
            for (i = 0; i < 4; i++) 
              pgImage->ipredmode[pgImage->mb_x * 4 + i + 1][pgImage->mb_y * 4 + j + 1] = -1; 
       } 
    } 
#endif // _ISOLATED_REGION_ 
//fprintf(stdout,"%2d",pgImage->disable_loop_filter_slice_flag); 
 
  } //end of MB-loop 
} 
 
 /*!  
 ************************************************************************************* 
 * \brief :  
 *    decoding slice header including first_mb_in_slice etc. 
 * \author : 
 *    Ma Zhan 
 ************************************************************************************* 
 */ 
void decode_slice_header() 
{ 
 
 
} 
 
 /*!  
 ************************************************************************************* 
 * \brief :  
 *    decoding slice header including first_mb_in_slice etc. 
 * \author : 
 *    Ma Zhan 
 ************************************************************************************* 
 */ 
void decode_slice_data() 
{ 
#if TRACE 
	// Here was the slice nr from the mb_data used.  This slice number is only set after  
	// the reconstruction of an MB and hence here not yet valid 
	fprintf(p_trace,"\n*********** Pic: %i (I/P) MB: %i Slice: %i Type %d **********\n", pgImage->number, pgImage->current_mb_nr, pgImage->current_slice_nr, pgImage->type); 
	fflush(p_trace); 
#endif 
     
	// Initializes the current macroblock 
	start_macroblock(); 
 
	// Get the syntax elements from the NAL 
 
	read_one_macroblock(); 
 
	// decode one macroblock 
	decode_one_macroblock(); 
   
	 
 
	pgImage->current_mb_nr++; 
  previous_qp = pgcurrMB->qp; 
} 
 
 /*!  
 ************************************************************************************* 
 * \brief :  
 *    Write decoded frame to output file 
 ************************************************************************************* 
 */ 
void write_frame( FILE *p_out)          //!< filestream to output file 
{ 
  int i,j; 
 
  for(i=0;iheight;i++) 
    for(j=0;jwidth;j++) 
    { 
      fputc(imgY[i][j],p_out); 
    } 
 
  for(i=0;iheight_cr;i++) 
    for(j=0;jwidth_cr;j++) 
    { 
      fputc(imgUV[0][i][j],p_out); 
    } 
 
  for(i=0;iheight_cr;i++) 
    for(j=0;jwidth_cr;j++) 
    { 
      fputc(imgUV[1][i][j],p_out); 
    } 
 
  fflush(p_out); 
 
}