00001
00015 #include "global.h"
00016 #include "intra4x4_pred.h"
00017 #include "mb_access.h"
00018 #include "image.h"
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #define P_X (PredPel[0])
00033 #define P_A (PredPel[1])
00034 #define P_B (PredPel[2])
00035 #define P_C (PredPel[3])
00036 #define P_D (PredPel[4])
00037 #define P_E (PredPel[5])
00038 #define P_F (PredPel[6])
00039 #define P_G (PredPel[7])
00040 #define P_H (PredPel[8])
00041 #define P_I (PredPel[9])
00042 #define P_J (PredPel[10])
00043 #define P_K (PredPel[11])
00044 #define P_L (PredPel[12])
00045
00046
00065 static inline int intra4x4_dc_pred(Macroblock *currMB,
00066 ColorPlane pl,
00067 int ioff,
00068 int joff)
00069 {
00070 Slice *currSlice = currMB->p_Slice;
00071 ImageParameters *p_Img = currMB->p_Img;
00072
00073 int i,j;
00074 int s0 = 0;
00075 imgpel **imgY = (pl) ? p_Img->dec_picture->imgUV[pl - 1] : p_Img->dec_picture->imgY;
00076
00077 PixelPos pix_a[4], pix_b;
00078
00079 int block_available_up;
00080 int block_available_left;
00081
00082 imgpel **mb_pred = currSlice->mb_pred[pl];
00083
00084 for (i=0;i<4;++i)
00085 {
00086 p_Img->getNeighbour(currMB, ioff - 1, joff + i, p_Img->mb_size[IS_LUMA], &pix_a[i]);
00087 }
00088 p_Img->getNeighbour(currMB, ioff , joff -1 , p_Img->mb_size[IS_LUMA], &pix_b);
00089
00090 if (p_Img->active_pps->constrained_intra_pred_flag)
00091 {
00092 for (i=0, block_available_left=1; i<4;++i)
00093 block_available_left &= pix_a[i].available ? p_Img->intra_block[pix_a[i].mb_addr]: 0;
00094 block_available_up = pix_b.available ? p_Img->intra_block [pix_b.mb_addr] : 0;
00095 }
00096 else
00097 {
00098 block_available_left = pix_a[0].available;
00099 block_available_up = pix_b.available;
00100 }
00101
00102
00103 if (block_available_up)
00104 {
00105 s0 += imgY[pix_b.pos_y][pix_b.pos_x + 0];
00106 s0 += imgY[pix_b.pos_y][pix_b.pos_x + 1];
00107 s0 += imgY[pix_b.pos_y][pix_b.pos_x + 2];
00108 s0 += imgY[pix_b.pos_y][pix_b.pos_x + 3];
00109 }
00110
00111 if (block_available_left)
00112 {
00113 s0 += imgY[pix_a[0].pos_y][pix_a[0].pos_x];
00114 s0 += imgY[pix_a[1].pos_y][pix_a[1].pos_x];
00115 s0 += imgY[pix_a[2].pos_y][pix_a[2].pos_x];
00116 s0 += imgY[pix_a[3].pos_y][pix_a[3].pos_x];
00117 }
00118
00119 if (block_available_up && block_available_left)
00120 {
00121
00122 s0 = (s0 + 4)>>3;
00123 }
00124 else if (!block_available_up && block_available_left)
00125 {
00126
00127 s0 = (s0 + 2)>>2;
00128 }
00129 else if (block_available_up && !block_available_left)
00130 {
00131
00132 s0 = (s0 + 2)>>2;
00133 }
00134 else
00135 {
00136
00137 s0 = p_Img->dc_pred_value_comp[pl];
00138 }
00139
00140 for (j=joff; j < joff + BLOCK_SIZE; ++j)
00141 {
00142 for (i=ioff; i < ioff + BLOCK_SIZE; ++i)
00143 {
00144
00145 mb_pred[j][i] = (imgpel) s0;
00146 }
00147 }
00148 return DECODING_OK;
00149 }
00150
00161 static inline int intra4x4_vert_pred(Macroblock *currMB,
00162 ColorPlane pl,
00163 int ioff,
00164 int joff)
00165 {
00166 Slice *currSlice = currMB->p_Slice;
00167 ImageParameters *p_Img = currMB->p_Img;
00168
00169 int j;
00170 imgpel **imgY = (pl) ? p_Img->dec_picture->imgUV[pl - 1] : p_Img->dec_picture->imgY;
00171
00172 int block_available_up;
00173
00174 PixelPos pix_b;
00175
00176 imgpel **mb_pred = currSlice->mb_pred[pl];
00177
00178 p_Img->getNeighbour(currMB, ioff, joff - 1 , p_Img->mb_size[IS_LUMA], &pix_b);
00179
00180 if (p_Img->active_pps->constrained_intra_pred_flag)
00181 {
00182 block_available_up = pix_b.available ? p_Img->intra_block [pix_b.mb_addr] : 0;
00183 }
00184 else
00185 {
00186 block_available_up = pix_b.available;
00187 }
00188
00189 if (!block_available_up)
00190 printf ("warning: Intra_4x4_Vertical prediction mode not allowed at mb %d\n", (int) p_Img->current_mb_nr);
00191
00192 for(j = joff; j < joff + BLOCK_SIZE; ++j)
00193 memcpy(&(mb_pred[j][ioff]), &(imgY[pix_b.pos_y][pix_b.pos_x]), BLOCK_SIZE * sizeof(imgpel));
00194
00195 return DECODING_OK;
00196 }
00197
00217 static inline int intra4x4_hor_pred(Macroblock *currMB,
00218 ColorPlane pl,
00219 int ioff,
00220 int joff)
00221 {
00222 ImageParameters *p_Img = currMB->p_Img;
00223 Slice *currSlice = currMB->p_Slice;
00224
00225 int i,j;
00226 imgpel **imgY = (pl) ? p_Img->dec_picture->imgUV[pl - 1] : p_Img->dec_picture->imgY;
00227
00228 PixelPos pix_a[4];
00229
00230 int block_available_left;
00231
00232 imgpel *predrow, prediction, **mb_pred = currSlice->mb_pred[pl];
00233
00234 for (i=0;i<4;++i)
00235 {
00236 p_Img->getNeighbour(currMB, ioff -1 , joff +i , p_Img->mb_size[IS_LUMA], &pix_a[i]);
00237 }
00238
00239 if (p_Img->active_pps->constrained_intra_pred_flag)
00240 {
00241 for (i=0, block_available_left=1; i<4;++i)
00242 block_available_left &= pix_a[i].available ? p_Img->intra_block[pix_a[i].mb_addr]: 0;
00243 }
00244 else
00245 {
00246 block_available_left = pix_a[0].available;
00247 }
00248
00249 if (!block_available_left)
00250 printf ("warning: Intra_4x4_Horizontal prediction mode not allowed at mb %d\n",(int) p_Img->current_mb_nr);
00251
00252 for(j=0;j<BLOCK_SIZE;++j)
00253 {
00254 predrow = mb_pred[j+joff];
00255 prediction = imgY[pix_a[j].pos_y][pix_a[j].pos_x];
00256 for(i = ioff;i < ioff + BLOCK_SIZE;++i)
00257 predrow[i]= prediction;
00258 }
00259
00260 return DECODING_OK;
00261 }
00262
00273 static inline int intra4x4_diag_down_right_pred(Macroblock *currMB,
00274 ColorPlane pl,
00275 int ioff,
00276 int joff)
00277 {
00278 Slice *currSlice = currMB->p_Slice;
00279 ImageParameters *p_Img = currMB->p_Img;
00280
00281 int i;
00282 imgpel PredPel[13];
00283 imgpel **imgY = (pl) ? p_Img->dec_picture->imgUV[pl - 1] : p_Img->dec_picture->imgY;
00284
00285 PixelPos pix_a[4];
00286 PixelPos pix_b, pix_d;
00287
00288 int block_available_up;
00289 int block_available_left;
00290 int block_available_up_left;
00291
00292 int jpos0 = joff, jpos1 = joff + 1, jpos2 = joff + 2, jpos3 = joff + 3;
00293 int ipos0 = ioff, ipos1 = ioff + 1, ipos2 = ioff + 2, ipos3 = ioff + 3;
00294 imgpel **mb_pred = currSlice->mb_pred[pl];
00295
00296 for (i=0;i<4;++i)
00297 {
00298 p_Img->getNeighbour(currMB, ioff -1 , joff +i , p_Img->mb_size[IS_LUMA], &pix_a[i]);
00299 }
00300
00301 p_Img->getNeighbour(currMB, ioff , joff -1 , p_Img->mb_size[IS_LUMA], &pix_b);
00302 p_Img->getNeighbour(currMB, ioff -1 , joff -1 , p_Img->mb_size[IS_LUMA], &pix_d);
00303
00304 if (p_Img->active_pps->constrained_intra_pred_flag)
00305 {
00306 for (i=0, block_available_left=1; i<4;++i)
00307 block_available_left &= pix_a[i].available ? p_Img->intra_block[pix_a[i].mb_addr]: 0;
00308 block_available_up = pix_b.available ? p_Img->intra_block [pix_b.mb_addr] : 0;
00309 block_available_up_left = pix_d.available ? p_Img->intra_block [pix_d.mb_addr] : 0;
00310 }
00311 else
00312 {
00313 block_available_left = pix_a[0].available;
00314 block_available_up = pix_b.available;
00315 block_available_up_left = pix_d.available;
00316 }
00317
00318 if ((!block_available_up)||(!block_available_left)||(!block_available_up_left))
00319 printf ("warning: Intra_4x4_Diagonal_Down_Right prediction mode not allowed at mb %d\n",(int) p_Img->current_mb_nr);
00320
00321
00322 P_A = imgY[pix_b.pos_y][pix_b.pos_x + 0];
00323 P_B = imgY[pix_b.pos_y][pix_b.pos_x + 1];
00324 P_C = imgY[pix_b.pos_y][pix_b.pos_x + 2];
00325 P_D = imgY[pix_b.pos_y][pix_b.pos_x + 3];
00326
00327 P_I = imgY[pix_a[0].pos_y][pix_a[0].pos_x];
00328 P_J = imgY[pix_a[1].pos_y][pix_a[1].pos_x];
00329 P_K = imgY[pix_a[2].pos_y][pix_a[2].pos_x];
00330 P_L = imgY[pix_a[3].pos_y][pix_a[3].pos_x];
00331
00332 P_X = imgY[pix_d.pos_y][pix_d.pos_x];
00333
00334 mb_pred[jpos3][ipos0] = (imgpel) ((P_L + 2*P_K + P_J + 2) >> 2);
00335 mb_pred[jpos2][ipos0] =
00336 mb_pred[jpos3][ipos1] = (imgpel) ((P_K + 2*P_J + P_I + 2) >> 2);
00337 mb_pred[jpos1][ipos0] =
00338 mb_pred[jpos2][ipos1] =
00339 mb_pred[jpos3][ipos2] = (imgpel) ((P_J + 2*P_I + P_X + 2) >> 2);
00340 mb_pred[jpos0][ipos0] =
00341 mb_pred[jpos1][ipos1] =
00342 mb_pred[jpos2][ipos2] =
00343 mb_pred[jpos3][ipos3] = (imgpel) ((P_I + 2*P_X + P_A + 2) >> 2);
00344 mb_pred[jpos0][ipos1] =
00345 mb_pred[jpos1][ipos2] =
00346 mb_pred[jpos2][ipos3] = (imgpel) ((P_X + 2*P_A + P_B + 2) >> 2);
00347 mb_pred[jpos0][ipos2] =
00348 mb_pred[jpos1][ipos3] = (imgpel) ((P_A + 2*P_B + P_C + 2) >> 2);
00349 mb_pred[jpos0][ipos3] = (imgpel) ((P_B + 2*P_C + P_D + 2) >> 2);
00350
00351 return DECODING_OK;
00352 }
00353
00364 static inline int intra4x4_diag_down_left_pred(Macroblock *currMB,
00365 ColorPlane pl,
00366 int ioff,
00367 int joff)
00368 {
00369 Slice *currSlice = currMB->p_Slice;
00370 ImageParameters *p_Img = currMB->p_Img;
00371
00372 imgpel PredPel[13];
00373 imgpel **imgY = (pl) ? p_Img->dec_picture->imgUV[pl - 1] : p_Img->dec_picture->imgY;
00374
00375 PixelPos pix_b, pix_c;
00376
00377 int block_available_up;
00378 int block_available_up_right;
00379
00380 int jpos0 = joff, jpos1 = joff + 1, jpos2 = joff + 2, jpos3 = joff + 3;
00381 int ipos0 = ioff, ipos1 = ioff + 1, ipos2 = ioff + 2, ipos3 = ioff + 3;
00382 imgpel **mb_pred = currSlice->mb_pred[pl];
00383
00384 p_Img->getNeighbour(currMB, ioff , joff - 1, p_Img->mb_size[IS_LUMA], &pix_b);
00385 p_Img->getNeighbour(currMB, ioff + 4, joff - 1, p_Img->mb_size[IS_LUMA], &pix_c);
00386
00387 pix_c.available = pix_c.available && !((ioff==4) && ((joff==4)||(joff==12)));
00388
00389 if (p_Img->active_pps->constrained_intra_pred_flag)
00390 {
00391 block_available_up = pix_b.available ? p_Img->intra_block [pix_b.mb_addr] : 0;
00392 block_available_up_right = pix_c.available ? p_Img->intra_block [pix_c.mb_addr] : 0;
00393 }
00394 else
00395 {
00396 block_available_up = pix_b.available;
00397 block_available_up_right = pix_c.available;
00398 }
00399
00400 if (!block_available_up)
00401 printf ("warning: Intra_4x4_Diagonal_Down_Left prediction mode not allowed at mb %d\n", (int) p_Img->current_mb_nr);
00402
00403
00404 P_A = imgY[pix_b.pos_y][pix_b.pos_x + 0];
00405 P_B = imgY[pix_b.pos_y][pix_b.pos_x + 1];
00406 P_C = imgY[pix_b.pos_y][pix_b.pos_x + 2];
00407 P_D = imgY[pix_b.pos_y][pix_b.pos_x + 3];
00408
00409 if (block_available_up_right)
00410 {
00411 P_E = imgY[pix_c.pos_y][pix_c.pos_x + 0];
00412 P_F = imgY[pix_c.pos_y][pix_c.pos_x + 1];
00413 P_G = imgY[pix_c.pos_y][pix_c.pos_x + 2];
00414 P_H = imgY[pix_c.pos_y][pix_c.pos_x + 3];
00415 }
00416 else
00417 {
00418 P_E = P_F = P_G = P_H = P_D;
00419 }
00420
00421 mb_pred[jpos0][ipos0] = (imgpel) ((P_A + P_C + 2*(P_B) + 2) >> 2);
00422 mb_pred[jpos0][ipos1] =
00423 mb_pred[jpos1][ipos0] = (imgpel) ((P_B + P_D + 2*(P_C) + 2) >> 2);
00424 mb_pred[jpos0][ipos2] =
00425 mb_pred[jpos1][ipos1] =
00426 mb_pred[jpos2][ipos0] = (imgpel) ((P_C + P_E + 2*(P_D) + 2) >> 2);
00427 mb_pred[jpos0][ipos3] =
00428 mb_pred[jpos1][ipos2] =
00429 mb_pred[jpos2][ipos1] =
00430 mb_pred[jpos3][ipos0] = (imgpel) ((P_D + P_F + 2*(P_E) + 2) >> 2);
00431 mb_pred[jpos1][ipos3] =
00432 mb_pred[jpos2][ipos2] =
00433 mb_pred[jpos3][ipos1] = (imgpel) ((P_E + P_G + 2*(P_F) + 2) >> 2);
00434 mb_pred[jpos2][ipos3] =
00435 mb_pred[jpos3][ipos2] = (imgpel) ((P_F + P_H + 2*(P_G) + 2) >> 2);
00436 mb_pred[jpos3][ipos3] = (imgpel) ((P_G + 3*(P_H) + 2) >> 2);
00437
00438 return DECODING_OK;
00439 }
00440
00451 static inline int intra4x4_vert_right_pred(Macroblock *currMB,
00452 ColorPlane pl,
00453 int ioff,
00454 int joff)
00455 {
00456 Slice *currSlice = currMB->p_Slice;
00457 ImageParameters *p_Img = currMB->p_Img;
00458
00459 int i;
00460 imgpel PredPel[13];
00461 imgpel **imgY = (pl) ? p_Img->dec_picture->imgUV[pl - 1] : p_Img->dec_picture->imgY;
00462
00463 PixelPos pix_a[4];
00464 PixelPos pix_b, pix_d;
00465
00466 int block_available_up;
00467 int block_available_left;
00468 int block_available_up_left;
00469
00470 int jpos0 = joff, jpos1 = joff + 1, jpos2 = joff + 2, jpos3 = joff + 3;
00471 int ipos0 = ioff, ipos1 = ioff + 1, ipos2 = ioff + 2, ipos3 = ioff + 3;
00472 imgpel **mb_pred = currSlice->mb_pred[pl];
00473
00474 for (i=0;i<4;++i)
00475 {
00476 p_Img->getNeighbour(currMB, ioff -1 , joff +i , p_Img->mb_size[IS_LUMA], &pix_a[i]);
00477 }
00478
00479 p_Img->getNeighbour(currMB, ioff , joff -1 , p_Img->mb_size[IS_LUMA], &pix_b);
00480 p_Img->getNeighbour(currMB, ioff -1 , joff -1 , p_Img->mb_size[IS_LUMA], &pix_d);
00481
00482 if (p_Img->active_pps->constrained_intra_pred_flag)
00483 {
00484 for (i=0, block_available_left=1; i<4;++i)
00485 block_available_left &= pix_a[i].available ? p_Img->intra_block[pix_a[i].mb_addr]: 0;
00486 block_available_up = pix_b.available ? p_Img->intra_block [pix_b.mb_addr] : 0;
00487 block_available_up_left = pix_d.available ? p_Img->intra_block [pix_d.mb_addr] : 0;
00488 }
00489 else
00490 {
00491 block_available_left = pix_a[0].available;
00492 block_available_up = pix_b.available;
00493 block_available_up_left = pix_d.available;
00494 }
00495
00496 if ((!block_available_up)||(!block_available_left)||(!block_available_up_left))
00497 printf ("warning: Intra_4x4_Vertical_Right prediction mode not allowed at mb %d\n", (int) p_Img->current_mb_nr);
00498
00499
00500 P_A = imgY[pix_b.pos_y][pix_b.pos_x + 0];
00501 P_B = imgY[pix_b.pos_y][pix_b.pos_x + 1];
00502 P_C = imgY[pix_b.pos_y][pix_b.pos_x + 2];
00503 P_D = imgY[pix_b.pos_y][pix_b.pos_x + 3];
00504
00505 P_I = imgY[pix_a[0].pos_y][pix_a[0].pos_x];
00506 P_J = imgY[pix_a[1].pos_y][pix_a[1].pos_x];
00507 P_K = imgY[pix_a[2].pos_y][pix_a[2].pos_x];
00508 P_L = imgY[pix_a[3].pos_y][pix_a[3].pos_x];
00509
00510 P_X = imgY[pix_d.pos_y][pix_d.pos_x];
00511
00512 mb_pred[jpos0][ipos0] =
00513 mb_pred[jpos2][ipos1] = (imgpel) ((P_X + P_A + 1) >> 1);
00514 mb_pred[jpos0][ipos1] =
00515 mb_pred[jpos2][ipos2] = (imgpel) ((P_A + P_B + 1) >> 1);
00516 mb_pred[jpos0][ipos2] =
00517 mb_pred[jpos2][ipos3] = (imgpel) ((P_B + P_C + 1) >> 1);
00518 mb_pred[jpos0][ipos3] = (imgpel) ((P_C + P_D + 1) >> 1);
00519 mb_pred[jpos1][ipos0] =
00520 mb_pred[jpos3][ipos1] = (imgpel) ((P_I + 2*P_X + P_A + 2) >> 2);
00521 mb_pred[jpos1][ipos1] =
00522 mb_pred[jpos3][ipos2] = (imgpel) ((P_X + 2*P_A + P_B + 2) >> 2);
00523 mb_pred[jpos1][ipos2] =
00524 mb_pred[jpos3][ipos3] = (imgpel) ((P_A + 2*P_B + P_C + 2) >> 2);
00525 mb_pred[jpos1][ipos3] = (imgpel) ((P_B + 2*P_C + P_D + 2) >> 2);
00526 mb_pred[jpos2][ipos0] = (imgpel) ((P_X + 2*P_I + P_J + 2) >> 2);
00527 mb_pred[jpos3][ipos0] = (imgpel) ((P_I + 2*P_J + P_K + 2) >> 2);
00528
00529 return DECODING_OK;
00530 }
00531
00532
00543 static inline int intra4x4_vert_left_pred(Macroblock *currMB,
00544 ColorPlane pl,
00545 int ioff,
00546 int joff)
00547 {
00548 Slice *currSlice = currMB->p_Slice;
00549 ImageParameters *p_Img = currMB->p_Img;
00550
00551 imgpel PredPel[13];
00552 imgpel **imgY = (pl) ? p_Img->dec_picture->imgUV[pl - 1] : p_Img->dec_picture->imgY;
00553
00554 PixelPos pix_b, pix_c;
00555
00556 int block_available_up;
00557 int block_available_up_right;
00558
00559 int jpos0 = joff, jpos1 = joff + 1, jpos2 = joff + 2, jpos3 = joff + 3;
00560 int ipos0 = ioff, ipos1 = ioff + 1, ipos2 = ioff + 2, ipos3 = ioff + 3;
00561 imgpel **mb_pred = currSlice->mb_pred[pl];
00562
00563 p_Img->getNeighbour(currMB, ioff , joff -1 , p_Img->mb_size[IS_LUMA], &pix_b);
00564 p_Img->getNeighbour(currMB, ioff +4 , joff -1 , p_Img->mb_size[IS_LUMA], &pix_c);
00565
00566 pix_c.available = pix_c.available && !((ioff==4) && ((joff==4)||(joff==12)));
00567
00568 if (p_Img->active_pps->constrained_intra_pred_flag)
00569 {
00570 block_available_up = pix_b.available ? p_Img->intra_block [pix_b.mb_addr] : 0;
00571 block_available_up_right = pix_c.available ? p_Img->intra_block [pix_c.mb_addr] : 0;
00572 }
00573 else
00574 {
00575 block_available_up = pix_b.available;
00576 block_available_up_right = pix_c.available;
00577 }
00578
00579
00580 if (!block_available_up)
00581 printf ("warning: Intra_4x4_Vertical_Left prediction mode not allowed at mb %d\n", (int) p_Img->current_mb_nr);
00582
00583
00584 P_A = imgY[pix_b.pos_y][pix_b.pos_x + 0];
00585 P_B = imgY[pix_b.pos_y][pix_b.pos_x + 1];
00586 P_C = imgY[pix_b.pos_y][pix_b.pos_x + 2];
00587 P_D = imgY[pix_b.pos_y][pix_b.pos_x + 3];
00588
00589 if (block_available_up_right)
00590 {
00591 P_E = imgY[pix_c.pos_y][pix_c.pos_x + 0];
00592 P_F = imgY[pix_c.pos_y][pix_c.pos_x + 1];
00593 P_G = imgY[pix_c.pos_y][pix_c.pos_x + 2];
00594 P_H = imgY[pix_c.pos_y][pix_c.pos_x + 3];
00595 }
00596 else
00597 {
00598 P_E = P_F = P_G = P_H = P_D;
00599 }
00600
00601 mb_pred[jpos0][ipos0] = (imgpel) ((P_A + P_B + 1) >> 1);
00602 mb_pred[jpos0][ipos1] =
00603 mb_pred[jpos2][ipos0] = (imgpel) ((P_B + P_C + 1) >> 1);
00604 mb_pred[jpos0][ipos2] =
00605 mb_pred[jpos2][ipos1] = (imgpel) ((P_C + P_D + 1) >> 1);
00606 mb_pred[jpos0][ipos3] =
00607 mb_pred[jpos2][ipos2] = (imgpel) ((P_D + P_E + 1) >> 1);
00608 mb_pred[jpos2][ipos3] = (imgpel) ((P_E + P_F + 1) >> 1);
00609 mb_pred[jpos1][ipos0] = (imgpel) ((P_A + 2*P_B + P_C + 2) >> 2);
00610 mb_pred[jpos1][ipos1] =
00611 mb_pred[jpos3][ipos0] = (imgpel) ((P_B + 2*P_C + P_D + 2) >> 2);
00612 mb_pred[jpos1][ipos2] =
00613 mb_pred[jpos3][ipos1] = (imgpel) ((P_C + 2*P_D + P_E + 2) >> 2);
00614 mb_pred[jpos1][ipos3] =
00615 mb_pred[jpos3][ipos2] = (imgpel) ((P_D + 2*P_E + P_F + 2) >> 2);
00616 mb_pred[jpos3][ipos3] = (imgpel) ((P_E + 2*P_F + P_G + 2) >> 2);
00617
00618 return DECODING_OK;
00619 }
00620
00631 static inline int intra4x4_hor_up_pred(Macroblock *currMB,
00632 ColorPlane pl,
00633 int ioff,
00634 int joff)
00635 {
00636 Slice *currSlice = currMB->p_Slice;
00637 ImageParameters *p_Img = currMB->p_Img;
00638
00639 int i;
00640 imgpel PredPel[13];
00641 imgpel **imgY = (pl) ? p_Img->dec_picture->imgUV[pl - 1] : p_Img->dec_picture->imgY;
00642
00643 PixelPos pix_a[4];
00644
00645 int block_available_left;
00646
00647 int jpos0 = joff, jpos1 = joff + 1, jpos2 = joff + 2, jpos3 = joff + 3;
00648 int ipos0 = ioff, ipos1 = ioff + 1, ipos2 = ioff + 2, ipos3 = ioff + 3;
00649 imgpel **mb_pred = currSlice->mb_pred[pl];
00650
00651 for (i=0;i<4;++i)
00652 {
00653 p_Img->getNeighbour(currMB, ioff -1 , joff +i , p_Img->mb_size[IS_LUMA], &pix_a[i]);
00654 }
00655
00656 if (p_Img->active_pps->constrained_intra_pred_flag)
00657 {
00658 for (i=0, block_available_left=1; i<4;++i)
00659 block_available_left &= pix_a[i].available ? p_Img->intra_block[pix_a[i].mb_addr]: 0;
00660 }
00661 else
00662 {
00663 block_available_left = pix_a[0].available;
00664 }
00665
00666 if (!block_available_left)
00667 printf ("warning: Intra_4x4_Horizontal_Up prediction mode not allowed at mb %d\n",(int) p_Img->current_mb_nr);
00668
00669
00670 P_I = imgY[pix_a[0].pos_y][pix_a[0].pos_x];
00671 P_J = imgY[pix_a[1].pos_y][pix_a[1].pos_x];
00672 P_K = imgY[pix_a[2].pos_y][pix_a[2].pos_x];
00673 P_L = imgY[pix_a[3].pos_y][pix_a[3].pos_x];
00674
00675 mb_pred[jpos0][ipos0] = (imgpel) ((P_I + P_J + 1) >> 1);
00676 mb_pred[jpos0][ipos1] = (imgpel) ((P_I + 2*P_J + P_K + 2) >> 2);
00677 mb_pred[jpos0][ipos2] =
00678 mb_pred[jpos1][ipos0] = (imgpel) ((P_J + P_K + 1) >> 1);
00679 mb_pred[jpos0][ipos3] =
00680 mb_pred[jpos1][ipos1] = (imgpel) ((P_J + 2*P_K + P_L + 2) >> 2);
00681 mb_pred[jpos1][ipos2] =
00682 mb_pred[jpos2][ipos0] = (imgpel) ((P_K + P_L + 1) >> 1);
00683 mb_pred[jpos1][ipos3] =
00684 mb_pred[jpos2][ipos1] = (imgpel) ((P_K + 2*P_L + P_L + 2) >> 2);
00685 mb_pred[jpos2][ipos3] =
00686 mb_pred[jpos3][ipos1] =
00687 mb_pred[jpos3][ipos0] =
00688 mb_pred[jpos2][ipos2] =
00689 mb_pred[jpos3][ipos2] =
00690 mb_pred[jpos3][ipos3] = (imgpel) P_L;
00691
00692 return DECODING_OK;
00693 }
00694
00705 static inline int intra4x4_hor_down_pred(Macroblock *currMB,
00706 ColorPlane pl,
00707 int ioff,
00708 int joff)
00709 {
00710 Slice *currSlice = currMB->p_Slice;
00711 ImageParameters *p_Img = currMB->p_Img;
00712
00713 int i;
00714 imgpel PredPel[13];
00715 imgpel **imgY = (pl) ? p_Img->dec_picture->imgUV[pl - 1] : p_Img->dec_picture->imgY;
00716
00717 PixelPos pix_a[4];
00718 PixelPos pix_b, pix_d;
00719
00720 int block_available_up;
00721 int block_available_left;
00722 int block_available_up_left;
00723
00724 int jpos0 = joff, jpos1 = joff + 1, jpos2 = joff + 2, jpos3 = joff + 3;
00725 int ipos0 = ioff, ipos1 = ioff + 1, ipos2 = ioff + 2, ipos3 = ioff + 3;
00726 imgpel **mb_pred = currSlice->mb_pred[pl];
00727
00728 for (i=0;i<4;++i)
00729 {
00730 p_Img->getNeighbour(currMB, ioff -1 , joff +i , p_Img->mb_size[IS_LUMA], &pix_a[i]);
00731 }
00732
00733 p_Img->getNeighbour(currMB, ioff , joff -1 , p_Img->mb_size[IS_LUMA], &pix_b);
00734 p_Img->getNeighbour(currMB, ioff -1 , joff -1 , p_Img->mb_size[IS_LUMA], &pix_d);
00735
00736 if (p_Img->active_pps->constrained_intra_pred_flag)
00737 {
00738 for (i=0, block_available_left=1; i<4;++i)
00739 block_available_left &= pix_a[i].available ? p_Img->intra_block[pix_a[i].mb_addr]: 0;
00740 block_available_up = pix_b.available ? p_Img->intra_block [pix_b.mb_addr] : 0;
00741 block_available_up_left = pix_d.available ? p_Img->intra_block [pix_d.mb_addr] : 0;
00742 }
00743 else
00744 {
00745 block_available_left = pix_a[0].available;
00746 block_available_up = pix_b.available;
00747 block_available_up_left = pix_d.available;
00748 }
00749
00750 if ((!block_available_up)||(!block_available_left)||(!block_available_up_left))
00751 printf ("warning: Intra_4x4_Horizontal_Down prediction mode not allowed at mb %d\n", (int) p_Img->current_mb_nr);
00752
00753
00754 P_A = imgY[pix_b.pos_y][pix_b.pos_x + 0];
00755 P_B = imgY[pix_b.pos_y][pix_b.pos_x + 1];
00756 P_C = imgY[pix_b.pos_y][pix_b.pos_x + 2];
00757 P_D = imgY[pix_b.pos_y][pix_b.pos_x + 3];
00758
00759 P_I = imgY[pix_a[0].pos_y][pix_a[0].pos_x];
00760 P_J = imgY[pix_a[1].pos_y][pix_a[1].pos_x];
00761 P_K = imgY[pix_a[2].pos_y][pix_a[2].pos_x];
00762 P_L = imgY[pix_a[3].pos_y][pix_a[3].pos_x];
00763
00764 P_X = imgY[pix_d.pos_y][pix_d.pos_x];
00765
00766 mb_pred[jpos0][ipos0] =
00767 mb_pred[jpos1][ipos2] = (imgpel) ((P_X + P_I + 1) >> 1);
00768 mb_pred[jpos0][ipos1] =
00769 mb_pred[jpos1][ipos3] = (imgpel) ((P_I + 2*P_X + P_A + 2) >> 2);
00770 mb_pred[jpos0][ipos2] = (imgpel) ((P_X + 2*P_A + P_B + 2) >> 2);
00771 mb_pred[jpos0][ipos3] = (imgpel) ((P_A + 2*P_B + P_C + 2) >> 2);
00772 mb_pred[jpos1][ipos0] =
00773 mb_pred[jpos2][ipos2] = (imgpel) ((P_I + P_J + 1) >> 1);
00774 mb_pred[jpos1][ipos1] =
00775 mb_pred[jpos2][ipos3] = (imgpel) ((P_X + 2*P_I + P_J + 2) >> 2);
00776 mb_pred[jpos2][ipos0] =
00777 mb_pred[jpos3][ipos2] = (imgpel) ((P_J + P_K + 1) >> 1);
00778 mb_pred[jpos2][ipos1] =
00779 mb_pred[jpos3][ipos3] = (imgpel) ((P_I + 2*P_J + P_K + 2) >> 2);
00780 mb_pred[jpos3][ipos0] = (imgpel) ((P_K + P_L + 1) >> 1);
00781 mb_pred[jpos3][ipos1] = (imgpel) ((P_J + 2*P_K + P_L + 2) >> 2);
00782
00783 return DECODING_OK;
00784 }
00785
00786
00797 int intrapred(Macroblock *currMB,
00798 ColorPlane pl,
00799 int ioff,
00800 int joff,
00801 int img_block_x,
00802 int img_block_y)
00803 {
00804 ImageParameters *p_Img = currMB->p_Img;
00805 byte predmode = p_Img->ipredmode[img_block_y][img_block_x];
00806 p_Img->ipmode_DPCM = predmode;
00807
00808 switch (predmode)
00809 {
00810 case DC_PRED:
00811 return (intra4x4_dc_pred(currMB, pl, ioff, joff));
00812 break;
00813 case VERT_PRED:
00814 return (intra4x4_vert_pred(currMB, pl, ioff, joff));
00815 break;
00816 case HOR_PRED:
00817 return (intra4x4_hor_pred(currMB, pl, ioff, joff));
00818 break;
00819 case DIAG_DOWN_RIGHT_PRED:
00820 return (intra4x4_diag_down_right_pred(currMB, pl, ioff, joff));
00821 break;
00822 case DIAG_DOWN_LEFT_PRED:
00823 return (intra4x4_diag_down_left_pred(currMB, pl, ioff, joff));
00824 break;
00825 case VERT_RIGHT_PRED:
00826 return (intra4x4_vert_right_pred(currMB, pl, ioff, joff));
00827 break;
00828 case VERT_LEFT_PRED:
00829 return (intra4x4_vert_left_pred(currMB, pl, ioff, joff));
00830 break;
00831 case HOR_UP_PRED:
00832 return (intra4x4_hor_up_pred(currMB, pl, ioff, joff));
00833 break;
00834 case HOR_DOWN_PRED:
00835 return (intra4x4_hor_down_pred(currMB, pl, ioff, joff));
00836 default:
00837 printf("Error: illegal intra_4x4 prediction mode: %d\n", (int) predmode);
00838 return SEARCH_SYNC;
00839 break;
00840 }
00841
00842 return DECODING_OK;
00843 }