www.pudn.com > wm2.5.zip > image.c


 
/* 
************************************************************************************* 
* File name: image.c 
* Function: Decode a Slice 
* 
************************************************************************************* 
*/ 
#include  
#include  
#include  
#include  
#include  
#include  
 
#include "global.h" 
#include "header.h" 
#include "bitstream.h" 
#include "vlc.h" 
#include "memalloc.h" 
extern FILE *bits; 
//extern int Slice_Enable; 
//extern int Position_of_Slice_in_Picbuff[176]; 
 
extern void UpdateiREG(); 
/* 
************************************************************************* 
* Function:decodes one I- or P-frame 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
int decode_one_frame(struct snr_par *snr) 
{ 
  time_t ltime1;                  // for time measurement 
  time_t ltime2; 
#if TRACE 
  int img_y,img_x; 
  int mb_x; 
#endif 
 
#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_ 
  //MZ 
  picture_data();  // decoding process 
 
  DeblockFrame(imgY , imgUV); 
 
#if TRACE 
		fprintf(p_trace,"@Deblocked Frame : \n"); 
		for(img_y=0;img_yheight;img_y++) 
		{ 
		 
			if(!(img_y%MB_BLOCK_SIZE)) 
			{ 
				for(mb_x=0;mb_x<(pgImage->width/MB_BLOCK_SIZE);mb_x++) 
					fprintf(p_trace,"  ------------------------------%2d------------------------------ ",mb_x+(img_y/MB_BLOCK_SIZE)*(pgImage->width/MB_BLOCK_SIZE)); 
				fprintf(p_trace,"\n"); 
			} 
			for(img_x=0;img_xwidth;img_x++) 
			{    
				fprintf(p_trace,"%4d",imgY[img_y][img_x]); 
				if((img_x+1)%MB_BLOCK_SIZE == 0)  fprintf(p_trace," "); 
			} 
			fprintf(p_trace,"\n"); 
				if ((img_y+1)%MB_BLOCK_SIZE == 0) fprintf(p_trace,"\n"); 
		} 
 
		fprintf(p_trace,"\n"); 
 
		for(img_y=0;img_yheight_cr;img_y++) 
		{ 
			//U 
			if(!(img_y%B8_SIZE)) 
			{ 
				for(mb_x=0;mb_x<(pgImage->width_cr/B8_SIZE);mb_x++) 
					fprintf(p_trace," ---------------%2d-------------- ",mb_x+(img_y/B8_SIZE)*(pgImage->width_cr/B8_SIZE)); 
			} 
			//V 
			if(!(img_y%B8_SIZE)) 
			{ 
				for(mb_x=0;mb_x<(pgImage->width_cr/B8_SIZE);mb_x++) 
					fprintf(p_trace," ---------------%2d-------------- ",mb_x+(img_y/B8_SIZE)*(pgImage->width_cr/B8_SIZE)); 
				fprintf(p_trace,"\n"); 
			} 
			for(img_x=0;img_xwidth_cr;img_x++) 
			{ 
				fprintf(p_trace,"%4d",imgUV[0][img_y][img_x]); 
				if((img_x+1)%B8_SIZE == 0) fprintf(p_trace," "); 
			} 
		 
			for(img_x=0;img_xwidth_cr;img_x++) 
			{    
				fprintf(p_trace,"%4d",imgUV[1][img_y][img_x]); 
				if((img_x+1)%B8_SIZE == 0)    fprintf(p_trace," "); 
			} 
				fprintf(p_trace,"\n"); 
				if ((img_y+1)%B8_SIZE == 0)   fprintf(p_trace,"\n"); // carriage 
		} 
 
 
#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); 
} 
/* 
************************************************************************* 
* Function: 
* Input:    lasting time while decoding one frame. 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
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); 
} 
 
 
/* 
************************************************************************* 
* Function:Find PSNR for all three components.Compare decoded frame with 
      the original sequence. Read input->jumpd frames to reflect frame skipping. 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
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_ 
  } 
} 
 
 
/* 
************************************************************************* 
* Function:Interpolation of 1/4 subpixel 
* Input: 
* Output: 
* Return:  
* Attention: 
* Note   :   Nov 13, 2004, accept M1466(北京工业大学), added by cbzhu 
************************************************************************* 
*/ 
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 iWeight1_2_h = 64; 
		const iWeight1_2_v = 8; 
 
 
    static const int COEF_QUART[4] = {0, 1, 1, 0}; 
		const 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 
} 
 
 
/* 
************************************************************************* 
* Function:Initializes the parameters for a new frame 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
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;i<(pgImage->width/MB_BLOCK_SIZE+2);i++)          // set edge to -1, indicate nothing to predict from 
	for(j=0;j<(pgImage->height/MB_BLOCK_SIZE+2);j++) 
	{ 
		pgImage->c_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 
} 
 
/* 
************************************************************************* 
* Function:decodes one picture 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
void picture_data() 
{ 
	//WJP FOR SLICE 
	int slice_nr=0; 
	int pos_of_NSLE_SC=1; 
	int next_slice_start_pos=0;//WJP FOR SLICE_HEADER 050320 
	int fixed_slice_qp; 
	int slice_delta_qp;//WJP FOR SLICE_HEADER 050320 
	int first_mb_nr_in_slice;//WJP FOR SLICE_HEADER 050320 
	 
// if(pps->skip_mode_flag) 
        pgImage->cod_counter=-1; 
 
	while (pgImage->current_mb_nrPicSizeInMbs) // loop over macroblocks 
	{ 
		//WJP FOR SLICE 
		if(Slice_Enable) 
		{ 
			if(pos_of_NSLE_SC!=0) 
			{ 
/*WJP FOR SLICE_HEADER 050320 
				if((pgImage->current_mb_nr/(pgImage->width/MB_BLOCK_SIZE) == next_slice_ver_pos)  
					&& !(pgImage->current_mb_nr%(pgImage->width/MB_BLOCK_SIZE))) 
*/ 
				if(pgImage->current_mb_nr == next_slice_start_pos)  
				{ 
					pgImage->current_slice_nr++; 
					slice_nr=pgImage->current_slice_nr; 
           
//         if(pps->skip_mode_flag) 
					      pgImage->cod_counter=-1; 
					 
					pos_of_NSLE_SC=Position_of_Slice_in_Picbuff[slice_nr+1]; 
/*WJP FOR SLICE_HEADER 050320 
					next_slice_ver_pos=currStream->streamBuffer[pos_of_NSLE_SC]; 
					currStream->frame_bitoffset = (Position_of_Slice_in_Picbuff[slice_nr]+1)*8; 
*/ 
					next_slice_start_pos = search_ue_code(pos_of_NSLE_SC*8); 
					currStream->frame_bitoffset = Position_of_Slice_in_Picbuff[slice_nr]*8; 
					first_mb_nr_in_slice = ue_v("first_mb_nr_in_slice"); 
//WJP END 050320 
					if(!fixed_picture_qp) 
					{ 
						fixed_slice_qp=u_v(1,"fixed_slice_qp"); 
//						slice_qp = u_v(6,"slice_qp");//WJP FOR SLICE_HEADER 050320					 
						slice_delta_qp = se_v("slice_delta_qp");						 
					} 
					//WJP FOR SLICE_DEBLOCK 050321 
					if(!loop_filter_disable)  
					{ 
						pgImage->disable_loop_filter_slice_flag = u_v(1,"disable_loop_filter_slice_flag"); 
					} 
					//WJP END 050321 
				} 
			} 
		} 
		//WJP END 
	   
#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(); 
		//printf("%d \n",pgImage->current_mb_nr); 
 
		// decode one macroblock 
		decode_one_macroblock(); 
		mb_data[pgImage->current_mb_nr].lf_alpha_c0_offset=-2; 
		mb_data[pgImage->current_mb_nr].lf_beta_offset=-1; 
		mb_data[pgImage->current_mb_nr].cbp_blk=0; 
	 
		pgImage->current_mb_nr++; 
 
		//printf("%d \n",first_mb_nr_in_slice); 
 
		//cbzhu 0412 
#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_ 
	} 
/*WJP FOR SLICE 
    //sw 8.2 
	if(currStream->frame_bitoffset%8) 
		fseek(bits, currStream->frame_bitoffset/8+1, SEEK_CUR); 
	else 
		fseek(bits, currStream->frame_bitoffset/8, SEEK_CUR); 
*/ 
}