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


/* 
*********************************************************************** 
* COPYRIGHT AND WARRANTY INFORMATION 
* 
* Copyright 2004, Advanced Audio Video Coding Standard, Part II 
* 
* DISCLAIMER OF WARRANTY 
* 
* These software programs are available to the users without any 
* license fee or royalty on an "as is" basis. The AVS disclaims 
* any and all warranties, whether express, implied, or statutory, 
* including any implied warranties of merchantability or of fitness 
* for a particular purpose. In no event shall the contributors or  
* the AVS be liable for any incidental, punitive, or consequential 
* damages of any kind whatsoever arising from the use of this program. 
* 
* This disclaimer of warranty extends to the user of this program 
* and user's customers, employees, agents, transferees, successors, 
* and assigns. 
* 
* The AVS does not represent or warrant that the program furnished 
* hereunder are free of infringement of any third-party patents. 
* Commercial implementations of AVS, including shareware, may be 
* subject to royalty fees to patent holders. Information regarding 
* the AVS patent policy is available from the AVS Web site at 
* http://www.avs.org.cn 
* 
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. 
************************************************************************ 
*/   
 
#include  
#include  
#include "global.h" 
#include "defines.h" 
#include "block.h" 
#include "intraprediction.h" 
 
 
// Notation for comments regarding prediction and predictors. 
// The pels of the 4x4 block are labelled a..p. The predictor pels above 
// are labelled A..H, from the left I..P, and from above left X, as follows: 
// 
//  X A B C D E F G H 
//  I a b c d 
//  J e f g h 
//  K i j k l 
//  L m n o p 
//  M 
//  N 
//  O 
//  P 
// 
 
// Predictor array index definitions 
#define P_X (PredPel[0]) 
#define P_A (PredPel[1]) 
#define P_B (PredPel[2]) 
#define P_C (PredPel[3]) 
#define P_D (PredPel[4]) 
#define P_E (PredPel[5]) 
#define P_F (PredPel[6]) 
#define P_G (PredPel[7]) 
#define P_H (PredPel[8]) 
#define P_I (PredPel[9]) 
#define P_J (PredPel[10]) 
#define P_K (PredPel[11]) 
#define P_L (PredPel[12]) 
#define P_M (PredPel[13]) 
#define P_N (PredPel[14]) 
#define P_O (PredPel[15]) 
#define P_P (PredPel[16]) 
 
/*! 
 *********************************************************************** 
 * \brief 
 *    makes and returns 4x4 blocks with all 5 intra prediction modes 
 * 
 * \return 
 *    DECODING_OK   decoding of intraprediction mode was sucessfull             
 *    SEARCH_SYNC   search next sync element as errors while decoding occured 
 *  
 *********************************************************************** 
 */ 
int intrapred(int b8, 
			        int b4, 
			        int ioff,					    //!< pixel offset X within MB 
			        int joff,					    //!< pixel offset Y within MB 
			        int img_block_x,			//!< location of block X, multiples of 4 
			        int img_block_y)			//!< location of block Y, multiples of 4 
{ 
	int i,j; 
	int s0; 
	int img_y,img_x; 
	int PredPel[17];  // array of predictor pels 
 
	int block_available_up; 
	int block_available_up_right; 
	int block_available_left; 
	int block_available_left_down; 
	int block_available_up_left; 
  //one 4x4 block one mode 
  byte predmode = pgImage->ipredmode[img_block_x+1][img_block_y+1];   //accordinate based on this 
   
  img_x=img_block_x*4; 
  img_y=img_block_y*4; 
 
 
  block_available_up      = (pgImage->ipredmode[img_block_x+1][img_block_y] >=0);              /// can use frm 
  block_available_left    = (pgImage->ipredmode[img_block_x][img_block_y+1] >=0);            /// can use frm 
  block_available_up_left = (pgImage->ipredmode[img_block_x][img_block_y] >=0); 
  block_available_left_down = 0;  // undecoded 
  block_available_up_right  = 0;  // undecoded 
 
  
	// end 
  
  i = (img_x & 15); 
  j = (img_y & 15); 
 
  // form predictor pels 
  if (block_available_up) 
  { 
    P_A = imgY[img_y-1][img_x+0]; 
    P_B = imgY[img_y-1][img_x+1]; 
    P_C = imgY[img_y-1][img_x+2]; 
    P_D = imgY[img_y-1][img_x+3]; 
	  P_E = P_F = P_G = P_H = P_D;   //last 5 pixels is equivalent.  
  } 
  else 
    P_A = P_B = P_C = P_D = P_E = P_F = P_G = P_H = 128; 
  
  // 
  if (block_available_left) 
  { 
    P_I = imgY[img_y+0][img_x-1]; 
    P_J = imgY[img_y+1][img_x-1]; 
    P_K = imgY[img_y+2][img_x-1]; 
    P_L = imgY[img_y+3][img_x-1]; 
	  P_M = P_N = P_O = P_P = P_L; 
  } 
  else 
    P_I = P_J = P_K = P_L = P_M = P_N = P_O = P_P = 128; 
   
  //luma r0 picking up 
  if (block_available_up_left) 
	  P_X = imgY[img_y-1][img_x-1]; 
  else 
	  P_X = 128; 
 
  //predmode selection   
  // 9 modes proposed by HUST in AVS_Mxxxx 
  switch (predmode) 
  { 
    case DC_PRED:                         // DC prediction  
      s0 = 0; 
      if (block_available_up && block_available_left) 
      {    
        // no edge 
        s0 = (P_A + P_B + P_C + P_D + P_I + P_J + P_K + P_L + 4)/(2*BLOCK_SIZE); 
      } 
      else if (!block_available_up && block_available_left) 
      { 
        // upper edge 
        s0 = (P_I + P_J + P_K + P_L + 2)/BLOCK_SIZE;              
      } 
      else if (block_available_up && !block_available_left) 
      { 
        // left edge 
        s0 = (P_A + P_B + P_C + P_D + 2)/BLOCK_SIZE;              
      } 
      else //if (!block_available_up && !block_available_left) 
      { 
        // top left corner, nothing to predict from 
        s0 = 128;                            
      } 
     
      for (j=0; j < BLOCK_SIZE; j++) 
	  	 for (i=0; i < BLOCK_SIZE; i++) 
        pgcurrMB->pred_sample[b8][b4][i][j] = s0;  // store DC prediction 
    break; 
         
    case VERT_PRED:                       // vertical prediction from block above  
      for(j=0;jpred_sample[b8][b4][i][j]=imgY[img_y-1][img_x+i];// store predicted 4x4 block  
    break; 
       
    case HOR_PRED:                        // horisontal prediction from left block  
      for(j=0;jpred_sample[b8][b4][i][j]=imgY[img_y+j][img_x-1]; // store predicted 4x4 block  
    break; 
       
    case DOWN_RIGHT_PRED: 
      pgcurrMB->pred_sample[b8][b4][0][3] = (P_L + 2*P_K + P_J + 2) / 4;  
      pgcurrMB->pred_sample[b8][b4][0][2] = 
      pgcurrMB->pred_sample[b8][b4][1][3] = (P_K + 2*P_J + P_I + 2) / 4;  
      pgcurrMB->pred_sample[b8][b4][0][1] = 
      pgcurrMB->pred_sample[b8][b4][1][2] =  
      pgcurrMB->pred_sample[b8][b4][2][3] = (P_J + 2*P_I + P_X + 2) / 4;  
      pgcurrMB->pred_sample[b8][b4][0][0] = 
      pgcurrMB->pred_sample[b8][b4][1][1] = 
      pgcurrMB->pred_sample[b8][b4][2][2] = 
      pgcurrMB->pred_sample[b8][b4][3][3] = (P_I + 2*P_X + P_A + 2) / 4;  
      pgcurrMB->pred_sample[b8][b4][1][0] = 
      pgcurrMB->pred_sample[b8][b4][2][1] = 
      pgcurrMB->pred_sample[b8][b4][3][2] = (P_X + 2*P_A + P_B + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][2][0] = 
      pgcurrMB->pred_sample[b8][b4][3][1] = (P_A + 2*P_B + P_C + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][3][0] = (P_B + 2*P_C + P_D + 2) / 4; 
    break; 
     
    case DOWN_LEFT_PRED: 
      pgcurrMB->pred_sample[b8][b4][0][0] = (P_A + P_C + P_I + P_K + 2*(P_B + P_J) + 4) / 8; 
      pgcurrMB->pred_sample[b8][b4][1][0] =  
      pgcurrMB->pred_sample[b8][b4][0][1] = (P_B + P_D + P_J + P_L + 2*(P_C + P_K) + 4) / 8; 
      pgcurrMB->pred_sample[b8][b4][2][0] = 
      pgcurrMB->pred_sample[b8][b4][1][1] = 
      pgcurrMB->pred_sample[b8][b4][0][2] = (P_C + P_E + P_K + P_M + 2*(P_D + P_L) + 4) / 8; 
      pgcurrMB->pred_sample[b8][b4][3][0] =  
      pgcurrMB->pred_sample[b8][b4][2][1] =  
      pgcurrMB->pred_sample[b8][b4][1][2] =  
      pgcurrMB->pred_sample[b8][b4][0][3] = (P_D + P_F + P_L + P_N + 2*(P_E + P_M) + 4) / 8; 
      pgcurrMB->pred_sample[b8][b4][3][1] =  
      pgcurrMB->pred_sample[b8][b4][2][2] =  
      pgcurrMB->pred_sample[b8][b4][1][3] = (P_E + P_G + P_M + P_O + 2*(P_F + P_N) + 4) / 8; 
      pgcurrMB->pred_sample[b8][b4][3][2] =  
      pgcurrMB->pred_sample[b8][b4][2][3] = (P_F + P_H + P_N + P_P + 2*(P_G + P_O) + 4) / 8; 
      pgcurrMB->pred_sample[b8][b4][3][3] = (P_G + P_O + P_H + P_P + 2) / 4; 
    break; 
      	 
    case VERT_RIGHT_PRED: // 5 make VERT_RIGHT_PRED Prediction   
      pgcurrMB->pred_sample[b8][b4][0][0] =  
      pgcurrMB->pred_sample[b8][b4][1][2] = (P_X + P_A + 1) / 2; 
      pgcurrMB->pred_sample[b8][b4][1][0] =  
      pgcurrMB->pred_sample[b8][b4][2][2] = (P_A + P_B + 1) / 2; 
      pgcurrMB->pred_sample[b8][b4][2][0] =  
      pgcurrMB->pred_sample[b8][b4][3][2] = (P_B + P_C + 1) / 2; 
      pgcurrMB->pred_sample[b8][b4][3][0] = (P_C + P_D + 1) / 2; 
      pgcurrMB->pred_sample[b8][b4][0][1] =  
      pgcurrMB->pred_sample[b8][b4][1][3] = (P_I + 2*P_X + P_A + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][1][1] =  
      pgcurrMB->pred_sample[b8][b4][2][3] = (P_X + 2*P_A + P_B + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][2][1] =  
      pgcurrMB->pred_sample[b8][b4][3][3] = (P_A + 2*P_B + P_C + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][3][1] = (P_B + 2*P_C + P_D + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][0][2] = (P_X + 2*P_I + P_J + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][0][3] = (P_I + 2*P_J + P_K + 2) / 4; 
    break; 
     
    case HOR_DOWN_PRED: // 6 make HOR_DOWN_PRED Prediction 
      pgcurrMB->pred_sample[b8][b4][0][0] =  
      pgcurrMB->pred_sample[b8][b4][2][1] = (P_X + P_I + 1) / 2; 
      pgcurrMB->pred_sample[b8][b4][1][0] =  
      pgcurrMB->pred_sample[b8][b4][3][1] = (P_I + 2*P_X + P_A + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][2][0] = (P_X + 2*P_A + P_B + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][3][0] = (P_A + 2*P_B + P_C + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][0][1] =  
      pgcurrMB->pred_sample[b8][b4][2][2] = (P_I + P_J + 1) / 2; 
      pgcurrMB->pred_sample[b8][b4][1][1] =  
      pgcurrMB->pred_sample[b8][b4][3][2] = (P_X + 2*P_I + P_J + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][0][2] =  
      pgcurrMB->pred_sample[b8][b4][2][3] = (P_J + P_K + 1) / 2; 
      pgcurrMB->pred_sample[b8][b4][1][2] =  
      pgcurrMB->pred_sample[b8][b4][3][3] = (P_I + 2*P_J + P_K + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][0][3] = (P_K + P_L + 1) / 2; 
      pgcurrMB->pred_sample[b8][b4][1][3] = (P_J + 2*P_K + P_L + 2) / 4; 
 	  break; // end HOR_DOWN_PRED 
     
    case VERT_LEFT_PRED: // 7 make VERT_LEFT_PRED Prediction 
      pgcurrMB->pred_sample[b8][b4][0][0] = (P_A + P_B + 1) / 2; 
      pgcurrMB->pred_sample[b8][b4][1][0] =  
      pgcurrMB->pred_sample[b8][b4][0][2] = (P_B + P_C + 1) / 2; 
      pgcurrMB->pred_sample[b8][b4][2][0] =  
      pgcurrMB->pred_sample[b8][b4][1][2] = (P_C + P_D + 1) / 2; 
      pgcurrMB->pred_sample[b8][b4][3][0] =  
      pgcurrMB->pred_sample[b8][b4][2][2] = (P_D + P_E + 1) / 2; 
      pgcurrMB->pred_sample[b8][b4][3][2] = (P_E + P_F + 1) / 2; 
      pgcurrMB->pred_sample[b8][b4][0][1] = (P_A + 2*P_B + P_C + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][1][1] =  
      pgcurrMB->pred_sample[b8][b4][0][3] = (P_B + 2*P_C + P_D + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][2][1] =  
      pgcurrMB->pred_sample[b8][b4][1][3] = (P_C + 2*P_D + P_E + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][3][1] =  
      pgcurrMB->pred_sample[b8][b4][2][3] = (P_D + 2*P_E + P_F + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][3][3] = (P_E + 2*P_F + P_G + 2) / 4; 
    break; // end VERT_LEFT_PRED	 
     
    case HOR_UP_PRED: // 8 make HOR_UP_PRED Prediction 
      pgcurrMB->pred_sample[b8][b4][0][0] = (P_I + P_J + 1) / 2; 
      pgcurrMB->pred_sample[b8][b4][1][0] = (P_I + 2*P_J + P_K + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][2][0] =  
      pgcurrMB->pred_sample[b8][b4][0][1] = (P_J + P_K + 1) / 2; 
      pgcurrMB->pred_sample[b8][b4][3][0] =  
      pgcurrMB->pred_sample[b8][b4][1][1] = (P_J + 2*P_K + P_L + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][2][1] =  
      pgcurrMB->pred_sample[b8][b4][0][2] = (P_K + P_L + 1) / 2; 
      pgcurrMB->pred_sample[b8][b4][3][1] =  
      pgcurrMB->pred_sample[b8][b4][1][2] = (P_K + 2*P_L + P_M + 2) / 4; 
      pgcurrMB->pred_sample[b8][b4][0][3] = 
      pgcurrMB->pred_sample[b8][b4][2][2] =  
      pgcurrMB->pred_sample[b8][b4][3][2] =  
      pgcurrMB->pred_sample[b8][b4][1][3] =  
      pgcurrMB->pred_sample[b8][b4][2][3] =  
      pgcurrMB->pred_sample[b8][b4][3][3] = P_L; 
    break; // end HOR_UP_PRED 
        
    default: 
      printf("Error: illegal prediction mode input: %d\n",predmode); 
      return SEARCH_SYNC; 
    break; 
  } 
 
#if TRACE 
  for(j=0;j<4;j++) 
	  for(i=0;i<4;i++) 
     MB_intrapred_Y[((b8>>1)<<3)+((b4>>1)<<2)+j][((b8 &1)<<3)+((b4 &1)<<2)+i] = pgcurrMB->pred_sample[b8][b4][i][j]; 
#endif 
  return DECODING_OK; 
} 
 
/*! 
************************************************************************* 
* \brief: 
*   
*  
* \return: 
* 
************************************************************************* 
*/ 
void intrapred_chroma_4x4(int mb_x, 
                          int mb_y, 
                          int b4, 
                          int mode) 
{ 
#define CBS 4 // chroma block size 
    unsigned char edgepixu[20]; 
#define EU (edgepixu + 10) 
    unsigned char edgepixv[20]; 
#define EV (edgepixv + 10) 
    int hlineU[CBS],vlineU[CBS]; 
    int hlineV[CBS],vlineV[CBS]; 
    int x,y; 
    int uv;  
	int u0,v0; 
    int bx = (b4 &1)<<2; 
    int by = (b4>>1)<<2; 
    int img_cx = (mb_x << 3) + bx;    // block pel x 
    int img_cy = (mb_y << 3) + by;    // block pel y 
	  //MZ 
 
    int mb_available_up      = (pgImage->ipredmode[(mb_x<<2)+1][(mb_y<<2)]>=0); 
    int mb_available_left    = (pgImage->ipredmode[(mb_x<<2)][(mb_y<<2)+1] >=0);            /// can use frm 
    int mb_available_up_left = (pgImage->ipredmode[(mb_x<<2)][(mb_y<<2)] >=0); 
 
  
     
 
  //MZ 
/*	int	 mb_nr = pgImage->current_mb_nr; 
  int  mb_available_up   =  ((mb_y == 0) ? 0 : (pgcurrMB->slice_nr == mb_data[mb_nr-pgImage->width/16].slice_nr)); 
  int  mb_available_left =  ((mb_x == 0) ? 0 : (mb_data[mb_nr].slice_nr == mb_data[mb_nr-1].slice_nr)); 
	int  mb_available_up_left = ((mb_x == 0 || mb_y == 0) ? 0: (mb_data[mb_nr].slice_nr == mb_data[mb_nr-pgImage->width/16-1].slice_nr)); 
 */ 
   // 
  int block_available_up      = (b4 ==0||b4==1)?mb_available_up:1; 
  int block_available_left    = (b4 ==0||b4==2)?mb_available_left:1; 
	int block_available_up_left =  (b4==0) ? mb_available_up_left :  
	                              ((b4==1) ? mb_available_up :  
								                ((b4==2) ? mb_available_left : 1  )); 
    
     
    assert(b4>=0 && b4 <=3); 
    uv = 0; 
    if (block_available_up) 
    { 
        for(x=0;xpred_sample[4][b4][x][y] = u0; 
		pgcurrMB->pred_sample[5][b4][x][y] = v0;   
      } 
    } 
 
        break; 
    case HOR_PRED_8: 
        if (!block_available_left) 
            error("unexpected HOR_PRED_8 chroma intra prediction mode",-1); 
        for (y=0;ypred_sample[4][b4][x][y] = vlineU[y]; 
                pgcurrMB->pred_sample[5][b4][x][y] = vlineV[y]; 
            } 
        } 
        break; 
    case VERT_PRED_8: 
        if (!block_available_up) 
            error("unexpected VERT_PRED_8 chroma intra prediction mode",-1); 
        for (x=0;xpred_sample[4][b4][x][y] = hlineU[x]; 
                pgcurrMB->pred_sample[5][b4][x][y] = hlineV[x]; 
            } 
        } 
        break; 
 
    default: 
        error("intrapred_chroma_4x4:illegal chroma intra prediction mode", 600); 
        break; 
    } 
 
#if TRACE 
   for(y=0;y>1)<<2)+y][((b4 &1)<<2)+x] = pgcurrMB->pred_sample[4][b4][x][y]; 
		    MB_intrapred_UV[1][((b4>>1)<<2)+y][((b4 &1)<<2)+x] = pgcurrMB->pred_sample[5][b4][x][y]; 
		}     
#endif 
}