www.pudn.com > rm52c.rar > block.c
/* *********************************************************************** * COPYRIGHT AND WARRANTY INFORMATION * * Copyright 2003, 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. ************************************************************************ */ /* ************************************************************************************* * File name: block.c * Function: Description * ************************************************************************************* */ #include#include #include #include #include #include "defines.h" #include "global.h" #include "elements.h" #include "block.h" #include "vlc.h" #include "golomb_dec.h" unsigned short IQ_TAB[64] = { 32768,36061,38968,42495,46341,50535,55437,60424, 32932,35734,38968,42495,46177,50535,55109,59933, 65535,35734,38968,42577,46341,50617,55027,60097, 32809,35734,38968,42454,46382,50576,55109,60056, 65535,35734,38968,42495,46320,50515,55109,60076, 65535,35744,38968,42495,46341,50535,55099,60087, 65535,35734,38973,42500,46341,50535,55109,60097, 32771,35734,38965,42497,46341,50535,55109,60099 }; short IQ_SHIFT[64] = { 15,15,15,15,15,15,15,15, 14,14,14,14,14,14,14,14, 14,13,13,13,13,13,13,13, 12,12,12,12,12,12,12,12, 12,11,11,11,11,11,11,11, 11,10,10,10,10,10,10,10, 10,9,9,9,9,9,9,9, 8,8,8,8,8,8,8,8 }; #define EP (edgepixels+20) /* ************************************************************************* * Function:Inverse transform 8x8 block. * Input: * Output: * Return: * Attention:input curr_blk has to be [lines][pixels] ************************************************************************* */ void inv_transform_B8(int curr_blk1[B8_SIZE][B8_SIZE] // block to be inverse transformed. ) { short int xx, yy; short int tmp[8]; short int t; short int b[8]; short int curr_blk[8][8]; for(yy=0; yy<8; yy++) for(xx=0; xx<8; xx++) { curr_blk[yy][xx] = (short int)curr_blk1[yy][xx]; } for(yy=0; yy<8; yy++) { // Horizontal inverse transform // Reorder tmp[0]=curr_blk[yy][0]; tmp[1]=curr_blk[yy][4]; tmp[2]=curr_blk[yy][2]; tmp[3]=curr_blk[yy][6]; tmp[4]=curr_blk[yy][1]; tmp[5]=curr_blk[yy][3]; tmp[6]=curr_blk[yy][5]; tmp[7]=curr_blk[yy][7]; // Downleft Butterfly /*Lou Change*/ b[0] = ((tmp[4] - tmp[7])<<1) + tmp[4]; b[1] = ((tmp[5] + tmp[6])<<1) + tmp[5]; b[2] = ((tmp[5] - tmp[6])<<1) - tmp[6]; b[3] = ((tmp[4] + tmp[7])<<1) + tmp[7]; b[4] = ((b[0] + b[1] + b[3])<<1) + b[1]; b[5] = ((b[0] - b[1] + b[2])<<1) + b[0]; b[6] = ((-b[1] - b[2] + b[3])<<1) + b[3]; b[7] = ((b[0] - b[2] - b[3])<<1) - b[2]; /*Lou End*/ // Upleft Butterfly /*Lou Change*/ t=((tmp[2]*10)+(tmp[3]<<2)); tmp[3]=((tmp[2]<<2)-(tmp[3]*10)); tmp[2]=t; t=(tmp[0]+tmp[1])<<3; tmp[1]=(tmp[0]-tmp[1])<<3; tmp[0]=t; /*Lou End*/ b[0]=tmp[0]+tmp[2]; b[1]=tmp[1]+tmp[3]; b[2]=tmp[1]-tmp[3]; b[3]=tmp[0]-tmp[2]; // Last Butterfly /*Lou Change*/ curr_blk[yy][0]=((b[0]+b[4])+(1<<2))>>3; curr_blk[yy][1]=((b[1]+b[5])+(1<<2))>>3; curr_blk[yy][2]=((b[2]+b[6])+(1<<2))>>3; curr_blk[yy][3]=((b[3]+b[7])+(1<<2))>>3; curr_blk[yy][7]=((b[0]-b[4])+(1<<2))>>3; curr_blk[yy][6]=((b[1]-b[5])+(1<<2))>>3; curr_blk[yy][5]=((b[2]-b[6])+(1<<2))>>3; curr_blk[yy][4]=((b[3]-b[7])+(1<<2))>>3; /*Lou End*/ } // Vertical inverse transform for(xx=0; xx<8; xx++) { // Reorder tmp[0]=curr_blk[0][xx]; tmp[1]=curr_blk[4][xx]; tmp[2]=curr_blk[2][xx]; tmp[3]=curr_blk[6][xx]; tmp[4]=curr_blk[1][xx]; tmp[5]=curr_blk[3][xx]; tmp[6]=curr_blk[5][xx]; tmp[7]=curr_blk[7][xx]; // Downleft Butterfly /*Lou Change*/ b[0] = ((tmp[4] - tmp[7])<<1) + tmp[4]; b[1] = ((tmp[5] + tmp[6])<<1) + tmp[5]; b[2] = ((tmp[5] - tmp[6])<<1) - tmp[6]; b[3] = ((tmp[4] + tmp[7])<<1) + tmp[7]; b[4] = ((b[0] + b[1] + b[3])<<1) + b[1]; b[5] = ((b[0] - b[1] + b[2])<<1) + b[0]; b[6] = ((-b[1] - b[2] + b[3])<<1) + b[3]; b[7] = ((b[0] - b[2] - b[3])<<1) - b[2]; /*Lou End*/ // Upleft Butterfly /*Lou Change*/ t=((tmp[2]*10)+(tmp[3]<<2)); tmp[3]=((tmp[2]<<2)-(tmp[3]*10)); tmp[2]=t; t=(tmp[0]+tmp[1])<<3; tmp[1]=(tmp[0]-tmp[1])<<3; tmp[0]=t; /*Lou End*/ b[0]=tmp[0]+tmp[2]; b[1]=tmp[1]+tmp[3]; b[2]=tmp[1]-tmp[3]; b[3]=tmp[0]-tmp[2]; // Last Butterfly // Last Butterfly curr_blk[0][xx]=/*(b[0]+b[4]+64)>>7;*/(Clip3(-32768,32703,b[0]+b[4])+64)>>7; curr_blk[1][xx]=/*(b[1]+b[5]+64)>>7;*/(Clip3(-32768,32703,b[1]+b[5])+64)>>7; curr_blk[2][xx]=/*(b[2]+b[6]+64)>>7;*/(Clip3(-32768,32703,b[2]+b[6])+64)>>7; curr_blk[3][xx]=/*(b[3]+b[7]+64)>>7;*/(Clip3(-32768,32703,b[3]+b[7])+64)>>7; curr_blk[7][xx]=/*(b[0]-b[4]+64)>>7;*/(Clip3(-32768,32703,b[0]-b[4])+64)>>7; curr_blk[6][xx]=/*(b[1]-b[5]+64)>>7;*/(Clip3(-32768,32703,b[1]-b[5])+64)>>7; curr_blk[5][xx]=/*(b[2]-b[6]+64)>>7;*/(Clip3(-32768,32703,b[2]-b[6])+64)>>7; curr_blk[4][xx]=/*(b[3]-b[7]+64)>>7;*/(Clip3(-32768,32703,b[3]-b[7])+64)>>7; if((b[0]+b[4])<=-32768 || (b[0]+b[4])>=(32768-65 )) printf("error\n"); if((b[1]+b[5])<=-32768 || (b[1]+b[5])>=(32768-65 )) printf("error\n"); if((b[2]+b[6])<=-32768 || (b[2]+b[6])>=(32768-65 )) printf("error\n"); if((b[3]+b[7])<=-32768 || (b[3]+b[7])>=(32768-65 )) printf("error\n"); if((b[0]-b[4])<=-32768 || (b[0]-b[4])>=(32768-65 )) printf("error\n"); if((b[1]-b[5])<=-32768 || (b[1]-b[5])>=(32768-65 )) printf("error\n"); if((b[2]-b[6])<=-32768 || (b[2]-b[6])>=(32768-65 )) printf("error\n"); if((b[3]-b[7])<=-32768 || (b[3]-b[7])>=(32768-65 )) printf("error\n"); } for(yy=0; yy<8; yy++) for(xx=0; xx<8; xx++) { curr_blk1[yy][xx] = curr_blk[yy][xx]; } } void idct_dequant_B8(int block8x8, int qp, // Quantization parameter int curr_blk[B8_SIZE][B8_SIZE], struct img_par *img ) { int xx,yy; int b8_y = (block8x8 / 2) << 3; int b8_x = (block8x8 % 2) << 3; int curr_val; // inverse transform inv_transform_B8(curr_blk); // normalize for(yy=0;yy<8;yy++) for(xx=0;xx<8;xx++) { if(block8x8 <= 3) curr_val = img->mpr[b8_x+xx][b8_y+yy] + curr_blk[yy][xx]; else curr_val = img->mpr[xx][yy] + curr_blk[yy][xx]; img->m7[xx][yy] = curr_blk[yy][xx] = clamp(curr_val,0,255); if(block8x8 <= 3) imgY[img->pix_y+b8_y+yy][img->pix_x+b8_x+xx] = curr_blk[yy][xx]; else imgUV[block8x8-4][img->pix_c_y+yy][img->pix_c_x+xx] = curr_blk[yy][xx]; } } /* ************************************************************************* * Function: * Input: * Output: * Return: * Attention: ************************************************************************* */ void reconstruct8x8(int curr_blk[8][8],int block8x8) { int yy,xx,block_y, block_x; int incr_y=1,off_y=0; Macroblock *currMB = &mb_data[img->current_mb_nr];//GB current_mb_nr]; if(block8x8<4) { block_y = (block8x8/2)*8; block_x = (block8x8%2)*8; for(yy=0;yy<8;yy++) { for(xx=0;xx<8;xx++) { imgY[img->pix_y+block_y+incr_y*yy+off_y][img->pix_x+block_x+xx] = curr_blk[yy][xx]; } } } else { for(yy=0;yy<8;yy++) { for(xx=0;xx<8;xx++) { imgUV[block8x8-4][img->pix_c_y+yy][img->pix_c_x+xx] = curr_blk[yy][xx]; } } } } /* ************************************************************************* * Function:Read coefficients of one 8x8 block * Input: * Output: * Return: * Attention: ************************************************************************* */ void readLumaCoeff_B8(int block8x8, struct inp_par *inp, struct img_par *img) { int i; int mb_nr = img->current_mb_nr; Macroblock *currMB = &mb_data[mb_nr]; const int cbp = currMB->cbp; SyntaxElement currSE; int intra; int inumblk; /* number of blocks per CBP*/ int inumcoeff; /* number of coeffs per block */ int icoef; /* current coefficient */ int ipos; int run, level; int ii,jj; int sbx, sby; int boff_x, boff_y; int any_coeff; int vlc_numcoef; int cbp_blk_mask; int tablenum; //add by qwang static const int incVlc_intra[7] = { 0,1,2,4,7,10,3000}; //qwang 11.29 static const int incVlc_inter[7] = { 0,1,2,3,6,9,3000}; //qwang 11.29 int buffer_level[65]; //add by qwang int buffer_run[64]; //add by qwang int EOB_Pos_intra[7] = { -1, 8, 8, 8, 6, 0, 0}; //qwang 11.29 int EOB_Pos_inter[7] = {-1, 2, 2, 2, 2, 0, 0}; //qwang 11.29 char (*AVS_VLC_table_intra)[64][2]; //qwang 11.29 char (*AVS_VLC_table_inter)[64][2]; //qwang 11.29 int symbol2D,Golomb_se_type; const char (*table2D)[27]; //digipro_1 float QP99; long sum; int shift = 7; //digipro_0 int val, QPI; int qp, q_shift, R[4][4]; // dequantization parameters static const int blkmode2ctx [4] = {LUMA_8x8, LUMA_8x4, LUMA_4x8, LUMA_4x4}; // this has to be done for each subblock seperately intra = IS_INTRA(currMB); inumblk = 1; inumcoeff = 65; // all positions + EOB // ========= dequantization values =========== qp = currMB->qp; // using old style qp. q_shift = qp/QUANT_PERIOD; QP99 = pow(2.0, (float)(qp-5.0)/8.0); for (shift=1; shift<16; shift++) { QPI = (int)((1< (1<<16)) { shift -=1; QPI = (int)((1< =0) { if(i==0) { AVS_2DVLC_INTRA_dec[i][ipos][0]=level+1; AVS_2DVLC_INTRA_dec[i][ipos][1]=run; AVS_2DVLC_INTRA_dec[i][ipos+1][0]=-(level+1); AVS_2DVLC_INTRA_dec[i][ipos+1][1]=run; } else { AVS_2DVLC_INTRA_dec[i][ipos][0]=level; AVS_2DVLC_INTRA_dec[i][ipos][1]=run; if(level) { AVS_2DVLC_INTRA_dec[i][ipos+1][0]=-(level); AVS_2DVLC_INTRA_dec[i][ipos+1][1]=run; } } } } } assert(AVS_2DVLC_INTRA_dec[0][0][1]>=0); //otherwise, tables are bad. } //make decoder table for 2DVLC_INTER code if(AVS_2DVLC_INTER_dec[0][0][1]<0) // Don't need to set this every time. rewrite later. { memset(AVS_2DVLC_INTER_dec,-1,sizeof(AVS_2DVLC_INTER_dec)); for(i=0;i<7;i++) { table2D=AVS_2DVLC_INTER[i]; for(run=0;run<26;run++) for(level=0;level<27;level++) { ipos=table2D[run][level]; assert(ipos<64); if(ipos>=0) { if(i==0) { AVS_2DVLC_INTER_dec[i][ipos][0]=level+1; AVS_2DVLC_INTER_dec[i][ipos][1]=run; AVS_2DVLC_INTER_dec[i][ipos+1][0]=-(level+1); AVS_2DVLC_INTER_dec[i][ipos+1][1]=run; } else { AVS_2DVLC_INTER_dec[i][ipos][0]=level; AVS_2DVLC_INTER_dec[i][ipos][1]=run; if(level) { AVS_2DVLC_INTER_dec[i][ipos+1][0]=-(level); AVS_2DVLC_INTER_dec[i][ipos+1][1]=run; } } } } } assert(AVS_2DVLC_INTER_dec[0][0][1]>=0); //otherwise, tables are bad. } //clear cbp_blk bits of thie 8x8 block (and not all 4!) cbp_blk_mask = cbp_blk_masks[0] ; if(block8x8&1)cbp_blk_mask<<=2; if(block8x8&2)cbp_blk_mask<<=8; currMB->cbp_blk&=~cbp_blk_mask; vlc_numcoef=-1; Golomb_se_type=SE_LUM_AC_INTER; if( intra ) { vlc_numcoef=0; //this means 'use numcoeffs symbol'. Golomb_se_type=SE_LUM_AC_INTRA; } AVS_VLC_table_intra = AVS_2DVLC_INTRA_dec; AVS_VLC_table_inter = AVS_2DVLC_INTER_dec; // === decoding === if ( cbp & (1< subblock_x = boff_x>>2; img->subblock_y = boff_y>>2; ipos = -1; any_coeff=1; //modified by qwang any_coeff=0 if(intra) { tablenum = 0; for(i=0; i >1; //decode level currSE.type=Golomb_se_type; currSE.golomb_grad = 1; currSE.golomb_maxlevels=11; readSyntaxElement_GOLOMB(&currSE,img,inp); level = currSE.value1 + ((run>MaxRun[0][tablenum])?1:RefAbsLevel[tablenum][run]); // if( (symbol2D-CODE2D_ESCAPE_SYMBOL) & 1 ) if(symbol2D & 1) // jlzheng 7.20 level=-level; } // 保存level,run到缓冲区 buffer_level[i] = level; buffer_run[i] = run; if(abs(level) > incVlc_intra[tablenum]) //qwang 11.29 { if(abs(level) <= 2) tablenum = abs(level); else if(abs(level) <= 4) tablenum = 3; else if(abs(level) <= 7) tablenum = 4; else if(abs(level) <= 10) tablenum = 5; else tablenum = 6; } }//loop for icoef //将解码的level,run写到img->m7[][]; for(i=(vlc_numcoef-1); i>=0; i--) { ipos += (buffer_run[i]+1); ii = SCAN[img->picture_structure][ipos][0]; jj = SCAN[img->picture_structure][ipos][1]; shift = IQ_SHIFT[qp]; QPI = IQ_TAB[qp]; val = buffer_level[i]; sum = (val*QPI+(1<<(shift-2)) )>>(shift-1); img->m7[boff_x + ii][boff_y + jj] = sum; } }//if (intra) else { tablenum = 0; for(i=0; i >1; //decode level currSE.type=Golomb_se_type; currSE.golomb_grad = 0; currSE.golomb_maxlevels=11; readSyntaxElement_GOLOMB(&currSE,img,inp); level = currSE.value1 + ((run>MaxRun[1][tablenum])?1:RefAbsLevel[tablenum+7][run]); if(symbol2D & 1) //jlzheng 7.20 level=-level; } // 保存level,run到缓冲区 buffer_level[i] = level; buffer_run[i] = run; if(abs(level) > incVlc_inter[tablenum]) //qwang 11.29 { if(abs(level) <= 3) tablenum = abs(level); else if(abs(level) <= 6) tablenum = 4; else if(abs(level) <= 9) tablenum = 5; else tablenum = 6; } }//loop for icoef //将解码的level,run写到img->m7[][]; for(i=(vlc_numcoef-1); i>=0; i--) { ipos += (buffer_run[i]+1); ii = SCAN[img->picture_structure][ipos][0]; jj = SCAN[img->picture_structure][ipos][1]; shift = IQ_SHIFT[qp]; QPI = IQ_TAB[qp]; val = buffer_level[i]; sum = (val*QPI+(1<<(shift-2)) )>>(shift-1); img->m7[boff_x + ii][boff_y + jj] = sum; } } icoef = vlc_numcoef; // CAVLC store number of coefficients sbx = img->subblock_x; sby = img->subblock_y; //add by qwang //CA_ABT store number of coefficients sbx = ((block8x8%2)==0) ? 0:1; sby = block8x8>1 ? 1:0; if(any_coeff) { cbp_blk_mask = cbp_blk_masks[ ((boff_y&4)>>1)|((boff_x&4)>>2) ] ; if(block8x8&1)cbp_blk_mask<<=2; if(block8x8&2)cbp_blk_mask<<=8; currMB->cbp_blk |= cbp_blk_mask; } }//end if ( cbp & (1< current_mb_nr; Macroblock *currMB = &mb_data[mb_nr]; const int cbp = currMB->cbp; SyntaxElement currSE; unsigned int is_last_levelrun; int intra; int inumblk; /* number of blocks per CBP*/ int inumcoeff; /* number of coeffs per block */ int ipos; int run, level; int ii,jj,i; int sbx, sby; int boff_x, boff_y; int any_coeff; int vlc_numcoef; int tablenum; //add by qwang int buffer_level[65]; //add by qwang int buffer_run[64]; //add by qwang static const int incVlc_chroma[5] = {0,1,2,4,3000}; //qwang 11.29 int EOB_Pos_chroma[2][5] = { {-1, 4, 8, 6, 4}, {-1, 0, 2, 0, 0} }; //qwang 11.29 char (*AVS_VLC_table_chroma)[64][2]; //qwang 11.29 int symbol2D,Golomb_se_type; const char (*table2D)[27]; float QP99; int QPI; int shift = 7; int val, temp; int R[4][4]; // dequantization parameters static const int blkmode2ctx [4] = {LUMA_8x8, LUMA_8x4, LUMA_4x8, LUMA_4x4}; int q_bits; int qp_chroma = QP_SCALE_CR[currMB->qp]; // using old style qp. //digipro_1 QP99 = pow(2.0, (float)(qp_chroma-5)/8.0); for (shift=1; shift<16; shift++) { QPI = (int)((1< (1<<16)) { shift -=1; QPI = (int)((1< =0) { if(i==0) { AVS_2DVLC_CHROMA_dec[i][ipos][0]=level+1; AVS_2DVLC_CHROMA_dec[i][ipos][1]=run; AVS_2DVLC_CHROMA_dec[i][ipos+1][0]=-(level+1); AVS_2DVLC_CHROMA_dec[i][ipos+1][1]=run; } else { AVS_2DVLC_CHROMA_dec[i][ipos][0]=level; AVS_2DVLC_CHROMA_dec[i][ipos][1]=run; if(level) { AVS_2DVLC_CHROMA_dec[i][ipos+1][0]=-(level); AVS_2DVLC_CHROMA_dec[i][ipos+1][1]=run; } } } } } assert(AVS_2DVLC_CHROMA_dec[0][0][1]>=0); //otherwise, tables are bad. } //clear cbp_blk bits of thie 8x8 block (and not all 4!) vlc_numcoef=-1; Golomb_se_type=SE_LUM_AC_INTER; if( intra ) { vlc_numcoef=0; //this means 'use numcoeffs symbol'. Golomb_se_type=SE_LUM_AC_INTRA; } AVS_VLC_table_chroma = AVS_2DVLC_CHROMA_dec; // === set offset in current macroblock === boff_x = ( (block8x8%2)<<3 ); boff_y = ( (block8x8/2)<<3 ); img->subblock_x = boff_x>>2; img->subblock_y = boff_y>>2; ipos = -1; any_coeff=1; is_last_levelrun=0; tablenum = 0; for(i=0; i >1; //decode level currSE.type=Golomb_se_type; currSE.golomb_grad = 0; currSE.golomb_maxlevels=11; readSyntaxElement_GOLOMB(&currSE,img,inp); level = currSE.value1 + ((run>MaxRun[2][tablenum])?1:RefAbsLevel[tablenum+14][run]); // if( (symbol2D-CODE2D_ESCAPE_SYMBOL) & 1 ) if(symbol2D & 1) // jlzheng 7.20 level=-level; } // 保存level,run到缓冲区 buffer_level[i] = level; buffer_run[i] = run; if(abs(level) > incVlc_chroma[tablenum]) //qwang 11.29 { if(abs(level) <= 2) tablenum = abs(level); else if(abs(level) <= 4) tablenum = 3; else tablenum = 4; } }//loop for icoef //将解码的level,run写到img->m7[][]; for(i=(vlc_numcoef-1); i>=0; i--) { ipos += (buffer_run[i]+1); ii = SCAN[img->picture_structure][ipos][0]; jj = SCAN[img->picture_structure][ipos][1]; shift = IQ_SHIFT[qp_chroma]; QPI = IQ_TAB[qp_chroma]; val = buffer_level[i]; temp = (val*QPI+(1<<(shift-2)) )>>(shift-1); img->m8[block8x8-4][ii][jj] = temp; } // CAVLC store number of coefficients sbx = img->subblock_x; sby = img->subblock_y; sbx = (img->subblock_x == 2) ? 1:0; if(any_coeff) { currMB->cbp_blk |= 0xf0000 << ((block8x8-4) << 2); } } /* ************************************************************************* * Function:Copy region of img->m7 corresponding to block8x8 to curr_blk[][]. * Input: * Output: * Return: * Attention:img->m7 is [x][y] and curr_blk is [y][x]. ************************************************************************* */ void get_curr_blk( int block8x8,struct img_par *img, int curr_blk[B8_SIZE][B8_SIZE]) { int xx, yy; int mb_y = (block8x8 / 2) << 3; int mb_x = (block8x8 % 2) << 3; Macroblock *currMB = &mb_data[img->current_mb_nr];/*lgp*/ for (yy=0; yy m7[mb_x+xx][mb_y+yy]; else curr_blk[yy][xx] = img->m8[block8x8-4][xx][yy]; } /* ************************************************************************* * Function:Make Intra prediction for all 9 modes for larger blocks than 4*4, that is for 4*8, 8*4 and 8*8 blocks. bs_x and bs_y may be only 4 and 8. img_x and img_y are pixels offsets in the picture. * Input: * Output: * Return: * Attention: ************************************************************************* */ int intrapred(struct img_par *img,int img_x,int img_y) { unsigned char edgepixels[40]; int x,y,last_pix,new_pix; unsigned int x_off,y_off; int i,predmode; int b4_x,b4_y; int b4,b8,mb; int block_available_up,block_available_up_right; int block_available_left,block_available_left_down; int bs_x,bs_y; int b8_x,b8_y; Macroblock *currMB = &mb_data[img->current_mb_nr];/*lgp*/ int MBRowSize = img->width / MB_BLOCK_SIZE;/*lgp*/ int off_up=1,incr_y=1,off_y=0; /*lgp*/ b8_x=img_x>>3; b8_y=img_y>>3; bs_x = bs_y = 8; x_off=img_x&0x0FU; y_off=img_y&0x0FU; #ifdef USE_6_INTRA_MODES assert(0); //not supported (could be added) #endif predmode = img->ipredmode[img_x/(2*BLOCK_SIZE)+1][img_y/(2*BLOCK_SIZE)+1]; assert(predmode>=0); { b4_x=img_x>>2; b4_y=img_y>>2; mb=(b4_x>>2)+(b4_y>>2)*(img->width>>2); b8=((b4_x&2)>>1)|(b4_y&2); b4=(b4_x&1)|((b4_y&1)<<1); //check block up block_available_up=( b8_y-1>=0 && img->ipredmode[1+b8_x][1+b8_y-1]>=0); //check block up right block_available_up_right=( b8_x+1<(img->width>>3) && b8_y-1>=0 && img->ipredmode[1+b8_x+1][1+b8_y-1]>=0); //check block left block_available_left=( b8_x - 1 >=0 && img->ipredmode[1+b8_x - 1][1+b8_y]>=0); //check block left down block_available_left_down=( b8_x - 1>=0 && b8_y + 1 < (img->height>>3) && img->ipredmode[1+b8_x-1][1+b8_y+1]>=0); if( ((img_x/8)%2) && ((img_y/8)%2)) block_available_up_right=0; if( ((img_x/8)%2) || ((img_y/8)%2)) block_available_left_down=0; //get prediciton pixels if(block_available_up) { for(x=0;x >2; last_pix=EP[i]; EP[i]=(unsigned char)new_pix; } } switch(predmode) { case DC_PRED:// 0 DC if(!block_available_up && !block_available_left) for(y=0UL;y mpr[x+x_off][y+y_off]=128UL; if(block_available_up && !block_available_left) for(y=0UL;y mpr[x+x_off][y+y_off]=EP[1+x]; if(!block_available_up && block_available_left) for(y=0UL;y mpr[x+x_off][y+y_off]=EP[-1-y]; if(block_available_up && block_available_left) for(y=0UL;y mpr[x+x_off][y+y_off]=(EP[1+x]+EP[-1-y])>>1; break; case VERT_PRED:// 1 vertical if(!block_available_up) printf("!!invalid intrapred mode %d!! %d \n",predmode, img->current_mb_nr); for(y=0UL;y mpr[x+x_off][y+y_off]=imgY[img_y-1][img_x+x]; break; case HOR_PRED:// 2 horizontal if(!block_available_left) printf("!!invalid intrapred mode %d!! %d \n",predmode, img->current_mb_nr); for(y=0UL;y mpr[x+x_off][y+y_off]=imgY[img_y+y][img_x-1]; break; case DOWN_RIGHT_PRED:// 3 down-right if(!block_available_left||!block_available_up) printf("!!invalid intrapred mode %d!! %d \n",predmode, img->current_mb_nr); for(y=0UL;y mpr[x+x_off][y+y_off]=EP[(int)x-(int)y]; break; case DOWN_LEFT_PRED:// 4 up-right bidirectional if(!block_available_left||!block_available_up) printf("!!invalid intrapred mode %d!! %d \n",predmode, img->current_mb_nr); for(y=0UL;y mpr[x+x_off][y+y_off]=(EP[2+x+y]+EP[-2-(int)(x+y)])>>1; break; }//end switch predmode return DECODING_OK; }