1/******************************************************************************
2*
3* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
4*
5* Licensed under the Apache License, Version 2.0 (the "License");
6* you may not use this file except in compliance with the License.
7* You may obtain a copy of the License at:
8*
9* http://www.apache.org/licenses/LICENSE-2.0
10*
11* Unless required by applicable law or agreed to in writing, software
12* distributed under the License is distributed on an "AS IS" BASIS,
13* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14* See the License for the specific language governing permissions and
15* limitations under the License.
16*
17******************************************************************************/
18/**
19*******************************************************************************
20* @file
21*  ihevc_intra_pred_filters.c
22*
23* @brief
24*  Contains function Definition for intra prediction  interpolation filters
25*
26*
27* @author
28*  Srinivas T
29*
30* @par List of Functions:
31*  - ihevc_intra_pred_luma_planar()
32*  - ihevc_intra_pred_luma_dc()
33*  - ihevc_intra_pred_luma_horz()
34*  - ihevc_intra_pred_luma_ver()
35*  - ihevc_intra_pred_luma_mode2()
36*  - ihevc_intra_pred_luma_mode_18_34()
37*  - ihevc_intra_pred_luma_mode_3_to_9()
38*  - ihevc_intra_pred_luma_mode_11_to_17()
39*  - ihevc_intra_pred_luma_mode_19_to_25()
40*  - ihevc_intra_pred_luma_mode_27_to_33()
41*  - ihevc_intra_pred_luma_ref_substitution()
42*
43* @remarks
44*  None
45*
46*******************************************************************************
47*/
48
49
50/*****************************************************************************/
51/* File Includes                                                             */
52/*****************************************************************************/
53
54#include <assert.h>
55#include "ihevc_typedefs.h"
56#include "ihevc_intra_pred.h"
57#include "ihevc_macros.h"
58#include "ihevc_func_selector.h"
59#include "ihevc_platform_macros.h"
60#include "ihevc_common_tables.h"
61#include "ihevc_defs.h"
62#include "ihevc_mem_fns.h"
63#include "ihevc_debug.h"
64
65/****************************************************************************/
66/* Constant Macros                                                          */
67/****************************************************************************/
68#define MAX_CU_SIZE 64
69#define BIT_DEPTH 8
70#define T32_4NT 128
71#define T16_4NT 64
72
73
74/****************************************************************************/
75/* Function Macros                                                          */
76/****************************************************************************/
77#define GET_BITS(y,x) ((y) & (1 << x)) && (1 << x)
78
79/*****************************************************************************/
80/* global tables Definition                                                  */
81/*****************************************************************************/
82
83
84/*****************************************************************************/
85/* Function Definition                                                      */
86/*****************************************************************************/
87
88/**
89*******************************************************************************
90*
91* @brief
92*    Intra prediction interpolation filter for pu1_ref substitution
93*
94*
95* @par Description:
96*    Reference substitution process for samples unavailable  for prediction
97*    Refer to section 8.4.4.2.2
98*
99* @param[in] pu1_top_left
100*  UWORD8 pointer to the top-left
101*
102* @param[in] pu1_top
103*  UWORD8 pointer to the top
104*
105* @param[in] pu1_left
106*  UWORD8 pointer to the left
107*
108* @param[in] src_strd
109*  WORD32 Source stride
110*
111* @param[in] nbr_flags
112*  WORD32 neighbor availability flags
113*
114* @param[in] nt
115*  WORD32 transform Block size
116*
117* @param[in] dst_strd
118*  WORD32 Destination stride
119*
120* @returns
121*
122* @remarks
123*  None
124*
125*******************************************************************************
126*/
127void ihevc_intra_pred_luma_ref_subst_all_avlble(UWORD8 *pu1_top_left,
128                                                UWORD8 *pu1_top,
129                                                UWORD8 *pu1_left,
130                                                WORD32 src_strd,
131                                                WORD32 nt,
132                                                WORD32 nbr_flags,
133                                                UWORD8 *pu1_dst,
134                                                WORD32 dst_strd)
135{
136
137    WORD32 i;
138    WORD32 two_nt = 2 * nt;
139    UNUSED(nbr_flags);
140    UNUSED(dst_strd);
141
142    /* Neighbor Flag Structure*/
143    /* MSB ---> LSB */
144    /*    Top-Left | Top-Right | Top | Left | Bottom-Left
145              1         4         4     4         4
146     */
147    ASSERT((nbr_flags == 0x11188) || (nbr_flags == 0x133CC) || (nbr_flags == 0x1FFFF));
148    {
149
150        if(nt == 4)
151        {
152            /* 1 bit extraction for all the neighboring blocks */
153
154
155            /* Else fill the corresponding samples */
156            pu1_dst[two_nt] = *pu1_top_left;
157            //if(left)
158            {
159                for(i = 0; i < nt; i++)
160                    pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
161            }
162//            if(bot_left)
163            {
164                for(i = nt; i < two_nt; i++)
165                    pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
166            }
167//            if(top)
168            {
169                ihevc_memcpy(&pu1_dst[two_nt + 1], pu1_top, nt);
170            }
171//            if(tp_right)
172            {
173                ihevc_memcpy(&pu1_dst[two_nt + 1 + nt], pu1_top + nt, nt);
174            }
175
176
177        }
178        else
179
180        {
181
182            /* Else fill the corresponding samples */
183            ASSERT((nt == 8) || (nt == 16) || (nt == 32));
184            pu1_dst[two_nt] = *pu1_top_left;
185
186            for(i = 0; i < nt; i++)
187                pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
188
189            for(i = nt; i < two_nt; i++)
190                pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
191
192            ihevc_memcpy_mul_8(&pu1_dst[two_nt + 1], pu1_top, nt);
193
194            ihevc_memcpy_mul_8(&pu1_dst[two_nt + 1 + nt], pu1_top + nt, nt);
195        }
196
197    }
198}
199
200
201void ihevc_intra_pred_luma_ref_substitution(UWORD8 *pu1_top_left,
202                                            UWORD8 *pu1_top,
203                                            UWORD8 *pu1_left,
204                                            WORD32 src_strd,
205                                            WORD32 nt,
206                                            WORD32 nbr_flags,
207                                            UWORD8 *pu1_dst,
208                                            WORD32 dst_strd)
209{
210    UWORD8 pu1_ref;
211    WORD32 dc_val, i;
212    WORD32 total_samples = (4 * nt) + 1;
213    WORD32 two_nt = 2 * nt;
214
215    WORD32 three_nt = 3 * nt;
216    WORD32 get_bits;
217    WORD32 next;
218    WORD32 bot_left, left, top, tp_right, tp_left;
219
220    WORD32 idx, nbr_id_from_bl, frwd_nbr_flag;
221    UNUSED(dst_strd);
222    /*dc_val = 1 << (BIT_DEPTH - 1);*/
223    dc_val = 1 << (8 - 1);
224
225
226    /* Neighbor Flag Structure*/
227    /* MSB ---> LSB */
228    /*    Top-Left | Top-Right | Top | Left | Bottom-Left
229              1         4         4     4         4
230     */
231    /* If no neighbor flags are present, fill the neighbor samples with DC value */
232    if(nbr_flags == 0)
233    {
234        for(i = 0; i < total_samples; i++)
235        {
236            pu1_dst[i] = dc_val;
237        }
238    }
239    else
240    {
241        if(nt <= 8)
242        {
243            /* 1 bit extraction for all the neighboring blocks */
244            tp_left = (nbr_flags & 0x10000) >> 16;
245            bot_left = (nbr_flags & 0x8) >> 3;
246            left = (nbr_flags & 0x80) >> 7;
247            top = (nbr_flags & 0x100) >> 8;
248            tp_right = (nbr_flags & 0x1000) >> 12;
249
250            /* Else fill the corresponding samples */
251            if(tp_left)
252                pu1_dst[two_nt] = *pu1_top_left;
253            else
254                pu1_dst[two_nt] = 0;
255
256
257            if(left)
258            {
259                for(i = 0; i < nt; i++)
260                    pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
261            }
262            else
263            {
264                ihevc_memset(&pu1_dst[two_nt - 1 - (nt - 1)], 0, nt);
265            }
266
267
268            if(bot_left)
269            {
270                for(i = nt; i < two_nt; i++)
271                    pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
272            }
273            else
274            {
275                ihevc_memset(&pu1_dst[two_nt - 1 - (two_nt - 1)], 0, nt);
276            }
277
278
279            if(top)
280            {
281                ihevc_memcpy(&pu1_dst[two_nt + 1], pu1_top, nt);
282            }
283            else
284            {
285                ihevc_memset(&pu1_dst[two_nt + 1], 0, nt);
286            }
287
288            if(tp_right)
289            {
290                ihevc_memcpy(&pu1_dst[two_nt + 1 + nt], pu1_top + nt, nt);
291            }
292            else
293            {
294                ihevc_memset(&pu1_dst[two_nt + 1 + nt], 0, nt);
295            }
296            next = 1;
297
298            /* If bottom -left is not available, reverse substitution process*/
299            if(bot_left == 0)
300            {
301                WORD32 a_nbr_flag[5];
302                a_nbr_flag[0] = bot_left;
303                a_nbr_flag[1] = left;
304                a_nbr_flag[2] = tp_left;
305                a_nbr_flag[3] = top;
306                a_nbr_flag[4] = tp_right;
307
308                /* Check for the 1st available sample from bottom-left*/
309                while(!a_nbr_flag[next])
310                    next++;
311
312                /* If Left, top-left are available*/
313                if(next <= 2)
314                {
315                    idx = nt * next;
316                    pu1_ref = pu1_dst[idx];
317                    for(i = 0; i < idx; i++)
318                        pu1_dst[i] = pu1_ref;
319                }
320                else /* If top, top-right are available */
321                {
322                    /* Idx is changed to copy 1 pixel value for top-left ,if top-left is not available*/
323                    idx = (nt * (next - 1)) + 1;
324                    pu1_ref = pu1_dst[idx];
325                    for(i = 0; i < idx; i++)
326                        pu1_dst[i] = pu1_ref;
327                }
328            }
329
330            /* Forward Substitution Process */
331            /* If left is Unavailable, copy the last bottom-left value */
332            if(left == 0)
333            {
334                ihevc_memset(&pu1_dst[nt], pu1_dst[nt - 1], nt);
335
336            }
337            /* If top-left is Unavailable, copy the last left value */
338            if(tp_left == 0)
339                pu1_dst[two_nt] = pu1_dst[two_nt - 1];
340            /* If top is Unavailable, copy the last top-left value */
341            if(top == 0)
342            {
343                ihevc_memset(&pu1_dst[two_nt + 1], pu1_dst[two_nt], nt);
344            }
345            /* If to right is Unavailable, copy the last top value */
346            if(tp_right == 0)
347            {
348                ihevc_memset(&pu1_dst[three_nt + 1], pu1_dst[three_nt], nt);
349
350            }
351        }
352
353        if(nt == 16)
354        {
355            WORD32 nbr_flags_temp = 0;
356            nbr_flags_temp = ((nbr_flags & 0xC) >> 2) + ((nbr_flags & 0xC0) >> 4)
357                            + ((nbr_flags & 0x300) >> 4)
358                            + ((nbr_flags & 0x3000) >> 6)
359                            + ((nbr_flags & 0x10000) >> 8);
360
361            /* Else fill the corresponding samples */
362            if(nbr_flags & 0x10000)
363                pu1_dst[two_nt] = *pu1_top_left;
364            else
365                pu1_dst[two_nt] = 0;
366
367            if(nbr_flags & 0xC0)
368            {
369                for(i = 0; i < nt; i++)
370                    pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
371            }
372            else
373            {
374                ihevc_memset_mul_8(&pu1_dst[two_nt - 1 - (nt - 1)], 0, nt);
375            }
376
377            /* Bottom - left availability is checked for every 8x8 TU position and set accordingly */
378            {
379                if(nbr_flags & 0x8)
380                {
381                    for(i = nt; i < (nt + 8); i++)
382                    pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
383                }
384                else
385                {
386                    ihevc_memset_mul_8(&pu1_dst[nt - 8], 0, 8);
387                }
388
389                if(nbr_flags & 0x4)
390                {
391                    for(i = (nt + 8); i < two_nt; i++)
392                        pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
393                }
394                else
395                {
396                    ihevc_memset_mul_8(&pu1_dst[0], 0, 8);
397                }
398            }
399
400            if(nbr_flags & 0x300)
401            {
402                ihevc_memcpy_mul_8(&pu1_dst[two_nt + 1], pu1_top, nt);
403            }
404            else
405            {
406                ihevc_memset_mul_8(&pu1_dst[two_nt + 1], 0, nt);
407            }
408
409            if(nbr_flags & 0x3000)
410            {
411                ihevc_memcpy_mul_8(&pu1_dst[two_nt + 1 + nt], pu1_top + nt, nt);
412            }
413            else
414            {
415                ihevc_memset_mul_8(&pu1_dst[two_nt + 1 + nt], 0, nt);
416            }
417            /* compute trailing zeors based on nbr_flag for substitution process of below left see section .*/
418            /* as each bit in nbr flags corresponds to 8 pels for bot_left, left, top and topright but 1 pel for topleft */
419            {
420                nbr_id_from_bl = look_up_trailing_zeros(nbr_flags_temp & 0XF) * 8; /* for below left and left */
421
422                if(nbr_id_from_bl == 64)
423                    nbr_id_from_bl = 32;
424
425                if(nbr_id_from_bl == 32)
426                {
427                    /* for top left : 1 pel per nbr bit */
428                    if(!((nbr_flags_temp >> 8) & 0x1))
429                    {
430                        nbr_id_from_bl++;
431                        nbr_id_from_bl += look_up_trailing_zeros((nbr_flags_temp >> 4) & 0xF) * 8; /* top and top right;  8 pels per nbr bit */
432                        //nbr_id_from_bl += idx * 8;
433                    }
434                }
435                /* Reverse Substitution Process*/
436                if(nbr_id_from_bl)
437                {
438                    /* Replicate the bottom-left and subsequent unavailable pixels with the 1st available pixel above */
439                    pu1_ref = pu1_dst[nbr_id_from_bl];
440                    for(i = (nbr_id_from_bl - 1); i >= 0; i--)
441                    {
442                        pu1_dst[i] = pu1_ref;
443                    }
444                }
445            }
446
447            /* for the loop of 4*Nt+1 pixels (excluding pixels computed from reverse substitution) */
448            while(nbr_id_from_bl < ((T16_4NT)+1))
449            {
450                /* To Obtain the next unavailable idx flag after reverse neighbor substitution  */
451                /* Devide by 8 to obtain the original index */
452                frwd_nbr_flag = (nbr_id_from_bl >> 3); /*+ (nbr_id_from_bl & 0x1);*/
453
454                /* The Top-left flag is at the last bit location of nbr_flags*/
455                if(nbr_id_from_bl == (T16_4NT / 2))
456                {
457                    get_bits = GET_BITS(nbr_flags_temp, 8);
458
459                    /* only pel substitution for TL */
460                    if(!get_bits)
461                        pu1_dst[nbr_id_from_bl] = pu1_dst[nbr_id_from_bl - 1];
462                }
463                else
464                {
465                    get_bits = GET_BITS(nbr_flags_temp, frwd_nbr_flag);
466                    if(!get_bits)
467                    {
468                        /* 8 pel substitution (other than TL) */
469                        pu1_ref = pu1_dst[nbr_id_from_bl - 1];
470                        ihevc_memset_mul_8(pu1_dst + nbr_id_from_bl, pu1_ref, 8);
471
472
473                    }
474
475                }
476                nbr_id_from_bl += (nbr_id_from_bl == (T16_4NT / 2)) ? 1 : 8;
477            }
478
479
480        }
481
482        if(nt == 32)
483        {
484            /* Else fill the corresponding samples */
485            if(nbr_flags & 0x10000)
486                pu1_dst[two_nt] = *pu1_top_left;
487            else
488                pu1_dst[two_nt] = 0;
489
490            if(nbr_flags & 0xF0)
491            {
492                for(i = 0; i < nt; i++)
493                    pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
494            }
495            else
496            {
497                ihevc_memset_mul_8(&pu1_dst[two_nt - 1 - (nt - 1)], 0, nt);
498            }
499
500            /* Bottom - left availability is checked for every 8x8 TU position and set accordingly */
501            {
502                if(nbr_flags & 0x8)
503                {
504                    for(i = nt; i < (nt + 8); i++)
505                    pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
506                }
507                else
508                {
509                    ihevc_memset_mul_8(&pu1_dst[24], 0, 8);
510                }
511
512                if(nbr_flags & 0x4)
513                {
514                    for(i = (nt + 8); i < (nt + 16); i++)
515                        pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
516                }
517                else
518                {
519                    ihevc_memset_mul_8(&pu1_dst[16], 0, 8);
520                }
521
522                if(nbr_flags & 0x2)
523                {
524                    for(i = (nt + 16); i < (nt + 24); i++)
525                        pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
526                }
527                else
528                {
529                    ihevc_memset_mul_8(&pu1_dst[8], 0, 8);
530                }
531
532                if(nbr_flags & 0x1)
533                {
534                    for(i = (nt + 24); i < (two_nt); i++)
535                        pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
536                }
537                else
538                {
539                    ihevc_memset_mul_8(&pu1_dst[0], 0, 8);
540                }
541            }
542
543
544            if(nbr_flags & 0xF00)
545            {
546                ihevc_memcpy_mul_8(&pu1_dst[two_nt + 1], pu1_top, nt);
547            }
548            else
549            {
550                ihevc_memset_mul_8(&pu1_dst[two_nt + 1], 0, nt);
551            }
552
553            if(nbr_flags & 0xF000)
554            {
555                ihevc_memcpy_mul_8(&pu1_dst[two_nt + 1 + nt], pu1_top + nt, nt);
556            }
557            else
558            {
559                ihevc_memset_mul_8(&pu1_dst[two_nt + 1 + nt], 0, nt);
560            }
561            /* compute trailing ones based on mbr_flag for substitution process of below left see section .*/
562            /* as each bit in nbr flags corresponds to 8 pels for bot_left, left, top and topright but 1 pel for topleft */
563            {
564                nbr_id_from_bl = look_up_trailing_zeros((nbr_flags & 0XFF)) * 8; /* for below left and left */
565
566                if(nbr_id_from_bl == 64)
567                {
568                    /* for top left : 1 pel per nbr bit */
569                    if(!((nbr_flags >> 16) & 0x1))
570                    {
571                        /* top left not available */
572                        nbr_id_from_bl++;
573                        /* top and top right;  8 pels per nbr bit */
574                        nbr_id_from_bl += look_up_trailing_zeros((nbr_flags >> 8) & 0xFF) * 8;
575                    }
576                }
577                /* Reverse Substitution Process*/
578                if(nbr_id_from_bl)
579                {
580                    /* Replicate the bottom-left and subsequent unavailable pixels with the 1st available pixel above */
581                    pu1_ref = pu1_dst[nbr_id_from_bl];
582                    for(i = (nbr_id_from_bl - 1); i >= 0; i--)
583                        pu1_dst[i] = pu1_ref;
584                }
585            }
586
587            /* for the loop of 4*Nt+1 pixels (excluding pixels computed from reverse substitution) */
588            while(nbr_id_from_bl < ((T32_4NT)+1))
589            {
590                /* To Obtain the next unavailable idx flag after reverse neighbor substitution  */
591                /* Devide by 8 to obtain the original index */
592                frwd_nbr_flag = (nbr_id_from_bl >> 3); /*+ (nbr_id_from_bl & 0x1);*/
593
594                /* The Top-left flag is at the last bit location of nbr_flags*/
595                if(nbr_id_from_bl == (T32_4NT / 2))
596                {
597                    get_bits = GET_BITS(nbr_flags, 16);
598                    /* only pel substitution for TL */
599                    if(!get_bits)
600                        pu1_dst[nbr_id_from_bl] = pu1_dst[nbr_id_from_bl - 1];
601                }
602                else
603                {
604                    get_bits = GET_BITS(nbr_flags, frwd_nbr_flag);
605                    if(!get_bits)
606                    {
607                        /* 8 pel substitution (other than TL) */
608                        pu1_ref = pu1_dst[nbr_id_from_bl - 1];
609                        ihevc_memset_mul_8(&pu1_dst[nbr_id_from_bl], pu1_ref, 8);
610
611                    }
612
613                }
614                nbr_id_from_bl += (nbr_id_from_bl == (T32_4NT / 2)) ? 1 : 8;
615            }
616        }
617
618    }
619}
620
621
622/**
623*******************************************************************************
624*
625* @brief
626*    Intra prediction interpolation filter for ref_filtering
627*
628*
629* @par Description:
630*    Reference DC filtering for neighboring samples dependent  on TU size and
631*    mode  Refer to section 8.4.4.2.3 in the standard
632*
633* @param[in] pu1_src
634*  UWORD8 pointer to the source
635*
636* @param[out] pu1_dst
637*  UWORD8 pointer to the destination
638*
639* @param[in] nt
640*  integer Transform Block size
641*
642* @param[in] mode
643*  integer intraprediction mode
644*
645* @returns
646*
647* @remarks
648*  None
649*
650*******************************************************************************
651*/
652
653
654void ihevc_intra_pred_ref_filtering(UWORD8 *pu1_src,
655                                    WORD32 nt,
656                                    UWORD8 *pu1_dst,
657                                    WORD32 mode,
658                                    WORD32 strong_intra_smoothing_enable_flag)
659{
660    WORD32 filter_flag;
661    WORD32 i; /* Generic indexing variable */
662    WORD32 four_nt = 4 * nt;
663    UWORD8 au1_flt[(4 * MAX_CU_SIZE) + 1];
664    WORD32 bi_linear_int_flag = 0;
665    WORD32 abs_cond_left_flag = 0;
666    WORD32 abs_cond_top_flag = 0;
667    /*WORD32 dc_val = 1 << (BIT_DEPTH - 5);*/
668    WORD32 dc_val = 1 << (8 - 5);
669    //WORD32 strong_intra_smoothing_enable_flag  = 1;
670
671    filter_flag = gau1_intra_pred_ref_filter[mode] & (1 << (CTZ(nt) - 2));
672    if(0 == filter_flag)
673    {
674        if(pu1_src == pu1_dst)
675        {
676            return;
677        }
678        else
679        {
680            for(i = 0; i < (four_nt + 1); i++)
681                pu1_dst[i] = pu1_src[i];
682        }
683    }
684
685    else
686    {
687        /* If strong intra smoothin is enabled and transform size is 32 */
688        if((1 == strong_intra_smoothing_enable_flag) && (32 == nt))
689        {
690            /* Strong Intra Filtering */
691            abs_cond_top_flag = (ABS(pu1_src[2 * nt] + pu1_src[4 * nt]
692                            - (2 * pu1_src[3 * nt]))) < dc_val;
693            abs_cond_left_flag = (ABS(pu1_src[2 * nt] + pu1_src[0]
694                            - (2 * pu1_src[nt]))) < dc_val;
695
696            bi_linear_int_flag = ((1 == abs_cond_left_flag)
697                            && (1 == abs_cond_top_flag));
698        }
699        /* Extremities Untouched*/
700        au1_flt[0] = pu1_src[0];
701        au1_flt[4 * nt] = pu1_src[4 * nt];
702
703        /* Strong filtering of reference samples */
704        if(1 == bi_linear_int_flag)
705        {
706            au1_flt[2 * nt] = pu1_src[2 * nt];
707
708            for(i = 1; i < (2 * nt); i++)
709                au1_flt[i] = (((2 * nt) - i) * pu1_src[0] + i * pu1_src[2 * nt] + 32) >> 6;
710
711            for(i = 1; i < (2 * nt); i++)
712                au1_flt[i + (2 * nt)] = (((2 * nt) - i) * pu1_src[2 * nt] + i * pu1_src[4 * nt] + 32) >> 6;
713
714        }
715        else
716        {
717            /* Perform bilinear filtering of Reference Samples */
718            for(i = 0; i < (four_nt - 1); i++)
719            {
720                au1_flt[i + 1] = (pu1_src[i] + 2 * pu1_src[i + 1]
721                                + pu1_src[i + 2] + 2) >> 2;
722            }
723        }
724
725
726        for(i = 0; i < (four_nt + 1); i++)
727            pu1_dst[i] = au1_flt[i];
728    }
729
730}
731
732
733/**
734*******************************************************************************
735*
736* @brief
737*    Intra prediction interpolation filter for luma planar
738*
739* @par Description:
740*    Planar Intraprediction with reference neighboring samples location
741*    pointed by 'pu1_ref' to the TU block location  pointed by 'pu1_dst'  Refer
742*    to section 8.4.4.2.4 in the standard
743*
744* @param[in] pu1_src
745*  UWORD8 pointer to the source
746*
747* @param[out] pu1_dst
748*  UWORD8 pointer to the destination
749*
750* @param[in] src_strd
751*  integer source stride
752*
753* @param[in] dst_strd
754*  integer destination stride
755*
756* @param[in] nt
757*  integer Transform Block size
758*
759* @param[in] mode
760*  integer intraprediction mode
761*
762* @returns
763*
764* @remarks
765*  None
766*
767*******************************************************************************
768*/
769
770
771void ihevc_intra_pred_luma_planar(UWORD8 *pu1_ref,
772                                  WORD32 src_strd,
773                                  UWORD8 *pu1_dst,
774                                  WORD32 dst_strd,
775                                  WORD32 nt,
776                                  WORD32 mode)
777{
778
779
780    WORD32 row, col;
781    WORD32 log2nt = 5;
782    WORD32 two_nt, three_nt;
783    UNUSED(src_strd);
784    UNUSED(mode);
785    switch(nt)
786    {
787        case 32:
788            log2nt = 5;
789            break;
790        case 16:
791            log2nt = 4;
792            break;
793        case 8:
794            log2nt = 3;
795            break;
796        case 4:
797            log2nt = 2;
798            break;
799        default:
800            break;
801    }
802    two_nt = 2 * nt;
803    three_nt = 3 * nt;
804    /* Planar filtering */
805    for(row = 0; row < nt; row++)
806    {
807        for(col = 0; col < nt; col++)
808        {
809            pu1_dst[row * dst_strd + col] = ((nt - 1 - col)
810                            * pu1_ref[two_nt - 1 - row]
811                            + (col + 1) * pu1_ref[three_nt + 1]
812                            + (nt - 1 - row) * pu1_ref[two_nt + 1 + col]
813                            + (row + 1) * pu1_ref[nt - 1] + nt) >> (log2nt + 1);
814        }
815    }
816}
817
818
819/**
820*******************************************************************************
821*
822* @brief
823*    Intra prediction interpolation filter for luma dc
824*
825* @par Description:
826*   Intraprediction for DC mode with reference neighboring  samples location
827*   pointed by 'pu1_ref' to the TU block  location pointed by 'pu1_dst'  Refer
828*   to section 8.4.4.2.5 in the standard
829*
830* @param[in] pu1_src
831*  UWORD8 pointer to the source
832*
833* @param[out] pu1_dst
834*  UWORD8 pointer to the destination
835*
836* @param[in] src_strd
837*  integer source stride
838*
839* @param[in] dst_strd
840*  integer destination stride
841*
842* @param[in] nt
843*  integer Transform Block size
844*
845* @param[in] mode
846*  integer intraprediction mode
847*
848* @returns
849*
850* @remarks
851*  None
852*
853*******************************************************************************
854*/
855
856
857void ihevc_intra_pred_luma_dc(UWORD8 *pu1_ref,
858                              WORD32 src_strd,
859                              UWORD8 *pu1_dst,
860                              WORD32 dst_strd,
861                              WORD32 nt,
862                              WORD32 mode)
863{
864
865    WORD32 acc_dc;
866    WORD32 dc_val, two_dc_val, three_dc_val;
867    WORD32 i;
868    WORD32 row, col;
869    WORD32 log2nt = 5;
870    WORD32 two_nt, three_nt;
871    UNUSED(mode);
872    UNUSED(src_strd);
873    switch(nt)
874    {
875        case 32:
876            log2nt = 5;
877            break;
878        case 16:
879            log2nt = 4;
880            break;
881        case 8:
882            log2nt = 3;
883            break;
884        case 4:
885            log2nt = 2;
886            break;
887        default:
888            break;
889    }
890    two_nt = 2 * nt;
891    three_nt = 3 * nt;
892
893    acc_dc = 0;
894    /* Calculate DC value for the transform block */
895    for(i = nt; i < two_nt; i++)
896        acc_dc += pu1_ref[i];
897
898    for(i = (two_nt + 1); i <= three_nt; i++)
899        acc_dc += pu1_ref[i];
900
901    dc_val = (acc_dc + nt) >> (log2nt + 1);
902
903    two_dc_val = 2 * dc_val;
904    three_dc_val = 3 * dc_val;
905
906
907    if(nt == 32)
908    {
909        for(row = 0; row < nt; row++)
910            for(col = 0; col < nt; col++)
911                pu1_dst[(row * dst_strd) + col] = dc_val;
912    }
913    else
914    {
915        /* DC filtering for the first top row and first left column */
916        pu1_dst[0] = ((pu1_ref[two_nt - 1] + two_dc_val + pu1_ref[two_nt + 1] + 2)
917                        >> 2);
918
919        for(col = 1; col < nt; col++)
920            pu1_dst[col] = (pu1_ref[two_nt + 1 + col] + three_dc_val + 2) >> 2;
921
922        for(row = 1; row < nt; row++)
923            pu1_dst[row * dst_strd] = (pu1_ref[two_nt - 1 - row] + three_dc_val + 2)
924                            >> 2;
925
926        /* Fill the remaining rows with DC value*/
927        for(row = 1; row < nt; row++)
928            for(col = 1; col < nt; col++)
929                pu1_dst[(row * dst_strd) + col] = dc_val;
930    }
931}
932
933
934
935/**
936*******************************************************************************
937*
938* @brief
939*     Intra prediction interpolation filter for horizontal luma variable.
940*
941* @par Description:
942*      Horizontal intraprediction(mode 10) with reference  samples location
943*      pointed by 'pu1_ref' to the TU block  location pointed by 'pu1_dst'  Refer
944*      to section 8.4.4.2.6 in the standard (Special case)
945*
946* @param[in] pu1_src
947*  UWORD8 pointer to the source
948*
949* @param[out] pu1_dst
950*  UWORD8 pointer to the destination
951*
952* @param[in] src_strd
953*  integer source stride
954*
955* @param[in] dst_strd
956*  integer destination stride
957*
958* @param[in] nt
959*  integer Transform Block size
960*
961* @param[in] mode
962*  integer intraprediction mode
963*
964* @returns
965*
966* @remarks
967*  None
968*
969*******************************************************************************
970*/
971
972
973void ihevc_intra_pred_luma_horz(UWORD8 *pu1_ref,
974                                WORD32 src_strd,
975                                UWORD8 *pu1_dst,
976                                WORD32 dst_strd,
977                                WORD32 nt,
978                                WORD32 mode)
979{
980
981    WORD32 row, col;
982    WORD32 two_nt;
983    WORD16 s2_predpixel;
984    UNUSED(mode);
985    UNUSED(src_strd);
986    two_nt = 2 * nt;
987
988    if(nt == 32)
989    {
990        for(row = 0; row < nt; row++)
991            for(col = 0; col < nt; col++)
992                pu1_dst[(row * dst_strd) + col] = pu1_ref[two_nt - 1 - row];
993    }
994    else
995    {
996        /*Filtering done for the 1st row */
997        for(col = 0; col < nt; col++)
998        {
999            s2_predpixel = pu1_ref[two_nt - 1]
1000                            + ((pu1_ref[two_nt + 1 + col] - pu1_ref[two_nt]) >> 1);
1001            pu1_dst[col] = CLIP_U8(s2_predpixel);
1002        }
1003
1004        /* Replication to next rows*/
1005        for(row = 1; row < nt; row++)
1006            for(col = 0; col < nt; col++)
1007                pu1_dst[(row * dst_strd) + col] = pu1_ref[two_nt - 1 - row];
1008    }
1009}
1010
1011
1012
1013
1014
1015/**
1016*******************************************************************************
1017*
1018* @brief
1019*     Intra prediction interpolation filter for vertical luma variable.
1020*
1021* @par Description:
1022*    Horizontal intraprediction with reference neighboring  samples location
1023*    pointed by 'pu1_ref' to the TU block  location pointed by 'pu1_dst'  Refer
1024*    to section 8.4.4.2.6 in the standard (Special case)
1025*
1026* @param[in] pu1_src
1027*  UWORD8 pointer to the source
1028*
1029* @param[out] pu1_dst
1030*  UWORD8 pointer to the destination
1031*
1032* @param[in] src_strd
1033*  integer source stride
1034*
1035* @param[in] dst_strd
1036*  integer destination stride
1037*
1038* @param[in] nt
1039*  integer Transform Block size
1040*
1041* @param[in] mode
1042*  integer intraprediction mode
1043*
1044* @returns
1045*
1046* @remarks
1047*  None
1048*
1049*******************************************************************************
1050*/
1051
1052
1053void ihevc_intra_pred_luma_ver(UWORD8 *pu1_ref,
1054                               WORD32 src_strd,
1055                               UWORD8 *pu1_dst,
1056                               WORD32 dst_strd,
1057                               WORD32 nt,
1058                               WORD32 mode)
1059{
1060    WORD32 row, col;
1061    WORD16 s2_predpixel;
1062    WORD32 two_nt = 2 * nt;
1063    UNUSED(mode);
1064    UNUSED(src_strd);
1065
1066    if(nt == 32)
1067    {
1068        /* Replication to next columns*/
1069        for(row = 0; row < nt; row++)
1070            for(col = 0; col < nt; col++)
1071                pu1_dst[(row * dst_strd) + col] = pu1_ref[two_nt + 1 + col];
1072    }
1073    else
1074    {
1075        /*Filtering done for the 1st column */
1076        for(row = 0; row < nt; row++)
1077        {
1078            s2_predpixel = pu1_ref[two_nt + 1]
1079                            + ((pu1_ref[two_nt - 1 - row] - pu1_ref[two_nt]) >> 1);
1080            pu1_dst[row * dst_strd] = CLIP_U8(s2_predpixel);
1081        }
1082
1083        /* Replication to next columns*/
1084        for(row = 0; row < nt; row++)
1085            for(col = 1; col < nt; col++)
1086                pu1_dst[(row * dst_strd) + col] = pu1_ref[two_nt + 1 + col];
1087    }
1088}
1089
1090
1091
1092
1093/**
1094*******************************************************************************
1095*
1096* @brief
1097*     Intra prediction interpolation filter for luma mode2.
1098*
1099* @par Description:
1100*    Intraprediction for mode 2 (sw angle) with reference  neighboring samples
1101*    location pointed by 'pu1_ref' to the  TU block location pointed by
1102*    'pu1_dst'  Refer to section 8.4.4.2.6 in the standard
1103*
1104* @param[in] pu1_src
1105*  UWORD8 pointer to the source
1106*
1107* @param[out] pu1_dst
1108*  UWORD8 pointer to the destination
1109*
1110* @param[in] src_strd
1111*  integer source stride
1112*
1113* @param[in] dst_strd
1114*  integer destination stride
1115*
1116* @param[in] nt
1117*  integer Transform Block size
1118*
1119* @param[in] mode
1120*  integer intraprediction mode
1121*
1122* @returns
1123*
1124* @remarks
1125*  None
1126*
1127*******************************************************************************
1128*/
1129
1130
1131void ihevc_intra_pred_luma_mode2(UWORD8 *pu1_ref,
1132                                 WORD32 src_strd,
1133                                 UWORD8 *pu1_dst,
1134                                 WORD32 dst_strd,
1135                                 WORD32 nt,
1136                                 WORD32 mode)
1137{
1138    WORD32 row, col;
1139    WORD32 two_nt = 2 * nt;
1140    WORD32 intra_pred_ang = 32;
1141    WORD32 idx = 0;
1142    UNUSED(mode);
1143    UNUSED(src_strd);
1144    /* For the angle 45, replication is done from the corresponding angle */
1145    /* intra_pred_ang = tan(angle) in q5 format */
1146    for(col = 0; col < nt; col++)
1147    {
1148        idx = ((col + 1) * intra_pred_ang) >> 5; /* Use idx++ */
1149
1150        for(row = 0; row < nt; row++)
1151            pu1_dst[col + (row * dst_strd)] = pu1_ref[two_nt - row - idx - 1];
1152    }
1153
1154}
1155
1156
1157/**
1158*******************************************************************************
1159*
1160* @brief
1161*    Intra prediction interpolation filter for luma mode 18 & mode 34.
1162*
1163* @par Description:
1164*    Intraprediction for mode 34 (ne angle) and  mode 18 (nw angle) with
1165*    reference  neighboring samples location pointed by 'pu1_ref' to the  TU
1166*    block location pointed by 'pu1_dst'
1167*
1168* @param[in] pu1_src
1169*  UWORD8 pointer to the source
1170*
1171* @param[out] pu1_dst
1172*  UWORD8 pointer to the destination
1173*
1174* @param[in] src_strd
1175*  integer source stride
1176*
1177* @param[in] dst_strd
1178*  integer destination stride
1179*
1180* @param[in] nt
1181*  integer Transform Block size
1182*
1183* @param[in] mode
1184*  integer intraprediction mode
1185*
1186* @returns
1187*
1188* @remarks
1189*  None
1190*
1191*******************************************************************************
1192*/
1193
1194
1195void ihevc_intra_pred_luma_mode_18_34(UWORD8 *pu1_ref,
1196                                      WORD32 src_strd,
1197                                      UWORD8 *pu1_dst,
1198                                      WORD32 dst_strd,
1199                                      WORD32 nt,
1200                                      WORD32 mode)
1201{
1202    WORD32 row, col;
1203    WORD32 intra_pred_ang;
1204    WORD32 idx = 0;
1205    WORD32 two_nt = 2 * nt;
1206    UNUSED(src_strd);
1207    intra_pred_ang = 32;    /*Default value*/
1208
1209    /* For mode 18, angle is -45degree */
1210    if(mode == 18)
1211        intra_pred_ang = -32;
1212    /* For mode 34, angle is 45degree */
1213    else if(mode == 34)
1214        intra_pred_ang = 32;
1215    /* For the angle 45 and -45, replication is done from the corresponding angle */
1216    /* No interpolation is done for 45 degree*/
1217    for(row = 0; row < nt; row++)
1218    {
1219        idx = ((row + 1) * intra_pred_ang) >> 5;
1220#if OPT
1221        if(mode == 18)
1222            idx--;
1223        if(mode == 34)
1224            idx++;
1225#endif
1226        for(col = 0; col < nt; col++)
1227            pu1_dst[col + (row * dst_strd)] = pu1_ref[two_nt + col + idx + 1];
1228
1229    }
1230
1231}
1232
1233
1234/**
1235*******************************************************************************
1236*
1237* @brief
1238*    Intra prediction interpolation filter for luma mode 3 to mode 9
1239*
1240* @par Description:
1241*    Intraprediction for mode 3 to 9  (positive angle, horizontal mode ) with
1242*    reference  neighboring samples location pointed by 'pu1_ref' to the  TU
1243*    block location pointed by 'pu1_dst'
1244*
1245* @param[in] pu1_src
1246*  UWORD8 pointer to the source
1247*
1248* @param[out] pu1_dst
1249*  UWORD8 pointer to the destination
1250*
1251* @param[in] src_strd
1252*  integer source stride
1253*
1254* @param[in] dst_strd
1255*  integer destination stride
1256*
1257* @param[in] nt
1258*  integer Transform Block size
1259*
1260* @param[in] mode
1261*  integer intraprediction mode
1262*
1263* @returns
1264*
1265* @remarks
1266*  None
1267*
1268*******************************************************************************
1269*/
1270
1271
1272void ihevc_intra_pred_luma_mode_3_to_9(UWORD8 *pu1_ref,
1273                                       WORD32 src_strd,
1274                                       UWORD8 *pu1_dst,
1275                                       WORD32 dst_strd,
1276                                       WORD32 nt,
1277                                       WORD32 mode)
1278{
1279    WORD32 row, col;
1280    WORD32 two_nt = 2 * nt;
1281    WORD32 intra_pred_ang;
1282    WORD32 idx, ref_main_idx;
1283    WORD32 pos, fract;
1284    UNUSED(src_strd);
1285    /* Intra Pred Angle according to the mode */
1286    intra_pred_ang = gai4_ihevc_ang_table[mode];
1287
1288    /* For the angles other then 45 degree, interpolation btw 2 neighboring */
1289    /* samples dependent on distance to obtain destination sample */
1290
1291    for(col = 0; col < nt; col++)
1292    {
1293        pos = ((col + 1) * intra_pred_ang);
1294        idx = pos >> 5;
1295        fract = pos & (31);
1296
1297        // Do linear filtering
1298        for(row = 0; row < nt; row++)
1299        {
1300            ref_main_idx = two_nt - row - idx - 1;
1301            pu1_dst[col + (row * dst_strd)] = (((32 - fract)
1302                            * pu1_ref[ref_main_idx]
1303                            + fract * pu1_ref[ref_main_idx - 1] + 16) >> 5);
1304        }
1305
1306    }
1307
1308}
1309
1310
1311/**
1312*******************************************************************************
1313*
1314* @brief
1315*   Intra prediction interpolation filter for luma mode 11 to mode 17
1316*
1317* @par Description:
1318*    Intraprediction for mode 11 to 17  (negative angle, horizontal mode )
1319*    with reference  neighboring samples location pointed by 'pu1_ref' to the
1320*    TU block location pointed by 'pu1_dst'
1321*
1322* @param[in] pu1_src
1323*  UWORD8 pointer to the source
1324*
1325* @param[out] pu1_dst
1326*  UWORD8 pointer to the destination
1327*
1328* @param[in] src_strd
1329*  integer source stride
1330*
1331* @param[in] dst_strd
1332*  integer destination stride
1333*
1334* @param[in] nt
1335*  integer Transform Block size
1336*
1337* @param[in] mode
1338*  integer intraprediction mode
1339*
1340* @returns
1341*
1342* @remarks
1343*  None
1344*
1345*******************************************************************************
1346*/
1347
1348
1349void ihevc_intra_pred_luma_mode_11_to_17(UWORD8 *pu1_ref,
1350                                         WORD32 src_strd,
1351                                         UWORD8 *pu1_dst,
1352                                         WORD32 dst_strd,
1353                                         WORD32 nt,
1354                                         WORD32 mode)
1355{
1356    /* This function and ihevc_intra_pred_luma_mode_19_to_25 are same except*/
1357    /* for ref main & side samples assignment,can be combined for */
1358    /* optimzation*/
1359
1360    WORD32 row, col, k;
1361    WORD32 two_nt;
1362    WORD32 intra_pred_ang, inv_ang, inv_ang_sum;
1363    WORD32 idx, ref_main_idx, ref_idx;
1364    WORD32 pos, fract;
1365
1366    UWORD8 ref_temp[2 * MAX_CU_SIZE + 1];
1367    UWORD8 *ref_main;
1368    UNUSED(src_strd);
1369    inv_ang_sum = 128;
1370    two_nt    = 2 * nt;
1371
1372    intra_pred_ang = gai4_ihevc_ang_table[mode];
1373
1374    inv_ang = gai4_ihevc_inv_ang_table[mode - 11];
1375    /* Intermediate reference samples for negative angle modes */
1376    /* This have to be removed during optimization*/
1377    /* For horizontal modes, (ref main = ref left) (ref side = ref above) */
1378
1379    ref_main = ref_temp + nt - 1;
1380    for(k = 0; k < nt + 1; k++)
1381        ref_temp[k + nt - 1] = pu1_ref[two_nt - k];
1382
1383    ref_main = ref_temp + nt - 1;
1384    ref_idx = (nt * intra_pred_ang) >> 5;
1385
1386    /* SIMD Optimization can be done using look-up table for the loop */
1387    /* For negative angled derive the main reference samples from side */
1388    /*  reference samples refer to section 8.4.4.2.6 */
1389    for(k = -1; k > ref_idx; k--)
1390    {
1391        inv_ang_sum += inv_ang;
1392        ref_main[k] = pu1_ref[two_nt + (inv_ang_sum >> 8)];
1393    }
1394
1395    /* For the angles other then 45 degree, interpolation btw 2 neighboring */
1396    /* samples dependent on distance to obtain destination sample */
1397    for(col = 0; col < nt; col++)
1398    {
1399        pos = ((col + 1) * intra_pred_ang);
1400        idx = pos >> 5;
1401        fract = pos & (31);
1402
1403        // Do linear filtering
1404        for(row = 0; row < nt; row++)
1405        {
1406            ref_main_idx = row + idx + 1;
1407            pu1_dst[col + (dst_strd * row)] = (UWORD8)(((32 - fract)
1408                            * ref_main[ref_main_idx]
1409                            + fract * ref_main[ref_main_idx + 1] + 16) >> 5);
1410
1411        }
1412
1413    }
1414
1415}
1416
1417
1418
1419/**
1420*******************************************************************************
1421*
1422* @brief
1423*   Intra prediction interpolation filter for luma mode 19 to mode 25
1424*
1425* @par Description:
1426*    Intraprediction for mode 19 to 25  (negative angle, vertical mode ) with
1427*    reference  neighboring samples location pointed by 'pu1_ref' to the  TU
1428*    block location pointed by 'pu1_dst'
1429*
1430* @param[in] pu1_src
1431*  UWORD8 pointer to the source
1432*
1433* @param[out] pu1_dst
1434*  UWORD8 pointer to the destination
1435*
1436* @param[in] src_strd
1437*  integer source stride
1438*
1439* @param[in] dst_strd
1440*  integer destination stride
1441*
1442* @param[in] nt
1443*  integer Transform Block size
1444*
1445* @param[in] mode
1446*  integer intraprediction mode
1447*
1448* @returns
1449*
1450* @remarks
1451*  None
1452*
1453*******************************************************************************
1454*/
1455
1456
1457void ihevc_intra_pred_luma_mode_19_to_25(UWORD8 *pu1_ref,
1458                                         WORD32 src_strd,
1459                                         UWORD8 *pu1_dst,
1460                                         WORD32 dst_strd,
1461                                         WORD32 nt,
1462                                         WORD32 mode)
1463{
1464
1465    WORD32 row, col, k;
1466    WORD32 two_nt, intra_pred_ang, idx;
1467    WORD32 inv_ang, inv_ang_sum, pos, fract;
1468    WORD32 ref_main_idx, ref_idx;
1469    UWORD8 ref_temp[(2 * MAX_CU_SIZE) + 1];
1470    UWORD8 *ref_main;
1471    UNUSED(src_strd);
1472    two_nt = 2 * nt;
1473    intra_pred_ang = gai4_ihevc_ang_table[mode];
1474    inv_ang = gai4_ihevc_inv_ang_table[mode - 12];
1475
1476    /* Intermediate reference samples for negative angle modes */
1477    /* This have to be removed during optimization*/
1478    /* For horizontal modes, (ref main = ref above) (ref side = ref left) */
1479    ref_main = ref_temp + nt - 1;
1480    for(k = 0; k < (nt + 1); k++)
1481        ref_temp[k + nt - 1] = pu1_ref[two_nt + k];
1482
1483    ref_idx = (nt * intra_pred_ang) >> 5;
1484    inv_ang_sum = 128;
1485
1486    /* SIMD Optimization can be done using look-up table for the loop */
1487    /* For negative angled derive the main reference samples from side */
1488    /*  reference samples refer to section 8.4.4.2.6 */
1489    for(k = -1; k > ref_idx; k--)
1490    {
1491        inv_ang_sum += inv_ang;
1492        ref_main[k] = pu1_ref[two_nt - (inv_ang_sum >> 8)];
1493    }
1494
1495    for(row = 0; row < nt; row++)
1496    {
1497        pos = ((row + 1) * intra_pred_ang);
1498        idx = pos >> 5;
1499        fract = pos & (31);
1500
1501        // Do linear filtering
1502        for(col = 0; col < nt; col++)
1503        {
1504            ref_main_idx = col + idx + 1;
1505            pu1_dst[(row * dst_strd) + col] = (UWORD8)(((32 - fract)
1506                            * ref_main[ref_main_idx]
1507                            + fract * ref_main[ref_main_idx + 1] + 16) >> 5);
1508
1509        }
1510
1511    }
1512
1513}
1514
1515
1516
1517/**
1518*******************************************************************************
1519*
1520* @brief
1521*    Intra prediction interpolation filter for luma mode 27 to mode 33
1522*
1523* @par Description:
1524*    Intraprediction for mode 27 to 33  (positive angle, vertical mode ) with
1525*    reference  neighboring samples location pointed by 'pu1_ref' to the  TU
1526*    block location pointed by 'pu1_dst'
1527*
1528* @param[in] pu1_src
1529*  UWORD8 pointer to the source
1530*
1531* @param[out] pu1_dst
1532*  UWORD8 pointer to the destination
1533*
1534* @param[in] src_strd
1535*  integer source stride
1536*
1537* @param[in] dst_strd
1538*  integer destination stride
1539*
1540* @param[in] nt
1541*  integer Transform Block size
1542*
1543* @param[in] mode
1544*  integer intraprediction mode
1545*
1546* @returns
1547*
1548* @remarks
1549*  None
1550*
1551*******************************************************************************
1552*/
1553
1554
1555void ihevc_intra_pred_luma_mode_27_to_33(UWORD8 *pu1_ref,
1556                                         WORD32 src_strd,
1557                                         UWORD8 *pu1_dst,
1558                                         WORD32 dst_strd,
1559                                         WORD32 nt,
1560                                         WORD32 mode)
1561{
1562    WORD32 row, col;
1563    WORD32 two_nt, pos, fract;
1564    WORD32 intra_pred_ang;
1565    WORD32 idx, ref_main_idx;
1566    UNUSED(src_strd);
1567    two_nt = 2 * nt;
1568    intra_pred_ang = gai4_ihevc_ang_table[mode];
1569
1570    for(row = 0; row < nt; row++)
1571    {
1572        pos = ((row + 1) * intra_pred_ang);
1573        idx = pos >> 5;
1574        fract = pos & (31);
1575
1576        // Do linear filtering
1577        for(col = 0; col < nt; col++)
1578        {
1579            ref_main_idx = two_nt + col + idx + 1;
1580            pu1_dst[col + (row * dst_strd)] = (((32 - fract)
1581                            * pu1_ref[ref_main_idx]
1582                            + fract * pu1_ref[ref_main_idx + 1] + 16) >> 5);
1583        }
1584
1585    }
1586
1587}
1588
1589