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