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