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 <limits.h>
13#include <stdlib.h>
14#include "vpx_config.h"
15#include "vpx/vpx_integer.h"
16
17static unsigned int sad_mx_n_c(const unsigned char *src_ptr, int src_stride,
18                               const unsigned char *ref_ptr, int ref_stride,
19                               unsigned int max_sad, int m, int n)
20{
21    int r, c;
22    unsigned int sad = 0;
23
24    for (r = 0; r < n; r++)
25    {
26        for (c = 0; c < m; c++)
27        {
28            sad += abs(src_ptr[c] - ref_ptr[c]);
29        }
30
31        if (sad > max_sad)
32          break;
33
34        src_ptr += src_stride;
35        ref_ptr += ref_stride;
36    }
37
38    return sad;
39}
40
41/* max_sad is provided as an optional optimization point. Alternative
42 * implementations of these functions are not required to check it.
43 */
44
45unsigned int vp8_sad16x16_c(const unsigned char *src_ptr, int src_stride,
46                            const unsigned char *ref_ptr, int ref_stride,
47                            unsigned int max_sad)
48{
49    return sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride, max_sad, 16, 16);
50}
51
52unsigned int vp8_sad8x8_c(const unsigned char *src_ptr, int src_stride,
53                          const unsigned char *ref_ptr, int ref_stride,
54                          unsigned int max_sad)
55{
56    return sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride, max_sad, 8, 8);
57}
58
59unsigned int vp8_sad16x8_c(const unsigned char *src_ptr, int src_stride,
60                           const unsigned char *ref_ptr, int ref_stride,
61                           unsigned int max_sad)
62{
63    return sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride, max_sad, 16, 8);
64
65}
66
67unsigned int vp8_sad8x16_c(const unsigned char *src_ptr, int src_stride,
68                           const unsigned char *ref_ptr, int ref_stride,
69                           unsigned int max_sad)
70{
71    return sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride, max_sad, 8, 16);
72}
73
74unsigned int vp8_sad4x4_c(const unsigned char *src_ptr, int src_stride,
75                          const unsigned char *ref_ptr, int ref_stride,
76                          unsigned int max_sad)
77{
78    return sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride, max_sad, 4, 4);
79}
80
81void vp8_sad16x16x3_c(const unsigned char *src_ptr, int src_stride,
82                      const unsigned char *ref_ptr, int ref_stride,
83                      unsigned int *sad_array)
84{
85    sad_array[0] = vp8_sad16x16_c(src_ptr, src_stride, ref_ptr + 0, ref_stride, UINT_MAX);
86    sad_array[1] = vp8_sad16x16_c(src_ptr, src_stride, ref_ptr + 1, ref_stride, UINT_MAX);
87    sad_array[2] = vp8_sad16x16_c(src_ptr, src_stride, ref_ptr + 2, ref_stride, UINT_MAX);
88}
89
90void vp8_sad16x16x8_c(const unsigned char *src_ptr, int src_stride,
91                      const unsigned char *ref_ptr, int ref_stride,
92                      unsigned short *sad_array)
93{
94    sad_array[0] = (unsigned short)vp8_sad16x16_c(src_ptr, src_stride, ref_ptr + 0, ref_stride, UINT_MAX);
95    sad_array[1] = (unsigned short)vp8_sad16x16_c(src_ptr, src_stride, ref_ptr + 1, ref_stride, UINT_MAX);
96    sad_array[2] = (unsigned short)vp8_sad16x16_c(src_ptr, src_stride, ref_ptr + 2, ref_stride, UINT_MAX);
97    sad_array[3] = (unsigned short)vp8_sad16x16_c(src_ptr, src_stride, ref_ptr + 3, ref_stride, UINT_MAX);
98    sad_array[4] = (unsigned short)vp8_sad16x16_c(src_ptr, src_stride, ref_ptr + 4, ref_stride, UINT_MAX);
99    sad_array[5] = (unsigned short)vp8_sad16x16_c(src_ptr, src_stride, ref_ptr + 5, ref_stride, UINT_MAX);
100    sad_array[6] = (unsigned short)vp8_sad16x16_c(src_ptr, src_stride, ref_ptr + 6, ref_stride, UINT_MAX);
101    sad_array[7] = (unsigned short)vp8_sad16x16_c(src_ptr, src_stride, ref_ptr + 7, ref_stride, UINT_MAX);
102}
103
104void vp8_sad16x8x3_c(const unsigned char *src_ptr, int src_stride,
105                     const unsigned char *ref_ptr, int ref_stride,
106                     unsigned int *sad_array)
107{
108    sad_array[0] = vp8_sad16x8_c(src_ptr, src_stride, ref_ptr + 0, ref_stride, UINT_MAX);
109    sad_array[1] = vp8_sad16x8_c(src_ptr, src_stride, ref_ptr + 1, ref_stride, UINT_MAX);
110    sad_array[2] = vp8_sad16x8_c(src_ptr, src_stride, ref_ptr + 2, ref_stride, UINT_MAX);
111}
112
113void vp8_sad16x8x8_c(const unsigned char *src_ptr, int src_stride,
114                     const unsigned char *ref_ptr, int ref_stride,
115                     unsigned short *sad_array)
116{
117    sad_array[0] = (unsigned short)vp8_sad16x8_c(src_ptr, src_stride, ref_ptr + 0, ref_stride, UINT_MAX);
118    sad_array[1] = (unsigned short)vp8_sad16x8_c(src_ptr, src_stride, ref_ptr + 1, ref_stride, UINT_MAX);
119    sad_array[2] = (unsigned short)vp8_sad16x8_c(src_ptr, src_stride, ref_ptr + 2, ref_stride, UINT_MAX);
120    sad_array[3] = (unsigned short)vp8_sad16x8_c(src_ptr, src_stride, ref_ptr + 3, ref_stride, UINT_MAX);
121    sad_array[4] = (unsigned short)vp8_sad16x8_c(src_ptr, src_stride, ref_ptr + 4, ref_stride, UINT_MAX);
122    sad_array[5] = (unsigned short)vp8_sad16x8_c(src_ptr, src_stride, ref_ptr + 5, ref_stride, UINT_MAX);
123    sad_array[6] = (unsigned short)vp8_sad16x8_c(src_ptr, src_stride, ref_ptr + 6, ref_stride, UINT_MAX);
124    sad_array[7] = (unsigned short)vp8_sad16x8_c(src_ptr, src_stride, ref_ptr + 7, ref_stride, UINT_MAX);
125}
126
127void vp8_sad8x8x3_c(const unsigned char *src_ptr, int src_stride,
128                    const unsigned char *ref_ptr, int ref_stride,
129                    unsigned int *sad_array)
130{
131    sad_array[0] = vp8_sad8x8_c(src_ptr, src_stride, ref_ptr + 0, ref_stride, UINT_MAX);
132    sad_array[1] = vp8_sad8x8_c(src_ptr, src_stride, ref_ptr + 1, ref_stride, UINT_MAX);
133    sad_array[2] = vp8_sad8x8_c(src_ptr, src_stride, ref_ptr + 2, ref_stride, UINT_MAX);
134}
135
136void vp8_sad8x8x8_c(const unsigned char *src_ptr, int src_stride,
137                    const unsigned char *ref_ptr, int ref_stride,
138                    unsigned short *sad_array)
139{
140    sad_array[0] = (unsigned short)vp8_sad8x8_c(src_ptr, src_stride, ref_ptr + 0, ref_stride, UINT_MAX);
141    sad_array[1] = (unsigned short)vp8_sad8x8_c(src_ptr, src_stride, ref_ptr + 1, ref_stride, UINT_MAX);
142    sad_array[2] = (unsigned short)vp8_sad8x8_c(src_ptr, src_stride, ref_ptr + 2, ref_stride, UINT_MAX);
143    sad_array[3] = (unsigned short)vp8_sad8x8_c(src_ptr, src_stride, ref_ptr + 3, ref_stride, UINT_MAX);
144    sad_array[4] = (unsigned short)vp8_sad8x8_c(src_ptr, src_stride, ref_ptr + 4, ref_stride, UINT_MAX);
145    sad_array[5] = (unsigned short)vp8_sad8x8_c(src_ptr, src_stride, ref_ptr + 5, ref_stride, UINT_MAX);
146    sad_array[6] = (unsigned short)vp8_sad8x8_c(src_ptr, src_stride, ref_ptr + 6, ref_stride, UINT_MAX);
147    sad_array[7] = (unsigned short)vp8_sad8x8_c(src_ptr, src_stride, ref_ptr + 7, ref_stride, UINT_MAX);
148}
149
150void vp8_sad8x16x3_c(const unsigned char *src_ptr, int src_stride,
151                     const unsigned char *ref_ptr, int ref_stride,
152                     unsigned int *sad_array)
153{
154    sad_array[0] = vp8_sad8x16_c(src_ptr, src_stride, ref_ptr + 0, ref_stride, UINT_MAX);
155    sad_array[1] = vp8_sad8x16_c(src_ptr, src_stride, ref_ptr + 1, ref_stride, UINT_MAX);
156    sad_array[2] = vp8_sad8x16_c(src_ptr, src_stride, ref_ptr + 2, ref_stride, UINT_MAX);
157}
158
159void vp8_sad8x16x8_c(const unsigned char *src_ptr, int src_stride,
160                     const unsigned char *ref_ptr, int ref_stride,
161                     unsigned short *sad_array)
162{
163    sad_array[0] = (unsigned short)vp8_sad8x16_c(src_ptr, src_stride, ref_ptr + 0, ref_stride, UINT_MAX);
164    sad_array[1] = (unsigned short)vp8_sad8x16_c(src_ptr, src_stride, ref_ptr + 1, ref_stride, UINT_MAX);
165    sad_array[2] = (unsigned short)vp8_sad8x16_c(src_ptr, src_stride, ref_ptr + 2, ref_stride, UINT_MAX);
166    sad_array[3] = (unsigned short)vp8_sad8x16_c(src_ptr, src_stride, ref_ptr + 3, ref_stride, UINT_MAX);
167    sad_array[4] = (unsigned short)vp8_sad8x16_c(src_ptr, src_stride, ref_ptr + 4, ref_stride, UINT_MAX);
168    sad_array[5] = (unsigned short)vp8_sad8x16_c(src_ptr, src_stride, ref_ptr + 5, ref_stride, UINT_MAX);
169    sad_array[6] = (unsigned short)vp8_sad8x16_c(src_ptr, src_stride, ref_ptr + 6, ref_stride, UINT_MAX);
170    sad_array[7] = (unsigned short)vp8_sad8x16_c(src_ptr, src_stride, ref_ptr + 7, ref_stride, UINT_MAX);
171}
172
173void vp8_sad4x4x3_c(const unsigned char *src_ptr, int src_stride,
174                    const unsigned char *ref_ptr, int ref_stride,
175                    unsigned int *sad_array)
176{
177    sad_array[0] = vp8_sad4x4_c(src_ptr, src_stride, ref_ptr + 0, ref_stride, UINT_MAX);
178    sad_array[1] = vp8_sad4x4_c(src_ptr, src_stride, ref_ptr + 1, ref_stride, UINT_MAX);
179    sad_array[2] = vp8_sad4x4_c(src_ptr, src_stride, ref_ptr + 2, ref_stride, UINT_MAX);
180}
181
182void vp8_sad4x4x8_c(const unsigned char *src_ptr, int src_stride,
183                    const unsigned char *ref_ptr, int ref_stride,
184                    unsigned short *sad_array)
185{
186    sad_array[0] = (unsigned short)vp8_sad4x4_c(src_ptr, src_stride, ref_ptr + 0, ref_stride, UINT_MAX);
187    sad_array[1] = (unsigned short)vp8_sad4x4_c(src_ptr, src_stride, ref_ptr + 1, ref_stride, UINT_MAX);
188    sad_array[2] = (unsigned short)vp8_sad4x4_c(src_ptr, src_stride, ref_ptr + 2, ref_stride, UINT_MAX);
189    sad_array[3] = (unsigned short)vp8_sad4x4_c(src_ptr, src_stride, ref_ptr + 3, ref_stride, UINT_MAX);
190    sad_array[4] = (unsigned short)vp8_sad4x4_c(src_ptr, src_stride, ref_ptr + 4, ref_stride, UINT_MAX);
191    sad_array[5] = (unsigned short)vp8_sad4x4_c(src_ptr, src_stride, ref_ptr + 5, ref_stride, UINT_MAX);
192    sad_array[6] = (unsigned short)vp8_sad4x4_c(src_ptr, src_stride, ref_ptr + 6, ref_stride, UINT_MAX);
193    sad_array[7] = (unsigned short)vp8_sad4x4_c(src_ptr, src_stride, ref_ptr + 7, ref_stride, UINT_MAX);
194}
195
196void vp8_sad16x16x4d_c(const unsigned char *src_ptr, int src_stride,
197                       const unsigned char * const ref_ptr[], int ref_stride,
198                       unsigned int *sad_array)
199{
200    sad_array[0] = vp8_sad16x16_c(src_ptr, src_stride, ref_ptr[0], ref_stride, UINT_MAX);
201    sad_array[1] = vp8_sad16x16_c(src_ptr, src_stride, ref_ptr[1], ref_stride, UINT_MAX);
202    sad_array[2] = vp8_sad16x16_c(src_ptr, src_stride, ref_ptr[2], ref_stride, UINT_MAX);
203    sad_array[3] = vp8_sad16x16_c(src_ptr, src_stride, ref_ptr[3], ref_stride, UINT_MAX);
204}
205
206void vp8_sad16x8x4d_c(const unsigned char *src_ptr, int src_stride,
207                      const unsigned char * const ref_ptr[], int ref_stride,
208                      unsigned int *sad_array)
209{
210    sad_array[0] = vp8_sad16x8_c(src_ptr, src_stride, ref_ptr[0], ref_stride, UINT_MAX);
211    sad_array[1] = vp8_sad16x8_c(src_ptr, src_stride, ref_ptr[1], ref_stride, UINT_MAX);
212    sad_array[2] = vp8_sad16x8_c(src_ptr, src_stride, ref_ptr[2], ref_stride, UINT_MAX);
213    sad_array[3] = vp8_sad16x8_c(src_ptr, src_stride, ref_ptr[3], ref_stride, UINT_MAX);
214}
215
216void vp8_sad8x8x4d_c(const unsigned char *src_ptr, int src_stride,
217                     const unsigned char * const ref_ptr[], int ref_stride,
218                     unsigned int *sad_array)
219{
220    sad_array[0] = vp8_sad8x8_c(src_ptr, src_stride, ref_ptr[0], ref_stride, UINT_MAX);
221    sad_array[1] = vp8_sad8x8_c(src_ptr, src_stride, ref_ptr[1], ref_stride, UINT_MAX);
222    sad_array[2] = vp8_sad8x8_c(src_ptr, src_stride, ref_ptr[2], ref_stride, UINT_MAX);
223    sad_array[3] = vp8_sad8x8_c(src_ptr, src_stride, ref_ptr[3], ref_stride, UINT_MAX);
224}
225
226void vp8_sad8x16x4d_c(const unsigned char *src_ptr, int src_stride,
227                      const unsigned char * const ref_ptr[], int ref_stride,
228                      unsigned int *sad_array)
229{
230    sad_array[0] = vp8_sad8x16_c(src_ptr, src_stride, ref_ptr[0], ref_stride, UINT_MAX);
231    sad_array[1] = vp8_sad8x16_c(src_ptr, src_stride, ref_ptr[1], ref_stride, UINT_MAX);
232    sad_array[2] = vp8_sad8x16_c(src_ptr, src_stride, ref_ptr[2], ref_stride, UINT_MAX);
233    sad_array[3] = vp8_sad8x16_c(src_ptr, src_stride, ref_ptr[3], ref_stride, UINT_MAX);
234}
235
236void vp8_sad4x4x4d_c(const unsigned char *src_ptr, int src_stride,
237                     const unsigned char * const ref_ptr[], int  ref_stride,
238                     unsigned int *sad_array)
239{
240    sad_array[0] = vp8_sad4x4_c(src_ptr, src_stride, ref_ptr[0], ref_stride, UINT_MAX);
241    sad_array[1] = vp8_sad4x4_c(src_ptr, src_stride, ref_ptr[1], ref_stride, UINT_MAX);
242    sad_array[2] = vp8_sad4x4_c(src_ptr, src_stride, ref_ptr[2], ref_stride, UINT_MAX);
243    sad_array[3] = vp8_sad4x4_c(src_ptr, src_stride, ref_ptr[3], ref_stride, UINT_MAX);
244}
245
246/* Copy 2 macroblocks to a buffer */
247void vp8_copy32xn_c(unsigned char *src_ptr, int src_stride,
248                    unsigned char *dst_ptr, int dst_stride,
249                    int height)
250{
251    int r;
252
253    for (r = 0; r < height; r++)
254    {
255#if !(CONFIG_FAST_UNALIGNED)
256        dst_ptr[0] = src_ptr[0];
257        dst_ptr[1] = src_ptr[1];
258        dst_ptr[2] = src_ptr[2];
259        dst_ptr[3] = src_ptr[3];
260        dst_ptr[4] = src_ptr[4];
261        dst_ptr[5] = src_ptr[5];
262        dst_ptr[6] = src_ptr[6];
263        dst_ptr[7] = src_ptr[7];
264        dst_ptr[8] = src_ptr[8];
265        dst_ptr[9] = src_ptr[9];
266        dst_ptr[10] = src_ptr[10];
267        dst_ptr[11] = src_ptr[11];
268        dst_ptr[12] = src_ptr[12];
269        dst_ptr[13] = src_ptr[13];
270        dst_ptr[14] = src_ptr[14];
271        dst_ptr[15] = src_ptr[15];
272        dst_ptr[16] = src_ptr[16];
273        dst_ptr[17] = src_ptr[17];
274        dst_ptr[18] = src_ptr[18];
275        dst_ptr[19] = src_ptr[19];
276        dst_ptr[20] = src_ptr[20];
277        dst_ptr[21] = src_ptr[21];
278        dst_ptr[22] = src_ptr[22];
279        dst_ptr[23] = src_ptr[23];
280        dst_ptr[24] = src_ptr[24];
281        dst_ptr[25] = src_ptr[25];
282        dst_ptr[26] = src_ptr[26];
283        dst_ptr[27] = src_ptr[27];
284        dst_ptr[28] = src_ptr[28];
285        dst_ptr[29] = src_ptr[29];
286        dst_ptr[30] = src_ptr[30];
287        dst_ptr[31] = src_ptr[31];
288#else
289        ((uint32_t *)dst_ptr)[0] = ((uint32_t *)src_ptr)[0] ;
290        ((uint32_t *)dst_ptr)[1] = ((uint32_t *)src_ptr)[1] ;
291        ((uint32_t *)dst_ptr)[2] = ((uint32_t *)src_ptr)[2] ;
292        ((uint32_t *)dst_ptr)[3] = ((uint32_t *)src_ptr)[3] ;
293        ((uint32_t *)dst_ptr)[4] = ((uint32_t *)src_ptr)[4] ;
294        ((uint32_t *)dst_ptr)[5] = ((uint32_t *)src_ptr)[5] ;
295        ((uint32_t *)dst_ptr)[6] = ((uint32_t *)src_ptr)[6] ;
296        ((uint32_t *)dst_ptr)[7] = ((uint32_t *)src_ptr)[7] ;
297#endif
298        src_ptr += src_stride;
299        dst_ptr += dst_stride;
300
301    }
302}
303