xref: /aosp_15_r20/external/libmpeg2/common/ideint_utils.c (revision a97c2a1f0a796dc32bed80d3353c69c5fc07c750)
1*a97c2a1fSXin Li /******************************************************************************
2*a97c2a1fSXin Li  *
3*a97c2a1fSXin Li  * Copyright (C) 2015 The Android Open Source Project
4*a97c2a1fSXin Li  *
5*a97c2a1fSXin Li  * Licensed under the Apache License, Version 2.0 (the "License");
6*a97c2a1fSXin Li  * you may not use this file except in compliance with the License.
7*a97c2a1fSXin Li  * You may obtain a copy of the License at:
8*a97c2a1fSXin Li  *
9*a97c2a1fSXin Li  * http://www.apache.org/licenses/LICENSE-2.0
10*a97c2a1fSXin Li  *
11*a97c2a1fSXin Li  * Unless required by applicable law or agreed to in writing, software
12*a97c2a1fSXin Li  * distributed under the License is distributed on an "AS IS" BASIS,
13*a97c2a1fSXin Li  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*a97c2a1fSXin Li  * See the License for the specific language governing permissions and
15*a97c2a1fSXin Li  * limitations under the License.
16*a97c2a1fSXin Li  *
17*a97c2a1fSXin Li  *****************************************************************************
18*a97c2a1fSXin Li  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*a97c2a1fSXin Li */
20*a97c2a1fSXin Li /**
21*a97c2a1fSXin Li *******************************************************************************
22*a97c2a1fSXin Li * @file
23*a97c2a1fSXin Li *  ideint_utils.c
24*a97c2a1fSXin Li *
25*a97c2a1fSXin Li * @brief
26*a97c2a1fSXin Li *  This file contains the definitions of the core  processing of the de
27*a97c2a1fSXin Li * interlacer.
28*a97c2a1fSXin Li *
29*a97c2a1fSXin Li * @author
30*a97c2a1fSXin Li *  Ittiam
31*a97c2a1fSXin Li *
32*a97c2a1fSXin Li * @par List of Functions:
33*a97c2a1fSXin Li *  ideint_weave_pic()
34*a97c2a1fSXin Li *  init_bob_indices()
35*a97c2a1fSXin Li *  ideint_weave_blk()
36*a97c2a1fSXin Li *  ideint_spatial_filter()
37*a97c2a1fSXin Li *
38*a97c2a1fSXin Li * @remarks
39*a97c2a1fSXin Li *  None
40*a97c2a1fSXin Li *
41*a97c2a1fSXin Li *******************************************************************************
42*a97c2a1fSXin Li */
43*a97c2a1fSXin Li /*****************************************************************************/
44*a97c2a1fSXin Li /* File Includes                                                             */
45*a97c2a1fSXin Li /*****************************************************************************/
46*a97c2a1fSXin Li /* System include files */
47*a97c2a1fSXin Li #include <stdio.h>
48*a97c2a1fSXin Li #include <stdint.h>
49*a97c2a1fSXin Li #include <string.h>
50*a97c2a1fSXin Li #include <stdlib.h>
51*a97c2a1fSXin Li #include <assert.h>
52*a97c2a1fSXin Li 
53*a97c2a1fSXin Li 
54*a97c2a1fSXin Li /* User include files */
55*a97c2a1fSXin Li #include "icv_datatypes.h"
56*a97c2a1fSXin Li #include "icv_macros.h"
57*a97c2a1fSXin Li #include "icv_platform_macros.h"
58*a97c2a1fSXin Li #include "icv.h"
59*a97c2a1fSXin Li #include "icv_variance.h"
60*a97c2a1fSXin Li #include "icv_sad.h"
61*a97c2a1fSXin Li #include "ideint.h"
62*a97c2a1fSXin Li #include "ideint_defs.h"
63*a97c2a1fSXin Li #include "ideint_structs.h"
64*a97c2a1fSXin Li #include "ideint_utils.h"
65*a97c2a1fSXin Li #include "ideint_cac.h"
66*a97c2a1fSXin Li 
67*a97c2a1fSXin Li /**
68*a97c2a1fSXin Li *******************************************************************************
69*a97c2a1fSXin Li *
70*a97c2a1fSXin Li * @brief
71*a97c2a1fSXin Li *  Weaves two fields to produce a frame
72*a97c2a1fSXin Li *
73*a97c2a1fSXin Li * @par   Description
74*a97c2a1fSXin Li *  Weaves two fields to produce a frame
75*a97c2a1fSXin Li *
76*a97c2a1fSXin Li * @param[in] ps_src_top
77*a97c2a1fSXin Li *  Top field source
78*a97c2a1fSXin Li *
79*a97c2a1fSXin Li * @param[in] ps_src_bot
80*a97c2a1fSXin Li *  Bottom field source
81*a97c2a1fSXin Li *
82*a97c2a1fSXin Li * @param[in] ps_dst_frm
83*a97c2a1fSXin Li *  Destination frame
84*a97c2a1fSXin Li *
85*a97c2a1fSXin Li * @returns
86*a97c2a1fSXin Li *   0 on Success
87*a97c2a1fSXin Li *
88*a97c2a1fSXin Li * @remarks
89*a97c2a1fSXin Li *
90*a97c2a1fSXin Li *******************************************************************************
91*a97c2a1fSXin Li */
ideint_weave_pic(icv_pic_t * ps_src_top,icv_pic_t * ps_src_bot,icv_pic_t * ps_dst_frm,WORD32 start_row,WORD32 num_rows)92*a97c2a1fSXin Li WORD32 ideint_weave_pic(icv_pic_t *ps_src_top,
93*a97c2a1fSXin Li                         icv_pic_t *ps_src_bot,
94*a97c2a1fSXin Li                         icv_pic_t *ps_dst_frm,
95*a97c2a1fSXin Li                         WORD32 start_row,
96*a97c2a1fSXin Li                         WORD32 num_rows)
97*a97c2a1fSXin Li {
98*a97c2a1fSXin Li     UWORD8 *pu1_src, *pu1_dst;
99*a97c2a1fSXin Li     WORD32 i, j, num_comp;
100*a97c2a1fSXin Li     icv_pic_t *ps_src_fld;
101*a97c2a1fSXin Li     WORD32 fld;
102*a97c2a1fSXin Li     icv_pic_t *ps_src_flds[2];
103*a97c2a1fSXin Li 
104*a97c2a1fSXin Li     num_comp = 3;
105*a97c2a1fSXin Li     ps_src_flds[0] = ps_src_top;
106*a97c2a1fSXin Li     ps_src_flds[1] = ps_src_bot;
107*a97c2a1fSXin Li 
108*a97c2a1fSXin Li     for(fld = 0; fld < 2; fld++)
109*a97c2a1fSXin Li     {
110*a97c2a1fSXin Li         ps_src_fld = ps_src_flds[fld];
111*a97c2a1fSXin Li         for(i = 0; i < num_comp; i++)
112*a97c2a1fSXin Li         {
113*a97c2a1fSXin Li             WORD32 src_strd;
114*a97c2a1fSXin Li             WORD32 dst_strd;
115*a97c2a1fSXin Li             WORD32 comp_row_start, comp_row_end;
116*a97c2a1fSXin Li             comp_row_start = start_row;
117*a97c2a1fSXin Li             comp_row_end = comp_row_start + num_rows;
118*a97c2a1fSXin Li             if(i)
119*a97c2a1fSXin Li             {
120*a97c2a1fSXin Li                 comp_row_start >>= 1;
121*a97c2a1fSXin Li                 comp_row_end >>= 1;
122*a97c2a1fSXin Li             }
123*a97c2a1fSXin Li 
124*a97c2a1fSXin Li             comp_row_end = MIN(comp_row_end, ps_dst_frm->ai4_ht[i]);
125*a97c2a1fSXin Li 
126*a97c2a1fSXin Li             pu1_src = ps_src_fld->apu1_buf[i];
127*a97c2a1fSXin Li             pu1_dst = ps_dst_frm->apu1_buf[i];
128*a97c2a1fSXin Li 
129*a97c2a1fSXin Li             src_strd = ps_src_fld->ai4_strd[i];
130*a97c2a1fSXin Li             dst_strd = ps_dst_frm->ai4_strd[i];
131*a97c2a1fSXin Li 
132*a97c2a1fSXin Li             /* If source field is bottom, increment destination */
133*a97c2a1fSXin Li             pu1_dst += fld * dst_strd;
134*a97c2a1fSXin Li 
135*a97c2a1fSXin Li             /* In case input and output are pointing to same buffer, then no need to copy */
136*a97c2a1fSXin Li             if((pu1_src != pu1_dst) || ((2 * dst_strd) != src_strd))
137*a97c2a1fSXin Li             {
138*a97c2a1fSXin Li                 pu1_dst += ps_dst_frm->ai4_strd[i] * comp_row_start;
139*a97c2a1fSXin Li                 pu1_src += ps_src_fld->ai4_strd[i] * comp_row_start / 2;
140*a97c2a1fSXin Li 
141*a97c2a1fSXin Li                 for(j = comp_row_start; j < comp_row_end; j += 2)
142*a97c2a1fSXin Li                 {
143*a97c2a1fSXin Li                     memcpy(pu1_dst, pu1_src, ps_dst_frm->ai4_wd[i]);
144*a97c2a1fSXin Li                     pu1_dst += ps_dst_frm->ai4_strd[i] * 2;
145*a97c2a1fSXin Li                     pu1_src += ps_src_fld->ai4_strd[i];
146*a97c2a1fSXin Li                 }
147*a97c2a1fSXin Li             }
148*a97c2a1fSXin Li         }
149*a97c2a1fSXin Li     }
150*a97c2a1fSXin Li     return 0;
151*a97c2a1fSXin Li }
152*a97c2a1fSXin Li 
153*a97c2a1fSXin Li 
154*a97c2a1fSXin Li /**
155*a97c2a1fSXin Li *******************************************************************************
156*a97c2a1fSXin Li *
157*a97c2a1fSXin Li * @brief
158*a97c2a1fSXin Li *  Weaves a 8x8 block
159*a97c2a1fSXin Li *
160*a97c2a1fSXin Li * @par   Description
161*a97c2a1fSXin Li *  Weaves a 8x8 block from two fields
162*a97c2a1fSXin Li *
163*a97c2a1fSXin Li * @param[in] pu1_top
164*a97c2a1fSXin Li *  Top field source
165*a97c2a1fSXin Li *
166*a97c2a1fSXin Li * @param[in] pu1_bot
167*a97c2a1fSXin Li *  Bottom field source
168*a97c2a1fSXin Li *
169*a97c2a1fSXin Li * @param[in] pu1_dst
170*a97c2a1fSXin Li *  Destination
171*a97c2a1fSXin Li *
172*a97c2a1fSXin Li * @param[in] dst_strd
173*a97c2a1fSXin Li *  Destination stride
174*a97c2a1fSXin Li *
175*a97c2a1fSXin Li * @param[in] src_strd
176*a97c2a1fSXin Li *  Source stride
177*a97c2a1fSXin Li *
178*a97c2a1fSXin Li * @returns
179*a97c2a1fSXin Li *  0 on success
180*a97c2a1fSXin Li *
181*a97c2a1fSXin Li * @remarks
182*a97c2a1fSXin Li *
183*a97c2a1fSXin Li *******************************************************************************
184*a97c2a1fSXin Li */
ideint_weave_blk(UWORD8 * pu1_top,UWORD8 * pu1_bot,UWORD8 * pu1_dst,WORD32 dst_strd,WORD32 src_strd,WORD32 wd,WORD32 ht)185*a97c2a1fSXin Li WORD32 ideint_weave_blk(UWORD8 *pu1_top,
186*a97c2a1fSXin Li                         UWORD8 *pu1_bot,
187*a97c2a1fSXin Li                         UWORD8 *pu1_dst,
188*a97c2a1fSXin Li                         WORD32 dst_strd,
189*a97c2a1fSXin Li                         WORD32 src_strd,
190*a97c2a1fSXin Li                         WORD32 wd,
191*a97c2a1fSXin Li                         WORD32 ht)
192*a97c2a1fSXin Li {
193*a97c2a1fSXin Li     WORD32 j;
194*a97c2a1fSXin Li 
195*a97c2a1fSXin Li     for(j = 0; j < ht; j += 2)
196*a97c2a1fSXin Li     {
197*a97c2a1fSXin Li         memcpy(pu1_dst, pu1_top, wd);
198*a97c2a1fSXin Li         pu1_dst += dst_strd;
199*a97c2a1fSXin Li         pu1_top += src_strd;
200*a97c2a1fSXin Li 
201*a97c2a1fSXin Li         memcpy(pu1_dst, pu1_bot, wd);
202*a97c2a1fSXin Li         pu1_dst += dst_strd;
203*a97c2a1fSXin Li         pu1_bot += src_strd;
204*a97c2a1fSXin Li     }
205*a97c2a1fSXin Li     return 0;
206*a97c2a1fSXin Li }
207*a97c2a1fSXin Li 
208*a97c2a1fSXin Li /**
209*a97c2a1fSXin Li *******************************************************************************
210*a97c2a1fSXin Li *
211*a97c2a1fSXin Li * @brief
212*a97c2a1fSXin Li *  Copy a boundary block and pad
213*a97c2a1fSXin Li *
214*a97c2a1fSXin Li * @par   Description
215*a97c2a1fSXin Li *  Copies a block on one of the boundaries and pads
216*a97c2a1fSXin Li *
217*a97c2a1fSXin Li * @param[in] pu1_top
218*a97c2a1fSXin Li *  Top field source
219*a97c2a1fSXin Li *
220*a97c2a1fSXin Li * @param[in] pu1_bot
221*a97c2a1fSXin Li *  Bottom field source
222*a97c2a1fSXin Li *
223*a97c2a1fSXin Li * @param[in] pu1_pad
224*a97c2a1fSXin Li *  Padded destination
225*a97c2a1fSXin Li *
226*a97c2a1fSXin Li * @param[in] cur_strd
227*a97c2a1fSXin Li *  Stride for pu1_top and pu1_bot
228*a97c2a1fSXin Li *
229*a97c2a1fSXin Li * @param[in] row
230*a97c2a1fSXin Li *  Current block's row
231*a97c2a1fSXin Li *
232*a97c2a1fSXin Li * @param[in] col
233*a97c2a1fSXin Li *  Current block's column
234*a97c2a1fSXin Li *
235*a97c2a1fSXin Li * @param[in] num_blks_y
236*a97c2a1fSXin Li *  Number of blocks in Y direction
237*a97c2a1fSXin Li *
238*a97c2a1fSXin Li * @param[in] num_blks_x
239*a97c2a1fSXin Li *  Number of blocks in X direction
240*a97c2a1fSXin Li 
241*a97c2a1fSXin Li * @returns
242*a97c2a1fSXin Li *  None
243*a97c2a1fSXin Li *
244*a97c2a1fSXin Li * @remarks
245*a97c2a1fSXin Li *
246*a97c2a1fSXin Li *******************************************************************************
247*a97c2a1fSXin Li */
ideint_pad_blk(UWORD8 * pu1_top,UWORD8 * pu1_bot,UWORD8 * pu1_pad,WORD32 cur_strd,WORD32 row,WORD32 col,WORD32 num_blks_y,WORD32 num_blks_x,WORD32 blk_wd,WORD32 blk_ht)248*a97c2a1fSXin Li void ideint_pad_blk(UWORD8 *pu1_top,
249*a97c2a1fSXin Li                     UWORD8 *pu1_bot,
250*a97c2a1fSXin Li                     UWORD8 *pu1_pad,
251*a97c2a1fSXin Li                     WORD32 cur_strd,
252*a97c2a1fSXin Li                     WORD32 row,
253*a97c2a1fSXin Li                     WORD32 col,
254*a97c2a1fSXin Li                     WORD32 num_blks_y,
255*a97c2a1fSXin Li                     WORD32 num_blks_x,
256*a97c2a1fSXin Li                     WORD32 blk_wd,
257*a97c2a1fSXin Li                     WORD32 blk_ht)
258*a97c2a1fSXin Li {
259*a97c2a1fSXin Li     WORD32 i;
260*a97c2a1fSXin Li     WORD32 num_cols, num_rows;
261*a97c2a1fSXin Li     UWORD8 *pu1_dst;
262*a97c2a1fSXin Li     UWORD8 *pu1_src_top;
263*a97c2a1fSXin Li     UWORD8 *pu1_src_bot;
264*a97c2a1fSXin Li 
265*a97c2a1fSXin Li     num_rows = blk_ht + 4;
266*a97c2a1fSXin Li     num_cols = blk_wd + 4;
267*a97c2a1fSXin Li 
268*a97c2a1fSXin Li     pu1_src_top = pu1_top - cur_strd - 2;
269*a97c2a1fSXin Li     pu1_src_bot = pu1_bot - cur_strd - 2;
270*a97c2a1fSXin Li     pu1_dst = pu1_pad;
271*a97c2a1fSXin Li 
272*a97c2a1fSXin Li     if(0 == col)
273*a97c2a1fSXin Li     {
274*a97c2a1fSXin Li         num_cols -= 2;
275*a97c2a1fSXin Li         pu1_dst += 2;
276*a97c2a1fSXin Li         pu1_src_top += 2;
277*a97c2a1fSXin Li         pu1_src_bot += 2;
278*a97c2a1fSXin Li     }
279*a97c2a1fSXin Li 
280*a97c2a1fSXin Li     if(0 == row)
281*a97c2a1fSXin Li     {
282*a97c2a1fSXin Li         num_rows -= 2;
283*a97c2a1fSXin Li         pu1_dst += 2 * (BLK_WD + 4);
284*a97c2a1fSXin Li         pu1_src_top += cur_strd;
285*a97c2a1fSXin Li         pu1_src_bot += cur_strd;
286*a97c2a1fSXin Li     }
287*a97c2a1fSXin Li 
288*a97c2a1fSXin Li     if((num_blks_x - 1) == col)
289*a97c2a1fSXin Li         num_cols -= 2;
290*a97c2a1fSXin Li 
291*a97c2a1fSXin Li     if((num_blks_y - 1) == row)
292*a97c2a1fSXin Li         num_rows -= 2;
293*a97c2a1fSXin Li 
294*a97c2a1fSXin Li     for(i = 0; i < num_rows; i += 2)
295*a97c2a1fSXin Li     {
296*a97c2a1fSXin Li         memcpy(pu1_dst, pu1_src_top, num_cols);
297*a97c2a1fSXin Li         pu1_dst += (BLK_WD + 4);
298*a97c2a1fSXin Li 
299*a97c2a1fSXin Li         memcpy(pu1_dst, pu1_src_bot, num_cols);
300*a97c2a1fSXin Li         pu1_dst += (BLK_WD + 4);
301*a97c2a1fSXin Li 
302*a97c2a1fSXin Li         pu1_src_top += cur_strd;
303*a97c2a1fSXin Li         pu1_src_bot += cur_strd;
304*a97c2a1fSXin Li     }
305*a97c2a1fSXin Li 
306*a97c2a1fSXin Li 
307*a97c2a1fSXin Li     /* Pad Left */
308*a97c2a1fSXin Li     if(0 == col)
309*a97c2a1fSXin Li     {
310*a97c2a1fSXin Li        for(i = 0; i < (BLK_HT + 4); i++)
311*a97c2a1fSXin Li        {
312*a97c2a1fSXin Li            WORD32 ofst = i * (BLK_WD + 4) + 2;
313*a97c2a1fSXin Li            pu1_pad[ofst - 1] = pu1_pad[ofst];
314*a97c2a1fSXin Li            pu1_pad[ofst - 2] = pu1_pad[ofst];
315*a97c2a1fSXin Li        }
316*a97c2a1fSXin Li     }
317*a97c2a1fSXin Li 
318*a97c2a1fSXin Li     /* Pad right */
319*a97c2a1fSXin Li     if((num_blks_x - 1) == col)
320*a97c2a1fSXin Li     {
321*a97c2a1fSXin Li        for(i = 0; i < (BLK_HT + 4); i++)
322*a97c2a1fSXin Li        {
323*a97c2a1fSXin Li            WORD32 ofst =  i * (BLK_WD + 4) + 2 + blk_wd - 1;
324*a97c2a1fSXin Li            WORD32 size = (BLK_WD - blk_wd) + 2;
325*a97c2a1fSXin Li            /* Padding on right should include padding for boundary
326*a97c2a1fSXin Li             * blocks when width is non-multiple of 8
327*a97c2a1fSXin Li             */
328*a97c2a1fSXin Li            memset(&pu1_pad[ofst + 1], pu1_pad[ofst], size);
329*a97c2a1fSXin Li        }
330*a97c2a1fSXin Li     }
331*a97c2a1fSXin Li 
332*a97c2a1fSXin Li     /* Pad Top */
333*a97c2a1fSXin Li     if(0 == row)
334*a97c2a1fSXin Li     {
335*a97c2a1fSXin Li         WORD32 src_ofst = 2 * (BLK_WD + 4);
336*a97c2a1fSXin Li         WORD32 dst_ofst = 0;
337*a97c2a1fSXin Li         memcpy(pu1_pad + dst_ofst, pu1_pad + src_ofst, (BLK_WD + 4));
338*a97c2a1fSXin Li         src_ofst += (BLK_WD + 4);
339*a97c2a1fSXin Li         dst_ofst += (BLK_WD + 4);
340*a97c2a1fSXin Li         memcpy(pu1_pad + dst_ofst, pu1_pad + src_ofst, (BLK_WD + 4));
341*a97c2a1fSXin Li     }
342*a97c2a1fSXin Li 
343*a97c2a1fSXin Li     /* Pad Bottom */
344*a97c2a1fSXin Li     if((num_blks_y - 1) == row)
345*a97c2a1fSXin Li     {
346*a97c2a1fSXin Li         WORD32 src_ofst = (0 + blk_ht) * (BLK_WD + 4);
347*a97c2a1fSXin Li         WORD32 dst_ofst = (1 + blk_ht) * (BLK_WD + 4);
348*a97c2a1fSXin Li         WORD32 size = (BLK_HT - blk_ht) + 2;
349*a97c2a1fSXin Li 
350*a97c2a1fSXin Li         /* Padding on bottom should include padding for boundary
351*a97c2a1fSXin Li          * blocks when height is non-multiple of 8
352*a97c2a1fSXin Li          */
353*a97c2a1fSXin Li         for(i = 0; i < size; i++)
354*a97c2a1fSXin Li         {
355*a97c2a1fSXin Li             memcpy(pu1_pad + dst_ofst, pu1_pad + src_ofst, (BLK_WD + 4));
356*a97c2a1fSXin Li             dst_ofst += (BLK_WD + 4);
357*a97c2a1fSXin Li         }
358*a97c2a1fSXin Li     }
359*a97c2a1fSXin Li }
360*a97c2a1fSXin Li 
361*a97c2a1fSXin Li /**
362*a97c2a1fSXin Li *******************************************************************************
363*a97c2a1fSXin Li *
364*a97c2a1fSXin Li * @brief
365*a97c2a1fSXin Li *  Performs spatial edge adaptive filtering
366*a97c2a1fSXin Li *
367*a97c2a1fSXin Li * @par   Description
368*a97c2a1fSXin Li *  Performs spatial edge adaptive filtering by detecting edge direction
369*a97c2a1fSXin Li *
370*a97c2a1fSXin Li * @param[in] pu1_src
371*a97c2a1fSXin Li *  Source buffer
372*a97c2a1fSXin Li *
373*a97c2a1fSXin Li * @param[in] pu1_out
374*a97c2a1fSXin Li *  Destination buffer
375*a97c2a1fSXin Li *
376*a97c2a1fSXin Li * @param[in] src_strd
377*a97c2a1fSXin Li *  Source stride
378*a97c2a1fSXin Li *
379*a97c2a1fSXin Li * @param[in] out_strd
380*a97c2a1fSXin Li *  Destination stride
381*a97c2a1fSXin Li 
382*a97c2a1fSXin Li * @returns
383*a97c2a1fSXin Li * None
384*a97c2a1fSXin Li *
385*a97c2a1fSXin Li * @remarks
386*a97c2a1fSXin Li *
387*a97c2a1fSXin Li *******************************************************************************
388*a97c2a1fSXin Li */
ideint_spatial_filter(UWORD8 * pu1_src,UWORD8 * pu1_out,WORD32 src_strd,WORD32 out_strd)389*a97c2a1fSXin Li void ideint_spatial_filter(UWORD8 *pu1_src,
390*a97c2a1fSXin Li                            UWORD8 *pu1_out,
391*a97c2a1fSXin Li                            WORD32 src_strd,
392*a97c2a1fSXin Li                            WORD32 out_strd)
393*a97c2a1fSXin Li {
394*a97c2a1fSXin Li     WORD32 i;
395*a97c2a1fSXin Li     WORD32 j;
396*a97c2a1fSXin Li     WORD32 k;
397*a97c2a1fSXin Li 
398*a97c2a1fSXin Li     /*********************************************************************/
399*a97c2a1fSXin Li     /* This loop is for the two halves inside the 8x4 block.             */
400*a97c2a1fSXin Li     /*********************************************************************/
401*a97c2a1fSXin Li     for(k = 0; k < 2; k++)
402*a97c2a1fSXin Li     {
403*a97c2a1fSXin Li         WORD32 adiff[3] = {0, 0, 0};
404*a97c2a1fSXin Li         WORD32 shift;
405*a97c2a1fSXin Li         WORD32 dir_45_le_90, dir_45_le_135, dir_135_le_90;
406*a97c2a1fSXin Li         UWORD8 *pu1_row_1, *pu1_row_2, *pu1_dst;
407*a97c2a1fSXin Li 
408*a97c2a1fSXin Li         /*****************************************************************/
409*a97c2a1fSXin Li         /* Direction detection                                           */
410*a97c2a1fSXin Li         /*****************************************************************/
411*a97c2a1fSXin Li         pu1_row_1 = pu1_src;
412*a97c2a1fSXin Li         pu1_row_2 = pu1_src + src_strd;
413*a97c2a1fSXin Li 
414*a97c2a1fSXin Li         /*****************************************************************/
415*a97c2a1fSXin Li         /* Calculating the difference along each of the 3 directions.    */
416*a97c2a1fSXin Li         /*****************************************************************/
417*a97c2a1fSXin Li         for(j = 0; j < SUB_BLK_HT; j ++)
418*a97c2a1fSXin Li         {
419*a97c2a1fSXin Li             for(i = 0; i < SUB_BLK_WD; i++)
420*a97c2a1fSXin Li             {
421*a97c2a1fSXin Li                 adiff[0] += ABS_DIF(pu1_row_1[i], pu1_row_2[i]); /*  90 */
422*a97c2a1fSXin Li 
423*a97c2a1fSXin Li                 adiff[1] += ABS_DIF(pu1_row_1[i - 1], pu1_row_2[i + 1]); /* 135 */
424*a97c2a1fSXin Li 
425*a97c2a1fSXin Li                 adiff[2] += ABS_DIF(pu1_row_1[i + 1], pu1_row_2[i - 1]); /*  45 */
426*a97c2a1fSXin Li             }
427*a97c2a1fSXin Li             pu1_row_1 += src_strd;
428*a97c2a1fSXin Li             pu1_row_2 += src_strd;
429*a97c2a1fSXin Li         }
430*a97c2a1fSXin Li 
431*a97c2a1fSXin Li         /*****************************************************************/
432*a97c2a1fSXin Li         /* Applying bias, to make the diff comparision more robust.      */
433*a97c2a1fSXin Li         /*****************************************************************/
434*a97c2a1fSXin Li         adiff[0] *= EDGE_BIAS_0;
435*a97c2a1fSXin Li         adiff[1] *= EDGE_BIAS_1;
436*a97c2a1fSXin Li         adiff[2] *= EDGE_BIAS_1;
437*a97c2a1fSXin Li 
438*a97c2a1fSXin Li         /*****************************************************************/
439*a97c2a1fSXin Li         /* comapring the diffs */
440*a97c2a1fSXin Li         /*****************************************************************/
441*a97c2a1fSXin Li         dir_45_le_90  = (adiff[2] <= adiff[0]);
442*a97c2a1fSXin Li         dir_45_le_135 = (adiff[2] <= adiff[1]);
443*a97c2a1fSXin Li         dir_135_le_90 = (adiff[1] <= adiff[0]);
444*a97c2a1fSXin Li 
445*a97c2a1fSXin Li         /*****************************************************************/
446*a97c2a1fSXin Li         /* Direction selection. */
447*a97c2a1fSXin Li         /*****************************************************************/
448*a97c2a1fSXin Li         shift = 0;
449*a97c2a1fSXin Li         if(1 == dir_45_le_135)
450*a97c2a1fSXin Li         {
451*a97c2a1fSXin Li             if(1 == dir_45_le_90)
452*a97c2a1fSXin Li                 shift = 1;
453*a97c2a1fSXin Li         }
454*a97c2a1fSXin Li         else
455*a97c2a1fSXin Li         {
456*a97c2a1fSXin Li             if(1 == dir_135_le_90)
457*a97c2a1fSXin Li                 shift = -1;
458*a97c2a1fSXin Li         }
459*a97c2a1fSXin Li 
460*a97c2a1fSXin Li         /*****************************************************************/
461*a97c2a1fSXin Li         /* Directional interpolation */
462*a97c2a1fSXin Li         /*****************************************************************/
463*a97c2a1fSXin Li         pu1_row_1 = pu1_src + shift;
464*a97c2a1fSXin Li         pu1_row_2 = pu1_src + src_strd - shift;
465*a97c2a1fSXin Li         pu1_dst   = pu1_out;
466*a97c2a1fSXin Li 
467*a97c2a1fSXin Li         for(j = 0; j < SUB_BLK_HT; j++)
468*a97c2a1fSXin Li         {
469*a97c2a1fSXin Li             for(i = 0; i < SUB_BLK_WD; i++)
470*a97c2a1fSXin Li             {
471*a97c2a1fSXin Li                 pu1_dst[i] = (UWORD8)AVG(pu1_row_1[i], pu1_row_2[i]);
472*a97c2a1fSXin Li             }
473*a97c2a1fSXin Li             pu1_row_1 += src_strd;
474*a97c2a1fSXin Li             pu1_row_2 += src_strd;
475*a97c2a1fSXin Li             pu1_dst   += out_strd;
476*a97c2a1fSXin Li         }
477*a97c2a1fSXin Li 
478*a97c2a1fSXin Li         pu1_out += SUB_BLK_WD;
479*a97c2a1fSXin Li         pu1_src += SUB_BLK_WD;
480*a97c2a1fSXin Li     }
481*a97c2a1fSXin Li }
482*a97c2a1fSXin Li 
483