1 /*!
2 *************************************************************************************
3 * \file intra4x4_pred_normal.c
4 *
5 * \brief
6 * Functions for intra 4x4 prediction
7 *
8 * \author
9 * Main contributors (see contributors.h for copyright,
10 * address and affiliation details)
11 * - Alexis Michael Tourapis <alexismt@ieee.org>
12 *
13 *************************************************************************************
14 */
15 #include "global.h"
16 #include "intra4x4_pred.h"
17 #include "mb_access.h"
18 #include "image.h"
19
20 // Notation for comments regarding prediction and predictors.
21 // The pels of the 4x4 block are labelled a..p. The predictor pels above
22 // are labelled A..H, from the left I..L, and from above left X, as follows:
23 //
24 // X A B C D E F G H
25 // I a b c d
26 // J e f g h
27 // K i j k l
28 // L m n o p
29 //
30
31 /*!
32 ***********************************************************************
33 * \brief
34 * makes and returns 4x4 DC prediction mode
35 *
36 * \param currMB
37 * current MB structure
38 * \param pl
39 * color plane
40 * \param ioff
41 * pixel offset X within MB
42 * \param joff
43 * pixel offset Y within MB
44 * \return
45 * DECODING_OK decoding of intra prediction mode was successful \n
46 *
47 ***********************************************************************
48 */
intra4x4_dc_pred(Macroblock * currMB,ColorPlane pl,int ioff,int joff)49 static int intra4x4_dc_pred(Macroblock *currMB,
50 ColorPlane pl,
51 int ioff,
52 int joff)
53 {
54 Slice *currSlice = currMB->p_Slice;
55 VideoParameters *p_Vid = currMB->p_Vid;
56
57 int j;
58 int s0 = 0;
59 imgpel **imgY = (pl) ? currSlice->dec_picture->imgUV[pl - 1] : currSlice->dec_picture->imgY;
60 imgpel *curpel = NULL;
61
62 PixelPos pix_a, pix_b;
63
64 int block_available_up;
65 int block_available_left;
66
67 imgpel **mb_pred = currSlice->mb_pred[pl];
68
69 getNonAffNeighbour(currMB, ioff - 1, joff , p_Vid->mb_size[IS_LUMA], &pix_a);
70 getNonAffNeighbour(currMB, ioff , joff -1, p_Vid->mb_size[IS_LUMA], &pix_b);
71
72 if (p_Vid->active_pps->constrained_intra_pred_flag)
73 {
74 block_available_left = pix_a.available ? currSlice->intra_block [pix_a.mb_addr] : 0;
75 block_available_up = pix_b.available ? currSlice->intra_block [pix_b.mb_addr] : 0;
76 }
77 else
78 {
79 block_available_left = pix_a.available;
80 block_available_up = pix_b.available;
81 }
82
83 // form predictor pels
84 if (block_available_up)
85 {
86 curpel = &imgY[pix_b.pos_y][pix_b.pos_x];
87 s0 += *curpel++;
88 s0 += *curpel++;
89 s0 += *curpel++;
90 s0 += *curpel;
91 }
92
93 if (block_available_left)
94 {
95 imgpel **img_pred = &imgY[pix_a.pos_y];
96 int pos_x = pix_a.pos_x;
97 s0 += *(*(img_pred ++) + pos_x);
98 s0 += *(*(img_pred ++) + pos_x);
99 s0 += *(*(img_pred ++) + pos_x);
100 s0 += *(*(img_pred ) + pos_x);
101 }
102
103 if (block_available_up && block_available_left)
104 {
105 // no edge
106 s0 = (s0 + 4)>>3;
107 }
108 else if (!block_available_up && block_available_left)
109 {
110 // upper edge
111 s0 = (s0 + 2)>>2;
112 }
113 else if (block_available_up && !block_available_left)
114 {
115 // left edge
116 s0 = (s0 + 2)>>2;
117 }
118 else //if (!block_available_up && !block_available_left)
119 {
120 // top left corner, nothing to predict from
121 s0 = p_Vid->dc_pred_value_comp[pl];
122 }
123
124 for (j=joff; j < joff + BLOCK_SIZE; ++j)
125 {
126 // store DC prediction
127 mb_pred[j][ioff ] = (imgpel) s0;
128 mb_pred[j][ioff + 1] = (imgpel) s0;
129 mb_pred[j][ioff + 2] = (imgpel) s0;
130 mb_pred[j][ioff + 3] = (imgpel) s0;
131 }
132 return DECODING_OK;
133 }
134
135 /*!
136 ***********************************************************************
137 * \brief
138 * makes and returns 4x4 vertical prediction mode
139 *
140 * \return
141 * DECODING_OK decoding of intra prediction mode was successful \n
142 *
143 ***********************************************************************
144 */
intra4x4_vert_pred(Macroblock * currMB,ColorPlane pl,int ioff,int joff)145 static int intra4x4_vert_pred(Macroblock *currMB, //!< current macroblock
146 ColorPlane pl, //!< current image plane
147 int ioff, //!< pixel offset X within MB
148 int joff) //!< pixel offset Y within MB
149 {
150 Slice *currSlice = currMB->p_Slice;
151 VideoParameters *p_Vid = currMB->p_Vid;
152
153 int block_available_up;
154 PixelPos pix_b;
155
156 getNonAffNeighbour(currMB, ioff, joff - 1 , p_Vid->mb_size[IS_LUMA], &pix_b);
157
158 if (p_Vid->active_pps->constrained_intra_pred_flag)
159 {
160 block_available_up = pix_b.available ? currSlice->intra_block [pix_b.mb_addr] : 0;
161 }
162 else
163 {
164 block_available_up = pix_b.available;
165 }
166
167 if (!block_available_up)
168 {
169 printf ("warning: Intra_4x4_Vertical prediction mode not allowed at mb %d\n", (int) currSlice->current_mb_nr);
170 }
171 else
172 {
173 imgpel **mb_pred = currSlice->mb_pred[pl];
174 imgpel *imgY = (pl) ? &currSlice->dec_picture->imgUV[pl - 1][pix_b.pos_y][pix_b.pos_x] : &currSlice->dec_picture->imgY[pix_b.pos_y][pix_b.pos_x];
175 memcpy(&(mb_pred[joff++][ioff]), imgY, BLOCK_SIZE * sizeof(imgpel));
176 memcpy(&(mb_pred[joff++][ioff]), imgY, BLOCK_SIZE * sizeof(imgpel));
177 memcpy(&(mb_pred[joff++][ioff]), imgY, BLOCK_SIZE * sizeof(imgpel));
178 memcpy(&(mb_pred[joff ][ioff]), imgY, BLOCK_SIZE * sizeof(imgpel));
179 }
180 return DECODING_OK;
181 }
182
183 /*!
184 ***********************************************************************
185 * \brief
186 * makes and returns 4x4 horizontal prediction mode
187 *
188 * \param currMB
189 * current MB structure
190 * \param pl
191 * color plane
192 * \param ioff
193 * pixel offset X within MB
194 * \param joff
195 * pixel offset Y within MB
196 *
197 * \return
198 * DECODING_OK decoding of intra prediction mode was successful
199 *
200 ***********************************************************************
201 */
intra4x4_hor_pred(Macroblock * currMB,ColorPlane pl,int ioff,int joff)202 static int intra4x4_hor_pred(Macroblock *currMB,
203 ColorPlane pl,
204 int ioff,
205 int joff)
206 {
207 VideoParameters *p_Vid = currMB->p_Vid;
208 Slice *currSlice = currMB->p_Slice;
209
210 PixelPos pix_a;
211
212 int block_available_left;
213
214 getNonAffNeighbour(currMB, ioff - 1 , joff, p_Vid->mb_size[IS_LUMA], &pix_a);
215
216 if (p_Vid->active_pps->constrained_intra_pred_flag)
217 {
218 block_available_left = pix_a.available ? currSlice->intra_block[pix_a.mb_addr]: 0;
219 }
220 else
221 {
222 block_available_left = pix_a.available;
223 }
224
225 if (!block_available_left)
226 printf ("warning: Intra_4x4_Horizontal prediction mode not allowed at mb %d\n",(int) currSlice->current_mb_nr);
227 else
228 #if (IMGTYPE == 0)
229 {
230 imgpel **imgY = (pl) ? currSlice->dec_picture->imgUV[pl - 1] : currSlice->dec_picture->imgY;
231 imgpel **mb_pred = &currSlice->mb_pred[pl][joff];
232 imgpel **img_pred = &imgY[pix_a.pos_y];
233 int pos_x = pix_a.pos_x;
234
235 memset((*(mb_pred++) + ioff), *(*(img_pred++) + pos_x), BLOCK_SIZE * sizeof (imgpel));
236 memset((*(mb_pred++) + ioff), *(*(img_pred++) + pos_x), BLOCK_SIZE * sizeof (imgpel));
237 memset((*(mb_pred++) + ioff), *(*(img_pred++) + pos_x), BLOCK_SIZE * sizeof (imgpel));
238 memset((*(mb_pred ) + ioff), *(*(img_pred ) + pos_x), BLOCK_SIZE * sizeof (imgpel));
239 }
240 #else
241 {
242 int j;
243 int pos_y = pix_a.pos_y;
244 int pos_x = pix_a.pos_x;
245 imgpel *predrow, prediction;
246 imgpel **mb_pred = &currSlice->mb_pred[pl][joff];
247 imgpel **imgY = (pl) ? currSlice->dec_picture->imgUV[pl - 1] : currSlice->dec_picture->imgY;
248
249 for(j=0;j<BLOCK_SIZE;++j)
250 {
251 predrow = mb_pred[j];
252 prediction = imgY[pos_y++][pos_x];
253 /* store predicted 4x4 block */
254 predrow[ioff ]= prediction;
255 predrow[ioff + 1]= prediction;
256 predrow[ioff + 2]= prediction;
257 predrow[ioff + 3]= prediction;
258 }
259 }
260 #endif
261
262 return DECODING_OK;
263 }
264
265 /*!
266 ***********************************************************************
267 * \brief
268 * makes and returns 4x4 diagonal down right prediction mode
269 *
270 * \return
271 * DECODING_OK decoding of intra prediction mode was successful \n
272 *
273 ***********************************************************************
274 */
intra4x4_diag_down_right_pred(Macroblock * currMB,ColorPlane pl,int ioff,int joff)275 static int intra4x4_diag_down_right_pred(Macroblock *currMB, //!< current macroblock
276 ColorPlane pl, //!< current image plane
277 int ioff, //!< pixel offset X within MB
278 int joff) //!< pixel offset Y within MB
279 {
280 Slice *currSlice = currMB->p_Slice;
281 VideoParameters *p_Vid = currMB->p_Vid;
282
283 imgpel **imgY = (pl) ? currSlice->dec_picture->imgUV[pl - 1] : currSlice->dec_picture->imgY;
284
285 PixelPos pix_a;
286 PixelPos pix_b, pix_d;
287
288 int block_available_up;
289 int block_available_left;
290 int block_available_up_left;
291
292 imgpel **mb_pred = currSlice->mb_pred[pl];
293
294 getNonAffNeighbour(currMB, ioff -1 , joff , p_Vid->mb_size[IS_LUMA], &pix_a);
295 getNonAffNeighbour(currMB, ioff , joff -1 , p_Vid->mb_size[IS_LUMA], &pix_b);
296 getNonAffNeighbour(currMB, ioff -1 , joff -1 , p_Vid->mb_size[IS_LUMA], &pix_d);
297
298 if (p_Vid->active_pps->constrained_intra_pred_flag)
299 {
300 block_available_left = pix_a.available ? currSlice->intra_block [pix_a.mb_addr]: 0;
301 block_available_up = pix_b.available ? currSlice->intra_block [pix_b.mb_addr] : 0;
302 block_available_up_left = pix_d.available ? currSlice->intra_block [pix_d.mb_addr] : 0;
303 }
304 else
305 {
306 block_available_left = pix_a.available;
307 block_available_up = pix_b.available;
308 block_available_up_left = pix_d.available;
309 }
310
311 if ((!block_available_up)||(!block_available_left)||(!block_available_up_left))
312 printf ("warning: Intra_4x4_Diagonal_Down_Right prediction mode not allowed at mb %d\n",(int) currSlice->current_mb_nr);
313 else
314 {
315 imgpel PredPixel[7];
316 imgpel **img_pred = &imgY[pix_a.pos_y];
317 int pix_x = pix_a.pos_x;
318 imgpel *pred_pel = &imgY[pix_b.pos_y][pix_b.pos_x];
319 // form predictor pels
320 imgpel p_a = *pred_pel++;
321 imgpel p_b = *pred_pel++;
322 imgpel p_c = *pred_pel++;
323 imgpel p_d = *pred_pel ;
324
325 imgpel p_i = *(*(img_pred++) + pix_x);
326 imgpel p_j = *(*(img_pred++) + pix_x);
327 imgpel p_k = *(*(img_pred++) + pix_x);
328 imgpel p_l = *(*(img_pred ) + pix_x);
329
330 imgpel p_x = imgY[pix_d.pos_y][pix_d.pos_x];
331
332 PredPixel[0] = (imgpel) ((p_l + 2*p_k + p_j + 2) >> 2);
333 PredPixel[1] = (imgpel) ((p_k + 2*p_j + p_i + 2) >> 2);
334 PredPixel[2] = (imgpel) ((p_j + 2*p_i + p_x + 2) >> 2);
335 PredPixel[3] = (imgpel) ((p_i + 2*p_x + p_a + 2) >> 2);
336 PredPixel[4] = (imgpel) ((p_x + 2*p_a + p_b + 2) >> 2);
337 PredPixel[5] = (imgpel) ((p_a + 2*p_b + p_c + 2) >> 2);
338 PredPixel[6] = (imgpel) ((p_b + 2*p_c + p_d + 2) >> 2);
339
340 memcpy(&mb_pred[joff++][ioff], &PredPixel[3], 4 * sizeof(imgpel));
341 memcpy(&mb_pred[joff++][ioff], &PredPixel[2], 4 * sizeof(imgpel));
342 memcpy(&mb_pred[joff++][ioff], &PredPixel[1], 4 * sizeof(imgpel));
343 memcpy(&mb_pred[joff ][ioff], &PredPixel[0], 4 * sizeof(imgpel));
344 }
345
346 return DECODING_OK;
347 }
348
349 /*!
350 ***********************************************************************
351 * \brief
352 * makes and returns 4x4 diagonal down left prediction mode
353 *
354 * \return
355 * DECODING_OK decoding of intra prediction mode was successful \n
356 *
357 ***********************************************************************
358 */
intra4x4_diag_down_left_pred(Macroblock * currMB,ColorPlane pl,int ioff,int joff)359 static int intra4x4_diag_down_left_pred(Macroblock *currMB, //!< current macroblock
360 ColorPlane pl, //!< current image plane
361 int ioff, //!< pixel offset X within MB
362 int joff) //!< pixel offset Y within MB
363 {
364 Slice *currSlice = currMB->p_Slice;
365 VideoParameters *p_Vid = currMB->p_Vid;
366
367 PixelPos pix_b, pix_c;
368
369 int block_available_up;
370 int block_available_up_right;
371
372 p_Vid->getNeighbour(currMB, ioff , joff - 1, p_Vid->mb_size[IS_LUMA], &pix_b);
373 p_Vid->getNeighbour(currMB, ioff + 4, joff - 1, p_Vid->mb_size[IS_LUMA], &pix_c);
374
375 pix_c.available = pix_c.available && !((ioff==4) && ((joff==4)||(joff==12)));
376
377 if (p_Vid->active_pps->constrained_intra_pred_flag)
378 {
379 block_available_up = pix_b.available ? currSlice->intra_block [pix_b.mb_addr] : 0;
380 block_available_up_right = pix_c.available ? currSlice->intra_block [pix_c.mb_addr] : 0;
381 }
382 else
383 {
384 block_available_up = pix_b.available;
385 block_available_up_right = pix_c.available;
386 }
387
388 if (!block_available_up)
389 printf ("warning: Intra_4x4_Diagonal_Down_Left prediction mode not allowed at mb %d\n", (int) currSlice->current_mb_nr);
390 else
391 {
392 imgpel **imgY = (pl) ? currSlice->dec_picture->imgUV[pl - 1] : currSlice->dec_picture->imgY;
393 imgpel **mb_pred = currSlice->mb_pred[pl];
394
395 imgpel p_e, p_f, p_g, p_h;
396 imgpel PredPixel[8];
397 imgpel *pred_pel = &imgY[pix_b.pos_y][pix_b.pos_x];
398
399 // form predictor pels
400 imgpel p_a = *pred_pel++;
401 imgpel p_b = *pred_pel++;
402 imgpel p_c = *pred_pel++;
403 imgpel p_d = *pred_pel ;
404
405 if (block_available_up_right)
406 {
407 pred_pel = &imgY[pix_c.pos_y][pix_c.pos_x];
408 p_e = *pred_pel++;
409 p_f = *pred_pel++;
410 p_g = *pred_pel++;
411 p_h = *pred_pel ;
412 }
413 else
414 {
415 p_e = p_f = p_g = p_h = p_d;
416 }
417
418 PredPixel[0] = (imgpel) ((p_a + p_c + 2*(p_b) + 2) >> 2);
419 PredPixel[1] = (imgpel) ((p_b + p_d + 2*(p_c) + 2) >> 2);
420 PredPixel[2] = (imgpel) ((p_c + p_e + 2*(p_d) + 2) >> 2);
421 PredPixel[3] = (imgpel) ((p_d + p_f + 2*(p_e) + 2) >> 2);
422 PredPixel[4] = (imgpel) ((p_e + p_g + 2*(p_f) + 2) >> 2);
423 PredPixel[5] = (imgpel) ((p_f + p_h + 2*(p_g) + 2) >> 2);
424 PredPixel[6] = (imgpel) ((p_g + 3*(p_h) + 2) >> 2);
425
426 memcpy(&mb_pred[joff++][ioff], &PredPixel[0], 4 * sizeof(imgpel));
427 memcpy(&mb_pred[joff++][ioff], &PredPixel[1], 4 * sizeof(imgpel));
428 memcpy(&mb_pred[joff++][ioff], &PredPixel[2], 4 * sizeof(imgpel));
429 memcpy(&mb_pred[joff ][ioff], &PredPixel[3], 4 * sizeof(imgpel));
430 }
431
432 return DECODING_OK;
433 }
434
435 /*!
436 ***********************************************************************
437 * \brief
438 * makes and returns 4x4 vertical right prediction mode
439 *
440 * \return
441 * DECODING_OK decoding of intra prediction mode was successful \n
442 *
443 ***********************************************************************
444 */
intra4x4_vert_right_pred(Macroblock * currMB,ColorPlane pl,int ioff,int joff)445 static int intra4x4_vert_right_pred(Macroblock *currMB, //!< current macroblock
446 ColorPlane pl, //!< current image plane
447 int ioff, //!< pixel offset X within MB
448 int joff) //!< pixel offset Y within MB
449 {
450 Slice *currSlice = currMB->p_Slice;
451 VideoParameters *p_Vid = currMB->p_Vid;
452
453 PixelPos pix_a, pix_b, pix_d;
454
455 int block_available_up;
456 int block_available_left;
457 int block_available_up_left;
458
459 getNonAffNeighbour(currMB, ioff -1 , joff , p_Vid->mb_size[IS_LUMA], &pix_a);
460 getNonAffNeighbour(currMB, ioff , joff -1 , p_Vid->mb_size[IS_LUMA], &pix_b);
461 getNonAffNeighbour(currMB, ioff -1 , joff -1 , p_Vid->mb_size[IS_LUMA], &pix_d);
462
463 if (p_Vid->active_pps->constrained_intra_pred_flag)
464 {
465 block_available_left = pix_a.available ? currSlice->intra_block[pix_a.mb_addr]: 0;
466 block_available_up = pix_b.available ? currSlice->intra_block [pix_b.mb_addr] : 0;
467 block_available_up_left = pix_d.available ? currSlice->intra_block [pix_d.mb_addr] : 0;
468 }
469 else
470 {
471 block_available_left = pix_a.available;
472 block_available_up = pix_b.available;
473 block_available_up_left = pix_d.available;
474 }
475
476 if ((!block_available_up)||(!block_available_left)||(!block_available_up_left))
477 printf ("warning: Intra_4x4_Vertical_Right prediction mode not allowed at mb %d\n", (int) currSlice->current_mb_nr);
478 {
479 imgpel **imgY = (pl) ? currSlice->dec_picture->imgUV[pl - 1] : currSlice->dec_picture->imgY;
480 imgpel **mb_pred = currSlice->mb_pred[pl];
481 imgpel PredPixel[10];
482
483 imgpel **img_pred = &imgY[pix_a.pos_y];
484 int pix_x = pix_a.pos_x;
485 imgpel *pred_pel = &imgY[pix_b.pos_y][pix_b.pos_x];
486 // form predictor pels
487 imgpel p_a = *pred_pel++;
488 imgpel p_b = *pred_pel++;
489 imgpel p_c = *pred_pel++;
490 imgpel p_d = *pred_pel ;
491
492 imgpel p_i = *(*(img_pred++) + pix_x);
493 imgpel p_j = *(*(img_pred++) + pix_x);
494 imgpel p_k = *(*(img_pred++) + pix_x);
495
496 imgpel p_x = imgY[pix_d.pos_y][pix_d.pos_x];
497
498 PredPixel[0] = (imgpel) ((p_x + 2*p_i + p_j + 2) >> 2);
499 PredPixel[1] = (imgpel) ((p_x + p_a + 1) >> 1);
500 PredPixel[2] = (imgpel) ((p_a + p_b + 1) >> 1);
501 PredPixel[3] = (imgpel) ((p_b + p_c + 1) >> 1);
502 PredPixel[4] = (imgpel) ((p_c + p_d + 1) >> 1);
503 PredPixel[5] = (imgpel) ((p_i + 2*p_j + p_k + 2) >> 2);
504 PredPixel[6] = (imgpel) ((p_i + 2*p_x + p_a + 2) >> 2);
505 PredPixel[7] = (imgpel) ((p_x + 2*p_a + p_b + 2) >> 2);
506 PredPixel[8] = (imgpel) ((p_a + 2*p_b + p_c + 2) >> 2);
507 PredPixel[9] = (imgpel) ((p_b + 2*p_c + p_d + 2) >> 2);
508
509 memcpy(&mb_pred[joff++][ioff], &PredPixel[1], 4 * sizeof(imgpel));
510 memcpy(&mb_pred[joff++][ioff], &PredPixel[6], 4 * sizeof(imgpel));
511 memcpy(&mb_pred[joff++][ioff], &PredPixel[0], 4 * sizeof(imgpel));
512 memcpy(&mb_pred[joff ][ioff], &PredPixel[5], 4 * sizeof(imgpel));
513
514 }
515
516 return DECODING_OK;
517 }
518
519
520 /*!
521 ***********************************************************************
522 * \brief
523 * makes and returns 4x4 vertical left prediction mode
524 *
525 * \return
526 * DECODING_OK decoding of intra prediction mode was successful \n
527 *
528 ***********************************************************************
529 */
intra4x4_vert_left_pred(Macroblock * currMB,ColorPlane pl,int ioff,int joff)530 static int intra4x4_vert_left_pred(Macroblock *currMB, //!< current macroblock
531 ColorPlane pl, //!< current image plane
532 int ioff, //!< pixel offset X within MB
533 int joff) //!< pixel offset Y within MB
534 {
535 Slice *currSlice = currMB->p_Slice;
536 VideoParameters *p_Vid = currMB->p_Vid;
537
538 PixelPos pix_b, pix_c;
539
540 int block_available_up;
541 int block_available_up_right;
542
543 p_Vid->getNeighbour(currMB, ioff , joff -1 , p_Vid->mb_size[IS_LUMA], &pix_b);
544 p_Vid->getNeighbour(currMB, ioff +4 , joff -1 , p_Vid->mb_size[IS_LUMA], &pix_c);
545
546 pix_c.available = pix_c.available && !((ioff==4) && ((joff==4)||(joff==12)));
547
548 if (p_Vid->active_pps->constrained_intra_pred_flag)
549 {
550 block_available_up = pix_b.available ? currSlice->intra_block [pix_b.mb_addr] : 0;
551 block_available_up_right = pix_c.available ? currSlice->intra_block [pix_c.mb_addr] : 0;
552 }
553 else
554 {
555 block_available_up = pix_b.available;
556 block_available_up_right = pix_c.available;
557 }
558
559
560 if (!block_available_up)
561 printf ("warning: Intra_4x4_Vertical_Left prediction mode not allowed at mb %d\n", (int) currSlice->current_mb_nr);
562 {
563 imgpel PredPixel[10];
564 imgpel **imgY = (pl) ? currSlice->dec_picture->imgUV[pl - 1] : currSlice->dec_picture->imgY;
565 imgpel **mb_pred = currSlice->mb_pred[pl];
566 imgpel *pred_pel = &imgY[pix_b.pos_y][pix_b.pos_x];
567
568 // form predictor pels
569 imgpel p_a = *pred_pel++;
570 imgpel p_b = *pred_pel++;
571 imgpel p_c = *pred_pel++;
572 imgpel p_d = *pred_pel ;
573 imgpel p_e, p_f, p_g;
574
575 if (block_available_up_right)
576 {
577 imgpel *pred_pel = &imgY[pix_c.pos_y][pix_c.pos_x];
578 p_e = *pred_pel++;
579 p_f = *pred_pel++;
580 p_g = *pred_pel++;
581 }
582 else
583 {
584 p_e = p_f = p_g = p_d;
585 }
586
587 PredPixel[0] = (imgpel) ((p_a + p_b + 1) >> 1);
588 PredPixel[1] = (imgpel) ((p_b + p_c + 1) >> 1);
589 PredPixel[2] = (imgpel) ((p_c + p_d + 1) >> 1);
590 PredPixel[3] = (imgpel) ((p_d + p_e + 1) >> 1);
591 PredPixel[4] = (imgpel) ((p_e + p_f + 1) >> 1);
592 PredPixel[5] = (imgpel) ((p_a + 2*p_b + p_c + 2) >> 2);
593 PredPixel[6] = (imgpel) ((p_b + 2*p_c + p_d + 2) >> 2);
594 PredPixel[7] = (imgpel) ((p_c + 2*p_d + p_e + 2) >> 2);
595 PredPixel[8] = (imgpel) ((p_d + 2*p_e + p_f + 2) >> 2);
596 PredPixel[9] = (imgpel) ((p_e + 2*p_f + p_g + 2) >> 2);
597
598 memcpy(&mb_pred[joff++][ioff], &PredPixel[0], 4 * sizeof(imgpel));
599 memcpy(&mb_pred[joff++][ioff], &PredPixel[5], 4 * sizeof(imgpel));
600 memcpy(&mb_pred[joff++][ioff], &PredPixel[1], 4 * sizeof(imgpel));
601 memcpy(&mb_pred[joff ][ioff], &PredPixel[6], 4 * sizeof(imgpel));
602 }
603 return DECODING_OK;
604 }
605
606 /*!
607 ***********************************************************************
608 * \brief
609 * makes and returns 4x4 horizontal up prediction mode
610 *
611 * \return
612 * DECODING_OK decoding of intra prediction mode was successful \n
613 *
614 ***********************************************************************
615 */
intra4x4_hor_up_pred(Macroblock * currMB,ColorPlane pl,int ioff,int joff)616 static int intra4x4_hor_up_pred(Macroblock *currMB, //!< current macroblock
617 ColorPlane pl, //!< current image plane
618 int ioff, //!< pixel offset X within MB
619 int joff) //!< pixel offset Y within MB
620 {
621 Slice *currSlice = currMB->p_Slice;
622 VideoParameters *p_Vid = currMB->p_Vid;
623
624 PixelPos pix_a;
625
626 int block_available_left;
627
628 getNonAffNeighbour(currMB, ioff -1 , joff, p_Vid->mb_size[IS_LUMA], &pix_a);
629
630 if (p_Vid->active_pps->constrained_intra_pred_flag)
631 {
632 block_available_left = pix_a.available ? currSlice->intra_block[pix_a.mb_addr]: 0;
633 }
634 else
635 {
636 block_available_left = pix_a.available;
637 }
638
639 if (!block_available_left)
640 printf ("warning: Intra_4x4_Horizontal_Up prediction mode not allowed at mb %d\n",(int) currSlice->current_mb_nr);
641 else
642 {
643 imgpel PredPixel[10];
644 imgpel **imgY = (pl) ? currSlice->dec_picture->imgUV[pl - 1] : currSlice->dec_picture->imgY;
645 imgpel **mb_pred = currSlice->mb_pred[pl];
646
647 imgpel **img_pred = &imgY[pix_a.pos_y];
648 int pix_x = pix_a.pos_x;
649
650 // form predictor pels
651 imgpel p_i = *(*(img_pred++) + pix_x);
652 imgpel p_j = *(*(img_pred++) + pix_x);
653 imgpel p_k = *(*(img_pred++) + pix_x);
654 imgpel p_l = *(*(img_pred ) + pix_x);
655
656 PredPixel[0] = (imgpel) ((p_i + p_j + 1) >> 1);
657 PredPixel[1] = (imgpel) ((p_i + 2*p_j + p_k + 2) >> 2);
658 PredPixel[2] = (imgpel) ((p_j + p_k + 1) >> 1);
659 PredPixel[3] = (imgpel) ((p_j + 2*p_k + p_l + 2) >> 2);
660 PredPixel[4] = (imgpel) ((p_k + p_l + 1) >> 1);
661 PredPixel[5] = (imgpel) ((p_k + 2*p_l + p_l + 2) >> 2);
662 PredPixel[6] = (imgpel) p_l;
663 PredPixel[7] = (imgpel) p_l;
664 PredPixel[8] = (imgpel) p_l;
665 PredPixel[9] = (imgpel) p_l;
666
667 memcpy(&mb_pred[joff++][ioff], &PredPixel[0], 4 * sizeof(imgpel));
668 memcpy(&mb_pred[joff++][ioff], &PredPixel[2], 4 * sizeof(imgpel));
669 memcpy(&mb_pred[joff++][ioff], &PredPixel[4], 4 * sizeof(imgpel));
670 memcpy(&mb_pred[joff++][ioff], &PredPixel[6], 4 * sizeof(imgpel));
671 }
672
673 return DECODING_OK;
674 }
675
676 /*!
677 ***********************************************************************
678 * \brief
679 * makes and returns 4x4 horizontal down prediction mode
680 *
681 * \return
682 * DECODING_OK decoding of intra prediction mode was successful \n
683 *
684 ***********************************************************************
685 */
intra4x4_hor_down_pred(Macroblock * currMB,ColorPlane pl,int ioff,int joff)686 static int intra4x4_hor_down_pred(Macroblock *currMB, //!< current macroblock
687 ColorPlane pl, //!< current image plane
688 int ioff, //!< pixel offset X within MB
689 int joff) //!< pixel offset Y within MB
690 {
691 Slice *currSlice = currMB->p_Slice;
692 VideoParameters *p_Vid = currMB->p_Vid;
693
694 PixelPos pix_a, pix_b, pix_d;
695
696 int block_available_up;
697 int block_available_left;
698 int block_available_up_left;
699
700 getNonAffNeighbour(currMB, ioff -1 , joff , p_Vid->mb_size[IS_LUMA], &pix_a);
701 getNonAffNeighbour(currMB, ioff , joff -1 , p_Vid->mb_size[IS_LUMA], &pix_b);
702 getNonAffNeighbour(currMB, ioff -1 , joff -1 , p_Vid->mb_size[IS_LUMA], &pix_d);
703
704 if (p_Vid->active_pps->constrained_intra_pred_flag)
705 {
706 block_available_left = pix_a.available ? currSlice->intra_block [pix_a.mb_addr]: 0;
707 block_available_up = pix_b.available ? currSlice->intra_block [pix_b.mb_addr] : 0;
708 block_available_up_left = pix_d.available ? currSlice->intra_block [pix_d.mb_addr] : 0;
709 }
710 else
711 {
712 block_available_left = pix_a.available;
713 block_available_up = pix_b.available;
714 block_available_up_left = pix_d.available;
715 }
716
717 if ((!block_available_up)||(!block_available_left)||(!block_available_up_left))
718 printf ("warning: Intra_4x4_Horizontal_Down prediction mode not allowed at mb %d\n", (int) currSlice->current_mb_nr);
719 else
720 {
721 imgpel PredPixel[10];
722 imgpel **imgY = (pl) ? currSlice->dec_picture->imgUV[pl - 1] : currSlice->dec_picture->imgY;
723 imgpel **mb_pred = currSlice->mb_pred[pl];
724
725 imgpel **img_pred = &imgY[pix_a.pos_y];
726 int pix_x = pix_a.pos_x;
727 imgpel *pred_pel = &imgY[pix_b.pos_y][pix_b.pos_x];
728
729 // form predictor pels
730 imgpel p_a = *pred_pel++;
731 imgpel p_b = *pred_pel++;
732 imgpel p_c = *pred_pel++;
733
734 imgpel p_i = *(*(img_pred++) + pix_x);
735 imgpel p_j = *(*(img_pred++) + pix_x);
736 imgpel p_k = *(*(img_pred++) + pix_x);
737 imgpel p_l = *(*(img_pred ) + pix_x);
738
739 imgpel p_x = imgY[pix_d.pos_y][pix_d.pos_x];
740
741 PredPixel[0] = (imgpel) ((p_k + p_l + 1) >> 1);
742 PredPixel[1] = (imgpel) ((p_j + 2*p_k + p_l + 2) >> 2);
743 PredPixel[2] = (imgpel) ((p_j + p_k + 1) >> 1);
744 PredPixel[3] = (imgpel) ((p_i + 2*p_j + p_k + 2) >> 2);
745 PredPixel[4] = (imgpel) ((p_i + p_j + 1) >> 1);
746 PredPixel[5] = (imgpel) ((p_x + 2*p_i + p_j + 2) >> 2);
747 PredPixel[6] = (imgpel) ((p_x + p_i + 1) >> 1);
748 PredPixel[7] = (imgpel) ((p_i + 2*p_x + p_a + 2) >> 2);
749 PredPixel[8] = (imgpel) ((p_x + 2*p_a + p_b + 2) >> 2);
750 PredPixel[9] = (imgpel) ((p_a + 2*p_b + p_c + 2) >> 2);
751
752 memcpy(&mb_pred[joff++][ioff], &PredPixel[6], 4 * sizeof(imgpel));
753 memcpy(&mb_pred[joff++][ioff], &PredPixel[4], 4 * sizeof(imgpel));
754 memcpy(&mb_pred[joff++][ioff], &PredPixel[2], 4 * sizeof(imgpel));
755 memcpy(&mb_pred[joff ][ioff], &PredPixel[0], 4 * sizeof(imgpel));
756 }
757
758 return DECODING_OK;
759 }
760
761
762 /*!
763 ***********************************************************************
764 * \brief
765 * makes and returns 4x4 intra prediction blocks
766 *
767 * \return
768 * DECODING_OK decoding of intra prediction mode was successful \n
769 * SEARCH_SYNC search next sync element as errors while decoding occured
770 ***********************************************************************
771 */
intra4x4_pred_normal(Macroblock * currMB,ColorPlane pl,int ioff,int joff,int img_block_x,int img_block_y)772 int intra4x4_pred_normal(Macroblock *currMB, //!< current macroblock
773 ColorPlane pl, //!< current image plane
774 int ioff, //!< pixel offset X within MB
775 int joff, //!< pixel offset Y within MB
776 int img_block_x, //!< location of block X, multiples of 4
777 int img_block_y) //!< location of block Y, multiples of 4
778 {
779 VideoParameters *p_Vid = currMB->p_Vid;
780 byte predmode = p_Vid->ipredmode[img_block_y][img_block_x];
781 currMB->ipmode_DPCM = predmode; //For residual DPCM
782
783 switch (predmode)
784 {
785 case DC_PRED:
786 return (intra4x4_dc_pred(currMB, pl, ioff, joff));
787 break;
788 case VERT_PRED:
789 return (intra4x4_vert_pred(currMB, pl, ioff, joff));
790 break;
791 case HOR_PRED:
792 return (intra4x4_hor_pred(currMB, pl, ioff, joff));
793 break;
794 case DIAG_DOWN_RIGHT_PRED:
795 return (intra4x4_diag_down_right_pred(currMB, pl, ioff, joff));
796 break;
797 case DIAG_DOWN_LEFT_PRED:
798 return (intra4x4_diag_down_left_pred(currMB, pl, ioff, joff));
799 break;
800 case VERT_RIGHT_PRED:
801 return (intra4x4_vert_right_pred(currMB, pl, ioff, joff));
802 break;
803 case VERT_LEFT_PRED:
804 return (intra4x4_vert_left_pred(currMB, pl, ioff, joff));
805 break;
806 case HOR_UP_PRED:
807 return (intra4x4_hor_up_pred(currMB, pl, ioff, joff));
808 break;
809 case HOR_DOWN_PRED:
810 return (intra4x4_hor_down_pred(currMB, pl, ioff, joff));
811 default:
812 printf("Error: illegal intra_4x4 prediction mode: %d\n", (int) predmode);
813 return SEARCH_SYNC;
814 break;
815 }
816 }
817