1/*
2 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11
12#include "vpx_ports/config.h"
13#include <math.h>
14#include "vp8/common/filter.h"
15#include "vp8/common/subpixel.h"
16#include "vpx_ports/mem.h"
17
18extern void vp8_filter_block2d_first_pass_armv6
19(
20    unsigned char *src_ptr,
21    short         *output_ptr,
22    unsigned int src_pixels_per_line,
23    unsigned int output_width,
24    unsigned int output_height,
25    const short *vp8_filter
26);
27
28extern void vp8_filter_block2d_second_pass_armv6
29(
30    short         *src_ptr,
31    unsigned char *output_ptr,
32    unsigned int output_pitch,
33    unsigned int cnt,
34    const short *vp8_filter
35);
36
37extern void vp8_filter4_block2d_second_pass_armv6
38(
39    short         *src_ptr,
40    unsigned char *output_ptr,
41    unsigned int output_pitch,
42    unsigned int cnt,
43    const short *vp8_filter
44);
45
46extern void vp8_filter_block2d_first_pass_only_armv6
47(
48    unsigned char *src_ptr,
49    unsigned char *output_ptr,
50    unsigned int src_pixels_per_line,
51    unsigned int cnt,
52    unsigned int output_pitch,
53    const short *vp8_filter
54);
55
56
57extern void vp8_filter_block2d_second_pass_only_armv6
58(
59    unsigned char *src_ptr,
60    unsigned char *output_ptr,
61    unsigned int src_pixels_per_line,
62    unsigned int cnt,
63    unsigned int output_pitch,
64    const short *vp8_filter
65);
66
67#if HAVE_ARMV6
68void vp8_sixtap_predict_armv6
69(
70    unsigned char  *src_ptr,
71    int  src_pixels_per_line,
72    int  xoffset,
73    int  yoffset,
74    unsigned char *dst_ptr,
75    int  dst_pitch
76)
77{
78    const short  *HFilter;
79    const short  *VFilter;
80    DECLARE_ALIGNED_ARRAY(4, short, FData, 12*4); /* Temp data buffer used in filtering */
81
82
83    HFilter = vp8_sub_pel_filters[xoffset];   /* 6 tap */
84    VFilter = vp8_sub_pel_filters[yoffset];   /* 6 tap */
85
86    /* Vfilter is null. First pass only */
87    if (xoffset && !yoffset)
88    {
89        /*vp8_filter_block2d_first_pass_armv6 ( src_ptr, FData+2, src_pixels_per_line, 4, 4, HFilter );
90        vp8_filter_block2d_second_pass_armv6 ( FData+2, dst_ptr, dst_pitch, 4, VFilter );*/
91
92        vp8_filter_block2d_first_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 4, dst_pitch, HFilter);
93    }
94    /* Hfilter is null. Second pass only */
95    else if (!xoffset && yoffset)
96    {
97        vp8_filter_block2d_second_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 4, dst_pitch, VFilter);
98    }
99    else
100    {
101        /* Vfilter is a 4 tap filter */
102        if (yoffset & 0x1)
103        {
104            vp8_filter_block2d_first_pass_armv6(src_ptr - src_pixels_per_line, FData + 1, src_pixels_per_line, 4, 7, HFilter);
105            vp8_filter4_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 4, VFilter);
106        }
107        /* Vfilter is 6 tap filter */
108        else
109        {
110            vp8_filter_block2d_first_pass_armv6(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 4, 9, HFilter);
111            vp8_filter_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 4, VFilter);
112        }
113    }
114}
115
116void vp8_sixtap_predict8x8_armv6
117(
118    unsigned char  *src_ptr,
119    int  src_pixels_per_line,
120    int  xoffset,
121    int  yoffset,
122    unsigned char *dst_ptr,
123    int  dst_pitch
124)
125{
126    const short  *HFilter;
127    const short  *VFilter;
128    DECLARE_ALIGNED_ARRAY(4, short, FData, 16*8); /* Temp data buffer used in filtering */
129
130    HFilter = vp8_sub_pel_filters[xoffset];   /* 6 tap */
131    VFilter = vp8_sub_pel_filters[yoffset];   /* 6 tap */
132
133    if (xoffset && !yoffset)
134    {
135        vp8_filter_block2d_first_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 8, dst_pitch, HFilter);
136    }
137    /* Hfilter is null. Second pass only */
138    else if (!xoffset && yoffset)
139    {
140        vp8_filter_block2d_second_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 8, dst_pitch, VFilter);
141    }
142    else
143    {
144        if (yoffset & 0x1)
145        {
146            vp8_filter_block2d_first_pass_armv6(src_ptr - src_pixels_per_line, FData + 1, src_pixels_per_line, 8, 11, HFilter);
147            vp8_filter4_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 8, VFilter);
148        }
149        else
150        {
151            vp8_filter_block2d_first_pass_armv6(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 8, 13, HFilter);
152            vp8_filter_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 8, VFilter);
153        }
154    }
155}
156
157
158void vp8_sixtap_predict16x16_armv6
159(
160    unsigned char  *src_ptr,
161    int  src_pixels_per_line,
162    int  xoffset,
163    int  yoffset,
164    unsigned char *dst_ptr,
165    int  dst_pitch
166)
167{
168    const short  *HFilter;
169    const short  *VFilter;
170    DECLARE_ALIGNED_ARRAY(4, short, FData, 24*16);    /* Temp data buffer used in filtering */
171
172    HFilter = vp8_sub_pel_filters[xoffset];   /* 6 tap */
173    VFilter = vp8_sub_pel_filters[yoffset];   /* 6 tap */
174
175    if (xoffset && !yoffset)
176    {
177        vp8_filter_block2d_first_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 16, dst_pitch, HFilter);
178    }
179    /* Hfilter is null. Second pass only */
180    else if (!xoffset && yoffset)
181    {
182        vp8_filter_block2d_second_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 16, dst_pitch, VFilter);
183    }
184    else
185    {
186        if (yoffset & 0x1)
187        {
188            vp8_filter_block2d_first_pass_armv6(src_ptr - src_pixels_per_line, FData + 1, src_pixels_per_line, 16, 19, HFilter);
189            vp8_filter4_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 16, VFilter);
190        }
191        else
192        {
193            vp8_filter_block2d_first_pass_armv6(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 16, 21, HFilter);
194            vp8_filter_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 16, VFilter);
195        }
196    }
197
198}
199#endif
200