ihevc_intra_ref_substitution_a9q.c revision a6f2c9632918ab0a365873930bf29cc26ff7dd6c
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*  ihevcd_intra_ref_substitution.c
22*
23* @brief
24*  Contains ref substitution functions
25*
26* @author
27*  Naveen
28*
29* @par List of Functions:
30* @remarks
31*  None
32*
33*******************************************************************************
34*/
35/*****************************************************************************/
36/* File Includes                                                             */
37/*****************************************************************************/
38#include <stdio.h>
39#include <stddef.h>
40#include <stdlib.h>
41#include <string.h>
42
43#include "ihevc_typedefs.h"
44#include "ihevc_platform_macros.h"
45#include "ihevc_intra_pred.h"
46#include "ihevc_mem_fns.h"
47#include "ihevc_chroma_intra_pred.h"
48#include "ihevc_common_tables.h"
49#include "ihevc_defs.h"
50#include "ihevc_mem_fns.h"
51#include "ihevc_macros.h"
52
53#define MAX_CU_SIZE 64
54#define BIT_DEPTH 8
55#define T32_4NT 128
56#define T16_4NT 64
57#define T16C_4NT 64
58#define T8C_4NT 32
59/****************************************************************************/
60/* Function Macros                                                          */
61/****************************************************************************/
62
63#define GET_BIT(y,x) ((y) & (1 << x)) && (1 << x)
64#define GET_BITS(y,x) ((y) & (1 << x)) && (1 << x)
65/**
66*******************************************************************************
67*
68* @brief
69*  Reference substitution process for samples unavailable  for prediction
70* Refer to section 8.4.4.2.2
71*
72* @par Description:
73*
74*
75* @param[in] pu1_top_left
76*  UWORD8 pointer to the top-left
77*
78* @param[in] pu1_top
79*  UWORD8 pointer to the top
80*
81* @param[in] pu1_left
82*  UWORD8 pointer to the left
83*
84* @param[in] src_strd
85*  WORD32 Source stride
86*
87* @param[in] nbr_flags
88*  WORD32 neighbor availability flags
89*
90* @param[in] nt
91*  WORD32 transform Block size
92*
93* @param[in] dst_strd
94*  WORD32 Destination stride
95*
96* @returns
97*
98* @remarks
99*  None
100*
101*******************************************************************************
102*/
103
104void ihevc_intra_pred_chroma_ref_substitution_a9q(UWORD8 *pu1_top_left,
105                                                  UWORD8 *pu1_top,
106                                                  UWORD8 *pu1_left,
107                                                  WORD32 src_strd,
108                                                  WORD32 nt,
109                                                  WORD32 nbr_flags,
110                                                  UWORD8 *pu1_dst,
111                                                  WORD32 dst_strd)
112{
113    UWORD8 pu1_ref_u, pu1_ref_v;
114    WORD32 dc_val, i, j;
115    WORD32 total_samples = (4 * nt) + 1;
116    WORD32 get_bits;
117    WORD32 next;
118    WORD32 bot_left, left, top, tp_right, tp_left;
119    WORD32 idx, nbr_id_from_bl, frwd_nbr_flag;
120    WORD32 a_nbr_flag[5];
121    UNUSED(dst_strd);
122    /* Neighbor Flag Structure*/
123    /* WORD32 nbr_flags MSB-->LSB   TOP LEFT | TOP-RIGHT |  TOP   | LEFT    | BOTTOM LEFT*/
124    /*                              (1 bit)     (4 bits)  (4 bits) (4 bits)  (4 bits)  */
125
126    if(nbr_flags == 0)
127    {
128/* If no neighbor flags are present, fill the neighbor samples with DC value */
129        /*dc_val = 1 << (BIT_DEPTH - 1);*/
130        dc_val = 1 << (8 - 1);
131        for(i = 0; i < (2 * total_samples); i++)
132        {
133            pu1_dst[i] = dc_val;
134        }
135    }
136    else
137    {
138        /* Else fill the corresponding samples */
139
140        /* Check for the neighbors availibility */
141        tp_left     = (nbr_flags & 0x10000);
142        tp_right    = (nbr_flags & 0x0f000);
143        top         = (nbr_flags & 0x00f00);
144        left        = (nbr_flags & 0x000f0);
145        bot_left    = (nbr_flags & 0x0000f);
146
147        /* Fill nbrs depending on avalibility */
148        /* Top -Left nbrs  */
149        if(0 != tp_left)
150        {
151            pu1_dst[(4 * nt)] = *pu1_top_left; // U top-left sample
152            pu1_dst[(4 * nt) + 1] = *(pu1_top_left + 1); // V top-left sample
153        }
154        /* Left nbrs  */
155        if(0 != left)
156        {
157            for(i = 0, j = 0; i < (2 * nt); i += 2)
158            {
159                pu1_dst[(4 * nt) - 2 - i] = pu1_left[j * src_strd]; // U left samples
160                pu1_dst[(4 * nt) - 1 - i] = pu1_left[(j * src_strd) + 1]; // V left samples
161                j++;
162            }
163        }
164        /* Bottom - Left nbrs  */
165        if(0 != bot_left)
166        {
167            for(i = (2 * nt), j = nt; i < (4 * nt); i += 2)
168            {
169                pu1_dst[(4 * nt) - 2 - i] = pu1_left[j * src_strd]; // U left samples
170                pu1_dst[(4 * nt) - 1 - i] = pu1_left[(j * src_strd) + 1]; // V left samples
171                j++;
172            }
173        }
174        /* Top nbrs  */
175        if(0 != top)
176        {
177            ihevc_memcpy_mul_8_a9q(&pu1_dst[(4 * nt) + 2], pu1_top, 2 * nt);
178            // U-V interleaved Top-top right samples
179        }
180
181        /* Top - Right nbrs  */
182        if(0 != tp_right)
183        {
184            ihevc_memcpy_mul_8_a9q(&pu1_dst[(4 * nt) + 2 + 2 * nt], pu1_top + 2 * nt, 2 * nt);
185            // U-V interleaved Top-top right samples
186        }
187
188        if(nt == 4)
189        {
190            /* 1 bit extraction for all the neighboring blocks */
191            tp_left = (nbr_flags & 0x10000) >> 16;
192            bot_left = (nbr_flags & 0x8) >> 3;
193            left = (nbr_flags & 0x80) >> 7;
194            top = (nbr_flags & 0x100) >> 8;
195            tp_right = (nbr_flags & 0x1000) >> 12;
196
197            next = 1;
198            a_nbr_flag[0] = bot_left;
199            a_nbr_flag[1] = left;
200            a_nbr_flag[2] = tp_left;
201            a_nbr_flag[3] = top;
202            a_nbr_flag[4] = tp_right;
203
204            /* If bottom -left is not available, reverse substitution process*/
205            if(bot_left == 0)
206            {
207                /* Check for the 1st available sample from bottom-left*/
208                while(!a_nbr_flag[next])
209                    next++;
210
211                /* If Left, top-left are available*/
212                if(next <= 2)
213                {
214                    UWORD16 *pu2_dst;
215                    idx = (nt * next);
216                    pu2_dst = (UWORD16 *)&pu1_dst[2 * idx];
217                    ihevc_memset_16bit_a9q((UWORD16 *)pu1_dst, pu2_dst[0], idx);
218                }
219                else /* If top, top-right are available */
220                {
221                    UWORD16 *pu2_dst;
222                    /* Idx is changed to copy 1 pixel value for top-left ,if top-left is not available*/
223                    idx = (nt * (next - 1)) + 1;
224                    pu2_dst = (UWORD16 *)&pu1_dst[2 * idx];
225                    ihevc_memset_16bit_a9q((UWORD16 *)pu1_dst, pu2_dst[0], idx);
226                }
227            }
228
229            if(left == 0)
230            {
231                UWORD16 *pu2_dst = (UWORD16 *)&pu1_dst[(2 * nt) - 2];
232                ihevc_memset_16bit_a9q((UWORD16 *)&pu1_dst[(2 * nt)], pu2_dst[0], nt);
233
234
235            }
236            if(tp_left == 0)
237            {
238                pu1_dst[4 * nt] = pu1_dst[(4 * nt) - 2];
239                pu1_dst[(4 * nt) + 1] = pu1_dst[(4 * nt) - 1];
240            }
241            if(top == 0)
242            {
243                UWORD16 *pu2_dst = (UWORD16 *)&pu1_dst[(4 * nt)];
244                ihevc_memset_16bit_a9q((UWORD16 *)&pu1_dst[(4 * nt) + 2], pu2_dst[0], nt);
245
246
247            }
248            if(tp_right == 0)
249            {
250                UWORD16 *pu2_dst = (UWORD16 *)&pu1_dst[(6 * nt)];
251                ihevc_memset_16bit_a9q((UWORD16 *)&pu1_dst[(6 * nt) + 2], pu2_dst[0], nt);
252
253
254            }
255        }
256        else if(nt == 8)
257        {
258            WORD32 nbr_flags_temp = 0;
259            nbr_flags_temp = ((nbr_flags & 0xC) >> 2) + ((nbr_flags & 0xC0) >> 4)
260                            + ((nbr_flags & 0x300) >> 4)
261                            + ((nbr_flags & 0x3000) >> 6)
262                            + ((nbr_flags & 0x10000) >> 8);
263
264            /* compute trailing zeors based on nbr_flag for substitution process of below left see section .*/
265            /* as each bit in nbr flags corresponds to 8 pels for bot_left, left, top and topright but 1 pel for topleft */
266            {
267                nbr_id_from_bl = look_up_trailing_zeros(nbr_flags_temp & 0XF) * 4; /* for bottom left and left */
268                if(nbr_id_from_bl == 32)
269                    nbr_id_from_bl = 16;
270                if(nbr_id_from_bl == 16)
271                {
272                    /* for top left : 1 pel per nbr bit */
273                    if(!((nbr_flags_temp >> 8) & 0x1))
274                    {
275                        nbr_id_from_bl++;
276                        nbr_id_from_bl += look_up_trailing_zeros((nbr_flags_temp >> 4) & 0xF) * 4; /* top and top right;  8 pels per nbr bit */
277
278                    }
279                }
280                /* Reverse Substitution Process*/
281                if(nbr_id_from_bl)
282                {
283                    /* Replicate the bottom-left and subsequent unavailable pixels with the 1st available pixel above */
284                    pu1_ref_u = pu1_dst[2 * nbr_id_from_bl];
285                    pu1_ref_v = pu1_dst[(2 * nbr_id_from_bl) + 1];
286                    for(i = 2 * (nbr_id_from_bl - 1); i >= 0; i -= 2)
287                    {
288                        pu1_dst[i] = pu1_ref_u;
289                        pu1_dst[i + 1] = pu1_ref_v;
290                    }
291                }
292            }
293
294            /* for the loop of 4*Nt+1 pixels (excluding pixels computed from reverse substitution) */
295            while(nbr_id_from_bl < ((T8C_4NT)+1))
296            {
297                /* To Obtain the next unavailable idx flag after reverse neighbor substitution  */
298                /* Divide by 8 to obtain the original index */
299                frwd_nbr_flag = (nbr_id_from_bl >> 2); /*+ (nbr_id_from_bl & 0x1);*/
300
301                /* The Top-left flag is at the last bit location of nbr_flags*/
302                if(nbr_id_from_bl == (T8C_4NT / 2))
303                {
304                    get_bits = GET_BIT(nbr_flags_temp, 8);
305
306                    /* only pel substitution for TL */
307                    if(!get_bits)
308                    {
309                        pu1_dst[2 * nbr_id_from_bl] = pu1_dst[(2 * nbr_id_from_bl) - 2];
310                        pu1_dst[(2 * nbr_id_from_bl) + 1] = pu1_dst[(2 * nbr_id_from_bl) - 1];
311                    }
312                }
313                else
314                {
315                    get_bits = GET_BIT(nbr_flags_temp, frwd_nbr_flag);
316                    if(!get_bits)
317                    {
318                        UWORD16 *pu2_dst;
319                        /* 8 pel substitution (other than TL) */
320                        pu2_dst = (UWORD16 *)&pu1_dst[(2 * nbr_id_from_bl) - 2];
321                        ihevc_memset_16bit_a9q((UWORD16 *)(pu1_dst + (2 * nbr_id_from_bl)), pu2_dst[0], 4);
322                    }
323
324                }
325                nbr_id_from_bl += (nbr_id_from_bl == (T8C_4NT / 2)) ? 1 : 4;
326            }
327
328        }
329        else if(nt == 16)
330        {
331            /* compute trailing ones based on mbr_flag for substitution process of below left see section .*/
332            /* as each bit in nbr flags corresponds to 4 pels for bot_left, left, top and topright but 1 pel for topleft */
333            {
334                nbr_id_from_bl = look_up_trailing_zeros((nbr_flags & 0XFF)) * 4; /* for bottom left and left */
335
336                if(nbr_id_from_bl == 32)
337                {
338                    /* for top left : 1 pel per nbr bit */
339                    if(!((nbr_flags >> 16) & 0x1))
340                    {
341                        /* top left not available */
342                        nbr_id_from_bl++;
343                        /* top and top right;  4 pels per nbr bit */
344                        nbr_id_from_bl += look_up_trailing_zeros((nbr_flags >> 8) & 0xFF) * 4;
345                    }
346                }
347                /* Reverse Substitution Process*/
348                if(nbr_id_from_bl)
349                {
350                    /* Replicate the bottom-left and subsequent unavailable pixels with the 1st available pixel above */
351                    pu1_ref_u = pu1_dst[2 * nbr_id_from_bl];
352                    pu1_ref_v = pu1_dst[2 * nbr_id_from_bl + 1];
353                    for(i = (2 * (nbr_id_from_bl - 1)); i >= 0; i -= 2)
354                    {
355                        pu1_dst[i] = pu1_ref_u;
356                        pu1_dst[i + 1] = pu1_ref_v;
357                    }
358                }
359            }
360
361            /* for the loop of 4*Nt+1 pixels (excluding pixels computed from reverse substitution) */
362            while(nbr_id_from_bl < ((T16C_4NT)+1))
363            {
364                /* To Obtain the next unavailable idx flag after reverse neighbor substitution  */
365                /* Devide by 4 to obtain the original index */
366                frwd_nbr_flag = (nbr_id_from_bl >> 2); /*+ (nbr_id_from_bl & 0x1);*/
367
368                /* The Top-left flag is at the last bit location of nbr_flags*/
369                if(nbr_id_from_bl == (T16C_4NT / 2))
370                {
371                    get_bits = GET_BIT(nbr_flags, 16);
372                    /* only pel substitution for TL */
373                    if(!get_bits)
374                    {
375                        pu1_dst[2 * nbr_id_from_bl] = pu1_dst[(2 * nbr_id_from_bl) - 2];
376                        pu1_dst[(2 * nbr_id_from_bl) + 1] = pu1_dst[(2 * nbr_id_from_bl) - 1];
377                    }
378                }
379                else
380                {
381                    get_bits = GET_BIT(nbr_flags, frwd_nbr_flag);
382                    if(!get_bits)
383                    {
384                        UWORD16 *pu2_dst;
385                        /* 4 pel substitution (other than TL) */
386                        pu2_dst = (UWORD16 *)&pu1_dst[(2 * nbr_id_from_bl) - 2];
387                        ihevc_memset_16bit_a9q((UWORD16 *)(pu1_dst + (2 * nbr_id_from_bl)), pu2_dst[0], 4);
388                    }
389
390                }
391                nbr_id_from_bl += (nbr_id_from_bl == (T16C_4NT / 2)) ? 1 : 4;
392            }
393        }
394    }
395}
396
397
398void ihevc_intra_pred_luma_ref_substitution_a9q(UWORD8 *pu1_top_left,
399                                                UWORD8 *pu1_top,
400                                                UWORD8 *pu1_left,
401                                                WORD32 src_strd,
402                                                WORD32 nt,
403                                                WORD32 nbr_flags,
404                                                UWORD8 *pu1_dst,
405                                                WORD32 dst_strd)
406{
407    UWORD8 pu1_ref;
408    WORD32 dc_val, i;
409    WORD32 total_samples = (4 * nt) + 1;
410    WORD32 two_nt = 2 * nt;
411
412    WORD32 three_nt = 3 * nt;
413    WORD32 get_bits;
414    WORD32 next;
415    WORD32 bot_left, left, top, tp_right, tp_left;
416
417    WORD32 idx, nbr_id_from_bl, frwd_nbr_flag;
418    UNUSED(dst_strd);
419    /*dc_val = 1 << (BIT_DEPTH - 1);*/
420    dc_val = 1 << (8 - 1);
421
422
423    /* Neighbor Flag Structure*/
424    /* MSB ---> LSB */
425    /*    Top-Left | Top-Right | Top | Left | Bottom-Left
426              1         4         4     4         4
427     */
428    /* If no neighbor flags are present, fill the neighbor samples with DC value */
429    if(nbr_flags == 0)
430    {
431        for(i = 0; i < total_samples; i++)
432        {
433            pu1_dst[i] = dc_val;
434        }
435    }
436    else
437    {
438        if(nt <= 8)
439        {
440            /* 1 bit extraction for all the neighboring blocks */
441            tp_left = (nbr_flags & 0x10000) >> 16;
442            bot_left = (nbr_flags & 0x8) >> 3;
443            left = (nbr_flags & 0x80) >> 7;
444            top = (nbr_flags & 0x100) >> 8;
445            tp_right = (nbr_flags & 0x1000) >> 12;
446
447            /* Else fill the corresponding samples */
448            if(tp_left)
449                pu1_dst[two_nt] = *pu1_top_left;
450            else
451                pu1_dst[two_nt] = 0;
452
453
454            if(left)
455            {
456                for(i = 0; i < nt; i++)
457                    pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
458            }
459            else
460            {
461                ihevc_memset_a9q(&pu1_dst[two_nt - 1 - (nt - 1)], 0, nt);
462            }
463
464
465            if(bot_left)
466            {
467                for(i = nt; i < two_nt; i++)
468                    pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
469            }
470            else
471            {
472                ihevc_memset_a9q(&pu1_dst[two_nt - 1 - (two_nt - 1)], 0, nt);
473            }
474
475
476            if(top)
477            {
478                ihevc_memcpy_a9q(&pu1_dst[two_nt + 1], pu1_top, nt);
479            }
480            else
481            {
482                ihevc_memset_a9q(&pu1_dst[two_nt + 1], 0, nt);
483            }
484
485            if(tp_right)
486            {
487                ihevc_memcpy_a9q(&pu1_dst[two_nt + 1 + nt], pu1_top + nt, nt);
488            }
489            else
490            {
491                ihevc_memset_a9q(&pu1_dst[two_nt + 1 + nt], 0, nt);
492            }
493            next = 1;
494
495            /* If bottom -left is not available, reverse substitution process*/
496            if(bot_left == 0)
497            {
498                WORD32 a_nbr_flag[5];
499                a_nbr_flag[0] = bot_left;
500                a_nbr_flag[1] = left;
501                a_nbr_flag[2] = tp_left;
502                a_nbr_flag[3] = top;
503                a_nbr_flag[4] = tp_right;
504
505                /* Check for the 1st available sample from bottom-left*/
506                while(!a_nbr_flag[next])
507                    next++;
508
509                /* If Left, top-left are available*/
510                if(next <= 2)
511                {
512                    idx = nt * next;
513                    pu1_ref = pu1_dst[idx];
514                    for(i = 0; i < idx; i++)
515                        pu1_dst[i] = pu1_ref;
516                }
517                else /* If top, top-right are available */
518                {
519                    /* Idx is changed to copy 1 pixel value for top-left ,if top-left is not available*/
520                    idx = (nt * (next - 1)) + 1;
521                    pu1_ref = pu1_dst[idx];
522                    for(i = 0; i < idx; i++)
523                        pu1_dst[i] = pu1_ref;
524                }
525            }
526
527            /* Forward Substitution Process */
528            /* If left is Unavailable, copy the last bottom-left value */
529            if(left == 0)
530            {
531                ihevc_memset_a9q(&pu1_dst[nt], pu1_dst[nt - 1], nt);
532
533            }
534            /* If top-left is Unavailable, copy the last left value */
535            if(tp_left == 0)
536                pu1_dst[two_nt] = pu1_dst[two_nt - 1];
537            /* If top is Unavailable, copy the last top-left value */
538            if(top == 0)
539            {
540                ihevc_memset_a9q(&pu1_dst[two_nt + 1], pu1_dst[two_nt], nt);
541            }
542            /* If to right is Unavailable, copy the last top value */
543            if(tp_right == 0)
544            {
545                ihevc_memset_a9q(&pu1_dst[three_nt + 1], pu1_dst[three_nt], nt);
546
547            }
548        }
549
550        if(nt == 16)
551        {
552            WORD32 nbr_flags_temp = 0;
553            nbr_flags_temp = ((nbr_flags & 0xC) >> 2) + ((nbr_flags & 0xC0) >> 4)
554                            + ((nbr_flags & 0x300) >> 4)
555                            + ((nbr_flags & 0x3000) >> 6)
556                            + ((nbr_flags & 0x10000) >> 8);
557
558            /* Else fill the corresponding samples */
559            if(nbr_flags & 0x10000)
560                pu1_dst[two_nt] = *pu1_top_left;
561            else
562                pu1_dst[two_nt] = 0;
563
564            if(nbr_flags & 0xC0)
565            {
566                for(i = 0; i < nt; i++)
567                    pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
568            }
569            else
570            {
571                ihevc_memset_mul_8_a9q(&pu1_dst[two_nt - 1 - (nt - 1)], 0, nt);
572            }
573
574            /* Bottom - left availability is checked for every 8x8 TU position and set accordingly */
575            {
576                if(nbr_flags & 0x8)
577                {
578                    for(i = nt; i < (nt + 8); i++)
579                    pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
580                }
581                else
582                {
583                    ihevc_memset_mul_8_a9q(&pu1_dst[nt - 8], 0, 8);
584                }
585
586                if(nbr_flags & 0x4)
587                {
588                    for(i = (nt + 8); i < two_nt; i++)
589                        pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
590                }
591                else
592                {
593                    ihevc_memset_mul_8_a9q(&pu1_dst[0], 0, 8);
594                }
595            }
596
597
598            if(nbr_flags & 0x300)
599            {
600                ihevc_memcpy_mul_8_a9q(&pu1_dst[two_nt + 1], pu1_top, nt);
601            }
602            else
603            {
604                ihevc_memset_mul_8_a9q(&pu1_dst[two_nt + 1], 0, nt);
605            }
606
607            if(nbr_flags & 0x3000)
608            {
609                ihevc_memcpy_mul_8_a9q(&pu1_dst[two_nt + 1 + nt], pu1_top + nt, nt);
610            }
611            else
612            {
613                ihevc_memset_mul_8_a9q(&pu1_dst[two_nt + 1 + nt], 0, nt);
614            }
615            /* compute trailing zeors based on nbr_flag for substitution process of below left see section .*/
616            /* as each bit in nbr flags corresponds to 8 pels for bot_left, left, top and topright but 1 pel for topleft */
617            {
618                nbr_id_from_bl = look_up_trailing_zeros(nbr_flags_temp & 0XF) * 8; /* for below left and left */
619
620                if(nbr_id_from_bl == 64)
621                    nbr_id_from_bl = 32;
622
623                if(nbr_id_from_bl == 32)
624                {
625                    /* for top left : 1 pel per nbr bit */
626                    if(!((nbr_flags_temp >> 8) & 0x1))
627                    {
628                        nbr_id_from_bl++;
629                        nbr_id_from_bl += look_up_trailing_zeros((nbr_flags_temp >> 4) & 0xF) * 8; /* top and top right;  8 pels per nbr bit */
630                        //nbr_id_from_bl += idx * 8;
631                    }
632                }
633                /* Reverse Substitution Process*/
634                if(nbr_id_from_bl)
635                {
636                    /* Replicate the bottom-left and subsequent unavailable pixels with the 1st available pixel above */
637                    pu1_ref = pu1_dst[nbr_id_from_bl];
638                    for(i = (nbr_id_from_bl - 1); i >= 0; i--)
639                    {
640                        pu1_dst[i] = pu1_ref;
641                    }
642                }
643            }
644
645            /* for the loop of 4*Nt+1 pixels (excluding pixels computed from reverse substitution) */
646            while(nbr_id_from_bl < ((T16_4NT) + 1))
647            {
648                /* To Obtain the next unavailable idx flag after reverse neighbor substitution  */
649                /* Devide by 8 to obtain the original index */
650                frwd_nbr_flag = (nbr_id_from_bl >> 3); /*+ (nbr_id_from_bl & 0x1);*/
651
652                /* The Top-left flag is at the last bit location of nbr_flags*/
653                if(nbr_id_from_bl == (T16_4NT / 2))
654                {
655                    get_bits = GET_BITS(nbr_flags_temp, 8);
656
657                    /* only pel substitution for TL */
658                    if(!get_bits)
659                        pu1_dst[nbr_id_from_bl] = pu1_dst[nbr_id_from_bl - 1];
660                }
661                else
662                {
663                    get_bits = GET_BITS(nbr_flags_temp, frwd_nbr_flag);
664                    if(!get_bits)
665                    {
666                        /* 8 pel substitution (other than TL) */
667                        pu1_ref = pu1_dst[nbr_id_from_bl - 1];
668                        ihevc_memset_mul_8_a9q(pu1_dst + nbr_id_from_bl, pu1_ref, 8);
669
670
671                    }
672
673                }
674                nbr_id_from_bl += (nbr_id_from_bl == (T16_4NT / 2)) ? 1 : 8;
675            }
676
677
678        }
679
680        if(nt == 32)
681        {
682            /* Else fill the corresponding samples */
683            if(nbr_flags & 0x10000)
684                pu1_dst[two_nt] = *pu1_top_left;
685            else
686                pu1_dst[two_nt] = 0;
687
688            if(nbr_flags & 0xF0)
689            {
690                for(i = 0; i < nt; i++)
691                    pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
692            }
693            else
694            {
695                ihevc_memset_mul_8_a9q(&pu1_dst[two_nt - 1 - (nt - 1)], 0, nt);
696            }
697
698            /* Bottom - left availability is checked for every 8x8 TU position and set accordingly */
699            {
700                if(nbr_flags & 0x8)
701                {
702                    for(i = nt; i < (nt + 8); i++)
703                    pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
704                }
705                else
706                {
707                    ihevc_memset_mul_8_a9q(&pu1_dst[24], 0, 8);
708                }
709
710                if(nbr_flags & 0x4)
711                {
712                    for(i = (nt + 8); i < (nt + 16); i++)
713                        pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
714                }
715                else
716                {
717                    ihevc_memset_mul_8_a9q(&pu1_dst[16], 0, 8);
718                }
719
720                if(nbr_flags & 0x2)
721                {
722                    for(i = (nt + 16); i < (nt + 24); i++)
723                        pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
724                }
725                else
726                {
727                    ihevc_memset_mul_8_a9q(&pu1_dst[8], 0, 8);
728                }
729
730                if(nbr_flags & 0x1)
731                {
732                    for(i = (nt + 24); i < (two_nt); i++)
733                        pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd];
734                }
735                else
736                {
737                    ihevc_memset_mul_8_a9q(&pu1_dst[0], 0, 8);
738                }
739            }
740
741            if(nbr_flags & 0xF00)
742            {
743                ihevc_memcpy_mul_8_a9q(&pu1_dst[two_nt + 1], pu1_top, nt);
744            }
745            else
746            {
747                ihevc_memset_mul_8_a9q(&pu1_dst[two_nt + 1], 0, nt);
748            }
749
750            if(nbr_flags & 0xF000)
751            {
752                ihevc_memcpy_mul_8_a9q(&pu1_dst[two_nt + 1 + nt], pu1_top + nt, nt);
753            }
754            else
755            {
756                ihevc_memset_mul_8_a9q(&pu1_dst[two_nt + 1 + nt], 0, nt);
757            }
758            /* compute trailing ones based on mbr_flag for substitution process of below left see section .*/
759            /* as each bit in nbr flags corresponds to 8 pels for bot_left, left, top and topright but 1 pel for topleft */
760            {
761                nbr_id_from_bl = look_up_trailing_zeros((nbr_flags & 0XFF)) * 8; /* for below left and left */
762
763                if(nbr_id_from_bl == 64)
764                {
765                    /* for top left : 1 pel per nbr bit */
766                    if(!((nbr_flags >> 16) & 0x1))
767                    {
768                        /* top left not available */
769                        nbr_id_from_bl++;
770                        /* top and top right;  8 pels per nbr bit */
771                        nbr_id_from_bl += look_up_trailing_zeros((nbr_flags >> 8) & 0xFF) * 8;
772                    }
773                }
774                /* Reverse Substitution Process*/
775                if(nbr_id_from_bl)
776                {
777                    /* Replicate the bottom-left and subsequent unavailable pixels with the 1st available pixel above */
778                    pu1_ref = pu1_dst[nbr_id_from_bl];
779                    for(i = (nbr_id_from_bl - 1); i >= 0; i--)
780                        pu1_dst[i] = pu1_ref;
781                }
782            }
783
784            /* for the loop of 4*Nt+1 pixels (excluding pixels computed from reverse substitution) */
785            while(nbr_id_from_bl < ((T32_4NT) + 1))
786            {
787                /* To Obtain the next unavailable idx flag after reverse neighbor substitution  */
788                /* Devide by 8 to obtain the original index */
789                frwd_nbr_flag = (nbr_id_from_bl >> 3); /*+ (nbr_id_from_bl & 0x1);*/
790
791                /* The Top-left flag is at the last bit location of nbr_flags*/
792                if(nbr_id_from_bl == (T32_4NT / 2))
793                {
794                    get_bits = GET_BITS(nbr_flags, 16);
795                    /* only pel substitution for TL */
796                    if(!get_bits)
797                        pu1_dst[nbr_id_from_bl] = pu1_dst[nbr_id_from_bl - 1];
798                }
799                else
800                {
801                    get_bits = GET_BITS(nbr_flags, frwd_nbr_flag);
802                    if(!get_bits)
803                    {
804                        /* 8 pel substitution (other than TL) */
805                        pu1_ref = pu1_dst[nbr_id_from_bl - 1];
806                        ihevc_memset_mul_8_a9q(&pu1_dst[nbr_id_from_bl], pu1_ref, 8);
807
808                    }
809
810                }
811                nbr_id_from_bl += (nbr_id_from_bl == (T32_4NT / 2)) ? 1 : 8;
812            }
813        }
814
815    }
816}
817